mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-14 18:47:39 -04:00
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
This commit is contained in:
parent
5729be4017
commit
060609a202
5 changed files with 57 additions and 4 deletions
|
@ -201,6 +201,7 @@ static int perform_soft_reset(void);
|
||||||
static int set_multiple_mode(int sectors);
|
static int set_multiple_mode(int sectors);
|
||||||
static int set_features(void);
|
static int set_features(void);
|
||||||
|
|
||||||
|
#ifndef ATA_TARGET_POLLING
|
||||||
STATICIRAM ICODE_ATTR int wait_for_bsy(void)
|
STATICIRAM ICODE_ATTR int wait_for_bsy(void)
|
||||||
{
|
{
|
||||||
long timeout = current_tick + HZ*30;
|
long timeout = current_tick + HZ*30;
|
||||||
|
@ -235,6 +236,12 @@ STATICIRAM ICODE_ATTR int wait_for_rdy(void)
|
||||||
|
|
||||||
return 0; /* timeout */
|
return 0; /* timeout */
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
extern int ata_wait_for_bsy(void);
|
||||||
|
extern int ata_wait_for_rdy(void);
|
||||||
|
#define wait_for_bsy ata_wait_for_bsy
|
||||||
|
#define wait_for_rdy ata_wait_for_rdy
|
||||||
|
#endif
|
||||||
|
|
||||||
STATICIRAM ICODE_ATTR int wait_for_start_of_transfer(void)
|
STATICIRAM ICODE_ATTR int wait_for_start_of_transfer(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
#include "panic.h"
|
#include "panic.h"
|
||||||
#include "ata.h"
|
#include "ata.h"
|
||||||
|
#include "ata-defines.h"
|
||||||
#include "ata-target.h"
|
#include "ata-target.h"
|
||||||
#include "ccm-imx31.h"
|
#include "ccm-imx31.h"
|
||||||
#ifdef HAVE_ATA_DMA
|
#ifdef HAVE_ATA_DMA
|
||||||
|
@ -459,6 +460,7 @@ bool ata_dma_setup(void *addr, unsigned long bytes, bool write)
|
||||||
* shouldn't be reached based upon size. Otherwise we simply didn't
|
* shouldn't be reached based upon size. Otherwise we simply didn't
|
||||||
* understand the DMA mode setup. Force PIO in both cases. */
|
* understand the DMA mode setup. Force PIO in both cases. */
|
||||||
ATA_INTF_CONTROL = ATA_FIFO_RST | ATA_ATA_RST;
|
ATA_INTF_CONTROL = ATA_FIFO_RST | ATA_ATA_RST;
|
||||||
|
yield();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -645,6 +647,43 @@ bool ata_dma_finish(void)
|
||||||
}
|
}
|
||||||
#endif /* HAVE_ATA_DMA */
|
#endif /* HAVE_ATA_DMA */
|
||||||
|
|
||||||
|
static int ata_wait_status(unsigned status, unsigned mask, int timeout)
|
||||||
|
{
|
||||||
|
long busy_timeout = usec_timer() + 2;
|
||||||
|
long end_tick = current_tick + timeout;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if ((ATA_DRIVE_STATUS & mask) == status)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (!TIME_AFTER(usec_timer(), busy_timeout))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ata_keep_active();
|
||||||
|
|
||||||
|
if (TIME_AFTER(current_tick, end_tick))
|
||||||
|
break;
|
||||||
|
|
||||||
|
sleep(0);
|
||||||
|
busy_timeout = usec_timer() + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; /* timed out */
|
||||||
|
}
|
||||||
|
|
||||||
|
int ata_wait_for_bsy(void)
|
||||||
|
{
|
||||||
|
/* BSY = 0 */
|
||||||
|
return ata_wait_status(0, STATUS_BSY, 30*HZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ata_wait_for_rdy(void)
|
||||||
|
{
|
||||||
|
/* RDY = 1 && BSY = 0 */
|
||||||
|
return ata_wait_status(STATUS_RDY, STATUS_RDY | STATUS_BSY, 40*HZ);
|
||||||
|
}
|
||||||
|
|
||||||
void ata_device_init(void)
|
void ata_device_init(void)
|
||||||
{
|
{
|
||||||
/* Make sure we're not in reset mode */
|
/* Make sure we're not in reset mode */
|
||||||
|
|
|
@ -53,4 +53,6 @@ bool ata_is_coldstart(void);
|
||||||
#define ATA_SET_DEVICE_FEATURES
|
#define ATA_SET_DEVICE_FEATURES
|
||||||
void ata_set_pio_timings(int mode);
|
void ata_set_pio_timings(int mode);
|
||||||
|
|
||||||
|
#define ATA_TARGET_POLLING
|
||||||
|
|
||||||
#endif /* ATA_TARGET_H */
|
#endif /* ATA_TARGET_H */
|
||||||
|
|
|
@ -97,10 +97,10 @@ void gpt_start(void)
|
||||||
while (GPTCR & GPTCR_SWR);
|
while (GPTCR & GPTCR_SWR);
|
||||||
/* No output
|
/* No output
|
||||||
* No capture
|
* No capture
|
||||||
* Enable in run mode only (doesn't tick while in WFI)
|
* Enable in wait and run mode
|
||||||
* Freerun mode (count to 0xFFFFFFFF and roll-over to 0x00000000)
|
* Freerun mode (count to 0xFFFFFFFF and roll-over to 0x00000000)
|
||||||
*/
|
*/
|
||||||
GPTCR = GPTCR_FRR | GPTCR_CLKSRC_IPG_CLK;
|
GPTCR = GPTCR_FRR | GPTCR_WAITEN | GPTCR_CLKSRC_IPG_CLK;
|
||||||
GPTPR = ipg_mhz - 1;
|
GPTPR = ipg_mhz - 1;
|
||||||
GPTCR |= GPTCR_EN;
|
GPTCR |= GPTCR_EN;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,12 +31,17 @@
|
||||||
/* Overdrive mode */
|
/* Overdrive mode */
|
||||||
#define CPUFREQ_MAX 528000000
|
#define CPUFREQ_MAX 528000000
|
||||||
|
|
||||||
static inline void udelay(unsigned int usecs)
|
static inline void udelay(unsigned long usecs)
|
||||||
{
|
{
|
||||||
unsigned stop = GPTCNT + usecs;
|
unsigned long stop = GPTCNT + usecs;
|
||||||
while (TIME_BEFORE(GPTCNT, stop));
|
while (TIME_BEFORE(GPTCNT, stop));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline unsigned long usec_timer(void)
|
||||||
|
{
|
||||||
|
return GPTCNT;
|
||||||
|
}
|
||||||
|
|
||||||
void watchdog_init(unsigned int half_seconds);
|
void watchdog_init(unsigned int half_seconds);
|
||||||
void watchdog_service(void);
|
void watchdog_service(void);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue