diff --strip-trailing-cr -u -r ../../rockbox/trunk/firmware/drivers/fat.c ../../rockbox-daily-20080330/firmware/drivers/fat.c --- ../../rockbox/trunk/firmware/drivers/fat.c 2008-03-29 09:50:37.000000000 +0200 +++ ../../rockbox-daily-20080330/firmware/drivers/fat.c 2008-03-29 10:05:08.000000000 +0200 @@ -2171,7 +2171,7 @@ first = sector; if ( ((sector != first) && (sector != last+1)) || /* not sequential */ - (last-first+1 == 256) ) { /* max 256 sectors per ata request */ + (last-first+1 == 128) ) { /* max 128 sectors per ata request */ long count = last - first + 1; rc = transfer(IF_MV2(fat_bpb,) first, count, buf, write ); if (rc < 0) diff --strip-trailing-cr -u -r ../../rockbox/trunk/firmware/target/arm/sandisk/ata-c200_e200.c ../../rockbox-daily-20080330/firmware/target/arm/sandisk/ata-c200_e200.c --- ../../rockbox/trunk/firmware/target/arm/sandisk/ata-c200_e200.c 2008-03-29 09:50:28.000000000 +0200 +++ ../../rockbox-daily-20080330/firmware/target/arm/sandisk/ata-c200_e200.c 2008-03-30 21:14:32.000000000 +0300 @@ -182,6 +182,19 @@ static unsigned int check_time[NUM_EC]; +static unsigned int sd_cpu_boost_ticks; +static unsigned int sd_cpu_boost_activated; + +/* remove cpu boost 1sec after the last disk access */ +static void sd_cpu_boost_control(void) +{ + if(sd_cpu_boost_ticks-- == 0) + { + cpu_boost(false); + sd_cpu_boost_activated = 0; + } +} + static inline bool sd_check_timeout(long timeout, int id) { return !TIME_AFTER(USEC_TIMER, check_time[id] + timeout); @@ -792,6 +805,17 @@ led(onoff); } + +/* at least 4 dma channels are available on the PP502x: +0x20 */ +#define DMA_CMD_REG_0 (*(volatile unsigned long*)0x6000b000) // dma size (4 ... 65536Byte) +#define DMA_STATUS_0 (*(volatile unsigned long*)0x6000b004) // dma status (poll bit31) +#define DMA_MEMPTR_0 (*(volatile unsigned long*)0x6000b010) // dma destination +#define DMA_FLAGS_0 (*(volatile unsigned long*)0x6000b014) +#define DMA_SOURCE_0 (*(volatile unsigned long*)0x6000b018) // dma source +#define DMA_UNKNOWN_0 (*(volatile unsigned long*)0x6000b01c) + +static char aligned[65536] CACHEALIGN_AT_LEAST_ATTR(16); + int ata_read_sectors(IF_MV2(int drive,) unsigned long start, int incount, void* inbuf) { @@ -799,13 +823,19 @@ const int drive = 0; #endif int ret; - unsigned char *buf, *buf_end; int bank; - /* TODO: Add DMA support. */ - mutex_lock(&sd_mtx); + /* Boost cpu on disk access for 1sec. */ + /* This is neccessary, because dma doesn't work reliable at 30MHz */ + sd_cpu_boost_ticks = 100; + if(sd_cpu_boost_activated == 0) + { + cpu_boost(true); + sd_cpu_boost_activated = 1; + } + ata_led(true); ata_read_retry: @@ -837,7 +867,7 @@ if (ret < 0) goto ata_read_error; } - + start -= bank * BLOCKS_PER_BANK; } @@ -861,22 +891,23 @@ if (ret < 0) goto ata_read_error; - /* TODO: Don't assume BLOCK_SIZE == SECTOR_SIZE */ +/////////////////////////////////////////////////////////////////////////////// + DMA_SOURCE_0 = (int)&DATA_REG; + DMA_MEMPTR_0 = (int)aligned + 0x10000000; /* use uncached area */ + DMA_UNKNOWN_0 = 0x12010000; + DMA_FLAGS_0 = 0x25000000; + DMA_CMD_REG_0 = 0x050d0000 + incount * currcard->block_size - 4; + DMA_CMD_REG_0 |= 0x80000000; /* Bit31:start dma, Bit30:enable interrupt */ + + /* poll status for dma completed */ + while(DMA_STATUS_0 & 0x80000000) yield(); + + DMA_CMD_REG_0 &=~0x80000000; + invalidate_icache(); +/////////////////////////////////////////////////////////////////////////////// - buf_end = (unsigned char *)inbuf + incount * currcard->block_size; - for (buf = inbuf; buf < buf_end;) - { - /* Wait for the FIFO to be full */ - if (sd_poll_status(FIFO_FULL, 0x80000)) - { - copy_read_sectors_fast(&buf); /* Copy one chunk of 16 words */ - /* TODO: Switch bank if necessary */ - continue; - } - - ret = -EC_FIFO_READ_FULL; - goto ata_read_error; - } + /* copy the data from 16byte aligned area */ + memcpy(inbuf, aligned, incount*512); last_disk_activity = current_tick; @@ -915,12 +946,24 @@ #ifndef HAVE_HOTSWAP const int drive = 0; #endif + unsigned short *ptr; int ret; - const unsigned char *buf, *buf_end; int bank; mutex_lock(&sd_mtx); + /* Boost cpu on disk access for 1sec. */ + /* This is neccessary, because dma doesn't work reliable at 30MHz */ + sd_cpu_boost_ticks = 100; + if(sd_cpu_boost_activated == 0) + { + cpu_boost(true); + sd_cpu_boost_activated = 1; + } + + /* copy the data to 16byte aligned area */ + memcpy(aligned, outbuf, count * 512); + ata_led(true); ata_write_retry: @@ -976,29 +1019,27 @@ if (ret < 0) goto ata_write_error; - buf_end = outbuf + count * currcard->block_size - 2*FIFO_LEN; +/////////////////////////////////////////////////////////////////////////////// + invalidate_icache(); + DMA_SOURCE_0 = (int)&DATA_REG; + DMA_MEMPTR_0 = (int)aligned + 0x10000000; /* use uncached area */ + DMA_UNKNOWN_0 = 0x12010000; + DMA_FLAGS_0 = 0x25000000; + DMA_CMD_REG_0 = 0x0d0d0000 + count * currcard->block_size - 0x10 - 4; + DMA_CMD_REG_0 |= 0x80000000; /* Bit31:start dma, Bit30:enable interrupt */ - for (buf = outbuf; buf <= buf_end;) - { - if (buf == buf_end) - { - /* Set SD_STATE_REG to PRG for the last buffer fill */ - SD_STATE_REG = PRG; - } + /* poll status for dma completed */ + while(DMA_STATUS_0 & 0x80000000) yield(); - udelay(2); /* needed here (loop is too fast :-) */ + DMA_CMD_REG_0 &=~0x80000000; - /* Wait for the FIFO to empty */ - if (sd_poll_status(FIFO_EMPTY, 0x80000)) - { - copy_write_sectors(&buf); /* Copy one chunk of 16 words */ - /* TODO: Switch bank if necessary */ - continue; - } - - ret = -EC_FIFO_WR_EMPTY; - goto ata_write_error; - } + /* set SD_STATE_REG to PRG and send the last 16bytes in PRG mode */ + SD_STATE_REG = PRG; + ptr = (unsigned short*)(aligned + count * currcard->block_size - 0x10); + udelay(1); /* needed here ??? */ + DATA_REG = ptr[0]; DATA_REG = ptr[1]; DATA_REG = ptr[2]; DATA_REG = ptr[3]; + DATA_REG = ptr[4]; DATA_REG = ptr[5]; DATA_REG = ptr[6]; DATA_REG = ptr[7]; +/////////////////////////////////////////////////////////////////////////////// last_disk_activity = current_tick; @@ -1178,6 +1219,8 @@ if (!initialized) mutex_init(&sd_mtx); + tick_add_task(sd_cpu_boost_control); + mutex_lock(&sd_mtx); ata_led(false); @@ -1323,4 +1366,4 @@ timeout_register(&sd1_oneshot, sd1_oneshot_callback, (3*HZ/10), 0); } -#endif /* HAVE_HOTSWAP */ +#endif