Skip to content

Commit

Permalink
MIPS: lantiq: Initialize the USB core on boot
Browse files Browse the repository at this point in the history
There is a DWC2 USB core in these SoCs. To make USB work we need to first
reset and power the state machine. These are SoC specific registers and
not part of the actual USB core.

Signed-off-by: Antti Seppälä <a.seppala@gmail.com>
Signed-off-by: John Crispin <blogic@openwrt.org>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/11449/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
  • Loading branch information
John Crispin authored and Ralf Baechle committed Nov 11, 2015
1 parent 1601078 commit 26cfdbe
Showing 1 changed file with 74 additions and 0 deletions.
74 changes: 74 additions & 0 deletions arch/mips/lantiq/xway/reset.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,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;
Expand Down Expand Up @@ -272,6 +303,45 @@ static void ltq_machine_power_off(void)
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;
Expand All @@ -295,6 +365,10 @@ static int __init mips_reboot_setup(void)
if (!ltq_rcu_membase)
panic("Failed to remap core memory");

if (of_machine_is_compatible("lantiq,ar9") ||
of_machine_is_compatible("lantiq,vr9"))
ltq_usb_init();

_machine_restart = ltq_machine_restart;
_machine_halt = ltq_machine_halt;
pm_power_off = ltq_machine_power_off;
Expand Down

0 comments on commit 26cfdbe

Please sign in to comment.