summaryrefslogtreecommitdiff
path: root/firmware/export/pl080.h
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/export/pl080.h')
-rw-r--r--firmware/export/pl080.h269
1 files changed, 269 insertions, 0 deletions
diff --git a/firmware/export/pl080.h b/firmware/export/pl080.h
new file mode 100644
index 0000000000..9e48f07f0c
--- /dev/null
+++ b/firmware/export/pl080.h
@@ -0,0 +1,269 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2014 Cástor Muñoz
11 *
12 * 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.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef _PL080_H
22#define _PL080_H
23
24/*
25 * ARM PrimeCell PL080 Multiple Master DMA controller
26 */
27#include <stddef.h>
28#include <stdbool.h>
29
30/* general defines */
31#define DMAC_CH_COUNT 8
32#define DMAC_LLI_MAX_COUNT 0xfff
33#define DMAC_CH_PRIO(x) (x)
34#define DMAC_CH_BASE(dmac_ba,ch_n) ((dmac_ba) + 0x100 + ((ch_n) << 5))
35
36/* PL080 controller registers */
37#define DMACINTSTS(base) (*((uint32_t volatile*)((base) + 0x00)))
38#define DMACINTTCSTS(base) (*((uint32_t volatile*)((base) + 0x04)))
39#define DMACINTTCCLR(base) (*((uint32_t volatile*)((base) + 0x08)))
40#define DMACINTERRSTS(base) (*((uint32_t volatile*)((base) + 0x0c)))
41#define DMACINTERRCLR(base) (*((uint32_t volatile*)((base) + 0x10)))
42#define DMACRAWINTTCSTS(base) (*((uint32_t volatile*)((base) + 0x14)))
43#define DMACRAWINTERRSTS(base) (*((uint32_t volatile*)((base) + 0x18)))
44#define DMACENABLEDCHANS(base) (*((uint32_t volatile*)((base) + 0x1c)))
45#define DMACSOFTBREQ(base) (*((uint32_t volatile*)((base) + 0x20)))
46#define DMACSOFTSREQ(base) (*((uint32_t volatile*)((base) + 0x24)))
47#define DMACSOFTLBREQ(base) (*((uint32_t volatile*)((base) + 0x28)))
48#define DMACSOFTLSREQ(base) (*((uint32_t volatile*)((base) + 0x2c)))
49#define DMACCONFIG(base) (*((uint32_t volatile*)((base) + 0x30)))
50#define DMACSYNC(base) (*((uint32_t volatile*)((base) + 0x34)))
51
52/* PL080 controller channel registers */
53#define DMACCxSRCADDR(base) (*((void* volatile*)((base) + 0x00)))
54#define DMACCxDESTADDR(base) (*((void* volatile*)((base) + 0x04)))
55#define DMACCxLINK(base) (*((uint32_t volatile*)((base) + 0x08)))
56#define DMACCxCONTROL(base) (*((uint32_t volatile*)((base) + 0x0c)))
57#define DMACCxCONFIG(base) (*((uint32_t volatile*)((base) + 0x10)))
58
59/* PL080 controller channel LLI */
60#define DMACCxLLI(base) ((struct dmac_lli volatile*)(base))
61
62/* PL080 DMA controller configuration register */
63#define DMACCONFIG_E_POS 0 /* DMAC enable */
64#define DMACCONFIG_E_MSK 0x1
65#define DMACCONFIG_M1_POS 1 /* AHB Master 1 endianness */
66#define DMACCONFIG_M1_MSK 0x1
67#define DMACCONFIG_M2_POS 2 /* AHB Master 2 endianness */
68#define DMACCONFIG_M2_MSK 0x1
69
70#define DMACCONFIG_E_BIT (1 << DMACCONFIG_E_POS)
71#define DMACCONFIG_M1_BIT (1 << DMACCCONFI_M1_POS)
72#define DMACCONFIG_M2_BIT (1 << DMACCCONFI_M2_POS)
73
74#define DMACCONFIG_M_LITTLE_ENDIAN 0
75#define DMACCONFIG_M_BIG_ENDIAN 1
76
77/* PL080 DMA controller channel LLI register */
78#define DMACCxLINK_LM_POS 0
79#define DMACCxLINK_LM_MSK 0x1
80#define DMACCxLINK_NEXTLLI_POS 2
81#define DMACCxLINK_NEXTLLI_MSK 0x3fffffff
82
83/* PL080 channel control register */
84#define DMACCxCONTROL_I_POS 31 /* terminal count interrupt */
85#define DMACCxCONTROL_I_MSK 0x1
86#define DMACCxCONTROL_PROT_POS 28 /* protection bits */
87#define DMACCxCONTROL_PROT_MSK 0x7
88#define DMACCxCONTROL_DI_POS 27 /* destination addr increment */
89#define DMACCxCONTROL_DI_MSK 0x1
90#define DMACCxCONTROL_SI_POS 26 /* source addr increment */
91#define DMACCxCONTROL_SI_MSK 0x1
92#define DMACCxCONTROL_D_POS 25 /* destinantion AHB master */
93#define DMACCxCONTROL_D_MSK 0x1
94#define DMACCxCONTROL_S_POS 24 /* source AHB master */
95#define DMACCxCONTROL_S_MSK 0x1
96#define DMACCxCONTROL_DWIDTH_POS 21 /* destinantion transfer width */
97#define DMACCxCONTROL_DWIDTH_MSK 0x7
98#define DMACCxCONTROL_SWIDTH_POS 18 /* source transfer width */
99#define DMACCxCONTROL_SWIDTH_MSK 0x7
100#define DMACCxCONTROL_DBSIZE_POS 15 /* destinantion burst size */
101#define DMACCxCONTROL_DBSIZE_MSK 0x7
102#define DMACCxCONTROL_SBSIZE_POS 12 /* source burst size */
103#define DMACCxCONTROL_SBSIZE_MSK 0x7
104#define DMACCxCONTROL_COUNT_POS 0 /* n SWIDTH size transfers */
105#define DMACCxCONTROL_COUNT_MSK 0xfff
106
107#define DMACCxCONTROL_WIDTH_8 0
108#define DMACCxCONTROL_WIDTH_16 1
109#define DMACCxCONTROL_WIDTH_32 2
110
111#define DMACCxCONTROL_BSIZE_1 0
112#define DMACCxCONTROL_BSIZE_4 1
113#define DMACCxCONTROL_BSIZE_8 2
114#define DMACCxCONTROL_BSIZE_16 3
115#define DMACCxCONTROL_BSIZE_32 4
116#define DMACCxCONTROL_BSIZE_64 5
117#define DMACCxCONTROL_BSIZE_128 6
118#define DMACCxCONTROL_BSIZE_256 7
119
120#define DMACCxCONTROL_INC_DISABLE 0
121#define DMACCxCONTROL_INC_ENABLE 1
122
123#define DMACCxCONTROL_I_BIT (1 << DMACCxCONTROL_I_POS)
124
125/* protection bits */
126#define DMAC_PROT_PRIV (1 << 0)
127#define DMAC_PROT_BUFF (1 << 1)
128#define DMAC_PROT_CACH (1 << 2)
129
130/* bus */
131#define DMAC_MASTER_AHB1 0
132#define DMAC_MASTER_AHB2 1
133
134/* PL080 channel configuration register */
135#define DMACCxCONFIG_E_POS 0 /* enable */
136#define DMACCxCONFIG_E_MSK 0x1
137#define DMACCxCONFIG_SRCPERI_POS 1 /* source peripheral */
138#define DMACCxCONFIG_SRCPERI_MSK 0xf
139#define DMACCxCONFIG_DESTPERI_POS 6 /* destination peripheral */
140#define DMACCxCONFIG_DESTPERI_MSK 0xf
141#define DMACCxCONFIG_FLOWCNTRL_POS 11 /* DMA transfer type */
142#define DMACCxCONFIG_FLOWCNTRL_MSK 0x7
143#define DMACCxCONFIG_IE_POS 14 /* interrupt error mask */
144#define DMACCxCONFIG_IE_MSK 0x1
145#define DMACCxCONFIG_ITC_POS 15 /* interrupt terminal count mask */
146#define DMACCxCONFIG_ITC_MSK 0x1
147#define DMACCxCONFIG_L_POS 16 /* lock */
148#define DMACCxCONFIG_L_MSK 0x1
149#define DMACCxCONFIG_A_POS 17 /* active */
150#define DMACCxCONFIG_A_MSK 0x1
151#define DMACCxCONFIG_H_POS 18 /* halt */
152#define DMACCxCONFIG_H_MSK 0x1
153
154#define DMACCxCONFIG_E_BIT (1 << DMACCxCONFIG_E_POS)
155#define DMACCxCONFIG_IE_BIT (1 << DMACCxCONFIG_IE_POS)
156#define DMACCxCONFIG_ITC_BIT (1 << DMACCxCONFIG_ITC_POS)
157#define DMACCxCONFIG_L_BIT (1 << DMACCxCONFIG_L_POS)
158#define DMACCxCONFIG_A_BIT (1 << DMACCxCONFIG_A_POS)
159#define DMACCxCONFIG_H_BIT (1 << DMACCxCONFIG_H_POS)
160
161#define DMACCxCONFIG_FLOWCNTRL_MEMMEM_DMA 0
162#define DMACCxCONFIG_FLOWCNTRL_MEMPERI_DMA 1
163#define DMACCxCONFIG_FLOWCNTRL_PERIMEM_DMA 2
164#define DMACCxCONFIG_FLOWCNTRL_PERIPERI_DMA 3
165#define DMACCxCONFIG_FLOWCNTRL_PERIPERI_DSTPERI 4
166#define DMACCxCONFIG_FLOWCNTRL_MEMPERI_PERI 5
167#define DMACCxCONFIG_FLOWCNTRL_PERIMEM_PERI 6
168#define DMACCxCONFIG_FLOWCNTRL_PERIPERI_SRCPERI 7
169
170/*
171 * types
172 */
173struct dmac_lli {
174 void* srcaddr;
175 void* dstaddr;
176 uint32_t link;
177 uint32_t control;
178} __attribute__((aligned(16)));
179
180struct dmac_tsk {
181 struct dmac_lli volatile *start_lli;
182 struct dmac_lli volatile *end_lli;
183 uint32_t size;
184 void *cb_data;
185};
186
187/* used when src/dst peri is memory */
188#define DMAC_PERI_NONE 0x80
189
190struct dmac_ch_cfg {
191 uint8_t srcperi;
192 uint8_t dstperi;
193 uint8_t sbsize;
194 uint8_t dbsize;
195 uint8_t swidth;
196 uint8_t dwidth;
197 uint8_t sbus;
198 uint8_t dbus;
199 uint8_t sinc;
200 uint8_t dinc;
201 uint8_t prot;
202 uint16_t lli_xfer_max_count;
203};
204
205struct dmac_ch {
206 /** user configurable data **/
207 struct dmac *dmac;
208 unsigned int prio;
209 void (*cb_fn)(void *cb_data);
210 /* tsk circular buffer */
211 struct dmac_tsk *tskbuf;
212 uint32_t tskbuf_mask;
213 uint32_t queue_mode;
214 /* lli circular buffer */
215 struct dmac_lli volatile *llibuf;
216 uint32_t llibuf_mask;
217 uint32_t llibuf_bus;
218
219 /** private driver data **/
220 uint32_t baddr;
221 struct dmac_lli volatile *llibuf_top;
222 uint32_t tasks_queued; /* roll-over counter */
223 uint32_t tasks_done; /* roll-over counter */
224 uint32_t control;
225 struct dmac_ch_cfg *cfg;
226};
227
228struct dmac {
229 /* user configurable data */
230 const uint32_t baddr;
231 const uint8_t m1;
232 const uint8_t m2;
233
234 /* driver private data */
235 struct dmac_ch *ch_l[DMAC_CH_COUNT];
236 uint32_t ch_run_status; /* channel running status mask */
237};
238
239/* dmac_ch->queue_mode */
240enum {
241 QUEUE_NORMAL,
242 QUEUE_LINK,
243};
244
245/*
246 * prototypes
247 */
248void dmac_callback(struct dmac *dmac);
249
250void dmac_open(struct dmac *dmac);
251
252void dmac_ch_init(struct dmac_ch *ch, struct dmac_ch_cfg *cfg);
253
254void dmac_ch_lock_int(struct dmac_ch *ch);
255void dmac_ch_unlock_int(struct dmac_ch *ch);
256
257void dmac_ch_queue_2d(struct dmac_ch *ch, void *srcaddr, void *dstaddr,
258 size_t size, size_t width, size_t stride, void *cb_data);
259#define dmac_ch_queue(ch, srcaddr, dstaddr, size, cb_data) \
260 dmac_ch_queue_2d(ch, srcaddr, dstaddr, size, 0, 0, cb_data)
261
262void dmac_ch_stop(struct dmac_ch* ch);
263
264bool dmac_ch_running(struct dmac_ch *ch);
265
266void *dmac_ch_get_info(struct dmac_ch *ch,
267 size_t *bytes, size_t *t_bytes);
268
269#endif /* _PL080_H */