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