xref: /rk3399_rockchip-uboot/board/freescale/b4860qds/b4860qds.c (revision 723806cc5bea9f8b37323dfd7568603f99af6a06)
1b5b06fb7SYork Sun /*
2b5b06fb7SYork Sun  * Copyright 2011-2012 Freescale Semiconductor, Inc.
3b5b06fb7SYork Sun  *
41a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
5b5b06fb7SYork Sun  */
6b5b06fb7SYork Sun 
7b5b06fb7SYork Sun #include <common.h>
8b5b06fb7SYork Sun #include <command.h>
9b5b06fb7SYork Sun #include <i2c.h>
10b5b06fb7SYork Sun #include <netdev.h>
11b5b06fb7SYork Sun #include <linux/compiler.h>
12b5b06fb7SYork Sun #include <asm/mmu.h>
13b5b06fb7SYork Sun #include <asm/processor.h>
141221ce45SMasahiro Yamada #include <linux/errno.h>
15b5b06fb7SYork Sun #include <asm/cache.h>
16b5b06fb7SYork Sun #include <asm/immap_85xx.h>
17b5b06fb7SYork Sun #include <asm/fsl_law.h>
18b5b06fb7SYork Sun #include <asm/fsl_serdes.h>
19b5b06fb7SYork Sun #include <asm/fsl_liodn.h>
20b5b06fb7SYork Sun #include <fm_eth.h>
21cd79e5f4SSuresh Gupta #include <hwconfig.h>
22b5b06fb7SYork Sun 
23b5b06fb7SYork Sun #include "../common/qixis.h"
24b5b06fb7SYork Sun #include "../common/vsc3316_3308.h"
25cb033741SShaveta Leekha #include "../common/idt8t49n222a_serdes_clk.h"
26652e29b4SShaveta Leekha #include "../common/zm7300.h"
27b5b06fb7SYork Sun #include "b4860qds.h"
28b5b06fb7SYork Sun #include "b4860qds_qixis.h"
29b5b06fb7SYork Sun #include "b4860qds_crossbar_con.h"
30b5b06fb7SYork Sun 
31b5b06fb7SYork Sun #define CLK_MUX_SEL_MASK	0x4
32b5b06fb7SYork Sun #define ETH_PHY_CLK_OUT		0x4
33b5b06fb7SYork Sun 
34b5b06fb7SYork Sun DECLARE_GLOBAL_DATA_PTR;
35b5b06fb7SYork Sun 
checkboard(void)36b5b06fb7SYork Sun int checkboard(void)
37b5b06fb7SYork Sun {
38b5b06fb7SYork Sun 	char buf[64];
39b5b06fb7SYork Sun 	u8 sw;
4067ac13b1SSimon Glass 	struct cpu_type *cpu = gd->arch.cpu;
41b5b06fb7SYork Sun 	static const char *const freq[] = {"100", "125", "156.25", "161.13",
42b5b06fb7SYork Sun 						"122.88", "122.88", "122.88"};
43b5b06fb7SYork Sun 	int clock;
44b5b06fb7SYork Sun 
45b5b06fb7SYork Sun 	printf("Board: %sQDS, ", cpu->name);
46b5b06fb7SYork Sun 	printf("Sys ID: 0x%02x, Sys Ver: 0x%02x, ",
47b5b06fb7SYork Sun 		QIXIS_READ(id), QIXIS_READ(arch));
48b5b06fb7SYork Sun 
49b5b06fb7SYork Sun 	sw = QIXIS_READ(brdcfg[0]);
50b5b06fb7SYork Sun 	sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT;
51b5b06fb7SYork Sun 
52b5b06fb7SYork Sun 	if (sw < 0x8)
53b5b06fb7SYork Sun 		printf("vBank: %d\n", sw);
54b5b06fb7SYork Sun 	else if (sw >= 0x8 && sw <= 0xE)
55b5b06fb7SYork Sun 		puts("NAND\n");
56b5b06fb7SYork Sun 	else
57b5b06fb7SYork Sun 		printf("invalid setting of SW%u\n", QIXIS_LBMAP_SWITCH);
58b5b06fb7SYork Sun 
59b5b06fb7SYork Sun 	printf("FPGA: v%d (%s), build %d",
60b5b06fb7SYork Sun 		(int)QIXIS_READ(scver), qixis_read_tag(buf),
61b5b06fb7SYork Sun 		(int)qixis_read_minor());
62b5b06fb7SYork Sun 	/* the timestamp string contains "\n" at the end */
63b5b06fb7SYork Sun 	printf(" on %s", qixis_read_time(buf));
64b5b06fb7SYork Sun 
65b5b06fb7SYork Sun 	/*
66b5b06fb7SYork Sun 	 * Display the actual SERDES reference clocks as configured by the
67b5b06fb7SYork Sun 	 * dip switches on the board.  Note that the SWx registers could
68b5b06fb7SYork Sun 	 * technically be set to force the reference clocks to match the
69b5b06fb7SYork Sun 	 * values that the SERDES expects (or vice versa).  For now, however,
70b5b06fb7SYork Sun 	 * we just display both values and hope the user notices when they
71b5b06fb7SYork Sun 	 * don't match.
72b5b06fb7SYork Sun 	 */
73b5b06fb7SYork Sun 	puts("SERDES Reference Clocks: ");
74b5b06fb7SYork Sun 	sw = QIXIS_READ(brdcfg[2]);
75b5b06fb7SYork Sun 	clock = (sw >> 5) & 7;
76b5b06fb7SYork Sun 	printf("Bank1=%sMHz ", freq[clock]);
77b5b06fb7SYork Sun 	sw = QIXIS_READ(brdcfg[4]);
78b5b06fb7SYork Sun 	clock = (sw >> 6) & 3;
79b5b06fb7SYork Sun 	printf("Bank2=%sMHz\n", freq[clock]);
80b5b06fb7SYork Sun 
81b5b06fb7SYork Sun 	return 0;
82b5b06fb7SYork Sun }
83b5b06fb7SYork Sun 
select_i2c_ch_pca(u8 ch)84b5b06fb7SYork Sun int select_i2c_ch_pca(u8 ch)
85b5b06fb7SYork Sun {
86b5b06fb7SYork Sun 	int ret;
87b5b06fb7SYork Sun 
88b5b06fb7SYork Sun 	/* Selecting proper channel via PCA*/
89b5b06fb7SYork Sun 	ret = i2c_write(I2C_MUX_PCA_ADDR, 0x0, 1, &ch, 1);
90b5b06fb7SYork Sun 	if (ret) {
91b5b06fb7SYork Sun 		printf("PCA: failed to select proper channel.\n");
92b5b06fb7SYork Sun 		return ret;
93b5b06fb7SYork Sun 	}
94b5b06fb7SYork Sun 
95b5b06fb7SYork Sun 	return 0;
96b5b06fb7SYork Sun }
97b5b06fb7SYork Sun 
98652e29b4SShaveta Leekha /*
99652e29b4SShaveta Leekha  * read_voltage from sensor on I2C bus
100652e29b4SShaveta Leekha  * We use average of 4 readings, waiting for 532us befor another reading
101652e29b4SShaveta Leekha  */
102652e29b4SShaveta Leekha #define WAIT_FOR_ADC	532	/* wait for 532 microseconds for ADC */
103652e29b4SShaveta Leekha #define NUM_READINGS	4	/* prefer to be power of 2 for efficiency */
104652e29b4SShaveta Leekha 
read_voltage(void)105652e29b4SShaveta Leekha static inline int read_voltage(void)
106652e29b4SShaveta Leekha {
107652e29b4SShaveta Leekha 	int i, ret, voltage_read = 0;
108652e29b4SShaveta Leekha 	u16 vol_mon;
109652e29b4SShaveta Leekha 
110652e29b4SShaveta Leekha 	for (i = 0; i < NUM_READINGS; i++) {
111652e29b4SShaveta Leekha 		ret = i2c_read(I2C_VOL_MONITOR_ADDR,
112652e29b4SShaveta Leekha 			I2C_VOL_MONITOR_BUS_V_OFFSET, 1, (void *)&vol_mon, 2);
113652e29b4SShaveta Leekha 		if (ret) {
114652e29b4SShaveta Leekha 			printf("VID: failed to read core voltage\n");
115652e29b4SShaveta Leekha 			return ret;
116652e29b4SShaveta Leekha 		}
117652e29b4SShaveta Leekha 		if (vol_mon & I2C_VOL_MONITOR_BUS_V_OVF) {
118652e29b4SShaveta Leekha 			printf("VID: Core voltage sensor error\n");
119652e29b4SShaveta Leekha 			return -1;
120652e29b4SShaveta Leekha 		}
121652e29b4SShaveta Leekha 		debug("VID: bus voltage reads 0x%04x\n", vol_mon);
122652e29b4SShaveta Leekha 		/* LSB = 4mv */
123652e29b4SShaveta Leekha 		voltage_read += (vol_mon >> I2C_VOL_MONITOR_BUS_V_SHIFT) * 4;
124652e29b4SShaveta Leekha 		udelay(WAIT_FOR_ADC);
125652e29b4SShaveta Leekha 	}
126652e29b4SShaveta Leekha 	/* calculate the average */
127652e29b4SShaveta Leekha 	voltage_read /= NUM_READINGS;
128652e29b4SShaveta Leekha 
129652e29b4SShaveta Leekha 	return voltage_read;
130652e29b4SShaveta Leekha }
131652e29b4SShaveta Leekha 
adjust_vdd(ulong vdd_override)132652e29b4SShaveta Leekha static int adjust_vdd(ulong vdd_override)
133652e29b4SShaveta Leekha {
134652e29b4SShaveta Leekha 	int re_enable = disable_interrupts();
135652e29b4SShaveta Leekha 	ccsr_gur_t __iomem *gur =
136652e29b4SShaveta Leekha 		(void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
137652e29b4SShaveta Leekha 	u32 fusesr;
138652e29b4SShaveta Leekha 	u8 vid;
139652e29b4SShaveta Leekha 	int vdd_target, vdd_last;
140652e29b4SShaveta Leekha 	int existing_voltage, temp_voltage, voltage; /* all in 1/10 mV */
141652e29b4SShaveta Leekha 	int ret;
142652e29b4SShaveta Leekha 	unsigned int orig_i2c_speed;
143652e29b4SShaveta Leekha 	unsigned long vdd_string_override;
144652e29b4SShaveta Leekha 	char *vdd_string;
145652e29b4SShaveta Leekha 	static const uint16_t vdd[32] = {
146652e29b4SShaveta Leekha 		0,	/* unused */
147652e29b4SShaveta Leekha 		9875,	/* 0.9875V */
148652e29b4SShaveta Leekha 		9750,
149652e29b4SShaveta Leekha 		9625,
150652e29b4SShaveta Leekha 		9500,
151652e29b4SShaveta Leekha 		9375,
152652e29b4SShaveta Leekha 		9250,
153652e29b4SShaveta Leekha 		9125,
154652e29b4SShaveta Leekha 		9000,
155652e29b4SShaveta Leekha 		8875,
156652e29b4SShaveta Leekha 		8750,
157652e29b4SShaveta Leekha 		8625,
158652e29b4SShaveta Leekha 		8500,
159652e29b4SShaveta Leekha 		8375,
160652e29b4SShaveta Leekha 		8250,
161652e29b4SShaveta Leekha 		8125,
162652e29b4SShaveta Leekha 		10000,	/* 1.0000V */
163652e29b4SShaveta Leekha 		10125,
164652e29b4SShaveta Leekha 		10250,
165652e29b4SShaveta Leekha 		10375,
166652e29b4SShaveta Leekha 		10500,
167652e29b4SShaveta Leekha 		10625,
168652e29b4SShaveta Leekha 		10750,
169652e29b4SShaveta Leekha 		10875,
170652e29b4SShaveta Leekha 		11000,
171652e29b4SShaveta Leekha 		0,	/* reserved */
172652e29b4SShaveta Leekha 	};
173652e29b4SShaveta Leekha 	struct vdd_drive {
174652e29b4SShaveta Leekha 		u8 vid;
175652e29b4SShaveta Leekha 		unsigned voltage;
176652e29b4SShaveta Leekha 	};
177652e29b4SShaveta Leekha 
178652e29b4SShaveta Leekha 	ret = select_i2c_ch_pca(I2C_MUX_CH_VOL_MONITOR);
179652e29b4SShaveta Leekha 	if (ret) {
180652e29b4SShaveta Leekha 		printf("VID: I2c failed to switch channel\n");
181652e29b4SShaveta Leekha 		ret = -1;
182652e29b4SShaveta Leekha 		goto exit;
183652e29b4SShaveta Leekha 	}
184652e29b4SShaveta Leekha 
185652e29b4SShaveta Leekha 	/* get the voltage ID from fuse status register */
186652e29b4SShaveta Leekha 	fusesr = in_be32(&gur->dcfg_fusesr);
187652e29b4SShaveta Leekha 	vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_VID_SHIFT) &
188652e29b4SShaveta Leekha 		FSL_CORENET_DCFG_FUSESR_VID_MASK;
189652e29b4SShaveta Leekha 	if (vid == FSL_CORENET_DCFG_FUSESR_VID_MASK) {
190652e29b4SShaveta Leekha 		vid = (fusesr >> FSL_CORENET_DCFG_FUSESR_ALTVID_SHIFT) &
191652e29b4SShaveta Leekha 			FSL_CORENET_DCFG_FUSESR_ALTVID_MASK;
192652e29b4SShaveta Leekha 	}
193652e29b4SShaveta Leekha 	vdd_target = vdd[vid];
194652e29b4SShaveta Leekha 	debug("VID:Reading from from fuse,vid=%x vdd is %dmV\n",
195652e29b4SShaveta Leekha 	      vid, vdd_target/10);
196652e29b4SShaveta Leekha 
197652e29b4SShaveta Leekha 	/* check override variable for overriding VDD */
19800caae6dSSimon Glass 	vdd_string = env_get("b4qds_vdd_mv");
199652e29b4SShaveta Leekha 	if (vdd_override == 0 && vdd_string &&
200652e29b4SShaveta Leekha 	    !strict_strtoul(vdd_string, 10, &vdd_string_override))
201652e29b4SShaveta Leekha 		vdd_override = vdd_string_override;
202652e29b4SShaveta Leekha 	if (vdd_override >= 819 && vdd_override <= 1212) {
203652e29b4SShaveta Leekha 		vdd_target = vdd_override * 10; /* convert to 1/10 mV */
204652e29b4SShaveta Leekha 		debug("VDD override is %lu\n", vdd_override);
205652e29b4SShaveta Leekha 	} else if (vdd_override != 0) {
206652e29b4SShaveta Leekha 		printf("Invalid value.\n");
207652e29b4SShaveta Leekha 	}
208652e29b4SShaveta Leekha 
209652e29b4SShaveta Leekha 	if (vdd_target == 0) {
210652e29b4SShaveta Leekha 		printf("VID: VID not used\n");
211652e29b4SShaveta Leekha 		ret = 0;
212652e29b4SShaveta Leekha 		goto exit;
213652e29b4SShaveta Leekha 	}
214652e29b4SShaveta Leekha 
215652e29b4SShaveta Leekha 	/*
216652e29b4SShaveta Leekha 	 * Read voltage monitor to check real voltage.
217652e29b4SShaveta Leekha 	 * Voltage monitor LSB is 4mv.
218652e29b4SShaveta Leekha 	 */
219652e29b4SShaveta Leekha 	vdd_last = read_voltage();
220652e29b4SShaveta Leekha 	if (vdd_last < 0) {
221652e29b4SShaveta Leekha 		printf("VID: abort VID adjustment\n");
222652e29b4SShaveta Leekha 		ret = -1;
223652e29b4SShaveta Leekha 		goto exit;
224652e29b4SShaveta Leekha 	}
225652e29b4SShaveta Leekha 
226652e29b4SShaveta Leekha 	debug("VID: Core voltage is at %d mV\n", vdd_last);
227652e29b4SShaveta Leekha 	ret = select_i2c_ch_pca(I2C_MUX_CH_DPM);
228652e29b4SShaveta Leekha 	if (ret) {
229652e29b4SShaveta Leekha 		printf("VID: I2c failed to switch channel to DPM\n");
230652e29b4SShaveta Leekha 		ret = -1;
231652e29b4SShaveta Leekha 		goto exit;
232652e29b4SShaveta Leekha 	}
233652e29b4SShaveta Leekha 
234652e29b4SShaveta Leekha 	/* Round up to the value of step of Voltage regulator */
235652e29b4SShaveta Leekha 	voltage = roundup(vdd_target, ZM_STEP);
236652e29b4SShaveta Leekha 	debug("VID: rounded up voltage = %d\n", voltage);
237652e29b4SShaveta Leekha 
238652e29b4SShaveta Leekha 	/* lower the speed to 100kHz to access ZM7300 device */
239652e29b4SShaveta Leekha 	debug("VID: Setting bus speed to 100KHz if not already set\n");
240652e29b4SShaveta Leekha 	orig_i2c_speed = i2c_get_bus_speed();
241652e29b4SShaveta Leekha 	if (orig_i2c_speed != 100000)
242652e29b4SShaveta Leekha 		i2c_set_bus_speed(100000);
243652e29b4SShaveta Leekha 
244652e29b4SShaveta Leekha 	/* Read the existing level on board, if equal to requsted one,
245652e29b4SShaveta Leekha 	   no need to re-set */
246652e29b4SShaveta Leekha 	existing_voltage = zm_read_voltage();
247652e29b4SShaveta Leekha 
248652e29b4SShaveta Leekha 	/* allowing the voltage difference of one step 0.0125V acceptable */
249652e29b4SShaveta Leekha 	if ((existing_voltage >= voltage) &&
250652e29b4SShaveta Leekha 	    (existing_voltage < (voltage + ZM_STEP))) {
251652e29b4SShaveta Leekha 		debug("VID: voltage already set as requested,returning\n");
252652e29b4SShaveta Leekha 		ret = existing_voltage;
253652e29b4SShaveta Leekha 		goto out;
254652e29b4SShaveta Leekha 	}
255652e29b4SShaveta Leekha 	debug("VID: Changing voltage for board from %dmV to %dmV\n",
256652e29b4SShaveta Leekha 	      existing_voltage/10, voltage/10);
257652e29b4SShaveta Leekha 
258652e29b4SShaveta Leekha 	if (zm_disable_wp() < 0) {
259652e29b4SShaveta Leekha 		ret = -1;
260652e29b4SShaveta Leekha 		goto out;
261652e29b4SShaveta Leekha 	}
262652e29b4SShaveta Leekha 	/* Change Voltage: the change is done through all the steps in the
263652e29b4SShaveta Leekha 	   way, to avoid reset to the board due to power good signal fail
264652e29b4SShaveta Leekha 	   in big voltage change gap jump.
265652e29b4SShaveta Leekha 	*/
266652e29b4SShaveta Leekha 	if (existing_voltage > voltage) {
267652e29b4SShaveta Leekha 		temp_voltage = existing_voltage - ZM_STEP;
268652e29b4SShaveta Leekha 			while (temp_voltage >= voltage) {
269652e29b4SShaveta Leekha 				ret = zm_write_voltage(temp_voltage);
270652e29b4SShaveta Leekha 				if (ret == temp_voltage) {
271652e29b4SShaveta Leekha 					temp_voltage -= ZM_STEP;
272652e29b4SShaveta Leekha 				} else {
273652e29b4SShaveta Leekha 					/* ZM7300 device failed to set
274652e29b4SShaveta Leekha 					 * the voltage */
275652e29b4SShaveta Leekha 					printf
276652e29b4SShaveta Leekha 					("VID:Stepping down vol failed:%dmV\n",
277652e29b4SShaveta Leekha 					 temp_voltage/10);
278652e29b4SShaveta Leekha 				     ret = -1;
279652e29b4SShaveta Leekha 				     goto out;
280652e29b4SShaveta Leekha 				}
281652e29b4SShaveta Leekha 			}
282652e29b4SShaveta Leekha 	} else {
283652e29b4SShaveta Leekha 		temp_voltage = existing_voltage + ZM_STEP;
284652e29b4SShaveta Leekha 			while (temp_voltage < (voltage + ZM_STEP)) {
285652e29b4SShaveta Leekha 				ret = zm_write_voltage(temp_voltage);
286652e29b4SShaveta Leekha 				if (ret == temp_voltage) {
287652e29b4SShaveta Leekha 					temp_voltage += ZM_STEP;
288652e29b4SShaveta Leekha 				} else {
289652e29b4SShaveta Leekha 					/* ZM7300 device failed to set
290652e29b4SShaveta Leekha 					 * the voltage */
291652e29b4SShaveta Leekha 					printf
292652e29b4SShaveta Leekha 					("VID:Stepping up vol failed:%dmV\n",
293652e29b4SShaveta Leekha 					 temp_voltage/10);
294652e29b4SShaveta Leekha 				     ret = -1;
295652e29b4SShaveta Leekha 				     goto out;
296652e29b4SShaveta Leekha 				}
297652e29b4SShaveta Leekha 			}
298652e29b4SShaveta Leekha 	}
299652e29b4SShaveta Leekha 
300652e29b4SShaveta Leekha 	if (zm_enable_wp() < 0)
301652e29b4SShaveta Leekha 		ret = -1;
302652e29b4SShaveta Leekha 
303652e29b4SShaveta Leekha 	/* restore the speed to 400kHz */
304652e29b4SShaveta Leekha out:	debug("VID: Restore the I2C bus speed to %dKHz\n",
305652e29b4SShaveta Leekha 				orig_i2c_speed/1000);
306652e29b4SShaveta Leekha 	i2c_set_bus_speed(orig_i2c_speed);
307652e29b4SShaveta Leekha 	if (ret < 0)
308652e29b4SShaveta Leekha 		goto exit;
309652e29b4SShaveta Leekha 
310652e29b4SShaveta Leekha 	ret = select_i2c_ch_pca(I2C_MUX_CH_VOL_MONITOR);
311652e29b4SShaveta Leekha 	if (ret) {
312652e29b4SShaveta Leekha 		printf("VID: I2c failed to switch channel\n");
313652e29b4SShaveta Leekha 		ret = -1;
314652e29b4SShaveta Leekha 		goto exit;
315652e29b4SShaveta Leekha 	}
316652e29b4SShaveta Leekha 	vdd_last = read_voltage();
317652e29b4SShaveta Leekha 	select_i2c_ch_pca(I2C_CH_DEFAULT);
318652e29b4SShaveta Leekha 
319652e29b4SShaveta Leekha 	if (vdd_last > 0)
320652e29b4SShaveta Leekha 		printf("VID: Core voltage %d mV\n", vdd_last);
321652e29b4SShaveta Leekha 	else
322652e29b4SShaveta Leekha 		ret = -1;
323652e29b4SShaveta Leekha 
324652e29b4SShaveta Leekha exit:
325652e29b4SShaveta Leekha 	if (re_enable)
326652e29b4SShaveta Leekha 		enable_interrupts();
327652e29b4SShaveta Leekha 	return ret;
328652e29b4SShaveta Leekha }
329652e29b4SShaveta Leekha 
configure_vsc3316_3308(void)330b5b06fb7SYork Sun int configure_vsc3316_3308(void)
331b5b06fb7SYork Sun {
332b5b06fb7SYork Sun 	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
333b5b06fb7SYork Sun 	unsigned int num_vsc16_con, num_vsc08_con;
334b5b06fb7SYork Sun 	u32 serdes1_prtcl, serdes2_prtcl;
335b5b06fb7SYork Sun 	int ret;
336cd79e5f4SSuresh Gupta 	char buffer[HWCONFIG_BUFFER_SIZE];
337cd79e5f4SSuresh Gupta 	char *buf = NULL;
338b5b06fb7SYork Sun 
339b5b06fb7SYork Sun 	serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
340b5b06fb7SYork Sun 			FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
341b5b06fb7SYork Sun 	if (!serdes1_prtcl) {
342b5b06fb7SYork Sun 		printf("SERDES1 is not enabled\n");
343b5b06fb7SYork Sun 		return 0;
344b5b06fb7SYork Sun 	}
345b5b06fb7SYork Sun 	serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
346b5b06fb7SYork Sun 	debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
347b5b06fb7SYork Sun 
348b5b06fb7SYork Sun 	serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
349b5b06fb7SYork Sun 			FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
350b5b06fb7SYork Sun 	if (!serdes2_prtcl) {
351b5b06fb7SYork Sun 		printf("SERDES2 is not enabled\n");
352b5b06fb7SYork Sun 		return 0;
353b5b06fb7SYork Sun 	}
354b5b06fb7SYork Sun 	serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
355b5b06fb7SYork Sun 	debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
356b5b06fb7SYork Sun 
357b5b06fb7SYork Sun 	switch (serdes1_prtcl) {
358c7d506d4Spoonam aggrwal 	case 0x29:
359b5b06fb7SYork Sun 	case 0x2a:
360b5b06fb7SYork Sun 	case 0x2C:
361b5b06fb7SYork Sun 	case 0x2D:
362b5b06fb7SYork Sun 	case 0x2E:
363b5b06fb7SYork Sun 			/*
364b5b06fb7SYork Sun 			 * Configuration:
365b5b06fb7SYork Sun 			 * SERDES: 1
366b5b06fb7SYork Sun 			 * Lanes: A,B: SGMII
367b5b06fb7SYork Sun 			 * Lanes: C,D,E,F,G,H: CPRI
368b5b06fb7SYork Sun 			 */
369b5b06fb7SYork Sun 		debug("Configuring crossbar to use onboard SGMII PHYs:"
370b5b06fb7SYork Sun 				"srds_prctl:%x\n", serdes1_prtcl);
371b5b06fb7SYork Sun 		num_vsc16_con = NUM_CON_VSC3316;
372b5b06fb7SYork Sun 		/* Configure VSC3316 crossbar switch */
373b5b06fb7SYork Sun 		ret = select_i2c_ch_pca(I2C_CH_VSC3316);
374b5b06fb7SYork Sun 		if (!ret) {
375b5b06fb7SYork Sun 			ret = vsc3316_config(VSC3316_TX_ADDRESS,
3760fecbba8SShaveta Leekha 					vsc16_tx_4sfp_sgmii_12_56,
3770fecbba8SShaveta Leekha 					num_vsc16_con);
378b5b06fb7SYork Sun 			if (ret)
379b5b06fb7SYork Sun 				return ret;
380b5b06fb7SYork Sun 			ret = vsc3316_config(VSC3316_RX_ADDRESS,
3810fecbba8SShaveta Leekha 					vsc16_rx_4sfp_sgmii_12_56,
3820fecbba8SShaveta Leekha 					num_vsc16_con);
383b5b06fb7SYork Sun 			if (ret)
384b5b06fb7SYork Sun 				return ret;
385b5b06fb7SYork Sun 		} else {
386b5b06fb7SYork Sun 			return ret;
387b5b06fb7SYork Sun 		}
388b5b06fb7SYork Sun 		break;
389b5b06fb7SYork Sun 
3908c328c21SShaveta Leekha 	case 0x01:
3915e5097c1SShaveta Leekha 	case 0x02:
3925e5097c1SShaveta Leekha 	case 0x04:
3935e5097c1SShaveta Leekha 	case 0x05:
3945e5097c1SShaveta Leekha 	case 0x06:
3958c328c21SShaveta Leekha 	case 0x07:
3965e5097c1SShaveta Leekha 	case 0x08:
3975e5097c1SShaveta Leekha 	case 0x09:
3985e5097c1SShaveta Leekha 	case 0x0A:
3995e5097c1SShaveta Leekha 	case 0x0B:
4005e5097c1SShaveta Leekha 	case 0x0C:
4018c328c21SShaveta Leekha 	case 0x2F:
4025e5097c1SShaveta Leekha 	case 0x30:
4035e5097c1SShaveta Leekha 	case 0x32:
4045e5097c1SShaveta Leekha 	case 0x33:
4055e5097c1SShaveta Leekha 	case 0x34:
4065e5097c1SShaveta Leekha 	case 0x39:
4075e5097c1SShaveta Leekha 	case 0x3A:
4085e5097c1SShaveta Leekha 	case 0x3C:
4095e5097c1SShaveta Leekha 	case 0x3D:
4105e5097c1SShaveta Leekha 	case 0x5C:
4115e5097c1SShaveta Leekha 	case 0x5D:
4125e5097c1SShaveta Leekha 			/*
4135e5097c1SShaveta Leekha 			 * Configuration:
4145e5097c1SShaveta Leekha 			 * SERDES: 1
4155e5097c1SShaveta Leekha 			 * Lanes: A,B: AURORA
4165e5097c1SShaveta Leekha 			 * Lanes: C,d: SGMII
4175e5097c1SShaveta Leekha 			 * Lanes: E,F,G,H: CPRI
4185e5097c1SShaveta Leekha 			 */
4195e5097c1SShaveta Leekha 		debug("Configuring crossbar for Aurora, SGMII 3 and 4,"
4205e5097c1SShaveta Leekha 				" and CPRI. srds_prctl:%x\n", serdes1_prtcl);
4215e5097c1SShaveta Leekha 		num_vsc16_con = NUM_CON_VSC3316;
4225e5097c1SShaveta Leekha 		/* Configure VSC3316 crossbar switch */
4235e5097c1SShaveta Leekha 		ret = select_i2c_ch_pca(I2C_CH_VSC3316);
4245e5097c1SShaveta Leekha 		if (!ret) {
4255e5097c1SShaveta Leekha 			ret = vsc3316_config(VSC3316_TX_ADDRESS,
4265e5097c1SShaveta Leekha 					vsc16_tx_sfp_sgmii_aurora,
4275e5097c1SShaveta Leekha 					num_vsc16_con);
4285e5097c1SShaveta Leekha 			if (ret)
4295e5097c1SShaveta Leekha 				return ret;
4305e5097c1SShaveta Leekha 			ret = vsc3316_config(VSC3316_RX_ADDRESS,
4315e5097c1SShaveta Leekha 					vsc16_rx_sfp_sgmii_aurora,
4325e5097c1SShaveta Leekha 					num_vsc16_con);
4335e5097c1SShaveta Leekha 			if (ret)
4345e5097c1SShaveta Leekha 				return ret;
4355e5097c1SShaveta Leekha 		} else {
4365e5097c1SShaveta Leekha 			return ret;
4375e5097c1SShaveta Leekha 		}
4385e5097c1SShaveta Leekha 		break;
4395e5097c1SShaveta Leekha 
440b41f192bSYork Sun #ifdef CONFIG_ARCH_B4420
441c7d506d4Spoonam aggrwal 	case 0x17:
442b5b06fb7SYork Sun 	case 0x18:
443b5b06fb7SYork Sun 			/*
444b5b06fb7SYork Sun 			 * Configuration:
445b5b06fb7SYork Sun 			 * SERDES: 1
446b5b06fb7SYork Sun 			 * Lanes: A,B,C,D: SGMII
447b5b06fb7SYork Sun 			 * Lanes: E,F,G,H: CPRI
448b5b06fb7SYork Sun 			 */
449b5b06fb7SYork Sun 		debug("Configuring crossbar to use onboard SGMII PHYs:"
450b5b06fb7SYork Sun 				"srds_prctl:%x\n", serdes1_prtcl);
451b5b06fb7SYork Sun 		num_vsc16_con = NUM_CON_VSC3316;
452b5b06fb7SYork Sun 		/* Configure VSC3316 crossbar switch */
453b5b06fb7SYork Sun 		ret = select_i2c_ch_pca(I2C_CH_VSC3316);
454b5b06fb7SYork Sun 		if (!ret) {
455b5b06fb7SYork Sun 			ret = vsc3316_config(VSC3316_TX_ADDRESS,
456b5b06fb7SYork Sun 					vsc16_tx_sgmii_lane_cd, num_vsc16_con);
457b5b06fb7SYork Sun 			if (ret)
458b5b06fb7SYork Sun 				return ret;
459b5b06fb7SYork Sun 			ret = vsc3316_config(VSC3316_RX_ADDRESS,
460b5b06fb7SYork Sun 					vsc16_rx_sgmii_lane_cd, num_vsc16_con);
461b5b06fb7SYork Sun 			if (ret)
462b5b06fb7SYork Sun 				return ret;
463b5b06fb7SYork Sun 		} else {
464b5b06fb7SYork Sun 			return ret;
465b5b06fb7SYork Sun 		}
466b5b06fb7SYork Sun 		break;
467b5b06fb7SYork Sun #endif
468b5b06fb7SYork Sun 
469b5b06fb7SYork Sun 	case 0x3E:
470b5b06fb7SYork Sun 	case 0x0D:
471b5b06fb7SYork Sun 	case 0x0E:
472b5b06fb7SYork Sun 	case 0x12:
473b5b06fb7SYork Sun 		num_vsc16_con = NUM_CON_VSC3316;
474b5b06fb7SYork Sun 		/* Configure VSC3316 crossbar switch */
475b5b06fb7SYork Sun 		ret = select_i2c_ch_pca(I2C_CH_VSC3316);
476b5b06fb7SYork Sun 		if (!ret) {
477b5b06fb7SYork Sun 			ret = vsc3316_config(VSC3316_TX_ADDRESS,
478b5b06fb7SYork Sun 					vsc16_tx_sfp, num_vsc16_con);
479b5b06fb7SYork Sun 			if (ret)
480b5b06fb7SYork Sun 				return ret;
481b5b06fb7SYork Sun 			ret = vsc3316_config(VSC3316_RX_ADDRESS,
482b5b06fb7SYork Sun 					vsc16_rx_sfp, num_vsc16_con);
483b5b06fb7SYork Sun 			if (ret)
484b5b06fb7SYork Sun 				return ret;
485b5b06fb7SYork Sun 		} else {
486b5b06fb7SYork Sun 			return ret;
487b5b06fb7SYork Sun 		}
488b5b06fb7SYork Sun 		break;
489b5b06fb7SYork Sun 	default:
490b5b06fb7SYork Sun 		printf("WARNING:VSC crossbars programming not supported for:%x"
491b5b06fb7SYork Sun 					" SerDes1 Protocol.\n", serdes1_prtcl);
492b5b06fb7SYork Sun 		return -1;
493b5b06fb7SYork Sun 	}
494b5b06fb7SYork Sun 
49589b94d85SShaohui Xie 	num_vsc08_con = NUM_CON_VSC3308;
49689b94d85SShaohui Xie 	/* Configure VSC3308 crossbar switch */
49789b94d85SShaohui Xie 	ret = select_i2c_ch_pca(I2C_CH_VSC3308);
498b5b06fb7SYork Sun 	switch (serdes2_prtcl) {
499b41f192bSYork Sun #ifdef CONFIG_ARCH_B4420
500fa6e7428Spoonam aggrwal 	case 0x9d:
501fa6e7428Spoonam aggrwal #endif
502b5b06fb7SYork Sun 	case 0x9E:
503b5b06fb7SYork Sun 	case 0x9A:
504b5b06fb7SYork Sun 	case 0x98:
5058c328c21SShaveta Leekha 	case 0x48:
506b5b06fb7SYork Sun 	case 0x49:
507b5b06fb7SYork Sun 	case 0x4E:
5088c328c21SShaveta Leekha 	case 0x79:
509b5b06fb7SYork Sun 	case 0x7A:
510b5b06fb7SYork Sun 		if (!ret) {
511b5b06fb7SYork Sun 			ret = vsc3308_config(VSC3308_TX_ADDRESS,
512b5b06fb7SYork Sun 					vsc08_tx_amc, num_vsc08_con);
513b5b06fb7SYork Sun 			if (ret)
514b5b06fb7SYork Sun 				return ret;
515b5b06fb7SYork Sun 			ret = vsc3308_config(VSC3308_RX_ADDRESS,
516b5b06fb7SYork Sun 					vsc08_rx_amc, num_vsc08_con);
517b5b06fb7SYork Sun 			if (ret)
518b5b06fb7SYork Sun 				return ret;
519b5b06fb7SYork Sun 		} else {
520b5b06fb7SYork Sun 			return ret;
521b5b06fb7SYork Sun 		}
522b5b06fb7SYork Sun 		break;
52389b94d85SShaohui Xie 	case 0x80:
52489b94d85SShaohui Xie 	case 0x81:
52589b94d85SShaohui Xie 	case 0x82:
52689b94d85SShaohui Xie 	case 0x83:
52789b94d85SShaohui Xie 	case 0x84:
52889b94d85SShaohui Xie 	case 0x85:
52989b94d85SShaohui Xie 	case 0x86:
53089b94d85SShaohui Xie 	case 0x87:
53189b94d85SShaohui Xie 	case 0x88:
53289b94d85SShaohui Xie 	case 0x89:
53389b94d85SShaohui Xie 	case 0x8a:
53489b94d85SShaohui Xie 	case 0x8b:
53589b94d85SShaohui Xie 	case 0x8c:
53689b94d85SShaohui Xie 	case 0x8d:
53789b94d85SShaohui Xie 	case 0x8e:
53889b94d85SShaohui Xie 	case 0xb1:
53989b94d85SShaohui Xie 	case 0xb2:
54089b94d85SShaohui Xie 		if (!ret) {
541cd79e5f4SSuresh Gupta 			/*
542cd79e5f4SSuresh Gupta 			 * Extract hwconfig from environment since environment
543cd79e5f4SSuresh Gupta 			 * is not setup properly yet
544cd79e5f4SSuresh Gupta 			 */
54500caae6dSSimon Glass 			env_get_f("hwconfig", buffer, sizeof(buffer));
546cd79e5f4SSuresh Gupta 			buf = buffer;
547cd79e5f4SSuresh Gupta 
548cd79e5f4SSuresh Gupta 			if (hwconfig_subarg_cmp_f("fsl_b4860_serdes2",
549cd79e5f4SSuresh Gupta 						  "sfp_amc", "sfp", buf)) {
550b24f6d40SShaohui Xie #ifdef CONFIG_SYS_FSL_B4860QDS_XFI_ERR
551b24f6d40SShaohui Xie 				/* change default VSC3308 for XFI erratum */
552b24f6d40SShaohui Xie 				ret = vsc3308_config_adjust(VSC3308_TX_ADDRESS,
553b24f6d40SShaohui Xie 						vsc08_tx_sfp, num_vsc08_con);
554b24f6d40SShaohui Xie 				if (ret)
555b24f6d40SShaohui Xie 					return ret;
556b24f6d40SShaohui Xie 
557b24f6d40SShaohui Xie 				ret = vsc3308_config_adjust(VSC3308_RX_ADDRESS,
558b24f6d40SShaohui Xie 						vsc08_rx_sfp, num_vsc08_con);
559b24f6d40SShaohui Xie 				if (ret)
560b24f6d40SShaohui Xie 					return ret;
561b24f6d40SShaohui Xie #else
56289b94d85SShaohui Xie 				ret = vsc3308_config(VSC3308_TX_ADDRESS,
56389b94d85SShaohui Xie 						vsc08_tx_sfp, num_vsc08_con);
56489b94d85SShaohui Xie 				if (ret)
56589b94d85SShaohui Xie 					return ret;
566cd79e5f4SSuresh Gupta 
56789b94d85SShaohui Xie 				ret = vsc3308_config(VSC3308_RX_ADDRESS,
56889b94d85SShaohui Xie 						vsc08_rx_sfp, num_vsc08_con);
56989b94d85SShaohui Xie 				if (ret)
57089b94d85SShaohui Xie 					return ret;
571b24f6d40SShaohui Xie #endif
57289b94d85SShaohui Xie 			} else {
573cd79e5f4SSuresh Gupta 				ret = vsc3308_config(VSC3308_TX_ADDRESS,
574cd79e5f4SSuresh Gupta 						vsc08_tx_amc, num_vsc08_con);
575cd79e5f4SSuresh Gupta 				if (ret)
576cd79e5f4SSuresh Gupta 					return ret;
577cd79e5f4SSuresh Gupta 
578cd79e5f4SSuresh Gupta 				ret = vsc3308_config(VSC3308_RX_ADDRESS,
579cd79e5f4SSuresh Gupta 						vsc08_rx_amc, num_vsc08_con);
580cd79e5f4SSuresh Gupta 				if (ret)
581cd79e5f4SSuresh Gupta 					return ret;
582cd79e5f4SSuresh Gupta 			}
583cd79e5f4SSuresh Gupta 
584cd79e5f4SSuresh Gupta 		} else {
58589b94d85SShaohui Xie 			return ret;
58689b94d85SShaohui Xie 		}
58789b94d85SShaohui Xie 		break;
588b5b06fb7SYork Sun 	default:
589b5b06fb7SYork Sun 		printf("WARNING:VSC crossbars programming not supported for: %x"
590b5b06fb7SYork Sun 					" SerDes2 Protocol.\n", serdes2_prtcl);
591b5b06fb7SYork Sun 		return -1;
592b5b06fb7SYork Sun 	}
593b5b06fb7SYork Sun 
594b5b06fb7SYork Sun 	return 0;
595b5b06fb7SYork Sun }
596b5b06fb7SYork Sun 
calibrate_pll(serdes_corenet_t * srds_regs,int pll_num)5977af9a074SShaveta Leekha static int calibrate_pll(serdes_corenet_t *srds_regs, int pll_num)
5987af9a074SShaveta Leekha {
5997af9a074SShaveta Leekha 	u32 rst_err;
6007af9a074SShaveta Leekha 
6017af9a074SShaveta Leekha 	/* Steps For SerDes PLLs reset and reconfiguration
6027af9a074SShaveta Leekha 	 * or PLL power-up procedure
6037af9a074SShaveta Leekha 	 */
6047af9a074SShaveta Leekha 	debug("CALIBRATE PLL:%d\n", pll_num);
6057af9a074SShaveta Leekha 	clrbits_be32(&srds_regs->bank[pll_num].rstctl,
6067af9a074SShaveta Leekha 			SRDS_RSTCTL_SDRST_B);
6077af9a074SShaveta Leekha 	udelay(10);
6087af9a074SShaveta Leekha 	clrbits_be32(&srds_regs->bank[pll_num].rstctl,
6097af9a074SShaveta Leekha 		(SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
6107af9a074SShaveta Leekha 	udelay(10);
6117af9a074SShaveta Leekha 	setbits_be32(&srds_regs->bank[pll_num].rstctl,
6127af9a074SShaveta Leekha 			SRDS_RSTCTL_RST);
6137af9a074SShaveta Leekha 	setbits_be32(&srds_regs->bank[pll_num].rstctl,
6147af9a074SShaveta Leekha 		(SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
6157af9a074SShaveta Leekha 		| SRDS_RSTCTL_SDRST_B));
6167af9a074SShaveta Leekha 
6177af9a074SShaveta Leekha 	udelay(20);
6187af9a074SShaveta Leekha 
6197af9a074SShaveta Leekha 	/* Check whether PLL has been locked or not */
6207af9a074SShaveta Leekha 	rst_err = in_be32(&srds_regs->bank[pll_num].rstctl) &
6217af9a074SShaveta Leekha 				SRDS_RSTCTL_RSTERR;
6227af9a074SShaveta Leekha 	rst_err >>= SRDS_RSTCTL_RSTERR_SHIFT;
6237af9a074SShaveta Leekha 	debug("RST_ERR value for PLL %d is: 0x%x:\n", pll_num, rst_err);
6247af9a074SShaveta Leekha 	if (rst_err)
6257af9a074SShaveta Leekha 		return rst_err;
6267af9a074SShaveta Leekha 
6277af9a074SShaveta Leekha 	return rst_err;
6287af9a074SShaveta Leekha }
6297af9a074SShaveta Leekha 
check_pll_locks(serdes_corenet_t * srds_regs,int pll_num)6307af9a074SShaveta Leekha static int check_pll_locks(serdes_corenet_t *srds_regs, int pll_num)
6317af9a074SShaveta Leekha {
6327af9a074SShaveta Leekha 	int ret = 0;
6337af9a074SShaveta Leekha 	u32 fcap, dcbias, bcap, pllcr1, pllcr0;
6347af9a074SShaveta Leekha 
6357af9a074SShaveta Leekha 	if (calibrate_pll(srds_regs, pll_num)) {
6367af9a074SShaveta Leekha 		/* STEP 1 */
6377af9a074SShaveta Leekha 		/* Read fcap, dcbias and bcap value */
6387af9a074SShaveta Leekha 		clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
6397af9a074SShaveta Leekha 				SRDS_PLLCR0_DCBIAS_OUT_EN);
6407af9a074SShaveta Leekha 		fcap = in_be32(&srds_regs->bank[pll_num].pllsr2) &
6417af9a074SShaveta Leekha 					SRDS_PLLSR2_FCAP;
6427af9a074SShaveta Leekha 		fcap >>= SRDS_PLLSR2_FCAP_SHIFT;
6437af9a074SShaveta Leekha 		bcap = in_be32(&srds_regs->bank[pll_num].pllsr2) &
6447af9a074SShaveta Leekha 					SRDS_PLLSR2_BCAP_EN;
6457af9a074SShaveta Leekha 		bcap >>= SRDS_PLLSR2_BCAP_EN_SHIFT;
6467af9a074SShaveta Leekha 		setbits_be32(&srds_regs->bank[pll_num].pllcr0,
6477af9a074SShaveta Leekha 				SRDS_PLLCR0_DCBIAS_OUT_EN);
6487af9a074SShaveta Leekha 		dcbias = in_be32(&srds_regs->bank[pll_num].pllsr2) &
6497af9a074SShaveta Leekha 					SRDS_PLLSR2_DCBIAS;
6507af9a074SShaveta Leekha 		dcbias >>= SRDS_PLLSR2_DCBIAS_SHIFT;
6517af9a074SShaveta Leekha 		debug("values of bcap:%x, fcap:%x and dcbias:%x\n",
6527af9a074SShaveta Leekha 					bcap, fcap, dcbias);
6537af9a074SShaveta Leekha 		if (fcap == 0 && bcap == 1) {
6547af9a074SShaveta Leekha 			/* Step 3 */
6557af9a074SShaveta Leekha 			clrbits_be32(&srds_regs->bank[pll_num].rstctl,
6567af9a074SShaveta Leekha 				(SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
6577af9a074SShaveta Leekha 				 | SRDS_RSTCTL_SDRST_B));
6587af9a074SShaveta Leekha 			clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
6597af9a074SShaveta Leekha 					SRDS_PLLCR1_BCAP_EN);
6607af9a074SShaveta Leekha 			setbits_be32(&srds_regs->bank[pll_num].pllcr1,
6617af9a074SShaveta Leekha 					SRDS_PLLCR1_BCAP_OVD);
6627af9a074SShaveta Leekha 			if (calibrate_pll(srds_regs, pll_num)) {
6637af9a074SShaveta Leekha 				/*save the fcap, dcbias and bcap values*/
6647af9a074SShaveta Leekha 				clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
6657af9a074SShaveta Leekha 						SRDS_PLLCR0_DCBIAS_OUT_EN);
6667af9a074SShaveta Leekha 				fcap = in_be32(&srds_regs->bank[pll_num].pllsr2)
6677af9a074SShaveta Leekha 					& SRDS_PLLSR2_FCAP;
6687af9a074SShaveta Leekha 				fcap >>= SRDS_PLLSR2_FCAP_SHIFT;
6697af9a074SShaveta Leekha 				bcap = in_be32(&srds_regs->bank[pll_num].pllsr2)
6707af9a074SShaveta Leekha 					& SRDS_PLLSR2_BCAP_EN;
6717af9a074SShaveta Leekha 				bcap >>= SRDS_PLLSR2_BCAP_EN_SHIFT;
6727af9a074SShaveta Leekha 				setbits_be32(&srds_regs->bank[pll_num].pllcr0,
6737af9a074SShaveta Leekha 						SRDS_PLLCR0_DCBIAS_OUT_EN);
6747af9a074SShaveta Leekha 				dcbias = in_be32
6757af9a074SShaveta Leekha 					(&srds_regs->bank[pll_num].pllsr2) &
6767af9a074SShaveta Leekha 							SRDS_PLLSR2_DCBIAS;
6777af9a074SShaveta Leekha 				dcbias >>= SRDS_PLLSR2_DCBIAS_SHIFT;
6787af9a074SShaveta Leekha 
6797af9a074SShaveta Leekha 				/* Step 4*/
6807af9a074SShaveta Leekha 				clrbits_be32(&srds_regs->bank[pll_num].rstctl,
6817af9a074SShaveta Leekha 				(SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
6827af9a074SShaveta Leekha 				 | SRDS_RSTCTL_SDRST_B));
6837af9a074SShaveta Leekha 				setbits_be32(&srds_regs->bank[pll_num].pllcr1,
6847af9a074SShaveta Leekha 						SRDS_PLLCR1_BYP_CAL);
6857af9a074SShaveta Leekha 				clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
6867af9a074SShaveta Leekha 						SRDS_PLLCR1_BCAP_EN);
6877af9a074SShaveta Leekha 				setbits_be32(&srds_regs->bank[pll_num].pllcr1,
6887af9a074SShaveta Leekha 						SRDS_PLLCR1_BCAP_OVD);
6897af9a074SShaveta Leekha 				/* change the fcap and dcbias to the saved
6907af9a074SShaveta Leekha 				 * values from Step 3 */
6917af9a074SShaveta Leekha 				clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
6927af9a074SShaveta Leekha 							SRDS_PLLCR1_PLL_FCAP);
6937af9a074SShaveta Leekha 				pllcr1 = (in_be32
6947af9a074SShaveta Leekha 					(&srds_regs->bank[pll_num].pllcr1)|
6957af9a074SShaveta Leekha 					(fcap << SRDS_PLLCR1_PLL_FCAP_SHIFT));
6967af9a074SShaveta Leekha 				out_be32(&srds_regs->bank[pll_num].pllcr1,
6977af9a074SShaveta Leekha 							pllcr1);
6987af9a074SShaveta Leekha 				clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
6997af9a074SShaveta Leekha 						SRDS_PLLCR0_DCBIAS_OVRD);
7007af9a074SShaveta Leekha 				pllcr0 = (in_be32
7017af9a074SShaveta Leekha 				(&srds_regs->bank[pll_num].pllcr0)|
7027af9a074SShaveta Leekha 				(dcbias << SRDS_PLLCR0_DCBIAS_OVRD_SHIFT));
7037af9a074SShaveta Leekha 				out_be32(&srds_regs->bank[pll_num].pllcr0,
7047af9a074SShaveta Leekha 							pllcr0);
7057af9a074SShaveta Leekha 				ret = calibrate_pll(srds_regs, pll_num);
7067af9a074SShaveta Leekha 				if (ret)
7077af9a074SShaveta Leekha 					return ret;
7087af9a074SShaveta Leekha 			} else {
7097af9a074SShaveta Leekha 				goto out;
7107af9a074SShaveta Leekha 			}
7117af9a074SShaveta Leekha 		} else { /* Step 5 */
7127af9a074SShaveta Leekha 			clrbits_be32(&srds_regs->bank[pll_num].rstctl,
7137af9a074SShaveta Leekha 				(SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
7147af9a074SShaveta Leekha 				 | SRDS_RSTCTL_SDRST_B));
7157af9a074SShaveta Leekha 			udelay(10);
7167af9a074SShaveta Leekha 			/* Change the fcap, dcbias, and bcap to the
7177af9a074SShaveta Leekha 			 * values from Step 1 */
7187af9a074SShaveta Leekha 			setbits_be32(&srds_regs->bank[pll_num].pllcr1,
7197af9a074SShaveta Leekha 					SRDS_PLLCR1_BYP_CAL);
7207af9a074SShaveta Leekha 			clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
7217af9a074SShaveta Leekha 						SRDS_PLLCR1_PLL_FCAP);
7227af9a074SShaveta Leekha 			pllcr1 = (in_be32(&srds_regs->bank[pll_num].pllcr1)|
7237af9a074SShaveta Leekha 				(fcap << SRDS_PLLCR1_PLL_FCAP_SHIFT));
7247af9a074SShaveta Leekha 			out_be32(&srds_regs->bank[pll_num].pllcr1,
7257af9a074SShaveta Leekha 						pllcr1);
7267af9a074SShaveta Leekha 			clrbits_be32(&srds_regs->bank[pll_num].pllcr0,
7277af9a074SShaveta Leekha 						SRDS_PLLCR0_DCBIAS_OVRD);
7287af9a074SShaveta Leekha 			pllcr0 = (in_be32(&srds_regs->bank[pll_num].pllcr0)|
7297af9a074SShaveta Leekha 				(dcbias << SRDS_PLLCR0_DCBIAS_OVRD_SHIFT));
7307af9a074SShaveta Leekha 			out_be32(&srds_regs->bank[pll_num].pllcr0,
7317af9a074SShaveta Leekha 						pllcr0);
7327af9a074SShaveta Leekha 			clrbits_be32(&srds_regs->bank[pll_num].pllcr1,
7337af9a074SShaveta Leekha 					SRDS_PLLCR1_BCAP_EN);
7347af9a074SShaveta Leekha 			setbits_be32(&srds_regs->bank[pll_num].pllcr1,
7357af9a074SShaveta Leekha 					SRDS_PLLCR1_BCAP_OVD);
7367af9a074SShaveta Leekha 			ret = calibrate_pll(srds_regs, pll_num);
7377af9a074SShaveta Leekha 			if (ret)
7387af9a074SShaveta Leekha 				return ret;
7397af9a074SShaveta Leekha 		}
7407af9a074SShaveta Leekha 	}
7417af9a074SShaveta Leekha out:
7427af9a074SShaveta Leekha 	return 0;
7437af9a074SShaveta Leekha }
7447af9a074SShaveta Leekha 
check_serdes_pll_locks(void)7457af9a074SShaveta Leekha static int check_serdes_pll_locks(void)
7467af9a074SShaveta Leekha {
7477af9a074SShaveta Leekha 	serdes_corenet_t *srds1_regs =
7487af9a074SShaveta Leekha 		(void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
7497af9a074SShaveta Leekha 	serdes_corenet_t *srds2_regs =
7507af9a074SShaveta Leekha 		(void *)CONFIG_SYS_FSL_CORENET_SERDES2_ADDR;
7517af9a074SShaveta Leekha 	int i, ret1, ret2;
7527af9a074SShaveta Leekha 
7537af9a074SShaveta Leekha 	debug("\nSerDes1 Lock check\n");
7547af9a074SShaveta Leekha 	for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
7557af9a074SShaveta Leekha 		ret1 = check_pll_locks(srds1_regs, i);
7567af9a074SShaveta Leekha 		if (ret1) {
7577af9a074SShaveta Leekha 			printf("SerDes1, PLL:%d didnt lock\n", i);
7587af9a074SShaveta Leekha 			return ret1;
7597af9a074SShaveta Leekha 		}
7607af9a074SShaveta Leekha 	}
7617af9a074SShaveta Leekha 	debug("\nSerDes2 Lock check\n");
7627af9a074SShaveta Leekha 	for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
7637af9a074SShaveta Leekha 		ret2 = check_pll_locks(srds2_regs, i);
7647af9a074SShaveta Leekha 		if (ret2) {
7657af9a074SShaveta Leekha 			printf("SerDes2, PLL:%d didnt lock\n", i);
7667af9a074SShaveta Leekha 			return ret2;
7677af9a074SShaveta Leekha 		}
7687af9a074SShaveta Leekha 	}
7697af9a074SShaveta Leekha 
7707af9a074SShaveta Leekha 	return 0;
7717af9a074SShaveta Leekha }
7727af9a074SShaveta Leekha 
config_serdes1_refclks(void)773cb033741SShaveta Leekha int config_serdes1_refclks(void)
774cb033741SShaveta Leekha {
775cb033741SShaveta Leekha 	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
776cb033741SShaveta Leekha 	serdes_corenet_t *srds_regs =
777cb033741SShaveta Leekha 		(void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
778cb033741SShaveta Leekha 	u32 serdes1_prtcl, lane;
7795e5097c1SShaveta Leekha 	unsigned int flag_sgmii_aurora_prtcl = 0;
780fb07c0a1SShaveta Leekha 	int i;
781fb07c0a1SShaveta Leekha 	int ret = 0;
782cb033741SShaveta Leekha 
783cb033741SShaveta Leekha 	serdes1_prtcl = in_be32(&gur->rcwsr[4]) &
784cb033741SShaveta Leekha 			FSL_CORENET2_RCWSR4_SRDS1_PRTCL;
785cb033741SShaveta Leekha 	if (!serdes1_prtcl) {
786cb033741SShaveta Leekha 		printf("SERDES1 is not enabled\n");
787cb033741SShaveta Leekha 		return -1;
788cb033741SShaveta Leekha 	}
789cb033741SShaveta Leekha 	serdes1_prtcl >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
790cb033741SShaveta Leekha 	debug("Using SERDES1 Protocol: 0x%x:\n", serdes1_prtcl);
791cb033741SShaveta Leekha 
792fb07c0a1SShaveta Leekha 	/* To prevent generation of reset request from SerDes
793fb07c0a1SShaveta Leekha 	 * while changing the refclks, By setting SRDS_RST_MSK bit,
794fb07c0a1SShaveta Leekha 	 * SerDes reset event cannot cause a reset request
795cb033741SShaveta Leekha 	 */
796fb07c0a1SShaveta Leekha 	setbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
797fb07c0a1SShaveta Leekha 
798cb033741SShaveta Leekha 	/* Reconfigure IDT idt8t49n222a device for CPRI to work
799cb033741SShaveta Leekha 	 * For this SerDes1's Refclk1 and refclk2 need to be set
800cb033741SShaveta Leekha 	 * to 122.88MHz
801cb033741SShaveta Leekha 	 */
802cb033741SShaveta Leekha 	switch (serdes1_prtcl) {
8038c328c21SShaveta Leekha 	case 0x29:
804cb033741SShaveta Leekha 	case 0x2A:
805cb033741SShaveta Leekha 	case 0x2C:
806cb033741SShaveta Leekha 	case 0x2D:
807cb033741SShaveta Leekha 	case 0x2E:
8088c328c21SShaveta Leekha 	case 0x01:
8095e5097c1SShaveta Leekha 	case 0x02:
8105e5097c1SShaveta Leekha 	case 0x04:
8115e5097c1SShaveta Leekha 	case 0x05:
8125e5097c1SShaveta Leekha 	case 0x06:
8138c328c21SShaveta Leekha 	case 0x07:
8145e5097c1SShaveta Leekha 	case 0x08:
8155e5097c1SShaveta Leekha 	case 0x09:
8165e5097c1SShaveta Leekha 	case 0x0A:
8175e5097c1SShaveta Leekha 	case 0x0B:
8185e5097c1SShaveta Leekha 	case 0x0C:
8198c328c21SShaveta Leekha 	case 0x2F:
8205e5097c1SShaveta Leekha 	case 0x30:
8215e5097c1SShaveta Leekha 	case 0x32:
8225e5097c1SShaveta Leekha 	case 0x33:
8235e5097c1SShaveta Leekha 	case 0x34:
8245e5097c1SShaveta Leekha 	case 0x39:
8255e5097c1SShaveta Leekha 	case 0x3A:
8265e5097c1SShaveta Leekha 	case 0x3C:
8275e5097c1SShaveta Leekha 	case 0x3D:
8285e5097c1SShaveta Leekha 	case 0x5C:
8295e5097c1SShaveta Leekha 	case 0x5D:
830cb033741SShaveta Leekha 		debug("Configuring idt8t49n222a for CPRI SerDes clks:"
831cb033741SShaveta Leekha 			" for srds_prctl:%x\n", serdes1_prtcl);
832cb033741SShaveta Leekha 		ret = select_i2c_ch_pca(I2C_CH_IDT);
833cb033741SShaveta Leekha 		if (!ret) {
834cb033741SShaveta Leekha 			ret = set_serdes_refclk(IDT_SERDES1_ADDRESS, 1,
835cb033741SShaveta Leekha 					SERDES_REFCLK_122_88,
836cb033741SShaveta Leekha 					SERDES_REFCLK_122_88, 0);
837cb033741SShaveta Leekha 			if (ret) {
838cb033741SShaveta Leekha 				printf("IDT8T49N222A configuration failed.\n");
839fb07c0a1SShaveta Leekha 				goto out;
840cb033741SShaveta Leekha 			} else
841fb07c0a1SShaveta Leekha 				debug("IDT8T49N222A configured.\n");
842cb033741SShaveta Leekha 		} else {
843fb07c0a1SShaveta Leekha 			goto out;
844cb033741SShaveta Leekha 		}
845cb033741SShaveta Leekha 		select_i2c_ch_pca(I2C_CH_DEFAULT);
846cb033741SShaveta Leekha 
847cb033741SShaveta Leekha 		/* Change SerDes1's Refclk1 to 125MHz for on board
8485e5097c1SShaveta Leekha 		 * SGMIIs or Aurora to work
849cb033741SShaveta Leekha 		 */
850cb033741SShaveta Leekha 		for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
851cb033741SShaveta Leekha 			enum srds_prtcl lane_prtcl = serdes_get_prtcl
852cb033741SShaveta Leekha 						(0, serdes1_prtcl, lane);
853cb033741SShaveta Leekha 			switch (lane_prtcl) {
854cb033741SShaveta Leekha 			case SGMII_FM1_DTSEC1:
855cb033741SShaveta Leekha 			case SGMII_FM1_DTSEC2:
856cb033741SShaveta Leekha 			case SGMII_FM1_DTSEC3:
857cb033741SShaveta Leekha 			case SGMII_FM1_DTSEC4:
858cb033741SShaveta Leekha 			case SGMII_FM1_DTSEC5:
859cb033741SShaveta Leekha 			case SGMII_FM1_DTSEC6:
8605e5097c1SShaveta Leekha 			case AURORA:
8615e5097c1SShaveta Leekha 				flag_sgmii_aurora_prtcl++;
862cb033741SShaveta Leekha 				break;
863cb033741SShaveta Leekha 			default:
864cb033741SShaveta Leekha 				break;
865cb033741SShaveta Leekha 			}
866cb033741SShaveta Leekha 		}
867cb033741SShaveta Leekha 
8685e5097c1SShaveta Leekha 		if (flag_sgmii_aurora_prtcl)
869cb033741SShaveta Leekha 			QIXIS_WRITE(brdcfg[4], QIXIS_SRDS1CLK_125);
870cb033741SShaveta Leekha 
871cb033741SShaveta Leekha 		/* Steps For SerDes PLLs reset and reconfiguration after
872cb033741SShaveta Leekha 		 * changing SerDes's refclks
873cb033741SShaveta Leekha 		 */
874c4930b1aSShaveta Leekha 		for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
875cb033741SShaveta Leekha 			debug("For PLL%d reset and reconfiguration after"
876cb033741SShaveta Leekha 			       " changing refclks\n", i+1);
877cb033741SShaveta Leekha 			clrbits_be32(&srds_regs->bank[i].rstctl,
878cb033741SShaveta Leekha 					SRDS_RSTCTL_SDRST_B);
879cb033741SShaveta Leekha 			udelay(10);
880cb033741SShaveta Leekha 			clrbits_be32(&srds_regs->bank[i].rstctl,
881cb033741SShaveta Leekha 				(SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
882cb033741SShaveta Leekha 			udelay(10);
883cb033741SShaveta Leekha 			setbits_be32(&srds_regs->bank[i].rstctl,
884cb033741SShaveta Leekha 					SRDS_RSTCTL_RST);
885cb033741SShaveta Leekha 			setbits_be32(&srds_regs->bank[i].rstctl,
886cb033741SShaveta Leekha 				(SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
887cb033741SShaveta Leekha 				| SRDS_RSTCTL_SDRST_B));
888cb033741SShaveta Leekha 		}
889cb033741SShaveta Leekha 		break;
890cb033741SShaveta Leekha 	default:
891cb033741SShaveta Leekha 		printf("WARNING:IDT8T49N222A configuration not"
892cb033741SShaveta Leekha 			" supported for:%x SerDes1 Protocol.\n",
893cb033741SShaveta Leekha 			serdes1_prtcl);
894cb033741SShaveta Leekha 	}
895cb033741SShaveta Leekha 
896fb07c0a1SShaveta Leekha out:
897fb07c0a1SShaveta Leekha 	/* Clearing SRDS_RST_MSK bit as now
898fb07c0a1SShaveta Leekha 	 * SerDes reset event can cause a reset request
899fb07c0a1SShaveta Leekha 	 */
900fb07c0a1SShaveta Leekha 	clrbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
901fb07c0a1SShaveta Leekha 	return ret;
902fb07c0a1SShaveta Leekha }
903fb07c0a1SShaveta Leekha 
config_serdes2_refclks(void)904fb07c0a1SShaveta Leekha int config_serdes2_refclks(void)
905fb07c0a1SShaveta Leekha {
906fb07c0a1SShaveta Leekha 	ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
907fb07c0a1SShaveta Leekha 	serdes_corenet_t *srds2_regs =
908fb07c0a1SShaveta Leekha 		(void *)CONFIG_SYS_FSL_CORENET_SERDES2_ADDR;
909fb07c0a1SShaveta Leekha 	u32 serdes2_prtcl;
910fb07c0a1SShaveta Leekha 	int ret = 0;
911fb07c0a1SShaveta Leekha 	int i;
912fb07c0a1SShaveta Leekha 
913fb07c0a1SShaveta Leekha 	serdes2_prtcl = in_be32(&gur->rcwsr[4]) &
914fb07c0a1SShaveta Leekha 			FSL_CORENET2_RCWSR4_SRDS2_PRTCL;
915fb07c0a1SShaveta Leekha 	if (!serdes2_prtcl) {
916fb07c0a1SShaveta Leekha 		debug("SERDES2 is not enabled\n");
917fb07c0a1SShaveta Leekha 		return -ENODEV;
918fb07c0a1SShaveta Leekha 	}
919fb07c0a1SShaveta Leekha 	serdes2_prtcl >>= FSL_CORENET2_RCWSR4_SRDS2_PRTCL_SHIFT;
920fb07c0a1SShaveta Leekha 	debug("Using SERDES2 Protocol: 0x%x:\n", serdes2_prtcl);
921fb07c0a1SShaveta Leekha 
922fb07c0a1SShaveta Leekha 	/* To prevent generation of reset request from SerDes
923fb07c0a1SShaveta Leekha 	 * while changing the refclks, By setting SRDS_RST_MSK bit,
924fb07c0a1SShaveta Leekha 	 * SerDes reset event cannot cause a reset request
925fb07c0a1SShaveta Leekha 	 */
926fb07c0a1SShaveta Leekha 	setbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
927fb07c0a1SShaveta Leekha 
928fb07c0a1SShaveta Leekha 	/* Reconfigure IDT idt8t49n222a device for PCIe SATA to work
929fb07c0a1SShaveta Leekha 	 * For this SerDes2's Refclk1 need to be set to 100MHz
930fb07c0a1SShaveta Leekha 	 */
931fb07c0a1SShaveta Leekha 	switch (serdes2_prtcl) {
932b41f192bSYork Sun #ifdef CONFIG_ARCH_B4420
933fa6e7428Spoonam aggrwal 	case 0x9d:
934fa6e7428Spoonam aggrwal #endif
935fb07c0a1SShaveta Leekha 	case 0x9E:
936fb07c0a1SShaveta Leekha 	case 0x9A:
9378c328c21SShaveta Leekha 		/* fallthrough */
9388c328c21SShaveta Leekha 	case 0xb1:
939fb07c0a1SShaveta Leekha 	case 0xb2:
940fb07c0a1SShaveta Leekha 		debug("Configuring IDT for PCIe SATA for srds_prctl:%x\n",
941fb07c0a1SShaveta Leekha 			serdes2_prtcl);
942fb07c0a1SShaveta Leekha 		ret = select_i2c_ch_pca(I2C_CH_IDT);
943fb07c0a1SShaveta Leekha 		if (!ret) {
944fb07c0a1SShaveta Leekha 			ret = set_serdes_refclk(IDT_SERDES2_ADDRESS, 2,
945fb07c0a1SShaveta Leekha 					SERDES_REFCLK_100,
946c4930b1aSShaveta Leekha 					SERDES_REFCLK_156_25, 0);
947fb07c0a1SShaveta Leekha 			if (ret) {
948fb07c0a1SShaveta Leekha 				printf("IDT8T49N222A configuration failed.\n");
949fb07c0a1SShaveta Leekha 				goto out;
950fb07c0a1SShaveta Leekha 			} else
951fb07c0a1SShaveta Leekha 				debug("IDT8T49N222A configured.\n");
952fb07c0a1SShaveta Leekha 		} else {
953fb07c0a1SShaveta Leekha 			goto out;
954fb07c0a1SShaveta Leekha 		}
955fb07c0a1SShaveta Leekha 		select_i2c_ch_pca(I2C_CH_DEFAULT);
956fb07c0a1SShaveta Leekha 
957fb07c0a1SShaveta Leekha 		/* Steps For SerDes PLLs reset and reconfiguration after
958fb07c0a1SShaveta Leekha 		 * changing SerDes's refclks
959fb07c0a1SShaveta Leekha 		 */
960c4930b1aSShaveta Leekha 		for (i = 0; i < CONFIG_SYS_FSL_SRDS_NUM_PLLS; i++) {
961fb07c0a1SShaveta Leekha 			clrbits_be32(&srds2_regs->bank[i].rstctl,
962fb07c0a1SShaveta Leekha 					SRDS_RSTCTL_SDRST_B);
963fb07c0a1SShaveta Leekha 			udelay(10);
964fb07c0a1SShaveta Leekha 			clrbits_be32(&srds2_regs->bank[i].rstctl,
965fb07c0a1SShaveta Leekha 				(SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B));
966fb07c0a1SShaveta Leekha 			udelay(10);
967fb07c0a1SShaveta Leekha 			setbits_be32(&srds2_regs->bank[i].rstctl,
968fb07c0a1SShaveta Leekha 					SRDS_RSTCTL_RST);
969fb07c0a1SShaveta Leekha 			setbits_be32(&srds2_regs->bank[i].rstctl,
970fb07c0a1SShaveta Leekha 				(SRDS_RSTCTL_SDEN | SRDS_RSTCTL_PLLRST_B
971fb07c0a1SShaveta Leekha 				| SRDS_RSTCTL_SDRST_B));
9727af9a074SShaveta Leekha 
9737af9a074SShaveta Leekha 			udelay(10);
974fb07c0a1SShaveta Leekha 		}
975fb07c0a1SShaveta Leekha 		break;
976fb07c0a1SShaveta Leekha 	default:
977fb07c0a1SShaveta Leekha 		printf("IDT configuration not supported for:%x S2 Protocol.\n",
978fb07c0a1SShaveta Leekha 			serdes2_prtcl);
979fb07c0a1SShaveta Leekha 	}
980fb07c0a1SShaveta Leekha 
981fb07c0a1SShaveta Leekha out:
982fb07c0a1SShaveta Leekha 	/* Clearing SRDS_RST_MSK bit as now
983fb07c0a1SShaveta Leekha 	 * SerDes reset event can cause a reset request
984fb07c0a1SShaveta Leekha 	 */
985fb07c0a1SShaveta Leekha 	clrbits_be32(&gur->rstrqmr1, FSL_CORENET_RSTRQMR1_SRDS_RST_MSK);
986fb07c0a1SShaveta Leekha 	return ret;
987cb033741SShaveta Leekha }
988cb033741SShaveta Leekha 
board_early_init_r(void)989b5b06fb7SYork Sun int board_early_init_r(void)
990b5b06fb7SYork Sun {
991b5b06fb7SYork Sun 	const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;
9929d045682SYork Sun 	int flash_esel = find_tlb_idx((void *)flashbase, 1);
993fb07c0a1SShaveta Leekha 	int ret;
994f7c28aa7SShaveta Leekha 	u32 svr = SVR_SOC_VER(get_svr());
995f7c28aa7SShaveta Leekha 
996f7c28aa7SShaveta Leekha 	/* Create law for MAPLE only for personalities having MAPLE */
997f7c28aa7SShaveta Leekha 	if ((svr == SVR_B4860) || (svr == SVR_B4440) ||
998f7c28aa7SShaveta Leekha 	    (svr == SVR_B4420) || (svr == SVR_B4220)) {
999f7c28aa7SShaveta Leekha 		set_next_law(CONFIG_SYS_MAPLE_MEM_PHYS, LAW_SIZE_16M,
1000f7c28aa7SShaveta Leekha 			     LAW_TRGT_IF_MAPLE);
1001f7c28aa7SShaveta Leekha 	}
1002b5b06fb7SYork Sun 
1003b5b06fb7SYork Sun 	/*
1004b5b06fb7SYork Sun 	 * Remap Boot flash + PROMJET region to caching-inhibited
1005b5b06fb7SYork Sun 	 * so that flash can be erased properly.
1006b5b06fb7SYork Sun 	 */
1007b5b06fb7SYork Sun 
1008b5b06fb7SYork Sun 	/* Flush d-cache and invalidate i-cache of any FLASH data */
1009b5b06fb7SYork Sun 	flush_dcache();
1010b5b06fb7SYork Sun 	invalidate_icache();
1011b5b06fb7SYork Sun 
10129d045682SYork Sun 	if (flash_esel == -1) {
10139d045682SYork Sun 		/* very unlikely unless something is messed up */
10149d045682SYork Sun 		puts("Error: Could not find TLB for FLASH BASE\n");
10159d045682SYork Sun 		flash_esel = 2;	/* give our best effort to continue */
10169d045682SYork Sun 	} else {
1017b5b06fb7SYork Sun 		/* invalidate existing TLB entry for flash + promjet */
1018b5b06fb7SYork Sun 		disable_tlb(flash_esel);
10199d045682SYork Sun 	}
1020b5b06fb7SYork Sun 
1021b5b06fb7SYork Sun 	set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS,
1022b5b06fb7SYork Sun 			MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
1023b5b06fb7SYork Sun 			0, flash_esel, BOOKE_PAGESZ_256M, 1);
1024b5b06fb7SYork Sun 
1025652e29b4SShaveta Leekha 	/*
1026652e29b4SShaveta Leekha 	 * Adjust core voltage according to voltage ID
1027652e29b4SShaveta Leekha 	 * This function changes I2C mux to channel 2.
1028652e29b4SShaveta Leekha 	 */
1029652e29b4SShaveta Leekha 	if (adjust_vdd(0) < 0)
1030652e29b4SShaveta Leekha 		printf("Warning: Adjusting core voltage failed\n");
1031652e29b4SShaveta Leekha 
1032cb033741SShaveta Leekha 	/* SerDes1 refclks need to be set again, as default clks
1033cb033741SShaveta Leekha 	 * are not suitable for CPRI and onboard SGMIIs to work
1034cb033741SShaveta Leekha 	 * simultaneously.
1035cb033741SShaveta Leekha 	 * This function will set SerDes1's Refclk1 and refclk2
1036cb033741SShaveta Leekha 	 * as per SerDes1 protocols
1037cb033741SShaveta Leekha 	 */
1038cb033741SShaveta Leekha 	if (config_serdes1_refclks())
1039cb033741SShaveta Leekha 		printf("SerDes1 Refclks couldn't set properly.\n");
1040cb033741SShaveta Leekha 	else
1041cb033741SShaveta Leekha 		printf("SerDes1 Refclks have been set.\n");
1042b5b06fb7SYork Sun 
1043fb07c0a1SShaveta Leekha 	/* SerDes2 refclks need to be set again, as default clks
1044fb07c0a1SShaveta Leekha 	 * are not suitable for PCIe SATA to work
1045fb07c0a1SShaveta Leekha 	 * This function will set SerDes2's Refclk1 and refclk2
1046fb07c0a1SShaveta Leekha 	 * for SerDes2 protocols having PCIe in them
1047fb07c0a1SShaveta Leekha 	 * for PCIe SATA to work
1048fb07c0a1SShaveta Leekha 	 */
1049fb07c0a1SShaveta Leekha 	ret = config_serdes2_refclks();
1050fb07c0a1SShaveta Leekha 	if (!ret)
1051fb07c0a1SShaveta Leekha 		printf("SerDes2 Refclks have been set.\n");
1052fb07c0a1SShaveta Leekha 	else if (ret == -ENODEV)
1053fb07c0a1SShaveta Leekha 		printf("SerDes disable, Refclks couldn't change.\n");
1054fb07c0a1SShaveta Leekha 	else
1055fb07c0a1SShaveta Leekha 		printf("SerDes2 Refclk reconfiguring failed.\n");
1056fb07c0a1SShaveta Leekha 
10577af9a074SShaveta Leekha #if defined(CONFIG_SYS_FSL_ERRATUM_A006384) || \
10587af9a074SShaveta Leekha 			defined(CONFIG_SYS_FSL_ERRATUM_A006475)
10597af9a074SShaveta Leekha 	/* Rechecking the SerDes locks after all SerDes configurations
10607af9a074SShaveta Leekha 	 * are done, As SerDes PLLs may not lock reliably at 5 G VCO
10617af9a074SShaveta Leekha 	 * and at cold temperatures.
10627af9a074SShaveta Leekha 	 * Following sequence ensure the proper locking of SerDes PLLs.
10637af9a074SShaveta Leekha 	 */
10647af9a074SShaveta Leekha 	if (SVR_MAJ(get_svr()) == 1) {
10657af9a074SShaveta Leekha 		if (check_serdes_pll_locks())
10667af9a074SShaveta Leekha 			printf("SerDes plls still not locked properly.\n");
10677af9a074SShaveta Leekha 		else
10687af9a074SShaveta Leekha 			printf("SerDes plls have been locked well.\n");
10697af9a074SShaveta Leekha 	}
10707af9a074SShaveta Leekha #endif
10717af9a074SShaveta Leekha 
1072b5b06fb7SYork Sun 	/* Configure VSC3316 and VSC3308 crossbar switches */
1073b5b06fb7SYork Sun 	if (configure_vsc3316_3308())
1074b5b06fb7SYork Sun 		printf("VSC:failed to configure VSC3316/3308.\n");
1075b5b06fb7SYork Sun 	else
1076b5b06fb7SYork Sun 		printf("VSC:VSC3316/3308 successfully configured.\n");
1077b5b06fb7SYork Sun 
1078b5b06fb7SYork Sun 	select_i2c_ch_pca(I2C_CH_DEFAULT);
1079b5b06fb7SYork Sun 
1080b5b06fb7SYork Sun 	return 0;
1081b5b06fb7SYork Sun }
1082b5b06fb7SYork Sun 
get_board_sys_clk(void)1083b5b06fb7SYork Sun unsigned long get_board_sys_clk(void)
1084b5b06fb7SYork Sun {
1085b5b06fb7SYork Sun 	u8 sysclk_conf = QIXIS_READ(brdcfg[1]);
1086b5b06fb7SYork Sun 
1087b5b06fb7SYork Sun 	switch ((sysclk_conf & 0x0C) >> 2) {
1088b5b06fb7SYork Sun 	case QIXIS_CLK_100:
1089b5b06fb7SYork Sun 		return 100000000;
1090b5b06fb7SYork Sun 	case QIXIS_CLK_125:
1091b5b06fb7SYork Sun 		return 125000000;
1092b5b06fb7SYork Sun 	case QIXIS_CLK_133:
1093b5b06fb7SYork Sun 		return 133333333;
1094b5b06fb7SYork Sun 	}
1095b5b06fb7SYork Sun 	return 66666666;
1096b5b06fb7SYork Sun }
1097b5b06fb7SYork Sun 
get_board_ddr_clk(void)1098b5b06fb7SYork Sun unsigned long get_board_ddr_clk(void)
1099b5b06fb7SYork Sun {
1100b5b06fb7SYork Sun 	u8 ddrclk_conf = QIXIS_READ(brdcfg[1]);
1101b5b06fb7SYork Sun 
1102b5b06fb7SYork Sun 	switch (ddrclk_conf & 0x03) {
1103b5b06fb7SYork Sun 	case QIXIS_CLK_100:
1104b5b06fb7SYork Sun 		return 100000000;
1105b5b06fb7SYork Sun 	case QIXIS_CLK_125:
1106b5b06fb7SYork Sun 		return 125000000;
1107b5b06fb7SYork Sun 	case QIXIS_CLK_133:
1108b5b06fb7SYork Sun 		return 133333333;
1109b5b06fb7SYork Sun 	}
1110b5b06fb7SYork Sun 	return 66666666;
1111b5b06fb7SYork Sun }
1112b5b06fb7SYork Sun 
serdes_refclock(u8 sw,u8 sdclk)1113b5b06fb7SYork Sun static int serdes_refclock(u8 sw, u8 sdclk)
1114b5b06fb7SYork Sun {
1115b5b06fb7SYork Sun 	unsigned int clock;
1116b5b06fb7SYork Sun 	int ret = -1;
1117b5b06fb7SYork Sun 	u8 brdcfg4;
1118b5b06fb7SYork Sun 
1119b5b06fb7SYork Sun 	if (sdclk == 1) {
1120b5b06fb7SYork Sun 		brdcfg4 = QIXIS_READ(brdcfg[4]);
1121b5b06fb7SYork Sun 		if ((brdcfg4 & CLK_MUX_SEL_MASK) == ETH_PHY_CLK_OUT)
1122b5b06fb7SYork Sun 			return SRDS_PLLCR0_RFCK_SEL_125;
1123b5b06fb7SYork Sun 		else
1124b5b06fb7SYork Sun 			clock = (sw >> 5) & 7;
1125b5b06fb7SYork Sun 	} else
1126b5b06fb7SYork Sun 		clock = (sw >> 6) & 3;
1127b5b06fb7SYork Sun 
1128b5b06fb7SYork Sun 	switch (clock) {
1129b5b06fb7SYork Sun 	case 0:
1130b5b06fb7SYork Sun 		ret = SRDS_PLLCR0_RFCK_SEL_100;
1131b5b06fb7SYork Sun 		break;
1132b5b06fb7SYork Sun 	case 1:
1133b5b06fb7SYork Sun 		ret = SRDS_PLLCR0_RFCK_SEL_125;
1134b5b06fb7SYork Sun 		break;
1135b5b06fb7SYork Sun 	case 2:
1136b5b06fb7SYork Sun 		ret = SRDS_PLLCR0_RFCK_SEL_156_25;
1137b5b06fb7SYork Sun 		break;
1138b5b06fb7SYork Sun 	case 3:
1139b5b06fb7SYork Sun 		ret = SRDS_PLLCR0_RFCK_SEL_161_13;
1140b5b06fb7SYork Sun 		break;
1141b5b06fb7SYork Sun 	case 4:
1142b5b06fb7SYork Sun 	case 5:
1143b5b06fb7SYork Sun 	case 6:
1144b5b06fb7SYork Sun 		ret = SRDS_PLLCR0_RFCK_SEL_122_88;
1145b5b06fb7SYork Sun 		break;
1146b5b06fb7SYork Sun 	default:
1147b5b06fb7SYork Sun 		ret = -1;
1148b5b06fb7SYork Sun 		break;
1149b5b06fb7SYork Sun 	}
1150b5b06fb7SYork Sun 
1151b5b06fb7SYork Sun 	return ret;
1152b5b06fb7SYork Sun }
1153b5b06fb7SYork Sun 
1154b5b06fb7SYork Sun #define NUM_SRDS_BANKS	2
1155b5b06fb7SYork Sun 
misc_init_r(void)1156b5b06fb7SYork Sun int misc_init_r(void)
1157b5b06fb7SYork Sun {
1158b5b06fb7SYork Sun 	u8 sw;
1159b5b06fb7SYork Sun 	serdes_corenet_t *srds_regs =
1160b5b06fb7SYork Sun 		(void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
1161b5b06fb7SYork Sun 	u32 actual[NUM_SRDS_BANKS];
1162b5b06fb7SYork Sun 	unsigned int i;
1163b5b06fb7SYork Sun 	int clock;
1164b5b06fb7SYork Sun 
1165b5b06fb7SYork Sun 	sw = QIXIS_READ(brdcfg[2]);
1166b5b06fb7SYork Sun 	clock = serdes_refclock(sw, 1);
1167b5b06fb7SYork Sun 	if (clock >= 0)
1168b5b06fb7SYork Sun 		actual[0] = clock;
1169b5b06fb7SYork Sun 	else
1170b5b06fb7SYork Sun 		printf("Warning: SDREFCLK1 switch setting is unsupported\n");
1171b5b06fb7SYork Sun 
1172b5b06fb7SYork Sun 	sw = QIXIS_READ(brdcfg[4]);
1173b5b06fb7SYork Sun 	clock = serdes_refclock(sw, 2);
1174b5b06fb7SYork Sun 	if (clock >= 0)
1175b5b06fb7SYork Sun 		actual[1] = clock;
1176b5b06fb7SYork Sun 	else
1177b5b06fb7SYork Sun 		printf("Warning: SDREFCLK2 switch setting unsupported\n");
1178b5b06fb7SYork Sun 
1179b5b06fb7SYork Sun 	for (i = 0; i < NUM_SRDS_BANKS; i++) {
1180b5b06fb7SYork Sun 		u32 pllcr0 = srds_regs->bank[i].pllcr0;
1181b5b06fb7SYork Sun 		u32 expected = pllcr0 & SRDS_PLLCR0_RFCK_SEL_MASK;
1182b5b06fb7SYork Sun 		if (expected != actual[i]) {
1183b5b06fb7SYork Sun 			printf("Warning: SERDES bank %u expects reference clock"
1184b5b06fb7SYork Sun 			       " %sMHz, but actual is %sMHz\n", i + 1,
1185b5b06fb7SYork Sun 			       serdes_clock_to_string(expected),
1186b5b06fb7SYork Sun 			       serdes_clock_to_string(actual[i]));
1187b5b06fb7SYork Sun 		}
1188b5b06fb7SYork Sun 	}
1189b5b06fb7SYork Sun 
1190b5b06fb7SYork Sun 	return 0;
1191b5b06fb7SYork Sun }
1192b5b06fb7SYork Sun 
ft_board_setup(void * blob,bd_t * bd)1193e895a4b0SSimon Glass int ft_board_setup(void *blob, bd_t *bd)
1194b5b06fb7SYork Sun {
1195b5b06fb7SYork Sun 	phys_addr_t base;
1196b5b06fb7SYork Sun 	phys_size_t size;
1197b5b06fb7SYork Sun 
1198b5b06fb7SYork Sun 	ft_cpu_setup(blob, bd);
1199b5b06fb7SYork Sun 
1200*723806ccSSimon Glass 	base = env_get_bootm_low();
1201*723806ccSSimon Glass 	size = env_get_bootm_size();
1202b5b06fb7SYork Sun 
1203b5b06fb7SYork Sun 	fdt_fixup_memory(blob, (u64)base, (u64)size);
1204b5b06fb7SYork Sun 
1205b5b06fb7SYork Sun #ifdef CONFIG_PCI
1206b5b06fb7SYork Sun 	pci_of_setup(blob, bd);
1207b5b06fb7SYork Sun #endif
1208b5b06fb7SYork Sun 
1209b5b06fb7SYork Sun 	fdt_fixup_liodn(blob);
1210b5b06fb7SYork Sun 
1211b5b06fb7SYork Sun #ifdef CONFIG_HAS_FSL_DR_USB
1212a5c289b9SSriram Dash 	fsl_fdt_fixup_dr_usb(blob, bd);
1213b5b06fb7SYork Sun #endif
1214b5b06fb7SYork Sun 
1215b5b06fb7SYork Sun #ifdef CONFIG_SYS_DPAA_FMAN
1216b5b06fb7SYork Sun 	fdt_fixup_fman_ethernet(blob);
1217b5b06fb7SYork Sun 	fdt_fixup_board_enet(blob);
1218b5b06fb7SYork Sun #endif
1219e895a4b0SSimon Glass 
1220e895a4b0SSimon Glass 	return 0;
1221b5b06fb7SYork Sun }
12224354889bSShaveta Leekha 
12234354889bSShaveta Leekha /*
12244354889bSShaveta Leekha  * Dump board switch settings.
12254354889bSShaveta Leekha  * The bits that cannot be read/sampled via some FPGA or some
12264354889bSShaveta Leekha  * registers, they will be displayed as
12274354889bSShaveta Leekha  * underscore in binary format. mask[] has those bits.
12284354889bSShaveta Leekha  * Some bits are calculated differently than the actual switches
12294354889bSShaveta Leekha  * if booting with overriding by FPGA.
12304354889bSShaveta Leekha  */
qixis_dump_switch(void)12314354889bSShaveta Leekha void qixis_dump_switch(void)
12324354889bSShaveta Leekha {
12334354889bSShaveta Leekha 	int i;
12344354889bSShaveta Leekha 	u8 sw[5];
12354354889bSShaveta Leekha 
12364354889bSShaveta Leekha 	/*
12374354889bSShaveta Leekha 	 * Any bit with 1 means that bit cannot be reverse engineered.
12384354889bSShaveta Leekha 	 * It will be displayed as _ in binary format.
12394354889bSShaveta Leekha 	 */
12404354889bSShaveta Leekha 	static const u8 mask[] = {0x07, 0, 0, 0xff, 0};
12414354889bSShaveta Leekha 	char buf[10];
12424354889bSShaveta Leekha 	u8 brdcfg[16], dutcfg[16];
12434354889bSShaveta Leekha 
12444354889bSShaveta Leekha 	for (i = 0; i < 16; i++) {
12454354889bSShaveta Leekha 		brdcfg[i] = qixis_read(offsetof(struct qixis, brdcfg[0]) + i);
12464354889bSShaveta Leekha 		dutcfg[i] = qixis_read(offsetof(struct qixis, dutcfg[0]) + i);
12474354889bSShaveta Leekha 	}
12484354889bSShaveta Leekha 
12494354889bSShaveta Leekha 	sw[0] = ((brdcfg[0] & 0x0f) << 4)	| \
12504354889bSShaveta Leekha 		(brdcfg[9] & 0x08);
12514354889bSShaveta Leekha 	sw[1] = ((dutcfg[1] & 0x01) << 7)	| \
12524354889bSShaveta Leekha 		((dutcfg[2] & 0x07) << 4)       | \
12534354889bSShaveta Leekha 		((dutcfg[6] & 0x10) >> 1)       | \
12544354889bSShaveta Leekha 		((dutcfg[6] & 0x80) >> 5)       | \
12554354889bSShaveta Leekha 		((dutcfg[1] & 0x40) >> 5)       | \
12564354889bSShaveta Leekha 		(dutcfg[6] & 0x01);
12574354889bSShaveta Leekha 	sw[2] = dutcfg[0];
12584354889bSShaveta Leekha 	sw[3] = 0;
12594354889bSShaveta Leekha 	sw[4] = ((brdcfg[1] & 0x30) << 2)	| \
12604354889bSShaveta Leekha 		((brdcfg[1] & 0xc0) >> 2)	| \
12614354889bSShaveta Leekha 		(brdcfg[1] & 0x0f);
12624354889bSShaveta Leekha 
12634354889bSShaveta Leekha 	puts("DIP switch settings:\n");
12644354889bSShaveta Leekha 	for (i = 0; i < 5; i++) {
12654354889bSShaveta Leekha 		printf("SW%d         = 0b%s (0x%02x)\n",
12664354889bSShaveta Leekha 			i + 1, byte_to_binary_mask(sw[i], mask[i], buf), sw[i]);
12674354889bSShaveta Leekha 	}
12684354889bSShaveta Leekha }
1269