osi_clock.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /* Copyright (C) 2018 RDA Technologies Limited and/or its affiliates("RDA").
  2. * All rights reserved.
  3. *
  4. * This software is supplied "AS IS" without any warranties.
  5. * RDA assumes no responsibility or liability for the use of the software,
  6. * conveys no license or title under any patent, copyright, or mask work
  7. * right to the product. RDA reserves the right to make changes in the
  8. * software without notification. RDA also make no representation or
  9. * warranty that such application will be suitable for the specified use
  10. * without further testing or modification.
  11. */
  12. #ifndef _OSI_CLOCK_H_
  13. #define _OSI_CLOCK_H_
  14. #include <stdint.h>
  15. #include <stdbool.h>
  16. #include <stddef.h>
  17. #ifdef __cplusplus
  18. extern "C" {
  19. #endif
  20. /**
  21. * \brief callback function for clk_sys change
  22. *
  23. * The callback is platform dependent. Typical usage is for hardware module,
  24. * whose clock is divided from clk_sys. So, when clk_sys is changed, it is
  25. * needed to update the divider from clk_sys.
  26. *
  27. * It is recommended to add callback only in hardware driver, and divider
  28. * change is needed.
  29. *
  30. * To ensure atomic, the callback will be called with interrupt disabled.
  31. * So, the callback should be as fast as possible, even trace inside
  32. * callback is discouraged.
  33. *
  34. * \param [in] sysClkFreq new clk_sys to be changed
  35. * \return hardware module working frequency
  36. */
  37. typedef uint32_t (*osiSysClkChangeCallback_t)(uint32_t sysClkFreq);
  38. /**
  39. * \brief clk_sys change callback registry
  40. */
  41. typedef struct
  42. {
  43. uint32_t tag; ///< name tag
  44. //! @cond Doxygen_Suppress
  45. uint32_t dummy0;
  46. uint32_t dummy1;
  47. uint32_t dummy2;
  48. //! @endcond
  49. } osiSysClkCallbackRegistry_t;
  50. /**
  51. * \brief clk_sys constraint registry
  52. */
  53. typedef struct
  54. {
  55. uint32_t tag; ///< name tag
  56. //! @cond Doxygen_Suppress
  57. uint32_t dummy0;
  58. uint32_t dummy1;
  59. uint32_t dummy2;
  60. uint32_t dummy3;
  61. uint32_t dummy4;
  62. //! @endcond
  63. } osiClockConstrainRegistry_t;
  64. /**
  65. * \brief clock management module initialization
  66. */
  67. void osiClockManInit(void);
  68. /**
  69. * \brief clock management start
  70. *
  71. * At initialization, clock management will just record clock constrains. Only
  72. * after this is called, clock management will start to change system clock
  73. * based on clock constrains.
  74. */
  75. void osiClockManStart(void);
  76. /**
  77. * \brief register clk_sys change callback
  78. *
  79. * When \p cb is NULL, it is the same as \p osiUnregisterSysClkChangeCallback(r).
  80. *
  81. * \param [in] r callback registry, must be valid
  82. * \param [in] cb callback function
  83. */
  84. void osiRegisterSysClkChangeCallback(osiSysClkCallbackRegistry_t *r, osiSysClkChangeCallback_t cb);
  85. /**
  86. * \brief unregister clk_sys change callback
  87. *
  88. * \param [in] r callback registry, must be valid
  89. */
  90. void osiUnregisterSysClkChangeCallback(osiSysClkCallbackRegistry_t *r);
  91. /**
  92. * \brief invoke all registered clk_sys change callbacks
  93. *
  94. * It should **only** be called in HAL, during clk_sys change. This must be
  95. * called with interrupt disabled.
  96. *
  97. * It shouldn't be called by application.
  98. *
  99. * \param [in] freq clk_sys frequency to be changed
  100. */
  101. void osiInvokeSysClkChangeCallbacks(uint32_t freq);
  102. /**
  103. * \brief set hardware minimal clock constrain
  104. *
  105. * It is not needed to specify \a to be supported by hardware divider. The
  106. * **closest** supported hardware divider will be chosen.
  107. *
  108. * When \a freq is too high to be supported by hardware, the highest
  109. * supported frequency will be chosen.
  110. *
  111. * After this call, the actual clk_sys may be different with \a freq:
  112. * - When there are higher frequency requests, the actual clk_sys frequency
  113. * may be higher than \a freq.
  114. * - When the closest supported frequency is lower, the actual clk_sys
  115. * frequency may be lower than \a freq.
  116. * - When \a freq is too high, clk_sys will be set to be the highest
  117. * supported frequency.
  118. *
  119. * \param [in] r clock constrain registry, must be valid
  120. * \param [in] freq minimum clk_sys frequency
  121. */
  122. void osiRequestSysClk(osiClockConstrainRegistry_t *r, uint32_t freq);
  123. /**
  124. * \brief set hardware minimal clock constrain, without specified frequency
  125. *
  126. * Besides it will prevent system sleep, it will prevent clk_sys related
  127. * power consumption optimization.
  128. *
  129. * \param [in] r clock constrain registry, must be valid
  130. */
  131. void osiRequestSysClkActive(osiClockConstrainRegistry_t *r);
  132. /**
  133. * \brief set software minimal clock constrain
  134. *
  135. * It is similar to \p osiRequestSysClk. However, it won't prevent system
  136. * sleep or clk_sys related power consumption optimization.
  137. *
  138. * \param [in] r clock constrain registry, must be valid
  139. * \param [in] freq minimum clk_sys frequency
  140. */
  141. void osiRequestPerfClk(osiClockConstrainRegistry_t *r, uint32_t freq);
  142. /**
  143. * \brief unset software or hardware minimal clock constrain
  144. *
  145. * \param [in] r clock constrain registry, must be valid
  146. */
  147. void osiReleaseClk(osiClockConstrainRegistry_t *r);
  148. /**
  149. * \brief whether slow down sys clock is allowed
  150. *
  151. * \return
  152. * - true if allowed
  153. * - false if not allowed
  154. */
  155. bool osiIsSlowSysClkAllowed(void);
  156. /**
  157. * \brief set hardware external RAM access constrain
  158. *
  159. * \param [in] r clock constrain registry, must be valid
  160. */
  161. void osiRequestExtRamAccess(osiClockConstrainRegistry_t *r);
  162. /**
  163. * \brief unset hardware external RAM access constrain
  164. *
  165. * \param [in] r clock constrain registry, must be valid
  166. */
  167. void osiReleaseExtRamAccess(osiClockConstrainRegistry_t *r);
  168. /**
  169. * \brief unset hardware external RAM access constrain
  170. *
  171. * \param [in] r clock constrain registry, must be valid
  172. */
  173. void osiReleaseAllConstrain(osiClockConstrainRegistry_t *r);
  174. /**
  175. * \brief reapply clk_sys based on constrain
  176. *
  177. * It is possible that some constrains aren't satisfied immediately,
  178. * especially to decrease clk_sys. So, it may be needed to reapply
  179. * constrains. Usually, it is called in idle thread.
  180. *
  181. * It should be called by system only.
  182. */
  183. void osiReapplySysClk(void);
  184. /**
  185. * \brief dump clock constrain information to memory
  186. *
  187. * It is for debug only. The data format of timer information dump is
  188. * not stable, and may change. Currently, there is 2 bytes header, and
  189. * 12 bytes for each clock constrain.
  190. *
  191. * Caller should make sure \p mem is enough for hold clock constrain
  192. * information of \p count.
  193. *
  194. * \param mem memory for clock constrain information dump
  195. * \param count maximum clock constrain count to be dump
  196. * \return dump memory size
  197. */
  198. int osiClockConstrainDump(void *mem, int count);
  199. #ifdef __cplusplus
  200. }
  201. #endif
  202. #endif