1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2015 Marvell International Ltd. 4 * 5 * Copyright (C) 2016 Stefan Roese <sr@denx.de> 6 * 7 * Based on: 8 * - drivers/pci/pcie_imx.c 9 * - drivers/pci/pci_mvebu.c 10 * - drivers/pci/pcie_xilinx.c 11 */ 12 13#include <common.h> 14#include <dm.h> 15#include <log.h> 16#include <pci.h> 17#include <asm/global_data.h> 18#include <asm/io.h> 19#include <asm-generic/gpio.h> 20#include <linux/delay.h> 21 22DECLARE_GLOBAL_DATA_PTR; 23 24/* PCI Config space registers */ 25#define PCIE_CONFIG_BAR0 0x10 26#define PCIE_LINK_STATUS_REG 0x80 27#define PCIE_LINK_STATUS_SPEED_OFF 16 28#define PCIE_LINK_STATUS_SPEED_MASK (0xf << PCIE_LINK_STATUS_SPEED_OFF) 29#define PCIE_LINK_STATUS_WIDTH_OFF 20 30#define PCIE_LINK_STATUS_WIDTH_MASK (0xf << PCIE_LINK_STATUS_WIDTH_OFF) 31 32/* Resizable bar capability registers */ 33#define RESIZABLE_BAR_CAP 0x250 34#define RESIZABLE_BAR_CTL0 0x254 35#define RESIZABLE_BAR_CTL1 0x258 36 37/* iATU registers */ 38#define PCIE_ATU_VIEWPORT 0x900 39#define PCIE_ATU_REGION_INBOUND (0x1 << 31) 40#define PCIE_ATU_REGION_OUTBOUND (0x0 << 31) 41#define PCIE_ATU_REGION_INDEX1 (0x1 << 0) 42#define PCIE_ATU_REGION_INDEX0 (0x0 << 0) 43#define PCIE_ATU_CR1 0x904 44#define PCIE_ATU_TYPE_MEM (0x0 << 0) 45#define PCIE_ATU_TYPE_IO (0x2 << 0) 46#define PCIE_ATU_TYPE_CFG0 (0x4 << 0) 47#define PCIE_ATU_TYPE_CFG1 (0x5 << 0) 48#define PCIE_ATU_CR2 0x908 49#define PCIE_ATU_ENABLE (0x1 << 31) 50#define PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30) 51#define PCIE_ATU_LOWER_BASE 0x90C 52#define PCIE_ATU_UPPER_BASE 0x910 53#define PCIE_ATU_LIMIT 0x914 54#define PCIE_ATU_LOWER_TARGET 0x918 55#define PCIE_ATU_BUS(x) (((x) & 0xff) << 24) 56#define PCIE_ATU_DEV(x) (((x) & 0x1f) << 19) 57#define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16) 58#define PCIE_ATU_UPPER_TARGET 0x91C 59 60#define PCIE_LINK_CAPABILITY 0x7C 61#define PCIE_LINK_CTL_2 0xA0 62#define TARGET_LINK_SPEED_MASK 0xF 63#define LINK_SPEED_GEN_1 0x1 64#define LINK_SPEED_GEN_2 0x2 65#define LINK_SPEED_GEN_3 0x3 66 67#define PCIE_GEN3_RELATED 0x890 68#define GEN3_EQU_DISABLE (1 << 16) 69#define GEN3_ZRXDC_NON_COMP (1 << 0) 70 71#define PCIE_GEN3_EQU_CTRL 0x8A8 72#define GEN3_EQU_EVAL_2MS_DISABLE (1 << 5) 73 74#define PCIE_ROOT_COMPLEX_MODE_MASK (0xF << 4) 75 76#define PCIE_LINK_UP_TIMEOUT_MS 100 77 78#define PCIE_GLOBAL_CONTROL 0x8000 79#define PCIE_APP_LTSSM_EN (1 << 2) 80#define PCIE_DEVICE_TYPE_OFFSET (4) 81#define PCIE_DEVICE_TYPE_MASK (0xF) 82#define PCIE_DEVICE_TYPE_EP (0x0) /* Endpoint */ 83#define PCIE_DEVICE_TYPE_LEP (0x1) /* Legacy endpoint */ 84#define PCIE_DEVICE_TYPE_RC (0x4) /* Root complex */ 85 86#define PCIE_GLOBAL_STATUS 0x8008 87#define PCIE_GLB_STS_RDLH_LINK_UP (1 << 1) 88#define PCIE_GLB_STS_PHY_LINK_UP (1 << 9) 89 90#define PCIE_ARCACHE_TRC 0x8050 91#define PCIE_AWCACHE_TRC 0x8054 92#define ARCACHE_SHAREABLE_CACHEABLE 0x3511 93#define AWCACHE_SHAREABLE_CACHEABLE 0x5311 94 95#define LINK_SPEED_GEN_1 0x1 96#define LINK_SPEED_GEN_2 0x2 97#define LINK_SPEED_GEN_3 0x3 98 99/** 100 * struct pcie_dw_mvebu - MVEBU DW PCIe controller state 101 * 102 * @ctrl_base: The base address of the register space 103 * @cfg_base: The base address of the configuration space 104 * @cfg_size: The size of the configuration space which is needed 105 * as it gets written into the PCIE_ATU_LIMIT register 106 * @first_busno: This driver supports multiple PCIe controllers. 107 * first_busno stores the bus number of the PCIe root-port 108 * number which may vary depending on the PCIe setup 109 * (PEX switches etc). 110 */ 111struct pcie_dw_mvebu { 112 void *ctrl_base; 113 void *cfg_base; 114 fdt_size_t cfg_size; 115 int first_busno; 116 117 /* IO and MEM PCI regions */ 118 int region_count; 119 struct pci_region io; 120 struct pci_region mem; 121}; 122 123static int pcie_dw_get_link_speed(const void *regs_base) 124{ 125 return (readl(regs_base + PCIE_LINK_STATUS_REG) & 126 PCIE_LINK_STATUS_SPEED_MASK) >> PCIE_LINK_STATUS_SPEED_OFF; 127} 128 129static int pcie_dw_get_link_width(const void *regs_base) 130{ 131 return (readl(regs_base + PCIE_LINK_STATUS_REG) & 132 PCIE_LINK_STATUS_WIDTH_MASK) >> PCIE_LINK_STATUS_WIDTH_OFF; 133} 134 135/** 136 * pcie_dw_prog_outbound_atu() - Configure ATU for outbound accesses 137 * 138 * @pcie: Pointer to the PCI controller state 139 * @index: ATU region index 140 * @type: ATU accsess type 141 * @cpu_addr: the physical address for the translation entry 142 * @pci_addr: the pcie bus address for the translation entry 143 * @size: the size of the translation entry 144 */ 145static void pcie_dw_prog_outbound_atu(struct pcie_dw_mvebu *pcie, int index, 146 int type, u64 cpu_addr, u64 pci_addr, 147 u32 size) 148{ 149 writel(PCIE_ATU_REGION_OUTBOUND | index, 150 pcie->ctrl_base + PCIE_ATU_VIEWPORT); 151 writel(lower_32_bits(cpu_addr), pcie->ctrl_base + PCIE_ATU_LOWER_BASE); 152 writel(upper_32_bits(cpu_addr), pcie->ctrl_base + PCIE_ATU_UPPER_BASE); 153 writel(lower_32_bits(cpu_addr + size - 1), 154 pcie->ctrl_base + PCIE_ATU_LIMIT); 155 writel(lower_32_bits(pci_addr), 156 pcie->ctrl_base + PCIE_ATU_LOWER_TARGET); 157 writel(upper_32_bits(pci_addr), 158 pcie->ctrl_base + PCIE_ATU_UPPER_TARGET); 159 writel(type, pcie->ctrl_base + PCIE_ATU_CR1); 160 writel(PCIE_ATU_ENABLE, pcie->ctrl_base + PCIE_ATU_CR2); 161} 162 163/** 164 * set_cfg_address() - Configure the PCIe controller config space access 165 * 166 * @pcie: Pointer to the PCI controller state 167 * @d: PCI device to access 168 * @where: Offset in the configuration space 169 * 170 * Configures the PCIe controller to access the configuration space of 171 * a specific PCIe device and returns the address to use for this 172 * access. 173 * 174 * Return: Address that can be used to access the configation space 175 * of the requested device / offset 176 */ 177static uintptr_t set_cfg_address(struct pcie_dw_mvebu *pcie, 178 pci_dev_t d, uint where) 179{ 180 uintptr_t va_address; 181 u32 atu_type; 182 183 /* 184 * Region #0 is used for Outbound CFG space access. 185 * Direction = Outbound 186 * Region Index = 0 187 */ 188 189 if (PCI_BUS(d) == (pcie->first_busno + 1)) 190 /* For local bus, change TLP Type field to 4. */ 191 atu_type = PCIE_ATU_TYPE_CFG0; 192 else 193 /* Otherwise, change TLP Type field to 5. */ 194 atu_type = PCIE_ATU_TYPE_CFG1; 195 196 if (PCI_BUS(d) == pcie->first_busno) { 197 /* Accessing root port configuration space. */ 198 va_address = (uintptr_t)pcie->ctrl_base; 199 } else { 200 d = PCI_MASK_BUS(d) | (PCI_BUS(d) - pcie->first_busno); 201 pcie_dw_prog_outbound_atu(pcie, PCIE_ATU_REGION_INDEX0, 202 atu_type, (u64)pcie->cfg_base, 203 d << 8, pcie->cfg_size); 204 va_address = (uintptr_t)pcie->cfg_base; 205 } 206 207 va_address += where & ~0x3; 208 209 return va_address; 210} 211 212/** 213 * pcie_dw_addr_valid() - Check for valid bus address 214 * 215 * @d: The PCI device to access 216 * @first_busno: Bus number of the PCIe controller root complex 217 * 218 * Return 1 (true) if the PCI device can be accessed by this controller. 219 * 220 * Return: 1 on valid, 0 on invalid 221 */ 222static int pcie_dw_addr_valid(pci_dev_t d, int first_busno) 223{ 224 if ((PCI_BUS(d) == first_busno) && (PCI_DEV(d) > 0)) 225 return 0; 226 if ((PCI_BUS(d) == first_busno + 1) && (PCI_DEV(d) > 0)) 227 return 0; 228 229 return 1; 230} 231 232/** 233 * pcie_dw_mvebu_read_config() - Read from configuration space 234 * 235 * @bus: Pointer to the PCI bus 236 * @bdf: Identifies the PCIe device to access 237 * @offset: The offset into the device's configuration space 238 * @valuep: A pointer at which to store the read value 239 * @size: Indicates the size of access to perform 240 * 241 * Read a value of size @size from offset @offset within the configuration 242 * space of the device identified by the bus, device & function numbers in @bdf 243 * on the PCI bus @bus. 244 * 245 * Return: 0 on success 246 */ 247static int pcie_dw_mvebu_read_config(const struct udevice *bus, pci_dev_t bdf, 248 uint offset, ulong *valuep, 249 enum pci_size_t size) 250{ 251 struct pcie_dw_mvebu *pcie = dev_get_priv(bus); 252 uintptr_t va_address; 253 ulong value; 254 255 debug("PCIE CFG read: (b,d,f)=(%2d,%2d,%2d) ", 256 PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf)); 257 258 if (!pcie_dw_addr_valid(bdf, pcie->first_busno)) { 259 debug("- out of range\n"); 260 *valuep = pci_get_ff(size); 261 return 0; 262 } 263 264 va_address = set_cfg_address(pcie, bdf, offset); 265 266 value = readl(va_address); 267 268 debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, value); 269 *valuep = pci_conv_32_to_size(value, offset, size); 270 271 if (pcie->region_count > 1) 272 pcie_dw_prog_outbound_atu(pcie, PCIE_ATU_REGION_INDEX0, 273 PCIE_ATU_TYPE_IO, pcie->io.phys_start, 274 pcie->io.bus_start, pcie->io.size); 275 276 return 0; 277} 278 279/** 280 * pcie_dw_mvebu_write_config() - Write to configuration space 281 * 282 * @bus: Pointer to the PCI bus 283 * @bdf: Identifies the PCIe device to access 284 * @offset: The offset into the device's configuration space 285 * @value: The value to write 286 * @size: Indicates the size of access to perform 287 * 288 * Write the value @value of size @size from offset @offset within the 289 * configuration space of the device identified by the bus, device & function 290 * numbers in @bdf on the PCI bus @bus. 291 * 292 * Return: 0 on success 293 */ 294static int pcie_dw_mvebu_write_config(struct udevice *bus, pci_dev_t bdf, 295 uint offset, ulong value, 296 enum pci_size_t size) 297{ 298 struct pcie_dw_mvebu *pcie = dev_get_priv(bus); 299 uintptr_t va_address; 300 ulong old; 301 302 debug("PCIE CFG write: (b,d,f)=(%2d,%2d,%2d) ", 303 PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf)); 304 debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, value); 305 306 if (!pcie_dw_addr_valid(bdf, pcie->first_busno)) { 307 debug("- out of range\n"); 308 return 0; 309 } 310 311 va_address = set_cfg_address(pcie, bdf, offset); 312 313 old = readl(va_address); 314 value = pci_conv_size_to_32(old, value, offset, size); 315 writel(value, va_address); 316 317 if (pcie->region_count > 1) 318 pcie_dw_prog_outbound_atu(pcie, PCIE_ATU_REGION_INDEX0, 319 PCIE_ATU_TYPE_IO, pcie->io.phys_start, 320 pcie->io.bus_start, pcie->io.size); 321 322 return 0; 323} 324 325/** 326 * pcie_dw_configure() - Configure link capabilities and speed 327 * 328 * @regs_base: A pointer to the PCIe controller registers 329 * @cap_speed: The capabilities and speed to configure 330 * 331 * Configure the link capabilities and speed in the PCIe root complex. 332 */ 333static void pcie_dw_configure(const void *regs_base, u32 cap_speed) 334{ 335 /* 336 * TODO (shadi@marvell.com, sr@denx.de): 337 * Need to read the serdes speed from the dts and according to it 338 * configure the PCIe gen 339 */ 340 341 /* Set link to GEN 3 */ 342 clrsetbits_le32(regs_base + PCIE_LINK_CTL_2, 343 TARGET_LINK_SPEED_MASK, cap_speed); 344 clrsetbits_le32(regs_base + PCIE_LINK_CAPABILITY, 345 TARGET_LINK_SPEED_MASK, cap_speed); 346 setbits_le32(regs_base + PCIE_GEN3_EQU_CTRL, GEN3_EQU_EVAL_2MS_DISABLE); 347} 348 349/** 350 * is_link_up() - Return the link state 351 * 352 * @regs_base: A pointer to the PCIe controller registers 353 * 354 * Return: 1 (true) for active line and 0 (false) for no link 355 */ 356static int is_link_up(const void *regs_base) 357{ 358 u32 mask = PCIE_GLB_STS_RDLH_LINK_UP | PCIE_GLB_STS_PHY_LINK_UP; 359 u32 reg; 360 361 reg = readl(regs_base + PCIE_GLOBAL_STATUS); 362 if ((reg & mask) == mask) 363 return 1; 364 365 return 0; 366} 367 368/** 369 * wait_link_up() - Wait for the link to come up 370 * 371 * @regs_base: A pointer to the PCIe controller registers 372 * 373 * Return: 1 (true) for active line and 0 (false) for no link (timeout) 374 */ 375static int wait_link_up(const void *regs_base) 376{ 377 unsigned long timeout; 378 379 timeout = get_timer(0) + PCIE_LINK_UP_TIMEOUT_MS; 380 while (!is_link_up(regs_base)) { 381 if (get_timer(0) > timeout) 382 return 0; 383 }; 384 385 return 1; 386} 387 388/** 389 * pcie_dw_mvebu_pcie_link_up() - Configure the PCIe root port 390 * 391 * @regs_base: A pointer to the PCIe controller registers 392 * @cap_speed: The capabilities and speed to configure 393 * 394 * Configure the PCIe controller root complex depending on the 395 * requested link capabilities and speed. 396 * 397 * Return: 1 (true) for active line and 0 (false) for no link 398 */ 399static int pcie_dw_mvebu_pcie_link_up(const void *regs_base, u32 cap_speed) 400{ 401 if (!is_link_up(regs_base)) { 402 /* Disable LTSSM state machine to enable configuration */ 403 clrbits_le32(regs_base + PCIE_GLOBAL_CONTROL, 404 PCIE_APP_LTSSM_EN); 405 } 406 407 clrsetbits_le32(regs_base + PCIE_GLOBAL_CONTROL, 408 PCIE_DEVICE_TYPE_MASK << PCIE_DEVICE_TYPE_OFFSET, 409 PCIE_DEVICE_TYPE_RC << PCIE_DEVICE_TYPE_OFFSET); 410 411 /* Set the PCIe master AXI attributes */ 412 writel(ARCACHE_SHAREABLE_CACHEABLE, regs_base + PCIE_ARCACHE_TRC); 413 writel(AWCACHE_SHAREABLE_CACHEABLE, regs_base + PCIE_AWCACHE_TRC); 414 415 /* DW pre link configurations */ 416 pcie_dw_configure(regs_base, cap_speed); 417 418 if (!is_link_up(regs_base)) { 419 /* Configuration done. Start LTSSM */ 420 setbits_le32(regs_base + PCIE_GLOBAL_CONTROL, 421 PCIE_APP_LTSSM_EN); 422 } 423 424 /* Check that link was established */ 425 if (!wait_link_up(regs_base)) 426 return 0; 427 428 /* 429 * Link can be established in Gen 1. still need to wait 430 * till MAC nagaotiation is completed 431 */ 432 udelay(100); 433 434 return 1; 435} 436 437/** 438 * pcie_dw_set_host_bars() - Configure the host BARs 439 * 440 * @regs_base: A pointer to the PCIe controller registers 441 * 442 * Configure the host BARs of the PCIe controller root port so that 443 * PCI(e) devices may access the system memory. 444 */ 445static void pcie_dw_set_host_bars(const void *regs_base) 446{ 447 u32 size = gd->ram_size; 448 u64 max_size; 449 u32 reg; 450 u32 bar0; 451 452 /* Verify the maximal BAR size */ 453 reg = readl(regs_base + RESIZABLE_BAR_CAP); 454 max_size = 1ULL << (5 + (reg + (1 << 4))); 455 456 if (size > max_size) { 457 size = max_size; 458 printf("Warning: PCIe BARs can't map all DRAM space\n"); 459 } 460 461 /* Set the BAR base and size towards DDR */ 462 bar0 = CFG_SYS_SDRAM_BASE & ~0xf; 463 bar0 |= PCI_BASE_ADDRESS_MEM_TYPE_32; 464 writel(CFG_SYS_SDRAM_BASE, regs_base + PCIE_CONFIG_BAR0); 465 466 reg = ((size >> 20) - 1) << 12; 467 writel(size, regs_base + RESIZABLE_BAR_CTL0); 468} 469 470/** 471 * pcie_dw_mvebu_probe() - Probe the PCIe bus for active link 472 * 473 * @dev: A pointer to the device being operated on 474 * 475 * Probe for an active link on the PCIe bus and configure the controller 476 * to enable this port. 477 * 478 * Return: 0 on success, else -ENODEV 479 */ 480static int pcie_dw_mvebu_probe(struct udevice *dev) 481{ 482 struct pcie_dw_mvebu *pcie = dev_get_priv(dev); 483 struct udevice *ctlr = pci_get_controller(dev); 484 struct pci_controller *hose = dev_get_uclass_priv(ctlr); 485#if CONFIG_IS_ENABLED(DM_GPIO) 486 struct gpio_desc reset_gpio; 487 488 gpio_request_by_name(dev, "marvell,reset-gpio", 0, &reset_gpio, 489 GPIOD_IS_OUT); 490 /* 491 * Issue reset to add-in card trough the dedicated GPIO. 492 * Some boards are connecting the card reset pin to common system 493 * reset wire and others are using separate GPIO port. 494 * In the last case we have to release a reset of the addon card 495 * using this GPIO. 496 */ 497 if (dm_gpio_is_valid(&reset_gpio)) { 498 dm_gpio_set_value(&reset_gpio, 1); /* assert */ 499 mdelay(200); 500 dm_gpio_set_value(&reset_gpio, 0); /* de-assert */ 501 mdelay(200); 502 } 503#else 504 debug("PCIE Reset on GPIO support is missing\n"); 505#endif /* DM_GPIO */ 506 507 pcie->first_busno = dev_seq(dev); 508 509 /* Don't register host if link is down */ 510 if (!pcie_dw_mvebu_pcie_link_up(pcie->ctrl_base, LINK_SPEED_GEN_3)) { 511 printf("PCIE-%d: Link down\n", dev_seq(dev)); 512 } else { 513 printf("PCIE-%d: Link up (Gen%d-x%d, Bus%d)\n", dev_seq(dev), 514 pcie_dw_get_link_speed(pcie->ctrl_base), 515 pcie_dw_get_link_width(pcie->ctrl_base), 516 hose->first_busno); 517 } 518 519 pcie->region_count = hose->region_count - CONFIG_NR_DRAM_BANKS; 520 521 /* Store the IO and MEM windows settings for future use by the ATU */ 522 if (pcie->region_count > 1) { 523 /* IO base */ 524 pcie->io.phys_start = hose->regions[0].phys_start; 525 /* IO_bus_addr */ 526 pcie->io.bus_start = hose->regions[0].bus_start; 527 /* IO size */ 528 pcie->io.size = hose->regions[0].size; 529 } 530 531 /* MEM base */ 532 pcie->mem.phys_start = hose->regions[pcie->region_count - 1].phys_start; 533 /* MEM_bus_addr */ 534 pcie->mem.bus_start = hose->regions[pcie->region_count - 1].bus_start; 535 /* MEM size */ 536 pcie->mem.size = hose->regions[pcie->region_count - 1].size; 537 538 pcie_dw_prog_outbound_atu(pcie, PCIE_ATU_REGION_INDEX1, 539 PCIE_ATU_TYPE_MEM, pcie->mem.phys_start, 540 pcie->mem.bus_start, pcie->mem.size); 541 542 /* Set the CLASS_REV of RC CFG header to PCI_CLASS_BRIDGE_PCI_NORMAL */ 543 clrsetbits_le32(pcie->ctrl_base + PCI_CLASS_REVISION, 544 0xffffff << 8, PCI_CLASS_BRIDGE_PCI_NORMAL << 8); 545 546 pcie_dw_set_host_bars(pcie->ctrl_base); 547 548 return 0; 549} 550 551/** 552 * pcie_dw_mvebu_of_to_plat() - Translate from DT to device state 553 * 554 * @dev: A pointer to the device being operated on 555 * 556 * Translate relevant data from the device tree pertaining to device @dev into 557 * state that the driver will later make use of. This state is stored in the 558 * device's private data structure. 559 * 560 * Return: 0 on success, else -EINVAL 561 */ 562static int pcie_dw_mvebu_of_to_plat(struct udevice *dev) 563{ 564 struct pcie_dw_mvebu *pcie = dev_get_priv(dev); 565 566 /* Get the controller base address */ 567 pcie->ctrl_base = devfdt_get_addr_index_ptr(dev, 0); 568 if (!pcie->ctrl_base) 569 return -EINVAL; 570 571 /* Get the config space base address and size */ 572 pcie->cfg_base = devfdt_get_addr_size_index_ptr(dev, 1, 573 &pcie->cfg_size); 574 if (!pcie->cfg_base) 575 return -EINVAL; 576 577 return 0; 578} 579 580static const struct dm_pci_ops pcie_dw_mvebu_ops = { 581 .read_config = pcie_dw_mvebu_read_config, 582 .write_config = pcie_dw_mvebu_write_config, 583}; 584 585static const struct udevice_id pcie_dw_mvebu_ids[] = { 586 { .compatible = "marvell,armada8k-pcie" }, 587 { } 588}; 589 590U_BOOT_DRIVER(pcie_dw_mvebu) = { 591 .name = "pcie_dw_mvebu", 592 .id = UCLASS_PCI, 593 .of_match = pcie_dw_mvebu_ids, 594 .ops = &pcie_dw_mvebu_ops, 595 .of_to_plat = pcie_dw_mvebu_of_to_plat, 596 .probe = pcie_dw_mvebu_probe, 597 .priv_auto = sizeof(struct pcie_dw_mvebu), 598}; 599