mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 10:04:04 +02:00
drm/vesadrm: Use helpers for programming gamma ramps
Replace vesadrm's code for programming the hardware gamma LUT with DRM helpers. Either load a provided gamma ramp or program a default. Set the individual entries with a callback. Each gamma value is given as 3 individual 16-bit values for red, green and blue. The driver reduces them to 8 bit to make them fit into hardware registers. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://lore.kernel.org/r/20250520094203.30545-6-tzimmermann@suse.de
This commit is contained in:
parent
a4871e6201
commit
c06cb85ad1
|
|
@ -9,6 +9,7 @@
|
|||
#include <drm/clients/drm_client_setup.h>
|
||||
#include <drm/drm_atomic.h>
|
||||
#include <drm/drm_atomic_state_helper.h>
|
||||
#include <drm/drm_color_mgmt.h>
|
||||
#include <drm/drm_connector.h>
|
||||
#include <drm/drm_damage_helper.h>
|
||||
#include <drm/drm_device.h>
|
||||
|
|
@ -87,15 +88,10 @@ static struct vesadrm_device *to_vesadrm_device(struct drm_device *dev)
|
|||
static void vesadrm_vga_cmap_write(struct vesadrm_device *vesa, unsigned int index,
|
||||
u16 red, u16 green, u16 blue)
|
||||
{
|
||||
u8 i8, r8, g8, b8;
|
||||
|
||||
if (index > 255)
|
||||
return;
|
||||
|
||||
i8 = index;
|
||||
r8 = red >> 8;
|
||||
g8 = green >> 8;
|
||||
b8 = blue >> 8;
|
||||
u8 i8 = index;
|
||||
u8 r8 = red >> 8;
|
||||
u8 g8 = green >> 8;
|
||||
u8 b8 = blue >> 8;
|
||||
|
||||
outb_p(i8, VGA_PEL_IW);
|
||||
outb_p(r8, VGA_PEL_D);
|
||||
|
|
@ -120,9 +116,6 @@ static void vesadrm_pmi_cmap_write(struct vesadrm_device *vesa, unsigned int ind
|
|||
0x00,
|
||||
};
|
||||
|
||||
if (index > 255)
|
||||
return;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"call *(%%esi)"
|
||||
: /* no return value */
|
||||
|
|
@ -135,43 +128,36 @@ static void vesadrm_pmi_cmap_write(struct vesadrm_device *vesa, unsigned int ind
|
|||
}
|
||||
#endif
|
||||
|
||||
static void vesadrm_set_gamma_linear(struct vesadrm_device *vesa,
|
||||
const struct drm_format_info *format)
|
||||
static void vesadrm_set_gamma_lut(struct drm_crtc *crtc, unsigned int index,
|
||||
u16 red, u16 green, u16 blue)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct vesadrm_device *vesa = to_vesadrm_device(dev);
|
||||
u8 i8 = index & 0xff;
|
||||
|
||||
if (drm_WARN_ON_ONCE(dev, index != i8))
|
||||
return; /* driver bug */
|
||||
|
||||
vesa->cmap_write(vesa, i8, red, green, blue);
|
||||
}
|
||||
|
||||
static void vesadrm_fill_gamma_lut(struct vesadrm_device *vesa,
|
||||
const struct drm_format_info *format)
|
||||
{
|
||||
struct drm_device *dev = &vesa->sysfb.dev;
|
||||
size_t i;
|
||||
u16 r16, g16, b16;
|
||||
struct drm_crtc *crtc = &vesa->crtc;
|
||||
|
||||
switch (format->format) {
|
||||
case DRM_FORMAT_XRGB1555:
|
||||
for (i = 0; i < 32; ++i) {
|
||||
r16 = i * 8 + i / 4;
|
||||
r16 |= (r16 << 8) | r16;
|
||||
vesa->cmap_write(vesa, i, r16, r16, r16);
|
||||
}
|
||||
drm_crtc_fill_gamma_555(crtc, vesadrm_set_gamma_lut);
|
||||
break;
|
||||
case DRM_FORMAT_RGB565:
|
||||
for (i = 0; i < 32; ++i) {
|
||||
r16 = i * 8 + i / 4;
|
||||
r16 |= (r16 << 8) | r16;
|
||||
g16 = i * 4 + i / 16;
|
||||
g16 |= (g16 << 8) | g16;
|
||||
b16 = r16;
|
||||
vesa->cmap_write(vesa, i, r16, g16, b16);
|
||||
}
|
||||
for (i = 32; i < 64; ++i) {
|
||||
g16 = i * 4 + i / 16;
|
||||
g16 |= (g16 << 8) | g16;
|
||||
vesa->cmap_write(vesa, i, 0, g16, 0);
|
||||
}
|
||||
drm_crtc_fill_gamma_565(crtc, vesadrm_set_gamma_lut);
|
||||
break;
|
||||
case DRM_FORMAT_RGB888:
|
||||
case DRM_FORMAT_XRGB8888:
|
||||
case DRM_FORMAT_BGRX8888:
|
||||
for (i = 0; i < 256; ++i) {
|
||||
r16 = (i << 8) | i;
|
||||
vesa->cmap_write(vesa, i, r16, r16, r16);
|
||||
}
|
||||
drm_crtc_fill_gamma_888(crtc, vesadrm_set_gamma_lut);
|
||||
break;
|
||||
default:
|
||||
drm_warn_once(dev, "Unsupported format %p4cc for gamma correction\n",
|
||||
|
|
@ -180,38 +166,24 @@ static void vesadrm_set_gamma_linear(struct vesadrm_device *vesa,
|
|||
}
|
||||
}
|
||||
|
||||
static void vesadrm_set_gamma_lut(struct vesadrm_device *vesa,
|
||||
const struct drm_format_info *format,
|
||||
struct drm_color_lut *lut)
|
||||
static void vesadrm_load_gamma_lut(struct vesadrm_device *vesa,
|
||||
const struct drm_format_info *format,
|
||||
struct drm_color_lut *lut)
|
||||
{
|
||||
struct drm_device *dev = &vesa->sysfb.dev;
|
||||
size_t i;
|
||||
u16 r16, g16, b16;
|
||||
struct drm_crtc *crtc = &vesa->crtc;
|
||||
|
||||
switch (format->format) {
|
||||
case DRM_FORMAT_XRGB1555:
|
||||
for (i = 0; i < 32; ++i) {
|
||||
r16 = lut[i * 8 + i / 4].red;
|
||||
g16 = lut[i * 8 + i / 4].green;
|
||||
b16 = lut[i * 8 + i / 4].blue;
|
||||
vesa->cmap_write(vesa, i, r16, g16, b16);
|
||||
}
|
||||
drm_crtc_load_gamma_555_from_888(crtc, lut, vesadrm_set_gamma_lut);
|
||||
break;
|
||||
case DRM_FORMAT_RGB565:
|
||||
for (i = 0; i < 32; ++i) {
|
||||
r16 = lut[i * 8 + i / 4].red;
|
||||
g16 = lut[i * 4 + i / 16].green;
|
||||
b16 = lut[i * 8 + i / 4].blue;
|
||||
vesa->cmap_write(vesa, i, r16, g16, b16);
|
||||
}
|
||||
for (i = 32; i < 64; ++i)
|
||||
vesa->cmap_write(vesa, i, 0, lut[i * 4 + i / 16].green, 0);
|
||||
drm_crtc_load_gamma_565_from_888(crtc, lut, vesadrm_set_gamma_lut);
|
||||
break;
|
||||
case DRM_FORMAT_RGB888:
|
||||
case DRM_FORMAT_XRGB8888:
|
||||
case DRM_FORMAT_BGRX8888:
|
||||
for (i = 0; i < 256; ++i)
|
||||
vesa->cmap_write(vesa, i, lut[i].red, lut[i].green, lut[i].blue);
|
||||
drm_crtc_load_gamma_888(crtc, lut, vesadrm_set_gamma_lut);
|
||||
break;
|
||||
default:
|
||||
drm_warn_once(dev, "Unsupported format %p4cc for gamma correction\n",
|
||||
|
|
@ -253,13 +225,13 @@ static void vesadrm_crtc_helper_atomic_flush(struct drm_crtc *crtc,
|
|||
if (crtc_state->enable && crtc_state->color_mgmt_changed) {
|
||||
if (sysfb_crtc_state->format == sysfb->fb_format) {
|
||||
if (crtc_state->gamma_lut)
|
||||
vesadrm_set_gamma_lut(vesa,
|
||||
sysfb_crtc_state->format,
|
||||
crtc_state->gamma_lut->data);
|
||||
vesadrm_load_gamma_lut(vesa,
|
||||
sysfb_crtc_state->format,
|
||||
crtc_state->gamma_lut->data);
|
||||
else
|
||||
vesadrm_set_gamma_linear(vesa, sysfb_crtc_state->format);
|
||||
vesadrm_fill_gamma_lut(vesa, sysfb_crtc_state->format);
|
||||
} else {
|
||||
vesadrm_set_gamma_linear(vesa, sysfb_crtc_state->format);
|
||||
vesadrm_fill_gamma_lut(vesa, sysfb_crtc_state->format);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user