pcie-artpec6.c 15.2 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0
2 3 4
/*
 * PCIe host controller driver for Axis ARTPEC-6 SoC
 *
5 6
 * Author: Niklas Cassel <niklas.cassel@axis.com>
 *
7 8 9 10 11
 * Based on work done by Phil Edworthy <phil@edworthys.org>
 */

#include <linux/delay.h>
#include <linux/kernel.h>
12
#include <linux/init.h>
13
#include <linux/of_device.h>
14 15 16 17 18 19 20 21 22 23 24
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/resource.h>
#include <linux/signal.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>

#include "pcie-designware.h"

25
#define to_artpec6_pcie(x)	dev_get_drvdata((x)->dev)
26

27 28 29 30 31
enum artpec_pcie_variants {
	ARTPEC6,
	ARTPEC7,
};

32
struct artpec6_pcie {
33
	struct dw_pcie		*pci;
34 35
	struct regmap		*regmap;	/* DT axis,syscon-pcie */
	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 46
static const struct of_device_id artpec6_pcie_of_match[];

47 48 49
/* PCIe Port Logic registers (memory-mapped) */
#define PL_OFFSET			0x700

50 51 52 53
#define ACK_F_ASPM_CTRL_OFF		(PL_OFFSET + 0xc)
#define ACK_N_FTS_MASK			GENMASK(15, 8)
#define ACK_N_FTS(x)			(((x) << 8) & ACK_N_FTS_MASK)

54 55
/* ARTPEC-6 specific registers */
#define PCIECFG				0x18
56 57 58
#define  PCIECFG_DBG_OEN		BIT(24)
#define  PCIECFG_CORE_RESET_REQ		BIT(21)
#define  PCIECFG_LTSSM_ENABLE		BIT(20)
59
#define  PCIECFG_DEVICE_TYPE_MASK	GENMASK(19, 16)
60 61 62 63 64 65 66 67
#define  PCIECFG_CLKREQ_B		BIT(11)
#define  PCIECFG_REFCLK_ENABLE		BIT(10)
#define  PCIECFG_PLL_ENABLE		BIT(9)
#define  PCIECFG_PCLK_ENABLE		BIT(8)
#define  PCIECFG_RISRCREN		BIT(4)
#define  PCIECFG_MODE_TX_DRV_EN		BIT(3)
#define  PCIECFG_CISRREN		BIT(2)
#define  PCIECFG_MACRO_ENABLE		BIT(0)
68 69 70 71 72 73 74
/* ARTPEC-7 specific fields */
#define  PCIECFG_REFCLKSEL		BIT(23)
#define  PCIECFG_NOC_RESET		BIT(3)

#define PCIESTAT			0x1c
/* ARTPEC-7 specific fields */
#define  PCIESTAT_EXTREFCLK		BIT(3)
75 76

#define NOCCFG				0x40
77 78 79 80
#define  NOCCFG_ENABLE_CLK_PCIE		BIT(4)
#define  NOCCFG_POWER_PCIE_IDLEACK	BIT(3)
#define  NOCCFG_POWER_PCIE_IDLE		BIT(2)
#define  NOCCFG_POWER_PCIE_IDLEREQ	BIT(1)
81 82

#define PHY_STATUS			0x118
83
#define  PHY_COSPLLLOCK			BIT(0)
84

85 86 87 88 89
#define PHY_TX_ASIC_OUT			0x4040
#define  PHY_TX_ASIC_OUT_TX_ACK		BIT(0)

#define PHY_RX_ASIC_OUT			0x405c
#define  PHY_RX_ASIC_OUT_ACK		BIT(0)
90

91 92 93 94 95 96 97 98 99 100 101 102 103
static u32 artpec6_pcie_readl(struct artpec6_pcie *artpec6_pcie, u32 offset)
{
	u32 val;

	regmap_read(artpec6_pcie->regmap, offset, &val);
	return val;
}

static void artpec6_pcie_writel(struct artpec6_pcie *artpec6_pcie, u32 offset, u32 val)
{
	regmap_write(artpec6_pcie->regmap, offset, val);
}

104
static u64 artpec6_pcie_cpu_addr_fixup(struct dw_pcie *pci, u64 pci_addr)
105
{
106 107 108 109 110 111 112 113 114 115 116 117 118
	struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
	struct pcie_port *pp = &pci->pp;
	struct dw_pcie_ep *ep = &pci->ep;

	switch (artpec6_pcie->mode) {
	case DW_PCIE_RC_TYPE:
		return pci_addr - pp->cfg0_base;
	case DW_PCIE_EP_TYPE:
		return pci_addr - ep->phys_base;
	default:
		dev_err(pci->dev, "UNKNOWN device type\n");
	}
	return pci_addr;
119 120
}

121
static int artpec6_pcie_establish_link(struct dw_pcie *pci)
122
{
123
	struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
124 125
	u32 val;

126
	val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
127
	val |= PCIECFG_LTSSM_ENABLE;
128
	artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
129

130 131 132
	return 0;
}

133 134 135
static void artpec6_pcie_stop_link(struct dw_pcie *pci)
{
	struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
136 137
	u32 val;

138
	val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
139
	val &= ~PCIECFG_LTSSM_ENABLE;
140
	artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
141 142 143 144 145 146 147 148
}

static const struct dw_pcie_ops dw_pcie_ops = {
	.cpu_addr_fixup = artpec6_pcie_cpu_addr_fixup,
	.start_link = artpec6_pcie_establish_link,
	.stop_link = artpec6_pcie_stop_link,
};

149
static void artpec6_pcie_wait_for_phy_a6(struct artpec6_pcie *artpec6_pcie)
150
{
151 152
	struct dw_pcie *pci = artpec6_pcie->pci;
	struct device *dev = pci->dev;
153 154 155
	u32 val;
	unsigned int retries;

156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
	retries = 50;
	do {
		usleep_range(1000, 2000);
		val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
		retries--;
	} while (retries &&
		(val & (NOCCFG_POWER_PCIE_IDLEACK | NOCCFG_POWER_PCIE_IDLE)));
	if (!retries)
		dev_err(dev, "PCIe clock manager did not leave idle state\n");

	retries = 50;
	do {
		usleep_range(1000, 2000);
		val = readl(artpec6_pcie->phy_base + PHY_STATUS);
		retries--;
	} while (retries && !(val & PHY_COSPLLLOCK));
	if (!retries)
		dev_err(dev, "PHY PLL did not lock\n");
}

176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
static void artpec6_pcie_wait_for_phy_a7(struct artpec6_pcie *artpec6_pcie)
{
	struct dw_pcie *pci = artpec6_pcie->pci;
	struct device *dev = pci->dev;
	u32 val;
	u16 phy_status_tx, phy_status_rx;
	unsigned int retries;

	retries = 50;
	do {
		usleep_range(1000, 2000);
		val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
		retries--;
	} while (retries &&
		(val & (NOCCFG_POWER_PCIE_IDLEACK | NOCCFG_POWER_PCIE_IDLE)));
	if (!retries)
		dev_err(dev, "PCIe clock manager did not leave idle state\n");

	retries = 50;
	do {
		usleep_range(1000, 2000);
		phy_status_tx = readw(artpec6_pcie->phy_base + PHY_TX_ASIC_OUT);
		phy_status_rx = readw(artpec6_pcie->phy_base + PHY_RX_ASIC_OUT);
		retries--;
	} while (retries && ((phy_status_tx & PHY_TX_ASIC_OUT_TX_ACK) ||
				(phy_status_rx & PHY_RX_ASIC_OUT_ACK)));
	if (!retries)
		dev_err(dev, "PHY did not enter Pn state\n");
}

static void artpec6_pcie_wait_for_phy(struct artpec6_pcie *artpec6_pcie)
{
	switch (artpec6_pcie->variant) {
	case ARTPEC6:
		artpec6_pcie_wait_for_phy_a6(artpec6_pcie);
		break;
	case ARTPEC7:
		artpec6_pcie_wait_for_phy_a7(artpec6_pcie);
		break;
	}
}

static void artpec6_pcie_init_phy_a6(struct artpec6_pcie *artpec6_pcie)
219 220
{
	u32 val;
221

222
	val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
223 224 225 226 227 228 229
	val |=  PCIECFG_RISRCREN |	/* Receiver term. 50 Ohm */
		PCIECFG_MODE_TX_DRV_EN |
		PCIECFG_CISRREN |	/* Reference clock term. 100 Ohm */
		PCIECFG_MACRO_ENABLE;
	val |= PCIECFG_REFCLK_ENABLE;
	val &= ~PCIECFG_DBG_OEN;
	val &= ~PCIECFG_CLKREQ_B;
230
	artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
231 232
	usleep_range(5000, 6000);

233
	val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
234
	val |= NOCCFG_ENABLE_CLK_PCIE;
235
	artpec6_pcie_writel(artpec6_pcie, NOCCFG, val);
236 237
	usleep_range(20, 30);

238
	val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
239
	val |= PCIECFG_PCLK_ENABLE | PCIECFG_PLL_ENABLE;
240
	artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
241 242
	usleep_range(6000, 7000);

243
	val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
244
	val &= ~NOCCFG_POWER_PCIE_IDLEREQ;
245
	artpec6_pcie_writel(artpec6_pcie, NOCCFG, val);
246
}
247

248 249 250 251 252
static void artpec6_pcie_init_phy_a7(struct artpec6_pcie *artpec6_pcie)
{
	struct dw_pcie *pci = artpec6_pcie->pci;
	u32 val;
	bool extrefclk;
253

254 255 256 257 258
	/* Check if external reference clock is connected */
	val = artpec6_pcie_readl(artpec6_pcie, PCIESTAT);
	extrefclk = !!(val & PCIESTAT_EXTREFCLK);
	dev_dbg(pci->dev, "Using reference clock: %s\n",
		extrefclk ? "external" : "internal");
259

260
	val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
261 262 263 264 265 266
	val |=  PCIECFG_RISRCREN |	/* Receiver term. 50 Ohm */
		PCIECFG_PCLK_ENABLE;
	if (extrefclk)
		val |= PCIECFG_REFCLKSEL;
	else
		val &= ~PCIECFG_REFCLKSEL;
267
	artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
268
	usleep_range(10, 20);
269

270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312
	val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
	val |= NOCCFG_ENABLE_CLK_PCIE;
	artpec6_pcie_writel(artpec6_pcie, NOCCFG, val);
	usleep_range(20, 30);

	val = artpec6_pcie_readl(artpec6_pcie, NOCCFG);
	val &= ~NOCCFG_POWER_PCIE_IDLEREQ;
	artpec6_pcie_writel(artpec6_pcie, NOCCFG, val);
}

static void artpec6_pcie_init_phy(struct artpec6_pcie *artpec6_pcie)
{
	switch (artpec6_pcie->variant) {
	case ARTPEC6:
		artpec6_pcie_init_phy_a6(artpec6_pcie);
		break;
	case ARTPEC7:
		artpec6_pcie_init_phy_a7(artpec6_pcie);
		break;
	}
}

static void artpec6_pcie_set_nfts(struct artpec6_pcie *artpec6_pcie)
{
	struct dw_pcie *pci = artpec6_pcie->pci;
	u32 val;

	if (artpec6_pcie->variant != ARTPEC7)
		return;

	/*
	 * Increase the N_FTS (Number of Fast Training Sequences)
	 * to be transmitted when transitioning from L0s to L0.
	 */
	val = dw_pcie_readl_dbi(pci, ACK_F_ASPM_CTRL_OFF);
	val &= ~ACK_N_FTS_MASK;
	val |= ACK_N_FTS(180);
	dw_pcie_writel_dbi(pci, ACK_F_ASPM_CTRL_OFF, val);

	/*
	 * Set the Number of Fast Training Sequences that the core
	 * advertises as its N_FTS during Gen2 or Gen3 link training.
	 */
313
	dw_pcie_link_set_n_fts(pci, 180);
314 315
}

316 317 318
static void artpec6_pcie_assert_core_reset(struct artpec6_pcie *artpec6_pcie)
{
	u32 val;
319

320
	val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
321 322 323 324 325 326 327 328
	switch (artpec6_pcie->variant) {
	case ARTPEC6:
		val |= PCIECFG_CORE_RESET_REQ;
		break;
	case ARTPEC7:
		val &= ~PCIECFG_NOC_RESET;
		break;
	}
329
	artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
330
}
331

332 333 334
static void artpec6_pcie_deassert_core_reset(struct artpec6_pcie *artpec6_pcie)
{
	u32 val;
335

336
	val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
337 338 339 340 341 342 343 344
	switch (artpec6_pcie->variant) {
	case ARTPEC6:
		val &= ~PCIECFG_CORE_RESET_REQ;
		break;
	case ARTPEC7:
		val |= PCIECFG_NOC_RESET;
		break;
	}
345
	artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
346
	usleep_range(100, 200);
347 348
}

349
static void artpec6_pcie_enable_interrupts(struct artpec6_pcie *artpec6_pcie)
350
{
351 352
	struct dw_pcie *pci = artpec6_pcie->pci;
	struct pcie_port *pp = &pci->pp;
353

354 355 356 357
	if (IS_ENABLED(CONFIG_PCI_MSI))
		dw_pcie_msi_init(pp);
}

358
static int artpec6_pcie_host_init(struct pcie_port *pp)
359
{
360 361
	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
	struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
362

363 364 365
	artpec6_pcie_assert_core_reset(artpec6_pcie);
	artpec6_pcie_init_phy(artpec6_pcie);
	artpec6_pcie_deassert_core_reset(artpec6_pcie);
366
	artpec6_pcie_wait_for_phy(artpec6_pcie);
367
	artpec6_pcie_set_nfts(artpec6_pcie);
368 369 370
	dw_pcie_setup_rc(pp);
	artpec6_pcie_establish_link(pci);
	dw_pcie_wait_for_link(pci);
371
	artpec6_pcie_enable_interrupts(artpec6_pcie);
372 373

	return 0;
374 375
}

376
static const struct dw_pcie_host_ops artpec6_pcie_host_ops = {
377 378 379
	.host_init = artpec6_pcie_host_init,
};

380
static int artpec6_add_pcie_port(struct artpec6_pcie *artpec6_pcie,
381
				 struct platform_device *pdev)
382
{
383 384 385
	struct dw_pcie *pci = artpec6_pcie->pci;
	struct pcie_port *pp = &pci->pp;
	struct device *dev = pci->dev;
386 387 388 389
	int ret;

	if (IS_ENABLED(CONFIG_PCI_MSI)) {
		pp->msi_irq = platform_get_irq_byname(pdev, "msi");
390
		if (pp->msi_irq < 0)
391
			return pp->msi_irq;
392 393 394 395 396 397
	}

	pp->ops = &artpec6_pcie_host_ops;

	ret = dw_pcie_host_init(pp);
	if (ret) {
398
		dev_err(dev, "failed to initialize host\n");
399 400 401 402 403 404
		return ret;
	}

	return 0;
}

405 406 407 408 409 410 411 412 413
static void artpec6_pcie_ep_init(struct dw_pcie_ep *ep)
{
	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
	struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
	enum pci_barno bar;

	artpec6_pcie_assert_core_reset(artpec6_pcie);
	artpec6_pcie_init_phy(artpec6_pcie);
	artpec6_pcie_deassert_core_reset(artpec6_pcie);
414
	artpec6_pcie_wait_for_phy(artpec6_pcie);
415
	artpec6_pcie_set_nfts(artpec6_pcie);
416

417
	for (bar = 0; bar < PCI_STD_NUM_BARS; bar++)
418 419 420
		dw_pcie_ep_reset_bar(pci, bar);
}

421
static int artpec6_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
422
				  enum pci_epc_irq_type type, u16 interrupt_num)
423 424 425 426 427 428 429 430
{
	struct dw_pcie *pci = to_dw_pcie_from_ep(ep);

	switch (type) {
	case PCI_EPC_IRQ_LEGACY:
		dev_err(pci->dev, "EP cannot trigger legacy IRQs\n");
		return -EINVAL;
	case PCI_EPC_IRQ_MSI:
431
		return dw_pcie_ep_raise_msi_irq(ep, func_no, interrupt_num);
432 433 434 435 436 437 438
	default:
		dev_err(pci->dev, "UNKNOWN IRQ type\n");
	}

	return 0;
}

439
static const struct dw_pcie_ep_ops pcie_ep_ops = {
440 441
	.ep_init = artpec6_pcie_ep_init,
	.raise_irq = artpec6_pcie_raise_irq,
442 443
};

444 445 446 447 448 449 450 451 452 453 454 455 456
static int artpec6_add_pcie_ep(struct artpec6_pcie *artpec6_pcie,
			       struct platform_device *pdev)
{
	int ret;
	struct dw_pcie_ep *ep;
	struct resource *res;
	struct device *dev = &pdev->dev;
	struct dw_pcie *pci = artpec6_pcie->pci;

	ep = &pci->ep;
	ep->ops = &pcie_ep_ops;

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi2");
457 458 459
	pci->dbi_base2 = devm_ioremap_resource(dev, res);
	if (IS_ERR(pci->dbi_base2))
		return PTR_ERR(pci->dbi_base2);
460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
	if (!res)
		return -EINVAL;

