fvp_pwrc.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /*
  2. * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <drivers/arm/fvp/fvp_pwrc.h>
  7. #include <lib/bakery_lock.h>
  8. #include <lib/mmio.h>
  9. #include <plat/arm/common/plat_arm.h>
  10. #include <platform_def.h>
  11. #define FVP_PWRC_ID_MASK U(0x00FFFFFF)
  12. /*
  13. * TODO: Someday there will be a generic power controller api. At the moment
  14. * each platform has its own pwrc so just exporting functions is fine.
  15. */
  16. ARM_INSTANTIATE_LOCK;
  17. /*
  18. * Core ID field is 24 bits wide and extracted from MPIDR.
  19. * Bits[23:16] represent Affinity Level 2
  20. * Bits[15:8] represent Affinity Level 1
  21. * Bits[7:0] represent Affinity Level 0
  22. */
  23. static unsigned int fvp_pwrc_core_id(u_register_t mpidr)
  24. {
  25. return (unsigned int)(mpidr & FVP_PWRC_ID_MASK);
  26. }
  27. unsigned int fvp_pwrc_get_cpu_wkr(u_register_t mpidr)
  28. {
  29. unsigned int id = fvp_pwrc_core_id(mpidr);
  30. return PSYSR_WK(fvp_pwrc_read_psysr(id));
  31. }
  32. unsigned int fvp_pwrc_read_psysr(u_register_t mpidr)
  33. {
  34. unsigned int rc;
  35. unsigned int id = fvp_pwrc_core_id(mpidr);
  36. arm_lock_get();
  37. mmio_write_32(PWRC_BASE + PSYSR_OFF, id);
  38. rc = mmio_read_32(PWRC_BASE + PSYSR_OFF);
  39. arm_lock_release();
  40. return rc;
  41. }
  42. void fvp_pwrc_write_pponr(u_register_t mpidr)
  43. {
  44. unsigned int id = fvp_pwrc_core_id(mpidr);
  45. arm_lock_get();
  46. mmio_write_32(PWRC_BASE + PPONR_OFF, id);
  47. arm_lock_release();
  48. }
  49. void fvp_pwrc_write_ppoffr(u_register_t mpidr)
  50. {
  51. unsigned int id = fvp_pwrc_core_id(mpidr);
  52. arm_lock_get();
  53. mmio_write_32(PWRC_BASE + PPOFFR_OFF, id);
  54. arm_lock_release();
  55. }
  56. void fvp_pwrc_set_wen(u_register_t mpidr)
  57. {
  58. unsigned int id = fvp_pwrc_core_id(mpidr);
  59. arm_lock_get();
  60. mmio_write_32(PWRC_BASE + PWKUPR_OFF,
  61. (unsigned int) (PWKUPR_WEN | id));
  62. arm_lock_release();
  63. }
  64. void fvp_pwrc_clr_wen(u_register_t mpidr)
  65. {
  66. unsigned int id = fvp_pwrc_core_id(mpidr);
  67. arm_lock_get();
  68. mmio_write_32(PWRC_BASE + PWKUPR_OFF, id);
  69. arm_lock_release();
  70. }
  71. void fvp_pwrc_write_pcoffr(u_register_t mpidr)
  72. {
  73. unsigned int id = fvp_pwrc_core_id(mpidr);
  74. arm_lock_get();
  75. mmio_write_32(PWRC_BASE + PCOFFR_OFF, id);
  76. arm_lock_release();
  77. }
  78. /* Nothing else to do here apart from initializing the lock */
  79. void __init plat_arm_pwrc_setup(void)
  80. {
  81. arm_lock_init();
  82. }