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