diff options
author | Amaury Pouly <pamaury@rockbox.org> | 2011-09-13 23:39:05 +0000 |
---|---|---|
committer | Amaury Pouly <pamaury@rockbox.org> | 2011-09-13 23:39:05 +0000 |
commit | af9d25611d8493ef349e80f06cc49d2cb814540b (patch) | |
tree | 49f01d730322d4bf26bf7fa374f0ea831f79fb4c /firmware | |
parent | 7ac1b9fb62f09d063829301adad1b06d1ca0b2cd (diff) | |
download | rockbox-af9d25611d8493ef349e80f06cc49d2cb814540b.tar.gz rockbox-af9d25611d8493ef349e80f06cc49d2cb814540b.zip |
imx233/fuze+: define mmc stubs, correctly handle ssp maximum transfer size, correctly handle flash size (including windowing)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30528 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/target/arm/imx233/mmc-imx233.c | 117 |
1 files changed, 98 insertions, 19 deletions
diff --git a/firmware/target/arm/imx233/mmc-imx233.c b/firmware/target/arm/imx233/mmc-imx233.c index d2e76e7f6c..8bdefebf6b 100644 --- a/firmware/target/arm/imx233/mmc-imx233.c +++ b/firmware/target/arm/imx233/mmc-imx233.c | |||
@@ -42,6 +42,9 @@ | |||
42 | static unsigned mmc_window_start = 0; | 42 | static unsigned mmc_window_start = 0; |
43 | static unsigned mmc_window_end = INT_MAX; | 43 | static unsigned mmc_window_end = INT_MAX; |
44 | static bool mmc_window_enable = true; | 44 | static bool mmc_window_enable = true; |
45 | static long mmc_last_activity = -1; | ||
46 | static bool mmc_is_active = false; | ||
47 | static unsigned mmc_size = 0; | ||
45 | 48 | ||
46 | static struct mutex mmc_mutex; | 49 | static struct mutex mmc_mutex; |
47 | 50 | ||
@@ -128,6 +131,16 @@ int mmc_init(void) | |||
128 | * gives bitrate of 96 / 2 / 1 = 48MHz */ | 131 | * gives bitrate of 96 / 2 / 1 = 48MHz */ |
129 | imx233_ssp_set_timings(MMC_SSP, 2, 0, 0xffff); | 132 | imx233_ssp_set_timings(MMC_SSP, 2, 0, 0xffff); |
130 | 133 | ||
134 | /* read extended CSD */ | ||
135 | { | ||
136 | uint8_t ext_csd[512]; | ||
137 | ret = imx233_ssp_sd_mmc_transfer(MMC_SSP, 8, 0, SSP_SHORT_RESP, ext_csd, 1, true, true, &status); | ||
138 | if(ret != 0) | ||
139 | return -12; | ||
140 | uint32_t *sec_count = (void *)&ext_csd[212]; | ||
141 | mmc_size = *sec_count; | ||
142 | } | ||
143 | |||
131 | #ifdef SANSA_FUZEPLUS | 144 | #ifdef SANSA_FUZEPLUS |
132 | if(mmc_window_enable) | 145 | if(mmc_window_enable) |
133 | { | 146 | { |
@@ -159,6 +172,7 @@ int mmc_init(void) | |||
159 | return -102; /* sigmatel partition */ | 172 | return -102; /* sigmatel partition */ |
160 | if((mmc_window_end - mmc_window_start) < 4 * 1024 * 1024) | 173 | if((mmc_window_end - mmc_window_start) < 4 * 1024 * 1024) |
161 | return -103; /* partition too small */ | 174 | return -103; /* partition too small */ |
175 | mmc_size = mmc_window_end - mmc_window_start; | ||
162 | } | 176 | } |
163 | #endif | 177 | #endif |
164 | 178 | ||
@@ -178,14 +192,14 @@ void mmc_get_info(IF_MD2(int drive,) struct storage_info *info) | |||
178 | (void) drive; | 192 | (void) drive; |
179 | #endif | 193 | #endif |
180 | info->sector_size = 512; | 194 | info->sector_size = 512; |
181 | info->num_sectors = 0xECC000 - 0x0001ac00; | 195 | info->num_sectors = mmc_size; |
182 | info->vendor = "Rockbox"; | 196 | info->vendor = "Rockbox"; |
183 | info->product = "Internal Storage"; | 197 | info->product = "Internal Storage"; |
184 | info->revision = "0.00"; | 198 | info->revision = "0.00"; |
185 | } | 199 | } |
186 | #endif | 200 | #endif |
187 | 201 | ||
188 | int mmc_read_sectors(IF_MD2(int drive,) unsigned long start, int count, void *buf) | 202 | static int transfer_sectors(IF_MD2(int drive,) unsigned long start, int count, void *buf, bool read) |
189 | { | 203 | { |
190 | IF_MD((void) drive); | 204 | IF_MD((void) drive); |
191 | /* check window */ | 205 | /* check window */ |
@@ -197,32 +211,45 @@ int mmc_read_sectors(IF_MD2(int drive,) unsigned long start, int count, void *bu | |||
197 | int ret = 0; | 211 | int ret = 0; |
198 | uint32_t resp; | 212 | uint32_t resp; |
199 | 213 | ||
200 | if(count == 1) | 214 | mmc_last_activity = current_tick; |
201 | { | 215 | mmc_is_active = true; |
202 | ret = imx233_ssp_sd_mmc_transfer(MMC_SSP, 17, start, SSP_SHORT_RESP, buf, | 216 | |
203 | count, false, true, &resp); | 217 | do |
204 | } | ||
205 | else | ||
206 | { | 218 | { |
207 | ret = imx233_ssp_sd_mmc_transfer(MMC_SSP, 23, count, SSP_SHORT_RESP, NULL, | 219 | int this_count = MIN(count, IMX233_MAX_SSP_XFER_SIZE / 512); |
208 | 0, false, false, &resp); | 220 | if(this_count == 1) |
209 | if(ret == 0) | 221 | { |
210 | ret = imx233_ssp_sd_mmc_transfer(MMC_SSP, 18, start, SSP_SHORT_RESP, buf, | 222 | ret = imx233_ssp_sd_mmc_transfer(MMC_SSP, read ? 17 : 24, start, |
211 | count, false, true, &resp); | 223 | SSP_SHORT_RESP, buf, this_count, false, read, &resp); |
212 | } | 224 | } |
225 | else | ||
226 | { | ||
227 | ret = imx233_ssp_sd_mmc_transfer(MMC_SSP, 23, this_count, SSP_SHORT_RESP, NULL, | ||
228 | 0, false, false, &resp); | ||
229 | if(ret == 0) | ||
230 | ret = imx233_ssp_sd_mmc_transfer(MMC_SSP, read ? 18 : 25, start, | ||
231 | SSP_SHORT_RESP, buf, this_count, false, read, &resp); | ||
232 | } | ||
233 | count -= this_count; | ||
234 | start += this_count; | ||
235 | buf += this_count * 512; | ||
236 | }while(count != 0 && ret == SSP_SUCCESS); | ||
237 | |||
238 | mmc_is_active = false; | ||
213 | 239 | ||
214 | mutex_unlock(&mmc_mutex); | 240 | mutex_unlock(&mmc_mutex); |
215 | 241 | ||
216 | return ret; | 242 | return ret; |
217 | } | 243 | } |
218 | 244 | ||
245 | int mmc_read_sectors(IF_MD2(int drive,) unsigned long start, int count, void *buf) | ||
246 | { | ||
247 | return transfer_sectors(IF_MD2(drive,) start, count, buf, true); | ||
248 | } | ||
249 | |||
219 | int mmc_write_sectors(IF_MD2(int drive,) unsigned long start, int count, const void* buf) | 250 | int mmc_write_sectors(IF_MD2(int drive,) unsigned long start, int count, const void* buf) |
220 | { | 251 | { |
221 | IF_MD((void) drive); | 252 | return transfer_sectors(IF_MD2(drive,) start, count, (void *)buf, false); |
222 | (void) start; | ||
223 | (void) count; | ||
224 | (void) buf; | ||
225 | return -1; | ||
226 | } | 253 | } |
227 | 254 | ||
228 | bool mmc_present(IF_MD(int drive)) | 255 | bool mmc_present(IF_MD(int drive)) |
@@ -236,3 +263,55 @@ bool mmc_removable(IF_MD(int drive)) | |||
236 | IF_MD((void) drive); | 263 | IF_MD((void) drive); |
237 | return false; | 264 | return false; |
238 | } | 265 | } |
266 | |||
267 | void mmc_sleep(void) | ||
268 | { | ||
269 | } | ||
270 | |||
271 | void mmc_sleepnow(void) | ||
272 | { | ||
273 | } | ||
274 | |||
275 | bool mmc_disk_is_active(void) | ||
276 | { | ||
277 | return mmc_is_active; | ||
278 | } | ||
279 | |||
280 | bool mmc_usb_active(void) | ||
281 | { | ||
282 | return mmc_disk_is_active(); | ||
283 | } | ||
284 | |||
285 | int mmc_soft_reset(void) | ||
286 | { | ||
287 | return 0; | ||
288 | } | ||
289 | |||
290 | int mmc_flush(void) | ||
291 | { | ||
292 | return 0; | ||
293 | } | ||
294 | |||
295 | void mmc_spin(void) | ||
296 | { | ||
297 | } | ||
298 | |||
299 | void mmc_spindown(int seconds) | ||
300 | { | ||
301 | (void) seconds; | ||
302 | } | ||
303 | |||
304 | long mmc_last_disk_activity(void) | ||
305 | { | ||
306 | return mmc_last_activity; | ||
307 | } | ||
308 | |||
309 | int mmc_spinup_time(void) | ||
310 | { | ||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | void mmc_enable(bool enable) | ||
315 | { | ||
316 | (void) enable; | ||
317 | } | ||