2 * Copyright (C) Marvell International Ltd. and its affiliates
4 * SPDX-License-Identifier: GPL-2.0
10 #include <asm/arch/cpu.h>
11 #include <asm/arch/soc.h>
14 #include "sys_env_lib.h"
16 int hws_pex_config(struct serdes_map *serdes_map)
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;
21 u32 idx, max_lane_num;
23 DEBUG_INIT_FULL_S("\n### hws_pex_config ###\n");
25 max_lane_num = hws_serdes_get_max_lane();
26 for (idx = 0; idx < max_lane_num; idx++) {
27 serdes_type = serdes_map[idx].serdes_type;
28 /* configuration for PEX only */
29 if ((serdes_type != PEX0) && (serdes_type != PEX1) &&
30 (serdes_type != PEX2) && (serdes_type != PEX3))
33 if ((serdes_type != PEX0) &&
34 ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
35 (serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
36 /* for PEX by4 - relevant for the first port only */
40 pex_idx = serdes_type - PEX0;
41 tmp = reg_read(PEX_CAPABILITIES_REG(pex_idx));
44 reg_write(PEX_CAPABILITIES_REG(pex_idx), tmp);
47 tmp = reg_read(SOC_CTRL_REG);
50 for (idx = 0; idx < max_lane_num; idx++) {
51 serdes_type = serdes_map[idx].serdes_type;
52 if ((serdes_type != PEX0) &&
53 ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
54 (serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
55 /* for PEX by4 - relevant for the first port only */
59 switch (serdes_type) {
61 tmp |= 0x1 << PCIE0_ENABLE_OFFS;
64 tmp |= 0x1 << PCIE1_ENABLE_OFFS;
67 tmp |= 0x1 << PCIE2_ENABLE_OFFS;
70 tmp |= 0x1 << PCIE3_ENABLE_OFFS;
77 reg_write(SOC_CTRL_REG, tmp);
79 /* Support gen1/gen2 */
80 DEBUG_INIT_FULL_S("Support gen1/gen2\n");
84 for (idx = 0; idx < max_lane_num; idx++) {
85 serdes_type = serdes_map[idx].serdes_type;
86 DEBUG_INIT_FULL_S(" serdes_type=0x");
87 DEBUG_INIT_FULL_D(serdes_type, 8);
88 DEBUG_INIT_FULL_S("\n");
89 DEBUG_INIT_FULL_S(" idx=0x");
90 DEBUG_INIT_FULL_D(idx, 8);
91 DEBUG_INIT_FULL_S("\n");
93 /* Configuration for PEX only */
94 if ((serdes_type != PEX0) && (serdes_type != PEX1) &&
95 (serdes_type != PEX2) && (serdes_type != PEX3))
98 if ((serdes_type != PEX0) &&
99 ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
100 (serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
101 /* for PEX by4 - relevant for the first port only */
105 pex_idx = serdes_type - PEX0;
106 tmp = reg_read(PEX_DBG_STATUS_REG(pex_idx));
108 first_busno = next_busno;
109 if ((tmp & 0x7f) != 0x7e) {
110 DEBUG_INIT_S("PCIe, Idx ");
111 DEBUG_INIT_D(pex_idx, 1);
112 DEBUG_INIT_S(": detected no link\n");
117 temp_pex_reg = reg_read((PEX_CFG_DIRECT_ACCESS
118 (pex_idx, PEX_LINK_CAPABILITY_REG)));
120 if (temp_pex_reg != 0x2)
123 temp_reg = (reg_read(PEX_CFG_DIRECT_ACCESS(
125 PEX_LINK_CTRL_STAT_REG)) &
128 /* Check if the link established is GEN1 */
130 ("Checking if the link established is gen1\n");
134 pex_local_bus_num_set(pex_idx, first_busno);
135 pex_local_dev_num_set(pex_idx, 1);
136 DEBUG_INIT_FULL_S("PCIe, Idx ");
137 DEBUG_INIT_FULL_D(pex_idx, 1);
139 DEBUG_INIT_S(":** Link is Gen1, check the EP capability\n");
140 /* link is Gen1, check the EP capability */
141 addr = pex_config_read(pex_idx, first_busno, 0, 0, 0x34) & 0xff;
142 DEBUG_INIT_FULL_C("pex_config_read: return addr=0x%x", addr, 4);
145 ("pex_config_read: return 0xff -->PCIe (%d): Detected No Link.",
150 while ((pex_config_read(pex_idx, first_busno, 0, 0, addr)
152 addr = (pex_config_read(pex_idx, first_busno, 0,
153 0, addr) & 0xff00) >> 8;
156 /* Check for Gen2 and above */
157 if ((pex_config_read(pex_idx, first_busno, 0, 0,
158 addr + 0xc) & 0xf) < 0x2) {
159 DEBUG_INIT_S("PCIe, Idx ");
160 DEBUG_INIT_D(pex_idx, 1);
161 DEBUG_INIT_S(": remains Gen1\n");
165 tmp = reg_read(PEX_LINK_CTRL_STATUS2_REG(pex_idx));
166 DEBUG_RD_REG(PEX_LINK_CTRL_STATUS2_REG(pex_idx), tmp);
167 tmp &= ~(BIT(0) | BIT(1));
169 tmp |= BIT(6); /* Select Deemphasize (-3.5d_b) */
170 reg_write(PEX_LINK_CTRL_STATUS2_REG(pex_idx), tmp);
171 DEBUG_WR_REG(PEX_LINK_CTRL_STATUS2_REG(pex_idx), tmp);
173 tmp = reg_read(PEX_CTRL_REG(pex_idx));
174 DEBUG_RD_REG(PEX_CTRL_REG(pex_idx), tmp);
176 reg_write(PEX_CTRL_REG(pex_idx), tmp);
177 DEBUG_WR_REG(PEX_CTRL_REG(pex_idx), tmp);
180 * We need to wait 10ms before reading the PEX_DBG_STATUS_REG
181 * in order not to read the status of the former state
185 DEBUG_INIT_S("PCIe, Idx ");
186 DEBUG_INIT_D(pex_idx, 1);
188 (": Link upgraded to Gen2 based on client cpabilities\n");
191 /* Update pex DEVICE ID */
192 ctrl_mode = sys_env_model_get();
194 for (idx = 0; idx < max_lane_num; idx++) {
195 serdes_type = serdes_map[idx].serdes_type;
196 /* configuration for PEX only */
197 if ((serdes_type != PEX0) && (serdes_type != PEX1) &&
198 (serdes_type != PEX2) && (serdes_type != PEX3))
201 if ((serdes_type != PEX0) &&
202 ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
203 (serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
204 /* for PEX by4 - relevant for the first port only */
208 pex_idx = serdes_type - PEX0;
209 dev_id = reg_read(PEX_CFG_DIRECT_ACCESS
210 (pex_idx, PEX_DEVICE_AND_VENDOR_ID));
212 dev_id |= ((ctrl_mode << 16) & 0xffff0000);
213 reg_write(PEX_CFG_DIRECT_ACCESS
214 (pex_idx, PEX_DEVICE_AND_VENDOR_ID), dev_id);
216 DEBUG_INIT_FULL_C("Update PEX Device ID ", ctrl_mode, 4);
221 int pex_local_bus_num_set(u32 pex_if, u32 bus_num)
225 DEBUG_INIT_FULL_S("\n### pex_local_bus_num_set ###\n");
227 if (bus_num >= MAX_PEX_BUSSES) {
228 DEBUG_INIT_C("pex_local_bus_num_set: Illegal bus number %d\n",
233 pex_status = reg_read(PEX_STATUS_REG(pex_if));
234 pex_status &= ~PXSR_PEX_BUS_NUM_MASK;
236 (bus_num << PXSR_PEX_BUS_NUM_OFFS) & PXSR_PEX_BUS_NUM_MASK;
237 reg_write(PEX_STATUS_REG(pex_if), pex_status);
242 int pex_local_dev_num_set(u32 pex_if, u32 dev_num)
246 DEBUG_INIT_FULL_S("\n### pex_local_dev_num_set ###\n");
248 pex_status = reg_read(PEX_STATUS_REG(pex_if));
249 pex_status &= ~PXSR_PEX_DEV_NUM_MASK;
251 (dev_num << PXSR_PEX_DEV_NUM_OFFS) & PXSR_PEX_DEV_NUM_MASK;
252 reg_write(PEX_STATUS_REG(pex_if), pex_status);
258 * pex_config_read - Read from configuration space
261 * This function performs a 32 bit read from PEX configuration space.
262 * It supports both type 0 and type 1 of Configuration Transactions
263 * (local and over bridge). In order to read from local bus segment, use
264 * bus number retrieved from pex_local_bus_num_get(). Other bus numbers
265 * will result configuration transaction of type 1 (over bridge).
268 * pex_if - PEX interface number.
269 * bus - PEX segment bus number.
270 * dev - PEX device number.
271 * func - Function number.
272 * reg_offs - Register offset.
278 * 32bit register data, 0xffffffff on error
280 u32 pex_config_read(u32 pex_if, u32 bus, u32 dev, u32 func, u32 reg_off)
283 u32 local_dev, local_bus;
286 pex_status = reg_read(PEX_STATUS_REG(pex_if));
288 ((pex_status & PXSR_PEX_DEV_NUM_MASK) >> PXSR_PEX_DEV_NUM_OFFS);
290 ((pex_status & PXSR_PEX_BUS_NUM_MASK) >> PXSR_PEX_BUS_NUM_OFFS);
293 * In PCI Express we have only one device number
294 * and this number is the first number we encounter
295 * else that the local_dev
296 * spec pex define return on config read/write on any device
298 if (bus == local_bus) {
299 if (local_dev == 0) {
301 * if local dev is 0 then the first number we encounter
304 if ((dev != 1) && (dev != local_dev))
308 * if local dev is not 0 then the first number we
311 if ((dev != 0) && (dev != local_dev))
316 /* Creating PEX address to be passed */
317 pex_data = (bus << PXCAR_BUS_NUM_OFFS);
318 pex_data |= (dev << PXCAR_DEVICE_NUM_OFFS);
319 pex_data |= (func << PXCAR_FUNC_NUM_OFFS);
320 /* Legacy register space */
321 pex_data |= (reg_off & PXCAR_REG_NUM_MASK);
322 /* Extended register space */
323 pex_data |= (((reg_off & PXCAR_REAL_EXT_REG_NUM_MASK) >>
324 PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS);
325 pex_data |= PXCAR_CONFIG_EN;
327 /* Write the address to the PEX configuration address register */
328 reg_write(PEX_CFG_ADDR_REG(pex_if), pex_data);
331 * In order to let the PEX controller absorbed the address
332 * of the read transaction we perform a validity check that
333 * the address was written
335 if (pex_data != reg_read(PEX_CFG_ADDR_REG(pex_if)))
338 /* Cleaning Master Abort */
339 reg_bit_set(PEX_CFG_DIRECT_ACCESS(pex_if, PEX_STATUS_AND_COMMAND),
341 /* Read the Data returned in the PEX Data register */
342 pex_data = reg_read(PEX_CFG_DATA_REG(pex_if));
344 DEBUG_INIT_FULL_C(" --> ", pex_data, 4);