diff options
Diffstat (limited to 'drivers/clk/ingenic')
-rw-r--r-- | drivers/clk/ingenic/cgu.c | 8 | ||||
-rw-r--r-- | drivers/clk/ingenic/cgu.h | 4 | ||||
-rw-r--r-- | drivers/clk/ingenic/jz4770-cgu.c | 49 |
3 files changed, 19 insertions, 42 deletions
diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c index 56a712c9075f..5ef7d9ba2195 100644 --- a/drivers/clk/ingenic/cgu.c +++ b/drivers/clk/ingenic/cgu.c @@ -43,7 +43,8 @@ static inline bool ingenic_cgu_gate_get(struct ingenic_cgu *cgu, const struct ingenic_cgu_gate_info *info) { - return readl(cgu->base + info->reg) & BIT(info->bit); + return !!(readl(cgu->base + info->reg) & BIT(info->bit)) + ^ info->clear_to_gate; } /** @@ -62,7 +63,7 @@ ingenic_cgu_gate_set(struct ingenic_cgu *cgu, { u32 clkgr = readl(cgu->base + info->reg); - if (val) + if (val ^ info->clear_to_gate) clkgr |= BIT(info->bit); else clkgr &= ~BIT(info->bit); @@ -511,6 +512,9 @@ static int ingenic_clk_enable(struct clk_hw *hw) spin_lock_irqsave(&cgu->lock, flags); ingenic_cgu_gate_set(cgu, &clk_info->gate, false); spin_unlock_irqrestore(&cgu->lock, flags); + + if (clk_info->gate.delay_us) + udelay(clk_info->gate.delay_us); } return 0; diff --git a/drivers/clk/ingenic/cgu.h b/drivers/clk/ingenic/cgu.h index 9da34910bd80..542192376ebf 100644 --- a/drivers/clk/ingenic/cgu.h +++ b/drivers/clk/ingenic/cgu.h @@ -111,10 +111,14 @@ struct ingenic_cgu_fixdiv_info { * struct ingenic_cgu_gate_info - information about a clock gate * @reg: offset of the gate control register within the CGU * @bit: offset of the bit in the register that controls the gate + * @clear_to_gate: if set, the clock is gated when the bit is cleared + * @delay_us: delay in microseconds after which the clock is considered stable */ struct ingenic_cgu_gate_info { unsigned reg; u8 bit; + bool clear_to_gate; + u16 delay_us; }; /** diff --git a/drivers/clk/ingenic/jz4770-cgu.c b/drivers/clk/ingenic/jz4770-cgu.c index c78d369b9403..bf46a0df2004 100644 --- a/drivers/clk/ingenic/jz4770-cgu.c +++ b/drivers/clk/ingenic/jz4770-cgu.c @@ -42,7 +42,6 @@ /* bits within the OPCR register */ #define OPCR_SPENDH BIT(5) /* UHC PHY suspend */ -#define OPCR_SPENDN BIT(7) /* OTG PHY suspend */ /* bits within the USBPCR1 register */ #define USBPCR1_UHC_POWER BIT(5) /* UHC PHY power down */ @@ -83,37 +82,6 @@ static const struct clk_ops jz4770_uhc_phy_ops = { .is_enabled = jz4770_uhc_phy_is_enabled, }; -static int jz4770_otg_phy_enable(struct clk_hw *hw) -{ - void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; - - writel(readl(reg_opcr) | OPCR_SPENDN, reg_opcr); - - /* Wait for the clock to be stable */ - udelay(50); - return 0; -} - -static void jz4770_otg_phy_disable(struct clk_hw *hw) -{ - void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; - - writel(readl(reg_opcr) & ~OPCR_SPENDN, reg_opcr); -} - -static int jz4770_otg_phy_is_enabled(struct clk_hw *hw) -{ - void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; - - return !!(readl(reg_opcr) & OPCR_SPENDN); -} - -static const struct clk_ops jz4770_otg_phy_ops = { - .enable = jz4770_otg_phy_enable, - .disable = jz4770_otg_phy_disable, - .is_enabled = jz4770_otg_phy_is_enabled, -}; - static const s8 pll_od_encoding[8] = { 0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3, }; @@ -186,7 +154,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = { "h1clk", CGU_CLK_DIV | CGU_CLK_GATE, .parents = { JZ4770_CLK_PLL0, }, .div = { CGU_REG_CPCCR, 24, 1, 4, 22, -1, -1 }, - .gate = { CGU_REG_LCR, 30 }, + .gate = { CGU_REG_CLKGR1, 7 }, }, [JZ4770_CLK_H2CLK] = { "h2clk", CGU_CLK_DIV, @@ -194,9 +162,10 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = { .div = { CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1 }, }, [JZ4770_CLK_C1CLK] = { - "c1clk", CGU_CLK_DIV, + "c1clk", CGU_CLK_DIV | CGU_CLK_GATE, .parents = { JZ4770_CLK_PLL0, }, .div = { CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1 }, + .gate = { CGU_REG_OPCR, 31, true }, // disable CCLK stop on idle }, [JZ4770_CLK_PCLK] = { "pclk", CGU_CLK_DIV, @@ -393,7 +362,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = { [JZ4770_CLK_VPU] = { "vpu", CGU_CLK_GATE, .parents = { JZ4770_CLK_H1CLK, }, - .gate = { CGU_REG_CLKGR1, 7 }, + .gate = { CGU_REG_LCR, 30, false, 150 }, }, [JZ4770_CLK_MMC0] = { "mmc0", CGU_CLK_GATE, @@ -410,6 +379,11 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = { .parents = { JZ4770_CLK_MMC2_MUX, }, .gate = { CGU_REG_CLKGR0, 12 }, }, + [JZ4770_CLK_OTG_PHY] = { + "usb_phy", CGU_CLK_GATE, + .parents = { JZ4770_CLK_OTG }, + .gate = { CGU_REG_OPCR, 7, true, 50 }, + }, /* Custom clocks */ @@ -418,11 +392,6 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = { .parents = { JZ4770_CLK_UHC, -1, -1, -1 }, .custom = { &jz4770_uhc_phy_ops }, }, - [JZ4770_CLK_OTG_PHY] = { - "usb_phy", CGU_CLK_CUSTOM, - .parents = { JZ4770_CLK_OTG, -1, -1, -1 }, - .custom = { &jz4770_otg_phy_ops }, - }, [JZ4770_CLK_EXT512] = { "ext/512", CGU_CLK_FIXDIV, |