clk-si544.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Driver for Silicon Labs Si544 Programmable Oscillator
  4. * Copyright (C) 2018 Topic Embedded Products
  5. * Author: Mike Looijmans <mike.looijmans@topic.nl>
  6. */
  7. #include <linux/clk-provider.h>
  8. #include <linux/delay.h>
  9. #include <linux/math64.h>
  10. #include <linux/module.h>
  11. #include <linux/i2c.h>
  12. #include <linux/regmap.h>
  13. #include <linux/slab.h>
  14. /* I2C registers (decimal as in datasheet) */
  15. #define SI544_REG_CONTROL 7
  16. #define SI544_REG_OE_STATE 17
  17. #define SI544_REG_HS_DIV 23
  18. #define SI544_REG_LS_HS_DIV 24
  19. #define SI544_REG_FBDIV0 26
  20. #define SI544_REG_FBDIV8 27
  21. #define SI544_REG_FBDIV16 28
  22. #define SI544_REG_FBDIV24 29
  23. #define SI544_REG_FBDIV32 30
  24. #define SI544_REG_FBDIV40 31
  25. #define SI544_REG_FCAL_OVR 69
  26. #define SI544_REG_ADPLL_DELTA_M0 231
  27. #define SI544_REG_ADPLL_DELTA_M8 232
  28. #define SI544_REG_ADPLL_DELTA_M16 233
  29. #define SI544_REG_PAGE_SELECT 255
  30. /* Register values */
  31. #define SI544_CONTROL_RESET BIT(7)
  32. #define SI544_CONTROL_MS_ICAL2 BIT(3)
  33. #define SI544_OE_STATE_ODC_OE BIT(0)
  34. /* Max freq depends on speed grade */
  35. #define SI544_MIN_FREQ 200000U
  36. /* Si544 Internal oscilator runs at 55.05 MHz */
  37. #define FXO 55050000U
  38. /* VCO range is 10.8 .. 12.1 GHz, max depends on speed grade */
  39. #define FVCO_MIN 10800000000ULL
  40. #define HS_DIV_MAX 2046
  41. #define HS_DIV_MAX_ODD 33
  42. /* Lowest frequency synthesizeable using only the HS divider */
  43. #define MIN_HSDIV_FREQ (FVCO_MIN / HS_DIV_MAX)
  44. /* Range and interpretation of the adjustment value */
  45. #define DELTA_M_MAX 8161512
  46. #define DELTA_M_FRAC_NUM 19
  47. #define DELTA_M_FRAC_DEN 20000
  48. struct clk_si544 {
  49. struct clk_hw hw;
  50. struct regmap *regmap;
  51. struct i2c_client *i2c_client;
  52. unsigned long max_freq;
  53. };
  54. #define to_clk_si544(_hw) container_of(_hw, struct clk_si544, hw)
  55. /**
  56. * struct clk_si544_muldiv - Multiplier/divider settings
  57. * @fb_div_frac: integer part of feedback divider (32 bits)
  58. * @fb_div_int: fractional part of feedback divider (11 bits)
  59. * @hs_div: 1st divider, 5..2046, must be even when >33
  60. * @ls_div_bits: 2nd divider, as 2^x, range 0..5
  61. * If ls_div_bits is non-zero, hs_div must be even
  62. * @delta_m: Frequency shift for small -950..+950 ppm changes, 24 bit
  63. */
  64. struct clk_si544_muldiv {
  65. u32 fb_div_frac;
  66. u16 fb_div_int;
  67. u16 hs_div;
  68. u8 ls_div_bits;
  69. s32 delta_m;
  70. };
  71. /* Enables or disables the output driver */
  72. static int si544_enable_output(struct clk_si544 *data, bool enable)
  73. {
  74. return regmap_update_bits(data->regmap, SI544_REG_OE_STATE,
  75. SI544_OE_STATE_ODC_OE, enable ? SI544_OE_STATE_ODC_OE : 0);
  76. }
  77. static int si544_prepare(struct clk_hw *hw)
  78. {
  79. struct clk_si544 *data = to_clk_si544(hw);
  80. return si544_enable_output(data, true);
  81. }
  82. static void si544_unprepare(struct clk_hw *hw)
  83. {
  84. struct clk_si544 *data = to_clk_si544(hw);
  85. si544_enable_output(data, false);
  86. }
  87. static int si544_is_prepared(struct clk_hw *hw)
  88. {
  89. struct clk_si544 *data = to_clk_si544(hw);
  90. unsigned int val;
  91. int err;
  92. err = regmap_read(data->regmap, SI544_REG_OE_STATE, &val);
  93. if (err < 0)
  94. return err;
  95. return !!(val & SI544_OE_STATE_ODC_OE);
  96. }
  97. /* Retrieve clock multiplier and dividers from hardware */
  98. static int si544_get_muldiv(struct clk_si544 *data,
  99. struct clk_si544_muldiv *settings)
  100. {
  101. int err;
  102. u8 reg[6];
  103. err = regmap_bulk_read(data->regmap, SI544_REG_HS_DIV, reg, 2);
  104. if (err)
  105. return err;
  106. settings->ls_div_bits = (reg[1] >> 4) & 0x07;
  107. settings->hs_div = (reg[1] & 0x07) << 8 | reg[0];
  108. err = regmap_bulk_read(data->regmap, SI544_REG_FBDIV0, reg, 6);
  109. if (err)
  110. return err;
  111. settings->fb_div_int = reg[4] | (reg[5] & 0x07) << 8;
  112. settings->fb_div_frac = reg[0] | reg[1] << 8 | reg[2] << 16 |
  113. reg[3] << 24;
  114. err = regmap_bulk_read(data->regmap, SI544_REG_ADPLL_DELTA_M0, reg, 3);
  115. if (err)
  116. return err;
  117. /* Interpret as 24-bit signed number */
  118. settings->delta_m = reg[0] << 8 | reg[1] << 16 | reg[2] << 24;
  119. settings->delta_m >>= 8;
  120. return 0;
  121. }
  122. static int si544_set_delta_m(struct clk_si544 *data, s32 delta_m)
  123. {
  124. u8 reg[3];
  125. reg[0] = delta_m;
  126. reg[1] = delta_m >> 8;
  127. reg[2] = delta_m >> 16;
  128. return regmap_bulk_write(data->regmap, SI544_REG_ADPLL_DELTA_M0,
  129. reg, 3);
  130. }
  131. static int si544_set_muldiv(struct clk_si544 *data,
  132. struct clk_si544_muldiv *settings)
  133. {
  134. int err;
  135. u8 reg[6];
  136. reg[0] = settings->hs_div;
  137. reg[1] = settings->hs_div >> 8 | settings->ls_div_bits << 4;
  138. err = regmap_bulk_write(data->regmap, SI544_REG_HS_DIV, reg, 2);
  139. if (err < 0)
  140. return err;
  141. reg[0] = settings->fb_div_frac;
  142. reg[1] = settings->fb_div_frac >> 8;
  143. reg[2] = settings->fb_div_frac >> 16;
  144. reg[3] = settings->fb_div_frac >> 24;
  145. reg[4] = settings->fb_div_int;
  146. reg[5] = settings->fb_div_int >> 8;
  147. /*
  148. * Writing to SI544_REG_FBDIV40 triggers the clock change, so that
  149. * must be written last
  150. */
  151. return regmap_bulk_write(data->regmap, SI544_REG_FBDIV0, reg, 6);
  152. }
  153. static bool is_valid_frequency(const struct clk_si544 *data,
  154. unsigned long frequency)
  155. {
  156. if (frequency < SI544_MIN_FREQ)
  157. return false;
  158. return frequency <= data->max_freq;
  159. }
  160. /* Calculate divider settings for a given frequency */
  161. static int si544_calc_muldiv(struct clk_si544_muldiv *settings,
  162. unsigned long frequency)
  163. {
  164. u64 vco;
  165. u32 ls_freq;
  166. u32 tmp;
  167. u8 res;
  168. /* Determine the minimum value of LS_DIV and resulting target freq. */
  169. ls_freq = frequency;
  170. settings->ls_div_bits = 0;
  171. if (frequency >= MIN_HSDIV_FREQ) {
  172. settings->ls_div_bits = 0;
  173. } else {
  174. res = 1;
  175. tmp = 2 * HS_DIV_MAX;
  176. while (tmp <= (HS_DIV_MAX * 32)) {
  177. if (((u64)frequency * tmp) >= FVCO_MIN)
  178. break;
  179. ++res;
  180. tmp <<= 1;
  181. }
  182. settings->ls_div_bits = res;
  183. ls_freq = frequency << res;
  184. }
  185. /* Determine minimum HS_DIV by rounding up */
  186. vco = FVCO_MIN + ls_freq - 1;
  187. do_div(vco, ls_freq);
  188. settings->hs_div = vco;
  189. /* round up to even number when required */
  190. if ((settings->hs_div & 1) &&
  191. (settings->hs_div > HS_DIV_MAX_ODD || settings->ls_div_bits))
  192. ++settings->hs_div;
  193. /* Calculate VCO frequency (in 10..12GHz range) */
  194. vco = (u64)ls_freq * settings->hs_div;
  195. /* Calculate the integer part of the feedback divider */
  196. tmp = do_div(vco, FXO);
  197. settings->fb_div_int = vco;
  198. /* And the fractional bits using the remainder */
  199. vco = (u64)tmp << 32;
  200. vco += FXO / 2; /* Round to nearest multiple */
  201. do_div(vco, FXO);
  202. settings->fb_div_frac = vco;
  203. /* Reset the frequency adjustment */
  204. settings->delta_m = 0;
  205. return 0;
  206. }
  207. /* Calculate resulting frequency given the register settings */
  208. static unsigned long si544_calc_center_rate(
  209. const struct clk_si544_muldiv *settings)
  210. {
  211. u32 d = settings->hs_div * BIT(settings->ls_div_bits);
  212. u64 vco;
  213. /* Calculate VCO from the fractional part */
  214. vco = (u64)settings->fb_div_frac * FXO;
  215. vco += (FXO / 2);
  216. vco >>= 32;
  217. /* Add the integer part of the VCO frequency */
  218. vco += (u64)settings->fb_div_int * FXO;
  219. /* Apply divider to obtain the generated frequency */
  220. do_div(vco, d);
  221. return vco;
  222. }
  223. static unsigned long si544_calc_rate(const struct clk_si544_muldiv *settings)
  224. {
  225. unsigned long rate = si544_calc_center_rate(settings);
  226. s64 delta = (s64)rate * (DELTA_M_FRAC_NUM * settings->delta_m);
  227. /*
  228. * The clock adjustment is much smaller than 1 Hz, round to the
  229. * nearest multiple. Apparently div64_s64 rounds towards zero, hence
  230. * check the sign and adjust into the proper direction.
  231. */
  232. if (settings->delta_m < 0)
  233. delta -= ((s64)DELTA_M_MAX * DELTA_M_FRAC_DEN) / 2;
  234. else
  235. delta += ((s64)DELTA_M_MAX * DELTA_M_FRAC_DEN) / 2;
  236. delta = div64_s64(delta, ((s64)DELTA_M_MAX * DELTA_M_FRAC_DEN));
  237. return rate + delta;
  238. }
  239. static unsigned long si544_recalc_rate(struct clk_hw *hw,
  240. unsigned long parent_rate)
  241. {
  242. struct clk_si544 *data = to_clk_si544(hw);
  243. struct clk_si544_muldiv settings;
  244. int err;
  245. err = si544_get_muldiv(data, &settings);
  246. if (err)
  247. return 0;
  248. return si544_calc_rate(&settings);
  249. }
  250. static long si544_round_rate(struct clk_hw *hw, unsigned long rate,
  251. unsigned long *parent_rate)
  252. {
  253. struct clk_si544 *data = to_clk_si544(hw);
  254. if (!is_valid_frequency(data, rate))
  255. return -EINVAL;
  256. /* The accuracy is less than 1 Hz, so any rate is possible */
  257. return rate;
  258. }
  259. /* Calculates the maximum "small" change, 950 * rate / 1000000 */
  260. static unsigned long si544_max_delta(unsigned long rate)
  261. {
  262. u64 num = rate;
  263. num *= DELTA_M_FRAC_NUM;
  264. do_div(num, DELTA_M_FRAC_DEN);
  265. return num;
  266. }
  267. static s32 si544_calc_delta(s32 delta, s32 max_delta)
  268. {
  269. s64 n = (s64)delta * DELTA_M_MAX;
  270. return div_s64(n, max_delta);
  271. }
  272. static int si544_set_rate(struct clk_hw *hw, unsigned long rate,
  273. unsigned long parent_rate)
  274. {
  275. struct clk_si544 *data = to_clk_si544(hw);
  276. struct clk_si544_muldiv settings;
  277. unsigned long center;
  278. long max_delta;
  279. long delta;
  280. unsigned int old_oe_state;
  281. int err;
  282. if (!is_valid_frequency(data, rate))
  283. return -EINVAL;
  284. /* Try using the frequency adjustment feature for a <= 950ppm change */
  285. err = si544_get_muldiv(data, &settings);
  286. if (err)
  287. return err;
  288. center = si544_calc_center_rate(&settings);
  289. max_delta = si544_max_delta(center);
  290. delta = rate - center;
  291. if (abs(delta) <= max_delta)
  292. return si544_set_delta_m(data,
  293. si544_calc_delta(delta, max_delta));
  294. /* Too big for the delta adjustment, need to reprogram */
  295. err = si544_calc_muldiv(&settings, rate);
  296. if (err)
  297. return err;
  298. err = regmap_read(data->regmap, SI544_REG_OE_STATE, &old_oe_state);
  299. if (err)
  300. return err;
  301. si544_enable_output(data, false);
  302. /* Allow FCAL for this frequency update */
  303. err = regmap_write(data->regmap, SI544_REG_FCAL_OVR, 0);
  304. if (err < 0)
  305. return err;
  306. err = si544_set_delta_m(data, settings.delta_m);
  307. if (err < 0)
  308. return err;
  309. err = si544_set_muldiv(data, &settings);
  310. if (err < 0)
  311. return err; /* Undefined state now, best to leave disabled */
  312. /* Trigger calibration */
  313. err = regmap_write(data->regmap, SI544_REG_CONTROL,
  314. SI544_CONTROL_MS_ICAL2);
  315. if (err < 0)
  316. return err;
  317. /* Applying a new frequency can take up to 10ms */
  318. usleep_range(10000, 12000);
  319. if (old_oe_state & SI544_OE_STATE_ODC_OE)
  320. si544_enable_output(data, true);
  321. return err;
  322. }
  323. static const struct clk_ops si544_clk_ops = {
  324. .prepare = si544_prepare,
  325. .unprepare = si544_unprepare,
  326. .is_prepared = si544_is_prepared,
  327. .recalc_rate = si544_recalc_rate,
  328. .round_rate = si544_round_rate,
  329. .set_rate = si544_set_rate,
  330. };
  331. static bool si544_regmap_is_volatile(struct device *dev, unsigned int reg)
  332. {
  333. switch (reg) {
  334. case SI544_REG_CONTROL:
  335. case SI544_REG_FCAL_OVR:
  336. return true;
  337. default:
  338. return false;
  339. }
  340. }
  341. static const struct regmap_config si544_regmap_config = {
  342. .reg_bits = 8,
  343. .val_bits = 8,
  344. .cache_type = REGCACHE_MAPLE,
  345. .max_register = SI544_REG_PAGE_SELECT,
  346. .volatile_reg = si544_regmap_is_volatile,
  347. };
  348. static int si544_probe(struct i2c_client *client)
  349. {
  350. struct clk_si544 *data;
  351. struct clk_init_data init;
  352. int err;
  353. data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
  354. if (!data)
  355. return -ENOMEM;
  356. init.ops = &si544_clk_ops;
  357. init.flags = 0;
  358. init.num_parents = 0;
  359. data->hw.init = &init;
  360. data->i2c_client = client;
  361. data->max_freq = (uintptr_t)i2c_get_match_data(client);
  362. if (of_property_read_string(client->dev.of_node, "clock-output-names",
  363. &init.name))
  364. init.name = client->dev.of_node->name;
  365. data->regmap = devm_regmap_init_i2c(client, &si544_regmap_config);
  366. if (IS_ERR(data->regmap))
  367. return PTR_ERR(data->regmap);
  368. i2c_set_clientdata(client, data);
  369. /* Select page 0, just to be sure, there appear to be no more */
  370. err = regmap_write(data->regmap, SI544_REG_PAGE_SELECT, 0);
  371. if (err < 0)
  372. return err;
  373. err = devm_clk_hw_register(&client->dev, &data->hw);
  374. if (err) {
  375. dev_err(&client->dev, "clock registration failed\n");
  376. return err;
  377. }
  378. err = devm_of_clk_add_hw_provider(&client->dev, of_clk_hw_simple_get,
  379. &data->hw);
  380. if (err) {
  381. dev_err(&client->dev, "unable to add clk provider\n");
  382. return err;
  383. }
  384. return 0;
  385. }
  386. static const struct i2c_device_id si544_id[] = {
  387. { "si544a", 1500000000 },
  388. { "si544b", 800000000 },
  389. { "si544c", 350000000 },
  390. { }
  391. };
  392. MODULE_DEVICE_TABLE(i2c, si544_id);
  393. static const struct of_device_id clk_si544_of_match[] = {
  394. { .compatible = "silabs,si544a", .data = (void *)1500000000 },
  395. { .compatible = "silabs,si544b", .data = (void *)800000000 },
  396. { .compatible = "silabs,si544c", .data = (void *)350000000 },
  397. { }
  398. };
  399. MODULE_DEVICE_TABLE(of, clk_si544_of_match);
  400. static struct i2c_driver si544_driver = {
  401. .driver = {
  402. .name = "si544",
  403. .of_match_table = clk_si544_of_match,
  404. },
  405. .probe = si544_probe,
  406. .id_table = si544_id,
  407. };
  408. module_i2c_driver(si544_driver);
  409. MODULE_AUTHOR("Mike Looijmans <mike.looijmans@topic.nl>");
  410. MODULE_DESCRIPTION("Si544 driver");
  411. MODULE_LICENSE("GPL");