summaryrefslogtreecommitdiff
path: root/firmware/target/arm/rk27xx/sd-rk27xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/rk27xx/sd-rk27xx.c')
-rw-r--r--firmware/target/arm/rk27xx/sd-rk27xx.c187
1 files changed, 69 insertions, 118 deletions
diff --git a/firmware/target/arm/rk27xx/sd-rk27xx.c b/firmware/target/arm/rk27xx/sd-rk27xx.c
index 6eeff7bae5..2ddfd0cf0a 100644
--- a/firmware/target/arm/rk27xx/sd-rk27xx.c
+++ b/firmware/target/arm/rk27xx/sd-rk27xx.c
@@ -34,13 +34,7 @@
34#include <string.h> 34#include <string.h>
35#include "panic.h" 35#include "panic.h"
36#include "stdbool.h" 36#include "stdbool.h"
37#include "ata_idle_notify.h" 37#include "storage.h"
38#include "sd.h"
39#include "usb.h"
40
41#ifdef HAVE_HOTSWAP
42#include "disk.h"
43#endif
44 38
45#include "lcd.h" 39#include "lcd.h"
46#include <stdarg.h> 40#include <stdarg.h>
@@ -57,21 +51,39 @@ static tCardInfo card_info;
57/* for compatibility */ 51/* for compatibility */
58static long last_disk_activity = -1; 52static long last_disk_activity = -1;
59 53
60static long sd_stack [(DEFAULT_STACK_SIZE*2 + 0x200)/sizeof(long)];
61static unsigned char aligned_buf[512] STORAGE_ALIGN_ATTR; 54static unsigned char aligned_buf[512] STORAGE_ALIGN_ATTR;
62 55
63static const char sd_thread_name[] = "ata/sd";
64static struct mutex sd_mtx SHAREDBSS_ATTR; 56static struct mutex sd_mtx SHAREDBSS_ATTR;
65static struct event_queue sd_queue;
66#ifndef BOOTLOADER 57#ifndef BOOTLOADER
67bool sd_enabled = false; 58bool sd_enabled = false;
68#endif 59#endif
69 60
61#ifdef CONFIG_STORAGE_MULTI
62static int sd_first_drive = 0;
63#else
64#define sd_first_drive 0
65#endif
66
70static struct semaphore transfer_completion_signal; 67static struct semaphore transfer_completion_signal;
71static struct semaphore command_completion_signal; 68static struct semaphore command_completion_signal;
72static volatile bool retry; 69static volatile bool retry;
73static volatile int cmd_error; 70static volatile int cmd_error;
74 71
72static void enable_controller(bool on)
73{
74 /* enable or disable clock signal for SD module */
75 if (on)
76 {
77 SCU_CLKCFG &= ~CLKCFG_SD;
78 led(true);
79 }
80 else
81 {
82 SCU_CLKCFG |= CLKCFG_SD;
83 led(false);
84 }
85}
86
75/* interrupt handler for SD */ 87/* interrupt handler for SD */
76void INT_SD(void) 88void INT_SD(void)
77{ 89{
@@ -318,81 +330,6 @@ static int sd_init_card(void)
318 return 0; 330 return 0;
319} 331}
320 332
321static void sd_thread(void) NORETURN_ATTR;
322static void sd_thread(void)
323{
324 struct queue_event ev;
325 bool idle_notified = false;
326
327 while (1)
328 {
329 queue_wait_w_tmo(&sd_queue, &ev, HZ);
330
331 switch ( ev.id )
332 {
333#ifdef HAVE_HOTSWAP
334 case SYS_HOTSWAP_INSERTED:
335 case SYS_HOTSWAP_EXTRACTED:;
336 int success = 1;
337
338 disk_unmount(sd_first_drive); /* release "by force" */
339
340 mutex_lock(&sd_mtx); /* lock-out card activity */
341
342 /* Force card init for new card, re-init for re-inserted one or
343 * clear if the last attempt to init failed with an error. */
344 card_info.initialized = 0;
345
346 if (ev.id == SYS_HOTSWAP_INSERTED)
347 {
348 success = 0;
349 sd_enable(true);
350 int rc = sd_init_card(sd_first_drive);
351 sd_enable(false);
352 if (rc >= 0)
353 success = 2;
354 else /* initialisation failed */
355 panicf("microSD init failed : %d", rc);
356 }
357
358 /* Access is now safe */
359 mutex_unlock(&sd_mtx);
360
361 if (success > 1)
362 success = disk_mount(sd_first_drive); /* 0 if fail */
363
364 /*
365 * Mount succeeded, or this was an EXTRACTED event,
366 * in both cases notify the system about the changed filesystems
367 */
368 if (success)
369 queue_broadcast(SYS_FS_CHANGED, 0);
370
371 break;
372#endif /* HAVE_HOTSWAP */
373
374 case SYS_TIMEOUT:
375 if (TIME_BEFORE(current_tick, last_disk_activity+(3*HZ)))
376 {
377 idle_notified = false;
378 }
379 else if (!idle_notified)
380 {
381 call_storage_idle_notifys(false);
382 idle_notified = true;
383 }
384 break;
385
386 case SYS_USB_CONNECTED:
387 usb_acknowledge(SYS_USB_CONNECTED_ACK);
388 /* Wait until the USB cable is extracted again */
389 usb_wait_for_disconnect(&sd_queue);
390
391 break;
392 }
393 }
394}
395
396static void init_controller(void) 333static void init_controller(void)
397{ 334{
398 /* reset SD module */ 335 /* reset SD module */
@@ -441,6 +378,7 @@ int sd_init(void)
441{ 378{
442 int ret; 379 int ret;
443 380
381 mutex_init(&sd_mtx);
444 semaphore_init(&transfer_completion_signal, 1, 0); 382 semaphore_init(&transfer_completion_signal, 1, 0);
445 semaphore_init(&command_completion_signal, 1, 0); 383 semaphore_init(&command_completion_signal, 1, 0);
446 384
@@ -450,13 +388,6 @@ int sd_init(void)
450 if(ret < 0) 388 if(ret < 0)
451 return ret; 389 return ret;
452 390
453 /* init mutex */
454 mutex_init(&sd_mtx);
455
456 queue_init(&sd_queue, true);
457 create_thread(sd_thread, sd_stack, sizeof(sd_stack), 0,
458 sd_thread_name IF_PRIO(, PRIORITY_USER_INTERFACE) IF_COP(, CPU));
459
460 return 0; 391 return 0;
461} 392}
462 393
@@ -523,7 +454,7 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count,
523 unsigned char *dst; 454 unsigned char *dst;
524 455
525 mutex_lock(&sd_mtx); 456 mutex_lock(&sd_mtx);
526 sd_enable(true); 457 enable_controller(true);
527 458
528 if (count <= 0 || start + count > card_info.numblocks) 459 if (count <= 0 || start + count > card_info.numblocks)
529 return -1; 460 return -1;
@@ -627,7 +558,7 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count,
627 558
628 } /* while (retry_cnt++ < 20) */ 559 } /* while (retry_cnt++ < 20) */
629 560
630 sd_enable(false); 561 enable_controller(false);
631 mutex_unlock(&sd_mtx); 562 mutex_unlock(&sd_mtx);
632 563
633 return ret; 564 return ret;
@@ -659,7 +590,7 @@ int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count,
659 /* bool card_selected = false; */ 590 /* bool card_selected = false; */
660 591
661 mutex_lock(&sd_mtx); 592 mutex_lock(&sd_mtx);
662 sd_enable(true); 593 enable_controller(true);
663 594
664 if (count <= 0 || start + count > card_info.numblocks) 595 if (count <= 0 || start + count > card_info.numblocks)
665 return -1; 596 return -1;
@@ -731,7 +662,7 @@ int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count,
731 break; 662 break;
732 } 663 }
733 664
734 sd_enable(false); 665 enable_controller(false);
735 mutex_unlock(&sd_mtx); 666 mutex_unlock(&sd_mtx);
736 667
737#ifdef RK27XX_SD_DEBUG 668#ifdef RK27XX_SD_DEBUG
@@ -746,17 +677,9 @@ int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count,
746 677
747void sd_enable(bool on) 678void sd_enable(bool on)
748{ 679{
749 /* enable or disable clock signal for SD module */ 680 mutex_lock(&sd_mtx);
750 if (on) 681 enable_controller(on);
751 { 682 mutex_unlock(&sd_mtx);
752 SCU_CLKCFG &= ~CLKCFG_SD;
753 led(true);
754 }
755 else
756 {
757 SCU_CLKCFG |= CLKCFG_SD;
758 led(false);
759 }
760} 683}
761 684
762#ifndef BOOTLOADER 685#ifndef BOOTLOADER
@@ -788,18 +711,13 @@ bool sd_present(IF_MD_NONVOID(int drive))
788 711
789static int sd_oneshot_callback(struct timeout *tmo) 712static int sd_oneshot_callback(struct timeout *tmo)
790{ 713{
791 (void)tmo;
792
793 /* This is called only if the state was stable for 300ms - check state 714 /* This is called only if the state was stable for 300ms - check state
794 * and post appropriate event. */ 715 * and post appropriate event. */
795 if (card_detect_target()) 716 queue_broadcast(card_detect_target() ? SYS_HOTSWAP_INSERTED :
796 { 717 SYS_HOTSWAP_EXTRACTED,
797 queue_broadcast(SYS_HOTSWAP_INSERTED, 0); 718 sd_first_drive);
798 }
799 else
800 queue_broadcast(SYS_HOTSWAP_EXTRACTED, 0);
801
802 return 0; 719 return 0;
720 (void)tmo;
803} 721}
804 722
805/* interrupt handler for SD detect */ 723/* interrupt handler for SD detect */
@@ -809,9 +727,42 @@ static int sd_oneshot_callback(struct timeout *tmo)
809#ifdef CONFIG_STORAGE_MULTI 727#ifdef CONFIG_STORAGE_MULTI
810int sd_num_drives(int first_drive) 728int sd_num_drives(int first_drive)
811{ 729{
812 (void)first_drive;
813
814 /* we have only one SD drive */ 730 /* we have only one SD drive */
731 sd_first_drive = first_drive;
815 return 1; 732 return 1;
816} 733}
817#endif /* CONFIG_STORAGE_MULTI */ 734#endif /* CONFIG_STORAGE_MULTI */
735
736int sd_event(long id, intptr_t data)
737{
738 int rc = 0;
739
740 switch (id)
741 {
742#ifdef HAVE_HOTSWAP
743 case SYS_HOTSWAP_INSERTED:
744 case SYS_HOTSWAP_EXTRACTED:
745 mutex_lock(&sd_mtx); /* lock-out card activity */
746
747 /* Force card init for new card, re-init for re-inserted one or
748 * clear if the last attempt to init failed with an error. */
749 card_info.initialized = 0;
750
751 if (id == SYS_HOTSWAP_INSERTED)
752 {
753 enable_controller(true);
754 rc = sd_init_card();
755 enable_controller(false);
756 }
757
758 mutex_unlock(&sd_mtx);
759 break;
760#endif /* HAVE_HOTSWAP */
761 default:
762 rc = storage_event_default_handler(id, data, last_disk_activity,
763 STORAGE_SD);
764 break;
765 }
766
767 return rc;
768}