diff options
author | Solomon Peachy <pizza@shaftnet.org> | 2024-04-22 21:55:26 -0400 |
---|---|---|
committer | Solomon Peachy <pizza@shaftnet.org> | 2024-04-26 07:28:01 -0400 |
commit | aa7357861a8ba9762ba1c5ac5fbcb2598abe3cd5 (patch) | |
tree | 54e43599b3e5bbd8e423bd3b0d768ff5918e2502 | |
parent | 9a17185e631b76d787152a9534bc2744036f57c0 (diff) | |
download | rockbox-aa7357861a8ba9762ba1c5ac5fbcb2598abe3cd5.tar.gz rockbox-aa7357861a8ba9762ba1c5ac5fbcb2598abe3cd5.zip |
ipod6g: Issue a FLUSH_CACHE[_EXT] command if device can't sleep.
Additionally, synchronize with the standard ATA driver's feature table
* Acoustic management set to quietest
* Set power mode to lowest w/o standby
Change-Id: I12e64354d4c946228e9a55fc8da2114127d08d28
-rw-r--r-- | firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c | 49 |
1 files changed, 45 insertions, 4 deletions
diff --git a/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c b/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c index f77cfcbac6..7a3be20577 100644 --- a/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c +++ b/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c | |||
@@ -48,6 +48,8 @@ | |||
48 | #define CMD_READ_DMA 0xC8 | 48 | #define CMD_READ_DMA 0xC8 |
49 | #define CMD_WRITE_DMA 0xCA | 49 | #define CMD_WRITE_DMA 0xCA |
50 | #define CMD_STANDBY_IMMEDIATE 0xE0 | 50 | #define CMD_STANDBY_IMMEDIATE 0xE0 |
51 | #define CMD_FLUSH_CACHE 0xE7 | ||
52 | #define CMD_FLUSH_CACHE_EXT 0xEA | ||
51 | #define CMD_IDENTIFY 0xEC | 53 | #define CMD_IDENTIFY 0xEC |
52 | #define CMD_SET_FEATURES 0xEF | 54 | #define CMD_SET_FEATURES 0xEF |
53 | 55 | ||
@@ -678,10 +680,15 @@ static int ata_power_up(void) | |||
678 | } | 680 | } |
679 | ata_dma = param ? true : false; | 681 | ata_dma = param ? true : false; |
680 | dma_mode = param; | 682 | dma_mode = param; |
681 | PASS_RC(ata_set_feature(0x03, param), 3, 4); | 683 | PASS_RC(ata_set_feature(0x03, param), 3, 4); /* Transfer mode */ |
682 | if (ata_identify_data[82] & BIT(5)) | 684 | if (ata_identify_data[82] & BIT(5)) |
683 | PASS_RC(ata_set_feature(0x02, 0), 3, 5); | 685 | PASS_RC(ata_set_feature(0x02, 0), 3, 5); /* Enable volatile write cache */ |
684 | if (ata_identify_data[82] & BIT(6)) PASS_RC(ata_set_feature(0xaa, 0), 3, 6); | 686 | if (ata_identify_data[82] & BIT(6)) |
687 | PASS_RC(ata_set_feature(0xaa, 0), 3, 6); /* Enable read lookahead */ | ||
688 | if (ata_identify_data[83] & BIT(3)) | ||
689 | PASS_RC(ata_set_feature(0x05, 0x80), 3, 7); /* Enable lowest power mode w/o standby */ | ||
690 | if (ata_identify_data[83] & BIT(9)) | ||
691 | PASS_RC(ata_set_feature(0x42, 0x80), 3, 8); /* Enable lowest noise mode */ | ||
685 | ATA_PIO_TIME = piotime; | 692 | ATA_PIO_TIME = piotime; |
686 | ATA_MDMA_TIME = mdmatime; | 693 | ATA_MDMA_TIME = mdmatime; |
687 | ATA_UDMA_TIME = udmatime; | 694 | ATA_UDMA_TIME = udmatime; |
@@ -692,7 +699,8 @@ static int ata_power_up(void) | |||
692 | | (((uint64_t)ata_identify_data[101]) << 16) | 699 | | (((uint64_t)ata_identify_data[101]) << 16) |
693 | | (((uint64_t)ata_identify_data[102]) << 32) | 700 | | (((uint64_t)ata_identify_data[102]) << 32) |
694 | | (((uint64_t)ata_identify_data[103]) << 48); | 701 | | (((uint64_t)ata_identify_data[103]) << 48); |
695 | else ata_total_sectors = ata_identify_data[60] | (((uint32_t)ata_identify_data[61]) << 16); | 702 | else |
703 | ata_total_sectors = ata_identify_data[60] | (((uint32_t)ata_identify_data[61]) << 16); | ||
696 | ata_total_sectors >>= 3; | 704 | ata_total_sectors >>= 3; |
697 | ata_powered = true; | 705 | ata_powered = true; |
698 | ata_set_active(); | 706 | ata_set_active(); |
@@ -981,12 +989,45 @@ void ata_spindown(int seconds) | |||
981 | ata_sleep_timeout = seconds * HZ; | 989 | ata_sleep_timeout = seconds * HZ; |
982 | } | 990 | } |
983 | 991 | ||
992 | static void ata_flush_cache(void) | ||
993 | { | ||
994 | uint8_t cmd; | ||
995 | |||
996 | if (ata_identify_data[83] & BIT(13)) { | ||
997 | cmd = CMD_FLUSH_CACHE_EXT; | ||
998 | } else if (ata_identify_data[83] & BIT(12)) { | ||
999 | cmd = CMD_FLUSH_CACHE; | ||
1000 | } else { | ||
1001 | /* If neither (mandatory!) command is supported | ||
1002 | then don't issue it. */ | ||
1003 | return; | ||
1004 | } | ||
1005 | |||
1006 | if (ceata) | ||
1007 | { | ||
1008 | memset(ceata_taskfile, 0, 16); | ||
1009 | ceata_taskfile[0xf] = cmd; | ||
1010 | ceata_wait_idle(); | ||
1011 | ceata_write_multiple_register(0, ceata_taskfile, 16); | ||
1012 | ceata_wait_idle(); | ||
1013 | } | ||
1014 | else | ||
1015 | { | ||
1016 | ata_wait_for_rdy(1000000); | ||
1017 | ata_write_cbr(&ATA_PIO_DVR, 0); | ||
1018 | ata_write_cbr(&ATA_PIO_CSD, cmd); | ||
1019 | ata_wait_for_rdy(1000000); | ||
1020 | } | ||
1021 | } | ||
1022 | |||
984 | void ata_sleepnow(void) | 1023 | void ata_sleepnow(void) |
985 | { | 1024 | { |
986 | mutex_lock(&ata_mutex); | 1025 | mutex_lock(&ata_mutex); |
987 | 1026 | ||
988 | if (ata_disk_can_poweroff()) | 1027 | if (ata_disk_can_poweroff()) |
989 | ata_power_down(); | 1028 | ata_power_down(); |
1029 | else | ||
1030 | ata_flush_cache(); | ||
990 | 1031 | ||
991 | mutex_unlock(&ata_mutex); | 1032 | mutex_unlock(&ata_mutex); |
992 | } | 1033 | } |