xref: /dpdk/lib/power/rte_power_uncore.c (revision da7e701151ea8b742d4c38ace3e4fefd1b4507fc)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  * Copyright(c) 2023 AMD Corporation
4  */
5 
6 #include <errno.h>
7 
8 #include <rte_errno.h>
9 #include <rte_spinlock.h>
10 
11 #include "rte_power_uncore.h"
12 #include "power_intel_uncore.h"
13 
14 enum rte_uncore_power_mgmt_env default_uncore_env = RTE_UNCORE_PM_ENV_NOT_SET;
15 
16 static rte_spinlock_t global_env_cfg_lock = RTE_SPINLOCK_INITIALIZER;
17 
18 static uint32_t
19 power_get_dummy_uncore_freq(unsigned int pkg __rte_unused,
20 	       unsigned int die __rte_unused)
21 {
22 	return 0;
23 }
24 
25 static int
26 power_set_dummy_uncore_freq(unsigned int pkg __rte_unused,
27 	       unsigned int die __rte_unused, uint32_t index __rte_unused)
28 {
29 	return 0;
30 }
31 
32 static int
33 power_dummy_uncore_freq_max(unsigned int pkg __rte_unused,
34 	       unsigned int die __rte_unused)
35 {
36 	return 0;
37 }
38 
39 static int
40 power_dummy_uncore_freq_min(unsigned int pkg __rte_unused,
41 	       unsigned int die __rte_unused)
42 {
43 	return 0;
44 }
45 
46 static int
47 power_dummy_uncore_freqs(unsigned int pkg __rte_unused, unsigned int die __rte_unused,
48 		uint32_t *freqs __rte_unused, uint32_t num __rte_unused)
49 {
50 	return 0;
51 }
52 
53 static int
54 power_dummy_uncore_get_num_freqs(unsigned int pkg __rte_unused,
55 	       unsigned int die __rte_unused)
56 {
57 	return 0;
58 }
59 
60 static unsigned int
61 power_dummy_uncore_get_num_pkgs(void)
62 {
63 	return 0;
64 }
65 
66 static unsigned int
67 power_dummy_uncore_get_num_dies(unsigned int pkg __rte_unused)
68 {
69 	return 0;
70 }
71 
72 /* function pointers */
73 rte_power_get_uncore_freq_t rte_power_get_uncore_freq = power_get_dummy_uncore_freq;
74 rte_power_set_uncore_freq_t rte_power_set_uncore_freq = power_set_dummy_uncore_freq;
75 rte_power_uncore_freq_change_t rte_power_uncore_freq_max = power_dummy_uncore_freq_max;
76 rte_power_uncore_freq_change_t rte_power_uncore_freq_min = power_dummy_uncore_freq_min;
77 rte_power_uncore_freqs_t rte_power_uncore_freqs = power_dummy_uncore_freqs;
78 rte_power_uncore_get_num_freqs_t rte_power_uncore_get_num_freqs = power_dummy_uncore_get_num_freqs;
79 rte_power_uncore_get_num_pkgs_t rte_power_uncore_get_num_pkgs = power_dummy_uncore_get_num_pkgs;
80 rte_power_uncore_get_num_dies_t rte_power_uncore_get_num_dies = power_dummy_uncore_get_num_dies;
81 
82 static void
83 reset_power_uncore_function_ptrs(void)
84 {
85 	rte_power_get_uncore_freq = power_get_dummy_uncore_freq;
86 	rte_power_set_uncore_freq = power_set_dummy_uncore_freq;
87 	rte_power_uncore_freq_max = power_dummy_uncore_freq_max;
88 	rte_power_uncore_freq_min = power_dummy_uncore_freq_min;
89 	rte_power_uncore_freqs  = power_dummy_uncore_freqs;
90 	rte_power_uncore_get_num_freqs = power_dummy_uncore_get_num_freqs;
91 	rte_power_uncore_get_num_pkgs = power_dummy_uncore_get_num_pkgs;
92 	rte_power_uncore_get_num_dies = power_dummy_uncore_get_num_dies;
93 }
94 
95 int
96 rte_power_set_uncore_env(enum rte_uncore_power_mgmt_env env)
97 {
98 	int ret;
99 
100 	rte_spinlock_lock(&global_env_cfg_lock);
101 
102 	if (default_uncore_env != RTE_UNCORE_PM_ENV_NOT_SET) {
103 		RTE_LOG(ERR, POWER, "Uncore Power Management Env already set.\n");
104 		rte_spinlock_unlock(&global_env_cfg_lock);
105 		return -1;
106 	}
107 
108 	ret = 0;
109 	if (env == RTE_UNCORE_PM_ENV_INTEL_UNCORE) {
110 		rte_power_get_uncore_freq = power_get_intel_uncore_freq;
111 		rte_power_set_uncore_freq = power_set_intel_uncore_freq;
112 		rte_power_uncore_freq_min  = power_intel_uncore_freq_min;
113 		rte_power_uncore_freq_max  = power_intel_uncore_freq_max;
114 		rte_power_uncore_freqs = power_intel_uncore_freqs;
115 		rte_power_uncore_get_num_freqs = power_intel_uncore_get_num_freqs;
116 		rte_power_uncore_get_num_pkgs = power_intel_uncore_get_num_pkgs;
117 		rte_power_uncore_get_num_dies = power_intel_uncore_get_num_dies;
118 	} else {
119 		RTE_LOG(ERR, POWER, "Invalid Power Management Environment(%d) set\n", env);
120 		ret = -1;
121 		goto out;
122 	}
123 
124 	default_uncore_env = env;
125 out:
126 	rte_spinlock_unlock(&global_env_cfg_lock);
127 	return ret;
128 }
129 
130 void
131 rte_power_unset_uncore_env(void)
132 {
133 	rte_spinlock_lock(&global_env_cfg_lock);
134 	default_uncore_env = RTE_UNCORE_PM_ENV_NOT_SET;
135 	reset_power_uncore_function_ptrs();
136 	rte_spinlock_unlock(&global_env_cfg_lock);
137 }
138 
139 enum rte_uncore_power_mgmt_env
140 rte_power_get_uncore_env(void)
141 {
142 	return default_uncore_env;
143 }
144 
145 int
146 rte_power_uncore_init(unsigned int pkg, unsigned int die)
147 {
148 	int ret = -1;
149 
150 	switch (default_uncore_env) {
151 	case RTE_UNCORE_PM_ENV_INTEL_UNCORE:
152 		return power_intel_uncore_init(pkg, die);
153 	default:
154 		RTE_LOG(INFO, POWER, "Uncore Env isn't set yet!\n");
155 		break;
156 	}
157 
158 	/* Auto detect Environment */
159 	RTE_LOG(INFO, POWER, "Attempting to initialise Intel Uncore power mgmt...\n");
160 	ret = power_intel_uncore_init(pkg, die);
161 	if (ret == 0) {
162 		rte_power_set_uncore_env(RTE_UNCORE_PM_ENV_INTEL_UNCORE);
163 		goto out;
164 	}
165 
166 	if (default_uncore_env == RTE_UNCORE_PM_ENV_NOT_SET) {
167 		RTE_LOG(ERR, POWER, "Unable to set Power Management Environment "
168 			"for package %u Die %u\n", pkg, die);
169 		ret = 0;
170 	}
171 out:
172 	return ret;
173 }
174 
175 int
176 rte_power_uncore_exit(unsigned int pkg, unsigned int die)
177 {
178 	switch (default_uncore_env) {
179 	case RTE_UNCORE_PM_ENV_INTEL_UNCORE:
180 		return power_intel_uncore_exit(pkg, die);
181 	default:
182 		RTE_LOG(ERR, POWER, "Uncore Env has not been set, unable to exit gracefully\n");
183 		break;
184 	}
185 	return -1;
186 }
187