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 2516b25920SPaul Mundt static unsigned int pll2_mult; 262825999eSPeter Griffin 272825999eSPeter Griffin static void master_clk_init(struct clk *clk) 282825999eSPeter Griffin { 2916b25920SPaul Mundt clk->rate = 10000000 * pll2_mult * 3016b25920SPaul Mundt pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007]; 312825999eSPeter Griffin } 322825999eSPeter Griffin 33*4ad2c061SMagnus Damm static struct sh_clk_ops sh7201_master_clk_ops = { 342825999eSPeter Griffin .init = master_clk_init, 352825999eSPeter Griffin }; 362825999eSPeter Griffin 37b68d8201SPaul Mundt static unsigned long module_clk_recalc(struct clk *clk) 382825999eSPeter Griffin { 399d56dd3bSPaul Mundt int idx = (__raw_readw(FREQCR) & 0x0007); 40b68d8201SPaul Mundt return clk->parent->rate / pfc_divisors[idx]; 412825999eSPeter Griffin } 422825999eSPeter Griffin 43*4ad2c061SMagnus Damm static struct sh_clk_ops sh7201_module_clk_ops = { 442825999eSPeter Griffin .recalc = module_clk_recalc, 452825999eSPeter Griffin }; 462825999eSPeter Griffin 47b68d8201SPaul Mundt static unsigned long bus_clk_recalc(struct clk *clk) 482825999eSPeter Griffin { 499d56dd3bSPaul Mundt int idx = (__raw_readw(FREQCR) & 0x0007); 50b68d8201SPaul Mundt return clk->parent->rate / pfc_divisors[idx]; 512825999eSPeter Griffin } 522825999eSPeter Griffin 53*4ad2c061SMagnus Damm static struct sh_clk_ops sh7201_bus_clk_ops = { 542825999eSPeter Griffin .recalc = bus_clk_recalc, 552825999eSPeter Griffin }; 562825999eSPeter Griffin 57b68d8201SPaul Mundt static unsigned long cpu_clk_recalc(struct clk *clk) 582825999eSPeter Griffin { 599d56dd3bSPaul Mundt int idx = ((__raw_readw(FREQCR) >> 4) & 0x0007); 60b68d8201SPaul Mundt return clk->parent->rate / ifc_divisors[idx]; 612825999eSPeter Griffin } 622825999eSPeter Griffin 63*4ad2c061SMagnus Damm static struct sh_clk_ops sh7201_cpu_clk_ops = { 642825999eSPeter Griffin .recalc = cpu_clk_recalc, 652825999eSPeter Griffin }; 662825999eSPeter Griffin 67*4ad2c061SMagnus Damm static struct sh_clk_ops *sh7201_clk_ops[] = { 682825999eSPeter Griffin &sh7201_master_clk_ops, 692825999eSPeter Griffin &sh7201_module_clk_ops, 702825999eSPeter Griffin &sh7201_bus_clk_ops, 712825999eSPeter Griffin &sh7201_cpu_clk_ops, 722825999eSPeter Griffin }; 732825999eSPeter Griffin 74*4ad2c061SMagnus Damm void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx) 752825999eSPeter Griffin { 7616b25920SPaul Mundt if (test_mode_pin(MODE_PIN1 | MODE_PIN0)) 7716b25920SPaul Mundt pll2_mult = 1; 7816b25920SPaul Mundt else if (test_mode_pin(MODE_PIN1)) 7916b25920SPaul Mundt pll2_mult = 2; 8016b25920SPaul Mundt else 8116b25920SPaul Mundt pll2_mult = 4; 8216b25920SPaul Mundt 832825999eSPeter Griffin if (idx < ARRAY_SIZE(sh7201_clk_ops)) 842825999eSPeter Griffin *ops = sh7201_clk_ops[idx]; 852825999eSPeter Griffin } 86