diff options
author | Wolfgang Denk <wd@denx.de> | 2010-10-13 20:59:47 +0200 |
---|---|---|
committer | Wolfgang Denk <wd@denx.de> | 2010-10-13 20:59:47 +0200 |
commit | e1b4c57096b87b4ada56df4154d9acee6a59141f (patch) | |
tree | 4d1ab61fd347a63410bcffc1ac2d85beeb247058 /drivers/block/mvsata_ide.c | |
parent | da61f6c45ad4a126bf0a9a8184fadc13073ecb3f (diff) | |
parent | 89bca0ab697fc75160dd0d685d7cb2ed26609a6d (diff) | |
download | u-boot-imx-e1b4c57096b87b4ada56df4154d9acee6a59141f.zip u-boot-imx-e1b4c57096b87b4ada56df4154d9acee6a59141f.tar.gz u-boot-imx-e1b4c57096b87b4ada56df4154d9acee6a59141f.tar.bz2 |
Merge branch 'master' of git://git.denx.de/u-boot-arm
Diffstat (limited to 'drivers/block/mvsata_ide.c')
-rw-r--r-- | drivers/block/mvsata_ide.c | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/drivers/block/mvsata_ide.c b/drivers/block/mvsata_ide.c index 077b278..3d6993a 100644 --- a/drivers/block/mvsata_ide.c +++ b/drivers/block/mvsata_ide.c @@ -91,29 +91,48 @@ struct mvsata_port_registers { #define MVSATA_SSTATUS_DET_DEVCOMM 0x00000003 /* + * Status codes to return to client callers. Currently, callers ignore + * exact value and only care for zero or nonzero, so no need to make this + * public, it is only #define'd for clarity. + * If/when standard negative codes are implemented in U-boot, then these + * #defines should be moved to, or replaced by ones from, the common list + * of status codes. + */ + +#define MVSATA_STATUS_OK 0 +#define MVSATA_STATUS_TIMEOUT -1 + +/* * Initialize one MVSATAHC port: set SControl's IPM to "always active" * and DET to "reset", then wait for SStatus's DET to become "device and * comm ok" (or time out after 50 us if no device), then set SControl's * DET back to "no action". */ -static void mvsata_ide_initialize_port(struct mvsata_port_registers *port) +static int mvsata_ide_initialize_port(struct mvsata_port_registers *port) { u32 control; u32 status; - u32 tout = 50; /* wait at most 50 us for SATA reset to complete */ + u32 timeleft = 10000; /* wait at most 10 ms for SATA reset to complete */ + /* Set control IPM to 3 (no low power) and DET to 1 (initialize) */ control = readl(&port->scontrol); control = (control & ~MVSATA_SCONTROL_MASK) | MVSATA_PORT_INIT; writel(control, &port->scontrol); - while (--tout) { + /* Toggle control DET back to 0 (normal operation) */ + control = (control & ~MVSATA_SCONTROL_MASK) | MVSATA_PORT_USE; + writel(control, &port->scontrol); + /* wait for status DET to become 3 (device and communication OK) */ + while (--timeleft) { status = readl(&port->sstatus) & MVSATA_SSTATUS_DET_MASK; if (status == MVSATA_SSTATUS_DET_DEVCOMM) break; udelay(1); } - control = (control & ~MVSATA_SCONTROL_MASK) | MVSATA_PORT_USE; - writel(control, &port->scontrol); + /* return success or time-out error depending on time left */ + if (!timeleft) + return MVSATA_STATUS_TIMEOUT; + return MVSATA_STATUS_OK; } /* @@ -123,18 +142,23 @@ static void mvsata_ide_initialize_port(struct mvsata_port_registers *port) int ide_preinit(void) { + int status; /* Enable ATA port 0 (could be SATA port 0 or 1) if declared */ #if defined(CONFIG_SYS_ATA_IDE0_OFFSET) - mvsata_ide_initialize_port( + status = mvsata_ide_initialize_port( (struct mvsata_port_registers *) (CONFIG_SYS_ATA_BASE_ADDR + CONFIG_SYS_ATA_IDE0_OFFSET)); + if (status) + return status; #endif /* Enable ATA port 1 (could be SATA port 0 or 1) if declared */ #if defined(CONFIG_SYS_ATA_IDE1_OFFSET) - mvsata_ide_initialize_port( + status = mvsata_ide_initialize_port( (struct mvsata_port_registers *) (CONFIG_SYS_ATA_BASE_ADDR + CONFIG_SYS_ATA_IDE1_OFFSET)); + if (status) + return status; #endif - /* return 0 as we always succeed */ - return 0; + /* return success if all ports initializations succeeded */ + return MVSATA_STATUS_OK; } |