pwm.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <plat_private.h>
  7. #include <pmu.h>
  8. #include <pwm.h>
  9. #include <soc.h>
  10. #define PWM0_IOMUX_PWM_EN (1 << 0)
  11. #define PWM1_IOMUX_PWM_EN (1 << 1)
  12. #define PWM2_IOMUX_PWM_EN (1 << 2)
  13. #define PWM3_IOMUX_PWM_EN (1 << 3)
  14. struct pwm_data_s {
  15. uint32_t iomux_bitmask;
  16. uint32_t enable_bitmask;
  17. };
  18. static struct pwm_data_s pwm_data;
  19. /*
  20. * Disable the PWMs.
  21. */
  22. void disable_pwms(void)
  23. {
  24. uint32_t i, val;
  25. pwm_data.iomux_bitmask = 0;
  26. /* Save PWMs pinmux and change PWMs pinmux to GPIOs */
  27. val = mmio_read_32(GRF_BASE + GRF_GPIO4C_IOMUX);
  28. if (((val >> GRF_GPIO4C2_IOMUX_SHIFT) &
  29. GRF_IOMUX_2BIT_MASK) == GRF_GPIO4C2_IOMUX_PWM) {
  30. pwm_data.iomux_bitmask |= PWM0_IOMUX_PWM_EN;
  31. val = BITS_WITH_WMASK(GRF_IOMUX_GPIO, GRF_IOMUX_2BIT_MASK,
  32. GRF_GPIO4C2_IOMUX_SHIFT);
  33. mmio_write_32(GRF_BASE + GRF_GPIO4C_IOMUX, val);
  34. }
  35. val = mmio_read_32(GRF_BASE + GRF_GPIO4C_IOMUX);
  36. if (((val >> GRF_GPIO4C6_IOMUX_SHIFT) &
  37. GRF_IOMUX_2BIT_MASK) == GRF_GPIO4C6_IOMUX_PWM) {
  38. pwm_data.iomux_bitmask |= PWM1_IOMUX_PWM_EN;
  39. val = BITS_WITH_WMASK(GRF_IOMUX_GPIO, GRF_IOMUX_2BIT_MASK,
  40. GRF_GPIO4C6_IOMUX_SHIFT);
  41. mmio_write_32(GRF_BASE + GRF_GPIO4C_IOMUX, val);
  42. }
  43. val = mmio_read_32(PMUGRF_BASE + PMUGRF_GPIO1C_IOMUX);
  44. if (((val >> PMUGRF_GPIO1C3_IOMUX_SHIFT) &
  45. GRF_IOMUX_2BIT_MASK) == PMUGRF_GPIO1C3_IOMUX_PWM) {
  46. pwm_data.iomux_bitmask |= PWM2_IOMUX_PWM_EN;
  47. val = BITS_WITH_WMASK(GRF_IOMUX_GPIO, GRF_IOMUX_2BIT_MASK,
  48. PMUGRF_GPIO1C3_IOMUX_SHIFT);
  49. mmio_write_32(PMUGRF_BASE + PMUGRF_GPIO1C_IOMUX, val);
  50. }
  51. val = mmio_read_32(PMUGRF_BASE + PMUGRF_GPIO0A_IOMUX);
  52. if (((val >> PMUGRF_GPIO0A6_IOMUX_SHIFT) &
  53. GRF_IOMUX_2BIT_MASK) == PMUGRF_GPIO0A6_IOMUX_PWM) {
  54. pwm_data.iomux_bitmask |= PWM3_IOMUX_PWM_EN;
  55. val = BITS_WITH_WMASK(GRF_IOMUX_GPIO, GRF_IOMUX_2BIT_MASK,
  56. PMUGRF_GPIO0A6_IOMUX_SHIFT);
  57. mmio_write_32(PMUGRF_BASE + PMUGRF_GPIO0A_IOMUX, val);
  58. }
  59. /* Disable the pwm channel */
  60. pwm_data.enable_bitmask = 0;
  61. for (i = 0; i < 4; i++) {
  62. val = mmio_read_32(PWM_BASE + PWM_CTRL(i));
  63. if ((val & PWM_ENABLE) != PWM_ENABLE)
  64. continue;
  65. pwm_data.enable_bitmask |= (1 << i);
  66. mmio_write_32(PWM_BASE + PWM_CTRL(i), val & ~PWM_ENABLE);
  67. }
  68. }
  69. /*
  70. * Enable the PWMs.
  71. */
  72. void enable_pwms(void)
  73. {
  74. uint32_t i, val;
  75. for (i = 0; i < 4; i++) {
  76. val = mmio_read_32(PWM_BASE + PWM_CTRL(i));
  77. if (!(pwm_data.enable_bitmask & (1 << i)))
  78. continue;
  79. mmio_write_32(PWM_BASE + PWM_CTRL(i), val | PWM_ENABLE);
  80. }
  81. /* Restore all IOMUXes */
  82. if (pwm_data.iomux_bitmask & PWM3_IOMUX_PWM_EN) {
  83. val = BITS_WITH_WMASK(PMUGRF_GPIO0A6_IOMUX_PWM,
  84. GRF_IOMUX_2BIT_MASK,
  85. PMUGRF_GPIO0A6_IOMUX_SHIFT);
  86. mmio_write_32(PMUGRF_BASE + PMUGRF_GPIO0A_IOMUX, val);
  87. }
  88. if (pwm_data.iomux_bitmask & PWM2_IOMUX_PWM_EN) {
  89. val = BITS_WITH_WMASK(PMUGRF_GPIO1C3_IOMUX_PWM,
  90. GRF_IOMUX_2BIT_MASK,
  91. PMUGRF_GPIO1C3_IOMUX_SHIFT);
  92. mmio_write_32(PMUGRF_BASE + PMUGRF_GPIO1C_IOMUX, val);
  93. }
  94. if (pwm_data.iomux_bitmask & PWM1_IOMUX_PWM_EN) {
  95. val = BITS_WITH_WMASK(GRF_GPIO4C6_IOMUX_PWM,
  96. GRF_IOMUX_2BIT_MASK,
  97. GRF_GPIO4C6_IOMUX_SHIFT);
  98. mmio_write_32(GRF_BASE + GRF_GPIO4C_IOMUX, val);
  99. }
  100. if (pwm_data.iomux_bitmask & PWM0_IOMUX_PWM_EN) {
  101. val = BITS_WITH_WMASK(GRF_GPIO4C2_IOMUX_PWM,
  102. GRF_IOMUX_2BIT_MASK,
  103. GRF_GPIO4C2_IOMUX_SHIFT);
  104. mmio_write_32(GRF_BASE + GRF_GPIO4C_IOMUX, val);
  105. }
  106. }