Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 25e06074 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "clk: qcom: clock-local2: Add memory toggle support for branch clocks"

parents d112533f 7e8955f4
Loading
Loading
Loading
Loading
+46 −37
Original line number Diff line number Diff line
@@ -414,12 +414,53 @@ static void branch_clk_halt_check(struct clk *c, u32 halt_check,
	}
}

static int branch_clk_set_flags(struct clk *c, unsigned flags)
{
	u32 cbcr_val;
	unsigned long irq_flags;
	struct branch_clk *branch = to_branch_clk(c);
	int delay_us = 0, ret = 0;

	spin_lock_irqsave(&local_clock_reg_lock, irq_flags);
	cbcr_val = readl_relaxed(CBCR_REG(branch));
	switch (flags) {
	case CLKFLAG_RETAIN_PERIPH:
		cbcr_val |= BIT(13);
		delay_us = 1;
		break;
	case CLKFLAG_NORETAIN_PERIPH:
		cbcr_val &= ~BIT(13);
		break;
	case CLKFLAG_RETAIN_MEM:
		cbcr_val |= BIT(14);
		delay_us = 1;
		break;
	case CLKFLAG_NORETAIN_MEM:
		cbcr_val &= ~BIT(14);
		break;
	default:
		ret = -EINVAL;
	}
	writel_relaxed(cbcr_val, CBCR_REG(branch));
	/* Make sure power is enabled before returning. */
	mb();
	udelay(delay_us);

	spin_unlock_irqrestore(&local_clock_reg_lock, irq_flags);

	return ret;
}

static int branch_clk_enable(struct clk *c)
{
	unsigned long flags;
	u32 cbcr_val;
	struct branch_clk *branch = to_branch_clk(c);

	if (branch->toggle_memory) {
		branch_clk_set_flags(c, CLKFLAG_RETAIN_MEM);
		branch_clk_set_flags(c, CLKFLAG_RETAIN_PERIPH);
	}
	spin_lock_irqsave(&local_clock_reg_lock, flags);
	cbcr_val = readl_relaxed(CBCR_REG(branch));
	cbcr_val |= CBCR_BRANCH_ENABLE_BIT;
@@ -448,6 +489,11 @@ static void branch_clk_disable(struct clk *c)
	/* Wait for clock to disable before continuing. */
	branch_clk_halt_check(c, branch->halt_check, CBCR_REG(branch),
				BRANCH_OFF);

	if (branch->toggle_memory) {
		branch_clk_set_flags(c, CLKFLAG_NORETAIN_MEM);
		branch_clk_set_flags(c, CLKFLAG_NORETAIN_PERIPH);
	}
}

static int branch_cdiv_set_rate(struct branch_clk *branch, unsigned long rate)
@@ -598,43 +644,6 @@ static int branch_clk_reset(struct clk *c, enum clk_reset_action action)
	return __branch_clk_reset(BCR_REG(branch), action);
}

static int branch_clk_set_flags(struct clk *c, unsigned flags)
{
	u32 cbcr_val;
	unsigned long irq_flags;
	struct branch_clk *branch = to_branch_clk(c);
	int delay_us = 0, ret = 0;

	spin_lock_irqsave(&local_clock_reg_lock, irq_flags);
	cbcr_val = readl_relaxed(CBCR_REG(branch));
	switch (flags) {
	case CLKFLAG_RETAIN_PERIPH:
		cbcr_val |= BIT(13);
		delay_us = 1;
		break;
	case CLKFLAG_NORETAIN_PERIPH:
		cbcr_val &= ~BIT(13);
		break;
	case CLKFLAG_RETAIN_MEM:
		cbcr_val |= BIT(14);
		delay_us = 1;
		break;
	case CLKFLAG_NORETAIN_MEM:
		cbcr_val &= ~BIT(14);
		break;
	default:
		ret = -EINVAL;
	}
	writel_relaxed(cbcr_val, CBCR_REG(branch));
	/* Make sure power is enabled before returning. */
	mb();
	udelay(delay_us);

	spin_unlock_irqrestore(&local_clock_reg_lock, irq_flags);

	return ret;
}

static void __iomem *branch_clk_list_registers(struct clk *c, int n,
				struct clk_register_data **regs, u32 *size)
{
+2 −0
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ extern struct clk_freq_tbl rcg_dummy_freq;
 * @cur_div: current branch divider value
 * @max_div: maximum branch divider value (if zero, no divider exists)
 * @halt_check: halt checking type
 * @toggle_memory: toggle memory during enable/disable if true
 * @base: pointer to base address of ioremapped registers.
 */
struct branch_clk {
@@ -96,6 +97,7 @@ struct branch_clk {
	u32 cur_div;
	u32 max_div;
	const u32 halt_check;
	bool toggle_memory;
	void *const __iomem *base;
};