[PATCH 0/5] Add support for PinePhone LCD panel

121 views
Skip to first unread message

Icenowy Zheng

unread,
Mar 11, 2020, 12:29:58 PM3/11/20
to Thierry Reding, Sam Ravnborg, Rob Herring, Maxime Ripard, Chen-Yu Tsai, Ondrej Jirman, dri-...@lists.freedesktop.org, devic...@vger.kernel.org, linux-...@vger.kernel.org, linux-ar...@lists.infradead.org, linux...@googlegroups.com, Icenowy Zheng
This patchset adds support for the LCD panel of PinePhone.

The first 3 patches are for the panel itself, and the last 2 patches are
for enabling it on PinePhone.

PATCH 4 is the fix of a bug in sun6i_mipi_dsi which will gets triggered
on XBD599.

Icenowy Zheng (5):
dt-bindings: vendor-prefixes: Add Xingbangda
dt-bindings: panel: add binding for Xingbangda XBD599 panel
drm: panel: add Xingbangda XBD599 panel
drm/sun4i: sun6i_mipi_dsi: fix horizontal timing calculation
arm64: allwinner: dts: a64: add LCD-related device nodes for PinePhone

.../display/panel/xingbangda,xbd599.yaml | 50 +++
.../devicetree/bindings/vendor-prefixes.yaml | 2 +
.../dts/allwinner/sun50i-a64-pinephone.dtsi | 37 ++
drivers/gpu/drm/panel/Kconfig | 9 +
drivers/gpu/drm/panel/Makefile | 1 +
.../gpu/drm/panel/panel-xingbangda-xbd599.c | 367 ++++++++++++++++++
drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 10 +-
7 files changed, 471 insertions(+), 5 deletions(-)
create mode 100644 Documentation/devicetree/bindings/display/panel/xingbangda,xbd599.yaml
create mode 100644 drivers/gpu/drm/panel/panel-xingbangda-xbd599.c

--
2.24.1

Icenowy Zheng

unread,
Mar 11, 2020, 12:33:46 PM3/11/20
to Thierry Reding, Sam Ravnborg, Rob Herring, Maxime Ripard, Chen-Yu Tsai, Ondrej Jirman, dri-...@lists.freedesktop.org, devic...@vger.kernel.org, linux-...@vger.kernel.org, linux-ar...@lists.infradead.org, linux...@googlegroups.com, Icenowy Zheng

Icenowy Zheng

unread,
Mar 11, 2020, 12:33:53 PM3/11/20
to Thierry Reding, Sam Ravnborg, Rob Herring, Maxime Ripard, Chen-Yu Tsai, Ondrej Jirman, dri-...@lists.freedesktop.org, devic...@vger.kernel.org, linux-...@vger.kernel.org, linux-ar...@lists.infradead.org, linux...@googlegroups.com, Icenowy Zheng
Shenzhen Xingbangda Display Technology Co., Ltd is a company which
produces LCD modules. It supplies the LCD panels of the PinePhone series
(the developers' kit and the final phone).

Add the vendor prefix of it.

Signed-off-by: Icenowy Zheng <ice...@aosc.io>
---
Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index b8e9ef79cab9..038a2180d34b 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1102,6 +1102,8 @@ patternProperties:
description: Xiaomi Technology Co., Ltd.
"^xillybus,.*":
description: Xillybus Ltd.
+ "^xingbangda,.*":
+ description: Shenzhen Xingbangda Display Technology Co., Ltd
"^xinpeng,.*":
description: Shenzhen Xinpeng Technology Co., Ltd
"^xlnx,.*":
--
2.24.1

Icenowy Zheng

unread,
Mar 11, 2020, 12:34:10 PM3/11/20
to Thierry Reding, Sam Ravnborg, Rob Herring, Maxime Ripard, Chen-Yu Tsai, Ondrej Jirman, dri-...@lists.freedesktop.org, devic...@vger.kernel.org, linux-...@vger.kernel.org, linux-ar...@lists.infradead.org, linux...@googlegroups.com, Icenowy Zheng
Xingbangda XBD599 is a 5.99" 720x1440 MIPI-DSI LCD panel.

Add its device tree binding.

Signed-off-by: Icenowy Zheng <ice...@aosc.io>
---
.../display/panel/xingbangda,xbd599.yaml | 50 +++++++++++++++++++
1 file changed, 50 insertions(+)
create mode 100644 Documentation/devicetree/bindings/display/panel/xingbangda,xbd599.yaml

diff --git a/Documentation/devicetree/bindings/display/panel/xingbangda,xbd599.yaml b/Documentation/devicetree/bindings/display/panel/xingbangda,xbd599.yaml
new file mode 100644
index 000000000000..62816b34de31
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/xingbangda,xbd599.yaml
@@ -0,0 +1,50 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/xingbangda,xbd599.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Xingbangda XBD599 5.99in MIPI-DSI LCD panel
+
+maintainers:
+ - Icenowy Zheng <ice...@aosc.io>
+
+allOf:
+ - $ref: panel-common.yaml#
+
+properties:
+ compatible:
+ const: xingbangda,xbd599
+ reg: true
+ backlight: true
+ reset-gpios: true
+ vcc-supply:
+ description: regulator that supplies the VCC voltage
+ iovcc-supply:
+ description: regulator that supplies the IOVCC voltage
+
+required:
+ - compatible
+ - reg
+ - backlight
+ - vcc-supply
+ - iovcc-supply
+
+additionalProperties: false
+
+examples:
+ - |
+ &dsi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ panel@0 {
+ compatible = "xingbangda,xbd599";
+ reg = <0>;
+ backlight = <&backlight>;
+ iovcc-supply = <&reg_dldo2>;
+ vcc-supply = <&reg_ldo_io0>;
+ };
+ };
+
+...
--
2.24.1

Icenowy Zheng

unread,
Mar 11, 2020, 12:34:17 PM3/11/20
to Thierry Reding, Sam Ravnborg, Rob Herring, Maxime Ripard, Chen-Yu Tsai, Ondrej Jirman, dri-...@lists.freedesktop.org, devic...@vger.kernel.org, linux-...@vger.kernel.org, linux-ar...@lists.infradead.org, linux...@googlegroups.com, Icenowy Zheng
Xingbangda XBD599 is a 5.99" 720x1440 MIPI-DSI IPS LCD panel made by
Xingbangda, which is used on PinePhone final assembled phones.

Add support for it.

Signed-off-by: Icenowy Zheng <ice...@aosc.io>
---
drivers/gpu/drm/panel/Kconfig | 9 +
drivers/gpu/drm/panel/Makefile | 1 +
.../gpu/drm/panel/panel-xingbangda-xbd599.c | 367 ++++++++++++++++++
3 files changed, 377 insertions(+)
create mode 100644 drivers/gpu/drm/panel/panel-xingbangda-xbd599.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index da3b84602cdd..d648f40469c7 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -413,6 +413,15 @@ config DRM_PANEL_TRULY_NT35597_WQXGA
Say Y here if you want to enable support for Truly NT35597 WQXGA Dual DSI
Video Mode panel