	ep->phys_base = res->start;
	ep->addr_size = resource_size(res);

	ret = dw_pcie_ep_init(ep);
	if (ret) {
		dev_err(dev, "failed to initialize endpoint\n");
		return ret;
	}

	return 0;
}

477 478
static int artpec6_pcie_probe(struct platform_device *pdev)
{
479
	struct device *dev = &pdev->dev;
480
	struct dw_pcie *pci;
481 482 483 484
	struct artpec6_pcie *artpec6_pcie;
	struct resource *dbi_base;
	struct resource *phy_base;
	int ret;
485 486
	const struct of_device_id *match;
	const struct artpec_pcie_of_data *data;
487
	enum artpec_pcie_variants variant;
488 489 490 491 492 493 494
	enum dw_pcie_device_mode mode;

	match = of_match_device(artpec6_pcie_of_match, dev);
	if (!match)
		return -EINVAL;

	data = (struct artpec_pcie_of_data *)match->data;
495
	variant = (enum artpec_pcie_variants)data->variant;
496
	mode = (enum dw_pcie_device_mode)data->mode;
497

498
	artpec6_pcie = devm_kzalloc(dev, sizeof(*artpec6_pcie), GFP_KERNEL);
499 500 501
	if (!artpec6_pcie)
		return -ENOMEM;

502 503 504 505 506
	pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
	if (!pci)
		return -ENOMEM;

	pci->dev = dev;
507
	pci->ops = &dw_pcie_ops;
508

509
	artpec6_pcie->pci = pci;
510
	artpec6_pcie->variant = variant;
511
	artpec6_pcie->mode = mode;
512

513
	dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
514 515 516
	pci->dbi_base = devm_ioremap_resource(dev, dbi_base);
	if (IS_ERR(pci->dbi_base))
		return PTR_ERR(pci->dbi_base);
517 518

	phy_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy");
519
	artpec6_pcie->phy_base = devm_ioremap_resource(dev, phy_base);
520 521 522 523
	if (IS_ERR(artpec6_pcie->phy_base))
		return PTR_ERR(artpec6_pcie->phy_base);

	artpec6_pcie->regmap =
524
		syscon_regmap_lookup_by_phandle(dev->of_node,
525 526 527 528
						"axis,syscon-pcie");
	if (IS_ERR(artpec6_pcie->regmap))
		return PTR_ERR(artpec6_pcie->regmap);

529 530
	platform_set_drvdata(pdev, artpec6_pcie);

531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556
	switch (artpec6_pcie->mode) {
	case DW_PCIE_RC_TYPE:
		if (!IS_ENABLED(CONFIG_PCIE_ARTPEC6_HOST))
			return -ENODEV;

		ret = artpec6_add_pcie_port(artpec6_pcie, pdev);
		if (ret < 0)
			return ret;
		break;
	case DW_PCIE_EP_TYPE: {
		u32 val;

		if (!IS_ENABLED(CONFIG_PCIE_ARTPEC6_EP))
			return -ENODEV;

		val = artpec6_pcie_readl(artpec6_pcie, PCIECFG);
		val &= ~PCIECFG_DEVICE_TYPE_MASK;
		artpec6_pcie_writel(artpec6_pcie, PCIECFG, val);
		ret = artpec6_add_pcie_ep(artpec6_pcie, pdev);
		if (ret < 0)
			return ret;
		break;
	}
	default:
		dev_err(dev, "INVALID device type %d\n", artpec6_pcie->mode);
	}
557 558 559 560

	return 0;
}

