]>
Commit | Line | Data |
---|---|---|
5e0de0e2 AS |
1 | /* |
2 | * (C) Copyright 2003 | |
3 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | |
4 | * | |
5 | * (C) Copyright 2004 | |
6 | * Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com. | |
7 | * | |
8 | * (C) Copyright 2005-2007 | |
9 | * Andre Schwarz, Matrix Vision GmbH, andre.schwarz@matrix-vision.de | |
10 | * | |
11 | * See file CREDITS for list of people who contributed to this | |
12 | * project. | |
13 | * | |
14 | * This program is free software; you can redistribute it and/or | |
15 | * modify it under the terms of the GNU General Public License as | |
16 | * published by the Free Software Foundation; either version 2 of | |
17 | * the License, or (at your option) any later version. | |
18 | * | |
19 | * This program is distributed in the hope that it will be useful, | |
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
22 | * GNU General Public License for more details. | |
23 | * | |
24 | * You should have received a copy of the GNU General Public License | |
25 | * along with this program; if not, write to the Free Software | |
26 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
27 | * MA 02111-1307 USA | |
28 | */ | |
29 | ||
30 | #include <common.h> | |
31 | #include <mpc5xxx.h> | |
32 | #include <malloc.h> | |
33 | #include <pci.h> | |
34 | #include <i2c.h> | |
f2302d44 | 35 | #include <fpga.h> |
5e0de0e2 AS |
36 | #include <environment.h> |
37 | #include <fdt_support.h> | |
e1d7480b | 38 | #include <netdev.h> |
5e0de0e2 AS |
39 | #include <asm/io.h> |
40 | #include "fpga.h" | |
41 | #include "mvbc_p.h" | |
42 | ||
43 | #define SDRAM_MODE 0x00CD0000 | |
44 | #define SDRAM_CONTROL 0x504F0000 | |
45 | #define SDRAM_CONFIG1 0xD2322800 | |
46 | #define SDRAM_CONFIG2 0x8AD70000 | |
47 | ||
48 | DECLARE_GLOBAL_DATA_PTR; | |
49 | ||
50 | static void sdram_start (int hi_addr) | |
51 | { | |
52 | long hi_bit = hi_addr ? 0x01000000 : 0; | |
53 | ||
54 | /* unlock mode register */ | |
55 | out_be32((u32*)MPC5XXX_SDRAM_CTRL, SDRAM_CONTROL | 0x80000000 | hi_bit); | |
56 | ||
57 | /* precharge all banks */ | |
58 | out_be32((u32*)MPC5XXX_SDRAM_CTRL, SDRAM_CONTROL | 0x80000002 | hi_bit); | |
59 | ||
60 | /* precharge all banks */ | |
61 | out_be32((u32*)MPC5XXX_SDRAM_CTRL, SDRAM_CONTROL | 0x80000002 | hi_bit); | |
62 | ||
63 | /* auto refresh */ | |
64 | out_be32((u32*)MPC5XXX_SDRAM_CTRL, SDRAM_CONTROL | 0x80000004 | hi_bit); | |
65 | ||
66 | /* set mode register */ | |
67 | out_be32((u32*)MPC5XXX_SDRAM_MODE, SDRAM_MODE); | |
68 | ||
69 | /* normal operation */ | |
70 | out_be32((u32*)MPC5XXX_SDRAM_CTRL, SDRAM_CONTROL | hi_bit); | |
71 | } | |
72 | ||
73 | phys_addr_t initdram (int board_type) | |
74 | { | |
75 | ulong dramsize = 0; | |
76 | ulong test1, | |
77 | test2; | |
78 | ||
79 | /* setup SDRAM chip selects */ | |
80 | out_be32((u32*)MPC5XXX_SDRAM_CS0CFG, 0x0000001e); | |
81 | ||
82 | /* setup config registers */ | |
83 | out_be32((u32*)MPC5XXX_SDRAM_CONFIG1, SDRAM_CONFIG1); | |
84 | out_be32((u32*)MPC5XXX_SDRAM_CONFIG2, SDRAM_CONFIG2); | |
85 | ||
86 | /* find RAM size using SDRAM CS0 only */ | |
87 | sdram_start(0); | |
6d0f6bcf | 88 | test1 = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, 0x80000000); |
5e0de0e2 | 89 | sdram_start(1); |
6d0f6bcf | 90 | test2 = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, 0x80000000); |
5e0de0e2 AS |
91 | if (test1 > test2) { |
92 | sdram_start(0); | |
93 | dramsize = test1; | |
94 | } else | |
95 | dramsize = test2; | |
96 | ||
97 | if (dramsize < (1 << 20)) | |
98 | dramsize = 0; | |
99 | ||
100 | if (dramsize > 0) | |
101 | out_be32((u32*)MPC5XXX_SDRAM_CS0CFG, 0x13 + | |
102 | __builtin_ffs(dramsize >> 20) - 1); | |
103 | else | |
104 | out_be32((u32*)MPC5XXX_SDRAM_CS0CFG, 0); | |
105 | ||
106 | return dramsize; | |
107 | } | |
108 | ||
109 | void mvbc_init_gpio(void) | |
110 | { | |
111 | struct mpc5xxx_gpio *gpio = (struct mpc5xxx_gpio*)MPC5XXX_GPIO; | |
112 | ||
113 | printf("Ports : 0x%08x\n", gpio->port_config); | |
f2302d44 | 114 | printf("PORCFG: 0x%08lx\n", *(vu_long*)MPC5XXX_CDM_PORCFG); |
5e0de0e2 AS |
115 | |
116 | out_be32(&gpio->simple_ddr, SIMPLE_DDR); | |
117 | out_be32(&gpio->simple_dvo, SIMPLE_DVO); | |
118 | out_be32(&gpio->simple_ode, SIMPLE_ODE); | |
119 | out_be32(&gpio->simple_gpioe, SIMPLE_GPIOEN); | |
120 | ||
a928d0df AS |
121 | out_8(&gpio->sint_ode, SINT_ODE); |
122 | out_8(&gpio->sint_ddr, SINT_DDR); | |
123 | out_8(&gpio->sint_dvo, SINT_DVO); | |
124 | out_8(&gpio->sint_inten, SINT_INTEN); | |
125 | out_be16(&gpio->sint_itype, SINT_ITYPE); | |
126 | out_8(&gpio->sint_gpioe, SINT_GPIOEN); | |
5e0de0e2 AS |
127 | |
128 | out_8((u8*)MPC5XXX_WU_GPIO_ODE, WKUP_ODE); | |
129 | out_8((u8*)MPC5XXX_WU_GPIO_DIR, WKUP_DIR); | |
130 | out_8((u8*)MPC5XXX_WU_GPIO_DATA_O, WKUP_DO); | |
131 | out_8((u8*)MPC5XXX_WU_GPIO_ENABLE, WKUP_EN); | |
132 | ||
133 | printf("simple_gpioe: 0x%08x\n", gpio->simple_gpioe); | |
134 | printf("sint_gpioe : 0x%08x\n", gpio->sint_gpioe); | |
135 | } | |
136 | ||
137 | void reset_environment(void) | |
138 | { | |
139 | char *s, sernr[64]; | |
140 | ||
141 | printf("\n*** RESET ENVIRONMENT ***\n"); | |
142 | memset(sernr, 0, sizeof(sernr)); | |
143 | s = getenv("serial#"); | |
144 | if (s) { | |
145 | printf("found serial# : %s\n", s); | |
146 | strncpy(sernr, s, 64); | |
147 | } | |
148 | gd->env_valid = 0; | |
149 | env_relocate(); | |
150 | if (s) | |
151 | setenv("serial#", sernr); | |
152 | } | |
153 | ||
154 | int misc_init_r(void) | |
155 | { | |
156 | char *s = getenv("reset_env"); | |
157 | ||
158 | if (!s) { | |
159 | if (in_8((u8*)MPC5XXX_WU_GPIO_DATA_I) & MPC5XXX_GPIO_WKUP_6) | |
160 | return 0; | |
161 | udelay(50000); | |
162 | if (in_8((u8*)MPC5XXX_WU_GPIO_DATA_I) & MPC5XXX_GPIO_WKUP_6) | |
163 | return 0; | |
164 | udelay(50000); | |
165 | if (in_8((u8*)MPC5XXX_WU_GPIO_DATA_I) & MPC5XXX_GPIO_WKUP_6) | |
166 | return 0; | |
167 | } | |
168 | printf(" === FACTORY RESET ===\n"); | |
169 | reset_environment(); | |
170 | saveenv(); | |
171 | ||
172 | return -1; | |
173 | } | |
174 | ||
175 | int checkboard(void) | |
176 | { | |
177 | mvbc_init_gpio(); | |
178 | printf("Board: Matrix Vision mvBlueCOUGAR-P\n"); | |
179 | ||
180 | return 0; | |
181 | } | |
182 | ||
183 | void flash_preinit(void) | |
184 | { | |
185 | /* | |
186 | * Now, when we are in RAM, enable flash write | |
187 | * access for detection process. | |
188 | * Note that CS_BOOT cannot be cleared when | |
189 | * executing in flash. | |
190 | */ | |
191 | clrbits_be32((u32*)MPC5XXX_BOOTCS_CFG, 0x1); | |
192 | } | |
193 | ||
194 | void flash_afterinit(ulong size) | |
195 | { | |
6d0f6bcf | 196 | out_be32((u32*)MPC5XXX_BOOTCS_START, START_REG(CONFIG_SYS_BOOTCS_START | |
5e0de0e2 | 197 | size)); |
6d0f6bcf | 198 | out_be32((u32*)MPC5XXX_CS0_START, START_REG(CONFIG_SYS_BOOTCS_START | |
5e0de0e2 | 199 | size)); |
6d0f6bcf | 200 | out_be32((u32*)MPC5XXX_BOOTCS_STOP, STOP_REG(CONFIG_SYS_BOOTCS_START | size, |
5e0de0e2 | 201 | size)); |
6d0f6bcf | 202 | out_be32((u32*)MPC5XXX_CS0_STOP, STOP_REG(CONFIG_SYS_BOOTCS_START | size, |
5e0de0e2 AS |
203 | size)); |
204 | } | |
205 | ||
206 | void pci_mvbc_fixup_irq(struct pci_controller *hose, pci_dev_t dev) | |
207 | { | |
208 | unsigned char line = 0xff; | |
209 | u32 base; | |
210 | ||
211 | if (PCI_BUS(dev) == 0) { | |
212 | switch (PCI_DEV (dev)) { | |
213 | case 0xa: /* FPGA */ | |
214 | line = 3; | |
215 | pci_hose_read_config_dword(hose, dev, PCI_BASE_ADDRESS_0, &base); | |
216 | printf("found FPA - enable arbitration\n"); | |
217 | writel(0x03, (u32*)(base + 0x80c0)); | |
218 | writel(0xf0, (u32*)(base + 0x8080)); | |
219 | break; | |
220 | case 0xb: /* LAN */ | |
221 | line = 2; | |
222 | break; | |
223 | case 0x1a: | |
224 | break; | |
225 | default: | |
226 | printf ("***pci_scan: illegal dev = 0x%08x\n", PCI_DEV (dev)); | |
227 | break; | |
228 | } | |
229 | pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, line); | |
230 | } | |
231 | } | |
232 | ||
233 | struct pci_controller hose = { | |
234 | fixup_irq:pci_mvbc_fixup_irq | |
235 | }; | |
236 | ||
237 | int mvbc_p_load_fpga(void) | |
238 | { | |
239 | size_t data_size = 0; | |
240 | void *fpga_data = NULL; | |
241 | char *datastr = getenv("fpgadata"); | |
242 | char *sizestr = getenv("fpgadatasize"); | |
243 | ||
244 | if (datastr) | |
245 | fpga_data = (void *)simple_strtoul(datastr, NULL, 16); | |
246 | if (sizestr) | |
247 | data_size = (size_t)simple_strtoul(sizestr, NULL, 16); | |
248 | ||
249 | return fpga_load(0, fpga_data, data_size); | |
250 | } | |
251 | ||
252 | extern void pci_mpc5xxx_init(struct pci_controller *); | |
253 | ||
254 | void pci_init_board(void) | |
255 | { | |
256 | char *s; | |
257 | int load_fpga = 1; | |
258 | ||
259 | mvbc_p_init_fpga(); | |
260 | s = getenv("skip_fpga"); | |
261 | if (s) { | |
262 | printf("found 'skip_fpga' -> FPGA _not_ loaded !\n"); | |
263 | load_fpga = 0; | |
264 | } | |
265 | if (load_fpga) { | |
266 | printf("loading FPGA ... "); | |
267 | mvbc_p_load_fpga(); | |
268 | printf("done\n"); | |
269 | } | |
270 | pci_mpc5xxx_init(&hose); | |
271 | } | |
272 | ||
273 | u8 *dhcp_vendorex_prep(u8 *e) | |
274 | { | |
275 | char *ptr; | |
276 | ||
277 | /* DHCP vendor-class-identifier = 60 */ | |
278 | if ((ptr = getenv("dhcp_vendor-class-identifier"))) { | |
279 | *e++ = 60; | |
280 | *e++ = strlen(ptr); | |
281 | while (*ptr) | |
282 | *e++ = *ptr++; | |
283 | } | |
284 | /* DHCP_CLIENT_IDENTIFIER = 61 */ | |
285 | if ((ptr = getenv("dhcp_client_id"))) { | |
286 | *e++ = 61; | |
287 | *e++ = strlen(ptr); | |
288 | while (*ptr) | |
289 | *e++ = *ptr++; | |
290 | } | |
291 | ||
292 | return e; | |
293 | } | |
294 | ||
295 | u8 *dhcp_vendorex_proc (u8 *popt) | |
296 | { | |
297 | return NULL; | |
298 | } | |
299 | ||
300 | void show_boot_progress(int val) | |
301 | { | |
302 | struct mpc5xxx_gpio *gpio = (struct mpc5xxx_gpio*)MPC5XXX_GPIO; | |
303 | ||
304 | switch(val) { | |
305 | case 0: /* FPGA ok */ | |
306 | setbits_be32(&gpio->simple_dvo, 0x80); | |
307 | break; | |
308 | case 1: | |
309 | setbits_be32(&gpio->simple_dvo, 0x40); | |
310 | break; | |
311 | case 12: | |
312 | setbits_be32(&gpio->simple_dvo, 0x20); | |
313 | break; | |
314 | case 15: | |
315 | setbits_be32(&gpio->simple_dvo, 0x10); | |
316 | break; | |
317 | default: | |
318 | break; | |
319 | } | |
320 | ||
321 | } | |
322 | ||
323 | void ft_board_setup(void *blob, bd_t *bd) | |
324 | { | |
325 | ft_cpu_setup(blob, bd); | |
326 | fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize); | |
327 | } | |
e1d7480b BW |
328 | |
329 | int board_eth_init(bd_t *bis) | |
330 | { | |
ad3381cf BW |
331 | cpu_eth_init(bis); /* Built in FEC comes first */ |
332 | return pci_eth_init(bis); | |
e1d7480b | 333 | } |