From e958af1110fe4ab7cd1916bbf0875a89ef439d5a Mon Sep 17 00:00:00 2001 From: juhosg Date: Sat, 21 Apr 2012 12:30:48 +0000 Subject: ramips: rt305x: add OHCI/EHCI registration code for RT3352 git-svn-id: svn://svn.openwrt.org/openwrt/trunk@31402 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../ramips/files/arch/mips/ralink/rt305x/devices.c | 132 ++++++++++++++++++++- 1 file changed, 127 insertions(+), 5 deletions(-) (limited to 'target/linux/ramips/files/arch/mips/ralink/rt305x/devices.c') 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 60e571179..bebab8171 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 #include #include +#include +#include #include @@ -25,6 +27,8 @@ #include #include +#include +#include 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(); + } } -- cgit v1.2.3