Merge tag 'u-boot-stm32-20200528' of https://gitlab.denx.de/u-boot/custodians/u-boot-stm
authorTom Rini <trini@konsulko.com>
Mon, 1 Jun 2020 15:42:22 +0000 (11:42 -0400)
committerTom Rini <trini@konsulko.com>
Mon, 1 Jun 2020 15:42:22 +0000 (11:42 -0400)
- stm32mp15: fix DT on DHCOR SOM and avenger96 board
- stm32mp15: re-enable KS8851 on DHCOM

77 files changed:
arch/arm/dts/Makefile
arch/arm/dts/meson-gxl-s805x-libretech-ac-u-boot.dtsi
arch/arm/dts/meson-gxl-s905d-libretech-pc-u-boot.dtsi
arch/arm/dts/meson-gxl-s905x-khadas-vim-u-boot.dtsi
arch/arm/dts/meson-gxm-khadas-vim2-u-boot.dtsi
arch/arm/dts/meson-gxm-s912-libretech-pc-u-boot.dtsi
arch/arm/dts/meson-khadas-vim3-u-boot.dtsi
arch/arm/dts/rk3399-evb-u-boot.dtsi
arch/arm/dts/rk3399-ficus-u-boot.dtsi
arch/arm/dts/rk3399-nanopi4-u-boot.dtsi
arch/arm/dts/rk3399-pinebook-pro-u-boot.dtsi [new file with mode: 0644]
arch/arm/dts/rk3399-pinebook-pro.dts [new file with mode: 0644]
arch/arm/dts/rk3399-rock960-u-boot.dtsi
arch/arm/mach-rockchip/rk3399/Kconfig
arch/arm/mach-rockchip/rk3399/rk3399.c
arch/arm/mach-rockchip/rk3399/syscon_rk3399.c
arch/arm/mach-rockchip/spl.c
board/pine64/pinebook-pro-rk3399/Kconfig [new file with mode: 0644]
board/pine64/pinebook-pro-rk3399/MAINTAINERS [new file with mode: 0644]
board/pine64/pinebook-pro-rk3399/Makefile [new file with mode: 0644]
board/pine64/pinebook-pro-rk3399/pinebook-pro-rk3399.c [new file with mode: 0644]
board/renesas/r2dplus/r2dplus.c
board/theobroma-systems/puma_rk3399/puma-rk3399.c
common/spl/spl.c
configs/evb-rk3399_defconfig
configs/khadas-vim3_defconfig
configs/khadas-vim3l_defconfig
configs/nanopc-t4-rk3399_defconfig
configs/pinebook-pro-rk3399_defconfig [new file with mode: 0644]
configs/r2dplus_defconfig
configs/roc-pc-mezzanine-rk3399_defconfig
configs/roc-pc-rk3399_defconfig
configs/rockpro64-rk3399_defconfig
configs/sandbox64_defconfig
configs/sandbox_defconfig
configs/sandbox_flattree_defconfig
configs/sandbox_spl_defconfig
doc/README.rockchip
doc/SPI/README.sandbox-spi
doc/arch/sandbox.rst
doc/board/rockchip/rockchip.rst
drivers/Makefile
drivers/clk/rockchip/clk_rk3399.c
drivers/core/read.c
drivers/i2c/designware_i2c.c
drivers/i2c/i2c-uclass.c
drivers/misc/i2c_eeprom.c
drivers/pci/pcie_rockchip.c
drivers/phy/Kconfig
drivers/phy/rockchip/Kconfig [new file with mode: 0644]
drivers/phy/rockchip/Makefile [new file with mode: 0644]
drivers/phy/rockchip/phy-rockchip-inno-usb2.c [new file with mode: 0644]
drivers/phy/rockchip/phy-rockchip-typec.c [new file with mode: 0644]
drivers/usb/common/common.c
drivers/usb/dwc3/core.c
drivers/usb/dwc3/core.h
drivers/usb/dwc3/dwc3-generic.c
drivers/usb/eth/r8152.c
drivers/usb/host/Kconfig
drivers/usb/host/Makefile
drivers/usb/host/ehci-mx6.c
drivers/usb/host/xhci-rockchip.c [deleted file]
include/configs/pinebook-pro-rk3399.h [new file with mode: 0644]
include/configs/rockchip-common.h
include/configs/rockpro64_rk3399.h
include/dt-bindings/input/gpio-keys.h [new file with mode: 0644]
include/dwc3-uboot.h
include/linux/usb/phy.h
tools/patman/README
tools/patman/func_test.py
tools/patman/gitutil.py
tools/patman/main.py
tools/patman/patchstream.py
tools/patman/series.py
tools/patman/test/0001-pci-Correct-cast-for-sandbox.patch
tools/patman/test/0002-fdt-Correct-cast-for-sandbox-in-fdtdec_setup_mem_siz.patch
tools/patman/test/test01.txt

index 12ec6c71dc5eb598e67c63bd7b0583bcd04a0a53..c6af87cf5e89221ec853fd69644e04b6e4877d46 100644 (file)
@@ -129,6 +129,7 @@ dtb-$(CONFIG_ROCKCHIP_RK3399) += \
        rk3399-nanopi-m4-2gb.dtb \
        rk3399-nanopi-neo4.dtb \
        rk3399-orangepi.dtb \
+       rk3399-pinebook-pro.dtb \
        rk3399-puma-ddr1333.dtb \
        rk3399-puma-ddr1600.dtb \
        rk3399-puma-ddr1866.dtb \
index c35158d7e9ee15be16cda93572e296e4e0e46eac..474a3e160447a7daa8e61246ff1e74c3c87b6fee 100644 (file)
@@ -4,4 +4,8 @@
  * Author: Neil Armstrong <narmstrong@baylibre.com>
  */
 
-#include "meson-gx-u-boot.dtsi"
+#include "meson-gxl-u-boot.dtsi"
+
+&dwc2 {
+       status = "okay";
+};
index c35158d7e9ee15be16cda93572e296e4e0e46eac..474a3e160447a7daa8e61246ff1e74c3c87b6fee 100644 (file)
@@ -4,4 +4,8 @@
  * Author: Neil Armstrong <narmstrong@baylibre.com>
  */
 
-#include "meson-gx-u-boot.dtsi"
+#include "meson-gxl-u-boot.dtsi"
+
+&dwc2 {
+       status = "okay";
+};
index 39270ea71c8b1b8b293090a525a6c07b07461e8a..474a3e160447a7daa8e61246ff1e74c3c87b6fee 100644 (file)
@@ -5,3 +5,7 @@
  */
 
 #include "meson-gxl-u-boot.dtsi"
+
+&dwc2 {
+       status = "okay";
+};
index bec9e05b0966207e7ba5c1d606d25e426719df72..7aecf2696bd4cd2fc07da98553c371f9c3cc15a3 100644 (file)
@@ -4,7 +4,7 @@
  * Author: Neil Armstrong <narmstrong@baylibre.com>
  */
 
-#include "meson-gx-u-boot.dtsi"
+#include "meson-gxl-u-boot.dtsi"
 
 / {
        aliases {
        };
 };
 
+&dwc2 {
+       status = "okay";
+};
+
 &sd_emmc_c {
        status = "okay";
        pinctrl-0 = <&emmc_pins>;
index c35158d7e9ee15be16cda93572e296e4e0e46eac..474a3e160447a7daa8e61246ff1e74c3c87b6fee 100644 (file)
@@ -4,4 +4,8 @@
  * Author: Neil Armstrong <narmstrong@baylibre.com>
  */
 
-#include "meson-gx-u-boot.dtsi"
+#include "meson-gxl-u-boot.dtsi"
+
+&dwc2 {
+       status = "okay";
+};
index 81fd5be3783bb6f02ab5f62d1ef658bfcc76c5b3..b5da4fdfc3eeba7310034b1be7f103d45240779f 100644 (file)
@@ -4,6 +4,8 @@
  * Author: Neil Armstrong <narmstrong@baylibre.com>
  */
 
+#include "meson-g12-common-u-boot.dtsi"
+
 / {
        aliases {
                spi0 = &spifc;
index e5659d79995d13c06b89e743b54459803bc4b0fb..c42bd2856f6b6f4378784e9c3b2a1f496b640bd4 100644 (file)
@@ -8,7 +8,7 @@
 
 / {
        chosen {
-               u-boot,spl-boot-order = &sdhci, &sdmmc;
+               u-boot,spl-boot-order = "same-as-spl", &sdhci, &sdmmc;
        };
 };
 
 &rk808 {
        u-boot,dm-pre-reloc;
 };
+
+&tcphy1 {
+       status = "okay";
+};
+
+&usbdrd3_1 {
+       status = "okay";
+};
+
+&usbdrd_dwc3_1 {
+       dr_mode = "host";
+       status = "okay";
+};
index f3f7aa7c459e613d1203da82c1c70dec9e758081..38e0897db91dd3d1306c3ce0c30b40939ab6e220 100644 (file)
@@ -8,6 +8,6 @@
 
 / {
        chosen {
-               u-boot,spl-boot-order = &sdhci, &sdmmc;
+               u-boot,spl-boot-order = "same-as-spl", &sdhci, &sdmmc;
        };
 };
index a126bbaf086f5bbf6eabe30de979ba057d003569..a9d10592d573fba875f99f878b28a90e8123364d 100644 (file)
@@ -5,6 +5,12 @@
 
 #include "rk3399-u-boot.dtsi"
 
+/{
+       chosen {
+               u-boot,spl-boot-order = "same-as-spl", &sdhci, &sdmmc;
+       };
+};
+
 &sdmmc {
        pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc_cd>;
 };
diff --git a/arch/arm/dts/rk3399-pinebook-pro-u-boot.dtsi b/arch/arm/dts/rk3399-pinebook-pro-u-boot.dtsi
new file mode 100644 (file)
index 0000000..1a2e24d
--- /dev/null
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Peter Robinson <pbrobinson at gmail.com>
+ */
+
+#include "rk3399-u-boot.dtsi"
+#include "rk3399-sdram-lpddr4-100.dtsi"
+
+/ {
+       aliases {
+               spi0 = &spi1;
+       };
+
+       chosen {
+               u-boot,spl-boot-order = "same-as-spl", &sdhci, &sdmmc;
+       };
+};
+
+&i2c0 {
+       u-boot,dm-pre-reloc;
+};
+
+&rk808 {
+       u-boot,dm-pre-reloc;
+};
+
+&sdhci {
+       max-frequency = <25000000>;
+       u-boot,dm-pre-reloc;
+};
+
+&sdmmc {
+       max-frequency = <20000000>;
+       u-boot,dm-pre-reloc;
+};
+
+&spiflash {
+       u-boot,dm-pre-reloc;
+};
+
+&vdd_log {
+       regulator-init-microvolt = <950000>;
+};
diff --git a/arch/arm/dts/rk3399-pinebook-pro.dts b/arch/arm/dts/rk3399-pinebook-pro.dts
new file mode 100644 (file)
index 0000000..294d21b
--- /dev/null
@@ -0,0 +1,1096 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd.
+ * Copyright (c) 2018 Akash Gajjar <Akash_Gajjar@mentor.com>
+ * Copyright (c) 2020 Tobias Schramm <t.schramm@manjaro.org>
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/gpio-keys.h>
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/pwm/pwm.h>
+#include <dt-bindings/usb/pd.h>
+#include <dt-bindings/leds/common.h>
+#include "rk3399.dtsi"
+#include "rk3399-opp.dtsi"
+
+/ {
+       model = "Pine64 Pinebook Pro";
+       compatible = "pine64,pinebook-pro", "rockchip,rk3399";
+
+       chosen {
+               stdout-path = "serial2:1500000n8";
+       };
+
+       backlight: edp-backlight {
+               compatible = "pwm-backlight";
+               power-supply = <&vcc_12v>;
+               pwms = <&pwm0 0 740740 0>;
+       };
+
+       edp_panel: edp-panel {
+               compatible = "boe,nv140fhmn49";
+               backlight = <&backlight>;
+               enable-gpios = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&panel_en_gpio>;
+               power-supply = <&vcc3v3_panel>;
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               panel_in_edp: endpoint@0 {
+                                       reg = <0>;
+                                       remote-endpoint = <&edp_out_panel>;
+                               };
+                       };
+               };
+       };
+
+       /*
+        * Use separate nodes for gpio-keys to allow for selective deactivation
+        * of wakeup sources via sysfs without disabling the whole key
+        */
+       gpio-key-lid {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&lidbtn_gpio>;
+
+               lid {
+                       debounce-interval = <20>;
+                       gpios = <&gpio1 RK_PA1 GPIO_ACTIVE_LOW>;
+                       label = "Lid";
+                       linux,code = <SW_LID>;
+                       linux,input-type = <EV_SW>;
+                       wakeup-event-action = <EV_ACT_DEASSERTED>;
+                       wakeup-source;
+               };
+       };
+
+       gpio-key-power {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwrbtn_gpio>;
+
+               power {
+                       debounce-interval = <20>;
+                       gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>;
+                       label = "Power";
+                       linux,code = <KEY_POWER>;
+                       wakeup-source;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwrled_gpio &slpled_gpio>;
+
+               green-led {
+                       color = <LED_COLOR_ID_GREEN>;
+                       default-state = "on";
+                       function = LED_FUNCTION_POWER;
+                       gpios = <&gpio0 RK_PB3 GPIO_ACTIVE_HIGH>;
+                       label = "green:power";
+               };
+
+               red-led {
+                       color = <LED_COLOR_ID_RED>;
+                       default-state = "off";
+                       function = LED_FUNCTION_STANDBY;
+                       gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>;
+                       label = "red:standby";
+                       panic-indicator;
+                       retain-state-suspended;
+               };
+       };
+
+       /* Power sequence for SDIO WiFi module */
+       sdio_pwrseq: sdio-pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               clocks = <&rk808 1>;
+               clock-names = "ext_clock";
+               pinctrl-names = "default";
+               pinctrl-0 = <&wifi_enable_h_gpio>;
+               post-power-on-delay-ms = <100>;
+               power-off-delay-us = <500000>;
+
+               /* WL_REG_ON on module */
+               reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>;
+       };
+
+       /* Audio components */
+       es8316-sound {
+               compatible = "simple-audio-card";
+               pinctrl-names = "default";
+               pinctrl-0 = <&hp_det_gpio>;
+               simple-audio-card,name = "rockchip,es8316-codec";
+               simple-audio-card,format = "i2s";
+               simple-audio-card,mclk-fs = <256>;
+
+               simple-audio-card,widgets =
+                       "Microphone", "Mic Jack",
+                       "Headphone", "Headphones",
+                       "Speaker", "Speaker";
+               simple-audio-card,routing =
+                       "MIC1", "Mic Jack",
+                       "Headphones", "HPOL",
+                       "Headphones", "HPOR",
+                       "Speaker Amplifier INL", "HPOL",
+                       "Speaker Amplifier INR", "HPOR",
+                       "Speaker", "Speaker Amplifier OUTL",
+                       "Speaker", "Speaker Amplifier OUTR";
+
+               simple-audio-card,hp-det-gpio = <&gpio0 RK_PB0 GPIO_ACTIVE_HIGH>;
+               simple-audio-card,aux-devs = <&speaker_amp>;
+               simple-audio-card,pin-switches = "Speaker";
+
+               simple-audio-card,cpu {
+                       sound-dai = <&i2s1>;
+               };
+
+               simple-audio-card,codec {
+                       sound-dai = <&es8316>;
+               };
+       };
+
+       speaker_amp: speaker-amplifier {
+               compatible = "simple-audio-amplifier";
+               enable-gpios = <&gpio4 RK_PD3 GPIO_ACTIVE_HIGH>;
+               sound-name-prefix = "Speaker Amplifier";
+               VCC-supply = <&pa_5v>;
+       };
+
+       /* Power tree */
+       /* Root power source */
+       vcc_sysin: vcc-sysin {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_sysin";
+               regulator-always-on;
+               regulator-boot-on;
+       };
+
+       /* Regulators supplied by vcc_sysin */
+       /* LCD backlight supply */
+       vcc_12v: vcc-12v {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_12v";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <12000000>;
+               regulator-max-microvolt = <12000000>;
+               vin-supply = <&vcc_sysin>;
+
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+
+       /* Main 3.3 V supply */
+       vcc3v3_sys: wifi_bat: vcc3v3-sys {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc3v3_sys";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&vcc_sysin>;
+
+               regulator-state-mem {
+                       regulator-on-in-suspend;
+               };
+       };
+
+       /* 5 V USB power supply */
+       vcc5v0_usb: pa_5v: vcc5v0-usb-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio1 RK_PB5 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwr_5v_gpio>;
+               regulator-name = "vcc5v0_usb";
+               regulator-always-on;
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&vcc_sysin>;
+
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+
+       /* RK3399 logic supply */
+       vdd_log: vdd-log {
+               compatible = "pwm-regulator";
+               pwms = <&pwm2 0 25000 1>;
+               regulator-name = "vdd_log";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <800000>;
+               regulator-max-microvolt = <1400000>;
+               vin-supply = <&vcc_sysin>;
+
+               regulator-state-mem {
+                       regulator-on-in-suspend;
+               };
+       };
+
+       /* Regulators supplied by vcc3v3_sys */
+       /* 0.9 V supply, always on */
+       vcc_0v9: vcc-0v9 {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_0v9";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <900000>;
+               regulator-max-microvolt = <900000>;
+               vin-supply = <&vcc3v3_sys>;
+       };
+
+       /* S3 1.8 V supply, switched by vcc1v8_s3 */
+       vcca1v8_s3: vcc1v8-s3 {
+               compatible = "regulator-fixed";
+               regulator-name = "vcca1v8_s3";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               vin-supply = <&vcc3v3_sys>;
+       };
+
+       /* micro SD card power */
+       vcc3v0_sd: vcc3v0-sd {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&sdmmc0_pwr_h_gpio>;
+               regulator-name = "vcc3v0_sd";
+               regulator-always-on;
+               regulator-min-microvolt = <3000000>;
+               regulator-max-microvolt = <3000000>;
+               vin-supply = <&vcc3v3_sys>;
+
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+
+       /* LCD panel power, called VCC3V3_S0 in schematic */
+       vcc3v3_panel: vcc3v3-panel {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio1 RK_PC6 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&lcdvcc_en_gpio>;
+               regulator-name = "vcc3v3_panel";
+               regulator-always-on;
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-enable-ramp-delay = <100000>;
+               vin-supply = <&vcc3v3_sys>;
+
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+
+       /* M.2 adapter power, switched by vcc1v8_s3 */
+       vcc3v3_ssd: vcc3v3-ssd {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc3v3_ssd";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&vcc3v3_sys>;
+       };
+
+       /* Regulators supplied by vcc5v0_usb */
+       /* USB 3 port power supply regulator  */
+       vcc5v0_otg: vcc5v0-otg {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio4 RK_PD2 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vcc5v0_host_en_gpio>;
+               regulator-name = "vcc5v0_otg";
+               regulator-always-on;
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&vcc5v0_usb>;
+
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+
+       /* Regulators supplied by vcc5v0_usb */
+       /* Type C port power supply regulator */
+       vbus_5vout: vbus_typec: vbus-5vout {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio1 RK_PA3 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vcc5v0_typec0_en_gpio>;
+               regulator-name = "vbus_5vout";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&vcc5v0_usb>;
+
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+
+       /* Regulators supplied by vcc_1v8 */
+       /* Primary 0.9 V LDO */
+       vcca0v9_s3: vcca0v9-s3 {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc0v9_s3";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&vcc_1v8>;
+
+               regulator-state-mem {
+                       regulator-on-in-suspend;
+               };
+       };
+
+       mains_charger: dc-charger {
+               compatible = "gpio-charger";
+               charger-type = "mains";
+               gpios = <&gpio4 RK_PD0 GPIO_ACTIVE_LOW>;
+
+               /* Also triggered by USB charger */
+               pinctrl-names = "default";
+               pinctrl-0 = <&dc_det_gpio>;
+       };
+};
+
+&cdn_dp {
+       status = "okay";
+};
+
+&cpu_b0 {
+       cpu-supply = <&vdd_cpu_b>;
+};
+
+&cpu_b1 {
+       cpu-supply = <&vdd_cpu_b>;
+};
+
+&cpu_l0 {
+       cpu-supply = <&vdd_cpu_l>;
+};
+
+&cpu_l1 {
+       cpu-supply = <&vdd_cpu_l>;
+};
+
+&cpu_l2 {
+       cpu-supply = <&vdd_cpu_l>;
+};
+
+&cpu_l3 {
+       cpu-supply = <&vdd_cpu_l>;
+};
+
+&edp {
+       force-hpd;
+       pinctrl-names = "default";
+       pinctrl-0 = <&edp_hpd>;
+       status = "okay";
+
+       ports {
+               edp_out: port@1 {
+                       reg = <1>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       edp_out_panel: endpoint@0 {
+                               reg = <0>;
+                               remote-endpoint = <&panel_in_edp>;
+                       };
+               };
+       };
+};
+
+&emmc_phy {
+       status = "okay";
+};
+
+&gpu {
+       mali-supply = <&vdd_gpu>;
+       status = "okay";
+};
+
+&hdmi_sound {
+       status = "okay";
+};
+
+&i2c0 {
+       clock-frequency = <400000>;
+       i2c-scl-falling-time-ns = <4>;
+       i2c-scl-rising-time-ns = <168>;
+       status = "okay";
+
+       rk808: pmic@1b {
+               compatible = "rockchip,rk808";
+               reg = <0x1b>;
+               #clock-cells = <1>;
+               clock-output-names = "xin32k", "rk808-clkout2";
+               interrupt-parent = <&gpio3>;
+               interrupts = <10 IRQ_TYPE_LEVEL_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pmic_int_l_gpio>;
+               rockchip,system-power-controller;
+               wakeup-source;
+
+               vcc1-supply = <&vcc_sysin>;
+               vcc2-supply = <&vcc_sysin>;
+               vcc3-supply = <&vcc_sysin>;
+               vcc4-supply = <&vcc_sysin>;
+               vcc6-supply = <&vcc_sysin>;
+               vcc7-supply = <&vcc_sysin>;
+               vcc8-supply = <&vcc3v3_sys>;
+               vcc9-supply = <&vcc_sysin>;
+               vcc10-supply = <&vcc_sysin>;
+               vcc11-supply = <&vcc_sysin>;
+               vcc12-supply = <&vcc3v3_sys>;
+               vcc13-supply = <&vcc_sysin>;
+               vcc14-supply = <&vcc_sysin>;
+
+               regulators {
+                       /* rk3399 center logic supply */
+                       vdd_center: DCDC_REG1 {
+                               regulator-name = "vdd_center";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <750000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-ramp-delay = <6001>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_cpu_l: DCDC_REG2 {
+                               regulator-name = "vdd_cpu_l";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <750000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-ramp-delay = <6001>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc_ddr: DCDC_REG3 {
+                               regulator-name = "vcc_ddr";
+                               regulator-always-on;
+                               regulator-boot-on;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                               };
+                       };
+
+                       vcc_1v8: vcc_wl: DCDC_REG4 {
+                               regulator-name = "vcc_1v8";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       /* not used */
+                       LDO_REG1 {
+                       };
+
+                       /* not used */
+                       LDO_REG2 {
+                       };
+
+                       vcc1v8_pmupll: LDO_REG3 {
+                               regulator-name = "vcc1v8_pmupll";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vcc_sdio: LDO_REG4 {
+                               regulator-name = "vcc_sdio";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3000000>;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3000000>;
+                               };
+                       };
+
+                       vcca3v0_codec: LDO_REG5 {
+                               regulator-name = "vcca3v0_codec";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3000000>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc_1v5: LDO_REG6 {
+                               regulator-name = "vcc_1v5";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1500000>;
+                               regulator-max-microvolt = <1500000>;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1500000>;
+                               };
+                       };
+
+                       vcca1v8_codec: LDO_REG7 {
+                               regulator-name = "vcca1v8_codec";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc_3v0: LDO_REG8 {
+                               regulator-name = "vcc_3v0";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3000000>;
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3000000>;
+                               };
+                       };
+
+                       vcc3v3_s3: SWITCH_REG1 {
+                               regulator-name = "vcc3v3_s3";
+                               regulator-always-on;
+                               regulator-boot-on;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc3v3_s0: SWITCH_REG2 {
+                               regulator-name = "vcc3v3_s0";
+                               regulator-always-on;
+                               regulator-boot-on;
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+               };
+       };
+
+       vdd_cpu_b: regulator@40 {
+               compatible = "silergy,syr827";
+               reg = <0x40>;
+               fcs,suspend-voltage-selector = <1>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vsel1_gpio>;
+               regulator-name = "vdd_cpu_b";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <712500>;
+               regulator-max-microvolt = <1500000>;
+               regulator-ramp-delay = <1000>;
+               vin-supply = <&vcc_1v8>;
+
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+
+       vdd_gpu: regulator@41 {
+               compatible = "silergy,syr828";
+               reg = <0x41>;
+               fcs,suspend-voltage-selector = <1>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vsel2_gpio>;
+               regulator-name = "vdd_gpu";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <712500>;
+               regulator-max-microvolt = <1500000>;
+               regulator-ramp-delay = <1000>;
+               vin-supply = <&vcc_1v8>;
+
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+};
+
+&i2c1 {
+       clock-frequency = <100000>;
+       i2c-scl-falling-time-ns = <4>;
+       i2c-scl-rising-time-ns = <168>;
+       status = "okay";
+
+       es8316: es8316@11 {
+               compatible = "everest,es8316";
+               reg = <0x11>;
+               clocks = <&cru SCLK_I2S_8CH_OUT>;
+               clock-names = "mclk";
+               #sound-dai-cells = <0>;
+       };
+};
+
+&i2c3 {
+       i2c-scl-falling-time-ns = <15>;
+       i2c-scl-rising-time-ns = <450>;
+       status = "okay";
+};
+
+&i2c4 {
+       i2c-scl-falling-time-ns = <20>;
+       i2c-scl-rising-time-ns = <600>;
+       status = "okay";
+
+       fusb0: fusb30x@22 {
+               compatible = "fcs,fusb302";
+               reg = <0x22>;
+               fcs,int_n = <&gpio1 RK_PA2 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&fusb0_int_gpio>;
+               vbus-supply = <&vbus_typec>;
+
+               connector {
+                       compatible = "usb-c-connector";
+                       data-role = "host";
+                       label = "USB-C";
+                       op-sink-microwatt = <1000000>;
+                       power-role = "dual";
+                       sink-pdos =
+                               <PDO_FIXED(5000, 2500, PDO_FIXED_USB_COMM)>;
+                       source-pdos =
+                               <PDO_FIXED(5000, 1400, PDO_FIXED_USB_COMM)>;
+                       try-power-role = "sink";
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+
+                                       usbc_hs: endpoint {
+                                               remote-endpoint =
+                                                       <&u2phy0_typec_hs>;
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+
+                                       usbc_ss: endpoint {
+                                               remote-endpoint =
+                                                       <&tcphy0_typec_ss>;
+                                       };
+                               };
+
+                               port@2 {
+                                       reg = <2>;
+
+                                       usbc_dp: endpoint {
+                                               remote-endpoint =
+                                                       <&tcphy0_typec_dp>;
+                                       };
+                               };
+                       };
+               };
+       };
+};
+
+&i2s1 {
+       #sound-dai-cells = <0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2s_8ch_mclk_gpio>, <&i2s1_2ch_bus>;
+       rockchip,capture-channels = <8>;
+       rockchip,playback-channels = <8>;
+       status = "okay";
+};
+
+&io_domains {
+       audio-supply = <&vcc_3v0>;
+       gpio1830-supply = <&vcc_3v0>;
+       sdmmc-supply = <&vcc_sdio>;
+       status = "okay";
+};
+
+&pcie_phy {
+       status = "okay";
+};
+
+&pcie0 {
+       bus-scan-delay-ms = <1000>;
+       ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>;
+       max-link-speed = <2>;
+       num-lanes = <4>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pcie_clkreqn_cpm>;
+       vpcie0v9-supply = <&vcca0v9_s3>;
+       vpcie1v8-supply = <&vcca1v8_s3>;
+       vpcie3v3-supply = <&vcc3v3_ssd>;
+       status = "okay";
+};
+
+&pinctrl {
+       buttons {
+               pwrbtn_gpio: pwrbtn-gpio {
+                       rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+
+               lidbtn_gpio: lidbtn-gpio {
+                       rockchip,pins = <1 RK_PA1 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       dc-charger {
+               dc_det_gpio: dc-det-gpio {
+                       rockchip,pins = <4 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       es8316 {
+               hp_det_gpio: hp-det-gpio {
+                       rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       fusb302x {
+               fusb0_int_gpio: fusb0-int-gpio {
+                       rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       i2s1 {
+               i2s_8ch_mclk_gpio: i2s-8ch-mclk-gpio {
+                       rockchip,pins = <4 RK_PA0 1 &pcfg_pull_none>;
+               };
+       };
+
+       lcd-panel {
+               lcdvcc_en_gpio: lcdvcc-en-gpio {
+                       rockchip,pins = <1 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               panel_en_gpio: panel-en-gpio {
+                       rockchip,pins = <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               lcd_panel_reset_gpio: lcd-panel-reset-gpio {
+                       rockchip,pins = <4 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       leds {
+               pwrled_gpio: pwrled_gpio {
+                       rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               slpled_gpio: slpled_gpio {
+                       rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       pmic {
+               pmic_int_l_gpio: pmic-int-l-gpio {
+                       rockchip,pins = <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+
+               vsel1_gpio: vsel1-gpio {
+                       rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>;
+               };
+
+               vsel2_gpio: vsel2-gpio {
+                       rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>;
+               };
+       };
+
+       sdcard {
+               sdmmc0_pwr_h_gpio: sdmmc0-pwr-h-gpio {
+                       rockchip,pins = <0 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+       };
+
+       sdio-pwrseq {
+               wifi_enable_h_gpio: wifi-enable-h-gpio {
+                       rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       usb-typec {
+               vcc5v0_typec0_en_gpio: vcc5v0-typec0-en-gpio {
+                       rockchip,pins = <1 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       usb2 {
+               pwr_5v_gpio: pwr-5v-gpio {
+                       rockchip,pins = <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               vcc5v0_host_en_gpio: vcc5v0-host-en-gpio {
+                       rockchip,pins = <4 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       wireless-bluetooth {
+               bt_wake_gpio: bt-wake-gpio {
+                       rockchip,pins = <2 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               bt_host_wake_gpio: bt-host-wake-gpio {
+                       rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               bt_reset_gpio: bt-reset-gpio {
+                       rockchip,pins = <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+};
+
+&pmu_io_domains {
+       pmu1830-supply = <&vcc_3v0>;
+       status = "okay";
+};
+
+&pwm0 {
+       status = "okay";
+};
+
+&pwm2 {
+       status = "okay";
+};
+
+&saradc {
+       vref-supply = <&vcca1v8_s3>;
+       status = "okay";
+};
+
+&sdmmc {
+       bus-width = <4>;
+       cap-mmc-highspeed;
+       cap-sd-highspeed;
+       cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>;
+       disable-wp;
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_bus4>;
+       sd-uhs-sdr104;
+       vmmc-supply = <&vcc3v0_sd>;
+       vqmmc-supply = <&vcc_sdio>;
+       status = "okay";
+};
+
+&sdio0 {
+       bus-width = <4>;
+       cap-sd-highspeed;
+       cap-sdio-irq;
+       keep-power-in-suspend;
+       mmc-pwrseq = <&sdio_pwrseq>;
+       non-removable;
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>;
+       sd-uhs-sdr104;
+       status = "okay";
+};
+
+&sdhci {
+       bus-width = <8>;
+       mmc-hs200-1_8v;
+       non-removable;
+       status = "okay";
+};
+
+&spi1 {
+       max-freq = <10000000>;
+       status = "okay";
+
+       spiflash: flash@0 {
+               compatible = "jedec,spi-nor";
+               reg = <0>;
+               m25p,fast-read;
+               spi-max-frequency = <10000000>;
+       };
+};
+
+&tcphy0 {
+       status = "okay";
+};
+
+&tcphy0_dp {
+       port {
+               tcphy0_typec_dp: endpoint {
+                       remote-endpoint = <&usbc_dp>;
+               };
+       };
+};
+
+&tcphy0_usb3 {
+       port {
+               tcphy0_typec_ss: endpoint {
+                       remote-endpoint = <&usbc_ss>;
+               };
+       };
+};
+
+&tcphy1 {
+       status = "okay";
+};
+
+&tsadc {
+       /* tshut mode 0:CRU 1:GPIO */
+       rockchip,hw-tshut-mode = <1>;
+       /* tshut polarity 0:LOW 1:HIGH */
+       rockchip,hw-tshut-polarity = <1>;
+       status = "okay";
+};
+
+&u2phy0 {
+       status = "okay";
+
+       u2phy0_otg: otg-port {
+               status = "okay";
+       };
+
+       u2phy0_host: host-port {
+               phy-supply = <&vcc5v0_otg>;
+               status = "okay";
+       };
+
+       port {
+               u2phy0_typec_hs: endpoint {
+                       remote-endpoint = <&usbc_hs>;
+               };
+       };
+};
+
+&u2phy1 {
+       status = "okay";
+
+       u2phy1_otg: otg-port {
+               status = "okay";
+       };
+
+       u2phy1_host: host-port {
+               phy-supply = <&vcc5v0_otg>;
+               status = "okay";
+       };
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+       uart-has-rtscts;
+       status = "okay";
+
+       bluetooth {
+               compatible = "brcm,bcm4345c5";
+               clocks = <&rk808 1>;
+               clock-names = "lpo";
+               device-wakeup-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>;
+               host-wakeup-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>;
+               max-speed = <1500000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&bt_host_wake_gpio &bt_wake_gpio &bt_reset_gpio>;
+               shutdown-gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>;
+               vbat-supply = <&wifi_bat>;
+               vddio-supply = <&vcc_wl>;
+       };
+};
+
+&uart2 {
+       status = "okay";
+};
+
+&usb_host0_ehci {
+       status = "okay";
+};
+
+&usb_host0_ohci {
+       status = "okay";
+};
+
+&usb_host1_ehci {
+       status = "okay";
+};
+
+&usb_host1_ohci {
+       status = "okay";
+};
+
+&usbdrd3_0 {
+       status = "okay";
+};
+
+&usbdrd_dwc3_0 {
+       dr_mode = "host";
+       status = "okay";
+};
+
+&usbdrd3_1 {
+       status = "okay";
+};
+
+&usbdrd_dwc3_1 {
+       dr_mode = "host";
+       status = "okay";
+};
+
+&vopb {
+       status = "okay";
+};
+
+&vopb_mmu {
+       status = "okay";
+};
+
+&vopl {
+       status = "okay";
+};
+
+&vopl_mmu {
+       status = "okay";
+};
index 82f2c311afbec944783030209634d265b4204be9..c190089e26431b6a0535fba927a56f12289973f2 100644 (file)
@@ -8,7 +8,7 @@
 
 / {
        chosen {
-               u-boot,spl-boot-order = &sdhci, &sdmmc;
+               u-boot,spl-boot-order = "same-as-spl", &sdhci, &sdmmc;
        };
 
        vdd_log: vdd-log {
index 927bb62a9fea628658b5a8e7c1c5112f734be467..254b9c5b4d728dd2522b3266fbdaf2076105140e 100644 (file)
@@ -19,6 +19,13 @@ config TARGET_EVB_RK3399
          with full function and physical connectors support like Type-C ports,
          USB.0 host ports, LVDS, JTAG, MAC, SD card, HDMI, USB-to-serial...
 
+config TARGET_PINEBOOK_PRO_RK3399
+       bool "Pinebook Pro"
+       help
+         Pinebook Pro is a laptop based on the Rockchip rk3399 SoC
+         with 4Gb RAM, onboard eMMC, USB-C, a USB3 and USB2 port,
+         1920*1080 screen and all the usual laptop features.
+
 config TARGET_PUMA_RK3399
        bool "Theobroma Systems RK3399-Q7 (Puma)"
        help
@@ -144,6 +151,7 @@ endif # BOOTCOUNT_LIMIT
 
 source "board/firefly/roc-pc-rk3399/Kconfig"
 source "board/google/gru/Kconfig"
+source "board/pine64/pinebook-pro-rk3399/Kconfig"
 source "board/pine64/rockpro64_rk3399/Kconfig"
 source "board/rockchip/evb_rk3399/Kconfig"
 source "board/theobroma-systems/puma_rk3399/Kconfig"
index 09b0d6ebe81a1eae99f360632a00daf5777d1701..4fda93b15271e501c14d77afbf817ff0a8b2727d 100644 (file)
@@ -28,7 +28,7 @@ DECLARE_GLOBAL_DATA_PTR;
 const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = {
        [BROM_BOOTSOURCE_EMMC] = "/sdhci@fe330000",
        [BROM_BOOTSOURCE_SPINOR] = "/spi@ff1d0000",
-       [BROM_BOOTSOURCE_SD] = "/dwmmc@fe320000",
+       [BROM_BOOTSOURCE_SD] = "/mmc@fe320000",
 };
 
 static struct mm_region rk3399_mem_map[] = {
@@ -176,7 +176,7 @@ const char *spl_decode_boot_device(u32 boot_device)
                u32 boot_device;
                const char *ofpath;
        } spl_boot_devices_tbl[] = {
-               { BOOT_DEVICE_MMC1, "/dwmmc@fe320000" },
+               { BOOT_DEVICE_MMC1, "/mmc@fe320000" },
                { BOOT_DEVICE_MMC2, "/sdhci@fe330000" },
                { BOOT_DEVICE_SPI, "/spi@ff1d0000" },
        };
index 6b02dc8beb20a4024161d257bec4f8b68519c6d7..690cbe7f27892944e5cf25ccd40c5c9b80b1e32c 100644 (file)
@@ -21,6 +21,9 @@ static const struct udevice_id rk3399_syscon_ids[] = {
 U_BOOT_DRIVER(syscon_rk3399) = {
        .name = "rk3399_syscon",
        .id = UCLASS_SYSCON,
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+       .bind = dm_scan_fdt_dev,
+#endif
        .of_match = rk3399_syscon_ids,
 };
 
index 46b32eb345845d2eae6889bcdb798b82cf7c4c86..cddf4fd3d572d75d327daba2241849155207a3c1 100644 (file)
@@ -108,9 +108,6 @@ __weak int arch_cpu_init(void)
 void board_init_f(ulong dummy)
 {
        int ret;
-#if !defined(CONFIG_TPL) || defined(CONFIG_SPL_OS_BOOT)
-       struct udevice *dev;
-#endif
 
 #ifdef CONFIG_DEBUG_UART
        /*
@@ -140,13 +137,15 @@ void board_init_f(ulong dummy)
        /* Init ARM arch timer in arch/arm/cpu/armv7/arch_timer.c */
        timer_init();
 #endif
-#if !defined(CONFIG_TPL) || defined(CONFIG_SPL_OS_BOOT)
+#if !defined(CONFIG_TPL) || defined(CONFIG_SPL_RAM)
        debug("\nspl:init dram\n");
-       ret = uclass_get_device(UCLASS_RAM, 0, &dev);
+       ret = dram_init();
        if (ret) {
                printf("DRAM init failed: %d\n", ret);
                return;
        }
+       gd->ram_top = gd->ram_base + get_effective_memsize();
+       gd->ram_top = board_get_usable_ram_top(gd->ram_size);
 #endif
        preloader_console_init();
 }
diff --git a/board/pine64/pinebook-pro-rk3399/Kconfig b/board/pine64/pinebook-pro-rk3399/Kconfig
new file mode 100644 (file)
index 0000000..3bb7ca4
--- /dev/null
@@ -0,0 +1,15 @@
+if TARGET_PINEBOOK_PRO_RK3399
+
+config SYS_BOARD
+       default "pinebook-pro-rk3399"
+
+config SYS_VENDOR
+       default "pine64"
+
+config SYS_CONFIG_NAME
+       default "pinebook-pro-rk3399"
+
+config BOARD_SPECIFIC_OPTIONS
+       def_bool y
+
+endif
diff --git a/board/pine64/pinebook-pro-rk3399/MAINTAINERS b/board/pine64/pinebook-pro-rk3399/MAINTAINERS
new file mode 100644 (file)
index 0000000..227c1c0
--- /dev/null
@@ -0,0 +1,8 @@
+PINEBOOK_PRO
+M:     Peter Robinson <pbrobinson@gmail.com>
+S:     Maintained
+F:     board/pine64/rk3399-pinebook-pro/
+F:     include/configs/rk3399-pinebook-pro.h
+F:     arch/arm/dts/rk3399-pinebook-pro.dts
+F:     arch/arm/dts/rk3399-pinebook-pro-u-boot.dtsi
+F:     configs/pinebook-pro-rk3399_defconfig
diff --git a/board/pine64/pinebook-pro-rk3399/Makefile b/board/pine64/pinebook-pro-rk3399/Makefile
new file mode 100644 (file)
index 0000000..2f692a1
--- /dev/null
@@ -0,0 +1 @@
+obj-y  += pinebook-pro-rk3399.o
diff --git a/board/pine64/pinebook-pro-rk3399/pinebook-pro-rk3399.c b/board/pine64/pinebook-pro-rk3399/pinebook-pro-rk3399.c
new file mode 100644 (file)
index 0000000..516292a
--- /dev/null
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ * (C) Copyright 2020 Peter Robinson <pbrobinson at gmail.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/arch-rockchip/clock.h>
+#include <asm/arch-rockchip/grf_rk3399.h>
+#include <asm/arch-rockchip/hardware.h>
+#include <asm/arch-rockchip/misc.h>
+#include <power/regulator.h>
+
+#define GRF_IO_VSEL_BT565_SHIFT 0
+#define PMUGRF_CON0_VSEL_SHIFT 8
+
+#ifndef CONFIG_SPL_BUILD
+int board_early_init_f(void)
+{
+       struct udevice *regulator;
+       int ret;
+
+       ret = regulator_get_by_platname("vcc5v0_usb", &regulator);
+       if (ret) {
+               pr_debug("%s vcc5v0_usb init fail! ret %d\n", __func__, ret);
+               goto out;
+       }
+
+       ret = regulator_set_enable(regulator, true);
+       if (ret)
+               pr_debug("%s vcc5v0-host-en-gpio set fail! ret %d\n", __func__, ret);
+
+out:
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_MISC_INIT_R
+static void setup_iodomain(void)
+{
+       struct rk3399_grf_regs *grf =
+          syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+       struct rk3399_pmugrf_regs *pmugrf =
+          syscon_get_first_range(ROCKCHIP_SYSCON_PMUGRF);
+
+       /* BT565 is in 1.8v domain */
+       rk_setreg(&grf->io_vsel, 1 << GRF_IO_VSEL_BT565_SHIFT);
+
+       /* Set GPIO1 1.8v/3.0v source select to PMU1830_VOL */
+       rk_setreg(&pmugrf->soc_con0, 1 << PMUGRF_CON0_VSEL_SHIFT);
+}
+
+int misc_init_r(void)
+{
+       const u32 cpuid_offset = 0x7;
+       const u32 cpuid_length = 0x10;
+       u8 cpuid[cpuid_length];
+       int ret;
+
+       setup_iodomain();
+
+       ret = rockchip_cpuid_from_efuse(cpuid_offset, cpuid_length, cpuid);
+       if (ret)
+               return ret;
+
+       ret = rockchip_cpuid_set(cpuid, cpuid_length);
+       if (ret)
+               return ret;
+
+       return ret;
+}
+#endif
index e4d0967c14c2f32b7e5068dd5af17c25380b8a82..0bbdb0e33ae523344fbaee57302d8bda2ca49c47 100644 (file)
@@ -46,7 +46,9 @@ void ide_set_reset(int idereset)
        }
 }
 
+#ifndef CONFIG_DM_ETH
 int board_eth_init(bd_t *bis)
 {
        return pci_eth_init(bis);
 }
+#endif
index 561579d056e1dfbf717d3987895fd0699757c237..f7f08ae617d4c58553c7f06fa154a08b01f94f3d 100644 (file)
@@ -77,7 +77,7 @@ static int setup_boottargets(void)
        }
 
        /*
-        * Only run, if booting from mmc1 (i.e. /dwmmc@fe320000) and
+        * Only run, if booting from mmc1 (i.e. /mmc@fe320000) and
         * only consider cases where the default boot-order first
         * tries to boot from mmc0 (eMMC) and then from mmc1
         * (i.e. external SD).
@@ -85,7 +85,7 @@ static int setup_boottargets(void)
         * In other words: the SD card will be moved to earlier in the
         * order, if U-Boot was also loaded from the SD-card.
         */
-       if (!strcmp(boot_device, "/dwmmc@fe320000")) {
+       if (!strcmp(boot_device, "/mmc@fe320000")) {
                char *mmc0, *mmc1;
 
                debug("%s: booted from SD-Card\n", __func__);
index 7ea0b06a8017ecd23776c38db2d13b19cbd91ddf..0e96a8cd10406e5b5c1531af64c1301be13a4a0c 100644 (file)
@@ -61,7 +61,8 @@ static bd_t bdata __attribute__ ((section(".data")));
  */
 __weak void show_boot_progress(int val) {}
 
-#if defined(CONFIG_SPL_OS_BOOT) || CONFIG_IS_ENABLED(HANDOFF)
+#if defined(CONFIG_SPL_OS_BOOT) || CONFIG_IS_ENABLED(HANDOFF) || \
+       defined(CONFIG_SPL_ATF)
 /* weak, default platform-specific function to initialize dram banks */
 __weak int dram_init_banksize(void)
 {
@@ -103,12 +104,14 @@ void __weak spl_perform_fixups(struct spl_image_info *spl_image)
 {
 }
 
-void spl_fixup_fdt(void)
+void spl_fixup_fdt(void *fdt_blob)
 {
-#if defined(CONFIG_SPL_OF_LIBFDT) && defined(CONFIG_SYS_SPL_ARGS_ADDR)
-       void *fdt_blob = (void *)CONFIG_SYS_SPL_ARGS_ADDR;
+#if defined(CONFIG_SPL_OF_LIBFDT)
        int err;
 
+       if (!fdt_blob)
+               return;
+
        err = fdt_check_header(fdt_blob);
        if (err < 0) {
                printf("fdt_root: %s\n", fdt_strerror(err));
@@ -640,7 +643,8 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
        initr_watchdog();
 #endif
 
-       if (IS_ENABLED(CONFIG_SPL_OS_BOOT) || CONFIG_IS_ENABLED(HANDOFF))
+       if (IS_ENABLED(CONFIG_SPL_OS_BOOT) || CONFIG_IS_ENABLED(HANDOFF) ||
+           IS_ENABLED(CONFIG_SPL_ATF))
                dram_init_banksize();
 
        bootcount_inc();
@@ -682,6 +686,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
 #if CONFIG_IS_ENABLED(ATF)
        case IH_OS_ARM_TRUSTED_FIRMWARE:
                debug("Jumping to U-Boot via ARM Trusted Firmware\n");
+               spl_fixup_fdt(spl_image.fdt_addr);
                spl_invoke_atf(&spl_image);
                break;
 #endif
@@ -701,7 +706,9 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
 #ifdef CONFIG_SPL_OS_BOOT
        case IH_OS_LINUX:
                debug("Jumping to Linux\n");
-               spl_fixup_fdt();
+#if defined(CONFIG_SYS_SPL_ARGS_ADDR)
+               spl_fixup_fdt((void *)CONFIG_SYS_SPL_ARGS_ADDR);
+#endif
                spl_board_prepare_for_linux();
                jump_to_image_linux(&spl_image);
 #endif
index 7f14e18b1b31966a5c79390cd9b88ec7c276b6a2..6cfb4e5dac19601dd94f5223f3c359bfa69c8a3f 100644 (file)
@@ -28,6 +28,7 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MISC=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ROCKCHIP=y
@@ -35,10 +36,13 @@ CONFIG_SF_DEFAULT_SPEED=20000000
 CONFIG_DM_ETH=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_GMAC_ROCKCHIP=y
+CONFIG_PHY_ROCKCHIP_INNO_USB2=y
+CONFIG_PHY_ROCKCHIP_TYPEC=y
 CONFIG_PMIC_RK8XX=y
 CONFIG_REGULATOR_PWM=y
 CONFIG_REGULATOR_RK8XX=y
 CONFIG_PWM_ROCKCHIP=y
+CONFIG_DM_RESET=y
 CONFIG_DM_RNG=y
 CONFIG_RNG_ROCKCHIP=y
 CONFIG_BAUDRATE=1500000
@@ -49,6 +53,8 @@ CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC3_GENERIC=y
 CONFIG_USB_HOST_ETHER=y
 CONFIG_USB_ETHER_ASIX=y
 CONFIG_USB_ETHER_ASIX88179=y
index 692138eb11500052daa2f4eb596ebbb6064541a7..4aeab0e35d6954eb27d2a1cd714125219c27b6d0 100644 (file)
@@ -40,6 +40,8 @@ CONFIG_ETH_DESIGNWARE=y
 CONFIG_MESON_G12A_USB_PHY=y
 CONFIG_PINCTRL=y
 CONFIG_PINCTRL_MESON_G12A=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MESON_EE_POWER_DOMAIN=y
 CONFIG_DM_REGULATOR=y
 CONFIG_DM_REGULATOR_FIXED=y
 CONFIG_DM_RESET=y
@@ -55,6 +57,7 @@ CONFIG_DM_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_DWC3=y
+CONFIG_USB_KEYBOARD=y
 # CONFIG_USB_DWC3_GADGET is not set
 CONFIG_USB_DWC3_MESON_G12A=y
 CONFIG_USB_GADGET=y
@@ -63,4 +66,10 @@ CONFIG_USB_GADGET_PRODUCT_NUM=0xfada
 CONFIG_USB_GADGET_DWC2_OTG=y
 CONFIG_USB_GADGET_DWC2_OTG_PHY_BUS_WIDTH_8=y
 CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_DM_VIDEO=y
+# CONFIG_VIDEO_BPP8 is not set
+# CONFIG_VIDEO_BPP16 is not set
+CONFIG_SYS_WHITE_ON_BLACK=y
+CONFIG_VIDEO_MESON=y
+CONFIG_VIDEO_DT_SIMPLEFB=y
 CONFIG_OF_LIBFDT_OVERLAY=y
index 28c20c0d6d59b5bc67d37d2bfdc5a34a2670dc81..887885f329fd255e28b4d2c623dd738f2e651ab5 100644 (file)
@@ -57,6 +57,7 @@ CONFIG_DM_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_DWC3=y
+CONFIG_USB_KEYBOARD=y
 # CONFIG_USB_DWC3_GADGET is not set
 CONFIG_USB_DWC3_MESON_G12A=y
 CONFIG_USB_GADGET=y
@@ -66,6 +67,9 @@ CONFIG_USB_GADGET_DWC2_OTG=y
 CONFIG_USB_GADGET_DWC2_OTG_PHY_BUS_WIDTH_8=y
 CONFIG_USB_GADGET_DOWNLOAD=y
 CONFIG_DM_VIDEO=y
+# CONFIG_VIDEO_BPP8 is not set
+# CONFIG_VIDEO_BPP16 is not set
+CONFIG_SYS_WHITE_ON_BLACK=y
 CONFIG_VIDEO_MESON=y
 CONFIG_VIDEO_DT_SIMPLEFB=y
 CONFIG_OF_LIBFDT_OVERLAY=y
index be91e27d822107ff7a3ca29102d787ecffd9fc3e..6fef7e61b9b945009257498336ec1c9d1516595b 100644 (file)
@@ -50,7 +50,10 @@ CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_DWC3=y
+CONFIG_ROCKCHIP_USB2_PHY=y
 CONFIG_USB_KEYBOARD=y
+CONFIG_USB_GADGET=y
 CONFIG_USB_HOST_ETHER=y
 CONFIG_USB_ETHER_ASIX=y
 CONFIG_USB_ETHER_ASIX88179=y
diff --git a/configs/pinebook-pro-rk3399_defconfig b/configs/pinebook-pro-rk3399_defconfig
new file mode 100644 (file)
index 0000000..0e9f0ec
--- /dev/null
@@ -0,0 +1,84 @@
+CONFIG_ARM=y
+CONFIG_ARCH_ROCKCHIP=y
+CONFIG_SYS_TEXT_BASE=0x00200000
+CONFIG_ENV_OFFSET=0x3F8000
+CONFIG_ROCKCHIP_RK3399=y
+CONFIG_RAM_RK3399_LPDDR4=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_TARGET_PINEBOOK_PRO_RK3399=y
+CONFIG_BAUDRATE=1500000
+CONFIG_DEBUG_UART=y
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_DEBUG_UART_BASE=0xFF1A0000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_SPL_SPI_SUPPORT=y
+CONFIG_SPL_SPI_FLASH_SUPPORT=y
+CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_DEFAULT_FDT_FILE="rockchip/rk3399-pinebook-pro.dtb"
+CONFIG_MISC_INIT_R=y
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x10000
+CONFIG_TPL=y
+CONFIG_SPL_OF_CONTROL=y
+CONFIG_DEFAULT_DEVICE_TREE="rk3399-pinebook-pro"
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_CMD_BOOTZ=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_MTDPARTS=y
+CONFIG_CMD_PMIC=y
+CONFIG_CMD_REGULATOR=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_SF=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_USB=y
+CONFIG_ROCKCHIP_GPIO=y
+CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_BOOTDELAY=3
+CONFIG_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_MISC=y
+CONFIG_ROCKCHIP_EFUSE=y
+CONFIG_MMC_DW=y
+CONFIG_MMC_DW_ROCKCHIP=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_SDMA=y
+CONFIG_MMC_SDHCI_ROCKCHIP=y
+CONFIG_ROCKCHIP_SPI=y
+CONFIG_SF_DEFAULT_SPEED=20000000
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_DM_ETH=y
+CONFIG_PMIC_RK8XX=y
+CONFIG_DM_PMIC_FAN53555=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_REGULATOR_RK8XX=y
+CONFIG_PWM_ROCKCHIP=y
+CONFIG_SYSRESET=y
+CONFIG_USB=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_DWC3=y
+# CONFIG_USB_XHCI_ROCKCHIP is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_DWC3=y
+CONFIG_ROCKCHIP_USB2_PHY=y
+CONFIG_USB_HOST_ETHER=y
+CONFIG_USB_ETHER_ASIX=y
+CONFIG_USB_ETHER_RTL8152=y
+CONFIG_USB_KEYBOARD=y
+CONFIG_USE_TINY_PRINTF=y
+CONFIG_SPL_TINY_MEMSET=y
+CONFIG_ERRNO_STR=y
+CONFIG_DM_VIDEO=y
+CONFIG_VIDEO_BPP16=y
+CONFIG_VIDEO_BPP32=y
+CONFIG_DISPLAY=y
+CONFIG_VIDEO_ROCKCHIP=y
+CONFIG_DISPLAY_ROCKCHIP_EDP=y
index 8ae4ba1a1c8d195cdab1832ec4413bc32bcd2915..900428a84f031be56f218c454ebe832dfe4f481c 100644 (file)
@@ -7,8 +7,7 @@ CONFIG_TARGET_R2DPLUS=y
 CONFIG_BOOTDELAY=-1
 CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="console=ttySC0,115200"
-# CONFIG_CMDLINE_EDITING is not set
-# CONFIG_AUTO_COMPLETE is not set
+CONFIG_HUSH_PARSER=y
 CONFIG_CMD_IMLS=y
 CONFIG_CMD_DM=y
 CONFIG_CMD_IDE=y
index d3a3b5ee4909b522846fcf1967f8c47a998ede21..1c1539bcb9a24c01adc207cea34d3c7fba488acf 100644 (file)
@@ -29,6 +29,7 @@ CONFIG_ENV_IS_IN_MMC=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MISC=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
 CONFIG_MMC_SDHCI=y
@@ -39,6 +40,8 @@ CONFIG_ETH_DESIGNWARE=y
 CONFIG_GMAC_ROCKCHIP=y
 CONFIG_NVME=y
 CONFIG_PCI=y
+CONFIG_PHY_ROCKCHIP_INNO_USB2=y
+CONFIG_PHY_ROCKCHIP_TYPEC=y
 CONFIG_PMIC_RK8XX=y
 CONFIG_REGULATOR_PWM=y
 CONFIG_REGULATOR_RK8XX=y
@@ -54,6 +57,8 @@ CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC3_GENERIC=y
 CONFIG_USB_KEYBOARD=y
 CONFIG_USB_HOST_ETHER=y
 CONFIG_USB_ETHER_ASIX=y
index aff690f0396a35626e3b5f6ab6f142022504a82e..76e76c160efeca47a028ce726565502365e89c9b 100644 (file)
@@ -28,6 +28,7 @@ CONFIG_ENV_IS_IN_MMC=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_MISC=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_ROCKCHIP=y
 CONFIG_MMC_SDHCI=y
@@ -36,11 +37,14 @@ CONFIG_SPI_FLASH_WINBOND=y
 CONFIG_DM_ETH=y
 CONFIG_ETH_DESIGNWARE=y
 CONFIG_GMAC_ROCKCHIP=y
+CONFIG_PHY_ROCKCHIP_INNO_USB2=y
+CONFIG_PHY_ROCKCHIP_TYPEC=y
 CONFIG_PMIC_RK8XX=y
 CONFIG_REGULATOR_PWM=y
 CONFIG_REGULATOR_RK8XX=y
 CONFIG_PWM_ROCKCHIP=y
 CONFIG_RAM_RK3399_LPDDR4=y
+CONFIG_DM_RESET=y
 CONFIG_BAUDRATE=1500000
 CONFIG_DEBUG_UART_SHIFT=2
 CONFIG_ROCKCHIP_SPI=y
@@ -50,6 +54,8 @@ CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC3_GENERIC=y
 CONFIG_USB_KEYBOARD=y
 CONFIG_USB_HOST_ETHER=y
 CONFIG_USB_ETHER_ASIX=y
index 9d4343a5a796395f3090217554a2a9d3f1b50bde..8c4b2f35c1b99b8119a896dcea6da71785d8ac84 100644 (file)
@@ -28,6 +28,7 @@ CONFIG_ENV_IS_IN_MMC=y
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_ROCKCHIP_GPIO=y
 CONFIG_SYS_I2C_ROCKCHIP=y
+CONFIG_DM_KEYBOARD=y
 CONFIG_MISC=y
 CONFIG_ROCKCHIP_EFUSE=y
 CONFIG_MMC_DW=y
@@ -52,6 +53,8 @@ CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_GENERIC=y
 CONFIG_USB_KEYBOARD=y
 CONFIG_USB_HOST_ETHER=y
 CONFIG_USB_ETHER_ASIX=y
index c1237ea296467efa44c6b3dd91f05798356f410e..a3f049e124e1bf84a88d5335c0bb778b5dec8fe0 100644 (file)
@@ -80,7 +80,6 @@ CONFIG_OF_CONTROL=y
 CONFIG_OF_LIVE=y
 CONFIG_OF_HOSTFILE=y
 CONFIG_DEFAULT_DEVICE_TREE="sandbox64"
-CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NETCONSOLE=y
 CONFIG_IP_DEFRAG=y
 CONFIG_REGMAP=y
index 9445d781182d51accc39fb70bd232477fce9da23..c09bf3349357a1efc9954b7a165ca12018c79aba 100644 (file)
@@ -89,7 +89,6 @@ CONFIG_OF_CONTROL=y
 CONFIG_OF_LIVE=y
 CONFIG_OF_HOSTFILE=y
 CONFIG_DEFAULT_DEVICE_TREE="sandbox"
-CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NETCONSOLE=y
 CONFIG_IP_DEFRAG=y
 CONFIG_REGMAP=y
index a4a7ae83795a8fe4d035d9f097e24b5489518346..21f9047046a3c0ae0a885d77c10f184e8237d2e3 100644 (file)
@@ -63,7 +63,6 @@ CONFIG_AMIGA_PARTITION=y
 CONFIG_OF_CONTROL=y
 CONFIG_OF_HOSTFILE=y
 CONFIG_DEFAULT_DEVICE_TREE="sandbox"
-CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NETCONSOLE=y
 CONFIG_IP_DEFRAG=y
 CONFIG_REGMAP=y
index 945fe54d20db32cf667512ae2ba61edc4394ae48..fc8b26e88cfe51272c692584c7dc3a1cc8661dfd 100644 (file)
@@ -79,7 +79,6 @@ CONFIG_SPL_OF_CONTROL=y
 CONFIG_OF_HOSTFILE=y
 CONFIG_DEFAULT_DEVICE_TREE="sandbox"
 CONFIG_SPL_OF_PLATDATA=y
-CONFIG_SYS_RELOC_GD_ENV_ADDR=y
 CONFIG_NETCONSOLE=y
 CONFIG_IP_DEFRAG=y
 CONFIG_SPL_DM=y
index 70c8798ed2d07de58f09d8cfe3d681151e729d91..154166ec7843428440d5ccc63f0ac041bccaa2c4 100644 (file)
@@ -8,6 +8,10 @@ U-Boot on Rockchip
 
 A wide range of Rockchip SoCs are supported in mainline U-Boot
 
+Warning
+=======
+This document is being moved to doc/board/rockchip, so information on it
+might be incomplete or outdated.
 
 Prerequisites
 =============
@@ -24,77 +28,9 @@ You will need:
    - Suitable ARM cross compiler, e.g.:
         sudo apt-get install gcc-4.7-arm-linux-gnueabi
 
-
 Building
 ========
 
-At present 11 RK3288 boards are supported:
-
-   - EVB RK3288 - use evb-rk3288 configuration
-   - Firefly RK3288 - use firefly-rk3288 configuration
-   - Hisense Chromebook - use chromebook_jerry configuration
-   - Asus C100P Chromebook - use chromebook_minnie configuration
-   - Asus Chromebit - use chromebook_mickey configuration
-   - MiQi RK3288 - use miqi-rk3288 configuration
-   - phyCORE-RK3288 RDK - use phycore-rk3288 configuration
-   - PopMetal RK3288 - use popmetal-rk3288 configuration
-   - Radxa Rock 2 - use rock2 configuration
-   - Tinker RK3288 - use tinker-rk3288 configuration
-   - Vyasa RK3288 - use vyasa-rk3288 configuration
-
-Two RK3036 boards are supported:
-
-   - EVB RK3036 - use evb-rk3036 configuration
-   - Kylin - use kylin_rk3036 configuration
-
-Two RK3308 boards are supported:
-
-   - EVB RK3308 - use evb-rk3308 configuration
-   - ROC-CC-RK3308 - use roc-cc-rk3308 configuration
-
-Three RK3328 boards are supported:
-
-   - EVB RK3328 - use evb-rk3328_defconfig
-   - Pine64 Rock64 board - use rock64-rk3328_defconfig
-   - Firefly / Libre Computer Project ROC-RK3328-CC board -
-     use roc-cc-rk3328_defconfig
-
-Size RK3399 boards are supported (aarch64):
-
-   - EBV RK3399 - use evb_rk3399 configuration
-   - Firefly RK3399 - use the firefly_rk3399 configuration
-   - Puma - use puma_rk3399 configuration
-   - Ficus - use ficus-rk3399 configuration
-   - Rock960 (Vamrs) - use rock960-rk3399 configuration
-   - Bob - use chromebook_bob configuration
-
-Four RK3368 boards are supported:
-
-   - Sheep - use sheep-rk3368 configuration
-   - Lion - use lion-rk3368 configuration
-   - Geekbox - use geekbox configuration
-   - EVB PX5 - use evb-px5  configuration
-
-One RK3128 board is supported:
-
-   - EVB RK3128 - use evb-rk3128 configuration
-
-One RK3229 board is supported:
-
-   - EVB RK3229 - use evb-rk3229 configuration
-
-Two RV1108 boards are supported:
-
-   - EVB RV1108 - use evb-rv1108 configuration
-   - Elgin R1 - use elgin-rv1108 configuration
-
-One RV3188 baord is supported:
-
-   - Raxda Rock - use rock configuration
-
-
-For example:
-
 1. To build RK3288 board:
 
    CROSS_COMPILE=arm-linux-gnueabi- make O=firefly firefly-rk3288_defconfig all
index dfa845cc82749a3bcd3703bbd2bffe7a5571ae40..f6a55fe78002e6a014005cf52b6fc038a76821f3 100644 (file)
@@ -2,59 +2,37 @@ Sandbox SPI/SPI Flash Implementation
 ====================================
 
 U-Boot supports SPI and SPI flash emulation in sandbox. This must be enabled
-using the --spi_sf paramter when starting U-Boot.
+via a device tree.
 
 For example:
 
-$ make O=sandbox sandbox_config
-$ make O=sandbox
-$ ./sandbox/u-boot --spi_sf 0:0:W25Q128:b/chromeos_peach/out/image.bin
-
-The four parameters to spi_sf are:
-
-   SPI bus number (typically 0)
-   SPI chip select number (typically 0)
-   SPI chip to emulate
-   File containing emulated data
+       spi@0 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0 1>;
+               compatible = "sandbox,spi";
+               cs-gpios = <0>, <&gpio_a 0>;
+               spi.bin@0 {
+                       reg = <0>;
+                       compatible = "spansion,m25p16", "jedec,spi-nor";
+                       spi-max-frequency = <40000000>;
+                       sandbox,filename = "spi.bin";
+               };
+       };
 
 Supported chips are W25Q16 (2MB), W25Q32 (4MB) and W25Q128 (16MB). Once
 U-Boot it started you can use 'sf' commands as normal. For example:
 
-$ ./b/sandbox/u-boot --spi_sf 0:0:W25Q128:b/chromeos_peach/out/image.bin \
-       -c "sf probe; sf test 0 100000; sf read 0 1000 1000; \
-               sf erase 1000 1000; sf write 0 1000 1000"
-
-
-U-Boot 2013.10-00237-gd4e0fdb (Nov 07 2013 - 20:08:15)
-
-DRAM:  128 MiB
-Using default environment
-
-In:    serial
-Out:   serial
-Err:   serial
-SF: Detected W25Q128BV with page size 256 Bytes, erase size 4 KiB, total 16 MiB
-SPI flash test:
-0 erase: 1 ticks, 1024000 KiB/s 8192.000 Mbps
-1 check: 2 ticks, 512000 KiB/s 4096.000 Mbps
-2 write: 6 ticks, 170666 KiB/s 1365.328 Mbps
-3 read: 0 ticks, 1048576000 KiB/s -201326.-592 Mbps
-Test passed
-0 erase: 1 ticks, 1024000 KiB/s 8192.000 Mbps
-1 check: 2 ticks, 512000 KiB/s 4096.000 Mbps
-2 write: 6 ticks, 170666 KiB/s 1365.328 Mbps
-3 read: 0 ticks, 1048576000 KiB/s -201326.-592 Mbps
-SF: 4096 bytes @ 0x1000 Read: OK
-SF: 4096 bytes @ 0x1000 Erased: OK
-SF: 4096 bytes @ 0x1000 Written: OK
-
+$ dd if=/dev/zero of=spi.bin bs=1M count=2
+$ u-boot -T
 
 Since the SPI bus is fully implemented as well as the SPI flash connected to
 it, you can also use low-level SPI commands to access the flash. For example
 this reads the device ID from the emulated chip:
 
 => sspi 0 32 9f
-FFEF4018
+SF: Detected m25p16 with page size 256 Bytes, erase size 64 KiB, total 2 MiB
+FF202015
 
 
 Simon Glass
index 6a1c6fc552b166839752824dde1bc2c8305c4358..360f22461a7d03ca89eb9ab844c9a0eca4a5bd51 100644 (file)
@@ -316,19 +316,29 @@ SPI Emulation
 
 Sandbox supports SPI and SPI flash emulation.
 
-This is controlled by the spi_sf argument, the format of which is::
-
-   bus:cs:device:file
-
-   bus    - SPI bus number
-   cs     - SPI chip select number
-   device - SPI device emulation name
-   file   - File on disk containing the data
-
-For example::
-
-   dd if=/dev/zero of=spi.bin bs=1M count=4
-   ./u-boot --spi_sf 0:0:M25P16:spi.bin
+The device can be enabled via a device tree, for example::
+
+    spi@0 {
+            #address-cells = <1>;
+            #size-cells = <0>;
+            reg = <0 1>;
+            compatible = "sandbox,spi";
+            cs-gpios = <0>, <&gpio_a 0>;
+            spi.bin@0 {
+                    reg = <0>;
+                    compatible = "spansion,m25p16", "jedec,spi-nor";
+                    spi-max-frequency = <40000000>;
+                    sandbox,filename = "spi.bin";
+            };
+    };
+
+The file must be created in advance::
+
+   $ dd if=/dev/zero of=spi.bin bs=1M count=2
+   $ u-boot -T
+
+Here, you can use "-T" or "-D" option to specify test.dtb or u-boot.dtb,
+respectively, or "-d <file>" for your own dtb.
 
 With this setup you can issue SPI flash commands as normal::
 
@@ -346,22 +356,6 @@ also use low-level SPI commands::
 This is issuing a READ_ID command and getting back 20 (ST Micro) part
 0x2015 (the M25P16).
 
-Drivers are connected to a particular bus/cs using sandbox's state
-structure (see the 'spi' member). A set of operations must be provided
-for each driver.
-
-
-Configuration settings for the curious are:
-
-CONFIG_SANDBOX_SPI_MAX_BUS:
-  The maximum number of SPI buses supported by the driver (default 1).
-
-CONFIG_SANDBOX_SPI_MAX_CS:
-  The maximum number of chip selects supported by the driver (default 10).
-
-CONFIG_SPI_IDLE_VAL:
-  The idle value on the SPI bus
-
 
 Block Device Emulation
 ----------------------
index cd9c8d6dc47b9808a833b3af89bc51cf119dace6..7b72fab496cf7d2c01437667a865bef92d06fe79 100644 (file)
@@ -21,44 +21,60 @@ mainline U-Boot.
 
 List of mainline supported rockchip boards:
 
+* rk3036
+     - Rockchip Evb-RK3036 (evb-rk3036)
+     - Kylin (kylin_rk3036)
+* rk3128
+     - Rockchip Evb-RK3128 (evb-rk3128)
+* rk3229
+     - Rockchip Evb-RK3229 (evb-rk3229)
 * rk3288
-     - Evb-RK3288
-     - Firefly-RK3288
-     - mqmaker MiQi
-     - Phytec RK3288 PCM-947
-     - PopMetal-RK3288
-     - Radxa Rock 2 Square
-     - Tinker-RK3288
-     - Google Jerry
-     - Google Mickey
-     - Google Minnie
-     - Google Speedy
-     - Amarula Vyasa-RK3288
+     - Rockchip Evb-RK3288 (evb-rk3288)
+     - Firefly-RK3288 (firefly-rk3288)
+     - MQmaker MiQi (miqi-rk3288)
+     - Phytec RK3288 PCM-947 (phycore-rk3288)
+     - PopMetal-RK3288 (popmetal-rk3288)
+     - Radxa Rock 2 Square (rock2)
+     - Tinker-RK3288 (tinker-rk3288)
+     - Google Jerry (chromebook_jerry)
+     - Google Mickey (chromebook_mickey)
+     - Google Minnie (chromebook_minnie)
+     - Google Speedy (chromebook_speedy)
+     - Amarula Vyasa-RK3288 (vyasa-rk3288)
+* rk3308
+     - Rockchip Evb-RK3308 (evb-rk3308)
+     - Roc-cc-RK3308 (roc-cc-rk3308)
 * rk3328
-     - Rockchip RK3328 EVB
-     - Pine64 Rock64
+     - Rockchip Evb-RK3328 (evb-rk3328)
+     - Pine64 Rock64 (rock64-rk3328)
+     - Firefly-RK3328 (roc-cc-rk3328)
 * rk3368
-     - GeekBox
-     - PX5 EVB
-     - Rockchip sheep board
-     - Theobroma Systems RK3368-uQ7 SoM
+     - GeekBox (geekbox)
+     - PX5 EVB (evb-px5)
+     - Rockchip Sheep (sheep-rk3368)
+     - Theobroma Systems RK3368-uQ7 SoM - Lion (lion-rk3368)
 * rk3399
-     - 96boards RK3399 Ficus
-     - 96boards Rock960
-     - Firefly-RK3399 Board
-     - Firefly ROC-RK3399-PC Board
-     - FriendlyElec NanoPC-T4
-     - FriendlyElec NanoPi M4
-     - FriendlyARM NanoPi NEO4
-     - Google Bob
-     - Khadas Edge
-     - Khadas Edge-Captain
-     - Khadas Edge-V
-     - Orange Pi RK3399 Board
-     - Pine64 RockPro64
-     - Radxa ROCK Pi 4
-     - Rockchip RK3399 Evaluation Board
-     - Theobroma Systems RK3399-Q7 SoM
+     - 96boards RK3399 Ficus (ficus-rk3399)
+     - 96boards Rock960 (rock960-rk3399)
+     - Firefly-RK3399 (firefly_rk3399)
+     - Firefly ROC-RK3399-PC
+     - FriendlyElec NanoPC-T4 (nanopc-t4-rk3399)
+     - FriendlyElec NanoPi M4 (nanopi-m4-rk3399)
+     - FriendlyARM NanoPi NEO4 (nanopi-neo4-rk3399)
+     - Google Bob (chromebook_bob)
+     - Khadas Edge (khadas-edge-rk3399)
+     - Khadas Edge-Captain (khadas-edge-captain-rk3399)
+     - Khadas Edge-V (hadas-edge-v-rk3399)
+     - Orange Pi RK3399 (orangepi-rk3399)
+     - Pine64 RockPro64 (rockpro64-rk3399)
+     - Radxa ROCK Pi 4 (rock-pi-4-rk3399)
+     - Rockchip Evb-RK3399 (evb_rk3399)
+     - Theobroma Systems RK3399-Q7 SoM - Puma (puma_rk3399)
+* rv1108
+     - Rockchip Evb-rv1108 (evb-rv1108)
+     - Elgin-R1 (elgin-rv1108)
+* rv3188
+     - Radxa Rock (rock)
 
 Building
 --------
@@ -117,14 +133,42 @@ To write an image that boots from an SD card (assumed to be /dev/sda)::
         sudo dd if=u-boot-rockchip.bin of=/dev/sda seek=64
         sync
 
+eMMC
+^^^^
+
+eMMC flash would probe on mmc0 in most of the rockchip platforms.
+
+Create GPT partition layout as defined in configurations::
+
+        mmc dev 0
+        gpt write mmc 0 $partitions
+
+Connect the USB-OTG cable between host and target device.
+
+Launch fastboot at target::
+
+        fastboot 0
+
+Upon successful gadget connection,host show the USB device like::
+
+        lsusb
+        Bus 001 Device 020: ID 2207:330c Fuzhou Rockchip Electronics Company RK3399 in Mask ROM mode
+
+Program the flash::
+
+        sudo fastboot -i 0x2207 flash loader1 idbloader.img
+        sudo fastboot -i 0x2207 flash loader2 u-boot.itb
+
+Note: for rockchip 32-bit platforms the U-Boot proper image
+is u-boot-dtb.img
+
 TODO
 ----
 
 - Add rockchip idbloader image building
 - Add rockchip TPL image building
 - Document SPI flash boot
-- Describe steps for eMMC flashing
 - Add missing SoC's with it boards list
 
 .. Jagan Teki <jagan@amarulasolutions.com>
-.. Fri Jan 10 00:08:40 IST 2020
+.. Sunday 24 May 2020 10:08:41 PM IST
index 420875042896a724ebe17319c778275811e182f2..94e8c5da170bf8adc7800c859a989dbd4ade3697 100644 (file)
@@ -91,6 +91,7 @@ obj-y += dfu/
 obj-$(CONFIG_PCH) += pch/
 obj-y += phy/allwinner/
 obj-y += phy/marvell/
+obj-y += phy/rockchip/
 obj-y += rtc/
 obj-y += scsi/
 obj-y += sound/
index 6a78837619eff53190a158ae87f0c6bce51a4bef..22c373a623ca96d2bc36aa45a23d61626f31cb4c 100644 (file)
@@ -728,7 +728,7 @@ static ulong rk3399_mmc_get_clk(struct rockchip_cru *cru, uint clk_id)
                div = 2;
                break;
        case SCLK_EMMC:
-               con = readl(&cru->clksel_con[21]);
+               con = readl(&cru->clksel_con[22]);
                div = 1;
                break;
        default:
@@ -1000,6 +1000,8 @@ static ulong rk3399_clk_set_rate(struct clk *clk, ulong rate)
        case ACLK_VOP1:
        case HCLK_VOP1:
        case HCLK_SD:
+       case SCLK_UPHY0_TCPDCORE:
+       case SCLK_UPHY1_TCPDCORE:
                /**
                 * assigned-clocks handling won't require for vopl, so
                 * return 0 to satisfy clk_set_defaults during device probe.
@@ -1094,6 +1096,12 @@ static int rk3399_clk_enable(struct clk *clk)
        case SCLK_MACREF_OUT:
                rk_clrreg(&priv->cru->clkgate_con[5], BIT(6));
                break;
+       case SCLK_USB2PHY0_REF:
+               rk_clrreg(&priv->cru->clkgate_con[6], BIT(5));
+               break;
+       case SCLK_USB2PHY1_REF:
+               rk_clrreg(&priv->cru->clkgate_con[6], BIT(6));
+               break;
        case ACLK_GMAC:
                rk_clrreg(&priv->cru->clkgate_con[32], BIT(0));
                break;
@@ -1139,6 +1147,18 @@ static int rk3399_clk_enable(struct clk *clk)
        case HCLK_HOST1_ARB:
                rk_clrreg(&priv->cru->clksel_con[20], BIT(8));
                break;
+       case SCLK_UPHY0_TCPDPHY_REF:
+               rk_clrreg(&priv->cru->clkgate_con[13], BIT(4));
+               break;
+       case SCLK_UPHY0_TCPDCORE:
+               rk_clrreg(&priv->cru->clkgate_con[13], BIT(5));
+               break;
+       case SCLK_UPHY1_TCPDPHY_REF:
+               rk_clrreg(&priv->cru->clkgate_con[13], BIT(6));
+               break;
+       case SCLK_UPHY1_TCPDCORE:
+               rk_clrreg(&priv->cru->clkgate_con[13], BIT(7));
+               break;
        case SCLK_PCIEPHY_REF:
                rk_clrreg(&priv->cru->clksel_con[18], BIT(10));
                break;
@@ -1170,6 +1190,12 @@ static int rk3399_clk_disable(struct clk *clk)
        case SCLK_MACREF_OUT:
                rk_setreg(&priv->cru->clkgate_con[5], BIT(6));
                break;
+       case SCLK_USB2PHY0_REF:
+               rk_setreg(&priv->cru->clkgate_con[6], BIT(5));
+               break;
+       case SCLK_USB2PHY1_REF:
+               rk_setreg(&priv->cru->clkgate_con[6], BIT(6));
+               break;
        case ACLK_GMAC:
                rk_setreg(&priv->cru->clkgate_con[32], BIT(0));
                break;
@@ -1215,6 +1241,18 @@ static int rk3399_clk_disable(struct clk *clk)
        case HCLK_HOST1_ARB:
                rk_setreg(&priv->cru->clksel_con[20], BIT(8));
                break;
+       case SCLK_UPHY0_TCPDPHY_REF:
+               rk_setreg(&priv->cru->clkgate_con[13], BIT(4));
+               break;
+       case SCLK_UPHY0_TCPDCORE:
+               rk_setreg(&priv->cru->clkgate_con[13], BIT(5));
+               break;
+       case SCLK_UPHY1_TCPDPHY_REF:
+               rk_setreg(&priv->cru->clkgate_con[13], BIT(6));
+               break;
+       case SCLK_UPHY1_TCPDCORE:
+               rk_setreg(&priv->cru->clkgate_con[13], BIT(7));
+               break;
        case SCLK_PCIEPHY_REF:
                rk_clrreg(&priv->cru->clksel_con[18], BIT(10));
                break;
index 3d421f7a69c71472abed7c0dd60de1b8c9a1c05e..047089c886711411e66316c5aeb093f0bc93ce88 100644 (file)
@@ -4,12 +4,12 @@
  * Written by Simon Glass <sjg@chromium.org>
  */
 
-#include <asm/types.h>
-#include <asm/io.h>
 #include <common.h>
 #include <dm.h>
-#include <mapmem.h>
 #include <dm/of_access.h>
+#include <mapmem.h>
+#include <asm/types.h>
+#include <asm/io.h>
 
 int dev_read_u32(const struct udevice *dev, const char *propname, u32 *outp)
 {
index 42ee7d523e37e349d905f9aa7c81d95f90d4b4ac..3616e2105fab36e2689cefb9ae8871fb44cd9835 100644 (file)
 #include <dm/device_compat.h>
 #include <linux/err.h>
 
+/*
+ * This assigned unique hex value is constant and is derived from the two ASCII
+ * letters 'DW' followed by a 16-bit unsigned number
+ */
+#define DW_I2C_COMP_TYPE       0x44570140
+
 #ifdef CONFIG_SYS_I2C_DW_ENABLE_STATUS_UNSUPPORTED
 static int  dw_i2c_enable(struct i2c_regs *i2c_base, bool enable)
 {
@@ -199,18 +205,24 @@ static int dw_i2c_calc_timing(struct dw_i2c *priv, enum i2c_speed_mode mode,
        return 0;
 }
 
-static int calc_bus_speed(struct dw_i2c *priv, int speed, ulong bus_clk,
-                         struct dw_i2c_speed_config *config)
+/**
+ * calc_bus_speed() - Calculate the config to use for a particular i2c speed
+ *
+ * @priv: Private information for the driver (NULL if not using driver model)
+ * @i2c_base: Registers for the I2C controller
+ * @speed: Required i2c speed in Hz
+ * @bus_clk: Input clock to the I2C controller in Hz (e.g. IC_CLK)
+ * @config: Returns the config to use for this speed
+ * @return 0 if OK, -ve on error
+ */
+static int calc_bus_speed(struct dw_i2c *priv, struct i2c_regs *regs, int speed,
+                         ulong bus_clk, struct dw_i2c_speed_config *config)
 {
        const struct dw_scl_sda_cfg *scl_sda_cfg = NULL;
-       struct i2c_regs *regs = priv->regs;
        enum i2c_speed_mode i2c_spd;
-       u32 comp_param1;
        int spk_cnt;
        int ret;
 
-       comp_param1 = readl(&regs->comp_param1);
-
        if (priv)
                scl_sda_cfg = priv->scl_sda_cfg;
        /* Allow high speed if there is no config, or the config allows it */
@@ -225,6 +237,9 @@ static int calc_bus_speed(struct dw_i2c *priv, int speed, ulong bus_clk,
 
        /* Check is high speed possible and fall back to fast mode if not */
        if (i2c_spd == IC_SPEED_MODE_HIGH) {
+               u32 comp_param1;
+
+               comp_param1 = readl(&regs->comp_param1);
                if ((comp_param1 & DW_IC_COMP_PARAM_1_SPEED_MODE_MASK)
                                != DW_IC_COMP_PARAM_1_SPEED_MODE_HIGH)
                        i2c_spd = IC_SPEED_MODE_FAST;
@@ -260,11 +275,14 @@ static int calc_bus_speed(struct dw_i2c *priv, int speed, ulong bus_clk,
        return 0;
 }
 
-/*
- * _dw_i2c_set_bus_speed - Set the i2c speed
- * @speed:     required i2c speed
+/**
+ * _dw_i2c_set_bus_speed() - Set the i2c speed
  *
- * Set the i2c speed.
+ * @priv: Private information for the driver (NULL if not using driver model)
+ * @i2c_base: Registers for the I2C controller
+ * @speed: Required i2c speed in Hz
+ * @bus_clk: Input clock to the I2C controller in Hz (e.g. IC_CLK)
+ * @return 0 if OK, -ve on error
  */
 static int _dw_i2c_set_bus_speed(struct dw_i2c *priv, struct i2c_regs *i2c_base,
                                 unsigned int speed, unsigned int bus_clk)
@@ -274,7 +292,7 @@ static int _dw_i2c_set_bus_speed(struct dw_i2c *priv, struct i2c_regs *i2c_base,
        unsigned int ena;
        int ret;
 
-       ret = calc_bus_speed(priv, speed, bus_clk, &config);
+       ret = calc_bus_speed(priv, i2c_base, speed, bus_clk, &config);
        if (ret)
                return ret;
 
@@ -754,6 +772,17 @@ int designware_i2c_ofdata_to_platdata(struct udevice *bus)
 int designware_i2c_probe(struct udevice *bus)
 {
        struct dw_i2c *priv = dev_get_priv(bus);
+       uint comp_type;
+
+       comp_type = readl(&priv->regs->comp_type);
+       if (comp_type != DW_I2C_COMP_TYPE) {
+               log_err("I2C bus %s has unknown type %#x\n", bus->name,
+                       comp_type);
+               return -ENXIO;
+       }
+
+       log_info("I2C bus %s version %#x\n", bus->name,
+                readl(&priv->regs->comp_version));
 
        return __dw_i2c_init(priv->regs, 0, 0);
 }
index 8166df7ba63b852b6156863e93226741ded1f3de..8bc69e870fd4389cc532eaa7e95af561acb75b99 100644 (file)
@@ -516,7 +516,7 @@ int i2c_deblock_gpio_loop(struct gpio_desc *sda_pin,
        udelay(delay);
 
        /*  Toggle SCL until slave release SDA */
-       while (scl_count-- >= 0) {
+       for (; scl_count; --scl_count) {
                i2c_gpio_set_pin(scl_pin, 1);
                udelay(delay);
                i2c_gpio_set_pin(scl_pin, 0);
index ed23a623846008b0125019b549b505fa3be85034..45c34d388c8ab90827e7e08f7f80f73da6305cf3 100644 (file)
@@ -18,6 +18,7 @@ struct i2c_eeprom_drv_data {
        u32 pagesize; /* page size in bytes */
        u32 addr_offset_mask; /* bits in addr used for offset overflow */
        u32 offset_len; /* size in bytes of offset */
+       u32 start_offset; /* valid start offset inside memory, by default 0 */
 };
 
 int i2c_eeprom_read(struct udevice *dev, int offset, uint8_t *buf, int size)
@@ -148,7 +149,11 @@ static int i2c_eeprom_std_probe(struct udevice *dev)
        i2c_set_chip_addr_offset_mask(dev, data->addr_offset_mask);
 
        /* Verify that the chip is functional */
-       ret = i2c_eeprom_read(dev, 0, &test_byte, 1);
+       /*
+        * Not all eeproms start from offset 0. Valid offset is available
+        * in the platform data struct.
+        */
+       ret = i2c_eeprom_read(dev, data->start_offset, &test_byte, 1);
        if (ret)
                return -ENODEV;
 
@@ -216,6 +221,7 @@ static const struct i2c_eeprom_drv_data atmel24mac402_data = {
        .pagesize = 16,
        .addr_offset_mask = 0,
        .offset_len = 1,
+       .start_offset = 0x80,
 };
 
 static const struct i2c_eeprom_drv_data atmel24c32_data = {
index 82a8396e42c0d4418223e56cdfcef1650ea902fe..0edc2464a8913e7cf8c2677b1667937538b3264e 100644 (file)
@@ -322,7 +322,7 @@ static int rockchip_pcie_set_vpcie(struct udevice *dev)
        struct rockchip_pcie *priv = dev_get_priv(dev);
        int ret;
 
-       if (!IS_ERR(priv->vpcie3v3)) {
+       if (priv->vpcie3v3) {
                ret = regulator_set_enable(priv->vpcie3v3, true);
                if (ret) {
                        dev_err(dev, "failed to enable vpcie3v3 (ret=%d)\n",
@@ -331,24 +331,31 @@ static int rockchip_pcie_set_vpcie(struct udevice *dev)
                }
        }
 
-       ret = regulator_set_enable(priv->vpcie1v8, true);
-       if (ret) {
-               dev_err(dev, "failed to enable vpcie1v8 (ret=%d)\n", ret);
-               goto err_disable_3v3;
+       if (priv->vpcie1v8) {
+               ret = regulator_set_enable(priv->vpcie1v8, true);
+               if (ret) {
+                       dev_err(dev, "failed to enable vpcie1v8 (ret=%d)\n",
+                               ret);
+                       goto err_disable_3v3;
+               }
        }
 
-       ret = regulator_set_enable(priv->vpcie0v9, true);
-       if (ret) {
-               dev_err(dev, "failed to enable vpcie0v9 (ret=%d)\n", ret);
-               goto err_disable_1v8;
+       if (priv->vpcie0v9) {
+               ret = regulator_set_enable(priv->vpcie0v9, true);
+               if (ret) {
+                       dev_err(dev, "failed to enable vpcie0v9 (ret=%d)\n",
+                               ret);
+                       goto err_disable_1v8;
+               }
        }
 
        return 0;
 
 err_disable_1v8:
-       regulator_set_enable(priv->vpcie1v8, false);
+       if (priv->vpcie1v8)
+               regulator_set_enable(priv->vpcie1v8, false);
 err_disable_3v3:
-       if (!IS_ERR(priv->vpcie3v3))
+       if (priv->vpcie3v3)
                regulator_set_enable(priv->vpcie3v3, false);
        return ret;
 }
@@ -424,14 +431,14 @@ static int rockchip_pcie_parse_dt(struct udevice *dev)
 
        ret = device_get_supply_regulator(dev, "vpcie1v8-supply",
                                          &priv->vpcie1v8);
-       if (ret) {
+       if (ret && ret != -ENOENT) {
                dev_err(dev, "failed to get vpcie1v8 supply (ret=%d)\n", ret);
                return ret;
        }
 
        ret = device_get_supply_regulator(dev, "vpcie0v9-supply",
                                          &priv->vpcie0v9);
-       if (ret) {
+       if (ret && ret != -ENOENT) {
                dev_err(dev, "failed to get vpcie0v9 supply (ret=%d)\n", ret);
                return ret;
        }
index 1e38c8741f0dab8ec7c3d77f46c524b91fcc44aa..9c775107e9c2c440a17caa49d329a77030fa2f71 100644 (file)
@@ -225,4 +225,5 @@ config PHY_MTK_TPHY
          multi-ports is first version, otherwise is second veriosn,
          so you can easily distinguish them by banks layout.
 
+source "drivers/phy/rockchip/Kconfig"
 endmenu
diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
new file mode 100644 (file)
index 0000000..84cc7c8
--- /dev/null
@@ -0,0 +1,21 @@
+#
+# Phy drivers for Rockchip platforms
+#
+
+menu "Rockchip PHY driver"
+
+config PHY_ROCKCHIP_INNO_USB2
+       bool "Rockchip INNO USB2PHY Driver"
+       depends on ARCH_ROCKCHIP
+       select PHY
+       help
+         Support for Rockchip USB2.0 PHY with Innosilicon IP block.
+
+config PHY_ROCKCHIP_TYPEC
+       bool "Rockchip TYPEC PHY Driver"
+       depends on ARCH_ROCKCHIP
+       select PHY
+       help
+         Enable this to support the Rockchip USB TYPEC PHY.
+
+endmenu
diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile
new file mode 100644 (file)
index 0000000..95b2f8a
--- /dev/null
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2020 Amarula Solutions(India)
+#
+
+obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2)   += phy-rockchip-inno-usb2.o
+obj-$(CONFIG_PHY_ROCKCHIP_TYPEC)       += phy-rockchip-typec.o
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
new file mode 100644 (file)
index 0000000..c5ea6ca
--- /dev/null
@@ -0,0 +1,312 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Rockchip USB2.0 PHY with Innosilicon IP block driver
+ *
+ * Copyright (C) 2016 Fuzhou Rockchip Electronics Co., Ltd
+ * Copyright (C) 2020 Amarula Solutions(India)
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <dm/lists.h>
+#include <generic-phy.h>
+#include <reset.h>
+#include <syscon.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <linux/iopoll.h>
+#include <asm/arch-rockchip/clock.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define usleep_range(a, b) udelay((b))
+#define BIT_WRITEABLE_SHIFT    16
+
+enum rockchip_usb2phy_port_id {
+       USB2PHY_PORT_OTG,
+       USB2PHY_PORT_HOST,
+       USB2PHY_NUM_PORTS,
+};
+
+struct usb2phy_reg {
+       unsigned int    offset;
+       unsigned int    bitend;
+       unsigned int    bitstart;
+       unsigned int    disable;
+       unsigned int    enable;
+};
+
+struct rockchip_usb2phy_port_cfg {
+       struct usb2phy_reg      phy_sus;
+       struct usb2phy_reg      bvalid_det_en;
+       struct usb2phy_reg      bvalid_det_st;
+       struct usb2phy_reg      bvalid_det_clr;
+       struct usb2phy_reg      ls_det_en;
+       struct usb2phy_reg      ls_det_st;
+       struct usb2phy_reg      ls_det_clr;
+       struct usb2phy_reg      utmi_avalid;
+       struct usb2phy_reg      utmi_bvalid;
+       struct usb2phy_reg      utmi_ls;
+       struct usb2phy_reg      utmi_hstdet;
+};
+
+struct rockchip_usb2phy_cfg {
+       unsigned int reg;
+       const struct rockchip_usb2phy_port_cfg port_cfgs[USB2PHY_NUM_PORTS];
+};
+
+struct rockchip_usb2phy {
+       void *reg_base;
+       struct clk phyclk;
+       const struct rockchip_usb2phy_cfg *phy_cfg;
+};
+
+static inline int property_enable(void *reg_base,
+                                 const struct usb2phy_reg *reg, bool en)
+{
+       unsigned int val, mask, tmp;
+
+       tmp = en ? reg->enable : reg->disable;
+       mask = GENMASK(reg->bitend, reg->bitstart);
+       val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT);
+
+       return writel(val, reg_base + reg->offset);
+}
+
+static const
+struct rockchip_usb2phy_port_cfg *us2phy_get_port(struct phy *phy)
+{
+       struct udevice *parent = dev_get_parent(phy->dev);
+       struct rockchip_usb2phy *priv = dev_get_priv(parent);
+       const struct rockchip_usb2phy_cfg *phy_cfg = priv->phy_cfg;
+
+       return &phy_cfg->port_cfgs[phy->id];
+}
+
+static int rockchip_usb2phy_power_on(struct phy *phy)
+{
+       struct udevice *parent = dev_get_parent(phy->dev);
+       struct rockchip_usb2phy *priv = dev_get_priv(parent);
+       const struct rockchip_usb2phy_port_cfg *port_cfg = us2phy_get_port(phy);
+
+       property_enable(priv->reg_base, &port_cfg->phy_sus, false);
+
+       /* waiting for the utmi_clk to become stable */
+       usleep_range(1500, 2000);
+
+       return 0;
+}
+
+static int rockchip_usb2phy_power_off(struct phy *phy)
+{
+       struct udevice *parent = dev_get_parent(phy->dev);
+       struct rockchip_usb2phy *priv = dev_get_priv(parent);
+       const struct rockchip_usb2phy_port_cfg *port_cfg = us2phy_get_port(phy);
+
+       property_enable(priv->reg_base, &port_cfg->phy_sus, true);
+
+       return 0;
+}
+
+static int rockchip_usb2phy_init(struct phy *phy)
+{
+       struct udevice *parent = dev_get_parent(phy->dev);
+       struct rockchip_usb2phy *priv = dev_get_priv(parent);
+       const struct rockchip_usb2phy_port_cfg *port_cfg = us2phy_get_port(phy);
+       int ret;
+
+       ret = clk_enable(&priv->phyclk);
+       if (ret) {
+               dev_err(phy->dev, "failed to enable phyclk (ret=%d)\n", ret);
+               return ret;
+       }
+
+       if (phy->id == USB2PHY_PORT_OTG) {
+               property_enable(priv->reg_base, &port_cfg->bvalid_det_clr, true);
+               property_enable(priv->reg_base, &port_cfg->bvalid_det_en, true);
+       } else if (phy->id == USB2PHY_PORT_HOST) {
+               property_enable(priv->reg_base, &port_cfg->bvalid_det_clr, true);
+               property_enable(priv->reg_base, &port_cfg->bvalid_det_en, true);
+       }
+
+       return 0;
+}
+
+static int rockchip_usb2phy_exit(struct phy *phy)
+{
+       struct udevice *parent = dev_get_parent(phy->dev);
+       struct rockchip_usb2phy *priv = dev_get_priv(parent);
+
+       clk_disable(&priv->phyclk);
+
+       return 0;
+}
+
+static int rockchip_usb2phy_of_xlate(struct phy *phy,
+                                    struct ofnode_phandle_args *args)
+{
+       const char *name = phy->dev->name;
+
+       if (!strcasecmp(name, "host-port"))
+               phy->id = USB2PHY_PORT_HOST;
+       else if (!strcasecmp(name, "otg-port"))
+               phy->id = USB2PHY_PORT_OTG;
+       else
+               dev_err(phy->dev, "improper %s device\n", name);
+
+       return 0;
+}
+
+static struct phy_ops rockchip_usb2phy_ops = {
+       .init = rockchip_usb2phy_init,
+       .exit = rockchip_usb2phy_exit,
+       .power_on = rockchip_usb2phy_power_on,
+       .power_off = rockchip_usb2phy_power_off,
+       .of_xlate = rockchip_usb2phy_of_xlate,
+};
+
+static int rockchip_usb2phy_probe(struct udevice *dev)
+{
+       struct rockchip_usb2phy *priv = dev_get_priv(dev);
+       const struct rockchip_usb2phy_cfg *phy_cfgs;
+       unsigned int reg;
+       int index, ret;
+
+       priv->reg_base = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+       if (IS_ERR(priv->reg_base))
+               return PTR_ERR(priv->reg_base);
+
+       ret = ofnode_read_u32(dev_ofnode(dev), "reg", &reg);
+       if (ret) {
+               dev_err(dev, "failed to read reg property (ret = %d)\n", ret);
+               return ret;
+       }
+
+       phy_cfgs = (const struct rockchip_usb2phy_cfg *)
+                                       dev_get_driver_data(dev);
+       if (!phy_cfgs)
+               return -EINVAL;
+
+       /* find out a proper config which can be matched with dt. */
+       index = 0;
+       while (phy_cfgs[index].reg) {
+               if (phy_cfgs[index].reg == reg) {
+                       priv->phy_cfg = &phy_cfgs[index];
+                       break;
+               }
+
+               ++index;
+       }
+
+       if (!priv->phy_cfg) {
+               dev_err(dev, "failed find proper phy-cfg\n");
+               return -EINVAL;
+       }
+
+       ret = clk_get_by_name(dev, "phyclk", &priv->phyclk);
+       if (ret) {
+               dev_err(dev, "failed to get the phyclk (ret=%d)\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int rockchip_usb2phy_bind(struct udevice *dev)
+{
+       struct udevice *usb2phy_dev;
+       ofnode node;
+       const char *name;
+       int ret = 0;
+
+       dev_for_each_subnode(node, dev) {
+               if (!ofnode_valid(node)) {
+                       dev_info(dev, "subnode %s not found\n", dev->name);
+                       return -ENXIO;
+               }
+
+               name = ofnode_get_name(node);
+               dev_dbg(dev, "subnode %s\n", name);
+
+               ret = device_bind_driver_to_node(dev, "rockchip_usb2phy_port",
+                                                name, node, &usb2phy_dev);
+               if (ret) {
+                       dev_err(dev,
+                               "'%s' cannot bind 'rockchip_usb2phy_port'\n", name);
+                       return ret;
+               }
+       }
+
+       return ret;
+}
+
+static const struct rockchip_usb2phy_cfg rk3399_usb2phy_cfgs[] = {
+       {
+               .reg            = 0xe450,
+               .port_cfgs      = {
+                       [USB2PHY_PORT_OTG] = {
+                               .phy_sus        = { 0xe454, 1, 0, 2, 1 },
+                               .bvalid_det_en  = { 0xe3c0, 3, 3, 0, 1 },
+                               .bvalid_det_st  = { 0xe3e0, 3, 3, 0, 1 },
+                               .bvalid_det_clr = { 0xe3d0, 3, 3, 0, 1 },
+                               .utmi_avalid    = { 0xe2ac, 7, 7, 0, 1 },
+                               .utmi_bvalid    = { 0xe2ac, 12, 12, 0, 1 },
+                       },
+                       [USB2PHY_PORT_HOST] = {
+                               .phy_sus        = { 0xe458, 1, 0, 0x2, 0x1 },
+                               .ls_det_en      = { 0xe3c0, 6, 6, 0, 1 },
+                               .ls_det_st      = { 0xe3e0, 6, 6, 0, 1 },
+                               .ls_det_clr     = { 0xe3d0, 6, 6, 0, 1 },
+                               .utmi_ls        = { 0xe2ac, 22, 21, 0, 1 },
+                               .utmi_hstdet    = { 0xe2ac, 23, 23, 0, 1 }
+                       }
+               },
+       },
+       {
+               .reg            = 0xe460,
+               .port_cfgs      = {
+                       [USB2PHY_PORT_OTG] = {
+                               .phy_sus        = { 0xe464, 1, 0, 2, 1 },
+                               .bvalid_det_en  = { 0xe3c0, 8, 8, 0, 1 },
+                               .bvalid_det_st  = { 0xe3e0, 8, 8, 0, 1 },
+                               .bvalid_det_clr = { 0xe3d0, 8, 8, 0, 1 },
+                               .utmi_avalid    = { 0xe2ac, 10, 10, 0, 1 },
+                               .utmi_bvalid    = { 0xe2ac, 16, 16, 0, 1 },
+                       },
+                       [USB2PHY_PORT_HOST] = {
+                               .phy_sus        = { 0xe468, 1, 0, 0x2, 0x1 },
+                               .ls_det_en      = { 0xe3c0, 11, 11, 0, 1 },
+                               .ls_det_st      = { 0xe3e0, 11, 11, 0, 1 },
+                               .ls_det_clr     = { 0xe3d0, 11, 11, 0, 1 },
+                               .utmi_ls        = { 0xe2ac, 26, 25, 0, 1 },
+                               .utmi_hstdet    = { 0xe2ac, 27, 27, 0, 1 }
+                       }
+               },
+       },
+       { /* sentinel */ }
+};
+
+static const struct udevice_id rockchip_usb2phy_ids[] = {
+       {
+               .compatible = "rockchip,rk3399-usb2phy",
+               .data = (ulong)&rk3399_usb2phy_cfgs,
+       },
+       { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(rockchip_usb2phy_port) = {
+       .name           = "rockchip_usb2phy_port",
+       .id             = UCLASS_PHY,
+       .ops            = &rockchip_usb2phy_ops,
+};
+
+U_BOOT_DRIVER(rockchip_usb2phy) = {
+       .name   = "rockchip_usb2phy",
+       .id     = UCLASS_PHY,
+       .of_match = rockchip_usb2phy_ids,
+       .probe = rockchip_usb2phy_probe,
+       .bind = rockchip_usb2phy_bind,
+       .priv_auto_alloc_size = sizeof(struct rockchip_usb2phy),
+};
diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
new file mode 100644 (file)
index 0000000..c9c8e1c
--- /dev/null
@@ -0,0 +1,796 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * ROCKCHIP Type-C PHY driver.
+ *
+ * Copyright (C) 2020 Amarula Solutions(India)
+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
+ * Author: Chris Zhong <zyw@rock-chips.com>
+ *         Kever Yang <kever.yang@rock-chips.com>
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <dm/lists.h>
+#include <generic-phy.h>
+#include <reset.h>
+#include <syscon.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <linux/iopoll.h>
+#include <asm/arch-rockchip/clock.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define usleep_range(a, b) udelay((b))
+
+#define CMN_SSM_BANDGAP                        (0x21 << 2)
+#define CMN_SSM_BIAS                   (0x22 << 2)
+#define CMN_PLLSM0_PLLEN               (0x29 << 2)
+#define CMN_PLLSM0_PLLPRE              (0x2a << 2)
+#define CMN_PLLSM0_PLLVREF             (0x2b << 2)
+#define CMN_PLLSM0_PLLLOCK             (0x2c << 2)
+#define CMN_PLLSM1_PLLEN               (0x31 << 2)
+#define CMN_PLLSM1_PLLPRE              (0x32 << 2)
+#define CMN_PLLSM1_PLLVREF             (0x33 << 2)
+#define CMN_PLLSM1_PLLLOCK             (0x34 << 2)
+#define CMN_PLLSM1_USER_DEF_CTRL       (0x37 << 2)
+#define CMN_ICAL_OVRD                  (0xc1 << 2)
+#define CMN_PLL0_VCOCAL_OVRD           (0x83 << 2)
+#define CMN_PLL0_VCOCAL_INIT           (0x84 << 2)
+#define CMN_PLL0_VCOCAL_ITER           (0x85 << 2)
+#define CMN_PLL0_LOCK_REFCNT_START     (0x90 << 2)
+#define CMN_PLL0_LOCK_PLLCNT_START     (0x92 << 2)
+#define CMN_PLL0_LOCK_PLLCNT_THR       (0x93 << 2)
+#define CMN_PLL0_INTDIV                        (0x94 << 2)
+#define CMN_PLL0_FRACDIV               (0x95 << 2)
+#define CMN_PLL0_HIGH_THR              (0x96 << 2)
+#define CMN_PLL0_DSM_DIAG              (0x97 << 2)
+#define CMN_PLL0_SS_CTRL1              (0x98 << 2)
+#define CMN_PLL0_SS_CTRL2              (0x99 << 2)
+#define CMN_PLL1_VCOCAL_START          (0xa1 << 2)
+#define CMN_PLL1_VCOCAL_OVRD           (0xa3 << 2)
+#define CMN_PLL1_VCOCAL_INIT           (0xa4 << 2)
+#define CMN_PLL1_VCOCAL_ITER           (0xa5 << 2)
+#define CMN_PLL1_LOCK_REFCNT_START     (0xb0 << 2)
+#define CMN_PLL1_LOCK_PLLCNT_START     (0xb2 << 2)
+#define CMN_PLL1_LOCK_PLLCNT_THR       (0xb3 << 2)
+#define CMN_PLL1_INTDIV                        (0xb4 << 2)
+#define CMN_PLL1_FRACDIV               (0xb5 << 2)
+#define CMN_PLL1_HIGH_THR              (0xb6 << 2)
+#define CMN_PLL1_DSM_DIAG              (0xb7 << 2)
+#define CMN_PLL1_SS_CTRL1              (0xb8 << 2)
+#define CMN_PLL1_SS_CTRL2              (0xb9 << 2)
+#define CMN_RXCAL_OVRD                 (0xd1 << 2)
+
+#define CMN_TXPUCAL_CTRL               (0xe0 << 2)
+#define CMN_TXPUCAL_OVRD               (0xe1 << 2)
+#define CMN_TXPDCAL_CTRL               (0xf0 << 2)
+#define CMN_TXPDCAL_OVRD               (0xf1 << 2)
+
+/* For CMN_TXPUCAL_CTRL, CMN_TXPDCAL_CTRL */
+#define CMN_TXPXCAL_START              BIT(15)
+#define CMN_TXPXCAL_DONE               BIT(14)
+#define CMN_TXPXCAL_NO_RESPONSE                BIT(13)
+#define CMN_TXPXCAL_CURRENT_RESPONSE   BIT(12)
+
+#define CMN_TXPU_ADJ_CTRL              (0x108 << 2)
+#define CMN_TXPD_ADJ_CTRL              (0x10c << 2)
+
+/*
+ * For CMN_TXPUCAL_CTRL, CMN_TXPDCAL_CTRL,
+ *     CMN_TXPU_ADJ_CTRL, CMN_TXPDCAL_CTRL
+ *
+ * NOTE: some of these registers are documented to be 2's complement
+ * signed numbers, but then documented to be always positive.  Weird.
+ * In such a case, using CMN_CALIB_CODE_POS() avoids the unnecessary
+ * sign extension.
+ */
+#define CMN_CALIB_CODE_WIDTH   7
+#define CMN_CALIB_CODE_OFFSET  0
+#define CMN_CALIB_CODE_MASK    GENMASK(CMN_CALIB_CODE_WIDTH, 0)
+#define CMN_CALIB_CODE(x)      \
+       sign_extend32((x) >> CMN_CALIB_CODE_OFFSET, CMN_CALIB_CODE_WIDTH)
+
+#define CMN_CALIB_CODE_POS_MASK        GENMASK(CMN_CALIB_CODE_WIDTH - 1, 0)
+#define CMN_CALIB_CODE_POS(x)  \
+       (((x) >> CMN_CALIB_CODE_OFFSET) & CMN_CALIB_CODE_POS_MASK)
+
+#define CMN_DIAG_PLL0_FBH_OVRD         (0x1c0 << 2)
+#define CMN_DIAG_PLL0_FBL_OVRD         (0x1c1 << 2)
+#define CMN_DIAG_PLL0_OVRD             (0x1c2 << 2)
+#define CMN_DIAG_PLL0_V2I_TUNE         (0x1c5 << 2)
+#define CMN_DIAG_PLL0_CP_TUNE          (0x1c6 << 2)
+#define CMN_DIAG_PLL0_LF_PROG          (0x1c7 << 2)
+#define CMN_DIAG_PLL1_FBH_OVRD         (0x1d0 << 2)
+#define CMN_DIAG_PLL1_FBL_OVRD         (0x1d1 << 2)
+#define CMN_DIAG_PLL1_OVRD             (0x1d2 << 2)
+#define CMN_DIAG_PLL1_V2I_TUNE         (0x1d5 << 2)
+#define CMN_DIAG_PLL1_CP_TUNE          (0x1d6 << 2)
+#define CMN_DIAG_PLL1_LF_PROG          (0x1d7 << 2)
+#define CMN_DIAG_PLL1_PTATIS_TUNE1     (0x1d8 << 2)
+#define CMN_DIAG_PLL1_PTATIS_TUNE2     (0x1d9 << 2)
+#define CMN_DIAG_PLL1_INCLK_CTRL       (0x1da << 2)
+#define CMN_DIAG_HSCLK_SEL             (0x1e0 << 2)
+
+#define XCVR_PSM_RCTRL(n)              ((0x4001 | ((n) << 9)) << 2)
+#define XCVR_PSM_CAL_TMR(n)            ((0x4002 | ((n) << 9)) << 2)
+#define XCVR_PSM_A0IN_TMR(n)           ((0x4003 | ((n) << 9)) << 2)
+#define TX_TXCC_CAL_SCLR_MULT(n)       ((0x4047 | ((n) << 9)) << 2)
+#define TX_TXCC_CPOST_MULT_00(n)       ((0x404c | ((n) << 9)) << 2)
+#define TX_TXCC_CPOST_MULT_01(n)       ((0x404d | ((n) << 9)) << 2)
+#define TX_TXCC_CPOST_MULT_10(n)       ((0x404e | ((n) << 9)) << 2)
+#define TX_TXCC_CPOST_MULT_11(n)       ((0x404f | ((n) << 9)) << 2)
+#define TX_TXCC_MGNFS_MULT_000(n)      ((0x4050 | ((n) << 9)) << 2)
+#define TX_TXCC_MGNFS_MULT_001(n)      ((0x4051 | ((n) << 9)) << 2)
+#define TX_TXCC_MGNFS_MULT_010(n)      ((0x4052 | ((n) << 9)) << 2)
+#define TX_TXCC_MGNFS_MULT_011(n)      ((0x4053 | ((n) << 9)) << 2)
+#define TX_TXCC_MGNFS_MULT_100(n)      ((0x4054 | ((n) << 9)) << 2)
+#define TX_TXCC_MGNFS_MULT_101(n)      ((0x4055 | ((n) << 9)) << 2)
+#define TX_TXCC_MGNFS_MULT_110(n)      ((0x4056 | ((n) << 9)) << 2)
+#define TX_TXCC_MGNFS_MULT_111(n)      ((0x4057 | ((n) << 9)) << 2)
+#define TX_TXCC_MGNLS_MULT_000(n)      ((0x4058 | ((n) << 9)) << 2)
+#define TX_TXCC_MGNLS_MULT_001(n)      ((0x4059 | ((n) << 9)) << 2)
+#define TX_TXCC_MGNLS_MULT_010(n)      ((0x405a | ((n) << 9)) << 2)
+#define TX_TXCC_MGNLS_MULT_011(n)      ((0x405b | ((n) << 9)) << 2)
+#define TX_TXCC_MGNLS_MULT_100(n)      ((0x405c | ((n) << 9)) << 2)
+#define TX_TXCC_MGNLS_MULT_101(n)      ((0x405d | ((n) << 9)) << 2)
+#define TX_TXCC_MGNLS_MULT_110(n)      ((0x405e | ((n) << 9)) << 2)
+#define TX_TXCC_MGNLS_MULT_111(n)      ((0x405f | ((n) << 9)) << 2)
+
+#define XCVR_DIAG_PLLDRC_CTRL(n)       ((0x40e0 | ((n) << 9)) << 2)
+#define XCVR_DIAG_BIDI_CTRL(n)         ((0x40e8 | ((n) << 9)) << 2)
+#define XCVR_DIAG_LANE_FCM_EN_MGN(n)   ((0x40f2 | ((n) << 9)) << 2)
+#define TX_PSC_A0(n)                   ((0x4100 | ((n) << 9)) << 2)
+#define TX_PSC_A1(n)                   ((0x4101 | ((n) << 9)) << 2)
+#define TX_PSC_A2(n)                   ((0x4102 | ((n) << 9)) << 2)
+#define TX_PSC_A3(n)                   ((0x4103 | ((n) << 9)) << 2)
+#define TX_RCVDET_CTRL(n)              ((0x4120 | ((n) << 9)) << 2)
+#define TX_RCVDET_EN_TMR(n)            ((0x4122 | ((n) << 9)) << 2)
+#define TX_RCVDET_ST_TMR(n)            ((0x4123 | ((n) << 9)) << 2)
+#define TX_DIAG_TX_DRV(n)              ((0x41e1 | ((n) << 9)) << 2)
+#define TX_DIAG_BGREF_PREDRV_DELAY     (0x41e7 << 2)
+
+/* Use this for "n" in macros like "_MULT_XXX" to target the aux channel */
+#define AUX_CH_LANE                    8
+
+#define TX_ANA_CTRL_REG_1              (0x5020 << 2)
+
+#define TXDA_DP_AUX_EN                 BIT(15)
+#define AUXDA_SE_EN                    BIT(14)
+#define TXDA_CAL_LATCH_EN              BIT(13)
+#define AUXDA_POLARITY                 BIT(12)
+#define TXDA_DRV_POWER_ISOLATION_EN    BIT(11)
+#define TXDA_DRV_POWER_EN_PH_2_N       BIT(10)
+#define TXDA_DRV_POWER_EN_PH_1_N       BIT(9)
+#define TXDA_BGREF_EN                  BIT(8)
+#define TXDA_DRV_LDO_EN                        BIT(7)
+#define TXDA_DECAP_EN_DEL              BIT(6)
+#define TXDA_DECAP_EN                  BIT(5)
+#define TXDA_UPHY_SUPPLY_EN_DEL                BIT(4)
+#define TXDA_UPHY_SUPPLY_EN            BIT(3)
+#define TXDA_LOW_LEAKAGE_EN            BIT(2)
+#define TXDA_DRV_IDLE_LOWI_EN          BIT(1)
+#define TXDA_DRV_CMN_MODE_EN           BIT(0)
+
+#define TX_ANA_CTRL_REG_2              (0x5021 << 2)
+
+#define AUXDA_DEBOUNCING_CLK           BIT(15)
+#define TXDA_LPBK_RECOVERED_CLK_EN     BIT(14)
+#define TXDA_LPBK_ISI_GEN_EN           BIT(13)
+#define TXDA_LPBK_SERIAL_EN            BIT(12)
+#define TXDA_LPBK_LINE_EN              BIT(11)
+#define TXDA_DRV_LDO_REDC_SINKIQ       BIT(10)
+#define XCVR_DECAP_EN_DEL              BIT(9)
+#define XCVR_DECAP_EN                  BIT(8)
+#define TXDA_MPHY_ENABLE_HS_NT         BIT(7)
+#define TXDA_MPHY_SA_MODE              BIT(6)
+#define TXDA_DRV_LDO_RBYR_FB_EN                BIT(5)
+#define TXDA_DRV_RST_PULL_DOWN         BIT(4)
+#define TXDA_DRV_LDO_BG_FB_EN          BIT(3)
+#define TXDA_DRV_LDO_BG_REF_EN         BIT(2)
+#define TXDA_DRV_PREDRV_EN_DEL         BIT(1)
+#define TXDA_DRV_PREDRV_EN             BIT(0)
+
+#define TXDA_COEFF_CALC_CTRL           (0x5022 << 2)
+
+#define TX_HIGH_Z                      BIT(6)
+#define TX_VMARGIN_OFFSET              3
+#define TX_VMARGIN_MASK                        0x7
+#define LOW_POWER_SWING_EN             BIT(2)
+#define TX_FCM_DRV_MAIN_EN             BIT(1)
+#define TX_FCM_FULL_MARGIN             BIT(0)
+
+#define TX_DIG_CTRL_REG_2              (0x5024 << 2)
+
+#define TX_HIGH_Z_TM_EN                        BIT(15)
+#define TX_RESCAL_CODE_OFFSET          0
+#define TX_RESCAL_CODE_MASK            0x3f
+
+#define TXDA_CYA_AUXDA_CYA             (0x5025 << 2)
+#define TX_ANA_CTRL_REG_3              (0x5026 << 2)
+#define TX_ANA_CTRL_REG_4              (0x5027 << 2)
+#define TX_ANA_CTRL_REG_5              (0x5029 << 2)
+
+#define RX_PSC_A0(n)                   ((0x8000 | ((n) << 9)) << 2)
+#define RX_PSC_A1(n)                   ((0x8001 | ((n) << 9)) << 2)
+#define RX_PSC_A2(n)                   ((0x8002 | ((n) << 9)) << 2)
+#define RX_PSC_A3(n)                   ((0x8003 | ((n) << 9)) << 2)
+#define RX_PSC_CAL(n)                  ((0x8006 | ((n) << 9)) << 2)
+#define RX_PSC_RDY(n)                  ((0x8007 | ((n) << 9)) << 2)
+#define RX_IQPI_ILL_CAL_OVRD           (0x8023 << 2)
+#define RX_EPI_ILL_CAL_OVRD            (0x8033 << 2)
+#define RX_SDCAL0_OVRD                 (0x8041 << 2)
+#define RX_SDCAL1_OVRD                 (0x8049 << 2)
+#define RX_SLC_INIT                    (0x806d << 2)
+#define RX_SLC_RUN                     (0x806e << 2)
+#define RX_CDRLF_CNFG2                 (0x8081 << 2)
+#define RX_SIGDET_HL_FILT_TMR(n)       ((0x8090 | ((n) << 9)) << 2)
+#define RX_SLC_IOP0_OVRD               (0x8101 << 2)
+#define RX_SLC_IOP1_OVRD               (0x8105 << 2)
+#define RX_SLC_QOP0_OVRD               (0x8109 << 2)
+#define RX_SLC_QOP1_OVRD               (0x810d << 2)
+#define RX_SLC_EOP0_OVRD               (0x8111 << 2)
+#define RX_SLC_EOP1_OVRD               (0x8115 << 2)
+#define RX_SLC_ION0_OVRD               (0x8119 << 2)
+#define RX_SLC_ION1_OVRD               (0x811d << 2)
+#define RX_SLC_QON0_OVRD               (0x8121 << 2)
+#define RX_SLC_QON1_OVRD               (0x8125 << 2)
+#define RX_SLC_EON0_OVRD               (0x8129 << 2)
+#define RX_SLC_EON1_OVRD               (0x812d << 2)
+#define RX_SLC_IEP0_OVRD               (0x8131 << 2)
+#define RX_SLC_IEP1_OVRD               (0x8135 << 2)
+#define RX_SLC_QEP0_OVRD               (0x8139 << 2)
+#define RX_SLC_QEP1_OVRD               (0x813d << 2)
+#define RX_SLC_EEP0_OVRD               (0x8141 << 2)
+#define RX_SLC_EEP1_OVRD               (0x8145 << 2)
+#define RX_SLC_IEN0_OVRD               (0x8149 << 2)
+#define RX_SLC_IEN1_OVRD               (0x814d << 2)
+#define RX_SLC_QEN0_OVRD               (0x8151 << 2)
+#define RX_SLC_QEN1_OVRD               (0x8155 << 2)
+#define RX_SLC_EEN0_OVRD               (0x8159 << 2)
+#define RX_SLC_EEN1_OVRD               (0x815d << 2)
+#define RX_REE_CTRL_DATA_MASK(n)       ((0x81bb | ((n) << 9)) << 2)
+#define RX_DIAG_SIGDET_TUNE(n)         ((0x81dc | ((n) << 9)) << 2)
+#define RX_DIAG_SC2C_DELAY             (0x81e1 << 2)
+
+#define PMA_LANE_CFG                   (0xc000 << 2)
+#define PIPE_CMN_CTRL1                 (0xc001 << 2)
+#define PIPE_CMN_CTRL2                 (0xc002 << 2)
+#define PIPE_COM_LOCK_CFG1             (0xc003 << 2)
+#define PIPE_COM_LOCK_CFG2             (0xc004 << 2)
+#define PIPE_RCV_DET_INH               (0xc005 << 2)
+#define DP_MODE_CTL                    (0xc008 << 2)
+#define DP_CLK_CTL                     (0xc009 << 2)
+#define STS                            (0xc00F << 2)
+#define PHY_ISO_CMN_CTRL               (0xc010 << 2)
+#define PHY_DP_TX_CTL                  (0xc408 << 2)
+#define PMA_CMN_CTRL1                  (0xc800 << 2)
+#define PHY_PMA_ISO_CMN_CTRL           (0xc810 << 2)
+#define PHY_ISOLATION_CTRL             (0xc81f << 2)
+#define PHY_PMA_ISO_XCVR_CTRL(n)       ((0xcc11 | ((n) << 6)) << 2)
+#define PHY_PMA_ISO_LINK_MODE(n)       ((0xcc12 | ((n) << 6)) << 2)
+#define PHY_PMA_ISO_PWRST_CTRL(n)      ((0xcc13 | ((n) << 6)) << 2)
+#define PHY_PMA_ISO_TX_DATA_LO(n)      ((0xcc14 | ((n) << 6)) << 2)
+#define PHY_PMA_ISO_TX_DATA_HI(n)      ((0xcc15 | ((n) << 6)) << 2)
+#define PHY_PMA_ISO_RX_DATA_LO(n)      ((0xcc16 | ((n) << 6)) << 2)
+#define PHY_PMA_ISO_RX_DATA_HI(n)      ((0xcc17 | ((n) << 6)) << 2)
+#define TX_BIST_CTRL(n)                        ((0x4140 | ((n) << 9)) << 2)
+#define TX_BIST_UDDWR(n)               ((0x4141 | ((n) << 9)) << 2)
+
+/*
+ * Selects which PLL clock will be driven on the analog high speed
+ * clock 0: PLL 0 div 1
+ * clock 1: PLL 1 div 2
+ */
+#define CLK_PLL_CONFIG                 0X30
+#define CLK_PLL_MASK                   0x33
+
+#define CMN_READY                      BIT(0)
+
+#define DP_PLL_CLOCK_ENABLE            BIT(2)
+#define DP_PLL_ENABLE                  BIT(0)
+#define DP_PLL_DATA_RATE_RBR           ((2 << 12) | (4 << 8))
+#define DP_PLL_DATA_RATE_HBR           ((2 << 12) | (4 << 8))
+#define DP_PLL_DATA_RATE_HBR2          ((1 << 12) | (2 << 8))
+
+#define DP_MODE_A0                     BIT(4)
+#define DP_MODE_A2                     BIT(6)
+#define DP_MODE_ENTER_A0               0xc101
+#define DP_MODE_ENTER_A2               0xc104
+
+#define PHY_MODE_SET_TIMEOUT           100000
+
+#define PIN_ASSIGN_C_E                 0x51d9
+#define PIN_ASSIGN_D_F                 0x5100
+
+#define MODE_DISCONNECT                        0
+#define MODE_UFP_USB                   BIT(0)
+#define MODE_DFP_USB                   BIT(1)
+#define MODE_DFP_DP                    BIT(2)
+
+struct usb3phy_reg {
+       u32 offset;
+       u32 enable_bit;
+       u32 write_enable;
+};
+
+/**
+ * struct rockchip_usb3phy_port_cfg: usb3-phy port configuration.
+ * @reg: the base address for usb3-phy config.
+ * @typec_conn_dir: the register of type-c connector direction.
+ * @usb3tousb2_en: the register of type-c force usb2 to usb2 enable.
+ * @external_psm: the register of type-c phy external psm clock.
+ * @pipe_status: the register of type-c phy pipe status.
+ * @usb3_host_disable: the register of type-c usb3 host disable.
+ * @usb3_host_port: the register of type-c usb3 host port.
+ * @uphy_dp_sel: the register of type-c phy DP select control.
+ */
+struct rockchip_usb3phy_port_cfg {
+       unsigned int reg;
+       struct usb3phy_reg typec_conn_dir;
+       struct usb3phy_reg usb3tousb2_en;
+       struct usb3phy_reg external_psm;
+       struct usb3phy_reg pipe_status;
+       struct usb3phy_reg usb3_host_disable;
+       struct usb3phy_reg usb3_host_port;
+       struct usb3phy_reg uphy_dp_sel;
+};
+
+struct rockchip_tcphy {
+       void __iomem *reg_base;
+       void __iomem *grf_base;
+       struct clk clk_core;
+       struct clk clk_ref;
+       struct reset_ctl uphy_rst;
+       struct reset_ctl pipe_rst;
+       struct reset_ctl tcphy_rst;
+       const struct rockchip_usb3phy_port_cfg *port_cfgs;
+       u8 mode;
+};
+
+struct phy_reg {
+       u16 value;
+       u32 addr;
+};
+
+static struct phy_reg usb3_pll_cfg[] = {
+       { 0xf0,         CMN_PLL0_VCOCAL_INIT },
+       { 0x18,         CMN_PLL0_VCOCAL_ITER },
+       { 0xd0,         CMN_PLL0_INTDIV },
+       { 0x4a4a,       CMN_PLL0_FRACDIV },
+       { 0x34,         CMN_PLL0_HIGH_THR },
+       { 0x1ee,        CMN_PLL0_SS_CTRL1 },
+       { 0x7f03,       CMN_PLL0_SS_CTRL2 },
+       { 0x20,         CMN_PLL0_DSM_DIAG },
+       { 0,            CMN_DIAG_PLL0_OVRD },
+       { 0,            CMN_DIAG_PLL0_FBH_OVRD },
+       { 0,            CMN_DIAG_PLL0_FBL_OVRD },
+       { 0x7,          CMN_DIAG_PLL0_V2I_TUNE },
+       { 0x45,         CMN_DIAG_PLL0_CP_TUNE },
+       { 0x8,          CMN_DIAG_PLL0_LF_PROG },
+};
+
+static inline int property_enable(struct rockchip_tcphy *priv,
+                                 const struct usb3phy_reg *reg, bool en)
+{
+       u32 mask = 1 << reg->write_enable;
+       u32 val = en << reg->enable_bit;
+
+       return writel(val | mask, priv->grf_base + reg->offset);
+}
+
+static int rockchip_tcphy_get_mode(struct rockchip_tcphy *priv)
+{
+       /* TODO: Add proper logic to find DP or USB3 mode */
+       return MODE_DFP_USB | MODE_UFP_USB;
+}
+
+static void rockchip_tcphy_cfg_24m(struct rockchip_tcphy *priv)
+{
+       u32 i, rdata;
+
+       /*
+        * cmn_ref_clk_sel = 3, select the 24Mhz for clk parent
+        * cmn_psm_clk_dig_div = 2, set the clk division to 2
+        */
+       writel(0x830, priv->reg_base + PMA_CMN_CTRL1);
+       for (i = 0; i < 4; i++) {
+               /*
+                * The following PHY configuration assumes a 24 MHz reference
+                * clock.
+                */
+               writel(0x90, priv->reg_base + XCVR_DIAG_LANE_FCM_EN_MGN(i));
+               writel(0x960, priv->reg_base + TX_RCVDET_EN_TMR(i));
+               writel(0x30, priv->reg_base + TX_RCVDET_ST_TMR(i));
+       }
+
+       rdata = readl(priv->reg_base + CMN_DIAG_HSCLK_SEL);
+       rdata &= ~CLK_PLL_MASK;
+       rdata |= CLK_PLL_CONFIG;
+       writel(rdata, priv->reg_base + CMN_DIAG_HSCLK_SEL);
+}
+
+static void rockchip_tcphy_cfg_usb3_pll(struct rockchip_tcphy *priv)
+{
+       u32 i;
+
+       /* load the configuration of PLL0 */
+       for (i = 0; i < ARRAY_SIZE(usb3_pll_cfg); i++)
+               writel(usb3_pll_cfg[i].value,
+                      priv->reg_base + usb3_pll_cfg[i].addr);
+}
+
+static void rockchip_tcphy_tx_usb3_cfg_lane(struct rockchip_tcphy *priv,
+                                           u32 lane)
+{
+       writel(0x7799, priv->reg_base + TX_PSC_A0(lane));
+       writel(0x7798, priv->reg_base + TX_PSC_A1(lane));
+       writel(0x5098, priv->reg_base + TX_PSC_A2(lane));
+       writel(0x5098, priv->reg_base + TX_PSC_A3(lane));
+       writel(0, priv->reg_base + TX_TXCC_MGNFS_MULT_000(lane));
+       writel(0xbf, priv->reg_base + XCVR_DIAG_BIDI_CTRL(lane));
+}
+
+static void rockchip_tcphy_rx_usb3_cfg_lane(struct rockchip_tcphy *priv,
+                                           u32 lane)
+{
+       writel(0xa6fd, priv->reg_base + RX_PSC_A0(lane));
+       writel(0xa6fd, priv->reg_base + RX_PSC_A1(lane));
+       writel(0xa410, priv->reg_base + RX_PSC_A2(lane));
+       writel(0x2410, priv->reg_base + RX_PSC_A3(lane));
+       writel(0x23ff, priv->reg_base + RX_PSC_CAL(lane));
+       writel(0x13, priv->reg_base + RX_SIGDET_HL_FILT_TMR(lane));
+       writel(0x03e7, priv->reg_base + RX_REE_CTRL_DATA_MASK(lane));
+       writel(0x1004, priv->reg_base + RX_DIAG_SIGDET_TUNE(lane));
+       writel(0x2010, priv->reg_base + RX_PSC_RDY(lane));
+       writel(0xfb, priv->reg_base + XCVR_DIAG_BIDI_CTRL(lane));
+}
+
+static int rockchip_tcphy_init(struct rockchip_tcphy *priv)
+{
+       const struct rockchip_usb3phy_port_cfg *cfg = priv->port_cfgs;
+       u32 val;
+       int ret;
+
+       ret = clk_enable(&priv->clk_core);
+       if (ret) {
+               dev_err(phy->dev, "failed to enable core clk (ret=%d)\n", ret);
+               return ret;
+       }
+
+       ret = clk_enable(&priv->clk_ref);
+       if (ret) {
+               dev_err(phy->dev, "failed to enable ref clk (ret=%d)\n", ret);
+               goto err_clk_core;
+       }
+
+       ret = reset_deassert(&priv->tcphy_rst);
+       if (ret) {
+               dev_err(phy->dev, "failed to deassert uphy-tcphy reset (ret=%d)\n",
+                       ret);
+               goto err_clk_ref;
+       }
+
+       property_enable(priv, &cfg->typec_conn_dir, 0);
+
+       rockchip_tcphy_cfg_24m(priv);
+
+       rockchip_tcphy_cfg_usb3_pll(priv);
+
+       rockchip_tcphy_tx_usb3_cfg_lane(priv, 0);
+       rockchip_tcphy_rx_usb3_cfg_lane(priv, 1);
+
+       ret = reset_deassert(&priv->uphy_rst);
+       if (ret) {
+               dev_err(phy->dev, "failed to deassert uphy rst (ret=%d)\n",
+                       ret);
+               goto err_tcphy_rst;
+       }
+
+       ret = readl_poll_sleep_timeout(priv->reg_base + PMA_CMN_CTRL1,
+                                      val, val & CMN_READY, 10,
+                                      PHY_MODE_SET_TIMEOUT);
+       if (ret < 0) {
+               dev_err(phy->dev, "PMA Timeout!\n");
+               ret = -ETIMEDOUT;
+               goto err_uphy_rst;
+       }
+
+       ret = reset_deassert(&priv->pipe_rst);
+       if (ret) {
+               dev_err(phy->dev, "failed to deassert pipe rst (ret=%d)\n",
+                       ret);
+               goto err_uphy_rst;
+       }
+
+       return 0;
+
+err_uphy_rst:
+       reset_assert(&priv->uphy_rst);
+err_tcphy_rst:
+       reset_assert(&priv->tcphy_rst);
+err_clk_ref:
+       clk_disable(&priv->clk_ref);
+err_clk_core:
+       clk_disable(&priv->clk_core);
+       return ret;
+}
+
+static void rockchip_tcphy_exit(struct rockchip_tcphy *priv)
+{
+       reset_assert(&priv->tcphy_rst);
+       reset_assert(&priv->uphy_rst);
+       reset_assert(&priv->pipe_rst);
+       clk_disable(&priv->clk_core);
+       clk_disable(&priv->clk_ref);
+}
+
+static int tcphy_cfg_usb3_to_usb2_only(struct rockchip_tcphy *priv,
+                                      bool value)
+{
+       const struct rockchip_usb3phy_port_cfg *cfg = priv->port_cfgs;
+
+       property_enable(priv, &cfg->usb3tousb2_en, value);
+       property_enable(priv, &cfg->usb3_host_disable, value);
+       property_enable(priv, &cfg->usb3_host_port, !value);
+
+       return 0;
+}
+
+static int rockchip_usb3_phy_power_on(struct phy *phy)
+{
+       struct udevice *parent = dev_get_parent(phy->dev);
+       struct rockchip_tcphy *priv = dev_get_priv(parent);
+       const struct rockchip_usb3phy_port_cfg *cfg = priv->port_cfgs;
+       const struct usb3phy_reg *reg = &cfg->pipe_status;
+       int timeout, new_mode;
+       u32 val;
+       int ret;
+
+       new_mode = rockchip_tcphy_get_mode(priv);
+       if (new_mode < 0) {
+               dev_err(phy->dev, "invalid mode %d\n", new_mode);
+               return new_mode;
+       }
+
+       if (priv->mode == new_mode)
+               return 0;
+
+       if (priv->mode == MODE_DISCONNECT) {
+               ret = rockchip_tcphy_init(priv);
+               if (ret) {
+                       dev_err(dev, "failed to init tcphy (ret=%d)\n", ret);
+                       return ret;
+               }
+       }
+
+       /* wait TCPHY for pipe ready */
+       for (timeout = 0; timeout < 100; timeout++) {
+               val = readl(priv->grf_base + reg->offset);
+               if (!(val & BIT(reg->enable_bit))) {
+                       priv->mode |= new_mode & (MODE_DFP_USB | MODE_UFP_USB);
+
+                       /* enable usb3 host */
+                       tcphy_cfg_usb3_to_usb2_only(priv, false);
+                       return 0;
+               }
+               usleep_range(10, 20);
+       }
+
+       if (priv->mode == MODE_DISCONNECT)
+               rockchip_tcphy_exit(priv);
+
+       return -ETIMEDOUT;
+}
+
+static int rockchip_usb3_phy_power_off(struct phy *phy)
+{
+       struct udevice *parent = dev_get_parent(phy->dev);
+       struct rockchip_tcphy *priv = dev_get_priv(parent);
+
+       tcphy_cfg_usb3_to_usb2_only(priv, false);
+
+       if (priv->mode == MODE_DISCONNECT)
+               goto exit;
+
+       priv->mode &= ~(MODE_UFP_USB | MODE_DFP_USB);
+       if (priv->mode == MODE_DISCONNECT)
+               rockchip_tcphy_exit(priv);
+
+exit:
+       return 0;
+}
+
+static struct phy_ops rockchip_tcphy_usb3_ops = {
+       .power_on = rockchip_usb3_phy_power_on,
+       .power_off = rockchip_usb3_phy_power_off,
+};
+
+static void rockchip_tcphy_pre_init(struct udevice *dev)
+{
+       struct rockchip_tcphy *priv = dev_get_priv(dev);
+       const struct rockchip_usb3phy_port_cfg *cfg = priv->port_cfgs;
+
+       reset_assert(&priv->tcphy_rst);
+       reset_assert(&priv->uphy_rst);
+       reset_assert(&priv->pipe_rst);
+
+       /* select external psm clock */
+       property_enable(priv, &cfg->external_psm, 1);
+       property_enable(priv, &cfg->usb3tousb2_en, 0);
+
+       priv->mode = MODE_DISCONNECT;
+}
+
+static int rockchip_tcphy_parse_dt(struct udevice *dev)
+{
+       struct rockchip_tcphy *priv = dev_get_priv(dev);
+       int ret;
+
+       priv->grf_base = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
+       if (IS_ERR(priv->grf_base))
+               return PTR_ERR(priv->grf_base);
+
+       ret = clk_get_by_name(dev, "tcpdcore", &priv->clk_core);
+       if (ret) {
+               dev_err(dev, "failed to get tcpdcore clk (ret=%d)\n", ret);
+               return ret;
+       }
+
+       ret = clk_get_by_name(dev, "tcpdphy-ref", &priv->clk_ref);
+       if (ret) {
+               dev_err(dev, "failed to get tcpdphy-ref clk (ret=%d)\n", ret);
+               return ret;
+       }
+
+       ret = reset_get_by_name(dev, "uphy", &priv->uphy_rst);
+       if (ret) {
+               dev_err(dev, "failed to get uphy reset (ret=%d)\n", ret);
+               return ret;
+       }
+
+       ret = reset_get_by_name(dev, "uphy-pipe", &priv->pipe_rst);
+       if (ret) {
+               dev_err(dev, "failed to get uphy-pipe reset (ret=%d)\n", ret);
+               return ret;
+       }
+
+       ret = reset_get_by_name(dev, "uphy-tcphy", &priv->tcphy_rst);
+       if (ret) {
+               dev_err(dev, "failed to get uphy-tcphy reset (ret=%d)\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static int rockchip_tcphy_probe(struct udevice *dev)
+{
+       struct rockchip_tcphy *priv = dev_get_priv(dev);
+       const struct rockchip_usb3phy_port_cfg *phy_cfgs;
+       unsigned int reg;
+       int index, ret;
+
+       priv->reg_base = (void __iomem *)dev_read_addr(dev);
+       if (IS_ERR(priv->reg_base))
+               return PTR_ERR(priv->reg_base);
+
+       ret = dev_read_u32_index(dev, "reg", 1, &reg);
+       if (ret) {
+               dev_err(dev, "failed to read reg property (ret = %d)\n", ret);
+               return ret;
+       }
+
+       phy_cfgs = (const struct rockchip_usb3phy_port_cfg *)
+                                       dev_get_driver_data(dev);
+       if (!phy_cfgs)
+               return -EINVAL;
+
+       /* find out a proper config which can be matched with dt. */
+       index = 0;
+       while (phy_cfgs[index].reg) {
+               if (phy_cfgs[index].reg == reg) {
+                       priv->port_cfgs = &phy_cfgs[index];
+                       break;
+               }
+
+               ++index;
+       }
+
+       if (!priv->port_cfgs) {
+               dev_err(dev, "failed find proper phy-cfg\n");
+               return -EINVAL;
+       }
+
+       ret = rockchip_tcphy_parse_dt(dev);
+       if (ret)
+               return ret;
+
+       rockchip_tcphy_pre_init(dev);
+
+       return 0;
+}
+
+static int rockchip_tcphy_bind(struct udevice *dev)
+{
+       struct udevice *tcphy_dev;
+       ofnode node;
+       const char *name;
+       int ret = 0;
+
+       dev_for_each_subnode(node, dev) {
+               if (!ofnode_valid(node)) {
+                       dev_info(dev, "subnode %s not found\n", dev->name);
+                       return -ENXIO;
+               }
+
+               name = ofnode_get_name(node);
+               dev_dbg(dev, "subnode %s\n", name);
+
+               if (!strcasecmp(name, "dp-port")) {
+                       dev_dbg(dev, "Warning: dp-port not supported yet!\n");
+                       continue;
+               } else if (!strcasecmp(name, "usb3-port")) {
+                       ret = device_bind_driver_to_node(dev,
+                                                        "rockchip_tcphy_usb3_port",
+                                                        name, node, &tcphy_dev);
+                       if (ret) {
+                               dev_err(dev,
+                                       "'%s' cannot bind 'rockchip_tcphy_usb3_port'\n",
+                                       name);
+                               return ret;
+                       }
+               }
+       }
+
+       return ret;
+}
+
+static const struct rockchip_usb3phy_port_cfg rk3399_typec_phy_cfgs[] = {
+       {
+               .reg                    = 0xff7c0000,
+               .typec_conn_dir         = { 0xe580, 0, 16 },
+               .usb3tousb2_en          = { 0xe580, 3, 19 },
+               .external_psm           = { 0xe588, 14, 30 },
+               .pipe_status            = { 0xe5c0, 0, 0 },
+               .usb3_host_disable      = { 0x2434, 0, 16 },
+               .usb3_host_port         = { 0x2434, 12, 28 },
+               .uphy_dp_sel            = { 0x6268, 19, 19 },
+       },
+       {
+               .reg                    = 0xff800000,
+               .typec_conn_dir         = { 0xe58c, 0, 16 },
+               .usb3tousb2_en          = { 0xe58c, 3, 19 },
+               .external_psm           = { 0xe594, 14, 30 },
+               .pipe_status            = { 0xe5c0, 16, 16 },
+               .usb3_host_disable      = { 0x2444, 0, 16 },
+               .usb3_host_port         = { 0x2444, 12, 28 },
+               .uphy_dp_sel            = { 0x6268, 3, 19 },
+       },
+       { /* sentinel */ }
+};
+
+static const struct udevice_id rockchip_typec_phy_ids[] = {
+       {
+               .compatible = "rockchip,rk3399-typec-phy",
+               .data = (ulong)&rk3399_typec_phy_cfgs,
+       },
+       { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(rockchip_tcphy_usb3_port) = {
+       .name           = "rockchip_tcphy_usb3_port",
+       .id             = UCLASS_PHY,
+       .ops            = &rockchip_tcphy_usb3_ops,
+};
+
+U_BOOT_DRIVER(rockchip_typec_phy) = {
+       .name   = "rockchip_typec_phy",
+       .id     = UCLASS_PHY,
+       .of_match = rockchip_typec_phy_ids,
+       .probe = rockchip_tcphy_probe,
+       .bind = rockchip_tcphy_bind,
+       .priv_auto_alloc_size = sizeof(struct rockchip_tcphy),
+};
index 0db281b970ef6913694c778868a5428d59c08156..d4ae18693c600b3251a09dc3581c0d1ce752fc0b 100644 (file)
@@ -10,6 +10,7 @@
 #include <dm.h>
 #include <linux/usb/otg.h>
 #include <linux/usb/ch9.h>
+#include <linux/usb/phy.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -64,3 +65,27 @@ enum usb_device_speed usb_get_maximum_speed(ofnode node)
 
        return USB_SPEED_UNKNOWN;
 }
+
+#if CONFIG_IS_ENABLED(DM_USB)
+static const char *const usbphy_modes[] = {
+       [USBPHY_INTERFACE_MODE_UNKNOWN] = "",
+       [USBPHY_INTERFACE_MODE_UTMI]    = "utmi",
+       [USBPHY_INTERFACE_MODE_UTMIW]   = "utmi_wide",
+};
+
+enum usb_phy_interface usb_get_phy_mode(ofnode node)
+{
+       const char *phy_type;
+       int i;
+
+       phy_type = ofnode_get_property(node, "phy_type", NULL);
+       if (!phy_type)
+               return USBPHY_INTERFACE_MODE_UNKNOWN;
+
+       for (i = 0; i < ARRAY_SIZE(usbphy_modes); i++)
+               if (!strcmp(phy_type, usbphy_modes[i]))
+                       return i;
+
+       return USBPHY_INTERFACE_MODE_UNKNOWN;
+}
+#endif
index 8d418c9412bb78b6196489dee62adee7611b38f8..86825565895f50b7691fe4bf40c758d69fffe98a 100644 (file)
@@ -336,6 +336,34 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
        parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8);
 }
 
+static void dwc3_hsphy_mode_setup(struct dwc3 *dwc)
+{
+       enum usb_phy_interface hsphy_mode = dwc->hsphy_mode;
+       u32 reg;
+
+       /* Set dwc3 usb2 phy config */
+       reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+
+       switch (hsphy_mode) {
+       case USBPHY_INTERFACE_MODE_UTMI:
+               reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK |
+                       DWC3_GUSB2PHYCFG_USBTRDTIM_MASK);
+               reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_8_BIT) |
+                       DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_8_BIT);
+               break;
+       case USBPHY_INTERFACE_MODE_UTMIW:
+               reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK |
+                       DWC3_GUSB2PHYCFG_USBTRDTIM_MASK);
+               reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_16_BIT) |
+                       DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_16_BIT);
+               break;
+       default:
+               break;
+       }
+
+       dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+}
+
 /**
  * dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core
  * @dwc: Pointer to our controller context structure
@@ -384,6 +412,8 @@ static void dwc3_phy_setup(struct dwc3 *dwc)
 
        dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
 
+       dwc3_hsphy_mode_setup(dwc);
+
        mdelay(100);
 
        reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
@@ -400,6 +430,12 @@ static void dwc3_phy_setup(struct dwc3 *dwc)
        if (dwc->dis_u2_susphy_quirk)
                reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
 
+       if (dwc->dis_enblslpm_quirk)
+               reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
+
+       if (dwc->dis_u2_freeclk_exists_quirk)
+               reg &= ~DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS;
+
        dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
 
        mdelay(100);
@@ -622,35 +658,6 @@ static void dwc3_core_exit_mode(struct dwc3 *dwc)
        dwc3_gadget_run(dwc);
 }
 
-static void dwc3_uboot_hsphy_mode(struct dwc3_device *dwc3_dev,
-                                 struct dwc3 *dwc)
-{
-       enum usb_phy_interface hsphy_mode = dwc3_dev->hsphy_mode;
-       u32 reg;
-
-       /* Set dwc3 usb2 phy config */
-       reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
-
-       switch (hsphy_mode) {
-       case USBPHY_INTERFACE_MODE_UTMI:
-               reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK |
-                       DWC3_GUSB2PHYCFG_USBTRDTIM_MASK);
-               reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_8_BIT) |
-                       DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_8_BIT);
-               break;
-       case USBPHY_INTERFACE_MODE_UTMIW:
-               reg &= ~(DWC3_GUSB2PHYCFG_PHYIF_MASK |
-                       DWC3_GUSB2PHYCFG_USBTRDTIM_MASK);
-               reg |= DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_16_BIT) |
-                       DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_16_BIT);
-               break;
-       default:
-               break;
-       }
-
-       dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
-}
-
 #define DWC3_ALIGN_MASK                (16 - 1)
 
 /**
@@ -721,6 +728,9 @@ int dwc3_uboot_init(struct dwc3_device *dwc3_dev)
        dwc->dis_u3_susphy_quirk = dwc3_dev->dis_u3_susphy_quirk;
        dwc->dis_u2_susphy_quirk = dwc3_dev->dis_u2_susphy_quirk;
        dwc->dis_del_phy_power_chg_quirk = dwc3_dev->dis_del_phy_power_chg_quirk;
+       dwc->dis_tx_ipgap_linecheck_quirk = dwc3_dev->dis_tx_ipgap_linecheck_quirk;
+       dwc->dis_enblslpm_quirk = dwc3_dev->dis_enblslpm_quirk;
+       dwc->dis_u2_freeclk_exists_quirk = dwc3_dev->dis_u2_freeclk_exists_quirk;
 
        dwc->tx_de_emphasis_quirk = dwc3_dev->tx_de_emphasis_quirk;
        if (dwc3_dev->tx_de_emphasis)
@@ -736,6 +746,8 @@ int dwc3_uboot_init(struct dwc3_device *dwc3_dev)
        dwc->hird_threshold = hird_threshold
                | (dwc->is_utmi_l1_suspend << 4);
 
+       dwc->hsphy_mode = dwc3_dev->hsphy_mode;
+
        dwc->index = dwc3_dev->index;
 
        dwc3_cache_hwparams(dwc);
@@ -760,8 +772,6 @@ int dwc3_uboot_init(struct dwc3_device *dwc3_dev)
                goto err0;
        }
 
-       dwc3_uboot_hsphy_mode(dwc3_dev, dwc);
-
        ret = dwc3_event_buffers_setup(dwc);
        if (ret) {
                dev_err(dwc->dev, "failed to setup event buffers\n");
@@ -894,6 +904,8 @@ void dwc3_of_parse(struct dwc3 *dwc)
         */
        hird_threshold = 12;
 
+       dwc->hsphy_mode = usb_get_phy_mode(dev->node);
+
        dwc->has_lpm_erratum = dev_read_bool(dev,
                                "snps,has-lpm-erratum");
        tmp = dev_read_u8_array_ptr(dev, "snps,lpm-nyet-threshold", 1);
@@ -928,6 +940,12 @@ void dwc3_of_parse(struct dwc3 *dwc)
                                "snps,dis_u2_susphy_quirk");
        dwc->dis_del_phy_power_chg_quirk = dev_read_bool(dev,
                                "snps,dis-del-phy-power-chg-quirk");
+       dwc->dis_tx_ipgap_linecheck_quirk = dev_read_bool(dev,
+                               "snps,dis-tx-ipgap-linecheck-quirk");
+       dwc->dis_enblslpm_quirk = dev_read_bool(dev,
+                               "snps,dis_enblslpm_quirk");
+       dwc->dis_u2_freeclk_exists_quirk = dev_read_bool(dev,
+                               "snps,dis-u2-freeclk-exists-quirk");
        dwc->tx_de_emphasis_quirk = dev_read_bool(dev,
                                "snps,tx_de_emphasis_quirk");
        tmp = dev_read_u8_array_ptr(dev, "snps,tx_de_emphasis", 1);
@@ -944,6 +962,7 @@ void dwc3_of_parse(struct dwc3 *dwc)
 int dwc3_init(struct dwc3 *dwc)
 {
        int ret;
+       u32 reg;
 
        dwc3_cache_hwparams(dwc);
 
@@ -965,6 +984,31 @@ int dwc3_init(struct dwc3 *dwc)
                goto event_fail;
        }
 
+       if (dwc->revision >= DWC3_REVISION_250A) {
+               reg = dwc3_readl(dwc->regs, DWC3_GUCTL1);
+
+               /*
+                * Enable hardware control of sending remote wakeup
+                * in HS when the device is in the L1 state.
+                */
+               if (dwc->revision >= DWC3_REVISION_290A)
+                       reg |= DWC3_GUCTL1_DEV_L1_EXIT_BY_HW;
+
+               if (dwc->dis_tx_ipgap_linecheck_quirk)
+                       reg |= DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS;
+
+               dwc3_writel(dwc->regs, DWC3_GUCTL1, reg);
+       }
+
+       if (dwc->dr_mode == USB_DR_MODE_HOST ||
+           dwc->dr_mode == USB_DR_MODE_OTG) {
+               reg = dwc3_readl(dwc->regs, DWC3_GUCTL);
+
+               reg |= DWC3_GUCTL_HSTINAUTORETRY;
+
+               dwc3_writel(dwc->regs, DWC3_GUCTL, reg);
+       }
+
        ret = dwc3_core_init_mode(dwc);
        if (ret)
                goto mode_fail;
index 2b4c51a406192f13ccc2c68c7344fc944796a3ce..44533fd7fed44491304f248697bd471ff6fe31bf 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/usb/ch9.h>
 #include <linux/usb/otg.h>
+#include <linux/usb/phy.h>
 
 #define DWC3_MSG_MAX   500
 
@@ -74,6 +75,7 @@
 #define DWC3_GCTL              0xc110
 #define DWC3_GEVTEN            0xc114
 #define DWC3_GSTS              0xc118
+#define DWC3_GUCTL1            0xc11c
 #define DWC3_GSNPSID           0xc120
 #define DWC3_GGPIO             0xc124
 #define DWC3_GUID              0xc128
 #define DWC3_GCTL_GBLHIBERNATIONEN     (1 << 1)
 #define DWC3_GCTL_DSBLCLKGTNG          (1 << 0)
 
+/* Global User Control Register */
+#define DWC3_GUCTL_HSTINAUTORETRY      BIT(14)
+
+/* Global User Control 1 Register */
+#define DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS     BIT(28)
+#define DWC3_GUCTL1_DEV_L1_EXIT_BY_HW  BIT(24)
+
 /* Global USB2 PHY Configuration Register */
 #define DWC3_GUSB2PHYCFG_PHYSOFTRST    (1 << 31)
+#define DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS     (1 << 30)
 #define DWC3_GUSB2PHYCFG_SUSPHY                (1 << 6)
+#define DWC3_GUSB2PHYCFG_ENBLSLPM      (1 << 8)
 #define DWC3_GUSB2PHYCFG_PHYIF(n)      ((n) << 3)
 #define DWC3_GUSB2PHYCFG_PHYIF_MASK    DWC3_GUSB2PHYCFG_PHYIF(1)
 #define DWC3_GUSB2PHYCFG_USBTRDTIM(n)  ((n) << 10)
@@ -649,6 +660,9 @@ struct dwc3_scratchpad_array {
  * @maximum_speed: maximum speed requested (mainly for testing purposes)
  * @revision: revision register contents
  * @dr_mode: requested mode of operation
+ * @hsphy_mode: UTMI phy mode, one of following:
+ *             - USBPHY_INTERFACE_MODE_UTMI
+ *             - USBPHY_INTERFACE_MODE_UTMIW
  * @dcfg: saved contents of DCFG register
  * @gctl: saved contents of GCTL register
  * @isoch_delay: wValue from Set Isochronous Delay request;
@@ -740,6 +754,7 @@ struct dwc3 {
        size_t                  regs_size;
 
        enum usb_dr_mode        dr_mode;
+       enum usb_phy_interface  hsphy_mode;
 
        /* used for suspend/resume */
        u32                     dcfg;
@@ -770,6 +785,7 @@ struct dwc3 {
 #define DWC3_REVISION_260A     0x5533260a
 #define DWC3_REVISION_270A     0x5533270a
 #define DWC3_REVISION_280A     0x5533280a
+#define DWC3_REVISION_290A     0x5533290a
 
        enum dwc3_ep0_next      ep0_next_event;
        enum dwc3_ep0_state     ep0state;
@@ -823,6 +839,9 @@ struct dwc3 {
        unsigned                dis_u3_susphy_quirk:1;
        unsigned                dis_u2_susphy_quirk:1;
        unsigned                dis_del_phy_power_chg_quirk:1;
+       unsigned                dis_tx_ipgap_linecheck_quirk:1;
+       unsigned                dis_enblslpm_quirk:1;
+       unsigned                dis_u2_freeclk_exists_quirk:1;
 
        unsigned                tx_de_emphasis_quirk:1;
        unsigned                tx_de_emphasis:2;
index 484e7a7b8c8bf6be176fd4d4d86923aabee73774..551f682024c058bbde63a3d72e57fcd043d311a6 100644 (file)
@@ -16,6 +16,7 @@
 #include <dm/lists.h>
 #include <dwc3-uboot.h>
 #include <linux/bitops.h>
+#include <linux/delay.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 #include <malloc.h>
 #include <clk.h>
 #include <usb/xhci.h>
 
+struct dwc3_glue_data {
+       struct clk_bulk         clks;
+       struct reset_ctl_bulk   resets;
+       fdt_addr_t regs;
+};
+
 struct dwc3_generic_plat {
        fdt_addr_t base;
        u32 maximum_speed;
@@ -49,6 +56,7 @@ static int dwc3_generic_probe(struct udevice *dev,
        int rc;
        struct dwc3_generic_plat *plat = dev_get_platdata(dev);
        struct dwc3 *dwc3 = &priv->dwc3;
+       struct dwc3_glue_data *glue = dev_get_platdata(dev->parent);
 
        dwc3->dev = dev;
        dwc3->maximum_speed = plat->maximum_speed;
@@ -57,10 +65,22 @@ static int dwc3_generic_probe(struct udevice *dev,
        dwc3_of_parse(dwc3);
 #endif
 
+       /*
+        * It must hold whole USB3.0 OTG controller in resetting to hold pipe
+        * power state in P2 before initializing TypeC PHY on RK3399 platform.
+        */
+       if (device_is_compatible(dev->parent, "rockchip,rk3399-dwc3")) {
+               reset_assert_bulk(&glue->resets);
+               udelay(1);
+       }
+
        rc = dwc3_setup_phy(dev, &priv->phys);
        if (rc)
                return rc;
 
+       if (device_is_compatible(dev->parent, "rockchip,rk3399-dwc3"))
+               reset_deassert_bulk(&glue->resets);
+
        priv->base = map_physmem(plat->base, DWC3_OTG_REGS_END, MAP_NOCACHE);
        dwc3->regs = priv->base + DWC3_GLOBALS_REGS_START;
 
@@ -188,12 +208,6 @@ U_BOOT_DRIVER(dwc3_generic_host) = {
 };
 #endif
 
-struct dwc3_glue_data {
-       struct clk_bulk         clks;
-       struct reset_ctl_bulk   resets;
-       fdt_addr_t regs;
-};
-
 struct dwc3_glue_ops {
        void (*select_dr_mode)(struct udevice *dev, int index,
                               enum usb_dr_mode mode);
@@ -396,6 +410,12 @@ static int dwc3_glue_probe(struct udevice *dev)
        if (ret)
                return ret;
 
+       if (glue->resets.count == 0) {
+               ret = dwc3_glue_reset_init(child, glue);
+               if (ret)
+                       return ret;
+       }
+
        while (child) {
                enum usb_dr_mode dr_mode;
 
@@ -427,6 +447,8 @@ static const struct udevice_id dwc3_glue_ids[] = {
        { .compatible = "ti,dwc3", .data = (ulong)&ti_ops },
        { .compatible = "ti,am437x-dwc3", .data = (ulong)&ti_ops },
        { .compatible = "ti,am654-dwc3" },
+       { .compatible = "rockchip,rk3328-dwc3" },
+       { .compatible = "rockchip,rk3399-dwc3" },
        { }
 };
 
index d9908ecc156210f4a82bbf02d62880fcc7c47fd1..f201a1789b6600a326834a72c1c1d12515c5fa51 100644 (file)
@@ -1354,9 +1354,8 @@ int r8152_eth_probe(struct usb_device *dev, unsigned int ifnum,
        struct usb_interface *iface;
        struct usb_interface_descriptor *iface_desc;
        int ep_in_found = 0, ep_out_found = 0;
-       int i;
-
        struct r8152 *tp;
+       int i;
 
        /* let's examine the device now */
        iface = &dev->config.if_desc[ifnum];
@@ -1399,10 +1398,13 @@ int r8152_eth_probe(struct usb_device *dev, unsigned int ifnum,
                if ((iface->ep_desc[i].bmAttributes &
                     USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
                        u8 ep_addr = iface->ep_desc[i].bEndpointAddress;
-                       if ((ep_addr & USB_DIR_IN) && !ep_in_found) {
-                               ss->ep_in = ep_addr &
-                                       USB_ENDPOINT_NUMBER_MASK;
-                               ep_in_found = 1;
+
+                       if (ep_addr & USB_DIR_IN) {
+                               if (!ep_in_found) {
+                                       ss->ep_in = ep_addr &
+                                               USB_ENDPOINT_NUMBER_MASK;
+                                       ep_in_found = 1;
+                               }
                        } else {
                                if (!ep_out_found) {
                                        ss->ep_out = ep_addr &
index f0a9ed226cb7e16430a841cd2fb45b740fcd21aa..1c374a7bd809b1ea725461a3d682802077e3b0ba 100644 (file)
@@ -53,15 +53,6 @@ config USB_XHCI_PCI
        help
          Enables support for the PCI-based xHCI controller.
 
-config USB_XHCI_ROCKCHIP
-       bool "Support for Rockchip on-chip xHCI USB controller"
-       depends on ARCH_ROCKCHIP
-       depends on DM_REGULATOR
-       depends on DM_USB
-       default y
-       help
-         Enables support for the on-chip xHCI controller on Rockchip SoCs.
-
 config USB_XHCI_RCAR
        bool "Renesas RCar USB 3.0 support"
        default y
index e8e3b17e42c6f4f03839dfca657d89d900d4f9a7..29d4f87e38b42a4a0d4bbf022954306a4f8ffb65 100644 (file)
@@ -48,7 +48,6 @@ obj-$(CONFIG_USB_XHCI_BRCM) += xhci-brcm.o
 obj-$(CONFIG_USB_XHCI_HCD) += xhci.o xhci-mem.o xhci-ring.o
 obj-$(CONFIG_USB_XHCI_DWC3) += xhci-dwc3.o
 obj-$(CONFIG_USB_XHCI_DWC3_OF_SIMPLE) += dwc3-of-simple.o
-obj-$(CONFIG_USB_XHCI_ROCKCHIP) += xhci-rockchip.o
 obj-$(CONFIG_USB_XHCI_EXYNOS) += xhci-exynos5.o
 obj-$(CONFIG_USB_XHCI_FSL) += xhci-fsl.o
 obj-$(CONFIG_USB_XHCI_MTK) += xhci-mtk.o
index 24f8ad7af84a229527ac75811e443af0e994e778..5f84c7b91d8a91e5b67c2628809d6d286db3d8bb 100644 (file)
@@ -447,8 +447,8 @@ static int mx6_init_after_reset(struct ehci_ctrl *dev)
                ret = regulator_set_enable(priv->vbus_supply,
                                           (type == USB_INIT_DEVICE) ?
                                           false : true);
-               if (ret) {
-                       puts("Error enabling VBUS supply\n");
+               if (ret && ret != -ENOSYS) {
+                       printf("Error enabling VBUS supply (ret=%i)\n", ret);
                        return ret;
                }
        }
@@ -614,8 +614,8 @@ static int ehci_usb_probe(struct udevice *dev)
                ret = regulator_set_enable(priv->vbus_supply,
                                           (type == USB_INIT_DEVICE) ?
                                           false : true);
-               if (ret) {
-                       puts("Error enabling VBUS supply\n");
+               if (ret && ret != -ENOSYS) {
+                       printf("Error enabling VBUS supply (ret=%i)\n", ret);
                        return ret;
                }
        }
diff --git a/drivers/usb/host/xhci-rockchip.c b/drivers/usb/host/xhci-rockchip.c
deleted file mode 100644 (file)
index 1c2bf04..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (c) 2016 Rockchip, Inc.
- * Authors: Daniel Meng <daniel.meng@rock-chips.com>
- */
-#include <common.h>
-#include <dm.h>
-#include <log.h>
-#include <malloc.h>
-#include <usb.h>
-#include <watchdog.h>
-#include <linux/errno.h>
-#include <linux/compat.h>
-#include <linux/usb/dwc3.h>
-#include <power/regulator.h>
-
-#include <usb/xhci.h>
-
-struct rockchip_xhci_platdata {
-       fdt_addr_t hcd_base;
-       struct udevice *vbus_supply;
-};
-
-/*
- * Contains pointers to register base addresses
- * for the usb controller.
- */
-struct rockchip_xhci {
-       struct usb_platdata usb_plat;
-       struct xhci_ctrl ctrl;
-       struct xhci_hccr *hcd;
-       struct dwc3 *dwc3_reg;
-};
-
-static int xhci_usb_ofdata_to_platdata(struct udevice *dev)
-{
-       struct rockchip_xhci_platdata *plat = dev_get_platdata(dev);
-       int ret = 0;
-
-       /*
-        * Get the base address for XHCI controller from the device node
-        */
-       plat->hcd_base = dev_read_addr(dev);
-       if (plat->hcd_base == FDT_ADDR_T_NONE) {
-               pr_err("Can't get the XHCI register base address\n");
-               return -ENXIO;
-       }
-
-       /* Vbus regulator */
-       ret = device_get_supply_regulator(dev, "vbus-supply",
-                                         &plat->vbus_supply);
-       if (ret)
-               debug("Can't get VBus regulator!\n");
-
-       return 0;
-}
-
-/*
- * rockchip_dwc3_phy_setup() - Configure USB PHY Interface of DWC3 Core
- * @dwc: Pointer to our controller context structure
- * @dev: Pointer to ulcass device
- */
-static void rockchip_dwc3_phy_setup(struct dwc3 *dwc3_reg,
-                                   struct udevice *dev)
-{
-       u32 reg;
-       u32 utmi_bits;
-
-       /* Set dwc3 usb2 phy config */
-       reg = readl(&dwc3_reg->g_usb2phycfg[0]);
-
-       if (dev_read_bool(dev, "snps,dis-enblslpm-quirk"))
-               reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM;
-
-       utmi_bits = dev_read_u32_default(dev, "snps,phyif-utmi-bits", -1);
-       if (utmi_bits == 16) {
-               reg |= DWC3_GUSB2PHYCFG_PHYIF;
-               reg &= ~DWC3_GUSB2PHYCFG_USBTRDTIM_MASK;
-               reg |= DWC3_GUSB2PHYCFG_USBTRDTIM_16BIT;
-       } else if (utmi_bits == 8) {
-               reg &= ~DWC3_GUSB2PHYCFG_PHYIF;
-               reg &= ~DWC3_GUSB2PHYCFG_USBTRDTIM_MASK;
-               reg |= DWC3_GUSB2PHYCFG_USBTRDTIM_8BIT;
-       }
-
-       if (dev_read_bool(dev, "snps,dis-u2-freeclk-exists-quirk"))
-               reg &= ~DWC3_GUSB2PHYCFG_U2_FREECLK_EXISTS;
-
-       if (dev_read_bool(dev, "snps,dis-u2-susphy-quirk"))
-               reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
-
-       writel(reg, &dwc3_reg->g_usb2phycfg[0]);
-}
-
-static int rockchip_xhci_core_init(struct rockchip_xhci *rkxhci,
-                                  struct udevice *dev)
-{
-       int ret;
-
-       ret = dwc3_core_init(rkxhci->dwc3_reg);
-       if (ret) {
-               pr_err("failed to initialize core\n");
-               return ret;
-       }
-
-       rockchip_dwc3_phy_setup(rkxhci->dwc3_reg, dev);
-
-       /* We are hard-coding DWC3 core to Host Mode */
-       dwc3_set_mode(rkxhci->dwc3_reg, DWC3_GCTL_PRTCAP_HOST);
-
-       return 0;
-}
-
-static int rockchip_xhci_core_exit(struct rockchip_xhci *rkxhci)
-{
-       return 0;
-}
-
-static int xhci_usb_probe(struct udevice *dev)
-{
-       struct rockchip_xhci_platdata *plat = dev_get_platdata(dev);
-       struct rockchip_xhci *ctx = dev_get_priv(dev);
-       struct xhci_hcor *hcor;
-       int ret;
-
-       ctx->hcd = (struct xhci_hccr *)plat->hcd_base;
-       ctx->dwc3_reg = (struct dwc3 *)((char *)(ctx->hcd) + DWC3_REG_OFFSET);
-       hcor = (struct xhci_hcor *)((uint64_t)ctx->hcd +
-                       HC_LENGTH(xhci_readl(&ctx->hcd->cr_capbase)));
-
-       if (plat->vbus_supply) {
-               ret = regulator_set_enable(plat->vbus_supply, true);
-               if (ret) {
-                       pr_err("XHCI: failed to set VBus supply\n");
-                       return ret;
-               }
-       }
-
-       ret = rockchip_xhci_core_init(ctx, dev);
-       if (ret) {
-               pr_err("XHCI: failed to initialize controller\n");
-               return ret;
-       }
-
-       return xhci_register(dev, ctx->hcd, hcor);
-}
-
-static int xhci_usb_remove(struct udevice *dev)
-{
-       struct rockchip_xhci_platdata *plat = dev_get_platdata(dev);
-       struct rockchip_xhci *ctx = dev_get_priv(dev);
-       int ret;
-
-       ret = xhci_deregister(dev);
-       if (ret)
-               return ret;
-       ret = rockchip_xhci_core_exit(ctx);
-       if (ret)
-               return ret;
-
-       if (plat->vbus_supply) {
-               ret = regulator_set_enable(plat->vbus_supply, false);
-               if (ret)
-                       pr_err("XHCI: failed to set VBus supply\n");
-       }
-
-       return ret;
-}
-
-static const struct udevice_id xhci_usb_ids[] = {
-       { .compatible = "rockchip,rk3328-xhci" },
-       { }
-};
-
-U_BOOT_DRIVER(usb_xhci) = {
-       .name   = "xhci_rockchip",
-       .id     = UCLASS_USB,
-       .of_match = xhci_usb_ids,
-       .ofdata_to_platdata = xhci_usb_ofdata_to_platdata,
-       .probe = xhci_usb_probe,
-       .remove = xhci_usb_remove,
-       .ops    = &xhci_usb_ops,
-       .bind   = dm_scan_fdt_dev,
-       .platdata_auto_alloc_size = sizeof(struct rockchip_xhci_platdata),
-       .priv_auto_alloc_size = sizeof(struct rockchip_xhci),
-       .flags  = DM_FLAG_ALLOC_PRIV_DMA,
-};
-
-static const struct udevice_id usb_phy_ids[] = {
-       { .compatible = "rockchip,rk3328-usb3-phy" },
-       { }
-};
-
-U_BOOT_DRIVER(usb_phy) = {
-       .name = "usb_phy_rockchip",
-       .of_match = usb_phy_ids,
-};
diff --git a/include/configs/pinebook-pro-rk3399.h b/include/configs/pinebook-pro-rk3399.h
new file mode 100644 (file)
index 0000000..4bc8802
--- /dev/null
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2016 Rockchip Electronics Co., Ltd
+ * Copyright (C) 2020 Peter Robinson <pbrobinson at gmail.com>
+ */
+
+#ifndef __PINEBOOK_PRO_RK3399_H
+#define __PINEBOOK_PRO_RK3399_H
+
+#define ROCKCHIP_DEVICE_SETTINGS \
+               "stdin=serial,usbkbd\0" \
+               "stdout=serial,vidconsole\0" \
+               "stderr=serial,vidconsole\0"
+
+#include <configs/rk3399_common.h>
+
+#if defined(CONFIG_ENV_IS_IN_MMC)
+#define CONFIG_SYS_MMC_ENV_DEV 0
+#elif defined(CONFIG_ENV_IS_IN_SPI_FLASH)
+#define CONFIG_ENV_SECT_SIZE           (8 * 1024)
+#endif
+
+#undef CONFIG_SYS_SPI_U_BOOT_OFFS
+#define CONFIG_SYS_SPI_U_BOOT_OFFS     1024 * 512
+
+#define SDRAM_BANK_SIZE                        (2UL << 30)
+
+#endif
index bf8c60d6dddb0e5f77e729604f85bf8998cb1dd5..0b9e24d1db44bd09899cd30893ea5e08204fd8bb 100644 (file)
        #define BOOT_TARGET_MMC(func)
 #endif
 
+#if CONFIG_IS_ENABLED(CMD_NVME)
+       #define BOOT_TARGET_NVME(func) func(NVME, nvme, 0)
+#else
+       #define BOOT_TARGET_NVME(func)
+#endif
+
 #if CONFIG_IS_ENABLED(CMD_USB)
        #define BOOT_TARGET_USB(func) func(USB, usb, 0)
 #else
@@ -50,6 +56,7 @@
 #ifdef CONFIG_ROCKCHIP_RK3399
 #define BOOT_TARGET_DEVICES(func) \
        BOOT_TARGET_MMC(func) \
+       BOOT_TARGET_NVME(func) \
        BOOT_TARGET_USB(func) \
        BOOT_TARGET_PXE(func) \
        BOOT_TARGET_DHCP(func) \
index 7a72cf6049986c0b08b49e7c4c040b0485ccd3a6..37a08b2c00f6e2eb355d964d45be9aa4b70598e2 100644 (file)
@@ -17,4 +17,6 @@
 
 #define SDRAM_BANK_SIZE                        (2UL << 30)
 
+#define CONFIG_USB_OHCI_NEW
+#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS     2
 #endif
diff --git a/include/dt-bindings/input/gpio-keys.h b/include/dt-bindings/input/gpio-keys.h
new file mode 100644 (file)
index 0000000..8962df7
--- /dev/null
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * This header provides constants for gpio keys bindings.
+ */
+
+#ifndef _DT_BINDINGS_GPIO_KEYS_H
+#define _DT_BINDINGS_GPIO_KEYS_H
+
+#define EV_ACT_ANY             0x00    /* asserted or deasserted */
+#define EV_ACT_ASSERTED                0x01    /* asserted */
+#define EV_ACT_DEASSERTED      0x02    /* deasserted */
+
+#endif /* _DT_BINDINGS_GPIO_KEYS_H */
index ecae34bf0697732caa40b83d5602d9844853ae6a..e08530ec4e5894365afefb25599683801b00084c 100644 (file)
@@ -34,6 +34,9 @@ struct dwc3_device {
        unsigned dis_u3_susphy_quirk;
        unsigned dis_u2_susphy_quirk;
        unsigned dis_del_phy_power_chg_quirk;
+       unsigned dis_tx_ipgap_linecheck_quirk;
+       unsigned dis_enblslpm_quirk;
+       unsigned dis_u2_freeclk_exists_quirk;
        unsigned tx_de_emphasis_quirk;
        unsigned tx_de_emphasis;
        int index;
index 158ca9cd853ff8cf73d02d2378338c8129827e26..1e1217a95834eaa4998f7e81f646b696782f51bd 100644 (file)
 #ifndef __LINUX_USB_PHY_H
 #define __LINUX_USB_PHY_H
 
+#include <dm/ofnode.h>
+
 enum usb_phy_interface {
        USBPHY_INTERFACE_MODE_UNKNOWN,
        USBPHY_INTERFACE_MODE_UTMI,
        USBPHY_INTERFACE_MODE_UTMIW,
 };
 
+#if CONFIG_IS_ENABLED(DM_USB)
+/**
+ * usb_get_phy_mode - Get phy mode for given device_node
+ * @np:        Pointer to the given device_node
+ *
+ * The function gets phy interface string from property 'phy_type',
+ * and returns the corresponding enum usb_phy_interface
+ */
+enum usb_phy_interface usb_get_phy_mode(ofnode node);
+#else
+static inline enum usb_phy_interface usb_get_phy_mode(ofnode node)
+{
+       return USBPHY_INTERFACE_MODE_UNKNOWN;
+}
+#endif
+
 #endif /* __LINUX_USB_PHY_H */
index 02d5829744954e5162f0306b17c74a7b56e2e219..52b2cf70bd0e58416205ee6e4e810c03652c3f90 100644 (file)
@@ -247,14 +247,37 @@ Series-changes: n
        to update the log there and then, knowing that the script will
        do the rest.
 
+Commit-changes: n
+- This line will not appear in the cover-letter changelog
+<blank line>
+       This tag is like Series-changes, except changes in this changelog will
+       only appear in the changelog of the commit this tag is in. This is
+       useful when you want to add notes which may not make sense in the cover
+       letter. For example, you can have short changes such as "New" or
+       "Lint".
+
+Cover-changes: n
+- This line will only appear in the cover letter
+<blank line>
+       This tag is like Series-changes, except changes in this changelog will
+       only appear in the cover-letter changelog. This is useful to summarize
+       changes made with Commit-changes, or to add additional context to
+       changes.
+
 Patch-cc: Their Name <email>
        This copies a single patch to another email address. Note that the
        Cc: used by git send-email is ignored by patman, but will be
        interpreted by git send-email if you use it.
 
 Series-process-log: sort, uniq
-       This tells patman to sort and/or uniq the change logs. It is
-       assumed that each change log entry is only a single line long.
+       This tells patman to sort and/or uniq the change logs. Changes may be
+       multiple lines long, as long as each subsequent line of a change begins
+       with a whitespace character. For example,
+
+- This change
+  continues onto the next line
+- But this change is separate
+
        Use 'sort' to sort the entries, and 'uniq' to include only
        unique entries. If omitted, no change log processing is done.
        Separate each tag with a comma.
@@ -474,6 +497,33 @@ print out the command line patman would have used.
 not later when you can't remember which patch you changed. You can always
 go back and change or remove logs from commits.
 
+7. Some mailing lists have size limits and when we add binary contents to
+our patches it's easy to exceed the size limits. Use "--no-binary" to
+generate patches without any binary contents. You are supposed to include
+a link to a git repository in your "Commit-notes", "Series-notes" or
+"Cover-letter" for maintainers to fetch the original commit.
+
+8. Patches will have no changelog entries for revisions where they did not
+change. For clarity, if there are no changes for this patch in the most
+recent revision of the series, a note will be added. For example, a patch
+with the following tags in the commit
+
+    Series-version: 5
+    Series-changes: 2
+    - Some change
+
+    Series-changes: 4
+    - Another change
+
+would have a changelog of
+
+    (no changes since v4)
+
+    Changes in v4:
+    - Another change
+
+    Changes in v2:
+    - Some change
 
 Other thoughts
 ==============
index b7e2825de88148c6b577519ded479e40987ac337..dc30078ccee65aa1d8e60c34cb72a636d2f110f8 100644 (file)
@@ -82,19 +82,33 @@ class TestFunctional(unittest.TestCase):
             Series-prefix: RFC
             Series-cc: Stefan Brüns <stefan.bruens@rwth-aachen.de>
             Cover-letter-cc: Lord Mëlchett <clergy@palace.gov>
-            Series-version: 2
+            Series-version: 3
+            Patch-cc: fred
+            Series-process-log: sort, uniq
             Series-changes: 4
             - Some changes
+            - Multi
+              line
+              change
+
+            Commit-changes: 2
+            - Changes only for this commit
+
+            Cover-changes: 4
+            - Some notes for the cover letter
 
             Cover-letter:
             test: A test patch series
             This is a test of how the cover
-            leter
+            letter
             works
             END
 
         and this in the first commit:
 
+            Commit-changes: 2
+            - second revision change
+
             Series-notes:
             some notes
             about some things
@@ -202,7 +216,7 @@ class TestFunctional(unittest.TestCase):
 
         expected = '''
 This is a test of how the cover
-leter
+letter
 works
 
 some notes
@@ -210,7 +224,11 @@ about some things
 from the first commit
 
 Changes in v4:
+- Multi
+  line
+  change
 - Some changes
+- Some notes for the cover letter
 
 Simon Glass (2):
   pci: Correct cast for sandbox
@@ -237,8 +255,34 @@ Simon Glass (2):
             subject = [line for line in lines if line.startswith('Subject')]
             self.assertEqual('Subject: [RFC %d/%d]' % (i + 1, count),
                              subject[0][:18])
+
+            # Check that we got our commit notes
+            start = 0
+            expected = ''
+
             if i == 0:
-                # Check that we got our commit notes
-                self.assertEqual('---', lines[17])
-                self.assertEqual('Some notes about', lines[18])
-                self.assertEqual('the first commit', lines[19])
+                start = 17
+                expected = '''---
+Some notes about
+the first commit
+
+(no changes since v2)
+
+Changes in v2:
+- second revision change'''
+            elif i == 1:
+                start = 17
+                expected = '''---
+
+Changes in v4:
+- Multi
+  line
+  change
+- Some changes
+
+Changes in v2:
+- Changes only for this commit'''
+
+            if expected:
+                expected = expected.splitlines()
+                self.assertEqual(expected, lines[start:(start+len(expected))])
index 770a0510142cf19ca271fa554d5170d6d5e8f321..72fc95d5580d497b13c6d72eaaaa32a7086058c8 100644 (file)
@@ -254,7 +254,7 @@ def Fetch(git_dir=None, work_tree=None):
     if result.return_code != 0:
         raise OSError('git fetch: %s' % result.stderr)
 
-def CreatePatches(start, count, series):
+def CreatePatches(start, count, ignore_binary, series):
     """Create a series of patches from the top of the current branch.
 
     The patch files are written to the current directory using
@@ -270,6 +270,8 @@ def CreatePatches(start, count, series):
     if series.get('version'):
         version = '%s ' % series['version']
     cmd = ['git', 'format-patch', '-M', '--signoff']
+    if ignore_binary:
+        cmd.append('--no-binary')
     if series.get('cover'):
         cmd.append('--cover-letter')
     prefix = series.GetPatchPrefix()
index f3d9c0c4348657540a1fdfb35621816b55080289..0974c840598b89a71f652f0815448ca3675ac87c 100755 (executable)
@@ -36,11 +36,11 @@ parser.add_option('-c', '--count', dest='count', type='int',
 parser.add_option('-i', '--ignore-errors', action='store_true',
        dest='ignore_errors', default=False,
        help='Send patches email even if patch errors are found')
+parser.add_option('-l', '--limit-cc', dest='limit', type='int',
+       default=None, help='Limit the cc list to LIMIT entries [default: %default]')
 parser.add_option('-m', '--no-maintainers', action='store_false',
        dest='add_maintainers', default=True,
        help="Don't cc the file maintainers automatically")
-parser.add_option('-l', '--limit-cc', dest='limit', type='int',
-       default=None, help='Limit the cc list to LIMIT entries [default: %default]')
 parser.add_option('-n', '--dry-run', action='store_true', dest='dry_run',
        default=False, help="Do a dry run (create but don't email patches)")
 parser.add_option('-p', '--project', default=project.DetectProject(),
@@ -52,21 +52,24 @@ parser.add_option('-s', '--start', dest='start', type='int',
        default=0, help='Commit to start creating patches from (0 = HEAD)')
 parser.add_option('-t', '--ignore-bad-tags', action='store_true',
                   default=False, help='Ignore bad tags / aliases')
-parser.add_option('--test', action='store_true', dest='test',
-                  default=False, help='run tests')
 parser.add_option('-v', '--verbose', action='store_true', dest='verbose',
        default=False, help='Verbose output of errors and warnings')
+parser.add_option('-T', '--thread', action='store_true', dest='thread',
+                  default=False, help='Create patches as a single thread')
 parser.add_option('--cc-cmd', dest='cc_cmd', type='string', action='store',
        default=None, help='Output cc list for patch file (used by git)')
+parser.add_option('--no-binary', action='store_true', dest='ignore_binary',
+                  default=False,
+                  help="Do not output contents of changes in binary files")
 parser.add_option('--no-check', action='store_false', dest='check_patch',
                   default=True,
                   help="Don't check for patch compliance")
 parser.add_option('--no-tags', action='store_false', dest='process_tags',
-                  default=True, help="Don't process subject tags as aliaes")
+                  default=True, help="Don't process subject tags as aliases")
 parser.add_option('--smtp-server', type='str',
                   help="Specify the SMTP server to 'git send-email'")
-parser.add_option('-T', '--thread', action='store_true', dest='thread',
-                  default=False, help='Create patches as a single thread')
+parser.add_option('--test', action='store_true', dest='test',
+                  default=False, help='run tests')
 
 parser.usage += """
 
@@ -144,7 +147,7 @@ else:
     if options.count:
         series = patchstream.GetMetaData(options.start, options.count)
         cover_fname, args = gitutil.CreatePatches(options.start, options.count,
-                series)
+                options.ignore_binary, series)
 
     # Fix up the patch files to our liking, and insert the cover letter
     patchstream.FixPatches(series, args)
index 405297505c9ca1bc584ec76817b554d8281b3530..4fe465e9ab81714c9ee392f32959814cbbc9c4ae 100644 (file)
@@ -24,11 +24,8 @@ re_allowed_after_test = re.compile('^Signed-off-by:')
 # Signoffs
 re_signoff = re.compile('^Signed-off-by: *(.*)')
 
-# The start of the cover letter
-re_cover = re.compile('^Cover-letter:')
-
-# A cover letter Cc
-re_cover_cc = re.compile('^Cover-letter-cc: *(.*)')
+# Cover letter tag
+re_cover = re.compile('^Cover-([a-z-]*): *(.*)')
 
 # Patch series tag
 re_series_tag = re.compile('^Series-([a-z-]*): *(.*)')
@@ -48,6 +45,9 @@ re_commit = re.compile('^commit ([0-9a-f]*)$')
 # We detect these since checkpatch doesn't always do it
 re_space_before_tab = re.compile('^[+].* \t')
 
+# Match indented lines for changes
+re_leading_whitespace = re.compile('^\s')
+
 # States we can be in - can we use range() and still have comments?
 STATE_MSG_HEADER = 0        # Still in the message header
 STATE_PATCH_SUBJECT = 1     # In patch subject (first line of log for a commit)
@@ -65,7 +65,7 @@ class PatchStream:
     def __init__(self, series, name=None, is_log=False):
         self.skip_blank = False          # True to skip a single blank line
         self.found_test = False          # Found a TEST= line
-        self.lines_after_test = 0        # MNumber of lines found after TEST=
+        self.lines_after_test = 0        # Number of lines found after TEST=
         self.warn = []                   # List of warnings we have collected
         self.linenum = 1                 # Output line number we are up to
         self.in_section = None           # Name of start...END section we are in
@@ -73,7 +73,9 @@ class PatchStream:
         self.section = []                # The current section...END section
         self.series = series             # Info about the patch series
         self.is_log = is_log             # True if indent like git log
-        self.in_change = 0               # Non-zero if we are in a change list
+        self.in_change = None            # Name of the change list we are in
+        self.change_version = 0          # Non-zero if we are in a change list
+        self.change_lines = []           # Lines of the current change
         self.blank_count = 0             # Number of blank lines stored up
         self.state = STATE_MSG_HEADER    # What state are we in?
         self.signoff = []                # Contents of signoff line
@@ -124,6 +126,36 @@ class PatchStream:
             self.skip_blank = True
             self.section = []
 
+    def ParseVersion(self, value, line):
+        """Parse a version from a *-changes tag
+
+        Args:
+            value: Tag value (part after 'xxx-changes: '
+            line: Source line containing tag
+
+        Returns:
+            The version as an integer
+        """
+        try:
+            return int(value)
+        except ValueError as str:
+            raise ValueError("%s: Cannot decode version info '%s'" %
+                (self.commit.hash, line))
+
+    def FinalizeChange(self):
+        """Finalize a (multi-line) change and add it to the series or commit"""
+        if not self.change_lines:
+            return
+        change = '\n'.join(self.change_lines)
+
+        if self.in_change == 'Series':
+            self.series.AddChange(self.change_version, self.commit, change)
+        elif self.in_change == 'Cover':
+            self.series.AddChange(self.change_version, None, change)
+        elif self.in_change == 'Commit':
+            self.commit.AddChange(self.change_version, change)
+        self.change_lines = []
+
     def ProcessLine(self, line):
         """Process a single line of a patch file or commit log
 
@@ -163,8 +195,8 @@ class PatchStream:
         change_id_match = re_change_id.match(line)
         commit_tag_match = re_commit_tag.match(line)
         cover_match = re_cover.match(line)
-        cover_cc_match = re_cover_cc.match(line)
         signoff_match = re_signoff.match(line)
+        leading_whitespace_match = re_leading_whitespace.match(line)
         tag_match = None
         if self.state == STATE_PATCH_HEADER:
             tag_match = re_tag.match(line)
@@ -183,8 +215,7 @@ class PatchStream:
 
         # If a tag is detected, or a new commit starts
         if series_tag_match or commit_tag_match or change_id_match or \
-           cover_match or cover_cc_match or signoff_match or \
-           self.state == STATE_MSG_HEADER:
+           cover_match or signoff_match or self.state == STATE_MSG_HEADER:
             # but we are already in a section, this means 'END' is missing
             # for that section, fix it up.
             if self.in_section:
@@ -205,8 +236,10 @@ class PatchStream:
             # but we are already in a change list, that means a blank line
             # is missing, fix it up.
             if self.in_change:
-                self.warn.append("Missing 'blank line' in section 'Series-changes'")
-                self.in_change = 0
+                self.warn.append("Missing 'blank line' in section '%s-changes'" % self.in_change)
+                self.FinalizeChange()
+                self.in_change = None
+                self.change_version = 0
 
         # If we are in a section, keep collecting lines until we see END
         if self.in_section:
@@ -242,26 +275,35 @@ class PatchStream:
         elif self.skip_blank and is_blank:
             self.skip_blank = False
 
-        # Detect the start of a cover letter section
+        # Detect Cover-xxx tags
         elif cover_match:
-            self.in_section = 'cover'
-            self.skip_blank = False
-
-        elif cover_cc_match:
-            value = cover_cc_match.group(1)
-            self.AddToSeries(line, 'cover-cc', value)
+            name = cover_match.group(1)
+            value = cover_match.group(2)
+            if name == 'letter':
+                self.in_section = 'cover'
+                self.skip_blank = False
+            elif name == 'letter-cc':
+                self.AddToSeries(line, 'cover-cc', value)
+            elif name == 'changes':
+                self.in_change = 'Cover'
+                self.change_version = self.ParseVersion(value, line)
 
         # If we are in a change list, key collected lines until a blank one
         elif self.in_change:
             if is_blank:
                 # Blank line ends this change list
-                self.in_change = 0
+                self.FinalizeChange()
+                self.in_change = None
+                self.change_version = 0
             elif line == '---':
-                self.in_change = 0
+                self.FinalizeChange()
+                self.in_change = None
+                self.change_version = 0
                 out = self.ProcessLine(line)
-            else:
-                if self.is_log:
-                    self.series.AddChange(self.in_change, self.commit, line)
+            elif self.is_log:
+                if not leading_whitespace_match:
+                    self.FinalizeChange()
+                self.change_lines.append(line)
             self.skip_blank = False
 
         # Detect Series-xxx tags
@@ -270,12 +312,8 @@ class PatchStream:
             value = series_tag_match.group(2)
             if name == 'changes':
                 # value is the version number: e.g. 1, or 2
-                try:
-                    value = int(value)
-                except ValueError as str:
-                    raise ValueError("%s: Cannot decode version info '%s'" %
-                        (self.commit.hash, line))
-                self.in_change = int(value)
+                self.in_change = 'Series'
+                self.change_version = self.ParseVersion(value, line)
             else:
                 self.AddToSeries(line, name, value)
                 self.skip_blank = True
@@ -297,6 +335,9 @@ class PatchStream:
             if name == 'notes':
                 self.AddToCommit(line, name, value)
                 self.skip_blank = True
+            elif name == 'changes':
+                self.in_change = 'Commit'
+                self.change_version = self.ParseVersion(value, line)
 
         # Detect the start of a new commit
         elif commit_match:
@@ -340,7 +381,7 @@ class PatchStream:
             elif line == '---':
                 self.state = STATE_DIFFS
 
-                # Output the tags (signeoff first), then change list
+                # Output the tags (signoff first), then change list
                 out = []
                 log = self.series.MakeChangeLog(self.commit)
                 out += [line]
@@ -355,6 +396,7 @@ class PatchStream:
 
     def Finalize(self):
         """Close out processing of this patch stream"""
+        self.FinalizeChange()
         self.CloseCommit()
         if self.lines_after_test:
             self.warn.append('Found %d lines after TEST=' %
index e5e28cebdf5e0ed016c0c246f4a5f7da8a72bd9f..ca7ca556dc8554621efcc2ee5448977efb0315f7 100644 (file)
@@ -2,6 +2,9 @@
 # Copyright (c) 2011 The Chromium OS Authors.
 #
 
+from __future__ import print_function
+
+import collections
 import itertools
 import os
 
@@ -144,38 +147,65 @@ class Series(dict):
             Changes in v4:
             - Jog the dial back closer to the widget
 
-            Changes in v3: None
             Changes in v2:
             - Fix the widget
             - Jog the dial
 
-            etc.
+            If there are no new changes in a patch, a note will be added
+
+            (no changes since v2)
+
+            Changes in v2:
+            - Fix the widget
+            - Jog the dial
         """
+        # Collect changes from the series and this commit
+        changes = collections.defaultdict(list)
+        for version, changelist in self.changes.items():
+            changes[version] += changelist
+        if commit:
+            for version, changelist in commit.changes.items():
+                changes[version] += [[commit, text] for text in changelist]
+
+        versions = sorted(changes, reverse=True)
+        newest_version = 1
+        if 'version' in self:
+            newest_version = max(newest_version, int(self.version))
+        if versions:
+            newest_version = max(newest_version, versions[0])
+
         final = []
         process_it = self.get('process_log', '').split(',')
         process_it = [item.strip() for item in process_it]
         need_blank = False
-        for change in sorted(self.changes, reverse=True):
+        for version in versions:
             out = []
-            for this_commit, text in self.changes[change]:
+            for this_commit, text in changes[version]:
                 if commit and this_commit != commit:
                     continue
                 if 'uniq' not in process_it or text not in out:
                     out.append(text)
-            line = 'Changes in v%d:' % change
-            have_changes = len(out) > 0
             if 'sort' in process_it:
                 out = sorted(out)
+            have_changes = len(out) > 0
+            line = 'Changes in v%d:' % version
             if have_changes:
                 out.insert(0, line)
-            else:
-                out = [line + ' None']
-            if need_blank:
-                out.insert(0, '')
+                if version < newest_version and len(final) == 0:
+                    out.insert(0, '')
+                    out.insert(0, '(no changes since v%d)' % version)
+                    newest_version = 0
+                # Only add a new line if we output something
+                if need_blank:
+                    out.insert(0, '')
+                    need_blank = False
             final += out
-            need_blank = have_changes
-        if self.changes:
+            need_blank = need_blank or have_changes
+
+        if len(final) > 0:
             final.append('')
+        elif newest_version != 1:
+            final = ['(no changes since v1)', '']
         return final
 
     def DoChecks(self):
index 7191176f7528a8207f42bf7e2a478d2a47cf8dd4..038943c2c9bb64afdbd903350a2cbc8058e36708 100644 (file)
@@ -15,6 +15,9 @@ cmd/pci.c:152:11: warning: format ‘%llx’ expects argument of type
 Fix it with a cast.
 
 Signed-off-by: Simon Glass <sjg@chromium.org>
+Commit-changes: 2
+- Changes only for this commit
+
 Series-notes:
 some notes
 about some things
index 702c0306ffe120420afe8eee8daa5a63889062b3..56278a6ce9b10997f20044fd434d5ff2ca434650 100644 (file)
@@ -21,13 +21,23 @@ Series-cc: Stefan Brüns <stefan.bruens@rwth-aachen.de>
 Cover-letter-cc: Lord Mëlchett <clergy@palace.gov>
 Series-version: 3
 Patch-cc: fred
+Series-process-log: sort, uniq
 Series-changes: 4
 - Some changes
+- Multi
+  line
+  change
+
+Commit-changes: 2
+- Changes only for this commit
+
+Cover-changes: 4
+- Some notes for the cover letter
 
 Cover-letter:
 test: A test patch series
 This is a test of how the cover
-leter
+letter
 works
 END
 ---
index 478ea93674d0082275e3d68848d65fedda1fa3d0..b238a8b4bab1bdc7450b806016233e30f4d4c447 100644 (file)
@@ -13,6 +13,9 @@ Date:   Sat Apr 15 15:39:08 2017 -0600
     Fix it with a cast.
     
     Signed-off-by: Simon Glass <sjg@chromium.org>
+    Commit-changes: 2
+    - second revision change
+
     Series-notes:
     some notes
     about some things
@@ -45,12 +48,22 @@ Date:   Sat Apr 15 15:39:08 2017 -0600
     Cover-letter-cc: Lord Mëlchett <clergy@palace.gov>
     Series-version: 3
     Patch-cc: fred
+    Series-process-log: sort, uniq
     Series-changes: 4
     - Some changes
+    - Multi
+      line
+      change
+
+    Commit-changes: 2
+    - Changes only for this commit
+
+    Cover-changes: 4
+    - Some notes for the cover letter
     
     Cover-letter:
     test: A test patch series
     This is a test of how the cover
-    leter
+    letter
     works
     END