diff options
Diffstat (limited to 'target/linux/ramips/files/arch')
| -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(); +	}  } | 
