clk-sp7021.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712
  1. // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
  2. /*
  3. * Copyright (C) Sunplus Technology Co., Ltd.
  4. * All rights reserved.
  5. */
  6. #include <linux/module.h>
  7. #include <linux/clk-provider.h>
  8. #include <linux/of.h>
  9. #include <linux/bitfield.h>
  10. #include <linux/slab.h>
  11. #include <linux/io.h>
  12. #include <linux/err.h>
  13. #include <linux/platform_device.h>
  14. #include <dt-bindings/clock/sunplus,sp7021-clkc.h>
  15. /* speical div_width values for PLLTV/PLLA */
  16. #define DIV_TV 33
  17. #define DIV_A 34
  18. /* PLLTV parameters */
  19. enum {
  20. SEL_FRA,
  21. SDM_MOD,
  22. PH_SEL,
  23. NFRA,
  24. DIVR,
  25. DIVN,
  26. DIVM,
  27. P_MAX
  28. };
  29. #define MASK_SEL_FRA GENMASK(1, 1)
  30. #define MASK_SDM_MOD GENMASK(2, 2)
  31. #define MASK_PH_SEL GENMASK(4, 4)
  32. #define MASK_NFRA GENMASK(12, 6)
  33. #define MASK_DIVR GENMASK(8, 7)
  34. #define MASK_DIVN GENMASK(7, 0)
  35. #define MASK_DIVM GENMASK(14, 8)
  36. /* HIWORD_MASK FIELD_PREP */
  37. #define HWM_FIELD_PREP(mask, value) \
  38. ({ \
  39. u64 _m = mask; \
  40. (_m << 16) | FIELD_PREP(_m, value); \
  41. })
  42. struct sp_pll {
  43. struct clk_hw hw;
  44. void __iomem *reg;
  45. spinlock_t lock; /* lock for reg */
  46. int div_shift;
  47. int div_width;
  48. int pd_bit; /* power down bit idx */
  49. int bp_bit; /* bypass bit idx */
  50. unsigned long brate; /* base rate, TODO: replace brate with muldiv */
  51. u32 p[P_MAX]; /* for hold PLLTV/PLLA parameters */
  52. };
  53. #define to_sp_pll(_hw) container_of(_hw, struct sp_pll, hw)
  54. struct sp_clk_gate_info {
  55. u16 reg; /* reg_index_shift */
  56. u16 ext_parent; /* parent is extclk */
  57. };
  58. static const struct sp_clk_gate_info sp_clk_gates[] = {
  59. { 0x02 },
  60. { 0x05 },
  61. { 0x06 },
  62. { 0x07 },
  63. { 0x09 },
  64. { 0x0b, 1 },
  65. { 0x0f, 1 },
  66. { 0x14 },
  67. { 0x15 },
  68. { 0x16 },
  69. { 0x17 },
  70. { 0x18, 1 },
  71. { 0x19, 1 },
  72. { 0x1a, 1 },
  73. { 0x1b, 1 },
  74. { 0x1c, 1 },
  75. { 0x1d, 1 },
  76. { 0x1e },
  77. { 0x1f, 1 },
  78. { 0x20 },
  79. { 0x21 },
  80. { 0x22 },
  81. { 0x23 },
  82. { 0x24 },
  83. { 0x25 },
  84. { 0x26 },
  85. { 0x2a },
  86. { 0x2b },
  87. { 0x2d },
  88. { 0x2e },
  89. { 0x30 },
  90. { 0x31 },
  91. { 0x32 },
  92. { 0x33 },
  93. { 0x3d },
  94. { 0x3e },
  95. { 0x3f },
  96. { 0x42 },
  97. { 0x44 },
  98. { 0x4b },
  99. { 0x4c },
  100. { 0x4d },
  101. { 0x4e },
  102. { 0x4f },
  103. { 0x50 },
  104. { 0x55 },
  105. { 0x60 },
  106. { 0x61 },
  107. { 0x6a },
  108. { 0x73 },
  109. { 0x86 },
  110. { 0x8a },
  111. { 0x8b },
  112. { 0x8d },
  113. { 0x8e },
  114. { 0x8f },
  115. { 0x90 },
  116. { 0x92 },
  117. { 0x93 },
  118. { 0x95 },
  119. { 0x96 },
  120. { 0x97 },
  121. { 0x98 },
  122. { 0x99 },
  123. };
  124. #define _M 1000000UL
  125. #define F_27M (27 * _M)
  126. /*********************************** PLL_TV **********************************/
  127. /* TODO: set proper FVCO range */
  128. #define FVCO_MIN (100 * _M)
  129. #define FVCO_MAX (200 * _M)
  130. #define F_MIN (FVCO_MIN / 8)
  131. #define F_MAX (FVCO_MAX)
  132. static long plltv_integer_div(struct sp_pll *clk, unsigned long freq)
  133. {
  134. /* valid m values: 27M must be divisible by m */
  135. static const u32 m_table[] = {
  136. 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32
  137. };
  138. u32 m, n, r;
  139. unsigned long fvco, nf;
  140. long ret;
  141. freq = clamp(freq, F_MIN, F_MAX);
  142. /* DIVR 0~3 */
  143. for (r = 0; r <= 3; r++) {
  144. fvco = freq << r;
  145. if (fvco <= FVCO_MAX)
  146. break;
  147. }
  148. /* DIVM */
  149. for (m = 0; m < ARRAY_SIZE(m_table); m++) {
  150. nf = fvco * m_table[m];
  151. n = nf / F_27M;
  152. if ((n * F_27M) == nf)
  153. break;
  154. }
  155. if (m >= ARRAY_SIZE(m_table)) {
  156. ret = -EINVAL;
  157. goto err_not_found;
  158. }
  159. /* save parameters */
  160. clk->p[SEL_FRA] = 0;
  161. clk->p[DIVR] = r;
  162. clk->p[DIVN] = n;
  163. clk->p[DIVM] = m_table[m];
  164. return freq;
  165. err_not_found:
  166. pr_err("%s: %s freq:%lu not found a valid setting\n",
  167. __func__, clk_hw_get_name(&clk->hw), freq);
  168. return ret;
  169. }
  170. /* parameters for PLLTV fractional divider */
  171. static const u32 pt[][5] = {
  172. /* conventional fractional */
  173. {
  174. 1, /* factor */
  175. 5, /* 5 * p0 (nint) */
  176. 1, /* 1 * p0 */
  177. F_27M, /* F_27M / p0 */
  178. 1, /* p0 / p2 */
  179. },
  180. /* phase rotation */
  181. {
  182. 10, /* factor */
  183. 54, /* 5.4 * p0 (nint) */
  184. 2, /* 0.2 * p0 */
  185. F_27M / 10, /* F_27M / p0 */
  186. 5, /* p0 / p2 */
  187. },
  188. };
  189. static const u32 sdm_mod_vals[] = { 91, 55 };
  190. static long plltv_fractional_div(struct sp_pll *clk, unsigned long freq)
  191. {
  192. u32 m, r;
  193. u32 nint, nfra;
  194. u32 df_quotient_min = 210000000;
  195. u32 df_remainder_min = 0;
  196. unsigned long fvco, nf, f, fout = 0;
  197. int sdm, ph;
  198. freq = clamp(freq, F_MIN, F_MAX);
  199. /* DIVR 0~3 */
  200. for (r = 0; r <= 3; r++) {
  201. fvco = freq << r;
  202. if (fvco <= FVCO_MAX)
  203. break;
  204. }
  205. f = F_27M >> r;
  206. /* PH_SEL */
  207. for (ph = ARRAY_SIZE(pt) - 1; ph >= 0; ph--) {
  208. const u32 *pp = pt[ph];
  209. /* SDM_MOD */
  210. for (sdm = 0; sdm < ARRAY_SIZE(sdm_mod_vals); sdm++) {
  211. u32 mod = sdm_mod_vals[sdm];
  212. /* DIVM 1~32 */
  213. for (m = 1; m <= 32; m++) {
  214. u32 df; /* diff freq */
  215. u32 df_quotient, df_remainder;
  216. nf = fvco * m;
  217. nint = nf / pp[3];
  218. if (nint < pp[1])
  219. continue;
  220. if (nint > pp[1])
  221. break;
  222. nfra = (((nf % pp[3]) * mod * pp[4]) + (F_27M / 2)) / F_27M;
  223. if (nfra) {
  224. u32 df0 = f * (nint + pp[2]) / pp[0];
  225. u32 df1 = f * (mod - nfra) / mod / pp[4];
  226. df = df0 - df1;
  227. } else {
  228. df = f * (nint) / pp[0];
  229. }
  230. df_quotient = df / m;
  231. df_remainder = ((df % m) * 1000) / m;
  232. if (freq > df_quotient) {
  233. df_quotient = freq - df_quotient - 1;
  234. df_remainder = 1000 - df_remainder;
  235. } else {
  236. df_quotient = df_quotient - freq;
  237. }
  238. if (df_quotient_min > df_quotient ||
  239. (df_quotient_min == df_quotient &&
  240. df_remainder_min > df_remainder)) {
  241. /* found a closer freq, save parameters */
  242. clk->p[SEL_FRA] = 1;
  243. clk->p[SDM_MOD] = sdm;
  244. clk->p[PH_SEL] = ph;
  245. clk->p[NFRA] = nfra;
  246. clk->p[DIVR] = r;
  247. clk->p[DIVM] = m;
  248. fout = df / m;
  249. df_quotient_min = df_quotient;
  250. df_remainder_min = df_remainder;
  251. }
  252. }
  253. }
  254. }
  255. if (!fout) {
  256. pr_err("%s: %s freq:%lu not found a valid setting\n",
  257. __func__, clk_hw_get_name(&clk->hw), freq);
  258. return -EINVAL;
  259. }
  260. return fout;
  261. }
  262. static long plltv_div(struct sp_pll *clk, unsigned long freq)
  263. {
  264. if (freq % 100)
  265. return plltv_fractional_div(clk, freq);
  266. return plltv_integer_div(clk, freq);
  267. }
  268. static int plltv_set_rate(struct sp_pll *clk)
  269. {
  270. unsigned long flags;
  271. u32 r0, r1, r2;
  272. r0 = BIT(clk->bp_bit + 16);
  273. r0 |= HWM_FIELD_PREP(MASK_SEL_FRA, clk->p[SEL_FRA]);
  274. r0 |= HWM_FIELD_PREP(MASK_SDM_MOD, clk->p[SDM_MOD]);
  275. r0 |= HWM_FIELD_PREP(MASK_PH_SEL, clk->p[PH_SEL]);
  276. r0 |= HWM_FIELD_PREP(MASK_NFRA, clk->p[NFRA]);
  277. r1 = HWM_FIELD_PREP(MASK_DIVR, clk->p[DIVR]);
  278. r2 = HWM_FIELD_PREP(MASK_DIVN, clk->p[DIVN] - 1);
  279. r2 |= HWM_FIELD_PREP(MASK_DIVM, clk->p[DIVM] - 1);
  280. spin_lock_irqsave(&clk->lock, flags);
  281. writel(r0, clk->reg);
  282. writel(r1, clk->reg + 4);
  283. writel(r2, clk->reg + 8);
  284. spin_unlock_irqrestore(&clk->lock, flags);
  285. return 0;
  286. }
  287. /*********************************** PLL_A ***********************************/
  288. /* from Q628_PLLs_REG_setting.xlsx */
  289. static const struct {
  290. u32 rate;
  291. u32 regs[5];
  292. } pa[] = {
  293. {
  294. .rate = 135475200,
  295. .regs = {
  296. 0x4801,
  297. 0x02df,
  298. 0x248f,
  299. 0x0211,
  300. 0x33e9
  301. }
  302. },
  303. {
  304. .rate = 147456000,
  305. .regs = {
  306. 0x4801,
  307. 0x1adf,
  308. 0x2490,
  309. 0x0349,
  310. 0x33e9
  311. }
  312. },
  313. {
  314. .rate = 196608000,
  315. .regs = {
  316. 0x4801,
  317. 0x42ef,
  318. 0x2495,
  319. 0x01c6,
  320. 0x33e9
  321. }
  322. },
  323. };
  324. static int plla_set_rate(struct sp_pll *clk)
  325. {
  326. const u32 *pp = pa[clk->p[0]].regs;
  327. unsigned long flags;
  328. int i;
  329. spin_lock_irqsave(&clk->lock, flags);
  330. for (i = 0; i < ARRAY_SIZE(pa->regs); i++)
  331. writel(0xffff0000 | pp[i], clk->reg + (i * 4));
  332. spin_unlock_irqrestore(&clk->lock, flags);
  333. return 0;
  334. }
  335. static long plla_round_rate(struct sp_pll *clk, unsigned long rate)
  336. {
  337. int i = ARRAY_SIZE(pa);
  338. while (--i) {
  339. if (rate >= pa[i].rate)
  340. break;
  341. }
  342. clk->p[0] = i;
  343. return pa[i].rate;
  344. }
  345. /********************************** SP_PLL ***********************************/
  346. static long sp_pll_calc_div(struct sp_pll *clk, unsigned long rate)
  347. {
  348. u32 fbdiv;
  349. u32 max = 1 << clk->div_width;
  350. fbdiv = DIV_ROUND_CLOSEST(rate, clk->brate);
  351. if (fbdiv > max)
  352. fbdiv = max;
  353. return fbdiv;
  354. }
  355. static long sp_pll_round_rate(struct clk_hw *hw, unsigned long rate,
  356. unsigned long *prate)
  357. {
  358. struct sp_pll *clk = to_sp_pll(hw);
  359. long ret;
  360. if (rate == *prate) {
  361. ret = *prate; /* bypass */
  362. } else if (clk->div_width == DIV_A) {
  363. ret = plla_round_rate(clk, rate);
  364. } else if (clk->div_width == DIV_TV) {
  365. ret = plltv_div(clk, rate);
  366. if (ret < 0)
  367. ret = *prate;
  368. } else {
  369. ret = sp_pll_calc_div(clk, rate) * clk->brate;
  370. }
  371. return ret;
  372. }
  373. static unsigned long sp_pll_recalc_rate(struct clk_hw *hw,
  374. unsigned long prate)
  375. {
  376. struct sp_pll *clk = to_sp_pll(hw);
  377. u32 reg = readl(clk->reg);
  378. unsigned long ret;
  379. if (reg & BIT(clk->bp_bit)) {
  380. ret = prate; /* bypass */
  381. } else if (clk->div_width == DIV_A) {
  382. ret = pa[clk->p[0]].rate;
  383. } else if (clk->div_width == DIV_TV) {
  384. u32 m, r, reg2;
  385. r = FIELD_GET(MASK_DIVR, readl(clk->reg + 4));
  386. reg2 = readl(clk->reg + 8);
  387. m = FIELD_GET(MASK_DIVM, reg2) + 1;
  388. if (reg & MASK_SEL_FRA) {
  389. /* fractional divider */
  390. u32 sdm = FIELD_GET(MASK_SDM_MOD, reg);
  391. u32 ph = FIELD_GET(MASK_PH_SEL, reg);
  392. u32 nfra = FIELD_GET(MASK_NFRA, reg);
  393. const u32 *pp = pt[ph];
  394. unsigned long r0, r1;
  395. ret = prate >> r;
  396. r0 = ret * (pp[1] + pp[2]) / pp[0];
  397. r1 = ret * (sdm_mod_vals[sdm] - nfra) / sdm_mod_vals[sdm] / pp[4];
  398. ret = (r0 - r1) / m;
  399. } else {
  400. /* integer divider */
  401. u32 n = FIELD_GET(MASK_DIVN, reg2) + 1;
  402. ret = (prate / m * n) >> r;
  403. }
  404. } else {
  405. u32 fbdiv = ((reg >> clk->div_shift) & ((1 << clk->div_width) - 1)) + 1;
  406. ret = clk->brate * fbdiv;
  407. }
  408. return ret;
  409. }
  410. static int sp_pll_set_rate(struct clk_hw *hw, unsigned long rate,
  411. unsigned long prate)
  412. {
  413. struct sp_pll *clk = to_sp_pll(hw);
  414. unsigned long flags;
  415. u32 reg;
  416. reg = BIT(clk->bp_bit + 16); /* HIWORD_MASK */
  417. if (rate == prate) {
  418. reg |= BIT(clk->bp_bit); /* bypass */
  419. } else if (clk->div_width == DIV_A) {
  420. return plla_set_rate(clk);
  421. } else if (clk->div_width == DIV_TV) {
  422. return plltv_set_rate(clk);
  423. } else if (clk->div_width) {
  424. u32 fbdiv = sp_pll_calc_div(clk, rate);
  425. u32 mask = GENMASK(clk->div_shift + clk->div_width - 1, clk->div_shift);
  426. reg |= mask << 16;
  427. reg |= ((fbdiv - 1) << clk->div_shift) & mask;
  428. }
  429. spin_lock_irqsave(&clk->lock, flags);
  430. writel(reg, clk->reg);
  431. spin_unlock_irqrestore(&clk->lock, flags);
  432. return 0;
  433. }
  434. static int sp_pll_enable(struct clk_hw *hw)
  435. {
  436. struct sp_pll *clk = to_sp_pll(hw);
  437. writel(BIT(clk->pd_bit + 16) | BIT(clk->pd_bit), clk->reg);
  438. return 0;
  439. }
  440. static void sp_pll_disable(struct clk_hw *hw)
  441. {
  442. struct sp_pll *clk = to_sp_pll(hw);
  443. writel(BIT(clk->pd_bit + 16), clk->reg);
  444. }
  445. static int sp_pll_is_enabled(struct clk_hw *hw)
  446. {
  447. struct sp_pll *clk = to_sp_pll(hw);
  448. return readl(clk->reg) & BIT(clk->pd_bit);
  449. }
  450. static const struct clk_ops sp_pll_ops = {
  451. .enable = sp_pll_enable,
  452. .disable = sp_pll_disable,
  453. .is_enabled = sp_pll_is_enabled,
  454. .round_rate = sp_pll_round_rate,
  455. .recalc_rate = sp_pll_recalc_rate,
  456. .set_rate = sp_pll_set_rate
  457. };
  458. static const struct clk_ops sp_pll_sub_ops = {
  459. .enable = sp_pll_enable,
  460. .disable = sp_pll_disable,
  461. .is_enabled = sp_pll_is_enabled,
  462. .recalc_rate = sp_pll_recalc_rate,
  463. };
  464. static struct clk_hw *sp_pll_register(struct device *dev, const char *name,
  465. const struct clk_parent_data *parent_data,
  466. void __iomem *reg, int pd_bit, int bp_bit,
  467. unsigned long brate, int shift, int width,
  468. unsigned long flags)
  469. {
  470. struct sp_pll *pll;
  471. struct clk_hw *hw;
  472. struct clk_init_data initd = {
  473. .name = name,
  474. .parent_data = parent_data,
  475. .ops = (bp_bit >= 0) ? &sp_pll_ops : &sp_pll_sub_ops,
  476. .num_parents = 1,
  477. .flags = flags,
  478. };
  479. int ret;
  480. pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
  481. if (!pll)
  482. return ERR_PTR(-ENOMEM);
  483. pll->hw.init = &initd;
  484. pll->reg = reg;
  485. pll->pd_bit = pd_bit;
  486. pll->bp_bit = bp_bit;
  487. pll->brate = brate;
  488. pll->div_shift = shift;
  489. pll->div_width = width;
  490. spin_lock_init(&pll->lock);
  491. hw = &pll->hw;
  492. ret = devm_clk_hw_register(dev, hw);
  493. if (ret)
  494. return ERR_PTR(ret);
  495. return hw;
  496. }
  497. #define PLLA_CTL (pll_base + 0x1c)
  498. #define PLLE_CTL (pll_base + 0x30)
  499. #define PLLF_CTL (pll_base + 0x34)
  500. #define PLLTV_CTL (pll_base + 0x38)
  501. static int sp7021_clk_probe(struct platform_device *pdev)
  502. {
  503. static const u32 sp_clken[] = {
  504. 0x67ef, 0x03ff, 0xff03, 0xfff0, 0x0004, /* G0.1~5 */
  505. 0x0000, 0x8000, 0xffff, 0x0040, 0x0000, /* G0.6~10 */
  506. };
  507. static struct clk_parent_data pd_ext, pd_sys, pd_e;
  508. struct device *dev = &pdev->dev;
  509. void __iomem *clk_base, *pll_base, *sys_base;
  510. struct clk_hw_onecell_data *clk_data;
  511. struct clk_hw **hws;
  512. int i;
  513. clk_base = devm_platform_ioremap_resource(pdev, 0);
  514. if (IS_ERR(clk_base))
  515. return PTR_ERR(clk_base);
  516. pll_base = devm_platform_ioremap_resource(pdev, 1);
  517. if (IS_ERR(pll_base))
  518. return PTR_ERR(pll_base);
  519. sys_base = devm_platform_ioremap_resource(pdev, 2);
  520. if (IS_ERR(sys_base))
  521. return PTR_ERR(sys_base);
  522. /* enable default clks */
  523. for (i = 0; i < ARRAY_SIZE(sp_clken); i++)
  524. writel((sp_clken[i] << 16) | sp_clken[i], clk_base + i * 4);
  525. clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, CLK_MAX),
  526. GFP_KERNEL);
  527. if (!clk_data)
  528. return -ENOMEM;
  529. clk_data->num = CLK_MAX;
  530. hws = clk_data->hws;
  531. pd_ext.index = 0;
  532. /* PLLs */
  533. hws[PLL_A] = sp_pll_register(dev, "plla", &pd_ext, PLLA_CTL,
  534. 11, 12, 27000000, 0, DIV_A, 0);
  535. if (IS_ERR(hws[PLL_A]))
  536. return PTR_ERR(hws[PLL_A]);
  537. hws[PLL_E] = sp_pll_register(dev, "plle", &pd_ext, PLLE_CTL,
  538. 6, 2, 50000000, 0, 0, 0);
  539. if (IS_ERR(hws[PLL_E]))
  540. return PTR_ERR(hws[PLL_E]);
  541. pd_e.hw = hws[PLL_E];
  542. hws[PLL_E_2P5] = sp_pll_register(dev, "plle_2p5", &pd_e, PLLE_CTL,
  543. 13, -1, 2500000, 0, 0, 0);
  544. if (IS_ERR(hws[PLL_E_2P5]))
  545. return PTR_ERR(hws[PLL_E_2P5]);
  546. hws[PLL_E_25] = sp_pll_register(dev, "plle_25", &pd_e, PLLE_CTL,
  547. 12, -1, 25000000, 0, 0, 0);
  548. if (IS_ERR(hws[PLL_E_25]))
  549. return PTR_ERR(hws[PLL_E_25]);
  550. hws[PLL_E_112P5] = sp_pll_register(dev, "plle_112p5", &pd_e, PLLE_CTL,
  551. 11, -1, 112500000, 0, 0, 0);
  552. if (IS_ERR(hws[PLL_E_112P5]))
  553. return PTR_ERR(hws[PLL_E_112P5]);
  554. hws[PLL_F] = sp_pll_register(dev, "pllf", &pd_ext, PLLF_CTL,
  555. 0, 10, 13500000, 1, 4, 0);
  556. if (IS_ERR(hws[PLL_F]))
  557. return PTR_ERR(hws[PLL_F]);
  558. hws[PLL_TV] = sp_pll_register(dev, "plltv", &pd_ext, PLLTV_CTL,
  559. 0, 15, 27000000, 0, DIV_TV, 0);
  560. if (IS_ERR(hws[PLL_TV]))
  561. return PTR_ERR(hws[PLL_TV]);
  562. hws[PLL_TV_A] = devm_clk_hw_register_divider(dev, "plltv_a", "plltv", 0,
  563. PLLTV_CTL + 4, 5, 1,
  564. CLK_DIVIDER_POWER_OF_TWO,
  565. &to_sp_pll(hws[PLL_TV])->lock);
  566. if (IS_ERR(hws[PLL_TV_A]))
  567. return PTR_ERR(hws[PLL_TV_A]);
  568. /* system clock, should not be disabled */
  569. hws[PLL_SYS] = sp_pll_register(dev, "pllsys", &pd_ext, sys_base,
  570. 10, 9, 13500000, 0, 4, CLK_IS_CRITICAL);
  571. if (IS_ERR(hws[PLL_SYS]))
  572. return PTR_ERR(hws[PLL_SYS]);
  573. pd_sys.hw = hws[PLL_SYS];
  574. /* gates */
  575. for (i = 0; i < ARRAY_SIZE(sp_clk_gates); i++) {
  576. char name[10];
  577. u32 j = sp_clk_gates[i].reg;
  578. struct clk_parent_data *pd = sp_clk_gates[i].ext_parent ? &pd_ext : &pd_sys;
  579. sprintf(name, "%02d_0x%02x", i, j);
  580. hws[i] = devm_clk_hw_register_gate_parent_data(dev, name, pd, 0,
  581. clk_base + (j >> 4) * 4,
  582. j & 0x0f,
  583. CLK_GATE_HIWORD_MASK,
  584. NULL);
  585. if (IS_ERR(hws[i]))
  586. return PTR_ERR(hws[i]);
  587. }
  588. return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
  589. }
  590. static const struct of_device_id sp7021_clk_dt_ids[] = {
  591. { .compatible = "sunplus,sp7021-clkc" },
  592. { }
  593. };
  594. MODULE_DEVICE_TABLE(of, sp7021_clk_dt_ids);
  595. static struct platform_driver sp7021_clk_driver = {
  596. .probe = sp7021_clk_probe,
  597. .driver = {
  598. .name = "sp7021-clk",
  599. .of_match_table = sp7021_clk_dt_ids,
  600. },
  601. };
  602. module_platform_driver(sp7021_clk_driver);
  603. MODULE_AUTHOR("Sunplus Technology");
  604. MODULE_LICENSE("GPL");
  605. MODULE_DESCRIPTION("Clock driver for Sunplus SP7021 SoC");