xref: /rk3399_ARM-atf/drivers/arm/fvp/fvp_pwrc.c (revision a3919ed0ab19182c801294902acebeb19d11d7b5)
1560293bbSAntonio Nino Diaz /*
2*70bc7444SMadhukar Pappireddy  * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
3560293bbSAntonio Nino Diaz  *
4560293bbSAntonio Nino Diaz  * SPDX-License-Identifier: BSD-3-Clause
5560293bbSAntonio Nino Diaz  */
6560293bbSAntonio Nino Diaz 
7560293bbSAntonio Nino Diaz #include <drivers/arm/fvp/fvp_pwrc.h>
8560293bbSAntonio Nino Diaz #include <lib/bakery_lock.h>
9560293bbSAntonio Nino Diaz #include <lib/mmio.h>
10560293bbSAntonio Nino Diaz #include <plat/arm/common/plat_arm.h>
11560293bbSAntonio Nino Diaz #include <platform_def.h>
12560293bbSAntonio Nino Diaz 
13*70bc7444SMadhukar Pappireddy #define FVP_PWRC_ID_MASK U(0x00FFFFFF)
14*70bc7444SMadhukar Pappireddy 
15560293bbSAntonio Nino Diaz /*
16560293bbSAntonio Nino Diaz  * TODO: Someday there will be a generic power controller api. At the moment
17560293bbSAntonio Nino Diaz  * each platform has its own pwrc so just exporting functions is fine.
18560293bbSAntonio Nino Diaz  */
19560293bbSAntonio Nino Diaz ARM_INSTANTIATE_LOCK;
20560293bbSAntonio Nino Diaz 
21*70bc7444SMadhukar Pappireddy /*
22*70bc7444SMadhukar Pappireddy  * Core ID field is 24 bits wide and extracted from MPIDR.
23*70bc7444SMadhukar Pappireddy  * Bits[23:16] represent Affinity Level 2
24*70bc7444SMadhukar Pappireddy  * Bits[15:8] represent Affinity Level 1
25*70bc7444SMadhukar Pappireddy  * Bits[7:0] represent Affinity Level 0
26*70bc7444SMadhukar Pappireddy  */
fvp_pwrc_core_id(u_register_t mpidr)27*70bc7444SMadhukar Pappireddy static unsigned int fvp_pwrc_core_id(u_register_t mpidr)
28*70bc7444SMadhukar Pappireddy {
29*70bc7444SMadhukar Pappireddy 	return (unsigned int)(mpidr & FVP_PWRC_ID_MASK);
30*70bc7444SMadhukar Pappireddy }
31*70bc7444SMadhukar Pappireddy 
fvp_pwrc_get_cpu_wkr(u_register_t mpidr)32560293bbSAntonio Nino Diaz unsigned int fvp_pwrc_get_cpu_wkr(u_register_t mpidr)
33560293bbSAntonio Nino Diaz {
34*70bc7444SMadhukar Pappireddy 	unsigned int id = fvp_pwrc_core_id(mpidr);
35*70bc7444SMadhukar Pappireddy 
36*70bc7444SMadhukar Pappireddy 	return PSYSR_WK(fvp_pwrc_read_psysr(id));
37560293bbSAntonio Nino Diaz }
38560293bbSAntonio Nino Diaz 
fvp_pwrc_read_psysr(u_register_t mpidr)39560293bbSAntonio Nino Diaz unsigned int fvp_pwrc_read_psysr(u_register_t mpidr)
40560293bbSAntonio Nino Diaz {
41560293bbSAntonio Nino Diaz 	unsigned int rc;
42*70bc7444SMadhukar Pappireddy 	unsigned int id = fvp_pwrc_core_id(mpidr);
43*70bc7444SMadhukar Pappireddy 
44560293bbSAntonio Nino Diaz 	arm_lock_get();
45*70bc7444SMadhukar Pappireddy 	mmio_write_32(PWRC_BASE + PSYSR_OFF, id);
46560293bbSAntonio Nino Diaz 	rc = mmio_read_32(PWRC_BASE + PSYSR_OFF);
47560293bbSAntonio Nino Diaz 	arm_lock_release();
48560293bbSAntonio Nino Diaz 	return rc;
49560293bbSAntonio Nino Diaz }
50560293bbSAntonio Nino Diaz 
fvp_pwrc_write_pponr(u_register_t mpidr)51560293bbSAntonio Nino Diaz void fvp_pwrc_write_pponr(u_register_t mpidr)
52560293bbSAntonio Nino Diaz {
53*70bc7444SMadhukar Pappireddy 	unsigned int id = fvp_pwrc_core_id(mpidr);
54*70bc7444SMadhukar Pappireddy 
55560293bbSAntonio Nino Diaz 	arm_lock_get();
56*70bc7444SMadhukar Pappireddy 	mmio_write_32(PWRC_BASE + PPONR_OFF, id);
57560293bbSAntonio Nino Diaz 	arm_lock_release();
58560293bbSAntonio Nino Diaz }
59560293bbSAntonio Nino Diaz 
fvp_pwrc_write_ppoffr(u_register_t mpidr)60560293bbSAntonio Nino Diaz void fvp_pwrc_write_ppoffr(u_register_t mpidr)
61560293bbSAntonio Nino Diaz {
62*70bc7444SMadhukar Pappireddy 	unsigned int id = fvp_pwrc_core_id(mpidr);
63*70bc7444SMadhukar Pappireddy 
64560293bbSAntonio Nino Diaz 	arm_lock_get();
65*70bc7444SMadhukar Pappireddy 	mmio_write_32(PWRC_BASE + PPOFFR_OFF, id);
66560293bbSAntonio Nino Diaz 	arm_lock_release();
67560293bbSAntonio Nino Diaz }
68560293bbSAntonio Nino Diaz 
fvp_pwrc_set_wen(u_register_t mpidr)69560293bbSAntonio Nino Diaz void fvp_pwrc_set_wen(u_register_t mpidr)
70560293bbSAntonio Nino Diaz {
71*70bc7444SMadhukar Pappireddy 	unsigned int id = fvp_pwrc_core_id(mpidr);
72*70bc7444SMadhukar Pappireddy 
73560293bbSAntonio Nino Diaz 	arm_lock_get();
74560293bbSAntonio Nino Diaz 	mmio_write_32(PWRC_BASE + PWKUPR_OFF,
75*70bc7444SMadhukar Pappireddy 		      (unsigned int) (PWKUPR_WEN | id));
76560293bbSAntonio Nino Diaz 	arm_lock_release();
77560293bbSAntonio Nino Diaz }
78560293bbSAntonio Nino Diaz 
fvp_pwrc_clr_wen(u_register_t mpidr)79560293bbSAntonio Nino Diaz void fvp_pwrc_clr_wen(u_register_t mpidr)
80560293bbSAntonio Nino Diaz {
81*70bc7444SMadhukar Pappireddy 	unsigned int id = fvp_pwrc_core_id(mpidr);
82*70bc7444SMadhukar Pappireddy 
83560293bbSAntonio Nino Diaz 	arm_lock_get();
84*70bc7444SMadhukar Pappireddy 	mmio_write_32(PWRC_BASE + PWKUPR_OFF, id);
85560293bbSAntonio Nino Diaz 	arm_lock_release();
86560293bbSAntonio Nino Diaz }
87560293bbSAntonio Nino Diaz 
fvp_pwrc_write_pcoffr(u_register_t mpidr)88560293bbSAntonio Nino Diaz void fvp_pwrc_write_pcoffr(u_register_t mpidr)
89560293bbSAntonio Nino Diaz {
90*70bc7444SMadhukar Pappireddy 	unsigned int id = fvp_pwrc_core_id(mpidr);
91*70bc7444SMadhukar Pappireddy 
92560293bbSAntonio Nino Diaz 	arm_lock_get();
93*70bc7444SMadhukar Pappireddy 	mmio_write_32(PWRC_BASE + PCOFFR_OFF, id);
94560293bbSAntonio Nino Diaz 	arm_lock_release();
95560293bbSAntonio Nino Diaz }
96560293bbSAntonio Nino Diaz 
97560293bbSAntonio Nino Diaz /* Nothing else to do here apart from initializing the lock */
plat_arm_pwrc_setup(void)98560293bbSAntonio Nino Diaz void __init plat_arm_pwrc_setup(void)
99560293bbSAntonio Nino Diaz {
100560293bbSAntonio Nino Diaz 	arm_lock_init();
101560293bbSAntonio Nino Diaz }
102560293bbSAntonio Nino Diaz 
103560293bbSAntonio Nino Diaz 
104560293bbSAntonio Nino Diaz 
105