Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save macromorgan/2e4cb2e1b0cb06ba34102aef0cd66011 to your computer and use it in GitHub Desktop.
Save macromorgan/2e4cb2e1b0cb06ba34102aef0cd66011 to your computer and use it in GitHub Desktop.
DSI Panel Patches for RK3566 Based Anbernic Devices
From b13013b1ab34b8eda4c78c1d63d29211cb6af03d Mon Sep 17 00:00:00 2001
From: Chris Morgan <macromorgan@hotmail.com>
Date: Tue, 30 Aug 2022 12:32:43 -0500
Subject: [PATCH] drm: Add Panel Drivers for ams495qa01 and RG353P
Do not upstream. I haven't confirmed the part number yet for the
RG353P panel and I haven't added gamma yet for the Samsung panel.
Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
---
drivers/gpu/drm/panel/Kconfig | 18 +
drivers/gpu/drm/panel/Makefile | 2 +
drivers/gpu/drm/panel/panel-anbernic-rg353.c | 485 ++++++++++++++++++
.../gpu/drm/panel/panel-samsung-ams495qa01.c | 318 ++++++++++++
4 files changed, 823 insertions(+)
create mode 100644 drivers/gpu/drm/panel/panel-anbernic-rg353.c
create mode 100644 drivers/gpu/drm/panel/panel-samsung-ams495qa01.c
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index a9043eacce97..297f604a2945 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -17,6 +17,14 @@ config DRM_PANEL_ABT_Y030XX067A
Y030XX067A 320x480 3.0" panel as found in the YLM RG-280M, RG-300
and RG-99 handheld gaming consoles.
+config DRM_PANEL_ANBERNIC_RG353
+ tristate "Anbernic RG353 panel driver"
+ depends on OF
+ depends on DRM_MIPI_DSI
+ depends on BACKLIGHT_CLASS_DEVICE
+ help
+ This driver supports the panel on the Anbernic RG353.
+
config DRM_PANEL_ARM_VERSATILE
tristate "ARM Versatile panel driver"
depends on OF
@@ -444,6 +452,16 @@ config DRM_PANEL_RONBO_RB070D30
Say Y here if you want to enable support for Ronbo Electronics
RB070D30 1024x600 DSI panel.
+config DRM_PANEL_SAMSUNG_AMS495QA01
+ tristate "Samsung AMS495QA01 DSI panel"
+ depends on OF && SPI
+ depends on DRM_MIPI_DSI
+ select DRM_MIPI_DBI
+ help
+ DRM panel driver for the Samsung AMS495QA01 panel. This panel
+ receives video data via DSI but commands via 3-Wire 9-bit
+ SPI.
+
config DRM_PANEL_SAMSUNG_ATNA33XC20
tristate "Samsung ATNA33XC20 eDP panel"
depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 34e717382dbb..d8ba23537ab2 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_DRM_PANEL_ABT_Y030XX067A) += panel-abt-y030xx067a.o
+obj-$(CONFIG_DRM_PANEL_ANBERNIC_RG353) += panel-anbernic-rg353.o
obj-$(CONFIG_DRM_PANEL_ARM_VERSATILE) += panel-arm-versatile.o
obj-$(CONFIG_DRM_PANEL_ASUS_Z00T_TM5P5_NT35596) += panel-asus-z00t-tm5p5-n35596.o
obj-$(CONFIG_DRM_PANEL_BOE_BF060Y8M_AJ0) += panel-boe-bf060y8m-aj0.o
@@ -42,6 +43,7 @@ obj-$(CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN) += panel-raspberrypi-touchscreen
obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM67191) += panel-raydium-rm67191.o
obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM68200) += panel-raydium-rm68200.o
obj-$(CONFIG_DRM_PANEL_RONBO_RB070D30) += panel-ronbo-rb070d30.o
+obj-$(CONFIG_DRM_PANEL_SAMSUNG_AMS495QA01) += panel-samsung-ams495qa01.o
obj-$(CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20) += panel-samsung-atna33xc20.o
obj-$(CONFIG_DRM_PANEL_SAMSUNG_DB7430) += panel-samsung-db7430.o
obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o
diff --git a/drivers/gpu/drm/panel/panel-anbernic-rg353.c b/drivers/gpu/drm/panel/panel-anbernic-rg353.c
new file mode 100644
index 000000000000..999f6766f436
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-anbernic-rg353.c
@@ -0,0 +1,485 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Anbernic RG353 MIPI-DSI panel driver
+ * Copyright (C) 2022 Chris Morgan
+ *
+ * based on
+ *
+ * Elida kd35t133 3.5" MIPI-DSI panel driver
+ * Copyright (C) Theobroma Systems 2020
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/media-bus-format.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regulator/consumer.h>
+
+#include <video/display_timing.h>
+#include <video/mipi_display.h>
+
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_panel.h>
+
+struct panel_rg353 {
+ struct device *dev;
+ struct drm_panel panel;
+ struct gpio_desc *reset_gpio;
+ struct regulator *vdd;
+ enum drm_panel_orientation orientation;
+ bool prepared;
+};
+
+static inline struct panel_rg353 *panel_to_panelrg353(struct drm_panel *panel)
+{
+ return container_of(panel, struct panel_rg353, panel);
+}
+
+#define dsi_dcs_write_seq(dsi, cmd, seq...) do { \
+ static const u8 b[] = { cmd, seq }; \
+ int ret; \
+ ret = mipi_dsi_dcs_write_buffer(dsi, b, ARRAY_SIZE(b)); \
+ if (ret < 0) \
+ return ret; \
+ } while (0)
+
+static int panel_rg353_init_sequence(struct panel_rg353 *ctx)
+{
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+
+ /*
+ * Init sequence was supplied by device vendor with no
+ * documentation.
+ */
+
+ dsi_dcs_write_seq(dsi, 0xFF, 0x30);
+ dsi_dcs_write_seq(dsi, 0xFF, 0x52);
+ dsi_dcs_write_seq(dsi, 0xFF, 0x01);
+ dsi_dcs_write_seq(dsi, 0xE3, 0x00);
+ dsi_dcs_write_seq(dsi, 0x03, 0x40);
+ dsi_dcs_write_seq(dsi, 0x04, 0x00);
+ dsi_dcs_write_seq(dsi, 0x05, 0x03);
+ dsi_dcs_write_seq(dsi, 0x24, 0x12);
+ dsi_dcs_write_seq(dsi, 0x25, 0x1E);
+ dsi_dcs_write_seq(dsi, 0x26, 0x28);
+ dsi_dcs_write_seq(dsi, 0x27, 0x52);
+ dsi_dcs_write_seq(dsi, 0x28, 0x57);
+ dsi_dcs_write_seq(dsi, 0x29, 0x01);
+ dsi_dcs_write_seq(dsi, 0x2A, 0xDF);
+ dsi_dcs_write_seq(dsi, 0x38, 0x9C);
+ dsi_dcs_write_seq(dsi, 0x39, 0xA7);
+ dsi_dcs_write_seq(dsi, 0x3A, 0x53);
+ dsi_dcs_write_seq(dsi, 0x44, 0x00);
+ dsi_dcs_write_seq(dsi, 0x49, 0x3C);
+ dsi_dcs_write_seq(dsi, 0x59, 0xFE);
+ dsi_dcs_write_seq(dsi, 0x5C, 0x00);
+ dsi_dcs_write_seq(dsi, 0x91, 0x77);
+ dsi_dcs_write_seq(dsi, 0x92, 0x77);
+ dsi_dcs_write_seq(dsi, 0xA0, 0x55);
+ dsi_dcs_write_seq(dsi, 0xA1, 0x50);
+ dsi_dcs_write_seq(dsi, 0xA4, 0x9C);
+ dsi_dcs_write_seq(dsi, 0xA7, 0x02);
+ dsi_dcs_write_seq(dsi, 0xA8, 0x01);
+ dsi_dcs_write_seq(dsi, 0xA9, 0x01);
+ dsi_dcs_write_seq(dsi, 0xAA, 0xFC);
+ dsi_dcs_write_seq(dsi, 0xAB, 0x28);
+ dsi_dcs_write_seq(dsi, 0xAC, 0x06);
+ dsi_dcs_write_seq(dsi, 0xAD, 0x06);
+ dsi_dcs_write_seq(dsi, 0xAE, 0x06);
+ dsi_dcs_write_seq(dsi, 0xAF, 0x03);
+ dsi_dcs_write_seq(dsi, 0xB0, 0x08);
+ dsi_dcs_write_seq(dsi, 0xB1, 0x26);
+ dsi_dcs_write_seq(dsi, 0xB2, 0x28);
+ dsi_dcs_write_seq(dsi, 0xB3, 0x28);
+ dsi_dcs_write_seq(dsi, 0xB4, 0x33);
+ dsi_dcs_write_seq(dsi, 0xB5, 0x08);
+ dsi_dcs_write_seq(dsi, 0xB6, 0x26);
+ dsi_dcs_write_seq(dsi, 0xB7, 0x08);
+ dsi_dcs_write_seq(dsi, 0xB8, 0x26);
+ dsi_dcs_write_seq(dsi, 0xFF, 0x30);
+ dsi_dcs_write_seq(dsi, 0xFF, 0x52);
+ dsi_dcs_write_seq(dsi, 0xFF, 0x02);
+ dsi_dcs_write_seq(dsi, 0xB1, 0x0E);
+ dsi_dcs_write_seq(dsi, 0xD1, 0x0E);
+ dsi_dcs_write_seq(dsi, 0xB4, 0x29);
+ dsi_dcs_write_seq(dsi, 0xD4, 0x2B);
+ dsi_dcs_write_seq(dsi, 0xB2, 0x0C);
+ dsi_dcs_write_seq(dsi, 0xD2, 0x0A);
+ dsi_dcs_write_seq(dsi, 0xB3, 0x28);
+ dsi_dcs_write_seq(dsi, 0xD3, 0x28);
+ dsi_dcs_write_seq(dsi, 0xB6, 0x11);
+ dsi_dcs_write_seq(dsi, 0xD6, 0x0D);
+ dsi_dcs_write_seq(dsi, 0xB7, 0x32);
+ dsi_dcs_write_seq(dsi, 0xD7, 0x30);
+ dsi_dcs_write_seq(dsi, 0xC1, 0x04);
+ dsi_dcs_write_seq(dsi, 0xE1, 0x06);
+ dsi_dcs_write_seq(dsi, 0xB8, 0x0A);
+ dsi_dcs_write_seq(dsi, 0xD8, 0x0A);
+ dsi_dcs_write_seq(dsi, 0xB9, 0x01);
+ dsi_dcs_write_seq(dsi, 0xD9, 0x01);
+ dsi_dcs_write_seq(dsi, 0xBD, 0x13);
+ dsi_dcs_write_seq(dsi, 0xDD, 0x13);
+ dsi_dcs_write_seq(dsi, 0xBC, 0x11);
+ dsi_dcs_write_seq(dsi, 0xDC, 0x11);
+ dsi_dcs_write_seq(dsi, 0xBB, 0x0F);
+ dsi_dcs_write_seq(dsi, 0xDB, 0x0F);
+ dsi_dcs_write_seq(dsi, 0xBA, 0x0F);
+ dsi_dcs_write_seq(dsi, 0xDA, 0x0F);
+ dsi_dcs_write_seq(dsi, 0xBE, 0x18);
+ dsi_dcs_write_seq(dsi, 0xDE, 0x18);
+ dsi_dcs_write_seq(dsi, 0xBF, 0x0F);
+ dsi_dcs_write_seq(dsi, 0xDF, 0x0F);
+ dsi_dcs_write_seq(dsi, 0xC0, 0x17);
+ dsi_dcs_write_seq(dsi, 0xE0, 0x17);
+ dsi_dcs_write_seq(dsi, 0xB5, 0x3B);
+ dsi_dcs_write_seq(dsi, 0xD5, 0x3C);
+ dsi_dcs_write_seq(dsi, 0xB0, 0x0B);
+ dsi_dcs_write_seq(dsi, 0xD0, 0x0C);
+ dsi_dcs_write_seq(dsi, 0xFF, 0x30);
+ dsi_dcs_write_seq(dsi, 0xFF, 0x52);
+ dsi_dcs_write_seq(dsi, 0xFF, 0x03);
+ dsi_dcs_write_seq(dsi, 0x00, 0x2A);
+ dsi_dcs_write_seq(dsi, 0x01, 0x2A);
+ dsi_dcs_write_seq(dsi, 0x02, 0x2A);
+ dsi_dcs_write_seq(dsi, 0x03, 0x2A);
+ dsi_dcs_write_seq(dsi, 0x04, 0x61);
+ dsi_dcs_write_seq(dsi, 0x05, 0x80);
+ dsi_dcs_write_seq(dsi, 0x06, 0xC7);
+ dsi_dcs_write_seq(dsi, 0x07, 0x01);
+ dsi_dcs_write_seq(dsi, 0x08, 0x82);
+ dsi_dcs_write_seq(dsi, 0x09, 0x83);
+ dsi_dcs_write_seq(dsi, 0x30, 0x2A);
+ dsi_dcs_write_seq(dsi, 0x31, 0x2A);
+ dsi_dcs_write_seq(dsi, 0x32, 0x2A);
+ dsi_dcs_write_seq(dsi, 0x33, 0x2A);
+ dsi_dcs_write_seq(dsi, 0x34, 0x61);
+ dsi_dcs_write_seq(dsi, 0x35, 0xC5);
+ dsi_dcs_write_seq(dsi, 0x36, 0x80);
+ dsi_dcs_write_seq(dsi, 0x37, 0x23);
+ dsi_dcs_write_seq(dsi, 0x40, 0x82);
+ dsi_dcs_write_seq(dsi, 0x41, 0x83);
+ dsi_dcs_write_seq(dsi, 0x42, 0x80);
+ dsi_dcs_write_seq(dsi, 0x43, 0x81);
+ dsi_dcs_write_seq(dsi, 0x44, 0x11);
+ dsi_dcs_write_seq(dsi, 0x45, 0xF2);
+ dsi_dcs_write_seq(dsi, 0x46, 0xF1);
+ dsi_dcs_write_seq(dsi, 0x47, 0x11);
+ dsi_dcs_write_seq(dsi, 0x48, 0xF4);
+ dsi_dcs_write_seq(dsi, 0x49, 0xF3);
+ dsi_dcs_write_seq(dsi, 0x50, 0x02);
+ dsi_dcs_write_seq(dsi, 0x51, 0x01);
+ dsi_dcs_write_seq(dsi, 0x52, 0x04);
+ dsi_dcs_write_seq(dsi, 0x53, 0x03);
+ dsi_dcs_write_seq(dsi, 0x54, 0x11);
+ dsi_dcs_write_seq(dsi, 0x55, 0xF6);
+ dsi_dcs_write_seq(dsi, 0x56, 0xF5);
+ dsi_dcs_write_seq(dsi, 0x57, 0x11);
+ dsi_dcs_write_seq(dsi, 0x58, 0xF8);
+ dsi_dcs_write_seq(dsi, 0x59, 0xF7);
+ dsi_dcs_write_seq(dsi, 0x7E, 0x02);
+ dsi_dcs_write_seq(dsi, 0x7F, 0x80);
+ dsi_dcs_write_seq(dsi, 0xE0, 0x5A);
+ dsi_dcs_write_seq(dsi, 0xB1, 0x00);
+ dsi_dcs_write_seq(dsi, 0xB4, 0x0E);
+ dsi_dcs_write_seq(dsi, 0xB5, 0x0F);
+ dsi_dcs_write_seq(dsi, 0xB6, 0x04);
+ dsi_dcs_write_seq(dsi, 0xB7, 0x07);
+ dsi_dcs_write_seq(dsi, 0xB8, 0x06);
+ dsi_dcs_write_seq(dsi, 0xB9, 0x05);
+ dsi_dcs_write_seq(dsi, 0xBA, 0x0F);
+ dsi_dcs_write_seq(dsi, 0xC7, 0x00);
+ dsi_dcs_write_seq(dsi, 0xCA, 0x0E);
+ dsi_dcs_write_seq(dsi, 0xCB, 0x0F);
+ dsi_dcs_write_seq(dsi, 0xCC, 0x04);
+ dsi_dcs_write_seq(dsi, 0xCD, 0x07);
+ dsi_dcs_write_seq(dsi, 0xCE, 0x06);
+ dsi_dcs_write_seq(dsi, 0xCF, 0x05);
+ dsi_dcs_write_seq(dsi, 0xD0, 0x0F);
+ dsi_dcs_write_seq(dsi, 0x81, 0x0F);
+ dsi_dcs_write_seq(dsi, 0x84, 0x0E);
+ dsi_dcs_write_seq(dsi, 0x85, 0x0F);
+ dsi_dcs_write_seq(dsi, 0x86, 0x07);
+ dsi_dcs_write_seq(dsi, 0x87, 0x04);
+ dsi_dcs_write_seq(dsi, 0x88, 0x05);
+ dsi_dcs_write_seq(dsi, 0x89, 0x06);
+ dsi_dcs_write_seq(dsi, 0x8A, 0x00);
+ dsi_dcs_write_seq(dsi, 0x97, 0x0F);
+ dsi_dcs_write_seq(dsi, 0x9A, 0x0E);
+ dsi_dcs_write_seq(dsi, 0x9B, 0x0F);
+ dsi_dcs_write_seq(dsi, 0x9C, 0x07);
+ dsi_dcs_write_seq(dsi, 0x9D, 0x04);
+ dsi_dcs_write_seq(dsi, 0x9E, 0x05);
+ dsi_dcs_write_seq(dsi, 0x9F, 0x06);
+ dsi_dcs_write_seq(dsi, 0xA0, 0x00);
+ dsi_dcs_write_seq(dsi, 0xFF, 0x30);
+ dsi_dcs_write_seq(dsi, 0xFF, 0x52);
+ dsi_dcs_write_seq(dsi, 0xFF, 0x02);
+ dsi_dcs_write_seq(dsi, 0x01, 0x01);
+ dsi_dcs_write_seq(dsi, 0x02, 0xDA);
+ dsi_dcs_write_seq(dsi, 0x03, 0xBA);
+ dsi_dcs_write_seq(dsi, 0x04, 0xA8);
+ dsi_dcs_write_seq(dsi, 0x05, 0x9A);
+ dsi_dcs_write_seq(dsi, 0x06, 0x70);
+ dsi_dcs_write_seq(dsi, 0x07, 0xFF);
+ dsi_dcs_write_seq(dsi, 0x08, 0x91);
+ dsi_dcs_write_seq(dsi, 0x09, 0x90);
+ dsi_dcs_write_seq(dsi, 0x0A, 0xFF);
+ dsi_dcs_write_seq(dsi, 0x0B, 0x8F);
+ dsi_dcs_write_seq(dsi, 0x0C, 0x60);
+ dsi_dcs_write_seq(dsi, 0x0D, 0x58);
+ dsi_dcs_write_seq(dsi, 0x0E, 0x48);
+ dsi_dcs_write_seq(dsi, 0x0F, 0x38);
+ dsi_dcs_write_seq(dsi, 0x10, 0x2B);
+ dsi_dcs_write_seq(dsi, 0xFF, 0x30);
+ dsi_dcs_write_seq(dsi, 0xFF, 0x52);
+ dsi_dcs_write_seq(dsi, 0xFF, 0x00);
+ dsi_dcs_write_seq(dsi, 0x36, 0x02);
+ dsi_dcs_write_seq(dsi, 0x3A, 0x70);
+
+ dev_dbg(ctx->dev, "Panel init sequence done\n");
+
+ return 0;
+}
+
+static int panel_rg353_unprepare(struct drm_panel *panel)
+{
+ struct panel_rg353 *ctx = panel_to_panelrg353(panel);
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+ int ret;
+
+ if (!ctx->prepared)
+ return 0;
+
+ ret = mipi_dsi_dcs_set_display_off(dsi);
+ if (ret < 0)
+ dev_err(ctx->dev, "failed to set display off: %d\n", ret);
+
+ msleep(20);
+
+ ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
+ if (ret < 0) {
+ dev_err(ctx->dev, "failed to enter sleep mode: %d\n", ret);
+ return ret;
+ }
+
+ msleep(10);
+
+ regulator_disable(ctx->vdd);
+
+ ctx->prepared = false;
+
+ return 0;
+}
+
+static int panel_rg353_prepare(struct drm_panel *panel)
+{
+ struct panel_rg353 *ctx = panel_to_panelrg353(panel);
+ struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
+ int ret;
+
+ if (ctx->prepared)
+ return 0;
+
+ dev_dbg(ctx->dev, "Resetting the panel\n");
+ ret = regulator_enable(ctx->vdd);
+ if (ret < 0) {
+ dev_err(ctx->dev, "Failed to enable vdd supply: %d\n", ret);
+ return ret;
+ }
+
+ usleep_range(2000, 3000);
+ gpiod_set_value_cansleep(ctx->reset_gpio, 1);
+ msleep(150);
+ gpiod_set_value_cansleep(ctx->reset_gpio, 0);
+ msleep(20);
+
+ ret = panel_rg353_init_sequence(ctx);
+ if (ret < 0) {
+ dev_err(ctx->dev, "Panel init sequence failed: %d\n", ret);
+ goto disable_vdd;
+ }
+
+ ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
+ if (ret < 0) {
+ dev_err(ctx->dev, "Failed to exit sleep mode: %d\n", ret);
+ goto disable_vdd;
+ }
+
+ msleep(200);
+
+ ret = mipi_dsi_dcs_set_display_on(dsi);
+ if (ret < 0) {
+ dev_err(ctx->dev, "Failed to set display on: %d\n", ret);
+ goto disable_vdd;
+ }
+
+ msleep(10);
+
+ ctx->prepared = true;
+
+ return 0;
+
+disable_vdd:
+ regulator_disable(ctx->vdd);
+ return ret;
+}
+
+/* verify width and height */
+static const struct drm_display_mode default_mode = {
+ .hdisplay = 640,
+ .hsync_start = 640 + 40,
+ .hsync_end = 640 + 40 + 2,
+ .htotal = 640 + 40 + 2 + 80,
+ .vdisplay = 480,
+ .vsync_start = 480 + 28,
+ .vsync_end = 480 + 28 + 2,
+ .vtotal = 480 + 28 + 2 + 56,
+ .clock = 29000,
+ .width_mm = 72,
+ .height_mm = 53,
+ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
+};
+
+static int panel_rg353_get_modes(struct drm_panel *panel,
+ struct drm_connector *connector)
+{
+ struct panel_rg353 *ctx = panel_to_panelrg353(panel);
+ struct drm_display_mode *mode;
+
+ mode = drm_mode_duplicate(connector->dev, &default_mode);
+ if (!mode) {
+ dev_err(ctx->dev, "Failed to add mode %ux%u@%u\n",
+ default_mode.hdisplay, default_mode.vdisplay,
+ drm_mode_vrefresh(&default_mode));
+ 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;
+ connector->display_info.bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE | DRM_BUS_FLAG_DE_LOW;
+ drm_mode_probed_add(connector, mode);
+ drm_connector_set_panel_orientation(connector, ctx->orientation);
+
+ return 1;
+}
+
+static const struct drm_panel_funcs panel_rg353_funcs = {
+ .unprepare = panel_rg353_unprepare,
+ .prepare = panel_rg353_prepare,
+ .get_modes = panel_rg353_get_modes,
+};
+
+static int panel_rg353_probe(struct mipi_dsi_device *dsi)
+{
+ struct device *dev = &dsi->dev;
+ struct panel_rg353 *ctx;
+ int ret;
+
+ ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(ctx->reset_gpio)) {
+ dev_err(dev, "cannot get reset gpio\n");
+ return PTR_ERR(ctx->reset_gpio);
+ }
+
+ ctx->vdd = devm_regulator_get(dev, "vdd");
+ if (IS_ERR(ctx->vdd)) {
+ ret = PTR_ERR(ctx->vdd);
+ if (ret != -EPROBE_DEFER)
+ dev_err(dev, "Failed to request vdd regulator: %d\n", ret);
+ return ret;
+ }
+
+ ret = of_drm_get_panel_orientation(dev->of_node, &ctx->orientation);
+ if (ret < 0) {
+ dev_err(dev, "%pOF: failed to get orientation %d\n", dev->of_node, ret);
+ return ret;
+ }
+
+ 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_BURST |
+ MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET |
+ MIPI_DSI_CLOCK_NON_CONTINUOUS;
+
+ drm_panel_init(&ctx->panel, &dsi->dev, &panel_rg353_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) {
+ dev_err(dev, "mipi_dsi_attach failed: %d\n", ret);
+ drm_panel_remove(&ctx->panel);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void panel_rg353_shutdown(struct mipi_dsi_device *dsi)
+{
+ struct panel_rg353 *ctx = mipi_dsi_get_drvdata(dsi);
+ int ret;
+
+ ret = drm_panel_unprepare(&ctx->panel);
+ if (ret < 0)
+ dev_err(&dsi->dev, "Failed to unprepare panel: %d\n", ret);
+
+ ret = drm_panel_disable(&ctx->panel);
+ if (ret < 0)
+ dev_err(&dsi->dev, "Failed to disable panel: %d\n", ret);
+}
+
+static int panel_rg353_remove(struct mipi_dsi_device *dsi)
+{
+ struct panel_rg353 *ctx = mipi_dsi_get_drvdata(dsi);
+ int ret;
+
+ panel_rg353_shutdown(dsi);
+
+ 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);
+
+ return 0;
+}
+
+static const struct of_device_id anbernic_rg353_of_match[] = {
+ { .compatible = "anbernic,rg353-panel" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, anbernic_rg353_of_match);
+
+static struct mipi_dsi_driver anbernic_rg353_driver = {
+ .driver = {
+ .name = "panel-anbernic-rg353",
+ .of_match_table = anbernic_rg353_of_match,
+ },
+ .probe = panel_rg353_probe,
+ .remove = panel_rg353_remove,
+ .shutdown = panel_rg353_shutdown,
+};
+module_mipi_dsi_driver(anbernic_rg353_driver);
+
+MODULE_AUTHOR("Chris Morgan <macromorgan@hotmail.com>");
+MODULE_DESCRIPTION("DRM driver for Anbernic RG353 MIPI DSI panel");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/panel/panel-samsung-ams495qa01.c b/drivers/gpu/drm/panel/panel-samsung-ams495qa01.c
new file mode 100644
index 000000000000..4bb910a70d13
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-samsung-ams495qa01.c
@@ -0,0 +1,318 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <drm/drm_mipi_dbi.h>
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_panel.h>
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/media-bus-format.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/regulator/consumer.h>
+#include <linux/spi/spi.h>
+
+#include <video/mipi_display.h>
+
+struct ams495qa01 {
+ /** @dev: the container device */
+ struct device *dev;
+ /** @dbi: the DBI bus abstraction handle */
+ struct mipi_dbi dbi;
+ /** @panel: the DRM panel instance for this device */
+ struct drm_panel panel;
+ /** @reset: reset GPIO line */
+ struct gpio_desc *reset;
+ /** @enable: enable GPIO line */
+ struct gpio_desc *enable;
+ /** @regulators: VCCIO and VIO supply regulators */
+ struct regulator_bulk_data regulators[2];
+ /** @dsi_dev: DSI child device (panel) */
+ struct mipi_dsi_device *dsi_dev;
+};
+
+static const struct drm_display_mode ams495qa01_mode = {
+ .clock = 33500,
+ .hdisplay = 960,
+ .hsync_start = 960 + 10,
+ .hsync_end = 960 + 10 + 2,
+ .htotal = 960 + 10 + 2 + 10,
+ .vdisplay = 544,
+ .vsync_start = 544 + 10,
+ .vsync_end = 544 + 10 + 2,
+ .vtotal = 544 + 10 + 2 + 10,
+ .width_mm = 111,
+ .height_mm = 63,
+};
+
+static inline struct ams495qa01 *to_ams495qa01(struct drm_panel *panel)
+{
+ return container_of(panel, struct ams495qa01, panel);
+}
+
+static int ams495qa01_prepare(struct drm_panel *panel)
+{
+ struct ams495qa01 *db = to_ams495qa01(panel);
+ struct mipi_dbi *dbi = &db->dbi;
+ int ret;
+
+ /* Power up */
+ ret = regulator_bulk_enable(ARRAY_SIZE(db->regulators),
+ db->regulators);
+ if (ret) {
+ dev_err(db->dev, "failed to enable regulators: %d\n", ret);
+ return ret;
+ }
+
+ /* Enable */
+ if (db->enable)
+ gpiod_set_value_cansleep(db->enable, 1);
+
+ usleep_range(2000, 3000);
+
+ /* Reset */
+ gpiod_set_value_cansleep(db->reset, 1);
+ usleep_range(1000, 5000);
+ gpiod_set_value_cansleep(db->reset, 0);
+ msleep(20);
+
+ /* Panel Init Sequence */
+ mipi_dbi_command(dbi, 0xf0, 0x5a, 0x5a);
+ mipi_dbi_command(dbi, 0xf1, 0x5a, 0x5a);
+ mipi_dbi_command(dbi, 0xb0, 0x02);
+ mipi_dbi_command(dbi, 0xf3, 0x3b);
+ mipi_dbi_command(dbi, 0xf4, 0x33, 0x42, 0x00, 0x08);
+ mipi_dbi_command(dbi, 0xf5, 0x00, 0x06, 0x26, 0x35, 0x03);
+ mipi_dbi_command(dbi, 0xf6, 0x02);
+ mipi_dbi_command(dbi, 0xc6, 0x0B, 0x00, 0x00, 0x3C, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00);
+ mipi_dbi_command(dbi, 0xf7, 0x20);
+ mipi_dbi_command(dbi, 0xf5, 0x00, 0x06, 0x27, 0x35, 0x03);
+ mipi_dbi_command(dbi, 0xb2, 0x06, 0x06, 0x06, 0x06);
+ mipi_dbi_command(dbi, 0xb1, 0x07, 0x00, 0x10);
+ mipi_dbi_command(dbi, 0xf8, 0x7f, 0x7a, 0x89, 0x67, 0x26, 0x38, 0x00, 0x00, 0x09, 0x67, 0x70, 0x88, 0x7a, 0x76, 0x05, 0x09, 0x23, 0x23, 0x23);
+ mipi_dbi_command(dbi, 0x11);
+ msleep(200);
+ mipi_dbi_command(dbi, 0x29);
+ msleep(10);
+ mipi_dbi_command(dbi, 0xb5, 0xff, 0xef, 0x35, 0x42, 0x0d, 0xd7, 0xff, 0x07, 0xff, 0xff, 0xfd, 0x00, 0x01, 0xff, 0x05, 0x12, 0x0f, 0xff, 0xff, 0xff, 0xff);
+ mipi_dbi_command(dbi, 0xb4, 0x15);
+ mipi_dbi_command(dbi, 0xb3, 0x00);
+ mipi_dbi_command(dbi, 0xf9, 0x01, 0x9f, 0x9f, 0xbe, 0xcf, 0xd7, 0xc9, 0xc2, 0xcb, 0xbb, 0xe1, 0xe3, 0xde, 0xd6, 0xd0, 0xd3, 0xfa, 0xed, 0xe6, 0x2f, 0x00, 0x2f);
+ mipi_dbi_command(dbi, 0xf9, 0x00);
+ mipi_dbi_command(dbi, 0x26, 0x00);
+ mipi_dbi_command(dbi, 0xb2, 0x12);
+ msleep(200);
+ mipi_dbi_command(dbi, 0x11);
+ msleep(200);
+ mipi_dbi_command(dbi, 0x29);
+ msleep(10);
+
+ return 0;
+}
+
+static int ams495qa01_unprepare(struct drm_panel *panel)
+{
+ struct ams495qa01 *db = to_ams495qa01(panel);
+ struct mipi_dbi *dbi = &db->dbi;
+
+ /* Panel Exit Sequence */
+ mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_OFF);
+ msleep(20);
+ mipi_dbi_command(dbi, MIPI_DCS_ENTER_SLEEP_MODE);
+ msleep(10);
+
+ gpiod_set_value_cansleep(db->reset, 0);
+
+ if (db->enable)
+ gpiod_set_value_cansleep(db->enable, 0);
+ regulator_bulk_disable(ARRAY_SIZE(db->regulators),
+ db->regulators);
+ msleep(20);
+
+ return 0;
+}
+
+static int ams495qa01_get_modes(struct drm_panel *panel,
+ struct drm_connector *connector)
+{
+ struct ams495qa01 *db = to_ams495qa01(panel);
+ struct drm_display_mode *mode;
+ static const u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
+
+ mode = drm_mode_duplicate(connector->dev, &ams495qa01_mode);
+ if (!mode) {
+ dev_err(db->dev, "failed to add mode\n");
+ return -ENOMEM;
+ }
+
+ connector->display_info.bpc = 8;
+ connector->display_info.width_mm = mode->width_mm;
+ connector->display_info.height_mm = mode->height_mm;
+ connector->display_info.bus_flags =
+ DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE;
+ drm_display_info_set_bus_formats(&connector->display_info,
+ &bus_format, 1);
+
+ drm_mode_set_name(mode);
+ mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+
+ drm_mode_probed_add(connector, mode);
+
+ return 1;
+}
+
+static const struct drm_panel_funcs ams495qa01_drm_funcs = {
+ .unprepare = ams495qa01_unprepare,
+ .prepare = ams495qa01_prepare,
+ .get_modes = ams495qa01_get_modes,
+};
+
+static int ams495qa01_probe(struct spi_device *spi)
+{
+ struct device *dev = &spi->dev;
+ struct device_node *endpoint, *dsi_host_node;
+ struct mipi_dsi_host *dsi_host;
+ struct ams495qa01 *db;
+ int ret;
+ struct mipi_dsi_device_info info = {
+ .type = "dupa",
+ .channel = 0,
+ .node = NULL,
+ };
+
+ db = devm_kzalloc(dev, sizeof(*db), GFP_KERNEL);
+ if (!db)
+ return -ENOMEM;
+
+ spi_set_drvdata(spi, db);
+
+ db->dev = dev;
+
+ /*
+ * VCI is the analog voltage supply
+ * VCCIO is the digital I/O voltage supply
+ */
+ db->regulators[0].supply = "vci";
+ db->regulators[1].supply = "vccio";
+ ret = devm_regulator_bulk_get(dev,
+ ARRAY_SIZE(db->regulators),
+ db->regulators);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to get regulators\n");
+
+ db->reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+ if (IS_ERR(db->reset)) {
+ ret = PTR_ERR(db->reset);
+ return dev_err_probe(dev, ret, "no RESET GPIO\n");
+ }
+
+ db->enable = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH);
+ if (IS_ERR(db->enable)) {
+ ret = PTR_ERR(db->enable);
+ return dev_err_probe(dev, ret, "cannot get ENABLE GPIO\n");
+ }
+
+ ret = mipi_dbi_spi_init(spi, &db->dbi, NULL);
+ if (ret)
+ return dev_err_probe(dev, ret, "MIPI DBI init failed\n");
+
+ endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
+ if (!endpoint) {
+ dev_err(dev, "failed to get endpoint\n");
+ return -ENODEV;
+ }
+
+ dsi_host_node = of_graph_get_remote_port_parent(endpoint);
+ if (!dsi_host_node) {
+ dev_err(dev, "failed to get remote port parent\n");
+ goto put_endpoint;
+ }
+
+ dsi_host = of_find_mipi_dsi_host_by_node(dsi_host_node);
+ if (!dsi_host) {
+ dev_err(dev, "failed to find dsi host\n");
+ goto put_host;
+ }
+
+ info.node = of_graph_get_remote_port(endpoint);
+ if (!info.node) {
+ dev_err(dev, "failed to get remote port node\n");
+ ret = -ENODEV;
+ goto put_host;
+ }
+
+ db->dsi_dev = devm_mipi_dsi_device_register_full(dev, dsi_host, &info);
+ if (IS_ERR(db->dsi_dev)) {
+ dev_err(dev, "failed to register dsi device: %ld\n",
+ PTR_ERR(db->dsi_dev));
+ ret = PTR_ERR(db->dsi_dev);
+ goto put_host;
+ }
+
+ db->dsi_dev->lanes = 2;
+ db->dsi_dev->format = MIPI_DSI_FMT_RGB888;
+ db->dsi_dev->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
+ MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET |
+ MIPI_DSI_CLOCK_NON_CONTINUOUS;
+
+ drm_panel_init(&db->panel, dev, &ams495qa01_drm_funcs,
+ DRM_MODE_CONNECTOR_DSI);
+
+ drm_panel_add(&db->panel);
+
+ ret = devm_mipi_dsi_attach(dev, db->dsi_dev);
+ if (ret < 0) {
+ dev_err(dev, "mipi_dsi_attach failed: %d\n", ret);
+ drm_panel_remove(&db->panel);
+ return ret;
+ }
+
+ of_node_put(dsi_host_node);
+ of_node_put(endpoint);
+ return 0;
+
+put_host:
+ of_node_put(dsi_host_node);
+
+put_endpoint:
+ of_node_put(endpoint);
+ return -ENODEV;
+}
+
+static void ams495qa01_remove(struct spi_device *spi)
+{
+ struct ams495qa01 *db = spi_get_drvdata(spi);
+
+ drm_panel_remove(&db->panel);
+}
+
+static const struct of_device_id ams495qa01_match[] = {
+ { .compatible = "samsung,ams495qa01", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ams495qa01_match);
+
+static const struct spi_device_id ams495qa01_ids[] = {
+ { "ams495qa01", 0 },
+ {},
+};
+MODULE_DEVICE_TABLE(spi, ams495qa01_ids);
+
+static struct spi_driver ams495qa01_driver = {
+ .probe = ams495qa01_probe,
+ .remove = ams495qa01_remove,
+ .id_table = ams495qa01_ids,
+ .driver = {
+ .name = "ams495qa01-panel",
+ .of_match_table = ams495qa01_match,
+ },
+};
+module_spi_driver(ams495qa01_driver);
+
+MODULE_AUTHOR("Chris Morgan <macromorgan@hotmail.com>");
+MODULE_DESCRIPTION("Samsung ams495qa01 panel driver");
+MODULE_LICENSE("GPL v2");
--
2.25.1
From fd2a4660bc8179560bbe70cd6c9365c722b214da Mon Sep 17 00:00:00 2001
From: Chris Morgan <macromorgan@hotmail.com>
Date: Tue, 30 Aug 2022 12:31:05 -0500
Subject: [PATCH] rockchip: Add Anbernic RG503 and RG353P devicetrees
Do not upstream, some hardware on this tree is not working yet.
Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
---
.../dts/rockchip/rk3566-anbernic-rg353p.dts | 152 ++++
.../dts/rockchip/rk3566-anbernic-rg503.dts | 143 +++
.../dts/rockchip/rk3566-anbernic-rgxx3.dtsi | 831 ++++++++++++++++++
3 files changed, 1126 insertions(+)
create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353p.dts
create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg503.dts
create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-anbernic-rgxx3.dtsi
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353p.dts b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353p.dts
new file mode 100644
index 000000000000..ef1d7a97971a
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353p.dts
@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3566-anbernic-rgxx3.dtsi"
+
+/ {
+ model = "RG353P";
+ compatible = "anbernic,rg353p", "rockchip,rk3566";
+
+ aliases {
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc0;
+ mmc2 = &sdmmc1;
+ mmc3 = &sdmmc2;
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ power-supply = <&vcc_sys>;
+ pwms = <&pwm4 0 25000 0>;
+ };
+};
+
+&dsi0 {
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ports {
+ dsi0_in: port@0 {
+ reg = <0>;
+ dsi0_in_vp0: endpoint {
+ remote-endpoint = <&vp0_out_dsi0>;
+ };
+ };
+
+ dsi0_out: port@1 {
+ reg = <1>;
+ mipi_out_panel: endpoint {
+ remote-endpoint = <&mipi_in_panel>;
+ };
+ };
+ };
+
+ panel@0 {
+ compatible = "anbernic,rg353-panel";
+ reg = <0>;
+ backlight = <&backlight>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcd_rst>;
+ reset-gpios = <&gpio4 RK_PA0 GPIO_ACTIVE_LOW>;
+ vdd-supply = <&vcc3v3_lcd0_n>;
+
+ port {
+ mipi_in_panel: endpoint {
+ remote-endpoint = <&mipi_out_panel>;
+ };
+ };
+ };
+};
+
+&gpio_keys_control {
+ button-5 {
+ gpios = <&gpio3 RK_PA5 GPIO_ACTIVE_LOW>;
+ label = "DPAD-LEFT";
+ linux,code = <BTN_DPAD_RIGHT>;
+ };
+
+ button-6 {
+ gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_LOW>;
+ label = "DPAD-RIGHT";
+ linux,code = <BTN_DPAD_LEFT>;
+ };
+
+ button-9 {
+ gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_LOW>;
+ label = "TR";
+ linux,code = <BTN_TR2>;
+ };
+
+ button-10 {
+ gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>;
+ label = "TR2";
+ linux,code = <BTN_TR>;
+ };
+
+ button-14 {
+ gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_LOW>;
+ label = "WEST";
+ linux,code = <BTN_WEST>;
+ };
+
+ button-15 {
+ gpios = <&gpio3 RK_PC2 GPIO_ACTIVE_LOW>;
+ label = "EAST";
+ linux,code = <BTN_EAST>;
+ };
+};
+
+&i2c0 {
+ /* This hardware is physically present but unused. */
+ cw2015@62 {
+ compatible = "cellwise,cw2015";
+ reg = <0x62>;
+ status = "disabled";
+ };
+};
+
+&i2c2 {
+ pintctrl-names = "default";
+ pinctrl-0 = <&i2c2m1_xfer>;
+ status = "okay";
+};
+
+&mipi_dphy0 {
+ status = "okay";
+};
+
+&pinctrl {
+ gpio-lcd {
+ lcd_rst: lcd-rst {
+ rockchip,pins =
+ <4 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&pwm4 {
+ status = "okay";
+};
+
+&sdhci {
+ pinctrl-0 = <&emmc_bus8>, <&emmc_clk>, <&emmc_cmd>, <&emmc_datastrobe>, <&emmc_rstnout>;
+ pinctrl-names = "default";
+ bus-width = <8>;
+ mmc-hs200-1_8v;
+ non-removable;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vcc_1v8>;
+ status = "okay";
+};
+
+&vp0 {
+ vp0_out_dsi0: endpoint@ROCKCHIP_VOP2_EP_MIPI0 {
+ reg = <ROCKCHIP_VOP2_EP_MIPI0>;
+ remote-endpoint = <&dsi0_in_vp0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg503.dts b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg503.dts
new file mode 100644
index 000000000000..1a8378ee0b3e
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg503.dts
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3566-anbernic-rgxx3.dtsi"
+
+/ {
+ model = "RG503";
+ compatible = "anbernic,rg503", "rockchip,rk3566";
+
+ aliases {
+ mmc0 = &sdmmc0;
+ mmc1 = &sdmmc1;
+ mmc2 = &sdmmc2;
+ };
+
+ gpio_spi: spi {
+ compatible = "spi-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi_pins>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ sck-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>;
+ mosi-gpios = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>;
+ cs-gpios = <&gpio4 RK_PA7 GPIO_ACTIVE_HIGH>;
+ num-chipselects = <0>;
+
+ panel@0 {
+ compatible = "samsung,ams495qa01";
+ reg = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcd_enable>, <&lcd_reset>;
+ enable-gpios = <&gpio4 RK_PB7 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&gpio4 RK_PA0 GPIO_ACTIVE_LOW>;
+ vci-supply = <&vcc3v3_lcd0_n>;
+ /*vccio-supply = <&vcc3v3_lcd0_n>;*/
+
+ port {
+ mipi_in_panel: endpoint {
+ remote-endpoint = <&mipi_out_panel>;
+ };
+ };
+ };
+ };
+};
+
+&dsi0 {
+ status = "okay";
+
+ ports {
+ dsi0_in: port@0 {
+ reg = <0>;
+
+ dsi0_in_vp0: endpoint {
+ remote-endpoint = <&vp0_out_dsi0>;
+ };
+ };
+
+ dsi0_out: port@1 {
+ reg = <1>;
+
+ mipi_out_panel: endpoint {
+ remote-endpoint = <&mipi_in_panel>;
+ };
+ };
+ };
+};
+
+&gpio_keys_control {
+ button-5 {
+ gpios = <&gpio3 RK_PA5 GPIO_ACTIVE_LOW>;
+ label = "DPAD-LEFT";
+ linux,code = <BTN_DPAD_LEFT>;
+ };
+
+ button-6 {
+ gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_LOW>;
+ label = "DPAD-RIGHT";
+ linux,code = <BTN_DPAD_RIGHT>;
+ };
+
+ button-9 {
+ gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_LOW>;
+ label = "TR";
+ linux,code = <BTN_TR>;
+ };
+
+ button-10 {
+ gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>;
+ label = "TR2";
+ linux,code = <BTN_TR2>;
+ };
+
+ button-14 {
+ gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_LOW>;
+ label = "EAST";
+ linux,code = <BTN_EAST>;
+ };
+
+ button-15 {
+ gpios = <&gpio3 RK_PC2 GPIO_ACTIVE_LOW>;
+ label = "WEST";
+ linux,code = <BTN_WEST>;
+ };
+};
+
+&mipi_dphy0 {
+ status = "okay";
+};
+
+&pinctrl {
+ gpio-spi {
+ spi_pins: spi-pins {
+ rockchip,pins =
+ <4 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>,
+ <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>,
+ <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ gpio-lcd {
+ lcd_enable: lcd-enable {
+ rockchip,pins =
+ <4 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ lcd_reset: lcd-reset {
+ rockchip,pins =
+ <4 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&vp0 {
+ vp0_out_dsi0: endpoint@ROCKCHIP_VOP2_EP_MIPI0 {
+ reg = <ROCKCHIP_VOP2_EP_MIPI0>;
+ remote-endpoint = <&dsi0_in_vp0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rgxx3.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rgxx3.dtsi
new file mode 100644
index 000000000000..688229ccdc2c
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rgxx3.dtsi
@@ -0,0 +1,831 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
+#include "rk3566.dtsi"
+
+/ {
+ chosen: chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ adc-joystick {
+ compatible = "adc-joystick";
+ io-channels = <&adc_mux 0>,
+ <&adc_mux 1>,
+ <&adc_mux 2>,
+ <&adc_mux 3>;
+ pinctrl-0 = <&joy_mux_en>;
+ pinctrl-names = "default";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ axis@0 {
+ reg = <0>;
+ abs-flat = <32>;
+ abs-fuzz = <32>;
+ abs-range = <1023 15>;
+ linux,code = <ABS_X>;
+ };
+
+ axis@1 {
+ reg = <1>;
+ abs-flat = <32>;
+ abs-fuzz = <32>;
+ abs-range = <15 1023>;
+ linux,code = <ABS_RX>;
+ };
+
+ axis@2 {
+ reg = <2>;
+ abs-flat = <32>;
+ abs-fuzz = <32>;
+ abs-range = <15 1023>;
+ linux,code = <ABS_Y>;
+ };
+
+ axis@3 {
+ reg = <3>;
+ abs-flat = <32>;
+ abs-fuzz = <32>;
+ abs-range = <1023 15>;
+ linux,code = <ABS_RY>;
+ };
+ };
+
+ adc_keys: adc-keys {
+ compatible = "adc-keys";
+ io-channels = <&saradc 0>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <60>;
+
+ /*
+ * Button is mapped to F key in BSP kernel, but
+ * according to input guidelines it should be mode.
+ */
+ button-mode {
+ label = "MODE";
+ linux,code = <BTN_MODE>;
+ press-threshold-microvolt = <1750>;
+ };
+ };
+
+ adc_mux: adc-mux {
+ compatible = "io-channel-mux";
+ channels = "left_x", "right_x", "left_y", "right_y";
+ #io-channel-cells = <1>;
+ io-channels = <&saradc 3>;
+ io-channel-names = "parent";
+ mux-controls = <&gpio_mux>;
+ settle-time-us = <100>;
+ };
+
+ gpio_keys_control: gpio-keys-control {
+ compatible = "gpio-keys";
+ pinctrl-0 = <&btn_pins_ctrl>;
+ pinctrl-names = "default";
+
+ button-1 {
+ gpios = <&gpio3 RK_PA1 GPIO_ACTIVE_LOW>;
+ label = "THUMBL";
+ linux,code = <BTN_THUMBL>;
+ };
+
+ button-2 {
+ gpios = <&gpio3 RK_PA2 GPIO_ACTIVE_LOW>;
+ label = "THUMBR";
+ linux,code = <BTN_THUMBR>;
+ };
+
+ button-3 {
+ gpios = <&gpio3 RK_PA3 GPIO_ACTIVE_LOW>;
+ label = "DPAD-UP";
+ linux,code = <BTN_DPAD_UP>;
+ };
+
+ button-4 {
+ gpios = <&gpio3 RK_PA4 GPIO_ACTIVE_LOW>;
+ label = "DPAD-DOWN";
+ linux,code = <BTN_DPAD_DOWN>;
+ };
+
+ button-7 {
+ gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>;
+ label = "TL";
+ linux,code = <BTN_TL>;
+ };
+
+ button-8 {
+ gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>;
+ label = "TL2";
+ linux,code = <BTN_TL2>;
+ };
+
+ button-11 {
+ gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_LOW>;
+ label = "START";
+ linux,code = <BTN_START>;
+ };
+
+ button-12 {
+ gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_LOW>;
+ label = "SELECT";
+ linux,code = <BTN_SELECT>;
+ };
+
+ button-13 {
+ gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>;
+ label = "NORTH";
+ linux,code = <BTN_NORTH>;
+ };
+
+ button-16 {
+ gpios = <&gpio3 RK_PC3 GPIO_ACTIVE_LOW>;
+ label = "SOUTH";
+ linux,code = <BTN_SOUTH>;
+ };
+ };
+
+ gpio_keys_vol: gpio-keys-vol {
+ compatible = "gpio-keys";
+ autorepeat;
+ pinctrl-0 = <&btn_pins_vol>;
+ pinctrl-names = "default";
+
+ button-vol-down {
+ gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>;
+ label = "VOLUMEDOWN";
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+
+ button-vol-up {
+ gpios = <&gpio3 RK_PA7 GPIO_ACTIVE_LOW>;
+ label = "VOLUMEUP";
+ linux,code = <KEY_VOLUMEUP>;
+ };
+ };
+
+ gpio_mux: mux-controller {
+ compatible = "gpio-mux";
+ mux-gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_LOW>,
+ <&gpio0 RK_PB7 GPIO_ACTIVE_LOW>;
+ #mux-control-cells = <0>;
+ };
+
+ hdmi-con {
+ compatible = "hdmi-connector";
+ ddc-i2c-bus = <&i2c5>;
+ type = "c";
+
+ port {
+ hdmi_con_in: endpoint {
+ remote-endpoint = <&hdmi_out_con>;
+ };
+ };
+ };
+
+ leds: gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-0 = <&led_pins>;
+ pinctrl-names = "default";
+
+ green_led: led-0 {
+ color = <LED_COLOR_ID_GREEN>;
+ default-state = "on";
+ function = LED_FUNCTION_POWER;
+ gpios = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
+ };
+
+ amber_led: led-1 {
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_CHARGING;
+ gpios = <&gpio0 RK_PC6 GPIO_ACTIVE_HIGH>;
+ retain-state-suspended;
+ };
+
+ red_led: led-2 {
+ color = <LED_COLOR_ID_RED>;
+ default-state = "off";
+ function = LED_FUNCTION_STATUS;
+ gpios = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ /* Channels reversed for both headphones and speakers. */
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "anbernic_rk817";
+ simple-audio-card,aux-devs = <&spk_amp>;
+ simple-audio-card,format = "i2s";
+ simple-audio-card,hp-det-gpio = <&gpio4 RK_PC6 GPIO_ACTIVE_HIGH>;
+ simple-audio-card,mclk-fs = <256>;
+ simple-audio-card,widgets =
+ "Microphone", "Mic Jack",
+ "Headphone", "Headphones",
+ "Speaker", "Internal Speakers";
+ simple-audio-card,routing =
+ "MICL", "Mic Jack",
+ "Headphones", "HPOL",
+ "Headphones", "HPOR",
+ "Internal Speakers", "Speaker Amp OUTL",
+ "Internal Speakers", "Speaker Amp OUTR",
+ "Speaker Amp INL", "HPOL",
+ "Speaker Amp INR", "HPOR";
+ simple-audio-card,pin-switches = "Internal Speakers";
+
+ simple-audio-card,codec {
+ sound-dai = <&rk817>;
+ };
+
+ simple-audio-card,cpu {
+ sound-dai = <&i2s1_8ch>;
+ };
+ };
+
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ clocks = <&rk817 1>;
+ clock-names = "ext_clock";
+ pinctrl-0 = <&wifi_enable_h>;
+ pinctrl-names = "default";
+ post-power-on-delay-ms = <200>;
+ reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_LOW>;
+ };
+
+ spk_amp: audio-amplifier {
+ compatible = "simple-audio-amplifier";
+ enable-gpios = <&gpio4 RK_PC2 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&spk_amp_enable_h>;
+ pinctrl-names = "default";
+ sound-name-prefix = "Speaker Amp";
+ };
+
+ vcc3v3_lcd0_n: regulator-vcc3v3-lcd0 {
+ compatible = "regulator-fixed";
+ gpio = <&gpio0 RK_PC2 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ pinctrl-0 = <&vcc_lcd_h>;
+ pinctrl-names = "default";
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc3v3_lcd0_n";
+ vin-supply = <&vcc_3v3>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_sys: regulator-vcc-sys {
+ compatible = "regulator-fixed";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3800000>;
+ regulator-max-microvolt = <3800000>;
+ regulator-name = "vcc_sys";
+ };
+
+ vcc_wifi: regulator-vcc-wifi {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
+ pinctrl-0 = <&vcc_wifi_h>;
+ pinctrl-names = "default";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc_wifi";
+ };
+
+ vibrator: pwm-vibrator {
+ compatible = "pwm-vibrator";
+ pwm-names = "enable";
+ pwms = <&pwm5 0 1000000000 0>;
+ };
+};
+
+&combphy1 {
+ status = "okay";
+};
+
+&cpu0 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu1 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu2 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&cpu3 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+&gpu {
+ mali-supply = <&vdd_gpu>;
+ status = "okay";
+};
+
+&hdmi {
+ ddc-i2c-bus = <&i2c5>;
+ pinctrl-0 = <&hdmitxm0_cec>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&hdmi_in {
+ hdmi_in_vp0: endpoint {
+ remote-endpoint = <&vp0_out_hdmi>;
+ };
+};
+
+&hdmi_out {
+ hdmi_out_con: endpoint {
+ remote-endpoint = <&hdmi_con_in>;
+ };
+};
+
+&hdmi_sound {
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+
+ rk817: pmic@20 {
+ compatible = "rockchip,rk817";
+ reg = <0x20>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+ clock-output-names = "rk808-clkout1", "rk808-clkout2";
+ clock-names = "mclk";
+ clocks = <&cru I2S1_MCLKOUT_TX>;
+ assigned-clocks = <&cru I2S1_MCLKOUT_TX>;
+ assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>;
+ #clock-cells = <1>;
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s1m0_mclk>, <&pmic_int_l>;
+ wakeup-source;
+
+ vcc1-supply = <&vcc_sys>;
+ vcc2-supply = <&vcc_sys>;
+ vcc3-supply = <&vcc_sys>;
+ vcc4-supply = <&vcc_sys>;
+ vcc5-supply = <&vcc_sys>;
+ vcc6-supply = <&vcc_sys>;
+ vcc7-supply = <&vcc_sys>;
+ vcc8-supply = <&vcc_sys>;
+ vcc9-supply = <&dcdc_boost>;
+
+ regulators {
+ vdd_logic: DCDC_REG1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-init-microvolt = <900000>;
+ regulator-ramp-delay = <6001>;
+ regulator-initial-mode = <0x2>;
+ regulator-name = "vdd_logic";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ regulator-suspend-microvolt = <900000>;
+ };
+ };
+
+ vdd_gpu: DCDC_REG2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-init-microvolt = <900000>;
+ regulator-ramp-delay = <6001>;
+ regulator-initial-mode = <0x2>;
+ regulator-name = "vdd_gpu";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc_ddr: DCDC_REG3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-initial-mode = <0x2>;
+ regulator-name = "vcc_ddr";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ };
+ };
+
+ vcc_3v3: DCDC_REG4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-initial-mode = <0x2>;
+ regulator-name = "vcc_3v3";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vcca1v8_pmu: LDO_REG1 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcca1v8_pmu";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <1800000>;
+ };
+ };
+
+ vdda_0v9: LDO_REG2 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+ regulator-name = "vdda_0v9";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdda0v9_pmu: LDO_REG3 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+ regulator-name = "vdda0v9_pmu";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <900000>;
+ };
+ };
+
+ vccio_acodec: LDO_REG4 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vccio_acodec";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vccio_sd: LDO_REG5 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vccio_sd";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc3v3_pmu: LDO_REG6 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc3v3_pmu";
+ regulator-state-mem {
+ regulator-on-in-suspend;
+ regulator-suspend-microvolt = <3300000>;
+ };
+ };
+
+ vcc_1v8: LDO_REG7 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc_1v8";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc1v8_dvp: LDO_REG8 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc1v8_dvp";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vcc2v8_dvp: LDO_REG9 {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-name = "vcc2v8_dvp";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ dcdc_boost: BOOST {
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <4700000>;
+ regulator-max-microvolt = <5400000>;
+ regulator-name = "boost";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ otg_switch: OTG_SWITCH {
+ regulator-name = "otg_switch";
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+
+ vdd_cpu: regulator@40 {
+ compatible = "fcs,fan53555";
+ reg = <0x40>;
+ fcs,suspend-voltage-selector = <1>;
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <712500>;
+ regulator-max-microvolt = <1390000>;
+ regulator-init-microvolt = <900000>;
+ regulator-name = "vdd_cpu";
+ regulator-ramp-delay = <2300>;
+ vin-supply = <&vcc_sys>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2c1 {
+ /* Unknown/unused device at 0x3c */
+ status = "disabled";
+};
+
+&i2c5 {
+ pinctrl-0 = <&i2c5m1_xfer>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&i2s0_8ch {
+ status = "okay";
+};
+
+&i2s1_8ch {
+ pinctrl-0 = <&i2s1m0_sclktx
+ &i2s1m0_lrcktx
+ &i2s1m0_sdi0
+ &i2s1m0_sdo0>;
+ pinctrl-names = "default";
+ rockchip,trcm-sync-tx-only;
+ status = "okay";
+};
+
+&pinctrl {
+ audio-amplifier {
+ spk_amp_enable_h: spk-amp-enable-h {
+ rockchip,pins =
+ <4 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ gpio-btns {
+ btn_pins_ctrl: btn-pins-ctrl {
+ rockchip,pins =
+ <3 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>,
+ <3 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>,
+ <3 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>,
+ <3 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>,
+ <3 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>,
+ <3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>,
+ <3 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>,
+ <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>,
+ <3 RK_PB3 RK_FUNC_GPIO &pcfg_pull_up>,
+ <3 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>,
+ <3 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>,
+ <3 RK_PB6 RK_FUNC_GPIO &pcfg_pull_up>,
+ <3 RK_PC0 RK_FUNC_GPIO &pcfg_pull_up>,
+ <3 RK_PC1 RK_FUNC_GPIO &pcfg_pull_up>,
+ <3 RK_PC2 RK_FUNC_GPIO &pcfg_pull_up>,
+ <3 RK_PC3 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+
+ btn_pins_vol: btn-pins-vol {
+ rockchip,pins =
+ <3 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>,
+ <3 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ gpio-led {
+ led_pins: led-pins {
+ rockchip,pins =
+ <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>,
+ <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>,
+ <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ joy-mux {
+ joy_mux_en: joy-mux-en {
+ rockchip,pins =
+ <0 RK_PB5 RK_FUNC_GPIO &pcfg_output_low>;
+ };
+ };
+
+ pmic {
+ pmic_int_l: pmic-int-l {
+ rockchip,pins =
+ <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+
+ sdio-pwrseq {
+ wifi_enable_h: wifi-enable-h {
+ rockchip,pins =
+ <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ vcc3v3-lcd {
+ vcc_lcd_h: vcc-lcd-h {
+ rockchip,pins =
+ <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ vcc-wifi {
+ vcc_wifi_h: vcc-wifi-h {
+ rockchip,pins =
+ <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+};
+
+&pmu_io_domains {
+ status = "okay";
+ pmuio1-supply = <&vcc3v3_pmu>;
+ pmuio2-supply = <&vcc3v3_pmu>;
+ vccio1-supply = <&vccio_acodec>;
+ vccio3-supply = <&vccio_sd>;
+ vccio4-supply = <&vcc_1v8>;
+ vccio5-supply = <&vcc_3v3>;
+ vccio6-supply = <&vcc1v8_dvp>;
+ vccio7-supply = <&vcc_3v3>;
+};
+
+&pwm5 {
+ status = "okay";
+};
+
+&saradc {
+ vref-supply = <&vcc_1v8>;
+ status = "okay";
+};
+
+&sdmmc0 {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
+ pinctrl-names = "default";
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vccio_sd>;
+ status = "okay";
+};
+
+&sdmmc1 {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cd-gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk &sdmmc1_det>;
+ pinctrl-names = "default";
+ sd-uhs-sdr104;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vcc1v8_dvp>;
+ status = "okay";
+};
+
+&sdmmc2 {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ keep-power-in-suspend;
+ mmc-pwrseq = <&sdio_pwrseq>;
+ non-removable;
+ pinctrl-0 = <&sdmmc2m0_bus4 &sdmmc2m0_cmd &sdmmc2m0_clk>;
+ pinctrl-names = "default";
+ vmmc-supply = <&vcc_wifi>;
+ vqmmc-supply = <&vcca1v8_pmu>;
+ status = "okay";
+};
+
+&tsadc {
+ rockchip,hw-tshut-mode = <1>;
+ rockchip,hw-tshut-polarity = <0>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-0 = <&uart1m1_xfer &uart1m1_ctsn &uart1m1_rtsn>;
+ pinctrl-names = "default";
+ uart-has-rtscts;
+ status = "okay";
+
+ bluetooth {
+ compatible = "realtek,rtl8821cs-bt";
+ device-wake-gpios = <&gpio4 4 GPIO_ACTIVE_HIGH>;
+ enable-gpios = <&gpio4 3 GPIO_ACTIVE_HIGH>;
+ host-wake-gpios = <&gpio4 5 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&uart2 {
+ status = "okay";
+};
+
+/*
+ * Lack the schematics to verify, but port works as a peripheral
+ * (and not a host or OTG port).
+ */
+&usb_host0_xhci {
+ dr_mode = "peripheral";
+ phys = <&usb2phy0_otg>;
+ phy-names = "usb2-phy";
+ status = "okay";
+};
+
+&usb_host1_ehci {
+ status = "okay";
+};
+
+&usb_host1_ohci {
+ status = "okay";
+};
+
+&usb_host1_xhci {
+ phy-names = "usb2-phy", "usb3-phy";
+ phys = <&usb2phy1_host>, <&combphy1 PHY_TYPE_USB3>;
+ status = "okay";
+};
+
+&usb2phy0 {
+ status = "okay";
+};
+
+&usb2phy0_otg {
+ status = "okay";
+};
+
+&usb2phy1 {
+ status = "okay";
+};
+
+&usb2phy1_host {
+ status = "okay";
+};
+
+&vop {
+ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>;
+ assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>;
+ status = "okay";
+};
+
+&vop_mmu {
+ status = "okay";
+};
+
+&vp0 {
+ vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
+ reg = <ROCKCHIP_VOP2_EP_HDMI0>;
+ remote-endpoint = <&hdmi_in_vp0>;
+ };
+};
--
2.25.1
From f149b55c3124265832fafc4b2641c304646d9fdb Mon Sep 17 00:00:00 2001
From: Chris Morgan <macromorgan@hotmail.com>
Date: Tue, 30 Aug 2022 12:29:40 -0500
Subject: [PATCH] rockchip: rk356x: add DSI and DSI-DPHY bindings
Do not upstream yet. Not verified working.
Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
---
arch/arm64/boot/dts/rockchip/rk356x.dtsi | 72 ++++++++++++++++++++++++
1 file changed, 72 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index 319981c3e9f7..ea4341346f74 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -699,6 +699,54 @@ vop_mmu: iommu@fe043e00 {
status = "disabled";
};
+ dsi0: dsi@fe060000 {
+ compatible = "rockchip,rk3568-mipi-dsi", "snps,dw-mipi-dsi";
+ reg = <0x00 0xfe060000 0x00 0x10000>;
+ interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_DSITX_0>, <&cru HCLK_VO>;
+ clock-names = "pclk", "hclk";
+ resets = <&cru SRST_P_DSITX_0>;
+ reset-names = "apb";
+ phys = <&mipi_dphy0>;
+ phy-names = "dphy";
+ power-domains = <&power RK3568_PD_VO>;
+ rockchip,grf = <&grf>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ };
+ };
+ };
+
+ dsi1: dsi@fe070000 {
+ compatible = "rockchip,rk3568-mipi-dsi", "snps,dw-mipi-dsi";
+ reg = <0x0 0xfe070000 0x0 0x10000>;
+ interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru PCLK_DSITX_1>, <&cru HCLK_VO>;
+ clock-names = "pclk", "hclk";
+ resets = <&cru SRST_P_DSITX_1>;
+ reset-names = "apb";
+ phys = <&mipi_dphy1>;
+ phy-names = "dphy";
+ power-domains = <&power RK3568_PD_VO>;
+ rockchip,grf = <&grf>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ };
+ };
+ };
+
hdmi: hdmi@fe0a0000 {
compatible = "rockchip,rk3568-dw-hdmi";
reg = <0x0 0xfe0a0000 0x0 0x20000>;
@@ -1594,6 +1642,30 @@ combphy2: phy@fe840000 {
status = "disabled";
};
+ mipi_dphy0: mipi-dphy@fe850000 {
+ compatible = "rockchip,rk3568-dsi-dphy";
+ reg = <0x0 0xfe850000 0x0 0x10000>;
+ clocks = <&pmucru CLK_MIPIDSIPHY0_REF>, <&cru PCLK_MIPIDSIPHY0>;
+ clock-names = "ref", "pclk";
+ resets = <&cru SRST_P_MIPIDSIPHY0>;
+ reset-names = "apb";
+ power-domains = <&power RK3568_PD_VO>;
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+
+ mipi_dphy1: mipi-dphy@fe860000 {
+ compatible = "rockchip,rk3568-dsi-dphy";
+ reg = <0x0 0xfe860000 0x0 0x10000>;
+ clocks = <&pmucru CLK_MIPIDSIPHY1_REF>, <&cru PCLK_MIPIDSIPHY1>;
+ clock-names = "ref", "pclk";
+ resets = <&cru SRST_P_MIPIDSIPHY1>;
+ reset-names = "apb";
+ power-domains = <&power RK3568_PD_VO>;
+ #phy-cells = <0>;
+ status = "disabled";
+ };
+
usb2phy0: usb2phy@fe8a0000 {
compatible = "rockchip,rk3568-usb2phy";
reg = <0x0 0xfe8a0000 0x0 0x10000>;
--
2.25.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment