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->root_bus_nr = -1; 403 pp->ops = &artpec6_pcie_host_ops; 404 405 ret = dw_pcie_host_init(pp); 406 if (ret) { 407 dev_err(dev, "failed to initialize host\n"); 408 return ret; 409 } 410 411 return 0; 412 } 413 414 static void artpec6_pcie_ep_init(struct dw_pcie_ep *ep) 415 { 416 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 417 struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci); 418 enum pci_barno bar; 419 420 artpec6_pcie_assert_core_reset(artpec6_pcie); 421 artpec6_pcie_init_phy(artpec6_pcie); 422 artpec6_pcie_deassert_core_reset(artpec6_pcie); 423 artpec6_pcie_wait_for_phy(artpec6_pcie); 424 artpec6_pcie_set_nfts(artpec6_pcie); 425 426 for (bar = BAR_0; bar <= BAR_5; bar++) 427 dw_pcie_ep_reset_bar(pci, bar); 428 } 429 430 static int artpec6_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no, 431 enum pci_epc_irq_type type, u8 interrupt_num) 432 { 433 struct dw_pcie *pci = to_dw_pcie_from_ep(ep); 434 435 switch (type) { 436 case PCI_EPC_IRQ_LEGACY: 437 dev_err(pci->dev, "EP cannot trigger legacy IRQs\n"); 438 return -EINVAL; 439 case PCI_EPC_IRQ_MSI: 440 return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num); 441 default: 442 dev_err(pci->dev, "UNKNOWN IRQ type\n"); 443 } 444 445 return 0; 446 } 447 448 static struct dw_pcie_ep_ops pcie_ep_ops = { 449 .ep_init = artpec6_pcie_ep_init, 450 .raise_irq = artpec6_pcie_raise_irq, 451 }; 452 453 static int artpec6_add_pcie_ep(struct artpec6_pcie *artpec6_pcie, 454 struct platform_device *pdev) 455 { 456 int ret; 457 struct dw_pcie_ep *ep; 458 struct resource *res; 459 struct device *dev = &pdev->dev; 460 struct dw_pcie *pci = artpec6_pcie->pci; 461 462 ep = &pci->ep; 463 ep->ops = &pcie_ep_ops; 464 465 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi2"); 466 pci->dbi_base2 = devm_ioremap_resource(dev, res); 467 if (IS_ERR(pci->dbi_base2)) 468 return PTR_ERR(pci->dbi_base2); 469 470 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space"); 471 if (!res) 472 return -EINVAL; 473 474 ep->phys_base = res->start; 475 ep->addr_size = resource_size(res); 476 477 ret = dw_pcie_ep_init(ep); 478 if (ret) { 479 dev_err(dev, "failed to initialize endpoint\n"); 480 return ret; 481 } 482 483 return 0; 484 } 485 486 static int artpec6_pcie_probe(struct platform_device *pdev) 487 { 488 struct device *dev = &pdev->dev; 489 struct dw_pcie *pci; 490 struct artpec6_pcie *artpec6_pcie; 491 struct resource *dbi_base; 492 struct resource *phy_base; 493 int ret; 494 const struct of_device_id *match; 495 const struct artpec_pcie_of_data *data; 496 enum artpec_pcie_variants variant; 497 enum dw_pcie_device_mode mode; 498 499 match = of_match_device(artpec6_pcie_of_match, dev); 500 if (!match) 501 return -EINVAL; 502 503 data = (struct artpec_pcie_of_data *)match->data; 504 variant = (enum artpec_pcie_variants)data->variant; 505 mode = (enum dw_pcie_device_mode)data->mode; 506 507 artpec6_pcie = devm_kzalloc(dev, sizeof(*artpec6_pcie), GFP_KERNEL); 508 if (!artpec6_pcie) 509 return -ENOMEM; 510 511 pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL); 512 if (!pci) 513 return -ENOMEM; 514 515 pci->dev = dev; 516 pci->ops = &dw_pcie_ops; 517 518 artpec6_pcie->pci = pci; 519 artpec6_pcie->variant = variant; 520 artpec6_pcie->mode = mode; 521 522 dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi"); 523 pci->dbi_base = devm_ioremap_resource(dev, dbi_base); 524 if (IS_ERR(pci->dbi_base)) 525 return PTR_ERR(pci->dbi_base); 526 527 phy_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy"); 528 artpec6_pcie->phy_base = devm_ioremap_resource(dev, phy_base); 529 if (IS_ERR(artpec6_pcie->phy_base)) 530 return PTR_ERR(artpec6_pcie->phy_base); 531 532 artpec6_pcie->regmap = 533 syscon_regmap_lookup_by_phandle(dev->of_node, 534 "axis,syscon-pcie"); 535 if (IS_ERR(artpec6_pcie->regmap)) 536 return PTR_ERR(artpec6_pcie->regmap); 537 538 platform_set_drvdata(pdev, artpec6_pcie); 539 540 switch (artpec6_pcie->mode) { 541 case DW_PCIE_RC_TYPE: 542 if (!IS_ENABLED(CONFIG_PCIE_ARTPEC6_HOST)) 543 return -ENODEV; 544 545 ret = artpec6_add_pcie_port(artpec6_pcie, pdev); 546 if (ret < 0) 547 return ret; 548 break; 549 case DW_PCIE_EP_TYPE: { 550 u32 val; 551 552 if (!IS_ENABLED(CONFIG_PCIE_ARTPEC6_EP)) 553 return -ENODEV; 554 555 val = artpec6_pcie_readl(artpec6_pcie, PCIECFG); 556 val &= ~PCIECFG_DEVICE_TYPE_MASK; 557 artpec6_pcie_writel(artpec6_pcie, PCIECFG, val); 558 ret = artpec6_add_pcie_ep(artpec6_pcie, pdev); 559 if (ret < 0) 560 return ret; 561 break; 562 } 563 default: 564 dev_err(dev, "INVALID device type %d\n", artpec6_pcie->mode); 565 } 566 567 return 0; 568 } 569 570 static const struct artpec_pcie_of_data artpec6_pcie_rc_of_data = { 571 .variant = ARTPEC6, 572 .mode = DW_PCIE_RC_TYPE, 573 }; 574 575 static const struct artpec_pcie_of_data artpec6_pcie_ep_of_data = { 576 .variant = ARTPEC6, 577 .mode = DW_PCIE_EP_TYPE, 578 }; 579 580 static const struct artpec_pcie_of_data artpec7_pcie_rc_of_data = { 581 .variant = ARTPEC7, 582 .mode = DW_PCIE_RC_TYPE, 583 }; 584 585 static const struct artpec_pcie_of_data artpec7_pcie_ep_of_data = { 586 .variant = ARTPEC7, 587 .mode = DW_PCIE_EP_TYPE, 588 }; 589 590 static const struct of_device_id artpec6_pcie_of_match[] = { 591 { 592 .compatible = "axis,artpec6-pcie", 593 .data = &artpec6_pcie_rc_of_data, 594 }, 595 { 596 .compatible = "axis,artpec6-pcie-ep", 597 .data = &artpec6_pcie_ep_of_data, 598 }, 599 { 600 .compatible = "axis,artpec7-pcie", 601 .data = &artpec7_pcie_rc_of_data, 602 }, 603 { 604 .compatible = "axis,artpec7-pcie-ep", 605 .data = &artpec7_pcie_ep_of_data, 606 }, 607 {}, 608 }; 609 610 static struct platform_driver artpec6_pcie_driver = { 611 .probe = artpec6_pcie_probe, 612 .driver = { 613 .name = "artpec6-pcie", 614 .of_match_table = artpec6_pcie_of_match, 615 .suppress_bind_attrs = true, 616 }, 617 }; 618 builtin_platform_driver(artpec6_pcie_driver); 619