[PATCH v2 05/11] drm/panel: Add panel driver for Samsung SOFEF01 DDIC

Marijn Suijten posted 11 patches 1 month, 2 weeks ago
[PATCH v2 05/11] drm/panel: Add panel driver for Samsung SOFEF01 DDIC
Posted by Marijn Suijten 1 month, 2 weeks ago
This Samsung SOFEF01-M Display-Driver-IC is used to drive 1080x2520@60Hz
command-mode DSI panels found in many Sony phones:
- Sony Xperia 5 (kumano bahamut): amb609tc01
- Sony Xperia 10 II (seine pdx201): ams597ut01
- Sony Xperia 10 III (lena pdx213): ams597ut04
- Sony Xperia 10 IV (murray pdx225): ams597ut05
- Sony Xperia 10 V (zambezi pdx235): ams605dk01
- Sony Xperia 10 VI (columbia pdx246): ams605dk01

The amb609tc01 and ams605dk01 come in slightly larger at 6.1" while the
others are 6.0".

A "fake" porch calculation is included to artificially bump the clock
rate necessary to account for "transfer overhead" (DSI packet headers)
since this is missing from the MSM DSI host driver; porches aren't
otherwise used on command-mode panels.

Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
---
 MAINTAINERS                                   |   1 +
 drivers/gpu/drm/panel/Kconfig                 |  18 +
 drivers/gpu/drm/panel/Makefile                |   1 +
 drivers/gpu/drm/panel/panel-samsung-sofef01.c | 463 ++++++++++++++++++++++++++
 4 files changed, 483 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 93468dde9df2..cd2c924749d3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8198,6 +8198,7 @@ DRM DRIVER FOR SAMSUNG SOFEF01 DDIC
 M:	Marijn Suijten <marijn.suijten@somainline.org>
 S:	Maintained
 F:	Documentation/devicetree/bindings/display/panel/samsung,sofef01-m.yaml
+F:	drivers/gpu/drm/panel/panel-samsung-sofef01.c
 
 DRM DRIVER FOR SHARP MEMORY LCD
 M:	Alex Lanzano <lanzano.alex@gmail.com>
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 10381291707e..2f06b48dfb89 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -935,6 +935,24 @@ config DRM_PANEL_SAMSUNG_SOFEF00
 
 	    Samsung AMS628NW01 (found in OnePlus 6, 1080x2280@60Hz)
 
+config DRM_PANEL_SAMSUNG_SOFEF01
+	tristate "Samsung SOFEF01-M DSI cmd mode panels"
+	depends on GPIOLIB
+	depends on OF
+	depends on DRM_MIPI_DSI
+	depends on BACKLIGHT_CLASS_DEVICE
+	help
+	  Say Y or M here if you want to enable support for the Samsung 6.0"/6.1"
+	  AMOLED DSI command mode panels found in multiple Sony smartphones:
+	  - Sony Xperia 5 (kumano bahamut): amb609tc01
+	  - Sony Xperia 10 II (seine pdx201): ams597ut01
+	  - Sony Xperia 10 III (lena pdx213): ams597ut04
+	  - Sony Xperia 10 IV (murray pdx225): ams597ut05
+	  - Sony Xperia 10 V (zambezi pdx235): ams605dk01
+	  - Sony Xperia 10 VI (columbia pdx246): ams605dk01
+
+	  This Display-IC features a fixed 1080x2520@60 mode.
+
 config DRM_PANEL_SEIKO_43WVF1G
 	tristate "Seiko 43WVF1G panel"
 	depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 186eb895af21..cbd9ef23b8d8 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -94,6 +94,7 @@ obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01) += panel-samsung-s6e88a0-ams4
 obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o
 obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA5X01_AMS561RA01) += panel-samsung-s6e8aa5x01-ams561ra01.o
 obj-$(CONFIG_DRM_PANEL_SAMSUNG_SOFEF00) += panel-samsung-sofef00.o
+obj-$(CONFIG_DRM_PANEL_SAMSUNG_SOFEF01) += panel-samsung-sofef01.o
 obj-$(CONFIG_DRM_PANEL_SEIKO_43WVF1G) += panel-seiko-43wvf1g.o
 obj-$(CONFIG_DRM_PANEL_SHARP_LQ079L1SX01) += panel-sharp-lq079l1sx01.o
 obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o
