pwm-imx-util.c 1.7 KB

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