aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Vasut <marex@denx.de>2013-03-18 14:24:02 -0400
committerShawn Guo <shawn.guo@linaro.org>2013-03-18 23:07:58 -0400
commit6a15075eced2d780fa6c5d83682410f47f2e800b (patch)
treeea7322920030c516a4757a8f4d22eda2ddf6fc75
parenta937536b868b8369b98967929045f1df54234323 (diff)
ARM: video: mxs: Fix mxsfb misconfiguring VDCTRL0
The issue fixed by this patch manifests only then using X11 with mxsfb driver. The X11 will display either shifted image or otherwise distorted image on the LCD. The problem is that the X11 tries to reconfigure the framebuffer and along the way calls fb_ops.fb_set_par() with X11's desired configuration values. The field of particular interest is fb_info->var.sync which contains non-standard values if configured by kernel. These are either FB_SYNC_DATA_ENABLE_HIGH_ACT, FB_SYNC_DOTCLK_FAILING_ACT or both, depending on the platform configuration. Both of these values are defined in the include/linux/mxsfb.h file. The driver interprets these values and configures the LCD controller accordingly. Yet X11 only has access to the standard values for this field defined in include/uapi/linux/fb.h and thus, unlike kernel, omits these special values. This results in distorted image on the LCD. This patch moves these non-standard values into new field of the mxsfb_platform_data structure so the driver can in turn check this field instead of the video mode field for these specific portions. Moreover, this patch prefixes these values with MXSFB_SYNC_ prefix instead of FB_SYNC_ prefix to prevent confusion of subsequent users. Signed-off-by: Marek Vasut <marex@denx.de> Cc: Fabio Estevam <fabio.estevam@freescale.com> Cc: Linux ARM <linux-arm-kernel@lists.infradead.org> Cc: Linux FBDEV <linux-fbdev@vger.kernel.org> Cc: Lothar Waßmann <LW@karo-electronics.de> Cc: Sascha Hauer <kernel@pengutronix.de> Tested-by: Fabio Estevam <fabio.estevam@freescale.com> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
-rw-r--r--arch/arm/mach-mxs/mach-mxs.c24
-rw-r--r--drivers/video/mxsfb.c7
-rw-r--r--include/linux/mxsfb.h7
3 files changed, 22 insertions, 16 deletions
diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c
index 3218f1f2c0e0..e7b781d3788f 100644
--- a/arch/arm/mach-mxs/mach-mxs.c
+++ b/arch/arm/mach-mxs/mach-mxs.c
@@ -41,8 +41,6 @@ static struct fb_videomode mx23evk_video_modes[] = {
41 .lower_margin = 4, 41 .lower_margin = 4,
42 .hsync_len = 1, 42 .hsync_len = 1,
43 .vsync_len = 1, 43 .vsync_len = 1,
44 .sync = FB_SYNC_DATA_ENABLE_HIGH_ACT |
45 FB_SYNC_DOTCLK_FAILING_ACT,
46 }, 44 },
47}; 45};
48 46
@@ -59,8 +57,6 @@ static struct fb_videomode mx28evk_video_modes[] = {
59 .lower_margin = 10, 57 .lower_margin = 10,
60 .hsync_len = 10, 58 .hsync_len = 10,
61 .vsync_len = 10, 59 .vsync_len = 10,
62 .sync = FB_SYNC_DATA_ENABLE_HIGH_ACT |
63 FB_SYNC_DOTCLK_FAILING_ACT,
64 }, 60 },
65}; 61};
66 62
@@ -77,7 +73,6 @@ static struct fb_videomode m28evk_video_modes[] = {
77 .lower_margin = 45, 73 .lower_margin = 45,
78 .hsync_len = 1, 74 .hsync_len = 1,
79 .vsync_len = 1, 75 .vsync_len = 1,
80 .sync = FB_SYNC_DATA_ENABLE_HIGH_ACT,
81 }, 76 },
82}; 77};
83 78
@@ -94,9 +89,7 @@ static struct fb_videomode apx4devkit_video_modes[] = {
94 .lower_margin = 13, 89 .lower_margin = 13,
95 .hsync_len = 48, 90 .hsync_len = 48,
96 .vsync_len = 3, 91 .vsync_len = 3,
97 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | 92 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
98 FB_SYNC_DATA_ENABLE_HIGH_ACT |
99 FB_SYNC_DOTCLK_FAILING_ACT,
100 }, 93 },
101}; 94};
102 95
@@ -113,9 +106,7 @@ static struct fb_videomode apf28dev_video_modes[] = {
113 .lower_margin = 0x15, 106 .lower_margin = 0x15,
114 .hsync_len = 64, 107 .hsync_len = 64,
115 .vsync_len = 4, 108 .vsync_len = 4,
116 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | 109 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
117 FB_SYNC_DATA_ENABLE_HIGH_ACT |
118 FB_SYNC_DOTCLK_FAILING_ACT,
119 }, 110 },
120}; 111};
121 112
@@ -132,7 +123,6 @@ static struct fb_videomode cfa10049_video_modes[] = {
132 .lower_margin = 2, 123 .lower_margin = 2,
133 .hsync_len = 15, 124 .hsync_len = 15,
134 .vsync_len = 15, 125 .vsync_len = 15,
135 .sync = FB_SYNC_DATA_ENABLE_HIGH_ACT
136 }, 126 },
137}; 127};
138 128
@@ -259,6 +249,8 @@ static void __init imx23_evk_init(void)
259 mxsfb_pdata.mode_count = ARRAY_SIZE(mx23evk_video_modes); 249 mxsfb_pdata.mode_count = ARRAY_SIZE(mx23evk_video_modes);
260 mxsfb_pdata.default_bpp = 32; 250 mxsfb_pdata.default_bpp = 32;
261 mxsfb_pdata.ld_intf_width = STMLCDIF_24BIT; 251 mxsfb_pdata.ld_intf_width = STMLCDIF_24BIT;
252 mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT |
253 MXSFB_SYNC_DOTCLK_FAILING_ACT;
262} 254}
263 255
264static inline void enable_clk_enet_out(void) 256static inline void enable_clk_enet_out(void)
@@ -278,6 +270,8 @@ static void __init imx28_evk_init(void)
278 mxsfb_pdata.mode_count = ARRAY_SIZE(mx28evk_video_modes); 270 mxsfb_pdata.mode_count = ARRAY_SIZE(mx28evk_video_modes);
279 mxsfb_pdata.default_bpp = 32; 271 mxsfb_pdata.default_bpp = 32;
280 mxsfb_pdata.ld_intf_width = STMLCDIF_24BIT; 272 mxsfb_pdata.ld_intf_width = STMLCDIF_24BIT;
273 mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT |
274 MXSFB_SYNC_DOTCLK_FAILING_ACT;
281 275
282 mxs_saif_clkmux_select(MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0); 276 mxs_saif_clkmux_select(MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0);
283} 277}
@@ -297,6 +291,7 @@ static void __init m28evk_init(void)
297 mxsfb_pdata.mode_count = ARRAY_SIZE(m28evk_video_modes); 291 mxsfb_pdata.mode_count = ARRAY_SIZE(m28evk_video_modes);
298 mxsfb_pdata.default_bpp = 16; 292 mxsfb_pdata.default_bpp = 16;
299 mxsfb_pdata.ld_intf_width = STMLCDIF_18BIT; 293 mxsfb_pdata.ld_intf_width = STMLCDIF_18BIT;
294 mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT;
300} 295}
301 296
302static void __init sc_sps1_init(void) 297static void __init sc_sps1_init(void)
@@ -322,6 +317,8 @@ static void __init apx4devkit_init(void)
322 mxsfb_pdata.mode_count = ARRAY_SIZE(apx4devkit_video_modes); 317 mxsfb_pdata.mode_count = ARRAY_SIZE(apx4devkit_video_modes);
323 mxsfb_pdata.default_bpp = 32; 318 mxsfb_pdata.default_bpp = 32;
324 mxsfb_pdata.ld_intf_width = STMLCDIF_24BIT; 319 mxsfb_pdata.ld_intf_width = STMLCDIF_24BIT;
320 mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT |
321 MXSFB_SYNC_DOTCLK_FAILING_ACT;
325} 322}
326 323
327#define ENET0_MDC__GPIO_4_0 MXS_GPIO_NR(4, 0) 324#define ENET0_MDC__GPIO_4_0 MXS_GPIO_NR(4, 0)
@@ -407,6 +404,7 @@ static void __init cfa10049_init(void)
407 mxsfb_pdata.mode_count = ARRAY_SIZE(cfa10049_video_modes); 404 mxsfb_pdata.mode_count = ARRAY_SIZE(cfa10049_video_modes);
408 mxsfb_pdata.default_bpp = 32; 405 mxsfb_pdata.default_bpp = 32;
409 mxsfb_pdata.ld_intf_width = STMLCDIF_18BIT; 406 mxsfb_pdata.ld_intf_width = STMLCDIF_18BIT;
407 mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT;
410} 408}
411 409
412static void __init cfa10037_init(void) 410static void __init cfa10037_init(void)
@@ -423,6 +421,8 @@ static void __init apf28_init(void)
423 mxsfb_pdata.mode_count = ARRAY_SIZE(apf28dev_video_modes); 421 mxsfb_pdata.mode_count = ARRAY_SIZE(apf28dev_video_modes);
424 mxsfb_pdata.default_bpp = 16; 422 mxsfb_pdata.default_bpp = 16;
425 mxsfb_pdata.ld_intf_width = STMLCDIF_16BIT; 423 mxsfb_pdata.ld_intf_width = STMLCDIF_16BIT;
424 mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT |
425 MXSFB_SYNC_DOTCLK_FAILING_ACT;
426} 426}
427 427
428static void __init mxs_machine_init(void) 428static void __init mxs_machine_init(void)
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c
index 755556ca5b2d..45169cbaba6e 100644
--- a/drivers/video/mxsfb.c
+++ b/drivers/video/mxsfb.c
@@ -169,6 +169,7 @@ struct mxsfb_info {
169 unsigned dotclk_delay; 169 unsigned dotclk_delay;
170 const struct mxsfb_devdata *devdata; 170 const struct mxsfb_devdata *devdata;
171 int mapped; 171 int mapped;
172 u32 sync;
172}; 173};
173 174
174#define mxsfb_is_v3(host) (host->devdata->ipversion == 3) 175#define mxsfb_is_v3(host) (host->devdata->ipversion == 3)
@@ -456,9 +457,9 @@ static int mxsfb_set_par(struct fb_info *fb_info)
456 vdctrl0 |= VDCTRL0_HSYNC_ACT_HIGH; 457 vdctrl0 |= VDCTRL0_HSYNC_ACT_HIGH;
457 if (fb_info->var.sync & FB_SYNC_VERT_HIGH_ACT) 458 if (fb_info->var.sync & FB_SYNC_VERT_HIGH_ACT)
458 vdctrl0 |= VDCTRL0_VSYNC_ACT_HIGH; 459 vdctrl0 |= VDCTRL0_VSYNC_ACT_HIGH;
459 if (fb_info->var.sync & FB_SYNC_DATA_ENABLE_HIGH_ACT) 460 if (host->sync & MXSFB_SYNC_DATA_ENABLE_HIGH_ACT)
460 vdctrl0 |= VDCTRL0_ENABLE_ACT_HIGH; 461 vdctrl0 |= VDCTRL0_ENABLE_ACT_HIGH;
461 if (fb_info->var.sync & FB_SYNC_DOTCLK_FAILING_ACT) 462 if (host->sync & MXSFB_SYNC_DOTCLK_FAILING_ACT)
462 vdctrl0 |= VDCTRL0_DOTCLK_ACT_FAILING; 463 vdctrl0 |= VDCTRL0_DOTCLK_ACT_FAILING;
463 464
464 writel(vdctrl0, host->base + LCDC_VDCTRL0); 465 writel(vdctrl0, host->base + LCDC_VDCTRL0);
@@ -861,6 +862,8 @@ static int mxsfb_probe(struct platform_device *pdev)
861 862
862 INIT_LIST_HEAD(&fb_info->modelist); 863 INIT_LIST_HEAD(&fb_info->modelist);
863 864
865 host->sync = pdata->sync;
866
864 ret = mxsfb_init_fbinfo(host); 867 ret = mxsfb_init_fbinfo(host);
865 if (ret != 0) 868 if (ret != 0)
866 goto error_init_fb; 869 goto error_init_fb;
diff --git a/include/linux/mxsfb.h b/include/linux/mxsfb.h
index f14943d55315..f80af8674342 100644
--- a/include/linux/mxsfb.h
+++ b/include/linux/mxsfb.h
@@ -24,8 +24,8 @@
24#define STMLCDIF_18BIT 2 /** pixel data bus to the display is of 18 bit width */ 24#define STMLCDIF_18BIT 2 /** pixel data bus to the display is of 18 bit width */
25#define STMLCDIF_24BIT 3 /** pixel data bus to the display is of 24 bit width */ 25#define STMLCDIF_24BIT 3 /** pixel data bus to the display is of 24 bit width */
26 26
27#define FB_SYNC_DATA_ENABLE_HIGH_ACT (1 << 6) 27#define MXSFB_SYNC_DATA_ENABLE_HIGH_ACT (1 << 6)
28#define FB_SYNC_DOTCLK_FAILING_ACT (1 << 7) /* failing/negtive edge sampling */ 28#define MXSFB_SYNC_DOTCLK_FAILING_ACT (1 << 7) /* failing/negtive edge sampling */
29 29
30struct mxsfb_platform_data { 30struct mxsfb_platform_data {
31 struct fb_videomode *mode_list; 31 struct fb_videomode *mode_list;
@@ -44,6 +44,9 @@ struct mxsfb_platform_data {
44 * allocated. If specified,fb_size must also be specified. 44 * allocated. If specified,fb_size must also be specified.
45 * fb_phys must be unused by Linux. 45 * fb_phys must be unused by Linux.
46 */ 46 */
47 u32 sync; /* sync mask, contains MXSFB specifics not
48 * carried in fb_info->var.sync
49 */
47}; 50};
48 51
49#endif /* __LINUX_MXSFB_H */ 52#endif /* __LINUX_MXSFB_H */