Path: blob/master/arch/sh/kernel/cpu/sh4a/clock-sh7780.c
17495 views
/*1* arch/sh/kernel/cpu/sh4a/clock-sh7780.c2*3* SH7780 support for the clock framework4*5* Copyright (C) 2005 Paul Mundt6*7* This file is subject to the terms and conditions of the GNU General Public8* License. See the file "COPYING" in the main directory of this archive9* for more details.10*/11#include <linux/init.h>12#include <linux/kernel.h>13#include <linux/io.h>14#include <linux/clkdev.h>15#include <asm/clock.h>16#include <asm/freq.h>17#include <asm/io.h>1819static int ifc_divisors[] = { 2, 4 };20static int bfc_divisors[] = { 1, 1, 1, 8, 12, 16, 24, 1 };21static int pfc_divisors[] = { 1, 24, 24, 1 };22static int cfc_divisors[] = { 1, 1, 4, 1, 6, 1, 1, 1 };2324static void master_clk_init(struct clk *clk)25{26clk->rate *= pfc_divisors[__raw_readl(FRQCR) & 0x0003];27}2829static struct clk_ops sh7780_master_clk_ops = {30.init = master_clk_init,31};3233static unsigned long module_clk_recalc(struct clk *clk)34{35int idx = (__raw_readl(FRQCR) & 0x0003);36return clk->parent->rate / pfc_divisors[idx];37}3839static struct clk_ops sh7780_module_clk_ops = {40.recalc = module_clk_recalc,41};4243static unsigned long bus_clk_recalc(struct clk *clk)44{45int idx = ((__raw_readl(FRQCR) >> 16) & 0x0007);46return clk->parent->rate / bfc_divisors[idx];47}4849static struct clk_ops sh7780_bus_clk_ops = {50.recalc = bus_clk_recalc,51};5253static unsigned long cpu_clk_recalc(struct clk *clk)54{55int idx = ((__raw_readl(FRQCR) >> 24) & 0x0001);56return clk->parent->rate / ifc_divisors[idx];57}5859static struct clk_ops sh7780_cpu_clk_ops = {60.recalc = cpu_clk_recalc,61};6263static struct clk_ops *sh7780_clk_ops[] = {64&sh7780_master_clk_ops,65&sh7780_module_clk_ops,66&sh7780_bus_clk_ops,67&sh7780_cpu_clk_ops,68};6970void __init arch_init_clk_ops(struct clk_ops **ops, int idx)71{72if (idx < ARRAY_SIZE(sh7780_clk_ops))73*ops = sh7780_clk_ops[idx];74}7576static unsigned long shyway_clk_recalc(struct clk *clk)77{78int idx = ((__raw_readl(FRQCR) >> 20) & 0x0007);79return clk->parent->rate / cfc_divisors[idx];80}8182static struct clk_ops sh7780_shyway_clk_ops = {83.recalc = shyway_clk_recalc,84};8586static struct clk sh7780_shyway_clk = {87.flags = CLK_ENABLE_ON_INIT,88.ops = &sh7780_shyway_clk_ops,89};9091/*92* Additional SH7780-specific on-chip clocks that aren't already part of the93* clock framework94*/95static struct clk *sh7780_onchip_clocks[] = {96&sh7780_shyway_clk,97};9899#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }100101static struct clk_lookup lookups[] = {102/* main clocks */103CLKDEV_CON_ID("shyway_clk", &sh7780_shyway_clk),104};105106int __init arch_clk_init(void)107{108struct clk *clk;109int i, ret = 0;110111cpg_clk_init();112113clk = clk_get(NULL, "master_clk");114for (i = 0; i < ARRAY_SIZE(sh7780_onchip_clocks); i++) {115struct clk *clkp = sh7780_onchip_clocks[i];116117clkp->parent = clk;118ret |= clk_register(clkp);119}120121clk_put(clk);122123clkdev_add_table(lookups, ARRAY_SIZE(lookups));124125return ret;126}127128129