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