Gigabeat S: Add ATA/IDE power management. Fix parameter order of regmod32 as it was intended (had some things mixed up :P).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17409 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
f18e4db81b
commit
df4bd0697d
4 changed files with 50 additions and 12 deletions
|
@ -26,6 +26,7 @@
|
|||
#include "ata.h"
|
||||
#include "ata-target.h"
|
||||
#include "clkctl-imx31.h"
|
||||
#
|
||||
|
||||
static const struct ata_pio_timings
|
||||
{
|
||||
|
@ -81,10 +82,15 @@ static const struct ata_pio_timings
|
|||
|
||||
static int pio_mode = 0; /* Setup mode 0 by default */
|
||||
|
||||
static void ata_wait_for_idle(void)
|
||||
{
|
||||
while (!(ATA_INTERRUPT_PENDING & ATA_CONTROLLER_IDLE));
|
||||
}
|
||||
|
||||
/* Setup the timing for PIO mode */
|
||||
void ata_set_pio_timings(int mode)
|
||||
{
|
||||
while (!(ATA_INTERRUPT_PENDING & ATA_CONTROLLER_IDLE));
|
||||
ata_wait_for_idle();
|
||||
|
||||
const struct ata_pio_timings * const timings = &pio_timings[mode];
|
||||
/* T = period in nanoseconds */
|
||||
|
@ -107,20 +113,34 @@ void ata_set_pio_timings(int mode)
|
|||
void ata_reset(void)
|
||||
{
|
||||
/* Be sure we're not busy */
|
||||
while (!(ATA_INTERRUPT_PENDING & ATA_CONTROLLER_IDLE));
|
||||
ata_wait_for_idle();
|
||||
|
||||
ATA_INTF_CONTROL &= ~ATA_ATA_RST;
|
||||
sleep(1);
|
||||
ATA_INTF_CONTROL |= ATA_ATA_RST;
|
||||
sleep(1);
|
||||
|
||||
while (!(ATA_INTERRUPT_PENDING & ATA_CONTROLLER_IDLE));
|
||||
ata_wait_for_idle();
|
||||
}
|
||||
|
||||
/* This function is called before enabling the USB bus */
|
||||
void ata_enable(bool on)
|
||||
{
|
||||
(void)on;
|
||||
/* Unconditionally clock module before writing regs */
|
||||
imx31_clkctl_module_clock_gating(CG_ATA, CGM_ON_ALL);
|
||||
|
||||
if (on)
|
||||
{
|
||||
ATA_INTF_CONTROL |= ATA_ATA_RST;
|
||||
}
|
||||
else
|
||||
{
|
||||
ata_wait_for_idle();
|
||||
|
||||
ATA_INTF_CONTROL &= ~ATA_ATA_RST;
|
||||
|
||||
/* Disable off - unclock ATA module */
|
||||
imx31_clkctl_module_clock_gating(CG_ATA, CGM_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
bool ata_is_coldstart(void)
|
||||
|
@ -130,7 +150,8 @@ bool ata_is_coldstart(void)
|
|||
|
||||
void ata_device_init(void)
|
||||
{
|
||||
ATA_INTF_CONTROL |= ATA_ATA_RST; /* Make sure we're not in reset mode */
|
||||
/* Make sure we're not in reset mode */
|
||||
ata_enable(true);
|
||||
|
||||
/* mode may be switched later once identify info is ready in which
|
||||
* case the main driver calls back */
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "power.h"
|
||||
#include "ata.h"
|
||||
#include "backlight.h"
|
||||
#include "backlight-target.h"
|
||||
#include "avic-imx31.h"
|
||||
|
@ -50,7 +51,21 @@ bool charging_state(void) {
|
|||
|
||||
void ide_power_enable(bool on)
|
||||
{
|
||||
(void)on;
|
||||
if (!on)
|
||||
{
|
||||
/* Bus must be isolated before power off */
|
||||
imx31_regmod32(&GPIO2_DR, (1 << 16), (1 << 16));
|
||||
}
|
||||
|
||||
/* HD power switch */
|
||||
imx31_regmod32(&GPIO3_DR, on ? (1 << 5) : 0, (1 << 5));
|
||||
|
||||
if (on)
|
||||
{
|
||||
/* Bus switch may be turned on after powerup */
|
||||
sleep(HZ/10);
|
||||
imx31_regmod32(&GPIO2_DR, 0, (1 << 16));
|
||||
}
|
||||
}
|
||||
|
||||
bool ide_powered(void)
|
||||
|
|
|
@ -27,7 +27,7 @@ void system_init(void)
|
|||
gpio_init();
|
||||
}
|
||||
|
||||
void imx31_regmod32(volatile uint32_t *reg_p, uint32_t mask, uint32_t value)
|
||||
void imx31_regmod32(volatile uint32_t *reg_p, uint32_t value, uint32_t mask)
|
||||
{
|
||||
value &= mask;
|
||||
mask = ~mask;
|
||||
|
|
|
@ -39,10 +39,12 @@ static struct i2c_node wm8978_i2c_node =
|
|||
void audiohw_init(void)
|
||||
{
|
||||
/* USB PLL = 338.688MHz, /30 = 11.2896MHz = 256Fs */
|
||||
imx31_regmod32(&CLKCTL_PDR1, PDR1_SSI1_PODF | PDR1_SSI2_PODF,
|
||||
PDR1_SSI1_PODFw(64-1) | PDR1_SSI2_PODFw(5-1));
|
||||
imx31_regmod32(&CLKCTL_PDR1, PDR1_SSI1_PRE_PODF | PDR1_SSI2_PRE_PODF,
|
||||
PDR1_SSI1_PRE_PODFw(4-1) | PDR1_SSI2_PRE_PODFw(1-1));
|
||||
imx31_regmod32(&CLKCTL_PDR1,
|
||||
PDR1_SSI1_PODFw(64-1) | PDR1_SSI2_PODFw(5-1),
|
||||
PDR1_SSI1_PODF | PDR1_SSI2_PODF);
|
||||
imx31_regmod32(&CLKCTL_PDR1,
|
||||
PDR1_SSI1_PRE_PODFw(4-1) | PDR1_SSI2_PRE_PODFw(1-1),
|
||||
PDR1_SSI1_PRE_PODF | PDR1_SSI2_PRE_PODF);
|
||||
i2c_enable_node(&wm8978_i2c_node, true);
|
||||
|
||||
audiohw_preinit();
|
||||
|
|
Loading…
Reference in a new issue