diff --git a/sys/arm/broadcom/bcm2835/bcm2835_fbd.c b/sys/arm/broadcom/bcm2835/bcm2835_fbd.c --- a/sys/arm/broadcom/bcm2835/bcm2835_fbd.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_fbd.c @@ -137,12 +137,12 @@ if (sc->fbswap) { switch (sc->info.fb_bpp) { case 24: - vt_generate_cons_palette(sc->info.fb_cmap, + vt_config_cons_colors(&sc->info, COLOR_FORMAT_RGB, 0xff, 0, 0xff, 8, 0xff, 16); sc->info.fb_cmsize = 16; break; case 32: - vt_generate_cons_palette(sc->info.fb_cmap, + vt_config_cons_colors(&sc->info, COLOR_FORMAT_RGB, 0xff, 16, 0xff, 8, 0xff, 0); sc->info.fb_cmsize = 16; break; diff --git a/sys/arm/freescale/imx/imx51_ipuv3_fbd.c b/sys/arm/freescale/imx/imx51_ipuv3_fbd.c --- a/sys/arm/freescale/imx/imx51_ipuv3_fbd.c +++ b/sys/arm/freescale/imx/imx51_ipuv3_fbd.c @@ -156,22 +156,22 @@ /* Use own color map, because of different RGB offset. */ static int -ipu3_fb_init_cmap(uint32_t *cmap, int bytespp) +ipu3_fb_init_colors(struct fb_info *info) { - switch (bytespp) { + switch (info->fb_depth) { case 8: - return (vt_generate_cons_palette(cmap, COLOR_FORMAT_RGB, + return (vt_config_cons_colors(info, COLOR_FORMAT_RGB, 0x7, 5, 0x7, 2, 0x3, 0)); case 15: - return (vt_generate_cons_palette(cmap, COLOR_FORMAT_RGB, + return (vt_config_cons_colors(info, COLOR_FORMAT_RGB, 0x1f, 10, 0x1f, 5, 0x1f, 0)); case 16: - return (vt_generate_cons_palette(cmap, COLOR_FORMAT_RGB, + return (vt_config_cons_colors(info, COLOR_FORMAT_RGB, 0x1f, 11, 0x3f, 5, 0x1f, 0)); case 24: case 32: /* Ignore alpha. */ - return (vt_generate_cons_palette(cmap, COLOR_FORMAT_RGB, + return (vt_config_cons_colors(info, COLOR_FORMAT_RGB, 0xff, 0, 0xff, 8, 0xff, 16)); default: return (1); @@ -303,7 +303,7 @@ sc->sc_info.fb_name = device_get_nameunit(dev); - ipu3_fb_init_cmap(sc->sc_info.fb_cmap, sc->sc_info.fb_depth); + ipu3_fb_init_colors(&sc->sc_info); sc->sc_info.fb_cmsize = 16; /* Ask newbus to attach framebuffer device to me. */ diff --git a/sys/dev/vt/colors/vt_termcolors.h b/sys/dev/vt/colors/vt_termcolors.h --- a/sys/dev/vt/colors/vt_termcolors.h +++ b/sys/dev/vt/colors/vt_termcolors.h @@ -30,6 +30,8 @@ * $FreeBSD$ */ +struct fb_info; + enum vt_color_format { COLOR_FORMAT_BW = 0, COLOR_FORMAT_GRAY, @@ -57,6 +59,6 @@ 8, 12, 10, 14, 9, 13, 11, 15 }; -/* Helper to fill color map used by driver */ -int vt_generate_cons_palette(uint32_t *palette, int format, uint32_t rmax, +/* Helper to fill color map and set RGB offsets used by driver */ +int vt_config_cons_colors(struct fb_info *info, int format, uint32_t rmax, int roffset, uint32_t gmax, int goffset, uint32_t bmax, int boffset); diff --git a/sys/dev/vt/colors/vt_termcolors.c b/sys/dev/vt/colors/vt_termcolors.c --- a/sys/dev/vt/colors/vt_termcolors.c +++ b/sys/dev/vt/colors/vt_termcolors.c @@ -34,6 +34,7 @@ #include #include #include +#include #include @@ -152,7 +153,7 @@ } } -int +static int vt_generate_cons_palette(uint32_t *palette, int format, uint32_t rmax, int roffset, uint32_t gmax, int goffset, uint32_t bmax, int boffset) { @@ -176,3 +177,18 @@ return (0); } + +int +vt_config_cons_colors(struct fb_info *info, int format, uint32_t rmax, + int roffset, uint32_t gmax, int goffset, uint32_t bmax, int boffset) +{ + if (format == COLOR_FORMAT_RGB) { + info->fb_rgboffs.red = roffset; + info->fb_rgboffs.green = goffset; + info->fb_rgboffs.blue = boffset; + } else + memset(&info->fb_rgboffs, 0, sizeof(info->fb_rgboffs)); + + return (vt_generate_cons_palette(info->fb_cmap, format, rmax, + roffset, gmax, goffset, bmax, boffset)); +} diff --git a/sys/dev/vt/hw/efifb/efifb.c b/sys/dev/vt/hw/efifb/efifb.c --- a/sys/dev/vt/hw/efifb/efifb.c +++ b/sys/dev/vt/hw/efifb/efifb.c @@ -131,7 +131,7 @@ roff = ffs(efifb->fb_mask_red) - 1; goff = ffs(efifb->fb_mask_green) - 1; boff = ffs(efifb->fb_mask_blue) - 1; - vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB, + vt_config_cons_colors(info, COLOR_FORMAT_RGB, efifb->fb_mask_red >> roff, roff, efifb->fb_mask_green >> goff, goff, efifb->fb_mask_blue >> boff, boff); diff --git a/sys/dev/vt/hw/fb/vt_early_fb.c b/sys/dev/vt/hw/fb/vt_early_fb.c --- a/sys/dev/vt/hw/fb/vt_early_fb.c +++ b/sys/dev/vt/hw/fb/vt_early_fb.c @@ -93,24 +93,24 @@ */ switch (info->fb_depth) { case 8: - vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB, + vt_config_cons_colors(info, COLOR_FORMAT_RGB, 0x7, 5, 0x7, 2, 0x3, 0); break; case 15: - vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB, + vt_config_cons_colors(info, COLOR_FORMAT_RGB, 0x1f, 10, 0x1f, 5, 0x1f, 0); break; case 16: - vt_generate_cons_palette(info->fb_cmap, COLOR_FORMAT_RGB, + vt_config_cons_colors(info, COLOR_FORMAT_RGB, 0x1f, 11, 0x3f, 5, 0x1f, 0); break; case 24: case 32: #if BYTE_ORDER == BIG_ENDIAN - vt_generate_cons_palette(info->fb_cmap, + vt_config_cons_colors(info, COLOR_FORMAT_RGB, 255, 0, 255, 8, 255, 16); #else - vt_generate_cons_palette(info->fb_cmap, + vt_config_cons_colors(info, COLOR_FORMAT_RGB, 255, 16, 255, 8, 255, 0); #endif #ifdef FDT diff --git a/sys/dev/vt/hw/fb/vt_fb.c b/sys/dev/vt/hw/fb/vt_fb.c --- a/sys/dev/vt/hw/fb/vt_fb.c +++ b/sys/dev/vt/hw/fb/vt_fb.c @@ -120,6 +120,14 @@ vd->vd_driver->vd_blank(vd, TC_BLACK); break; + case FBIO_GETRGBOFFS: /* get RGB offsets */ + if (info->fb_rgboffs.red == 0 && info->fb_rgboffs.green == 0 && + info->fb_rgboffs.blue == 0) + return (ENOTTY); + memcpy((struct fb_rgboffs *)data, &info->fb_rgboffs, + sizeof(struct fb_rgboffs)); + break; + default: error = ENOIOCTL; break; @@ -432,22 +440,22 @@ } static int -vt_fb_init_cmap(uint32_t *cmap, int depth) +vt_fb_init_colors(struct fb_info *info) { - switch (depth) { + switch (FBTYPE_GET_BPP(info)) { case 8: - return (vt_generate_cons_palette(cmap, COLOR_FORMAT_RGB, + return (vt_config_cons_colors(info, COLOR_FORMAT_RGB, 0x7, 5, 0x7, 2, 0x3, 0)); case 15: - return (vt_generate_cons_palette(cmap, COLOR_FORMAT_RGB, + return (vt_config_cons_colors(info, COLOR_FORMAT_RGB, 0x1f, 10, 0x1f, 5, 0x1f, 0)); case 16: - return (vt_generate_cons_palette(cmap, COLOR_FORMAT_RGB, + return (vt_config_cons_colors(info, COLOR_FORMAT_RGB, 0x1f, 11, 0x3f, 5, 0x1f, 0)); case 24: case 32: /* Ignore alpha. */ - return (vt_generate_cons_palette(cmap, COLOR_FORMAT_RGB, + return (vt_config_cons_colors(info, COLOR_FORMAT_RGB, 0xff, 16, 0xff, 8, 0xff, 0)); default: return (1); @@ -478,7 +486,7 @@ info->fb_flags |= FB_FLAG_NOMMAP; if (info->fb_cmsize <= 0) { - err = vt_fb_init_cmap(info->fb_cmap, FBTYPE_GET_BPP(info)); + err = vt_fb_init_colors(info); if (err) return (CN_DEAD); info->fb_cmsize = 16; diff --git a/sys/dev/vt/hw/ofwfb/ofwfb.c b/sys/dev/vt/hw/ofwfb/ofwfb.c --- a/sys/dev/vt/hw/ofwfb/ofwfb.c +++ b/sys/dev/vt/hw/ofwfb/ofwfb.c @@ -400,7 +400,7 @@ ofwfb_initialize(struct vt_device *vd) { struct ofwfb_softc *sc = vd->vd_softc; - int i, err; + int i, err, r, g, b; cell_t retval; sc->fb.fb_cmsize = 16; @@ -419,7 +419,7 @@ * No color format issues here, since we are passing the RGB * components separately to Open Firmware. */ - vt_generate_cons_palette(sc->fb.fb_cmap, COLOR_FORMAT_RGB, 255, + vt_config_cons_colors(&sc->fb, COLOR_FORMAT_RGB, 255, 16, 255, 8, 255, 0); for (i = 0; i < 16; i++) { @@ -457,19 +457,17 @@ TUNABLE_INT_FETCH("hw.ofwfb.argb32_pixel", &sc->argb); if (sc->endian_flip) { if (sc->argb) - vt_generate_cons_palette(sc->fb.fb_cmap, - COLOR_FORMAT_RGB, 255, 8, 255, 16, 255, 24); + r = 8, g = 16, b = 24; else - vt_generate_cons_palette(sc->fb.fb_cmap, - COLOR_FORMAT_RGB, 255, 24, 255, 16, 255, 8); + r = 24, g = 16, b = 8; } else { if (sc->argb) - vt_generate_cons_palette(sc->fb.fb_cmap, - COLOR_FORMAT_RGB, 255, 16, 255, 8, 255, 0); + r = 16, g = 8, b = 0; else - vt_generate_cons_palette(sc->fb.fb_cmap, - COLOR_FORMAT_RGB, 255, 0, 255, 8, 255, 16); + r = 0, g = 8, b = 16; } + vt_config_cons_colors(&sc->fb, + COLOR_FORMAT_RGB, 255, r, 255, g, 255, b); break; default: diff --git a/sys/dev/vt/hw/vbefb/vbefb.c b/sys/dev/vt/hw/vbefb/vbefb.c --- a/sys/dev/vt/hw/vbefb/vbefb.c +++ b/sys/dev/vt/hw/vbefb/vbefb.c @@ -135,7 +135,7 @@ roff = ffs(vbefb->fb_mask_red) - 1; goff = ffs(vbefb->fb_mask_green) - 1; boff = ffs(vbefb->fb_mask_blue) - 1; - vt_generate_cons_palette(info->fb_cmap, format, + vt_config_cons_colors(info, format, vbefb->fb_mask_red >> roff, roff, vbefb->fb_mask_green >> goff, goff, vbefb->fb_mask_blue >> boff, boff); diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c --- a/sys/dev/vt/vt_core.c +++ b/sys/dev/vt/vt_core.c @@ -2559,6 +2559,7 @@ case FBIO_GETDISPSTART: /* get display start address */ case FBIO_GETLINEWIDTH: /* get scan line width in bytes */ case FBIO_BLANK: /* blank display */ + case FBIO_GETRGBOFFS: /* get RGB offsets */ if (vd->vd_driver->vd_fb_ioctl) return (vd->vd_driver->vd_fb_ioctl(vd, cmd, data, td)); break; diff --git a/sys/powerpc/ps3/ps3_syscons.c b/sys/powerpc/ps3/ps3_syscons.c --- a/sys/powerpc/ps3/ps3_syscons.c +++ b/sys/powerpc/ps3/ps3_syscons.c @@ -228,7 +228,7 @@ sc->fb_info.fb_cmsize = 16; /* 32-bit VGA palette */ - vt_generate_cons_palette(sc->fb_info.fb_cmap, COLOR_FORMAT_RGB, + vt_config_cons_colors(&sc->fb_info, COLOR_FORMAT_RGB, 255, 16, 255, 8, 255, 0); /* Set correct graphics context */ diff --git a/sys/sys/fbio.h b/sys/sys/fbio.h --- a/sys/sys/fbio.h +++ b/sys/sys/fbio.h @@ -110,6 +110,15 @@ #define FBTYPE_GET_BPP(_fb) ((_fb)->fb_bpp) #define FBTYPE_GET_BYTESPP(_fb) ((_fb)->fb_bpp / 8) +/* + * RGB offsets as returned by FBIO_GETRGBOFFS. + */ +struct fb_rgboffs { + int red; + int green; + int blue; +}; + #ifdef _KERNEL struct fb_info; @@ -148,6 +157,8 @@ int fb_stride; int fb_bpp; /* bits per pixel */ uint32_t fb_cmap[16]; + + struct fb_rgboffs fb_rgboffs; /* RGB offsets */ }; int fbd_list(void); @@ -619,4 +630,7 @@ #define FBIO_BLANK _IOW('F', 115, int) +/* get RGB offsets */ +#define FBIO_GETRGBOFFS _IOR('F', 116, struct fb_rgboffs) + #endif /* !_SYS_FBIO_H_ */