summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2008-05-08 08:03:08 +0000
committerMichael Sevakis <jethead71@rockbox.org>2008-05-08 08:03:08 +0000
commitdf4bd0697d2925266df6af52c1247bf60a854db4 (patch)
treea8c03adedc5450b8dbaad3f2a4cf1529d7ce5a44
parentf18e4db81b5503c864c41505cf5e8122638c0089 (diff)
downloadrockbox-df4bd0697d2925266df6af52c1247bf60a854db4.tar.gz
rockbox-df4bd0697d2925266df6af52c1247bf60a854db4.zip
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
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/ata-imx31.c33
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/power-imx31.c17
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/system-imx31.c2
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/wmcodec-imx31.c10
4 files changed, 50 insertions, 12 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/ata-imx31.c b/firmware/target/arm/imx31/gigabeat-s/ata-imx31.c
index 9c3c72e2c5..885e7e7521 100644
--- a/firmware/target/arm/imx31/gigabeat-s/ata-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/ata-imx31.c
@@ -26,6 +26,7 @@
26#include "ata.h" 26#include "ata.h"
27#include "ata-target.h" 27#include "ata-target.h"
28#include "clkctl-imx31.h" 28#include "clkctl-imx31.h"
29#
29 30
30static const struct ata_pio_timings 31static const struct ata_pio_timings
31{ 32{
@@ -81,10 +82,15 @@ static const struct ata_pio_timings
81 82
82static int pio_mode = 0; /* Setup mode 0 by default */ 83static int pio_mode = 0; /* Setup mode 0 by default */
83 84
85static void ata_wait_for_idle(void)
86{
87 while (!(ATA_INTERRUPT_PENDING & ATA_CONTROLLER_IDLE));
88}
89
84/* Setup the timing for PIO mode */ 90/* Setup the timing for PIO mode */
85void ata_set_pio_timings(int mode) 91void ata_set_pio_timings(int mode)
86{ 92{
87 while (!(ATA_INTERRUPT_PENDING & ATA_CONTROLLER_IDLE)); 93 ata_wait_for_idle();
88 94
89 const struct ata_pio_timings * const timings = &pio_timings[mode]; 95 const struct ata_pio_timings * const timings = &pio_timings[mode];
90 /* T = period in nanoseconds */ 96 /* T = period in nanoseconds */
@@ -107,20 +113,34 @@ void ata_set_pio_timings(int mode)
107void ata_reset(void) 113void ata_reset(void)
108{ 114{
109 /* Be sure we're not busy */ 115 /* Be sure we're not busy */
110 while (!(ATA_INTERRUPT_PENDING & ATA_CONTROLLER_IDLE)); 116 ata_wait_for_idle();
111 117
112 ATA_INTF_CONTROL &= ~ATA_ATA_RST; 118 ATA_INTF_CONTROL &= ~ATA_ATA_RST;
113 sleep(1); 119 sleep(1);
114 ATA_INTF_CONTROL |= ATA_ATA_RST; 120 ATA_INTF_CONTROL |= ATA_ATA_RST;
115 sleep(1); 121 sleep(1);
116 122
117 while (!(ATA_INTERRUPT_PENDING & ATA_CONTROLLER_IDLE)); 123 ata_wait_for_idle();
118} 124}
119 125
120/* This function is called before enabling the USB bus */
121void ata_enable(bool on) 126void ata_enable(bool on)
122{ 127{
123 (void)on; 128 /* Unconditionally clock module before writing regs */
129 imx31_clkctl_module_clock_gating(CG_ATA, CGM_ON_ALL);
130
131 if (on)
132 {
133 ATA_INTF_CONTROL |= ATA_ATA_RST;
134 }
135 else
136 {
137 ata_wait_for_idle();
138
139 ATA_INTF_CONTROL &= ~ATA_ATA_RST;
140
141 /* Disable off - unclock ATA module */
142 imx31_clkctl_module_clock_gating(CG_ATA, CGM_OFF);
143 }
124} 144}
125 145
126bool ata_is_coldstart(void) 146bool ata_is_coldstart(void)
@@ -130,7 +150,8 @@ bool ata_is_coldstart(void)
130 150
131void ata_device_init(void) 151void ata_device_init(void)
132{ 152{
133 ATA_INTF_CONTROL |= ATA_ATA_RST; /* Make sure we're not in reset mode */ 153 /* Make sure we're not in reset mode */
154 ata_enable(true);
134 155
135 /* mode may be switched later once identify info is ready in which 156 /* mode may be switched later once identify info is ready in which
136 * case the main driver calls back */ 157 * case the main driver calls back */
diff --git a/firmware/target/arm/imx31/gigabeat-s/power-imx31.c b/firmware/target/arm/imx31/gigabeat-s/power-imx31.c
index e51318d16f..3e845d7d93 100644
--- a/firmware/target/arm/imx31/gigabeat-s/power-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/power-imx31.c
@@ -19,6 +19,7 @@
19#include "config.h" 19#include "config.h"
20#include "system.h" 20#include "system.h"
21#include "power.h" 21#include "power.h"
22#include "ata.h"
22#include "backlight.h" 23#include "backlight.h"
23#include "backlight-target.h" 24#include "backlight-target.h"
24#include "avic-imx31.h" 25#include "avic-imx31.h"
@@ -50,7 +51,21 @@ bool charging_state(void) {
50 51
51void ide_power_enable(bool on) 52void ide_power_enable(bool on)
52{ 53{
53 (void)on; 54 if (!on)
55 {
56 /* Bus must be isolated before power off */
57 imx31_regmod32(&GPIO2_DR, (1 << 16), (1 << 16));
58 }
59
60 /* HD power switch */
61 imx31_regmod32(&GPIO3_DR, on ? (1 << 5) : 0, (1 << 5));
62
63 if (on)
64 {
65 /* Bus switch may be turned on after powerup */
66 sleep(HZ/10);
67 imx31_regmod32(&GPIO2_DR, 0, (1 << 16));
68 }
54} 69}
55 70
56bool ide_powered(void) 71bool ide_powered(void)
diff --git a/firmware/target/arm/imx31/gigabeat-s/system-imx31.c b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c
index ca82a18fbd..412bbcc4b0 100644
--- a/firmware/target/arm/imx31/gigabeat-s/system-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c
@@ -27,7 +27,7 @@ void system_init(void)
27 gpio_init(); 27 gpio_init();
28} 28}
29 29
30void imx31_regmod32(volatile uint32_t *reg_p, uint32_t mask, uint32_t value) 30void imx31_regmod32(volatile uint32_t *reg_p, uint32_t value, uint32_t mask)
31{ 31{
32 value &= mask; 32 value &= mask;
33 mask = ~mask; 33 mask = ~mask;
diff --git a/firmware/target/arm/imx31/gigabeat-s/wmcodec-imx31.c b/firmware/target/arm/imx31/gigabeat-s/wmcodec-imx31.c
index c8a04ce20e..a88571ee14 100644
--- a/firmware/target/arm/imx31/gigabeat-s/wmcodec-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/wmcodec-imx31.c
@@ -39,10 +39,12 @@ static struct i2c_node wm8978_i2c_node =
39void audiohw_init(void) 39void audiohw_init(void)
40{ 40{
41 /* USB PLL = 338.688MHz, /30 = 11.2896MHz = 256Fs */ 41 /* USB PLL = 338.688MHz, /30 = 11.2896MHz = 256Fs */
42 imx31_regmod32(&CLKCTL_PDR1, PDR1_SSI1_PODF | PDR1_SSI2_PODF, 42 imx31_regmod32(&CLKCTL_PDR1,
43 PDR1_SSI1_PODFw(64-1) | PDR1_SSI2_PODFw(5-1)); 43 PDR1_SSI1_PODFw(64-1) | PDR1_SSI2_PODFw(5-1),
44 imx31_regmod32(&CLKCTL_PDR1, PDR1_SSI1_PRE_PODF | PDR1_SSI2_PRE_PODF, 44 PDR1_SSI1_PODF | PDR1_SSI2_PODF);
45 PDR1_SSI1_PRE_PODFw(4-1) | PDR1_SSI2_PRE_PODFw(1-1)); 45 imx31_regmod32(&CLKCTL_PDR1,
46 PDR1_SSI1_PRE_PODFw(4-1) | PDR1_SSI2_PRE_PODFw(1-1),
47 PDR1_SSI1_PRE_PODF | PDR1_SSI2_PRE_PODF);
46 i2c_enable_node(&wm8978_i2c_node, true); 48 i2c_enable_node(&wm8978_i2c_node, true);
47 49
48 audiohw_preinit(); 50 audiohw_preinit();