1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * PCIe host controller driver for Axis ARTPEC-6 SoC 4 * 5 * Author: Niklas Cassel <niklas.cassel@axis.com> 6 * 7 * Based on work done by Phil Edworthy <phil@edworthys.org> 8 */ 9 10 #include <linux/delay.h> 11 #include <linux/kernel.h> 12 #include <linux/init.h> 13 #include <linux/of_device.h> 14 #include <linux/pci.h> 15 #include <linux/platform_device.h> 16 #include <linux/resource.h> 17 #include <linux/signal.h> 18 #include <linux/types.h> 19 #include <linux/interrupt.h> 20 #include <linux/mfd/syscon.h> 21 #include <linux/regmap.h> 22 23 #include "pcie-designware.h" 24 25 #define to_artpec6_pcie(x) dev_get_drvdata((x)->dev) 26 27 enum artpec_pcie_variants { 28 ARTPEC6, 29 ARTPEC7, 30 }; 31 32 struct artpec6_pcie { 33 struct dw_pcie *pci; 34 struct regmap *regmap; /* DT axis,syscon-pcie */ 35 void __iomem *phy_base; /* DT phy */ 36 enum artpec_pcie_variants variant; 37 enum dw_pcie_device_mode mode; 38 }; 39 40 struct artpec_pcie_of_data { 41 enum artpec_pcie_variants variant; 42 enum dw_pcie_device_mode mode; 43 }; 44 45 static const struct of_device_id artpec6_pcie_of_match[]; 46 47 /* ARTPEC-6 specific registers */ 48 #define PCIECFG 0x18 49 #define PCIECFG_DBG_OEN BIT(24) 50 #define PCIECFG_CORE_RESET_REQ BIT(21) 51 #define PCIECFG_LTSSM_ENABLE BIT(20) 52 #define PCIECFG_DEVICE_TYPE_MASK GENMASK(19, 16) 53 #define PCIECFG_CLKREQ_B BIT(11) 54 #define PCIECFG_REFCLK_ENABLE BIT(10) 55 #define PCIECFG_PLL_ENABLE BIT(9) 56 #define PCIECFG_PCLK_ENABLE BIT(8) 57 #define PCIECFG_RISRCREN BIT(4) 58 #define PCIECFG_MODE_TX_DRV_EN BIT(3) 59 #define PCIECFG_CISRREN BIT(2) 60 #define PCIECFG_MACRO_ENABLE BIT(0) 61 /* ARTPEC-7 specific fields */ 62 #define PCIECFG_REFCLKSEL BIT(23) 63 #define PCIECFG_NOC_RESET BIT(3) 64 65 #define PCIESTAT 0x1c 66 /* ARTPEC-7 specific fields */ 67 #define PCIESTAT_EXTREFCLK BIT(3) 68 69 #define NOCCFG 0x40 70 #define NOCCFG_ENABLE_CLK_PCIE BIT(4) 71 #define NOCCFG_POWER_PCIE_IDLEACK BIT(3) 72 #define NOCCFG_POWER_PCIE_IDLE BIT(2) 73 #define NOCCFG_POWER_PCIE_IDLEREQ BIT(1) 74 75 #define PHY_STATUS 0x118 76 #define PHY_COSPLLLOCK BIT(0) 77 78 #define PHY_TX_ASIC_OUT 0x4040 79 #define PHY_TX_ASIC_OUT_TX_ACK BIT(0) 80 81 #define PHY_RX_ASIC_OUT 0x405c 82 #define PHY_RX_ASIC_OUT_ACK BIT(0) 83 84 static u32 artpec6_pcie_readl(struct artpec6_pcie *artpec6_pcie, u32 offset) 85 { 86 u32 val; 87 88 regmap_read(artpec6_pcie->regmap, offset, &val); 89 return val; 90 } 91 92 static void artpec6_pcie_writel(struct artpec6_pcie *artpec6_pcie, u32 offset, u32 val) 93 { 94 regmap_write(artpec6_pcie->regmap, offset, val); 95 } 96 97 static u64 artpec6_pcie_cpu_addr_fixup(struct dw_pcie *pci, u64 pci_addr) 98 { 99 struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci); 100 struct pcie_port *pp = &pci->pp; 101 struct dw_pcie_ep *ep = &pci->ep; 102 103 switch (artpec6_pcie->mode) { 104 case DW_PCIE_RC_TYPE: 105 return pci_addr - pp->cfg0_base; 106 case DW_PCIE_EP_TYPE: 107 return pci_addr - ep->phys_base; 108 default: 109 dev_err(pci->dev, "UNKNOWN device type\n"); 110 } 111 return pci_addr; 112 } 113 114 static int artpec6_pcie_establish_link(struct dw_pcie *pci) 115 { 116 struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci); 117 u32 val; 118 119 val = artpec6_pcie_readl(artpec6_pcie, PCIECFG); 120 val |= PCIECFG_LTSSM_ENABLE; 121 artpec6_pcie_writel(artpec6_pcie, PCIECFG, val); 122 123 return 0; 124 } 125 126 static void artpec6_pcie_stop_link(struct dw_pcie *pci) 127 { 128 struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci); 129 u32 val; 130 131 val = artpec6_pcie_readl(artpec6_pcie, PCIECFG); 132 val &= ~PCIECFG_LTSSM_ENABLE; 133 artpec6_pcie_writel(artpec6_pcie, PCIECFG, val); 134 } 135 136 static const struct dw_pcie_ops dw_pcie_ops = { 137 .cpu_addr_fixup = artpec6_pcie_cpu_addr_fixup, 138 .start_link = artpec6_pcie_establish_link, 139 .stop_link = artpec6_pcie_stop_link, 140 }; 141 142 static void artpec6_pcie_wait_for_phy_a6(struct artpec6_pcie *artpec6_pcie) 143 { 144 struct dw_pcie *pci = artpec6_pcie->pci; 145 struct device *dev = pci->dev; 146 u32 val; 147 unsigned int retries; 148 149 retries = 50; 150 do { 151 usleep_range(1000, 2000); 152 val = artpec6_pcie_readl(artpec6_pcie, NOCCFG); 153 retries--; 154 } while (retries && 155 (val & (NOCCFG_POWER_PCIE_IDLEACK | NOCCFG_POWER_PCIE_IDLE))); 156 if (!retries) 157 dev_err(dev, "PCIe clock manager did not leave idle state\n"); 158 159 retries = 50; 160 do { 161 usleep_range(1000, 2000); 162 val = readl(artpec6_pcie->phy_base + PHY_STATUS); 163 retries--; 164 } while (retries && !(val & PHY_COSPLLLOCK)); 165 if (!retries) 166 dev_err(dev, "PHY PLL did not lock\n"); 167 } 168 169 static void artpec6_pcie_wait_for_phy_a7(struct artpec6_pcie *artpec6_pcie) 170 { 171 struct dw_pcie *pci = artpec6_pcie->pci; 172 struct device *dev = pci->dev; 173 u32 val; 174 u16 phy_status_tx, phy_status_rx; 175 unsigned int retries; 176 177 retries = 50; 178 do { 179 usleep_range(1000, 2000); 180 val = artpec6_pcie_readl(artpec6_pcie, NOCCFG); 181 retries--; 182 } while (retries && 183 (val & (NOCCFG_POWER_PCIE_IDLEACK | NOCCFG_POWER_PCIE_IDLE))); 184 if (!retries) 185 dev_err(dev, "PCIe clock manager did not leave idle state\n"); 186 187 retries = 50; 188 do { 189 usleep_range(1000, 2000); 190 phy_status_tx = readw(artpec6_pcie->phy_base + PHY_TX_ASIC_OUT); 191 phy_status_rx = readw(artpec6_pcie->phy_base + PHY_RX_ASIC_OUT); 192 retries--; 193 } while (retries && ((phy_status_tx & PHY_TX_ASIC_OUT_TX_ACK) || 194 (phy_status_rx & PHY_RX_ASIC_OUT_ACK))); 195 if (!retries) 196 dev_err(dev, "PHY did not enter Pn state\n"); 197 } 198 199 static void artpec6_pcie_wait_for_phy(struct artpec6_pcie *artpec6_pcie) 200 { 201 switch (artpec6_pcie->variant) { 202 case ARTPEC6: 203 artpec6_pcie_wait_for_phy_a6(artpec6_pcie); 204 break; 205 case ARTPEC7: 206 artpec6_pcie_wait_for_phy_a7(artpec6_pcie); 207 break; 208 } 209 } 210 211 static void artpec6_pcie_init_phy_a6(struct artpec6_pcie *artpec6_pcie) 212 { 213 u32 val; 214 215 val = artpec6_pcie_readl(artpec6_pcie, PCIECFG); 216 val |= PCIECFG_RISRCREN | /* Receiver term. 50 Ohm */ 217 PCIECFG_MODE_TX_DRV_EN | 218 PCIECFG_CISRREN | /* Reference clock term. 100 Ohm */ 219 PCIECFG_MACRO_ENABLE; 220 val |= PCIECFG_REFCLK_ENABLE; 221 val &= ~PCIECFG_DBG_OEN; 222 val &= ~PCIECFG_CLKREQ_B; 223 artpec6_pcie_writel(artpec6_pcie, PCIECFG, val); 224 usleep_range(5000, 6000); 225 226 val = artpec6_pcie_readl(artpec6_pcie, NOCCFG); 227 val |= NOCCFG_ENABLE_CLK_PCIE; 228 artpec6_pcie_writel(artpec6_pcie, NOCCFG, val); 229 usleep_range(20, 30); 230 231 val = artpec6_pcie_readl(artpec6_pcie, PCIECFG); 232 val |= PCIECFG_PCLK_ENABLE | PCIECFG_PLL_ENABLE; 233 artpec6_pcie_writel(artpec6_pcie, PCIECFG, val); 234 usleep_range(6000, 7000); 235 236 val = artpec6_pcie_readl(artpec6_pcie, NOCCFG); 237 val &= ~NOCCFG_POWER_PCIE_IDLEREQ; 238 artpec6_pcie_writel(artpec6_pcie, NOCCFG, val); 239 } 240 241 static void artpec6_pcie_init_phy_a7(struct artpec6_pcie *artpec6_pcie) 242 { 243 struct dw_pcie *pci = artpec6_pcie->pci; 244 u32 val; 245 bool extrefclk; 246 247 /* Check if external reference clock is connected */ 248 val = artpec6_pcie_readl(artpec6_pcie, PCIESTAT); 249 extrefclk = !!(val & PCIESTAT_EXTREFCLK); 250 dev_dbg(pci->dev, "Using reference clock: %s\n", 251 extrefclk ? "external" : "internal"); 252 253 val = artpec6_pcie_readl(artpec6_pcie, PCIECFG); 254 val |= PCIECFG_RISRCREN | /* Receiver term. 50 Ohm */ 255 PCIECFG_PCLK_ENABLE; 256 if (extrefclk) 257 val |= PCIECFG_REFCLKSEL; 258 else 259 val &= ~PCIECFG_REFCLKSEL; 260 artpec6_pcie_writel(artpec6_pcie, PCIECFG, val); 261 usleep_range(10, 20); 262 263 val = artpec6_pcie_readl(artpec6_pcie, NOCCFG); 264 val |= NOCCFG_ENABLE_CLK_PCIE; 265 artpec6_pcie_writel(artpec6_pcie, NOCCFG, val); 266 usleep_range(20, 30); 267 268 val = artpec6_pcie_readl(artpec6_pcie, NOCCFG); 269 val &= ~NOCCFG_POWER_PCIE_IDLEREQ; 270 artpec6_pcie_writel(artpec6_pcie, NOCCFG, val); 271 } 272 273 static void artpec6_pcie_init_phy(struct artpec6_pcie *artpec6_pcie) 274 { 275 switch (artpec6_pcie->variant) { 276 case ARTPEC6: 277 artpec6_pcie_init_phy_a6(artpec6_pcie); 278 break; 279 case ARTPEC7: 280 artpec6_pcie_init_phy_a7(artpec6_pcie); 281 break; 282 } 283 } 284 285 static void artpec6_pcie_assert_core_reset(struct artpec6_pcie *artpec6_pcie) 286 { 287 u32 val; 288 289 val = artpec6_pcie_readl(artpec6_pcie, PCIECFG); 290 switch (artpec6_pcie->variant) { 291 case ARTPEC6: 292 val |= PCIECFG_CORE_RESET_REQ; 293 break; 294 case ARTPEC7: 295 val &= ~PCIECFG_NOC_RESET; 296 break; 297 } 298 artpec6_pcie_writel(artpec6_pcie, PCIECFG, val); 299 } 300 301 static void artpec6_pcie_deassert_core_reset(struct artpec6_pcie *artpec6_pcie) 302 { 303 u32 val; 304 305 val = artpec6_pcie_readl(artpec6_pcie, PCIECFG); 306 switch (artpec6_pcie->variant) { 307 case ARTPEC6: 308 val &= ~PCIECFG_CORE_RESET_REQ; 309 break; 310 case ARTPEC7: 311 val |= PCIECFG_NOC_RESET; 312 break; 313 } 314 artpec6_pcie_writel(artpec6_pcie, PCIECFG, val); 315 usleep_range(100, 200); 316 } 317 318 static int artpec6_pcie_host_init(struct pcie_port *pp) 319 { 320 struct dw_pcie *pci = to_dw_pcie_from_pp(pp); 321 struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci); 322 323 if (artpec6_pcie->variant == ARTPEC7) { 324 pci->n_fts[0] = 180; 325 pci->n_fts[1] = 180; 326 } 327 artpec6_pcie_assert_core_reset(artpec6_pcie); 328 artpec6_pcie_init_phy(artpec6_pcie); 329 artpec6_pcie_deassert_core_reset(artpec6_pcie); 330 artpec6_pcie_wait_for_phy(artpec6_pcie); 331 dw_pcie_setup_rc(pp); 332 artpec6_pcie_establish_link(pci); 333 dw_pcie_wait_for_link(pci); 334 dw_pcie_msi_init(pp); 335 336 return 0; 337 } 338 339 static const struct dw_pcie_host_ops artpec6_pcie_host_ops = { 340 .host_init = artpec6_pcie_host_init, 341 }; 342 343 static int artpec6_add_pcie_port(struct artpec6_pcie *artpec6_pcie, 344 struct platform_device *pdev) 345 { 346 struct dw_pcie *pci = artpec6_pcie->pci; 347 struct pcie_port *pp = &pci->pp; 348 struct device *dev = pci->dev; 349 int ret; 350 351 if (IS_ENABLED(CONFIG_PCI_MSI)) { 352 pp->msi_irq = platform_get_irq_byname(pdev, "msi"); 353 if (pp->msi_irq < 0) 354 return pp->msi_irq; 355 } 356 357 pp->ops = &artpec6_pcie_host_ops; 358 359 ret = dw_pcie_host_init(pp); 360 if (ret) { 361 dev_err(dev, "failed to initialize host\n"); 362 return ret; 363 } 364 365 return 0; 366 } 367 368 static void artpec6_pcie_ep_init(struct dw_pcie_ep *ep) 369 { 370 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 371 struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci); 372 enum pci_barno bar; 373 374 artpec6_pcie_assert_core_reset(artpec6_pcie); 375 artpec6_pcie_init_phy(artpec6_pcie); 376 artpec6_pcie_deassert_core_reset(artpec6_pcie); 377 artpec6_pcie_wait_for_phy(artpec6_pcie); 378 379 for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) 380 dw_pcie_ep_reset_bar(pci, bar); 381 } 382 383 static int artpec6_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no, 384 enum pci_epc_irq_type type, u16 interrupt_num) 385 { 386 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 387 388 switch (type) { 389 case PCI_EPC_IRQ_LEGACY: 390 dev_err(pci->dev, "EP cannot trigger legacy IRQs\n"); 391 return -EINVAL; 392 case PCI_EPC_IRQ_MSI: 393 return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num); 394 default: 395 dev_err(pci->dev, "UNKNOWN IRQ type\n"); 396 } 397 398 return 0; 399 } 400 401 static const struct dw_pcie_ep_ops pcie_ep_ops = { 402 .ep_init = artpec6_pcie_ep_init, 403 .raise_irq = artpec6_pcie_raise_irq, 404 }; 405 406 static int artpec6_add_pcie_ep(struct artpec6_pcie *artpec6_pcie, 407 struct platform_device *pdev) 408 { 409 int ret; 410 struct dw_pcie_ep *ep; 411 struct resource *res; 412 struct device *dev = &pdev->dev; 413 struct dw_pcie *pci = artpec6_pcie->pci; 414 415 ep = &pci->ep; 416 ep->ops = &pcie_ep_ops; 417 418 pci->dbi_base2 = devm_platform_ioremap_resource_byname(pdev, "dbi2"); 419 if (IS_ERR(pci->dbi_base2)) 420 return PTR_ERR(pci->dbi_base2); 421 422 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space"); 423 if (!res) 424 return -EINVAL; 425 426 ep->phys_base = res->start; 427 ep->addr_size = resource_size(res); 428 429 ret = dw_pcie_ep_init(ep); 430 if (ret) { 431 dev_err(dev, "failed to initialize endpoint\n"); 432 return ret; 433 } 434 435 return 0; 436 } 437 438 static int artpec6_pcie_probe(struct platform_device *pdev) 439 { 440 struct device *dev = &pdev->dev; 441 struct dw_pcie *pci; 442 struct artpec6_pcie *artpec6_pcie; 443 int ret; 444 const struct of_device_id *match; 445 const struct artpec_pcie_of_data *data; 446 enum artpec_pcie_variants variant; 447 enum dw_pcie_device_mode mode; 448 449 match = of_match_device(artpec6_pcie_of_match, dev); 450 if (!match) 451 return -EINVAL; 452 453 data = (struct artpec_pcie_of_data *)match->data; 454 variant = (enum artpec_pcie_variants)data->variant; 455 mode = (enum dw_pcie_device_mode)data->mode; 456 457 artpec6_pcie = devm_kzalloc(dev, sizeof(*artpec6_pcie), GFP_KERNEL); 458 if (!artpec6_pcie) 459 return -ENOMEM; 460 461 pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL); 462 if (!pci) 463 return -ENOMEM; 464 465 pci->dev = dev; 466 pci->ops = &dw_pcie_ops; 467 468 artpec6_pcie->pci = pci; 469 artpec6_pcie->variant = variant; 470 artpec6_pcie->mode = mode; 471 472 pci->dbi_base = devm_platform_ioremap_resource_byname(pdev, "dbi"); 473 if (IS_ERR(pci->dbi_base)) 474 return PTR_ERR(pci->dbi_base); 475 476 artpec6_pcie->phy_base = 477 devm_platform_ioremap_resource_byname(pdev, "phy"); 478 if (IS_ERR(artpec6_pcie->phy_base)) 479 return PTR_ERR(artpec6_pcie->phy_base); 480 481 artpec6_pcie->regmap = 482 syscon_regmap_lookup_by_phandle(dev->of_node, 483 "axis,syscon-pcie"); 484 if (IS_ERR(artpec6_pcie->regmap)) 485 return PTR_ERR(artpec6_pcie->regmap); 486 487 platform_set_drvdata(pdev, artpec6_pcie); 488 489 switch (artpec6_pcie->mode) { 490 case DW_PCIE_RC_TYPE: 491 if (!IS_ENABLED(CONFIG_PCIE_ARTPEC6_HOST)) 492 return -ENODEV; 493 494 ret = artpec6_add_pcie_port(artpec6_pcie, pdev); 495 if (ret < 0) 496 return ret; 497 break; 498 case DW_PCIE_EP_TYPE: { 499 u32 val; 500 501 if (!IS_ENABLED(CONFIG_PCIE_ARTPEC6_EP)) 502 return -ENODEV; 503 504 val = artpec6_pcie_readl(artpec6_pcie, PCIECFG); 505 val &= ~PCIECFG_DEVICE_TYPE_MASK; 506 artpec6_pcie_writel(artpec6_pcie, PCIECFG, val); 507 ret = artpec6_add_pcie_ep(artpec6_pcie, pdev); 508 if (ret < 0) 509 return ret; 510 break; 511 } 512 default: 513 dev_err(dev, "INVALID device type %d\n", artpec6_pcie->mode); 514 } 515 516 return 0; 517 } 518 519 static const struct artpec_pcie_of_data artpec6_pcie_rc_of_data = { 520 .variant = ARTPEC6, 521 .mode = DW_PCIE_RC_TYPE, 522 }; 523 524 static const struct artpec_pcie_of_data artpec6_pcie_ep_of_data = { 525 .variant = ARTPEC6, 526 .mode = DW_PCIE_EP_TYPE, 527 }; 528 529 static const struct artpec_pcie_of_data artpec7_pcie_rc_of_data = { 530 .variant = ARTPEC7, 531 .mode = DW_PCIE_RC_TYPE, 532 }; 533 534 static const struct artpec_pcie_of_data artpec7_pcie_ep_of_data = { 535 .variant = ARTPEC7, 536 .mode = DW_PCIE_EP_TYPE, 537 }; 538 539 static const struct of_device_id artpec6_pcie_of_match[] = { 540 { 541 .compatible = "axis,artpec6-pcie", 542 .data = &artpec6_pcie_rc_of_data, 543 }, 544 { 545 .compatible = "axis,artpec6-pcie-ep", 546 .data = &artpec6_pcie_ep_of_data, 547 }, 548 { 549 .compatible = "axis,artpec7-pcie", 550 .data = &artpec7_pcie_rc_of_data, 551 }, 552 { 553 .compatible = "axis,artpec7-pcie-ep", 554 .data = &artpec7_pcie_ep_of_data, 555 }, 556 {}, 557 }; 558 559 static struct platform_driver artpec6_pcie_driver = { 560 .probe = artpec6_pcie_probe, 561 .driver = { 562 .name = "artpec6-pcie", 563 .of_match_table = artpec6_pcie_of_match, 564 .suppress_bind_attrs = true, 565 }, 566 }; 567 builtin_platform_driver(artpec6_pcie_driver); 568