1 #include <linux/clk.h> 2 #include <linux/compiler.h> 3 #include <linux/slab.h> 4 #include <linux/io.h> 5 #include <asm/clock.h> 6 7 static int sh_clk_mstp32_enable(struct clk *clk) 8 { 9 __raw_writel(__raw_readl(clk->enable_reg) & ~(1 << clk->enable_bit), 10 clk->enable_reg); 11 return 0; 12 } 13 14 static void sh_clk_mstp32_disable(struct clk *clk) 15 { 16 __raw_writel(__raw_readl(clk->enable_reg) | (1 << clk->enable_bit), 17 clk->enable_reg); 18 } 19 20 static struct clk_ops sh_clk_mstp32_clk_ops = { 21 .enable = sh_clk_mstp32_enable, 22 .disable = sh_clk_mstp32_disable, 23 .recalc = followparent_recalc, 24 }; 25 26 int __init sh_clk_mstp32_register(struct clk *clks, int nr) 27 { 28 struct clk *clkp; 29 int ret = 0; 30 int k; 31 32 for (k = 0; !ret && (k < nr); k++) { 33 clkp = clks + k; 34 clkp->ops = &sh_clk_mstp32_clk_ops; 35 ret |= clk_register(clkp); 36 } 37 38 return ret; 39 } 40 41 static long sh_clk_div_round_rate(struct clk *clk, unsigned long rate) 42 { 43 return clk_rate_table_round(clk, clk->freq_table, rate); 44 } 45 46 static int sh_clk_div6_divisors[64] = { 47 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 48 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 49 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 50 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64 51 }; 52 53 static struct clk_div_mult_table sh_clk_div6_table = { 54 .divisors = sh_clk_div6_divisors, 55 .nr_divisors = ARRAY_SIZE(sh_clk_div6_divisors), 56 }; 57 58 static unsigned long sh_clk_div6_recalc(struct clk *clk) 59 { 60 struct clk_div_mult_table *table = &sh_clk_div6_table; 61 unsigned int idx; 62 63 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, 64 table, NULL); 65 66 idx = __raw_readl(clk->enable_reg) & 0x003f; 67 68 return clk->freq_table[idx].frequency; 69 } 70 71 static int sh_clk_div6_set_rate(struct clk *clk, 72 unsigned long rate, int algo_id) 73 { 74 unsigned long value; 75 int idx; 76 77 idx = clk_rate_table_find(clk, clk->freq_table, rate); 78 if (idx < 0) 79 return idx; 80 81 value = __raw_readl(clk->enable_reg); 82 value &= ~0x3f; 83 value |= idx; 84 __raw_writel(value, clk->enable_reg); 85 return 0; 86 } 87 88 static int sh_clk_div6_enable(struct clk *clk) 89 { 90 unsigned long value; 91 int ret; 92 93 ret = sh_clk_div6_set_rate(clk, clk->rate, 0); 94 if (ret == 0) { 95 value = __raw_readl(clk->enable_reg); 96 value &= ~0x100; /* clear stop bit to enable clock */ 97 __raw_writel(value, clk->enable_reg); 98 } 99 return ret; 100 } 101 102 static void sh_clk_div6_disable(struct clk *clk) 103 { 104 unsigned long value; 105 106 value = __raw_readl(clk->enable_reg); 107 value |= 0x100; /* stop clock */ 108 value |= 0x3f; /* VDIV bits must be non-zero, overwrite divider */ 109 __raw_writel(value, clk->enable_reg); 110 } 111 112 static struct clk_ops sh_clk_div6_clk_ops = { 113 .recalc = sh_clk_div6_recalc, 114 .round_rate = sh_clk_div_round_rate, 115 .set_rate = sh_clk_div6_set_rate, 116 .enable = sh_clk_div6_enable, 117 .disable = sh_clk_div6_disable, 118 }; 119 120 int __init sh_clk_div6_register(struct clk *clks, int nr) 121 { 122 struct clk *clkp; 123 void *freq_table; 124 int nr_divs = sh_clk_div6_table.nr_divisors; 125 int freq_table_size = sizeof(struct cpufreq_frequency_table); 126 int ret = 0; 127 int k; 128 129 freq_table_size *= (nr_divs + 1); 130 freq_table = kzalloc(freq_table_size * nr, GFP_KERNEL); 131 if (!freq_table) { 132 pr_err("sh_clk_div6_register: unable to alloc memory\n"); 133 return -ENOMEM; 134 } 135 136 for (k = 0; !ret && (k < nr); k++) { 137 clkp = clks + k; 138 139 clkp->ops = &sh_clk_div6_clk_ops; 140 clkp->id = -1; 141 clkp->freq_table = freq_table + (k * freq_table_size); 142 clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END; 143 144 ret = clk_register(clkp); 145 } 146 147 return ret; 148 } 149 150 static unsigned long sh_clk_div4_recalc(struct clk *clk) 151 { 152 struct clk_div_mult_table *table = clk->priv; 153 unsigned int idx; 154 155 clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, 156 table, &clk->arch_flags); 157 158 idx = (__raw_readl(clk->enable_reg) >> clk->enable_bit) & 0x000f; 159 160 return clk->freq_table[idx].frequency; 161 } 162 163 static struct clk_ops sh_clk_div4_clk_ops = { 164 .recalc = sh_clk_div4_recalc, 165 .round_rate = sh_clk_div_round_rate, 166 }; 167 168 int __init sh_clk_div4_register(struct clk *clks, int nr, 169 struct clk_div_mult_table *table) 170 { 171 struct clk *clkp; 172 void *freq_table; 173 int nr_divs = table->nr_divisors; 174 int freq_table_size = sizeof(struct cpufreq_frequency_table); 175 int ret = 0; 176 int k; 177 178 freq_table_size *= (nr_divs + 1); 179 freq_table = kzalloc(freq_table_size * nr, GFP_KERNEL); 180 if (!freq_table) { 181 pr_err("sh_clk_div4_register: unable to alloc memory\n"); 182 return -ENOMEM; 183 } 184 185 for (k = 0; !ret && (k < nr); k++) { 186 clkp = clks + k; 187 188 clkp->ops = &sh_clk_div4_clk_ops; 189 clkp->id = -1; 190 clkp->priv = table; 191 192 clkp->freq_table = freq_table + (k * freq_table_size); 193 clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END; 194 195 ret = clk_register(clkp); 196 } 197 198 return ret; 199 } 200 201 #ifdef CONFIG_SH_CLK_CPG_LEGACY 202 static struct clk master_clk = { 203 .name = "master_clk", 204 .flags = CLK_ENABLE_ON_INIT, 205 .rate = CONFIG_SH_PCLK_FREQ, 206 }; 207 208 static struct clk peripheral_clk = { 209 .name = "peripheral_clk", 210 .parent = &master_clk, 211 .flags = CLK_ENABLE_ON_INIT, 212 }; 213 214 static struct clk bus_clk = { 215 .name = "bus_clk", 216 .parent = &master_clk, 217 .flags = CLK_ENABLE_ON_INIT, 218 }; 219 220 static struct clk cpu_clk = { 221 .name = "cpu_clk", 222 .parent = &master_clk, 223 .flags = CLK_ENABLE_ON_INIT, 224 }; 225 226 /* 227 * The ordering of these clocks matters, do not change it. 228 */ 229 static struct clk *onchip_clocks[] = { 230 &master_clk, 231 &peripheral_clk, 232 &bus_clk, 233 &cpu_clk, 234 }; 235 236 int __init __deprecated cpg_clk_init(void) 237 { 238 int i, ret = 0; 239 240 for (i = 0; i < ARRAY_SIZE(onchip_clocks); i++) { 241 struct clk *clk = onchip_clocks[i]; 242 arch_init_clk_ops(&clk->ops, i); 243 if (clk->ops) 244 ret |= clk_register(clk); 245 } 246 247 return ret; 248 } 249 250 /* 251 * Placeholder for compatability, until the lazy CPUs do this 252 * on their own. 253 */ 254 int __init __weak arch_clk_init(void) 255 { 256 return cpg_clk_init(); 257 } 258 #endif /* CONFIG_SH_CPG_CLK_LEGACY */ 259