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