blob: 62a0316ed00948217cd3faced29d92d296b71ea4 [file] [log] [blame]
Minghuan Liana4d6b612014-10-31 13:43:44 +08001/*
Minghuan Lianfdab5452015-01-21 17:29:20 +08002 * Copyright 2014-2015 Freescale Semiconductor, Inc.
Minghuan Liana4d6b612014-10-31 13:43:44 +08003 * Layerscape PCIe driver
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
7
8#include <common.h>
9#include <asm/arch/fsl_serdes.h>
10#include <pci.h>
11#include <asm/io.h>
Minghuan Lianfdab5452015-01-21 17:29:20 +080012#include <errno.h>
13#include <malloc.h>
Minghuan Lianc1067842016-12-13 14:54:17 +080014#include <dm.h>
Mingkai Hu19218992015-11-11 17:58:34 +080015#ifndef CONFIG_LS102XA
Mingkai Hu0e58b512015-10-26 19:47:50 +080016#include <asm/arch/fdt.h>
Mingkai Hu19218992015-11-11 17:58:34 +080017#include <asm/arch/soc.h>
Hou Zhiqiang09716a7b2016-12-13 14:54:16 +080018#else
19#include <asm/arch/immap_ls102xa.h>
Minghuan Lian5d7d24b2015-07-10 11:35:09 +080020#endif
Hou Zhiqiang09716a7b2016-12-13 14:54:16 +080021#include "pcie_layerscape.h"
Minghuan Lianfdab5452015-01-21 17:29:20 +080022
Minghuan Lianc1067842016-12-13 14:54:17 +080023DECLARE_GLOBAL_DATA_PTR;
24
25#ifndef CONFIG_DM_PCI
Minghuan Lianfdab5452015-01-21 17:29:20 +080026#ifdef CONFIG_LS102XA
Minghuan Lianfdab5452015-01-21 17:29:20 +080027/* PEX1/2 Misc Ports Status Register */
28#define LTSSM_STATE_SHIFT 20
Minghuan Lianfdab5452015-01-21 17:29:20 +080029
30static int ls_pcie_link_state(struct ls_pcie *pcie)
31{
32 u32 state;
33 struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR;
34
35 state = in_be32(&scfg->pexmscportsr[pcie->idx]);
36 state = (state >> LTSSM_STATE_SHIFT) & LTSSM_STATE_MASK;
37 if (state < LTSSM_PCIE_L0) {
38 debug("....PCIe link error. LTSSM=0x%02x.\n", state);
39 return 0;
40 }
41
42 return 1;
43}
44#else
Minghuan Lianfdab5452015-01-21 17:29:20 +080045static int ls_pcie_link_state(struct ls_pcie *pcie)
46{
47 u32 state;
48
Mingkai Hu19218992015-11-11 17:58:34 +080049 state = pex_lut_in32(pcie->dbi + PCIE_LUT_BASE + PCIE_LUT_DBG) &
Minghuan Liand2255272015-03-12 10:58:49 +080050 LTSSM_STATE_MASK;
51 if (state < LTSSM_PCIE_L0) {
52 debug("....PCIe link error. LTSSM=0x%02x.\n", state);
53 return 0;
54 }
Minghuan Lianfdab5452015-01-21 17:29:20 +080055
Minghuan Liand2255272015-03-12 10:58:49 +080056 return 1;
Minghuan Lianfdab5452015-01-21 17:29:20 +080057}
58#endif
59
60static int ls_pcie_link_up(struct ls_pcie *pcie)
61{
62 int state;
63 u32 cap;
64
65 state = ls_pcie_link_state(pcie);
66 if (state)
67 return state;
68
69 /* Try to download speed to gen1 */
70 cap = readl(pcie->dbi + PCIE_LINK_CAP);
71 writel((cap & (~PCIE_LINK_SPEED_MASK)) | 1, pcie->dbi + PCIE_LINK_CAP);
Minghuan Liand2255272015-03-12 10:58:49 +080072 /*
73 * Notice: the following delay has critical impact on link training
74 * if too short (<30ms) the link doesn't get up.
75 */
76 mdelay(100);
Minghuan Lianfdab5452015-01-21 17:29:20 +080077 state = ls_pcie_link_state(pcie);
78 if (state)
79 return state;
80
81 writel(cap, pcie->dbi + PCIE_LINK_CAP);
82
83 return 0;
84}
85
86static void ls_pcie_cfg0_set_busdev(struct ls_pcie *pcie, u32 busdev)
87{
88 writel(PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0,
89 pcie->dbi + PCIE_ATU_VIEWPORT);
90 writel(busdev, pcie->dbi + PCIE_ATU_LOWER_TARGET);
91}
92
93static void ls_pcie_cfg1_set_busdev(struct ls_pcie *pcie, u32 busdev)
94{
95 writel(PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1,
96 pcie->dbi + PCIE_ATU_VIEWPORT);
97 writel(busdev, pcie->dbi + PCIE_ATU_LOWER_TARGET);
98}
99
100static void ls_pcie_iatu_outbound_set(struct ls_pcie *pcie, int idx, int type,
101 u64 phys, u64 bus_addr, pci_size_t size)
102{
103 writel(PCIE_ATU_REGION_OUTBOUND | idx, pcie->dbi + PCIE_ATU_VIEWPORT);
104 writel((u32)phys, pcie->dbi + PCIE_ATU_LOWER_BASE);
105 writel(phys >> 32, pcie->dbi + PCIE_ATU_UPPER_BASE);
106 writel(phys + size - 1, pcie->dbi + PCIE_ATU_LIMIT);
107 writel((u32)bus_addr, pcie->dbi + PCIE_ATU_LOWER_TARGET);
108 writel(bus_addr >> 32, pcie->dbi + PCIE_ATU_UPPER_TARGET);
109 writel(type, pcie->dbi + PCIE_ATU_CR1);
110 writel(PCIE_ATU_ENABLE, pcie->dbi + PCIE_ATU_CR2);
111}
112
Minghuan Lian5d7d24b2015-07-10 11:35:09 +0800113/* Use bar match mode and MEM type as default */
114static void ls_pcie_iatu_inbound_set(struct ls_pcie *pcie, int idx,
115 int bar, u64 phys)
116{
117 writel(PCIE_ATU_REGION_INBOUND | idx, pcie->dbi + PCIE_ATU_VIEWPORT);
118 writel((u32)phys, pcie->dbi + PCIE_ATU_LOWER_TARGET);
119 writel(phys >> 32, pcie->dbi + PCIE_ATU_UPPER_TARGET);
120 writel(PCIE_ATU_TYPE_MEM, pcie->dbi + PCIE_ATU_CR1);
121 writel(PCIE_ATU_ENABLE | PCIE_ATU_BAR_MODE_ENABLE |
122 PCIE_ATU_BAR_NUM(bar), pcie->dbi + PCIE_ATU_CR2);
123}
124
Minghuan Lianfdab5452015-01-21 17:29:20 +0800125static void ls_pcie_setup_atu(struct ls_pcie *pcie, struct ls_pcie_info *info)
126{
127#ifdef DEBUG
128 int i;
129#endif
130
131 /* ATU 0 : OUTBOUND : CFG0 */
132 ls_pcie_iatu_outbound_set(pcie, PCIE_ATU_REGION_INDEX0,
133 PCIE_ATU_TYPE_CFG0,
134 info->cfg0_phys,
135 0,
136 info->cfg0_size);
137 /* ATU 1 : OUTBOUND : CFG1 */
138 ls_pcie_iatu_outbound_set(pcie, PCIE_ATU_REGION_INDEX1,
139 PCIE_ATU_TYPE_CFG1,
140 info->cfg1_phys,
141 0,
142 info->cfg1_size);
143 /* ATU 2 : OUTBOUND : MEM */
144 ls_pcie_iatu_outbound_set(pcie, PCIE_ATU_REGION_INDEX2,
145 PCIE_ATU_TYPE_MEM,
146 info->mem_phys,
147 info->mem_bus,
148 info->mem_size);
149 /* ATU 3 : OUTBOUND : IO */
150 ls_pcie_iatu_outbound_set(pcie, PCIE_ATU_REGION_INDEX3,
151 PCIE_ATU_TYPE_IO,
152 info->io_phys,
153 info->io_bus,
154 info->io_size);
155
156#ifdef DEBUG
157 for (i = 0; i <= PCIE_ATU_REGION_INDEX3; i++) {
158 writel(PCIE_ATU_REGION_OUTBOUND | i,
159 pcie->dbi + PCIE_ATU_VIEWPORT);
160 debug("iATU%d:\n", i);
161 debug("\tLOWER PHYS 0x%08x\n",
162 readl(pcie->dbi + PCIE_ATU_LOWER_BASE));
163 debug("\tUPPER PHYS 0x%08x\n",
164 readl(pcie->dbi + PCIE_ATU_UPPER_BASE));
165 debug("\tLOWER BUS 0x%08x\n",
166 readl(pcie->dbi + PCIE_ATU_LOWER_TARGET));
167 debug("\tUPPER BUS 0x%08x\n",
168 readl(pcie->dbi + PCIE_ATU_UPPER_TARGET));
169 debug("\tLIMIT 0x%08x\n",
170 readl(pcie->dbi + PCIE_ATU_LIMIT));
171 debug("\tCR1 0x%08x\n",
172 readl(pcie->dbi + PCIE_ATU_CR1));
173 debug("\tCR2 0x%08x\n",
174 readl(pcie->dbi + PCIE_ATU_CR2));
175 }
176#endif
177}
178
179int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
180{
181 /* Do not skip controller */
182 return 0;
183}
184
185static int ls_pcie_addr_valid(struct pci_controller *hose, pci_dev_t d)
186{
187 if (PCI_DEV(d) > 0)
188 return -EINVAL;
189
Minghuan Liand2255272015-03-12 10:58:49 +0800190 /* Controller does not support multi-function in RC mode */
191 if ((PCI_BUS(d) == hose->first_busno) && (PCI_FUNC(d) > 0))
192 return -EINVAL;
193
Minghuan Lianfdab5452015-01-21 17:29:20 +0800194 return 0;
195}
196
197static int ls_pcie_read_config(struct pci_controller *hose, pci_dev_t d,
198 int where, u32 *val)
199{
200 struct ls_pcie *pcie = hose->priv_data;
201 u32 busdev, *addr;
202
203 if (ls_pcie_addr_valid(hose, d)) {
204 *val = 0xffffffff;
Bin Meng51170a42016-01-08 01:03:21 -0800205 return 0;
Minghuan Lianfdab5452015-01-21 17:29:20 +0800206 }
207
208 if (PCI_BUS(d) == hose->first_busno) {
209 addr = pcie->dbi + (where & ~0x3);
210 } else {
211 busdev = PCIE_ATU_BUS(PCI_BUS(d)) |
212 PCIE_ATU_DEV(PCI_DEV(d)) |
213 PCIE_ATU_FUNC(PCI_FUNC(d));
214
215 if (PCI_BUS(d) == hose->first_busno + 1) {
216 ls_pcie_cfg0_set_busdev(pcie, busdev);
217 addr = pcie->va_cfg0 + (where & ~0x3);
218 } else {
219 ls_pcie_cfg1_set_busdev(pcie, busdev);
220 addr = pcie->va_cfg1 + (where & ~0x3);
221 }
222 }
223
224 *val = readl(addr);
225
226 return 0;
227}
228
229static int ls_pcie_write_config(struct pci_controller *hose, pci_dev_t d,
230 int where, u32 val)
231{
232 struct ls_pcie *pcie = hose->priv_data;
233 u32 busdev, *addr;
234
235 if (ls_pcie_addr_valid(hose, d))
236 return -EINVAL;
237
238 if (PCI_BUS(d) == hose->first_busno) {
239 addr = pcie->dbi + (where & ~0x3);
240 } else {
241 busdev = PCIE_ATU_BUS(PCI_BUS(d)) |
242 PCIE_ATU_DEV(PCI_DEV(d)) |
243 PCIE_ATU_FUNC(PCI_FUNC(d));
244
245 if (PCI_BUS(d) == hose->first_busno + 1) {
246 ls_pcie_cfg0_set_busdev(pcie, busdev);
247 addr = pcie->va_cfg0 + (where & ~0x3);
248 } else {
249 ls_pcie_cfg1_set_busdev(pcie, busdev);
250 addr = pcie->va_cfg1 + (where & ~0x3);
251 }
252 }
253
254 writel(val, addr);
255
256 return 0;
257}
258
259static void ls_pcie_setup_ctrl(struct ls_pcie *pcie,
260 struct ls_pcie_info *info)
261{
262 struct pci_controller *hose = &pcie->hose;
263 pci_dev_t dev = PCI_BDF(hose->first_busno, 0, 0);
264
265 ls_pcie_setup_atu(pcie, info);
266
267 pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_0, 0);
268
269 /* program correct class for RC */
Minghuan Liand2255272015-03-12 10:58:49 +0800270 writel(1, pcie->dbi + PCIE_DBI_RO_WR_EN);
Minghuan Lianfdab5452015-01-21 17:29:20 +0800271 pci_hose_write_config_word(hose, dev, PCI_CLASS_DEVICE,
272 PCI_CLASS_BRIDGE_PCI);
Minghuan Liand2255272015-03-12 10:58:49 +0800273#ifndef CONFIG_LS102XA
274 writel(0, pcie->dbi + PCIE_DBI_RO_WR_EN);
275#endif
Minghuan Lianfdab5452015-01-21 17:29:20 +0800276}
277
Minghuan Lian5d7d24b2015-07-10 11:35:09 +0800278static void ls_pcie_ep_setup_atu(struct ls_pcie *pcie,
279 struct ls_pcie_info *info)
280{
281 u64 phys = CONFIG_SYS_PCI_EP_MEMORY_BASE;
282
283 /* ATU 0 : INBOUND : map BAR0 */
284 ls_pcie_iatu_inbound_set(pcie, PCIE_ATU_REGION_INDEX0, 0, phys);
285 /* ATU 1 : INBOUND : map BAR1 */
286 phys += PCIE_BAR1_SIZE;
287 ls_pcie_iatu_inbound_set(pcie, PCIE_ATU_REGION_INDEX1, 1, phys);
288 /* ATU 2 : INBOUND : map BAR2 */
289 phys += PCIE_BAR2_SIZE;
290 ls_pcie_iatu_inbound_set(pcie, PCIE_ATU_REGION_INDEX2, 2, phys);
291 /* ATU 3 : INBOUND : map BAR4 */
292 phys = CONFIG_SYS_PCI_EP_MEMORY_BASE + PCIE_BAR4_SIZE;
293 ls_pcie_iatu_inbound_set(pcie, PCIE_ATU_REGION_INDEX3, 4, phys);
294
295 /* ATU 0 : OUTBOUND : map 4G MEM */
296 ls_pcie_iatu_outbound_set(pcie, PCIE_ATU_REGION_INDEX0,
297 PCIE_ATU_TYPE_MEM,
298 info->phys_base,
299 0,
300 4 * 1024 * 1024 * 1024ULL);
301}
302
303/* BAR0 and BAR1 are 32bit BAR2 and BAR4 are 64bit */
304static void ls_pcie_ep_setup_bar(void *bar_base, int bar, u32 size)
305{
306 if (size < 4 * 1024)
307 return;
308
309 switch (bar) {
310 case 0:
311 writel(size - 1, bar_base + PCI_BASE_ADDRESS_0);
312 break;
313 case 1:
314 writel(size - 1, bar_base + PCI_BASE_ADDRESS_1);
315 break;
316 case 2:
317 writel(size - 1, bar_base + PCI_BASE_ADDRESS_2);
318 writel(0, bar_base + PCI_BASE_ADDRESS_3);
319 break;
320 case 4:
321 writel(size - 1, bar_base + PCI_BASE_ADDRESS_4);
322 writel(0, bar_base + PCI_BASE_ADDRESS_5);
323 break;
324 default:
325 break;
326 }
327}
328
329static void ls_pcie_ep_setup_bars(void *bar_base)
330{
331 /* BAR0 - 32bit - 4K configuration */
332 ls_pcie_ep_setup_bar(bar_base, 0, PCIE_BAR0_SIZE);
333 /* BAR1 - 32bit - 8K MSIX*/
334 ls_pcie_ep_setup_bar(bar_base, 1, PCIE_BAR1_SIZE);
335 /* BAR2 - 64bit - 4K MEM desciptor */
336 ls_pcie_ep_setup_bar(bar_base, 2, PCIE_BAR2_SIZE);
337 /* BAR4 - 64bit - 1M MEM*/
338 ls_pcie_ep_setup_bar(bar_base, 4, PCIE_BAR4_SIZE);
339}
340
341static void ls_pcie_setup_ep(struct ls_pcie *pcie, struct ls_pcie_info *info)
342{
343 struct pci_controller *hose = &pcie->hose;
344 pci_dev_t dev = PCI_BDF(hose->first_busno, 0, 0);
345 int sriov;
346
347 sriov = pci_hose_find_ext_capability(hose, dev, PCI_EXT_CAP_ID_SRIOV);
348 if (sriov) {
349 int pf, vf;
350
351 for (pf = 0; pf < PCIE_PF_NUM; pf++) {
352 for (vf = 0; vf <= PCIE_VF_NUM; vf++) {
Mingkai Hu19218992015-11-11 17:58:34 +0800353#ifndef CONFIG_LS102XA
Minghuan Lian5d7d24b2015-07-10 11:35:09 +0800354 writel(PCIE_LCTRL0_VAL(pf, vf),
355 pcie->dbi + PCIE_LUT_BASE +
356 PCIE_LUT_LCTRL0);
Mingkai Hu19218992015-11-11 17:58:34 +0800357#endif
Minghuan Lian5d7d24b2015-07-10 11:35:09 +0800358 ls_pcie_ep_setup_bars(pcie->dbi);
359 ls_pcie_ep_setup_atu(pcie, info);
360 }
361 }
362
363 /* Disable CFG2 */
Mingkai Hu19218992015-11-11 17:58:34 +0800364#ifndef CONFIG_LS102XA
Minghuan Lian5d7d24b2015-07-10 11:35:09 +0800365 writel(0, pcie->dbi + PCIE_LUT_BASE + PCIE_LUT_LCTRL0);
Mingkai Hu19218992015-11-11 17:58:34 +0800366#endif
Minghuan Lian5d7d24b2015-07-10 11:35:09 +0800367 } else {
368 ls_pcie_ep_setup_bars(pcie->dbi + PCIE_NO_SRIOV_BAR_BASE);
369 ls_pcie_ep_setup_atu(pcie, info);
370 }
Stuart Yoder45e78ac2016-03-10 10:52:30 -0600371}
372
Minghuan Lianfdab5452015-01-21 17:29:20 +0800373int ls_pcie_init_ctrl(int busno, enum srds_prtcl dev, struct ls_pcie_info *info)
374{
375 struct ls_pcie *pcie;
376 struct pci_controller *hose;
377 int num = dev - PCIE1;
378 pci_dev_t pdev = PCI_BDF(busno, 0, 0);
379 int i, linkup, ep_mode;
380 u8 header_type;
381 u16 temp16;
382
383 if (!is_serdes_configured(dev)) {
384 printf("PCIe%d: disabled\n", num + 1);
385 return busno;
386 }
387
388 pcie = malloc(sizeof(*pcie));
389 if (!pcie)
390 return busno;
391 memset(pcie, 0, sizeof(*pcie));
392
393 hose = &pcie->hose;
394 hose->priv_data = pcie;
395 hose->first_busno = busno;
396 pcie->idx = num;
397 pcie->dbi = map_physmem(info->regs, PCIE_DBI_SIZE, MAP_NOCACHE);
398 pcie->va_cfg0 = map_physmem(info->cfg0_phys,
399 info->cfg0_size,
400 MAP_NOCACHE);
401 pcie->va_cfg1 = map_physmem(info->cfg1_phys,
402 info->cfg1_size,
403 MAP_NOCACHE);
Stuart Yoder45e78ac2016-03-10 10:52:30 -0600404 pcie->next_lut_index = 0;
Minghuan Lianfdab5452015-01-21 17:29:20 +0800405
406 /* outbound memory */
407 pci_set_region(&hose->regions[0],
408 (pci_size_t)info->mem_bus,
409 (phys_size_t)info->mem_phys,
410 (pci_size_t)info->mem_size,
411 PCI_REGION_MEM);
412
413 /* outbound io */
414 pci_set_region(&hose->regions[1],
415 (pci_size_t)info->io_bus,
416 (phys_size_t)info->io_phys,
417 (pci_size_t)info->io_size,
418 PCI_REGION_IO);
419
420 /* System memory space */
421 pci_set_region(&hose->regions[2],
422 CONFIG_SYS_PCI_MEMORY_BUS,
423 CONFIG_SYS_PCI_MEMORY_PHYS,
424 CONFIG_SYS_PCI_MEMORY_SIZE,
425 PCI_REGION_SYS_MEMORY);
426
427 hose->region_count = 3;
428
429 for (i = 0; i < hose->region_count; i++)
430 debug("PCI reg:%d %016llx:%016llx %016llx %08lx\n",
431 i,
432 (u64)hose->regions[i].phys_start,
433 (u64)hose->regions[i].bus_start,
434 (u64)hose->regions[i].size,
435 hose->regions[i].flags);
436
437 pci_set_ops(hose,
438 pci_hose_read_config_byte_via_dword,
439 pci_hose_read_config_word_via_dword,
440 ls_pcie_read_config,
441 pci_hose_write_config_byte_via_dword,
442 pci_hose_write_config_word_via_dword,
443 ls_pcie_write_config);
444
445 pci_hose_read_config_byte(hose, pdev, PCI_HEADER_TYPE, &header_type);
446 ep_mode = (header_type & 0x7f) == PCI_HEADER_TYPE_NORMAL;
447 printf("PCIe%u: %s ", info->pci_num,
448 ep_mode ? "Endpoint" : "Root Complex");
449
Minghuan Lian5d7d24b2015-07-10 11:35:09 +0800450 if (ep_mode)
451 ls_pcie_setup_ep(pcie, info);
452 else
453 ls_pcie_setup_ctrl(pcie, info);
454
Minghuan Lianfdab5452015-01-21 17:29:20 +0800455 linkup = ls_pcie_link_up(pcie);
456
457 if (!linkup) {
458 /* Let the user know there's no PCIe link */
459 printf("no link, regs @ 0x%lx\n", info->regs);
460 hose->last_busno = hose->first_busno;
461 return busno;
462 }
463
464 /* Print the negotiated PCIe link width */
Minghuan Liand2255272015-03-12 10:58:49 +0800465 pci_hose_read_config_word(hose, pdev, PCIE_LINK_STA, &temp16);
466 printf("x%d gen%d, regs @ 0x%lx\n", (temp16 & 0x3f0) >> 4,
467 (temp16 & 0xf), info->regs);
Minghuan Lianfdab5452015-01-21 17:29:20 +0800468
469 if (ep_mode)
470 return busno;
471
Minghuan Lianfdab5452015-01-21 17:29:20 +0800472 pci_register_hose(hose);
473
474 hose->last_busno = pci_hose_scan(hose);
475
476 printf("PCIe%x: Bus %02x - %02x\n",
477 info->pci_num, hose->first_busno, hose->last_busno);
478
479 return hose->last_busno + 1;
480}
481
482int ls_pcie_init_board(int busno)
483{
484 struct ls_pcie_info info;
485
486#ifdef CONFIG_PCIE1
487 SET_LS_PCIE_INFO(info, 1);
488 busno = ls_pcie_init_ctrl(busno, PCIE1, &info);
489#endif
490
491#ifdef CONFIG_PCIE2
492 SET_LS_PCIE_INFO(info, 2);
493 busno = ls_pcie_init_ctrl(busno, PCIE2, &info);
494#endif
495
496#ifdef CONFIG_PCIE3
497 SET_LS_PCIE_INFO(info, 3);
498 busno = ls_pcie_init_ctrl(busno, PCIE3, &info);
499#endif
500
501#ifdef CONFIG_PCIE4
502 SET_LS_PCIE_INFO(info, 4);
503 busno = ls_pcie_init_ctrl(busno, PCIE4, &info);
504#endif
505
506 return busno;
507}
508
509void pci_init_board(void)
510{
511 ls_pcie_init_board(0);
512}
Minghuan Lianc1067842016-12-13 14:54:17 +0800513
514#else
515LIST_HEAD(ls_pcie_list);
516
517static unsigned int dbi_readl(struct ls_pcie *pcie, unsigned int offset)
518{
519 return in_le32(pcie->dbi + offset);
520}
521
522static void dbi_writel(struct ls_pcie *pcie, unsigned int value,
523 unsigned int offset)
524{
525 out_le32(pcie->dbi + offset, value);
526}
527
528static unsigned int ctrl_readl(struct ls_pcie *pcie, unsigned int offset)
529{
530 if (pcie->big_endian)
531 return in_be32(pcie->ctrl + offset);
532 else
533 return in_le32(pcie->ctrl + offset);
534}
535
536static void ctrl_writel(struct ls_pcie *pcie, unsigned int value,
537 unsigned int offset)
538{
539 if (pcie->big_endian)
540 out_be32(pcie->ctrl + offset, value);
541 else
542 out_le32(pcie->ctrl + offset, value);
543}
544
545static int ls_pcie_ltssm(struct ls_pcie *pcie)
546{
547 u32 state;
548 uint svr;
549
550 svr = get_svr();
551 if (((svr >> SVR_VAR_PER_SHIFT) & SVR_LS102XA_MASK) == SVR_LS102XA) {
552 state = ctrl_readl(pcie, LS1021_PEXMSCPORTSR(pcie->idx));
553 state = (state >> LS1021_LTSSM_STATE_SHIFT) & LTSSM_STATE_MASK;
554 } else {
555 state = ctrl_readl(pcie, PCIE_PF_DBG) & LTSSM_STATE_MASK;
556 }
557
558 return state;
559}
560
561static int ls_pcie_link_up(struct ls_pcie *pcie)
562{
563 int ltssm;
564
565 ltssm = ls_pcie_ltssm(pcie);
566 if (ltssm < LTSSM_PCIE_L0)
567 return 0;
568
569 return 1;
570}
571
572static void ls_pcie_cfg0_set_busdev(struct ls_pcie *pcie, u32 busdev)
573{
574 dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0,
575 PCIE_ATU_VIEWPORT);
576 dbi_writel(pcie, busdev, PCIE_ATU_LOWER_TARGET);
577}
578
579static void ls_pcie_cfg1_set_busdev(struct ls_pcie *pcie, u32 busdev)
580{
581 dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1,
582 PCIE_ATU_VIEWPORT);
583 dbi_writel(pcie, busdev, PCIE_ATU_LOWER_TARGET);
584}
585
586static void ls_pcie_atu_outbound_set(struct ls_pcie *pcie, int idx, int type,
587 u64 phys, u64 bus_addr, pci_size_t size)
588{
589 dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND | idx, PCIE_ATU_VIEWPORT);
590 dbi_writel(pcie, (u32)phys, PCIE_ATU_LOWER_BASE);
591 dbi_writel(pcie, phys >> 32, PCIE_ATU_UPPER_BASE);
592 dbi_writel(pcie, (u32)phys + size - 1, PCIE_ATU_LIMIT);
593 dbi_writel(pcie, (u32)bus_addr, PCIE_ATU_LOWER_TARGET);
594 dbi_writel(pcie, bus_addr >> 32, PCIE_ATU_UPPER_TARGET);
595 dbi_writel(pcie, type, PCIE_ATU_CR1);
596 dbi_writel(pcie, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
597}
598
599/* Use bar match mode and MEM type as default */
600static void ls_pcie_atu_inbound_set(struct ls_pcie *pcie, int idx,
601 int bar, u64 phys)
602{
603 dbi_writel(pcie, PCIE_ATU_REGION_INBOUND | idx, PCIE_ATU_VIEWPORT);
604 dbi_writel(pcie, (u32)phys, PCIE_ATU_LOWER_TARGET);
605 dbi_writel(pcie, phys >> 32, PCIE_ATU_UPPER_TARGET);
606 dbi_writel(pcie, PCIE_ATU_TYPE_MEM, PCIE_ATU_CR1);
607 dbi_writel(pcie, PCIE_ATU_ENABLE | PCIE_ATU_BAR_MODE_ENABLE |
608 PCIE_ATU_BAR_NUM(bar), PCIE_ATU_CR2);
609}
610
611static void ls_pcie_dump_atu(struct ls_pcie *pcie)
612{
613 int i;
614
615 for (i = 0; i < PCIE_ATU_REGION_NUM; i++) {
616 dbi_writel(pcie, PCIE_ATU_REGION_OUTBOUND | i,
617 PCIE_ATU_VIEWPORT);
618 debug("iATU%d:\n", i);
619 debug("\tLOWER PHYS 0x%08x\n",
620 dbi_readl(pcie, PCIE_ATU_LOWER_BASE));
621 debug("\tUPPER PHYS 0x%08x\n",
622 dbi_readl(pcie, PCIE_ATU_UPPER_BASE));
623 debug("\tLOWER BUS 0x%08x\n",
624 dbi_readl(pcie, PCIE_ATU_LOWER_TARGET));
625 debug("\tUPPER BUS 0x%08x\n",
626 dbi_readl(pcie, PCIE_ATU_UPPER_TARGET));
627 debug("\tLIMIT 0x%08x\n",
628 readl(pcie->dbi + PCIE_ATU_LIMIT));
629 debug("\tCR1 0x%08x\n",
630 dbi_readl(pcie, PCIE_ATU_CR1));
631 debug("\tCR2 0x%08x\n",
632 dbi_readl(pcie, PCIE_ATU_CR2));
633 }
634}
635
636static void ls_pcie_setup_atu(struct ls_pcie *pcie)
637{
638 struct pci_region *io, *mem, *pref;
639 unsigned long long offset = 0;
640 int idx = 0;
641 uint svr;
642
643 svr = get_svr();
644 if (((svr >> SVR_VAR_PER_SHIFT) & SVR_LS102XA_MASK) == SVR_LS102XA) {
645 offset = LS1021_PCIE_SPACE_OFFSET +
646 LS1021_PCIE_SPACE_SIZE * pcie->idx;
647 }
648
649 /* ATU 0 : OUTBOUND : CFG0 */
650 ls_pcie_atu_outbound_set(pcie, PCIE_ATU_REGION_INDEX0,
651 PCIE_ATU_TYPE_CFG0,
652 pcie->cfg_res.start + offset,
653 0,
654 fdt_resource_size(&pcie->cfg_res) / 2);
655 /* ATU 1 : OUTBOUND : CFG1 */
656 ls_pcie_atu_outbound_set(pcie, PCIE_ATU_REGION_INDEX1,
657 PCIE_ATU_TYPE_CFG1,
658 pcie->cfg_res.start + offset +
659 fdt_resource_size(&pcie->cfg_res) / 2,
660 0,
661 fdt_resource_size(&pcie->cfg_res) / 2);
662
663 pci_get_regions(pcie->bus, &io, &mem, &pref);
664 idx = PCIE_ATU_REGION_INDEX1 + 1;
665
666 if (io)
667 /* ATU : OUTBOUND : IO */
668 ls_pcie_atu_outbound_set(pcie, idx++,
669 PCIE_ATU_TYPE_IO,
670 io->phys_start + offset,
671 io->bus_start,
672 io->size);
673
674 if (mem)
675 /* ATU : OUTBOUND : MEM */
676 ls_pcie_atu_outbound_set(pcie, idx++,
677 PCIE_ATU_TYPE_MEM,
678 mem->phys_start + offset,
679 mem->bus_start,
680 mem->size);
681
682 if (pref)
683 /* ATU : OUTBOUND : pref */
684 ls_pcie_atu_outbound_set(pcie, idx++,
685 PCIE_ATU_TYPE_MEM,
686 pref->phys_start + offset,
687 pref->bus_start,
688 pref->size);
689
690 ls_pcie_dump_atu(pcie);
691}
692
693/* Return 0 if the address is valid, -errno if not valid */
694static int ls_pcie_addr_valid(struct ls_pcie *pcie, pci_dev_t bdf)
695{
696 struct udevice *bus = pcie->bus;
697
698 if (!pcie->enabled)
699 return -ENXIO;
700
701 if (PCI_BUS(bdf) < bus->seq)
702 return -EINVAL;
703
704 if ((PCI_BUS(bdf) > bus->seq) && (!ls_pcie_link_up(pcie)))
705 return -EINVAL;
706
707 if (PCI_BUS(bdf) <= (bus->seq + 1) && (PCI_DEV(bdf) > 0))
708 return -EINVAL;
709
710 return 0;
711}
712
713void *ls_pcie_conf_address(struct ls_pcie *pcie, pci_dev_t bdf,
714 int offset)
715{
716 struct udevice *bus = pcie->bus;
717 u32 busdev;
718
719 if (PCI_BUS(bdf) == bus->seq)
720 return pcie->dbi + offset;
721
722 busdev = PCIE_ATU_BUS(PCI_BUS(bdf)) |
723 PCIE_ATU_DEV(PCI_DEV(bdf)) |
724 PCIE_ATU_FUNC(PCI_FUNC(bdf));
725
726 if (PCI_BUS(bdf) == bus->seq + 1) {
727 ls_pcie_cfg0_set_busdev(pcie, busdev);
728 return pcie->cfg0 + offset;
729 } else {
730 ls_pcie_cfg1_set_busdev(pcie, busdev);
731 return pcie->cfg1 + offset;
732 }
733}
734
735static int ls_pcie_read_config(struct udevice *bus, pci_dev_t bdf,
736 uint offset, ulong *valuep,
737 enum pci_size_t size)
738{
739 struct ls_pcie *pcie = dev_get_priv(bus);
740 void *address;
741
742 if (ls_pcie_addr_valid(pcie, bdf)) {
743 *valuep = pci_get_ff(size);
744 return 0;
745 }
746
747 address = ls_pcie_conf_address(pcie, bdf, offset);
748
749 switch (size) {
750 case PCI_SIZE_8:
751 *valuep = readb(address);
752 return 0;
753 case PCI_SIZE_16:
754 *valuep = readw(address);
755 return 0;
756 case PCI_SIZE_32:
757 *valuep = readl(address);
758 return 0;
759 default:
760 return -EINVAL;
761 }
762}
763
764static int ls_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
765 uint offset, ulong value,
766 enum pci_size_t size)
767{
768 struct ls_pcie *pcie = dev_get_priv(bus);
769 void *address;
770
771 if (ls_pcie_addr_valid(pcie, bdf))
772 return 0;
773
774 address = ls_pcie_conf_address(pcie, bdf, offset);
775
776 switch (size) {
777 case PCI_SIZE_8:
778 writeb(value, address);
779 return 0;
780 case PCI_SIZE_16:
781 writew(value, address);
782 return 0;
783 case PCI_SIZE_32:
784 writel(value, address);
785 return 0;
786 default:
787 return -EINVAL;
788 }
789}
790
791/* Clear multi-function bit */
792static void ls_pcie_clear_multifunction(struct ls_pcie *pcie)
793{
794 writeb(PCI_HEADER_TYPE_BRIDGE, pcie->dbi + PCI_HEADER_TYPE);
795}
796
797/* Fix class value */
798static void ls_pcie_fix_class(struct ls_pcie *pcie)
799{
800 writew(PCI_CLASS_BRIDGE_PCI, pcie->dbi + PCI_CLASS_DEVICE);
801}
802
803/* Drop MSG TLP except for Vendor MSG */
804static void ls_pcie_drop_msg_tlp(struct ls_pcie *pcie)
805{
806 u32 val;
807
808 val = dbi_readl(pcie, PCIE_STRFMR1);
809 val &= 0xDFFFFFFF;
810 dbi_writel(pcie, val, PCIE_STRFMR1);
811}
812
813/* Disable all bars in RC mode */
814static void ls_pcie_disable_bars(struct ls_pcie *pcie)
815{
816 u32 sriov;
817
818 sriov = in_le32(pcie->dbi + PCIE_SRIOV);
819
820 /*
821 * TODO: For PCIe controller with SRIOV, the method to disable bars
822 * is different and more complex, so will add later.
823 */
824 if (PCI_EXT_CAP_ID(sriov) == PCI_EXT_CAP_ID_SRIOV)
825 return;
826
827 dbi_writel(pcie, 0, PCIE_CS2_OFFSET + PCI_BASE_ADDRESS_0);
828 dbi_writel(pcie, 0, PCIE_CS2_OFFSET + PCI_BASE_ADDRESS_1);
829 dbi_writel(pcie, 0, PCIE_CS2_OFFSET + PCI_ROM_ADDRESS1);
830}
831
832static void ls_pcie_setup_ctrl(struct ls_pcie *pcie)
833{
834 ls_pcie_setup_atu(pcie);
835
836 dbi_writel(pcie, 1, PCIE_DBI_RO_WR_EN);
837 ls_pcie_fix_class(pcie);
838 ls_pcie_clear_multifunction(pcie);
839 ls_pcie_drop_msg_tlp(pcie);
840 dbi_writel(pcie, 0, PCIE_DBI_RO_WR_EN);
841
842 ls_pcie_disable_bars(pcie);
843}
844
845static void ls_pcie_ep_setup_atu(struct ls_pcie *pcie)
846{
847 u64 phys = CONFIG_SYS_PCI_EP_MEMORY_BASE;
848
849 /* ATU 0 : INBOUND : map BAR0 */
850 ls_pcie_atu_inbound_set(pcie, 0, 0, phys);
851 /* ATU 1 : INBOUND : map BAR1 */
852 phys += PCIE_BAR1_SIZE;
853 ls_pcie_atu_inbound_set(pcie, 1, 1, phys);
854 /* ATU 2 : INBOUND : map BAR2 */
855 phys += PCIE_BAR2_SIZE;
856 ls_pcie_atu_inbound_set(pcie, 2, 2, phys);
857 /* ATU 3 : INBOUND : map BAR4 */
858 phys = CONFIG_SYS_PCI_EP_MEMORY_BASE + PCIE_BAR4_SIZE;
859 ls_pcie_atu_inbound_set(pcie, 3, 4, phys);
860
861 /* ATU 0 : OUTBOUND : map MEM */
862 ls_pcie_atu_outbound_set(pcie, 0,
863 PCIE_ATU_TYPE_MEM,
864 pcie->cfg_res.start,
865 0,
866 CONFIG_SYS_PCI_MEMORY_SIZE);
867}
868
869/* BAR0 and BAR1 are 32bit BAR2 and BAR4 are 64bit */
870static void ls_pcie_ep_setup_bar(void *bar_base, int bar, u32 size)
871{
872 /* The least inbound window is 4KiB */
873 if (size < 4 * 1024)
874 return;
875
876 switch (bar) {
877 case 0:
878 writel(size - 1, bar_base + PCI_BASE_ADDRESS_0);
879 break;
880 case 1:
881 writel(size - 1, bar_base + PCI_BASE_ADDRESS_1);
882 break;
883 case 2:
884 writel(size - 1, bar_base + PCI_BASE_ADDRESS_2);
885 writel(0, bar_base + PCI_BASE_ADDRESS_3);
886 break;
887 case 4:
888 writel(size - 1, bar_base + PCI_BASE_ADDRESS_4);
889 writel(0, bar_base + PCI_BASE_ADDRESS_5);
890 break;
891 default:
892 break;
893 }
894}
895
896static void ls_pcie_ep_setup_bars(void *bar_base)
897{
898 /* BAR0 - 32bit - 4K configuration */
899 ls_pcie_ep_setup_bar(bar_base, 0, PCIE_BAR0_SIZE);
900 /* BAR1 - 32bit - 8K MSIX*/
901 ls_pcie_ep_setup_bar(bar_base, 1, PCIE_BAR1_SIZE);
902 /* BAR2 - 64bit - 4K MEM desciptor */
903 ls_pcie_ep_setup_bar(bar_base, 2, PCIE_BAR2_SIZE);
904 /* BAR4 - 64bit - 1M MEM*/
905 ls_pcie_ep_setup_bar(bar_base, 4, PCIE_BAR4_SIZE);
906}
907
908static void ls_pcie_setup_ep(struct ls_pcie *pcie)
909{
910 u32 sriov;
911
912 sriov = readl(pcie->dbi + PCIE_SRIOV);
913 if (PCI_EXT_CAP_ID(sriov) == PCI_EXT_CAP_ID_SRIOV) {
914 int pf, vf;
915
916 for (pf = 0; pf < PCIE_PF_NUM; pf++) {
917 for (vf = 0; vf <= PCIE_VF_NUM; vf++) {
918 ctrl_writel(pcie, PCIE_LCTRL0_VAL(pf, vf),
919 PCIE_PF_VF_CTRL);
920
921 ls_pcie_ep_setup_bars(pcie->dbi);
922 ls_pcie_ep_setup_atu(pcie);
923 }
924 }
925 /* Disable CFG2 */
926 ctrl_writel(pcie, 0, PCIE_PF_VF_CTRL);
927 } else {
928 ls_pcie_ep_setup_bars(pcie->dbi + PCIE_NO_SRIOV_BAR_BASE);
929 ls_pcie_ep_setup_atu(pcie);
930 }
931}
932
933static int ls_pcie_probe(struct udevice *dev)
934{
935 struct ls_pcie *pcie = dev_get_priv(dev);
936 const void *fdt = gd->fdt_blob;
937 int node = dev->of_offset;
938 u8 header_type;
939 u16 link_sta;
940 bool ep_mode;
941 int ret;
942
943 pcie->bus = dev;
944
945 ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
946 "dbi", &pcie->dbi_res);
947 if (ret) {
948 printf("ls-pcie: resource \"dbi\" not found\n");
949 return ret;
950 }
951
952 pcie->idx = (pcie->dbi_res.start - PCIE_SYS_BASE_ADDR) / PCIE_CCSR_SIZE;
953
954 list_add(&pcie->list, &ls_pcie_list);
955
956 pcie->enabled = is_serdes_configured(PCIE_SRDS_PRTCL(pcie->idx));
957 if (!pcie->enabled) {
958 printf("PCIe%d: %s disabled\n", pcie->idx, dev->name);
959 return 0;
960 }
961
962 pcie->dbi = map_physmem(pcie->dbi_res.start,
963 fdt_resource_size(&pcie->dbi_res),
964 MAP_NOCACHE);
965
966 ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
967 "lut", &pcie->lut_res);
968 if (!ret)
969 pcie->lut = map_physmem(pcie->lut_res.start,
970 fdt_resource_size(&pcie->lut_res),
971 MAP_NOCACHE);
972
973 ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
974 "ctrl", &pcie->ctrl_res);
975 if (!ret)
976 pcie->ctrl = map_physmem(pcie->ctrl_res.start,
977 fdt_resource_size(&pcie->ctrl_res),
978 MAP_NOCACHE);
979 if (!pcie->ctrl)
980 pcie->ctrl = pcie->lut;
981
982 if (!pcie->ctrl) {
983 printf("%s: NOT find CTRL\n", dev->name);
984 return -1;
985 }
986
987 ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
988 "config", &pcie->cfg_res);
989 if (ret) {
990 printf("%s: resource \"config\" not found\n", dev->name);
991 return ret;
992 }
993
994 pcie->cfg0 = map_physmem(pcie->cfg_res.start,
995 fdt_resource_size(&pcie->cfg_res),
996 MAP_NOCACHE);
997 pcie->cfg1 = pcie->cfg0 + fdt_resource_size(&pcie->cfg_res) / 2;
998
999 pcie->big_endian = fdtdec_get_bool(fdt, node, "big-endian");
1000
1001 debug("%s dbi:%lx lut:%lx ctrl:0x%lx cfg0:0x%lx, big-endian:%d\n",
1002 dev->name, (unsigned long)pcie->dbi, (unsigned long)pcie->lut,
1003 (unsigned long)pcie->ctrl, (unsigned long)pcie->cfg0,
1004 pcie->big_endian);
1005
1006 header_type = readb(pcie->dbi + PCI_HEADER_TYPE);
1007 ep_mode = (header_type & 0x7f) == PCI_HEADER_TYPE_NORMAL;
1008 printf("PCIe%u: %s %s", pcie->idx, dev->name,
1009 ep_mode ? "Endpoint" : "Root Complex");
1010
1011 if (ep_mode)
1012 ls_pcie_setup_ep(pcie);
1013 else
1014 ls_pcie_setup_ctrl(pcie);
1015
1016 if (!ls_pcie_link_up(pcie)) {
1017 /* Let the user know there's no PCIe link */
1018 printf(": no link\n");
1019 return 0;
1020 }
1021
1022 /* Print the negotiated PCIe link width */
1023 link_sta = readw(pcie->dbi + PCIE_LINK_STA);
1024 printf(": x%d gen%d\n", (link_sta & PCIE_LINK_WIDTH_MASK) >> 4,
1025 link_sta & PCIE_LINK_SPEED_MASK);
1026
1027 return 0;
1028}
1029
1030static const struct dm_pci_ops ls_pcie_ops = {
1031 .read_config = ls_pcie_read_config,
1032 .write_config = ls_pcie_write_config,
1033};
1034
1035static const struct udevice_id ls_pcie_ids[] = {
1036 { .compatible = "fsl,ls-pcie" },
1037 { }
1038};
1039
1040U_BOOT_DRIVER(pci_layerscape) = {
1041 .name = "pci_layerscape",
1042 .id = UCLASS_PCI,
1043 .of_match = ls_pcie_ids,
1044 .ops = &ls_pcie_ops,
1045 .probe = ls_pcie_probe,
1046 .priv_auto_alloc_size = sizeof(struct ls_pcie),
1047};
1048#endif /* CONFIG_DM_PCI */