dbdma.h revision 259284
142649Simp/*-
241806Simp * Copyright (c) 2008 Nathan Whitehorn
3196789Simp * All rights reserved
4196789Simp *
5196789Simp * Redistribution and use in source and binary forms, with or without
6196789Simp * modification, are permitted provided that the following conditions
7243800Srwatson * are met:
842649Simp * 1. Redistributions of source code must retain the above copyright
9243800Srwatson *    notice, this list of conditions and the following disclaimer.
10243800Srwatson * 2. Redistributions in binary form must reproduce the above copyright
11132841Simp *    notice, this list of conditions and the following disclaimer in the
12196789Simp *    documentation and/or other materials provided with the distribution.
13132841Simp *
14249665Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15249735Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16256283Sgjb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17249714Simp * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18249665Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19279264Sdelphij * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20279264Sdelphij * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21279264Sdelphij * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22279264Sdelphij * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23279264Sdelphij * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24279264Sdelphij * SUCH DAMAGE.
25279264Sdelphij *
26279264Sdelphij * $FreeBSD: head/sys/powerpc/include/dbdma.h 259284 2013-12-13 02:37:35Z jhibbits $
27279264Sdelphij */
28279264Sdelphij
29279264Sdelphij#ifndef _MACHINE_DBDMA_H_
30279264Sdelphij#define _MACHINE_DBDMA_H_
31279264Sdelphij
32277808Sdelphij#include <sys/param.h>
33277808Sdelphij#include <machine/bus.h>
34277808Sdelphij
35277808Sdelphij/*
36277808Sdelphij * Apple's DBDMA (Descriptor-based DMA) interface is a common DMA engine
37277808Sdelphij * used by a variety of custom Apple ASICs. It is described in the CHRP
38277808Sdelphij * specification and in the book Macintosh Technology in the Common
39277808Sdelphij * Hardware Reference Platform, copyright 1995 Apple Computer.
40277195Sdelphij */
41277195Sdelphij
42277195Sdelphij/* DBDMA Command Values */
43276158Sdes
44276158Sdesenum {
45276158Sdes	DBDMA_OUTPUT_MORE	= 0,
46276158Sdes	DBDMA_OUTPUT_LAST	= 1,
47276158Sdes	DBDMA_INPUT_MORE	= 2,
48276158Sdes	DBDMA_INPUT_LAST	= 3,
49275854Sdelphij
50275854Sdelphij	DBDMA_STORE_QUAD	= 4,
51275854Sdelphij	DBDMA_LOAD_QUAD		= 5,
52275671Sdelphij	DBDMA_NOP		= 6,
53275671Sdelphij	DBDMA_STOP		= 7
54275671Sdelphij};
55274110Sdes
56274110Sdes/* These codes are for the interrupt, branch, and wait flags */
57274110Sdes
58274110Sdesenum {
59274110Sdes	DBDMA_NEVER		= 0,
60274110Sdes	DBDMA_COND_TRUE		= 1,
61274110Sdes	DBDMA_COND_FALSE	= 2,
62274110Sdes	DBDMA_ALWAYS		= 3
63274110Sdes};
64274110Sdes
65274110Sdes/* Channel status bits */
66274110Sdes#define DBDMA_STATUS_RUN    (0x01 << 15)
67274110Sdes#define DBDMA_STATUS_PAUSE  (0x01 << 14)
68274110Sdes#define DBDMA_STATUS_FLUSH  (0x01 << 13)
69273439Sdelphij#define DBDMA_STATUS_WAKE   (0x01 << 12)
70273439Sdelphij#define DBDMA_STATUS_DEAD   (0x01 << 11)
71273439Sdelphij#define DBDMA_STATUS_ACTIVE (0x01 << 10)
72273439Sdelphij
73273415Sdelphij/* Set by hardware if a branch was taken */
74273415Sdelphij#define DBDMA_STATUS_BRANCH 8
75273415Sdelphij
76273415Sdelphijstruct dbdma_command;
77273415Sdelphijtypedef struct dbdma_command dbdma_command_t;
78273415Sdelphijstruct dbdma_channel;
79273415Sdelphijtypedef struct dbdma_channel dbdma_channel_t;
80273415Sdelphij
81273415Sdelphijint dbdma_allocate_channel(struct resource *dbdma_regs, u_int offset,
82273415Sdelphij    bus_dma_tag_t parent_dma, int slots, dbdma_channel_t **chan);
83273415Sdelphij
84273415Sdelphijint dbdma_resize_channel(dbdma_channel_t *chan, int newslots);
85273415Sdelphijint dbdma_free_channel(dbdma_channel_t *chan);
86271669Sdelphij
87271669Sdelphijvoid dbdma_run(dbdma_channel_t *chan);
88271669Sdelphijvoid dbdma_stop(dbdma_channel_t *chan);
89271304Sdelphijvoid dbdma_reset(dbdma_channel_t *chan);
90271304Sdelphijvoid dbdma_set_current_cmd(dbdma_channel_t *chan, int slot);
91271304Sdelphij
92268434Sdelphijvoid dbdma_pause(dbdma_channel_t *chan);
93268434Sdelphijvoid dbdma_wake(dbdma_channel_t *chan);
94268434Sdelphij
95268434Sdelphij/*
96267829Sdelphij * DBDMA uses a 16 bit channel control register to describe the current
97267829Sdelphij * state of DMA on the channel. The high-order bits (8-15) contain information
98267829Sdelphij * on the run state and are listed in the DBDMA_STATUS_* constants above. These
99267829Sdelphij * are manipulated with the dbdma_run/stop/reset() routines above.
100267829Sdelphij *
101267829Sdelphij * The low order bits (0-7) are device dependent status bits. These can be set
102267829Sdelphij * and read by both hardware and software. The mask is the set of bits to
103267829Sdelphij * modify; if mask is 0x03 and value is 0, the lowest order 2 bits will be
104267829Sdelphij * zeroed.
105267829Sdelphij */
106267829Sdelphij
107267829Sdelphijuint16_t dbdma_get_chan_status(dbdma_channel_t *chan);
108267104Sdelphij
109267104Sdelphijuint8_t dbdma_get_device_status(dbdma_channel_t *chan);
110267104Sdelphijvoid dbdma_set_device_status(dbdma_channel_t *chan, uint8_t mask,
111267017Sdelphij    uint8_t value);
112267017Sdelphij
113267017Sdelphij/*
114267017Sdelphij * Each DBDMA command word has the current channel status register and the
115267017Sdelphij * number of residual bytes (requested - actually transferred) written to it
116267017Sdelphij * at time of command completion.
117267017Sdelphij */
118267017Sdelphij
119267017Sdelphijuint16_t dbdma_get_cmd_status(dbdma_channel_t *chan, int slot);
120267017Sdelphijuint16_t dbdma_get_residuals(dbdma_channel_t *chan, int slot);
121267017Sdelphij
122265987Sdelphijvoid dbdma_clear_cmd_status(dbdma_channel_t *chan, int slot);
123265987Sdelphij
124265987Sdelphij/*
125265987Sdelphij * The interrupt/branch/wait selector let you specify a set of values
126265987Sdelphij * of the device dependent status bits that will cause intterupt/branch/wait
127265987Sdelphij * conditions to be taken if the flags for these are set to one of the
128265987Sdelphij * DBDMA_COND_* values.
129265124Sdelphij *
130265124Sdelphij * The condition is considered true if (status & mask) == value.
131265124Sdelphij */
132265124Sdelphij
133265124Sdelphijvoid dbdma_set_interrupt_selector(dbdma_channel_t *chan, uint8_t mask,
134265124Sdelphij    uint8_t value);
135265124Sdelphijvoid dbdma_set_branch_selector(dbdma_channel_t *chan, uint8_t mask,
136265124Sdelphij    uint8_t value);
137265124Sdelphijvoid dbdma_set_wait_selector(dbdma_channel_t *chan, uint8_t mask,
138265124Sdelphij    uint8_t value);
139264267Sdelphij
140264267Sdelphijvoid dbdma_insert_command(dbdma_channel_t *chan, int slot, int command,
141264267Sdelphij    int stream, bus_addr_t data, size_t count, uint8_t interrupt,
142264267Sdelphij    uint8_t branch, uint8_t wait, uint32_t branch_slot);
143264267Sdelphij
144264267Sdelphijvoid dbdma_insert_stop(dbdma_channel_t *chan, int slot);
145259758Shrsvoid dbdma_insert_nop(dbdma_channel_t *chan, int slot);
146259758Shrsvoid dbdma_insert_branch(dbdma_channel_t *chan, int slot, int to_slot);
147259758Shrs
148259758Shrsvoid dbdma_sync_commands(dbdma_channel_t *chan, bus_dmasync_op_t op);
149259758Shrs
150259758Shrsvoid dbdma_save_state(dbdma_channel_t *chan);
151259758Shrsvoid dbdma_restore_state(dbdma_channel_t *chan);
152259758Shrs
153259758Shrs#endif /* _MACHINE_DBDMA_H_ */
154259758Shrs