* [PATCH 0/2] drm/panel: Add Novatek NT37801 panel driver
@ 2025-05-05 9:16 Krzysztof Kozlowski
2025-05-05 9:16 ` [PATCH 1/2] dt-bindings: display: panel: Add Novatek NT37801 Krzysztof Kozlowski
2025-05-05 9:16 ` [PATCH 2/2] drm/panel: Add Novatek NT37801 panel driver Krzysztof Kozlowski
0 siblings, 2 replies; 8+ messages in thread
From: Krzysztof Kozlowski @ 2025-05-05 9:16 UTC (permalink / raw)
To: Krzysztof Kozlowski, Neil Armstrong, Jessica Zhang, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Conor Dooley
Cc: Krzysztof Kozlowski, dri-devel, devicetree, linux-kernel
Add driver for the Novatek NT37801 or NT37810 AMOLED DSI panel, used on
Qualcomm MTP8750 board (SM8750).
Best regards,
Krzysztof
---
Krzysztof Kozlowski (2):
dt-bindings: display: panel: Add Novatek NT37801
drm/panel: Add Novatek NT37801 panel driver
.../bindings/display/panel/novatek,nt37801.yaml | 69 +++++
MAINTAINERS | 6 +
drivers/gpu/drm/panel/Kconfig | 10 +
drivers/gpu/drm/panel/Makefile | 1 +
drivers/gpu/drm/panel/panel-novatek-nt37801.c | 336 +++++++++++++++++++++
5 files changed, 422 insertions(+)
---
base-commit: 0273d02b2f84f645e8b8ab317722931eb96f6130
change-id: 20250424-sm8750-display-panel-6b66cacb5001
Best regards,
--
Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/2] dt-bindings: display: panel: Add Novatek NT37801
2025-05-05 9:16 [PATCH 0/2] drm/panel: Add Novatek NT37801 panel driver Krzysztof Kozlowski
@ 2025-05-05 9:16 ` Krzysztof Kozlowski
2025-05-08 12:41 ` Linus Walleij
2025-05-05 9:16 ` [PATCH 2/2] drm/panel: Add Novatek NT37801 panel driver Krzysztof Kozlowski
1 sibling, 1 reply; 8+ messages in thread
From: Krzysztof Kozlowski @ 2025-05-05 9:16 UTC (permalink / raw)
To: Krzysztof Kozlowski, Neil Armstrong, Jessica Zhang, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Conor Dooley
Cc: Krzysztof Kozlowski, dri-devel, devicetree, linux-kernel
Add bindings for the Novatek NT37801 or NT37810 AMOLED DSI panel.
Sources, like downstream DTS, schematics and hardware manuals, use two
model names (NT37801 and NT37810), so choose one and hope it is correct.
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
.../bindings/display/panel/novatek,nt37801.yaml | 69 ++++++++++++++++++++++
1 file changed, 69 insertions(+)
diff --git a/Documentation/devicetree/bindings/display/panel/novatek,nt37801.yaml b/Documentation/devicetree/bindings/display/panel/novatek,nt37801.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..1b38c1d0af6825341e047af57584a93261e7af2c
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/novatek,nt37801.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/novatek,nt37801.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Novatek NT37801 AMOLED DSI Panel
+
+maintainers:
+ - Krzysztof Kozlowski <krzk@kernel.org>
+
+description:
+ Naming is inconclusive and different sources claim this is either Novatek
+ NT37801 or NT37810 AMOLED DSI Panel.
+
+allOf:
+ - $ref: panel-common.yaml#
+
+properties:
+ compatible:
+ const: novatek,nt37801
+
+ reg:
+ maxItems: 1
+ description: DSI virtual channel
+
+ vci-supply: true
+ vdd-supply: true
+ vddio-supply: true
+ port: true
+ reset-gpios: true
+
+required:
+ - compatible
+ - reg
+ - vci-supply
+ - vdd-supply
+ - vddio-supply
+ - port
+ - reset-gpios
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+
+ dsi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ panel@0 {
+ compatible = "novatek,nt37801";
+ reg = <0>;
+
+ vci-supply = <&vreg_l13b_3p0>;
+ vdd-supply = <&vreg_l11b_1p2>;
+ vddio-supply = <&vreg_l12b_1p8>;
+
+ reset-gpios = <&tlmm 98 GPIO_ACTIVE_LOW>;
+
+ port {
+ endpoint {
+ remote-endpoint = <&dsi0_out>;
+ };
+ };
+ };
+ };
+...
--
2.45.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/2] drm/panel: Add Novatek NT37801 panel driver
2025-05-05 9:16 [PATCH 0/2] drm/panel: Add Novatek NT37801 panel driver Krzysztof Kozlowski
2025-05-05 9:16 ` [PATCH 1/2] dt-bindings: display: panel: Add Novatek NT37801 Krzysztof Kozlowski
@ 2025-05-05 9:16 ` Krzysztof Kozlowski
2025-05-05 13:58 ` Neil Armstrong
2025-05-08 12:54 ` Linus Walleij
1 sibling, 2 replies; 8+ messages in thread
From: Krzysztof Kozlowski @ 2025-05-05 9:16 UTC (permalink / raw)
To: Krzysztof Kozlowski, Neil Armstrong, Jessica Zhang, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Conor Dooley
Cc: Krzysztof Kozlowski, dri-devel, devicetree, linux-kernel
Add driver for the Novatek NT37801 or NT37810 AMOLED DSI 1440x3200
panel in CMD mode, used on Qualcomm MTP8750 board (SM8750).
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
MAINTAINERS | 6 +
drivers/gpu/drm/panel/Kconfig | 10 +
drivers/gpu/drm/panel/Makefile | 1 +
drivers/gpu/drm/panel/panel-novatek-nt37801.c | 336 ++++++++++++++++++++++++++
4 files changed, 353 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index b2c3be5f6131432647dd01f22bbf4bf1c8bde9e6..78cdd5f81c322c230a82c8a877b2338d932478cb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7595,6 +7595,12 @@ T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
F: Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml
F: drivers/gpu/drm/panel/panel-novatek-nt36672a.c
+DRM DRIVER FOR NOVATEK NT37801 PANELS
+M: Krzysztof Kozlowski <krzk@kernel.org>
+S: Maintained
+F: Documentation/devicetree/bindings/display/panel/novatek,nt37801.yaml
+F: drivers/gpu/drm/panel/panel-novatek-nt37801.c
+
DRM DRIVER FOR NVIDIA GEFORCE/QUADRO GPUS
M: Lyude Paul <lyude@redhat.com>
M: Danilo Krummrich <dakr@kernel.org>
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 7e9c60a626fbbabb954ed2a7e3d1ef5eee0679d6..c7b688995c8d31b7445aa79dcc310742e4e724d8 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -508,6 +508,16 @@ config DRM_PANEL_NOVATEK_NT36672E
LCD panel module. The panel has a resolution of 1080x2408 and uses 24 bit
RGB per pixel.
+config DRM_PANEL_NOVATEK_NT37801
+ tristate "Novatek NT37801/NT37810 AMOLED DSI panel"
+ depends on OF
+ depends on DRM_MIPI_DSI
+ depends on BACKLIGHT_CLASS_DEVICE
+ help
+ Say Y here if you want to enable support for Novatek NT37801 (or
+ NT37810) AMOLED DSI Video Mode LCD panel module with 1440x3200
+ resolution.
+
config DRM_PANEL_NOVATEK_NT39016
tristate "Novatek NT39016 RGB/SPI panel"
depends on OF && SPI
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 883974f0cba128e28f23e31512f8d30d59913b0e..2dcc224cba63e9cf59410fd974e5f068bb9e26b3 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35950) += panel-novatek-nt35950.o
obj-$(CONFIG_DRM_PANEL_NOVATEK_NT36523) += panel-novatek-nt36523.o
obj-$(CONFIG_DRM_PANEL_NOVATEK_NT36672A) += panel-novatek-nt36672a.o
obj-$(CONFIG_DRM_PANEL_NOVATEK_NT36672E) += panel-novatek-nt36672e.o
+obj-$(CONFIG_DRM_PANEL_NOVATEK_NT37801) += panel-novatek-nt37801.o
obj-$(CONFIG_DRM_PANEL_NOVATEK_NT39016) += panel-novatek-nt39016.o
obj-$(CONFIG_DRM_PANEL_MANTIX_MLAF057WE51) += panel-mantix-mlaf057we51.o
obj-$(CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO) += panel-olimex-lcd-olinuxino.o
diff --git a/drivers/gpu/drm/panel/panel-novatek-nt37801.c b/drivers/gpu/drm/panel/panel-novatek-nt37801.c
new file mode 100644
index 0000000000000000000000000000000000000000..2c07a61c3a58819ca4c5e39ae352eac1b1fc694c
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-novatek-nt37801.c
@@ -0,0 +1,336 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2024 Linaro Limited
+
+#include <linux/backlight.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/regulator/consumer.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+
+#include <drm/display/drm_dsc.h>
+#include <drm/display/drm_dsc_helper.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_probe_helper.h>
+
+#include <video/mipi_display.h>
+
+struct novatek_nt37801 {
+ struct drm_panel panel;
+ struct mipi_dsi_device *dsi;
+ struct drm_dsc_config dsc;
+ struct gpio_desc *reset_gpio;
+ struct regulator_bulk_data *supplies;
+};
+
+static const struct regulator_bulk_data novatek_nt37801_supplies[] = {
+ { .supply = "vddio" },
+ { .supply = "vci" },
+ { .supply = "vdd" },
+};
+
+static inline struct novatek_nt37801 *to_novatek_nt37801(struct drm_panel *panel)
+{
+ return container_of(panel, struct novatek_nt37801, panel);
+}
+
+static void novatek_nt37801_reset(struct novatek_nt37801 *ctx)
+{
+ gpiod_set_value_cansleep(ctx->reset_gpio, 0);
+ usleep_range(10000, 21000);
+ gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+ usleep_range(10000, 21000);
+ gpiod_set_value_cansleep(ctx->reset_gpio, 0);
+ usleep_range(10000, 21000);
+}
+
+static int novatek_nt37801_on(struct novatek_nt37801 *ctx)
+{
+ struct mipi_dsi_device *dsi = ctx->dsi;
+ struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi };
+
+ dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0,
+ 0x55, 0xaa, 0x52, 0x08, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xc5, 0x0b, 0x0b, 0x0b);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xff, 0xaa, 0x55, 0xa5, 0x80);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x02);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf5, 0x10);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x1b);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf4, 0x55);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x18);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf8, 0x19);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x0f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfc, 0x00);
+ mipi_dsi_dcs_set_column_address_multi(&dsi_ctx, 0x0000, 0x059f);
+ mipi_dsi_dcs_set_page_address_multi(&dsi_ctx, 0x0000, 0x0c7f);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x90, 0x03, 0x03);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x91,
+ 0x89, 0x28, 0x00, 0x28, 0xc2, 0x00, 0x02,
+ 0x68, 0x04, 0x6c, 0x00, 0x0a, 0x02, 0x77,
+ 0x01, 0xe9, 0x10, 0xf0);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xff, 0xaa, 0x55, 0xa5, 0x81);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x23);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfb,
+ 0x00, 0x01, 0x00, 0x11, 0x33, 0x33, 0x33,
+ 0x55, 0x57, 0xd0, 0x00, 0x00, 0x44, 0x56,
+ 0x77, 0x78, 0x9a, 0xbc, 0xdd, 0xf0);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x06);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf3, 0xdc);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_SET_GAMMA_CURVE, 0x00);
+ mipi_dsi_dcs_set_tear_on_multi(&dsi_ctx, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3b, 0x00, 0x18, 0x00, 0x10);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_CONTROL_DISPLAY,
+ 0x20);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x51,
+ 0x07, 0xff, 0x07, 0xff, 0x0f, 0xff);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5a, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5f, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x9c, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_MEMORY_START);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2f, 0x00);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0,
+ 0x55, 0xaa, 0x52, 0x08, 0x01);
+ mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb2, 0x55, 0x01, 0xff, 0x03);
+ mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx);
+ mipi_dsi_msleep(&dsi_ctx, 120);
+ mipi_dsi_dcs_set_display_on_multi(&dsi_ctx);
+ mipi_dsi_msleep(&dsi_ctx, 20);
+
+ return dsi_ctx.accum_err;
+}
+
+static int novatek_nt37801_off(struct novatek_nt37801 *ctx)
+{
+ struct mipi_dsi_device *dsi = ctx->dsi;
+ struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi };
+
+ dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
+
+ mipi_dsi_dcs_set_display_off_multi(&dsi_ctx);
+ mipi_dsi_msleep(&dsi_ctx, 20);
+
+ mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx);
+ mipi_dsi_msleep(&dsi_ctx, 120);
+
+ return dsi_ctx.accum_err;
+}
+
+static int novatek_nt37801_prepare(struct drm_panel *panel)
+{
+ struct novatek_nt37801 *ctx = to_novatek_nt37801(panel);
+ struct device *dev = &ctx->dsi->dev;
+ struct drm_dsc_picture_parameter_set pps;
+ int ret;
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(novatek_nt37801_supplies),
+ ctx->supplies);
+ if (ret < 0)
+ return ret;
+
+ novatek_nt37801_reset(ctx);
+
+ ret = novatek_nt37801_on(ctx);
+ if (ret < 0)
+ goto err;
+
+ drm_dsc_pps_payload_pack(&pps, &ctx->dsc);
+
+ ret = mipi_dsi_picture_parameter_set(ctx->dsi, &pps);
+ if (ret < 0) {
+ dev_err(panel->dev, "failed to transmit PPS: %d\n", ret);
+ goto err;
+ }
+
+ ret = mipi_dsi_compression_mode(ctx->dsi, true);
+ if (ret < 0) {
+ dev_err(dev, "failed to enable compression mode: %d\n", ret);
+ goto err;
+ }
+
+ msleep(28);
+
+ return 0;
+
+err:
+ gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+ regulator_bulk_disable(ARRAY_SIZE(novatek_nt37801_supplies),
+ ctx->supplies);
+
+ return ret;
+}
+
+static int novatek_nt37801_unprepare(struct drm_panel *panel)
+{
+ struct novatek_nt37801 *ctx = to_novatek_nt37801(panel);
+ struct device *dev = &ctx->dsi->dev;
+ int ret;
+
+ ret = novatek_nt37801_off(ctx);
+ if (ret < 0)
+ dev_err(dev, "Failed to un-initialize panel: %d\n", ret);
+
+ gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+
+ regulator_bulk_disable(ARRAY_SIZE(novatek_nt37801_supplies),
+ ctx->supplies);
+
+ return 0;
+}
+
+static const struct drm_display_mode novatek_nt37801_mode = {
+ .clock = (1440 + 20 + 4 + 20) * (3200 + 20 + 2 + 18) * 120 / 1000,
+ .hdisplay = 1440,
+ .hsync_start = 1440 + 20,
+ .hsync_end = 1440 + 20 + 4,
+ .htotal = 1440 + 20 + 4 + 20,
+ .vdisplay = 3200,
+ .vsync_start = 3200 + 20,
+ .vsync_end = 3200 + 20 + 2,
+ .vtotal = 3200 + 20 + 2 + 18,
+ .type = DRM_MODE_TYPE_DRIVER,
+};
+
+static int novatek_nt37801_get_modes(struct drm_panel *panel,
+ struct drm_connector *connector)
+{
+ return drm_connector_helper_get_modes_fixed(connector,
+ &novatek_nt37801_mode);
+}
+
+static const struct drm_panel_funcs novatek_nt37801_panel_funcs = {
+ .prepare = novatek_nt37801_prepare,
+ .unprepare = novatek_nt37801_unprepare,
+ .get_modes = novatek_nt37801_get_modes,
+};
+
+static int novatek_nt37801_bl_update_status(struct backlight_device *bl)
+{
+ struct mipi_dsi_device *dsi = bl_get_data(bl);
+ u16 brightness = backlight_get_brightness(bl);
+ int ret;
+
+ dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
+
+ ret = mipi_dsi_dcs_set_display_brightness_large(dsi, brightness);
+ if (ret < 0)
+ return ret;
+
+ dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
+ return 0;
+}
+
+static const struct backlight_ops novatek_nt37801_bl_ops = {
+ .update_status = novatek_nt37801_bl_update_status,
+};
+
+static struct backlight_device *
+novatek_nt37801_create_backlight(struct mipi_dsi_device *dsi)
+{
+ struct device *dev = &dsi->dev;
+ const struct backlight_properties props = {
+ .type = BACKLIGHT_RAW,
+ .brightness = 4095,
+ .max_brightness = 4095,
+ };
+
+ return devm_backlight_device_register(dev, dev_name(dev), dev, dsi,
+ &novatek_nt37801_bl_ops, &props);
+}
+
+static int novatek_nt37801_probe(struct mipi_dsi_device *dsi)
+{
+ struct device *dev = &dsi->dev;
+ struct novatek_nt37801 *ctx;
+ int ret;
+
+ ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ ret = devm_regulator_bulk_get_const(dev,
+ ARRAY_SIZE(novatek_nt37801_supplies),
+ novatek_nt37801_supplies,
+ &ctx->supplies);
+ if (ret < 0)
+ return ret;
+
+ ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+ 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;
+ mipi_dsi_set_drvdata(dsi, ctx);
+
+ dsi->lanes = 4;
+ dsi->format = MIPI_DSI_FMT_RGB888;
+ dsi->mode_flags = MIPI_DSI_MODE_NO_EOT_PACKET | MIPI_DSI_CLOCK_NON_CONTINUOUS;
+
+ drm_panel_init(&ctx->panel, dev, &novatek_nt37801_panel_funcs,
+ DRM_MODE_CONNECTOR_DSI);
+ ctx->panel.prepare_prev_first = true;
+
+ ctx->panel.backlight = novatek_nt37801_create_backlight(dsi);
+ 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);
+
+ /* This panel only supports DSC; unconditionally enable it */
+ dsi->dsc = &ctx->dsc;
+ ctx->dsc.dsc_version_major = 1;
+ ctx->dsc.dsc_version_minor = 1;
+ ctx->dsc.slice_height = 40;
+ ctx->dsc.slice_width = 720;
+ ctx->dsc.slice_count = 1440 / ctx->dsc.slice_width;
+ ctx->dsc.bits_per_component = 8;
+ ctx->dsc.bits_per_pixel = 8 << 4; /* 4 fractional bits */
+ ctx->dsc.block_pred_enable = true;
+
+ ret = mipi_dsi_attach(dsi);
+ if (ret < 0) {
+ drm_panel_remove(&ctx->panel);
+ return dev_err_probe(dev, ret, "Failed to attach to DSI host\n");
+ }
+
+ return 0;
+}
+
+static void novatek_nt37801_remove(struct mipi_dsi_device *dsi)
+{
+ struct novatek_nt37801 *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 novatek_nt37801_of_match[] = {
+ { .compatible = "novatek,nt37801" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, novatek_nt37801_of_match);
+
+static struct mipi_dsi_driver novatek_nt37801_driver = {
+ .probe = novatek_nt37801_probe,
+ .remove = novatek_nt37801_remove,
+ .driver = {
+ .name = "panel-novatek-nt37801",
+ .of_match_table = novatek_nt37801_of_match,
+ },
+};
+module_mipi_dsi_driver(novatek_nt37801_driver);
+
+MODULE_AUTHOR("Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>");
+MODULE_DESCRIPTION("Panel driver for the Novatek NT37801/NT37810 AMOLED DSI panel");
+MODULE_LICENSE("GPL");
--
2.45.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] drm/panel: Add Novatek NT37801 panel driver
2025-05-05 9:16 ` [PATCH 2/2] drm/panel: Add Novatek NT37801 panel driver Krzysztof Kozlowski
@ 2025-05-05 13:58 ` Neil Armstrong
2025-05-05 15:14 ` Krzysztof Kozlowski
2025-05-08 12:54 ` Linus Walleij
1 sibling, 1 reply; 8+ messages in thread
From: Neil Armstrong @ 2025-05-05 13:58 UTC (permalink / raw)
To: Krzysztof Kozlowski, Krzysztof Kozlowski, Jessica Zhang,
David Airlie, Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Conor Dooley
Cc: dri-devel, devicetree, linux-kernel
On 05/05/2025 11:16, Krzysztof Kozlowski wrote:
> Add driver for the Novatek NT37801 or NT37810 AMOLED DSI 1440x3200
> panel in CMD mode, used on Qualcomm MTP8750 board (SM8750).
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> ---
> MAINTAINERS | 6 +
> drivers/gpu/drm/panel/Kconfig | 10 +
> drivers/gpu/drm/panel/Makefile | 1 +
> drivers/gpu/drm/panel/panel-novatek-nt37801.c | 336 ++++++++++++++++++++++++++
> 4 files changed, 353 insertions(+)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index b2c3be5f6131432647dd01f22bbf4bf1c8bde9e6..78cdd5f81c322c230a82c8a877b2338d932478cb 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -7595,6 +7595,12 @@ T: git https://gitlab.freedesktop.org/drm/misc/kernel.git
> F: Documentation/devicetree/bindings/display/panel/novatek,nt36672a.yaml
> F: drivers/gpu/drm/panel/panel-novatek-nt36672a.c
>
> +DRM DRIVER FOR NOVATEK NT37801 PANELS
> +M: Krzysztof Kozlowski <krzk@kernel.org>
> +S: Maintained
> +F: Documentation/devicetree/bindings/display/panel/novatek,nt37801.yaml
> +F: drivers/gpu/drm/panel/panel-novatek-nt37801.c
> +
> DRM DRIVER FOR NVIDIA GEFORCE/QUADRO GPUS
> M: Lyude Paul <lyude@redhat.com>
> M: Danilo Krummrich <dakr@kernel.org>
> diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
> index 7e9c60a626fbbabb954ed2a7e3d1ef5eee0679d6..c7b688995c8d31b7445aa79dcc310742e4e724d8 100644
> --- a/drivers/gpu/drm/panel/Kconfig
> +++ b/drivers/gpu/drm/panel/Kconfig
> @@ -508,6 +508,16 @@ config DRM_PANEL_NOVATEK_NT36672E
> LCD panel module. The panel has a resolution of 1080x2408 and uses 24 bit
> RGB per pixel.
>
> +config DRM_PANEL_NOVATEK_NT37801
> + tristate "Novatek NT37801/NT37810 AMOLED DSI panel"
> + depends on OF
> + depends on DRM_MIPI_DSI
> + depends on BACKLIGHT_CLASS_DEVICE
> + help
> + Say Y here if you want to enable support for Novatek NT37801 (or
> + NT37810) AMOLED DSI Video Mode LCD panel module with 1440x3200
> + resolution.
> +
> config DRM_PANEL_NOVATEK_NT39016
> tristate "Novatek NT39016 RGB/SPI panel"
> depends on OF && SPI
> diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
> index 883974f0cba128e28f23e31512f8d30d59913b0e..2dcc224cba63e9cf59410fd974e5f068bb9e26b3 100644
> --- a/drivers/gpu/drm/panel/Makefile
> +++ b/drivers/gpu/drm/panel/Makefile
> @@ -50,6 +50,7 @@ obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35950) += panel-novatek-nt35950.o
> obj-$(CONFIG_DRM_PANEL_NOVATEK_NT36523) += panel-novatek-nt36523.o
> obj-$(CONFIG_DRM_PANEL_NOVATEK_NT36672A) += panel-novatek-nt36672a.o
> obj-$(CONFIG_DRM_PANEL_NOVATEK_NT36672E) += panel-novatek-nt36672e.o
> +obj-$(CONFIG_DRM_PANEL_NOVATEK_NT37801) += panel-novatek-nt37801.o
> obj-$(CONFIG_DRM_PANEL_NOVATEK_NT39016) += panel-novatek-nt39016.o
> obj-$(CONFIG_DRM_PANEL_MANTIX_MLAF057WE51) += panel-mantix-mlaf057we51.o
> obj-$(CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO) += panel-olimex-lcd-olinuxino.o
> diff --git a/drivers/gpu/drm/panel/panel-novatek-nt37801.c b/drivers/gpu/drm/panel/panel-novatek-nt37801.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..2c07a61c3a58819ca4c5e39ae352eac1b1fc694c
> --- /dev/null
> +++ b/drivers/gpu/drm/panel/panel-novatek-nt37801.c
> @@ -0,0 +1,336 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +// Copyright (c) 2024 Linaro Limited
> +
> +#include <linux/backlight.h>
> +#include <linux/delay.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +
> +#include <drm/display/drm_dsc.h>
> +#include <drm/display/drm_dsc_helper.h>
> +#include <drm/drm_mipi_dsi.h>
> +#include <drm/drm_modes.h>
> +#include <drm/drm_panel.h>
> +#include <drm/drm_probe_helper.h>
> +
> +#include <video/mipi_display.h>
> +
> +struct novatek_nt37801 {
> + struct drm_panel panel;
> + struct mipi_dsi_device *dsi;
> + struct drm_dsc_config dsc;
> + struct gpio_desc *reset_gpio;
> + struct regulator_bulk_data *supplies;
> +};
> +
> +static const struct regulator_bulk_data novatek_nt37801_supplies[] = {
> + { .supply = "vddio" },
> + { .supply = "vci" },
> + { .supply = "vdd" },
> +};
> +
> +static inline struct novatek_nt37801 *to_novatek_nt37801(struct drm_panel *panel)
> +{
> + return container_of(panel, struct novatek_nt37801, panel);
> +}
> +
> +static void novatek_nt37801_reset(struct novatek_nt37801 *ctx)
> +{
> + gpiod_set_value_cansleep(ctx->reset_gpio, 0);
> + usleep_range(10000, 21000);
> + gpiod_set_value_cansleep(ctx->reset_gpio, 1);
> + usleep_range(10000, 21000);
> + gpiod_set_value_cansleep(ctx->reset_gpio, 0);
> + usleep_range(10000, 21000);
> +}
> +
> +static int novatek_nt37801_on(struct novatek_nt37801 *ctx)
> +{
> + struct mipi_dsi_device *dsi = ctx->dsi;
> + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi };
> +
> + dsi->mode_flags |= MIPI_DSI_MODE_LPM;
> +
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0,
> + 0x55, 0xaa, 0x52, 0x08, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xc5, 0x0b, 0x0b, 0x0b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xff, 0xaa, 0x55, 0xa5, 0x80);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x02);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf5, 0x10);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x1b);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf4, 0x55);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x18);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf8, 0x19);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x0f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfc, 0x00);
> + mipi_dsi_dcs_set_column_address_multi(&dsi_ctx, 0x0000, 0x059f);
> + mipi_dsi_dcs_set_page_address_multi(&dsi_ctx, 0x0000, 0x0c7f);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x90, 0x03, 0x03);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x91,
> + 0x89, 0x28, 0x00, 0x28, 0xc2, 0x00, 0x02,
> + 0x68, 0x04, 0x6c, 0x00, 0x0a, 0x02, 0x77,
> + 0x01, 0xe9, 0x10, 0xf0);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xff, 0xaa, 0x55, 0xa5, 0x81);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x23);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xfb,
> + 0x00, 0x01, 0x00, 0x11, 0x33, 0x33, 0x33,
> + 0x55, 0x57, 0xd0, 0x00, 0x00, 0x44, 0x56,
> + 0x77, 0x78, 0x9a, 0xbc, 0xdd, 0xf0);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x6f, 0x06);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf3, 0xdc);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_SET_GAMMA_CURVE, 0x00);
> + mipi_dsi_dcs_set_tear_on_multi(&dsi_ctx, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x3b, 0x00, 0x18, 0x00, 0x10);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_CONTROL_DISPLAY,
> + 0x20);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x51,
> + 0x07, 0xff, 0x07, 0xff, 0x0f, 0xff);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5a, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x5f, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x9c, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, MIPI_DCS_WRITE_MEMORY_START);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0x2f, 0x00);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0,
> + 0x55, 0xaa, 0x52, 0x08, 0x01);
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xb2, 0x55, 0x01, 0xff, 0x03);
> + mipi_dsi_dcs_exit_sleep_mode_multi(&dsi_ctx);
> + mipi_dsi_msleep(&dsi_ctx, 120);
> + mipi_dsi_dcs_set_display_on_multi(&dsi_ctx);
> + mipi_dsi_msleep(&dsi_ctx, 20);
> +
> + return dsi_ctx.accum_err;
> +}
> +
> +static int novatek_nt37801_off(struct novatek_nt37801 *ctx)
> +{
> + struct mipi_dsi_device *dsi = ctx->dsi;
> + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi };
> +
> + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
> +
> + mipi_dsi_dcs_set_display_off_multi(&dsi_ctx);
> + mipi_dsi_msleep(&dsi_ctx, 20);
> +
> + mipi_dsi_dcs_enter_sleep_mode_multi(&dsi_ctx);
> + mipi_dsi_msleep(&dsi_ctx, 120);
> +
> + return dsi_ctx.accum_err;
> +}
> +
> +static int novatek_nt37801_prepare(struct drm_panel *panel)
> +{
> + struct novatek_nt37801 *ctx = to_novatek_nt37801(panel);
> + struct device *dev = &ctx->dsi->dev;
> + struct drm_dsc_picture_parameter_set pps;
> + int ret;
> +
> + ret = regulator_bulk_enable(ARRAY_SIZE(novatek_nt37801_supplies),
> + ctx->supplies);
> + if (ret < 0)
> + return ret;
> +
> + novatek_nt37801_reset(ctx);
> +
> + ret = novatek_nt37801_on(ctx);
> + if (ret < 0)
> + goto err;
> +
> + drm_dsc_pps_payload_pack(&pps, &ctx->dsc);
> +
> + ret = mipi_dsi_picture_parameter_set(ctx->dsi, &pps);
> + if (ret < 0) {
> + dev_err(panel->dev, "failed to transmit PPS: %d\n", ret);
> + goto err;
> + }
> +
> + ret = mipi_dsi_compression_mode(ctx->dsi, true);
> + if (ret < 0) {
> + dev_err(dev, "failed to enable compression mode: %d\n", ret);
> + goto err;
> + }
> +
> + msleep(28);
> +
> + return 0;
> +
> +err:
> + gpiod_set_value_cansleep(ctx->reset_gpio, 1);
> + regulator_bulk_disable(ARRAY_SIZE(novatek_nt37801_supplies),
> + ctx->supplies);
> +
> + return ret;
> +}
> +
> +static int novatek_nt37801_unprepare(struct drm_panel *panel)
> +{
> + struct novatek_nt37801 *ctx = to_novatek_nt37801(panel);
> + struct device *dev = &ctx->dsi->dev;
> + int ret;
> +
> + ret = novatek_nt37801_off(ctx);
> + if (ret < 0)
> + dev_err(dev, "Failed to un-initialize panel: %d\n", ret);
> +
> + gpiod_set_value_cansleep(ctx->reset_gpio, 1);
> +
> + regulator_bulk_disable(ARRAY_SIZE(novatek_nt37801_supplies),
> + ctx->supplies);
> +
> + return 0;
> +}
> +
> +static const struct drm_display_mode novatek_nt37801_mode = {
> + .clock = (1440 + 20 + 4 + 20) * (3200 + 20 + 2 + 18) * 120 / 1000,
> + .hdisplay = 1440,
> + .hsync_start = 1440 + 20,
> + .hsync_end = 1440 + 20 + 4,
> + .htotal = 1440 + 20 + 4 + 20,
> + .vdisplay = 3200,
> + .vsync_start = 3200 + 20,
> + .vsync_end = 3200 + 20 + 2,
> + .vtotal = 3200 + 20 + 2 + 18,
> + .type = DRM_MODE_TYPE_DRIVER,
> +};
> +
> +static int novatek_nt37801_get_modes(struct drm_panel *panel,
> + struct drm_connector *connector)
> +{
> + return drm_connector_helper_get_modes_fixed(connector,
> + &novatek_nt37801_mode);
> +}
> +
> +static const struct drm_panel_funcs novatek_nt37801_panel_funcs = {
> + .prepare = novatek_nt37801_prepare,
> + .unprepare = novatek_nt37801_unprepare,
> + .get_modes = novatek_nt37801_get_modes,
> +};
> +
> +static int novatek_nt37801_bl_update_status(struct backlight_device *bl)
> +{
> + struct mipi_dsi_device *dsi = bl_get_data(bl);
> + u16 brightness = backlight_get_brightness(bl);
> + int ret;
> +
> + dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
> +
> + ret = mipi_dsi_dcs_set_display_brightness_large(dsi, brightness);
> + if (ret < 0)
> + return ret;
> +
> + dsi->mode_flags |= MIPI_DSI_MODE_LPM;
> +
> + return 0;
> +}
> +
> +static const struct backlight_ops novatek_nt37801_bl_ops = {
> + .update_status = novatek_nt37801_bl_update_status,
> +};
> +
> +static struct backlight_device *
> +novatek_nt37801_create_backlight(struct mipi_dsi_device *dsi)
> +{
> + struct device *dev = &dsi->dev;
> + const struct backlight_properties props = {
> + .type = BACKLIGHT_RAW,
> + .brightness = 4095,
> + .max_brightness = 4095,
> + };
> +
> + return devm_backlight_device_register(dev, dev_name(dev), dev, dsi,
> + &novatek_nt37801_bl_ops, &props);
> +}
> +
> +static int novatek_nt37801_probe(struct mipi_dsi_device *dsi)
> +{
> + struct device *dev = &dsi->dev;
> + struct novatek_nt37801 *ctx;
> + int ret;
> +
> + ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
> + if (!ctx)
> + return -ENOMEM;
> +
> + ret = devm_regulator_bulk_get_const(dev,
> + ARRAY_SIZE(novatek_nt37801_supplies),
> + novatek_nt37801_supplies,
> + &ctx->supplies);
> + if (ret < 0)
> + return ret;
> +
> + ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
> + 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;
> + mipi_dsi_set_drvdata(dsi, ctx);
> +
> + dsi->lanes = 4;
> + dsi->format = MIPI_DSI_FMT_RGB888;
> + dsi->mode_flags = MIPI_DSI_MODE_NO_EOT_PACKET | MIPI_DSI_CLOCK_NON_CONTINUOUS;
> +
> + drm_panel_init(&ctx->panel, dev, &novatek_nt37801_panel_funcs,
> + DRM_MODE_CONNECTOR_DSI);
Please switch to devm_drm_panel_alloc()
> + ctx->panel.prepare_prev_first = true;
> +
> + ctx->panel.backlight = novatek_nt37801_create_backlight(dsi);
> + 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);
> +
> + /* This panel only supports DSC; unconditionally enable it */
> + dsi->dsc = &ctx->dsc;
> + ctx->dsc.dsc_version_major = 1;
> + ctx->dsc.dsc_version_minor = 1;
> + ctx->dsc.slice_height = 40;
> + ctx->dsc.slice_width = 720;
> + ctx->dsc.slice_count = 1440 / ctx->dsc.slice_width;
> + ctx->dsc.bits_per_component = 8;
> + ctx->dsc.bits_per_pixel = 8 << 4; /* 4 fractional bits */
> + ctx->dsc.block_pred_enable = true;
> +
> + ret = mipi_dsi_attach(dsi);
> + if (ret < 0) {
> + drm_panel_remove(&ctx->panel);
> + return dev_err_probe(dev, ret, "Failed to attach to DSI host\n");
> + }
> +
> + return 0;
> +}
> +
> +static void novatek_nt37801_remove(struct mipi_dsi_device *dsi)
> +{
> + struct novatek_nt37801 *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 novatek_nt37801_of_match[] = {
> + { .compatible = "novatek,nt37801" },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, novatek_nt37801_of_match);
> +
> +static struct mipi_dsi_driver novatek_nt37801_driver = {
> + .probe = novatek_nt37801_probe,
> + .remove = novatek_nt37801_remove,
> + .driver = {
> + .name = "panel-novatek-nt37801",
> + .of_match_table = novatek_nt37801_of_match,
> + },
> +};
> +module_mipi_dsi_driver(novatek_nt37801_driver);
> +
> +MODULE_AUTHOR("Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>");
> +MODULE_DESCRIPTION("Panel driver for the Novatek NT37801/NT37810 AMOLED DSI panel");
> +MODULE_LICENSE("GPL");
>
With that fixed:
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] drm/panel: Add Novatek NT37801 panel driver
2025-05-05 13:58 ` Neil Armstrong
@ 2025-05-05 15:14 ` Krzysztof Kozlowski
0 siblings, 0 replies; 8+ messages in thread
From: Krzysztof Kozlowski @ 2025-05-05 15:14 UTC (permalink / raw)
To: Neil Armstrong, Krzysztof Kozlowski, Jessica Zhang, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Conor Dooley
Cc: dri-devel, devicetree, linux-kernel
On 05/05/2025 15:58, Neil Armstrong wrote:
>> + dsi->lanes = 4;
>> + dsi->format = MIPI_DSI_FMT_RGB888;
>> + dsi->mode_flags = MIPI_DSI_MODE_NO_EOT_PACKET | MIPI_DSI_CLOCK_NON_CONTINUOUS;
>> +
>> + drm_panel_init(&ctx->panel, dev, &novatek_nt37801_panel_funcs,
>> + DRM_MODE_CONNECTOR_DSI);
>
> Please switch to devm_drm_panel_alloc()
Ack
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/2] dt-bindings: display: panel: Add Novatek NT37801
2025-05-05 9:16 ` [PATCH 1/2] dt-bindings: display: panel: Add Novatek NT37801 Krzysztof Kozlowski
@ 2025-05-08 12:41 ` Linus Walleij
0 siblings, 0 replies; 8+ messages in thread
From: Linus Walleij @ 2025-05-08 12:41 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Krzysztof Kozlowski, Neil Armstrong, Jessica Zhang, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Conor Dooley, dri-devel,
devicetree, linux-kernel
On Mon, May 5, 2025 at 11:16 AM Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
> Add bindings for the Novatek NT37801 or NT37810 AMOLED DSI panel.
> Sources, like downstream DTS, schematics and hardware manuals, use two
> model names (NT37801 and NT37810), so choose one and hope it is correct.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] drm/panel: Add Novatek NT37801 panel driver
2025-05-05 9:16 ` [PATCH 2/2] drm/panel: Add Novatek NT37801 panel driver Krzysztof Kozlowski
2025-05-05 13:58 ` Neil Armstrong
@ 2025-05-08 12:54 ` Linus Walleij
2025-05-08 13:54 ` Krzysztof Kozlowski
1 sibling, 1 reply; 8+ messages in thread
From: Linus Walleij @ 2025-05-08 12:54 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Krzysztof Kozlowski, Neil Armstrong, Jessica Zhang, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Conor Dooley, dri-devel,
devicetree, linux-kernel
Hi Krzysztof,
thanks for your patch!
On Mon, May 5, 2025 at 11:16 AM Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
> Add driver for the Novatek NT37801 or NT37810 AMOLED DSI 1440x3200
> panel in CMD mode, used on Qualcomm MTP8750 board (SM8750).
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
(...)
> +static int novatek_nt37801_on(struct novatek_nt37801 *ctx)
> +{
> + struct mipi_dsi_device *dsi = ctx->dsi;
> + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi };
> +
> + dsi->mode_flags |= MIPI_DSI_MODE_LPM;
> +
> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0,
> + 0x55, 0xaa, 0x52, 0x08, 0x01);
The above is obviously some kind of unlocking
sequence to open page 1 of some vendor registers.
We know this because the exact same sequence appear in
panel-innolux-p079zca.c and panel-sony-tulip-truly-nt35521.c
and the last argument is the page, so there we added
a switch page macro making it clear what is going on.
Could you do the same here?
With this addressed:
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] drm/panel: Add Novatek NT37801 panel driver
2025-05-08 12:54 ` Linus Walleij
@ 2025-05-08 13:54 ` Krzysztof Kozlowski
0 siblings, 0 replies; 8+ messages in thread
From: Krzysztof Kozlowski @ 2025-05-08 13:54 UTC (permalink / raw)
To: Linus Walleij
Cc: Krzysztof Kozlowski, Neil Armstrong, Jessica Zhang, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Conor Dooley, dri-devel,
devicetree, linux-kernel
On 08/05/2025 14:54, Linus Walleij wrote:
> (...)
>> +static int novatek_nt37801_on(struct novatek_nt37801 *ctx)
>> +{
>> + struct mipi_dsi_device *dsi = ctx->dsi;
>> + struct mipi_dsi_multi_context dsi_ctx = { .dsi = dsi };
>> +
>> + dsi->mode_flags |= MIPI_DSI_MODE_LPM;
>> +
>> + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, 0xf0,
>> + 0x55, 0xaa, 0x52, 0x08, 0x01);
>
> The above is obviously some kind of unlocking
> sequence to open page 1 of some vendor registers.
>
> We know this because the exact same sequence appear in
> panel-innolux-p079zca.c and panel-sony-tulip-truly-nt35521.c
> and the last argument is the page, so there we added
> a switch page macro making it clear what is going on.
> Could you do the same here?
I don't have docs and this is auto-generated panel driver based on
downstream DTS, but sure, I can prepare something similar based on above
assumption.
>
> With this addressed:
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
>
> Yours,
> Linus Walleij
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-05-08 13:54 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-05 9:16 [PATCH 0/2] drm/panel: Add Novatek NT37801 panel driver Krzysztof Kozlowski
2025-05-05 9:16 ` [PATCH 1/2] dt-bindings: display: panel: Add Novatek NT37801 Krzysztof Kozlowski
2025-05-08 12:41 ` Linus Walleij
2025-05-05 9:16 ` [PATCH 2/2] drm/panel: Add Novatek NT37801 panel driver Krzysztof Kozlowski
2025-05-05 13:58 ` Neil Armstrong
2025-05-05 15:14 ` Krzysztof Kozlowski
2025-05-08 12:54 ` Linus Walleij
2025-05-08 13:54 ` Krzysztof Kozlowski
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).