blob: 0e3b4941ab74d1b4a1dd33c565aa5baf775c7f3f [file] [log] [blame]
Minghuan Lianda419022014-10-31 13:43:44 +08001/*
Minghuan Liane4e8cb72015-01-21 17:29:20 +08002 * Copyright 2014-2015 Freescale Semiconductor, Inc.
Minghuan Lianda419022014-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 Liane4e8cb72015-01-21 17:29:20 +080012#include <errno.h>
13#include <malloc.h>
Mingkai Huaf523a02015-11-11 17:58:34 +080014#ifndef CONFIG_LS102XA
Mingkai Hu9f3183d2015-10-26 19:47:50 +080015#include <asm/arch/fdt.h>
Mingkai Huaf523a02015-11-11 17:58:34 +080016#include <asm/arch/soc.h>
Hou Zhiqianga7294ab2016-12-13 14:54:16 +080017#else
18#include <asm/arch/immap_ls102xa.h>
Mingkai Hu9f3183d2015-10-26 19:47:50 +080019#endif
Hou Zhiqianga7294ab2016-12-13 14:54:16 +080020#include "pcie_layerscape.h"
Minghuan Liane4e8cb72015-01-21 17:29:20 +080021
22#ifdef CONFIG_LS102XA
Minghuan Liane4e8cb72015-01-21 17:29:20 +080023/* PEX1/2 Misc Ports Status Register */
24#define LTSSM_STATE_SHIFT 20
Minghuan Liane4e8cb72015-01-21 17:29:20 +080025
26static int ls_pcie_link_state(struct ls_pcie *pcie)
27{
28 u32 state;
29 struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR;
30
31 state = in_be32(&scfg->pexmscportsr[pcie->idx]);
32 state = (state >> LTSSM_STATE_SHIFT) & LTSSM_STATE_MASK;
33 if (state < LTSSM_PCIE_L0) {
34 debug("....PCIe link error. LTSSM=0x%02x.\n", state);
35 return 0;
36 }
37
38 return 1;
39}
40#else
Minghuan Liane4e8cb72015-01-21 17:29:20 +080041static int ls_pcie_link_state(struct ls_pcie *pcie)
42{
43 u32 state;
44
Mingkai Huaf523a02015-11-11 17:58:34 +080045 state = pex_lut_in32(pcie->dbi + PCIE_LUT_BASE + PCIE_LUT_DBG) &
Minghuan Lian00704592015-03-12 10:58:49 +080046 LTSSM_STATE_MASK;
47 if (state < LTSSM_PCIE_L0) {
48 debug("....PCIe link error. LTSSM=0x%02x.\n", state);
49 return 0;
50 }
Minghuan Liane4e8cb72015-01-21 17:29:20 +080051
Minghuan Lian00704592015-03-12 10:58:49 +080052 return 1;
Minghuan Liane4e8cb72015-01-21 17:29:20 +080053}
54#endif
55
56static int ls_pcie_link_up(struct ls_pcie *pcie)
57{
58 int state;
59 u32 cap;
60
61 state = ls_pcie_link_state(pcie);
62 if (state)
63 return state;
64
65 /* Try to download speed to gen1 */
66 cap = readl(pcie->dbi + PCIE_LINK_CAP);
67 writel((cap & (~PCIE_LINK_SPEED_MASK)) | 1, pcie->dbi + PCIE_LINK_CAP);
Minghuan Lian00704592015-03-12 10:58:49 +080068 /*
69 * Notice: the following delay has critical impact on link training
70 * if too short (<30ms) the link doesn't get up.
71 */
72 mdelay(100);
Minghuan Liane4e8cb72015-01-21 17:29:20 +080073 state = ls_pcie_link_state(pcie);
74 if (state)
75 return state;
76
77 writel(cap, pcie->dbi + PCIE_LINK_CAP);
78
79 return 0;
80}
81
82static void ls_pcie_cfg0_set_busdev(struct ls_pcie *pcie, u32 busdev)
83{
84 writel(PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0,
85 pcie->dbi + PCIE_ATU_VIEWPORT);
86 writel(busdev, pcie->dbi + PCIE_ATU_LOWER_TARGET);
87}
88
89static void ls_pcie_cfg1_set_busdev(struct ls_pcie *pcie, u32 busdev)
90{
91 writel(PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1,
92 pcie->dbi + PCIE_ATU_VIEWPORT);
93 writel(busdev, pcie->dbi + PCIE_ATU_LOWER_TARGET);
94}
95
96static void ls_pcie_iatu_outbound_set(struct ls_pcie *pcie, int idx, int type,
97 u64 phys, u64 bus_addr, pci_size_t size)
98{
99 writel(PCIE_ATU_REGION_OUTBOUND | idx, pcie->dbi + PCIE_ATU_VIEWPORT);
100 writel((u32)phys, pcie->dbi + PCIE_ATU_LOWER_BASE);
101 writel(phys >> 32, pcie->dbi + PCIE_ATU_UPPER_BASE);
102 writel(phys + size - 1, pcie->dbi + PCIE_ATU_LIMIT);
103 writel((u32)bus_addr, pcie->dbi + PCIE_ATU_LOWER_TARGET);
104 writel(bus_addr >> 32, pcie->dbi + PCIE_ATU_UPPER_TARGET);
105 writel(type, pcie->dbi + PCIE_ATU_CR1);
106 writel(PCIE_ATU_ENABLE, pcie->dbi + PCIE_ATU_CR2);
107}
108
Minghuan Lian01cafce2015-07-10 11:35:09 +0800109/* Use bar match mode and MEM type as default */
110static void ls_pcie_iatu_inbound_set(struct ls_pcie *pcie, int idx,
111 int bar, u64 phys)
112{
113 writel(PCIE_ATU_REGION_INBOUND | idx, pcie->dbi + PCIE_ATU_VIEWPORT);
114 writel((u32)phys, pcie->dbi + PCIE_ATU_LOWER_TARGET);
115 writel(phys >> 32, pcie->dbi + PCIE_ATU_UPPER_TARGET);
116 writel(PCIE_ATU_TYPE_MEM, pcie->dbi + PCIE_ATU_CR1);
117 writel(PCIE_ATU_ENABLE | PCIE_ATU_BAR_MODE_ENABLE |
118 PCIE_ATU_BAR_NUM(bar), pcie->dbi + PCIE_ATU_CR2);
119}
120
Minghuan Liane4e8cb72015-01-21 17:29:20 +0800121static void ls_pcie_setup_atu(struct ls_pcie *pcie, struct ls_pcie_info *info)
122{
123#ifdef DEBUG
124 int i;
125#endif
126
127 /* ATU 0 : OUTBOUND : CFG0 */
128 ls_pcie_iatu_outbound_set(pcie, PCIE_ATU_REGION_INDEX0,
129 PCIE_ATU_TYPE_CFG0,
130 info->cfg0_phys,
131 0,
132 info->cfg0_size);
133 /* ATU 1 : OUTBOUND : CFG1 */
134 ls_pcie_iatu_outbound_set(pcie, PCIE_ATU_REGION_INDEX1,
135 PCIE_ATU_TYPE_CFG1,
136 info->cfg1_phys,
137 0,
138 info->cfg1_size);
139 /* ATU 2 : OUTBOUND : MEM */
140 ls_pcie_iatu_outbound_set(pcie, PCIE_ATU_REGION_INDEX2,
141 PCIE_ATU_TYPE_MEM,
142 info->mem_phys,
143 info->mem_bus,
144 info->mem_size);
145 /* ATU 3 : OUTBOUND : IO */
146 ls_pcie_iatu_outbound_set(pcie, PCIE_ATU_REGION_INDEX3,
147 PCIE_ATU_TYPE_IO,
148 info->io_phys,
149 info->io_bus,
150 info->io_size);
151
152#ifdef DEBUG
153 for (i = 0; i <= PCIE_ATU_REGION_INDEX3; i++) {
154 writel(PCIE_ATU_REGION_OUTBOUND | i,
155 pcie->dbi + PCIE_ATU_VIEWPORT);
156 debug("iATU%d:\n", i);
157 debug("\tLOWER PHYS 0x%08x\n",
158 readl(pcie->dbi + PCIE_ATU_LOWER_BASE));
159 debug("\tUPPER PHYS 0x%08x\n",
160 readl(pcie->dbi + PCIE_ATU_UPPER_BASE));
161 debug("\tLOWER BUS 0x%08x\n",
162 readl(pcie->dbi + PCIE_ATU_LOWER_TARGET));
163 debug("\tUPPER BUS 0x%08x\n",
164 readl(pcie->dbi + PCIE_ATU_UPPER_TARGET));
165 debug("\tLIMIT 0x%08x\n",
166 readl(pcie->dbi + PCIE_ATU_LIMIT));
167 debug("\tCR1 0x%08x\n",
168 readl(pcie->dbi + PCIE_ATU_CR1));
169 debug("\tCR2 0x%08x\n",
170 readl(pcie->dbi + PCIE_ATU_CR2));
171 }
172#endif
173}
174
175int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
176{
177 /* Do not skip controller */
178 return 0;
179}
180
181static int ls_pcie_addr_valid(struct pci_controller *hose, pci_dev_t d)
182{
183 if (PCI_DEV(d) > 0)
184 return -EINVAL;
185
Minghuan Lian00704592015-03-12 10:58:49 +0800186 /* Controller does not support multi-function in RC mode */
187 if ((PCI_BUS(d) == hose->first_busno) && (PCI_FUNC(d) > 0))
188 return -EINVAL;
189
Minghuan Liane4e8cb72015-01-21 17:29:20 +0800190 return 0;
191}
192
193static int ls_pcie_read_config(struct pci_controller *hose, pci_dev_t d,
194 int where, u32 *val)
195{
196 struct ls_pcie *pcie = hose->priv_data;
197 u32 busdev, *addr;
198
199 if (ls_pcie_addr_valid(hose, d)) {
200 *val = 0xffffffff;
Bin Meng7ba34ff2016-01-08 01:03:21 -0800201 return 0;
Minghuan Liane4e8cb72015-01-21 17:29:20 +0800202 }
203
204 if (PCI_BUS(d) == hose->first_busno) {
205 addr = pcie->dbi + (where & ~0x3);
206 } else {
207 busdev = PCIE_ATU_BUS(PCI_BUS(d)) |
208 PCIE_ATU_DEV(PCI_DEV(d)) |
209 PCIE_ATU_FUNC(PCI_FUNC(d));
210
211 if (PCI_BUS(d) == hose->first_busno + 1) {
212 ls_pcie_cfg0_set_busdev(pcie, busdev);
213 addr = pcie->va_cfg0 + (where & ~0x3);
214 } else {
215 ls_pcie_cfg1_set_busdev(pcie, busdev);
216 addr = pcie->va_cfg1 + (where & ~0x3);
217 }
218 }
219
220 *val = readl(addr);
221
222 return 0;
223}
224
225static int ls_pcie_write_config(struct pci_controller *hose, pci_dev_t d,
226 int where, u32 val)
227{
228 struct ls_pcie *pcie = hose->priv_data;
229 u32 busdev, *addr;
230
231 if (ls_pcie_addr_valid(hose, d))
232 return -EINVAL;
233
234 if (PCI_BUS(d) == hose->first_busno) {
235 addr = pcie->dbi + (where & ~0x3);
236 } else {
237 busdev = PCIE_ATU_BUS(PCI_BUS(d)) |
238 PCIE_ATU_DEV(PCI_DEV(d)) |
239 PCIE_ATU_FUNC(PCI_FUNC(d));
240
241 if (PCI_BUS(d) == hose->first_busno + 1) {
242 ls_pcie_cfg0_set_busdev(pcie, busdev);
243 addr = pcie->va_cfg0 + (where & ~0x3);
244 } else {
245 ls_pcie_cfg1_set_busdev(pcie, busdev);
246 addr = pcie->va_cfg1 + (where & ~0x3);
247 }
248 }
249
250 writel(val, addr);
251
252 return 0;
253}
254
255static void ls_pcie_setup_ctrl(struct ls_pcie *pcie,
256 struct ls_pcie_info *info)
257{
258 struct pci_controller *hose = &pcie->hose;
259 pci_dev_t dev = PCI_BDF(hose->first_busno, 0, 0);
260
261 ls_pcie_setup_atu(pcie, info);
262
263 pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_0, 0);
264
265 /* program correct class for RC */
Minghuan Lian00704592015-03-12 10:58:49 +0800266 writel(1, pcie->dbi + PCIE_DBI_RO_WR_EN);
Minghuan Liane4e8cb72015-01-21 17:29:20 +0800267 pci_hose_write_config_word(hose, dev, PCI_CLASS_DEVICE,
268 PCI_CLASS_BRIDGE_PCI);
Minghuan Lian00704592015-03-12 10:58:49 +0800269#ifndef CONFIG_LS102XA
270 writel(0, pcie->dbi + PCIE_DBI_RO_WR_EN);
271#endif
Minghuan Liane4e8cb72015-01-21 17:29:20 +0800272}
273
Minghuan Lian01cafce2015-07-10 11:35:09 +0800274static void ls_pcie_ep_setup_atu(struct ls_pcie *pcie,
275 struct ls_pcie_info *info)
276{
277 u64 phys = CONFIG_SYS_PCI_EP_MEMORY_BASE;
278
279 /* ATU 0 : INBOUND : map BAR0 */
280 ls_pcie_iatu_inbound_set(pcie, PCIE_ATU_REGION_INDEX0, 0, phys);
281 /* ATU 1 : INBOUND : map BAR1 */
282 phys += PCIE_BAR1_SIZE;
283 ls_pcie_iatu_inbound_set(pcie, PCIE_ATU_REGION_INDEX1, 1, phys);
284 /* ATU 2 : INBOUND : map BAR2 */
285 phys += PCIE_BAR2_SIZE;
286 ls_pcie_iatu_inbound_set(pcie, PCIE_ATU_REGION_INDEX2, 2, phys);
287 /* ATU 3 : INBOUND : map BAR4 */
288 phys = CONFIG_SYS_PCI_EP_MEMORY_BASE + PCIE_BAR4_SIZE;
289 ls_pcie_iatu_inbound_set(pcie, PCIE_ATU_REGION_INDEX3, 4, phys);
290
291 /* ATU 0 : OUTBOUND : map 4G MEM */
292 ls_pcie_iatu_outbound_set(pcie, PCIE_ATU_REGION_INDEX0,
293 PCIE_ATU_TYPE_MEM,
294 info->phys_base,
295 0,
296 4 * 1024 * 1024 * 1024ULL);
297}
298
299/* BAR0 and BAR1 are 32bit BAR2 and BAR4 are 64bit */
300static void ls_pcie_ep_setup_bar(void *bar_base, int bar, u32 size)
301{
302 if (size < 4 * 1024)
303 return;
304
305 switch (bar) {
306 case 0:
307 writel(size - 1, bar_base + PCI_BASE_ADDRESS_0);
308 break;
309 case 1:
310 writel(size - 1, bar_base + PCI_BASE_ADDRESS_1);
311 break;
312 case 2:
313 writel(size - 1, bar_base + PCI_BASE_ADDRESS_2);
314 writel(0, bar_base + PCI_BASE_ADDRESS_3);
315 break;
316 case 4:
317 writel(size - 1, bar_base + PCI_BASE_ADDRESS_4);
318 writel(0, bar_base + PCI_BASE_ADDRESS_5);
319 break;
320 default:
321 break;
322 }
323}
324
325static void ls_pcie_ep_setup_bars(void *bar_base)
326{
327 /* BAR0 - 32bit - 4K configuration */
328 ls_pcie_ep_setup_bar(bar_base, 0, PCIE_BAR0_SIZE);
329 /* BAR1 - 32bit - 8K MSIX*/
330 ls_pcie_ep_setup_bar(bar_base, 1, PCIE_BAR1_SIZE);
331 /* BAR2 - 64bit - 4K MEM desciptor */
332 ls_pcie_ep_setup_bar(bar_base, 2, PCIE_BAR2_SIZE);
333 /* BAR4 - 64bit - 1M MEM*/
334 ls_pcie_ep_setup_bar(bar_base, 4, PCIE_BAR4_SIZE);
335}
336
337static void ls_pcie_setup_ep(struct ls_pcie *pcie, struct ls_pcie_info *info)
338{
339 struct pci_controller *hose = &pcie->hose;
340 pci_dev_t dev = PCI_BDF(hose->first_busno, 0, 0);
341 int sriov;
342
343 sriov = pci_hose_find_ext_capability(hose, dev, PCI_EXT_CAP_ID_SRIOV);
344 if (sriov) {
345 int pf, vf;
346
347 for (pf = 0; pf < PCIE_PF_NUM; pf++) {
348 for (vf = 0; vf <= PCIE_VF_NUM; vf++) {
Mingkai Huaf523a02015-11-11 17:58:34 +0800349#ifndef CONFIG_LS102XA
Minghuan Lian01cafce2015-07-10 11:35:09 +0800350 writel(PCIE_LCTRL0_VAL(pf, vf),
351 pcie->dbi + PCIE_LUT_BASE +
352 PCIE_LUT_LCTRL0);
Mingkai Huaf523a02015-11-11 17:58:34 +0800353#endif
Minghuan Lian01cafce2015-07-10 11:35:09 +0800354 ls_pcie_ep_setup_bars(pcie->dbi);
355 ls_pcie_ep_setup_atu(pcie, info);
356 }
357 }
358
359 /* Disable CFG2 */
Mingkai Huaf523a02015-11-11 17:58:34 +0800360#ifndef CONFIG_LS102XA
Minghuan Lian01cafce2015-07-10 11:35:09 +0800361 writel(0, pcie->dbi + PCIE_LUT_BASE + PCIE_LUT_LCTRL0);
Mingkai Huaf523a02015-11-11 17:58:34 +0800362#endif
Minghuan Lian01cafce2015-07-10 11:35:09 +0800363 } else {
364 ls_pcie_ep_setup_bars(pcie->dbi + PCIE_NO_SRIOV_BAR_BASE);
365 ls_pcie_ep_setup_atu(pcie, info);
366 }
367}
368
Minghuan Liane4e8cb72015-01-21 17:29:20 +0800369int ls_pcie_init_ctrl(int busno, enum srds_prtcl dev, struct ls_pcie_info *info)
370{
371 struct ls_pcie *pcie;
372 struct pci_controller *hose;
373 int num = dev - PCIE1;
374 pci_dev_t pdev = PCI_BDF(busno, 0, 0);
375 int i, linkup, ep_mode;
376 u8 header_type;
377 u16 temp16;
378
379 if (!is_serdes_configured(dev)) {
380 printf("PCIe%d: disabled\n", num + 1);
381 return busno;
382 }
383
384 pcie = malloc(sizeof(*pcie));
385 if (!pcie)
386 return busno;
387 memset(pcie, 0, sizeof(*pcie));
388
389 hose = &pcie->hose;
390 hose->priv_data = pcie;
391 hose->first_busno = busno;
392 pcie->idx = num;
393 pcie->dbi = map_physmem(info->regs, PCIE_DBI_SIZE, MAP_NOCACHE);
394 pcie->va_cfg0 = map_physmem(info->cfg0_phys,
395 info->cfg0_size,
396 MAP_NOCACHE);
397 pcie->va_cfg1 = map_physmem(info->cfg1_phys,
398 info->cfg1_size,
399 MAP_NOCACHE);
Stuart Yoder5e8e27b2016-03-10 10:52:30 -0600400 pcie->next_lut_index = 0;
Minghuan Liane4e8cb72015-01-21 17:29:20 +0800401
402 /* outbound memory */
403 pci_set_region(&hose->regions[0],
404 (pci_size_t)info->mem_bus,
405 (phys_size_t)info->mem_phys,
406 (pci_size_t)info->mem_size,
407 PCI_REGION_MEM);
408
409 /* outbound io */
410 pci_set_region(&hose->regions[1],
411 (pci_size_t)info->io_bus,
412 (phys_size_t)info->io_phys,
413 (pci_size_t)info->io_size,
414 PCI_REGION_IO);
415
416 /* System memory space */
417 pci_set_region(&hose->regions[2],
418 CONFIG_SYS_PCI_MEMORY_BUS,
419 CONFIG_SYS_PCI_MEMORY_PHYS,
420 CONFIG_SYS_PCI_MEMORY_SIZE,
421 PCI_REGION_SYS_MEMORY);
422
423 hose->region_count = 3;
424
425 for (i = 0; i < hose->region_count; i++)
426 debug("PCI reg:%d %016llx:%016llx %016llx %08lx\n",
427 i,
428 (u64)hose->regions[i].phys_start,
429 (u64)hose->regions[i].bus_start,
430 (u64)hose->regions[i].size,
431 hose->regions[i].flags);
432
433 pci_set_ops(hose,
434 pci_hose_read_config_byte_via_dword,
435 pci_hose_read_config_word_via_dword,
436 ls_pcie_read_config,
437 pci_hose_write_config_byte_via_dword,
438 pci_hose_write_config_word_via_dword,
439 ls_pcie_write_config);
440
441 pci_hose_read_config_byte(hose, pdev, PCI_HEADER_TYPE, &header_type);
442 ep_mode = (header_type & 0x7f) == PCI_HEADER_TYPE_NORMAL;
443 printf("PCIe%u: %s ", info->pci_num,
444 ep_mode ? "Endpoint" : "Root Complex");
445
Minghuan Lian01cafce2015-07-10 11:35:09 +0800446 if (ep_mode)
447 ls_pcie_setup_ep(pcie, info);
448 else
449 ls_pcie_setup_ctrl(pcie, info);
450
Minghuan Liane4e8cb72015-01-21 17:29:20 +0800451 linkup = ls_pcie_link_up(pcie);
452
453 if (!linkup) {
454 /* Let the user know there's no PCIe link */
455 printf("no link, regs @ 0x%lx\n", info->regs);
456 hose->last_busno = hose->first_busno;
457 return busno;
458 }
459
460 /* Print the negotiated PCIe link width */
Minghuan Lian00704592015-03-12 10:58:49 +0800461 pci_hose_read_config_word(hose, pdev, PCIE_LINK_STA, &temp16);
462 printf("x%d gen%d, regs @ 0x%lx\n", (temp16 & 0x3f0) >> 4,
463 (temp16 & 0xf), info->regs);
Minghuan Liane4e8cb72015-01-21 17:29:20 +0800464
465 if (ep_mode)
466 return busno;
467
Minghuan Liane4e8cb72015-01-21 17:29:20 +0800468 pci_register_hose(hose);
469
470 hose->last_busno = pci_hose_scan(hose);
471
472 printf("PCIe%x: Bus %02x - %02x\n",
473 info->pci_num, hose->first_busno, hose->last_busno);
474
475 return hose->last_busno + 1;
476}
477
478int ls_pcie_init_board(int busno)
479{
480 struct ls_pcie_info info;
481
482#ifdef CONFIG_PCIE1
483 SET_LS_PCIE_INFO(info, 1);
484 busno = ls_pcie_init_ctrl(busno, PCIE1, &info);
485#endif
486
487#ifdef CONFIG_PCIE2
488 SET_LS_PCIE_INFO(info, 2);
489 busno = ls_pcie_init_ctrl(busno, PCIE2, &info);
490#endif
491
492#ifdef CONFIG_PCIE3
493 SET_LS_PCIE_INFO(info, 3);
494 busno = ls_pcie_init_ctrl(busno, PCIE3, &info);
495#endif
496
497#ifdef CONFIG_PCIE4
498 SET_LS_PCIE_INFO(info, 4);
499 busno = ls_pcie_init_ctrl(busno, PCIE4, &info);
500#endif
501
502 return busno;
503}
504
505void pci_init_board(void)
506{
507 ls_pcie_init_board(0);
508}