]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/freescale/p3060qds/p3060qds.c
Merge branch 'master' of git://git.denx.de/u-boot-ppc4xx
[karo-tx-uboot.git] / board / freescale / p3060qds / p3060qds.c
1 /*
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
44 DECLARE_GLOBAL_DATA_PTR;
45
46 int 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
98 int 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
108 void 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
134 void 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
176 int 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
207 static 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
223 int 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  */
269 static 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  */
284 void 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
317 void 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 }