1 /*
2  * Copyright (c) 2022 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 wpdsphpxpg : 3;
20 	uint16_t rsvd3      : 1;
21 	uint16_t wphstpg    : 1;
22 	uint16_t rsvd5      : 1;
23 	uint16_t wphubhppg  : 1;
24 	uint16_t wpdspulppg : 1;
25 	uint16_t wpioxpg    : 2;
26 	uint16_t rsvd11     : 2;
27 	uint16_t wpmlpg     : 1;
28 	uint16_t rsvd14     : 2;
29 	uint16_t phubulppg  : 1;
30 };
31 
32 #define ACE_PWRCTL ((volatile struct ace_pwrctl *) &ACE_DfPMCCU.dfpwrctl)
33 
34 /* Power Status register - reports the power domain status. */
35 struct ace_pwrsts {
36 	uint16_t dsphpxpgs : 4;
37 	uint16_t hstpgs    : 1;
38 	uint16_t rsvd5     : 1;
39 	uint16_t hubhppgs  : 1;
40 	uint16_t dspulppgs : 1;
41 	uint16_t ioxpgs    : 4;
42 	uint16_t mlpgs     : 2;
43 	uint16_t rsvd14    : 1;
44 	uint16_t hubulppgs : 1;
45 };
46 
47 #define ACE_PWRSTS ((volatile struct ace_pwrsts *) &ACE_DfPMCCU.dfpwrsts)
48 
49 /**
50  * @brief Power up a specific CPU.
51  *
52  * This sets the "not power gating" bit in the power control
53  * register to disable power gating to CPU, thus powering up
54  * the CPU.
55  *
56  * @param cpu_num CPU to be powered up.
57  */
soc_cpu_power_up(int cpu_num)58 static ALWAYS_INLINE void soc_cpu_power_up(int cpu_num)
59 {
60 	ACE_PWRCTL->wpdsphpxpg |= BIT(cpu_num);
61 }
62 
63 /**
64  * @brief Power down a specific CPU.
65  *
66  * This clears the "not power gating" bit in the power control
67  * register to enable power gating to CPU, thus powering down
68  * the CPU.
69  *
70  * @param cpu_num CPU to be powered down.
71  */
soc_cpu_power_down(int cpu_num)72 static ALWAYS_INLINE void soc_cpu_power_down(int cpu_num)
73 {
74 	ACE_PWRCTL->wpdsphpxpg &= ~BIT(cpu_num);
75 }
76 
77 /**
78  * @brief Test if a CPU is currently powered.
79  *
80  * This queries the power status register to see if the CPU
81  * is currently powered.
82  *
83  * @param cpu_num CPU to be queried.
84  * @return True if CPU is powered, false if now.
85  */
soc_cpu_is_powered(int cpu_num)86 static ALWAYS_INLINE bool soc_cpu_is_powered(int cpu_num)
87 {
88 	return (ACE_PWRSTS->dsphpxpgs & BIT(cpu_num)) == BIT(cpu_num);
89 }
90 
91 /**
92  * @brief Restore timer after leaving soft-off.
93  *
94  */
95 void intel_adsp_clock_soft_off_exit(void);
96 
97 /**
98  * @brief Retrieve node identifier for Intel ADSP HOST power domain.
99  */
100 #define INTEL_ADSP_HST_DOMAIN_DTNODE DT_NODELABEL(hst_domain)
101 
102 /**
103  * @brief Intel ADSP HOST power domain pointer.
104  */
105 #define INTEL_ADSP_HST_DOMAIN_DEV DEVICE_DT_GET(INTEL_ADSP_HST_DOMAIN_DTNODE)
106 
107 #define INTEL_ADSP_HST_DOMAIN_BIT DT_PROP(INTEL_ADSP_HST_DOMAIN_DTNODE, bit_position)
108 
109 #define INTEL_ADSP_ACE15_MAGIC_KEY 0xFFFACE15
110 
111 #endif /* ZEPHYR_SOC_INTEL_ADSP_POWER_H_ */
112