blob: 7380e09a3be8547f489837060260e346e303c60b [file] [log] [blame]
Sheetal Tigadoli58a9eca2019-12-18 20:05:09 +05301/*
2 * Copyright (c) 2019-2020, Broadcom
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <errno.h>
8#include <stdbool.h>
9
10#include <common/debug.h>
11#include <drivers/delay_timer.h>
12#include <lib/mmio.h>
13
14#include <paxb.h>
15#include <sr_def.h>
16#include <sr_utils.h>
17
18/* total number of PCIe Phys */
19#define NUM_OF_PCIE_SERDES 8
20
21#define CFG_RC_PMI_ADDR 0x1130
22#define PMI_RX_TERM_SEQ ((0x1 << 27) | (0x1ff << 16) | (0xd090))
23#define PMI_RX_TERM_VAL 0x4c00
24#define PMI_PLL_CTRL_4 0xd0b4
25#define PMI_SERDES_CLK_ENABLE (1 << 12)
26
27#define WAR_PLX_PRESET_PARITY_FAIL
28
29#define CFG_RC_REG_PHY_CTL_10 0x1838
30#define PHY_CTL_10_GEN3_MATCH_PARITY (1 << 15)
31
32#define PMI_X8_CORE0_7_PATCH_SEQ ((0x1 << 27) | (0x1ff << 16) | (0xd2a5))
33#define PMI_X8_CORE0_7_PATCH_VAL 0xd864
34
35#define PMI_ADDR_BCAST(addr) ((0x1 << 27) | (0x1ff << 16) | (addr))
36#define PMI_ADDR_LANE0(addr) ((0x1 << 27) | (addr))
37#define PMI_ADDR_LANE1(addr) ((0x1 << 27) | (0x1 << 16) | (addr))
38
39#define MERLIN16_PCIE_BLK2_PWRMGMT_7 ((0x1 << 27) | (0x1ff << 16) | 0x1208)
40#define MERLIN16_PCIE_BLK2_PWRMGMT_8 ((0x1 << 27) | (0x1ff << 16) | 0x1209)
41#define MERLIN16_AMS_TX_CTRL_5 ((0x1 << 27) | (0x1ff << 16) | 0xd0a5)
42#define MERLIN16_AMS_TX_CTRL_5_VAL \
43 ((1 << 13) | (1 << 12) | (1 << 11) | (1 << 10))
44#define MERLIN16_PCIE_BLK2_PWRMGMT_7_VAL 0x96
45#define MERLIN16_PCIE_BLK2_PWRMGMT_8_VAL 0x12c
46
47#define CFG_RC_PMI_WDATA 0x1134
48#define CFG_RC_WCMD_SHIFT 31
49#define CFG_RC_WCMD_MASK ((uint32_t)1U << CFG_RC_WCMD_SHIFT)
50#define CFG_RC_RCMD_SHIFT 30
51#define CFG_RC_RCMD_MASK ((uint32_t)1U << CFG_RC_RCMD_SHIFT)
52#define CFG_RC_RWCMD_MASK (CFG_RC_RCMD_MASK | CFG_RC_WCMD_MASK)
53#define CFG_RC_PMI_RDATA 0x1138
54#define CFG_RC_RACK_SHIFT 31
55#define CFG_RC_RACK_MASK ((uint32_t)1U << CFG_RC_RACK_SHIFT)
56
57/* allow up to 5 ms for PMI write to finish */
58#define PMI_TIMEOUT_MS 5
59
60/* in 2x8 RC mode, one needs to patch up Serdes 3 and 7 for link to come up */
61#define SERDES_PATCH_PIPEMUX_INDEX 0x3
62#define SERDES_PATCH_INDEX 0x8
63
64#define DSC_UC_CTRL 0xd00d
65#define DSC_UC_CTRL_RDY_CMD (1 << 7)
66#define LANE_DBG_RST_CTRL 0xd164
67#define UC_A_CLK_CTRL0 0xd200
68#define UC_A_RST_CTRL0 0xd201
69#define UC_A_AHB_CTRL0 0xd202
70#define UC_A_AHB_STAT0 0xd203
71#define UC_A_AHB_WADDR_LSW 0xd204
72#define UC_A_AHB_WADDR_MSW 0xd205
73#define UC_A_AHB_WDATA_LSW 0xd206
74#define UC_A_AHB_WDATA_MSW 0xd207
75#define UC_A_AHB_RADDR_LSW 0xd208
76#define UC_A_AHB_RADDR_MSW 0xd209
77#define UC_A_AHB_RDATA_LSW 0xd20a
78#define UC_A_AHB_RDATA_MSW 0xd20b
79#define UC_VERSION_NUM 0xd230
80#define DSC_SM_CTL22 0xd267
81#define UC_DBG1 0xd251
82
83#define LOAD_UC_CHECK 0
84#define UC_RAM_INIT_TIMEOUT 100
85#define UC_RAM_CONTROL 0xd225
86#define UC_INIT_TIMEOUT 100
87#define SIZE_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
88#define SZ_4 4
89#define GET_2_BYTES(p, i) ((uint16_t)p[i] | (uint16_t)p[i+1] << 8)
90
91/*
92 * List of PCIe LCPLL related registers
93 *
94 * LCPLL channel 0 provides the Serdes pad clock when running in RC mode
95 */
96#define PCIE_LCPLL_BASE 0x40000000
97
98#define PCIE_LCPLL_CTRL0_OFFSET 0x00
99#define PCIE_LCPLL_RESETB_SHIFT 31
100#define PCIE_LCPLL_RESETB_MASK BIT(PCIE_LCPLL_RESETB_SHIFT)
101#define PCIE_LCPLL_P_RESETB_SHIFT 30
102#define PCIE_LCPLL_P_RESETB_MASK BIT(PCIE_LCPLL_P_RESETB_SHIFT)
103
104#define PCIE_LCPLL_CTRL3_OFFSET 0x0c
105#define PCIE_LCPLL_EN_CTRL_SHIFT 16
106#define PCIE_LCPLL_CM_ENA 0x1a
107#define PCIE_LCPLL_CM_BUF_ENA 0x18
108#define PCIE_LCPLL_D2C2_ENA 0x2
109#define PCIE_LCPLL_REF_CLK_SHIFT 1
110#define PCIE_LCPLL_REF_CLK_MASK BIT(PCIE_LCPLL_REF_CLK_SHIFT)
111#define PCIE_LCPLL_CTRL13_OFFSET 0x34
112#define PCIE_LCPLL_D2C2_CTRL_SHIFT 16
113#define PCIE_LCPLL_D2C2_TERM_DISC 0xe0
114
115#define PCIE_LCPLL_STATUS_OFFSET 0x40
116#define PCIE_LCPLL_LOCK_SHIFT 12
117#define PCIE_LCPLL_LOCK_MASK BIT(PCIE_LCPLL_LOCK_SHIFT)
118
119#define PCIE_PIPE_MUX_RC_MODE_OVERRIDE_CFG 0x114
120#define PCIE_TX_CLKMASTER_CTRL_OVERRIDE_CFG 0x11c
121
122/* wait 500 microseconds for PCIe LCPLL to power up */
123#define PCIE_LCPLL_DELAY_US 500
124
125/* allow up to 5 ms for PCIe LCPLL VCO to lock */
126#define PCIE_LCPLL_TIMEOUT_MS 5
127
128#define PCIE_PIPE_MUX_CONFIGURATION_CFG 0x4000010c
129
130#define PCIE_PIPEMUX_SHIFT 19
131#define PCIE_PIPEMUX_MASK 0xf
132
133/* keep track of PIPEMUX index to use */
134static unsigned int pipemux_idx;
135
136/*
137 * PCIe PIPEMUX lookup table
138 *
139 * Each array index represents a PIPEMUX strap setting
140 * The array element represents a bitmap where a set bit means the PCIe core
141 * needs to be enabled as RC
142 */
143static uint8_t pipemux_table[] = {
144 /* PIPEMUX = 0, EP 1x16 */
145 0x00,
146 /* PIPEMUX = 1, EP 1x8 + RC 1x8, core 7 */
147 0x80,
148 /* PIPEMUX = 2, EP 4x4 */
149 0x00,
150 /* PIPEMUX = 3, RC 2x8, cores 0, 7 */
151 0x81,
152 /* PIPEMUX = 4, RC 4x4, cores 0, 1, 6, 7 */
153 0xc3,
154 /* PIPEMUX = 5, RC 8x2, all 8 cores */
155 0xff,
156 /* PIPEMUX = 6, RC 3x4 + 2x2, cores 0, 2, 3, 6, 7 */
157 0xcd,
158 /* PIPEMUX = 7, RC 1x4 + 6x2, cores 0, 2, 3, 4, 5, 6, 7 */
159 0xfd,
160 /* PIPEMUX = 8, EP 1x8 + RC 4x2, cores 4, 5, 6, 7 */
161 0xf0,
162 /* PIPEMUX = 9, EP 1x8 + RC 2x4, cores 6, 7 */
163 0xc0,
164 /* PIPEMUX = 10, EP 2x4 + RC 2x4, cores 1, 6 */
165 0x42,
166 /* PIPEMUX = 11, EP 2x4 + RC 4x2, cores 2, 3, 4, 5 */
167 0x3c,
168 /* PIPEMUX = 12, EP 1x4 + RC 6x2, cores 2, 3, 4, 5, 6, 7 */
169 0xfc,
170 /* PIPEMUX = 13, RC 2x4 + RC 1x4 + 2x2, cores 2, 3, 6 */
171 0x4c,
172};
173
174/*
175 * Return 1 if pipemux strap is supported
176 */
177static int pipemux_strap_is_valid(uint32_t pipemux)
178{
179 if (pipemux < ARRAY_SIZE(pipemux_table))
180 return 1;
181 else
182 return 0;
183}
184
185/*
186 * Read the PCIe PIPEMUX from strap
187 */
188static uint32_t pipemux_strap_read(void)
189{
190 uint32_t pipemux;
191
192 pipemux = mmio_read_32(PCIE_PIPE_MUX_CONFIGURATION_CFG);
193 pipemux &= PCIE_PIPEMUX_MASK;
194 if (pipemux == PCIE_PIPEMUX_MASK) {
195 /* read the PCIe PIPEMUX strap setting */
196 pipemux = mmio_read_32(CDRU_CHIP_STRAP_DATA_LSW);
197 pipemux >>= PCIE_PIPEMUX_SHIFT;
198 pipemux &= PCIE_PIPEMUX_MASK;
199 }
200
201 return pipemux;
202}
203
204/*
205 * Store the PIPEMUX index (set for each boot)
206 */
207static void pipemux_save_index(unsigned int idx)
208{
209 pipemux_idx = idx;
210}
211
212static int paxb_sr_core_needs_enable(unsigned int core_idx)
213{
214 return !!((pipemux_table[pipemux_idx] >> core_idx) & 0x1);
215}
216
217static int pipemux_sr_init(void)
218{
219 uint32_t pipemux;
220
221 /* read the PCIe PIPEMUX strap setting */
222 pipemux = pipemux_strap_read();
223 if (!pipemux_strap_is_valid(pipemux)) {
224 ERROR("Invalid PCIe PIPEMUX strap %u\n", pipemux);
225 return -EIO;
226 }
227
228 /* no PCIe RC is needed */
229 if (!pipemux_table[pipemux]) {
230 WARN("PIPEMUX indicates no PCIe RC required\n");
231 return -ENODEV;
232 }
233
234 /* save the PIPEMUX strap */
235 pipemux_save_index(pipemux);
236
237 return 0;
238}
239
240/*
241 * PCIe RC serdes link width
242 *
243 * The array is first organized in rows as indexed by the PIPEMUX setting.
244 * Within each row, eight lane width entries are specified -- one entry
245 * per PCIe core, from 0 to 7.
246 *
247 * Note: The EP lanes/cores are not mapped in this table! EP cores are
248 * controlled and thus configured by Nitro.
249 */
250static uint8_t link_width_table[][NUM_OF_SR_PCIE_CORES] = {
251 /* PIPEMUX = 0, EP 1x16 */
252 {0, 0, 0, 0, 0, 0, 0, 0},
253 /* PIPEMUX = 1, EP 1x8 + RC 1x8, core 7 */
254 {0, 0, 0, 0, 0, 0, 0, 8},
255 /* PIPEMUX = 2, EP 4x4 */
256 {0, 0, 0, 0, 0, 0, 0, 0},
257 /* PIPEMUX = 3, RC 2x8, cores 0, 7 */
258 {8, 0, 0, 0, 0, 0, 0, 8},
259 /* PIPEMUX = 4, RC 4x4, cores 0, 1, 6, 7 */
260 {4, 4, 0, 0, 0, 0, 4, 4},
261 /* PIPEMUX = 5, RC 8x2, all 8 cores */
262 {2, 2, 2, 2, 2, 2, 2, 2},
263 /* PIPEMUX = 6, RC 3x4 (cores 0, 6, 7), RC 2x2 (cores 2, 3) */
264 {4, 0, 2, 2, 0, 0, 4, 4},
265 /* PIPEMUX = 7, RC 1x4 (core 0), RC 6x2 (cores 2, 3, 4, 5, 6, 7 */
266 {4, 0, 2, 2, 2, 2, 2, 2},
267 /* PIPEMUX = 8, EP 1x8 + RC 4x2 (cores 4, 5, 6, 7) */
268 {0, 0, 0, 0, 2, 2, 2, 2},
269 /* PIPEMUX = 9, EP 1x8 + RC 2x4 (cores 6, 7) */
270 {0, 0, 0, 0, 0, 0, 4, 4},
271 /* PIPEMUX = 10, EP 2x4 + RC 2x4 (cores 1, 6) */
272 {0, 4, 0, 0, 0, 0, 4, 0},
273 /* PIPEMUX = 11, EP 2x4 + RC 4x2 (cores 2, 3, 4, 5) */
274 {0, 0, 2, 2, 2, 2, 0, 0},
275 /* PIPEMUX = 12, EP 1x4 + RC 6x2 (cores 2, 3, 4, 5, 6, 7) */
276 {0, 0, 2, 2, 2, 2, 2, 2},
277 /* PIPEMUX = 13, EP 2x4 + RC 1x4 (core 6) + RC 2x2 (cores 2, 3) */
278 {0, 0, 2, 2, 0, 0, 4, 0}
279};
280
281/*
282 * function for writes to the Serdes registers through the PMI interface
283 */
284static int paxb_pmi_write(unsigned int core_idx, uint32_t pmi, uint32_t val)
285{
286 uint32_t status;
287 unsigned int timeout = PMI_TIMEOUT_MS;
288
289 paxb_rc_cfg_write(core_idx, CFG_RC_PMI_ADDR, pmi);
290
291 val &= ~CFG_RC_RWCMD_MASK;
292 val |= CFG_RC_WCMD_MASK;
293 paxb_rc_cfg_write(core_idx, CFG_RC_PMI_WDATA, val);
294
295 do {
296 status = paxb_rc_cfg_read(core_idx, CFG_RC_PMI_WDATA);
297
298 /* wait for write command bit to clear */
299 if ((status & CFG_RC_WCMD_MASK) == 0)
300 return 0;
301 } while (--timeout);
302
303 return -EIO;
304}
305
306/*
307 * function for reads from the Serdes registers through the PMI interface
308 */
309static int paxb_pmi_read(unsigned int core_idx, uint32_t pmi, uint32_t *val)
310{
311 uint32_t status;
312 unsigned int timeout = PMI_TIMEOUT_MS;
313
314 paxb_rc_cfg_write(core_idx, CFG_RC_PMI_ADDR, pmi);
315
316 paxb_rc_cfg_write(core_idx, CFG_RC_PMI_WDATA, CFG_RC_RCMD_MASK);
317
318 do {
319 status = paxb_rc_cfg_read(core_idx, CFG_RC_PMI_RDATA);
320
321 /* wait for read ack bit set */
322 if ((status & CFG_RC_RACK_MASK)) {
323 *val = paxb_rc_cfg_read(core_idx, CFG_RC_PMI_RDATA);
324 return 0;
325 }
326 } while (--timeout);
327
328 return -EIO;
329}
330
331
332#ifndef BOARD_PCIE_EXT_CLK
333/*
334 * PCIe Override clock lookup table
335 *
336 * Each array index represents pcie override clock has been done
337 * by CFW or not.
338 */
339static uint8_t pcie_override_clk_table[] = {
340 /* PIPEMUX = 0, EP 1x16 */
341 0x0,
342 /* PIPEMUX = 1, EP 1x8 + RC 1x8, core 7 */
343 0x1,
344 /* PIPEMUX = 2, EP 4x4 */
345 0x0,
346 /* PIPEMUX = 3, RC 2x8, cores 0, 7 */
347 0x0,
348 /* PIPEMUX = 4, RC 4x4, cores 0, 1, 6, 7 */
349 0x0,
350 /* PIPEMUX = 5, RC 8x2, all 8 cores */
351 0x0,
352 /* PIPEMUX = 6, RC 3x4 + 2x2, cores 0, 2, 3, 6, 7 */
353 0x0,
354 /* PIPEMUX = 7, RC 1x4 + 6x2, cores 0, 2, 3, 4, 5, 6, 7 */
355 0x0,
356 /* PIPEMUX = 8, EP 1x8 + RC 4x2, cores 4, 5, 6, 7 */
357 0x0,
358 /* PIPEMUX = 9, EP 1x8 + RC 2x4, cores 6, 7 */
359 0x0,
360 /* PIPEMUX = 10, EP 2x4 + RC 2x4, cores 1, 6 */
361 0x0,
362 /* PIPEMUX = 11, EP 2x4 + RC 4x2, cores 2, 3, 4, 5 */
363 0x0,
364 /* PIPEMUX = 12, EP 1x4 + RC 6x2, cores 2, 3, 4, 5, 6, 7 */
365 0x0,
366 /* PIPEMUX = 13, RC 2x4 + RC 1x4 + 2x2, cores 2, 3, 6 */
367 0x0,
368};
369
370/*
371 * Bring up LCPLL channel 0 reference clock for PCIe serdes used in RC mode
372 */
373static int pcie_lcpll_init(void)
374{
375 uintptr_t reg;
376 unsigned int timeout = PCIE_LCPLL_TIMEOUT_MS;
377 uint32_t val;
378
379 if (pcie_override_clk_table[pipemux_idx]) {
380 /*
381 * Check rc_mode_override again to avoid halt
382 * because of cfw uninitialized lcpll.
383 */
384 reg = (uintptr_t)(PCIE_LCPLL_BASE +
385 PCIE_PIPE_MUX_RC_MODE_OVERRIDE_CFG);
386 val = mmio_read_32(reg);
387 if (val & 0x1)
388 return 0;
389 else
390 return -ENODEV;
391 }
392
393 /* power on PCIe LCPLL and its LDO */
394 reg = (uintptr_t)CRMU_AON_CTRL1;
395 mmio_setbits_32(reg, CRMU_PCIE_LCPLL_PWR_ON_MASK |
396 CRMU_PCIE_LCPLL_PWRON_LDO_MASK);
397 udelay(PCIE_LCPLL_DELAY_US);
398
399 /* remove isolation */
400 mmio_clrbits_32(reg, CRMU_PCIE_LCPLL_ISO_IN_MASK);
401 udelay(PCIE_LCPLL_DELAY_US);
402
403 /* disconnect termination */
404 reg = (uintptr_t)(PCIE_LCPLL_BASE + PCIE_LCPLL_CTRL13_OFFSET);
405 mmio_setbits_32(reg, PCIE_LCPLL_D2C2_TERM_DISC <<
406 PCIE_LCPLL_D2C2_CTRL_SHIFT);
407
408 /* enable CML buf1/2 and D2C2 */
409 reg = (uintptr_t)(PCIE_LCPLL_BASE + PCIE_LCPLL_CTRL3_OFFSET);
410 mmio_setbits_32(reg, PCIE_LCPLL_CM_ENA << PCIE_LCPLL_EN_CTRL_SHIFT);
411
412 /* select diff clock mux out as ref clock */
413 mmio_clrbits_32(reg, PCIE_LCPLL_REF_CLK_MASK);
414
415 /* delay for 500 microseconds per ASIC spec for PCIe LCPLL */
416 udelay(PCIE_LCPLL_DELAY_US);
417
418 /* now bring PCIe LCPLL out of reset */
419 reg = (uintptr_t)(PCIE_LCPLL_BASE + PCIE_LCPLL_CTRL0_OFFSET);
420 mmio_setbits_32(reg, PCIE_LCPLL_RESETB_MASK);
421
422 /* wait for PLL to lock */
423 reg = (uintptr_t)(PCIE_LCPLL_BASE + PCIE_LCPLL_STATUS_OFFSET);
424 do {
425 val = mmio_read_32(reg);
426 if ((val & PCIE_LCPLL_LOCK_MASK) == PCIE_LCPLL_LOCK_MASK) {
427 /* now bring the post divider out of reset */
428 reg = (uintptr_t)(PCIE_LCPLL_BASE +
429 PCIE_LCPLL_CTRL0_OFFSET);
430 mmio_setbits_32(reg, PCIE_LCPLL_P_RESETB_MASK);
431 VERBOSE("PCIe LCPLL locked\n");
432 return 0;
433 }
434 mdelay(1);
435 } while (--timeout);
436
437 ERROR("PCIe LCPLL failed to lock\n");
438 return -EIO;
439}
440#else
441/*
442 * Bring up EXT CLK reference clock for PCIe serdes used in RC mode
443 * XTAL_BYPASS (3 << 0)
444 * INTR_LC_REF (5 << 0)
445 * PD_CML_LC_REF_OUT (1 << 4)
446 * PD_CML_REF_CH_OUT (1 << 8)
447 * CLK_MASTER_SEL (1 << 11)
448 * CLK_MASTER_CTRL_A (1 << 12)
449 * CLK_MASTER_CTRL_B (2 << 14)
450 */
451static const uint16_t pcie_ext_clk[][NUM_OF_PCIE_SERDES] = {
452 /* PIPEMUX = 0, EP 1x16 */
453 {0},
454 /* PIPEMUX = 1, EP 1x8 + RC 1x8, core 7 */
455 {0},
456 /* PIPEMUX = 2, EP 4x4 */
457 {0},
458 /* PIPEMUX = 3, RC 2x8, cores 0, 7 */
459 {0x8803, 0x9115, 0x9115, 0x1115, 0x8803, 0x9115, 0x9115, 0x1115},
460 /* PIPEMUX = 4, RC 4x4, cores 0, 1, 6, 7 */
461 {0x8803, 0x1115, 0x8915, 0x1115, 0x8803, 0x1115, 0x8915, 0x1115,},
462 /* PIPEMUX = 5, RC 8x2, all 8 cores */
463 {0x0803, 0x0915, 0x0915, 0x0915, 0x0803, 0x0915, 0x0915, 0x0915,},
464 /* PIPEMUX = 6, RC 3x4 + 2x2, cores 0, 2, 3, 6, 7 */
465 {0},
466 /* PIPEMUX = 7, RC 1x4 + 6x2, cores 0, 2, 3, 4, 5, 6, 7 */
467 {0},
468 /* PIPEMUX = 8, EP 1x8 + RC 4x2, cores 4, 5, 6, 7 */
469 {0},
470 /* PIPEMUX = 9, EP 1x8 + RC 2x4, cores 6, 7 */
471 {0},
472 /* PIPEMUX = 10, EP 2x4 + RC 2x4, cores 1, 6 */
473 {0},
474 /* PIPEMUX = 11, EP 2x4 + RC 4x2, cores 2, 3, 4, 5 */
475 {0},
476 /* PIPEMUX = 12, EP 1x4 + RC 6x2, cores 2, 3, 4, 5, 6, 7 */
477 {0},
478 /* PIPEMUX = 13, RC 2x4 + RC 1x4 + 2x2, cores 2, 3, 6 */
479 {0},
480};
481
482static void pcie_ext_clk_init(void)
483{
484 unsigned int serdes;
485 uint32_t val;
486
487 for (serdes = 0; serdes < NUM_OF_PCIE_SERDES; serdes++) {
488 val = pcie_ext_clk[pipemux_idx][serdes];
489 if (!val)
490 return;
491 mmio_write_32(PCIE_CORE_RESERVED_CFG +
492 serdes * PCIE_CORE_PWR_OFFSET, val);
493 }
494 /* disable CML buf1/2 and enable D2C2 */
495 mmio_clrsetbits_32((PCIE_LCPLL_BASE + PCIE_LCPLL_CTRL3_OFFSET),
496 PCIE_LCPLL_CM_BUF_ENA << PCIE_LCPLL_EN_CTRL_SHIFT,
497 PCIE_LCPLL_D2C2_ENA << PCIE_LCPLL_EN_CTRL_SHIFT);
498 mmio_write_32(PCIE_LCPLL_BASE + PCIE_TX_CLKMASTER_CTRL_OVERRIDE_CFG, 1);
499 INFO("Overriding Clocking - using REF clock from PAD...\n");
500}
501#endif
502
503static int load_uc(unsigned int core_idx)
504{
505 return 0;
506}
507
508static int paxb_serdes_gate_clock(unsigned int core_idx, int gate_clk)
509{
510 unsigned int link_width, serdes, nr_serdes;
511 uintptr_t pmi_base;
512 unsigned int rdata;
513 uint32_t core_offset = core_idx * PCIE_CORE_PWR_OFFSET;
514
515 link_width = paxb->get_link_width(core_idx);
516 if (!link_width) {
517 ERROR("Unsupported PIPEMUX\n");
518 return -EOPNOTSUPP;
519 }
520
521 nr_serdes = link_width / 2;
522 pmi_base = (uintptr_t)(PCIE_CORE_PMI_CFG_BASE + core_offset);
523
524 for (serdes = 0; serdes < nr_serdes; serdes++) {
525 mmio_write_32(pmi_base, serdes);
526 paxb_pmi_read(core_idx, PMI_ADDR_LANE0(PMI_PLL_CTRL_4), &rdata);
527 if (!gate_clk)
528 rdata |= PMI_SERDES_CLK_ENABLE;
529 else
530 rdata &= ~PMI_SERDES_CLK_ENABLE;
531 paxb_pmi_write(core_idx, PMI_ADDR_BCAST(PMI_PLL_CTRL_4), rdata);
532 }
533 return 0;
534}
535
536static int paxb_gen3_serdes_init(unsigned int core_idx, uint32_t nSerdes)
537{
538 uint32_t rdata;
539 int serdes;
540 uintptr_t pmi_base;
541 unsigned int timeout;
542 unsigned int reg_d230, reg_d267;
543
544
545 pmi_base = (uintptr_t)(PCIE_CORE_PMI_CFG_BASE +
546 (core_idx * PCIE_CORE_PWR_OFFSET));
547
548 for (serdes = 0; serdes < nSerdes; serdes++) {
549 /* select the PMI interface */
550 mmio_write_32(pmi_base, serdes);
551
552 /* Clock enable */
553 paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_A_CLK_CTRL0),
554 0x3);
555
556 /* Release reset of master */
557 paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_A_RST_CTRL0),
558 0x1);
559
560 /* clearing PRAM memory */
561 paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_A_AHB_CTRL0),
562 0x100);
563
564 timeout = UC_RAM_INIT_TIMEOUT;
565 do {
566 paxb_pmi_read(core_idx,
567 PMI_ADDR_LANE0(UC_A_AHB_STAT0),
568 &rdata);
569 } while ((rdata & 0x01) == 0 && timeout--);
570
571 if (!timeout)
572 return -EIO;
573
574 timeout = UC_RAM_INIT_TIMEOUT;
575 do {
576 paxb_pmi_read(core_idx,
577 PMI_ADDR_LANE1(UC_A_AHB_STAT0),
578 &rdata);
579 } while ((rdata & 0x01) == 0 && timeout--);
580
581 if (!timeout)
582 return -EIO;
583
584 /* clearing PRAM memory */
585 paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_A_AHB_CTRL0),
586 0);
587
588 /* to identify 2 lane serdes */
589 paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_DBG1), 0x1);
590
591 /* De-Assert Pram & master resets */
592 paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_A_RST_CTRL0),
593 0x9);
594
595 if (load_uc(core_idx))
596 return -EIO;
597
598 /* UC UC ready for command */
599 paxb_pmi_read(core_idx, PMI_ADDR_LANE0(DSC_UC_CTRL),
600 &rdata);
601 rdata |= DSC_UC_CTRL_RDY_CMD;
602 paxb_pmi_write(core_idx, PMI_ADDR_LANE0(DSC_UC_CTRL),
603 rdata);
604
605 paxb_pmi_read(core_idx, PMI_ADDR_LANE1(DSC_UC_CTRL),
606 &rdata);
607 rdata |= DSC_UC_CTRL_RDY_CMD;
608 paxb_pmi_write(core_idx, PMI_ADDR_LANE1(DSC_UC_CTRL),
609 rdata);
610
611 /* Lane reset */
612 paxb_pmi_write(core_idx,
613 PMI_ADDR_BCAST(LANE_DBG_RST_CTRL), 0x3);
614
615 /* De-Assert Core and Master resets */
616 paxb_pmi_write(core_idx, PMI_ADDR_BCAST(UC_A_RST_CTRL0),
617 0x3);
618
619 timeout = UC_INIT_TIMEOUT;
620 while (timeout--) {
621 paxb_pmi_read(core_idx,
622 PMI_ADDR_LANE0(UC_VERSION_NUM),
623 &reg_d230);
624 paxb_pmi_read(core_idx,
625 PMI_ADDR_LANE0(DSC_SM_CTL22),
626 &reg_d267);
627
628 if (((reg_d230 & 0xffff) != 0) &
629 ((reg_d267 & 0xc000) == 0xc000)) {
630 break;
631 }
632 mdelay(1);
633 }
634
635 if (!timeout)
636 return -EIO;
637
638 timeout = UC_INIT_TIMEOUT;
639 while (timeout--) {
640 paxb_pmi_read(core_idx,
641 PMI_ADDR_LANE1(UC_VERSION_NUM),
642 &reg_d230);
643 paxb_pmi_read(core_idx,
644 PMI_ADDR_LANE1(DSC_SM_CTL22),
645 &reg_d267);
646
647 if (((reg_d230 & 0xffff) != 0) &
648 ((reg_d267 & 0xc000) == 0xc000)) {
649 break;
650 }
651 mdelay(1);
652 }
653
654 if (!timeout)
655 return -EIO;
656 }
657 return 0;
658}
659
660static int pcie_serdes_requires_patch(unsigned int serdes_idx)
661{
662 if (pipemux_idx != SERDES_PATCH_PIPEMUX_INDEX)
663 return 0;
664
665 return !!((SERDES_PATCH_INDEX >> serdes_idx) & 0x1);
666}
667
668static void pcie_tx_coeff_p7(unsigned int core_idx)
669{
670 paxb_pmi_write(core_idx, PMI_ADDR_BCAST(0xd11b), 0x00aa);
671 paxb_pmi_write(core_idx, PMI_ADDR_BCAST(0xd11c), 0x1155);
672 paxb_pmi_write(core_idx, PMI_ADDR_BCAST(0xd11d), 0x2449);
673 paxb_pmi_write(core_idx, PMI_ADDR_BCAST(0xd11e), 0x000f);
674 paxb_pmi_write(core_idx, PMI_ADDR_BCAST(0xd307), 0x0001);
675}
676
677
678static unsigned int paxb_sr_get_rc_link_width(unsigned int core_idx)
679{
680 return link_width_table[pipemux_idx][core_idx];
681}
682
683static uint32_t paxb_sr_get_rc_link_speed(void)
684{
685 return GEN3_LINK_SPEED;
686}
687
688
689static int paxb_serdes_init(unsigned int core_idx, unsigned int nr_serdes)
690{
691 uint32_t core_offset = core_idx * PCIE_CORE_PWR_OFFSET;
692 unsigned int serdes;
693 uintptr_t pmi_base;
694 int ret;
695
696 /*
697 * Each serdes has a x2 link width
698 *
699 * Use PAXB to patch the serdes for proper RX termination through the
700 * PMI interface
701 */
702 pmi_base = (uintptr_t)(PCIE_CORE_PMI_CFG_BASE + core_offset);
703 for (serdes = 0; serdes < nr_serdes; serdes++) {
704 /* select the PMI interface */
705 mmio_write_32(pmi_base, serdes);
706
707 /* patch Serdes for RX termination */
708 ret = paxb_pmi_write(core_idx, PMI_RX_TERM_SEQ,
709 PMI_RX_TERM_VAL);
710 if (ret)
711 goto err_pmi;
712
713 ret = paxb_pmi_write(core_idx, MERLIN16_PCIE_BLK2_PWRMGMT_7,
714 MERLIN16_PCIE_BLK2_PWRMGMT_7_VAL);
715 if (ret)
716 goto err_pmi;
717
718 ret = paxb_pmi_write(core_idx, MERLIN16_PCIE_BLK2_PWRMGMT_8,
719 MERLIN16_PCIE_BLK2_PWRMGMT_8_VAL);
720 if (ret)
721 goto err_pmi;
722
723 ret = paxb_pmi_write(core_idx, MERLIN16_AMS_TX_CTRL_5,
724 MERLIN16_AMS_TX_CTRL_5_VAL);
725 if (ret)
726 goto err_pmi;
727
728 pcie_tx_coeff_p7(core_idx);
729
730 if (pcie_serdes_requires_patch(serdes)) {
731 if (((core_idx == 0) || (core_idx == 7))) {
732 ret = paxb_pmi_write(core_idx,
733 PMI_X8_CORE0_7_PATCH_SEQ,
734 PMI_X8_CORE0_7_PATCH_VAL);
735 if (ret)
736 goto err_pmi;
737 }
738 }
739 }
740
741 return 0;
742
743err_pmi:
744 ERROR("PCIe PMI write failed\n");
745 return ret;
746}
747
748static int paxb_sr_phy_init(void)
749{
750 int ret;
751 unsigned int core_idx;
752
753#ifndef BOARD_PCIE_EXT_CLK
754 ret = pcie_lcpll_init();
755 if (ret)
756 return ret;
757#else
758 pcie_ext_clk_init();
759#endif
760
761 for (core_idx = 0; core_idx < paxb->num_cores; core_idx++) {
762 if (!pcie_core_needs_enable(core_idx))
763 continue;
764 unsigned int link_width;
765
766 paxb_serdes_gate_clock(core_idx, 0);
767
768 link_width = paxb->get_link_width(core_idx);
769 if (!link_width) {
770 ERROR("Unsupported PIPEMUX\n");
771 return -EOPNOTSUPP;
772 }
773
774 ret = paxb_serdes_init(core_idx, link_width / 2);
775 if (ret) {
776 ERROR("PCIe serdes initialization failed for core %u\n",
777 core_idx);
778 return ret;
779 }
780
781
782 ret = paxb_gen3_serdes_init(core_idx, link_width / 2);
783 if (ret) {
784 ERROR("PCIe GEN3 serdes initialization failed\n");
785 return ret;
786 }
787
788 }
789 return 0;
790}
791
792const paxb_cfg sr_paxb_cfg = {
793 .type = PAXB_SR,
794 .device_id = SR_B0_DEVICE_ID,
795 .pipemux_init = pipemux_sr_init,
796 .phy_init = paxb_sr_phy_init,
797 .core_needs_enable = paxb_sr_core_needs_enable,
798 .num_cores = NUM_OF_SR_PCIE_CORES,
799 .get_link_width = paxb_sr_get_rc_link_width,
800 .get_link_speed = paxb_sr_get_rc_link_speed,
801};
802
803const paxb_cfg *paxb_get_sr_config(void)
804{
805 return &sr_paxb_cfg;
806}