1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* |
3 | * BRIEF MODULE DESCRIPTION |
4 | * PCI init for Ralink RT2880 solution |
5 | * |
6 | * Copyright 2007 Ralink Inc. (bruce_chang@ralinktech.com.tw) |
7 | * |
8 | * May 2007 Bruce Chang |
9 | * Initial Release |
10 | * |
11 | * May 2009 Bruce Chang |
12 | * support RT2880/RT3883 PCIe |
13 | * |
14 | * May 2011 Bruce Chang |
15 | * support RT6855/MT7620 PCIe |
16 | */ |
17 | |
18 | #include <linux/bitops.h> |
19 | #include <linux/clk.h> |
20 | #include <linux/delay.h> |
21 | #include <linux/gpio/consumer.h> |
22 | #include <linux/module.h> |
23 | #include <linux/of.h> |
24 | #include <linux/of_address.h> |
25 | #include <linux/of_pci.h> |
26 | #include <linux/of_platform.h> |
27 | #include <linux/pci.h> |
28 | #include <linux/phy/phy.h> |
29 | #include <linux/platform_device.h> |
30 | #include <linux/reset.h> |
31 | #include <linux/sys_soc.h> |
32 | |
33 | #include "../pci.h" |
34 | |
35 | /* MediaTek-specific configuration registers */ |
36 | #define PCIE_FTS_NUM 0x70c |
37 | #define PCIE_FTS_NUM_MASK GENMASK(15, 8) |
38 | #define PCIE_FTS_NUM_L0(x) (((x) & 0xff) << 8) |
39 | |
40 | /* Host-PCI bridge registers */ |
41 | #define RALINK_PCI_PCICFG_ADDR 0x0000 |
42 | #define RALINK_PCI_PCIMSK_ADDR 0x000c |
43 | #define RALINK_PCI_CONFIG_ADDR 0x0020 |
44 | #define RALINK_PCI_CONFIG_DATA 0x0024 |
45 | #define RALINK_PCI_MEMBASE 0x0028 |
46 | #define RALINK_PCI_IOBASE 0x002c |
47 | |
48 | /* PCIe RC control registers */ |
49 | #define RALINK_PCI_ID 0x0030 |
50 | #define RALINK_PCI_CLASS 0x0034 |
51 | #define RALINK_PCI_SUBID 0x0038 |
52 | #define RALINK_PCI_STATUS 0x0050 |
53 | |
54 | /* Some definition values */ |
55 | #define PCIE_REVISION_ID BIT(0) |
56 | #define PCIE_CLASS_CODE (0x60400 << 8) |
57 | #define PCIE_BAR_MAP_MAX GENMASK(30, 16) |
58 | #define PCIE_BAR_ENABLE BIT(0) |
59 | #define PCIE_PORT_INT_EN(x) BIT(20 + (x)) |
60 | #define PCIE_PORT_LINKUP BIT(0) |
61 | #define PCIE_PORT_CNT 3 |
62 | |
63 | #define INIT_PORTS_DELAY_MS 100 |
64 | #define PERST_DELAY_MS 100 |
65 | |
66 | /** |
67 | * struct mt7621_pcie_port - PCIe port information |
68 | * @base: I/O mapped register base |
69 | * @list: port list |
70 | * @pcie: pointer to PCIe host info |
71 | * @clk: pointer to the port clock gate |
72 | * @phy: pointer to PHY control block |
73 | * @pcie_rst: pointer to port reset control |
74 | * @gpio_rst: gpio reset |
75 | * @slot: port slot |
76 | * @enabled: indicates if port is enabled |
77 | */ |
78 | struct mt7621_pcie_port { |
79 | void __iomem *base; |
80 | struct list_head list; |
81 | struct mt7621_pcie *pcie; |
82 | struct clk *clk; |
83 | struct phy *phy; |
84 | struct reset_control *pcie_rst; |
85 | struct gpio_desc *gpio_rst; |
86 | u32 slot; |
87 | bool enabled; |
88 | }; |
89 | |
90 | /** |
91 | * struct mt7621_pcie - PCIe host information |
92 | * @base: IO Mapped Register Base |
93 | * @dev: Pointer to PCIe device |
94 | * @ports: pointer to PCIe port information |
95 | * @resets_inverted: depends on chip revision |
96 | * reset lines are inverted. |
97 | */ |
98 | struct mt7621_pcie { |
99 | struct device *dev; |
100 | void __iomem *base; |
101 | struct list_head ports; |
102 | bool resets_inverted; |
103 | }; |
104 | |
105 | static inline u32 pcie_read(struct mt7621_pcie *pcie, u32 reg) |
106 | { |
107 | return readl_relaxed(pcie->base + reg); |
108 | } |
109 | |
110 | static inline void pcie_write(struct mt7621_pcie *pcie, u32 val, u32 reg) |
111 | { |
112 | writel_relaxed(val, pcie->base + reg); |
113 | } |
114 | |
115 | static inline u32 pcie_port_read(struct mt7621_pcie_port *port, u32 reg) |
116 | { |
117 | return readl_relaxed(port->base + reg); |
118 | } |
119 | |
120 | static inline void pcie_port_write(struct mt7621_pcie_port *port, |
121 | u32 val, u32 reg) |
122 | { |
123 | writel_relaxed(val, port->base + reg); |
124 | } |
125 | |
126 | static void __iomem *mt7621_pcie_map_bus(struct pci_bus *bus, |
127 | unsigned int devfn, int where) |
128 | { |
129 | struct mt7621_pcie *pcie = bus->sysdata; |
130 | u32 address = PCI_CONF1_EXT_ADDRESS(bus->number, PCI_SLOT(devfn), |
131 | PCI_FUNC(devfn), where); |
132 | |
133 | writel_relaxed(address, pcie->base + RALINK_PCI_CONFIG_ADDR); |
134 | |
135 | return pcie->base + RALINK_PCI_CONFIG_DATA + (where & 3); |
136 | } |
137 | |
138 | static struct pci_ops mt7621_pcie_ops = { |
139 | .map_bus = mt7621_pcie_map_bus, |
140 | .read = pci_generic_config_read, |
141 | .write = pci_generic_config_write, |
142 | }; |
143 | |
144 | static u32 read_config(struct mt7621_pcie *pcie, unsigned int dev, u32 reg) |
145 | { |
146 | u32 address = PCI_CONF1_EXT_ADDRESS(0, dev, 0, reg); |
147 | |
148 | pcie_write(pcie, val: address, RALINK_PCI_CONFIG_ADDR); |
149 | return pcie_read(pcie, RALINK_PCI_CONFIG_DATA); |
150 | } |
151 | |
152 | static void write_config(struct mt7621_pcie *pcie, unsigned int dev, |
153 | u32 reg, u32 val) |
154 | { |
155 | u32 address = PCI_CONF1_EXT_ADDRESS(0, dev, 0, reg); |
156 | |
157 | pcie_write(pcie, val: address, RALINK_PCI_CONFIG_ADDR); |
158 | pcie_write(pcie, val, RALINK_PCI_CONFIG_DATA); |
159 | } |
160 | |
161 | static inline void mt7621_rst_gpio_pcie_assert(struct mt7621_pcie_port *port) |
162 | { |
163 | if (port->gpio_rst) |
164 | gpiod_set_value(desc: port->gpio_rst, value: 1); |
165 | } |
166 | |
167 | static inline void mt7621_rst_gpio_pcie_deassert(struct mt7621_pcie_port *port) |
168 | { |
169 | if (port->gpio_rst) |
170 | gpiod_set_value(desc: port->gpio_rst, value: 0); |
171 | } |
172 | |
173 | static inline bool mt7621_pcie_port_is_linkup(struct mt7621_pcie_port *port) |
174 | { |
175 | return (pcie_port_read(port, RALINK_PCI_STATUS) & PCIE_PORT_LINKUP) != 0; |
176 | } |
177 | |
178 | static inline void mt7621_control_assert(struct mt7621_pcie_port *port) |
179 | { |
180 | struct mt7621_pcie *pcie = port->pcie; |
181 | |
182 | if (pcie->resets_inverted) |
183 | reset_control_assert(rstc: port->pcie_rst); |
184 | else |
185 | reset_control_deassert(rstc: port->pcie_rst); |
186 | } |
187 | |
188 | static inline void mt7621_control_deassert(struct mt7621_pcie_port *port) |
189 | { |
190 | struct mt7621_pcie *pcie = port->pcie; |
191 | |
192 | if (pcie->resets_inverted) |
193 | reset_control_deassert(rstc: port->pcie_rst); |
194 | else |
195 | reset_control_assert(rstc: port->pcie_rst); |
196 | } |
197 | |
198 | static int mt7621_pcie_parse_port(struct mt7621_pcie *pcie, |
199 | struct device_node *node, |
200 | int slot) |
201 | { |
202 | struct mt7621_pcie_port *port; |
203 | struct device *dev = pcie->dev; |
204 | struct platform_device *pdev = to_platform_device(dev); |
205 | char name[10]; |
206 | int err; |
207 | |
208 | port = devm_kzalloc(dev, size: sizeof(*port), GFP_KERNEL); |
209 | if (!port) |
210 | return -ENOMEM; |
211 | |
212 | port->base = devm_platform_ioremap_resource(pdev, index: slot + 1); |
213 | if (IS_ERR(ptr: port->base)) |
214 | return PTR_ERR(ptr: port->base); |
215 | |
216 | port->clk = devm_get_clk_from_child(dev, np: node, NULL); |
217 | if (IS_ERR(ptr: port->clk)) { |
218 | dev_err(dev, "failed to get pcie%d clock\n" , slot); |
219 | return PTR_ERR(ptr: port->clk); |
220 | } |
221 | |
222 | port->pcie_rst = of_reset_control_get_exclusive(node, NULL); |
223 | if (PTR_ERR(ptr: port->pcie_rst) == -EPROBE_DEFER) { |
224 | dev_err(dev, "failed to get pcie%d reset control\n" , slot); |
225 | return PTR_ERR(ptr: port->pcie_rst); |
226 | } |
227 | |
228 | snprintf(buf: name, size: sizeof(name), fmt: "pcie-phy%d" , slot); |
229 | port->phy = devm_of_phy_get(dev, np: node, con_id: name); |
230 | if (IS_ERR(ptr: port->phy)) { |
231 | dev_err(dev, "failed to get pcie-phy%d\n" , slot); |
232 | err = PTR_ERR(ptr: port->phy); |
233 | goto remove_reset; |
234 | } |
235 | |
236 | port->gpio_rst = devm_gpiod_get_index_optional(dev, con_id: "reset" , index: slot, |
237 | flags: GPIOD_OUT_LOW); |
238 | if (IS_ERR(ptr: port->gpio_rst)) { |
239 | dev_err(dev, "failed to get GPIO for PCIe%d\n" , slot); |
240 | err = PTR_ERR(ptr: port->gpio_rst); |
241 | goto remove_reset; |
242 | } |
243 | |
244 | port->slot = slot; |
245 | port->pcie = pcie; |
246 | |
247 | INIT_LIST_HEAD(list: &port->list); |
248 | list_add_tail(new: &port->list, head: &pcie->ports); |
249 | |
250 | return 0; |
251 | |
252 | remove_reset: |
253 | reset_control_put(rstc: port->pcie_rst); |
254 | return err; |
255 | } |
256 | |
257 | static int mt7621_pcie_parse_dt(struct mt7621_pcie *pcie) |
258 | { |
259 | struct device *dev = pcie->dev; |
260 | struct platform_device *pdev = to_platform_device(dev); |
261 | struct device_node *node = dev->of_node, *child; |
262 | int err; |
263 | |
264 | pcie->base = devm_platform_ioremap_resource(pdev, index: 0); |
265 | if (IS_ERR(ptr: pcie->base)) |
266 | return PTR_ERR(ptr: pcie->base); |
267 | |
268 | for_each_available_child_of_node(node, child) { |
269 | int slot; |
270 | |
271 | err = of_pci_get_devfn(np: child); |
272 | if (err < 0) { |
273 | of_node_put(node: child); |
274 | dev_err(dev, "failed to parse devfn: %d\n" , err); |
275 | return err; |
276 | } |
277 | |
278 | slot = PCI_SLOT(err); |
279 | |
280 | err = mt7621_pcie_parse_port(pcie, node: child, slot); |
281 | if (err) { |
282 | of_node_put(node: child); |
283 | return err; |
284 | } |
285 | } |
286 | |
287 | return 0; |
288 | } |
289 | |
290 | static int mt7621_pcie_init_port(struct mt7621_pcie_port *port) |
291 | { |
292 | struct mt7621_pcie *pcie = port->pcie; |
293 | struct device *dev = pcie->dev; |
294 | u32 slot = port->slot; |
295 | int err; |
296 | |
297 | err = phy_init(phy: port->phy); |
298 | if (err) { |
299 | dev_err(dev, "failed to initialize port%d phy\n" , slot); |
300 | return err; |
301 | } |
302 | |
303 | err = phy_power_on(phy: port->phy); |
304 | if (err) { |
305 | dev_err(dev, "failed to power on port%d phy\n" , slot); |
306 | phy_exit(phy: port->phy); |
307 | return err; |
308 | } |
309 | |
310 | port->enabled = true; |
311 | |
312 | return 0; |
313 | } |
314 | |
315 | static void mt7621_pcie_reset_assert(struct mt7621_pcie *pcie) |
316 | { |
317 | struct mt7621_pcie_port *port; |
318 | |
319 | list_for_each_entry(port, &pcie->ports, list) { |
320 | /* PCIe RC reset assert */ |
321 | mt7621_control_assert(port); |
322 | |
323 | /* PCIe EP reset assert */ |
324 | mt7621_rst_gpio_pcie_assert(port); |
325 | } |
326 | |
327 | msleep(PERST_DELAY_MS); |
328 | } |
329 | |
330 | static void mt7621_pcie_reset_rc_deassert(struct mt7621_pcie *pcie) |
331 | { |
332 | struct mt7621_pcie_port *port; |
333 | |
334 | list_for_each_entry(port, &pcie->ports, list) |
335 | mt7621_control_deassert(port); |
336 | } |
337 | |
338 | static void mt7621_pcie_reset_ep_deassert(struct mt7621_pcie *pcie) |
339 | { |
340 | struct mt7621_pcie_port *port; |
341 | |
342 | list_for_each_entry(port, &pcie->ports, list) |
343 | mt7621_rst_gpio_pcie_deassert(port); |
344 | |
345 | msleep(PERST_DELAY_MS); |
346 | } |
347 | |
348 | static int mt7621_pcie_init_ports(struct mt7621_pcie *pcie) |
349 | { |
350 | struct device *dev = pcie->dev; |
351 | struct mt7621_pcie_port *port, *tmp; |
352 | u8 num_disabled = 0; |
353 | int err; |
354 | |
355 | mt7621_pcie_reset_assert(pcie); |
356 | mt7621_pcie_reset_rc_deassert(pcie); |
357 | |
358 | list_for_each_entry_safe(port, tmp, &pcie->ports, list) { |
359 | u32 slot = port->slot; |
360 | |
361 | if (slot == 1) { |
362 | port->enabled = true; |
363 | continue; |
364 | } |
365 | |
366 | err = mt7621_pcie_init_port(port); |
367 | if (err) { |
368 | dev_err(dev, "initializing port %d failed\n" , slot); |
369 | list_del(entry: &port->list); |
370 | } |
371 | } |
372 | |
373 | msleep(INIT_PORTS_DELAY_MS); |
374 | mt7621_pcie_reset_ep_deassert(pcie); |
375 | |
376 | tmp = NULL; |
377 | list_for_each_entry(port, &pcie->ports, list) { |
378 | u32 slot = port->slot; |
379 | |
380 | if (!mt7621_pcie_port_is_linkup(port)) { |
381 | dev_info(dev, "pcie%d no card, disable it (RST & CLK)\n" , |
382 | slot); |
383 | mt7621_control_assert(port); |
384 | port->enabled = false; |
385 | num_disabled++; |
386 | |
387 | if (slot == 0) { |
388 | tmp = port; |
389 | continue; |
390 | } |
391 | |
392 | if (slot == 1 && tmp && !tmp->enabled) |
393 | phy_power_off(phy: tmp->phy); |
394 | } |
395 | } |
396 | |
397 | return (num_disabled != PCIE_PORT_CNT) ? 0 : -ENODEV; |
398 | } |
399 | |
400 | static void mt7621_pcie_enable_port(struct mt7621_pcie_port *port) |
401 | { |
402 | struct mt7621_pcie *pcie = port->pcie; |
403 | u32 slot = port->slot; |
404 | u32 val; |
405 | |
406 | /* enable pcie interrupt */ |
407 | val = pcie_read(pcie, RALINK_PCI_PCIMSK_ADDR); |
408 | val |= PCIE_PORT_INT_EN(slot); |
409 | pcie_write(pcie, val, RALINK_PCI_PCIMSK_ADDR); |
410 | |
411 | /* map 2G DDR region */ |
412 | pcie_port_write(port, PCIE_BAR_MAP_MAX | PCIE_BAR_ENABLE, |
413 | PCI_BASE_ADDRESS_0); |
414 | |
415 | /* configure class code and revision ID */ |
416 | pcie_port_write(port, PCIE_CLASS_CODE | PCIE_REVISION_ID, |
417 | RALINK_PCI_CLASS); |
418 | |
419 | /* configure RC FTS number to 250 when it leaves L0s */ |
420 | val = read_config(pcie, dev: slot, PCIE_FTS_NUM); |
421 | val &= ~PCIE_FTS_NUM_MASK; |
422 | val |= PCIE_FTS_NUM_L0(0x50); |
423 | write_config(pcie, dev: slot, PCIE_FTS_NUM, val); |
424 | } |
425 | |
426 | static int mt7621_pcie_enable_ports(struct pci_host_bridge *host) |
427 | { |
428 | struct mt7621_pcie *pcie = pci_host_bridge_priv(bridge: host); |
429 | struct device *dev = pcie->dev; |
430 | struct mt7621_pcie_port *port; |
431 | struct resource_entry *entry; |
432 | int err; |
433 | |
434 | entry = resource_list_first_type(list: &host->windows, IORESOURCE_IO); |
435 | if (!entry) { |
436 | dev_err(dev, "cannot get io resource\n" ); |
437 | return -EINVAL; |
438 | } |
439 | |
440 | /* Setup MEMWIN and IOWIN */ |
441 | pcie_write(pcie, val: 0xffffffff, RALINK_PCI_MEMBASE); |
442 | pcie_write(pcie, val: entry->res->start - entry->offset, RALINK_PCI_IOBASE); |
443 | |
444 | list_for_each_entry(port, &pcie->ports, list) { |
445 | if (port->enabled) { |
446 | err = clk_prepare_enable(clk: port->clk); |
447 | if (err) { |
448 | dev_err(dev, "enabling clk pcie%d\n" , |
449 | port->slot); |
450 | return err; |
451 | } |
452 | |
453 | mt7621_pcie_enable_port(port); |
454 | dev_info(dev, "PCIE%d enabled\n" , port->slot); |
455 | } |
456 | } |
457 | |
458 | return 0; |
459 | } |
460 | |
461 | static int mt7621_pcie_register_host(struct pci_host_bridge *host) |
462 | { |
463 | struct mt7621_pcie *pcie = pci_host_bridge_priv(bridge: host); |
464 | |
465 | host->ops = &mt7621_pcie_ops; |
466 | host->sysdata = pcie; |
467 | return pci_host_probe(bridge: host); |
468 | } |
469 | |
470 | static const struct soc_device_attribute mt7621_pcie_quirks_match[] = { |
471 | { .soc_id = "mt7621" , .revision = "E2" }, |
472 | { /* sentinel */ } |
473 | }; |
474 | |
475 | static int mt7621_pcie_probe(struct platform_device *pdev) |
476 | { |
477 | struct device *dev = &pdev->dev; |
478 | const struct soc_device_attribute *attr; |
479 | struct mt7621_pcie_port *port; |
480 | struct mt7621_pcie *pcie; |
481 | struct pci_host_bridge *bridge; |
482 | int err; |
483 | |
484 | if (!dev->of_node) |
485 | return -ENODEV; |
486 | |
487 | bridge = devm_pci_alloc_host_bridge(dev, priv: sizeof(*pcie)); |
488 | if (!bridge) |
489 | return -ENOMEM; |
490 | |
491 | pcie = pci_host_bridge_priv(bridge); |
492 | pcie->dev = dev; |
493 | platform_set_drvdata(pdev, data: pcie); |
494 | INIT_LIST_HEAD(list: &pcie->ports); |
495 | |
496 | attr = soc_device_match(matches: mt7621_pcie_quirks_match); |
497 | if (attr) |
498 | pcie->resets_inverted = true; |
499 | |
500 | err = mt7621_pcie_parse_dt(pcie); |
501 | if (err) { |
502 | dev_err(dev, "parsing DT failed\n" ); |
503 | return err; |
504 | } |
505 | |
506 | err = mt7621_pcie_init_ports(pcie); |
507 | if (err) { |
508 | dev_err(dev, "nothing connected in virtual bridges\n" ); |
509 | return 0; |
510 | } |
511 | |
512 | err = mt7621_pcie_enable_ports(host: bridge); |
513 | if (err) { |
514 | dev_err(dev, "error enabling pcie ports\n" ); |
515 | goto remove_resets; |
516 | } |
517 | |
518 | return mt7621_pcie_register_host(host: bridge); |
519 | |
520 | remove_resets: |
521 | list_for_each_entry(port, &pcie->ports, list) |
522 | reset_control_put(rstc: port->pcie_rst); |
523 | |
524 | return err; |
525 | } |
526 | |
527 | static void mt7621_pcie_remove(struct platform_device *pdev) |
528 | { |
529 | struct mt7621_pcie *pcie = platform_get_drvdata(pdev); |
530 | struct mt7621_pcie_port *port; |
531 | |
532 | list_for_each_entry(port, &pcie->ports, list) |
533 | reset_control_put(rstc: port->pcie_rst); |
534 | } |
535 | |
536 | static const struct of_device_id mt7621_pcie_ids[] = { |
537 | { .compatible = "mediatek,mt7621-pci" }, |
538 | {}, |
539 | }; |
540 | MODULE_DEVICE_TABLE(of, mt7621_pcie_ids); |
541 | |
542 | static struct platform_driver mt7621_pcie_driver = { |
543 | .probe = mt7621_pcie_probe, |
544 | .remove_new = mt7621_pcie_remove, |
545 | .driver = { |
546 | .name = "mt7621-pci" , |
547 | .of_match_table = mt7621_pcie_ids, |
548 | }, |
549 | }; |
550 | builtin_platform_driver(mt7621_pcie_driver); |
551 | |
552 | MODULE_LICENSE("GPL v2" ); |
553 | |