[uboot-lantiq] add support for arv4518 and arv752DWP22 boards
[openwrt/svn-archive/archive.git] / package / uboot-lantiq / files / board / arcadyan / arv4518 / arv4518.c
1 /*
2 * (C) Copyright 2003
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
5 * (C) Copyright 2010
6 * Thomas Langer, Ralph Hempel
7 *
8 * See file CREDITS for list of people who contributed to this
9 * project.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of
14 * the License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24 * MA 02111-1307 USA
25 */
26
27 #include <common.h>
28 #include <command.h>
29 #include <netdev.h>
30 #include <miiphy.h>
31 #include <asm/addrspace.h>
32 #include <asm/danube.h>
33 #include <asm/reboot.h>
34 #include <asm/io.h>
35 #if defined(CONFIG_CMD_HTTPD)
36 #include <httpd.h>
37 #endif
38 #if defined(CONFIG_PCI)
39 #include <pci.h>
40 #endif
41
42 extern ulong ifx_get_ddr_hz(void);
43 extern ulong ifx_get_cpuclk(void);
44
45 /* IDs and registers of known external switches */
46 #define ID_RTL8306 0x5988
47 #define CONFIG_EXTRA_SWITCH 1
48 void _machine_restart(void)
49 {
50 *DANUBE_RCU_RST_REQ |=1<<30;
51 }
52
53 #ifdef CONFIG_SYS_RAMBOOT
54 phys_size_t initdram(int board_type)
55 {
56 return get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, CONFIG_SYS_MAX_RAM);
57 }
58 #elif defined(CONFIG_USE_DDR_RAM)
59 phys_size_t initdram(int board_type)
60 {
61 return (CONFIG_SYS_MAX_RAM);
62 }
63 #else
64
65 static ulong max_sdram_size(void) /* per Chip Select */
66 {
67 /* The only supported SDRAM data width is 16bit.
68 */
69 #define CFG_DW 4
70
71 /* The only supported number of SDRAM banks is 4.
72 */
73 #define CFG_NB 4
74
75 ulong cfgpb0 = *DANUBE_SDRAM_MC_CFGPB0;
76 int cols = cfgpb0 & 0xF;
77 int rows = (cfgpb0 & 0xF0) >> 4;
78 ulong size = (1 << (rows + cols)) * CFG_DW * CFG_NB;
79
80 return size;
81 }
82
83 /*
84 * Check memory range for valid RAM. A simple memory test determines
85 * the actually available RAM size between addresses `base' and
86 * `base + maxsize'.
87 */
88
89 static long int dram_size(long int *base, long int maxsize)
90 {
91 volatile long int *addr;
92 ulong cnt, val;
93 ulong save[32]; /* to make test non-destructive */
94 unsigned char i = 0;
95
96 for (cnt = (maxsize / sizeof (long)) >> 1; cnt > 0; cnt >>= 1) {
97 addr = base + cnt; /* pointer arith! */
98
99 save[i++] = *addr;
100 *addr = ~cnt;
101 }
102
103 /* write 0 to base address */
104 addr = base;
105 save[i] = *addr;
106 *addr = 0;
107
108 /* check at base address */
109 if ((val = *addr) != 0) {
110 *addr = save[i];
111 return (0);
112 }
113
114 for (cnt = 1; cnt < maxsize / sizeof (long); cnt <<= 1) {
115 addr = base + cnt; /* pointer arith! */
116
117 val = *addr;
118 *addr = save[--i];
119
120 if (val != (~cnt)) {
121 return (cnt * sizeof (long));
122 }
123 }
124 return (maxsize);
125 }
126
127 phys_size_t initdram(int board_type)
128 {
129 int rows, cols, best_val = *DANUBE_SDRAM_MC_CFGPB0;
130 ulong size, max_size = 0;
131 ulong our_address;
132
133 /* load t9 into our_address */
134 asm volatile ("move %0, $25" : "=r" (our_address) :);
135
136 /* Can't probe for RAM size unless we are running from Flash.
137 * find out whether running from DRAM or Flash.
138 */
139 if (CPHYSADDR(our_address) < CPHYSADDR(PHYS_FLASH_1))
140 {
141 return max_sdram_size();
142 }
143
144 for (cols = 0x8; cols <= 0xC; cols++)
145 {
146 for (rows = 0xB; rows <= 0xD; rows++)
147 {
148 *DANUBE_SDRAM_MC_CFGPB0 = (0x14 << 8) |
149 (rows << 4) | cols;
150 size = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE,
151 max_sdram_size());
152
153 if (size > max_size)
154 {
155 best_val = *DANUBE_SDRAM_MC_CFGPB0;
156 max_size = size;
157 }
158 }
159 }
160
161 *DANUBE_SDRAM_MC_CFGPB0 = best_val;
162 return max_size;
163 }
164 #endif
165
166 int checkboard (void)
167 {
168 unsigned long chipid = *DANUBE_MPS_CHIPID;
169 int part_num;
170
171 puts ("Board: ");
172
173 part_num = DANUBE_MPS_CHIPID_PARTNUM_GET(chipid);
174 switch (part_num)
175 {
176 case 0x129:
177 case 0x12D:
178 case 0x12b:
179 puts("Danube/Twinpass/Vinax-VE ");
180 break;
181 default:
182 printf ("unknown, chip part number 0x%03X ", part_num);
183 break;
184 }
185 printf ("V1.%ld, ", DANUBE_MPS_CHIPID_VERSION_GET(chipid));
186
187 printf("DDR Speed %ld MHz, ", ifx_get_ddr_hz()/1000000);
188 printf("CPU Speed %ld MHz\n", ifx_get_cpuclk()/1000000);
189
190 return 0;
191 }
192
193 #ifdef CONFIG_SKIP_LOWLEVEL_INIT
194 int board_early_init_f(void)
195 {
196 #ifdef CONFIG_EBU_ADDSEL0
197 (*DANUBE_EBU_ADDSEL0) = CONFIG_EBU_ADDSEL0;
198 #endif
199 #ifdef CONFIG_EBU_ADDSEL1
200 (*DANUBE_EBU_ADDSEL1) = CONFIG_EBU_ADDSEL1;
201 #endif
202 #ifdef CONFIG_EBU_ADDSEL2
203 (*DANUBE_EBU_ADDSEL2) = CONFIG_EBU_ADDSEL2;
204 #endif
205 #ifdef CONFIG_EBU_ADDSEL3
206 (*DANUBE_EBU_ADDSEL3) = CONFIG_EBU_ADDSEL3;
207 #endif
208 #ifdef CONFIG_EBU_BUSCON0
209 (*DANUBE_EBU_BUSCON0) = CONFIG_EBU_BUSCON0;
210 #endif
211 #ifdef CONFIG_EBU_BUSCON1
212 (*DANUBE_EBU_BUSCON1) = CONFIG_EBU_BUSCON1;
213 #endif
214 #ifdef CONFIG_EBU_BUSCON2
215 (*DANUBE_EBU_BUSCON2) = CONFIG_EBU_BUSCON2;
216 #endif
217 #ifdef CONFIG_EBU_BUSCON3
218 (*DANUBE_EBU_BUSCON3) = CONFIG_EBU_BUSCON3;
219 #endif
220
221 return 0;
222 }
223 #endif /* CONFIG_SKIP_LOWLEVEL_INIT */
224
225
226 #ifdef CONFIG_EXTRA_SWITCH
227 static int external_switch_init(void)
228 {
229 unsigned short chipid;
230 static char * const name = "lq_cpe_eth";
231
232 /* earlier no valid response is available, at least on Twinpass & Tantos @ 111MHz, M4530 platform */
233 udelay(100000);
234
235 puts("\nsearching for rtl8306 switch ... ");
236 if (miiphy_read(name, 4, 30, &chipid) == 0) {
237 puts("s1\n");
238 if (chipid == ID_RTL8306) {
239 puts("found");
240 /* set led mode */
241 miiphy_write(name, 0, 19, 0xffff);
242 /* magic */
243 miiphy_write(name, 4, 22, 0x877f);
244 puts("\n");
245 return 0;
246 }
247 puts("failed\n");
248 }
249 puts("\nno known switch found ... \n");
250
251 return 0;
252 }
253 #endif /* CONFIG_EXTRA_SWITCH */
254
255 int board_eth_init(bd_t *bis)
256 {
257 #if defined(CONFIG_IFX_ETOP)
258 uchar enetaddr[6];
259 if (!eth_getenv_enetaddr("ethaddr", enetaddr))
260 eth_setenv_enetaddr("ethaddr", (uchar *)0xb03f0016);
261
262 *DANUBE_PMU_PWDCR &= 0xFFFFEFDF;
263 *DANUBE_PMU_PWDCR &=~(1<<DANUBE_PMU_DMA_SHIFT);/*enable DMA from PMU*/
264
265 if (lq_eth_initialize(bis))
266 return -1;
267
268 *DANUBE_RCU_RST_REQ |=1;
269 udelay(200000);
270 *DANUBE_RCU_RST_REQ &=(unsigned long)~1;
271 udelay(1000);
272
273 #ifdef CONFIG_EXTRA_SWITCH
274 if (external_switch_init()<0)
275 return -1;
276 #endif /* CONFIG_EXTRA_SWITCH */
277 #endif /* CONFIG_IFX_ETOP */
278
279 return 0;
280 }
281
282 #if defined(CONFIG_CMD_HTTPD)
283 int do_http_upgrade(const unsigned char *data, const ulong size)
284 {
285 char buf[128];
286
287 if(getenv ("ram_addr") == NULL)
288 return -1;
289 if(getenv ("kernel_addr") == NULL)
290 return -1;
291 /* check the image */
292 if(run_command("imi ${ram_addr}", 0) < 0) {
293 return -1;
294 }
295 /* write the image to the flash */
296 puts("http ugrade ...\n");
297 sprintf(buf, "era ${kernel_addr} +0x%lx; cp.b ${ram_addr} ${kernel_addr} 0x%lx", size, size);
298 return run_command(buf, 0);
299 }
300
301 int do_http_progress(const int state)
302 {
303 /* toggle LED's here */
304 switch(state) {
305 case HTTP_PROGRESS_START:
306 puts("http start\n");
307 break;
308 case HTTP_PROGRESS_TIMEOUT:
309 puts(".");
310 break;
311 case HTTP_PROGRESS_UPLOAD_READY:
312 puts("http upload ready\n");
313 break;
314 case HTTP_PROGRESS_UGRADE_READY:
315 puts("http ugrade ready\n");
316 break;
317 case HTTP_PROGRESS_UGRADE_FAILED:
318 puts("http ugrade failed\n");
319 break;
320 }
321 return 0;
322 }
323
324 unsigned long do_http_tmp_address(void)
325 {
326 char *s = getenv ("ram_addr");
327 if (s) {
328 ulong tmp = simple_strtoul (s, NULL, 16);
329 return tmp;
330 }
331 return 0 /*0x80a00000*/;
332 }
333
334 #endif