summaryrefslogtreecommitdiff
path: root/firmware/target/arm/as3525/sd-as3525v2.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/as3525/sd-as3525v2.c')
-rw-r--r--firmware/target/arm/as3525/sd-as3525v2.c188
1 files changed, 69 insertions, 119 deletions
diff --git a/firmware/target/arm/as3525/sd-as3525v2.c b/firmware/target/arm/as3525/sd-as3525v2.c
index 3f39629e0b..f78345577c 100644
--- a/firmware/target/arm/as3525/sd-as3525v2.c
+++ b/firmware/target/arm/as3525/sd-as3525v2.c
@@ -22,7 +22,6 @@
22 22
23#include "config.h" /* for HAVE_MULTIVOLUME */ 23#include "config.h" /* for HAVE_MULTIVOLUME */
24#include "fs_defines.h" 24#include "fs_defines.h"
25#include "thread.h"
26#include "gcc_extensions.h" 25#include "gcc_extensions.h"
27#include "led.h" 26#include "led.h"
28#include "sdmmc.h" 27#include "sdmmc.h"
@@ -36,19 +35,7 @@
36#include "pl081.h" /* DMA controller */ 35#include "pl081.h" /* DMA controller */
37#include "dma-target.h" /* DMA request lines */ 36#include "dma-target.h" /* DMA request lines */
38#include "clock-target.h" 37#include "clock-target.h"
39#include "panic.h" 38#include "storage.h"
40#include "stdbool.h"
41#include "ata_idle_notify.h"
42#include "sd.h"
43#include "usb.h"
44
45#ifdef HAVE_HOTSWAP
46#include "disk.h"
47#endif
48
49#include "lcd.h"
50#include <stdarg.h>
51#include "sysfont.h"
52 39
53#define INTERNAL_AS3525 0 /* embedded SD card */ 40#define INTERNAL_AS3525 0 /* embedded SD card */
54#define SD_SLOT_AS3525 1 /* SD slot if present */ 41#define SD_SLOT_AS3525 1 /* SD slot if present */
@@ -327,13 +314,15 @@ static unsigned char *uncached_buffer = AS3525_UNCACHED_ADDR(&aligned_buffer[0])
327 314
328static tCardInfo card_info[NUM_DRIVES]; 315static tCardInfo card_info[NUM_DRIVES];
329 316
317#ifdef CONFIG_STORAGE_MULTI
318static int sd_first_drive = 0;
319#else
320#define sd_first_drive 0
321#endif
322
330/* for compatibility */ 323/* for compatibility */
331static long last_disk_activity = -1; 324static long last_disk_activity = -1;
332
333static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)];
334static const char sd_thread_name[] = "ata/sd";
335static struct mutex sd_mtx SHAREDBSS_ATTR; 325static struct mutex sd_mtx SHAREDBSS_ATTR;
336static struct event_queue sd_queue;
337#ifndef BOOTLOADER 326#ifndef BOOTLOADER
338bool sd_enabled = false; 327bool sd_enabled = false;
339#endif 328#endif
@@ -371,6 +360,22 @@ void INT_NAND(void)
371 MCI_CTRL |= INT_ENABLE; 360 MCI_CTRL |= INT_ENABLE;
372} 361}
373 362
363#ifndef BOOTLOADER
364static void enable_controller(bool on)
365{
366 if (on)
367 {
368 bitset32(&CGU_PERI, CGU_MCI_CLOCK_ENABLE);
369 CGU_SDSLOT |= (1<<7); /* interface enable */
370 }
371 else
372 {
373 CGU_SDSLOT &= ~(1<<7); /* interface enable */
374 bitclr32(&CGU_PERI, CGU_MCI_CLOCK_ENABLE);
375 }
376}
377#endif /* BOOTLOADER */
378
374static inline bool card_detect_target(void) 379static inline bool card_detect_target(void)
375{ 380{
376#if defined(HAVE_MULTIDRIVE) 381#if defined(HAVE_MULTIDRIVE)
@@ -577,75 +582,6 @@ static int sd_init_card(const int drive)
577 return 0; 582 return 0;
578} 583}
579 584
580static void sd_thread(void) NORETURN_ATTR;
581static void sd_thread(void)
582{
583 struct queue_event ev;
584 bool idle_notified = false;
585
586 while (1)
587 {
588 queue_wait_w_tmo(&sd_queue, &ev, HZ);
589
590 switch ( ev.id )
591 {
592#ifdef HAVE_HOTSWAP
593 case SYS_HOTSWAP_INSERTED:
594 case SYS_HOTSWAP_EXTRACTED:;
595 int success = 1;
596
597 disk_unmount(SD_SLOT_AS3525); /* release "by force" */
598
599 mutex_lock(&sd_mtx); /* lock-out card activity */
600
601 /* Force card init for new card, re-init for re-inserted one or
602 * clear if the last attempt to init failed with an error. */
603 card_info[SD_SLOT_AS3525].initialized = 0;
604
605 if (ev.id == SYS_HOTSWAP_INSERTED)
606 {
607 sd_enable(true);
608 success = sd_init_card(SD_SLOT_AS3525) == 0 ? 2 : 0;
609 sd_enable(false);
610 }
611
612 mutex_unlock(&sd_mtx);
613
614 if (success > 1)
615 success = disk_mount(SD_SLOT_AS3525); /* 0 if fail */
616
617 /*
618 * Mount succeeded, or this was an EXTRACTED event,
619 * in both cases notify the system about the changed filesystems
620 */
621 if (success)
622 queue_broadcast(SYS_FS_CHANGED, 0);
623
624 break;
625#endif /* HAVE_HOTSWAP */
626
627 case SYS_TIMEOUT:
628 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
629 {
630 idle_notified = false;
631 }
632 else if (!idle_notified)
633 {
634 call_storage_idle_notifys(false);
635 idle_notified = true;
636 }
637 break;
638
639 case SYS_USB_CONNECTED:
640 usb_acknowledge(SYS_USB_CONNECTED_ACK);
641 /* Wait until the USB cable is extracted again */
642 usb_wait_for_disconnect(&sd_queue);
643
644 break;
645 }
646 }
647}
648
649static void init_controller(void) 585static void init_controller(void)
650{ 586{
651 int hcon_numcards = ((MCI_HCON>>1) & 0x1F) + 1; 587 int hcon_numcards = ((MCI_HCON>>1) & 0x1F) + 1;
@@ -706,6 +642,7 @@ int sd_init(void)
706 | (AS3525_SDSLOT_DIV << 2) 642 | (AS3525_SDSLOT_DIV << 2)
707 | 1; /* clock source = PLLA */ 643 | 1; /* clock source = PLLA */
708 644
645 mutex_init(&sd_mtx);
709 semaphore_init(&transfer_completion_signal, 1, 0); 646 semaphore_init(&transfer_completion_signal, 1, 0);
710 semaphore_init(&command_completion_signal, 1, 0); 647 semaphore_init(&command_completion_signal, 1, 0);
711 648
@@ -737,16 +674,9 @@ int sd_init(void)
737 if(ret < 0) 674 if(ret < 0)
738 return ret; 675 return ret;
739 676
740 /* init mutex */
741 mutex_init(&sd_mtx);
742
743 queue_init(&sd_queue, true);
744 create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0,
745 sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU));
746
747#ifndef BOOTLOADER 677#ifndef BOOTLOADER
748 sd_enabled = true; 678 sd_enabled = true;
749 sd_enable(false); 679 enable_controller(false);
750#endif 680#endif
751 return 0; 681 return 0;
752} 682}
@@ -767,7 +697,7 @@ static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start,
767 697
768 mutex_lock(&sd_mtx); 698 mutex_lock(&sd_mtx);
769#ifndef BOOTLOADER 699#ifndef BOOTLOADER
770 sd_enable(true); 700 enable_controller(true);
771 led(true); 701 led(true);
772#endif 702#endif
773 703
@@ -925,7 +855,7 @@ retry_with_reinit:
925 855
926exit: 856exit:
927#ifndef BOOTLOADER 857#ifndef BOOTLOADER
928 sd_enable(false); 858 enable_controller(false);
929 led(false); 859 led(false);
930#endif 860#endif
931 mutex_unlock(&sd_mtx); 861 mutex_unlock(&sd_mtx);
@@ -952,16 +882,9 @@ long sd_last_disk_activity(void)
952 882
953void sd_enable(bool on) 883void sd_enable(bool on)
954{ 884{
955 if (on) 885 mutex_lock(&sd_mtx);
956 { 886 enable_controller(on);
957 bitset32(&CGU_PERI, CGU_MCI_CLOCK_ENABLE); 887 mutex_unlock(&sd_mtx);
958 CGU_SDSLOT |= (1<<7); /* interface enable */
959 }
960 else
961 {
962 CGU_SDSLOT &= ~(1<<7); /* interface enable */
963 bitclr32(&CGU_PERI, CGU_MCI_CLOCK_ENABLE);
964 }
965} 888}
966#endif /* BOOTLOADER */ 889#endif /* BOOTLOADER */
967 890
@@ -983,18 +906,13 @@ bool sd_present(IF_MD_NONVOID(int drive))
983 906
984static int sd1_oneshot_callback(struct timeout *tmo) 907static int sd1_oneshot_callback(struct timeout *tmo)
985{ 908{
986 (void)tmo;
987
988 /* This is called only if the state was stable for 300ms - check state 909 /* This is called only if the state was stable for 300ms - check state
989 * and post appropriate event. */ 910 * and post appropriate event. */
990 if (card_detect_target()) 911 queue_broadcast(card_detect_target() ? SYS_HOTSWAP_INSERTED :
991 { 912 SYS_HOTSWAP_EXTRACTED,
992 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 913 sd_first_drive + SD_SLOT_AS3525);
993 }
994 else
995 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
996
997 return 0; 914 return 0;
915 (void)tmo;
998} 916}
999 917
1000void sd_gpioa_isr(void) 918void sd_gpioa_isr(void)
@@ -1012,9 +930,41 @@ void sd_gpioa_isr(void)
1012#ifdef CONFIG_STORAGE_MULTI 930#ifdef CONFIG_STORAGE_MULTI
1013int sd_num_drives(int first_drive) 931int sd_num_drives(int first_drive)
1014{ 932{
1015 /* We don't care which logical drive number(s) we have been assigned */ 933 sd_first_drive = first_drive;
1016 (void)first_drive;
1017
1018 return NUM_DRIVES; 934 return NUM_DRIVES;
1019} 935}
1020#endif /* CONFIG_STORAGE_MULTI */ 936#endif /* CONFIG_STORAGE_MULTI */
937
938int sd_event(long id, intptr_t data)
939{
940 int rc = 0;
941
942 switch (id)
943 {
944#ifdef HAVE_HOTSWAP
945 case SYS_HOTSWAP_INSERTED:
946 case SYS_HOTSWAP_EXTRACTED:
947 mutex_lock(&sd_mtx); /* lock-out card activity */
948
949 /* Force card init for new card, re-init for re-inserted one or
950 * clear if the last attempt to init failed with an error. */
951 card_info[data].initialized = 0;
952
953 if (id == SYS_HOTSWAP_INSERTED)
954 {
955 enable_controller(true);
956 rc = sd_init_card(data);
957 enable_controller(false);
958 }
959
960 mutex_unlock(&sd_mtx);
961 break;
962#endif /* HAVE_HOTSWAP */
963 default:
964 rc = storage_event_default_handler(id, data, last_disk_activity,
965 STORAGE_SD);
966 break;
967 }
968
969 return rc;
970}