]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/bf537-stamp/bf537-stamp.c
Blackfin: bf537-stamp: rewrite MAC-in-flash handling
[karo-tx-uboot.git] / board / bf537-stamp / bf537-stamp.c
1 /*
2  * U-boot - main board file
3  *
4  * Copyright (c) 2005-2008 Analog Devices Inc.
5  *
6  * (C) Copyright 2000-2004
7  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
8  *
9  * See file CREDITS for list of people who contributed to this
10  * project.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License as
14  * published by the Free Software Foundation; either version 2 of
15  * the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
25  * MA 02110-1301 USA
26  */
27
28 #include <common.h>
29 #include <config.h>
30 #include <command.h>
31 #include <asm/blackfin.h>
32 #include <asm/net.h>
33 #include <net.h>
34 #include <asm/mach-common/bits/bootrom.h>
35 #include <netdev.h>
36
37 DECLARE_GLOBAL_DATA_PTR;
38
39 #define POST_WORD_ADDR 0xFF903FFC
40
41 int checkboard(void)
42 {
43         printf("Board: ADI BF537 stamp board\n");
44         printf("       Support: http://blackfin.uclinux.org/\n");
45         return 0;
46 }
47
48 #if defined(CONFIG_BFIN_IDE)
49
50 void cf_outb(unsigned char val, volatile unsigned char *addr)
51 {
52         *(addr) = val;
53         SSYNC();
54 }
55
56 unsigned char cf_inb(volatile unsigned char *addr)
57 {
58         volatile unsigned char c;
59
60         c = *(addr);
61         SSYNC();
62
63         return c;
64 }
65
66 void cf_insw(unsigned short *sect_buf, unsigned short *addr, int words)
67 {
68         int i;
69
70         for (i = 0; i < words; i++)
71                 *(sect_buf + i) = *(addr);
72         SSYNC();
73 }
74
75 void cf_outsw(unsigned short *addr, unsigned short *sect_buf, int words)
76 {
77         int i;
78
79         for (i = 0; i < words; i++)
80                 *(addr) = *(sect_buf + i);
81         SSYNC();
82 }
83 #endif                          /* CONFIG_BFIN_IDE */
84
85 phys_size_t initdram(int board_type)
86 {
87         gd->bd->bi_memstart = CONFIG_SYS_SDRAM_BASE;
88         gd->bd->bi_memsize = CONFIG_SYS_MAX_RAM_SIZE;
89         return gd->bd->bi_memsize;
90 }
91
92 void board_reset(void)
93 {
94         /* workaround for weak pull ups on ssel */
95         if (CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_SPI_MASTER) {
96                 bfin_write_PORTF_FER(bfin_read_PORTF_FER() & ~PF10);
97                 bfin_write_PORTFIO_SET(PF10);
98                 udelay(1);
99         }
100 }
101
102 #ifdef CONFIG_BFIN_MAC
103 static void board_init_enetaddr(uchar *mac_addr)
104 {
105 #ifdef CONFIG_SYS_NO_FLASH
106 # define USE_MAC_IN_FLASH 0
107 #else
108 # define USE_MAC_IN_FLASH 1
109 #endif
110         bool valid_mac = false;
111
112         if (USE_MAC_IN_FLASH) {
113                 /* we cram the MAC in the last flash sector */
114                 uchar *board_mac_addr = (uchar *)0x203F0000;
115                 if (is_valid_ether_addr(board_mac_addr)) {
116                         memcpy(mac_addr, board_mac_addr, 6);
117                         valid_mac = true;
118                 }
119         }
120
121         if (!valid_mac) {
122                 puts("Warning: Generating 'random' MAC address\n");
123                 bfin_gen_rand_mac(mac_addr);
124         }
125
126         eth_setenv_enetaddr("ethaddr", mac_addr);
127 }
128
129 int board_eth_init(bd_t *bis)
130 {
131         return bfin_EMAC_initialize(bis);
132 }
133 #endif
134
135 #if defined(CONFIG_MISC_INIT_R)
136 /* miscellaneous platform dependent initialisations */
137 int misc_init_r(void)
138 {
139 #ifdef CONFIG_BFIN_MAC
140         uchar enetaddr[6];
141         if (!eth_getenv_enetaddr("ethaddr", enetaddr))
142                 board_init_enetaddr(enetaddr);
143 #endif
144
145 #ifndef CONFIG_SYS_NO_FLASH
146         /* we use the last sector for the MAC address / POST LDR */
147         extern flash_info_t flash_info[];
148         flash_protect(FLAG_PROTECT_SET, 0x203F0000, 0x203FFFFF, &flash_info[0]);
149 #endif
150
151 #if defined(CONFIG_BFIN_IDE)
152 #if defined(CONFIG_BFIN_TRUE_IDE)
153         /* Enable ATASEL when in True IDE mode */
154         printf("Using CF True IDE Mode\n");
155         cf_outb(0, (unsigned char *)CONFIG_CF_ATASEL_ENA);
156         udelay(1000);
157 #elif defined(CONFIG_BFIN_CF_IDE)
158         /* Disable ATASEL when we're in Common Memory Mode */
159         printf("Using CF Common Memory Mode\n");
160         cf_outb(0, (unsigned char *)CONFIG_CF_ATASEL_DIS);
161         udelay(1000);
162 #elif defined(CONFIG_BFIN_HDD_IDE)
163         printf("Using HDD IDE Mode\n");
164 #endif
165         ide_init();
166 #endif                          /* CONFIG_BFIN_IDE */
167         return 0;
168 }
169 #endif                          /* CONFIG_MISC_INIT_R */
170
171 #ifdef CONFIG_POST
172 /* Using sw10-PF5 as the hotkey */
173 int post_hotkeys_pressed(void)
174 {
175         int delay = 3;
176         int i;
177         unsigned short value;
178
179         *pPORTF_FER &= ~PF5;
180         *pPORTFIO_DIR &= ~PF5;
181         *pPORTFIO_INEN |= PF5;
182
183         printf("########Press SW10 to enter Memory POST########: %2d ", delay);
184         while (delay--) {
185                 for (i = 0; i < 100; i++) {
186                         value = *pPORTFIO & PF5;
187                         if (value != 0) {
188                                 break;
189                         }
190                         udelay(10000);
191                 }
192                 printf("\b\b\b%2d ", delay);
193         }
194         printf("\b\b\b 0");
195         printf("\n");
196         if (value == 0)
197                 return 0;
198         else {
199                 printf("Hotkey has been pressed, Enter POST . . . . . .\n");
200                 return 1;
201         }
202 }
203 #endif
204
205 #if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER)
206 void post_word_store(ulong a)
207 {
208         volatile ulong *save_addr = (volatile ulong *)POST_WORD_ADDR;
209         *save_addr = a;
210 }
211
212 ulong post_word_load(void)
213 {
214         volatile ulong *save_addr = (volatile ulong *)POST_WORD_ADDR;
215         return *save_addr;
216 }
217 #endif
218
219 #ifdef CONFIG_POST
220 int uart_post_test(int flags)
221 {
222         return 0;
223 }
224
225 #define BLOCK_SIZE 0x10000
226 #define VERIFY_ADDR 0x2000000
227 extern int erase_block_flash(int);
228 extern int write_data(long lStart, long lCount, uchar * pnData);
229 int flash_post_test(int flags)
230 {
231         unsigned short *pbuf, *temp;
232         int offset, n, i;
233         int value = 0;
234         int result = 0;
235         printf("\n");
236         pbuf = (unsigned short *)VERIFY_ADDR;
237         temp = pbuf;
238         for (n = FLASH_START_POST_BLOCK; n < FLASH_END_POST_BLOCK; n++) {
239                 offset = (n - 7) * BLOCK_SIZE;
240                 printf("--------Erase   block:%2d..", n);
241                 erase_block_flash(n);
242                 printf("OK\r");
243                 printf("--------Program block:%2d...", n);
244                 write_data(CONFIG_SYS_FLASH_BASE + offset, BLOCK_SIZE, pbuf);
245                 printf("OK\r");
246                 printf("--------Verify  block:%2d...", n);
247                 for (i = 0; i < BLOCK_SIZE; i += 2) {
248                         if (*(unsigned short *)(CONFIG_SYS_FLASH_BASE + offset + i) !=
249                             *temp++) {
250                                 value = 1;
251                                 result = 1;
252                         }
253                 }
254                 if (value)
255                         printf("failed\n");
256                 else
257                         printf("OK              %3d%%\r",
258                                (int)(
259                                      (n + 1 -
260                                       FLASH_START_POST_BLOCK) *
261                                      100 / (FLASH_END_POST_BLOCK -
262                                             FLASH_START_POST_BLOCK)));
263
264                 temp = pbuf;
265                 value = 0;
266         }
267         printf("\n");
268         if (result)
269                 return -1;
270         else
271                 return 0;
272 }
273
274 /****************************************************
275  * LED1 ---- PF6        LED2 ---- PF7               *
276  * LED3 ---- PF8        LED4 ---- PF9               *
277  * LED5 ---- PF10       LED6 ---- PF11              *
278  ****************************************************/
279 int led_post_test(int flags)
280 {
281         *pPORTF_FER &= ~(PF6 | PF7 | PF8 | PF9 | PF10 | PF11);
282         *pPORTFIO_DIR |= PF6 | PF7 | PF8 | PF9 | PF10 | PF11;
283         *pPORTFIO_INEN &= ~(PF6 | PF7 | PF8 | PF9 | PF10 | PF11);
284         *pPORTFIO &= ~(PF6 | PF7 | PF8 | PF9 | PF10 | PF11);
285         udelay(1000000);
286         printf("LED1 on");
287         *pPORTFIO |= PF6;
288         udelay(1000000);
289         printf("\b\b\b\b\b\b\b");
290         printf("LED2 on");
291         *pPORTFIO |= PF7;
292         udelay(1000000);
293         printf("\b\b\b\b\b\b\b");
294         printf("LED3 on");
295         *pPORTFIO |= PF8;
296         udelay(1000000);
297         printf("\b\b\b\b\b\b\b");
298         printf("LED4 on");
299         *pPORTFIO |= PF9;
300         udelay(1000000);
301         printf("\b\b\b\b\b\b\b");
302         printf("LED5 on");
303         *pPORTFIO |= PF10;
304         udelay(1000000);
305         printf("\b\b\b\b\b\b\b");
306         printf("lED6 on");
307         *pPORTFIO |= PF11;
308         printf("\b\b\b\b\b\b\b ");
309         return 0;
310 }
311
312 /************************************************
313  *  SW10 ---- PF5       SW11 ---- PF4           *
314  *  SW12 ---- PF3       SW13 ---- PF2           *
315  ************************************************/
316 int button_post_test(int flags)
317 {
318         int i, delay = 5;
319         unsigned short value = 0;
320         int result = 0;
321
322         *pPORTF_FER &= ~(PF5 | PF4 | PF3 | PF2);
323         *pPORTFIO_DIR &= ~(PF5 | PF4 | PF3 | PF2);
324         *pPORTFIO_INEN |= (PF5 | PF4 | PF3 | PF2);
325
326         printf("\n--------Press SW10: %2d ", delay);
327         while (delay--) {
328                 for (i = 0; i < 100; i++) {
329                         value = *pPORTFIO & PF5;
330                         if (value != 0) {
331                                 break;
332                         }
333                         udelay(10000);
334                 }
335                 printf("\b\b\b%2d ", delay);
336         }
337         if (value != 0)
338                 printf("\b\bOK");
339         else {
340                 result = -1;
341                 printf("\b\bfailed");
342         }
343
344         delay = 5;
345         printf("\n--------Press SW11: %2d ", delay);
346         while (delay--) {
347                 for (i = 0; i < 100; i++) {
348                         value = *pPORTFIO & PF4;
349                         if (value != 0) {
350                                 break;
351                         }
352                         udelay(10000);
353                 }
354                 printf("\b\b\b%2d ", delay);
355         }
356         if (value != 0)
357                 printf("\b\bOK");
358         else {
359                 result = -1;
360                 printf("\b\bfailed");
361         }
362
363         delay = 5;
364         printf("\n--------Press SW12: %2d ", delay);
365         while (delay--) {
366                 for (i = 0; i < 100; i++) {
367                         value = *pPORTFIO & PF3;
368                         if (value != 0) {
369                                 break;
370                         }
371                         udelay(10000);
372                 }
373                 printf("\b\b\b%2d ", delay);
374         }
375         if (value != 0)
376                 printf("\b\bOK");
377         else {
378                 result = -1;
379                 printf("\b\bfailed");
380         }
381
382         delay = 5;
383         printf("\n--------Press SW13: %2d ", delay);
384         while (delay--) {
385                 for (i = 0; i < 100; i++) {
386                         value = *pPORTFIO & PF2;
387                         if (value != 0) {
388                                 break;
389                         }
390                         udelay(10000);
391                 }
392                 printf("\b\b\b%2d ", delay);
393         }
394         if (value != 0)
395                 printf("\b\bOK");
396         else {
397                 result = -1;
398                 printf("\b\bfailed");
399         }
400         printf("\n");
401         return result;
402 }
403 #endif