aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/controller/dwc/pci-meson.c
diff options
context:
space:
mode:
authorYue Wang <yue.wang@amlogic.com>2018-12-18 03:04:46 -0500
committerLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2018-12-19 05:24:30 -0500
commit9c0ef6d34fdbfb4f948b96d7611f0fd47649044e (patch)
tree46c24483dd3aeb6cd4eb1bb376e527a8ef50e17c /drivers/pci/controller/dwc/pci-meson.c
parent7cd2103911018ecc6f3d2e6239ab5e00fb684d76 (diff)
PCI: amlogic: Add the Amlogic Meson PCIe controller driver
The Amlogic Meson PCIe host controller is based on the Synopsys DesignWare PCI core. This patch adds the driver support for Meson PCIe controller. Link: https://lore.kernel.org/linux-pci/20181218224708.GB22610@google.com/ Signed-off-by: Yue Wang <yue.wang@amlogic.com> Signed-off-by: Hanjie Lin <hanjie.lin@amlogic.com> [lorenzo.pieralisi@arm.com: updated coding/comment style] Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Diffstat (limited to 'drivers/pci/controller/dwc/pci-meson.c')
-rw-r--r--drivers/pci/controller/dwc/pci-meson.c592
1 files changed, 592 insertions, 0 deletions
diff --git a/drivers/pci/controller/dwc/pci-meson.c b/drivers/pci/controller/dwc/pci-meson.c
new file mode 100644
index 000000000000..241ebe0c4505
--- /dev/null
+++ b/drivers/pci/controller/dwc/pci-meson.c
@@ -0,0 +1,592 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * PCIe host controller driver for Amlogic MESON SoCs
4 *
5 * Copyright (c) 2018 Amlogic, inc.
6 * Author: Yue Wang <yue.wang@amlogic.com>
7 */
8
9#include <linux/clk.h>
10#include <linux/delay.h>
11#include <linux/of_device.h>
12#include <linux/of_gpio.h>
13#include <linux/pci.h>
14#include <linux/platform_device.h>
15#include <linux/reset.h>
16#include <linux/resource.h>
17#include <linux/types.h>
18
19#include "pcie-designware.h"
20
21#define to_meson_pcie(x) dev_get_drvdata((x)->dev)
22
23/* External local bus interface registers */
24#define PLR_OFFSET 0x700
25#define PCIE_PORT_LINK_CTRL_OFF (PLR_OFFSET + 0x10)
26#define FAST_LINK_MODE BIT(7)
27#define LINK_CAPABLE_MASK GENMASK(21, 16)
28#define LINK_CAPABLE_X1 BIT(16)
29
30#define PCIE_GEN2_CTRL_OFF (PLR_OFFSET + 0x10c)
31#define NUM_OF_LANES_MASK GENMASK(12, 8)
32#define NUM_OF_LANES_X1 BIT(8)
33#define DIRECT_SPEED_CHANGE BIT(17)
34
35#define TYPE1_HDR_OFFSET 0x0
36#define PCIE_STATUS_COMMAND (TYPE1_HDR_OFFSET + 0x04)
37#define PCI_IO_EN BIT(0)
38#define PCI_MEM_SPACE_EN BIT(1)
39#define PCI_BUS_MASTER_EN BIT(2)
40
41#define PCIE_BASE_ADDR0 (TYPE1_HDR_OFFSET + 0x10)
42#define PCIE_BASE_ADDR1 (TYPE1_HDR_OFFSET + 0x14)
43
44#define PCIE_CAP_OFFSET 0x70
45#define PCIE_DEV_CTRL_DEV_STUS (PCIE_CAP_OFFSET + 0x08)
46#define PCIE_CAP_MAX_PAYLOAD_MASK GENMASK(7, 5)
47#define PCIE_CAP_MAX_PAYLOAD_SIZE(x) ((x) << 5)
48#define PCIE_CAP_MAX_READ_REQ_MASK GENMASK(14, 12)
49#define PCIE_CAP_MAX_READ_REQ_SIZE(x) ((x) << 12)
50
51/* PCIe specific config registers */
52#define PCIE_CFG0 0x0
53#define APP_LTSSM_ENABLE BIT(7)
54
55#define PCIE_CFG_STATUS12 0x30
56#define IS_SMLH_LINK_UP(x) ((x) & (1 << 6))
57#define IS_RDLH_LINK_UP(x) ((x) & (1 << 16))
58#define IS_LTSSM_UP(x) ((((x) >> 10) & 0x1f) == 0x11)
59
60#define PCIE_CFG_STATUS17 0x44
61#define PM_CURRENT_STATE(x) (((x) >> 7) & 0x1)
62
63#define WAIT_LINKUP_TIMEOUT 4000
64#define PORT_CLK_RATE 100000000UL
65#define MAX_PAYLOAD_SIZE 256
66#define MAX_READ_REQ_SIZE 256
67#define MESON_PCIE_PHY_POWERUP 0x1c
68#define PCIE_RESET_DELAY 500
69#define PCIE_SHARED_RESET 1
70#define PCIE_NORMAL_RESET 0
71
72enum pcie_data_rate {
73 PCIE_GEN1,
74 PCIE_GEN2,
75 PCIE_GEN3,
76 PCIE_GEN4
77};
78
79struct meson_pcie_mem_res {
80 void __iomem *elbi_base;
81 void __iomem *cfg_base;
82 void __iomem *phy_base;
83};
84
85struct meson_pcie_clk_res {
86 struct clk *clk;
87 struct clk *mipi_gate;
88 struct clk *port_clk;
89 struct clk *general_clk;
90};
91
92struct meson_pcie_rc_reset {
93 struct reset_control *phy;
94 struct reset_control *port;
95 struct reset_control *apb;
96};
97
98struct meson_pcie {
99 struct dw_pcie pci;
100 struct meson_pcie_mem_res mem_res;
101 struct meson_pcie_clk_res clk_res;
102 struct meson_pcie_rc_reset mrst;
103 struct gpio_desc *reset_gpio;
104};
105
106static struct reset_control *meson_pcie_get_reset(struct meson_pcie *mp,
107 const char *id,
108 u32 reset_type)
109{
110 struct device *dev = mp->pci.dev;
111 struct reset_control *reset;
112
113 if (reset_type == PCIE_SHARED_RESET)
114 reset = devm_reset_control_get_shared(dev, id);
115 else
116 reset = devm_reset_control_get(dev, id);
117
118 return reset;
119}
120
121static int meson_pcie_get_resets(struct meson_pcie *mp)
122{
123 struct meson_pcie_rc_reset *mrst = &mp->mrst;
124
125 mrst->phy = meson_pcie_get_reset(mp, "phy", PCIE_SHARED_RESET);
126 if (IS_ERR(mrst->phy))
127 return PTR_ERR(mrst->phy);
128 reset_control_deassert(mrst->phy);
129
130 mrst->port = meson_pcie_get_reset(mp, "port", PCIE_NORMAL_RESET);
131 if (IS_ERR(mrst->port))
132 return PTR_ERR(mrst->port);
133 reset_control_deassert(mrst->port);
134
135 mrst->apb = meson_pcie_get_reset(mp, "apb", PCIE_SHARED_RESET);
136 if (IS_ERR(mrst->apb))
137 return PTR_ERR(mrst->apb);
138 reset_control_deassert(mrst->apb);
139
140 return 0;
141}
142
143static void __iomem *meson_pcie_get_mem(struct platform_device *pdev,
144 struct meson_pcie *mp,
145 const char *id)
146{
147 struct device *dev = mp->pci.dev;
148 struct resource *res;
149
150 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, id);
151
152 return devm_ioremap_resource(dev, res);
153}
154
155static void __iomem *meson_pcie_get_mem_shared(struct platform_device *pdev,
156 struct meson_pcie *mp,
157 const char *id)
158{
159 struct device *dev = mp->pci.dev;
160 struct resource *res;
161
162 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, id);
163 if (!res) {
164 dev_err(dev, "No REG resource %s\n", id);
165 return ERR_PTR(-ENXIO);
166 }
167
168 return devm_ioremap(dev, res->start, resource_size(res));
169}
170
171static int meson_pcie_get_mems(struct platform_device *pdev,
172 struct meson_pcie *mp)
173{
174 mp->mem_res.elbi_base = meson_pcie_get_mem(pdev, mp, "elbi");
175 if (IS_ERR(mp->mem_res.elbi_base))
176 return PTR_ERR(mp->mem_res.elbi_base);
177
178 mp->mem_res.cfg_base = meson_pcie_get_mem(pdev, mp, "cfg");
179 if (IS_ERR(mp->mem_res.cfg_base))
180 return PTR_ERR(mp->mem_res.cfg_base);
181
182 /* Meson SoC has two PCI controllers use same phy register*/
183 mp->mem_res.phy_base = meson_pcie_get_mem_shared(pdev, mp, "phy");
184 if (IS_ERR(mp->mem_res.phy_base))
185 return PTR_ERR(mp->mem_res.phy_base);
186
187 return 0;
188}
189
190static void meson_pcie_power_on(struct meson_pcie *mp)
191{
192 writel(MESON_PCIE_PHY_POWERUP, mp->mem_res.phy_base);
193}
194
195static void meson_pcie_reset(struct meson_pcie *mp)
196{
197 struct meson_pcie_rc_reset *mrst = &mp->mrst;
198
199 reset_control_assert(mrst->phy);
200 udelay(PCIE_RESET_DELAY);
201 reset_control_deassert(mrst->phy);
202 udelay(PCIE_RESET_DELAY);
203
204 reset_control_assert(mrst->port);
205 reset_control_assert(mrst->apb);
206 udelay(PCIE_RESET_DELAY);
207 reset_control_deassert(mrst->port);
208 reset_control_deassert(mrst->apb);
209 udelay(PCIE_RESET_DELAY);
210}
211
212static inline struct clk *meson_pcie_probe_clock(struct device *dev,
213 const char *id, u64 rate)
214{
215 struct clk *clk;
216 int ret;
217
218 clk = devm_clk_get(dev, id);
219 if (IS_ERR(clk))
220 return clk;
221
222 if (rate) {
223 ret = clk_set_rate(clk, rate);
224 if (ret) {
225 dev_err(dev, "set clk rate failed, ret = %d\n", ret);
226 return ERR_PTR(ret);
227 }
228 }
229
230 ret = clk_prepare_enable(clk);
231 if (ret) {
232 dev_err(dev, "couldn't enable clk\n");
233 return ERR_PTR(ret);
234 }
235
236 devm_add_action_or_reset(dev,
237 (void (*) (void *))clk_disable_unprepare,
238 clk);
239
240 return clk;
241}
242
243static int meson_pcie_probe_clocks(struct meson_pcie *mp)
244{
245 struct device *dev = mp->pci.dev;
246 struct meson_pcie_clk_res *res = &mp->clk_res;
247
248 res->port_clk = meson_pcie_probe_clock(dev, "port", PORT_CLK_RATE);
249 if (IS_ERR(res->port_clk))
250 return PTR_ERR(res->port_clk);
251
252 res->mipi_gate = meson_pcie_probe_clock(dev, "pcie_mipi_en", 0);
253 if (IS_ERR(res->mipi_gate))
254 return PTR_ERR(res->mipi_gate);
255
256 res->general_clk = meson_pcie_probe_clock(dev, "pcie_general", 0);
257 if (IS_ERR(res->general_clk))
258 return PTR_ERR(res->general_clk);
259
260 res->clk = meson_pcie_probe_clock(dev, "pcie", 0);
261 if (IS_ERR(res->clk))
262 return PTR_ERR(res->clk);
263
264 return 0;
265}
266
267static inline void meson_elb_writel(struct meson_pcie *mp, u32 val, u32 reg)
268{
269 writel(val, mp->mem_res.elbi_base + reg);
270}
271
272static inline u32 meson_elb_readl(struct meson_pcie *mp, u32 reg)
273{
274 return readl(mp->mem_res.elbi_base + reg);
275}
276
277static inline u32 meson_cfg_readl(struct meson_pcie *mp, u32 reg)
278{
279 return readl(mp->mem_res.cfg_base + reg);
280}
281
282static inline void meson_cfg_writel(struct meson_pcie *mp, u32 val, u32 reg)
283{
284 writel(val, mp->mem_res.cfg_base + reg);
285}
286
287static void meson_pcie_assert_reset(struct meson_pcie *mp)
288{
289 gpiod_set_value_cansleep(mp->reset_gpio, 0);
290 udelay(500);
291 gpiod_set_value_cansleep(mp->reset_gpio, 1);
292}
293
294static void meson_pcie_init_dw(struct meson_pcie *mp)
295{
296 u32 val;
297
298 val = meson_cfg_readl(mp, PCIE_CFG0);
299 val |= APP_LTSSM_ENABLE;
300 meson_cfg_writel(mp, val, PCIE_CFG0);
301
302 val = meson_elb_readl(mp, PCIE_PORT_LINK_CTRL_OFF);
303 val &= ~LINK_CAPABLE_MASK;
304 meson_elb_writel(mp, val, PCIE_PORT_LINK_CTRL_OFF);
305
306 val = meson_elb_readl(mp, PCIE_PORT_LINK_CTRL_OFF);
307 val |= LINK_CAPABLE_X1 | FAST_LINK_MODE;
308 meson_elb_writel(mp, val, PCIE_PORT_LINK_CTRL_OFF);
309
310 val = meson_elb_readl(mp, PCIE_GEN2_CTRL_OFF);
311 val &= ~NUM_OF_LANES_MASK;
312 meson_elb_writel(mp, val, PCIE_GEN2_CTRL_OFF);
313
314 val = meson_elb_readl(mp, PCIE_GEN2_CTRL_OFF);
315 val |= NUM_OF_LANES_X1 | DIRECT_SPEED_CHANGE;
316 meson_elb_writel(mp, val, PCIE_GEN2_CTRL_OFF);
317
318 meson_elb_writel(mp, 0x0, PCIE_BASE_ADDR0);
319 meson_elb_writel(mp, 0x0, PCIE_BASE_ADDR1);
320}
321
322static int meson_size_to_payload(struct meson_pcie *mp, int size)
323{
324 struct device *dev = mp->pci.dev;
325
326 /*
327 * dwc supports 2^(val+7) payload size, which val is 0~5 default to 1.
328 * So if input size is not 2^order alignment or less than 2^7 or bigger
329 * than 2^12, just set to default size 2^(1+7).
330 */
331 if (!is_power_of_2(size) || size < 128 || size > 4096) {
332 dev_warn(dev, "payload size %d, set to default 256\n", size);
333 return 1;
334 }
335
336 return fls(size) - 8;
337}
338
339static void meson_set_max_payload(struct meson_pcie *mp, int size)
340{
341 u32 val;
342 int max_payload_size = meson_size_to_payload(mp, size);
343
344 val = meson_elb_readl(mp, PCIE_DEV_CTRL_DEV_STUS);
345 val &= ~PCIE_CAP_MAX_PAYLOAD_MASK;
346 meson_elb_writel(mp, val, PCIE_DEV_CTRL_DEV_STUS);
347
348 val = meson_elb_readl(mp, PCIE_DEV_CTRL_DEV_STUS);
349 val |= PCIE_CAP_MAX_PAYLOAD_SIZE(max_payload_size);
350 meson_elb_writel(mp, val, PCIE_DEV_CTRL_DEV_STUS);
351}
352
353static void meson_set_max_rd_req_size(struct meson_pcie *mp, int size)
354{
355 u32 val;
356 int max_rd_req_size = meson_size_to_payload(mp, size);
357
358 val = meson_elb_readl(mp, PCIE_DEV_CTRL_DEV_STUS);
359 val &= ~PCIE_CAP_MAX_READ_REQ_MASK;
360 meson_elb_writel(mp, val, PCIE_DEV_CTRL_DEV_STUS);
361
362 val = meson_elb_readl(mp, PCIE_DEV_CTRL_DEV_STUS);
363 val |= PCIE_CAP_MAX_READ_REQ_SIZE(max_rd_req_size);
364 meson_elb_writel(mp, val, PCIE_DEV_CTRL_DEV_STUS);
365}
366
367static inline void meson_enable_memory_space(struct meson_pcie *mp)
368{
369 /* Set the RC Bus Master, Memory Space and I/O Space enables */
370 meson_elb_writel(mp, PCI_IO_EN | PCI_MEM_SPACE_EN | PCI_BUS_MASTER_EN,
371 PCIE_STATUS_COMMAND);
372}
373
374static int meson_pcie_establish_link(struct meson_pcie *mp)
375{
376 struct dw_pcie *pci = &mp->pci;
377 struct pcie_port *pp = &pci->pp;
378
379 meson_pcie_init_dw(mp);
380 meson_set_max_payload(mp, MAX_PAYLOAD_SIZE);
381 meson_set_max_rd_req_size(mp, MAX_READ_REQ_SIZE);
382
383 dw_pcie_setup_rc(pp);
384 meson_enable_memory_space(mp);
385
386 meson_pcie_assert_reset(mp);
387
388 return dw_pcie_wait_for_link(pci);
389}
390
391static void meson_pcie_enable_interrupts(struct meson_pcie *mp)
392{
393 if (IS_ENABLED(CONFIG_PCI_MSI))
394 dw_pcie_msi_init(&mp->pci.pp);
395}
396
397static int meson_pcie_rd_own_conf(struct pcie_port *pp, int where, int size,
398 u32 *val)
399{
400 struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
401 int ret;
402
403 ret = dw_pcie_read(pci->dbi_base + where, size, val);
404 if (ret != PCIBIOS_SUCCESSFUL)
405 return ret;
406
407 /*
408 * There is a bug in the MESON AXG PCIe controller whereby software
409 * cannot program the PCI_CLASS_DEVICE register, so we must fabricate
410 * the return value in the config accessors.
411 */
412 if (where == PCI_CLASS_REVISION && size == 4)
413 *val = (PCI_CLASS_BRIDGE_PCI << 16) | (*val & 0xffff);
414 else if (where == PCI_CLASS_DEVICE && size == 2)
415 *val = PCI_CLASS_BRIDGE_PCI;
416 else if (where == PCI_CLASS_DEVICE && size == 1)
417 *val = PCI_CLASS_BRIDGE_PCI & 0xff;
418 else if (where == PCI_CLASS_DEVICE + 1 && size == 1)
419 *val = (PCI_CLASS_BRIDGE_PCI >> 8) & 0xff;
420
421 return PCIBIOS_SUCCESSFUL;
422}
423
424static int meson_pcie_wr_own_conf(struct pcie_port *pp, int where,
425 int size, u32 val)
426{
427 struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
428
429 return dw_pcie_write(pci->dbi_base + where, size, val);
430}
431
432static int meson_pcie_link_up(struct dw_pcie *pci)
433{
434 struct meson_pcie *mp = to_meson_pcie(pci);
435 struct device *dev = pci->dev;
436 u32 speed_okay = 0;
437 u32 cnt = 0;
438 u32 state12, state17, smlh_up, ltssm_up, rdlh_up;
439
440 do {
441 state12 = meson_cfg_readl(mp, PCIE_CFG_STATUS12);
442 state17 = meson_cfg_readl(mp, PCIE_CFG_STATUS17);
443 smlh_up = IS_SMLH_LINK_UP(state12);
444 rdlh_up = IS_RDLH_LINK_UP(state12);
445 ltssm_up = IS_LTSSM_UP(state12);
446
447 if (PM_CURRENT_STATE(state17) < PCIE_GEN3)
448 speed_okay = 1;
449
450 if (smlh_up)
451 dev_dbg(dev, "smlh_link_up is on\n");
452 if (rdlh_up)
453 dev_dbg(dev, "rdlh_link_up is on\n");
454 if (ltssm_up)
455 dev_dbg(dev, "ltssm_up is on\n");
456 if (speed_okay)
457 dev_dbg(dev, "speed_okay\n");
458
459 if (smlh_up && rdlh_up && ltssm_up && speed_okay)
460 return 1;
461
462 cnt++;
463
464 udelay(10);
465 } while (cnt < WAIT_LINKUP_TIMEOUT);
466
467 dev_err(dev, "error: wait linkup timeout\n");
468 return 0;
469}
470
471static int meson_pcie_host_init(struct pcie_port *pp)
472{
473 struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
474 struct meson_pcie *mp = to_meson_pcie(pci);
475 int ret;
476
477 ret = meson_pcie_establish_link(mp);
478 if (ret)
479 return ret;
480
481 meson_pcie_enable_interrupts(mp);
482
483 return 0;
484}
485
486static const struct dw_pcie_host_ops meson_pcie_host_ops = {
487 .rd_own_conf = meson_pcie_rd_own_conf,
488 .wr_own_conf = meson_pcie_wr_own_conf,
489 .host_init = meson_pcie_host_init,
490};
491
492static int meson_add_pcie_port(struct meson_pcie *mp,
493 struct platform_device *pdev)
494{
495 struct dw_pcie *pci = &mp->pci;
496 struct pcie_port *pp = &pci->pp;
497 struct device *dev = &pdev->dev;
498 int ret;
499
500 if (IS_ENABLED(CONFIG_PCI_MSI)) {
501 pp->msi_irq = platform_get_irq(pdev, 0);
502 if (pp->msi_irq < 0) {
503 dev_err(dev, "failed to get MSI IRQ\n");
504 return pp->msi_irq;
505 }
506 }
507
508 pp->ops = &meson_pcie_host_ops;
509 pci->dbi_base = mp->mem_res.elbi_base;
510
511 ret = dw_pcie_host_init(pp);
512 if (ret) {
513 dev_err(dev, "failed to initialize host\n");
514 return ret;
515 }
516
517 return 0;
518}
519
520static const struct dw_pcie_ops dw_pcie_ops = {
521 .link_up = meson_pcie_link_up,
522};
523
524static int meson_pcie_probe(struct platform_device *pdev)
525{
526 struct device *dev = &pdev->dev;
527 struct dw_pcie *pci;
528 struct meson_pcie *mp;
529 int ret;
530
531 mp = devm_kzalloc(dev, sizeof(*mp), GFP_KERNEL);
532 if (!mp)
533 return -ENOMEM;
534
535 pci = &mp->pci;
536 pci->dev = dev;
537 pci->ops = &dw_pcie_ops;
538
539 mp->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
540 if (IS_ERR(mp->reset_gpio)) {
541 dev_err(dev, "get reset gpio failed\n");
542 return PTR_ERR(mp->reset_gpio);
543 }
544
545 ret = meson_pcie_get_resets(mp);
546 if (ret) {
547 dev_err(dev, "get reset resource failed, %d\n", ret);
548 return ret;
549 }
550
551 ret = meson_pcie_get_mems(pdev, mp);
552 if (ret) {
553 dev_err(dev, "get memory resource failed, %d\n", ret);
554 return ret;
555 }
556
557 meson_pcie_power_on(mp);
558 meson_pcie_reset(mp);
559
560 ret = meson_pcie_probe_clocks(mp);
561 if (ret) {
562 dev_err(dev, "init clock resources failed, %d\n", ret);
563 return ret;
564 }
565
566 platform_set_drvdata(pdev, mp);
567
568 ret = meson_add_pcie_port(mp, pdev);
569 if (ret < 0) {
570 dev_err(dev, "Add PCIe port failed, %d\n", ret);
571 return ret;
572 }
573
574 return 0;
575}
576
577static const struct of_device_id meson_pcie_of_match[] = {
578 {
579 .compatible = "amlogic,axg-pcie",
580 },
581 {},
582};
583
584static struct platform_driver meson_pcie_driver = {
585 .probe = meson_pcie_probe,
586 .driver = {
587 .name = "meson-pcie",
588 .of_match_table = meson_pcie_of_match,
589 },
590};
591
592builtin_platform_driver(meson_pcie_driver);