aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorLeandro Lupori <luporl@FreeBSD.org>2021-11-25 18:54:11 +0000
committerLeandro Lupori <luporl@FreeBSD.org>2021-11-25 19:39:25 +0000
commitb9f3b63ab21ed5d1288de1acff511eb733201139 (patch)
tree9fb18ee9c34c0b60fd1ddfcf3f74ff867e587f99 /sys
parentb19740f4ce7a542783f87de2fee48476a7801d86 (diff)
downloadsrc-b9f3b63ab21ed5d1288de1acff511eb733201139.tar.gz
src-b9f3b63ab21ed5d1288de1acff511eb733201139.zip
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
Diffstat (limited to 'sys')
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_fbd.c4
-rw-r--r--sys/arm/freescale/imx/imx51_ipuv3_fbd.c14
-rw-r--r--sys/dev/vt/colors/vt_termcolors.c18
-rw-r--r--sys/dev/vt/colors/vt_termcolors.h6
-rw-r--r--sys/dev/vt/hw/efifb/efifb.c2
-rw-r--r--sys/dev/vt/hw/fb/vt_early_fb.c10
-rw-r--r--sys/dev/vt/hw/fb/vt_fb.c22
-rw-r--r--sys/dev/vt/hw/ofwfb/ofwfb.c18
-rw-r--r--sys/dev/vt/hw/vbefb/vbefb.c2
-rw-r--r--sys/dev/vt/vt_core.c1
-rw-r--r--sys/powerpc/ps3/ps3_syscons.c2
-rw-r--r--sys/sys/fbio.h14
12 files changed, 76 insertions, 37 deletions
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_fbd.c b/sys/arm/broadcom/bcm2835/bcm2835_fbd.c
index 93849b3551d9..c148235e5c33 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_fbd.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_fbd.c
@@ -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;
diff --git a/sys/arm/freescale/imx/imx51_ipuv3_fbd.c b/sys/arm/freescale/imx/imx51_ipuv3_fbd.c
index 644664fa8aa3..be1526228bf4 100644
--- a/sys/arm/freescale/imx/imx51_ipuv3_fbd.c
+++ b/sys/arm/freescale/imx/imx51_ipuv3_fbd.c
@@ -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. */
diff --git a/sys/dev/vt/colors/vt_termcolors.c b/sys/dev/vt/colors/vt_termcolors.c
index dff276a86100..fe340eeae518 100644
--- a/sys/dev/vt/colors/vt_termcolors.c
+++ b/sys/dev/vt/colors/vt_termcolors.c
@@ -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));
+}
diff --git a/sys/dev/vt/colors/vt_termcolors.h b/sys/dev/vt/colors/vt_termcolors.h
index 3fc99ee9743f..32521eebaf31 100644
--- 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 @@ 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);
diff --git a/sys/dev/vt/hw/efifb/efifb.c b/sys/dev/vt/hw/efifb/efifb.c
index e4deb1b9d9e5..de361ea45b97 100644
--- a/sys/dev/vt/hw/efifb/efifb.c
+++ b/sys/dev/vt/hw/efifb/efifb.c
@@ -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);
diff --git a/sys/dev/vt/hw/fb/vt_early_fb.c b/sys/dev/vt/hw/fb/vt_early_fb.c
index 9d9635835202..e3dace2d5092 100644
--- a/sys/dev/vt/hw/fb/vt_early_fb.c
+++ b/sys/dev/vt/hw/fb/vt_early_fb.c
@@ -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
diff --git a/sys/dev/vt/hw/fb/vt_fb.c b/sys/dev/vt/hw/fb/vt_fb.c
index 2f6c4c3939d5..093bf35ac6ba 100644
--- a/sys/dev/vt/hw/fb/vt_fb.c
+++ b/sys/dev/vt/hw/fb/vt_fb.c
@@ -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;
diff --git a/sys/dev/vt/hw/ofwfb/ofwfb.c b/sys/dev/vt/hw/ofwfb/ofwfb.c
index e388356450d6..4f24c471be1b 100644
--- a/sys/dev/vt/hw/ofwfb/ofwfb.c
+++ b/sys/dev/vt/hw/ofwfb/ofwfb.c
@@ -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:
diff --git a/sys/dev/vt/hw/vbefb/vbefb.c b/sys/dev/vt/hw/vbefb/vbefb.c
index 2e8fe8330e56..569a40eb7d95 100644
--- a/sys/dev/vt/hw/vbefb/vbefb.c
+++ b/sys/dev/vt/hw/vbefb/vbefb.c
@@ -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);
diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c
index 0fab05ff4096..4ce3a48be288 100644
--- a/sys/dev/vt/vt_core.c
+++ b/sys/dev/vt/vt_core.c
@@ -2559,6 +2559,7 @@ skip_thunk:
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
index ed339f199746..30b6ff9bc8a2 100644
--- a/sys/powerpc/ps3/ps3_syscons.c
+++ b/sys/powerpc/ps3/ps3_syscons.c
@@ -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 */
diff --git a/sys/sys/fbio.h b/sys/sys/fbio.h
index 3b47b11345cf..c44774a766a0 100644
--- a/sys/sys/fbio.h
+++ b/sys/sys/fbio.h
@@ -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_ */