diff --git a/target/linux/lantiq/patches-3.18/0039-MIPS-lantiq-initialize-usb-on-boot.patch b/target/linux/lantiq/patches-3.18/0039-MIPS-lantiq-initialize-usb-on-boot.patch new file mode 100644 index 0000000000..938ae65313 --- /dev/null +++ b/target/linux/lantiq/patches-3.18/0039-MIPS-lantiq-initialize-usb-on-boot.patch @@ -0,0 +1,95 @@ +--- a/arch/mips/lantiq/xway/reset.c 2015-02-09 18:23:01.837007936 +0200 ++++ b/arch/mips/lantiq/xway/reset.c 2015-02-09 19:16:43.006081435 +0200 +@@ -44,6 +44,37 @@ + #define RCU_BOOT_SEL(x) ((x >> 18) & 0x7) + #define RCU_BOOT_SEL_XRX200(x) (((x >> 17) & 0xf) | ((x >> 8) & 0x10)) + ++/* dwc2 USB configuration registers */ ++#define RCU_USB1CFG 0x0018 ++#define RCU_USB2CFG 0x0034 ++ ++/* USB DMA endianness bits */ ++#define RCU_USBCFG_HDSEL_BIT BIT(11) ++#define RCU_USBCFG_HOST_END_BIT BIT(10) ++#define RCU_USBCFG_SLV_END_BIT BIT(9) ++ ++/* USB reset bits */ ++#define RCU_USBRESET 0x0010 ++ ++#define USBRESET_BIT BIT(4) ++ ++#define RCU_USBRESET2 0x0048 ++ ++#define USB1RESET_BIT BIT(4) ++#define USB2RESET_BIT BIT(5) ++ ++#define RCU_CFG1A 0x0038 ++#define RCU_CFG1B 0x003C ++ ++/* USB PMU devices */ ++#define PMU_AHBM BIT(15) ++#define PMU_USB0 BIT(6) ++#define PMU_USB1 BIT(27) ++ ++/* USB PHY PMU devices */ ++#define PMU_USB0_P BIT(0) ++#define PMU_USB1_P BIT(26) ++ + /* remapped base addr of the reset control unit */ + static void __iomem *ltq_rcu_membase; + static struct device_node *ltq_rcu_np; +@@ -200,6 +231,45 @@ + unreachable(); + } + ++static void ltq_usb_init(void) ++{ ++ /* Power for USB cores 1 & 2 */ ++ ltq_pmu_enable(PMU_AHBM); ++ ltq_pmu_enable(PMU_USB0); ++ ltq_pmu_enable(PMU_USB1); ++ ++ ltq_rcu_w32(ltq_rcu_r32(RCU_CFG1A) | BIT(0), RCU_CFG1A); ++ ltq_rcu_w32(ltq_rcu_r32(RCU_CFG1B) | BIT(0), RCU_CFG1B); ++ ++ /* Enable USB PHY power for cores 1 & 2 */ ++ ltq_pmu_enable(PMU_USB0_P); ++ ltq_pmu_enable(PMU_USB1_P); ++ ++ /* Configure cores to host mode */ ++ ltq_rcu_w32(ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_HDSEL_BIT, ++ RCU_USB1CFG); ++ ltq_rcu_w32(ltq_rcu_r32(RCU_USB2CFG) & ~RCU_USBCFG_HDSEL_BIT, ++ RCU_USB2CFG); ++ ++ /* Select DMA endianness (Host-endian: big-endian) */ ++ ltq_rcu_w32((ltq_rcu_r32(RCU_USB1CFG) & ~RCU_USBCFG_SLV_END_BIT) ++ | RCU_USBCFG_HOST_END_BIT, RCU_USB1CFG); ++ ltq_rcu_w32(ltq_rcu_r32((RCU_USB2CFG) & ~RCU_USBCFG_SLV_END_BIT) ++ | RCU_USBCFG_HOST_END_BIT, RCU_USB2CFG); ++ ++ /* Hard reset USB state machines */ ++ ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET) | USBRESET_BIT, RCU_USBRESET); ++ udelay(50 * 1000); ++ ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET) & ~USBRESET_BIT, RCU_USBRESET); ++ ++ /* Soft reset USB state machines */ ++ ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET2) ++ | USB1RESET_BIT | USB2RESET_BIT, RCU_USBRESET2); ++ udelay(50 * 1000); ++ ltq_rcu_w32(ltq_rcu_r32(RCU_USBRESET2) ++ & ~(USB1RESET_BIT | USB2RESET_BIT), RCU_USBRESET2); ++} ++ + static int __init mips_reboot_setup(void) + { + struct resource res; +@@ -223,6 +293,8 @@ + if (!ltq_rcu_membase) + panic("Failed to remap core memory"); + ++ ltq_usb_init(); ++ + _machine_restart = ltq_machine_restart; + _machine_halt = ltq_machine_halt; + pm_power_off = ltq_machine_power_off;