This patch adds USB storage support for the delta board. This is the first
[platform/kernel/u-boot.git] / board / delta / delta.c
1 /*
2  * (C) Copyright 2002
3  * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
4  *
5  * (C) Copyright 2002
6  * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
7  * Marius Groeger <mgroeger@sysgo.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., 59 Temple Place, Suite 330, Boston,
25  * MA 02111-1307 USA
26  */
27
28 #include <common.h>
29 #include <i2c.h>
30 #include <da9030.h>
31 #include <malloc.h>
32 #include <command.h>
33 #include <asm/arch/pxa-regs.h>
34
35 DECLARE_GLOBAL_DATA_PTR;
36
37 /* ------------------------------------------------------------------------- */
38
39 static void init_DA9030(void);
40 static void keys_init(void);
41 static void get_pressed_keys(uchar *s);
42 static uchar *key_match(uchar *kbd_data);
43
44 /*
45  * Miscelaneous platform dependent initialisations
46  */
47
48 int board_init (void)
49 {
50         /* memory and cpu-speed are setup before relocation */
51         /* so we do _nothing_ here */
52
53         /* arch number of Lubbock-Board mk@tbd: fix this! */
54         gd->bd->bi_arch_number = MACH_TYPE_LUBBOCK;
55
56         /* adress of boot parameters */
57         gd->bd->bi_boot_params = 0xa0000100;
58
59         return 0;
60 }
61
62 int board_late_init(void)
63 {
64 #ifdef DELTA_CHECK_KEYBD
65         uchar kbd_data[KEYBD_DATALEN];
66         char keybd_env[2 * KEYBD_DATALEN + 1];
67         char *str;
68         int i;
69 #endif /* DELTA_CHECK_KEYBD */
70
71         setenv("stdout", "serial");
72         setenv("stderr", "serial");
73
74 #ifdef DELTA_CHECK_KEYBD
75         keys_init();
76
77         memset(kbd_data, '\0', KEYBD_DATALEN);
78
79         /* check for pressed keys and setup keybd_env */
80         get_pressed_keys(kbd_data);
81
82         for (i = 0; i < KEYBD_DATALEN; ++i) {
83                 sprintf (keybd_env + i + i, "%02X", kbd_data[i]);
84         }
85         setenv ("keybd", keybd_env);
86
87         str = strdup ((char *)key_match (kbd_data));    /* decode keys */
88
89 # ifdef CONFIG_PREBOOT  /* automatically configure "preboot" command on key match */
90         setenv ("preboot", str);        /* set or delete definition */
91 # endif /* CONFIG_PREBOOT */
92         if (str != NULL) {
93                 free (str);
94         }
95 #endif /* DELTA_CHECK_KEYBD */
96
97         init_DA9030();
98         return 0;
99 }
100
101
102 /* board dependant usb stuff */
103 int usb_board_init()
104 {
105         /*
106          * Enable USB host clock.
107          */
108         CKENA |= (CKENA_2_USBHOST |  CKENA_20_UDC);
109         udelay(100);
110
111         /* Configure Port 2 for Host (USB Client Registers) */
112         UP2OCR = 0x3000c;
113
114 #if 0
115         GPIO2_2 = 0x801; /* USBHPEN - Alt. Fkt. 1 */
116         GPIO3_2 = 0x801; /* USBHPWR - Alt. Fkt. 1 */
117 #endif
118
119         UHCHR |= UHCHR_FHR;
120         wait_ms(11);    /* udelay(11); */
121         UHCHR &= ~UHCHR_FHR;
122
123         UHCHR |= UHCHR_FSBIR;
124         while (UHCHR & UHCHR_FSBIR)
125                 udelay(1);
126
127 #if 0
128         UHCHR |= UHCHR_PCPL; /* USBHPEN is active low */
129         UHCHR |= UHCHR_PSPL; /* USBHPWR is active low */
130 #endif
131
132         UHCHR &= ~UHCHR_SSEP0;
133         UHCHR &= ~UHCHR_SSEP1;
134         UHCHR &= ~UHCHR_SSE;
135
136         return 0;
137 }
138
139 int usb_board_stop()
140 {
141         /* may not want to do this */
142         /* CKENA &= ~(CKENA_2_USBHOST |  CKENA_20_UDC); */
143
144         return 0;
145 }
146
147
148 /*
149  * Magic Key Handling, mainly copied from board/lwmon/lwmon.c
150  */
151 #ifdef DELTA_CHECK_KEYBD
152
153 static uchar kbd_magic_prefix[] = "key_magic";
154 static uchar kbd_command_prefix[] = "key_cmd";
155
156 /*
157  * Get pressed keys
158  * s is a buffer of size KEYBD_DATALEN-1
159  */
160 static void get_pressed_keys(uchar *s)
161 {
162         unsigned long val;
163         val = GPLR3;
164
165         if(val & (1<<31))
166                 *s++ = KEYBD_KP_DKIN0;
167         if(val & (1<<18))
168                 *s++ = KEYBD_KP_DKIN1;
169         if(val & (1<<29))
170                 *s++ = KEYBD_KP_DKIN2;
171         if(val & (1<<22))
172                 *s++ = KEYBD_KP_DKIN5;
173 }
174
175 static void keys_init()
176 {
177         CKENB |= CKENB_7_GPIO;
178         udelay(100);
179
180         /* Configure GPIOs */
181         GPIO127 = 0xa840;       /* KP_DKIN0 */
182         GPIO114 = 0xa840;       /* KP_DKIN1 */
183         GPIO125 = 0xa840;       /* KP_DKIN2 */
184         GPIO118 = 0xa840;       /* KP_DKIN5 */
185
186         /* Configure GPIOs as inputs */
187         GPDR3 &= ~(1<<31 | 1<<18 | 1<<29 | 1<<22);
188         GCDR3 = (1<<31 | 1<<18 | 1<<29 | 1<<22);
189
190         udelay(100);
191 }
192
193 static int compare_magic (uchar *kbd_data, uchar *str)
194 {
195         /* uchar compare[KEYBD_DATALEN-1]; */
196         uchar compare[KEYBD_DATALEN];
197         char *nxt;
198         int i;
199
200         /* Don't include modifier byte */
201         /* memcpy (compare, kbd_data+1, KEYBD_DATALEN-1); */
202         memcpy (compare, kbd_data, KEYBD_DATALEN);
203
204         for (; str != NULL; str = (*nxt) ? (uchar *)(nxt+1) : (uchar *)nxt) {
205                 uchar c;
206                 int k;
207
208                 c = (uchar) simple_strtoul ((char *)str, (char **) (&nxt), 16);
209
210                 if (str == (uchar *)nxt) {      /* invalid character */
211                         break;
212                 }
213
214                 /*
215                  * Check if this key matches the input.
216                  * Set matches to zero, so they match only once
217                  * and we can find duplicates or extra keys
218                  */
219                 for (k = 0; k < sizeof(compare); ++k) {
220                         if (compare[k] == '\0') /* only non-zero entries */
221                                 continue;
222                         if (c == compare[k]) {  /* found matching key */
223                                 compare[k] = '\0';
224                                 break;
225                         }
226                 }
227                 if (k == sizeof(compare)) {
228                         return -1;              /* unmatched key */
229                 }
230         }
231
232         /*
233          * A full match leaves no keys in the `compare' array,
234          */
235         for (i = 0; i < sizeof(compare); ++i) {
236                 if (compare[i])
237                 {
238                         return -1;
239                 }
240         }
241
242         return 0;
243 }
244
245
246 static uchar *key_match (uchar *kbd_data)
247 {
248         char magic[sizeof (kbd_magic_prefix) + 1];
249         uchar *suffix;
250         char *kbd_magic_keys;
251
252         /*
253          * The following string defines the characters that can pe appended
254          * to "key_magic" to form the names of environment variables that
255          * hold "magic" key codes, i. e. such key codes that can cause
256          * pre-boot actions. If the string is empty (""), then only
257          * "key_magic" is checked (old behaviour); the string "125" causes
258          * checks for "key_magic1", "key_magic2" and "key_magic5", etc.
259          */
260         if ((kbd_magic_keys = getenv ("magic_keys")) == NULL)
261                 kbd_magic_keys = "";
262
263         /* loop over all magic keys;
264          * use '\0' suffix in case of empty string
265          */
266         for (suffix=(uchar *)kbd_magic_keys; *suffix || suffix==(uchar *)kbd_magic_keys; ++suffix) {
267                 sprintf (magic, "%s%c", kbd_magic_prefix, *suffix);
268 #if 0
269                 printf ("### Check magic \"%s\"\n", magic);
270 #endif
271                 if (compare_magic(kbd_data, (uchar *)getenv(magic)) == 0) {
272                         char cmd_name[sizeof (kbd_command_prefix) + 1];
273                         char *cmd;
274
275                         sprintf (cmd_name, "%s%c", kbd_command_prefix, *suffix);
276
277                         cmd = getenv (cmd_name);
278 #if 0
279                         printf ("### Set PREBOOT to $(%s): \"%s\"\n",
280                                 cmd_name, cmd ? cmd : "<<NULL>>");
281 #endif
282                         *kbd_data = *suffix;
283                         return ((uchar *)cmd);
284                 }
285         }
286 #if 0
287         printf ("### Delete PREBOOT\n");
288 #endif
289         *kbd_data = '\0';
290         return (NULL);
291 }
292
293 int do_kbd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
294 {
295         uchar kbd_data[KEYBD_DATALEN];
296         char keybd_env[2 * KEYBD_DATALEN + 1];
297         int i;
298
299         /* Read keys */
300         get_pressed_keys(kbd_data);
301         puts ("Keys:");
302         for (i = 0; i < KEYBD_DATALEN; ++i) {
303                 sprintf (keybd_env + i + i, "%02X", kbd_data[i]);
304                 printf (" %02x", kbd_data[i]);
305         }
306         putc ('\n');
307         setenv ("keybd", keybd_env);
308         return 0;
309 }
310
311 U_BOOT_CMD(
312            kbd, 1,      1,      do_kbd,
313            "kbd     - read keyboard status\n",
314            NULL
315 );
316
317 #endif /* DELTA_CHECK_KEYBD */
318
319
320 int dram_init (void)
321 {
322         gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
323         gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
324         gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
325         gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
326         gd->bd->bi_dram[2].start = PHYS_SDRAM_3;
327         gd->bd->bi_dram[2].size = PHYS_SDRAM_3_SIZE;
328         gd->bd->bi_dram[3].start = PHYS_SDRAM_4;
329         gd->bd->bi_dram[3].size = PHYS_SDRAM_4_SIZE;
330
331         return 0;
332 }
333
334 void i2c_init_board()
335 {
336         CKENB |= (CKENB_4_I2C);
337
338         /* setup I2C GPIO's */
339         GPIO32 = 0x801;         /* SCL = Alt. Fkt. 1 */
340         GPIO33 = 0x801;         /* SDA = Alt. Fkt. 1 */
341 }
342
343 /* initialize the DA9030 Power Controller */
344 static void init_DA9030()
345 {
346         uchar addr = (uchar) DA9030_I2C_ADDR, val = 0;
347
348         CKENB |= CKENB_7_GPIO;
349         udelay(100);
350
351         /* Rising Edge on EXTON to reset DA9030 */
352         GPIO17 = 0x8800;        /* configure GPIO17, no pullup, -down */
353         GPDR0 |= (1<<17);       /* GPIO17 is output */
354         GSDR0 = (1<<17);
355         GPCR0 = (1<<17);        /* drive GPIO17 low */
356         GPSR0 = (1<<17);        /* drive GPIO17 high */
357
358 #if CFG_DA9030_EXTON_DELAY
359         udelay((unsigned long) CFG_DA9030_EXTON_DELAY); /* wait for DA9030 */
360 #endif
361         GPCR0 = (1<<17);        /* drive GPIO17 low */
362
363         /* reset the watchdog and go active (0xec) */
364         val = (SYS_CONTROL_A_HWRES_ENABLE |
365                (0x6<<4) |
366                SYS_CONTROL_A_WDOG_ACTION |
367                SYS_CONTROL_A_WATCHDOG);
368         if(i2c_write(addr, SYS_CONTROL_A, 1, &val, 1)) {
369                 printf("Error accessing DA9030 via i2c.\n");
370                 return;
371         }
372
373         val = 0x80;
374         if(i2c_write(addr, IRQ_MASK_B, 1, &val, 1)) {
375                 printf("Error accessing DA9030 via i2c.\n");
376                 return;
377         }
378
379         i2c_reg_write(addr, REG_CONTROL_1_97, 0xfd); /* disable LDO1, enable LDO6 */
380         i2c_reg_write(addr, LDO2_3, 0xd1);      /* LDO2 =1,9V, LDO3=3,1V */
381         i2c_reg_write(addr, LDO4_5, 0xcc);      /* LDO2 =1,9V, LDO3=3,1V */
382         i2c_reg_write(addr, LDO6_SIMCP, 0x3e);  /* LDO6=3,2V, SIMCP = 5V support */
383         i2c_reg_write(addr, LDO7_8, 0xc9);      /* LDO7=2,7V, LDO8=3,0V */
384         i2c_reg_write(addr, LDO9_12, 0xec);     /* LDO9=3,0V, LDO12=3,2V */
385         i2c_reg_write(addr, BUCK, 0x0c);        /* Buck=1.2V */
386         i2c_reg_write(addr, REG_CONTROL_2_98, 0x7f); /* All LDO'S on 8,9,10,11,12,14 */
387         i2c_reg_write(addr, LDO_10_11, 0xcc);   /* LDO10=3.0V  LDO11=3.0V */
388         i2c_reg_write(addr, LDO_15, 0xae);      /* LDO15=1.8V, dislock first 3bit */
389         i2c_reg_write(addr, LDO_14_16, 0x05);   /* LDO14=2.8V, LDO16=NB */
390         i2c_reg_write(addr, LDO_18_19, 0x9c);   /* LDO18=3.0V, LDO19=2.7V */
391         i2c_reg_write(addr, LDO_17_SIMCP0, 0x2c); /* LDO17=3.0V, SIMCP=3V support */
392         i2c_reg_write(addr, BUCK2_DVC1, 0x9a);  /* Buck2=1.5V plus Update support of 520 MHz */
393         i2c_reg_write(addr, REG_CONTROL_2_18, 0x43); /* Ball on */
394         i2c_reg_write(addr, MISC_CONTROLB, 0x08); /* session valid enable */
395         i2c_reg_write(addr, USBPUMP, 0xc1);     /* start pump, ignore HW signals */
396
397         val = i2c_reg_read(addr, STATUS);
398         if(val & STATUS_CHDET)
399                 printf("Charger detected, turning on LED.\n");
400         else {
401                 printf("No charger detetected.\n");
402                 /* undervoltage? print error and power down */
403         }
404 }
405
406
407 #if 0
408 /* reset the DA9030 watchdog */
409 void hw_watchdog_reset(void)
410 {
411         uchar addr = (uchar) DA9030_I2C_ADDR, val = 0;
412         val = i2c_reg_read(addr, SYS_CONTROL_A);
413         val |= SYS_CONTROL_A_WATCHDOG;
414         i2c_reg_write(addr, SYS_CONTROL_A, val);
415 }
416 #endif