pwm-imx-util.c 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. /*
  2. * (C) Copyright 2014
  3. * Heiko Schocher, DENX Software Engineering, hs@denx.de.
  4. *
  5. * Basic support for the pwm modul on imx6.
  6. *
  7. * Based on linux:drivers/pwm/pwm-imx.c
  8. * from
  9. * Sascha Hauer <s.hauer@pengutronix.de>
  10. *
  11. * SPDX-License-Identifier: GPL-2.0
  12. */
  13. #include <common.h>
  14. #include <div64.h>
  15. #include <asm/arch/imx-regs.h>
  16. /* pwm_id from 0..3 */
  17. struct pwm_regs *pwm_id_to_reg(int pwm_id)
  18. {
  19. switch (pwm_id) {
  20. case 0:
  21. return (struct pwm_regs *)PWM1_BASE_ADDR;
  22. break;
  23. case 1:
  24. return (struct pwm_regs *)PWM2_BASE_ADDR;
  25. break;
  26. case 2:
  27. return (struct pwm_regs *)PWM3_BASE_ADDR;
  28. break;
  29. case 3:
  30. return (struct pwm_regs *)PWM4_BASE_ADDR;
  31. break;
  32. default:
  33. printf("unknown pwm_id: %d\n", pwm_id);
  34. break;
  35. }
  36. return NULL;
  37. }
  38. int pwm_imx_get_parms(int period_ns, int duty_ns, unsigned long *period_c,
  39. unsigned long *duty_c, unsigned long *prescale)
  40. {
  41. unsigned long long c;
  42. /*
  43. * we have not yet a clock framework for imx6, so add the clock
  44. * value here as a define. Replace it when we have the clock
  45. * framework.
  46. */
  47. c = CONFIG_IMX6_PWM_PER_CLK;
  48. c = c * period_ns;
  49. do_div(c, 1000000000);
  50. *period_c = c;
  51. *prescale = *period_c / 0x10000 + 1;
  52. *period_c /= *prescale;
  53. c = (unsigned long long)(*period_c * duty_ns);
  54. do_div(c, period_ns);
  55. *duty_c = c;
  56. /*
  57. * according to imx pwm RM, the real period value should be
  58. * PERIOD value in PWMPR plus 2.
  59. */
  60. if (*period_c > 2)
  61. *period_c -= 2;
  62. else
  63. *period_c = 0;
  64. return 0;
  65. }