Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0
2/*
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
9#ifndef CONFIG_BLACKFIN
10
11#define MUSB_HSDMA_BASE 0x200
12#define MUSB_HSDMA_INTR (MUSB_HSDMA_BASE + 0)
13#define MUSB_HSDMA_CONTROL 0x4
14#define MUSB_HSDMA_ADDRESS 0x8
15#define MUSB_HSDMA_COUNT 0xc
16
17#define MUSB_HSDMA_CHANNEL_OFFSET(_bchannel, _offset) \
18 (MUSB_HSDMA_BASE + (_bchannel << 4) + _offset)
19
20#define musb_read_hsdma_addr(mbase, bchannel) \
21 musb_readl(mbase, \
22 MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS))
23
24#define musb_write_hsdma_addr(mbase, bchannel, addr) \
25 musb_writel(mbase, \
26 MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS), \
27 addr)
28
29#define musb_read_hsdma_count(mbase, bchannel) \
30 musb_readl(mbase, \
31 MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT))
32
33#define musb_write_hsdma_count(mbase, bchannel, len) \
34 musb_writel(mbase, \
35 MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT), \
36 len)
37#else
38
39#define MUSB_HSDMA_BASE 0x400
40#define MUSB_HSDMA_INTR (MUSB_HSDMA_BASE + 0)
41#define MUSB_HSDMA_CONTROL 0x04
42#define MUSB_HSDMA_ADDR_LOW 0x08
43#define MUSB_HSDMA_ADDR_HIGH 0x0C
44#define MUSB_HSDMA_COUNT_LOW 0x10
45#define MUSB_HSDMA_COUNT_HIGH 0x14
46
47#define MUSB_HSDMA_CHANNEL_OFFSET(_bchannel, _offset) \
48 (MUSB_HSDMA_BASE + (_bchannel * 0x20) + _offset)
49
50static inline u32 musb_read_hsdma_addr(void __iomem *mbase, u8 bchannel)
51{
52 u32 addr = musb_readw(mbase,
53 MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_HIGH));
54
55 addr = addr << 16;
56
57 addr |= musb_readw(mbase,
58 MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_LOW));
59
60 return addr;
61}
62
63static inline void musb_write_hsdma_addr(void __iomem *mbase,
64 u8 bchannel, dma_addr_t dma_addr)
65{
66 musb_writew(mbase,
67 MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_LOW),
68 dma_addr);
69 musb_writew(mbase,
70 MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDR_HIGH),
71 (dma_addr >> 16));
72}
73
74static inline u32 musb_read_hsdma_count(void __iomem *mbase, u8 bchannel)
75{
76 u32 count = musb_readw(mbase,
77 MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_HIGH));
78
79 count = count << 16;
80
81 count |= musb_readw(mbase,
82 MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_LOW));
83
84 return count;
85}
86
87static inline void musb_write_hsdma_count(void __iomem *mbase,
88 u8 bchannel, u32 len)
89{
90 musb_writew(mbase,
91 MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_LOW),len);
92 musb_writew(mbase,
93 MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT_HIGH),
94 (len >> 16));
95}
96
97#endif /* CONFIG_BLACKFIN */
98
99/* control register (16-bit): */
100#define MUSB_HSDMA_ENABLE_SHIFT 0
101#define MUSB_HSDMA_TRANSMIT_SHIFT 1
102#define MUSB_HSDMA_MODE1_SHIFT 2
103#define MUSB_HSDMA_IRQENABLE_SHIFT 3
104#define MUSB_HSDMA_ENDPOINT_SHIFT 4
105#define MUSB_HSDMA_BUSERROR_SHIFT 8
106#define MUSB_HSDMA_BURSTMODE_SHIFT 9
107#define MUSB_HSDMA_BURSTMODE (3 << MUSB_HSDMA_BURSTMODE_SHIFT)
108#define MUSB_HSDMA_BURSTMODE_UNSPEC 0
109#define MUSB_HSDMA_BURSTMODE_INCR4 1
110#define MUSB_HSDMA_BURSTMODE_INCR8 2
111#define MUSB_HSDMA_BURSTMODE_INCR16 3
112
113#define MUSB_HSDMA_CHANNELS 8
114
115struct musb_dma_controller;
116
117struct musb_dma_channel {
118 struct dma_channel channel;
119 struct musb_dma_controller *controller;
120 u32 start_addr;
121 u32 len;
122 u16 max_packet_sz;
123 u8 idx;
124 u8 epnum;
125 u8 transmit;
126};
127
128struct musb_dma_controller {
129 struct dma_controller controller;
130 struct musb_dma_channel channel[MUSB_HSDMA_CHANNELS];
131 void *private_data;
132 void __iomem *base;
133 u8 channel_count;
134 u8 used_channels;
135 int irq;
136};