diff options
-rw-r--r-- | drivers/video/fbdev/amba-clcd.c | 8 | ||||
-rw-r--r-- | include/linux/amba/clcd.h | 18 |
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 | ||
113 | struct clcd_regs { | 119 | struct 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) { |