]>
Commit | Line | Data |
---|---|---|
c59e1b4d | 1 | /* |
3d7506fa | 2 | * Copyright 2010-2012 Freescale Semiconductor, Inc. |
c59e1b4d TT |
3 | * Authors: Srikanth Srinivasan <srikanth.srinivasan@freescale.com> |
4 | * Timur Tabi <timur@freescale.com> | |
5 | * | |
1a459660 | 6 | * SPDX-License-Identifier: GPL-2.0+ |
c59e1b4d TT |
7 | */ |
8 | ||
9 | #include <common.h> | |
10 | #include <command.h> | |
11 | #include <pci.h> | |
12 | #include <asm/processor.h> | |
13 | #include <asm/mmu.h> | |
14 | #include <asm/cache.h> | |
15 | #include <asm/immap_85xx.h> | |
16 | #include <asm/fsl_pci.h> | |
5614e71b | 17 | #include <fsl_ddr_sdram.h> |
c59e1b4d TT |
18 | #include <asm/fsl_serdes.h> |
19 | #include <asm/io.h> | |
b08c8c48 | 20 | #include <linux/libfdt.h> |
c59e1b4d | 21 | #include <fdt_support.h> |
063c1263 | 22 | #include <fsl_mdio.h> |
c59e1b4d TT |
23 | #include <tsec.h> |
24 | #include <asm/fsl_law.h> | |
c59e1b4d TT |
25 | #include <netdev.h> |
26 | #include <i2c.h> | |
a2d12f88 | 27 | #include <hwconfig.h> |
c59e1b4d TT |
28 | |
29 | #include "../common/ngpixis.h" | |
30 | ||
31 | DECLARE_GLOBAL_DATA_PTR; | |
32 | ||
33 | int board_early_init_f(void) | |
34 | { | |
35 | ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; | |
36 | ||
37 | /* Set pmuxcr to allow both i2c1 and i2c2 */ | |
38 | setbits_be32(&gur->pmuxcr, 0x1000); | |
af253608 MM |
39 | #ifdef CONFIG_SYS_RAMBOOT |
40 | setbits_be32(&gur->pmuxcr, | |
41 | in_be32(&gur->pmuxcr) | MPC85xx_PMUXCR_SD_DATA); | |
42 | #endif | |
c59e1b4d TT |
43 | |
44 | /* Read back the register to synchronize the write. */ | |
45 | in_be32(&gur->pmuxcr); | |
46 | ||
47 | /* Set the pin muxing to enable ETSEC2. */ | |
48 | clrbits_be32(&gur->pmuxcr2, 0x001F8000); | |
49 | ||
9b6e9d1c JY |
50 | /* Enable the SPI */ |
51 | clrsetbits_8(&pixis->brdcfg0, PIXIS_ELBC_SPI_MASK, PIXIS_SPI); | |
52 | ||
c59e1b4d TT |
53 | return 0; |
54 | } | |
55 | ||
56 | int checkboard(void) | |
57 | { | |
58 | u8 sw; | |
59 | ||
5d065c3e TT |
60 | printf("Board: P1022DS Sys ID: 0x%02x, " |
61 | "Sys Ver: 0x%02x, FPGA Ver: 0x%02x, ", | |
c59e1b4d TT |
62 | in_8(&pixis->id), in_8(&pixis->arch), in_8(&pixis->scver)); |
63 | ||
64 | sw = in_8(&PIXIS_SW(PIXIS_LBMAP_SWITCH)); | |
65 | ||
66 | switch ((sw & PIXIS_LBMAP_MASK) >> 6) { | |
67 | case 0: | |
68 | printf ("vBank: %u\n", ((sw & 0x30) >> 4)); | |
69 | break; | |
70 | case 1: | |
71 | printf ("NAND\n"); | |
72 | break; | |
73 | case 2: | |
74 | case 3: | |
75 | puts ("Promjet\n"); | |
76 | break; | |
77 | } | |
78 | ||
79 | return 0; | |
80 | } | |
81 | ||
c59e1b4d TT |
82 | #define CONFIG_TFP410_I2C_ADDR 0x38 |
83 | ||
a2d12f88 TT |
84 | /* Masks for the SSI_TDM and AUDCLK bits of the ngPIXIS BRDCFG1 register. */ |
85 | #define CONFIG_PIXIS_BRDCFG1_SSI_TDM_MASK 0x0c | |
86 | #define CONFIG_PIXIS_BRDCFG1_AUDCLK_MASK 0x03 | |
87 | ||
88 | /* Route the I2C1 pins to the SSI port instead. */ | |
89 | #define CONFIG_PIXIS_BRDCFG1_SSI_TDM_SSI 0x08 | |
90 | ||
91 | /* Choose the 12.288Mhz codec reference clock */ | |
92 | #define CONFIG_PIXIS_BRDCFG1_AUDCLK_12 0x02 | |
93 | ||
94 | /* Choose the 11.2896Mhz codec reference clock */ | |
95 | #define CONFIG_PIXIS_BRDCFG1_AUDCLK_11 0x01 | |
96 | ||
b93f81a4 JY |
97 | /* Connect to USB2 */ |
98 | #define CONFIG_PIXIS_BRDCFG0_USB2 0x10 | |
99 | /* Connect to TFM bus */ | |
100 | #define CONFIG_PIXIS_BRDCFG1_TDM 0x0c | |
101 | /* Connect to SPI */ | |
102 | #define CONFIG_PIXIS_BRDCFG0_SPI 0x80 | |
103 | ||
c59e1b4d TT |
104 | int misc_init_r(void) |
105 | { | |
106 | u8 temp; | |
a2d12f88 TT |
107 | const char *audclk; |
108 | size_t arglen; | |
b93f81a4 | 109 | ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); |
c59e1b4d | 110 | |
a2d12f88 | 111 | /* For DVI, enable the TFP410 Encoder. */ |
c59e1b4d TT |
112 | |
113 | temp = 0xBF; | |
114 | if (i2c_write(CONFIG_TFP410_I2C_ADDR, 0x08, 1, &temp, sizeof(temp)) < 0) | |
115 | return -1; | |
c59e1b4d TT |
116 | if (i2c_read(CONFIG_TFP410_I2C_ADDR, 0x08, 1, &temp, sizeof(temp)) < 0) |
117 | return -1; | |
c59e1b4d TT |
118 | debug("DVI Encoder Read: 0x%02x\n", temp); |
119 | ||
120 | temp = 0x10; | |
121 | if (i2c_write(CONFIG_TFP410_I2C_ADDR, 0x0A, 1, &temp, sizeof(temp)) < 0) | |
122 | return -1; | |
c59e1b4d TT |
123 | if (i2c_read(CONFIG_TFP410_I2C_ADDR, 0x0A, 1, &temp, sizeof(temp)) < 0) |
124 | return -1; | |
c59e1b4d TT |
125 | debug("DVI Encoder Read: 0x%02x\n",temp); |
126 | ||
b93f81a4 JY |
127 | /* Enable the USB2 in PMUXCR2 and FGPA */ |
128 | if (hwconfig("usb2")) { | |
129 | clrsetbits_be32(&gur->pmuxcr2, MPC85xx_PMUXCR2_ETSECUSB_MASK, | |
130 | MPC85xx_PMUXCR2_USB); | |
131 | setbits_8(&pixis->brdcfg0, CONFIG_PIXIS_BRDCFG0_USB2); | |
132 | } | |
133 | ||
134 | /* tdm and audio can not enable simultaneous*/ | |
135 | if (hwconfig("tdm") && hwconfig("audclk")){ | |
136 | printf("WARNING: TDM and AUDIO can not be enabled simultaneous !\n"); | |
137 | return -1; | |
138 | } | |
139 | ||
140 | /* Enable the TDM in PMUXCR and FGPA */ | |
141 | if (hwconfig("tdm")) { | |
142 | clrsetbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_TDM_MASK, | |
143 | MPC85xx_PMUXCR_TDM); | |
144 | setbits_8(&pixis->brdcfg1, CONFIG_PIXIS_BRDCFG1_TDM); | |
145 | /* TDM need some configration option by SPI */ | |
146 | clrsetbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_SPI_MASK, | |
147 | MPC85xx_PMUXCR_SPI); | |
148 | setbits_8(&pixis->brdcfg0, CONFIG_PIXIS_BRDCFG0_SPI); | |
149 | } | |
150 | ||
a2d12f88 TT |
151 | /* |
152 | * Enable the reference clock for the WM8776 codec, and route the MUX | |
153 | * pins for SSI. The default is the 12.288 MHz clock | |
154 | */ | |
155 | ||
b93f81a4 JY |
156 | if (hwconfig("audclk")) { |
157 | temp = in_8(&pixis->brdcfg1) & ~(CONFIG_PIXIS_BRDCFG1_SSI_TDM_MASK | | |
158 | CONFIG_PIXIS_BRDCFG1_AUDCLK_MASK); | |
159 | temp |= CONFIG_PIXIS_BRDCFG1_SSI_TDM_SSI; | |
160 | ||
161 | audclk = hwconfig_arg("audclk", &arglen); | |
162 | /* Check the first two chars only */ | |
163 | if (audclk && (strncmp(audclk, "11", 2) == 0)) | |
164 | temp |= CONFIG_PIXIS_BRDCFG1_AUDCLK_11; | |
165 | else | |
166 | temp |= CONFIG_PIXIS_BRDCFG1_AUDCLK_12; | |
167 | setbits_8(&pixis->brdcfg1, temp); | |
168 | } | |
a2d12f88 | 169 | |
c59e1b4d TT |
170 | return 0; |
171 | } | |
172 | ||
9f43d799 KG |
173 | /* |
174 | * A list of PCI and SATA slots | |
175 | */ | |
176 | enum slot_id { | |
177 | SLOT_PCIE1 = 1, | |
178 | SLOT_PCIE2, | |
179 | SLOT_PCIE3, | |
180 | SLOT_PCIE4, | |
181 | SLOT_PCIE5, | |
182 | SLOT_SATA1, | |
183 | SLOT_SATA2 | |
184 | }; | |
185 | ||
186 | /* | |
187 | * This array maps the slot identifiers to their names on the P1022DS board. | |
188 | */ | |
189 | static const char *slot_names[] = { | |
190 | [SLOT_PCIE1] = "Slot 1", | |
191 | [SLOT_PCIE2] = "Slot 2", | |
192 | [SLOT_PCIE3] = "Slot 3", | |
193 | [SLOT_PCIE4] = "Slot 4", | |
194 | [SLOT_PCIE5] = "Mini-PCIe", | |
195 | [SLOT_SATA1] = "SATA 1", | |
196 | [SLOT_SATA2] = "SATA 2", | |
197 | }; | |
198 | ||
199 | /* | |
200 | * This array maps a given SERDES configuration and SERDES device to the PCI or | |
201 | * SATA slot that it connects to. This mapping is hard-coded in the FPGA. | |
202 | */ | |
203 | static u8 serdes_dev_slot[][SATA2 + 1] = { | |
204 | [0x01] = { [PCIE3] = SLOT_PCIE4, [PCIE2] = SLOT_PCIE5 }, | |
205 | [0x02] = { [SATA1] = SLOT_SATA1, [SATA2] = SLOT_SATA2 }, | |
206 | [0x09] = { [PCIE1] = SLOT_PCIE1, [PCIE3] = SLOT_PCIE4, | |
207 | [PCIE2] = SLOT_PCIE5 }, | |
208 | [0x16] = { [PCIE1] = SLOT_PCIE1, [PCIE3] = SLOT_PCIE2, | |
209 | [PCIE2] = SLOT_PCIE3, | |
210 | [SATA1] = SLOT_SATA1, [SATA2] = SLOT_SATA2 }, | |
211 | [0x17] = { [PCIE1] = SLOT_PCIE1, [PCIE3] = SLOT_PCIE2, | |
212 | [PCIE2] = SLOT_PCIE3 }, | |
213 | [0x1a] = { [PCIE1] = SLOT_PCIE1, [PCIE2] = SLOT_PCIE3, | |
214 | [PCIE2] = SLOT_PCIE3, | |
215 | [SATA1] = SLOT_SATA1, [SATA2] = SLOT_SATA2 }, | |
216 | [0x1c] = { [PCIE1] = SLOT_PCIE1, | |
217 | [SATA1] = SLOT_SATA1, [SATA2] = SLOT_SATA2 }, | |
218 | [0x1e] = { [PCIE1] = SLOT_PCIE1, [PCIE3] = SLOT_PCIE3 }, | |
219 | [0x1f] = { [PCIE1] = SLOT_PCIE1 }, | |
220 | }; | |
221 | ||
222 | ||
223 | /* | |
224 | * Returns the name of the slot to which the PCIe or SATA controller is | |
225 | * connected | |
226 | */ | |
a4aafcc9 | 227 | const char *board_serdes_name(enum srds_prtcl device) |
9f43d799 KG |
228 | { |
229 | ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; | |
230 | u32 pordevsr = in_be32(&gur->pordevsr); | |
231 | unsigned int srds_cfg = (pordevsr & MPC85xx_PORDEVSR_IO_SEL) >> | |
232 | MPC85xx_PORDEVSR_IO_SEL_SHIFT; | |
233 | enum slot_id slot = serdes_dev_slot[srds_cfg][device]; | |
234 | const char *name = slot_names[slot]; | |
235 | ||
236 | if (name) | |
237 | return name; | |
238 | else | |
239 | return "Nothing"; | |
240 | } | |
241 | ||
c59e1b4d TT |
242 | #ifdef CONFIG_PCI |
243 | void pci_init_board(void) | |
244 | { | |
a4aafcc9 | 245 | fsl_pcie_init_board(0); |
c59e1b4d TT |
246 | } |
247 | #endif | |
248 | ||
249 | int board_early_init_r(void) | |
250 | { | |
251 | const unsigned int flashbase = CONFIG_SYS_FLASH_BASE; | |
9d045682 | 252 | int flash_esel = find_tlb_idx((void *)flashbase, 1); |
c59e1b4d TT |
253 | |
254 | /* | |
255 | * Remap Boot flash + PROMJET region to caching-inhibited | |
256 | * so that flash can be erased properly. | |
257 | */ | |
258 | ||
259 | /* Flush d-cache and invalidate i-cache of any FLASH data */ | |
260 | flush_dcache(); | |
261 | invalidate_icache(); | |
262 | ||
9d045682 YS |
263 | if (flash_esel == -1) { |
264 | /* very unlikely unless something is messed up */ | |
265 | puts("Error: Could not find TLB for FLASH BASE\n"); | |
266 | flash_esel = 2; /* give our best effort to continue */ | |
267 | } else { | |
268 | /* invalidate existing TLB entry for flash + promjet */ | |
269 | disable_tlb(flash_esel); | |
270 | } | |
c59e1b4d TT |
271 | |
272 | set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS, | |
273 | MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, | |
274 | 0, flash_esel, BOOKE_PAGESZ_256M, 1); | |
275 | ||
276 | return 0; | |
277 | } | |
278 | ||
279 | /* | |
280 | * Initialize on-board and/or PCI Ethernet devices | |
281 | * | |
282 | * Returns: | |
283 | * <0, error | |
284 | * 0, no ethernet devices found | |
285 | * >0, number of ethernet devices initialized | |
286 | */ | |
287 | int board_eth_init(bd_t *bis) | |
288 | { | |
063c1263 | 289 | struct fsl_pq_mdio_info mdio_info; |
c59e1b4d TT |
290 | struct tsec_info_struct tsec_info[2]; |
291 | unsigned int num = 0; | |
292 | ||
293 | #ifdef CONFIG_TSEC1 | |
294 | SET_STD_TSEC_INFO(tsec_info[num], 1); | |
295 | num++; | |
296 | #endif | |
297 | #ifdef CONFIG_TSEC2 | |
298 | SET_STD_TSEC_INFO(tsec_info[num], 2); | |
299 | num++; | |
300 | #endif | |
301 | ||
063c1263 AF |
302 | mdio_info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR; |
303 | mdio_info.name = DEFAULT_MII_NAME; | |
304 | fsl_pq_mdio_init(bis, &mdio_info); | |
305 | ||
c59e1b4d TT |
306 | return tsec_eth_init(bis, tsec_info, num) + pci_eth_init(bis); |
307 | } | |
308 | ||
309 | #ifdef CONFIG_OF_BOARD_SETUP | |
a2d12f88 TT |
310 | /** |
311 | * ft_codec_setup - fix up the clock-frequency property of the codec node | |
312 | * | |
313 | * Update the clock-frequency property based on the value of the 'audclk' | |
29b83d98 TT |
314 | * hwconfig option. If audclk is not specified, then don't write anything |
315 | * to the device tree, because it means that the codec clock is disabled. | |
a2d12f88 TT |
316 | */ |
317 | static void ft_codec_setup(void *blob, const char *compatible) | |
318 | { | |
319 | const char *audclk; | |
320 | size_t arglen; | |
321 | u32 freq; | |
322 | ||
323 | audclk = hwconfig_arg("audclk", &arglen); | |
29b83d98 TT |
324 | if (audclk) { |
325 | if (strncmp(audclk, "11", 2) == 0) | |
326 | freq = 11289600; | |
327 | else | |
328 | freq = 12288000; | |
a2d12f88 | 329 | |
29b83d98 TT |
330 | do_fixup_by_compat_u32(blob, compatible, "clock-frequency", |
331 | freq, 1); | |
332 | } | |
a2d12f88 TT |
333 | } |
334 | ||
e895a4b0 | 335 | int ft_board_setup(void *blob, bd_t *bd) |
c59e1b4d TT |
336 | { |
337 | phys_addr_t base; | |
338 | phys_size_t size; | |
339 | ||
340 | ft_cpu_setup(blob, bd); | |
341 | ||
723806cc SG |
342 | base = env_get_bootm_low(); |
343 | size = env_get_bootm_size(); | |
c59e1b4d TT |
344 | |
345 | fdt_fixup_memory(blob, (u64)base, (u64)size); | |
346 | ||
3d7506fa | 347 | #ifdef CONFIG_HAS_FSL_DR_USB |
a5c289b9 | 348 | fsl_fdt_fixup_dr_usb(blob, bd); |
3d7506fa | 349 | #endif |
350 | ||
6525d51f | 351 | FT_FSL_PCI_SETUP; |
c59e1b4d TT |
352 | |
353 | #ifdef CONFIG_FSL_SGMII_RISER | |
354 | fsl_sgmii_riser_fdt_fixup(blob); | |
355 | #endif | |
a2d12f88 TT |
356 | |
357 | /* Update the WM8776 node's clock frequency property */ | |
358 | ft_codec_setup(blob, "wlf,wm8776"); | |
e895a4b0 SG |
359 | |
360 | return 0; | |
c59e1b4d TT |
361 | } |
362 | #endif |