0001
0002
0003
0004
0005
0006 #include <linux/clk-provider.h>
0007 #include <linux/clkdev.h>
0008 #include <linux/clk/at91_pmc.h>
0009 #include <linux/of.h>
0010 #include <linux/mfd/syscon.h>
0011 #include <linux/regmap.h>
0012 #include <soc/at91/atmel-sfr.h>
0013
0014 #include "pmc.h"
0015
0016
0017
0018
0019
0020 #define UTMI_RATE 480000000
0021
0022 struct clk_utmi {
0023 struct clk_hw hw;
0024 struct regmap *regmap_pmc;
0025 struct regmap *regmap_sfr;
0026 struct at91_clk_pms pms;
0027 };
0028
0029 #define to_clk_utmi(hw) container_of(hw, struct clk_utmi, hw)
0030
0031 static inline bool clk_utmi_ready(struct regmap *regmap)
0032 {
0033 unsigned int status;
0034
0035 regmap_read(regmap, AT91_PMC_SR, &status);
0036
0037 return status & AT91_PMC_LOCKU;
0038 }
0039
0040 static int clk_utmi_prepare(struct clk_hw *hw)
0041 {
0042 struct clk_hw *hw_parent;
0043 struct clk_utmi *utmi = to_clk_utmi(hw);
0044 unsigned int uckr = AT91_PMC_UPLLEN | AT91_PMC_UPLLCOUNT |
0045 AT91_PMC_BIASEN;
0046 unsigned int utmi_ref_clk_freq;
0047 unsigned long parent_rate;
0048
0049
0050
0051
0052
0053
0054 hw_parent = clk_hw_get_parent(hw);
0055 parent_rate = clk_hw_get_rate(hw_parent);
0056
0057 switch (parent_rate) {
0058 case 12000000:
0059 utmi_ref_clk_freq = 0;
0060 break;
0061 case 16000000:
0062 utmi_ref_clk_freq = 1;
0063 break;
0064 case 24000000:
0065 utmi_ref_clk_freq = 2;
0066 break;
0067
0068
0069
0070
0071 case 48000000:
0072 utmi_ref_clk_freq = 3;
0073 break;
0074 default:
0075 pr_err("UTMICK: unsupported mainck rate\n");
0076 return -EINVAL;
0077 }
0078
0079 if (utmi->regmap_sfr) {
0080 regmap_update_bits(utmi->regmap_sfr, AT91_SFR_UTMICKTRIM,
0081 AT91_UTMICKTRIM_FREQ, utmi_ref_clk_freq);
0082 } else if (utmi_ref_clk_freq) {
0083 pr_err("UTMICK: sfr node required\n");
0084 return -EINVAL;
0085 }
0086
0087 regmap_update_bits(utmi->regmap_pmc, AT91_CKGR_UCKR, uckr, uckr);
0088
0089 while (!clk_utmi_ready(utmi->regmap_pmc))
0090 cpu_relax();
0091
0092 return 0;
0093 }
0094
0095 static int clk_utmi_is_prepared(struct clk_hw *hw)
0096 {
0097 struct clk_utmi *utmi = to_clk_utmi(hw);
0098
0099 return clk_utmi_ready(utmi->regmap_pmc);
0100 }
0101
0102 static void clk_utmi_unprepare(struct clk_hw *hw)
0103 {
0104 struct clk_utmi *utmi = to_clk_utmi(hw);
0105
0106 regmap_update_bits(utmi->regmap_pmc, AT91_CKGR_UCKR,
0107 AT91_PMC_UPLLEN, 0);
0108 }
0109
0110 static unsigned long clk_utmi_recalc_rate(struct clk_hw *hw,
0111 unsigned long parent_rate)
0112 {
0113
0114 return UTMI_RATE;
0115 }
0116
0117 static int clk_utmi_save_context(struct clk_hw *hw)
0118 {
0119 struct clk_utmi *utmi = to_clk_utmi(hw);
0120
0121 utmi->pms.status = clk_utmi_is_prepared(hw);
0122
0123 return 0;
0124 }
0125
0126 static void clk_utmi_restore_context(struct clk_hw *hw)
0127 {
0128 struct clk_utmi *utmi = to_clk_utmi(hw);
0129
0130 if (utmi->pms.status)
0131 clk_utmi_prepare(hw);
0132 }
0133
0134 static const struct clk_ops utmi_ops = {
0135 .prepare = clk_utmi_prepare,
0136 .unprepare = clk_utmi_unprepare,
0137 .is_prepared = clk_utmi_is_prepared,
0138 .recalc_rate = clk_utmi_recalc_rate,
0139 .save_context = clk_utmi_save_context,
0140 .restore_context = clk_utmi_restore_context,
0141 };
0142
0143 static struct clk_hw * __init
0144 at91_clk_register_utmi_internal(struct regmap *regmap_pmc,
0145 struct regmap *regmap_sfr,
0146 const char *name, const char *parent_name,
0147 const struct clk_ops *ops, unsigned long flags)
0148 {
0149 struct clk_utmi *utmi;
0150 struct clk_hw *hw;
0151 struct clk_init_data init;
0152 int ret;
0153
0154 utmi = kzalloc(sizeof(*utmi), GFP_KERNEL);
0155 if (!utmi)
0156 return ERR_PTR(-ENOMEM);
0157
0158 init.name = name;
0159 init.ops = ops;
0160 init.parent_names = parent_name ? &parent_name : NULL;
0161 init.num_parents = parent_name ? 1 : 0;
0162 init.flags = flags;
0163
0164 utmi->hw.init = &init;
0165 utmi->regmap_pmc = regmap_pmc;
0166 utmi->regmap_sfr = regmap_sfr;
0167
0168 hw = &utmi->hw;
0169 ret = clk_hw_register(NULL, &utmi->hw);
0170 if (ret) {
0171 kfree(utmi);
0172 hw = ERR_PTR(ret);
0173 }
0174
0175 return hw;
0176 }
0177
0178 struct clk_hw * __init
0179 at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr,
0180 const char *name, const char *parent_name)
0181 {
0182 return at91_clk_register_utmi_internal(regmap_pmc, regmap_sfr, name,
0183 parent_name, &utmi_ops, CLK_SET_RATE_GATE);
0184 }
0185
0186 static int clk_utmi_sama7g5_prepare(struct clk_hw *hw)
0187 {
0188 struct clk_utmi *utmi = to_clk_utmi(hw);
0189 struct clk_hw *hw_parent;
0190 unsigned long parent_rate;
0191 unsigned int val;
0192
0193 hw_parent = clk_hw_get_parent(hw);
0194 parent_rate = clk_hw_get_rate(hw_parent);
0195
0196 switch (parent_rate) {
0197 case 16000000:
0198 val = 0;
0199 break;
0200 case 20000000:
0201 val = 2;
0202 break;
0203 case 24000000:
0204 val = 3;
0205 break;
0206 case 32000000:
0207 val = 5;
0208 break;
0209 default:
0210 pr_err("UTMICK: unsupported main_xtal rate\n");
0211 return -EINVAL;
0212 }
0213
0214 regmap_write(utmi->regmap_pmc, AT91_PMC_XTALF, val);
0215
0216 return 0;
0217
0218 }
0219
0220 static int clk_utmi_sama7g5_is_prepared(struct clk_hw *hw)
0221 {
0222 struct clk_utmi *utmi = to_clk_utmi(hw);
0223 struct clk_hw *hw_parent;
0224 unsigned long parent_rate;
0225 unsigned int val;
0226
0227 hw_parent = clk_hw_get_parent(hw);
0228 parent_rate = clk_hw_get_rate(hw_parent);
0229
0230 regmap_read(utmi->regmap_pmc, AT91_PMC_XTALF, &val);
0231 switch (val & 0x7) {
0232 case 0:
0233 if (parent_rate == 16000000)
0234 return 1;
0235 break;
0236 case 2:
0237 if (parent_rate == 20000000)
0238 return 1;
0239 break;
0240 case 3:
0241 if (parent_rate == 24000000)
0242 return 1;
0243 break;
0244 case 5:
0245 if (parent_rate == 32000000)
0246 return 1;
0247 break;
0248 default:
0249 break;
0250 }
0251
0252 return 0;
0253 }
0254
0255 static int clk_utmi_sama7g5_save_context(struct clk_hw *hw)
0256 {
0257 struct clk_utmi *utmi = to_clk_utmi(hw);
0258
0259 utmi->pms.status = clk_utmi_sama7g5_is_prepared(hw);
0260
0261 return 0;
0262 }
0263
0264 static void clk_utmi_sama7g5_restore_context(struct clk_hw *hw)
0265 {
0266 struct clk_utmi *utmi = to_clk_utmi(hw);
0267
0268 if (utmi->pms.status)
0269 clk_utmi_sama7g5_prepare(hw);
0270 }
0271
0272 static const struct clk_ops sama7g5_utmi_ops = {
0273 .prepare = clk_utmi_sama7g5_prepare,
0274 .is_prepared = clk_utmi_sama7g5_is_prepared,
0275 .recalc_rate = clk_utmi_recalc_rate,
0276 .save_context = clk_utmi_sama7g5_save_context,
0277 .restore_context = clk_utmi_sama7g5_restore_context,
0278 };
0279
0280 struct clk_hw * __init
0281 at91_clk_sama7g5_register_utmi(struct regmap *regmap_pmc, const char *name,
0282 const char *parent_name)
0283 {
0284 return at91_clk_register_utmi_internal(regmap_pmc, NULL, name,
0285 parent_name, &sama7g5_utmi_ops, 0);
0286 }