pwm-fsl-ftm.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Freescale FlexTimer Module (FTM) PWM Driver
  4. *
  5. * Copyright 2012-2013 Freescale Semiconductor, Inc.
  6. * Copyright 2020-2025 NXP
  7. */
  8. #include <linux/clk.h>
  9. #include <linux/err.h>
  10. #include <linux/io.h>
  11. #include <linux/kernel.h>
  12. #include <linux/module.h>
  13. #include <linux/of.h>
  14. #include <linux/platform_device.h>
  15. #include <linux/pm.h>
  16. #include <linux/pwm.h>
  17. #include <linux/regmap.h>
  18. #include <linux/slab.h>
  19. #include <linux/fsl/ftm.h>
  20. #define FTM_SC_CLK(c) (((c) + 1) << FTM_SC_CLK_MASK_SHIFT)
  21. enum fsl_pwm_clk {
  22. FSL_PWM_CLK_SYS,
  23. FSL_PWM_CLK_FIX,
  24. FSL_PWM_CLK_EXT,
  25. FSL_PWM_CLK_CNTEN,
  26. FSL_PWM_CLK_MAX
  27. };
  28. struct fsl_ftm_soc {
  29. bool has_enable_bits;
  30. bool has_flt_reg;
  31. unsigned int npwm;
  32. };
  33. struct fsl_pwm_periodcfg {
  34. enum fsl_pwm_clk clk_select;
  35. unsigned int clk_ps;
  36. unsigned int mod_period;
  37. };
  38. struct fsl_pwm_chip {
  39. struct regmap *regmap;
  40. /* This value is valid iff a pwm is running */
  41. struct fsl_pwm_periodcfg period;
  42. struct clk *ipg_clk;
  43. struct clk *clk[FSL_PWM_CLK_MAX];
  44. const struct fsl_ftm_soc *soc;
  45. };
  46. static inline struct fsl_pwm_chip *to_fsl_chip(struct pwm_chip *chip)
  47. {
  48. return pwmchip_get_drvdata(chip);
  49. }
  50. static void ftm_clear_write_protection(struct fsl_pwm_chip *fpc)
  51. {
  52. u32 val;
  53. regmap_read(fpc->regmap, FTM_FMS, &val);
  54. if (val & FTM_FMS_WPEN)
  55. regmap_set_bits(fpc->regmap, FTM_MODE, FTM_MODE_WPDIS);
  56. }
  57. static void ftm_set_write_protection(struct fsl_pwm_chip *fpc)
  58. {
  59. regmap_set_bits(fpc->regmap, FTM_FMS, FTM_FMS_WPEN);
  60. }
  61. static bool fsl_pwm_periodcfg_are_equal(const struct fsl_pwm_periodcfg *a,
  62. const struct fsl_pwm_periodcfg *b)
  63. {
  64. if (a->clk_select != b->clk_select)
  65. return false;
  66. if (a->clk_ps != b->clk_ps)
  67. return false;
  68. if (a->mod_period != b->mod_period)
  69. return false;
  70. return true;
  71. }
  72. static int fsl_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
  73. {
  74. int ret;
  75. struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
  76. ret = clk_prepare_enable(fpc->ipg_clk);
  77. if (!ret && fpc->soc->has_enable_bits)
  78. regmap_set_bits(fpc->regmap, FTM_SC, BIT(pwm->hwpwm + 16));
  79. return ret;
  80. }
  81. static void fsl_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
  82. {
  83. struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
  84. if (fpc->soc->has_enable_bits)
  85. regmap_clear_bits(fpc->regmap, FTM_SC, BIT(pwm->hwpwm + 16));
  86. clk_disable_unprepare(fpc->ipg_clk);
  87. }
  88. static unsigned int fsl_pwm_ticks_to_ns(struct fsl_pwm_chip *fpc,
  89. unsigned int ticks)
  90. {
  91. unsigned long rate;
  92. unsigned long long exval;
  93. rate = clk_get_rate(fpc->clk[fpc->period.clk_select]);
  94. if (rate >> fpc->period.clk_ps == 0)
  95. return 0;
  96. exval = ticks;
  97. exval *= 1000000000UL;
  98. do_div(exval, rate >> fpc->period.clk_ps);
  99. return exval;
  100. }
  101. static bool fsl_pwm_calculate_period_clk(struct fsl_pwm_chip *fpc,
  102. unsigned int period_ns,
  103. enum fsl_pwm_clk index,
  104. struct fsl_pwm_periodcfg *periodcfg
  105. )
  106. {
  107. unsigned long long c;
  108. unsigned int ps;
  109. c = clk_get_rate(fpc->clk[index]);
  110. c = c * period_ns;
  111. do_div(c, 1000000000UL);
  112. if (c == 0)
  113. return false;
  114. for (ps = 0; ps < 8 ; ++ps, c >>= 1) {
  115. if (c <= 0x10000) {
  116. periodcfg->clk_select = index;
  117. periodcfg->clk_ps = ps;
  118. periodcfg->mod_period = c - 1;
  119. return true;
  120. }
  121. }
  122. return false;
  123. }
  124. static bool fsl_pwm_calculate_period(struct fsl_pwm_chip *fpc,
  125. unsigned int period_ns,
  126. struct fsl_pwm_periodcfg *periodcfg)
  127. {
  128. enum fsl_pwm_clk m0, m1;
  129. unsigned long fix_rate, ext_rate;
  130. bool ret;
  131. ret = fsl_pwm_calculate_period_clk(fpc, period_ns, FSL_PWM_CLK_SYS,
  132. periodcfg);
  133. if (ret)
  134. return true;
  135. fix_rate = clk_get_rate(fpc->clk[FSL_PWM_CLK_FIX]);
  136. ext_rate = clk_get_rate(fpc->clk[FSL_PWM_CLK_EXT]);
  137. if (fix_rate > ext_rate) {
  138. m0 = FSL_PWM_CLK_FIX;
  139. m1 = FSL_PWM_CLK_EXT;
  140. } else {
  141. m0 = FSL_PWM_CLK_EXT;
  142. m1 = FSL_PWM_CLK_FIX;
  143. }
  144. ret = fsl_pwm_calculate_period_clk(fpc, period_ns, m0, periodcfg);
  145. if (ret)
  146. return true;
  147. return fsl_pwm_calculate_period_clk(fpc, period_ns, m1, periodcfg);
  148. }
  149. static unsigned int fsl_pwm_calculate_duty(struct fsl_pwm_chip *fpc,
  150. unsigned int duty_ns)
  151. {
  152. unsigned long long duty;
  153. unsigned int period = fpc->period.mod_period + 1;
  154. unsigned int period_ns = fsl_pwm_ticks_to_ns(fpc, period);
  155. if (!period_ns)
  156. return 0;
  157. duty = (unsigned long long)duty_ns * period;
  158. do_div(duty, period_ns);
  159. return (unsigned int)duty;
  160. }
  161. static bool fsl_pwm_is_any_pwm_enabled(struct fsl_pwm_chip *fpc,
  162. struct pwm_device *pwm)
  163. {
  164. u32 val;
  165. regmap_read(fpc->regmap, FTM_OUTMASK, &val);
  166. if (~val & 0xFF)
  167. return true;
  168. else
  169. return false;
  170. }
  171. static bool fsl_pwm_is_other_pwm_enabled(struct fsl_pwm_chip *fpc,
  172. struct pwm_device *pwm)
  173. {
  174. u32 val;
  175. regmap_read(fpc->regmap, FTM_OUTMASK, &val);
  176. if (~(val | BIT(pwm->hwpwm)) & 0xFF)
  177. return true;
  178. else
  179. return false;
  180. }
  181. static int fsl_pwm_apply_config(struct pwm_chip *chip,
  182. struct pwm_device *pwm,
  183. const struct pwm_state *newstate)
  184. {
  185. struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
  186. unsigned int duty;
  187. u32 reg_polarity;
  188. struct fsl_pwm_periodcfg periodcfg;
  189. bool do_write_period = false;
  190. if (!fsl_pwm_calculate_period(fpc, newstate->period, &periodcfg)) {
  191. dev_err(pwmchip_parent(chip), "failed to calculate new period\n");
  192. return -EINVAL;
  193. }
  194. if (!fsl_pwm_is_any_pwm_enabled(fpc, pwm))
  195. do_write_period = true;
  196. /*
  197. * The Freescale FTM controller supports only a single period for
  198. * all PWM channels, therefore verify if the newly computed period
  199. * is different than the current period being used. In such case
  200. * we allow to change the period only if no other pwm is running.
  201. */
  202. else if (!fsl_pwm_periodcfg_are_equal(&fpc->period, &periodcfg)) {
  203. if (fsl_pwm_is_other_pwm_enabled(fpc, pwm)) {
  204. dev_err(pwmchip_parent(chip),
  205. "Cannot change period for PWM %u, disable other PWMs first\n",
  206. pwm->hwpwm);
  207. return -EBUSY;
  208. }
  209. if (fpc->period.clk_select != periodcfg.clk_select) {
  210. int ret;
  211. enum fsl_pwm_clk oldclk = fpc->period.clk_select;
  212. enum fsl_pwm_clk newclk = periodcfg.clk_select;
  213. ret = clk_prepare_enable(fpc->clk[newclk]);
  214. if (ret)
  215. return ret;
  216. clk_disable_unprepare(fpc->clk[oldclk]);
  217. }
  218. do_write_period = true;
  219. }
  220. ftm_clear_write_protection(fpc);
  221. if (do_write_period) {
  222. regmap_update_bits(fpc->regmap, FTM_SC, FTM_SC_CLK_MASK,
  223. FTM_SC_CLK(periodcfg.clk_select));
  224. regmap_update_bits(fpc->regmap, FTM_SC, FTM_SC_PS_MASK,
  225. periodcfg.clk_ps);
  226. regmap_write(fpc->regmap, FTM_MOD, periodcfg.mod_period);
  227. fpc->period = periodcfg;
  228. }
  229. duty = fsl_pwm_calculate_duty(fpc, newstate->duty_cycle);
  230. regmap_write(fpc->regmap, FTM_CSC(pwm->hwpwm),
  231. FTM_CSC_MSB | FTM_CSC_ELSB);
  232. regmap_write(fpc->regmap, FTM_CV(pwm->hwpwm), duty);
  233. reg_polarity = 0;
  234. if (newstate->polarity == PWM_POLARITY_INVERSED)
  235. reg_polarity = BIT(pwm->hwpwm);
  236. regmap_update_bits(fpc->regmap, FTM_POL, BIT(pwm->hwpwm), reg_polarity);
  237. ftm_set_write_protection(fpc);
  238. return 0;
  239. }
  240. static int fsl_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
  241. const struct pwm_state *newstate)
  242. {
  243. struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
  244. struct pwm_state *oldstate = &pwm->state;
  245. int ret;
  246. /*
  247. * oldstate to newstate : action
  248. *
  249. * disabled to disabled : ignore
  250. * enabled to disabled : disable
  251. * enabled to enabled : update settings
  252. * disabled to enabled : update settings + enable
  253. */
  254. if (!newstate->enabled) {
  255. if (oldstate->enabled) {
  256. regmap_set_bits(fpc->regmap, FTM_OUTMASK,
  257. BIT(pwm->hwpwm));
  258. clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_CNTEN]);
  259. clk_disable_unprepare(fpc->clk[fpc->period.clk_select]);
  260. }
  261. return 0;
  262. }
  263. ret = fsl_pwm_apply_config(chip, pwm, newstate);
  264. if (ret)
  265. return ret;
  266. /* check if need to enable */
  267. if (!oldstate->enabled) {
  268. ret = clk_prepare_enable(fpc->clk[fpc->period.clk_select]);
  269. if (ret)
  270. return ret;
  271. ret = clk_prepare_enable(fpc->clk[FSL_PWM_CLK_CNTEN]);
  272. if (ret) {
  273. clk_disable_unprepare(fpc->clk[fpc->period.clk_select]);
  274. return ret;
  275. }
  276. regmap_clear_bits(fpc->regmap, FTM_OUTMASK, BIT(pwm->hwpwm));
  277. }
  278. return ret;
  279. }
  280. static const struct pwm_ops fsl_pwm_ops = {
  281. .request = fsl_pwm_request,
  282. .free = fsl_pwm_free,
  283. .apply = fsl_pwm_apply,
  284. };
  285. static int fsl_pwm_init(struct fsl_pwm_chip *fpc)
  286. {
  287. int ret;
  288. ret = clk_prepare_enable(fpc->ipg_clk);
  289. if (ret)
  290. return ret;
  291. regmap_write(fpc->regmap, FTM_CNTIN, 0x00);
  292. regmap_write(fpc->regmap, FTM_OUTINIT, 0x00);
  293. regmap_write(fpc->regmap, FTM_OUTMASK, 0xFF);
  294. clk_disable_unprepare(fpc->ipg_clk);
  295. return 0;
  296. }
  297. static bool fsl_pwm_volatile_reg(struct device *dev, unsigned int reg)
  298. {
  299. switch (reg) {
  300. case FTM_FMS:
  301. case FTM_MODE:
  302. case FTM_CNT:
  303. return true;
  304. }
  305. return false;
  306. }
  307. static bool fsl_pwm_is_reg(struct device *dev, unsigned int reg)
  308. {
  309. struct pwm_chip *chip = dev_get_drvdata(dev);
  310. struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
  311. if (reg >= FTM_CSC(fpc->soc->npwm) && reg < FTM_CNTIN)
  312. return false;
  313. if ((reg == FTM_FLTCTRL || reg == FTM_FLTPOL) && !fpc->soc->has_flt_reg)
  314. return false;
  315. return true;
  316. }
  317. static const struct regmap_config fsl_pwm_regmap_config = {
  318. .reg_bits = 32,
  319. .reg_stride = 4,
  320. .val_bits = 32,
  321. .max_register = FTM_PWMLOAD,
  322. .volatile_reg = fsl_pwm_volatile_reg,
  323. .cache_type = REGCACHE_FLAT,
  324. .writeable_reg = fsl_pwm_is_reg,
  325. .readable_reg = fsl_pwm_is_reg,
  326. };
  327. static int fsl_pwm_probe(struct platform_device *pdev)
  328. {
  329. const struct fsl_ftm_soc *soc = of_device_get_match_data(&pdev->dev);
  330. struct pwm_chip *chip;
  331. struct fsl_pwm_chip *fpc;
  332. void __iomem *base;
  333. int ret;
  334. chip = devm_pwmchip_alloc(&pdev->dev, soc->npwm, sizeof(*fpc));
  335. if (IS_ERR(chip))
  336. return PTR_ERR(chip);
  337. fpc = to_fsl_chip(chip);
  338. fpc->soc = soc;
  339. base = devm_platform_ioremap_resource(pdev, 0);
  340. if (IS_ERR(base))
  341. return PTR_ERR(base);
  342. fpc->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "ftm_sys", base,
  343. &fsl_pwm_regmap_config);
  344. if (IS_ERR(fpc->regmap)) {
  345. dev_err(&pdev->dev, "regmap init failed\n");
  346. return PTR_ERR(fpc->regmap);
  347. }
  348. fpc->clk[FSL_PWM_CLK_SYS] = devm_clk_get(&pdev->dev, "ftm_sys");
  349. if (IS_ERR(fpc->clk[FSL_PWM_CLK_SYS])) {
  350. dev_err(&pdev->dev, "failed to get \"ftm_sys\" clock\n");
  351. return PTR_ERR(fpc->clk[FSL_PWM_CLK_SYS]);
  352. }
  353. fpc->clk[FSL_PWM_CLK_FIX] = devm_clk_get(&pdev->dev, "ftm_fix");
  354. if (IS_ERR(fpc->clk[FSL_PWM_CLK_FIX]))
  355. return PTR_ERR(fpc->clk[FSL_PWM_CLK_FIX]);
  356. fpc->clk[FSL_PWM_CLK_EXT] = devm_clk_get(&pdev->dev, "ftm_ext");
  357. if (IS_ERR(fpc->clk[FSL_PWM_CLK_EXT]))
  358. return PTR_ERR(fpc->clk[FSL_PWM_CLK_EXT]);
  359. fpc->clk[FSL_PWM_CLK_CNTEN] =
  360. devm_clk_get(&pdev->dev, "ftm_cnt_clk_en");
  361. if (IS_ERR(fpc->clk[FSL_PWM_CLK_CNTEN]))
  362. return PTR_ERR(fpc->clk[FSL_PWM_CLK_CNTEN]);
  363. /*
  364. * ipg_clk is the interface clock for the IP. If not provided, use the
  365. * ftm_sys clock as the default.
  366. */
  367. fpc->ipg_clk = devm_clk_get(&pdev->dev, "ipg");
  368. if (IS_ERR(fpc->ipg_clk))
  369. fpc->ipg_clk = fpc->clk[FSL_PWM_CLK_SYS];
  370. chip->ops = &fsl_pwm_ops;
  371. ret = devm_pwmchip_add(&pdev->dev, chip);
  372. if (ret < 0) {
  373. dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
  374. return ret;
  375. }
  376. platform_set_drvdata(pdev, chip);
  377. return fsl_pwm_init(fpc);
  378. }
  379. #ifdef CONFIG_PM_SLEEP
  380. static int fsl_pwm_suspend(struct device *dev)
  381. {
  382. struct pwm_chip *chip = dev_get_drvdata(dev);
  383. struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
  384. int i;
  385. regcache_cache_only(fpc->regmap, true);
  386. regcache_mark_dirty(fpc->regmap);
  387. for (i = 0; i < chip->npwm; i++) {
  388. struct pwm_device *pwm = &chip->pwms[i];
  389. if (!test_bit(PWMF_REQUESTED, &pwm->flags))
  390. continue;
  391. clk_disable_unprepare(fpc->ipg_clk);
  392. if (!pwm_is_enabled(pwm))
  393. continue;
  394. clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_CNTEN]);
  395. clk_disable_unprepare(fpc->clk[fpc->period.clk_select]);
  396. }
  397. return 0;
  398. }
  399. static int fsl_pwm_resume(struct device *dev)
  400. {
  401. struct pwm_chip *chip = dev_get_drvdata(dev);
  402. struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
  403. int i;
  404. for (i = 0; i < chip->npwm; i++) {
  405. struct pwm_device *pwm = &chip->pwms[i];
  406. if (!test_bit(PWMF_REQUESTED, &pwm->flags))
  407. continue;
  408. clk_prepare_enable(fpc->ipg_clk);
  409. if (!pwm_is_enabled(pwm))
  410. continue;
  411. clk_prepare_enable(fpc->clk[fpc->period.clk_select]);
  412. clk_prepare_enable(fpc->clk[FSL_PWM_CLK_CNTEN]);
  413. }
  414. /* restore all registers from cache */
  415. regcache_cache_only(fpc->regmap, false);
  416. regcache_sync(fpc->regmap);
  417. return 0;
  418. }
  419. #endif
  420. static const struct dev_pm_ops fsl_pwm_pm_ops = {
  421. SET_SYSTEM_SLEEP_PM_OPS(fsl_pwm_suspend, fsl_pwm_resume)
  422. };
  423. static const struct fsl_ftm_soc vf610_ftm_pwm = {
  424. .has_enable_bits = false,
  425. .has_flt_reg = true,
  426. .npwm = 8,
  427. };
  428. static const struct fsl_ftm_soc imx8qm_ftm_pwm = {
  429. .has_enable_bits = true,
  430. .has_flt_reg = true,
  431. .npwm = 8,
  432. };
  433. static const struct fsl_ftm_soc s32g2_ftm_pwm = {
  434. .has_enable_bits = true,
  435. .has_flt_reg = false,
  436. .npwm = 6,
  437. };
  438. static const struct of_device_id fsl_pwm_dt_ids[] = {
  439. { .compatible = "fsl,vf610-ftm-pwm", .data = &vf610_ftm_pwm },
  440. { .compatible = "fsl,imx8qm-ftm-pwm", .data = &imx8qm_ftm_pwm },
  441. { .compatible = "nxp,s32g2-ftm-pwm", .data = &s32g2_ftm_pwm },
  442. { /* sentinel */ }
  443. };
  444. MODULE_DEVICE_TABLE(of, fsl_pwm_dt_ids);
  445. static struct platform_driver fsl_pwm_driver = {
  446. .driver = {
  447. .name = "fsl-ftm-pwm",
  448. .of_match_table = fsl_pwm_dt_ids,
  449. .pm = &fsl_pwm_pm_ops,
  450. },
  451. .probe = fsl_pwm_probe,
  452. };
  453. module_platform_driver(fsl_pwm_driver);
  454. MODULE_DESCRIPTION("Freescale FlexTimer Module PWM Driver");
  455. MODULE_AUTHOR("Xiubo Li <Li.Xiubo@freescale.com>");
  456. MODULE_ALIAS("platform:fsl-ftm-pwm");
  457. MODULE_LICENSE("GPL");