X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fsvn-archive%2Farchive.git;a=blobdiff_plain;f=target%2Flinux%2Framips%2Ffiles%2Farch%2Fmips%2Fralink%2Frt305x%2Fdevices.c;fp=target%2Flinux%2Framips%2Ffiles%2Farch%2Fmips%2Fralink%2Frt305x%2Fdevices.c;h=bebab8171a00a4bb5e3c7db23afdb85865c4a7c1;hp=60e57117973c46ca66687012b1826f4904df2ca6;hb=223158f21232b5c78276fd599646d8f141c5e261;hpb=723e7ef700d39c39ac6c973e8fafa67b0fda84d3 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 #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(); + } }