Commit 364a7bf5 authored by Peter Rosin's avatar Peter Rosin Committed by Boris Brezillon

drm: atmel-hlcdc: add support for 8-bit color lookup table mode

All layers of all supported chips support this, the only variable is the
base address of the lookup table in the register map.
Acked-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: default avatarPeter Rosin <peda@axentia.se>
Signed-off-by: default avatarBoris Brezillon <boris.brezillon@free-electrons.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1498107791-17450-3-git-send-email-peda@axentia.se
parent ae7c59f0
...@@ -430,6 +430,7 @@ static const struct drm_crtc_funcs atmel_hlcdc_crtc_funcs = { ...@@ -430,6 +430,7 @@ static const struct drm_crtc_funcs atmel_hlcdc_crtc_funcs = {
.enable_vblank = atmel_hlcdc_crtc_enable_vblank, .enable_vblank = atmel_hlcdc_crtc_enable_vblank,
.disable_vblank = atmel_hlcdc_crtc_disable_vblank, .disable_vblank = atmel_hlcdc_crtc_disable_vblank,
.set_property = drm_atomic_helper_crtc_set_property, .set_property = drm_atomic_helper_crtc_set_property,
.gamma_set = drm_atomic_helper_legacy_gamma_set,
}; };
int atmel_hlcdc_crtc_create(struct drm_device *dev) int atmel_hlcdc_crtc_create(struct drm_device *dev)
...@@ -485,6 +486,10 @@ int atmel_hlcdc_crtc_create(struct drm_device *dev) ...@@ -485,6 +486,10 @@ int atmel_hlcdc_crtc_create(struct drm_device *dev)
drm_crtc_helper_add(&crtc->base, &lcdc_crtc_helper_funcs); drm_crtc_helper_add(&crtc->base, &lcdc_crtc_helper_funcs);
drm_crtc_vblank_reset(&crtc->base); drm_crtc_vblank_reset(&crtc->base);
drm_mode_crtc_set_gamma_size(&crtc->base, ATMEL_HLCDC_CLUT_SIZE);
drm_crtc_enable_color_mgmt(&crtc->base, 0, false,
ATMEL_HLCDC_CLUT_SIZE);
dc->crtc = &crtc->base; dc->crtc = &crtc->base;
return 0; return 0;
......
...@@ -42,6 +42,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9n12_layers[] = { ...@@ -42,6 +42,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9n12_layers[] = {
.default_color = 3, .default_color = 3,
.general_config = 4, .general_config = 4,
}, },
.clut_offset = 0x400,
}, },
}; };
...@@ -73,6 +74,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = { ...@@ -73,6 +74,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = {
.disc_pos = 5, .disc_pos = 5,
.disc_size = 6, .disc_size = 6,
}, },
.clut_offset = 0x400,
}, },
{ {
.name = "overlay1", .name = "overlay1",
...@@ -91,6 +93,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = { ...@@ -91,6 +93,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = {
.chroma_key_mask = 8, .chroma_key_mask = 8,
.general_config = 9, .general_config = 9,
}, },
.clut_offset = 0x800,
}, },
{ {
.name = "high-end-overlay", .name = "high-end-overlay",
...@@ -112,6 +115,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = { ...@@ -112,6 +115,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = {
.scaler_config = 13, .scaler_config = 13,
.csc = 14, .csc = 14,
}, },
.clut_offset = 0x1000,
}, },
{ {
.name = "cursor", .name = "cursor",
...@@ -131,6 +135,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = { ...@@ -131,6 +135,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = {
.chroma_key_mask = 8, .chroma_key_mask = 8,
.general_config = 9, .general_config = 9,
}, },
.clut_offset = 0x1400,
}, },
}; };
...@@ -162,6 +167,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = { ...@@ -162,6 +167,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
.disc_pos = 5, .disc_pos = 5,
.disc_size = 6, .disc_size = 6,
}, },
.clut_offset = 0x600,
}, },
{ {
.name = "overlay1", .name = "overlay1",
...@@ -180,6 +186,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = { ...@@ -180,6 +186,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
.chroma_key_mask = 8, .chroma_key_mask = 8,
.general_config = 9, .general_config = 9,
}, },
.clut_offset = 0xa00,
}, },
{ {
.name = "overlay2", .name = "overlay2",
...@@ -198,6 +205,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = { ...@@ -198,6 +205,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
.chroma_key_mask = 8, .chroma_key_mask = 8,
.general_config = 9, .general_config = 9,
}, },
.clut_offset = 0xe00,
}, },
{ {
.name = "high-end-overlay", .name = "high-end-overlay",
...@@ -223,6 +231,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = { ...@@ -223,6 +231,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
}, },
.csc = 14, .csc = 14,
}, },
.clut_offset = 0x1200,
}, },
{ {
.name = "cursor", .name = "cursor",
...@@ -244,6 +253,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = { ...@@ -244,6 +253,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
.general_config = 9, .general_config = 9,
.scaler_config = 13, .scaler_config = 13,
}, },
.clut_offset = 0x1600,
}, },
}; };
...@@ -275,6 +285,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = { ...@@ -275,6 +285,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = {
.disc_pos = 5, .disc_pos = 5,
.disc_size = 6, .disc_size = 6,
}, },
.clut_offset = 0x600,
}, },
{ {
.name = "overlay1", .name = "overlay1",
...@@ -293,6 +304,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = { ...@@ -293,6 +304,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = {
.chroma_key_mask = 8, .chroma_key_mask = 8,
.general_config = 9, .general_config = 9,
}, },
.clut_offset = 0xa00,
}, },
{ {
.name = "overlay2", .name = "overlay2",
...@@ -311,6 +323,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = { ...@@ -311,6 +323,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = {
.chroma_key_mask = 8, .chroma_key_mask = 8,
.general_config = 9, .general_config = 9,
}, },
.clut_offset = 0xe00,
}, },
{ {
.name = "high-end-overlay", .name = "high-end-overlay",
...@@ -336,6 +349,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = { ...@@ -336,6 +349,7 @@ static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = {
}, },
.csc = 14, .csc = 14,
}, },
.clut_offset = 0x1200,
}, },
}; };
......
...@@ -88,6 +88,11 @@ ...@@ -88,6 +88,11 @@
#define ATMEL_HLCDC_YUV422SWP BIT(17) #define ATMEL_HLCDC_YUV422SWP BIT(17)
#define ATMEL_HLCDC_DSCALEOPT BIT(20) #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_XRGB4444_MODE ATMEL_HLCDC_RGB_MODE(0)
#define ATMEL_HLCDC_ARGB4444_MODE ATMEL_HLCDC_RGB_MODE(1) #define ATMEL_HLCDC_ARGB4444_MODE ATMEL_HLCDC_RGB_MODE(1)
#define ATMEL_HLCDC_RGBA4444_MODE ATMEL_HLCDC_RGB_MODE(2) #define ATMEL_HLCDC_RGBA4444_MODE ATMEL_HLCDC_RGB_MODE(2)
...@@ -142,6 +147,8 @@ ...@@ -142,6 +147,8 @@
#define ATMEL_HLCDC_DMA_CHANNEL_DSCR_DONE BIT(2) #define ATMEL_HLCDC_DMA_CHANNEL_DSCR_DONE BIT(2)
#define ATMEL_HLCDC_DMA_CHANNEL_DSCR_OVERRUN BIT(3) #define ATMEL_HLCDC_DMA_CHANNEL_DSCR_OVERRUN BIT(3)
#define ATMEL_HLCDC_CLUT_SIZE 256
#define ATMEL_HLCDC_MAX_LAYERS 6 #define ATMEL_HLCDC_MAX_LAYERS 6
/** /**
...@@ -259,6 +266,7 @@ struct atmel_hlcdc_layer_desc { ...@@ -259,6 +266,7 @@ struct atmel_hlcdc_layer_desc {
int id; int id;
int regs_offset; int regs_offset;
int cfgs_offset; int cfgs_offset;
int clut_offset;
struct atmel_hlcdc_formats *formats; struct atmel_hlcdc_formats *formats;
struct atmel_hlcdc_layer_cfg_layout layout; struct atmel_hlcdc_layer_cfg_layout layout;
int max_width; int max_width;
...@@ -414,6 +422,14 @@ static inline u32 atmel_hlcdc_layer_read_cfg(struct atmel_hlcdc_layer *layer, ...@@ -414,6 +422,14 @@ static inline u32 atmel_hlcdc_layer_read_cfg(struct atmel_hlcdc_layer *layer,
(cfgid * sizeof(u32))); (cfgid * sizeof(u32)));
} }
static inline void atmel_hlcdc_layer_write_clut(struct atmel_hlcdc_layer *layer,
unsigned int c, u32 val)
{
regmap_write(layer->regmap,
layer->desc->clut_offset + c * sizeof(u32),
val);
}
static inline void atmel_hlcdc_layer_init(struct atmel_hlcdc_layer *layer, static inline void atmel_hlcdc_layer_init(struct atmel_hlcdc_layer *layer,
const struct atmel_hlcdc_layer_desc *desc, const struct atmel_hlcdc_layer_desc *desc,
struct regmap *regmap) struct regmap *regmap)
......
...@@ -83,6 +83,7 @@ drm_plane_state_to_atmel_hlcdc_plane_state(struct drm_plane_state *s) ...@@ -83,6 +83,7 @@ drm_plane_state_to_atmel_hlcdc_plane_state(struct drm_plane_state *s)
#define SUBPIXEL_MASK 0xffff #define SUBPIXEL_MASK 0xffff
static uint32_t rgb_formats[] = { static uint32_t rgb_formats[] = {
DRM_FORMAT_C8,
DRM_FORMAT_XRGB4444, DRM_FORMAT_XRGB4444,
DRM_FORMAT_ARGB4444, DRM_FORMAT_ARGB4444,
DRM_FORMAT_RGBA4444, DRM_FORMAT_RGBA4444,
...@@ -100,6 +101,7 @@ struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_formats = { ...@@ -100,6 +101,7 @@ struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_formats = {
}; };
static uint32_t rgb_and_yuv_formats[] = { static uint32_t rgb_and_yuv_formats[] = {
DRM_FORMAT_C8,
DRM_FORMAT_XRGB4444, DRM_FORMAT_XRGB4444,
DRM_FORMAT_ARGB4444, DRM_FORMAT_ARGB4444,
DRM_FORMAT_RGBA4444, DRM_FORMAT_RGBA4444,
...@@ -128,6 +130,9 @@ struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_and_yuv_formats = { ...@@ -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) static int atmel_hlcdc_format_to_plane_mode(u32 format, u32 *mode)
{ {
switch (format) { switch (format) {
case DRM_FORMAT_C8:
*mode = ATMEL_HLCDC_C8_MODE;
break;
case DRM_FORMAT_XRGB4444: case DRM_FORMAT_XRGB4444:
*mode = ATMEL_HLCDC_XRGB4444_MODE; *mode = ATMEL_HLCDC_XRGB4444_MODE;
break; break;
...@@ -424,6 +429,29 @@ static void atmel_hlcdc_plane_update_format(struct atmel_hlcdc_plane *plane, ...@@ -424,6 +429,29 @@ static void atmel_hlcdc_plane_update_format(struct atmel_hlcdc_plane *plane,
ATMEL_HLCDC_LAYER_FORMAT_CFG, cfg); ATMEL_HLCDC_LAYER_FORMAT_CFG, cfg);
} }
static void atmel_hlcdc_plane_update_clut(struct atmel_hlcdc_plane *plane)
{
struct drm_crtc *crtc = plane->base.crtc;
struct drm_color_lut *lut;
int idx;
if (!crtc || !crtc->state)
return;
if (!crtc->state->color_mgmt_changed || !crtc->state->gamma_lut)
return;
lut = (struct drm_color_lut *)crtc->state->gamma_lut->data;
for (idx = 0; idx < ATMEL_HLCDC_CLUT_SIZE; idx++, lut++) {
u32 val = ((lut->red << 8) & 0xff0000) |
(lut->green & 0xff00) |
(lut->blue >> 8);
atmel_hlcdc_layer_write_clut(&plane->layer, idx, val);
}
}
static void atmel_hlcdc_plane_update_buffers(struct atmel_hlcdc_plane *plane, static void atmel_hlcdc_plane_update_buffers(struct atmel_hlcdc_plane *plane,
struct atmel_hlcdc_plane_state *state) struct atmel_hlcdc_plane_state *state)
{ {
...@@ -768,6 +796,7 @@ static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p, ...@@ -768,6 +796,7 @@ static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p,
atmel_hlcdc_plane_update_pos_and_size(plane, state); atmel_hlcdc_plane_update_pos_and_size(plane, state);
atmel_hlcdc_plane_update_general_settings(plane, state); atmel_hlcdc_plane_update_general_settings(plane, state);
atmel_hlcdc_plane_update_format(plane, state); atmel_hlcdc_plane_update_format(plane, state);
atmel_hlcdc_plane_update_clut(plane);
atmel_hlcdc_plane_update_buffers(plane, state); atmel_hlcdc_plane_update_buffers(plane, state);
atmel_hlcdc_plane_update_disc_area(plane, state); atmel_hlcdc_plane_update_disc_area(plane, state);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment