Tue Apr 14 18:37:43 2015 UTC ()
Add a driver for the Enhanced Direct Memory Access controller found
in the AM335x SoC. Written by Jared D. McNeill, with some final debug
by me.
Supports only DMA (not QDMA) yet, and there's no support for DMA event
matrix yet (this means that only primary DMA events can be used)


(bouyer)
diff -r1.29 -r1.30 src/sys/arch/arm/omap/files.omap2
diff -r1.21 -r1.22 src/sys/arch/arm/omap/omap2_obio.c
diff -r1.2 -r1.3 src/sys/arch/arm/omap/omap2_obiovar.h
diff -r1.28 -r1.29 src/sys/arch/arm/omap/omap2_reg.h
diff -r0 -r1.1 src/sys/arch/arm/omap/omap_edma.c
diff -r0 -r1.1 src/sys/arch/arm/omap/omap_edma.c.orig
diff -r0 -r1.1 src/sys/arch/arm/omap/omap_edma.h
diff -r0 -r1.1 src/sys/arch/arm/omap/omap_edma.h.orig

cvs diff -r1.29 -r1.30 src/sys/arch/arm/omap/Attic/files.omap2 (expand / switch to unified diff)

--- src/sys/arch/arm/omap/Attic/files.omap2 2014/08/22 19:44:04 1.29
+++ src/sys/arch/arm/omap/Attic/files.omap2 2015/04/14 18:37:43 1.30
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1# $NetBSD: files.omap2,v 1.29 2014/08/22 19:44:04 jakllsch Exp $ 1# $NetBSD: files.omap2,v 1.30 2015/04/14 18:37:43 bouyer Exp $
2# 2#
3# Configuration info for Texas Instruments OMAP2/OMAP3 CPU support 3# Configuration info for Texas Instruments OMAP2/OMAP3 CPU support
4# Based on xscale/files.pxa2x0 4# Based on xscale/files.pxa2x0
5# 5#
6 6
7include "arch/arm/pic/files.pic" 7include "arch/arm/pic/files.pic"
8include "arch/arm/cortex/files.cortex" 8include "arch/arm/cortex/files.cortex"
9 9
10file arch/arm/arm32/irq_dispatch.S 10file arch/arm/arm32/irq_dispatch.S
11file arch/arm/omap/omap_dma.c 11file arch/arm/omap/omap_dma.c
12 12
13# Memory size in megabytes 13# Memory size in megabytes
14defparam opt_omap.h MEMSIZE 14defparam opt_omap.h MEMSIZE
@@ -22,27 +22,27 @@ defflag opt_omap.h OMAP_2430: OMAP_2X @@ -22,27 +22,27 @@ defflag opt_omap.h OMAP_2430: OMAP_2X
22defflag opt_omap.h OMAP_2420: OMAP_2XXX 22defflag opt_omap.h OMAP_2420: OMAP_2XXX
23defflag opt_omap.h OMAP_3XXX: OMAP3 23defflag opt_omap.h OMAP_3XXX: OMAP3
24defflag opt_omap.h OMAP_3430: OMAP_3XXX 24defflag opt_omap.h OMAP_3430: OMAP_3XXX
25defflag opt_omap.h OMAP_3530: OMAP_3XXX 25defflag opt_omap.h OMAP_3530: OMAP_3XXX
26defflag opt_omap.h OMAP_4XXX: OMAP4 26defflag opt_omap.h OMAP_4XXX: OMAP4
27defflag opt_omap.h OMAP_4430: OMAP_4XXX 27defflag opt_omap.h OMAP_4430: OMAP_4XXX
28defflag opt_omap.h OMAP_4460: OMAP_4XXX 28defflag opt_omap.h OMAP_4460: OMAP_4XXX
29defflag opt_omap.h OMAP_5XXX: OMAP5 29defflag opt_omap.h OMAP_5XXX: OMAP5
30defflag opt_omap.h OMAP_5430: OMAP_5XXX 30defflag opt_omap.h OMAP_5430: OMAP_5XXX
31defflag opt_omap.h TI_AM335X: OMAP3 31defflag opt_omap.h TI_AM335X: OMAP3
32defflag opt_omap.h TI_DM37XX: OMAP3 32defflag opt_omap.h TI_DM37XX: OMAP3
33 33
34# OBIO just an attach point 34# OBIO just an attach point
35device obio { [addr=-1], [size=0], [intr=-1], [mult=1], [intrbase=-1], [nobyteacc=0] 35device obio { [addr=-1], [size=0], [intr=-1], [mult=1], [intrbase=-1], [nobyteacc=0], [edmabase=-1]
36 } : bus_space_generic 36 } : bus_space_generic
37attach obio at mainbus 37attach obio at mainbus
38file arch/arm/omap/omap2_obio.c obio needs-count 38file arch/arm/omap/omap2_obio.c obio needs-count
39 39
40# OBIO files 40# OBIO files
41file arch/arm/omap/omap_space.c obio 41file arch/arm/omap/omap_space.c obio
42file arch/arm/omap/omap_a2x_space.c obio 42file arch/arm/omap/omap_a2x_space.c obio
43file arch/arm/arm/bus_space_a2x.S obio 43file arch/arm/arm/bus_space_a2x.S obio
44file arch/arm/omap/omap_a4x_space.c obio 44file arch/arm/omap/omap_a4x_space.c obio
45file arch/arm/arm/bus_space_a4x.S obio 45file arch/arm/arm/bus_space_a4x.S obio
46 46
47# TI Sitara control module 47# TI Sitara control module
48device sitaracm 48device sitaracm
@@ -160,17 +160,21 @@ file arch/arm/omap/omapfb.c omapfb @@ -160,17 +160,21 @@ file arch/arm/omap/omapfb.c omapfb
160# TI AM335x framebuffer 160# TI AM335x framebuffer
161device tifb: rasops32, rasops24, rasops16, rasops8, wsemuldisplaydev, vcons, edid 161device tifb: rasops32, rasops24, rasops16, rasops8, wsemuldisplaydev, vcons, edid
162attach tifb at obio 162attach tifb at obio
163file arch/arm/omap/tifb.c tifb 163file arch/arm/omap/tifb.c tifb
164 164
165device cpsw: ether, ifnet, arp, mii, mii_phy 165device cpsw: ether, ifnet, arp, mii, mii_phy
166attach cpsw at obio 166attach cpsw at obio
167file arch/arm/omap/if_cpsw.c cpsw 167file arch/arm/omap/if_cpsw.c cpsw
168 168
169device omapdma 169device omapdma
170attach omapdma at obio 170attach omapdma at obio
171file arch/arm/omap/omap3_sdma.c omapdma needs-flag 171file arch/arm/omap/omap3_sdma.c omapdma needs-flag
172 172
 173device edma
 174attach edma at obio
 175file arch/arm/omap/omap_edma.c edma needs-flag
 176
173# these bus space methods are not bus-specific ... 177# these bus space methods are not bus-specific ...
174# 178#
175file arch/arm/omap/omap_nobyteacc_space.c emifs | gpmc 179file arch/arm/omap/omap_nobyteacc_space.c emifs | gpmc
176file arch/arm/omap/omap_nobyteacc_io.S emifs | gpmc 180file arch/arm/omap/omap_nobyteacc_io.S emifs | gpmc

cvs diff -r1.21 -r1.22 src/sys/arch/arm/omap/Attic/omap2_obio.c (expand / switch to unified diff)

--- src/sys/arch/arm/omap/Attic/omap2_obio.c 2013/06/15 21:58:20 1.21
+++ src/sys/arch/arm/omap/Attic/omap2_obio.c 2015/04/14 18:37:43 1.22
@@ -1,17 +1,17 @@ @@ -1,17 +1,17 @@
1/* $Id: omap2_obio.c,v 1.21 2013/06/15 21:58:20 matt Exp $ */ 1/* $Id: omap2_obio.c,v 1.22 2015/04/14 18:37:43 bouyer Exp $ */
2 2
3/* adapted from: */ 3/* adapted from: */
4/* $NetBSD: omap2_obio.c,v 1.21 2013/06/15 21:58:20 matt Exp $ */ 4/* $NetBSD: omap2_obio.c,v 1.22 2015/04/14 18:37:43 bouyer Exp $ */
5 5
6 6
7/* 7/*
8 * Autoconfiguration support for the Texas Instruments OMAP "On Board" I/O. 8 * Autoconfiguration support for the Texas Instruments OMAP "On Board" I/O.
9 * 9 *
10 * Based on arm/omap/omap_emifs.c which in turn was derived 10 * Based on arm/omap/omap_emifs.c which in turn was derived
11 * Based on arm/xscale/pxa2x0.c which in turn was derived 11 * Based on arm/xscale/pxa2x0.c which in turn was derived
12 * from arm/sa11x0/sa11x0.c 12 * from arm/sa11x0/sa11x0.c
13 * 13 *
14 * Copyright (c) 2002, 2005 Genetec Corporation. All rights reserved. 14 * Copyright (c) 2002, 2005 Genetec Corporation. All rights reserved.
15 * Written by Hiroyuki Bessho for Genetec Corporation. 15 * Written by Hiroyuki Bessho for Genetec Corporation.
16 * 16 *
17 * Redistribution and use in source and binary forms, with or without 17 * Redistribution and use in source and binary forms, with or without
@@ -93,27 +93,27 @@ @@ -93,27 +93,27 @@
93 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 93 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
94 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 94 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
95 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 95 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
96 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 96 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
97 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 97 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
98 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 98 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
99 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 99 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
100 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 100 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
101 * SUCH DAMAGE. 101 * SUCH DAMAGE.
102 */ 102 */
103 103
104#include "opt_omap.h" 104#include "opt_omap.h"
105#include <sys/cdefs.h> 105#include <sys/cdefs.h>
106__KERNEL_RCSID(0, "$NetBSD: omap2_obio.c,v 1.21 2013/06/15 21:58:20 matt Exp $"); 106__KERNEL_RCSID(0, "$NetBSD: omap2_obio.c,v 1.22 2015/04/14 18:37:43 bouyer Exp $");
107 107
108#include "locators.h" 108#include "locators.h"
109#include "obio.h" 109#include "obio.h"
110 110
111#include <sys/param.h> 111#include <sys/param.h>
112#include <sys/systm.h> 112#include <sys/systm.h>
113#include <sys/device.h> 113#include <sys/device.h>
114#include <sys/kernel.h> 114#include <sys/kernel.h>
115#include <sys/reboot.h> 115#include <sys/reboot.h>
116 116
117#include <machine/cpu.h> 117#include <machine/cpu.h>
118#include <sys/bus.h> 118#include <sys/bus.h>
119 119
@@ -274,26 +274,27 @@ obio_search(device_t parent, cfdata_t cf @@ -274,26 +274,27 @@ obio_search(device_t parent, cfdata_t cf
274 oa.obio_iot = &omap_a4x_bs_tag; 274 oa.obio_iot = &omap_a4x_bs_tag;
275 break; 275 break;
276 default: 276 default:
277 panic("Unsupported EMIFS multiplier."); 277 panic("Unsupported EMIFS multiplier.");
278 break; 278 break;
279 } 279 }
280 } 280 }
281 281
282 oa.obio_dmat = sc->sc_dmat; 282 oa.obio_dmat = sc->sc_dmat;
283 oa.obio_addr = cf->cf_loc[OBIOCF_ADDR]; 283 oa.obio_addr = cf->cf_loc[OBIOCF_ADDR];
284 oa.obio_size = cf->cf_loc[OBIOCF_SIZE]; 284 oa.obio_size = cf->cf_loc[OBIOCF_SIZE];
285 oa.obio_intr = cf->cf_loc[OBIOCF_INTR]; 285 oa.obio_intr = cf->cf_loc[OBIOCF_INTR];
286 oa.obio_intrbase = cf->cf_loc[OBIOCF_INTRBASE]; 286 oa.obio_intrbase = cf->cf_loc[OBIOCF_INTRBASE];
 287 oa.obio_edmabase = cf->cf_loc[OBIOCF_EDMABASE];
