Replace ast's code for programming the hardware gamma/palette LUT with DRM helpers. Either load provided data or program a default. Set the individual entries with a callback.
Each gamma/palette 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 <tzimmerm...@suse.de> Acked-by: Javier Martinez Canillas <javi...@redhat.com> --- drivers/gpu/drm/ast/ast_mode.c | 69 +++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 1de832964e92..7908087bcb5a 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -34,6 +34,7 @@ #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_color_mgmt.h> #include <drm/drm_crtc.h> #include <drm/drm_damage_helper.h> #include <drm/drm_format_helper.h> @@ -71,31 +72,44 @@ static unsigned long ast_fb_vram_size(struct ast_device *ast) return cursor_offset - offset; } -static inline void ast_load_palette_index(struct ast_device *ast, - u8 index, u8 red, u8 green, - u8 blue) +static void ast_set_gamma_lut(struct drm_crtc *crtc, unsigned int index, + u16 red, u16 green, u16 blue) { - ast_io_write8(ast, AST_IO_VGADWR, index); + struct drm_device *dev = crtc->dev; + struct ast_device *ast = to_ast_device(dev); + u8 i8 = index & 0xff; + u8 r8 = red >> 8; + u8 g8 = green >> 8; + u8 b8 = blue >> 8; + + if (drm_WARN_ON_ONCE(dev, index != i8)) + return; /* driver bug */ + + ast_io_write8(ast, AST_IO_VGADWR, i8); ast_io_read8(ast, AST_IO_VGASRI); - ast_io_write8(ast, AST_IO_VGAPDR, red); + ast_io_write8(ast, AST_IO_VGAPDR, r8); ast_io_read8(ast, AST_IO_VGASRI); - ast_io_write8(ast, AST_IO_VGAPDR, green); + ast_io_write8(ast, AST_IO_VGAPDR, g8); ast_io_read8(ast, AST_IO_VGASRI); - ast_io_write8(ast, AST_IO_VGAPDR, blue); + ast_io_write8(ast, AST_IO_VGAPDR, b8); ast_io_read8(ast, AST_IO_VGASRI); } -static void ast_crtc_set_gamma_linear(struct ast_device *ast, - const struct drm_format_info *format) +static void ast_crtc_fill_gamma(struct ast_device *ast, + const struct drm_format_info *format) { - int i; + struct drm_crtc *crtc = &ast->crtc; switch (format->format) { - case DRM_FORMAT_C8: /* In this case, gamma table is used as color palette */ + case DRM_FORMAT_C8: + /* gamma table is used as color palette */ + drm_crtc_fill_palette_8(crtc, ast_set_gamma_lut); + break; case DRM_FORMAT_RGB565: + /* also uses 8-bit gamma ramp on low-color modes */ + fallthrough; case DRM_FORMAT_XRGB8888: - for (i = 0; i < AST_LUT_SIZE; i++) - ast_load_palette_index(ast, i, i, i, i); + drm_crtc_fill_gamma_888(crtc, ast_set_gamma_lut); break; default: drm_warn_once(&ast->base, "Unsupported format %p4cc for gamma correction\n", @@ -104,21 +118,22 @@ static void ast_crtc_set_gamma_linear(struct ast_device *ast, } } -static void ast_crtc_set_gamma(struct ast_device *ast, - const struct drm_format_info *format, - struct drm_color_lut *lut) +static void ast_crtc_load_gamma(struct ast_device *ast, + const struct drm_format_info *format, + struct drm_color_lut *lut) { - int i; + struct drm_crtc *crtc = &ast->crtc; switch (format->format) { - case DRM_FORMAT_C8: /* In this case, gamma table is used as color palette */ + case DRM_FORMAT_C8: + /* gamma table is used as color palette */ + drm_crtc_load_palette_8(crtc, lut, ast_set_gamma_lut); + break; case DRM_FORMAT_RGB565: + /* also uses 8-bit gamma ramp on low-color modes */ + fallthrough; case DRM_FORMAT_XRGB8888: - for (i = 0; i < AST_LUT_SIZE; i++) - ast_load_palette_index(ast, i, - lut[i].red >> 8, - lut[i].green >> 8, - lut[i].blue >> 8); + drm_crtc_load_gamma_888(crtc, lut, ast_set_gamma_lut); break; default: drm_warn_once(&ast->base, "Unsupported format %p4cc for gamma correction\n", @@ -811,11 +826,11 @@ ast_crtc_helper_atomic_flush(struct drm_crtc *crtc, */ if (crtc_state->enable && crtc_state->color_mgmt_changed) { if (crtc_state->gamma_lut) - ast_crtc_set_gamma(ast, - ast_crtc_state->format, - crtc_state->gamma_lut->data); + ast_crtc_load_gamma(ast, + ast_crtc_state->format, + crtc_state->gamma_lut->data); else - ast_crtc_set_gamma_linear(ast, ast_crtc_state->format); + ast_crtc_fill_gamma(ast, ast_crtc_state->format); } } -- 2.49.0