We add code to identify a few different panels mounted
on the s6e63m0 controller. This is necessary to achieve
the proper biasing with DSI versions of the panel.

Cc: Stephan Gerhold <[email protected]>
Cc: PaweÅ‚ Chmiel <[email protected]>
Signed-off-by: Linus Walleij <[email protected]>
---
 drivers/gpu/drm/panel/panel-samsung-s6e63m0.c | 61 +++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c 
b/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c
index b25021bdd724..0b22e382b80f 100644
--- a/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c
+++ b/drivers/gpu/drm/panel/panel-samsung-s6e63m0.c
@@ -26,12 +26,21 @@
 #define MCS_ELVSS_ON                0xb1
 #define MCS_MIECTL1                0xc0
 #define MCS_BCMODE                              0xc1
+#define MCS_READ_ID1           0xda
+#define MCS_READ_ID2           0xdb
+#define MCS_READ_ID3           0xdc
+#define MCS_LEVEL_2_KEY                0xf0
+#define MCS_MTP_KEY            0xf1
 #define MCS_DISCTL   0xf2
 #define MCS_SRCCTL           0xf6
 #define MCS_IFCTL                       0xf7
 #define MCS_PANELCTL         0xF8
 #define MCS_PGAMMACTL                   0xfa
 
+#define S6E63M0_LCD_ID_VALUE_M2                0xA4
+#define S6E63M0_LCD_ID_VALUE_SM2       0xB4
+#define S6E63M0_LCD_ID_VALUE_SM2_1     0xB6
+
 #define NUM_GAMMA_LEVELS             11
 #define GAMMA_TABLE_COUNT           23
 
@@ -91,6 +100,7 @@ struct s6e63m0 {
        int (*dcs_write)(struct device *dev, const u8 *data, size_t len);
        struct drm_panel panel;
        struct backlight_device *bl_dev;
+       u8 lcd_type;
 
        struct regulator_bulk_data supplies[2];
        struct gpio_desc *reset_gpio;
@@ -159,6 +169,48 @@ static void s6e63m0_dcs_write(struct s6e63m0 *ctx, const 
u8 *data, size_t len)
                s6e63m0_dcs_write(ctx, d, ARRAY_SIZE(d)); \
        })
 
+
+static int s6e63m0_check_lcd_type(struct s6e63m0 *ctx)
+{
+       u8 id1, id2, id3;
+       int ret;
+
+       s6e63m0_dcs_read(ctx, MCS_READ_ID1, &id1);
+       s6e63m0_dcs_read(ctx, MCS_READ_ID2, &id2);
+       s6e63m0_dcs_read(ctx, MCS_READ_ID3, &id3);
+
+       ret = s6e63m0_clear_error(ctx);
+       if (ret) {
+               DRM_DEV_ERROR(ctx->dev, "error checking LCD type (%d)\n",
+                             ret);
+               ctx->lcd_type = 0x00;
+               return ret;
+       }
+
+       DRM_DEV_INFO(ctx->dev, "MTP ID: %02x %02x %02x\n", id1, id2, id3);
+
+       /* We attempt to detect what panel is mounted on the controller */
+       switch (id2) {
+       case S6E63M0_LCD_ID_VALUE_M2:
+               DRM_DEV_INFO(ctx->dev,
+                            "detected LCD panel AMS397GE MIPI M2\n");
+               break;
+       case S6E63M0_LCD_ID_VALUE_SM2:
+       case S6E63M0_LCD_ID_VALUE_SM2_1:
+               DRM_DEV_INFO(ctx->dev,
+                            "detected LCD panel AMS397GE MIPI SM2\n");
+               break;
+       default:
+               DRM_DEV_INFO(ctx->dev,
+                            "unknown LCD panel type %02x\n", id2);
+               break;
+       }
+
+       ctx->lcd_type = id2;
+
+       return 0;
+}
+
 static void s6e63m0_init(struct s6e63m0 *ctx)
 {
        s6e63m0_dcs_write_seq_static(ctx, MCS_PANELCTL,
@@ -312,6 +364,15 @@ static int s6e63m0_prepare(struct drm_panel *panel)
        if (ret < 0)
                return ret;
 
+       /* Magic to unlock level 2 control of the display */
+       s6e63m0_dcs_write_seq_static(ctx, MCS_LEVEL_2_KEY, 0x5a, 0x5a);
+       /* Magic to unlock MTP reading */
+       s6e63m0_dcs_write_seq_static(ctx, MCS_MTP_KEY, 0x5a, 0x5a);
+
+       ret = s6e63m0_check_lcd_type(ctx);
+       if (ret < 0)
+               return ret;
+
        s6e63m0_init(ctx);
 
        ret = s6e63m0_clear_error(ctx);
-- 
2.26.2

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to