mt_smp.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /*
  2. * Copyright (c) 2022, MediaTek Inc. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <arch_helpers.h>
  8. #include <common/debug.h>
  9. #include <drivers/delay_timer.h>
  10. #include <plat/common/platform.h>
  11. #include <lib/pm/mtk_pm.h>
  12. #include <mcucfg.h>
  13. #include "mt_cpu_pm.h"
  14. #include "mt_smp.h"
  15. static inline int is_core_power_status_on(unsigned int cpuid)
  16. {
  17. return !!(mmio_read_32(CPU_PWR_STATUS) & BIT(cpuid));
  18. }
  19. void mt_smp_core_init_arch(unsigned int cluster, unsigned int cpu, int arm64,
  20. struct cpu_pwr_ctrl *pwr_ctrl)
  21. {
  22. CPU_PM_ASSERT(cluster == 0);
  23. CPU_PM_ASSERT(pwr_ctrl != NULL);
  24. /* aa64naa32 in bits[16:23] */
  25. if (arm64 != 0) {
  26. mmio_setbits_32(pwr_ctrl->arch_addr, 1 << (16 + cpu));
  27. } else {
  28. mmio_clrbits_32(pwr_ctrl->arch_addr, 1 << (16 + cpu));
  29. }
  30. }
  31. void mt_smp_core_bootup_address_set(struct cpu_pwr_ctrl *pwr_ctrl, uintptr_t entry)
  32. {
  33. CPU_PM_ASSERT(pwr_ctrl != NULL);
  34. /* Set bootup address */
  35. mmio_write_32(pwr_ctrl->rvbaraddr_l, entry);
  36. }
  37. int mt_smp_power_core_on(unsigned int cpu_id, struct cpu_pwr_ctrl *pwr_ctrl)
  38. {
  39. unsigned int val = is_core_power_status_on(cpu_id);
  40. CPU_PM_ASSERT(pwr_ctrl);
  41. mmio_clrbits_32(pwr_ctrl->pwpr, RESETPWRON_CONFIG);
  42. if (val == 0) {
  43. /*
  44. * Set to 0 after BIG VPROC bulk powered on (configure in MCUPM) and
  45. * before big core power-on sequence.
  46. */
  47. if (cpu_id >= PLAT_CPU_PM_B_BUCK_ISO_ID) {
  48. mmio_write_32(DREQ20_BIG_VPROC_ISO, 0);
  49. }
  50. mmio_setbits_32(pwr_ctrl->pwpr, PWR_RST_B);
  51. dsbsy();
  52. /* set mp0_spmc_pwr_on_cpuX = 1 */
  53. mmio_setbits_32(pwr_ctrl->pwpr, PWR_ON);
  54. val = 0;
  55. while (is_core_power_status_on(cpu_id) == 0) {
  56. DO_SMP_CORE_ON_WAIT_TIMEOUT(val);
  57. mmio_clrbits_32(pwr_ctrl->pwpr, PWR_ON);
  58. mmio_setbits_32(pwr_ctrl->pwpr, PWR_ON);
  59. }
  60. } else {
  61. INFO("[%s:%d] - core_%u haven been power on\n", __func__, __LINE__, cpu_id);
  62. }
  63. return MTK_CPUPM_E_OK;
  64. }
  65. int mt_smp_power_core_off(struct cpu_pwr_ctrl *pwr_ctrl)
  66. {
  67. /* set mp0_spmc_pwr_on_cpuX = 1 */
  68. mmio_clrbits_32(pwr_ctrl->pwpr, PWR_ON);
  69. return MTK_CPUPM_E_OK;
  70. }
  71. void mt_smp_init(void)
  72. {
  73. /* clear RESETPWRON_CONFIG of mcusys/cluster/core0 */
  74. mmio_clrbits_32(SPM_MCUSYS_PWR_CON, RESETPWRON_CONFIG);
  75. mmio_clrbits_32(SPM_MP0_CPUTOP_PWR_CON, RESETPWRON_CONFIG);
  76. }