xref: /OK3568_Linux_fs/u-boot/board/freescale/mpc8610hpcd/mpc8610hpcd.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright 2007,2009-2011 Freescale Semiconductor, Inc.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #include <common.h>
8*4882a593Smuzhiyun #include <command.h>
9*4882a593Smuzhiyun #include <pci.h>
10*4882a593Smuzhiyun #include <asm/processor.h>
11*4882a593Smuzhiyun #include <asm/immap_86xx.h>
12*4882a593Smuzhiyun #include <asm/fsl_pci.h>
13*4882a593Smuzhiyun #include <fsl_ddr_sdram.h>
14*4882a593Smuzhiyun #include <asm/fsl_serdes.h>
15*4882a593Smuzhiyun #include <i2c.h>
16*4882a593Smuzhiyun #include <asm/io.h>
17*4882a593Smuzhiyun #include <linux/libfdt.h>
18*4882a593Smuzhiyun #include <fdt_support.h>
19*4882a593Smuzhiyun #include <spd_sdram.h>
20*4882a593Smuzhiyun #include <netdev.h>
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun void sdram_init(void);
25*4882a593Smuzhiyun phys_size_t fixed_sdram(void);
26*4882a593Smuzhiyun int mpc8610hpcd_diu_init(void);
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun /* called before any console output */
board_early_init_f(void)30*4882a593Smuzhiyun int board_early_init_f(void)
31*4882a593Smuzhiyun {
32*4882a593Smuzhiyun 	volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
33*4882a593Smuzhiyun 	volatile ccsr_gur_t *gur = &immap->im_gur;
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun 	gur->gpiocr |= 0x88aa5500; /* DIU16, IR1, UART0, UART2 */
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun 	return 0;
38*4882a593Smuzhiyun }
39*4882a593Smuzhiyun 
misc_init_r(void)40*4882a593Smuzhiyun int misc_init_r(void)
41*4882a593Smuzhiyun {
42*4882a593Smuzhiyun 	u8 tmp_val, version;
43*4882a593Smuzhiyun 	u8 *pixis_base = (u8 *)PIXIS_BASE;
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun 	/*Do not use 8259PIC*/
46*4882a593Smuzhiyun 	tmp_val = in_8(pixis_base + PIXIS_BRDCFG0);
47*4882a593Smuzhiyun 	out_8(pixis_base + PIXIS_BRDCFG0, tmp_val | 0x80);
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun 	/*For FPGA V7 or higher, set the IRQMAPSEL to 0 to use MAP0 interrupt*/
50*4882a593Smuzhiyun 	version = in_8(pixis_base + PIXIS_PVER);
51*4882a593Smuzhiyun 	if(version >= 0x07) {
52*4882a593Smuzhiyun 		tmp_val = in_8(pixis_base + PIXIS_BRDCFG0);
53*4882a593Smuzhiyun 		out_8(pixis_base + PIXIS_BRDCFG0, tmp_val & 0xbf);
54*4882a593Smuzhiyun 	}
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun 	/* Using this for DIU init before the driver in linux takes over
57*4882a593Smuzhiyun 	 *  Enable the TFP410 Encoder (I2C address 0x38)
58*4882a593Smuzhiyun 	 */
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun 	tmp_val = 0xBF;
61*4882a593Smuzhiyun 	i2c_write(0x38, 0x08, 1, &tmp_val, sizeof(tmp_val));
62*4882a593Smuzhiyun 	/* Verify if enabled */
63*4882a593Smuzhiyun 	tmp_val = 0;
64*4882a593Smuzhiyun 	i2c_read(0x38, 0x08, 1, &tmp_val, sizeof(tmp_val));
65*4882a593Smuzhiyun 	debug("DVI Encoder Read: 0x%02x\n", tmp_val);
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun 	tmp_val = 0x10;
68*4882a593Smuzhiyun 	i2c_write(0x38, 0x0A, 1, &tmp_val, sizeof(tmp_val));
69*4882a593Smuzhiyun 	/* Verify if enabled */
70*4882a593Smuzhiyun 	tmp_val = 0;
71*4882a593Smuzhiyun 	i2c_read(0x38, 0x0A, 1, &tmp_val, sizeof(tmp_val));
72*4882a593Smuzhiyun 	debug("DVI Encoder Read: 0x%02x\n", tmp_val);
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun 	return 0;
75*4882a593Smuzhiyun }
76*4882a593Smuzhiyun 
checkboard(void)77*4882a593Smuzhiyun int checkboard(void)
78*4882a593Smuzhiyun {
79*4882a593Smuzhiyun 	volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
80*4882a593Smuzhiyun 	volatile ccsr_local_mcm_t *mcm = &immap->im_local_mcm;
81*4882a593Smuzhiyun 	u8 *pixis_base = (u8 *)PIXIS_BASE;
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 	printf ("Board: MPC8610HPCD, Sys ID: 0x%02x, "
84*4882a593Smuzhiyun 		"Sys Ver: 0x%02x, FPGA Ver: 0x%02x, ",
85*4882a593Smuzhiyun 		in_8(pixis_base + PIXIS_ID), in_8(pixis_base + PIXIS_VER),
86*4882a593Smuzhiyun 		in_8(pixis_base + PIXIS_PVER));
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun 	/*
89*4882a593Smuzhiyun 	 * The MPC8610 HPCD workbook says that LBMAP=11 is the "normal" boot
90*4882a593Smuzhiyun 	 * bank and LBMAP=00 is the alternate bank.  However, the pixis
91*4882a593Smuzhiyun 	 * altbank code can only set bits, not clear them, so we treat 00 as
92*4882a593Smuzhiyun 	 * the normal bank and 11 as the alternate.
93*4882a593Smuzhiyun 	 */
94*4882a593Smuzhiyun 	switch (in_8(pixis_base + PIXIS_VBOOT) & 0xC0) {
95*4882a593Smuzhiyun 	case 0:
96*4882a593Smuzhiyun 		puts("vBank: Standard\n");
97*4882a593Smuzhiyun 		break;
98*4882a593Smuzhiyun 	case 0x40:
99*4882a593Smuzhiyun 		puts("Promjet\n");
100*4882a593Smuzhiyun 		break;
101*4882a593Smuzhiyun 	case 0x80:
102*4882a593Smuzhiyun 		puts("NAND\n");
103*4882a593Smuzhiyun 		break;
104*4882a593Smuzhiyun 	case 0xC0:
105*4882a593Smuzhiyun 		puts("vBank: Alternate\n");
106*4882a593Smuzhiyun 		break;
107*4882a593Smuzhiyun 	}
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun 	mcm->abcr |= 0x00010000; /* 0 */
110*4882a593Smuzhiyun 	mcm->hpmr3 = 0x80000008; /* 4c */
111*4882a593Smuzhiyun 	mcm->hpmr0 = 0;
112*4882a593Smuzhiyun 	mcm->hpmr1 = 0;
113*4882a593Smuzhiyun 	mcm->hpmr2 = 0;
114*4882a593Smuzhiyun 	mcm->hpmr4 = 0;
115*4882a593Smuzhiyun 	mcm->hpmr5 = 0;
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun 	return 0;
118*4882a593Smuzhiyun }
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 
dram_init(void)121*4882a593Smuzhiyun int dram_init(void)
122*4882a593Smuzhiyun {
123*4882a593Smuzhiyun 	phys_size_t dram_size = 0;
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun #if defined(CONFIG_SPD_EEPROM)
126*4882a593Smuzhiyun 	dram_size = fsl_ddr_sdram();
127*4882a593Smuzhiyun #else
128*4882a593Smuzhiyun 	dram_size = fixed_sdram();
129*4882a593Smuzhiyun #endif
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun 	setup_ddr_bat(dram_size);
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun 	debug(" DDR: ");
134*4882a593Smuzhiyun 	gd->ram_size = dram_size;
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun 	return 0;
137*4882a593Smuzhiyun }
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun #if !defined(CONFIG_SPD_EEPROM)
141*4882a593Smuzhiyun /*
142*4882a593Smuzhiyun  * Fixed sdram init -- doesn't use serial presence detect.
143*4882a593Smuzhiyun  */
144*4882a593Smuzhiyun 
fixed_sdram(void)145*4882a593Smuzhiyun phys_size_t fixed_sdram(void)
146*4882a593Smuzhiyun {
147*4882a593Smuzhiyun #if !defined(CONFIG_SYS_RAMBOOT)
148*4882a593Smuzhiyun 	volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
149*4882a593Smuzhiyun 	struct ccsr_ddr __iomem *ddr = &immap->im_ddr1;
150*4882a593Smuzhiyun 	uint d_init;
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun 	ddr->cs0_bnds = 0x0000001f;
153*4882a593Smuzhiyun 	ddr->cs0_config = 0x80010202;
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun 	ddr->timing_cfg_3 = 0x00000000;
156*4882a593Smuzhiyun 	ddr->timing_cfg_0 = 0x00260802;
157*4882a593Smuzhiyun 	ddr->timing_cfg_1 = 0x3935d322;
158*4882a593Smuzhiyun 	ddr->timing_cfg_2 = 0x14904cc8;
159*4882a593Smuzhiyun 	ddr->sdram_mode = 0x00480432;
160*4882a593Smuzhiyun 	ddr->sdram_mode_2 = 0x00000000;
161*4882a593Smuzhiyun 	ddr->sdram_interval = 0x06180fff; /* 0x06180100; */
162*4882a593Smuzhiyun 	ddr->sdram_data_init = 0xDEADBEEF;
163*4882a593Smuzhiyun 	ddr->sdram_clk_cntl = 0x03800000;
164*4882a593Smuzhiyun 	ddr->sdram_cfg_2 = 0x04400010;
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun #if defined(CONFIG_DDR_ECC)
167*4882a593Smuzhiyun 	ddr->err_int_en = 0x0000000d;
168*4882a593Smuzhiyun 	ddr->err_disable = 0x00000000;
169*4882a593Smuzhiyun 	ddr->err_sbe = 0x00010000;
170*4882a593Smuzhiyun #endif
171*4882a593Smuzhiyun 	asm("sync;isync");
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun 	udelay(500);
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 	ddr->sdram_cfg = 0xc3000000; /* 0xe3008000;*/
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun #if defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
179*4882a593Smuzhiyun 	d_init = 1;
180*4882a593Smuzhiyun 	debug("DDR - 1st controller: memory initializing\n");
181*4882a593Smuzhiyun 	/*
182*4882a593Smuzhiyun 	 * Poll until memory is initialized.
183*4882a593Smuzhiyun 	 * 512 Meg at 400 might hit this 200 times or so.
184*4882a593Smuzhiyun 	 */
185*4882a593Smuzhiyun 	while ((ddr->sdram_cfg_2 & (d_init << 4)) != 0)
186*4882a593Smuzhiyun 		udelay(1000);
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun 	debug("DDR: memory initialized\n\n");
189*4882a593Smuzhiyun 	asm("sync; isync");
190*4882a593Smuzhiyun 	udelay(500);
191*4882a593Smuzhiyun #endif
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun 	return 512 * 1024 * 1024;
194*4882a593Smuzhiyun #endif
195*4882a593Smuzhiyun 	return CONFIG_SYS_SDRAM_SIZE * 1024 * 1024;
196*4882a593Smuzhiyun }
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun #endif
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun #if defined(CONFIG_PCI)
201*4882a593Smuzhiyun /*
202*4882a593Smuzhiyun  * Initialize PCI Devices, report devices found.
203*4882a593Smuzhiyun  */
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun #ifndef CONFIG_PCI_PNP
206*4882a593Smuzhiyun static struct pci_config_table pci_fsl86xxads_config_table[] = {
207*4882a593Smuzhiyun 	{PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
208*4882a593Smuzhiyun 	 PCI_IDSEL_NUMBER, PCI_ANY_ID,
209*4882a593Smuzhiyun 	 pci_cfgfunc_config_device, {PCI_ENET0_IOADDR,
210*4882a593Smuzhiyun 				 PCI_ENET0_MEMADDR,
211*4882a593Smuzhiyun 				 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER} },
212*4882a593Smuzhiyun 	{}
213*4882a593Smuzhiyun };
214*4882a593Smuzhiyun #endif
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun 
217*4882a593Smuzhiyun static struct pci_controller pci1_hose;
218*4882a593Smuzhiyun #endif /* CONFIG_PCI */
219*4882a593Smuzhiyun 
pci_init_board(void)220*4882a593Smuzhiyun void pci_init_board(void)
221*4882a593Smuzhiyun {
222*4882a593Smuzhiyun 	volatile immap_t *immap = (immap_t *) CONFIG_SYS_CCSRBAR;
223*4882a593Smuzhiyun 	volatile ccsr_gur_t *gur = &immap->im_gur;
224*4882a593Smuzhiyun 	struct fsl_pci_info pci_info;
225*4882a593Smuzhiyun 	u32 devdisr;
226*4882a593Smuzhiyun 	int first_free_busno;
227*4882a593Smuzhiyun 	int pci_agent;
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun 	devdisr = in_be32(&gur->devdisr);
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun 	first_free_busno = fsl_pcie_init_board(0);
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun #ifdef CONFIG_PCI1
234*4882a593Smuzhiyun 	if (!(devdisr & MPC86xx_DEVDISR_PCI1)) {
235*4882a593Smuzhiyun 		SET_STD_PCI_INFO(pci_info, 1);
236*4882a593Smuzhiyun 		set_next_law(pci_info.mem_phys,
237*4882a593Smuzhiyun 			law_size_bits(pci_info.mem_size), pci_info.law);
238*4882a593Smuzhiyun 		set_next_law(pci_info.io_phys,
239*4882a593Smuzhiyun 			law_size_bits(pci_info.io_size), pci_info.law);
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun 		pci_agent = fsl_setup_hose(&pci1_hose, pci_info.regs);
242*4882a593Smuzhiyun 		printf("PCI: connected to PCI slots as %s" \
243*4882a593Smuzhiyun 			" (base address %lx)\n",
244*4882a593Smuzhiyun 			pci_agent ? "Agent" : "Host",
245*4882a593Smuzhiyun 			pci_info.regs);
246*4882a593Smuzhiyun #ifndef CONFIG_PCI_PNP
247*4882a593Smuzhiyun 		pci1_hose.config_table = pci_mpc86xxcts_config_table;
248*4882a593Smuzhiyun #endif
249*4882a593Smuzhiyun 		first_free_busno = fsl_pci_init_port(&pci_info,
250*4882a593Smuzhiyun 					&pci1_hose, first_free_busno);
251*4882a593Smuzhiyun 	} else {
252*4882a593Smuzhiyun 		printf("PCI: disabled\n");
253*4882a593Smuzhiyun 	}
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun 	puts("\n");
256*4882a593Smuzhiyun #else
257*4882a593Smuzhiyun 	setbits_be32(&gur->devdisr, MPC86xx_DEVDISR_PCI1); /* disable */
258*4882a593Smuzhiyun #endif
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun 	fsl_pcie_init_board(first_free_busno);
261*4882a593Smuzhiyun }
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun #if defined(CONFIG_OF_BOARD_SETUP)
ft_board_setup(void * blob,bd_t * bd)264*4882a593Smuzhiyun int ft_board_setup(void *blob, bd_t *bd)
265*4882a593Smuzhiyun {
266*4882a593Smuzhiyun 	ft_cpu_setup(blob, bd);
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun 	FT_FSL_PCI_SETUP;
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun 	return 0;
271*4882a593Smuzhiyun }
272*4882a593Smuzhiyun #endif
273*4882a593Smuzhiyun 
274*4882a593Smuzhiyun /*
275*4882a593Smuzhiyun  * get_board_sys_clk
276*4882a593Smuzhiyun  * Reads the FPGA on board for CONFIG_SYS_CLK_FREQ
277*4882a593Smuzhiyun  */
278*4882a593Smuzhiyun 
279*4882a593Smuzhiyun unsigned long
get_board_sys_clk(ulong dummy)280*4882a593Smuzhiyun get_board_sys_clk(ulong dummy)
281*4882a593Smuzhiyun {
282*4882a593Smuzhiyun 	u8 i;
283*4882a593Smuzhiyun 	ulong val = 0;
284*4882a593Smuzhiyun 	u8 *pixis_base = (u8 *)PIXIS_BASE;
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 	i = in_8(pixis_base + PIXIS_SPD);
287*4882a593Smuzhiyun 	i &= 0x07;
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun 	switch (i) {
290*4882a593Smuzhiyun 	case 0:
291*4882a593Smuzhiyun 		val = 33333000;
292*4882a593Smuzhiyun 		break;
293*4882a593Smuzhiyun 	case 1:
294*4882a593Smuzhiyun 		val = 39999600;
295*4882a593Smuzhiyun 		break;
296*4882a593Smuzhiyun 	case 2:
297*4882a593Smuzhiyun 		val = 49999500;
298*4882a593Smuzhiyun 		break;
299*4882a593Smuzhiyun 	case 3:
300*4882a593Smuzhiyun 		val = 66666000;
301*4882a593Smuzhiyun 		break;
302*4882a593Smuzhiyun 	case 4:
303*4882a593Smuzhiyun 		val = 83332500;
304*4882a593Smuzhiyun 		break;
305*4882a593Smuzhiyun 	case 5:
306*4882a593Smuzhiyun 		val = 99999000;
307*4882a593Smuzhiyun 		break;
308*4882a593Smuzhiyun 	case 6:
309*4882a593Smuzhiyun 		val = 133332000;
310*4882a593Smuzhiyun 		break;
311*4882a593Smuzhiyun 	case 7:
312*4882a593Smuzhiyun 		val = 166665000;
313*4882a593Smuzhiyun 		break;
314*4882a593Smuzhiyun 	}
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun 	return val;
317*4882a593Smuzhiyun }
318*4882a593Smuzhiyun 
board_eth_init(bd_t * bis)319*4882a593Smuzhiyun int board_eth_init(bd_t *bis)
320*4882a593Smuzhiyun {
321*4882a593Smuzhiyun 	return pci_eth_init(bis);
322*4882a593Smuzhiyun }
323*4882a593Smuzhiyun 
board_reset(void)324*4882a593Smuzhiyun void board_reset(void)
325*4882a593Smuzhiyun {
326*4882a593Smuzhiyun 	u8 *pixis_base = (u8 *)PIXIS_BASE;
327*4882a593Smuzhiyun 
328*4882a593Smuzhiyun 	out_8(pixis_base + PIXIS_RST, 0);
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun 	while (1)
331*4882a593Smuzhiyun 		;
332*4882a593Smuzhiyun }
333