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 <manikanda...@microchip.com>
[durai.manicka...@microchip.com: update output format using is_xlcdc flag]
Signed-off-by: Durai Manickam KR <durai.manicka...@microchip.com>
---
 .../gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c    | 123 +++++++++++++-----
 1 file changed, 89 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c 
b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
index c3d0c60ba419..0d10f84c82d8 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
@@ -287,11 +287,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)
 {
@@ -305,37 +312,83 @@ 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;
+                       }
                }
        }
 
@@ -344,14 +397,16 @@ static int atmel_hlcdc_connector_output_mode(struct 
drm_connector_state *state)
 
 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;
@@ -372,7 +427,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

Reply via email to