xref: /rk3399_rockchip-uboot/drivers/usb/musb-new/musb_dma.h (revision ea3310e8aafad1da72d9a5e60568d725cbdefdbd)
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