5f223f9b5601e67df144882558320025923fcc5a
[platform/kernel/u-boot.git] / arch / arm / mach-mvebu / serdes / a38x / ctrl_pex.c
1 /*
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
16 int hws_pex_config(struct serdes_map *serdes_map)
17 {
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;
22
23         DEBUG_INIT_FULL_S("\n### hws_pex_config ###\n");
24
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))
31                         continue;
32
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 */
37                         continue;
38                 }
39
40                 pex_idx = serdes_type - PEX0;
41                 tmp = reg_read(PEX_CAPABILITIES_REG(pex_idx));
42                 tmp &= ~(0xf << 20);
43                 tmp |= (0x4 << 20);
44                 reg_write(PEX_CAPABILITIES_REG(pex_idx), tmp);
45         }
46
47         tmp = reg_read(SOC_CTRL_REG);
48         tmp &= ~0x03;
49
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 */
56                         continue;
57                 }
58
59                 switch (serdes_type) {
60                 case PEX0:
61                         tmp |= 0x1 << PCIE0_ENABLE_OFFS;
62                         break;
63                 case PEX1:
64                         tmp |= 0x1 << PCIE1_ENABLE_OFFS;
65                         break;
66                 case PEX2:
67                         tmp |= 0x1 << PCIE2_ENABLE_OFFS;
68                         break;
69                 case PEX3:
70                         tmp |= 0x1 << PCIE3_ENABLE_OFFS;
71                         break;
72                 default:
73                         break;
74                 }
75         }
76
77         reg_write(SOC_CTRL_REG, tmp);
78
79         /* Support gen1/gen2 */
80         DEBUG_INIT_FULL_S("Support gen1/gen2\n");
81         next_busno = 0;
82         mdelay(150);
83
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");
92
93                 /* Configuration for PEX only */
94                 if ((serdes_type != PEX0) && (serdes_type != PEX1) &&
95                     (serdes_type != PEX2) && (serdes_type != PEX3))
96                         continue;
97
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 */
102                         continue;
103                 }
104
105                 pex_idx = serdes_type - PEX0;
106                 tmp = reg_read(PEX_DBG_STATUS_REG(pex_idx));
107
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");
113                         continue;
114                 }
115
116                 next_busno++;
117                 temp_pex_reg = reg_read((PEX_CFG_DIRECT_ACCESS
118                                          (pex_idx, PEX_LINK_CAPABILITY_REG)));
119                 temp_pex_reg &= 0xf;
120                 if (temp_pex_reg != 0x2)
121                         continue;
122
123                 temp_reg = (reg_read(PEX_CFG_DIRECT_ACCESS(
124                                              pex_idx,
125                                              PEX_LINK_CTRL_STAT_REG)) &
126                             0xf0000) >> 16;
127
128                 /* Check if the link established is GEN1 */
129                 DEBUG_INIT_FULL_S
130                         ("Checking if the link established is gen1\n");
131                 if (temp_reg != 0x1)
132                         continue;
133
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);
138
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);
143                 if (addr == 0xff) {
144                         DEBUG_INIT_FULL_C
145                                 ("pex_config_read: return 0xff -->PCIe (%d): Detected No Link.",
146                                  pex_idx, 1);
147                         continue;
148                 }
149
150                 while ((pex_config_read(pex_idx, first_busno, 0, 0, addr)
151                         & 0xff) != 0x10) {
152                         addr = (pex_config_read(pex_idx, first_busno, 0,
153                                                 0, addr) & 0xff00) >> 8;
154                 }
155
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");
162                         continue;
163                 }
164
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));
168                 tmp |= 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);
172
173                 tmp = reg_read(PEX_CTRL_REG(pex_idx));
174                 DEBUG_RD_REG(PEX_CTRL_REG(pex_idx), tmp);
175                 tmp |= BIT(10);
176                 reg_write(PEX_CTRL_REG(pex_idx), tmp);
177                 DEBUG_WR_REG(PEX_CTRL_REG(pex_idx), tmp);
178
179                 /*
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
182                  */
183                 mdelay(10);
184
185                 DEBUG_INIT_S("PCIe, Idx ");
186                 DEBUG_INIT_D(pex_idx, 1);
187                 DEBUG_INIT_S
188                         (": Link upgraded to Gen2 based on client cpabilities\n");
189         }
190
191         /* Update pex DEVICE ID */
192         ctrl_mode = sys_env_model_get();
193
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))
199                         continue;
200
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 */
205                         continue;
206                 }
207
208                 pex_idx = serdes_type - PEX0;
209                 dev_id = reg_read(PEX_CFG_DIRECT_ACCESS
210                                   (pex_idx, PEX_DEVICE_AND_VENDOR_ID));
211                 dev_id &= 0xffff;
212                 dev_id |= ((ctrl_mode << 16) & 0xffff0000);
213                 reg_write(PEX_CFG_DIRECT_ACCESS
214                           (pex_idx, PEX_DEVICE_AND_VENDOR_ID), dev_id);
215         }
216         DEBUG_INIT_FULL_C("Update PEX Device ID ", ctrl_mode, 4);
217
218         return MV_OK;
219 }
220
221 int pex_local_bus_num_set(u32 pex_if, u32 bus_num)
222 {
223         u32 pex_status;
224
225         DEBUG_INIT_FULL_S("\n### pex_local_bus_num_set ###\n");
226
227         if (bus_num >= MAX_PEX_BUSSES) {
228                 DEBUG_INIT_C("pex_local_bus_num_set: Illegal bus number %d\n",
229                              bus_num, 4);
230                 return MV_BAD_PARAM;
231         }
232
233         pex_status = reg_read(PEX_STATUS_REG(pex_if));
234         pex_status &= ~PXSR_PEX_BUS_NUM_MASK;
235         pex_status |=
236             (bus_num << PXSR_PEX_BUS_NUM_OFFS) & PXSR_PEX_BUS_NUM_MASK;
237         reg_write(PEX_STATUS_REG(pex_if), pex_status);
238
239         return MV_OK;
240 }
241
242 int pex_local_dev_num_set(u32 pex_if, u32 dev_num)
243 {
244         u32 pex_status;
245
246         DEBUG_INIT_FULL_S("\n### pex_local_dev_num_set ###\n");
247
248         pex_status = reg_read(PEX_STATUS_REG(pex_if));
249         pex_status &= ~PXSR_PEX_DEV_NUM_MASK;
250         pex_status |=
251             (dev_num << PXSR_PEX_DEV_NUM_OFFS) & PXSR_PEX_DEV_NUM_MASK;
252         reg_write(PEX_STATUS_REG(pex_if), pex_status);
253
254         return MV_OK;
255 }
256
257 /*
258  * pex_config_read - Read from configuration space
259  *
260  * DESCRIPTION:
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).
266  *
267  * INPUT:
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.
273  *
274  * OUTPUT:
275  *       None.
276  *
277  * RETURN:
278  *       32bit register data, 0xffffffff on error
279  */
280 u32 pex_config_read(u32 pex_if, u32 bus, u32 dev, u32 func, u32 reg_off)
281 {
282         u32 pex_data = 0;
283         u32 local_dev, local_bus;
284         u32 pex_status;
285
286         pex_status = reg_read(PEX_STATUS_REG(pex_if));
287         local_dev =
288             ((pex_status & PXSR_PEX_DEV_NUM_MASK) >> PXSR_PEX_DEV_NUM_OFFS);
289         local_bus =
290             ((pex_status & PXSR_PEX_BUS_NUM_MASK) >> PXSR_PEX_BUS_NUM_OFFS);
291
292         /*
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
297          */
298         if (bus == local_bus) {
299                 if (local_dev == 0) {
300                         /*
301                          * if local dev is 0 then the first number we encounter
302                          * after 0 is 1
303                          */
304                         if ((dev != 1) && (dev != local_dev))
305                                 return MV_ERROR;
306                 } else {
307                         /*
308                          * if local dev is not 0 then the first number we
309                          * encounter is 0
310                          */
311                         if ((dev != 0) && (dev != local_dev))
312                                 return MV_ERROR;
313                 }
314         }
315
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;
326
327         /* Write the address to the PEX configuration address register */
328         reg_write(PEX_CFG_ADDR_REG(pex_if), pex_data);
329
330         /*
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
334          */
335         if (pex_data != reg_read(PEX_CFG_ADDR_REG(pex_if)))
336                 return MV_ERROR;
337
338         /* Cleaning Master Abort */
339         reg_bit_set(PEX_CFG_DIRECT_ACCESS(pex_if, PEX_STATUS_AND_COMMAND),
340                     PXSAC_MABORT);
341         /* Read the Data returned in the PEX Data register */
342         pex_data = reg_read(PEX_CFG_DATA_REG(pex_if));
343
344         DEBUG_INIT_FULL_C(" --> ", pex_data, 4);
345
346         return pex_data;
347 }