mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2 0/2] gpu/drm: panel: add support for DSI panel used in Motorola Atrix 4G and Droid X2
@ 2026-02-23  6:46 Svyatoslav Ryhel
  2026-02-23  6:46 ` [PATCH v2 1/2] dt-bindings: display: panel: document Atrix 4G and Droid X2 DSI panel Svyatoslav Ryhel
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Svyatoslav Ryhel @ 2026-02-23  6:46 UTC (permalink / raw)
  To: Neil Armstrong, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Svyatoslav Ryhel
  Cc: dri-devel, devicetree, linux-kernel

Add support for the DSI LCD panel module found in Motorola Atrix 4G or
Droid X2 smartphones. Exact panel vendor and model are unknown hence panel
uses generic compatible based on board where it is used. The panel has a
540x960 resolution with 24 bit RGB per pixel.

---
Changes in v2:
- updated schema commit description
---

Svyatoslav Ryhel (2):
  dt-bindings: display: panel: document Atrix 4G and Droid X2 DSI panel
  gpu/drm: panel: add support for DSI panel used in Motorola Atrix 4G
    and Droid X2

 .../display/panel/motorola,mot-panel.yaml     |  69 +++++
 drivers/gpu/drm/panel/Kconfig                 |  12 +
 drivers/gpu/drm/panel/Makefile                |   1 +
 drivers/gpu/drm/panel/panel-motorola-mot.c    | 244 ++++++++++++++++++
 4 files changed, 326 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/panel/motorola,mot-panel.yaml
 create mode 100644 drivers/gpu/drm/panel/panel-motorola-mot.c

-- 
2.51.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2 1/2] dt-bindings: display: panel: document Atrix 4G and Droid X2 DSI panel
  2026-02-23  6:46 [PATCH v2 0/2] gpu/drm: panel: add support for DSI panel used in Motorola Atrix 4G and Droid X2 Svyatoslav Ryhel
@ 2026-02-23  6:46 ` Svyatoslav Ryhel
  2026-03-05 23:54   ` Rob Herring (Arm)
  2026-02-23  6:46 ` [PATCH v2 2/2] gpu/drm: panel: add support for DSI panel used in Motorola Atrix 4G and Droid X2 Svyatoslav Ryhel
  2026-03-10 13:28 ` [PATCH v2 0/2] " Neil Armstrong
  2 siblings, 1 reply; 6+ messages in thread
From: Svyatoslav Ryhel @ 2026-02-23  6:46 UTC (permalink / raw)
  To: Neil Armstrong, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Svyatoslav Ryhel
  Cc: dri-devel, devicetree, linux-kernel

Atrix 4G and Droid X2 are based on a board called by Motorola "Mot" and
use the same 540x960 DSI video mode panel. Exact panel vendor and model
are unknown hence generic compatible based on board name "Mot" is used.

Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
 .../display/panel/motorola,mot-panel.yaml     | 69 +++++++++++++++++++
 1 file changed, 69 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/panel/motorola,mot-panel.yaml

diff --git a/Documentation/devicetree/bindings/display/panel/motorola,mot-panel.yaml b/Documentation/devicetree/bindings/display/panel/motorola,mot-panel.yaml
new file mode 100644
index 000000000000..99fa1b3ed426
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/motorola,mot-panel.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/motorola,mot-panel.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Atrix 4G and Droid X2 DSI Display Panel
+
+maintainers:
+  - Svyatoslav Ryhel <clamor95@gmail.com>
+
+description:
+  Atrix 4G and Droid X2 use the same 540x960 DSI video mode panel. Exact
+  panel vendor and model are unknown hence generic compatible based on the
+  board name "Mot" is used.
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    items:
+      - const: motorola,mot-panel
+
+  reg:
+    maxItems: 1
+
+  vdd-supply:
+    description: Regulator for main power supply.
+
+  vddio-supply:
+    description: Regulator for 1.8V IO power supply.
+
+  backlight: true
+  reset-gpios: true
+  port: true
+
+required:
+  - compatible
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    dsi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        panel@0 {
+            compatible = "motorola,mot-panel";
+            reg = <0>;
+
+            reset-gpios = <&gpio 35 GPIO_ACTIVE_LOW>;
+
+            vdd-supply = <&vdd_5v0_panel>;
+            vddio-supply = <&vdd_1v8_vio>;
+
+            backlight = <&backlight>;
+
+            port {
+                panel_in: endpoint {
+                    remote-endpoint = <&dsi_out>;
+                };
+            };
+        };
+    };
+...
-- 
2.51.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2 2/2] gpu/drm: panel: add support for DSI panel used in Motorola Atrix 4G and Droid X2
  2026-02-23  6:46 [PATCH v2 0/2] gpu/drm: panel: add support for DSI panel used in Motorola Atrix 4G and Droid X2 Svyatoslav Ryhel
  2026-02-23  6:46 ` [PATCH v2 1/2] dt-bindings: display: panel: document Atrix 4G and Droid X2 DSI panel Svyatoslav Ryhel
@ 2026-02-23  6:46 ` Svyatoslav Ryhel
  2026-03-10 13:09   ` Neil Armstrong
  2026-03-10 13:28 ` [PATCH v2 0/2] " Neil Armstrong
  2 siblings, 1 reply; 6+ messages in thread
From: Svyatoslav Ryhel @ 2026-02-23  6:46 UTC (permalink / raw)
  To: Neil Armstrong, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Svyatoslav Ryhel
  Cc: dri-devel, devicetree, linux-kernel

Add support for the DSI LCD panel module found in Motorola Atrix 4G or
Droid X2 smartphones. Exact panel vendor and model are unknown hence panel
uses generic compatible based on board where it is used. The panel has a
540x960 resolution with 24 bit RGB per pixel.

Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
 drivers/gpu/drm/panel/Kconfig              |  12 +
 drivers/gpu/drm/panel/Makefile             |   1 +
 drivers/gpu/drm/panel/panel-motorola-mot.c | 244 +++++++++++++++++++++
 3 files changed, 257 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-motorola-mot.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 307152ad7759..477c54c90b01 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -464,6 +464,18 @@ config DRM_PANEL_MANTIX_MLAF057WE51
 	  has a resolution of 720x1440 pixels, a built in backlight and touch
 	  controller.
 
+config DRM_PANEL_MOTOROLA_MOT
+	tristate "Atrix 4G and Droid X2 540x960 DSI video mode panel"
+	depends on OF
+	depends on DRM_MIPI_DSI
+	depends on BACKLIGHT_CLASS_DEVICE
+	select VIDEOMODE_HELPERS
+	help
+	  Say Y here if you want to enable support for the LCD panel module
+	  for Motorola Atrix 4G or Droid X2. Exact panel vendor and model are
+	  unknown. The panel has a 540x960 resolution and uses 24 bit RGB per
+	  pixel.
+
 config DRM_PANEL_NEC_NL8048HL11
 	tristate "NEC NL8048HL11 RGB panel"
 	depends on GPIOLIB && OF && SPI
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index aeffaa95666d..e17ef8140806 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_DRM_PANEL_LG_LD070WX3) += panel-lg-ld070wx3.o
 obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
 obj-$(CONFIG_DRM_PANEL_LG_SW43408) += panel-lg-sw43408.o
 obj-$(CONFIG_DRM_PANEL_MAGNACHIP_D53E6EA8966) += panel-magnachip-d53e6ea8966.o
+obj-$(CONFIG_DRM_PANEL_MOTOROLA_MOT) += panel-motorola-mot.o
 obj-$(CONFIG_DRM_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o
 obj-$(CONFIG_DRM_PANEL_NEWVISION_NV3051D) += panel-newvision-nv3051d.o
 obj-$(CONFIG_DRM_PANEL_NEWVISION_NV3052C) += panel-newvision-nv3052c.o
diff --git a/drivers/gpu/drm/panel/panel-motorola-mot.c b/drivers/gpu/drm/panel/panel-motorola-mot.c
new file mode 100644
index 000000000000..eb1f86c3d704
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-motorola-mot.c
@@ -0,0 +1,244 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/array_size.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/property.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>
+
+static const struct regulator_bulk_data mot_panel_supplies[] = {
+	{ .supply = "vddio" }, { .supply = "vdd" },
+};
+
+struct mot_panel {
+	struct drm_panel panel;
+	struct mipi_dsi_device *dsi;
+
+	struct gpio_desc *reset_gpio;
+
+	struct regulator_bulk_data *supplies;
+};
+
+static inline struct mot_panel *to_mot_panel(struct drm_panel *panel)
+{
+	return container_of(panel, struct mot_panel, panel);
+}
+
+static void mot_panel_reset(struct mot_panel *priv)
+{
+	gpiod_set_value_cansleep(priv->reset_gpio, 1);
+	usleep_range(50000, 51000);
+	gpiod_set_value_cansleep(priv->reset_gpio, 0);
+	usleep_range(10000, 11000);
+}
+
+static void mot_es2(struct mipi_dsi_multi_context *ctx)
+{
+	mipi_dsi_generic_write_seq_multi(ctx, 0x55, 0x01);
+
+	mipi_dsi_dcs_exit_sleep_mode_multi(ctx);
+	mipi_dsi_msleep(ctx, 120);
+
+	mipi_dsi_generic_write_seq_multi(ctx, 0xf4, 0x00, 0xbb, 0x46, 0x53, 0x0c, 0x49,
+					 0x74, 0x29, 0x12, 0x15, 0x2f, 0x2f, 0x04);
+	mipi_dsi_generic_write_seq_multi(ctx, 0xf8, 0x4b, 0x04, 0x10, 0x1a, 0x2c, 0x2c,
+					 0x2c, 0x2c, 0x14, 0x12);
+
+	mipi_dsi_generic_write_seq_multi(ctx, 0xb5, 0x03, 0x7f, 0x00, 0x80, 0xc7, 0x00);
+	mipi_dsi_generic_write_seq_multi(ctx, 0xb7, 0x66, 0xf6, 0x46, 0x9f, 0x90, 0x99,
+					 0xff, 0x80, 0x6d, 0x01);
+
+	/* Gamma R */
+	mipi_dsi_generic_write_seq_multi(ctx, 0xf9, 0x04);
+	mipi_dsi_generic_write_seq_multi(ctx, 0xfa, 0x00, 0x2f, 0x30, 0x12, 0x0e, 0x0c,
+					 0x22, 0x27, 0x31, 0x2e, 0x07, 0x0f);
+	mipi_dsi_generic_write_seq_multi(ctx, 0xfb, 0x00, 0x2f, 0x30, 0x12, 0x0e, 0x0c,
+					 0x22, 0x27, 0x31, 0x2e, 0x07, 0x0f);
+
+	/* Gamma G */
+	mipi_dsi_generic_write_seq_multi(ctx, 0xf9, 0x02);
+	mipi_dsi_generic_write_seq_multi(ctx, 0xfa, 0x00, 0x2f, 0x37, 0x15, 0x15, 0x11,
+					 0x1f, 0x25, 0x2d, 0x2a, 0x05, 0x0f);
+	mipi_dsi_generic_write_seq_multi(ctx, 0xfb, 0x00, 0x2f, 0x37, 0x15, 0x15, 0x11,
+					 0x1f, 0x25, 0x2d, 0x2a, 0x05, 0x0f);
+
+	/* Gamma B */
+	mipi_dsi_generic_write_seq_multi(ctx, 0xf9, 0x01);
+	mipi_dsi_generic_write_seq_multi(ctx, 0xfa, 0x00, 0x2f, 0x3f, 0x16, 0x1f, 0x15,
+					 0x1f, 0x25, 0x2d, 0x2b, 0x06, 0x0b);
+	mipi_dsi_generic_write_seq_multi(ctx, 0xfb, 0x00, 0x2f, 0x3f, 0x16, 0x1f, 0x15,
+					 0x1f, 0x25, 0x2d, 0x2b, 0x06, 0x0b);
+
+	/* Gamma W */
+	mipi_dsi_generic_write_seq_multi(ctx, 0xf9, 0x20);
+	mipi_dsi_generic_write_seq_multi(ctx, 0xfa, 0x00, 0x2f, 0x34, 0x15, 0x1a, 0x11,
+					 0x1f, 0x23, 0x2d, 0x29, 0x02, 0x08);
+	mipi_dsi_generic_write_seq_multi(ctx, 0xfb, 0x00, 0x2f, 0x34, 0x15, 0x1a, 0x11,
+					 0x1f, 0x23, 0x2d, 0x29, 0x02, 0x08);
+
+	mipi_dsi_generic_write_seq_multi(ctx, 0x53, 0x2c);
+	mipi_dsi_generic_write_seq_multi(ctx, 0x35, 0x00);
+}
+
+static int mot_panel_prepare(struct drm_panel *panel)
+{
+	struct mot_panel *priv = to_mot_panel(panel);
+	struct mipi_dsi_multi_context ctx = { .dsi = priv->dsi };
+	struct device *dev = panel->dev;
+	int ret;
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(mot_panel_supplies), priv->supplies);
+	if (ret < 0) {
+		dev_err(dev, "failed to enable power supplies: %d\n", ret);
+		return ret;
+	}
+
+	mot_panel_reset(priv);
+
+	mipi_dsi_generic_write_seq_multi(&ctx, 0xf0, 0x5a, 0x5a);
+	mipi_dsi_generic_write_seq_multi(&ctx, 0xf1, 0x5a, 0x5a);
+	mipi_dsi_generic_write_seq_multi(&ctx, 0xd0, 0x8e);
+
+	mot_es2(&ctx);
+
+	mipi_dsi_dcs_set_display_on_multi(&ctx);
+	mipi_dsi_msleep(&ctx, 20);
+
+	return ctx.accum_err;
+}
+
+static int mot_panel_disable(struct drm_panel *panel)
+{
+	struct mot_panel *priv = to_mot_panel(panel);
+	struct mipi_dsi_multi_context ctx = { .dsi = priv->dsi };
+
+	mipi_dsi_dcs_set_display_off_multi(&ctx);
+	mipi_dsi_dcs_enter_sleep_mode_multi(&ctx);
+	mipi_dsi_msleep(&ctx, 70);
+
+	return ctx.accum_err;
+}
+
+static int mot_panel_unprepare(struct drm_panel *panel)
+{
+	struct mot_panel *priv = to_mot_panel(panel);
+
+	usleep_range(10000, 11000);
+
+	gpiod_set_value_cansleep(priv->reset_gpio, 1);
+	usleep_range(5000, 6000);
+
+	regulator_bulk_disable(ARRAY_SIZE(mot_panel_supplies), priv->supplies);
+
+	return 0;
+}
+
+static const struct drm_display_mode mot_panel_mode = {
+	.clock = (540 + 32 + 32 + 16) * (960 + 12 + 12 + 8) * 60 / 1000,
+	.hdisplay = 540,
+	.hsync_start = 540 + 32,
+	.hsync_end = 540 + 32 + 32,
+	.htotal = 540 + 32 + 32 + 16,
+	.vdisplay = 960,
+	.vsync_start = 960 + 12,
+	.vsync_end = 960 + 12 + 12,
+	.vtotal = 960 + 12 + 12 + 8,
+	.width_mm = 51,
+	.height_mm = 91,
+	.type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
+};
+
+static int mot_panel_get_modes(struct drm_panel *panel,
+			       struct drm_connector *connector)
+{
+	return drm_connector_helper_get_modes_fixed(connector, &mot_panel_mode);
+}
+
+static const struct drm_panel_funcs mot_panel_panel_funcs = {
+	.prepare = mot_panel_prepare,
+	.disable = mot_panel_disable,
+	.unprepare = mot_panel_unprepare,
+	.get_modes = mot_panel_get_modes,
+};
+
+static int mot_panel_probe(struct mipi_dsi_device *dsi)
+{
+	struct device *dev = &dsi->dev;
+	struct mot_panel *priv;
+	int ret;
+
+	priv = devm_drm_panel_alloc(dev, struct mot_panel, panel,
+				    &mot_panel_panel_funcs,
+				    DRM_MODE_CONNECTOR_DSI);
+	if (IS_ERR(priv))
+		return PTR_ERR(priv);
+
+	ret = devm_regulator_bulk_get_const(dev, ARRAY_SIZE(mot_panel_supplies),
+					    mot_panel_supplies, &priv->supplies);
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "failed to get supplies\n");
+
+	priv->reset_gpio = devm_gpiod_get_optional(dev, "reset",
+						   GPIOD_OUT_HIGH);
+	if (IS_ERR(priv->reset_gpio))
+		return dev_err_probe(dev, PTR_ERR(priv->reset_gpio),
+				     "failed to get reset gpios\n");
+
+	priv->dsi = dsi;
+	mipi_dsi_set_drvdata(dsi, priv);
+
+	dsi->lanes = 2;
+	dsi->format = MIPI_DSI_FMT_RGB888;
+	dsi->mode_flags = MIPI_DSI_MODE_LPM;
+
+	ret = drm_panel_of_backlight(&priv->panel);
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "failed to get backlight\n");
+
+	drm_panel_add(&priv->panel);
+
+	ret = devm_mipi_dsi_attach(dev, dsi);
+	if (ret < 0) {
+		drm_panel_remove(&priv->panel);
+		return dev_err_probe(dev, ret, "failed to attach to DSI host\n");
+	}
+
+	return 0;
+}
+
+static void mot_panel_remove(struct mipi_dsi_device *dsi)
+{
+	struct mot_panel *priv = mipi_dsi_get_drvdata(dsi);
+
+	drm_panel_remove(&priv->panel);
+}
+
+static const struct of_device_id mot_panel_of_match[] = {
+	{ .compatible = "motorola,mot-panel" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mot_panel_of_match);
+
+static struct mipi_dsi_driver mot_panel_driver = {
+	.driver = {
+		.name = "panel-motorola-mot",
+		.of_match_table = mot_panel_of_match,
+	},
+	.probe = mot_panel_probe,
+	.remove = mot_panel_remove,
+};
+module_mipi_dsi_driver(mot_panel_driver);
+
+MODULE_AUTHOR("Svyatoslav Ryhel <clamor95@gmail.com>");
+MODULE_DESCRIPTION("Motorola MOT panel driver");
+MODULE_LICENSE("GPL");
-- 
2.51.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 1/2] dt-bindings: display: panel: document Atrix 4G and Droid X2 DSI panel
  2026-02-23  6:46 ` [PATCH v2 1/2] dt-bindings: display: panel: document Atrix 4G and Droid X2 DSI panel Svyatoslav Ryhel
@ 2026-03-05 23:54   ` Rob Herring (Arm)
  0 siblings, 0 replies; 6+ messages in thread
From: Rob Herring (Arm) @ 2026-03-05 23:54 UTC (permalink / raw)
  To: Svyatoslav Ryhel
  Cc: Simona Vetter, dri-devel, linux-kernel, Maarten Lankhorst,
	Maxime Ripard, David Airlie, Krzysztof Kozlowski, Conor Dooley,
	Thomas Zimmermann, devicetree, Neil Armstrong


On Mon, 23 Feb 2026 08:46:29 +0200, Svyatoslav Ryhel wrote:
> Atrix 4G and Droid X2 are based on a board called by Motorola "Mot" and
> use the same 540x960 DSI video mode panel. Exact panel vendor and model
> are unknown hence generic compatible based on board name "Mot" is used.
> 
> Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
> ---
>  .../display/panel/motorola,mot-panel.yaml     | 69 +++++++++++++++++++
>  1 file changed, 69 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/display/panel/motorola,mot-panel.yaml
> 

Reviewed-by: Rob Herring (Arm) <robh@kernel.org>


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 2/2] gpu/drm: panel: add support for DSI panel used in Motorola Atrix 4G and Droid X2
  2026-02-23  6:46 ` [PATCH v2 2/2] gpu/drm: panel: add support for DSI panel used in Motorola Atrix 4G and Droid X2 Svyatoslav Ryhel
