1/* 2 * arch/metag/kernel/clock.c 3 * 4 * Copyright (C) 2012 Imagination Technologies Ltd. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 */ 10 11#include <linux/clk.h> 12#include <linux/delay.h> 13#include <linux/io.h> 14#include <linux/of.h> 15 16#include <asm/param.h> 17#include <asm/clock.h> 18 19struct meta_clock_desc _meta_clock; 20 21/* Default machine get_core_freq callback. */ 22static unsigned long get_core_freq_default(void) 23{ 24#ifdef CONFIG_METAG_META21 25 /* 26 * Meta 2 cores divide down the core clock for the Meta timers, so we 27 * can estimate the core clock from the divider. 28 */ 29 return (metag_in32(EXPAND_TIMER_DIV) + 1) * 1000000; 30#else 31 /* 32 * On Meta 1 we don't know the core clock, but assuming the Meta timer 33 * is correct it can be estimated based on loops_per_jiffy. 34 */ 35 return (loops_per_jiffy * HZ * 5) >> 1; 36#endif 37} 38 39static struct clk *clk_core; 40 41/* Clk based get_core_freq callback. */ 42static unsigned long get_core_freq_clk(void) 43{ 44 return clk_get_rate(clk_core); 45} 46 47/** 48 * init_metag_core_clock() - Set up core clock from devicetree. 49 * 50 * Checks to see if a "core" clock is provided in the device tree, and overrides 51 * the get_core_freq callback to use it. 52 */ 53static void __init init_metag_core_clock(void) 54{ 55 /* 56 * See if a core clock is provided by the devicetree (and 57 * registered by the init callback above). 58 */ 59 struct device_node *node; 60 node = of_find_compatible_node(NULL, NULL, "img,meta"); 61 if (!node) { 62 pr_warn("%s: no compatible img,meta DT node found\n", 63 __func__); 64 return; 65 } 66 67 clk_core = of_clk_get_by_name(node, "core"); 68 if (IS_ERR(clk_core)) { 69 pr_warn("%s: no core clock found in DT\n", 70 __func__); 71 return; 72 } 73 74 /* 75 * Override the core frequency callback to use 76 * this clk. 77 */ 78 _meta_clock.get_core_freq = get_core_freq_clk; 79} 80 81/** 82 * init_metag_clocks() - Set up clocks from devicetree. 83 * 84 * Set up important clocks from device tree. In particular any needed for clock 85 * sources. 86 */ 87void __init init_metag_clocks(void) 88{ 89 init_metag_core_clock(); 90 91 pr_info("Core clock frequency: %lu Hz\n", get_coreclock()); 92} 93 94/** 95 * setup_meta_clocks() - Early set up of the Meta clock. 96 * @desc: Clock descriptor usually provided by machine description 97 * 98 * Ensures all callbacks are valid. 99 */ 100void __init setup_meta_clocks(struct meta_clock_desc *desc) 101{ 102 /* copy callbacks */ 103 if (desc) 104 _meta_clock = *desc; 105 106 /* set fallback functions */ 107 if (!_meta_clock.get_core_freq) 108 _meta_clock.get_core_freq = get_core_freq_default; 109} 110 111