diff options
author | William Wilgus <me.theuser@yahoo.com> | 2018-07-29 04:46:04 +0200 |
---|---|---|
committer | William Wilgus <me.theuser@yahoo.com> | 2019-12-31 05:57:38 +0100 |
commit | 9f336217c28dd16daeafc05e5019db0e0dd5c350 (patch) | |
tree | 06537880372f40659a7998ca291a9aecf433d340 /firmware/target/arm/as3525/sd-as3525.c | |
parent | f45db552f39579b31d428350f8853d52187f5733 (diff) | |
download | rockbox-9f336217c28dd16daeafc05e5019db0e0dd5c350.tar.gz rockbox-9f336217c28dd16daeafc05e5019db0e0dd5c350.zip |
Sansa AS3525V1 Sd Interface implement powersave mode
This patch cleans up the sd driver for the V1 sansas
powersave implemented for the sd interface
Change-Id: I3d864f7aa304cf792cc65fa4ff06c1e52fbed329
Diffstat (limited to 'firmware/target/arm/as3525/sd-as3525.c')
-rw-r--r-- | firmware/target/arm/as3525/sd-as3525.c | 95 |
1 files changed, 65 insertions, 30 deletions
diff --git a/firmware/target/arm/as3525/sd-as3525.c b/firmware/target/arm/as3525/sd-as3525.c index 494a76a782..86286fa985 100644 --- a/firmware/target/arm/as3525/sd-as3525.c +++ b/firmware/target/arm/as3525/sd-as3525.c | |||
@@ -89,6 +89,8 @@ | |||
89 | | MCI_CMD_CRC_FAIL) | 89 | | MCI_CMD_CRC_FAIL) |
90 | 90 | ||
91 | #define MCI_FIFO(i) ((unsigned long *) (pl180_base[i]+0x80)) | 91 | #define MCI_FIFO(i) ((unsigned long *) (pl180_base[i]+0x80)) |
92 | |||
93 | #define IDE_INTERFACE_CLK (1<<6) /* non AHB interface */ | ||
92 | /* volumes */ | 94 | /* volumes */ |
93 | #define INTERNAL_AS3525 0 /* embedded SD card */ | 95 | #define INTERNAL_AS3525 0 /* embedded SD card */ |
94 | #define SD_SLOT_AS3525 1 /* SD slot if present */ | 96 | #define SD_SLOT_AS3525 1 /* SD slot if present */ |
@@ -109,7 +111,8 @@ static void init_pl180_controller(const int drive); | |||
109 | 111 | ||
110 | static tCardInfo card_info[NUM_DRIVES]; | 112 | static tCardInfo card_info[NUM_DRIVES]; |
111 | 113 | ||
112 | /* maximum timeouts recommanded in the SD Specification v2.00 */ | 114 | /* maximum timeouts recommended in the SD Specification v2.00 */ |
115 | /* MCI_DATA_TIMER register data timeout in card bus clock periods */ | ||
113 | #define SD_MAX_READ_TIMEOUT ((AS3525_PCLK_FREQ) / 1000 * 100) /* 100 ms */ | 116 | #define SD_MAX_READ_TIMEOUT ((AS3525_PCLK_FREQ) / 1000 * 100) /* 100 ms */ |
114 | #define SD_MAX_WRITE_TIMEOUT ((AS3525_PCLK_FREQ) / 1000 * 250) /* 250 ms */ | 117 | #define SD_MAX_WRITE_TIMEOUT ((AS3525_PCLK_FREQ) / 1000 * 250) /* 250 ms */ |
115 | 118 | ||
@@ -143,7 +146,17 @@ static unsigned char *uncached_buffer = AS3525_UNCACHED_ADDR(&aligned_buffer[0]) | |||
143 | 146 | ||
144 | static inline void mci_delay(void) { udelay(1000) ; } | 147 | static inline void mci_delay(void) { udelay(1000) ; } |
145 | 148 | ||
146 | static void enable_controller(bool on) | 149 | static inline bool card_detect_target(void) |
150 | { | ||
151 | #if defined(HAVE_MULTIDRIVE) | ||
152 | return !(GPIOA_PIN(2)); | ||
153 | #else | ||
154 | return false; | ||
155 | #endif | ||
156 | } | ||
157 | |||
158 | #if defined(HAVE_MULTIDRIVE) || defined(HAVE_HOTSWAP) | ||
159 | static void enable_controller_mci(bool on) | ||
147 | { | 160 | { |
148 | 161 | ||
149 | #if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE) | 162 | #if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE) |
@@ -197,17 +210,33 @@ static void enable_controller(bool on) | |||
197 | #endif | 210 | #endif |
198 | } | 211 | } |
199 | } | 212 | } |
213 | #endif /* defined(HAVE_MULTIDRIVE) || defined(HAVE_HOTSWAP) */ | ||
200 | 214 | ||
201 | static inline bool card_detect_target(void) | 215 | /* AMS v1 have two different drive interfaces MCI_SD(XPD) and GGU_IDE */ |
216 | static void enable_controller(bool on, const int drive) | ||
202 | { | 217 | { |
203 | #if defined(HAVE_MULTIDRIVE) | 218 | |
204 | return !(GPIOA_PIN(2)); | 219 | if (drive == INTERNAL_AS3525) |
205 | #else | 220 | { |
206 | return false; | 221 | #ifndef BOOTLOADER |
222 | if (on) | ||
223 | { | ||
224 | bitset32(&CGU_PERI, CGU_NAF_CLOCK_ENABLE); | ||
225 | CGU_IDE |= IDE_INTERFACE_CLK; /* interface enable */ | ||
226 | } | ||
227 | else | ||
228 | { | ||
229 | CGU_IDE &= ~(IDE_INTERFACE_CLK); /* interface disable */ | ||
230 | bitclr32(&CGU_PERI, CGU_NAF_CLOCK_ENABLE); | ||
231 | } | ||
232 | #endif | ||
233 | } | ||
234 | #if defined(HAVE_MULTIDRIVE) || defined(HAVE_HOTSWAP) | ||
235 | else | ||
236 | enable_controller_mci(on); | ||
207 | #endif | 237 | #endif |
208 | } | 238 | } |
209 | 239 | ||
210 | |||
211 | #ifdef HAVE_HOTSWAP | 240 | #ifdef HAVE_HOTSWAP |
212 | static int sd1_oneshot_callback(struct timeout *tmo) | 241 | static int sd1_oneshot_callback(struct timeout *tmo) |
213 | { | 242 | { |
@@ -326,6 +355,7 @@ static bool send_cmd(const int drive, const int cmd, const int arg, | |||
326 | return false; | 355 | return false; |
327 | } | 356 | } |
328 | 357 | ||
358 | /* MCI_CLOCK = MCLK / 2x(ClkDiv[bits 7:0]+1) */ | ||
329 | #define MCI_FULLSPEED (MCI_CLOCK_ENABLE | MCI_CLOCK_BYPASS) /* MCLK */ | 359 | #define MCI_FULLSPEED (MCI_CLOCK_ENABLE | MCI_CLOCK_BYPASS) /* MCLK */ |
330 | #define MCI_HALFSPEED (MCI_CLOCK_ENABLE) /* MCLK/2 */ | 360 | #define MCI_HALFSPEED (MCI_CLOCK_ENABLE) /* MCLK/2 */ |
331 | #define MCI_QUARTERSPEED (MCI_CLOCK_ENABLE | 1) /* MCLK/4 */ | 361 | #define MCI_QUARTERSPEED (MCI_CLOCK_ENABLE | 1) /* MCLK/4 */ |
@@ -345,7 +375,7 @@ static int sd_init_card(const int drive) | |||
345 | /* 100 - 400kHz clock required for Identification Mode */ | 375 | /* 100 - 400kHz clock required for Identification Mode */ |
346 | /* Start of Card Identification Mode ************************************/ | 376 | /* Start of Card Identification Mode ************************************/ |
347 | 377 | ||
348 | /* CMD0 Go Idle */ | 378 | /* CMD0 Go Idle -- all card functions switch back to default */ |
349 | if(!send_cmd(drive, SD_GO_IDLE_STATE, 0, MCI_NO_RESP, NULL)) | 379 | if(!send_cmd(drive, SD_GO_IDLE_STATE, 0, MCI_NO_RESP, NULL)) |
350 | return -1; | 380 | return -1; |
351 | mci_delay(); | 381 | mci_delay(); |
@@ -393,10 +423,10 @@ static int sd_init_card(const int drive) | |||
393 | 423 | ||
394 | if(sd_wait_for_tran_state(drive)) | 424 | if(sd_wait_for_tran_state(drive)) |
395 | return -6; | 425 | return -6; |
396 | /* CMD6 */ | 426 | /* CMD6 0xf indicates no influence, [3:0],0x1 - HS Access*/ |
397 | if(!send_cmd(drive, SD_SWITCH_FUNC, 0x80fffff1, MCI_NO_RESP, NULL)) | 427 | if(!send_cmd(drive, SD_SWITCH_FUNC, 0x80fffff1, MCI_NO_RESP, NULL)) |
398 | return -7; | 428 | return -7; |
399 | sleep(HZ/10); | 429 | sleep(HZ/10);/* need to wait at least 8 clock periods */ |
400 | 430 | ||
401 | /* go back to STBY state so we can read csd */ | 431 | /* go back to STBY state so we can read csd */ |
402 | /* CMD7 w/rca=0: Deselect card to put it in STBY state */ | 432 | /* CMD7 w/rca=0: Deselect card to put it in STBY state */ |
@@ -423,7 +453,8 @@ static int sd_init_card(const int drive) | |||
423 | #if defined(HAVE_MULTIDRIVE) | 453 | #if defined(HAVE_MULTIDRIVE) |
424 | else | 454 | else |
425 | /* MCICLK = PCLK/2 = 31MHz(HS) or PCLK/4 = 15.5 Mhz (STD)*/ | 455 | /* MCICLK = PCLK/2 = 31MHz(HS) or PCLK/4 = 15.5 Mhz (STD)*/ |
426 | MCI_CLOCK(drive) = (hs_card ? MCI_HALFSPEED : MCI_QUARTERSPEED); | 456 | MCI_CLOCK(drive) = (hs_card ? MCI_HALFSPEED : MCI_QUARTERSPEED) | |
457 | MCI_CLOCK_POWERSAVE; /* SD supports powersave */ | ||
427 | #endif | 458 | #endif |
428 | 459 | ||
429 | /* CMD7 w/rca: Select card to put it in TRAN state */ | 460 | /* CMD7 w/rca: Select card to put it in TRAN state */ |
@@ -517,7 +548,7 @@ static void init_pl180_controller(const int drive) | |||
517 | int sd_init(void) | 548 | int sd_init(void) |
518 | { | 549 | { |
519 | int ret; | 550 | int ret; |
520 | CGU_IDE = (1<<6) /* enable non AHB interface*/ | 551 | CGU_IDE = IDE_INTERFACE_CLK /* enable interface */ |
521 | | (AS3525_IDE_DIV << 2) | 552 | | (AS3525_IDE_DIV << 2) |
522 | | AS3525_CLK_PLLA; /* clock source = PLLA */ | 553 | | AS3525_CLK_PLLA; /* clock source = PLLA */ |
523 | 554 | ||
@@ -540,7 +571,9 @@ int sd_init(void) | |||
540 | /* init mutex */ | 571 | /* init mutex */ |
541 | mutex_init(&sd_mtx); | 572 | mutex_init(&sd_mtx); |
542 | 573 | ||
543 | enable_controller(false); | 574 | for (int i = 0; i < NUM_DRIVES ; i++) |
575 | enable_controller(false, i); | ||
576 | |||
544 | return 0; | 577 | return 0; |
545 | } | 578 | } |
546 | 579 | ||
@@ -656,7 +689,7 @@ static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start, | |||
656 | unsigned long response; | 689 | unsigned long response; |
657 | bool aligned = !((uintptr_t)buf & (CACHEALIGN_SIZE - 1)); | 690 | bool aligned = !((uintptr_t)buf & (CACHEALIGN_SIZE - 1)); |
658 | 691 | ||
659 | enable_controller(true); | 692 | enable_controller(true, drive); |
660 | led(true); | 693 | led(true); |
661 | 694 | ||
662 | if (card_info[drive].initialized <= 0) | 695 | if (card_info[drive].initialized <= 0) |
@@ -692,17 +725,15 @@ static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start, | |||
692 | else | 725 | else |
693 | discard_dcache_range(buf, count * SECTOR_SIZE); | 726 | discard_dcache_range(buf, count * SECTOR_SIZE); |
694 | } | 727 | } |
695 | 728 | const int cmd = write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK; | |
696 | while(count) | 729 | while(count > 0) |
697 | { | 730 | { |
698 | /* 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 |
699 | * register, so we have to transfer maximum 127 sectors at a time. */ | 732 | * register, so we have to transfer maximum 127 sectors at a time. */ |
700 | unsigned int transfer = (count >= 128) ? 127 : count; /* sectors */ | 733 | unsigned int transfer = (count >= 128) ? 127 : count; /* sectors */ |
701 | void *dma_buf; | 734 | void *dma_buf; |
702 | const int cmd = | 735 | |
703 | write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK; | ||
704 | unsigned long bank_start = start; | 736 | unsigned long bank_start = start; |
705 | unsigned long status; | ||
706 | 737 | ||
707 | /* Only switch banks for internal storage */ | 738 | /* Only switch banks for internal storage */ |
708 | if(drive == INTERNAL_AS3525) | 739 | if(drive == INTERNAL_AS3525) |
@@ -770,10 +801,7 @@ static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start, | |||
770 | /*Small delay for writes prevents data crc failures at lower freqs*/ | 801 | /*Small delay for writes prevents data crc failures at lower freqs*/ |
771 | #ifdef HAVE_MULTIDRIVE | 802 | #ifdef HAVE_MULTIDRIVE |
772 | if((drive == SD_SLOT_AS3525) && !hs_card) | 803 | if((drive == SD_SLOT_AS3525) && !hs_card) |
773 | { | 804 | udelay(4); |
774 | int write_delay = 125; | ||
775 | while(write_delay--); | ||
776 | } | ||
777 | #endif | 805 | #endif |
778 | } | 806 | } |
779 | else | 807 | else |
@@ -804,7 +832,7 @@ static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start, | |||
804 | 832 | ||
805 | last_disk_activity = current_tick; | 833 | last_disk_activity = current_tick; |
806 | 834 | ||
807 | if(!send_cmd(drive, SD_STOP_TRANSMISSION, 0, MCI_RESP, &status)) | 835 | if(!send_cmd(drive, SD_STOP_TRANSMISSION, 0, MCI_RESP, &response)) |
808 | { | 836 | { |
809 | ret = -4*20; | 837 | ret = -4*20; |
810 | goto sd_transfer_error; | 838 | goto sd_transfer_error; |
@@ -831,7 +859,7 @@ sd_transfer_error: | |||
831 | sd_transfer_error_nodma: | 859 | sd_transfer_error_nodma: |
832 | 860 | ||
833 | led(false); | 861 | led(false); |
834 | enable_controller(false); | 862 | enable_controller(false, drive); |
835 | 863 | ||
836 | if (ret) /* error */ | 864 | if (ret) /* error */ |
837 | card_info[drive].initialized = 0; | 865 | card_info[drive].initialized = 0; |
@@ -922,12 +950,18 @@ void ams_sd_get_debug_info(struct ams_sd_debug_info *info) | |||
922 | #define MCI_SD *((volatile unsigned long *)(SD_MCI_BASE + 0x04)) | 950 | #define MCI_SD *((volatile unsigned long *)(SD_MCI_BASE + 0x04)) |
923 | 951 | ||
924 | mutex_lock(&sd_mtx); | 952 | mutex_lock(&sd_mtx); |
925 | enable_controller(true); /* must be on to read regs */ | 953 | |
954 | for (int i = 0; i < NUM_DRIVES ; i++) | ||
955 | enable_controller(true, i); /* must be on to read regs */ | ||
956 | |||
926 | info->mci_nand = MCI_NAND; | 957 | info->mci_nand = MCI_NAND; |
927 | #ifdef HAVE_MULTIDRIVE | 958 | #ifdef HAVE_MULTIDRIVE |
928 | info->mci_sd = MCI_SD; | 959 | info->mci_sd = MCI_SD; |
929 | #endif | 960 | #endif |
930 | enable_controller(false); | 961 | |
962 | for (int i = 0; i < NUM_DRIVES ; i++) | ||
963 | enable_controller(false, i); | ||
964 | |||
931 | mutex_unlock(&sd_mtx); | 965 | mutex_unlock(&sd_mtx); |
932 | } | 966 | } |
933 | 967 | ||
@@ -948,10 +982,10 @@ int sd_event(long id, intptr_t data) | |||
948 | 982 | ||
949 | if (id == SYS_HOTSWAP_INSERTED) | 983 | if (id == SYS_HOTSWAP_INSERTED) |
950 | { | 984 | { |
951 | enable_controller(true); | 985 | enable_controller(true, data); |
952 | init_pl180_controller(data); | 986 | init_pl180_controller(data); |
953 | rc = sd_init_card(data); | 987 | rc = sd_init_card(data); |
954 | enable_controller(false); | 988 | enable_controller(false, data); |
955 | } | 989 | } |
956 | 990 | ||
957 | mutex_unlock(&sd_mtx); | 991 | mutex_unlock(&sd_mtx); |
@@ -968,3 +1002,4 @@ int sd_event(long id, intptr_t data) | |||
968 | 1002 | ||
969 | return rc; | 1003 | return rc; |
970 | } | 1004 | } |
1005 | |||