2 +++ b/drivers/usb/host/ehci-fotg2xx.c
5 + * EHCI Host Controller driver
7 + * Copyright (C) 2006 Sony Computer Entertainment Inc.
8 + * Copyright 2006 Sony Corp.
10 + * This program is free software; you can redistribute it and/or modify
11 + * it under the terms of the GNU General Public License as published by
12 + * the Free Software Foundation; version 2 of the License.
15 +#include <linux/platform_device.h>
16 +#include <mach/hardware.h>
18 +#define otg_set(port, bits) writel(readl(hcd->regs + port) | bits, hcd->regs + port)
20 +#define otg_clear(port, bits) writel(readl(hcd->regs + port) & ~bits, hcd->regs + port)
22 +#define GLOBAL_ISR 0xC0
23 +#define GLOBAL_ICR 0xC4
25 +#define HCD_MISC 0x40
27 +#define OTGC_SCR 0x80
28 +#define OTGC_INT_EN 0x88
30 +#define GLOBAL_INT_POLARITY (1 << 3)
31 +#define GLOBAL_INT_MASK_HC (1 << 2)
32 +#define GLOBAL_INT_MASK_OTG (1 << 1)
33 +#define GLOBAL_INT_MASK_DEV (1 << 0)
35 +#define OTGC_SCR_ID (1 << 21)
36 +#define OTGC_SCR_CROLE (1 << 20)
37 +#define OTGC_SCR_VBUS_VLD (1 << 19)
38 +#define OTGC_SCR_A_SRP_RESP_TYPE (1 << 8)
39 +#define OTGC_SCR_A_SRP_DET_EN (1 << 7)
40 +#define OTGC_SCR_A_SET_B_HNP_EN (1 << 6)
41 +#define OTGC_SCR_A_BUS_DROP (1 << 5)
42 +#define OTGC_SCR_A_BUS_REQ (1 << 4)
44 +#define OTGC_INT_APLGRMV (1 << 12)
45 +#define OTGC_INT_BPLGRMV (1 << 11)
46 +#define OTGC_INT_OVC (1 << 10)
47 +#define OTGC_INT_IDCHG (1 << 9)
48 +#define OTGC_INT_RLCHG (1 << 8)
49 +#define OTGC_INT_AVBUSERR (1 << 5)
50 +#define OTGC_INT_ASRPDET (1 << 4)
51 +#define OTGC_INT_BSRPDN (1 << 0)
53 +#define OTGC_INT_A_TYPE (OTGC_INT_ASRPDET|OTGC_INT_AVBUSERR|OTGC_INT_OVC|OTGC_INT_RLCHG|OTGC_INT_IDCHG|OTGC_INT_APLGRMV)
54 +#define OTGC_INT_B_TYPE (OTGC_INT_AVBUSERR|OTGC_INT_OVC|OTGC_INT_RLCHG|OTGC_INT_IDCHG)
56 +static void fotg2xx_otgc_role_change(struct usb_hcd *hcd);
58 +static void fotg2xx_otgc_init(struct usb_hcd *hcd)
60 + struct ehci_hcd *ehci = hcd_to_ehci(hcd);
63 + reg = __raw_readl(hcd->regs + OTGC_SCR);
64 + ehci_info(ehci, "role detected: %s, ",
65 + (reg & OTGC_SCR_CROLE) ? "Peripheral" : "Host");
67 + if (reg & OTGC_SCR_ID)
68 + ehci_info(ehci, "B-Device (may be unsupported!)\n");
70 + ehci_info(ehci, "A-Device\n");
72 + /* Enable the SRP detect */
73 + reg &= ~OTGC_SCR_A_SRP_RESP_TYPE;
74 + __raw_writel(reg, hcd->regs + OTGC_SCR);
76 + reg = __raw_readl(hcd->regs + OTGC_INT_EN);
77 + /* clear INT B: bits AVBUSERR | OVC | RLCHG | IDCHG */
78 + reg &= ~OTGC_INT_B_TYPE;
79 + /* set INT A: bits ASRPDET | AVBUSERR | OVC | RLCHG | IDCHG | APLGRMV */
80 + reg |= OTGC_INT_A_TYPE;
81 + __raw_writel(reg, hcd->regs + OTGC_INT_EN);
83 + reg = __raw_readl(hcd->regs + GLOBAL_ICR);
84 + reg &= ~GLOBAL_INT_MASK_OTG;
85 + __raw_writel(reg, hcd->regs + GLOBAL_ICR);
87 + /* setup MISC register, fixes timing problems */
88 + reg = __raw_readl(hcd->regs + HCD_MISC);
90 + __raw_writel(reg, hcd->regs + HCD_MISC);
92 + fotg2xx_otgc_role_change(hcd);
95 +static void fotg2xx_otgh_close(struct usb_hcd *hcd)
99 + /* <1>.Enable Interrupt Mask */
100 + reg = __raw_readl(hcd->regs + GLOBAL_ICR);
101 + reg |= GLOBAL_INT_MASK_HC;
102 + __raw_writel(reg, hcd->regs + GLOBAL_ICR);
104 + /* <2>.Clear the Interrupt status */
105 + reg = __raw_readl(hcd->regs + 0x18);
107 + __raw_writel(reg, hcd->regs + 0x14);
110 +static void fotg2xx_otgh_open(struct usb_hcd *hcd)
114 + reg = __raw_readl(hcd->regs + OTGC_SCR);
115 + reg &= ~OTGC_SCR_A_SRP_DET_EN;
116 + __raw_writel(reg, hcd->regs + OTGC_SCR);
118 + reg = __raw_readl(hcd->regs + GLOBAL_ICR);
119 + reg &= ~GLOBAL_INT_MASK_HC;
120 + __raw_writel(reg, hcd->regs + GLOBAL_ICR);
123 +/* change to host role */
124 +static void fotg2xx_otgc_role_change(struct usb_hcd *hcd)
127 + /* clear A_SET_B_HNP_EN */
128 + otg_clear(0x80, BIT(6));
130 + /*** Enable VBUS driving */
131 + if (readl(hcd->regs + 0x80) & BIT(19))
132 + printk(KERN_INFO "VBUS already enabled\n");
136 + /* clear A_BUS_DROP */
137 + otg_clear(0x80, BIT(5));
139 + /* set A_BUS_REQ */
140 + otg_set(0x80, BIT(4));
142 + /* set global bus reg to VBUS on */
143 + writel(readl(IO_ADDRESS(0x40000000) + 0x30) | ((BIT(21)|BIT(22))),
144 + IO_ADDRESS(0x40000000) + 0x30);
146 + if (readl(hcd->regs + 0x80) & (1<<19)) {
147 + printk(KERN_INFO "Waiting for VBus");
148 + while (!(readl(hcd->regs + 0x80) & (1<<19)) && (cnt < 80)) {
149 + printk(KERN_CONT ".");
152 + printk(KERN_CONT "\n");
154 + printk(KERN_INFO "VBUS enabled.\n");
158 + fotg2xx_otgh_open(hcd);
161 +static int fotg2xx_ehci_hc_reset(struct usb_hcd *hcd)
164 + struct ehci_hcd *ehci = hcd_to_ehci(hcd);
166 + ehci->caps = hcd->regs;
167 + ehci->regs = hcd->regs + HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
169 + dbg_hcs_params(ehci, "reset");
170 + dbg_hcc_params(ehci, "reset");
172 + ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
175 + result = ehci_halt(ehci);
179 + return ehci_init(hcd);
183 + * Name: OTGC_INT_ISR
184 + * Description:This interrupt service routine belongs to the OTG-Controller
185 + * <1>.Check for ID_Change
186 + * <2>.Check for RL_Change
188 + * Input: wINTStatus
191 +void fotg2xx_int_isr(struct usb_hcd *hcd, u32 wINTStatus)
193 + /* <1>.Check for ID_Change */
194 + if (wINTStatus&OTGC_INT_IDCHG) {
195 + if ((readl(hcd->regs + 0x80) & BIT(21)) != 0)
196 + fotg2xx_otgc_init(hcd); /* Change to B Type */
198 + fotg2xx_otgc_init(hcd); /* Change to A Type */
203 + /* <2>.Check for RL_Change */
204 + if (wINTStatus&OTGC_INT_RLCHG)
205 + fotg2xx_otgc_role_change(hcd);
207 + /* <3>.Error Detect */
208 + if (wINTStatus&OTGC_INT_AVBUSERR)
209 + printk(KERN_ERR "VBus error!\n");
211 + if (wINTStatus&OTGC_INT_OVC)
212 + printk(KERN_WARNING "Overcurrent detected!\n");
214 + /* <3>.Check for Type-A/Type-B Interrupt */
215 + if ((readl(hcd->regs + 0x80) & BIT(21)) == 0) { /*For Type-A Interrupt*/
216 + if (wINTStatus & (OTGC_INT_A_TYPE | OTGC_INT_ASRPDET)) {
217 + /* <1>.SRP detected => then set global variable */
218 + printk(KERN_WARNING "SRP detected, but not implemented!\n");
222 + /* <2>.Turn on the V Bus */
223 + pFTC_OTG->otg.state = OTG_STATE_A_WAIT_VRISE;
224 + OTGC_enable_vbus_draw_storlink(1);
225 + pFTC_OTG->otg.state = OTG_STATE_A_HOST;
226 + /* <3>.Should waiting for Device-Connect Wait 300ms */
227 + INFO(pFTC_OTG, ">>> OTG-A Waiting for OTG-B Connect,\n");
229 + while (mwHost20_PORTSC_ConnectStatus_Rd() == 0) {
232 + /* Waiting for 300 ms */
233 + if (wTempCounter > 300) {
234 + mdwOTGC_Control_A_SRP_DET_EN_Clr();
235 + INFO(pFTC_OTG, ">>> OTG-B do not connect under 300 ms...\n");
239 + /* <4>.If Connect => issue quick Reset */
240 + if (mwHost20_PORTSC_ConnectStatus_Rd() > 0) {
241 + mdelay(300); /* For OPT-A Test */
242 + OTGH_host_quick_Reset();
244 + pFTC_OTG->otg.host->A_Disable_Set_Feature_HNP = 0;
248 + } else { /* For Type-B Interrupt */
253 +static irqreturn_t fotg2xx_ehci_irq(int irq, void *devid)
255 + struct usb_hcd *hcd = devid;
258 + /* OTG Interrupt Status Register */
259 + val = readl(hcd->regs + 0x84);
263 + /* supposed to do "INT STS Clr" - XXX */
264 + writel(readl(hcd->regs + 0x84) | val, hcd->regs + 0x84);
266 + fotg2xx_int_isr(hcd, val);
268 + /* supposed to do "INT STS Clr" - XXX */
269 + writel(readl(hcd->regs + 0x84) | val, hcd->regs + 0x84);
271 + return IRQ_HANDLED;
274 + if ((readl(hcd->regs + 0x80) & BIT(20)) == 0) { /* Role is HOST */
275 + if (readl(hcd->regs + 0xC0) & BIT(2)) { /* INT STS HOST */
276 + /* leave this for ehci irq handler */
280 + printk(KERN_WARNING
281 + "received irq for peripheral - don't know what to do!\n");
283 + /* do not call the ehci irq handler */
284 + return IRQ_HANDLED;
287 +static int fotg2xx_ehci_run(struct usb_hcd *hcd)
291 + retval = ehci_run(hcd);
293 + fotg2xx_otgh_close(hcd);
294 + fotg2xx_otgc_init(hcd);
299 +static const struct hc_driver fotg2xx_ehci_hc_driver = {
300 + .description = hcd_name,
301 + .product_desc = "FOTG2XX EHCI Host Controller",
302 + .hcd_priv_size = sizeof(struct ehci_hcd),
304 + .flags = HCD_MEMORY | HCD_USB2,
305 + .reset = fotg2xx_ehci_hc_reset,
306 + .start = fotg2xx_ehci_run,
308 + .shutdown = ehci_shutdown,
310 + .urb_enqueue = ehci_urb_enqueue,
311 + .urb_dequeue = ehci_urb_dequeue,
312 + .endpoint_disable = ehci_endpoint_disable,
313 + .endpoint_reset = ehci_endpoint_reset,
315 + .get_frame_number = ehci_get_frame,
317 + .hub_status_data = ehci_hub_status_data,
318 + .hub_control = ehci_hub_control,
319 +#if defined(CONFIG_PM)
320 + .bus_suspend = ehci_bus_suspend,
321 + .bus_resume = ehci_bus_resume,
323 + .relinquish_port = ehci_relinquish_port,
324 + .port_handed_over = ehci_port_handed_over,
326 + .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
329 +static int fotg2xx_ehci_probe(struct platform_device *pdev)
331 + const struct hc_driver *driver = &fotg2xx_ehci_hc_driver;
332 + struct usb_hcd *hcd;
333 + struct resource *res;
337 + pr_debug("initializing FOTG2XX-SOC USB Controller\n");
339 + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
341 + dev_err(&pdev->dev,
342 + "Found HC with no IRQ. Check %s setup!\n",
343 + dev_name(&pdev->dev));
349 + hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
355 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
357 + dev_err(&pdev->dev,
358 + "Found HC with no register addr. Check %s setup!\n",
359 + dev_name(&pdev->dev));
364 + hcd->rsrc_start = res->start;
365 + hcd->rsrc_len = res->end - res->start + 1;
366 + if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
367 + driver->description)) {
368 + dev_dbg(&pdev->dev, "controller already in use\n");
373 + hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
374 + if (hcd->regs == NULL) {
375 + dev_dbg(&pdev->dev, "error mapping memory\n");
381 + /* set global reg to mini-A host */
382 + writel(readl(IO_ADDRESS(0x40000000) + 0x30) & ~(BIT(30)|BIT(29)),
383 + IO_ADDRESS(0x40000000) + 0x30);
385 + /* USB0&USB1 - VBUS off */
386 + writel(readl(IO_ADDRESS(0x40000000) + 0x30) & ~(BIT(21)|BIT(22)),
387 + IO_ADDRESS(0x40000000) + 0x30);
389 + if ((readl(hcd->regs) == 0x01000010) &&
390 + (readl(hcd->regs + 4) == 0x00000001) &&
391 + (readl(hcd->regs + 8) == 0x00000006)) {
392 + dev_info(&pdev->dev,
393 + "Found Faraday OTG 2XX controller (base = 0x%08lX)\n",
394 + (unsigned long) hcd->rsrc_start);
396 + dev_err(&pdev->dev, "fotg2xx id mismatch: found %d.%d.%d\n",
397 + readl(hcd->regs + 0x00),
398 + readl(hcd->regs + 0x04),
399 + readl(hcd->regs + 0x08));
404 + platform_set_drvdata(pdev, hcd);
406 + /* mask interrupts - peripheral, otg, host, hi-active (bits 0,1,2,3) */
407 + otg_set(0xc4, BIT(3)); /* hi active */
409 + otg_set(0xc4, BIT(2)); /* host */
410 + otg_set(0xc4, BIT(1)); /* otg */
411 + otg_set(0xc4, BIT(0)); /* peripheral */
413 + /* register additional interrupt - here we check otg status */
414 + if ((request_irq(irq, &fotg2xx_ehci_irq, IRQF_SHARED | IRQF_DISABLED,
415 + hcd->irq_descr, hcd)) != 0) {
416 + dev_dbg(&pdev->dev, "error requesting irq %d\n", irq);
421 + retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
427 + iounmap(hcd->regs);
429 + release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
433 + dev_err(&pdev->dev, "init %s fail, %d\n", dev_name(&pdev->dev), retval);
437 +/* may be called without controller electrically present */
438 +/* may be called with controller, bus, and devices active */
440 +int fotg2xx_ehci_remove(struct platform_device *pdev)
442 + struct usb_hcd *hcd =
443 + (struct usb_hcd *)platform_get_drvdata(pdev);
445 + usb_remove_hcd(hcd);
446 + release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
447 + iounmap(hcd->regs);
449 + platform_set_drvdata(pdev, NULL);
454 +MODULE_ALIAS("platform:ehci-fotg2xx");
456 +static struct platform_driver fotg2xx_ehci_driver = {
457 + .probe = fotg2xx_ehci_probe,
458 + .remove = fotg2xx_ehci_remove,
460 + .name = "ehci-fotg2xx",
463 --- a/drivers/usb/host/ehci.h
464 +++ b/drivers/usb/host/ehci.h
465 @@ -600,7 +600,12 @@ static inline unsigned int
466 ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc)
468 if (ehci_is_TDI(ehci)) {
469 +#ifdef CONFIG_ARCH_GEMINI
470 + portsc = readl(ehci_to_hcd(ehci)->regs + 0x80);
471 + switch ((portsc>>22)&3) {
473 switch ((portsc >> (ehci->has_hostpc ? 25 : 26)) & 3) {
478 --- a/drivers/usb/host/ehci-hcd.c
479 +++ b/drivers/usb/host/ehci-hcd.c
480 @@ -204,10 +204,12 @@ static int ehci_halt (struct ehci_hcd *e
481 * This routine gets called during probe before ehci->command
482 * has been initialized, so we can't rely on its value.
484 +#ifndef CONFIG_ARCH_GEMINI
485 ehci->command &= ~CMD_RUN;
486 temp = ehci_readl(ehci, &ehci->regs->command);
487 temp &= ~(CMD_RUN | CMD_IAAD);
488 ehci_writel(ehci, temp, &ehci->regs->command);
491 spin_unlock_irq(&ehci->lock);
492 synchronize_irq(ehci_to_hcd(ehci)->irq);
493 @@ -257,13 +259,17 @@ static int ehci_reset (struct ehci_hcd *
494 if (ehci->has_hostpc) {
495 ehci_writel(ehci, USBMODE_EX_HC | USBMODE_EX_VBPS,
496 &ehci->regs->usbmode_ex);
497 +#ifndef CONFIG_ARCH_GEMINI
498 ehci_writel(ehci, TXFIFO_DEFAULT, &ehci->regs->txfill_tuning);
504 +#ifndef CONFIG_ARCH_GEMINI
505 if (ehci_is_TDI(ehci))
510 dbgp_external_startup(ehci_to_hcd(ehci));
511 @@ -341,11 +347,14 @@ static void ehci_silence_controller(stru
512 ehci->rh_state = EHCI_RH_HALTED;
513 ehci_turn_off_all_ports(ehci);
515 +#ifndef CONFIG_ARCH_GEMINI
516 /* make BIOS/etc use companion controller during reboot */
517 ehci_writel(ehci, 0, &ehci->regs->configured_flag);
519 /* unblock posted writes */
520 ehci_readl(ehci, &ehci->regs->configured_flag);
523 spin_unlock_irq(&ehci->lock);
526 @@ -600,7 +609,9 @@ static int ehci_run (struct usb_hcd *hcd
527 // Philips, Intel, and maybe others need CMD_RUN before the
528 // root hub will detect new devices (why?); NEC doesn't
529 ehci->command &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET);
530 +#ifndef CONFIG_ARCH_GEMINI
531 ehci->command |= CMD_RUN;
533 ehci_writel(ehci, ehci->command, &ehci->regs->command);
534 dbg_cmd (ehci, "init", ehci->command);
536 @@ -620,9 +631,11 @@ static int ehci_run (struct usb_hcd *hcd
538 down_write(&ehci_cf_port_reset_rwsem);
539 ehci->rh_state = EHCI_RH_RUNNING;
540 +#ifndef CONFIG_ARCH_GEMINI
541 ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
542 ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
544 +#endif /* !CONFIG_ARCH_GEMINI */
545 up_write(&ehci_cf_port_reset_rwsem);
546 ehci->last_periodic_enable = ktime_get_real();
548 @@ -1238,6 +1251,11 @@ MODULE_DESCRIPTION(DRIVER_DESC);
549 MODULE_AUTHOR (DRIVER_AUTHOR);
550 MODULE_LICENSE ("GPL");
552 +#ifdef CONFIG_ARCH_GEMINI
553 +#include "ehci-fotg2xx.c"
554 +#define PLATFORM_DRIVER fotg2xx_ehci_driver
557 #ifdef CONFIG_USB_EHCI_FSL
558 #include "ehci-fsl.c"
559 #define PLATFORM_DRIVER ehci_fsl_driver
560 --- a/drivers/usb/host/ehci-hub.c
561 +++ b/drivers/usb/host/ehci-hub.c
562 @@ -912,6 +912,12 @@ static int ehci_hub_control (
563 /* see what we found out */
564 temp = check_reset_complete (ehci, wIndex, status_reg,
565 ehci_readl(ehci, status_reg));
566 +#ifdef CONFIG_ARCH_GEMINI
567 + /* restart schedule */
568 + ehci_writel(ehci, ehci_readl(ehci, &ehci->regs->command) | CMD_RUN, &ehci->regs->command);
570 +// hcd->state = HC_STATE_RUNNING;
574 if (!(temp & (PORT_RESUME|PORT_RESET))) {
575 --- a/drivers/usb/Kconfig
576 +++ b/drivers/usb/Kconfig
577 @@ -47,6 +47,7 @@ config USB_ARCH_HAS_EHCI
578 default y if MICROBLAZE
579 default y if SPARC_LEON
580 default y if ARCH_MMP
581 + default y if ARCH_GEMINI
582 default y if MACH_LOONGSON1
583 default y if PLAT_ORION
585 @@ -96,7 +97,7 @@ config USB
586 traditional PC serial port. The bus supplies power to peripherals
587 and allows for hot swapping. Up to 127 USB peripherals can be
588 connected to a single USB host in a tree structure.
591 The USB host is the root of the tree, the peripherals are the
592 leaves and the inner nodes are special USB devices called hubs.
593 Most PCs now have USB host ports, used to connect peripherals
594 --- a/include/linux/usb/ehci_def.h
595 +++ b/include/linux/usb/ehci_def.h
596 @@ -111,6 +111,7 @@ struct ehci_regs {
597 /* ASYNCLISTADDR: offset 0x18 */
598 u32 async_next; /* address of next async queue head */
600 +#ifndef CONFIG_ARCH_GEMINI
603 /* TXFILLTUNING: offset 0x24 */
604 @@ -118,6 +119,7 @@ struct ehci_regs {
605 #define TXFIFO_DEFAULT (8<<16) /* FIFO burst threshold 8 */
608 +#endif /* !CONFIG_ARCH_GEMINI */
610 /* CONFIGFLAG: offset 0x40 */