blob: 51289c0b277e3970c24c498529b6b150309ad2ea [file] [log] [blame]
Greg Kroah-Hartman5fd54ac2017-11-03 11:28:30 +01001// SPDX-License-Identifier: GPL-2.0
Bryan Wu6995eb62008-12-02 21:33:47 +02002/*
3 * MUSB OTG driver - support for Mentor's DMA controller
4 *
5 * Copyright 2005 Mentor Graphics Corporation
6 * Copyright (C) 2005-2007 by Texas Instruments
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
25 * NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
Bryan Wu6995eb62008-12-02 21:33:47 +020035#ifndef CONFIG_BLACKFIN
36
37#define MUSB_HSDMA_BASE 0x200
38#define MUSB_HSDMA_INTR (MUSB_HSDMA_BASE + 0)
39#define MUSB_HSDMA_CONTROL 0x4
40#define MUSB_HSDMA_ADDRESS 0x8
41#define MUSB_HSDMA_COUNT 0xc
42
43#define MUSB_HSDMA_CHANNEL_OFFSET(_bchannel, _offset) \
44 (MUSB_HSDMA_BASE + (_bchannel << 4) + _offset)
45
46#define musb_read_hsdma_addr(mbase, bchannel) \
47 musb_readl(mbase, \
48 MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS))
49
50#define musb_write_hsdma_addr(mbase, bchannel, addr) \
51 musb_writel(mbase, \
52 MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS), \
53 addr)
54
Anand Gadiyar452f0392009-12-28 13:40:35 +020055#define musb_read_hsdma_count(mbase, bchannel) \
56 musb_readl(mbase, \
57 MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT))
58
Bryan Wu6995eb62008-12-02 21:33:47 +020059#define musb_write_hsdma_count(mbase, bchannel, len) \
60 musb_writel(mbase, \
61 MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT), \
62 len)
63#else
64
65#define MUSB_HSDMA_BASE 0x400
66#define MUSB_HSDMA_INTR (MUSB_HSDMA_BASE + 0)
67#define MUSB_HSDMA_CONTROL 0x04
68#define MUSB_HSDMA_ADDR_LOW 0x08
69#define MUSB_HSDMA_ADDR_HIGH 0x0C
70#define MUSB_HSDMA_COUNT_LOW 0x10
71#define MUSB_HSDMA_COUNT_HIGH 0x14
72
73#define MUSB_HSDMA_CHANNEL_OFFSET(_bchannel, _offset) \
74 (MUSB_HSDMA_BASE + (_bchannel * 0x20) + _offset)
75
76static inline u32 musb_read_hsdma_addr(void __iomem *mbase, u8 bchannel)
77{
78 u32 addr = musb_readw(mbase,
79 MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_HIGH));
80
81 addr = addr << 16;
82
83 addr |= musb_readw(mbase,
84 MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_LOW));
85
86 return addr;
87}
88
89static inline void musb_write_hsdma_addr(void __iomem *mbase,
90 u8 bchannel, dma_addr_t dma_addr)
91{
92 musb_writew(mbase,
93 MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_LOW),
Bob Liu9c668072011-01-05 17:36:41 +080094 dma_addr);
Bryan Wu6995eb62008-12-02 21:33:47 +020095 musb_writew(mbase,
96 MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_HIGH),
Bob Liu9c668072011-01-05 17:36:41 +080097 (dma_addr >> 16));
Bryan Wu6995eb62008-12-02 21:33:47 +020098}
99
Anand Gadiyar452f0392009-12-28 13:40:35 +0200100static inline u32 musb_read_hsdma_count(void __iomem *mbase, u8 bchannel)
101{
Bob Liu9c668072011-01-05 17:36:41 +0800102 u32 count = musb_readw(mbase,
Anand Gadiyar452f0392009-12-28 13:40:35 +0200103 MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_HIGH));
Bob Liu9c668072011-01-05 17:36:41 +0800104
105 count = count << 16;
106
107 count |= musb_readw(mbase,
108 MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_LOW));
109
110 return count;
Anand Gadiyar452f0392009-12-28 13:40:35 +0200111}
112
Bryan Wu6995eb62008-12-02 21:33:47 +0200113static inline void musb_write_hsdma_count(void __iomem *mbase,
114 u8 bchannel, u32 len)
115{
Bob Liu9c668072011-01-05 17:36:41 +0800116 musb_writew(mbase,
117 MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_LOW),len);
118 musb_writew(mbase,
Bryan Wu6995eb62008-12-02 21:33:47 +0200119 MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_HIGH),
Bob Liu9c668072011-01-05 17:36:41 +0800120 (len >> 16));
Bryan Wu6995eb62008-12-02 21:33:47 +0200121}
122
123#endif /* CONFIG_BLACKFIN */
124
125/* control register (16-bit): */
126#define MUSB_HSDMA_ENABLE_SHIFT 0
127#define MUSB_HSDMA_TRANSMIT_SHIFT 1
128#define MUSB_HSDMA_MODE1_SHIFT 2
129#define MUSB_HSDMA_IRQENABLE_SHIFT 3
130#define MUSB_HSDMA_ENDPOINT_SHIFT 4
131#define MUSB_HSDMA_BUSERROR_SHIFT 8
132#define MUSB_HSDMA_BURSTMODE_SHIFT 9
133#define MUSB_HSDMA_BURSTMODE (3 << MUSB_HSDMA_BURSTMODE_SHIFT)
134#define MUSB_HSDMA_BURSTMODE_UNSPEC 0
135#define MUSB_HSDMA_BURSTMODE_INCR4 1
136#define MUSB_HSDMA_BURSTMODE_INCR8 2
137#define MUSB_HSDMA_BURSTMODE_INCR16 3
138
139#define MUSB_HSDMA_CHANNELS 8
140
141struct musb_dma_controller;
142
143struct musb_dma_channel {
144 struct dma_channel channel;
145 struct musb_dma_controller *controller;
146 u32 start_addr;
147 u32 len;
148 u16 max_packet_sz;
149 u8 idx;
150 u8 epnum;
151 u8 transmit;
152};
153
154struct musb_dma_controller {
155 struct dma_controller controller;
156 struct musb_dma_channel channel[MUSB_HSDMA_CHANNELS];
157 void *private_data;
158 void __iomem *base;
159 u8 channel_count;
160 u8 used_channels;
Tony Lindgren8c300fe2017-01-03 18:13:48 -0600161 int irq;
Bryan Wu6995eb62008-12-02 21:33:47 +0200162};