]> Git Repo - J-u-boot.git/blob - drivers/pci/pcie_dw_sifive.c
pci: Remove <common.h> and add needed includes
[J-u-boot.git] / drivers / pci / pcie_dw_sifive.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * SiFive FU740 DesignWare PCIe Controller
4  *
5  * Copyright (C) 2020-2021 SiFive, Inc.
6  *
7  * Based in early part on the i.MX6 PCIe host controller shim which is:
8  *
9  * Copyright (C) 2013 Kosagi
10  *              http://www.kosagi.com
11  *
12  * Based on driver from author: Alan Mikhak <[email protected]>
13  */
14 #include <asm/io.h>
15 #include <asm-generic/gpio.h>
16 #include <clk.h>
17 #include <dm.h>
18 #include <dm/device_compat.h>
19 #include <generic-phy.h>
20 #include <linux/bitops.h>
21 #include <linux/log2.h>
22 #include <pci.h>
23 #include <pci_ep.h>
24 #include <pci_ids.h>
25 #include <regmap.h>
26 #include <reset.h>
27 #include <syscon.h>
28
29 #include "pcie_dw_common.h"
30
31 struct pcie_sifive {
32         /* Must be first member of the struct */
33         struct pcie_dw dw;
34
35         /* private control regs */
36         void __iomem *priv_base;
37
38         /* reset, power, clock resources */
39         int sys_int_pin;
40         struct gpio_desc pwren_gpio;
41         struct gpio_desc reset_gpio;
42         struct clk aux_ck;
43         struct reset_ctl reset;
44 };
45
46 enum pcie_sifive_devtype {
47         SV_PCIE_UNKNOWN_TYPE = 0,
48         SV_PCIE_ENDPOINT_TYPE = 1,
49         SV_PCIE_HOST_TYPE = 3
50 };
51
52 #define ASSERTION_DELAY         100
53 #define PCIE_PERST_ASSERT       0x0
54 #define PCIE_PERST_DEASSERT     0x1
55 #define PCIE_PHY_RESET          0x1
56 #define PCIE_PHY_RESET_DEASSERT 0x0
57 #define GPIO_LOW                0x0
58 #define GPIO_HIGH               0x1
59 #define PCIE_PHY_SEL            0x1
60
61 #define sv_info(sv, fmt, arg...)        printf(fmt, ## arg)
62 #define sv_warn(sv, fmt, arg...)        printf(fmt, ## arg)
63 #define sv_debug(sv, fmt, arg...)       debug(fmt, ## arg)
64 #define sv_err(sv, fmt, arg...)         printf(fmt, ## arg)
65
66 /* Doorbell Interface */
67 #define DBI_OFFSET                      0x0
68 #define DBI_SIZE                        0x1000
69
70 #define PL_OFFSET                       0x700
71
72 #define PHY_DEBUG_R0                    (PL_OFFSET + 0x28)
73
74 #define PHY_DEBUG_R1                    (PL_OFFSET + 0x2c)
75 #define PHY_DEBUG_R1_LINK_UP            (0x1 << 4)
76 #define PHY_DEBUG_R1_LINK_IN_TRAINING   (0x1 << 29)
77
78 #define PCIE_MISC_CONTROL_1             0x8bc
79 #define DBI_RO_WR_EN                    BIT(0)
80
81 /* pcie reset */
82 #define PCIEX8MGMT_PERST_N              0x0
83
84 /* LTSSM */
85 #define PCIEX8MGMT_APP_LTSSM_ENABLE     0x10
86 #define LTSSM_ENABLE_BIT                BIT(0)
87
88 /* phy reset */
89 #define PCIEX8MGMT_APP_HOLD_PHY_RST     0x18
90
91 /* device type */
92 #define PCIEX8MGMT_DEVICE_TYPE          0x708
93 #define DEVICE_TYPE_EP                  0x0
94 #define DEVICE_TYPE_RC                  0x4
95
96 /* phy control registers*/
97 #define PCIEX8MGMT_PHY0_CR_PARA_ADDR    0x860
98 #define PCIEX8MGMT_PHY0_CR_PARA_RD_EN   0x870
99 #define PCIEX8MGMT_PHY0_CR_PARA_RD_DATA 0x878
100 #define PCIEX8MGMT_PHY0_CR_PARA_SEL     0x880
101 #define PCIEX8MGMT_PHY0_CR_PARA_WR_DATA 0x888
102 #define PCIEX8MGMT_PHY0_CR_PARA_WR_EN   0x890
103 #define PCIEX8MGMT_PHY0_CR_PARA_ACK     0x898
104 #define PCIEX8MGMT_PHY1_CR_PARA_ADDR    0x8a0
105 #define PCIEX8MGMT_PHY1_CR_PARA_RD_EN   0x8b0
106 #define PCIEX8MGMT_PHY1_CR_PARA_RD_DATA 0x8b8
107 #define PCIEX8MGMT_PHY1_CR_PARA_SEL     0x8c0
108 #define PCIEX8MGMT_PHY1_CR_PARA_WR_DATA 0x8c8
109 #define PCIEX8MGMT_PHY1_CR_PARA_WR_EN   0x8d0
110 #define PCIEX8MGMT_PHY1_CR_PARA_ACK     0x8d8
111
112 #define PCIEX8MGMT_LANE_NUM             8
113 #define PCIEX8MGMT_LANE                 0x1008
114 #define PCIEX8MGMT_LANE_OFF             0x100
115 #define PCIEX8MGMT_TERM_MODE            0x0e21
116
117 #define PCIE_CAP_BASE                   0x70
118 #define PCI_CONFIG(r)                   (DBI_OFFSET + (r))
119 #define PCIE_CAPABILITIES(r)            PCI_CONFIG(PCIE_CAP_BASE + (r))
120
121 /* Link capability */
122 #define PF0_PCIE_CAP_LINK_CAP           PCIE_CAPABILITIES(0xc)
123 #define PCIE_LINK_CAP_MAX_SPEED_MASK    0xf
124 #define PCIE_LINK_CAP_MAX_SPEED_GEN1    BIT(0)
125 #define PCIE_LINK_CAP_MAX_SPEED_GEN2    BIT(1)
126 #define PCIE_LINK_CAP_MAX_SPEED_GEN3    BIT(2)
127 #define PCIE_LINK_CAP_MAX_SPEED_GEN4    BIT(3)
128
129 static enum pcie_sifive_devtype pcie_sifive_get_devtype(struct pcie_sifive *sv)
130 {
131         u32 val;
132
133         val = readl(sv->priv_base + PCIEX8MGMT_DEVICE_TYPE);
134         switch (val) {
135         case DEVICE_TYPE_RC:
136                 return SV_PCIE_HOST_TYPE;
137         case DEVICE_TYPE_EP:
138                 return SV_PCIE_ENDPOINT_TYPE;
139         default:
140                 return SV_PCIE_UNKNOWN_TYPE;
141         }
142 }
143
144 static void pcie_sifive_priv_set_state(struct pcie_sifive *sv, u32 reg,
145                                        u32 bits, int state)
146 {
147         u32 val;
148
149         val = readl(sv->priv_base + reg);
150         val = state ? (val | bits) : (val & !bits);
151         writel(val, sv->priv_base + reg);
152 }
153
154 static void pcie_sifive_assert_reset(struct pcie_sifive *sv)
155 {
156         dm_gpio_set_value(&sv->reset_gpio, GPIO_LOW);
157         writel(PCIE_PERST_ASSERT, sv->priv_base + PCIEX8MGMT_PERST_N);
158         mdelay(ASSERTION_DELAY);
159 }
160
161 static void pcie_sifive_power_on(struct pcie_sifive *sv)
162 {
163         dm_gpio_set_value(&sv->pwren_gpio, GPIO_HIGH);
164         mdelay(ASSERTION_DELAY);
165 }
166
167 static void pcie_sifive_deassert_reset(struct pcie_sifive *sv)
168 {
169         writel(PCIE_PERST_DEASSERT, sv->priv_base + PCIEX8MGMT_PERST_N);
170         dm_gpio_set_value(&sv->reset_gpio, GPIO_HIGH);
171         mdelay(ASSERTION_DELAY);
172 }
173
174 static int pcie_sifive_setphy(const u8 phy, const u8 write,
175                               const u16 addr, const u16 wrdata,
176                               u16 *rddata, struct pcie_sifive *sv)
177 {
178         unsigned char ack = 0;
179
180         if (!(phy == 0 || phy == 1))
181                 return -2;
182
183         /* setup phy para */
184         writel(addr, sv->priv_base +
185                (phy ? PCIEX8MGMT_PHY1_CR_PARA_ADDR :
186                 PCIEX8MGMT_PHY0_CR_PARA_ADDR));
187
188         if (write)
189                 writel(wrdata, sv->priv_base +
190                        (phy ? PCIEX8MGMT_PHY1_CR_PARA_WR_DATA :
191                         PCIEX8MGMT_PHY0_CR_PARA_WR_DATA));
192
193         /* enable access if write */
194         if (write)
195                 writel(1, sv->priv_base +
196                        (phy ? PCIEX8MGMT_PHY1_CR_PARA_WR_EN :
197                         PCIEX8MGMT_PHY0_CR_PARA_WR_EN));
198         else
199                 writel(1, sv->priv_base +
200                        (phy ? PCIEX8MGMT_PHY1_CR_PARA_RD_EN :
201                         PCIEX8MGMT_PHY0_CR_PARA_RD_EN));
202
203         /* wait for wait_idle */
204         do {
205                 u32 val;
206
207                 val = readl(sv->priv_base +
208                             (phy ? PCIEX8MGMT_PHY1_CR_PARA_ACK :
209                              PCIEX8MGMT_PHY0_CR_PARA_ACK));
210                 if (val) {
211                         ack = 1;
212                         if (!write)
213                                 readl(sv->priv_base +
214                                       (phy ? PCIEX8MGMT_PHY1_CR_PARA_RD_DATA :
215                                        PCIEX8MGMT_PHY0_CR_PARA_RD_DATA));
216                         mdelay(1);
217                 }
218         } while (!ack);
219
220         /* clear */
221         if (write)
222                 writel(0, sv->priv_base +
223                        (phy ? PCIEX8MGMT_PHY1_CR_PARA_WR_EN :
224                         PCIEX8MGMT_PHY0_CR_PARA_WR_EN));
225         else
226                 writel(0, sv->priv_base +
227                        (phy ? PCIEX8MGMT_PHY1_CR_PARA_RD_EN :
228                         PCIEX8MGMT_PHY0_CR_PARA_RD_EN));
229
230         while (readl(sv->priv_base +
231                      (phy ? PCIEX8MGMT_PHY1_CR_PARA_ACK :
232                       PCIEX8MGMT_PHY0_CR_PARA_ACK))) {
233                 /* wait for ~wait_idle */
234         }
235
236         return 0;
237 }
238
239 static void pcie_sifive_init_phy(struct pcie_sifive *sv)
240 {
241         int lane;
242
243         /* enable phy cr_para_sel interfaces */
244         writel(PCIE_PHY_SEL, sv->priv_base + PCIEX8MGMT_PHY0_CR_PARA_SEL);
245         writel(PCIE_PHY_SEL, sv->priv_base + PCIEX8MGMT_PHY1_CR_PARA_SEL);
246         mdelay(1);
247
248         /* set PHY AC termination mode */
249         for (lane = 0; lane < PCIEX8MGMT_LANE_NUM; lane++) {
250                 pcie_sifive_setphy(0, 1,
251                                    PCIEX8MGMT_LANE +
252                                    (PCIEX8MGMT_LANE_OFF * lane),
253                                    PCIEX8MGMT_TERM_MODE, NULL, sv);
254                 pcie_sifive_setphy(1, 1,
255                                    PCIEX8MGMT_LANE +
256                                    (PCIEX8MGMT_LANE_OFF * lane),
257                                    PCIEX8MGMT_TERM_MODE, NULL, sv);
258         }
259 }
260
261 static int pcie_sifive_check_link(struct pcie_sifive *sv)
262 {
263         u32 val;
264
265         val = readl(sv->dw.dbi_base + PHY_DEBUG_R1);
266         return (val & PHY_DEBUG_R1_LINK_UP) &&
267                 !(val & PHY_DEBUG_R1_LINK_IN_TRAINING);
268 }
269
270 static void pcie_sifive_force_gen1(struct pcie_sifive *sv)
271 {
272         u32 val, linkcap;
273
274         /*
275          * Force Gen1 operation when starting the link. In case the link is
276          * started in Gen2 mode, there is a possibility the devices on the
277          * bus will not be detected at all. This happens with PCIe switches.
278          */
279
280         /* ctrl_ro_wr_enable */
281         val = readl(sv->dw.dbi_base + PCIE_MISC_CONTROL_1);
282         val |= DBI_RO_WR_EN;
283         writel(val, sv->dw.dbi_base + PCIE_MISC_CONTROL_1);
284
285         /* configure link cap */
286         linkcap = readl(sv->dw.dbi_base + PF0_PCIE_CAP_LINK_CAP);
287         linkcap |= PCIE_LINK_CAP_MAX_SPEED_MASK;
288         writel(linkcap, sv->dw.dbi_base + PF0_PCIE_CAP_LINK_CAP);
289
290         /* ctrl_ro_wr_disable */
291         val &= ~DBI_RO_WR_EN;
292         writel(val, sv->dw.dbi_base + PCIE_MISC_CONTROL_1);
293 }
294
295 static void pcie_sifive_print_phy_debug(struct pcie_sifive *sv)
296 {
297         sv_err(sv, "PHY DEBUG_R0=0x%08x DEBUG_R1=0x%08x\n",
298                readl(sv->dw.dbi_base + PHY_DEBUG_R0),
299                readl(sv->dw.dbi_base + PHY_DEBUG_R1));
300 }
301
302 static int pcie_sifive_wait_for_link(struct pcie_sifive *sv)
303 {
304         u32 val;
305         int timeout;
306
307         /* Wait for the link to train */
308         mdelay(20);
309         timeout = 20;
310
311         do {
312                 mdelay(1);
313         } while (--timeout && !pcie_sifive_check_link(sv));
314
315         val = readl(sv->dw.dbi_base + PHY_DEBUG_R1);
316         if (!(val & PHY_DEBUG_R1_LINK_UP) ||
317             (val & PHY_DEBUG_R1_LINK_IN_TRAINING)) {
318                 sv_info(sv, "Failed to negotiate PCIe link!\n");
319                 pcie_sifive_print_phy_debug(sv);
320                 writel(PCIE_PHY_RESET,
321                        sv->priv_base + PCIEX8MGMT_APP_HOLD_PHY_RST);
322                 return -ETIMEDOUT;
323         }
324
325         return 0;
326 }
327
328 static int pcie_sifive_start_link(struct pcie_sifive *sv)
329 {
330         if (pcie_sifive_check_link(sv))
331                 return -EALREADY;
332
333         pcie_sifive_force_gen1(sv);
334
335         /* set ltssm */
336         pcie_sifive_priv_set_state(sv, PCIEX8MGMT_APP_LTSSM_ENABLE,
337                                    LTSSM_ENABLE_BIT, 1);
338         return 0;
339 }
340
341 static int pcie_sifive_init_port(struct udevice *dev,
342                                  enum pcie_sifive_devtype mode)
343 {
344         struct pcie_sifive *sv = dev_get_priv(dev);
345         int ret;
346
347         /* Power on reset */
348         pcie_sifive_assert_reset(sv);
349         pcie_sifive_power_on(sv);
350         pcie_sifive_deassert_reset(sv);
351
352         /* Enable pcieauxclk */
353         ret = clk_enable(&sv->aux_ck);
354         if (ret)
355                 dev_err(dev, "unable to enable pcie_aux clock\n");
356
357         /*
358          * assert hold_phy_rst (hold the controller LTSSM in reset
359          * after power_up_rst_n for register programming with cr_para)
360          */
361         writel(PCIE_PHY_RESET, sv->priv_base + PCIEX8MGMT_APP_HOLD_PHY_RST);
362
363         /* deassert power_up_rst_n */
364         ret = reset_deassert(&sv->reset);
365         if (ret < 0) {
366                 dev_err(dev, "failed to deassert reset");
367                 return -EINVAL;
368         }
369
370         pcie_sifive_init_phy(sv);
371
372         /* disable pcieauxclk */
373         clk_disable(&sv->aux_ck);
374
375         /* deassert hold_phy_rst */
376         writel(PCIE_PHY_RESET_DEASSERT,
377                sv->priv_base + PCIEX8MGMT_APP_HOLD_PHY_RST);
378
379         /* enable pcieauxclk */
380         clk_enable(&sv->aux_ck);
381
382         /* Set desired mode while core is not operational */
383         if (mode == SV_PCIE_HOST_TYPE)
384                 writel(DEVICE_TYPE_RC,
385                        sv->priv_base + PCIEX8MGMT_DEVICE_TYPE);
386         else
387                 writel(DEVICE_TYPE_EP,
388                        sv->priv_base + PCIEX8MGMT_DEVICE_TYPE);
389
390         /* Confirm desired mode from operational core */
391         if (pcie_sifive_get_devtype(sv) != mode)
392                 return -EINVAL;
393
394         pcie_dw_setup_host(&sv->dw);
395
396         if (pcie_sifive_start_link(sv) == -EALREADY)
397                 sv_info(sv, "PCIe link is already up\n");
398         else if (pcie_sifive_wait_for_link(sv) == -ETIMEDOUT)
399                 return -ETIMEDOUT;
400
401         return 0;
402 }
403
404 static int pcie_sifive_probe(struct udevice *dev)
405 {
406         struct pcie_sifive *sv = dev_get_priv(dev);
407         struct udevice *parent = pci_get_controller(dev);
408         struct pci_controller *hose = dev_get_uclass_priv(parent);
409         int err;
410
411         sv->dw.first_busno = dev_seq(dev);
412         sv->dw.dev = dev;
413
414         err = pcie_sifive_init_port(dev, SV_PCIE_HOST_TYPE);
415         if (err) {
416                 sv_info(sv, "Failed to init port.\n");
417                 return err;
418         }
419
420         printf("PCIE-%d: Link up (Gen%d-x%d, Bus%d)\n",
421                dev_seq(dev), pcie_dw_get_link_speed(&sv->dw),
422                pcie_dw_get_link_width(&sv->dw),
423                hose->first_busno);
424
425         return pcie_dw_prog_outbound_atu_unroll(&sv->dw,
426                                                 PCIE_ATU_REGION_INDEX0,
427                                                 PCIE_ATU_TYPE_MEM,
428                                                 sv->dw.mem.phys_start,
429                                                 sv->dw.mem.bus_start,
430                                                 sv->dw.mem.size);
431 }
432
433 static void __iomem *get_fdt_addr(struct udevice *dev, const char *name)
434 {
435         fdt_addr_t addr;
436
437         addr = dev_read_addr_name(dev, name);
438
439         return (addr == FDT_ADDR_T_NONE) ? NULL : (void __iomem *)addr;
440 }
441
442 static int pcie_sifive_of_to_plat(struct udevice *dev)
443 {
444         struct pcie_sifive *sv = dev_get_priv(dev);
445         int err;
446
447         /* get designware DBI base addr */
448         sv->dw.dbi_base = get_fdt_addr(dev, "dbi");
449         if (!sv->dw.dbi_base)
450                 return -EINVAL;
451
452         /* get private control base addr */
453         sv->priv_base = get_fdt_addr(dev, "mgmt");
454         if (!sv->priv_base)
455                 return -EINVAL;
456
457         gpio_request_by_name(dev, "pwren-gpios", 0, &sv->pwren_gpio,
458                              GPIOD_IS_OUT);
459
460         if (!dm_gpio_is_valid(&sv->pwren_gpio)) {
461                 sv_info(sv, "pwren_gpio is invalid\n");
462                 return -EINVAL;
463         }
464
465         gpio_request_by_name(dev, "reset-gpios", 0, &sv->reset_gpio,
466                              GPIOD_IS_OUT);
467
468         if (!dm_gpio_is_valid(&sv->reset_gpio)) {
469                 sv_info(sv, "reset_gpio is invalid\n");
470                 return -EINVAL;
471         }
472
473         err = clk_get_by_index(dev, 0, &sv->aux_ck);
474         if (err) {
475                 sv_info(sv, "clk_get_by_index(aux_ck) failed: %d\n", err);
476                 return err;
477         }
478
479         err = reset_get_by_index(dev, 0, &sv->reset);
480         if (err) {
481                 sv_info(sv, "reset_get_by_index(reset) failed: %d\n", err);
482                 return err;
483         }
484
485         return 0;
486 }
487
488 static const struct dm_pci_ops pcie_sifive_ops = {
489         .read_config    = pcie_dw_read_config,
490         .write_config   = pcie_dw_write_config,
491 };
492
493 static const struct udevice_id pcie_sifive_ids[] = {
494         { .compatible = "sifive,fu740-pcie" },
495         {}
496 };
497
498 U_BOOT_DRIVER(pcie_sifive) = {
499         .name           = "pcie_sifive",
500         .id             = UCLASS_PCI,
501         .of_match       = pcie_sifive_ids,
502         .ops            = &pcie_sifive_ops,
503         .of_to_plat     = pcie_sifive_of_to_plat,
504         .probe          = pcie_sifive_probe,
505         .priv_auto      = sizeof(struct pcie_sifive),
506 };
This page took 0.054203 seconds and 4 git commands to generate.