blob: 6285edf4b03707e1ed0324d0d76b561642ec197e [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>
Green Wanba5919b2021-05-27 06:52:10 -070017#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
31struct 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
46enum 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
129static 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
144static 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
154static 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
161static 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
167static 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
174static 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
239static 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
261static 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
270static 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
295static 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
302static 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
328static 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
341static 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
404static 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
433static 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
442static 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
488static const struct dm_pci_ops pcie_sifive_ops = {
489 .read_config = pcie_dw_read_config,
490 .write_config = pcie_dw_write_config,
491};
492
493static const struct udevice_id pcie_sifive_ids[] = {
494 { .compatible = "sifive,fu740-pcie" },
495 {}
496};
497
498U_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};