1
2
3
4
5
6
7#include <common.h>
8#include <spl.h>
9#include <asm/io.h>
10#include <asm/arch/cpu.h>
11#include <asm/arch/soc.h>
12
13#include "ctrl_pex.h"
14#include "sys_env_lib.h"
15
16__weak void board_pex_config(void)
17{
18
19}
20
21int hws_pex_config(const struct serdes_map *serdes_map, u8 count)
22{
23 u32 pex_idx, tmp, next_busno, first_busno, temp_pex_reg,
24 temp_reg, addr, dev_id, ctrl_mode;
25 enum serdes_type serdes_type;
26 u32 idx;
27
28 DEBUG_INIT_FULL_S("\n### hws_pex_config ###\n");
29
30 for (idx = 0; idx < count; idx++) {
31 serdes_type = serdes_map[idx].serdes_type;
32
33 if ((serdes_type != PEX0) && (serdes_type != PEX1) &&
34 (serdes_type != PEX2) && (serdes_type != PEX3))
35 continue;
36
37 if ((serdes_type != PEX0) &&
38 ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
39 (serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
40
41 continue;
42 }
43
44 pex_idx = serdes_type - PEX0;
45 tmp = reg_read(PEX_CAPABILITIES_REG(pex_idx));
46 tmp &= ~(0xf << 20);
47 tmp |= (0x4 << 20);
48 reg_write(PEX_CAPABILITIES_REG(pex_idx), tmp);
49 }
50
51 tmp = reg_read(SOC_CTRL_REG);
52 tmp &= ~0x03;
53
54 for (idx = 0; idx < count; idx++) {
55 serdes_type = serdes_map[idx].serdes_type;
56 if ((serdes_type != PEX0) &&
57 ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
58 (serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
59
60 continue;
61 }
62
63 switch (serdes_type) {
64 case PEX0:
65 tmp |= 0x1 << PCIE0_ENABLE_OFFS;
66 break;
67 case PEX1:
68 tmp |= 0x1 << PCIE1_ENABLE_OFFS;
69 break;
70 case PEX2:
71 tmp |= 0x1 << PCIE2_ENABLE_OFFS;
72 break;
73 case PEX3:
74 tmp |= 0x1 << PCIE3_ENABLE_OFFS;
75 break;
76 default:
77 break;
78 }
79 }
80
81 reg_write(SOC_CTRL_REG, tmp);
82
83
84 DEBUG_INIT_FULL_S("Support gen1/gen2\n");
85
86 board_pex_config();
87
88 next_busno = 0;
89 mdelay(150);
90
91 for (idx = 0; idx < count; idx++) {
92 serdes_type = serdes_map[idx].serdes_type;
93 DEBUG_INIT_FULL_S(" serdes_type=0x");
94 DEBUG_INIT_FULL_D(serdes_type, 8);
95 DEBUG_INIT_FULL_S("\n");
96 DEBUG_INIT_FULL_S(" idx=0x");
97 DEBUG_INIT_FULL_D(idx, 8);
98 DEBUG_INIT_FULL_S("\n");
99
100
101 if ((serdes_type != PEX0) && (serdes_type != PEX1) &&
102 (serdes_type != PEX2) && (serdes_type != PEX3))
103 continue;
104
105 if ((serdes_type != PEX0) &&
106 ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
107 (serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
108
109 continue;
110 }
111
112 pex_idx = serdes_type - PEX0;
113 tmp = reg_read(PEX_DBG_STATUS_REG(pex_idx));
114
115 first_busno = next_busno;
116 if ((tmp & 0x7f) != 0x7e) {
117 DEBUG_INIT_S("PCIe, Idx ");
118 DEBUG_INIT_D(pex_idx, 1);
119 DEBUG_INIT_S(": detected no link\n");
120 continue;
121 }
122
123 next_busno++;
124 temp_pex_reg = reg_read((PEX_CFG_DIRECT_ACCESS
125 (pex_idx, PEX_LINK_CAPABILITY_REG)));
126 temp_pex_reg &= 0xf;
127 if (temp_pex_reg != 0x2)
128 continue;
129
130 temp_reg = (reg_read(PEX_CFG_DIRECT_ACCESS(
131 pex_idx,
132 PEX_LINK_CTRL_STAT_REG)) &
133 0xf0000) >> 16;
134
135
136 DEBUG_INIT_FULL_S
137 ("Checking if the link established is gen1\n");
138 if (temp_reg != 0x1)
139 continue;
140
141 pex_local_bus_num_set(pex_idx, first_busno);
142 pex_local_dev_num_set(pex_idx, 1);
143 DEBUG_INIT_FULL_S("PCIe, Idx ");
144 DEBUG_INIT_FULL_D(pex_idx, 1);
145
146 DEBUG_INIT_S(":** Link is Gen1, check the EP capability\n");
147
148 addr = pex_config_read(pex_idx, first_busno, 0, 0, 0x34) & 0xff;
149 DEBUG_INIT_FULL_C("pex_config_read: return addr=0x%x", addr, 4);
150 if (addr == 0xff) {
151 DEBUG_INIT_FULL_C
152 ("pex_config_read: return 0xff -->PCIe (%d): Detected No Link.",
153 pex_idx, 1);
154 continue;
155 }
156
157 while ((pex_config_read(pex_idx, first_busno, 0, 0, addr)
158 & 0xff) != 0x10) {
159 addr = (pex_config_read(pex_idx, first_busno, 0,
160 0, addr) & 0xff00) >> 8;
161 }
162
163
164 if ((pex_config_read(pex_idx, first_busno, 0, 0,
165 addr + 0xc) & 0xf) < 0x2) {
166 DEBUG_INIT_S("PCIe, Idx ");
167 DEBUG_INIT_D(pex_idx, 1);
168 DEBUG_INIT_S(": remains Gen1\n");
169 continue;
170 }
171
172 tmp = reg_read(PEX_LINK_CTRL_STATUS2_REG(pex_idx));
173 DEBUG_RD_REG(PEX_LINK_CTRL_STATUS2_REG(pex_idx), tmp);
174 tmp &= ~(BIT(0) | BIT(1));
175 tmp |= BIT(1);
176 tmp |= BIT(6);
177 reg_write(PEX_LINK_CTRL_STATUS2_REG(pex_idx), tmp);
178 DEBUG_WR_REG(PEX_LINK_CTRL_STATUS2_REG(pex_idx), tmp);
179
180 tmp = reg_read(PEX_CTRL_REG(pex_idx));
181 DEBUG_RD_REG(PEX_CTRL_REG(pex_idx), tmp);
182 tmp |= BIT(10);
183 reg_write(PEX_CTRL_REG(pex_idx), tmp);
184 DEBUG_WR_REG(PEX_CTRL_REG(pex_idx), tmp);
185
186
187
188
189
190 mdelay(10);
191
192 DEBUG_INIT_S("PCIe, Idx ");
193 DEBUG_INIT_D(pex_idx, 1);
194 DEBUG_INIT_S
195 (": Link upgraded to Gen2 based on client capabilities\n");
196 }
197
198
199 ctrl_mode = sys_env_model_get();
200
201 for (idx = 0; idx < count; idx++) {
202 serdes_type = serdes_map[idx].serdes_type;
203
204 if ((serdes_type != PEX0) && (serdes_type != PEX1) &&
205 (serdes_type != PEX2) && (serdes_type != PEX3))
206 continue;
207
208 if ((serdes_type != PEX0) &&
209 ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
210 (serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
211
212 continue;
213 }
214
215 pex_idx = serdes_type - PEX0;
216 dev_id = reg_read(PEX_CFG_DIRECT_ACCESS
217 (pex_idx, PEX_DEVICE_AND_VENDOR_ID));
218 dev_id &= 0xffff;
219 dev_id |= ((ctrl_mode << 16) & 0xffff0000);
220 reg_write(PEX_CFG_DIRECT_ACCESS
221 (pex_idx, PEX_DEVICE_AND_VENDOR_ID), dev_id);
222 }
223 DEBUG_INIT_FULL_C("Update PEX Device ID ", ctrl_mode, 4);
224
225 return MV_OK;
226}
227
228int pex_local_bus_num_set(u32 pex_if, u32 bus_num)
229{
230 u32 pex_status;
231
232 DEBUG_INIT_FULL_S("\n### pex_local_bus_num_set ###\n");
233
234 if (bus_num >= MAX_PEX_BUSSES) {
235 DEBUG_INIT_C("pex_local_bus_num_set: Illegal bus number %d\n",
236 bus_num, 4);
237 return MV_BAD_PARAM;
238 }
239
240 pex_status = reg_read(PEX_STATUS_REG(pex_if));
241 pex_status &= ~PXSR_PEX_BUS_NUM_MASK;
242 pex_status |=
243 (bus_num << PXSR_PEX_BUS_NUM_OFFS) & PXSR_PEX_BUS_NUM_MASK;
244 reg_write(PEX_STATUS_REG(pex_if), pex_status);
245
246 return MV_OK;
247}
248
249int pex_local_dev_num_set(u32 pex_if, u32 dev_num)
250{
251 u32 pex_status;
252
253 DEBUG_INIT_FULL_S("\n### pex_local_dev_num_set ###\n");
254
255 pex_status = reg_read(PEX_STATUS_REG(pex_if));
256 pex_status &= ~PXSR_PEX_DEV_NUM_MASK;
257 pex_status |=
258 (dev_num << PXSR_PEX_DEV_NUM_OFFS) & PXSR_PEX_DEV_NUM_MASK;
259 reg_write(PEX_STATUS_REG(pex_if), pex_status);
260
261 return MV_OK;
262}
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287u32 pex_config_read(u32 pex_if, u32 bus, u32 dev, u32 func, u32 reg_off)
288{
289 u32 pex_data = 0;
290 u32 local_dev, local_bus;
291 u32 pex_status;
292
293 pex_status = reg_read(PEX_STATUS_REG(pex_if));
294 local_dev =
295 ((pex_status & PXSR_PEX_DEV_NUM_MASK) >> PXSR_PEX_DEV_NUM_OFFS);
296 local_bus =
297 ((pex_status & PXSR_PEX_BUS_NUM_MASK) >> PXSR_PEX_BUS_NUM_OFFS);
298
299
300
301
302
303
304
305 if (bus == local_bus) {
306 if (local_dev == 0) {
307
308
309
310
311 if ((dev != 1) && (dev != local_dev))
312 return MV_ERROR;
313 } else {
314
315
316
317
318 if ((dev != 0) && (dev != local_dev))
319 return MV_ERROR;
320 }
321 }
322
323
324 pex_data = (bus << PXCAR_BUS_NUM_OFFS);
325 pex_data |= (dev << PXCAR_DEVICE_NUM_OFFS);
326 pex_data |= (func << PXCAR_FUNC_NUM_OFFS);
327
328 pex_data |= (reg_off & PXCAR_REG_NUM_MASK);
329
330 pex_data |= (((reg_off & PXCAR_REAL_EXT_REG_NUM_MASK) >>
331 PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS);
332 pex_data |= PXCAR_CONFIG_EN;
333
334
335 reg_write(PEX_CFG_ADDR_REG(pex_if), pex_data);
336
337
338
339
340
341
342 if (pex_data != reg_read(PEX_CFG_ADDR_REG(pex_if)))
343 return MV_ERROR;
344
345
346 reg_bit_set(PEX_CFG_DIRECT_ACCESS(pex_if, PEX_STATUS_AND_COMMAND),
347 PXSAC_MABORT);
348
349 pex_data = reg_read(PEX_CFG_DATA_REG(pex_if));
350
351 DEBUG_INIT_FULL_C(" --> ", pex_data, 4);
352
353 return pex_data;
354}
355