aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/s3c-hsotg.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/s3c-hsotg.c')
-rw-r--r--drivers/usb/gadget/s3c-hsotg.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
index 1f73b485732d..26193eceb323 100644
--- a/drivers/usb/gadget/s3c-hsotg.c
+++ b/drivers/usb/gadget/s3c-hsotg.c
@@ -297,6 +297,12 @@ static void s3c_hsotg_ctrl_epint(struct s3c_hsotg *hsotg,
297 */ 297 */
298static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg) 298static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg)
299{ 299{
300 unsigned int ep;
301 unsigned int addr;
302 unsigned int size;
303 int timeout;
304 u32 val;
305
300 /* the ryu 2.6.24 release ahs 306 /* the ryu 2.6.24 release ahs
301 writel(0x1C0, hsotg->regs + S3C_GRXFSIZ); 307 writel(0x1C0, hsotg->regs + S3C_GRXFSIZ);
302 writel(S3C_GNPTXFSIZ_NPTxFStAddr(0x200) | 308 writel(S3C_GNPTXFSIZ_NPTxFStAddr(0x200) |
@@ -310,6 +316,51 @@ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg)
310 writel(S3C_GNPTXFSIZ_NPTxFStAddr(2048) | 316 writel(S3C_GNPTXFSIZ_NPTxFStAddr(2048) |
311 S3C_GNPTXFSIZ_NPTxFDep(0x1C0), 317 S3C_GNPTXFSIZ_NPTxFDep(0x1C0),
312 hsotg->regs + S3C_GNPTXFSIZ); 318 hsotg->regs + S3C_GNPTXFSIZ);
319
320 /* arange all the rest of the TX FIFOs, as some versions of this
321 * block have overlapping default addresses. This also ensures
322 * that if the settings have been changed, then they are set to
323 * known values. */
324
325 /* start at the end of the GNPTXFSIZ, rounded up */
326 addr = 2048 + 1024;
327 size = 768;
328
329 /* currently we allocate TX FIFOs for all possible endpoints,
330 * and assume that they are all the same size. */
331
332 for (ep = 0; ep <= 15; ep++) {
333 val = addr;
334 val |= size << S3C_DPTXFSIZn_DPTxFSize_SHIFT;
335 addr += size;
336
337 writel(val, hsotg->regs + S3C_DPTXFSIZn(ep));
338 }
339
340 /* according to p428 of the design guide, we need to ensure that
341 * all fifos are flushed before continuing */
342
343 writel(S3C_GRSTCTL_TxFNum(0x10) | S3C_GRSTCTL_TxFFlsh |
344 S3C_GRSTCTL_RxFFlsh, hsotg->regs + S3C_GRSTCTL);
345
346 /* wait until the fifos are both flushed */
347 timeout = 100;
348 while (1) {
349 val = readl(hsotg->regs + S3C_GRSTCTL);
350
351 if ((val & (S3C_GRSTCTL_TxFFlsh | S3C_GRSTCTL_RxFFlsh)) == 0)
352 break;
353
354 if (--timeout == 0) {
355 dev_err(hsotg->dev,
356 "%s: timeout flushing fifos (GRSTCTL=%08x)\n",
357 __func__, val);
358 }
359
360 udelay(1);
361 }
362
363 dev_dbg(hsotg->dev, "FIFOs reset, timeout at %d\n", timeout);
313} 364}
314 365
315/** 366/**
@@ -2574,6 +2625,9 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
2574 writel(S3C_DCTL_CGOUTNak | S3C_DCTL_CGNPInNAK, 2625 writel(S3C_DCTL_CGOUTNak | S3C_DCTL_CGNPInNAK,
2575 hsotg->regs + S3C_DCTL); 2626 hsotg->regs + S3C_DCTL);
2576 2627
2628 /* must be at-least 3ms to allow bus to see disconnect */
2629 msleep(3);
2630
2577 /* remove the soft-disconnect and let's go */ 2631 /* remove the soft-disconnect and let's go */
2578 __bic32(hsotg->regs + S3C_DCTL, S3C_DCTL_SftDiscon); 2632 __bic32(hsotg->regs + S3C_DCTL, S3C_DCTL_SftDiscon);
2579 2633
@@ -2730,6 +2784,9 @@ static void s3c_hsotg_init(struct s3c_hsotg *hsotg)
2730 2784
2731 writel(0, hsotg->regs + S3C_DAINTMSK); 2785 writel(0, hsotg->regs + S3C_DAINTMSK);
2732 2786
2787 /* Be in disconnected state until gadget is registered */
2788 __orr32(hsotg->regs + S3C_DCTL, S3C_DCTL_SftDiscon);
2789
2733 if (0) { 2790 if (0) {
2734 /* post global nak until we're ready */ 2791 /* post global nak until we're ready */
2735 writel(S3C_DCTL_SGNPInNAK | S3C_DCTL_SGOUTNak, 2792 writel(S3C_DCTL_SGNPInNAK | S3C_DCTL_SGOUTNak,