diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2011-01-22 09:23:31 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2011-01-22 09:23:31 +0000 |
commit | 060609a2023bfcc99472cfe4e94a2cc3704bd92c (patch) | |
tree | cc51f89e8dc4cca19ff4453195cd712888314368 | |
parent | 5729be4017c6e6081069c56637c4339aaddddd0b (diff) | |
download | rockbox-060609a2023bfcc99472cfe4e94a2cc3704bd92c.tar.gz rockbox-060609a2023bfcc99472cfe4e94a2cc3704bd92c.zip |
i.MX31: Busy wait for a couple microseconds at most then sleep until next tick when polling drive status. This prevents pointless jumps to overdrive speed from perceived high load when waiting for lengthy ops to complete such as spinup and sleep.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29108 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | firmware/drivers/ata.c | 7 | ||||
-rw-r--r-- | firmware/target/arm/imx31/ata-imx31.c | 39 | ||||
-rw-r--r-- | firmware/target/arm/imx31/ata-target.h | 2 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/system-gigabeat-s.c | 4 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/system-target.h | 9 |
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); | |||
201 | static int set_multiple_mode(int sectors); | 201 | static int set_multiple_mode(int sectors); |
202 | static int set_features(void); | 202 | static int set_features(void); |
203 | 203 | ||
204 | #ifndef ATA_TARGET_POLLING | ||
204 | STATICIRAM ICODE_ATTR int wait_for_bsy(void) | 205 | STATICIRAM 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 | ||
240 | extern int ata_wait_for_bsy(void); | ||
241 | extern 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 | ||
239 | STATICIRAM ICODE_ATTR int wait_for_start_of_transfer(void) | 246 | STATICIRAM 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 | ||
650 | static 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 | |||
675 | int ata_wait_for_bsy(void) | ||
676 | { | ||
677 | /* BSY = 0 */ | ||
678 | return ata_wait_status(0, STATUS_BSY, 30*HZ); | ||
679 | } | ||
680 | |||
681 | int 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 | |||
648 | void ata_device_init(void) | 687 | void 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 |
54 | void ata_set_pio_timings(int mode); | 54 | void 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 | ||
34 | static inline void udelay(unsigned int usecs) | 34 | static 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 | ||
40 | static inline unsigned long usec_timer(void) | ||
41 | { | ||
42 | return GPTCNT; | ||
43 | } | ||
44 | |||
40 | void watchdog_init(unsigned int half_seconds); | 45 | void watchdog_init(unsigned int half_seconds); |
41 | void watchdog_service(void); | 46 | void watchdog_service(void); |
42 | 47 | ||