| Index: emcore/trunk/target/ipodclassic/storage_ata.c |
| — | — | @@ -68,9 +68,10 @@ |
| 69 | 69 | uint32_t ata_last_offset; |
| 70 | 70 | uint64_t ata_last_phys; |
| 71 | 71 | |
| | 72 | +static uint16_t ata_read_cbr(uint32_t volatile* reg); |
| 72 | 73 | int ata_bbt_read_sectors(uint32_t sector, uint32_t count, void* buffer) |
| 73 | 74 | { |
| 74 | | - if (ata_last_phys != sector - 1 && ata_last_phys > sector - 64) ata_soft_reset(); |
| | 75 | + if (ata_last_phys != sector - 1 && ata_last_phys > sector - 64) ata_reset(); |
| 75 | 76 | int rc = ata_rw_sectors_internal(sector, count, buffer, false); |
| 76 | 77 | if (rc) rc = ata_rw_sectors_internal(sector, count, buffer, false); |
| 77 | 78 | ata_last_phys = sector + count - 1; |
| — | — | @@ -89,7 +90,7 @@ |
| 90 | 91 | #ifdef ATA_HAVE_BBT |
| 91 | 92 | .bbt_translate = ata_bbt_translate, |
| 92 | 93 | .bbt_reload = ata_bbt_reload, |
| 93 | | - .bbt_disable = ata_bbt_disable |
| | 94 | + .bbt_disable = ata_bbt_disable, |
| 94 | 95 | #endif |
| 95 | 96 | }; |
| 96 | 97 | |
| — | — | @@ -107,7 +108,7 @@ |
| 108 | 109 | static uint16_t ata_read_cbr(uint32_t volatile* reg) |
| 109 | 110 | { |
| 110 | 111 | while (!(ATA_PIO_READY & 2)) yield(); |
| 111 | | - volatile uint32_t dummy = *reg; |
| | 112 | + uint32_t dummy = *reg; |
| 112 | 113 | while (!(ATA_PIO_READY & 1)) yield(); |
| 113 | 114 | return ATA_PIO_RDATA; |
| 114 | 115 | } |
| — | — | @@ -492,20 +493,20 @@ |
| 493 | 494 | | SDCI_CMD_CMD_TYPE_ADTC | cmdtype | responsetype |
| 494 | 495 | | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR, |
| 495 | 496 | direction | MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_COUNT(count), |
| 496 | | - NULL, CEATA_COMMAND_TIMEOUT), 4, 0); |
| | 497 | + NULL, CEATA_COMMAND_TIMEOUT), 3, 0); |
| 497 | 498 | if (write) SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX; |
| 498 | 499 | if (wakeup_wait(&mmc_wakeup, timeout) == THREAD_TIMEOUT) |
| 499 | 500 | { |
| 500 | | - PASS_RC(ceata_cancel_command(), 4, 1); |
| | 501 | + PASS_RC(ceata_cancel_command(), 3, 1); |
| 501 | 502 | RET_ERR(2); |
| 502 | 503 | } |
| 503 | | - PASS_RC(mmc_dsta_check_data_success(), 4, 3); |
| | 504 | + PASS_RC(mmc_dsta_check_data_success(), 3, 3); |
| 504 | 505 | if (wakeup_wait(&mmc_comp_wakeup, timeout) == THREAD_TIMEOUT) |
| 505 | 506 | { |
| 506 | | - PASS_RC(ceata_cancel_command(), 4, 4); |
| 507 | | - RET_ERR(4); |
| | 507 | + PASS_RC(ceata_cancel_command(), 3, 4); |
| | 508 | + RET_ERR(5); |
| 508 | 509 | } |
| 509 | | - PASS_RC(ceata_check_error(), 4, 5); |
| | 510 | + PASS_RC(ceata_check_error(), 3, 6); |
| 510 | 511 | return 0; |
| 511 | 512 | } |
| 512 | 513 | |
| — | — | @@ -543,12 +544,25 @@ |
| 544 | 545 | |
| 545 | 546 | int ata_set_feature(uint32_t feature, uint32_t param) |
| 546 | 547 | { |
| 547 | | - PASS_RC(ata_wait_for_rdy(500000), 1, 0); |
| 548 | | - ata_write_cbr(&ATA_PIO_DVR, 0); |
| 549 | | - ata_write_cbr(&ATA_PIO_FED, 3); |
| 550 | | - ata_write_cbr(&ATA_PIO_SCR, param); |
| 551 | | - ata_write_cbr(&ATA_PIO_CSD, feature); |
| 552 | | - PASS_RC(ata_wait_for_rdy(500000), 1, 1); |
| | 548 | + if (ceata) |
| | 549 | + { |
| | 550 | + memset(ceata_taskfile, 0, 16); |
| | 551 | + ceata_taskfile[0x1] = feature; |
| | 552 | + ceata_taskfile[0x2] = param; |
| | 553 | + ceata_taskfile[0xf] = 0xef; |
| | 554 | + PASS_RC(ceata_wait_idle(), 2, 0); |
| | 555 | + PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 2, 1); |
| | 556 | + PASS_RC(ceata_wait_idle(), 2, 2); |
| | 557 | + } |
| | 558 | + else |
| | 559 | + { |
| | 560 | + PASS_RC(ata_wait_for_rdy(2000000), 2, 0); |
| | 561 | + ata_write_cbr(&ATA_PIO_DVR, 0); |
| | 562 | + ata_write_cbr(&ATA_PIO_FED, feature); |
| | 563 | + ata_write_cbr(&ATA_PIO_SCR, param); |
| | 564 | + ata_write_cbr(&ATA_PIO_CSD, 0xef); |
| | 565 | + PASS_RC(ata_wait_for_rdy(2000000), 2, 1); |
| | 566 | + } |
| 553 | 567 | return 0; |
| 554 | 568 | } |
| 555 | 569 | |
| — | — | @@ -555,10 +569,16 @@ |
| 556 | 570 | int ata_power_up() |
| 557 | 571 | { |
| 558 | 572 | ata_set_active(); |
| 559 | | - if (ata_powered) return 0; |
| 560 | 573 | i2c_sendbyte(0, 0xe6, 0x1b, 1); |
| 561 | 574 | if (ceata) |
| 562 | 575 | { |
| | 576 | + ata_lba48 = true; |
| | 577 | + ata_dma = true; |
| | 578 | + PCON(8) = 0x33333333; |
| | 579 | + PCON(9) = 0x00000033; |
| | 580 | + PCON(11) |= 0xf; |
| | 581 | + *((uint32_t volatile*)0x38a00000) = 0; |
| | 582 | + *((uint32_t volatile*)0x38700000) = 0; |
| 563 | 583 | clockgate_enable(9, true); |
| 564 | 584 | SDCI_RESET = 0xa5; |
| 565 | 585 | sleep(1000); |
| — | — | @@ -569,18 +589,21 @@ |
| 570 | 590 | SDCI_CDIV = SDCI_CDIV_CLKDIV(260); |
| 571 | 591 | *((uint32_t volatile*)0x3cf00200) = 0xb000f; |
| 572 | 592 | SDCI_IRQ_MASK = SDCI_IRQ_MASK_MASK_DAT_DONE_INT | SDCI_IRQ_MASK_MASK_IOCARD_IRQ_INT; |
| 573 | | - PASS_RC(mmc_init(), 2, 0); |
| | 593 | + PASS_RC(mmc_init(), 3, 0); |
| 574 | 594 | SDCI_CDIV = SDCI_CDIV_CLKDIV(4); |
| 575 | 595 | sleep(10000); |
| 576 | | - PASS_RC(ceata_init(8), 2, 1); |
| 577 | | - PASS_RC(ata_identify(ata_identify_data), 2, 2); |
| | 596 | + PASS_RC(ceata_init(8), 3, 1); |
| | 597 | + PASS_RC(ata_identify(ata_identify_data), 3, 2); |
| 578 | 598 | } |
| 579 | 599 | else |
| 580 | 600 | { |
| 581 | | - sleep(1000); |
| | 601 | + PCON(7) = 0x44444444; |
| | 602 | + PCON(8) = 0x44444444; |
| | 603 | + PCON(9) = 0x44444444; |
| | 604 | + PCON(10) = (PCON(10) & ~0xffff) | 0x4444; |
| 582 | 605 | clockgate_enable(5, true); |
| 583 | 606 | ATA_CFG = BIT(0); |
| 584 | | - sleep(1000); |
| | 607 | + sleep(10000); |
| 585 | 608 | ATA_CFG = 0; |
| 586 | 609 | sleep(6000); |
| 587 | 610 | ATA_SWRST = BIT(0); |
| — | — | @@ -593,7 +616,7 @@ |
| 594 | 617 | ATA_PIO_LHR = 0; |
| 595 | 618 | ATA_CFG = BIT(6); |
| 596 | 619 | while (!(ATA_PIO_READY & BIT(1))) sleep(100); |
| 597 | | - PASS_RC(ata_identify(ata_identify_data), 2, 0); |
| | 620 | + PASS_RC(ata_identify(ata_identify_data), 3, 3); |
| 598 | 621 | uint32_t piotime = 0x11f3; |
| 599 | 622 | uint32_t mdmatime = 0x1c175; |
| 600 | 623 | uint32_t udmatime = 0x5071152; |
| — | — | @@ -649,13 +672,14 @@ |
| 650 | 673 | } |
| 651 | 674 | } |
| 652 | 675 | ata_dma = param ? true : false; |
| 653 | | - PASS_RC(ata_set_feature(0xef, param), 2, 1); |
| 654 | | - if (ata_identify_data[82] & BIT(5)) PASS_RC(ata_set_feature(0x02, 0), 2, 2); |
| 655 | | - if (ata_identify_data[82] & BIT(6)) PASS_RC(ata_set_feature(0x55, 0), 2, 3); |
| | 676 | + PASS_RC(ata_set_feature(0x03, param), 3, 4); |
| 656 | 677 | ATA_PIO_TIME = piotime; |
| 657 | 678 | ATA_MDMA_TIME = mdmatime; |
| 658 | 679 | ATA_UDMA_TIME = udmatime; |
| 659 | 680 | } |
| | 681 | + if (ata_identify_data[82] & BIT(5)) |
| | 682 | + PASS_RC(ata_set_feature(ata_bbt ? 0x82 : 0x02, 0), 3, 5); |
| | 683 | + if (ata_identify_data[82] & BIT(6)) PASS_RC(ata_set_feature(0xaa, 0), 3, 6); |
| 660 | 684 | if (ata_lba48) |
| 661 | 685 | ata_total_sectors = ata_identify_data[100] |
| 662 | 686 | | (((uint64_t)ata_identify_data[101]) << 16) |
| — | — | @@ -678,7 +702,8 @@ |
| 679 | 703 | ceata_taskfile[0xf] = 0xe0; |
| 680 | 704 | ceata_wait_idle(); |
| 681 | 705 | ceata_write_multiple_register(0, ceata_taskfile, 16); |
| 682 | | - sleep(1000000); |
| | 706 | + ceata_wait_idle(); |
| | 707 | + sleep(100000); |
| 683 | 708 | clockgate_enable(9, false); |
| 684 | 709 | } |
| 685 | 710 | else |
| — | — | @@ -692,6 +717,11 @@ |
| 693 | 718 | while (!(ATA_CONTROL & BIT(1))) yield(); |
| 694 | 719 | clockgate_enable(5, false); |
| 695 | 720 | } |
| | 721 | + PCON(7) = 0; |
| | 722 | + PCON(8) = 0; |
| | 723 | + PCON(9) = 0; |
| | 724 | + PCON(10) &= ~0xffff; |
| | 725 | + PCON(11) &= ~0xf; |
| 696 | 726 | i2c_sendbyte(0, 0xe6, 0x1b, 0); |
| 697 | 727 | } |
| 698 | 728 | |
| — | — | @@ -863,7 +893,7 @@ |
| 864 | 894 | uint32_t cnt; |
| 865 | 895 | PASS_RC(ata_bbt_translate(sector, count, &phys, &cnt), 0, 0); |
| 866 | 896 | uint32_t offset = phys - sector; |
| 867 | | - if (offset != ata_last_offset && phys - ata_last_phys < 64) ata_soft_reset(); |
| | 897 | + if (offset != ata_last_offset && phys - ata_last_phys < 64) ata_reset(); |
| 868 | 898 | ata_last_offset = offset; |
| 869 | 899 | ata_last_phys = phys + cnt; |
| 870 | 900 | PASS_RC(ata_rw_sectors_internal(phys, cnt, buffer, write), 0, 0); |
| — | — | @@ -889,7 +919,7 @@ |
| 890 | 920 | uint32_t cnt = MIN(ata_lba48 ? 8192 : 32, count); |
| 891 | 921 | int rc = -1; |
| 892 | 922 | rc = ata_rw_chunk(sector, cnt, buffer, write); |
| 893 | | - if (rc && ata_error_srst) ata_soft_reset(); |
| | 923 | + if (rc && ata_error_srst) ata_reset(); |
| 894 | 924 | if (rc && ata_retries) |
| 895 | 925 | { |
| 896 | 926 | void* buf = buffer; |
| — | — | @@ -901,7 +931,7 @@ |
| 902 | 932 | while (tries-- && rc) |
| 903 | 933 | { |
| 904 | 934 | rc = ata_rw_chunk(sect, 1, buf, write); |
| 905 | | - if (rc && ata_error_srst) ata_soft_reset(); |
| | 935 | + if (rc && ata_error_srst) ata_reset(); |
| 906 | 936 | } |
| 907 | 937 | if (rc) break; |
| 908 | 938 | buf += SECTOR_SIZE; |
| — | — | @@ -941,17 +971,46 @@ |
| 942 | 972 | ata_write_cbr(&ATA_PIO_DAD, BIT(1) | BIT(2)); |
| 943 | 973 | sleep(10); |
| 944 | 974 | ata_write_cbr(&ATA_PIO_DAD, 0); |
| 945 | | - rc = ata_wait_for_rdy(20000000); |
| | 975 | + rc = ata_wait_for_rdy(3000000); |
| 946 | 976 | } |
| | 977 | + ata_set_active(); |
| | 978 | + mutex_unlock(&ata_mutex); |
| | 979 | + PASS_RC(rc, 1, 1); |
| | 980 | + return 0; |
| | 981 | +} |
| | 982 | + |
| | 983 | +int ata_hard_reset() |
| | 984 | +{ |
| | 985 | + mutex_lock(&ata_mutex, TIMEOUT_BLOCK); |
| | 986 | + PASS_RC(ata_power_up(), 0, 0); |
| | 987 | + ata_set_active(); |
| | 988 | + mutex_unlock(&ata_mutex); |
| | 989 | + return 0; |
| | 990 | +} |
| | 991 | + |
| | 992 | +int ata_reset() |
| | 993 | +{ |
| | 994 | + int rc; |
| | 995 | + mutex_lock(&ata_mutex, TIMEOUT_BLOCK); |
| | 996 | + if (!ata_powered) PASS_RC(ata_power_up(), 2, 0); |
| | 997 | + ata_set_active(); |
| | 998 | + rc = ata_soft_reset(); |
| 947 | 999 | if (IS_ERR(rc)) |
| 948 | 1000 | { |
| 949 | | - ata_power_down(); |
| 950 | | - sleep(3000000); |
| 951 | | - ata_power_up(); |
| | 1001 | + rc = ata_hard_reset(); |
| | 1002 | + if (IS_ERR(rc)) |
| | 1003 | + { |
| | 1004 | + rc = ERR_RC((rc << 2) | 1); |
| | 1005 | + ata_power_down(); |
| | 1006 | + sleep(3000000); |
| | 1007 | + int rc2 = ata_power_up(); |
| | 1008 | + if (IS_ERR(rc2)) rc = ERR_RC((rc << 2) | 2); |
| | 1009 | + } |
| | 1010 | + else rc = 1; |
| 952 | 1011 | } |
| 953 | 1012 | ata_set_active(); |
| 954 | 1013 | mutex_unlock(&ata_mutex); |
| 955 | | - PASS_RC(rc, 1, 1); |
| | 1014 | + return rc; |
| 956 | 1015 | } |
| 957 | 1016 | |
| 958 | 1017 | int ata_read_sectors(IF_MD2(int drive,) unsigned long start, int incount, |
| — | — | @@ -1032,7 +1091,7 @@ |
| 1033 | 1092 | { |
| 1034 | 1093 | mutex_lock(&ata_mutex, TIMEOUT_BLOCK); |
| 1035 | 1094 | ata_bbt_disable(); |
| 1036 | | - PASS_RC(ata_power_up(), 0, 0); |
| | 1095 | + PASS_RC(ata_power_up(), 1, 0); |
| 1037 | 1096 | uint32_t* buf = (uint32_t*)memalign(0x10, 0x1000); |
| 1038 | 1097 | if (buf) |
| 1039 | 1098 | { |
| — | — | @@ -1040,6 +1099,7 @@ |
| 1041 | 1100 | ata_virtual_sectors = ata_total_sectors; |
| 1042 | 1101 | else if (!memcmp(buf, "emBIbbth", 8)) |
| 1043 | 1102 | { |
| | 1103 | + if (ata_identify_data[82] & BIT(5)) PASS_RC(ata_set_feature(0x02, 0), 1, 1); |
| 1044 | 1104 | ata_virtual_sectors = (((uint64_t)buf[0x1fd]) << 32) | buf[0x1fc]; |
| 1045 | 1105 | uint32_t count = buf[0x1ff]; |
| 1046 | 1106 | ata_bbt = (typeof(ata_bbt))memalign(0x10, 0x1000 * count); |
| — | — | @@ -1074,6 +1134,7 @@ |
| 1075 | 1135 | } |
| 1076 | 1136 | else ata_virtual_sectors = ata_total_sectors; |
| 1077 | 1137 | mutex_unlock(&ata_mutex); |
| | 1138 | + return 0; |
| 1078 | 1139 | } |
| 1079 | 1140 | #endif |
| 1080 | 1141 | |
| — | — | @@ -1084,23 +1145,6 @@ |
| 1085 | 1146 | wakeup_init(&mmc_wakeup); |
| 1086 | 1147 | wakeup_init(&mmc_comp_wakeup); |
| 1087 | 1148 | ceata = PDAT(11) & BIT(1); |
| 1088 | | - if (ceata) |
| 1089 | | - { |
| 1090 | | - ata_lba48 = true; |
| 1091 | | - ata_dma = true; |
| 1092 | | - PCON(8) = 0x33333333; |
| 1093 | | - PCON(9) = (PCON(9) & ~0xff) | 0x33; |
| 1094 | | - PCON(11) |= 0xf; |
| 1095 | | - *((uint32_t volatile*)0x38a00000) = 0; |
| 1096 | | - *((uint32_t volatile*)0x38700000) = 0; |
| 1097 | | - } |
| 1098 | | - else |
| 1099 | | - { |
| 1100 | | - PCON(7) = 0x44444444; |
| 1101 | | - PCON(8) = 0x44444444; |
| 1102 | | - PCON(9) = 0x44444444; |
| 1103 | | - PCON(10) = (PCON(10) & ~0xffff) | 0x4444; |
| 1104 | | - } |
| 1105 | 1149 | ata_powered = false; |
| 1106 | 1150 | ata_total_sectors = 0; |
| 1107 | 1151 | #ifdef ATA_HAVE_BBT |
| Index: emcore/trunk/storage.c |
| — | — | @@ -334,7 +334,7 @@ |
| 335 | 335 | int rc=0; |
| 336 | 336 | |
| 337 | 337 | #if (CONFIG_STORAGE & STORAGE_ATA) |
| 338 | | - if ((rc=ata_soft_reset())) return rc; |
| | 338 | + if ((rc=ata_reset())) return rc; |
| 339 | 339 | #endif |
| 340 | 340 | |
| 341 | 341 | #if (CONFIG_STORAGE & STORAGE_MMC) |