12825999eSPeter Griffin /* 22825999eSPeter Griffin * arch/sh/kernel/cpu/sh2a/clock-sh7201.c 32825999eSPeter Griffin * 42825999eSPeter Griffin * SH7201 support for the clock framework 52825999eSPeter Griffin * 62825999eSPeter Griffin * Copyright (C) 2008 Peter Griffin <pgriffin@mpc-data.co.uk> 72825999eSPeter Griffin * 82825999eSPeter Griffin * Based on clock-sh4.c 92825999eSPeter Griffin * Copyright (C) 2005 Paul Mundt 102825999eSPeter Griffin * 112825999eSPeter Griffin * This file is subject to the terms and conditions of the GNU General Public 122825999eSPeter Griffin * License. See the file "COPYING" in the main directory of this archive 132825999eSPeter Griffin * for more details. 142825999eSPeter Griffin */ 152825999eSPeter Griffin #include <linux/init.h> 162825999eSPeter Griffin #include <linux/kernel.h> 172825999eSPeter Griffin #include <asm/clock.h> 182825999eSPeter Griffin #include <asm/freq.h> 192825999eSPeter Griffin #include <asm/io.h> 202825999eSPeter Griffin 21270c5609STobias Klauser static const int pll1rate[]={1,2,3,4,6,8}; 22270c5609STobias Klauser static const int pfc_divisors[]={1,2,3,4,6,8,12}; 232825999eSPeter Griffin #define ifc_divisors pfc_divisors 242825999eSPeter Griffin 252825999eSPeter Griffin #if (CONFIG_SH_CLK_MD == 0) 262825999eSPeter Griffin #define PLL2 (4) 272825999eSPeter Griffin #elif (CONFIG_SH_CLK_MD == 2) 282825999eSPeter Griffin #define PLL2 (2) 292825999eSPeter Griffin #elif (CONFIG_SH_CLK_MD == 3) 302825999eSPeter Griffin #define PLL2 (1) 312825999eSPeter Griffin #else 322825999eSPeter Griffin #error "Illegal Clock Mode!" 332825999eSPeter Griffin #endif 342825999eSPeter Griffin 352825999eSPeter Griffin static void master_clk_init(struct clk *clk) 362825999eSPeter Griffin { 379d56dd3bSPaul Mundt return 10000000 * PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007]; 382825999eSPeter Griffin } 392825999eSPeter Griffin 402825999eSPeter Griffin static struct clk_ops sh7201_master_clk_ops = { 412825999eSPeter Griffin .init = master_clk_init, 422825999eSPeter Griffin }; 432825999eSPeter Griffin 44b68d8201SPaul Mundt static unsigned long module_clk_recalc(struct clk *clk) 452825999eSPeter Griffin { 469d56dd3bSPaul Mundt int idx = (__raw_readw(FREQCR) & 0x0007); 47b68d8201SPaul Mundt return clk->parent->rate / pfc_divisors[idx]; 482825999eSPeter Griffin } 492825999eSPeter Griffin 502825999eSPeter Griffin static struct clk_ops sh7201_module_clk_ops = { 512825999eSPeter Griffin .recalc = module_clk_recalc, 522825999eSPeter Griffin }; 532825999eSPeter Griffin 54b68d8201SPaul Mundt static unsigned long bus_clk_recalc(struct clk *clk) 552825999eSPeter Griffin { 569d56dd3bSPaul Mundt int idx = (__raw_readw(FREQCR) & 0x0007); 57b68d8201SPaul Mundt return clk->parent->rate / pfc_divisors[idx]; 582825999eSPeter Griffin } 592825999eSPeter Griffin 602825999eSPeter Griffin static struct clk_ops sh7201_bus_clk_ops = { 612825999eSPeter Griffin .recalc = bus_clk_recalc, 622825999eSPeter Griffin }; 632825999eSPeter Griffin 64b68d8201SPaul Mundt static unsigned long cpu_clk_recalc(struct clk *clk) 652825999eSPeter Griffin { 669d56dd3bSPaul Mundt int idx = ((__raw_readw(FREQCR) >> 4) & 0x0007); 67b68d8201SPaul Mundt return clk->parent->rate / ifc_divisors[idx]; 682825999eSPeter Griffin } 692825999eSPeter Griffin 702825999eSPeter Griffin static struct clk_ops sh7201_cpu_clk_ops = { 712825999eSPeter Griffin .recalc = cpu_clk_recalc, 722825999eSPeter Griffin }; 732825999eSPeter Griffin 742825999eSPeter Griffin static struct clk_ops *sh7201_clk_ops[] = { 752825999eSPeter Griffin &sh7201_master_clk_ops, 762825999eSPeter Griffin &sh7201_module_clk_ops, 772825999eSPeter Griffin &sh7201_bus_clk_ops, 782825999eSPeter Griffin &sh7201_cpu_clk_ops, 792825999eSPeter Griffin }; 802825999eSPeter Griffin 812825999eSPeter Griffin void __init arch_init_clk_ops(struct clk_ops **ops, int idx) 822825999eSPeter Griffin { 832825999eSPeter Griffin if (idx < ARRAY_SIZE(sh7201_clk_ops)) 842825999eSPeter Griffin *ops = sh7201_clk_ops[idx]; 852825999eSPeter Griffin } 86