1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Clock driver for TPS68470 PMIC 4 * 5 * Copyright (c) 2021 Red Hat Inc. 6 * Copyright (C) 2018 Intel Corporation 7 * 8 * Authors: 9 * Hans de Goede <hdegoede@redhat.com> 10 * Zaikuo Wang <zaikuo.wang@intel.com> 11 * Tianshu Qiu <tian.shu.qiu@intel.com> 12 * Jian Xu Zheng <jian.xu.zheng@intel.com> 13 * Yuning Pu <yuning.pu@intel.com> 14 * Antti Laakso <antti.laakso@intel.com> 15 */ 16 17 #include <linux/clk-provider.h> 18 #include <linux/clkdev.h> 19 #include <linux/kernel.h> 20 #include <linux/mfd/tps68470.h> 21 #include <linux/module.h> 22 #include <linux/platform_device.h> 23 #include <linux/platform_data/tps68470.h> 24 #include <linux/regmap.h> 25 26 #define TPS68470_CLK_NAME "tps68470-clk" 27 28 #define to_tps68470_clkdata(clkd) \ 29 container_of(clkd, struct tps68470_clkdata, clkout_hw) 30 31 static struct tps68470_clkout_freqs { 32 unsigned long freq; 33 unsigned int xtaldiv; 34 unsigned int plldiv; 35 unsigned int postdiv; 36 unsigned int buckdiv; 37 unsigned int boostdiv; 38 } clk_freqs[] = { 39 /* 40 * The PLL is used to multiply the crystal oscillator 41 * frequency range of 3 MHz to 27 MHz by a programmable 42 * factor of F = (M/N)*(1/P) such that the output 43 * available at the HCLK_A or HCLK_B pins are in the range 44 * of 4 MHz to 64 MHz in increments of 0.1 MHz. 45 * 46 * hclk_# = osc_in * (((plldiv*2)+320) / (xtaldiv+30)) * (1 / 2^postdiv) 47 * 48 * PLL_REF_CLK should be as close as possible to 100kHz 49 * PLL_REF_CLK = input clk / XTALDIV[7:0] + 30) 50 * 51 * PLL_VCO_CLK = (PLL_REF_CLK * (plldiv*2 + 320)) 52 * 53 * BOOST should be as close as possible to 2Mhz 54 * BOOST = PLL_VCO_CLK / (BOOSTDIV[4:0] + 16) * 55 * 56 * BUCK should be as close as possible to 5.2Mhz 57 * BUCK = PLL_VCO_CLK / (BUCKDIV[3:0] + 5) 58 * 59 * osc_in xtaldiv plldiv postdiv hclk_# 60 * 20Mhz 170 32 1 19.2Mhz 61 * 20Mhz 170 40 1 20Mhz 62 * 20Mhz 170 80 1 24Mhz 63 */ 64 { 19200000, 170, 32, 1, 2, 3 }, 65 { 20000000, 170, 40, 1, 3, 4 }, 66 { 24000000, 170, 80, 1, 4, 8 }, 67 }; 68 69 struct tps68470_clkdata { 70 struct clk_hw clkout_hw; 71 struct regmap *regmap; 72 unsigned long rate; 73 }; 74 75 static int tps68470_clk_is_prepared(struct clk_hw *hw) 76 { 77 struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw); 78 int val; 79 80 if (regmap_read(clkdata->regmap, TPS68470_REG_PLLCTL, &val)) 81 return 0; 82 83 return val & TPS68470_PLL_EN_MASK; 84 } 85 86 static int tps68470_clk_prepare(struct clk_hw *hw) 87 { 88 struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw); 89 90 regmap_write(clkdata->regmap, TPS68470_REG_CLKCFG1, 91 (TPS68470_PLL_OUTPUT_ENABLE << TPS68470_OUTPUT_A_SHIFT) | 92 (TPS68470_PLL_OUTPUT_ENABLE << TPS68470_OUTPUT_B_SHIFT)); 93 94 regmap_update_bits(clkdata->regmap, TPS68470_REG_PLLCTL, 95 TPS68470_PLL_EN_MASK, TPS68470_PLL_EN_MASK); 96 97 /* 98 * The PLLCTL reg lock bit is set by the PMIC after approx. 4ms and 99 * does not indicate a true lock, so just wait 4 ms. 100 */ 101 usleep_range(4000, 5000); 102 103 return 0; 104 } 105 106 static void tps68470_clk_unprepare(struct clk_hw *hw) 107 { 108 struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw); 109 110 /* Disable clock first ... */ 111 regmap_update_bits(clkdata->regmap, TPS68470_REG_PLLCTL, TPS68470_PLL_EN_MASK, 0); 112 113 /* ... and then tri-state the clock outputs. */ 114 regmap_write(clkdata->regmap, TPS68470_REG_CLKCFG1, 0); 115 } 116 117 static unsigned long tps68470_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) 118 { 119 struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw); 120 121 return clkdata->rate; 122 } 123 124 /* 125 * This returns the index of the clk_freqs[] cfg with the closest rate for 126 * use in tps68470_clk_round_rate(). tps68470_clk_set_rate() checks that 127 * the rate of the returned cfg is an exact match. 128 */ 129 static unsigned int tps68470_clk_cfg_lookup(unsigned long rate) 130 { 131 long diff, best_diff = LONG_MAX; 132 unsigned int i, best_idx = 0; 133 134 for (i = 0; i < ARRAY_SIZE(clk_freqs); i++) { 135 diff = clk_freqs[i].freq - rate; 136 if (diff == 0) 137 return i; 138 139 diff = abs(diff); 140 if (diff < best_diff) { 141 best_diff = diff; 142 best_idx = i; 143 } 144 } 145 146 return best_idx; 147 } 148 149 static long tps68470_clk_round_rate(struct clk_hw *hw, unsigned long rate, 150 unsigned long *parent_rate) 151 { 152 unsigned int idx = tps68470_clk_cfg_lookup(rate); 153 154 return clk_freqs[idx].freq; 155 } 156 157 static int tps68470_clk_set_rate(struct clk_hw *hw, unsigned long rate, 158 unsigned long parent_rate) 159 { 160 struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw); 161 unsigned int idx = tps68470_clk_cfg_lookup(rate); 162 163 if (rate != clk_freqs[idx].freq) 164 return -EINVAL; 165 166 regmap_write(clkdata->regmap, TPS68470_REG_BOOSTDIV, clk_freqs[idx].boostdiv); 167 regmap_write(clkdata->regmap, TPS68470_REG_BUCKDIV, clk_freqs[idx].buckdiv); 168 regmap_write(clkdata->regmap, TPS68470_REG_PLLSWR, TPS68470_PLLSWR_DEFAULT); 169 regmap_write(clkdata->regmap, TPS68470_REG_XTALDIV, clk_freqs[idx].xtaldiv); 170 regmap_write(clkdata->regmap, TPS68470_REG_PLLDIV, clk_freqs[idx].plldiv); 171 regmap_write(clkdata->regmap, TPS68470_REG_POSTDIV, clk_freqs[idx].postdiv); 172 regmap_write(clkdata->regmap, TPS68470_REG_POSTDIV2, clk_freqs[idx].postdiv); 173 regmap_write(clkdata->regmap, TPS68470_REG_CLKCFG2, TPS68470_CLKCFG2_DRV_STR_2MA); 174 175 regmap_write(clkdata->regmap, TPS68470_REG_PLLCTL, 176 TPS68470_OSC_EXT_CAP_DEFAULT << TPS68470_OSC_EXT_CAP_SHIFT | 177 TPS68470_CLK_SRC_XTAL << TPS68470_CLK_SRC_SHIFT); 178 179 clkdata->rate = rate; 180 181 return 0; 182 } 183 184 static const struct clk_ops tps68470_clk_ops = { 185 .is_prepared = tps68470_clk_is_prepared, 186 .prepare = tps68470_clk_prepare, 187 .unprepare = tps68470_clk_unprepare, 188 .recalc_rate = tps68470_clk_recalc_rate, 189 .round_rate = tps68470_clk_round_rate, 190 .set_rate = tps68470_clk_set_rate, 191 }; 192 193 static int tps68470_clk_probe(struct platform_device *pdev) 194 { 195 struct tps68470_clk_platform_data *pdata = pdev->dev.platform_data; 196 struct clk_init_data tps68470_clk_initdata = { 197 .name = TPS68470_CLK_NAME, 198 .ops = &tps68470_clk_ops, 199 /* Changing the dividers when the PLL is on is not allowed */ 200 .flags = CLK_SET_RATE_GATE, 201 }; 202 struct tps68470_clkdata *tps68470_clkdata; 203 struct tps68470_clk_consumer *consumer; 204 int ret; 205 int i; 206 207 tps68470_clkdata = devm_kzalloc(&pdev->dev, sizeof(*tps68470_clkdata), 208 GFP_KERNEL); 209 if (!tps68470_clkdata) 210 return -ENOMEM; 211 212 tps68470_clkdata->regmap = dev_get_drvdata(pdev->dev.parent); 213 tps68470_clkdata->clkout_hw.init = &tps68470_clk_initdata; 214 215 /* Set initial rate */ 216 tps68470_clk_set_rate(&tps68470_clkdata->clkout_hw, clk_freqs[0].freq, 0); 217 218 ret = devm_clk_hw_register(&pdev->dev, &tps68470_clkdata->clkout_hw); 219 if (ret) 220 return ret; 221 222 ret = devm_clk_hw_register_clkdev(&pdev->dev, &tps68470_clkdata->clkout_hw, 223 TPS68470_CLK_NAME, NULL); 224 if (ret) 225 return ret; 226 227 if (pdata) { 228 for (i = 0; i < pdata->n_consumers; i++) { 229 consumer = &pdata->consumers[i]; 230 ret = devm_clk_hw_register_clkdev(&pdev->dev, 231 &tps68470_clkdata->clkout_hw, 232 consumer->consumer_con_id, 233 consumer->consumer_dev_name); 234 } 235 } 236 237 return ret; 238 } 239 240 static struct platform_driver tps68470_clk_driver = { 241 .driver = { 242 .name = TPS68470_CLK_NAME, 243 }, 244 .probe = tps68470_clk_probe, 245 }; 246 247 /* 248 * The ACPI tps68470 probe-ordering depends on the clk/gpio/regulator drivers 249 * registering before the drivers for the camera-sensors which use them bind. 250 * subsys_initcall() ensures this when the drivers are builtin. 251 */ 252 static int __init tps68470_clk_init(void) 253 { 254 return platform_driver_register(&tps68470_clk_driver); 255 } 256 subsys_initcall(tps68470_clk_init); 257 258 static void __exit tps68470_clk_exit(void) 259 { 260 platform_driver_unregister(&tps68470_clk_driver); 261 } 262 module_exit(tps68470_clk_exit); 263 264 MODULE_ALIAS("platform:tps68470-clk"); 265 MODULE_DESCRIPTION("clock driver for TPS68470 pmic"); 266 MODULE_LICENSE("GPL"); 267