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