blob: 201dd1b24c1f7a545a00924abae972f60f2f191b [file] [log] [blame]
Maurus Cuelenaeree025cb12008-05-05 15:47:26 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2008 by Maurus Cuelenaere
11 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
Maurus Cuelenaeree025cb12008-05-05 15:47:26 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "config.h"
23#include "kernel.h"
24#include "thread.h"
25#include "system.h"
26#include "dma-target.h"
27#include "dm320.h"
28#include "ata-target.h"
29#include <stdbool.h>
30
31#define CS1_START 0x50000000
32#define CS2_START 0x60000000
33#define SDRAM_START 0x00900000
34#define FLASH_START 0x00100000
35#define CF_START 0x40000000
36#define SSFDC_START 0x48000000
37
38static struct wakeup transfer_completion_signal;
39
40static bool dma_in_progress = false;
41
Maurus Cuelenaeree025cb12008-05-05 15:47:26 +000042void MTC0(void)
43{
44 IO_INTC_IRQ1 = INTR_IRQ1_MTC0;
45 wakeup_signal(&transfer_completion_signal);
46 dma_in_progress = false;
47}
48
49void dma_start(const void* addr, size_t size)
50{
51 /* Compatibility with Gigabeat S in dma_start.c */
52 (void) addr;
53 (void) size;
54}
55
56#define ATA_DEST (ATA_IOBASE-CS1_START)
57void dma_ata_read(unsigned char* buf, int shortcount)
Maurus Cuelenaerefd0eed92008-05-05 15:50:17 +000058{
Maurus Cuelenaeree025cb12008-05-05 15:47:26 +000059 if(dma_in_progress)
60 wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
61
Maurus Cuelenaeree025cb12008-05-05 15:47:26 +000062 while((unsigned long)buf & 0x1F)
63 {
64 unsigned short tmp;
65 tmp = ATA_DATA;
66 *buf++ = tmp & 0xFF;
67 *buf++ = tmp >> 8;
68 shortcount--;
69 }
70
71 if (!shortcount)
72 return;
73
74 IO_SDRAM_SDDMASEL = 0x0820; /* 32-byte burst mode transfer */
75 IO_EMIF_DMAMTCSEL = 1; /* Select CS1 */
76 IO_EMIF_AHBADDH = ((unsigned long)buf >> 16) & 0x7FFF; /* Set variable address */
77 IO_EMIF_AHBADDL = (unsigned long)buf & 0xFFFF;
78 IO_EMIF_MTCADDH = ( (1 << 15) | (ATA_DEST >> 16) ); /* Set fixed address */
79 IO_EMIF_MTCADDL = ATA_DEST & 0xFFFF;
80 IO_EMIF_DMASIZE = shortcount/2; /* 16-bits *2 = 1 word */
81 IO_EMIF_DMACTL = 3; /* Select MTC->AHB and start transfer */
82
83 dma_in_progress = true;
84 wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
85
Maurus Cuelenaeree025cb12008-05-05 15:47:26 +000086 if(shortcount % 2)
87 {
Maurus Cuelenaeree025cb12008-05-05 15:47:26 +000088 unsigned short tmp;
89 tmp = ATA_DATA;
90 *buf++ = tmp & 0xFF;
91 *buf++ = tmp >> 8;
92 }
93}
94
95void dma_ata_write(unsigned char* buf, int wordcount)
96{
97 if(dma_in_progress)
98 wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
99
100 while((unsigned long)buf & 0x1F)
101 {
102 unsigned short tmp;
103 tmp = (unsigned short) *buf++;
104 tmp |= (unsigned short) *buf++ << 8;
105 SET_16BITREG(ATA_DATA, tmp);
106 wordcount--;
107 }
108
109 if (!wordcount)
110 return;
111
112 IO_SDRAM_SDDMASEL = 0x0830; /* 32-byte burst mode transfer */
113 IO_EMIF_DMAMTCSEL = 1; /* Select CS1 */
114 IO_EMIF_AHBADDH = ((unsigned long)buf >> 16) & ~(1 << 15); /* Set variable address */
115 IO_EMIF_AHBADDL = (unsigned long)buf & 0xFFFF;
116 IO_EMIF_MTCADDH = ( (1 << 15) | (ATA_DEST >> 16) ); /* Set fixed address */
117 IO_EMIF_MTCADDL = ATA_DEST & 0xFFFF;
118 IO_EMIF_DMASIZE = (wordcount+1)/2;
119 IO_EMIF_DMACTL = 1; /* Select AHB->MTC and start transfer */
120
121 dma_in_progress = true;
122 wakeup_wait(&transfer_completion_signal, TIMEOUT_BLOCK);
123}
124
125void dma_init(void)
126{
127 IO_INTC_EINT1 |= INTR_EINT1_MTC0; /* enable MTC interrupt */
128 wakeup_init(&transfer_completion_signal);
129 dma_in_progress = false;
130}