Created
April 23, 2016 22:12
-
-
Save anonymous/5f3bcab69a01fdfa9f47bac73b74cf10 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/apps/plugins/SOURCES b/apps/plugins/SOURCES | |
index c512a9e..e9d6f58 100644 | |
--- a/apps/plugins/SOURCES | |
+++ b/apps/plugins/SOURCES | |
@@ -221,7 +221,7 @@ superdom.c | |
#endif /* LCD_DEPTH > 1 */ | |
- | |
+test_disk.c | |
#ifdef HAVE_TEST_PLUGINS /* enable in advanced build options */ | |
#ifdef HAVE_ADJUSTABLE_CPU_FREQ | |
test_boost.c | |
diff --git a/apps/plugins/test_disk.c b/apps/plugins/test_disk.c | |
index 332cc1c..b458b33 100644 | |
--- a/apps/plugins/test_disk.c | |
+++ b/apps/plugins/test_disk.c | |
@@ -433,10 +433,10 @@ enum plugin_status plugin_start(const void* parameter) | |
} | |
audiobuf = rb->plugin_get_audio_buffer(&audiobuflen); | |
- /* align start and length to 32 bit */ | |
- align = (-(intptr_t)audiobuf) & 3; | |
+ /* align start and length to 16 byte */ | |
+ align = (-(intptr_t)audiobuf) & 0xf; | |
audiobuf += align; | |
- audiobuflen = (audiobuflen - align) & ~3; | |
+ audiobuflen = (audiobuflen - align) & ~0xf; | |
rb->srand(*rb->current_tick); | |
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c | |
index ec04ac1..e4d4e39 100644 | |
--- a/firmware/drivers/ata.c | |
+++ b/firmware/drivers/ata.c | |
@@ -209,6 +209,14 @@ static ICODE_ATTR int wait_for_bsy(void) | |
{ | |
long timeout = current_tick + HZ*30; | |
+ /* | |
+ need to wait before reading status according to ATA specification | |
+ instead of using sleep function, read ATA_STATUS 3 times and | |
+ discard the first two reads, pio timing 120ns *3 dealy, | |
+ */ | |
+ ATA_IN8(ATA_STATUS); | |
+ ATA_IN8(ATA_STATUS); | |
+ | |
do | |
{ | |
if (!(ATA_IN8(ATA_STATUS) & STATUS_BSY)) | |
@@ -388,8 +396,11 @@ static int ata_transfer_sectors(unsigned long start, | |
timeout = current_tick + READWRITE_TIMEOUT; | |
+/* nothing to select for single drive | |
ATA_OUT8(ATA_SELECT, ata_device); | |
- if (!wait_for_rdy()) | |
+*/ | |
+ | |
+ if (!wait_for_bsy()) | |
{ | |
ret = -3; | |
goto error; | |
@@ -447,13 +458,15 @@ static int ata_transfer_sectors(unsigned long start, | |
#endif | |
} | |
- /* wait at least 400ns between writing command and reading status */ | |
- __asm__ volatile ("nop"); | |
+ /* wait at least 400ns between writing command and reading status | |
+ we might have a problem here because the delay here is CPU frequency dependent | |
+ move this delay to wait_for_bsy() and use IO delay. | |
+ */ | |
+/* __asm__ volatile ("nop"); | |
__asm__ volatile ("nop"); | |
__asm__ volatile ("nop"); | |
__asm__ volatile ("nop"); | |
- __asm__ volatile ("nop"); | |
- | |
+*/ | |
#ifdef HAVE_ATA_DMA | |
if (usedma) { | |
if (!ata_dma_finish()) | |
@@ -1022,7 +1035,7 @@ static int identify(void) | |
{ | |
int i; | |
- ATA_OUT8(ATA_SELECT, ata_device); | |
+// ATA_OUT8(ATA_SELECT, ata_device); | |
if(!wait_for_rdy()) { | |
DEBUGF("identify() - not RDY\n"); | |
@@ -1057,7 +1070,9 @@ static int perform_soft_reset(void) | |
ATA_OUT8(ATA_SELECT, SELECT_LBA | ata_device ); | |
ATA_OUT8(ATA_CONTROL, CONTROL_nIEN|CONTROL_SRST ); | |
- sleep(1); /* >= 5us */ | |
+ | |
+/*the delay here is unnecessary*/ | |
+// sleep(1); /* >= 5us */ | |
#ifdef HAVE_ATA_DMA | |
/* DMA requires INTRQ be enabled */ | |
@@ -1065,7 +1080,13 @@ static int perform_soft_reset(void) | |
#else | |
ATA_OUT8(ATA_CONTROL, CONTROL_nIEN); | |
#endif | |
- sleep(1); /* >2ms */ | |
+ | |
+/*we've been sleep too long here, some drives (flash drives) might have already | |
+fall into sleep mode during the 1sec sleep, subsequently lock into soft_reset loop. | |
+This could be the cause of "sucker" of 30 seconds or freeze. As we have already added the 400us | |
+delay in wait_for_bsy(), which is called in wait_for_rdy(), no more wait is needed here. | |
+*/ | |
+// sleep(1); /* >2ms */ | |
/* This little sucker can take up to 30 seconds */ | |
retry_count = 8; | |
diff --git a/firmware/export/config/ipodvideo.h b/firmware/export/config/ipodvideo.h | |
index 707c7d9..1d36ea1 100644 | |
--- a/firmware/export/config/ipodvideo.h | |
+++ b/firmware/export/config/ipodvideo.h | |
@@ -241,6 +241,7 @@ | |
*/ | |
#ifndef BOOTLOADER | |
#define HAVE_ATA_DMA | |
+#define ATA_DMA_WRITES | |
#endif | |
/* Define this if a programmable hotkey is mapped */ | |
diff --git a/firmware/target/arm/pp/ata-pp5020.c b/firmware/target/arm/pp/ata-pp5020.c | |
index 1fc302a..aacb988 100644 | |
--- a/firmware/target/arm/pp/ata-pp5020.c | |
+++ b/firmware/target/arm/pp/ata-pp5020.c | |
@@ -42,6 +42,22 @@ bool ata_is_coldstart() | |
/* TODO: Implement coldstart variable */ | |
} | |
+/* These are PIO timings for 80 Mhz. At 24 Mhz, | |
+ the first value is 0 but the rest are the same. | |
+ They go in IDE0_PRI_TIMING0. | |
+ | |
+ Rockbox used 0x10, and test_disk shows that leads to faster PIO. | |
+ If 0x10 is incorrect, these timings may be needed with some devices. | |
+*/ | |
+static const unsigned long pio80mhz[] = { | |
+ 0xC293, 0x43A2, 0x11A1, 0x7232, 0x3131 | |
+}; | |
+ | |
+/* Setup the timing for PIO mode */ | |
+void ata_set_pio_timings(int mode){ | |
+ IDE0_PRI_TIMING0 = pio80mhz[mode]; | |
+}; | |
+ | |
void ata_device_init() | |
{ | |
#ifdef SAMSUNG_YH920 | |
@@ -63,21 +79,14 @@ void ata_device_init() | |
#endif | |
#endif | |
- IDE0_PRI_TIMING0 = 0x10; | |
- IDE0_PRI_TIMING1 = 0x80002150; | |
+ /* set timing for pio mode4, it is very unlikely the the HDD is not support | |
+ pio mode4, and crucial M500 mSATA drive only support pio mode 3 & 4 according | |
+ to micron datasheet | |
+ */ | |
+ IDE0_PRI_TIMING0 = pio80mhz[4]; | |
+ IDE0_PRI_TIMING1 = 0x80003371; //udma 2 timing | |
} | |
-/* These are PIO timings for 80 Mhz. At 24 Mhz, | |
- the first value is 0 but the rest are the same. | |
- They go in IDE0_PRI_TIMING0. | |
- | |
- Rockbox used 0x10, and test_disk shows that leads to faster PIO. | |
- If 0x10 is incorrect, these timings may be needed with some devices. | |
-static const unsigned long pio80mhz[] = { | |
- 0xC293, 0x43A2, 0x11A1, 0x7232, 0x3131 | |
-}; | |
-*/ | |
- | |
#ifdef HAVE_ATA_DMA | |
/* Timings for multi-word and ultra DMA modes. | |
These go in IDE0_PRI_TIMING1 | |
diff --git a/firmware/target/arm/pp/ata-target.h b/firmware/target/arm/pp/ata-target.h | |
index b888f85..b3e4f79 100644 | |
--- a/firmware/target/arm/pp/ata-target.h | |
+++ b/firmware/target/arm/pp/ata-target.h | |
@@ -52,7 +52,7 @@ | |
/* asm optimized reading and writing */ | |
#define ATA_OPTIMIZED_READING | |
#define ATA_OPTIMIZED_WRITING | |
- | |
+#define ATA_SET_PIO_TIMING | |
#endif /* CONFIG_CPU */ | |
#ifdef HAVE_ATA_DMA | |
@@ -72,7 +72,7 @@ | |
* UDMA 1 is stable at 24 Mhz. | |
*/ | |
#if CPUFREQ_NORMAL >= 30000000 | |
-#define ATA_MAX_UDMA 2 | |
+#define ATA_MAX_UDMA 4 | |
#elif CPUFREQ_NORMAL >= 24000000 | |
#define ATA_MAX_UDMA 1 | |
#else | |
-- | |
2.8.0 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment