From aa7357861a8ba9762ba1c5ac5fbcb2598abe3cd5 Mon Sep 17 00:00:00 2001 From: Solomon Peachy Date: Mon, 22 Apr 2024 21:55:26 -0400 Subject: 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 --- .../target/arm/s5l8702/ipod6g/storage_ata-6g.c | 49 ++++++++++++++++++++-- 1 file 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 @@ #define CMD_READ_DMA 0xC8 #define CMD_WRITE_DMA 0xCA #define CMD_STANDBY_IMMEDIATE 0xE0 +#define CMD_FLUSH_CACHE 0xE7 +#define CMD_FLUSH_CACHE_EXT 0xEA #define CMD_IDENTIFY 0xEC #define CMD_SET_FEATURES 0xEF @@ -678,10 +680,15 @@ static int ata_power_up(void) } ata_dma = param ? true : false; dma_mode = param; - PASS_RC(ata_set_feature(0x03, param), 3, 4); + PASS_RC(ata_set_feature(0x03, param), 3, 4); /* Transfer mode */ if (ata_identify_data[82] & BIT(5)) - PASS_RC(ata_set_feature(0x02, 0), 3, 5); - if (ata_identify_data[82] & BIT(6)) PASS_RC(ata_set_feature(0xaa, 0), 3, 6); + PASS_RC(ata_set_feature(0x02, 0), 3, 5); /* Enable volatile write cache */ + if (ata_identify_data[82] & BIT(6)) + PASS_RC(ata_set_feature(0xaa, 0), 3, 6); /* Enable read lookahead */ + if (ata_identify_data[83] & BIT(3)) + PASS_RC(ata_set_feature(0x05, 0x80), 3, 7); /* Enable lowest power mode w/o standby */ + if (ata_identify_data[83] & BIT(9)) + PASS_RC(ata_set_feature(0x42, 0x80), 3, 8); /* Enable lowest noise mode */ ATA_PIO_TIME = piotime; ATA_MDMA_TIME = mdmatime; ATA_UDMA_TIME = udmatime; @@ -692,7 +699,8 @@ static int ata_power_up(void) | (((uint64_t)ata_identify_data[101]) << 16) | (((uint64_t)ata_identify_data[102]) << 32) | (((uint64_t)ata_identify_data[103]) << 48); - else ata_total_sectors = ata_identify_data[60] | (((uint32_t)ata_identify_data[61]) << 16); + else + ata_total_sectors = ata_identify_data[60] | (((uint32_t)ata_identify_data[61]) << 16); ata_total_sectors >>= 3; ata_powered = true; ata_set_active(); @@ -981,12 +989,45 @@ void ata_spindown(int seconds) ata_sleep_timeout = seconds * HZ; } +static void ata_flush_cache(void) +{ + uint8_t cmd; + + if (ata_identify_data[83] & BIT(13)) { + cmd = CMD_FLUSH_CACHE_EXT; + } else if (ata_identify_data[83] & BIT(12)) { + cmd = CMD_FLUSH_CACHE; + } else { + /* If neither (mandatory!) command is supported + then don't issue it. */ + return; + } + + if (ceata) + { + memset(ceata_taskfile, 0, 16); + ceata_taskfile[0xf] = cmd; + ceata_wait_idle(); + ceata_write_multiple_register(0, ceata_taskfile, 16); + ceata_wait_idle(); + } + else + { + ata_wait_for_rdy(1000000); + ata_write_cbr(&ATA_PIO_DVR, 0); + ata_write_cbr(&ATA_PIO_CSD, cmd); + ata_wait_for_rdy(1000000); + } +} + void ata_sleepnow(void) { mutex_lock(&ata_mutex); if (ata_disk_can_poweroff()) ata_power_down(); + else + ata_flush_cache(); mutex_unlock(&ata_mutex); } -- cgit v1.2.3