linux/arch/sh/kernel/cpu/sh5/clock-sh5.c
<<
>>
Prefs
   1/*
   2 * arch/sh/kernel/cpu/sh5/clock-sh5.c
   3 *
   4 * SH-5 support for the clock framework
   5 *
   6 *  Copyright (C) 2008  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/io.h>
  16
  17static int ifc_table[] = { 2, 4, 6, 8, 10, 12, 16, 24 };
  18
  19/* Clock, Power and Reset Controller */
  20#define CPRC_BLOCK_OFF  0x01010000
  21#define CPRC_BASE       (PHYS_PERIPHERAL_BLOCK + CPRC_BLOCK_OFF)
  22
  23static unsigned long cprc_base;
  24
  25static void master_clk_init(struct clk *clk)
  26{
  27        int idx = (__raw_readl(cprc_base + 0x00) >> 6) & 0x0007;
  28        clk->rate *= ifc_table[idx];
  29}
  30
  31static struct sh_clk_ops sh5_master_clk_ops = {
  32        .init           = master_clk_init,
  33};
  34
  35static unsigned long module_clk_recalc(struct clk *clk)
  36{
  37        int idx = (__raw_readw(cprc_base) >> 12) & 0x0007;
  38        return clk->parent->rate / ifc_table[idx];
  39}
  40
  41static struct sh_clk_ops sh5_module_clk_ops = {
  42        .recalc         = module_clk_recalc,
  43};
  44
  45static unsigned long bus_clk_recalc(struct clk *clk)
  46{
  47        int idx = (__raw_readw(cprc_base) >> 3) & 0x0007;
  48        return clk->parent->rate / ifc_table[idx];
  49}
  50
  51static struct sh_clk_ops sh5_bus_clk_ops = {
  52        .recalc         = bus_clk_recalc,
  53};
  54
  55static unsigned long cpu_clk_recalc(struct clk *clk)
  56{
  57        int idx = (__raw_readw(cprc_base) & 0x0007);
  58        return clk->parent->rate / ifc_table[idx];
  59}
  60
  61static struct sh_clk_ops sh5_cpu_clk_ops = {
  62        .recalc         = cpu_clk_recalc,
  63};
  64
  65static struct sh_clk_ops *sh5_clk_ops[] = {
  66        &sh5_master_clk_ops,
  67        &sh5_module_clk_ops,
  68        &sh5_bus_clk_ops,
  69        &sh5_cpu_clk_ops,
  70};
  71
  72void __init arch_init_clk_ops(struct sh_clk_ops **ops, int idx)
  73{
  74        cprc_base = (unsigned long)ioremap_nocache(CPRC_BASE, 1024);
  75        BUG_ON(!cprc_base);
  76
  77        if (idx < ARRAY_SIZE(sh5_clk_ops))
  78                *ops = sh5_clk_ops[idx];
  79}
  80