1f315828bSThierry Reding /* 2f315828bSThierry Reding * Copyright (c) 2010, CompuLab, Ltd. 3f315828bSThierry Reding * Author: Mike Rapoport <mike@compulab.co.il> 4f315828bSThierry Reding * 5f315828bSThierry Reding * Based on NVIDIA PCIe driver 6f315828bSThierry Reding * Copyright (c) 2008-2009, NVIDIA Corporation. 7f315828bSThierry Reding * 8f315828bSThierry Reding * Copyright (c) 2013-2014, NVIDIA Corporation. 9f315828bSThierry Reding * 10f315828bSThierry Reding * SPDX-License-Identifier: GPL-2.0 11f315828bSThierry Reding */ 12f315828bSThierry Reding 13f315828bSThierry Reding #define DEBUG 14f315828bSThierry Reding #define pr_fmt(fmt) "tegra-pcie: " fmt 15f315828bSThierry Reding 16f315828bSThierry Reding #include <common.h> 17f315828bSThierry Reding #include <errno.h> 18f315828bSThierry Reding #include <fdtdec.h> 19f315828bSThierry Reding #include <malloc.h> 20f315828bSThierry Reding #include <pci.h> 21f315828bSThierry Reding 22f315828bSThierry Reding #include <asm/io.h> 23f315828bSThierry Reding #include <asm/gpio.h> 24f315828bSThierry Reding 25f315828bSThierry Reding #include <asm/arch/clock.h> 26f315828bSThierry Reding #include <asm/arch/powergate.h> 27f315828bSThierry Reding #include <asm/arch-tegra/xusb-padctl.h> 28f315828bSThierry Reding 29f315828bSThierry Reding #include <linux/list.h> 30f315828bSThierry Reding 31f315828bSThierry Reding #include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h> 32f315828bSThierry Reding 33f315828bSThierry Reding DECLARE_GLOBAL_DATA_PTR; 34f315828bSThierry Reding 35f315828bSThierry Reding #define AFI_AXI_BAR0_SZ 0x00 36f315828bSThierry Reding #define AFI_AXI_BAR1_SZ 0x04 37f315828bSThierry Reding #define AFI_AXI_BAR2_SZ 0x08 38f315828bSThierry Reding #define AFI_AXI_BAR3_SZ 0x0c 39f315828bSThierry Reding #define AFI_AXI_BAR4_SZ 0x10 40f315828bSThierry Reding #define AFI_AXI_BAR5_SZ 0x14 41f315828bSThierry Reding 42f315828bSThierry Reding #define AFI_AXI_BAR0_START 0x18 43f315828bSThierry Reding #define AFI_AXI_BAR1_START 0x1c 44f315828bSThierry Reding #define AFI_AXI_BAR2_START 0x20 45f315828bSThierry Reding #define AFI_AXI_BAR3_START 0x24 46f315828bSThierry Reding #define AFI_AXI_BAR4_START 0x28 47f315828bSThierry Reding #define AFI_AXI_BAR5_START 0x2c 48f315828bSThierry Reding 49f315828bSThierry Reding #define AFI_FPCI_BAR0 0x30 50f315828bSThierry Reding #define AFI_FPCI_BAR1 0x34 51f315828bSThierry Reding #define AFI_FPCI_BAR2 0x38 52f315828bSThierry Reding #define AFI_FPCI_BAR3 0x3c 53f315828bSThierry Reding #define AFI_FPCI_BAR4 0x40 54f315828bSThierry Reding #define AFI_FPCI_BAR5 0x44 55f315828bSThierry Reding 56f315828bSThierry Reding #define AFI_CACHE_BAR0_SZ 0x48 57f315828bSThierry Reding #define AFI_CACHE_BAR0_ST 0x4c 58f315828bSThierry Reding #define AFI_CACHE_BAR1_SZ 0x50 59f315828bSThierry Reding #define AFI_CACHE_BAR1_ST 0x54 60f315828bSThierry Reding 61f315828bSThierry Reding #define AFI_MSI_BAR_SZ 0x60 62f315828bSThierry Reding #define AFI_MSI_FPCI_BAR_ST 0x64 63f315828bSThierry Reding #define AFI_MSI_AXI_BAR_ST 0x68 64f315828bSThierry Reding 65f315828bSThierry Reding #define AFI_CONFIGURATION 0xac 66f315828bSThierry Reding #define AFI_CONFIGURATION_EN_FPCI (1 << 0) 67f315828bSThierry Reding 68f315828bSThierry Reding #define AFI_FPCI_ERROR_MASKS 0xb0 69f315828bSThierry Reding 70f315828bSThierry Reding #define AFI_INTR_MASK 0xb4 71f315828bSThierry Reding #define AFI_INTR_MASK_INT_MASK (1 << 0) 72f315828bSThierry Reding #define AFI_INTR_MASK_MSI_MASK (1 << 8) 73f315828bSThierry Reding 74f315828bSThierry Reding #define AFI_SM_INTR_ENABLE 0xc4 75f315828bSThierry Reding #define AFI_SM_INTR_INTA_ASSERT (1 << 0) 76f315828bSThierry Reding #define AFI_SM_INTR_INTB_ASSERT (1 << 1) 77f315828bSThierry Reding #define AFI_SM_INTR_INTC_ASSERT (1 << 2) 78f315828bSThierry Reding #define AFI_SM_INTR_INTD_ASSERT (1 << 3) 79f315828bSThierry Reding #define AFI_SM_INTR_INTA_DEASSERT (1 << 4) 80f315828bSThierry Reding #define AFI_SM_INTR_INTB_DEASSERT (1 << 5) 81f315828bSThierry Reding #define AFI_SM_INTR_INTC_DEASSERT (1 << 6) 82f315828bSThierry Reding #define AFI_SM_INTR_INTD_DEASSERT (1 << 7) 83f315828bSThierry Reding 84f315828bSThierry Reding #define AFI_AFI_INTR_ENABLE 0xc8 85f315828bSThierry Reding #define AFI_INTR_EN_INI_SLVERR (1 << 0) 86f315828bSThierry Reding #define AFI_INTR_EN_INI_DECERR (1 << 1) 87f315828bSThierry Reding #define AFI_INTR_EN_TGT_SLVERR (1 << 2) 88f315828bSThierry Reding #define AFI_INTR_EN_TGT_DECERR (1 << 3) 89f315828bSThierry Reding #define AFI_INTR_EN_TGT_WRERR (1 << 4) 90f315828bSThierry Reding #define AFI_INTR_EN_DFPCI_DECERR (1 << 5) 91f315828bSThierry Reding #define AFI_INTR_EN_AXI_DECERR (1 << 6) 92f315828bSThierry Reding #define AFI_INTR_EN_FPCI_TIMEOUT (1 << 7) 93f315828bSThierry Reding #define AFI_INTR_EN_PRSNT_SENSE (1 << 8) 94f315828bSThierry Reding 95f315828bSThierry Reding #define AFI_PCIE_CONFIG 0x0f8 96f315828bSThierry Reding #define AFI_PCIE_CONFIG_PCIE_DISABLE(x) (1 << ((x) + 1)) 97f315828bSThierry Reding #define AFI_PCIE_CONFIG_PCIE_DISABLE_ALL 0xe 98f315828bSThierry Reding #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK (0xf << 20) 99f315828bSThierry Reding #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_SINGLE (0x0 << 20) 100f315828bSThierry Reding #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_420 (0x0 << 20) 101f315828bSThierry Reding #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X2_X1 (0x0 << 20) 102f315828bSThierry Reding #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL (0x1 << 20) 103f315828bSThierry Reding #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_222 (0x1 << 20) 104f315828bSThierry Reding #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X4_X1 (0x1 << 20) 105f315828bSThierry Reding #define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_411 (0x2 << 20) 106f315828bSThierry Reding 107f315828bSThierry Reding #define AFI_FUSE 0x104 108f315828bSThierry Reding #define AFI_FUSE_PCIE_T0_GEN2_DIS (1 << 2) 109f315828bSThierry Reding 110f315828bSThierry Reding #define AFI_PEX0_CTRL 0x110 111f315828bSThierry Reding #define AFI_PEX1_CTRL 0x118 112f315828bSThierry Reding #define AFI_PEX2_CTRL 0x128 113f315828bSThierry Reding #define AFI_PEX_CTRL_RST (1 << 0) 114f315828bSThierry Reding #define AFI_PEX_CTRL_CLKREQ_EN (1 << 1) 115f315828bSThierry Reding #define AFI_PEX_CTRL_REFCLK_EN (1 << 3) 116f315828bSThierry Reding #define AFI_PEX_CTRL_OVERRIDE_EN (1 << 4) 117f315828bSThierry Reding 118f315828bSThierry Reding #define AFI_PLLE_CONTROL 0x160 119f315828bSThierry Reding #define AFI_PLLE_CONTROL_BYPASS_PADS2PLLE_CONTROL (1 << 9) 120f315828bSThierry Reding #define AFI_PLLE_CONTROL_PADS2PLLE_CONTROL_EN (1 << 1) 121f315828bSThierry Reding 122f315828bSThierry Reding #define AFI_PEXBIAS_CTRL_0 0x168 123f315828bSThierry Reding 124f315828bSThierry Reding #define PADS_CTL_SEL 0x0000009C 125f315828bSThierry Reding 126f315828bSThierry Reding #define PADS_CTL 0x000000A0 127f315828bSThierry Reding #define PADS_CTL_IDDQ_1L (1 << 0) 128f315828bSThierry Reding #define PADS_CTL_TX_DATA_EN_1L (1 << 6) 129f315828bSThierry Reding #define PADS_CTL_RX_DATA_EN_1L (1 << 10) 130f315828bSThierry Reding 131f315828bSThierry Reding #define PADS_PLL_CTL_TEGRA20 0x000000B8 132f315828bSThierry Reding #define PADS_PLL_CTL_TEGRA30 0x000000B4 133f315828bSThierry Reding #define PADS_PLL_CTL_RST_B4SM (0x1 << 1) 134f315828bSThierry Reding #define PADS_PLL_CTL_LOCKDET (0x1 << 8) 135f315828bSThierry Reding #define PADS_PLL_CTL_REFCLK_MASK (0x3 << 16) 136f315828bSThierry Reding #define PADS_PLL_CTL_REFCLK_INTERNAL_CML (0x0 << 16) 137f315828bSThierry Reding #define PADS_PLL_CTL_REFCLK_INTERNAL_CMOS (0x1 << 16) 138f315828bSThierry Reding #define PADS_PLL_CTL_REFCLK_EXTERNAL (0x2 << 16) 139f315828bSThierry Reding #define PADS_PLL_CTL_TXCLKREF_MASK (0x1 << 20) 140f315828bSThierry Reding #define PADS_PLL_CTL_TXCLKREF_DIV10 (0x0 << 20) 141f315828bSThierry Reding #define PADS_PLL_CTL_TXCLKREF_DIV5 (0x1 << 20) 142f315828bSThierry Reding #define PADS_PLL_CTL_TXCLKREF_BUF_EN (0x1 << 22) 143f315828bSThierry Reding 144f315828bSThierry Reding #define PADS_REFCLK_CFG0 0x000000C8 145f315828bSThierry Reding #define PADS_REFCLK_CFG1 0x000000CC 146f315828bSThierry Reding 147f315828bSThierry Reding /* 148f315828bSThierry Reding * Fields in PADS_REFCLK_CFG*. Those registers form an array of 16-bit 149f315828bSThierry Reding * entries, one entry per PCIe port. These field definitions and desired 150f315828bSThierry Reding * values aren't in the TRM, but do come from NVIDIA. 151f315828bSThierry Reding */ 152f315828bSThierry Reding #define PADS_REFCLK_CFG_TERM_SHIFT 2 /* 6:2 */ 153f315828bSThierry Reding #define PADS_REFCLK_CFG_E_TERM_SHIFT 7 154f315828bSThierry Reding #define PADS_REFCLK_CFG_PREDI_SHIFT 8 /* 11:8 */ 155f315828bSThierry Reding #define PADS_REFCLK_CFG_DRVI_SHIFT 12 /* 15:12 */ 156f315828bSThierry Reding 157f315828bSThierry Reding /* Default value provided by HW engineering is 0xfa5c */ 158f315828bSThierry Reding #define PADS_REFCLK_CFG_VALUE \ 159f315828bSThierry Reding ( \ 160f315828bSThierry Reding (0x17 << PADS_REFCLK_CFG_TERM_SHIFT) | \ 161f315828bSThierry Reding (0 << PADS_REFCLK_CFG_E_TERM_SHIFT) | \ 162f315828bSThierry Reding (0xa << PADS_REFCLK_CFG_PREDI_SHIFT) | \ 163f315828bSThierry Reding (0xf << PADS_REFCLK_CFG_DRVI_SHIFT) \ 164f315828bSThierry Reding ) 165f315828bSThierry Reding 166f315828bSThierry Reding #define RP_VEND_XP 0x00000F00 167f315828bSThierry Reding #define RP_VEND_XP_DL_UP (1 << 30) 168f315828bSThierry Reding 169f315828bSThierry Reding #define RP_PRIV_MISC 0x00000FE0 170f315828bSThierry Reding #define RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT (0xE << 0) 171f315828bSThierry Reding #define RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT (0xF << 0) 172f315828bSThierry Reding 173f315828bSThierry Reding #define RP_LINK_CONTROL_STATUS 0x00000090 174f315828bSThierry Reding #define RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE 0x20000000 175f315828bSThierry Reding #define RP_LINK_CONTROL_STATUS_LINKSTAT_MASK 0x3fff0000 176f315828bSThierry Reding 177f315828bSThierry Reding struct tegra_pcie; 178f315828bSThierry Reding 179f315828bSThierry Reding struct tegra_pcie_port { 180f315828bSThierry Reding struct tegra_pcie *pcie; 181f315828bSThierry Reding 182f315828bSThierry Reding struct fdt_resource regs; 183f315828bSThierry Reding unsigned int num_lanes; 184f315828bSThierry Reding unsigned int index; 185f315828bSThierry Reding 186f315828bSThierry Reding struct list_head list; 187f315828bSThierry Reding }; 188f315828bSThierry Reding 189f315828bSThierry Reding struct tegra_pcie_soc { 190f315828bSThierry Reding unsigned int num_ports; 191f315828bSThierry Reding unsigned long pads_pll_ctl; 192f315828bSThierry Reding unsigned long tx_ref_sel; 193f315828bSThierry Reding bool has_pex_clkreq_en; 194f315828bSThierry Reding bool has_pex_bias_ctrl; 195f315828bSThierry Reding bool has_cml_clk; 196f315828bSThierry Reding bool has_gen2; 197f315828bSThierry Reding }; 198f315828bSThierry Reding 199f315828bSThierry Reding struct tegra_pcie { 200f315828bSThierry Reding struct pci_controller hose; 201f315828bSThierry Reding 202f315828bSThierry Reding struct fdt_resource pads; 203f315828bSThierry Reding struct fdt_resource afi; 204f315828bSThierry Reding struct fdt_resource cs; 205f315828bSThierry Reding 206f315828bSThierry Reding struct fdt_resource prefetch; 207f315828bSThierry Reding struct fdt_resource mem; 208f315828bSThierry Reding struct fdt_resource io; 209f315828bSThierry Reding 210f315828bSThierry Reding struct list_head ports; 211f315828bSThierry Reding unsigned long xbar; 212f315828bSThierry Reding 213f315828bSThierry Reding const struct tegra_pcie_soc *soc; 214f315828bSThierry Reding struct tegra_xusb_phy *phy; 215f315828bSThierry Reding }; 216f315828bSThierry Reding 217f315828bSThierry Reding static inline struct tegra_pcie *to_tegra_pcie(struct pci_controller *hose) 218f315828bSThierry Reding { 219f315828bSThierry Reding return container_of(hose, struct tegra_pcie, hose); 220f315828bSThierry Reding } 221f315828bSThierry Reding 222f315828bSThierry Reding static void afi_writel(struct tegra_pcie *pcie, unsigned long value, 223f315828bSThierry Reding unsigned long offset) 224f315828bSThierry Reding { 225f315828bSThierry Reding writel(value, pcie->afi.start + offset); 226f315828bSThierry Reding } 227f315828bSThierry Reding 228f315828bSThierry Reding static unsigned long afi_readl(struct tegra_pcie *pcie, unsigned long offset) 229f315828bSThierry Reding { 230f315828bSThierry Reding return readl(pcie->afi.start + offset); 231f315828bSThierry Reding } 232f315828bSThierry Reding 233f315828bSThierry Reding static void pads_writel(struct tegra_pcie *pcie, unsigned long value, 234f315828bSThierry Reding unsigned long offset) 235f315828bSThierry Reding { 236f315828bSThierry Reding writel(value, pcie->pads.start + offset); 237f315828bSThierry Reding } 238f315828bSThierry Reding 239f315828bSThierry Reding static unsigned long pads_readl(struct tegra_pcie *pcie, unsigned long offset) 240f315828bSThierry Reding { 241f315828bSThierry Reding return readl(pcie->pads.start + offset); 242f315828bSThierry Reding } 243f315828bSThierry Reding 244f315828bSThierry Reding static unsigned long rp_readl(struct tegra_pcie_port *port, 245f315828bSThierry Reding unsigned long offset) 246f315828bSThierry Reding { 247f315828bSThierry Reding return readl(port->regs.start + offset); 248f315828bSThierry Reding } 249f315828bSThierry Reding 250f315828bSThierry Reding static void rp_writel(struct tegra_pcie_port *port, unsigned long value, 251f315828bSThierry Reding unsigned long offset) 252f315828bSThierry Reding { 253f315828bSThierry Reding writel(value, port->regs.start + offset); 254f315828bSThierry Reding } 255f315828bSThierry Reding 256f315828bSThierry Reding static unsigned long tegra_pcie_conf_offset(pci_dev_t bdf, int where) 257f315828bSThierry Reding { 258f315828bSThierry Reding return ((where & 0xf00) << 16) | (PCI_BUS(bdf) << 16) | 259f315828bSThierry Reding (PCI_DEV(bdf) << 11) | (PCI_FUNC(bdf) << 8) | 260f315828bSThierry Reding (where & 0xfc); 261f315828bSThierry Reding } 262f315828bSThierry Reding 263f315828bSThierry Reding static int tegra_pcie_conf_address(struct tegra_pcie *pcie, pci_dev_t bdf, 264f315828bSThierry Reding int where, unsigned long *address) 265f315828bSThierry Reding { 266f315828bSThierry Reding unsigned int bus = PCI_BUS(bdf); 267f315828bSThierry Reding 268f315828bSThierry Reding if (bus == 0) { 269f315828bSThierry Reding unsigned int dev = PCI_DEV(bdf); 270f315828bSThierry Reding struct tegra_pcie_port *port; 271f315828bSThierry Reding 272f315828bSThierry Reding list_for_each_entry(port, &pcie->ports, list) { 273f315828bSThierry Reding if (port->index + 1 == dev) { 274f315828bSThierry Reding *address = port->regs.start + (where & ~3); 275f315828bSThierry Reding return 0; 276f315828bSThierry Reding } 277f315828bSThierry Reding } 278f315828bSThierry Reding } else { 279f315828bSThierry Reding *address = pcie->cs.start + tegra_pcie_conf_offset(bdf, where); 280f315828bSThierry Reding return 0; 281f315828bSThierry Reding } 282f315828bSThierry Reding 283f315828bSThierry Reding return -1; 284f315828bSThierry Reding } 285f315828bSThierry Reding 286f315828bSThierry Reding static int tegra_pcie_read_conf(struct pci_controller *hose, pci_dev_t bdf, 287f315828bSThierry Reding int where, u32 *value) 288f315828bSThierry Reding { 289f315828bSThierry Reding struct tegra_pcie *pcie = to_tegra_pcie(hose); 290f315828bSThierry Reding unsigned long address; 291f315828bSThierry Reding int err; 292f315828bSThierry Reding 293f315828bSThierry Reding err = tegra_pcie_conf_address(pcie, bdf, where, &address); 294f315828bSThierry Reding if (err < 0) { 295f315828bSThierry Reding *value = 0xffffffff; 296f315828bSThierry Reding return 1; 297f315828bSThierry Reding } 298f315828bSThierry Reding 299f315828bSThierry Reding *value = readl(address); 300f315828bSThierry Reding 301f315828bSThierry Reding /* fixup root port class */ 302f315828bSThierry Reding if (PCI_BUS(bdf) == 0) { 303f315828bSThierry Reding if (where == PCI_CLASS_REVISION) { 304f315828bSThierry Reding *value &= ~0x00ff0000; 305f315828bSThierry Reding *value |= PCI_CLASS_BRIDGE_PCI << 16; 306f315828bSThierry Reding } 307f315828bSThierry Reding } 308f315828bSThierry Reding 309f315828bSThierry Reding return 0; 310f315828bSThierry Reding } 311f315828bSThierry Reding 312f315828bSThierry Reding static int tegra_pcie_write_conf(struct pci_controller *hose, pci_dev_t bdf, 313f315828bSThierry Reding int where, u32 value) 314f315828bSThierry Reding { 315f315828bSThierry Reding struct tegra_pcie *pcie = to_tegra_pcie(hose); 316f315828bSThierry Reding unsigned long address; 317f315828bSThierry Reding int err; 318f315828bSThierry Reding 319f315828bSThierry Reding err = tegra_pcie_conf_address(pcie, bdf, where, &address); 320f315828bSThierry Reding if (err < 0) 321f315828bSThierry Reding return 1; 322f315828bSThierry Reding 323f315828bSThierry Reding writel(value, address); 324f315828bSThierry Reding 325f315828bSThierry Reding return 0; 326f315828bSThierry Reding } 327f315828bSThierry Reding 328f315828bSThierry Reding static int tegra_pcie_port_parse_dt(const void *fdt, int node, 329f315828bSThierry Reding struct tegra_pcie_port *port) 330f315828bSThierry Reding { 331f315828bSThierry Reding const u32 *addr; 332f315828bSThierry Reding int len; 333f315828bSThierry Reding 334f315828bSThierry Reding addr = fdt_getprop(fdt, node, "assigned-addresses", &len); 335f315828bSThierry Reding if (!addr) { 336f315828bSThierry Reding error("property \"assigned-addresses\" not found"); 337f315828bSThierry Reding return -FDT_ERR_NOTFOUND; 338f315828bSThierry Reding } 339f315828bSThierry Reding 340f315828bSThierry Reding port->regs.start = fdt32_to_cpu(addr[2]); 341f315828bSThierry Reding port->regs.end = port->regs.start + fdt32_to_cpu(addr[4]); 342f315828bSThierry Reding 343f315828bSThierry Reding return 0; 344f315828bSThierry Reding } 345f315828bSThierry Reding 346f315828bSThierry Reding static int tegra_pcie_get_xbar_config(const void *fdt, int node, u32 lanes, 347f315828bSThierry Reding unsigned long *xbar) 348f315828bSThierry Reding { 349f315828bSThierry Reding enum fdt_compat_id id = fdtdec_lookup(fdt, node); 350f315828bSThierry Reding 351f315828bSThierry Reding switch (id) { 352f315828bSThierry Reding case COMPAT_NVIDIA_TEGRA20_PCIE: 353f315828bSThierry Reding switch (lanes) { 354f315828bSThierry Reding case 0x00000004: 355f315828bSThierry Reding debug("single-mode configuration\n"); 356f315828bSThierry Reding *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_SINGLE; 357f315828bSThierry Reding return 0; 358f315828bSThierry Reding 359f315828bSThierry Reding case 0x00000202: 360f315828bSThierry Reding debug("dual-mode configuration\n"); 361f315828bSThierry Reding *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL; 362f315828bSThierry Reding return 0; 363f315828bSThierry Reding } 364f315828bSThierry Reding break; 365f315828bSThierry Reding 366f315828bSThierry Reding case COMPAT_NVIDIA_TEGRA30_PCIE: 367f315828bSThierry Reding switch (lanes) { 368f315828bSThierry Reding case 0x00000204: 369f315828bSThierry Reding debug("4x1, 2x1 configuration\n"); 370f315828bSThierry Reding *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_420; 371f315828bSThierry Reding return 0; 372f315828bSThierry Reding 373f315828bSThierry Reding case 0x00020202: 374f315828bSThierry Reding debug("2x3 configuration\n"); 375f315828bSThierry Reding *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_222; 376f315828bSThierry Reding return 0; 377f315828bSThierry Reding 378f315828bSThierry Reding case 0x00010104: 379f315828bSThierry Reding debug("4x1, 1x2 configuration\n"); 380f315828bSThierry Reding *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_411; 381f315828bSThierry Reding return 0; 382f315828bSThierry Reding } 383f315828bSThierry Reding break; 384f315828bSThierry Reding 385f315828bSThierry Reding case COMPAT_NVIDIA_TEGRA124_PCIE: 386f315828bSThierry Reding switch (lanes) { 387f315828bSThierry Reding case 0x0000104: 388f315828bSThierry Reding debug("4x1, 1x1 configuration\n"); 389f315828bSThierry Reding *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X4_X1; 390f315828bSThierry Reding return 0; 391f315828bSThierry Reding 392f315828bSThierry Reding case 0x0000102: 393f315828bSThierry Reding debug("2x1, 1x1 configuration\n"); 394f315828bSThierry Reding *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X2_X1; 395f315828bSThierry Reding return 0; 396f315828bSThierry Reding } 397f315828bSThierry Reding break; 398f315828bSThierry Reding 399f315828bSThierry Reding default: 400f315828bSThierry Reding break; 401f315828bSThierry Reding } 402f315828bSThierry Reding 403f315828bSThierry Reding return -FDT_ERR_NOTFOUND; 404f315828bSThierry Reding } 405f315828bSThierry Reding 406f315828bSThierry Reding static int tegra_pcie_parse_dt_ranges(const void *fdt, int node, 407f315828bSThierry Reding struct tegra_pcie *pcie) 408f315828bSThierry Reding { 409f315828bSThierry Reding const u32 *ptr, *end; 410f315828bSThierry Reding int len; 411f315828bSThierry Reding 412f315828bSThierry Reding ptr = fdt_getprop(fdt, node, "ranges", &len); 413f315828bSThierry Reding if (!ptr) { 414f315828bSThierry Reding error("missing \"ranges\" property"); 415f315828bSThierry Reding return -FDT_ERR_NOTFOUND; 416f315828bSThierry Reding } 417f315828bSThierry Reding 418f315828bSThierry Reding end = ptr + len / 4; 419f315828bSThierry Reding 420f315828bSThierry Reding while (ptr < end) { 421f315828bSThierry Reding struct fdt_resource *res = NULL; 422f315828bSThierry Reding u32 space = fdt32_to_cpu(*ptr); 423f315828bSThierry Reding 424f315828bSThierry Reding switch ((space >> 24) & 0x3) { 425f315828bSThierry Reding case 0x01: 426f315828bSThierry Reding res = &pcie->io; 427f315828bSThierry Reding break; 428f315828bSThierry Reding 429f315828bSThierry Reding case 0x02: /* 32 bit */ 430f315828bSThierry Reding case 0x03: /* 64 bit */ 431f315828bSThierry Reding if (space & (1 << 30)) 432f315828bSThierry Reding res = &pcie->prefetch; 433f315828bSThierry Reding else 434f315828bSThierry Reding res = &pcie->mem; 435f315828bSThierry Reding 436f315828bSThierry Reding break; 437f315828bSThierry Reding } 438f315828bSThierry Reding 439f315828bSThierry Reding if (res) { 440f315828bSThierry Reding res->start = fdt32_to_cpu(ptr[3]); 441f315828bSThierry Reding res->end = res->start + fdt32_to_cpu(ptr[5]); 442f315828bSThierry Reding } 443f315828bSThierry Reding 444f315828bSThierry Reding ptr += 3 + 1 + 2; 445f315828bSThierry Reding } 446f315828bSThierry Reding 447f315828bSThierry Reding debug("PCI regions:\n"); 448f315828bSThierry Reding debug(" I/O: %#x-%#x\n", pcie->io.start, pcie->io.end); 449f315828bSThierry Reding debug(" non-prefetchable memory: %#x-%#x\n", pcie->mem.start, 450f315828bSThierry Reding pcie->mem.end); 451f315828bSThierry Reding debug(" prefetchable memory: %#x-%#x\n", pcie->prefetch.start, 452f315828bSThierry Reding pcie->prefetch.end); 453f315828bSThierry Reding 454f315828bSThierry Reding return 0; 455f315828bSThierry Reding } 456f315828bSThierry Reding 457f315828bSThierry Reding static int tegra_pcie_parse_port_info(const void *fdt, int node, 458f315828bSThierry Reding unsigned int *index, 459f315828bSThierry Reding unsigned int *lanes) 460f315828bSThierry Reding { 461a62e84d7SBin Meng struct fdt_pci_addr addr; 462f315828bSThierry Reding int err; 463f315828bSThierry Reding 464f315828bSThierry Reding err = fdtdec_get_int(fdt, node, "nvidia,num-lanes", 0); 465f315828bSThierry Reding if (err < 0) { 466f315828bSThierry Reding error("failed to parse \"nvidia,num-lanes\" property"); 467f315828bSThierry Reding return err; 468f315828bSThierry Reding } 469f315828bSThierry Reding 470f315828bSThierry Reding *lanes = err; 471f315828bSThierry Reding 472*053b86e6SSjoerd Simons err = fdtdec_get_pci_addr(fdt, node, 0, "reg", &addr); 473f315828bSThierry Reding if (err < 0) { 474f315828bSThierry Reding error("failed to parse \"reg\" property"); 475f315828bSThierry Reding return err; 476f315828bSThierry Reding } 477f315828bSThierry Reding 478*053b86e6SSjoerd Simons *index = PCI_DEV(addr.phys_hi) - 1; 479f315828bSThierry Reding 480f315828bSThierry Reding return 0; 481f315828bSThierry Reding } 482f315828bSThierry Reding 483f315828bSThierry Reding static int tegra_pcie_parse_dt(const void *fdt, int node, 484f315828bSThierry Reding struct tegra_pcie *pcie) 485f315828bSThierry Reding { 486f315828bSThierry Reding int err, subnode; 487f315828bSThierry Reding u32 lanes = 0; 488f315828bSThierry Reding 489f315828bSThierry Reding err = fdt_get_named_resource(fdt, node, "reg", "reg-names", "pads", 490f315828bSThierry Reding &pcie->pads); 491f315828bSThierry Reding if (err < 0) { 492f315828bSThierry Reding error("resource \"pads\" not found"); 493f315828bSThierry Reding return err; 494f315828bSThierry Reding } 495f315828bSThierry Reding 496f315828bSThierry Reding err = fdt_get_named_resource(fdt, node, "reg", "reg-names", "afi", 497f315828bSThierry Reding &pcie->afi); 498f315828bSThierry Reding if (err < 0) { 499f315828bSThierry Reding error("resource \"afi\" not found"); 500f315828bSThierry Reding return err; 501f315828bSThierry Reding } 502f315828bSThierry Reding 503f315828bSThierry Reding err = fdt_get_named_resource(fdt, node, "reg", "reg-names", "cs", 504f315828bSThierry Reding &pcie->cs); 505f315828bSThierry Reding if (err < 0) { 506f315828bSThierry Reding error("resource \"cs\" not found"); 507f315828bSThierry Reding return err; 508f315828bSThierry Reding } 509f315828bSThierry Reding 510f315828bSThierry Reding pcie->phy = tegra_xusb_phy_get(TEGRA_XUSB_PADCTL_PCIE); 511f315828bSThierry Reding if (pcie->phy) { 512f315828bSThierry Reding err = tegra_xusb_phy_prepare(pcie->phy); 513f315828bSThierry Reding if (err < 0) { 514f315828bSThierry Reding error("failed to prepare PHY: %d", err); 515f315828bSThierry Reding return err; 516f315828bSThierry Reding } 517f315828bSThierry Reding } 518f315828bSThierry Reding 519f315828bSThierry Reding err = tegra_pcie_parse_dt_ranges(fdt, node, pcie); 520f315828bSThierry Reding if (err < 0) { 521f315828bSThierry Reding error("failed to parse \"ranges\" property"); 522f315828bSThierry Reding return err; 523f315828bSThierry Reding } 524f315828bSThierry Reding 525f315828bSThierry Reding fdt_for_each_subnode(fdt, subnode, node) { 526f315828bSThierry Reding unsigned int index = 0, num_lanes = 0; 527f315828bSThierry Reding struct tegra_pcie_port *port; 528f315828bSThierry Reding 529f315828bSThierry Reding err = tegra_pcie_parse_port_info(fdt, subnode, &index, 530f315828bSThierry Reding &num_lanes); 531f315828bSThierry Reding if (err < 0) { 532f315828bSThierry Reding error("failed to obtain root port info"); 533f315828bSThierry Reding continue; 534f315828bSThierry Reding } 535f315828bSThierry Reding 536f315828bSThierry Reding lanes |= num_lanes << (index << 3); 537f315828bSThierry Reding 538f315828bSThierry Reding if (!fdtdec_get_is_enabled(fdt, subnode)) 539f315828bSThierry Reding continue; 540f315828bSThierry Reding 541f315828bSThierry Reding port = malloc(sizeof(*port)); 542f315828bSThierry Reding if (!port) 543f315828bSThierry Reding continue; 544f315828bSThierry Reding 545f315828bSThierry Reding memset(port, 0, sizeof(*port)); 546f315828bSThierry Reding port->num_lanes = num_lanes; 547f315828bSThierry Reding port->index = index; 548f315828bSThierry Reding 549f315828bSThierry Reding err = tegra_pcie_port_parse_dt(fdt, subnode, port); 550f315828bSThierry Reding if (err < 0) { 551f315828bSThierry Reding free(port); 552f315828bSThierry Reding continue; 553f315828bSThierry Reding } 554f315828bSThierry Reding 555f315828bSThierry Reding list_add_tail(&port->list, &pcie->ports); 556f315828bSThierry Reding port->pcie = pcie; 557f315828bSThierry Reding } 558f315828bSThierry Reding 559f315828bSThierry Reding err = tegra_pcie_get_xbar_config(fdt, node, lanes, &pcie->xbar); 560f315828bSThierry Reding if (err < 0) { 561f315828bSThierry Reding error("invalid lane configuration"); 562f315828bSThierry Reding return err; 563f315828bSThierry Reding } 564f315828bSThierry Reding 565f315828bSThierry Reding return 0; 566f315828bSThierry Reding } 567f315828bSThierry Reding 568f315828bSThierry Reding int __weak tegra_pcie_board_init(void) 569f315828bSThierry Reding { 570f315828bSThierry Reding return 0; 571f315828bSThierry Reding } 572f315828bSThierry Reding 573f315828bSThierry Reding static int tegra_pcie_power_on(struct tegra_pcie *pcie) 574f315828bSThierry Reding { 575f315828bSThierry Reding const struct tegra_pcie_soc *soc = pcie->soc; 576f315828bSThierry Reding unsigned long value; 577f315828bSThierry Reding int err; 578f315828bSThierry Reding 579f315828bSThierry Reding /* reset PCIEXCLK logic, AFI controller and PCIe controller */ 580f315828bSThierry Reding reset_set_enable(PERIPH_ID_PCIEXCLK, 1); 581f315828bSThierry Reding reset_set_enable(PERIPH_ID_AFI, 1); 582f315828bSThierry Reding reset_set_enable(PERIPH_ID_PCIE, 1); 583f315828bSThierry Reding 584f315828bSThierry Reding err = tegra_powergate_power_off(TEGRA_POWERGATE_PCIE); 585f315828bSThierry Reding if (err < 0) { 586f315828bSThierry Reding error("failed to power off PCIe partition: %d", err); 587f315828bSThierry Reding return err; 588f315828bSThierry Reding } 589f315828bSThierry Reding 590f315828bSThierry Reding tegra_pcie_board_init(); 591f315828bSThierry Reding 592f315828bSThierry Reding err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE, 593f315828bSThierry Reding PERIPH_ID_PCIE); 594f315828bSThierry Reding if (err < 0) { 595f315828bSThierry Reding error("failed to power up PCIe partition: %d", err); 596f315828bSThierry Reding return err; 597f315828bSThierry Reding } 598f315828bSThierry Reding 599f315828bSThierry Reding /* take AFI controller out of reset */ 600f315828bSThierry Reding reset_set_enable(PERIPH_ID_AFI, 0); 601f315828bSThierry Reding 602f315828bSThierry Reding /* enable AFI clock */ 603f315828bSThierry Reding clock_enable(PERIPH_ID_AFI); 604f315828bSThierry Reding 605f315828bSThierry Reding if (soc->has_cml_clk) { 606f315828bSThierry Reding /* enable CML clock */ 607f315828bSThierry Reding value = readl(NV_PA_CLK_RST_BASE + 0x48c); 608f315828bSThierry Reding value |= (1 << 0); 609f315828bSThierry Reding value &= ~(1 << 1); 610f315828bSThierry Reding writel(value, NV_PA_CLK_RST_BASE + 0x48c); 611f315828bSThierry Reding } 612f315828bSThierry Reding 613f315828bSThierry Reding err = tegra_plle_enable(); 614f315828bSThierry Reding if (err < 0) { 615f315828bSThierry Reding error("failed to enable PLLE: %d\n", err); 616f315828bSThierry Reding return err; 617f315828bSThierry Reding } 618f315828bSThierry Reding 619f315828bSThierry Reding return 0; 620f315828bSThierry Reding } 621f315828bSThierry Reding 622f315828bSThierry Reding static int tegra_pcie_pll_wait(struct tegra_pcie *pcie, unsigned long timeout) 623f315828bSThierry Reding { 624f315828bSThierry Reding const struct tegra_pcie_soc *soc = pcie->soc; 625f315828bSThierry Reding unsigned long start = get_timer(0); 626f315828bSThierry Reding u32 value; 627f315828bSThierry Reding 628f315828bSThierry Reding while (get_timer(start) < timeout) { 629f315828bSThierry Reding value = pads_readl(pcie, soc->pads_pll_ctl); 630f315828bSThierry Reding if (value & PADS_PLL_CTL_LOCKDET) 631f315828bSThierry Reding return 0; 632f315828bSThierry Reding } 633f315828bSThierry Reding 634f315828bSThierry Reding return -ETIMEDOUT; 635f315828bSThierry Reding } 636f315828bSThierry Reding 637f315828bSThierry Reding static int tegra_pcie_phy_enable(struct tegra_pcie *pcie) 638f315828bSThierry Reding { 639f315828bSThierry Reding const struct tegra_pcie_soc *soc = pcie->soc; 640f315828bSThierry Reding u32 value; 641f315828bSThierry Reding int err; 642f315828bSThierry Reding 643f315828bSThierry Reding /* initialize internal PHY, enable up to 16 PCIe lanes */ 644f315828bSThierry Reding pads_writel(pcie, 0, PADS_CTL_SEL); 645f315828bSThierry Reding 646f315828bSThierry Reding /* override IDDQ to 1 on all 4 lanes */ 647f315828bSThierry Reding value = pads_readl(pcie, PADS_CTL); 648f315828bSThierry Reding value |= PADS_CTL_IDDQ_1L; 649f315828bSThierry Reding pads_writel(pcie, value, PADS_CTL); 650f315828bSThierry Reding 651f315828bSThierry Reding /* 652f315828bSThierry Reding * Set up PHY PLL inputs select PLLE output as refclock, set TX 653f315828bSThierry Reding * ref sel to div10 (not div5). 654f315828bSThierry Reding */ 655f315828bSThierry Reding value = pads_readl(pcie, soc->pads_pll_ctl); 656f315828bSThierry Reding value &= ~(PADS_PLL_CTL_REFCLK_MASK | PADS_PLL_CTL_TXCLKREF_MASK); 657f315828bSThierry Reding value |= PADS_PLL_CTL_REFCLK_INTERNAL_CML | soc->tx_ref_sel; 658f315828bSThierry Reding pads_writel(pcie, value, soc->pads_pll_ctl); 659f315828bSThierry Reding 660f315828bSThierry Reding /* reset PLL */ 661f315828bSThierry Reding value = pads_readl(pcie, soc->pads_pll_ctl); 662f315828bSThierry Reding value &= ~PADS_PLL_CTL_RST_B4SM; 663f315828bSThierry Reding pads_writel(pcie, value, soc->pads_pll_ctl); 664f315828bSThierry Reding 665f315828bSThierry Reding udelay(20); 666f315828bSThierry Reding 667f315828bSThierry Reding /* take PLL out of reset */ 668f315828bSThierry Reding value = pads_readl(pcie, soc->pads_pll_ctl); 669f315828bSThierry Reding value |= PADS_PLL_CTL_RST_B4SM; 670f315828bSThierry Reding pads_writel(pcie, value, soc->pads_pll_ctl); 671f315828bSThierry Reding 672f315828bSThierry Reding /* configure the reference clock driver */ 673f315828bSThierry Reding value = PADS_REFCLK_CFG_VALUE | (PADS_REFCLK_CFG_VALUE << 16); 674f315828bSThierry Reding pads_writel(pcie, value, PADS_REFCLK_CFG0); 675f315828bSThierry Reding 676f315828bSThierry Reding if (soc->num_ports > 2) 677f315828bSThierry Reding pads_writel(pcie, PADS_REFCLK_CFG_VALUE, PADS_REFCLK_CFG1); 678f315828bSThierry Reding 679f315828bSThierry Reding /* wait for the PLL to lock */ 680f315828bSThierry Reding err = tegra_pcie_pll_wait(pcie, 500); 681f315828bSThierry Reding if (err < 0) { 682f315828bSThierry Reding error("PLL failed to lock: %d", err); 683f315828bSThierry Reding return err; 684f315828bSThierry Reding } 685f315828bSThierry Reding 686f315828bSThierry Reding /* turn off IDDQ override */ 687f315828bSThierry Reding value = pads_readl(pcie, PADS_CTL); 688f315828bSThierry Reding value &= ~PADS_CTL_IDDQ_1L; 689f315828bSThierry Reding pads_writel(pcie, value, PADS_CTL); 690f315828bSThierry Reding 691f315828bSThierry Reding /* enable TX/RX data */ 692f315828bSThierry Reding value = pads_readl(pcie, PADS_CTL); 693f315828bSThierry Reding value |= PADS_CTL_TX_DATA_EN_1L | PADS_CTL_RX_DATA_EN_1L; 694f315828bSThierry Reding pads_writel(pcie, value, PADS_CTL); 695f315828bSThierry Reding 696f315828bSThierry Reding return 0; 697f315828bSThierry Reding } 698f315828bSThierry Reding 699f315828bSThierry Reding static int tegra_pcie_enable_controller(struct tegra_pcie *pcie) 700f315828bSThierry Reding { 701f315828bSThierry Reding const struct tegra_pcie_soc *soc = pcie->soc; 702f315828bSThierry Reding struct tegra_pcie_port *port; 703f315828bSThierry Reding u32 value; 704f315828bSThierry Reding int err; 705f315828bSThierry Reding 706f315828bSThierry Reding if (pcie->phy) { 707f315828bSThierry Reding value = afi_readl(pcie, AFI_PLLE_CONTROL); 708f315828bSThierry Reding value &= ~AFI_PLLE_CONTROL_BYPASS_PADS2PLLE_CONTROL; 709f315828bSThierry Reding value |= AFI_PLLE_CONTROL_PADS2PLLE_CONTROL_EN; 710f315828bSThierry Reding afi_writel(pcie, value, AFI_PLLE_CONTROL); 711f315828bSThierry Reding } 712f315828bSThierry Reding 713f315828bSThierry Reding if (soc->has_pex_bias_ctrl) 714f315828bSThierry Reding afi_writel(pcie, 0, AFI_PEXBIAS_CTRL_0); 715f315828bSThierry Reding 716f315828bSThierry Reding value = afi_readl(pcie, AFI_PCIE_CONFIG); 717f315828bSThierry Reding value &= ~AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK; 718f315828bSThierry Reding value |= AFI_PCIE_CONFIG_PCIE_DISABLE_ALL | pcie->xbar; 719f315828bSThierry Reding 720f315828bSThierry Reding list_for_each_entry(port, &pcie->ports, list) 721f315828bSThierry Reding value &= ~AFI_PCIE_CONFIG_PCIE_DISABLE(port->index); 722f315828bSThierry Reding 723f315828bSThierry Reding afi_writel(pcie, value, AFI_PCIE_CONFIG); 724f315828bSThierry Reding 725f315828bSThierry Reding value = afi_readl(pcie, AFI_FUSE); 726f315828bSThierry Reding 727f315828bSThierry Reding if (soc->has_gen2) 728f315828bSThierry Reding value &= ~AFI_FUSE_PCIE_T0_GEN2_DIS; 729f315828bSThierry Reding else 730f315828bSThierry Reding value |= AFI_FUSE_PCIE_T0_GEN2_DIS; 731f315828bSThierry Reding 732f315828bSThierry Reding afi_writel(pcie, value, AFI_FUSE); 733f315828bSThierry Reding 734f315828bSThierry Reding if (pcie->phy) 735f315828bSThierry Reding err = tegra_xusb_phy_enable(pcie->phy); 736f315828bSThierry Reding else 737f315828bSThierry Reding err = tegra_pcie_phy_enable(pcie); 738f315828bSThierry Reding 739f315828bSThierry Reding if (err < 0) { 740f315828bSThierry Reding error("failed to power on PHY: %d\n", err); 741f315828bSThierry Reding return err; 742f315828bSThierry Reding } 743f315828bSThierry Reding 744f315828bSThierry Reding /* take the PCIEXCLK logic out of reset */ 745f315828bSThierry Reding reset_set_enable(PERIPH_ID_PCIEXCLK, 0); 746f315828bSThierry Reding 747f315828bSThierry Reding /* finally enable PCIe */ 748f315828bSThierry Reding value = afi_readl(pcie, AFI_CONFIGURATION); 749f315828bSThierry Reding value |= AFI_CONFIGURATION_EN_FPCI; 750f315828bSThierry Reding afi_writel(pcie, value, AFI_CONFIGURATION); 751f315828bSThierry Reding 752f315828bSThierry Reding /* disable all interrupts */ 753f315828bSThierry Reding afi_writel(pcie, 0, AFI_AFI_INTR_ENABLE); 754f315828bSThierry Reding afi_writel(pcie, 0, AFI_SM_INTR_ENABLE); 755f315828bSThierry Reding afi_writel(pcie, 0, AFI_INTR_MASK); 756f315828bSThierry Reding afi_writel(pcie, 0, AFI_FPCI_ERROR_MASKS); 757f315828bSThierry Reding 758f315828bSThierry Reding return 0; 759f315828bSThierry Reding } 760f315828bSThierry Reding 761f315828bSThierry Reding static void tegra_pcie_setup_translations(struct tegra_pcie *pcie) 762f315828bSThierry Reding { 763f315828bSThierry Reding unsigned long fpci, axi, size; 764f315828bSThierry Reding 765f315828bSThierry Reding /* BAR 0: type 1 extended configuration space */ 766f315828bSThierry Reding fpci = 0xfe100000; 767f315828bSThierry Reding size = fdt_resource_size(&pcie->cs); 768f315828bSThierry Reding axi = pcie->cs.start; 769f315828bSThierry Reding 770f315828bSThierry Reding afi_writel(pcie, axi, AFI_AXI_BAR0_START); 771f315828bSThierry Reding afi_writel(pcie, size >> 12, AFI_AXI_BAR0_SZ); 772f315828bSThierry Reding afi_writel(pcie, fpci, AFI_FPCI_BAR0); 773f315828bSThierry Reding 774f315828bSThierry Reding /* BAR 1: downstream I/O */ 775f315828bSThierry Reding fpci = 0xfdfc0000; 776f315828bSThierry Reding size = fdt_resource_size(&pcie->io); 777f315828bSThierry Reding axi = pcie->io.start; 778f315828bSThierry Reding 779f315828bSThierry Reding afi_writel(pcie, axi, AFI_AXI_BAR1_START); 780f315828bSThierry Reding afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ); 781f315828bSThierry Reding afi_writel(pcie, fpci, AFI_FPCI_BAR1); 782f315828bSThierry Reding 783f315828bSThierry Reding /* BAR 2: prefetchable memory */ 784f315828bSThierry Reding fpci = (((pcie->prefetch.start >> 12) & 0x0fffffff) << 4) | 0x1; 785f315828bSThierry Reding size = fdt_resource_size(&pcie->prefetch); 786f315828bSThierry Reding axi = pcie->prefetch.start; 787f315828bSThierry Reding 788f315828bSThierry Reding afi_writel(pcie, axi, AFI_AXI_BAR2_START); 789f315828bSThierry Reding afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ); 790f315828bSThierry Reding afi_writel(pcie, fpci, AFI_FPCI_BAR2); 791f315828bSThierry Reding 792f315828bSThierry Reding /* BAR 3: non-prefetchable memory */ 793f315828bSThierry Reding fpci = (((pcie->mem.start >> 12) & 0x0fffffff) << 4) | 0x1; 794f315828bSThierry Reding size = fdt_resource_size(&pcie->mem); 795f315828bSThierry Reding axi = pcie->mem.start; 796f315828bSThierry Reding 797f315828bSThierry Reding afi_writel(pcie, axi, AFI_AXI_BAR3_START); 798f315828bSThierry Reding afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ); 799f315828bSThierry Reding afi_writel(pcie, fpci, AFI_FPCI_BAR3); 800f315828bSThierry Reding 801f315828bSThierry Reding /* NULL out the remaining BARs as they are not used */ 802f315828bSThierry Reding afi_writel(pcie, 0, AFI_AXI_BAR4_START); 803f315828bSThierry Reding afi_writel(pcie, 0, AFI_AXI_BAR4_SZ); 804f315828bSThierry Reding afi_writel(pcie, 0, AFI_FPCI_BAR4); 805f315828bSThierry Reding 806f315828bSThierry Reding afi_writel(pcie, 0, AFI_AXI_BAR5_START); 807f315828bSThierry Reding afi_writel(pcie, 0, AFI_AXI_BAR5_SZ); 808f315828bSThierry Reding afi_writel(pcie, 0, AFI_FPCI_BAR5); 809f315828bSThierry Reding 810f315828bSThierry Reding /* map all upstream transactions as uncached */ 811f315828bSThierry Reding afi_writel(pcie, NV_PA_SDRAM_BASE, AFI_CACHE_BAR0_ST); 812f315828bSThierry Reding afi_writel(pcie, 0, AFI_CACHE_BAR0_SZ); 813f315828bSThierry Reding afi_writel(pcie, 0, AFI_CACHE_BAR1_ST); 814f315828bSThierry Reding afi_writel(pcie, 0, AFI_CACHE_BAR1_SZ); 815f315828bSThierry Reding 816f315828bSThierry Reding /* MSI translations are setup only when needed */ 817f315828bSThierry Reding afi_writel(pcie, 0, AFI_MSI_FPCI_BAR_ST); 818f315828bSThierry Reding afi_writel(pcie, 0, AFI_MSI_BAR_SZ); 819f315828bSThierry Reding afi_writel(pcie, 0, AFI_MSI_AXI_BAR_ST); 820f315828bSThierry Reding afi_writel(pcie, 0, AFI_MSI_BAR_SZ); 821f315828bSThierry Reding } 822f315828bSThierry Reding 823f315828bSThierry Reding static unsigned long tegra_pcie_port_get_pex_ctrl(struct tegra_pcie_port *port) 824f315828bSThierry Reding { 825f315828bSThierry Reding unsigned long ret = 0; 826f315828bSThierry Reding 827f315828bSThierry Reding switch (port->index) { 828f315828bSThierry Reding case 0: 829f315828bSThierry Reding ret = AFI_PEX0_CTRL; 830f315828bSThierry Reding break; 831f315828bSThierry Reding 832f315828bSThierry Reding case 1: 833f315828bSThierry Reding ret = AFI_PEX1_CTRL; 834f315828bSThierry Reding break; 835f315828bSThierry Reding 836f315828bSThierry Reding case 2: 837f315828bSThierry Reding ret = AFI_PEX2_CTRL; 838f315828bSThierry Reding break; 839f315828bSThierry Reding } 840f315828bSThierry Reding 841f315828bSThierry Reding return ret; 842f315828bSThierry Reding } 843f315828bSThierry Reding 844f315828bSThierry Reding static void tegra_pcie_port_reset(struct tegra_pcie_port *port) 845f315828bSThierry Reding { 846f315828bSThierry Reding unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port); 847f315828bSThierry Reding unsigned long value; 848f315828bSThierry Reding 849f315828bSThierry Reding /* pulse reset signel */ 850f315828bSThierry Reding value = afi_readl(port->pcie, ctrl); 851f315828bSThierry Reding value &= ~AFI_PEX_CTRL_RST; 852f315828bSThierry Reding afi_writel(port->pcie, value, ctrl); 853f315828bSThierry Reding 854f315828bSThierry Reding udelay(2000); 855f315828bSThierry Reding 856f315828bSThierry Reding value = afi_readl(port->pcie, ctrl); 857f315828bSThierry Reding value |= AFI_PEX_CTRL_RST; 858f315828bSThierry Reding afi_writel(port->pcie, value, ctrl); 859f315828bSThierry Reding } 860f315828bSThierry Reding 861f315828bSThierry Reding static void tegra_pcie_port_enable(struct tegra_pcie_port *port) 862f315828bSThierry Reding { 863f315828bSThierry Reding unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port); 864f315828bSThierry Reding unsigned long value; 865f315828bSThierry Reding 866f315828bSThierry Reding /* enable reference clock */ 867f315828bSThierry Reding value = afi_readl(port->pcie, ctrl); 868f315828bSThierry Reding value |= AFI_PEX_CTRL_REFCLK_EN; 869f315828bSThierry Reding 870f315828bSThierry Reding if (port->pcie->soc->has_pex_clkreq_en) 871f315828bSThierry Reding value |= AFI_PEX_CTRL_CLKREQ_EN; 872f315828bSThierry Reding 873f315828bSThierry Reding value |= AFI_PEX_CTRL_OVERRIDE_EN; 874f315828bSThierry Reding 875f315828bSThierry Reding afi_writel(port->pcie, value, ctrl); 876f315828bSThierry Reding 877f315828bSThierry Reding tegra_pcie_port_reset(port); 878f315828bSThierry Reding } 879f315828bSThierry Reding 880f315828bSThierry Reding static bool tegra_pcie_port_check_link(struct tegra_pcie_port *port) 881f315828bSThierry Reding { 882f315828bSThierry Reding unsigned int retries = 3; 883f315828bSThierry Reding unsigned long value; 884f315828bSThierry Reding 885f315828bSThierry Reding value = rp_readl(port, RP_PRIV_MISC); 886f315828bSThierry Reding value &= ~RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT; 887f315828bSThierry Reding value |= RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT; 888f315828bSThierry Reding rp_writel(port, value, RP_PRIV_MISC); 889f315828bSThierry Reding 890f315828bSThierry Reding do { 891f315828bSThierry Reding unsigned int timeout = 200; 892f315828bSThierry Reding 893f315828bSThierry Reding do { 894f315828bSThierry Reding value = rp_readl(port, RP_VEND_XP); 895f315828bSThierry Reding if (value & RP_VEND_XP_DL_UP) 896f315828bSThierry Reding break; 897f315828bSThierry Reding 898f315828bSThierry Reding udelay(2000); 899f315828bSThierry Reding } while (--timeout); 900f315828bSThierry Reding 901f315828bSThierry Reding if (!timeout) { 902f315828bSThierry Reding debug("link %u down, retrying\n", port->index); 903f315828bSThierry Reding goto retry; 904f315828bSThierry Reding } 905f315828bSThierry Reding 906f315828bSThierry Reding timeout = 200; 907f315828bSThierry Reding 908f315828bSThierry Reding do { 909f315828bSThierry Reding value = rp_readl(port, RP_LINK_CONTROL_STATUS); 910f315828bSThierry Reding if (value & RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE) 911f315828bSThierry Reding return true; 912f315828bSThierry Reding 913f315828bSThierry Reding udelay(2000); 914f315828bSThierry Reding } while (--timeout); 915f315828bSThierry Reding 916f315828bSThierry Reding retry: 917f315828bSThierry Reding tegra_pcie_port_reset(port); 918f315828bSThierry Reding } while (--retries); 919f315828bSThierry Reding 920f315828bSThierry Reding return false; 921f315828bSThierry Reding } 922f315828bSThierry Reding 923f315828bSThierry Reding static void tegra_pcie_port_disable(struct tegra_pcie_port *port) 924f315828bSThierry Reding { 925f315828bSThierry Reding unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port); 926f315828bSThierry Reding unsigned long value; 927f315828bSThierry Reding 928f315828bSThierry Reding /* assert port reset */ 929f315828bSThierry Reding value = afi_readl(port->pcie, ctrl); 930f315828bSThierry Reding value &= ~AFI_PEX_CTRL_RST; 931f315828bSThierry Reding afi_writel(port->pcie, value, ctrl); 932f315828bSThierry Reding 933f315828bSThierry Reding /* disable reference clock */ 934f315828bSThierry Reding value = afi_readl(port->pcie, ctrl); 935f315828bSThierry Reding value &= ~AFI_PEX_CTRL_REFCLK_EN; 936f315828bSThierry Reding afi_writel(port->pcie, value, ctrl); 937f315828bSThierry Reding } 938f315828bSThierry Reding 939f315828bSThierry Reding static void tegra_pcie_port_free(struct tegra_pcie_port *port) 940f315828bSThierry Reding { 941f315828bSThierry Reding list_del(&port->list); 942f315828bSThierry Reding free(port); 943f315828bSThierry Reding } 944f315828bSThierry Reding 945f315828bSThierry Reding static int tegra_pcie_enable(struct tegra_pcie *pcie) 946f315828bSThierry Reding { 947f315828bSThierry Reding struct tegra_pcie_port *port, *tmp; 948f315828bSThierry Reding 949f315828bSThierry Reding list_for_each_entry_safe(port, tmp, &pcie->ports, list) { 950f315828bSThierry Reding debug("probing port %u, using %u lanes\n", port->index, 951f315828bSThierry Reding port->num_lanes); 952f315828bSThierry Reding 953f315828bSThierry Reding tegra_pcie_port_enable(port); 954f315828bSThierry Reding 955f315828bSThierry Reding if (tegra_pcie_port_check_link(port)) 956f315828bSThierry Reding continue; 957f315828bSThierry Reding 958f315828bSThierry Reding debug("link %u down, ignoring\n", port->index); 959f315828bSThierry Reding 960f315828bSThierry Reding tegra_pcie_port_disable(port); 961f315828bSThierry Reding tegra_pcie_port_free(port); 962f315828bSThierry Reding } 963f315828bSThierry Reding 964f315828bSThierry Reding return 0; 965f315828bSThierry Reding } 966f315828bSThierry Reding 967f315828bSThierry Reding static const struct tegra_pcie_soc tegra20_pcie_soc = { 968f315828bSThierry Reding .num_ports = 2, 969f315828bSThierry Reding .pads_pll_ctl = PADS_PLL_CTL_TEGRA20, 970f315828bSThierry Reding .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_DIV10, 971f315828bSThierry Reding .has_pex_clkreq_en = false, 972f315828bSThierry Reding .has_pex_bias_ctrl = false, 973f315828bSThierry Reding .has_cml_clk = false, 974f315828bSThierry Reding .has_gen2 = false, 975f315828bSThierry Reding }; 976f315828bSThierry Reding 977f315828bSThierry Reding static const struct tegra_pcie_soc tegra30_pcie_soc = { 978f315828bSThierry Reding .num_ports = 3, 979f315828bSThierry Reding .pads_pll_ctl = PADS_PLL_CTL_TEGRA30, 980f315828bSThierry Reding .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN, 981f315828bSThierry Reding .has_pex_clkreq_en = true, 982f315828bSThierry Reding .has_pex_bias_ctrl = true, 983f315828bSThierry Reding .has_cml_clk = true, 984f315828bSThierry Reding .has_gen2 = false, 985f315828bSThierry Reding }; 986f315828bSThierry Reding 987f315828bSThierry Reding static const struct tegra_pcie_soc tegra124_pcie_soc = { 988f315828bSThierry Reding .num_ports = 2, 989f315828bSThierry Reding .pads_pll_ctl = PADS_PLL_CTL_TEGRA30, 990f315828bSThierry Reding .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN, 991f315828bSThierry Reding .has_pex_clkreq_en = true, 992f315828bSThierry Reding .has_pex_bias_ctrl = true, 993f315828bSThierry Reding .has_cml_clk = true, 994f315828bSThierry Reding .has_gen2 = true, 995f315828bSThierry Reding }; 996f315828bSThierry Reding 997f315828bSThierry Reding static int process_nodes(const void *fdt, int nodes[], unsigned int count) 998f315828bSThierry Reding { 999f315828bSThierry Reding unsigned int i; 1000f315828bSThierry Reding 1001f315828bSThierry Reding for (i = 0; i < count; i++) { 1002f315828bSThierry Reding const struct tegra_pcie_soc *soc; 1003f315828bSThierry Reding struct tegra_pcie *pcie; 1004f315828bSThierry Reding enum fdt_compat_id id; 1005f315828bSThierry Reding int err; 1006f315828bSThierry Reding 1007f315828bSThierry Reding if (!fdtdec_get_is_enabled(fdt, nodes[i])) 1008f315828bSThierry Reding continue; 1009f315828bSThierry Reding 1010f315828bSThierry Reding id = fdtdec_lookup(fdt, nodes[i]); 1011f315828bSThierry Reding switch (id) { 1012f315828bSThierry Reding case COMPAT_NVIDIA_TEGRA20_PCIE: 1013f315828bSThierry Reding soc = &tegra20_pcie_soc; 1014f315828bSThierry Reding break; 1015f315828bSThierry Reding 1016f315828bSThierry Reding case COMPAT_NVIDIA_TEGRA30_PCIE: 1017f315828bSThierry Reding soc = &tegra30_pcie_soc; 1018f315828bSThierry Reding break; 1019f315828bSThierry Reding 1020f315828bSThierry Reding case COMPAT_NVIDIA_TEGRA124_PCIE: 1021f315828bSThierry Reding soc = &tegra124_pcie_soc; 1022f315828bSThierry Reding break; 1023f315828bSThierry Reding 1024f315828bSThierry Reding default: 1025f315828bSThierry Reding error("unsupported compatible: %s", 1026f315828bSThierry Reding fdtdec_get_compatible(id)); 1027f315828bSThierry Reding continue; 1028f315828bSThierry Reding } 1029f315828bSThierry Reding 1030f315828bSThierry Reding pcie = malloc(sizeof(*pcie)); 1031f315828bSThierry Reding if (!pcie) { 1032f315828bSThierry Reding error("failed to allocate controller"); 1033f315828bSThierry Reding continue; 1034f315828bSThierry Reding } 1035f315828bSThierry Reding 1036f315828bSThierry Reding memset(pcie, 0, sizeof(*pcie)); 1037f315828bSThierry Reding pcie->soc = soc; 1038f315828bSThierry Reding 1039f315828bSThierry Reding INIT_LIST_HEAD(&pcie->ports); 1040f315828bSThierry Reding 1041f315828bSThierry Reding err = tegra_pcie_parse_dt(fdt, nodes[i], pcie); 1042f315828bSThierry Reding if (err < 0) { 1043f315828bSThierry Reding free(pcie); 1044f315828bSThierry Reding continue; 1045f315828bSThierry Reding } 1046f315828bSThierry Reding 1047f315828bSThierry Reding err = tegra_pcie_power_on(pcie); 1048f315828bSThierry Reding if (err < 0) { 1049f315828bSThierry Reding error("failed to power on"); 1050f315828bSThierry Reding continue; 1051f315828bSThierry Reding } 1052f315828bSThierry Reding 1053f315828bSThierry Reding err = tegra_pcie_enable_controller(pcie); 1054f315828bSThierry Reding if (err < 0) { 1055f315828bSThierry Reding error("failed to enable controller"); 1056f315828bSThierry Reding continue; 1057f315828bSThierry Reding } 1058f315828bSThierry Reding 1059f315828bSThierry Reding tegra_pcie_setup_translations(pcie); 1060f315828bSThierry Reding 1061f315828bSThierry Reding err = tegra_pcie_enable(pcie); 1062f315828bSThierry Reding if (err < 0) { 1063f315828bSThierry Reding error("failed to enable PCIe"); 1064f315828bSThierry Reding continue; 1065f315828bSThierry Reding } 1066f315828bSThierry Reding 1067f315828bSThierry Reding pcie->hose.first_busno = 0; 1068f315828bSThierry Reding pcie->hose.current_busno = 0; 1069f315828bSThierry Reding pcie->hose.last_busno = 0; 1070f315828bSThierry Reding 1071f315828bSThierry Reding pci_set_region(&pcie->hose.regions[0], NV_PA_SDRAM_BASE, 1072f315828bSThierry Reding NV_PA_SDRAM_BASE, gd->ram_size, 1073f315828bSThierry Reding PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); 1074f315828bSThierry Reding 1075f315828bSThierry Reding pci_set_region(&pcie->hose.regions[1], pcie->io.start, 1076f315828bSThierry Reding pcie->io.start, fdt_resource_size(&pcie->io), 1077f315828bSThierry Reding PCI_REGION_IO); 1078f315828bSThierry Reding 1079f315828bSThierry Reding pci_set_region(&pcie->hose.regions[2], pcie->mem.start, 1080f315828bSThierry Reding pcie->mem.start, fdt_resource_size(&pcie->mem), 1081f315828bSThierry Reding PCI_REGION_MEM); 1082f315828bSThierry Reding 1083f315828bSThierry Reding pci_set_region(&pcie->hose.regions[3], pcie->prefetch.start, 1084f315828bSThierry Reding pcie->prefetch.start, 1085f315828bSThierry Reding fdt_resource_size(&pcie->prefetch), 1086f315828bSThierry Reding PCI_REGION_MEM | PCI_REGION_PREFETCH); 1087f315828bSThierry Reding 1088f315828bSThierry Reding pcie->hose.region_count = 4; 1089f315828bSThierry Reding 1090f315828bSThierry Reding pci_set_ops(&pcie->hose, 1091f315828bSThierry Reding pci_hose_read_config_byte_via_dword, 1092f315828bSThierry Reding pci_hose_read_config_word_via_dword, 1093f315828bSThierry Reding tegra_pcie_read_conf, 1094f315828bSThierry Reding pci_hose_write_config_byte_via_dword, 1095f315828bSThierry Reding pci_hose_write_config_word_via_dword, 1096f315828bSThierry Reding tegra_pcie_write_conf); 1097f315828bSThierry Reding 1098f315828bSThierry Reding pci_register_hose(&pcie->hose); 1099f315828bSThierry Reding 1100f315828bSThierry Reding #ifdef CONFIG_PCI_SCAN_SHOW 1101f315828bSThierry Reding printf("PCI: Enumerating devices...\n"); 1102f315828bSThierry Reding printf("---------------------------------------\n"); 1103f315828bSThierry Reding printf(" Device ID Description\n"); 1104f315828bSThierry Reding printf(" ------ -- -----------\n"); 1105f315828bSThierry Reding #endif 1106f315828bSThierry Reding 1107f315828bSThierry Reding pcie->hose.last_busno = pci_hose_scan(&pcie->hose); 1108f315828bSThierry Reding } 1109f315828bSThierry Reding 1110f315828bSThierry Reding return 0; 1111f315828bSThierry Reding } 1112f315828bSThierry Reding 1113f315828bSThierry Reding void pci_init_board(void) 1114f315828bSThierry Reding { 1115f315828bSThierry Reding const void *fdt = gd->fdt_blob; 1116f315828bSThierry Reding int count, nodes[1]; 1117f315828bSThierry Reding 1118f315828bSThierry Reding count = fdtdec_find_aliases_for_id(fdt, "pcie-controller", 1119f315828bSThierry Reding COMPAT_NVIDIA_TEGRA124_PCIE, 1120f315828bSThierry Reding nodes, ARRAY_SIZE(nodes)); 1121f315828bSThierry Reding if (process_nodes(fdt, nodes, count)) 1122f315828bSThierry Reding return; 1123f315828bSThierry Reding 1124f315828bSThierry Reding count = fdtdec_find_aliases_for_id(fdt, "pcie-controller", 1125f315828bSThierry Reding COMPAT_NVIDIA_TEGRA30_PCIE, 1126f315828bSThierry Reding nodes, ARRAY_SIZE(nodes)); 1127f315828bSThierry Reding if (process_nodes(fdt, nodes, count)) 1128f315828bSThierry Reding return; 1129f315828bSThierry Reding 1130f315828bSThierry Reding count = fdtdec_find_aliases_for_id(fdt, "pcie-controller", 1131f315828bSThierry Reding COMPAT_NVIDIA_TEGRA20_PCIE, 1132f315828bSThierry Reding nodes, ARRAY_SIZE(nodes)); 1133f315828bSThierry Reding if (process_nodes(fdt, nodes, count)) 1134f315828bSThierry Reding return; 1135f315828bSThierry Reding } 1136f315828bSThierry Reding 1137f315828bSThierry Reding int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev) 1138f315828bSThierry Reding { 1139f315828bSThierry Reding if (PCI_BUS(dev) != 0 && PCI_DEV(dev) > 0) 1140f315828bSThierry Reding return 1; 1141f315828bSThierry Reding 1142f315828bSThierry Reding return 0; 1143f315828bSThierry Reding } 1144