Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0
0002  *
0003  * Clock Tree for the Texas Instruments TLV320AIC32x4
0004  *
0005  * Copyright 2019 Annaliese McDermond
0006  *
0007  * Author: Annaliese McDermond <nh6z@nh6z.net>
0008  */
0009 
0010 #include <linux/clk-provider.h>
0011 #include <linux/clkdev.h>
0012 #include <linux/regmap.h>
0013 #include <linux/device.h>
0014 
0015 #include "tlv320aic32x4.h"
0016 
0017 #define to_clk_aic32x4(_hw) container_of(_hw, struct clk_aic32x4, hw)
0018 struct clk_aic32x4 {
0019     struct clk_hw hw;
0020     struct device *dev;
0021     struct regmap *regmap;
0022     unsigned int reg;
0023 };
0024 
0025 /*
0026  * struct clk_aic32x4_pll_muldiv - Multiplier/divider settings
0027  * @p:      Divider
0028  * @r:      first multiplier
0029  * @j:      integer part of second multiplier
0030  * @d:      decimal part of second multiplier
0031  */
0032 struct clk_aic32x4_pll_muldiv {
0033     u8 p;
0034     u16 r;
0035     u8 j;
0036     u16 d;
0037 };
0038 
0039 struct aic32x4_clkdesc {
0040     const char *name;
0041     const char * const *parent_names;
0042     unsigned int num_parents;
0043     const struct clk_ops *ops;
0044     unsigned int reg;
0045 };
0046 
0047 static int clk_aic32x4_pll_prepare(struct clk_hw *hw)
0048 {
0049     struct clk_aic32x4 *pll = to_clk_aic32x4(hw);
0050 
0051     return regmap_update_bits(pll->regmap, AIC32X4_PLLPR,
0052                 AIC32X4_PLLEN, AIC32X4_PLLEN);
0053 }
0054 
0055 static void clk_aic32x4_pll_unprepare(struct clk_hw *hw)
0056 {
0057     struct clk_aic32x4 *pll = to_clk_aic32x4(hw);
0058 
0059     regmap_update_bits(pll->regmap, AIC32X4_PLLPR,
0060                 AIC32X4_PLLEN, 0);
0061 }
0062 
0063 static int clk_aic32x4_pll_is_prepared(struct clk_hw *hw)
0064 {
0065     struct clk_aic32x4 *pll = to_clk_aic32x4(hw);
0066 
0067     unsigned int val;
0068     int ret;
0069 
0070     ret = regmap_read(pll->regmap, AIC32X4_PLLPR, &val);
0071     if (ret < 0)
0072         return ret;
0073 
0074     return !!(val & AIC32X4_PLLEN);
0075 }
0076 
0077 static int clk_aic32x4_pll_get_muldiv(struct clk_aic32x4 *pll,
0078             struct clk_aic32x4_pll_muldiv *settings)
0079 {
0080     /*  Change to use regmap_bulk_read? */
0081     unsigned int val;
0082     int ret;
0083 
0084     ret = regmap_read(pll->regmap, AIC32X4_PLLPR, &val);
0085     if (ret < 0)
0086         return ret;
0087     settings->r = val & AIC32X4_PLL_R_MASK;
0088     settings->p = (val & AIC32X4_PLL_P_MASK) >> AIC32X4_PLL_P_SHIFT;
0089 
0090     ret = regmap_read(pll->regmap, AIC32X4_PLLJ, &val);
0091     if (ret < 0)
0092         return ret;
0093     settings->j = val;
0094 
0095     ret = regmap_read(pll->regmap, AIC32X4_PLLDMSB, &val);
0096     if (ret < 0)
0097         return ret;
0098     settings->d = val << 8;
0099 
0100     ret = regmap_read(pll->regmap, AIC32X4_PLLDLSB,  &val);
0101     if (ret < 0)
0102         return ret;
0103     settings->d |= val;
0104 
0105     return 0;
0106 }
0107 
0108 static int clk_aic32x4_pll_set_muldiv(struct clk_aic32x4 *pll,
0109             struct clk_aic32x4_pll_muldiv *settings)
0110 {
0111     int ret;
0112     /*  Change to use regmap_bulk_write for some if not all? */
0113 
0114     ret = regmap_update_bits(pll->regmap, AIC32X4_PLLPR,
0115                 AIC32X4_PLL_R_MASK, settings->r);
0116     if (ret < 0)
0117         return ret;
0118 
0119     ret = regmap_update_bits(pll->regmap, AIC32X4_PLLPR,
0120                 AIC32X4_PLL_P_MASK,
0121                 settings->p << AIC32X4_PLL_P_SHIFT);
0122     if (ret < 0)
0123         return ret;
0124 
0125     ret = regmap_write(pll->regmap, AIC32X4_PLLJ, settings->j);
0126     if (ret < 0)
0127         return ret;
0128 
0129     ret = regmap_write(pll->regmap, AIC32X4_PLLDMSB, (settings->d >> 8));
0130     if (ret < 0)
0131         return ret;
0132     ret = regmap_write(pll->regmap, AIC32X4_PLLDLSB, (settings->d & 0xff));
0133     if (ret < 0)
0134         return ret;
0135 
0136     return 0;
0137 }
0138 
0139 static unsigned long clk_aic32x4_pll_calc_rate(
0140             struct clk_aic32x4_pll_muldiv *settings,
0141             unsigned long parent_rate)
0142 {
0143     u64 rate;
0144     /*
0145      * We scale j by 10000 to account for the decimal part of P and divide
0146      * it back out later.
0147      */
0148     rate = (u64) parent_rate * settings->r *
0149                 ((settings->j * 10000) + settings->d);
0150 
0151     return (unsigned long) DIV_ROUND_UP_ULL(rate, settings->p * 10000);
0152 }
0153 
0154 static int clk_aic32x4_pll_calc_muldiv(struct clk_aic32x4_pll_muldiv *settings,
0155             unsigned long rate, unsigned long parent_rate)
0156 {
0157     u64 multiplier;
0158 
0159     settings->p = parent_rate / AIC32X4_MAX_PLL_CLKIN + 1;
0160     if (settings->p > 8)
0161         return -1;
0162 
0163     /*
0164      * We scale this figure by 10000 so that we can get the decimal part
0165      * of the multiplier.   This is because we can't do floating point
0166      * math in the kernel.
0167      */
0168     multiplier = (u64) rate * settings->p * 10000;
0169     do_div(multiplier, parent_rate);
0170 
0171     /*
0172      * J can't be over 64, so R can scale this.
0173      * R can't be greater than 4.
0174      */
0175     settings->r = ((u32) multiplier / 640000) + 1;
0176     if (settings->r > 4)
0177         return -1;
0178     do_div(multiplier, settings->r);
0179 
0180     /*
0181      * J can't be < 1.
0182      */
0183     if (multiplier < 10000)
0184         return -1;
0185 
0186     /* Figure out the integer part, J, and the fractional part, D. */
0187     settings->j = (u32) multiplier / 10000;
0188     settings->d = (u32) multiplier % 10000;
0189 
0190     return 0;
0191 }
0192 
0193 static unsigned long clk_aic32x4_pll_recalc_rate(struct clk_hw *hw,
0194             unsigned long parent_rate)
0195 {
0196     struct clk_aic32x4 *pll = to_clk_aic32x4(hw);
0197     struct clk_aic32x4_pll_muldiv settings;
0198     int ret;
0199 
0200     ret =  clk_aic32x4_pll_get_muldiv(pll, &settings);
0201     if (ret < 0)
0202         return 0;
0203 
0204     return clk_aic32x4_pll_calc_rate(&settings, parent_rate);
0205 }
0206 
0207 static long clk_aic32x4_pll_round_rate(struct clk_hw *hw,
0208             unsigned long rate,
0209             unsigned long *parent_rate)
0210 {
0211     struct clk_aic32x4_pll_muldiv settings;
0212     int ret;
0213 
0214     ret = clk_aic32x4_pll_calc_muldiv(&settings, rate, *parent_rate);
0215     if (ret < 0)
0216         return 0;
0217 
0218     return clk_aic32x4_pll_calc_rate(&settings, *parent_rate);
0219 }
0220 
0221 static int clk_aic32x4_pll_set_rate(struct clk_hw *hw,
0222             unsigned long rate,
0223             unsigned long parent_rate)
0224 {
0225     struct clk_aic32x4 *pll = to_clk_aic32x4(hw);
0226     struct clk_aic32x4_pll_muldiv settings;
0227     int ret;
0228 
0229     ret = clk_aic32x4_pll_calc_muldiv(&settings, rate, parent_rate);
0230     if (ret < 0)
0231         return -EINVAL;
0232 
0233     ret = clk_aic32x4_pll_set_muldiv(pll, &settings);
0234     if (ret)
0235         return ret;
0236 
0237     /* 10ms is the delay to wait before the clocks are stable */
0238     msleep(10);
0239 
0240     return 0;
0241 }
0242 
0243 static int clk_aic32x4_pll_set_parent(struct clk_hw *hw, u8 index)
0244 {
0245     struct clk_aic32x4 *pll = to_clk_aic32x4(hw);
0246 
0247     return regmap_update_bits(pll->regmap,
0248                 AIC32X4_CLKMUX,
0249                 AIC32X4_PLL_CLKIN_MASK,
0250                 index << AIC32X4_PLL_CLKIN_SHIFT);
0251 }
0252 
0253 static u8 clk_aic32x4_pll_get_parent(struct clk_hw *hw)
0254 {
0255     struct clk_aic32x4 *pll = to_clk_aic32x4(hw);
0256     unsigned int val;
0257 
0258     regmap_read(pll->regmap, AIC32X4_PLLPR, &val);
0259 
0260     return (val & AIC32X4_PLL_CLKIN_MASK) >> AIC32X4_PLL_CLKIN_SHIFT;
0261 }
0262 
0263 
0264 static const struct clk_ops aic32x4_pll_ops = {
0265     .prepare = clk_aic32x4_pll_prepare,
0266     .unprepare = clk_aic32x4_pll_unprepare,
0267     .is_prepared = clk_aic32x4_pll_is_prepared,
0268     .recalc_rate = clk_aic32x4_pll_recalc_rate,
0269     .round_rate = clk_aic32x4_pll_round_rate,
0270     .set_rate = clk_aic32x4_pll_set_rate,
0271     .set_parent = clk_aic32x4_pll_set_parent,
0272     .get_parent = clk_aic32x4_pll_get_parent,
0273 };
0274 
0275 static int clk_aic32x4_codec_clkin_set_parent(struct clk_hw *hw, u8 index)
0276 {
0277     struct clk_aic32x4 *mux = to_clk_aic32x4(hw);
0278 
0279     return regmap_update_bits(mux->regmap,
0280         AIC32X4_CLKMUX,
0281         AIC32X4_CODEC_CLKIN_MASK, index << AIC32X4_CODEC_CLKIN_SHIFT);
0282 }
0283 
0284 static u8 clk_aic32x4_codec_clkin_get_parent(struct clk_hw *hw)
0285 {
0286     struct clk_aic32x4 *mux = to_clk_aic32x4(hw);
0287     unsigned int val;
0288 
0289     regmap_read(mux->regmap, AIC32X4_CLKMUX, &val);
0290 
0291     return (val & AIC32X4_CODEC_CLKIN_MASK) >> AIC32X4_CODEC_CLKIN_SHIFT;
0292 }
0293 
0294 static const struct clk_ops aic32x4_codec_clkin_ops = {
0295     .set_parent = clk_aic32x4_codec_clkin_set_parent,
0296     .get_parent = clk_aic32x4_codec_clkin_get_parent,
0297 };
0298 
0299 static int clk_aic32x4_div_prepare(struct clk_hw *hw)
0300 {
0301     struct clk_aic32x4 *div = to_clk_aic32x4(hw);
0302 
0303     return regmap_update_bits(div->regmap, div->reg,
0304                 AIC32X4_DIVEN, AIC32X4_DIVEN);
0305 }
0306 
0307 static void clk_aic32x4_div_unprepare(struct clk_hw *hw)
0308 {
0309     struct clk_aic32x4 *div = to_clk_aic32x4(hw);
0310 
0311     regmap_update_bits(div->regmap, div->reg,
0312             AIC32X4_DIVEN, 0);
0313 }
0314 
0315 static int clk_aic32x4_div_set_rate(struct clk_hw *hw, unsigned long rate,
0316                 unsigned long parent_rate)
0317 {
0318     struct clk_aic32x4 *div = to_clk_aic32x4(hw);
0319     u8 divisor;
0320 
0321     divisor = DIV_ROUND_UP(parent_rate, rate);
0322     if (divisor > 128)
0323         return -EINVAL;
0324 
0325     return regmap_update_bits(div->regmap, div->reg,
0326                 AIC32X4_DIV_MASK, divisor);
0327 }
0328 
0329 static long clk_aic32x4_div_round_rate(struct clk_hw *hw, unsigned long rate,
0330                 unsigned long *parent_rate)
0331 {
0332     unsigned long divisor;
0333 
0334     divisor = DIV_ROUND_UP(*parent_rate, rate);
0335     if (divisor > 128)
0336         return -EINVAL;
0337 
0338     return DIV_ROUND_UP(*parent_rate, divisor);
0339 }
0340 
0341 static unsigned long clk_aic32x4_div_recalc_rate(struct clk_hw *hw,
0342                         unsigned long parent_rate)
0343 {
0344     struct clk_aic32x4 *div = to_clk_aic32x4(hw);
0345 
0346     unsigned int val;
0347 
0348     regmap_read(div->regmap, div->reg, &val);
0349 
0350     return DIV_ROUND_UP(parent_rate, val & AIC32X4_DIV_MASK);
0351 }
0352 
0353 static const struct clk_ops aic32x4_div_ops = {
0354     .prepare = clk_aic32x4_div_prepare,
0355     .unprepare = clk_aic32x4_div_unprepare,
0356     .set_rate = clk_aic32x4_div_set_rate,
0357     .round_rate = clk_aic32x4_div_round_rate,
0358     .recalc_rate = clk_aic32x4_div_recalc_rate,
0359 };
0360 
0361 static int clk_aic32x4_bdiv_set_parent(struct clk_hw *hw, u8 index)
0362 {
0363     struct clk_aic32x4 *mux = to_clk_aic32x4(hw);
0364 
0365     return regmap_update_bits(mux->regmap, AIC32X4_IFACE3,
0366                 AIC32X4_BDIVCLK_MASK, index);
0367 }
0368 
0369 static u8 clk_aic32x4_bdiv_get_parent(struct clk_hw *hw)
0370 {
0371     struct clk_aic32x4 *mux = to_clk_aic32x4(hw);
0372     unsigned int val;
0373 
0374     regmap_read(mux->regmap, AIC32X4_IFACE3, &val);
0375 
0376     return val & AIC32X4_BDIVCLK_MASK;
0377 }
0378 
0379 static const struct clk_ops aic32x4_bdiv_ops = {
0380     .prepare = clk_aic32x4_div_prepare,
0381     .unprepare = clk_aic32x4_div_unprepare,
0382     .set_parent = clk_aic32x4_bdiv_set_parent,
0383     .get_parent = clk_aic32x4_bdiv_get_parent,
0384     .set_rate = clk_aic32x4_div_set_rate,
0385     .round_rate = clk_aic32x4_div_round_rate,
0386     .recalc_rate = clk_aic32x4_div_recalc_rate,
0387 };
0388 
0389 static struct aic32x4_clkdesc aic32x4_clkdesc_array[] = {
0390     {
0391         .name = "pll",
0392         .parent_names =
0393             (const char* []) { "mclk", "bclk", "gpio", "din" },
0394         .num_parents = 4,
0395         .ops = &aic32x4_pll_ops,
0396         .reg = 0,
0397     },
0398     {
0399         .name = "codec_clkin",
0400         .parent_names =
0401             (const char *[]) { "mclk", "bclk", "gpio", "pll" },
0402         .num_parents = 4,
0403         .ops = &aic32x4_codec_clkin_ops,
0404         .reg = 0,
0405     },
0406     {
0407         .name = "ndac",
0408         .parent_names = (const char * []) { "codec_clkin" },
0409         .num_parents = 1,
0410         .ops = &aic32x4_div_ops,
0411         .reg = AIC32X4_NDAC,
0412     },
0413     {
0414         .name = "mdac",
0415         .parent_names = (const char * []) { "ndac" },
0416         .num_parents = 1,
0417         .ops = &aic32x4_div_ops,
0418         .reg = AIC32X4_MDAC,
0419     },
0420     {
0421         .name = "nadc",
0422         .parent_names = (const char * []) { "codec_clkin" },
0423         .num_parents = 1,
0424         .ops = &aic32x4_div_ops,
0425         .reg = AIC32X4_NADC,
0426     },
0427     {
0428         .name = "madc",
0429         .parent_names = (const char * []) { "nadc" },
0430         .num_parents = 1,
0431         .ops = &aic32x4_div_ops,
0432         .reg = AIC32X4_MADC,
0433     },
0434     {
0435         .name = "bdiv",
0436         .parent_names =
0437             (const char *[]) { "ndac", "mdac", "nadc", "madc" },
0438         .num_parents = 4,
0439         .ops = &aic32x4_bdiv_ops,
0440         .reg = AIC32X4_BCLKN,
0441     },
0442 };
0443 
0444 static struct clk *aic32x4_register_clk(struct device *dev,
0445             struct aic32x4_clkdesc *desc)
0446 {
0447     struct clk_init_data init;
0448     struct clk_aic32x4 *priv;
0449     const char *devname = dev_name(dev);
0450 
0451     init.ops = desc->ops;
0452     init.name = desc->name;
0453     init.parent_names = desc->parent_names;
0454     init.num_parents = desc->num_parents;
0455     init.flags = 0;
0456 
0457     priv = devm_kzalloc(dev, sizeof(struct clk_aic32x4), GFP_KERNEL);
0458     if (priv == NULL)
0459         return (struct clk *) -ENOMEM;
0460 
0461     priv->dev = dev;
0462     priv->hw.init = &init;
0463     priv->regmap = dev_get_regmap(dev, NULL);
0464     priv->reg = desc->reg;
0465 
0466     clk_hw_register_clkdev(&priv->hw, desc->name, devname);
0467     return devm_clk_register(dev, &priv->hw);
0468 }
0469 
0470 int aic32x4_register_clocks(struct device *dev, const char *mclk_name)
0471 {
0472     int i;
0473 
0474     /*
0475      * These lines are here to preserve the current functionality of
0476      * the driver with regard to the DT.  These should eventually be set
0477      * by DT nodes so that the connections can be set up in configuration
0478      * rather than code.
0479      */
0480     aic32x4_clkdesc_array[0].parent_names =
0481             (const char* []) { mclk_name, "bclk", "gpio", "din" };
0482     aic32x4_clkdesc_array[1].parent_names =
0483             (const char *[]) { mclk_name, "bclk", "gpio", "pll" };
0484 
0485     for (i = 0; i < ARRAY_SIZE(aic32x4_clkdesc_array); ++i)
0486         aic32x4_register_clk(dev, &aic32x4_clkdesc_array[i]);
0487 
0488     return 0;
0489 }
0490 EXPORT_SYMBOL_GPL(aic32x4_register_clocks);