From 6393357c53a8080cd9fb7e77bf7f0683a544379f Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Wed, 6 May 2020 13:06:56 +0200 Subject: [PATCH 01/15] board: puma: use dtb given on the commandline instead of using u-boot.dtb The make_fit_spl scripts get the dtb to use as commandline option, so use it for puma as well. Signed-off-by: Heiko Stuebner --- board/theobroma-systems/puma_rk3399/fit_spl_atf.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board/theobroma-systems/puma_rk3399/fit_spl_atf.sh b/board/theobroma-systems/puma_rk3399/fit_spl_atf.sh index 420e7daf4c..c9396577a9 100755 --- a/board/theobroma-systems/puma_rk3399/fit_spl_atf.sh +++ b/board/theobroma-systems/puma_rk3399/fit_spl_atf.sh @@ -69,7 +69,7 @@ cat << __HEADER_EOF }; fdt { description = "RK3399-Q7 (Puma) flat device-tree"; - data = /incbin/("u-boot.dtb"); + data = /incbin/("$1"); type = "flat_dt"; compression = "none"; }; From 5c606ca35c421faf42499f78ce4a4e7745d53df6 Mon Sep 17 00:00:00 2001 From: Deepak Das Date: Wed, 15 Apr 2020 08:55:24 +0530 Subject: [PATCH 02/15] rockchip: rk3399: enable spl-fifo-mode for sdmmc adapting commit fa2047c47310 ("rockchip: rk3328: enable spl-fifo-mode for emmc and sdmmc") for rk3399. Since mmc to sram can't do dma, add patch to prevent aborts transferring TF-A parts. Signed-off-by: Deepak Das --- arch/arm/dts/rk3399-u-boot.dtsi | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/dts/rk3399-u-boot.dtsi b/arch/arm/dts/rk3399-u-boot.dtsi index 9bb130a92a..22017ecd60 100644 --- a/arch/arm/dts/rk3399-u-boot.dtsi +++ b/arch/arm/dts/rk3399-u-boot.dtsi @@ -91,6 +91,9 @@ &sdmmc { u-boot,dm-pre-reloc; + + /* mmc to sram can't do dma, prevent aborts transferring TF-A parts */ + u-boot,spl-fifo-mode; }; &spi1 { From 1266ef105f671b41b7e3e77bf68c7564e355995e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Fri, 24 Apr 2020 22:03:29 +0100 Subject: [PATCH 03/15] rockpro64: Enable HDMI output on rockpro64 board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reference to commit that adds HDMI to other rk3399 boards: commit 9778edae5576 ("rockchip: Enable HDMI output on rk3399 board w/ HDMI") Signed-off-by: Andrius Štikonas Cc: Manivannan Sadhasivam Cc: Jagan Teki Cc: Kever Yang Tested-by: Mark Kettenis Reviewed-by: Jagan Teki Reviewed-by: Kever Yang --- configs/rockpro64-rk3399_defconfig | 7 +++++++ include/configs/rockpro64_rk3399.h | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/configs/rockpro64-rk3399_defconfig b/configs/rockpro64-rk3399_defconfig index 8074e4665a..53abce0057 100644 --- a/configs/rockpro64-rk3399_defconfig +++ b/configs/rockpro64-rk3399_defconfig @@ -58,5 +58,12 @@ CONFIG_USB_ETHER_ASIX88179=y CONFIG_USB_ETHER_MCS7830=y CONFIG_USB_ETHER_RTL8152=y CONFIG_USB_ETHER_SMSC95XX=y +CONFIG_USB_KEYBOARD=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_HDMI=y diff --git a/include/configs/rockpro64_rk3399.h b/include/configs/rockpro64_rk3399.h index 5f52c1e4f6..7a72cf6049 100644 --- a/include/configs/rockpro64_rk3399.h +++ b/include/configs/rockpro64_rk3399.h @@ -6,6 +6,11 @@ #ifndef __ROCKPRO64_RK3399_H #define __ROCKPRO64_RK3399_H +#define ROCKCHIP_DEVICE_SETTINGS \ + "stdin=serial,usbkbd\0" \ + "stdout=serial,vidconsole\0" \ + "stderr=serial,vidconsole\0" + #include #define CONFIG_SYS_MMC_ENV_DEV 0 From 30d09a2f17e82cb893dc3720490f4bed0fb225db Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Sat, 9 May 2020 22:26:19 +0530 Subject: [PATCH 04/15] clk: rk3399: Add enable/disable clks Yes, most of the high speed peripheral clocks in rk3399 enabled by default. But it would be better to handle them via clk enable/disable API for handling proper reset conditions like 'usb reset' over command line. So, enable USB, GMAC clock via enable/disable ops. Signed-off-by: Jagan Teki Tested-by: Suniel Mahesh # roc-rk3399-pc Tested-by: Suniel Mahesh #roc-rk3399-pc Reviewed-by: Kever Yang --- drivers/clk/rockchip/clk_rk3399.c | 148 ++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c index e009f1cf6c..371410d9a9 100644 --- a/drivers/clk/rockchip/clk_rk3399.c +++ b/drivers/clk/rockchip/clk_rk3399.c @@ -1074,12 +1074,160 @@ static int __maybe_unused rk3399_clk_set_parent(struct clk *clk, return -ENOENT; } +static int rk3399_clk_enable(struct clk *clk) +{ + struct rk3399_clk_priv *priv = dev_get_priv(clk->dev); + + switch (clk->id) { + case SCLK_MAC: + rk_clrreg(&priv->cru->clkgate_con[5], BIT(5)); + break; + case SCLK_MAC_RX: + rk_clrreg(&priv->cru->clkgate_con[5], BIT(8)); + break; + case SCLK_MAC_TX: + rk_clrreg(&priv->cru->clkgate_con[5], BIT(9)); + break; + case SCLK_MACREF: + rk_clrreg(&priv->cru->clkgate_con[5], BIT(7)); + break; + case SCLK_MACREF_OUT: + rk_clrreg(&priv->cru->clkgate_con[5], BIT(6)); + break; + case ACLK_GMAC: + rk_clrreg(&priv->cru->clkgate_con[32], BIT(0)); + break; + case PCLK_GMAC: + rk_clrreg(&priv->cru->clkgate_con[32], BIT(2)); + break; + case SCLK_USB3OTG0_REF: + rk_clrreg(&priv->cru->clkgate_con[12], BIT(1)); + break; + case SCLK_USB3OTG1_REF: + rk_clrreg(&priv->cru->clkgate_con[12], BIT(2)); + break; + case SCLK_USB3OTG0_SUSPEND: + rk_clrreg(&priv->cru->clkgate_con[12], BIT(3)); + break; + case SCLK_USB3OTG1_SUSPEND: + rk_clrreg(&priv->cru->clkgate_con[12], BIT(4)); + break; + case ACLK_USB3OTG0: + rk_clrreg(&priv->cru->clkgate_con[30], BIT(1)); + break; + case ACLK_USB3OTG1: + rk_clrreg(&priv->cru->clkgate_con[30], BIT(2)); + break; + case ACLK_USB3_RKSOC_AXI_PERF: + rk_clrreg(&priv->cru->clkgate_con[30], BIT(3)); + break; + case ACLK_USB3: + rk_clrreg(&priv->cru->clkgate_con[12], BIT(0)); + break; + case ACLK_USB3_GRF: + rk_clrreg(&priv->cru->clkgate_con[30], BIT(4)); + break; + case HCLK_HOST0: + rk_clrreg(&priv->cru->clksel_con[20], BIT(5)); + break; + case HCLK_HOST0_ARB: + rk_clrreg(&priv->cru->clksel_con[20], BIT(6)); + break; + case HCLK_HOST1: + rk_clrreg(&priv->cru->clksel_con[20], BIT(7)); + break; + case HCLK_HOST1_ARB: + rk_clrreg(&priv->cru->clksel_con[20], BIT(8)); + break; + default: + debug("%s: unsupported clk %ld\n", __func__, clk->id); + return -ENOENT; + } + + return 0; +} + +static int rk3399_clk_disable(struct clk *clk) +{ + struct rk3399_clk_priv *priv = dev_get_priv(clk->dev); + + switch (clk->id) { + case SCLK_MAC: + rk_setreg(&priv->cru->clkgate_con[5], BIT(5)); + break; + case SCLK_MAC_RX: + rk_setreg(&priv->cru->clkgate_con[5], BIT(8)); + break; + case SCLK_MAC_TX: + rk_setreg(&priv->cru->clkgate_con[5], BIT(9)); + break; + case SCLK_MACREF: + rk_setreg(&priv->cru->clkgate_con[5], BIT(7)); + break; + case SCLK_MACREF_OUT: + rk_setreg(&priv->cru->clkgate_con[5], BIT(6)); + break; + case ACLK_GMAC: + rk_setreg(&priv->cru->clkgate_con[32], BIT(0)); + break; + case PCLK_GMAC: + rk_setreg(&priv->cru->clkgate_con[32], BIT(2)); + break; + case SCLK_USB3OTG0_REF: + rk_setreg(&priv->cru->clkgate_con[12], BIT(1)); + break; + case SCLK_USB3OTG1_REF: + rk_setreg(&priv->cru->clkgate_con[12], BIT(2)); + break; + case SCLK_USB3OTG0_SUSPEND: + rk_setreg(&priv->cru->clkgate_con[12], BIT(3)); + break; + case SCLK_USB3OTG1_SUSPEND: + rk_setreg(&priv->cru->clkgate_con[12], BIT(4)); + break; + case ACLK_USB3OTG0: + rk_setreg(&priv->cru->clkgate_con[30], BIT(1)); + break; + case ACLK_USB3OTG1: + rk_setreg(&priv->cru->clkgate_con[30], BIT(2)); + break; + case ACLK_USB3_RKSOC_AXI_PERF: + rk_setreg(&priv->cru->clkgate_con[30], BIT(3)); + break; + case ACLK_USB3: + rk_setreg(&priv->cru->clkgate_con[12], BIT(0)); + break; + case ACLK_USB3_GRF: + rk_setreg(&priv->cru->clkgate_con[30], BIT(4)); + break; + case HCLK_HOST0: + rk_setreg(&priv->cru->clksel_con[20], BIT(5)); + break; + case HCLK_HOST0_ARB: + rk_setreg(&priv->cru->clksel_con[20], BIT(6)); + break; + case HCLK_HOST1: + rk_setreg(&priv->cru->clksel_con[20], BIT(7)); + break; + case HCLK_HOST1_ARB: + rk_setreg(&priv->cru->clksel_con[20], BIT(8)); + break; + default: + debug("%s: unsupported clk %ld\n", __func__, clk->id); + return -ENOENT; + } + + return 0; +} + static struct clk_ops rk3399_clk_ops = { .get_rate = rk3399_clk_get_rate, .set_rate = rk3399_clk_set_rate, #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) .set_parent = rk3399_clk_set_parent, #endif + .enable = rk3399_clk_enable, + .disable = rk3399_clk_disable, }; #ifdef CONFIG_SPL_BUILD From 912f633d01334b006b9594404a1feed336efd10b Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Sat, 9 May 2020 22:26:20 +0530 Subject: [PATCH 05/15] clk: rk3399: Enable/Disable the PCIEPHY clk Enable/Disable the PCIEPHY clk for rk3399. CLK is clear in both enable and disable functionality. Signed-off-by: Jagan Teki Tested-by: Suniel Mahesh #roc-rk3399-pc Reviewed-by: Kever Yang --- drivers/clk/rockchip/clk_rk3399.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/clk/rockchip/clk_rk3399.c b/drivers/clk/rockchip/clk_rk3399.c index 371410d9a9..6a78837619 100644 --- a/drivers/clk/rockchip/clk_rk3399.c +++ b/drivers/clk/rockchip/clk_rk3399.c @@ -1139,6 +1139,9 @@ static int rk3399_clk_enable(struct clk *clk) case HCLK_HOST1_ARB: rk_clrreg(&priv->cru->clksel_con[20], BIT(8)); break; + case SCLK_PCIEPHY_REF: + rk_clrreg(&priv->cru->clksel_con[18], BIT(10)); + break; default: debug("%s: unsupported clk %ld\n", __func__, clk->id); return -ENOENT; @@ -1212,6 +1215,9 @@ static int rk3399_clk_disable(struct clk *clk) case HCLK_HOST1_ARB: rk_setreg(&priv->cru->clksel_con[20], BIT(8)); break; + case SCLK_PCIEPHY_REF: + rk_clrreg(&priv->cru->clksel_con[18], BIT(10)); + break; default: debug("%s: unsupported clk %ld\n", __func__, clk->id); return -ENOENT; From 99d59069c0a18147b1a475236b0632d085315c43 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Sat, 9 May 2020 22:26:21 +0530 Subject: [PATCH 06/15] pci: Add Rockchip PCIe controller driver Add Rockchip PCIe controller driver for rk3399 platform. Driver support Gen1 by operating as a Root complex. Thanks to Patrick for initial work. Signed-off-by: Patrick Wildt Signed-off-by: Jagan Teki Reviewed-by: Kever Yang Tested-by: Suniel Mahesh #roc-rk3399-pc --- drivers/pci/Kconfig | 8 + drivers/pci/Makefile | 1 + drivers/pci/pcie_rockchip.c | 467 ++++++++++++++++++++++++++++++++++++ drivers/pci/pcie_rockchip.h | 79 ++++++ 4 files changed, 555 insertions(+) create mode 100644 drivers/pci/pcie_rockchip.c create mode 100644 drivers/pci/pcie_rockchip.h diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 6fc26884e2..6d8c22aacf 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -197,4 +197,12 @@ config PCIE_MEDIATEK Say Y here if you want to enable Gen2 PCIe controller, which could be found on MT7623 SoC family. +config PCIE_ROCKCHIP + bool "Enable Rockchip PCIe driver" + select DM_PCI + default y if ROCKCHIP_RK3399 + help + Say Y here if you want to enable PCIe controller support on + Rockchip SoCs. + endif diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index c051ecc9f3..493e9354dd 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -43,3 +43,4 @@ obj-$(CONFIG_PCI_PHYTIUM) += pcie_phytium.o 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 diff --git a/drivers/pci/pcie_rockchip.c b/drivers/pci/pcie_rockchip.c new file mode 100644 index 0000000000..3f06f783ca --- /dev/null +++ b/drivers/pci/pcie_rockchip.c @@ -0,0 +1,467 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Rockchip AXI PCIe host controller driver + * + * Copyright (c) 2016 Rockchip, Inc. + * Copyright (c) 2020 Amarula Solutions(India) + * Copyright (c) 2020 Jagan Teki + * Copyright (c) 2019 Patrick Wildt + * Copyright (c) 2018 Mark Kettenis + * + * Bits taken from Linux Rockchip PCIe host controller. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pcie_rockchip.h" + +DECLARE_GLOBAL_DATA_PTR; + +static int rockchip_pcie_off_conf(pci_dev_t bdf, uint offset) +{ + unsigned int bus = PCI_BUS(bdf); + unsigned int dev = PCI_DEV(bdf); + unsigned int func = PCI_FUNC(bdf); + + return (bus << 20) | (dev << 15) | (func << 12) | (offset & ~0x3); +} + +static int rockchip_pcie_rd_conf(const struct udevice *udev, pci_dev_t bdf, + uint offset, ulong *valuep, + enum pci_size_t size) +{ + struct rockchip_pcie *priv = dev_get_priv(udev); + unsigned int bus = PCI_BUS(bdf); + unsigned int dev = PCI_DEV(bdf); + int where = rockchip_pcie_off_conf(bdf, offset); + ulong value; + + if (bus == priv->first_busno && dev == 0) { + value = readl(priv->apb_base + PCIE_RC_NORMAL_BASE + where); + *valuep = pci_conv_32_to_size(value, offset, size); + return 0; + } + + if ((bus == priv->first_busno + 1) && dev == 0) { + value = readl(priv->axi_base + where); + *valuep = pci_conv_32_to_size(value, offset, size); + return 0; + } + + *valuep = pci_get_ff(size); + + return 0; +} + +static int rockchip_pcie_wr_conf(struct udevice *udev, pci_dev_t bdf, + uint offset, ulong value, + enum pci_size_t size) +{ + struct rockchip_pcie *priv = dev_get_priv(udev); + unsigned int bus = PCI_BUS(bdf); + unsigned int dev = PCI_DEV(bdf); + int where = rockchip_pcie_off_conf(bdf, offset); + ulong old; + + if (bus == priv->first_busno && dev == 0) { + old = readl(priv->apb_base + PCIE_RC_NORMAL_BASE + where); + value = pci_conv_size_to_32(old, value, offset, size); + writel(value, priv->apb_base + PCIE_RC_NORMAL_BASE + where); + return 0; + } + + if ((bus == priv->first_busno + 1) && dev == 0) { + old = readl(priv->axi_base + where); + value = pci_conv_size_to_32(old, value, offset, size); + writel(value, priv->axi_base + where); + return 0; + } + + return 0; +} + +static int rockchip_pcie_atr_init(struct rockchip_pcie *priv) +{ + struct udevice *ctlr = pci_get_controller(priv->dev); + struct pci_controller *hose = dev_get_uclass_priv(ctlr); + u64 addr, size, offset; + u32 type; + int i, region; + + /* Use region 0 to map PCI configuration space. */ + writel(25 - 1, priv->apb_base + PCIE_ATR_OB_ADDR0(0)); + writel(0, priv->apb_base + PCIE_ATR_OB_ADDR1(0)); + writel(PCIE_ATR_HDR_CFG_TYPE0 | PCIE_ATR_HDR_RID, + priv->apb_base + PCIE_ATR_OB_DESC0(0)); + writel(0, priv->apb_base + PCIE_ATR_OB_DESC1(0)); + + for (i = 0; i < hose->region_count; i++) { + if (hose->regions[i].flags == PCI_REGION_SYS_MEMORY) + continue; + + if (hose->regions[i].flags == PCI_REGION_IO) + type = PCIE_ATR_HDR_IO; + else + type = PCIE_ATR_HDR_MEM; + + /* Only support identity mappings. */ + if (hose->regions[i].bus_start != + hose->regions[i].phys_start) + return -EINVAL; + + /* Only support mappings aligned on a region boundary. */ + addr = hose->regions[i].bus_start; + if (addr & (PCIE_ATR_OB_REGION_SIZE - 1)) + return -EINVAL; + + /* Mappings should lie between AXI and APB regions. */ + size = hose->regions[i].size; + if (addr < (u64)priv->axi_base + PCIE_ATR_OB_REGION0_SIZE) + return -EINVAL; + if (addr + size > (u64)priv->apb_base) + return -EINVAL; + + offset = addr - (u64)priv->axi_base - PCIE_ATR_OB_REGION0_SIZE; + region = 1 + (offset / PCIE_ATR_OB_REGION_SIZE); + while (size > 0) { + writel(32 - 1, + priv->apb_base + PCIE_ATR_OB_ADDR0(region)); + writel(0, priv->apb_base + PCIE_ATR_OB_ADDR1(region)); + writel(type | PCIE_ATR_HDR_RID, + priv->apb_base + PCIE_ATR_OB_DESC0(region)); + writel(0, priv->apb_base + PCIE_ATR_OB_DESC1(region)); + + addr += PCIE_ATR_OB_REGION_SIZE; + size -= PCIE_ATR_OB_REGION_SIZE; + region++; + } + } + + /* Passthrough inbound translations unmodified. */ + writel(32 - 1, priv->apb_base + PCIE_ATR_IB_ADDR0(2)); + writel(0, priv->apb_base + PCIE_ATR_IB_ADDR1(2)); + + return 0; +} + +static int rockchip_pcie_init_port(struct udevice *dev) +{ + struct rockchip_pcie *priv = dev_get_priv(dev); + u32 cr, val, status; + int ret; + + if (dm_gpio_is_valid(&priv->ep_gpio)) + dm_gpio_set_value(&priv->ep_gpio, 0); + + ret = reset_assert(&priv->aclk_rst); + if (ret) { + dev_err(dev, "failed to assert aclk reset (ret=%d)\n", ret); + return ret; + } + + ret = reset_assert(&priv->pclk_rst); + if (ret) { + dev_err(dev, "failed to assert pclk reset (ret=%d)\n", ret); + return ret; + } + + ret = reset_assert(&priv->pm_rst); + if (ret) { + dev_err(dev, "failed to assert pm reset (ret=%d)\n", ret); + return ret; + } + + ret = reset_assert(&priv->core_rst); + if (ret) { + dev_err(dev, "failed to assert core reset (ret=%d)\n", ret); + return ret; + } + + ret = reset_assert(&priv->mgmt_rst); + if (ret) { + dev_err(dev, "failed to assert mgmt reset (ret=%d)\n", ret); + return ret; + } + + ret = reset_assert(&priv->mgmt_sticky_rst); + if (ret) { + dev_err(dev, "failed to assert mgmt-sticky reset (ret=%d)\n", + ret); + return ret; + } + + ret = reset_assert(&priv->pipe_rst); + if (ret) { + dev_err(dev, "failed to assert pipe reset (ret=%d)\n", ret); + return ret; + } + + udelay(10); + + ret = reset_deassert(&priv->pm_rst); + if (ret) { + dev_err(dev, "failed to deassert pm reset (ret=%d)\n", ret); + return ret; + } + + ret = reset_deassert(&priv->aclk_rst); + if (ret) { + dev_err(dev, "failed to deassert aclk reset (ret=%d)\n", ret); + return ret; + } + + ret = reset_deassert(&priv->pclk_rst); + if (ret) { + dev_err(dev, "failed to deassert pclk reset (ret=%d)\n", ret); + return ret; + } + + /* Select GEN1 for now */ + cr = PCIE_CLIENT_GEN_SEL_1; + /* Set Root complex mode */ + cr |= PCIE_CLIENT_CONF_ENABLE | PCIE_CLIENT_MODE_RC; + writel(cr, priv->apb_base + PCIE_CLIENT_CONFIG); + + ret = reset_deassert(&priv->mgmt_sticky_rst); + if (ret) { + dev_err(dev, "failed to deassert mgmt-sticky reset (ret=%d)\n", + ret); + return ret; + } + + ret = reset_deassert(&priv->core_rst); + if (ret) { + dev_err(dev, "failed to deassert core reset (ret=%d)\n", ret); + return ret; + } + + ret = reset_deassert(&priv->mgmt_rst); + if (ret) { + dev_err(dev, "failed to deassert mgmt reset (ret=%d)\n", ret); + return ret; + } + + ret = reset_deassert(&priv->pipe_rst); + if (ret) { + dev_err(dev, "failed to deassert pipe reset (ret=%d)\n", ret); + return ret; + } + + /* Enable Gen1 training */ + writel(PCIE_CLIENT_LINK_TRAIN_ENABLE, + priv->apb_base + PCIE_CLIENT_CONFIG); + + if (dm_gpio_is_valid(&priv->ep_gpio)) + dm_gpio_set_value(&priv->ep_gpio, 1); + + ret = readl_poll_sleep_timeout + (priv->apb_base + PCIE_CLIENT_BASIC_STATUS1, + status, PCIE_LINK_UP(status), 20, 500 * 1000); + if (ret) { + dev_err(dev, "PCIe link training gen1 timeout!\n"); + return ret; + } + + /* Initialize Root Complex registers. */ + writel(PCIE_LM_VENDOR_ROCKCHIP, priv->apb_base + PCIE_LM_VENDOR_ID); + writel(PCI_CLASS_BRIDGE_PCI << 16, + priv->apb_base + PCIE_RC_BASE + PCI_CLASS_REVISION); + writel(PCIE_LM_RCBARPIE | PCIE_LM_RCBARPIS, + priv->apb_base + PCIE_LM_RCBAR); + + if (dev_read_bool(dev, "aspm-no-l0s")) { + val = readl(priv->apb_base + PCIE_RC_PCIE_LCAP); + val &= ~PCIE_RC_PCIE_LCAP_APMS_L0S; + writel(val, priv->apb_base + PCIE_RC_PCIE_LCAP); + } + + /* Configure Address Translation. */ + ret = rockchip_pcie_atr_init(priv); + if (ret) { + dev_err(dev, "PCIE-%d: ATR init failed\n", dev->seq); + return ret; + } + + return 0; +} + +static int rockchip_pcie_set_vpcie(struct udevice *dev) +{ + struct rockchip_pcie *priv = dev_get_priv(dev); + int ret; + + if (!IS_ERR(priv->vpcie3v3)) { + ret = regulator_set_enable(priv->vpcie3v3, true); + if (ret) { + dev_err(dev, "failed to enable vpcie3v3 (ret=%d)\n", + ret); + return ret; + } + } + + 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; + } + + return 0; + +err_disable_1v8: + regulator_set_enable(priv->vpcie1v8, false); +err_disable_3v3: + if (!IS_ERR(priv->vpcie3v3)) + regulator_set_enable(priv->vpcie3v3, false); + return ret; +} + +static int rockchip_pcie_parse_dt(struct udevice *dev) +{ + struct rockchip_pcie *priv = dev_get_priv(dev); + int ret; + + priv->axi_base = dev_read_addr_name(dev, "axi-base"); + if (!priv->axi_base) + return -ENODEV; + + priv->apb_base = dev_read_addr_name(dev, "apb-base"); + if (!priv->axi_base) + return -ENODEV; + + ret = gpio_request_by_name(dev, "ep-gpios", 0, + &priv->ep_gpio, GPIOD_IS_OUT); + if (ret) { + dev_err(dev, "failed to find ep-gpios property\n"); + return ret; + } + + ret = reset_get_by_name(dev, "core", &priv->core_rst); + if (ret) { + dev_err(dev, "failed to get core reset (ret=%d)\n", ret); + return ret; + } + + ret = reset_get_by_name(dev, "mgmt", &priv->mgmt_rst); + if (ret) { + dev_err(dev, "failed to get mgmt reset (ret=%d)\n", ret); + return ret; + } + + ret = reset_get_by_name(dev, "mgmt-sticky", &priv->mgmt_sticky_rst); + if (ret) { + dev_err(dev, "failed to get mgmt-sticky reset (ret=%d)\n", ret); + return ret; + } + + ret = reset_get_by_name(dev, "pipe", &priv->pipe_rst); + if (ret) { + dev_err(dev, "failed to get pipe reset (ret=%d)\n", ret); + return ret; + } + + ret = reset_get_by_name(dev, "pm", &priv->pm_rst); + if (ret) { + dev_err(dev, "failed to get pm reset (ret=%d)\n", ret); + return ret; + } + + ret = reset_get_by_name(dev, "pclk", &priv->pclk_rst); + if (ret) { + dev_err(dev, "failed to get pclk reset (ret=%d)\n", ret); + return ret; + } + + ret = reset_get_by_name(dev, "aclk", &priv->aclk_rst); + if (ret) { + dev_err(dev, "failed to get aclk reset (ret=%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 = device_get_supply_regulator(dev, "vpcie1v8-supply", + &priv->vpcie1v8); + if (ret) { + 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) { + dev_err(dev, "failed to get vpcie0v9 supply (ret=%d)\n", ret); + return ret; + } + + return 0; +} + +static int rockchip_pcie_probe(struct udevice *dev) +{ + struct rockchip_pcie *priv = dev_get_priv(dev); + struct udevice *ctlr = pci_get_controller(dev); + struct pci_controller *hose = dev_get_uclass_priv(ctlr); + int ret; + + priv->first_busno = dev->seq; + priv->dev = dev; + + ret = rockchip_pcie_parse_dt(dev); + if (ret) + return ret; + + ret = rockchip_pcie_set_vpcie(dev); + if (ret) + return ret; + + ret = rockchip_pcie_init_port(dev); + if (ret) + return ret; + + dev_info(dev, "PCIE-%d: Link up (Bus%d)\n", + dev->seq, hose->first_busno); + + return 0; +} + +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,rk3399-pcie" }, + { } +}; + +U_BOOT_DRIVER(rockchip_pcie) = { + .name = "rockchip_pcie", + .id = UCLASS_PCI, + .of_match = rockchip_pcie_ids, + .ops = &rockchip_pcie_ops, + .probe = rockchip_pcie_probe, + .priv_auto_alloc_size = sizeof(struct rockchip_pcie), +}; diff --git a/drivers/pci/pcie_rockchip.h b/drivers/pci/pcie_rockchip.h new file mode 100644 index 0000000000..6ded5c9553 --- /dev/null +++ b/drivers/pci/pcie_rockchip.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Rockchip PCIe Headers + * + * Copyright (c) 2016 Rockchip, Inc. + * Copyright (c) 2020 Amarula Solutions(India) + * Copyright (c) 2020 Jagan Teki + * Copyright (c) 2019 Patrick Wildt + * + */ + +#define HIWORD_UPDATE(mask, val) (((mask) << 16) | (val)) +#define HIWORD_UPDATE_BIT(val) HIWORD_UPDATE(val, val) + +#define ENCODE_LANES(x) ((((x) >> 1) & 3) << 4) +#define PCIE_CLIENT_BASE 0x0 +#define PCIE_CLIENT_CONFIG (PCIE_CLIENT_BASE + 0x00) +#define PCIE_CLIENT_CONF_ENABLE HIWORD_UPDATE_BIT(0x0001) +#define PCIE_CLIENT_LINK_TRAIN_ENABLE HIWORD_UPDATE_BIT(0x0002) +#define PCIE_CLIENT_MODE_RC HIWORD_UPDATE_BIT(0x0040) +#define PCIE_CLIENT_GEN_SEL_1 HIWORD_UPDATE(0x0080, 0) +#define PCIE_CLIENT_BASIC_STATUS1 0x0048 +#define PCIE_CLIENT_LINK_STATUS_UP GENMASK(21, 20) +#define PCIE_CLIENT_LINK_STATUS_MASK GENMASK(21, 20) +#define PCIE_LINK_UP(x) \ + (((x) & PCIE_CLIENT_LINK_STATUS_MASK) == PCIE_CLIENT_LINK_STATUS_UP) +#define PCIE_RC_NORMAL_BASE 0x800000 +#define PCIE_LM_BASE 0x900000 +#define PCIE_LM_VENDOR_ID (PCIE_LM_BASE + 0x44) +#define PCIE_LM_VENDOR_ROCKCHIP 0x1d87 +#define PCIE_LM_RCBAR (PCIE_LM_BASE + 0x300) +#define PCIE_LM_RCBARPIE BIT(19) +#define PCIE_LM_RCBARPIS BIT(20) +#define PCIE_RC_BASE 0xa00000 +#define PCIE_RC_CONFIG_DCR (PCIE_RC_BASE + 0x0c4) +#define PCIE_RC_CONFIG_DCR_CSPL_SHIFT 18 +#define PCIE_RC_CONFIG_DCR_CPLS_SHIFT 26 +#define PCIE_RC_PCIE_LCAP (PCIE_RC_BASE + 0x0cc) +#define PCIE_RC_PCIE_LCAP_APMS_L0S BIT(10) +#define PCIE_ATR_BASE 0xc00000 +#define PCIE_ATR_OB_ADDR0(i) (PCIE_ATR_BASE + 0x000 + (i) * 0x20) +#define PCIE_ATR_OB_ADDR1(i) (PCIE_ATR_BASE + 0x004 + (i) * 0x20) +#define PCIE_ATR_OB_DESC0(i) (PCIE_ATR_BASE + 0x008 + (i) * 0x20) +#define PCIE_ATR_OB_DESC1(i) (PCIE_ATR_BASE + 0x00c + (i) * 0x20) +#define PCIE_ATR_IB_ADDR0(i) (PCIE_ATR_BASE + 0x800 + (i) * 0x8) +#define PCIE_ATR_IB_ADDR1(i) (PCIE_ATR_BASE + 0x804 + (i) * 0x8) +#define PCIE_ATR_HDR_MEM 0x2 +#define PCIE_ATR_HDR_IO 0x6 +#define PCIE_ATR_HDR_CFG_TYPE0 0xa +#define PCIE_ATR_HDR_CFG_TYPE1 0xb +#define PCIE_ATR_HDR_RID BIT(23) + +#define PCIE_ATR_OB_REGION0_SIZE (32 * 1024 * 1024) +#define PCIE_ATR_OB_REGION_SIZE (1 * 1024 * 1024) + +struct rockchip_pcie { + fdt_addr_t axi_base; + fdt_addr_t apb_base; + int first_busno; + struct udevice *dev; + + /* resets */ + struct reset_ctl core_rst; + struct reset_ctl mgmt_rst; + struct reset_ctl mgmt_sticky_rst; + struct reset_ctl pipe_rst; + struct reset_ctl pm_rst; + struct reset_ctl pclk_rst; + struct reset_ctl aclk_rst; + + /* gpio */ + struct gpio_desc ep_gpio; + + /* vpcie regulators */ + struct udevice *vpcie12v; + struct udevice *vpcie3v3; + struct udevice *vpcie1v8; + struct udevice *vpcie0v9; +}; From 89f2fa0b5e82fa5fa05e5bce0e24bc1d863270ce Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Sat, 9 May 2020 22:26:22 +0530 Subject: [PATCH 07/15] pci: Add Rockchip PCIe PHY controller driver Yes, it is possible to have a dedicated UCLASS PHY driver for this Rockchip PCIe PHY but there are some issues on Generic PHY framework to support the same. The Generic PHY framework is unable to get the PHY if the PHY parent is of a different uclass. Say if we try to get the PCIe PHY then the phy-uclass will look for PHY in the first instance if it is not in the root node it will try to probe the parent by assuming that the actual PHY is inside the parent PHY of UCLASS_PHY. But, in rk3399 hardware representation PHY like emmc, usb and pcie are part of syscon which is completely a different of UCLASS_SYSCON. Example: grf: syscon@ff770000 { compatible = "rockchip,rk3399-grf", "syscon", "simple-mfd"; reg = <0x0 0xff770000 0x0 0x10000>; #address-cells = <1>; #size-cells = <1>; pcie_phy: pcie-phy { compatible = "rockchip,rk3399-pcie-phy"; clocks = <&cru SCLK_PCIEPHY_REF>; clock-names = "refclk"; #phy-cells = <1>; resets = <&cru SRST_PCIEPHY>; drive-impedance-ohm = <50>; reset-names = "phy"; status = "disabled"; }; }; Due to this limitation, this patch adds a separate PHY driver for Rockchip PCIe. This might be removed in future once Generic PHY supports this limitation. Signed-off-by: Jagan Teki Tested-by: Suniel Mahesh #roc-rk3399-pc Reviewed-by: Kever Yang --- drivers/pci/Makefile | 2 +- drivers/pci/pcie_rockchip.c | 50 ++++++-- drivers/pci/pcie_rockchip.h | 63 ++++++++++ drivers/pci/pcie_rockchip_phy.c | 205 ++++++++++++++++++++++++++++++++ 4 files changed, 306 insertions(+), 14 deletions(-) create mode 100644 drivers/pci/pcie_rockchip_phy.c diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 493e9354dd..955351c5c2 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -43,4 +43,4 @@ obj-$(CONFIG_PCI_PHYTIUM) += pcie_phytium.o 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_ROCKCHIP) += pcie_rockchip.o pcie_rockchip_phy.o diff --git a/drivers/pci/pcie_rockchip.c b/drivers/pci/pcie_rockchip.c index 3f06f783ca..82a8396e42 100644 --- a/drivers/pci/pcie_rockchip.c +++ b/drivers/pci/pcie_rockchip.c @@ -159,6 +159,8 @@ static int rockchip_pcie_atr_init(struct rockchip_pcie *priv) static int rockchip_pcie_init_port(struct udevice *dev) { struct rockchip_pcie *priv = dev_get_priv(dev); + struct rockchip_pcie_phy *phy = pcie_get_phy(priv); + struct rockchip_pcie_phy_ops *ops = phy_get_ops(phy); u32 cr, val, status; int ret; @@ -183,29 +185,35 @@ static int rockchip_pcie_init_port(struct udevice *dev) return ret; } + ret = ops->init(phy); + if (ret) { + dev_err(dev, "failed to init phy (ret=%d)\n", ret); + goto err_exit_phy; + } + ret = reset_assert(&priv->core_rst); if (ret) { dev_err(dev, "failed to assert core reset (ret=%d)\n", ret); - return ret; + goto err_exit_phy; } ret = reset_assert(&priv->mgmt_rst); if (ret) { dev_err(dev, "failed to assert mgmt reset (ret=%d)\n", ret); - return ret; + goto err_exit_phy; } ret = reset_assert(&priv->mgmt_sticky_rst); if (ret) { dev_err(dev, "failed to assert mgmt-sticky reset (ret=%d)\n", ret); - return ret; + goto err_exit_phy; } ret = reset_assert(&priv->pipe_rst); if (ret) { dev_err(dev, "failed to assert pipe reset (ret=%d)\n", ret); - return ret; + goto err_exit_phy; } udelay(10); @@ -213,19 +221,19 @@ static int rockchip_pcie_init_port(struct udevice *dev) ret = reset_deassert(&priv->pm_rst); if (ret) { dev_err(dev, "failed to deassert pm reset (ret=%d)\n", ret); - return ret; + goto err_exit_phy; } ret = reset_deassert(&priv->aclk_rst); if (ret) { dev_err(dev, "failed to deassert aclk reset (ret=%d)\n", ret); - return ret; + goto err_exit_phy; } ret = reset_deassert(&priv->pclk_rst); if (ret) { dev_err(dev, "failed to deassert pclk reset (ret=%d)\n", ret); - return ret; + goto err_exit_phy; } /* Select GEN1 for now */ @@ -234,29 +242,35 @@ static int rockchip_pcie_init_port(struct udevice *dev) cr |= PCIE_CLIENT_CONF_ENABLE | PCIE_CLIENT_MODE_RC; writel(cr, priv->apb_base + PCIE_CLIENT_CONFIG); + ret = ops->power_on(phy); + if (ret) { + dev_err(dev, "failed to power on phy (ret=%d)\n", ret); + goto err_power_off_phy; + } + ret = reset_deassert(&priv->mgmt_sticky_rst); if (ret) { dev_err(dev, "failed to deassert mgmt-sticky reset (ret=%d)\n", ret); - return ret; + goto err_power_off_phy; } ret = reset_deassert(&priv->core_rst); if (ret) { dev_err(dev, "failed to deassert core reset (ret=%d)\n", ret); - return ret; + goto err_power_off_phy; } ret = reset_deassert(&priv->mgmt_rst); if (ret) { dev_err(dev, "failed to deassert mgmt reset (ret=%d)\n", ret); - return ret; + goto err_power_off_phy; } ret = reset_deassert(&priv->pipe_rst); if (ret) { dev_err(dev, "failed to deassert pipe reset (ret=%d)\n", ret); - return ret; + goto err_power_off_phy; } /* Enable Gen1 training */ @@ -271,7 +285,7 @@ static int rockchip_pcie_init_port(struct udevice *dev) status, PCIE_LINK_UP(status), 20, 500 * 1000); if (ret) { dev_err(dev, "PCIe link training gen1 timeout!\n"); - return ret; + goto err_power_off_phy; } /* Initialize Root Complex registers. */ @@ -291,10 +305,16 @@ static int rockchip_pcie_init_port(struct udevice *dev) ret = rockchip_pcie_atr_init(priv); if (ret) { dev_err(dev, "PCIE-%d: ATR init failed\n", dev->seq); - return ret; + goto err_power_off_phy; } return 0; + +err_power_off_phy: + ops->power_off(phy); +err_exit_phy: + ops->exit(phy); + return ret; } static int rockchip_pcie_set_vpcie(struct udevice *dev) @@ -433,6 +453,10 @@ static int rockchip_pcie_probe(struct udevice *dev) if (ret) return ret; + ret = rockchip_pcie_phy_get(dev); + if (ret) + return ret; + ret = rockchip_pcie_set_vpcie(dev); if (ret) return ret; diff --git a/drivers/pci/pcie_rockchip.h b/drivers/pci/pcie_rockchip.h index 6ded5c9553..c3a0a2846d 100644 --- a/drivers/pci/pcie_rockchip.h +++ b/drivers/pci/pcie_rockchip.h @@ -53,11 +53,61 @@ #define PCIE_ATR_OB_REGION0_SIZE (32 * 1024 * 1024) #define PCIE_ATR_OB_REGION_SIZE (1 * 1024 * 1024) +/* + * The higher 16-bit of this register is used for write protection + * only if BIT(x + 16) set to 1 the BIT(x) can be written. + */ +#define HIWORD_UPDATE_MASK(val, mask, shift) \ + ((val) << (shift) | (mask) << ((shift) + 16)) + +#define PHY_CFG_DATA_SHIFT 7 +#define PHY_CFG_ADDR_SHIFT 1 +#define PHY_CFG_DATA_MASK 0xf +#define PHY_CFG_ADDR_MASK 0x3f +#define PHY_CFG_RD_MASK 0x3ff +#define PHY_CFG_WR_ENABLE 1 +#define PHY_CFG_WR_DISABLE 1 +#define PHY_CFG_WR_SHIFT 0 +#define PHY_CFG_WR_MASK 1 +#define PHY_CFG_PLL_LOCK 0x10 +#define PHY_CFG_CLK_TEST 0x10 +#define PHY_CFG_CLK_SCC 0x12 +#define PHY_CFG_SEPE_RATE BIT(3) +#define PHY_CFG_PLL_100M BIT(3) +#define PHY_PLL_LOCKED BIT(9) +#define PHY_PLL_OUTPUT BIT(10) +#define PHY_LANE_IDLE_OFF 0x1 +#define PHY_LANE_IDLE_MASK 0x1 +#define PHY_LANE_IDLE_A_SHIFT 3 +#define PHY_LANE_IDLE_B_SHIFT 4 +#define PHY_LANE_IDLE_C_SHIFT 5 +#define PHY_LANE_IDLE_D_SHIFT 6 + +#define PCIE_PHY_CONF 0xe220 +#define PCIE_PHY_STATUS 0xe2a4 +#define PCIE_PHY_LANEOFF 0xe214 + +struct rockchip_pcie_phy { + void *reg_base; + struct clk refclk; + struct reset_ctl phy_rst; + struct rockchip_pcie_phy_ops *ops; +}; + +struct rockchip_pcie_phy_ops { + int (*init)(struct rockchip_pcie_phy *phy); + int (*exit)(struct rockchip_pcie_phy *phy); + int (*power_on)(struct rockchip_pcie_phy *phy); + int (*power_off)(struct rockchip_pcie_phy *phy); +}; + struct rockchip_pcie { fdt_addr_t axi_base; fdt_addr_t apb_base; int first_busno; struct udevice *dev; + struct rockchip_pcie_phy rk_phy; + struct rockchip_pcie_phy *phy; /* resets */ struct reset_ctl core_rst; @@ -77,3 +127,16 @@ struct rockchip_pcie { struct udevice *vpcie1v8; struct udevice *vpcie0v9; }; + +int rockchip_pcie_phy_get(struct udevice *dev); + +inline struct rockchip_pcie_phy *pcie_get_phy(struct rockchip_pcie *pcie) +{ + return pcie->phy; +} + +inline +struct rockchip_pcie_phy_ops *phy_get_ops(struct rockchip_pcie_phy *phy) +{ + return (struct rockchip_pcie_phy_ops *)phy->ops; +} diff --git a/drivers/pci/pcie_rockchip_phy.c b/drivers/pci/pcie_rockchip_phy.c new file mode 100644 index 0000000000..47f5d6c7e3 --- /dev/null +++ b/drivers/pci/pcie_rockchip_phy.c @@ -0,0 +1,205 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Rockchip PCIe PHY driver + * + * Copyright (c) 2016 Rockchip, Inc. + * Copyright (c) 2020 Amarula Solutions(India) + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pcie_rockchip.h" + +DECLARE_GLOBAL_DATA_PTR; + +static void phy_wr_cfg(struct rockchip_pcie_phy *phy, u32 addr, u32 data) +{ + u32 reg; + + reg = HIWORD_UPDATE_MASK(data, PHY_CFG_DATA_MASK, PHY_CFG_DATA_SHIFT); + reg |= HIWORD_UPDATE_MASK(addr, PHY_CFG_ADDR_MASK, PHY_CFG_ADDR_SHIFT); + writel(reg, phy->reg_base + PCIE_PHY_CONF); + + udelay(1); + + reg = HIWORD_UPDATE_MASK(PHY_CFG_WR_ENABLE, + PHY_CFG_WR_MASK, + PHY_CFG_WR_SHIFT); + writel(reg, phy->reg_base + PCIE_PHY_CONF); + + udelay(1); + + reg = HIWORD_UPDATE_MASK(PHY_CFG_WR_DISABLE, + PHY_CFG_WR_MASK, + PHY_CFG_WR_SHIFT); + writel(reg, phy->reg_base + PCIE_PHY_CONF); +} + +static int rockchip_pcie_phy_power_on(struct rockchip_pcie_phy *phy) +{ + int ret = 0; + u32 reg, status; + + ret = reset_deassert(&phy->phy_rst); + if (ret) { + dev_err(dev, "failed to assert phy reset\n"); + return ret; + } + + reg = HIWORD_UPDATE_MASK(PHY_CFG_PLL_LOCK, + PHY_CFG_ADDR_MASK, + PHY_CFG_ADDR_SHIFT); + writel(reg, phy->reg_base + PCIE_PHY_CONF); + + reg = HIWORD_UPDATE_MASK(!PHY_LANE_IDLE_OFF, + PHY_LANE_IDLE_MASK, + PHY_LANE_IDLE_A_SHIFT); + writel(reg, phy->reg_base + PCIE_PHY_LANEOFF); + + ret = -EINVAL; + ret = readl_poll_sleep_timeout(phy->reg_base + PCIE_PHY_STATUS, + status, + status & PHY_PLL_LOCKED, + 20 * 1000, + 50); + if (ret) { + dev_err(&phy->dev, "pll lock timeout!\n"); + goto err_pll_lock; + } + + phy_wr_cfg(phy, PHY_CFG_CLK_TEST, PHY_CFG_SEPE_RATE); + phy_wr_cfg(phy, PHY_CFG_CLK_SCC, PHY_CFG_PLL_100M); + + ret = -ETIMEDOUT; + ret = readl_poll_sleep_timeout(phy->reg_base + PCIE_PHY_STATUS, + status, + !(status & PHY_PLL_OUTPUT), + 20 * 1000, + 50); + if (ret) { + dev_err(&phy->dev, "pll output enable timeout!\n"); + goto err_pll_lock; + } + + reg = HIWORD_UPDATE_MASK(PHY_CFG_PLL_LOCK, + PHY_CFG_ADDR_MASK, + PHY_CFG_ADDR_SHIFT); + writel(reg, phy->reg_base + PCIE_PHY_CONF); + + ret = -EINVAL; + ret = readl_poll_sleep_timeout(phy->reg_base + PCIE_PHY_STATUS, + status, + status & PHY_PLL_LOCKED, + 20 * 1000, + 50); + if (ret) { + dev_err(&phy->dev, "pll relock timeout!\n"); + goto err_pll_lock; + } + + return 0; + +err_pll_lock: + reset_assert(&phy->phy_rst); + return ret; +} + +static int rockchip_pcie_phy_power_off(struct rockchip_pcie_phy *phy) +{ + int ret; + u32 reg; + + reg = HIWORD_UPDATE_MASK(PHY_LANE_IDLE_OFF, + PHY_LANE_IDLE_MASK, + PHY_LANE_IDLE_A_SHIFT); + writel(reg, phy->reg_base + PCIE_PHY_LANEOFF); + + ret = reset_assert(&phy->phy_rst); + if (ret) { + dev_err(dev, "failed to assert phy reset\n"); + return ret; + } + + return 0; +} + +static int rockchip_pcie_phy_init(struct rockchip_pcie_phy *phy) +{ + int ret; + + ret = clk_enable(&phy->refclk); + if (ret) { + dev_err(dev, "failed to enable refclk clock\n"); + return ret; + } + + ret = reset_assert(&phy->phy_rst); + if (ret) { + dev_err(dev, "failed to assert phy reset\n"); + goto err_reset; + } + + return 0; + +err_reset: + clk_disable(&phy->refclk); + return ret; +} + +static int rockchip_pcie_phy_exit(struct rockchip_pcie_phy *phy) +{ + clk_disable(&phy->refclk); + + return 0; +} + +static struct rockchip_pcie_phy_ops pcie_phy_ops = { + .init = rockchip_pcie_phy_init, + .power_on = rockchip_pcie_phy_power_on, + .power_off = rockchip_pcie_phy_power_off, + .exit = rockchip_pcie_phy_exit, +}; + +int rockchip_pcie_phy_get(struct udevice *dev) +{ + struct rockchip_pcie *priv = dev_get_priv(dev); + struct rockchip_pcie_phy *phy_priv = &priv->rk_phy; + ofnode phy_node; + u32 phandle; + int ret; + + phandle = dev_read_u32_default(dev, "phys", 0); + phy_node = ofnode_get_by_phandle(phandle); + if (!ofnode_valid(phy_node)) { + dev_err(dev, "failed to found pcie-phy\n"); + return -ENODEV; + } + + phy_priv->reg_base = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); + + ret = clk_get_by_index_nodev(phy_node, 0, &phy_priv->refclk); + if (ret) { + dev_err(dev, "failed to get refclk clock phandle\n"); + return ret; + } + + ret = reset_get_by_index_nodev(phy_node, 0, &phy_priv->phy_rst); + if (ret) { + dev_err(dev, "failed to get phy reset phandle\n"); + return ret; + } + + phy_priv->ops = &pcie_phy_ops; + priv->phy = phy_priv; + + return 0; +} From 765a12d6a39ee2151421c5fc0250d9eefdf0e085 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Sat, 9 May 2020 22:26:23 +0530 Subject: [PATCH 08/15] rockchip: Enable PCIe/M.2 on rk3399 board w/ M.2 Enable PCIe/M.2 support on - NanoPC-T4 - ROC-RK3399-PC Mezzanine boards. Signed-off-by: Jagan Teki Tested-by: Suniel Mahesh #roc-rk3399-pc Reviewed-by: Kever Yang --- arch/arm/dts/rk3399-u-boot.dtsi | 1 + configs/nanopc-t4-rk3399_defconfig | 4 ++++ configs/roc-pc-mezzanine-rk3399_defconfig | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/arch/arm/dts/rk3399-u-boot.dtsi b/arch/arm/dts/rk3399-u-boot.dtsi index 22017ecd60..8237782408 100644 --- a/arch/arm/dts/rk3399-u-boot.dtsi +++ b/arch/arm/dts/rk3399-u-boot.dtsi @@ -8,6 +8,7 @@ aliases { mmc0 = &sdhci; mmc1 = &sdmmc; + pci0 = &pcie0; }; cic: syscon@ff620000 { diff --git a/configs/nanopc-t4-rk3399_defconfig b/configs/nanopc-t4-rk3399_defconfig index ae865908d8..3bb5b498f2 100644 --- a/configs/nanopc-t4-rk3399_defconfig +++ b/configs/nanopc-t4-rk3399_defconfig @@ -18,6 +18,7 @@ CONFIG_CMD_BOOTZ=y CONFIG_CMD_GPT=y CONFIG_CMD_MMC=y CONFIG_CMD_USB=y +CONFIG_CMD_PCI=y # CONFIG_CMD_SETEXPR is not set CONFIG_CMD_TIME=y CONFIG_SPL_OF_CONTROL=y @@ -34,10 +35,13 @@ CONFIG_MMC_SDHCI_ROCKCHIP=y CONFIG_DM_ETH=y CONFIG_ETH_DESIGNWARE=y CONFIG_GMAC_ROCKCHIP=y +CONFIG_NVME=y +CONFIG_PCI=y CONFIG_PMIC_RK8XX=y CONFIG_REGULATOR_PWM=y CONFIG_REGULATOR_RK8XX=y CONFIG_PWM_ROCKCHIP=y +CONFIG_DM_RESET=y CONFIG_BAUDRATE=1500000 CONFIG_DEBUG_UART_SHIFT=2 CONFIG_SYSRESET=y diff --git a/configs/roc-pc-mezzanine-rk3399_defconfig b/configs/roc-pc-mezzanine-rk3399_defconfig index 1879944bc5..7f55307676 100644 --- a/configs/roc-pc-mezzanine-rk3399_defconfig +++ b/configs/roc-pc-mezzanine-rk3399_defconfig @@ -19,6 +19,7 @@ CONFIG_CMD_BOOTZ=y CONFIG_CMD_GPT=y CONFIG_CMD_MMC=y CONFIG_CMD_USB=y +CONFIG_CMD_PCI=y # CONFIG_CMD_SETEXPR is not set CONFIG_CMD_TIME=y CONFIG_SPL_OF_CONTROL=y @@ -36,11 +37,14 @@ CONFIG_SPI_FLASH_WINBOND=y CONFIG_DM_ETH=y CONFIG_ETH_DESIGNWARE=y CONFIG_GMAC_ROCKCHIP=y +CONFIG_NVME=y +CONFIG_PCI=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 From 0672e9803b88cbc8268ee65120cfa27fe8e2fb82 Mon Sep 17 00:00:00 2001 From: Jagan Teki Date: Sat, 9 May 2020 22:26:24 +0530 Subject: [PATCH 09/15] rockchip: Enable PCIe/M.2 on rock960 board Due to board limitation some SSD's would work on rock960 PCIe M.2 only with 1.8V IO domain. So, this patch enables grf io_sel explicitly to make PCIe/M.2 to work. Cc: Tom Cubie Signed-off-by: Jagan Teki Acked-by: Manivannan Sadhasivam Reviewed-by: Kever Yang --- board/vamrs/rock960_rk3399/rock960-rk3399.c | 24 +++++++++++++++++++++ configs/rock960-rk3399_defconfig | 5 +++++ 2 files changed, 29 insertions(+) diff --git a/board/vamrs/rock960_rk3399/rock960-rk3399.c b/board/vamrs/rock960_rk3399/rock960-rk3399.c index 68a127b9ac..a7fc38d42f 100644 --- a/board/vamrs/rock960_rk3399/rock960-rk3399.c +++ b/board/vamrs/rock960_rk3399/rock960-rk3399.c @@ -2,3 +2,27 @@ /* * Copyright (C) 2018 Manivannan Sadhasivam */ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_MISC_INIT_R +int misc_init_r(void) +{ + struct rk3399_grf_regs *grf = + syscon_get_first_range(ROCKCHIP_SYSCON_GRF); + + /** + * Some SSD's to work on rock960 would require explicit + * domain voltage change, so BT565 is in 1.8v domain + */ + rk_setreg(&grf->io_vsel, BIT(0)); + + return 0; +} +#endif diff --git a/configs/rock960-rk3399_defconfig b/configs/rock960-rk3399_defconfig index 045d989a19..64517f9623 100644 --- a/configs/rock960-rk3399_defconfig +++ b/configs/rock960-rk3399_defconfig @@ -9,6 +9,7 @@ CONFIG_DEBUG_UART_BASE=0xFF1A0000 CONFIG_DEBUG_UART_CLOCK=24000000 CONFIG_DEBUG_UART=y CONFIG_DEFAULT_FDT_FILE="rockchip/rk3399-rock960.dtb" +CONFIG_MISC_INIT_R=y CONFIG_DISPLAY_BOARDINFO_LATE=y # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set CONFIG_SPL_STACK_R=y @@ -19,6 +20,7 @@ CONFIG_CMD_BOOTZ=y CONFIG_CMD_GPT=y CONFIG_CMD_MMC=y CONFIG_CMD_USB=y +CONFIG_CMD_PCI=y # CONFIG_CMD_SETEXPR is not set CONFIG_CMD_TIME=y CONFIG_CMD_PMIC=y @@ -36,10 +38,13 @@ CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_SDMA=y CONFIG_MMC_SDHCI_ROCKCHIP=y CONFIG_DM_ETH=y +CONFIG_NVME=y +CONFIG_PCI=y CONFIG_PMIC_RK8XX=y CONFIG_REGULATOR_PWM=y CONFIG_REGULATOR_RK8XX=y CONFIG_PWM_ROCKCHIP=y +CONFIG_DM_RESET=y CONFIG_BAUDRATE=1500000 CONFIG_DEBUG_UART_SHIFT=2 CONFIG_SYSRESET=y From 69cd0c463d4bd8b9c3c20c96640c612333947d7e Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 9 May 2020 21:31:03 +0200 Subject: [PATCH 10/15] tools: value checks in rkcommon_check_params() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Building with -Wtype-limits yields tools/rkcommon.c: In function ‘rkcommon_check_params’: tools/rkcommon.c:158:27: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits] 158 | if (spl_params.init_size < 0) | ^ tools/rkcommon.c:165:28: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits] 165 | if (spl_params.boot_size < 0) | Fix the value checks. Signed-off-by: Heinrich Schuchardt Reviewed-by: Kever Yang --- tools/rkcommon.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/rkcommon.c b/tools/rkcommon.c index 8f281f5901..61c392e27d 100644 --- a/tools/rkcommon.c +++ b/tools/rkcommon.c @@ -133,7 +133,7 @@ static int rkcommon_get_aligned_size(struct image_tool_params *params, int rkcommon_check_params(struct image_tool_params *params) { - int i; + int i, size; /* * If this is a operation (list or extract), the don't require @@ -153,17 +153,17 @@ int rkcommon_check_params(struct image_tool_params *params) spl_params.boot_file += 1; } - spl_params.init_size = - rkcommon_get_aligned_size(params, spl_params.init_file); - if (spl_params.init_size < 0) + size = rkcommon_get_aligned_size(params, spl_params.init_file); + if (size < 0) return EXIT_FAILURE; + spl_params.init_size = size; /* Boot file is optional, and only for back-to-bootrom functionality. */ if (spl_params.boot_file) { - spl_params.boot_size = - rkcommon_get_aligned_size(params, spl_params.boot_file); - if (spl_params.boot_size < 0) + size = rkcommon_get_aligned_size(params, spl_params.boot_file); + if (size < 0) return EXIT_FAILURE; + spl_params.boot_size = size; } if (spl_params.init_size > rkcommon_get_spl_size(params)) { From 353ad95aa6562654726a91cb457f30d5f2a85f4c Mon Sep 17 00:00:00 2001 From: Urja Rannikko Date: Wed, 13 May 2020 19:15:20 +0000 Subject: [PATCH 11/15] rockchip: spl: veyron speedy boots from SPI Apparently speedy was forgotten from this list of veyron devices. Fixes: 49105fb7ed ("rockchip: add common spl board file") Signed-off-by: Urja Rannikko Reviewed-by: Kever Yang --- arch/arm/mach-rockchip/spl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-rockchip/spl.c b/arch/arm/mach-rockchip/spl.c index ec2f66d188..46b32eb345 100644 --- a/arch/arm/mach-rockchip/spl.c +++ b/arch/arm/mach-rockchip/spl.c @@ -53,7 +53,8 @@ u32 spl_boot_device(void) #if defined(CONFIG_TARGET_CHROMEBOOK_JERRY) || \ defined(CONFIG_TARGET_CHROMEBIT_MICKEY) || \ - defined(CONFIG_TARGET_CHROMEBOOK_MINNIE) + defined(CONFIG_TARGET_CHROMEBOOK_MINNIE) || \ + defined(CONFIG_TARGET_CHROMEBOOK_SPEEDY) return BOOT_DEVICE_SPI; #endif if (CONFIG_IS_ENABLED(ROCKCHIP_BACK_TO_BROM)) From fffdf7290cee85232ee522e27c09c7f1178e6219 Mon Sep 17 00:00:00 2001 From: Urja Rannikko Date: Wed, 13 May 2020 19:15:21 +0000 Subject: [PATCH 12/15] rockchip: veyron: move board_early_init_f to _r (after reloc) Previously veyron_init() was called in board_init() context, which is called after relocation. Moving it to veyron.c used board_early_init_f which is called way earlier, and causes veyron_init to hang. Using board_early_init_r instead fixes this. Fixes: b678f2790c ("rockchip: rk3288: Move veyron_init() back to veyron.c") Signed-off-by: Urja Rannikko Reviewed-by: Kever Yang --- board/google/veyron/veyron.c | 2 +- configs/chromebit_mickey_defconfig | 1 + configs/chromebook_jerry_defconfig | 2 +- configs/chromebook_minnie_defconfig | 1 + configs/chromebook_speedy_defconfig | 2 +- 5 files changed, 5 insertions(+), 3 deletions(-) diff --git a/board/google/veyron/veyron.c b/board/google/veyron/veyron.c index 6d84a326a3..391d973c0b 100644 --- a/board/google/veyron/veyron.c +++ b/board/google/veyron/veyron.c @@ -71,7 +71,7 @@ static int veyron_init(void) } #endif -int board_early_init_f(void) +int board_early_init_r(void) { struct udevice *dev; int ret; diff --git a/configs/chromebit_mickey_defconfig b/configs/chromebit_mickey_defconfig index b1ad7bdd1d..b290f0fcb9 100644 --- a/configs/chromebit_mickey_defconfig +++ b/configs/chromebit_mickey_defconfig @@ -19,6 +19,7 @@ CONFIG_USE_PREBOOT=y CONFIG_DEFAULT_FDT_FILE="rk3288-veyron-mickey.dtb" # CONFIG_DISPLAY_CPUINFO is not set CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_BOARD_EARLY_INIT_R=y # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set CONFIG_SPL_STACK_R=y CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000 diff --git a/configs/chromebook_jerry_defconfig b/configs/chromebook_jerry_defconfig index 16eee2238b..f6bdf80aee 100644 --- a/configs/chromebook_jerry_defconfig +++ b/configs/chromebook_jerry_defconfig @@ -20,7 +20,7 @@ CONFIG_LOG=y CONFIG_DEFAULT_FDT_FILE="rk3288-veyron-jerry.dtb" # CONFIG_DISPLAY_CPUINFO is not set CONFIG_DISPLAY_BOARDINFO_LATE=y -CONFIG_BOARD_EARLY_INIT_F=y +CONFIG_BOARD_EARLY_INIT_R=y # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set CONFIG_SPL_STACK_R=y CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000 diff --git a/configs/chromebook_minnie_defconfig b/configs/chromebook_minnie_defconfig index 2c0415431f..c229177f64 100644 --- a/configs/chromebook_minnie_defconfig +++ b/configs/chromebook_minnie_defconfig @@ -20,6 +20,7 @@ CONFIG_SILENT_CONSOLE=y CONFIG_DEFAULT_FDT_FILE="rk3288-veyron-minnie.dtb" # CONFIG_DISPLAY_CPUINFO is not set CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_BOARD_EARLY_INIT_R=y # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set CONFIG_SPL_STACK_R=y CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000 diff --git a/configs/chromebook_speedy_defconfig b/configs/chromebook_speedy_defconfig index b4116a34e6..be434871ff 100644 --- a/configs/chromebook_speedy_defconfig +++ b/configs/chromebook_speedy_defconfig @@ -20,7 +20,7 @@ CONFIG_SILENT_CONSOLE=y CONFIG_DEFAULT_FDT_FILE="rk3288-veyron-speedy.dtb" # CONFIG_DISPLAY_CPUINFO is not set CONFIG_DISPLAY_BOARDINFO_LATE=y -CONFIG_BOARD_EARLY_INIT_F=y +CONFIG_BOARD_EARLY_INIT_R=y # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set CONFIG_SPL_STACK_R=y CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000 From e68a84360173f90fa37df875e6aa2c83f2858b80 Mon Sep 17 00:00:00 2001 From: Urja Rannikko Date: Wed, 13 May 2020 19:15:22 +0000 Subject: [PATCH 13/15] rockchip: spl-boot-order: do not attempt to access fdt if OF_PLATDATA gd->fdt_blob is null if using OF_PLATDATA in SPL, which causes a hang after f0921f5098 ("fdt: Sync up to the latest libfdt"). We use the same test that is used in spl_common_init on whether to call fdtdec_setup to unconditionally avoid linking in the fdt-using code when not necessary and thus reduce SPL size. Signed-off-by: Urja Rannikko Reviewed-by: Kever Yang --- arch/arm/mach-rockchip/spl-boot-order.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/mach-rockchip/spl-boot-order.c b/arch/arm/mach-rockchip/spl-boot-order.c index c2e4023007..94673f34c9 100644 --- a/arch/arm/mach-rockchip/spl-boot-order.c +++ b/arch/arm/mach-rockchip/spl-boot-order.c @@ -99,6 +99,12 @@ __weak const char *board_spl_was_booted_from(void) void board_boot_order(u32 *spl_boot_list) { + /* In case of no fdt (or only platdata), use spl_boot_device() */ + if (!CONFIG_IS_ENABLED(OF_CONTROL) || CONFIG_IS_ENABLED(OF_PLATDATA)) { + spl_boot_list[0] = spl_boot_device(); + return; + } + const void *blob = gd->fdt_blob; int chosen_node = fdt_path_offset(blob, "/chosen"); int idx = 0; From 5e50f8787cefd7f35f8d33983876d56d1dc5463a Mon Sep 17 00:00:00 2001 From: Urja Rannikko Date: Wed, 13 May 2020 19:15:23 +0000 Subject: [PATCH 14/15] defconfig: veyron: no need for CONFIG_SPL_PINCTRL_FULL Veyrons do not need full pinctrl support for SPL. The full pinctrl support does nothing when enabled with OF_PLATDATA, thus was already unused. This frees about 4kB of SPL size. Signed-off-by: Urja Rannikko Reviewed-by: Kever Yang --- configs/chromebit_mickey_defconfig | 3 +-- configs/chromebook_jerry_defconfig | 3 +-- configs/chromebook_minnie_defconfig | 3 +-- configs/chromebook_speedy_defconfig | 1 + 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/configs/chromebit_mickey_defconfig b/configs/chromebit_mickey_defconfig index b290f0fcb9..23efafb0d2 100644 --- a/configs/chromebit_mickey_defconfig +++ b/configs/chromebit_mickey_defconfig @@ -73,8 +73,7 @@ CONFIG_SPI_FLASH_GIGADEVICE=y CONFIG_PINCTRL=y CONFIG_PINCONF=y CONFIG_SPL_PINCTRL=y -# CONFIG_SPL_PINMUX is not set -CONFIG_SPL_PINCONF=y +# CONFIG_SPL_PINCTRL_FULL is not set CONFIG_DM_PMIC=y # CONFIG_SPL_PMIC_CHILDREN is not set CONFIG_PMIC_RK8XX=y diff --git a/configs/chromebook_jerry_defconfig b/configs/chromebook_jerry_defconfig index f6bdf80aee..443e3cdace 100644 --- a/configs/chromebook_jerry_defconfig +++ b/configs/chromebook_jerry_defconfig @@ -75,8 +75,7 @@ CONFIG_SPI_FLASH_GIGADEVICE=y CONFIG_PINCTRL=y CONFIG_PINCONF=y CONFIG_SPL_PINCTRL=y -# CONFIG_SPL_PINMUX is not set -CONFIG_SPL_PINCONF=y +# CONFIG_SPL_PINCTRL_FULL is not set CONFIG_DM_PMIC=y # CONFIG_SPL_PMIC_CHILDREN is not set CONFIG_PMIC_RK8XX=y diff --git a/configs/chromebook_minnie_defconfig b/configs/chromebook_minnie_defconfig index c229177f64..99ac0e0674 100644 --- a/configs/chromebook_minnie_defconfig +++ b/configs/chromebook_minnie_defconfig @@ -75,8 +75,7 @@ CONFIG_SPI_FLASH_GIGADEVICE=y CONFIG_PINCTRL=y CONFIG_PINCONF=y CONFIG_SPL_PINCTRL=y -# CONFIG_SPL_PINMUX is not set -CONFIG_SPL_PINCONF=y +# CONFIG_SPL_PINCTRL_FULL is not set CONFIG_DM_PMIC=y # CONFIG_SPL_PMIC_CHILDREN is not set CONFIG_PMIC_RK8XX=y diff --git a/configs/chromebook_speedy_defconfig b/configs/chromebook_speedy_defconfig index be434871ff..5a5152541b 100644 --- a/configs/chromebook_speedy_defconfig +++ b/configs/chromebook_speedy_defconfig @@ -74,6 +74,7 @@ CONFIG_SPI_FLASH_GIGADEVICE=y CONFIG_PINCTRL=y CONFIG_PINCONF=y CONFIG_SPL_PINCTRL=y +# CONFIG_SPL_PINCTRL_FULL is not set CONFIG_DM_PMIC=y # CONFIG_SPL_PMIC_CHILDREN is not set CONFIG_PMIC_RK8XX=y From 33863f744d513f5c16a254870e7b3cef8580bbc9 Mon Sep 17 00:00:00 2001 From: Kurt Miller Date: Wed, 13 May 2020 15:55:20 -0400 Subject: [PATCH 15/15] rockchip: rk3328: rock64 - fix gen3 SPL hang Use the same approach as ROC-RK3328-CC which enables SPL GPIO, pinctl and regulator support. This allows the gen3 board to boot through SPL and does not break gen2 in the process. Signed-off-by: Kurt Miller Acked-by: Matwey V. Kornilov Reviewed-by: Kever Yang --- arch/arm/dts/rk3328-rock64-u-boot.dtsi | 21 +++++++++++++++++++++ configs/rock64-rk3328_defconfig | 7 ++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/arch/arm/dts/rk3328-rock64-u-boot.dtsi b/arch/arm/dts/rk3328-rock64-u-boot.dtsi index 8318bf4e60..f076075076 100644 --- a/arch/arm/dts/rk3328-rock64-u-boot.dtsi +++ b/arch/arm/dts/rk3328-rock64-u-boot.dtsi @@ -11,6 +11,22 @@ }; }; +&gpio0 { + u-boot,dm-spl; +}; + +&pinctrl { + u-boot,dm-spl; +}; + +&sdmmc0m1_gpio { + u-boot,dm-spl; +}; + +&pcfg_pull_up_4ma { + u-boot,dm-spl; +}; + &usb_host0_xhci { vbus-supply = <&vcc_host_5v>; status = "okay"; @@ -25,3 +41,8 @@ /delete-property/ regulator-always-on; /delete-property/ regulator-boot-on; }; + +/* Need this and all the pinctrl/gpio stuff above to set pinmux */ +&vcc_sd { + u-boot,dm-spl; +}; diff --git a/configs/rock64-rk3328_defconfig b/configs/rock64-rk3328_defconfig index 7d096d38c6..0bc2198f5c 100644 --- a/configs/rock64-rk3328_defconfig +++ b/configs/rock64-rk3328_defconfig @@ -1,6 +1,7 @@ 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 @@ -25,6 +26,8 @@ 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 @@ -36,7 +39,7 @@ CONFIG_CMD_TIME=y CONFIG_SPL_OF_CONTROL=y CONFIG_TPL_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="rk3328-rock64" -CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" +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 @@ -64,7 +67,9 @@ 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_SPL_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_REGULATOR_RK8XX=y CONFIG_PWM_ROCKCHIP=y