diff options
46 files changed, 2899 insertions, 380 deletions
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 12ec6c71dc..c6af87cf5e 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -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 \ diff --git a/arch/arm/dts/rk3399-evb-u-boot.dtsi b/arch/arm/dts/rk3399-evb-u-boot.dtsi index e5659d7999..c42bd2856f 100644 --- a/arch/arm/dts/rk3399-evb-u-boot.dtsi +++ b/arch/arm/dts/rk3399-evb-u-boot.dtsi @@ -8,7 +8,7 @@ / { chosen { - u-boot,spl-boot-order = &sdhci, &sdmmc; + u-boot,spl-boot-order = "same-as-spl", &sdhci, &sdmmc; }; }; @@ -23,3 +23,16 @@ &rk808 { u-boot,dm-pre-reloc; }; + +&tcphy1 { + status = "okay"; +}; + +&usbdrd3_1 { + status = "okay"; +}; + +&usbdrd_dwc3_1 { + dr_mode = "host"; + status = "okay"; +}; diff --git a/arch/arm/dts/rk3399-ficus-u-boot.dtsi b/arch/arm/dts/rk3399-ficus-u-boot.dtsi index f3f7aa7c45..38e0897db9 100644 --- a/arch/arm/dts/rk3399-ficus-u-boot.dtsi +++ b/arch/arm/dts/rk3399-ficus-u-boot.dtsi @@ -8,6 +8,6 @@ / { chosen { - u-boot,spl-boot-order = &sdhci, &sdmmc; + u-boot,spl-boot-order = "same-as-spl", &sdhci, &sdmmc; }; }; diff --git a/arch/arm/dts/rk3399-nanopi4-u-boot.dtsi b/arch/arm/dts/rk3399-nanopi4-u-boot.dtsi index a126bbaf08..a9d10592d5 100644 --- a/arch/arm/dts/rk3399-nanopi4-u-boot.dtsi +++ b/arch/arm/dts/rk3399-nanopi4-u-boot.dtsi @@ -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 index 0000000000..1a2e24d3ef --- /dev/null +++ b/arch/arm/dts/rk3399-pinebook-pro-u-boot.dtsi @@ -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 index 0000000000..294d21bf45 --- /dev/null +++ b/arch/arm/dts/rk3399-pinebook-pro.dts @@ -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"; +}; diff --git a/arch/arm/dts/rk3399-rock960-u-boot.dtsi b/arch/arm/dts/rk3399-rock960-u-boot.dtsi index 82f2c311af..c190089e26 100644 --- a/arch/arm/dts/rk3399-rock960-u-boot.dtsi +++ b/arch/arm/dts/rk3399-rock960-u-boot.dtsi @@ -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 { diff --git a/arch/arm/mach-rockchip/rk3399/Kconfig b/arch/arm/mach-rockchip/rk3399/Kconfig index 927bb62a9f..254b9c5b4d 100644 --- a/arch/arm/mach-rockchip/rk3399/Kconfig +++ b/arch/arm/mach-rockchip/rk3399/Kconfig @@ -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" diff --git a/arch/arm/mach-rockchip/rk3399/rk3399.c b/arch/arm/mach-rockchip/rk3399/rk3399.c index 09b0d6ebe8..4fda93b152 100644 --- a/arch/arm/mach-rockchip/rk3399/rk3399.c +++ b/arch/arm/mach-rockchip/rk3399/rk3399.c @@ -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" }, }; diff --git a/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c b/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c index 6b02dc8beb..690cbe7f27 100644 --- a/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c +++ b/arch/arm/mach-rockchip/rk3399/syscon_rk3399.c @@ -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, }; diff --git a/arch/arm/mach-rockchip/spl.c b/arch/arm/mach-rockchip/spl.c index 46b32eb345..cddf4fd3d5 100644 --- a/arch/arm/mach-rockchip/spl.c +++ b/arch/arm/mach-rockchip/spl.c @@ -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 index 0000000000..3bb7ca448e --- /dev/null +++ b/board/pine64/pinebook-pro-rk3399/Kconfig @@ -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 index 0000000000..227c1c0bea --- /dev/null +++ b/board/pine64/pinebook-pro-rk3399/MAINTAINERS @@ -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 index 0000000000..2f692a12a6 --- /dev/null +++ b/board/pine64/pinebook-pro-rk3399/Makefile @@ -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 index 0000000000..516292aaa5 --- /dev/null +++ b/board/pine64/pinebook-pro-rk3399/pinebook-pro-rk3399.c @@ -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", ®ulator); + 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 diff --git a/board/theobroma-systems/puma_rk3399/puma-rk3399.c b/board/theobroma-systems/puma_rk3399/puma-rk3399.c index 561579d056..f7f08ae617 100644 --- a/board/theobroma-systems/puma_rk3399/puma-rk3399.c +++ b/board/theobroma-systems/puma_rk3399/puma-rk3399.c @@ -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__); diff --git a/common/spl/spl.c b/common/spl/spl.c index 7ea0b06a80..0e96a8cd10 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -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 diff --git a/configs/evb-rk3399_defconfig b/configs/evb-rk3399_defconfig index 7f14e18b1b..6cfb4e5dac 100644 --- a/configs/evb-rk3399_defconfig +++ b/configs/evb-rk3399_defconfig @@ -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 diff --git a/configs/nanopc-t4-rk3399_defconfig b/configs/nanopc-t4-rk3399_defconfig index be91e27d82..6fef7e61b9 100644 --- a/configs/nanopc-t4-rk3399_defconfig +++ b/configs/nanopc-t4-rk3399_defconfig @@ -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 index 0000000000..0e9f0ec250 --- /dev/null +++ b/configs/pinebook-pro-rk3399_defconfig @@ -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 diff --git a/configs/roc-pc-mezzanine-rk3399_defconfig b/configs/roc-pc-mezzanine-rk3399_defconfig index d3a3b5ee49..1c1539bcb9 100644 --- a/configs/roc-pc-mezzanine-rk3399_defconfig +++ b/configs/roc-pc-mezzanine-rk3399_defconfig @@ -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 diff --git a/configs/roc-pc-rk3399_defconfig b/configs/roc-pc-rk3399_defconfig index aff690f039..76e76c160e 100644 --- a/configs/roc-pc-rk3399_defconfig +++ b/configs/roc-pc-rk3399_defconfig @@ -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 diff --git a/configs/rockpro64-rk3399_defconfig b/configs/rockpro64-rk3399_defconfig index 9d4343a5a7..8c4b2f35c1 100644 --- a/configs/rockpro64-rk3399_defconfig +++ b/configs/rockpro64-rk3399_defconfig @@ -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 diff --git a/doc/README.rockchip b/doc/README.rockchip index 70c8798ed2..154166ec78 100644 --- a/doc/README.rockchip +++ b/doc/README.rockchip @@ -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 diff --git a/doc/board/rockchip/rockchip.rst b/doc/board/rockchip/rockchip.rst index cd9c8d6dc4..7b72fab496 100644 --- a/doc/board/rockchip/rockchip.rst +++ b/doc/board/rockchip/rockchip.rst @@ -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 diff --git a/drivers/Makefile b/drivers/Makefile index 4208750428..94e8c5da17 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -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/ diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c index 6a78837619..22c373a623 100644 --- a/drivers/clk/rockchip/clk_rk3399.c +++ b/drivers/clk/rockchip/clk_rk3399.c @@ -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; diff --git a/drivers/pci/pcie_rockchip.c b/drivers/pci/pcie_rockchip.c index 82a8396e42..0edc2464a8 100644 --- a/drivers/pci/pcie_rockchip.c +++ b/drivers/pci/pcie_rockchip.c @@ -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; } diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 1e38c8741f..9c775107e9 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -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 index 0000000000..84cc7c876d --- /dev/null +++ b/drivers/phy/rockchip/Kconfig @@ -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 index 0000000000..95b2f8a3c0 --- /dev/null +++ b/drivers/phy/rockchip/Makefile @@ -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 index 0000000000..c5ea6ca31f --- /dev/null +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c @@ -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", ®); + 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 index 0000000000..c9c8e1c542 --- /dev/null +++ b/drivers/phy/rockchip/phy-rockchip-typec.c @@ -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, ®); + 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), +}; diff --git a/drivers/usb/common/common.c b/drivers/usb/common/common.c index 0db281b970..d4ae18693c 100644 --- a/drivers/usb/common/common.c +++ b/drivers/usb/common/common.c @@ -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 diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 8d418c9412..8682556589 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -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; diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 2b4c51a406..44533fd7fe 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -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 @@ -160,9 +162,18 @@ #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; diff --git a/drivers/usb/dwc3/dwc3-generic.c b/drivers/usb/dwc3/dwc3-generic.c index 484e7a7b8c..551f682024 100644 --- a/drivers/usb/dwc3/dwc3-generic.c +++ b/drivers/usb/dwc3/dwc3-generic.c @@ -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> @@ -26,6 +27,12 @@ #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" }, { } }; diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index f0a9ed226c..1c374a7bd8 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -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 diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index e8e3b17e42..29d4f87e38 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -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 diff --git a/drivers/usb/host/xhci-rockchip.c b/drivers/usb/host/xhci-rockchip.c deleted file mode 100644 index 1c2bf04df3..0000000000 --- a/drivers/usb/host/xhci-rockchip.c +++ /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 index 0000000000..4bc8802d11 --- /dev/null +++ b/include/configs/pinebook-pro-rk3399.h @@ -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 diff --git a/include/configs/rockchip-common.h b/include/configs/rockchip-common.h index bf8c60d6dd..0b9e24d1db 100644 --- a/include/configs/rockchip-common.h +++ b/include/configs/rockchip-common.h @@ -23,6 +23,12 @@ #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) \ diff --git a/include/configs/rockpro64_rk3399.h b/include/configs/rockpro64_rk3399.h index 7a72cf6049..37a08b2c00 100644 --- a/include/configs/rockpro64_rk3399.h +++ b/include/configs/rockpro64_rk3399.h @@ -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 index 0000000000..8962df79e7 --- /dev/null +++ b/include/dt-bindings/input/gpio-keys.h @@ -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 */ diff --git a/include/dwc3-uboot.h b/include/dwc3-uboot.h index ecae34bf06..e08530ec4e 100644 --- a/include/dwc3-uboot.h +++ b/include/dwc3-uboot.h @@ -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; diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h index 158ca9cd85..1e1217a958 100644 --- a/include/linux/usb/phy.h +++ b/include/linux/usb/phy.h @@ -10,10 +10,28 @@ #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 */ |