linux/arch/sh/kernel/cpu/sh2a/clock-sh7203.c
<<
>>
Prefs
   1/*
   2 * arch/sh/kernel/cpu/sh2a/clock-sh7203.c
   3 *
   4 * SH7203 support for the clock framework
   5 *
   6 *  Copyright (C) 2007 Kieran Bingham (MPC-Data Ltd)
   7 *
   8 * Based on clock-sh7263.c
   9 *  Copyright (C) 2006  Yoshinori Sato
  10 *
  11 * Based on clock-sh4.c
  12 *  Copyright (C) 2005  Paul Mundt
  13 *
  14 * This file is subject to the terms and conditions of the GNU General Public
  15 * License.  See the file "COPYING" in the main directory of this archive
  16 * for more details.
  17 */
  18#include <linux/init.h>
  19#include <linux/kernel.h>
  20#include <asm/clock.h>
  21#include <asm/freq.h>
  22#include <asm/io.h>
  23
  24static const int pll1rate[]={8,12,16,0};
  25static const int pfc_divisors[]={1,2,3,4,6,8,12};
  26#define ifc_divisors pfc_divisors
  27
  28static unsigned int pll2_mult;
  29
  30static void master_clk_init(struct clk *clk)
  31{
  32        clk->rate *= pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0003] * pll2_mult;
  33}
  34
  35static struct sh_clk_ops sh7203_master_clk_ops = {
  36        .init           = master_clk_init,
  37};
  38
  39static unsigned long module_clk_recalc(struct clk *clk)
  40{
  41        int idx = (__raw_readw(FREQCR) & 0x0007);
  42        return clk->parent->rate / pfc_divisors[idx];
  43}
  44
  45static struct sh_clk_ops sh7203_module_clk_ops = {
  46        .recalc         = module_clk_recalc,
  47};
  48
  49static unsigned long bus_clk_recalc(struct clk *clk)
  50{
  51        int idx = (__raw_readw(FREQCR) & 0x0007);
  52        return clk->parent->rate / pfc_divisors[idx-2];
  53}
  54
  55static struct sh_clk_ops sh7203_bus_clk_ops = {
  56        .recalc         = bus_clk_recalc,
  57};
  58
  59static struct sh_clk_ops sh7203_cpu_clk_ops = {
  60        .recalc         = followparent_recalc,
  61};
  62
  63static struct sh_clk_ops *sh7203_clk_ops[] = {
  64        &sh7203_master_clk_ops,
  65        &sh7203_module_clk_ops,
  66        &sh7203_bus_clk_ops,
  67        &sh7203_cpu_clk_ops,
  68};
  69
  70void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
  71{
  72        if (test_mode_pin(MODE_PIN1))
  73                pll2_mult = 4;
  74        else if (test_mode_pin(MODE_PIN0))
  75                pll2_mult = 2;
  76        else
  77                pll2_mult = 1;
  78
  79        if (idx < ARRAY_SIZE(sh7203_clk_ops))
  80                *ops = sh7203_clk_ops[idx];
  81}
  82