Пример #1
0
static int clk_fracdiv_get_config(unsigned long rate_out, unsigned long rate,
		u32 *numerator, u32 *denominator)
{
	u32 gcd_val;
	gcd_val = clk_gcd(rate, rate_out);
	clk_debug("%s: frac_get_seting rate=%lu, parent=%lu, gcd=%d\n",
			__func__, rate_out, rate, gcd_val);

	if (!gcd_val) {
		clk_err("gcd=0, frac div is not be supported\n");
		return -EINVAL;
	}

	*numerator = rate_out / gcd_val;
	*denominator = rate / gcd_val;

	clk_debug("%s: frac_get_seting numerator=%d, denominator=%d, times=%d\n",
			__func__, *numerator, *denominator,
			*denominator / *numerator);

	if (*numerator > 0xffff || *denominator > 0xffff ||
			(*denominator / (*numerator)) < 20) {
		clk_err("can't get a available nume and deno\n");
		return -EINVAL;
	}

	return 0;

}
Пример #2
0
static int clk_ddr_set_rate(struct clk_hw *hw, unsigned long rate,
		unsigned long parent_rate)
{
	struct clk *parent = __clk_get_parent(hw->clk);
	struct clk *grand_p = __clk_get_parent(parent);


	/* Do nothing before ddr init */
	if (!ddr_change_freq)
		return 0;

	if (IS_ERR_OR_NULL(parent) || IS_ERR_OR_NULL(grand_p)) {
		clk_err("fail to get parent or grand_parent!\n");
		return -EINVAL;
	}

	clk_debug("%s: will set rate = %lu\n", __func__, rate);

	/* Func provided by ddr driver */
	ddr_change_freq(rate/MHZ);

	parent->rate = parent->ops->recalc_rate(parent->hw,
			__clk_get_rate(grand_p));

	return 0;
}
Пример #3
0
static int clk_i2s_fracdiv_set_rate(struct clk_hw *hw, unsigned long rate,
		unsigned long parent_rate)
{
	u32 numerator, denominator;
	struct clk_divider *div = to_clk_divider(hw);
	int i = 10;


	if(clk_fracdiv_get_config(rate, parent_rate,
				&numerator, &denominator) == 0) {
		while (i--) {
			writel((numerator - 1) << 16 | denominator, div->reg);
			mdelay(1);
			writel(numerator << 16 | denominator, div->reg);
			mdelay(1);
		}
		clk_debug("%s set rate=%lu,is ok\n", hw->clk->name, rate);
	} else {
		clk_err("clk_frac_div name=%s can't get rate=%lu\n",
				hw->clk->name, rate);
		return -EINVAL;
	}

	return 0;
}
Пример #4
0
static int mt_golden_setting_init(void)
{
#if defined(CONFIG_MT_ENG_BUILD)
#define GOLDEN_SETTING_BUF_SIZE (2 * PAGE_SIZE)

	unsigned int *buf;

	buf = kmalloc(GOLDEN_SETTING_BUF_SIZE, GFP_KERNEL);

	if (NULL != buf) {
		_golden_setting_init(&_golden, buf, GOLDEN_SETTING_BUF_SIZE);

#ifdef CONFIG_OF
        _golden.phy_base = 0;
        _golden.io_base = 0;
#endif
		{
			struct proc_dir_entry *dir = NULL;
			int i;

			const struct {
				const char *name;
				const struct file_operations *fops;
			} entries[] = {
				PROC_ENTRY(golden_test),
			};

			dir = proc_mkdir("golden", NULL);

			if (!dir) {
				clk_err("[%s]: fail to mkdir /proc/golden\n", __func__);
				EXIT_FUNC(FUNC_LV_API);
				return -ENOMEM;
			}

			for (i = 0; i < ARRAY_SIZE(entries); i++) {
				if (!proc_create(entries[i].name, S_IRUGO | S_IWUSR | S_IWGRP, dir, entries[i].fops))
					clk_err("[%s]: fail to mkdir /proc/golden/%s\n", __func__, entries[i].name);
			}
		}
	}

#endif // CONFIG_MT_ENG_BUILD
	return 0;
}
Пример #5
0
static long clk_core_determine_rate(struct clk_hw *hw, unsigned long rate,
		unsigned long *best_parent_rate,
		struct clk **best_parent_p)
{
	struct clk *parent = __clk_get_parent(hw->clk);

	if (IS_ERR_OR_NULL(parent)) {
		clk_err("fail to get parent!\n");
		return 0;
	}

	return clk_round_rate(parent, rate);
}
Пример #6
0
static int clk_core_set_rate(struct clk_hw *hw, unsigned long rate,
		unsigned long parent_rate)
{
	struct clk *parent = __clk_get_parent(hw->clk);
	struct clk *grand_p = __clk_get_parent(parent);
	int ret;

	if (IS_ERR_OR_NULL(parent) || IS_ERR_OR_NULL(grand_p)) {
		clk_err("fail to get parent or grand_parent!\n");
		return -EINVAL;
	}

	ret = parent->ops->set_rate(parent->hw, rate, __clk_get_rate(grand_p));
	parent->rate = parent->ops->recalc_rate(parent->hw,
			__clk_get_rate(grand_p));

	return ret;
}
Пример #7
0
struct clk *rk_clk_register_pd(struct device *dev, const char *name,
		const char *parent_name, unsigned long flags, 
		u32 pd_id, spinlock_t *lock)
{
	struct clk_pd *pd;
	struct clk *clk;
	struct clk_init_data init;


	/* allocate the pd */
	pd = kzalloc(sizeof(struct clk_pd), GFP_KERNEL);
	if (!pd) {
		clk_err("%s: could not allocate pd clk\n", __func__);
		return ERR_PTR(-ENOMEM);
	}

	init.name = name;
	init.flags = flags | CLK_IS_BASIC;
	init.parent_names = (parent_name ? &parent_name: NULL);
	init.num_parents = (parent_name ? 1 : 0);

	if(pd_id == CLK_PD_VIRT)
		init.ops = &clk_pd_virt_ops;
	else
		init.ops = &clk_pd_ops;

	/* struct clk_pd assignments */
	pd->id= pd_id;
	pd->lock = lock;
	pd->hw.init = &init;

	/* register the clock */
	clk = clk_register(dev, &pd->hw);

	if (IS_ERR(clk))
		kfree(pd);

	return clk;
}