1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright 2006, 2007, 2010-2011 Freescale Semiconductor.
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
5*4882a593Smuzhiyun */
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun #include <common.h>
8*4882a593Smuzhiyun #include <pci.h>
9*4882a593Smuzhiyun #include <asm/processor.h>
10*4882a593Smuzhiyun #include <asm/immap_86xx.h>
11*4882a593Smuzhiyun #include <asm/fsl_pci.h>
12*4882a593Smuzhiyun #include <fsl_ddr_sdram.h>
13*4882a593Smuzhiyun #include <asm/fsl_serdes.h>
14*4882a593Smuzhiyun #include <asm/io.h>
15*4882a593Smuzhiyun #include <linux/libfdt.h>
16*4882a593Smuzhiyun #include <fdt_support.h>
17*4882a593Smuzhiyun #include <netdev.h>
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun phys_size_t fixed_sdram(void);
22*4882a593Smuzhiyun
checkboard(void)23*4882a593Smuzhiyun int checkboard(void)
24*4882a593Smuzhiyun {
25*4882a593Smuzhiyun u8 vboot;
26*4882a593Smuzhiyun u8 *pixis_base = (u8 *)PIXIS_BASE;
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun printf ("Board: MPC8641HPCN, Sys ID: 0x%02x, "
29*4882a593Smuzhiyun "Sys Ver: 0x%02x, FPGA Ver: 0x%02x, ",
30*4882a593Smuzhiyun in_8(pixis_base + PIXIS_ID), in_8(pixis_base + PIXIS_VER),
31*4882a593Smuzhiyun in_8(pixis_base + PIXIS_PVER));
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun vboot = in_8(pixis_base + PIXIS_VBOOT);
34*4882a593Smuzhiyun if (vboot & PIXIS_VBOOT_FMAP)
35*4882a593Smuzhiyun printf ("vBank: %d\n", ((vboot & PIXIS_VBOOT_FBANK) >> 6));
36*4882a593Smuzhiyun else
37*4882a593Smuzhiyun puts ("Promjet\n");
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun return 0;
40*4882a593Smuzhiyun }
41*4882a593Smuzhiyun
dram_init(void)42*4882a593Smuzhiyun int dram_init(void)
43*4882a593Smuzhiyun {
44*4882a593Smuzhiyun phys_size_t dram_size = 0;
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun #if defined(CONFIG_SPD_EEPROM)
47*4882a593Smuzhiyun dram_size = fsl_ddr_sdram();
48*4882a593Smuzhiyun #else
49*4882a593Smuzhiyun dram_size = fixed_sdram();
50*4882a593Smuzhiyun #endif
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun setup_ddr_bat(dram_size);
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun debug(" DDR: ");
55*4882a593Smuzhiyun gd->ram_size = dram_size;
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun return 0;
58*4882a593Smuzhiyun }
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun #if !defined(CONFIG_SPD_EEPROM)
62*4882a593Smuzhiyun /*
63*4882a593Smuzhiyun * Fixed sdram init -- doesn't use serial presence detect.
64*4882a593Smuzhiyun */
65*4882a593Smuzhiyun phys_size_t
fixed_sdram(void)66*4882a593Smuzhiyun fixed_sdram(void)
67*4882a593Smuzhiyun {
68*4882a593Smuzhiyun #if !defined(CONFIG_SYS_RAMBOOT)
69*4882a593Smuzhiyun volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
70*4882a593Smuzhiyun struct ccsr_ddr __iomem *ddr = &immap->im_ddr1;
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun ddr->cs0_bnds = CONFIG_SYS_DDR_CS0_BNDS;
73*4882a593Smuzhiyun ddr->cs0_config = CONFIG_SYS_DDR_CS0_CONFIG;
74*4882a593Smuzhiyun ddr->timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3;
75*4882a593Smuzhiyun ddr->timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0;
76*4882a593Smuzhiyun ddr->timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1;
77*4882a593Smuzhiyun ddr->timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2;
78*4882a593Smuzhiyun ddr->sdram_mode = CONFIG_SYS_DDR_MODE_1;
79*4882a593Smuzhiyun ddr->sdram_mode_2 = CONFIG_SYS_DDR_MODE_2;
80*4882a593Smuzhiyun ddr->sdram_interval = CONFIG_SYS_DDR_INTERVAL;
81*4882a593Smuzhiyun ddr->sdram_data_init = CONFIG_SYS_DDR_DATA_INIT;
82*4882a593Smuzhiyun ddr->sdram_clk_cntl = CONFIG_SYS_DDR_CLK_CTRL;
83*4882a593Smuzhiyun ddr->sdram_ocd_cntl = CONFIG_SYS_DDR_OCD_CTRL;
84*4882a593Smuzhiyun ddr->sdram_ocd_status = CONFIG_SYS_DDR_OCD_STATUS;
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun #if defined (CONFIG_DDR_ECC)
87*4882a593Smuzhiyun ddr->err_disable = 0x0000008D;
88*4882a593Smuzhiyun ddr->err_sbe = 0x00ff0000;
89*4882a593Smuzhiyun #endif
90*4882a593Smuzhiyun asm("sync;isync");
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun udelay(500);
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun #if defined (CONFIG_DDR_ECC)
95*4882a593Smuzhiyun /* Enable ECC checking */
96*4882a593Smuzhiyun ddr->sdram_cfg = (CONFIG_SYS_DDR_CONTROL | 0x20000000);
97*4882a593Smuzhiyun #else
98*4882a593Smuzhiyun ddr->sdram_cfg = CONFIG_SYS_DDR_CONTROL;
99*4882a593Smuzhiyun ddr->sdram_cfg_2 = CONFIG_SYS_DDR_CONTROL2;
100*4882a593Smuzhiyun #endif
101*4882a593Smuzhiyun asm("sync; isync");
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun udelay(500);
104*4882a593Smuzhiyun #endif
105*4882a593Smuzhiyun return CONFIG_SYS_SDRAM_SIZE * 1024 * 1024;
106*4882a593Smuzhiyun }
107*4882a593Smuzhiyun #endif /* !defined(CONFIG_SPD_EEPROM) */
108*4882a593Smuzhiyun
pci_init_board(void)109*4882a593Smuzhiyun void pci_init_board(void)
110*4882a593Smuzhiyun {
111*4882a593Smuzhiyun fsl_pcie_init_board(0);
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun #ifdef CONFIG_PCIE1
114*4882a593Smuzhiyun /*
115*4882a593Smuzhiyun * Activate ULI1575 legacy chip by performing a fake
116*4882a593Smuzhiyun * memory access. Needed to make ULI RTC work.
117*4882a593Smuzhiyun */
118*4882a593Smuzhiyun in_be32((unsigned *) ((char *)(CONFIG_SYS_PCIE1_MEM_VIRT
119*4882a593Smuzhiyun + CONFIG_SYS_PCIE1_MEM_SIZE - 0x1000000)));
120*4882a593Smuzhiyun #endif /* CONFIG_PCIE1 */
121*4882a593Smuzhiyun }
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun #if defined(CONFIG_OF_BOARD_SETUP)
ft_board_setup(void * blob,bd_t * bd)125*4882a593Smuzhiyun int ft_board_setup(void *blob, bd_t *bd)
126*4882a593Smuzhiyun {
127*4882a593Smuzhiyun int off;
128*4882a593Smuzhiyun u64 *tmp;
129*4882a593Smuzhiyun int addrcells;
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun ft_cpu_setup(blob, bd);
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun FT_FSL_PCI_SETUP;
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun /*
136*4882a593Smuzhiyun * Warn if it looks like the device tree doesn't match u-boot.
137*4882a593Smuzhiyun * This is just an estimation, based on the location of CCSR,
138*4882a593Smuzhiyun * which is defined by the "reg" property in the soc node.
139*4882a593Smuzhiyun */
140*4882a593Smuzhiyun off = fdt_path_offset(blob, "/soc8641");
141*4882a593Smuzhiyun addrcells = fdt_address_cells(blob, 0);
142*4882a593Smuzhiyun tmp = (u64 *)fdt_getprop(blob, off, "reg", NULL);
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun if (tmp) {
145*4882a593Smuzhiyun u64 addr;
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun if (addrcells == 1)
148*4882a593Smuzhiyun addr = *(u32 *)tmp;
149*4882a593Smuzhiyun else
150*4882a593Smuzhiyun addr = *tmp;
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun if (addr != CONFIG_SYS_CCSRBAR_PHYS)
153*4882a593Smuzhiyun printf("WARNING: The CCSRBAR address in your .dts "
154*4882a593Smuzhiyun "does not match the address of the CCSR "
155*4882a593Smuzhiyun "in u-boot. This means your .dts might "
156*4882a593Smuzhiyun "be old.\n");
157*4882a593Smuzhiyun }
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun return 0;
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun #endif
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun /*
165*4882a593Smuzhiyun * get_board_sys_clk
166*4882a593Smuzhiyun * Reads the FPGA on board for CONFIG_SYS_CLK_FREQ
167*4882a593Smuzhiyun */
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun unsigned long
get_board_sys_clk(ulong dummy)170*4882a593Smuzhiyun get_board_sys_clk(ulong dummy)
171*4882a593Smuzhiyun {
172*4882a593Smuzhiyun u8 i, go_bit, rd_clks;
173*4882a593Smuzhiyun ulong val = 0;
174*4882a593Smuzhiyun u8 *pixis_base = (u8 *)PIXIS_BASE;
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun go_bit = in_8(pixis_base + PIXIS_VCTL);
177*4882a593Smuzhiyun go_bit &= 0x01;
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun rd_clks = in_8(pixis_base + PIXIS_VCFGEN0);
180*4882a593Smuzhiyun rd_clks &= 0x1C;
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun /*
183*4882a593Smuzhiyun * Only if both go bit and the SCLK bit in VCFGEN0 are set
184*4882a593Smuzhiyun * should we be using the AUX register. Remember, we also set the
185*4882a593Smuzhiyun * GO bit to boot from the alternate bank on the on-board flash
186*4882a593Smuzhiyun */
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun if (go_bit) {
189*4882a593Smuzhiyun if (rd_clks == 0x1c)
190*4882a593Smuzhiyun i = in_8(pixis_base + PIXIS_AUX);
191*4882a593Smuzhiyun else
192*4882a593Smuzhiyun i = in_8(pixis_base + PIXIS_SPD);
193*4882a593Smuzhiyun } else {
194*4882a593Smuzhiyun i = in_8(pixis_base + PIXIS_SPD);
195*4882a593Smuzhiyun }
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun i &= 0x07;
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun switch (i) {
200*4882a593Smuzhiyun case 0:
201*4882a593Smuzhiyun val = 33000000;
202*4882a593Smuzhiyun break;
203*4882a593Smuzhiyun case 1:
204*4882a593Smuzhiyun val = 40000000;
205*4882a593Smuzhiyun break;
206*4882a593Smuzhiyun case 2:
207*4882a593Smuzhiyun val = 50000000;
208*4882a593Smuzhiyun break;
209*4882a593Smuzhiyun case 3:
210*4882a593Smuzhiyun val = 66000000;
211*4882a593Smuzhiyun break;
212*4882a593Smuzhiyun case 4:
213*4882a593Smuzhiyun val = 83000000;
214*4882a593Smuzhiyun break;
215*4882a593Smuzhiyun case 5:
216*4882a593Smuzhiyun val = 100000000;
217*4882a593Smuzhiyun break;
218*4882a593Smuzhiyun case 6:
219*4882a593Smuzhiyun val = 134000000;
220*4882a593Smuzhiyun break;
221*4882a593Smuzhiyun case 7:
222*4882a593Smuzhiyun val = 166000000;
223*4882a593Smuzhiyun break;
224*4882a593Smuzhiyun }
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun return val;
227*4882a593Smuzhiyun }
228*4882a593Smuzhiyun
board_eth_init(bd_t * bis)229*4882a593Smuzhiyun int board_eth_init(bd_t *bis)
230*4882a593Smuzhiyun {
231*4882a593Smuzhiyun /* Initialize TSECs */
232*4882a593Smuzhiyun cpu_eth_init(bis);
233*4882a593Smuzhiyun return pci_eth_init(bis);
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun
board_reset(void)236*4882a593Smuzhiyun void board_reset(void)
237*4882a593Smuzhiyun {
238*4882a593Smuzhiyun u8 *pixis_base = (u8 *)PIXIS_BASE;
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun out_8(pixis_base + PIXIS_RST, 0);
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun while (1)
243*4882a593Smuzhiyun ;
244*4882a593Smuzhiyun }
245