diff --git a/Targets/LS2K/ls2k/start.S b/Targets/LS2K/ls2k/start.S index bfc57e7f..ac733a0b 100644 --- a/Targets/LS2K/ls2k/start.S +++ b/Targets/LS2K/ls2k/start.S @@ -1159,6 +1159,37 @@ pcie_cfg_done: sw t2,0x14(t1) #endif 2: +#ifdef CONFIG_LS2K_FIX_SATA_PHY + li t0, 0xbfe10000 + + //power down phy + lw t1, 0x454(t0) + li t2, (1 << 31) + or t1, t1, t2 + sw t1, 0x454(t0) + + //delay a while + li t1, 0x1000 + 1: + subu t1, t1, 1 + bnez t1, 1b + nop + + li t0, 0xbfe10000 + //power up phy + lw t1, 0x454(t0) + li t2, (1 << 31) + not t2, t2 + and t1, t1, t2 + sw t1, 0x454(t0) + + //delay a while + li t1, 0x10000 + 1: + subu t1, t1, 1 + bnez t1, 1b + nop +#endif #if 1 /* Config SATA : use internel clock */ li t0, 0xbfe10000 @@ -1267,6 +1298,35 @@ pcie_cfg_done: sd t1, 0x0(t0) #endif +#ifdef CONFIG_LS2K_FIX_SATA_PHY + //power down phy + lw t1, 0x454(t0) + li t2, (1 << 31) + or t1, t1, t2 + sw t1, 0x454(t0) + + //delay a while + li t1, 0x1000 + 1: + subu t1, t1, 1 + bnez t1, 1b + nop + + li t0, 0xbfe10000 + //power up phy + lw t1, 0x454(t0) + li t2, (1 << 31) + not t2, t2 + and t1, t1, t2 + sw t1, 0x454(t0) + + //delay a while + li t1, 0x10000 + 1: + subu t1, t1, 1 + bnez t1, 1b + nop +#endif #if 1 // Fix the Gmac0 multi-func to enable Gmac1 li t0, 0xbfe13800 diff --git a/sys/dev/pci/ahci.c b/sys/dev/pci/ahci.c index 1f99a132..a4f6b505 100755 --- a/sys/dev/pci/ahci.c +++ b/sys/dev/pci/ahci.c @@ -270,7 +270,11 @@ int ahci_link_up(struct ahci_probe_ent *probe_ent, u8 port) int ahci_reset(void *base) { +#ifdef CONFIG_LS2K_FIX_SATA_PHY + int i = 2000; +#else int i = 1000; +#endif u32 *host_ctl_reg = base + HOST_CTL; u32 tmp = readl(host_ctl_reg); /* global controller reset */ @@ -425,6 +429,10 @@ int ahci_host_init(struct ahci_probe_ent *probe_ent) debug("SATA port %d status: 0x%x\n", i, tmp); if ((tmp & PORT_SCR_STAT_DET_MASK) == PORT_SCR_STAT_DET_PHYRDY) probe_ent->link_port_map |= (0x01 << i); +#ifdef CONFIG_LS2K_FIX_SATA_PHY + else + return 1; +#endif } tmp = readl(mmio + HOST_CTL); @@ -505,7 +513,35 @@ static void *ahci_init_one(u32 regbase) /* initialize adapter */ rc = ahci_host_init(probe_ent); if (rc) +#ifndef CONFIG_LS2K_FIX_SATA_PHY goto err_out; +#else + { + *(volatile unsigned int *)(0xbfe10454) = 0x80001fff; + msleep(100); + *(volatile unsigned int *)(0xbfe10454) = 0x1fff; + msleep(100); + *(volatile unsigned int *)(0xbfe10450) &= ~(1 << 2); + msleep(100); + *(volatile unsigned int *)(0xbfe10450) |= (1 << 2); + msleep(100); + rc = ahci_host_init(probe_ent); + if (rc) + { + *(volatile unsigned int *)(0xbfe10454) = 0x80001fff; + msleep(100); + *(volatile unsigned int *)(0xbfe10454) = 0x1fff; + msleep(100); + *(volatile unsigned int *)(0xbfe10450) &= ~(1 << 2); + msleep(100); + *(volatile unsigned int *)(0xbfe10450) |= (1 << 2); + msleep(100); + rc = ahci_host_init(probe_ent); + if (rc) + goto err_out; + } + } +#endif ahci_print_info(probe_ent); diff --git a/sys/dev/pci/ahcisata.c b/sys/dev/pci/ahcisata.c index 9ddaa27b..57bca1c6 100755 --- a/sys/dev/pci/ahcisata.c +++ b/sys/dev/pci/ahcisata.c @@ -528,9 +528,10 @@ static int waiting_for_cmd_completed(volatile u8 * offset, { int i; u32 status; + timeout_msec *= 2000; for (i = 0; ((status = readl(offset)) & sign) && i < timeout_msec; i++) - ; + delay(1); return (i < timeout_msec) ? 0 : -1; } @@ -771,20 +772,33 @@ static int get_ahci_device_data(struct ahci_sata_softc *sc, u8 * fis, int fis_le printf("AHCI SATA error: CI is set when START is zero!\n"); }; writel_with_flush(1, port_mmio + PORT_CMD_ISSUE); - if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE, 20000000, 0x1)) { + if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE, 200, 0x1)) { printf("%s : timeout exit! %d bytes transferred.\n", __func__, __LINE__, pp->cmd_slot->status); printf("PxIS: 0x%08x, PxSERR: 0x%08x\n", readl(port_mmio + PORT_IRQ_STAT), readl(port_mmio + PORT_SCR_ERR)); printf("PxTFD: 0x%08x, PxSSTS: 0x%08x\n", readl(port_mmio + PORT_TFDATA), readl(port_mmio + PORT_SCR_STAT)); - if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE, 2000000, 0x1)) { + if (waiting_for_cmd_completed(port_mmio + PORT_CMD_ISSUE, 200, 0x1)) { printf("Waiting another 2s is useless.\n"); - }else{ +#ifdef CONFIG_LS2K_FIX_SATA_PHY + *(volatile unsigned int *)(0xbfe10454) = 0x80001fff; + msleep(100); + *(volatile unsigned int *)(0xbfe10454) = 0x0001fff; + msleep(100); +#endif + }else{ printf("Waiting another 2s is usefull.\n"); } +#ifndef CONFIG_LS2K_FIX_SATA_PHY return -1; + #else + *(volatile unsigned int *)(0xbfe10454) = 0x80001fff; + msleep(100); + *(volatile unsigned int *)(0xbfe10454) = 0x0001fff; + msleep(100); + #endif } ahci_debug("%d byte transferred.\n", pp->cmd_slot->status);