1 /* 2 * arch/sh/kernel/cpu/sh2/clock-sh7619.c 3 * 4 * SH7619 support for the clock framework 5 * 6 * Copyright (C) 2006 Yoshinori Sato 7 * 8 * Based on clock-sh4.c 9 * Copyright (C) 2005 Paul Mundt 10 * 11 * This file is subject to the terms and conditions of the GNU General Public 12 * License. See the file "COPYING" in the main directory of this archive 13 * for more details. 14 */ 15 #include <linux/init.h> 16 #include <linux/kernel.h> 17 #include <asm/clock.h> 18 #include <asm/freq.h> 19 #include <asm/io.h> 20 21 static const int pll1rate[] = {1,2}; 22 static const int pfc_divisors[] = {1,2,0,4}; 23 24 #if (CONFIG_SH_CLK_MD == 1) || (CONFIG_SH_CLK_MD == 2) 25 #define PLL2 (4) 26 #elif (CONFIG_SH_CLK_MD == 5) || (CONFIG_SH_CLK_MD == 6) 27 #define PLL2 (2) 28 #else 29 #error "Illigal Clock Mode!" 30 #endif 31 32 static void master_clk_init(struct clk *clk) 33 { 34 clk->rate *= PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 7]; 35 } 36 37 static struct clk_ops sh7619_master_clk_ops = { 38 .init = master_clk_init, 39 }; 40 41 static unsigned long module_clk_recalc(struct clk *clk) 42 { 43 int idx = (__raw_readw(FREQCR) & 0x0007); 44 return clk->parent->rate / pfc_divisors[idx]; 45 } 46 47 static struct clk_ops sh7619_module_clk_ops = { 48 .recalc = module_clk_recalc, 49 }; 50 51 static unsigned long bus_clk_recalc(struct clk *clk) 52 { 53 return clk->parent->rate / pll1rate[(__raw_readw(FREQCR) >> 8) & 7]; 54 } 55 56 static struct clk_ops sh7619_bus_clk_ops = { 57 .recalc = bus_clk_recalc, 58 }; 59 60 static struct clk_ops sh7619_cpu_clk_ops = { 61 .recalc = followparent_recalc, 62 }; 63 64 static struct clk_ops *sh7619_clk_ops[] = { 65 &sh7619_master_clk_ops, 66 &sh7619_module_clk_ops, 67 &sh7619_bus_clk_ops, 68 &sh7619_cpu_clk_ops, 69 }; 70 71 void __init arch_init_clk_ops(struct clk_ops **ops, int idx) 72 { 73 if (idx < ARRAY_SIZE(sh7619_clk_ops)) 74 *ops = sh7619_clk_ops[idx]; 75 } 76