Hi! I need color lookup support for the atmel-hlcdc driver, and had a peek at the code. I also looked at the drivers/gpu/drm/stm driver and came up with the below diff. It compiles, but I have not booted it for the simple reason that I can't imagine it will work. Sure, the code fills the clut registers in the .load_lut helper function and I think it might even do the right thing when setting up the mode. I'm less sure DMA will work correctly? It might, but I haven't looked at it for many seconds... The big question is how the color info gets into the new clut array I created in atmel_hlcdc_crtc? When I look at the stm driver, which does it just like this AFAICT I just don't see it. So, what I'm I missing? Also, when I'm looking at the docs for .load_lut I get the feeling that I'm barking up some dead old tree. help Cheers, peda diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c index 53489859997b..62ef30676cc3 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c @@ -61,6 +61,7 @@ struct atmel_hlcdc_crtc { struct atmel_hlcdc_dc *dc; struct drm_pending_vblank_event *event; int id; + u32 clut[256]; }; static inline struct atmel_hlcdc_crtc * @@ -140,6 +141,23 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct drm_crtc *c) cfg); } +static void +atmel_hlcdc_crtc_load_lut(struct drm_crtc *c) +{ + struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(c); + struct atmel_hlcdc_dc *dc = crtc->dc; + unsigned int color; + int layer; + + for (layer = 0; layer < ATMEL_HLCDC_MAX_LAYERS; layer++) { + if (!dc->layers[layer]) + continue; + for (color = 0; color < 256; color++) + atmel_hlcdc_layer_write_clut(dc->layers[layer], + color, crtc->clut[color]); + } +} + static enum drm_mode_status atmel_hlcdc_crtc_mode_valid(struct drm_crtc *c, const struct drm_display_mode *mode) @@ -319,6 +337,7 @@ static const struct drm_crtc_helper_funcs lcdc_crtc_helper_funcs = { .mode_set = drm_helper_crtc_mode_set, .mode_set_nofb = atmel_hlcdc_crtc_mode_set_nofb, .mode_set_base = drm_helper_crtc_mode_set_base, + .load_lut = atmel_hlcdc_crtc_load_lut, .disable = atmel_hlcdc_crtc_disable, .enable = atmel_hlcdc_crtc_enable, .atomic_check = atmel_hlcdc_crtc_atomic_check, diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c index 30dbffdb45a3..4723cadb67c4 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c @@ -37,6 +37,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9n12_layers[] = { .id = 0, .type = ATMEL_HLCDC_BASE_LAYER, .cfgs_offset = 0x2c, + .clut_offset = 0x400, .layout = { .xstride = { 2 }, .default_color = 3, @@ -66,6 +67,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = { .id = 0, .type = ATMEL_HLCDC_BASE_LAYER, .cfgs_offset = 0x2c, + .clut_offset = 0x400, .layout = { .xstride = { 2 }, .default_color = 3, @@ -81,6 +83,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = { .id = 1, .type = ATMEL_HLCDC_OVERLAY_LAYER, .cfgs_offset = 0x2c, + .clut_offset = 0x800, .layout = { .pos = 2, .size = 3, @@ -99,6 +102,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = { .id = 2, .type = ATMEL_HLCDC_OVERLAY_LAYER, .cfgs_offset = 0x4c, + .clut_offset = 0x1000, .layout = { .pos = 2, .size = 3, @@ -122,6 +126,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = { .max_width = 128, .max_height = 128, .cfgs_offset = 0x2c, + .clut_offset = 0x1400, .layout = { .pos = 2, .size = 3, @@ -155,6 +160,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = { .id = 0, .type = ATMEL_HLCDC_BASE_LAYER, .cfgs_offset = 0x2c, + .clut_offset = 0x600, .layout = { .xstride = { 2 }, .default_color = 3, @@ -170,6 +176,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = { .id = 1, .type = ATMEL_HLCDC_OVERLAY_LAYER, .cfgs_offset = 0x2c, + .clut_offset = 0xa00, .layout = { .pos = 2, .size = 3, @@ -188,6 +195,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = { .id = 2, .type = ATMEL_HLCDC_OVERLAY_LAYER, .cfgs_offset = 0x2c, + .clut_offset = 0xe00, .layout = { .pos = 2, .size = 3, @@ -206,6 +214,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = { .id = 3, .type = ATMEL_HLCDC_OVERLAY_LAYER, .cfgs_offset = 0x4c, + .clut_offset = 0x1200, .layout = { .pos = 2, .size = 3, @@ -233,6 +242,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = { .max_width = 128, .max_height = 128, .cfgs_offset = 0x2c, + .clut_offset = 0x1600, .layout = { .pos = 2, .size = 3, diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h index b0596a84c1b8..a2cc2ab923fa 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h @@ -88,6 +88,11 @@ #define ATMEL_HLCDC_YUV422SWP BIT(17) #define ATMEL_HLCDC_DSCALEOPT BIT(20) +#define ATMEL_HLCDC_C1_MODE ATMEL_HLCDC_CLUT_MODE(0) +#define ATMEL_HLCDC_C2_MODE ATMEL_HLCDC_CLUT_MODE(1) +#define ATMEL_HLCDC_C4_MODE ATMEL_HLCDC_CLUT_MODE(2) +#define ATMEL_HLCDC_C8_MODE ATMEL_HLCDC_CLUT_MODE(3) + #define ATMEL_HLCDC_XRGB4444_MODE ATMEL_HLCDC_RGB_MODE(0) #define ATMEL_HLCDC_ARGB4444_MODE ATMEL_HLCDC_RGB_MODE(1) #define ATMEL_HLCDC_RGBA4444_MODE ATMEL_HLCDC_RGB_MODE(2) @@ -259,6 +264,7 @@ struct atmel_hlcdc_layer_desc { int id; int regs_offset; int cfgs_offset; + int clut_offset; struct atmel_hlcdc_formats *formats; struct atmel_hlcdc_layer_cfg_layout layout; int max_width; @@ -414,6 +420,14 @@ static inline u32 atmel_hlcdc_layer_read_cfg(struct atmel_hlcdc_layer *layer, (cfgid * sizeof(u32))); } +static inline void atmel_hlcdc_layer_write_clut(struct atmel_hlcdc_layer *layer, + unsigned int c, u32 val) +{ + atmel_hlcdc_layer_write_reg(layer, + layer->desc->clut_offset + c * sizeof(u32), + val); +} + static inline void atmel_hlcdc_layer_init(struct atmel_hlcdc_layer *layer, const struct atmel_hlcdc_layer_desc *desc, struct regmap *regmap) diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c index 1124200bb280..5537843e48fe 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c @@ -83,6 +83,7 @@ drm_plane_state_to_atmel_hlcdc_plane_state(struct drm_plane_state *s) #define SUBPIXEL_MASK 0xffff static uint32_t rgb_formats[] = { + DRM_FORMAT_C8, DRM_FORMAT_XRGB4444, DRM_FORMAT_ARGB4444, DRM_FORMAT_RGBA4444, @@ -100,6 +101,7 @@ struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_formats = { }; static uint32_t rgb_and_yuv_formats[] = { + DRM_FORMAT_C8, DRM_FORMAT_XRGB4444, DRM_FORMAT_ARGB4444, DRM_FORMAT_RGBA4444, @@ -128,6 +130,9 @@ struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_and_yuv_formats = { static int atmel_hlcdc_format_to_plane_mode(u32 format, u32 *mode) { switch (format) { + case DRM_FORMAT_C8: + *mode = ATMEL_HLCDC_C8_MODE; + break; case DRM_FORMAT_XRGB4444: *mode = ATMEL_HLCDC_XRGB4444_MODE; break; _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel