Annotation of sys/arch/macppc/dev/dbdma.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: dbdma.c,v 1.8 2006/01/13 19:25:44 miod Exp $ */
2: /* $NetBSD: dbdma.c,v 1.2 1998/08/21 16:13:28 tsubai Exp $ */
3:
4: /*
5: * Copyright 1991-1998 by Open Software Foundation, Inc.
6: * All Rights Reserved
7: *
8: * Permission to use, copy, modify, and distribute this software and
9: * its documentation for any purpose and without fee is hereby granted,
10: * provided that the above copyright notice appears in all copies and
11: * that both the copyright notice and this permission notice appear in
12: * supporting documentation.
13: *
14: * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
15: * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
16: * FOR A PARTICULAR PURPOSE.
17: *
18: * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
19: * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
20: * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
21: * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
22: * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23: *
24: */
25:
26: #include <sys/param.h>
27: #include <sys/malloc.h>
28: #include <sys/systm.h>
29:
30: #include <uvm/uvm_extern.h>
31:
32: #include <machine/bus.h>
33: #include <macppc/dev/dbdma.h>
34:
35: dbdma_command_t *dbdma_alloc_commands = NULL;
36:
37: void
38: dbdma_start(dbdma_regmap_t *dmap, dbdma_t dt)
39: {
40: u_int32_t addr = dt->d_paddr;
41:
42: DBDMA_ST4_ENDIAN(&dmap->d_intselect, DBDMA_CLEAR_CNTRL((0xffff)));
43: DBDMA_ST4_ENDIAN(&dmap->d_control, DBDMA_CLEAR_CNTRL((
44: DBDMA_CNTRL_ACTIVE |
45: DBDMA_CNTRL_DEAD |
46: DBDMA_CNTRL_WAKE |
47: DBDMA_CNTRL_FLUSH |
48: DBDMA_CNTRL_PAUSE |
49: DBDMA_CNTRL_RUN)));
50:
51: /* XXX time-bind it? */
52: do {
53: delay(10);
54: } while (DBDMA_LD4_ENDIAN(&dmap->d_status) & DBDMA_CNTRL_ACTIVE);
55:
56:
57: DBDMA_ST4_ENDIAN(&dmap->d_cmdptrhi, 0); /* 64-bit not yet */
58: DBDMA_ST4_ENDIAN(&dmap->d_cmdptrlo, addr);
59:
60: DBDMA_ST4_ENDIAN(&dmap->d_control,
61: DBDMA_SET_CNTRL(DBDMA_CNTRL_RUN|DBDMA_CNTRL_WAKE)|
62: DBDMA_CLEAR_CNTRL(DBDMA_CNTRL_PAUSE|DBDMA_CNTRL_DEAD) );
63: }
64:
65: void
66: dbdma_stop(dbdma_regmap_t *dmap)
67: {
68: DBDMA_ST4_ENDIAN(&dmap->d_control, DBDMA_CLEAR_CNTRL(DBDMA_CNTRL_RUN) |
69: DBDMA_SET_CNTRL(DBDMA_CNTRL_FLUSH));
70:
71: while (DBDMA_LD4_ENDIAN(&dmap->d_status) &
72: (DBDMA_CNTRL_ACTIVE|DBDMA_CNTRL_FLUSH));
73: }
74:
75: void
76: dbdma_flush(dbdma_regmap_t *dmap)
77: {
78: DBDMA_ST4_ENDIAN(&dmap->d_control, DBDMA_SET_CNTRL(DBDMA_CNTRL_FLUSH));
79:
80: /* XXX time-bind it? */
81: while (DBDMA_LD4_ENDIAN(&dmap->d_status) & (DBDMA_CNTRL_FLUSH));
82: }
83:
84: void
85: dbdma_reset(dbdma_regmap_t *dmap)
86: {
87: DBDMA_ST4_ENDIAN(&dmap->d_control,
88: DBDMA_CLEAR_CNTRL( (DBDMA_CNTRL_ACTIVE |
89: DBDMA_CNTRL_DEAD |
90: DBDMA_CNTRL_WAKE |
91: DBDMA_CNTRL_FLUSH |
92: DBDMA_CNTRL_PAUSE |
93: DBDMA_CNTRL_RUN )));
94:
95: /* XXX time-bind it? */
96: while (DBDMA_LD4_ENDIAN(&dmap->d_status) & DBDMA_CNTRL_RUN);
97: }
98:
99: void
100: dbdma_continue(dbdma_regmap_t *dmap)
101: {
102: DBDMA_ST4_ENDIAN(&dmap->d_control,
103: DBDMA_SET_CNTRL(DBDMA_CNTRL_RUN | DBDMA_CNTRL_WAKE) |
104: DBDMA_CLEAR_CNTRL(DBDMA_CNTRL_PAUSE | DBDMA_CNTRL_DEAD));
105: }
106:
107: void
108: dbdma_pause(dbdma_regmap_t *dmap)
109: {
110: DBDMA_ST4_ENDIAN(&dmap->d_control,DBDMA_SET_CNTRL(DBDMA_CNTRL_PAUSE));
111:
112: /* XXX time-bind it? */
113: while (DBDMA_LD4_ENDIAN(&dmap->d_status) & DBDMA_CNTRL_ACTIVE);
114: }
115:
116: dbdma_t
117: dbdma_alloc(bus_dma_tag_t dmat, int size)
118: {
119: dbdma_t dt;
120: int error;
121:
122: dt = malloc(sizeof *dt, M_DEVBUF, M_NOWAIT);
123: if (!dt)
124: return (dt);
125: bzero(dt, sizeof *dt);
126:
127: dt->d_size = size *= sizeof(dbdma_command_t);
128: dt->d_dmat = dmat;
129: if ((error = bus_dmamem_alloc(dmat, size, NBPG, 0, dt->d_segs,
130: 1, &dt->d_nsegs, BUS_DMA_NOWAIT)) != 0) {
131: printf("dbdma: unable to allocate dma, error = %d\n", error);
132: } else if ((error = bus_dmamem_map(dmat, dt->d_segs, dt->d_nsegs, size,
133: (caddr_t *)&dt->d_addr, BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) {
134: printf("dbdma: unable to map dma, error = %d\n", error);
135: } else if ((error = bus_dmamap_create(dmat, dt->d_size, 1,
136: dt->d_size, 0, BUS_DMA_NOWAIT, &dt->d_map)) != 0) {
137: printf("dbdma: unable to create dma map, error = %d\n", error);
138: } else if ((error = bus_dmamap_load_raw(dmat, dt->d_map,
139: dt->d_segs, dt->d_nsegs, size, BUS_DMA_NOWAIT)) != 0) {
140: printf("dbdma: unable to load dma map, error = %d\n", error);
141: } else
142: return dt;
143:
144: dbdma_free(dt);
145: return (NULL);
146: }
147:
148: void
149: dbdma_free(dbdma_t dt)
150: {
151: if (dt->d_map)
152: bus_dmamap_destroy(dt->d_dmat, dt->d_map);
153: if (dt->d_addr)
154: bus_dmamem_unmap(dt->d_dmat, (caddr_t)dt->d_addr, dt->d_size);
155: if (dt->d_nsegs)
156: bus_dmamem_free(dt->d_dmat, dt->d_segs, dt->d_nsegs);
157: free(dt, M_DEVBUF);
158: }
CVSweb