xref: /rk3399_rockchip-uboot/board/freescale/mpc8349itx/mpc8349itx.c (revision e58fe95784d2514fc9c21028dc59f2b319a35d80)
1*e58fe957SKim Phillips /*
2*e58fe957SKim Phillips  * Copyright (C) Freescale Semiconductor, Inc. 2006. All rights reserved.
3*e58fe957SKim Phillips  *
4*e58fe957SKim Phillips  * See file CREDITS for list of people who contributed to this
5*e58fe957SKim Phillips  * project.
6*e58fe957SKim Phillips  *
7*e58fe957SKim Phillips  * This program is free software; you can redistribute it and/or
8*e58fe957SKim Phillips  * modify it under the terms of the GNU General Public License as
9*e58fe957SKim Phillips  * published by the Free Software Foundation; either version 2 of
10*e58fe957SKim Phillips  * the License, or (at your option) any later version.
11*e58fe957SKim Phillips  *
12*e58fe957SKim Phillips  * This program is distributed in the hope that it will be useful,
13*e58fe957SKim Phillips  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14*e58fe957SKim Phillips  * MERCHANTABILITY or FITNESS for A PARTICULAR PURPOSE.  See the
15*e58fe957SKim Phillips  * GNU General Public License for more details.
16*e58fe957SKim Phillips  *
17*e58fe957SKim Phillips  * You should have received a copy of the GNU General Public License
18*e58fe957SKim Phillips  * along with this program; if not, write to the Free Software
19*e58fe957SKim Phillips  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20*e58fe957SKim Phillips  * MA 02111-1307 USA
21*e58fe957SKim Phillips  */
22*e58fe957SKim Phillips 
23*e58fe957SKim Phillips #include <common.h>
24*e58fe957SKim Phillips #include <ioports.h>
25*e58fe957SKim Phillips #include <mpc83xx.h>
26*e58fe957SKim Phillips #include <i2c.h>
27*e58fe957SKim Phillips #include <spd.h>
28*e58fe957SKim Phillips #include <miiphy.h>
29*e58fe957SKim Phillips 
30*e58fe957SKim Phillips #ifdef CONFIG_PCI
31*e58fe957SKim Phillips #include <asm/mpc8349_pci.h>
32*e58fe957SKim Phillips #include <pci.h>
33*e58fe957SKim Phillips #endif
34*e58fe957SKim Phillips 
35*e58fe957SKim Phillips #ifdef CONFIG_SPD_EEPROM
36*e58fe957SKim Phillips #include <spd_sdram.h>
37*e58fe957SKim Phillips #else
38*e58fe957SKim Phillips #include <asm/mmu.h>
39*e58fe957SKim Phillips #endif
40*e58fe957SKim Phillips #if defined(CONFIG_OF_FLAT_TREE)
41*e58fe957SKim Phillips #include <ft_build.h>
42*e58fe957SKim Phillips #elif defined(CONFIG_OF_LIBFDT)
43*e58fe957SKim Phillips #include <libfdt.h>
44*e58fe957SKim Phillips #endif
45*e58fe957SKim Phillips 
46*e58fe957SKim Phillips #ifndef CONFIG_SPD_EEPROM
47*e58fe957SKim Phillips /*************************************************************************
48*e58fe957SKim Phillips  *  fixed sdram init -- doesn't use serial presence detect.
49*e58fe957SKim Phillips  ************************************************************************/
50*e58fe957SKim Phillips int fixed_sdram(void)
51*e58fe957SKim Phillips {
52*e58fe957SKim Phillips 	volatile immap_t *im = (immap_t *) CFG_IMMR;
53*e58fe957SKim Phillips 	u32 ddr_size;		/* The size of RAM, in bytes */
54*e58fe957SKim Phillips 	u32 ddr_size_log2 = 0;
55*e58fe957SKim Phillips 
56*e58fe957SKim Phillips 	for (ddr_size = CFG_DDR_SIZE * 0x100000; ddr_size > 1; ddr_size >>= 1) {
57*e58fe957SKim Phillips 		if (ddr_size & 1) {
58*e58fe957SKim Phillips 			return -1;
59*e58fe957SKim Phillips 		}
60*e58fe957SKim Phillips 		ddr_size_log2++;
61*e58fe957SKim Phillips 	}
62*e58fe957SKim Phillips 
63*e58fe957SKim Phillips 	im->sysconf.ddrlaw[0].ar =
64*e58fe957SKim Phillips 	    LAWAR_EN | ((ddr_size_log2 - 1) & LAWAR_SIZE);
65*e58fe957SKim Phillips 	im->sysconf.ddrlaw[0].bar = (CFG_DDR_SDRAM_BASE >> 12) & 0xfffff;
66*e58fe957SKim Phillips 
67*e58fe957SKim Phillips 	/* Only one CS0 for DDR */
68*e58fe957SKim Phillips 	im->ddr.csbnds[0].csbnds = 0x0000000f;
69*e58fe957SKim Phillips 	im->ddr.cs_config[0] = CFG_DDR_CONFIG;
70*e58fe957SKim Phillips 
71*e58fe957SKim Phillips 	debug("cs0_bnds = 0x%08x\n", im->ddr.csbnds[0].csbnds);
72*e58fe957SKim Phillips 	debug("cs0_config = 0x%08x\n", im->ddr.cs_config[0]);
73*e58fe957SKim Phillips 
74*e58fe957SKim Phillips 	debug("DDR:bar=0x%08x\n", im->sysconf.ddrlaw[0].bar);
75*e58fe957SKim Phillips 	debug("DDR:ar=0x%08x\n", im->sysconf.ddrlaw[0].ar);
76*e58fe957SKim Phillips 
77*e58fe957SKim Phillips 	im->ddr.timing_cfg_1 = CFG_DDR_TIMING_1;
78*e58fe957SKim Phillips 	im->ddr.timing_cfg_2 = CFG_DDR_TIMING_2;/* Was "2 << TIMING_CFG2_WR_DATA_DELAY_SHIFT" */
79*e58fe957SKim Phillips 	im->ddr.sdram_cfg = SDRAM_CFG_SREN | SDRAM_CFG_SDRAM_TYPE_DDR1;
80*e58fe957SKim Phillips 	im->ddr.sdram_mode =
81*e58fe957SKim Phillips 	    (0x0000 << SDRAM_MODE_ESD_SHIFT) | (0x0032 << SDRAM_MODE_SD_SHIFT);
82*e58fe957SKim Phillips 	im->ddr.sdram_interval =
83*e58fe957SKim Phillips 	    (0x0410 << SDRAM_INTERVAL_REFINT_SHIFT) | (0x0100 <<
84*e58fe957SKim Phillips 						       SDRAM_INTERVAL_BSTOPRE_SHIFT);
85*e58fe957SKim Phillips 	im->ddr.sdram_clk_cntl = CFG_DDR_SDRAM_CLK_CNTL;
86*e58fe957SKim Phillips 
87*e58fe957SKim Phillips 	udelay(200);
88*e58fe957SKim Phillips 
89*e58fe957SKim Phillips 	im->ddr.sdram_cfg |= SDRAM_CFG_MEM_EN;
90*e58fe957SKim Phillips 
91*e58fe957SKim Phillips 	debug("DDR:timing_cfg_1=0x%08x\n", im->ddr.timing_cfg_1);
92*e58fe957SKim Phillips 	debug("DDR:timing_cfg_2=0x%08x\n", im->ddr.timing_cfg_2);
93*e58fe957SKim Phillips 	debug("DDR:sdram_mode=0x%08x\n", im->ddr.sdram_mode);
94*e58fe957SKim Phillips 	debug("DDR:sdram_interval=0x%08x\n", im->ddr.sdram_interval);
95*e58fe957SKim Phillips 	debug("DDR:sdram_cfg=0x%08x\n", im->ddr.sdram_cfg);
96*e58fe957SKim Phillips 
97*e58fe957SKim Phillips 	return CFG_DDR_SIZE;
98*e58fe957SKim Phillips }
99*e58fe957SKim Phillips #endif
100*e58fe957SKim Phillips 
101*e58fe957SKim Phillips #ifdef CONFIG_PCI
102*e58fe957SKim Phillips /*
103*e58fe957SKim Phillips  * Initialize PCI Devices, report devices found
104*e58fe957SKim Phillips  */
105*e58fe957SKim Phillips #ifndef CONFIG_PCI_PNP
106*e58fe957SKim Phillips static struct pci_config_table pci_mpc83xxmitx_config_table[] = {
107*e58fe957SKim Phillips 	{
108*e58fe957SKim Phillips 	 PCI_ANY_ID,
109*e58fe957SKim Phillips 	 PCI_ANY_ID,
110*e58fe957SKim Phillips 	 PCI_ANY_ID,
111*e58fe957SKim Phillips 	 PCI_ANY_ID,
112*e58fe957SKim Phillips 	 0x0f,
113*e58fe957SKim Phillips 	 PCI_ANY_ID,
114*e58fe957SKim Phillips 	 pci_cfgfunc_config_device,
115*e58fe957SKim Phillips 	 {
116*e58fe957SKim Phillips 	  PCI_ENET0_IOADDR,
117*e58fe957SKim Phillips 	  PCI_ENET0_MEMADDR,
118*e58fe957SKim Phillips 	  PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER}
119*e58fe957SKim Phillips 	 },
120*e58fe957SKim Phillips 	{}
121*e58fe957SKim Phillips }
122*e58fe957SKim Phillips #endif
123*e58fe957SKim Phillips 
124*e58fe957SKim Phillips volatile static struct pci_controller hose[] = {
125*e58fe957SKim Phillips 	{
126*e58fe957SKim Phillips #ifndef CONFIG_PCI_PNP
127*e58fe957SKim Phillips 	      config_table:pci_mpc83xxmitx_config_table,
128*e58fe957SKim Phillips #endif
129*e58fe957SKim Phillips 	 },
130*e58fe957SKim Phillips 	{
131*e58fe957SKim Phillips #ifndef CONFIG_PCI_PNP
132*e58fe957SKim Phillips 	      config_table:pci_mpc83xxmitx_config_table,
133*e58fe957SKim Phillips #endif
134*e58fe957SKim Phillips 	 }
135*e58fe957SKim Phillips };
136*e58fe957SKim Phillips #endif				/* CONFIG_PCI */
137*e58fe957SKim Phillips 
138*e58fe957SKim Phillips long int initdram(int board_type)
139*e58fe957SKim Phillips {
140*e58fe957SKim Phillips 	volatile immap_t *im = (immap_t *) CFG_IMMR;
141*e58fe957SKim Phillips 	u32 msize = 0;
142*e58fe957SKim Phillips #ifdef CONFIG_DDR_ECC
143*e58fe957SKim Phillips 	volatile ddr83xx_t *ddr = &im->ddr;
144*e58fe957SKim Phillips #endif
145*e58fe957SKim Phillips 
146*e58fe957SKim Phillips 	if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32) im)
147*e58fe957SKim Phillips 		return -1;
148*e58fe957SKim Phillips 
149*e58fe957SKim Phillips 	/* DDR SDRAM - Main SODIMM */
150*e58fe957SKim Phillips 	im->sysconf.ddrlaw[0].bar = CFG_DDR_BASE & LAWBAR_BAR;
151*e58fe957SKim Phillips #ifdef CONFIG_SPD_EEPROM
152*e58fe957SKim Phillips 	msize = spd_sdram();
153*e58fe957SKim Phillips #else
154*e58fe957SKim Phillips 	msize = fixed_sdram();
155*e58fe957SKim Phillips #endif
156*e58fe957SKim Phillips 
157*e58fe957SKim Phillips #ifdef CONFIG_DDR_ECC
158*e58fe957SKim Phillips 	if (ddr->sdram_cfg & SDRAM_CFG_ECC_EN)
159*e58fe957SKim Phillips 		/* Unlike every other board, on the 83xx spd_sdram() returns
160*e58fe957SKim Phillips 		   megabytes instead of just bytes.  That's why we need to
161*e58fe957SKim Phillips 		   multiple by 1MB when calling ddr_enable_ecc(). */
162*e58fe957SKim Phillips 		ddr_enable_ecc(msize * 1048576);
163*e58fe957SKim Phillips #endif
164*e58fe957SKim Phillips 
165*e58fe957SKim Phillips 	/* return total bus RAM size(bytes) */
166*e58fe957SKim Phillips 	return msize * 1024 * 1024;
167*e58fe957SKim Phillips }
168*e58fe957SKim Phillips 
169*e58fe957SKim Phillips int checkboard(void)
170*e58fe957SKim Phillips {
171*e58fe957SKim Phillips #ifdef CONFIG_MPC8349ITX
172*e58fe957SKim Phillips 	puts("Board: Freescale MPC8349E-mITX\n");
173*e58fe957SKim Phillips #else
174*e58fe957SKim Phillips 	puts("Board: Freescale MPC8349E-mITX-GP\n");
175*e58fe957SKim Phillips #endif
176*e58fe957SKim Phillips 
177*e58fe957SKim Phillips 	return 0;
178*e58fe957SKim Phillips }
179*e58fe957SKim Phillips 
180*e58fe957SKim Phillips /*
181*e58fe957SKim Phillips  * Implement a work-around for a hardware problem with compact
182*e58fe957SKim Phillips  * flash.
183*e58fe957SKim Phillips  *
184*e58fe957SKim Phillips  * Program the UPM if compact flash is enabled.
185*e58fe957SKim Phillips  */
186*e58fe957SKim Phillips int misc_init_f(void)
187*e58fe957SKim Phillips {
188*e58fe957SKim Phillips #ifdef CONFIG_VSC7385
189*e58fe957SKim Phillips 	volatile u32 *vsc7385_cpuctrl;
190*e58fe957SKim Phillips 
191*e58fe957SKim Phillips 	/* 0x1c0c0 is the VSC7385 CPU Control (CPUCTRL) Register.  The power up
192*e58fe957SKim Phillips 	   default of VSC7385 L1_IRQ and L2_IRQ requests are active high.  That
193*e58fe957SKim Phillips 	   means it is 0 when the IRQ is not active.  This makes the wire-AND
194*e58fe957SKim Phillips 	   logic always assert IRQ7 to CPU even if there is no request from the
195*e58fe957SKim Phillips 	   switch.  Since the compact flash and the switch share the same IRQ,
196*e58fe957SKim Phillips 	   the Linux kernel will think that the compact flash is requesting irq
197*e58fe957SKim Phillips 	   and get stuck when it tries to clear the IRQ.  Thus we need to set
198*e58fe957SKim Phillips 	   the L2_IRQ0 and L2_IRQ1 to active low.
199*e58fe957SKim Phillips 
200*e58fe957SKim Phillips 	   The following code sets the L1_IRQ and L2_IRQ polarity to active low.
201*e58fe957SKim Phillips 	   Without this code, compact flash will not work in Linux because
202*e58fe957SKim Phillips 	   unlike U-Boot, Linux uses the IRQ, so this code is necessary if we
203*e58fe957SKim Phillips 	   don't enable compact flash for U-Boot.
204*e58fe957SKim Phillips 	 */
205*e58fe957SKim Phillips 
206*e58fe957SKim Phillips 	vsc7385_cpuctrl = (volatile u32 *)(CFG_VSC7385_BASE + 0x1c0c0);
207*e58fe957SKim Phillips 	*vsc7385_cpuctrl |= 0x0c;
208*e58fe957SKim Phillips #endif
209*e58fe957SKim Phillips 
210*e58fe957SKim Phillips #ifdef CONFIG_COMPACT_FLASH
211*e58fe957SKim Phillips 	/* UPM Table Configuration Code */
212*e58fe957SKim Phillips 	static uint UPMATable[] = {
213*e58fe957SKim Phillips 		0xcffffc00, 0x0fffff00, 0x0fafff00, 0x0fafff00,
214*e58fe957SKim Phillips 		0x0faffd00, 0x0faffc04, 0x0ffffc00, 0x3ffffc01,
215*e58fe957SKim Phillips 		0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
216*e58fe957SKim Phillips 		0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
217*e58fe957SKim Phillips 		0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfff7fc00,
218*e58fe957SKim Phillips 		0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
219*e58fe957SKim Phillips 		0xcffffc00, 0x0fffff00, 0x0ff3ff00, 0x0ff3ff00,
220*e58fe957SKim Phillips 		0x0ff3fe00, 0x0ffffc00, 0x3ffffc05, 0xfffffc00,
221*e58fe957SKim Phillips 		0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
222*e58fe957SKim Phillips 		0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
223*e58fe957SKim Phillips 		0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
224*e58fe957SKim Phillips 		0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
225*e58fe957SKim Phillips 		0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
226*e58fe957SKim Phillips 		0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00,
227*e58fe957SKim Phillips 		0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01,
228*e58fe957SKim Phillips 		0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01
229*e58fe957SKim Phillips 	};
230*e58fe957SKim Phillips 	volatile immap_t *immap = (immap_t *) CFG_IMMR;
231*e58fe957SKim Phillips 	volatile lbus83xx_t *lbus = &immap->lbus;
232*e58fe957SKim Phillips 
233*e58fe957SKim Phillips 	lbus->bank[3].br = CFG_BR3_PRELIM;
234*e58fe957SKim Phillips 	lbus->bank[3].or = CFG_OR3_PRELIM;
235*e58fe957SKim Phillips 
236*e58fe957SKim Phillips 	/* Program the MAMR. RFEN=0, OP=00, UWPL=1, AM=000, DS=01, G0CL=000,
237*e58fe957SKim Phillips 	   GPL4=0, RLF=0001, WLF=0001, TLF=0001, MAD=000000
238*e58fe957SKim Phillips 	 */
239*e58fe957SKim Phillips 	lbus->mamr = 0x08404440;
240*e58fe957SKim Phillips 
241*e58fe957SKim Phillips 	upmconfig(0, UPMATable, sizeof(UPMATable) / sizeof(UPMATable[0]));
242*e58fe957SKim Phillips 
243*e58fe957SKim Phillips 	puts("UPMA:  Configured for compact flash\n");
244*e58fe957SKim Phillips #endif
245*e58fe957SKim Phillips 
246*e58fe957SKim Phillips 	return 0;
247*e58fe957SKim Phillips }
248*e58fe957SKim Phillips 
249*e58fe957SKim Phillips /*
250*e58fe957SKim Phillips  * Make sure the EEPROM has the HRCW correctly programmed.
251*e58fe957SKim Phillips  * Make sure the RTC is correctly programmed.
252*e58fe957SKim Phillips  *
253*e58fe957SKim Phillips  * The MPC8349E-mITX can be configured to load the HRCW from
254*e58fe957SKim Phillips  * EEPROM instead of flash.  This is controlled via jumpers
255*e58fe957SKim Phillips  * LGPL0, 1, and 3.  Normally, these jumpers are set to 000 (all
256*e58fe957SKim Phillips  * jumpered), but if they're set to 001 or 010, then the HRCW is
257*e58fe957SKim Phillips  * read from the "I2C EEPROM".
258*e58fe957SKim Phillips  *
259*e58fe957SKim Phillips  * This function makes sure that the I2C EEPROM is programmed
260*e58fe957SKim Phillips  * correctly.
261*e58fe957SKim Phillips  */
262*e58fe957SKim Phillips int misc_init_r(void)
263*e58fe957SKim Phillips {
264*e58fe957SKim Phillips 	int rc = 0;
265*e58fe957SKim Phillips 
266*e58fe957SKim Phillips #ifdef CONFIG_HARD_I2C
267*e58fe957SKim Phillips 
268*e58fe957SKim Phillips 	unsigned int orig_bus = i2c_get_bus_num();
269*e58fe957SKim Phillips 	u8 i2c_data;
270*e58fe957SKim Phillips 
271*e58fe957SKim Phillips #ifdef CFG_I2C_RTC_ADDR
272*e58fe957SKim Phillips 	u8 ds1339_data[17];
273*e58fe957SKim Phillips #endif
274*e58fe957SKim Phillips 
275*e58fe957SKim Phillips #ifdef CFG_I2C_EEPROM_ADDR
276*e58fe957SKim Phillips 	static u8 eeprom_data[] =	/* HRCW data */
277*e58fe957SKim Phillips 	{
278*e58fe957SKim Phillips 		0xAA, 0x55, 0xAA,       /* Preamble */
279*e58fe957SKim Phillips 		0x7C, 		        /* ACS=0, BYTE_EN=1111, CONT=1 */
280*e58fe957SKim Phillips 		0x02, 0x40, 	        /* RCWL ADDR=0x0_0900 */
281*e58fe957SKim Phillips 		(CFG_HRCW_LOW >> 24) & 0xFF,
282*e58fe957SKim Phillips 		(CFG_HRCW_LOW >> 16) & 0xFF,
283*e58fe957SKim Phillips 		(CFG_HRCW_LOW >> 8) & 0xFF,
284*e58fe957SKim Phillips 		CFG_HRCW_LOW & 0xFF,
285*e58fe957SKim Phillips 		0x7C, 		        /* ACS=0, BYTE_EN=1111, CONT=1 */
286*e58fe957SKim Phillips 		0x02, 0x41,	        /* RCWH ADDR=0x0_0904 */
287*e58fe957SKim Phillips 		(CFG_HRCW_HIGH >> 24) & 0xFF,
288*e58fe957SKim Phillips 		(CFG_HRCW_HIGH >> 16) & 0xFF,
289*e58fe957SKim Phillips 		(CFG_HRCW_HIGH >> 8) & 0xFF,
290*e58fe957SKim Phillips 		CFG_HRCW_HIGH & 0xFF
291*e58fe957SKim Phillips 	};
292*e58fe957SKim Phillips 
293*e58fe957SKim Phillips 	u8 data[sizeof(eeprom_data)];
294*e58fe957SKim Phillips #endif
295*e58fe957SKim Phillips 
296*e58fe957SKim Phillips 	printf("Board revision: ");
297*e58fe957SKim Phillips 	i2c_set_bus_num(1);
298*e58fe957SKim Phillips 	if (i2c_read(CFG_I2C_8574A_ADDR2, 0, 0, &i2c_data, sizeof(i2c_data)) == 0)
299*e58fe957SKim Phillips 		printf("%u.%u (PCF8475A)\n", (i2c_data & 0x02) >> 1, i2c_data & 0x01);
300*e58fe957SKim Phillips 	else if (i2c_read(CFG_I2C_8574_ADDR2, 0, 0, &i2c_data, sizeof(i2c_data)) == 0)
301*e58fe957SKim Phillips 		printf("%u.%u (PCF8475)\n",  (i2c_data & 0x02) >> 1, i2c_data & 0x01);
302*e58fe957SKim Phillips 	else {
303*e58fe957SKim Phillips 		printf("Unknown\n");
304*e58fe957SKim Phillips 		rc = 1;
305*e58fe957SKim Phillips 	}
306*e58fe957SKim Phillips 
307*e58fe957SKim Phillips #ifdef CFG_I2C_EEPROM_ADDR
308*e58fe957SKim Phillips 	i2c_set_bus_num(0);
309*e58fe957SKim Phillips 
310*e58fe957SKim Phillips 	if (i2c_read(CFG_I2C_EEPROM_ADDR, 0, 2, data, sizeof(data)) == 0) {
311*e58fe957SKim Phillips 		if (memcmp(data, eeprom_data, sizeof(data)) != 0) {
312*e58fe957SKim Phillips 			if (i2c_write
313*e58fe957SKim Phillips 			    (CFG_I2C_EEPROM_ADDR, 0, 2, eeprom_data,
314*e58fe957SKim Phillips 			     sizeof(eeprom_data)) != 0) {
315*e58fe957SKim Phillips 				puts("Failure writing the HRCW to EEPROM via I2C.\n");
316*e58fe957SKim Phillips 				rc = 1;
317*e58fe957SKim Phillips 			}
318*e58fe957SKim Phillips 		}
319*e58fe957SKim Phillips 	} else {
320*e58fe957SKim Phillips 		puts("Failure reading the HRCW from EEPROM via I2C.\n");
321*e58fe957SKim Phillips 		rc = 1;
322*e58fe957SKim Phillips 	}
323*e58fe957SKim Phillips #endif
324*e58fe957SKim Phillips 
325*e58fe957SKim Phillips #ifdef CFG_I2C_RTC_ADDR
326*e58fe957SKim Phillips 	i2c_set_bus_num(1);
327*e58fe957SKim Phillips 
328*e58fe957SKim Phillips 	if (i2c_read(CFG_I2C_RTC_ADDR, 0, 1, ds1339_data, sizeof(ds1339_data))
329*e58fe957SKim Phillips 	    == 0) {
330*e58fe957SKim Phillips 
331*e58fe957SKim Phillips 		/* Work-around for MPC8349E-mITX bug #13601.
332*e58fe957SKim Phillips 		   If the RTC does not contain valid register values, the DS1339
333*e58fe957SKim Phillips 		   Linux driver will not work.
334*e58fe957SKim Phillips 		 */
335*e58fe957SKim Phillips 
336*e58fe957SKim Phillips 		/* Make sure status register bits 6-2 are zero */
337*e58fe957SKim Phillips 		ds1339_data[0x0f] &= ~0x7c;
338*e58fe957SKim Phillips 
339*e58fe957SKim Phillips 		/* Check for a valid day register value */
340*e58fe957SKim Phillips 		ds1339_data[0x03] &= ~0xf8;
341*e58fe957SKim Phillips 		if (ds1339_data[0x03] == 0) {
342*e58fe957SKim Phillips 			ds1339_data[0x03] = 1;
343*e58fe957SKim Phillips 		}
344*e58fe957SKim Phillips 
345*e58fe957SKim Phillips 		/* Check for a valid date register value */
346*e58fe957SKim Phillips 		ds1339_data[0x04] &= ~0xc0;
347*e58fe957SKim Phillips 		if ((ds1339_data[0x04] == 0) ||
348*e58fe957SKim Phillips 		    ((ds1339_data[0x04] & 0x0f) > 9) ||
349*e58fe957SKim Phillips 		    (ds1339_data[0x04] >= 0x32)) {
350*e58fe957SKim Phillips 			ds1339_data[0x04] = 1;
351*e58fe957SKim Phillips 		}
352*e58fe957SKim Phillips 
353*e58fe957SKim Phillips 		/* Check for a valid month register value */
354*e58fe957SKim Phillips 		ds1339_data[0x05] &= ~0x60;
355*e58fe957SKim Phillips 
356*e58fe957SKim Phillips 		if ((ds1339_data[0x05] == 0) ||
357*e58fe957SKim Phillips 		    ((ds1339_data[0x05] & 0x0f) > 9) ||
358*e58fe957SKim Phillips 		    ((ds1339_data[0x05] >= 0x13)
359*e58fe957SKim Phillips 		     && (ds1339_data[0x05] <= 0x19))) {
360*e58fe957SKim Phillips 			ds1339_data[0x05] = 1;
361*e58fe957SKim Phillips 		}
362*e58fe957SKim Phillips 
363*e58fe957SKim Phillips 		/* Enable Oscillator and rate select */
364*e58fe957SKim Phillips 		ds1339_data[0x0e] = 0x1c;
365*e58fe957SKim Phillips 
366*e58fe957SKim Phillips 		/* Work-around for MPC8349E-mITX bug #13330.
367*e58fe957SKim Phillips 		   Ensure that the RTC control register contains the value 0x1c.
368*e58fe957SKim Phillips 		   This affects SATA performance.
369*e58fe957SKim Phillips 		 */
370*e58fe957SKim Phillips 
371*e58fe957SKim Phillips 		if (i2c_write
372*e58fe957SKim Phillips 		    (CFG_I2C_RTC_ADDR, 0, 1, ds1339_data,
373*e58fe957SKim Phillips 		     sizeof(ds1339_data))) {
374*e58fe957SKim Phillips 			puts("Failure writing to the RTC via I2C.\n");
375*e58fe957SKim Phillips 			rc = 1;
376*e58fe957SKim Phillips 		}
377*e58fe957SKim Phillips 	} else {
378*e58fe957SKim Phillips 		puts("Failure reading from the RTC via I2C.\n");
379*e58fe957SKim Phillips 		rc = 1;
380*e58fe957SKim Phillips 	}
381*e58fe957SKim Phillips #endif
382*e58fe957SKim Phillips 
383*e58fe957SKim Phillips 	i2c_set_bus_num(orig_bus);
384*e58fe957SKim Phillips #endif
385*e58fe957SKim Phillips 
386*e58fe957SKim Phillips 	return rc;
387*e58fe957SKim Phillips }
388*e58fe957SKim Phillips 
389*e58fe957SKim Phillips #if defined(CONFIG_OF_BOARD_SETUP)
390*e58fe957SKim Phillips void ft_board_setup(void *blob, bd_t *bd)
391*e58fe957SKim Phillips {
392*e58fe957SKim Phillips #if defined(CONFIG_OF_FLAT_TREE)
393*e58fe957SKim Phillips 	u32 *p;
394*e58fe957SKim Phillips 	int len;
395*e58fe957SKim Phillips 
396*e58fe957SKim Phillips 	p = ft_get_prop(blob, "/memory/reg", &len);
397*e58fe957SKim Phillips 	if (p != NULL) {
398*e58fe957SKim Phillips 		*p++ = cpu_to_be32(bd->bi_memstart);
399*e58fe957SKim Phillips 		*p = cpu_to_be32(bd->bi_memsize);
400*e58fe957SKim Phillips 	}
401*e58fe957SKim Phillips #endif
402*e58fe957SKim Phillips 	ft_cpu_setup(blob, bd);
403*e58fe957SKim Phillips #ifdef CONFIG_PCI
404*e58fe957SKim Phillips 	ft_pci_setup(blob, bd);
405*e58fe957SKim Phillips #endif
406*e58fe957SKim Phillips }
407*e58fe957SKim Phillips #endif
408