Merge branch 'master' of git://www.denx.de/git/u-boot-marvell
[oweals/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(const struct serdes_map *serdes_map, u8 count)
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;
22
23         DEBUG_INIT_FULL_S("\n### hws_pex_config ###\n");
24
25         for (idx = 0; idx < count; idx++) {
26                 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
49         for (idx = 0; idx < count; idx++) {
50                 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
83         for (idx = 0; idx < count; idx++) {
84                 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 capabilities\n");
188         }
189
190         /* Update pex DEVICE ID */
191         ctrl_mode = sys_env_model_get();
192
193         for (idx = 0; idx < count; idx++) {
194                 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
220 int 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
241 int 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  */
279 u32 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 }