summaryrefslogtreecommitdiffstats
path: root/firmware/target/arm/as3525/sd-as3525.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/as3525/sd-as3525.c')
-rw-r--r--firmware/target/arm/as3525/sd-as3525.c138
1 files changed, 35 insertions, 103 deletions
diff --git a/firmware/target/arm/as3525/sd-as3525.c b/firmware/target/arm/as3525/sd-as3525.c
index 9e4a86acbe..494a76a782 100644
--- a/firmware/target/arm/as3525/sd-as3525.c
+++ b/firmware/target/arm/as3525/sd-as3525.c
@@ -89,8 +89,6 @@
| MCI_CMD_CRC_FAIL)
#define MCI_FIFO(i) ((unsigned long *) (pl180_base[i]+0x80))
-
-#define IDE_INTERFACE_CLK (1<<6) /* non AHB interface */
/* volumes */
#define INTERNAL_AS3525 0 /* embedded SD card */
#define SD_SLOT_AS3525 1 /* SD slot if present */
@@ -111,8 +109,7 @@ static void init_pl180_controller(const int drive);
static tCardInfo card_info[NUM_DRIVES];
-/* maximum timeouts recommended in the SD Specification v2.00 */
-/* MCI_DATA_TIMER register data timeout in card bus clock periods */
+/* maximum timeouts recommanded in the SD Specification v2.00 */
#define SD_MAX_READ_TIMEOUT ((AS3525_PCLK_FREQ) / 1000 * 100) /* 100 ms */
#define SD_MAX_WRITE_TIMEOUT ((AS3525_PCLK_FREQ) / 1000 * 250) /* 250 ms */
@@ -146,17 +143,7 @@ static unsigned char *uncached_buffer = AS3525_UNCACHED_ADDR(&aligned_buffer[0])
static inline void mci_delay(void) { udelay(1000) ; }
-static inline bool card_detect_target(void)
-{
-#if defined(HAVE_MULTIDRIVE)
- return !(GPIOA_PIN(2));
-#else
- return false;
-#endif
-}
-
-#if defined(HAVE_MULTIDRIVE) || defined(HAVE_HOTSWAP)
-static void enable_controller_mci(bool on)
+static void enable_controller(bool on)
{
#if defined(HAVE_BUTTON_LIGHT) && defined(HAVE_MULTIDRIVE)
@@ -210,33 +197,17 @@ static void enable_controller_mci(bool on)
#endif
}
}
-#endif /* defined(HAVE_MULTIDRIVE) || defined(HAVE_HOTSWAP) */
-/* AMS v1 have two different drive interfaces MCI_SD(XPD) and GGU_IDE */
-static void enable_controller(bool on, const int drive)
+static inline bool card_detect_target(void)
{
-
- if (drive == INTERNAL_AS3525)
- {
-#ifndef BOOTLOADER
- if (on)
- {
- bitset32(&CGU_PERI, CGU_NAF_CLOCK_ENABLE);
- CGU_IDE |= IDE_INTERFACE_CLK; /* interface enable */
- }
- else
- {
- CGU_IDE &= ~(IDE_INTERFACE_CLK); /* interface disable */
- bitclr32(&CGU_PERI, CGU_NAF_CLOCK_ENABLE);
- }
-#endif
- }
-#if defined(HAVE_MULTIDRIVE) || defined(HAVE_HOTSWAP)
- else
- enable_controller_mci(on);
+#if defined(HAVE_MULTIDRIVE)
+ return !(GPIOA_PIN(2));
+#else
+ return false;
#endif
}
+
#ifdef HAVE_HOTSWAP
static int sd1_oneshot_callback(struct timeout *tmo)
{
@@ -355,7 +326,6 @@ static bool send_cmd(const int drive, const int cmd, const int arg,
return false;
}
-/* MCI_CLOCK = MCLK / 2x(ClkDiv[bits 7:0]+1) */
#define MCI_FULLSPEED (MCI_CLOCK_ENABLE | MCI_CLOCK_BYPASS) /* MCLK */
#define MCI_HALFSPEED (MCI_CLOCK_ENABLE) /* MCLK/2 */
#define MCI_QUARTERSPEED (MCI_CLOCK_ENABLE | 1) /* MCLK/4 */
@@ -375,7 +345,7 @@ static int sd_init_card(const int drive)
/* 100 - 400kHz clock required for Identification Mode */
/* Start of Card Identification Mode ************************************/
- /* CMD0 Go Idle -- all card functions switch back to default */
+ /* CMD0 Go Idle */
if(!send_cmd(drive, SD_GO_IDLE_STATE, 0, MCI_NO_RESP, NULL))
return -1;
mci_delay();
@@ -423,10 +393,10 @@ static int sd_init_card(const int drive)
if(sd_wait_for_tran_state(drive))
return -6;
- /* CMD6 0xf indicates no influence, [3:0],0x1 - HS Access*/
+ /* CMD6 */
if(!send_cmd(drive, SD_SWITCH_FUNC, 0x80fffff1, MCI_NO_RESP, NULL))
return -7;
- sleep(HZ/10);/* need to wait at least 8 clock periods */
+ sleep(HZ/10);
/* go back to STBY state so we can read csd */
/* CMD7 w/rca=0: Deselect card to put it in STBY state */
@@ -547,7 +517,7 @@ static void init_pl180_controller(const int drive)
int sd_init(void)
{
int ret;
- CGU_IDE = IDE_INTERFACE_CLK /* enable interface */
+ CGU_IDE = (1<<6) /* enable non AHB interface*/
| (AS3525_IDE_DIV << 2)
| AS3525_CLK_PLLA; /* clock source = PLLA */
@@ -570,9 +540,7 @@ int sd_init(void)
/* init mutex */
mutex_init(&sd_mtx);
- for (int i = 0; i < NUM_DRIVES ; i++)
- enable_controller(false, i);
-
+ enable_controller(false);
return 0;
}
@@ -688,7 +656,7 @@ static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start,
unsigned long response;
bool aligned = !((uintptr_t)buf & (CACHEALIGN_SIZE - 1));
- enable_controller(true, drive);
+ enable_controller(true);
led(true);
if (card_info[drive].initialized <= 0)
@@ -724,21 +692,27 @@ static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start,
else
discard_dcache_range(buf, count * SECTOR_SIZE);
}
- const int cmd = write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK;
- while(count > 0)
+
+ while(count)
{
/* 128 * 512 = 2^16, and doesn't fit in the 16 bits of DATA_LENGTH
* register, so we have to transfer maximum 127 sectors at a time. */
unsigned int transfer = (count >= 128) ? 127 : count; /* sectors */
void *dma_buf;
-
+ const int cmd =
+ write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK;
unsigned long bank_start = start;
+ unsigned long status;
/* Only switch banks for internal storage */
if(drive == INTERNAL_AS3525)
{
- unsigned int bank = bank_start / BLOCKS_PER_BANK;
- bank_start -= bank * BLOCKS_PER_BANK;
+ unsigned int bank = 0;
+ while(bank_start >= BLOCKS_PER_BANK)
+ {
+ bank_start -= BLOCKS_PER_BANK;
+ bank++;
+ }
/* Switch bank if needed */
if(card_info[INTERNAL_AS3525].current_bank != bank)
@@ -796,7 +770,10 @@ static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start,
/*Small delay for writes prevents data crc failures at lower freqs*/
#ifdef HAVE_MULTIDRIVE
if((drive == SD_SLOT_AS3525) && !hs_card)
- udelay(4);
+ {
+ int write_delay = 125;
+ while(write_delay--);
+ }
#endif
}
else
@@ -827,7 +804,7 @@ static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start,
last_disk_activity = current_tick;
- if(!send_cmd(drive, SD_STOP_TRANSMISSION, 0, MCI_RESP, &response))
+ if(!send_cmd(drive, SD_STOP_TRANSMISSION, 0, MCI_RESP, &status))
{
ret = -4*20;
goto sd_transfer_error;
@@ -854,7 +831,7 @@ sd_transfer_error:
sd_transfer_error_nodma:
led(false);
- enable_controller(false, drive);
+ enable_controller(false);
if (ret) /* error */
card_info[drive].initialized = 0;
@@ -945,18 +922,12 @@ void ams_sd_get_debug_info(struct ams_sd_debug_info *info)
#define MCI_SD *((volatile unsigned long *)(SD_MCI_BASE + 0x04))
mutex_lock(&sd_mtx);
-
- for (int i = 0; i < NUM_DRIVES ; i++)
- enable_controller(true, i); /* must be on to read regs */
-
+ enable_controller(true); /* must be on to read regs */
info->mci_nand = MCI_NAND;
#ifdef HAVE_MULTIDRIVE
info->mci_sd = MCI_SD;
#endif
-
- for (int i = 0; i < NUM_DRIVES ; i++)
- enable_controller(false, i);
-
+ enable_controller(false);
mutex_unlock(&sd_mtx);
}
@@ -977,10 +948,10 @@ int sd_event(long id, intptr_t data)
if (id == SYS_HOTSWAP_INSERTED)
{
- enable_controller(true, data);
+ enable_controller(true);
init_pl180_controller(data);
rc = sd_init_card(data);
- enable_controller(false, data);
+ enable_controller(false);
}
mutex_unlock(&sd_mtx);
@@ -997,42 +968,3 @@ int sd_event(long id, intptr_t data)
return rc;
}
-
-#if defined(CONFIG_POWER_SAVING) && (CONFIG_POWER_SAVING & POWERSV_DISK)
-/* declared in system-as3525.c */
-void ams_sd_set_low_speed(bool slow)
-{
- /* block access while speed is changed */
- mutex_lock(&sd_mtx);
- enable_controller(true, INTERNAL_AS3525);
-
- /* After a data write, data cannot be written to MCI_CLOCK
- for 3 MCLK periods + 2 PCLK periods. ~10us worst case
- */
- udelay(100);
- if (slow)
- {
- /* only affects internal drive clock speed*/
- CGU_IDE = (CGU_IDE & ~(0xF << 2)) | (AS3525_IDE_DIV_MAX << 2);
- /* power save is enabled for the sd card(s) */
- for (int i = 0; i < NUM_DRIVES ; i++)
- {
- if (i != INTERNAL_AS3525 && (MCI_CLOCK(i) & MCI_CLOCK_POWERSAVE) == 0)
- MCI_CLOCK(i) |= MCI_CLOCK_POWERSAVE;
- }
- }
- else
- {
- /* Full Speed */
- CGU_IDE = (CGU_IDE & ~(0xF << 2)) | (AS3525_IDE_DIV << 2);
- for (int i = 0; i < NUM_DRIVES ; i++)
- {
- if (i != INTERNAL_AS3525 && (MCI_CLOCK(i) & MCI_CLOCK_POWERSAVE) != 0)
- MCI_CLOCK(i) = (MCI_CLOCK(i) & ~MCI_CLOCK_POWERSAVE);
- }
- }
- enable_controller(false, INTERNAL_AS3525);
- mutex_unlock(&sd_mtx);
-}
-#endif
-