1 /*
2  * Copyright 2011-2012 Freescale Semiconductor, Inc.
3  *
4  * SPDX-License-Identifier:	GPL-2.0+
5  */
6 
7 #include <common.h>
8 #include <command.h>
9 #include <i2c.h>
10 #include <netdev.h>
11 #include <linux/compiler.h>
12 #include <asm/mmu.h>
13 #include <asm/processor.h>
14 #include <asm/cache.h>
15 #include <asm/immap_85xx.h>
16 #include <asm/fsl_law.h>
17 #include <asm/fsl_serdes.h>
18 #include <asm/fsl_portals.h>
19 #include <asm/fsl_liodn.h>
20 #include <fm_eth.h>
21 
22 #include "../common/qixis.h"
23 #include "../common/vsc3316_3308.h"
24 #include "../common/idt8t49n222a_serdes_clk.h"
25 #include "b4860qds.h"
26 #include "b4860qds_qixis.h"
27 #include "b4860qds_crossbar_con.h"
28 
29 #define CLK_MUX_SEL_MASK	0x4
30 #define ETH_PHY_CLK_OUT		0x4
31 #define PLL_NUM			2
32 
33 DECLARE_GLOBAL_DATA_PTR;
34 
35 int checkboard(void)
36 {
37 	char buf[64];
38 	u8 sw;
39 	struct cpu_type *cpu = gd->arch.cpu;
40 	static const char *const freq[] = {"100", "125", "156.25", "161.13",
41 						"122.88", "122.88", "122.88"};
42 	int clock;
43 
44 	printf("Board: %sQDS, ", cpu->name);
45 	printf("Sys ID: 0x%02x, Sys Ver: 0x%02x, ",
46 		QIXIS_READ(id), QIXIS_READ(arch));
47 
48 	sw = QIXIS_READ(brdcfg[0]);
49 	sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT;
50 
51 	if (sw < 0x8)
52 		printf("vBank: %d\n", sw);
53 	else if (sw >= 0x8 && sw <= 0xE)
54 		puts("NAND\n");
55 	else
56 		printf("invalid setting of SW%u\n", QIXIS_LBMAP_SWITCH);
57 
58 	printf("FPGA: v%d (%s), build %d",
59 		(int)QIXIS_READ(scver), qixis_read_tag(buf),
60 		(int)qixis_read_minor());
61 	/* the timestamp string contains "\n" at the end */
62 	printf(" on %s", qixis_read_time(buf));
63 
64 	/*
65 	 * Display the actual SERDES reference clocks as configured by the
66 	 * dip switches on the board.  Note that the SWx registers could
67 	 * technically be set to force the reference clocks to match the
68 	 * values that the SERDES expects (or vice versa).  For now, however,
69 	 * we just display both values and hope the user notices when they
70 	 * don't match.
71 	 */
72 	puts("SERDES Reference Clocks: ");
73 	sw = QIXIS_READ(brdcfg[2]);
74 	clock = (sw >> 5) & 7;
75 	printf("Bank1=%sMHz ", freq[clock]);
76 	sw = QIXIS_READ(brdcfg[4]);
77 	clock = (sw >> 6) & 3;
78 	printf("Bank2=%sMHz\n", freq[clock]);
79 
80 	return 0;
81 }
82 
83 int select_i2c_ch_pca(u8 ch)
84 {
85 	int ret;
86 
87 	/* Selecting proper channel via PCA*/
88 	ret = i2c_write(I2C_MUX_PCA_ADDR, 0x0, 1, &ch, 1);
89 	if (ret) {
90 		printf("PCA: failed to select proper channel.\n");
91 		return ret;
92 	}
93 
94 	return 0;
95 }
96 
97 int configure_vsc3316_3308(void)
98 {
99 	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
100 	unsigned int num_vsc16_con, num_vsc08_con;
101 	u32 serdes1_prtcl, serdes2_prtcl;
102 	int ret;
103 
104 	serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
105 			FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
106 	if (!serdes1_prtcl) {
107 		printf("SERDES1 is not enabled\n");
108 		return 0;
109 	}
110 	serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
111 	debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
112 
113 	serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
114 			FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
115 	if (!serdes2_prtcl) {
116 		printf("SERDES2 is not enabled\n");
117 		return 0;
118 	}
119 	serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
120 	debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
121 
122 	switch (serdes1_prtcl) {
123 	case 0x2a:
124 	case 0x2C:
125 	case 0x2D:
126 	case 0x2E:
127 			/*
128 			 * Configuration:
129 			 * SERDES: 1
130 			 * Lanes: A,B: SGMII
131 			 * Lanes: C,D,E,F,G,H: CPRI
132 			 */
133 		debug("Configuring crossbar to use onboard SGMII PHYs:"
134 				"srds_prctl:%x\n", serdes1_prtcl);
135 		num_vsc16_con = NUM_CON_VSC3316;
136 		/* Configure VSC3316 crossbar switch */
137 		ret = select_i2c_ch_pca(I2C_CH_VSC3316);
138 		if (!ret) {
139 			ret = vsc3316_config(VSC3316_TX_ADDRESS,
140 					vsc16_tx_4sfp_sgmii_12_56,
141 					num_vsc16_con);
142 			if (ret)
143 				return ret;
144 			ret = vsc3316_config(VSC3316_RX_ADDRESS,
145 					vsc16_rx_4sfp_sgmii_12_56,
146 					num_vsc16_con);
147 			if (ret)
148 				return ret;
149 		} else {
150 			return ret;
151 		}
152 		break;
153 
154 #ifdef CONFIG_PPC_B4420
155 	case 0x18:
156 			/*
157 			 * Configuration:
158 			 * SERDES: 1
159 			 * Lanes: A,B,C,D: SGMII
160 			 * Lanes: E,F,G,H: CPRI
161 			 */
162 		debug("Configuring crossbar to use onboard SGMII PHYs:"
163 				"srds_prctl:%x\n", serdes1_prtcl);
164 		num_vsc16_con = NUM_CON_VSC3316;
165 		/* Configure VSC3316 crossbar switch */
166 		ret = select_i2c_ch_pca(I2C_CH_VSC3316);
167 		if (!ret) {
168 			ret = vsc3316_config(VSC3316_TX_ADDRESS,
169 					vsc16_tx_sgmii_lane_cd, num_vsc16_con);
170 			if (ret)
171 				return ret;
172 			ret = vsc3316_config(VSC3316_RX_ADDRESS,
173 					vsc16_rx_sgmii_lane_cd, num_vsc16_con);
174 			if (ret)
175 				return ret;
176 		} else {
177 			return ret;
178 		}
179 		break;
180 #endif
181 
182 	case 0x3E:
183 	case 0x0D:
184 	case 0x0E:
185 	case 0x12:
186 		num_vsc16_con = NUM_CON_VSC3316;
187 		/* Configure VSC3316 crossbar switch */
188 		ret = select_i2c_ch_pca(I2C_CH_VSC3316);
189 		if (!ret) {
190 			ret = vsc3316_config(VSC3316_TX_ADDRESS,
191 					vsc16_tx_sfp, num_vsc16_con);
192 			if (ret)
193 				return ret;
194 			ret = vsc3316_config(VSC3316_RX_ADDRESS,
195 					vsc16_rx_sfp, num_vsc16_con);
196 			if (ret)
197 				return ret;
198 		} else {
199 			return ret;
200 		}
201 		break;
202 	default:
203 		printf("WARNING:VSC crossbars programming not supported for:%x"
204 					" SerDes1 Protocol.\n", serdes1_prtcl);
205 		return -1;
206 	}
207 
208 	switch (serdes2_prtcl) {
209 	case 0x9E:
210 	case 0x9A:
211 	case 0x98:
212 	case 0xb2:
213 	case 0x49:
214 	case 0x4E:
215 	case 0x8D:
216 	case 0x7A:
217 		num_vsc08_con = NUM_CON_VSC3308;
218 		/* Configure VSC3308 crossbar switch */
219 		ret = select_i2c_ch_pca(I2C_CH_VSC3308);
220 		if (!ret) {
221 			ret = vsc3308_config(VSC3308_TX_ADDRESS,
222 					vsc08_tx_amc, num_vsc08_con);
223 			if (ret)
224 				return ret;
225 			ret = vsc3308_config(VSC3308_RX_ADDRESS,
226 					vsc08_rx_amc, num_vsc08_con);
227 			if (ret)
228 				return ret;
229 		} else {
230 			return ret;
231 		}
232 		break;
233 	default:
234 		printf("WARNING:VSC crossbars programming not supported for: %x"
235 					" SerDes2 Protocol.\n", serdes2_prtcl);
236 		return -1;
237 	}
238 
239 	return 0;
240 }
241 
242 int config_serdes1_refclks(void)
243 {
244 	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
245 	serdes_corenet_t *srds_regs =
246 		(void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
247 	u32 serdes1_prtcl, lane;
248 	unsigned int flag_sgmii_prtcl = 0;
249 	int ret, i;
250 
251 	serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
252 			FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
253 	if (!serdes1_prtcl) {
254 		printf("SERDES1 is not enabled\n");
255 		return -1;
256 	}
257 	serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
258 	debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
259 
260 	/* Clear SRDS_RSTCTL_RST bit for both PLLs before changing refclks
261 	 */
262 	for (i = 0; i < PLL_NUM; i++)
263 		clrbits_be32(&srds_regs->bank[i].rstctl, SRDS_RSTCTL_RST);
264 	/* Reconfigure IDT idt8t49n222a device for CPRI to work
265 	 * For this SerDes1's Refclk1 and refclk2 need to be set
266 	 * to 122.88MHz
267 	 */
268 	switch (serdes1_prtcl) {
269 	case 0x2A:
270 	case 0x2C:
271 	case 0x2D:
272 	case 0x2E:
273 		debug("Configuring idt8t49n222a for CPRI SerDes clks:"
274 			" for srds_prctl:%x\n", serdes1_prtcl);
275 		ret = select_i2c_ch_pca(I2C_CH_IDT);
276 		if (!ret) {
277 			ret = set_serdes_refclk(IDT_SERDES1_ADDRESS, 1,
278 					SERDES_REFCLK_122_88,
279 					SERDES_REFCLK_122_88, 0);
280 			if (ret) {
281 				printf("IDT8T49N222A configuration failed.\n");
282 				return ret;
283 			} else
284 				printf("IDT8T49N222A configured.\n");
285 		} else {
286 			return ret;
287 		}
288 		select_i2c_ch_pca(I2C_CH_DEFAULT);
289 
290 		/* Change SerDes1's Refclk1 to 125MHz for on board
291 		 * SGMIIs to work
292 		 */
293 		for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
294 			enum srds_prtcl lane_prtcl = serdes_get_prtcl
295 						(0, serdes1_prtcl, lane);
296 			switch (lane_prtcl) {
297 			case SGMII_FM1_DTSEC1:
298 			case SGMII_FM1_DTSEC2:
299 			case SGMII_FM1_DTSEC3:
300 			case SGMII_FM1_DTSEC4:
301 			case SGMII_FM1_DTSEC5:
302 			case SGMII_FM1_DTSEC6:
303 				flag_sgmii_prtcl++;
304 				break;
305 			default:
306 				break;
307 			}
308 		}
309 
310 		if (flag_sgmii_prtcl)
311 			QIXIS_WRITE(brdcfg[4], QIXIS_SRDS1CLK_125);
312 
313 		/* Steps For SerDes PLLs reset and reconfiguration after
314 		 * changing SerDes's refclks
315 		 */
316 		for (i = 0; i < PLL_NUM; i++) {
317 			debug("For PLL%d reset and reconfiguration after"
318 			       " changing refclks\n", i+1);
319 			clrbits_be32(&srds_regs->bank[i].rstctl,
320 					SRDS_RSTCTL_SDRST_B);
321 			udelay(10);
322 			clrbits_be32(&srds_regs->bank[i].rstctl,
323 				(SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
324 			udelay(10);
325 			setbits_be32(&srds_regs->bank[i].rstctl,
326 					SRDS_RSTCTL_RST);
327 			setbits_be32(&srds_regs->bank[i].rstctl,
328 				(SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
329 				| SRDS_RSTCTL_SDRST_B));
330 		}
331 		break;
332 	default:
333 		printf("WARNING:IDT8T49N222A configuration not"
334 			" supported for:%x SerDes1 Protocol.\n",
335 			serdes1_prtcl);
336 		return -1;
337 	}
338 
339 	return 0;
340 }
341 
342 int board_early_init_r(void)
343 {
344 	const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;
345 	const u8 flash_esel = find_tlb_idx((void *)flashbase, 1);
346 
347 	/*
348 	 * Remap Boot flash + PROMJET region to caching-inhibited
349 	 * so that flash can be erased properly.
350 	 */
351 
352 	/* Flush d-cache and invalidate i-cache of any FLASH data */
353 	flush_dcache();
354 	invalidate_icache();
355 
356 	/* invalidate existing TLB entry for flash + promjet */
357 	disable_tlb(flash_esel);
358 
359 	set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS,
360 			MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
361 			0, flash_esel, BOOKE_PAGESZ_256M, 1);
362 
363 	set_liodns();
364 #ifdef CONFIG_SYS_DPAA_QBMAN
365 	setup_portals();
366 #endif
367 	/* SerDes1 refclks need to be set again, as default clks
368 	 * are not suitable for CPRI and onboard SGMIIs to work
369 	 * simultaneously.
370 	 * This function will set SerDes1's Refclk1 and refclk2
371 	 * as per SerDes1 protocols
372 	 */
373 	if (config_serdes1_refclks())
374 		printf("SerDes1 Refclks couldn't set properly.\n");
375 	else
376 		printf("SerDes1 Refclks have been set.\n");
377 
378 	/* Configure VSC3316 and VSC3308 crossbar switches */
379 	if (configure_vsc3316_3308())
380 		printf("VSC:failed to configure VSC3316/3308.\n");
381 	else
382 		printf("VSC:VSC3316/3308 successfully configured.\n");
383 
384 	select_i2c_ch_pca(I2C_CH_DEFAULT);
385 
386 	return 0;
387 }
388 
389 unsigned long get_board_sys_clk(void)
390 {
391 	u8 sysclk_conf = QIXIS_READ(brdcfg[1]);
392 
393 	switch ((sysclk_conf & 0x0C) >> 2) {
394 	case QIXIS_CLK_100:
395 		return 100000000;
396 	case QIXIS_CLK_125:
397 		return 125000000;
398 	case QIXIS_CLK_133:
399 		return 133333333;
400 	}
401 	return 66666666;
402 }
403 
404 unsigned long get_board_ddr_clk(void)
405 {
406 	u8 ddrclk_conf = QIXIS_READ(brdcfg[1]);
407 
408 	switch (ddrclk_conf & 0x03) {
409 	case QIXIS_CLK_100:
410 		return 100000000;
411 	case QIXIS_CLK_125:
412 		return 125000000;
413 	case QIXIS_CLK_133:
414 		return 133333333;
415 	}
416 	return 66666666;
417 }
418 
419 static int serdes_refclock(u8 sw, u8 sdclk)
420 {
421 	unsigned int clock;
422 	int ret = -1;
423 	u8 brdcfg4;
424 
425 	if (sdclk == 1) {
426 		brdcfg4 = QIXIS_READ(brdcfg[4]);
427 		if ((brdcfg4 & CLK_MUX_SEL_MASK) == ETH_PHY_CLK_OUT)
428 			return SRDS_PLLCR0_RFCK_SEL_125;
429 		else
430 			clock = (sw >> 5) & 7;
431 	} else
432 		clock = (sw >> 6) & 3;
433 
434 	switch (clock) {
435 	case 0:
436 		ret = SRDS_PLLCR0_RFCK_SEL_100;
437 		break;
438 	case 1:
439 		ret = SRDS_PLLCR0_RFCK_SEL_125;
440 		break;
441 	case 2:
442 		ret = SRDS_PLLCR0_RFCK_SEL_156_25;
443 		break;
444 	case 3:
445 		ret = SRDS_PLLCR0_RFCK_SEL_161_13;
446 		break;
447 	case 4:
448 	case 5:
449 	case 6:
450 		ret = SRDS_PLLCR0_RFCK_SEL_122_88;
451 		break;
452 	default:
453 		ret = -1;
454 		break;
455 	}
456 
457 	return ret;
458 }
459 
460 static const char *serdes_clock_to_string(u32 clock)
461 {
462 	switch (clock) {
463 	case SRDS_PLLCR0_RFCK_SEL_100:
464 		return "100";
465 	case SRDS_PLLCR0_RFCK_SEL_125:
466 		return "125";
467 	case SRDS_PLLCR0_RFCK_SEL_156_25:
468 		return "156.25";
469 	case SRDS_PLLCR0_RFCK_SEL_161_13:
470 		return "161.13";
471 	default:
472 		return "122.88";
473 	}
474 }
475 
476 #define NUM_SRDS_BANKS	2
477 
478 int misc_init_r(void)
479 {
480 	u8 sw;
481 	serdes_corenet_t *srds_regs =
482 		(void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
483 	u32 actual[NUM_SRDS_BANKS];
484 	unsigned int i;
485 	int clock;
486 
487 	sw = QIXIS_READ(brdcfg[2]);
488 	clock = serdes_refclock(sw, 1);
489 	if (clock >= 0)
490 		actual[0] = clock;
491 	else
492 		printf("Warning: SDREFCLK1 switch setting is unsupported\n");
493 
494 	sw = QIXIS_READ(brdcfg[4]);
495 	clock = serdes_refclock(sw, 2);
496 	if (clock >= 0)
497 		actual[1] = clock;
498 	else
499 		printf("Warning: SDREFCLK2 switch setting unsupported\n");
500 
501 	for (i = 0; i < NUM_SRDS_BANKS; i++) {
502 		u32 pllcr0 = srds_regs->bank[i].pllcr0;
503 		u32 expected = pllcr0 & SRDS_PLLCR0_RFCK_SEL_MASK;
504 		if (expected != actual[i]) {
505 			printf("Warning: SERDES bank %u expects reference clock"
506 			       " %sMHz, but actual is %sMHz\n", i + 1,
507 			       serdes_clock_to_string(expected),
508 			       serdes_clock_to_string(actual[i]));
509 		}
510 	}
511 
512 	return 0;
513 }
514 
515 void ft_board_setup(void *blob, bd_t *bd)
516 {
517 	phys_addr_t base;
518 	phys_size_t size;
519 
520 	ft_cpu_setup(blob, bd);
521 
522 	base = getenv_bootm_low();
523 	size = getenv_bootm_size();
524 
525 	fdt_fixup_memory(blob, (u64)base, (u64)size);
526 
527 #ifdef CONFIG_PCI
528 	pci_of_setup(blob, bd);
529 #endif
530 
531 	fdt_fixup_liodn(blob);
532 
533 #ifdef CONFIG_HAS_FSL_DR_USB
534 	fdt_fixup_dr_usb(blob, bd);
535 #endif
536 
537 #ifdef CONFIG_SYS_DPAA_FMAN
538 	fdt_fixup_fman_ethernet(blob);
539 	fdt_fixup_board_enet(blob);
540 #endif
541 }
542 
543 /*
544  * Dump board switch settings.
545  * The bits that cannot be read/sampled via some FPGA or some
546  * registers, they will be displayed as
547  * underscore in binary format. mask[] has those bits.
548  * Some bits are calculated differently than the actual switches
549  * if booting with overriding by FPGA.
550  */
551 void qixis_dump_switch(void)
552 {
553 	int i;
554 	u8 sw[5];
555 
556 	/*
557 	 * Any bit with 1 means that bit cannot be reverse engineered.
558 	 * It will be displayed as _ in binary format.
559 	 */
560 	static const u8 mask[] = {0x07, 0, 0, 0xff, 0};
561 	char buf[10];
562 	u8 brdcfg[16], dutcfg[16];
563 
564 	for (i = 0; i < 16; i++) {
565 		brdcfg[i] = qixis_read(offsetof(struct qixis, brdcfg[0]) + i);
566 		dutcfg[i] = qixis_read(offsetof(struct qixis, dutcfg[0]) + i);
567 	}
568 
569 	sw[0] = ((brdcfg[0] & 0x0f) << 4)	| \
570 		(brdcfg[9] & 0x08);
571 	sw[1] = ((dutcfg[1] & 0x01) << 7)	| \
572 		((dutcfg[2] & 0x07) << 4)       | \
573 		((dutcfg[6] & 0x10) >> 1)       | \
574 		((dutcfg[6] & 0x80) >> 5)       | \
575 		((dutcfg[1] & 0x40) >> 5)       | \
576 		(dutcfg[6] & 0x01);
577 	sw[2] = dutcfg[0];
578 	sw[3] = 0;
579 	sw[4] = ((brdcfg[1] & 0x30) << 2)	| \
580 		((brdcfg[1] & 0xc0) >> 2)	| \
581 		(brdcfg[1] & 0x0f);
582 
583 	puts("DIP switch settings:\n");
584 	for (i = 0; i < 5; i++) {
585 		printf("SW%d         = 0b%s (0x%02x)\n",
586 			i + 1, byte_to_binary_mask(sw[i], mask[i], buf), sw[i]);
587 	}
588 }
589