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