123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- /*
- * 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;
- }
|