dbdma.c revision 1.1
1/*
2 * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991
3 *              All Rights Reserved
4 *
5 * Permission to use, copy, modify, and distribute this software and
6 * its documentation for any purpose and without fee is hereby granted,
7 * provided that the above copyright notice appears in all copies and
8 * that both the copyright notice and this permission notice appear in
9 * supporting documentation.
10 *
11 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
12 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
13 * FOR A PARTICULAR PURPOSE.
14 *
15 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
16 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
17 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
18 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
19 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 *
21 */
22
23#include <sys/param.h>
24#include <sys/malloc.h>
25
26#include <machine/pio.h>
27#include <macppc/dev/dbdma.h>
28
29#define eieio() __asm__ volatile("eieio")
30
31
32static int	dbdma_alloc_index = 0;
33dbdma_command_t	*dbdma_alloc_commands = NULL;
34
35void
36dbdma_start(dmap, commands)
37	dbdma_regmap_t *dmap;
38	dbdma_command_t *commands;
39{
40	unsigned long addr = kvtop((vm_offset_t) commands);
41
42	if (addr & 0xf)
43		panic("dbdma_start command structure not 16-byte aligned");
44
45	dmap->d_intselect = 0xff;  /* Endian magic - clear out interrupts */
46	DBDMA_ST4_ENDIAN(&dmap->d_control,
47			 DBDMA_CLEAR_CNTRL( (DBDMA_CNTRL_ACTIVE	|
48					     DBDMA_CNTRL_DEAD	|
49					     DBDMA_CNTRL_WAKE	|
50					     DBDMA_CNTRL_FLUSH	|
51					     DBDMA_CNTRL_PAUSE	|
52					     DBDMA_CNTRL_RUN      )));
53	eieio();
54
55	while (DBDMA_LD4_ENDIAN(&dmap->d_status) & DBDMA_CNTRL_ACTIVE)
56		eieio();
57
58	dmap->d_cmdptrhi = 0;	eieio();/* 64-bit not yet */
59	DBDMA_ST4_ENDIAN(&dmap->d_cmdptrlo, addr); eieio();
60
61	DBDMA_ST4_ENDIAN(&dmap->d_control, DBDMA_SET_CNTRL(DBDMA_CNTRL_RUN));
62	eieio();
63}
64
65void
66dbdma_stop(dmap)
67	dbdma_regmap_t *dmap;
68{
69	out32rb(&dmap->d_control, DBDMA_CLEAR_CNTRL(DBDMA_CNTRL_RUN) |
70			  DBDMA_SET_CNTRL(DBDMA_CNTRL_FLUSH));
71
72	while (in32rb(&dmap->d_status) &
73		(DBDMA_CNTRL_ACTIVE|DBDMA_CNTRL_FLUSH));
74}
75
76void
77dbdma_flush(dmap)
78	dbdma_regmap_t *dmap;
79{
80	out32rb(&dmap->d_control, DBDMA_SET_CNTRL(DBDMA_CNTRL_FLUSH));
81
82	while (in32rb(&dmap->d_status) & (DBDMA_CNTRL_FLUSH));
83}
84
85void
86dbdma_reset(dmap)
87	dbdma_regmap_t *dmap;
88{
89	out32rb(&dmap->d_control,
90			 DBDMA_CLEAR_CNTRL( (DBDMA_CNTRL_ACTIVE	|
91					     DBDMA_CNTRL_DEAD	|
92					     DBDMA_CNTRL_WAKE	|
93					     DBDMA_CNTRL_FLUSH	|
94					     DBDMA_CNTRL_PAUSE	|
95					     DBDMA_CNTRL_RUN      )));
96
97	while (in32rb(&dmap->d_status) & DBDMA_CNTRL_RUN);
98}
99
100void
101dbdma_continue(dmap)
102	dbdma_regmap_t *dmap;
103{
104	out32rb(&dmap->d_control,
105		DBDMA_SET_CNTRL(DBDMA_CNTRL_RUN | DBDMA_CNTRL_WAKE) |
106		DBDMA_CLEAR_CNTRL(DBDMA_CNTRL_PAUSE | DBDMA_CNTRL_DEAD));
107}
108
109void
110dbdma_pause(dmap)
111	dbdma_regmap_t *dmap;
112{
113	DBDMA_ST4_ENDIAN(&dmap->d_control,DBDMA_SET_CNTRL(DBDMA_CNTRL_PAUSE));
114	eieio();
115
116	while (DBDMA_LD4_ENDIAN(&dmap->d_status) & DBDMA_CNTRL_ACTIVE)
117		eieio();
118}
119
120dbdma_command_t	*
121dbdma_alloc(size)
122	int size;
123{
124	u_int buf;
125
126	buf = (u_int)malloc(size + 0x0f, M_DEVBUF, M_WAITOK);
127	buf = (buf + 0x0f) & ~0x0f;
128
129	return (dbdma_command_t *)buf;
130}
131