287 288
288#if defined(OMAP2) 289#if defined(OMAP2)
289 if ((oa.obio_addr >= sc->sc_base) 290 if ((oa.obio_addr >= sc->sc_base)
290 && (oa.obio_addr < (sc->sc_base + sc->sc_size))) { 291 && (oa.obio_addr < (sc->sc_base + sc->sc_size))) {
291 /* XXX 292 /* XXX
292 * if size was specified, then check it too 293 * if size was specified, then check it too
293 * otherwise just assume it is OK 294 * otherwise just assume it is OK
294 */ 295 */
295 if ((oa.obio_size != OBIOCF_SIZE_DEFAULT) 296 if ((oa.obio_size != OBIOCF_SIZE_DEFAULT)
296 && ((oa.obio_addr + oa.obio_size) 297 && ((oa.obio_addr + oa.obio_size)
297 >= (sc->sc_base + sc->sc_size))) 298 >= (sc->sc_base + sc->sc_size)))
298 return 1; /* NG */ 299 return 1; /* NG */
299 if (config_match(parent, cf, &oa)) { 300 if (config_match(parent, cf, &oa)) {
@@ -341,26 +342,27 @@ obio_find(device_t parent, cfdata_t cf,  @@ -341,26 +342,27 @@ obio_find(device_t parent, cfdata_t cf,
341 break; 342 break;
342 case 4: 343 case 4:
343 oa->obio_iot = &omap_a4x_bs_tag; 344 oa->obio_iot = &omap_a4x_bs_tag;
344 break; 345 break;
345 default: 346 default:
346 panic("Unsupported EMIFS multiplier."); 347 panic("Unsupported EMIFS multiplier.");
347 break; 348 break;
348 } 349 }
349 } 350 }
350 oa->obio_addr = cf->cf_loc[OBIOCF_ADDR]; 351 oa->obio_addr = cf->cf_loc[OBIOCF_ADDR];
351 oa->obio_size = cf->cf_loc[OBIOCF_SIZE]; 352 oa->obio_size = cf->cf_loc[OBIOCF_SIZE];
352 oa->obio_intr = cf->cf_loc[OBIOCF_INTR]; 353 oa->obio_intr = cf->cf_loc[OBIOCF_INTR];
353 oa->obio_intrbase = cf->cf_loc[OBIOCF_INTRBASE]; 354 oa->obio_intrbase = cf->cf_loc[OBIOCF_INTRBASE];
 355 oa->obio_edmabase = cf->cf_loc[OBIOCF_EDMABASE];
354 356
355 return config_match(parent, cf, oa); 357 return config_match(parent, cf, oa);
356} 358}
357 359
358#if 0 && NOMAP2ICU == 0 360#if 0 && NOMAP2ICU == 0
359#error no avic present in config file 361#error no avic present in config file
360#endif 362#endif
361 363
362static const struct { 364static const struct {
363 const char *name; 365 const char *name;
364 bus_addr_t addr; 366 bus_addr_t addr;
365 bool required; 367 bool required;
366} critical_devs[] = { 368} critical_devs[] = {
@@ -388,26 +390,27 @@ static const struct { @@ -388,26 +390,27 @@ static const struct {
388#if defined(GPIO7_BASE) 390#if defined(GPIO7_BASE)
389 { .name = "gpio7", .addr = GPIO7_BASE, .required = false }, 391 { .name = "gpio7", .addr = GPIO7_BASE, .required = false },
390#endif 392#endif
391#if defined(GPIO8_BASE) 393#if defined(GPIO8_BASE)
392 { .name = "gpio8", .addr = GPIO8_BASE, .required = false }, 394 { .name = "gpio8", .addr = GPIO8_BASE, .required = false },
393#endif 395#endif
394#if 0 396#if 0
395 { .name = "dmac", .addr = DMAC_BASE, .required = true }, 397 { .name = "dmac", .addr = DMAC_BASE, .required = true },
396#endif 398#endif
397#if defined(TI_AM335X) 399#if defined(TI_AM335X)
398 { .name = "omapicu", .addr = 0x48200000, .required = true }, 400 { .name = "omapicu", .addr = 0x48200000, .required = true },
399 { .name = "prcm", .addr = 0x44e00000, .required = true }, 401 { .name = "prcm", .addr = 0x44e00000, .required = true },
400 { .name = "sitaracm", .addr = 0x44e10000, .required = true }, 402 { .name = "sitaracm", .addr = 0x44e10000, .required = true },
 403 { .name = "edma", .addr = 0x49000000, .required = false },
401#endif 404#endif
402#if defined(OMAP_3530) 405#if defined(OMAP_3530)
403 { .name = "omapdma", .addr = OMAP3530_SDMA_BASE, .required = true }, 406 { .name = "omapdma", .addr = OMAP3530_SDMA_BASE, .required = true },
404#endif 407#endif
405}; 408};
406 409
407static void 410static void
408obio_attach_critical(struct obio_softc *sc) 411obio_attach_critical(struct obio_softc *sc)
409{ 412{
410 struct obio_attach_args oa; 413 struct obio_attach_args oa;
411 cfdata_t cf; 414 cfdata_t cf;
412 size_t i; 415 size_t i;
413 416

cvs diff -r1.2 -r1.3 src/sys/arch/arm/omap/Attic/omap2_obiovar.h (expand / switch to unified diff)

--- src/sys/arch/arm/omap/Attic/omap2_obiovar.h 2012/09/05 00:19:59 1.2
+++ src/sys/arch/arm/omap/Attic/omap2_obiovar.h 2015/04/14 18:37:43 1.3
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: omap2_obiovar.h,v 1.2 2012/09/05 00:19:59 matt Exp $ */ 1/* $NetBSD: omap2_obiovar.h,v 1.3 2015/04/14 18:37:43 bouyer Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2007 Microsoft 4 * Copyright (c) 2007 Microsoft
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -30,26 +30,27 @@ @@ -30,26 +30,27 @@
30 */ 30 */
31#ifndef _ARM_OMAP_OMAP2_OBIOVAR_H_ 31#ifndef _ARM_OMAP_OMAP2_OBIOVAR_H_
32#define _ARM_OMAP_OMAP2_OBIOVAR_H_ 32#define _ARM_OMAP_OMAP2_OBIOVAR_H_
33 33
34struct obio_attach_args { 34struct obio_attach_args {
35 const char *obio_name; 35 const char *obio_name;
36 bus_space_tag_t obio_iot; 36 bus_space_tag_t obio_iot;
37 bus_addr_t obio_addr; 37 bus_addr_t obio_addr;
38 bus_size_t obio_size; 38 bus_size_t obio_size;
39 int obio_intr; 39 int obio_intr;
40 bus_dma_tag_t obio_dmat; 40 bus_dma_tag_t obio_dmat;
41 unsigned int obio_mult; 41 unsigned int obio_mult;
42 unsigned int obio_intrbase; 42 unsigned int obio_intrbase;
 43 int obio_edmabase;
43}; 44};
44 45
45struct obio_softc { 46struct obio_softc {
46 device_t sc_dev; 47 device_t sc_dev;
47 bus_dma_tag_t sc_dmat; 48 bus_dma_tag_t sc_dmat;
48 bus_space_tag_t sc_iot; 49 bus_space_tag_t sc_iot;
49 bus_space_handle_t sc_ioh; 50 bus_space_handle_t sc_ioh;
50 bus_addr_t sc_base; 51 bus_addr_t sc_base;
51 bus_size_t sc_size; 52 bus_size_t sc_size;
52 device_t sc_obio_dev; 53 device_t sc_obio_dev;
53}; 54};
54 55
55#endif /* _ARM_OMAP_OMAP2_OBIOVAR_H_ */ 56#endif /* _ARM_OMAP_OMAP2_OBIOVAR_H_ */

cvs diff -r1.28 -r1.29 src/sys/arch/arm/omap/Attic/omap2_reg.h (expand / switch to unified diff)

--- src/sys/arch/arm/omap/Attic/omap2_reg.h 2014/07/20 23:08:43 1.28
+++ src/sys/arch/arm/omap/Attic/omap2_reg.h 2015/04/14 18:37:43 1.29
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: omap2_reg.h,v 1.28 2014/07/20 23:08:43 bouyer Exp $ */ 1/* $NetBSD: omap2_reg.h,v 1.29 2015/04/14 18:37:43 bouyer Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2007 Microsoft 4 * Copyright (c) 2007 Microsoft
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -886,15 +886,30 @@ @@ -886,15 +886,30 @@
886#define CTLMOD_CONTROL_STATUS_SYSBOOT1 __BITS(23,22) 886#define CTLMOD_CONTROL_STATUS_SYSBOOT1 __BITS(23,22)
887 887
888#define TI_AM335X_CTLMOD_DEVID 0x0600 888#define TI_AM335X_CTLMOD_DEVID 0x0600
889#define TI_AM335X_CTLMOD_DEVID_REV(x) (((x) >> 28) & 0xf) 889#define TI_AM335X_CTLMOD_DEVID_REV(x) (((x) >> 28) & 0xf)
890#endif 890#endif
891#if defined(OMAP4) || defined(TI_AM335X) 891#if defined(OMAP4) || defined(TI_AM335X)
892#define EMIF_SDRAM_CONFIG 8 892#define EMIF_SDRAM_CONFIG 8
893#define SDRAM_CONFIG_WIDTH __BITS(15,14) 893#define SDRAM_CONFIG_WIDTH __BITS(15,14)
894#define SDRAM_CONFIG_RSIZE __BITS(9,7) 894#define SDRAM_CONFIG_RSIZE __BITS(9,7)
895#define SDRAM_CONFIG_IBANK __BITS(6,4) 895#define SDRAM_CONFIG_IBANK __BITS(6,4)
896#define SDRAM_CONFIG_EBANK __BIT(3) 896#define SDRAM_CONFIG_EBANK __BIT(3)
897#define SDRAM_CONFIG_PAGESIZE __BITS(2,0) 897#define SDRAM_CONFIG_PAGESIZE __BITS(2,0)
898#endif 898#endif
899  899
 900/* EDMA3 */
 901#define AM335X_TPCC_BASE 0x49000000
 902#define AM335X_TPCC_SIZE 0x00100000
 903#define AM335X_TPTC0_BASE 0x49800000
 904#define AM335X_TPTC0_SIZE 0x00100000
 905#define AM335X_TPTC1_BASE 0x49900000
 906#define AM335X_TPTC1_SIZE 0x00100000
 907#define AM335X_TPTC2_BASE 0x49a00000
 908#define AM335X_TPTC2_SIZE 0x00100000
 909#define AM335X_INT_EDMACOMPINT 12
 910#define AM335X_INT_EDMAMPERR 13
 911#define AM335X_INT_EDMAERRINT 14
 912#define AM335X_INT_TCERRINT0 112
 913#define AM335X_INT_TCERRINT1 113
 914#define AM335X_INT_TCERRINT2 114
900#endif /* _ARM_OMAP_OMAP2_REG_H_ */ 915#endif /* _ARM_OMAP_OMAP2_REG_H_ */

File Added: src/sys/arch/arm/omap/Attic/omap_edma.c
/* $NetBSD: omap_edma.c,v 1.1 2015/04/14 18:37:43 bouyer Exp $ */

/*-
 * Copyright (c) 2014 Jared D. McNeill <jmcneill@invisible.ca>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: omap_edma.c,v 1.1 2015/04/14 18:37:43 bouyer Exp $");

#include "opt_omap.h"

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/conf.h>
#include <sys/intr.h>
#include <sys/mutex.h>
#include <sys/bus.h>
#include <sys/bitops.h>

#include <arm/omap/am335x_prcm.h>
#include <arm/omap/omap2_prcm.h>
#include <arm/omap/sitara_cm.h>
#include <arm/omap/sitara_cmreg.h>

#include <arm/omap/omap2_reg.h>
#include <arm/omap/omap2_obiovar.h>
#include <arm/omap/omap_edma.h>

#ifdef TI_AM335X
static const struct omap_module edma3cc_module =
	{ AM335X_PRCM_CM_PER, CM_PER_TPCC_CLKCTRL };
static const struct omap_module edma3tc0_module =
	{ AM335X_PRCM_CM_PER, CM_PER_TPTC0_CLKCTRL };
static const struct omap_module edma3tc1_module =
	{ AM335X_PRCM_CM_PER, CM_PER_TPTC1_CLKCTRL };
static const struct omap_module edma3tc2_module =
	{ AM335X_PRCM_CM_PER, CM_PER_TPTC2_CLKCTRL };
#endif

#define NUM_DMA_CHANNELS	64
#define NUM_PARAM_SETS		256
#define MAX_PARAM_PER_CHANNEL	32

#ifdef EDMA_DEBUG
int edmadebug = 1;
#define DPRINTF(n,s)    do { if ((n) <= edmadebug) device_printf s; } while (0)
#else
#define DPRINTF(n,s)    do {} while (0)
#endif

struct edma_softc;

struct edma_channel {
	struct edma_softc *ch_sc;
	enum edma_type ch_type;
	uint8_t ch_index;
	void (*ch_callback)(void *);
	void *ch_callbackarg;
	unsigned int ch_nparams;
};

struct edma_softc {
	device_t sc_dev;
	bus_space_tag_t sc_iot;
	bus_space_handle_t sc_ioh;
	kmutex_t sc_lock;
	struct edma_channel sc_dma[NUM_DMA_CHANNELS];

	void *sc_ih;
	void *sc_mperr_ih;
	void *sc_errint_ih;

	uint32_t sc_dmamask[NUM_DMA_CHANNELS / 32];
	uint32_t sc_parammask[NUM_PARAM_SETS / 32];
};

static int edma_match(device_t, cfdata_t, void *);
static void edma_attach(device_t, device_t, void *);

static void edma_init(struct edma_softc *);
static int edma_intr(void *);
static int edma_mperr_intr(void *);
static int edma_errint_intr(void *);
static void edma_write_param(struct edma_softc *,
				  unsigned int, const struct edma_param *);
static bool edma_bit_isset(uint32_t *, unsigned int);
static void edma_bit_set(uint32_t *, unsigned int);
static void edma_bit_clr(uint32_t *, unsigned int);

CFATTACH_DECL_NEW(edma, sizeof(struct edma_softc),
    edma_match, edma_attach, NULL, NULL);

#define EDMA_READ(sc, reg) \
	bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))
#define EDMA_WRITE(sc, reg, val) \
	bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))

static int
edma_match(device_t parent, cfdata_t match, void *aux)
{
	struct obio_attach_args *obio = aux;

#ifdef TI_AM335X
	if (obio->obio_addr == AM335X_TPCC_BASE &&
	    obio->obio_size == AM335X_TPCC_SIZE &&
	    obio->obio_intrbase == AM335X_INT_EDMACOMPINT)
		return 1;
#endif

	return 0;
}

static void
edma_attach(device_t parent, device_t self, void *aux)
{
	struct edma_softc *sc = device_private(self);
	struct obio_attach_args *obio = aux;
	int idx;

	sc->sc_dev = self;
	sc->sc_iot = obio->obio_iot;
	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SCHED);
	if (bus_space_map(obio->obio_iot, obio->obio_addr, obio->obio_size,
	    0, &sc->sc_ioh) != 0) {
		aprint_error(": couldn't map address spcae\n");
		return;
	}

	aprint_normal("\n");
	aprint_naive("\n");

	for (idx = 0; idx < NUM_DMA_CHANNELS; idx++) {
		struct edma_channel *ch = &sc->sc_dma[idx];
		ch->ch_sc = sc;
		ch->ch_type = EDMA_TYPE_DMA;
		ch->ch_index = idx;
		ch->ch_callback = NULL;
		ch->ch_callbackarg = NULL;
		ch->ch_nparams = 0;
	}

	edma_init(sc);

	sc->sc_ih = intr_establish(obio->obio_intrbase + 0,
	    IPL_SCHED, IST_LEVEL, edma_intr, sc);
	KASSERT(sc->sc_ih != NULL);

	sc->sc_mperr_ih = intr_establish(obio->obio_intrbase + 1,
	    IPL_SCHED, IST_LEVEL, edma_mperr_intr, sc);
	sc->sc_errint_ih = intr_establish(obio->obio_intrbase + 2,
	    IPL_SCHED, IST_LEVEL, edma_errint_intr, sc);
}

/*
 * Hardware initialization
 */
static void
edma_init(struct edma_softc *sc)
{
	struct edma_param param;
	uint32_t val;
	int idx;

#ifdef TI_AM335X
	prcm_module_enable(&edma3cc_module);
	prcm_module_enable(&edma3tc0_module);
	prcm_module_enable(&edma3tc1_module);
	prcm_module_enable(&edma3tc2_module);
#endif

	val = EDMA_READ(sc, EDMA_CCCFG_REG);
	if (val & EDMA_CCCFG_CHMAP_EXIST) {
		for (idx = 0; idx < NUM_DMA_CHANNELS; idx++) {
			EDMA_WRITE(sc, EDMA_DCHMAP_REG(idx),
			    __SHIFTIN(0, EDMA_DCHMAP_PAENTRY));
		}
	}

	memset(&param, 0, sizeof(param));
	param.ep_bcnt = 1;
	for (idx = 0; idx < NUM_PARAM_SETS; idx++) {
		edma_write_param(sc, idx, &param);
	}

	/* reserve PaRAM entry 0 for dummy slot */
	edma_bit_set(sc->sc_parammask, 0);
	for (idx = 1; idx <= 32; idx++) {
		edma_bit_set(sc->sc_parammask, idx);
	}
}

/*
 * Write a PaRAM entry
 */
static void
edma_write_param(struct edma_softc *sc,
    unsigned int idx, const struct edma_param *ep)
{
	EDMA_WRITE(sc, EDMA_PARAM_OPT_REG(idx), ep->ep_opt);
	EDMA_WRITE(sc, EDMA_PARAM_SRC_REG(idx), ep->ep_src);
	EDMA_WRITE(sc, EDMA_PARAM_CNT_REG(idx),
	    __SHIFTIN(ep->ep_bcnt, EDMA_PARAM_CNT_BCNT) |
	    __SHIFTIN(ep->ep_acnt, EDMA_PARAM_CNT_ACNT));
	EDMA_WRITE(sc, EDMA_PARAM_DST_REG(idx), ep->ep_dst);
	EDMA_WRITE(sc, EDMA_PARAM_BIDX_REG(idx),
	    __SHIFTIN(ep->ep_dstbidx, EDMA_PARAM_BIDX_DSTBIDX) |
	    __SHIFTIN(ep->ep_srcbidx, EDMA_PARAM_BIDX_SRCBIDX));
	EDMA_WRITE(sc, EDMA_PARAM_LNK_REG(idx),
	    __SHIFTIN(ep->ep_bcntrld, EDMA_PARAM_LNK_BCNTRLD) |
	    __SHIFTIN(ep->ep_link, EDMA_PARAM_LNK_LINK));
	EDMA_WRITE(sc, EDMA_PARAM_CIDX_REG(idx),
	    __SHIFTIN(ep->ep_dstcidx, EDMA_PARAM_CIDX_DSTCIDX) |
	    __SHIFTIN(ep->ep_srccidx, EDMA_PARAM_CIDX_SRCCIDX));
	EDMA_WRITE(sc, EDMA_PARAM_CCNT_REG(idx),
	    __SHIFTIN(ep->ep_ccnt, EDMA_PARAM_CCNT_CCNT));
}

static bool
edma_bit_isset(uint32_t *bits, unsigned int bit)
{
	return !!(bits[bit >> 5] & (1 << (bit & 0x1f)));
}

static void
edma_bit_set(uint32_t *bits, unsigned int bit)
{
	bits[bit >> 5] |= (1 << (bit & 0x1f));
}

static void
edma_bit_clr(uint32_t *bits, unsigned int bit)
{
	bits[bit >> 5] &= ~(1 << (bit & 0x1f));
}

static int
edma_intr(void *priv)
{
	struct edma_softc *sc = priv;
	uint64_t ipr, ier;
	int bit, idx;

	ipr = EDMA_READ(sc, EDMA_IPR_REG);
	ipr |= (uint64_t)EDMA_READ(sc, EDMA_IPRH_REG) << 32;
	if (ipr == 0)
		return 0;

	ier = EDMA_READ(sc, EDMA_IER_REG);
	ier |= (uint64_t)EDMA_READ(sc, EDMA_IERH_REG) << 32;

	DPRINTF(2, (sc->sc_dev, "ipr = 0x%016llx ier 0x%016llx\n", ipr, ier));

	EDMA_WRITE(sc, EDMA_ICR_REG, ipr & 0xffffffff);
	EDMA_WRITE(sc, EDMA_ICRH_REG, ipr >> 32);

	while ((bit = ffs64(ipr)) != 0) {
		idx = bit - 1;
		ipr &= ~__BIT(idx);
		if (!(ier & __BIT(idx)))
			continue;
		if (!edma_bit_isset(sc->sc_dmamask, idx))
			continue;

		sc->sc_dma[idx].ch_callback(sc->sc_dma[idx].ch_callbackarg);
	}

	EDMA_WRITE(sc, EDMA_IEVAL_REG, EDMA_IEVAL_EVAL);

	return 1;
}

static int
edma_mperr_intr(void *priv)
{
	printf(" ===== edma mperr!\n");
	return 0;
}

static int
edma_errint_intr(void *priv)
{
	printf(" ===== edma errint!\n");
	return 0;
}


/*
 * Allocate a DMA channel. Currently only DMA types are supported, not QDMA.
 * Returns NULL on failure.
 */
struct edma_channel *
edma_channel_alloc(enum edma_type type, unsigned int drq,
    void (*cb)(void *), void *cbarg)
{
	struct edma_softc *sc;
	device_t dev;
	struct edma_channel *ch = NULL;

	KASSERT(drq < __arraycount(sc->sc_dma));
	KASSERT(type == EDMA_TYPE_DMA);	/* QDMA not implemented */
	KASSERT(cb != NULL);
	KASSERT(cbarg != NULL);

	dev = device_find_by_driver_unit("edma", 0);
	if (dev == NULL)
		return NULL;
	sc = device_private(dev);

	mutex_enter(&sc->sc_lock);
	if (!edma_bit_isset(sc->sc_dmamask, drq)) {
		ch = &sc->sc_dma[drq];
		KASSERT(ch->ch_callback == NULL);
		KASSERT(ch->ch_index == drq);
		ch->ch_callback = cb;
		ch->ch_callbackarg = cbarg;
		edma_bit_set(sc->sc_dmamask, drq);
	}

	if (ch == NULL)
		goto done;

	EDMA_WRITE(sc, EDMA_DRAE_REG(0), sc->sc_dmamask[0]);
	EDMA_WRITE(sc, EDMA_DRAEH_REG(0), sc->sc_dmamask[1]);

	if (ch->ch_index < 32) {
		EDMA_WRITE(sc, EDMA_ICR_REG, __BIT(ch->ch_index));
		EDMA_WRITE(sc, EDMA_IESR_REG, __BIT(ch->ch_index));
	} else {
		EDMA_WRITE(sc, EDMA_ICRH_REG, __BIT(ch->ch_index - 32));
		EDMA_WRITE(sc, EDMA_IESRH_REG, __BIT(ch->ch_index - 32));
	}

done:
	mutex_exit(&sc->sc_lock);

	return ch;
}

/*
 * Free a DMA channel allocated with edma_channel_alloc
 */
void
edma_channel_free(struct edma_channel *ch)
{
	struct edma_softc *sc = ch->ch_sc;

	KASSERT(ch->ch_nparams == 0);

	mutex_enter(&sc->sc_lock);
	if (ch->ch_index < 32) {
		EDMA_WRITE(sc, EDMA_IECR_REG, __BIT(ch->ch_index));
	} else {
		EDMA_WRITE(sc, EDMA_IECRH_REG, __BIT(ch->ch_index - 32));
	}
	ch->ch_callback = NULL;
	ch->ch_callbackarg = NULL;
	edma_bit_clr(sc->sc_dmamask, ch->ch_index);
	mutex_exit(&sc->sc_lock);
}

/*
 * Allocate a PaRAM entry. The driver artifically restricts the number
 * of PaRAM entries available for each channel to MAX_PARAM_PER_CHANNEL.
 * If the number of entries for the channel has been exceeded, or there
 * are no entries available, 0xffff is returned.
 */
uint16_t
edma_param_alloc(struct edma_channel *ch)
{
	struct edma_softc *sc = ch->ch_sc;
	uint16_t param_entry = 0xffff;
	int idx;

	if (ch->ch_nparams == MAX_PARAM_PER_CHANNEL)
		return param_entry;

	mutex_enter(&sc->sc_lock);
	for (idx = 0; idx < NUM_PARAM_SETS; idx++) {
		if (!edma_bit_isset(sc->sc_parammask, idx)) {
			param_entry = idx;
			edma_bit_set(sc->sc_parammask, idx);
			ch->ch_nparams++;
			break;
		}
	}
	mutex_exit(&sc->sc_lock);

	return param_entry;
}

/*
 * Free a PaRAM entry allocated with edma_param_alloc
 */
void
edma_param_free(struct edma_channel *ch, uint16_t param_entry)
{
	struct edma_softc *sc = ch->ch_sc;

	KASSERT(param_entry < NUM_PARAM_SETS);
	KASSERT(ch->ch_nparams > 0);
	KASSERT(edma_bit_isset(sc->sc_parammask, param_entry));

	mutex_enter(&sc->sc_lock);
	edma_bit_clr(sc->sc_parammask, param_entry);
	ch->ch_nparams--;
	mutex_exit(&sc->sc_lock);
}

/*
 * Update a PaRAM entry register set with caller-provided values
 */
void
edma_set_param(struct edma_channel *ch, uint16_t param_entry,
    struct edma_param *ep)
{
	struct edma_softc *sc = ch->ch_sc;

	KASSERT(param_entry < NUM_PARAM_SETS);
	KASSERT(ch->ch_nparams > 0);
	KASSERT(edma_bit_isset(sc->sc_parammask, param_entry));

	DPRINTF(1, (sc->sc_dev, "write param entry ch# %d pe %d: 0x%08x -> 0x%08x (%u, %u, %u)\n", ch->ch_index, param_entry, ep->ep_src, ep->ep_dst, ep->ep_acnt, ep->ep_bcnt, ep->ep_ccnt));
	edma_write_param(sc, param_entry, ep);
}

/*
 * Enable a DMA channel: Point channel to the PaRam entry,
 * clear error if any, and only set the Event Enable bit.
 * The Even will either be generated by hardware, or with
 * edma_transfer_start()
 */
int
edma_transfer_enable(struct edma_channel *ch, uint16_t param_entry)
{
	struct edma_softc *sc = ch->ch_sc;
	bus_size_t off = (ch->ch_index < 32 ? 0 : 4);
	uint32_t bit = __BIT(ch->ch_index < 32 ?
			     ch->ch_index : ch->ch_index - 32);

	DPRINTF(1, (sc->sc_dev, "enable transfer ch# %d off %d bit %x pe %d\n", ch->ch_index, (int)off, bit, param_entry));

	EDMA_WRITE(sc, EDMA_DCHMAP_REG(ch->ch_index),
	    __SHIFTIN(param_entry, EDMA_DCHMAP_PAENTRY));

	uint32_t ccerr = EDMA_READ(sc, EDMA_CCERR_REG);
	if (ccerr) {
		device_printf(sc->sc_dev, " !!! CCER %08x\n", ccerr);
		EDMA_WRITE(sc, EDMA_CCERRCLR_REG, ccerr);
	}

	EDMA_WRITE(sc, EDMA_EESR_REG + off, bit);
	return 0;
}

/*
 * Software-start a DMA channel: Set the Event bit.
 */
int
edma_transfer_start(struct edma_channel *ch)
{
	struct edma_softc *sc = ch->ch_sc;
	bus_size_t off = (ch->ch_index < 32 ? 0 : 4);
	uint32_t bit = __BIT(ch->ch_index < 32 ?
			     ch->ch_index : ch->ch_index - 32);

	DPRINTF(1, (sc->sc_dev, "start transfer ch# %d off %d bit %x pe %d\n", ch->ch_index, (int)off, bit));

	EDMA_WRITE(sc, EDMA_ESR_REG + off, bit);
	return 0;
}

/*
 * Halt a DMA transfer. Called after successfull transfer, or to abort
 * a transfer.
 */
void
edma_halt(struct edma_channel *ch)
{
	struct edma_softc *sc = ch->ch_sc;
	bus_size_t off = (ch->ch_index < 32 ? 0 : 4);
	uint32_t bit = __BIT(ch->ch_index < 32 ?
			     ch->ch_index : ch->ch_index - 32);
	
	EDMA_WRITE(sc, EDMA_EECR_REG + off, bit);
	EDMA_WRITE(sc, EDMA_ECR_REG + off, bit);
	EDMA_WRITE(sc, EDMA_SECR_REG + off, bit);
	EDMA_WRITE(sc, EDMA_EMCR_REG + off, bit);

	EDMA_WRITE(sc, EDMA_DCHMAP_REG(ch->ch_index),
	    __SHIFTIN(0, EDMA_DCHMAP_PAENTRY));
}

uint8_t
edma_channel_index(struct edma_channel *ch)
{
	return ch->ch_index;
}

void
edma_dump(struct edma_channel *ch)
{
	static const struct {
		const char *name;
		uint16_t off;
	} regs[] = {
		{ "ER", EDMA_ER_REG },
		{ "ERH", EDMA_ERH_REG },
		{ "EER", EDMA_EER_REG },
		{ "EERH", EDMA_EERH_REG },
		{ "SER", EDMA_SER_REG },
		{ "SERH", EDMA_SERH_REG },
		{ "IER", EDMA_IER_REG },
		{ "IERH", EDMA_IERH_REG },
		{ "IPR", EDMA_IPR_REG },
		{ "IPRH", EDMA_IPRH_REG },
		{ "CCERR", EDMA_CCERR_REG },
		{ "CCSTAT", EDMA_CCSTAT_REG },
		{ "DRAE0", EDMA_DRAE_REG(0) },
		{ "DRAEH0", EDMA_DRAEH_REG(0) },
		{ NULL, 0 }
	};
	struct edma_softc *sc = ch->ch_sc;
	int i;

	for (i = 0; regs[i].name; i++) {
		device_printf(sc->sc_dev, "%s: %08x\n",
		    regs[i].name, EDMA_READ(sc, regs[i].off));
	}
	device_printf(sc->sc_dev, "DCHMAP%d: %08x\n", ch->ch_index,
	    EDMA_READ(sc, EDMA_DCHMAP_REG(ch->ch_index)));
}

void
edma_dump_param(struct edma_channel *ch, uint16_t param_entry)
{
	struct {
		const char *name;
		uint16_t off;
	} regs[] = {
		{ "OPT", EDMA_PARAM_OPT_REG(param_entry) },
		{ "CNT", EDMA_PARAM_CNT_REG(param_entry) },
		{ "DST", EDMA_PARAM_DST_REG(param_entry) },
		{ "BIDX", EDMA_PARAM_BIDX_REG(param_entry) },
		{ "LNK", EDMA_PARAM_LNK_REG(param_entry) },
		{ "CIDX", EDMA_PARAM_CIDX_REG(param_entry) },
		{ "CCNT", EDMA_PARAM_CCNT_REG(param_entry) },
		{ NULL, 0 }
	};
	struct edma_softc *sc = ch->ch_sc;
	int i;

	for (i = 0; regs[i].name; i++) {
		device_printf(sc->sc_dev, "%s%d: %08x\n",
		    regs[i].name, param_entry, EDMA_READ(sc, regs[i].off));
	}
}

File Added: src/sys/arch/arm/omap/Attic/omap_edma.c.orig

File Added: src/sys/arch/arm/omap/Attic/omap_edma.h
/* $NetBSD: omap_edma.h,v 1.1 2015/04/14 18:37:43 bouyer Exp $ */

/*-
 * Copyright (c) 2014 Jared D. McNeill <jmcneill@invisible.ca>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef _OMAP_EDMA_H
#define _OMAP_EDMA_H

#define EDMA_PID_REG			0x0000
#define EDMA_CCCFG_REG			0x0004
#define EDMA_CCCFG_MP_EXIST		__BIT(25)
#define EDMA_CCCFG_CHMAP_EXIST		__BIT(24)
#define EDMA_CCCFG_NUM_REGN		__BITS(21,20)
#define EDMA_CCCFG_NUM_EVQUEUE		__BITS(18,16)
#define EDMA_CCCFG_NUM_PAENTRY		__BITS(14,12)
#define EDMA_CCCFG_NUM_INTCH		__BITS(10,8)
#define EDMA_CCCFG_NUM_QDMACH		__BITS(6,4)
#define EDMA_CCCFG_NUM_DMACH		__BITS(2,0)
#define EDMA_SYSCONFIG_REG		0x0010
#define EDMA_DCHMAP_REG(n)		(0x0100 + 4 * (n))
#define EDMA_DCHMAP_PAENTRY		__BITS(13,5)
#define EDMA_QCHMAP_REG(n)		(0x0200 + 4 * (n))
#define EDMA_DMAQNUM_REG(n)		(0x0240 + 4 * (n))
#define EDMA_QDMAQNUM_REG		0x0260
#define EDMA_QUEPRI_REG			0x0284
#define EDMA_EMR_REG			0x0300
#define EDMA_EMRH_REG			0x0304
#define EDMA_EMCR_REG			0x0308
#define EDMA_EMCRH_REG			0x030c
#define EDMA_QEMR_REG			0x0310
#define EDMA_QEMRC_REG			0x0314
#define EDMA_CCERR_REG			0x0318
#define EDMA_CCERRCLR_REG		0x031c
#define EDMA_EEVAL_REG			0x0320
#define EDMA_DRAE_REG(n)		(0x0340 + 8 * (n))
#define EDMA_DRAEH_REG(n)		(0x0340 + 8 * (n) + 4)
#define EDMA_QRAE_REG(n)		(0x0380 + 4 * (n))
#define EDMA_QE_REG(q, e)		(0x0400 + 0x40 * (q) + 4 * (e))
#define EDMA_QSTAT_REG(n)		(0x0600 + 4 * (n))
#define EDMA_QWMTHRA_REG		0x0620
#define EDMA_CCSTAT_REG			0x0640
#define EDMA_MPFAR_REG			0x0800
#define EDMA_MPFSR_REG			0x0804
#define EDMA_MPFCR_REG			0x0808
#define EDMA_MPPAG_REG			0x080c
#define EDMA_MPPA_REG(n)		(0x0810 + 4 * (n))
#define EDMA_ER_REG			0x1000
#define EDMA_ERH_REG			0x1004
#define EDMA_ECR_REG			0x1008
#define EDMA_ECRH_REG			0x100c
#define EDMA_ESR_REG			0x1010
#define EDMA_ESRH_REG			0x1014
#define EDMA_CER_REG			0x1018
#define EDMA_CERH_REG			0x101c
#define EDMA_EER_REG			0x1020
#define EDMA_EERH_REG			0x1024
#define EDMA_EECR_REG			0x1028
#define EDMA_EECRH_REG			0x102c
#define EDMA_EESR_REG			0x1030
#define EDMA_EESRH_REG			0x1034
#define EDMA_SER_REG			0x1038
#define EDMA_SERH_REG			0x103c
#define EDMA_SECR_REG			0x1040
#define EDMA_SECRH_REG			0x1044
#define EDMA_IER_REG			0x1050
#define EDMA_IERH_REG			0x1054
#define EDMA_IECR_REG			0x1058
#define EDMA_IECRH_REG			0x105c
#define EDMA_IESR_REG			0x1060
#define EDMA_IESRH_REG			0x1064
#define EDMA_IPR_REG			0x1068
#define EDMA_IPRH_REG			0x106c
#define EDMA_ICR_REG			0x1070
#define EDMA_ICRH_REG			0x1074
#define EDMA_IEVAL_REG			0x1078
#define EDMA_IEVAL_EVAL			__BIT(0)
#define EDMA_QER_REG			0x1080
#define EDMA_QEER_REG			0x1084
#define EDMA_QEECR_REG			0x1088
#define EDMA_QEESR_REG			0x108c
#define EDMA_QSER_REG			0x1090
#define EDMA_QSECR_REG			0x1094

#define EDMA_PARAM_BASE(n)		(0x4000 + 0x20 * (n))
#define EDMA_PARAM_OPT_REG(n)		(EDMA_PARAM_BASE(n) + 0x00)
#define EDMA_PARAM_OPT_PRIV		__BIT(31)
#define EDMA_PARAM_OPT_PRIVID		__BITS(27,24)
#define EDMA_PARAM_OPT_ITCCHEN		__BIT(23)
#define EDMA_PARAM_OPT_TCCHEN		__BIT(22)
#define EDMA_PARAM_OPT_ITCINTEN		__BIT(21)
#define EDMA_PARAM_OPT_TCINTEN		__BIT(20)
#define EDMA_PARAM_OPT_TCC		__BITS(17,12)
#define EDMA_PARAM_OPT_TCCMODE		__BIT(11)
#define EDMA_PARAM_OPT_FWID		__BITS(10,8)
#define EDMA_PARAM_OPT_STATIC		__BIT(3)
#define EDMA_PARAM_OPT_SYNCDIM		__BIT(2)
#define EDMA_PARAM_OPT_DAM		__BIT(1)
#define EDMA_PARAM_OPT_SAM		__BIT(0)
#define EDMA_PARAM_SRC_REG(n)		(EDMA_PARAM_BASE(n) + 0x04)
#define EDMA_PARAM_CNT_REG(n)		(EDMA_PARAM_BASE(n) + 0x08)
#define EDMA_PARAM_CNT_BCNT		__BITS(31,16)
#define EDMA_PARAM_CNT_ACNT		__BITS(15,0)
#define EDMA_PARAM_DST_REG(n)		(EDMA_PARAM_BASE(n) + 0x0c)
#define EDMA_PARAM_BIDX_REG(n)		(EDMA_PARAM_BASE(n) + 0x10)
#define EDMA_PARAM_BIDX_DSTBIDX		__BITS(31,16)
#define EDMA_PARAM_BIDX_SRCBIDX		__BITS(15,0)
#define EDMA_PARAM_LNK_REG(n)		(EDMA_PARAM_BASE(n) + 0x14)
#define EDMA_PARAM_LNK_BCNTRLD		__BITS(31,16)
#define EDMA_PARAM_LNK_LINK		__BITS(15,0)
#define EDMA_PARAM_CIDX_REG(n)		(EDMA_PARAM_BASE(n) + 0x18)
#define EDMA_PARAM_CIDX_DSTCIDX		__BITS(31,16)
#define EDMA_PARAM_CIDX_SRCCIDX		__BITS(15,0)
#define EDMA_PARAM_CCNT_REG(n)		(EDMA_PARAM_BASE(n) + 0x1c)
#define EDMA_PARAM_CCNT_CCNT		__BITS(15,0)

enum edma_type {
	EDMA_TYPE_DMA,
	EDMA_TYPE_QDMA
};

struct edma_param {
	uint32_t	ep_opt;
	uint32_t	ep_src;
	uint32_t	ep_dst;
	uint16_t	ep_bcnt;
	uint16_t	ep_acnt;
	uint16_t	ep_dstbidx;
	uint16_t	ep_srcbidx;
	uint16_t	ep_bcntrld;
	uint16_t	ep_link;
	uint16_t	ep_dstcidx;
	uint16_t	ep_srccidx;
	uint16_t	ep_ccnt;
};

struct edma_channel;

struct edma_channel *edma_channel_alloc(enum edma_type, unsigned int,
					void (*)(void *), void *);
void edma_channel_free(struct edma_channel *);
uint16_t edma_param_alloc(struct edma_channel *);
void edma_param_free(struct edma_channel *, uint16_t);
void edma_set_param(struct edma_channel *, uint16_t, struct edma_param *);
int edma_transfer_enable(struct edma_channel *, uint16_t);
int edma_transfer_start(struct edma_channel *);
void edma_halt(struct edma_channel *);
uint8_t edma_channel_index(struct edma_channel *);
void edma_dump(struct edma_channel *);
void edma_dump_param(struct edma_channel *, uint16_t);

#endif /* !_OMAP_EDMA_H */

File Added: src/sys/arch/arm/omap/Attic/omap_edma.h.orig