diff --git a/drivers/gpu/drm/panel/panel-samsung-sofef01.c b/drivers/gpu/drm/panel/panel-samsung-sofef01.c
new file mode 100644
index 000000000000..bb1cefd16fe9
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-samsung-sofef01.c
@@ -0,0 +1,463 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023 Marijn Suijten <marijn.suijten@somainline.org>
+ *
+ * Based on the following Sony downstream DTS command sequences:
+ * - Xperia 5 (kumano bahamut): https://github.com/sonyxperiadev/kernel-copyleft/blob/55.2.A.4.xxx/arch/arm64/boot/dts/somc/dsi-panel-sofef01_m-fhd_plus.dtsi
+ * - Xperia 10 II (seine pdx201): https://github.com/sonyxperiadev/kernel-copyleft/blob/59.1.A.2.xxx/arch/arm64/boot/dts/somc/dsi-panel-sofef01_m-fhd_plus.dtsi
+ * - Xperia 10 III (lena pdx213): https://github.com/sonyxperiadev/kernel-copyleft-dts/blob/62.1.A.0.xxx/qcom/dsi-panel-pdx213-amoled-fhd-cmd.dtsi
+ * - Xperia 10 IV (murray pdx225): https://github.com/sonyxperiadev/kernel-copyleft-dts/blob/65.1.A.4.xxx/qcom/dsi-panel-samsung-amoled-fhd-cmd.dtsi
+ * - Xperia 10 V (zambezi pdx235): https://github.com/sonyxperiadev/kernel-copyleft-dts/blob/68.2.A.2.xxx/qcom/dsi-panel-samsung-amoled-fhd-cmd.dtsi
+ * - Xperia 10 VI (columbia pdx246): https://github.com/sonyxperiadev/kernel-copyleft-dts/blob/70.0.A.2.xxx/qcom/dsi-panel-samsung-amoled-fhd-cmd.dtsi
+ */
+
+#include <linux/backlight.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regulator/consumer.h>
+
+#include <video/mipi_display.h>
+
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_probe_helper.h>
+
+#define WRITE_CONTROL_DISPLAY_AOD_LOW BIT(0)
+#define WRITE_CONTROL_DISPLAY_AOD_ON BIT(1)
+#define WRITE_CONTROL_DISPLAY_DIMMING BIT(3)
+#define WRITE_CONTROL_DISPLAY_LOCAL_HBM BIT(4)
+#define WRITE_CONTROL_DISPLAY_BACKLIGHT BIT(5)
+#define WRITE_CONTROL_DISPLAY_HBM GENMASK(6, 7)
+
+/* Only used to send a few differentiating DCS between the two panel variants,
+ * without exactly knowing what they mean.  These do not seem to be related to
+ * panel functionality nor have any visual impact, but they are sent anyway just
+ * in case.
+ */
+enum panel_type {
+	/* Sony Xperia 5 */
+	PANEL_TYPE_TC01,
+	/* Sony Xperia 10 II */
+	PANEL_TYPE_UT01,
+	/* Sony Xperia 10 III */
+	PANEL_TYPE_UT04,
+	/* Sony Xperia 10 IV */
+	PANEL_TYPE_UT05,
+	/* Sony Xperia 10 V and 10 VI */
+	PANEL_TYPE_DK01,
+};
+
+const struct regulator_bulk_data samsung_sofef01_m_supplies[] = {
+	{ .supply = "vddio", /* 1.8 V */ },
+	{ .supply = "vci", /* 3.0 V */ },
+};
+
+struct samsung_sofef01_m {
+	struct drm_panel panel;
+	struct mipi_dsi_device *dsi;
+	struct regulator_bulk_data *supplies;
+	struct gpio_desc *reset_gpio;
+	const struct drm_display_mode *mode;
+	enum panel_type panel_type;
+};
+
+static inline struct samsung_sofef01_m *
+to_samsung_sofef01_m(struct drm_panel *panel)
+{
+	return container_of(panel, struct samsung_sofef01_m, panel);
+}
+
+static void samsung_sofef01_m_reset(struct samsung_sofef01_m *ctx)
+{
+	gpiod_set_value_cansleep(ctx->reset_gpio, 0);
+	usleep_range(10000, 11000);
+	gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+	usleep_range(10000, 11000);
+	gpiod_set_value_cansleep(ctx->reset_gpio, 0);
+	usleep_range(10000, 11000);
+}
+
+static int samsung_sofef01_m_program(struct samsung_sofef01_m *ctx)
+{
+	struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi };
+
+	dsi_ctx.dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
+	mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx);
+	/* TC01 & UT01 require 10ms, UT04 11ms, and the rest 120ms */
+	mipi_dsi_msleep(&dsi_ctx, 120);
+
+	mipi_dsi_dcs_set_tear_on_multi(&dsi_ctx, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
+
+	if (ctx->panel_type == PANEL_TYPE_TC01 ||
+	    ctx->panel_type == PANEL_TYPE_UT01 ||
+	    ctx->panel_type == PANEL_TYPE_UT04) {
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0x5a, 0x5a);
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xdf, 0x03);
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xe0, 0x01);
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0xa5, 0xa5);
+	}
+
+	if (ctx->panel_type == PANEL_TYPE_UT04) {
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0x5a, 0x5a);
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfc, 0x5a, 0x5a);
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xE1, 0x00, 0x00, 0x02, 0x00, 0x1C, 0x1C,
+					     0x00, 0x00, 0x20, 0x00, 0x00, 0x01, 0x19);
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfc, 0xa5, 0xa5);
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0xa5, 0xa5);
+	}
+
+	mipi_dsi_dcs_set_column_address_multi(&dsi_ctx, 0, 1080 - 1);
+	mipi_dsi_dcs_set_page_address_multi(&dsi_ctx, 0, 2520 - 1);
+
+	if (ctx->panel_type == PANEL_TYPE_UT05 || ctx->panel_type == PANEL_TYPE_DK01) {
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0x5a, 0x5a);
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb0, 0x27, 0xf2);
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf2, 0x80);
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf7, 0x07);
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0xa5, 0xa5);
+
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0x5a, 0x5a);
+		/* Downstream: ERR_FG Enable */
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xe5, 0x15);
+		if (ctx->panel_type == PANEL_TYPE_DK01)
+			mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xed, 0x0f, 0x4c, 0x20);
+		else
+			mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xed, 0x04, 0x4c, 0x20);
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0xa5, 0xa5);
+
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0x5a, 0x5a);
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb0, 0x02, 0x8f);
+
+		if (ctx->panel_type == PANEL_TYPE_DK01)
+			/* Downstream Xperia 10 V: FLM1,FLM2 On */
+			mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x8f, 0x27, 0x25);
+		else if (0) /* TODO: Both use the DK01 panel */
+			/* Downstream Xperia 10 VI: FLM1 On, FLM2 On */
+			mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x8f, 0x27, 0x27);
+		else
+			/* Downsteam: FLM1 on, FLM2 off */
+			mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x8f, 0x27, 0x05);
+
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0xa5, 0xa5);
+
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0x5a, 0x5a);
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb0, 0x92, 0x63);
+		/* Downstream: dimming speed setting */
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x63, 0x05);
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0xa5, 0xa5);
+	}
+
+	if (ctx->panel_type == PANEL_TYPE_UT05 || ctx->panel_type == PANEL_TYPE_DK01) {
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_CONTROL_DISPLAY,
+					     WRITE_CONTROL_DISPLAY_BACKLIGHT
+					     | WRITE_CONTROL_DISPLAY_DIMMING);
+	} else {
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_CONTROL_DISPLAY,
+					     WRITE_CONTROL_DISPLAY_BACKLIGHT);
+	}
+
+	mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_POWER_SAVE, 0x00);
+
+	if (ctx->panel_type != PANEL_TYPE_UT05 && ctx->panel_type != PANEL_TYPE_DK01) {
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0x5a, 0x5a);
+
+		if (ctx->panel_type == PANEL_TYPE_TC01 || ctx->panel_type == PANEL_TYPE_UT01)
+			mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xbe, 0x92, 0x29);
+		else if (ctx->panel_type == PANEL_TYPE_UT04)
+			mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xbe, 0x92, 0x09);
+
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0xa5, 0xa5);
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0x5a, 0x5a);
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb0, 0x06);
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb6, 0x90);
+		mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0xa5, 0xa5);
+	}
+
+	mipi_dsi_msleep(&dsi_ctx, 110);
+
+	return dsi_ctx.accum_err;
+}
+
+static int samsung_sofef01_m_prepare(struct drm_panel *panel)
+{
+	struct samsung_sofef01_m *ctx = to_samsung_sofef01_m(panel);
+	struct device *dev = &ctx->dsi->dev;
+	int ret;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(samsung_sofef01_m_supplies), ctx->supplies);
+	if (ret < 0) {
+		dev_err(dev, "Failed to enable regulators: %d\n", ret);
+		return ret;
+	}
+
+	samsung_sofef01_m_reset(ctx);
+
+	ret = samsung_sofef01_m_program(ctx);
+	if (ret < 0) {
+		dev_err(dev, "Failed to program panel: %d\n", ret);
+		goto fail;
+	}
+
+	return 0;
+
+fail:
+	gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+	regulator_bulk_disable(ARRAY_SIZE(samsung_sofef01_m_supplies), ctx->supplies);
+	return ret;
+}
+
+static int samsung_sofef01_m_enable(struct drm_panel *panel)
+{
+	struct samsung_sofef01_m *ctx = to_samsung_sofef01_m(panel);
+	struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi };
+
+	mipi_dsi_dcs_set_display_on_multi(&dsi_ctx);
+	mipi_dsi_usleep_range(&dsi_ctx, 16000, 17000);
+
+	return dsi_ctx.accum_err;
+}
+
+static int samsung_sofef01_m_disable(struct drm_panel *panel)
+{
+	struct samsung_sofef01_m *ctx = to_samsung_sofef01_m(panel);
+	struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi };
+
+	mipi_dsi_dcs_set_display_off_multi(&dsi_ctx);
+	mipi_dsi_usleep_range(&dsi_ctx, 120000, 121000);
+
+	return dsi_ctx.accum_err;
+}
+
+static int samsung_sofef01_m_unprepare(struct drm_panel *panel)
+{
+	struct samsung_sofef01_m *ctx = to_samsung_sofef01_m(panel);
+	struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi };
+
+	mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx);
+	mipi_dsi_usleep_range(&dsi_ctx, 100000, 101000);
+
+	ctx->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
+
+	gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+	regulator_bulk_disable(ARRAY_SIZE(samsung_sofef01_m_supplies), ctx->supplies);
+
+	return dsi_ctx.accum_err;
+}
+
+static int samsung_sofef01_m_get_modes(struct drm_panel *panel,
+				       struct drm_connector *connector)
+{
+	struct samsung_sofef01_m *ctx = to_samsung_sofef01_m(panel);
+
+	return drm_connector_helper_get_modes_fixed(connector, ctx->mode);
+}
+
+static const struct drm_panel_funcs samsung_sofef01_m_panel_funcs = {
+	.prepare = samsung_sofef01_m_prepare,
+	.enable = samsung_sofef01_m_enable,
+	.disable = samsung_sofef01_m_disable,
+	.unprepare = samsung_sofef01_m_unprepare,
+	.get_modes = samsung_sofef01_m_get_modes,
+};
+
+static int samsung_sofef01_m_bl_update_status(struct backlight_device *bl)
+{
+	struct mipi_dsi_device *dsi = bl_get_data(bl);
+	u16 brightness = backlight_get_brightness(bl);
+
+	return mipi_dsi_dcs_set_display_brightness_large(dsi, brightness);
+}
+
+static int samsung_sofef01_m_bl_get_brightness(struct backlight_device *bl)
+{
+	struct mipi_dsi_device *dsi = bl_get_data(bl);
+	u16 brightness;
+	int ret;
+
+	ret = mipi_dsi_dcs_get_display_brightness_large(dsi, &brightness);
+
+	if (ret < 0)
+		return ret;
+
+	return brightness;
+}
+
+static const struct backlight_ops samsung_sofef01_m_bl_ops = {
+	.update_status = samsung_sofef01_m_bl_update_status,
+	.get_brightness = samsung_sofef01_m_bl_get_brightness,
+};
+
+/*
+ * drm/msm's DSI code does not calculate transfer time but instead relies on
+ * fake porch values (which are not a thing in CMD mode) to represent the
+ * transfer time.
+ *
+ * Use the following expressions based on qcom,mdss-dsi-panel-clockrate from
+ * downstream DT to artificially bump the mode's clock that reflects the
+ * necessary transfer time / overhead.
+ */
+static const unsigned int dsi_lanes = 4;
+static const unsigned int bpp = 24;
+/* qcom,mdss-dsi-panel-clockrate from downstream DT */
+static const unsigned long bitclk_hz = 1132293600;
+static const unsigned long stable_clockrate = bitclk_hz * dsi_lanes / bpp;
+static const unsigned long fake_porch = stable_clockrate / (2520 * 60) - 1080;
+
+/* 61x142mm variant, Sony Xperia 5 */
+static const struct drm_display_mode samsung_sofef01_m_61_142_mode = {
+	.clock = (1080 + fake_porch) * 2520 * 60 / 1000,
+	.hdisplay = 1080,
+	.hsync_start = 1080 + fake_porch,
+	.hsync_end = 1080 + fake_porch,
+	.htotal = 1080 + fake_porch,
+	.vdisplay = 2520,
+	.vsync_start = 2520,
+	.vsync_end = 2520,
+	.vtotal = 2520,
+	.width_mm = 61,
+	.height_mm = 142,
+	.type = DRM_MODE_TYPE_DRIVER,
+};
+
+/* 61x141mm variant, Sony Xperia 10 V and 10 VI */
+static const struct drm_display_mode samsung_sofef01_m_61_141_mode = {
+	.clock = (1080 + fake_porch) * 2520 * 60 / 1000,
+	.hdisplay = 1080,
+	.hsync_start = 1080 + fake_porch,
+	.hsync_end = 1080 + fake_porch,
+	.htotal = 1080 + fake_porch,
+	.vdisplay = 2520,
+	.vsync_start = 2520,
+	.vsync_end = 2520,
+	.vtotal = 2520,
+	.width_mm = 61,
+	.height_mm = 141,
+	.type = DRM_MODE_TYPE_DRIVER,
+};
+
+/* 60x139mm variant, Sony Xperia 10 II, 10 III and 10 IV */
+static const struct drm_display_mode samsung_sofef01_m_60_139_mode = {
+	.clock = (1080 + fake_porch) * 2520 * 60 / 1000,
+	.hdisplay = 1080,
+	.hsync_start = 1080 + fake_porch,
+	.hsync_end = 1080 + fake_porch,
+	.htotal = 1080 + fake_porch,
+	.vdisplay = 2520,
+	.vsync_start = 2520,
+	.vsync_end = 2520,
+	.vtotal = 2520,
+	.width_mm = 60,
+	.height_mm = 139,
+	.type = DRM_MODE_TYPE_DRIVER,
+};
+
+static int samsung_sofef01_m_probe(struct mipi_dsi_device *dsi)
+{
+	const struct backlight_properties props = {
+		.type = BACKLIGHT_RAW,
+		.brightness = 100,
+		.max_brightness = 1023,
+	};
+	struct device *dev = &dsi->dev;
+	struct samsung_sofef01_m *ctx;
+	int ret;
+
+	ctx = devm_drm_panel_alloc(dev, struct samsung_sofef01_m, panel,
+				   &samsung_sofef01_m_panel_funcs,
+				   DRM_MODE_CONNECTOR_DSI);
+	if (IS_ERR(ctx))
+		return PTR_ERR(ctx);
+
+	ret = devm_regulator_bulk_get_const(
+		dev,
+		ARRAY_SIZE(samsung_sofef01_m_supplies),
+		samsung_sofef01_m_supplies,
+		&ctx->supplies);
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "Failed to get regulators\n");
+
+	ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
+	if (IS_ERR(ctx->reset_gpio))
+		return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio),
+				     "Failed to get reset-gpios\n");
+
+	ctx->dsi = dsi;
+	ctx->panel_type = (enum panel_type)of_device_get_match_data(dev);
+	if (ctx->panel_type == PANEL_TYPE_TC01)
+		ctx->mode = &samsung_sofef01_m_61_142_mode;
+	else if (ctx->panel_type == PANEL_TYPE_DK01)
+		ctx->mode = &samsung_sofef01_m_61_141_mode;
+	else
+		ctx->mode = &samsung_sofef01_m_60_139_mode;
+	mipi_dsi_set_drvdata(dsi, ctx);
+
+	dsi->lanes = 4;
+	dsi->format = MIPI_DSI_FMT_RGB888;
+	dsi->mode_flags = MIPI_DSI_CLOCK_NON_CONTINUOUS;
+
+	ctx->panel.prepare_prev_first = true;
+
+	ctx->panel.backlight = devm_backlight_device_register(
+		dev, dev_name(dev), dev, dsi,
+		&samsung_sofef01_m_bl_ops,
+		&props);
+	if (IS_ERR(ctx->panel.backlight))
+		return dev_err_probe(dev, PTR_ERR(ctx->panel.backlight),
+				     "Failed to create backlight\n");
+
+	drm_panel_add(&ctx->panel);
+
+	ret = mipi_dsi_attach(dsi);
+	if (ret < 0) {
+		dev_err(dev, "Failed to attach to DSI host: %d\n", ret);
+		drm_panel_remove(&ctx->panel);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void samsung_sofef01_m_remove(struct mipi_dsi_device *dsi)
+{
+	struct samsung_sofef01_m *ctx = mipi_dsi_get_drvdata(dsi);
+	int ret;
+
+	ret = mipi_dsi_detach(dsi);
+	if (ret < 0)
+		dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret);
+
+	drm_panel_remove(&ctx->panel);
+}
+
+static const struct of_device_id samsung_sofef01_m_of_match[] = {
+	{ .compatible = "samsung,sofef01-m-amb609tc01",
+	  .data = (void *)PANEL_TYPE_TC01 },
+	{ .compatible = "samsung,sofef01-m-ams597ut01",
+	  .data = (void *)PANEL_TYPE_UT01 },
+	{ .compatible = "samsung,sofef01-m-ams597ut04",
+	  .data = (void *)PANEL_TYPE_UT04 },
+	{ .compatible = "samsung,sofef01-m-ams597ut05",
+	  .data = (void *)PANEL_TYPE_UT05 },
+	{ .compatible = "samsung,sofef01-m-ams605dk01",
+	  .data = (void *)PANEL_TYPE_DK01 },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, samsung_sofef01_m_of_match);
+
+static struct mipi_dsi_driver samsung_sofef01_m_driver = {
+	.probe = samsung_sofef01_m_probe,
+	.remove = samsung_sofef01_m_remove,
+	.driver = {
+		.name = "panel-samsung-sofef01-m",
+		.of_match_table = samsung_sofef01_m_of_match,
+	},
+};
+module_mipi_dsi_driver(samsung_sofef01_m_driver);
+
+MODULE_AUTHOR("Marijn Suijten <marijn.suijten@somainline.org>");
+MODULE_DESCRIPTION("DRM panel driver for Samsung SOFEF01-M Display-Driver-IC panels");
+MODULE_LICENSE("GPL");

