aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/fbdev/amba-clcd.c8
-rw-r--r--include/linux/amba/clcd.h18
2 files changed, 23 insertions, 3 deletions
diff --git a/drivers/video/fbdev/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c
index 5bd20e8800bc..080e8a246faf 100644
--- a/drivers/video/fbdev/amba-clcd.c
+++ b/drivers/video/fbdev/amba-clcd.c
@@ -675,6 +675,7 @@ static int clcdfb_of_init_tft_panel(struct clcd_fb *fb, u32 r0, u32 g0, u32 b0)
675 } panels[] = { 675 } panels[] = {
676 { 0x110, 1, 7, 13, CLCD_CAP_5551 }, 676 { 0x110, 1, 7, 13, CLCD_CAP_5551 },
677 { 0x110, 0, 8, 16, CLCD_CAP_888 }, 677 { 0x110, 0, 8, 16, CLCD_CAP_888 },
678 { 0x110, 16, 8, 0, CLCD_CAP_888 },
678 { 0x111, 4, 14, 20, CLCD_CAP_444 }, 679 { 0x111, 4, 14, 20, CLCD_CAP_444 },
679 { 0x111, 3, 11, 19, CLCD_CAP_444 | CLCD_CAP_5551 }, 680 { 0x111, 3, 11, 19, CLCD_CAP_444 | CLCD_CAP_5551 },
680 { 0x111, 3, 10, 19, CLCD_CAP_444 | CLCD_CAP_5551 | 681 { 0x111, 3, 10, 19, CLCD_CAP_444 | CLCD_CAP_5551 |
@@ -702,6 +703,13 @@ static int clcdfb_of_init_tft_panel(struct clcd_fb *fb, u32 r0, u32 g0, u32 b0)
702 fb->panel->caps = panels[i].caps; 703 fb->panel->caps = panels[i].caps;
703 } 704 }
704 705
706 /*
707 * If we actually physically connected the R lines to B and
708 * vice versa
709 */
710 if (r0 != 0 && b0 == 0)
711 fb->panel->bgr_connection = true;
712
705 return fb->panel->caps ? 0 : -EINVAL; 713 return fb->panel->caps ? 0 : -EINVAL;
706} 714}
707 715
diff --git a/include/linux/amba/clcd.h b/include/linux/amba/clcd.h
index e64c1ccebb76..8b64ec0d574b 100644
--- a/include/linux/amba/clcd.h
+++ b/include/linux/amba/clcd.h
@@ -108,6 +108,12 @@ struct clcd_panel {
108 grayscale:1; 108 grayscale:1;
109 unsigned int connector; 109 unsigned int connector;
110 struct backlight_device *backlight; 110 struct backlight_device *backlight;
111 /*
112 * If the B/R lines are switched between the CLCD
113 * and the panel we need to know this and not try to
114 * compensate with the BGR bit in the control register.
115 */
116 bool bgr_connection;
111}; 117};
112 118
113struct clcd_regs { 119struct clcd_regs {
@@ -234,16 +240,22 @@ static inline void clcdfb_decode(struct clcd_fb *fb, struct clcd_regs *regs)
234 if (var->grayscale) 240 if (var->grayscale)
235 val |= CNTL_LCDBW; 241 val |= CNTL_LCDBW;
236 242
237 if (fb->panel->caps && fb->board->caps && 243 if (fb->panel->caps && fb->board->caps && var->bits_per_pixel >= 16) {
238 var->bits_per_pixel >= 16) {
239 /* 244 /*
240 * if board and panel supply capabilities, we can support 245 * if board and panel supply capabilities, we can support
241 * changing BGR/RGB depending on supplied parameters 246 * changing BGR/RGB depending on supplied parameters. Here
247 * we switch to what the framebuffer is providing if need
248 * be, so if the framebuffer is BGR but the display connection
249 * is RGB (first case) we switch it around. Vice versa mutatis
250 * mutandis if the framebuffer is RGB but the display connection
251 * is BGR, we flip it around.
242 */ 252 */
243 if (var->red.offset == 0) 253 if (var->red.offset == 0)
244 val &= ~CNTL_BGR; 254 val &= ~CNTL_BGR;
245 else 255 else
246 val |= CNTL_BGR; 256 val |= CNTL_BGR;
257 if (fb->panel->bgr_connection)
258 val ^= CNTL_BGR;
247 } 259 }
248 260
249 switch (var->bits_per_pixel) { 261 switch (var->bits_per_pixel) {