summaryrefslogtreecommitdiff
path: root/firmware/target/arm/tms320dm320/sdmmc-dm320.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/tms320dm320/sdmmc-dm320.c')
-rw-r--r--firmware/target/arm/tms320dm320/sdmmc-dm320.c949
1 files changed, 949 insertions, 0 deletions
diff --git a/firmware/target/arm/tms320dm320/sdmmc-dm320.c b/firmware/target/arm/tms320dm320/sdmmc-dm320.c
new file mode 100644
index 0000000000..307b90ec3b
--- /dev/null
+++ b/firmware/target/arm/tms320dm320/sdmmc-dm320.c
@@ -0,0 +1,949 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: $
9 *
10 * Copyright (C) 2011 by Tomasz Moń
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "sd.h"
23#include "system.h"
24#include <string.h>
25#include "gcc_extensions.h"
26#include "thread.h"
27#include "panic.h"
28#include "kernel.h"
29#include "dma-target.h"
30
31//#define SD_DEBUG
32
33#ifdef SD_DEBUG
34#include "lcd-target.h"
35#include "lcd.h"
36#include "font.h"
37#ifdef BOOTLOADER
38#include "common.h"
39#else
40#include "debug.h"
41#endif
42#endif
43#include "sdmmc.h"
44#include "disk.h"
45#include "fat.h"
46#include "system-target.h"
47
48/* The configuration method is not very flexible. */
49#define CARD_NUM_SLOT 1
50#define NUM_CARDS 2
51
52#define EC_OK 0
53#define EC_FAILED 1
54#define EC_NOCARD 2
55#define EC_WAIT_STATE_FAILED 3
56#define EC_POWER_UP 4
57#define EC_FIFO_WR_EMPTY 5
58#define EC_FIFO_WR_DONE 6
59#define EC_TRAN_READ_ENTRY 7
60#define EC_TRAN_READ_EXIT 8
61#define EC_TRAN_WRITE_ENTRY 9
62#define EC_TRAN_WRITE_EXIT 10
63#define EC_COMMAND 11
64#define EC_WRITE_PROTECT 12
65#define EC_DATA_TIMEOUT 13
66#define EC_RESP_TIMEOUT 14
67#define EC_CRC_ERROR 15
68#define NUM_EC 16
69
70#define MIN_YIELD_PERIOD 1000
71#define UNALIGNED_NUM_SECTORS 10
72#define MAX_TRANSFER_ERRORS 10
73
74#define SECTOR_SIZE 512
75#define BLOCKS_PER_BANK 0x7A7800
76
77/* command flags for send_cmd */
78#define SDHC_RESP_FMT_NONE 0x0000
79#define SDHC_RESP_FMT_1 0x0200
80#define SDHC_RESP_FMT_2 0x0400
81#define SDHC_RESP_FMT_3 0x0600
82
83#define INITIAL_CLK 312500 /* Initial clock */
84#define SD_CLK 24000000 /* Clock for SD cards */
85#define MMC_CLK 15000000 /* Clock for MMC cards */
86
87#ifdef SD_DEBUG
88#ifdef BOOTLOADER
89#define dbgprintf printf
90#else
91#define dbgprintf DEBUGF
92#endif
93#else
94#define dbgprintf(...)
95#endif
96
97struct sd_card_status
98{
99 int retry;
100 int retry_max;
101};
102
103/** static, private data **/
104
105/* for compatibility */
106static long last_disk_activity = -1;
107
108static bool initialized = false;
109static unsigned int sd_thread_id = 0;
110
111static bool sd_enabled = false;
112static long next_yield = 0;
113
114static tCardInfo card_info [NUM_CARDS];
115static tCardInfo *currcard;
116
117static struct sd_card_status sd_status[NUM_CARDS] =
118{
119#if NUM_CARDS > 1
120 {0, 10},
121#endif
122 {0, 10}
123};
124
125/* Shoot for around 75% usage */
126static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x1c0)/sizeof(long)];
127static const char sd_thread_name[] = "sd";
128static struct mutex sd_mtx SHAREDBSS_ATTR;
129static struct event_queue sd_queue;
130static volatile unsigned int transfer_error[NUM_DRIVES];
131/* align on cache line size */
132static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE]
133 __attribute__((aligned(32)));
134
135static void sd_card_mux(int card_no)
136{
137#ifdef HAVE_MULTIDRIVE
138#ifdef SANSA_CONNECT
139 /* GIO6 - select Card; GIO5 - select iNAND (both active low) */
140 if (card_no == CARD_NUM_SLOT)
141 {
142 IO_GIO_BITSET0 = (1 << 5); /* deselect iNAND (GIO5) */
143 IO_GIO_BITCLR0 = (1 << 6); /* select card (GIO6) */
144 }
145 else
146 {
147 IO_GIO_BITSET0 = (1 << 6); /* deselect card (GIO6) */
148 IO_GIO_BITCLR0 = (1 << 5); /* select iNAND (GIO5) */
149 }
150#else /* Different players */
151 (void)card_no;
152#endif
153#else /* No multidrive */
154 (void)card_no;
155#endif
156}
157
158
159void sd_enable(bool on)
160{
161 if (sd_enabled == on)
162 return; /* nothing to do */
163
164 if (on)
165 {
166 sd_enabled = true;
167 }
168 else
169 {
170 sd_enabled = false;
171 }
172}
173
174/* sets clock rate just like OF does */
175static void sd_set_clock_rate(unsigned long rate)
176{
177 unsigned char rate_val = 0;
178
179 if (rate == INITIAL_CLK)
180 {
181 rate_val = 0x3B;
182 }
183 else if (rate > INITIAL_CLK)
184 {
185 rate_val = 0;
186 }
187 else
188 {
189 rate_val = 0xFF;
190 }
191
192 IO_MMC_MEM_CLK_CONTROL = (IO_MMC_MEM_CLK_CONTROL & 0xFF00) | rate_val;
193}
194
195static int sd_poll_status(int st_reg_num, volatile unsigned int flag)
196{
197 unsigned int status;
198 unsigned int status1;
199 bool done;
200
201 do
202 {
203 long time = current_tick;
204
205 if (TIME_AFTER(time, next_yield))
206 {
207 long ty = current_tick;
208 yield();
209 next_yield = ty + MIN_YIELD_PERIOD;
210 }
211
212 status = IO_MMC_STATUS0;
213 status1 = IO_MMC_STATUS1;
214
215 if (status & MMC_ST0_CMD_TIMEOUT)
216 {
217 dbgprintf("CMD timeout");
218 return -EC_RESP_TIMEOUT;
219 }
220 if (status & MMC_ST0_DATA_TIMEOUT)
221 {
222 dbgprintf("DATA timeout");
223 return -EC_DATA_TIMEOUT;
224 }
225
226 if (status &
227 (MMC_ST0_WR_CRCERR | MMC_ST0_RD_CRCERR | MMC_ST0_RESP_CRCERR))
228 {
229 dbgprintf("CRC error");
230 return -EC_CRC_ERROR;
231 }
232
233 if (st_reg_num == 0)
234 {
235 done = status & flag;
236 }
237 else
238 {
239 done = status1 & flag;
240 }
241 } while (!done);
242
243 return EC_OK;
244}
245
246static int dma_wait_for_completion(void)
247{
248 unsigned short dma_status;
249
250 do
251 {
252 long time = current_tick;
253
254 if (TIME_AFTER(time, next_yield))
255 {
256 long ty = current_tick;
257 yield();
258 next_yield = ty + MIN_YIELD_PERIOD;
259 }
260
261 dma_status = IO_MMC_SD_DMA_STATUS1;
262 if (dma_status & (1 << 13))
263 {
264 return -EC_DATA_TIMEOUT;
265 }
266 } while (dma_status & (1 << 12));
267
268 return EC_OK;
269}
270
271static int sd_command(int cmd, unsigned long arg,
272 int cmdat, unsigned long *response)
273{
274 int ret;
275
276 /* Clear response registers */
277 IO_MMC_RESPONSE0 = 0;
278 IO_MMC_RESPONSE1 = 0;
279 IO_MMC_RESPONSE2 = 0;
280 IO_MMC_RESPONSE3 = 0;
281 IO_MMC_RESPONSE4 = 0;
282 IO_MMC_RESPONSE5 = 0;
283 IO_MMC_RESPONSE6 = 0;
284 IO_MMC_RESPONSE7 = 0;
285 IO_MMC_COMMAND_INDEX = 0;
286 IO_MMC_SPI_DATA = 0;
287
288 IO_MMC_ARG_LOW = (unsigned int)((arg & 0xFFFF));
289 IO_MMC_ARG_HI = (unsigned int)((arg & 0xFFFF0000) >> 16);
290
291 /* SD is always in push-pull mode */
292 cmdat |= MMC_CMD_PPLEN;
293
294 cmdat |= (cmd & MMC_CMD_CMD_MASK);
295
296 if (cmdat & MMC_CMD_DATA)
297 cmdat |= MMC_CMD_DCLR;
298
299 IO_MMC_COMMAND = cmdat;
300
301 if (cmdat & MMC_CMD_DATA)
302 {
303 /* Command requires data - do not wait for RSPDNE */
304 ret = EC_OK;
305 }
306 else
307 {
308 ret = sd_poll_status(0, MMC_ST0_RSPDNE);
309 }
310
311 if (ret != EC_OK)
312 {
313 dbgprintf("Command failed (ret %d)", ret);
314 return ret;
315 }
316
317 if (response == NULL)
318 {
319 /* discard response */
320 }
321 else if ((cmdat & SDHC_RESP_FMT_1) || (cmdat & SDHC_RESP_FMT_3))
322 {
323 response[0] = (IO_MMC_RESPONSE7 << 16) | IO_MMC_RESPONSE6;
324 }
325 else if (cmdat & SDHC_RESP_FMT_2)
326 {
327 response[0] = (IO_MMC_RESPONSE7 << 16) | IO_MMC_RESPONSE6;
328 response[1] = (IO_MMC_RESPONSE5 << 16) | IO_MMC_RESPONSE4;
329 response[2] = (IO_MMC_RESPONSE3 << 16) | IO_MMC_RESPONSE2;
330 response[3] = (IO_MMC_RESPONSE1 << 16) | IO_MMC_RESPONSE0;
331 }
332
333 return 0;
334}
335
336static int sd_init_card(const int card_no)
337{
338 bool sdhc = false;
339 unsigned long response[4];
340 int ret;
341 int i;
342
343 memset(currcard, 0, sizeof(*currcard));
344 sd_card_mux(card_no);
345
346 /* Set data bus width to 1 bit */
347 bitclr16(&IO_MMC_CONTROL, MMC_CTRL_WIDTH);
348 sd_set_clock_rate(INITIAL_CLK);
349
350 ret = sd_command(SD_GO_IDLE_STATE, 0, MMC_CMD_INITCLK, NULL);
351
352 if (ret < 0)
353 return -1;
354
355 ret = sd_command(SD_SEND_IF_COND, 0x1AA,
356 SDHC_RESP_FMT_3, response);
357 if ((response[0] & 0xFFF) == 0x1AA)
358 {
359 sdhc = true;
360 dbgprintf("found sdhc card");
361 }
362
363 while ((currcard->ocr & (1 << 31)) == 0) /* until card is powered up */
364 {
365 ret = sd_command(SD_APP_CMD, currcard->rca,
366 SDHC_RESP_FMT_1, NULL);
367 if (ret < 0)
368 {
369 dbgprintf("SD_APP_CMD failed");
370 return -1;
371 }
372
373 ret = sd_command(SD_APP_OP_COND,
374 (1 << 20) /* 3.2-3.3V */ |
375 (1 << 21) /* 3.3-3.4V */ |
376 (sdhc ? (1 << 30) : 0),
377 SDHC_RESP_FMT_3, &currcard->ocr);
378
379 if (ret < 0)
380 {
381 dbgprintf("SD_APP_OP_COND failed");
382 return -1;
383 }
384 }
385
386 dbgprintf("Card powered up");
387
388 ret = sd_command(SD_ALL_SEND_CID, 0,
389 SDHC_RESP_FMT_2, response);
390 if (ret < 0)
391 {
392 dbgprintf("SD_ALL_SEND_CID failed");
393 return -1;
394 }
395
396 for (i = 0; i<4; i++)
397 {
398 currcard->cid[i] = response[i];
399 }
400
401 ret = sd_command(SD_SEND_RELATIVE_ADDR, 0,
402 SDHC_RESP_FMT_1, &currcard->rca);
403 if (ret < 0)
404 {
405 dbgprintf("SD_SEND_RELATIVE_ADDR failed");
406 return -1;
407 }
408
409 ret = sd_command(SD_SEND_CSD, currcard->rca,
410 SDHC_RESP_FMT_2, response);
411 if (ret < 0)
412 {
413 dbgprintf("SD_SEND_CSD failed");
414 return -1;
415 }
416
417 for (i = 0; i<4; i++)
418 {
419 currcard->csd[i] = response[i];
420 }
421
422 sd_parse_csd(currcard);
423
424 sd_set_clock_rate(currcard->speed);
425
426 ret = sd_command(SD_SELECT_CARD, currcard->rca,
427 SDHC_RESP_FMT_1, NULL);
428 if (ret < 0)
429 {
430 dbgprintf("SD_SELECT_CARD failed");
431 return -1;
432 }
433
434 ret = sd_command(SD_APP_CMD, currcard->rca,
435 SDHC_RESP_FMT_1, NULL);
436 if (ret < 0)
437 {
438 dbgprintf("SD_APP_CMD failed");
439 return -1;
440 }
441
442 ret = sd_command(SD_SET_BUS_WIDTH, currcard->rca | 2,
443 SDHC_RESP_FMT_1, NULL); /* 4 bit */
444 if (ret < 0)
445 {
446 dbgprintf("SD_SET_BUS_WIDTH failed");
447 return -1;
448 }
449
450 /* Set data bus width to 4 bits */
451 bitset16(&IO_MMC_CONTROL, MMC_CTRL_WIDTH);
452
453 ret = sd_command(SD_SET_BLOCKLEN, currcard->blocksize,
454 SDHC_RESP_FMT_1, NULL);
455 if (ret < 0)
456 {
457 dbgprintf("SD_SET_BLOCKLEN failed");
458 return -1;
459 }
460
461 IO_MMC_BLOCK_LENGTH = currcard->blocksize;
462
463 dbgprintf("Card initialized");
464 currcard->initialized = 1;
465
466 return EC_OK;
467}
468
469/* lock must already by aquired */
470static void sd_select_device(int card_no)
471{
472 currcard = &card_info[card_no];
473
474 if (card_no == 0)
475 {
476 /* Main card always gets a chance */
477 sd_status[0].retry = 0;
478 }
479
480 if (currcard->initialized > 0)
481 {
482 /* This card is already initialized - switch to it */
483 sd_card_mux(card_no);
484 return;
485 }
486
487 if (currcard->initialized == 0)
488 {
489 /* Card needs (re)init */
490 sd_init_card(card_no);
491 }
492}
493
494static inline bool card_detect_target(void)
495{
496#ifdef SANSA_CONNECT
497 bool removed;
498
499 removed = IO_GIO_BITSET0 & (1 << 14);
500
501 return !removed;
502#else
503 return false;
504#endif
505}
506
507
508#ifdef HAVE_HOTSWAP
509
510static int sd1_oneshot_callback(struct timeout *tmo)
511{
512 (void)tmo;
513
514 /* This is called only if the state was stable for 300ms - check state
515 * and post appropriate event. */
516 if (card_detect_target())
517 {
518 queue_broadcast(SYS_HOTSWAP_INSERTED, 0);
519 }
520 else
521 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
522 return 0;
523}
524
525#ifdef SANSA_CONNECT
526void GIO14(void) __attribute__ ((section(".icode")));
527void GIO14(void)
528{
529 static struct timeout sd1_oneshot;
530
531 /* clear interrupt */
532 IO_INTC_IRQ2 = (1<<3);
533
534 timeout_register(&sd1_oneshot, sd1_oneshot_callback, (3*HZ/10), 0);
535}
536#endif
537
538bool sd_removable(IF_MD_NONVOID(int card_no))
539{
540#ifndef HAVE_MULTIDRIVE
541 const int card_no = 0;
542#endif
543
544 return (card_no == CARD_NUM_SLOT);
545}
546
547bool sd_present(IF_MD_NONVOID(int card_no))
548{
549#ifndef HAVE_MULTIDRIVE
550 const int card_no = 0;
551#endif
552
553 return (card_no == CARD_NUM_SLOT) ? card_detect_target() :
554#ifdef SANSA_CONNECT
555 true; /* iNAND is always present */
556#else
557 false;
558#endif
559}
560
561#else /* no hotswap */
562
563bool sd_removable(IF_MD_NONVOID(int card_no))
564{
565#ifdef HAVE_MULTIDRIVE
566 (void)card_no;
567#endif
568
569 /* not applicable */
570 return false;
571}
572
573#endif /* HAVE_HOTSWAP */
574
575static void sd_thread(void) NORETURN_ATTR;
576static void sd_thread(void)
577{
578 struct queue_event ev;
579
580 /* TODO */
581 while (1)
582 {
583 queue_wait_w_tmo(&sd_queue, &ev, HZ);
584 switch ( ev.id )
585 {
586#ifdef HAVE_HOTSWAP
587 case SYS_HOTSWAP_INSERTED:
588 case SYS_HOTSWAP_EXTRACTED:
589 {
590 int success = 1;
591 fat_lock(); /* lock-out FAT activity first -
592 prevent deadlocking via disk_mount that
593 would cause a reverse-order attempt with
594 another thread */
595 mutex_lock(&sd_mtx); /* lock-out card activity - direct calls
596 into driver that bypass the fat cache */
597
598 /* We now have exclusive control of fat cache and ata */
599
600 disk_unmount(0); /* release "by force", ensure file
601 descriptors aren't leaked and any busy
602 ones are invalid if mounting */
603
604 /* Force card init for new card, re-init for re-inserted one or
605 * clear if the last attempt to init failed with an error. */
606 card_info[0].initialized = 0;
607
608 if (ev.id == SYS_HOTSWAP_INSERTED)
609 {
610 /* FIXME: once sd_enabled is implement properly,
611 * reinitializing the controllers might be needed */
612 sd_enable(true);
613 if (success < 0) /* initialisation failed */
614 panicf("SD init failed : %d", success);
615 success = disk_mount(0); /* 0 if fail */
616 }
617
618 /* notify the system about the changed filesystems
619 */
620 if (success)
621 queue_broadcast(SYS_FS_CHANGED, 0);
622
623 /* Access is now safe */
624 mutex_unlock(&sd_mtx);
625 fat_unlock();
626 sd_enable(false);
627 }
628 break;
629#endif
630 }
631 }
632}
633
634static int sd_wait_for_state(unsigned int state)
635{
636 unsigned long response = 0;
637 unsigned int timeout = HZ; /* ticks */
638 long t = current_tick;
639
640 while (1)
641 {
642 long tick;
643 int ret = sd_command(SD_SEND_STATUS, currcard->rca,
644 SDHC_RESP_FMT_1, &response);
645 if (ret < 0)
646 return ret;
647
648 if ((SD_R1_CURRENT_STATE(response) == state))
649 {
650 return EC_OK;
651 }
652
653 if(TIME_AFTER(current_tick, t + timeout))
654 return -2;
655
656 if (TIME_AFTER((tick = current_tick), next_yield))
657 {
658 yield();
659 timeout += current_tick - tick;
660 next_yield = tick + MIN_YIELD_PERIOD;
661 }
662 }
663}
664
665static int sd_transfer_sectors(int card_no, unsigned long start,
666 int count, void *buffer, bool write)
667{
668 int ret;
669 unsigned long start_addr;
670 int dma_channel = -1;
671 bool use_direct_dma;
672 int count_per_dma;
673 unsigned long rel_addr;
674
675 dbgprintf("transfer %d %d %d", card_no, start, count);
676 mutex_lock(&sd_mtx);
677 sd_enable(true);
678
679sd_transfer_retry:
680 if (card_no == CARD_NUM_SLOT && !card_detect_target())
681 {
682 /* no external sd-card inserted */
683 ret = -EC_NOCARD;
684 goto sd_transfer_error;
685 }
686
687 sd_select_device(card_no);
688
689 if (currcard->initialized < 0)
690 {
691 ret = currcard->initialized;
692 goto sd_transfer_error;
693 }
694
695 last_disk_activity = current_tick;
696
697 ret = sd_wait_for_state(SD_TRAN);
698 if (ret < EC_OK)
699 {
700 goto sd_transfer_error;
701 }
702
703 IO_MMC_BLOCK_LENGTH = currcard->blocksize;
704
705 start_addr = start;
706
707 do
708 {
709 count_per_dma = count;
710
711 if (((unsigned long)buffer) & 0x1F)
712 {
713 /* MMC/SD interface requires 32-byte alignment of buffer */
714 use_direct_dma = false;
715 if (count > UNALIGNED_NUM_SECTORS)
716 {
717 count_per_dma = UNALIGNED_NUM_SECTORS;
718 }
719 }
720 else
721 {
722 use_direct_dma = true;
723 }
724
725 if (write == true)
726 {
727 if (use_direct_dma == false)
728 {
729 memcpy(aligned_buffer, buffer, count_per_dma*SD_BLOCK_SIZE);
730 }
731 commit_dcache_range(use_direct_dma ? buffer : aligned_buffer,
732 count_per_dma*SD_BLOCK_SIZE);
733 }
734
735 IO_MMC_NR_BLOCKS = count_per_dma;
736
737 /* Set start_addr to the correct unit (blocks or bytes) */
738 if (!(card_info[card_no].ocr & SD_OCR_CARD_CAPACITY_STATUS))
739 start_addr *= SD_BLOCK_SIZE; /* not SDHC */
740
741 ret = sd_command(write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK,
742 start_addr, MMC_CMD_DCLR | MMC_CMD_DATA |
743 SDHC_RESP_FMT_1 | (write ? MMC_CMD_WRITE : 0),
744 NULL);
745
746 if (ret < 0)
747 goto sd_transfer_error;
748
749 /* other burst modes are not supported for this peripheral */
750 dma_channel = dma_request_channel(DMA_PERIPHERAL_MMCSD,
751 DMA_MODE_8_BURST);
752
753 if (use_direct_dma == true)
754 {
755 rel_addr = ((unsigned long)buffer)-CONFIG_SDRAM_START;
756 }
757 else
758 {
759 rel_addr = ((unsigned long)aligned_buffer)-CONFIG_SDRAM_START;
760 }
761
762 IO_MMC_SD_DMA_ADDR_LOW = rel_addr & 0xFFFF;
763 IO_MMC_SD_DMA_ADDR_HI = (rel_addr & 0xFFFF0000) >> 16;
764
765 IO_MMC_SD_DMA_MODE |= MMC_DMAMODE_ENABLE;
766 if (write == true)
767 {
768 IO_MMC_SD_DMA_MODE |= MMC_DMAMODE_WRITE;
769 }
770
771 IO_MMC_SD_DMA_TRIGGER = 1;
772
773 dbgprintf("SD DMA transfer in progress");
774
775 ret = dma_wait_for_completion();
776 dma_release_channel(dma_channel);
777
778 dbgprintf("SD DMA transfer complete");
779
780 if (ret != EC_OK)
781 {
782 goto sd_transfer_error;
783 }
784
785 count -= count_per_dma;
786
787 if (write == false)
788 {
789 discard_dcache_range(use_direct_dma ? buffer : aligned_buffer,
790 count_per_dma*SD_BLOCK_SIZE);
791
792 if (use_direct_dma == false)
793 {
794 memcpy(buffer, aligned_buffer, count_per_dma*SD_BLOCK_SIZE);
795 }
796 }
797
798 buffer += count_per_dma*SD_BLOCK_SIZE;
799 start_addr += count_per_dma;
800
801 last_disk_activity = current_tick;
802
803 ret = sd_command(SD_STOP_TRANSMISSION, 0, SDHC_RESP_FMT_1, NULL);
804 if (ret < 0)
805 {
806 goto sd_transfer_error;
807 }
808
809 ret = sd_wait_for_state(SD_TRAN);
810 if (ret < 0)
811 {
812 goto sd_transfer_error;
813 }
814 } while (count > 0);
815
816 while (1)
817 {
818 sd_enable(false);
819 mutex_unlock(&sd_mtx);
820
821 return ret;
822
823sd_transfer_error:
824 if (sd_status[card_no].retry < sd_status[card_no].retry_max
825 && ret != -EC_NOCARD)
826 {
827 sd_status[card_no].retry++;
828 currcard->initialized = 0;
829 goto sd_transfer_retry;
830 }
831 }
832}
833
834int sd_read_sectors(IF_MD2(int card_no,) unsigned long start, int incount,
835 void* inbuf)
836{
837#ifndef HAVE_MULTIDRIVE
838 const int card_no = 0;
839#endif
840 return sd_transfer_sectors(card_no, start, incount, inbuf, false);
841}
842
843int sd_write_sectors(IF_MD2(int card_no,) unsigned long start, int count,
844 const void* outbuf)
845{
846#ifndef BOOTLOADER
847#ifndef HAVE_MULTIDRIVE
848 const int card_no = 0;
849#endif
850 return sd_transfer_sectors(card_no, start, count, (void*)outbuf, true);
851#else /* we don't need write support in bootloader */
852#ifdef HAVE_MULTIDRIVE
853 (void)card_no;
854#endif
855 (void)start;
856 (void)count;
857 (void)outbuf;
858 return 0;
859#endif
860}
861
862int sd_init(void)
863{
864 int ret = EC_OK;
865
866#ifndef BOOTLOADER
867 sd_enabled = true;
868 sd_enable(false);
869#endif
870 mutex_init(&sd_mtx);
871
872 mutex_lock(&sd_mtx);
873 initialized = true;
874
875 /* based on linux/drivers/mmc/dm320mmc.c
876 Copyright (C) 2006 ZSI, All Rights Reserved.
877 Written by: Ben Bostwick */
878
879 bitclr16(&IO_CLK_MOD2, CLK_MOD2_MMC);
880 bitset16(&IO_CLK_INV, CLK_INV_MMC);
881
882 /* mmc module clock: 75 Mhz (AHB) / 2 = ~37.5 Mhz */
883 /* OF uses 1, but for some reason it freezes on us */
884 IO_CLK_DIV3 = (IO_CLK_DIV3 & 0xFF00) | 0x02;
885
886 bitset16(&IO_CLK_MOD2, CLK_MOD2_MMC);
887
888 /* set mmc module into reset */
889 bitset16(&IO_MMC_CONTROL, (MMC_CTRL_DATRST | MMC_CTRL_CMDRST));
890
891 /* set resp timeout to max */
892 IO_MMC_RESPONSE_TIMEOUT |= 0x1FFF;
893 IO_MMC_READ_TIMEOUT = 0xFFFF;
894
895 /* all done, take mmc module out of reset */
896 bitclr16(&IO_MMC_CONTROL, (MMC_CTRL_DATRST | MMC_CTRL_CMDRST));
897
898#ifdef SANSA_CONNECT
899 /* GIO37 - Power Card; GIO38 - Power iNAND (both active low) */
900 IO_GIO_DIR2 &= ~((1 << 5) /* GIO37 */ | (1 << 6) /* GIO38 */);
901 IO_GIO_INV2 &= ~((1 << 5) /* GIO37 */ | (1 << 6) /* GIO38 */);
902 IO_GIO_BITCLR2 = (1 << 5) | (1 << 6);
903
904 /* GIO6 - select Card; GIO5 - select iNAND (both active low) */
905 IO_GIO_DIR0 &= ~((1 << 6) /* GIO6 */ | (1 << 5) /* GIO5 */);
906 IO_GIO_INV0 &= ~((1 << 6) /* GIO6 */ | (1 << 5) /* GIO5 */);
907 IO_GIO_BITSET0 = (1 << 6) | (1 << 5);
908
909#ifdef HAVE_HOTSWAP
910 /* GIO14 is card detect */
911 IO_GIO_DIR0 |= (1 << 14); /* Set GIO14 as input */
912 IO_GIO_INV0 &= ~(1 << 14); /* GIO14 not inverted */
913 IO_GIO_IRQPORT |= (1 << 14); /* Enable GIO14 external interrupt */
914 IO_GIO_IRQEDGE |= (1 << 14); /* Any edge detection */
915
916 /* Enable GIO14 interrupt */
917 IO_INTC_EINT2 |= INTR_EINT2_EXT14;
918#endif
919#endif
920
921 sd_select_device(1);
922
923 /* Enable Memory Card CLK */
924 bitset16(&IO_MMC_MEM_CLK_CONTROL, (1 << 8));
925
926 queue_init(&sd_queue, true);
927 sd_thread_id = create_thread(sd_thread, sd_stack, sizeof(sd_stack),
928 0, sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE)
929 IF_COP(, CPU));
930
931 mutex_unlock(&sd_mtx);
932
933 return ret;
934}
935
936long sd_last_disk_activity(void)
937{
938 return last_disk_activity;
939}
940
941tCardInfo *card_get_info_target(int card_no)
942{
943 return &card_info[card_no];
944}
945
946void sd_sleepnow(void)
947{
948}
949