@ 2026-03-10 13:09   ` Neil Armstrong
  0 siblings, 0 replies; 6+ messages in thread
From: Neil Armstrong @ 2026-03-10 13:09 UTC (permalink / raw)
  To: Svyatoslav Ryhel, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: dri-devel, devicetree, linux-kernel

On 2/23/26 07:46, Svyatoslav Ryhel wrote:
> Add support for the DSI LCD panel module found in Motorola Atrix 4G or
> Droid X2 smartphones. Exact panel vendor and model are unknown hence panel
> uses generic compatible based on board where it is used. The panel has a
> 540x960 resolution with 24 bit RGB per pixel.
> 
> Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
> ---
>   drivers/gpu/drm/panel/Kconfig              |  12 +
>   drivers/gpu/drm/panel/Makefile             |   1 +
>   drivers/gpu/drm/panel/panel-motorola-mot.c | 244 +++++++++++++++++++++
>   3 files changed, 257 insertions(+)
>   create mode 100644 drivers/gpu/drm/panel/panel-motorola-mot.c
> 
> diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
> index 307152ad7759..477c54c90b01 100644
> --- a/drivers/gpu/drm/panel/Kconfig
> +++ b/drivers/gpu/drm/panel/Kconfig
> @@ -464,6 +464,18 @@ config DRM_PANEL_MANTIX_MLAF057WE51
>   	  has a resolution of 720x1440 pixels, a built in backlight and touch
>   	  controller.
>   
> +config DRM_PANEL_MOTOROLA_MOT
> +	tristate "Atrix 4G and Droid X2 540x960 DSI video mode panel"
> +	depends on OF
> +	depends on DRM_MIPI_DSI
> +	depends on BACKLIGHT_CLASS_DEVICE
> +	select VIDEOMODE_HELPERS
> +	help
> +	  Say Y here if you want to enable support for the LCD panel module
> +	  for Motorola Atrix 4G or Droid X2. Exact panel vendor and model are
> +	  unknown. The panel has a 540x960 resolution and uses 24 bit RGB per
> +	  pixel.
> +
>   config DRM_PANEL_NEC_NL8048HL11
>   	tristate "NEC NL8048HL11 RGB panel"
>   	depends on GPIOLIB && OF && SPI
> diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
> index aeffaa95666d..e17ef8140806 100644
> --- a/drivers/gpu/drm/panel/Makefile
> +++ b/drivers/gpu/drm/panel/Makefile
> @@ -45,6 +45,7 @@ obj-$(CONFIG_DRM_PANEL_LG_LD070WX3) += panel-lg-ld070wx3.o
>   obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
>   obj-$(CONFIG_DRM_PANEL_LG_SW43408) += panel-lg-sw43408.o
>   obj-$(CONFIG_DRM_PANEL_MAGNACHIP_D53E6EA8966) += panel-magnachip-d53e6ea8966.o
> +obj-$(CONFIG_DRM_PANEL_MOTOROLA_MOT) += panel-motorola-mot.o
>   obj-$(CONFIG_DRM_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o
>   obj-$(CONFIG_DRM_PANEL_NEWVISION_NV3051D) += panel-newvision-nv3051d.o
>   obj-$(CONFIG_DRM_PANEL_NEWVISION_NV3052C) += panel-newvision-nv3052c.o
> diff --git a/drivers/gpu/drm/panel/panel-motorola-mot.c b/drivers/gpu/drm/panel/panel-motorola-mot.c
> new file mode 100644
> index 000000000000..eb1f86c3d704
> --- /dev/null
> +++ b/drivers/gpu/drm/panel/panel-motorola-mot.c
> @@ -0,0 +1,244 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include <linux/array_size.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +#include <linux/property.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>
> +
> +static const struct regulator_bulk_data mot_panel_supplies[] = {
> +	{ .supply = "vddio" }, { .supply = "vdd" },
> +};
> +
> +struct mot_panel {
> +	struct drm_panel panel;
> +	struct mipi_dsi_device *dsi;
> +
> +	struct gpio_desc *reset_gpio;
> +
> +	struct regulator_bulk_data *supplies;
> +};
> +
> +static inline struct mot_panel *to_mot_panel(struct drm_panel *panel)
> +{
> +	return container_of(panel, struct mot_panel, panel);
> +}
> +
> +static void mot_panel_reset(struct mot_panel *priv)
> +{
> +	gpiod_set_value_cansleep(priv->reset_gpio, 1);
> +	usleep_range(50000, 51000);
> +	gpiod_set_value_cansleep(priv->reset_gpio, 0);
> +	usleep_range(10000, 11000);
> +}
> +
> +static void mot_es2(struct mipi_dsi_multi_context *ctx)
> +{
> +	mipi_dsi_generic_write_seq_multi(ctx, 0x55, 0x01);
> +
> +	mipi_dsi_dcs_exit_sleep_mode_multi(ctx);
> +	mipi_dsi_msleep(ctx, 120);
> +
> +	mipi_dsi_generic_write_seq_multi(ctx, 0xf4, 0x00, 0xbb, 0x46, 0x53, 0x0c, 0x49,
> +					 0x74, 0x29, 0x12, 0x15, 0x2f, 0x2f, 0x04);
> +	mipi_dsi_generic_write_seq_multi(ctx, 0xf8, 0x4b, 0x04, 0x10, 0x1a, 0x2c, 0x2c,
> +					 0x2c, 0x2c, 0x14, 0x12);
> +
> +	mipi_dsi_generic_write_seq_multi(ctx, 0xb5, 0x03, 0x7f, 0x00, 0x80, 0xc7, 0x00);
> +	mipi_dsi_generic_write_seq_multi(ctx, 0xb7, 0x66, 0xf6, 0x46, 0x9f, 0x90, 0x99,
> +					 0xff, 0x80, 0x6d, 0x01);
> +
> +	/* Gamma R */
> +	mipi_dsi_generic_write_seq_multi(ctx, 0xf9, 0x04);
> +	mipi_dsi_generic_write_seq_multi(ctx, 0xfa, 0x00, 0x2f, 0x30, 0x12, 0x0e, 0x0c,
> +					 0x22, 0x27, 0x31, 0x2e, 0x07, 0x0f);
> +	mipi_dsi_generic_write_seq_multi(ctx, 0xfb, 0x00, 0x2f, 0x30, 0x12, 0x0e, 0x0c,
> +					 0x22, 0x27, 0x31, 0x2e, 0x07, 0x0f);
> +
> +	/* Gamma G */
> +	mipi_dsi_generic_write_seq_multi(ctx, 0xf9, 0x02);
> +	mipi_dsi_generic_write_seq_multi(ctx, 0xfa, 0x00, 0x2f, 0x37, 0x15, 0x15, 0x11,
> +					 0x1f, 0x25, 0x2d, 0x2a, 0x05, 0x0f);
> +	mipi_dsi_generic_write_seq_multi(ctx, 0xfb, 0x00, 0x2f, 0x37, 0x15, 0x15, 0x11,
> +					 0x1f, 0x25, 0x2d, 0x2a, 0x05, 0x0f);
> +
> +	/* Gamma B */
> +	mipi_dsi_generic_write_seq_multi(ctx, 0xf9, 0x01);
> +	mipi_dsi_generic_write_seq_multi(ctx, 0xfa, 0x00, 0x2f, 0x3f, 0x16, 0x1f, 0x15,
> +					 0x1f, 0x25, 0x2d, 0x2b, 0x06, 0x0b);
> +	mipi_dsi_generic_write_seq_multi(ctx, 0xfb, 0x00, 0x2f, 0x3f, 0x16, 0x1f, 0x15,
> +					 0x1f, 0x25, 0x2d, 0x2b, 0x06, 0x0b);
> +
> +	/* Gamma W */
> +	mipi_dsi_generic_write_seq_multi(ctx, 0xf9, 0x20);
> +	mipi_dsi_generic_write_seq_multi(ctx, 0xfa, 0x00, 0x2f, 0x34, 0x15, 0x1a, 0x11,
> +					 0x1f, 0x23, 0x2d, 0x29, 0x02, 0x08);
> +	mipi_dsi_generic_write_seq_multi(ctx, 0xfb, 0x00, 0x2f, 0x34, 0x15, 0x1a, 0x11,
> +					 0x1f, 0x23, 0x2d, 0x29, 0x02, 0x08);
> +
> +	mipi_dsi_generic_write_seq_multi(ctx, 0x53, 0x2c);
> +	mipi_dsi_generic_write_seq_multi(ctx, 0x35, 0x00);
> +}
> +
> +static int mot_panel_prepare(struct drm_panel *panel)
> +{
> +	struct mot_panel *priv = to_mot_panel(panel);
> +	struct mipi_dsi_multi_context ctx = { .dsi = priv->dsi };
> +	struct device *dev = panel->dev;
> +	int ret;
> +
> +	ret = regulator_bulk_enable(ARRAY_SIZE(mot_panel_supplies), priv->supplies);
> +	if (ret < 0) {
> +		dev_err(dev, "failed to enable power supplies: %d\n", ret);
> +		return ret;
> +	}
> +
> +	mot_panel_reset(priv);
> +
> +	mipi_dsi_generic_write_seq_multi(&ctx, 0xf0, 0x5a, 0x5a);
> +	mipi_dsi_generic_write_seq_multi(&ctx, 0xf1, 0x5a, 0x5a);
> +	mipi_dsi_generic_write_seq_multi(&ctx, 0xd0, 0x8e);
> +
> +	mot_es2(&ctx);
> +
> +	mipi_dsi_dcs_set_display_on_multi(&ctx);
> +	mipi_dsi_msleep(&ctx, 20);
> +
> +	return ctx.accum_err;
> +}
> +
> +static int mot_panel_disable(struct drm_panel *panel)
> +{
> +	struct mot_panel *priv = to_mot_panel(panel);
> +	struct mipi_dsi_multi_context ctx = { .dsi = priv->dsi };
> +
> +	mipi_dsi_dcs_set_display_off_multi(&ctx);
> +	mipi_dsi_dcs_enter_sleep_mode_multi(&ctx);
> +	mipi_dsi_msleep(&ctx, 70);
> +
> +	return ctx.accum_err;
> +}
> +
> +static int mot_panel_unprepare(struct drm_panel *panel)
> +{
> +	struct mot_panel *priv = to_mot_panel(panel);
> +
> +	usleep_range(10000, 11000);
> +
> +	gpiod_set_value_cansleep(priv->reset_gpio, 1);
> +	usleep_range(5000, 6000);
> +
> +	regulator_bulk_disable(ARRAY_SIZE(mot_panel_supplies), priv->supplies);
> +
> +	return 0;
> +}
> +
> +static const struct drm_display_mode mot_panel_mode = {
> +	.clock = (540 + 32 + 32 + 16) * (960 + 12 + 12 + 8) * 60 / 1000,
> +	.hdisplay = 540,
> +	.hsync_start = 540 + 32,
> +	.hsync_end = 540 + 32 + 32,
> +	.htotal = 540 + 32 + 32 + 16,
> +	.vdisplay = 960,
> +	.vsync_start = 960 + 12,
> +	.vsync_end = 960 + 12 + 12,
> +	.vtotal = 960 + 12 + 12 + 8,
> +	.width_mm = 51,
> +	.height_mm = 91,
> +	.type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
> +};
> +
> +static int mot_panel_get_modes(struct drm_panel *panel,
> +			       struct drm_connector *connector)
> +{
> +	return drm_connector_helper_get_modes_fixed(connector, &mot_panel_mode);
> +}
> +
> +static const struct drm_panel_funcs mot_panel_panel_funcs = {
> +	.prepare = mot_panel_prepare,
> +	.disable = mot_panel_disable,
> +	.unprepare = mot_panel_unprepare,
> +	.get_modes = mot_panel_get_modes,
> +};
> +
> +static int mot_panel_probe(struct mipi_dsi_device *dsi)
> +{
> +	struct device *dev = &dsi->dev;
> +	struct mot_panel *priv;
> +	int ret;
> +
> +	priv = devm_drm_panel_alloc(dev, struct mot_panel, panel,
> +				    &mot_panel_panel_funcs,
> +				    DRM_MODE_CONNECTOR_DSI);
> +	if (IS_ERR(priv))
> +		return PTR_ERR(priv);
> +
> +	ret = devm_regulator_bulk_get_const(dev, ARRAY_SIZE(mot_panel_supplies),
> +					    mot_panel_supplies, &priv->supplies);
> +	if (ret < 0)
> +		return dev_err_probe(dev, ret, "failed to get supplies\n");
> +
> +	priv->reset_gpio = devm_gpiod_get_optional(dev, "reset",
> +						   GPIOD_OUT_HIGH);
> +	if (IS_ERR(priv->reset_gpio))
> +		return dev_err_probe(dev, PTR_ERR(priv->reset_gpio),
> +				     "failed to get reset gpios\n");
> +
> +	priv->dsi = dsi;
> +	mipi_dsi_set_drvdata(dsi, priv);
> +
> +	dsi->lanes = 2;
> +	dsi->format = MIPI_DSI_FMT_RGB888;
> +	dsi->mode_flags = MIPI_DSI_MODE_LPM;
> +
> +	ret = drm_panel_of_backlight(&priv->panel);
> +	if (ret < 0)
> +		return dev_err_probe(dev, ret, "failed to get backlight\n");
> +
> +	drm_panel_add(&priv->panel);
> +
> +	ret = devm_mipi_dsi_attach(dev, dsi);
> +	if (ret < 0) {
> +		drm_panel_remove(&priv->panel);
> +		return dev_err_probe(dev, ret, "failed to attach to DSI host\n");
> +	}
> +
> +	return 0;
> +}
> +
> +static void mot_panel_remove(struct mipi_dsi_device *dsi)
> +{
> +	struct mot_panel *priv = mipi_dsi_get_drvdata(dsi);
> +
> +	drm_panel_remove(&priv->panel);
> +}
> +
> +static const struct of_device_id mot_panel_of_match[] = {
> +	{ .compatible = "motorola,mot-panel" },
> +	{ /* sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, mot_panel_of_match);
> +
> +static struct mipi_dsi_driver mot_panel_driver = {
> +	.driver = {
> +		.name = "panel-motorola-mot",
> +		.of_match_table = mot_panel_of_match,
> +	},
> +	.probe = mot_panel_probe,
> +	.remove = mot_panel_remove,
> +};
> +module_mipi_dsi_driver(mot_panel_driver);
> +
> +MODULE_AUTHOR("Svyatoslav Ryhel <clamor95@gmail.com>");
> +MODULE_DESCRIPTION("Motorola MOT panel driver");
> +MODULE_LICENSE("GPL");

Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>

Thanks,
Neil

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 0/2] gpu/drm: panel: add support for DSI panel used in Motorola Atrix 4G and Droid X2
  2026-02-23  6:46 [PATCH v2 0/2] gpu/drm: panel: add support for DSI panel used in Motorola Atrix 4G and Droid X2 Svyatoslav Ryhel
  2026-02-23  6:46 ` [PATCH v2 1/2] dt-bindings: display: panel: document Atrix 4G and Droid X2 DSI panel Svyatoslav Ryhel
  2026-02-23  6:46 ` [PATCH v2 2/2] gpu/drm: panel: add support for DSI panel used in Motorola Atrix 4G and Droid X2 Svyatoslav Ryhel
@ 2026-03-10 13:28 ` Neil Armstrong
  2 siblings, 0 replies; 6+ messages in thread
