diff options
-rw-r--r-- | firmware/target/arm/as3525/sd-as3525.c | 28 | ||||
-rw-r--r-- | firmware/target/arm/as3525/sd-as3525v2.c | 31 | ||||
-rw-r--r-- | firmware/target/arm/as3525/system-target.h | 2 |
3 files changed, 49 insertions, 12 deletions
diff --git a/firmware/target/arm/as3525/sd-as3525.c b/firmware/target/arm/as3525/sd-as3525.c index 9e55c16be6..52bf6932ec 100644 --- a/firmware/target/arm/as3525/sd-as3525.c +++ b/firmware/target/arm/as3525/sd-as3525.c | |||
@@ -669,6 +669,7 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start, | |||
669 | #endif | 669 | #endif |
670 | int ret = 0; | 670 | int ret = 0; |
671 | unsigned loops = 0; | 671 | unsigned loops = 0; |
672 | bool aligned = !((uintptr_t)buf & (CACHEALIGN_SIZE - 1)); | ||
672 | 673 | ||
673 | mutex_lock(&sd_mtx); | 674 | mutex_lock(&sd_mtx); |
674 | sd_enable(true); | 675 | sd_enable(true); |
@@ -700,6 +701,14 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start, | |||
700 | 701 | ||
701 | dma_retain(); | 702 | dma_retain(); |
702 | 703 | ||
704 | if(aligned) | ||
705 | { | ||
706 | if(write) | ||
707 | clean_dcache_range(buf, count * SECTOR_SIZE); | ||
708 | else | ||
709 | dump_dcache_range(buf, count * SECTOR_SIZE); | ||
710 | } | ||
711 | |||
703 | while(count) | 712 | while(count) |
704 | { | 713 | { |
705 | /* 128 * 512 = 2^16, and doesn't fit in the 16 bits of DATA_LENGTH | 714 | /* 128 * 512 = 2^16, and doesn't fit in the 16 bits of DATA_LENGTH |
@@ -740,12 +749,19 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start, | |||
740 | if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */ | 749 | if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */ |
741 | bank_start *= SD_BLOCK_SIZE; | 750 | bank_start *= SD_BLOCK_SIZE; |
742 | 751 | ||
743 | dma_buf = aligned_buffer; | 752 | if(aligned) |
744 | if(transfer > UNALIGNED_NUM_SECTORS) | 753 | { |
745 | transfer = UNALIGNED_NUM_SECTORS; | 754 | dma_buf = buf; |
755 | } | ||
756 | else | ||
757 | { | ||
758 | dma_buf = aligned_buffer; | ||
759 | if(transfer > UNALIGNED_NUM_SECTORS) | ||
760 | transfer = UNALIGNED_NUM_SECTORS; | ||
746 | 761 | ||
747 | if(write) | 762 | if(write) |
748 | memcpy(uncached_buffer, buf, transfer * SD_BLOCK_SIZE); | 763 | memcpy(uncached_buffer, buf, transfer * SD_BLOCK_SIZE); |
764 | } | ||
749 | 765 | ||
750 | ret = sd_wait_for_tran_state(drive); | 766 | ret = sd_wait_for_tran_state(drive); |
751 | if (ret < 0) | 767 | if (ret < 0) |
@@ -804,7 +820,7 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start, | |||
804 | 820 | ||
805 | if(!transfer_error[drive]) | 821 | if(!transfer_error[drive]) |
806 | { | 822 | { |
807 | if(!write) | 823 | if(!write && !aligned) |
808 | memcpy(buf, uncached_buffer, transfer * SD_BLOCK_SIZE); | 824 | memcpy(buf, uncached_buffer, transfer * SD_BLOCK_SIZE); |
809 | buf += transfer * SD_BLOCK_SIZE; | 825 | buf += transfer * SD_BLOCK_SIZE; |
810 | start += transfer; | 826 | start += transfer; |
diff --git a/firmware/target/arm/as3525/sd-as3525v2.c b/firmware/target/arm/as3525/sd-as3525v2.c index 386b76e758..d268bc779c 100644 --- a/firmware/target/arm/as3525/sd-as3525v2.c +++ b/firmware/target/arm/as3525/sd-as3525v2.c | |||
@@ -789,6 +789,8 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start, | |||
789 | #ifndef HAVE_MULTIDRIVE | 789 | #ifndef HAVE_MULTIDRIVE |
790 | const int drive = 0; | 790 | const int drive = 0; |
791 | #endif | 791 | #endif |
792 | bool aligned = !((uintptr_t)buf & (CACHEALIGN_SIZE - 1)); | ||
793 | |||
792 | 794 | ||
793 | mutex_lock(&sd_mtx); | 795 | mutex_lock(&sd_mtx); |
794 | #ifndef BOOTLOADER | 796 | #ifndef BOOTLOADER |
@@ -828,17 +830,34 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start, | |||
828 | last_disk_activity = current_tick; | 830 | last_disk_activity = current_tick; |
829 | dma_retain(); | 831 | dma_retain(); |
830 | 832 | ||
833 | if(aligned) | ||
834 | { | ||
835 | if(write) | ||
836 | clean_dcache_range(buf, count * SECTOR_SIZE); | ||
837 | else | ||
838 | dump_dcache_range(buf, count * SECTOR_SIZE); | ||
839 | } | ||
840 | |||
831 | const int cmd = write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK; | 841 | const int cmd = write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK; |
832 | 842 | ||
833 | do | 843 | do |
834 | { | 844 | { |
835 | void *dma_buf = aligned_buffer; | 845 | void *dma_buf; |
836 | unsigned int transfer = count; | 846 | unsigned int transfer = count; |
837 | if(transfer > UNALIGNED_NUM_SECTORS) | ||
838 | transfer = UNALIGNED_NUM_SECTORS; | ||
839 | 847 | ||
840 | if(write) | 848 | if(aligned) |
841 | memcpy(uncached_buffer, buf, transfer * SD_BLOCK_SIZE); | 849 | { |
850 | dma_buf = buf; | ||
851 | } | ||
852 | else | ||
853 | { | ||
854 | dma_buf = aligned_buffer; | ||
855 | if(transfer > UNALIGNED_NUM_SECTORS) | ||
856 | transfer = UNALIGNED_NUM_SECTORS; | ||
857 | |||
858 | if(write) | ||
859 | memcpy(uncached_buffer, buf, transfer * SD_BLOCK_SIZE); | ||
860 | } | ||
842 | 861 | ||
843 | /* Interrupt handler might set this to true during transfer */ | 862 | /* Interrupt handler might set this to true during transfer */ |
844 | retry = false; | 863 | retry = false; |
@@ -893,7 +912,7 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start, | |||
893 | 912 | ||
894 | if(!retry) | 913 | if(!retry) |
895 | { | 914 | { |
896 | if(!write) | 915 | if(!write && !aligned) |
897 | memcpy(buf, uncached_buffer, transfer * SD_BLOCK_SIZE); | 916 | memcpy(buf, uncached_buffer, transfer * SD_BLOCK_SIZE); |
898 | buf += transfer * SD_BLOCK_SIZE; | 917 | buf += transfer * SD_BLOCK_SIZE; |
899 | start += transfer; | 918 | start += transfer; |
diff --git a/firmware/target/arm/as3525/system-target.h b/firmware/target/arm/as3525/system-target.h index f7dc1ac312..5d11ecb26c 100644 --- a/firmware/target/arm/as3525/system-target.h +++ b/firmware/target/arm/as3525/system-target.h | |||
@@ -27,6 +27,8 @@ | |||
27 | 27 | ||
28 | #include "clock-target.h" /* CPUFREQ_* are defined here */ | 28 | #include "clock-target.h" /* CPUFREQ_* are defined here */ |
29 | 29 | ||
30 | #define STORAGE_WANTS_ALIGN | ||
31 | |||
30 | /* We can use a interrupt-based mechanism on the fuzev2 */ | 32 | /* We can use a interrupt-based mechanism on the fuzev2 */ |
31 | #define INCREASED_SCROLLWHEEL_POLLING \ | 33 | #define INCREASED_SCROLLWHEEL_POLLING \ |
32 | (defined(HAVE_SCROLLWHEEL) && (CONFIG_CPU == AS3525)) | 34 | (defined(HAVE_SCROLLWHEEL) && (CONFIG_CPU == AS3525)) |