metag: init common clk and use "core" clk

If the common clock framework is enabled, call of_clk_init(NULL) in
time_init() to register device tree clocks with the clock framework.

After this time_init() calls a new function init_metag_clocks(), which
looks for a clock named "core" in the node compatible with "img,meta"
(usually the root node). If found the get_core_freq machine callback is
overridden to obtain the core clock frequency using that clock.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Cc: Mike Turquette <mturquette@linaro.org>
Cc: Grant Likely <grant.likely@linaro.org>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: devicetree-discuss@lists.ozlabs.org
This commit is contained in:
James Hogan 2013-01-15 15:27:45 +00:00
parent c24d2976c7
commit caa279dda4
4 changed files with 106 additions and 3 deletions

View File

@ -0,0 +1,30 @@
* Meta Processor Binding
This binding specifies what properties must be available in the device tree
representation of a Meta Processor Core, which is the root node in the tree.
Required properties:
- compatible: Specifies the compatibility list for the Meta processor.
The type shall be <string> and the value shall include "img,meta".
Optional properties:
- clocks: Clock consumer specifiers as described in
Documentation/devicetree/bindings/clock/clock-bindings.txt
- clock-names: Clock consumer names as described in
Documentation/devicetree/bindings/clock/clock-bindings.txt.
Clocks are identified by name. Valid clocks are:
- "core": The Meta core clock from which the Meta timers are derived.
* Examples
/ {
compatible = "toumaz,tz1090", "img,meta";
clocks = <&meta_core_clk>;
clock-names = "core";
};

View File

@ -19,6 +19,8 @@
* core frequency will be determined like this:
* Meta 1: based on loops_per_jiffy.
* Meta 2: (EXPAND_TIMER_DIV + 1) MHz.
* If a "core" clock is provided by the device tree, it
* will override this function.
*/
struct meta_clock_desc {
unsigned long (*get_core_freq)(void);
@ -26,6 +28,12 @@ struct meta_clock_desc {
extern struct meta_clock_desc _meta_clock;
/*
* Perform platform clock initialisation, reading clocks from device tree etc.
* Only accessible during boot.
*/
void init_metag_clocks(void);
/*
* Set up the default clock, ensuring all callbacks are valid - only accessible
* during boot.

View File

@ -8,8 +8,10 @@
* 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>
@ -34,8 +36,61 @@ static unsigned long get_core_freq_default(void)
#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);
}
/**
* setup_meta_clocks() - Set up the Meta clock.
* 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();
}
/**
* setup_meta_clocks() - Early set up of the Meta clock.
* @desc: Clock descriptor usually provided by machine description
*
* Ensures all callbacks are valid.

View File

@ -5,11 +5,21 @@
*
*/
#include <linux/init.h>
#include <clocksource/metag_generic.h>
#include <linux/clk-provider.h>
#include <linux/init.h>
#include <asm/clock.h>
void __init time_init(void)
{
#ifdef CONFIG_COMMON_CLK
/* Init clocks from device tree */
of_clk_init(NULL);
#endif
/* Init meta clocks, particularly the core clock */
init_metag_clocks();
/* Set up the timer clock sources */
metag_generic_timer_init();
}