xref: /linux/drivers/usb/renesas_usbhs/fifo.c (revision dad67397f2090b29cd1f169e6a4ac6f3532c6858)
1 /*
2  * Renesas USB driver
3  *
4  * Copyright (C) 2011 Renesas Solutions Corp.
5  * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
15  *
16  */
17 #include <linux/delay.h>
18 #include <linux/io.h>
19 #include "./common.h"
20 #include "./pipe.h"
21 
22 /*
23  *		packet info function
24  */
25 static int usbhsf_null_handle(struct usbhs_pkt *pkt)
26 {
27 	struct usbhs_priv *priv = usbhs_pipe_to_priv(pkt->pipe);
28 	struct device *dev = usbhs_priv_to_dev(priv);
29 
30 	dev_err(dev, "null handler\n");
31 
32 	return -EINVAL;
33 }
34 
35 static struct usbhs_pkt_handle usbhsf_null_handler = {
36 	.prepare = usbhsf_null_handle,
37 	.try_run = usbhsf_null_handle,
38 };
39 
40 void usbhs_pkt_init(struct usbhs_pkt *pkt)
41 {
42 	INIT_LIST_HEAD(&pkt->node);
43 }
44 
45 void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt,
46 		    struct usbhs_pkt_handle *handler,
47 		    void *buf, int len, int zero)
48 {
49 	struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
50 	struct device *dev = usbhs_priv_to_dev(priv);
51 
52 	if (!handler) {
53 		dev_err(dev, "no handler function\n");
54 		handler = &usbhsf_null_handler;
55 	}
56 
57 	list_del_init(&pkt->node);
58 	list_add_tail(&pkt->node, &pipe->list);
59 
60 	pkt->pipe	= pipe;
61 	pkt->buf	= buf;
62 	pkt->handler	= handler;
63 	pkt->length	= len;
64 	pkt->zero	= zero;
65 	pkt->actual	= 0;
66 }
67 
68 void usbhs_pkt_pop(struct usbhs_pkt *pkt)
69 {
70 	list_del_init(&pkt->node);
71 }
72 
73 struct usbhs_pkt *usbhs_pkt_get(struct usbhs_pipe *pipe)
74 {
75 	if (list_empty(&pipe->list))
76 		return NULL;
77 
78 	return list_entry(pipe->list.next, struct usbhs_pkt, node);
79 }
80 
81 /*
82  *		irq enable/disable function
83  */
84 #define usbhsf_irq_empty_ctrl(p, e) usbhsf_irq_callback_ctrl(p, bempsts, e)
85 #define usbhsf_irq_ready_ctrl(p, e) usbhsf_irq_callback_ctrl(p, brdysts, e)
86 #define usbhsf_irq_callback_ctrl(pipe, status, enable)			\
87 	({								\
88 		struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);	\
89 		struct usbhs_mod *mod = usbhs_mod_get_current(priv);	\
90 		u16 status = (1 << usbhs_pipe_number(pipe));		\
91 		if (!mod)						\
92 			return;						\
93 		if (enable)						\
94 			mod->irq_##status |= status;			\
95 		else							\
96 			mod->irq_##status &= ~status;			\
97 		usbhs_irq_callback_update(priv, mod);			\
98 	})
99 
100 static void usbhsf_tx_irq_ctrl(struct usbhs_pipe *pipe, int enable)
101 {
102 	/*
103 	 * And DCP pipe can NOT use "ready interrupt" for "send"
104 	 * it should use "empty" interrupt.
105 	 * see
106 	 *   "Operation" - "Interrupt Function" - "BRDY Interrupt"
107 	 *
108 	 * on the other hand, normal pipe can use "ready interrupt" for "send"
109 	 * even though it is single/double buffer
110 	 */
111 	if (usbhs_pipe_is_dcp(pipe))
112 		usbhsf_irq_empty_ctrl(pipe, enable);
113 	else
114 		usbhsf_irq_ready_ctrl(pipe, enable);
115 }
116 
117 static void usbhsf_rx_irq_ctrl(struct usbhs_pipe *pipe, int enable)
118 {
119 	usbhsf_irq_ready_ctrl(pipe, enable);
120 }
121 
122 /*
123  *		FIFO ctrl
124  */
125 static void usbhsf_send_terminator(struct usbhs_pipe *pipe)
126 {
127 	struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
128 
129 	usbhs_bset(priv, CFIFOCTR, BVAL, BVAL);
130 }
131 
132 static int usbhsf_fifo_barrier(struct usbhs_priv *priv)
133 {
134 	int timeout = 1024;
135 
136 	do {
137 		/* The FIFO port is accessible */
138 		if (usbhs_read(priv, CFIFOCTR) & FRDY)
139 			return 0;
140 
141 		udelay(10);
142 	} while (timeout--);
143 
144 	return -EBUSY;
145 }
146 
147 static void usbhsf_fifo_clear(struct usbhs_pipe *pipe)
148 {
149 	struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
150 
151 	if (!usbhs_pipe_is_dcp(pipe))
152 		usbhsf_fifo_barrier(priv);
153 
154 	usbhs_write(priv, CFIFOCTR, BCLR);
155 }
156 
157 static int usbhsf_fifo_rcv_len(struct usbhs_priv *priv)
158 {
159 	return usbhs_read(priv, CFIFOCTR) & DTLN_MASK;
160 }
161 
162 static int usbhsf_fifo_select(struct usbhs_pipe *pipe, int write)
163 {
164 	struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
165 	struct device *dev = usbhs_priv_to_dev(priv);
166 	int timeout = 1024;
167 	u16 mask = ((1 << 5) | 0xF);		/* mask of ISEL | CURPIPE */
168 	u16 base = usbhs_pipe_number(pipe);	/* CURPIPE */
169 
170 	if (usbhs_pipe_is_dcp(pipe))
171 		base |= (1 == write) << 5;	/* ISEL */
172 
173 	/* "base" will be used below  */
174 	usbhs_write(priv, CFIFOSEL, base | MBW_32);
175 
176 	/* check ISEL and CURPIPE value */
177 	while (timeout--) {
178 		if (base == (mask & usbhs_read(priv, CFIFOSEL)))
179 			return 0;
180 		udelay(10);
181 	}
182 
183 	dev_err(dev, "fifo select error\n");
184 
185 	return -EIO;
186 }
187 
188 /*
189  *		PIO fifo functions
190  */
191 static int usbhsf_try_push(struct usbhs_pkt *pkt)
192 {
193 	struct usbhs_pipe *pipe = pkt->pipe;
194 	struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
195 	struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
196 	struct device *dev = usbhs_priv_to_dev(priv);
197 	void __iomem *addr = priv->base + CFIFO;
198 	u8 *buf;
199 	int maxp = usbhs_pipe_get_maxpacket(pipe);
200 	int total_len;
201 	int i, ret, len;
202 	int is_short, is_done;
203 
204 	ret = usbhsf_fifo_select(pipe, 1);
205 	if (ret < 0)
206 		goto usbhs_fifo_write_busy;
207 
208 	ret = usbhs_pipe_is_accessible(pipe);
209 	if (ret < 0)
210 		goto usbhs_fifo_write_busy;
211 
212 	ret = usbhsf_fifo_barrier(priv);
213 	if (ret < 0)
214 		goto usbhs_fifo_write_busy;
215 
216 	buf		= pkt->buf    + pkt->actual;
217 	len		= pkt->length - pkt->actual;
218 	len		= min(len, maxp);
219 	total_len	= len;
220 	is_short	= total_len < maxp;
221 
222 	/*
223 	 * FIXME
224 	 *
225 	 * 32-bit access only
226 	 */
227 	if (len >= 4 && !((unsigned long)buf & 0x03)) {
228 		iowrite32_rep(addr, buf, len / 4);
229 		len %= 4;
230 		buf += total_len - len;
231 	}
232 
233 	/* the rest operation */
234 	for (i = 0; i < len; i++)
235 		iowrite8(buf[i], addr + (0x03 - (i & 0x03)));
236 
237 	/*
238 	 * variable update
239 	 */
240 	pkt->actual += total_len;
241 
242 	if (pkt->actual < pkt->length)
243 		is_done = 0;		/* there are remainder data */
244 	else if (is_short)
245 		is_done = 1;		/* short packet */
246 	else
247 		is_done = !pkt->zero;	/* send zero packet ? */
248 
249 	/*
250 	 * pipe/irq handling
251 	 */
252 	if (is_short)
253 		usbhsf_send_terminator(pipe);
254 
255 	usbhsf_tx_irq_ctrl(pipe, !is_done);
256 	usbhs_pipe_enable(pipe);
257 
258 	dev_dbg(dev, "  send %d (%d/ %d/ %d/ %d)\n",
259 		usbhs_pipe_number(pipe),
260 		pkt->length, pkt->actual, is_done, pkt->zero);
261 
262 	/*
263 	 * Transmission end
264 	 */
265 	if (is_done) {
266 		if (usbhs_pipe_is_dcp(pipe))
267 			usbhs_dcp_control_transfer_done(pipe);
268 
269 		info->done(pkt);
270 	}
271 
272 	return 0;
273 
274 usbhs_fifo_write_busy:
275 	/*
276 	 * pipe is busy.
277 	 * retry in interrupt
278 	 */
279 	usbhsf_tx_irq_ctrl(pipe, 1);
280 
281 	return ret;
282 }
283 
284 struct usbhs_pkt_handle usbhs_fifo_push_handler = {
285 	.prepare = usbhsf_try_push,
286 	.try_run = usbhsf_try_push,
287 };
288 
289 static int usbhsf_prepare_pop(struct usbhs_pkt *pkt)
290 {
291 	struct usbhs_pipe *pipe = pkt->pipe;
292 	int ret;
293 
294 	/*
295 	 * select pipe and enable it to prepare packet receive
296 	 */
297 	ret = usbhsf_fifo_select(pipe, 0);
298 	if (ret < 0)
299 		return ret;
300 
301 	usbhs_pipe_enable(pipe);
302 	usbhsf_rx_irq_ctrl(pipe, 1);
303 
304 	return ret;
305 }
306 
307 static int usbhsf_try_pop(struct usbhs_pkt *pkt)
308 {
309 	struct usbhs_pipe *pipe = pkt->pipe;
310 	struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
311 	struct device *dev = usbhs_priv_to_dev(priv);
312 	void __iomem *addr = priv->base + CFIFO;
313 	u8 *buf;
314 	u32 data = 0;
315 	int maxp = usbhs_pipe_get_maxpacket(pipe);
316 	int rcv_len, len;
317 	int i, ret;
318 	int total_len = 0;
319 	int is_done = 0;
320 
321 	ret = usbhsf_fifo_select(pipe, 0);
322 	if (ret < 0)
323 		return ret;
324 
325 	ret = usbhsf_fifo_barrier(priv);
326 	if (ret < 0)
327 		return ret;
328 
329 	rcv_len = usbhsf_fifo_rcv_len(priv);
330 
331 	buf		= pkt->buf    + pkt->actual;
332 	len		= pkt->length - pkt->actual;
333 	len		= min(len, rcv_len);
334 	total_len	= len;
335 
336 	/*
337 	 * Buffer clear if Zero-Length packet
338 	 *
339 	 * see
340 	 * "Operation" - "FIFO Buffer Memory" - "FIFO Port Function"
341 	 */
342 	if (0 == rcv_len) {
343 		usbhsf_fifo_clear(pipe);
344 		goto usbhs_fifo_read_end;
345 	}
346 
347 	/*
348 	 * FIXME
349 	 *
350 	 * 32-bit access only
351 	 */
352 	if (len >= 4 && !((unsigned long)buf & 0x03)) {
353 		ioread32_rep(addr, buf, len / 4);
354 		len %= 4;
355 		buf += total_len - len;
356 	}
357 
358 	/* the rest operation */
359 	for (i = 0; i < len; i++) {
360 		if (!(i & 0x03))
361 			data = ioread32(addr);
362 
363 		buf[i] = (data >> ((i & 0x03) * 8)) & 0xff;
364 	}
365 
366 	pkt->actual += total_len;
367 
368 usbhs_fifo_read_end:
369 	if ((pkt->actual == pkt->length) ||	/* receive all data */
370 	    (total_len < maxp))			/* short packet */
371 		is_done = 1;
372 
373 	dev_dbg(dev, "  recv %d (%d/ %d/ %d/ %d)\n",
374 		usbhs_pipe_number(pipe),
375 		pkt->length, pkt->actual, is_done, pkt->zero);
376 
377 	if (is_done) {
378 		struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
379 
380 		usbhsf_rx_irq_ctrl(pipe, 0);
381 		usbhs_pipe_disable(pipe);
382 
383 		info->done(pkt);
384 	}
385 
386 	return 0;
387 }
388 
389 struct usbhs_pkt_handle usbhs_fifo_pop_handler = {
390 	.prepare = usbhsf_prepare_pop,
391 	.try_run = usbhsf_try_pop,
392 };
393 
394 /*
395  *		handler function
396  */
397 static int usbhsf_ctrl_stage_end(struct usbhs_pkt *pkt)
398 {
399 	struct usbhs_pipe *pipe = pkt->pipe;
400 	struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
401 	struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
402 
403 	usbhs_dcp_control_transfer_done(pipe);
404 
405 	info->done(pkt);
406 
407 	return 0;
408 }
409 
410 struct usbhs_pkt_handle usbhs_ctrl_stage_end_handler = {
411 	.prepare = usbhsf_ctrl_stage_end,
412 	.try_run = usbhsf_ctrl_stage_end,
413 };
414 
415 /*
416  *		irq functions
417  */
418 static int usbhsf_irq_empty(struct usbhs_priv *priv,
419 			    struct usbhs_irq_state *irq_state)
420 {
421 	struct usbhs_pipe *pipe;
422 	struct usbhs_pkt *pkt;
423 	struct device *dev = usbhs_priv_to_dev(priv);
424 	int i, ret;
425 
426 	if (!irq_state->bempsts) {
427 		dev_err(dev, "debug %s !!\n", __func__);
428 		return -EIO;
429 	}
430 
431 	dev_dbg(dev, "irq empty [0x%04x]\n", irq_state->bempsts);
432 
433 	/*
434 	 * search interrupted "pipe"
435 	 * not "uep".
436 	 */
437 	usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
438 		if (!(irq_state->bempsts & (1 << i)))
439 			continue;
440 
441 		pkt = usbhs_pkt_get(pipe);
442 		ret = usbhs_pkt_run(pkt);
443 		if (ret < 0)
444 			dev_err(dev, "irq_empty run_error %d : %d\n", i, ret);
445 	}
446 
447 	return 0;
448 }
449 
450 static int usbhsf_irq_ready(struct usbhs_priv *priv,
451 			    struct usbhs_irq_state *irq_state)
452 {
453 	struct usbhs_pipe *pipe;
454 	struct usbhs_pkt *pkt;
455 	struct device *dev = usbhs_priv_to_dev(priv);
456 	int i, ret;
457 
458 	if (!irq_state->brdysts) {
459 		dev_err(dev, "debug %s !!\n", __func__);
460 		return -EIO;
461 	}
462 
463 	dev_dbg(dev, "irq ready [0x%04x]\n", irq_state->brdysts);
464 
465 	/*
466 	 * search interrupted "pipe"
467 	 * not "uep".
468 	 */
469 	usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
470 		if (!(irq_state->brdysts & (1 << i)))
471 			continue;
472 
473 		pkt = usbhs_pkt_get(pipe);
474 		ret = usbhs_pkt_run(pkt);
475 		if (ret < 0)
476 			dev_err(dev, "irq_ready run_error %d : %d\n", i, ret);
477 	}
478 
479 	return 0;
480 }
481 
482 /*
483  *		fifo init
484  */
485 void usbhs_fifo_init(struct usbhs_priv *priv)
486 {
487 	struct usbhs_mod *mod = usbhs_mod_get_current(priv);
488 
489 	mod->irq_empty		= usbhsf_irq_empty;
490 	mod->irq_ready		= usbhsf_irq_ready;
491 	mod->irq_bempsts	= 0;
492 	mod->irq_brdysts	= 0;
493 }
494 
495 void usbhs_fifo_quit(struct usbhs_priv *priv)
496 {
497 	struct usbhs_mod *mod = usbhs_mod_get_current(priv);
498 
499 	mod->irq_empty		= NULL;
500 	mod->irq_ready		= NULL;
501 	mod->irq_bempsts	= 0;
502 	mod->irq_brdysts	= 0;
503 }
504