-- 
2.52.0
Re: [PATCH v2 05/11] drm/panel: Add panel driver for Samsung SOFEF01 DDIC
Posted by Linus Walleij 1 month, 2 weeks ago
Hi Marijn,

thanks for your patch!

On Mon, Dec 22, 2025 at 12:32 AM Marijn Suijten
<marijn.suijten@somainline.org> wrote:

> This Samsung SOFEF01-M Display-Driver-IC is used to drive 1080x2520@60Hz
> command-mode DSI panels found in many Sony phones:
> - Sony Xperia 5 (kumano bahamut): amb609tc01
> - Sony Xperia 10 II (seine pdx201): ams597ut01
> - Sony Xperia 10 III (lena pdx213): ams597ut04
> - Sony Xperia 10 IV (murray pdx225): ams597ut05
> - Sony Xperia 10 V (zambezi pdx235): ams605dk01
> - Sony Xperia 10 VI (columbia pdx246): ams605dk01
>
> The amb609tc01 and ams605dk01 come in slightly larger at 6.1" while the
> others are 6.0".
>
> A "fake" porch calculation is included to artificially bump the clock
> rate necessary to account for "transfer overhead" (DSI packet headers)
> since this is missing from the MSM DSI host driver; porches aren't
> otherwise used on command-mode panels.
>
> Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>

Excellent work with abstracting all the sofef01-m panels!

Only nitpicks follow:

> +       if (ctx->panel_type == PANEL_TYPE_TC01 ||
> +           ctx->panel_type == PANEL_TYPE_UT01 ||
> +           ctx->panel_type == PANEL_TYPE_UT04) {
> +               mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0x5a, 0x5a);

The sofef00 driver tell us exactly what this sequence is:

#define sofef00_test_key_on_lvl2(ctx) \
        mipi_dsi_dcs_write_seq_multi(ctx, 0xf0, 0x5a, 0x5a)
#define sofef00_test_key_off_lvl2(ctx) \
        mipi_dsi_dcs_write_seq_multi(ctx, 0xf0, 0xa5, 0xa5)

I would just rename these two to sofef01_test_key_on/off_lvl2()
and use the same helpers in this driver to follow the sofef00 pattern.

> +       if (ctx->panel_type == PANEL_TYPE_UT04) {
> +               mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0x5a, 0x5a);

Like here

> +               mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfc, 0x5a, 0x5a);
> +               mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xE1, 0x00, 0x00, 0x02, 0x00, 0x1C, 0x1C,
> +                                            0x00, 0x00, 0x20, 0x00, 0x00, 0x01, 0x19);
> +               mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfc, 0xa5, 0xa5);
> +               mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0xa5, 0xa5);

