vt: export RGB offsets with FBIO_GETRGBOFFS
Add a new ioctl to vt to make it possible to export RGB offsets set by vt drivers. This is needed to fix colors on X and Mesa on some machines, especially on modern PowerPC64 BE ones. With the appropriate changes in SCFB, to use this ioctl to find out the correct RGB offsets, this fixes wrong colors on Talos II and Blackbird, when used with their built-in video cards. Reviewed by: alfredo Sponsored by: Instituto de Pesquisas Eldorado (eldorado.org.br) Differential Revision: https://reviews.freebsd.org/D29000
This commit is contained in:
parent
b19740f4ce
commit
b9f3b63ab2
@ -137,12 +137,12 @@ bcm_fb_setup_fbd(struct bcmsc_softc *sc)
|
||||
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;
|
||||
|
@ -156,22 +156,22 @@ ipu3_fb_init(struct ipu3sc_softc *sc)
|
||||
|
||||
/* 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 @@ ipu3_fb_attach(device_t dev)
|
||||
|
||||
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. */
|
||||
|
@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/libkern.h>
|
||||
#include <sys/fbio.h>
|
||||
|
||||
#include <dev/vt/colors/vt_termcolors.h>
|
||||
|
||||
@ -152,7 +153,7 @@ vt_palette_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ vt_generate_cons_palette(uint32_t *palette, int format, uint32_t rmax,
|
||||
|
||||
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));
|
||||
}
|
||||
|
@ -30,6 +30,8 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
struct fb_info;
|
||||
|
||||
enum vt_color_format {
|
||||
COLOR_FORMAT_BW = 0,
|
||||
COLOR_FORMAT_GRAY,
|
||||
@ -57,6 +59,6 @@ static const int cons_to_vga_colors[NCOLORS] = {
|
||||
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);
|
||||
|
@ -131,7 +131,7 @@ vt_efifb_init(struct vt_device *vd)
|
||||
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);
|
||||
|
@ -93,24 +93,24 @@ vt_efb_initialize(struct fb_info *info)
|
||||
*/
|
||||
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
|
||||
|
@ -120,6 +120,14 @@ vt_fb_ioctl(struct vt_device *vd, u_long cmd, caddr_t data, struct thread *td)
|
||||
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 @@ vt_fb_postswitch(struct vt_device *vd)
|
||||
}
|
||||
|
||||
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 @@ vt_fb_init(struct vt_device *vd)
|
||||
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;
|
||||
|
@ -400,7 +400,7 @@ static void
|
||||
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 @@ ofwfb_initialize(struct vt_device *vd)
|
||||
* 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 @@ ofwfb_initialize(struct vt_device *vd)
|
||||
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:
|
||||
|
@ -135,7 +135,7 @@ vt_vbefb_init(struct vt_device *vd)
|
||||
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);
|
||||
|
@ -2559,6 +2559,7 @@ vtterm_ioctl(struct terminal *tm, u_long cmd, caddr_t data,
|
||||
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;
|
||||
|
@ -228,7 +228,7 @@ ps3fb_init(struct vt_device *vd)
|
||||
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 */
|
||||
|
@ -110,6 +110,15 @@ struct fbtype {
|
||||
#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 @@ struct fb_info {
|
||||
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 @@ typedef struct video_color_palette video_color_palette_t;
|
||||
|
||||
#define FBIO_BLANK _IOW('F', 115, int)
|
||||
|
||||
/* get RGB offsets */
|
||||
#define FBIO_GETRGBOFFS _IOR('F', 116, struct fb_rgboffs)
|
||||
|
||||
#endif /* !_SYS_FBIO_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user