tsp_timer.c 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /*
  2. * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <arch_helpers.h>
  8. #include <plat/common/platform.h>
  9. #include "tsp_private.h"
  10. /*******************************************************************************
  11. * Data structure to keep track of per-cpu secure generic timer context across
  12. * power management operations.
  13. ******************************************************************************/
  14. typedef struct timer_context {
  15. uint64_t cval;
  16. uint32_t ctl;
  17. } timer_context_t;
  18. static timer_context_t pcpu_timer_context[PLATFORM_CORE_COUNT];
  19. /*******************************************************************************
  20. * This function initializes the generic timer to fire every 0.5 second
  21. ******************************************************************************/
  22. void tsp_generic_timer_start(void)
  23. {
  24. uint64_t cval;
  25. uint32_t ctl = 0;
  26. /* The timer will fire every 0.5 second */
  27. cval = read_cntpct_el0() + (read_cntfrq_el0() >> 1);
  28. write_cntps_cval_el1(cval);
  29. /* Enable the secure physical timer */
  30. set_cntp_ctl_enable(ctl);
  31. write_cntps_ctl_el1(ctl);
  32. }
  33. /*******************************************************************************
  34. * This function deasserts the timer interrupt and sets it up again
  35. ******************************************************************************/
  36. void tsp_generic_timer_handler(void)
  37. {
  38. /* Ensure that the timer did assert the interrupt */
  39. assert(get_cntp_ctl_istatus(read_cntps_ctl_el1()));
  40. /*
  41. * Disable the timer and reprogram it. The barriers ensure that there is
  42. * no reordering of instructions around the reprogramming code.
  43. */
  44. isb();
  45. write_cntps_ctl_el1(0);
  46. tsp_generic_timer_start();
  47. isb();
  48. }
  49. /*******************************************************************************
  50. * This function deasserts the timer interrupt prior to cpu power down
  51. ******************************************************************************/
  52. void tsp_generic_timer_stop(void)
  53. {
  54. /* Disable the timer */
  55. write_cntps_ctl_el1(0);
  56. }
  57. /*******************************************************************************
  58. * This function saves the timer context prior to cpu suspension
  59. ******************************************************************************/
  60. void tsp_generic_timer_save(void)
  61. {
  62. uint32_t linear_id = plat_my_core_pos();
  63. pcpu_timer_context[linear_id].cval = read_cntps_cval_el1();
  64. pcpu_timer_context[linear_id].ctl = read_cntps_ctl_el1();
  65. flush_dcache_range((uint64_t) &pcpu_timer_context[linear_id],
  66. sizeof(pcpu_timer_context[linear_id]));
  67. }
  68. /*******************************************************************************
  69. * This function restores the timer context post cpu resumption
  70. ******************************************************************************/
  71. void tsp_generic_timer_restore(void)
  72. {
  73. uint32_t linear_id = plat_my_core_pos();
  74. write_cntps_cval_el1(pcpu_timer_context[linear_id].cval);
  75. write_cntps_ctl_el1(pcpu_timer_context[linear_id].ctl);
  76. }