Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Clock driver for TPS68470 PMIC
0004  *
0005  * Copyright (c) 2021 Red Hat Inc.
0006  * Copyright (C) 2018 Intel Corporation
0007  *
0008  * Authors:
0009  *  Hans de Goede <hdegoede@redhat.com>
0010  *  Zaikuo Wang <zaikuo.wang@intel.com>
0011  *  Tianshu Qiu <tian.shu.qiu@intel.com>
0012  *  Jian Xu Zheng <jian.xu.zheng@intel.com>
0013  *  Yuning Pu <yuning.pu@intel.com>
0014  *  Antti Laakso <antti.laakso@intel.com>
0015  */
0016 
0017 #include <linux/clk-provider.h>
0018 #include <linux/clkdev.h>
0019 #include <linux/kernel.h>
0020 #include <linux/mfd/tps68470.h>
0021 #include <linux/module.h>
0022 #include <linux/platform_device.h>
0023 #include <linux/platform_data/tps68470.h>
0024 #include <linux/regmap.h>
0025 
0026 #define TPS68470_CLK_NAME "tps68470-clk"
0027 
0028 #define to_tps68470_clkdata(clkd) \
0029     container_of(clkd, struct tps68470_clkdata, clkout_hw)
0030 
0031 static struct tps68470_clkout_freqs {
0032     unsigned long freq;
0033     unsigned int xtaldiv;
0034     unsigned int plldiv;
0035     unsigned int postdiv;
0036     unsigned int buckdiv;
0037     unsigned int boostdiv;
0038 } clk_freqs[] = {
0039 /*
0040  *  The PLL is used to multiply the crystal oscillator
0041  *  frequency range of 3 MHz to 27 MHz by a programmable
0042  *  factor of F = (M/N)*(1/P) such that the output
0043  *  available at the HCLK_A or HCLK_B pins are in the range
0044  *  of 4 MHz to 64 MHz in increments of 0.1 MHz.
0045  *
0046  * hclk_# = osc_in * (((plldiv*2)+320) / (xtaldiv+30)) * (1 / 2^postdiv)
0047  *
0048  * PLL_REF_CLK should be as close as possible to 100kHz
0049  * PLL_REF_CLK = input clk / XTALDIV[7:0] + 30)
0050  *
0051  * PLL_VCO_CLK = (PLL_REF_CLK * (plldiv*2 + 320))
0052  *
0053  * BOOST should be as close as possible to 2Mhz
0054  * BOOST = PLL_VCO_CLK / (BOOSTDIV[4:0] + 16) *
0055  *
0056  * BUCK should be as close as possible to 5.2Mhz
0057  * BUCK = PLL_VCO_CLK / (BUCKDIV[3:0] + 5)
0058  *
0059  * osc_in   xtaldiv  plldiv   postdiv   hclk_#
0060  * 20Mhz    170      32       1         19.2Mhz
0061  * 20Mhz    170      40       1         20Mhz
0062  * 20Mhz    170      80       1         24Mhz
0063  */
0064     { 19200000, 170, 32, 1, 2, 3 },
0065     { 20000000, 170, 40, 1, 3, 4 },
0066     { 24000000, 170, 80, 1, 4, 8 },
0067 };
0068 
0069 struct tps68470_clkdata {
0070     struct clk_hw clkout_hw;
0071     struct regmap *regmap;
0072     unsigned long rate;
0073 };
0074 
0075 static int tps68470_clk_is_prepared(struct clk_hw *hw)
0076 {
0077     struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw);
0078     int val;
0079 
0080     if (regmap_read(clkdata->regmap, TPS68470_REG_PLLCTL, &val))
0081         return 0;
0082 
0083     return val & TPS68470_PLL_EN_MASK;
0084 }
0085 
0086 static int tps68470_clk_prepare(struct clk_hw *hw)
0087 {
0088     struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw);
0089 
0090     regmap_write(clkdata->regmap, TPS68470_REG_CLKCFG1,
0091                (TPS68470_PLL_OUTPUT_ENABLE << TPS68470_OUTPUT_A_SHIFT) |
0092                (TPS68470_PLL_OUTPUT_ENABLE << TPS68470_OUTPUT_B_SHIFT));
0093 
0094     regmap_update_bits(clkdata->regmap, TPS68470_REG_PLLCTL,
0095                TPS68470_PLL_EN_MASK, TPS68470_PLL_EN_MASK);
0096 
0097     /*
0098      * The PLLCTL reg lock bit is set by the PMIC after approx. 4ms and
0099      * does not indicate a true lock, so just wait 4 ms.
0100      */
0101     usleep_range(4000, 5000);
0102 
0103     return 0;
0104 }
0105 
0106 static void tps68470_clk_unprepare(struct clk_hw *hw)
0107 {
0108     struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw);
0109 
0110     /* Disable clock first ... */
0111     regmap_update_bits(clkdata->regmap, TPS68470_REG_PLLCTL, TPS68470_PLL_EN_MASK, 0);
0112 
0113     /* ... and then tri-state the clock outputs. */
0114     regmap_write(clkdata->regmap, TPS68470_REG_CLKCFG1, 0);
0115 }
0116 
0117 static unsigned long tps68470_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
0118 {
0119     struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw);
0120 
0121     return clkdata->rate;
0122 }
0123 
0124 /*
0125  * This returns the index of the clk_freqs[] cfg with the closest rate for
0126  * use in tps68470_clk_round_rate(). tps68470_clk_set_rate() checks that
0127  * the rate of the returned cfg is an exact match.
0128  */
0129 static unsigned int tps68470_clk_cfg_lookup(unsigned long rate)
0130 {
0131     long diff, best_diff = LONG_MAX;
0132     unsigned int i, best_idx = 0;
0133 
0134     for (i = 0; i < ARRAY_SIZE(clk_freqs); i++) {
0135         diff = clk_freqs[i].freq - rate;
0136         if (diff == 0)
0137             return i;
0138 
0139         diff = abs(diff);
0140         if (diff < best_diff) {
0141             best_diff = diff;
0142             best_idx = i;
0143         }
0144     }
0145 
0146     return best_idx;
0147 }
0148 
0149 static long tps68470_clk_round_rate(struct clk_hw *hw, unsigned long rate,
0150                     unsigned long *parent_rate)
0151 {
0152     unsigned int idx = tps68470_clk_cfg_lookup(rate);
0153 
0154     return clk_freqs[idx].freq;
0155 }
0156 
0157 static int tps68470_clk_set_rate(struct clk_hw *hw, unsigned long rate,
0158                  unsigned long parent_rate)
0159 {
0160     struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw);
0161     unsigned int idx = tps68470_clk_cfg_lookup(rate);
0162 
0163     if (rate != clk_freqs[idx].freq)
0164         return -EINVAL;
0165 
0166     regmap_write(clkdata->regmap, TPS68470_REG_BOOSTDIV, clk_freqs[idx].boostdiv);
0167     regmap_write(clkdata->regmap, TPS68470_REG_BUCKDIV, clk_freqs[idx].buckdiv);
0168     regmap_write(clkdata->regmap, TPS68470_REG_PLLSWR, TPS68470_PLLSWR_DEFAULT);
0169     regmap_write(clkdata->regmap, TPS68470_REG_XTALDIV, clk_freqs[idx].xtaldiv);
0170     regmap_write(clkdata->regmap, TPS68470_REG_PLLDIV, clk_freqs[idx].plldiv);
0171     regmap_write(clkdata->regmap, TPS68470_REG_POSTDIV, clk_freqs[idx].postdiv);
0172     regmap_write(clkdata->regmap, TPS68470_REG_POSTDIV2, clk_freqs[idx].postdiv);
0173     regmap_write(clkdata->regmap, TPS68470_REG_CLKCFG2, TPS68470_CLKCFG2_DRV_STR_2MA);
0174 
0175     regmap_write(clkdata->regmap, TPS68470_REG_PLLCTL,
0176              TPS68470_OSC_EXT_CAP_DEFAULT << TPS68470_OSC_EXT_CAP_SHIFT |
0177              TPS68470_CLK_SRC_XTAL << TPS68470_CLK_SRC_SHIFT);
0178 
0179     clkdata->rate = rate;
0180 
0181     return 0;
0182 }
0183 
0184 static const struct clk_ops tps68470_clk_ops = {
0185     .is_prepared = tps68470_clk_is_prepared,
0186     .prepare = tps68470_clk_prepare,
0187     .unprepare = tps68470_clk_unprepare,
0188     .recalc_rate = tps68470_clk_recalc_rate,
0189     .round_rate = tps68470_clk_round_rate,
0190     .set_rate = tps68470_clk_set_rate,
0191 };
0192 
0193 static int tps68470_clk_probe(struct platform_device *pdev)
0194 {
0195     struct tps68470_clk_platform_data *pdata = pdev->dev.platform_data;
0196     struct clk_init_data tps68470_clk_initdata = {
0197         .name = TPS68470_CLK_NAME,
0198         .ops = &tps68470_clk_ops,
0199         /* Changing the dividers when the PLL is on is not allowed */
0200         .flags = CLK_SET_RATE_GATE,
0201     };
0202     struct tps68470_clkdata *tps68470_clkdata;
0203     int ret;
0204 
0205     tps68470_clkdata = devm_kzalloc(&pdev->dev, sizeof(*tps68470_clkdata),
0206                     GFP_KERNEL);
0207     if (!tps68470_clkdata)
0208         return -ENOMEM;
0209 
0210     tps68470_clkdata->regmap = dev_get_drvdata(pdev->dev.parent);
0211     tps68470_clkdata->clkout_hw.init = &tps68470_clk_initdata;
0212 
0213     /* Set initial rate */
0214     tps68470_clk_set_rate(&tps68470_clkdata->clkout_hw, clk_freqs[0].freq, 0);
0215 
0216     ret = devm_clk_hw_register(&pdev->dev, &tps68470_clkdata->clkout_hw);
0217     if (ret)
0218         return ret;
0219 
0220     ret = devm_clk_hw_register_clkdev(&pdev->dev, &tps68470_clkdata->clkout_hw,
0221                       TPS68470_CLK_NAME, NULL);
0222     if (ret)
0223         return ret;
0224 
0225     if (pdata) {
0226         ret = devm_clk_hw_register_clkdev(&pdev->dev,
0227                           &tps68470_clkdata->clkout_hw,
0228                           pdata->consumer_con_id,
0229                           pdata->consumer_dev_name);
0230     }
0231 
0232     return ret;
0233 }
0234 
0235 static struct platform_driver tps68470_clk_driver = {
0236     .driver = {
0237         .name = TPS68470_CLK_NAME,
0238     },
0239     .probe = tps68470_clk_probe,
0240 };
0241 
0242 /*
0243  * The ACPI tps68470 probe-ordering depends on the clk/gpio/regulator drivers
0244  * registering before the drivers for the camera-sensors which use them bind.
0245  * subsys_initcall() ensures this when the drivers are builtin.
0246  */
0247 static int __init tps68470_clk_init(void)
0248 {
0249     return platform_driver_register(&tps68470_clk_driver);
0250 }
0251 subsys_initcall(tps68470_clk_init);
0252 
0253 static void __exit tps68470_clk_exit(void)
0254 {
0255     platform_driver_unregister(&tps68470_clk_driver);
0256 }
0257 module_exit(tps68470_clk_exit);
0258 
0259 MODULE_ALIAS("platform:tps68470-clk");
0260 MODULE_DESCRIPTION("clock driver for TPS68470 pmic");
0261 MODULE_LICENSE("GPL");