diff options
author | juhosg <juhosg@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-04-21 12:30:48 +0000 |
---|---|---|
committer | juhosg <juhosg@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-04-21 12:30:48 +0000 |
commit | e958af1110fe4ab7cd1916bbf0875a89ef439d5a (patch) | |
tree | ab37216928244125c1b1c2094281490ed96fdbed /target/linux/ramips/files/arch/mips/ralink/rt305x/devices.c | |
parent | 3ff5d8da9a9bbdf1727661d3c50311af524b4b5d (diff) |
ramips: rt305x: add OHCI/EHCI registration code for RT3352
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@31402 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/ramips/files/arch/mips/ralink/rt305x/devices.c')
-rw-r--r-- | target/linux/ramips/files/arch/mips/ralink/rt305x/devices.c | 132 |
1 files changed, 127 insertions, 5 deletions
diff --git a/target/linux/ramips/files/arch/mips/ralink/rt305x/devices.c b/target/linux/ramips/files/arch/mips/ralink/rt305x/devices.c index 60e5711797..bebab8171a 100644 --- a/target/linux/ramips/files/arch/mips/ralink/rt305x/devices.c +++ b/target/linux/ramips/files/arch/mips/ralink/rt305x/devices.c @@ -16,6 +16,8 @@ #include <linux/mtd/physmap.h> #include <linux/spi/spi.h> #include <linux/rt2x00_platform.h> +#include <linux/delay.h> +#include <linux/dma-mapping.h> #include <asm/addrspace.h> @@ -25,6 +27,8 @@ #include <ramips_eth_platform.h> #include <rt305x_esw_platform.h> +#include <rt3883_ehci_platform.h> +#include <rt3883_ohci_platform.h> static struct resource rt305x_flash0_resources[] = { { @@ -257,7 +261,7 @@ void __init rt305x_register_spi(struct spi_board_info *info, int n) platform_device_register(&rt305x_spi_device); } -static struct resource rt305x_usb_resources[] = { +static struct resource rt305x_dwc_otg_resources[] = { { .start = RT305X_OTG_BASE, .end = RT305X_OTG_BASE + 0x3FFFF, @@ -269,16 +273,134 @@ static struct resource rt305x_usb_resources[] = { }, }; -static struct platform_device rt305x_usb_device = { +static struct platform_device rt305x_dwc_otg_device = { .name = "dwc_otg", - .resource = rt305x_usb_resources, - .num_resources = ARRAY_SIZE(rt305x_usb_resources), + .resource = rt305x_dwc_otg_resources, + .num_resources = ARRAY_SIZE(rt305x_dwc_otg_resources), .dev = { .platform_data = NULL, } }; +static atomic_t rt3352_usb_use_count = ATOMIC_INIT(0); + +static void rt3352_usb_host_start(void) +{ + u32 t; + + if (atomic_inc_return(&rt3352_usb_use_count) != 1) + return; + + t = rt305x_sysc_rr(RT3352_SYSC_REG_USB_PS); + + /* enable clock for port0's and port1's phys */ + t = rt305x_sysc_rr(RT3352_SYSC_REG_CLKCFG1); + t = t | RT3352_CLKCFG1_UPHY0_CLK_EN | RT3352_CLKCFG1_UPHY1_CLK_EN; + rt305x_sysc_wr(t, RT3352_SYSC_REG_CLKCFG1); + mdelay(500); + + /* pull USBHOST and USBDEV out from reset */ + t = rt305x_sysc_rr(RT3352_SYSC_REG_RSTCTRL); + t &= ~(RT3352_RSTCTRL_UHST | RT3352_RSTCTRL_UDEV); + rt305x_sysc_wr(t, RT3352_SYSC_REG_RSTCTRL); + mdelay(500); + + /* enable host mode */ + t = rt305x_sysc_rr(RT3352_SYSC_REG_SYSCFG1); + t |= RT3352_SYSCFG1_USB0_HOST_MODE; + rt305x_sysc_wr(t, RT3352_SYSC_REG_SYSCFG1); + + t = rt305x_sysc_rr(RT3352_SYSC_REG_USB_PS); +} + +static void rt3352_usb_host_stop(void) +{ + u32 t; + + if (atomic_dec_return(&rt3352_usb_use_count) != 0) + return; + + /* put USBHOST and USBDEV into reset */ + t = rt305x_sysc_rr(RT3352_SYSC_REG_RSTCTRL); + t |= RT3352_RSTCTRL_UHST | RT3352_RSTCTRL_UDEV; + rt305x_sysc_wr(t, RT3352_SYSC_REG_RSTCTRL); + udelay(10000); + + /* disable clock for port0's and port1's phys*/ + t = rt305x_sysc_rr(RT3352_SYSC_REG_CLKCFG1); + t &= ~(RT3352_CLKCFG1_UPHY0_CLK_EN | RT3352_CLKCFG1_UPHY1_CLK_EN); + rt305x_sysc_wr(t, RT3352_SYSC_REG_CLKCFG1); + udelay(10000); +} + +static struct rt3883_ehci_platform_data rt3352_ehci_data = { + .start_hw = rt3352_usb_host_start, + .stop_hw = rt3352_usb_host_stop, +}; + +static struct resource rt3352_ehci_resources[] = { + { + .start = RT3352_EHCI_BASE, + .end = RT3352_EHCI_BASE + RT3352_EHCI_SIZE - 1, + .flags = IORESOURCE_MEM, + }, { + .start = RT305X_INTC_IRQ_OTG, + .end = RT305X_INTC_IRQ_OTG, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 rt3352_ehci_dmamask = DMA_BIT_MASK(32); +static struct platform_device rt3352_ehci_device = { + .name = "rt3352-ehci", + .id = -1, + .resource = rt3352_ehci_resources, + .num_resources = ARRAY_SIZE(rt3352_ehci_resources), + .dev = { + .dma_mask = &rt3352_ehci_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &rt3352_ehci_data, + }, +}; + +static struct resource rt3352_ohci_resources[] = { + { + .start = RT3352_OHCI_BASE, + .end = RT3352_OHCI_BASE + RT3352_OHCI_SIZE - 1, + .flags = IORESOURCE_MEM, + }, { + .start = RT305X_INTC_IRQ_OTG, + .end = RT305X_INTC_IRQ_OTG, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct rt3883_ohci_platform_data rt3352_ohci_data = { + .start_hw = rt3352_usb_host_start, + .stop_hw = rt3352_usb_host_stop, +}; + +static u64 rt3352_ohci_dmamask = DMA_BIT_MASK(32); +static struct platform_device rt3352_ohci_device = { + .name = "rt3352-ohci", + .id = -1, + .resource = rt3352_ohci_resources, + .num_resources = ARRAY_SIZE(rt3352_ohci_resources), + .dev = { + .dma_mask = &rt3352_ohci_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &rt3352_ohci_data, + }, +}; + void __init rt305x_register_usb(void) { - platform_device_register(&rt305x_usb_device); + if (soc_is_rt305x() || soc_is_rt3350()) { + platform_device_register(&rt305x_dwc_otg_device); + } else if (soc_is_rt3352()) { + platform_device_register(&rt3352_ehci_device); + platform_device_register(&rt3352_ohci_device); + } else { + BUG(); + } } |