From: Neil Armstrong @ 2026-03-10 13:28 UTC (permalink / raw)
  To: Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	David Airlie, Simona Vetter, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Svyatoslav Ryhel
  Cc: dri-devel, devicetree, linux-kernel

Hi,

On Mon, 23 Feb 2026 08:46:28 +0200, Svyatoslav Ryhel wrote:
> Add support for the DSI LCD panel module found in Motorola Atrix 4G or
> Droid X2 smartphones. Exact panel vendor and model are unknown hence panel
> uses generic compatible based on board where it is used. The panel has a
> 540x960 resolution with 24 bit RGB per pixel.
> 

Thanks, Applied to https://gitlab.freedesktop.org/drm/misc/kernel.git (drm-misc-next)

[1/2] dt-bindings: display: panel: document Atrix 4G and Droid X2 DSI panel
      https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/6b263e50c036ab5a366142fb050e287d50d404b6
[2/2] gpu/drm: panel: add support for DSI panel used in Motorola Atrix 4G and Droid X2
      https://gitlab.freedesktop.org/drm/misc/kernel/-/commit/a187482243cac177d04ce9b5571acc76ab800e9b

-- 
Neil


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-03-10 13:29 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-02-23  6:46 [PATCH v2 0/2] gpu/drm: panel: add support for DSI panel used in Motorola Atrix 4G and Droid X2 Svyatoslav Ryhel
2026-02-23  6:46 ` [PATCH v2 1/2] dt-bindings: display: panel: document Atrix 4G and Droid X2 DSI panel Svyatoslav Ryhel
2026-03-05 23:54   ` Rob Herring (Arm)
2026-02-23  6:46 ` [PATCH v2 2/2] gpu/drm: panel: add support for DSI panel used in Motorola Atrix 4G and Droid X2 Svyatoslav Ryhel
2026-03-10 13:09   ` Neil Armstrong
2026-03-10 13:28 ` [PATCH v2 0/2] " Neil Armstrong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®