clk-versaclock5.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791
  1. /*
  2. * Driver for IDT Versaclock 5
  3. *
  4. * Copyright (C) 2017 Marek Vasut <marek.vasut@gmail.com>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. */
  16. /*
  17. * Possible optimizations:
  18. * - Use spread spectrum
  19. * - Use integer divider in FOD if applicable
  20. */
  21. #include <linux/clk.h>
  22. #include <linux/clk-provider.h>
  23. #include <linux/delay.h>
  24. #include <linux/i2c.h>
  25. #include <linux/interrupt.h>
  26. #include <linux/mod_devicetable.h>
  27. #include <linux/module.h>
  28. #include <linux/of.h>
  29. #include <linux/of_platform.h>
  30. #include <linux/rational.h>
  31. #include <linux/regmap.h>
  32. #include <linux/slab.h>
  33. /* VersaClock5 registers */
  34. #define VC5_OTP_CONTROL 0x00
  35. /* Factory-reserved register block */
  36. #define VC5_RSVD_DEVICE_ID 0x01
  37. #define VC5_RSVD_ADC_GAIN_7_0 0x02
  38. #define VC5_RSVD_ADC_GAIN_15_8 0x03
  39. #define VC5_RSVD_ADC_OFFSET_7_0 0x04
  40. #define VC5_RSVD_ADC_OFFSET_15_8 0x05
  41. #define VC5_RSVD_TEMPY 0x06
  42. #define VC5_RSVD_OFFSET_TBIN 0x07
  43. #define VC5_RSVD_GAIN 0x08
  44. #define VC5_RSVD_TEST_NP 0x09
  45. #define VC5_RSVD_UNUSED 0x0a
  46. #define VC5_RSVD_BANDGAP_TRIM_UP 0x0b
  47. #define VC5_RSVD_BANDGAP_TRIM_DN 0x0c
  48. #define VC5_RSVD_CLK_R_12_CLK_AMP_4 0x0d
  49. #define VC5_RSVD_CLK_R_34_CLK_AMP_4 0x0e
  50. #define VC5_RSVD_CLK_AMP_123 0x0f
  51. /* Configuration register block */
  52. #define VC5_PRIM_SRC_SHDN 0x10
  53. #define VC5_PRIM_SRC_SHDN_EN_XTAL BIT(7)
  54. #define VC5_PRIM_SRC_SHDN_EN_CLKIN BIT(6)
  55. #define VC5_PRIM_SRC_SHDN_SP BIT(1)
  56. #define VC5_PRIM_SRC_SHDN_EN_GBL_SHDN BIT(0)
  57. #define VC5_VCO_BAND 0x11
  58. #define VC5_XTAL_X1_LOAD_CAP 0x12
  59. #define VC5_XTAL_X2_LOAD_CAP 0x13
  60. #define VC5_REF_DIVIDER 0x15
  61. #define VC5_REF_DIVIDER_SEL_PREDIV2 BIT(7)
  62. #define VC5_REF_DIVIDER_REF_DIV(n) ((n) & 0x3f)
  63. #define VC5_VCO_CTRL_AND_PREDIV 0x16
  64. #define VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV BIT(7)
  65. #define VC5_FEEDBACK_INT_DIV 0x17
  66. #define VC5_FEEDBACK_INT_DIV_BITS 0x18
  67. #define VC5_FEEDBACK_FRAC_DIV(n) (0x19 + (n))
  68. #define VC5_RC_CONTROL0 0x1e
  69. #define VC5_RC_CONTROL1 0x1f
  70. /* Register 0x20 is factory reserved */
  71. /* Output divider control for divider 1,2,3,4 */
  72. #define VC5_OUT_DIV_CONTROL(idx) (0x21 + ((idx) * 0x10))
  73. #define VC5_OUT_DIV_CONTROL_RESET BIT(7)
  74. #define VC5_OUT_DIV_CONTROL_SELB_NORM BIT(3)
  75. #define VC5_OUT_DIV_CONTROL_SEL_EXT BIT(2)
  76. #define VC5_OUT_DIV_CONTROL_INT_MODE BIT(1)
  77. #define VC5_OUT_DIV_CONTROL_EN_FOD BIT(0)
  78. #define VC5_OUT_DIV_FRAC(idx, n) (0x22 + ((idx) * 0x10) + (n))
  79. #define VC5_OUT_DIV_FRAC4_OD_SCEE BIT(1)
  80. #define VC5_OUT_DIV_STEP_SPREAD(idx, n) (0x26 + ((idx) * 0x10) + (n))
  81. #define VC5_OUT_DIV_SPREAD_MOD(idx, n) (0x29 + ((idx) * 0x10) + (n))
  82. #define VC5_OUT_DIV_SKEW_INT(idx, n) (0x2b + ((idx) * 0x10) + (n))
  83. #define VC5_OUT_DIV_INT(idx, n) (0x2d + ((idx) * 0x10) + (n))
  84. #define VC5_OUT_DIV_SKEW_FRAC(idx) (0x2f + ((idx) * 0x10))
  85. /* Registers 0x30, 0x40, 0x50 are factory reserved */
  86. /* Clock control register for clock 1,2 */
  87. #define VC5_CLK_OUTPUT_CFG(idx, n) (0x60 + ((idx) * 0x2) + (n))
  88. #define VC5_CLK_OUTPUT_CFG1_EN_CLKBUF BIT(0)
  89. #define VC5_CLK_OE_SHDN 0x68
  90. #define VC5_CLK_OS_SHDN 0x69
  91. #define VC5_GLOBAL_REGISTER 0x76
  92. #define VC5_GLOBAL_REGISTER_GLOBAL_RESET BIT(5)
  93. /* PLL/VCO runs between 2.5 GHz and 3.0 GHz */
  94. #define VC5_PLL_VCO_MIN 2500000000UL
  95. #define VC5_PLL_VCO_MAX 3000000000UL
  96. /* VC5 Input mux settings */
  97. #define VC5_MUX_IN_XIN BIT(0)
  98. #define VC5_MUX_IN_CLKIN BIT(1)
  99. /* Supported IDT VC5 models. */
  100. enum vc5_model {
  101. IDT_VC5_5P49V5923,
  102. IDT_VC5_5P49V5933,
  103. };
  104. struct vc5_driver_data;
  105. struct vc5_hw_data {
  106. struct clk_hw hw;
  107. struct vc5_driver_data *vc5;
  108. u32 div_int;
  109. u32 div_frc;
  110. unsigned int num;
  111. };
  112. struct vc5_driver_data {
  113. struct i2c_client *client;
  114. struct regmap *regmap;
  115. enum vc5_model model;
  116. struct clk *pin_xin;
  117. struct clk *pin_clkin;
  118. unsigned char clk_mux_ins;
  119. struct clk_hw clk_mux;
  120. struct vc5_hw_data clk_pll;
  121. struct vc5_hw_data clk_fod[2];
  122. struct vc5_hw_data clk_out[3];
  123. };
  124. static const char * const vc5_mux_names[] = {
  125. "mux"
  126. };
  127. static const char * const vc5_pll_names[] = {
  128. "pll"
  129. };
  130. static const char * const vc5_fod_names[] = {
  131. "fod0", "fod1", "fod2", "fod3",
  132. };
  133. static const char * const vc5_clk_out_names[] = {
  134. "out0_sel_i2cb", "out1", "out2", "out3", "out4",
  135. };
  136. /*
  137. * VersaClock5 i2c regmap
  138. */
  139. static bool vc5_regmap_is_writeable(struct device *dev, unsigned int reg)
  140. {
  141. /* Factory reserved regs, make them read-only */
  142. if (reg <= 0xf)
  143. return false;
  144. /* Factory reserved regs, make them read-only */
  145. if (reg == 0x14 || reg == 0x1c || reg == 0x1d)
  146. return false;
  147. return true;
  148. }
  149. static const struct regmap_config vc5_regmap_config = {
  150. .reg_bits = 8,
  151. .val_bits = 8,
  152. .cache_type = REGCACHE_RBTREE,
  153. .max_register = 0x76,
  154. .writeable_reg = vc5_regmap_is_writeable,
  155. };
  156. /*
  157. * VersaClock5 input multiplexer between XTAL and CLKIN divider
  158. */
  159. static unsigned char vc5_mux_get_parent(struct clk_hw *hw)
  160. {
  161. struct vc5_driver_data *vc5 =
  162. container_of(hw, struct vc5_driver_data, clk_mux);
  163. const u8 mask = VC5_PRIM_SRC_SHDN_EN_XTAL | VC5_PRIM_SRC_SHDN_EN_CLKIN;
  164. unsigned int src;
  165. regmap_read(vc5->regmap, VC5_PRIM_SRC_SHDN, &src);
  166. src &= mask;
  167. if (src == VC5_PRIM_SRC_SHDN_EN_XTAL)
  168. return 0;
  169. if (src == VC5_PRIM_SRC_SHDN_EN_CLKIN)
  170. return 1;
  171. dev_warn(&vc5->client->dev,
  172. "Invalid clock input configuration (%02x)\n", src);
  173. return 0;
  174. }
  175. static int vc5_mux_set_parent(struct clk_hw *hw, u8 index)
  176. {
  177. struct vc5_driver_data *vc5 =
  178. container_of(hw, struct vc5_driver_data, clk_mux);
  179. const u8 mask = VC5_PRIM_SRC_SHDN_EN_XTAL | VC5_PRIM_SRC_SHDN_EN_CLKIN;
  180. u8 src;
  181. if ((index > 1) || !vc5->clk_mux_ins)
  182. return -EINVAL;
  183. if (vc5->clk_mux_ins == (VC5_MUX_IN_CLKIN | VC5_MUX_IN_XIN)) {
  184. if (index == 0)
  185. src = VC5_PRIM_SRC_SHDN_EN_XTAL;
  186. if (index == 1)
  187. src = VC5_PRIM_SRC_SHDN_EN_CLKIN;
  188. } else {
  189. if (index != 0)
  190. return -EINVAL;
  191. if (vc5->clk_mux_ins == VC5_MUX_IN_XIN)
  192. src = VC5_PRIM_SRC_SHDN_EN_XTAL;
  193. if (vc5->clk_mux_ins == VC5_MUX_IN_CLKIN)
  194. src = VC5_PRIM_SRC_SHDN_EN_CLKIN;
  195. }
  196. return regmap_update_bits(vc5->regmap, VC5_PRIM_SRC_SHDN, mask, src);
  197. }
  198. static unsigned long vc5_mux_recalc_rate(struct clk_hw *hw,
  199. unsigned long parent_rate)
  200. {
  201. struct vc5_driver_data *vc5 =
  202. container_of(hw, struct vc5_driver_data, clk_mux);
  203. unsigned int prediv, div;
  204. regmap_read(vc5->regmap, VC5_VCO_CTRL_AND_PREDIV, &prediv);
  205. /* The bypass_prediv is set, PLL fed from Ref_in directly. */
  206. if (prediv & VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV)
  207. return parent_rate;
  208. regmap_read(vc5->regmap, VC5_REF_DIVIDER, &div);
  209. /* The Sel_prediv2 is set, PLL fed from prediv2 (Ref_in / 2) */
  210. if (div & VC5_REF_DIVIDER_SEL_PREDIV2)
  211. return parent_rate / 2;
  212. else
  213. return parent_rate / VC5_REF_DIVIDER_REF_DIV(div);
  214. }
  215. static long vc5_mux_round_rate(struct clk_hw *hw, unsigned long rate,
  216. unsigned long *parent_rate)
  217. {
  218. unsigned long idiv;
  219. /* PLL cannot operate with input clock above 50 MHz. */
  220. if (rate > 50000000)
  221. return -EINVAL;
  222. /* CLKIN within range of PLL input, feed directly to PLL. */
  223. if (*parent_rate <= 50000000)
  224. return *parent_rate;
  225. idiv = DIV_ROUND_UP(*parent_rate, rate);
  226. if (idiv > 127)
  227. return -EINVAL;
  228. return *parent_rate / idiv;
  229. }
  230. static int vc5_mux_set_rate(struct clk_hw *hw, unsigned long rate,
  231. unsigned long parent_rate)
  232. {
  233. struct vc5_driver_data *vc5 =
  234. container_of(hw, struct vc5_driver_data, clk_mux);
  235. unsigned long idiv;
  236. u8 div;
  237. /* CLKIN within range of PLL input, feed directly to PLL. */
  238. if (parent_rate <= 50000000) {
  239. regmap_update_bits(vc5->regmap, VC5_VCO_CTRL_AND_PREDIV,
  240. VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV,
  241. VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV);
  242. regmap_update_bits(vc5->regmap, VC5_REF_DIVIDER, 0xff, 0x00);
  243. return 0;
  244. }
  245. idiv = DIV_ROUND_UP(parent_rate, rate);
  246. /* We have dedicated div-2 predivider. */
  247. if (idiv == 2)
  248. div = VC5_REF_DIVIDER_SEL_PREDIV2;
  249. else
  250. div = VC5_REF_DIVIDER_REF_DIV(idiv);
  251. regmap_update_bits(vc5->regmap, VC5_REF_DIVIDER, 0xff, div);
  252. regmap_update_bits(vc5->regmap, VC5_VCO_CTRL_AND_PREDIV,
  253. VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV, 0);
  254. return 0;
  255. }
  256. static const struct clk_ops vc5_mux_ops = {
  257. .set_parent = vc5_mux_set_parent,
  258. .get_parent = vc5_mux_get_parent,
  259. .recalc_rate = vc5_mux_recalc_rate,
  260. .round_rate = vc5_mux_round_rate,
  261. .set_rate = vc5_mux_set_rate,
  262. };
  263. /*
  264. * VersaClock5 PLL/VCO
  265. */
  266. static unsigned long vc5_pll_recalc_rate(struct clk_hw *hw,
  267. unsigned long parent_rate)
  268. {
  269. struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
  270. struct vc5_driver_data *vc5 = hwdata->vc5;
  271. u32 div_int, div_frc;
  272. u8 fb[5];
  273. regmap_bulk_read(vc5->regmap, VC5_FEEDBACK_INT_DIV, fb, 5);
  274. div_int = (fb[0] << 4) | (fb[1] >> 4);
  275. div_frc = (fb[2] << 16) | (fb[3] << 8) | fb[4];
  276. /* The PLL divider has 12 integer bits and 24 fractional bits */
  277. return (parent_rate * div_int) + ((parent_rate * div_frc) >> 24);
  278. }
  279. static long vc5_pll_round_rate(struct clk_hw *hw, unsigned long rate,
  280. unsigned long *parent_rate)
  281. {
  282. struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
  283. u32 div_int;
  284. u64 div_frc;
  285. if (rate < VC5_PLL_VCO_MIN)
  286. rate = VC5_PLL_VCO_MIN;
  287. if (rate > VC5_PLL_VCO_MAX)
  288. rate = VC5_PLL_VCO_MAX;
  289. /* Determine integer part, which is 12 bit wide */
  290. div_int = rate / *parent_rate;
  291. if (div_int > 0xfff)
  292. rate = *parent_rate * 0xfff;
  293. /* Determine best fractional part, which is 24 bit wide */
  294. div_frc = rate % *parent_rate;
  295. div_frc *= BIT(24) - 1;
  296. do_div(div_frc, *parent_rate);
  297. hwdata->div_int = div_int;
  298. hwdata->div_frc = (u32)div_frc;
  299. return (*parent_rate * div_int) + ((*parent_rate * div_frc) >> 24);
  300. }
  301. static int vc5_pll_set_rate(struct clk_hw *hw, unsigned long rate,
  302. unsigned long parent_rate)
  303. {
  304. struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
  305. struct vc5_driver_data *vc5 = hwdata->vc5;
  306. u8 fb[5];
  307. fb[0] = hwdata->div_int >> 4;
  308. fb[1] = hwdata->div_int << 4;
  309. fb[2] = hwdata->div_frc >> 16;
  310. fb[3] = hwdata->div_frc >> 8;
  311. fb[4] = hwdata->div_frc;
  312. return regmap_bulk_write(vc5->regmap, VC5_FEEDBACK_INT_DIV, fb, 5);
  313. }
  314. static const struct clk_ops vc5_pll_ops = {
  315. .recalc_rate = vc5_pll_recalc_rate,
  316. .round_rate = vc5_pll_round_rate,
  317. .set_rate = vc5_pll_set_rate,
  318. };
  319. static unsigned long vc5_fod_recalc_rate(struct clk_hw *hw,
  320. unsigned long parent_rate)
  321. {
  322. struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
  323. struct vc5_driver_data *vc5 = hwdata->vc5;
  324. /* VCO frequency is divided by two before entering FOD */
  325. u32 f_in = parent_rate / 2;
  326. u32 div_int, div_frc;
  327. u8 od_int[2];
  328. u8 od_frc[4];
  329. regmap_bulk_read(vc5->regmap, VC5_OUT_DIV_INT(hwdata->num, 0),
  330. od_int, 2);
  331. regmap_bulk_read(vc5->regmap, VC5_OUT_DIV_FRAC(hwdata->num, 0),
  332. od_frc, 4);
  333. div_int = (od_int[0] << 4) | (od_int[1] >> 4);
  334. div_frc = (od_frc[0] << 22) | (od_frc[1] << 14) |
  335. (od_frc[2] << 6) | (od_frc[3] >> 2);
  336. /* The PLL divider has 12 integer bits and 30 fractional bits */
  337. return div64_u64((u64)f_in << 24ULL, ((u64)div_int << 24ULL) + div_frc);
  338. }
  339. static long vc5_fod_round_rate(struct clk_hw *hw, unsigned long rate,
  340. unsigned long *parent_rate)
  341. {
  342. struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
  343. /* VCO frequency is divided by two before entering FOD */
  344. u32 f_in = *parent_rate / 2;
  345. u32 div_int;
  346. u64 div_frc;
  347. /* Determine integer part, which is 12 bit wide */
  348. div_int = f_in / rate;
  349. /*
  350. * WARNING: The clock chip does not output signal if the integer part
  351. * of the divider is 0xfff and fractional part is non-zero.
  352. * Clamp the divider at 0xffe to keep the code simple.
  353. */
  354. if (div_int > 0xffe) {
  355. div_int = 0xffe;
  356. rate = f_in / div_int;
  357. }
  358. /* Determine best fractional part, which is 30 bit wide */
  359. div_frc = f_in % rate;
  360. div_frc <<= 24;
  361. do_div(div_frc, rate);
  362. hwdata->div_int = div_int;
  363. hwdata->div_frc = (u32)div_frc;
  364. return div64_u64((u64)f_in << 24ULL, ((u64)div_int << 24ULL) + div_frc);
  365. }
  366. static int vc5_fod_set_rate(struct clk_hw *hw, unsigned long rate,
  367. unsigned long parent_rate)
  368. {
  369. struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
  370. struct vc5_driver_data *vc5 = hwdata->vc5;
  371. u8 data[14] = {
  372. hwdata->div_frc >> 22, hwdata->div_frc >> 14,
  373. hwdata->div_frc >> 6, hwdata->div_frc << 2,
  374. 0, 0, 0, 0, 0,
  375. 0, 0,
  376. hwdata->div_int >> 4, hwdata->div_int << 4,
  377. 0
  378. };
  379. regmap_bulk_write(vc5->regmap, VC5_OUT_DIV_FRAC(hwdata->num, 0),
  380. data, 14);
  381. /*
  382. * Toggle magic bit in undocumented register for unknown reason.
  383. * This is what the IDT timing commander tool does and the chip
  384. * datasheet somewhat implies this is needed, but the register
  385. * and the bit is not documented.
  386. */
  387. regmap_update_bits(vc5->regmap, VC5_GLOBAL_REGISTER,
  388. VC5_GLOBAL_REGISTER_GLOBAL_RESET, 0);
  389. regmap_update_bits(vc5->regmap, VC5_GLOBAL_REGISTER,
  390. VC5_GLOBAL_REGISTER_GLOBAL_RESET,
  391. VC5_GLOBAL_REGISTER_GLOBAL_RESET);
  392. return 0;
  393. }
  394. static const struct clk_ops vc5_fod_ops = {
  395. .recalc_rate = vc5_fod_recalc_rate,
  396. .round_rate = vc5_fod_round_rate,
  397. .set_rate = vc5_fod_set_rate,
  398. };
  399. static int vc5_clk_out_prepare(struct clk_hw *hw)
  400. {
  401. struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
  402. struct vc5_driver_data *vc5 = hwdata->vc5;
  403. /* Enable the clock buffer */
  404. regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1),
  405. VC5_CLK_OUTPUT_CFG1_EN_CLKBUF,
  406. VC5_CLK_OUTPUT_CFG1_EN_CLKBUF);
  407. return 0;
  408. }
  409. static void vc5_clk_out_unprepare(struct clk_hw *hw)
  410. {
  411. struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
  412. struct vc5_driver_data *vc5 = hwdata->vc5;
  413. /* Enable the clock buffer */
  414. regmap_update_bits(vc5->regmap, VC5_CLK_OUTPUT_CFG(hwdata->num, 1),
  415. VC5_CLK_OUTPUT_CFG1_EN_CLKBUF, 0);
  416. }
  417. static unsigned char vc5_clk_out_get_parent(struct clk_hw *hw)
  418. {
  419. struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
  420. struct vc5_driver_data *vc5 = hwdata->vc5;
  421. const u8 mask = VC5_OUT_DIV_CONTROL_SELB_NORM |
  422. VC5_OUT_DIV_CONTROL_SEL_EXT |
  423. VC5_OUT_DIV_CONTROL_EN_FOD;
  424. const u8 fodclkmask = VC5_OUT_DIV_CONTROL_SELB_NORM |
  425. VC5_OUT_DIV_CONTROL_EN_FOD;
  426. const u8 extclk = VC5_OUT_DIV_CONTROL_SELB_NORM |
  427. VC5_OUT_DIV_CONTROL_SEL_EXT;
  428. unsigned int src;
  429. regmap_read(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num), &src);
  430. src &= mask;
  431. if ((src & fodclkmask) == VC5_OUT_DIV_CONTROL_EN_FOD)
  432. return 0;
  433. if (src == extclk)
  434. return 1;
  435. dev_warn(&vc5->client->dev,
  436. "Invalid clock output configuration (%02x)\n", src);
  437. return 0;
  438. }
  439. static int vc5_clk_out_set_parent(struct clk_hw *hw, u8 index)
  440. {
  441. struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
  442. struct vc5_driver_data *vc5 = hwdata->vc5;
  443. const u8 mask = VC5_OUT_DIV_CONTROL_RESET |
  444. VC5_OUT_DIV_CONTROL_SELB_NORM |
  445. VC5_OUT_DIV_CONTROL_SEL_EXT |
  446. VC5_OUT_DIV_CONTROL_EN_FOD;
  447. const u8 extclk = VC5_OUT_DIV_CONTROL_SELB_NORM |
  448. VC5_OUT_DIV_CONTROL_SEL_EXT;
  449. u8 src = VC5_OUT_DIV_CONTROL_RESET;
  450. if (index == 0)
  451. src |= VC5_OUT_DIV_CONTROL_EN_FOD;
  452. else
  453. src |= extclk;
  454. return regmap_update_bits(vc5->regmap, VC5_OUT_DIV_CONTROL(hwdata->num),
  455. mask, src);
  456. }
  457. static const struct clk_ops vc5_clk_out_ops = {
  458. .prepare = vc5_clk_out_prepare,
  459. .unprepare = vc5_clk_out_unprepare,
  460. .set_parent = vc5_clk_out_set_parent,
  461. .get_parent = vc5_clk_out_get_parent,
  462. };
  463. static struct clk_hw *vc5_of_clk_get(struct of_phandle_args *clkspec,
  464. void *data)
  465. {
  466. struct vc5_driver_data *vc5 = data;
  467. unsigned int idx = clkspec->args[0];
  468. if (idx > 2)
  469. return ERR_PTR(-EINVAL);
  470. return &vc5->clk_out[idx].hw;
  471. }
  472. static int vc5_map_index_to_output(const enum vc5_model model,
  473. const unsigned int n)
  474. {
  475. switch (model) {
  476. case IDT_VC5_5P49V5933:
  477. return (n == 0) ? 0 : 3;
  478. case IDT_VC5_5P49V5923:
  479. default:
  480. return n;
  481. }
  482. }
  483. static const struct of_device_id clk_vc5_of_match[];
  484. static int vc5_probe(struct i2c_client *client,
  485. const struct i2c_device_id *id)
  486. {
  487. const struct of_device_id *of_id =
  488. of_match_device(clk_vc5_of_match, &client->dev);
  489. struct vc5_driver_data *vc5;
  490. struct clk_init_data init;
  491. const char *parent_names[2];
  492. unsigned int n, idx;
  493. int ret;
  494. vc5 = devm_kzalloc(&client->dev, sizeof(*vc5), GFP_KERNEL);
  495. if (vc5 == NULL)
  496. return -ENOMEM;
  497. i2c_set_clientdata(client, vc5);
  498. vc5->client = client;
  499. vc5->model = (enum vc5_model)of_id->data;
  500. vc5->pin_xin = devm_clk_get(&client->dev, "xin");
  501. if (PTR_ERR(vc5->pin_xin) == -EPROBE_DEFER)
  502. return -EPROBE_DEFER;
  503. vc5->pin_clkin = devm_clk_get(&client->dev, "clkin");
  504. if (PTR_ERR(vc5->pin_clkin) == -EPROBE_DEFER)
  505. return -EPROBE_DEFER;
  506. vc5->regmap = devm_regmap_init_i2c(client, &vc5_regmap_config);
  507. if (IS_ERR(vc5->regmap)) {
  508. dev_err(&client->dev, "failed to allocate register map\n");
  509. return PTR_ERR(vc5->regmap);
  510. }
  511. /* Register clock input mux */
  512. memset(&init, 0, sizeof(init));
  513. if (!IS_ERR(vc5->pin_xin)) {
  514. vc5->clk_mux_ins |= VC5_MUX_IN_XIN;
  515. parent_names[init.num_parents++] = __clk_get_name(vc5->pin_xin);
  516. } else if (vc5->model == IDT_VC5_5P49V5933) {
  517. /* IDT VC5 5P49V5933 has built-in oscilator. */
  518. vc5->pin_xin = clk_register_fixed_rate(&client->dev,
  519. "internal-xtal", NULL,
  520. 0, 25000000);
  521. if (IS_ERR(vc5->pin_xin))
  522. return PTR_ERR(vc5->pin_xin);
  523. vc5->clk_mux_ins |= VC5_MUX_IN_XIN;
  524. parent_names[init.num_parents++] = __clk_get_name(vc5->pin_xin);
  525. }
  526. if (!IS_ERR(vc5->pin_clkin)) {
  527. vc5->clk_mux_ins |= VC5_MUX_IN_CLKIN;
  528. parent_names[init.num_parents++] =
  529. __clk_get_name(vc5->pin_clkin);
  530. }
  531. if (!init.num_parents) {
  532. dev_err(&client->dev, "no input clock specified!\n");
  533. return -EINVAL;
  534. }
  535. init.name = vc5_mux_names[0];
  536. init.ops = &vc5_mux_ops;
  537. init.flags = 0;
  538. init.parent_names = parent_names;
  539. vc5->clk_mux.init = &init;
  540. ret = devm_clk_hw_register(&client->dev, &vc5->clk_mux);
  541. if (ret) {
  542. dev_err(&client->dev, "unable to register %s\n", init.name);
  543. goto err_clk;
  544. }
  545. /* Register PLL */
  546. memset(&init, 0, sizeof(init));
  547. init.name = vc5_pll_names[0];
  548. init.ops = &vc5_pll_ops;
  549. init.flags = CLK_SET_RATE_PARENT;
  550. init.parent_names = vc5_mux_names;
  551. init.num_parents = 1;
  552. vc5->clk_pll.num = 0;
  553. vc5->clk_pll.vc5 = vc5;
  554. vc5->clk_pll.hw.init = &init;
  555. ret = devm_clk_hw_register(&client->dev, &vc5->clk_pll.hw);
  556. if (ret) {
  557. dev_err(&client->dev, "unable to register %s\n", init.name);
  558. goto err_clk;
  559. }
  560. /* Register FODs */
  561. for (n = 0; n < 2; n++) {
  562. idx = vc5_map_index_to_output(vc5->model, n);
  563. memset(&init, 0, sizeof(init));
  564. init.name = vc5_fod_names[idx];
  565. init.ops = &vc5_fod_ops;
  566. init.flags = CLK_SET_RATE_PARENT;
  567. init.parent_names = vc5_pll_names;
  568. init.num_parents = 1;
  569. vc5->clk_fod[n].num = idx;
  570. vc5->clk_fod[n].vc5 = vc5;
  571. vc5->clk_fod[n].hw.init = &init;
  572. ret = devm_clk_hw_register(&client->dev, &vc5->clk_fod[n].hw);
  573. if (ret) {
  574. dev_err(&client->dev, "unable to register %s\n",
  575. init.name);
  576. goto err_clk;
  577. }
  578. }
  579. /* Register MUX-connected OUT0_I2C_SELB output */
  580. memset(&init, 0, sizeof(init));
  581. init.name = vc5_clk_out_names[0];
  582. init.ops = &vc5_clk_out_ops;
  583. init.flags = CLK_SET_RATE_PARENT;
  584. init.parent_names = vc5_mux_names;
  585. init.num_parents = 1;
  586. vc5->clk_out[0].num = idx;
  587. vc5->clk_out[0].vc5 = vc5;
  588. vc5->clk_out[0].hw.init = &init;
  589. ret = devm_clk_hw_register(&client->dev, &vc5->clk_out[0].hw);
  590. if (ret) {
  591. dev_err(&client->dev, "unable to register %s\n",
  592. init.name);
  593. goto err_clk;
  594. }
  595. /* Register FOD-connected OUTx outputs */
  596. for (n = 1; n < 3; n++) {
  597. idx = vc5_map_index_to_output(vc5->model, n - 1);
  598. parent_names[0] = vc5_fod_names[idx];
  599. if (n == 1)
  600. parent_names[1] = vc5_mux_names[0];
  601. else
  602. parent_names[1] = vc5_clk_out_names[n - 1];
  603. memset(&init, 0, sizeof(init));
  604. init.name = vc5_clk_out_names[idx + 1];
  605. init.ops = &vc5_clk_out_ops;
  606. init.flags = CLK_SET_RATE_PARENT;
  607. init.parent_names = parent_names;
  608. init.num_parents = 2;
  609. vc5->clk_out[n].num = idx;
  610. vc5->clk_out[n].vc5 = vc5;
  611. vc5->clk_out[n].hw.init = &init;
  612. ret = devm_clk_hw_register(&client->dev,
  613. &vc5->clk_out[n].hw);
  614. if (ret) {
  615. dev_err(&client->dev, "unable to register %s\n",
  616. init.name);
  617. goto err_clk;
  618. }
  619. }
  620. ret = of_clk_add_hw_provider(client->dev.of_node, vc5_of_clk_get, vc5);
  621. if (ret) {
  622. dev_err(&client->dev, "unable to add clk provider\n");
  623. goto err_clk;
  624. }
  625. return 0;
  626. err_clk:
  627. if (vc5->model == IDT_VC5_5P49V5933)
  628. clk_unregister_fixed_rate(vc5->pin_xin);
  629. return ret;
  630. }
  631. static int vc5_remove(struct i2c_client *client)
  632. {
  633. struct vc5_driver_data *vc5 = i2c_get_clientdata(client);
  634. of_clk_del_provider(client->dev.of_node);
  635. if (vc5->model == IDT_VC5_5P49V5933)
  636. clk_unregister_fixed_rate(vc5->pin_xin);
  637. return 0;
  638. }
  639. static const struct i2c_device_id vc5_id[] = {
  640. { "5p49v5923", .driver_data = IDT_VC5_5P49V5923 },
  641. { "5p49v5933", .driver_data = IDT_VC5_5P49V5933 },
  642. { }
  643. };
  644. MODULE_DEVICE_TABLE(i2c, vc5_id);
  645. static const struct of_device_id clk_vc5_of_match[] = {
  646. { .compatible = "idt,5p49v5923", .data = (void *)IDT_VC5_5P49V5923 },
  647. { .compatible = "idt,5p49v5933", .data = (void *)IDT_VC5_5P49V5933 },
  648. { },
  649. };
  650. MODULE_DEVICE_TABLE(of, clk_vc5_of_match);
  651. static struct i2c_driver vc5_driver = {
  652. .driver = {
  653. .name = "vc5",
  654. .of_match_table = clk_vc5_of_match,
  655. },
  656. .probe = vc5_probe,
  657. .remove = vc5_remove,
  658. .id_table = vc5_id,
  659. };
  660. module_i2c_driver(vc5_driver);
  661. MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
  662. MODULE_DESCRIPTION("IDT VersaClock 5 driver");
  663. MODULE_LICENSE("GPL");