1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> 4 */ 5 6 #include <linux/clk-provider.h> 7 #include <linux/clkdev.h> 8 #include <linux/clk/at91_pmc.h> 9 #include <linux/of.h> 10 #include <linux/mfd/syscon.h> 11 #include <linux/regmap.h> 12 #include <soc/at91/atmel-sfr.h> 13 14 #include "pmc.h" 15 16 /* 17 * The purpose of this clock is to generate a 480 MHz signal. A different 18 * rate can't be configured. 19 */ 20 #define UTMI_RATE 480000000 21 22 struct clk_utmi { 23 struct clk_hw hw; 24 struct regmap *regmap_pmc; 25 struct regmap *regmap_sfr; 26 struct at91_clk_pms pms; 27 }; 28 29 #define to_clk_utmi(hw) container_of(hw, struct clk_utmi, hw) 30 31 static inline bool clk_utmi_ready(struct regmap *regmap) 32 { 33 unsigned int status; 34 35 regmap_read(regmap, AT91_PMC_SR, &status); 36 37 return status & AT91_PMC_LOCKU; 38 } 39 40 static int clk_utmi_prepare(struct clk_hw *hw) 41 { 42 struct clk_hw *hw_parent; 43 struct clk_utmi *utmi = to_clk_utmi(hw); 44 unsigned int uckr = AT91_PMC_UPLLEN | AT91_PMC_UPLLCOUNT | 45 AT91_PMC_BIASEN; 46 unsigned int utmi_ref_clk_freq; 47 unsigned long parent_rate; 48 49 /* 50 * If mainck rate is different from 12 MHz, we have to configure the 51 * FREQ field of the SFR_UTMICKTRIM register to generate properly 52 * the utmi clock. 53 */ 54 hw_parent = clk_hw_get_parent(hw); 55 parent_rate = clk_hw_get_rate(hw_parent); 56 57 switch (parent_rate) { 58 case 12000000: 59 utmi_ref_clk_freq = 0; 60 break; 61 case 16000000: 62 utmi_ref_clk_freq = 1; 63 break; 64 case 24000000: 65 utmi_ref_clk_freq = 2; 66 break; 67 /* 68 * Not supported on SAMA5D2 but it's not an issue since MAINCK 69 * maximum value is 24 MHz. 70 */ 71 case 48000000: 72 utmi_ref_clk_freq = 3; 73 break; 74 default: 75 pr_err("UTMICK: unsupported mainck rate\n"); 76 return -EINVAL; 77 } 78 79 if (utmi->regmap_sfr) { 80 regmap_update_bits(utmi->regmap_sfr, AT91_SFR_UTMICKTRIM, 81 AT91_UTMICKTRIM_FREQ, utmi_ref_clk_freq); 82 } else if (utmi_ref_clk_freq) { 83 pr_err("UTMICK: sfr node required\n"); 84 return -EINVAL; 85 } 86 87 regmap_update_bits(utmi->regmap_pmc, AT91_CKGR_UCKR, uckr, uckr); 88 89 while (!clk_utmi_ready(utmi->regmap_pmc)) 90 cpu_relax(); 91 92 return 0; 93 } 94 95 static int clk_utmi_is_prepared(struct clk_hw *hw) 96 { 97 struct clk_utmi *utmi = to_clk_utmi(hw); 98 99 return clk_utmi_ready(utmi->regmap_pmc); 100 } 101 102 static void clk_utmi_unprepare(struct clk_hw *hw) 103 { 104 struct clk_utmi *utmi = to_clk_utmi(hw); 105 106 regmap_update_bits(utmi->regmap_pmc, AT91_CKGR_UCKR, 107 AT91_PMC_UPLLEN, 0); 108 } 109 110 static unsigned long clk_utmi_recalc_rate(struct clk_hw *hw, 111 unsigned long parent_rate) 112 { 113 /* UTMI clk rate is fixed. */ 114 return UTMI_RATE; 115 } 116 117 static int clk_utmi_save_context(struct clk_hw *hw) 118 { 119 struct clk_utmi *utmi = to_clk_utmi(hw); 120 121 utmi->pms.status = clk_utmi_is_prepared(hw); 122 123 return 0; 124 } 125 126 static void clk_utmi_restore_context(struct clk_hw *hw) 127 { 128 struct clk_utmi *utmi = to_clk_utmi(hw); 129 130 if (utmi->pms.status) 131 clk_utmi_prepare(hw); 132 } 133 134 static const struct clk_ops utmi_ops = { 135 .prepare = clk_utmi_prepare, 136 .unprepare = clk_utmi_unprepare, 137 .is_prepared = clk_utmi_is_prepared, 138 .recalc_rate = clk_utmi_recalc_rate, 139 .save_context = clk_utmi_save_context, 140 .restore_context = clk_utmi_restore_context, 141 }; 142 143 static struct clk_hw * __init 144 at91_clk_register_utmi_internal(struct regmap *regmap_pmc, 145 struct regmap *regmap_sfr, 146 const char *name, const char *parent_name, 147 struct clk_hw *parent_hw, 148 const struct clk_ops *ops, unsigned long flags) 149 { 150 struct clk_utmi *utmi; 151 struct clk_hw *hw; 152 struct clk_init_data init = {}; 153 int ret; 154 155 if (!(parent_name || parent_hw)) 156 return ERR_PTR(-EINVAL); 157 158 utmi = kzalloc(sizeof(*utmi), GFP_KERNEL); 159 if (!utmi) 160 return ERR_PTR(-ENOMEM); 161 162 init.name = name; 163 init.ops = ops; 164 if (parent_hw) 165 init.parent_hws = (const struct clk_hw **)&parent_hw; 166 else 167 init.parent_names = &parent_name; 168 init.num_parents = 1; 169 init.flags = flags; 170 171 utmi->hw.init = &init; 172 utmi->regmap_pmc = regmap_pmc; 173 utmi->regmap_sfr = regmap_sfr; 174 175 hw = &utmi->hw; 176 ret = clk_hw_register(NULL, &utmi->hw); 177 if (ret) { 178 kfree(utmi); 179 hw = ERR_PTR(ret); 180 } 181 182 return hw; 183 } 184 185 struct clk_hw * __init 186 at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr, 187 const char *name, const char *parent_name, 188 struct clk_hw *parent_hw) 189 { 190 return at91_clk_register_utmi_internal(regmap_pmc, regmap_sfr, name, 191 parent_name, parent_hw, &utmi_ops, CLK_SET_RATE_GATE); 192 } 193 194 static int clk_utmi_sama7g5_prepare(struct clk_hw *hw) 195 { 196 struct clk_utmi *utmi = to_clk_utmi(hw); 197 struct clk_hw *hw_parent; 198 unsigned long parent_rate; 199 unsigned int val; 200 201 hw_parent = clk_hw_get_parent(hw); 202 parent_rate = clk_hw_get_rate(hw_parent); 203 204 switch (parent_rate) { 205 case 16000000: 206 val = 0; 207 break; 208 case 20000000: 209 val = 2; 210 break; 211 case 24000000: 212 val = 3; 213 break; 214 case 32000000: 215 val = 5; 216 break; 217 default: 218 pr_err("UTMICK: unsupported main_xtal rate\n"); 219 return -EINVAL; 220 } 221 222 regmap_write(utmi->regmap_pmc, AT91_PMC_XTALF, val); 223 224 return 0; 225 226 } 227 228 static int clk_utmi_sama7g5_is_prepared(struct clk_hw *hw) 229 { 230 struct clk_utmi *utmi = to_clk_utmi(hw); 231 struct clk_hw *hw_parent; 232 unsigned long parent_rate; 233 unsigned int val; 234 235 hw_parent = clk_hw_get_parent(hw); 236 parent_rate = clk_hw_get_rate(hw_parent); 237 238 regmap_read(utmi->regmap_pmc, AT91_PMC_XTALF, &val); 239 switch (val & 0x7) { 240 case 0: 241 if (parent_rate == 16000000) 242 return 1; 243 break; 244 case 2: 245 if (parent_rate == 20000000) 246 return 1; 247 break; 248 case 3: 249 if (parent_rate == 24000000) 250 return 1; 251 break; 252 case 5: 253 if (parent_rate == 32000000) 254 return 1; 255 break; 256 default: 257 break; 258 } 259 260 return 0; 261 } 262 263 static int clk_utmi_sama7g5_save_context(struct clk_hw *hw) 264 { 265 struct clk_utmi *utmi = to_clk_utmi(hw); 266 267 utmi->pms.status = clk_utmi_sama7g5_is_prepared(hw); 268 269 return 0; 270 } 271 272 static void clk_utmi_sama7g5_restore_context(struct clk_hw *hw) 273 { 274 struct clk_utmi *utmi = to_clk_utmi(hw); 275 276 if (utmi->pms.status) 277 clk_utmi_sama7g5_prepare(hw); 278 } 279 280 static const struct clk_ops sama7g5_utmi_ops = { 281 .prepare = clk_utmi_sama7g5_prepare, 282 .is_prepared = clk_utmi_sama7g5_is_prepared, 283 .recalc_rate = clk_utmi_recalc_rate, 284 .save_context = clk_utmi_sama7g5_save_context, 285 .restore_context = clk_utmi_sama7g5_restore_context, 286 }; 287 288 struct clk_hw * __init 289 at91_clk_sama7g5_register_utmi(struct regmap *regmap_pmc, const char *name, 290 const char *parent_name, struct clk_hw *parent_hw) 291 { 292 return at91_clk_register_utmi_internal(regmap_pmc, NULL, name, 293 parent_name, parent_hw, &sama7g5_utmi_ops, 0); 294 } 295