]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/pcs440ep/pcs440ep.c
Merge remote-tracking branch 'u-boot-ti/master'
[karo-tx-uboot.git] / board / pcs440ep / pcs440ep.c
1 /*
2  * (C) Copyright 2006
3  * Stefan Roese, DENX Software Engineering, sr@denx.de.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  */
23
24 #include <common.h>
25 #include <asm/ppc4xx.h>
26 #include <malloc.h>
27 #include <command.h>
28 #include <crc.h>
29 #include <asm/processor.h>
30 #include <spd_sdram.h>
31 #include <status_led.h>
32 #include <sha1.h>
33 #include <asm/io.h>
34 #include <net.h>
35 #include <ata.h>
36
37 DECLARE_GLOBAL_DATA_PTR;
38
39 extern flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips     */
40
41 unsigned char   sha1_checksum[SHA1_SUM_LEN];
42
43 /* swap 4 Bits (Bit0 = Bit3, Bit1 = Bit2, Bit2 = Bit1 and Bit3 = Bit0) */
44 unsigned char swapbits[16] = {0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
45                               0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf};
46
47 static void set_leds (int val)
48 {
49         out32(GPIO0_OR, (in32 (GPIO0_OR) & ~0x78000000) | (val << 27));
50 }
51
52 #define GET_LEDS ((in32 (GPIO0_OR) & 0x78000000) >> 27)
53
54 void __led_init (led_id_t mask, int state)
55 {
56         int     val = GET_LEDS;
57
58         if (state == STATUS_LED_ON)
59                 val |= mask;
60         else
61                 val &= ~mask;
62         set_leds (val);
63 }
64
65 void __led_set (led_id_t mask, int state)
66 {
67         int     val = GET_LEDS;
68
69         if (state == STATUS_LED_ON)
70                 val |= mask;
71         else if (state == STATUS_LED_OFF)
72                 val &= ~mask;
73         set_leds (val);
74 }
75
76 void __led_toggle (led_id_t mask)
77 {
78         int     val = GET_LEDS;
79
80         val ^= mask;
81         set_leds (val);
82 }
83
84 static void status_led_blink (void)
85 {
86         int     i;
87         int     val = GET_LEDS;
88
89         /* set all LED which are on, to state BLINKING */
90         for (i = 0; i < 4; i++) {
91                 if (val & 0x01) status_led_set (3 - i, STATUS_LED_BLINKING);
92                 else status_led_set (3 - i, STATUS_LED_OFF);
93                 val = val >> 1;
94         }
95 }
96
97 #if defined(CONFIG_SHOW_BOOT_PROGRESS)
98 void show_boot_progress (int val)
99 {
100         /* find all valid Codes for val in README */
101         if (val == -BOOTSTAGE_ID_NEED_RESET)
102                 return;
103         if (val < 0) {
104                 /* smthing goes wrong */
105                 status_led_blink ();
106                 return;
107         }
108         switch (val) {
109         case BOOTSTAGE_ID_CHECK_MAGIC:
110                 /* validating Image */
111                 status_led_set(0, STATUS_LED_OFF);
112                 status_led_set(1, STATUS_LED_ON);
113                 status_led_set(2, STATUS_LED_ON);
114                 break;
115         case BOOTSTAGE_ID_RUN_OS:
116                 status_led_set(0, STATUS_LED_ON);
117                 status_led_set(1, STATUS_LED_ON);
118                 status_led_set(2, STATUS_LED_ON);
119                 break;
120 #if 0
121         case BOOTSTAGE_ID_NET_ETH_START:
122                 /* starting Ethernet configuration */
123                 status_led_set(0, STATUS_LED_OFF);
124                 status_led_set(1, STATUS_LED_OFF);
125                 status_led_set(2, STATUS_LED_ON);
126                 break;
127 #endif
128         case BOOTSTAGE_ID_NET_START:
129                 /* loading Image */
130                 status_led_set(0, STATUS_LED_ON);
131                 status_led_set(1, STATUS_LED_OFF);
132                 status_led_set(2, STATUS_LED_ON);
133                 break;
134         }
135 }
136 #endif
137
138 int board_early_init_f(void)
139 {
140         register uint reg;
141
142         set_leds(0);                    /* display boot info counter */
143
144         /*--------------------------------------------------------------------
145          * Setup the external bus controller/chip selects
146          *-------------------------------------------------------------------*/
147         mtdcr(EBC0_CFGADDR, EBC0_CFG);
148         reg = mfdcr(EBC0_CFGDATA);
149         mtdcr(EBC0_CFGDATA, reg | 0x04000000);  /* Set ATC */
150
151         /*--------------------------------------------------------------------
152          * GPIO's are alreay setup in arch/powerpc/cpu/ppc4xx/cpu_init.c
153          * via define from board config file.
154          *-------------------------------------------------------------------*/
155
156         /*--------------------------------------------------------------------
157          * Setup the interrupt controller polarities, triggers, etc.
158          *-------------------------------------------------------------------*/
159         mtdcr(UIC0SR, 0xffffffff);      /* clear all */
160         mtdcr(UIC0ER, 0x00000000);      /* disable all */
161         mtdcr(UIC0CR, 0x00000001);      /* UIC1 crit is critical */
162         mtdcr(UIC0PR, 0xfffffe1f);      /* per ref-board manual */
163         mtdcr(UIC0TR, 0x01c00000);      /* per ref-board manual */
164         mtdcr(UIC0VR, 0x00000001);      /* int31 highest, base=0x000 */
165         mtdcr(UIC0SR, 0xffffffff);      /* clear all */
166
167         mtdcr(UIC1SR, 0xffffffff);      /* clear all */
168         mtdcr(UIC1ER, 0x00000000);      /* disable all */
169         mtdcr(UIC1CR, 0x00000000);      /* all non-critical */
170         mtdcr(UIC1PR, 0xffffe0ff);      /* per ref-board manual */
171         mtdcr(UIC1TR, 0x00ffc000);      /* per ref-board manual */
172         mtdcr(UIC1VR, 0x00000001);      /* int31 highest, base=0x000 */
173         mtdcr(UIC1SR, 0xffffffff);      /* clear all */
174
175         /*--------------------------------------------------------------------
176          * Setup other serial configuration
177          *-------------------------------------------------------------------*/
178         mfsdr(SDR0_PCI0, reg);
179         mtsdr(SDR0_PCI0, 0x80000000 | reg);     /* PCI arbiter enabled */
180         mtsdr(SDR0_PFC0, 0x00000000);   /* Pin function: enable GPIO49-63 */
181         mtsdr(SDR0_PFC1, 0x00048000);   /* Pin function: UART0 has 4 pins, select IRQ5 */
182
183         return 0;
184 }
185
186 #define EEPROM_LEN      256
187 static void load_ethaddr(void)
188 {
189         int     ok_ethaddr, ok_eth1addr;
190         int     ret;
191         uchar   buf[EEPROM_LEN];
192         char    *use_eeprom;
193         u16     checksumcrc16 = 0;
194
195         /* If the env is sane, then nothing for us to do */
196         ok_ethaddr = eth_getenv_enetaddr("ethaddr", buf);
197         ok_eth1addr = eth_getenv_enetaddr("eth1addr", buf);
198         if (ok_ethaddr && ok_eth1addr)
199                 return;
200
201         /* read the MACs from EEprom */
202         status_led_set (0, STATUS_LED_ON);
203         status_led_set (1, STATUS_LED_ON);
204         ret = eeprom_read (CONFIG_SYS_I2C_EEPROM_ADDR, 0, buf, EEPROM_LEN);
205         if (ret == 0) {
206                 checksumcrc16 = cyg_crc16 (buf, EEPROM_LEN - 2);
207                 /* check, if the EEprom is programmed:
208                  * - The Prefix(Byte 0,1,2) is equal to "ATR"
209                  * - The checksum, stored in the last 2 Bytes, is correct
210                  */
211                 if ((strncmp ((char *)buf,"ATR",3) != 0) ||
212                     ((checksumcrc16 >> 8) != buf[EEPROM_LEN - 2]) ||
213                     ((checksumcrc16 & 0xff) != buf[EEPROM_LEN - 1])) {
214                         /* EEprom is not programmed */
215                         printf("%s: EEPROM Checksum not OK\n", __FUNCTION__);
216                 } else {
217                         /* get the MACs */
218                         if (!ok_ethaddr)
219                                 eth_setenv_enetaddr("ethaddr", &buf[3]);
220                         if (!ok_eth1addr)
221                                 eth_setenv_enetaddr("eth1addr", &buf[9]);
222                         return;
223                 }
224         }
225
226         /* some error reading the EEprom */
227         if ((use_eeprom = getenv ("use_eeprom_ethaddr")) == NULL) {
228                 /* dont use bootcmd */
229                 setenv("bootdelay", "-1");
230                 return;
231         }
232         /* == default ? use standard */
233         if (strncmp (use_eeprom, "default", 7) == 0) {
234                 return;
235         }
236         /* Env doesnt exist -> hang */
237         status_led_blink ();
238         /* here we do this "handy" because we have no interrupts
239            at this time */
240         puts ("### EEPROM ERROR ### Please RESET the board ###\n");
241         for (;;) {
242                 __led_toggle (12);
243                 udelay (100000);
244         }
245         return;
246 }
247
248 #ifdef CONFIG_PREBOOT
249
250 static uchar kbd_magic_prefix[]         = "key_magic";
251 static uchar kbd_command_prefix[]       = "key_cmd";
252
253 struct kbd_data_t {
254         char s1;
255         char s2;
256 };
257
258 struct kbd_data_t* get_keys (struct kbd_data_t *kbd_data)
259 {
260         char *val;
261         unsigned long tmp;
262
263         /* use the DIPs for some bootoptions */
264         val = getenv (ENV_NAME_DIP);
265         tmp = simple_strtoul (val, NULL, 16);
266
267         kbd_data->s2 = (tmp & 0x0f);
268         kbd_data->s1 = (tmp & 0xf0) >> 4;
269         return kbd_data;
270 }
271
272 static int compare_magic (const struct kbd_data_t *kbd_data, char *str)
273 {
274         char s1 = str[0];
275
276         if (s1 >= '0' && s1 <= '9')
277                 s1 -= '0';
278         else if (s1 >= 'a' && s1 <= 'f')
279                 s1 = s1 - 'a' + 10;
280         else if (s1 >= 'A' && s1 <= 'F')
281                 s1 = s1 - 'A' + 10;
282         else
283                 return -1;
284
285         if (s1 != kbd_data->s1) return -1;
286
287         s1 = str[1];
288         if (s1 >= '0' && s1 <= '9')
289                 s1 -= '0';
290         else if (s1 >= 'a' && s1 <= 'f')
291                 s1 = s1 - 'a' + 10;
292         else if (s1 >= 'A' && s1 <= 'F')
293                 s1 = s1 - 'A' + 10;
294         else
295                 return -1;
296
297         if (s1 != kbd_data->s2) return -1;
298         return 0;
299 }
300
301 static char *key_match (const struct kbd_data_t *kbd_data)
302 {
303         char magic[sizeof (kbd_magic_prefix) + 1];
304         char *suffix;
305         char *kbd_magic_keys;
306
307         /*
308          * The following string defines the characters that can be appended
309          * to "key_magic" to form the names of environment variables that
310          * hold "magic" key codes, i. e. such key codes that can cause
311          * pre-boot actions. If the string is empty (""), then only
312          * "key_magic" is checked (old behaviour); the string "125" causes
313          * checks for "key_magic1", "key_magic2" and "key_magic5", etc.
314          */
315         if ((kbd_magic_keys = getenv ("magic_keys")) == NULL)
316                 kbd_magic_keys = "";
317
318         /* loop over all magic keys;
319          * use '\0' suffix in case of empty string
320          */
321         for (suffix = kbd_magic_keys; *suffix ||
322                      suffix == kbd_magic_keys; ++suffix) {
323                 sprintf (magic, "%s%c", kbd_magic_prefix, *suffix);
324                 if (compare_magic (kbd_data, getenv (magic)) == 0) {
325                         char cmd_name[sizeof (kbd_command_prefix) + 1];
326                         char *cmd;
327
328                         sprintf (cmd_name, "%s%c", kbd_command_prefix, *suffix);
329                         cmd = getenv (cmd_name);
330
331                         return (cmd);
332                 }
333         }
334         return (NULL);
335 }
336
337 #endif /* CONFIG_PREBOOT */
338
339 static int pcs440ep_readinputs (void)
340 {
341         int     i;
342         char    value[20];
343
344         /* read the inputs and set the Envvars */
345         /* Revision Level Bit 26 - 29 */
346         i = ((in32 (GPIO0_IR) & 0x0000003c) >> 2);
347         i = swapbits[i];
348         sprintf (value, "%02x", i);
349         setenv (ENV_NAME_REVLEV, value);
350         /* Solder Switch Bit 30 - 33 */
351         i = (in32 (GPIO0_IR) & 0x00000003) << 2;
352         i += (in32 (GPIO1_IR) & 0xc0000000) >> 30;
353         i = swapbits[i];
354         sprintf (value, "%02x", i);
355         setenv (ENV_NAME_SOLDER, value);
356         /* DIP Switch Bit 49 - 56 */
357         i = ((in32 (GPIO1_IR) & 0x00007f80) >> 7);
358         i = (swapbits[i & 0x0f] << 4) + swapbits[(i & 0xf0) >> 4];
359         sprintf (value, "%02x", i);
360         setenv (ENV_NAME_DIP, value);
361         return 0;
362 }
363
364
365 #if defined(CONFIG_SHA1_CHECK_UB_IMG)
366 /*************************************************************************
367  * calculate a SHA1 sum for the U-Boot image in Flash.
368  *
369  ************************************************************************/
370 static int pcs440ep_sha1 (int docheck)
371 {
372         unsigned char *data;
373         unsigned char *ptroff;
374         unsigned char output[20];
375         unsigned char org[20];
376         int     i, len = CONFIG_SHA1_LEN;
377
378         memcpy ((char *)CONFIG_SYS_LOAD_ADDR, (char *)CONFIG_SHA1_START, len);
379         data = (unsigned char *)CONFIG_SYS_LOAD_ADDR;
380         ptroff = &data[len + SHA1_SUM_POS];
381
382         for (i = 0; i < SHA1_SUM_LEN; i++) {
383                 org[i] = ptroff[i];
384                 ptroff[i] = 0;
385         }
386
387         sha1_csum ((unsigned char *) data, len, (unsigned char *)output);
388
389         if (docheck == 2) {
390                 for (i = 0; i < 20 ; i++) {
391                         printf("%02X ", output[i]);
392                 }
393                 printf("\n");
394         }
395         if (docheck == 1) {
396                 for (i = 0; i < 20 ; i++) {
397                         if (org[i] != output[i]) return 1;
398                 }
399         }
400         return 0;
401 }
402
403 /*************************************************************************
404  * do some checks after the SHA1 checksum from the U-Boot Image was
405  * calculated.
406  *
407  ************************************************************************/
408 static void pcs440ep_checksha1 (void)
409 {
410         int     ret;
411         char    *cs_test;
412
413         status_led_set (0, STATUS_LED_OFF);
414         status_led_set (1, STATUS_LED_OFF);
415         status_led_set (2, STATUS_LED_ON);
416         ret = pcs440ep_sha1 (1);
417         if (ret == 0) return;
418
419         if ((cs_test = getenv ("cs_test")) == NULL) {
420                 /* Env doesnt exist -> hang */
421                 status_led_blink ();
422                 /* here we do this "handy" because we have no interrupts
423                    at this time */
424                 puts ("### SHA1 ERROR ### Please RESET the board ###\n");
425                 for (;;) {
426                         __led_toggle (2);
427                         udelay (100000);
428                 }
429         }
430
431         if (strncmp (cs_test, "off", 3) == 0) {
432                 printf ("SHA1 U-Boot sum NOT ok!\n");
433                 setenv ("bootdelay", "-1");
434         }
435 }
436 #else
437 static __inline__ void pcs440ep_checksha1 (void) { do {} while (0);}
438 #endif
439
440 int misc_init_r (void)
441 {
442         uint pbcr;
443         int size_val = 0;
444
445         load_ethaddr();
446
447         /* Re-do sizing to get full correct info */
448         mtdcr(EBC0_CFGADDR, PB0CR);
449         pbcr = mfdcr(EBC0_CFGDATA);
450         switch (gd->bd->bi_flashsize) {
451         case 1 << 20:
452                 size_val = 0;
453                 break;
454         case 2 << 20:
455                 size_val = 1;
456                 break;
457         case 4 << 20:
458                 size_val = 2;
459                 break;
460         case 8 << 20:
461                 size_val = 3;
462                 break;
463         case 16 << 20:
464                 size_val = 4;
465                 break;
466         case 32 << 20:
467                 size_val = 5;
468                 break;
469         case 64 << 20:
470                 size_val = 6;
471                 break;
472         case 128 << 20:
473                 size_val = 7;
474                 break;
475         }
476         pbcr = (pbcr & 0x0001ffff) | gd->bd->bi_flashstart | (size_val << 17);
477         mtdcr(EBC0_CFGADDR, PB0CR);
478         mtdcr(EBC0_CFGDATA, pbcr);
479
480         /* adjust flash start and offset */
481         gd->bd->bi_flashstart = 0 - gd->bd->bi_flashsize;
482         gd->bd->bi_flashoffset = 0;
483
484         /* Monitor protection ON by default */
485         (void)flash_protect(FLAG_PROTECT_SET,
486                             -CONFIG_SYS_MONITOR_LEN,
487                             0xffffffff,
488                             &flash_info[1]);
489
490         /* Env protection ON by default */
491         (void)flash_protect(FLAG_PROTECT_SET,
492                             CONFIG_ENV_ADDR_REDUND,
493                             CONFIG_ENV_ADDR_REDUND + 2*CONFIG_ENV_SECT_SIZE - 1,
494                             &flash_info[1]);
495
496         pcs440ep_readinputs ();
497         pcs440ep_checksha1 ();
498 #ifdef CONFIG_PREBOOT
499         {
500                 struct kbd_data_t kbd_data;
501                 /* Decode keys */
502                 char *str = strdup (key_match (get_keys (&kbd_data)));
503                 /* Set or delete definition */
504                 setenv ("preboot", str);
505                 free (str);
506         }
507 #endif /* CONFIG_PREBOOT */
508         return 0;
509 }
510
511 int checkboard(void)
512 {
513         char buf[64];
514         int i = getenv_f("serial#", buf, sizeof(buf));
515
516         printf("Board: PCS440EP");
517         if (i > 0) {
518                 puts(", serial# ");
519                 puts(buf);
520         }
521         putc('\n');
522
523         return (0);
524 }
525
526 void spd_ddr_init_hang (void)
527 {
528         status_led_set (0, STATUS_LED_OFF);
529         status_led_set (1, STATUS_LED_ON);
530         /* we cannot use hang() because we are still running from
531            Flash, and so the status_led driver is not initialized */
532         puts ("### SDRAM ERROR ### Please RESET the board ###\n");
533         for (;;) {
534                 __led_toggle (4);
535                 udelay (100000);
536         }
537 }
538
539 phys_size_t initdram (int board_type)
540 {
541         long dram_size = 0;
542
543         status_led_set (0, STATUS_LED_ON);
544         status_led_set (1, STATUS_LED_OFF);
545         dram_size = spd_sdram();
546         status_led_set (0, STATUS_LED_OFF);
547         status_led_set (1, STATUS_LED_ON);
548         if (dram_size == 0) {
549                 hang();
550         }
551
552         return dram_size;
553 }
554
555 /*************************************************************************
556  *  hw_watchdog_reset
557  *
558  *      This routine is called to reset (keep alive) the watchdog timer
559  *
560  ************************************************************************/
561 #if defined(CONFIG_HW_WATCHDOG)
562 void hw_watchdog_reset(void)
563 {
564
565 }
566 #endif
567
568 /*************************************************************************
569  * "led" Commando for the U-Boot shell
570  *
571  ************************************************************************/
572 int do_led (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
573 {
574         int     rcode = 0, i;
575         ulong   pattern = 0;
576
577         pattern = simple_strtoul (argv[1], NULL, 16);
578         if (pattern > 0x400) {
579                 int     val = GET_LEDS;
580                 printf ("led: %x\n", val);
581                 return rcode;
582         }
583         if (pattern > 0x200) {
584                 status_led_blink ();
585                 hang ();
586                 return rcode;
587         }
588         if (pattern > 0x100) {
589                 status_led_blink ();
590                 return rcode;
591         }
592         pattern &= 0x0f;
593         for (i = 0; i < 4; i++) {
594                 if (pattern & 0x01) status_led_set (i, STATUS_LED_ON);
595                 else status_led_set (i, STATUS_LED_OFF);
596                 pattern = pattern >> 1;
597         }
598         return rcode;
599 }
600
601 U_BOOT_CMD(
602         led,    2,      1,      do_led,
603         "set the DIAG-LED",
604         "[bitmask] 0x01 = DIAG 1 on\n"
605         "              0x02 = DIAG 2 on\n"
606         "              0x04 = DIAG 3 on\n"
607         "              0x08 = DIAG 4 on\n"
608         "              > 0x100 set the LED, who are on, to state blinking"
609 );
610
611 #if defined(CONFIG_SHA1_CHECK_UB_IMG)
612 /*************************************************************************
613  * "sha1" Commando for the U-Boot shell
614  *
615  ************************************************************************/
616 int do_sha1 (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
617 {
618         int     rcode = -1;
619
620         if (argc < 2) {
621 usage:
622                 return cmd_usage(cmdtp);
623         }
624
625         if (argc >= 3) {
626                 unsigned char *data;
627                 unsigned char output[20];
628                 int     len;
629                 int     i;
630
631                 data = (unsigned char *)simple_strtoul (argv[1], NULL, 16);
632                 len = simple_strtoul (argv[2], NULL, 16);
633                 sha1_csum (data, len, (unsigned char *)output);
634                 printf ("U-Boot sum:\n");
635                 for (i = 0; i < 20 ; i++) {
636                         printf ("%02X ", output[i]);
637                 }
638                 printf ("\n");
639                 if (argc == 4) {
640                         data = (unsigned char *)simple_strtoul (argv[3], NULL, 16);
641                         memcpy (data, output, 20);
642                 }
643                 return 0;
644         }
645         if (argc == 2) {
646                 char *ptr = argv[1];
647                 if (*ptr != '-') goto usage;
648                 ptr++;
649                 if ((*ptr == 'c') || (*ptr == 'C')) {
650                         rcode = pcs440ep_sha1 (1);
651                         printf ("SHA1 U-Boot sum %sok!\n", (rcode != 0) ? "not " : "");
652                 } else if ((*ptr == 'p') || (*ptr == 'P')) {
653                         rcode = pcs440ep_sha1 (2);
654                 } else {
655                         rcode = pcs440ep_sha1 (0);
656                 }
657                 return rcode;
658         }
659         return rcode;
660 }
661
662 U_BOOT_CMD(
663         sha1,   4,      1,      do_sha1,
664         "calculate the SHA1 Sum",
665         "address len [addr]  calculate the SHA1 sum [save at addr]\n"
666         "     -p calculate the SHA1 sum from the U-Boot image in flash and print\n"
667         "     -c check the U-Boot image in flash"
668 );
669 #endif
670
671 #if defined (CONFIG_CMD_IDE)
672 /* These addresses need to be shifted one place to the left
673  * ( bus per_addr 20 -30 is connectsd on CF bus A10-A0)
674  * These values are shifted
675  */
676 void inline ide_outb(int dev, int port, unsigned char val)
677 {
678         debug ("ide_outb (dev= %d, port= 0x%x, val= 0x%02x) : @ 0x%08lx\n",
679                 dev, port, val, (ATA_CURR_BASE(dev)+port));
680
681         out_be16((u16 *)(ATA_CURR_BASE(dev)+(port << 1)), val);
682 }
683 unsigned char inline ide_inb(int dev, int port)
684 {
685         uchar val;
686         val = in_be16((u16 *)(ATA_CURR_BASE(dev)+(port << 1)));
687         debug ("ide_inb (dev= %d, port= 0x%x) : @ 0x%08lx -> 0x%02x\n",
688                 dev, port, (ATA_CURR_BASE(dev)+port), val);
689         return (val);
690 }
691 #endif
692
693 #ifdef CONFIG_IDE_PREINIT
694 int ide_preinit (void)
695 {
696         /* Set True IDE Mode */
697         out32 (GPIO0_OR, (in32 (GPIO0_OR) | 0x00100000));
698         out32 (GPIO0_OR, (in32 (GPIO0_OR) | 0x00200000));
699         out32 (GPIO1_OR, (in32 (GPIO1_OR) & ~0x00008040));
700         udelay (100000);
701         return 0;
702 }
703 #endif
704
705 #if defined (CONFIG_CMD_IDE) && defined (CONFIG_IDE_RESET)
706 void ide_set_reset (int idereset)
707 {
708         debug ("ide_reset(%d)\n", idereset);
709         if (idereset == 0) {
710                 out32 (GPIO0_OR, (in32 (GPIO0_OR) | 0x00200000));
711         } else {
712                 out32 (GPIO0_OR, (in32 (GPIO0_OR) & ~0x00200000));
713         }
714         udelay (10000);
715 }
716 #endif /* defined (CONFIG_CMD_IDE) && defined (CONFIG_IDE_RESET) */
717
718
719 /* this is motly the same as it should, causing a little code duplication */
720 #if defined(CONFIG_CMD_IDE)
721 #define EIEIO           __asm__ volatile ("eieio")
722
723 void ide_input_swap_data(int dev, ulong *sect_buf, int words)
724 {
725         volatile ushort *pbuf =
726                 (ushort *) (ATA_CURR_BASE(dev) + ATA_DATA_REG);
727         ushort *dbuf = (ushort *) sect_buf;
728
729         debug("in input swap data base for read is %lx\n",
730                 (unsigned long) pbuf);
731
732         while (words--) {
733                 *dbuf++ = *pbuf;
734                 *dbuf++ = *pbuf;
735         }
736 }
737
738 void ide_output_data(int dev, const ulong *sect_buf, int words)
739 {
740         ushort *dbuf;
741         volatile ushort *pbuf;
742
743         pbuf = (ushort *) (ATA_CURR_BASE(dev) + ATA_DATA_REG);
744         dbuf = (ushort *) sect_buf;
745         while (words--) {
746                 EIEIO;
747                 *pbuf = ld_le16(dbuf++);
748                 EIEIO;
749                 *pbuf = ld_le16(dbuf++);
750         }
751 }
752
753 void ide_input_data(int dev, ulong *sect_buf, int words)
754 {
755         ushort *dbuf;
756         volatile ushort *pbuf;
757
758         pbuf = (ushort *) (ATA_CURR_BASE(dev) + ATA_DATA_REG);
759         dbuf = (ushort *) sect_buf;
760
761         debug("in input data base for read is %lx\n", (unsigned long) pbuf);
762
763         while (words--) {
764                 EIEIO;
765                 *dbuf++ = ld_le16(pbuf);
766                 EIEIO;
767                 *dbuf++ = ld_le16(pbuf);
768         }
769 }
770
771 #endif