aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/renesas_usbhs/pipe.c
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2011-06-06 01:18:03 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-06-07 12:10:07 -0400
commite8d548d549688d335236f7f6f8bcee141a207ff8 (patch)
tree6adc569824995e4e8e6cf21ed1428a89da9a8118 /drivers/usb/renesas_usbhs/pipe.c
parentad6f2a8bc53b7cc104f481a648ce357528cc08eb (diff)
usb: renesas_usbhs: fifo became independent from pipe.
Current renesas_usbhs has PIO data transfer mode which controls CFIFO. And it was implemented in pipe.c. But, fifo control method needs more flexible implementation to support DMAEngine. This patch create fifo.c, and it became independent from pipe.c. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/renesas_usbhs/pipe.c')
-rw-r--r--drivers/usb/renesas_usbhs/pipe.c252
1 files changed, 29 insertions, 223 deletions
diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c
index 80fc4add6af2..75e9e3cbc0e5 100644
--- a/drivers/usb/renesas_usbhs/pipe.c
+++ b/drivers/usb/renesas_usbhs/pipe.c
@@ -15,7 +15,6 @@
15 * 15 *
16 */ 16 */
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/io.h>
19#include <linux/slab.h> 18#include <linux/slab.h>
20#include "./common.h" 19#include "./common.h"
21#include "./pipe.h" 20#include "./pipe.h"
@@ -23,13 +22,8 @@
23/* 22/*
24 * macros 23 * macros
25 */ 24 */
26#define usbhsp_priv_to_pipeinfo(pr) (&(pr)->pipe_info)
27#define usbhsp_pipe_to_priv(p) ((p)->priv)
28
29#define usbhsp_addr_offset(p) ((usbhs_pipe_number(p) - 1) * 2) 25#define usbhsp_addr_offset(p) ((usbhs_pipe_number(p) - 1) * 2)
30 26
31#define usbhsp_is_dcp(p) ((p)->priv->pipe_info.pipe == (p))
32
33#define usbhsp_flags_set(p, f) ((p)->flags |= USBHS_PIPE_FLAGS_##f) 27#define usbhsp_flags_set(p, f) ((p)->flags |= USBHS_PIPE_FLAGS_##f)
34#define usbhsp_flags_clr(p, f) ((p)->flags &= ~USBHS_PIPE_FLAGS_##f) 28#define usbhsp_flags_clr(p, f) ((p)->flags &= ~USBHS_PIPE_FLAGS_##f)
35#define usbhsp_flags_has(p, f) ((p)->flags & USBHS_PIPE_FLAGS_##f) 29#define usbhsp_flags_has(p, f) ((p)->flags & USBHS_PIPE_FLAGS_##f)
@@ -77,10 +71,10 @@ void usbhs_usbreq_set_val(struct usbhs_priv *priv, struct usb_ctrlrequest *req)
77 */ 71 */
78static void usbhsp_pipectrl_set(struct usbhs_pipe *pipe, u16 mask, u16 val) 72static void usbhsp_pipectrl_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
79{ 73{
80 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); 74 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
81 int offset = usbhsp_addr_offset(pipe); 75 int offset = usbhsp_addr_offset(pipe);
82 76
83 if (usbhsp_is_dcp(pipe)) 77 if (usbhs_pipe_is_dcp(pipe))
84 usbhs_bset(priv, DCPCTR, mask, val); 78 usbhs_bset(priv, DCPCTR, mask, val);
85 else 79 else
86 usbhs_bset(priv, PIPEnCTR + offset, mask, val); 80 usbhs_bset(priv, PIPEnCTR + offset, mask, val);
@@ -88,10 +82,10 @@ static void usbhsp_pipectrl_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
88 82
89static u16 usbhsp_pipectrl_get(struct usbhs_pipe *pipe) 83static u16 usbhsp_pipectrl_get(struct usbhs_pipe *pipe)
90{ 84{
91 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); 85 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
92 int offset = usbhsp_addr_offset(pipe); 86 int offset = usbhsp_addr_offset(pipe);
93 87
94 if (usbhsp_is_dcp(pipe)) 88 if (usbhs_pipe_is_dcp(pipe))
95 return usbhs_read(priv, DCPCTR); 89 return usbhs_read(priv, DCPCTR);
96 else 90 else
97 return usbhs_read(priv, PIPEnCTR + offset); 91 return usbhs_read(priv, PIPEnCTR + offset);
@@ -104,9 +98,9 @@ static void __usbhsp_pipe_xxx_set(struct usbhs_pipe *pipe,
104 u16 dcp_reg, u16 pipe_reg, 98 u16 dcp_reg, u16 pipe_reg,
105 u16 mask, u16 val) 99 u16 mask, u16 val)
106{ 100{
107 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); 101 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
108 102
109 if (usbhsp_is_dcp(pipe)) 103 if (usbhs_pipe_is_dcp(pipe))
110 usbhs_bset(priv, dcp_reg, mask, val); 104 usbhs_bset(priv, dcp_reg, mask, val);
111 else 105 else
112 usbhs_bset(priv, pipe_reg, mask, val); 106 usbhs_bset(priv, pipe_reg, mask, val);
@@ -115,9 +109,9 @@ static void __usbhsp_pipe_xxx_set(struct usbhs_pipe *pipe,
115static u16 __usbhsp_pipe_xxx_get(struct usbhs_pipe *pipe, 109static u16 __usbhsp_pipe_xxx_get(struct usbhs_pipe *pipe,
116 u16 dcp_reg, u16 pipe_reg) 110 u16 dcp_reg, u16 pipe_reg)
117{ 111{
118 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); 112 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
119 113
120 if (usbhsp_is_dcp(pipe)) 114 if (usbhs_pipe_is_dcp(pipe))
121 return usbhs_read(priv, dcp_reg); 115 return usbhs_read(priv, dcp_reg);
122 else 116 else
123 return usbhs_read(priv, pipe_reg); 117 return usbhs_read(priv, pipe_reg);
@@ -136,7 +130,7 @@ static void usbhsp_pipe_cfg_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
136 */ 130 */
137static void usbhsp_pipe_buf_set(struct usbhs_pipe *pipe, u16 mask, u16 val) 131static void usbhsp_pipe_buf_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
138{ 132{
139 if (usbhsp_is_dcp(pipe)) 133 if (usbhs_pipe_is_dcp(pipe))
140 return; 134 return;
141 135
142 __usbhsp_pipe_xxx_set(pipe, 0, PIPEBUF, mask, val); 136 __usbhsp_pipe_xxx_set(pipe, 0, PIPEBUF, mask, val);
@@ -160,7 +154,7 @@ static u16 usbhsp_pipe_maxp_get(struct usbhs_pipe *pipe)
160 */ 154 */
161static void usbhsp_pipe_select(struct usbhs_pipe *pipe) 155static void usbhsp_pipe_select(struct usbhs_pipe *pipe)
162{ 156{
163 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); 157 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
164 158
165 /* 159 /*
166 * On pipe, this is necessary before 160 * On pipe, this is necessary before
@@ -182,7 +176,7 @@ static void usbhsp_pipe_select(struct usbhs_pipe *pipe)
182 176
183static int usbhsp_pipe_barrier(struct usbhs_pipe *pipe) 177static int usbhsp_pipe_barrier(struct usbhs_pipe *pipe)
184{ 178{
185 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); 179 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
186 int timeout = 1024; 180 int timeout = 1024;
187 u16 val; 181 u16 val;
188 182
@@ -205,7 +199,7 @@ static int usbhsp_pipe_barrier(struct usbhs_pipe *pipe)
205 * - "Pipe Control Registers Switching Procedure" 199 * - "Pipe Control Registers Switching Procedure"
206 */ 200 */
207 usbhs_write(priv, CFIFOSEL, 0); 201 usbhs_write(priv, CFIFOSEL, 0);
208 usbhs_fifo_disable(pipe); 202 usbhs_pipe_disable(pipe);
209 203
210 do { 204 do {
211 val = usbhsp_pipectrl_get(pipe); 205 val = usbhsp_pipectrl_get(pipe);
@@ -220,7 +214,7 @@ static int usbhsp_pipe_barrier(struct usbhs_pipe *pipe)
220 return -EBUSY; 214 return -EBUSY;
221} 215}
222 216
223static int usbhsp_pipe_is_accessible(struct usbhs_pipe *pipe) 217int usbhs_pipe_is_accessible(struct usbhs_pipe *pipe)
224{ 218{
225 u16 val; 219 u16 val;
226 220
@@ -253,7 +247,7 @@ static void __usbhsp_pid_try_nak_if_stall(struct usbhs_pipe *pipe)
253 } 247 }
254} 248}
255 249
256void usbhs_fifo_disable(struct usbhs_pipe *pipe) 250void usbhs_pipe_disable(struct usbhs_pipe *pipe)
257{ 251{
258 int timeout = 1024; 252 int timeout = 1024;
259 u16 val; 253 u16 val;
@@ -273,7 +267,7 @@ void usbhs_fifo_disable(struct usbhs_pipe *pipe)
273 } while (timeout--); 267 } while (timeout--);
274} 268}
275 269
276void usbhs_fifo_enable(struct usbhs_pipe *pipe) 270void usbhs_pipe_enable(struct usbhs_pipe *pipe)
277{ 271{
278 /* see "Pipe n Control Register" - "PID" */ 272 /* see "Pipe n Control Register" - "PID" */
279 __usbhsp_pid_try_nak_if_stall(pipe); 273 __usbhsp_pid_try_nak_if_stall(pipe);
@@ -281,7 +275,7 @@ void usbhs_fifo_enable(struct usbhs_pipe *pipe)
281 usbhsp_pipectrl_set(pipe, PID_MASK, PID_BUF); 275 usbhsp_pipectrl_set(pipe, PID_MASK, PID_BUF);
282} 276}
283 277
284void usbhs_fifo_stall(struct usbhs_pipe *pipe) 278void usbhs_pipe_stall(struct usbhs_pipe *pipe)
285{ 279{
286 u16 pid = usbhsp_pipectrl_get(pipe); 280 u16 pid = usbhsp_pipectrl_get(pipe);
287 281
@@ -302,191 +296,6 @@ void usbhs_fifo_stall(struct usbhs_pipe *pipe)
302} 296}
303 297
304/* 298/*
305 * CFIFO ctrl
306 */
307void usbhs_fifo_send_terminator(struct usbhs_pipe *pipe)
308{
309 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe);
310
311 usbhs_bset(priv, CFIFOCTR, BVAL, BVAL);
312}
313
314static void usbhsp_fifo_clear(struct usbhs_pipe *pipe)
315{
316 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe);
317
318 usbhs_write(priv, CFIFOCTR, BCLR);
319}
320
321static int usbhsp_fifo_barrier(struct usbhs_priv *priv)
322{
323 int timeout = 1024;
324
325 do {
326 /* The FIFO port is accessible */
327 if (usbhs_read(priv, CFIFOCTR) & FRDY)
328 return 0;
329
330 udelay(10);
331 } while (timeout--);
332
333 return -EBUSY;
334}
335
336static int usbhsp_fifo_rcv_len(struct usbhs_priv *priv)
337{
338 return usbhs_read(priv, CFIFOCTR) & DTLN_MASK;
339}
340
341static int usbhsp_fifo_select(struct usbhs_pipe *pipe, int write)
342{
343 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe);
344 struct device *dev = usbhs_priv_to_dev(priv);
345 int timeout = 1024;
346 u16 mask = ((1 << 5) | 0xF); /* mask of ISEL | CURPIPE */
347 u16 base = usbhs_pipe_number(pipe); /* CURPIPE */
348
349 if (usbhsp_is_dcp(pipe))
350 base |= (1 == write) << 5; /* ISEL */
351
352 /* "base" will be used below */
353 usbhs_write(priv, CFIFOSEL, base | MBW_32);
354
355 /* check ISEL and CURPIPE value */
356 while (timeout--) {
357 if (base == (mask & usbhs_read(priv, CFIFOSEL)))
358 return 0;
359 udelay(10);
360 }
361
362 dev_err(dev, "fifo select error\n");
363
364 return -EIO;
365}
366
367int usbhs_fifo_prepare_write(struct usbhs_pipe *pipe)
368{
369 return usbhsp_fifo_select(pipe, 1);
370}
371
372int usbhs_fifo_write(struct usbhs_pipe *pipe, u8 *buf, int len)
373{
374 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe);
375 void __iomem *addr = priv->base + CFIFO;
376 int maxp = usbhs_pipe_get_maxpacket(pipe);
377 int total_len;
378 int i, ret;
379
380 ret = usbhsp_pipe_is_accessible(pipe);
381 if (ret < 0)
382 return ret;
383
384 ret = usbhsp_fifo_select(pipe, 1);
385 if (ret < 0)
386 return ret;
387
388 ret = usbhsp_fifo_barrier(priv);
389 if (ret < 0)
390 return ret;
391
392 len = min(len, maxp);
393 total_len = len;
394
395 /*
396 * FIXME
397 *
398 * 32-bit access only
399 */
400 if (len >= 4 &&
401 !((unsigned long)buf & 0x03)) {
402 iowrite32_rep(addr, buf, len / 4);
403 len %= 4;
404 buf += total_len - len;
405 }
406
407 /* the rest operation */
408 for (i = 0; i < len; i++)
409 iowrite8(buf[i], addr + (0x03 - (i & 0x03)));
410
411 if (total_len < maxp)
412 usbhs_fifo_send_terminator(pipe);
413
414 return total_len;
415}
416
417int usbhs_fifo_prepare_read(struct usbhs_pipe *pipe)
418{
419 int ret;
420
421 /*
422 * select pipe and enable it to prepare packet receive
423 */
424 ret = usbhsp_fifo_select(pipe, 0);
425 if (ret < 0)
426 return ret;
427
428 usbhs_fifo_enable(pipe);
429
430 return ret;
431}
432
433int usbhs_fifo_read(struct usbhs_pipe *pipe, u8 *buf, int len)
434{
435 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe);
436 void __iomem *addr = priv->base + CFIFO;
437 int rcv_len;
438 int i, ret;
439 int total_len;
440 u32 data = 0;
441
442 ret = usbhsp_fifo_select(pipe, 0);
443 if (ret < 0)
444 return ret;
445
446 ret = usbhsp_fifo_barrier(priv);
447 if (ret < 0)
448 return ret;
449
450 rcv_len = usbhsp_fifo_rcv_len(priv);
451
452 /*
453 * Buffer clear if Zero-Length packet
454 *
455 * see
456 * "Operation" - "FIFO Buffer Memory" - "FIFO Port Function"
457 */
458 if (0 == rcv_len) {
459 usbhsp_fifo_clear(pipe);
460 return 0;
461 }
462
463 len = min(rcv_len, len);
464 total_len = len;
465
466 /*
467 * FIXME
468 *
469 * 32-bit access only
470 */
471 if (len >= 4 &&
472 !((unsigned long)buf & 0x03)) {
473 ioread32_rep(addr, buf, len / 4);
474 len %= 4;
475 buf += rcv_len - len;
476 }
477
478 /* the rest operation */
479 for (i = 0; i < len; i++) {
480 if (!(i & 0x03))
481 data = ioread32(addr);
482
483 buf[i] = (data >> ((i & 0x03) * 8)) & 0xff;
484 }
485
486 return total_len;
487}
488
489/*
490 * pipe setup 299 * pipe setup
491 */ 300 */
492static int usbhsp_possible_double_buffer(struct usbhs_pipe *pipe) 301static int usbhsp_possible_double_buffer(struct usbhs_pipe *pipe)
@@ -519,7 +328,7 @@ static u16 usbhsp_setup_pipecfg(struct usbhs_pipe *pipe,
519 }; 328 };
520 int is_double = usbhsp_possible_double_buffer(pipe); 329 int is_double = usbhsp_possible_double_buffer(pipe);
521 330
522 if (usbhsp_is_dcp(pipe)) 331 if (usbhs_pipe_is_dcp(pipe))
523 return -EINVAL; 332 return -EINVAL;
524 333
525 /* 334 /*
@@ -590,8 +399,8 @@ static u16 usbhsp_setup_pipebuff(struct usbhs_pipe *pipe,
590 const struct usb_endpoint_descriptor *desc, 399 const struct usb_endpoint_descriptor *desc,
591 int is_host) 400 int is_host)
592{ 401{
593 struct usbhs_priv *priv = usbhsp_pipe_to_priv(pipe); 402 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
594 struct usbhs_pipe_info *info = usbhsp_priv_to_pipeinfo(priv); 403 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
595 struct device *dev = usbhs_priv_to_dev(priv); 404 struct device *dev = usbhs_priv_to_dev(priv);
596 int pipe_num = usbhs_pipe_number(pipe); 405 int pipe_num = usbhs_pipe_number(pipe);
597 int is_double = usbhsp_possible_double_buffer(pipe); 406 int is_double = usbhsp_possible_double_buffer(pipe);
@@ -669,7 +478,7 @@ static u16 usbhsp_setup_pipebuff(struct usbhs_pipe *pipe,
669 */ 478 */
670int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe) 479int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe)
671{ 480{
672 u16 mask = usbhsp_is_dcp(pipe) ? DCP_MAXP_MASK : PIPE_MAXP_MASK; 481 u16 mask = usbhs_pipe_is_dcp(pipe) ? DCP_MAXP_MASK : PIPE_MAXP_MASK;
673 482
674 usbhsp_pipe_select(pipe); 483 usbhsp_pipe_select(pipe);
675 484
@@ -724,7 +533,7 @@ static struct usbhs_pipe *usbhsp_get_pipe(struct usbhs_priv *priv, u32 type)
724 533
725void usbhs_pipe_init(struct usbhs_priv *priv) 534void usbhs_pipe_init(struct usbhs_priv *priv)
726{ 535{
727 struct usbhs_pipe_info *info = usbhsp_priv_to_pipeinfo(priv); 536 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
728 struct usbhs_pipe *pipe; 537 struct usbhs_pipe *pipe;
729 int i; 538 int i;
730 539
@@ -748,7 +557,9 @@ void usbhs_pipe_init(struct usbhs_priv *priv)
748 usbhsp_flags_init(pipe); 557 usbhsp_flags_init(pipe);
749 pipe->mod_private = NULL; 558 pipe->mod_private = NULL;
750 559
751 usbhsp_fifo_clear(pipe); 560 /* pipe force init */
561 usbhsp_pipectrl_set(pipe, ACLRM, ACLRM);
562 usbhsp_pipectrl_set(pipe, ACLRM, 0);
752 } 563 }
753} 564}
754 565
@@ -769,7 +580,7 @@ struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv,
769 return NULL; 580 return NULL;
770 } 581 }
771 582
772 usbhs_fifo_disable(pipe); 583 usbhs_pipe_disable(pipe);
773 584
774 /* make sure pipe is not busy */ 585 /* make sure pipe is not busy */
775 ret = usbhsp_pipe_barrier(pipe); 586 ret = usbhsp_pipe_barrier(pipe);
@@ -782,11 +593,6 @@ struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv,
782 pipebuf = usbhsp_setup_pipebuff(pipe, desc, is_host); 593 pipebuf = usbhsp_setup_pipebuff(pipe, desc, is_host);
783 pipemaxp = usbhsp_setup_pipemaxp(pipe, desc, is_host); 594 pipemaxp = usbhsp_setup_pipemaxp(pipe, desc, is_host);
784 595
785 /* buffer clear
786 * see PIPECFG :: BFRE */
787 usbhsp_pipectrl_set(pipe, ACLRM, ACLRM);
788 usbhsp_pipectrl_set(pipe, ACLRM, 0);
789
790 usbhsp_pipe_select(pipe); 596 usbhsp_pipe_select(pipe);
791 usbhsp_pipe_cfg_set(pipe, 0xFFFF, pipecfg); 597 usbhsp_pipe_cfg_set(pipe, 0xFFFF, pipecfg);
792 usbhsp_pipe_buf_set(pipe, 0xFFFF, pipebuf); 598 usbhsp_pipe_buf_set(pipe, 0xFFFF, pipebuf);
@@ -827,9 +633,9 @@ struct usbhs_pipe *usbhs_dcp_malloc(struct usbhs_priv *priv)
827 633
828void usbhs_dcp_control_transfer_done(struct usbhs_pipe *pipe) 634void usbhs_dcp_control_transfer_done(struct usbhs_pipe *pipe)
829{ 635{
830 WARN_ON(!usbhsp_is_dcp(pipe)); 636 WARN_ON(!usbhs_pipe_is_dcp(pipe));
831 637
832 usbhs_fifo_enable(pipe); 638 usbhs_pipe_enable(pipe);
833 usbhsp_pipectrl_set(pipe, CCPL, CCPL); 639 usbhsp_pipectrl_set(pipe, CCPL, CCPL);
834} 640}
835 641
@@ -839,7 +645,7 @@ void usbhs_dcp_control_transfer_done(struct usbhs_pipe *pipe)
839 */ 645 */
840int usbhs_pipe_probe(struct usbhs_priv *priv) 646int usbhs_pipe_probe(struct usbhs_priv *priv)
841{ 647{
842 struct usbhs_pipe_info *info = usbhsp_priv_to_pipeinfo(priv); 648 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
843 struct usbhs_pipe *pipe; 649 struct usbhs_pipe *pipe;
844 struct device *dev = usbhs_priv_to_dev(priv); 650 struct device *dev = usbhs_priv_to_dev(priv);
845 u32 *pipe_type = usbhs_get_dparam(priv, pipe_type); 651 u32 *pipe_type = usbhs_get_dparam(priv, pipe_type);
@@ -876,7 +682,7 @@ int usbhs_pipe_probe(struct usbhs_priv *priv)
876 682
877void usbhs_pipe_remove(struct usbhs_priv *priv) 683void usbhs_pipe_remove(struct usbhs_priv *priv)
878{ 684{
879 struct usbhs_pipe_info *info = usbhsp_priv_to_pipeinfo(priv); 685 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
880 686
881 kfree(info->pipe); 687 kfree(info->pipe);
882} 688}