]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
d1712369 | 2 | /* |
561e710a | 3 | * Copyright 2009-2011 Freescale Semiconductor, Inc. |
d1712369 KG |
4 | */ |
5 | ||
6 | #include <common.h> | |
7 | #include <command.h> | |
8 | #include <netdev.h> | |
0e159024 | 9 | #include <linux/compiler.h> |
d1712369 KG |
10 | #include <asm/mmu.h> |
11 | #include <asm/processor.h> | |
12 | #include <asm/cache.h> | |
13 | #include <asm/immap_85xx.h> | |
14 | #include <asm/fsl_law.h> | |
d1712369 | 15 | #include <asm/fsl_serdes.h> |
d1712369 | 16 | #include <asm/fsl_liodn.h> |
2915609a | 17 | #include <fm_eth.h> |
d1712369 | 18 | |
d1712369 | 19 | #include "../common/ngpixis.h" |
2915609a | 20 | #include "corenet_ds.h" |
d1712369 KG |
21 | |
22 | DECLARE_GLOBAL_DATA_PTR; | |
23 | ||
d1712369 KG |
24 | int checkboard (void) |
25 | { | |
26 | u8 sw; | |
67ac13b1 | 27 | struct cpu_type *cpu = gd->arch.cpu; |
3b83649d | 28 | #if defined(CONFIG_TARGET_P3041DS) || defined(CONFIG_TARGET_P5020DS) || \ |
161b4724 | 29 | defined(CONFIG_TARGET_P5040DS) |
46299078 | 30 | unsigned int i; |
f165bc35 | 31 | #endif |
d31e53b4 | 32 | static const char * const freq[] = {"100", "125", "156.25", "212.5" }; |
d1712369 KG |
33 | |
34 | printf("Board: %sDS, ", cpu->name); | |
35 | printf("Sys ID: 0x%02x, Sys Ver: 0x%02x, FPGA Ver: 0x%02x, ", | |
36 | in_8(&pixis->id), in_8(&pixis->arch), in_8(&pixis->scver)); | |
37 | ||
38 | sw = in_8(&PIXIS_SW(PIXIS_LBMAP_SWITCH)); | |
39 | sw = (sw & PIXIS_LBMAP_MASK) >> PIXIS_LBMAP_SHIFT; | |
40 | ||
41 | if (sw < 0x8) | |
42 | printf("vBank: %d\n", sw); | |
43 | else if (sw == 0x8) | |
44 | puts("Promjet\n"); | |
45 | else if (sw == 0x9) | |
46 | puts("NAND\n"); | |
47 | else | |
48 | printf("invalid setting of SW%u\n", PIXIS_LBMAP_SWITCH); | |
49 | ||
d1712369 KG |
50 | /* Display the actual SERDES reference clocks as configured by the |
51 | * dip switches on the board. Note that the SWx registers could | |
52 | * technically be set to force the reference clocks to match the | |
53 | * values that the SERDES expects (or vice versa). For now, however, | |
54 | * we just display both values and hope the user notices when they | |
55 | * don't match. | |
56 | */ | |
57 | puts("SERDES Reference Clocks: "); | |
161b4724 YS |
58 | #if defined(CONFIG_TARGET_P3041DS) || defined(CONFIG_TARGET_P5020DS) || \ |
59 | defined(CONFIG_TARGET_P5040DS) | |
e02aea61 KG |
60 | sw = in_8(&PIXIS_SW(5)); |
61 | for (i = 0; i < 3; i++) { | |
e02aea61 KG |
62 | unsigned int clock = (sw >> (6 - (2 * i))) & 3; |
63 | ||
64 | printf("Bank%u=%sMhz ", i+1, freq[clock]); | |
65 | } | |
161b4724 | 66 | #ifdef CONFIG_TARGET_P5040DS |
d31e53b4 TT |
67 | /* On P5040DS, SW11[7:8] determines the Bank 4 frequency */ |
68 | sw = in_8(&PIXIS_SW(9)); | |
69 | printf("Bank4=%sMhz ", freq[sw & 3]); | |
70 | #endif | |
e02aea61 KG |
71 | puts("\n"); |
72 | #else | |
d1712369 | 73 | sw = in_8(&PIXIS_SW(3)); |
d31e53b4 TT |
74 | /* SW3[2]: 0 = 100 Mhz, 1 = 125 MHz */ |
75 | /* SW3[3]: 0 = 125 Mhz, 1 = 156.25 MHz */ | |
76 | /* SW3[4]: 0 = 125 Mhz, 1 = 156.25 MHz */ | |
77 | printf("Bank1=%sMHz ", freq[!!(sw & 0x40)]); | |
78 | printf("Bank2=%sMHz ", freq[1 + !!(sw & 0x20)]); | |
79 | printf("Bank3=%sMHz\n", freq[1 + !!(sw & 0x10)]); | |
e02aea61 | 80 | #endif |
d1712369 KG |
81 | |
82 | return 0; | |
83 | } | |
84 | ||
85 | int board_early_init_f(void) | |
86 | { | |
87 | volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); | |
88 | ||
89 | /* | |
90 | * P4080 DS board only uses the DDR1_MCK0/3 and DDR2_MCK0/3 | |
91 | * disable the DDR1_MCK1/2/4/5 and DDR2_MCK1/2/4/5 to reduce | |
92 | * the noise introduced by these unterminated and unused clock pairs. | |
93 | */ | |
94 | setbits_be32(&gur->ddrclkdr, 0x001B001B); | |
95 | ||
96 | return 0; | |
97 | } | |
98 | ||
99 | int board_early_init_r(void) | |
100 | { | |
101 | const unsigned int flashbase = CONFIG_SYS_FLASH_BASE; | |
9d045682 | 102 | int flash_esel = find_tlb_idx((void *)flashbase, 1); |
d1712369 KG |
103 | |
104 | /* | |
105 | * Remap Boot flash + PROMJET region to caching-inhibited | |
106 | * so that flash can be erased properly. | |
107 | */ | |
108 | ||
109 | /* Flush d-cache and invalidate i-cache of any FLASH data */ | |
110 | flush_dcache(); | |
111 | invalidate_icache(); | |
112 | ||
9d045682 YS |
113 | if (flash_esel == -1) { |
114 | /* very unlikely unless something is messed up */ | |
115 | puts("Error: Could not find TLB for FLASH BASE\n"); | |
116 | flash_esel = 2; /* give our best effort to continue */ | |
117 | } else { | |
118 | /* invalidate existing TLB entry for flash + promjet */ | |
119 | disable_tlb(flash_esel); | |
120 | } | |
d1712369 KG |
121 | |
122 | set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS, /* tlb, epn, rpn */ | |
123 | MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, /* perms, wimge */ | |
124 | 0, flash_esel, BOOKE_PAGESZ_256M, 1); /* ts, esel, tsize, iprot */ | |
125 | ||
d1712369 KG |
126 | return 0; |
127 | } | |
128 | ||
d1712369 KG |
129 | #define NUM_SRDS_BANKS 3 |
130 | ||
131 | int misc_init_r(void) | |
132 | { | |
133 | serdes_corenet_t *srds_regs = (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR; | |
134 | u32 actual[NUM_SRDS_BANKS]; | |
135 | unsigned int i; | |
e02aea61 | 136 | u8 sw; |
d1712369 | 137 | |
161b4724 YS |
138 | #if defined(CONFIG_TARGET_P3041DS) || defined(CONFIG_TARGET_P5020DS) || \ |
139 | defined(CONFIG_TARGET_P5040DS) | |
e02aea61 KG |
140 | sw = in_8(&PIXIS_SW(5)); |
141 | for (i = 0; i < 3; i++) { | |
142 | unsigned int clock = (sw >> (6 - (2 * i))) & 3; | |
143 | switch (clock) { | |
144 | case 0: | |
145 | actual[i] = SRDS_PLLCR0_RFCK_SEL_100; | |
146 | break; | |
147 | case 1: | |
148 | actual[i] = SRDS_PLLCR0_RFCK_SEL_125; | |
149 | break; | |
150 | case 2: | |
151 | actual[i] = SRDS_PLLCR0_RFCK_SEL_156_25; | |
152 | break; | |
153 | default: | |
154 | printf("Warning: SDREFCLK%u switch setting of '11' is " | |
155 | "unsupported\n", i + 1); | |
156 | break; | |
157 | } | |
158 | } | |
159 | #else | |
d1712369 KG |
160 | /* Warn if the expected SERDES reference clocks don't match the |
161 | * actual reference clocks. This needs to be done after calling | |
162 | * p4080_erratum_serdes8(), since that function may modify the clocks. | |
163 | */ | |
e02aea61 KG |
164 | sw = in_8(&PIXIS_SW(3)); |
165 | actual[0] = (sw & 0x40) ? | |
d1712369 | 166 | SRDS_PLLCR0_RFCK_SEL_125 : SRDS_PLLCR0_RFCK_SEL_100; |
e02aea61 | 167 | actual[1] = (sw & 0x20) ? |
d1712369 | 168 | SRDS_PLLCR0_RFCK_SEL_156_25 : SRDS_PLLCR0_RFCK_SEL_125; |
e02aea61 | 169 | actual[2] = (sw & 0x10) ? |
d1712369 | 170 | SRDS_PLLCR0_RFCK_SEL_156_25 : SRDS_PLLCR0_RFCK_SEL_125; |
e02aea61 | 171 | #endif |
d1712369 KG |
172 | |
173 | for (i = 0; i < NUM_SRDS_BANKS; i++) { | |
174 | u32 expected = srds_regs->bank[i].pllcr0 & SRDS_PLLCR0_RFCK_SEL_MASK; | |
175 | if (expected != actual[i]) { | |
176 | printf("Warning: SERDES bank %u expects reference clock" | |
177 | " %sMHz, but actual is %sMHz\n", i + 1, | |
178 | serdes_clock_to_string(expected), | |
179 | serdes_clock_to_string(actual[i])); | |
180 | } | |
181 | } | |
182 | ||
183 | return 0; | |
184 | } | |
185 | ||
e895a4b0 | 186 | int ft_board_setup(void *blob, bd_t *bd) |
d1712369 KG |
187 | { |
188 | phys_addr_t base; | |
189 | phys_size_t size; | |
190 | ||
191 | ft_cpu_setup(blob, bd); | |
192 | ||
723806cc SG |
193 | base = env_get_bootm_low(); |
194 | size = env_get_bootm_size(); | |
d1712369 KG |
195 | |
196 | fdt_fixup_memory(blob, (u64)base, (u64)size); | |
197 | ||
198 | #ifdef CONFIG_PCI | |
199 | pci_of_setup(blob, bd); | |
200 | #endif | |
201 | ||
202 | fdt_fixup_liodn(blob); | |
a5c289b9 | 203 | fsl_fdt_fixup_dr_usb(blob, bd); |
d1712369 | 204 | |
2915609a AF |
205 | #ifdef CONFIG_SYS_DPAA_FMAN |
206 | fdt_fixup_fman_ethernet(blob); | |
207 | fdt_fixup_board_enet(blob); | |
208 | #endif | |
e895a4b0 SG |
209 | |
210 | return 0; | |
d1712369 | 211 | } |