summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/drivers/ata.c7
-rw-r--r--firmware/target/arm/imx31/ata-imx31.c39
-rw-r--r--firmware/target/arm/imx31/ata-target.h2
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/system-gigabeat-s.c4
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/system-target.h9
5 files changed, 57 insertions, 4 deletions
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c
index 7d37d051c9..2cdd67482a 100644
--- a/firmware/drivers/ata.c
+++ b/firmware/drivers/ata.c
@@ -201,6 +201,7 @@ static int perform_soft_reset(void);
201static int set_multiple_mode(int sectors); 201static int set_multiple_mode(int sectors);
202static int set_features(void); 202static int set_features(void);
203 203
204#ifndef ATA_TARGET_POLLING
204STATICIRAM ICODE_ATTR int wait_for_bsy(void) 205STATICIRAM ICODE_ATTR int wait_for_bsy(void)
205{ 206{
206 long timeout = current_tick + HZ*30; 207 long timeout = current_tick + HZ*30;
@@ -235,6 +236,12 @@ STATICIRAM ICODE_ATTR int wait_for_rdy(void)
235 236
236 return 0; /* timeout */ 237 return 0; /* timeout */
237} 238}
239#else
240extern int ata_wait_for_bsy(void);
241extern int ata_wait_for_rdy(void);
242#define wait_for_bsy ata_wait_for_bsy
243#define wait_for_rdy ata_wait_for_rdy
244#endif
238 245
239STATICIRAM ICODE_ATTR int wait_for_start_of_transfer(void) 246STATICIRAM ICODE_ATTR int wait_for_start_of_transfer(void)
240{ 247{
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 */
diff --git a/firmware/target/arm/imx31/ata-target.h b/firmware/target/arm/imx31/ata-target.h
index da1902acea..24141c6aa7 100644
--- a/firmware/target/arm/imx31/ata-target.h
+++ b/firmware/target/arm/imx31/ata-target.h
@@ -53,4 +53,6 @@ bool ata_is_coldstart(void);
53#define ATA_SET_DEVICE_FEATURES 53#define ATA_SET_DEVICE_FEATURES
54void ata_set_pio_timings(int mode); 54void ata_set_pio_timings(int mode);
55 55
56#define ATA_TARGET_POLLING
57
56#endif /* ATA_TARGET_H */ 58#endif /* ATA_TARGET_H */
diff --git a/firmware/target/arm/imx31/gigabeat-s/system-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/system-gigabeat-s.c
index 978c7f77cd..1f177d4252 100644
--- a/firmware/target/arm/imx31/gigabeat-s/system-gigabeat-s.c
+++ b/firmware/target/arm/imx31/gigabeat-s/system-gigabeat-s.c
@@ -97,10 +97,10 @@ void gpt_start(void)
97 while (GPTCR & GPTCR_SWR); 97 while (GPTCR & GPTCR_SWR);
98 /* No output 98 /* No output
99 * No capture 99 * No capture
100 * Enable in run mode only (doesn't tick while in WFI) 100 * Enable in wait and run mode
101 * Freerun mode (count to 0xFFFFFFFF and roll-over to 0x00000000) 101 * Freerun mode (count to 0xFFFFFFFF and roll-over to 0x00000000)
102 */ 102 */
103 GPTCR = GPTCR_FRR | GPTCR_CLKSRC_IPG_CLK; 103 GPTCR = GPTCR_FRR | GPTCR_WAITEN | GPTCR_CLKSRC_IPG_CLK;
104 GPTPR = ipg_mhz - 1; 104 GPTPR = ipg_mhz - 1;
105 GPTCR |= GPTCR_EN; 105 GPTCR |= GPTCR_EN;
106} 106}
diff --git a/firmware/target/arm/imx31/gigabeat-s/system-target.h b/firmware/target/arm/imx31/gigabeat-s/system-target.h
index f3ba719443..4449b570f7 100644
--- a/firmware/target/arm/imx31/gigabeat-s/system-target.h
+++ b/firmware/target/arm/imx31/gigabeat-s/system-target.h
@@ -31,12 +31,17 @@
31/* Overdrive mode */ 31/* Overdrive mode */
32#define CPUFREQ_MAX 528000000 32#define CPUFREQ_MAX 528000000
33 33
34static inline void udelay(unsigned int usecs) 34static inline void udelay(unsigned long usecs)
35{ 35{
36 unsigned stop = GPTCNT + usecs; 36 unsigned long stop = GPTCNT + usecs;
37 while (TIME_BEFORE(GPTCNT, stop)); 37 while (TIME_BEFORE(GPTCNT, stop));
38} 38}
39 39
40static inline unsigned long usec_timer(void)
41{
42 return GPTCNT;
43}
44
40void watchdog_init(unsigned int half_seconds); 45void watchdog_init(unsigned int half_seconds);
41void watchdog_service(void); 46void watchdog_service(void);
42 47