mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-24 16:11:33 +00:00
ahci: Support spin-up and link-up separately
Add HDD handling to the SSD-only AHCI driver, by separately dealing with spin-up and link-up. Signed-off-by: Marc Jones <marc.jones@chromium.org> Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
57847660bb
commit
2a0c61d401
1 changed files with 38 additions and 5 deletions
|
@ -53,6 +53,7 @@ hd_driveid_t *ataid[AHCI_MAX_PORTS];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Maximum timeouts for each event */
|
/* Maximum timeouts for each event */
|
||||||
|
#define WAIT_MS_SPINUP 10000
|
||||||
#define WAIT_MS_DATAIO 5000
|
#define WAIT_MS_DATAIO 5000
|
||||||
#define WAIT_MS_LINKUP 4
|
#define WAIT_MS_LINKUP 4
|
||||||
|
|
||||||
|
@ -129,7 +130,7 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
|
||||||
unsigned short vendor;
|
unsigned short vendor;
|
||||||
#endif
|
#endif
|
||||||
volatile u8 *mmio = (volatile u8 *)probe_ent->mmio_base;
|
volatile u8 *mmio = (volatile u8 *)probe_ent->mmio_base;
|
||||||
u32 tmp, cap_save;
|
u32 tmp, cap_save, cmd;
|
||||||
int i, j;
|
int i, j;
|
||||||
volatile u8 *port_mmio;
|
volatile u8 *port_mmio;
|
||||||
|
|
||||||
|
@ -137,7 +138,7 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
|
||||||
|
|
||||||
cap_save = readl(mmio + HOST_CAP);
|
cap_save = readl(mmio + HOST_CAP);
|
||||||
cap_save &= ((1 << 28) | (1 << 17));
|
cap_save &= ((1 << 28) | (1 << 17));
|
||||||
cap_save |= (1 << 27);
|
cap_save |= (1 << 27); /* Staggered Spin-up. Not needed. */
|
||||||
|
|
||||||
/* global controller reset */
|
/* global controller reset */
|
||||||
tmp = readl(mmio + HOST_CTL);
|
tmp = readl(mmio + HOST_CTL);
|
||||||
|
@ -201,9 +202,18 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
|
||||||
msleep(500);
|
msleep(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug("Spinning up port %d... ", i);
|
/* Add the spinup command to whatever mode bits may
|
||||||
writel(PORT_CMD_SPIN_UP, port_mmio + PORT_CMD);
|
* already be on in the command register.
|
||||||
|
*/
|
||||||
|
cmd = readl(port_mmio + PORT_CMD);
|
||||||
|
cmd |= PORT_CMD_FIS_RX;
|
||||||
|
cmd |= PORT_CMD_SPIN_UP;
|
||||||
|
writel_with_flush(cmd, port_mmio + PORT_CMD);
|
||||||
|
|
||||||
|
/* Bring up SATA link.
|
||||||
|
* SATA link bringup time is usually less than 1 ms; only very
|
||||||
|
* rarely has it taken between 1-2 ms. Never seen it above 2 ms.
|
||||||
|
*/
|
||||||
j = 0;
|
j = 0;
|
||||||
while (j < WAIT_MS_LINKUP) {
|
while (j < WAIT_MS_LINKUP) {
|
||||||
tmp = readl(port_mmio + PORT_SCR_STAT);
|
tmp = readl(port_mmio + PORT_SCR_STAT);
|
||||||
|
@ -212,7 +222,30 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
|
||||||
udelay(1000);
|
udelay(1000);
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
if (j == WAIT_MS_LINKUP)
|
if (j == WAIT_MS_LINKUP) {
|
||||||
|
printf("SATA link %d timeout.\n", i);
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
debug("SATA link ok.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear error status */
|
||||||
|
tmp = readl(port_mmio + PORT_SCR_ERR);
|
||||||
|
if (tmp)
|
||||||
|
writel(tmp, port_mmio + PORT_SCR_ERR);
|
||||||
|
|
||||||
|
debug("Spinning up device on SATA port %d... ", i);
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
while (j < WAIT_MS_SPINUP) {
|
||||||
|
tmp = readl(port_mmio + PORT_TFDATA);
|
||||||
|
if (!(tmp & (ATA_STAT_BUSY | ATA_STAT_DRQ)))
|
||||||
|
break;
|
||||||
|
udelay(1000);
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
printf("Target spinup took %d ms.\n", j);
|
||||||
|
if (j == WAIT_MS_SPINUP)
|
||||||
debug("timeout.\n");
|
debug("timeout.\n");
|
||||||
else
|
else
|
||||||
debug("ok.\n");
|
debug("ok.\n");
|
||||||
|
|
Loading…
Add table
Reference in a new issue