1// SPDX-License-Identifier: GPL-2.0
2/*
3 * R8A66597 UDC
4 *
5 * Copyright (C) 2007-2009 Renesas Solutions Corp.
6 *
7 * Author : Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
8 */
9
10#ifndef __R8A66597_H__
11#define __R8A66597_H__
12
13#include <linux/clk.h>
14#include <linux/usb/r8a66597.h>
15
16#define R8A66597_MAX_SAMPLING	10
17
18#define R8A66597_MAX_NUM_PIPE	8
19#define R8A66597_MAX_NUM_BULK	3
20#define R8A66597_MAX_NUM_ISOC	2
21#define R8A66597_MAX_NUM_INT	2
22
23#define R8A66597_BASE_PIPENUM_BULK	3
24#define R8A66597_BASE_PIPENUM_ISOC	1
25#define R8A66597_BASE_PIPENUM_INT	6
26
27#define R8A66597_BASE_BUFNUM	6
28#define R8A66597_MAX_BUFNUM	0x4F
29
30#define is_bulk_pipe(pipenum)	\
31	((pipenum >= R8A66597_BASE_PIPENUM_BULK) && \
32	 (pipenum < (R8A66597_BASE_PIPENUM_BULK + R8A66597_MAX_NUM_BULK)))
33#define is_interrupt_pipe(pipenum)	\
34	((pipenum >= R8A66597_BASE_PIPENUM_INT) && \
35	 (pipenum < (R8A66597_BASE_PIPENUM_INT + R8A66597_MAX_NUM_INT)))
36#define is_isoc_pipe(pipenum)	\
37	((pipenum >= R8A66597_BASE_PIPENUM_ISOC) && \
38	 (pipenum < (R8A66597_BASE_PIPENUM_ISOC + R8A66597_MAX_NUM_ISOC)))
39
40#define r8a66597_is_sudmac(r8a66597)	(r8a66597->pdata->sudmac)
41struct r8a66597_pipe_info {
42	u16	pipe;
43	u16	epnum;
44	u16	maxpacket;
45	u16	type;
46	u16	interval;
47	u16	dir_in;
48};
49
50struct r8a66597_request {
51	struct usb_request	req;
52	struct list_head	queue;
53};
54
55struct r8a66597_ep {
56	struct usb_ep		ep;
57	struct r8a66597		*r8a66597;
58	struct r8a66597_dma	*dma;
59
60	struct list_head	queue;
61	unsigned		busy:1;
62	unsigned		wedge:1;
63	unsigned		internal_ccpl:1;	/* use only control */
64
65	/* this member can able to after r8a66597_enable */
66	unsigned		use_dma:1;
67	u16			pipenum;
68	u16			type;
69
70	/* register address */
71	unsigned char		fifoaddr;
72	unsigned char		fifosel;
73	unsigned char		fifoctr;
74	unsigned char		pipectr;
75	unsigned char		pipetre;
76	unsigned char		pipetrn;
77};
78
79struct r8a66597_dma {
80	unsigned		used:1;
81	unsigned		dir:1;	/* 1 = IN(write), 0 = OUT(read) */
82};
83
84struct r8a66597 {
85	spinlock_t		lock;
86	void __iomem		*reg;
87	void __iomem		*sudmac_reg;
88
89	struct clk *clk;
90	struct r8a66597_platdata	*pdata;
91
92	struct usb_gadget		gadget;
93	struct usb_gadget_driver	*driver;
94
95	struct r8a66597_ep	ep[R8A66597_MAX_NUM_PIPE];
96	struct r8a66597_ep	*pipenum2ep[R8A66597_MAX_NUM_PIPE];
97	struct r8a66597_ep	*epaddr2ep[16];
98	struct r8a66597_dma	dma;
99
100	struct timer_list	timer;
101	struct usb_request	*ep0_req;	/* for internal request */
102	u16			ep0_data;	/* for internal request */
103	u16			old_vbus;
104	u16			scount;
105	u16			old_dvsq;
106	u16			device_status;	/* for GET_STATUS */
107
108	/* pipe config */
109	unsigned char bulk;
110	unsigned char interrupt;
111	unsigned char isochronous;
112	unsigned char num_dma;
113
114	unsigned irq_sense_low:1;
115};
116
117#define gadget_to_r8a66597(_gadget)	\
118		container_of(_gadget, struct r8a66597, gadget)
119#define r8a66597_to_gadget(r8a66597) (&r8a66597->gadget)
120#define r8a66597_to_dev(r8a66597)	(r8a66597->gadget.dev.parent)
121
122static inline u16 r8a66597_read(struct r8a66597 *r8a66597, unsigned long offset)
123{
124	return ioread16(r8a66597->reg + offset);
125}
126
127static inline void r8a66597_read_fifo(struct r8a66597 *r8a66597,
128				      unsigned long offset,
129				      unsigned char *buf,
130				      int len)
131{
132	void __iomem *fifoaddr = r8a66597->reg + offset;
133	unsigned int data = 0;
134	int i;
135
136	if (r8a66597->pdata->on_chip) {
137		/* 32-bit accesses for on_chip controllers */
138
139		/* aligned buf case */
140		if (len >= 4 && !((unsigned long)buf & 0x03)) {
141			ioread32_rep(fifoaddr, buf, len / 4);
142			buf += len & ~0x03;
143			len &= 0x03;
144		}
145
146		/* unaligned buf case */
147		for (i = 0; i < len; i++) {
148			if (!(i & 0x03))
149				data = ioread32(fifoaddr);
150
151			buf[i] = (data >> ((i & 0x03) * 8)) & 0xff;
152		}
153	} else {
154		/* 16-bit accesses for external controllers */
155
156		/* aligned buf case */
157		if (len >= 2 && !((unsigned long)buf & 0x01)) {
158			ioread16_rep(fifoaddr, buf, len / 2);
159			buf += len & ~0x01;
160			len &= 0x01;
161		}
162
163		/* unaligned buf case */
164		for (i = 0; i < len; i++) {
165			if (!(i & 0x01))
166				data = ioread16(fifoaddr);
167
168			buf[i] = (data >> ((i & 0x01) * 8)) & 0xff;
169		}
170	}
171}
172
173static inline void r8a66597_write(struct r8a66597 *r8a66597, u16 val,
174				  unsigned long offset)
175{
176	iowrite16(val, r8a66597->reg + offset);
177}
178
179static inline void r8a66597_mdfy(struct r8a66597 *r8a66597,
180				 u16 val, u16 pat, unsigned long offset)
181{
182	u16 tmp;
183	tmp = r8a66597_read(r8a66597, offset);
184	tmp = tmp & (~pat);
185	tmp = tmp | val;
186	r8a66597_write(r8a66597, tmp, offset);
187}
188
189#define r8a66597_bclr(r8a66597, val, offset)	\
190			r8a66597_mdfy(r8a66597, 0, val, offset)
191#define r8a66597_bset(r8a66597, val, offset)	\
192			r8a66597_mdfy(r8a66597, val, 0, offset)
193
194static inline void r8a66597_write_fifo(struct r8a66597 *r8a66597,
195				       struct r8a66597_ep *ep,
196				       unsigned char *buf,
197				       int len)
198{
199	void __iomem *fifoaddr = r8a66597->reg + ep->fifoaddr;
200	int adj = 0;
201	int i;
202
203	if (r8a66597->pdata->on_chip) {
204		/* 32-bit access only if buf is 32-bit aligned */
205		if (len >= 4 && !((unsigned long)buf & 0x03)) {
206			iowrite32_rep(fifoaddr, buf, len / 4);
207			buf += len & ~0x03;
208			len &= 0x03;
209		}
210	} else {
211		/* 16-bit access only if buf is 16-bit aligned */
212		if (len >= 2 && !((unsigned long)buf & 0x01)) {
213			iowrite16_rep(fifoaddr, buf, len / 2);
214			buf += len & ~0x01;
215			len &= 0x01;
216		}
217	}
218
219	/* adjust fifo address in the little endian case */
220	if (!(r8a66597_read(r8a66597, CFIFOSEL) & BIGEND)) {
221		if (r8a66597->pdata->on_chip)
222			adj = 0x03; /* 32-bit wide */
223		else
224			adj = 0x01; /* 16-bit wide */
225	}
226
227	if (r8a66597->pdata->wr0_shorted_to_wr1)
228		r8a66597_bclr(r8a66597, MBW_16, ep->fifosel);
229	for (i = 0; i < len; i++)
230		iowrite8(buf[i], fifoaddr + adj - (i & adj));
231	if (r8a66597->pdata->wr0_shorted_to_wr1)
232		r8a66597_bclr(r8a66597, MBW_16, ep->fifosel);
233}
234
235static inline u16 get_xtal_from_pdata(struct r8a66597_platdata *pdata)
236{
237	u16 clock = 0;
238
239	switch (pdata->xtal) {
240	case R8A66597_PLATDATA_XTAL_12MHZ:
241		clock = XTAL12;
242		break;
243	case R8A66597_PLATDATA_XTAL_24MHZ:
244		clock = XTAL24;
245		break;
246	case R8A66597_PLATDATA_XTAL_48MHZ:
247		clock = XTAL48;
248		break;
249	default:
250		printk(KERN_ERR "r8a66597: platdata clock is wrong.\n");
251		break;
252	}
253
254	return clock;
255}
256
257static inline u32 r8a66597_sudmac_read(struct r8a66597 *r8a66597,
258				       unsigned long offset)
259{
260	return ioread32(r8a66597->sudmac_reg + offset);
261}
262
263static inline void r8a66597_sudmac_write(struct r8a66597 *r8a66597, u32 val,
264					 unsigned long offset)
265{
266	iowrite32(val, r8a66597->sudmac_reg + offset);
267}
268
269#define get_pipectr_addr(pipenum)	(PIPE1CTR + (pipenum - 1) * 2)
270#define get_pipetre_addr(pipenum)	(PIPE1TRE + (pipenum - 1) * 4)
271#define get_pipetrn_addr(pipenum)	(PIPE1TRN + (pipenum - 1) * 4)
272
273#define enable_irq_ready(r8a66597, pipenum)	\
274	enable_pipe_irq(r8a66597, pipenum, BRDYENB)
275#define disable_irq_ready(r8a66597, pipenum)	\
276	disable_pipe_irq(r8a66597, pipenum, BRDYENB)
277#define enable_irq_empty(r8a66597, pipenum)	\
278	enable_pipe_irq(r8a66597, pipenum, BEMPENB)
279#define disable_irq_empty(r8a66597, pipenum)	\
280	disable_pipe_irq(r8a66597, pipenum, BEMPENB)
281#define enable_irq_nrdy(r8a66597, pipenum)	\
282	enable_pipe_irq(r8a66597, pipenum, NRDYENB)
283#define disable_irq_nrdy(r8a66597, pipenum)	\
284	disable_pipe_irq(r8a66597, pipenum, NRDYENB)
285
286#endif	/* __R8A66597_H__ */
287
288