+config DRM_PANEL_XINGBANGDA_XBD599
+ tristate "Xingbangda XBD599 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 the Xingbangda XBD599
+ MIPI DSI Video Mode panel.
+
config DRM_PANEL_XINPENG_XPP055C272
tristate "Xinpeng XPP055C272 panel driver"
depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index af1e2a3cc5fc..d9645f079e59 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -44,4 +44,5 @@ obj-$(CONFIG_DRM_PANEL_TPO_TD028TTEC1) += panel-tpo-td028ttec1.o
obj-$(CONFIG_DRM_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
obj-$(CONFIG_DRM_PANEL_TPO_TPG110) += panel-tpo-tpg110.o
obj-$(CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA) += panel-truly-nt35597.o
+obj-$(CONFIG_DRM_PANEL_XINGBANGDA_XBD599) += panel-xingbangda-xbd599.o
obj-$(CONFIG_DRM_PANEL_XINPENG_XPP055C272) += panel-xinpeng-xpp055c272.o
diff --git a/drivers/gpu/drm/panel/panel-xingbangda-xbd599.c b/drivers/gpu/drm/panel/panel-xingbangda-xbd599.c
new file mode 100644
index 000000000000..68a5d8bb7f26
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-xingbangda-xbd599.c
@@ -0,0 +1,367 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xingbangda XBD599 MIPI-DSI panel driver
+ *
+ * Copyright (C) 2019 Icenowy Zheng <ice...@aosc.io>
+ *
+ * Based on panel-rocktech-jh057n00900.c, which is:
+ * Copyright (C) Purism SPC 2019
+ */
+
+#include <linux/gpio/consumer.h>
+#include <linux/delay.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/regulator/consumer.h>
+
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_print.h>
+
+#define DRV_NAME "panel-xingbangda-xbd599"
+
+/* Manufacturer specific Commands send via DSI */
+#define ST7703_CMD_ALL_PIXEL_OFF 0x22
+#define ST7703_CMD_ALL_PIXEL_ON 0x23
+#define ST7703_CMD_SETDISP 0xB2
+#define ST7703_CMD_SETRGBIF 0xB3
+#define ST7703_CMD_SETCYC 0xB4
+#define ST7703_CMD_SETBGP 0xB5
+#define ST7703_CMD_SETVCOM 0xB6
+#define ST7703_CMD_SETOTP 0xB7
+#define ST7703_CMD_SETPOWER_EXT 0xB8
+#define ST7703_CMD_SETEXTC 0xB9
+#define ST7703_CMD_SETMIPI 0xBA
+#define ST7703_CMD_SETVDC 0xBC
+#define ST7703_CMD_SETSCR 0xC0
+#define ST7703_CMD_SETPOWER 0xC1
+#define ST7703_CMD_UNK_C6 0xC6
+#define ST7703_CMD_SETPANEL 0xCC
+#define ST7703_CMD_SETGAMMA 0xE0
+#define ST7703_CMD_SETEQ 0xE3
+#define ST7703_CMD_SETGIP1 0xE9
+#define ST7703_CMD_SETGIP2 0xEA
+
+static const char * const regulator_names[] = {
+ "iovcc",
+ "vcc",
+};
+
+struct xbd599 {
+ struct device *dev;
+ struct drm_panel panel;
+ struct gpio_desc *reset_gpio;
+ struct regulator_bulk_data supplies[ARRAY_SIZE(regulator_names)];
+ bool prepared;
+};
+
+static inline struct xbd599 *panel_to_xbd599(struct drm_panel *panel)
+{
+ return container_of(panel, struct xbd599, panel);
+}
+
+#define dsi_dcs_write_seq(dsi, cmd, seq...) do { \
+ static const u8 d[] = { seq }; \
+ int ret; \
+ ret = mipi_dsi_dcs_write(dsi, cmd, d, ARRAY_SIZE(d)); \
+ if (ret < 0) \
+ return ret; \
+ } while (0)
+
+static int xbd599_init_sequence(struct xbd599 *ctx)
+{
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+ struct device *dev = ctx->dev;
+ int ret;
+
+ /*
+ * Init sequence was supplied by the panel vendor.
+ */
+ dsi_dcs_write_seq(dsi, ST7703_CMD_SETEXTC,
+ 0xF1, 0x12, 0x83);
+ dsi_dcs_write_seq(dsi, ST7703_CMD_SETMIPI,
+ 0x33, 0x81, 0x05, 0xF9, 0x0E, 0x0E, 0x20, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x25,
+ 0x00, 0x91, 0x0a, 0x00, 0x00, 0x02, 0x4F, 0x11,
+ 0x00, 0x00, 0x37);
+ dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER_EXT,
+ 0x25, 0x22, 0x20, 0x03);
+ dsi_dcs_write_seq(dsi, ST7703_CMD_SETRGBIF,
+ 0x10, 0x10, 0x05, 0x05, 0x03, 0xFF, 0x00, 0x00,
+ 0x00, 0x00);
+ dsi_dcs_write_seq(dsi, ST7703_CMD_SETSCR,
+ 0x73, 0x73, 0x50, 0x50, 0x00, 0xC0, 0x08, 0x70,
+ 0x00);
+ dsi_dcs_write_seq(dsi, ST7703_CMD_SETVDC, 0x4E);
+ dsi_dcs_write_seq(dsi, ST7703_CMD_SETPANEL, 0x0B);
+ dsi_dcs_write_seq(dsi, ST7703_CMD_SETCYC, 0x80);
+ dsi_dcs_write_seq(dsi, ST7703_CMD_SETDISP, 0xF0, 0x12, 0xF0);
+ dsi_dcs_write_seq(dsi, ST7703_CMD_SETEQ,
+ 0x00, 0x00, 0x0B, 0x0B, 0x10, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0xFF, 0x00, 0xC0, 0x10);
+ dsi_dcs_write_seq(dsi, 0xC6, 0x01, 0x00, 0xFF, 0xFF, 0x00);
+ dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER,
+ 0x74, 0x00, 0x32, 0x32, 0x77, 0xF1, 0xFF, 0xFF,
+ 0xCC, 0xCC, 0x77, 0x77);
+ dsi_dcs_write_seq(dsi, ST7703_CMD_SETBGP, 0x07, 0x07);
+ dsi_dcs_write_seq(dsi, ST7703_CMD_SETVCOM, 0x2C, 0x2C);
+ dsi_dcs_write_seq(dsi, 0xBF, 0x02, 0x11, 0x00);
+
+ dsi_dcs_write_seq(dsi, ST7703_CMD_SETGIP1,
+ 0x82, 0x10, 0x06, 0x05, 0xA2, 0x0A, 0xA5, 0x12,
+ 0x31, 0x23, 0x37, 0x83, 0x04, 0xBC, 0x27, 0x38,
+ 0x0C, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x75, 0x75, 0x31, 0x88,
+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x13, 0x88, 0x64,
+ 0x64, 0x20, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+ 0x02, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+ dsi_dcs_write_seq(dsi, ST7703_CMD_SETGIP2,
+ 0x02, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x46, 0x02, 0x88,
+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x64, 0x88, 0x13,
+ 0x57, 0x13, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+ 0x75, 0x88, 0x23, 0x14, 0x00, 0x00, 0x02, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00 ,0x00, 0x00, 0x00, 0x03, 0x0A,
+ 0xA5, 0x00, 0x00, 0x00, 0x00);
+ dsi_dcs_write_seq(dsi, ST7703_CMD_SETGAMMA,
+ 0x00, 0x09, 0x0D, 0x23, 0x27, 0x3C, 0x41, 0x35,
+ 0x07, 0x0D, 0x0E, 0x12, 0x13, 0x10, 0x12, 0x12,
+ 0x18, 0x00, 0x09, 0x0D, 0x23, 0x27, 0x3C, 0x41,
+ 0x35, 0x07, 0x0D, 0x0E, 0x12, 0x13, 0x10, 0x12,
+ 0x12, 0x18);
+ msleep(20);
+
+ ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
+ if (ret < 0) {
+ DRM_DEV_ERROR(dev, "Failed to exit sleep mode\n");
+ return ret;
+ }
+ msleep(250);
+
+ ret = mipi_dsi_dcs_set_display_on(dsi);
+ if (ret)
+ return ret;
+ msleep(50);
+
+ DRM_DEV_DEBUG_DRIVER(dev, "Panel init sequence done\n");
+ return 0;
+}
+
+static int xbd599_disable(struct drm_panel *panel)
+{
+ struct xbd599 *ctx = panel_to_xbd599(panel);
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+
+ return mipi_dsi_dcs_set_display_off(dsi);
+}
+
+static int xbd599_unprepare(struct drm_panel *panel)
+{
+ struct xbd599 *ctx = panel_to_xbd599(panel);
+
+ if (!ctx->prepared)
+ return 0;
+
+ regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+ ctx->prepared = false;
+
+ return 0;
+}
+
+static int xbd599_enable(struct drm_panel *panel)
+{
+ struct xbd599 *ctx = panel_to_xbd599(panel);
+ int ret;
+
+ ret = xbd599_init_sequence(ctx);
+ if (ret < 0) {
+ DRM_DEV_ERROR(ctx->dev, "Panel init sequence failed: %d\n",
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int xbd599_prepare(struct drm_panel *panel)
+{
+ struct xbd599 *ctx = panel_to_xbd599(panel);
+ int ret;
+
+ if (ctx->prepared)
+ return 0;
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+ if (ret)
+ return ret;
+
+ DRM_DEV_DEBUG_DRIVER(ctx->dev, "Resetting the panel\n");
+ gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+ usleep_range(20, 40);
+ gpiod_set_value_cansleep(ctx->reset_gpio, 0);
+ msleep(20);
+
+ ctx->prepared = true;
+
+ return 0;
+}
+
+static const struct drm_display_mode xbd599_default_mode = {
+ .hdisplay = 720,
+ .hsync_start = 720 + 40,
+ .hsync_end = 720 + 40 + 40,
+ .htotal = 720 + 40 + 40 + 40,
+ .vdisplay = 1440,
+ .vsync_start = 1440 + 18,
+ .vsync_end = 1440 + 18 + 10,
+ .vtotal = 1440 + 18 + 10 + 17,
+ .vrefresh = 60,
+ .clock = 69000,
+ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
+
+ .width_mm = 68,
+ .height_mm = 136,
+ .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
+};
+
+static int xbd599_get_modes(struct drm_panel *panel,
+ struct drm_connector *connector)
+{
+ struct xbd599 *ctx = panel_to_xbd599(panel);
+ struct drm_display_mode *mode;
+
+ mode = drm_mode_duplicate(connector->dev, &xbd599_default_mode);
+ if (!mode) {
+ DRM_DEV_ERROR(ctx->dev, "Failed to add mode\n");
+ return -ENOMEM;
+ }
+
+ drm_mode_set_name(mode);
+
+ mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+ connector->display_info.width_mm = mode->width_mm;
+ connector->display_info.height_mm = mode->height_mm;
+ drm_mode_probed_add(connector, mode);
+
+ return 1;
+}
+
+static const struct drm_panel_funcs xbd599_drm_funcs = {
+ .disable = xbd599_disable,
+ .unprepare = xbd599_unprepare,
+ .enable = xbd599_enable,
+ .prepare = xbd599_prepare,
+ .get_modes = xbd599_get_modes,
+};
+
+static int xbd599_probe(struct mipi_dsi_device *dsi)
+{
+ struct device *dev = &dsi->dev;
+ struct xbd599 *ctx;
+ int i, ret;
+
+ ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ for (i = 0; i < ARRAY_SIZE(ctx->supplies); i++)
+ ctx->supplies[i].supply = regulator_names[i];
+
+ ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies),
+ ctx->supplies);
+ if (ret < 0) {
+ DRM_DEV_ERROR(&dsi->dev, "cannot get regulators\n");
+ return ret;
+ }
+
+ ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(ctx->reset_gpio)) {
+ DRM_DEV_ERROR(dev, "cannot get reset gpio\n");
+ return PTR_ERR(ctx->reset_gpio);
+ }
+
+ mipi_dsi_set_drvdata(dsi, ctx);
+
+ ctx->dev = dev;
+
+ dsi->lanes = 4;
+ dsi->format = MIPI_DSI_FMT_RGB888;
+ dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
+
+ drm_panel_init(&ctx->panel, &dsi->dev, &xbd599_drm_funcs,
+ DRM_MODE_CONNECTOR_DSI);
+
+ ret = drm_panel_of_backlight(&ctx->panel);
+ if (ret)
+ return ret;
+
+ drm_panel_add(&ctx->panel);
+
+ ret = mipi_dsi_attach(dsi);
+ if (ret < 0) {
+ DRM_DEV_ERROR(dev, "mipi_dsi_attach failed. Is host ready?\n");
+ drm_panel_remove(&ctx->panel);
+ return ret;
+ }
+
+ DRM_DEV_INFO(dev, "%ux%u@%u %ubpp dsi %udl - ready\n",
+ xbd599_default_mode.hdisplay,
+ xbd599_default_mode.vdisplay,
+ xbd599_default_mode.vrefresh,
+ mipi_dsi_pixel_format_to_bpp(dsi->format), dsi->lanes);
+
+ return 0;
+}
+
+static void xbd599_shutdown(struct mipi_dsi_device *dsi)
+{
+ struct xbd599 *ctx = mipi_dsi_get_drvdata(dsi);
+ int ret;
+
+ ret = xbd599_unprepare(&ctx->panel);
+ if (ret < 0)
+ DRM_DEV_ERROR(&dsi->dev, "Failed to unprepare panel: %d\n",
+ ret);
+}
+
+static int xbd599_remove(struct mipi_dsi_device *dsi)
+{
+ struct xbd599 *ctx = mipi_dsi_get_drvdata(dsi);
+ int ret;
+
+ xbd599_shutdown(dsi);
+
+ ret = mipi_dsi_detach(dsi);
+ if (ret < 0)
+ DRM_DEV_ERROR(&dsi->dev, "Failed to detach from DSI host: %d\n",
+ ret);
+
+ drm_panel_remove(&ctx->panel);
+
+ return 0;
+}
+
+static const struct of_device_id xbd599_of_match[] = {
+ { .compatible = "xingbangda,xbd599", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, xbd599_of_match);
+
+static struct mipi_dsi_driver xbd599_driver = {
+ .probe = xbd599_probe,
+ .remove = xbd599_remove,
+ .shutdown = xbd599_shutdown,
+ .driver = {
+ .name = DRV_NAME,
+ .of_match_table = xbd599_of_match,
+ },
+};
+module_mipi_dsi_driver(xbd599_driver);
+
+MODULE_AUTHOR("Icenowy Zheng <ice...@aosc.io>");
+MODULE_DESCRIPTION("DRM driver for Xingbangda XBD599 MIPI DSI panel");
+MODULE_LICENSE("GPL v2");
--
2.24.1

Icenowy Zheng

unread,
Mar 11, 2020, 12:34:38 PM3/11/20
to Thierry Reding, Sam Ravnborg, Rob Herring, Maxime Ripard, Chen-Yu Tsai, Ondrej Jirman, dri-...@lists.freedesktop.org, devic...@vger.kernel.org, linux-...@vger.kernel.org, linux-ar...@lists.infradead.org, linux...@googlegroups.com, Icenowy Zheng
The max() function call in horizontal timing calculation shouldn't pad a
length already subtracted with overhead to overhead, instead it should
only prevent the set timing to underflow.

Signed-off-by: Icenowy Zheng <ice...@aosc.io>
---
drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
index 059939789730..5f2313c40328 100644
--- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
+++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
@@ -555,7 +555,7 @@ static void sun6i_dsi_setup_timings(struct sun6i_dsi *dsi,
*/
#define HSA_PACKET_OVERHEAD 10
hsa = max((unsigned int)HSA_PACKET_OVERHEAD,
- (mode->hsync_end - mode->hsync_start) * Bpp - HSA_PACKET_OVERHEAD);
+ (mode->hsync_end - mode->hsync_start) * Bpp) - HSA_PACKET_OVERHEAD;

/*
* The backporch is set using a blanking packet (4
@@ -564,7 +564,7 @@ static void sun6i_dsi_setup_timings(struct sun6i_dsi *dsi,
*/
#define HBP_PACKET_OVERHEAD 6
hbp = max((unsigned int)HBP_PACKET_OVERHEAD,
- (mode->htotal - mode->hsync_end) * Bpp - HBP_PACKET_OVERHEAD);
+ (mode->htotal - mode->hsync_end) * Bpp) - HBP_PACKET_OVERHEAD;

