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