• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 */
134 static 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  */
143 static 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  */
pipemux_strap_is_valid(uint32_t pipemux)177 static 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  */
pipemux_strap_read(void)188 static 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  */
pipemux_save_index(unsigned int idx)207 static void pipemux_save_index(unsigned int idx)
208 {
209 	pipemux_idx = idx;
210 }
211 
paxb_sr_core_needs_enable(unsigned int core_idx)212 static int paxb_sr_core_needs_enable(unsigned int core_idx)
213 {
214 	return !!((pipemux_table[pipemux_idx] >> core_idx) & 0x1);
215 }
216 
pipemux_sr_init(void)217 static 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  */
250 static 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  */
paxb_pmi_write(unsigned int core_idx,uint32_t pmi,uint32_t val)284 static 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  */
paxb_pmi_read(unsigned int core_idx,uint32_t pmi,uint32_t * val)309 static 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  */
339 static 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  */
pcie_lcpll_init(void)373 static 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  */
451 static 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 
pcie_ext_clk_init(void)482 static 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 
load_uc(unsigned int core_idx)503 static int load_uc(unsigned int core_idx)
504 {
505 	return 0;
506 }
507 
paxb_serdes_gate_clock(unsigned int core_idx,int gate_clk)508 static 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 
paxb_gen3_serdes_init(unsigned int core_idx,uint32_t nSerdes)536 static 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 
pcie_serdes_requires_patch(unsigned int serdes_idx)660 static 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 
pcie_tx_coeff_p7(unsigned int core_idx)668 static 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 
paxb_sr_get_rc_link_width(unsigned int core_idx)678 static unsigned int paxb_sr_get_rc_link_width(unsigned int core_idx)
679 {
680 	return link_width_table[pipemux_idx][core_idx];
681 }
682 
paxb_sr_get_rc_link_speed(void)683 static uint32_t paxb_sr_get_rc_link_speed(void)
684 {
685 	return GEN3_LINK_SPEED;
686 }
687 
688 
paxb_serdes_init(unsigned int core_idx,unsigned int nr_serdes)689 static 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 
743 err_pmi:
744 	ERROR("PCIe PMI write failed\n");
745 	return ret;
746 }
747 
paxb_sr_phy_init(void)748 static 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 
792 const 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 
paxb_get_sr_config(void)803 const paxb_cfg *paxb_get_sr_config(void)
804 {
805 	return &sr_paxb_cfg;
806 }
807