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