diff options
Diffstat (limited to 'target/linux/gemini/patches-4.1/130-usb-ehci-fot2g.patch')
-rw-r--r-- | target/linux/gemini/patches-4.1/130-usb-ehci-fot2g.patch | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/target/linux/gemini/patches-4.1/130-usb-ehci-fot2g.patch b/target/linux/gemini/patches-4.1/130-usb-ehci-fot2g.patch new file mode 100644 index 0000000000..5f6eecca93 --- /dev/null +++ b/target/linux/gemini/patches-4.1/130-usb-ehci-fot2g.patch @@ -0,0 +1,210 @@ +--- a/arch/arm/mach-gemini/devices.c ++++ b/arch/arm/mach-gemini/devices.c +@@ -188,3 +188,64 @@ int platform_register_ethernet(struct ge + + return platform_device_register(ðernet_device); + } ++ ++static struct resource usb0_resources[] = { ++ { ++ .start = GEMINI_USB0_BASE, ++ .end = GEMINI_USB0_BASE + 0xfff, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = IRQ_USB0, ++ .end = IRQ_USB0, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct resource usb1_resources[] = { ++ { ++ .start = GEMINI_USB1_BASE, ++ .end = GEMINI_USB1_BASE + 0xfff, ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = IRQ_USB1, ++ .end = IRQ_USB1, ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static u64 usb0_dmamask = 0xffffffffUL; ++static u64 usb1_dmamask = 0xffffffffUL; ++ ++static struct platform_device usb_device[] = { ++ { ++ .name = "ehci-fotg2", ++ .id = 0, ++ .dev = { ++ .dma_mask = &usb0_dmamask, ++ .coherent_dma_mask = 0xffffffff, ++ }, ++ .num_resources = ARRAY_SIZE(usb0_resources), ++ .resource = usb0_resources, ++ }, ++ { ++ .name = "ehci-fotg2", ++ .id = 1, ++ .dev = { ++ .dma_mask = &usb1_dmamask, ++ .coherent_dma_mask = 0xffffffff, ++ }, ++ .num_resources = ARRAY_SIZE(usb1_resources), ++ .resource = usb1_resources, ++ }, ++}; ++ ++int __init platform_register_usb(unsigned int id) ++{ ++ if (id > 1) ++ return -EINVAL; ++ ++ return platform_device_register(&usb_device[id]); ++} ++ +--- a/arch/arm/mach-gemini/common.h ++++ b/arch/arm/mach-gemini/common.h +@@ -30,6 +30,7 @@ extern int platform_register_pflash(unsi + unsigned int nr_parts); + extern int platform_register_watchdog(void); + extern int platform_register_ethernet(struct gemini_gmac_platform_data *pdata); ++extern int platform_register_usb(unsigned int id); + + extern void gemini_restart(enum reboot_mode mode, const char *cmd); + +--- a/drivers/usb/host/ehci-hcd.c ++++ b/drivers/usb/host/ehci-hcd.c +@@ -351,11 +351,13 @@ static void ehci_silence_controller(stru + ehci->rh_state = EHCI_RH_HALTED; + ehci_turn_off_all_ports(ehci); + ++#ifndef CONFIG_ARCH_GEMINI + /* make BIOS/etc use companion controller during reboot */ + ehci_writel(ehci, 0, &ehci->regs->configured_flag); + + /* unblock posted writes */ + ehci_readl(ehci, &ehci->regs->configured_flag); ++#endif + spin_unlock_irq(&ehci->lock); + } + +@@ -607,7 +609,9 @@ static int ehci_run (struct usb_hcd *hcd + // Philips, Intel, and maybe others need CMD_RUN before the + // root hub will detect new devices (why?); NEC doesn't + ehci->command &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET); ++#ifndef CONFIG_ARCH_GEMINI + ehci->command |= CMD_RUN; ++#endif + ehci_writel(ehci, ehci->command, &ehci->regs->command); + dbg_cmd (ehci, "init", ehci->command); + +@@ -627,9 +631,11 @@ static int ehci_run (struct usb_hcd *hcd + */ + down_write(&ehci_cf_port_reset_rwsem); + ehci->rh_state = EHCI_RH_RUNNING; ++#ifndef CONFIG_ARCH_GEMINI + ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); + ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ + msleep(5); ++#endif + up_write(&ehci_cf_port_reset_rwsem); + ehci->last_periodic_enable = ktime_get_real(); + +@@ -767,9 +773,10 @@ static irqreturn_t ehci_irq (struct usb_ + pcd_status = status; + + /* resume root hub? */ ++#ifndef CONFIG_ARCH_GEMINI + if (ehci->rh_state == EHCI_RH_SUSPENDED) + usb_hcd_resume_root_hub(hcd); +- ++#endif + /* get per-port change detect bits */ + if (ehci->has_ppcd) + ppcd = status >> 16; +@@ -1250,6 +1257,11 @@ MODULE_DESCRIPTION(DRIVER_DESC); + MODULE_AUTHOR (DRIVER_AUTHOR); + MODULE_LICENSE ("GPL"); + ++#ifdef CONFIG_ARCH_GEMINI ++#include "ehci-fotg2.c" ++#define PLATFORM_DRIVER ehci_fotg2_driver ++#endif ++ + #ifdef CONFIG_USB_EHCI_FSL + #include "ehci-fsl.c" + #define PLATFORM_DRIVER ehci_fsl_driver +--- a/drivers/usb/host/ehci-timer.c ++++ b/drivers/usb/host/ehci-timer.c +@@ -208,7 +208,9 @@ static void ehci_handle_controller_death + + /* Clean up the mess */ + ehci->rh_state = EHCI_RH_HALTED; ++#ifndef CONFIG_ARCH_GEMINI + ehci_writel(ehci, 0, &ehci->regs->configured_flag); ++#endif + ehci_writel(ehci, 0, &ehci->regs->intr_enable); + ehci_work(ehci); + end_unlink_async(ehci); +--- a/drivers/usb/host/ehci.h ++++ b/drivers/usb/host/ehci.h +@@ -656,7 +656,12 @@ static inline unsigned int + ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc) + { + if (ehci_is_TDI(ehci)) { +- switch ((portsc >> (ehci->has_hostpc ? 25 : 26)) & 3) { ++#ifdef CONFIG_ARCH_GEMINI ++ portsc = readl(ehci_to_hcd(ehci)->regs + 0x80); ++ switch ((portsc>>22)&3) { ++#else ++ switch ((portsc>>26)&3) { ++#endif + case 0: + return 0; + case 1: +--- a/drivers/usb/host/ehci-hub.c ++++ b/drivers/usb/host/ehci-hub.c +@@ -1075,6 +1075,11 @@ int ehci_hub_control( + /* see what we found out */ + temp = check_reset_complete (ehci, wIndex, status_reg, + ehci_readl(ehci, status_reg)); ++#ifdef CONFIG_ARCH_GEMINI ++ /* restart schedule */ ++ ehci->command |= CMD_RUN; ++ ehci_writel(ehci, ehci->command, &ehci->regs->command); ++#endif + } + + /* transfer dedicated ports to the companion hc */ +--- a/include/linux/usb/ehci_def.h ++++ b/include/linux/usb/ehci_def.h +@@ -112,8 +112,13 @@ struct ehci_regs { + u32 frame_list; /* points to periodic list */ + /* ASYNCLISTADDR: offset 0x18 */ + u32 async_next; /* address of next async queue head */ +- ++#ifndef CONFIG_ARCH_GEMINI + u32 reserved1[2]; ++#else ++ u32 reserved1; ++ /* PORTSC: offset 0x20 for Faraday OTG */ ++ u32 port_status[1]; ++#endif + + /* TXFILLTUNING: offset 0x24 */ + u32 txfill_tuning; /* TX FIFO Tuning register */ +@@ -125,8 +130,11 @@ struct ehci_regs { + u32 configured_flag; + #define FLAG_CF (1<<0) /* true: we'll support "high speed" */ + ++#ifndef CONFIG_ARCH_GEMINI + /* PORTSC: offset 0x44 */ + u32 port_status[0]; /* up to N_PORTS */ ++#endif ++ + /* EHCI 1.1 addendum */ + #define PORTSC_SUSPEND_STS_ACK 0 + #define PORTSC_SUSPEND_STS_NYET 1 |