And here.

> +       if (ctx->panel_type == PANEL_TYPE_UT05 || ctx->panel_type == PANEL_TYPE_DK01) {
> +               mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0x5a, 0x5a);

And here.

> +               mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb0, 0x27, 0xf2);
> +               mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf2, 0x80);
> +               mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf7, 0x07);
> +               mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0xa5, 0xa5);

And here.

> +               mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0x5a, 0x5a);

And here.

> +               /* Downstream: ERR_FG Enable */
> +               mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xe5, 0x15);
> +               if (ctx->panel_type == PANEL_TYPE_DK01)
> +                       mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xed, 0x0f, 0x4c, 0x20);
> +               else
> +                       mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xed, 0x04, 0x4c, 0x20);
> +               mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0xa5, 0xa5);

And here.

> +
> +               mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0x5a, 0x5a);

And here.

> +               mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb0, 0x02, 0x8f);
> +
> +               if (ctx->panel_type == PANEL_TYPE_DK01)
> +                       /* Downstream Xperia 10 V: FLM1,FLM2 On */
> +                       mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x8f, 0x27, 0x25);
> +               else if (0) /* TODO: Both use the DK01 panel */
> +                       /* Downstream Xperia 10 VI: FLM1 On, FLM2 On */
> +                       mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x8f, 0x27, 0x27);
> +               else
> +                       /* Downsteam: FLM1 on, FLM2 off */
> +                       mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x8f, 0x27, 0x05);
> +
> +               mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0xa5, 0xa5);

