Commit 2427bb241b1db35c6e699ad55adf4a30083b79cd

Authored by Laurent Pinchart
1 parent 49d79ba2e3

fbdev: sh_mobile_lcdc: Restart LCDC in runtime PM resume handler

Instead of restoring registers blindly, restart the LCDC by going
through the startup sequence when resuming from runtime PM suspend. All
registers are now correctly initialized in the right order.

As a side effect, this also gets rid fo a possible panning restore issue
caused by always saving the frame buffer base address registers from set
A instead of the currently active set.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Showing 2 changed files with 5 additions and 45 deletions Side-by-side Diff

drivers/video/sh_mobile_lcdcfb.c
... ... @@ -32,17 +32,6 @@
32 32 #define SIDE_B_OFFSET 0x1000
33 33 #define MIRROR_OFFSET 0x2000
34 34  
35   -/* shared registers and their order for context save/restore */
36   -static int lcdc_shared_regs[] = {
37   - _LDDCKR,
38   - _LDDCKSTPR,
39   - _LDINTR,
40   - _LDDDSR,
41   - _LDCNT1R,
42   - _LDCNT2R,
43   -};
44   -#define NR_SHARED_REGS ARRAY_SIZE(lcdc_shared_regs)
45   -
46 35 #define MAX_XRES 1920
47 36 #define MAX_YRES 1080
48 37  
... ... @@ -111,7 +100,6 @@
111 100 unsigned long lddckr;
112 101 struct sh_mobile_lcdc_chan ch[2];
113 102 struct notifier_block notifier;
114   - unsigned long saved_shared_regs[NR_SHARED_REGS];
115 103 int started;
116 104 int forced_bpp; /* 2 channel LCDC must share bpp setting */
117 105 struct sh_mobile_meram_info *meram_dev;
118 106  
119 107  
120 108  
121 109  
... ... @@ -1289,47 +1277,20 @@
1289 1277 static int sh_mobile_lcdc_runtime_suspend(struct device *dev)
1290 1278 {
1291 1279 struct platform_device *pdev = to_platform_device(dev);
1292   - struct sh_mobile_lcdc_priv *p = platform_get_drvdata(pdev);
1293   - struct sh_mobile_lcdc_chan *ch;
1294   - int k, n;
  1280 + struct sh_mobile_lcdc_priv *priv = platform_get_drvdata(pdev);
1295 1281  
1296   - /* save per-channel registers */
1297   - for (k = 0; k < ARRAY_SIZE(p->ch); k++) {
1298   - ch = &p->ch[k];
1299   - if (!ch->enabled)
1300   - continue;
1301   - for (n = 0; n < NR_CH_REGS; n++)
1302   - ch->saved_ch_regs[n] = lcdc_read_chan(ch, n);
1303   - }
1304   -
1305   - /* save shared registers */
1306   - for (n = 0; n < NR_SHARED_REGS; n++)
1307   - p->saved_shared_regs[n] = lcdc_read(p, lcdc_shared_regs[n]);
1308   -
1309 1282 /* turn off LCDC hardware */
1310   - lcdc_write(p, _LDCNT1R, 0);
  1283 + lcdc_write(priv, _LDCNT1R, 0);
  1284 +
1311 1285 return 0;
1312 1286 }
1313 1287  
1314 1288 static int sh_mobile_lcdc_runtime_resume(struct device *dev)
1315 1289 {
1316 1290 struct platform_device *pdev = to_platform_device(dev);
1317   - struct sh_mobile_lcdc_priv *p = platform_get_drvdata(pdev);
1318   - struct sh_mobile_lcdc_chan *ch;
1319   - int k, n;
  1291 + struct sh_mobile_lcdc_priv *priv = platform_get_drvdata(pdev);
1320 1292  
1321   - /* restore per-channel registers */
1322   - for (k = 0; k < ARRAY_SIZE(p->ch); k++) {
1323   - ch = &p->ch[k];
1324   - if (!ch->enabled)
1325   - continue;
1326   - for (n = 0; n < NR_CH_REGS; n++)
1327   - lcdc_write_chan(ch, n, ch->saved_ch_regs[n]);
1328   - }
1329   -
1330   - /* restore shared registers */
1331   - for (n = 0; n < NR_SHARED_REGS; n++)
1332   - lcdc_write(p, lcdc_shared_regs[n], p->saved_shared_regs[n]);
  1293 + __sh_mobile_lcdc_start(priv);
1333 1294  
1334 1295 return 0;
1335 1296 }
drivers/video/sh_mobile_lcdcfb.h
... ... @@ -32,7 +32,6 @@
32 32 unsigned long enabled; /* ME and SE in LDCNT2R */
33 33 struct sh_mobile_lcdc_chan_cfg cfg;
34 34 u32 pseudo_palette[PALETTE_NR];
35   - unsigned long saved_ch_regs[NR_CH_REGS];
36 35 struct fb_info *info;
37 36 struct backlight_device *bl;
38 37 dma_addr_t dma_handle;