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