summaryrefslogtreecommitdiff
path: root/firmware/target/arm/tms320dm320/creative-zvm/dma-creativezvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/tms320dm320/creative-zvm/dma-creativezvm.c')
-rw-r--r--firmware/target/arm/tms320dm320/creative-zvm/dma-creativezvm.c150
1 files changed, 150 insertions, 0 deletions
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2008 by Maurus Cuelenaere
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "config.h"
21#include "kernel.h"
22#include "thread.h"
23#include "system.h"
24#include "dma-target.h"
25#include "dm320.h"
26#include "ata-target.h"
27#include <stdbool.h>
28
29#define CS1_START 0x50000000
30#define CS2_START 0x60000000
31#define SDRAM_START 0x00900000
32#define FLASH_START 0x00100000
33#define CF_START 0x40000000
34#define SSFDC_START 0x48000000
35
36static struct wakeup transfer_completion_signal;
37
38static bool dma_in_progress = false;
39
40static int debugi = 0;
41static void debugj(char* mes)
42{
43 lcd_puts(0,debugi++,mes);
44 lcd_update();
45}
46
47void MTC0(void)
48{
49 IO_INTC_IRQ1 = INTR_IRQ1_MTC0;
50 wakeup_signal(&transfer_completion_signal);
51 dma_in_progress = false;
52}
53
54void dma_start(const void* addr, size_t size)
55{
56 /* Compatibility with Gigabeat S in dma_start.c */
57 (void) addr;
58 (void) size;
59}
60
61#define ATA_DEST (ATA_IOBASE-CS1_START)
62void dma_ata_read(unsigned char* buf, int shortcount)
63{
64 char mes[30];
65 snprintf(mes, 30, "read(0x%x, %d)", buf, shortcount);
66 debugj(mes);
67
68 if(dma_in_progress)
69 wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
70
71 if((unsigned long)buf & 0x1F)
72 debugj(" aligning");
73 while((unsigned long)buf & 0x1F)
74 {
75 unsigned short tmp;
76 tmp = ATA_DATA;
77 *buf++ = tmp & 0xFF;
78 *buf++ = tmp >> 8;
79 shortcount--;
80 }
81
82 if (!shortcount)
83 return;
84
85 IO_SDRAM_SDDMASEL = 0x0820; /* 32-byte burst mode transfer */
86 IO_EMIF_DMAMTCSEL = 1; /* Select CS1 */
87 IO_EMIF_AHBADDH = ((unsigned long)buf >> 16) & 0x7FFF; /* Set variable address */
88 IO_EMIF_AHBADDL = (unsigned long)buf & 0xFFFF;
89 IO_EMIF_MTCADDH = ( (1 << 15) | (ATA_DEST >> 16) ); /* Set fixed address */
90 IO_EMIF_MTCADDL = ATA_DEST & 0xFFFF;
91 IO_EMIF_DMASIZE = shortcount/2; /* 16-bits *2 = 1 word */
92 IO_EMIF_DMACTL = 3; /* Select MTC->AHB and start transfer */
93
94 dma_in_progress = true;
95 wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
96
97 int i;
98 for(i = 0; i < 30; i++)
99 {
100 if(*buf++ != 0)
101 mes[i] = *buf;
102 }
103 debugj(mes);
104
105 if(shortcount % 2)
106 {
107 debugj(" aligning");
108 unsigned short tmp;
109 tmp = ATA_DATA;
110 *buf++ = tmp & 0xFF;
111 *buf++ = tmp >> 8;
112 }
113}
114
115void dma_ata_write(unsigned char* buf, int wordcount)
116{
117 if(dma_in_progress)
118 wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
119
120 while((unsigned long)buf & 0x1F)
121 {
122 unsigned short tmp;
123 tmp = (unsigned short) *buf++;
124 tmp |= (unsigned short) *buf++ << 8;
125 SET_16BITREG(ATA_DATA, tmp);
126 wordcount--;
127 }
128
129 if (!wordcount)
130 return;
131
132 IO_SDRAM_SDDMASEL = 0x0830; /* 32-byte burst mode transfer */
133 IO_EMIF_DMAMTCSEL = 1; /* Select CS1 */
134 IO_EMIF_AHBADDH = ((unsigned long)buf >> 16) & ~(1 << 15); /* Set variable address */
135 IO_EMIF_AHBADDL = (unsigned long)buf & 0xFFFF;
136 IO_EMIF_MTCADDH = ( (1 << 15) | (ATA_DEST >> 16) ); /* Set fixed address */
137 IO_EMIF_MTCADDL = ATA_DEST & 0xFFFF;
138 IO_EMIF_DMASIZE = (wordcount+1)/2;
139 IO_EMIF_DMACTL = 1; /* Select AHB->MTC and start transfer */
140
141 dma_in_progress = true;
142 wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
143}
144
145void dma_init(void)
146{
147 IO_INTC_EINT1 |= INTR_EINT1_MTC0; /* enable MTC interrupt */
148 wakeup_init(&transfer_completion_signal);
149 dma_in_progress = false;
150}