static int alpha_pll_set_rate(struct clk *c, unsigned long rate)
{
	struct alpha_pll_clk *pll = to_alpha_pll_clk(c);
	struct alpha_pll_masks *masks = pll->masks;
	unsigned long flags, freq_hz;
	u32 regval, l_val;
	int vco_val;
	u64 a_val;

	freq_hz = round_rate_up(pll, rate, &l_val, &a_val);
	if (freq_hz != rate) {
		pr_err("alpha_pll: Call clk_set_rate with rounded rates!\n");
		return -EINVAL;
	}

	vco_val = find_vco(pll, freq_hz);
	if (IS_ERR_VALUE(vco_val)) {
		pr_err("alpha pll: not in a valid vco range\n");
		return -EINVAL;
	}

	/*
	 * Ensure PLL is off before changing rate. For optimization reasons,
	 * assume no downstream clock is actively using it. No support
	 * for dynamic update at the moment.
	 */
	spin_lock_irqsave(&c->lock, flags);
	if (c->count)
		alpha_pll_disable(c);

	a_val = a_val << (ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH);

	writel_relaxed(l_val, L_REG(pll));
	__iowrite32_copy(A_REG(pll), &a_val, 2);

	if (masks->vco_mask) {
		regval = readl_relaxed(VCO_REG(pll));
		regval &= ~(masks->vco_mask << masks->vco_shift);
		regval |= vco_val << masks->vco_shift;
		writel_relaxed(regval, VCO_REG(pll));
	}

	regval = readl_relaxed(ALPHA_EN_REG(pll));
	regval |= masks->alpha_en_mask;
	writel_relaxed(regval, ALPHA_EN_REG(pll));

	if (c->count)
		alpha_pll_enable(c);

	spin_unlock_irqrestore(&c->lock, flags);
	return 0;
}
static void setup_alpha_pll_values(u64 a_val, u32 l_val, u32 vco_val,
				struct alpha_pll_clk *pll)
{
	struct alpha_pll_masks *masks = pll->masks;
	u32 regval;

	a_val = a_val << (ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH);

	writel_relaxed(l_val, L_REG(pll));
	__iowrite32_copy(A_REG(pll), &a_val, 2);

	if (vco_val != UINT_MAX) {
		regval = readl_relaxed(VCO_REG(pll));
		regval &= ~(masks->vco_mask << masks->vco_shift);
		regval |= vco_val << masks->vco_shift;
		writel_relaxed(regval, VCO_REG(pll));
	}

	regval = readl_relaxed(ALPHA_EN_REG(pll));
	regval |= masks->alpha_en_mask;
	writel_relaxed(regval, ALPHA_EN_REG(pll));
}