1 /* 2 * arch/sh/kernel/cpu/sh4/clock-sh4-202.c 3 * 4 * Additional SH4-202 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 <linux/err.h> 15 #include <asm/clock.h> 16 #include <asm/freq.h> 17 #include <asm/io.h> 18 19 #define CPG2_FRQCR3 0xfe0a0018 20 21 static int frqcr3_divisors[] = { 1, 2, 3, 4, 6, 8, 16 }; 22 static int frqcr3_values[] = { 0, 1, 2, 3, 4, 5, 6 }; 23 24 static void emi_clk_recalc(struct clk *clk) 25 { 26 int idx = ctrl_inl(CPG2_FRQCR3) & 0x0007; 27 clk->rate = clk->parent->rate / frqcr3_divisors[idx]; 28 } 29 30 static inline int frqcr3_lookup(struct clk *clk, unsigned long rate) 31 { 32 int divisor = clk->parent->rate / rate; 33 int i; 34 35 for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++) 36 if (frqcr3_divisors[i] == divisor) 37 return frqcr3_values[i]; 38 39 /* Safe fallback */ 40 return 5; 41 } 42 43 static struct clk_ops sh4202_emi_clk_ops = { 44 .recalc = emi_clk_recalc, 45 }; 46 47 static struct clk sh4202_emi_clk = { 48 .name = "emi_clk", 49 .flags = CLK_ALWAYS_ENABLED, 50 .ops = &sh4202_emi_clk_ops, 51 }; 52 53 static void femi_clk_recalc(struct clk *clk) 54 { 55 int idx = (ctrl_inl(CPG2_FRQCR3) >> 3) & 0x0007; 56 clk->rate = clk->parent->rate / frqcr3_divisors[idx]; 57 } 58 59 static struct clk_ops sh4202_femi_clk_ops = { 60 .recalc = femi_clk_recalc, 61 }; 62 63 static struct clk sh4202_femi_clk = { 64 .name = "femi_clk", 65 .flags = CLK_ALWAYS_ENABLED, 66 .ops = &sh4202_femi_clk_ops, 67 }; 68 69 static void shoc_clk_init(struct clk *clk) 70 { 71 int i; 72 73 /* 74 * For some reason, the shoc_clk seems to be set to some really 75 * insane value at boot (values outside of the allowable frequency 76 * range for instance). We deal with this by scaling it back down 77 * to something sensible just in case. 78 * 79 * Start scaling from the high end down until we find something 80 * that passes rate verification.. 81 */ 82 for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++) { 83 int divisor = frqcr3_divisors[i]; 84 85 if (clk->ops->set_rate(clk, clk->parent->rate / 86 divisor, 0) == 0) 87 break; 88 } 89 90 WARN_ON(i == ARRAY_SIZE(frqcr3_divisors)); /* Undefined clock */ 91 } 92 93 static void shoc_clk_recalc(struct clk *clk) 94 { 95 int idx = (ctrl_inl(CPG2_FRQCR3) >> 6) & 0x0007; 96 clk->rate = clk->parent->rate / frqcr3_divisors[idx]; 97 } 98 99 static int shoc_clk_verify_rate(struct clk *clk, unsigned long rate) 100 { 101 struct clk *bclk = clk_get(NULL, "bus_clk"); 102 unsigned long bclk_rate = clk_get_rate(bclk); 103 104 clk_put(bclk); 105 106 if (rate > bclk_rate) 107 return 1; 108 if (rate > 66000000) 109 return 1; 110 111 return 0; 112 } 113 114 static int shoc_clk_set_rate(struct clk *clk, unsigned long rate, int algo_id) 115 { 116 unsigned long frqcr3; 117 unsigned int tmp; 118 119 /* Make sure we have something sensible to switch to */ 120 if (shoc_clk_verify_rate(clk, rate) != 0) 121 return -EINVAL; 122 123 tmp = frqcr3_lookup(clk, rate); 124 125 frqcr3 = ctrl_inl(CPG2_FRQCR3); 126 frqcr3 &= ~(0x0007 << 6); 127 frqcr3 |= tmp << 6; 128 ctrl_outl(frqcr3, CPG2_FRQCR3); 129 130 clk->rate = clk->parent->rate / frqcr3_divisors[tmp]; 131 132 return 0; 133 } 134 135 static struct clk_ops sh4202_shoc_clk_ops = { 136 .init = shoc_clk_init, 137 .recalc = shoc_clk_recalc, 138 .set_rate = shoc_clk_set_rate, 139 }; 140 141 static struct clk sh4202_shoc_clk = { 142 .name = "shoc_clk", 143 .flags = CLK_ALWAYS_ENABLED, 144 .ops = &sh4202_shoc_clk_ops, 145 }; 146 147 static struct clk *sh4202_onchip_clocks[] = { 148 &sh4202_emi_clk, 149 &sh4202_femi_clk, 150 &sh4202_shoc_clk, 151 }; 152 153 static int __init sh4202_clk_init(void) 154 { 155 struct clk *clk = clk_get(NULL, "master_clk"); 156 int i; 157 158 for (i = 0; i < ARRAY_SIZE(sh4202_onchip_clocks); i++) { 159 struct clk *clkp = sh4202_onchip_clocks[i]; 160 161 clkp->parent = clk; 162 clk_register(clkp); 163 clk_enable(clkp); 164 } 165 166 /* 167 * Now that we have the rest of the clocks registered, we need to 168 * force the parent clock to propagate so that these clocks will 169 * automatically figure out their rate. We cheat by handing the 170 * parent clock its current rate and forcing child propagation. 171 */ 172 clk_set_rate(clk, clk_get_rate(clk)); 173 174 clk_put(clk); 175 176 return 0; 177 } 178 179 arch_initcall(sh4202_clk_init); 180 181