1 /*
2  * Copyright (c) 2024 Intel Corporation
3  * SPDX-License-Identifier: Apache-2.0
4  */
5 
6 #include <stdint.h>
7 #include <zephyr/toolchain.h>
8 #include <zephyr/sys/util_macro.h>
9 #include <adsp_shim.h>
10 
11 #ifndef ZEPHYR_SOC_INTEL_ADSP_POWER_H_
12 #define ZEPHYR_SOC_INTEL_ADSP_POWER_H_
13 
14 /* Value used as delay when waiting for hw register state change. */
15 #define HW_STATE_CHECK_DELAY 64
16 
17 /* Power Control register - controls the power domain operations. */
18 struct ace_pwrctl {
19 	uint16_t rsvd4: 5;
20 	uint16_t wphstpg: 1;
21 	uint16_t wphubhppg: 1;
22 	uint16_t wpdspulppg: 1;
23 	uint16_t wpioxpg: 2;
24 	uint16_t rsvd11: 2;
25 	uint16_t wpmlpg: 1;
26 	uint16_t rsvd14: 2;
27 	uint16_t phubulppg: 1;
28 };
29 
30 struct ace_pwrctl2 {
31 	uint16_t wpdsphpxpg: 5;
32 	uint16_t rsvd15: 11;
33 };
34 
35 #define ACE_PWRCTL  ((volatile struct ace_pwrctl *)&ACE_DfPMCCU.dfpwrctl)
36 #define ACE_PWRCTL2 ((volatile struct ace_pwrctl2 *)&ACE_DfPMCCU.dfpwrctl2)
37 
38 /* Power Status register - reports the power domain status. */
39 struct ace_pwrsts {
40 	uint16_t rsvd4: 5;
41 	uint16_t hstpgs: 1;
42 	uint16_t hubhppgs: 1;
43 	uint16_t dspulppgs: 1;
44 	uint16_t ioxpgs: 2;
45 	uint16_t rsvd11: 2;
46 	uint16_t mlpgs: 1;
47 	uint16_t rsvd14: 2;
48 	uint16_t hubulppgs: 1;
49 };
50 
51 struct ace_pwrsts2 {
52 	uint16_t dsphpxpgs: 5;
53 	uint16_t rsvd15: 11;
54 };
55 
56 #define ACE_PWRSTS  ((volatile struct ace_pwrsts *)&ACE_DfPMCCU.dfpwrsts)
57 #define ACE_PWRSTS2 ((volatile struct ace_pwrsts2 *)&ACE_DfPMCCU.dfpwrsts2)
58 
59 /**
60  * @brief Power up a specific CPU.
61  *
62  * This sets the "not power gating" bit in the power control
63  * register to disable power gating to CPU, thus powering up
64  * the CPU.
65  *
66  * @param cpu_num CPU to be powered up.
67  */
soc_cpu_power_up(int cpu_num)68 static ALWAYS_INLINE void soc_cpu_power_up(int cpu_num)
69 {
70 	ACE_PWRCTL2->wpdsphpxpg |= BIT(cpu_num);
71 }
72 
73 /**
74  * @brief Power down a specific CPU.
75  *
76  * This clears the "not power gating" bit in the power control
77  * register to enable power gating to CPU, thus powering down
78  * the CPU.
79  *
80  * @param cpu_num CPU to be powered down.
81  */
soc_cpu_power_down(int cpu_num)82 static ALWAYS_INLINE void soc_cpu_power_down(int cpu_num)
83 {
84 	ACE_PWRCTL2->wpdsphpxpg &= ~BIT(cpu_num);
85 }
86 
87 /**
88  * @brief Test if a CPU is currently powered.
89  *
90  * This queries the power status register to see if the CPU
91  * is currently powered.
92  *
93  * @param cpu_num CPU to be queried.
94  * @return True if CPU is powered, false if now.
95  */
soc_cpu_is_powered(int cpu_num)96 static ALWAYS_INLINE bool soc_cpu_is_powered(int cpu_num)
97 {
98 	return (ACE_PWRSTS2->dsphpxpgs & BIT(cpu_num)) == BIT(cpu_num);
99 }
100 
101 /**
102  * @brief Restore timer after leaving soft-off.
103  *
104  */
105 void intel_adsp_clock_soft_off_exit(void);
106 
107 
108 /**
109  * @brief Retrieve node identifier for Intel ADSP HOST power domain.
110  */
111 #define INTEL_ADSP_HST_DOMAIN_DTNODE DT_NODELABEL(hst_domain)
112 
113 /**
114  * @brief Intel ADSP HOST power domain pointer.
115  */
116 #define INTEL_ADSP_HST_DOMAIN_DEV DEVICE_DT_GET(INTEL_ADSP_HST_DOMAIN_DTNODE)
117 
118 #endif /* ZEPHYR_SOC_INTEL_ADSP_POWER_H_ */
119