Commit 83ba7a7b authored by Linus Walleij's avatar Linus Walleij
Browse files

drm/panel: s6e63m0: Add code to identify panel



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.

Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Tested-by: default avatarStephan Gerhold <stephan@gerhold.net>
Cc: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
Acked-by: default avatarPaul Cercueil <paul@crapouillou.net>
Link: https://patchwork.freedesktop.org/patch/msgid/20200809215104.1830206-5-linus.walleij@linaro.org
parent 91867ac7
Loading
Loading
Loading
Loading
+60 −0
Original line number Diff line number Diff line
@@ -25,12 +25,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

@@ -90,6 +99,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;
@@ -157,6 +167,47 @@ 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,
@@ -310,6 +361,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);