Skip to contentSkip to conversation

Enable MIPI dsi display for rk3399

PATCH New eric.gao at rock-chips.com 6 participants 19 messages Apr 1, 2017 – Apr 6, 2017

Subsystems (6)
lore
Share & tools
lore
#0 lore raw

cover Enable MIPI dsi display for rk3399

From: "eric.gao" <[email protected]>

This serial patchs enable mipi dsi display for rk3399,and let the
system log print to lcd. The function of each patch is decribe in the following.Thank you.
Patch 1: Fix system halt when we enable bucks of PMIC rk808. Patch 2: Enable i2c for rk3399.
Patch 3: Enable PMIC rk808 for display system using. Patch 4: Enable rkclk init,prepare aclk dclk for vop. Patch 5: Add mipi display,panel driver and so on.
Patch 6: Enable print log to lcd.
Patch 7: Fix crash when scrolling screen.

eric.gao (7):
system halt when we enable bucks of PMIC rk808 Enable i2c for rk3399
Enable RK808 for rk3399 evb
Enable rkclk init function
Add mipi display support for rk3399 && rk3288 Enable print log file to lcd
crash when scroll screen

 arch/arm/dts/rk3399-evb.dts                      | 141 +++++++++
 arch/arm/dts/rk3399.dtsi                         |  88 ++++++
 arch/arm/include/asm/arch-rockchip/cru_rk3399.h  |   2 +-
 arch/arm/include/asm/arch-rockchip/mipi_rk3399.h | 203 +++++++++++++
 arch/arm/include/asm/arch-rockchip/vop_rk3288.h  |   1 +
 arch/arm/mach-rockchip/rk3399/syscon_rk3399.c    |   1 +
 configs/evb-rk3399_defconfig                     |  11 +
 drivers/clk/rockchip/clk_rk3399.c                |   4 +
 drivers/i2c/rk_i2c.c                             |   1 +
 drivers/video/Kconfig                            |   2 +
 drivers/video/console_normal.c                   |   2 +-
 drivers/video/rockchip/Kconfig                   |  44 +++
 drivers/video/rockchip/Makefile                  |   7 +-
 drivers/video/rockchip/panel.c                   |  81 +++++
 drivers/video/rockchip/rk_mipi.c                 | 371 +++++++++++++++++++++++
 drivers/video/rockchip/rk_vop.c                  |  12 +-
 include/configs/rk3399_common.h                  |   5 +-
 17 files changed, 969 insertions(+), 7 deletions(-)
 create mode 100644 arch/arm/include/asm/arch-rockchip/mipi_rk3399.h
 create mode 100644 drivers/video/rockchip/Kconfig
 create mode 100644 drivers/video/rockchip/panel.c
 create mode 100644 drivers/video/rockchip/rk_mipi.c
Signature · 1 line
1.9.1
#1 lore raw

PATCH 1/7 system halt when we enable bucks of PMIC rk808

From: "eric.gao" <[email protected]>

if we enable PMIC rk808,the system will halt at very early stage ,log is shown as bellow.

INFO:    plat_rockchip_pmu_init(1211): pd status 3e
INFO:    BL31: Initializing runtime services
INFO:    BL31: Preparing for EL3 exit to normal world
INFO:    Entry point address = 0x200000
INFO:    SPSR = 0x3c9

time 44561b, 0 (<<----Just stop here)

It's caused by the absence of "{ }" in file rk3399/syscon_rk3399.c ,which will lead to memory overflow like below.According to Sysmap file ,we can find the function buck_get_value of rk808 is just follow the compatible struct, the pointer "of_match" point to "buck_get_value", but it is not a struct and don't have member of compatible, In this case,system crash. So,on the face, it looks like that rk808 is guilty. but he is really innocent.

while (of_match->compatible) { <<----------

    if (!strcmp(of_match->compatible, compat)) {
    *of_idp = of_match;
    return 0;
    }
    of_match++;
}

---

 arch/arm/mach-rockchip/rk3399/syscon_rk3399.c | 1 +
 1 file changed, 1 insertion(+)
