From acc57ecf05500d2ed47f0d3898245d0029e1cc0c Mon Sep 17 00:00:00 2001 From: Hugh Cole-Baker Date: Sun, 22 Nov 2020 13:03:45 +0000 Subject: [PATCH 01/10] rockchip: rk3399-roc-pc: default to SPI bus 1 for SPI-flash SPI flash on this board is located on bus 1, default to using bus 1 for SPI flash on both rk3399-roc-pc and -mezzanine, and stop aliasing it to bus 0. Signed-off-by: Hugh Cole-Baker Suggested-by: Simon Glass Fixes: c4cea2bb ("rockchip: Enable building a SPI ROM image on bob") Reviewed-by: Kever Yang --- arch/arm/dts/rk3399-roc-pc-u-boot.dtsi | 4 ---- configs/roc-pc-mezzanine-rk3399_defconfig | 1 + configs/roc-pc-rk3399_defconfig | 1 + 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/arm/dts/rk3399-roc-pc-u-boot.dtsi b/arch/arm/dts/rk3399-roc-pc-u-boot.dtsi index fc155e6903..e3c9364e35 100644 --- a/arch/arm/dts/rk3399-roc-pc-u-boot.dtsi +++ b/arch/arm/dts/rk3399-roc-pc-u-boot.dtsi @@ -7,10 +7,6 @@ #include "rk3399-sdram-lpddr4-100.dtsi" / { - aliases { - spi0 = &spi1; - }; - chosen { u-boot,spl-boot-order = "same-as-spl", &spi_flash, &sdhci, &sdmmc; }; diff --git a/configs/roc-pc-mezzanine-rk3399_defconfig b/configs/roc-pc-mezzanine-rk3399_defconfig index ae16f3558a..8aa5a15518 100644 --- a/configs/roc-pc-mezzanine-rk3399_defconfig +++ b/configs/roc-pc-mezzanine-rk3399_defconfig @@ -42,6 +42,7 @@ CONFIG_MMC_DW=y CONFIG_MMC_DW_ROCKCHIP=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ROCKCHIP=y +CONFIG_SF_DEFAULT_BUS=1 CONFIG_SPI_FLASH_WINBOND=y CONFIG_DM_ETH=y CONFIG_ETH_DESIGNWARE=y diff --git a/configs/roc-pc-rk3399_defconfig b/configs/roc-pc-rk3399_defconfig index 774707b115..927b57685d 100644 --- a/configs/roc-pc-rk3399_defconfig +++ b/configs/roc-pc-rk3399_defconfig @@ -41,6 +41,7 @@ CONFIG_MMC_DW=y CONFIG_MMC_DW_ROCKCHIP=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ROCKCHIP=y +CONFIG_SF_DEFAULT_BUS=1 CONFIG_SPI_FLASH_WINBOND=y CONFIG_DM_ETH=y CONFIG_ETH_DESIGNWARE=y From a2ca3c6032d5659665e7985e0a3424d99135d3cf Mon Sep 17 00:00:00 2001 From: Hugh Cole-Baker Date: Sun, 22 Nov 2020 13:03:46 +0000 Subject: [PATCH 02/10] rockchip: puma-haikou: default to SPI bus 1 for SPI-flash SPI flash on this machine is located on bus 1, default to using bus 1 for SPI flash and stop aliasing it to bus 0. Formerly the alias spi1 pointed to &spi5, use an alias spi5 for this instead. Signed-off-by: Hugh Cole-Baker Suggested-by: Kever Yang Reviewed-by: Kever Yang --- arch/arm/dts/rk3399-puma-haikou-u-boot.dtsi | 3 +-- configs/puma-rk3399_defconfig | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm/dts/rk3399-puma-haikou-u-boot.dtsi b/arch/arm/dts/rk3399-puma-haikou-u-boot.dtsi index 29846c4b00..e7a1aea3a5 100644 --- a/arch/arm/dts/rk3399-puma-haikou-u-boot.dtsi +++ b/arch/arm/dts/rk3399-puma-haikou-u-boot.dtsi @@ -28,8 +28,7 @@ }; aliases { - spi0 = &spi1; - spi1 = &spi5; + spi5 = &spi5; }; /* diff --git a/configs/puma-rk3399_defconfig b/configs/puma-rk3399_defconfig index 60178e3754..0f15936c2d 100644 --- a/configs/puma-rk3399_defconfig +++ b/configs/puma-rk3399_defconfig @@ -44,6 +44,7 @@ CONFIG_ENV_OVERWRITE=y CONFIG_ENV_IS_IN_MMC=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_SYS_MMC_ENV_DEV=1 +CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_ROCKCHIP_GPIO=y CONFIG_SYS_I2C_ROCKCHIP=y CONFIG_MISC=y @@ -53,6 +54,7 @@ CONFIG_MMC_DW_ROCKCHIP=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_SDMA=y CONFIG_MMC_SDHCI_ROCKCHIP=y +CONFIG_SF_DEFAULT_BUS=1 CONFIG_SF_DEFAULT_SPEED=20000000 CONFIG_SPI_FLASH_GIGADEVICE=y CONFIG_SPI_FLASH_WINBOND=y From 2a6eb3b8f0f83dba954ed4d34179afd8adbb982d Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Mon, 7 Dec 2020 10:52:51 +0800 Subject: [PATCH 03/10] rockchip: evb-rk3399: Provide init voltage Add missing regulator-init-microvolt property to vdd_center regulator. Signed-off-by: Kever Yang --- arch/arm/dts/rk3399-evb-u-boot.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/dts/rk3399-evb-u-boot.dtsi b/arch/arm/dts/rk3399-evb-u-boot.dtsi index 8056dc843e..523ae78657 100644 --- a/arch/arm/dts/rk3399-evb-u-boot.dtsi +++ b/arch/arm/dts/rk3399-evb-u-boot.dtsi @@ -38,6 +38,10 @@ status = "okay"; }; +&vdd_center { + regulator-init-microvolt = <900000>; +}; + &sdmmc { u-boot,dm-pre-reloc; bus-width = <4>; From ec0f08c779ec23d5ef0fbec9f832a7830786a491 Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Mon, 7 Dec 2020 10:52:52 +0800 Subject: [PATCH 04/10] rockchip: firefly-rk3399: Provide init voltage Add missing regulator-init-microvolt property to vdd_log regulator. Signed-off-by: Kever Yang --- arch/arm/dts/rk3399-firefly-u-boot.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/dts/rk3399-firefly-u-boot.dtsi b/arch/arm/dts/rk3399-firefly-u-boot.dtsi index 38e0897db9..c58ad95d12 100644 --- a/arch/arm/dts/rk3399-firefly-u-boot.dtsi +++ b/arch/arm/dts/rk3399-firefly-u-boot.dtsi @@ -11,3 +11,7 @@ u-boot,spl-boot-order = "same-as-spl", &sdhci, &sdmmc; }; }; + +&vdd_log { + regulator-init-microvolt = <950000>; +}; From 09b053c970344173ac56bc4bf230942b67e3f4f5 Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Mon, 7 Dec 2020 10:52:53 +0800 Subject: [PATCH 05/10] rockchip: leez-rk3399: Provide init voltage Add missing regulator-init-microvolt property to vdd_log regulator. Signed-off-by: Kever Yang --- arch/arm/dts/rk3399-leez-p710-u-boot.dtsi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/dts/rk3399-leez-p710-u-boot.dtsi b/arch/arm/dts/rk3399-leez-p710-u-boot.dtsi index f8b2a1d56e..c638ce2597 100644 --- a/arch/arm/dts/rk3399-leez-p710-u-boot.dtsi +++ b/arch/arm/dts/rk3399-leez-p710-u-boot.dtsi @@ -11,3 +11,7 @@ u-boot,spl-boot-order = "same-as-spl", &sdhci, &sdmmc; }; }; + +&vdd_log { + regulator-init-microvolt = <950000>; +}; From 5972c577809cb62b1bea89266998cc4d6297cea8 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Wed, 16 Dec 2020 15:48:42 +0000 Subject: [PATCH 06/10] arm: dts: rockchip: rk3399: enable rng at the SoC level The rng is embedded in the SoC so enable it in the device tree universally, the use of it can be controlled by enabling/disabling at the device config level. Signed-off-by: Peter Robinson Cc: Kever Yang Reviewed-by: Kever Yang --- arch/arm/dts/rk3399-evb-u-boot.dtsi | 4 ---- arch/arm/dts/rk3399-pinebook-pro-u-boot.dtsi | 4 ---- arch/arm/dts/rk3399-rockpro64-u-boot.dtsi | 4 ---- arch/arm/dts/rk3399-u-boot.dtsi | 2 +- 4 files changed, 1 insertion(+), 13 deletions(-) diff --git a/arch/arm/dts/rk3399-evb-u-boot.dtsi b/arch/arm/dts/rk3399-evb-u-boot.dtsi index 523ae78657..5e39b1493d 100644 --- a/arch/arm/dts/rk3399-evb-u-boot.dtsi +++ b/arch/arm/dts/rk3399-evb-u-boot.dtsi @@ -13,10 +13,6 @@ }; }; -&rng { - status = "okay"; -}; - &i2c0 { u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/rk3399-pinebook-pro-u-boot.dtsi b/arch/arm/dts/rk3399-pinebook-pro-u-boot.dtsi index ee3b98698e..1eafb40ce3 100644 --- a/arch/arm/dts/rk3399-pinebook-pro-u-boot.dtsi +++ b/arch/arm/dts/rk3399-pinebook-pro-u-boot.dtsi @@ -24,10 +24,6 @@ u-boot,dm-pre-reloc; }; -&rng { - status = "okay"; -}; - &sdhci { max-frequency = <25000000>; u-boot,dm-pre-reloc; diff --git a/arch/arm/dts/rk3399-rockpro64-u-boot.dtsi b/arch/arm/dts/rk3399-rockpro64-u-boot.dtsi index 6317b47e41..37dff04adf 100644 --- a/arch/arm/dts/rk3399-rockpro64-u-boot.dtsi +++ b/arch/arm/dts/rk3399-rockpro64-u-boot.dtsi @@ -15,10 +15,6 @@ }; }; -&rng { - status = "okay"; -}; - &spi1 { spi_flash: flash@0 { u-boot,dm-pre-reloc; diff --git a/arch/arm/dts/rk3399-u-boot.dtsi b/arch/arm/dts/rk3399-u-boot.dtsi index ecd230c720..73922c328a 100644 --- a/arch/arm/dts/rk3399-u-boot.dtsi +++ b/arch/arm/dts/rk3399-u-boot.dtsi @@ -32,7 +32,7 @@ rng: rng@ff8b8000 { compatible = "rockchip,cryptov1-rng"; reg = <0x0 0xff8b8000 0x0 0x1000>; - status = "disabled"; + status = "okay"; }; dmc: dmc { From a475bef5340c83663c864512234b7da94bfda265 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Wed, 16 Dec 2020 15:48:43 +0000 Subject: [PATCH 07/10] configs: rk3399: enable rng on firefly/rock960/rockpro64 Enable the RNG on the Firefly, rock960 and RockPro64 devices to enable KASLR on devices that support it. Signed-off-by: Peter Robinson Cc: Akash Gajjar Cc: Jagan Teki Cc: Kever Yang Cc: Manivannan Sadhasivam Reviewed-by: Kever Yang --- configs/firefly-rk3399_defconfig | 2 ++ configs/rock960-rk3399_defconfig | 2 ++ configs/rockpro64-rk3399_defconfig | 2 ++ 3 files changed, 6 insertions(+) diff --git a/configs/firefly-rk3399_defconfig b/configs/firefly-rk3399_defconfig index c453b82dc5..cfbaae40aa 100644 --- a/configs/firefly-rk3399_defconfig +++ b/configs/firefly-rk3399_defconfig @@ -35,6 +35,8 @@ CONFIG_MMC_DW=y CONFIG_MMC_DW_ROCKCHIP=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ROCKCHIP=y +CONFIG_DM_RNG=y +CONFIG_RNG_ROCKCHIP=y CONFIG_SF_DEFAULT_SPEED=20000000 CONFIG_DM_ETH=y CONFIG_ETH_DESIGNWARE=y diff --git a/configs/rock960-rk3399_defconfig b/configs/rock960-rk3399_defconfig index 65dce3cd73..aadbc55f57 100644 --- a/configs/rock960-rk3399_defconfig +++ b/configs/rock960-rk3399_defconfig @@ -39,6 +39,8 @@ CONFIG_MMC_DW_ROCKCHIP=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_SDMA=y CONFIG_MMC_SDHCI_ROCKCHIP=y +CONFIG_DM_RNG=y +CONFIG_RNG_ROCKCHIP=y CONFIG_DM_ETH=y CONFIG_NVME=y CONFIG_PCI=y diff --git a/configs/rockpro64-rk3399_defconfig b/configs/rockpro64-rk3399_defconfig index 575b7a20d5..f78dfcc8f7 100644 --- a/configs/rockpro64-rk3399_defconfig +++ b/configs/rockpro64-rk3399_defconfig @@ -42,6 +42,8 @@ CONFIG_MMC_DW=y CONFIG_MMC_DW_ROCKCHIP=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ROCKCHIP=y +CONFIG_DM_RNG=y +CONFIG_RNG_ROCKCHIP=y CONFIG_SF_DEFAULT_BUS=1 CONFIG_SPI_FLASH_GIGADEVICE=y CONFIG_DM_ETH=y From b821e0db460045664d6e6388612bdf99e9c2e07f Mon Sep 17 00:00:00 2001 From: David Bauer Date: Thu, 7 Jan 2021 00:06:11 +0100 Subject: [PATCH 08/10] rockchip: rk3328: Add support for FriendlyARM NanoPi R2S This adds support for the NanoPi R2S from FriendlyArm. Rockchip RK3328 SoC 1GB DDR4 RAM Gigabit Ethernet (WAN) Gigabit Ethernet (USB3) (LAN) USB 2.0 Host Port MicroSD slot Reset button WAN - LAN - SYS LED Signed-off-by: David Bauer Reviewed-by: Kever Yang --- arch/arm/dts/Makefile | 1 + arch/arm/dts/rk3328-nanopi-r2s-u-boot.dtsi | 40 +++ arch/arm/dts/rk3328-nanopi-r2s.dts | 370 +++++++++++++++++++++ board/rockchip/evb_rk3328/MAINTAINERS | 7 + configs/nanopi-r2s-rk3328_defconfig | 98 ++++++ 5 files changed, 516 insertions(+) create mode 100644 arch/arm/dts/rk3328-nanopi-r2s-u-boot.dtsi create mode 100644 arch/arm/dts/rk3328-nanopi-r2s.dts create mode 100644 configs/nanopi-r2s-rk3328_defconfig diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index e320c2254e..ebdda1a8f2 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -110,6 +110,7 @@ dtb-$(CONFIG_ROCKCHIP_RK3308) += \ dtb-$(CONFIG_ROCKCHIP_RK3328) += \ rk3328-evb.dtb \ + rk3328-nanopi-r2s.dtb \ rk3328-roc-cc.dtb \ rk3328-rock64.dtb \ rk3328-rock-pi-e.dtb diff --git a/arch/arm/dts/rk3328-nanopi-r2s-u-boot.dtsi b/arch/arm/dts/rk3328-nanopi-r2s-u-boot.dtsi new file mode 100644 index 0000000000..9e2ced1541 --- /dev/null +++ b/arch/arm/dts/rk3328-nanopi-r2s-u-boot.dtsi @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2018-2019 Rockchip Electronics Co., Ltd + * (C) Copyright 2020 David Bauer + */ + +#include "rk3328-u-boot.dtsi" +#include "rk3328-sdram-ddr4-666.dtsi" +/ { + chosen { + u-boot,spl-boot-order = "same-as-spl", &sdmmc, &emmc; + }; +}; + +&gpio0 { + u-boot,dm-spl; +}; + +&pinctrl { + u-boot,dm-spl; +}; + +&sdmmc0m1_gpio { + u-boot,dm-spl; +}; + +&pcfg_pull_up_4ma { + u-boot,dm-spl; +}; + +/* Need this and all the pinctrl/gpio stuff above to set pinmux */ +&vcc_sd { + u-boot,dm-spl; +}; + +&gmac2io { + snps,reset-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; + snps,reset-active-low; + snps,reset-delays-us = <0 10000 50000>; +}; diff --git a/arch/arm/dts/rk3328-nanopi-r2s.dts b/arch/arm/dts/rk3328-nanopi-r2s.dts new file mode 100644 index 0000000000..5445c5cb3d --- /dev/null +++ b/arch/arm/dts/rk3328-nanopi-r2s.dts @@ -0,0 +1,370 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 David Bauer + */ + +/dts-v1/; + +#include +#include +#include "rk3328.dtsi" + +/ { + model = "FriendlyElec NanoPi R2S"; + compatible = "friendlyarm,nanopi-r2s", "rockchip,rk3328"; + + chosen { + stdout-path = "serial2:1500000n8"; + }; + + gmac_clk: gmac-clock { + compatible = "fixed-clock"; + clock-frequency = <125000000>; + clock-output-names = "gmac_clkin"; + #clock-cells = <0>; + }; + + keys { + compatible = "gpio-keys"; + pinctrl-0 = <&reset_button_pin>; + pinctrl-names = "default"; + + reset { + label = "reset"; + gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_LOW>; + linux,code = ; + debounce-interval = <50>; + }; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-0 = <&lan_led_pin>, <&sys_led_pin>, <&wan_led_pin>; + pinctrl-names = "default"; + + lan_led: led-0 { + gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>; + label = "nanopi-r2s:green:lan"; + }; + + sys_led: led-1 { + gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>; + label = "nanopi-r2s:red:sys"; + }; + + wan_led: led-2 { + gpios = <&gpio2 RK_PC2 GPIO_ACTIVE_HIGH>; + label = "nanopi-r2s:green:wan"; + }; + }; + + vcc_io_sdio: sdmmcio-regulator { + compatible = "regulator-gpio"; + enable-active-high; + gpios = <&gpio1 RK_PD4 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&sdio_vcc_pin>; + pinctrl-names = "default"; + regulator-name = "vcc_io_sdio"; + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-settling-time-us = <5000>; + regulator-type = "voltage"; + startup-delay-us = <2000>; + states = <1800000 0x1 + 3300000 0x0>; + vin-supply = <&vcc_io_33>; + }; + + vcc_sd: sdmmc-regulator { + compatible = "regulator-fixed"; + gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&sdmmc0m1_gpio>; + pinctrl-names = "default"; + regulator-name = "vcc_sd"; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_io_33>; + }; + + vdd_5v: vdd-5v { + compatible = "regulator-fixed"; + regulator-name = "vdd_5v"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; +}; + +&cpu2 { + cpu-supply = <&vdd_arm>; +}; + +&cpu3 { + cpu-supply = <&vdd_arm>; +}; + +&gmac2io { + assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>; + assigned-clock-parents = <&gmac_clk>, <&gmac_clk>; + clock_in_out = "input"; + phy-handle = <&rtl8211e>; + phy-mode = "rgmii"; + phy-supply = <&vcc_io_33>; + pinctrl-0 = <&rgmiim1_pins>; + pinctrl-names = "default"; + rx_delay = <0x18>; + snps,aal; + tx_delay = <0x24>; + status = "okay"; + + mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + + rtl8211e: ethernet-phy@1 { + compatible = "ethernet-phy-id001c.c915", + "ethernet-phy-ieee802.3-c22"; + reg = <1>; + pinctrl-0 = <ð_phy_reset_pin>; + pinctrl-names = "default"; + reset-assert-us = <10000>; + reset-deassert-us = <50000>; + reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&i2c1 { + status = "okay"; + + rk805: pmic@18 { + compatible = "rockchip,rk805"; + reg = <0x18>; + interrupt-parent = <&gpio1>; + interrupts = <24 IRQ_TYPE_LEVEL_LOW>; + #clock-cells = <1>; + clock-output-names = "xin32k", "rk805-clkout2"; + gpio-controller; + #gpio-cells = <2>; + pinctrl-0 = <&pmic_int_l>; + pinctrl-names = "default"; + rockchip,system-power-controller; + wakeup-source; + + vcc1-supply = <&vdd_5v>; + vcc2-supply = <&vdd_5v>; + vcc3-supply = <&vdd_5v>; + vcc4-supply = <&vdd_5v>; + vcc5-supply = <&vcc_io_33>; + vcc6-supply = <&vdd_5v>; + + regulators { + vdd_log: DCDC_REG1 { + regulator-name = "vdd_log"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1450000>; + regulator-ramp-delay = <12500>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + + vdd_arm: DCDC_REG2 { + regulator-name = "vdd_arm"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1450000>; + regulator-ramp-delay = <12500>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc_ddr: DCDC_REG3 { + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_io_33: DCDC_REG4 { + regulator-name = "vcc_io_33"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_18: LDO_REG1 { + regulator-name = "vcc_18"; + 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>; + }; + }; + + vcc18_emmc: LDO_REG2 { + regulator-name = "vcc18_emmc"; + 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>; + }; + }; + + vdd_10: LDO_REG3 { + regulator-name = "vdd_10"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1000000>; + }; + }; + }; + }; +}; + +&io_domains { + pmuio-supply = <&vcc_io_33>; + vccio1-supply = <&vcc_io_33>; + vccio2-supply = <&vcc18_emmc>; + vccio3-supply = <&vcc_io_sdio>; + vccio4-supply = <&vcc_18>; + vccio5-supply = <&vcc_io_33>; + vccio6-supply = <&vcc_io_33>; + status = "okay"; +}; + +&pinctrl { + button { + reset_button_pin: reset-button-pin { + rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + ethernet-phy { + eth_phy_reset_pin: eth-phy-reset-pin { + rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; + + leds { + lan_led_pin: lan-led-pin { + rockchip,pins = <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + sys_led_pin: sys-led-pin { + rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + wan_led_pin: wan-led-pin { + rockchip,pins = <2 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pmic { + pmic_int_l: pmic-int-l { + rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + sd { + sdio_vcc_pin: sdio-vcc-pin { + rockchip,pins = <1 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; + +&pwm2 { + status = "okay"; +}; + +&sdmmc { + bus-width = <4>; + cap-sd-highspeed; + disable-wp; + pinctrl-0 = <&sdmmc0_clk>, <&sdmmc0_cmd>, <&sdmmc0_dectn>, <&sdmmc0_bus4>; + pinctrl-names = "default"; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vcc_io_sdio>; + status = "okay"; +}; + +&tsadc { + rockchip,hw-tshut-mode = <0>; + rockchip,hw-tshut-polarity = <0>; + status = "okay"; +}; + +&u2phy { + status = "okay"; +}; + +&u2phy_host { + status = "okay"; +}; + +&u2phy_otg { + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&usb20_otg { + status = "okay"; + dr_mode = "host"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; diff --git a/board/rockchip/evb_rk3328/MAINTAINERS b/board/rockchip/evb_rk3328/MAINTAINERS index e7dd59ff4e..14fda46e8f 100644 --- a/board/rockchip/evb_rk3328/MAINTAINERS +++ b/board/rockchip/evb_rk3328/MAINTAINERS @@ -5,6 +5,13 @@ F: board/rockchip/evb_rk3328 F: include/configs/evb_rk3328.h F: configs/evb-rk3328_defconfig +NANOPI-R2S-RK3328 +M: David Bauer +S: Maintained +F: configs/nanopi-r2s-rk3328_defconfig +F: arch/arm/dts/rk3328-nanopi-r2s-u-boot.dtsi +F: arch/arm/dts/rk3328-nanopi-r2s.dts + ROC-RK3328-CC M: Loic Devulder M: Chen-Yu Tsai diff --git a/configs/nanopi-r2s-rk3328_defconfig b/configs/nanopi-r2s-rk3328_defconfig new file mode 100644 index 0000000000..2f67439f78 --- /dev/null +++ b/configs/nanopi-r2s-rk3328_defconfig @@ -0,0 +1,98 @@ +CONFIG_ARM=y +CONFIG_ARCH_ROCKCHIP=y +CONFIG_SYS_TEXT_BASE=0x00200000 +CONFIG_SPL_GPIO_SUPPORT=y +CONFIG_ENV_OFFSET=0x3F8000 +CONFIG_ROCKCHIP_RK3328=y +CONFIG_TPL_ROCKCHIP_COMMON_BOARD=y +CONFIG_TPL_LIBCOMMON_SUPPORT=y +CONFIG_TPL_LIBGENERIC_SUPPORT=y +CONFIG_SPL_DRIVERS_MISC_SUPPORT=y +CONFIG_SPL_STACK_R_ADDR=0x600000 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_DEBUG_UART_BASE=0xFF130000 +CONFIG_DEBUG_UART_CLOCK=24000000 +CONFIG_SYSINFO=y +CONFIG_DEBUG_UART=y +CONFIG_TPL_SYS_MALLOC_F_LEN=0x800 +# CONFIG_ANDROID_BOOT_IMAGE is not set +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_SPL_LOAD_FIT=y +CONFIG_DEFAULT_FDT_FILE="rockchip/rk3328-nanopi-r2s.dtb" +CONFIG_MISC_INIT_R=y +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_DISPLAY_BOARDINFO_LATE=y +# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set +CONFIG_TPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_STACK_R=y +CONFIG_SPL_I2C_SUPPORT=y +CONFIG_SPL_POWER_SUPPORT=y +CONFIG_SPL_ATF=y +CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y +CONFIG_CMD_BOOTZ=y +CONFIG_CMD_GPT=y +CONFIG_CMD_MMC=y +CONFIG_CMD_USB=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_TIME=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_TPL_OF_CONTROL=y +CONFIG_DEFAULT_DEVICE_TREE="rk3328-nanopi-r2s" +CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" +CONFIG_TPL_OF_PLATDATA=y +CONFIG_ENV_IS_IN_MMC=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_TPL_DM=y +CONFIG_REGMAP=y +CONFIG_SPL_REGMAP=y +CONFIG_TPL_REGMAP=y +CONFIG_SYSCON=y +CONFIG_SPL_SYSCON=y +CONFIG_TPL_SYSCON=y +CONFIG_CLK=y +CONFIG_SPL_CLK=y +CONFIG_FASTBOOT_BUF_ADDR=0x800800 +CONFIG_FASTBOOT_CMD_OEM_FORMAT=y +CONFIG_ROCKCHIP_GPIO=y +CONFIG_SYS_I2C_ROCKCHIP=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_ROCKCHIP=y +CONFIG_SF_DEFAULT_SPEED=20000000 +CONFIG_DM_ETH=y +CONFIG_ETH_DESIGNWARE=y +CONFIG_GMAC_ROCKCHIP=y +CONFIG_PINCTRL=y +CONFIG_SPL_PINCTRL=y +CONFIG_DM_PMIC=y +CONFIG_PMIC_RK8XX=y +CONFIG_SPL_DM_REGULATOR=y +CONFIG_REGULATOR_PWM=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_SPL_DM_REGULATOR_FIXED=y +CONFIG_REGULATOR_RK8XX=y +CONFIG_PWM_ROCKCHIP=y +CONFIG_RAM=y +CONFIG_SPL_RAM=y +CONFIG_TPL_RAM=y +CONFIG_DM_RESET=y +CONFIG_BAUDRATE=1500000 +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_SYSRESET=y +# CONFIG_TPL_SYSRESET is not set +CONFIG_USB=y +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_DWC2=y +CONFIG_USB_DWC3=y +# CONFIG_USB_DWC3_GADGET is not set +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_DWC2_OTG=y +CONFIG_SPL_TINY_MEMSET=y +CONFIG_TPL_TINY_MEMSET=y +CONFIG_ERRNO_STR=y From 6ec62b6ca6986196d733383e628e7f5618f4cdd1 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Fri, 15 Jan 2021 18:01:21 +0800 Subject: [PATCH 09/10] phy: rockchip: Add Rockchip Synopsys PCIe 3.0 PHY Add the Rockchip Synopsys based PCIe 3.0 PHY driver as part of Generic PHY framework. Signed-off-by: Shawn Lin Reviewed-by: Simon Glass Reviewed-by: Kever Yang --- drivers/phy/rockchip/Kconfig | 6 + drivers/phy/rockchip/Makefile | 1 + .../phy/rockchip/phy-rockchip-snps-pcie3.c | 157 ++++++++++++++++++ 3 files changed, 164 insertions(+) create mode 100644 drivers/phy/rockchip/phy-rockchip-snps-pcie3.c diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig index 2318e71f35..b794cdaf6a 100644 --- a/drivers/phy/rockchip/Kconfig +++ b/drivers/phy/rockchip/Kconfig @@ -18,6 +18,12 @@ config PHY_ROCKCHIP_PCIE help Enable this to support the Rockchip PCIe PHY. +config PHY_ROCKCHIP_SNPS_PCIE3 + bool "Rockchip Snps PCIe3 PHY Driver" + depends on PHY && ARCH_ROCKCHIP + help + Support for Rockchip PCIe3 PHY with Synopsys IP block. + config PHY_ROCKCHIP_TYPEC bool "Rockchip TYPEC PHY Driver" depends on ARCH_ROCKCHIP diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile index 44049154f9..f6ad3bf59a 100644 --- a/drivers/phy/rockchip/Makefile +++ b/drivers/phy/rockchip/Makefile @@ -5,4 +5,5 @@ obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o +obj-$(CONFIG_PHY_ROCKCHIP_SNPS_PCIE3) += phy-rockchip-snps-pcie3.o obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o diff --git a/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c new file mode 100644 index 0000000000..5ae41fbeee --- /dev/null +++ b/drivers/phy/rockchip/phy-rockchip-snps-pcie3.c @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Rockchip PCIE3.0 phy driver + * + * Copyright (C) 2021 Rockchip Electronics Co., Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GRF_PCIE30PHY_CON1 0x4 +#define GRF_PCIE30PHY_CON6 0x18 +#define GRF_PCIE30PHY_CON9 0x24 + +/** + * struct rockchip_p3phy_priv - RK DW PCIe PHY state + * + * @mmio: The base address of PHY internal registers + * @phy_grf: The regmap for controlling pipe signal + * @p30phy: The reset signal for PHY + * @ref_clk_m: The reference clock of M for PHY + * @ref_clk_n: The reference clock of N for PHY + * @pclk: The clock for accessing PHY blocks + */ +struct rockchip_p3phy_priv { + void __iomem *mmio; + struct regmap *phy_grf; + struct reset_ctl p30phy; + struct clk ref_clk_m; + struct clk ref_clk_n; + struct clk pclk; +}; + +static int rochchip_p3phy_init(struct phy *phy) +{ + struct rockchip_p3phy_priv *priv = dev_get_priv(phy->dev); + int ret; + + ret = clk_enable(&priv->ref_clk_m); + if (ret < 0 && ret != -ENOSYS) + return ret; + + ret = clk_enable(&priv->ref_clk_n); + if (ret < 0 && ret != -ENOSYS) + goto err_ref; + + ret = clk_enable(&priv->pclk); + if (ret < 0 && ret != -ENOSYS) + goto err_pclk; + + reset_assert(&priv->p30phy); + udelay(1); + + /* Deassert PCIe PMA output clamp mode */ + regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON9, + (0x1 << 15) | (0x1 << 31)); + + reset_deassert(&priv->p30phy); + udelay(1); + + return 0; +err_pclk: + clk_disable(&priv->ref_clk_n); +err_ref: + clk_disable(&priv->ref_clk_m); + + return ret; +} + +static int rochchip_p3phy_exit(struct phy *phy) +{ + struct rockchip_p3phy_priv *priv = dev_get_priv(phy->dev); + + clk_disable(&priv->ref_clk_m); + clk_disable(&priv->ref_clk_n); + clk_disable(&priv->pclk); + reset_assert(&priv->p30phy); + + return 0; +} + +static int rockchip_p3phy_probe(struct udevice *dev) +{ + struct rockchip_p3phy_priv *priv = dev_get_priv(dev); + struct udevice *syscon; + int ret; + + priv->mmio = (void __iomem *)dev_read_addr(dev); + if ((fdt_addr_t)priv->mmio == FDT_ADDR_T_NONE) + return -EINVAL; + + ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, + "rockchip,phy-grf", &syscon); + if (ret) { + pr_err("unable to find syscon device for rockchip,phy-grf\n"); + return ret; + } + + priv->phy_grf = syscon_get_regmap(syscon); + if (IS_ERR(priv->phy_grf)) { + dev_err(dev, "failed to find rockchip,phy_grf regmap\n"); + return PTR_ERR(priv->phy_grf); + } + + ret = reset_get_by_name(dev, "phy", &priv->p30phy); + if (ret) { + dev_err(dev, "no phy reset control specified\n"); + return ret; + } + + ret = clk_get_by_name(dev, "refclk_m", &priv->ref_clk_m); + if (ret) { + dev_err(dev, "failed to find ref clock M\n"); + return PTR_ERR(&priv->ref_clk_m); + } + + ret = clk_get_by_name(dev, "refclk_n", &priv->ref_clk_n); + if (ret) { + dev_err(dev, "failed to find ref clock N\n"); + return PTR_ERR(&priv->ref_clk_n); + } + + ret = clk_get_by_name(dev, "pclk", &priv->pclk); + if (ret) { + dev_err(dev, "failed to find pclk\n"); + return PTR_ERR(&priv->pclk); + } + + return 0; +} + +static struct phy_ops rochchip_p3phy_ops = { + .init = rochchip_p3phy_init, + .exit = rochchip_p3phy_exit, +}; + +static const struct udevice_id rockchip_p3phy_of_match[] = { + { .compatible = "rockchip,rk3568-pcie3-phy" }, + { }, +}; + +U_BOOT_DRIVER(rockchip_pcie3phy) = { + .name = "rockchip_pcie3phy", + .id = UCLASS_PHY, + .of_match = rockchip_p3phy_of_match, + .ops = &rochchip_p3phy_ops, + .probe = rockchip_p3phy_probe, + .priv_auto = sizeof(struct rockchip_p3phy_priv), +}; From 9ddc0787bd660214366e386ce689dd78299ac9d0 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Fri, 15 Jan 2021 18:01:22 +0800 Subject: [PATCH 10/10] pci: Add Rockchip dwc based PCIe controller driver Add Rockchip dwc based PCIe controller driver for rk356x platform. Driver support Gen3 by operating as a Root complex. Signed-off-by: Shawn Lin Reviewed-by: Simon Glass Reviewed-by: Kever Yang --- drivers/pci/Kconfig | 9 + drivers/pci/Makefile | 1 + drivers/pci/pcie_dw_rockchip.c | 877 +++++++++++++++++++++++++++++++++ drivers/phy/rockchip/Kconfig | 3 + 4 files changed, 890 insertions(+) create mode 100644 drivers/pci/pcie_dw_rockchip.c diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 65498bce1d..b1de38f766 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -281,6 +281,15 @@ config PCIE_ROCKCHIP Say Y here if you want to enable PCIe controller support on Rockchip SoCs. +config PCIE_DW_ROCKCHIP + bool "Rockchip DesignWare based PCIe controller" + depends on ARCH_ROCKCHIP + select DM_PCI + select PHY_ROCKCHIP_SNPS_PCIE3 + help + Say Y here if you want to enable DW PCIe controller support on + Rockchip SoCs. + config PCI_BRCMSTB bool "Broadcom STB PCIe controller" depends on DM_PCI diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 8b4d49a590..5ed94bc95c 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -48,5 +48,6 @@ obj-$(CONFIG_PCIE_INTEL_FPGA) += pcie_intel_fpga.o obj-$(CONFIG_PCI_KEYSTONE) += pcie_dw_ti.o obj-$(CONFIG_PCIE_MEDIATEK) += pcie_mediatek.o obj-$(CONFIG_PCIE_ROCKCHIP) += pcie_rockchip.o +obj-$(CONFIG_PCIE_DW_ROCKCHIP) += pcie_dw_rockchip.o obj-$(CONFIG_PCI_BRCMSTB) += pcie_brcmstb.o obj-$(CONFIG_PCI_OCTEONTX) += pci_octeontx.o diff --git a/drivers/pci/pcie_dw_rockchip.c b/drivers/pci/pcie_dw_rockchip.c new file mode 100644 index 0000000000..15270627b0 --- /dev/null +++ b/drivers/pci/pcie_dw_rockchip.c @@ -0,0 +1,877 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Rockchip DesignWare based PCIe host controller driver + * + * Copyright (c) 2021 Rockchip, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +/** + * struct rk_pcie - RK DW PCIe controller state + * + * @vpcie3v3: The 3.3v power supply for slot + * @dbi_base: The base address of dwc core regs + * @apb_base: The base address of vendor regs + * @cfg_base: The base address of config header space + * @cfg_size: The size of the configuration space which is needed + * as it gets written into the PCIE_ATU_LIMIT register + * @first_busno: This driver supports multiple PCIe controllers. + * first_busno stores the bus number of the PCIe root-port + * number which may vary depending on the PCIe setup + * (PEX switches etc). + * @rst_gpio: The #PERST signal for slot + * @io: The IO space for EP's BAR + * @mem: The memory space for EP's BAR + */ +struct rk_pcie { + struct udevice *dev; + struct udevice *vpcie3v3; + void *dbi_base; + void *apb_base; + void *cfg_base; + fdt_size_t cfg_size; + struct phy phy; + struct clk_bulk clks; + int first_busno; + struct reset_ctl_bulk rsts; + struct gpio_desc rst_gpio; + struct pci_region io; + struct pci_region mem; +}; + +/* Parameters for the waiting for iATU enabled routine */ +#define PCIE_CLIENT_GENERAL_DEBUG 0x104 +#define PCIE_CLIENT_HOT_RESET_CTRL 0x180 +#define PCIE_LTSSM_ENABLE_ENHANCE BIT(4) +#define PCIE_CLIENT_LTSSM_STATUS 0x300 +#define SMLH_LINKUP BIT(16) +#define RDLH_LINKUP BIT(17) +#define PCIE_CLIENT_DBG_FIFO_MODE_CON 0x310 +#define PCIE_CLIENT_DBG_FIFO_PTN_HIT_D0 0x320 +#define PCIE_CLIENT_DBG_FIFO_PTN_HIT_D1 0x324 +#define PCIE_CLIENT_DBG_FIFO_TRN_HIT_D0 0x328 +#define PCIE_CLIENT_DBG_FIFO_TRN_HIT_D1 0x32c +#define PCIE_CLIENT_DBG_FIFO_STATUS 0x350 +#define PCIE_CLIENT_DBG_TRANSITION_DATA 0xffff0000 +#define PCIE_CLIENT_DBF_EN 0xffff0003 + +/* PCI DBICS registers */ +#define PCIE_LINK_STATUS_REG 0x80 +#define PCIE_LINK_STATUS_SPEED_OFF 16 +#define PCIE_LINK_STATUS_SPEED_MASK (0xf << PCIE_LINK_STATUS_SPEED_OFF) +#define PCIE_LINK_STATUS_WIDTH_OFF 20 +#define PCIE_LINK_STATUS_WIDTH_MASK (0xf << PCIE_LINK_STATUS_WIDTH_OFF) + +#define PCIE_LINK_CAPABILITY 0x7c +#define PCIE_LINK_CTL_2 0xa0 +#define TARGET_LINK_SPEED_MASK 0xf +#define LINK_SPEED_GEN_1 0x1 +#define LINK_SPEED_GEN_2 0x2 +#define LINK_SPEED_GEN_3 0x3 + +#define PCIE_MISC_CONTROL_1_OFF 0x8bc +#define PCIE_DBI_RO_WR_EN BIT(0) + +#define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80c +#define PORT_LOGIC_SPEED_CHANGE BIT(17) + +/* + * iATU Unroll-specific register definitions + * From 4.80 core version the address translation will be made by unroll. + * The registers are offset from atu_base + */ +#define PCIE_ATU_UNR_REGION_CTRL1 0x00 +#define PCIE_ATU_UNR_REGION_CTRL2 0x04 +#define PCIE_ATU_UNR_LOWER_BASE 0x08 +#define PCIE_ATU_UNR_UPPER_BASE 0x0c +#define PCIE_ATU_UNR_LIMIT 0x10 +#define PCIE_ATU_UNR_LOWER_TARGET 0x14 +#define PCIE_ATU_UNR_UPPER_TARGET 0x18 + +#define PCIE_ATU_REGION_INDEX1 (0x1 << 0) +#define PCIE_ATU_REGION_INDEX0 (0x0 << 0) +#define PCIE_ATU_TYPE_MEM (0x0 << 0) +#define PCIE_ATU_TYPE_IO (0x2 << 0) +#define PCIE_ATU_TYPE_CFG0 (0x4 << 0) +#define PCIE_ATU_TYPE_CFG1 (0x5 << 0) +#define PCIE_ATU_ENABLE (0x1 << 31) +#define PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30) +#define PCIE_ATU_BUS(x) (((x) & 0xff) << 24) +#define PCIE_ATU_DEV(x) (((x) & 0x1f) << 19) +#define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16) + +/* Register address builder */ +#define PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(region) \ + ((0x3 << 20) | ((region) << 9)) + +/* Parameters for the waiting for iATU enabled routine */ +#define LINK_WAIT_MAX_IATU_RETRIES 5 +#define LINK_WAIT_IATU_US 10000 + +/* Parameters for the waiting for #perst signal */ +#define PERST_WAIT_MS 1000 + +static int rk_pcie_read(void __iomem *addr, int size, u32 *val) +{ + if ((uintptr_t)addr & (size - 1)) { + *val = 0; + return PCIBIOS_UNSUPPORTED; + } + + if (size == 4) { + *val = readl(addr); + } else if (size == 2) { + *val = readw(addr); + } else if (size == 1) { + *val = readb(addr); + } else { + *val = 0; + return -ENODEV; + } + + return 0; +} + +static int rk_pcie_write(void __iomem *addr, int size, u32 val) +{ + if ((uintptr_t)addr & (size - 1)) + return PCIBIOS_UNSUPPORTED; + + if (size == 4) + writel(val, addr); + else if (size == 2) + writew(val, addr); + else if (size == 1) + writeb(val, addr); + else + return -ENODEV; + + return 0; +} + +static u32 __rk_pcie_read_apb(struct rk_pcie *rk_pcie, void __iomem *base, + u32 reg, size_t size) +{ + int ret; + u32 val; + + ret = rk_pcie_read(base + reg, size, &val); + if (ret) + dev_err(rk_pcie->dev, "Read APB address failed\n"); + + return val; +} + +static void __rk_pcie_write_apb(struct rk_pcie *rk_pcie, void __iomem *base, + u32 reg, size_t size, u32 val) +{ + int ret; + + ret = rk_pcie_write(base + reg, size, val); + if (ret) + dev_err(rk_pcie->dev, "Write APB address failed\n"); +} + +/** + * rk_pcie_readl_apb() - Read vendor regs + * + * @rk_pcie: Pointer to the PCI controller state + * @reg: Offset of regs + */ +static inline u32 rk_pcie_readl_apb(struct rk_pcie *rk_pcie, u32 reg) +{ + return __rk_pcie_read_apb(rk_pcie, rk_pcie->apb_base, reg, 0x4); +} + +/** + * rk_pcie_writel_apb() - Write vendor regs + * + * @rk_pcie: Pointer to the PCI controller state + * @reg: Offset of regs + * @val: Value to be writen + */ +static inline void rk_pcie_writel_apb(struct rk_pcie *rk_pcie, u32 reg, + u32 val) +{ + __rk_pcie_write_apb(rk_pcie, rk_pcie->apb_base, reg, 0x4, val); +} + +static int rk_pcie_get_link_speed(struct rk_pcie *rk_pcie) +{ + return (readl(rk_pcie->dbi_base + PCIE_LINK_STATUS_REG) & + PCIE_LINK_STATUS_SPEED_MASK) >> PCIE_LINK_STATUS_SPEED_OFF; +} + +static int rk_pcie_get_link_width(struct rk_pcie *rk_pcie) +{ + return (readl(rk_pcie->dbi_base + PCIE_LINK_STATUS_REG) & + PCIE_LINK_STATUS_WIDTH_MASK) >> PCIE_LINK_STATUS_WIDTH_OFF; +} + +static void rk_pcie_writel_ob_unroll(struct rk_pcie *rk_pcie, u32 index, + u32 reg, u32 val) +{ + u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index); + void __iomem *base = rk_pcie->dbi_base; + + writel(val, base + offset + reg); +} + +static u32 rk_pcie_readl_ob_unroll(struct rk_pcie *rk_pcie, u32 index, u32 reg) +{ + u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index); + void __iomem *base = rk_pcie->dbi_base; + + return readl(base + offset + reg); +} + +static inline void rk_pcie_dbi_write_enable(struct rk_pcie *rk_pcie, bool en) +{ + u32 val; + + val = readl(rk_pcie->dbi_base + PCIE_MISC_CONTROL_1_OFF); + + if (en) + val |= PCIE_DBI_RO_WR_EN; + else + val &= ~PCIE_DBI_RO_WR_EN; + writel(val, rk_pcie->dbi_base + PCIE_MISC_CONTROL_1_OFF); +} + +/** + * rockchip_pcie_setup_host() - Setup the PCIe controller for RC opertaion + * + * @rk_pcie: Pointer to the PCI controller state + * + * Configure the host BARs of the PCIe controller root port so that + * PCI(e) devices may access the system memory. + */ +static void rk_pcie_setup_host(struct rk_pcie *rk_pcie) +{ + u32 val; + + rk_pcie_dbi_write_enable(rk_pcie, true); + + /* setup RC BARs */ + writel(PCI_BASE_ADDRESS_MEM_TYPE_64, + rk_pcie->dbi_base + PCI_BASE_ADDRESS_0); + writel(0x0, rk_pcie->dbi_base + PCI_BASE_ADDRESS_1); + + /* setup interrupt pins */ + clrsetbits_le32(rk_pcie->dbi_base + PCI_INTERRUPT_LINE, + 0xff00, 0x100); + + /* setup bus numbers */ + clrsetbits_le32(rk_pcie->dbi_base + PCI_PRIMARY_BUS, + 0xffffff, 0x00ff0100); + + /* setup command register */ + clrsetbits_le32(rk_pcie->dbi_base + PCI_PRIMARY_BUS, + 0xffff, + PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER | PCI_COMMAND_SERR); + + /* program correct class for RC */ + writew(PCI_CLASS_BRIDGE_PCI, rk_pcie->dbi_base + PCI_CLASS_DEVICE); + /* Better disable write permission right after the update */ + + setbits_le32(rk_pcie->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL, + PORT_LOGIC_SPEED_CHANGE) + + rk_pcie_dbi_write_enable(rk_pcie, false); +} + +/** + * rk_pcie_configure() - Configure link capabilities and speed + * + * @rk_pcie: Pointer to the PCI controller state + * @cap_speed: The capabilities and speed to configure + * + * Configure the link capabilities and speed in the PCIe root complex. + */ +static void rk_pcie_configure(struct rk_pcie *pci, u32 cap_speed) +{ + u32 val; + + rk_pcie_dbi_write_enable(pci, true); + + clrsetbits_le32(pci->dbi_base + PCIE_LINK_CAPABILITY, + TARGET_LINK_SPEED_MASK, cap_speed); + + clrsetbits_le32(pci->dbi_base + PCIE_LINK_CTL_2, + TARGET_LINK_SPEED_MASK, cap_speed); + + rk_pcie_dbi_write_enable(pci, false); +} + +/** + * rk_pcie_dw_prog_outbound_atu_unroll() - Configure ATU for outbound accesses + * + * @rk_pcie: Pointer to the PCI controller state + * @index: ATU region index + * @type: ATU accsess type + * @cpu_addr: the physical address for the translation entry + * @pci_addr: the pcie bus address for the translation entry + * @size: the size of the translation entry + * + * Return: 0 is successful and -1 is failure + */ +static int rk_pcie_prog_outbound_atu_unroll(struct rk_pcie *pci, int index, + int type, u64 cpu_addr, + u64 pci_addr, u32 size) +{ + u32 retries, val; + + dev_dbg(pci->dev, "ATU programmed with: index: %d, type: %d, cpu addr: %8llx, pci addr: %8llx, size: %8x\n", + index, type, cpu_addr, pci_addr, size); + + rk_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_LOWER_BASE, + lower_32_bits(cpu_addr)); + rk_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_UPPER_BASE, + upper_32_bits(cpu_addr)); + rk_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_LIMIT, + lower_32_bits(cpu_addr + size - 1)); + rk_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_LOWER_TARGET, + lower_32_bits(pci_addr)); + rk_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_UPPER_TARGET, + upper_32_bits(pci_addr)); + rk_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL1, + type); + rk_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL2, + PCIE_ATU_ENABLE); + + /* + * Make sure ATU enable takes effect before any subsequent config + * and I/O accesses. + */ + for (retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; retries++) { + val = rk_pcie_readl_ob_unroll(pci, index, + PCIE_ATU_UNR_REGION_CTRL2); + if (val & PCIE_ATU_ENABLE) + return 0; + + udelay(LINK_WAIT_IATU_US); + } + dev_err(pci->dev, "outbound iATU is not being enabled\n"); + + return -1; +} + +/** + * rk_pcie_dw_addr_valid() - Check for valid bus address + * + * @d: The PCI device to access + * @first_busno: Bus number of the PCIe controller root complex + * + * Return 1 (true) if the PCI device can be accessed by this controller. + * + * Return: 1 on valid, 0 on invalid + */ +static int rk_pcie_addr_valid(pci_dev_t d, int first_busno) +{ + if ((PCI_BUS(d) == first_busno) && (PCI_DEV(d) > 0)) + return 0; + if ((PCI_BUS(d) == first_busno + 1) && (PCI_DEV(d) > 0)) + return 0; + + return 1; +} + +/** + * set_cfg_address() - Configure the PCIe controller config space access + * + * @rk_pcie: Pointer to the PCI controller state + * @d: PCI device to access + * @where: Offset in the configuration space + * + * Configures the PCIe controller to access the configuration space of + * a specific PCIe device and returns the address to use for this + * access. + * + * Return: Address that can be used to access the configation space + * of the requested device / offset + */ +static uintptr_t set_cfg_address(struct rk_pcie *pcie, + pci_dev_t d, uint where) +{ + int rel_bus = PCI_BUS(d) - pcie->first_busno; + uintptr_t va_address; + u32 atu_type; + int ret; + + /* Use dbi_base for own configuration read and write */ + if (!rel_bus) { + va_address = (uintptr_t)pcie->dbi_base; + goto out; + } + + if (rel_bus == 1) + /* + * For local bus whose primary bus number is root bridge, + * change TLP Type field to 4. + */ + atu_type = PCIE_ATU_TYPE_CFG0; + else + /* Otherwise, change TLP Type field to 5. */ + atu_type = PCIE_ATU_TYPE_CFG1; + + /* + * Not accessing root port configuration space? + * Region #0 is used for Outbound CFG space access. + * Direction = Outbound + * Region Index = 0 + */ + d = PCI_MASK_BUS(d); + d = PCI_ADD_BUS(rel_bus, d); + ret = rk_pcie_prog_outbound_atu_unroll(pcie, PCIE_ATU_REGION_INDEX1, + atu_type, (u64)pcie->cfg_base, + d << 8, pcie->cfg_size); + if (ret) + return (uintptr_t)ret; + + va_address = (uintptr_t)pcie->cfg_base; + +out: + va_address += where & ~0x3; + + return va_address; +} + +/** + * rockchip_pcie_rd_conf() - Read from configuration space + * + * @bus: Pointer to the PCI bus + * @bdf: Identifies the PCIe device to access + * @offset: The offset into the device's configuration space + * @valuep: A pointer at which to store the read value + * @size: Indicates the size of access to perform + * + * Read a value of size @size from offset @offset within the configuration + * space of the device identified by the bus, device & function numbers in @bdf + * on the PCI bus @bus. + * + * Return: 0 on success + */ +static int rockchip_pcie_rd_conf(const struct udevice *bus, pci_dev_t bdf, + uint offset, ulong *valuep, + enum pci_size_t size) +{ + struct rk_pcie *pcie = dev_get_priv(bus); + uintptr_t va_address; + ulong value; + + debug("PCIE CFG read: bdf=%2x:%2x:%2x\n", + PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf)); + + if (!rk_pcie_addr_valid(bdf, pcie->first_busno)) { + debug("- out of range\n"); + *valuep = pci_get_ff(size); + return 0; + } + + va_address = set_cfg_address(pcie, bdf, offset); + + value = readl(va_address); + + debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, value); + *valuep = pci_conv_32_to_size(value, offset, size); + + return rk_pcie_prog_outbound_atu_unroll(pcie, + PCIE_ATU_REGION_INDEX1, + PCIE_ATU_TYPE_IO, + pcie->io.phys_start, + pcie->io.bus_start, + pcie->io.size); +} + +/** + * rockchip_pcie_wr_conf() - Write to configuration space + * + * @bus: Pointer to the PCI bus + * @bdf: Identifies the PCIe device to access + * @offset: The offset into the device's configuration space + * @value: The value to write + * @size: Indicates the size of access to perform + * + * Write the value @value of size @size from offset @offset within the + * configuration space of the device identified by the bus, device & function + * numbers in @bdf on the PCI bus @bus. + * + * Return: 0 on success + */ +static int rockchip_pcie_wr_conf(struct udevice *bus, pci_dev_t bdf, + uint offset, ulong value, + enum pci_size_t size) +{ + struct rk_pcie *pcie = dev_get_priv(bus); + uintptr_t va_address; + ulong old; + + debug("PCIE CFG write: (b,d,f)=(%2d,%2d,%2d)\n", + PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf)); + debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, value); + + if (!rk_pcie_addr_valid(bdf, pcie->first_busno)) { + debug("- out of range\n"); + return 0; + } + + va_address = set_cfg_address(pcie, bdf, offset); + + old = readl(va_address); + value = pci_conv_size_to_32(old, value, offset, size); + writel(value, va_address); + + return rk_pcie_prog_outbound_atu_unroll(pcie, + PCIE_ATU_REGION_INDEX1, + PCIE_ATU_TYPE_IO, + pcie->io.phys_start, + pcie->io.bus_start, + pcie->io.size); + +} + +static void rk_pcie_enable_debug(struct rk_pcie *rk_pcie) +{ + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_PTN_HIT_D0, + PCIE_CLIENT_DBG_TRANSITION_DATA); + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_PTN_HIT_D1, + PCIE_CLIENT_DBG_TRANSITION_DATA); + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_TRN_HIT_D0, + PCIE_CLIENT_DBG_TRANSITION_DATA); + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_TRN_HIT_D1, + PCIE_CLIENT_DBG_TRANSITION_DATA); + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_MODE_CON, + PCIE_CLIENT_DBF_EN); +} + +static void rk_pcie_debug_dump(struct rk_pcie *rk_pcie) +{ + u32 loop; + + debug("ltssm = 0x%x\n", + rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS)); + for (loop = 0; loop < 64; loop++) + debug("fifo_status = 0x%x\n", + rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_STATUS)); +} + +static inline void rk_pcie_link_status_clear(struct rk_pcie *rk_pcie) +{ + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_GENERAL_DEBUG, 0x0); +} + +static inline void rk_pcie_disable_ltssm(struct rk_pcie *rk_pcie) +{ + rk_pcie_writel_apb(rk_pcie, 0x0, 0xc0008); +} + +static inline void rk_pcie_enable_ltssm(struct rk_pcie *rk_pcie) +{ + rk_pcie_writel_apb(rk_pcie, 0x0, 0xc000c); +} + +static int is_link_up(struct rk_pcie *priv) +{ + u32 val; + + val = rk_pcie_readl_apb(priv, PCIE_CLIENT_LTSSM_STATUS); + if ((val & (RDLH_LINKUP | SMLH_LINKUP)) == 0x30000 && + (val & GENMASK(5, 0)) == 0x11) + return 1; + + return 0; +} + +/** + * rk_pcie_link_up() - Wait for the link to come up + * + * @rk_pcie: Pointer to the PCI controller state + * @cap_speed: Desired link speed + * + * Return: 1 (true) for active line and negetive (false) for no link (timeout) + */ +static int rk_pcie_link_up(struct rk_pcie *priv, u32 cap_speed) +{ + int retries; + + if (is_link_up(priv)) { + printf("PCI Link already up before configuration!\n"); + return 1; + } + + /* DW pre link configurations */ + rk_pcie_configure(priv, cap_speed); + + /* Rest the device */ + if (dm_gpio_is_valid(&priv->rst_gpio)) { + dm_gpio_set_value(&priv->rst_gpio, 0); + /* + * Minimal is 100ms from spec but we see + * some wired devices need much more, such as 600ms. + * Add a enough delay to cover all cases. + */ + msleep(PERST_WAIT_MS); + dm_gpio_set_value(&priv->rst_gpio, 1); + } + + rk_pcie_disable_ltssm(priv); + rk_pcie_link_status_clear(priv); + rk_pcie_enable_debug(priv); + + /* Enable LTSSM */ + rk_pcie_enable_ltssm(priv); + + for (retries = 0; retries < 5; retries++) { + if (is_link_up(priv)) { + dev_info(priv->dev, "PCIe Link up, LTSSM is 0x%x\n", + rk_pcie_readl_apb(priv, PCIE_CLIENT_LTSSM_STATUS)); + rk_pcie_debug_dump(priv); + return 0; + } + + dev_info(priv->dev, "PCIe Linking... LTSSM is 0x%x\n", + rk_pcie_readl_apb(priv, PCIE_CLIENT_LTSSM_STATUS)); + rk_pcie_debug_dump(priv); + msleep(1000); + } + + dev_err(priv->dev, "PCIe-%d Link Fail\n", dev_seq(priv->dev)); + /* Link maybe in Gen switch recovery but we need to wait more 1s */ + msleep(1000); + return -EIO; +} + +static int rockchip_pcie_init_port(struct udevice *dev) +{ + int ret; + u32 val; + struct rk_pcie *priv = dev_get_priv(dev); + + /* Set power and maybe external ref clk input */ + if (priv->vpcie3v3) { + ret = regulator_set_value(priv->vpcie3v3, 3300000); + if (ret) { + dev_err(priv->dev, "failed to enable vpcie3v3 (ret=%d)\n", + ret); + return ret; + } + } + + msleep(1000); + + ret = generic_phy_init(&priv->phy); + if (ret) { + dev_err(dev, "failed to init phy (ret=%d)\n", ret); + return ret; + } + + ret = generic_phy_power_on(&priv->phy); + if (ret) { + dev_err(dev, "failed to power on phy (ret=%d)\n", ret); + goto err_exit_phy; + } + + ret = reset_deassert_bulk(&priv->rsts); + if (ret) { + dev_err(dev, "failed to deassert resets (ret=%d)\n", ret); + goto err_power_off_phy; + } + + ret = clk_enable_bulk(&priv->clks); + if (ret) { + dev_err(dev, "failed to enable clks (ret=%d)\n", ret); + goto err_deassert_bulk; + } + + /* LTSSM EN ctrl mode */ + val = rk_pcie_readl_apb(priv, PCIE_CLIENT_HOT_RESET_CTRL); + val |= PCIE_LTSSM_ENABLE_ENHANCE | (PCIE_LTSSM_ENABLE_ENHANCE << 16); + rk_pcie_writel_apb(priv, PCIE_CLIENT_HOT_RESET_CTRL, val); + + /* Set RC mode */ + rk_pcie_writel_apb(priv, 0x0, 0xf00040); + rk_pcie_setup_host(priv); + + ret = rk_pcie_link_up(priv, LINK_SPEED_GEN_3); + if (ret < 0) + goto err_link_up; + + return 0; +err_link_up: + clk_disable_bulk(&priv->clks); +err_deassert_bulk: + reset_assert_bulk(&priv->rsts); +err_power_off_phy: + generic_phy_power_off(&priv->phy); +err_exit_phy: + generic_phy_exit(&priv->phy); + + return ret; +} + +static int rockchip_pcie_parse_dt(struct udevice *dev) +{ + struct rk_pcie *priv = dev_get_priv(dev); + int ret; + + priv->dbi_base = (void *)dev_read_addr_index(dev, 0); + if (!priv->dbi_base) + return -ENODEV; + + dev_dbg(dev, "DBI address is 0x%p\n", priv->dbi_base); + + priv->apb_base = (void *)dev_read_addr_index(dev, 1); + if (!priv->apb_base) + return -ENODEV; + + dev_dbg(dev, "APB address is 0x%p\n", priv->apb_base); + + ret = gpio_request_by_name(dev, "reset-gpios", 0, + &priv->rst_gpio, GPIOD_IS_OUT); + if (ret) { + dev_err(dev, "failed to find reset-gpios property\n"); + return ret; + } + + ret = reset_get_bulk(dev, &priv->rsts); + if (ret) { + dev_err(dev, "Can't get reset: %d\n", ret); + return ret; + } + + ret = clk_get_bulk(dev, &priv->clks); + if (ret) { + dev_err(dev, "Can't get clock: %d\n", ret); + return ret; + } + + ret = device_get_supply_regulator(dev, "vpcie3v3-supply", + &priv->vpcie3v3); + if (ret && ret != -ENOENT) { + dev_err(dev, "failed to get vpcie3v3 supply (ret=%d)\n", ret); + return ret; + } + + ret = generic_phy_get_by_index(dev, 0, &priv->phy); + if (ret) { + dev_err(dev, "failed to get pcie phy (ret=%d)\n", ret); + return ret; + } + + return 0; +} + +/** + * rockchip_pcie_probe() - Probe the PCIe bus for active link + * + * @dev: A pointer to the device being operated on + * + * Probe for an active link on the PCIe bus and configure the controller + * to enable this port. + * + * Return: 0 on success, else -ENODEV + */ +static int rockchip_pcie_probe(struct udevice *dev) +{ + struct rk_pcie *priv = dev_get_priv(dev); + struct udevice *ctlr = pci_get_controller(dev); + struct pci_controller *hose = dev_get_uclass_priv(ctlr); + int reti = 0; + + priv->first_busno = dev_seq(dev); + priv->dev = dev; + + ret = rockchip_pcie_parse_dt(dev); + if (ret) + return ret; + + ret = rockchip_pcie_init_port(dev); + if (ret) + return ret; + + dev_info(dev, "PCIE-%d: Link up (Gen%d-x%d, Bus%d)\n", + dev_seq(dev), rk_pcie_get_link_speed(priv), + rk_pcie_get_link_width(priv), + hose->first_busno); + + for (ret = 0; ret < hose->region_count; ret++) { + if (hose->regions[ret].flags == PCI_REGION_IO) { + priv->io.phys_start = hose->regions[ret].phys_start; /* IO base */ + priv->io.bus_start = hose->regions[ret].bus_start; /* IO_bus_addr */ + priv->io.size = hose->regions[ret].size; /* IO size */ + } else if (hose->regions[ret].flags == PCI_REGION_MEM) { + priv->mem.phys_start = hose->regions[ret].phys_start; /* MEM base */ + priv->mem.bus_start = hose->regions[ret].bus_start; /* MEM_bus_addr */ + priv->mem.size = hose->regions[ret].size; /* MEM size */ + } else if (hose->regions[ret].flags == PCI_REGION_SYS_MEMORY) { + priv->cfg_base = (void *)(priv->io.phys_start - priv->io.size); + priv->cfg_size = priv->io.size; + } else { + dev_err(dev, "invalid flags type!\n"); + } + } + + dev_dbg(dev, "Config space: [0x%p - 0x%p, size 0x%llx]\n", + priv->cfg_base, priv->cfg_base + priv->cfg_size, + priv->cfg_size); + + dev_dbg(dev, "IO space: [0x%llx - 0x%llx, size 0x%lx]\n", + priv->io.phys_start, priv->io.phys_start + priv->io.size, + priv->io.size); + + dev_dbg(dev, "IO bus: [0x%lx - 0x%lx, size 0x%lx]\n", + priv->io.bus_start, priv->io.bus_start + priv->io.size, + priv->io.size); + + dev_dbg(dev, "MEM space: [0x%llx - 0x%llx, size 0x%lx]\n", + priv->mem.phys_start, priv->mem.phys_start + priv->mem.size, + priv->mem.size); + + dev_dbg(dev, "MEM bus: [0x%lx - 0x%lx, size 0x%lx]\n", + priv->mem.bus_start, priv->mem.bus_start + priv->mem.size, + priv->mem.size); + + return rk_pcie_prog_outbound_atu_unroll(priv, + PCIE_ATU_REGION_INDEX0, + PCIE_ATU_TYPE_MEM, + priv->mem.phys_start, + priv->mem.bus_start, + priv->mem.size); +} + +static const struct dm_pci_ops rockchip_pcie_ops = { + .read_config = rockchip_pcie_rd_conf, + .write_config = rockchip_pcie_wr_conf, +}; + +static const struct udevice_id rockchip_pcie_ids[] = { + { .compatible = "rockchip,rk3568-pcie" }, + { } +}; + +U_BOOT_DRIVER(rockchip_dw_pcie) = { + .name = "pcie_dw_rockchip", + .id = UCLASS_PCI, + .of_match = rockchip_pcie_ids, + .ops = &rockchip_pcie_ops, + .probe = rockchip_pcie_probe, + .priv_auto = sizeof(struct rk_pcie), +}; diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig index b794cdaf6a..e477a6cd9e 100644 --- a/drivers/phy/rockchip/Kconfig +++ b/drivers/phy/rockchip/Kconfig @@ -23,6 +23,9 @@ config PHY_ROCKCHIP_SNPS_PCIE3 depends on PHY && ARCH_ROCKCHIP help Support for Rockchip PCIe3 PHY with Synopsys IP block. + It could support PCIe Gen3 single root complex, and could + also be able splited into multiple combinations of lanes. + config PHY_ROCKCHIP_TYPEC bool "Rockchip TYPEC PHY Driver"