Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save macromorgan/02b160041aeb9750d9207d50826f6279 to your computer and use it in GitHub Desktop.
Save macromorgan/02b160041aeb9750d9207d50826f6279 to your computer and use it in GitHub Desktop.
DSI Panel Mainlining Effort for Anbernic RG353
From 498c9e0a673c171c19b24700a154f14ec3d58a9f Mon Sep 17 00:00:00 2001
From: Chris Morgan <macromorgan@hotmail.com>
Date: Tue, 2 Aug 2022 15:16:46 -0500
Subject: Add dsi and dsi-dphy to rk356x
Add the necessary devicetree bindings to the rk356x.dtsi file.
---
arch/arm64/boot/dts/rockchip/rk356x.dtsi | 80 ++++++++++++++++++++++++
1 file changed, 80 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index 319981c3e9f7..b4819201dc9b 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -699,6 +699,62 @@ 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>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <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>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ };
+ };
+ };
+
hdmi: hdmi@fe0a0000 {
compatible = "rockchip,rk3568-dw-hdmi";
reg = <0x0 0xfe0a0000 0x0 0x20000>;
@@ -1594,6 +1650,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
From 201e27fdcce3b23fe682d475482661af99d6019f Mon Sep 17 00:00:00 2001
From: Chris Morgan <macromorgan@hotmail.com>
Date: Tue, 2 Aug 2022 15:17:46 -0500
Subject: Add Devicetrees for Anbernic RG353 and RG503
Note that the RG503 is basically unloved in the past month, so it's
going to be way behind. A lot of stuff also doesn't work just yet.
---
arch/arm64/boot/dts/rockchip/Makefile | 2 +
.../dts/rockchip/rk3566-anbernic-rg353.dts | 1084 +++++++++++++++++
.../dts/rockchip/rk3566-anbernic-rg503.dts | 736 +++++++++++
3 files changed, 1822 insertions(+)
create mode 100755 arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353.dts
create mode 100755 arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg503.dts
diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index ef79a672804a..228b4ec4b773 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -57,6 +57,8 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rockpro64.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire-excavator.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399pro-rock-pi-n10.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-anbernic-rg353.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-anbernic-rg503.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-pinenote-v1.1.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-pinenote-v1.2.dtb
dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-a.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353.dts b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353.dts
new file mode 100755
index 000000000000..9a5fe328c1be
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353.dts
@@ -0,0 +1,1084 @@
+// 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"
+
+/ {
+ model = "Anbernic RK3566 RG353";
+ compatible = "anbernic,rg353", "rockchip,rk3566";
+
+ aliases {
+ mmc0 = &sdhci;
+ mmc1 = &sdmmc0;
+ mmc2 = &sdmmc1;
+ mmc3 = &sdmmc2;
+ };
+
+ chosen: chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ /* works with pending upstream patch */
+ adc-joystick {
+ compatible = "adc-joystick";
+ pinctrl-names = "default";
+ pinctrl-0 = <&joy_mux_en>;
+ io-channels = <&adc_mux 0>,
+ <&adc_mux 1>,
+ <&adc_mux 2>,
+ <&adc_mux 3>;
+ poll-interval = <60>;
+ #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>;
+ };
+ };
+
+ /* works */
+ adc_keys: adc-keys {
+ compatible = "adc-keys";
+ io-channels = <&saradc 0>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1800000>;
+ poll-interval = <60>;
+
+ mode-key {
+ label = "MODE";
+ linux,code = <BTN_MODE>;
+ press-threshold-microvolt = <1750>;
+ };
+ };
+
+ /* works */
+ adc_mux: adc-mux {
+ compatible = "io-channel-mux";
+ io-channels = <&saradc 3>;
+ io-channel-names = "parent";
+ settle-time-us = <100>;
+ #io-channel-cells = <1>;
+
+ mux-controls = <&gpio_mux>;
+ channels = "left_x", "right_x", "left_y", "right_y";
+ };
+
+ /* works */
+ backlight: backlight {
+ compatible = "pwm-backlight";
+ pwms = <&pwm4 0 25000 0>;
+ };
+
+ /* works */
+ gpio_keys: gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&btn_pins>;
+
+ sw1 {
+ gpios = <&gpio3 RK_PA1 GPIO_ACTIVE_LOW>;
+ label = "THUMBL";
+ linux,code = <BTN_THUMBL>;
+ };
+
+ sw2 {
+ gpios = <&gpio3 RK_PA2 GPIO_ACTIVE_LOW>;
+ label = "THUMBR";
+ linux,code = <BTN_THUMBR>;
+ };
+
+ sw3 {
+ gpios = <&gpio3 RK_PA3 GPIO_ACTIVE_LOW>;
+ label = "DPAD-UP";
+ linux,code = <BTN_DPAD_UP>;
+ };
+
+ sw4 {
+ gpios = <&gpio3 RK_PA4 GPIO_ACTIVE_LOW>;
+ label = "DPAD-DOWN";
+ linux,code = <BTN_DPAD_DOWN>;
+ };
+
+ sw5 {
+ gpios = <&gpio3 RK_PA5 GPIO_ACTIVE_LOW>;
+ label = "DPAD-LEFT";
+ linux,code = <BTN_DPAD_RIGHT>;
+ };
+
+ sw6 {
+ gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_LOW>;
+ label = "DPAD-RIGHT";
+ linux,code = <BTN_DPAD_LEFT>;
+ };
+
+ sw7 {
+ gpios = <&gpio3 RK_PA7 GPIO_ACTIVE_LOW>;
+ label = "VOLUMEUP";
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ sw8 {
+ gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>;
+ label = "VOLUMEDOWN";
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+
+ sw9 {
+ gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>;
+ label = "TL";
+ linux,code = <BTN_TL>;
+ };
+
+ sw10 {
+ gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>;
+ label = "TL2";
+ linux,code = <BTN_TL2>;
+ };
+
+ sw11 {
+ gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_LOW>;
+ label = "TR";
+ linux,code = <BTN_TR2>;
+ };
+
+ sw12 {
+ gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>;
+ label = "TR2";
+ linux,code = <BTN_TR>;
+ };
+
+ sw13 {
+ gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_LOW>;
+ label = "START";
+ linux,code = <BTN_START>;
+ };
+
+ sw14 {
+ gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_LOW>;
+ label = "SELECT";
+ linux,code = <BTN_SELECT>;
+ };
+
+ sw15 {
+ gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>;
+ label = "NORTH";
+ linux,code = <BTN_NORTH>;
+ };
+
+ sw16 {
+ gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_LOW>;
+ label = "WEST";
+ linux,code = <BTN_WEST>;
+ };
+
+ sw17 {
+ gpios = <&gpio3 RK_PC2 GPIO_ACTIVE_LOW>;
+ label = "EAST";
+ linux,code = <BTN_EAST>;
+ };
+
+ sw18 {
+ gpios = <&gpio3 RK_PC3 GPIO_ACTIVE_LOW>;
+ label = "SOUTH";
+ linux,code = <BTN_SOUTH>;
+ };
+ };
+
+ /* works with pending upstream patch */
+ gpio_mux: mux-controller {
+ compatible = "gpio-mux";
+ #mux-control-cells = <0>;
+
+ mux-gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_LOW>,
+ <&gpio0 RK_PB7 GPIO_ACTIVE_LOW>;
+ };
+
+ /* untested */
+ hdmi-con {
+ compatible = "hdmi-connector";
+ type = "c";
+
+ port {
+ hdmi_con_in: endpoint {
+ remote-endpoint = <&hdmi_out_con>;
+ };
+ };
+ };
+
+ /* works */
+ leds: gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&leds_gpio>;
+
+ green_led: led-0 {
+ gpios = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_POWER;
+ default-state = "on";
+ };
+
+ amber_led: led-1 {
+ gpios = <&gpio0 RK_PC6 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_CHARGING;
+ retain-state-suspended;
+ };
+
+ red_led: led-2 {
+ gpios = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_STATUS;
+ default-state = "off";
+ };
+ };
+
+ /* works */
+ rk817-sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "Analog";
+ 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>;
+ };
+ };
+
+ /* does not work yet */
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ clocks = <&rk817 1>;
+ clock-names = "ext_clock";
+ pinctrl-names = "default";
+ pinctrl-0 = <&wifi_enable_h>;
+ post-power-on-delay-ms = <200>;
+ reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_LOW>;
+ };
+
+ /* works */
+ 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";
+ };
+
+ /* works */
+ vcc3v3_lcd0_n: vcc3v3-lcd0-n {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_lcd0_n";
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&gpio0 RK_PC2 GPIO_ACTIVE_HIGH>;
+ vin-supply = <&vcc_3v3>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ /* unknown */
+ vcc_sd: vcc-sd {
+ regulator-always-on;
+ regulator-boot-on;
+ compatible = "regulator-fixed";
+ enable-active-low;
+ enable-gpio = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc_sd_h>;
+ regulator-name = "vcc_sd";
+ };
+
+ /* works */
+ vcc_sys: vcc_sys {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3800000>;
+ regulator-max-microvolt = <3800000>;
+ };
+
+ /* unknown */
+ vcc_wifi: vcc-wifi {
+ regulator-always-on;
+ regulator-boot-on;
+ compatible = "regulator-fixed";
+ enable-active-high;
+ enable-gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&vcc_wifi_h>;
+ regulator-name = "vcc_wifi";
+ };
+
+ /* works */
+ vibrator: pwm-vibrator {
+ compatible = "pwm-vibrator";
+ pwms = <&pwm5 0 1000000000 0>;
+ pwm-names = "enable";
+ };
+};
+
+/* unknown */
+&combphy1 {
+ status = "okay";
+};
+
+/* unknown */
+&combphy2 {
+ status = "okay";
+};
+
+/* works */
+&cpu0 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+/* works */
+&cpu1 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+/* works */
+&cpu2 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+/* works */
+&cpu3 {
+ cpu-supply = <&vdd_cpu>;
+};
+
+/* unclear, system unstable if some of these clocks aren't set */
+&cru {
+ assigned-clocks =
+ <&pmucru CLK_RTC_32K>, <&pmucru PLL_PPLL>,
+ <&pmucru PCLK_PMU>, <&cru PLL_CPLL>,
+ <&cru PLL_GPLL>,
+ <&cru ACLK_BUS>, <&cru PCLK_BUS>,
+ <&cru ACLK_TOP_HIGH>, <&cru ACLK_TOP_LOW>,
+ <&cru HCLK_TOP>, <&cru PCLK_TOP>,
+ <&cru ACLK_PERIMID>, <&cru HCLK_PERIMID>,
+ <&cru PLL_NPLL>,
+ <&cru ACLK_PIPE>, <&cru PCLK_PIPE>,
+ <&cru ACLK_VOP>;
+ assigned-clock-rates =
+ <32768>, <200000000>,
+ <100000000>, <1000000000>,
+ <1188000000>,
+ <150000000>, <100000000>,
+ <500000000>, <400000000>,
+ <150000000>, <100000000>,
+ <300000000>, <150000000>,
+ <1200000000>,
+ <400000000>, <100000000>,
+ <500000000>;
+};
+
+
+/* partially working */
+&dsi0 {
+ status = "okay";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dsi_in: port@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ dsi0_in_vp1: endpoint {
+ remote-endpoint = <&vp1_out_dsi0>;
+ };
+ };
+
+ dsi0_out: port@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ 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_gpio>;
+ reset-gpios = <&gpio4 RK_PA0 GPIO_ACTIVE_LOW>;
+ vdd-supply = <&vcc3v3_lcd0_n>;
+
+ port {
+ mipi_in_panel: endpoint {
+ remote-endpoint = <&mipi_out_panel>;
+ };
+ };
+ };
+};
+
+/*&dsi0_in {
+ dsi0_in_vp1: endpoint {
+ remote-endpoint = <&vp1_out_dsi0>;
+ };
+};*/
+
+/* partially working */
+&mipi_dphy0 {
+ status = "okay";
+};
+
+/* untested */
+&gpu {
+ mali-supply = <&vdd_gpu>;
+ status = "okay";
+};
+
+/* untested */
+&hdmi {
+ status = "okay";
+};
+
+/* untested */
+&hdmi_in {
+ hdmi_in_vp1: endpoint {
+ remote-endpoint = <&vp1_out_hdmi>;
+ };
+};
+
+/* untested */
+&hdmi_out {
+ hdmi_out_con: endpoint {
+ remote-endpoint = <&hdmi_con_in>;
+ };
+};
+
+/* does not work */
+&hdmi_sound {
+ status = "okay";
+};
+
+/* working */
+&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>;
+ regulator-name = "vdd_cpu";
+ regulator-min-microvolt = <712500>;
+ regulator-max-microvolt = <1390000>;
+ regulator-init-microvolt = <900000>;
+ regulator-ramp-delay = <2300>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc_sys>;
+ fcs,suspend-voltage-selector = <1>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ /* This hardware is physically present but unused. */
+ cw2015@62 {
+ compatible = "cellwise,cw2015";
+ reg = <0x62>;
+ status = "disabled";
+ };
+};
+
+/* mystery device at address 3c */
+&i2c1 {
+ status = "okay";
+};
+
+/* touchscreen not set up at address 1a */
+&i2c2 {
+ pintctrl-names = "default";
+ pinctrl-0 = <&i2c2m1_xfer>;
+ status = "okay";
+};
+
+/* unknown */
+&i2s0_8ch {
+ status = "okay";
+};
+
+/* working */
+&i2s1_8ch {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2s1m0_sclktx
+ &i2s1m0_lrcktx
+ &i2s1m0_sdi0
+ &i2s1m0_sdo0>;
+ rockchip,trcm-sync-tx-only;
+ status = "okay";
+};
+
+&pinctrl {
+
+ btns {
+ btn_pins: btn-pins {
+ 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_PA7 RK_FUNC_GPIO &pcfg_pull_up>,
+ <3 RK_PB0 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_PB7 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>;
+ };
+ };
+
+ gpio-leds {
+ leds_gpio: leds-gpio {
+ 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>;
+ };
+ };
+
+ lcd {
+ lcd_rst_gpio: lcd-rst-gpio {
+ rockchip,pins =
+ <4 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ audio-amplifier {
+ spk_amp_enable_h: spk-amp-enable-h {
+ rockchip,pins =
+ <4 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
+
+ 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>;
+ };
+ };
+
+ vcc-sd {
+ vcc_sd_h: vcc-sd-h {
+ rockchip,pins =
+ <0 RK_PA5 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>;
+ };
+ };
+};
+
+/* unknown */
+&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>;
+};
+
+/* working */
+&pwm4 {
+ status = "okay";
+};
+
+/* working */
+&pwm5 {
+ status = "okay";
+};
+
+/* working */
+&saradc {
+ vref-supply = <&vcc_1v8>;
+ status = "okay";
+};
+
+/* untested */
+&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";
+};
+
+/* working */
+&sdmmc0 {
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ supports-sd;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vccio_sd>;
+ status = "okay";
+};
+
+/* working */
+&sdmmc1 {
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ cd-gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk &sdmmc1_det>;
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ supports-sd;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vcc1v8_dvp>;
+ status = "okay";
+};
+
+/* not working */
+&sdmmc2 {
+ bus-width = <4>;
+ cap-sd-highspeed;
+ cap-sdio-irq;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc2m0_bus4 &sdmmc2m0_cmd &sdmmc2m0_clk>;
+ keep-power-in-suspend;
+ supports-sdio;
+ disable-wp;
+ non-removable;
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ mmc-pwrseq = <&sdio_pwrseq>;
+ vmmc-supply = <&vcc_sd>;
+ vqmmc-supply = <&vcca1v8_pmu>;
+ status = "okay";
+
+ rtl8821cs: wifi@1 {
+ compatible = "realtek,rtl8821cs";
+ enable-gpios = <&gpio4 2 GPIO_ACTIVE_HIGH>;
+ host-wake-gpios = <&gpio4 1 GPIO_ACTIVE_HIGH>;
+ };
+
+};
+
+/* working */
+&tsadc {
+ rockchip,hw-tshut-mode = <1>;
+ rockchip,hw-tshut-polarity = <0>;
+ status = "okay";
+};
+
+/* not working */
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1m1_xfer &uart1m1_ctsn &uart1m1_rtsn>;
+ uart-has-rtscts;
+ status = "okay";
+
+ bluetooth {
+ compatible = "realtek,rtl8821cs-bt", "realtek,rtl8822cs-bt";
+ device-wake-gpios = <&gpio4 4 GPIO_ACTIVE_HIGH>;
+ enable-gpios = <&gpio4 3 GPIO_ACTIVE_HIGH>;
+ host-wake-gpios = <&gpio4 5 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+/* working */
+&uart2 {
+ status = "okay";
+};
+
+/* usb partially working */
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_host0_ohci {
+ status = "okay";
+};
+
+&usb_host0_xhci {
+ phys = <&usb2phy0_otg>;
+ phy-names = "usb2-phy";
+ snps,dis_enblslpm_quirk;
+ snps,dis-u2-freeclk-exists-quirk;
+ snps,dis-del-phy-power-chg-quirk;
+ snps,dis-tx-ipgap-linecheck-quirk;
+ status = "okay";
+};
+
+&usb_host1_ehci {
+ status = "okay";
+};
+
+&usb_host1_ohci {
+ status = "okay";
+};
+
+&usb_host1_xhci {
+ phys = <&usb2phy1_host>, <&combphy1 PHY_TYPE_USB3>;
+ phy-names = "usb2-phy", "usb3-phy";
+ status = "okay";
+};
+
+&usb2phy0 {
+ status = "okay";
+};
+
+&usb2phy1 {
+ status = "okay";
+};
+
+&usb2phy0_host {
+ status = "okay";
+};
+
+&usb2phy0_otg {
+ status = "okay";
+};
+
+&usb2phy1_host {
+ status = "okay";
+};
+
+&usb2phy1_otg {
+ status = "okay";
+};
+
+/* video out partially working */
+&vop {
+ assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>;
+ assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>;
+ status = "okay";
+};
+
+&vop_mmu {
+ status = "okay";
+};
+
+&vp1 {
+ vp1_out_dsi0: endpoint@ROCKCHIP_VOP2_EP_MIPI0 {
+ reg = <ROCKCHIP_VOP2_EP_MIPI0>;
+ remote-endpoint = <&dsi0_in_vp1>;
+ };
+
+ vp1_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
+ reg = <ROCKCHIP_VOP2_EP_HDMI0>;
+ remote-endpoint = <&hdmi_in_vp1>;
+ };
+};
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 100755
index 000000000000..4f4d1b80c959
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg503.dts
@@ -0,0 +1,736 @@
+// 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"
+
+/ {
+ model = "Anbernic RK3566 RG503";
+ compatible = "anbernic,rg503", "rockchip,rk3566";
+
+ aliases {
+ mmc0 = &sdmmc0;
+ mmc1 = &sdmmc1;
+ };
+
+ chosen: chosen {
+ stdout-path = "serial2:1500000n8";
+ };
+
+ adc-joystick {
+ compatible = "adc-joystick";
+ pinctrl-names = "default";
+ pinctrl-0 = <&joy_mux_en>;
+ io-channels = <&adc_mux 0>,
+ <&adc_mux 1>,
+ <&adc_mux 2>,
+ <&adc_mux 3>;
+ poll-interval = <60>;
+ #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>;
+
+ mode-key {
+ label = "MODE";
+ linux,code = <BTN_MODE>;
+ press-threshold-microvolt = <1750>;
+ };
+ };
+
+ adc_mux: adc-mux {
+ compatible = "io-channel-mux";
+ io-channels = <&saradc 3>;
+ io-channel-names = "parent";
+ settle-time-us = <100>;
+ #io-channel-cells = <1>;
+
+ mux-controls = <&gpio_mux>;
+ channels = "left_x", "right_x", "left_y", "right_y";
+ };
+
+ gpio_keys: gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&btn_pins>;
+
+ sw1 {
+ gpios = <&gpio3 RK_PA1 GPIO_ACTIVE_LOW>;
+ label = "THUMBL";
+ linux,code = <BTN_THUMBL>;
+ };
+
+ sw2 {
+ gpios = <&gpio3 RK_PA2 GPIO_ACTIVE_LOW>;
+ label = "THUMBR";
+ linux,code = <BTN_THUMBR>;
+ };
+
+ sw3 {
+ gpios = <&gpio3 RK_PA3 GPIO_ACTIVE_LOW>;
+ label = "DPAD-UP";
+ linux,code = <BTN_DPAD_UP>;
+ };
+
+ sw4 {
+ gpios = <&gpio3 RK_PA4 GPIO_ACTIVE_LOW>;
+ label = "DPAD-DOWN";
+ linux,code = <BTN_DPAD_DOWN>;
+ };
+
+ sw5 {
+ gpios = <&gpio3 RK_PA5 GPIO_ACTIVE_LOW>;
+ label = "DPAD-LEFT";
+ linux,code = <BTN_DPAD_LEFT>;
+ };
+
+ sw6 {
+ gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_LOW>;
+ label = "DPAD-RIGHT";
+ linux,code = <BTN_DPAD_RIGHT>;
+ };
+
+ sw7 {
+ gpios = <&gpio3 RK_PA7 GPIO_ACTIVE_LOW>;
+ label = "VOLUMEUP";
+ linux,code = <KEY_VOLUMEUP>;
+ };
+
+ sw8 {
+ gpios = <&gpio3 RK_PB0 GPIO_ACTIVE_LOW>;
+ label = "VOLUMEDOWN";
+ linux,code = <KEY_VOLUMEDOWN>;
+ };
+
+ sw9 {
+ gpios = <&gpio3 RK_PB1 GPIO_ACTIVE_LOW>;
+ label = "TL";
+ linux,code = <BTN_TL>;
+ };
+
+ sw10 {
+ gpios = <&gpio3 RK_PB2 GPIO_ACTIVE_LOW>;
+ label = "TL2";
+ linux,code = <BTN_TL2>;
+ };
+
+ sw11 {
+ gpios = <&gpio3 RK_PB3 GPIO_ACTIVE_LOW>;
+ label = "TR";
+ linux,code = <BTN_TR>;
+ };
+
+ sw12 {
+ gpios = <&gpio3 RK_PB4 GPIO_ACTIVE_LOW>;
+ label = "TR2";
+ linux,code = <BTN_TR2>;
+ };
+
+ sw13 {
+ gpios = <&gpio3 RK_PB5 GPIO_ACTIVE_LOW>;
+ label = "START";
+ linux,code = <BTN_START>;
+ };
+
+ sw14 {
+ gpios = <&gpio3 RK_PB6 GPIO_ACTIVE_LOW>;
+ label = "SELECT";
+ linux,code = <BTN_SELECT>;
+ };
+
+ sw15 {
+ gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>;
+ label = "NORTH";
+ linux,code = <BTN_NORTH>;
+ };
+
+ sw16 {
+ gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_LOW>;
+ label = "WEST";
+ linux,code = <BTN_WEST>;
+ };
+
+ sw17 {
+ gpios = <&gpio3 RK_PC2 GPIO_ACTIVE_LOW>;
+ label = "EAST";
+ linux,code = <BTN_EAST>;
+ };
+
+ sw18 {
+ gpios = <&gpio3 RK_PC3 GPIO_ACTIVE_LOW>;
+ label = "SOUTH";
+ linux,code = <BTN_SOUTH>;
+ };
+ };
+
+ gpio_mux: mux-controller {
+ compatible = "gpio-mux";
+ #mux-control-cells = <0>;
+
+ mux-gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_LOW>,
+ <&gpio0 RK_PB7 GPIO_ACTIVE_LOW>;
+ };
+
+ leds: gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&leds_gpio>;
+
+ green_led: led-0 {
+ gpios = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_POWER;
+ default-state = "on";
+ };
+
+ amber_led: led-1 {
+ gpios = <&gpio0 RK_PC6 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_AMBER>;
+ function = LED_FUNCTION_CHARGING;
+ retain-state-suspended;
+ };
+
+ red_led: led-2 {
+ gpios = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
+ color = <LED_COLOR_ID_RED>;
+ function = LED_FUNCTION_STATUS;
+ default-state = "off";
+ };
+ };
+
+ spi_gpio: spi-gpio {
+ compatible = "spi-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcd_spi_gpio>;
+ #address-cells = <0x1>;
+ #size-cells = <0x0>;
+
+ 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 = <1>;
+
+ spidev@0 {
+ reg = <0>;
+ compatible = "rohm,dh2228fv";
+ spi-max-frequency = <500000>;
+ spi-3wire;
+ };
+ };
+
+ vcc3v3_lcd0_n: vcc3v3-lcd0-n {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3_lcd0_n";
+ regulator-boot-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ enable-active-high;
+ gpio = <&gpio0 RK_PC2 GPIO_ACTIVE_HIGH>;
+ vin-supply = <&vcc_3v3>;
+
+ /*regulator-state-mem {
+ regulator-off-in-suspend;
+ };*/
+ regulator-always-on;
+
+ };
+
+ vcc_sys: vcc_sys {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc_sys";
+ regulator-always-on;
+ regulator-boot-on;
+ regulator-min-microvolt = <3800000>;
+ regulator-max-microvolt = <3800000>;
+ };
+
+ vibrator: pwm-vibrator {
+ compatible = "pwm-vibrator";
+ pwms = <&pwm5 0 1000000000 0>;
+ pwm-names = "enable";
+ };
+};
+
+&combphy1 {
+ status = "okay";
+};
+
+&combphy2 {
+ 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";
+};
+
+&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-cells = <1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pmic_int_l>;
+ rockchip,system-power-controller;
+ 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>;
+ regulator-name = "vdd_cpu";
+ regulator-min-microvolt = <712500>;
+ regulator-max-microvolt = <1390000>;
+ regulator-init-microvolt = <900000>;
+ regulator-ramp-delay = <2300>;
+ regulator-always-on;
+ regulator-boot-on;
+ vin-supply = <&vcc_sys>;
+ fcs,suspend-voltage-selector = <1>;
+
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+};
+
+&i2c1 {
+ status = "okay";
+};
+
+&pinctrl {
+
+ btns {
+ btn_pins: btn-pins {
+ 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_PA7 RK_FUNC_GPIO &pcfg_pull_up>,
+ <3 RK_PB0 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_PB7 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>;
+ };
+ };
+
+ gpio-leds {
+ leds_gpio: leds-gpio {
+ 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>;
+ };
+ };
+
+ lcd {
+ lcd_rst_gpio: lcd-rst-gpio {
+ rockchip,pins =
+ <4 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ lcd_enable_gpio: lcd-enable-gpio {
+ rockchip,pins =
+ <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+
+ lcd_spi_gpio: lcd-spi-gpio {
+ 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>;
+ };
+ };
+
+ pmic {
+ pmic_int_l: pmic-int-l {
+ rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+ };
+ };
+};
+
+&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-mmc-highspeed;
+ cap-sd-highspeed;
+ cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ supports-sd;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vccio_sd>;
+ status = "okay";
+};
+
+&sdmmc1 {
+ bus-width = <4>;
+ cap-mmc-highspeed;
+ cap-sd-highspeed;
+ cd-gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>;
+ disable-wp;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk &sdmmc1_det>;
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ supports-sd;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vcc1v8_dvp>;
+ status = "okay";
+};
+
+&tsadc {
+ rockchip,hw-tshut-mode = <1>;
+ rockchip,hw-tshut-polarity = <0>;
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_xfer>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1m0_xfer &uart1m0_ctsn>;
+ status = "okay";
+ uart-has-rtscts;
+};
+
+&uart2 {
+ status = "okay";
+};
+
+&usb_host0_ehci {
+ status = "okay";
+};
+
+&usb_host0_ohci {
+ status = "okay";
+};
+
+&usb_host1_ehci {
+ status = "okay";
+};
+
+&usb_host1_ohci {
+ status = "okay";
+};
+
+&usb2phy0 {
+ status = "okay";
+};
+
+&usb2phy1 {
+ status = "okay";
+};
+
+&usb2phy0_host {
+ status = "okay";
+};
+
+&usb2phy0_otg {
+ status = "okay";
+};
+
+&usb2phy1_host {
+ status = "okay";
+};
+
+&usb2phy1_otg {
+ status = "okay";
+};
--
2.25.1
From 019abab6ca23ae5bd58d5636df460834e54e7ffc Mon Sep 17 00:00:00 2001
From: Chris Morgan <macromorgan@hotmail.com>
Date: Tue, 2 Aug 2022 14:03:48 -0500
Subject: Add Panel Driver for RG353
Note this is still a massive WIP, and without a datasheet I have
to use the timings in the BSP devicetree (which may not be correct).
Also, without a part number I don't even know what to call it yet.
---
drivers/gpu/drm/panel/Kconfig | 8 +
drivers/gpu/drm/panel/Makefile | 1 +
drivers/gpu/drm/panel/panel-anbernic-rg353.c | 485 +++++++++++++++++++
3 files changed, 494 insertions(+)
create mode 100644 drivers/gpu/drm/panel/panel-anbernic-rg353.c
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 38799effd00a..2a0078676174 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
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 42a7ab54234b..9bd9919e1466 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
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..011420f80e34
--- /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;
+ }
+
+ msleep(20);
+
+ 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 + 18,
+ .vsync_end = 480 + 18 + 2,
+ .vtotal = 480 + 18 + 2 + 28,
+ .clock = 50000,
+ .width_mm = 72,
+ .height_mm = 53,
+};
+
+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;
+ 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");
--
2.25.1
From 2df76864b3b7115744e1f6f4fdb1ed5e3f5ea238 Mon Sep 17 00:00:00 2001
From: Chris Morgan <macromorgan@hotmail.com>
Date: Tue, 2 Aug 2022 14:05:57 -0500
Subject: Add support for the rk356x for the dw-mipi-dsi-rockchip
driver
I don't know if this is fully correct. The addition of the hclk
didn't seem to do anything, so that may be optional.
---
.../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 72 ++++++++++++++++++-
1 file changed, 70 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
index 110e83aad9bb..f13190cf7234 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
@@ -179,6 +179,22 @@
#define RK3399_TXRX_SRC_SEL_ISP0 BIT(4)
#define RK3399_TXRX_TURNREQUEST GENMASK(3, 0)
+#define RK3568_GRF_VO_CON2 0x0368
+#define RK3568_DSI0_SKEWCALHS (0x1f << 11)
+#define RK3568_DSI0_FORCETXSTOPMODE (0xf << 4)
+#define RK3568_DSI0_TURNDISABLE BIT(2)
+#define RK3568_DSI0_FORCERXMODE BIT(0)
+
+/* note these registers do not appear in the datasheet, they are
+ * however present in the BSP driver which is where these values
+ * come from. Name GRF_VO_CON3 is assumed.
+ */
+#define RK3568_GRF_VO_CON3 0x36c
+#define RK3568_DSI1_SKEWCALHS (0x1f << 11)
+#define RK3568_DSI1_FORCETXSTOPMODE (0xf << 4)
+#define RK3568_DSI1_TURNDISABLE BIT(2)
+#define RK3568_DSI1_FORCERXMODE BIT(0)
+
#define HIWORD_UPDATE(val, mask) (val | (mask) << 16)
enum {
@@ -239,6 +255,7 @@ struct dw_mipi_dsi_rockchip {
struct regmap *grf_regmap;
struct clk *pclk;
+ struct clk *hclk;
struct clk *pllref_clk;
struct clk *grf_clk;
struct clk *phy_cfg_clk;
@@ -735,8 +752,9 @@ static void dw_mipi_dsi_rockchip_config(struct dw_mipi_dsi_rockchip *dsi)
static void dw_mipi_dsi_rockchip_set_lcdsel(struct dw_mipi_dsi_rockchip *dsi,
int mux)
{
- regmap_write(dsi->grf_regmap, dsi->cdata->lcdsel_grf_reg,
- mux ? dsi->cdata->lcdsel_lit : dsi->cdata->lcdsel_big);
+ if (dsi->cdata->lcdsel_grf_reg < 0)
+ regmap_write(dsi->grf_regmap, dsi->cdata->lcdsel_grf_reg,
+ mux ? dsi->cdata->lcdsel_lit : dsi->cdata->lcdsel_big);
}
static int
@@ -963,6 +981,8 @@ static int dw_mipi_dsi_rockchip_bind(struct device *dev,
DRM_DEV_ERROR(dev, "Failed to create drm encoder\n");
goto out_pll_clk;
}
+ rockchip_drm_encoder_set_crtc_endpoint_id(&dsi->encoder,
+ dev->of_node, 0, 0);
ret = dw_mipi_dsi_bind(dsi->dmd, &dsi->encoder.encoder);
if (ret) {
@@ -1120,6 +1140,9 @@ static int dw_mipi_dsi_dphy_init(struct phy *phy)
goto err_graph;
if (dsi->cdata->dphy_rx_init) {
+ ret = clk_prepare_enable(dsi->hclk);
+ if (ret < 0)
+ goto err_init;
ret = clk_prepare_enable(dsi->pclk);
if (ret < 0)
goto err_init;
@@ -1127,12 +1150,14 @@ static int dw_mipi_dsi_dphy_init(struct phy *phy)
ret = clk_prepare_enable(dsi->grf_clk);
if (ret) {
clk_disable_unprepare(dsi->pclk);
+ clk_disable_unprepare(dsi->hclk);
goto err_init;
}
ret = dsi->cdata->dphy_rx_init(phy);
clk_disable_unprepare(dsi->grf_clk);
clk_disable_unprepare(dsi->pclk);
+ clk_disable_unprepare(dsi->hclk);
if (ret < 0)
goto err_init;
}
@@ -1199,6 +1224,12 @@ static int dw_mipi_dsi_dphy_power_on(struct phy *phy)
return ret;
}
+ ret = clk_prepare_enable(dsi->hclk);
+ if (ret) {
+ DRM_DEV_ERROR(dsi->dev, "Failed to enable hclk: %d\n", ret);
+ goto err_hclk;
+ }
+
ret = clk_prepare_enable(dsi->pclk);
if (ret) {
DRM_DEV_ERROR(dsi->dev, "Failed to enable pclk: %d\n", ret);
@@ -1252,6 +1283,8 @@ static int dw_mipi_dsi_dphy_power_on(struct phy *phy)
err_grf_clk:
clk_disable_unprepare(dsi->pclk);
err_pclk:
+ clk_disable_unprepare(dsi->hclk);
+err_hclk:
pm_runtime_put(dsi->dev);
return ret;
}
@@ -1275,6 +1308,7 @@ static int dw_mipi_dsi_dphy_power_off(struct phy *phy)
clk_disable_unprepare(dsi->grf_clk);
clk_disable_unprepare(dsi->pclk);
+ clk_disable_unprepare(dsi->hclk);
pm_runtime_put(dsi->dev);
@@ -1371,6 +1405,13 @@ static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev)
return ret;
}
+ dsi->hclk = devm_clk_get_optional(dev, "hclk");
+ if (IS_ERR(dsi->hclk)) {
+ ret = PTR_ERR(dsi->hclk);
+ DRM_DEV_ERROR(dev, "Unable to get hclk: %d\n", ret);
+ return ret;
+ }
+
dsi->pllref_clk = devm_clk_get(dev, "ref");
if (IS_ERR(dsi->pllref_clk)) {
if (dsi->phy) {
@@ -1612,6 +1653,30 @@ static const struct rockchip_dw_dsi_chip_data rk3399_chip_data[] = {
{ /* sentinel */ }
};
+static const struct rockchip_dw_dsi_chip_data rk3568_chip_data[] = {
+ {
+ .reg = 0xfe060000,
+ .lcdsel_grf_reg = -1,
+ .lanecfg1_grf_reg = RK3568_GRF_VO_CON2,
+ .lanecfg1 = HIWORD_UPDATE(0, RK3568_DSI0_SKEWCALHS |
+ RK3568_DSI0_FORCETXSTOPMODE |
+ RK3568_DSI0_TURNDISABLE |
+ RK3568_DSI0_FORCERXMODE),
+ .max_data_lanes = 4,
+ },
+ {
+ .reg = 0xfe070000,
+ .lcdsel_grf_reg = -1,
+ .lanecfg1_grf_reg = RK3568_GRF_VO_CON3,
+ .lanecfg1 = HIWORD_UPDATE(0, RK3568_DSI1_SKEWCALHS |
+ RK3568_DSI1_FORCETXSTOPMODE |
+ RK3568_DSI1_TURNDISABLE |
+ RK3568_DSI1_FORCERXMODE),
+ .max_data_lanes = 4,
+ },
+ { /* sentinel */ }
+};
+
static const struct of_device_id dw_mipi_dsi_rockchip_dt_ids[] = {
{
.compatible = "rockchip,px30-mipi-dsi",
@@ -1622,6 +1687,9 @@ static const struct of_device_id dw_mipi_dsi_rockchip_dt_ids[] = {
}, {
.compatible = "rockchip,rk3399-mipi-dsi",
.data = &rk3399_chip_data,
+ }, {
+ .compatible = "rockchip,rk3568-mipi-dsi",
+ .data = &rk3568_chip_data,
},
{ /* sentinel */ }
};
--
2.25.1
From 570ba28763cad10eca27c337c9d7deae88779f09 Mon Sep 17 00:00:00 2001
From: Chris Morgan <macromorgan@hotmail.com>
Date: Tue, 2 Aug 2022 14:07:29 -0500
Subject: Add rk356x support to phy-rockchip-inno-dsidphy
Not sure if this is right, but my attempt at adding the rk356x
to the dphy.
---
.../phy/rockchip/phy-rockchip-inno-dsidphy.c | 220 +++++++++++++-----
1 file changed, 166 insertions(+), 54 deletions(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
index 630e01b5c19b..6a0c21803c09 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
@@ -84,9 +84,25 @@
#define DATA_LANE_0_SKEW_PHASE_MASK GENMASK(2, 0)
#define DATA_LANE_0_SKEW_PHASE(x) UPDATE(x, 2, 0)
/* Analog Register Part: reg08 */
+#define PLL_POST_DIV_ENABLE_MASK BIT(5)
+#define PLL_POST_DIV_ENABLE BIT(5)
#define SAMPLE_CLOCK_DIRECTION_MASK BIT(4)
#define SAMPLE_CLOCK_DIRECTION_REVERSE BIT(4)
#define SAMPLE_CLOCK_DIRECTION_FORWARD 0
+#define LOWFRE_EN_MASK BIT(5)
+#define PLL_OUTPUT_FREQUENCY_DIV_BY_1 0
+#define PLL_OUTPUT_FREQUENCY_DIV_BY_2 1
+/* Analog Register Part: reg0b */
+#define CLOCK_LANE_VOD_RANGE_SET_MASK GENMASK(3, 0)
+#define CLOCK_LANE_VOD_RANGE_SET(x) UPDATE(x, 3, 0)
+#define VOD_MIN_RANGE 0x1
+#define VOD_MID_RANGE 0x3
+#define VOD_BIG_RANGE 0x7
+#define VOD_MAX_RANGE 0xf
+/* Analog Register Part: reg1E */
+#define PLL_MODE_SEL_MASK GENMASK(6, 5)
+#define PLL_MODE_SEL_LVDS_MODE 0
+#define PLL_MODE_SEL_MIPI_MODE BIT(5)
/* Digital Register Part: reg00 */
#define REG_DIG_RSTN_MASK BIT(0)
#define REG_DIG_RSTN_NORMAL BIT(0)
@@ -102,20 +118,22 @@
#define T_LPX_CNT_MASK GENMASK(5, 0)
#define T_LPX_CNT(x) UPDATE(x, 5, 0)
/* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg06 */
+#define T_HS_ZERO_CNT_HI_MASK BIT(7)
+#define T_HS_ZERO_CNT_HI(x) UPDATE(x, 7, 7)
#define T_HS_PREPARE_CNT_MASK GENMASK(6, 0)
#define T_HS_PREPARE_CNT(x) UPDATE(x, 6, 0)
/* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg07 */
-#define T_HS_ZERO_CNT_MASK GENMASK(5, 0)
-#define T_HS_ZERO_CNT(x) UPDATE(x, 5, 0)
+#define T_HS_ZERO_CNT_LO_MASK GENMASK(5, 0)
+#define T_HS_ZERO_CNT_LO(x) UPDATE(x, 5, 0)
/* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg08 */
#define T_HS_TRAIL_CNT_MASK GENMASK(6, 0)
#define T_HS_TRAIL_CNT(x) UPDATE(x, 6, 0)
/* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg09 */
-#define T_HS_EXIT_CNT_MASK GENMASK(4, 0)
-#define T_HS_EXIT_CNT(x) UPDATE(x, 4, 0)
+#define T_HS_EXIT_CNT_LO_MASK GENMASK(4, 0)
+#define T_HS_EXIT_CNT_LO(x) UPDATE(x, 4, 0)
/* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg0a */
-#define T_CLK_POST_CNT_MASK GENMASK(3, 0)
-#define T_CLK_POST_CNT(x) UPDATE(x, 3, 0)
+#define T_CLK_POST_CNT_LO_MASK GENMASK(3, 0)
+#define T_CLK_POST_CNT_LO(x) UPDATE(x, 3, 0)
/* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg0c */
#define LPDT_TX_PPI_SYNC_MASK BIT(2)
#define LPDT_TX_PPI_SYNC_ENABLE BIT(2)
@@ -129,9 +147,13 @@
#define T_CLK_PRE_CNT_MASK GENMASK(3, 0)
#define T_CLK_PRE_CNT(x) UPDATE(x, 3, 0)
/* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg10 */
+#define T_CLK_POST_CNT_HI_MASK GENMASK(7, 6)
+#define T_CLK_POST_CNT_HI(x) UPDATE(x, 7, 6)
#define T_TA_GO_CNT_MASK GENMASK(5, 0)
#define T_TA_GO_CNT(x) UPDATE(x, 5, 0)
/* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg11 */
+#define T_HS_EXIT_CNT_HI_MASK BIT(6)
+#define T_HS_EXIT_CNT_HI(x) UPDATE(x, 6, 6)
#define T_TA_SURE_CNT_MASK GENMASK(5, 0)
#define T_TA_SURE_CNT(x) UPDATE(x, 5, 0)
/* Clock/Data0/Data1/Data2/Data3 Lane Register Part: reg12 */
@@ -169,11 +191,23 @@
#define DSI_PHY_STATUS 0xb0
#define PHY_LOCK BIT(0)
+enum phy_max_rate {
+ MAX_1GHZ,
+ MAX_2_5GHZ,
+};
+
+struct inno_video_phy_plat_data {
+ const struct inno_mipi_dphy_timing *inno_mipi_dphy_timing_table;
+ const unsigned int num_timings;
+ enum phy_max_rate max_rate;
+};
+
struct inno_dsidphy {
struct device *dev;
struct clk *ref_clk;
struct clk *pclk_phy;
struct clk *pclk_host;
+ const struct inno_video_phy_plat_data *pdata;
void __iomem *phy_base;
void __iomem *host_base;
struct reset_control *rst;
@@ -200,6 +234,53 @@ enum {
REGISTER_PART_LVDS,
};
+struct inno_mipi_dphy_timing {
+ unsigned long rate;
+ u8 lpx;
+ u8 hs_prepare;
+ u8 clk_lane_hs_zero;
+ u8 data_lane_hs_zero;
+ u8 hs_trail;
+};
+
+static const
+struct inno_mipi_dphy_timing inno_mipi_dphy_timing_table_max_1ghz[] = {
+ { 110000000, 0x0, 0x20, 0x16, 0x02, 0x22},
+ { 150000000, 0x0, 0x06, 0x16, 0x03, 0x45},
+ { 200000000, 0x0, 0x18, 0x17, 0x04, 0x0b},
+ { 250000000, 0x0, 0x05, 0x17, 0x05, 0x16},
+ { 300000000, 0x0, 0x51, 0x18, 0x06, 0x2c},
+ { 400000000, 0x0, 0x64, 0x19, 0x07, 0x33},
+ { 500000000, 0x0, 0x20, 0x1b, 0x07, 0x4e},
+ { 600000000, 0x0, 0x6a, 0x1d, 0x08, 0x3a},
+ { 700000000, 0x0, 0x3e, 0x1e, 0x08, 0x6a},
+ { 800000000, 0x0, 0x21, 0x1f, 0x09, 0x29},
+ {1000000000, 0x0, 0x09, 0x20, 0x09, 0x27},
+};
+
+static const
+struct inno_mipi_dphy_timing inno_mipi_dphy_timing_table_max_2_5ghz[] = {
+ { 110000000, 0x02, 0x7f, 0x16, 0x02, 0x02},
+ { 150000000, 0x02, 0x7f, 0x16, 0x03, 0x02},
+ { 200000000, 0x02, 0x7f, 0x17, 0x04, 0x02},
+ { 250000000, 0x02, 0x7f, 0x17, 0x05, 0x04},
+ { 300000000, 0x02, 0x7f, 0x18, 0x06, 0x04},
+ { 400000000, 0x03, 0x7e, 0x19, 0x07, 0x04},
+ { 500000000, 0x03, 0x7c, 0x1b, 0x07, 0x08},
+ { 600000000, 0x03, 0x70, 0x1d, 0x08, 0x10},
+ { 700000000, 0x05, 0x40, 0x1e, 0x08, 0x30},
+ { 800000000, 0x05, 0x02, 0x1f, 0x09, 0x30},
+ {1000000000, 0x05, 0x08, 0x20, 0x09, 0x30},
+ {1200000000, 0x06, 0x03, 0x32, 0x14, 0x0f},
+ {1400000000, 0x09, 0x03, 0x32, 0x14, 0x0f},
+ {1600000000, 0x0d, 0x42, 0x36, 0x0e, 0x0f},
+ {1800000000, 0x0e, 0x47, 0x7a, 0x0e, 0x0f},
+ {2000000000, 0x11, 0x64, 0x7a, 0x0e, 0x0b},
+ {2200000000, 0x13, 0x64, 0x7e, 0x15, 0x0b},
+ {2400000000, 0x13, 0x33, 0x7f, 0x15, 0x6a},
+ {2500000000, 0x15, 0x54, 0x7f, 0x15, 0x6a},
+};
+
static inline struct inno_dsidphy *hw_to_inno(struct clk_hw *hw)
{
return container_of(hw, struct inno_dsidphy, pll.hw);
@@ -290,31 +371,15 @@ static unsigned long inno_dsidphy_pll_calc_rate(struct inno_dsidphy *inno,
static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
{
struct phy_configure_opts_mipi_dphy *cfg = &inno->dphy_cfg;
- const struct {
- unsigned long rate;
- u8 hs_prepare;
- u8 clk_lane_hs_zero;
- u8 data_lane_hs_zero;
- u8 hs_trail;
- } timings[] = {
- { 110000000, 0x20, 0x16, 0x02, 0x22},
- { 150000000, 0x06, 0x16, 0x03, 0x45},
- { 200000000, 0x18, 0x17, 0x04, 0x0b},
- { 250000000, 0x05, 0x17, 0x05, 0x16},
- { 300000000, 0x51, 0x18, 0x06, 0x2c},
- { 400000000, 0x64, 0x19, 0x07, 0x33},
- { 500000000, 0x20, 0x1b, 0x07, 0x4e},
- { 600000000, 0x6a, 0x1d, 0x08, 0x3a},
- { 700000000, 0x3e, 0x1e, 0x08, 0x6a},
- { 800000000, 0x21, 0x1f, 0x09, 0x29},
- {1000000000, 0x09, 0x20, 0x09, 0x27},
- };
+ const struct inno_mipi_dphy_timing *timings;
u32 t_txbyteclkhs, t_txclkesc;
u32 txbyteclkhs, txclkesc, esc_clk_div;
u32 hs_exit, clk_post, clk_pre, wakeup, lpx, ta_go, ta_sure, ta_wait;
u32 hs_prepare, hs_trail, hs_zero, clk_lane_hs_zero, data_lane_hs_zero;
unsigned int i;
+ timings = inno->pdata->inno_mipi_dphy_timing_table;
+
inno_dsidphy_pll_calc_rate(inno, cfg->hs_clk_rate);
/* Select MIPI mode */
@@ -327,6 +392,13 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
REG_FBDIV_HI_MASK, REG_FBDIV_HI(inno->pll.fbdiv));
phy_update_bits(inno, REGISTER_PART_ANALOG, 0x04,
REG_FBDIV_LO_MASK, REG_FBDIV_LO(inno->pll.fbdiv));
+ if (inno->pdata->max_rate == MAX_2_5GHZ) {
+ phy_update_bits(inno, REGISTER_PART_ANALOG, 0x08,
+ PLL_POST_DIV_ENABLE_MASK, PLL_POST_DIV_ENABLE);
+ phy_update_bits(inno, REGISTER_PART_ANALOG, 0x0b,
+ CLOCK_LANE_VOD_RANGE_SET_MASK,
+ CLOCK_LANE_VOD_RANGE_SET(VOD_MAX_RANGE));
+ }
/* Enable PLL and LDO */
phy_update_bits(inno, REGISTER_PART_ANALOG, 0x01,
REG_LDOPD_MASK | REG_PLLPD_MASK,
@@ -345,9 +417,9 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
REG_DIG_RSTN_MASK, REG_DIG_RSTN_NORMAL);
txbyteclkhs = inno->pll.rate / 8;
- t_txbyteclkhs = div_u64(PSEC_PER_SEC, txbyteclkhs);
+ t_txbyteclkhs = DIV_ROUND_CLOSEST_ULL(PSEC_PER_SEC, txbyteclkhs);
- esc_clk_div = DIV_ROUND_UP(txbyteclkhs, 20000000);
+ esc_clk_div = DIV_ROUND_CLOSEST_ULL(txbyteclkhs, 20000000);
txclkesc = txbyteclkhs / esc_clk_div;
t_txclkesc = div_u64(PSEC_PER_SEC, txclkesc);
@@ -355,52 +427,55 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
* The value of counter for HS Ths-exit
* Ths-exit = Tpin_txbyteclkhs * value
*/
- hs_exit = DIV_ROUND_UP(cfg->hs_exit, t_txbyteclkhs);
+ hs_exit = DIV_ROUND_CLOSEST_ULL(cfg->hs_exit, t_txbyteclkhs);
/*
* The value of counter for HS Tclk-post
* Tclk-post = Tpin_txbyteclkhs * value
*/
- clk_post = DIV_ROUND_UP(cfg->clk_post, t_txbyteclkhs);
+ clk_post = DIV_ROUND_CLOSEST_ULL(cfg->clk_post, t_txbyteclkhs);
/*
* The value of counter for HS Tclk-pre
* Tclk-pre = Tpin_txbyteclkhs * value
*/
- clk_pre = DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE);
-
- /*
- * The value of counter for HS Tlpx Time
- * Tlpx = Tpin_txbyteclkhs * (2 + value)
- */
- lpx = DIV_ROUND_UP(cfg->lpx, t_txbyteclkhs);
- if (lpx >= 2)
- lpx -= 2;
+ clk_pre = DIV_ROUND_CLOSEST_ULL(cfg->clk_pre, BITS_PER_BYTE);
/*
* The value of counter for HS Tta-go
* Tta-go for turnaround
* Tta-go = Ttxclkesc * value
*/
- ta_go = DIV_ROUND_UP(cfg->ta_go, t_txclkesc);
+ ta_go = DIV_ROUND_CLOSEST_ULL(cfg->ta_go, t_txclkesc);
/*
* The value of counter for HS Tta-sure
* Tta-sure for turnaround
* Tta-sure = Ttxclkesc * value
*/
- ta_sure = DIV_ROUND_UP(cfg->ta_sure, t_txclkesc);
+ ta_sure = DIV_ROUND_CLOSEST_ULL(cfg->ta_sure, t_txclkesc);
/*
* The value of counter for HS Tta-wait
* Tta-wait for turnaround
* Tta-wait = Ttxclkesc * value
*/
- ta_wait = DIV_ROUND_UP(cfg->ta_get, t_txclkesc);
+ ta_wait = DIV_ROUND_CLOSEST_ULL(cfg->ta_get, t_txclkesc);
- for (i = 0; i < ARRAY_SIZE(timings); i++)
+ for (i = 0; i < inno->pdata->num_timings; i++)
if (inno->pll.rate <= timings[i].rate)
break;
- if (i == ARRAY_SIZE(timings))
+ if (i == inno->pdata->num_timings)
--i;
+ /*
+ * The value of counter for HS Tlpx Time
+ * Tlpx = Tpin_txbyteclkhs * (2 + value)
+ */
+ if (inno->pdata->max_rate == MAX_1GHZ) {
+ lpx = DIV_ROUND_CLOSEST_ULL(cfg->lpx, t_txbyteclkhs);
+ if (lpx >= 2)
+ lpx -= 2;
+ } else
+ lpx = timings[i].lpx;
+
hs_prepare = timings[i].hs_prepare;
hs_trail = timings[i].hs_trail;
clk_lane_hs_zero = timings[i].clk_lane_hs_zero;
@@ -417,14 +492,23 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
T_LPX_CNT(lpx));
phy_update_bits(inno, i, 0x06, T_HS_PREPARE_CNT_MASK,
T_HS_PREPARE_CNT(hs_prepare));
- phy_update_bits(inno, i, 0x07, T_HS_ZERO_CNT_MASK,
- T_HS_ZERO_CNT(hs_zero));
+ if (inno->pdata->max_rate == MAX_2_5GHZ)
+ phy_update_bits(inno, i, 0x06, T_HS_ZERO_CNT_HI_MASK,
+ T_HS_ZERO_CNT_HI(hs_zero >> 6));
+ phy_update_bits(inno, i, 0x07, T_HS_ZERO_CNT_LO_MASK,
+ T_HS_ZERO_CNT_LO(hs_zero));
phy_update_bits(inno, i, 0x08, T_HS_TRAIL_CNT_MASK,
T_HS_TRAIL_CNT(hs_trail));
- phy_update_bits(inno, i, 0x09, T_HS_EXIT_CNT_MASK,
- T_HS_EXIT_CNT(hs_exit));
- phy_update_bits(inno, i, 0x0a, T_CLK_POST_CNT_MASK,
- T_CLK_POST_CNT(clk_post));
+ if (inno->pdata->max_rate == MAX_2_5GHZ)
+ phy_update_bits(inno, i, 0x11, T_HS_EXIT_CNT_HI_MASK,
+ T_HS_EXIT_CNT_HI(hs_exit >> 5));
+ phy_update_bits(inno, i, 0x09, T_HS_EXIT_CNT_LO_MASK,
+ T_HS_EXIT_CNT_LO(hs_exit));
+ if (inno->pdata->max_rate == MAX_2_5GHZ)
+ phy_update_bits(inno, i, 0x10, T_CLK_POST_CNT_HI_MASK,
+ T_CLK_POST_CNT_HI(clk_post >> 4));
+ phy_update_bits(inno, i, 0x0a, T_CLK_POST_CNT_LO_MASK,
+ T_CLK_POST_CNT_LO(clk_post));
phy_update_bits(inno, i, 0x0e, T_CLK_PRE_CNT_MASK,
T_CLK_PRE_CNT(clk_pre));
phy_update_bits(inno, i, 0x0c, T_WAKEUP_CNT_HI_MASK,
@@ -452,8 +536,9 @@ static void inno_dsidphy_lvds_mode_enable(struct inno_dsidphy *inno)
/* Sample clock reverse direction */
phy_update_bits(inno, REGISTER_PART_ANALOG, 0x08,
- SAMPLE_CLOCK_DIRECTION_MASK,
- SAMPLE_CLOCK_DIRECTION_REVERSE);
+ SAMPLE_CLOCK_DIRECTION_MASK | LOWFRE_EN_MASK,
+ SAMPLE_CLOCK_DIRECTION_REVERSE |
+ PLL_OUTPUT_FREQUENCY_DIV_BY_1);
/* Select LVDS mode */
phy_update_bits(inno, REGISTER_PART_LVDS, 0x03,
@@ -473,6 +558,10 @@ static void inno_dsidphy_lvds_mode_enable(struct inno_dsidphy *inno)
msleep(20);
+ /* Select PLL mode */
+ phy_update_bits(inno, REGISTER_PART_ANALOG, 0x1e,
+ PLL_MODE_SEL_MASK, PLL_MODE_SEL_LVDS_MODE);
+
/* Reset LVDS digital logic */
phy_update_bits(inno, REGISTER_PART_LVDS, 0x00,
LVDS_DIGITAL_INTERNAL_RESET_MASK,
@@ -592,6 +681,18 @@ static const struct phy_ops inno_dsidphy_ops = {
.owner = THIS_MODULE,
};
+static const struct inno_video_phy_plat_data max_1ghz_video_phy_plat_data = {
+ .inno_mipi_dphy_timing_table = inno_mipi_dphy_timing_table_max_1ghz,
+ .num_timings = ARRAY_SIZE(inno_mipi_dphy_timing_table_max_1ghz),
+ .max_rate = MAX_1GHZ,
+};
+
+static const struct inno_video_phy_plat_data max_2_5ghz_video_phy_plat_data = {
+ .inno_mipi_dphy_timing_table = inno_mipi_dphy_timing_table_max_2_5ghz,
+ .num_timings = ARRAY_SIZE(inno_mipi_dphy_timing_table_max_2_5ghz),
+ .max_rate = MAX_2_5GHZ,
+};
+
static int inno_dsidphy_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -605,6 +706,7 @@ static int inno_dsidphy_probe(struct platform_device *pdev)
return -ENOMEM;
inno->dev = dev;
+ inno->pdata = of_device_get_match_data(inno->dev);
platform_set_drvdata(pdev, inno);
inno->phy_base = devm_platform_ioremap_resource(pdev, 0);
@@ -663,9 +765,19 @@ static int inno_dsidphy_remove(struct platform_device *pdev)
}
static const struct of_device_id inno_dsidphy_of_match[] = {
- { .compatible = "rockchip,px30-dsi-dphy", },
- { .compatible = "rockchip,rk3128-dsi-dphy", },
- { .compatible = "rockchip,rk3368-dsi-dphy", },
+ {
+ .compatible = "rockchip,px30-dsi-dphy",
+ .data = &max_1ghz_video_phy_plat_data,
+ }, {
+ .compatible = "rockchip,rk3128-dsi-dphy",
+ .data = &max_1ghz_video_phy_plat_data,
+ }, {
+ .compatible = "rockchip,rk3368-dsi-dphy",
+ .data = &max_1ghz_video_phy_plat_data,
+ }, {
+ .compatible = "rockchip,rk3568-dsi-dphy",
+ .data = &max_2_5ghz_video_phy_plat_data,
+ },
{}
};
MODULE_DEVICE_TABLE(of, inno_dsidphy_of_match);
--
2.25.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment