1 /*
2  * Copyright 2011-2012 Freescale Semiconductor, Inc.
3  *
4  * See file CREDITS for list of people who contributed to this
5  * project.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of
10  * the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20  * MA 02111-1307 USA
21  */
22 
23 #include <common.h>
24 #include <command.h>
25 #include <i2c.h>
26 #include <netdev.h>
27 #include <linux/compiler.h>
28 #include <asm/mmu.h>
29 #include <asm/processor.h>
30 #include <asm/cache.h>
31 #include <asm/immap_85xx.h>
32 #include <asm/fsl_law.h>
33 #include <asm/fsl_serdes.h>
34 #include <asm/fsl_portals.h>
35 #include <asm/fsl_liodn.h>
36 #include <fm_eth.h>
37 
38 #include "../common/qixis.h"
39 #include "../common/vsc3316_3308.h"
40 #include "b4860qds.h"
41 #include "b4860qds_qixis.h"
42 #include "b4860qds_crossbar_con.h"
43 
44 #define CLK_MUX_SEL_MASK	0x4
45 #define ETH_PHY_CLK_OUT		0x4
46 
47 DECLARE_GLOBAL_DATA_PTR;
48 
49 int checkboard(void)
50 {
51 	char buf[64];
52 	u8 sw;
53 	struct cpu_type *cpu = gd->arch.cpu;
54 	ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
55 	unsigned int i;
56 	static const char *const freq[] = {"100", "125", "156.25", "161.13",
57 						"122.88", "122.88", "122.88"};
58 	int clock;
59 
60 	printf("Board: %sQDS, ", cpu->name);
61 	printf("Sys ID: 0x%02x, Sys Ver: 0x%02x, ",
62 		QIXIS_READ(id), QIXIS_READ(arch));
63 
64 	sw = QIXIS_READ(brdcfg[0]);
65 	sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT;
66 
67 	if (sw < 0x8)
68 		printf("vBank: %d\n", sw);
69 	else if (sw >= 0x8 && sw <= 0xE)
70 		puts("NAND\n");
71 	else
72 		printf("invalid setting of SW%u\n", QIXIS_LBMAP_SWITCH);
73 
74 	printf("FPGA: v%d (%s), build %d",
75 		(int)QIXIS_READ(scver), qixis_read_tag(buf),
76 		(int)qixis_read_minor());
77 	/* the timestamp string contains "\n" at the end */
78 	printf(" on %s", qixis_read_time(buf));
79 
80 	/* Display the RCW, so that no one gets confused as to what RCW
81 	 * we're actually using for this boot.
82 	 */
83 	puts("Reset Configuration Word (RCW):");
84 	for (i = 0; i < ARRAY_SIZE(gur->rcwsr); i++) {
85 		u32 rcw = in_be32(&gur->rcwsr[i]);
86 
87 		if ((i % 4) == 0)
88 			printf("\n       %08x:", i * 4);
89 		printf(" %08x", rcw);
90 	}
91 	puts("\n");
92 
93 	/*
94 	 * Display the actual SERDES reference clocks as configured by the
95 	 * dip switches on the board.  Note that the SWx registers could
96 	 * technically be set to force the reference clocks to match the
97 	 * values that the SERDES expects (or vice versa).  For now, however,
98 	 * we just display both values and hope the user notices when they
99 	 * don't match.
100 	 */
101 	puts("SERDES Reference Clocks: ");
102 	sw = QIXIS_READ(brdcfg[2]);
103 	clock = (sw >> 5) & 7;
104 	printf("Bank1=%sMHz ", freq[clock]);
105 	sw = QIXIS_READ(brdcfg[4]);
106 	clock = (sw >> 6) & 3;
107 	printf("Bank2=%sMHz\n", freq[clock]);
108 
109 	return 0;
110 }
111 
112 int select_i2c_ch_pca(u8 ch)
113 {
114 	int ret;
115 
116 	/* Selecting proper channel via PCA*/
117 	ret = i2c_write(I2C_MUX_PCA_ADDR, 0x0, 1, &ch, 1);
118 	if (ret) {
119 		printf("PCA: failed to select proper channel.\n");
120 		return ret;
121 	}
122 
123 	return 0;
124 }
125 
126 int configure_vsc3316_3308(void)
127 {
128 	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
129 	unsigned int num_vsc16_con, num_vsc08_con;
130 	u32 serdes1_prtcl, serdes2_prtcl;
131 	int ret;
132 
133 	serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
134 			FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
135 	if (!serdes1_prtcl) {
136 		printf("SERDES1 is not enabled\n");
137 		return 0;
138 	}
139 	serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
140 	debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
141 
142 	serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
143 			FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
144 	if (!serdes2_prtcl) {
145 		printf("SERDES2 is not enabled\n");
146 		return 0;
147 	}
148 	serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
149 	debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
150 
151 	switch (serdes1_prtcl) {
152 	case 0x2a:
153 	case 0x2C:
154 	case 0x2D:
155 	case 0x2E:
156 			/*
157 			 * Configuration:
158 			 * SERDES: 1
159 			 * Lanes: A,B: SGMII
160 			 * Lanes: C,D,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_ab, num_vsc16_con);
170 			if (ret)
171 				return ret;
172 			ret = vsc3316_config(VSC3316_RX_ADDRESS,
173 					vsc16_rx_sgmii_lane_ab, num_vsc16_con);
174 			if (ret)
175 				return ret;
176 		} else {
177 			return ret;
178 		}
179 		break;
180 
181 #ifdef CONFIG_PPC_B4420
182 	case 0x18:
183 			/*
184 			 * Configuration:
185 			 * SERDES: 1
186 			 * Lanes: A,B,C,D: SGMII
187 			 * Lanes: E,F,G,H: CPRI
188 			 */
189 		debug("Configuring crossbar to use onboard SGMII PHYs:"
190 				"srds_prctl:%x\n", serdes1_prtcl);
191 		num_vsc16_con = NUM_CON_VSC3316;
192 		/* Configure VSC3316 crossbar switch */
193 		ret = select_i2c_ch_pca(I2C_CH_VSC3316);
194 		if (!ret) {
195 			ret = vsc3316_config(VSC3316_TX_ADDRESS,
196 					vsc16_tx_sgmii_lane_cd, num_vsc16_con);
197 			if (ret)
198 				return ret;
199 			ret = vsc3316_config(VSC3316_RX_ADDRESS,
200 					vsc16_rx_sgmii_lane_cd, num_vsc16_con);
201 			if (ret)
202 				return ret;
203 		} else {
204 			return ret;
205 		}
206 		break;
207 #endif
208 
209 	case 0x3E:
210 	case 0x0D:
211 	case 0x0E:
212 	case 0x12:
213 		num_vsc16_con = NUM_CON_VSC3316;
214 		/* Configure VSC3316 crossbar switch */
215 		ret = select_i2c_ch_pca(I2C_CH_VSC3316);
216 		if (!ret) {
217 			ret = vsc3316_config(VSC3316_TX_ADDRESS,
218 					vsc16_tx_sfp, num_vsc16_con);
219 			if (ret)
220 				return ret;
221 			ret = vsc3316_config(VSC3316_RX_ADDRESS,
222 					vsc16_rx_sfp, num_vsc16_con);
223 			if (ret)
224 				return ret;
225 		} else {
226 			return ret;
227 		}
228 		break;
229 	default:
230 		printf("WARNING:VSC crossbars programming not supported for:%x"
231 					" SerDes1 Protocol.\n", serdes1_prtcl);
232 		return -1;
233 	}
234 
235 	switch (serdes2_prtcl) {
236 	case 0x9E:
237 	case 0x9A:
238 	case 0x98:
239 	case 0xb2:
240 	case 0x49:
241 	case 0x4E:
242 	case 0x8D:
243 	case 0x7A:
244 		num_vsc08_con = NUM_CON_VSC3308;
245 		/* Configure VSC3308 crossbar switch */
246 		ret = select_i2c_ch_pca(I2C_CH_VSC3308);
247 		if (!ret) {
248 			ret = vsc3308_config(VSC3308_TX_ADDRESS,
249 					vsc08_tx_amc, num_vsc08_con);
250 			if (ret)
251 				return ret;
252 			ret = vsc3308_config(VSC3308_RX_ADDRESS,
253 					vsc08_rx_amc, num_vsc08_con);
254 			if (ret)
255 				return ret;
256 		} else {
257 			return ret;
258 		}
259 		break;
260 	default:
261 		printf("WARNING:VSC crossbars programming not supported for: %x"
262 					" SerDes2 Protocol.\n", serdes2_prtcl);
263 		return -1;
264 	}
265 
266 	return 0;
267 }
268 
269 int board_early_init_r(void)
270 {
271 	const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;
272 	const u8 flash_esel = find_tlb_idx((void *)flashbase, 1);
273 
274 	/*
275 	 * Remap Boot flash + PROMJET region to caching-inhibited
276 	 * so that flash can be erased properly.
277 	 */
278 
279 	/* Flush d-cache and invalidate i-cache of any FLASH data */
280 	flush_dcache();
281 	invalidate_icache();
282 
283 	/* invalidate existing TLB entry for flash + promjet */
284 	disable_tlb(flash_esel);
285 
286 	set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS,
287 			MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
288 			0, flash_esel, BOOKE_PAGESZ_256M, 1);
289 
290 	set_liodns();
291 #ifdef CONFIG_SYS_DPAA_QBMAN
292 	setup_portals();
293 #endif
294 
295 	/* Configure VSC3316 and VSC3308 crossbar switches */
296 	if (configure_vsc3316_3308())
297 		printf("VSC:failed to configure VSC3316/3308.\n");
298 	else
299 		printf("VSC:VSC3316/3308 successfully configured.\n");
300 
301 	select_i2c_ch_pca(I2C_CH_DEFAULT);
302 
303 	return 0;
304 }
305 
306 unsigned long get_board_sys_clk(void)
307 {
308 	u8 sysclk_conf = QIXIS_READ(brdcfg[1]);
309 
310 	switch ((sysclk_conf & 0x0C) >> 2) {
311 	case QIXIS_CLK_100:
312 		return 100000000;
313 	case QIXIS_CLK_125:
314 		return 125000000;
315 	case QIXIS_CLK_133:
316 		return 133333333;
317 	}
318 	return 66666666;
319 }
320 
321 unsigned long get_board_ddr_clk(void)
322 {
323 	u8 ddrclk_conf = QIXIS_READ(brdcfg[1]);
324 
325 	switch (ddrclk_conf & 0x03) {
326 	case QIXIS_CLK_100:
327 		return 100000000;
328 	case QIXIS_CLK_125:
329 		return 125000000;
330 	case QIXIS_CLK_133:
331 		return 133333333;
332 	}
333 	return 66666666;
334 }
335 
336 static int serdes_refclock(u8 sw, u8 sdclk)
337 {
338 	unsigned int clock;
339 	int ret = -1;
340 	u8 brdcfg4;
341 
342 	if (sdclk == 1) {
343 		brdcfg4 = QIXIS_READ(brdcfg[4]);
344 		if ((brdcfg4 & CLK_MUX_SEL_MASK) == ETH_PHY_CLK_OUT)
345 			return SRDS_PLLCR0_RFCK_SEL_125;
346 		else
347 			clock = (sw >> 5) & 7;
348 	} else
349 		clock = (sw >> 6) & 3;
350 
351 	switch (clock) {
352 	case 0:
353 		ret = SRDS_PLLCR0_RFCK_SEL_100;
354 		break;
355 	case 1:
356 		ret = SRDS_PLLCR0_RFCK_SEL_125;
357 		break;
358 	case 2:
359 		ret = SRDS_PLLCR0_RFCK_SEL_156_25;
360 		break;
361 	case 3:
362 		ret = SRDS_PLLCR0_RFCK_SEL_161_13;
363 		break;
364 	case 4:
365 	case 5:
366 	case 6:
367 		ret = SRDS_PLLCR0_RFCK_SEL_122_88;
368 		break;
369 	default:
370 		ret = -1;
371 		break;
372 	}
373 
374 	return ret;
375 }
376 
377 static const char *serdes_clock_to_string(u32 clock)
378 {
379 	switch (clock) {
380 	case SRDS_PLLCR0_RFCK_SEL_100:
381 		return "100";
382 	case SRDS_PLLCR0_RFCK_SEL_125:
383 		return "125";
384 	case SRDS_PLLCR0_RFCK_SEL_156_25:
385 		return "156.25";
386 	case SRDS_PLLCR0_RFCK_SEL_161_13:
387 		return "161.13";
388 	default:
389 		return "122.88";
390 	}
391 }
392 
393 #define NUM_SRDS_BANKS	2
394 
395 int misc_init_r(void)
396 {
397 	u8 sw;
398 	serdes_corenet_t *srds_regs =
399 		(void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
400 	u32 actual[NUM_SRDS_BANKS];
401 	unsigned int i;
402 	int clock;
403 
404 	sw = QIXIS_READ(brdcfg[2]);
405 	clock = serdes_refclock(sw, 1);
406 	if (clock >= 0)
407 		actual[0] = clock;
408 	else
409 		printf("Warning: SDREFCLK1 switch setting is unsupported\n");
410 
411 	sw = QIXIS_READ(brdcfg[4]);
412 	clock = serdes_refclock(sw, 2);
413 	if (clock >= 0)
414 		actual[1] = clock;
415 	else
416 		printf("Warning: SDREFCLK2 switch setting unsupported\n");
417 
418 	for (i = 0; i < NUM_SRDS_BANKS; i++) {
419 		u32 pllcr0 = srds_regs->bank[i].pllcr0;
420 		u32 expected = pllcr0 & SRDS_PLLCR0_RFCK_SEL_MASK;
421 		if (expected != actual[i]) {
422 			printf("Warning: SERDES bank %u expects reference clock"
423 			       " %sMHz, but actual is %sMHz\n", i + 1,
424 			       serdes_clock_to_string(expected),
425 			       serdes_clock_to_string(actual[i]));
426 		}
427 	}
428 
429 	return 0;
430 }
431 
432 void ft_board_setup(void *blob, bd_t *bd)
433 {
434 	phys_addr_t base;
435 	phys_size_t size;
436 
437 	ft_cpu_setup(blob, bd);
438 
439 	base = getenv_bootm_low();
440 	size = getenv_bootm_size();
441 
442 	fdt_fixup_memory(blob, (u64)base, (u64)size);
443 
444 #ifdef CONFIG_PCI
445 	pci_of_setup(blob, bd);
446 #endif
447 
448 	fdt_fixup_liodn(blob);
449 
450 #ifdef CONFIG_HAS_FSL_DR_USB
451 	fdt_fixup_dr_usb(blob, bd);
452 #endif
453 
454 #ifdef CONFIG_SYS_DPAA_FMAN
455 	fdt_fixup_fman_ethernet(blob);
456 	fdt_fixup_board_enet(blob);
457 #endif
458 }
459 
460 /*
461  * Dump board switch settings.
462  * The bits that cannot be read/sampled via some FPGA or some
463  * registers, they will be displayed as
464  * underscore in binary format. mask[] has those bits.
465  * Some bits are calculated differently than the actual switches
466  * if booting with overriding by FPGA.
467  */
468 void qixis_dump_switch(void)
469 {
470 	int i;
471 	u8 sw[5];
472 
473 	/*
474 	 * Any bit with 1 means that bit cannot be reverse engineered.
475 	 * It will be displayed as _ in binary format.
476 	 */
477 	static const u8 mask[] = {0x07, 0, 0, 0xff, 0};
478 	char buf[10];
479 	u8 brdcfg[16], dutcfg[16];
480 
481 	for (i = 0; i < 16; i++) {
482 		brdcfg[i] = qixis_read(offsetof(struct qixis, brdcfg[0]) + i);
483 		dutcfg[i] = qixis_read(offsetof(struct qixis, dutcfg[0]) + i);
484 	}
485 
486 	sw[0] = ((brdcfg[0] & 0x0f) << 4)	| \
487 		(brdcfg[9] & 0x08);
488 	sw[1] = ((dutcfg[1] & 0x01) << 7)	| \
489 		((dutcfg[2] & 0x07) << 4)       | \
490 		((dutcfg[6] & 0x10) >> 1)       | \
491 		((dutcfg[6] & 0x80) >> 5)       | \
492 		((dutcfg[1] & 0x40) >> 5)       | \
493 		(dutcfg[6] & 0x01);
494 	sw[2] = dutcfg[0];
495 	sw[3] = 0;
496 	sw[4] = ((brdcfg[1] & 0x30) << 2)	| \
497 		((brdcfg[1] & 0xc0) >> 2)	| \
498 		(brdcfg[1] & 0x0f);
499 
500 	puts("DIP switch settings:\n");
501 	for (i = 0; i < 5; i++) {
502 		printf("SW%d         = 0b%s (0x%02x)\n",
503 			i + 1, byte_to_binary_mask(sw[i], mask[i], buf), sw[i]);
504 	}
505 }
506