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