Beispiel #1
0
static int vt8500_dclk_set_rate(struct clk_hw *hw, unsigned long rate,
				unsigned long parent_rate)
{
	struct clk_device *cdev = to_clk_device(hw);
	u32 divisor;
	unsigned long flags = 0;

	if (rate == 0)
		return 0;

	divisor =  parent_rate / rate;

	/* If prate / rate would be decimal, incr the divisor */
	if (rate * divisor < parent_rate)
		divisor++;

	if (divisor == cdev->div_mask + 1)
		divisor = 0;

	/* SDMMC mask may need to be corrected before testing if its valid */
	if ((cdev->div_mask == 0x3F) && (divisor > 31)) {
		/*
		 * Bit 5 is a fixed /64 predivisor. If the requested divisor
		 * is >31 then correct for the fixed divisor being required.
		 */
		divisor = 0x20 + (divisor / 64);
	}

	if (divisor > cdev->div_mask) {
		pr_err("%s: invalid divisor for clock\n", __func__);
		return -EINVAL;
	}

	spin_lock_irqsave(cdev->lock, flags);

	vt8500_pmc_wait_busy();
	writel(divisor, cdev->div_reg);
	vt8500_pmc_wait_busy();

	spin_lock_irqsave(cdev->lock, flags);

	return 0;
}
static int vtwm_pll_set_rate(struct clk_hw *hw, unsigned long rate,
				unsigned long parent_rate)
{
	struct clk_pll *pll = to_clk_pll(hw);
	u32 filter, mul, div1, div2;
	u32 pll_val;
	unsigned long flags = 0;

	/* sanity check */

	switch (pll->type) {
	case PLL_TYPE_VT8500:
		vt8500_find_pll_bits(rate, parent_rate, &mul, &div1);
		pll_val = VT8500_BITS_TO_VAL(mul, div1);
		break;
	case PLL_TYPE_WM8650:
		wm8650_find_pll_bits(rate, parent_rate, &mul, &div1, &div2);
		pll_val = WM8650_BITS_TO_VAL(mul, div1, div2);
		break;
	case PLL_TYPE_WM8750:
		wm8750_find_pll_bits(rate, parent_rate, &filter, &mul, &div1, &div2);
		pll_val = WM8750_BITS_TO_VAL(filter, mul, div1, div2);
		break;
	case PLL_TYPE_WM8850:
		wm8850_find_pll_bits(rate, parent_rate, &mul, &div1, &div2);
		pll_val = WM8850_BITS_TO_VAL(mul, div1, div2);
		break;
	default:
		pr_err("%s: invalid pll type\n", __func__);
		return 0;
	}

	spin_lock_irqsave(pll->lock, flags);

	vt8500_pmc_wait_busy();
	writel(pll_val, pll->reg);
	vt8500_pmc_wait_busy();

	spin_unlock_irqrestore(pll->lock, flags);

	return 0;
}