blob: ff97a8e4fcda977ed85dd8ed665373768dbbd85f [file] [log] [blame]
Kuninori Morimotof1407d52011-04-04 13:44:59 +09001/*
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>
Kuninori Morimotof1407d52011-04-04 13:44:59 +090018#include <linux/slab.h>
19#include "./common.h"
20#include "./pipe.h"
21
22/*
23 * macros
24 */
Kuninori Morimotof1407d52011-04-04 13:44:59 +090025#define usbhsp_addr_offset(p) ((usbhs_pipe_number(p) - 1) * 2)
26
Kuninori Morimotof1407d52011-04-04 13:44:59 +090027#define usbhsp_flags_set(p, f) ((p)->flags |= USBHS_PIPE_FLAGS_##f)
28#define usbhsp_flags_clr(p, f) ((p)->flags &= ~USBHS_PIPE_FLAGS_##f)
29#define usbhsp_flags_has(p, f) ((p)->flags & USBHS_PIPE_FLAGS_##f)
30#define usbhsp_flags_init(p) do {(p)->flags = 0; } while (0)
31
Kuninori Morimotof1407d52011-04-04 13:44:59 +090032/*
33 * for debug
34 */
35static char *usbhsp_pipe_name[] = {
36 [USB_ENDPOINT_XFER_CONTROL] = "DCP",
37 [USB_ENDPOINT_XFER_BULK] = "BULK",
38 [USB_ENDPOINT_XFER_INT] = "INT",
39 [USB_ENDPOINT_XFER_ISOC] = "ISO",
40};
41
42/*
Kuninori Morimotof1407d52011-04-04 13:44:59 +090043 * DCPCTR/PIPEnCTR functions
44 */
45static void usbhsp_pipectrl_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
46{
Kuninori Morimotoe8d548d2011-06-06 14:18:03 +090047 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
Kuninori Morimotof1407d52011-04-04 13:44:59 +090048 int offset = usbhsp_addr_offset(pipe);
49
Kuninori Morimotoe8d548d2011-06-06 14:18:03 +090050 if (usbhs_pipe_is_dcp(pipe))
Kuninori Morimotof1407d52011-04-04 13:44:59 +090051 usbhs_bset(priv, DCPCTR, mask, val);
52 else
53 usbhs_bset(priv, PIPEnCTR + offset, mask, val);
54}
55
56static u16 usbhsp_pipectrl_get(struct usbhs_pipe *pipe)
57{
Kuninori Morimotoe8d548d2011-06-06 14:18:03 +090058 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
Kuninori Morimotof1407d52011-04-04 13:44:59 +090059 int offset = usbhsp_addr_offset(pipe);
60
Kuninori Morimotoe8d548d2011-06-06 14:18:03 +090061 if (usbhs_pipe_is_dcp(pipe))
Kuninori Morimotof1407d52011-04-04 13:44:59 +090062 return usbhs_read(priv, DCPCTR);
63 else
64 return usbhs_read(priv, PIPEnCTR + offset);
65}
66
67/*
68 * DCP/PIPE functions
69 */
70static void __usbhsp_pipe_xxx_set(struct usbhs_pipe *pipe,
71 u16 dcp_reg, u16 pipe_reg,
72 u16 mask, u16 val)
73{
Kuninori Morimotoe8d548d2011-06-06 14:18:03 +090074 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
Kuninori Morimotof1407d52011-04-04 13:44:59 +090075
Kuninori Morimotoe8d548d2011-06-06 14:18:03 +090076 if (usbhs_pipe_is_dcp(pipe))
Kuninori Morimotof1407d52011-04-04 13:44:59 +090077 usbhs_bset(priv, dcp_reg, mask, val);
78 else
79 usbhs_bset(priv, pipe_reg, mask, val);
80}
81
Kuninori Morimotof1407d52011-04-04 13:44:59 +090082/*
83 * DCPCFG/PIPECFG functions
84 */
85static void usbhsp_pipe_cfg_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
86{
87 __usbhsp_pipe_xxx_set(pipe, DCPCFG, PIPECFG, mask, val);
88}
89
90/*
91 * PIPEBUF
92 */
93static void usbhsp_pipe_buf_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
94{
Kuninori Morimotoe8d548d2011-06-06 14:18:03 +090095 if (usbhs_pipe_is_dcp(pipe))
Kuninori Morimotof1407d52011-04-04 13:44:59 +090096 return;
97
98 __usbhsp_pipe_xxx_set(pipe, 0, PIPEBUF, mask, val);
99}
100
101/*
102 * DCPMAXP/PIPEMAXP
103 */
104static void usbhsp_pipe_maxp_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
105{
106 __usbhsp_pipe_xxx_set(pipe, DCPMAXP, PIPEMAXP, mask, val);
107}
108
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900109/*
110 * pipe control functions
111 */
112static void usbhsp_pipe_select(struct usbhs_pipe *pipe)
113{
Kuninori Morimotoe8d548d2011-06-06 14:18:03 +0900114 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900115
116 /*
117 * On pipe, this is necessary before
118 * accesses to below registers.
119 *
120 * PIPESEL : usbhsp_pipe_select
121 * PIPECFG : usbhsp_pipe_cfg_xxx
122 * PIPEBUF : usbhsp_pipe_buf_xxx
123 * PIPEMAXP : usbhsp_pipe_maxp_xxx
124 * PIPEPERI
125 */
126
127 /*
128 * if pipe is dcp, no pipe is selected.
129 * it is no problem, because dcp have its register
130 */
131 usbhs_write(priv, PIPESEL, 0xF & usbhs_pipe_number(pipe));
132}
133
134static int usbhsp_pipe_barrier(struct usbhs_pipe *pipe)
135{
Kuninori Morimotoe8d548d2011-06-06 14:18:03 +0900136 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900137 int timeout = 1024;
138 u16 val;
139
140 /*
141 * make sure....
142 *
143 * Modify these bits when CSSTS = 0, PID = NAK, and no pipe number is
144 * specified by the CURPIPE bits.
145 * When changing the setting of this bit after changing
146 * the PID bits for the selected pipe from BUF to NAK,
147 * check that CSSTS = 0 and PBUSY = 0.
148 */
149
150 /*
151 * CURPIPE bit = 0
152 *
153 * see also
154 * "Operation"
155 * - "Pipe Control"
156 * - "Pipe Control Registers Switching Procedure"
157 */
158 usbhs_write(priv, CFIFOSEL, 0);
Kuninori Morimotoe8d548d2011-06-06 14:18:03 +0900159 usbhs_pipe_disable(pipe);
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900160
161 do {
162 val = usbhsp_pipectrl_get(pipe);
163 val &= CSSTS | PID_MASK;
164 if (!val)
165 return 0;
166
167 udelay(10);
168
169 } while (timeout--);
170
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900171 return -EBUSY;
172}
173
Kuninori Morimotoe8d548d2011-06-06 14:18:03 +0900174int usbhs_pipe_is_accessible(struct usbhs_pipe *pipe)
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900175{
176 u16 val;
177
178 val = usbhsp_pipectrl_get(pipe);
179 if (val & BSTS)
180 return 0;
181
182 return -EBUSY;
183}
184
185/*
186 * PID ctrl
187 */
188static void __usbhsp_pid_try_nak_if_stall(struct usbhs_pipe *pipe)
189{
190 u16 pid = usbhsp_pipectrl_get(pipe);
191
192 pid &= PID_MASK;
193
194 /*
195 * see
196 * "Pipe n Control Register" - "PID"
197 */
198 switch (pid) {
199 case PID_STALL11:
200 usbhsp_pipectrl_set(pipe, PID_MASK, PID_STALL10);
201 /* fall-through */
202 case PID_STALL10:
203 usbhsp_pipectrl_set(pipe, PID_MASK, PID_NAK);
204 }
205}
206
Kuninori Morimotoe8d548d2011-06-06 14:18:03 +0900207void usbhs_pipe_disable(struct usbhs_pipe *pipe)
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900208{
Kuninori Morimotoc786e092011-05-11 16:00:09 +0900209 int timeout = 1024;
210 u16 val;
211
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900212 /* see "Pipe n Control Register" - "PID" */
213 __usbhsp_pid_try_nak_if_stall(pipe);
214
215 usbhsp_pipectrl_set(pipe, PID_MASK, PID_NAK);
Kuninori Morimotoc786e092011-05-11 16:00:09 +0900216
217 do {
218 val = usbhsp_pipectrl_get(pipe);
219 val &= PBUSY;
220 if (!val)
221 break;
222
223 udelay(10);
224 } while (timeout--);
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900225}
226
Kuninori Morimotoe8d548d2011-06-06 14:18:03 +0900227void usbhs_pipe_enable(struct usbhs_pipe *pipe)
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900228{
229 /* see "Pipe n Control Register" - "PID" */
230 __usbhsp_pid_try_nak_if_stall(pipe);
231
232 usbhsp_pipectrl_set(pipe, PID_MASK, PID_BUF);
233}
234
Kuninori Morimotoe8d548d2011-06-06 14:18:03 +0900235void usbhs_pipe_stall(struct usbhs_pipe *pipe)
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900236{
237 u16 pid = usbhsp_pipectrl_get(pipe);
238
239 pid &= PID_MASK;
240
241 /*
242 * see
243 * "Pipe n Control Register" - "PID"
244 */
245 switch (pid) {
246 case PID_NAK:
247 usbhsp_pipectrl_set(pipe, PID_MASK, PID_STALL10);
248 break;
249 case PID_BUF:
250 usbhsp_pipectrl_set(pipe, PID_MASK, PID_STALL11);
251 break;
252 }
253}
254
255/*
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900256 * pipe setup
257 */
258static int usbhsp_possible_double_buffer(struct usbhs_pipe *pipe)
259{
260 /*
261 * only ISO / BULK pipe can use double buffer
262 */
Kuninori Morimoto356db7e2011-10-10 22:02:21 -0700263 if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK) ||
264 usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_ISOC))
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900265 return 1;
266
267 return 0;
268}
269
270static u16 usbhsp_setup_pipecfg(struct usbhs_pipe *pipe,
Kuninori Morimotof5aa8892011-10-10 21:59:46 -0700271 int is_host,
272 int dir_in)
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900273{
274 u16 type = 0;
275 u16 bfre = 0;
276 u16 dblb = 0;
277 u16 cntmd = 0;
278 u16 dir = 0;
279 u16 epnum = 0;
280 u16 shtnak = 0;
281 u16 type_array[] = {
282 [USB_ENDPOINT_XFER_BULK] = TYPE_BULK,
283 [USB_ENDPOINT_XFER_INT] = TYPE_INT,
284 [USB_ENDPOINT_XFER_ISOC] = TYPE_ISO,
285 };
286 int is_double = usbhsp_possible_double_buffer(pipe);
287
Kuninori Morimotoe8d548d2011-06-06 14:18:03 +0900288 if (usbhs_pipe_is_dcp(pipe))
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900289 return -EINVAL;
290
291 /*
292 * PIPECFG
293 *
294 * see
295 * - "Register Descriptions" - "PIPECFG" register
296 * - "Features" - "Pipe configuration"
297 * - "Operation" - "Pipe Control"
298 */
299
300 /* TYPE */
Kuninori Morimoto356db7e2011-10-10 22:02:21 -0700301 type = type_array[usbhs_pipe_type(pipe)];
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900302
303 /* BFRE */
Kuninori Morimoto356db7e2011-10-10 22:02:21 -0700304 if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_ISOC) ||
305 usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK))
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900306 bfre = 0; /* FIXME */
307
308 /* DBLB */
Kuninori Morimoto356db7e2011-10-10 22:02:21 -0700309 if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_ISOC) ||
310 usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK))
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900311 dblb = (is_double) ? DBLB : 0;
312
313 /* CNTMD */
Kuninori Morimoto356db7e2011-10-10 22:02:21 -0700314 if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK))
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900315 cntmd = 0; /* FIXME */
316
317 /* DIR */
Kuninori Morimotof5aa8892011-10-10 21:59:46 -0700318 if (dir_in)
Kuninori Morimotoad6f2a82011-06-06 14:17:56 +0900319 usbhsp_flags_set(pipe, IS_DIR_HOST);
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900320
Kuninori Morimotof5aa8892011-10-10 21:59:46 -0700321 if ((is_host && !dir_in) ||
322 (!is_host && dir_in))
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900323 dir |= DIR_OUT;
324
Kuninori Morimotoad6f2a82011-06-06 14:17:56 +0900325 if (!dir)
326 usbhsp_flags_set(pipe, IS_DIR_IN);
327
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900328 /* SHTNAK */
Kuninori Morimoto356db7e2011-10-10 22:02:21 -0700329 if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK) &&
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900330 !dir)
331 shtnak = SHTNAK;
332
333 /* EPNUM */
Kuninori Morimotof5aa8892011-10-10 21:59:46 -0700334 epnum = 0; /* see usbhs_pipe_config_update() */
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900335
336 return type |
337 bfre |
338 dblb |
339 cntmd |
340 dir |
341 shtnak |
342 epnum;
343}
344
Kuninori Morimotof5aa8892011-10-10 21:59:46 -0700345static u16 usbhsp_setup_pipebuff(struct usbhs_pipe *pipe)
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900346{
Kuninori Morimotoe8d548d2011-06-06 14:18:03 +0900347 struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
348 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900349 struct device *dev = usbhs_priv_to_dev(priv);
350 int pipe_num = usbhs_pipe_number(pipe);
351 int is_double = usbhsp_possible_double_buffer(pipe);
352 u16 buff_size;
353 u16 bufnmb;
354 u16 bufnmb_cnt;
355
356 /*
357 * PIPEBUF
358 *
359 * see
360 * - "Register Descriptions" - "PIPEBUF" register
361 * - "Features" - "Pipe configuration"
362 * - "Operation" - "FIFO Buffer Memory"
363 * - "Operation" - "Pipe Control"
364 *
365 * ex) if pipe6 - pipe9 are USB_ENDPOINT_XFER_INT (SH7724)
366 *
367 * BUFNMB: PIPE
368 * 0: pipe0 (DCP 256byte)
369 * 1: -
370 * 2: -
371 * 3: -
372 * 4: pipe6 (INT 64byte)
373 * 5: pipe7 (INT 64byte)
374 * 6: pipe8 (INT 64byte)
375 * 7: pipe9 (INT 64byte)
376 * 8 - xx: free (for BULK, ISOC)
377 */
378
379 /*
380 * FIXME
381 *
382 * it doesn't have good buffer allocator
383 *
384 * DCP : 256 byte
385 * BULK: 512 byte
386 * INT : 64 byte
387 * ISOC: 512 byte
388 */
Kuninori Morimoto356db7e2011-10-10 22:02:21 -0700389 if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_CONTROL))
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900390 buff_size = 256;
Kuninori Morimoto356db7e2011-10-10 22:02:21 -0700391 else if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_INT))
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900392 buff_size = 64;
393 else
394 buff_size = 512;
395
396 /* change buff_size to register value */
397 bufnmb_cnt = (buff_size / 64) - 1;
398
399 /* BUFNMB has been reserved for INT pipe
400 * see above */
Kuninori Morimoto356db7e2011-10-10 22:02:21 -0700401 if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_INT)) {
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900402 bufnmb = pipe_num - 2;
403 } else {
404 bufnmb = info->bufnmb_last;
405 info->bufnmb_last += bufnmb_cnt + 1;
406
407 /*
408 * double buffer
409 */
410 if (is_double)
411 info->bufnmb_last += bufnmb_cnt + 1;
412 }
413
414 dev_dbg(dev, "pipe : %d : buff_size 0x%x: bufnmb 0x%x\n",
415 pipe_num, buff_size, bufnmb);
416
417 return (0x1f & bufnmb_cnt) << 10 |
418 (0xff & bufnmb) << 0;
419}
420
Kuninori Morimotof5aa8892011-10-10 21:59:46 -0700421void usbhs_pipe_config_update(struct usbhs_pipe *pipe, u16 epnum, u16 maxp)
422{
423 usbhsp_pipe_barrier(pipe);
424
Kuninori Morimoto7fd097e2011-10-10 22:00:42 -0700425 pipe->maxp = maxp;
426
Kuninori Morimotof5aa8892011-10-10 21:59:46 -0700427 usbhsp_pipe_select(pipe);
428 usbhsp_pipe_maxp_set(pipe, 0xFFFF, maxp);
429
430 if (!usbhs_pipe_is_dcp(pipe))
431 usbhsp_pipe_cfg_set(pipe, 0x000F, epnum);
432}
433
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900434/*
435 * pipe control
436 */
437int usbhs_pipe_get_maxpacket(struct usbhs_pipe *pipe)
438{
Kuninori Morimoto7fd097e2011-10-10 22:00:42 -0700439 /*
440 * see
441 * usbhs_pipe_config_update()
442 * usbhs_dcp_malloc()
443 */
444 return pipe->maxp;
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900445}
446
447int usbhs_pipe_is_dir_in(struct usbhs_pipe *pipe)
448{
449 return usbhsp_flags_has(pipe, IS_DIR_IN);
450}
451
Kuninori Morimotoad6f2a82011-06-06 14:17:56 +0900452int usbhs_pipe_is_dir_host(struct usbhs_pipe *pipe)
453{
454 return usbhsp_flags_has(pipe, IS_DIR_HOST);
455}
456
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900457void usbhs_pipe_clear_sequence(struct usbhs_pipe *pipe)
458{
459 usbhsp_pipectrl_set(pipe, SQCLR, SQCLR);
460}
461
Kuninori Morimoto08e6c612011-06-09 16:48:25 +0900462void usbhs_pipe_clear(struct usbhs_pipe *pipe)
463{
464 usbhsp_pipectrl_set(pipe, ACLRM, ACLRM);
465 usbhsp_pipectrl_set(pipe, ACLRM, 0);
466}
467
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900468static struct usbhs_pipe *usbhsp_get_pipe(struct usbhs_priv *priv, u32 type)
469{
470 struct usbhs_pipe *pos, *pipe;
471 int i;
472
473 /*
474 * find target pipe
475 */
476 pipe = NULL;
477 usbhs_for_each_pipe_with_dcp(pos, priv, i) {
Kuninori Morimoto356db7e2011-10-10 22:02:21 -0700478 if (!usbhs_pipe_type_is(pos, type))
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900479 continue;
480 if (usbhsp_flags_has(pos, IS_USED))
481 continue;
482
483 pipe = pos;
484 break;
485 }
486
487 if (!pipe)
488 return NULL;
489
490 /*
491 * initialize pipe flags
492 */
493 usbhsp_flags_init(pipe);
494 usbhsp_flags_set(pipe, IS_USED);
495
496 return pipe;
497}
498
Kuninori Morimoto4bd04812011-06-06 14:18:07 +0900499void usbhs_pipe_init(struct usbhs_priv *priv,
Kuninori Morimotoe73a9892011-06-06 14:19:03 +0900500 void (*done)(struct usbhs_pkt *pkt),
501 int (*dma_map_ctrl)(struct usbhs_pkt *pkt, int map))
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900502{
Kuninori Morimotoe8d548d2011-06-06 14:18:03 +0900503 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
Kuninori Morimotodad67392011-06-06 14:18:28 +0900504 struct device *dev = usbhs_priv_to_dev(priv);
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900505 struct usbhs_pipe *pipe;
506 int i;
507
Kuninori Morimotodad67392011-06-06 14:18:28 +0900508 if (!done) {
509 dev_err(dev, "no done function\n");
510 return;
511 }
512
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900513 /*
514 * FIXME
515 *
516 * driver needs good allocator.
517 *
518 * find first free buffer area (BULK, ISOC)
519 * (DCP, INT area is fixed)
520 *
521 * buffer number 0 - 3 have been reserved for DCP
522 * see
523 * usbhsp_to_bufnmb
524 */
525 info->bufnmb_last = 4;
526 usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
Kuninori Morimoto356db7e2011-10-10 22:02:21 -0700527 if (usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_INT))
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900528 info->bufnmb_last++;
529
530 usbhsp_flags_init(pipe);
Kuninori Morimotod77e3f42011-06-06 14:18:50 +0900531 pipe->fifo = NULL;
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900532 pipe->mod_private = NULL;
Kuninori Morimoto6acb95d2011-06-06 14:18:16 +0900533 INIT_LIST_HEAD(&pipe->list);
Kuninori Morimoto45e13e62011-04-21 14:09:58 +0900534
Kuninori Morimotoe8d548d2011-06-06 14:18:03 +0900535 /* pipe force init */
Kuninori Morimoto08e6c612011-06-09 16:48:25 +0900536 usbhs_pipe_clear(pipe);
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900537 }
Kuninori Morimoto4bd04812011-06-06 14:18:07 +0900538
Kuninori Morimotodad67392011-06-06 14:18:28 +0900539 info->done = done;
Kuninori Morimotoe73a9892011-06-06 14:19:03 +0900540 info->dma_map_ctrl = dma_map_ctrl;
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900541}
542
543struct usbhs_pipe *usbhs_pipe_malloc(struct usbhs_priv *priv,
Kuninori Morimotof5aa8892011-10-10 21:59:46 -0700544 int endpoint_type,
545 int dir_in)
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900546{
547 struct device *dev = usbhs_priv_to_dev(priv);
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900548 struct usbhs_pipe *pipe;
Kuninori Morimoto0deb3e72011-10-10 22:02:45 -0700549 int is_host = usbhs_mod_is_host(priv);
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900550 int ret;
Kuninori Morimotof5aa8892011-10-10 21:59:46 -0700551 u16 pipecfg, pipebuf;
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900552
Kuninori Morimotof5aa8892011-10-10 21:59:46 -0700553 pipe = usbhsp_get_pipe(priv, endpoint_type);
Kuninori Morimotof429ea32011-04-21 14:10:24 +0900554 if (!pipe) {
555 dev_err(dev, "can't get pipe (%s)\n",
Kuninori Morimotof5aa8892011-10-10 21:59:46 -0700556 usbhsp_pipe_name[endpoint_type]);
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900557 return NULL;
Kuninori Morimotof429ea32011-04-21 14:10:24 +0900558 }
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900559
Kuninori Morimoto6acb95d2011-06-06 14:18:16 +0900560 INIT_LIST_HEAD(&pipe->list);
561
Kuninori Morimotoe8d548d2011-06-06 14:18:03 +0900562 usbhs_pipe_disable(pipe);
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900563
564 /* make sure pipe is not busy */
565 ret = usbhsp_pipe_barrier(pipe);
566 if (ret < 0) {
567 dev_err(dev, "pipe setup failed %d\n", usbhs_pipe_number(pipe));
568 return NULL;
569 }
570
Kuninori Morimotof5aa8892011-10-10 21:59:46 -0700571 pipecfg = usbhsp_setup_pipecfg(pipe, is_host, dir_in);
572 pipebuf = usbhsp_setup_pipebuff(pipe);
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900573
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900574 usbhsp_pipe_select(pipe);
575 usbhsp_pipe_cfg_set(pipe, 0xFFFF, pipecfg);
576 usbhsp_pipe_buf_set(pipe, 0xFFFF, pipebuf);
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900577
578 usbhs_pipe_clear_sequence(pipe);
579
580 dev_dbg(dev, "enable pipe %d : %s (%s)\n",
581 usbhs_pipe_number(pipe),
Kuninori Morimotof5aa8892011-10-10 21:59:46 -0700582 usbhsp_pipe_name[endpoint_type],
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900583 usbhs_pipe_is_dir_in(pipe) ? "in" : "out");
584
Kuninori Morimotof5aa8892011-10-10 21:59:46 -0700585 /*
586 * epnum / maxp are still not set to this pipe.
587 * call usbhs_pipe_config_update() after this function !!
588 */
589
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900590 return pipe;
591}
592
Kuninori Morimotod77e3f42011-06-06 14:18:50 +0900593void usbhs_pipe_select_fifo(struct usbhs_pipe *pipe, struct usbhs_fifo *fifo)
594{
595 if (pipe->fifo)
596 pipe->fifo->pipe = NULL;
597
598 pipe->fifo = fifo;
599
600 if (fifo)
601 fifo->pipe = pipe;
602}
603
604
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900605/*
606 * dcp control
607 */
608struct usbhs_pipe *usbhs_dcp_malloc(struct usbhs_priv *priv)
609{
610 struct usbhs_pipe *pipe;
611
612 pipe = usbhsp_get_pipe(priv, USB_ENDPOINT_XFER_CONTROL);
613 if (!pipe)
614 return NULL;
615
Kuninori Morimoto6acb95d2011-06-06 14:18:16 +0900616 INIT_LIST_HEAD(&pipe->list);
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900617
Kuninori Morimotof5aa8892011-10-10 21:59:46 -0700618 /*
619 * call usbhs_pipe_config_update() after this function !!
620 */
621
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900622 return pipe;
623}
624
625void usbhs_dcp_control_transfer_done(struct usbhs_pipe *pipe)
626{
Kuninori Morimotoe8d548d2011-06-06 14:18:03 +0900627 WARN_ON(!usbhs_pipe_is_dcp(pipe));
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900628
Kuninori Morimotoe8d548d2011-06-06 14:18:03 +0900629 usbhs_pipe_enable(pipe);
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900630 usbhsp_pipectrl_set(pipe, CCPL, CCPL);
631}
632
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900633/*
634 * pipe module function
635 */
636int usbhs_pipe_probe(struct usbhs_priv *priv)
637{
Kuninori Morimotoe8d548d2011-06-06 14:18:03 +0900638 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900639 struct usbhs_pipe *pipe;
640 struct device *dev = usbhs_priv_to_dev(priv);
641 u32 *pipe_type = usbhs_get_dparam(priv, pipe_type);
642 int pipe_size = usbhs_get_dparam(priv, pipe_size);
643 int i;
644
645 /* This driver expects 1st pipe is DCP */
646 if (pipe_type[0] != USB_ENDPOINT_XFER_CONTROL) {
647 dev_err(dev, "1st PIPE is not DCP\n");
648 return -EINVAL;
649 }
650
651 info->pipe = kzalloc(sizeof(struct usbhs_pipe) * pipe_size, GFP_KERNEL);
652 if (!info->pipe) {
653 dev_err(dev, "Could not allocate pipe\n");
654 return -ENOMEM;
655 }
656
657 info->size = pipe_size;
658
659 /*
660 * init pipe
661 */
662 usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
663 pipe->priv = priv;
Kuninori Morimoto356db7e2011-10-10 22:02:21 -0700664
665 usbhs_pipe_type(pipe) =
666 pipe_type[i] & USB_ENDPOINT_XFERTYPE_MASK;
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900667
668 dev_dbg(dev, "pipe %x\t: %s\n",
669 i, usbhsp_pipe_name[pipe_type[i]]);
670 }
671
672 return 0;
673}
674
675void usbhs_pipe_remove(struct usbhs_priv *priv)
676{
Kuninori Morimotoe8d548d2011-06-06 14:18:03 +0900677 struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
Kuninori Morimotof1407d52011-04-04 13:44:59 +0900678
679 kfree(info->pipe);
680}