1eb81955bSIlya Yanok /*
2eb81955bSIlya Yanok * MUSB OTG driver DMA controller abstraction
3eb81955bSIlya Yanok *
4eb81955bSIlya Yanok * Copyright 2005 Mentor Graphics Corporation
5eb81955bSIlya Yanok * Copyright (C) 2005-2006 by Texas Instruments
6eb81955bSIlya Yanok * Copyright (C) 2006-2007 Nokia Corporation
7eb81955bSIlya Yanok *
8*5b8031ccSTom Rini * SPDX-License-Identifier: GPL-2.0
9eb81955bSIlya Yanok */
10eb81955bSIlya Yanok
11eb81955bSIlya Yanok #ifndef __MUSB_DMA_H__
12eb81955bSIlya Yanok #define __MUSB_DMA_H__
13eb81955bSIlya Yanok
14eb81955bSIlya Yanok struct musb_hw_ep;
15eb81955bSIlya Yanok
16eb81955bSIlya Yanok /*
17eb81955bSIlya Yanok * DMA Controller Abstraction
18eb81955bSIlya Yanok *
19eb81955bSIlya Yanok * DMA Controllers are abstracted to allow use of a variety of different
20eb81955bSIlya Yanok * implementations of DMA, as allowed by the Inventra USB cores. On the
21eb81955bSIlya Yanok * host side, usbcore sets up the DMA mappings and flushes caches; on the
22eb81955bSIlya Yanok * peripheral side, the gadget controller driver does. Responsibilities
23eb81955bSIlya Yanok * of a DMA controller driver include:
24eb81955bSIlya Yanok *
25eb81955bSIlya Yanok * - Handling the details of moving multiple USB packets
26eb81955bSIlya Yanok * in cooperation with the Inventra USB core, including especially
27eb81955bSIlya Yanok * the correct RX side treatment of short packets and buffer-full
28eb81955bSIlya Yanok * states (both of which terminate transfers).
29eb81955bSIlya Yanok *
30eb81955bSIlya Yanok * - Knowing the correlation between dma channels and the
31eb81955bSIlya Yanok * Inventra core's local endpoint resources and data direction.
32eb81955bSIlya Yanok *
33eb81955bSIlya Yanok * - Maintaining a list of allocated/available channels.
34eb81955bSIlya Yanok *
35eb81955bSIlya Yanok * - Updating channel status on interrupts,
36eb81955bSIlya Yanok * whether shared with the Inventra core or separate.
37eb81955bSIlya Yanok */
38eb81955bSIlya Yanok
39eb81955bSIlya Yanok #define DMA_ADDR_INVALID (~(dma_addr_t)0)
40eb81955bSIlya Yanok
4195de1e2fSPaul Kocialkowski #ifndef CONFIG_USB_MUSB_PIO_ONLY
42eb81955bSIlya Yanok #define is_dma_capable() (1)
43eb81955bSIlya Yanok #else
44eb81955bSIlya Yanok #define is_dma_capable() (0)
45eb81955bSIlya Yanok #endif
46eb81955bSIlya Yanok
47eb81955bSIlya Yanok #ifdef CONFIG_USB_TI_CPPI_DMA
48eb81955bSIlya Yanok #define is_cppi_enabled() 1
49eb81955bSIlya Yanok #else
50eb81955bSIlya Yanok #define is_cppi_enabled() 0
51eb81955bSIlya Yanok #endif
52eb81955bSIlya Yanok
53eb81955bSIlya Yanok #ifdef CONFIG_USB_TUSB_OMAP_DMA
54eb81955bSIlya Yanok #define tusb_dma_omap() 1
55eb81955bSIlya Yanok #else
56eb81955bSIlya Yanok #define tusb_dma_omap() 0
57eb81955bSIlya Yanok #endif
58eb81955bSIlya Yanok
59eb81955bSIlya Yanok /*
60eb81955bSIlya Yanok * DMA channel status ... updated by the dma controller driver whenever that
61eb81955bSIlya Yanok * status changes, and protected by the overall controller spinlock.
62eb81955bSIlya Yanok */
63eb81955bSIlya Yanok enum dma_channel_status {
64eb81955bSIlya Yanok /* unallocated */
65eb81955bSIlya Yanok MUSB_DMA_STATUS_UNKNOWN,
66eb81955bSIlya Yanok /* allocated ... but not busy, no errors */
67eb81955bSIlya Yanok MUSB_DMA_STATUS_FREE,
68eb81955bSIlya Yanok /* busy ... transactions are active */
69eb81955bSIlya Yanok MUSB_DMA_STATUS_BUSY,
70eb81955bSIlya Yanok /* transaction(s) aborted due to ... dma or memory bus error */
71eb81955bSIlya Yanok MUSB_DMA_STATUS_BUS_ABORT,
72eb81955bSIlya Yanok /* transaction(s) aborted due to ... core error or USB fault */
73eb81955bSIlya Yanok MUSB_DMA_STATUS_CORE_ABORT
74eb81955bSIlya Yanok };
75eb81955bSIlya Yanok
76eb81955bSIlya Yanok struct dma_controller;
77eb81955bSIlya Yanok
78eb81955bSIlya Yanok /**
79eb81955bSIlya Yanok * struct dma_channel - A DMA channel.
80eb81955bSIlya Yanok * @private_data: channel-private data
81eb81955bSIlya Yanok * @max_len: the maximum number of bytes the channel can move in one
82eb81955bSIlya Yanok * transaction (typically representing many USB maximum-sized packets)
83eb81955bSIlya Yanok * @actual_len: how many bytes have been transferred
84eb81955bSIlya Yanok * @status: current channel status (updated e.g. on interrupt)
85eb81955bSIlya Yanok * @desired_mode: true if mode 1 is desired; false if mode 0 is desired
86eb81955bSIlya Yanok *
87eb81955bSIlya Yanok * channels are associated with an endpoint for the duration of at least
88eb81955bSIlya Yanok * one usb transfer.
89eb81955bSIlya Yanok */
90eb81955bSIlya Yanok struct dma_channel {
91eb81955bSIlya Yanok void *private_data;
92eb81955bSIlya Yanok /* FIXME not void* private_data, but a dma_controller * */
93eb81955bSIlya Yanok size_t max_len;
94eb81955bSIlya Yanok size_t actual_len;
95eb81955bSIlya Yanok enum dma_channel_status status;
96eb81955bSIlya Yanok bool desired_mode;
97eb81955bSIlya Yanok };
98eb81955bSIlya Yanok
99eb81955bSIlya Yanok /*
100eb81955bSIlya Yanok * dma_channel_status - return status of dma channel
101eb81955bSIlya Yanok * @c: the channel
102eb81955bSIlya Yanok *
103eb81955bSIlya Yanok * Returns the software's view of the channel status. If that status is BUSY
104eb81955bSIlya Yanok * then it's possible that the hardware has completed (or aborted) a transfer,
105eb81955bSIlya Yanok * so the driver needs to update that status.
106eb81955bSIlya Yanok */
107eb81955bSIlya Yanok static inline enum dma_channel_status
dma_channel_status(struct dma_channel * c)108eb81955bSIlya Yanok dma_channel_status(struct dma_channel *c)
109eb81955bSIlya Yanok {
110eb81955bSIlya Yanok return (is_dma_capable() && c) ? c->status : MUSB_DMA_STATUS_UNKNOWN;
111eb81955bSIlya Yanok }
112eb81955bSIlya Yanok
113eb81955bSIlya Yanok /**
114eb81955bSIlya Yanok * struct dma_controller - A DMA Controller.
115eb81955bSIlya Yanok * @start: call this to start a DMA controller;
116eb81955bSIlya Yanok * return 0 on success, else negative errno
117eb81955bSIlya Yanok * @stop: call this to stop a DMA controller
118eb81955bSIlya Yanok * return 0 on success, else negative errno
119eb81955bSIlya Yanok * @channel_alloc: call this to allocate a DMA channel
120eb81955bSIlya Yanok * @channel_release: call this to release a DMA channel
121eb81955bSIlya Yanok * @channel_abort: call this to abort a pending DMA transaction,
122eb81955bSIlya Yanok * returning it to FREE (but allocated) state
123eb81955bSIlya Yanok *
124eb81955bSIlya Yanok * Controllers manage dma channels.
125eb81955bSIlya Yanok */
126eb81955bSIlya Yanok struct dma_controller {
127eb81955bSIlya Yanok int (*start)(struct dma_controller *);
128eb81955bSIlya Yanok int (*stop)(struct dma_controller *);
129eb81955bSIlya Yanok struct dma_channel *(*channel_alloc)(struct dma_controller *,
130eb81955bSIlya Yanok struct musb_hw_ep *, u8 is_tx);
131eb81955bSIlya Yanok void (*channel_release)(struct dma_channel *);
132eb81955bSIlya Yanok int (*channel_program)(struct dma_channel *channel,
133eb81955bSIlya Yanok u16 maxpacket, u8 mode,
134eb81955bSIlya Yanok dma_addr_t dma_addr,
135eb81955bSIlya Yanok u32 length);
136eb81955bSIlya Yanok int (*channel_abort)(struct dma_channel *);
137eb81955bSIlya Yanok int (*is_compatible)(struct dma_channel *channel,
138eb81955bSIlya Yanok u16 maxpacket,
139eb81955bSIlya Yanok void *buf, u32 length);
140eb81955bSIlya Yanok };
141eb81955bSIlya Yanok
142eb81955bSIlya Yanok /* called after channel_program(), may indicate a fault */
143eb81955bSIlya Yanok extern void musb_dma_completion(struct musb *musb, u8 epnum, u8 transmit);
144eb81955bSIlya Yanok
145eb81955bSIlya Yanok
146eb81955bSIlya Yanok extern struct dma_controller *__init
147eb81955bSIlya Yanok dma_controller_create(struct musb *, void __iomem *);
148eb81955bSIlya Yanok
149eb81955bSIlya Yanok extern void dma_controller_destroy(struct dma_controller *);
150eb81955bSIlya Yanok
151eb81955bSIlya Yanok #endif /* __MUSB_DMA_H__ */
152