Annotation of sys/arch/macppc/dev/dbdma.c, Revision 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