/*
 * It works on following logic:
 *
 * For enabling clock, enable = 1
 *	set2dis = 1	-> clear bit	-> set = 0
 *	set2dis = 0	-> set bit	-> set = 1
 *
 * For disabling clock, enable = 0
 *	set2dis = 1	-> set bit	-> set = 1
 *	set2dis = 0	-> clear bit	-> set = 0
 *
 * So, result is always: enable xor set2dis.
 */
static void clk_gate_endisable(struct clk_hw *hw, int enable)
{
	struct clk_gate *gate = to_clk_gate(hw);
	int set = gate->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0;
	unsigned long uninitialized_var(flags);
	u32 reg;

	set ^= enable;

	if (gate->lock)
		spin_lock_irqsave(gate->lock, flags);
	else
		__acquire(gate->lock);

	if (gate->flags & CLK_GATE_HIWORD_MASK) {
		reg = BIT(gate->bit_idx + 16);
		if (set)
			reg |= BIT(gate->bit_idx);
	} else {
		reg = clk_readl(gate->reg);

		if (set)
			reg |= BIT(gate->bit_idx);
		else
			reg &= ~BIT(gate->bit_idx);
	}

	clk_writel(reg, gate->reg);

	if (gate->lock)
		spin_unlock_irqrestore(gate->lock, flags);
	else
		__release(gate->lock);
}
/*
 * It works on following logic:
 *
 * For enabling clock, enable = 1
 *	set2dis = 1	-> clear bit	-> set = 0
 *	set2dis = 0	-> set bit	-> set = 1
 *
 * For disabling clock, enable = 0
 *	set2dis = 1	-> set bit	-> set = 1
 *	set2dis = 0	-> clear bit	-> set = 0
 *
 * So, result is always: enable xor set2dis.
 */
static void clk_gate_endisable(struct clk_hw *hw, int enable)
{
	struct clk_gate *gate = to_clk_gate(hw);
	int set = gate->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0;
	unsigned long flags = 0;
	u32 reg;

	set ^= enable;

#ifdef CONFIG_HISI_CLK
        #define CLK_GATE_ALWAYS_ON_MASK   0x4
	if ((!set) && (gate->flags & CLK_GATE_ALWAYS_ON_MASK))
		return;
#endif
	if (gate->lock)
		spin_lock_irqsave(gate->lock, flags);

	if (gate->flags & CLK_GATE_HIWORD_MASK) {
		reg = BIT(gate->bit_idx + 16);
		if (set)
			reg |= BIT(gate->bit_idx);
	} else {
		reg = readl(gate->reg);

		if (set)
			reg |= BIT(gate->bit_idx);
		else
			reg &= ~BIT(gate->bit_idx);
	}

	writel(reg, gate->reg);

	if (gate->lock)
		spin_unlock_irqrestore(gate->lock, flags);
}
Esempio n. 3
0
/*
 * It works on following logic:
 *
 * For enabling clock, enable = 1
 *	set2dis = 1	-> clear bit	-> set = 0
 *	set2dis = 0	-> set bit	-> set = 1
 *
 * For disabling clock, enable = 0
 *	set2dis = 1	-> set bit	-> set = 1
 *	set2dis = 0	-> clear bit	-> set = 0
 *
 * So, result is always: enable xor set2dis.
 */
static void clk_gate_endisable(struct clk_hw *hw, int enable)
{
	struct clk_gate *gate = to_clk_gate(hw);
	int set = gate->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0;
	u32 reg;
	int ret;

	set ^= enable;

	if (gate->flags & CLK_GATE_HIWORD_MASK) {
		reg = BIT(gate->bit_idx + 16);
	} else {
		ret = zynqmp_pm_mmio_read((u32)(ulong)gate->reg, &reg);
		if (ret)
			pr_warn_once("Read fail gate address: %x\n",
					(u32)(ulong)gate->reg);

		if (!set)
			reg &= ~BIT(gate->bit_idx);
	}

	if (set)
		reg |= BIT(gate->bit_idx);
	ret = zynqmp_pm_mmio_writel(reg, gate->reg);
	if (ret)
		pr_warn_once("Write failed gate address:%x\n", (u32)(ulong)reg);
}
Esempio n. 4
0
static int lpc18xx_ccu_gate_endisable(struct clk_hw *hw, bool enable)
{
	struct clk_gate *gate = to_clk_gate(hw);
	u32 val;

	/*
	 * Divider field is write only, so divider stat field must
	 * be read so divider field can be set accordingly.
	 */
	val = clk_readl(gate->reg);
	if (val & LPC18XX_CCU_DIVSTAT)
		val |= LPC18XX_CCU_DIV;

	if (enable) {
		val |= LPC18XX_CCU_RUN;
	} else {
		/*
		 * To safely disable a branch clock a squence of two separate
		 * writes must be used. First write should set the AUTO bit
		 * and the next write should clear the RUN bit.
		 */
		val |= LPC18XX_CCU_AUTO;
		clk_writel(val, gate->reg);

		val &= ~LPC18XX_CCU_RUN;
	}

	clk_writel(val, gate->reg);

	return 0;
}
Esempio n. 5
0
static void clk_gate_disable(struct clk_hw *hw)
{
	struct clk_gate *gate = to_clk_gate(hw);

	if (gate->flags & CLK_GATE_SET_TO_DISABLE)
		clk_gate_set_bit(gate);
	else
		clk_gate_clear_bit(gate);
}
void clk_hw_unregister_gate(struct clk_hw *hw)
{
	struct clk_gate *gate;

	gate = to_clk_gate(hw);

	clk_hw_unregister(hw);
	kfree(gate);
}
Esempio n. 7
0
static int mtk_cg_bit_is_set(struct clk_hw *hw)
{
	struct mtk_clk_gate *cg = to_clk_gate(hw);
	u32 val;

	regmap_read(cg->regmap, cg->sta_ofs, &val);

	val &= BIT(cg->bit);

	return val != 0;
}
Esempio n. 8
0
static int clk_gate_enable(struct clk_hw *hw)
{
	struct clk_gate *gate = to_clk_gate(hw);

	if (gate->flags & CLK_GATE_SET_TO_DISABLE)
		clk_gate_clear_bit(gate);
	else
		clk_gate_set_bit(gate);

	return 0;
}
void clk_unregister_gate(struct clk *clk)
{
	struct clk_gate *gate;
	struct clk_hw *hw;

	hw = __clk_get_hw(clk);
	if (!hw)
		return;

	gate = to_clk_gate(hw);

	clk_unregister(clk);
	kfree(gate);
}
static int clk_gate_is_enabled(struct clk_hw *hw)
{
	u32 reg;
	struct clk_gate *gate = to_clk_gate(hw);

	reg = clk_readl(gate->reg);

	/* if a set bit disables this clk, flip it before masking */
	if (gate->flags & CLK_GATE_SET_TO_DISABLE)
		reg ^= BIT(gate->bit_idx);

	reg &= BIT(gate->bit_idx);

	return reg ? 1 : 0;
}
Esempio n. 11
0
static struct clk *clk_gating_get_src(
	struct of_phandle_args *clkspec, void *data)
{
	int n;

	if (clkspec->args_count < 1)
		return ERR_PTR(-EINVAL);

	for (n = 0; n < ctrl->num_gates; n++) {
		struct clk_gate *gate =
			to_clk_gate(__clk_get_hw(ctrl->gates[n]));
		if (clkspec->args[0] == gate->bit_idx)
			return ctrl->gates[n];
	}
	return ERR_PTR(-ENODEV);
}
Esempio n. 12
0
static int zynqmp_clk_gate_is_enabled(struct clk_hw *hw)
{
	u32 reg;
	int ret;
	struct clk_gate *gate = to_clk_gate(hw);

	ret = zynqmp_pm_mmio_read((u32)(ulong)gate->reg, &reg);
	if (ret)
		pr_warn_once("Read failed gate address: %x\n",
				(u32)(ulong)gate->reg);

	/* if a set bit disables this clk, flip it before masking */
	if (gate->flags & CLK_GATE_SET_TO_DISABLE)
		reg ^= BIT(gate->bit_idx);

	reg &= BIT(gate->bit_idx);

	return reg ? 1 : 0;
}
Esempio n. 13
0
static int cg_is_enabled(struct clk_hw *hw)
{
	struct mtk_clk_gate *cg = to_clk_gate(hw);
	u32 mask;
	u32 val;
	int r;
#ifdef Bring_Up
        return 0;
#endif

	mask = BIT(cg->bit);
	val = mask & readl(cg->sta_addr);

	r = (cg->flags & CLK_GATE_INVERSE) ? (val != 0) : (val == 0);

	pr_debug("%d, %s, bit[%d]\n", r, __clk_get_name(hw->clk), (int)cg->bit);

	return r;
}
Esempio n. 14
0
static int clk_gate_is_enabled(struct clk_hw *hw)
{
	u32 reg;
	struct clk_gate *gate = to_clk_gate(hw);
#if !defined(CONFIG_MTK_LEGACY) /* FIXME: only for bring up */
	printk("[CCF] %s: %s\n", __func__, __clk_get_name(hw->clk));
	return 1;
#endif /* !defined(CONFIG_MTK_LEGACY) */

	reg = readl(gate->reg);

	/* if a set bit disables this clk, flip it before masking */
	if (gate->flags & CLK_GATE_SET_TO_DISABLE)
		reg ^= BIT(gate->bit_idx);

	reg &= BIT(gate->bit_idx);

	return reg ? 1 : 0;
}
Esempio n. 15
0
static void cg_disable(struct clk_hw *hw)
{
	unsigned long flags = 0;
	struct mtk_clk_gate *cg = to_clk_gate(hw);
	u32 mask = BIT(cg->bit);
#ifdef Bring_Up
	pr_debug("[CCF] %s: %s, bit: %u\n", __func__, __clk_get_name(hw->clk),
	       cg->bit);
        return;
#endif

	pr_debug("%s, bit: %u\n", __clk_get_name(hw->clk), cg->bit);

	mtk_clk_lock(flags);

	if (cg->flags & CLK_GATE_INVERSE)
		cg_clr_mask(cg, mask);
	else
		cg_set_mask(cg, mask);

	mtk_clk_unlock(flags);
}
Esempio n. 16
0
/*
 * It works on following logic:
 *
 * For enabling clock, enable = 1
 *	set2dis = 1	-> clear bit	-> set = 0
 *	set2dis = 0	-> set bit	-> set = 1
 *
 * For disabling clock, enable = 0
 *	set2dis = 1	-> set bit	-> set = 1
 *	set2dis = 0	-> clear bit	-> set = 0
 *
 * So, result is always: enable xor set2dis.
 */
static void clk_gate_endisable(struct clk_hw *hw, int enable)
{
	struct clk_gate *gate = to_clk_gate(hw);
	int set = gate->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0;
	unsigned long flags = 0;
	u32 reg;

	set ^= enable;

	if (gate->lock)
		spin_lock_irqsave(gate->lock, flags);

	reg = readl(gate->reg);

	if (set)
		reg |= BIT(gate->bit_idx);
	else
		reg &= ~BIT(gate->bit_idx);

	writel(reg, gate->reg);

	if (gate->lock)
		spin_unlock_irqrestore(gate->lock, flags);
}
Esempio n. 17
0
static void mtk_cg_clr_bit(struct clk_hw *hw)
{
	struct mtk_clk_gate *cg = to_clk_gate(hw);

	regmap_write(cg->regmap, cg->clr_ofs, BIT(cg->bit));
}