From e025cb1c3816cf755ed61484695dcabfdcf649b3 Mon Sep 17 00:00:00 2001 From: Maurus Cuelenaere Date: Mon, 5 May 2008 15:47:26 +0000 Subject: Split up DMA and ATA, but don't enable it (yet). git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17386 a1c6a512-1295-4272-9138-f99709370657 --- .../arm/tms320dm320/creative-zvm/dma-creativezvm.c | 150 +++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 firmware/target/arm/tms320dm320/creative-zvm/dma-creativezvm.c (limited to 'firmware/target/arm/tms320dm320/creative-zvm/dma-creativezvm.c') diff --git a/firmware/target/arm/tms320dm320/creative-zvm/dma-creativezvm.c b/firmware/target/arm/tms320dm320/creative-zvm/dma-creativezvm.c new file mode 100644 index 0000000000..a714df84a8 --- /dev/null +++ b/firmware/target/arm/tms320dm320/creative-zvm/dma-creativezvm.c @@ -0,0 +1,150 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 by Maurus Cuelenaere + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "config.h" +#include "kernel.h" +#include "thread.h" +#include "system.h" +#include "dma-target.h" +#include "dm320.h" +#include "ata-target.h" +#include + +#define CS1_START 0x50000000 +#define CS2_START 0x60000000 +#define SDRAM_START 0x00900000 +#define FLASH_START 0x00100000 +#define CF_START 0x40000000 +#define SSFDC_START 0x48000000 + +static struct wakeup transfer_completion_signal; + +static bool dma_in_progress = false; + +static int debugi = 0; +static void debugj(char* mes) +{ + lcd_puts(0,debugi++,mes); + lcd_update(); +} + +void MTC0(void) +{ + IO_INTC_IRQ1 = INTR_IRQ1_MTC0; + wakeup_signal(&transfer_completion_signal); + dma_in_progress = false; +} + +void dma_start(const void* addr, size_t size) +{ + /* Compatibility with Gigabeat S in dma_start.c */ + (void) addr; + (void) size; +} + +#define ATA_DEST (ATA_IOBASE-CS1_START) +void dma_ata_read(unsigned char* buf, int shortcount) +{ + char mes[30]; + snprintf(mes, 30, "read(0x%x, %d)", buf, shortcount); + debugj(mes); + + if(dma_in_progress) + wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK); + + if((unsigned long)buf & 0x1F) + debugj(" aligning"); + while((unsigned long)buf & 0x1F) + { + unsigned short tmp; + tmp = ATA_DATA; + *buf++ = tmp & 0xFF; + *buf++ = tmp >> 8; + shortcount--; + } + + if (!shortcount) + return; + + IO_SDRAM_SDDMASEL = 0x0820; /* 32-byte burst mode transfer */ + IO_EMIF_DMAMTCSEL = 1; /* Select CS1 */ + IO_EMIF_AHBADDH = ((unsigned long)buf >> 16) & 0x7FFF; /* Set variable address */ + IO_EMIF_AHBADDL = (unsigned long)buf & 0xFFFF; + IO_EMIF_MTCADDH = ( (1 << 15) | (ATA_DEST >> 16) ); /* Set fixed address */ + IO_EMIF_MTCADDL = ATA_DEST & 0xFFFF; + IO_EMIF_DMASIZE = shortcount/2; /* 16-bits *2 = 1 word */ + IO_EMIF_DMACTL = 3; /* Select MTC->AHB and start transfer */ + + dma_in_progress = true; + wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK); + + int i; + for(i = 0; i < 30; i++) + { + if(*buf++ != 0) + mes[i] = *buf; + } + debugj(mes); + + if(shortcount % 2) + { + debugj(" aligning"); + unsigned short tmp; + tmp = ATA_DATA; + *buf++ = tmp & 0xFF; + *buf++ = tmp >> 8; + } +} + +void dma_ata_write(unsigned char* buf, int wordcount) +{ + if(dma_in_progress) + wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK); + + while((unsigned long)buf & 0x1F) + { + unsigned short tmp; + tmp = (unsigned short) *buf++; + tmp |= (unsigned short) *buf++ << 8; + SET_16BITREG(ATA_DATA, tmp); + wordcount--; + } + + if (!wordcount) + return; + + IO_SDRAM_SDDMASEL = 0x0830; /* 32-byte burst mode transfer */ + IO_EMIF_DMAMTCSEL = 1; /* Select CS1 */ + IO_EMIF_AHBADDH = ((unsigned long)buf >> 16) & ~(1 << 15); /* Set variable address */ + IO_EMIF_AHBADDL = (unsigned long)buf & 0xFFFF; + IO_EMIF_MTCADDH = ( (1 << 15) | (ATA_DEST >> 16) ); /* Set fixed address */ + IO_EMIF_MTCADDL = ATA_DEST & 0xFFFF; + IO_EMIF_DMASIZE = (wordcount+1)/2; + IO_EMIF_DMACTL = 1; /* Select AHB->MTC and start transfer */ + + dma_in_progress = true; + wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK); +} + +void dma_init(void) +{ + IO_INTC_EINT1 |= INTR_EINT1_MTC0; /* enable MTC interrupt */ + wakeup_init(&transfer_completion_signal); + dma_in_progress = false; +} -- cgit v1.2.3