#define WAIT_MS_SPINUP 20000
#define WAIT_MS_DATAIO 5000
#define WAIT_MS_FLUSH 5000
-#define WAIT_MS_LINKUP 4
+#define WAIT_MS_LINKUP 200
static inline u32 ahci_port_base(u32 base, u32 port)
{
return 1;
}
+#ifdef CONFIG_SUNXI_AHCI
+/* The sunxi AHCI controller requires this undocumented setup */
+static void sunxi_dma_init(volatile u8 *port_mmio)
+{
+ clrsetbits_le32(port_mmio + PORT_P0DMACR, 0x0000ff00, 0x00004400);
+}
+#endif
+
static int ahci_host_init(struct ahci_probe_ent *probe_ent)
{
#ifndef CONFIG_SCSI_AHCI_PLAT
msleep(500);
}
+#ifdef CONFIG_SUNXI_AHCI
+ sunxi_dma_init(port_mmio);
+#endif
+
/* Add the spinup command to whatever mode bits may
* already be on in the command register.
*/
writel_with_flush(pp->rx_fis, port_mmio + PORT_FIS_ADDR);
+#ifdef CONFIG_SUNXI_AHCI
+ sunxi_dma_init(port_mmio);
+#endif
+
writel_with_flush(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX |
PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP |
PORT_CMD_START, port_mmio + PORT_CMD);
95 - 4,
};
u8 fis[20];
+ u16 *idbuf;
ALLOC_CACHE_ALIGN_BUFFER(u16, tmpid, ATA_ID_WORDS);
u8 port;
return -EIO;
}
- if (ataid[port])
- free(ataid[port]);
- ataid[port] = tmpid;
- ata_swap_buf_le16(tmpid, ATA_ID_WORDS);
+ if (!ataid[port]) {
+ ataid[port] = malloc(ATA_ID_WORDS * 2);
+ if (!ataid[port]) {
+ printf("%s: No memory for ataid[port]\n", __func__);
+ return -ENOMEM;
+ }
+ }
+
+ idbuf = ataid[port];
+
+ memcpy(idbuf, tmpid, ATA_ID_WORDS * 2);
+ ata_swap_buf_le16(idbuf, ATA_ID_WORDS);
memcpy(&pccb->pdata[8], "ATA ", 8);
- ata_id_strcpy((u16 *) &pccb->pdata[16], &tmpid[ATA_ID_PROD], 16);
- ata_id_strcpy((u16 *) &pccb->pdata[32], &tmpid[ATA_ID_FW_REV], 4);
+ ata_id_strcpy((u16 *)&pccb->pdata[16], &idbuf[ATA_ID_PROD], 16);
+ ata_id_strcpy((u16 *)&pccb->pdata[32], &idbuf[ATA_ID_FW_REV], 4);
#ifdef DEBUG
- ata_dump_id(tmpid);
+ ata_dump_id(idbuf);
#endif
return 0;
}