diff options
author | Jens Arnold <amiconn@rockbox.org> | 2008-09-17 18:53:11 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2008-09-17 18:53:11 +0000 |
commit | 3655a32a3e8e49bc0e70f28eaa6d60f17fbdb412 (patch) | |
tree | dc38c94af8625875248d320965524b122ca5c027 /firmware/drivers/ata_mmc.c | |
parent | d29faf07a3b092fd1b2076e1a219264c5f4aa5d7 (diff) | |
download | rockbox-3655a32a3e8e49bc0e70f28eaa6d60f17fbdb412.tar.gz rockbox-3655a32a3e8e49bc0e70f28eaa6d60f17fbdb412.zip |
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
Diffstat (limited to 'firmware/drivers/ata_mmc.c')
-rw-r--r-- | firmware/drivers/ata_mmc.c | 78 |
1 files changed, 36 insertions, 42 deletions
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) | |||
172 | led(true); | 172 | led(true); |
173 | last_disk_activity = current_tick; | 173 | last_disk_activity = current_tick; |
174 | 174 | ||
175 | mmc_enable_int_flash_clock(card_no == 0); | ||
176 | |||
175 | if (!card_info[card_no].initialized) | 177 | if (!card_info[card_no].initialized) |
176 | { | 178 | { |
177 | setup_sci1(7); /* Initial rate: 375 kbps (need <= 400 per mmc specs) */ | 179 | setup_sci1(7); /* Initial rate: 375 kbps (need <= 400 per mmc specs) */ |
@@ -402,11 +404,11 @@ static int initialize_card(int card_no) | |||
402 | mmc_status = MMC_TOUCHED; | 404 | mmc_status = MMC_TOUCHED; |
403 | /* switch to SPI mode */ | 405 | /* switch to SPI mode */ |
404 | send_cmd(CMD_GO_IDLE_STATE, 0, response); | 406 | send_cmd(CMD_GO_IDLE_STATE, 0, response); |
405 | if (response[0] != 0x01) | 407 | if (response[0] != 0x01) |
406 | return -1; /* error response */ | 408 | return -1; /* error response */ |
407 | 409 | ||
408 | /* initialize card */ | 410 | /* initialize card */ |
409 | for (i = 0; i < 100; i++) /* timeout 1 sec */ | 411 | for (i = 0; i < HZ; i++) /* timeout 1 sec */ |
410 | { | 412 | { |
411 | sleep(1); | 413 | sleep(1); |
412 | if (send_cmd(CMD_SEND_OP_COND, 0, response) == 0) | 414 | if (send_cmd(CMD_SEND_OP_COND, 0, response) == 0) |
@@ -461,13 +463,10 @@ static int initialize_card(int card_no) | |||
461 | 463 | ||
462 | /* r2w_factor, write timeout */ | 464 | /* r2w_factor, write timeout */ |
463 | card->r2w_factor = 1 << card_extract_bits(card->csd, 99, 3); | 465 | card->r2w_factor = 1 << card_extract_bits(card->csd, 99, 3); |
464 | if (card->r2w_factor > 32) /* dirty MMC spec violation */ | 466 | card->write_timeout = card->read_timeout * card->r2w_factor; |
465 | { | 467 | |
466 | card->read_timeout *= 4; /* add safety factor */ | 468 | if (card->r2w_factor > 32) /* Such cards often need extra read delay */ |
467 | card->write_timeout = card->read_timeout * 8; | 469 | card->read_timeout *= 4; |
468 | } | ||
469 | else | ||
470 | card->write_timeout = card->read_timeout * card->r2w_factor; | ||
471 | 470 | ||
472 | /* switch to full speed */ | 471 | /* switch to full speed */ |
473 | setup_sci1(card->bitrate_register); | 472 | setup_sci1(card->bitrate_register); |
@@ -943,18 +942,15 @@ int ata_soft_reset(void) | |||
943 | 942 | ||
944 | void ata_enable(bool on) | 943 | void ata_enable(bool on) |
945 | { | 944 | { |
946 | PBCR1 &= ~0x0CF0; /* PB13, PB11 and PB10 become GPIOs, if not modified below */ | 945 | PBCR1 &= ~0x0CF0; /* PB13, PB11 and PB10 become GPIO, |
947 | PACR2 &= ~0x4000; /* use PA7 (bridge reset) as GPIO */ | 946 | * if not modified below */ |
948 | if (on) | 947 | if (on) |
949 | { | 948 | PBCR1 |= 0x08A0; /* as SCK1, TxD1, RxD1 */ |
950 | PBCR1 |= 0x08A0; /* as SCK1, TxD1, RxD1 */ | 949 | |
951 | IPRE &= 0x0FFF; /* disable SCI1 interrupts for the CPU */ | 950 | and_b(~0x80, &PADRL); /* assert flash reset */ |
952 | mmc_enable_int_flash_clock(true); /* always enabled in SPI mode */ | 951 | sleep(HZ/100); |
953 | } | 952 | or_b(0x80, &PADRL); /* de-assert flash reset */ |
954 | and_b(~0x80, &PADRL); /* assert reset */ | 953 | sleep(HZ/100); |
955 | sleep(HZ/20); | ||
956 | or_b(0x80, &PADRL); /* de-assert reset */ | ||
957 | sleep(HZ/20); | ||
958 | card_info[0].initialized = false; | 954 | card_info[0].initialized = false; |
959 | card_info[1].initialized = false; | 955 | card_info[1].initialized = false; |
960 | } | 956 | } |
@@ -971,36 +967,33 @@ int ata_init(void) | |||
971 | mutex_lock(&mmc_mutex); | 967 | mutex_lock(&mmc_mutex); |
972 | led(false); | 968 | led(false); |
973 | 969 | ||
974 | /* Port setup */ | ||
975 | PACR1 &= ~0x0F00; /* GPIO function for PA12, /IRQ1 for PA13 */ | ||
976 | PACR1 |= 0x0400; | ||
977 | PADR |= 0x0680; /* set all the selects + reset high (=inactive) */ | ||
978 | PAIOR |= 0x1680; /* make outputs for them and the PA12 clock gate */ | ||
979 | |||
980 | PBDR |= 0x2C00; /* SCK1, TxD1 and RxD1 high when GPIO CHECKME: mask */ | ||
981 | PBIOR |= 0x2000; /* SCK1 output */ | ||
982 | PBIOR &= ~0x0C00; /* TxD1, RxD1 input */ | ||
983 | |||
984 | last_mmc_status = mmc_detect(); | 970 | last_mmc_status = mmc_detect(); |
985 | #ifndef HAVE_MULTIVOLUME | 971 | #ifndef HAVE_MULTIVOLUME |
986 | if (last_mmc_status) | 972 | /* Use MMC if inserted, internal flash otherwise */ |
987 | { /* MMC inserted */ | 973 | current_card = last_mmc_status ? 1 : 0; |
988 | current_card = 1; | ||
989 | } | ||
990 | else | ||
991 | { /* no MMC, use internal memory */ | ||
992 | current_card = 0; | ||
993 | } | ||
994 | #endif | 974 | #endif |
995 | 975 | ||
996 | new_mmc_circuit = ((HW_MASK & MMC_CLOCK_POLARITY) != 0); | 976 | if (!initialized) |
997 | ata_enable(true); | ||
998 | |||
999 | if ( !initialized ) | ||
1000 | { | 977 | { |
1001 | if (!last_mmc_status) | 978 | if (!last_mmc_status) |
1002 | mmc_status = MMC_UNTOUCHED; | 979 | mmc_status = MMC_UNTOUCHED; |
1003 | 980 | ||
981 | /* Port setup */ | ||
982 | PACR1 &= ~0x0F3C; /* GPIO function for PA13 (flash busy), PA12 | ||
983 | * (clk gate), PA10 (flash CS), PA9 (MMC CS) */ | ||
984 | PACR2 &= ~0x4000; /* GPIO for PA7 (flash reset) */ | ||
985 | PADR |= 0x0680; /* set all the selects + reset high (=inactive) */ | ||
986 | PAIOR |= 0x1680; /* make outputs for them and the PA12 clock gate */ | ||
987 | |||
988 | PBCR1 &= ~0x0CF0; /* GPIO function for PB13, PB11 and PB10 */ | ||
989 | PBDR |= 0x2C00; /* SCK1, TxD1 and RxD1 high in GPIO */ | ||
990 | PBIOR |= 0x2000; /* SCK1 output */ | ||
991 | PBIOR &= ~0x0C00; /* TxD1, RxD1 input */ | ||
992 | |||
993 | IPRE &= 0x0FFF; /* disable SCI1 interrupts for the CPU */ | ||
994 | |||
995 | new_mmc_circuit = ((HW_MASK & MMC_CLOCK_POLARITY) != 0); | ||
996 | |||
1004 | create_thread(mmc_thread, mmc_stack, | 997 | create_thread(mmc_thread, mmc_stack, |
1005 | sizeof(mmc_stack), 0, mmc_thread_name | 998 | sizeof(mmc_stack), 0, mmc_thread_name |
1006 | IF_PRIO(, PRIORITY_SYSTEM) | 999 | IF_PRIO(, PRIORITY_SYSTEM) |
@@ -1008,6 +1001,7 @@ int ata_init(void) | |||
1008 | tick_add_task(mmc_tick); | 1001 | tick_add_task(mmc_tick); |
1009 | initialized = true; | 1002 | initialized = true; |
1010 | } | 1003 | } |
1004 | ata_enable(true); | ||
1011 | 1005 | ||
1012 | mutex_unlock(&mmc_mutex); | 1006 | mutex_unlock(&mmc_mutex); |
1013 | return rc; | 1007 | return rc; |