1 /******************************************************************
2 * Copyright 2005 Mentor Graphics Corporation
3 * Copyright (C) 2005-2006 by Texas Instruments
5 * This file is part of the Inventra Controller Driver for Linux.
7 * The Inventra Controller Driver for Linux is free software; you
8 * can redistribute it and/or modify it under the terms of the GNU
9 * General Public License version 2 as published by the Free Software
12 * The Inventra Controller Driver for Linux is distributed in
13 * the hope that it will be useful, but WITHOUT ANY WARRANTY;
14 * without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 * License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with The Inventra Controller Driver for Linux ; if not,
20 * write to the Free Software Foundation, Inc., 59 Temple Place,
21 * Suite 330, Boston, MA 02111-1307 USA
23 * ANY DOWNLOAD, USE, REPRODUCTION, MODIFICATION OR DISTRIBUTION
24 * OF THIS DRIVER INDICATES YOUR COMPLETE AND UNCONDITIONAL ACCEPTANCE
25 * OF THOSE TERMS.THIS DRIVER IS PROVIDED "AS IS" AND MENTOR GRAPHICS
26 * MAKES NO WARRANTIES, EXPRESS OR IMPLIED, RELATED TO THIS DRIVER.
27 * MENTOR GRAPHICS SPECIFICALLY DISCLAIMS ALL IMPLIED WARRANTIES
28 * OF MERCHANTABILITY; FITNESS FOR A PARTICULAR PURPOSE AND
29 * NON-INFRINGEMENT. MENTOR GRAPHICS DOES NOT PROVIDE SUPPORT
30 * SERVICES OR UPDATES FOR THIS DRIVER, EVEN IF YOU ARE A MENTOR
31 * GRAPHICS SUPPORT CUSTOMER.
32 ******************************************************************/
34 #ifndef __MUSB_DMA_H__
35 #define __MUSB_DMA_H__
40 * DMA Controller Abstraction
42 * DMA Controllers are abstracted to allow use of a variety of different
43 * implementations of DMA, as allowed by the Inventra USB cores. On the
44 * host side, usbcore sets up the DMA mappings and flushes caches; on the
45 * peripheral side, the gadget controller driver does. Responsibilities
46 * of a DMA controller driver include:
48 * - Handling the details of moving multiple USB packets
49 * in cooperation with the Inventra USB core, including especially
50 * the correct RX side treatment of short packets and buffer-full
51 * states (both of which terminate transfers).
53 * - Knowing the correlation between dma channels and the
54 * Inventra core's local endpoint resources and data direction.
56 * - Maintaining a list of allocated/available channels.
58 * - Updating channel status on interrupts,
59 * whether shared with the Inventra core or separate.
62 #define DMA_ADDR_INVALID (~(dma_addr_t)0)
64 #ifndef CONFIG_USB_INVENTRA_FIFO
65 #define is_dma_capable() (1)
67 #define is_dma_capable() (0)
70 #ifdef CONFIG_USB_TI_CPPI_DMA
71 #define is_cppi_enabled() 1
73 #define is_cppi_enabled() 0
78 * DMA channel status ... updated by the dma controller driver whenever that
79 * status changes, and protected by the overall controller spinlock.
81 enum dma_channel_status {
83 MGC_DMA_STATUS_UNKNOWN,
84 /* allocated ... but not busy, no errors */
86 /* busy ... transactions are active */
88 /* transaction(s) aborted due to ... dma or memory bus error */
89 MGC_DMA_STATUS_BUS_ABORT,
90 /* transaction(s) aborted due to ... core error or USB fault */
91 MGC_DMA_STATUS_CORE_ABORT
94 struct dma_controller;
97 * struct dma_channel - A DMA channel.
98 * @pPrivateData: channel-private data
99 * @wMaxLength: the maximum number of bytes the channel can move in one
100 * transaction (typically representing many USB maximum-sized packets)
101 * @dwActualLength: how many bytes have been transferred
102 * @bStatus: current channel status (updated e.g. on interrupt)
103 * @bDesiredMode: TRUE if mode 1 is desired; FALSE if mode 0 is desired
105 * channels are associated with an endpoint for the duration of at least
110 // FIXME not void* private_data, but a dma_controller *
112 size_t dwActualLength;
113 enum dma_channel_status bStatus;
118 * Program a DMA channel to move data at the core's request.
119 * The local core endpoint and direction should already be known,
120 * since they are specified in the channel_alloc call.
122 * @channel: pointer to a channel obtained by channel_alloc
123 * @maxpacket: the maximum packet size
124 * @bMode: TRUE if mode 1; FALSE if mode 0
125 * @dma_addr: base address of data (in DMA space)
126 * @length: the number of bytes to transfer; no larger than the channel's
127 * reported dwMaxLength
129 * Returns TRUE on success, else FALSE
131 typedef int (*MGC_pfDmaProgramChannel) (
132 struct dma_channel *channel,
139 * dma_channel_status - return status of dma channel
142 * Returns the software's view of the channel status. If that status is BUSY
143 * then it's possible that the hardware has completed (or aborted) a transfer,
144 * so the driver needs to update that status.
146 static inline enum dma_channel_status
147 dma_channel_status(struct dma_channel *c)
149 return (is_dma_capable() && c) ? c->bStatus : MGC_DMA_STATUS_UNKNOWN;
153 * struct dma_controller - A DMA Controller.
154 * @pPrivateData: controller-private data;
155 * @start: call this to start a DMA controller;
156 * return 0 on success, else negative errno
157 * @stop: call this to stop a DMA controller
158 * return 0 on success, else negative errno
159 * @channel_alloc: call this to allocate a DMA channel
160 * @channel_release: call this to release a DMA channel
161 * @channel_abort: call this to abort a pending DMA transaction,
162 * returning it to FREE (but allocated) state
164 * Controllers manage dma channels.
166 struct dma_controller {
168 int (*start)(struct dma_controller *);
169 int (*stop)(struct dma_controller *);
170 struct dma_channel *(*channel_alloc)(struct dma_controller *,
171 struct musb_hw_ep *, u8 is_tx);
172 void (*channel_release)(struct dma_channel *);
173 MGC_pfDmaProgramChannel channel_program;
174 int (*channel_abort)(struct dma_channel *);
177 /* called after channel_program(), may indicate a fault */
178 extern void musb_dma_completion(struct musb *musb, u8 bLocalEnd, u8 bTransmit);
181 extern struct dma_controller *__init
182 dma_controller_create(struct musb *, void __iomem *);
184 extern void dma_controller_destroy(struct dma_controller *);
186 #endif /* __MUSB_DMA_H__ */