Newer
Older
* (C) Copyright 2000-2005
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*/
/*
* IDE support
*/
#include <common.h>
#include <config.h>
#include <watchdog.h>
#include <command.h>
#include <image.h>
#include <asm/byteorder.h>
#include <asm/io.h>
#if defined(CONFIG_IDE_8xx_DIRECT) || defined(CONFIG_IDE_PCMCIA)
# include <pcmcia.h>
#endif
#ifdef CONFIG_MPC5xxx
#include <mpc5xxx.h>
#endif
#ifdef CONFIG_STATUS_LED
# include <status_led.h>
#endif
#ifdef CONFIG_IDE_8xx_DIRECT
DECLARE_GLOBAL_DATA_PTR;
#endif
#ifdef __PPC__
# define EIEIO __asm__ volatile ("eieio")
# define SYNC __asm__ volatile ("sync")
#else
# define EIEIO /* nothing */
# define SYNC /* nothing */
/* Timings for IDE Interface
*
* SETUP / LENGTH / HOLD - cycles valid for 50 MHz clk
* 70 165 30 PIO-Mode 0, [ns]
* 4 9 2 [Cycles]
* 50 125 20 PIO-Mode 1, [ns]
* 3 7 2 [Cycles]
* 30 100 15 PIO-Mode 2, [ns]
* 2 6 1 [Cycles]
* 30 80 10 PIO-Mode 3, [ns]
* 2 5 1 [Cycles]
* 25 70 10 PIO-Mode 4, [ns]
* 2 4 1 [Cycles]
*/
const static pio_config_t pio_config_ns [IDE_MAX_PIO_MODE+1] =
{
/* Setup Length Hold */
{ 70, 165, 30 }, /* PIO-Mode 0, [ns] */
{ 50, 125, 20 }, /* PIO-Mode 1, [ns] */
{ 30, 101, 15 }, /* PIO-Mode 2, [ns] */
{ 30, 80, 10 }, /* PIO-Mode 3, [ns] */
{ 25, 70, 10 }, /* PIO-Mode 4, [ns] */
};
static pio_config_t pio_config_clk [IDE_MAX_PIO_MODE+1];
#ifndef CONFIG_SYS_PIO_MODE
#define CONFIG_SYS_PIO_MODE 0 /* use a relaxed default */
static int pio_mode = CONFIG_SYS_PIO_MODE;
/* Make clock cycles and always round up */
#define PCMCIA_MK_CLKS( t, T ) (( (t) * (T) + 999U ) / 1000U )
#endif /* CONFIG_IDE_8xx_DIRECT */
/* ------------------------------------------------------------------------- */
/* Current I/O Device */
static int curr_device = -1;
/* Current offset for IDE0 / IDE1 bus access */
ulong ide_bus_offset[CONFIG_SYS_IDE_MAXBUS] = {
#if defined(CONFIG_SYS_ATA_IDE0_OFFSET)
CONFIG_SYS_ATA_IDE0_OFFSET,
#if defined(CONFIG_SYS_ATA_IDE1_OFFSET) && (CONFIG_SYS_IDE_MAXBUS > 1)
CONFIG_SYS_ATA_IDE1_OFFSET,
static int ide_bus_ok[CONFIG_SYS_IDE_MAXBUS];
static int ide_bus_ok[CONFIG_SYS_IDE_MAXBUS] = {0,};
block_dev_desc_t ide_dev_desc[CONFIG_SYS_IDE_MAXDEVICE];
/* ------------------------------------------------------------------------- */
#ifdef CONFIG_IDE_LED
#if !defined(CONFIG_KUP4K) && !defined(CONFIG_KUP4X) &&!defined(CONFIG_BMS2003) &&!defined(CONFIG_CPC45)
static void ide_led (uchar led, uchar status);
#else
extern void ide_led (uchar led, uchar status);
#endif
#else
#else
extern void ide_led(uchar led, uchar status);
#define LED_IDE1 1
#define LED_IDE2 2
#define CONFIG_IDE_LED 1
#define DEVICE_LED(x) 1
#endif
#endif
#ifdef CONFIG_IDE_RESET
static void ide_reset (void);
#else
#define ide_reset() /* dummy */
#endif
static void ide_ident (block_dev_desc_t *dev_desc);
static uchar ide_wait (int dev, ulong t);
#define IDE_TIME_OUT 2000 /* 2 sec timeout */
#define ATAPI_TIME_OUT 7000 /* 7 sec timeout (5 sec seems to work...) */
#define IDE_SPIN_UP_TIME_OUT 5000 /* 5 sec spin-up timeout */
static void input_data(int dev, ulong *sect_buf, int words);
static void output_data(int dev, ulong *sect_buf, int words);
static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len);
#ifndef CONFIG_SYS_ATA_PORT_ADDR
#define CONFIG_SYS_ATA_PORT_ADDR(port) (port)
#ifdef CONFIG_ATAPI
static void atapi_inquiry(block_dev_desc_t *dev_desc);
Grant Likely
committed
ulong atapi_read (int device, lbaint_t blknr, ulong blkcnt, void *buffer);
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
#endif
#ifdef CONFIG_IDE_8xx_DIRECT
static void set_pcmcia_timing (int pmode);
#endif
/* ------------------------------------------------------------------------- */
int do_ide (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
int rcode = 0;
switch (argc) {
case 0:
case 1:
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
case 2:
if (strncmp(argv[1],"res",3) == 0) {
puts ("\nReset IDE"
#ifdef CONFIG_IDE_8xx_DIRECT
" on PCMCIA " PCMCIA_SLOT_MSG
#endif
": ");
ide_init ();
return 0;
} else if (strncmp(argv[1],"inf",3) == 0) {
int i;
putc ('\n');
for (i=0; i<CONFIG_SYS_IDE_MAXDEVICE; ++i) {
if (ide_dev_desc[i].type==DEV_TYPE_UNKNOWN)
continue; /* list only known devices */
printf ("IDE device %d: ", i);
dev_print(&ide_dev_desc[i]);
}
return 0;
} else if (strncmp(argv[1],"dev",3) == 0) {
if ((curr_device < 0) || (curr_device >= CONFIG_SYS_IDE_MAXDEVICE)) {
puts ("\nno IDE devices available\n");
return 1;
}
printf ("\nIDE device %d: ", curr_device);
dev_print(&ide_dev_desc[curr_device]);
return 0;
} else if (strncmp(argv[1],"part",4) == 0) {
int dev, ok;
for (ok=0, dev=0; dev<CONFIG_SYS_IDE_MAXDEVICE; ++dev) {
if (ide_dev_desc[dev].part_type!=PART_TYPE_UNKNOWN) {
++ok;
if (dev)
putc ('\n');
print_part(&ide_dev_desc[dev]);
}
}
if (!ok) {
puts ("\nno IDE devices available\n");
rcode ++;
}
return rcode;
}
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
case 3:
if (strncmp(argv[1],"dev",3) == 0) {
int dev = (int)simple_strtoul(argv[2], NULL, 10);
printf ("\nIDE device %d: ", dev);
if (dev >= CONFIG_SYS_IDE_MAXDEVICE) {
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
puts ("unknown device\n");
return 1;
}
dev_print(&ide_dev_desc[dev]);
/*ide_print (dev);*/
if (ide_dev_desc[dev].type == DEV_TYPE_UNKNOWN) {
return 1;
}
curr_device = dev;
puts ("... is now current device\n");
return 0;
} else if (strncmp(argv[1],"part",4) == 0) {
int dev = (int)simple_strtoul(argv[2], NULL, 10);
if (ide_dev_desc[dev].part_type!=PART_TYPE_UNKNOWN) {
print_part(&ide_dev_desc[dev]);
} else {
printf ("\nIDE device %d not available\n", dev);
rcode = 1;
}
return rcode;
#if 0
} else if (strncmp(argv[1],"pio",4) == 0) {
int mode = (int)simple_strtoul(argv[2], NULL, 10);
if ((mode >= 0) && (mode <= IDE_MAX_PIO_MODE)) {
puts ("\nSetting ");
pio_mode = mode;
ide_init ();
} else {
printf ("\nInvalid PIO mode %d (0 ... %d only)\n",
mode, IDE_MAX_PIO_MODE);
}
return;
#endif
}
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
default:
/* at least 4 args */
if (strcmp(argv[1],"read") == 0) {
ulong addr = simple_strtoul(argv[2], NULL, 16);
ulong cnt = simple_strtoul(argv[4], NULL, 16);
ulong n;
#ifdef CONFIG_SYS_64BIT_LBA
lbaint_t blk = simple_strtoull(argv[3], NULL, 16);
printf ("\nIDE read: device %d block # %qd, count %ld ... ",
#else
lbaint_t blk = simple_strtoul(argv[3], NULL, 16);
printf ("\nIDE read: device %d block # %ld, count %ld ... ",
curr_device, blk, cnt);
#endif
n = ide_dev_desc[curr_device].block_read (curr_device,
blk, cnt,
(ulong *)addr);
/* flush cache after read */
flush_cache (addr, cnt*ide_dev_desc[curr_device].blksz);
printf ("%ld blocks read: %s\n",
n, (n==cnt) ? "OK" : "ERROR");
if (n==cnt) {
return 0;
} else {
return 1;
}
} else if (strcmp(argv[1],"write") == 0) {
ulong addr = simple_strtoul(argv[2], NULL, 16);
ulong cnt = simple_strtoul(argv[4], NULL, 16);
ulong n;
#ifdef CONFIG_SYS_64BIT_LBA
lbaint_t blk = simple_strtoull(argv[3], NULL, 16);
printf ("\nIDE write: device %d block # %qd, count %ld ... ",
#else
lbaint_t blk = simple_strtoul(argv[3], NULL, 16);
printf ("\nIDE write: device %d block # %ld, count %ld ... ",
curr_device, blk, cnt);
#endif
n = ide_write (curr_device, blk, cnt, (ulong *)addr);
printf ("%ld blocks written: %s\n",
n, (n==cnt) ? "OK" : "ERROR");
if (n==cnt) {
return 0;
} else {
return 1;
}
} else {
printf ("Usage:\n%s\n", cmdtp->usage);
rcode = 1;
}
return rcode;
}
}
int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
char *boot_device = NULL;
char *ep;
int dev, part = 0;
ulong addr, cnt;
disk_partition_t info;
image_header_t *hdr;
int rcode = 0;
Marian Balakowicz
committed
#if defined(CONFIG_FIT)
const void *fit_hdr = NULL;
Marian Balakowicz
committed
#endif
addr = CONFIG_SYS_LOAD_ADDR;
boot_device = getenv ("bootdevice");
break;
case 2:
addr = simple_strtoul(argv[1], NULL, 16);
boot_device = getenv ("bootdevice");
break;
case 3:
addr = simple_strtoul(argv[1], NULL, 16);
boot_device = argv[2];
break;
default:
printf ("Usage:\n%s\n", cmdtp->usage);
if (!boot_device) {
puts ("\n** No boot device **\n");
dev = simple_strtoul(boot_device, &ep, 16);
if (ide_dev_desc[dev].type==DEV_TYPE_UNKNOWN) {
printf ("\n** Device %d not available\n", dev);
if (*ep) {
if (*ep != ':') {
puts ("\n** Invalid boot device, use `dev[:part]' **\n");
return 1;
}
part = simple_strtoul(++ep, NULL, 16);
}
if (get_partition_info (&ide_dev_desc[dev], part, &info)) {
if ((strncmp((char *)info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) &&
(strncmp((char *)info.type, BOOT_PART_COMP, sizeof(info.type)) != 0)) {
printf ("\n** Invalid partition type \"%.32s\""
" (expect \"" BOOT_PART_TYPE "\")\n",
info.type);
printf ("\nLoading from IDE device %d, partition %d: "
"Name: %.32s Type: %.32s\n",
dev, part, info.name, info.type);
debug ("First Block: %ld, # of blocks: %ld, Block Size: %ld\n",
info.start, info.size, info.blksz);
if (ide_dev_desc[dev].block_read (dev, info.start, 1, (ulong *)addr) != 1) {
printf ("** Read error on %d:%d\n", dev, part);
switch (genimg_get_format ((void *)addr)) {
case IMAGE_FORMAT_LEGACY:
hdr = (image_header_t *)addr;
show_boot_progress (49);
if (!image_check_hcrc (hdr)) {
puts ("\n** Bad Header Checksum **\n");
show_boot_progress (-50);
return 1;
}
show_boot_progress (50);
image_print_contents (hdr);
cnt = image_get_image_size (hdr);
break;
#if defined(CONFIG_FIT)
case IMAGE_FORMAT_FIT:
Marian Balakowicz
committed
fit_hdr = (const void *)addr;
puts ("Fit image detected...\n");
cnt = fit_get_size (fit_hdr);
break;
#endif
default:
Marian Balakowicz
committed
show_boot_progress (-49);
puts ("** Unknown image type\n");
return 1;
}
cnt += info.blksz - 1;
cnt /= info.blksz;
cnt -= 1;
if (ide_dev_desc[dev].block_read (dev, info.start+1, cnt,
(ulong *)(addr+info.blksz)) != cnt) {
printf ("** Read error on %d:%d\n", dev, part);
Marian Balakowicz
committed
#if defined(CONFIG_FIT)
/* This cannot be done earlier, we need complete FIT image in RAM first */
if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) {
if (!fit_check_format (fit_hdr)) {
show_boot_progress (-140);
puts ("** Bad FIT image format\n");
return 1;
}
show_boot_progress (141);
fit_print_contents (fit_hdr);
}
Marian Balakowicz
committed
#endif
/* Loading ok, update default load address */
load_addr = addr;
/* Check if we should attempt an auto-start */
if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {
char *local_args[2];
extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
local_args[0] = argv[0];
local_args[1] = NULL;
printf ("Automatic boot of image at addr 0x%08lX ...\n", addr);
do_bootm (cmdtp, 0, 1, local_args);
rcode = 1;
}
return rcode;
}
/* ------------------------------------------------------------------------- */
void inline
__ide_outb(int dev, int port, unsigned char val)
{
debug ("ide_outb (dev= %d, port= 0x%x, val= 0x%02x) : @ 0x%08lx\n",
dev, port, val, (ATA_CURR_BASE(dev)+CONFIG_SYS_ATA_PORT_ADDR(port)));
outb(val, (ATA_CURR_BASE(dev)+CONFIG_SYS_ATA_PORT_ADDR(port)));
}
void inline ide_outb (int dev, int port, unsigned char val)
__attribute__((weak, alias("__ide_outb")));
unsigned char inline
__ide_inb(int dev, int port)
{
uchar val;
val = inb((ATA_CURR_BASE(dev)+CONFIG_SYS_ATA_PORT_ADDR(port)));
debug ("ide_inb (dev= %d, port= 0x%x) : @ 0x%08lx -> 0x%02x\n",
dev, port, (ATA_CURR_BASE(dev)+CONFIG_SYS_ATA_PORT_ADDR(port)), val);
return val;
}
unsigned char inline ide_inb(int dev, int port)
__attribute__((weak, alias("__ide_inb")));
#ifdef CONFIG_TUNE_PIO
int inline
__ide_set_piomode(int pio_mode)
{
return 0;
}
int inline ide_set_piomode(int pio_mode)
__attribute__((weak, alias("__ide_set_piomode")));
#endif
void ide_init (void)
{
#ifdef CONFIG_IDE_8xx_DIRECT
volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
volatile pcmconf8xx_t *pcmp = &(immr->im_pcmcia);
#endif
unsigned char c;
int i, bus;
#if defined(CONFIG_AMIGAONEG3SE) || defined(CONFIG_SC3)
unsigned int ata_reset_time = ATA_RESET_TIME;
char *s;
#ifdef CONFIG_AMIGAONEG3SE
unsigned int max_bus_scan;
#endif
#ifdef CONFIG_IDE_8xx_PCCARD
extern int pcmcia_on (void);
extern int ide_devices_found; /* Initialized in check_ide_device() */
#endif /* CONFIG_IDE_8xx_PCCARD */
#ifdef CONFIG_IDE_PREINIT
WATCHDOG_RESET();
if (ide_preinit ()) {
puts ("ide_preinit failed\n");
return;
}
#endif /* CONFIG_IDE_PREINIT */
#ifdef CONFIG_IDE_8xx_PCCARD
extern int pcmcia_on (void);
extern int ide_devices_found; /* Initialized in check_ide_device() */
ide_devices_found = 0;
pcmcia_on();
if (!ide_devices_found)
return;
udelay (1000000); /* 1 s */
#endif /* CONFIG_IDE_8xx_PCCARD */
WATCHDOG_RESET();
/* Initialize PIO timing tables */
for (i=0; i <= IDE_MAX_PIO_MODE; ++i) {
pio_config_clk[i].t_setup = PCMCIA_MK_CLKS(pio_config_ns[i].t_setup,
gd->bus_clk);
pio_config_clk[i].t_length = PCMCIA_MK_CLKS(pio_config_ns[i].t_length,
gd->bus_clk);
pio_config_clk[i].t_hold = PCMCIA_MK_CLKS(pio_config_ns[i].t_hold,
gd->bus_clk);
debug ( "PIO Mode %d: setup=%2d ns/%d clk"
" len=%3d ns/%d clk"
" hold=%2d ns/%d clk\n",
i,
pio_config_ns[i].t_setup, pio_config_clk[i].t_setup,
pio_config_ns[i].t_length, pio_config_clk[i].t_length,
pio_config_ns[i].t_hold, pio_config_clk[i].t_hold);
#endif /* CONFIG_IDE_8xx_DIRECT */
/* Reset the IDE just to be sure.
* Light LED's to show
*/
ide_led ((LED_IDE1 | LED_IDE2), 1); /* LED's on */
ide_reset (); /* ATAPI Drives seems to need a proper IDE Reset */
#ifdef CONFIG_IDE_8xx_DIRECT
/* PCMCIA / IDE initialization for common mem space */
pcmp->pcmc_pgcrb = 0;
/* start in PIO mode 0 - most relaxed timings */
pio_mode = 0;
set_pcmcia_timing (pio_mode);
#endif /* CONFIG_IDE_8xx_DIRECT */
/*
* Wait for IDE to get ready.
* According to spec, this can take up to 31 seconds!
*/
for (bus=0; bus<CONFIG_SYS_IDE_MAXBUS; ++bus) {
int dev = bus * (CONFIG_SYS_IDE_MAXDEVICE / CONFIG_SYS_IDE_MAXBUS);
#else
s = getenv("ide_maxbus");
if (s)
max_bus_scan = simple_strtol(s, NULL, 10);
max_bus_scan = CONFIG_SYS_IDE_MAXBUS;
for (bus=0; bus<max_bus_scan; ++bus) {
int dev = bus * (CONFIG_SYS_IDE_MAXDEVICE / max_bus_scan);
#ifdef CONFIG_IDE_8xx_PCCARD
/* Skip non-ide devices from probing */
if ((ide_devices_found & (1 << bus)) == 0) {
ide_led ((LED_IDE1 | LED_IDE2), 0); /* LED's off */
continue;
}
#endif
printf ("Bus %d: ", bus);
ide_bus_ok[bus] = 0;
/* Select device
*/
udelay (100000); /* 100 ms */
ide_outb (dev, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(dev));
#if defined(CONFIG_AMIGAONEG3SE) || defined(CONFIG_SC3)
if ((s = getenv("ide_reset_timeout")) != NULL)
ata_reset_time = simple_strtol(s, NULL, 10);
#if defined(CONFIG_AMIGAONEG3SE) || defined(CONFIG_SC3)
if (i > (ata_reset_time * 100)) {
#else
puts ("** Timeout **\n");
ide_led ((LED_IDE1 | LED_IDE2), 0); /* LED's off */
#ifdef CONFIG_AMIGAONEG3SE
/* If this is the second bus, the first one was OK */
ide_bus_ok[bus] = 0;
goto skip_bus;
return;
}
if ((i >= 100) && ((i%100)==0)) {
putc ('.');
}
} while (c & ATA_STAT_BUSY);
if (c & (ATA_STAT_BUSY | ATA_STAT_FAULT)) {
puts ("not available ");
debug ("Status = 0x%02X ", c);
#ifndef CONFIG_ATAPI /* ATAPI Devices do not set DRDY */
} else if ((c & ATA_STAT_READY) == 0) {
puts ("not available ");
debug ("Status = 0x%02X ", c);
#endif
} else {
puts ("OK ");
ide_bus_ok[bus] = 1;
}
WATCHDOG_RESET();
}
#ifdef CONFIG_AMIGAONEG3SE
skip_bus:
#endif
putc ('\n');
ide_led ((LED_IDE1 | LED_IDE2), 0); /* LED's off */
curr_device = -1;
for (i=0; i<CONFIG_SYS_IDE_MAXDEVICE; ++i) {
#ifdef CONFIG_IDE_LED
int led = (IDE_BUS(i) == 0) ? LED_IDE1 : LED_IDE2;
#endif
ide_dev_desc[i].type=DEV_TYPE_UNKNOWN;
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
ide_dev_desc[i].if_type=IF_TYPE_IDE;
ide_dev_desc[i].dev=i;
ide_dev_desc[i].part_type=PART_TYPE_UNKNOWN;
ide_dev_desc[i].blksz=0;
ide_dev_desc[i].lba=0;
ide_dev_desc[i].block_read=ide_read;
if (!ide_bus_ok[IDE_BUS(i)])
continue;
ide_led (led, 1); /* LED on */
ide_ident(&ide_dev_desc[i]);
ide_led (led, 0); /* LED off */
dev_print(&ide_dev_desc[i]);
/* ide_print (i); */
if ((ide_dev_desc[i].lba > 0) && (ide_dev_desc[i].blksz > 0)) {
init_part (&ide_dev_desc[i]); /* initialize partition type */
if (curr_device < 0)
curr_device = i;
}
}
WATCHDOG_RESET();
}
/* ------------------------------------------------------------------------- */
block_dev_desc_t * ide_get_dev(int dev)
{
return (dev < CONFIG_SYS_IDE_MAXDEVICE) ? &ide_dev_desc[dev] : NULL;
}
#ifdef CONFIG_IDE_8xx_DIRECT
static void
set_pcmcia_timing (int pmode)
{
volatile immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
volatile pcmconf8xx_t *pcmp = &(immr->im_pcmcia);
ulong timings;
debug ("Set timing for PIO Mode %d\n", pmode);
timings = PCMCIA_SHT(pio_config_clk[pmode].t_hold)
| PCMCIA_SST(pio_config_clk[pmode].t_setup)
| PCMCIA_SL (pio_config_clk[pmode].t_length)
;
/* IDE 0
*/
pcmp->pcmc_pbr0 = CONFIG_SYS_PCMCIA_PBR0;
pcmp->pcmc_por0 = CONFIG_SYS_PCMCIA_POR0
#if (CONFIG_SYS_PCMCIA_POR0 != 0)
debug ("PBR0: %08x POR0: %08x\n", pcmp->pcmc_pbr0, pcmp->pcmc_por0);
pcmp->pcmc_pbr1 = CONFIG_SYS_PCMCIA_PBR1;
pcmp->pcmc_por1 = CONFIG_SYS_PCMCIA_POR1
#if (CONFIG_SYS_PCMCIA_POR1 != 0)
debug ("PBR1: %08x POR1: %08x\n", pcmp->pcmc_pbr1, pcmp->pcmc_por1);
pcmp->pcmc_pbr2 = CONFIG_SYS_PCMCIA_PBR2;
pcmp->pcmc_por2 = CONFIG_SYS_PCMCIA_POR2
#if (CONFIG_SYS_PCMCIA_POR2 != 0)
debug ("PBR2: %08x POR2: %08x\n", pcmp->pcmc_pbr2, pcmp->pcmc_por2);
pcmp->pcmc_pbr3 = CONFIG_SYS_PCMCIA_PBR3;
pcmp->pcmc_por3 = CONFIG_SYS_PCMCIA_POR3
#if (CONFIG_SYS_PCMCIA_POR3 != 0)
debug ("PBR3: %08x POR3: %08x\n", pcmp->pcmc_pbr3, pcmp->pcmc_por3);
pcmp->pcmc_pbr4 = CONFIG_SYS_PCMCIA_PBR4;
pcmp->pcmc_por4 = CONFIG_SYS_PCMCIA_POR4
#if (CONFIG_SYS_PCMCIA_POR4 != 0)
debug ("PBR4: %08x POR4: %08x\n", pcmp->pcmc_pbr4, pcmp->pcmc_por4);
pcmp->pcmc_pbr5 = CONFIG_SYS_PCMCIA_PBR5;
pcmp->pcmc_por5 = CONFIG_SYS_PCMCIA_POR5
#if (CONFIG_SYS_PCMCIA_POR5 != 0)
debug ("PBR5: %08x POR5: %08x\n", pcmp->pcmc_pbr5, pcmp->pcmc_por5);
pcmp->pcmc_pbr6 = CONFIG_SYS_PCMCIA_PBR6;
pcmp->pcmc_por6 = CONFIG_SYS_PCMCIA_POR6
#if (CONFIG_SYS_PCMCIA_POR6 != 0)
debug ("PBR6: %08x POR6: %08x\n", pcmp->pcmc_pbr6, pcmp->pcmc_por6);
pcmp->pcmc_pbr7 = CONFIG_SYS_PCMCIA_PBR7;
pcmp->pcmc_por7 = CONFIG_SYS_PCMCIA_POR7
#if (CONFIG_SYS_PCMCIA_POR7 != 0)
debug ("PBR7: %08x POR7: %08x\n", pcmp->pcmc_pbr7, pcmp->pcmc_por7);
}
#endif /* CONFIG_IDE_8xx_DIRECT */
/* ------------------------------------------------------------------------- */
static void
output_data_short(int dev, ulong *sect_buf, int words)
{
ushort *dbuf;
volatile ushort *pbuf;
pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
dbuf = (ushort *)sect_buf;
while (words--) {
EIEIO;
EIEIO;
*pbuf = 0;
# endif /* CONFIG_AMIGAONEG3SE */
/* We only need to swap data if we are running on a big endian cpu. */
/* But Au1x00 cpu:s already swaps data in big endian mode! */
#if defined(__LITTLE_ENDIAN) || ( defined(CONFIG_AU1X00) && !defined(CONFIG_GTH2) )
#define input_swap_data(x,y,z) input_data(x,y,z)
#else
static void
input_swap_data(int dev, ulong *sect_buf, int words)
{
#if defined(CONFIG_HMI10) || defined(CONFIG_CPC45)
uchar i;
volatile uchar *pbuf_even = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_EVEN);
volatile uchar *pbuf_odd = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_ODD);
ushort *dbuf = (ushort *)sect_buf;
while (words--) {
for (i=0; i<2; i++) {
*(((uchar *)(dbuf)) + 1) = *pbuf_even;
*(uchar *)dbuf = *pbuf_odd;
dbuf+=1;
}
}
volatile ushort *pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
ushort *dbuf = (ushort *)sect_buf;
debug("in input swap data base for read is %lx\n", (unsigned long) pbuf);
while (words--) {
#ifdef __MIPS__
*dbuf++ = swab16p((u16*)pbuf);
*dbuf++ = swab16p((u16*)pbuf);
#elif defined(CONFIG_PCS440EP)
*dbuf++ = *pbuf;
*dbuf++ = *pbuf;
*dbuf++ = ld_le16(pbuf);
*dbuf++ = ld_le16(pbuf);
}
#endif
#endif /* __LITTLE_ENDIAN || CONFIG_AU1X00 */
#if defined(__PPC__) || defined(CONFIG_PXA_PCMCIA) || defined(CONFIG_SH)
static void
output_data(int dev, ulong *sect_buf, int words)
{
#if defined(CONFIG_HMI10) || defined(CONFIG_CPC45)
uchar *dbuf;
volatile uchar *pbuf_even;
volatile uchar *pbuf_odd;
pbuf_even = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_EVEN);
pbuf_odd = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_ODD);
dbuf = (uchar *)sect_buf;
while (words--) {
EIEIO;
*pbuf_even = *dbuf++;
EIEIO;
*pbuf_odd = *dbuf++;
EIEIO;
*pbuf_even = *dbuf++;
EIEIO;
*pbuf_odd = *dbuf++;
}
#else
ushort *dbuf;
volatile ushort *pbuf;
pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
dbuf = (ushort *)sect_buf;
while (words--) {
#if defined(CONFIG_PCS440EP)
/* not tested, because CF was write protected */
EIEIO;
*pbuf = ld_le16(dbuf++);
EIEIO;
*pbuf = ld_le16(dbuf++);
#else
EIEIO;
*pbuf = *dbuf++;
EIEIO;
*pbuf = *dbuf++;
}
#endif
#else /* ! __PPC__ */
static void
output_data(int dev, ulong *sect_buf, int words)
{
outsw(ATA_CURR_BASE(dev)+ATA_DATA_REG, sect_buf, words<<1);
#if defined(__PPC__) || defined(CONFIG_PXA_PCMCIA) || defined(CONFIG_SH)
static void
input_data(int dev, ulong *sect_buf, int words)
{
#if defined(CONFIG_HMI10) || defined(CONFIG_CPC45)
uchar *dbuf;
volatile uchar *pbuf_even;
volatile uchar *pbuf_odd;
pbuf_even = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_EVEN);
pbuf_odd = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_ODD);
dbuf = (uchar *)sect_buf;
while (words--) {
*dbuf++ = *pbuf_even;
SYNC;
*dbuf++ = *pbuf_odd;
EIEIO;
*dbuf++ = *pbuf_even;
EIEIO;
*dbuf++ = *pbuf_odd;
EIEIO;