diff options
Diffstat (limited to 'firmware/target')
-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 | 6 |
3 files changed, 53 insertions, 12 deletions
diff --git a/firmware/target/arm/as3525/sd-as3525.c b/firmware/target/arm/as3525/sd-as3525.c index 7e61fa509f..423181ab7a 100644 --- a/firmware/target/arm/as3525/sd-as3525.c +++ b/firmware/target/arm/as3525/sd-as3525.c | |||
@@ -686,6 +686,7 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start, | |||
686 | #endif | 686 | #endif |
687 | int ret = 0; | 687 | int ret = 0; |
688 | unsigned loops = 0; | 688 | unsigned loops = 0; |
689 | bool aligned = !((uintptr_t)buf & (CACHEALIGN_SIZE - 1)); | ||
689 | 690 | ||
690 | mutex_lock(&sd_mtx); | 691 | mutex_lock(&sd_mtx); |
691 | sd_enable(true); | 692 | sd_enable(true); |
@@ -717,6 +718,14 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start, | |||
717 | 718 | ||
718 | dma_retain(); | 719 | dma_retain(); |
719 | 720 | ||
721 | if(aligned) | ||
722 | { | ||
723 | if(write) | ||
724 | clean_dcache_range(buf, count * SECTOR_SIZE); | ||
725 | else | ||
726 | dump_dcache_range(buf, count * SECTOR_SIZE); | ||
727 | } | ||
728 | |||
720 | while(count) | 729 | while(count) |
721 | { | 730 | { |
722 | /* 128 * 512 = 2^16, and doesn't fit in the 16 bits of DATA_LENGTH | 731 | /* 128 * 512 = 2^16, and doesn't fit in the 16 bits of DATA_LENGTH |
@@ -758,12 +767,19 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start, | |||
758 | if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */ | 767 | if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */ |
759 | bank_start *= SD_BLOCK_SIZE; | 768 | bank_start *= SD_BLOCK_SIZE; |
760 | 769 | ||
761 | dma_buf = aligned_buffer; | 770 | if(aligned) |
762 | if(transfer > UNALIGNED_NUM_SECTORS) | 771 | { |
763 | transfer = UNALIGNED_NUM_SECTORS; | 772 | dma_buf = AS3525_PHYSICAL_ADDR(buf); |
773 | } | ||
774 | else | ||
775 | { | ||
776 | dma_buf = aligned_buffer; | ||
777 | if(transfer > UNALIGNED_NUM_SECTORS) | ||
778 | transfer = UNALIGNED_NUM_SECTORS; | ||
764 | 779 | ||
765 | if(write) | 780 | if(write) |
766 | memcpy(uncached_buffer, buf, transfer * SD_BLOCK_SIZE); | 781 | memcpy(uncached_buffer, buf, transfer * SD_BLOCK_SIZE); |
782 | } | ||
767 | 783 | ||
768 | ret = sd_wait_for_tran_state(drive); | 784 | ret = sd_wait_for_tran_state(drive); |
769 | if (ret < 0) | 785 | if (ret < 0) |
@@ -822,7 +838,7 @@ static int sd_transfer_sectors(IF_MD2(int drive,) unsigned long start, | |||
822 | 838 | ||
823 | if(!transfer_error[drive]) | 839 | if(!transfer_error[drive]) |
824 | { | 840 | { |
825 | if(!write) | 841 | if(!write && !aligned) |
826 | memcpy(buf, uncached_buffer, transfer * SD_BLOCK_SIZE); | 842 | memcpy(buf, uncached_buffer, transfer * SD_BLOCK_SIZE); |
827 | buf += transfer * SD_BLOCK_SIZE; | 843 | buf += transfer * SD_BLOCK_SIZE; |
828 | start += transfer; | 844 | start += transfer; |
diff --git a/firmware/target/arm/as3525/sd-as3525v2.c b/firmware/target/arm/as3525/sd-as3525v2.c index 386b76e758..238cd7a5eb 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 = AS3525_PHYSICAL_ADDR(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..b3b9001a45 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)) |
@@ -39,6 +41,10 @@ | |||
39 | #endif | 41 | #endif |
40 | 42 | ||
41 | #define AS3525_UNCACHED_ADDR(a) ((typeof(a)) ((uintptr_t)(a) + 0x10000000)) | 43 | #define AS3525_UNCACHED_ADDR(a) ((typeof(a)) ((uintptr_t)(a) + 0x10000000)) |
44 | #define AS3525_PHYSICAL_ADDR(a) \ | ||
45 | ((typeof(a)) ((((uintptr_t)(a)) & (MEM*0x100000)) \ | ||
46 | ? (((uintptr_t)(a)) - IRAM_ORIG) \ | ||
47 | : ((uintptr_t)(a)))) | ||
42 | 48 | ||
43 | #ifdef SANSA_C200V2 | 49 | #ifdef SANSA_C200V2 |
44 | /* 0: Backlight on A5, 1: Backlight on A7 */ | 50 | /* 0: Backlight on A5, 1: Backlight on A7 */ |