]> git.sur5r.net Git - u-boot/blobdiff - drivers/block/ahci.c
macb: simplify gmac initialisation
[u-boot] / drivers / block / ahci.c
index a409f63770473e5c3a83039d42e67ed5640a2363..dce99adc6b58cfbcf00530c0d84c1963357a5aaf 100644 (file)
@@ -41,7 +41,7 @@ u16 *ataid[AHCI_MAX_PORTS];
 #define WAIT_MS_SPINUP 20000
 #define WAIT_MS_DATAIO 5000
 #define WAIT_MS_FLUSH  5000
-#define WAIT_MS_LINKUP 40
+#define WAIT_MS_LINKUP 200
 
 static inline u32 ahci_port_base(u32 base, u32 port)
 {
@@ -129,6 +129,14 @@ int __weak ahci_link_up(struct ahci_probe_ent *probe_ent, u8 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
@@ -213,6 +221,10 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
                        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.
                 */
@@ -545,6 +557,10 @@ static int ahci_port_start(u8 port)
 
        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);
@@ -623,6 +639,7 @@ static int ata_scsiop_inquiry(ccb *pccb)
                95 - 4,
        };
        u8 fis[20];
+       u16 *idbuf;
        ALLOC_CACHE_ALIGN_BUFFER(u16, tmpid, ATA_ID_WORDS);
        u8 port;
 
@@ -649,17 +666,25 @@ static int ata_scsiop_inquiry(ccb *pccb)
                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;
 }