Message ID | 1400073709-15012-1-git-send-email-tiwai@suse.de (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Wed, 2014-05-14 at 15:21 +0200, Takashi Iwai wrote: > case 16: /* RGB 565 */ > var->bits_per_pixel = 16; > - var->red.offset = 11; > + if (fb_be_math(info)) { > + var->red.offset = 11; > + var->green.offset = 5; > + var->blue.offset = 0; > + } else { > + var->red.offset = 0; > + var->green.offset = 5; > + var->blue.offset = 11; > + } > var->red.length = 5; > - var->green.offset = 5; > var->green.length = 6; > - var->blue.offset = 0; > var->blue.length = 5; > var->transp.offset = 0; > var->transp.length = 0; > break; I somewhat doubt that this (and 5:5:5) actually work, do they ? the green gets split into two separate fields, which we can't express properly here... Cheers, Ben. -- To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Mon, 2014-06-16 at 17:35 +1000, Benjamin Herrenschmidt wrote: > I somewhat doubt that this (and 5:5:5) actually work, do they ? the > green gets split into two separate fields, which we can't express > properly here... So the conclusion of further investigation is: - The right fix is to fix qemu to flip endian - There's an open discussion as to whether qemu could do it automatically when the guest endian changes on powerpc as a quick fix, the long run approach is to have a register to control it, I'm working on it. offb can then "learn" to flick it like it does the palette hack today. - If we want to ever support foreign endian offb with X, we need to do things a bit differently based on the foreign endian bit that is already there. - We must revert the existing cmap swap patch from the kernel, it's broken and will break things when we fix qemu (and breaks with real HW in LE mode). I've sent a revert request to Linus and CC'ed stable. Cheers, Ben. -- To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
At Tue, 17 Jun 2014 09:54:07 +1000, Benjamin Herrenschmidt wrote: > > On Mon, 2014-06-16 at 17:35 +1000, Benjamin Herrenschmidt wrote: > > > I somewhat doubt that this (and 5:5:5) actually work, do they ? the > > green gets split into two separate fields, which we can't express > > properly here... > > So the conclusion of further investigation is: > > - The right fix is to fix qemu to flip endian > > - There's an open discussion as to whether qemu could do it > automatically when the guest endian changes on powerpc as a quick fix, > the long run approach is to have a register to control it, I'm working > on it. offb can then "learn" to flick it like it does the palette hack > today. > > - If we want to ever support foreign endian offb with X, we need to do > things a bit differently based on the foreign endian bit that is already > there. > > - We must revert the existing cmap swap patch from the kernel, it's > broken and will break things when we fix qemu (and breaks with real HW > in LE mode). I've sent a revert request to Linus and CC'ed stable. Yeah, I agree. Both the current palette fix and my patch are really wrong band-aiding. (Though, the issue in X is rather a problem of X itself. X should work with the tweaked RGB offsets.) thanks, Takashi -- To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/video/fbdev/offb.c b/drivers/video/fbdev/offb.c index 7d44d669d5b6..0224a62aa49d 100644 --- a/drivers/video/fbdev/offb.c +++ b/drivers/video/fbdev/offb.c @@ -93,13 +93,6 @@ extern boot_infos_t *boot_infos; #define FB_RIGHT_POS(p, bpp) (fb_be_math(p) ? 0 : (32 - (bpp))) -static inline u32 offb_cmap_byteswap(struct fb_info *info, u32 value) -{ - u32 bpp = info->var.bits_per_pixel; - - return cpu_to_be32(value) >> FB_RIGHT_POS(info, bpp); -} - /* * Set a single color register. The values supplied are already * rounded down to the hardware's capabilities (according to the @@ -129,7 +122,7 @@ static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, mask <<= info->var.transp.offset; value |= mask; } - pal[regno] = offb_cmap_byteswap(info, value); + pal[regno] = value; return 0; } @@ -451,6 +444,8 @@ static void __init offb_init_fb(const char *name, const char *full_name, else fix->visual = FB_VISUAL_TRUECOLOR; + info->flags = FBINFO_DEFAULT | FBINFO_MISC_FIRMWARE | foreign_endian; + var->xoffset = var->yoffset = 0; switch (depth) { case 8: @@ -466,35 +461,54 @@ static void __init offb_init_fb(const char *name, const char *full_name, break; case 15: /* RGB 555 */ var->bits_per_pixel = 16; - var->red.offset = 10; + if (fb_be_math(info)) { + var->red.offset = 10; + var->green.offset = 5; + var->blue.offset = 0; + } else { + var->red.offset = 0; + var->green.offset = 5; + var->blue.offset = 10; + } var->red.length = 5; - var->green.offset = 5; var->green.length = 5; - var->blue.offset = 0; var->blue.length = 5; var->transp.offset = 0; var->transp.length = 0; break; case 16: /* RGB 565 */ var->bits_per_pixel = 16; - var->red.offset = 11; + if (fb_be_math(info)) { + var->red.offset = 11; + var->green.offset = 5; + var->blue.offset = 0; + } else { + var->red.offset = 0; + var->green.offset = 5; + var->blue.offset = 11; + } var->red.length = 5; - var->green.offset = 5; var->green.length = 6; - var->blue.offset = 0; var->blue.length = 5; var->transp.offset = 0; var->transp.length = 0; break; case 32: /* RGB 888 */ var->bits_per_pixel = 32; - var->red.offset = 16; + if (fb_be_math(info)) { + var->red.offset = 16; + var->green.offset = 8; + var->blue.offset = 0; + var->transp.offset = 24; + } else { + var->red.offset = 8; + var->green.offset = 16; + var->blue.offset = 24; + var->transp.offset = 0; + } var->red.length = 8; - var->green.offset = 8; var->green.length = 8; - var->blue.offset = 0; var->blue.length = 8; - var->transp.offset = 24; var->transp.length = 8; break; } @@ -521,7 +535,6 @@ static void __init offb_init_fb(const char *name, const char *full_name, info->fbops = &offb_ops; info->screen_base = ioremap(address, fix->smem_len); info->pseudo_palette = (void *) (info + 1); - info->flags = FBINFO_DEFAULT | FBINFO_MISC_FIRMWARE | foreign_endian; fb_alloc_cmap(&info->cmap, 256, 0);
Although the color palette was corrected for little endian by the commit [e1edf18b: offb: Add palette hack for little endian], the graphics mode is still shown in psychedelic colors. For fixing this properly, we rather need to correct the RGB offsets depending on endianess. Since the RGB base offsets are corrected, we don't need the hack for pallette color entries. This patch reverts that, too. Signed-off-by: Takashi Iwai <tiwai@suse.de> --- drivers/video/fbdev/offb.c | 51 +++++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 19 deletions(-)