And here.
(etc).

+/- these changes:
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij
Re: [PATCH v2 05/11] drm/panel: Add panel driver for Samsung SOFEF01 DDIC
Posted by Marijn Suijten 1 month, 2 weeks ago
On 2025-12-26 14:21:37, Linus Walleij wrote:
...
> Only nitpicks follow:
> 
> > +       if (ctx->panel_type == PANEL_TYPE_TC01 ||
> > +           ctx->panel_type == PANEL_TYPE_UT01 ||
> > +           ctx->panel_type == PANEL_TYPE_UT04) {
> > +               mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0x5a, 0x5a);
> 
> The sofef00 driver tell us exactly what this sequence is:
> 
> #define sofef00_test_key_on_lvl2(ctx) \
>         mipi_dsi_dcs_write_seq_multi(ctx, 0xf0, 0x5a, 0x5a)
> #define sofef00_test_key_off_lvl2(ctx) \
>         mipi_dsi_dcs_write_seq_multi(ctx, 0xf0, 0xa5, 0xa5)
> 
> I would just rename these two to sofef01_test_key_on/off_lvl2()
> and use the same helpers in this driver to follow the sofef00 pattern.

Right, yes.  I think I already brought this up in V1, that some existing
Samsung drivers call this (the 0xf0 part) the MCS PASSWORD, others call it the
LEVEL_2_KEY or USER_KEY or ACCESSPROT.

I'm curious (though should probably look up the patch history) where these names
come from, which of these names match the sofef01/03/souxp00 DDICs provided
here, and what they're supposed to mean (MCS: Magic Command Sequence?).

Then there are possibly a lot more constants we can glean from other drivers,
though again without confirmation that it's identical on this DDIC.

- Marijn
Re: [PATCH v2 05/11] drm/panel: Add panel driver for Samsung SOFEF01 DDIC
Posted by Linus Walleij 1 month, 2 weeks ago
On Fri, Dec 26, 2025 at 3:16 PM Marijn Suijten
<marijn.suijten@somainline.org> wrote:
> On 2025-12-26 14:21:37, Linus Walleij wrote:

> > The sofef00 driver tell us exactly what this sequence is:
> >
> > #define sofef00_test_key_on_lvl2(ctx) \
> >         mipi_dsi_dcs_write_seq_multi(ctx, 0xf0, 0x5a, 0x5a)
> > #define sofef00_test_key_off_lvl2(ctx) \
> >         mipi_dsi_dcs_write_seq_multi(ctx, 0xf0, 0xa5, 0xa5)
> >
> > I would just rename these two to sofef01_test_key_on/off_lvl2()
> > and use the same helpers in this driver to follow the sofef00 pattern.
>
> Right, yes.  I think I already brought this up in V1, that some existing
> Samsung drivers call this (the 0xf0 part) the MCS PASSWORD, others call it the
> LEVEL_2_KEY or USER_KEY or ACCESSPROT.

Actually all of the samsung s6e panels are suspected to be s0fef0/1
display controller variants, which you see if you look inside
panel-samsung-s6e*, for example panel-samsung-s6e3fc2x01.c has this:

#define s6e3fc2x01_test_key_on_lvl1(ctx) \
        mipi_dsi_dcs_write_seq_multi(ctx, 0x9f, 0xa5, 0xa5)
#define s6e3fc2x01_test_key_off_lvl1(ctx) \
        mipi_dsi_dcs_write_seq_multi(ctx, 0x9f, 0x5a, 0x5a)
#define s6e3fc2x01_test_key_on_lvl2(ctx) \
        mipi_dsi_dcs_write_seq_multi(ctx, 0xf0, 0x5a, 0x5a)
#define s6e3fc2x01_test_key_off_lvl2(ctx) \
        mipi_dsi_dcs_write_seq_multi(ctx, 0xf0, 0xa5, 0xa5)
#define s6e3fc2x01_test_key_on_lvl3(ctx) \
        mipi_dsi_dcs_write_seq_multi(ctx, 0xfc, 0x5a, 0x5a)
#define s6e3fc2x01_test_key_off_lvl3(ctx) \
        mipi_dsi_dcs_write_seq_multi(ctx, 0xfc, 0xa5, 0xa5)

So there is also the explanation of the 0xfc command.

> Then there are possibly a lot more constants we can glean from other drivers,
> though again without confirmation that it's identical on this DDIC.

I think the s0fef0/1 drivers and all the panel-samsung-s6e* drivers
should probably be unified a bit maybe we can just create a
local s0fef.h file with the above for all these drivers to use?

(If someone has actual datasheets for s0fef0/1 that would be great.)

