1179644Smarcel/*-
2179644Smarcel * Copyright (c) 2008 Nathan Whitehorn
3179644Smarcel * All rights reserved
4179644Smarcel *
5179644Smarcel * Redistribution and use in source and binary forms, with or without
6179644Smarcel * modification, are permitted provided that the following conditions
7179644Smarcel * are met:
8179644Smarcel * 1. Redistributions of source code must retain the above copyright
9179644Smarcel *    notice, this list of conditions and the following disclaimer.
10179644Smarcel * 2. Redistributions in binary form must reproduce the above copyright
11179644Smarcel *    notice, this list of conditions and the following disclaimer in the
12179644Smarcel *    documentation and/or other materials provided with the distribution.
13179644Smarcel *
14179644Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15179644Smarcel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16179644Smarcel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17179644Smarcel * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18179644Smarcel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19179644Smarcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20179644Smarcel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21179644Smarcel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22179644Smarcel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23179644Smarcel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24179644Smarcel * SUCH DAMAGE.
25179644Smarcel *
26179644Smarcel * $FreeBSD$
27179644Smarcel */
28179644Smarcel
29179644Smarcel#ifndef _MACHINE_DBDMA_H_
30179644Smarcel#define _MACHINE_DBDMA_H_
31179644Smarcel
32179644Smarcel#include <sys/param.h>
33179644Smarcel#include <machine/bus.h>
34179644Smarcel
35179644Smarcel/*
36179644Smarcel * Apple's DBDMA (Descriptor-based DMA) interface is a common DMA engine
37179644Smarcel * used by a variety of custom Apple ASICs. It is described in the CHRP
38179644Smarcel * specification and in the book Macintosh Technology in the Common
39179644Smarcel * Hardware Reference Platform, copyright 1995 Apple Computer.
40179644Smarcel */
41179644Smarcel
42179644Smarcel/* DBDMA Command Values */
43179644Smarcel
44179644Smarcelenum {
45179644Smarcel	DBDMA_OUTPUT_MORE	= 0,
46179644Smarcel	DBDMA_OUTPUT_LAST	= 1,
47179644Smarcel	DBDMA_INPUT_MORE	= 2,
48179644Smarcel	DBDMA_INPUT_LAST	= 3,
49179644Smarcel
50179644Smarcel	DBDMA_STORE_QUAD	= 4,
51179644Smarcel	DBDMA_LOAD_QUAD		= 5,
52179644Smarcel	DBDMA_NOP		= 6,
53179644Smarcel	DBDMA_STOP		= 7
54179644Smarcel};
55179644Smarcel
56179644Smarcel/* These codes are for the interrupt, branch, and wait flags */
57179644Smarcel
58179644Smarcelenum {
59179644Smarcel	DBDMA_NEVER		= 0,
60179644Smarcel	DBDMA_COND_TRUE		= 1,
61179644Smarcel	DBDMA_COND_FALSE	= 2,
62179644Smarcel	DBDMA_ALWAYS		= 3
63179644Smarcel};
64179644Smarcel
65179644Smarcel/* Channel status bits */
66179644Smarcel#define DBDMA_STATUS_RUN    (0x01 << 15)
67179644Smarcel#define DBDMA_STATUS_PAUSE  (0x01 << 14)
68179644Smarcel#define DBDMA_STATUS_FLUSH  (0x01 << 13)
69179644Smarcel#define DBDMA_STATUS_WAKE   (0x01 << 12)
70179644Smarcel#define DBDMA_STATUS_DEAD   (0x01 << 11)
71179644Smarcel#define DBDMA_STATUS_ACTIVE (0x01 << 10)
72179644Smarcel
73179644Smarcel/* Set by hardware if a branch was taken */
74179644Smarcel#define DBDMA_STATUS_BRANCH 8
75179644Smarcel
76179644Smarcelstruct dbdma_command;
77179644Smarceltypedef struct dbdma_command dbdma_command_t;
78179644Smarcelstruct dbdma_channel;
79179644Smarceltypedef struct dbdma_channel dbdma_channel_t;
80179644Smarcel
81183288Snwhitehornint dbdma_allocate_channel(struct resource *dbdma_regs, u_int offset,
82179644Smarcel    bus_dma_tag_t parent_dma, int slots, dbdma_channel_t **chan);
83179644Smarcel
84179644Smarcelint dbdma_resize_channel(dbdma_channel_t *chan, int newslots);
85179644Smarcelint dbdma_free_channel(dbdma_channel_t *chan);
86179644Smarcel
87179644Smarcelvoid dbdma_run(dbdma_channel_t *chan);
88179644Smarcelvoid dbdma_stop(dbdma_channel_t *chan);
89179644Smarcelvoid dbdma_reset(dbdma_channel_t *chan);
90179644Smarcelvoid dbdma_set_current_cmd(dbdma_channel_t *chan, int slot);
91179644Smarcel
92179644Smarcelvoid dbdma_pause(dbdma_channel_t *chan);
93179644Smarcelvoid dbdma_wake(dbdma_channel_t *chan);
94179644Smarcel
95183411Snwhitehorn/*
96183411Snwhitehorn * DBDMA uses a 16 bit channel control register to describe the current
97183411Snwhitehorn * state of DMA on the channel. The high-order bits (8-15) contain information
98183411Snwhitehorn * on the run state and are listed in the DBDMA_STATUS_* constants above. These
99183411Snwhitehorn * are manipulated with the dbdma_run/stop/reset() routines above.
100183411Snwhitehorn *
101183411Snwhitehorn * The low order bits (0-7) are device dependent status bits. These can be set
102183411Snwhitehorn * and read by both hardware and software. The mask is the set of bits to
103183411Snwhitehorn * modify; if mask is 0x03 and value is 0, the lowest order 2 bits will be
104183411Snwhitehorn * zeroed.
105183411Snwhitehorn */
106183411Snwhitehorn
107179644Smarceluint16_t dbdma_get_chan_status(dbdma_channel_t *chan);
108179644Smarcel
109183411Snwhitehornuint8_t dbdma_get_device_status(dbdma_channel_t *chan);
110183411Snwhitehornvoid dbdma_set_device_status(dbdma_channel_t *chan, uint8_t mask,
111183411Snwhitehorn    uint8_t value);
112183411Snwhitehorn
113183411Snwhitehorn/*
114183411Snwhitehorn * Each DBDMA command word has the current channel status register and the
115183411Snwhitehorn * number of residual bytes (requested - actually transferred) written to it
116183411Snwhitehorn * at time of command completion.
117183411Snwhitehorn */
118183411Snwhitehorn
119183411Snwhitehornuint16_t dbdma_get_cmd_status(dbdma_channel_t *chan, int slot);
120183411Snwhitehornuint16_t dbdma_get_residuals(dbdma_channel_t *chan, int slot);
121183411Snwhitehorn
122183411Snwhitehornvoid dbdma_clear_cmd_status(dbdma_channel_t *chan, int slot);
123183411Snwhitehorn
124183411Snwhitehorn/*
125183411Snwhitehorn * The interrupt/branch/wait selector let you specify a set of values
126183411Snwhitehorn * of the device dependent status bits that will cause intterupt/branch/wait
127183411Snwhitehorn * conditions to be taken if the flags for these are set to one of the
128183411Snwhitehorn * DBDMA_COND_* values.
129183411Snwhitehorn *
130183411Snwhitehorn * The condition is considered true if (status & mask) == value.
131183411Snwhitehorn */
132183411Snwhitehorn
133179644Smarcelvoid dbdma_set_interrupt_selector(dbdma_channel_t *chan, uint8_t mask,
134179644Smarcel    uint8_t value);
135179644Smarcelvoid dbdma_set_branch_selector(dbdma_channel_t *chan, uint8_t mask,
136179644Smarcel    uint8_t value);
137179644Smarcelvoid dbdma_set_wait_selector(dbdma_channel_t *chan, uint8_t mask,
138179644Smarcel    uint8_t value);
139179644Smarcel
140179644Smarcelvoid dbdma_insert_command(dbdma_channel_t *chan, int slot, int command,
141179644Smarcel    int stream, bus_addr_t data, size_t count, uint8_t interrupt,
142179644Smarcel    uint8_t branch, uint8_t wait, uint32_t branch_slot);
143179644Smarcel
144179644Smarcelvoid dbdma_insert_stop(dbdma_channel_t *chan, int slot);
145179644Smarcelvoid dbdma_insert_nop(dbdma_channel_t *chan, int slot);
146179644Smarcelvoid dbdma_insert_branch(dbdma_channel_t *chan, int slot, int to_slot);
147179644Smarcel
148179644Smarcelvoid dbdma_sync_commands(dbdma_channel_t *chan, bus_dmasync_op_t op);
149179644Smarcel
150259284Sjhibbitsvoid dbdma_save_state(dbdma_channel_t *chan);
151259284Sjhibbitsvoid dbdma_restore_state(dbdma_channel_t *chan);
152259284Sjhibbits
153179644Smarcel#endif /* _MACHINE_DBDMA_H_ */
154