blob: 01caa98d41719982cd7aaae278aea5cf37d443cc [file] [log] [blame]
Ryder Lee637cfaca2017-05-21 11:42:24 +08001/*
2 * MediaTek PCIe host controller driver.
3 *
4 * Copyright (c) 2017 MediaTek Inc.
5 * Author: Ryder Lee <ryder.lee@mediatek.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/clk.h>
18#include <linux/delay.h>
Ryder Leee10b7a12017-08-10 14:34:54 +080019#include <linux/iopoll.h>
Ryder Lee637cfaca2017-05-21 11:42:24 +080020#include <linux/kernel.h>
21#include <linux/of_address.h>
22#include <linux/of_pci.h>
23#include <linux/of_platform.h>
24#include <linux/pci.h>
25#include <linux/phy/phy.h>
26#include <linux/platform_device.h>
27#include <linux/pm_runtime.h>
28#include <linux/reset.h>
29
30/* PCIe shared registers */
31#define PCIE_SYS_CFG 0x00
32#define PCIE_INT_ENABLE 0x0c
33#define PCIE_CFG_ADDR 0x20
34#define PCIE_CFG_DATA 0x24
35
36/* PCIe per port registers */
37#define PCIE_BAR0_SETUP 0x10
38#define PCIE_CLASS 0x34
39#define PCIE_LINK_STATUS 0x50
40
41#define PCIE_PORT_INT_EN(x) BIT(20 + (x))
42#define PCIE_PORT_PERST(x) BIT(1 + (x))
43#define PCIE_PORT_LINKUP BIT(0)
44#define PCIE_BAR_MAP_MAX GENMASK(31, 16)
45
46#define PCIE_BAR_ENABLE BIT(0)
47#define PCIE_REVISION_ID BIT(0)
48#define PCIE_CLASS_CODE (0x60400 << 8)
49#define PCIE_CONF_REG(regn) (((regn) & GENMASK(7, 2)) | \
50 ((((regn) >> 8) & GENMASK(3, 0)) << 24))
51#define PCIE_CONF_FUN(fun) (((fun) << 8) & GENMASK(10, 8))
52#define PCIE_CONF_DEV(dev) (((dev) << 11) & GENMASK(15, 11))
53#define PCIE_CONF_BUS(bus) (((bus) << 16) & GENMASK(23, 16))
54#define PCIE_CONF_ADDR(regn, fun, dev, bus) \
55 (PCIE_CONF_REG(regn) | PCIE_CONF_FUN(fun) | \
56 PCIE_CONF_DEV(dev) | PCIE_CONF_BUS(bus))
57
58/* MediaTek specific configuration registers */
59#define PCIE_FTS_NUM 0x70c
60#define PCIE_FTS_NUM_MASK GENMASK(15, 8)
61#define PCIE_FTS_NUM_L0(x) ((x) & 0xff << 8)
62
63#define PCIE_FC_CREDIT 0x73c
64#define PCIE_FC_CREDIT_MASK (GENMASK(31, 31) | GENMASK(28, 16))
65#define PCIE_FC_CREDIT_VAL(x) ((x) << 16)
66
Honghui Zhangc681c932017-08-10 14:34:56 +080067struct mtk_pcie_port;
68
69/**
70 * struct mtk_pcie_soc - differentiate between host generations
71 * @ops: pointer to configuration access functions
72 * @startup: pointer to controller setting functions
73 */
74struct mtk_pcie_soc {
75 struct pci_ops *ops;
76 int (*startup)(struct mtk_pcie_port *port);
77};
78
Ryder Lee637cfaca2017-05-21 11:42:24 +080079/**
80 * struct mtk_pcie_port - PCIe port information
81 * @base: IO mapped register base
82 * @list: port list
83 * @pcie: pointer to PCIe host info
84 * @reset: pointer to port reset control
85 * @sys_ck: pointer to bus clock
86 * @phy: pointer to phy control block
87 * @lane: lane count
Honghui Zhang4f6f0462017-08-10 14:34:55 +080088 * @slot: port slot
Ryder Lee637cfaca2017-05-21 11:42:24 +080089 */
90struct mtk_pcie_port {
91 void __iomem *base;
92 struct list_head list;
93 struct mtk_pcie *pcie;
94 struct reset_control *reset;
95 struct clk *sys_ck;
96 struct phy *phy;
97 u32 lane;
Honghui Zhang4f6f0462017-08-10 14:34:55 +080098 u32 slot;
Ryder Lee637cfaca2017-05-21 11:42:24 +080099};
100
101/**
102 * struct mtk_pcie - PCIe host information
103 * @dev: pointer to PCIe device
104 * @base: IO mapped register base
105 * @free_ck: free-run reference clock
106 * @io: IO resource
107 * @pio: PIO resource
108 * @mem: non-prefetchable memory resource
109 * @busn: bus range
110 * @offset: IO / Memory offset
111 * @ports: pointer to PCIe port information
Honghui Zhangc681c932017-08-10 14:34:56 +0800112 * @soc: pointer to SoC-dependent operations
Ryder Lee637cfaca2017-05-21 11:42:24 +0800113 */
114struct mtk_pcie {
115 struct device *dev;
116 void __iomem *base;
117 struct clk *free_ck;
118
119 struct resource io;
120 struct resource pio;
121 struct resource mem;
122 struct resource busn;
123 struct {
124 resource_size_t mem;
125 resource_size_t io;
126 } offset;
127 struct list_head ports;
Honghui Zhangc681c932017-08-10 14:34:56 +0800128 const struct mtk_pcie_soc *soc;
Ryder Lee637cfaca2017-05-21 11:42:24 +0800129};
130
Ryder Lee637cfaca2017-05-21 11:42:24 +0800131static void mtk_pcie_subsys_powerdown(struct mtk_pcie *pcie)
132{
133 struct device *dev = pcie->dev;
134
135 clk_disable_unprepare(pcie->free_ck);
136
137 if (dev->pm_domain) {
138 pm_runtime_put_sync(dev);
139 pm_runtime_disable(dev);
140 }
141}
142
143static void mtk_pcie_port_free(struct mtk_pcie_port *port)
144{
145 struct mtk_pcie *pcie = port->pcie;
146 struct device *dev = pcie->dev;
147
148 devm_iounmap(dev, port->base);
149 list_del(&port->list);
150 devm_kfree(dev, port);
151}
152
153static void mtk_pcie_put_resources(struct mtk_pcie *pcie)
154{
155 struct mtk_pcie_port *port, *tmp;
156
157 list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
158 phy_power_off(port->phy);
159 clk_disable_unprepare(port->sys_ck);
160 mtk_pcie_port_free(port);
161 }
162
163 mtk_pcie_subsys_powerdown(pcie);
164}
165
166static void __iomem *mtk_pcie_map_bus(struct pci_bus *bus,
167 unsigned int devfn, int where)
168{
169 struct pci_host_bridge *host = pci_find_host_bridge(bus);
170 struct mtk_pcie *pcie = pci_host_bridge_priv(host);
171
172 writel(PCIE_CONF_ADDR(where, PCI_FUNC(devfn), PCI_SLOT(devfn),
173 bus->number), pcie->base + PCIE_CFG_ADDR);
174
175 return pcie->base + PCIE_CFG_DATA + (where & 3);
176}
177
178static struct pci_ops mtk_pcie_ops = {
179 .map_bus = mtk_pcie_map_bus,
180 .read = pci_generic_config_read,
181 .write = pci_generic_config_write,
182};
183
Ryder Leee10b7a12017-08-10 14:34:54 +0800184static int mtk_pcie_startup_port(struct mtk_pcie_port *port)
Ryder Lee637cfaca2017-05-21 11:42:24 +0800185{
186 struct mtk_pcie *pcie = port->pcie;
Honghui Zhang4f6f0462017-08-10 14:34:55 +0800187 u32 func = PCI_FUNC(port->slot << 3);
188 u32 slot = PCI_SLOT(port->slot << 3);
Ryder Lee637cfaca2017-05-21 11:42:24 +0800189 u32 val;
Ryder Leee10b7a12017-08-10 14:34:54 +0800190 int err;
191
192 /* assert port PERST_N */
193 val = readl(pcie->base + PCIE_SYS_CFG);
Honghui Zhang4f6f0462017-08-10 14:34:55 +0800194 val |= PCIE_PORT_PERST(port->slot);
Ryder Leee10b7a12017-08-10 14:34:54 +0800195 writel(val, pcie->base + PCIE_SYS_CFG);
196
197 /* de-assert port PERST_N */
198 val = readl(pcie->base + PCIE_SYS_CFG);
Honghui Zhang4f6f0462017-08-10 14:34:55 +0800199 val &= ~PCIE_PORT_PERST(port->slot);
Ryder Leee10b7a12017-08-10 14:34:54 +0800200 writel(val, pcie->base + PCIE_SYS_CFG);
201
202 /* 100ms timeout value should be enough for Gen1/2 training */
203 err = readl_poll_timeout(port->base + PCIE_LINK_STATUS, val,
204 !!(val & PCIE_PORT_LINKUP), 20,
205 100 * USEC_PER_MSEC);
206 if (err)
207 return -ETIMEDOUT;
Ryder Lee637cfaca2017-05-21 11:42:24 +0800208
209 /* enable interrupt */
210 val = readl(pcie->base + PCIE_INT_ENABLE);
Honghui Zhang4f6f0462017-08-10 14:34:55 +0800211 val |= PCIE_PORT_INT_EN(port->slot);
Ryder Lee637cfaca2017-05-21 11:42:24 +0800212 writel(val, pcie->base + PCIE_INT_ENABLE);
213
214 /* map to all DDR region. We need to set it before cfg operation. */
215 writel(PCIE_BAR_MAP_MAX | PCIE_BAR_ENABLE,
216 port->base + PCIE_BAR0_SETUP);
217
218 /* configure class code and revision ID */
219 writel(PCIE_CLASS_CODE | PCIE_REVISION_ID, port->base + PCIE_CLASS);
220
221 /* configure FC credit */
222 writel(PCIE_CONF_ADDR(PCIE_FC_CREDIT, func, slot, 0),
223 pcie->base + PCIE_CFG_ADDR);
224 val = readl(pcie->base + PCIE_CFG_DATA);
225 val &= ~PCIE_FC_CREDIT_MASK;
226 val |= PCIE_FC_CREDIT_VAL(0x806c);
227 writel(PCIE_CONF_ADDR(PCIE_FC_CREDIT, func, slot, 0),
228 pcie->base + PCIE_CFG_ADDR);
229 writel(val, pcie->base + PCIE_CFG_DATA);
230
231 /* configure RC FTS number to 250 when it leaves L0s */
232 writel(PCIE_CONF_ADDR(PCIE_FTS_NUM, func, slot, 0),
233 pcie->base + PCIE_CFG_ADDR);
234 val = readl(pcie->base + PCIE_CFG_DATA);
235 val &= ~PCIE_FTS_NUM_MASK;
236 val |= PCIE_FTS_NUM_L0(0x50);
237 writel(PCIE_CONF_ADDR(PCIE_FTS_NUM, func, slot, 0),
238 pcie->base + PCIE_CFG_ADDR);
239 writel(val, pcie->base + PCIE_CFG_DATA);
Ryder Lee637cfaca2017-05-21 11:42:24 +0800240
Ryder Leee10b7a12017-08-10 14:34:54 +0800241 return 0;
Ryder Lee637cfaca2017-05-21 11:42:24 +0800242}
243
Honghui Zhang4f6f0462017-08-10 14:34:55 +0800244static void mtk_pcie_enable_port(struct mtk_pcie_port *port)
Ryder Lee637cfaca2017-05-21 11:42:24 +0800245{
Honghui Zhangc681c932017-08-10 14:34:56 +0800246 struct mtk_pcie *pcie = port->pcie;
247 struct device *dev = pcie->dev;
Ryder Lee637cfaca2017-05-21 11:42:24 +0800248 int err;
249
250 err = clk_prepare_enable(port->sys_ck);
251 if (err) {
Honghui Zhang4f6f0462017-08-10 14:34:55 +0800252 dev_err(dev, "failed to enable port%d clock\n", port->slot);
Ryder Lee637cfaca2017-05-21 11:42:24 +0800253 goto err_sys_clk;
254 }
255
256 reset_control_assert(port->reset);
257 reset_control_deassert(port->reset);
258
259 err = phy_power_on(port->phy);
260 if (err) {
Honghui Zhang4f6f0462017-08-10 14:34:55 +0800261 dev_err(dev, "failed to power on port%d phy\n", port->slot);
Ryder Lee637cfaca2017-05-21 11:42:24 +0800262 goto err_phy_on;
263 }
264
Honghui Zhangc681c932017-08-10 14:34:56 +0800265 if (!pcie->soc->startup(port))
Ryder Lee637cfaca2017-05-21 11:42:24 +0800266 return;
Ryder Lee637cfaca2017-05-21 11:42:24 +0800267
Honghui Zhang4f6f0462017-08-10 14:34:55 +0800268 dev_info(dev, "Port%d link down\n", port->slot);
Ryder Lee637cfaca2017-05-21 11:42:24 +0800269
270 phy_power_off(port->phy);
271err_phy_on:
272 clk_disable_unprepare(port->sys_ck);
273err_sys_clk:
274 mtk_pcie_port_free(port);
275}
276
Honghui Zhang4f6f0462017-08-10 14:34:55 +0800277static int mtk_pcie_parse_port(struct mtk_pcie *pcie,
278 struct device_node *node,
279 int slot)
Ryder Lee637cfaca2017-05-21 11:42:24 +0800280{
281 struct mtk_pcie_port *port;
282 struct resource *regs;
283 struct device *dev = pcie->dev;
284 struct platform_device *pdev = to_platform_device(dev);
285 char name[10];
286 int err;
287
288 port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
289 if (!port)
290 return -ENOMEM;
291
292 err = of_property_read_u32(node, "num-lanes", &port->lane);
293 if (err) {
294 dev_err(dev, "missing num-lanes property\n");
295 return err;
296 }
297
Honghui Zhang4f6f0462017-08-10 14:34:55 +0800298 regs = platform_get_resource(pdev, IORESOURCE_MEM, slot + 1);
Ryder Lee637cfaca2017-05-21 11:42:24 +0800299 port->base = devm_ioremap_resource(dev, regs);
300 if (IS_ERR(port->base)) {
Honghui Zhang4f6f0462017-08-10 14:34:55 +0800301 dev_err(dev, "failed to map port%d base\n", slot);
Ryder Lee637cfaca2017-05-21 11:42:24 +0800302 return PTR_ERR(port->base);
303 }
304
Honghui Zhang4f6f0462017-08-10 14:34:55 +0800305 snprintf(name, sizeof(name), "sys_ck%d", slot);
Ryder Lee637cfaca2017-05-21 11:42:24 +0800306 port->sys_ck = devm_clk_get(dev, name);
307 if (IS_ERR(port->sys_ck)) {
Honghui Zhang4f6f0462017-08-10 14:34:55 +0800308 dev_err(dev, "failed to get port%d clock\n", slot);
Ryder Lee637cfaca2017-05-21 11:42:24 +0800309 return PTR_ERR(port->sys_ck);
310 }
311
Honghui Zhang4f6f0462017-08-10 14:34:55 +0800312 snprintf(name, sizeof(name), "pcie-rst%d", slot);
Philipp Zabel608fcac2017-07-19 17:26:00 +0200313 port->reset = devm_reset_control_get_optional_exclusive(dev, name);
Ryder Lee637cfaca2017-05-21 11:42:24 +0800314 if (PTR_ERR(port->reset) == -EPROBE_DEFER)
315 return PTR_ERR(port->reset);
316
317 /* some platforms may use default PHY setting */
Honghui Zhang4f6f0462017-08-10 14:34:55 +0800318 snprintf(name, sizeof(name), "pcie-phy%d", slot);
Ryder Lee637cfaca2017-05-21 11:42:24 +0800319 port->phy = devm_phy_optional_get(dev, name);
320 if (IS_ERR(port->phy))
321 return PTR_ERR(port->phy);
322
Honghui Zhang4f6f0462017-08-10 14:34:55 +0800323 port->slot = slot;
Ryder Lee637cfaca2017-05-21 11:42:24 +0800324 port->pcie = pcie;
325
326 INIT_LIST_HEAD(&port->list);
327 list_add_tail(&port->list, &pcie->ports);
328
329 return 0;
330}
331
332static int mtk_pcie_subsys_powerup(struct mtk_pcie *pcie)
333{
334 struct device *dev = pcie->dev;
335 struct platform_device *pdev = to_platform_device(dev);
336 struct resource *regs;
337 int err;
338
339 /* get shared registers */
340 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
341 pcie->base = devm_ioremap_resource(dev, regs);
342 if (IS_ERR(pcie->base)) {
343 dev_err(dev, "failed to map shared register\n");
344 return PTR_ERR(pcie->base);
345 }
346
347 pcie->free_ck = devm_clk_get(dev, "free_ck");
348 if (IS_ERR(pcie->free_ck)) {
349 if (PTR_ERR(pcie->free_ck) == -EPROBE_DEFER)
350 return -EPROBE_DEFER;
351
352 pcie->free_ck = NULL;
353 }
354
355 if (dev->pm_domain) {
356 pm_runtime_enable(dev);
357 pm_runtime_get_sync(dev);
358 }
359
360 /* enable top level clock */
361 err = clk_prepare_enable(pcie->free_ck);
362 if (err) {
363 dev_err(dev, "failed to enable free_ck\n");
364 goto err_free_ck;
365 }
366
367 return 0;
368
369err_free_ck:
370 if (dev->pm_domain) {
371 pm_runtime_put_sync(dev);
372 pm_runtime_disable(dev);
373 }
374
375 return err;
376}
377
378static int mtk_pcie_setup(struct mtk_pcie *pcie)
379{
380 struct device *dev = pcie->dev;
381 struct device_node *node = dev->of_node, *child;
382 struct of_pci_range_parser parser;
383 struct of_pci_range range;
384 struct resource res;
385 struct mtk_pcie_port *port, *tmp;
386 int err;
387
388 if (of_pci_range_parser_init(&parser, node)) {
389 dev_err(dev, "missing \"ranges\" property\n");
390 return -EINVAL;
391 }
392
393 for_each_of_pci_range(&parser, &range) {
394 err = of_pci_range_to_resource(&range, node, &res);
395 if (err < 0)
396 return err;
397
398 switch (res.flags & IORESOURCE_TYPE_BITS) {
399 case IORESOURCE_IO:
400 pcie->offset.io = res.start - range.pci_addr;
401
402 memcpy(&pcie->pio, &res, sizeof(res));
403 pcie->pio.name = node->full_name;
404
405 pcie->io.start = range.cpu_addr;
406 pcie->io.end = range.cpu_addr + range.size - 1;
407 pcie->io.flags = IORESOURCE_MEM;
408 pcie->io.name = "I/O";
409
410 memcpy(&res, &pcie->io, sizeof(res));
411 break;
412
413 case IORESOURCE_MEM:
414 pcie->offset.mem = res.start - range.pci_addr;
415
416 memcpy(&pcie->mem, &res, sizeof(res));
417 pcie->mem.name = "non-prefetchable";
418 break;
419 }
420 }
421
422 err = of_pci_parse_bus_range(node, &pcie->busn);
423 if (err < 0) {
424 dev_err(dev, "failed to parse bus ranges property: %d\n", err);
425 pcie->busn.name = node->name;
426 pcie->busn.start = 0;
427 pcie->busn.end = 0xff;
428 pcie->busn.flags = IORESOURCE_BUS;
429 }
430
431 for_each_available_child_of_node(node, child) {
Honghui Zhang4f6f0462017-08-10 14:34:55 +0800432 int slot;
Ryder Lee637cfaca2017-05-21 11:42:24 +0800433
434 err = of_pci_get_devfn(child);
435 if (err < 0) {
436 dev_err(dev, "failed to parse devfn: %d\n", err);
437 return err;
438 }
439
Honghui Zhang4f6f0462017-08-10 14:34:55 +0800440 slot = PCI_SLOT(err);
Ryder Lee637cfaca2017-05-21 11:42:24 +0800441
Honghui Zhang4f6f0462017-08-10 14:34:55 +0800442 err = mtk_pcie_parse_port(pcie, child, slot);
Ryder Lee637cfaca2017-05-21 11:42:24 +0800443 if (err)
444 return err;
445 }
446
447 err = mtk_pcie_subsys_powerup(pcie);
448 if (err)
449 return err;
450
451 /* enable each port, and then check link status */
452 list_for_each_entry_safe(port, tmp, &pcie->ports, list)
Honghui Zhang4f6f0462017-08-10 14:34:55 +0800453 mtk_pcie_enable_port(port);
Ryder Lee637cfaca2017-05-21 11:42:24 +0800454
455 /* power down PCIe subsys if slots are all empty (link down) */
456 if (list_empty(&pcie->ports))
457 mtk_pcie_subsys_powerdown(pcie);
458
459 return 0;
460}
461
462static int mtk_pcie_request_resources(struct mtk_pcie *pcie)
463{
464 struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
465 struct list_head *windows = &host->windows;
466 struct device *dev = pcie->dev;
467 int err;
468
469 pci_add_resource_offset(windows, &pcie->pio, pcie->offset.io);
470 pci_add_resource_offset(windows, &pcie->mem, pcie->offset.mem);
471 pci_add_resource(windows, &pcie->busn);
472
473 err = devm_request_pci_bus_resources(dev, windows);
474 if (err < 0)
475 return err;
476
477 pci_remap_iospace(&pcie->pio, pcie->io.start);
478
479 return 0;
480}
481
482static int mtk_pcie_register_host(struct pci_host_bridge *host)
483{
484 struct mtk_pcie *pcie = pci_host_bridge_priv(host);
485 struct pci_bus *child;
486 int err;
487
488 host->busnr = pcie->busn.start;
489 host->dev.parent = pcie->dev;
Honghui Zhangc681c932017-08-10 14:34:56 +0800490 host->ops = pcie->soc->ops;
Ryder Lee637cfaca2017-05-21 11:42:24 +0800491 host->map_irq = of_irq_parse_and_map_pci;
492 host->swizzle_irq = pci_common_swizzle;
493
494 err = pci_scan_root_bus_bridge(host);
495 if (err < 0)
496 return err;
497
498 pci_bus_size_bridges(host->bus);
499 pci_bus_assign_resources(host->bus);
500
501 list_for_each_entry(child, &host->bus->children, node)
502 pcie_bus_configure_settings(child);
503
504 pci_bus_add_devices(host->bus);
505
506 return 0;
507}
508
509static int mtk_pcie_probe(struct platform_device *pdev)
510{
511 struct device *dev = &pdev->dev;
512 struct mtk_pcie *pcie;
513 struct pci_host_bridge *host;
514 int err;
515
516 host = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
517 if (!host)
518 return -ENOMEM;
519
520 pcie = pci_host_bridge_priv(host);
521
522 pcie->dev = dev;
Honghui Zhangc681c932017-08-10 14:34:56 +0800523 pcie->soc = of_device_get_match_data(dev);
Ryder Lee637cfaca2017-05-21 11:42:24 +0800524 platform_set_drvdata(pdev, pcie);
525 INIT_LIST_HEAD(&pcie->ports);
526
527 err = mtk_pcie_setup(pcie);
528 if (err)
529 return err;
530
531 err = mtk_pcie_request_resources(pcie);
532 if (err)
533 goto put_resources;
534
535 err = mtk_pcie_register_host(host);
536 if (err)
537 goto put_resources;
538
539 return 0;
540
541put_resources:
542 if (!list_empty(&pcie->ports))
543 mtk_pcie_put_resources(pcie);
544
545 return err;
546}
547
Honghui Zhangc681c932017-08-10 14:34:56 +0800548static const struct mtk_pcie_soc mtk_pcie_soc_v1 = {
549 .ops = &mtk_pcie_ops,
550 .startup = mtk_pcie_startup_port,
551};
552
Ryder Lee637cfaca2017-05-21 11:42:24 +0800553static const struct of_device_id mtk_pcie_ids[] = {
Honghui Zhangc681c932017-08-10 14:34:56 +0800554 { .compatible = "mediatek,mt2701-pcie", .data = &mtk_pcie_soc_v1 },
555 { .compatible = "mediatek,mt7623-pcie", .data = &mtk_pcie_soc_v1 },
Ryder Lee637cfaca2017-05-21 11:42:24 +0800556 {},
557};
558
559static struct platform_driver mtk_pcie_driver = {
560 .probe = mtk_pcie_probe,
561 .driver = {
562 .name = "mtk-pcie",
563 .of_match_table = mtk_pcie_ids,
564 .suppress_bind_attrs = true,
565 },
566};
567builtin_platform_driver(mtk_pcie_driver);