summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2008-09-17 18:53:11 +0000
committerJens Arnold <amiconn@rockbox.org>2008-09-17 18:53:11 +0000
commit3655a32a3e8e49bc0e70f28eaa6d60f17fbdb412 (patch)
treedc38c94af8625875248d320965524b122ca5c027
parentd29faf07a3b092fd1b2076e1a219264c5f4aa5d7 (diff)
downloadrockbox-3655a32a3e8e49bc0e70f28eaa6d60f17fbdb412.zip
rockbox-3655a32a3e8e49bc0e70f28eaa6d60f17fbdb412.tar.gz
rockbox-3655a32a3e8e49bc0e70f28eaa6d60f17fbdb412.tar.bz2
rockbox-3655a32a3e8e49bc0e70f28eaa6d60f17fbdb412.tar.xz
Further MMC driver touchup: * Save a tiny amount of power by not enabling the internal flash clock when accessing the MMC. * R2W factors > 32 are valid in newer MMC specs, so don't limit to 32 anymore. * Revise the port setup, and only do the basic setup once.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18541 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/drivers/ata_mmc.c78
1 files changed, 36 insertions, 42 deletions
diff --git a/firmware/drivers/ata_mmc.c b/firmware/drivers/ata_mmc.c
index d7b7346..5acc75c 100644
--- a/firmware/drivers/ata_mmc.c
+++ b/firmware/drivers/ata_mmc.c
@@ -172,6 +172,8 @@ static int select_card(int card_no)
led(true);
last_disk_activity = current_tick;
+ mmc_enable_int_flash_clock(card_no == 0);
+
if (!card_info[card_no].initialized)
{
setup_sci1(7); /* Initial rate: 375 kbps (need <= 400 per mmc specs) */
@@ -402,11 +404,11 @@ static int initialize_card(int card_no)
mmc_status = MMC_TOUCHED;
/* switch to SPI mode */
send_cmd(CMD_GO_IDLE_STATE, 0, response);
- if (response[0] != 0x01)
+ if (response[0] != 0x01)
return -1; /* error response */
/* initialize card */
- for (i = 0; i < 100; i++) /* timeout 1 sec */
+ for (i = 0; i < HZ; i++) /* timeout 1 sec */
{
sleep(1);
if (send_cmd(CMD_SEND_OP_COND, 0, response) == 0)
@@ -461,13 +463,10 @@ static int initialize_card(int card_no)
/* r2w_factor, write timeout */
card->r2w_factor = 1 << card_extract_bits(card->csd, 99, 3);
- if (card->r2w_factor > 32) /* dirty MMC spec violation */
- {
- card->read_timeout *= 4; /* add safety factor */
- card->write_timeout = card->read_timeout * 8;
- }
- else
- card->write_timeout = card->read_timeout * card->r2w_factor;
+ card->write_timeout = card->read_timeout * card->r2w_factor;
+
+ if (card->r2w_factor > 32) /* Such cards often need extra read delay */
+ card->read_timeout *= 4;
/* switch to full speed */
setup_sci1(card->bitrate_register);
@@ -943,18 +942,15 @@ int ata_soft_reset(void)
void ata_enable(bool on)
{
- PBCR1 &= ~0x0CF0; /* PB13, PB11 and PB10 become GPIOs, if not modified below */
- PACR2 &= ~0x4000; /* use PA7 (bridge reset) as GPIO */
+ PBCR1 &= ~0x0CF0; /* PB13, PB11 and PB10 become GPIO,
+ * if not modified below */
if (on)
- {
- PBCR1 |= 0x08A0; /* as SCK1, TxD1, RxD1 */
- IPRE &= 0x0FFF; /* disable SCI1 interrupts for the CPU */
- mmc_enable_int_flash_clock(true); /* always enabled in SPI mode */
- }
- and_b(~0x80, &PADRL); /* assert reset */
- sleep(HZ/20);
- or_b(0x80, &PADRL); /* de-assert reset */
- sleep(HZ/20);
+ PBCR1 |= 0x08A0; /* as SCK1, TxD1, RxD1 */
+
+ and_b(~0x80, &PADRL); /* assert flash reset */
+ sleep(HZ/100);
+ or_b(0x80, &PADRL); /* de-assert flash reset */
+ sleep(HZ/100);
card_info[0].initialized = false;
card_info[1].initialized = false;
}
@@ -971,36 +967,33 @@ int ata_init(void)
mutex_lock(&mmc_mutex);
led(false);
- /* Port setup */
- PACR1 &= ~0x0F00; /* GPIO function for PA12, /IRQ1 for PA13 */
- PACR1 |= 0x0400;
- PADR |= 0x0680; /* set all the selects + reset high (=inactive) */
- PAIOR |= 0x1680; /* make outputs for them and the PA12 clock gate */
-
- PBDR |= 0x2C00; /* SCK1, TxD1 and RxD1 high when GPIO CHECKME: mask */
- PBIOR |= 0x2000; /* SCK1 output */
- PBIOR &= ~0x0C00; /* TxD1, RxD1 input */
-
last_mmc_status = mmc_detect();
#ifndef HAVE_MULTIVOLUME
- if (last_mmc_status)
- { /* MMC inserted */
- current_card = 1;
- }
- else
- { /* no MMC, use internal memory */
- current_card = 0;
- }
+ /* Use MMC if inserted, internal flash otherwise */
+ current_card = last_mmc_status ? 1 : 0;
#endif
- new_mmc_circuit = ((HW_MASK & MMC_CLOCK_POLARITY) != 0);
- ata_enable(true);
-
- if ( !initialized )
+ if (!initialized)
{
if (!last_mmc_status)
mmc_status = MMC_UNTOUCHED;
+ /* Port setup */
+ PACR1 &= ~0x0F3C; /* GPIO function for PA13 (flash busy), PA12
+ * (clk gate), PA10 (flash CS), PA9 (MMC CS) */
+ PACR2 &= ~0x4000; /* GPIO for PA7 (flash reset) */
+ PADR |= 0x0680; /* set all the selects + reset high (=inactive) */
+ PAIOR |= 0x1680; /* make outputs for them and the PA12 clock gate */
+
+ PBCR1 &= ~0x0CF0; /* GPIO function for PB13, PB11 and PB10 */
+ PBDR |= 0x2C00; /* SCK1, TxD1 and RxD1 high in GPIO */
+ PBIOR |= 0x2000; /* SCK1 output */
+ PBIOR &= ~0x0C00; /* TxD1, RxD1 input */
+
+ IPRE &= 0x0FFF; /* disable SCI1 interrupts for the CPU */
+
+ new_mmc_circuit = ((HW_MASK & MMC_CLOCK_POLARITY) != 0);
+
create_thread(mmc_thread, mmc_stack,
sizeof(mmc_stack), 0, mmc_thread_name
IF_PRIO(, PRIORITY_SYSTEM)
@@ -1008,6 +1001,7 @@ int ata_init(void)
tick_add_task(mmc_tick);
initialized = true;
}
+ ata_enable(true);
mutex_unlock(&mmc_mutex);
return rc;