Yours,
Linus Walleij
Re: [PATCH v2 05/11] drm/panel: Add panel driver for Samsung SOFEF01 DDIC
Posted by Marijn Suijten 1 month, 1 week ago
On 2025-12-26 18:43:03, Linus Walleij wrote:
> On Fri, Dec 26, 2025 at 3:16 PM Marijn Suijten
> <marijn.suijten@somainline.org> wrote:
> > On 2025-12-26 14:21:37, Linus Walleij wrote:
> 
> > > The sofef00 driver tell us exactly what this sequence is:
> > >
> > > #define sofef00_test_key_on_lvl2(ctx) \
> > >         mipi_dsi_dcs_write_seq_multi(ctx, 0xf0, 0x5a, 0x5a)
> > > #define sofef00_test_key_off_lvl2(ctx) \
> > >         mipi_dsi_dcs_write_seq_multi(ctx, 0xf0, 0xa5, 0xa5)
> > >
> > > I would just rename these two to sofef01_test_key_on/off_lvl2()
> > > and use the same helpers in this driver to follow the sofef00 pattern.
> >
> > Right, yes.  I think I already brought this up in V1, that some existing
> > Samsung drivers call this (the 0xf0 part) the MCS PASSWORD, others call it the
> > LEVEL_2_KEY or USER_KEY or ACCESSPROT.
> 
> Actually all of the samsung s6e panels are suspected to be s0fef0/1

Just noting the first 0 is actually the letter o.

> display controller variants, which you see if you look inside
> panel-samsung-s6e*, for example panel-samsung-s6e3fc2x01.c has this:

...

> I think the s0fef0/1 drivers and all the panel-samsung-s6e* drivers
> should probably be unified a bit maybe we can just create a
> local s0fef.h file with the above for all these drivers to use?
> 
> (If someone has actual datasheets for s0fef0/1 that would be great.)

If we know exactly what the commands are, and have their arguments documented,
it'd be nice to have these as constants and functions in a global reusable
header, but it does require being absolutely certain on their meaning and
equivalence.

- Marijn
Re: [PATCH v2 05/11] drm/panel: Add panel driver for Samsung SOFEF01 DDIC
Posted by Linus Walleij 1 month, 1 week ago
On Mon, Dec 29, 2025 at 12:43 PM Marijn Suijten
<marijn.suijten@somainline.org> wrote:

> > Actually all of the samsung s6e panels are suspected to be s0fef0/1
>
> Just noting the first 0 is actually the letter o.

Yeah I'm sloppy :D sorry.

> > display controller variants, which you see if you look inside
> > panel-samsung-s6e*, for example panel-samsung-s6e3fc2x01.c has this:
> ...
>
> > I think the s0fef0/1 drivers and all the panel-samsung-s6e* drivers
> > should probably be unified a bit maybe we can just create a
> > local s0fef.h file with the above for all these drivers to use?
> >
> > (If someone has actual datasheets for s0fef0/1 that would be great.)
>
> If we know exactly what the commands are, and have their arguments documented,
> it'd be nice to have these as constants and functions in a global reusable
> header, but it does require being absolutely certain on their meaning and
> equivalence.

Yeah well. When all we have is code dumps all we can do is try to
split out the stuff we know for sure is shared. Like the different
unlock commands...

Yours,
Linus Walleij
Re: [PATCH v2 05/11] drm/panel: Add panel driver for Samsung SOFEF01 DDIC
Posted by Marijn Suijten 1 month, 2 weeks ago
On 2025-12-26 15:16:30, Marijn Suijten wrote:
> On 2025-12-26 14:21:37, Linus Walleij wrote:
> ...
> > Only nitpicks follow:
> > 
> > > +       if (ctx->panel_type == PANEL_TYPE_TC01 ||
> > > +           ctx->panel_type == PANEL_TYPE_UT01 ||
> > > +           ctx->panel_type == PANEL_TYPE_UT04) {
> > > +               mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0, 0x5a, 0x5a);
> > 
> > The sofef00 driver tell us exactly what this sequence is:
> > 
> > #define sofef00_test_key_on_lvl2(ctx) \
> >         mipi_dsi_dcs_write_seq_multi(ctx, 0xf0, 0x5a, 0x5a)
> > #define sofef00_test_key_off_lvl2(ctx) \
> >         mipi_dsi_dcs_write_seq_multi(ctx, 0xf0, 0xa5, 0xa5)
> > 
> > I would just rename these two to sofef01_test_key_on/off_lvl2()
> > and use the same helpers in this driver to follow the sofef00 pattern.
> 
> Right, yes.  I think I already brought this up in V1, that some existing
> Samsung drivers call this (the 0xf0 part) the MCS PASSWORD, others call it the
> LEVEL_2_KEY or USER_KEY or ACCESSPROT.
> 
> I'm curious (though should probably look up the patch history) where these names
> come from, which of these names match the sofef01/03/souxp00 DDICs provided
> here, and what they're supposed to mean (MCS: Magic Command Sequence?).

I should have probably looked this up before asking; Manufacturer Command
Sequence.

Likely a generic prefix someone came up with to label commands that are not
part of DCS.

> Then there are possibly a lot more constants we can glean from other drivers,
> though again without confirmation that it's identical on this DDIC.
> 
> - Marijn
Re: [PATCH v2 05/11] drm/panel: Add panel driver for Samsung SOFEF01 DDIC
Posted by kernel test robot 1 month, 2 weeks ago
Hi Marijn,

kernel test robot noticed the following build warnings:

[auto build test WARNING on cc3aa43b44bdb43dfbac0fcb51c56594a11338a8]