561
static const struct artpec_pcie_of_data artpec6_pcie_rc_of_data = {
562
	.variant = ARTPEC6,
563 564 565 566
	.mode = DW_PCIE_RC_TYPE,
};

static const struct artpec_pcie_of_data artpec6_pcie_ep_of_data = {
567 568 569 570 571 572 573 574 575 576 577
	.variant = ARTPEC6,
	.mode = DW_PCIE_EP_TYPE,
};

static const struct artpec_pcie_of_data artpec7_pcie_rc_of_data = {
	.variant = ARTPEC7,
	.mode = DW_PCIE_RC_TYPE,
};

static const struct artpec_pcie_of_data artpec7_pcie_ep_of_data = {
	.variant = ARTPEC7,
578 579 580
	.mode = DW_PCIE_EP_TYPE,
};

581
static const struct of_device_id artpec6_pcie_of_match[] = {
582 583 584 585 586 587 588 589
	{
		.compatible = "axis,artpec6-pcie",
		.data = &artpec6_pcie_rc_of_data,
	},
	{
		.compatible = "axis,artpec6-pcie-ep",
		.data = &artpec6_pcie_ep_of_data,
	},
590 591 592 593 594 595 596 597
	{
		.compatible = "axis,artpec7-pcie",
		.data = &artpec7_pcie_rc_of_data,
	},
	{
		.compatible = "axis,artpec7-pcie-ep",
		.data = &artpec7_pcie_ep_of_data,
	},
598 599 600 601 602 603 604 605
	{},
};

static struct platform_driver artpec6_pcie_driver = {
	.probe = artpec6_pcie_probe,
	.driver = {
		.name	= "artpec6-pcie",
		.of_match_table = artpec6_pcie_of_match,
606
		.suppress_bind_attrs = true,
607 608
	},
};
609
builtin_platform_driver(artpec6_pcie_driver);