aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/brcm63xx/patches-4.9/348-MIPS-BCM63XX-fix-BCM63268-USB-clock.patch
blob: 0b8a5a170603f456313eb6654992d4de7df98faf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -586,6 +586,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
@@ -1533,6 +1536,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
@@ -63,6 +63,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
  */
@@ -235,7 +255,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;
 	}