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