110 lines · 2.6 KB · C
RawDownload
/* * arch/metag/kernel/clock.c * * Copyright (C) 2012 Imagination Technologies Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include <linux/clk.h>#include <linux/delay.h>#include <linux/io.h>#include <linux/of.h> #include <asm/param.h>#include <asm/clock.h> struct meta_clock_desc _meta_clock; /* Default machine get_core_freq callback. */static unsigned long get_core_freq_default(void){#ifdef CONFIG_METAG_META21	/*	 * Meta 2 cores divide down the core clock for the Meta timers, so we	 * can estimate the core clock from the divider.	 */	return (metag_in32(EXPAND_TIMER_DIV) + 1) * 1000000;#else	/*	 * On Meta 1 we don't know the core clock, but assuming the Meta timer	 * is correct it can be estimated based on loops_per_jiffy.	 */	return (loops_per_jiffy * HZ * 5) >> 1;#endif} static struct clk *clk_core; /* Clk based get_core_freq callback. */static unsigned long get_core_freq_clk(void){	return clk_get_rate(clk_core);} /** * init_metag_core_clock() - Set up core clock from devicetree. * * Checks to see if a "core" clock is provided in the device tree, and overrides * the get_core_freq callback to use it. */static void __init init_metag_core_clock(void){	/*	 * See if a core clock is provided by the devicetree (and	 * registered by the init callback above).	 */	struct device_node *node;	node = of_find_compatible_node(NULL, NULL, "img,meta");	if (!node) {		pr_warn("%s: no compatible img,meta DT node found\n",			__func__);		return;	} 	clk_core = of_clk_get_by_name(node, "core");	if (IS_ERR(clk_core)) {		pr_warn("%s: no core clock found in DT\n",			__func__);		return;	} 	/*	 * Override the core frequency callback to use	 * this clk.	 */	_meta_clock.get_core_freq = get_core_freq_clk;} /** * init_metag_clocks() - Set up clocks from devicetree. * * Set up important clocks from device tree. In particular any needed for clock * sources. */void __init init_metag_clocks(void){	init_metag_core_clock(); 	pr_info("Core clock frequency: %lu Hz\n", get_coreclock());} /** * setup_meta_clocks() - Early set up of the Meta clock. * @desc:	Clock descriptor usually provided by machine description * * Ensures all callbacks are valid. */void __init setup_meta_clocks(struct meta_clock_desc *desc){	/* copy callbacks */	if (desc)		_meta_clock = *desc; 	/* set fallback functions */	if (!_meta_clock.get_core_freq)		_meta_clock.get_core_freq = get_core_freq_default;}