hal_avs.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. #include <sunxi_hal_common.h>
  2. #include <sunxi_hal_avs.h>
  3. #include <interrupt.h>
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. static hal_sunxi_avs hal_avs[AVS_NUM];
  7. int hal_avs_continue(hal_avs_id_t id)
  8. {
  9. u32 val;
  10. hal_sunxi_avs *avs;
  11. if (id >= AVS_NUM)
  12. {
  13. AVS_ERR("avs id is too big!!!\n");
  14. return -1;
  15. }
  16. avs = &hal_avs[id];
  17. val = hal_readl(avs->base + AVS_CNT_CTRL_REG);
  18. val &= ~(1 << (id + 8));
  19. hal_writel(val, avs->base + AVS_CNT_CTRL_REG);
  20. return 0;
  21. }
  22. int hal_avs_pause(hal_avs_id_t id)
  23. {
  24. u32 val;
  25. hal_sunxi_avs *avs;
  26. if (id >= AVS_NUM)
  27. {
  28. AVS_ERR("avs id is too big!!!\n");
  29. return -1;
  30. }
  31. avs = &hal_avs[id];
  32. val = hal_readl(avs->base + AVS_CNT_CTRL_REG);
  33. val |= (1 << (id + 8));
  34. hal_writel(val, avs->base + AVS_CNT_CTRL_REG);
  35. return 0;
  36. }
  37. int hal_avs_disable(hal_avs_id_t id)
  38. {
  39. u32 val;
  40. hal_sunxi_avs *avs;
  41. if (id >= AVS_NUM)
  42. {
  43. AVS_ERR("avs id is too big!!!\n");
  44. return -1;
  45. }
  46. avs = &hal_avs[id];
  47. val = hal_readl(avs->base + AVS_CNT_CTRL_REG);
  48. val &= ~(1 << id);
  49. hal_writel(val, avs->base + AVS_CNT_CTRL_REG);
  50. return 0;
  51. }
  52. int hal_avs_enable(hal_avs_id_t id)
  53. {
  54. u32 val;
  55. hal_sunxi_avs *avs;
  56. if (id >= AVS_NUM)
  57. {
  58. AVS_ERR("avs id is too big!!!\n");
  59. return -1;
  60. }
  61. avs = &hal_avs[id];
  62. val = hal_readl(avs->base + AVS_CNT_CTRL_REG);
  63. val |= (1 << id);
  64. hal_writel(val, avs->base + AVS_CNT_CTRL_REG);
  65. return 0;
  66. }
  67. int hal_avs_get_counter(hal_avs_id_t id, u32 *counter)
  68. {
  69. hal_sunxi_avs *avs;
  70. if (id >= AVS_NUM)
  71. {
  72. AVS_ERR("avs id is too big!!!\n");
  73. return -1;
  74. }
  75. avs = &hal_avs[id];
  76. *counter = hal_readl(avs->base + AVS_CNT_REG(id));
  77. return 0;
  78. }
  79. int hal_avs_set_counter(hal_avs_id_t id, u32 counter)
  80. {
  81. hal_sunxi_avs *avs;
  82. if (id >= AVS_NUM)
  83. {
  84. AVS_ERR("avs id is too big!!!\n");
  85. return -1;
  86. }
  87. avs = &hal_avs[id];
  88. hal_writel(counter, avs->base + AVS_CNT_REG(id));
  89. return 0;
  90. }
  91. int hal_avs_set_cnt_div(hal_avs_id_t id, u32 div)
  92. {
  93. u32 val;
  94. hal_sunxi_avs *avs;
  95. if (id >= AVS_NUM)
  96. {
  97. AVS_ERR("avs id is too big!!!\n");
  98. return -1;
  99. }
  100. avs = &hal_avs[id];
  101. val = hal_readl(avs->base + AVS_CNT_DIV_REG);
  102. val &= ~(AVS_DIV_MASK << (16 * id));
  103. div &= AVS_DIV_MASK;
  104. val |= (div << (16 * id));
  105. hal_writel(val, avs->base + AVS_CNT_DIV_REG);
  106. return 0;
  107. }
  108. int hal_avs_init(hal_avs_id_t id)
  109. {
  110. hal_sunxi_avs *avs;
  111. if (id >= AVS_NUM)
  112. {
  113. AVS_ERR("avs id is too big!!!\n");
  114. return -1;
  115. }
  116. avs = &hal_avs[id];
  117. avs->id = id;
  118. avs->base = SUNXI_TMR_PBASE;
  119. avs->enable = 1;
  120. avs->clk = hal_clock_get(SUNXI_AVS_CLK_TYPE, SUNXI_AVS_CLK);
  121. AVS_INFO("avs_clk:%d", avs->clk);
  122. hal_clock_enable(avs->clk);
  123. return 0;
  124. }
  125. int hal_avs_uninit(hal_avs_id_t id)
  126. {
  127. hal_sunxi_avs *avs;
  128. hal_avs_id_t i;
  129. if (id >= AVS_NUM)
  130. {
  131. AVS_ERR("avs id is too big!!!\n");
  132. return -1;
  133. }
  134. avs = &hal_avs[id];
  135. avs->enable = 0;
  136. for (i = 0; i < AVS_NUM; i++)
  137. {
  138. if (hal_avs[i].enable)
  139. {
  140. break;
  141. }
  142. }
  143. if (i == AVS_NUM)
  144. {
  145. hal_clock_disable(avs->clk);
  146. }
  147. return 0;
  148. }
  149. int hal_avs_control(hal_avs_id_t id, hal_avs_cmd_t cmd, void *arg)
  150. {
  151. hal_sunxi_avs *avs;
  152. u32 *counter, *div;
  153. if (id >= AVS_NUM)
  154. {
  155. AVS_ERR("avs id is too big!!!\n");
  156. return -1;
  157. }
  158. avs = &hal_avs[id];
  159. switch (cmd)
  160. {
  161. case AVS_ENABLE:
  162. return hal_avs_enable(id);
  163. case AVS_DISABLE:
  164. return hal_avs_disable(id);
  165. case AVS_PAUSE:
  166. return hal_avs_pause(id);
  167. case AVS_CONTINUE:
  168. return hal_avs_continue(id);
  169. case AVS_SET_COUNTER:
  170. counter = (u32 *)arg;
  171. return hal_avs_set_counter(id, *counter);
  172. case AVS_GET_COUNTER:
  173. counter = (u32 *)arg;
  174. return hal_avs_get_counter(id, counter);
  175. case AVS_SET_DIV:
  176. div = (u32 *)arg;
  177. return hal_avs_set_cnt_div(id, *div);
  178. default:
  179. return -1;
  180. }
  181. return 0;
  182. }