summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx31/ata-imx31.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx31/ata-imx31.c')
-rw-r--r--firmware/target/arm/imx31/ata-imx31.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/firmware/target/arm/imx31/ata-imx31.c b/firmware/target/arm/imx31/ata-imx31.c
index 6ba49cada0..c3e3c51e63 100644
--- a/firmware/target/arm/imx31/ata-imx31.c
+++ b/firmware/target/arm/imx31/ata-imx31.c
@@ -26,6 +26,7 @@
26#include "power.h" 26#include "power.h"
27#include "panic.h" 27#include "panic.h"
28#include "ata.h" 28#include "ata.h"
29#include "ata-defines.h"
29#include "ata-target.h" 30#include "ata-target.h"
30#include "ccm-imx31.h" 31#include "ccm-imx31.h"
31#ifdef HAVE_ATA_DMA 32#ifdef HAVE_ATA_DMA
@@ -459,6 +460,7 @@ bool ata_dma_setup(void *addr, unsigned long bytes, bool write)
459 * shouldn't be reached based upon size. Otherwise we simply didn't 460 * shouldn't be reached based upon size. Otherwise we simply didn't
460 * understand the DMA mode setup. Force PIO in both cases. */ 461 * understand the DMA mode setup. Force PIO in both cases. */
461 ATA_INTF_CONTROL = ATA_FIFO_RST | ATA_ATA_RST; 462 ATA_INTF_CONTROL = ATA_FIFO_RST | ATA_ATA_RST;
463 yield();
462 return false; 464 return false;
463 } 465 }
464 466
@@ -645,6 +647,43 @@ bool ata_dma_finish(void)
645} 647}
646#endif /* HAVE_ATA_DMA */ 648#endif /* HAVE_ATA_DMA */
647 649
650static int ata_wait_status(unsigned status, unsigned mask, int timeout)
651{
652 long busy_timeout = usec_timer() + 2;
653 long end_tick = current_tick + timeout;
654
655 while (1)
656 {
657 if ((ATA_DRIVE_STATUS & mask) == status)
658 return 1;
659
660 if (!TIME_AFTER(usec_timer(), busy_timeout))
661 continue;
662
663 ata_keep_active();
664
665 if (TIME_AFTER(current_tick, end_tick))
666 break;
667
668 sleep(0);
669 busy_timeout = usec_timer() + 2;
670 }
671
672 return 0; /* timed out */
673}
674
675int ata_wait_for_bsy(void)
676{
677 /* BSY = 0 */
678 return ata_wait_status(0, STATUS_BSY, 30*HZ);
679}
680
681int ata_wait_for_rdy(void)
682{
683 /* RDY = 1 && BSY = 0 */
684 return ata_wait_status(STATUS_RDY, STATUS_RDY | STATUS_BSY, 40*HZ);
685}
686
648void ata_device_init(void) 687void ata_device_init(void)
649{ 688{
650 /* Make sure we're not in reset mode */ 689 /* Make sure we're not in reset mode */