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.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 dw_pcie_rp *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 dw_pcie_rp *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 332 return 0; 333 } 334 335 static const struct dw_pcie_host_ops artpec6_pcie_host_ops = { 336 .init = artpec6_pcie_host_init, 337 }; 338 339 static void artpec6_pcie_ep_init(struct dw_pcie_ep *ep) 340 { 341 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 342 struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci); 343 enum pci_barno bar; 344 345 artpec6_pcie_assert_core_reset(artpec6_pcie); 346 artpec6_pcie_init_phy(artpec6_pcie); 347 artpec6_pcie_deassert_core_reset(artpec6_pcie); 348 artpec6_pcie_wait_for_phy(artpec6_pcie); 349 350 for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) 351 dw_pcie_ep_reset_bar(pci, bar); 352 } 353 354 static int artpec6_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no, 355 unsigned int type, u16 interrupt_num) 356 { 357 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 358 359 switch (type) { 360 case PCI_IRQ_INTX: 361 dev_err(pci->dev, "EP cannot trigger INTx IRQs\n"); 362 return -EINVAL; 363 case PCI_IRQ_MSI: 364 return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num); 365 default: 366 dev_err(pci->dev, "UNKNOWN IRQ type\n"); 367 } 368 369 return 0; 370 } 371 372 static const struct dw_pcie_ep_ops pcie_ep_ops = { 373 .init = artpec6_pcie_ep_init, 374 .raise_irq = artpec6_pcie_raise_irq, 375 }; 376 377 static int artpec6_pcie_probe(struct platform_device *pdev) 378 { 379 struct device *dev = &pdev->dev; 380 struct dw_pcie *pci; 381 struct artpec6_pcie *artpec6_pcie; 382 int ret; 383 const struct artpec_pcie_of_data *data; 384 enum artpec_pcie_variants variant; 385 enum dw_pcie_device_mode mode; 386 u32 val; 387 388 data = of_device_get_match_data(dev); 389 if (!data) 390 return -EINVAL; 391 392 variant = (enum artpec_pcie_variants)data->variant; 393 mode = (enum dw_pcie_device_mode)data->mode; 394 395 artpec6_pcie = devm_kzalloc(dev, sizeof(*artpec6_pcie), GFP_KERNEL); 396 if (!artpec6_pcie) 397 return -ENOMEM; 398 399 pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL); 400 if (!pci) 401 return -ENOMEM; 402 403 pci->dev = dev; 404 pci->ops = &dw_pcie_ops; 405 406 artpec6_pcie->pci = pci; 407 artpec6_pcie->variant = variant; 408 artpec6_pcie->mode = mode; 409 410 artpec6_pcie->phy_base = 411 devm_platform_ioremap_resource_byname(pdev, "phy"); 412 if (IS_ERR(artpec6_pcie->phy_base)) 413 return PTR_ERR(artpec6_pcie->phy_base); 414 415 artpec6_pcie->regmap = 416 syscon_regmap_lookup_by_phandle(dev->of_node, 417 "axis,syscon-pcie"); 418 if (IS_ERR(artpec6_pcie->regmap)) 419 return PTR_ERR(artpec6_pcie->regmap); 420 421 platform_set_drvdata(pdev, artpec6_pcie); 422 423 switch (artpec6_pcie->mode) { 424 case DW_PCIE_RC_TYPE: 425 if (!IS_ENABLED(CONFIG_PCIE_ARTPEC6_HOST)) 426 return -ENODEV; 427 428 pci->pp.ops = &artpec6_pcie_host_ops; 429 430 ret = dw_pcie_host_init(&pci->pp); 431 if (ret < 0) 432 return ret; 433 break; 434 case DW_PCIE_EP_TYPE: 435 if (!IS_ENABLED(CONFIG_PCIE_ARTPEC6_EP)) 436 return -ENODEV; 437 438 val = artpec6_pcie_readl(artpec6_pcie, PCIECFG); 439 val &= ~PCIECFG_DEVICE_TYPE_MASK; 440 artpec6_pcie_writel(artpec6_pcie, PCIECFG, val); 441 442 pci->ep.ops = &pcie_ep_ops; 443 444 return dw_pcie_ep_init(&pci->ep); 445 default: 446 dev_err(dev, "INVALID device type %d\n", artpec6_pcie->mode); 447 } 448 449 return 0; 450 } 451 452 static const struct artpec_pcie_of_data artpec6_pcie_rc_of_data = { 453 .variant = ARTPEC6, 454 .mode = DW_PCIE_RC_TYPE, 455 }; 456 457 static const struct artpec_pcie_of_data artpec6_pcie_ep_of_data = { 458 .variant = ARTPEC6, 459 .mode = DW_PCIE_EP_TYPE, 460 }; 461 462 static const struct artpec_pcie_of_data artpec7_pcie_rc_of_data = { 463 .variant = ARTPEC7, 464 .mode = DW_PCIE_RC_TYPE, 465 }; 466 467 static const struct artpec_pcie_of_data artpec7_pcie_ep_of_data = { 468 .variant = ARTPEC7, 469 .mode = DW_PCIE_EP_TYPE, 470 }; 471 472 static const struct of_device_id artpec6_pcie_of_match[] = { 473 { 474 .compatible = "axis,artpec6-pcie", 475 .data = &artpec6_pcie_rc_of_data, 476 }, 477 { 478 .compatible = "axis,artpec6-pcie-ep", 479 .data = &artpec6_pcie_ep_of_data, 480 }, 481 { 482 .compatible = "axis,artpec7-pcie", 483 .data = &artpec7_pcie_rc_of_data, 484 }, 485 { 486 .compatible = "axis,artpec7-pcie-ep", 487 .data = &artpec7_pcie_ep_of_data, 488 }, 489 {}, 490 }; 491 492 static struct platform_driver artpec6_pcie_driver = { 493 .probe = artpec6_pcie_probe, 494 .driver = { 495 .name = "artpec6-pcie", 496 .of_match_table = artpec6_pcie_of_match, 497 .suppress_bind_attrs = true, 498 }, 499 }; 500 builtin_platform_driver(artpec6_pcie_driver); 501