arch/arm/mach-rockchip/rk3399/syscon_rk3399.c +1 -0
index d32985b..74d4552 100644
@@ -14,6 +14,7 @@ static const struct udevice_id rk3399_syscon_ids[] = {
 	{ .compatible = "rockchip,rk3399-pmugrf", .data = ROCKCHIP_SYSCON_PMUGRF },
 	{ .compatible = "rockchip,rk3399-pmusgrf", .data = ROCKCHIP_SYSCON_PMUSGRF },
 	{ .compatible = "rockchip,rk3399-cic", .data = ROCKCHIP_SYSCON_CIC },
+	{ }
 };
 
 U_BOOT_DRIVER(syscon_rk3399) = {
Signature · 1 line
1.9.1
#2 lore raw

PATCH 1/7 system halt when we enable bucks of PMIC rk808

Quoted 28 lines · On 1 April 2017 at 08:42, <[email protected]> wrote:

From: "eric.gao" <[email protected]>

if we enable PMIC rk808,the system will halt at very early stage ,log is shown as bellow.

INFO:    plat_rockchip_pmu_init(1211): pd status 3e
INFO:    BL31: Initializing runtime services
INFO:    BL31: Preparing for EL3 exit to normal world
INFO:    Entry point address = 0x200000
INFO:    SPSR = 0x3c9

time 44561b, 0 (<<----Just stop here)

It's caused by the absence of "{ }" in file rk3399/syscon_rk3399.c ,which will lead to memory overflow like below.According to Sysmap file ,we can find the function buck_get_value of rk808 is just follow the compatible struct, the pointer "of_match" point to "buck_get_value", but it is not a struct and don't have member of compatible, In this case,system crash. So,on the face, it looks like that rk808 is guilty. but he is really innocent.

while (of_match->compatible) { <<----------

    if (!strcmp(of_match->compatible, compat)) {
    *of_idp = of_match;
    return 0;
    }
    of_match++;
}
Quoted 5 lines

---

 arch/arm/mach-rockchip/rk3399/syscon_rk3399.c | 1 +
 1 file changed, 1 insertion(+)

(I'm assuming you will resend with the changes Kever mentioned, thanks)

#3 lore raw

PATCH 2/7 Enable i2c for rk3399

In reply to eric.gao at rock-chips.com

From: "eric.gao" <[email protected]>

---

 arch/arm/dts/rk3399.dtsi     | 16 ++++++++++++++++
 configs/evb-rk3399_defconfig |  1 +
 drivers/i2c/rk_i2c.c         |  1 +
 3 files changed, 18 insertions(+)
arch/arm/dts/rk3399.dtsi +16 -0
index 456fdb6..93e3bf4 100644
@@ -26,6 +26,7 @@
 		serial4 = &uart4;
 		mmc0 = &sdhci;
 		mmc1 = &sdmmc;
+		i2c0 = &i2c0;
 	};
 
 	cpus {
@@ -651,6 +652,21 @@
 		status = "disabled";
 	};
 
+	i2c0: i2c at ff3c0000 {
+		compatible = "rockchip,rk3399-i2c";
+		reg = <0x0 0xff3c0000 0x0 0x1000>;
+		assigned-clocks = <&pmucru SCLK_I2C0_PMU>;
+		assigned-clock-rates = <200000000>;
+		clocks = <&pmucru SCLK_I2C0_PMU>, <&pmucru PCLK_I2C0_PMU>;
+		clock-names = "i2c", "pclk";
+		interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH 0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c0_xfer>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
 	pinctrl: pinctrl {
 		u-boot,dm-pre-reloc;
 		compatible = "rockchip,rk3399-pinctrl";
configs/evb-rk3399_defconfig +1 -0
index bedc1fd..2e2f9a8 100644
@@ -58,3 +58,4 @@ CONFIG_USB_EHCI_GENERIC=y
 CONFIG_USB_STORAGE=y
 CONFIG_USE_TINY_PRINTF=y
 CONFIG_ERRNO_STR=y
+CONFIG_SYS_I2C_ROCKCHIP=y
drivers/i2c/rk_i2c.c +1 -0
index 7c701cb..a4c8c2ba 100644
@@ -381,6 +381,7 @@ static const struct dm_i2c_ops rockchip_i2c_ops = {
 
 static const struct udevice_id rockchip_i2c_ids[] = {
 	{ .compatible = "rockchip,rk3288-i2c" },
+	{ .compatible = "rockchip,rk3399-i2c" },
 	{ }
 };
 
Signature · 1 line
1.9.1
#4 lore raw

PATCH 2/7 Enable i2c for rk3399

Hello Eric,

Am 01.04.2017 um 16:42 schrieb eric.gao at rock-chips.com:

Quoted 9 lines

From: "eric.gao" <[email protected]>

---

  arch/arm/dts/rk3399.dtsi     | 16 ++++++++++++++++
  configs/evb-rk3399_defconfig |  1 +
  drivers/i2c/rk_i2c.c         |  1 +
  3 files changed, 18 insertions(+)

bye,
Heiko

Quoted 57 lines
arch/arm/dts/rk3399.dtsi +16 -0
index 456fdb6..93e3bf4 100644
@@ -26,6 +26,7 @@
  		serial4 = &uart4;
  		mmc0 = &sdhci;
  		mmc1 = &sdmmc;
+		i2c0 = &i2c0;
  	};
 
  	cpus {
@@ -651,6 +652,21 @@
  		status = "disabled";
  	};
 
+	i2c0: i2c at ff3c0000 {
+		compatible = "rockchip,rk3399-i2c";
+		reg = <0x0 0xff3c0000 0x0 0x1000>;
+		assigned-clocks = <&pmucru SCLK_I2C0_PMU>;
+		assigned-clock-rates = <200000000>;
+		clocks = <&pmucru SCLK_I2C0_PMU>, <&pmucru PCLK_I2C0_PMU>;
+		clock-names = "i2c", "pclk";
+		interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH 0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&i2c0_xfer>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "disabled";
+	};
+
  	pinctrl: pinctrl {
  		u-boot,dm-pre-reloc;
  		compatible = "rockchip,rk3399-pinctrl";
configs/evb-rk3399_defconfig +1 -0
index bedc1fd..2e2f9a8 100644
@@ -58,3 +58,4 @@ CONFIG_USB_EHCI_GENERIC=y
  CONFIG_USB_STORAGE=y
  CONFIG_USE_TINY_PRINTF=y
  CONFIG_ERRNO_STR=y
+CONFIG_SYS_I2C_ROCKCHIP=y
drivers/i2c/rk_i2c.c +1 -0
index 7c701cb..a4c8c2ba 100644
@@ -381,6 +381,7 @@ static const struct dm_i2c_ops rockchip_i2c_ops = {
 
  static const struct udevice_id rockchip_i2c_ids[] = {
  	{ .compatible = "rockchip,rk3288-i2c" },
+	{ .compatible = "rockchip,rk3399-i2c" },
  	{ }
  };
 
Signature · 2 lines
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
#5 lore raw

PATCH 3/7 Enable RK808 for rk3399 evb

In reply to eric.gao at rock-chips.com

From: "eric.gao" <[email protected]>

---

 arch/arm/dts/rk3399-evb.dts  | 108 +++++++++++++++++++++++++++++++++++++++++++
 configs/evb-rk3399_defconfig |   5 ++
 2 files changed, 113 insertions(+)
arch/arm/dts/rk3399-evb.dts +108 -0
index a959989..7a889c7 100644
@@ -51,6 +51,22 @@
 		regulator-name = "vcc5v0_host";
 		gpio = <&gpio4 25 GPIO_ACTIVE_HIGH>;
 	};
+
+	vccsys: vccsys {
+		compatible = "regulator-fixed";
+		regulator-name = "vccsys";
+		regulator-boot-on;
+		regulator-always-on;
+	};
+	vcc33_sys: vcc33-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc33_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vccsys>;
+	};
 };
 
 &emmc_phy {
@@ -110,6 +126,98 @@
 	status = "okay";
 };
 
+&i2c0 {
+	status = "okay";
+
+	clock-frequency = <400000>;
+	i2c-scl-falling-time-ns = <50>;
+	i2c-scl-rising-time-ns = <100>;
+	u-boot,dm-pre-reloc;
+
+	rk808: pmic at 1b {
+		compatible = "rockchip,rk808";
+		clock-output-names = "xin32k", "wifibt_32kin";
+		interrupt-parent = <&gpio0>;
+		interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_int_l>;
+		reg = <0x1b>;
+		rockchip,system-power-controller;
+		#clock-cells = <1>;
+		u-boot,dm-pre-reloc;
+		status = "okay";
+
+		vcc1-supply = <&vcc33_sys>;
+		vcc2-supply = <&vcc33_sys>;
+		vcc3-supply = <&vcc33_sys>;
+		vcc4-supply = <&vcc33_sys>;
+		vcc6-supply = <&vcc33_sys>;
+		vcc7-supply = <&vcc33_sys>;
+		vcc11-supply = <&vcc33_sys>;
+		vcc12-supply = <&vcc33_sys>;
+		vddio-supply = <&vcc1v8>;
+		regulators {
+			vdd_cpu_b: DCDC_REG1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <1450000>;
+				regulator-name = "vdd_cpu_b";
+			};
+
+			vdd_cpu_l: DCDC_REG2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <1450000>;
+				regulator-name = "vdd_cpu_l";
+			};
+
+			vcc135_ddr: DCDC_REG3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vcc135_ddr";
+			};
+
+			vcc18: DCDC_REG4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc_18";
+			};
+
+			vcc1v8_dvp: LDO_REG1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vcc18_dvp";
+			};
+
+			vcc1v8: LDO_REG3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-name = "vdd_18";
+			};
+
+			vcc3v0: LDO_REG8 {
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-name = "vcc3v0";
+			};
+
+			vcc33_lcd: SWITCH_REG2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-name = "vcc33_lcd";
+			};
+		};
+	};
+};
+
 &pinctrl {
 	pmic {
 		pmic_int_l: pmic-int-l {
configs/evb-rk3399_defconfig +5 -0
index 2e2f9a8..aac6d2d 100644
@@ -59,3 +59,8 @@ CONFIG_USB_STORAGE=y
 CONFIG_USE_TINY_PRINTF=y
 CONFIG_ERRNO_STR=y
 CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_DM_PMIC=y
+CONFIG_PMIC_CHILDREN=y
+CONFIG_SPL_PMIC_CHILDREN=y
+CONFIG_PMIC_RK808=y
+CONFIG_REGULATOR_RK808=y
Signature · 1 line
1.9.1
#7 lore raw

PATCH 4/7 Enable rkclk init function

In reply to eric.gao at rock-chips.com

From: "eric.gao" <[email protected]>

---

 drivers/clk/rockchip/clk_rk3399.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/clk/rockchip/clk_rk3399.c +4 -0
index 922ce7e..cfcd1e4 100644
@@ -20,6 +20,10 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#ifndef CONFIG_SPL_BUILD
+#define CONFIG_SPL_BUILD
+#endif
+
 #if CONFIG_IS_ENABLED(OF_PLATDATA)
 struct rk3399_clk_plat {
 	struct dtd_rockchip_rk3399_cru dtd;
Signature · 1 line
1.9.1
maintainer
#8 lore raw

PATCH 4/7 Enable rkclk init function

Hi Eric,

Am Samstag, 1. April 2017, 22:42:54 CEST schrieb eric.gao at rock-chips.com:

Quoted 13 lines

From: "eric.gao" <[email protected]>

---

 drivers/clk/rockchip/clk_rk3399.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/clk/rockchip/clk_rk3399.c +0 -0
index 922ce7e..cfcd1e4 100644

drivers/clk/rockchip/clk_rk3399.c line 26

Quoted 7 lines
drivers/clk/rockchip/clk_rk3399.c +4 -0
@@ -20,6 +20,10 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#ifndef CONFIG_SPL_BUILD
+#define CONFIG_SPL_BUILD
+#endif
+

That looks very strange. In all cases your commit message should explain why a change is necessary, i.e. what you want to achieve.

In this special case, also rkclk_init runs from SPL context and inits the clocks already, the full u-boot then finds the clocks already set up as necessary and should have no need to for rkclk_init at all itself.

Heiko

author
#9 lore raw

PATCH 4/7 Enable rkclk init function

Dear Heiko,

Thanks for your review.

I will add commit for all patches.

The reason I add this declaration is that spl for rk3399 is still
not ready, I used

ourself rkloader, which can not initial clock suitable for video module. Anyway,

I will drop this signal patch and wait for spl ready. Thank you.

Quoted 35 lines · Heiko Stuebner

Hi Eric,

Am Samstag, 1. April 2017, 22:42:54 CEST schrieb eric.gao at rock-chips.com:

Quoted 13 lines

From: "eric.gao" <[email protected]>

---

  drivers/clk/rockchip/clk_rk3399.c | 4 ++++
  1 file changed, 4 insertions(+)
drivers/clk/rockchip/clk_rk3399.c +0 -0
index 922ce7e..cfcd1e4 100644

drivers/clk/rockchip/clk_rk3399.c line 26

Quoted 7 lines
drivers/clk/rockchip/clk_rk3399.c +4 -0
@@ -20,6 +20,10 @@
 
  DECLARE_GLOBAL_DATA_PTR;
 
+#ifndef CONFIG_SPL_BUILD
+#define CONFIG_SPL_BUILD
+#endif
+

That looks very strange. In all cases your commit message should explain why a change is necessary, i.e. what you want to achieve.

In this special case, also rkclk_init runs from SPL context and inits the clocks already, the full u-boot then finds the clocks already set up as necessary and should have no need to for rkclk_init at all itself.

Heiko

#10 lore raw

PATCH 5/7 Add mipi display support for rk3399 && rk3288

In reply to eric.gao at rock-chips.com

From: "eric.gao" <[email protected]>

---

 arch/arm/dts/rk3399-evb.dts                      |  33 ++
 arch/arm/dts/rk3399.dtsi                         |  72 +++++
 arch/arm/include/asm/arch-rockchip/cru_rk3399.h  |   2 +-
 arch/arm/include/asm/arch-rockchip/mipi_rk3399.h | 203 +++++++++++++
 arch/arm/include/asm/arch-rockchip/vop_rk3288.h  |   1 +
 configs/evb-rk3399_defconfig                     |   4 +
 drivers/video/Kconfig                            |   2 +
 drivers/video/rockchip/Kconfig                   |  44 +++
 drivers/video/rockchip/Makefile                  |   7 +-
 drivers/video/rockchip/panel.c                   |  81 +++++
 drivers/video/rockchip/rk_mipi.c                 | 371 +++++++++++++++++++++++
 drivers/video/rockchip/rk_vop.c                  |  12 +-
 12 files changed, 827 insertions(+), 5 deletions(-)
 create mode 100644 arch/arm/include/asm/arch-rockchip/mipi_rk3399.h
 create mode 100644 drivers/video/rockchip/Kconfig
 create mode 100644 drivers/video/rockchip/panel.c
 create mode 100644 drivers/video/rockchip/rk_mipi.c
arch/arm/dts/rk3399-evb.dts +33 -0
index 7a889c7..abb00e8 100644
@@ -52,6 +52,10 @@
 		gpio = <&gpio4 25 GPIO_ACTIVE_HIGH>;
 	};
 
+	panel:panel {
+		compatible = "BOE,TV080WUM";
+		status = "disabled";
+	};
 	vccsys: vccsys {
 		compatible = "regulator-fixed";
 		regulator-name = "vccsys";
@@ -218,6 +222,35 @@
 	};
 };
 
+&panel {
+	backlight_en = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+	backlight_pwm = <&gpio4 18 GPIO_ACTIVE_HIGH>;
+	power-supply = <&vcc33_lcd>;
+	status = "okay";
+};
+
+&mipi_dsi {
+	status = "okay";
+	display-timings {
+		timing0 {
+		bits-per-pixel = <24>;
+		clock-frequency = <160000000>;
+		hfront-porch = <120>;
+		hsync-len = <20>;
+		hback-porch = <21>;
+		hactive = <1200>;
+		vfront-porch = <21>;
+		vsync-len = <3>;
+		vback-porch = <18>;
+		vactive = <1920>;
+		hsync-active = <0>;
+		vsync-active = <0>;
+		de-active = <1>;
+		pixelclk-active = <0>;
+		};
+	};
+};
+
 &pinctrl {
 	pmic {
 		pmic_int_l: pmic-int-l {
arch/arm/dts/rk3399.dtsi +72 -0

78 lines not on this page · raw message

arch/arm/include/asm/arch-rockchip/cru_rk3399.h +1 -1
index cf830d0..8aa08d4 100644
@@ -74,7 +74,7 @@ check_member(rk3399_cru, sdio1_con[1], 0x594);
 #define OSC_HZ		(24*MHz)
 #define APLL_HZ		(600*MHz)
 #define GPLL_HZ		(594*MHz)
-#define CPLL_HZ		(384*MHz)
+#define CPLL_HZ		(594*MHz)
 #define PPLL_HZ		(676*MHz)
 
 #define PMU_PCLK_HZ	(48*MHz)
arch/arm/include/asm/arch-rockchip/mipi_rk3399.h new file +203 -0

203 lines not on this page · raw message

arch/arm/include/asm/arch-rockchip/vop_rk3288.h +1 -0
index 0ce3d67..d5599ec 100644
@@ -90,6 +90,7 @@ enum vop_modes {
 	VOP_MODE_EDP = 0,
 	VOP_MODE_HDMI,
 	VOP_MODE_LVDS,
+	VOP_MODE_MIPI,
 	VOP_MODE_NONE,
 	VOP_MODE_AUTO_DETECT,
 	VOP_MODE_UNKNOWN,
configs/evb-rk3399_defconfig +4 -0
index aac6d2d..b9cb0e8 100644
@@ -64,3 +64,7 @@ CONFIG_PMIC_CHILDREN=y
 CONFIG_SPL_PMIC_CHILDREN=y
 CONFIG_PMIC_RK808=y
 CONFIG_REGULATOR_RK808=y
+CONFIG_DM_VIDEO=y
+CONFIG_DISPLAY=y
+CONFIG_VIDEO_ROCKCHIP=y
+CONFIG_DISPLAY_MIPI=y
drivers/video/Kconfig +2 -0
index 2069576..4b03a9a 100644
@@ -405,6 +405,8 @@ config VIDEO_ROCKCHIP
 	   (DSI). This driver supports the on-chip video output device, and
 	   targets the Rockchip RK3288.
 
+source "drivers/video/rockchip/Kconfig"
+
 config VIDEO_SANDBOX_SDL
 	bool "Enable sandbox video console using SDL"
 	depends on SANDBOX
drivers/video/rockchip/Kconfig new file +44 -0

44 lines not on this page · raw message

drivers/video/rockchip/Makefile +6 -1
index 7962f86..98b26ea 100644
@@ -5,4 +5,9 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
-obj-y += rk_edp.o rk_hdmi.o rk_vop.o rk_lvds.o
+obj-$(CONFIG_VIDEO_ROCKCHIP) += rk_vop.o
+obj-$(CONFIG_VIDEO_ROCKCHIP) += panel.o
+obj-$(CONFIG_DISPLAY_MIPI) += rk_mipi.o
+obj-$(CONFIG_DISPLAY_EDP) += rk_edp.o
+obj-$(CONFIG_DISPLAY_LVDS) += rk_lvds.o
+obj-$(CONFIG_DISPLAY_HDMI) += rk_hdmi.o
drivers/video/rockchip/panel.c new file +81 -0

81 lines not on this page · raw message

drivers/video/rockchip/rk_mipi.c new file +371 -0

371 lines not on this page · raw message

drivers/video/rockchip/rk_vop.c +9 -3
index aeecb58..1de00f1 100644
@@ -109,6 +109,10 @@ void rkvop_mode_set(struct rk3288_vop *regs,
 		clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN,
 				V_HDMI_OUT_EN(1));
 		break;
+	case VOP_MODE_MIPI:
+		clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN,
+				V_MIPI_OUT_EN(1));
+		break;
 	case VOP_MODE_EDP:
 	default:
 		clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN,
@@ -245,7 +249,7 @@ int rk_display_init(struct udevice *dev, ulong fbbase,
 	ret = clk_get_by_index(dev, 1, &clk);
 	if (!ret)
 		ret = clk_set_rate(&clk, timing.pixelclock.typ);
-	if (ret) {
+	if (!ret) {
 		debug("%s: Failed to set pixel clock: ret=%d\n", __func__, ret);
 		return ret;
 	}
@@ -327,7 +331,7 @@ static int rk_vop_probe(struct udevice *dev)
 	for (node = fdt_first_subnode(blob, port);
 	     node > 0;
 	     node = fdt_next_subnode(blob, node)) {
-		ret = rk_display_init(dev, plat->base, VIDEO_BPP16, node);
+		ret = rk_display_init(dev, plat->base, VIDEO_BPP32, node);
 		if (ret)
 			debug("Device failed: ret=%d\n", ret);
 		if (!ret)
@@ -342,7 +346,7 @@ static int rk_vop_bind(struct udevice *dev)
 {
 	struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
 
-	plat->size = 1920 * 1080 * 2;
+	plat->size = 1920 * 1200 * 4;
 
 	return 0;
 }
@@ -351,6 +355,8 @@ static const struct video_ops rk_vop_ops = {
 };
 
 static const struct udevice_id rk_vop_ids[] = {
+	{ .compatible = "rockchip,rk3399-vop-big" },
+	{ .compatible = "rockchip,rk3399-vop-lit" },
 	{ .compatible = "rockchip,rk3288-vop" },
 	{ }
 };
Signature · 1 line
1.9.1
#11 lore raw

PATCH 5/7 Add mipi display support for rk3399 && rk3288

Hi eric,

2017-04-01 22:42 GMT+08:00 <[email protected]>:

Quoted 61 lines

From: "eric.gao" <[email protected]>

---

 arch/arm/dts/rk3399-evb.dts                      |  33 ++
 arch/arm/dts/rk3399.dtsi                         |  72 +++++
 arch/arm/include/asm/arch-rockchip/cru_rk3399.h  |   2 +-
 arch/arm/include/asm/arch-rockchip/mipi_rk3399.h | 203 +++++++++++++
 arch/arm/include/asm/arch-rockchip/vop_rk3288.h  |   1 +
 configs/evb-rk3399_defconfig                     |   4 +
 drivers/video/Kconfig                            |   2 +
 drivers/video/rockchip/Kconfig                   |  44 +++
 drivers/video/rockchip/Makefile                  |   7 +-
 drivers/video/rockchip/panel.c                   |  81 +++++
 drivers/video/rockchip/rk_mipi.c                 | 371 +++++++++++++++++++++++
 drivers/video/rockchip/rk_vop.c                  |  12 +-
 12 files changed, 827 insertions(+), 5 deletions(-)
 create mode 100644 arch/arm/include/asm/arch-rockchip/mipi_rk3399.h
 create mode 100644 drivers/video/rockchip/Kconfig
 create mode 100644 drivers/video/rockchip/panel.c
 create mode 100644 drivers/video/rockchip/rk_mipi.c
arch/arm/dts/rk3399-evb.dts +23 -0
index 7a889c7..abb00e8 100644
@@ -52,6 +52,10 @@
                gpio = <&gpio4 25 GPIO_ACTIVE_HIGH>;
        };
 
+       panel:panel {
+               compatible = "BOE,TV080WUM";
+               status = "disabled";
+       };
        vccsys: vccsys {
                compatible = "regulator-fixed";
                regulator-name = "vccsys";
@@ -218,6 +222,35 @@
        };
 };
 
+&panel {
+       backlight_en = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+       backlight_pwm = <&gpio4 18 GPIO_ACTIVE_HIGH>;
+       power-supply = <&vcc33_lcd>;
+       status = "okay";
+};
+
+&mipi_dsi {
+       status = "okay";
+       display-timings {
+               timing0 {
+               bits-per-pixel = <24>;
+               clock-frequency = <160000000>;
+               hfront-porch = <120>;
+               hsync-len = <20>;
+               hback-porch = <21>;
+               hactive = <1200>;
+               vfront-porch = <21>;
+               vsync-len = <3>;

arch/arm/dts/rk3399-evb.dts line 253

Quoted 10 lines
arch/arm/dts/rk3399-evb.dts +10 -0
+               vback-porch = <18>;
+               vactive = <1920>;
+               hsync-active = <0>;
+               vsync-active = <0>;
+               de-active = <1>;
+               pixelclk-active = <0>;
+               };
+       };
+};
+

Evb board can use different screens, so we'd better not hard-code the choice. And, Please split dts changes to a separate patch.

Quoted 487 lines
arch/arm/dts/rk3399-evb.dts +0 -0
 &pinctrl {
        pmic {
                pmic_int_l: pmic-int-l {
arch/arm/dts/rk3399.dtsi +72 -0
index 93e3bf4..c82e674 100644
@@ -667,6 +667,78 @@
                status = "disabled";
        };
 
+       vopl: vop at ff8f0000 {
+               u-boot,dm-pre-reloc;
+               compatible = "rockchip,rk3399-vop-lit";
+               reg = <0x0 0xff8f0000 0x0 0x3efc>;
+               interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH 0>;
+               clocks = <&cru ACLK_VOP1>, <&cru DCLK_VOP1>, <&cru HCLK_VOP1>;
+               clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
+               resets = <&cru SRST_A_VOP1>, <&cru SRST_H_VOP1>, <&cru SRST_D_VOP1>;
+               reset-names = "axi", "ahb", "dclk";
+               status = "okay";
+               vopl_out: port {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       vopl_out_mipi: endpoint at 0 {
+                               reg = <3>;
+                               remote-endpoint = <&mipi_in_vopl>;
+                       };
+               };
+       };
+
+       vopb: vop at ff900000 {
+               u-boot,dm-pre-reloc;
+               compatible = "rockchip,rk3399-vop-big";
+               reg = <0x0 0xff900000 0x0 0x3efc>;
+               interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH 0>;
+               clocks = <&cru ACLK_VOP0>, <&cru DCLK_VOP0>, <&cru HCLK_VOP0>;
+               #clock-cells = <0>;
+               clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
+               resets = <&cru SRST_A_VOP0>, <&cru SRST_H_VOP0>, <&cru SRST_D_VOP0>;
+               reset-names = "axi", "ahb", "dclk";
+               /*power-domains = <&power RK3399_PD_VOPB>;*/
+               status = "okay";
+               vopb_out: port {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       vopb_out_mipi: endpoint at 0 {
+                               reg = <3>;
+                               remote-endpoint = <&mipi_in_vopb>;
+                       };
+               };
+       };
+
+       mipi_dsi: mipi at ff960000 {
+               compatible = "rockchip,rk3399_mipi_dsi";
+               reg = <0x0 0xff960000 0x0 0x8000>;
+               interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH 0>;
+               clocks = <&cru SCLK_MIPIDPHY_REF>, <&cru PCLK_MIPI_DSI0>,
+                        <&cru SCLK_DPHY_TX0_CFG>;
+               clock-names = "ref", "pclk", "phy_cfg";
+               rockchip,grf = <&grf>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <1>;
+                       mipi_in: port {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               mipi_in_vopb: endpoint at 0 {
+                                       reg = <0>;
+                                       remote-endpoint = <&vopb_out_mipi>;
+                               };
+                               mipi_in_vopl: endpoint at 1 {
+                                       reg = <1>;
+                                       remote-endpoint = <&vopl_out_mipi>;
+                               };
+                       };
+               };
+       };
+
        pinctrl: pinctrl {
                u-boot,dm-pre-reloc;
                compatible = "rockchip,rk3399-pinctrl";
arch/arm/include/asm/arch-rockchip/cru_rk3399.h +1 -1
index cf830d0..8aa08d4 100644
@@ -74,7 +74,7 @@ check_member(rk3399_cru, sdio1_con[1], 0x594);
 #define OSC_HZ         (24*MHz)
 #define APLL_HZ                (600*MHz)
 #define GPLL_HZ                (594*MHz)
-#define CPLL_HZ                (384*MHz)
+#define CPLL_HZ                (594*MHz)
 #define PPLL_HZ                (676*MHz)
 
 #define PMU_PCLK_HZ    (48*MHz)
arch/arm/include/asm/arch-rockchip/mipi_rk3399.h new file +203 -0
new file mode 100644
index 0000000..478cb21
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2017-2025 Fuzhou Rockchip Electronics Co., Ltd
+ * author: eric.gao at rock-chips.com
+ * create date: 2017-03-31
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef RK33_MIPI_DSI_H
+#define RK33_MIPI_DSI_H
+
+#define GRF_BASE        0xFF770000
+#define RK_GRF_CON20    0x06250
+#define RK_GRF_CON22    0x06258
+#define MHz 1000000
+
+#define MIPI_DSI_HOST0_BASE    0xff960000
+#define MIPI_DSI_HOST1_BASE    0xff968000
+
+/*
+ * function bits definition
+ * register addr | bits | offest
+ */
+#define DSI_HOST_BITS(addr, bits, bit_offset) \
+       ((addr<<16) | (bits<<8) | (bit_offset))
+
+/* DWC_DSI_VERSION_0X3133302A */
+#define VERSION                                DSI_HOST_BITS(0X000, 32, 0)
+#define SHUTDOWNZ                      DSI_HOST_BITS(0X004, 1, 0)
+#define TO_CLK_DIVISION                DSI_HOST_BITS(0X008, 8, 8)
+#define TX_ESC_CLK_DIVISION    DSI_HOST_BITS(0X008, 8, 0)
+#define DPI_VCID                       DSI_HOST_BITS(0X00C, 2, 0)
+#define EN18_LOOSELY           DSI_HOST_BITS(0X010, 1, 8)
+#define DPI_COLOR_CODING       DSI_HOST_BITS(0X010, 4, 0)
+#define COLORM_ACTIVE_LOW      DSI_HOST_BITS(0X014, 1, 4)
+#define SHUTD_ACTIVE_LOW       DSI_HOST_BITS(0X014, 1, 3)
+#define HSYNC_ACTIVE_LOW       DSI_HOST_BITS(0X014, 1, 2)
+#define VSYNC_ACTIVE_LOW       DSI_HOST_BITS(0X014, 1, 1)
+#define DATAEN_ACTIVE_LOW      DSI_HOST_BITS(0X014, 1, 0)
+#define OUTVACT_LPCMD_TIME     DSI_HOST_BITS(0X018, 8, 16)
+#define INVACT_LPCMD_TIME      DSI_HOST_BITS(0X018, 8, 0)
+#define CRC_RX_EN                      DSI_HOST_BITS(0X02C, 1, 4)
+#define ECC_RX_EN                      DSI_HOST_BITS(0X02C, 1, 3)
+#define BTA_EN                         DSI_HOST_BITS(0X02C, 1, 2)
+#define EOTP_RX_EN                     DSI_HOST_BITS(0X02C, 1, 1)
+#define EOTP_TX_EN                     DSI_HOST_BITS(0X02C, 1, 0)
+#define GEN_VID_RX                     DSI_HOST_BITS(0X030, 2, 0)
+#define CMD_VIDEO_MODE         DSI_HOST_BITS(0X034, 1, 0)
+#define VPG_ORIENTATION                DSI_HOST_BITS(0X038, 1, 24)
+#define VPG_MODE                       DSI_HOST_BITS(0X038, 1, 20)
+#define VPG_EN                         DSI_HOST_BITS(0X038, 1, 16)
+#define LP_CMD_EN                      DSI_HOST_BITS(0X038, 1, 15)
+#define FRAME_BTA_ACK_EN       DSI_HOST_BITS(0X038, 1, 14)
+#define LP_HFP_EN                      DSI_HOST_BITS(0X038, 1, 13)
+#define LP_HBP_EN                      DSI_HOST_BITS(0X038, 1, 12)
+#define LP_VACT_EN                     DSI_HOST_BITS(0X038, 1, 11)
+#define LP_VFP_EN                      DSI_HOST_BITS(0X038, 1, 10)
+#define LP_VBP_EN                      DSI_HOST_BITS(0X038, 1, 9)
+#define LP_VSA_EN                      DSI_HOST_BITS(0X038, 1, 8)
+#define VID_MODE_TYPE          DSI_HOST_BITS(0X038, 2, 0)
+#define VID_PKT_SIZE           DSI_HOST_BITS(0X03C, 14, 0)
+#define NUM_CHUNKS                     DSI_HOST_BITS(0X040, 13, 0)
+#define NULL_PKT_SIZE          DSI_HOST_BITS(0X044, 13, 0)
+#define VID_HSA_TIME           DSI_HOST_BITS(0X048, 12, 0)
+#define VID_HBP_TIME           DSI_HOST_BITS(0X04C, 12, 0)
+#define VID_HLINE_TIME         DSI_HOST_BITS(0X050, 15, 0)
+#define VID_VSA_LINES          DSI_HOST_BITS(0X054, 10, 0)
+#define VID_VBP_LINES          DSI_HOST_BITS(0X058, 10, 0)
+#define VID_VFP_LINES          DSI_HOST_BITS(0X05C, 10, 0)
+#define VID_ACTIVE_LINES       DSI_HOST_BITS(0X060, 14, 0)
+#define EDPI_CMD_SIZE          DSI_HOST_BITS(0X064, 16, 0)
+#define MAX_RD_PKT_SIZE                DSI_HOST_BITS(0X068, 1, 24)
+#define DCS_LW_TX                      DSI_HOST_BITS(0X068, 1, 19)
+#define DCS_SR_0P_TX           DSI_HOST_BITS(0X068, 1, 18)
+#define DCS_SW_1P_TX           DSI_HOST_BITS(0X068, 1, 17)
+#define DCS_SW_0P_TX           DSI_HOST_BITS(0X068, 1, 16)
+#define GEN_LW_TX                      DSI_HOST_BITS(0X068, 1, 14)
+#define GEN_SR_2P_TX           DSI_HOST_BITS(0X068, 1, 13)
+#define GEN_SR_1P_TX           DSI_HOST_BITS(0X068, 1, 12)
+#define GEN_SR_0P_TX           DSI_HOST_BITS(0X068, 1, 11)
+#define GEN_SW_2P_TX           DSI_HOST_BITS(0X068, 1, 10)
+#define GEN_SW_1P_TX           DSI_HOST_BITS(0X068, 1, 9)
+#define GEN_SW_0P_TX           DSI_HOST_BITS(0X068, 1, 8)
+#define ACK_RQST_EN                    DSI_HOST_BITS(0X068, 1, 1)
+#define TEAR_FX_EN                     DSI_HOST_BITS(0X068, 1, 0)
+#define GEN_WC_MSBYTE          DSI_HOST_BITS(0X06C, 14, 16)
+#define GEN_WC_LSBYTE          DSI_HOST_BITS(0X06C, 8, 8)
+#define GEN_VC                         DSI_HOST_BITS(0X06C, 2, 6)
+#define GEN_DT                         DSI_HOST_BITS(0X06C, 6, 0)
+#define GEN_PLD_DATA           DSI_HOST_BITS(0X070, 32, 0)
+#define GEN_RD_CMD_BUSY                DSI_HOST_BITS(0X074, 1, 6)
+#define GEN_PLD_R_FULL         DSI_HOST_BITS(0X074, 1, 5)
+#define GEN_PLD_R_EMPTY                DSI_HOST_BITS(0X074, 1, 4)
+#define GEN_PLD_W_FULL         DSI_HOST_BITS(0X074, 1, 3)
+#define GEN_PLD_W_EMPTY                DSI_HOST_BITS(0X074, 1, 2)
+#define GEN_CMD_FULL           DSI_HOST_BITS(0X074, 1, 1)
+#define GEN_CMD_EMPTY          DSI_HOST_BITS(0X074, 1, 0)
+#define HSTX_TO_CNT                    DSI_HOST_BITS(0X078, 16, 16)
+#define LPRX_TO_CNT                    DSI_HOST_BITS(0X078, 16, 0)
+#define HS_RD_TO_CNT           DSI_HOST_BITS(0X07C, 16, 0)
+#define LP_RD_TO_CNT           DSI_HOST_BITS(0X080, 16, 0)
+#define PRESP_TO_MODE          DSI_HOST_BITS(0X084, 1, 24)
+#define HS_WR_TO_CNT           DSI_HOST_BITS(0X084, 16, 0)
+#define LP_WR_TO_CNT           DSI_HOST_BITS(0X088, 16, 0)
+#define BTA_TO_CNT                     DSI_HOST_BITS(0X08C, 16, 0)
+#define AUTO_CLKLANE_CTRL      DSI_HOST_BITS(0X094, 1, 1)
+#define PHY_TXREQUESTCLKHS     DSI_HOST_BITS(0X094, 1, 0)
+#define PHY_HS2LP_TIME_CLK_LANE        DSI_HOST_BITS(0X098, 10, 16)
+#define PHY_HS2HS_TIME_CLK_LANE        DSI_HOST_BITS(0X098, 10, 0)
+#define PHY_HS2LP_TIME         DSI_HOST_BITS(0X09C, 8, 24)
+#define PHY_LP2HS_TIME         DSI_HOST_BITS(0X09C, 8, 16)
+#define MAX_RD_TIME                    DSI_HOST_BITS(0X09C, 15, 0)
+#define PHY_FORCEPLL           DSI_HOST_BITS(0X0A0, 1, 3)
+#define PHY_ENABLECLK          DSI_HOST_BITS(0X0A0, 1, 2)
+#define PHY_RSTZ                       DSI_HOST_BITS(0X0A0, 1, 1)
+#define PHY_SHUTDOWNZ          DSI_HOST_BITS(0X0A0, 1, 0)
+#define PHY_STOP_WAIT_TIME     DSI_HOST_BITS(0X0A4, 8, 8)
+#define N_LANES                                DSI_HOST_BITS(0X0A4, 2, 0)
+#define PHY_TXEXITULPSLAN      DSI_HOST_BITS(0X0A8, 1, 3)
+#define PHY_TXREQULPSLAN       DSI_HOST_BITS(0X0A8, 1, 2)
+#define PHY_TXEXITULPSCLK      DSI_HOST_BITS(0X0A8, 1, 1)
+#define PHY_TXREQULPSCLK       DSI_HOST_BITS(0X0A8, 1, 0)
+#define PHY_TX_TRIGGERS                DSI_HOST_BITS(0X0AC, 4, 0)
+#define PHYSTOPSTATECLKLANE    DSI_HOST_BITS(0X0B0, 1, 2)
+#define PHYLOCK                                DSI_HOST_BITS(0X0B0, 1, 0)
+#define PHY_TESTCLK                    DSI_HOST_BITS(0X0B4, 1, 1)
+#define PHY_TESTCLR                    DSI_HOST_BITS(0X0B4, 1, 0)
+#define PHY_TESTEN                     DSI_HOST_BITS(0X0B8, 1, 16)
+#define PHY_TESTDOUT           DSI_HOST_BITS(0X0B8, 8, 8)
+#define PHY_TESTDIN                    DSI_HOST_BITS(0X0B8, 8, 0)
+#define PHY_TEST_CTRL1         DSI_HOST_BITS(0X0B8, 17, 0)
+#define PHY_TEST_CTRL0         DSI_HOST_BITS(0X0B4, 2, 0)
+#define INT_ST0                                DSI_HOST_BITS(0X0BC, 21, 0)
+#define INT_ST1                                DSI_HOST_BITS(0X0C0, 18, 0)
+#define INT_MKS0                       DSI_HOST_BITS(0X0C4, 21, 0)
+#define INT_MKS1                       DSI_HOST_BITS(0X0C8, 18, 0)
+#define INT_FORCE0                     DSI_HOST_BITS(0X0D8, 21, 0)
+#define INT_FORCE1                     DSI_HOST_BITS(0X0DC, 18, 0)
+
+#define code_hs_rx_clock       0x34
+#define code_hs_rx_lane0       0x44
+#define code_hs_rx_lane1       0x54
+#define code_hs_rx_lane2       0x84
+#define code_hs_rx_lane3       0x94
+
+#define code_pll_input_div_rat 0x17
+#define code_pll_loop_div_rat  0x18
+#define code_pll_vcorange_vcocap       0x10
+#define code_pll_input_loop_div_rat    0x19
+#define code_pll_cpctrl        0x11
+
+#define code_hstxdatalanerequsetstatetime      0x70
+#define code_hstxdatalanepreparestatetime      0x71
+#define code_hstxdatalanehszerostatetime       0x72
+
+enum vid_mode_type_enum {
+       NON_BURST_SYNC_PLUSE = 0,
+       NON_BURST_SYNC_EVENT,
+       BURST_MODE,
+};
+
+enum cmd_video_mode {
+       VIDEO_MODE = 0,
+       CMD_MODE,
+};
+
+enum dpi_color_coding {
+       DPI_16BIT_CFG_1 = 0,
+       DPI_16BIT_CFG_2,
+       DPI_16BIT_CFG_3,
+       DPI_18BIT_CFG_1,
+       DPI_18BIT_CFG_2,
+       DPI_24BIT,
+       DPI_20BIT_YCBCR_422_LP,
+       DPI_24BIT_YCBCR_422,
+       DPI_16BIT_YCBCR_422,
+       DPI_30BIT,
+       DPI_36BIT,
+       DPI_12BIT_YCBCR_420,
+};
+
+enum  vop_id {
+       VOP_B = 0,
+       VOP_L,
+};
+
+/*
+ * Name :rk_write_reg(reg,val)
+ *
+ * reg: register name from the above define file,it contain the addr,
+ *      bits number and bits offset
+ * val: reg value that will be writen to register, it can't be over
+ *      the real bit num limit, For example, TO_CLK_DIVISION have 8
+ *      bits space, so it's value can't great than 255
+ */
+#define GET_VAL(reg, val) ((val & (~(0xffffffff << ((reg & 0xffff) >> 8)))) \
+               << (reg&0xff)) | ((readl((reg >> 16)+MIPI_DSI_HOST0_BASE)) & \
+               (~((0xffffffff<<(reg&0xff))&(0xffffffff>>\
+               (32-(reg&0xff)-((reg>>8)&0xff))))))
+#define GET_ADDR(reg) (reg >> 16)+MIPI_DSI_HOST0_BASE
+#define rk_write_reg(reg, val) writel(GET_VAL(reg, val), GET_ADDR(reg));
+
+#endif /* end of RK33_MIPI_DSI_H */
arch/arm/include/asm/arch-rockchip/vop_rk3288.h +1 -0
index 0ce3d67..d5599ec 100644
@@ -90,6 +90,7 @@ enum vop_modes {
        VOP_MODE_EDP = 0,
        VOP_MODE_HDMI,
        VOP_MODE_LVDS,
+       VOP_MODE_MIPI,
        VOP_MODE_NONE,
        VOP_MODE_AUTO_DETECT,
        VOP_MODE_UNKNOWN,
configs/evb-rk3399_defconfig +4 -0
index aac6d2d..b9cb0e8 100644
@@ -64,3 +64,7 @@ CONFIG_PMIC_CHILDREN=y
 CONFIG_SPL_PMIC_CHILDREN=y
 CONFIG_PMIC_RK808=y
 CONFIG_REGULATOR_RK808=y
+CONFIG_DM_VIDEO=y
+CONFIG_DISPLAY=y
+CONFIG_VIDEO_ROCKCHIP=y
+CONFIG_DISPLAY_MIPI=y
drivers/video/Kconfig +2 -0
index 2069576..4b03a9a 100644
@@ -405,6 +405,8 @@ config VIDEO_ROCKCHIP
           (DSI). This driver supports the on-chip video output device, and
           targets the Rockchip RK3288.
 
+source "drivers/video/rockchip/Kconfig"
+
 config VIDEO_SANDBOX_SDL
        bool "Enable sandbox video console using SDL"
        depends on SANDBOX
drivers/video/rockchip/Kconfig new file +44 -0
new file mode 100644
index 0000000..72473f6
@@ -0,0 +1,44 @@
+#
+# video drivers configuration
+# for rockchip soc
+#
+
+menu "Video Display Port Select"
+
+config DISPLAY_MIPI
+       bool "MIPI Port"
+       depends on VIDEO_ROCKCHIP
+       help
+               Select MIPI dsi for video port.
+               if you want to enable these function,you need
+               to turn on the DM_VIDEO,VDEIO_ROCKCHIP together
+               what is more,you shoud also enable the related
+               power,such as lcd3v3, lcd1v8,lcd1v0 and so on.
+config DISPLAY_EDP
+       bool "EDP Port"
+       depends on VIDEO_ROCKCHIP
+       help
+               Select EDP for video port.
+               if you want to enable these function,you need
+               to turn on the DM_VIDEO,VDEIO_ROCKCHIP together
+               what is more,you shoud also enable the related
+               power,such as lcd3v3, lcd1v8,lcd1v0 and so on.
+config DISPLAY_LVDS
+       bool "LVDS Port"
+       depends on VIDEO_ROCKCHIP
+       help
+               Select LVDS for video port.
+               if you want to enable these function,you need
+               to turn on the DM_VIDEO,VDEIO_ROCKCHIP together
+               what is more,you shoud also enable the related
+               power,such as lcd3v3, lcd1v8,lcd1v0 and so on.
+config DISPLAY_HDMI
+       bool "HDMI port"
+       depends on VIDEO_ROCKCHIP
+       help
+               Select HDMI for video port
+               if you want to enable these function,you need
+               to turn on the DM_VIDEO,VDEIO_ROCKCHIP together
+               what is more,you shoud also enable the related
+               power,such as lcd3v3, lcd1v8,lcd1v0 and so on.
+endmenu
drivers/video/rockchip/Makefile +6 -1
index 7962f86..98b26ea 100644
@@ -5,4 +5,9 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
-obj-y += rk_edp.o rk_hdmi.o rk_vop.o rk_lvds.o
+obj-$(CONFIG_VIDEO_ROCKCHIP) += rk_vop.o
+obj-$(CONFIG_VIDEO_ROCKCHIP) += panel.o
+obj-$(CONFIG_DISPLAY_MIPI) += rk_mipi.o
+obj-$(CONFIG_DISPLAY_EDP) += rk_edp.o
+obj-$(CONFIG_DISPLAY_LVDS) += rk_lvds.o
+obj-$(CONFIG_DISPLAY_HDMI) += rk_hdmi.o
drivers/video/rockchip/panel.c new file +71 -0
new file mode 100644
index 0000000..8b02b0f
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <display.h>
+#include <dm.h>
+#include <edid.h>
+#include <panel.h>
+#include <asm/hardware.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <asm/arch/mipi_rk3399.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/grf_rk3288.h>
+#include <dt-bindings/clock/rk3288-cru.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int bind(struct udevice *dev)
+{
+       debug("Panel bind@%s_Line:%d\n", __func__, __LINE__);
+       return 0;
+}
+
+static int probe(struct udevice *dev)
+{
+       debug("Panel probe@%s_Line:%d\n", __func__, __LINE__);
+       return 0;
+}
+
+int rk_panel_enable_backlight(struct udevice *dev)
+{
+       struct gpio_desc bg_en, bg_pwm;
+       int node;
+
+       node = fdt_node_offset_by_compatible(gd->fdt_blob, 0, "BOE,TV080WUM");
+       if (node < 0) {
+               debug("Can't find node@%s_Line:%d\n", __func__, __LINE__);
+               return -EINVAL;
+       }
+       gpio_request_by_name_nodev(gd->fdt_blob, node, "backlight_en",
+                                  0, &bg_en, GPIOD_IS_OUT);
+       gpio_request_by_name_nodev(gd->fdt_blob, node,
+                                  "backlight_pwm", 0, &bg_pwm, GPIOD_IS_OUT);
+       if (dm_gpio_is_valid(&bg_en)) {
+               dm_gpio_set_value(&bg_en, 1);
+               dm_gpio_set_value(&bg_pwm, 1);
+       } else {
+               debug("GPIO Invalid@%s_Line:%d\n", __func__, __LINE__);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static const struct panel_ops rk_panel_ops = {
+       .enable_backlight = rk_panel_enable_backlight,
+};
+
+static const struct udevice_id rk_panel_ids[] = {
+       { .compatible = "BOE,TV080WUM" },
+       { }

drivers/video/rockchip/panel.c line 81

Quoted 10 lines
drivers/video/rockchip/panel.c new file +10 -0
+};
+
+U_BOOT_DRIVER(rk_panel) = {
+       .name   = "rk_panel",
+       .id     = UCLASS_PANEL,
+       .of_match = rk_panel_ids,
+       .bind   = bind,
+       .probe  = probe,
+       .ops    = &rk_panel_ops,
+};

Why not use simple_panel?

Quoted 420 lines
drivers/video/rockchip/rk_mipi.c new file +371 -0
new file mode 100644
index 0000000..84cfb96
@@ -0,0 +1,371 @@
+/*
+ * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <display.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <panel.h>
+#include <asm/hardware.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <asm/arch/mipi_rk3399.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/grf_rk3288.h>
+#include <dt-bindings/clock/rk3288-cru.h>
+#include <dm/uclass-internal.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct mipi_dsi {
+       u32 ref_clk;
+       u32 sys_clk;
+       u32 pix_clk;
+       u32 phy_clk;
+       u32 txbyte_clk;
+       u32 txesc_clk;
+};
+
+int rk_mipi_read_timing(struct udevice *dev, struct display_timing *timing)
+{
+       if (fdtdec_decode_display_timing
+                       (gd->fdt_blob, dev_of_offset(dev), 0, timing)) {
+               debug("%s: Failed to decode display timing\n", __func__);
+               return -EINVAL;
+       }
+       return 0;
+}
+
+int rk_mipi_dsi_enable(struct udevice *dev, struct mipi_dsi *mipi,
+                  const struct display_timing *timing)
+{
+       int node, timing_node;
+       int val;
+       struct display_plat *disp_uc_plat = dev_get_uclass_platdata(dev);
+       u32 txbyte_clk = mipi->txbyte_clk;
+       u32 txesc_clk = mipi->txesc_clk;
+
+       txesc_clk = txbyte_clk/(txbyte_clk/txesc_clk + 1);
+
+       /* Select the video source */
+       switch (disp_uc_plat->source_id) {
+       case VOP_B:
+                val = 0x1 << 16 | 0x0;
+                writel(val, GRF_BASE+RK_GRF_CON20);
+                break;
+       case VOP_L:
+                val = 0x1 << 16 | 0x1;
+                writel(val, GRF_BASE+RK_GRF_CON20);
+                break;
+       default:
+                return -EINVAL;
+       }
+
+       /* Set Controller as TX mode */
+       val = 0x1 << 28 | 0x0 << 12;
+       val |= 0xf << 20 | 0x0 << 4;
+       val |= 0xf << 16 | 0x0;
+       writel(val, GRF_BASE+RK_GRF_CON22);
+
+       /* Set Display timing parameter */
+       rk_write_reg(VID_HSA_TIME, timing->hsync_len.typ);
+       rk_write_reg(VID_HBP_TIME, timing->hback_porch.typ);
+       rk_write_reg(VID_HLINE_TIME,
+                    (timing->hsync_len.typ +
+                    timing->hback_porch.typ +
+                    timing->hactive.typ +
+                    timing->hfront_porch.typ));
+       rk_write_reg(VID_VSA_LINES, timing->vsync_len.typ);
+       rk_write_reg(VID_VBP_LINES, timing->vback_porch.typ);
+       rk_write_reg(VID_VFP_LINES, timing->vfront_porch.typ);
+       rk_write_reg(VID_ACTIVE_LINES, timing->vactive.typ);
+
+       /* Set Signal Polarity */
+       val = (timing->flags & DISPLAY_FLAGS_HSYNC_LOW) ? 1 : 0;
+       rk_write_reg(HSYNC_ACTIVE_LOW, val);
+
+       val = (timing->flags & DISPLAY_FLAGS_VSYNC_LOW) ? 1 : 0;
+       rk_write_reg(VSYNC_ACTIVE_LOW, val);
+
+       val = (timing->flags & DISPLAY_FLAGS_DE_LOW) ? 1 : 0;
+       rk_write_reg(DISPLAY_FLAGS_DE_LOW, val);
+
+       val = (timing->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE) ? 1 : 0;
+       rk_write_reg(COLORM_ACTIVE_LOW, val);
+
+       /* Set video mode */
+       rk_write_reg(CMD_VIDEO_MODE, VIDEO_MODE);
+
+       /* Set video mode transmission type as burst mode */
+       rk_write_reg(VID_MODE_TYPE, BURST_MODE);
+
+       /* Set pix num in a video package */
+       rk_write_reg(VID_PKT_SIZE, 0x4b0);
+
+       /* Set dpi color coding depth 24 bit */
+       timing_node = fdt_subnode_offset(gd->fdt_blob,
+                       dev_of_offset(dev), "display-timings");
+       node = fdt_first_subnode(gd->fdt_blob, timing_node);
+       val = fdtdec_get_int(gd->fdt_blob, node, "bits-per-pixel", -1);
+       switch (val) {
+       case 16:
+               rk_write_reg(DPI_COLOR_CODING, DPI_16BIT_CFG_1);
+               break;
+       case 24:
+               rk_write_reg(DPI_COLOR_CODING, DPI_24BIT);
+               break;
+       case 30:
+               rk_write_reg(DPI_COLOR_CODING, DPI_30BIT);
+               break;
+       default:
+               rk_write_reg(DPI_COLOR_CODING, DPI_24BIT);
+       }
+       /* Enable low power mode */
+       rk_write_reg(LP_CMD_EN, 1);
+       rk_write_reg(LP_HFP_EN, 1);
+       rk_write_reg(LP_VACT_EN, 1);
+       rk_write_reg(LP_VFP_EN, 1);
+       rk_write_reg(LP_VBP_EN, 1);
+       rk_write_reg(LP_VSA_EN, 1);
+
+       /* Division for timeout counter clk */
+       rk_write_reg(TO_CLK_DIVISION, 0x0a);
+
+       /* Tx esc clk division from txbyte clk */
+       rk_write_reg(TX_ESC_CLK_DIVISION, txbyte_clk/txesc_clk);
+
+       /*
+        * Timeout count for hs<->lp
+        * transation between Line period
+        */
+       rk_write_reg(HSTX_TO_CNT, 0x3e8);
+
+       /* Phy State transfer timing */
+       rk_write_reg(PHY_STOP_WAIT_TIME, 32);
+       rk_write_reg(PHY_TXREQUESTCLKHS, 1);
+       rk_write_reg(PHY_HS2LP_TIME, 0x14);
+       rk_write_reg(PHY_LP2HS_TIME, 0x10);
+       rk_write_reg(MAX_RD_TIME, 0x2710);
+
+       /* Power on */
+       rk_write_reg(SHUTDOWNZ, 1);
+
+       return 0;
+}
+
+/*
+ * rk mipi dphy write function
+ */
+static void rk_mipi_phy_write(unsigned char test_code,
+                                               unsigned char *test_data,
+                                               unsigned char size)
+{
+       int i = 0;
+       /* Write Test code */
+       rk_write_reg(PHY_TESTCLK, 1);
+       rk_write_reg(PHY_TESTDIN, test_code);
+       rk_write_reg(PHY_TESTEN, 1);
+       rk_write_reg(PHY_TESTCLK, 0);
+       rk_write_reg(PHY_TESTEN, 0);
+
+       /* Write Test data */
+       for (i = 0; i < size; i++) {
+               rk_write_reg(PHY_TESTCLK, 0);
+               rk_write_reg(PHY_TESTDIN, test_data[i]);
+               rk_write_reg(PHY_TESTCLK, 1);
+       }
+}
+
+/*
+ * mipi dphy config function. calculate the suitable prediv,
+ * feedback div,fsfreqrang value ,cap ,lpf and so on
+ * according to the given pix clk ratthe.and then enable phy
+ */
+static int rk_mipi_phy_enable(struct mipi_dsi *mipi)
+{
+       int i;
+       u64     fbdiv;
+       u64 prediv = 1;
+       u64 ddr_clk = mipi->phy_clk;
+       u32 refclk      = mipi->ref_clk;
+       u32 remain      = refclk;
+       unsigned char test_data[2] = {0};
+
+       /* dphy fsfreqrang */
+       int rang[39][2] = {
+       {90, 0x01}, {100, 0x10}, {110, 0x20}, {130, 0x01},
+       {140, 0x11}, {150, 0x21}, {170, 0x02}, {180, 0x12},
+       {200, 0x22}, {220, 0x03}, {240, 0x13}, {250, 0x23},
+       {270, 0x04}, {300, 0x14}, {330, 0x05}, {360, 0x15},
+       {400, 0x25}, {450, 0x06}, {500, 0x16}, {550, 0x07},
+       {600, 0x17}, {650, 0x08}, {700, 0x18}, {750, 0x09},
+       {800, 0x19}, {850, 0x29}, {900, 0x39}, {950, 0x0a},
+       {1000, 0x1a}, {1050, 0x2a}, {1100, 0x3a}, {1150, 0x0b},
+       {1200, 0x1b}, {1250, 0x2b}, {1300, 0x3b}, {1350, 0x0c},
+       {1400, 0x1c}, {1450, 0x2c}, {1500, 0x3c} };
+
+       /* Shutdown mode */
+       rk_write_reg(PHY_SHUTDOWNZ, 0);
+       rk_write_reg(PHY_RSTZ, 0);
+       rk_write_reg(PHY_TESTCLR, 1);
+       mdelay(10);
+       /* Pll locking */
+       rk_write_reg(PHY_TESTCLR, 0);
+       mdelay(10);
+
+       /* config cp and lfp */
+       test_data[0] = 0x80 | (ddr_clk / (200*MHz)) << 3 | 0x3;
+       rk_mipi_phy_write(0x10, test_data, 1);
+
+       test_data[0] = 0x8;
+       rk_mipi_phy_write(0x11, test_data, 1);
+
+       test_data[0] = 0x80 | 0x40;
+       rk_mipi_phy_write(0x12, test_data, 1);
+
+       /* select the suitable value for fsfreqrang reg */
+       for (i = 0; i < 39; i++) {
+               if (ddr_clk / (MHz) >= rang[i][0])
+                       break;
+       }
+       test_data[0] = rang[i][1] << 1;
+       rk_mipi_phy_write(code_hs_rx_lane0, test_data, 1);
+       /*
+        * Calculate the best ddrclk and it's
+        * corresponding div value, If the given
+        * pixelclock is great than 250M, the ddr
+        * clk will be fix 1500M.otherwise , it's
+        * equal to ddr_clk= pixclk*6.
+        */
+       for (i = 1; i < 6; i++) {
+               if ((ddr_clk * i % refclk < remain) &&
+                   (ddr_clk * i / refclk) < 512) {
+                       prediv = i;
+                       remain = ddr_clk * i % refclk;
+               }
+       }
+       fbdiv   = ddr_clk * prediv / refclk;
+       ddr_clk = refclk * fbdiv / prediv;
+       mipi->phy_clk = ddr_clk;
+       /* config prediv and feedback reg */
+       test_data[0] = prediv - 1;
+       rk_mipi_phy_write(code_pll_input_div_rat, test_data, 1);
+       mdelay(2);
+       test_data[0] = (fbdiv - 1) & 0x1f;
+       rk_mipi_phy_write(code_pll_loop_div_rat, test_data, 1);
+       mdelay(2);
+       test_data[0] = (fbdiv - 1) >> 5 | 0x80;
+       rk_mipi_phy_write(code_pll_loop_div_rat, test_data, 1);
+       mdelay(2);
+       test_data[0] = 0x30;
+       rk_mipi_phy_write(code_pll_input_loop_div_rat, test_data, 1);
+       mdelay(2);
+
+       /* rest config */
+       test_data[0] = 0x4d;
+       rk_mipi_phy_write(0x20, test_data, 1);
+
+       test_data[0] = 0x3d;
+       rk_mipi_phy_write(0x21, test_data, 1);
+
+       test_data[0] = 0xdf;
+       rk_mipi_phy_write(0x21, test_data, 1);
+
+       test_data[0] =  0x7;
+       rk_mipi_phy_write(0x22, test_data, 1);
+
+       test_data[0] = 0x80 | 0x7;
+       rk_mipi_phy_write(0x22, test_data, 1);
+
+       test_data[0] = 0x80 | 15;
+       rk_mipi_phy_write(code_hstxdatalanerequsetstatetime,
+                         test_data, 1);
+       test_data[0] = 0x80 | 85;
+       rk_mipi_phy_write(code_hstxdatalanepreparestatetime,
+                         test_data, 1);
+       test_data[0] = 0x40 | 10;
+       rk_mipi_phy_write(code_hstxdatalanehszerostatetime,
+                         test_data, 1);
+       /* enter into stop mode */
+       rk_write_reg(N_LANES, 0x03);
+       rk_write_reg(PHY_ENABLECLK, 1);
+       mdelay(10);
+       rk_write_reg(PHY_FORCEPLL, 1);
+       mdelay(10);
+       rk_write_reg(PHY_SHUTDOWNZ, 1);
+       mdelay(10);
+       rk_write_reg(PHY_RSTZ, 1);
+       mdelay(10);
+
+       return 0;
+}
+
+static int enable(struct udevice *dev, int panel_bpp,
+                               const struct display_timing *timing)
+{
+       struct udevice *panel;
+       /* Check if there are avalble panel */
+       if (uclass_first_device(UCLASS_PANEL, &panel)) {
+               debug("No panel found@%s_LINE:%d\n", __func__, __LINE__);
+               return -EINVAL;
+       }
+       return panel_enable_backlight(panel);
+}
+
+/*
+ * probe function: check panel existence and reading
+ * it's timing. then config mipi dsi controller and
+ * enable it according to the timing parameter
+ */
+static int probe(struct udevice *dev)
+{
+       struct display_timing timing;
+       struct mipi_dsi mipi;
+
+       /* Read panel timing,and save to struct timing */
+       rk_mipi_read_timing(dev, &timing);
+
+       /* fill the mipi controller parameter */
+       mipi.ref_clk    = 24*MHz;
+       mipi.sys_clk    = mipi.ref_clk;
+       mipi.pix_clk    = timing.pixelclock.typ;
+       mipi.phy_clk    = mipi.pix_clk * 6;
+       mipi.txbyte_clk = mipi.phy_clk / 8;
+       mipi.txesc_clk  = 20*MHz;
+
+       /* config mipi dsi according to timing and enable it */
+       rk_mipi_dsi_enable(dev, &mipi, &timing);
+
+       /* init mipi dsi phy */
+       rk_mipi_phy_enable(&mipi);
+
+       return 0;
+}
+
+static const struct dm_display_ops rk_mipi_dsi_ops = {
+       .read_timing = rk_mipi_read_timing,
+       .enable = enable,
+};
+
+static const struct udevice_id rk_mipi_dsi_ids[] = {
+       { .compatible = "rockchip,rk3399_mipi_dsi" },
+       { }
+};
+
+U_BOOT_DRIVER(rk_mipi_dsi) = {
+       .name   = "rk_mipi_dsi",
+       .id     = UCLASS_DISPLAY,
+       .of_match = rk_mipi_dsi_ids,
+       .probe  = probe,
+       .ops    = &rk_mipi_dsi_ops,
+};
+
drivers/video/rockchip/rk_vop.c +7 -3
index aeecb58..1de00f1 100644
@@ -109,6 +109,10 @@ void rkvop_mode_set(struct rk3288_vop *regs,
                clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN,
                                V_HDMI_OUT_EN(1));
                break;
+       case VOP_MODE_MIPI:
+               clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN,
+                               V_MIPI_OUT_EN(1));
+               break;
        case VOP_MODE_EDP:
        default:
                clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN,
@@ -245,7 +249,7 @@ int rk_display_init(struct udevice *dev, ulong fbbase,
        ret = clk_get_by_index(dev, 1, &clk);
        if (!ret)
                ret = clk_set_rate(&clk, timing.pixelclock.typ);
-       if (ret) {
+       if (!ret) {
                debug("%s: Failed to set pixel clock: ret=%d\n", __func__, ret);
                return ret;
        }
@@ -327,7 +331,7 @@ static int rk_vop_probe(struct udevice *dev)
        for (node = fdt_first_subnode(blob, port);
             node > 0;
             node = fdt_next_subnode(blob, node)) {
-               ret = rk_display_init(dev, plat->base, VIDEO_BPP16, node);
+               ret = rk_display_init(dev, plat->base, VIDEO_BPP32, node);
                if (ret)
                        debug("Device failed: ret=%d\n", ret);
                if (!ret)
@@ -342,7 +346,7 @@ static int rk_vop_bind(struct udevice *dev)
 {
        struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
 
-       plat->size = 1920 * 1080 * 2;
+       plat->size = 1920 * 1200 * 4;
 
        return 0;
 }

drivers/video/rockchip/rk_vop.c static const struct video_ops rk_vop_ops = {

Quoted 9 lines
drivers/video/rockchip/rk_vop.c +2 -1
@@ -351,6 +355,8 @@ static const struct video_ops rk_vop_ops = {
 };
 
 static const struct udevice_id rk_vop_ids[] = {
+       { .compatible = "rockchip,rk3399-vop-big" },
+       { .compatible = "rockchip,rk3399-vop-lit" },
        { .compatible = "rockchip,rk3288-vop" },
        { }
 };
--

{ .compatible = "rockchip,rk3288-vop" },

Quoted 7 lines

1.9.1

_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
https://lists.denx.de/listinfo/u-boot

#12 lore raw

PATCH 5/7 Add mipi display support for rk3399 && rk3288

In reply to eric.gao at rock-chips.com

Hi Eric,

Quoted 7 lines · On 1 April 2017 at 08:42, <[email protected]> wrote:

From: "eric.gao" <[email protected]>

---

 arch/arm/dts/rk3399-evb.dts                      |  33 ++
 arch/arm/dts/rk3399.dtsi                         |  72 +++++

Please can you put the .dts changes in a separate patch?

Quoted 4 lines
 arch/arm/include/asm/arch-rockchip/cru_rk3399.h  |   2 +-
 arch/arm/include/asm/arch-rockchip/mipi_rk3399.h | 203 +++++++++++++
 arch/arm/include/asm/arch-rockchip/vop_rk3288.h  |   1 +
 configs/evb-rk3399_defconfig                     |   4 +

Also enabling it for a board should be in a separate patch.

Quoted 6 lines
 drivers/video/Kconfig                            |   2 +
 drivers/video/rockchip/Kconfig                   |  44 +++
 drivers/video/rockchip/Makefile                  |   7 +-
 drivers/video/rockchip/panel.c                   |  81 +++++
 drivers/video/rockchip/rk_mipi.c                 | 371 +++++++++++++++++++++++
 drivers/video/rockchip/rk_vop.c                  |  12 +-

And the actual driver should be in a driver patch. So I think you want 3 patches altogether.

Quoted 161 lines
 12 files changed, 827 insertions(+), 5 deletions(-)
 create mode 100644 arch/arm/include/asm/arch-rockchip/mipi_rk3399.h
 create mode 100644 drivers/video/rockchip/Kconfig
 create mode 100644 drivers/video/rockchip/panel.c
 create mode 100644 drivers/video/rockchip/rk_mipi.c
arch/arm/dts/rk3399-evb.dts +33 -0
index 7a889c7..abb00e8 100644
@@ -52,6 +52,10 @@
                gpio = <&gpio4 25 GPIO_ACTIVE_HIGH>;
        };
 
+       panel:panel {
+               compatible = "BOE,TV080WUM";
+               status = "disabled";
+       };
        vccsys: vccsys {
                compatible = "regulator-fixed";
                regulator-name = "vccsys";
@@ -218,6 +222,35 @@
        };
 };
 
+&panel {
+       backlight_en = <&gpio1 13 GPIO_ACTIVE_HIGH>;
+       backlight_pwm = <&gpio4 18 GPIO_ACTIVE_HIGH>;
+       power-supply = <&vcc33_lcd>;
+       status = "okay";
+};
+
+&mipi_dsi {
+       status = "okay";
+       display-timings {
+               timing0 {
+               bits-per-pixel = <24>;
+               clock-frequency = <160000000>;
+               hfront-porch = <120>;
+               hsync-len = <20>;
+               hback-porch = <21>;
+               hactive = <1200>;
+               vfront-porch = <21>;
+               vsync-len = <3>;
+               vback-porch = <18>;
+               vactive = <1920>;
+               hsync-active = <0>;
+               vsync-active = <0>;
+               de-active = <1>;
+               pixelclk-active = <0>;
+               };
+       };
+};
+
 &pinctrl {
        pmic {
                pmic_int_l: pmic-int-l {
arch/arm/dts/rk3399.dtsi +72 -0
index 93e3bf4..c82e674 100644
@@ -667,6 +667,78 @@
                status = "disabled";
        };
 
+       vopl: vop at ff8f0000 {
+               u-boot,dm-pre-reloc;
+               compatible = "rockchip,rk3399-vop-lit";
+               reg = <0x0 0xff8f0000 0x0 0x3efc>;
+               interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH 0>;
+               clocks = <&cru ACLK_VOP1>, <&cru DCLK_VOP1>, <&cru HCLK_VOP1>;
+               clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
+               resets = <&cru SRST_A_VOP1>, <&cru SRST_H_VOP1>, <&cru SRST_D_VOP1>;
+               reset-names = "axi", "ahb", "dclk";
+               status = "okay";
+               vopl_out: port {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       vopl_out_mipi: endpoint at 0 {
+                               reg = <3>;
+                               remote-endpoint = <&mipi_in_vopl>;
+                       };
+               };
+       };
+
+       vopb: vop at ff900000 {
+               u-boot,dm-pre-reloc;
+               compatible = "rockchip,rk3399-vop-big";
+               reg = <0x0 0xff900000 0x0 0x3efc>;
+               interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH 0>;
+               clocks = <&cru ACLK_VOP0>, <&cru DCLK_VOP0>, <&cru HCLK_VOP0>;
+               #clock-cells = <0>;
+               clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
+               resets = <&cru SRST_A_VOP0>, <&cru SRST_H_VOP0>, <&cru SRST_D_VOP0>;
+               reset-names = "axi", "ahb", "dclk";
+               /*power-domains = <&power RK3399_PD_VOPB>;*/
+               status = "okay";
+               vopb_out: port {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       vopb_out_mipi: endpoint at 0 {
+                               reg = <3>;
+                               remote-endpoint = <&mipi_in_vopb>;
+                       };
+               };
+       };
+
+       mipi_dsi: mipi at ff960000 {
+               compatible = "rockchip,rk3399_mipi_dsi";
+               reg = <0x0 0xff960000 0x0 0x8000>;
+               interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH 0>;
+               clocks = <&cru SCLK_MIPIDPHY_REF>, <&cru PCLK_MIPI_DSI0>,
+                        <&cru SCLK_DPHY_TX0_CFG>;
+               clock-names = "ref", "pclk", "phy_cfg";
+               rockchip,grf = <&grf>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <1>;
+                       mipi_in: port {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               mipi_in_vopb: endpoint at 0 {
+                                       reg = <0>;
+                                       remote-endpoint = <&vopb_out_mipi>;
+                               };
+                               mipi_in_vopl: endpoint at 1 {
+                                       reg = <1>;
+                                       remote-endpoint = <&vopl_out_mipi>;
+                               };
+                       };
+               };
+       };
+
        pinctrl: pinctrl {
                u-boot,dm-pre-reloc;
                compatible = "rockchip,rk3399-pinctrl";
arch/arm/include/asm/arch-rockchip/cru_rk3399.h +1 -1
index cf830d0..8aa08d4 100644
@@ -74,7 +74,7 @@ check_member(rk3399_cru, sdio1_con[1], 0x594);
 #define OSC_HZ         (24*MHz)
 #define APLL_HZ                (600*MHz)
 #define GPLL_HZ                (594*MHz)
-#define CPLL_HZ                (384*MHz)
+#define CPLL_HZ                (594*MHz)
 #define PPLL_HZ                (676*MHz)
 
 #define PMU_PCLK_HZ    (48*MHz)
arch/arm/include/asm/arch-rockchip/mipi_rk3399.h new file +2 -0
new file mode 100644
index 0000000..478cb21
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2017-2025 Fuzhou Rockchip Electronics Co., Ltd

arch/arm/include/asm/arch-rockchip/mipi_rk3399.h line 12

Quoted 10 lines
arch/arm/include/asm/arch-rockchip/mipi_rk3399.h new file +10 -0
+ * author: eric.gao at rock-chips.com
+ * create date: 2017-03-31
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef RK33_MIPI_DSI_H
+#define RK33_MIPI_DSI_H
+
+#define GRF_BASE        0xFF770000

Can we get this from the device tree? We have a SYSCON for GRF I think.

arch/arm/include/asm/arch-rockchip/mipi_rk3399.h line 15

Quoted 3 lines
arch/arm/include/asm/arch-rockchip/mipi_rk3399.h new file +3 -0
+#define RK_GRF_CON20    0x06250
+#define RK_GRF_CON22    0x06258
+#define MHz 1000000

Don't we have this defined somewhere?

arch/arm/include/asm/arch-rockchip/mipi_rk3399.h line 18

Quoted 3 lines
arch/arm/include/asm/arch-rockchip/mipi_rk3399.h new file +3 -0
+
+#define MIPI_DSI_HOST0_BASE    0xff960000
+#define MIPI_DSI_HOST1_BASE    0xff968000

Can we get these from the device tree?

arch/arm/include/asm/arch-rockchip/mipi_rk3399.h line 21

Quoted 3 lines
arch/arm/include/asm/arch-rockchip/mipi_rk3399.h new file +3 -0
+
+/*
+ * function bits definition

Function bits for what? Can you expand the comment?

Quoted 123 lines
arch/arm/include/asm/arch-rockchip/mipi_rk3399.h new file +123 -0
+ * register addr | bits | offest
+ */
+#define DSI_HOST_BITS(addr, bits, bit_offset) \
+       ((addr<<16) | (bits<<8) | (bit_offset))
+
+/* DWC_DSI_VERSION_0X3133302A */
+#define VERSION                                DSI_HOST_BITS(0X000, 32, 0)
+#define SHUTDOWNZ                      DSI_HOST_BITS(0X004, 1, 0)
+#define TO_CLK_DIVISION                DSI_HOST_BITS(0X008, 8, 8)
+#define TX_ESC_CLK_DIVISION    DSI_HOST_BITS(0X008, 8, 0)
+#define DPI_VCID                       DSI_HOST_BITS(0X00C, 2, 0)
+#define EN18_LOOSELY           DSI_HOST_BITS(0X010, 1, 8)
+#define DPI_COLOR_CODING       DSI_HOST_BITS(0X010, 4, 0)
+#define COLORM_ACTIVE_LOW      DSI_HOST_BITS(0X014, 1, 4)
+#define SHUTD_ACTIVE_LOW       DSI_HOST_BITS(0X014, 1, 3)
+#define HSYNC_ACTIVE_LOW       DSI_HOST_BITS(0X014, 1, 2)
+#define VSYNC_ACTIVE_LOW       DSI_HOST_BITS(0X014, 1, 1)
+#define DATAEN_ACTIVE_LOW      DSI_HOST_BITS(0X014, 1, 0)
+#define OUTVACT_LPCMD_TIME     DSI_HOST_BITS(0X018, 8, 16)
+#define INVACT_LPCMD_TIME      DSI_HOST_BITS(0X018, 8, 0)
+#define CRC_RX_EN                      DSI_HOST_BITS(0X02C, 1, 4)
+#define ECC_RX_EN                      DSI_HOST_BITS(0X02C, 1, 3)
+#define BTA_EN                         DSI_HOST_BITS(0X02C, 1, 2)
+#define EOTP_RX_EN                     DSI_HOST_BITS(0X02C, 1, 1)
+#define EOTP_TX_EN                     DSI_HOST_BITS(0X02C, 1, 0)
+#define GEN_VID_RX                     DSI_HOST_BITS(0X030, 2, 0)
+#define CMD_VIDEO_MODE         DSI_HOST_BITS(0X034, 1, 0)
+#define VPG_ORIENTATION                DSI_HOST_BITS(0X038, 1, 24)
+#define VPG_MODE                       DSI_HOST_BITS(0X038, 1, 20)
+#define VPG_EN                         DSI_HOST_BITS(0X038, 1, 16)
+#define LP_CMD_EN                      DSI_HOST_BITS(0X038, 1, 15)
+#define FRAME_BTA_ACK_EN       DSI_HOST_BITS(0X038, 1, 14)
+#define LP_HFP_EN                      DSI_HOST_BITS(0X038, 1, 13)
+#define LP_HBP_EN                      DSI_HOST_BITS(0X038, 1, 12)
+#define LP_VACT_EN                     DSI_HOST_BITS(0X038, 1, 11)
+#define LP_VFP_EN                      DSI_HOST_BITS(0X038, 1, 10)
+#define LP_VBP_EN                      DSI_HOST_BITS(0X038, 1, 9)
+#define LP_VSA_EN                      DSI_HOST_BITS(0X038, 1, 8)
+#define VID_MODE_TYPE          DSI_HOST_BITS(0X038, 2, 0)
+#define VID_PKT_SIZE           DSI_HOST_BITS(0X03C, 14, 0)
+#define NUM_CHUNKS                     DSI_HOST_BITS(0X040, 13, 0)
+#define NULL_PKT_SIZE          DSI_HOST_BITS(0X044, 13, 0)
+#define VID_HSA_TIME           DSI_HOST_BITS(0X048, 12, 0)
+#define VID_HBP_TIME           DSI_HOST_BITS(0X04C, 12, 0)
+#define VID_HLINE_TIME         DSI_HOST_BITS(0X050, 15, 0)
+#define VID_VSA_LINES          DSI_HOST_BITS(0X054, 10, 0)
+#define VID_VBP_LINES          DSI_HOST_BITS(0X058, 10, 0)
+#define VID_VFP_LINES          DSI_HOST_BITS(0X05C, 10, 0)
+#define VID_ACTIVE_LINES       DSI_HOST_BITS(0X060, 14, 0)
+#define EDPI_CMD_SIZE          DSI_HOST_BITS(0X064, 16, 0)
+#define MAX_RD_PKT_SIZE                DSI_HOST_BITS(0X068, 1, 24)
+#define DCS_LW_TX                      DSI_HOST_BITS(0X068, 1, 19)
+#define DCS_SR_0P_TX           DSI_HOST_BITS(0X068, 1, 18)
+#define DCS_SW_1P_TX           DSI_HOST_BITS(0X068, 1, 17)
+#define DCS_SW_0P_TX           DSI_HOST_BITS(0X068, 1, 16)
+#define GEN_LW_TX                      DSI_HOST_BITS(0X068, 1, 14)
+#define GEN_SR_2P_TX           DSI_HOST_BITS(0X068, 1, 13)
+#define GEN_SR_1P_TX           DSI_HOST_BITS(0X068, 1, 12)
+#define GEN_SR_0P_TX           DSI_HOST_BITS(0X068, 1, 11)
+#define GEN_SW_2P_TX           DSI_HOST_BITS(0X068, 1, 10)
+#define GEN_SW_1P_TX           DSI_HOST_BITS(0X068, 1, 9)
+#define GEN_SW_0P_TX           DSI_HOST_BITS(0X068, 1, 8)
+#define ACK_RQST_EN                    DSI_HOST_BITS(0X068, 1, 1)
+#define TEAR_FX_EN                     DSI_HOST_BITS(0X068, 1, 0)
+#define GEN_WC_MSBYTE          DSI_HOST_BITS(0X06C, 14, 16)
+#define GEN_WC_LSBYTE          DSI_HOST_BITS(0X06C, 8, 8)
+#define GEN_VC                         DSI_HOST_BITS(0X06C, 2, 6)
+#define GEN_DT                         DSI_HOST_BITS(0X06C, 6, 0)
+#define GEN_PLD_DATA           DSI_HOST_BITS(0X070, 32, 0)
+#define GEN_RD_CMD_BUSY                DSI_HOST_BITS(0X074, 1, 6)
+#define GEN_PLD_R_FULL         DSI_HOST_BITS(0X074, 1, 5)
+#define GEN_PLD_R_EMPTY                DSI_HOST_BITS(0X074, 1, 4)
+#define GEN_PLD_W_FULL         DSI_HOST_BITS(0X074, 1, 3)
+#define GEN_PLD_W_EMPTY                DSI_HOST_BITS(0X074, 1, 2)
+#define GEN_CMD_FULL           DSI_HOST_BITS(0X074, 1, 1)
+#define GEN_CMD_EMPTY          DSI_HOST_BITS(0X074, 1, 0)
+#define HSTX_TO_CNT                    DSI_HOST_BITS(0X078, 16, 16)
+#define LPRX_TO_CNT                    DSI_HOST_BITS(0X078, 16, 0)
+#define HS_RD_TO_CNT           DSI_HOST_BITS(0X07C, 16, 0)
+#define LP_RD_TO_CNT           DSI_HOST_BITS(0X080, 16, 0)
+#define PRESP_TO_MODE          DSI_HOST_BITS(0X084, 1, 24)
+#define HS_WR_TO_CNT           DSI_HOST_BITS(0X084, 16, 0)
+#define LP_WR_TO_CNT           DSI_HOST_BITS(0X088, 16, 0)
+#define BTA_TO_CNT                     DSI_HOST_BITS(0X08C, 16, 0)
+#define AUTO_CLKLANE_CTRL      DSI_HOST_BITS(0X094, 1, 1)
+#define PHY_TXREQUESTCLKHS     DSI_HOST_BITS(0X094, 1, 0)
+#define PHY_HS2LP_TIME_CLK_LANE        DSI_HOST_BITS(0X098, 10, 16)
+#define PHY_HS2HS_TIME_CLK_LANE        DSI_HOST_BITS(0X098, 10, 0)
+#define PHY_HS2LP_TIME         DSI_HOST_BITS(0X09C, 8, 24)
+#define PHY_LP2HS_TIME         DSI_HOST_BITS(0X09C, 8, 16)
+#define MAX_RD_TIME                    DSI_HOST_BITS(0X09C, 15, 0)
+#define PHY_FORCEPLL           DSI_HOST_BITS(0X0A0, 1, 3)
+#define PHY_ENABLECLK          DSI_HOST_BITS(0X0A0, 1, 2)
+#define PHY_RSTZ                       DSI_HOST_BITS(0X0A0, 1, 1)
+#define PHY_SHUTDOWNZ          DSI_HOST_BITS(0X0A0, 1, 0)
+#define PHY_STOP_WAIT_TIME     DSI_HOST_BITS(0X0A4, 8, 8)
+#define N_LANES                                DSI_HOST_BITS(0X0A4, 2, 0)
+#define PHY_TXEXITULPSLAN      DSI_HOST_BITS(0X0A8, 1, 3)
+#define PHY_TXREQULPSLAN       DSI_HOST_BITS(0X0A8, 1, 2)
+#define PHY_TXEXITULPSCLK      DSI_HOST_BITS(0X0A8, 1, 1)
+#define PHY_TXREQULPSCLK       DSI_HOST_BITS(0X0A8, 1, 0)
+#define PHY_TX_TRIGGERS                DSI_HOST_BITS(0X0AC, 4, 0)
+#define PHYSTOPSTATECLKLANE    DSI_HOST_BITS(0X0B0, 1, 2)
+#define PHYLOCK                                DSI_HOST_BITS(0X0B0, 1, 0)
+#define PHY_TESTCLK                    DSI_HOST_BITS(0X0B4, 1, 1)
+#define PHY_TESTCLR                    DSI_HOST_BITS(0X0B4, 1, 0)
+#define PHY_TESTEN                     DSI_HOST_BITS(0X0B8, 1, 16)
+#define PHY_TESTDOUT           DSI_HOST_BITS(0X0B8, 8, 8)
+#define PHY_TESTDIN                    DSI_HOST_BITS(0X0B8, 8, 0)
+#define PHY_TEST_CTRL1         DSI_HOST_BITS(0X0B8, 17, 0)
+#define PHY_TEST_CTRL0         DSI_HOST_BITS(0X0B4, 2, 0)
+#define INT_ST0                                DSI_HOST_BITS(0X0BC, 21, 0)
+#define INT_ST1                                DSI_HOST_BITS(0X0C0, 18, 0)
+#define INT_MKS0                       DSI_HOST_BITS(0X0C4, 21, 0)
+#define INT_MKS1                       DSI_HOST_BITS(0X0C8, 18, 0)
+#define INT_FORCE0                     DSI_HOST_BITS(0X0D8, 21, 0)
+#define INT_FORCE1                     DSI_HOST_BITS(0X0DC, 18, 0)
+
+#define code_hs_rx_clock       0x34
+#define code_hs_rx_lane0       0x44
+#define code_hs_rx_lane1       0x54
+#define code_hs_rx_lane2       0x84
+#define code_hs_rx_lane3       0x94

arch/arm/include/asm/arch-rockchip/mipi_rk3399.h line 154

Quoted 10 lines
arch/arm/include/asm/arch-rockchip/mipi_rk3399.h new file +10 -0
+
+#define code_pll_input_div_rat 0x17
+#define code_pll_loop_div_rat  0x18
+#define code_pll_vcorange_vcocap       0x10
+#define code_pll_input_loop_div_rat    0x19
+#define code_pll_cpctrl        0x11
+
+#define code_hstxdatalanerequsetstatetime      0x70
+#define code_hstxdatalanepreparestatetime      0x71
+#define code_hstxdatalanehszerostatetime       0x72

Please use all caps for these defines.

arch/arm/include/asm/arch-rockchip/mipi_rk3399.h line 156

Quoted 2 lines
arch/arm/include/asm/arch-rockchip/mipi_rk3399.h new file +2 -0
+
+enum vid_mode_type_enum {

How about vid_mode_type_t as it is shorter

Quoted 33 lines
arch/arm/include/asm/arch-rockchip/mipi_rk3399.h new file +33 -0
+       NON_BURST_SYNC_PLUSE = 0,
+       NON_BURST_SYNC_EVENT,
+       BURST_MODE,
+};
+
+enum cmd_video_mode {
+       VIDEO_MODE = 0,
+       CMD_MODE,
+};
+
+enum dpi_color_coding {
+       DPI_16BIT_CFG_1 = 0,
+       DPI_16BIT_CFG_2,
+       DPI_16BIT_CFG_3,
+       DPI_18BIT_CFG_1,
+       DPI_18BIT_CFG_2,
+       DPI_24BIT,
+       DPI_20BIT_YCBCR_422_LP,
+       DPI_24BIT_YCBCR_422,
+       DPI_16BIT_YCBCR_422,
+       DPI_30BIT,
+       DPI_36BIT,
+       DPI_12BIT_YCBCR_420,
+};
+
+enum  vop_id {
+       VOP_B = 0,
+       VOP_L,
+};
+
+/*
+ * Name :rk_write_reg(reg,val)
+ *

arch/arm/include/asm/arch-rockchip/mipi_rk3399.h line 199

Quoted 10 lines
arch/arm/include/asm/arch-rockchip/mipi_rk3399.h new file +10 -0
+ * reg: register name from the above define file,it contain the addr,
+ *      bits number and bits offset
+ * val: reg value that will be writen to register, it can't be over
+ *      the real bit num limit, For example, TO_CLK_DIVISION have 8
+ *      bits space, so it's value can't great than 255
+ */
+#define GET_VAL(reg, val) ((val & (~(0xffffffff << ((reg & 0xffff) >> 8)))) \
+               << (reg&0xff)) | ((readl((reg >> 16)+MIPI_DSI_HOST0_BASE)) & \
+               (~((0xffffffff<<(reg&0xff))&(0xffffffff>>\
+               (32-(reg&0xff)-((reg>>8)&0xff))))))

What is the purpose of this? Could it instead be a table of values?

struct something {
u8 addr;
u8 bits;
u8 offset;
}

static const struct something some_table[] = {
{ 1, 2, 3},
...
};

arch/arm/include/asm/arch-rockchip/mipi_rk3399.h line 200

Quoted 1 line
arch/arm/include/asm/arch-rockchip/mipi_rk3399.h new file +1 -0
+#define GET_ADDR(reg) (reg >> 16)+MIPI_DSI_HOST0_BASE

Can we drop this one?

arch/arm/include/asm/arch-rockchip/mipi_rk3399.h line 201

Quoted 1 line
arch/arm/include/asm/arch-rockchip/mipi_rk3399.h new file +1 -0
+#define rk_write_reg(reg, val) writel(GET_VAL(reg, val), GET_ADDR(reg));

Is this different from rk_clrsetreg() ? Can you put this next to that function?

Quoted 74 lines
arch/arm/include/asm/arch-rockchip/mipi_rk3399.h new file +2 -0
+
+#endif /* end of RK33_MIPI_DSI_H */
arch/arm/include/asm/arch-rockchip/vop_rk3288.h +1 -0
index 0ce3d67..d5599ec 100644
@@ -90,6 +90,7 @@ enum vop_modes {
        VOP_MODE_EDP = 0,
        VOP_MODE_HDMI,
        VOP_MODE_LVDS,
+       VOP_MODE_MIPI,
        VOP_MODE_NONE,
        VOP_MODE_AUTO_DETECT,
        VOP_MODE_UNKNOWN,
configs/evb-rk3399_defconfig +4 -0
index aac6d2d..b9cb0e8 100644
@@ -64,3 +64,7 @@ CONFIG_PMIC_CHILDREN=y
 CONFIG_SPL_PMIC_CHILDREN=y
 CONFIG_PMIC_RK808=y
 CONFIG_REGULATOR_RK808=y
+CONFIG_DM_VIDEO=y
+CONFIG_DISPLAY=y
+CONFIG_VIDEO_ROCKCHIP=y
+CONFIG_DISPLAY_MIPI=y
drivers/video/Kconfig +2 -0
index 2069576..4b03a9a 100644
@@ -405,6 +405,8 @@ config VIDEO_ROCKCHIP
           (DSI). This driver supports the on-chip video output device, and
           targets the Rockchip RK3288.
 
+source "drivers/video/rockchip/Kconfig"
+
 config VIDEO_SANDBOX_SDL
        bool "Enable sandbox video console using SDL"
        depends on SANDBOX
drivers/video/rockchip/Kconfig new file +29 -0
new file mode 100644
index 0000000..72473f6
@@ -0,0 +1,44 @@
+#
+# video drivers configuration
+# for rockchip soc
+#
+
+menu "Video Display Port Select"
+
+config DISPLAY_MIPI
+       bool "MIPI Port"
+       depends on VIDEO_ROCKCHIP
+       help
+               Select MIPI dsi for video port.
+               if you want to enable these function,you need
+               to turn on the DM_VIDEO,VDEIO_ROCKCHIP together
+               what is more,you shoud also enable the related
+               power,such as lcd3v3, lcd1v8,lcd1v0 and so on.
+config DISPLAY_EDP
+       bool "EDP Port"
+       depends on VIDEO_ROCKCHIP
+       help
+               Select EDP for video port.
+               if you want to enable these function,you need
+               to turn on the DM_VIDEO,VDEIO_ROCKCHIP together
+               what is more,you shoud also enable the related
+               power,such as lcd3v3, lcd1v8,lcd1v0 and so on.
+config DISPLAY_LVDS
+       bool "LVDS Port"
+       depends on VIDEO_ROCKCHIP
+       help

drivers/video/rockchip/Kconfig line 39

Quoted 10 lines
drivers/video/rockchip/Kconfig new file +10 -0
+               Select LVDS for video port.
+               if you want to enable these function,you need
+               to turn on the DM_VIDEO,VDEIO_ROCKCHIP together
+               what is more,you shoud also enable the related
+               power,such as lcd3v3, lcd1v8,lcd1v0 and so on.
+config DISPLAY_HDMI
+       bool "HDMI port"
+       depends on VIDEO_ROCKCHIP
+       help
+               Select HDMI for video port

There are two different things:

- Compiling in the driver
- Deciding which one to use

Here I think you have one config for both. I think the config should just decide whether to compile in the driver. The device tree, or some environment variable, should select which to use.

drivers/video/rockchip/Kconfig line 44

Quoted 5 lines
drivers/video/rockchip/Kconfig new file +5 -0
+               if you want to enable these function,you need
+               to turn on the DM_VIDEO,VDEIO_ROCKCHIP together
+               what is more,you shoud also enable the related
+               power,such as lcd3v3, lcd1v8,lcd1v0 and so on.
+endmenu

Is it possible to have more than one port? The above settings are in the device tree, aren't they? For example on firefly I think it uses HDMI if it can detect it.

Quoted 21 lines
drivers/video/rockchip/Makefile +6 -1
index 7962f86..98b26ea 100644
@@ -5,4 +5,9 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
-obj-y += rk_edp.o rk_hdmi.o rk_vop.o rk_lvds.o
+obj-$(CONFIG_VIDEO_ROCKCHIP) += rk_vop.o
+obj-$(CONFIG_VIDEO_ROCKCHIP) += panel.o
+obj-$(CONFIG_DISPLAY_MIPI) += rk_mipi.o
+obj-$(CONFIG_DISPLAY_EDP) += rk_edp.o
+obj-$(CONFIG_DISPLAY_LVDS) += rk_lvds.o
+obj-$(CONFIG_DISPLAY_HDMI) += rk_hdmi.o
drivers/video/rockchip/panel.c new file +0 -0
new file mode 100644
index 0000000..8b02b0f

drivers/video/rockchip/panel.c line 7

Quoted 7 lines
drivers/video/rockchip/panel.c new file +7 -0
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.

Can you use SPDX?

Quoted 13 lines
drivers/video/rockchip/panel.c new file +13 -0
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <display.h>
+#include <dm.h>
+#include <edid.h>
+#include <panel.h>
+#include <asm/hardware.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/gpio.h>
+#include <asm/io.h>

drivers/video/rockchip/panel.c line 30

Quoted 10 lines
drivers/video/rockchip/panel.c new file +10 -0
+#include <asm/arch/mipi_rk3399.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/grf_rk3288.h>
+#include <dt-bindings/clock/rk3288-cru.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int bind(struct udevice *dev)
+{
+       debug("Panel bind@%s_Line:%d\n", __func__, __LINE__);

Please put a blank line before the last return in a function

drivers/video/rockchip/panel.c line 40

Quoted 10 lines
drivers/video/rockchip/panel.c new file +10 -0
+       return 0;
+}
+
+static int probe(struct udevice *dev)
+{
+       debug("Panel probe@%s_Line:%d\n", __func__, __LINE__);
+       return 0;
+}
+
+int rk_panel_enable_backlight(struct udevice *dev)

static

drivers/video/rockchip/panel.c line 49

Quoted 9 lines
drivers/video/rockchip/panel.c new file +9 -0
+{
+       struct gpio_desc bg_en, bg_pwm;
+       int node;
+
+       node = fdt_node_offset_by_compatible(gd->fdt_blob, 0, "BOE,TV080WUM");
+       if (node < 0) {
+               debug("Can't find node@%s_Line:%d\n", __func__, __LINE__);
+               return -EINVAL;
+       }

This should be obtained via a phandle to a panel node, not searching for a particular compatible string.

drivers/video/rockchip/panel.c line 51

Quoted 2 lines
drivers/video/rockchip/panel.c new file +2 -0
+       gpio_request_by_name_nodev(gd->fdt_blob, node, "backlight_en",
+                                  0, &bg_en, GPIOD_IS_OUT);

This is a driver so you should be able to use the normal gpio_request_by_name()

Quoted 42 lines
drivers/video/rockchip/panel.c new file +30 -0
+       gpio_request_by_name_nodev(gd->fdt_blob, node,
+                                  "backlight_pwm", 0, &bg_pwm, GPIOD_IS_OUT);
+       if (dm_gpio_is_valid(&bg_en)) {
+               dm_gpio_set_value(&bg_en, 1);
+               dm_gpio_set_value(&bg_pwm, 1);
+       } else {
+               debug("GPIO Invalid@%s_Line:%d\n", __func__, __LINE__);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static const struct panel_ops rk_panel_ops = {
+       .enable_backlight = rk_panel_enable_backlight,
+};
+
+static const struct udevice_id rk_panel_ids[] = {
+       { .compatible = "BOE,TV080WUM" },
+       { }
+};
+
+U_BOOT_DRIVER(rk_panel) = {
+       .name   = "rk_panel",
+       .id     = UCLASS_PANEL,
+       .of_match = rk_panel_ids,
+       .bind   = bind,
+       .probe  = probe,
+       .ops    = &rk_panel_ops,
+};
drivers/video/rockchip/rk_mipi.c new file +6 -0
new file mode 100644
index 0000000..84cfb96
@@ -0,0 +1,371 @@
+/*
+ * Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or

drivers/video/rockchip/rk_mipi.c line 16

Quoted 10 lines
drivers/video/rockchip/rk_mipi.c new file +10 -0
+ * (at your option) any later version.
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <display.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <panel.h>
+#include <asm/hardware.h>

This does below with the other asms.

Quoted 37 lines
drivers/video/rockchip/rk_mipi.c new file +37 -0
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <asm/arch/mipi_rk3399.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/grf_rk3288.h>
+#include <dt-bindings/clock/rk3288-cru.h>
+#include <dm/uclass-internal.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct mipi_dsi {
+       u32 ref_clk;
+       u32 sys_clk;
+       u32 pix_clk;
+       u32 phy_clk;
+       u32 txbyte_clk;
+       u32 txesc_clk;
+};
+
+int rk_mipi_read_timing(struct udevice *dev, struct display_timing *timing)
+{
+       if (fdtdec_decode_display_timing
+                       (gd->fdt_blob, dev_of_offset(dev), 0, timing)) {
+               debug("%s: Failed to decode display timing\n", __func__);
+               return -EINVAL;
+       }
+       return 0;
+}
+
+int rk_mipi_dsi_enable(struct udevice *dev, struct mipi_dsi *mipi,
+                  const struct display_timing *timing)
+{
+       int node, timing_node;
+       int val;
+       struct display_plat *disp_uc_plat = dev_get_uclass_platdata(dev);

drivers/video/rockchip/rk_mipi.c line 63

Quoted 10 lines
drivers/video/rockchip/rk_mipi.c new file +10 -0
+       u32 txbyte_clk = mipi->txbyte_clk;
+       u32 txesc_clk = mipi->txesc_clk;
+
+       txesc_clk = txbyte_clk/(txbyte_clk/txesc_clk + 1);
+
+       /* Select the video source */
+       switch (disp_uc_plat->source_id) {
+       case VOP_B:
+                val = 0x1 << 16 | 0x0;
+                writel(val, GRF_BASE+RK_GRF_CON20);

Spaces around +

GRF_BASE should come from a SYSCON or a phandle. Set it up in your ofdata_to_platdata() method, then you can use it in the driver.

drivers/video/rockchip/rk_mipi.c line 66

Quoted 3 lines
drivers/video/rockchip/rk_mipi.c new file +3 -0
+                break;
+       case VOP_L:
+                val = 0x1 << 16 | 0x1;

Can you have defines for these things?

drivers/video/rockchip/rk_mipi.c line 77

Quoted 11 lines
drivers/video/rockchip/rk_mipi.c new file +11 -0
+                writel(val, GRF_BASE+RK_GRF_CON20);
+                break;
+       default:
+                return -EINVAL;
+       }
+
+       /* Set Controller as TX mode */
+       val = 0x1 << 28 | 0x0 << 12;
+       val |= 0xf << 20 | 0x0 << 4;
+       val |= 0xf << 16 | 0x0;
+       writel(val, GRF_BASE+RK_GRF_CON22);

Defines for these?

Quoted 116 lines
drivers/video/rockchip/rk_mipi.c new file +116 -0
+
+       /* Set Display timing parameter */
+       rk_write_reg(VID_HSA_TIME, timing->hsync_len.typ);
+       rk_write_reg(VID_HBP_TIME, timing->hback_porch.typ);
+       rk_write_reg(VID_HLINE_TIME,
+                    (timing->hsync_len.typ +
+                    timing->hback_porch.typ +
+                    timing->hactive.typ +
+                    timing->hfront_porch.typ));
+       rk_write_reg(VID_VSA_LINES, timing->vsync_len.typ);
+       rk_write_reg(VID_VBP_LINES, timing->vback_porch.typ);
+       rk_write_reg(VID_VFP_LINES, timing->vfront_porch.typ);
+       rk_write_reg(VID_ACTIVE_LINES, timing->vactive.typ);
+
+       /* Set Signal Polarity */
+       val = (timing->flags & DISPLAY_FLAGS_HSYNC_LOW) ? 1 : 0;
+       rk_write_reg(HSYNC_ACTIVE_LOW, val);
+
+       val = (timing->flags & DISPLAY_FLAGS_VSYNC_LOW) ? 1 : 0;
+       rk_write_reg(VSYNC_ACTIVE_LOW, val);
+
+       val = (timing->flags & DISPLAY_FLAGS_DE_LOW) ? 1 : 0;
+       rk_write_reg(DISPLAY_FLAGS_DE_LOW, val);
+
+       val = (timing->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE) ? 1 : 0;
+       rk_write_reg(COLORM_ACTIVE_LOW, val);
+
+       /* Set video mode */
+       rk_write_reg(CMD_VIDEO_MODE, VIDEO_MODE);
+
+       /* Set video mode transmission type as burst mode */
+       rk_write_reg(VID_MODE_TYPE, BURST_MODE);
+
+       /* Set pix num in a video package */
+       rk_write_reg(VID_PKT_SIZE, 0x4b0);
+
+       /* Set dpi color coding depth 24 bit */
+       timing_node = fdt_subnode_offset(gd->fdt_blob,
+                       dev_of_offset(dev), "display-timings");
+       node = fdt_first_subnode(gd->fdt_blob, timing_node);
+       val = fdtdec_get_int(gd->fdt_blob, node, "bits-per-pixel", -1);
+       switch (val) {
+       case 16:
+               rk_write_reg(DPI_COLOR_CODING, DPI_16BIT_CFG_1);
+               break;
+       case 24:
+               rk_write_reg(DPI_COLOR_CODING, DPI_24BIT);
+               break;
+       case 30:
+               rk_write_reg(DPI_COLOR_CODING, DPI_30BIT);
+               break;
+       default:
+               rk_write_reg(DPI_COLOR_CODING, DPI_24BIT);
+       }
+       /* Enable low power mode */
+       rk_write_reg(LP_CMD_EN, 1);
+       rk_write_reg(LP_HFP_EN, 1);
+       rk_write_reg(LP_VACT_EN, 1);
+       rk_write_reg(LP_VFP_EN, 1);
+       rk_write_reg(LP_VBP_EN, 1);
+       rk_write_reg(LP_VSA_EN, 1);
+
+       /* Division for timeout counter clk */
+       rk_write_reg(TO_CLK_DIVISION, 0x0a);
+
+       /* Tx esc clk division from txbyte clk */
+       rk_write_reg(TX_ESC_CLK_DIVISION, txbyte_clk/txesc_clk);
+
+       /*
+        * Timeout count for hs<->lp
+        * transation between Line period
+        */
+       rk_write_reg(HSTX_TO_CNT, 0x3e8);
+
+       /* Phy State transfer timing */
+       rk_write_reg(PHY_STOP_WAIT_TIME, 32);
+       rk_write_reg(PHY_TXREQUESTCLKHS, 1);
+       rk_write_reg(PHY_HS2LP_TIME, 0x14);
+       rk_write_reg(PHY_LP2HS_TIME, 0x10);
+       rk_write_reg(MAX_RD_TIME, 0x2710);
+
+       /* Power on */
+       rk_write_reg(SHUTDOWNZ, 1);
+
+       return 0;
+}
+
+/*
+ * rk mipi dphy write function
+ */
+static void rk_mipi_phy_write(unsigned char test_code,
+                                               unsigned char *test_data,
+                                               unsigned char size)
+{
+       int i = 0;
+       /* Write Test code */
+       rk_write_reg(PHY_TESTCLK, 1);
+       rk_write_reg(PHY_TESTDIN, test_code);
+       rk_write_reg(PHY_TESTEN, 1);
+       rk_write_reg(PHY_TESTCLK, 0);
+       rk_write_reg(PHY_TESTEN, 0);
+
+       /* Write Test data */
+       for (i = 0; i < size; i++) {
+               rk_write_reg(PHY_TESTCLK, 0);
+               rk_write_reg(PHY_TESTDIN, test_data[i]);
+               rk_write_reg(PHY_TESTCLK, 1);
+       }
+}
+
+/*
+ * mipi dphy config function. calculate the suitable prediv,
+ * feedback div,fsfreqrang value ,cap ,lpf and so on
+ * according to the given pix clk ratthe.and then enable phy
+ */
+static int rk_mipi_phy_enable(struct mipi_dsi *mipi)

drivers/video/rockchip/rk_mipi.c line 203

Quoted 10 lines
drivers/video/rockchip/rk_mipi.c new file +10 -0
+{
+       int i;
+       u64     fbdiv;
+       u64 prediv = 1;
+       u64 ddr_clk = mipi->phy_clk;
+       u32 refclk      = mipi->ref_clk;
+       u32 remain      = refclk;
+       unsigned char test_data[2] = {0};
+
+       /* dphy fsfreqrang */

??

drivers/video/rockchip/rk_mipi.c line 205

Quoted 2 lines
drivers/video/rockchip/rk_mipi.c new file +2 -0
+       int rang[39][2] = {
+       {90, 0x01}, {100, 0x10}, {110, 0x20}, {130, 0x01},

Indent these lines

Quoted 21 lines
drivers/video/rockchip/rk_mipi.c new file +21 -0
+       {140, 0x11}, {150, 0x21}, {170, 0x02}, {180, 0x12},
+       {200, 0x22}, {220, 0x03}, {240, 0x13}, {250, 0x23},
+       {270, 0x04}, {300, 0x14}, {330, 0x05}, {360, 0x15},
+       {400, 0x25}, {450, 0x06}, {500, 0x16}, {550, 0x07},
+       {600, 0x17}, {650, 0x08}, {700, 0x18}, {750, 0x09},
+       {800, 0x19}, {850, 0x29}, {900, 0x39}, {950, 0x0a},
+       {1000, 0x1a}, {1050, 0x2a}, {1100, 0x3a}, {1150, 0x0b},
+       {1200, 0x1b}, {1250, 0x2b}, {1300, 0x3b}, {1350, 0x0c},
+       {1400, 0x1c}, {1450, 0x2c}, {1500, 0x3c} };
+
+       /* Shutdown mode */
+       rk_write_reg(PHY_SHUTDOWNZ, 0);
+       rk_write_reg(PHY_RSTZ, 0);
+       rk_write_reg(PHY_TESTCLR, 1);
+       mdelay(10);
+       /* Pll locking */
+       rk_write_reg(PHY_TESTCLR, 0);
+       mdelay(10);
+
+       /* config cp and lfp */
+       test_data[0] = 0x80 | (ddr_clk / (200*MHz)) << 3 | 0x3;

drivers/video/rockchip/rk_mipi.c line 236

Quoted 10 lines
drivers/video/rockchip/rk_mipi.c new file +10 -0
+       rk_mipi_phy_write(0x10, test_data, 1);
+
+       test_data[0] = 0x8;
+       rk_mipi_phy_write(0x11, test_data, 1);
+
+       test_data[0] = 0x80 | 0x40;
+       rk_mipi_phy_write(0x12, test_data, 1);
+
+       /* select the suitable value for fsfreqrang reg */
+       for (i = 0; i < 39; i++) {

What is 39? Is is ARRAY_SIZE(rang)?

drivers/video/rockchip/rk_mipi.c line 247

Quoted 11 lines
drivers/video/rockchip/rk_mipi.c new file +11 -0
+               if (ddr_clk / (MHz) >= rang[i][0])
+                       break;
+       }
+       test_data[0] = rang[i][1] << 1;
+       rk_mipi_phy_write(code_hs_rx_lane0, test_data, 1);
+       /*
+        * Calculate the best ddrclk and it's
+        * corresponding div value, If the given
+        * pixelclock is great than 250M, the ddr
+        * clk will be fix 1500M.otherwise , it's
+        * equal to ddr_clk= pixclk*6.

Can you use (say) 75 columns for this?

Quoted 14 lines
drivers/video/rockchip/rk_mipi.c new file +14 -0
+        */
+       for (i = 1; i < 6; i++) {
+               if ((ddr_clk * i % refclk < remain) &&
+                   (ddr_clk * i / refclk) < 512) {
+                       prediv = i;
+                       remain = ddr_clk * i % refclk;
+               }
+       }
+       fbdiv   = ddr_clk * prediv / refclk;
+       ddr_clk = refclk * fbdiv / prediv;
+       mipi->phy_clk = ddr_clk;
+       /* config prediv and feedback reg */
+       test_data[0] = prediv - 1;
+       rk_mipi_phy_write(code_pll_input_div_rat, test_data, 1);

drivers/video/rockchip/rk_mipi.c line 271

Quoted 10 lines
drivers/video/rockchip/rk_mipi.c new file +10 -0
+       mdelay(2);
+       test_data[0] = (fbdiv - 1) & 0x1f;
+       rk_mipi_phy_write(code_pll_loop_div_rat, test_data, 1);
+       mdelay(2);
+       test_data[0] = (fbdiv - 1) >> 5 | 0x80;
+       rk_mipi_phy_write(code_pll_loop_div_rat, test_data, 1);
+       mdelay(2);
+       test_data[0] = 0x30;
+       rk_mipi_phy_write(code_pll_input_loop_div_rat, test_data, 1);
+       mdelay(2);

What are these long delays for? Please add a comment.

Quoted 37 lines
drivers/video/rockchip/rk_mipi.c new file +36 -0
+
+       /* rest config */
+       test_data[0] = 0x4d;
+       rk_mipi_phy_write(0x20, test_data, 1);
+
+       test_data[0] = 0x3d;
+       rk_mipi_phy_write(0x21, test_data, 1);
+
+       test_data[0] = 0xdf;
+       rk_mipi_phy_write(0x21, test_data, 1);
+
+       test_data[0] =  0x7;
+       rk_mipi_phy_write(0x22, test_data, 1);
+
 
+       test_data[0] = 0x80 | 0x7;
+       rk_mipi_phy_write(0x22, test_data, 1);
+
+       test_data[0] = 0x80 | 15;
+       rk_mipi_phy_write(code_hstxdatalanerequsetstatetime,
+                         test_data, 1);
+       test_data[0] = 0x80 | 85;
+       rk_mipi_phy_write(code_hstxdatalanepreparestatetime,
+                         test_data, 1);
+       test_data[0] = 0x40 | 10;
+       rk_mipi_phy_write(code_hstxdatalanehszerostatetime,
+                         test_data, 1);
+       /* enter into stop mode */
+       rk_write_reg(N_LANES, 0x03);
+       rk_write_reg(PHY_ENABLECLK, 1);
+       mdelay(10);
+       rk_write_reg(PHY_FORCEPLL, 1);
+       mdelay(10);
+       rk_write_reg(PHY_SHUTDOWNZ, 1);
+       mdelay(10);
+       rk_write_reg(PHY_RSTZ, 1);
+       mdelay(10);

drivers/video/rockchip/rk_mipi.c line 317

Quoted 10 lines
drivers/video/rockchip/rk_mipi.c new file +10 -0
+
+       return 0;
+}
+
+static int enable(struct udevice *dev, int panel_bpp,
+                               const struct display_timing *timing)
+{
+       struct udevice *panel;
+       /* Check if there are avalble panel */
+       if (uclass_first_device(UCLASS_PANEL, &panel)) {

I suppose you can pick the first panel, but can't you use the DT to tell you which one?

See rk_lvds.c for what it does.

drivers/video/rockchip/rk_mipi.c line 329

Quoted 12 lines
drivers/video/rockchip/rk_mipi.c new file +12 -0
+               debug("No panel found@%s_LINE:%d\n", __func__, __LINE__);
+               return -EINVAL;
+       }
+       return panel_enable_backlight(panel);
+}
+
+/*
+ * probe function: check panel existence and reading
+ * it's timing. then config mipi dsi controller and
+ * enable it according to the timing parameter
+ */
+static int probe(struct udevice *dev)

Can you use rk_mipi_probe() etc. for these functions just to make them more unique?

Quoted 7 lines
drivers/video/rockchip/rk_mipi.c new file +7 -0
+{
+       struct display_timing timing;
+       struct mipi_dsi mipi;
+
+       /* Read panel timing,and save to struct timing */
+       rk_mipi_read_timing(dev, &timing);
+

drivers/video/rockchip/rk_mipi.c line 346

Quoted 10 lines
drivers/video/rockchip/rk_mipi.c new file +10 -0
+       /* fill the mipi controller parameter */
+       mipi.ref_clk    = 24*MHz;
+       mipi.sys_clk    = mipi.ref_clk;
+       mipi.pix_clk    = timing.pixelclock.typ;
+       mipi.phy_clk    = mipi.pix_clk * 6;
+       mipi.txbyte_clk = mipi.phy_clk / 8;
+       mipi.txesc_clk  = 20*MHz;
+
+       /* config mipi dsi according to timing and enable it */
+       rk_mipi_dsi_enable(dev, &mipi, &timing);

Check error?

drivers/video/rockchip/rk_mipi.c line 349

Quoted 3 lines
drivers/video/rockchip/rk_mipi.c new file +3 -0
+
+       /* init mipi dsi phy */
+       rk_mipi_phy_enable(&mipi);

Check error?

Quoted 38 lines
drivers/video/rockchip/rk_mipi.c new file +22 -0
+
+       return 0;
+}
+
+static const struct dm_display_ops rk_mipi_dsi_ops = {
+       .read_timing = rk_mipi_read_timing,
+       .enable = enable,
+};
+
+static const struct udevice_id rk_mipi_dsi_ids[] = {
+       { .compatible = "rockchip,rk3399_mipi_dsi" },
+       { }
+};
+
+U_BOOT_DRIVER(rk_mipi_dsi) = {
+       .name   = "rk_mipi_dsi",
+       .id     = UCLASS_DISPLAY,
+       .of_match = rk_mipi_dsi_ids,
+       .probe  = probe,
+       .ops    = &rk_mipi_dsi_ops,
+};
+
drivers/video/rockchip/rk_vop.c +4 -0
index aeecb58..1de00f1 100644
@@ -109,6 +109,10 @@ void rkvop_mode_set(struct rk3288_vop *regs,
                clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN,
                                V_HDMI_OUT_EN(1));
                break;
+       case VOP_MODE_MIPI:
+               clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN,
+                               V_MIPI_OUT_EN(1));
+               break;
        case VOP_MODE_EDP:
        default:
                clrsetbits_le32(&regs->sys_ctrl, M_ALL_OUT_EN,

drivers/video/rockchip/rk_vop.c int rk_display_init(struct udevice *dev, ulong fbbase, · line 252

Quoted 5 lines
drivers/video/rockchip/rk_vop.c +1 -1
@@ -245,7 +249,7 @@ int rk_display_init(struct udevice *dev, ulong fbbase,
        ret = clk_get_by_index(dev, 1, &clk);
        if (!ret)
                ret = clk_set_rate(&clk, timing.pixelclock.typ);
-       if (ret) {
+       if (!ret) {

Why is this changing?

drivers/video/rockchip/rk_vop.c static int rk_vop_probe(struct udevice *dev) · line 334

Quoted 9 lines
drivers/video/rockchip/rk_vop.c +1 -1
                debug("%s: Failed to set pixel clock: ret=%d\n", __func__, ret);
                return ret;
        }
@@ -327,7 +331,7 @@ static int rk_vop_probe(struct udevice *dev)
        for (node = fdt_first_subnode(blob, port);
             node > 0;
             node = fdt_next_subnode(blob, node)) {
-               ret = rk_display_init(dev, plat->base, VIDEO_BPP16, node);
+               ret = rk_display_init(dev, plat->base, VIDEO_BPP32, node);

Maybe we need a way to select which depth to use?

drivers/video/rockchip/rk_vop.c static int rk_vop_bind(struct udevice *dev) · line 349

Quoted 9 lines
drivers/video/rockchip/rk_vop.c +1 -1
                if (ret)
                        debug("Device failed: ret=%d\n", ret);
                if (!ret)
@@ -342,7 +346,7 @@ static int rk_vop_bind(struct udevice *dev)
 {
        struct video_uc_platdata *plat = dev_get_uclass_platdata(dev);
 
-       plat->size = 1920 * 1080 * 2;
+       plat->size = 1920 * 1200 * 4;

And it should probably calculate this, so HDMI continues to work.

Quoted 13 lines
drivers/video/rockchip/rk_vop.c +2 -1
        return 0;
 }
@@ -351,6 +355,8 @@ static const struct video_ops rk_vop_ops = {
 };
 
 static const struct udevice_id rk_vop_ids[] = {
+       { .compatible = "rockchip,rk3399-vop-big" },
+       { .compatible = "rockchip,rk3399-vop-lit" },
        { .compatible = "rockchip,rk3288-vop" },
        { }
 };
--
Quoted 3 lines

1.9.1

Regards,
Simon

#13 lore raw

PATCH 6/7 Enable print log file to lcd

In reply to eric.gao at rock-chips.com

From: "eric.gao" <[email protected]>

---

 configs/evb-rk3399_defconfig    | 1 +
 include/configs/rk3399_common.h | 5 ++++-
 2 files changed, 5 insertions(+), 1 deletion(-)
configs/evb-rk3399_defconfig +1 -0
index b9cb0e8..89b2e17 100644
@@ -68,3 +68,4 @@ CONFIG_DM_VIDEO=y
 CONFIG_DISPLAY=y
 CONFIG_VIDEO_ROCKCHIP=y
 CONFIG_DISPLAY_MIPI=y
+CONFIG_VIDCONSOLE_AS_LCD=y
include/configs/rk3399_common.h +4 -1
index 4ba81ac..6183f4e 100644
@@ -69,7 +69,10 @@
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	ENV_MEM_LAYOUT_SETTINGS \
 	"partitions=" PARTS_DEFAULT \
-	BOOTENV
+	BOOTENV \
+	"stdin=serial,cros-ec-keyb\0" \
+	"stdout=serial,vidconsole\0" \
+	"stderr=serial,vidconsole\0"
 
 #endif
 
Signature · 1 line
1.9.1
#14 lore raw

PATCH 6/7 Enable print log file to lcd

Quoted 9 lines · On 1 April 2017 at 08:42, <[email protected]> wrote:

From: "eric.gao" <[email protected]>

---

 configs/evb-rk3399_defconfig    | 1 +
 include/configs/rk3399_common.h | 5 ++++-
 2 files changed, 5 insertions(+), 1 deletion(-)

configs/evb-rk3399_defconfig CONFIG_DM_VIDEO=y · line 71

Quoted 9 lines
configs/evb-rk3399_defconfig +1 -0
index b9cb0e8..89b2e17 100644
@@ -68,3 +68,4 @@ CONFIG_DM_VIDEO=y
 CONFIG_DISPLAY=y
 CONFIG_VIDEO_ROCKCHIP=y
 CONFIG_DISPLAY_MIPI=y
+CONFIG_VIDCONSOLE_AS_LCD=y

But do you need this option?

Quoted 20 lines
include/configs/rk3399_common.h +4 -2
index 4ba81ac..6183f4e 100644
@@ -69,7 +69,10 @@
 #define CONFIG_EXTRA_ENV_SETTINGS \
        ENV_MEM_LAYOUT_SETTINGS \
        "partitions=" PARTS_DEFAULT \
-       BOOTENV
+       BOOTENV \
+       "stdin=serial,cros-ec-keyb\0" \
+       "stdout=serial,vidconsole\0" \
+       "stderr=serial,vidconsole\0"
 
 #endif
 
--

1.9.1

author
#15 lore raw

PATCH 6/7 Enable print log file to lcd

Dear Glass,

Thank you, I will drop this patch and move it to README file.

Quoted 46 lines · Simon Glass
Quoted 9 lines · On 1 April 2017 at 08:42, <[email protected]> wrote:

From: "eric.gao" <[email protected]>

---

  configs/evb-rk3399_defconfig    | 1 +
  include/configs/rk3399_common.h | 5 ++++-
  2 files changed, 5 insertions(+), 1 deletion(-)

configs/evb-rk3399_defconfig CONFIG_DM_VIDEO=y · line 71

Quoted 9 lines
configs/evb-rk3399_defconfig +1 -0
index b9cb0e8..89b2e17 100644
@@ -68,3 +68,4 @@ CONFIG_DM_VIDEO=y
  CONFIG_DISPLAY=y
  CONFIG_VIDEO_ROCKCHIP=y
  CONFIG_DISPLAY_MIPI=y
+CONFIG_VIDCONSOLE_AS_LCD=y

But do you need this option?

Quoted 20 lines
include/configs/rk3399_common.h +4 -2
index 4ba81ac..6183f4e 100644
@@ -69,7 +69,10 @@
  #define CONFIG_EXTRA_ENV_SETTINGS \
         ENV_MEM_LAYOUT_SETTINGS \
         "partitions=" PARTS_DEFAULT \
-       BOOTENV
+       BOOTENV \
+       "stdin=serial,cros-ec-keyb\0" \
+       "stdout=serial,vidconsole\0" \
+       "stderr=serial,vidconsole\0"
 
  #endif
 
--

1.9.1

#16 lore raw

PATCH 7/7 crash when scroll screen

In reply to eric.gao at rock-chips.com

From: "eric.gao" <[email protected]>

After enable log printing to lcd,when the screen start scroll,the system crash.And the log is shown as bellow.

"Synchronous Abort" handler, esr 0x96000045
"Synchronous Abort" handler, esr 0x96000045

Checking the source code, we found that the variate "pixels" get a wrong value.

int pixels = VIDEO_FONT_HEIGHT * vid_priv->line_length;

"pixels" here means the value of pixels for a character,rather than the byte for a character. so the variate "pixels" is 4 times bigger than it's exact value. which will cause the memory overflow when the cpu run the following code.

for (i = 0; i < pixels; i++)

    *dst++ = clr; <<----

---

 drivers/video/console_normal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/video/console_normal.c +1 -1
index 89a55dd..b627d48 100644
@@ -18,7 +18,7 @@ static int console_normal_set_row(struct udevice *dev, uint row, int clr)
 {
 	struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
 	void *line;
-	int pixels = VIDEO_FONT_HEIGHT * vid_priv->line_length;
+	int pixels = VIDEO_FONT_HEIGHT * vid_priv->xsize;
 	int i;
 
 	line = vid_priv->fb + row * VIDEO_FONT_HEIGHT * vid_priv->line_length;
Signature · 1 line
1.9.1
#17 lore raw

PATCH 7/7 crash when scroll screen

Hi Eric,

Quoted 18 lines · On 1 April 2017 at 08:42, <[email protected]> wrote:

From: "eric.gao" <[email protected]>

After enable log printing to lcd,when the screen start scroll,the system crash.And the log is shown as bellow.

"Synchronous Abort" handler, esr 0x96000045
"Synchronous Abort" handler, esr 0x96000045

Checking the source code, we found that the variate "pixels" get a wrong value.

int pixels = VIDEO_FONT_HEIGHT * vid_priv->line_length;

"pixels" here means the value of pixels for a character,rather than the byte for a character. so the variate "pixels" is 4 times bigger than it's exact value. which will cause the memory overflow when the cpu run the following code.

Quoted 8 lines

for (i = 0; i < pixels; i++)

    *dst++ = clr; <<----

---

 drivers/video/console_normal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Can you compare with this patch?

I did not apply it as it was part of a larger series, sorry.

Regards,
Simon

#18 lore raw

cover Enable MIPI dsi display for rk3399

In reply to eric.gao at rock-chips.com

Hi Eric,

1. Please use full name in you signature;

2. add commit message for all your commits;

3. add 'rockchip' and module name for all your patches.

4. 'From: ' in not need for patch from yourself.

Thanks,
- Kever

Quoted 46 lines · eric.gao at rock-chips.com

From: "eric.gao" <[email protected]>

This serial patchs enable mipi dsi display for rk3399,and let the
system log print to lcd. The function of each patch is decribe in the following.Thank you.
Patch 1: Fix system halt when we enable bucks of PMIC rk808. Patch 2: Enable i2c for rk3399.
Patch 3: Enable PMIC rk808 for display system using. Patch 4: Enable rkclk init,prepare aclk dclk for vop. Patch 5: Add mipi display,panel driver and so on.
Patch 6: Enable print log to lcd.
Patch 7: Fix crash when scrolling screen.

eric.gao (7):
system halt when we enable bucks of PMIC rk808 Enable i2c for rk3399
Enable RK808 for rk3399 evb
Enable rkclk init function
Add mipi display support for rk3399 && rk3288 Enable print log file to lcd
crash when scroll screen

  arch/arm/dts/rk3399-evb.dts                      | 141 +++++++++
  arch/arm/dts/rk3399.dtsi                         |  88 ++++++
  arch/arm/include/asm/arch-rockchip/cru_rk3399.h  |   2 +-
  arch/arm/include/asm/arch-rockchip/mipi_rk3399.h | 203 +++++++++++++
  arch/arm/include/asm/arch-rockchip/vop_rk3288.h  |   1 +
  arch/arm/mach-rockchip/rk3399/syscon_rk3399.c    |   1 +
  configs/evb-rk3399_defconfig                     |  11 +
  drivers/clk/rockchip/clk_rk3399.c                |   4 +
  drivers/i2c/rk_i2c.c                             |   1 +
  drivers/video/Kconfig                            |   2 +
  drivers/video/console_normal.c                   |   2 +-
  drivers/video/rockchip/Kconfig                   |  44 +++
  drivers/video/rockchip/Makefile                  |   7 +-
  drivers/video/rockchip/panel.c                   |  81 +++++
  drivers/video/rockchip/rk_mipi.c                 | 371 +++++++++++++++++++++++
  drivers/video/rockchip/rk_vop.c                  |  12 +-
  include/configs/rk3399_common.h                  |   5 +-
  17 files changed, 969 insertions(+), 7 deletions(-)

create mode 100644 arch/arm/include/asm/arch-rockchip/mipi_rk3399.h create mode 100644 drivers/video/rockchip/Kconfig
create mode 100644 drivers/video/rockchip/panel.c
create mode 100644 drivers/video/rockchip/rk_mipi.c