diff mbox series

[4/4] drm/panel: s6e63m0: Add code to identify panel

Message ID 20200809215104.1830206-5-linus.walleij@linaro.org
State Accepted
Commit 83ba7a7b3d4a70fe92122f039539566c9526228c
Headers show
Series drm/panel: s6e63m0: Add DSI transport | expand

Commit Message

Linus Walleij Aug. 9, 2020, 9:51 p.m. UTC
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 <stephan@gerhold.net>
Cc: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/gpu/drm/panel/panel-samsung-s6e63m0.c | 61 +++++++++++++++++++
 1 file changed, 61 insertions(+)
diff mbox series

Patch

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);