url:    https://github.com/intel-lab-lkp/linux/commits/Marijn-Suijten/drm-panel-Clean-up-SOFEF00-config-dependencies/20251222-073548
base:   cc3aa43b44bdb43dfbac0fcb51c56594a11338a8
patch link:    https://lore.kernel.org/r/20251222-drm-panels-sony-v2-5-82a87465d163%40somainline.org
patch subject: [PATCH v2 05/11] drm/panel: Add panel driver for Samsung SOFEF01 DDIC
config: riscv-allyesconfig (https://download.01.org/0day-ci/archive/20251224/202512242356.EwESE8Qv-lkp@intel.com/config)
compiler: clang version 16.0.6 (https://github.com/llvm/llvm-project 7cbf1a2591520c2491aa35339f227775f4d3adf6)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251224/202512242356.EwESE8Qv-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202512242356.EwESE8Qv-lkp@intel.com/

All warnings (new ones prefixed by >>):

>> drivers/gpu/drm/panel/panel-samsung-sofef01.c:389:20: warning: cast to smaller integer type 'enum panel_type' from 'const void *' [-Wvoid-pointer-to-enum-cast]
           ctx->panel_type = (enum panel_type)of_device_get_match_data(dev);
                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1 warning generated.


vim +389 drivers/gpu/drm/panel/panel-samsung-sofef01.c

   357	
   358	static int samsung_sofef01_m_probe(struct mipi_dsi_device *dsi)
   359	{
   360		const struct backlight_properties props = {
   361			.type = BACKLIGHT_RAW,
   362			.brightness = 100,
   363			.max_brightness = 1023,
   364		};
   365		struct device *dev = &dsi->dev;
   366		struct samsung_sofef01_m *ctx;
   367		int ret;
   368	
   369		ctx = devm_drm_panel_alloc(dev, struct samsung_sofef01_m, panel,
   370					   &samsung_sofef01_m_panel_funcs,
   371					   DRM_MODE_CONNECTOR_DSI);
   372		if (IS_ERR(ctx))
   373			return PTR_ERR(ctx);
   374	
   375		ret = devm_regulator_bulk_get_const(
   376			dev,
   377			ARRAY_SIZE(samsung_sofef01_m_supplies),
   378			samsung_sofef01_m_supplies,
   379			&ctx->supplies);
   380		if (ret < 0)
   381			return dev_err_probe(dev, ret, "Failed to get regulators\n");
   382	
   383		ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
   384		if (IS_ERR(ctx->reset_gpio))
   385			return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio),
   386					     "Failed to get reset-gpios\n");
   387	
   388		ctx->dsi = dsi;
 > 389		ctx->panel_type = (enum panel_type)of_device_get_match_data(dev);
   390		if (ctx->panel_type == PANEL_TYPE_TC01)
   391			ctx->mode = &samsung_sofef01_m_61_142_mode;
   392		else if (ctx->panel_type == PANEL_TYPE_DK01)
   393			ctx->mode = &samsung_sofef01_m_61_141_mode;
   394		else
   395			ctx->mode = &samsung_sofef01_m_60_139_mode;
   396		mipi_dsi_set_drvdata(dsi, ctx);
   397	
   398		dsi->lanes = 4;
   399		dsi->format = MIPI_DSI_FMT_RGB888;
   400		dsi->mode_flags = MIPI_DSI_CLOCK_NON_CONTINUOUS;
   401	
   402		ctx->panel.prepare_prev_first = true;
   403	
   404		ctx->panel.backlight = devm_backlight_device_register(
   405			dev, dev_name(dev), dev, dsi,
   406			&samsung_sofef01_m_bl_ops,
   407			&props);
   408		if (IS_ERR(ctx->panel.backlight))
   409			return dev_err_probe(dev, PTR_ERR(ctx->panel.backlight),
   410					     "Failed to create backlight\n");
   411	
   412		drm_panel_add(&ctx->panel);
   413	
   414		ret = mipi_dsi_attach(dsi);
   415		if (ret < 0) {
   416			dev_err(dev, "Failed to attach to DSI host: %d\n", ret);
   417			drm_panel_remove(&ctx->panel);
   418			return ret;
   419		}
   420	
   421		return 0;
   422	}
   423	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH v2 05/11] drm/panel: Add panel driver for Samsung SOFEF01 DDIC
Posted by Dmitry Baryshkov 1 month, 2 weeks ago
On Mon, Dec 22, 2025 at 12:32:11AM +0100, Marijn Suijten wrote:
> This Samsung SOFEF01-M Display-Driver-IC is used to drive 1080x2520@60Hz
> command-mode DSI panels found in many Sony phones:
> - Sony Xperia 5 (kumano bahamut): amb609tc01
> - Sony Xperia 10 II (seine pdx201): ams597ut01
> - Sony Xperia 10 III (lena pdx213): ams597ut04
> - Sony Xperia 10 IV (murray pdx225): ams597ut05
> - Sony Xperia 10 V (zambezi pdx235): ams605dk01
> - Sony Xperia 10 VI (columbia pdx246): ams605dk01
> 
> The amb609tc01 and ams605dk01 come in slightly larger at 6.1" while the
> others are 6.0".
> 
> A "fake" porch calculation is included to artificially bump the clock
> rate necessary to account for "transfer overhead" (DSI packet headers)
> since this is missing from the MSM DSI host driver; porches aren't
> otherwise used on command-mode panels.
> 
> Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
> ---
>  MAINTAINERS                                   |   1 +
>  drivers/gpu/drm/panel/Kconfig                 |  18 +
>  drivers/gpu/drm/panel/Makefile                |   1 +
>  drivers/gpu/drm/panel/panel-samsung-sofef01.c | 463 ++++++++++++++++++++++++++
>  4 files changed, 483 insertions(+)
> 

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>


-- 
With best wishes
Dmitry