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