pwm-imx-util.c 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. /*
  2. * (C) Copyright 2014
  3. * Heiko Schocher, DENX Software Engineering, hs@denx.de.
  4. *
  5. * Basic support for the pwm module 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..7 */
  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. case 1:
  23. return (struct pwm_regs *)PWM2_BASE_ADDR;
  24. case 2:
  25. return (struct pwm_regs *)PWM3_BASE_ADDR;
  26. case 3:
  27. return (struct pwm_regs *)PWM4_BASE_ADDR;
  28. #ifdef CONFIG_MX6SX
  29. case 4:
  30. return (struct pwm_regs *)PWM5_BASE_ADDR;
  31. case 5:
  32. return (struct pwm_regs *)PWM6_BASE_ADDR;
  33. case 6:
  34. return (struct pwm_regs *)PWM7_BASE_ADDR;
  35. case 7:
  36. return (struct pwm_regs *)PWM8_BASE_ADDR;
  37. #endif
  38. default:
  39. printf("unknown pwm_id: %d\n", pwm_id);
  40. break;
  41. }
  42. return NULL;
  43. }
  44. int pwm_imx_get_parms(int period_ns, int duty_ns, unsigned long *period_c,
  45. unsigned long *duty_c, unsigned long *prescale)
  46. {
  47. unsigned long long c;
  48. /*
  49. * we have not yet a clock framework for imx6, so add the clock
  50. * value here as a define. Replace it when we have the clock
  51. * framework.
  52. */
  53. c = CONFIG_IMX6_PWM_PER_CLK;
  54. c = c * period_ns;
  55. do_div(c, 1000000000);
  56. *period_c = c;
  57. *prescale = *period_c / 0x10000 + 1;
  58. *period_c /= *prescale;
  59. c = *period_c * (unsigned long long)duty_ns;
  60. do_div(c, period_ns);
  61. *duty_c = c;
  62. /*
  63. * according to imx pwm RM, the real period value should be
  64. * PERIOD value in PWMPR plus 2.
  65. */
  66. if (*period_c > 2)
  67. *period_c -= 2;
  68. else
  69. *period_c = 0;
  70. return 0;
  71. }