/*
* The frontporch is set using a sync event (4 bytes)
@@ -574,7 +574,7 @@ static void sun6i_dsi_setup_timings(struct sun6i_dsi *dsi,
*/
#define HFP_PACKET_OVERHEAD 16
hfp = max((unsigned int)HFP_PACKET_OVERHEAD,
- (mode->hsync_start - mode->hdisplay) * Bpp - HFP_PACKET_OVERHEAD);
+ (mode->hsync_start - mode->hdisplay) * Bpp) - HFP_PACKET_OVERHEAD;

/*
* The blanking is set using a sync event (4 bytes)
@@ -583,8 +583,8 @@ static void sun6i_dsi_setup_timings(struct sun6i_dsi *dsi,
*/
#define HBLK_PACKET_OVERHEAD 10
hblk = max((unsigned int)HBLK_PACKET_OVERHEAD,
- (mode->htotal - (mode->hsync_end - mode->hsync_start)) * Bpp -
- HBLK_PACKET_OVERHEAD);
+ (mode->htotal - (mode->hsync_end - mode->hsync_start)) * Bpp) -
+ HBLK_PACKET_OVERHEAD;

/*
* And I'm not entirely sure what vblk is about. The driver in
--
2.24.1

Icenowy Zheng

unread,
Mar 11, 2020, 12:35:04 PM3/11/20
to Thierry Reding, Sam Ravnborg, Rob Herring, Maxime Ripard, Chen-Yu Tsai, Ondrej Jirman, dri-...@lists.freedesktop.org, devic...@vger.kernel.org, linux-...@vger.kernel.org, linux-ar...@lists.infradead.org, linux...@googlegroups.com, Icenowy Zheng
PinePhone uses PWM backlight and a XBD599 LCD panel over DSI for
display.

Add its device nodes.

Signed-off-by: Icenowy Zheng <ice...@aosc.io>
---
.../dts/allwinner/sun50i-a64-pinephone.dtsi | 37 +++++++++++++++++++
1 file changed, 37 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
index cefda145c3c9..96d9150423e0 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
@@ -16,6 +16,15 @@ aliases {
serial0 = &uart0;
};

+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&r_pwm 0 50000 PWM_POLARITY_INVERTED>;
+ brightness-levels = <0 16 18 20 22 24 26 29 32 35 38 42 46 51 56 62 68 75 83 91 100>;
+ default-brightness-level = <15>;
+ enable-gpios = <&pio 7 10 GPIO_ACTIVE_HIGH>; /* PH10 */
+ power-supply = <&reg_ldo_io0>;
+ };
+
chosen {
stdout-path = "serial0:115200n8";
};
@@ -84,6 +93,30 @@ &dai {
status = "okay";
};

