Color lookup support for the atmel-hlcdc driver

Peter Rosin peda at axentia.se
Tue Jun 13 14:34:25 UTC 2017


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;


More information about the dri-devel mailing list