linux/arch/sh/kernel/cpu/sh4a/clock-sh7770.c
<<
>>
Prefs
   1/*
   2 * arch/sh/kernel/cpu/sh4a/clock-sh7770.c
   3 *
   4 * SH7770 support for the clock framework
   5 *
   6 *  Copyright (C) 2005  Paul Mundt
   7 *
   8 * This file is subject to the terms and conditions of the GNU General Public
   9 * License.  See the file "COPYING" in the main directory of this archive
  10 * for more details.
  11 */
  12#include <linux/init.h>
  13#include <linux/kernel.h>
  14#include <asm/clock.h>
  15#include <asm/freq.h>
  16#include <asm/io.h>
  17
  18static int ifc_divisors[] = { 1, 1, 1, 1, 1, 1, 1, 1 };
  19static int bfc_divisors[] = { 1, 1, 1, 1, 1, 8,12, 1 };
  20static int pfc_divisors[] = { 1, 8, 1,10,12,16, 1, 1 };
  21
  22static void master_clk_init(struct clk *clk)
  23{
  24        clk->rate *= pfc_divisors[(ctrl_inl(FRQCR) >> 28) & 0x000f];
  25}
  26
  27static struct clk_ops sh7770_master_clk_ops = {
  28        .init           = master_clk_init,
  29};
  30
  31static unsigned long module_clk_recalc(struct clk *clk)
  32{
  33        int idx = ((ctrl_inl(FRQCR) >> 28) & 0x000f);
  34        return clk->parent->rate / pfc_divisors[idx];
  35}
  36
  37static struct clk_ops sh7770_module_clk_ops = {
  38        .recalc         = module_clk_recalc,
  39};
  40
  41static unsigned long bus_clk_recalc(struct clk *clk)
  42{
  43        int idx = (ctrl_inl(FRQCR) & 0x000f);
  44        return clk->parent->rate / bfc_divisors[idx];
  45}
  46
  47static struct clk_ops sh7770_bus_clk_ops = {
  48        .recalc         = bus_clk_recalc,
  49};
  50
  51static unsigned long cpu_clk_recalc(struct clk *clk)
  52{
  53        int idx = ((ctrl_inl(FRQCR) >> 24) & 0x000f);
  54        return clk->parent->rate / ifc_divisors[idx];
  55}
  56
  57static struct clk_ops sh7770_cpu_clk_ops = {
  58        .recalc         = cpu_clk_recalc,
  59};
  60
  61static struct clk_ops *sh7770_clk_ops[] = {
  62        &sh7770_master_clk_ops,
  63        &sh7770_module_clk_ops,
  64        &sh7770_bus_clk_ops,
  65        &sh7770_cpu_clk_ops,
  66};
  67
  68void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
  69{
  70        if (idx < ARRAY_SIZE(sh7770_clk_ops))
  71                *ops = sh7770_clk_ops[idx];
  72}
  73
  74