pwm-pru.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * PWM driver for PRU PWM controller
  4. *
  5. * Copyright (C) 2019 by Texas Instruments Incorporated - http://www.ti.com/
  6. * Author: Bin Liu <b-liu@ti.com>
  7. */
  8. #include <linux/module.h>
  9. #include <linux/of_irq.h>
  10. #include <linux/of_platform.h>
  11. #include <linux/pruss.h>
  12. #include <linux/pwm.h>
  13. #include <linux/regmap.h>
  14. #include <linux/remoteproc.h>
  15. #define PP_FW_MAGIC_NUMBER 0x4d575047 /* "GPWM" */
  16. #define PP_NUM_CHIPS 2
  17. #define PPC_NUM_PWMS 12
  18. /*
  19. * PWM duty cycle and period thresholds in ns. PWM output is undefined
  20. * if its duty cycle or period is out of the range. Valid settings:
  21. * period: 10us ~ 2sec
  22. * duty cycle: 400ns ~ (period - 400ns)
  23. */
  24. #define PP_MIN_DUTY_NS 400
  25. #define PP_MIN_PERIOD_NS 10000
  26. #define PP_MAX_PERIOD_NS 2000000000 /* 2 sec */
  27. /* global registers */
  28. #define PP_FW_MAGIC 0x00
  29. #define PP_FW_VERSION 0x08
  30. #define PP_CTRL 0x14
  31. #define PP_STAT 0x18
  32. /* PP_CTRL bits */
  33. #define PP_CTRL_IEP_EN BIT(0)
  34. #define PP_CHIP0_OFFSET 0x1c
  35. #define PP_CHIP1_OFFSET 0x68
  36. /* pwm chip register offsets */
  37. #define PPC_PWM_CFG 0x00
  38. #define PPC_PWM_EN 0x08
  39. #define PPC_PWM_PERIOD 0x0c /* holds half of period_ns value */
  40. #define PPC_PWM_DC0 0x10
  41. #define PPC_PWM_DC(x) (PPC_PWM_DC0 + ((x) << 2))
  42. /* PP_PWM_RECFG bits */
  43. #define PPC_PWM_CFG_DC0 BIT(2)
  44. #define PPC_PWM_CFG_DC_MASK GENMASK(13, 2)
  45. #define PPC_PWM_CFG_COMMIT 1
  46. enum {
  47. PWMEN_UPDATE,
  48. PRD_UPDATE,
  49. MAX_REGFIELDS
  50. };
  51. #define to_pru_pwmchip(c) container_of((c), struct pru_pwmchip, chip)
  52. struct pru_pwmchip {
  53. struct pwm_chip chip;
  54. int period_owner;
  55. spinlock_t period_lock; /* lock to serialize pwm period access */
  56. struct regmap *map;
  57. struct regmap_field *pwmen_update;
  58. struct regmap_field *period_update;
  59. };
  60. struct pru_pwm {
  61. struct device *dev;
  62. struct rproc *pru;
  63. struct pruss *pruss;
  64. int pru_id;
  65. struct pruss_mem_region mem;
  66. struct regmap *map;
  67. struct regmap_field *fw_inited;
  68. };
  69. static const struct regmap_config ppc_regmap_config = {
  70. .reg_bits = 32,
  71. .reg_stride = 4,
  72. .val_bits = 32,
  73. .max_register = PPC_PWM_DC(PPC_NUM_PWMS - 1),
  74. };
  75. static const struct reg_field ppc_regfields[MAX_REGFIELDS] = {
  76. [PWMEN_UPDATE] = REG_FIELD(PPC_PWM_CFG, 0, 0),
  77. [PRD_UPDATE] = REG_FIELD(PPC_PWM_CFG, 1, 1),
  78. };
  79. static struct regmap_config pp_regmap_config = {
  80. .reg_bits = 32,
  81. .reg_stride = 4,
  82. .val_bits = 32,
  83. .max_register = PP_STAT,
  84. };
  85. static const struct reg_field pp_regfield = REG_FIELD(PP_STAT, 3, 3);
  86. static int prupwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
  87. int duty_ns, int period_ns)
  88. {
  89. struct pru_pwmchip *ppc = to_pru_pwmchip(chip);
  90. int duty;
  91. int idx;
  92. int ret = 0;
  93. spin_lock(&ppc->period_lock);
  94. if (period_ns < PP_MIN_PERIOD_NS || period_ns > PP_MAX_PERIOD_NS) {
  95. ret = -EINVAL;
  96. goto out;
  97. }
  98. /* check whether period has been set by another pwm */
  99. if (period_ns != pwm_get_period(pwm) && ppc->period_owner != -1 &&
  100. ppc->period_owner != pwm->hwpwm) {
  101. ret = -EACCES;
  102. goto out;
  103. }
  104. if ((duty_ns && duty_ns < PP_MIN_DUTY_NS) ||
  105. duty_ns > period_ns - PP_MIN_DUTY_NS) {
  106. ret = -EINVAL;
  107. goto out;
  108. }
  109. if (period_ns != pwm_get_period(pwm)) {
  110. for (idx = 0; idx < chip->npwm; idx++) {
  111. /* skip current pwm device */
  112. if (idx == pwm->hwpwm)
  113. continue;
  114. /*
  115. * the period is global to all pwms, so it cannot be
  116. * less than the duty cycle of any pwm.
  117. */
  118. duty = pwm_get_duty_cycle(&chip->pwms[idx]);
  119. if (period_ns >= duty)
  120. continue;
  121. dev_err(chip->dev, "Error: new period (%d) is less than pwm%d duty cycle (%d)\n",
  122. period_ns, idx, duty);
  123. ret = -EINVAL;
  124. goto out;
  125. }
  126. ppc->period_owner = pwm->hwpwm;
  127. kobject_uevent(&chip->dev->kobj, KOBJ_CHANGE);
  128. /* update the new period in pwm->state for all pwms */
  129. for (idx = 0; idx < chip->npwm; idx++)
  130. pwm_set_period(&chip->pwms[idx], period_ns);
  131. /* the pwm period register holds half of the period value */
  132. regmap_write(ppc->map, PPC_PWM_PERIOD, period_ns >> 1);
  133. regmap_field_write(ppc->period_update, PPC_PWM_CFG_COMMIT);
  134. }
  135. regmap_write(ppc->map, PPC_PWM_DC(pwm->hwpwm), duty_ns);
  136. regmap_update_bits(ppc->map, PPC_PWM_CFG, PPC_PWM_CFG_DC0 << pwm->hwpwm,
  137. PPC_PWM_CFG_DC0 << pwm->hwpwm);
  138. out:
  139. spin_unlock(&ppc->period_lock);
  140. return ret;
  141. }
  142. static int prupwm_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
  143. {
  144. struct pru_pwmchip *ppc = to_pru_pwmchip(chip);
  145. regmap_update_bits(ppc->map, PPC_PWM_EN, BIT(pwm->hwpwm),
  146. BIT(pwm->hwpwm));
  147. regmap_field_write(ppc->pwmen_update, PPC_PWM_CFG_COMMIT);
  148. return 0;
  149. }
  150. static void prupwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
  151. {
  152. struct pru_pwmchip *ppc = to_pru_pwmchip(chip);
  153. regmap_update_bits(ppc->map, PPC_PWM_EN, BIT(pwm->hwpwm), 0);
  154. regmap_field_write(ppc->pwmen_update, PPC_PWM_CFG_COMMIT);
  155. }
  156. /* default period register value might not be 0, update it in pwm->state */
  157. static void prupwm_pwm_get_init_state(struct pwm_chip *chip,
  158. struct pwm_device *pwm,
  159. struct pwm_state *state)
  160. {
  161. struct pru_pwmchip *ppc = to_pru_pwmchip(chip);
  162. int period;
  163. regmap_read(ppc->map, PPC_PWM_PERIOD, &period);
  164. pwm_set_period(pwm, period << 1);
  165. }
  166. static void prupwm_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
  167. {
  168. struct pru_pwmchip *ppc = to_pru_pwmchip(chip);
  169. /* set pwm duty cycle register to 0 */
  170. regmap_write(ppc->map, PPC_PWM_DC(pwm->hwpwm), 0);
  171. regmap_update_bits(ppc->map, PPC_PWM_CFG, PPC_PWM_CFG_DC0 << pwm->hwpwm,
  172. PPC_PWM_CFG_DC0 << pwm->hwpwm);
  173. pwm_set_duty_cycle(pwm, 0);
  174. spin_lock(&ppc->period_lock);
  175. if (ppc->period_owner == pwm->hwpwm) {
  176. ppc->period_owner = -1;
  177. kobject_uevent(&chip->dev->kobj, KOBJ_CHANGE);
  178. }
  179. spin_unlock(&ppc->period_lock);
  180. }
  181. static const struct pwm_ops prupwm_pwm_ops = {
  182. .config = prupwm_pwm_config,
  183. .enable = prupwm_pwm_enable,
  184. .disable = prupwm_pwm_disable,
  185. .get_state = prupwm_pwm_get_init_state,
  186. .free = prupwm_pwm_free,
  187. .owner = THIS_MODULE,
  188. };
  189. static const struct of_device_id pru_pwmchip_of_match[] = {
  190. { .compatible = "ti,pru-pwmchip", },
  191. {},
  192. };
  193. MODULE_DEVICE_TABLE(of, pru_pwmchip_of_match);
  194. #ifdef CONFIG_PWM_SYSFS
  195. static int prupwm_uevent(struct device *dev, struct kobj_uevent_env *env)
  196. {
  197. struct pwm_chip *chip = dev_get_drvdata(dev);
  198. struct pru_pwmchip *ppc = to_pru_pwmchip(chip);
  199. int ret;
  200. ret = add_uevent_var(env, "PERIOD_OWNER=%d", ppc->period_owner);
  201. return ret;
  202. }
  203. #endif
  204. static int pru_pwmchip_probe(struct platform_device *pdev)
  205. {
  206. struct device *dev = &pdev->dev;
  207. struct platform_device *parent = to_platform_device(dev->parent);
  208. struct pru_pwm *pp = platform_get_drvdata(parent);
  209. struct pru_pwmchip *ppc;
  210. void __iomem *mbase;
  211. int idx, ret;
  212. ppc = devm_kzalloc(pp->dev, sizeof(*ppc), GFP_KERNEL);
  213. if (!ppc)
  214. return -ENOMEM;
  215. ret = of_property_read_u32(dev->of_node, "reg", &idx);
  216. if (ret || idx < 0 || idx >= PP_NUM_CHIPS)
  217. return -EINVAL;
  218. platform_set_drvdata(pdev, ppc);
  219. spin_lock_init(&ppc->period_lock);
  220. ppc->period_owner = -1;
  221. mbase = pp->mem.va + (idx ? PP_CHIP1_OFFSET : PP_CHIP0_OFFSET);
  222. ppc->map = devm_regmap_init_mmio(dev, mbase, &ppc_regmap_config);
  223. if (IS_ERR(ppc->map)) {
  224. dev_err(dev, "failed to init regmap (%d)\n", ret);
  225. return PTR_ERR(ppc->map);
  226. }
  227. ppc->pwmen_update =
  228. devm_regmap_field_alloc(dev, ppc->map,
  229. ppc_regfields[PWMEN_UPDATE]);
  230. if (IS_ERR(ppc->pwmen_update))
  231. return PTR_ERR(ppc->pwmen_update);
  232. ppc->period_update =
  233. devm_regmap_field_alloc(dev, ppc->map,
  234. ppc_regfields[PRD_UPDATE]);
  235. if (IS_ERR(ppc->period_update))
  236. return PTR_ERR(ppc->period_update);
  237. ppc->chip.dev = dev;
  238. ppc->chip.ops = &prupwm_pwm_ops;
  239. ppc->chip.base = -1;
  240. ppc->chip.npwm = PPC_NUM_PWMS;
  241. /* set initial duty cycle register of all pwms to 0 */
  242. for (idx = 0; idx < PPC_NUM_PWMS; idx++)
  243. regmap_write(ppc->map, PPC_PWM_DC(idx), 0);
  244. /* commit the duty cycle config changes */
  245. regmap_write(ppc->map, PPC_PWM_CFG, PPC_PWM_CFG_DC_MASK);
  246. ret = pwmchip_add(&ppc->chip);
  247. if (ret)
  248. dev_err(dev, "pwmchip_add() failed: %d\n", ret);
  249. #ifdef CONFIG_PWM_SYSFS
  250. if (ppc->chip.sysfs_dev)
  251. ppc->chip.sysfs_dev->class->dev_uevent = prupwm_uevent;
  252. #endif
  253. return ret;
  254. }
  255. static int pru_pwmchip_remove(struct platform_device *pdev)
  256. {
  257. struct pru_pwmchip *ppc = platform_get_drvdata(pdev);
  258. return pwmchip_remove(&ppc->chip);
  259. }
  260. static struct platform_driver pru_pwmchip_driver = {
  261. .driver = {
  262. .name = "pru_pwmchip",
  263. .of_match_table = pru_pwmchip_of_match,
  264. },
  265. .probe = pru_pwmchip_probe,
  266. .remove = pru_pwmchip_remove,
  267. };
  268. static int prupwm_init_prufw(struct device_node *np, struct pru_pwm *pp)
  269. {
  270. struct device *dev = pp->dev;
  271. struct device_node *child;
  272. enum pruss_mem mem_id;
  273. u32 reg, id;
  274. int ret = 0;
  275. pp->pru = pru_rproc_get(np, 0);
  276. if (IS_ERR(pp->pru)) {
  277. ret = PTR_ERR(pp->pru);
  278. if (ret != -EPROBE_DEFER)
  279. dev_err(dev, "failed to get pru (%d)\n", ret);
  280. return ret;
  281. }
  282. pp->pruss = pruss_get(pp->pru);
  283. if (IS_ERR(pp->pruss)) {
  284. ret = PTR_ERR(pp->pruss);
  285. dev_err(dev, "failed to get pruss handle (%d)\n", ret);
  286. goto put_pru;
  287. }
  288. pp->pru_id = pru_rproc_get_id(pp->pru);
  289. if (pp->pru_id < 0) {
  290. dev_err(dev, "failed to get pru id (%d)\n", pp->pru_id);
  291. ret = -EINVAL;
  292. goto put_pruss;
  293. }
  294. if (pp->pru_id > 1) {
  295. dev_err(dev, "invalid pru id (%d)\n", pp->pru_id);
  296. ret = -EINVAL;
  297. goto put_pruss;
  298. }
  299. mem_id = pp->pru_id ? PRUSS_MEM_DRAM1 : PRUSS_MEM_DRAM0;
  300. ret = pruss_request_mem_region(pp->pruss, mem_id, &pp->mem);
  301. if (ret) {
  302. dev_err(dev, "failed to get pruss mem region (%d)\n", ret);
  303. goto put_pruss;
  304. }
  305. pp->map = devm_regmap_init_mmio(dev, pp->mem.va, &pp_regmap_config);
  306. if (IS_ERR(pp->map)) {
  307. ret = PTR_ERR(pp->map);
  308. dev_err(dev, "failed to init register map (%d)\n", ret);
  309. goto put_mem;
  310. }
  311. pp->fw_inited = devm_regmap_field_alloc(dev, pp->map, pp_regfield);
  312. if (IS_ERR(pp->fw_inited)) {
  313. ret = PTR_ERR(pp->fw_inited);
  314. goto put_mem;
  315. }
  316. /* clear the mem region before firmware runs by rproc_boot() */
  317. memset_io(pp->mem.va, 0, pp->mem.size);
  318. ret = rproc_boot(pp->pru);
  319. if (ret) {
  320. dev_err(dev, "failed to boot pru (%d)\n", ret);
  321. goto put_mem;
  322. }
  323. regmap_read(pp->map, PP_FW_MAGIC, &reg);
  324. if (reg != PP_FW_MAGIC_NUMBER) {
  325. dev_err(dev, "invalid firmware magic number\n");
  326. ret = -EINVAL;
  327. goto put_rproc;
  328. }
  329. regmap_read(pp->map, PP_FW_VERSION, &reg);
  330. if (reg > 0x01000000) {
  331. dev_err(dev, "unsupported firmware version(0x%x)\n", reg);
  332. ret = -EINVAL;
  333. goto put_rproc;
  334. }
  335. reg = 0;
  336. for_each_available_child_of_node(np, child) {
  337. ret = of_property_read_u32(child, "reg", &id);
  338. if (ret || id >= PP_NUM_CHIPS) {
  339. dev_err(dev, "invalid pwmchip id %d (%d)\n", id, ret);
  340. ret = -EINVAL;
  341. goto put_rproc;
  342. }
  343. reg |= 1 << (id + 1);
  344. }
  345. if (reg)
  346. reg |= PP_CTRL_IEP_EN;
  347. regmap_write(pp->map, PP_CTRL, reg);
  348. /* check for firmware init completion, timeout in 100us */
  349. ret = regmap_field_read_poll_timeout(pp->fw_inited, reg, reg, 0, 100);
  350. if (ret == -ETIMEDOUT)
  351. dev_err(dev, "failed to initialize firmware\n");
  352. else if (!ret)
  353. return 0;
  354. put_rproc:
  355. rproc_shutdown(pp->pru);
  356. put_mem:
  357. pruss_release_mem_region(pp->pruss, &pp->mem);
  358. put_pruss:
  359. pruss_put(pp->pruss);
  360. put_pru:
  361. pru_rproc_put(pp->pru);
  362. return ret;
  363. }
  364. static int prupwm_exit_pruss(struct pru_pwm *pp)
  365. {
  366. int ret;
  367. rproc_shutdown(pp->pru);
  368. ret = pruss_release_mem_region(pp->pruss, &pp->mem);
  369. if (ret)
  370. return ret;
  371. pruss_put(pp->pruss);
  372. pru_rproc_put(pp->pru);
  373. return 0;
  374. }
  375. static const struct of_device_id prupwm_of_match[] = {
  376. { .compatible = "ti,pru-pwm", },
  377. {},
  378. };
  379. MODULE_DEVICE_TABLE(of, prupwm_of_match);
  380. static int prupwm_probe(struct platform_device *pdev)
  381. {
  382. struct pru_pwm *pp;
  383. struct device *dev = &pdev->dev;
  384. struct device_node *np = dev->of_node;
  385. int ret;
  386. if (!np)
  387. return -ENODEV; /* non-DT not supported */
  388. pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
  389. if (!pp)
  390. return -ENOMEM;
  391. pp->dev = dev;
  392. ret = prupwm_init_prufw(np, pp);
  393. if (ret < 0)
  394. return -ENODEV;
  395. platform_set_drvdata(pdev, pp);
  396. ret = of_platform_populate(np, NULL, NULL, dev);
  397. if (ret) {
  398. dev_err(dev, "failed to create pwmchip\n");
  399. prupwm_exit_pruss(pp);
  400. return ret;
  401. }
  402. return 0;
  403. }
  404. static int prupwm_remove(struct platform_device *pdev)
  405. {
  406. struct pru_pwm *pp = platform_get_drvdata(pdev);
  407. of_platform_depopulate(&pdev->dev);
  408. return prupwm_exit_pruss(pp);
  409. }
  410. static struct platform_driver prupwm_driver = {
  411. .driver = {
  412. .name = "prupwm",
  413. .of_match_table = prupwm_of_match,
  414. },
  415. .probe = prupwm_probe,
  416. .remove = prupwm_remove,
  417. };
  418. static int __init prupwm_init(void)
  419. {
  420. int ret;
  421. ret = platform_driver_register(&pru_pwmchip_driver);
  422. if (ret)
  423. return ret;
  424. ret = platform_driver_register(&prupwm_driver);
  425. if (ret)
  426. platform_driver_unregister(&pru_pwmchip_driver);
  427. return ret;
  428. }
  429. module_init(prupwm_init);
  430. static void __exit prupwm_exit(void)
  431. {
  432. platform_driver_unregister(&prupwm_driver);
  433. platform_driver_unregister(&pru_pwmchip_driver);
  434. }
  435. module_exit(prupwm_exit);
  436. MODULE_AUTHOR("Bin Liu <b-liu@ti.com>");
  437. MODULE_DESCRIPTION("PRU PWM Driver");
  438. MODULE_LICENSE("GPL v2");