1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
|
#ifndef _MTK_QMU_H_
#define _MTK_QMU_H_
#ifdef MUSB_QMU_SUPPORT
/* for musb_read/write api */
#include "mtk_musb.h"
#include "musb_debug.h"
#include "musb_io.h"
#include <linux/dmapool.h>
/* CUSTOM SETTING */
#define GPD_LEN_ALIGNED (64) /* > gpd len (16) and cache line size aligned */
#define GPD_EXT_LEN (48) /* GPD_LEN_ALIGNED - 16(should be sizeof(TGPD) */
#define GPD_SZ (16)
#define MAX_GPD_NUM 36
#define RXQ_NUM 8
#define TXQ_NUM 8
#define MAX_QMU_EP RXQ_NUM
#define TXQ 0
#define RXQ 1
/* QMU SETTING */
#define NO_ZLP 0
#define HW_MODE 1
#define GPD_MODE 2
//#define TXZLP GPD_MODE
//#define TXZLP HW_MODE
#define TXZLP NO_ZLP
//#define CFG_RX_ZLP_EN
//#define CFG_RX_COZ_EN
#define CFG_CS_CHECK
//#define CFG_EMPTY_CHECK
/* TGPD */
typedef struct _TGPD
{
u8 flag;
u8 chksum;
u16 DataBufferLen; /*Rx Allow Length*/
/* address field, 32-bit long */
u32 pNext;
u32 pBuf;
u16 bufLen;
u8 ExtLength;
u8 ZTepFlag;
}TGPD, *PGPD;
typedef struct _GPD_RANGE {
PGPD pNext;
PGPD pStart;
PGPD pEnd;
}GPD_R, *RGPD;
extern int mtk_qmu_dbg_level; /* refer to musb_core.c */
static inline int mtk_dbg_level(unsigned level)
{
return mtk_qmu_dbg_level >= level;
}
#define LOG_EMERG 0
#define LOG_ALERT 1
#define LOG_CRIT 2
#define LOG_ERR 3
#define LOG_WARN 4
#define LOG_NOTICE 5
#define LOG_INFO 6
#define LOG_DBG 7
#define QMU_DBG_ON
#ifdef QMU_DBG_ON
#define QMU_ERR(format, args...) do {if(mtk_dbg_level(LOG_ERR)){printk(KERN_WARNING "QMU_ERR,<%s %d>, " format , __func__, __LINE__ , ## args);}}while(0)
#define QMU_WARN(format, args...) do {if(mtk_dbg_level(LOG_WARN)){printk(KERN_WARNING "QMU_WARN,<%s %d>, " format , __func__, __LINE__ , ## args);}}while(0)
#define QMU_INFO(format, args...) do {if(mtk_dbg_level(LOG_INFO)){printk(KERN_WARNING "QMU_INFO,<%s %d>, " format , __func__, __LINE__ , ## args);}}while(0)
#define QMU_DBG(format, args...) do {if(mtk_dbg_level(LOG_DBG)){printk(KERN_WARNING "QMU_DBG,<%s %d>, " format , __func__, __LINE__ , ## args);}}while(0)
#else
#define QMU_ERR(format, args...) do {}while(0)
#define QMU_WARN(format, args...) do {}while(0)
#define QMU_INFO(format, args...) do {}while(0)
#define QMU_DBG(format, args...) do {}while(0)
#endif
/* QMU macros */
#define USB_HW_QMU_OFF 0x0000
#define USB_HW_QUCS_OFF 0x0300
#define USB_HW_QIRQ_OFF 0x0400
#define USB_HW_QDBG_OFF 0x04F0
#define MGC_O_QMU_QCR0 0x0000
#define MGC_O_QMU_QCR2 0x0008
#define MGC_O_QMU_QCR3 0x000C
#define MGC_O_QMU_RQCSR0 0x0010
#define MGC_O_QMU_RQSAR0 0x0014
#define MGC_O_QMU_RQCPR0 0x0018
#define MGC_O_QMU_RQCSR(n) (MGC_O_QMU_RQCSR0+0x0010*((n)-1))
#define MGC_O_QMU_RQSAR(n) (MGC_O_QMU_RQSAR0+0x0010*((n)-1))
#define MGC_O_QMU_RQCPR(n) (MGC_O_QMU_RQCPR0+0x0010*((n)-1))
#define MGC_O_QMU_RQTR_BASE 0x0090
#define MGC_O_QMU_RQTR(n) (MGC_O_QMU_RQTR_BASE+0x4*((n)-1))
#define MGC_O_QMU_RQLDPR0 0x0100
#define MGC_O_QMU_RQLDPR(n) (MGC_O_QMU_RQLDPR0+0x4*((n)-1))
#define MGC_O_QMU_TQCSR0 0x0200
#define MGC_O_QMU_TQSAR0 0x0204
#define MGC_O_QMU_TQCPR0 0x0208
#define MGC_O_QMU_TQCSR(n) (MGC_O_QMU_TQCSR0+0x0010*((n)-1))
#define MGC_O_QMU_TQSAR(n) (MGC_O_QMU_TQSAR0+0x0010*((n)-1))
#define MGC_O_QMU_TQCPR(n) (MGC_O_QMU_TQCPR0+0x0010*((n)-1))
#define MGC_O_QMU_QAR 0x0300
#define MGC_O_QUCS_USBGCSR 0x0000
#define MGC_O_QIRQ_QISAR 0x0000
#define MGC_O_QIRQ_QIMR 0x0004
#define MGC_O_QIRQ_QIMCR 0x0008
#define MGC_O_QIRQ_QIMSR 0x000C
#define MGC_O_QIRQ_IOCDISR 0x0030
#define MGC_O_QIRQ_TEPEMPR 0x0060
#define MGC_O_QIRQ_TEPEMPMR 0x0064
#define MGC_O_QIRQ_TEPEMPMCR 0x0068
#define MGC_O_QIRQ_TEPEMPMSR 0x006C
#define MGC_O_QIRQ_REPEMPR 0x0070
#define MGC_O_QIRQ_REPEMPMR 0x0074
#define MGC_O_QIRQ_REPEMPMCR 0x0078
#define MGC_O_QIRQ_REPEMPMSR 0x007C
#define MGC_O_QIRQ_RQEIR 0x0090
#define MGC_O_QIRQ_RQEIMR 0x0094
#define MGC_O_QIRQ_RQEIMCR 0x0098
#define MGC_O_QIRQ_RQEIMSR 0x009C
#define MGC_O_QIRQ_REPEIR 0x00A0
#define MGC_O_QIRQ_REPEIMR 0x00A4
#define MGC_O_QIRQ_REPEIMCR 0x00A8
#define MGC_O_QIRQ_REPEIMSR 0x00AC
#define MGC_O_QIRQ_TQEIR 0x00B0
#define MGC_O_QIRQ_TQEIMR 0x00B4
#define MGC_O_QIRQ_TQEIMCR 0x00B8
#define MGC_O_QIRQ_TQEIMSR 0x00BC
#define MGC_O_QIRQ_TEPEIR 0x00C0
#define MGC_O_QIRQ_TEPEIMR 0x00C4
#define MGC_O_QIRQ_TEPEIMCR 0x00C8
#define MGC_O_QIRQ_TEPEIMSR 0x00CC
#define MGC_O_QDBG_DFCR 0x0000
#define MGC_O_QDBG_DFMR 0x0004
/* brief Queue Control value Definition */
#define DQMU_QUE_START 0x00000001
#define DQMU_QUE_RESUME 0x00000002
#define DQMU_QUE_STOP 0x00000004
#define DQMU_QUE_ACTIVE 0x00008000
/*brief USB QMU Special Control USBGCSR value Definition*/
#define USB_QMU_Tx0_EN 0x00000001
#define USB_QMU_Tx_EN(n) (USB_QMU_Tx0_EN<<((n)-1))
#define USB_QMU_Rx0_EN 0x00010000
#define USB_QMU_Rx_EN(n) (USB_QMU_Rx0_EN<<((n)-1))
#define USB_QMU_HIFEVT_EN 0x00000100
#define USB_QMU_HIFCMD_EN 0x01000000
#define DQMU_SW_RESET 0x00010000
#define DQMU_CS16B_EN 0x80000000
#define DQMU_TQ0CS_EN 0x00010000
#define DQMU_TQCS_EN(n) (DQMU_TQ0CS_EN<<((n)-1))
#define DQMU_RQ0CS_EN 0x00000001
#define DQMU_RQCS_EN(n) (DQMU_RQ0CS_EN<<((n)-1))
#define DQMU_TX0_ZLP 0x01000000
#define DQMU_TX_ZLP(n) (DQMU_TX0_ZLP<<((n)-1))
#define DQMU_TX0_MULTIPLE 0x00010000
#define DQMU_TX_MULTIPLE(n) (DQMU_TX0_MULTIPLE<<((n)-1))
#define DQMU_RX0_MULTIPLE 0x00010000
#define DQMU_RX_MULTIPLE(n) (DQMU_RX0_MULTIPLE<<((n)-1))
#define DQMU_RX0_ZLP 0x01000000
#define DQMU_RX_ZLP(n) (DQMU_RX0_ZLP<<((n)-1))
#define DQMU_RX0_COZ 0x00000100
#define DQMU_RX_COZ(n) (DQMU_RX0_COZ<<((n)-1))
#define DQMU_M_TXEP_ERR 0x10000000
#define DQMU_M_TXQ_ERR 0x08000000
#define DQMU_M_RXEP_ERR 0x04000000
#define DQMU_M_RXQ_ERR 0x02000000
#define DQMU_M_RQ_EMPTY 0x00020000
#define DQMU_M_TQ_EMPTY 0x00010000
#define DQMU_M_RX0_EMPTY 0x00000001
#define DQMU_M_RX_EMPTY(n) (DQMU_M_RX0_EMPTY<<((n)-1))
#define DQMU_M_TX0_EMPTY 0x00000001
#define DQMU_M_TX_EMPTY(n) (DQMU_M_TX0_EMPTY<<((n)-1))
#define DQMU_M_RX0_DONE 0x00000100
#define DQMU_M_RX_DONE(n) (DQMU_M_RX0_DONE<<((n)-1))
#define DQMU_M_TX0_DONE 0x00000001
#define DQMU_M_TX_DONE(n) (DQMU_M_TX0_DONE<<((n)-1))
#define DQMU_M_RX0_ZLP_ERR 0x01000000
#define DQMU_M_RX_ZLP_ERR(n) (DQMU_M_RX0_ZLP_ERR<<((n)-1))
#define DQMU_M_RX0_LEN_ERR 0x00000100
#define DQMU_M_RX_LEN_ERR(n) (DQMU_M_RX0_LEN_ERR<<((n)-1))
#define DQMU_M_RX0_GPDCS_ERR 0x00000001
#define DQMU_M_RX_GPDCS_ERR(n) (DQMU_M_RX0_GPDCS_ERR<<((n)-1))
#define DQMU_M_TX0_LEN_ERR 0x00010000
#define DQMU_M_TX_LEN_ERR(n) (DQMU_M_TX0_LEN_ERR<<((n)-1))
#define DQMU_M_TX0_GPDCS_ERR 0x00000100
#define DQMU_M_TX_GPDCS_ERR(n) (DQMU_M_TX0_GPDCS_ERR<<((n)-1))
#define DQMU_M_TX0_BDCS_ERR 0x00000001
#define DQMU_M_TX_BDCS_ERR(n) (DQMU_M_TX0_BDCS_ERR<<((n)-1))
#define DQMU_M_TX0_EP_ERR 0x00000001
#define DQMU_M_TX_EP_ERR(n) (DQMU_M_TX0_EP_ERR<<((n)-1))
#define DQMU_M_RX0_EP_ERR 0x00000001
#define DQMU_M_RX_EP_ERR(n) (DQMU_M_RX0_EP_ERR<<((n)-1))
#define DQMU_M_RQ_DIS_IOC(n) (0x100<<((n)-1))
#define MGC_ReadQMU8(base,_offset) \
musb_readb(base, (USB_HW_QMU_OFF + _offset))
#define MGC_ReadQUCS8(base,_offset) \
musb_readb(base, (USB_HW_QUCS_OFF + _offset))
#define MGC_ReadQIRQ8(base,_offset) \
musb_readb(base, (USB_HW_QIRQ_OFF + _offset))
#define MGC_ReadQMU16(base,_offset) \
musb_readw(base, (USB_HW_QMU_OFF + _offset))
#define MGC_ReadQUCS16(base,_offset) \
musb_readw(base,(USB_HW_QUCS_OFF + _offset))
#define MGC_ReadQIRQ16(base,_offset) \
musb_readw(base, (USB_HW_QIRQ_OFF + _offset))
#define MGC_ReadQMU32(base,_offset) \
musb_readl(base, (USB_HW_QMU_OFF + _offset))
#define MGC_ReadQUCS32(base,_offset) \
musb_readl(base, (USB_HW_QUCS_OFF + _offset))
#define MGC_ReadQIRQ32(base,_offset) \
musb_readl(base, (USB_HW_QIRQ_OFF + _offset))
#define MGC_WriteQMU32(base,_offset, _data) \
musb_writel(base, (USB_HW_QMU_OFF + _offset), _data)
#define MGC_WriteQUCS32(base,_offset, _data) \
musb_writel(base, (USB_HW_QUCS_OFF + _offset), _data)
#define MGC_WriteQIRQ32(base,_offset, _data) \
musb_writel(base,(USB_HW_QIRQ_OFF + _offset), _data)
u8 PDU_calcCksum(u8 *data, int len);
/* brief Define DMAQ GPD format */
#define TGPD_FLAGS_HWO 0x01
#define TGPD_IS_FLAGS_HWO(_pd) (((TGPD *)_pd)->flag & TGPD_FLAGS_HWO)
#define TGPD_SET_FLAGS_HWO(_pd) (((TGPD *)_pd)->flag |= TGPD_FLAGS_HWO)
#define TGPD_CLR_FLAGS_HWO(_pd) (((TGPD *)_pd)->flag &= (~TGPD_FLAGS_HWO))
#define TGPD_FORMAT_BDP 0x02
#define TGPD_IS_FORMAT_BDP(_pd) (((TGPD *)_pd)->flag & TGPD_FORMAT_BDP)
#define TGPD_SET_FORMAT_BDP(_pd) (((TGPD *)_pd)->flag |= TGPD_FORMAT_BDP)
#define TGPD_CLR_FORMAT_BDP(_pd) (((TGPD *)_pd)->flag &= (~TGPD_FORMAT_BDP))
#define TGPD_SET_FLAG(_pd, _flag) ((TGPD *)_pd)->flag = (((TGPD *)_pd)->flag&(~TGPD_FLAGS_HWO))|(_flag)
#define TGPD_GET_FLAG(_pd) (((TGPD *)_pd)->flag & TGPD_FLAGS_HWO)
#define TGPD_SET_CHKSUM(_pd, _n) ((TGPD *)_pd)->chksum = PDU_calcCksum((u8 *)_pd, _n)
#define TGPD_SET_CHKSUM_HWO(_pd, _n) ((TGPD *)_pd)->chksum = PDU_calcCksum((u8 *)_pd, _n)-1
#define TGPD_GET_CHKSUM(_pd) ((TGPD *)_pd)->chksum
#define TGPD_SET_FORMAT(_pd, _fmt) ((TGPD *)_pd)->flag = (((TGPD *)_pd)->flag&(~TGPD_FORMAT_BDP))|(_fmt)
#define TGPD_GET_FORMAT(_pd) ((((TGPD *)_pd)->flag & TGPD_FORMAT_BDP)>>1)
#define TGPD_SET_DataBUF_LEN(_pd, _len) ((TGPD *)_pd)->DataBufferLen = _len
#define TGPD_ADD_DataBUF_LEN(_pd, _len) ((TGPD *)_pd)->DataBufferLen += _len
#define TGPD_GET_DataBUF_LEN(_pd) ((TGPD *)_pd)->DataBufferLen
#define TGPD_SET_NEXT(_pd, _next) ((TGPD *)_pd)->pNext = (u32)(unsigned long)((TGPD *)_next)
#define TGPD_GET_NEXT(_pd) (TGPD *)(unsigned long)((TGPD *)_pd)->pNext
#define TGPD_SET_DATA(_pd, _data) ((TGPD *)_pd)->pBuf = (u32)(unsigned long)_data
#define TGPD_GET_DATA(_pd) (u8 *)(unsigned long)((TGPD *)_pd)->pBuf
#define TGPD_SET_BUF_LEN(_pd, _len) ((TGPD *)_pd)->bufLen = _len
#define TGPD_ADD_BUF_LEN(_pd, _len) ((TGPD *)_pd)->bufLen += _len
#define TGPD_GET_BUF_LEN(_pd) ((TGPD *)_pd)->bufLen
#define TGPD_SET_EXT_LEN(_pd, _len) ((TGPD *)_pd)->ExtLength = _len
#define TGPD_GET_EXT_LEN(_pd) ((TGPD *)_pd)->ExtLength
#define TGPD_SET_EPaddr(_pd, _EP) ((TGPD *)_pd)->ZTepFlag =(((TGPD *)_pd)->ZTepFlag&0xF0)|(_EP)
#define TGPD_GET_EPaddr(_pd) ((TGPD *)_pd)->ZTepFlag & 0x0F
#define TGPD_FORMAT_TGL 0x10
#define TGPD_IS_FORMAT_TGL(_pd) (((TGPD *)_pd)->ZTepFlag & TGPD_FORMAT_TGL)
#define TGPD_SET_FORMAT_TGL(_pd) (((TGPD *)_pd)->ZTepFlag |=TGPD_FORMAT_TGL)
#define TGPD_CLR_FORMAT_TGL(_pd) (((TGPD *)_pd)->ZTepFlag &= (~TGPD_FORMAT_TGL))
#define TGPD_FORMAT_ZLP 0x20
#define TGPD_IS_FORMAT_ZLP(_pd) (((TGPD *)_pd)->ZTepFlag & TGPD_FORMAT_ZLP)
#define TGPD_SET_FORMAT_ZLP(_pd) (((TGPD *)_pd)->ZTepFlag |=TGPD_FORMAT_ZLP)
#define TGPD_CLR_FORMAT_ZLP(_pd) (((TGPD *)_pd)->ZTepFlag &= (~TGPD_FORMAT_ZLP))
#define TGPD_SET_TGL(_pd, _TGL) ((TGPD *)_pd)->ZTepFlag |=(( _TGL) ? 0x10: 0x00)
#define TGPD_GET_TGL(_pd) ((TGPD *)_pd)->ZTepFlag & 0x10 ? 1:0
#define TGPD_SET_ZLP(_pd, _ZLP) ((TGPD *)_pd)->ZTepFlag |= ((_ZLP) ? 0x20: 0x00)
#define TGPD_GET_ZLP(_pd) ((TGPD *)_pd)->ZTepFlag & 0x20 ? 1:0
#define TGPD_FLAG_IOC 0x80
#define TGPD_SET_IOC(_pd) (((TGPD *)_pd)->flag |= TGPD_FLAG_IOC)
extern void qmu_destroy_gpd_pool(struct device *dev);
extern int qmu_init_gpd_pool(struct device *dev);
extern void qmu_reset_gpd_pool(u32 ep_num, u8 isRx);
extern bool mtk_is_qmu_enabled(u8 EP_Num, u8 isRx);
extern void mtk_qmu_enable(struct musb *musb, u8 EP_Num, u8 isRx);
extern void mtk_qmu_insert_task(u8 EP_Num, u8 isRx, u8* buf, u32 length, u8 zlp);
extern void mtk_qmu_resume(u8 EP_Num, u8 isRx);
extern void qmu_done_rx(struct musb *musb, u8 ep_num);
extern void qmu_done_tx(struct musb *musb, u8 ep_num);
extern void mtk_disable_q(struct musb *musb, u8 ep_num, u8 isRx);
extern void mtk_qmu_irq_err(struct musb *musb, u32 qisar);
extern void flush_ep_csr(struct musb *musb, u8 ep_num, u8 isRx);
extern void mtk_qmu_stop(u8 ep_num, u8 isRx);
#endif
#endif
|