summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/export/config/sansaclipplus.h4
-rw-r--r--firmware/target/arm/as3525/sd-as3525v2.c129
2 files changed, 99 insertions, 34 deletions
diff --git a/firmware/export/config/sansaclipplus.h b/firmware/export/config/sansaclipplus.h
index f54951f0ac..310df3a115 100644
--- a/firmware/export/config/sansaclipplus.h
+++ b/firmware/export/config/sansaclipplus.h
@@ -9,13 +9,13 @@
9#define FIRMWARE_OFFSET_FILE_DATA 8 9#define FIRMWARE_OFFSET_FILE_DATA 8
10#define FIRMWARE_OFFSET_FILE_CRC 0 10#define FIRMWARE_OFFSET_FILE_CRC 0
11 11
12#if 0 /* TODO */ 12
13#ifndef BOOTLOADER 13#ifndef BOOTLOADER
14#define HAVE_MULTIDRIVE 14#define HAVE_MULTIDRIVE
15#define NUM_DRIVES 2 15#define NUM_DRIVES 2
16#define HAVE_HOTSWAP 16#define HAVE_HOTSWAP
17#endif 17#endif
18#endif 18
19 19
20#if 0 /* disabled since there is no driver (yet) */ 20#if 0 /* disabled since there is no driver (yet) */
21 21
diff --git a/firmware/target/arm/as3525/sd-as3525v2.c b/firmware/target/arm/as3525/sd-as3525v2.c
index 37f3a70601..992db4d307 100644
--- a/firmware/target/arm/as3525/sd-as3525v2.c
+++ b/firmware/target/arm/as3525/sd-as3525v2.c
@@ -140,6 +140,7 @@
140#define CMD_WAIT_PRV_DAT_BIT (1<<13) 140#define CMD_WAIT_PRV_DAT_BIT (1<<13)
141#define CMD_ABRT_CMD_BIT (1<<14) 141#define CMD_ABRT_CMD_BIT (1<<14)
142#define CMD_SEND_INIT_BIT (1<<15) 142#define CMD_SEND_INIT_BIT (1<<15)
143#define CMD_CARD_NO(x) ((x)<<16) /* 5 bits wide */
143#define CMD_SEND_CLK_ONLY (1<<21) 144#define CMD_SEND_CLK_ONLY (1<<21)
144#define CMD_READ_CEATA (1<<22) 145#define CMD_READ_CEATA (1<<22)
145#define CMD_CCS_EXPECTED (1<<23) 146#define CMD_CCS_EXPECTED (1<<23)
@@ -326,14 +327,9 @@ static struct wakeup transfer_completion_signal;
326static volatile bool retry; 327static volatile bool retry;
327static volatile bool data_transfer = false; 328static volatile bool data_transfer = false;
328 329
329static inline bool card_detect_target(void)
330{
331#if defined(HAVE_MULTIDRIVE) 330#if defined(HAVE_MULTIDRIVE)
332 return !(GPIOA_PIN(2)); 331int active_card = 0;
333#else
334 return false;
335#endif 332#endif
336}
337 333
338static inline void mci_delay(void) { int i = 0xffff; while(i--) ; } 334static inline void mci_delay(void) { int i = 0xffff; while(i--) ; }
339 335
@@ -353,10 +349,32 @@ void INT_NAND(void)
353 MCI_CTRL |= INT_ENABLE; 349 MCI_CTRL |= INT_ENABLE;
354} 350}
355 351
356static bool send_cmd(const int cmd, const int arg, const int flags, 352static inline bool card_detect_target(void)
353{
354#if defined(HAVE_MULTIDRIVE)
355 return !(GPIOA_PIN(2));
356#else
357 return false;
358#endif
359}
360
361static bool send_cmd(const int drive, const int cmd, const int arg, const int flags,
357 unsigned long *response) 362 unsigned long *response)
358{ 363{
364#if defined(HAVE_MULTIDRIVE)
365 /* Check to see if we need to switch cards */
366 if(sd_present(SD_SLOT_AS3525))
367 if(active_card != drive)
368 {
369 GPIOB_PIN(5) = (1-drive) << 5;
370 active_card = drive;
371 }
372
373 MCI_COMMAND = cmd | CMD_CARD_NO(drive);
374#else
375 (void) drive;
359 MCI_COMMAND = cmd; 376 MCI_COMMAND = cmd;
377#endif
360 378
361 if(flags & MCI_RESP) 379 if(flags & MCI_RESP)
362 { 380 {
@@ -420,13 +438,13 @@ static int sd_init_card(const int drive)
420 /* Start of Card Identification Mode ************************************/ 438 /* Start of Card Identification Mode ************************************/
421 439
422 /* CMD0 Go Idle */ 440 /* CMD0 Go Idle */
423 if(!send_cmd(SD_GO_IDLE_STATE, 0, MCI_NO_RESP, NULL)) 441 if(!send_cmd(drive, SD_GO_IDLE_STATE, 0, MCI_NO_RESP, NULL))
424 return -1; 442 return -1;
425 mci_delay(); 443 mci_delay();
426 444
427 /* CMD8 Check for v2 sd card. Must be sent before using ACMD41 445 /* CMD8 Check for v2 sd card. Must be sent before using ACMD41
428 Non v2 cards will not respond to this command*/ 446 Non v2 cards will not respond to this command*/
429 if(send_cmd(SD_SEND_IF_COND, 0x1AA, MCI_RESP, &response)) 447 if(send_cmd(drive, SD_SEND_IF_COND, 0x1AA, MCI_RESP, &response))
430 if((response & 0xFFF) == 0x1AA) 448 if((response & 0xFFF) == 0x1AA)
431 sd_v2 = true; 449 sd_v2 = true;
432 450
@@ -439,37 +457,45 @@ static int sd_init_card(const int drive)
439 return -2; 457 return -2;
440 458
441 /* app_cmd */ 459 /* app_cmd */
442 send_cmd(SD_APP_CMD, 0, MCI_RESP, &response); 460 send_cmd(drive, SD_APP_CMD, 0, MCI_RESP, &response);
443 461
444 /* ACMD41 For v2 cards set HCS bit[30] & send host voltage range to all */ 462 /* ACMD41 For v2 cards set HCS bit[30] & send host voltage range to all */
445 if(!send_cmd(SD_APP_OP_COND, (sd_v2 ? 0x40FF8000 : (1<<23)), 463 if(!send_cmd(drive, SD_APP_OP_COND, (sd_v2 ? 0x40FF8000 : (1<<23)),
446 MCI_RESP, &card_info[drive].ocr)) 464 MCI_RESP, &card_info[drive].ocr))
447 return -3; 465 return -3;
448 } while(!(card_info[drive].ocr & (1<<31)) ); 466 } while(!(card_info[drive].ocr & (1<<31)) );
449 467
450 /* CMD2 send CID */ 468 /* CMD2 send CID */
451 if(!send_cmd(SD_ALL_SEND_CID, 0, MCI_RESP|MCI_LONG_RESP, card_info[drive].cid)) 469 if(!send_cmd(drive, SD_ALL_SEND_CID, 0, MCI_RESP|MCI_LONG_RESP, card_info[drive].cid))
452 return -5; 470 return -4;
453 471
454 /* CMD3 send RCA */ 472 /* CMD3 send RCA */
455 if(!send_cmd(SD_SEND_RELATIVE_ADDR, 0, MCI_RESP, &card_info[drive].rca)) 473 if(!send_cmd(drive, SD_SEND_RELATIVE_ADDR, 0, MCI_RESP, &card_info[drive].rca))
456 return -4; 474 return -5;
457 475
476#ifdef HAVE_MULTIDRIVE
477 /* Make sure we have 2 unique rca numbers */
478 if(card_info[INTERNAL_AS3525].rca == card_info[SD_SLOT_AS3525].rca)
479 if(!send_cmd(drive, SD_SEND_RELATIVE_ADDR, 0, MCI_RESP, &card_info[drive].rca))
480 return -6;
481#endif
458 /* End of Card Identification Mode ************************************/ 482 /* End of Card Identification Mode ************************************/
459 483
460 /* CMD9 send CSD */ 484 /* CMD9 send CSD */
461 if(!send_cmd(SD_SEND_CSD, card_info[drive].rca, 485 if(!send_cmd(drive, SD_SEND_CSD, card_info[drive].rca,
462 MCI_RESP|MCI_LONG_RESP, card_info[drive].csd)) 486 MCI_RESP|MCI_LONG_RESP, card_info[drive].csd))
463 return -5; 487 return -7;
464 488
465 sd_parse_csd(&card_info[drive]); 489 sd_parse_csd(&card_info[drive]);
466 490
467 /* Card back to full speed */ 491 /* Card back to full speed */
468 MCI_CLKDIV &= ~(0xFF); /* CLK_DIV_0 : bits 7:0 = 0x00 */ 492 MCI_CLKDIV &= ~(0xFF); /* CLK_DIV_0 : bits 7:0 = 0x00 */
469 493
494#ifndef HAVE_MULTIDRIVE
470 /* CMD7 w/rca: Select card to put it in TRAN state */ 495 /* CMD7 w/rca: Select card to put it in TRAN state */
471 if(!send_cmd(SD_SELECT_CARD, card_info[drive].rca, MCI_NO_RESP, NULL)) 496 if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_NO_RESP, NULL))
472 return -6; 497 return -8;
498#endif
473 499
474 card_info[drive].initialized = 1; 500 card_info[drive].initialized = 1;
475 501
@@ -566,12 +592,15 @@ static void sd_thread(void)
566 592
567static void init_controller(void) 593static void init_controller(void)
568{ 594{
569 MCI_PWREN = 0x0; /* power off all cards */ 595 int hcon_numcards = ((MCI_HCON>>1) & 0x1F) + 1;
596 int card_mask = (1 << hcon_numcards) - 1;
597
598 MCI_PWREN &= ~card_mask; /* power off all cards */
570 599
571 MCI_CLKSRC = 0x00; /* All CLK_SRC_CRD set to 0*/ 600 MCI_CLKSRC = 0x00; /* All CLK_SRC_CRD set to 0*/
572 MCI_CLKDIV = 0x00; /* CLK_DIV_0 : bits 7:0 */ 601 MCI_CLKDIV = 0x00; /* CLK_DIV_0 : bits 7:0 */
573 602
574 MCI_PWREN = PWR_CRD_0; /* power up card 0 (internal) */ 603 MCI_PWREN |= card_mask; /* power up cards */
575 mci_delay(); 604 mci_delay();
576 605
577 MCI_CTRL |= CTRL_RESET; 606 MCI_CTRL |= CTRL_RESET;
@@ -584,7 +613,7 @@ static void init_controller(void)
584 613
585 MCI_CTYPE = 0x0; /* all cards 1 bit bus for now */ 614 MCI_CTYPE = 0x0; /* all cards 1 bit bus for now */
586 615
587 MCI_CLKENA = CCLK_ENA_CRD0; 616 MCI_CLKENA = card_mask;
588 617
589 MCI_ARGUMENT = 0; 618 MCI_ARGUMENT = 0;
590 MCI_COMMAND = CMD_DONE_BIT|CMD_SEND_CLK_ONLY|CMD_WAIT_PRV_DAT_BIT; 619 MCI_COMMAND = CMD_DONE_BIT|CMD_SEND_CLK_ONLY|CMD_WAIT_PRV_DAT_BIT;
@@ -598,6 +627,8 @@ static void init_controller(void)
598 627
599 MCI_MASK = 0xffffffff & ~(MCI_INT_ACD|MCI_INT_CRDDET); 628 MCI_MASK = 0xffffffff & ~(MCI_INT_ACD|MCI_INT_CRDDET);
600 629
630 GPIOB_DIR |= (1<<5); /* Pin B5 output */
631
601 MCI_CTRL |= INT_ENABLE; 632 MCI_CTRL |= INT_ENABLE;
602} 633}
603 634
@@ -614,14 +645,23 @@ int sd_init(void)
614 CGU_MEMSTICK = (1<<8) | (1<<7) | 645 CGU_MEMSTICK = (1<<8) | (1<<7) |
615 ((CLK_DIV(AS3525_PLLA_FREQ, AS3525_MS_FREQ) -1) << 2) | 1; 646 ((CLK_DIV(AS3525_PLLA_FREQ, AS3525_MS_FREQ) -1) << 2) | 1;
616 647
617 /* FIXME: divider should be shifted by 2, but doing prevents card
618 * initialisation */
619 *(volatile int*)(CGU_BASE+0x3C) = (1<<7) | 648 *(volatile int*)(CGU_BASE+0x3C) = (1<<7) |
620 (CLK_DIV(AS3525_PLLA_FREQ, 24000000) -1) | 1; 649 (CLK_DIV(AS3525_PLLA_FREQ, 24000000) -1)<<2 | 1;
621 650
622 wakeup_init(&transfer_completion_signal); 651 wakeup_init(&transfer_completion_signal);
623 652
624 VIC_INT_ENABLE |= INTERRUPT_NAND; 653#ifdef HAVE_MULTIDRIVE
654 /* setup isr for microsd monitoring */
655 VIC_INT_ENABLE = (INTERRUPT_GPIOA);
656 /* clear previous irq */
657 GPIOA_IC = (1<<2);
658 /* enable edge detecting */
659 GPIOA_IS &= ~(1<<2);
660 /* detect both raising and falling edges */
661 GPIOA_IBE |= (1<<2);
662#endif
663
664 VIC_INT_ENABLE = INTERRUPT_NAND;
625 665
626 init_controller(); 666 init_controller();
627 ret = sd_init_card(INTERNAL_AS3525); 667 ret = sd_init_card(INTERNAL_AS3525);
@@ -652,7 +692,7 @@ static int sd_wait_for_state(const int drive, unsigned int state)
652 { 692 {
653 long tick; 693 long tick;
654 694
655 if(!send_cmd(SD_SEND_STATUS, card_info[drive].rca, 695 if(!send_cmd(drive, SD_SEND_STATUS, card_info[drive].rca,
656 MCI_RESP, &response)) 696 MCI_RESP, &response))
657 return -1; 697 return -1;
658 698
@@ -698,6 +738,12 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
698 } 738 }
699 } 739 }
700 740
741#ifdef HAVE_MULTIDRIVE
742 /* CMD7 w/rca: Select card to put it in TRAN state */
743 if(!send_cmd(drive, SD_SELECT_CARD, card_info[drive].rca, MCI_NO_RESP, NULL))
744 return -6;
745#endif
746
701 last_disk_activity = current_tick; 747 last_disk_activity = current_tick;
702 ret = sd_wait_for_state(drive, SD_TRAN); 748 ret = sd_wait_for_state(drive, SD_TRAN);
703 if (ret < 0) 749 if (ret < 0)
@@ -706,7 +752,7 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
706 "IDLE", "RDY", "IDENT", "STBY", "TRAN", "DATA", "RCV", "PRG", "DIS" 752 "IDLE", "RDY", "IDENT", "STBY", "TRAN", "DATA", "RCV", "PRG", "DIS"
707 }; 753 };
708 if(ret <= -10) 754 if(ret <= -10)
709 panicf("wait for state failed (%s)", st[(-ret / 10) % 9]); 755 panicf("wait for state failed (%s) %d", st[(-ret / 10) % 9], drive);
710 else 756 else
711 panicf("wait for state failed"); 757 panicf("wait for state failed");
712 goto sd_transfer_error; 758 goto sd_transfer_error;
@@ -745,9 +791,9 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
745 791
746 792
747 if(card_info[drive].ocr & (1<<30) ) /* SDHC */ 793 if(card_info[drive].ocr & (1<<30) ) /* SDHC */
748 ret = send_cmd(cmd, start, MCI_NO_RESP, NULL); 794 ret = send_cmd(drive, cmd, start, MCI_NO_RESP, NULL);
749 else 795 else
750 ret = send_cmd(cmd, start * SD_BLOCK_SIZE, 796 ret = send_cmd(drive, cmd, start * SD_BLOCK_SIZE,
751 MCI_NO_RESP, NULL); 797 MCI_NO_RESP, NULL);
752 798
753 if (ret < 0) 799 if (ret < 0)
@@ -766,7 +812,7 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
766 812
767 last_disk_activity = current_tick; 813 last_disk_activity = current_tick;
768 814
769 if(!send_cmd(SD_STOP_TRANSMISSION, 0, MCI_NO_RESP, NULL)) 815 if(!send_cmd(drive, SD_STOP_TRANSMISSION, 0, MCI_NO_RESP, NULL))
770 { 816 {
771 ret = -666; 817 ret = -666;
772 panicf("STOP TRANSMISSION failed"); 818 panicf("STOP TRANSMISSION failed");
@@ -792,6 +838,12 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start,
792 838
793 dma_release(); 839 dma_release();
794 840
841#ifdef HAVE_MULTIDRIVE
842 /* CMD7 w/rca =0 : deselect card to put it in STBY state */
843 if(!send_cmd(drive, SD_SELECT_CARD, 0, MCI_NO_RESP, NULL))
844 return -6;
845#endif
846
795#ifndef BOOTLOADER 847#ifndef BOOTLOADER
796 sd_enable(false); 848 sd_enable(false);
797#endif 849#endif
@@ -836,7 +888,10 @@ long sd_last_disk_activity(void)
836void sd_enable(bool on) 888void sd_enable(bool on)
837{ 889{
838 /* TODO */ 890 /* TODO */
839 (void)on; 891 if(on)
892 CCU_IO |= (1<<2); /* XPD is SD-MCI interface (b3:2 = 01) */
893 else
894 CCU_IO &= ~(1<<2); /* XPD is general purpose IO (b3:2 = 00) */
840 return; 895 return;
841} 896}
842 897
@@ -889,3 +944,13 @@ void card_enable_monitoring_target(bool on)
889 GPIOA_IE &= ~(1<<2); 944 GPIOA_IE &= ~(1<<2);
890} 945}
891#endif /* HAVE_HOTSWAP */ 946#endif /* HAVE_HOTSWAP */
947
948#ifdef CONFIG_STORAGE_MULTI
949int sd_num_drives(int first_drive)
950{
951 /* We don't care which logical drive number(s) we have been assigned */
952 (void)first_drive;
953
954 return NUM_DRIVES;
955}
956#endif /* CONFIG_STORAGE_MULTI */