From 3655a32a3e8e49bc0e70f28eaa6d60f17fbdb412 Mon Sep 17 00:00:00 2001 From: Jens Arnold Date: Wed, 17 Sep 2008 18:53:11 +0000 Subject: 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 --- firmware/drivers/ata_mmc.c | 78 +++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 42 deletions(-) (limited to 'firmware/drivers/ata_mmc.c') diff --git a/firmware/drivers/ata_mmc.c b/firmware/drivers/ata_mmc.c index d7b734603a..5acc75c680 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; -- cgit v1.2.3