From d0bf9958aedb2283167f7b06fba19f054d953833 Mon Sep 17 00:00:00 2001 From: jc_gargma Date: Thu, 9 Jan 2020 01:42:01 -0800 Subject: Updated to compile from source --- 0001-nvme-support.patch | 1936 +++++++++++++++++++++++++++++++++++++++++++++ PKGBUILD | 80 +- boot.txt | 3 +- idbloader.img | Bin 163836 -> 0 bytes rk3399trust.ini | 17 + trust.img | Bin 4194304 -> 0 bytes uboot-pinebookpro.install | 19 +- uboot.img | Bin 4194304 -> 0 bytes 8 files changed, 2017 insertions(+), 38 deletions(-) create mode 100644 0001-nvme-support.patch delete mode 100644 idbloader.img create mode 100644 rk3399trust.ini delete mode 100644 trust.img delete mode 100644 uboot.img diff --git a/0001-nvme-support.patch b/0001-nvme-support.patch new file mode 100644 index 0000000..2b931b6 --- /dev/null +++ b/0001-nvme-support.patch @@ -0,0 +1,1936 @@ +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 f78e3dd..e995676 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -1,37 +1,71 @@ # Maintainer: jc_gargma # Maintainer (Manjaro): Dan Johansen # Contributor (Manjaro): Spikerguy -# Pre-Built IMG by MrFixit +# Contributor (Manjaro): Kevin Mihelich +# Contributor (Manjaro): Adam # # I maintain this because: # Not in an official repo and I use it # Manjaro version fails to build pkgname=uboot-pinebookpro -pkgver=1.1 -pkgrel=4 -pkgdesc="U-Boot for Pinebook Pro (prebuilt binaries)" -arch=('aarch64') -url='https://github.com/mrfixit2001/updates_repo/tree/v1.1/pinebook/filesystem' +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' license=('GPL') -makedepends=('uboot-tools') -#Commented out until we know the parition to be used. -#install=${pkgname}.install -source=('uboot.img' - 'trust.img' - 'idbloader.img' - 'boot.txt' - 'mkscr' - ) -sha256sums=('f9a3d144ab8702ab1ab2f39280f4976bbac621a90fb3eaa1729077f34355ca89' - 'bd62940658c632bf39c883cf3ba1e4054ac893bc31df2ea45e05cb633da49598' - '40a0ecb986818db4c2d984045037fd12414fa9a7553b0edcbb45225dce31d12f' - '0635926d7deda636827b413f78acfe3a286cdc87a26ea379bc2c4985bb901c77' - 'a4fc8b6b92bc364d6542670d294aa618a8501fb8729f415cc0a3eed776ef0c8e') +backup=('boot/boot.txt' 'boot/boot.scr') +depends=('uboot-tools') +makedepends=('bc' 'git' 'rockchip-tools' 'python' 'dtc') +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' + '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} + +} package() { - mkdir -p "${pkgdir}"/boot - cp uboot.img trust.img idbloader.img "${pkgdir}"/boot - mkimage -A arm -O linux -T script -C none -n "U-Boot boot script" -d ${srcdir}/boot.txt "${pkgdir}/boot/boot.scr" + cd rockchip-u-boot + + 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 ${srcdir}/{boot.txt,mkscr} "${pkgdir}"/boot } diff --git a/boot.txt b/boot.txt index 7ce8eff..a10884f 100644 --- a/boot.txt +++ b/boot.txt @@ -4,7 +4,8 @@ setenv macaddr da 19 c8 7a 6d f4 part uuid ${devtype} ${devnum}:${bootpart} uuid -setenv bootargs console=ttyS2,1500000n8 root=PARTUUID=${uuid} rw rootwait append video=eDP-1:1920x1080@60 +setenv bootargs console=ttyS2,1500000 root=PARTUUID=${uuid} rw rootwait +#setenv bootargs console=ttyS2,1500000 root=PARTUUID=${uuid} rw rootwait bootsplash.bootfile=bootsplash-themes/manjaro/bootsplash setenv fdtfile rockchip/rk3399-pinebook-pro.dtb if load ${devtype} ${devnum}:${bootpart} ${kernel_addr_r} /boot/Image; then diff --git a/idbloader.img b/idbloader.img deleted file mode 100644 index 7c161e6..0000000 Binary files a/idbloader.img and /dev/null differ diff --git a/rk3399trust.ini b/rk3399trust.ini new file mode 100644 index 0000000..1fea252 --- /dev/null +++ b/rk3399trust.ini @@ -0,0 +1,17 @@ +[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/trust.img b/trust.img deleted file mode 100644 index 510d639..0000000 Binary files a/trust.img and /dev/null differ diff --git a/uboot-pinebookpro.install b/uboot-pinebookpro.install index 71e1ff7..7377a35 100644 --- a/uboot-pinebookpro.install +++ b/uboot-pinebookpro.install @@ -1,17 +1,9 @@ flash_uboot() { - echo "A new U-Boot version needs to be flashed onto /dev/mmcblk0." - echo "Do you want to do this now? [y|N]" - read -r shouldwe - if [[ $shouldwe =~ ^([yY][eE][sS]|[yY])$ ]]; then - dd if=/boot/idbloader.img of=/dev/mmcblk0 seek=64 conv=notrunc - dd if=/boot/uboot.img of=/dev/mmcblk0 seek=16384 conv=notrunc - dd if=/boot/trust.img of=/dev/mmcblk0 seek=24576 conv=notrunc - else - echo "You can do this later by running:" - echo "# dd if=/boot/idbloader.img of=/dev/mmcblk0 seek=64 conv=notrunc" - echo "# dd if=/boot/uboot.img of=/dev/mmcblk0 seek=16384 conv=notrunc" - echo "# dd if=/boot/trust.img of=/dev/mmcblk0 seek=24576 conv=notrunc" - fi + 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" } ## arg 1: the new package version @@ -24,4 +16,3 @@ post_install() { post_upgrade() { flash_uboot } - diff --git a/uboot.img b/uboot.img deleted file mode 100644 index 05bb23f..0000000 Binary files a/uboot.img and /dev/null differ -- cgit v1.2.1