blob: ae8ba45e69d125b96241570aacdafeaa788fdf0c [file] [log] [blame]
Poonam Aggrwal49249e12011-02-09 19:17:53 +00001/*
2 * Copyright 2010-2011 Freescale Semiconductor, Inc.
3 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02004 * SPDX-License-Identifier: GPL-2.0+
Poonam Aggrwal49249e12011-02-09 19:17:53 +00005 */
6
7#include <common.h>
8#include <asm/processor.h>
9#include <asm/mmu.h>
10#include <asm/cache.h>
11#include <asm/immap_85xx.h>
12#include <asm/io.h>
13#include <miiphy.h>
14#include <libfdt.h>
15#include <fdt_support.h>
16#include <fsl_mdio.h>
17#include <tsec.h>
18#include <mmc.h>
19#include <netdev.h>
20#include <pci.h>
21#include <asm/fsl_serdes.h>
22#include <asm/fsl_ifc.h>
23#include <asm/fsl_pci.h>
Poonam Aggrwal49249e12011-02-09 19:17:53 +000024#include <hwconfig.h>
Shengzhou Liuad89da02013-09-13 14:46:02 +080025#include <i2c.h>
Poonam Aggrwal49249e12011-02-09 19:17:53 +000026
27DECLARE_GLOBAL_DATA_PTR;
28
29#define GPIO4_PCIE_RESET_SET 0x08000000
30#define MUX_CPLD_CAN_UART 0x00
31#define MUX_CPLD_TDM 0x01
32#define MUX_CPLD_SPICS0_FLASH 0x00
33#define MUX_CPLD_SPICS0_SLIC 0x02
Shengzhou Liuad89da02013-09-13 14:46:02 +080034#define PMUXCR1_IFC_MASK 0x00ffff00
35#define PMUXCR1_SDHC_MASK 0x00fff000
36#define PMUXCR1_SDHC_ENABLE 0x00555000
Poonam Aggrwal49249e12011-02-09 19:17:53 +000037
Shengzhou Liuad89da02013-09-13 14:46:02 +080038enum {
39 MUX_TYPE_IFC,
40 MUX_TYPE_SDHC,
41};
42
43static uint sd_ifc_mux;
44
Poonam Aggrwal49249e12011-02-09 19:17:53 +000045struct cpld_data {
46 u8 cpld_ver; /* cpld revision */
47 u8 pcba_ver; /* pcb revision number */
48 u8 twindie_ddr3;
49 u8 res1[6];
50 u8 bank_sel; /* NOR Flash bank */
51 u8 res2[5];
52 u8 usb2_sel;
53 u8 res3[1];
54 u8 porsw_sel;
55 u8 tdm_can_sel;
56 u8 spi_cs0_sel; /* SPI CS0 SLIC/SPI Flash */
57 u8 por0; /* POR Options */
58 u8 por1; /* POR Options */
59 u8 por2; /* POR Options */
60 u8 por3; /* POR Options */
61};
Poonam Aggrwal49249e12011-02-09 19:17:53 +000062
63int board_early_init_f(void)
64{
65 ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR);
Poonam Aggrwal49249e12011-02-09 19:17:53 +000066 struct fsl_ifc *ifc = (void *)CONFIG_SYS_IFC_ADDR;
67
68 /* Clock configuration to access CPLD using IFC(GPCM) */
69 setbits_be32(&ifc->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT);
Poonam Aggrwal49249e12011-02-09 19:17:53 +000070 /*
71 * Reset PCIe slots via GPIO4
72 */
73 setbits_be32(&pgpio->gpdir, GPIO4_PCIE_RESET_SET);
74 setbits_be32(&pgpio->gpdat, GPIO4_PCIE_RESET_SET);
75
76 return 0;
77}
78
79int board_early_init_r(void)
80{
Poonam Aggrwal49249e12011-02-09 19:17:53 +000081 const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;
82 const u8 flash_esel = find_tlb_idx((void *)flashbase, 1);
83
84 /*
85 * Remap Boot flash region to caching-inhibited
86 * so that flash can be erased properly.
87 */
88
89 /* Flush d-cache and invalidate i-cache of any FLASH data */
90 flush_dcache();
91 invalidate_icache();
92
93 /* invalidate existing TLB entry for flash */
94 disable_tlb(flash_esel);
95
96 set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS,
97 MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
98 0, flash_esel, BOOKE_PAGESZ_16M, 1);
99
100 set_tlb(1, flashbase + 0x1000000,
101 CONFIG_SYS_FLASH_BASE_PHYS + 0x1000000,
102 MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
103 0, flash_esel+1, BOOKE_PAGESZ_16M, 1);
Poonam Aggrwal49249e12011-02-09 19:17:53 +0000104 return 0;
105}
106
107#ifdef CONFIG_PCI
108void pci_init_board(void)
109{
110 fsl_pcie_init_board(0);
111}
112#endif /* ifdef CONFIG_PCI */
113
Shengzhou Liuad89da02013-09-13 14:46:02 +0800114int config_board_mux(int ctrl_type)
115{
116 ccsr_gur_t __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
117 u8 tmp;
118
119 switch (ctrl_type) {
120 case MUX_TYPE_IFC:
121 i2c_set_bus_num(I2C_PCA9557_BUS_NUM);
122 tmp = 0xf0;
123 i2c_write(I2C_PCA9557_ADDR1, 3, 1, &tmp, 1);
124 tmp = 0x01;
125 i2c_write(I2C_PCA9557_ADDR1, 1, 1, &tmp, 1);
126 sd_ifc_mux = MUX_TYPE_IFC;
127 clrbits_be32(&gur->pmuxcr, PMUXCR1_IFC_MASK);
128 break;
129 case MUX_TYPE_SDHC:
130 i2c_set_bus_num(I2C_PCA9557_BUS_NUM);
131 tmp = 0xf0;
132 i2c_write(I2C_PCA9557_ADDR1, 3, 1, &tmp, 1);
133 tmp = 0x05;
134 i2c_write(I2C_PCA9557_ADDR1, 1, 1, &tmp, 1);
135 sd_ifc_mux = MUX_TYPE_SDHC;
136 clrsetbits_be32(&gur->pmuxcr, PMUXCR1_SDHC_MASK,
137 PMUXCR1_SDHC_ENABLE);
138 break;
139 default:
140 break;
141 }
142
143 return 0;
144}
145
Poonam Aggrwal49249e12011-02-09 19:17:53 +0000146int checkboard(void)
147{
148 struct cpu_type *cpu;
149
Simon Glass67ac13b2012-12-13 20:48:48 +0000150 cpu = gd->arch.cpu;
Timur Tabi5d065c32012-03-15 11:42:27 +0000151 printf("Board: %sRDB\n", cpu->name);
Poonam Aggrwal49249e12011-02-09 19:17:53 +0000152
Shengzhou Liuad89da02013-09-13 14:46:02 +0800153#ifdef CONFIG_SDCARD
154 /* switch to IFC to read info from CPLD */
155 config_board_mux(MUX_TYPE_IFC);
156#endif
157
Poonam Aggrwal49249e12011-02-09 19:17:53 +0000158 return 0;
159}
160
161#ifdef CONFIG_TSEC_ENET
162int board_eth_init(bd_t *bis)
163{
164 struct fsl_pq_mdio_info mdio_info;
165 struct tsec_info_struct tsec_info[4];
166 struct cpu_type *cpu;
167 int num = 0;
168
Simon Glass67ac13b2012-12-13 20:48:48 +0000169 cpu = gd->arch.cpu;
Poonam Aggrwal49249e12011-02-09 19:17:53 +0000170
171#ifdef CONFIG_TSEC1
172 SET_STD_TSEC_INFO(tsec_info[num], 1);
173 num++;
174#endif
175#ifdef CONFIG_TSEC2
176 SET_STD_TSEC_INFO(tsec_info[num], 2);
177 num++;
178#endif
179#ifdef CONFIG_TSEC3
180 /* P1014 and it's derivatives do not support eTSEC3 */
York Sun48f6a5c2012-07-06 17:10:33 -0500181 if (cpu->soc_ver != SVR_P1014) {
Poonam Aggrwal49249e12011-02-09 19:17:53 +0000182 SET_STD_TSEC_INFO(tsec_info[num], 3);
183 num++;
184 }
185#endif
186 if (!num) {
187 printf("No TSECs initialized\n");
188 return 0;
189 }
190
191 mdio_info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR;
192 mdio_info.name = DEFAULT_MII_NAME;
193
194 fsl_pq_mdio_init(bis, &mdio_info);
195
196 tsec_eth_init(bis, tsec_info, num);
197
198 return pci_eth_init(bis);
199}
200#endif
201
202#if defined(CONFIG_OF_BOARD_SETUP)
203void fdt_del_flexcan(void *blob)
204{
205 int nodeoff = 0;
206
207 while ((nodeoff = fdt_node_offset_by_compatible(blob, 0,
Shengzhou Liuf68a7302013-03-25 07:30:09 +0000208 "fsl,p1010-flexcan")) >= 0) {
Poonam Aggrwal49249e12011-02-09 19:17:53 +0000209 fdt_del_node(blob, nodeoff);
210 }
211}
212
213void fdt_del_spi_flash(void *blob)
214{
215 int nodeoff = 0;
216
217 while ((nodeoff = fdt_node_offset_by_compatible(blob, 0,
218 "spansion,s25sl12801")) >= 0) {
219 fdt_del_node(blob, nodeoff);
220 }
221}
222
223void fdt_del_spi_slic(void *blob)
224{
225 int nodeoff = 0;
226
227 while ((nodeoff = fdt_node_offset_by_compatible(blob, 0,
228 "zarlink,le88266")) >= 0) {
229 fdt_del_node(blob, nodeoff);
230 }
231}
232
233void fdt_del_tdm(void *blob)
234{
235 int nodeoff = 0;
236
237 while ((nodeoff = fdt_node_offset_by_compatible(blob, 0,
238 "fsl,starlite-tdm")) >= 0) {
239 fdt_del_node(blob, nodeoff);
240 }
241}
242
Shengzhou Liu487e8ab2012-04-25 23:43:24 +0000243void fdt_del_sdhc(void *blob)
244{
245 int nodeoff = 0;
246
247 while ((nodeoff = fdt_node_offset_by_compatible(blob, 0,
248 "fsl,esdhc")) >= 0) {
249 fdt_del_node(blob, nodeoff);
250 }
251}
252
Shengzhou Liuad89da02013-09-13 14:46:02 +0800253void fdt_del_ifc(void *blob)
254{
255 int nodeoff = 0;
256
257 while ((nodeoff = fdt_node_offset_by_compatible(blob, 0,
258 "fsl,ifc")) >= 0) {
259 fdt_del_node(blob, nodeoff);
260 }
261}
262
Shengzhou Liu487e8ab2012-04-25 23:43:24 +0000263void fdt_disable_uart1(void *blob)
264{
265 int nodeoff;
266
267 nodeoff = fdt_node_offset_by_compat_reg(blob, "fsl,ns16550",
268 CONFIG_SYS_NS16550_COM2);
269
270 if (nodeoff > 0) {
271 fdt_status_disabled(blob, nodeoff);
272 } else {
273 printf("WARNING unable to set status for fsl,ns16550 "
274 "uart1: %s\n", fdt_strerror(nodeoff));
275 }
276}
277
Poonam Aggrwal49249e12011-02-09 19:17:53 +0000278void ft_board_setup(void *blob, bd_t *bd)
279{
280 phys_addr_t base;
281 phys_size_t size;
282 struct cpu_type *cpu;
283
Simon Glass67ac13b2012-12-13 20:48:48 +0000284 cpu = gd->arch.cpu;
Poonam Aggrwal49249e12011-02-09 19:17:53 +0000285
286 ft_cpu_setup(blob, bd);
287
288 base = getenv_bootm_low();
289 size = getenv_bootm_size();
290
291#if defined(CONFIG_PCI)
292 FT_FSL_PCI_SETUP;
293#endif
294
295 fdt_fixup_memory(blob, (u64)base, (u64)size);
296
Ramneek Mehresha311db62011-11-08 10:21:28 +0530297#if defined(CONFIG_HAS_FSL_DR_USB)
Poonam Aggrwal49249e12011-02-09 19:17:53 +0000298 fdt_fixup_dr_usb(blob, bd);
Ramneek Mehresha311db62011-11-08 10:21:28 +0530299#endif
Poonam Aggrwal49249e12011-02-09 19:17:53 +0000300
301 /* P1014 and it's derivatives don't support CAN and eTSEC3 */
York Sun48f6a5c2012-07-06 17:10:33 -0500302 if (cpu->soc_ver == SVR_P1014) {
Poonam Aggrwal49249e12011-02-09 19:17:53 +0000303 fdt_del_flexcan(blob);
304 fdt_del_node_and_alias(blob, "ethernet2");
305 }
Shengzhou Liuad89da02013-09-13 14:46:02 +0800306
307 /* Delete IFC node as IFC pins are multiplexing with SDHC */
308 if (sd_ifc_mux != MUX_TYPE_IFC)
309 fdt_del_ifc(blob);
310 else
311 fdt_del_sdhc(blob);
312
Poonam Aggrwal49249e12011-02-09 19:17:53 +0000313 if (hwconfig_subarg_cmp("fsl_p1010mux", "tdm_can", "can")) {
Poonam Aggrwal49249e12011-02-09 19:17:53 +0000314 fdt_del_tdm(blob);
315 fdt_del_spi_slic(blob);
Shengzhou Liu487e8ab2012-04-25 23:43:24 +0000316 } else if (hwconfig_subarg_cmp("fsl_p1010mux", "tdm_can", "tdm")) {
Poonam Aggrwal49249e12011-02-09 19:17:53 +0000317 fdt_del_flexcan(blob);
318 fdt_del_spi_flash(blob);
Shengzhou Liu487e8ab2012-04-25 23:43:24 +0000319 fdt_disable_uart1(blob);
320 } else {
321 /*
322 * If we don't set fsl_p1010mux:tdm_can to "can" or "tdm"
323 * explicitly, defaultly spi_cs_sel to spi-flash instead of
324 * to tdm/slic.
325 */
326 fdt_del_tdm(blob);
327 fdt_del_flexcan(blob);
328 fdt_disable_uart1(blob);
Poonam Aggrwal49249e12011-02-09 19:17:53 +0000329 }
Poonam Aggrwal49249e12011-02-09 19:17:53 +0000330}
331#endif
332
Shengzhou Liuad89da02013-09-13 14:46:02 +0800333#ifdef CONFIG_SDCARD
334int board_mmc_init(bd_t *bis)
335{
336 config_board_mux(MUX_TYPE_SDHC);
337 return -1;
338}
339#else
340void board_reset(void)
341{
342 /* mux to IFC to enable CPLD for reset */
343 if (sd_ifc_mux != MUX_TYPE_IFC)
344 config_board_mux(MUX_TYPE_IFC);
345}
346#endif
347
348
Poonam Aggrwal49249e12011-02-09 19:17:53 +0000349int misc_init_r(void)
350{
351 struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE);
352 ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
353
354 if (hwconfig_subarg_cmp("fsl_p1010mux", "tdm_can", "can")) {
355 clrbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_CAN1_TDM |
356 MPC85xx_PMUXCR_CAN1_UART |
357 MPC85xx_PMUXCR_CAN2_TDM |
358 MPC85xx_PMUXCR_CAN2_UART);
359 out_8(&cpld_data->tdm_can_sel, MUX_CPLD_CAN_UART);
Shengzhou Liu487e8ab2012-04-25 23:43:24 +0000360 } else if (hwconfig_subarg_cmp("fsl_p1010mux", "tdm_can", "tdm")) {
Poonam Aggrwal49249e12011-02-09 19:17:53 +0000361 clrbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_CAN2_UART |
362 MPC85xx_PMUXCR_CAN1_UART);
363 setbits_be32(&gur->pmuxcr, MPC85xx_PMUXCR_CAN2_TDM |
364 MPC85xx_PMUXCR_CAN1_TDM);
365 clrbits_be32(&gur->pmuxcr2, MPC85xx_PMUXCR2_UART_GPIO);
366 setbits_be32(&gur->pmuxcr2, MPC85xx_PMUXCR2_UART_TDM);
367 out_8(&cpld_data->tdm_can_sel, MUX_CPLD_TDM);
368 out_8(&cpld_data->spi_cs0_sel, MUX_CPLD_SPICS0_SLIC);
Shengzhou Liu487e8ab2012-04-25 23:43:24 +0000369 } else {
370 /* defaultly spi_cs_sel to flash */
371 out_8(&cpld_data->spi_cs0_sel, MUX_CPLD_SPICS0_FLASH);
372 }
373
Shengzhou Liuad89da02013-09-13 14:46:02 +0800374 if (hwconfig("esdhc"))
375 config_board_mux(MUX_TYPE_SDHC);
376 else if (hwconfig("ifc"))
377 config_board_mux(MUX_TYPE_IFC);
378
Poonam Aggrwal49249e12011-02-09 19:17:53 +0000379 return 0;
380}
Shengzhou Liuad89da02013-09-13 14:46:02 +0800381
382static int pin_mux_cmd(cmd_tbl_t *cmdtp, int flag, int argc,
383 char * const argv[])
384{
385 if (argc < 2)
386 return CMD_RET_USAGE;
387 if (strcmp(argv[1], "ifc") == 0)
388 config_board_mux(MUX_TYPE_IFC);
389 else if (strcmp(argv[1], "sdhc") == 0)
390 config_board_mux(MUX_TYPE_SDHC);
391 else
392 return CMD_RET_USAGE;
393 return 0;
394}
395
396U_BOOT_CMD(
397 mux, 2, 0, pin_mux_cmd,
398 "configure multiplexing pin for IFC/SDHC bus in runtime",
399 "bus_type (e.g. mux sdhc)"
400);