power: add p-state driver compatibility
[dpdk.git] / lib / librte_power / rte_power.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4
5 #include <rte_atomic.h>
6
7 #include "rte_power.h"
8 #include "power_acpi_cpufreq.h"
9 #include "power_kvm_vm.h"
10 #include "power_pstate_cpufreq.h"
11 #include "power_common.h"
12
13 enum power_management_env global_default_env = PM_ENV_NOT_SET;
14
15 volatile uint32_t global_env_cfg_status = 0;
16
17 /* function pointers */
18 rte_power_freqs_t rte_power_freqs  = NULL;
19 rte_power_get_freq_t rte_power_get_freq = NULL;
20 rte_power_set_freq_t rte_power_set_freq = NULL;
21 rte_power_freq_change_t rte_power_freq_up = NULL;
22 rte_power_freq_change_t rte_power_freq_down = NULL;
23 rte_power_freq_change_t rte_power_freq_max = NULL;
24 rte_power_freq_change_t rte_power_freq_min = NULL;
25 rte_power_freq_change_t rte_power_turbo_status;
26 rte_power_freq_change_t rte_power_freq_enable_turbo;
27 rte_power_freq_change_t rte_power_freq_disable_turbo;
28 rte_power_get_capabilities_t rte_power_get_capabilities;
29
30 int
31 rte_power_set_env(enum power_management_env env)
32 {
33         if (rte_atomic32_cmpset(&global_env_cfg_status, 0, 1) == 0) {
34                 return 0;
35         }
36         if (env == PM_ENV_ACPI_CPUFREQ) {
37                 rte_power_freqs = power_acpi_cpufreq_freqs;
38                 rte_power_get_freq = power_acpi_cpufreq_get_freq;
39                 rte_power_set_freq = power_acpi_cpufreq_set_freq;
40                 rte_power_freq_up = power_acpi_cpufreq_freq_up;
41                 rte_power_freq_down = power_acpi_cpufreq_freq_down;
42                 rte_power_freq_min = power_acpi_cpufreq_freq_min;
43                 rte_power_freq_max = power_acpi_cpufreq_freq_max;
44                 rte_power_turbo_status = power_acpi_turbo_status;
45                 rte_power_freq_enable_turbo = power_acpi_enable_turbo;
46                 rte_power_freq_disable_turbo = power_acpi_disable_turbo;
47                 rte_power_get_capabilities = power_acpi_get_capabilities;
48         } else if (env == PM_ENV_KVM_VM) {
49                 rte_power_freqs = power_kvm_vm_freqs;
50                 rte_power_get_freq = power_kvm_vm_get_freq;
51                 rte_power_set_freq = power_kvm_vm_set_freq;
52                 rte_power_freq_up = power_kvm_vm_freq_up;
53                 rte_power_freq_down = power_kvm_vm_freq_down;
54                 rte_power_freq_min = power_kvm_vm_freq_min;
55                 rte_power_freq_max = power_kvm_vm_freq_max;
56                 rte_power_turbo_status = power_kvm_vm_turbo_status;
57                 rte_power_freq_enable_turbo = power_kvm_vm_enable_turbo;
58                 rte_power_freq_disable_turbo = power_kvm_vm_disable_turbo;
59                 rte_power_get_capabilities = power_kvm_vm_get_capabilities;
60         } else if (env == PM_ENV_PSTATE_CPUFREQ) {
61                 rte_power_freqs = power_pstate_cpufreq_freqs;
62                 rte_power_get_freq = power_pstate_cpufreq_get_freq;
63                 rte_power_set_freq = power_pstate_cpufreq_set_freq;
64                 rte_power_freq_up = power_pstate_cpufreq_freq_up;
65                 rte_power_freq_down = power_pstate_cpufreq_freq_down;
66                 rte_power_freq_min = power_pstate_cpufreq_freq_min;
67                 rte_power_freq_max = power_pstate_cpufreq_freq_max;
68                 rte_power_turbo_status = power_pstate_turbo_status;
69                 rte_power_freq_enable_turbo = power_pstate_enable_turbo;
70                 rte_power_freq_disable_turbo = power_pstate_disable_turbo;
71                 rte_power_get_capabilities = power_pstate_get_capabilities;
72
73         } else {
74                 RTE_LOG(ERR, POWER, "Invalid Power Management Environment(%d) set\n",
75                                 env);
76                 rte_power_unset_env();
77                 return -1;
78         }
79         global_default_env = env;
80         return 0;
81 }
82
83 void
84 rte_power_unset_env(void)
85 {
86         if (rte_atomic32_cmpset(&global_env_cfg_status, 1, 0) != 0)
87                 global_default_env = PM_ENV_NOT_SET;
88 }
89
90 enum power_management_env
91 rte_power_get_env(void) {
92         return global_default_env;
93 }
94
95 int
96 rte_power_init(unsigned int lcore_id)
97 {
98         int ret = -1;
99
100         switch (global_default_env) {
101         case PM_ENV_ACPI_CPUFREQ:
102                 return power_acpi_cpufreq_init(lcore_id);
103         case PM_ENV_KVM_VM:
104                 return power_kvm_vm_init(lcore_id);
105         case PM_ENV_PSTATE_CPUFREQ:
106                 return power_pstate_cpufreq_init(lcore_id);
107         default:
108                 RTE_LOG(INFO, POWER, "Env isn't set yet!\n");
109         }
110
111         /* Auto detect Environment */
112         RTE_LOG(INFO, POWER, "Attempting to initialise ACPI cpufreq power management...\n");
113         ret = power_acpi_cpufreq_init(lcore_id);
114         if (ret == 0) {
115                 rte_power_set_env(PM_ENV_ACPI_CPUFREQ);
116                 goto out;
117         }
118
119         RTE_LOG(INFO, POWER, "Attempting to initialise PSTAT power management...\n");
120         ret = power_pstate_cpufreq_init(lcore_id);
121         if (ret == 0) {
122                 rte_power_set_env(PM_ENV_PSTATE_CPUFREQ);
123                 goto out;
124         }
125
126         RTE_LOG(INFO, POWER, "Attempting to initialise VM power management...\n");
127         ret = power_kvm_vm_init(lcore_id);
128         if (ret == 0) {
129                 rte_power_set_env(PM_ENV_KVM_VM);
130                 goto out;
131         }
132         RTE_LOG(ERR, POWER, "Unable to set Power Management Environment for lcore "
133                         "%u\n", lcore_id);
134 out:
135         return ret;
136 }
137
138 int
139 rte_power_exit(unsigned int lcore_id)
140 {
141         switch (global_default_env) {
142         case PM_ENV_ACPI_CPUFREQ:
143                 return power_acpi_cpufreq_exit(lcore_id);
144         case PM_ENV_KVM_VM:
145                 return power_kvm_vm_exit(lcore_id);
146         case PM_ENV_PSTATE_CPUFREQ:
147                 return power_pstate_cpufreq_exit(lcore_id);
148         default:
149                 RTE_LOG(ERR, POWER, "Environment has not been set, unable to exit gracefully\n");
150
151         }
152         return -1;
153
154 }