pwm-imx-util.c 1.7 KB

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