* [PATCH v5 1/8] mfd: atmel-hlcdc: Add compatible for sam9x75 XLCD controller
2023-09-15 10:48 [PATCH v5 0/8] Add support for XLCDC to sam9x7 SoC family Manikandan Muralidharan
@ 2023-09-15 10:48 ` Manikandan Muralidharan
2023-09-20 13:33 ` (subset) " Lee Jones
2023-09-15 10:48 ` [PATCH v5 2/8] drm: atmel-hlcdc: add flag and driver ops to differentiate XLCDC and HLCDC IP Manikandan Muralidharan
` (6 subsequent siblings)
7 siblings, 1 reply; 14+ messages in thread
From: Manikandan Muralidharan @ 2023-09-15 10:48 UTC (permalink / raw)
To: sam, bbrezillon, airlied, daniel, nicolas.ferre,
alexandre.belloni, lee, dri-devel, linux-arm-kernel,
linux-kernel
Cc: Hari.PrasathGE, Balamanikandan.Gunasundar, Durai.ManickamKR,
Nayabbasha.Sayed, Dharma.B, Varshini.Rajendran, Balakrishnan.S,
Manikandan Muralidharan
Add compatible for sam9x75 XLCD controller.
Signed-off-by: Manikandan Muralidharan <manikandan.m@microchip.com>
---
drivers/mfd/atmel-hlcdc.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/mfd/atmel-hlcdc.c b/drivers/mfd/atmel-hlcdc.c
index 3c2414ba4b01..1daa7410468a 100644
--- a/drivers/mfd/atmel-hlcdc.c
+++ b/drivers/mfd/atmel-hlcdc.c
@@ -141,6 +141,7 @@ static const struct of_device_id atmel_hlcdc_match[] = {
{ .compatible = "atmel,sama5d3-hlcdc" },
{ .compatible = "atmel,sama5d4-hlcdc" },
{ .compatible = "microchip,sam9x60-hlcdc" },
+ { .compatible = "microchip,sam9x75-xlcdc" },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, atmel_hlcdc_match);
--
2.25.1
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: (subset) [PATCH v5 1/8] mfd: atmel-hlcdc: Add compatible for sam9x75 XLCD controller
2023-09-15 10:48 ` [PATCH v5 1/8] mfd: atmel-hlcdc: Add compatible for sam9x75 XLCD controller Manikandan Muralidharan
@ 2023-09-20 13:33 ` Lee Jones
0 siblings, 0 replies; 14+ messages in thread
From: Lee Jones @ 2023-09-20 13:33 UTC (permalink / raw)
To: sam, bbrezillon, airlied, daniel, nicolas.ferre,
alexandre.belloni, lee, dri-devel, linux-arm-kernel,
linux-kernel, Manikandan Muralidharan
Cc: Hari.PrasathGE, Balamanikandan.Gunasundar, Durai.ManickamKR,
Nayabbasha.Sayed, Dharma.B, Varshini.Rajendran, Balakrishnan.S
On Fri, 15 Sep 2023 16:18:42 +0530, Manikandan Muralidharan wrote:
> Add compatible for sam9x75 XLCD controller.
>
>
Applied, thanks!
[1/8] mfd: atmel-hlcdc: Add compatible for sam9x75 XLCD controller
commit: c743c12c79ff716e081095c5a2ba360e42b39d78
--
Lee Jones [李琼斯]
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v5 2/8] drm: atmel-hlcdc: add flag and driver ops to differentiate XLCDC and HLCDC IP
2023-09-15 10:48 [PATCH v5 0/8] Add support for XLCDC to sam9x7 SoC family Manikandan Muralidharan
2023-09-15 10:48 ` [PATCH v5 1/8] mfd: atmel-hlcdc: Add compatible for sam9x75 XLCD controller Manikandan Muralidharan
@ 2023-09-15 10:48 ` Manikandan Muralidharan
2023-09-15 10:48 ` [PATCH v5 3/8] drm: atmel-hlcdc: add LCD controller layer definition for sam9x75 Manikandan Muralidharan
` (5 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Manikandan Muralidharan @ 2023-09-15 10:48 UTC (permalink / raw)
To: sam, bbrezillon, airlied, daniel, nicolas.ferre,
alexandre.belloni, lee, dri-devel, linux-arm-kernel,
linux-kernel
Cc: Hari.PrasathGE, Balamanikandan.Gunasundar, Durai.ManickamKR,
Nayabbasha.Sayed, Dharma.B, Varshini.Rajendran, Balakrishnan.S,
Manikandan Muralidharan
Add is_xlcdc flag and LCD IP specific ops in driver data to differentiate
XLCDC and HLCDC code within the atmel-hlcdc driver files.
Signed-off-by: Manikandan Muralidharan <manikandan.m@microchip.com>
---
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h | 68 ++++++++++++++++++++
1 file changed, 68 insertions(+)
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
index 5b5c774e0edf..c61fa1733da4 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
@@ -177,6 +177,9 @@ struct atmel_hlcdc_layer_cfg_layout {
int csc;
};
+struct atmel_hlcdc_plane_state;
+struct atmel_lcdc_dc_ops;
+
/**
* Atmel HLCDC DMA descriptor structure
*
@@ -304,8 +307,10 @@ atmel_hlcdc_layer_to_plane(struct atmel_hlcdc_layer *layer)
* @conflicting_output_formats: true if RGBXXX output formats conflict with
* each other.
* @fixed_clksrc: true if clock source is fixed
+ * @is_xlcdc: true if XLCDC IP is supported
* @layers: a layer description table describing available layers
* @nlayers: layer description table size
+ * @ops: atmel lcdc dc ops
*/
struct atmel_hlcdc_dc_desc {
int min_width;
@@ -317,8 +322,10 @@ struct atmel_hlcdc_dc_desc {
int max_hpw;
bool conflicting_output_formats;
bool fixed_clksrc;
+ bool is_xlcdc;
const struct atmel_hlcdc_layer_desc *layers;
int nlayers;
+ const struct atmel_lcdc_dc_ops *ops;
};
/**
@@ -345,6 +352,67 @@ struct atmel_hlcdc_dc {
} suspend;
};
+/**
+ * struct atmel_lcdc_dc_ops - describes atmel_lcdc ops group
+ * to differentiate HLCDC and XLCDC IP code support.
+ * @plane_setup_scaler: update the vertical and horizontal scaling factors
+ * @update_lcdc_buffers: update the each LCDC layers DMA registers.
+ * @lcdc_atomic_disable: disable LCDC interrupts and layers
+ * @lcdc_update_general_settings: update each LCDC layers general
+ * confiugration register.
+ * @lcdc_atomic_update: enable the LCDC layers and interrupts.
+ * @lcdc_csc_init: update the color space conversion co-efficient of
+ * High-end overlay register.
+ * @lcdc_irq_dbg: to raise alert incase of interrupt overrun in any LCDC layer.
+ */
+struct atmel_lcdc_dc_ops {
+ void (*plane_setup_scaler)(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_plane_state *state);
+ void (*update_lcdc_buffers)(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_plane_state *state,
+ u32 sr, int i);
+ void (*lcdc_atomic_disable)(struct atmel_hlcdc_plane *plane);
+ void (*lcdc_update_general_settings)(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_plane_state *state);
+ void (*lcdc_atomic_update)(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_dc *dc);
+ void (*lcdc_csc_init)(struct atmel_hlcdc_plane *plane,
+ const struct atmel_hlcdc_layer_desc *desc);
+ void (*lcdc_irq_dbg)(struct atmel_hlcdc_plane *plane,
+ const struct atmel_hlcdc_layer_desc *desc);
+};
+
+void atmel_hlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_plane_state *state);
+void atmel_xlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_plane_state *state);
+void update_hlcdc_buffers(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_plane_state *state,
+ u32 sr, int i);
+void update_xlcdc_buffers(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_plane_state *state,
+ u32 sr, int i);
+void hlcdc_atomic_disable(struct atmel_hlcdc_plane *plane);
+void xlcdc_atomic_disable(struct atmel_hlcdc_plane *plane);
+void
+atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_plane_state *state);
+void
+atmel_xlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_plane_state *state);
+void hlcdc_atomic_update(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_dc *dc);
+void xlcdc_atomic_update(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_dc *dc);
+void hlcdc_csc_init(struct atmel_hlcdc_plane *plane,
+ const struct atmel_hlcdc_layer_desc *desc);
+void xlcdc_csc_init(struct atmel_hlcdc_plane *plane,
+ const struct atmel_hlcdc_layer_desc *desc);
+void hlcdc_irq_dbg(struct atmel_hlcdc_plane *plane,
+ const struct atmel_hlcdc_layer_desc *desc);
+void xlcdc_irq_dbg(struct atmel_hlcdc_plane *plane,
+ const struct atmel_hlcdc_layer_desc *desc);
+
extern struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_formats;
extern struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_and_yuv_formats;
--
2.25.1
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH v5 3/8] drm: atmel-hlcdc: add LCD controller layer definition for sam9x75
2023-09-15 10:48 [PATCH v5 0/8] Add support for XLCDC to sam9x7 SoC family Manikandan Muralidharan
2023-09-15 10:48 ` [PATCH v5 1/8] mfd: atmel-hlcdc: Add compatible for sam9x75 XLCD controller Manikandan Muralidharan
2023-09-15 10:48 ` [PATCH v5 2/8] drm: atmel-hlcdc: add flag and driver ops to differentiate XLCDC and HLCDC IP Manikandan Muralidharan
@ 2023-09-15 10:48 ` Manikandan Muralidharan
2023-09-25 14:14 ` claudiu beznea
2023-09-15 10:48 ` [PATCH v5 4/8] drm: atmel-hlcdc: Define SAM9X7 SoC XLCDC specific registers Manikandan Muralidharan
` (4 subsequent siblings)
7 siblings, 1 reply; 14+ messages in thread
From: Manikandan Muralidharan @ 2023-09-15 10:48 UTC (permalink / raw)
To: sam, bbrezillon, airlied, daniel, nicolas.ferre,
alexandre.belloni, lee, dri-devel, linux-arm-kernel,
linux-kernel
Cc: Hari.PrasathGE, Balamanikandan.Gunasundar, Durai.ManickamKR,
Nayabbasha.Sayed, Dharma.B, Varshini.Rajendran, Balakrishnan.S,
Manikandan Muralidharan
Add the LCD controller layer definition and descriptor structure for
sam9x75 for the following layers,
- Base Layer
- Overlay1 Layer
- Overlay2 Layer
- High End Overlay
Signed-off-by: Manikandan Muralidharan <manikandan.m@microchip.com>
---
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 97 ++++++++++++++++++++
1 file changed, 97 insertions(+)
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
index fa0f9a93d50d..d30aec174aa2 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
@@ -462,6 +462,99 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sam9x60 = {
.layers = atmel_hlcdc_sam9x60_layers,
};
+static const struct atmel_hlcdc_layer_desc atmel_xlcdc_sam9x75_layers[] = {
+ {
+ .name = "base",
+ .formats = &atmel_hlcdc_plane_rgb_formats,
+ .regs_offset = 0x60,
+ .id = 0,
+ .type = ATMEL_HLCDC_BASE_LAYER,
+ .cfgs_offset = 0x1c,
+ .layout = {
+ .xstride = { 2 },
+ .default_color = 3,
+ .general_config = 4,
+ .disc_pos = 5,
+ .disc_size = 6,
+ },
+ .clut_offset = 0x700,
+ },
+ {
+ .name = "overlay1",
+ .formats = &atmel_hlcdc_plane_rgb_formats,
+ .regs_offset = 0x160,
+ .id = 1,
+ .type = ATMEL_HLCDC_OVERLAY_LAYER,
+ .cfgs_offset = 0x1c,
+ .layout = {
+ .pos = 2,
+ .size = 3,
+ .xstride = { 4 },
+ .pstride = { 5 },
+ .default_color = 6,
+ .chroma_key = 7,
+ .chroma_key_mask = 8,
+ .general_config = 9,
+ },
+ .clut_offset = 0xb00,
+ },
+ {
+ .name = "overlay2",
+ .formats = &atmel_hlcdc_plane_rgb_formats,
+ .regs_offset = 0x260,
+ .id = 2,
+ .type = ATMEL_HLCDC_OVERLAY_LAYER,
+ .cfgs_offset = 0x1c,
+ .layout = {
+ .pos = 2,
+ .size = 3,
+ .xstride = { 4 },
+ .pstride = { 5 },
+ .default_color = 6,
+ .chroma_key = 7,
+ .chroma_key_mask = 8,
+ .general_config = 9,
+ },
+ .clut_offset = 0xf00,
+ },
+ {
+ .name = "high-end-overlay",
+ .formats = &atmel_hlcdc_plane_rgb_and_yuv_formats,
+ .regs_offset = 0x360,
+ .id = 3,
+ .type = ATMEL_HLCDC_OVERLAY_LAYER,
+ .cfgs_offset = 0x30,
+ .layout = {
+ .pos = 2,
+ .size = 3,
+ .memsize = 4,
+ .xstride = { 5, 7 },
+ .pstride = { 6, 8 },
+ .default_color = 9,
+ .chroma_key = 10,
+ .chroma_key_mask = 11,
+ .general_config = 12,
+ .csc = 16,
+ .scaler_config = 23,
+ },
+ .clut_offset = 0x1300,
+ },
+};
+
+static const struct atmel_hlcdc_dc_desc atmel_xlcdc_dc_sam9x75 = {
+ .min_width = 0,
+ .min_height = 0,
+ .max_width = 2048,
+ .max_height = 2048,
+ .max_spw = 0xff,
+ .max_vpw = 0xff,
+ .max_hpw = 0x3ff,
+ .fixed_clksrc = true,
+ .is_xlcdc = true,
+ .nlayers = ARRAY_SIZE(atmel_xlcdc_sam9x75_layers),
+ .layers = atmel_xlcdc_sam9x75_layers,
+};
+
static const struct of_device_id atmel_hlcdc_of_match[] = {
{
.compatible = "atmel,at91sam9n12-hlcdc",
@@ -487,6 +580,10 @@ static const struct of_device_id atmel_hlcdc_of_match[] = {
.compatible = "microchip,sam9x60-hlcdc",
.data = &atmel_hlcdc_dc_sam9x60,
},
+ {
+ .compatible = "microchip,sam9x75-xlcdc",
+ .data = &atmel_xlcdc_dc_sam9x75,
+ },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, atmel_hlcdc_of_match);
--
2.25.1
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH v5 3/8] drm: atmel-hlcdc: add LCD controller layer definition for sam9x75
2023-09-15 10:48 ` [PATCH v5 3/8] drm: atmel-hlcdc: add LCD controller layer definition for sam9x75 Manikandan Muralidharan
@ 2023-09-25 14:14 ` claudiu beznea
0 siblings, 0 replies; 14+ messages in thread
From: claudiu beznea @ 2023-09-25 14:14 UTC (permalink / raw)
To: Manikandan Muralidharan, sam, bbrezillon, airlied, daniel,
nicolas.ferre, alexandre.belloni, lee, dri-devel,
linux-arm-kernel, linux-kernel
Cc: Hari.PrasathGE, Balamanikandan.Gunasundar, Durai.ManickamKR,
Nayabbasha.Sayed, Dharma.B, Varshini.Rajendran, Balakrishnan.S
On 15.09.2023 13:48, Manikandan Muralidharan wrote:
> Add the LCD controller layer definition and descriptor structure for
> sam9x75 for the following layers,
s/,/:
> - Base Layer
> - Overlay1 Layer
> - Overlay2 Layer
> - High End Overlay
>
> Signed-off-by: Manikandan Muralidharan <manikandan.m@microchip.com>
> ---
> drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 97 ++++++++++++++++++++
> 1 file changed, 97 insertions(+)
>
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> index fa0f9a93d50d..d30aec174aa2 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> @@ -462,6 +462,99 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sam9x60 = {
> .layers = atmel_hlcdc_sam9x60_layers,
> };
>
> +static const struct atmel_hlcdc_layer_desc atmel_xlcdc_sam9x75_layers[] = {
> + {
> + .name = "base",
> + .formats = &atmel_hlcdc_plane_rgb_formats,
> + .regs_offset = 0x60,
> + .id = 0,
> + .type = ATMEL_HLCDC_BASE_LAYER,
> + .cfgs_offset = 0x1c,
> + .layout = {
> + .xstride = { 2 },
> + .default_color = 3,
> + .general_config = 4,
> + .disc_pos = 5,
> + .disc_size = 6,
> + },
> + .clut_offset = 0x700,
> + },
> + {
> + .name = "overlay1",
> + .formats = &atmel_hlcdc_plane_rgb_formats,
> + .regs_offset = 0x160,
> + .id = 1,
> + .type = ATMEL_HLCDC_OVERLAY_LAYER,
> + .cfgs_offset = 0x1c,
> + .layout = {
> + .pos = 2,
> + .size = 3,
> + .xstride = { 4 },
> + .pstride = { 5 },
> + .default_color = 6,
> + .chroma_key = 7,
> + .chroma_key_mask = 8,
> + .general_config = 9,
> + },
> + .clut_offset = 0xb00,
> + },
> + {
> + .name = "overlay2",
> + .formats = &atmel_hlcdc_plane_rgb_formats,
> + .regs_offset = 0x260,
> + .id = 2,
> + .type = ATMEL_HLCDC_OVERLAY_LAYER,
> + .cfgs_offset = 0x1c,
> + .layout = {
> + .pos = 2,
> + .size = 3,
> + .xstride = { 4 },
> + .pstride = { 5 },
> + .default_color = 6,
> + .chroma_key = 7,
> + .chroma_key_mask = 8,
> + .general_config = 9,
> + },
> + .clut_offset = 0xf00,
> + },
> + {
> + .name = "high-end-overlay",
> + .formats = &atmel_hlcdc_plane_rgb_and_yuv_formats,
> + .regs_offset = 0x360,
> + .id = 3,
> + .type = ATMEL_HLCDC_OVERLAY_LAYER,
> + .cfgs_offset = 0x30,
> + .layout = {
> + .pos = 2,
> + .size = 3,
> + .memsize = 4,
> + .xstride = { 5, 7 },
> + .pstride = { 6, 8 },
> + .default_color = 9,
> + .chroma_key = 10,
> + .chroma_key_mask = 11,
> + .general_config = 12,
> + .csc = 16,
> + .scaler_config = 23,
> + },
> + .clut_offset = 0x1300,
> + },
> +};
> +
> +static const struct atmel_hlcdc_dc_desc atmel_xlcdc_dc_sam9x75 = {
> + .min_width = 0,
> + .min_height = 0,
> + .max_width = 2048,
> + .max_height = 2048,
> + .max_spw = 0xff,
> + .max_vpw = 0xff,
> + .max_hpw = 0x3ff,
> + .fixed_clksrc = true,
> + .is_xlcdc = true,
> + .nlayers = ARRAY_SIZE(atmel_xlcdc_sam9x75_layers),
> + .layers = atmel_xlcdc_sam9x75_layers,
> +};
> +
> static const struct of_device_id atmel_hlcdc_of_match[] = {
> {
> .compatible = "atmel,at91sam9n12-hlcdc",
> @@ -487,6 +580,10 @@ static const struct of_device_id atmel_hlcdc_of_match[] = {
> .compatible = "microchip,sam9x60-hlcdc",
> .data = &atmel_hlcdc_dc_sam9x60,
> },
> + {
> + .compatible = "microchip,sam9x75-xlcdc",
> + .data = &atmel_xlcdc_dc_sam9x75,
> + },
> { /* sentinel */ },
> };
> MODULE_DEVICE_TABLE(of, atmel_hlcdc_of_match);
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v5 4/8] drm: atmel-hlcdc: Define SAM9X7 SoC XLCDC specific registers
2023-09-15 10:48 [PATCH v5 0/8] Add support for XLCDC to sam9x7 SoC family Manikandan Muralidharan
` (2 preceding siblings ...)
2023-09-15 10:48 ` [PATCH v5 3/8] drm: atmel-hlcdc: add LCD controller layer definition for sam9x75 Manikandan Muralidharan
@ 2023-09-15 10:48 ` Manikandan Muralidharan
2023-09-25 14:14 ` claudiu beznea
2023-09-15 10:48 ` [PATCH v5 5/8] drm: atmel_hlcdc: Add support for XLCDC in atmel LCD driver Manikandan Muralidharan
` (3 subsequent siblings)
7 siblings, 1 reply; 14+ messages in thread
From: Manikandan Muralidharan @ 2023-09-15 10:48 UTC (permalink / raw)
To: sam, bbrezillon, airlied, daniel, nicolas.ferre,
alexandre.belloni, lee, dri-devel, linux-arm-kernel,
linux-kernel
Cc: Hari.PrasathGE, Balamanikandan.Gunasundar, Durai.ManickamKR,
Nayabbasha.Sayed, Dharma.B, Varshini.Rajendran, Balakrishnan.S,
Manikandan Muralidharan, Durai Manickam KR
From: Durai Manickam KR <durai.manickamkr@microchip.com>
The register address of the XLCDC IP used in SAM9X7 SoC family
are different from the previous HLCDC.Defining those address
space with valid macros.
Signed-off-by: Durai Manickam KR <durai.manickamkr@microchip.com>
[manikandan.m@microchip.com: Remove unused macro definitions]
Signed-off-by: Manikandan Muralidharan <manikandan.m@microchip.com>
---
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h | 42 ++++++++++++++++++++
include/linux/mfd/atmel-hlcdc.h | 10 +++++
2 files changed, 52 insertions(+)
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
index c61fa1733da4..9965c7cc5bf8 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
@@ -15,6 +15,7 @@
#include <drm/drm_plane.h>
+/* LCD controller common registers */
#define ATMEL_HLCDC_LAYER_CHER 0x0
#define ATMEL_HLCDC_LAYER_CHDR 0x4
#define ATMEL_HLCDC_LAYER_CHSR 0x8
@@ -128,6 +129,47 @@
#define ATMEL_HLCDC_MAX_LAYERS 6
+/* XLCDC controller specific registers */
+#define ATMEL_XLCDC_LAYER_ENR 0x10
+#define ATMEL_XLCDC_LAYER_EN BIT(0)
+
+#define ATMEL_XLCDC_LAYER_IER 0x0
+#define ATMEL_XLCDC_LAYER_IDR 0x4
+#define ATMEL_XLCDC_LAYER_ISR 0xc
+#define ATMEL_XLCDC_LAYER_OVR_IRQ(p) BIT(2 + (8 * (p)))
+
+#define ATMEL_XLCDC_LAYER_PLANE_ADDR(p) (((p) * 0x4) + 0x18)
+
+#define ATMEL_XLCDC_LAYER_DMA_CFG 0
+
+#define ATMEL_XLCDC_LAYER_DMA BIT(0)
+#define ATMEL_XLCDC_LAYER_REP BIT(1)
+#define ATMEL_XLCDC_LAYER_DISCEN BIT(4)
+
+#define ATMEL_XLCDC_LAYER_SFACTC_A0_MULT_AS (4 << 6)
+#define ATMEL_XLCDC_LAYER_SFACTA_ONE BIT(9)
+#define ATMEL_XLCDC_LAYER_DFACTC_M_A0_MULT_AS (6 << 11)
+#define ATMEL_XLCDC_LAYER_DFACTA_ONE BIT(14)
+
+#define ATMEL_XLCDC_LAYER_A0_SHIFT 16
+#define ATMEL_XLCDC_LAYER_A0(x) \
+ ((x) << ATMEL_XLCDC_LAYER_A0_SHIFT)
+
+#define ATMEL_XLCDC_LAYER_VSCALER_LUMA_ENABLE BIT(0)
+#define ATMEL_XLCDC_LAYER_VSCALER_CHROMA_ENABLE BIT(1)
+#define ATMEL_XLCDC_LAYER_HSCALER_LUMA_ENABLE BIT(4)
+#define ATMEL_XLCDC_LAYER_HSCALER_CHROMA_ENABLE BIT(5)
+
+#define ATMEL_XLCDC_LAYER_VXSYCFG_ONE BIT(0)
+#define ATMEL_XLCDC_LAYER_VXSYTAP2_ENABLE BIT(4)
+#define ATMEL_XLCDC_LAYER_VXSCCFG_ONE BIT(16)
+#define ATMEL_XLCDC_LAYER_VXSCTAP2_ENABLE BIT(20)
+
+#define ATMEL_XLCDC_LAYER_HXSYCFG_ONE BIT(0)
+#define ATMEL_XLCDC_LAYER_HXSYTAP2_ENABLE BIT(4)
+#define ATMEL_XLCDC_LAYER_HXSCCFG_ONE BIT(16)
+#define ATMEL_XLCDC_LAYER_HXSCTAP2_ENABLE BIT(20)
+
/**
* Atmel HLCDC Layer registers layout structure
*
diff --git a/include/linux/mfd/atmel-hlcdc.h b/include/linux/mfd/atmel-hlcdc.h
index a186119a49b5..80d675a03b39 100644
--- a/include/linux/mfd/atmel-hlcdc.h
+++ b/include/linux/mfd/atmel-hlcdc.h
@@ -22,6 +22,8 @@
#define ATMEL_HLCDC_DITHER BIT(6)
#define ATMEL_HLCDC_DISPDLY BIT(7)
#define ATMEL_HLCDC_MODE_MASK GENMASK(9, 8)
+#define ATMEL_XLCDC_MODE_MASK GENMASK(10, 8)
+#define ATMEL_XLCDC_DPI BIT(11)
#define ATMEL_HLCDC_PP BIT(10)
#define ATMEL_HLCDC_VSPSU BIT(12)
#define ATMEL_HLCDC_VSPHO BIT(13)
@@ -34,6 +36,12 @@
#define ATMEL_HLCDC_IDR 0x30
#define ATMEL_HLCDC_IMR 0x34
#define ATMEL_HLCDC_ISR 0x38
+#define ATMEL_XLCDC_ATTRE 0x3c
+
+#define ATMEL_XLCDC_BASE_UPDATE BIT(0)
+#define ATMEL_XLCDC_OVR1_UPDATE BIT(1)
+#define ATMEL_XLCDC_OVR3_UPDATE BIT(2)
+#define ATMEL_XLCDC_HEO_UPDATE BIT(3)
#define ATMEL_HLCDC_CLKPOL BIT(0)
#define ATMEL_HLCDC_CLKSEL BIT(2)
@@ -48,6 +56,8 @@
#define ATMEL_HLCDC_DISP BIT(2)
#define ATMEL_HLCDC_PWM BIT(3)
#define ATMEL_HLCDC_SIP BIT(4)
+#define ATMEL_XLCDC_SD BIT(5)
+#define ATMEL_XLCDC_CM BIT(6)
#define ATMEL_HLCDC_SOF BIT(0)
#define ATMEL_HLCDC_SYNCDIS BIT(1)
--
2.25.1
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH v5 4/8] drm: atmel-hlcdc: Define SAM9X7 SoC XLCDC specific registers
2023-09-15 10:48 ` [PATCH v5 4/8] drm: atmel-hlcdc: Define SAM9X7 SoC XLCDC specific registers Manikandan Muralidharan
@ 2023-09-25 14:14 ` claudiu beznea
0 siblings, 0 replies; 14+ messages in thread
From: claudiu beznea @ 2023-09-25 14:14 UTC (permalink / raw)
To: Manikandan Muralidharan, sam, bbrezillon, airlied, daniel,
nicolas.ferre, alexandre.belloni, lee, dri-devel,
linux-arm-kernel, linux-kernel
Cc: Hari.PrasathGE, Balamanikandan.Gunasundar, Durai.ManickamKR,
Nayabbasha.Sayed, Dharma.B, Varshini.Rajendran, Balakrishnan.S
On 15.09.2023 13:48, Manikandan Muralidharan wrote:
> From: Durai Manickam KR <durai.manickamkr@microchip.com>
>
> The register address of the XLCDC IP used in SAM9X7 SoC family
> are different from the previous HLCDC.Defining those address
Add a space after .
> space with valid macros.
>
> Signed-off-by: Durai Manickam KR <durai.manickamkr@microchip.com>
> [manikandan.m@microchip.com: Remove unused macro definitions]
> Signed-off-by: Manikandan Muralidharan <manikandan.m@microchip.com>
> ---
> drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h | 42 ++++++++++++++++++++
> include/linux/mfd/atmel-hlcdc.h | 10 +++++
> 2 files changed, 52 insertions(+)
>
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
> index c61fa1733da4..9965c7cc5bf8 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
> @@ -15,6 +15,7 @@
>
> #include <drm/drm_plane.h>
>
> +/* LCD controller common registers */
> #define ATMEL_HLCDC_LAYER_CHER 0x0
> #define ATMEL_HLCDC_LAYER_CHDR 0x4
> #define ATMEL_HLCDC_LAYER_CHSR 0x8
> @@ -128,6 +129,47 @@
>
> #define ATMEL_HLCDC_MAX_LAYERS 6
>
> +/* XLCDC controller specific registers */
> +#define ATMEL_XLCDC_LAYER_ENR 0x10
> +#define ATMEL_XLCDC_LAYER_EN BIT(0)
> +
> +#define ATMEL_XLCDC_LAYER_IER 0x0
> +#define ATMEL_XLCDC_LAYER_IDR 0x4
> +#define ATMEL_XLCDC_LAYER_ISR 0xc
> +#define ATMEL_XLCDC_LAYER_OVR_IRQ(p) BIT(2 + (8 * (p)))
> +
> +#define ATMEL_XLCDC_LAYER_PLANE_ADDR(p) (((p) * 0x4) + 0x18)
> +
> +#define ATMEL_XLCDC_LAYER_DMA_CFG 0
> +
> +#define ATMEL_XLCDC_LAYER_DMA BIT(0)
> +#define ATMEL_XLCDC_LAYER_REP BIT(1)
> +#define ATMEL_XLCDC_LAYER_DISCEN BIT(4)
> +
> +#define ATMEL_XLCDC_LAYER_SFACTC_A0_MULT_AS (4 << 6)
> +#define ATMEL_XLCDC_LAYER_SFACTA_ONE BIT(9)
> +#define ATMEL_XLCDC_LAYER_DFACTC_M_A0_MULT_AS (6 << 11)
> +#define ATMEL_XLCDC_LAYER_DFACTA_ONE BIT(14)
> +
> +#define ATMEL_XLCDC_LAYER_A0_SHIFT 16
> +#define ATMEL_XLCDC_LAYER_A0(x) \
> + ((x) << ATMEL_XLCDC_LAYER_A0_SHIFT)
> +
> +#define ATMEL_XLCDC_LAYER_VSCALER_LUMA_ENABLE BIT(0)
> +#define ATMEL_XLCDC_LAYER_VSCALER_CHROMA_ENABLE BIT(1)
> +#define ATMEL_XLCDC_LAYER_HSCALER_LUMA_ENABLE BIT(4)
> +#define ATMEL_XLCDC_LAYER_HSCALER_CHROMA_ENABLE BIT(5)
> +
> +#define ATMEL_XLCDC_LAYER_VXSYCFG_ONE BIT(0)
> +#define ATMEL_XLCDC_LAYER_VXSYTAP2_ENABLE BIT(4)
> +#define ATMEL_XLCDC_LAYER_VXSCCFG_ONE BIT(16)
> +#define ATMEL_XLCDC_LAYER_VXSCTAP2_ENABLE BIT(20)
> +
> +#define ATMEL_XLCDC_LAYER_HXSYCFG_ONE BIT(0)
> +#define ATMEL_XLCDC_LAYER_HXSYTAP2_ENABLE BIT(4)
> +#define ATMEL_XLCDC_LAYER_HXSCCFG_ONE BIT(16)
> +#define ATMEL_XLCDC_LAYER_HXSCTAP2_ENABLE BIT(20)
> +
> /**
> * Atmel HLCDC Layer registers layout structure
> *
> diff --git a/include/linux/mfd/atmel-hlcdc.h b/include/linux/mfd/atmel-hlcdc.h
> index a186119a49b5..80d675a03b39 100644
> --- a/include/linux/mfd/atmel-hlcdc.h
> +++ b/include/linux/mfd/atmel-hlcdc.h
> @@ -22,6 +22,8 @@
> #define ATMEL_HLCDC_DITHER BIT(6)
> #define ATMEL_HLCDC_DISPDLY BIT(7)
> #define ATMEL_HLCDC_MODE_MASK GENMASK(9, 8)
> +#define ATMEL_XLCDC_MODE_MASK GENMASK(10, 8)
> +#define ATMEL_XLCDC_DPI BIT(11)
> #define ATMEL_HLCDC_PP BIT(10)
> #define ATMEL_HLCDC_VSPSU BIT(12)
> #define ATMEL_HLCDC_VSPHO BIT(13)
> @@ -34,6 +36,12 @@
> #define ATMEL_HLCDC_IDR 0x30
> #define ATMEL_HLCDC_IMR 0x34
> #define ATMEL_HLCDC_ISR 0x38
> +#define ATMEL_XLCDC_ATTRE 0x3c
> +
> +#define ATMEL_XLCDC_BASE_UPDATE BIT(0)
> +#define ATMEL_XLCDC_OVR1_UPDATE BIT(1)
> +#define ATMEL_XLCDC_OVR3_UPDATE BIT(2)
> +#define ATMEL_XLCDC_HEO_UPDATE BIT(3)
>
> #define ATMEL_HLCDC_CLKPOL BIT(0)
> #define ATMEL_HLCDC_CLKSEL BIT(2)
> @@ -48,6 +56,8 @@
> #define ATMEL_HLCDC_DISP BIT(2)
> #define ATMEL_HLCDC_PWM BIT(3)
> #define ATMEL_HLCDC_SIP BIT(4)
> +#define ATMEL_XLCDC_SD BIT(5)
> +#define ATMEL_XLCDC_CM BIT(6)
>
> #define ATMEL_HLCDC_SOF BIT(0)
> #define ATMEL_HLCDC_SYNCDIS BIT(1)
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v5 5/8] drm: atmel_hlcdc: Add support for XLCDC in atmel LCD driver
2023-09-15 10:48 [PATCH v5 0/8] Add support for XLCDC to sam9x7 SoC family Manikandan Muralidharan
` (3 preceding siblings ...)
2023-09-15 10:48 ` [PATCH v5 4/8] drm: atmel-hlcdc: Define SAM9X7 SoC XLCDC specific registers Manikandan Muralidharan
@ 2023-09-15 10:48 ` Manikandan Muralidharan
2023-09-25 14:17 ` claudiu beznea
2023-09-15 10:48 ` [PATCH v5 6/8] drm: atmel-hlcdc: add DPI mode support for XLCDC Manikandan Muralidharan
` (2 subsequent siblings)
7 siblings, 1 reply; 14+ messages in thread
From: Manikandan Muralidharan @ 2023-09-15 10:48 UTC (permalink / raw)
To: sam, bbrezillon, airlied, daniel, nicolas.ferre,
alexandre.belloni, lee, dri-devel, linux-arm-kernel,
linux-kernel
Cc: Hari.PrasathGE, Balamanikandan.Gunasundar, Durai.ManickamKR,
Nayabbasha.Sayed, Dharma.B, Varshini.Rajendran, Balakrishnan.S,
Manikandan Muralidharan, Durai Manickam KR
- XLCDC in SAM9X7 has different sets of registers and additional
configuration bits when compared to previous HLCDC IP. Read/write
operation on the controller registers is now separated using the
XLCDC status flag and with HLCDC and XLCDC IP specific ops.
- HEO scaling, window resampling, Alpha blending, YUV-to-RGB
conversion in XLCDC is derived and handled using additional
configuration bits and registers.
- Writing one to the Enable fields of each layer in LCD_ATTRE
is required to reflect the values set in Configuration, FBA, Enable
registers of each layer
Signed-off-by: Manikandan Muralidharan <manikandan.m@microchip.com>
Co-developed-by: Hari Prasath Gujulan Elango <Hari.PrasathGE@microchip.com>
Signed-off-by: Hari Prasath Gujulan Elango <Hari.PrasathGE@microchip.com>
Co-developed-by: Durai Manickam KR <durai.manickamkr@microchip.com>
Signed-off-by: Durai Manickam KR <durai.manickamkr@microchip.com>
---
.../gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c | 33 +-
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 26 ++
.../gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 317 ++++++++++++++----
3 files changed, 315 insertions(+), 61 deletions(-)
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
index cc5cf4c2faf7..1ac31c0c474a 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
@@ -79,6 +79,7 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct drm_crtc *c)
unsigned int mask = ATMEL_HLCDC_CLKDIV_MASK | ATMEL_HLCDC_CLKPOL;
unsigned int cfg = 0;
int div, ret;
+ bool is_xlcdc = crtc->dc->desc->is_xlcdc;
/* get encoder from crtc */
drm_for_each_encoder(en_iter, ddev) {
@@ -164,10 +165,10 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct drm_crtc *c)
state = drm_crtc_state_to_atmel_hlcdc_crtc_state(c->state);
cfg = state->output_mode << 8;
- if (adj->flags & DRM_MODE_FLAG_NVSYNC)
+ if (!is_xlcdc && (adj->flags & DRM_MODE_FLAG_NVSYNC))
cfg |= ATMEL_HLCDC_VSPOL;
- if (adj->flags & DRM_MODE_FLAG_NHSYNC)
+ if (!is_xlcdc && (adj->flags & DRM_MODE_FLAG_NHSYNC))
cfg |= ATMEL_HLCDC_HSPOL;
regmap_update_bits(regmap, ATMEL_HLCDC_CFG(5),
@@ -202,6 +203,20 @@ static void atmel_hlcdc_crtc_atomic_disable(struct drm_crtc *c,
pm_runtime_get_sync(dev->dev);
+ if (crtc->dc->desc->is_xlcdc) {
+ regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_XLCDC_CM);
+ if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
+ !(status & ATMEL_XLCDC_CM),
+ 10, 1000))
+ dev_warn(dev->dev, "Atmel LCDC status register CMSTS timeout\n");
+
+ regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_XLCDC_SD);
+ if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
+ status & ATMEL_XLCDC_SD,
+ 10, 1000))
+ dev_warn(dev->dev, "Atmel LCDC status register SDSTS timeout\n");
+ }
+
regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_HLCDC_DISP);
while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
(status & ATMEL_HLCDC_DISP))
@@ -256,6 +271,20 @@ static void atmel_hlcdc_crtc_atomic_enable(struct drm_crtc *c,
!(status & ATMEL_HLCDC_DISP))
cpu_relax();
+ if (crtc->dc->desc->is_xlcdc) {
+ regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_XLCDC_CM);
+ if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
+ status & ATMEL_XLCDC_CM,
+ 10, 1000))
+ dev_warn(dev->dev, "Atmel LCDC status register CMSTS timeout\n");
+
+ regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_XLCDC_SD);
+ if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
+ !(status & ATMEL_XLCDC_SD),
+ 10, 1000))
+ dev_warn(dev->dev, "Atmel LCDC status register SDSTS timeout\n");
+ }
+
pm_runtime_put_sync(dev->dev);
}
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
index d30aec174aa2..7702c2f16178 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
@@ -30,6 +30,26 @@
#define ATMEL_HLCDC_LAYER_IRQS_OFFSET 8
+static const struct atmel_lcdc_dc_ops atmel_hlcdc_ops = {
+ .plane_setup_scaler = atmel_hlcdc_plane_setup_scaler,
+ .update_lcdc_buffers = update_hlcdc_buffers,
+ .lcdc_atomic_disable = hlcdc_atomic_disable,
+ .lcdc_update_general_settings = atmel_hlcdc_plane_update_general_settings,
+ .lcdc_atomic_update = hlcdc_atomic_update,
+ .lcdc_csc_init = hlcdc_csc_init,
+ .lcdc_irq_dbg = hlcdc_irq_dbg,
+};
+
+static const struct atmel_lcdc_dc_ops atmel_xlcdc_ops = {
+ .plane_setup_scaler = atmel_xlcdc_plane_setup_scaler,
+ .update_lcdc_buffers = update_xlcdc_buffers,
+ .lcdc_atomic_disable = xlcdc_atomic_disable,
+ .lcdc_update_general_settings = atmel_xlcdc_plane_update_general_settings,
+ .lcdc_atomic_update = xlcdc_atomic_update,
+ .lcdc_csc_init = xlcdc_csc_init,
+ .lcdc_irq_dbg = xlcdc_irq_dbg,
+};
+
static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9n12_layers[] = {
{
.name = "base",
@@ -58,6 +78,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_at91sam9n12 = {
.conflicting_output_formats = true,
.nlayers = ARRAY_SIZE(atmel_hlcdc_at91sam9n12_layers),
.layers = atmel_hlcdc_at91sam9n12_layers,
+ .ops = &atmel_hlcdc_ops,
};
static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = {
@@ -151,6 +172,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_at91sam9x5 = {
.conflicting_output_formats = true,
.nlayers = ARRAY_SIZE(atmel_hlcdc_at91sam9x5_layers),
.layers = atmel_hlcdc_at91sam9x5_layers,
+ .ops = &atmel_hlcdc_ops,
};
static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
@@ -269,6 +291,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sama5d3 = {
.conflicting_output_formats = true,
.nlayers = ARRAY_SIZE(atmel_hlcdc_sama5d3_layers),
.layers = atmel_hlcdc_sama5d3_layers,
+ .ops = &atmel_hlcdc_ops,
};
static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = {
@@ -364,6 +387,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sama5d4 = {
.max_hpw = 0x3ff,
.nlayers = ARRAY_SIZE(atmel_hlcdc_sama5d4_layers),
.layers = atmel_hlcdc_sama5d4_layers,
+ .ops = &atmel_hlcdc_ops,
};
static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sam9x60_layers[] = {
@@ -460,6 +484,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sam9x60 = {
.fixed_clksrc = true,
.nlayers = ARRAY_SIZE(atmel_hlcdc_sam9x60_layers),
.layers = atmel_hlcdc_sam9x60_layers,
+ .ops = &atmel_hlcdc_ops,
};
static const struct atmel_hlcdc_layer_desc atmel_xlcdc_sam9x75_layers[] = {
@@ -553,6 +578,7 @@ static const struct atmel_hlcdc_dc_desc atmel_xlcdc_dc_sam9x75 = {
.is_xlcdc = true,
.nlayers = ARRAY_SIZE(atmel_xlcdc_sam9x75_layers),
.layers = atmel_xlcdc_sam9x75_layers,
+ .ops = &atmel_xlcdc_ops,
};
static const struct of_device_id atmel_hlcdc_of_match[] = {
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
index daa508504f47..e2a5bed86fdb 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
@@ -282,7 +282,7 @@ atmel_hlcdc_plane_scaler_set_phicoeff(struct atmel_hlcdc_plane *plane,
coeff_tab[i]);
}
-static void atmel_hlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
+void atmel_hlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
struct atmel_hlcdc_plane_state *state)
{
const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
@@ -330,11 +330,56 @@ static void atmel_hlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
yfactor));
}
+void atmel_xlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_plane_state *state)
+{
+ const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
+ u32 xfactor, yfactor;
+
+ if (!desc->layout.scaler_config)
+ return;
+
+ if (state->crtc_w == state->src_w && state->crtc_h == state->src_h) {
+ atmel_hlcdc_layer_write_cfg(&plane->layer,
+ desc->layout.scaler_config, 0);
+ return;
+ }
+
+ /* xfactor = round[(2^20 * XMEMSIZE)/XSIZE)] */
+ xfactor = (u32)(((1 << 20) * state->src_w) / state->crtc_w);
+
+ /* yfactor = round[(2^20 * YMEMSIZE)/YSIZE)] */
+ yfactor = (u32)(((1 << 20) * state->src_h) / state->crtc_h);
+
+ atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config,
+ ATMEL_XLCDC_LAYER_VSCALER_LUMA_ENABLE |
+ ATMEL_XLCDC_LAYER_VSCALER_CHROMA_ENABLE |
+ ATMEL_XLCDC_LAYER_HSCALER_LUMA_ENABLE |
+ ATMEL_XLCDC_LAYER_HSCALER_CHROMA_ENABLE);
+
+ atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 1,
+ yfactor);
+ atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 3,
+ xfactor);
+
+ /* As per YCbCr window resampling configuration */
+ if (state->base.fb->format->format == DRM_FORMAT_YUV420) {
+ yfactor /= 2;
+ xfactor /= 2;
+ } /* else As per ARGB window resampling configuration */
+
+ atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 2,
+ yfactor);
+ atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 4,
+ xfactor);
+}
+
static void
atmel_hlcdc_plane_update_pos_and_size(struct atmel_hlcdc_plane *plane,
struct atmel_hlcdc_plane_state *state)
{
const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
+ struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
if (desc->layout.size)
atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.size,
@@ -352,10 +397,10 @@ atmel_hlcdc_plane_update_pos_and_size(struct atmel_hlcdc_plane *plane,
ATMEL_HLCDC_LAYER_POS(state->crtc_x,
state->crtc_y));
- atmel_hlcdc_plane_setup_scaler(plane, state);
+ dc->desc->ops->plane_setup_scaler(plane, state);
}
-static void
+void
atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
struct atmel_hlcdc_plane_state *state)
{
@@ -393,6 +438,40 @@ atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
cfg);
}
+void
+atmel_xlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_plane_state *state)
+{
+ unsigned int cfg;
+ const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
+ const struct drm_format_info *format = state->base.fb->format;
+
+ atmel_hlcdc_layer_write_cfg(&plane->layer, ATMEL_XLCDC_LAYER_DMA_CFG,
+ ATMEL_HLCDC_LAYER_DMA_BLEN_INCR16 | state->ahb_id);
+
+ cfg = ATMEL_XLCDC_LAYER_DMA | ATMEL_XLCDC_LAYER_REP;
+
+ if (plane->base.type != DRM_PLANE_TYPE_PRIMARY) {
+ /*
+ * Alpha Blending bits specific to SAM9X7 SoC
+ */
+ cfg |= ATMEL_XLCDC_LAYER_SFACTC_A0_MULT_AS |
+ ATMEL_XLCDC_LAYER_SFACTA_ONE |
+ ATMEL_XLCDC_LAYER_DFACTC_M_A0_MULT_AS |
+ ATMEL_XLCDC_LAYER_DFACTA_ONE;
+ if (format->has_alpha)
+ cfg |= ATMEL_XLCDC_LAYER_A0(0xff);
+ else
+ cfg |= ATMEL_XLCDC_LAYER_A0(state->base.alpha);
+ }
+
+ if (state->disc_h && state->disc_w)
+ cfg |= ATMEL_XLCDC_LAYER_DISCEN;
+
+ atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.general_config,
+ cfg);
+}
+
static void atmel_hlcdc_plane_update_format(struct atmel_hlcdc_plane *plane,
struct atmel_hlcdc_plane_state *state)
{
@@ -437,36 +516,53 @@ static void atmel_hlcdc_plane_update_clut(struct atmel_hlcdc_plane *plane,
}
}
+void update_hlcdc_buffers(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_plane_state *state, u32 sr, int i)
+{
+ atmel_hlcdc_layer_write_reg(&plane->layer,
+ ATMEL_HLCDC_LAYER_PLANE_HEAD(i),
+ state->dscrs[i]->self);
+
+ if (sr & ATMEL_HLCDC_LAYER_EN)
+ return;
+ atmel_hlcdc_layer_write_reg(&plane->layer,
+ ATMEL_HLCDC_LAYER_PLANE_ADDR(i),
+ state->dscrs[i]->addr);
+ atmel_hlcdc_layer_write_reg(&plane->layer,
+ ATMEL_HLCDC_LAYER_PLANE_CTRL(i),
+ state->dscrs[i]->ctrl);
+ atmel_hlcdc_layer_write_reg(&plane->layer,
+ ATMEL_HLCDC_LAYER_PLANE_NEXT(i),
+ state->dscrs[i]->self);
+}
+
+void update_xlcdc_buffers(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_plane_state *state,
+ u32 sr, int i)
+{
+ atmel_hlcdc_layer_write_reg(&plane->layer,
+ ATMEL_XLCDC_LAYER_PLANE_ADDR(i),
+ state->dscrs[i]->addr);
+}
+
static void atmel_hlcdc_plane_update_buffers(struct atmel_hlcdc_plane *plane,
- struct atmel_hlcdc_plane_state *state)
+ struct atmel_hlcdc_plane_state *state)
{
const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
+ struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
struct drm_framebuffer *fb = state->base.fb;
u32 sr;
int i;
- sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR);
+ if (!dc->desc->is_xlcdc)
+ sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR);
for (i = 0; i < state->nplanes; i++) {
struct drm_gem_dma_object *gem = drm_fb_dma_get_gem_obj(fb, i);
state->dscrs[i]->addr = gem->dma_addr + state->offsets[i];
- atmel_hlcdc_layer_write_reg(&plane->layer,
- ATMEL_HLCDC_LAYER_PLANE_HEAD(i),
- state->dscrs[i]->self);
-
- if (!(sr & ATMEL_HLCDC_LAYER_EN)) {
- atmel_hlcdc_layer_write_reg(&plane->layer,
- ATMEL_HLCDC_LAYER_PLANE_ADDR(i),
- state->dscrs[i]->addr);
- atmel_hlcdc_layer_write_reg(&plane->layer,
- ATMEL_HLCDC_LAYER_PLANE_CTRL(i),
- state->dscrs[i]->ctrl);
- atmel_hlcdc_layer_write_reg(&plane->layer,
- ATMEL_HLCDC_LAYER_PLANE_NEXT(i),
- state->dscrs[i]->self);
- }
+ dc->desc->ops->update_lcdc_buffers(plane, state, sr, i);
if (desc->layout.xstride[i])
atmel_hlcdc_layer_write_cfg(&plane->layer,
@@ -712,11 +808,8 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p,
return 0;
}
-static void atmel_hlcdc_plane_atomic_disable(struct drm_plane *p,
- struct drm_atomic_state *state)
+void hlcdc_atomic_disable(struct atmel_hlcdc_plane *plane)
{
- struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
-
/* Disable interrupts */
atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_IDR,
0xffffffff);
@@ -731,6 +824,70 @@ static void atmel_hlcdc_plane_atomic_disable(struct drm_plane *p,
atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_ISR);
}
+void xlcdc_atomic_disable(struct atmel_hlcdc_plane *plane)
+{
+ /* Disable interrupts */
+ atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_XLCDC_LAYER_IDR,
+ 0xffffffff);
+
+ /* Disable the layer */
+ atmel_hlcdc_layer_write_reg(&plane->layer,
+ ATMEL_XLCDC_LAYER_ENR, 0);
+
+ /* Clear all pending interrupts */
+ atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_XLCDC_LAYER_ISR);
+}
+
+static void atmel_hlcdc_plane_atomic_disable(struct drm_plane *p,
+ struct drm_atomic_state *state)
+{
+ struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
+ struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
+
+ dc->desc->ops->lcdc_atomic_disable(plane);
+}
+
+void hlcdc_atomic_update(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_dc *dc)
+{
+ u32 sr;
+
+ /* Enable the overrun interrupts. */
+ atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_IER,
+ ATMEL_HLCDC_LAYER_OVR_IRQ(0) |
+ ATMEL_HLCDC_LAYER_OVR_IRQ(1) |
+ ATMEL_HLCDC_LAYER_OVR_IRQ(2));
+
+ /* Apply the new config at the next SOF event. */
+ sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR);
+ atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHER,
+ ATMEL_HLCDC_LAYER_UPDATE |
+ (sr & ATMEL_HLCDC_LAYER_EN ?
+ ATMEL_HLCDC_LAYER_A2Q : ATMEL_HLCDC_LAYER_EN));
+}
+
+void xlcdc_atomic_update(struct atmel_hlcdc_plane *plane,
+ struct atmel_hlcdc_dc *dc)
+{
+ /* Enable the overrun interrupts. */
+ atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_XLCDC_LAYER_IER,
+ ATMEL_XLCDC_LAYER_OVR_IRQ(0) |
+ ATMEL_XLCDC_LAYER_OVR_IRQ(1) |
+ ATMEL_XLCDC_LAYER_OVR_IRQ(2));
+
+ atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_XLCDC_LAYER_ENR,
+ ATMEL_XLCDC_LAYER_EN);
+
+ /*
+ * Updating XLCDC_xxxCFGx, XLCDC_xxxFBA and XLCDC_xxxEN,
+ * (where xxx indicates each layer) requires writing one to the
+ * Update Attribute field for each layer in LCDC_ATTRE register for SAM9X7.
+ */
+ regmap_write(dc->hlcdc->regmap, ATMEL_XLCDC_ATTRE, ATMEL_XLCDC_BASE_UPDATE |
+ ATMEL_XLCDC_OVR1_UPDATE | ATMEL_XLCDC_OVR3_UPDATE |
+ ATMEL_XLCDC_HEO_UPDATE);
+}
+
static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p,
struct drm_atomic_state *state)
{
@@ -739,7 +896,7 @@ static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p,
struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
struct atmel_hlcdc_plane_state *hstate =
drm_plane_state_to_atmel_hlcdc_plane_state(new_s);
- u32 sr;
+ struct atmel_hlcdc_dc *dc = p->dev->dev_private;
if (!new_s->crtc || !new_s->fb)
return;
@@ -750,29 +907,63 @@ static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p,
}
atmel_hlcdc_plane_update_pos_and_size(plane, hstate);
- atmel_hlcdc_plane_update_general_settings(plane, hstate);
+ dc->desc->ops->lcdc_update_general_settings(plane, hstate);
atmel_hlcdc_plane_update_format(plane, hstate);
atmel_hlcdc_plane_update_clut(plane, hstate);
atmel_hlcdc_plane_update_buffers(plane, hstate);
atmel_hlcdc_plane_update_disc_area(plane, hstate);
- /* Enable the overrun interrupts. */
- atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_IER,
- ATMEL_HLCDC_LAYER_OVR_IRQ(0) |
- ATMEL_HLCDC_LAYER_OVR_IRQ(1) |
- ATMEL_HLCDC_LAYER_OVR_IRQ(2));
+ dc->desc->ops->lcdc_atomic_update(plane, dc);
+}
- /* Apply the new config at the next SOF event. */
- sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR);
- atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHER,
- ATMEL_HLCDC_LAYER_UPDATE |
- (sr & ATMEL_HLCDC_LAYER_EN ?
- ATMEL_HLCDC_LAYER_A2Q : ATMEL_HLCDC_LAYER_EN));
+void hlcdc_csc_init(struct atmel_hlcdc_plane *plane,
+ const struct atmel_hlcdc_layer_desc *desc)
+{
+ /*
+ * TODO: declare a "yuv-to-rgb-conv-factors" property to let
+ * userspace modify these factors (using a BLOB property ?).
+ */
+ static u32 hlcdc_csc_coeffs[] = {
+ 0x4c900091,
+ 0x7a5f5090,
+ 0x40040890
+ };
+
+ for (int i = 0; i < ARRAY_SIZE(hlcdc_csc_coeffs); i++) {
+ atmel_hlcdc_layer_write_cfg(&plane->layer,
+ desc->layout.csc + i,
+ hlcdc_csc_coeffs[i]);
+ }
+}
+
+void xlcdc_csc_init(struct atmel_hlcdc_plane *plane,
+ const struct atmel_hlcdc_layer_desc *desc)
+{
+ /*
+ * yuv-to-rgb-conv-factors are now defined from LCDC_HEOCFG16 to
+ * LCDC_HEOCFG21 registers in SAM9X7.
+ */
+ static u32 xlcdc_csc_coeffs[] = {
+ 0x00000488,
+ 0x00000648,
+ 0x1EA00480,
+ 0x00001D28,
+ 0x08100480,
+ 0x00000000,
+ 0x00000007
+ };
+
+ for (int i = 0; i < ARRAY_SIZE(xlcdc_csc_coeffs); i++) {
+ atmel_hlcdc_layer_write_cfg(&plane->layer,
+ desc->layout.csc + i,
+ xlcdc_csc_coeffs[i]);
+ }
}
static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane)
{
const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
+ struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
if (desc->type == ATMEL_HLCDC_OVERLAY_LAYER ||
desc->type == ATMEL_HLCDC_CURSOR_LAYER) {
@@ -796,31 +987,16 @@ static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane)
return ret;
}
- if (desc->layout.csc) {
- /*
- * TODO: decare a "yuv-to-rgb-conv-factors" property to let
- * userspace modify these factors (using a BLOB property ?).
- */
- atmel_hlcdc_layer_write_cfg(&plane->layer,
- desc->layout.csc,
- 0x4c900091);
- atmel_hlcdc_layer_write_cfg(&plane->layer,
- desc->layout.csc + 1,
- 0x7a5f5090);
- atmel_hlcdc_layer_write_cfg(&plane->layer,
- desc->layout.csc + 2,
- 0x40040890);
- }
+ if (desc->layout.csc)
+ dc->desc->ops->lcdc_csc_init(plane, desc);
return 0;
}
-void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane)
+void hlcdc_irq_dbg(struct atmel_hlcdc_plane *plane,
+ const struct atmel_hlcdc_layer_desc *desc)
{
- const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
- u32 isr;
-
- isr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_ISR);
+ u32 isr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_ISR);
/*
* There's not much we can do in case of overrun except informing
@@ -830,8 +1006,31 @@ void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane)
if (isr &
(ATMEL_HLCDC_LAYER_OVR_IRQ(0) | ATMEL_HLCDC_LAYER_OVR_IRQ(1) |
ATMEL_HLCDC_LAYER_OVR_IRQ(2)))
- dev_dbg(plane->base.dev->dev, "overrun on plane %s\n",
- desc->name);
+ dev_warn(plane->base.dev->dev, "overrun on plane %s\n", desc->name);
+}
+
+void xlcdc_irq_dbg(struct atmel_hlcdc_plane *plane,
+ const struct atmel_hlcdc_layer_desc *desc)
+{
+ u32 isr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_XLCDC_LAYER_ISR);
+
+ /*
+ * There's not much we can do in case of overrun except informing
+ * the user. However, we are in interrupt context here, hence the
+ * use of dev_dbg().
+ */
+ if (isr &
+ (ATMEL_XLCDC_LAYER_OVR_IRQ(0) | ATMEL_XLCDC_LAYER_OVR_IRQ(1) |
+ ATMEL_XLCDC_LAYER_OVR_IRQ(2)))
+ dev_warn(plane->base.dev->dev, "overrun on plane %s\n", desc->name);
+}
+
+void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane)
+{
+ const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
+ struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
+
+ dc->desc->ops->lcdc_irq_dbg(plane, desc);
}
static const struct drm_plane_helper_funcs atmel_hlcdc_layer_plane_helper_funcs = {
--
2.25.1
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH v5 5/8] drm: atmel_hlcdc: Add support for XLCDC in atmel LCD driver
2023-09-15 10:48 ` [PATCH v5 5/8] drm: atmel_hlcdc: Add support for XLCDC in atmel LCD driver Manikandan Muralidharan
@ 2023-09-25 14:17 ` claudiu beznea
0 siblings, 0 replies; 14+ messages in thread
From: claudiu beznea @ 2023-09-25 14:17 UTC (permalink / raw)
To: Manikandan Muralidharan, sam, bbrezillon, airlied, daniel,
nicolas.ferre, alexandre.belloni, lee, dri-devel,
linux-arm-kernel, linux-kernel
Cc: Hari.PrasathGE, Balamanikandan.Gunasundar, Durai.ManickamKR,
Nayabbasha.Sayed, Dharma.B, Varshini.Rajendran, Balakrishnan.S
On 15.09.2023 13:48, Manikandan Muralidharan wrote:
> - XLCDC in SAM9X7 has different sets of registers and additional
> configuration bits when compared to previous HLCDC IP. Read/write
> operation on the controller registers is now separated using the
> XLCDC status flag and with HLCDC and XLCDC IP specific ops.
> - HEO scaling, window resampling, Alpha blending, YUV-to-RGB
> conversion in XLCDC is derived and handled using additional
> configuration bits and registers.
> - Writing one to the Enable fields of each layer in LCD_ATTRE
> is required to reflect the values set in Configuration, FBA, Enable
> registers of each layer
Having "-" may be interpreted as you are doing multiple things in this patch.
>
> Signed-off-by: Manikandan Muralidharan <manikandan.m@microchip.com>
> Co-developed-by: Hari Prasath Gujulan Elango <Hari.PrasathGE@microchip.com>
> Signed-off-by: Hari Prasath Gujulan Elango <Hari.PrasathGE@microchip.com>
> Co-developed-by: Durai Manickam KR <durai.manickamkr@microchip.com>
> Signed-off-by: Durai Manickam KR <durai.manickamkr@microchip.com>
> ---
> .../gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c | 33 +-
> drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 26 ++
> .../gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 317 ++++++++++++++----
> 3 files changed, 315 insertions(+), 61 deletions(-)
>
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
> index cc5cf4c2faf7..1ac31c0c474a 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
> @@ -79,6 +79,7 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct drm_crtc *c)
> unsigned int mask = ATMEL_HLCDC_CLKDIV_MASK | ATMEL_HLCDC_CLKPOL;
> unsigned int cfg = 0;
> int div, ret;
> + bool is_xlcdc = crtc->dc->desc->is_xlcdc;
>
> /* get encoder from crtc */
> drm_for_each_encoder(en_iter, ddev) {
> @@ -164,10 +165,10 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct drm_crtc *c)
> state = drm_crtc_state_to_atmel_hlcdc_crtc_state(c->state);
> cfg = state->output_mode << 8;
>
> - if (adj->flags & DRM_MODE_FLAG_NVSYNC)
> + if (!is_xlcdc && (adj->flags & DRM_MODE_FLAG_NVSYNC))
> cfg |= ATMEL_HLCDC_VSPOL;
>
> - if (adj->flags & DRM_MODE_FLAG_NHSYNC)
> + if (!is_xlcdc && (adj->flags & DRM_MODE_FLAG_NHSYNC))
> cfg |= ATMEL_HLCDC_HSPOL;
>
> regmap_update_bits(regmap, ATMEL_HLCDC_CFG(5),
> @@ -202,6 +203,20 @@ static void atmel_hlcdc_crtc_atomic_disable(struct drm_crtc *c,
>
> pm_runtime_get_sync(dev->dev);
>
> + if (crtc->dc->desc->is_xlcdc) {
> + regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_XLCDC_CM);
> + if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
> + !(status & ATMEL_XLCDC_CM),
> + 10, 1000))
> + dev_warn(dev->dev, "Atmel LCDC status register CMSTS timeout\n");
> +
> + regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_XLCDC_SD);
> + if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
> + status & ATMEL_XLCDC_SD,
> + 10, 1000))
> + dev_warn(dev->dev, "Atmel LCDC status register SDSTS timeout\n");
> + }
> +
> regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_HLCDC_DISP);
> while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) &&
> (status & ATMEL_HLCDC_DISP))
> @@ -256,6 +271,20 @@ static void atmel_hlcdc_crtc_atomic_enable(struct drm_crtc *c,
> !(status & ATMEL_HLCDC_DISP))
> cpu_relax();
>
> + if (crtc->dc->desc->is_xlcdc) {
> + regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_XLCDC_CM);
> + if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
> + status & ATMEL_XLCDC_CM,
> + 10, 1000))
> + dev_warn(dev->dev, "Atmel LCDC status register CMSTS timeout\n");
> +
> + regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_XLCDC_SD);
> + if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status,
> + !(status & ATMEL_XLCDC_SD),
> + 10, 1000))
> + dev_warn(dev->dev, "Atmel LCDC status register SDSTS timeout\n");
> + }
> +
> pm_runtime_put_sync(dev->dev);
>
> }
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> index d30aec174aa2..7702c2f16178 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
> @@ -30,6 +30,26 @@
>
> #define ATMEL_HLCDC_LAYER_IRQS_OFFSET 8
>
> +static const struct atmel_lcdc_dc_ops atmel_hlcdc_ops = {
there are 2 spaces b/w atmel_lcdc_dc_ops and atmel_hlcdc_ops.
> + .plane_setup_scaler = atmel_hlcdc_plane_setup_scaler,
> + .update_lcdc_buffers = update_hlcdc_buffers,
> + .lcdc_atomic_disable = hlcdc_atomic_disable,
> + .lcdc_update_general_settings = atmel_hlcdc_plane_update_general_settings,
> + .lcdc_atomic_update = hlcdc_atomic_update,
> + .lcdc_csc_init = hlcdc_csc_init,
> + .lcdc_irq_dbg = hlcdc_irq_dbg,
> +};
> +
> +static const struct atmel_lcdc_dc_ops atmel_xlcdc_ops = {
Same here.
> + .plane_setup_scaler = atmel_xlcdc_plane_setup_scaler,
> + .update_lcdc_buffers = update_xlcdc_buffers,
> + .lcdc_atomic_disable = xlcdc_atomic_disable,
> + .lcdc_update_general_settings = atmel_xlcdc_plane_update_general_settings,
> + .lcdc_atomic_update = xlcdc_atomic_update,
> + .lcdc_csc_init = xlcdc_csc_init,
> + .lcdc_irq_dbg = xlcdc_irq_dbg,
> +};
> +
> static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9n12_layers[] = {
> {
> .name = "base",
> @@ -58,6 +78,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_at91sam9n12 = {
> .conflicting_output_formats = true,
> .nlayers = ARRAY_SIZE(atmel_hlcdc_at91sam9n12_layers),
> .layers = atmel_hlcdc_at91sam9n12_layers,
> + .ops = &atmel_hlcdc_ops,
> };
>
> static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = {
> @@ -151,6 +172,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_at91sam9x5 = {
> .conflicting_output_formats = true,
> .nlayers = ARRAY_SIZE(atmel_hlcdc_at91sam9x5_layers),
> .layers = atmel_hlcdc_at91sam9x5_layers,
> + .ops = &atmel_hlcdc_ops,
> };
>
> static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = {
> @@ -269,6 +291,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sama5d3 = {
> .conflicting_output_formats = true,
> .nlayers = ARRAY_SIZE(atmel_hlcdc_sama5d3_layers),
> .layers = atmel_hlcdc_sama5d3_layers,
> + .ops = &atmel_hlcdc_ops,
> };
>
> static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = {
> @@ -364,6 +387,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sama5d4 = {
> .max_hpw = 0x3ff,
> .nlayers = ARRAY_SIZE(atmel_hlcdc_sama5d4_layers),
> .layers = atmel_hlcdc_sama5d4_layers,
> + .ops = &atmel_hlcdc_ops,
> };
>
> static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sam9x60_layers[] = {
> @@ -460,6 +484,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sam9x60 = {
> .fixed_clksrc = true,
> .nlayers = ARRAY_SIZE(atmel_hlcdc_sam9x60_layers),
> .layers = atmel_hlcdc_sam9x60_layers,
> + .ops = &atmel_hlcdc_ops,
> };
>
> static const struct atmel_hlcdc_layer_desc atmel_xlcdc_sam9x75_layers[] = {
> @@ -553,6 +578,7 @@ static const struct atmel_hlcdc_dc_desc atmel_xlcdc_dc_sam9x75 = {
> .is_xlcdc = true,
> .nlayers = ARRAY_SIZE(atmel_xlcdc_sam9x75_layers),
> .layers = atmel_xlcdc_sam9x75_layers,
> + .ops = &atmel_xlcdc_ops,
> };
>
> static const struct of_device_id atmel_hlcdc_of_match[] = {
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> index daa508504f47..e2a5bed86fdb 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
> @@ -282,7 +282,7 @@ atmel_hlcdc_plane_scaler_set_phicoeff(struct atmel_hlcdc_plane *plane,
> coeff_tab[i]);
> }
>
> -static void atmel_hlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
> +void atmel_hlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
> struct atmel_hlcdc_plane_state *state)
run checkpatch.pl on scripts: align struct atmel_hlcdc_plane_state *state
with (. But may not be needed if follows advices on previous patches.
> {
> const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
> @@ -330,11 +330,56 @@ static void atmel_hlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
> yfactor));
> }
>
> +void atmel_xlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane,
> + struct atmel_hlcdc_plane_state *state)
> +{
> + const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
> + u32 xfactor, yfactor;
> +
> + if (!desc->layout.scaler_config)
> + return;
> +
> + if (state->crtc_w == state->src_w && state->crtc_h == state->src_h) {
> + atmel_hlcdc_layer_write_cfg(&plane->layer,
> + desc->layout.scaler_config, 0);
> + return;
> + }
> +
> + /* xfactor = round[(2^20 * XMEMSIZE)/XSIZE)] */
> + xfactor = (u32)(((1 << 20) * state->src_w) / state->crtc_w);
> +
> + /* yfactor = round[(2^20 * YMEMSIZE)/YSIZE)] */
> + yfactor = (u32)(((1 << 20) * state->src_h) / state->crtc_h);
> +
> + atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config,
> + ATMEL_XLCDC_LAYER_VSCALER_LUMA_ENABLE |
> + ATMEL_XLCDC_LAYER_VSCALER_CHROMA_ENABLE |
> + ATMEL_XLCDC_LAYER_HSCALER_LUMA_ENABLE |
> + ATMEL_XLCDC_LAYER_HSCALER_CHROMA_ENABLE);
> +
> + atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 1,
> + yfactor);
> + atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 3,
> + xfactor);
> +
> + /* As per YCbCr window resampling configuration */
> + if (state->base.fb->format->format == DRM_FORMAT_YUV420) {
> + yfactor /= 2;
> + xfactor /= 2;
> + } /* else As per ARGB window resampling configuration */
This kind of describing behavior is a bit odd. You could try to describe
what is needed before if statement.
> +
> + atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 2,
> + yfactor);
> + atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 4,
> + xfactor);
> +}
> +
> static void
> atmel_hlcdc_plane_update_pos_and_size(struct atmel_hlcdc_plane *plane,
> struct atmel_hlcdc_plane_state *state)
> {
> const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
> + struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
>
> if (desc->layout.size)
> atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.size,
> @@ -352,10 +397,10 @@ atmel_hlcdc_plane_update_pos_and_size(struct atmel_hlcdc_plane *plane,
> ATMEL_HLCDC_LAYER_POS(state->crtc_x,
> state->crtc_y));
>
> - atmel_hlcdc_plane_setup_scaler(plane, state);
> + dc->desc->ops->plane_setup_scaler(plane, state);
> }
>
> -static void
> +void
> atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
> struct atmel_hlcdc_plane_state *state)
> {
> @@ -393,6 +438,40 @@ atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
> cfg);
> }
>
> +void
> +atmel_xlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane,
> + struct atmel_hlcdc_plane_state *state)
> +{
> + unsigned int cfg;
Add it after pointers. Reverse christmass tree is more readable AFAICT.
> + const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
> + const struct drm_format_info *format = state->base.fb->format;
> +
> + atmel_hlcdc_layer_write_cfg(&plane->layer, ATMEL_XLCDC_LAYER_DMA_CFG,
> + ATMEL_HLCDC_LAYER_DMA_BLEN_INCR16 | state->ahb_id);
> +
> + cfg = ATMEL_XLCDC_LAYER_DMA | ATMEL_XLCDC_LAYER_REP;
> +
> + if (plane->base.type != DRM_PLANE_TYPE_PRIMARY) {
> + /*
> + * Alpha Blending bits specific to SAM9X7 SoC
> + */
> + cfg |= ATMEL_XLCDC_LAYER_SFACTC_A0_MULT_AS |
> + ATMEL_XLCDC_LAYER_SFACTA_ONE |
> + ATMEL_XLCDC_LAYER_DFACTC_M_A0_MULT_AS |
> + ATMEL_XLCDC_LAYER_DFACTA_ONE;
> + if (format->has_alpha)
> + cfg |= ATMEL_XLCDC_LAYER_A0(0xff);
> + else
> + cfg |= ATMEL_XLCDC_LAYER_A0(state->base.alpha);
> + }
> +
> + if (state->disc_h && state->disc_w)
> + cfg |= ATMEL_XLCDC_LAYER_DISCEN;
> +
> + atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.general_config,
> + cfg);
> +}
> +
> static void atmel_hlcdc_plane_update_format(struct atmel_hlcdc_plane *plane,
> struct atmel_hlcdc_plane_state *state)
> {
> @@ -437,36 +516,53 @@ static void atmel_hlcdc_plane_update_clut(struct atmel_hlcdc_plane *plane,
> }
> }
>
> +void update_hlcdc_buffers(struct atmel_hlcdc_plane *plane,
> + struct atmel_hlcdc_plane_state *state, u32 sr, int i)
> +{
> + atmel_hlcdc_layer_write_reg(&plane->layer,
> + ATMEL_HLCDC_LAYER_PLANE_HEAD(i),
> + state->dscrs[i]->self);
> +
> + if (sr & ATMEL_HLCDC_LAYER_EN)
> + return;
One extra line here makes it more readable.
> + atmel_hlcdc_layer_write_reg(&plane->layer,
> + ATMEL_HLCDC_LAYER_PLANE_ADDR(i),
> + state->dscrs[i]->addr);
> + atmel_hlcdc_layer_write_reg(&plane->layer,
> + ATMEL_HLCDC_LAYER_PLANE_CTRL(i),
> + state->dscrs[i]->ctrl);
> + atmel_hlcdc_layer_write_reg(&plane->layer,
> + ATMEL_HLCDC_LAYER_PLANE_NEXT(i),
> + state->dscrs[i]->self);
> +}
> +
> +void update_xlcdc_buffers(struct atmel_hlcdc_plane *plane,
> + struct atmel_hlcdc_plane_state *state,
> + u32 sr, int i)
> +{
> + atmel_hlcdc_layer_write_reg(&plane->layer,
> + ATMEL_XLCDC_LAYER_PLANE_ADDR(i),
> + state->dscrs[i]->addr);
> +}
> +
> static void atmel_hlcdc_plane_update_buffers(struct atmel_hlcdc_plane *plane,
> - struct atmel_hlcdc_plane_state *state)
> + struct atmel_hlcdc_plane_state *state)
> {
> const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
> + struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
> struct drm_framebuffer *fb = state->base.fb;
> u32 sr;
> int i;
>
> - sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR);
> + if (!dc->desc->is_xlcdc)
> + sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR);
>
> for (i = 0; i < state->nplanes; i++) {
> struct drm_gem_dma_object *gem = drm_fb_dma_get_gem_obj(fb, i);
>
> state->dscrs[i]->addr = gem->dma_addr + state->offsets[i];
>
> - atmel_hlcdc_layer_write_reg(&plane->layer,
> - ATMEL_HLCDC_LAYER_PLANE_HEAD(i),
> - state->dscrs[i]->self);
> -
> - if (!(sr & ATMEL_HLCDC_LAYER_EN)) {
> - atmel_hlcdc_layer_write_reg(&plane->layer,
> - ATMEL_HLCDC_LAYER_PLANE_ADDR(i),
> - state->dscrs[i]->addr);
> - atmel_hlcdc_layer_write_reg(&plane->layer,
> - ATMEL_HLCDC_LAYER_PLANE_CTRL(i),
> - state->dscrs[i]->ctrl);
> - atmel_hlcdc_layer_write_reg(&plane->layer,
> - ATMEL_HLCDC_LAYER_PLANE_NEXT(i),
> - state->dscrs[i]->self);
> - }
> + dc->desc->ops->update_lcdc_buffers(plane, state, sr, i);
>
> if (desc->layout.xstride[i])
> atmel_hlcdc_layer_write_cfg(&plane->layer,
> @@ -712,11 +808,8 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p,
> return 0;
> }
>
> -static void atmel_hlcdc_plane_atomic_disable(struct drm_plane *p,
> - struct drm_atomic_state *state)
> +void hlcdc_atomic_disable(struct atmel_hlcdc_plane *plane)
> {
> - struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
> -
> /* Disable interrupts */
> atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_IDR,
> 0xffffffff);
> @@ -731,6 +824,70 @@ static void atmel_hlcdc_plane_atomic_disable(struct drm_plane *p,
> atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_ISR);
> }
>
> +void xlcdc_atomic_disable(struct atmel_hlcdc_plane *plane)
> +{
> + /* Disable interrupts */
> + atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_XLCDC_LAYER_IDR,
> + 0xffffffff);
> +
> + /* Disable the layer */
> + atmel_hlcdc_layer_write_reg(&plane->layer,
> + ATMEL_XLCDC_LAYER_ENR, 0);
> +
> + /* Clear all pending interrupts */
> + atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_XLCDC_LAYER_ISR);
> +}
> +
> +static void atmel_hlcdc_plane_atomic_disable(struct drm_plane *p,
> + struct drm_atomic_state *state)
> +{
> + struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
> + struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
> +
> + dc->desc->ops->lcdc_atomic_disable(plane);
> +}
> +
> +void hlcdc_atomic_update(struct atmel_hlcdc_plane *plane,
> + struct atmel_hlcdc_dc *dc)
> +{
> + u32 sr;
> +
> + /* Enable the overrun interrupts. */
> + atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_IER,
> + ATMEL_HLCDC_LAYER_OVR_IRQ(0) |
> + ATMEL_HLCDC_LAYER_OVR_IRQ(1) |
> + ATMEL_HLCDC_LAYER_OVR_IRQ(2));
> +
> + /* Apply the new config at the next SOF event. */
> + sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR);
> + atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHER,
> + ATMEL_HLCDC_LAYER_UPDATE |
> + (sr & ATMEL_HLCDC_LAYER_EN ?
> + ATMEL_HLCDC_LAYER_A2Q : ATMEL_HLCDC_LAYER_EN));
> +}
> +
> +void xlcdc_atomic_update(struct atmel_hlcdc_plane *plane,
> + struct atmel_hlcdc_dc *dc)
> +{
> + /* Enable the overrun interrupts. */
> + atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_XLCDC_LAYER_IER,
> + ATMEL_XLCDC_LAYER_OVR_IRQ(0) |
> + ATMEL_XLCDC_LAYER_OVR_IRQ(1) |
> + ATMEL_XLCDC_LAYER_OVR_IRQ(2));
> +
> + atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_XLCDC_LAYER_ENR,
> + ATMEL_XLCDC_LAYER_EN);
> +
> + /*
> + * Updating XLCDC_xxxCFGx, XLCDC_xxxFBA and XLCDC_xxxEN,
> + * (where xxx indicates each layer) requires writing one to the
> + * Update Attribute field for each layer in LCDC_ATTRE register for SAM9X7.
> + */
> + regmap_write(dc->hlcdc->regmap, ATMEL_XLCDC_ATTRE, ATMEL_XLCDC_BASE_UPDATE |
> + ATMEL_XLCDC_OVR1_UPDATE | ATMEL_XLCDC_OVR3_UPDATE |
> + ATMEL_XLCDC_HEO_UPDATE);
> +}
> +
> static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p,
> struct drm_atomic_state *state)
> {
> @@ -739,7 +896,7 @@ static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p,
> struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p);
> struct atmel_hlcdc_plane_state *hstate =
> drm_plane_state_to_atmel_hlcdc_plane_state(new_s);
> - u32 sr;
> + struct atmel_hlcdc_dc *dc = p->dev->dev_private;
>
> if (!new_s->crtc || !new_s->fb)
> return;
> @@ -750,29 +907,63 @@ static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p,
> }
>
> atmel_hlcdc_plane_update_pos_and_size(plane, hstate);
> - atmel_hlcdc_plane_update_general_settings(plane, hstate);
> + dc->desc->ops->lcdc_update_general_settings(plane, hstate);
> atmel_hlcdc_plane_update_format(plane, hstate);
> atmel_hlcdc_plane_update_clut(plane, hstate);
> atmel_hlcdc_plane_update_buffers(plane, hstate);
> atmel_hlcdc_plane_update_disc_area(plane, hstate);
>
> - /* Enable the overrun interrupts. */
> - atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_IER,
> - ATMEL_HLCDC_LAYER_OVR_IRQ(0) |
> - ATMEL_HLCDC_LAYER_OVR_IRQ(1) |
> - ATMEL_HLCDC_LAYER_OVR_IRQ(2));
> + dc->desc->ops->lcdc_atomic_update(plane, dc);
> +}
>
> - /* Apply the new config at the next SOF event. */
> - sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR);
> - atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHER,
> - ATMEL_HLCDC_LAYER_UPDATE |
> - (sr & ATMEL_HLCDC_LAYER_EN ?
> - ATMEL_HLCDC_LAYER_A2Q : ATMEL_HLCDC_LAYER_EN));
> +void hlcdc_csc_init(struct atmel_hlcdc_plane *plane,
> + const struct atmel_hlcdc_layer_desc *desc)
> +{
> + /*
> + * TODO: declare a "yuv-to-rgb-conv-factors" property to let
> + * userspace modify these factors (using a BLOB property ?).
> + */
> + static u32 hlcdc_csc_coeffs[] = {
static const u32 hlcdc_csc_coeffs[] = {
> + 0x4c900091,
> + 0x7a5f5090,
> + 0x40040890
> + };
> +
> + for (int i = 0; i < ARRAY_SIZE(hlcdc_csc_coeffs); i++) {
> + atmel_hlcdc_layer_write_cfg(&plane->layer,
> + desc->layout.csc + i,
> + hlcdc_csc_coeffs[i]);
> + }
> +}
> +
> +void xlcdc_csc_init(struct atmel_hlcdc_plane *plane,
> + const struct atmel_hlcdc_layer_desc *desc)
> +{
> + /*
> + * yuv-to-rgb-conv-factors are now defined from LCDC_HEOCFG16 to
> + * LCDC_HEOCFG21 registers in SAM9X7.
> + */
> + static u32 xlcdc_csc_coeffs[] = {
static const u32 xlcdc_csc_coeffs[] = {
> + 0x00000488,
> + 0x00000648,
> + 0x1EA00480,
> + 0x00001D28,
> + 0x08100480,
> + 0x00000000,
> + 0x00000007
> + };
> +
> + for (int i = 0; i < ARRAY_SIZE(xlcdc_csc_coeffs); i++) {
> + atmel_hlcdc_layer_write_cfg(&plane->layer,
> + desc->layout.csc + i,
> + xlcdc_csc_coeffs[i]);
> + }
> }
>
> static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane)
> {
> const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
> + struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
>
> if (desc->type == ATMEL_HLCDC_OVERLAY_LAYER ||
> desc->type == ATMEL_HLCDC_CURSOR_LAYER) {
> @@ -796,31 +987,16 @@ static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane)
> return ret;
> }
>
> - if (desc->layout.csc) {
> - /*
> - * TODO: decare a "yuv-to-rgb-conv-factors" property to let
> - * userspace modify these factors (using a BLOB property ?).
> - */
> - atmel_hlcdc_layer_write_cfg(&plane->layer,
> - desc->layout.csc,
> - 0x4c900091);
> - atmel_hlcdc_layer_write_cfg(&plane->layer,
> - desc->layout.csc + 1,
> - 0x7a5f5090);
> - atmel_hlcdc_layer_write_cfg(&plane->layer,
> - desc->layout.csc + 2,
> - 0x40040890);
> - }
> + if (desc->layout.csc)
> + dc->desc->ops->lcdc_csc_init(plane, desc);
>
> return 0;
> }
>
> -void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane)
> +void hlcdc_irq_dbg(struct atmel_hlcdc_plane *plane,
> + const struct atmel_hlcdc_layer_desc *desc)
> {
> - const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
> - u32 isr;
> -
> - isr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_ISR);
> + u32 isr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_ISR);
>
> /*
> * There's not much we can do in case of overrun except informing
> @@ -830,8 +1006,31 @@ void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane)
> if (isr &
> (ATMEL_HLCDC_LAYER_OVR_IRQ(0) | ATMEL_HLCDC_LAYER_OVR_IRQ(1) |
> ATMEL_HLCDC_LAYER_OVR_IRQ(2)))
> - dev_dbg(plane->base.dev->dev, "overrun on plane %s\n",
> - desc->name);
> + dev_warn(plane->base.dev->dev, "overrun on plane %s\n", desc->name);
why changed it to dev_warn() ?
> +}
> +
> +void xlcdc_irq_dbg(struct atmel_hlcdc_plane *plane,
> + const struct atmel_hlcdc_layer_desc *desc)
> +{
> + u32 isr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_XLCDC_LAYER_ISR);
> +
> + /*
> + * There's not much we can do in case of overrun except informing
> + * the user. However, we are in interrupt context here, hence the
> + * use of dev_dbg().
> + */
> + if (isr &
> + (ATMEL_XLCDC_LAYER_OVR_IRQ(0) | ATMEL_XLCDC_LAYER_OVR_IRQ(1) |
> + ATMEL_XLCDC_LAYER_OVR_IRQ(2)))
> + dev_warn(plane->base.dev->dev, "overrun on plane %s\n", desc->name);
> +}
> +
> +void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane)
> +{
> + const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc;
> + struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private;
> +
> + dc->desc->ops->lcdc_irq_dbg(plane, desc);
> }
>
> static const struct drm_plane_helper_funcs atmel_hlcdc_layer_plane_helper_funcs = {
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v5 6/8] drm: atmel-hlcdc: add DPI mode support for XLCDC
2023-09-15 10:48 [PATCH v5 0/8] Add support for XLCDC to sam9x7 SoC family Manikandan Muralidharan
` (4 preceding siblings ...)
2023-09-15 10:48 ` [PATCH v5 5/8] drm: atmel_hlcdc: Add support for XLCDC in atmel LCD driver Manikandan Muralidharan
@ 2023-09-15 10:48 ` Manikandan Muralidharan
2023-09-25 14:14 ` claudiu beznea
2023-09-15 10:48 ` [PATCH v5 7/8] drm: atmel-hlcdc: add vertical and horizontal scaling " Manikandan Muralidharan
2023-09-15 10:48 ` [PATCH v5 8/8] drm: atmel-hlcdc: add support for DSI output formats Manikandan Muralidharan
7 siblings, 1 reply; 14+ messages in thread
From: Manikandan Muralidharan @ 2023-09-15 10:48 UTC (permalink / raw)
To: sam, bbrezillon, airlied, daniel, nicolas.ferre,
alexandre.belloni, lee, dri-devel, linux-arm-kernel,
linux-kernel
Cc: Hari.PrasathGE, Balamanikandan.Gunasundar, Durai.ManickamKR,
Nayabbasha.Sayed, Dharma.B, Varshini.Rajendran, Balakrishnan.S,
Manikandan Muralidharan, Durai Manickam KR
Add support for Display Pixel Interface (DPI) Compatible Mode
support in atmel-hlcdc driver for XLCDC IP along with legacy
pixel mapping.DPI mode BIT is configured in LCDC_CFG5 register.
Signed-off-by: Manikandan Muralidharan <manikandan.m@microchip.com>
[durai.manickamkr@microchip.com: update DPI mode bit using is_xlcdc flag]
Signed-off-by: Durai Manickam KR <durai.manickamkr@microchip.com>
---
.../gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c | 22 ++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
index 1ac31c0c474a..b0051ec02f7f 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
@@ -30,10 +30,12 @@
*
* @base: base CRTC state
* @output_mode: RGBXXX output mode
+ * @dpi: output DPI mode
*/
struct atmel_hlcdc_crtc_state {
struct drm_crtc_state base;
unsigned int output_mode;
+ u8 dpi;
};
static inline struct atmel_hlcdc_crtc_state *
@@ -164,6 +166,8 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct drm_crtc *c)
state = drm_crtc_state_to_atmel_hlcdc_crtc_state(c->state);
cfg = state->output_mode << 8;
+ if (is_xlcdc)
+ cfg |= state->dpi << 11;
if (!is_xlcdc && (adj->flags & DRM_MODE_FLAG_NVSYNC))
cfg |= ATMEL_HLCDC_VSPOL;
@@ -176,7 +180,9 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct drm_crtc *c)
ATMEL_HLCDC_VSPDLYS | ATMEL_HLCDC_VSPDLYE |
ATMEL_HLCDC_DISPPOL | ATMEL_HLCDC_DISPDLY |
ATMEL_HLCDC_VSPSU | ATMEL_HLCDC_VSPHO |
- ATMEL_HLCDC_GUARDTIME_MASK | ATMEL_HLCDC_MODE_MASK,
+ ATMEL_HLCDC_GUARDTIME_MASK |
+ (is_xlcdc ? ATMEL_XLCDC_MODE_MASK |
+ ATMEL_XLCDC_DPI : ATMEL_HLCDC_MODE_MASK),
cfg);
clk_disable_unprepare(crtc->dc->hlcdc->sys_clk);
@@ -374,7 +380,15 @@ static int atmel_hlcdc_crtc_select_output_mode(struct drm_crtc_state *state)
hstate = drm_crtc_state_to_atmel_hlcdc_crtc_state(state);
hstate->output_mode = fls(output_fmts) - 1;
-
+ if (crtc->dc->desc->is_xlcdc) {
+ /* check if MIPI DPI bit needs to be set */
+ if (fls(output_fmts) > 3) {
+ hstate->output_mode -= 4;
+ hstate->dpi = 1;
+ } else {
+ hstate->dpi = 0;
+ }
+ }
return 0;
}
@@ -478,7 +492,7 @@ static struct drm_crtc_state *
atmel_hlcdc_crtc_duplicate_state(struct drm_crtc *crtc)
{
struct atmel_hlcdc_crtc_state *state, *cur;
-
+ struct atmel_hlcdc_crtc *c = drm_crtc_to_atmel_hlcdc_crtc(crtc);
if (WARN_ON(!crtc->state))
return NULL;
@@ -489,6 +503,8 @@ atmel_hlcdc_crtc_duplicate_state(struct drm_crtc *crtc)
cur = drm_crtc_state_to_atmel_hlcdc_crtc_state(crtc->state);
state->output_mode = cur->output_mode;
+ if (c->dc->desc->is_xlcdc)
+ state->dpi = cur->dpi;
return &state->base;
}
--
2.25.1
^ permalink raw reply [flat|nested] 14+ messages in thread* Re: [PATCH v5 6/8] drm: atmel-hlcdc: add DPI mode support for XLCDC
2023-09-15 10:48 ` [PATCH v5 6/8] drm: atmel-hlcdc: add DPI mode support for XLCDC Manikandan Muralidharan
@ 2023-09-25 14:14 ` claudiu beznea
0 siblings, 0 replies; 14+ messages in thread
From: claudiu beznea @ 2023-09-25 14:14 UTC (permalink / raw)
To: Manikandan Muralidharan, sam, bbrezillon, airlied, daniel,
nicolas.ferre, alexandre.belloni, lee, dri-devel,
linux-arm-kernel, linux-kernel
Cc: Hari.PrasathGE, Balamanikandan.Gunasundar, Durai.ManickamKR,
Nayabbasha.Sayed, Dharma.B, Varshini.Rajendran, Balakrishnan.S
On 15.09.2023 13:48, Manikandan Muralidharan wrote:
> Add support for Display Pixel Interface (DPI) Compatible Mode
> support in atmel-hlcdc driver for XLCDC IP along with legacy
> pixel mapping.DPI mode BIT is configured in LCDC_CFG5 register.
Space after .
>
> Signed-off-by: Manikandan Muralidharan <manikandan.m@microchip.com>
> [durai.manickamkr@microchip.com: update DPI mode bit using is_xlcdc flag]
> Signed-off-by: Durai Manickam KR <durai.manickamkr@microchip.com>
> ---
> .../gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c | 22 ++++++++++++++++---
> 1 file changed, 19 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
> index 1ac31c0c474a..b0051ec02f7f 100644
> --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
> +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
> @@ -30,10 +30,12 @@
> *
> * @base: base CRTC state
> * @output_mode: RGBXXX output mode
> + * @dpi: output DPI mode
> */
> struct atmel_hlcdc_crtc_state {
> struct drm_crtc_state base;
> unsigned int output_mode;
> + u8 dpi;
> };
>
> static inline struct atmel_hlcdc_crtc_state *
> @@ -164,6 +166,8 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct drm_crtc *c)
>
> state = drm_crtc_state_to_atmel_hlcdc_crtc_state(c->state);
> cfg = state->output_mode << 8;
> + if (is_xlcdc)
> + cfg |= state->dpi << 11;
>
> if (!is_xlcdc && (adj->flags & DRM_MODE_FLAG_NVSYNC))
> cfg |= ATMEL_HLCDC_VSPOL;
> @@ -176,7 +180,9 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct drm_crtc *c)
> ATMEL_HLCDC_VSPDLYS | ATMEL_HLCDC_VSPDLYE |
> ATMEL_HLCDC_DISPPOL | ATMEL_HLCDC_DISPDLY |
> ATMEL_HLCDC_VSPSU | ATMEL_HLCDC_VSPHO |
> - ATMEL_HLCDC_GUARDTIME_MASK | ATMEL_HLCDC_MODE_MASK,
> + ATMEL_HLCDC_GUARDTIME_MASK |
> + (is_xlcdc ? ATMEL_XLCDC_MODE_MASK |
> + ATMEL_XLCDC_DPI : ATMEL_HLCDC_MODE_MASK),
> cfg);
>
> clk_disable_unprepare(crtc->dc->hlcdc->sys_clk);
> @@ -374,7 +380,15 @@ static int atmel_hlcdc_crtc_select_output_mode(struct drm_crtc_state *state)
>
> hstate = drm_crtc_state_to_atmel_hlcdc_crtc_state(state);
> hstate->output_mode = fls(output_fmts) - 1;
> -
> + if (crtc->dc->desc->is_xlcdc) {
> + /* check if MIPI DPI bit needs to be set */
> + if (fls(output_fmts) > 3) {
> + hstate->output_mode -= 4;
> + hstate->dpi = 1;
> + } else {
> + hstate->dpi = 0;
> + }
> + }
> return 0;
> }
>
> @@ -478,7 +492,7 @@ static struct drm_crtc_state *
> atmel_hlcdc_crtc_duplicate_state(struct drm_crtc *crtc)
> {
> struct atmel_hlcdc_crtc_state *state, *cur;
> -
> + struct atmel_hlcdc_crtc *c = drm_crtc_to_atmel_hlcdc_crtc(crtc);
Keep the blank line here.
> if (WARN_ON(!crtc->state))
> return NULL;
>
> @@ -489,6 +503,8 @@ atmel_hlcdc_crtc_duplicate_state(struct drm_crtc *crtc)
>
> cur = drm_crtc_state_to_atmel_hlcdc_crtc_state(crtc->state);
> state->output_mode = cur->output_mode;
> + if (c->dc->desc->is_xlcdc)
> + state->dpi = cur->dpi;
>
> return &state->base;
> }
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v5 7/8] drm: atmel-hlcdc: add vertical and horizontal scaling support for XLCDC
2023-09-15 10:48 [PATCH v5 0/8] Add support for XLCDC to sam9x7 SoC family Manikandan Muralidharan
` (5 preceding siblings ...)
2023-09-15 10:48 ` [PATCH v5 6/8] drm: atmel-hlcdc: add DPI mode support for XLCDC Manikandan Muralidharan
@ 2023-09-15 10:48 ` Manikandan Muralidharan
2023-09-15 10:48 ` [PATCH v5 8/8] drm: atmel-hlcdc: add support for DSI output formats Manikandan Muralidharan
7 siblings, 0 replies; 14+ messages in thread
From: Manikandan Muralidharan @ 2023-09-15 10:48 UTC (permalink / raw)
To: sam, bbrezillon, airlied, daniel, nicolas.ferre,
alexandre.belloni, lee, dri-devel, linux-arm-kernel,
linux-kernel
Cc: Hari.PrasathGE, Balamanikandan.Gunasundar, Durai.ManickamKR,
Nayabbasha.Sayed, Dharma.B, Varshini.Rajendran, Balakrishnan.S,
Manikandan Muralidharan
Update the LCDC_HEOCFG30 and LCDC_HEOCFG31 registers of XLCDC IP which
supports vertical and horizontal scaling with Bilinear and Bicubic
co-efficients taps for Chroma and Luma componenets of the Pixel.
Signed-off-by: Manikandan Muralidharan <manikandan.m@microchip.com>
---
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 2 ++
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h | 4 ++++
.../gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 20 +++++++++++++++++++
3 files changed, 26 insertions(+)
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
index 7702c2f16178..2e1b79a38ac7 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
@@ -561,6 +561,8 @@ static const struct atmel_hlcdc_layer_desc atmel_xlcdc_sam9x75_layers[] = {
.general_config = 12,
.csc = 16,
.scaler_config = 23,
+ .vxs_config = 30,
+ .hxs_config = 31,
},
.clut_offset = 0x1300,
},
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
index 9965c7cc5bf8..aad907ccb65a 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h
@@ -198,6 +198,8 @@
* @disc_pos: discard area position register
* @disc_size: discard area size register
* @csc: color space conversion register
+ * @vxs_config: vertical scalar filter taps control register
+ * @hxs_config: horizontal scalar filter taps control register
*/
struct atmel_hlcdc_layer_cfg_layout {
int xstride[ATMEL_HLCDC_LAYER_MAX_PLANES];
@@ -217,6 +219,8 @@ struct atmel_hlcdc_layer_cfg_layout {
int disc_pos;
int disc_size;
int csc;
+ int vxs_config;
+ int hxs_config;
};
struct atmel_hlcdc_plane_state;
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
index e2a5bed86fdb..070a377ad3b8 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
@@ -958,6 +958,26 @@ void xlcdc_csc_init(struct atmel_hlcdc_plane *plane,
desc->layout.csc + i,
xlcdc_csc_coeffs[i]);
}
+
+ if (desc->layout.vxs_config && desc->layout.hxs_config) {
+ /*
+ * Updating vxs.config and hxs.config fixes the
+ * Green Color Issue in SAM9X7 EGT Video Player App
+ */
+ atmel_hlcdc_layer_write_cfg(&plane->layer,
+ desc->layout.vxs_config,
+ ATMEL_XLCDC_LAYER_VXSYCFG_ONE |
+ ATMEL_XLCDC_LAYER_VXSYTAP2_ENABLE |
+ ATMEL_XLCDC_LAYER_VXSCCFG_ONE |
+ ATMEL_XLCDC_LAYER_VXSCTAP2_ENABLE);
+
+ atmel_hlcdc_layer_write_cfg(&plane->layer,
+ desc->layout.hxs_config,
+ ATMEL_XLCDC_LAYER_HXSYCFG_ONE |
+ ATMEL_XLCDC_LAYER_HXSYTAP2_ENABLE |
+ ATMEL_XLCDC_LAYER_HXSCCFG_ONE |
+ ATMEL_XLCDC_LAYER_HXSCTAP2_ENABLE);
+ }
}
static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane)
--
2.25.1
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH v5 8/8] drm: atmel-hlcdc: add support for DSI output formats
2023-09-15 10:48 [PATCH v5 0/8] Add support for XLCDC to sam9x7 SoC family Manikandan Muralidharan
` (6 preceding siblings ...)
2023-09-15 10:48 ` [PATCH v5 7/8] drm: atmel-hlcdc: add vertical and horizontal scaling " Manikandan Muralidharan
@ 2023-09-15 10:48 ` Manikandan Muralidharan
7 siblings, 0 replies; 14+ messages in thread
From: Manikandan Muralidharan @ 2023-09-15 10:48 UTC (permalink / raw)
To: sam, bbrezillon, airlied, daniel, nicolas.ferre,
alexandre.belloni, lee, dri-devel, linux-arm-kernel,
linux-kernel
Cc: Hari.PrasathGE, Balamanikandan.Gunasundar, Durai.ManickamKR,
Nayabbasha.Sayed, Dharma.B, Varshini.Rajendran, Balakrishnan.S,
Manikandan Muralidharan, Durai Manickam KR
Add support for the following DPI mode if the encoder type
is DSI as per the XLCDC IP datasheet:
- 16BPPCFG1
- 16BPPCFG2
- 16BPPCFG3
- 18BPPCFG1
- 18BPPCFG2
- 24BPP
Signed-off-by: Manikandan Muralidharan <manikandan.m@microchip.com>
[durai.manickamkr@microchip.com: update output format using is_xlcdc flag]
Signed-off-by: Durai Manickam KR <durai.manickamkr@microchip.com>
---
.../gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c | 123 +++++++++++++-----
1 file changed, 88 insertions(+), 35 deletions(-)
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
index b0051ec02f7f..f59eb65000da 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
@@ -295,11 +295,18 @@ static void atmel_hlcdc_crtc_atomic_enable(struct drm_crtc *c,
}
-#define ATMEL_HLCDC_RGB444_OUTPUT BIT(0)
-#define ATMEL_HLCDC_RGB565_OUTPUT BIT(1)
-#define ATMEL_HLCDC_RGB666_OUTPUT BIT(2)
-#define ATMEL_HLCDC_RGB888_OUTPUT BIT(3)
-#define ATMEL_HLCDC_OUTPUT_MODE_MASK GENMASK(3, 0)
+#define ATMEL_HLCDC_RGB444_OUTPUT BIT(0)
+#define ATMEL_HLCDC_RGB565_OUTPUT BIT(1)
+#define ATMEL_HLCDC_RGB666_OUTPUT BIT(2)
+#define ATMEL_HLCDC_RGB888_OUTPUT BIT(3)
+#define ATMEL_HLCDC_DPI_RGB565C1_OUTPUT BIT(4)
+#define ATMEL_HLCDC_DPI_RGB565C2_OUTPUT BIT(5)
+#define ATMEL_HLCDC_DPI_RGB565C3_OUTPUT BIT(6)
+#define ATMEL_HLCDC_DPI_RGB666C1_OUTPUT BIT(7)
+#define ATMEL_HLCDC_DPI_RGB666C2_OUTPUT BIT(8)
+#define ATMEL_HLCDC_DPI_RGB888_OUTPUT BIT(9)
+#define ATMEL_HLCDC_OUTPUT_MODE_MASK GENMASK(3, 0)
+#define ATMEL_XLCDC_OUTPUT_MODE_MASK GENMASK(9, 0)
static int atmel_hlcdc_connector_output_mode(struct drm_connector_state *state)
{
@@ -313,53 +320,99 @@ static int atmel_hlcdc_connector_output_mode(struct drm_connector_state *state)
if (!encoder)
encoder = connector->encoder;
- switch (atmel_hlcdc_encoder_get_bus_fmt(encoder)) {
- case 0:
- break;
- case MEDIA_BUS_FMT_RGB444_1X12:
- return ATMEL_HLCDC_RGB444_OUTPUT;
- case MEDIA_BUS_FMT_RGB565_1X16:
- return ATMEL_HLCDC_RGB565_OUTPUT;
- case MEDIA_BUS_FMT_RGB666_1X18:
- return ATMEL_HLCDC_RGB666_OUTPUT;
- case MEDIA_BUS_FMT_RGB888_1X24:
- return ATMEL_HLCDC_RGB888_OUTPUT;
- default:
- return -EINVAL;
- }
-
- for (j = 0; j < info->num_bus_formats; j++) {
- switch (info->bus_formats[j]) {
- case MEDIA_BUS_FMT_RGB444_1X12:
- supported_fmts |= ATMEL_HLCDC_RGB444_OUTPUT;
+ if (encoder->encoder_type == DRM_MODE_ENCODER_DSI) {
+ /*
+ * atmel-hlcdc to support DSI formats with DSI video pipeline
+ * when DRM_MODE_ENCODER_DSI type is set by
+ * connector driver component.
+ */
+ switch (atmel_hlcdc_encoder_get_bus_fmt(encoder)) {
+ case 0:
break;
case MEDIA_BUS_FMT_RGB565_1X16:
- supported_fmts |= ATMEL_HLCDC_RGB565_OUTPUT;
- break;
+ return ATMEL_HLCDC_DPI_RGB565C1_OUTPUT;
case MEDIA_BUS_FMT_RGB666_1X18:
- supported_fmts |= ATMEL_HLCDC_RGB666_OUTPUT;
- break;
+ return ATMEL_HLCDC_DPI_RGB666C1_OUTPUT;
+ case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
+ return ATMEL_HLCDC_DPI_RGB666C2_OUTPUT;
case MEDIA_BUS_FMT_RGB888_1X24:
- supported_fmts |= ATMEL_HLCDC_RGB888_OUTPUT;
- break;
+ return ATMEL_HLCDC_DPI_RGB888_OUTPUT;
default:
+ return -EINVAL;
+ }
+
+ for (j = 0; j < info->num_bus_formats; j++) {
+ switch (info->bus_formats[j]) {
+ case MEDIA_BUS_FMT_RGB565_1X16:
+ supported_fmts |=
+ ATMEL_HLCDC_DPI_RGB565C1_OUTPUT;
+ break;
+ case MEDIA_BUS_FMT_RGB666_1X18:
+ supported_fmts |=
+ ATMEL_HLCDC_DPI_RGB666C1_OUTPUT;
+ break;
+ case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
+ supported_fmts |=
+ ATMEL_HLCDC_DPI_RGB666C2_OUTPUT;
+ break;
+ case MEDIA_BUS_FMT_RGB888_1X24:
+ supported_fmts |=
+ ATMEL_HLCDC_DPI_RGB888_OUTPUT;
+ break;
+ default:
+ break;
+ }
+ }
+ } else {
+ switch (atmel_hlcdc_encoder_get_bus_fmt(encoder)) {
+ case 0:
break;
+ case MEDIA_BUS_FMT_RGB444_1X12:
+ return ATMEL_HLCDC_RGB444_OUTPUT;
+ case MEDIA_BUS_FMT_RGB565_1X16:
+ return ATMEL_HLCDC_RGB565_OUTPUT;
+ case MEDIA_BUS_FMT_RGB666_1X18:
+ return ATMEL_HLCDC_RGB666_OUTPUT;
+ case MEDIA_BUS_FMT_RGB888_1X24:
+ return ATMEL_HLCDC_RGB888_OUTPUT;
+ default:
+ return -EINVAL;
}
- }
+ for (j = 0; j < info->num_bus_formats; j++) {
+ switch (info->bus_formats[j]) {
+ case MEDIA_BUS_FMT_RGB444_1X12:
+ supported_fmts |= ATMEL_HLCDC_RGB444_OUTPUT;
+ break;
+ case MEDIA_BUS_FMT_RGB565_1X16:
+ supported_fmts |= ATMEL_HLCDC_RGB565_OUTPUT;
+ break;
+ case MEDIA_BUS_FMT_RGB666_1X18:
+ supported_fmts |= ATMEL_HLCDC_RGB666_OUTPUT;
+ break;
+ case MEDIA_BUS_FMT_RGB888_1X24:
+ supported_fmts |= ATMEL_HLCDC_RGB888_OUTPUT;
+ break;
+ default:
+ break;
+ }
+ }
+ }
return supported_fmts;
}
static int atmel_hlcdc_crtc_select_output_mode(struct drm_crtc_state *state)
{
- unsigned int output_fmts = ATMEL_HLCDC_OUTPUT_MODE_MASK;
+ unsigned int output_fmts;
struct atmel_hlcdc_crtc_state *hstate;
struct drm_connector_state *cstate;
struct drm_connector *connector;
- struct atmel_hlcdc_crtc *crtc;
+ struct atmel_hlcdc_crtc *crtc = drm_crtc_to_atmel_hlcdc_crtc(state->crtc);
int i;
+ bool is_xlcdc = crtc->dc->desc->is_xlcdc;
- crtc = drm_crtc_to_atmel_hlcdc_crtc(state->crtc);
+ output_fmts = is_xlcdc ? ATMEL_XLCDC_OUTPUT_MODE_MASK :
+ ATMEL_HLCDC_OUTPUT_MODE_MASK;
for_each_new_connector_in_state(state->state, connector, cstate, i) {
unsigned int supported_fmts = 0;
@@ -380,7 +433,7 @@ static int atmel_hlcdc_crtc_select_output_mode(struct drm_crtc_state *state)
hstate = drm_crtc_state_to_atmel_hlcdc_crtc_state(state);
hstate->output_mode = fls(output_fmts) - 1;
- if (crtc->dc->desc->is_xlcdc) {
+ if (is_xlcdc) {
/* check if MIPI DPI bit needs to be set */
if (fls(output_fmts) > 3) {
hstate->output_mode -= 4;
--
2.25.1
^ permalink raw reply [flat|nested] 14+ messages in thread