blob: 43e7f2888a525a578bfbd361a060a56056bc4997 [file] [log] [blame]
Shengzhou Liuae6b03f2011-11-22 16:51:13 +08001/*
ramneek mehresh3d7506f2012-04-18 19:39:53 +00002 * Copyright 2011-2012 Freescale Semiconductor, Inc.
Shengzhou Liuae6b03f2011-11-22 16:51:13 +08003 *
4 * See file CREDITS for list of people who contributed to this
5 * project.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA
21 */
22
23#include <common.h>
24#include <command.h>
25#include <netdev.h>
26#include <linux/compiler.h>
27#include <asm/mmu.h>
28#include <asm/processor.h>
29#include <asm/cache.h>
30#include <asm/immap_85xx.h>
31#include <asm/fsl_law.h>
32#include <asm/fsl_serdes.h>
33#include <asm/fsl_portals.h>
34#include <asm/fsl_liodn.h>
35#include <fm_eth.h>
36#include <configs/P3060QDS.h>
37#include <libfdt.h>
38#include <fdt_support.h>
39
40#include "../common/qixis.h"
41#include "p3060qds.h"
42#include "p3060qds_qixis.h"
43
44DECLARE_GLOBAL_DATA_PTR;
45
46int checkboard(void)
47{
48 u8 sw;
49 struct cpu_type *cpu = gd->cpu;
50 ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
51 unsigned int i;
52
53 printf("Board: %s", cpu->name);
54 puts("QDS, ");
55
56 printf("Sys ID: 0x%02x, Sys Ver: 0x%02x, FPGA Ver: 0x%02x, ",
57 QIXIS_READ(id), QIXIS_READ(arch), QIXIS_READ(scver));
58
59 sw = QIXIS_READ(brdcfg[0]);
60 sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT;
61
62 if (sw < 0x8)
63 printf("vBank: %d\n", sw);
64 else if (sw == 0x8)
65 puts("Promjet\n");
66 else if (sw == 0x9)
67 puts("NAND\n");
68 else
69 printf("invalid setting of SW%u\n", PIXIS_LBMAP_SWITCH);
70
Shengzhou Liuae6b03f2011-11-22 16:51:13 +080071 puts("Reset Configuration Word (RCW):");
72 for (i = 0; i < ARRAY_SIZE(gur->rcwsr); i++) {
73 u32 rcw = in_be32(&gur->rcwsr[i]);
74
75 if ((i % 4) == 0)
76 printf("\n %08x:", i * 4);
77 printf(" %08x", rcw);
78 }
79 puts("\n");
80
81 puts("SERDES Reference Clocks: ");
82 sw = QIXIS_READ(brdcfg[2]);
83 for (i = 0; i < 3; i++) {
84 static const char * const freq[] = {"100", "125", "Reserved",
85 "156.25"};
86 unsigned int clock = (sw >> (2 * i)) & 3;
87
88 printf("Bank%u=%sMhz ", i+1, freq[clock]);
89 }
90 puts("\n");
91
92 return 0;
93}
94
95int board_early_init_f(void)
96{
97 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
98
99 /* only single DDR controller on QDS board, disable DDR1_MCK4/5 */
100 setbits_be32(&gur->ddrclkdr, 0x00030000);
101
102 return 0;
103}
104
105void board_config_serdes_mux(void)
106{
107 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
108 int cfg = (in_be32(&gur->rcwsr[4]) &
109 FSL_CORENET_RCWSR4_SRDS_PRTCL) >> 26;
110
111 switch (cfg) {
112 case 0x03:
113 case 0x06:
114 /* set Lane I,J as SGMII */
115 QIXIS_WRITE(brdcfg[6], BRDCFG6_SD4MX_B | BRDCFG6_SD3MX_A |
116 BRDCFG6_SD2MX_B | BRDCFG6_SD1MX_A);
117 break;
118 case 0x16:
119 case 0x19:
120 case 0x1c:
121 /* set Lane I,J as Aurora Debug */
122 QIXIS_WRITE(brdcfg[6], BRDCFG6_SD4MX_A | BRDCFG6_SD3MX_B |
123 BRDCFG6_SD2MX_A | BRDCFG6_SD1MX_B);
124 break;
125 default:
126 puts("Invalid SerDes protocol for P3060QDS\n");
127 break;
128 }
129}
130
131void board_config_usb_mux(void)
132{
133 u8 brdcfg4, brdcfg5, brdcfg7;
134 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
135 u32 rcwsr11 = in_be32(&gur->rcwsr[11]);
136 u32 ec1 = rcwsr11 & FSL_CORENET_RCWSR11_EC1;
137 u32 ec2 = rcwsr11 & FSL_CORENET_RCWSR11_EC2;
138
139 brdcfg4 = QIXIS_READ(brdcfg[4]);
140 brdcfg4 &= ~BRDCFG4_EC_MODE_MASK;
141 if ((ec1 == FSL_CORENET_RCWSR11_EC1_FM1_USB1) &&
142 (ec2 == FSL_CORENET_RCWSR11_EC2_USB2)) {
143 brdcfg4 |= BRDCFG4_EC2_USB_EC1_USB;
144
145 } else if ((ec1 == FSL_CORENET_RCWSR11_EC1_FM1_USB1) &&
146 ((ec2 == FSL_CORENET_RCWSR11_EC2_FM1_DTSEC2) ||
147 (ec2 == FSL_CORENET_RCWSR11_EC2_FM2_DTSEC1))) {
148 brdcfg4 |= BRDCFG4_EC2_RGMII_EC1_USB;
149
150 } else if ((ec1 == FSL_CORENET_RCWSR11_EC1_FM1_DTSEC1) &&
151 (ec2 == FSL_CORENET_RCWSR11_EC2_USB2)) {
152 brdcfg4 |= BRDCFG4_EC2_USB_EC1_RGMII;
153
154 } else if ((ec1 == FSL_CORENET_RCWSR11_EC1_FM1_DTSEC1) &&
155 ((ec2 == FSL_CORENET_RCWSR11_EC2_FM1_DTSEC2) ||
156 (ec2 == FSL_CORENET_RCWSR11_EC2_FM2_DTSEC1))) {
157 brdcfg4 |= BRDCFG4_EC2_RGMII_EC1_RGMII;
158 } else {
159 brdcfg4 |= BRDCFG4_EC2_MII_EC1_MII;
160 }
161 QIXIS_WRITE(brdcfg[4], brdcfg4);
162
163 brdcfg5 = QIXIS_READ(brdcfg[5]);
164 brdcfg5 &= ~(BRDCFG5_USB1ID_MASK | BRDCFG5_USB2ID_MASK);
165 brdcfg5 |= (BRDCFG5_USB1ID_CTRL | BRDCFG5_USB2ID_CTRL);
166 QIXIS_WRITE(brdcfg[5], brdcfg5);
167
168 brdcfg7 = BRDCFG7_JTAGMX_COP_JTAG | BRDCFG7_IQ1MX_IRQ_EVT |
169 BRDCFG7_G1MX_USB1 | BRDCFG7_D1MX_TSEC3USB | BRDCFG7_I3MX_USB1;
170 QIXIS_WRITE(brdcfg[7], brdcfg7);
171}
172
173int board_early_init_r(void)
174{
175 const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;
176 const u8 flash_esel = find_tlb_idx((void *)flashbase, 1);
177
178 /*
179 * Remap Boot flash + PROMJET region to caching-inhibited
180 * so that flash can be erased properly.
181 */
182
183 /* Flush d-cache and invalidate i-cache of any FLASH data */
184 flush_dcache();
185 invalidate_icache();
186
187 /* invalidate existing TLB entry for flash + promjet */
188 disable_tlb(flash_esel);
189
190 set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS,
191 MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
192 0, flash_esel, BOOKE_PAGESZ_256M, 1);
193
194 set_liodns();
195#ifdef CONFIG_SYS_DPAA_QBMAN
196 setup_portals();
197#endif
198 board_config_serdes_mux();
199 board_config_usb_mux();
200
201 return 0;
202}
203
204static const char *serdes_clock_to_string(u32 clock)
205{
206 switch (clock) {
207 case SRDS_PLLCR0_RFCK_SEL_100:
208 return "100";
209 case SRDS_PLLCR0_RFCK_SEL_125:
210 return "125";
211 case SRDS_PLLCR0_RFCK_SEL_156_25:
212 return "156.25";
213 default:
214 return "150";
215 }
216}
217
218#define NUM_SRDS_BANKS 3
219
220int misc_init_r(void)
221{
222 serdes_corenet_t *srds_regs;
223 u32 actual[NUM_SRDS_BANKS];
224 unsigned int i;
225 u8 sw;
226
227 sw = QIXIS_READ(brdcfg[2]);
228 for (i = 0; i < 3; i++) {
229 unsigned int clock = (sw >> (2 * i)) & 3;
230 switch (clock) {
231 case 0:
232 actual[i] = SRDS_PLLCR0_RFCK_SEL_100;
233 break;
234 case 1:
235 actual[i] = SRDS_PLLCR0_RFCK_SEL_125;
236 break;
237 case 3:
238 actual[i] = SRDS_PLLCR0_RFCK_SEL_156_25;
239 break;
240 default:
241 printf("Warning: SDREFCLK%u switch setting of '10' is "
242 "unsupported\n", i + 1);
243 break;
244 }
245 }
246
247 srds_regs = (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
248 for (i = 0; i < NUM_SRDS_BANKS; i++) {
249 u32 pllcr0 = in_be32(&srds_regs->bank[i].pllcr0);
250 u32 expected = pllcr0 & SRDS_PLLCR0_RFCK_SEL_MASK;
251 if (expected != actual[i]) {
252 printf("Warning: SERDES bank %u expects reference clock"
253 " %sMHz, but actual is %sMHz\n", i + 1,
254 serdes_clock_to_string(expected),
255 serdes_clock_to_string(actual[i]));
256 }
257 }
258
259 return 0;
260}
261
262/*
263 * This is map of CVDD values. 33 means CVDD is 3.3v, 25 means CVDD is 2.5v,
264 * 18 means CVDD is 1.8v.
265 */
266static u8 IO_VSEL[] = {
267 33, 33, 33, 25, 25, 25, 18, 18, 18,
268 33, 33, 33, 25, 25, 25, 18, 18, 18,
269 33, 33, 33, 25, 25, 25, 18, 18, 18,
270 33, 33, 33, 33, 33
271};
272
273#define IO_VSEL_MASK 0x1f
274
275/*
276 * different CVDD selects diffenert spi flashs, read dutcfg[3] to get CVDD,
277 * then set status of spi flash nodes to 'disabled' according to CVDD.
278 * CVDD '33' will select spi flash0 and flash1, CVDD '25' will select spi
279 * flash2, CVDD '18' will select spi flash3.
280 */
281void fdt_fixup_board_spi(void *blob)
282{
283 u8 sw5 = QIXIS_READ(dutcfg[3]);
284
285 switch (IO_VSEL[sw5 & IO_VSEL_MASK]) {
286 /* 3.3v */
287 case 33:
288 do_fixup_by_compat(blob, "atmel,at45db081d", "status",
289 "disabled", strlen("disabled") + 1, 1);
290 do_fixup_by_compat(blob, "spansion,sst25wf040", "status",
291 "disabled", strlen("disabled") + 1, 1);
292 break;
293 /* 2.5v */
294 case 25:
295 do_fixup_by_compat(blob, "spansion,s25sl12801", "status",
296 "disabled", strlen("disabled") + 1, 1);
297 do_fixup_by_compat(blob, "spansion,en25q32", "status",
298 "disabled", strlen("disabled") + 1, 1);
299 do_fixup_by_compat(blob, "spansion,sst25wf040", "status",
300 "disabled", strlen("disabled") + 1, 1);
301 break;
302 /* 1.8v */
303 case 18:
304 do_fixup_by_compat(blob, "spansion,s25sl12801", "status",
305 "disabled", strlen("disabled") + 1, 1);
306 do_fixup_by_compat(blob, "spansion,en25q32", "status",
307 "disabled", strlen("disabled") + 1, 1);
308 do_fixup_by_compat(blob, "atmel,at45db081d", "status",
309 "disabled", strlen("disabled") + 1, 1);
310 break;
311 }
312}
313
314void ft_board_setup(void *blob, bd_t *bd)
315{
316 phys_addr_t base;
317 phys_size_t size;
318
319 ft_cpu_setup(blob, bd);
320
321 base = getenv_bootm_low();
322 size = getenv_bootm_size();
323
324 fdt_fixup_memory(blob, (u64)base, (u64)size);
325
ramneek mehresh3d7506f2012-04-18 19:39:53 +0000326#if defined(CONFIG_HAS_FSL_DR_USB) || defined(CONFIG_HAS_FSL_MPH_USB)
327 fdt_fixup_dr_usb(blob, bd);
328#endif
329
Shengzhou Liuae6b03f2011-11-22 16:51:13 +0800330#ifdef CONFIG_PCI
331 pci_of_setup(blob, bd);
332#endif
333
334 fdt_fixup_liodn(blob);
335 fdt_fixup_dr_usb(blob, bd);
336 fdt_fixup_board_spi(blob);
337
338#ifdef CONFIG_SYS_DPAA_FMAN
339 fdt_fixup_fman_ethernet(blob);
340 fdt_fixup_board_enet(blob);
341#endif
342}