1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (c) 2017 Cadence 3 // Cadence PCIe host controller driver. 4 // Author: Cyrille Pitchen <cyrille.pitchen@free-electrons.com> 5 6 #include <linux/delay.h> 7 #include <linux/kernel.h> 8 #include <linux/module.h> 9 #include <linux/list_sort.h> 10 #include <linux/of_address.h> 11 #include <linux/of_pci.h> 12 #include <linux/platform_device.h> 13 14 #include "pcie-cadence.h" 15 #include "pcie-cadence-host-common.h" 16 17 static u8 bar_aperture_mask[] = { 18 [RP_BAR0] = 0x1F, 19 [RP_BAR1] = 0xF, 20 }; 21 22 void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn, 23 int where) 24 { 25 struct pci_host_bridge *bridge = pci_find_host_bridge(bus); 26 struct cdns_pcie_rc *rc = pci_host_bridge_priv(bridge); 27 struct cdns_pcie *pcie = &rc->pcie; 28 unsigned int busn = bus->number; 29 u32 addr0, desc0; 30 31 if (pci_is_root_bus(bus)) { 32 /* 33 * Only the root port (devfn == 0) is connected to this bus. 34 * All other PCI devices are behind some bridge hence on another 35 * bus. 36 */ 37 if (devfn) 38 return NULL; 39 40 return pcie->reg_base + (where & 0xfff); 41 } 42 /* Check that the link is up */ 43 if (!(cdns_pcie_readl(pcie, CDNS_PCIE_LM_BASE) & 0x1)) 44 return NULL; 45 /* Clear AXI link-down status */ 46 cdns_pcie_writel(pcie, CDNS_PCIE_AT_LINKDOWN, 0x0); 47 48 /* Update Output registers for AXI region 0. */ 49 addr0 = CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS(12) | 50 CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN(devfn) | 51 CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_BUS(busn); 52 cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR0(0), addr0); 53 54 /* Configuration Type 0 or Type 1 access. */ 55 desc0 = CDNS_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID | 56 CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(0); 57 /* 58 * The bus number was already set once for all in desc1 by 59 * cdns_pcie_host_init_address_translation(). 60 */ 61 if (busn == bridge->busnr + 1) 62 desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE0; 63 else 64 desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE1; 65 cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC0(0), desc0); 66 67 return rc->cfg_base + (where & 0xfff); 68 } 69 EXPORT_SYMBOL_GPL(cdns_pci_map_bus); 70 71 static struct pci_ops cdns_pcie_host_ops = { 72 .map_bus = cdns_pci_map_bus, 73 .read = pci_generic_config_read, 74 .write = pci_generic_config_write, 75 }; 76 77 static void cdns_pcie_host_disable_ptm_response(struct cdns_pcie *pcie) 78 { 79 u32 val; 80 81 val = cdns_pcie_readl(pcie, CDNS_PCIE_LM_PTM_CTRL); 82 cdns_pcie_writel(pcie, CDNS_PCIE_LM_PTM_CTRL, val & ~CDNS_PCIE_LM_TPM_CTRL_PTMRSEN); 83 } 84 85 static void cdns_pcie_host_enable_ptm_response(struct cdns_pcie *pcie) 86 { 87 u32 val; 88 89 val = cdns_pcie_readl(pcie, CDNS_PCIE_LM_PTM_CTRL); 90 cdns_pcie_writel(pcie, CDNS_PCIE_LM_PTM_CTRL, val | CDNS_PCIE_LM_TPM_CTRL_PTMRSEN); 91 } 92 93 static void cdns_pcie_host_deinit_root_port(struct cdns_pcie_rc *rc) 94 { 95 struct cdns_pcie *pcie = &rc->pcie; 96 u32 value, ctrl; 97 98 cdns_pcie_rp_writew(pcie, PCI_CLASS_DEVICE, 0xffff); 99 cdns_pcie_rp_writeb(pcie, PCI_CLASS_PROG, 0xff); 100 cdns_pcie_rp_writeb(pcie, PCI_CLASS_REVISION, 0xff); 101 cdns_pcie_writel(pcie, CDNS_PCIE_LM_ID, 0xffffffff); 102 cdns_pcie_rp_writew(pcie, PCI_DEVICE_ID, 0xffff); 103 ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED; 104 value = ~(CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL(ctrl) | 105 CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL(ctrl) | 106 CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_ENABLE | 107 CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_64BITS | 108 CDNS_PCIE_LM_RC_BAR_CFG_IO_ENABLE | 109 CDNS_PCIE_LM_RC_BAR_CFG_IO_32BITS); 110 cdns_pcie_writel(pcie, CDNS_PCIE_LM_RC_BAR_CFG, value); 111 } 112 113 static int cdns_pcie_host_init_root_port(struct cdns_pcie_rc *rc) 114 { 115 struct cdns_pcie *pcie = &rc->pcie; 116 u32 value, ctrl; 117 u32 id; 118 119 /* 120 * Set the root complex BAR configuration register: 121 * - disable both BAR0 and BAR1. 122 * - enable Prefetchable Memory Base and Limit registers in type 1 123 * config space (64 bits). 124 * - enable IO Base and Limit registers in type 1 config 125 * space (32 bits). 126 */ 127 ctrl = CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED; 128 value = CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL(ctrl) | 129 CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL(ctrl) | 130 CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_ENABLE | 131 CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_64BITS | 132 CDNS_PCIE_LM_RC_BAR_CFG_IO_ENABLE | 133 CDNS_PCIE_LM_RC_BAR_CFG_IO_32BITS; 134 cdns_pcie_writel(pcie, CDNS_PCIE_LM_RC_BAR_CFG, value); 135 136 /* Set root port configuration space */ 137 if (rc->vendor_id != 0xffff) { 138 id = CDNS_PCIE_LM_ID_VENDOR(rc->vendor_id) | 139 CDNS_PCIE_LM_ID_SUBSYS(rc->vendor_id); 140 cdns_pcie_writel(pcie, CDNS_PCIE_LM_ID, id); 141 } 142 143 if (rc->device_id != 0xffff) 144 cdns_pcie_rp_writew(pcie, PCI_DEVICE_ID, rc->device_id); 145 146 cdns_pcie_rp_writeb(pcie, PCI_CLASS_REVISION, 0); 147 cdns_pcie_rp_writeb(pcie, PCI_CLASS_PROG, 0); 148 cdns_pcie_rp_writew(pcie, PCI_CLASS_DEVICE, PCI_CLASS_BRIDGE_PCI); 149 150 return 0; 151 } 152 153 int cdns_pcie_host_bar_ib_config(struct cdns_pcie_rc *rc, 154 enum cdns_pcie_rp_bar bar, 155 u64 cpu_addr, 156 u64 size, 157 unsigned long flags) 158 { 159 struct cdns_pcie *pcie = &rc->pcie; 160 u32 addr0, addr1, aperture, value; 161 162 if (!rc->avail_ib_bar[bar]) 163 return -EBUSY; 164 165 rc->avail_ib_bar[bar] = false; 166 167 aperture = ilog2(size); 168 addr0 = CDNS_PCIE_AT_IB_RP_BAR_ADDR0_NBITS(aperture) | 169 (lower_32_bits(cpu_addr) & GENMASK(31, 8)); 170 addr1 = upper_32_bits(cpu_addr); 171 cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_RP_BAR_ADDR0(bar), addr0); 172 cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_RP_BAR_ADDR1(bar), addr1); 173 174 if (bar == RP_NO_BAR) 175 return 0; 176 177 value = cdns_pcie_readl(pcie, CDNS_PCIE_LM_RC_BAR_CFG); 178 value &= ~(LM_RC_BAR_CFG_CTRL_MEM_64BITS(bar) | 179 LM_RC_BAR_CFG_CTRL_PREF_MEM_64BITS(bar) | 180 LM_RC_BAR_CFG_CTRL_MEM_32BITS(bar) | 181 LM_RC_BAR_CFG_CTRL_PREF_MEM_32BITS(bar) | 182 LM_RC_BAR_CFG_APERTURE(bar, bar_aperture_mask[bar] + 2)); 183 if (size + cpu_addr >= SZ_4G) { 184 if (!(flags & IORESOURCE_PREFETCH)) 185 value |= LM_RC_BAR_CFG_CTRL_MEM_64BITS(bar); 186 value |= LM_RC_BAR_CFG_CTRL_PREF_MEM_64BITS(bar); 187 } else { 188 if (!(flags & IORESOURCE_PREFETCH)) 189 value |= LM_RC_BAR_CFG_CTRL_MEM_32BITS(bar); 190 value |= LM_RC_BAR_CFG_CTRL_PREF_MEM_32BITS(bar); 191 } 192 193 value |= LM_RC_BAR_CFG_APERTURE(bar, aperture); 194 cdns_pcie_writel(pcie, CDNS_PCIE_LM_RC_BAR_CFG, value); 195 196 return 0; 197 } 198 199 static void cdns_pcie_host_unmap_dma_ranges(struct cdns_pcie_rc *rc) 200 { 201 struct cdns_pcie *pcie = &rc->pcie; 202 enum cdns_pcie_rp_bar bar; 203 u32 value; 204 205 /* Reset inbound configuration for all BARs which were being used */ 206 for (bar = RP_BAR0; bar <= RP_NO_BAR; bar++) { 207 if (rc->avail_ib_bar[bar]) 208 continue; 209 210 cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_RP_BAR_ADDR0(bar), 0); 211 cdns_pcie_writel(pcie, CDNS_PCIE_AT_IB_RP_BAR_ADDR1(bar), 0); 212 213 if (bar == RP_NO_BAR) 214 continue; 215 216 value = ~(LM_RC_BAR_CFG_CTRL_MEM_64BITS(bar) | 217 LM_RC_BAR_CFG_CTRL_PREF_MEM_64BITS(bar) | 218 LM_RC_BAR_CFG_CTRL_MEM_32BITS(bar) | 219 LM_RC_BAR_CFG_CTRL_PREF_MEM_32BITS(bar) | 220 LM_RC_BAR_CFG_APERTURE(bar, bar_aperture_mask[bar] + 2)); 221 cdns_pcie_writel(pcie, CDNS_PCIE_LM_RC_BAR_CFG, value); 222 } 223 } 224 225 static void cdns_pcie_host_deinit_address_translation(struct cdns_pcie_rc *rc) 226 { 227 struct cdns_pcie *pcie = &rc->pcie; 228 struct pci_host_bridge *bridge = pci_host_bridge_from_priv(rc); 229 struct resource_entry *entry; 230 int r; 231 232 cdns_pcie_host_unmap_dma_ranges(rc); 233 234 /* 235 * Reset outbound region 0 which was reserved for configuration space 236 * accesses. 237 */ 238 cdns_pcie_reset_outbound_region(pcie, 0); 239 240 /* Reset rest of the outbound regions */ 241 r = 1; 242 resource_list_for_each_entry(entry, &bridge->windows) { 243 cdns_pcie_reset_outbound_region(pcie, r); 244 r++; 245 } 246 } 247 248 static int cdns_pcie_host_init_address_translation(struct cdns_pcie_rc *rc) 249 { 250 struct cdns_pcie *pcie = &rc->pcie; 251 struct pci_host_bridge *bridge = pci_host_bridge_from_priv(rc); 252 struct resource *cfg_res = rc->cfg_res; 253 struct resource_entry *entry; 254 u64 cpu_addr = cfg_res->start; 255 u32 addr0, addr1, desc1; 256 int r, busnr = 0; 257 258 entry = resource_list_first_type(&bridge->windows, IORESOURCE_BUS); 259 if (entry) 260 busnr = entry->res->start; 261 262 /* 263 * Reserve region 0 for PCI configure space accesses: 264 * OB_REGION_PCI_ADDR0 and OB_REGION_DESC0 are updated dynamically by 265 * cdns_pci_map_bus(), other region registers are set here once for all. 266 */ 267 addr1 = 0; /* Should be programmed to zero. */ 268 desc1 = CDNS_PCIE_AT_OB_REGION_DESC1_BUS(busnr); 269 cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(0), addr1); 270 cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC1(0), desc1); 271 272 if (pcie->ops && pcie->ops->cpu_addr_fixup) 273 cpu_addr = pcie->ops->cpu_addr_fixup(pcie, cpu_addr); 274 275 addr0 = CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(12) | 276 (lower_32_bits(cpu_addr) & GENMASK(31, 8)); 277 addr1 = upper_32_bits(cpu_addr); 278 cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(0), addr0); 279 cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(0), addr1); 280 281 r = 1; 282 resource_list_for_each_entry(entry, &bridge->windows) { 283 struct resource *res = entry->res; 284 u64 pci_addr = res->start - entry->offset; 285 286 if (resource_type(res) == IORESOURCE_IO) 287 cdns_pcie_set_outbound_region(pcie, busnr, 0, r, 288 true, 289 pci_pio_to_address(res->start), 290 pci_addr, 291 resource_size(res)); 292 else 293 cdns_pcie_set_outbound_region(pcie, busnr, 0, r, 294 false, 295 res->start, 296 pci_addr, 297 resource_size(res)); 298 299 r++; 300 } 301 302 return cdns_pcie_host_map_dma_ranges(rc, cdns_pcie_host_bar_ib_config); 303 } 304 305 static void cdns_pcie_host_deinit(struct cdns_pcie_rc *rc) 306 { 307 cdns_pcie_host_deinit_address_translation(rc); 308 cdns_pcie_host_deinit_root_port(rc); 309 } 310 311 int cdns_pcie_host_init(struct cdns_pcie_rc *rc) 312 { 313 int err; 314 315 err = cdns_pcie_host_init_root_port(rc); 316 if (err) 317 return err; 318 319 return cdns_pcie_host_init_address_translation(rc); 320 } 321 EXPORT_SYMBOL_GPL(cdns_pcie_host_init); 322 323 static void cdns_pcie_host_link_disable(struct cdns_pcie_rc *rc) 324 { 325 struct cdns_pcie *pcie = &rc->pcie; 326 327 cdns_pcie_stop_link(pcie); 328 cdns_pcie_host_disable_ptm_response(pcie); 329 } 330 331 int cdns_pcie_host_link_setup(struct cdns_pcie_rc *rc) 332 { 333 struct cdns_pcie *pcie = &rc->pcie; 334 struct device *dev = rc->pcie.dev; 335 int ret; 336 337 if (rc->quirk_detect_quiet_flag) 338 cdns_pcie_detect_quiet_min_delay_set(&rc->pcie); 339 340 cdns_pcie_host_enable_ptm_response(pcie); 341 342 ret = cdns_pcie_start_link(pcie); 343 if (ret) { 344 dev_err(dev, "Failed to start link\n"); 345 return ret; 346 } 347 348 ret = cdns_pcie_host_start_link(rc, cdns_pcie_link_up); 349 if (ret) 350 dev_dbg(dev, "PCIe link never came up\n"); 351 352 return 0; 353 } 354 EXPORT_SYMBOL_GPL(cdns_pcie_host_link_setup); 355 356 void cdns_pcie_host_disable(struct cdns_pcie_rc *rc) 357 { 358 struct pci_host_bridge *bridge; 359 360 bridge = pci_host_bridge_from_priv(rc); 361 pci_stop_root_bus(bridge->bus); 362 pci_remove_root_bus(bridge->bus); 363 364 cdns_pcie_host_deinit(rc); 365 cdns_pcie_host_link_disable(rc); 366 } 367 EXPORT_SYMBOL_GPL(cdns_pcie_host_disable); 368 369 int cdns_pcie_host_setup(struct cdns_pcie_rc *rc) 370 { 371 struct device *dev = rc->pcie.dev; 372 struct platform_device *pdev = to_platform_device(dev); 373 struct device_node *np = dev->of_node; 374 struct pci_host_bridge *bridge; 375 enum cdns_pcie_rp_bar bar; 376 struct cdns_pcie *pcie; 377 struct resource *res; 378 int ret; 379 380 bridge = pci_host_bridge_from_priv(rc); 381 if (!bridge) 382 return -ENOMEM; 383 384 pcie = &rc->pcie; 385 pcie->is_rc = true; 386 387 rc->vendor_id = 0xffff; 388 of_property_read_u32(np, "vendor-id", &rc->vendor_id); 389 390 rc->device_id = 0xffff; 391 of_property_read_u32(np, "device-id", &rc->device_id); 392 393 pcie->reg_base = devm_platform_ioremap_resource_byname(pdev, "reg"); 394 if (IS_ERR(pcie->reg_base)) { 395 dev_err(dev, "missing \"reg\"\n"); 396 return PTR_ERR(pcie->reg_base); 397 } 398 399 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg"); 400 rc->cfg_base = devm_pci_remap_cfg_resource(dev, res); 401 if (IS_ERR(rc->cfg_base)) 402 return PTR_ERR(rc->cfg_base); 403 rc->cfg_res = res; 404 405 ret = cdns_pcie_host_link_setup(rc); 406 if (ret) 407 return ret; 408 409 for (bar = RP_BAR0; bar <= RP_NO_BAR; bar++) 410 rc->avail_ib_bar[bar] = true; 411 412 ret = cdns_pcie_host_init(rc); 413 if (ret) 414 return ret; 415 416 if (!bridge->ops) 417 bridge->ops = &cdns_pcie_host_ops; 418 419 return pci_host_probe(bridge); 420 } 421 EXPORT_SYMBOL_GPL(cdns_pcie_host_setup); 422 423 MODULE_LICENSE("GPL"); 424 MODULE_DESCRIPTION("Cadence PCIe host controller driver"); 425 MODULE_AUTHOR("Cyrille Pitchen <cyrille.pitchen@free-electrons.com>"); 426