--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h @@ -587,6 +587,9 @@ #define TIMER_CTL_MONOTONIC_MASK (1 << 30) #define TIMER_CTL_ENABLE_MASK (1 << 31) +/* Clock reset control (63268 only) */ +#define TIMER_CLK_RST_CTL_REG 0x2c +#define CLK_RST_CTL_USB_REF_CLK_EN (1 << 18) /************************************************************************* * _REG relative to RSET_WDT @@ -1534,6 +1537,11 @@ #define STRAPBUS_63268_FCVO_SHIFT 21 #define STRAPBUS_63268_FCVO_MASK (0xf << STRAPBUS_63268_FCVO_SHIFT) +#define MISC_IDDQ_CTRL_6328_REG 0x48 +#define MISC_IDDQ_CTRL_63268_REG 0x4c + +#define IDDQ_CTRL_63268_USBH (1 << 4) + #define MISC_STRAPBUS_6328_REG 0x240 #define STRAPBUS_6328_FCVO_SHIFT 7 #define STRAPBUS_6328_FCVO_MASK (0x1f << STRAPBUS_6328_FCVO_SHIFT) --- a/arch/mips/bcm63xx/clk.c +++ b/arch/mips/bcm63xx/clk.c @@ -64,6 +64,26 @@ static void bcm_ub_hwclock_set(u32 mask, bcm_perf_writel(reg, PERF_UB_CKCTL_REG); } +static void bcm_misc_iddq_set(u32 mask, int enable) +{ + u32 offset; + u32 reg; + + if (BCMCPU_IS_6328() || BCMCPU_IS_6362()) + offset = MISC_IDDQ_CTRL_6328_REG; + else if (BCMCPU_IS_63268()) + offset = MISC_IDDQ_CTRL_63268_REG; + else + return; + + reg = bcm_misc_readl(offset); + if (enable) + reg &= ~mask; + else + reg |= mask; + bcm_misc_writel(reg, offset); +} + /* * Ethernet MAC "misc" clock: dma clocks and main clock on 6348 */ @@ -236,7 +256,17 @@ static void usbh_set(struct clk *clk, in } else if (BCMCPU_IS_6368()) { bcm_hwclock_set(CKCTL_6368_USBH_EN, enable); } else if (BCMCPU_IS_63268()) { + u32 reg; + bcm_hwclock_set(CKCTL_63268_USBH_EN, enable); + bcm_misc_iddq_set(IDDQ_CTRL_63268_USBH, enable); + bcm63xx_core_set_reset(BCM63XX_RESET_USBH, !enable); + reg = bcm_timer_readl(TIMER_CLK_RST_CTL_REG); + if (enable) + reg |= CLK_RST_CTL_USB_REF_CLK_EN; + else + reg &= ~CLK_RST_CTL_USB_REF_CLK_EN; + bcm_timer_writel(reg, TIMER_CLK_RST_CTL_REG); } else { return; }