Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
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  * The purpose of this clock is to generate a 480 MHz signal. A different
0018  * rate can't be configured.
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      * If mainck rate is different from 12 MHz, we have to configure the
0051      * FREQ field of the SFR_UTMICKTRIM register to generate properly
0052      * the utmi clock.
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      * Not supported on SAMA5D2 but it's not an issue since MAINCK
0069      * maximum value is 24 MHz.
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     /* UTMI clk rate is fixed. */
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 }