diff options
Diffstat (limited to 'target/linux')
-rw-r--r-- | target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt305x_regs.h | 34 | ||||
-rw-r--r-- | target/linux/ramips/files/arch/mips/ralink/rt305x/devices.c | 132 |
2 files changed, 161 insertions, 5 deletions
diff --git a/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt305x_regs.h b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt305x_regs.h index e12158205..db037a583 100644 --- a/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt305x_regs.h +++ b/target/linux/ramips/files/arch/mips/include/asm/mach-ralink/rt305x_regs.h @@ -46,6 +46,11 @@ #define RT305X_FLASH1_SIZE (16 * 1024 * 1024) #define RT305X_FLASH0_SIZE (8 * 1024 * 1024) +#define RT3352_EHCI_BASE 0x101c0000 +#define RT3352_EHCI_SIZE 0x1000 +#define RT3352_OHCI_BASE 0x101c1000 +#define RT3352_OHCI_SIZE 0x1000 + /* SYSC registers */ #define SYSC_REG_CHIP_NAME0 0x000 /* Chip Name 0 */ #define SYSC_REG_CHIP_NAME1 0x004 /* Chip Name 1 */ @@ -57,6 +62,11 @@ #define SYSC_REG_IA_ADDRESS 0x310 /* Illegal Access Address */ #define SYSC_REG_IA_TYPE 0x314 /* Illegal Access Type */ +#define RT3352_SYSC_REG_SYSCFG1 0x014 +#define RT3352_SYSC_REG_CLKCFG1 0x030 +#define RT3352_SYSC_REG_RSTCTRL 0x034 +#define RT3352_SYSC_REG_USB_PS 0x05c + #define RT3052_CHIP_NAME0 0x30335452 #define RT3052_CHIP_NAME1 0x20203235 @@ -85,6 +95,11 @@ #define RT3352_SYSCFG0_CPUCLK_LOW 0x0 #define RT3352_SYSCFG0_CPUCLK_HIGH 0x1 +#define RT3352_SYSCFG1_USB0_HOST_MODE BIT(10) + +#define RT3352_CLKCFG1_UPHY0_CLK_EN BIT(18) +#define RT3352_CLKCFG1_UPHY1_CLK_EN BIT(20) + #define RT305X_GPIO_MODE_I2C BIT(0) #define RT305X_GPIO_MODE_SPI BIT(1) #define RT305X_GPIO_MODE_UART0_SHIFT 2 @@ -121,6 +136,25 @@ #define RT305X_RESET_OTG BIT(22) #define RT305X_RESET_ESW BIT(23) +#define RT3352_RSTCTRL_SYS BIT(0) +#define RT3352_RSTCTRL_TIMER BIT(8) +#define RT3352_RSTCTRL_INTC BIT(9) +#define RT3352_RSTCTRL_MEMC BIT(10) +#define RT3352_RSTCTRL_PCM BIT(11) +#define RT3352_RSTCTRL_UART0 BIT(12) +#define RT3352_RSTCTRL_PIO BIT(13) +#define RT3352_RSTCTRL_DMA BIT(14) +#define RT3352_RSTCTRL_I2C BIT(16) +#define RT3352_RSTCTRL_I2S BIT(17) +#define RT3352_RSTCTRL_SPI BIT(18) +#define RT3352_RSTCTRL_UART1 BIT(19) +#define RT3352_RSTCTRL_WNIC BIT(20) +#define RT3352_RSTCTRL_FE BIT(21) +#define RT3352_RSTCTRL_UHST BIT(22) +#define RT3352_RSTCTRL_ESW BIT(23) +#define RT3352_RSTCTRL_EPHY BIT(24) +#define RT3352_RSTCTRL_UDEV BIT(25) + #define RT305X_INTC_INT_SYSCTL BIT(0) #define RT305X_INTC_INT_TIMER0 BIT(1) #define RT305X_INTC_INT_TIMER1 BIT(2) 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 <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(); + } } |