blob: 06a7715773c92317d910d07afb5cfc284b7d23bb [file] [log] [blame]
Stefan Roese6a905952015-04-20 09:31:27 +02001/*
2 * Copyright (C) Marvell International Ltd. and its affiliates
3 *
4 * SPDX-License-Identifier: GPL-2.0
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
Kevin Smith6406d432015-10-23 17:53:19 +000016int hws_pex_config(const struct serdes_map *serdes_map, u8 count)
Stefan Roese6a905952015-04-20 09:31:27 +020017{
18 u32 pex_idx, tmp, next_busno, first_busno, temp_pex_reg,
19 temp_reg, addr, dev_id, ctrl_mode;
20 enum serdes_type serdes_type;
Kevin Smith6406d432015-10-23 17:53:19 +000021 u32 idx;
Stefan Roese6a905952015-04-20 09:31:27 +020022
23 DEBUG_INIT_FULL_S("\n### hws_pex_config ###\n");
24
Kevin Smith6406d432015-10-23 17:53:19 +000025 for (idx = 0; idx < count; idx++) {
Stefan Roese6a905952015-04-20 09:31:27 +020026 serdes_type = serdes_map[idx].serdes_type;
27 /* configuration for PEX only */
28 if ((serdes_type != PEX0) && (serdes_type != PEX1) &&
29 (serdes_type != PEX2) && (serdes_type != PEX3))
30 continue;
31
32 if ((serdes_type != PEX0) &&
33 ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
34 (serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
35 /* for PEX by4 - relevant for the first port only */
36 continue;
37 }
38
39 pex_idx = serdes_type - PEX0;
40 tmp = reg_read(PEX_CAPABILITIES_REG(pex_idx));
41 tmp &= ~(0xf << 20);
42 tmp |= (0x4 << 20);
43 reg_write(PEX_CAPABILITIES_REG(pex_idx), tmp);
44 }
45
46 tmp = reg_read(SOC_CTRL_REG);
47 tmp &= ~0x03;
48
Kevin Smith6406d432015-10-23 17:53:19 +000049 for (idx = 0; idx < count; idx++) {
Stefan Roese6a905952015-04-20 09:31:27 +020050 serdes_type = serdes_map[idx].serdes_type;
51 if ((serdes_type != PEX0) &&
52 ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
53 (serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
54 /* for PEX by4 - relevant for the first port only */
55 continue;
56 }
57
58 switch (serdes_type) {
59 case PEX0:
60 tmp |= 0x1 << PCIE0_ENABLE_OFFS;
61 break;
62 case PEX1:
63 tmp |= 0x1 << PCIE1_ENABLE_OFFS;
64 break;
65 case PEX2:
66 tmp |= 0x1 << PCIE2_ENABLE_OFFS;
67 break;
68 case PEX3:
69 tmp |= 0x1 << PCIE3_ENABLE_OFFS;
70 break;
71 default:
72 break;
73 }
74 }
75
76 reg_write(SOC_CTRL_REG, tmp);
77
78 /* Support gen1/gen2 */
79 DEBUG_INIT_FULL_S("Support gen1/gen2\n");
80 next_busno = 0;
81 mdelay(150);
82
Kevin Smith6406d432015-10-23 17:53:19 +000083 for (idx = 0; idx < count; idx++) {
Stefan Roese6a905952015-04-20 09:31:27 +020084 serdes_type = serdes_map[idx].serdes_type;
85 DEBUG_INIT_FULL_S(" serdes_type=0x");
86 DEBUG_INIT_FULL_D(serdes_type, 8);
87 DEBUG_INIT_FULL_S("\n");
88 DEBUG_INIT_FULL_S(" idx=0x");
89 DEBUG_INIT_FULL_D(idx, 8);
90 DEBUG_INIT_FULL_S("\n");
91
92 /* Configuration for PEX only */
93 if ((serdes_type != PEX0) && (serdes_type != PEX1) &&
94 (serdes_type != PEX2) && (serdes_type != PEX3))
95 continue;
96
97 if ((serdes_type != PEX0) &&
98 ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
99 (serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
100 /* for PEX by4 - relevant for the first port only */
101 continue;
102 }
103
104 pex_idx = serdes_type - PEX0;
105 tmp = reg_read(PEX_DBG_STATUS_REG(pex_idx));
106
107 first_busno = next_busno;
108 if ((tmp & 0x7f) != 0x7e) {
109 DEBUG_INIT_S("PCIe, Idx ");
110 DEBUG_INIT_D(pex_idx, 1);
111 DEBUG_INIT_S(": detected no link\n");
112 continue;
113 }
114
115 next_busno++;
116 temp_pex_reg = reg_read((PEX_CFG_DIRECT_ACCESS
117 (pex_idx, PEX_LINK_CAPABILITY_REG)));
118 temp_pex_reg &= 0xf;
119 if (temp_pex_reg != 0x2)
120 continue;
121
122 temp_reg = (reg_read(PEX_CFG_DIRECT_ACCESS(
123 pex_idx,
124 PEX_LINK_CTRL_STAT_REG)) &
125 0xf0000) >> 16;
126
127 /* Check if the link established is GEN1 */
128 DEBUG_INIT_FULL_S
129 ("Checking if the link established is gen1\n");
130 if (temp_reg != 0x1)
131 continue;
132
133 pex_local_bus_num_set(pex_idx, first_busno);
134 pex_local_dev_num_set(pex_idx, 1);
135 DEBUG_INIT_FULL_S("PCIe, Idx ");
136 DEBUG_INIT_FULL_D(pex_idx, 1);
137
138 DEBUG_INIT_S(":** Link is Gen1, check the EP capability\n");
139 /* link is Gen1, check the EP capability */
140 addr = pex_config_read(pex_idx, first_busno, 0, 0, 0x34) & 0xff;
141 DEBUG_INIT_FULL_C("pex_config_read: return addr=0x%x", addr, 4);
142 if (addr == 0xff) {
143 DEBUG_INIT_FULL_C
144 ("pex_config_read: return 0xff -->PCIe (%d): Detected No Link.",
145 pex_idx, 1);
146 continue;
147 }
148
149 while ((pex_config_read(pex_idx, first_busno, 0, 0, addr)
150 & 0xff) != 0x10) {
151 addr = (pex_config_read(pex_idx, first_busno, 0,
152 0, addr) & 0xff00) >> 8;
153 }
154
155 /* Check for Gen2 and above */
156 if ((pex_config_read(pex_idx, first_busno, 0, 0,
157 addr + 0xc) & 0xf) < 0x2) {
158 DEBUG_INIT_S("PCIe, Idx ");
159 DEBUG_INIT_D(pex_idx, 1);
160 DEBUG_INIT_S(": remains Gen1\n");
161 continue;
162 }
163
164 tmp = reg_read(PEX_LINK_CTRL_STATUS2_REG(pex_idx));
165 DEBUG_RD_REG(PEX_LINK_CTRL_STATUS2_REG(pex_idx), tmp);
166 tmp &= ~(BIT(0) | BIT(1));
167 tmp |= BIT(1);
168 tmp |= BIT(6); /* Select Deemphasize (-3.5d_b) */
169 reg_write(PEX_LINK_CTRL_STATUS2_REG(pex_idx), tmp);
170 DEBUG_WR_REG(PEX_LINK_CTRL_STATUS2_REG(pex_idx), tmp);
171
172 tmp = reg_read(PEX_CTRL_REG(pex_idx));
173 DEBUG_RD_REG(PEX_CTRL_REG(pex_idx), tmp);
174 tmp |= BIT(10);
175 reg_write(PEX_CTRL_REG(pex_idx), tmp);
176 DEBUG_WR_REG(PEX_CTRL_REG(pex_idx), tmp);
177
178 /*
179 * We need to wait 10ms before reading the PEX_DBG_STATUS_REG
180 * in order not to read the status of the former state
181 */
182 mdelay(10);
183
184 DEBUG_INIT_S("PCIe, Idx ");
185 DEBUG_INIT_D(pex_idx, 1);
186 DEBUG_INIT_S
187 (": Link upgraded to Gen2 based on client cpabilities\n");
188 }
189
190 /* Update pex DEVICE ID */
191 ctrl_mode = sys_env_model_get();
192
Kevin Smith6406d432015-10-23 17:53:19 +0000193 for (idx = 0; idx < count; idx++) {
Stefan Roese6a905952015-04-20 09:31:27 +0200194 serdes_type = serdes_map[idx].serdes_type;
195 /* configuration for PEX only */
196 if ((serdes_type != PEX0) && (serdes_type != PEX1) &&
197 (serdes_type != PEX2) && (serdes_type != PEX3))
198 continue;
199
200 if ((serdes_type != PEX0) &&
201 ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
202 (serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
203 /* for PEX by4 - relevant for the first port only */
204 continue;
205 }
206
207 pex_idx = serdes_type - PEX0;
208 dev_id = reg_read(PEX_CFG_DIRECT_ACCESS
209 (pex_idx, PEX_DEVICE_AND_VENDOR_ID));
210 dev_id &= 0xffff;
211 dev_id |= ((ctrl_mode << 16) & 0xffff0000);
212 reg_write(PEX_CFG_DIRECT_ACCESS
213 (pex_idx, PEX_DEVICE_AND_VENDOR_ID), dev_id);
214 }
215 DEBUG_INIT_FULL_C("Update PEX Device ID ", ctrl_mode, 4);
216
217 return MV_OK;
218}
219
220int pex_local_bus_num_set(u32 pex_if, u32 bus_num)
221{
222 u32 pex_status;
223
224 DEBUG_INIT_FULL_S("\n### pex_local_bus_num_set ###\n");
225
226 if (bus_num >= MAX_PEX_BUSSES) {
227 DEBUG_INIT_C("pex_local_bus_num_set: Illegal bus number %d\n",
228 bus_num, 4);
229 return MV_BAD_PARAM;
230 }
231
232 pex_status = reg_read(PEX_STATUS_REG(pex_if));
233 pex_status &= ~PXSR_PEX_BUS_NUM_MASK;
234 pex_status |=
235 (bus_num << PXSR_PEX_BUS_NUM_OFFS) & PXSR_PEX_BUS_NUM_MASK;
236 reg_write(PEX_STATUS_REG(pex_if), pex_status);
237
238 return MV_OK;
239}
240
241int pex_local_dev_num_set(u32 pex_if, u32 dev_num)
242{
243 u32 pex_status;
244
245 DEBUG_INIT_FULL_S("\n### pex_local_dev_num_set ###\n");
246
247 pex_status = reg_read(PEX_STATUS_REG(pex_if));
248 pex_status &= ~PXSR_PEX_DEV_NUM_MASK;
249 pex_status |=
250 (dev_num << PXSR_PEX_DEV_NUM_OFFS) & PXSR_PEX_DEV_NUM_MASK;
251 reg_write(PEX_STATUS_REG(pex_if), pex_status);
252
253 return MV_OK;
254}
255
256/*
257 * pex_config_read - Read from configuration space
258 *
259 * DESCRIPTION:
260 * This function performs a 32 bit read from PEX configuration space.
261 * It supports both type 0 and type 1 of Configuration Transactions
262 * (local and over bridge). In order to read from local bus segment, use
263 * bus number retrieved from pex_local_bus_num_get(). Other bus numbers
264 * will result configuration transaction of type 1 (over bridge).
265 *
266 * INPUT:
267 * pex_if - PEX interface number.
268 * bus - PEX segment bus number.
269 * dev - PEX device number.
270 * func - Function number.
271 * reg_offs - Register offset.
272 *
273 * OUTPUT:
274 * None.
275 *
276 * RETURN:
277 * 32bit register data, 0xffffffff on error
278 */
279u32 pex_config_read(u32 pex_if, u32 bus, u32 dev, u32 func, u32 reg_off)
280{
281 u32 pex_data = 0;
282 u32 local_dev, local_bus;
283 u32 pex_status;
284
285 pex_status = reg_read(PEX_STATUS_REG(pex_if));
286 local_dev =
287 ((pex_status & PXSR_PEX_DEV_NUM_MASK) >> PXSR_PEX_DEV_NUM_OFFS);
288 local_bus =
289 ((pex_status & PXSR_PEX_BUS_NUM_MASK) >> PXSR_PEX_BUS_NUM_OFFS);
290
291 /*
292 * In PCI Express we have only one device number
293 * and this number is the first number we encounter
294 * else that the local_dev
295 * spec pex define return on config read/write on any device
296 */
297 if (bus == local_bus) {
298 if (local_dev == 0) {
299 /*
300 * if local dev is 0 then the first number we encounter
301 * after 0 is 1
302 */
303 if ((dev != 1) && (dev != local_dev))
304 return MV_ERROR;
305 } else {
306 /*
307 * if local dev is not 0 then the first number we
308 * encounter is 0
309 */
310 if ((dev != 0) && (dev != local_dev))
311 return MV_ERROR;
312 }
313 }
314
315 /* Creating PEX address to be passed */
316 pex_data = (bus << PXCAR_BUS_NUM_OFFS);
317 pex_data |= (dev << PXCAR_DEVICE_NUM_OFFS);
318 pex_data |= (func << PXCAR_FUNC_NUM_OFFS);
319 /* Legacy register space */
320 pex_data |= (reg_off & PXCAR_REG_NUM_MASK);
321 /* Extended register space */
322 pex_data |= (((reg_off & PXCAR_REAL_EXT_REG_NUM_MASK) >>
323 PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS);
324 pex_data |= PXCAR_CONFIG_EN;
325
326 /* Write the address to the PEX configuration address register */
327 reg_write(PEX_CFG_ADDR_REG(pex_if), pex_data);
328
329 /*
330 * In order to let the PEX controller absorbed the address
331 * of the read transaction we perform a validity check that
332 * the address was written
333 */
334 if (pex_data != reg_read(PEX_CFG_ADDR_REG(pex_if)))
335 return MV_ERROR;
336
337 /* Cleaning Master Abort */
338 reg_bit_set(PEX_CFG_DIRECT_ACCESS(pex_if, PEX_STATUS_AND_COMMAND),
339 PXSAC_MABORT);
340 /* Read the Data returned in the PEX Data register */
341 pex_data = reg_read(PEX_CFG_DATA_REG(pex_if));
342
343 DEBUG_INIT_FULL_C(" --> ", pex_data, 4);
344
345 return pex_data;
346}