diff options
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s/ata-imx31.c')
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/ata-imx31.c | 33 |
1 files changed, 27 insertions, 6 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 | ||
30 | static const struct ata_pio_timings | 31 | static const struct ata_pio_timings |
31 | { | 32 | { |
@@ -81,10 +82,15 @@ static const struct ata_pio_timings | |||
81 | 82 | ||
82 | static int pio_mode = 0; /* Setup mode 0 by default */ | 83 | static int pio_mode = 0; /* Setup mode 0 by default */ |
83 | 84 | ||
85 | static 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 */ |
85 | void ata_set_pio_timings(int mode) | 91 | void 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) | |||
107 | void ata_reset(void) | 113 | void 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 */ | ||
121 | void ata_enable(bool on) | 126 | void 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 | ||
126 | bool ata_is_coldstart(void) | 146 | bool ata_is_coldstart(void) |
@@ -130,7 +150,8 @@ bool ata_is_coldstart(void) | |||
130 | 150 | ||
131 | void ata_device_init(void) | 151 | void 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 */ |