From e47f97d24810421586f03270cde2126c570c0132 Mon Sep 17 00:00:00 2001 From: jc_gargma Date: Mon, 20 Jan 2020 16:00:16 -0800 Subject: Updated to build from source Added missing python makedepend --- 0001-nvme-support.patch | 1936 --------------------------------------------- PKGBUILD | 63 +- rk3399trust.ini | 17 - uboot-pinebookpro.install | 10 +- 4 files changed, 26 insertions(+), 2000 deletions(-) delete mode 100644 0001-nvme-support.patch delete mode 100644 rk3399trust.ini diff --git a/0001-nvme-support.patch b/0001-nvme-support.patch deleted file mode 100644 index 2b931b6..0000000 --- a/0001-nvme-support.patch +++ /dev/null @@ -1,1936 +0,0 @@ -From ff6151f17ca2f2dca33d63a9fd6db9fde1d6ac3a Mon Sep 17 00:00:00 2001 -From: brian -Date: Wed, 15 May 2019 16:34:25 +0800 -Subject: [PATCH 01/12] pci: add rk3399 pcie driver - -Signed-off-by: brian ---- - drivers/pci/Kconfig | 8 + - drivers/pci/Makefile | 1 + - drivers/pci/pcie.h | 85 +++ - drivers/pci/pcie_rockchip.c | 1144 +++++++++++++++++++++++++++++++++++ - 4 files changed, 1238 insertions(+) - create mode 100644 drivers/pci/pcie.h - create mode 100644 drivers/pci/pcie_rockchip.c - -diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig -index e2a1c0a409..e0faadbf16 100644 ---- a/drivers/pci/Kconfig -+++ b/drivers/pci/Kconfig -@@ -43,6 +43,14 @@ config PCIE_DW_MVEBU - Armada-8K SoCs. The PCIe controller on Armada-8K is based on - DesignWare hardware. - -+config PCIE_ROCKCHIP -+ bool "Enable ROCKCHIP PCIe driver" -+ depends on DM_PCI -+ depends on ROCKCHIP_RK3399 -+ help -+ Say Y here if you want to enable PCIe controller support on -+ rockchip SoCs. -+ - config PCI_SANDBOX - bool "Sandbox PCI support" - depends on SANDBOX && DM_PCI -diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile -index ad44e83996..d4c1664a91 100644 ---- a/drivers/pci/Makefile -+++ b/drivers/pci/Makefile -@@ -30,6 +30,7 @@ obj-$(CONFIG_SH7780_PCI) +=pci_sh7780.o - obj-$(CONFIG_PCI_TEGRA) += pci_tegra.o - obj-$(CONFIG_TSI108_PCI) += tsi108_pci.o - obj-$(CONFIG_PCIE_DW_MVEBU) += pcie_dw_mvebu.o -+obj-$(CONFIG_PCIE_ROCKCHIP) += pcie_rockchip.o - obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape.o - obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape_fixup.o - obj-$(CONFIG_PCI_XILINX) += pcie_xilinx.o -diff --git a/drivers/pci/pcie.h b/drivers/pci/pcie.h -new file mode 100644 -index 0000000000..3d68037e0e ---- /dev/null -+++ b/drivers/pci/pcie.h -@@ -0,0 +1,85 @@ -+/* -+ * (C) Copyright 2016 Rockchip Electronics -+ * Shawn Lin -+ * -+ * SPDX-License-Identifier: GPL-2.0+ -+ */ -+ -+#ifndef __PCIE_H -+#define __PCIE_H -+ -+//#include "../config.h" -+#include -+#include -+#include -+//#include -+#include -+#ifndef CONFIG_RKCHIP_RK3399 -+#define CONFIG_RKCHIP_RK3399 -+#endif -+//#include -+#define CONFIG_RK_LCD_SIZE SZ_32M -+ -+//#define BIT(x) (1 << (x)) -+/* Capability lists */ -+#define PCI_CAP_LIST_ID 0 /* Capability ID */ -+#define PCI_CAP_ID_PM 0x01 /* Power Management */ -+#define PCI_CAP_ID_AGP 0x02 /* Accelerated Graphics Port */ -+#define PCI_CAP_ID_VPD 0x03 /* Vital Product Data */ -+#define PCI_CAP_ID_SLOTID 0x04 /* Slot Identification */ -+#define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */ -+#define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */ -+#define PCI_CAP_ID_PCIX 0x07 /* PCI-X */ -+#define PCI_CAP_ID_HT 0x08 /* HyperTransport */ -+#define PCI_CAP_ID_VNDR 0x09 /* Vendor-Specific */ -+#define PCI_CAP_ID_DBG 0x0A /* Debug port */ -+#define PCI_CAP_ID_CCRC 0x0B /* CompactPCI Central Resource Control */ -+#define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */ -+#define PCI_CAP_ID_SSVID 0x0D /* Bridge subsystem vendor/device ID */ -+#define PCI_CAP_ID_AGP3 0x0E /* AGP Target PCI-PCI bridge */ -+#define PCI_CAP_ID_SECDEV 0x0F /* Secure Device */ -+#define PCI_CAP_ID_EXP 0x10 /* PCI Express */ -+#define PCI_CAP_ID_MSIX 0x11 /* MSI-X */ -+#define PCI_CAP_ID_SATA 0x12 /* SATA Data/Index Conf. */ -+#define PCI_CAP_ID_AF 0x13 /* PCI Advanced Features */ -+#define PCI_CAP_ID_EA 0x14 /* PCI Enhanced Allocation */ -+#define PCI_CAP_ID_MAX PCI_CAP_ID_EA -+#define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */ -+#define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */ -+#define PCI_CAP_SIZEOF 4 -+ -+#define PCI_PRIMARY_BUS 0x18 /* Primary bus number */ -+#define PCI_SUBORDINATE_BUS 0x1a /* Highest bus number behind the bridge */ -+#define PCI_BRIDGE_CONTROL 0x3e -+#define PCI_VENDOR_ID 0x00 /* 16 bits */ -+#define PCI_DEVICE_ID 0x02 /* 16 bits */ -+#define PCI_COMMAND 0x04 /* 16 bits */ -+#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */ -+#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */ -+#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */ -+#define PCI_COMMAND_SPECIAL 0x8 /* Enable response to special cycles */ -+#define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */ -+#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */ -+#define PCI_COMMAND_PARITY 0x40 /* Enable parity checking */ -+#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */ -+#define PCI_COMMAND_SERR 0x100 /* Enable SERR */ -+#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */ -+#define PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */ -+#define PCI_CLASS_REVISION 0x08 /* High 24 bits are class, low 8 revision */ -+#define PCI_CLASS_MSC (0x01 << 24) -+#define PCI_SUBCLASS_NVME (0x08 << 16) -+#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */ -+#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits [htype 0,1 only] */ -+#define PCI_IO_BASE 0x1c /* I/O range behind the bridge */ -+#define PCI_LNKCTL 0xd0 -+#define PCI_EXP_LNKCTL_RL 0x0020 /* Retrain Link */ -+#define PCI_EXP_LNKCTL_CCC 0x0040 /* Common Clock Configuration */ -+#define PCI_RC_CTRL_CAP 0xdc /* Root control and cap */ -+#define PCI_IO_BASE_UPPER16 0x30 /* Upper half of I/O addresses */ -+#define PCI_MEMORY_BASE 0x20 /* Memory range behind */ -+#define PCI_PREF_MEMORY_BASE 0x24 /* Prefetchable memory range behind */ -+#define PCI_PREF_BASE_UPPER32 0x28 /* Upper half of prefetchable memory range */ -+#define PCI_PREF_LIMIT_UPPER32 0x2c -+ -+#define MAX_PCI_REGIONS 7 -+#endif /* __PCIE_H */ -diff --git a/drivers/pci/pcie_rockchip.c b/drivers/pci/pcie_rockchip.c -new file mode 100644 -index 0000000000..e4e696f4b9 ---- /dev/null -+++ b/drivers/pci/pcie_rockchip.c -@@ -0,0 +1,1144 @@ -+ -+#include -+#include -+#include -+#include "pcie.h" -+#include -+#include -+#include -+#include -+#include -+ -+DECLARE_GLOBAL_DATA_PTR; -+ -+static bool fixed_resource; -+enum pcie_reset_id { -+ PCIE_RESET_PHY = 1, -+ PCIE_RESET_ACLK, -+ PCIE_RESET_PCLK, -+ PCIE_RESET_PM, -+ PCIE_RESET_NOFATAL, -+}; -+ -+enum of_gpio_flags { -+ OF_GPIO_ACTIVE_LOW = 0x1, -+}; -+ -+/* -+ * The upper 16 bits of PCIE_CLIENT_CONFIG are a write mask for the lower 16 -+ * bits. This allows atomic updates of the register without locking. -+ */ -+#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_ARI_ENABLE HIWORD_UPDATE_BIT(0x0008) -+#define PCIE_CLIENT_CONF_LANE_NUM(x) HIWORD_UPDATE(0x0030, ENCODE_LANES(x)) -+#define PCIE_CLIENT_MODE_RC HIWORD_UPDATE_BIT(0x0040) -+#define PCIE_CLIENT_GEN_SEL_1 HIWORD_UPDATE(0x0080, 0) -+#define PCIE_CLIENT_GEN_SEL_2 HIWORD_UPDATE_BIT(0x0080) -+#define PCIE_CLIENT_BASIC_STATUS1 (PCIE_CLIENT_BASE + 0x48) -+#define PCIE_CLIENT_LINK_STATUS_UP 0x00300000 -+#define PCIE_CLIENT_LINK_STATUS_MASK 0x00300000 -+#define PCIE_CLIENT_INT_MASK (PCIE_CLIENT_BASE + 0x4c) -+#define PCIE_CLIENT_INT_STATUS (PCIE_CLIENT_BASE + 0x50) -+#define PCIE_CLIENT_INTR_MASK 0x1e0 -+#define PCIE_CLIENT_INTR_SHIFT 5 -+#define PCIE_CLIENT_INT_LEGACY_DONE BIT(15) -+#define PCIE_CLIENT_INT_MSG BIT(14) -+#define PCIE_CLIENT_INT_HOT_RST BIT(13) -+#define PCIE_CLIENT_INT_DPA BIT(12) -+#define PCIE_CLIENT_INT_FATAL_ERR BIT(11) -+#define PCIE_CLIENT_INT_NFATAL_ERR BIT(10) -+#define PCIE_CLIENT_INT_CORR_ERR BIT(9) -+#define PCIE_CLIENT_INT_INTD BIT(8) -+#define PCIE_CLIENT_INT_INTC BIT(7) -+#define PCIE_CLIENT_INT_INTB BIT(6) -+#define PCIE_CLIENT_INT_INTA BIT(5) -+#define PCIE_CLIENT_INT_LOCAL BIT(4) -+#define PCIE_CLIENT_INT_UDMA BIT(3) -+#define PCIE_CLIENT_INT_PHY BIT(2) -+#define PCIE_CLIENT_INT_HOT_PLUG BIT(1) -+#define PCIE_CLIENT_INT_PWR_STCG BIT(0) -+ -+#define PCIE_CLIENT_INT_LEGACY \ -+ (PCIE_CLIENT_INT_INTA | PCIE_CLIENT_INT_INTB | \ -+ PCIE_CLIENT_INT_INTC | PCIE_CLIENT_INT_INTD) -+ -+#define PCIE_CLIENT_INT_CLI \ -+ (PCIE_CLIENT_INT_CORR_ERR | PCIE_CLIENT_INT_NFATAL_ERR | \ -+ PCIE_CLIENT_INT_FATAL_ERR | PCIE_CLIENT_INT_DPA | \ -+ PCIE_CLIENT_INT_HOT_RST | PCIE_CLIENT_INT_MSG | \ -+ PCIE_CLIENT_INT_LEGACY_DONE | PCIE_CLIENT_INT_LEGACY | \ -+ PCIE_CLIENT_INT_PHY) -+ -+#define PCIE_CORE_CTRL_MGMT_BASE 0x900000 -+#define PCIE_CORE_CTRL (PCIE_CORE_CTRL_MGMT_BASE + 0x000) -+#define PCIE_CORE_PL_CONF_SPEED_5G 0x00000008 -+#define PCIE_CORE_PL_CONF_SPEED_MASK 0x00000018 -+#define PCIE_CORE_PL_CONF_LANE_MASK 0x00000006 -+#define PCIE_CORE_PL_CONF_LANE_SHIFT 1 -+#define PCIE_CORE_CTRL_PLC1 (PCIE_CORE_CTRL_MGMT_BASE + 0x004) -+#define PCIE_CORE_CTRL_PLC1_FTS_MASK 0xffff00 -+#define PCIE_CORE_CTRL_PLC1_FTS_SHIFT 8 -+#define PCIE_CORE_CTRL_PLC1_FTS_CNT 0xffff -+#define PCIE_CORE_TXCREDIT_CFG1 (PCIE_CORE_CTRL_MGMT_BASE + 0x020) -+#define PCIE_CORE_TXCREDIT_CFG1_MUI_MASK 0xFFFF0000 -+#define PCIE_CORE_TXCREDIT_CFG1_MUI_SHIFT 16 -+#define PCIE_CORE_TXCREDIT_CFG1_MUI_ENCODE(x) \ -+ (((x) >> 3) << PCIE_CORE_TXCREDIT_CFG1_MUI_SHIFT) -+#define PCIE_CORE_INT_STATUS (PCIE_CORE_CTRL_MGMT_BASE + 0x20c) -+#define PCIE_CORE_INT_PRFPE BIT(0) -+#define PCIE_CORE_INT_CRFPE BIT(1) -+#define PCIE_CORE_INT_RRPE BIT(2) -+#define PCIE_CORE_INT_PRFO BIT(3) -+#define PCIE_CORE_INT_CRFO BIT(4) -+#define PCIE_CORE_INT_RT BIT(5) -+#define PCIE_CORE_INT_RTR BIT(6) -+#define PCIE_CORE_INT_PE BIT(7) -+#define PCIE_CORE_INT_MTR BIT(8) -+#define PCIE_CORE_INT_UCR BIT(9) -+#define PCIE_CORE_INT_FCE BIT(10) -+#define PCIE_CORE_INT_CT BIT(11) -+#define PCIE_CORE_INT_UTC BIT(18) -+#define PCIE_CORE_INT_MMVC BIT(19) -+#define PCIE_CORE_CONFIG_VENDOR (PCIE_CORE_CTRL_MGMT_BASE + 0x44) -+#define PCIE_CORE_INT_MASK (PCIE_CORE_CTRL_MGMT_BASE + 0x210) -+#define PCIE_RC_BAR_CONF (PCIE_CORE_CTRL_MGMT_BASE + 0x300) -+ -+#define PCIE_CORE_INT \ -+ (PCIE_CORE_INT_PRFPE | PCIE_CORE_INT_CRFPE | \ -+ PCIE_CORE_INT_RRPE | PCIE_CORE_INT_CRFO | \ -+ PCIE_CORE_INT_RT | PCIE_CORE_INT_RTR | \ -+ PCIE_CORE_INT_PE | PCIE_CORE_INT_MTR | \ -+ PCIE_CORE_INT_UCR | PCIE_CORE_INT_FCE | \ -+ PCIE_CORE_INT_CT | PCIE_CORE_INT_UTC | \ -+ PCIE_CORE_INT_MMVC) -+ -+#define PCIE_RC_CONFIG_BASE 0xa00000 -+#define PCIE_RC_CONFIG_VENDOR (PCIE_RC_CONFIG_BASE + 0x0) -+#define PCIE_RC_CONFIG_RID_CCR (PCIE_RC_CONFIG_BASE + 0x08) -+#define PCIE_RC_CONFIG_SCC_SHIFT 16 -+#define PCIE_RC_CONFIG_DCR (PCIE_RC_CONFIG_BASE + 0xc4) -+#define PCIE_RC_CONFIG_DCR_CSPL_SHIFT 18 -+#define PCIE_RC_CONFIG_DCR_CSPL_LIMIT 0xff -+#define PCIE_RC_CONFIG_DCR_CPLS_SHIFT 26 -+#define PCIE_RC_CONFIG_LINK_CAP (PCIE_RC_CONFIG_BASE + 0xcc) -+#define PCIE_RC_CONFIG_LINK_CAP_L0S BIT(10) -+#define PCIE_RC_CONFIG_LCS (PCIE_RC_CONFIG_BASE + 0xd0) -+#define PCIE_RC_CONFIG_L1_SUBSTATE_CTRL2 (PCIE_RC_CONFIG_BASE + 0x90c) -+#define PCIE_RC_CONFIG_THP_CAP (PCIE_RC_CONFIG_BASE + 0x274) -+#define PCIE_RC_CONFIG_THP_CAP_NEXT_MASK 0xfff00000 -+ -+#define PCIE_CORE_AXI_CONF_BASE 0xc00000 -+#define PCIE_CORE_OB_REGION_ADDR0 (PCIE_CORE_AXI_CONF_BASE + 0x0) -+#define PCIE_CORE_OB_REGION_ADDR0_NUM_BITS 0x3f -+#define PCIE_CORE_OB_REGION_ADDR0_LO_ADDR 0xffffff00 -+#define PCIE_CORE_OB_REGION_ADDR1 (PCIE_CORE_AXI_CONF_BASE + 0x4) -+#define PCIE_CORE_OB_REGION_DESC0 (PCIE_CORE_AXI_CONF_BASE + 0x8) -+#define PCIE_CORE_OB_REGION_DESC1 (PCIE_CORE_AXI_CONF_BASE + 0xc) -+ -+#define PCIE_CORE_AXI_INBOUND_BASE 0xc00800 -+#define PCIE_RP_IB_ADDR0 (PCIE_CORE_AXI_INBOUND_BASE + 0x0) -+#define PCIE_CORE_IB_REGION_ADDR0_NUM_BITS 0x3f -+#define PCIE_CORE_IB_REGION_ADDR0_LO_ADDR 0xffffff00 -+#define PCIE_RP_IB_ADDR1 (PCIE_CORE_AXI_INBOUND_BASE + 0x4) -+ -+/* Size of one AXI Region (not Region 0) */ -+#define AXI_REGION_SIZE BIT(20) -+/* Size of Region 0, equal to sum of sizes of other regions */ -+#define AXI_REGION_0_SIZE (32 * (0x1 << 20)) -+#define OB_REG_SIZE_SHIFT 5 -+#define IB_ROOT_PORT_REG_SIZE_SHIFT 3 -+#define AXI_WRAPPER_IO_WRITE 0x6 -+#define AXI_WRAPPER_MEM_WRITE 0x2 -+ -+#define MAX_AXI_IB_ROOTPORT_REGION_NUM 3 -+#define MIN_AXI_ADDR_BITS_PASSED 8 -+#define ROCKCHIP_VENDOR_ID 0x1d87 -+#define PCIE_ECAM_BUS(x) (((x) & 0xff) << 20) -+#define PCIE_ECAM_DEV(x) (((x) & 0x1f) << 15) -+#define PCIE_ECAM_FUNC(x) (((x) & 0x7) << 12) -+#define PCIE_ECAM_REG(x) (((x) & 0xfff) << 0) -+#define PCIE_ECAM_ADDR(bus, dev, func, reg) \ -+ (PCIE_ECAM_BUS(bus) | PCIE_ECAM_DEV(dev) | \ -+ PCIE_ECAM_FUNC(func) | PCIE_ECAM_REG(reg)) -+ -+#define RC_REGION_0_ADDR_TRANS_H 0x00000000 -+#define RC_REGION_0_ADDR_TRANS_L 0x00000000 -+#define RC_REGION_0_PASS_BITS (25 - 1) -+#define MAX_AXI_WRAPPER_REGION_NUM 33 -+ -+#define PCI_CLASS_BRIDGE_PCI 0x0604 -+ -+#define HIWORD_UPDATE_PHY(val, mask, shift) \ -+ ((val) << (shift) | (mask) << ((shift) + 16)) -+ -+#define PHY_MAX_LANE_NUM 4 -+#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_A_STATUS 0x30 -+#define PHY_LANE_B_STATUS 0x31 -+#define PHY_LANE_C_STATUS 0x32 -+#define PHY_LANE_D_STATUS 0x33 -+#define PHY_LANE_RX_DET_SHIFT 11 -+#define PHY_LANE_RX_DET_TH 0x1 -+#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 -+ -+struct rockchip_pcie_phy { -+ u64 reg_base; -+ u64 pcie_conf; -+ u32 pcie_status; -+ u32 rst_addr; -+}; -+ -+struct pcie_bus { -+ struct pci_region regions[MAX_PCI_REGIONS]; -+ u32 region_count; -+ u64 msi_base; -+}; -+ -+struct pcie_rockchip { -+ int first_busno; -+ u32 rst_addr; -+ u64 axi_base; -+ u32 axi_size; -+ u64 apb_base; -+ struct rockchip_pcie_phy phy; -+ struct gpio_desc rst_gpio; -+ struct pcie_bus bus; -+}; -+ -+#define RKIO_CRU_PHYS 0xFF760000 -+#define RKIO_GRF_PHYS 0xFF770000 -+#define CRU_SOFTRST_CON 0x400 -+#define CRU_SOFTRSTS_CON(i) (CRU_SOFTRST_CON + ((i) * 4)) -+void rkcru_pcie_soft_reset(enum pcie_reset_id id, u32 val) -+{ -+ if (id == PCIE_RESET_PHY) { -+ writel((0x1 << 23) | (val << 7), -+ RKIO_CRU_PHYS + CRU_SOFTRSTS_CON(8)); -+ } else if (id == PCIE_RESET_ACLK) { -+ writel((0x1 << 16) | (val << 0), -+ RKIO_CRU_PHYS + CRU_SOFTRSTS_CON(8)); -+ } else if (id == PCIE_RESET_PCLK) { -+ writel((0x1 << 17) | (val << 1), -+ RKIO_CRU_PHYS + CRU_SOFTRSTS_CON(8)); -+ } else if (id == PCIE_RESET_PM) { -+ writel((0x1 << 22) | (val << 6), -+ RKIO_CRU_PHYS + CRU_SOFTRSTS_CON(8)); -+ } else if (id == PCIE_RESET_NOFATAL) { -+ if (val) -+ val = 0xf; -+ -+ writel((0xf << 18) | (val << 2), -+ RKIO_CRU_PHYS + CRU_SOFTRSTS_CON(8)); -+ } else { -+ debug("%s: incorrect reset ops\n", __func__); -+ } -+} -+ -+ -+static inline u32 phy_rd_cfg(struct rockchip_pcie_phy *rk_phy, -+ u32 addr) -+{ -+ writel(HIWORD_UPDATE_PHY(addr, -+ PHY_CFG_RD_MASK, -+ PHY_CFG_ADDR_SHIFT), -+ rk_phy->reg_base + rk_phy->pcie_conf); -+ return readl(rk_phy->reg_base + rk_phy->pcie_status); -+} -+ -+static inline void phy_wr_cfg(struct rockchip_pcie_phy *rk_phy, -+ u32 addr, u32 data) -+{ -+ writel(HIWORD_UPDATE_PHY(data, PHY_CFG_DATA_MASK, -+ PHY_CFG_DATA_SHIFT) | -+ HIWORD_UPDATE_PHY(addr, PHY_CFG_ADDR_MASK, -+ PHY_CFG_ADDR_SHIFT), -+ rk_phy->reg_base + rk_phy->pcie_conf); -+ -+ udelay(3); -+ writel(HIWORD_UPDATE_PHY(PHY_CFG_WR_ENABLE, -+ PHY_CFG_WR_MASK, -+ PHY_CFG_WR_SHIFT), -+ rk_phy->reg_base + rk_phy->pcie_conf); -+ -+ udelay(3); -+ writel(HIWORD_UPDATE_PHY(PHY_CFG_WR_DISABLE, -+ PHY_CFG_WR_MASK, -+ PHY_CFG_WR_SHIFT), -+ rk_phy->reg_base + rk_phy->pcie_conf); -+} -+ -+/** -+ * 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 pcie_rockchip_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; -+} -+ -+static int rockchip_pcie_rd_own_conf(void *priv, int where, int size, u32 *val) -+{ -+ struct pcie_rockchip *rockchip = (struct pcie_rockchip *)priv; -+ u64 addr = rockchip->apb_base + PCIE_RC_CONFIG_BASE + where; -+ -+ if (size == 4) { -+ *val = readl(addr); -+ } else if (size == 2) { -+ *val = readw(addr); -+ } else if (size == 1) { -+ *val = readb(addr); -+ } else { -+ *val = 0; -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static int rockchip_pcie_wr_own_conf(void *priv, int where, int size, u32 val) -+{ -+ struct pcie_rockchip *rockchip = (struct pcie_rockchip *)priv; -+ u32 mask, tmp, offset; -+ -+ offset = where & ~0x3; -+ if (size == 4) { -+ writel(val, (u64)(rockchip->apb_base + PCIE_RC_CONFIG_BASE + offset)); -+ return 0; -+ } -+ -+ mask = ~(((1 << (size * 8)) - 1) << ((where & 0x3) * 8)); -+ -+ /* -+ * N.B. This read/modify/write isn't safe in general because it can -+ * corrupt RW1C bits in adjacent registers. But the hardware -+ * doesn't support smaller writes. -+ */ -+ tmp = readl(rockchip->apb_base + PCIE_RC_CONFIG_BASE + offset) & mask; -+ tmp |= val << ((where & 0x3) * 8); -+ writel(tmp, rockchip->apb_base + PCIE_RC_CONFIG_BASE + offset); -+ -+ return 0; -+} -+ -+static int rockchip_pcie_rd_other_conf(void *priv, int where, -+ int size, u32 *val) -+{ -+ u32 busdev; -+ struct pcie_rockchip *rockchip = (struct pcie_rockchip *)priv; -+ -+ /* -+ * BDF = 01:00:00 -+ * end-to-end support, no hierarchy.... -+ */ -+ busdev = PCIE_ECAM_ADDR(1, 0, 0, where); -+ -+ if (size == 4) { -+ *val = readl(rockchip->axi_base + busdev); -+ } else if (size == 2) { -+ *val = readw(rockchip->axi_base + busdev); -+ } else if (size == 1) { -+ *val = readb(rockchip->axi_base + busdev); -+ } else { -+ *val = 0; -+ return -1; -+ } -+ return 0; -+} -+ -+static int rockchip_pcie_wr_other_conf(void *priv, int where, int size, u32 val) -+{ -+ struct pcie_rockchip *rockchip = (struct pcie_rockchip *)priv; -+ u32 busdev; -+ -+ /* -+ * BDF = 01:00:00 -+ * end-to-end support, no hierarchy.... -+ */ -+ busdev = PCIE_ECAM_ADDR(1, 0, 0, where); -+ -+ if (size == 4) -+ writel(val, rockchip->axi_base + busdev); -+ else if (size == 2) -+ writew(val, rockchip->axi_base + busdev); -+ else if (size == 1) -+ writeb(val, rockchip->axi_base + busdev); -+ else -+ return -1; -+ -+ return 0; -+} -+ -+static int pcie_rockchip_read_config(struct udevice *bus, pci_dev_t bdf, -+ uint offset, ulong *valuep, enum pci_size_t size) -+{ -+ struct pcie_rockchip *pcie = dev_get_priv(bus); -+ int size1; -+ int ret; -+ -+ if (!pcie_rockchip_addr_valid(bdf, pcie->first_busno)) { -+ debug("- out of range\n"); -+ *valuep = pci_get_ff(size); -+ return 0; -+ } -+ -+ if( size == PCI_SIZE_8 ) -+ size1 = 1; -+ else if( size == PCI_SIZE_16 ) -+ size1 = 2; -+ else if( size == PCI_SIZE_32 ) -+ size1 = 4; -+ else { -+ debug("invalid\n"); -+ return -1; -+ } -+ -+ if(PCI_BUS(bdf) == pcie->first_busno) { -+ ret = rockchip_pcie_rd_own_conf(pcie, offset, size1,(u32 *)valuep); -+ if(ret < 0) -+ return ret; -+ } else { -+ ret = rockchip_pcie_rd_other_conf(pcie, offset, size1, (u32 *)valuep); -+ if(ret < 0) -+ return ret; -+ } -+ return 0; -+} -+ -+static int pcie_rockchip_write_config(struct udevice *bus, pci_dev_t bdf, -+ uint offset, ulong value, enum pci_size_t size) -+{ -+ struct pcie_rockchip *pcie = dev_get_priv(bus); -+ int size1; -+ int ret; -+ if (!pcie_rockchip_addr_valid(bdf, pcie->first_busno)) { -+ debug("- out of range\n"); -+ return 0; -+ } -+ if( size == PCI_SIZE_8 ) -+ size1 = 1; -+ else if( size == PCI_SIZE_16 ) -+ size1 = 2; -+ else if( size == PCI_SIZE_32 ) -+ size1 = 4; -+ else { -+ debug("invalid\n"); -+ return -1; -+ } -+ -+ -+ if(PCI_BUS(bdf) == pcie->first_busno) { -+ ret = rockchip_pcie_wr_own_conf(pcie, offset, size1, value); -+ if(ret < 0) -+ return ret; -+ } else { -+ ret = rockchip_pcie_wr_other_conf(pcie, offset, size1, value); -+ if(ret < 0) -+ return ret; -+ } -+ return 0; -+} -+static u32 rockchip_pcie_read(struct pcie_rockchip *rockchip, u32 reg) -+{ -+ return readl(rockchip->apb_base + reg); -+} -+ -+static void rockchip_pcie_write(struct pcie_rockchip *rockchip, u32 val, u32 reg) -+{ -+ writel(val, rockchip->apb_base + reg); -+} -+ -+ -+static int config_link(struct udevice *dev) -+{ -+ struct pcie_rockchip *rockchip = dev_get_priv(dev); -+ u32 value,timeout, i; -+ u32 pointer, next_pointer; -+ u32 table_size; -+ u64 msix_table_addr = 0x0; -+ bool is_msi = false, is_msix = false; -+ u32 cmd; -+ -+ rockchip_pcie_rd_other_conf((void *)rockchip, PCI_CLASS_REVISION, 4, &value); -+ if ((value & (0xffff << 16)) != -+ (PCI_CLASS_MSC | PCI_SUBCLASS_NVME)) { -+ debug("PCIe: device's classe code & revision ID = 0x%x\n", -+ value); -+ debug("PCIe: We only support NVMe\n"); -+ return -EINVAL; -+ } -+ -+ rockchip_pcie_rd_other_conf((void *)rockchip, PCI_VENDOR_ID, 2, &value); -+ rockchip_pcie_rd_other_conf((void *)rockchip, PCI_DEVICE_ID, 2, &value); -+ -+ rockchip_pcie_wr_own_conf((void *)rockchip, PCI_PRIMARY_BUS, 4, 0x0); -+ rockchip_pcie_wr_own_conf((void *)rockchip, PCI_BRIDGE_CONTROL, 2, 0x0); -+ rockchip_pcie_wr_own_conf((void *)rockchip, PCI_COMMAND + 0x2, 2, 0xffff); -+ rockchip_pcie_wr_own_conf((void *)rockchip, PCI_PRIMARY_BUS, 4, 0xff0100); -+ /* only support 64bit non-prefetchable 16k mem region: BAR0 + BAR1 -+ * clear BAR1 for upper 32bit, no need to wr all 1s to see the size -+ */ -+ rockchip_pcie_wr_other_conf((void *)rockchip, PCI_BASE_ADDRESS_1, 4, 0x0); -+ -+ /* clear CCC and enable retrain link */ -+ rockchip_pcie_rd_own_conf((void *)rockchip, PCI_LNKCTL, 2, &value); -+ value &= ~PCI_EXP_LNKCTL_CCC; -+ value |= PCI_EXP_LNKCTL_RL; -+ rockchip_pcie_wr_own_conf((void *)rockchip, PCI_LNKCTL, 2, value); -+ -+ /* wait for clear of LTS */ -+ timeout = 2000; -+ while (timeout--) { -+ rockchip_pcie_rd_own_conf((void *)rockchip, PCI_LNKCTL + 0x2, 2, &value); -+ if (!(value & BIT(11))) -+ break; -+ mdelay(1); -+ } -+ if (!timeout) { -+ debug("PCIe: fail to clear LTS\n"); -+ return -ETIMEDOUT; -+ } -+ -+ /* write SBN */ -+ rockchip_pcie_wr_own_conf((void *)rockchip, PCI_SUBORDINATE_BUS, 1, 0x1); -+ /* clear some enable bits for error */ -+ rockchip_pcie_wr_own_conf((void *)rockchip, PCI_BRIDGE_CONTROL, 2, 0x0); -+ /* write EP's command register, disable EP */ -+ rockchip_pcie_wr_other_conf((void *)rockchip, PCI_COMMAND, 2, 0x0); -+ -+ for (i = 0; i < rockchip->bus.region_count; i++) { -+ if (rockchip->bus.regions[i].flags == PCI_REGION_MEM) { -+ /* configre BAR0 */ -+ rockchip_pcie_wr_other_conf((void *)rockchip, PCI_BASE_ADDRESS_0, 4, -+ rockchip->bus.regions[i].bus_start); -+ /* configre BAR1 */ -+ rockchip_pcie_wr_other_conf((void *)rockchip, PCI_BASE_ADDRESS_1, -+ 4, 0x0); -+ break; -+ } -+ } -+ -+ /* write EP's command register */ -+ rockchip_pcie_wr_other_conf((void *)rockchip, PCI_COMMAND, 2, 0x0); -+ -+ /* write RC's IO base and limit including upper */ -+ rockchip_pcie_wr_own_conf((void *)rockchip, PCI_IO_BASE_UPPER16, 4, 0xffff); -+ rockchip_pcie_wr_own_conf((void *)rockchip, PCI_IO_BASE, 2, 0xf0); -+ rockchip_pcie_wr_own_conf((void *)rockchip, PCI_IO_BASE_UPPER16, 4, 0x0); -+ /* write RC's Mem base and limit including upper */ -+ value = (rockchip->bus.regions[i].bus_start) >> 16; -+ rockchip_pcie_wr_own_conf((void *)rockchip, PCI_MEMORY_BASE, 4, -+ value | (value << 16)); -+ rockchip_pcie_wr_own_conf((void *)rockchip, PCI_PREF_LIMIT_UPPER32, 4, 0x0); -+ rockchip_pcie_wr_own_conf((void *)rockchip, PCI_PREF_MEMORY_BASE, 4, 0xfff0); -+ rockchip_pcie_wr_own_conf((void *)rockchip, PCI_PREF_BASE_UPPER32, 4, 0x0); -+ rockchip_pcie_wr_own_conf((void *)rockchip, PCI_PREF_LIMIT_UPPER32, 4, 0x0); -+ /* clear some enable bits for error */ -+ rockchip_pcie_wr_own_conf((void *)rockchip, PCI_BRIDGE_CONTROL, 2, 0x0); -+ -+ /* read RC root control and cap, clear some int enable */ -+ rockchip_pcie_wr_own_conf((void *)rockchip, PCI_RC_CTRL_CAP, 2, 0x0); -+ -+ /* clear RC's error status, correctable and uncorectable error */ -+ rockchip_pcie_wr_own_conf((void *)rockchip, 0x130, 4, 0x0); -+ rockchip_pcie_wr_own_conf((void *)rockchip, 0x110, 4, 0x0); -+ rockchip_pcie_wr_own_conf((void *)rockchip, 0x104, 4, 0x0); -+ -+ value = 0; -+ rockchip_pcie_rd_other_conf((void *)rockchip, 0x34, 1, &pointer); -+ debug("PCIe: cap pointer = 0x%x\n", pointer); -+ -+ for (;;) { -+ rockchip_pcie_rd_other_conf((void *)rockchip, pointer, 2, &next_pointer); -+ if ((next_pointer & 0xff) == PCI_CAP_ID_MSI) { -+ is_msi = true; -+ break; -+ } else if ((next_pointer & 0xff) == PCI_CAP_ID_MSIX) { -+ is_msix = true; -+ break; -+ } -+ -+ pointer = (next_pointer >> 8); -+ if (pointer == 0) -+ break; -+ } -+ if (is_msi) { -+ debug("PCIe: msi cap pointer = 0x%x\n", pointer); -+ rockchip_pcie_rd_other_conf((void *)rockchip, pointer + 2, 2, &value); -+ value |= 0x1; -+ rockchip_pcie_wr_other_conf((void *)rockchip, pointer + 2, 2, value); -+ rockchip_pcie_wr_other_conf((void *)rockchip, pointer + 4, 4, -+ rockchip->bus.msi_base); -+ rockchip_pcie_wr_other_conf((void *)rockchip, pointer + 8, 4, 0x0); -+ } else if (is_msix) { -+ debug("PCIe: msi-x cap pointer = 0x%x\n", pointer); -+ rockchip_pcie_rd_other_conf((void *)rockchip, pointer + 2, 2, &value); -+ debug("PCIe: msi-x table size = %d\n", value & 0x7ff); -+ table_size = value & 0x7ff; -+ rockchip_pcie_rd_other_conf((void *)rockchip, pointer + 8, 2, &value); -+ debug("PCIe: msi-x BIR = 0x%x\n", value & 0x7); -+ debug("PCIe: msi-x table offset = 0x%x\n", value & 0xfffffff8); -+ -+ for (i = 0; i < rockchip->bus.region_count; i++) { -+ if (rockchip->bus.regions[i].flags == PCI_REGION_MEM) -+ msix_table_addr = rockchip->bus.regions[i].bus_start + -+ (value & 0xfffffff8); -+ } -+ -+ if (msix_table_addr == 0) -+ return -EINVAL; -+ -+ debug("PCIe: msi-x table begin addr = 0x%llx\n", -+ msix_table_addr); -+ for (i = 0; i < table_size; i++) { -+ writel(rockchip->bus.msi_base, msix_table_addr + i * 0x0); -+ writel(0x0, msix_table_addr + i * 0x4); -+ writel(i, msix_table_addr + i * 0x8); -+ writel(0x0, msix_table_addr + i * 0xc); -+ } -+ rockchip_pcie_wr_other_conf((void *)rockchip, pointer + 2, 2, 0x20); -+ rockchip_pcie_wr_other_conf((void *)rockchip, pointer + 2, 2, 0xc020); -+ rockchip_pcie_wr_other_conf((void *)rockchip, pointer + 2, 2, 0x8020); -+ } else { -+ debug("PCIe: no msi and msi-x\n"); -+ } -+ -+ rockchip_pcie_rd_other_conf((void *)rockchip, PCI_COMMAND, 2, &value); -+ value |= PCI_COMMAND_INTX_DISABLE; -+ rockchip_pcie_wr_other_conf((void *)rockchip, PCI_COMMAND, 2, value); -+ -+ rockchip_pcie_rd_other_conf((void *)rockchip, PCI_COMMAND, 2, &cmd); -+ cmd = (cmd | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); -+ rockchip_pcie_wr_other_conf((void *)rockchip, PCI_COMMAND, 2, cmd); -+ -+ return 0; -+} -+ -+static int phy_init(struct rockchip_pcie_phy *rk_phy) -+{ -+ /* -+ * uboot should enable all the clks and please don't -+ * modify the PCIe clock hierarchy. We need 24M from OSC -+ * for the phy. -+ */ -+ -+ /* assert phy-rst SOFTRST_CON8 */ -+ rkcru_pcie_soft_reset(PCIE_RESET_PHY, 1); -+ return 0; -+} -+ -+static int phy_power_on(struct rockchip_pcie_phy *rk_phy) -+{ -+ u32 status; -+ u32 timeout = 2000; -+ -+ -+ /* deassert phy-rst */ -+ debug("PCIe phy_power_on start! rk_phy->reg_base = 0x%x, \n",(u32)rk_phy->reg_base); -+ rkcru_pcie_soft_reset(PCIE_RESET_PHY, 0); -+ /* lock-> sel & scc -> relock */ -+ writel(HIWORD_UPDATE_PHY(PHY_CFG_PLL_LOCK, -+ PHY_CFG_ADDR_MASK, -+ PHY_CFG_ADDR_SHIFT), -+ rk_phy->reg_base + rk_phy->pcie_conf); -+ -+ while (timeout--) { -+ status = readl(rk_phy->reg_base + rk_phy->pcie_status); -+ if (status & PHY_PLL_LOCKED) { -+ debug("pll locked!\n"); -+ break; -+ } -+ mdelay(1); -+ } -+ -+ if (timeout == 0) { -+ debug("pll lock timeout\n"); -+ return -1; -+ } -+ -+ phy_wr_cfg(rk_phy, PHY_CFG_CLK_TEST, PHY_CFG_SEPE_RATE); -+ phy_wr_cfg(rk_phy, PHY_CFG_CLK_SCC, PHY_CFG_PLL_100M); -+ -+ timeout = 2000; -+ while (timeout--) { -+ status = readl(rk_phy->reg_base + rk_phy->pcie_status); -+ if (!(status & PHY_PLL_OUTPUT)) { -+ debug("pll output enable done!\n"); -+ break; -+ } -+ mdelay(1); -+ } -+ -+ if (timeout == 0) { -+ debug("pll output enable timeout\n"); -+ return -1; -+ } -+ -+ writel(HIWORD_UPDATE_PHY(PHY_CFG_PLL_LOCK, -+ PHY_CFG_ADDR_MASK, -+ PHY_CFG_ADDR_SHIFT), -+ rk_phy->reg_base + rk_phy->pcie_conf); -+ -+ timeout = 2000; -+ while (timeout--) { -+ status = readl(rk_phy->reg_base + rk_phy->pcie_status); -+ if (status & PHY_PLL_LOCKED) { -+ debug("pll relocked!\n"); -+ break; -+ } -+ mdelay(1); -+ } -+ -+ if (timeout == 0) { -+ debug("pll relock timeout\n"); -+ return -1; -+ } -+ -+ debug("PCIe phy_power_on end!\n"); -+ -+ return 0; -+} -+ -+static int rockchip_pcie_init_port(struct pcie_rockchip *rockchip) -+{ -+ u32 status; -+ u32 timeout; -+ u32 reg; -+ -+ /* assert aclk_rst */ -+ rkcru_pcie_soft_reset(PCIE_RESET_ACLK, 1); -+ /* assert pclk_rst */ -+ rkcru_pcie_soft_reset(PCIE_RESET_ACLK, 1); -+ /* assert pm_rst */ -+ rkcru_pcie_soft_reset(PCIE_RESET_PM, 1); -+ -+ udelay(10); /* need a nearly 10us delay per design */ -+ -+ /* deassert aclk_rst */ -+ rkcru_pcie_soft_reset(PCIE_RESET_PM, 0); -+ /* deassert pclk_rst */ -+ rkcru_pcie_soft_reset(PCIE_RESET_ACLK, 0); -+ /* deassert pm_rst */ -+ rkcru_pcie_soft_reset(PCIE_RESET_PCLK, 0); -+ -+ phy_init(&rockchip->phy); -+ -+ /* assert: mgmt_sticky_rst->core_rst->mgmt_rst->pipe_rst */ -+ rkcru_pcie_soft_reset(PCIE_RESET_NOFATAL, 1); -+ -+ rockchip_pcie_write(rockchip, PCIE_CLIENT_GEN_SEL_1, -+ PCIE_CLIENT_CONFIG); -+ -+ rockchip_pcie_write(rockchip, -+ PCIE_CLIENT_CONF_ENABLE | -+ PCIE_CLIENT_LINK_TRAIN_ENABLE | -+ PCIE_CLIENT_ARI_ENABLE | -+ PCIE_CLIENT_CONF_LANE_NUM(4) | -+ PCIE_CLIENT_MODE_RC, -+ PCIE_CLIENT_CONFIG); -+ -+ phy_power_on(&rockchip->phy); -+ -+ /* assert: mgmt_sticky_rst->core_rst->mgmt_rst->pipe_rst */ -+ rkcru_pcie_soft_reset(PCIE_RESET_NOFATAL, 0); -+ -+ /* Enable Gen1 training */ -+ rockchip_pcie_write(rockchip, PCIE_CLIENT_LINK_TRAIN_ENABLE, -+ PCIE_CLIENT_CONFIG); -+ -+ if (!fixed_resource) { -+ dm_gpio_set_value(&rockchip->rst_gpio, 1); -+ } else { -+ #ifdef CONFIG_RKCHIP_RK3399 -+ /* GPIO4 D3 output high level */ -+ debug("pcie_cdns: warning: double check your reset io\n"); -+ reg = readl(0xff790000); -+ reg |= BIT(27); -+ writel(reg, 0xff790000); -+ #else -+ debug("please do the correct reset ops for pcie_cdns\n"); -+ #endif -+ } -+ -+ timeout = 2000; -+ while (--timeout) { -+ status = rockchip_pcie_read(rockchip, -+ PCIE_CLIENT_BASIC_STATUS1); -+ if ((status & PCIE_CLIENT_LINK_STATUS_MASK) == -+ PCIE_CLIENT_LINK_STATUS_UP) { -+ debug("PCIe link training gen1 pass!\n"); -+ break; -+ } -+ mdelay(1); -+ } -+ -+ if (!timeout) { -+ debug("PCIe link training gen1 timeout!\n"); -+ return -ETIMEDOUT; -+ } -+ -+ /* Check the final link width from negotiated lane counter from MGMT */ -+ status = rockchip_pcie_read(rockchip, PCIE_CORE_CTRL); -+ status = 0x1 << ((status & PCIE_CORE_PL_CONF_LANE_MASK) >> -+ PCIE_CORE_PL_CONF_LANE_SHIFT); -+ debug("current link width is x%d\n", status); -+ -+ rockchip_pcie_write(rockchip, ROCKCHIP_VENDOR_ID, -+ PCIE_CORE_CONFIG_VENDOR); -+ rockchip_pcie_write(rockchip, -+ PCI_CLASS_BRIDGE_PCI << PCIE_RC_CONFIG_SCC_SHIFT, -+ PCIE_RC_CONFIG_RID_CCR); -+ rockchip_pcie_write(rockchip, 0x0, PCIE_RC_BAR_CONF); -+ rockchip_pcie_write(rockchip, -+ (RC_REGION_0_ADDR_TRANS_L + RC_REGION_0_PASS_BITS), -+ PCIE_CORE_OB_REGION_ADDR0); -+ rockchip_pcie_write(rockchip, RC_REGION_0_ADDR_TRANS_H, -+ PCIE_CORE_OB_REGION_ADDR1); -+ rockchip_pcie_write(rockchip, 0x0080000a, PCIE_CORE_OB_REGION_DESC0); -+ rockchip_pcie_write(rockchip, 0x0, PCIE_CORE_OB_REGION_DESC1); -+ return 0; -+} -+ -+static int rockchip_pcie_prog_ob_atu(struct pcie_rockchip *rockchip, -+ int region_no, int type, u8 num_pass_bits, -+ u32 lower_addr, u32 upper_addr) -+{ -+ u32 ob_addr_0; -+ u32 ob_addr_1; -+ u32 ob_desc_0; -+ u32 aw_offset; -+ -+ if (region_no >= MAX_AXI_WRAPPER_REGION_NUM) -+ return -1; -+ if (num_pass_bits + 1 < 8) -+ return -1; -+ if (num_pass_bits > 63) -+ return -1; -+ if (region_no == 0) { -+ if (AXI_REGION_0_SIZE < (2ULL << num_pass_bits)) -+ return -1; -+ } -+ if (region_no != 0) { -+ if (AXI_REGION_SIZE < (2ULL << num_pass_bits)) -+ return -1; -+ } -+ -+ aw_offset = (region_no << OB_REG_SIZE_SHIFT); -+ -+ ob_addr_0 = num_pass_bits & PCIE_CORE_OB_REGION_ADDR0_NUM_BITS; -+ ob_addr_0 |= lower_addr & PCIE_CORE_OB_REGION_ADDR0_LO_ADDR; -+ ob_addr_1 = upper_addr; -+ ob_desc_0 = (1 << 23 | type); -+ rockchip_pcie_write(rockchip, ob_addr_0, -+ PCIE_CORE_OB_REGION_ADDR0 + aw_offset); -+ rockchip_pcie_write(rockchip, ob_addr_1, -+ PCIE_CORE_OB_REGION_ADDR1 + aw_offset); -+ rockchip_pcie_write(rockchip, ob_desc_0, -+ PCIE_CORE_OB_REGION_DESC0 + aw_offset); -+ rockchip_pcie_write(rockchip, 0, -+ PCIE_CORE_OB_REGION_DESC1 + aw_offset); -+ -+ return 0; -+} -+ -+static int rockchip_pcie_prog_ib_atu(struct pcie_rockchip *rockchip, -+ int region_no, u8 num_pass_bits, -+ u32 lower_addr, u32 upper_addr) -+{ -+ u32 ib_addr_0; -+ u32 ib_addr_1; -+ u32 aw_offset; -+ -+ if (region_no > MAX_AXI_IB_ROOTPORT_REGION_NUM) -+ return -1; -+ if (num_pass_bits + 1 < MIN_AXI_ADDR_BITS_PASSED) -+ return -1; -+ if (num_pass_bits > 63) -+ return -1; -+ -+ aw_offset = (region_no << IB_ROOT_PORT_REG_SIZE_SHIFT); -+ -+ ib_addr_0 = num_pass_bits & PCIE_CORE_IB_REGION_ADDR0_NUM_BITS; -+ ib_addr_0 |= (lower_addr << 8) & PCIE_CORE_IB_REGION_ADDR0_LO_ADDR; -+ ib_addr_1 = upper_addr; -+ rockchip_pcie_write(rockchip, ib_addr_0, PCIE_RP_IB_ADDR0 + aw_offset); -+ rockchip_pcie_write(rockchip, ib_addr_1, PCIE_RP_IB_ADDR1 + aw_offset); -+ -+ return 0; -+} -+ -+static int rockchip_pcie_cfg_atu(struct pcie_rockchip *rockchip) -+{ -+ u64 mem_bus_addr = rockchip->axi_base + rockchip->axi_size; -+ u32 mem_size = 0; -+ u64 io_bus_addr = mem_bus_addr + mem_size; -+ u32 io_size = 0;struct pcie_bus *pbus = &rockchip->bus; -+ int reg_no = 0; -+ int offset; -+ int err, i; -+ for (i = 0; i < pbus->region_count; i++) { -+ if (pbus->regions[i].flags == PCI_REGION_MEM) { -+ mem_size = (u32)(pbus->regions[i].size); -+ debug("mem_size = 0x%x\n", mem_size); -+ } else if (pbus->regions[i].flags == PCI_REGION_IO) { -+ io_size = pbus->regions[i].size; -+ debug("io_size = 0x%x\n", io_size); -+ } -+ } -+ if (mem_size) { -+ for (reg_no = 0; reg_no < (mem_size >> 20); reg_no++) { -+ err = rockchip_pcie_prog_ob_atu(rockchip, reg_no + 1, -+ AXI_WRAPPER_MEM_WRITE, -+ 20 - 1, -+ mem_bus_addr + -+ (reg_no << 20), -+ 0); -+ if (err) -+ debug("program RC mem outbound ATU failed\n"); -+ } -+ } -+ err = rockchip_pcie_prog_ib_atu(rockchip, 2, 32 - 1, 0x0, 0); -+ if (err) -+ debug("program RC mem inbound ATU failed\n"); -+ offset = mem_size >> 20; -+ if (io_size) { -+ for (reg_no = 0; reg_no < (io_size >> 20); reg_no++) { -+ err = rockchip_pcie_prog_ob_atu(rockchip, -+ reg_no + 1 + offset, -+ AXI_WRAPPER_IO_WRITE, -+ 20 - 1, -+ io_bus_addr + -+ (reg_no << 20), -+ 0); -+ if (err) -+ debug("program RC io outbound ATU failed\n"); -+ } -+ } -+ return 0; -+} -+ -+const char *compat[] = { -+ "rockchip,rk3399-pcie", -+}; -+ -+static int pcie_rockchip_probe(struct udevice *dev) -+{ -+ -+ struct pcie_rockchip *rockchip = dev_get_priv(dev); -+ int err; -+ -+ -+ rockchip->first_busno = dev->seq; -+ /* Setup link */ -+ err = rockchip_pcie_init_port(rockchip); -+ if (err) { -+ debug("failed to init port\n"); -+ return err; -+ } -+ /* Setup ATU */ -+ err = rockchip_pcie_cfg_atu(rockchip); -+ if(err) { -+ debug("failed to configure atu\n"); -+ return err; -+ } -+ -+ config_link(dev); -+ return 0; -+} -+ -+ -+static int pcie_rockchip_ofdata_to_platdata(struct udevice *dev) -+{ -+ struct pcie_rockchip *rockchip = dev_get_priv(dev); -+ int node = -1; -+ int i; -+ u32 reg; -+ struct fdt_resource res_axi, res_apb; -+ struct udevice *ctrl = pci_get_controller(dev); -+ struct pci_controller *hose = dev_get_uclass_priv(ctrl); -+ struct pcie_bus *pbus = &rockchip->bus; -+ -+ if( !gd->fdt_blob) { -+ debug("rockchip_pcie_parse_dt: gd->fdt_blob no found\n"); -+ fixed_resource = true; -+ goto do_fixed; -+ } -+ -+ for (i = 0; i < ARRAY_SIZE(compat); i++) { -+ node = fdt_node_offset_by_compatible(gd->fdt_blob, 0, compat[i]); -+ if (node > 0) -+ break; -+ } -+ -+ if (node < 0) { -+ debug("rockchip_pcie_parse_dt: no compat found\n"); -+ return node; -+ } -+ -+ i = fdt_get_named_resource(gd->fdt_blob, node, "reg", "reg-names", -+ "axi-base", &res_axi); -+ if (i) { -+ debug("can't get regs axi-base addresses!\n"); -+ return -ENOMEM; -+ } -+ -+ i = fdt_get_named_resource(gd->fdt_blob, node, "reg", "reg-names", -+ "apb-base", &res_apb); -+ if (i) { -+ debug("can't get regs apb-base addresses!\n"); -+ return -ENOMEM; -+ } -+do_fixed: -+ if(fixed_resource) { -+ #ifdef CONFIG_RKCHIP_RK3399 -+ rockchip->axi_base = 0xf8000000; -+ rockchip->apb_base = 0xfd000000; -+ rockchip->axi_size = 0x2000000; -+ #else -+ debug("please assign your PCIe resource\n"); -+ return -EINVAL; -+ #endif -+ } else { -+ rockchip->axi_base = res_axi.start; -+ rockchip->apb_base = res_apb.start; -+ rockchip->axi_size = res_axi.end - res_axi.start + 1; -+ } -+ -+ if(fixed_resource) { -+ #ifdef CONFIG_RKCHIP_RK3399 -+ -+ rockchip->phy.reg_base = RKIO_GRF_PHYS; -+ rockchip->phy.rst_addr = RKIO_CRU_PHYS + 0x420; -+ rockchip->phy.pcie_conf = 0xe220; -+ rockchip->phy.pcie_status = 0xe2a4; -+ rockchip->rst_addr = RKIO_CRU_PHYS + 0x420; -+ rockchip->bus.msi_base = 0xfee30040; -+ #else -+ debug("please assign your PCIe resource\n"); -+ return -EINVAL; -+ #endif -+ } else if (!strcmp(compat[i], "rockchip,rk3399-pcie")) { -+ rockchip->phy.reg_base = RKIO_GRF_PHYS; -+ rockchip->phy.rst_addr = RKIO_CRU_PHYS + 0x420; -+ rockchip->phy.pcie_conf = 0xe220; -+ rockchip->phy.pcie_status = 0xe2a4; -+ rockchip->rst_addr = RKIO_CRU_PHYS + 0x420; -+ rockchip->bus.msi_base = 0xfee30040; -+ } else { -+ debug("unknown Soc using pcie_cdns\n"); -+ return -EINVAL; -+ } -+ -+ if (fixed_resource) -+ goto fixed_rst; -+#ifdef CONFIG_DM_GPIO -+ gpio_request_by_name(dev, "ep-gpios", 0, &rockchip->rst_gpio, GPIOD_IS_OUT); -+ -+ if (dm_gpio_is_valid(&rockchip->rst_gpio)) { -+ dm_gpio_set_value(&rockchip->rst_gpio, 0); -+ mdelay(200); -+ }; -+ -+#else -+ debug("PCIE Reset on GPIO support is missing\n"); -+#endif -+ pbus->regions[0].flags = PCI_REGION_MEM; -+ pbus->regions[0].phys_start = hose->regions[0].phys_start; -+ pbus->regions[0].bus_start = hose->regions[0].bus_start; -+ pbus->regions[0].size = hose->regions[0].size; -+ pbus->regions[1].flags = PCI_REGION_IO; -+ pbus->regions[1].phys_start = hose->regions[1].phys_start; -+ pbus->regions[1].bus_start = hose->regions[1].bus_start; -+ pbus->regions[1].size = hose->regions[1].size; -+ pbus->region_count = 2; -+ return 0; -+ -+fixed_rst: -+ #ifdef CONFIG_RKCHIP_RK3399 -+ /* set GPIO4 D3 as output low now*/ -+ debug("pcie: warning: double check your PCIe reset gpio!\n"); -+ writel((0x3 << 30) | (0x0 << 14), RKIO_GRF_PHYS + 0xe010); -+ reg = readl(0xff790000 + 0x4); -+ reg |= BIT(27); -+ writel(reg, 0xff790000 + 0x4); -+ reg = readl(0xff790000); -+ reg &= ~BIT(27); -+ writel(reg, 0xff790000); -+ pbus->regions[0].flags = PCI_REGION_MEM; -+ pbus->regions[0].phys_start = 0xfa000000; -+ pbus->regions[0].bus_start = 0xfa000000; -+ pbus->regions[0].size = 0x600000; -+ pbus->regions[1].flags = PCI_REGION_IO; -+ pbus->regions[1].phys_start = 0xfa600000; -+ pbus->regions[1].bus_start = 0xfa600000; -+ pbus->regions[1].size = 0x100000; -+ pbus->region_count = 2; -+ -+ return 0; -+ #else -+ debug("please assign the fixed_rst\n"); -+ return -EINVAL; -+ #endif -+} -+ -+ -+static const struct dm_pci_ops pcie_rockchip_ops = { -+ .read_config = pcie_rockchip_read_config, -+ .write_config = pcie_rockchip_write_config, -+}; -+ -+static const struct udevice_id pcie_rockchip_ids[] = { -+ { .compatible = "rockchip,rk3399-pcie" }, -+ { } -+}; -+ -+ -+U_BOOT_DRIVER(pcie_rockchip) = { -+ .name = "pcie_rockchip", -+ .id = UCLASS_PCI, -+ .of_match = pcie_rockchip_ids, -+ .ops = &pcie_rockchip_ops, -+ .ofdata_to_platdata = pcie_rockchip_ofdata_to_platdata, -+ .probe = pcie_rockchip_probe, -+ .priv_auto_alloc_size = sizeof(struct pcie_rockchip), -+}; -+ -+ - -From f85a4725e660e9614d496cccc9d6b52b23360e65 Mon Sep 17 00:00:00 2001 -From: Bin Meng -Date: Wed, 15 May 2019 08:37:56 -0700 -Subject: [PATCH 02/12] nvme: Fix warning of cast from pointer to integer of - different size - -When dma_addr_t is u32 in 64-bit, there are some warnings when -building NVME driver. Fix it by doing an additional (long) cast. - -Signed-off-by: Bin Meng ---- - drivers/nvme/nvme.c | 4 ++-- - drivers/nvme/nvme_show.c | 4 ++-- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c -index 1c3519ba74..636a2d3ac1 100644 ---- a/drivers/nvme/nvme.c -+++ b/drivers/nvme/nvme.c -@@ -578,7 +578,7 @@ static int nvme_get_info_from_identify(struct nvme_dev *dev) - int ret; - int shift = NVME_CAP_MPSMIN(dev->cap) + 12; - -- ret = nvme_identify(dev, 0, 1, (dma_addr_t)ctrl); -+ ret = nvme_identify(dev, 0, 1, (dma_addr_t)(long)ctrl); - if (ret) - return -EIO; - -@@ -647,7 +647,7 @@ static int nvme_blk_probe(struct udevice *udev) - ns->dev = ndev; - /* extract the namespace id from the block device name */ - ns->ns_id = trailing_strtol(udev->name) + 1; -- if (nvme_identify(ndev, ns->ns_id, 0, (dma_addr_t)id)) -+ if (nvme_identify(ndev, ns->ns_id, 0, (dma_addr_t)(long)id)) - return -EIO; - - flbas = id->flbas & NVME_NS_FLBAS_LBA_MASK; -diff --git a/drivers/nvme/nvme_show.c b/drivers/nvme/nvme_show.c -index 52351388e2..1aa3838c2a 100644 ---- a/drivers/nvme/nvme_show.c -+++ b/drivers/nvme/nvme_show.c -@@ -112,14 +112,14 @@ int nvme_print_info(struct udevice *udev) - ALLOC_CACHE_ALIGN_BUFFER(char, buf_ctrl, sizeof(struct nvme_id_ctrl)); - struct nvme_id_ctrl *ctrl = (struct nvme_id_ctrl *)buf_ctrl; - -- if (nvme_identify(dev, 0, 1, (dma_addr_t)ctrl)) -+ if (nvme_identify(dev, 0, 1, (dma_addr_t)(long)ctrl)) - return -EIO; - - print_optional_admin_cmd(le16_to_cpu(ctrl->oacs), ns->devnum); - print_optional_nvm_cmd(le16_to_cpu(ctrl->oncs), ns->devnum); - print_format_nvme_attributes(ctrl->fna, ns->devnum); - -- if (nvme_identify(dev, ns->ns_id, 0, (dma_addr_t)id)) -+ if (nvme_identify(dev, ns->ns_id, 0, (dma_addr_t)(long)id)) - return -EIO; - - print_formats(id, ns); - -From 56d2cd1f5e58fbbcbe46e9caec48057148713e8b Mon Sep 17 00:00:00 2001 -From: Aaron Williams -Date: Thu, 22 Aug 2019 20:37:26 -0700 -Subject: [PATCH 03/12] nvme: Fix PRP Offset Invalid - -When large writes take place I saw a Samsung EVO 970+ return a status -value of 0x13, PRP Offset Invalid. I tracked this down to the -improper handling of PRP entries. The blocks the PRP entries are -placed in cannot cross a page boundary and thus should be allocated -on page boundaries. This is how the Linux kernel driver works. - -With this patch, the PRP pool is allocated on a page boundary and -other than the very first allocation, the pool size is a multiple of -the page size. Each page can hold (4096 / 8) - 1 entries since the -last entry must point to the next page in the pool. - -Signed-off-by: Aaron Williams -Reviewed-by: Bin Meng ---- - drivers/nvme/nvme.c | 29 +++++++++++++++++++---------- - 1 file changed, 19 insertions(+), 10 deletions(-) - -diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c -index 636a2d3ac1..3fd98b2f1d 100644 ---- a/drivers/nvme/nvme.c -+++ b/drivers/nvme/nvme.c -@@ -74,6 +74,9 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2, - u64 *prp_pool; - int length = total_len; - int i, nprps; -+ u32 prps_per_page = (page_size >> 3) - 1; -+ u32 num_pages; -+ - length -= (page_size - offset); - - if (length <= 0) { -@@ -90,15 +93,20 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2, - } - - nprps = DIV_ROUND_UP(length, page_size); -+ num_pages = DIV_ROUND_UP(nprps, prps_per_page); - - if (nprps > dev->prp_entry_num) { - free(dev->prp_pool); -- dev->prp_pool = malloc(nprps << 3); -+ /* -+ * Always increase in increments of pages. It doesn't waste -+ * much memory and reduces the number of allocations. -+ */ -+ dev->prp_pool = memalign(page_size, num_pages * page_size); - if (!dev->prp_pool) { - printf("Error: malloc prp_pool fail\n"); - return -ENOMEM; - } -- dev->prp_entry_num = nprps; -+ dev->prp_entry_num = prps_per_page * num_pages; - } - - prp_pool = dev->prp_pool; -@@ -790,14 +798,6 @@ static int nvme_probe(struct udevice *udev) - } - memset(ndev->queues, 0, NVME_Q_NUM * sizeof(struct nvme_queue *)); - -- ndev->prp_pool = malloc(MAX_PRP_POOL); -- if (!ndev->prp_pool) { -- ret = -ENOMEM; -- printf("Error: %s: Out of memory!\n", udev->name); -- goto free_nvme; -- } -- ndev->prp_entry_num = MAX_PRP_POOL >> 3; -- - ndev->cap = nvme_readq(&ndev->bar->cap); - ndev->q_depth = min_t(int, NVME_CAP_MQES(ndev->cap) + 1, NVME_Q_DEPTH); - ndev->db_stride = 1 << NVME_CAP_STRIDE(ndev->cap); -@@ -807,6 +807,15 @@ static int nvme_probe(struct udevice *udev) - if (ret) - goto free_queue; - -+ /* Allocate after the page size is known */ -+ ndev->prp_pool = memalign(ndev->page_size, MAX_PRP_POOL); -+ if (!ndev->prp_pool) { -+ ret = -ENOMEM; -+ printf("Error: %s: Out of memory!\n", udev->name); -+ goto free_nvme; -+ } -+ ndev->prp_entry_num = MAX_PRP_POOL >> 3; -+ - ret = nvme_setup_io_queues(ndev); - if (ret) - goto free_queue; - -From 94d53b2bcb33db5cc1dff8a579ca32da56c6d95d Mon Sep 17 00:00:00 2001 -From: Patrick Wildt -Date: Thu, 3 Oct 2019 13:48:47 +0200 -Subject: [PATCH 04/12] nvme: add accessor to namespace id and eui64 - -This adds a function which can be used by e.g. EFI to retrieve -the namespace identifier and EUI64. For that it adds the EUI64 -to its driver internal namespace structure and copies the EUI64 -during namespace identification. - -Signed-off-by: Patrick Wildt -Tested-by: Heinrich Schuchardt -Reviewed-by: Bin Meng ---- - drivers/nvme/nvme.c | 13 +++++++++++++ - drivers/nvme/nvme.h | 1 + - include/nvme.h | 12 ++++++++++++ - 3 files changed, 26 insertions(+) - -diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c -index 3fd98b2f1d..b9a29cdf79 100644 ---- a/drivers/nvme/nvme.c -+++ b/drivers/nvme/nvme.c -@@ -622,6 +622,18 @@ static int nvme_get_info_from_identify(struct nvme_dev *dev) - return 0; - } - -+int nvme_get_namespace_id(struct udevice *udev, u32 *ns_id, u8 *eui64) -+{ -+ struct nvme_ns *ns = dev_get_priv(udev); -+ -+ if (ns_id) -+ *ns_id = ns->ns_id; -+ if (eui64) -+ memcpy(eui64, ns->eui64, sizeof(ns->eui64)); -+ -+ return 0; -+} -+ - int nvme_scan_namespace(void) - { - struct uclass *uc; -@@ -658,6 +670,7 @@ static int nvme_blk_probe(struct udevice *udev) - if (nvme_identify(ndev, ns->ns_id, 0, (dma_addr_t)(long)id)) - return -EIO; - -+ memcpy(&ns->eui64, &id->eui64, sizeof(id->eui64)); - flbas = id->flbas & NVME_NS_FLBAS_LBA_MASK; - ns->flbas = flbas; - ns->lba_shift = id->lbaf[flbas].ds; -diff --git a/drivers/nvme/nvme.h b/drivers/nvme/nvme.h -index 67bf6e187f..a6b98e0cc5 100644 ---- a/drivers/nvme/nvme.h -+++ b/drivers/nvme/nvme.h -@@ -638,6 +638,7 @@ struct nvme_ns { - struct list_head list; - struct nvme_dev *dev; - unsigned ns_id; -+ u8 eui64[8]; - int devnum; - int lba_shift; - u8 flbas; -diff --git a/include/nvme.h b/include/nvme.h -index 8375d61e02..7e66c37639 100644 ---- a/include/nvme.h -+++ b/include/nvme.h -@@ -79,4 +79,16 @@ int nvme_scan_namespace(void); - */ - int nvme_print_info(struct udevice *udev); - -+/** -+ * nvme_get_namespace_id - return namespace identifier -+ * -+ * This returns the namespace identifier. -+ * -+ * @udev: NVMe controller device -+ * @ns_id: Place where to put the name space identifier -+ * @eui64: Place where to put the IEEE Extended Unique Identifier -+ * @return: 0 on success, -ve on error -+ */ -+int nvme_get_namespace_id(struct udevice *udev, u32 *ns_id, u8 *eui64); -+ - #endif /* __NVME_H__ */ - -From 674cfc997907aead6fdd4605e30fb036f0af5111 Mon Sep 17 00:00:00 2001 -From: Patrick Wildt -Date: Wed, 16 Oct 2019 23:22:50 +0200 -Subject: [PATCH 05/12] nvme: flush dcache on both r/w, and the prp list - -It's possible that the data cache for the buffer still holds data -to be flushed to memory, since the buffer was probably used as stack -before. Thus we need to make sure to flush it also on reads, since -it's possible that the cache is automatically flused to memory after -the NVMe DMA transfer happened, thus overwriting the NVMe transfer's -data. Also add a missing dcache flush for the prp list. - -Signed-off-by: Patrick Wildt -Reviewed-by: Bin Meng ---- - drivers/nvme/nvme.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c -index b9a29cdf79..88bb93a7a1 100644 ---- a/drivers/nvme/nvme.c -+++ b/drivers/nvme/nvme.c -@@ -124,6 +124,9 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2, - } - *prp2 = (ulong)dev->prp_pool; - -+ flush_dcache_range((ulong)dev->prp_pool, (ulong)dev->prp_pool + -+ dev->prp_entry_num * sizeof(u64)); -+ - return 0; - } - -@@ -707,9 +710,8 @@ static ulong nvme_blk_rw(struct udevice *udev, lbaint_t blknr, - u16 lbas = 1 << (dev->max_transfer_shift - ns->lba_shift); - u64 total_lbas = blkcnt; - -- if (!read) -- flush_dcache_range((unsigned long)buffer, -- (unsigned long)buffer + total_len); -+ flush_dcache_range((unsigned long)buffer, -+ (unsigned long)buffer + total_len); - - c.rw.opcode = read ? nvme_cmd_read : nvme_cmd_write; - c.rw.flags = 0; - -From cefb73541899430569130dcfdc6069f8cd863401 Mon Sep 17 00:00:00 2001 -From: Patrick Wildt -Date: Wed, 16 Oct 2019 08:42:04 +0200 -Subject: [PATCH 06/12] nvme: use page-aligned buffer for identify command - -Change the stack-allocated buffer for the identification command -to explicitly allocate page-aligned buffers. Even though the spec -seems to allow having admin queue commands on non page-aligned -buffers, it seems to not be possible on my i.MX8MQ board with a -a Silicon Power P34A80. Since all of the NVMe drivers I have seen -always do admin commands on a page-aligned buffer, which does work -on my system, it makes sense for us to do that as well. - -Signed-off-by: Patrick Wildt -Reviewed-by: Bin Meng ---- - drivers/nvme/nvme.c | 24 ++++++++++++++++++------ - 1 file changed, 18 insertions(+), 6 deletions(-) - -diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c -index 88bb93a7a1..adf4ea0646 100644 ---- a/drivers/nvme/nvme.c -+++ b/drivers/nvme/nvme.c -@@ -584,14 +584,19 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) - - static int nvme_get_info_from_identify(struct nvme_dev *dev) - { -- ALLOC_CACHE_ALIGN_BUFFER(char, buf, sizeof(struct nvme_id_ctrl)); -- struct nvme_id_ctrl *ctrl = (struct nvme_id_ctrl *)buf; -+ struct nvme_id_ctrl *ctrl; - int ret; - int shift = NVME_CAP_MPSMIN(dev->cap) + 12; - -+ ctrl = memalign(dev->page_size, sizeof(struct nvme_id_ctrl)); -+ if (!ctrl) -+ return -ENOMEM; -+ - ret = nvme_identify(dev, 0, 1, (dma_addr_t)(long)ctrl); -- if (ret) -+ if (ret) { -+ free(ctrl); - return -EIO; -+ } - - dev->nn = le32_to_cpu(ctrl->nn); - dev->vwc = ctrl->vwc; -@@ -622,6 +627,7 @@ static int nvme_get_info_from_identify(struct nvme_dev *dev) - dev->max_transfer_shift = 20; - } - -+ free(ctrl); - return 0; - } - -@@ -662,16 +668,21 @@ static int nvme_blk_probe(struct udevice *udev) - struct blk_desc *desc = dev_get_uclass_platdata(udev); - struct nvme_ns *ns = dev_get_priv(udev); - u8 flbas; -- ALLOC_CACHE_ALIGN_BUFFER(char, buf, sizeof(struct nvme_id_ns)); -- struct nvme_id_ns *id = (struct nvme_id_ns *)buf; - struct pci_child_platdata *pplat; -+ struct nvme_id_ns *id; -+ -+ id = memalign(ndev->page_size, sizeof(struct nvme_id_ns)); -+ if (!id) -+ return -ENOMEM; - - memset(ns, 0, sizeof(*ns)); - ns->dev = ndev; - /* extract the namespace id from the block device name */ - ns->ns_id = trailing_strtol(udev->name) + 1; -- if (nvme_identify(ndev, ns->ns_id, 0, (dma_addr_t)(long)id)) -+ if (nvme_identify(ndev, ns->ns_id, 0, (dma_addr_t)(long)id)) { -+ free(id); - return -EIO; -+ } - - memcpy(&ns->eui64, &id->eui64, sizeof(id->eui64)); - flbas = id->flbas & NVME_NS_FLBAS_LBA_MASK; -@@ -691,6 +702,7 @@ static int nvme_blk_probe(struct udevice *udev) - memcpy(desc->revision, ndev->firmware_rev, sizeof(ndev->firmware_rev)); - part_init(desc); - -+ free(id); - return 0; - } - - -From d584cd5c8968678e8477467ec4931468cb680f8a Mon Sep 17 00:00:00 2001 -From: Heinrich Schuchardt -Date: Fri, 21 Dec 2018 02:18:16 +0100 -Subject: [PATCH 07/12] distro_bootcmd: add NVME support - -Some boards support NVME drives. We should be able to use them as boot -devices. - -NVME access requires running 'nvme scan'. - -Signed-off-by: Heinrich Schuchardt -Reviewed-by: Simon Glass -Signed-off-by: Alexander Graf ---- - include/config_distro_bootcmd.h | 27 +++++++++++++++++++++++++++ - 1 file changed, 27 insertions(+) - -diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h -index 1d9056c92f..3e1f2b5464 100644 ---- a/include/config_distro_bootcmd.h -+++ b/include/config_distro_bootcmd.h -@@ -162,6 +162,31 @@ - BOOT_TARGET_DEVICES_references_SATA_without_CONFIG_SATA - #endif - -+#ifdef CONFIG_NVME -+#define BOOTENV_RUN_NVME_INIT "run nvme_init; " -+#define BOOTENV_SET_NVME_NEED_INIT "setenv nvme_need_init; " -+#define BOOTENV_SHARED_NVME \ -+ "nvme_init=" \ -+ "if ${nvme_need_init}; then " \ -+ "setenv nvme_need_init false; " \ -+ "nvme scan; " \ -+ "fi\0" \ -+ \ -+ "nvme_boot=" \ -+ BOOTENV_RUN_NVME_INIT \ -+ BOOTENV_SHARED_BLKDEV_BODY(nvme) -+#define BOOTENV_DEV_NVME BOOTENV_DEV_BLKDEV -+#define BOOTENV_DEV_NAME_NVME BOOTENV_DEV_NAME_BLKDEV -+#else -+#define BOOTENV_RUN_NVME_INIT -+#define BOOTENV_SET_NVME_NEED_INIT -+#define BOOTENV_SHARED_NVME -+#define BOOTENV_DEV_NVME \ -+ BOOT_TARGET_DEVICES_references_NVME_without_CONFIG_NVME -+#define BOOTENV_DEV_NAME_NVME \ -+ BOOT_TARGET_DEVICES_references_NVME_without_CONFIG_NVME -+#endif -+ - #ifdef CONFIG_SCSI - #define BOOTENV_RUN_SCSI_INIT "run scsi_init; " - #define BOOTENV_SET_SCSI_NEED_INIT "setenv scsi_need_init; " -@@ -320,6 +345,7 @@ - BOOTENV_SHARED_USB \ - BOOTENV_SHARED_SATA \ - BOOTENV_SHARED_SCSI \ -+ BOOTENV_SHARED_NVME \ - BOOTENV_SHARED_IDE \ - BOOTENV_SHARED_UBIFS \ - BOOTENV_SHARED_EFI \ -@@ -392,6 +418,7 @@ - BOOT_TARGET_DEVICES(BOOTENV_DEV) \ - \ - "distro_bootcmd=" BOOTENV_SET_SCSI_NEED_INIT \ -+ BOOTENV_SET_NVME_NEED_INIT \ - "for target in ${boot_targets}; do " \ - "run bootcmd_${target}; " \ - "done\0" - -From e8be135d0780361a689ba4c23d2b36f3f31fc27d Mon Sep 17 00:00:00 2001 -From: Patrick Wildt -Date: Thu, 3 Oct 2019 11:10:57 +0200 -Subject: [PATCH 08/12] NVMe: do PCI enumerate before nvme scan - -Make sure that the PCI busses are enumerated before trying to -find a NVMe device. - -Signed-off-by: Patrick Wildt -Reviewed-by: Bin Meng ---- - include/config_distro_bootcmd.h | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h -index 3e1f2b5464..af47e2039d 100644 ---- a/include/config_distro_bootcmd.h -+++ b/include/config_distro_bootcmd.h -@@ -173,6 +173,7 @@ - "fi\0" \ - \ - "nvme_boot=" \ -+ BOOTENV_RUN_PCI_ENUM \ - BOOTENV_RUN_NVME_INIT \ - BOOTENV_SHARED_BLKDEV_BODY(nvme) - #define BOOTENV_DEV_NVME BOOTENV_DEV_BLKDEV - -From 1ff1111432ef85b4ebf63b6e3cba9033b608f005 Mon Sep 17 00:00:00 2001 -From: pcm720 -Date: Thu, 28 Nov 2019 15:44:54 +0300 -Subject: [PATCH 09/12] arm: dts: pinebookpro: Add PCIe definitions - ---- - arch/arm/dts/rk3399-pinebook-pro.dts | 29 ++++++++++++++++++++++++++++ - 1 file changed, 29 insertions(+) - -diff --git a/arch/arm/dts/rk3399-pinebook-pro.dts b/arch/arm/dts/rk3399-pinebook-pro.dts -index 3e88976115..af64d9c1a3 100644 ---- a/arch/arm/dts/rk3399-pinebook-pro.dts -+++ b/arch/arm/dts/rk3399-pinebook-pro.dts -@@ -234,6 +234,19 @@ - vin-supply = <&dc_12v>; - }; - */ -+ -+ vcc3v3_pcie: vcc3v3-pcie-regulator { -+ compatible = "regulator-fixed"; -+ enable-active-high; -+ gpio = <&gpio1 RK_PD0 GPIO_ACTIVE_HIGH>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie_pwr_en>; -+ regulator-name = "vcc3v3_pcie"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ vin-supply = <&dc_12v>; -+ }; -+ - vcc1v8_sdio: vcca1v8_sdio: vcc1v8-sdio { - u-boot,dm-pre-reloc; - compatible = "regulator-fixed"; -@@ -341,6 +354,21 @@ - status = "okay"; - }; - -+&pcie_phy { -+ status = "okay"; -+}; -+ -+&pcie0 { -+ ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>; -+ num-lanes = <4>; -+ max-link-speed = <2>; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&pcie_clkreqn_cpm>; -+ vpcie3v3-supply = <&vcc3v3_pcie>; -+ bus-scan-delay-ms = <1000>; -+ status = "okay"; -+}; -+ - &sdio0 { - u-boot,dm-pre-reloc; - clock-frequency = <50000000>; -@@ -360,6 +388,7 @@ - vqmmc-supply = <&vcc1v8_sdio>; /* IO line */ - vmmc-supply = <&vcc3v0_sdio>; /* card's power */ - status = "okay"; -+ defer_pcie = <2000>; - }; - - &sdmmc { - -From 42167d9ae003d56a75fdcfb9da2af12b68c3c151 Mon Sep 17 00:00:00 2001 -From: pcm720 -Date: Thu, 28 Nov 2019 15:48:04 +0300 -Subject: [PATCH 10/12] configs: pinebookpro-rk3399_defconfig: Enable NVMe - support - ---- - configs/pinebookpro-rk3399_defconfig | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/configs/pinebookpro-rk3399_defconfig b/configs/pinebookpro-rk3399_defconfig -index 640d49593a..8180b60e28 100644 ---- a/configs/pinebookpro-rk3399_defconfig -+++ b/configs/pinebookpro-rk3399_defconfig -@@ -146,3 +146,12 @@ CONFIG_SPL_TINY_MEMSET=y - CONFIG_ERRNO_STR=y - CONFIG_DM_REGULATOR_GPIO=y - CONFIG_DEVRES=y -+CONFIG_HAVE_BLOCK_DEVICE=y -+CONFIG_SPL_GPIO_SUPPORT=y -+CONFIG_SPL_PCI_SUPPORT=y -+CONFIG_CMD_PCI=y -+CONFIG_CMD_CACHE=y -+CONFIG_NVME=y -+CONFIG_PCI=y -+CONFIG_DM_PCI=y -+CONFIG_PCIE_ROCKCHIP=y - -From ef8a863863d8773f178096c921a604fe53a67b27 Mon Sep 17 00:00:00 2001 -From: pcm720 -Date: Thu, 28 Nov 2019 16:05:35 +0300 -Subject: [PATCH 11/12] configs: rockchip: Add NVMe to boot targets - ---- - include/configs/rockchip-common.h | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/include/configs/rockchip-common.h b/include/configs/rockchip-common.h -index 93b5e205fb..fc9048d16a 100644 ---- a/include/configs/rockchip-common.h -+++ b/include/configs/rockchip-common.h -@@ -48,6 +48,12 @@ - #define BOOT_TARGET_MMC0(func) - #endif - -+#if (CONFIG_IS_ENABLED(CMD_NVME) && CONFIG_IS_ENABLED(CMD_CACHE) && CONFIG_IS_ENABLED(CMD_PCI)) -+ #define BOOT_TARGET_NVME(func) func(NVME, nvme, 0) -+#else -+ #define BOOT_TARGET_NVME(func) -+#endif -+ - #if CONFIG_IS_ENABLED(CMD_RKNAND) - #define BOOT_TARGET_RKNAND(func) func(RKNAND, rknand, 0) - #else -@@ -74,6 +80,7 @@ - - #define BOOT_TARGET_DEVICES(func) \ - BOOT_TARGET_MMC1(func) \ -+ BOOT_TARGET_NVME(func) \ - BOOT_TARGET_RKNAND(func) \ - BOOT_TARGET_USB(func) \ - BOOT_TARGET_MMC0(func) \ -@@ -117,6 +124,8 @@ - "rkimg_bootdev=" \ - "if mmc dev 1; then " \ - "setenv devtype mmc; setenv devnum 1; echo Boot from SDcard;" \ -+ "elif nvme dev 0; then " \ -+ "setenv devtype nvme; setenv devnum 0; echo Boot from NVMe;" \ - "elif mmc dev 0; then " \ - "setenv devtype mmc; setenv devnum 0; echo Boot from eMMC" \ - "elif mtd_blk dev 0; then " \ - -From 8d216dc8e4c33d92415fee4840ae7ec9e2232169 Mon Sep 17 00:00:00 2001 -From: pcm720 -Date: Thu, 28 Nov 2019 16:50:20 +0300 -Subject: [PATCH 12/12] distro_bootcmd: Rename PCI_ENUM definition to match - upstream - ---- - include/config_distro_bootcmd.h | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h -index af47e2039d..e3137a0c33 100644 ---- a/include/config_distro_bootcmd.h -+++ b/include/config_distro_bootcmd.h -@@ -226,11 +226,11 @@ - #endif - - #if defined(CONFIG_DM_PCI) --#define BOOTENV_RUN_NET_PCI_ENUM "run boot_net_pci_enum; " -+#define BOOTENV_RUN_PCI_ENUM "run boot_pci_enum; " - #define BOOTENV_SHARED_PCI \ -- "boot_net_pci_enum=pci enum\0" -+ "boot_pci_enum=pci enum\0" - #else --#define BOOTENV_RUN_NET_PCI_ENUM -+#define BOOTENV_RUN_PCI_ENUM - #define BOOTENV_SHARED_PCI - #endif - -@@ -299,7 +299,7 @@ - #define BOOTENV_DEV_DHCP(devtypeu, devtypel, instance) \ - "bootcmd_dhcp=" \ - BOOTENV_RUN_NET_USB_START \ -- BOOTENV_RUN_NET_PCI_ENUM \ -+ BOOTENV_RUN_PCI_ENUM \ - "if dhcp ${scriptaddr} ${boot_script_dhcp}; then " \ - "source ${scriptaddr}; " \ - "fi;" \ -@@ -318,7 +318,7 @@ - #define BOOTENV_DEV_PXE(devtypeu, devtypel, instance) \ - "bootcmd_pxe=" \ - BOOTENV_RUN_NET_USB_START \ -- BOOTENV_RUN_NET_PCI_ENUM \ -+ BOOTENV_RUN_PCI_ENUM \ - "dhcp; " \ - "if pxe get; then " \ - "pxe boot; " \ - diff --git a/PKGBUILD b/PKGBUILD index e995676..97c2000 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -1,6 +1,5 @@ # Maintainer: jc_gargma # Maintainer (Manjaro): Dan Johansen -# Contributor (Manjaro): Spikerguy # Contributor (Manjaro): Kevin Mihelich # Contributor (Manjaro): Adam @@ -9,63 +8,43 @@ # Manjaro version fails to build pkgname=uboot-pinebookpro -pkgver=2017.09 -pkgrel=2 -pkgdesc="U-Boot for Pinebook Pro - MrFixit2001's source tree" -#arch=('aarch64') -arch=('x86_64') -url='http://www.denx.de/wiki/U-Boot/WebHome' +pkgver=2020.01 +pkgrel=4 +pkgdesc="U-Boot for Pinebook Pro" +arch=('aarch64') +#arch=('x86_64') +url='https://git.eno.space/pbp-uboot' license=('GPL') backup=('boot/boot.txt' 'boot/boot.scr') depends=('uboot-tools') -makedepends=('bc' 'git' 'rockchip-tools' 'python' 'dtc') +makedepends=('arm-none-eabi-gcc' 'bc' 'dtc' 'git' 'python') install=${pkgname}.install -_commit_rkbin=0d4740f2c0c897ebc1a074580376689b8454ddd8 -_commit_uboot=183e247f9022f934a2224ce71f3030447068c32c -source=("git+https://github.com/mrfixit2001/rockchip-u-boot.git#commit=$_commit_uboot" - "git+https://github.com/rockchip-linux/rkbin.git#commit=$_commit_rkbin" - "0001-nvme-support.patch" - 'rk3399trust.ini' +_commit_atf=22d12c4148c373932a7a81e5d1c59a767e143ac2 +source=("git+https://git.eno.space/pbp-uboot.git" + "git+https://github.com/ARM-software/arm-trusted-firmware.git#commit=$_commit_atf" 'boot.txt' 'mkscr') b2sums=('SKIP' 'SKIP' - '8b63d5ac418d5fe0fc4df35086ce437f228bcd087ca63625c0e4c2670d106b8eaa6bd54f325f3cfdce16b91ed697205d8dba32c8c78a506f9bdffd12e94dde34' - 'd2e62e9d4950c89c5597590adbb399d615414d634c607c3c9a70a90ccee451b85b6563b7f568c668395e1e843821323fce48e03fe35aa2f5a211e4ae08d7e2ab' 'cf03a62fd803187ab91db0942a5d7f835ffcf75c3b0b6ab8ca8c3e8a6762b328339580f3a80eeb1569bf4bca87a9cd60a83c3713338af2de4244717177c8d363' '4ea782264696aa85e30847413088bd338e2beb2ec4e57c2808f80af28ac613ab4ae82b37eb0ff902e66f8a12082a1f9a546bbf20dfeb4c43f59f465987043ede') -prepare() { - cd rockchip-u-boot - patch -Np1 -i "${srcdir}/0001-nvme-support.patch" - sed -i 's/KBUILD_CFLAGS += -fshort-wchar -Werror/KBUILD_CFLAGS += -fshort-wchar/' Makefile -} build() { - cd rockchip-u-boot - - unset CLFAGS CXXFLAGS CPPFLAGS LDFLAGS - - make pinebookpro-rk3399_defconfig - - sed -i 's/CONFIG_IDENT_STRING=""/CONFIG_IDENT_STRING=" Manjaro ARM"/' .config - make EXTRAVERSION=-${pkgrel} - + cd arm-trusted-firmware + unset CFLAGS CXXFLAGS CPPFLAGS LDFLAGS + make PLAT=rk3399 + cd ../pbp-uboot + unset CFLAGS CXXFLAGS CPPFLAGS LDFLAGS + make pinebook_pro-rk3399_defconfig + echo 'CONFIG_IDENT_STRING=" Arch Linux ARM"' >> .config + make BL31=../arm-trusted-firmware/build/rk3399/release/bl31/bl31.elf EXTRAVERSION=-${pkgrel} } package() { - cd rockchip-u-boot + cd pbp-uboot mkdir -p "${pkgdir}/boot" - - tools/mkimage -n rk3399 -T rksd -d ../rkbin/bin/rk33/rk3399_ddr_800MHz_v1.23.bin "${pkgdir}/boot/idbloader.img" - cat ../rkbin/bin/rk33/rk3399_miniloader_v1.19.bin >> "${pkgdir}/boot/idbloader.img" - - loaderimage --pack --uboot u-boot-dtb.bin "${pkgdir}/boot/uboot.img" 0x200000 - - trust_merger ../rk3399trust.ini - - cp trust.img "${pkgdir}/boot" - - tools/mkimage -A arm -O linux -T script -C none -n "U-Boot boot script" -d ../boot.txt "${pkgdir}/boot/boot.scr" + cp idbloader.img u-boot.itb "${pkgdir}/boot" + mkimage -A arm -O linux -T script -C none -n "U-Boot boot script" -d ${srcdir}/boot.txt "${pkgdir}/boot/boot.scr" cp ${srcdir}/{boot.txt,mkscr} "${pkgdir}"/boot } diff --git a/rk3399trust.ini b/rk3399trust.ini deleted file mode 100644 index 1fea252..0000000 --- a/rk3399trust.ini +++ /dev/null @@ -1,17 +0,0 @@ -[VERSION] -MAJOR=1 -MINOR=0 -[BL30_OPTION] -SEC=0 -[BL31_OPTION] -SEC=1 -PATH=../rkbin/bin/rk33/rk3399_bl31_v1.29.elf -ADDR=0x00010000 -[BL32_OPTION] -SEC=1 -PATH=../rkbin/bin/rk33/rk3399_bl32_v1.20.bin -ADDR=0x08400000 -[BL33_OPTION] -SEC=0 -[OUTPUT] -PATH=trust.img diff --git a/uboot-pinebookpro.install b/uboot-pinebookpro.install index 7377a35..3b9aa22 100644 --- a/uboot-pinebookpro.install +++ b/uboot-pinebookpro.install @@ -1,9 +1,9 @@ flash_uboot() { - echo "A new U-Boot version needs to be flashed onto /dev/mmcblkX." - echo "You can do this later by running:" - echo "# dd if=/boot/idbloader.img of=/dev/mmcblkX seek=64 conv=notrunc" - echo "# dd if=/boot/uboot.img of=/dev/mmcblkX seek=16384 conv=notrunc" - echo "# dd if=/boot/trust.img of=/dev/mmcblkX seek=24576 conv=notrunc" + echo "A new U-Boot version needs to be flashed onto your install drive." + echo "Please use lsblk to determine your drive, before proceeding." + echo "You can flash the new U-Boot by running:" + echo "# dd if=/boot/idbloader.img of=/dev/mmcblkX seek=64 conv=notrunc" + echo "# dd if=/boot/u-boot.itb of=/dev/mmcblkX seek=16384 conv=notrunc" } ## arg 1: the new package version -- cgit v1.2.1