+&de {
+ status = "okay";
+};
+
+&dphy {
+ status = "okay";
+};
+
+&dsi {
+ vcc-dsi-supply = <&reg_dldo1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ panel@0 {
+ compatible = "xingbangda,xbd599";
+ reg = <0>;
+ reset-gpios = <&pio 3 23 GPIO_ACTIVE_LOW>; /* PD23 */
+ iovcc-supply = <&reg_dldo2>;
+ vcc-supply = <&reg_ldo_io0>;
+ backlight = <&backlight>;
+ };
+};
+
&ehci0 {
status = "okay";
};
@@ -188,6 +221,10 @@ &r_pio {
*/
};

+&r_pwm {
+ status = "okay";
+};
+
&r_rsb {
status = "okay";

--
2.24.1

Rob Herring

unread,
Mar 12, 2020, 11:45:22 AM3/12/20
to Icenowy Zheng, Thierry Reding, Sam Ravnborg, Chen-Yu Tsai, Ondrej Jirman, dri-...@lists.freedesktop.org, devic...@vger.kernel.org, linux-...@vger.kernel.org, linux-ar...@lists.infradead.org, linux...@googlegroups.com, Icenowy Zheng
On Thu, 12 Mar 2020 00:33:26 +0800, Icenowy Zheng wrote:
> Xingbangda XBD599 is a 5.99" 720x1440 MIPI-DSI LCD panel.
>
> Add its device tree binding.
>
> Signed-off-by: Icenowy Zheng <ice...@aosc.io>
> ---
> .../display/panel/xingbangda,xbd599.yaml | 50 +++++++++++++++++++
> 1 file changed, 50 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/display/panel/xingbangda,xbd599.yaml
>

My bot found errors running 'make dt_binding_check' on your patch:

Error: Documentation/devicetree/bindings/display/panel/xingbangda,xbd599.example.dts:17.1-5 syntax error
FATAL ERROR: Unable to parse input tree
scripts/Makefile.lib:311: recipe for target 'Documentation/devicetree/bindings/display/panel/xingbangda,xbd599.example.dt.yaml' failed
make[1]: *** [Documentation/devicetree/bindings/display/panel/xingbangda,xbd599.example.dt.yaml] Error 1
make[1]: *** Waiting for unfinished jobs....
Makefile:1262: recipe for target 'dt_binding_check' failed
make: *** [dt_binding_check] Error 2

See https://patchwork.ozlabs.org/patch/1253057
Please check and re-submit.

Icenowy Zheng

unread,
Mar 14, 2020, 4:04:11 AM3/14/20
to Sam Ravnborg, Thierry Reding, Rob Herring, Maxime Ripard, Chen-Yu Tsai, Ondrej Jirman, dri-...@lists.freedesktop.org, devic...@vger.kernel.org, linux-...@vger.kernel.org, linux-ar...@lists.infradead.org, linux...@googlegroups.com


于 2020年3月14日 GMT+08:00 下午4:00:00, Sam Ravnborg <s...@ravnborg.org> 写到:
>Hi Icenowy
>
>A few details in the following.
>
> Sam
>
>On Thu, Mar 12, 2020 at 12:33:27AM +0800, Icenowy Zheng wrote:
>> Xingbangda XBD599 is a 5.99" 720x1440 MIPI-DSI IPS LCD panel made by
>> Xingbangda, which is used on PinePhone final assembled phones.
>>
>> Add support for it.
>>
>> Signed-off-by: Icenowy Zheng <ice...@aosc.io>
>> ---
>> drivers/gpu/drm/panel/Kconfig | 9 +
>> drivers/gpu/drm/panel/Makefile | 1 +
>> .../gpu/drm/panel/panel-xingbangda-xbd599.c | 367
>++++++++++++++++++
>> 3 files changed, 377 insertions(+)
>> create mode 100644 drivers/gpu/drm/panel/panel-xingbangda-xbd599.c
>>
>> +++ b/drivers/gpu/drm/panel/panel-xingbangda-xbd599.c
>> @@ -0,0 +1,367 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Xingbangda XBD599 MIPI-DSI panel driver
>> + *
>> + * Copyright (C) 2019 Icenowy Zheng <ice...@aosc.io>
>2020?

The work started at Mid 2019.

Is 2019-2020 okay?

>
>> + *
>> + * Based on panel-rocktech-jh057n00900.c, which is:
>> + * Copyright (C) Purism SPC 2019
>> + */
>> +
>> +#include <linux/gpio/consumer.h>
>> +#include <linux/delay.h>
>> +#include <linux/mod_devicetable.h>
>> +#include <linux/module.h>
>> +#include <linux/of_device.h>
>> +#include <linux/regulator/consumer.h>
>Sort alphabetically.
>
>> +
>> +#include <drm/drm_mipi_dsi.h>
>> +#include <drm/drm_modes.h>
>> +#include <drm/drm_panel.h>
>> +#include <drm/drm_print.h>
>> +
>> +#define DRV_NAME "panel-xingbangda-xbd599"
>No reason for this indirection, it is only used once
>The following is the same for many panels but anyway.
>
>The init order for a display is
>
> prepare
> enable
>
> # Display is now fully operational
>
> disable
> unprepare
>
> # display is now off and turned off (no power)
>
>So when reading panel drivers my personal preference is to read the
>functions in that order - this makes it easier to follow the sequence.
>
>Thats just my personal opinion - so feel free to ignore.
>
>> +
>> +static int xbd599_unprepare(struct drm_panel *panel)
>> +{
>> + struct xbd599 *ctx = panel_to_xbd599(panel);
>> +
>> + if (!ctx->prepared)
>> + return 0;
>> +
>> + regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
>> + ctx->prepared = false;
>> +
>> + return 0;
>> +}
>Maybe activate reset before power is turned off.
>So when power is turned on again later the panel is kept in reset.
>
>This would also make this a closer mirror of what is done in prepare()
>Use drm_panel_unprepare().
>There may be, or may come functionality in drm_panel that is required.
--
使用 K-9 Mail 发送自我的Android设备。

Icenowy Zheng

unread,
Mar 16, 2020, 9:35:42 AM3/16/20
to Thierry Reding, Sam Ravnborg, Rob Herring, Maxime Ripard, Chen-Yu Tsai, Ondrej Jirman, dri-...@lists.freedesktop.org, devic...@vger.kernel.org, linux-...@vger.kernel.org, linux-ar...@lists.infradead.org, linux...@googlegroups.com, Icenowy Zheng
This patchset adds support for the LCD panel of PinePhone.

The first 3 patches are for the panel itself, and the last 2 patches are
for enabling it on PinePhone.

PATCH 4 is the fix of a bug in sun6i_mipi_dsi which will gets triggered
on XBD599.

Icenowy Zheng (5):
dt-bindings: vendor-prefixes: Add Xingbangda
dt-bindings: panel: add binding for Xingbangda XBD599 panel
drm: panel: add Xingbangda XBD599 panel
drm/sun4i: sun6i_mipi_dsi: fix horizontal timing calculation
arm64: allwinner: dts: a64: add LCD-related device nodes for PinePhone

.../display/panel/xingbangda,xbd599.yaml | 50 +++
.../devicetree/bindings/vendor-prefixes.yaml | 2 +
.../dts/allwinner/sun50i-a64-pinephone.dtsi | 37 ++
drivers/gpu/drm/panel/Kconfig | 9 +
drivers/gpu/drm/panel/Makefile | 1 +
.../gpu/drm/panel/panel-xingbangda-xbd599.c | 366 ++++++++++++++++++
drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 10 +-
7 files changed, 470 insertions(+), 5 deletions(-)

Icenowy Zheng

unread,
Mar 16, 2020, 9:36:05 AM3/16/20
to Thierry Reding, Sam Ravnborg, Rob Herring, Maxime Ripard, Chen-Yu Tsai, Ondrej Jirman, dri-...@lists.freedesktop.org, devic...@vger.kernel.org, linux-...@vger.kernel.org, linux-ar...@lists.infradead.org, linux...@googlegroups.com, Icenowy Zheng
Shenzhen Xingbangda Display Technology Co., Ltd is a company which
produces LCD modules. It supplies the LCD panels of the PinePhone series
(the developers' kit and the final phone).

Add the vendor prefix of it.

Signed-off-by: Icenowy Zheng <ice...@aosc.io>
---
No changes in v2.

Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 23ca95bee298..0d9e966eff19 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1106,6 +1106,8 @@ patternProperties:

Icenowy Zheng

unread,
Mar 16, 2020, 9:37:25 AM3/16/20
to Thierry Reding, Sam Ravnborg, Rob Herring, Maxime Ripard, Chen-Yu Tsai, Ondrej Jirman, dri-...@lists.freedesktop.org, devic...@vger.kernel.org, linux-...@vger.kernel.org, linux-ar...@lists.infradead.org, linux...@googlegroups.com, Icenowy Zheng
Xingbangda XBD599 is a 5.99" 720x1440 MIPI-DSI LCD panel.

Add its device tree binding.

Signed-off-by: Icenowy Zheng <ice...@aosc.io>
---
Changes in v2:
- Example fix.
- Format fix.

.../display/panel/xingbangda,xbd599.yaml | 50 +++++++++++++++++++
1 file changed, 50 insertions(+)
create mode 100644 Documentation/devicetree/bindings/display/panel/xingbangda,xbd599.yaml

diff --git a/Documentation/devicetree/bindings/display/panel/xingbangda,xbd599.yaml b/Documentation/devicetree/bindings/display/panel/xingbangda,xbd599.yaml
new file mode 100644
index 000000000000..b27bcf11198f
+ dsi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ panel@0 {
+ compatible = "xingbangda,xbd599";
+ reg = <0>;
+ backlight = <&backlight>;
+ iovcc-supply = <&reg_dldo2>;
+ vcc-supply = <&reg_ldo_io0>;

Icenowy Zheng

unread,
Mar 16, 2020, 9:37:42 AM3/16/20
to Thierry Reding, Sam Ravnborg, Rob Herring, Maxime Ripard, Chen-Yu Tsai, Ondrej Jirman, dri-...@lists.freedesktop.org, devic...@vger.kernel.org, linux-...@vger.kernel.org, linux-ar...@lists.infradead.org, linux...@googlegroups.com, Icenowy Zheng
Xingbangda XBD599 is a 5.99" 720x1440 MIPI-DSI IPS LCD panel made by
Xingbangda, which is used on PinePhone final assembled phones.

Add support for it.

Signed-off-by: Icenowy Zheng <ice...@aosc.io>
---
Changes in v2:
- Raised copyright info to 2020.
- Sort panel operation functions.
- Sort inclusion.

drivers/gpu/drm/panel/Kconfig | 9 +
drivers/gpu/drm/panel/Makefile | 1 +
.../gpu/drm/panel/panel-xingbangda-xbd599.c | 366 ++++++++++++++++++
3 files changed, 376 insertions(+)
create mode 100644 drivers/gpu/drm/panel/panel-xingbangda-xbd599.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index a1723c1b5fbf..cf0c59015a44 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -433,6 +433,15 @@ config DRM_PANEL_TRULY_NT35597_WQXGA
Say Y here if you want to enable support for Truly NT35597 WQXGA Dual DSI
Video Mode panel

+config DRM_PANEL_XINGBANGDA_XBD599
+ tristate "Xingbangda XBD599 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 the Xingbangda XBD599
+ MIPI DSI Video Mode panel.
+
config DRM_PANEL_XINPENG_XPP055C272
tristate "Xinpeng XPP055C272 panel driver"
depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 96a883cd6630..c84ed5215984 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -46,4 +46,5 @@ obj-$(CONFIG_DRM_PANEL_TPO_TD028TTEC1) += panel-tpo-td028ttec1.o
obj-$(CONFIG_DRM_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
obj-$(CONFIG_DRM_PANEL_TPO_TPG110) += panel-tpo-tpg110.o
obj-$(CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA) += panel-truly-nt35597.o
+obj-$(CONFIG_DRM_PANEL_XINGBANGDA_XBD599) += panel-xingbangda-xbd599.o
obj-$(CONFIG_DRM_PANEL_XINPENG_XPP055C272) += panel-xinpeng-xpp055c272.o
diff --git a/drivers/gpu/drm/panel/panel-xingbangda-xbd599.c b/drivers/gpu/drm/panel/panel-xingbangda-xbd599.c
new file mode 100644
index 000000000000..8d56b6579111
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-xingbangda-xbd599.c
@@ -0,0 +1,366 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xingbangda XBD599 MIPI-DSI panel driver
+ *
+ * Copyright (C) 2019-2020 Icenowy Zheng <ice...@aosc.io>
+ *
+ * Based on panel-rocktech-jh057n00900.c, which is:
+ * Copyright (C) Purism SPC 2019
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/regulator/consumer.h>
+
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_print.h>
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0A,
+static int xbd599_disable(struct drm_panel *panel)
+{
+ struct xbd599 *ctx = panel_to_xbd599(panel);
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+
+ return mipi_dsi_dcs_set_display_off(dsi);
+}
+
+static int xbd599_unprepare(struct drm_panel *panel)
+{
+ struct xbd599 *ctx = panel_to_xbd599(panel);
+
+ if (!ctx->prepared)
+ return 0;
+
+ gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+ regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+ ctx->prepared = false;
+
+ return 0;
+}
+ .prepare = xbd599_prepare,
+ .enable = xbd599_enable,
+ .disable = xbd599_disable,
+ .unprepare = xbd599_unprepare,
+ ret = drm_panel_unprepare(&ctx->panel);
+ .name = "panel-xingbangda-xbd599",

Icenowy Zheng

unread,
Mar 16, 2020, 9:37:59 AM3/16/20
to Thierry Reding, Sam Ravnborg, Rob Herring, Maxime Ripard, Chen-Yu Tsai, Ondrej Jirman, dri-...@lists.freedesktop.org, devic...@vger.kernel.org, linux-...@vger.kernel.org, linux-ar...@lists.infradead.org, linux...@googlegroups.com, Icenowy Zheng
The max() function call in horizontal timing calculation shouldn't pad a
length already subtracted with overhead to overhead, instead it should
only prevent the set timing to underflow.

Signed-off-by: Icenowy Zheng <ice...@aosc.io>
---
No changes in v2.

Icenowy Zheng

unread,
Mar 16, 2020, 9:38:13 AM3/16/20
to Thierry Reding, Sam Ravnborg, Rob Herring, Maxime Ripard, Chen-Yu Tsai, Ondrej Jirman, dri-...@lists.freedesktop.org, devic...@vger.kernel.org, linux-...@vger.kernel.org, linux-ar...@lists.infradead.org, linux...@googlegroups.com, Icenowy Zheng
PinePhone uses PWM backlight and a XBD599 LCD panel over DSI for
display.

Add its device nodes.

Signed-off-by: Icenowy Zheng <ice...@aosc.io>
---
No changes in v2.

+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ panel@0 {
+ compatible = "xingbangda,xbd599";
+ reg = <0>;
+ reset-gpios = <&pio 3 23 GPIO_ACTIVE_LOW>; /* PD23 */
+ iovcc-supply = <&reg_dldo2>;
+ vcc-supply = <&reg_ldo_io0>;

Ondřej Jirman

unread,
Mar 16, 2020, 3:11:25 PM3/16/20
to Icenowy Zheng, Thierry Reding, Sam Ravnborg, Rob Herring, Maxime Ripard, Chen-Yu Tsai, dri-...@lists.freedesktop.org, devic...@vger.kernel.org, linux-...@vger.kernel.org, linux-ar...@lists.infradead.org, linux...@googlegroups.com
Hello Icenowy,

On Mon, Mar 16, 2020 at 09:35:01PM +0800, Icenowy Zheng wrote:
> Xingbangda XBD599 is a 5.99" 720x1440 MIPI-DSI IPS LCD panel made by
> Xingbangda, which is used on PinePhone final assembled phones.
>
> [snip]
>
> +static const struct drm_display_mode xbd599_default_mode = {
> + .hdisplay = 720,
> + .hsync_start = 720 + 40,
> + .hsync_end = 720 + 40 + 40,
> + .htotal = 720 + 40 + 40 + 40,
> + .vdisplay = 1440,
> + .vsync_start = 1440 + 18,
> + .vsync_end = 1440 + 18 + 10,
> + .vtotal = 1440 + 18 + 10 + 17,
> + .vrefresh = 60,

Does the display actually run for you at 60fps? I measured 36.63 FPS with
a DRM app that just does DRM_IOCTL_MODE_ATOMIC update after each
DRM_EVENT_FLIP_COMPLETE event.

thank you and regards,
o.

Linus Walleij

unread,
Mar 19, 2020, 10:09:03 AM3/19/20
to Icenowy Zheng, Thierry Reding, Sam Ravnborg, Rob Herring, Maxime Ripard, Chen-Yu Tsai, Ondrej Jirman, open list:DRM PANEL DRIVERS, open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS, linux-...@vger.kernel.org, Linux ARM, linux-sunxi
Hi Icenowy!

Thanks for your patch.

On Mon, Mar 16, 2020 at 2:37 PM Icenowy Zheng <ice...@aosc.io> wrote:

> Xingbangda XBD599 is a 5.99" 720x1440 MIPI-DSI IPS LCD panel made by
> Xingbangda, which is used on PinePhone final assembled phones.
>
> Add support for it.
>
> Signed-off-by: Icenowy Zheng <ice...@aosc.io>
(...)

> +/* Manufacturer specific Commands send via DSI */
> +#define ST7703_CMD_ALL_PIXEL_OFF 0x22
> +#define ST7703_CMD_ALL_PIXEL_ON 0x23
> +#define ST7703_CMD_SETDISP 0xB2
> +#define ST7703_CMD_SETRGBIF 0xB3
> +#define ST7703_CMD_SETCYC 0xB4
> +#define ST7703_CMD_SETBGP 0xB5
> +#define ST7703_CMD_SETVCOM 0xB6
> +#define ST7703_CMD_SETOTP 0xB7
> +#define ST7703_CMD_SETPOWER_EXT 0xB8
> +#define ST7703_CMD_SETEXTC 0xB9
> +#define ST7703_CMD_SETMIPI 0xBA
> +#define ST7703_CMD_SETVDC 0xBC
> +#define ST7703_CMD_SETSCR 0xC0
> +#define ST7703_CMD_SETPOWER 0xC1
> +#define ST7703_CMD_UNK_C6 0xC6
> +#define ST7703_CMD_SETPANEL 0xCC
> +#define ST7703_CMD_SETGAMMA 0xE0
> +#define ST7703_CMD_SETEQ 0xE3
> +#define ST7703_CMD_SETGIP1 0xE9
> +#define ST7703_CMD_SETGIP2 0xEA

It appears that the Himax HX8363 is using the same display controller
if you look at the datasheet:
http://www.datasheet-pdf.com/PDF/HX8369-A-Datasheet-Himax-729024
There you find an explanation to some of the commands.

People are trying to add support for this panel too:
https://discuss.96boards.org/t/adding-support-to-himax-hx8363-panel/9068

The set-up values etc for the Himax display will be widely
different because it is using the same display controller
for a display of 480x800(854) pixels.

You should definately insert code to read the MTP bytes:
0xDA manufacturer
0xDB driver version
0xDC LCD module/driver
And print these, se e.g. my newly added NT35510 driver or
the Sony ACX424AKP driver.

Nobody seems to have any documentation of these MTP
ID bytes but they are certainly consistent among
e.g Ilitek or Novatek display drivers.

I do not think that either Xingbangda or Himax have made
this display controller. The number of advanced display
controller vendors in the world is actually pretty limited.
Ilitek, Novatek or TPO make most of them.

It is a bit of a problem for the development world that
display manufacturers hide the details of which display
controller they actually use, because we can't have
2 different drivers for the same display controller just
because Himax and Xingbada package it up with
their own branding.

This actually looks very much like an Ilitek display controller.
Some commands are clearly identical to Ilitek ILI9342:
http://www.ampdisplay.com/documents/pdf/ILI9342_DS_V008_20100331.pdf

I would:

1. Try to determine what the actual display controller
is. I think it is some Ilitek.

2. Write a panel-ilitek-ili9342.c (if that is the actual controller)
and parameterize it for this display controller the same
way we do in e.g. panel-novatek-nt35510.c or
panel-ilitek-ili9322.c, so you use the compatible string
to set up the actual per-display settings for this display
controller.
Already just using the HX8363 datasheet you can turn this into
something much more readable akin to how the NT35510 driver
is done.

> +static const struct drm_display_mode xbd599_default_mode = {
> + .hdisplay = 720,
> + .hsync_start = 720 + 40,
> + .hsync_end = 720 + 40 + 40,
> + .htotal = 720 + 40 + 40 + 40,
> + .vdisplay = 1440,
> + .vsync_start = 1440 + 18,
> + .vsync_end = 1440 + 18 + 10,
> + .vtotal = 1440 + 18 + 10 + 17,
> + .vrefresh = 60,

I think this vrefresh is going away soon.

> + .clock = 69000,
> + .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
> +
> + .width_mm = 68,
> + .height_mm = 136,
> + .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
> +};

All of this as well as some of the initialization
sequences should be per-variant data. (Switched by
the compatible).

Yours,
Linus Walleij

Linus Walleij

unread,
Mar 19, 2020, 10:14:41 AM3/19/20
to Icenowy Zheng, Thierry Reding, Sam Ravnborg, Rob Herring, Maxime Ripard, Chen-Yu Tsai, Ondrej Jirman, open list:DRM PANEL DRIVERS, open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS, linux-...@vger.kernel.org, Linux ARM, linux-sunxi
Hi Icenowy,

On Mon, Mar 16, 2020 at 2:37 PM Icenowy Zheng <ice...@aosc.io> wrote:

> Xingbangda XBD599 is a 5.99" 720x1440 MIPI-DSI LCD panel.
>
> Add its device tree binding.
>
> Signed-off-by: Icenowy Zheng <ice...@aosc.io>
(...)

> +properties:
> + compatible:
> + const: xingbangda,xbd599

As noticed in the review of the driver, this display is very close to
himax,hx8363.

I think the best is to determin what actual display controller it is,
I think it is some kind of Ilitek controller since Ilitek ili9342 is
clearly very similar.

The best would be something like name the bindings
ilitek-ili9342.yaml and then:

properties:
compatible:
items:
- const: xingbangda,xbd599
- const: ilitek,ili9342

Possibly use oneOf and add support for the himax,hx8363
already while you're at it.

Yours,
Linus Walleij

Icenowy Zheng

unread,
Mar 19, 2020, 10:52:06 AM3/19/20
to Thierry Reding, Sam Ravnborg, Rob Herring, Maxime Ripard, Chen-Yu Tsai, Ondrej Jirman, dri-...@lists.freedesktop.org, devic...@vger.kernel.org, linux-...@vger.kernel.org, linux-ar...@lists.infradead.org, linux...@googlegroups.com
在 2020-03-16星期一的 21:35 +0800,Icenowy Zheng写道:
> PinePhone uses PWM backlight and a XBD599 LCD panel over DSI for
> display.
>
> Add its device nodes.
>
> Signed-off-by: Icenowy Zheng <ice...@aosc.io>
> ---
> No changes in v2.
>
> .../dts/allwinner/sun50i-a64-pinephone.dtsi | 37
> +++++++++++++++++++
> 1 file changed, 37 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> index cefda145c3c9..96d9150423e0 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> @@ -16,6 +16,15 @@ aliases {
> serial0 = &uart0;
> };
>
> + backlight: backlight {
> + compatible = "pwm-backlight";
> + pwms = <&r_pwm 0 50000 PWM_POLARITY_INVERTED>;
> + brightness-levels = <0 16 18 20 22 24 26 29 32 35 38 42
> 46 51 56 62 68 75 83 91 100>;

Should I drop the 0 here and replace it with 14?

I have heard community complaining about setting 0 to brightness make
the screen black.

(I think in this situation bl_power or blank the DSI panel can still
totally shut down the backlight).

Ondřej Jirman

unread,
Mar 19, 2020, 12:10:06 PM3/19/20
to Icenowy Zheng, Thierry Reding, Sam Ravnborg, Rob Herring, Maxime Ripard, Chen-Yu Tsai, dri-...@lists.freedesktop.org, devic...@vger.kernel.org, linux-...@vger.kernel.org, linux-ar...@lists.infradead.org, linux...@googlegroups.com
On Thu, Mar 19, 2020 at 10:51:36PM +0800, Icenowy Zheng wrote:
> 在 2020-03-16星期一的 21:35 +0800,Icenowy Zheng写道:
> > PinePhone uses PWM backlight and a XBD599 LCD panel over DSI for
> > display.
> >
> > Add its device nodes.
> >
> > Signed-off-by: Icenowy Zheng <ice...@aosc.io>
> > ---
> > No changes in v2.
> >
> > .../dts/allwinner/sun50i-a64-pinephone.dtsi | 37
> > +++++++++++++++++++
> > 1 file changed, 37 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> > b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> > index cefda145c3c9..96d9150423e0 100644
> > --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
> > @@ -16,6 +16,15 @@ aliases {
> > serial0 = &uart0;
> > };
> >
> > + backlight: backlight {
> > + compatible = "pwm-backlight";
> > + pwms = <&r_pwm 0 50000 PWM_POLARITY_INVERTED>;
> > + brightness-levels = <0 16 18 20 22 24 26 29 32 35 38 42
> > 46 51 56 62 68 75 83 91 100>;
>
> Should I drop the 0 here and replace it with 14?

Almost all boards in arm/boot/dts start at 0.

> I have heard community complaining about setting 0 to brightness make
> the screen black.

Level 0 (first value in the list) is special, and turns off the backlight:

123 if (brightness > 0) {
124 pwm_get_state(pb->pwm, &state);
125 state.duty_cycle = compute_duty_cycle(pb, brightness);
126 pwm_apply_state(pb->pwm, &state);
127 pwm_backlight_power_on(pb);
128 } else {
129 pwm_backlight_power_off(pb);
130 }

o.

Icenowy Zheng

unread,
Mar 20, 2020, 4:07:44 AM3/20/20
to linux-ar...@lists.infradead.org, Linus Walleij, Ondrej Jirman, open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS, linux-sunxi, linux-...@vger.kernel.org, Maxime Ripard, Rob Herring, Chen-Yu Tsai, Thierry Reding, open list:DRM PANEL DRIVERS, Sam Ravnborg, Linux ARM


于 2020年3月19日 GMT+08:00 下午10:14:27, Linus Walleij <linus....@linaro.org> 写到:
>Hi Icenowy,
>
>On Mon, Mar 16, 2020 at 2:37 PM Icenowy Zheng <ice...@aosc.io> wrote:
>
>> Xingbangda XBD599 is a 5.99" 720x1440 MIPI-DSI LCD panel.
>>
>> Add its device tree binding.
>>
>> Signed-off-by: Icenowy Zheng <ice...@aosc.io>
>(...)
>
>> +properties:
>> + compatible:
>> + const: xingbangda,xbd599
>
>As noticed in the review of the driver, this display is very close to
>himax,hx8363.
>
>I think the best is to determin what actual display controller it is,
>I think it is some kind of Ilitek controller since Ilitek ili9342 is
>clearly very similar.

It's Sitronix ST7703, same as the Librem 5 panel.

>
>The best would be something like name the bindings
>ilitek-ili9342.yaml and then:
>
>properties:
> compatible:
> items:
> - const: xingbangda,xbd599
> - const: ilitek,ili9342
>
>Possibly use oneOf and add support for the himax,hx8363
>already while you're at it.
>
>Yours,
>Linus Walleij
>
>_______________________________________________
>linux-arm-kernel mailing list
>linux-ar...@lists.infradead.org
>http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Linus Walleij

unread,
Mar 20, 2020, 5:11:38 AM3/20/20
to Icenowy Zheng, Jagan Teki, Linux ARM, Ondrej Jirman, open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS, linux-sunxi, linux-...@vger.kernel.org, Maxime Ripard, Rob Herring, Chen-Yu Tsai, Thierry Reding, open list:DRM PANEL DRIVERS, Sam Ravnborg
On Fri, Mar 20, 2020 at 9:07 AM Icenowy Zheng <ice...@aosc.io> wrote:
> 于 2020年3月19日 GMT+08:00 下午10:14:27, Linus Walleij <linus....@linaro.org> 写到:
> >On Mon, Mar 16, 2020 at 2:37 PM Icenowy Zheng <ice...@aosc.io> wrote:

> >As noticed in the review of the driver, this display is very close to
> >himax,hx8363.
> >
> >I think the best is to determin what actual display controller it is,
> >I think it is some kind of Ilitek controller since Ilitek ili9342 is
> >clearly very similar.
>
> It's Sitronix ST7703, same as the Librem 5 panel.

Heh, I wonder how it comes that it is so similar to Ilitek.
I guess I will never understand how the silicon ecosystem works
in asia (I did read a lot of Bunnie Huang's articles and hardware
hacking book to try to understand...)

This file should be named sitronix,st7703.yaml then.

According to the code in the Librem 5:
https://source.puri.sm/Librem5/linux-next/blob/imx8-current-librem5/drivers/gpu/drm/panel/panel-sitronix-st7701.c
The actual name of the display is Techstar ts8550b.
And the display controller is st7701, so maybe we should
actually name it sitronix,st770x.yaml if there are some
sub-variants of st770x?

> >properties:
> > compatible:
> > items:
> > - const: xingbangda,xbd599
> > - const: ilitek,ili9342
> >
> >Possibly use oneOf and add support for the himax,hx8363
> >already while you're at it.

This should at least be:

compatible:
items:
- enum:
- xingbangda,xbd599
- himax,hx8363
- techstar,ts8550b
- enum:
- sitronix,st7701
- sitronix,st7703

So panel nodes using this panel become
compatible = "xingbangda,sbd599", "sitronix,st7703"
etc.

This way it is straight-forward for drivers to identify the panel
vendor and display controller.

Yours,
Linus Walleij

Linus Walleij

unread,
Mar 20, 2020, 5:18:47 AM3/20/20
to Icenowy Zheng, Jagan Teki, Thierry Reding, Sam Ravnborg, Rob Herring, Maxime Ripard, Chen-Yu Tsai, Ondrej Jirman, open list:DRM PANEL DRIVERS, open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS, linux-...@vger.kernel.org, Linux ARM, linux-sunxi
So following up on this:

We should state in the commit message that this driver is for all
displays using the Sitronix ST770x display controllers.
The driver should be named panel-sitronix-st770x.c.

On Thu, Mar 19, 2020 at 3:08 PM Linus Walleij <linus....@linaro.org> wrote:

> > +/* Manufacturer specific Commands send via DSI */
> > +#define ST7703_CMD_ALL_PIXEL_OFF 0x22
> > +#define ST7703_CMD_ALL_PIXEL_ON 0x23
> > +#define ST7703_CMD_SETDISP 0xB2
> > +#define ST7703_CMD_SETRGBIF 0xB3
> > +#define ST7703_CMD_SETCYC 0xB4
> > +#define ST7703_CMD_SETBGP 0xB5
> > +#define ST7703_CMD_SETVCOM 0xB6
> > +#define ST7703_CMD_SETOTP 0xB7
> > +#define ST7703_CMD_SETPOWER_EXT 0xB8
> > +#define ST7703_CMD_SETEXTC 0xB9
> > +#define ST7703_CMD_SETMIPI 0xBA
> > +#define ST7703_CMD_SETVDC 0xBC
> > +#define ST7703_CMD_SETSCR 0xC0
> > +#define ST7703_CMD_SETPOWER 0xC1
> > +#define ST7703_CMD_UNK_C6 0xC6
> > +#define ST7703_CMD_SETPANEL 0xCC
> > +#define ST7703_CMD_SETGAMMA 0xE0
> > +#define ST7703_CMD_SETEQ 0xE3
> > +#define ST7703_CMD_SETGIP1 0xE9
> > +#define ST7703_CMD_SETGIP2 0xEA

I should have seen the ST7703 prefix shouldn't I...

> This actually looks very much like an Ilitek display controller.
> Some commands are clearly identical to Ilitek ILI9342:
> http://www.ampdisplay.com/documents/pdf/ILI9342_DS_V008_20100331.pdf

I'm still wondering about the apparent similarity between
ST770x and Ilitek ILI9342, haha :D

> 1. Try to determine what the actual display controller
> is. I think it is some Ilitek.

OK so this is Sitronix ST770x.

> 2. Write a panel-ilitek-ili9342.c (if that is the actual controller)
> and parameterize it for this display controller the same
> way we do in e.g. panel-novatek-nt35510.c or
> panel-ilitek-ili9322.c, so you use the compatible string
> to set up the actual per-display settings for this display
> controller.

This should be panel-sitronix-st770x.c

Yours,
Linus Walleij

Icenowy Zheng

unread,
Mar 20, 2020, 5:21:54 AM3/20/20
to linux-ar...@lists.infradead.org, Linus Walleij, Jagan Teki, Ondrej Jirman, open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS, linux-...@vger.kernel.org, Maxime Ripard, linux-sunxi, Rob Herring, Thierry Reding, open list:DRM PANEL DRIVERS, Chen-Yu Tsai, Sam Ravnborg, Linux ARM


于 2020年3月20日 GMT+08:00 下午5:11:22, Linus Walleij <linus....@linaro.org> 写到:
>On Fri, Mar 20, 2020 at 9:07 AM Icenowy Zheng <ice...@aosc.io> wrote:
>> 于 2020年3月19日 GMT+08:00 下午10:14:27, Linus Walleij
><linus....@linaro.org> 写到:
>> >On Mon, Mar 16, 2020 at 2:37 PM Icenowy Zheng <ice...@aosc.io>
>wrote:
>
>> >As noticed in the review of the driver, this display is very close
>to
>> >himax,hx8363.
>> >
>> >I think the best is to determin what actual display controller it
>is,
>> >I think it is some kind of Ilitek controller since Ilitek ili9342 is
>> >clearly very similar.
>>
>> It's Sitronix ST7703, same as the Librem 5 panel.
>
>Heh, I wonder how it comes that it is so similar to Ilitek.
>I guess I will never understand how the silicon ecosystem works
>in asia (I did read a lot of Bunnie Huang's articles and hardware
>hacking book to try to understand...)
>
>This file should be named sitronix,st7703.yaml then.
>
>According to the code in the Librem 5:
>https://source.puri.sm/Librem5/linux-next/blob/imx8-current-librem5/drivers/gpu/drm/panel/panel-sitronix-st7701.c
>The actual name of the display is Techstar ts8550b.

Sorry, for Librem 5 panel, I mean Rocktech JH057N00900 here.

This is also the code that my patchset based on.
Reply all
Reply to author
Forward
0 new messages