136ddf31bSPaul Mundt /* 236ddf31bSPaul Mundt * arch/sh/kernel/cpu/sh4/clock-sh4-202.c 336ddf31bSPaul Mundt * 436ddf31bSPaul Mundt * Additional SH4-202 support for the clock framework 536ddf31bSPaul Mundt * 636ddf31bSPaul Mundt * Copyright (C) 2005 Paul Mundt 736ddf31bSPaul Mundt * 836ddf31bSPaul Mundt * This file is subject to the terms and conditions of the GNU General Public 936ddf31bSPaul Mundt * License. See the file "COPYING" in the main directory of this archive 1036ddf31bSPaul Mundt * for more details. 1136ddf31bSPaul Mundt */ 1236ddf31bSPaul Mundt #include <linux/init.h> 1336ddf31bSPaul Mundt #include <linux/kernel.h> 1436ddf31bSPaul Mundt #include <linux/err.h> 1536ddf31bSPaul Mundt #include <asm/clock.h> 1636ddf31bSPaul Mundt #include <asm/freq.h> 1736ddf31bSPaul Mundt #include <asm/io.h> 1836ddf31bSPaul Mundt 1936ddf31bSPaul Mundt #define CPG2_FRQCR3 0xfe0a0018 2036ddf31bSPaul Mundt 2136ddf31bSPaul Mundt static int frqcr3_divisors[] = { 1, 2, 3, 4, 6, 8, 16 }; 2236ddf31bSPaul Mundt static int frqcr3_values[] = { 0, 1, 2, 3, 4, 5, 6 }; 2336ddf31bSPaul Mundt 2436ddf31bSPaul Mundt static void emi_clk_recalc(struct clk *clk) 2536ddf31bSPaul Mundt { 2636ddf31bSPaul Mundt int idx = ctrl_inl(CPG2_FRQCR3) & 0x0007; 2736ddf31bSPaul Mundt clk->rate = clk->parent->rate / frqcr3_divisors[idx]; 2836ddf31bSPaul Mundt } 2936ddf31bSPaul Mundt 3036ddf31bSPaul Mundt static inline int frqcr3_lookup(struct clk *clk, unsigned long rate) 3136ddf31bSPaul Mundt { 3236ddf31bSPaul Mundt int divisor = clk->parent->rate / rate; 3336ddf31bSPaul Mundt int i; 3436ddf31bSPaul Mundt 3536ddf31bSPaul Mundt for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++) 3636ddf31bSPaul Mundt if (frqcr3_divisors[i] == divisor) 3736ddf31bSPaul Mundt return frqcr3_values[i]; 3836ddf31bSPaul Mundt 3936ddf31bSPaul Mundt /* Safe fallback */ 4036ddf31bSPaul Mundt return 5; 4136ddf31bSPaul Mundt } 4236ddf31bSPaul Mundt 4336ddf31bSPaul Mundt static struct clk_ops sh4202_emi_clk_ops = { 4436ddf31bSPaul Mundt .recalc = emi_clk_recalc, 4536ddf31bSPaul Mundt }; 4636ddf31bSPaul Mundt 4736ddf31bSPaul Mundt static struct clk sh4202_emi_clk = { 4836ddf31bSPaul Mundt .name = "emi_clk", 4936ddf31bSPaul Mundt .flags = CLK_ALWAYS_ENABLED, 5036ddf31bSPaul Mundt .ops = &sh4202_emi_clk_ops, 5136ddf31bSPaul Mundt }; 5236ddf31bSPaul Mundt 5336ddf31bSPaul Mundt static void femi_clk_recalc(struct clk *clk) 5436ddf31bSPaul Mundt { 5536ddf31bSPaul Mundt int idx = (ctrl_inl(CPG2_FRQCR3) >> 3) & 0x0007; 5636ddf31bSPaul Mundt clk->rate = clk->parent->rate / frqcr3_divisors[idx]; 5736ddf31bSPaul Mundt } 5836ddf31bSPaul Mundt 5936ddf31bSPaul Mundt static struct clk_ops sh4202_femi_clk_ops = { 6036ddf31bSPaul Mundt .recalc = femi_clk_recalc, 6136ddf31bSPaul Mundt }; 6236ddf31bSPaul Mundt 6336ddf31bSPaul Mundt static struct clk sh4202_femi_clk = { 6436ddf31bSPaul Mundt .name = "femi_clk", 6536ddf31bSPaul Mundt .flags = CLK_ALWAYS_ENABLED, 6636ddf31bSPaul Mundt .ops = &sh4202_femi_clk_ops, 6736ddf31bSPaul Mundt }; 6836ddf31bSPaul Mundt 6936ddf31bSPaul Mundt static void shoc_clk_init(struct clk *clk) 7036ddf31bSPaul Mundt { 7136ddf31bSPaul Mundt int i; 7236ddf31bSPaul Mundt 7336ddf31bSPaul Mundt /* 7436ddf31bSPaul Mundt * For some reason, the shoc_clk seems to be set to some really 7536ddf31bSPaul Mundt * insane value at boot (values outside of the allowable frequency 7636ddf31bSPaul Mundt * range for instance). We deal with this by scaling it back down 7736ddf31bSPaul Mundt * to something sensible just in case. 7836ddf31bSPaul Mundt * 7936ddf31bSPaul Mundt * Start scaling from the high end down until we find something 8036ddf31bSPaul Mundt * that passes rate verification.. 8136ddf31bSPaul Mundt */ 8236ddf31bSPaul Mundt for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++) { 8336ddf31bSPaul Mundt int divisor = frqcr3_divisors[i]; 8436ddf31bSPaul Mundt 851929cb34Sdmitry pervushin if (clk->ops->set_rate(clk, clk->parent->rate / 861929cb34Sdmitry pervushin divisor, 0) == 0) 8736ddf31bSPaul Mundt break; 8836ddf31bSPaul Mundt } 8936ddf31bSPaul Mundt 9036ddf31bSPaul Mundt WARN_ON(i == ARRAY_SIZE(frqcr3_divisors)); /* Undefined clock */ 9136ddf31bSPaul Mundt } 9236ddf31bSPaul Mundt 9336ddf31bSPaul Mundt static void shoc_clk_recalc(struct clk *clk) 9436ddf31bSPaul Mundt { 9536ddf31bSPaul Mundt int idx = (ctrl_inl(CPG2_FRQCR3) >> 6) & 0x0007; 9636ddf31bSPaul Mundt clk->rate = clk->parent->rate / frqcr3_divisors[idx]; 9736ddf31bSPaul Mundt } 9836ddf31bSPaul Mundt 9936ddf31bSPaul Mundt static int shoc_clk_verify_rate(struct clk *clk, unsigned long rate) 10036ddf31bSPaul Mundt { 1011d118562SPaul Mundt struct clk *bclk = clk_get(NULL, "bus_clk"); 10236ddf31bSPaul Mundt unsigned long bclk_rate = clk_get_rate(bclk); 10336ddf31bSPaul Mundt 10436ddf31bSPaul Mundt clk_put(bclk); 10536ddf31bSPaul Mundt 10636ddf31bSPaul Mundt if (rate > bclk_rate) 10736ddf31bSPaul Mundt return 1; 10836ddf31bSPaul Mundt if (rate > 66000000) 10936ddf31bSPaul Mundt return 1; 11036ddf31bSPaul Mundt 11136ddf31bSPaul Mundt return 0; 11236ddf31bSPaul Mundt } 11336ddf31bSPaul Mundt 11436ddf31bSPaul Mundt static int shoc_clk_set_rate(struct clk *clk, unsigned long rate) 11536ddf31bSPaul Mundt { 11636ddf31bSPaul Mundt unsigned long frqcr3; 11736ddf31bSPaul Mundt unsigned int tmp; 11836ddf31bSPaul Mundt 11936ddf31bSPaul Mundt /* Make sure we have something sensible to switch to */ 12036ddf31bSPaul Mundt if (shoc_clk_verify_rate(clk, rate) != 0) 12136ddf31bSPaul Mundt return -EINVAL; 12236ddf31bSPaul Mundt 12336ddf31bSPaul Mundt tmp = frqcr3_lookup(clk, rate); 12436ddf31bSPaul Mundt 12536ddf31bSPaul Mundt frqcr3 = ctrl_inl(CPG2_FRQCR3); 12636ddf31bSPaul Mundt frqcr3 &= ~(0x0007 << 6); 12736ddf31bSPaul Mundt frqcr3 |= tmp << 6; 12836ddf31bSPaul Mundt ctrl_outl(frqcr3, CPG2_FRQCR3); 12936ddf31bSPaul Mundt 13036ddf31bSPaul Mundt clk->rate = clk->parent->rate / frqcr3_divisors[tmp]; 13136ddf31bSPaul Mundt 13236ddf31bSPaul Mundt return 0; 13336ddf31bSPaul Mundt } 13436ddf31bSPaul Mundt 13536ddf31bSPaul Mundt static struct clk_ops sh4202_shoc_clk_ops = { 13636ddf31bSPaul Mundt .init = shoc_clk_init, 13736ddf31bSPaul Mundt .recalc = shoc_clk_recalc, 13836ddf31bSPaul Mundt .set_rate = shoc_clk_set_rate, 13936ddf31bSPaul Mundt }; 14036ddf31bSPaul Mundt 14136ddf31bSPaul Mundt static struct clk sh4202_shoc_clk = { 14236ddf31bSPaul Mundt .name = "shoc_clk", 14336ddf31bSPaul Mundt .flags = CLK_ALWAYS_ENABLED, 14436ddf31bSPaul Mundt .ops = &sh4202_shoc_clk_ops, 14536ddf31bSPaul Mundt }; 14636ddf31bSPaul Mundt 14736ddf31bSPaul Mundt static struct clk *sh4202_onchip_clocks[] = { 14836ddf31bSPaul Mundt &sh4202_emi_clk, 14936ddf31bSPaul Mundt &sh4202_femi_clk, 15036ddf31bSPaul Mundt &sh4202_shoc_clk, 15136ddf31bSPaul Mundt }; 15236ddf31bSPaul Mundt 15336ddf31bSPaul Mundt static int __init sh4202_clk_init(void) 15436ddf31bSPaul Mundt { 1551d118562SPaul Mundt struct clk *clk = clk_get(NULL, "master_clk"); 15636ddf31bSPaul Mundt int i; 15736ddf31bSPaul Mundt 15836ddf31bSPaul Mundt for (i = 0; i < ARRAY_SIZE(sh4202_onchip_clocks); i++) { 15936ddf31bSPaul Mundt struct clk *clkp = sh4202_onchip_clocks[i]; 16036ddf31bSPaul Mundt 16136ddf31bSPaul Mundt clkp->parent = clk; 16236ddf31bSPaul Mundt clk_register(clkp); 16336ddf31bSPaul Mundt clk_enable(clkp); 16436ddf31bSPaul Mundt } 16536ddf31bSPaul Mundt 16636ddf31bSPaul Mundt /* 16736ddf31bSPaul Mundt * Now that we have the rest of the clocks registered, we need to 16836ddf31bSPaul Mundt * force the parent clock to propagate so that these clocks will 16936ddf31bSPaul Mundt * automatically figure out their rate. We cheat by handing the 17036ddf31bSPaul Mundt * parent clock its current rate and forcing child propagation. 17136ddf31bSPaul Mundt */ 17236ddf31bSPaul Mundt clk_set_rate(clk, clk_get_rate(clk)); 17336ddf31bSPaul Mundt 17436ddf31bSPaul Mundt clk_put(clk); 17536ddf31bSPaul Mundt 17636ddf31bSPaul Mundt return 0; 17736ddf31bSPaul Mundt } 17836ddf31bSPaul Mundt 17936ddf31bSPaul Mundt arch_initcall(sh4202_clk_init); 18036ddf31bSPaul Mundt 181