tools/power/x86/intel-speed-select: Abstract get_get_trl
[platform/kernel/linux-starfive.git] / tools / power / x86 / intel-speed-select / isst-core-mbox.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Intel Speed Select -- Enumerate and control features for Mailbox Interface
4  * Copyright (c) 2023 Intel Corporation.
5  */
6 #include "isst.h"
7
8 static int mbox_get_disp_freq_multiplier(void)
9 {
10         return DISP_FREQ_MULTIPLIER;
11 }
12
13 static int mbox_get_trl_max_levels(void)
14 {
15         return 3;
16 }
17
18 static char *mbox_get_trl_level_name(int level)
19 {
20         switch (level) {
21         case 0:
22                 return "sse";
23         case 1:
24                 return "avx2";
25         case 2:
26                 return "avx512";
27         default:
28                 return NULL;
29         }
30 }
31
32 static int mbox_is_punit_valid(struct isst_id *id)
33 {
34         if (id->cpu < 0)
35                 return 0;
36
37         if (id->pkg < 0 || id->die < 0 || id->punit)
38                 return 0;
39
40         return 1;
41 }
42
43 static int mbox_get_config_levels(struct isst_id *id, struct isst_pkg_ctdp *pkg_dev)
44 {
45         unsigned int resp;
46         int ret;
47
48         ret = isst_send_mbox_command(id->cpu, CONFIG_TDP,
49                                      CONFIG_TDP_GET_LEVELS_INFO, 0, 0, &resp);
50         if (ret) {
51                 pkg_dev->levels = 0;
52                 pkg_dev->locked = 1;
53                 pkg_dev->current_level = 0;
54                 pkg_dev->version = 0;
55                 pkg_dev->enabled = 0;
56                 return 0;
57         }
58
59         debug_printf("cpu:%d CONFIG_TDP_GET_LEVELS_INFO resp:%x\n", id->cpu, resp);
60
61         pkg_dev->version = resp & 0xff;
62         pkg_dev->levels = (resp >> 8) & 0xff;
63         pkg_dev->current_level = (resp >> 16) & 0xff;
64         pkg_dev->locked = !!(resp & BIT(24));
65         pkg_dev->enabled = !!(resp & BIT(31));
66
67         return 0;
68 }
69
70 static int mbox_get_ctdp_control(struct isst_id *id, int config_index,
71                           struct isst_pkg_ctdp_level_info *ctdp_level)
72 {
73         int cp_state, cp_cap;
74         unsigned int resp;
75         int ret;
76
77         ret = isst_send_mbox_command(id->cpu, CONFIG_TDP,
78                                      CONFIG_TDP_GET_TDP_CONTROL, 0,
79                                      config_index, &resp);
80         if (ret)
81                 return ret;
82
83         ctdp_level->fact_support = resp & BIT(0);
84         ctdp_level->pbf_support = !!(resp & BIT(1));
85         ctdp_level->fact_enabled = !!(resp & BIT(16));
86         ctdp_level->pbf_enabled = !!(resp & BIT(17));
87
88         ret = isst_read_pm_config(id, &cp_state, &cp_cap);
89         if (ret) {
90                 debug_printf("cpu:%d pm_config is not supported\n", id->cpu);
91         } else {
92                 debug_printf("cpu:%d pm_config SST-CP state:%d cap:%d\n", id->cpu, cp_state, cp_cap);
93                 ctdp_level->sst_cp_support = cp_cap;
94                 ctdp_level->sst_cp_enabled = cp_state;
95         }
96
97         debug_printf(
98                 "cpu:%d CONFIG_TDP_GET_TDP_CONTROL resp:%x fact_support:%d pbf_support: %d fact_enabled:%d pbf_enabled:%d\n",
99                 id->cpu, resp, ctdp_level->fact_support, ctdp_level->pbf_support,
100                 ctdp_level->fact_enabled, ctdp_level->pbf_enabled);
101
102         return 0;
103 }
104
105 static int mbox_get_tdp_info(struct isst_id *id, int config_index,
106                       struct isst_pkg_ctdp_level_info *ctdp_level)
107 {
108         unsigned int resp;
109         int ret;
110
111         ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_TDP_INFO,
112                                      0, config_index, &resp);
113         if (ret) {
114                 isst_display_error_info_message(1, "Invalid level, Can't get TDP information at level", 1, config_index);
115                 return ret;
116         }
117
118         ctdp_level->pkg_tdp = resp & GENMASK(14, 0);
119         ctdp_level->tdp_ratio = (resp & GENMASK(23, 16)) >> 16;
120
121         debug_printf(
122                 "cpu:%d ctdp:%d CONFIG_TDP_GET_TDP_INFO resp:%x tdp_ratio:%d pkg_tdp:%d\n",
123                 id->cpu, config_index, resp, ctdp_level->tdp_ratio,
124                 ctdp_level->pkg_tdp);
125
126         ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_TJMAX_INFO,
127                                      0, config_index, &resp);
128         if (ret)
129                 return ret;
130
131         ctdp_level->t_proc_hot = resp & GENMASK(7, 0);
132
133         debug_printf(
134                 "cpu:%d ctdp:%d CONFIG_TDP_GET_TJMAX_INFO resp:%x t_proc_hot:%d\n",
135                 id->cpu, config_index, resp, ctdp_level->t_proc_hot);
136
137         return 0;
138 }
139
140 static int mbox_get_pwr_info(struct isst_id *id, int config_index,
141                       struct isst_pkg_ctdp_level_info *ctdp_level)
142 {
143         unsigned int resp;
144         int ret;
145
146         ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_PWR_INFO,
147                                      0, config_index, &resp);
148         if (ret)
149                 return ret;
150
151         ctdp_level->pkg_max_power = resp & GENMASK(14, 0);
152         ctdp_level->pkg_min_power = (resp & GENMASK(30, 16)) >> 16;
153
154         debug_printf(
155                 "cpu:%d ctdp:%d CONFIG_TDP_GET_PWR_INFO resp:%x pkg_max_power:%d pkg_min_power:%d\n",
156                 id->cpu, config_index, resp, ctdp_level->pkg_max_power,
157                 ctdp_level->pkg_min_power);
158
159         return 0;
160 }
161
162 static int mbox_get_coremask_info(struct isst_id *id, int config_index,
163                            struct isst_pkg_ctdp_level_info *ctdp_level)
164 {
165         unsigned int resp;
166         int i, ret;
167
168         ctdp_level->cpu_count = 0;
169         for (i = 0; i < 2; ++i) {
170                 unsigned long long mask;
171                 int cpu_count = 0;
172
173                 ret = isst_send_mbox_command(id->cpu, CONFIG_TDP,
174                                              CONFIG_TDP_GET_CORE_MASK, 0,
175                                              (i << 8) | config_index, &resp);
176                 if (ret)
177                         return ret;
178
179                 debug_printf(
180                         "cpu:%d ctdp:%d mask:%d CONFIG_TDP_GET_CORE_MASK resp:%x\n",
181                         id->cpu, config_index, i, resp);
182
183                 mask = (unsigned long long)resp << (32 * i);
184                 set_cpu_mask_from_punit_coremask(id, mask,
185                                                  ctdp_level->core_cpumask_size,
186                                                  ctdp_level->core_cpumask,
187                                                  &cpu_count);
188                 ctdp_level->cpu_count += cpu_count;
189                 debug_printf("cpu:%d ctdp:%d mask:%d cpu count:%d\n", id->cpu,
190                              config_index, i, ctdp_level->cpu_count);
191         }
192
193         return 0;
194 }
195
196 static int mbox_get_get_trl(struct isst_id *id, int level, int avx_level, int *trl)
197 {
198         unsigned int req, resp;
199         int ret;
200
201         req = level | (avx_level << 16);
202         ret = isst_send_mbox_command(id->cpu, CONFIG_TDP,
203                                      CONFIG_TDP_GET_TURBO_LIMIT_RATIOS, 0, req,
204                                      &resp);
205         if (ret)
206                 return ret;
207
208         debug_printf(
209                 "cpu:%d CONFIG_TDP_GET_TURBO_LIMIT_RATIOS req:%x resp:%x\n",
210                 id->cpu, req, resp);
211
212         trl[0] = resp & GENMASK(7, 0);
213         trl[1] = (resp & GENMASK(15, 8)) >> 8;
214         trl[2] = (resp & GENMASK(23, 16)) >> 16;
215         trl[3] = (resp & GENMASK(31, 24)) >> 24;
216
217         req = level | BIT(8) | (avx_level << 16);
218         ret = isst_send_mbox_command(id->cpu, CONFIG_TDP,
219                                      CONFIG_TDP_GET_TURBO_LIMIT_RATIOS, 0, req,
220                                      &resp);
221         if (ret)
222                 return ret;
223
224         debug_printf("cpu:%d CONFIG_TDP_GET_TURBO_LIMIT req:%x resp:%x\n", id->cpu,
225                      req, resp);
226
227         trl[4] = resp & GENMASK(7, 0);
228         trl[5] = (resp & GENMASK(15, 8)) >> 8;
229         trl[6] = (resp & GENMASK(23, 16)) >> 16;
230         trl[7] = (resp & GENMASK(31, 24)) >> 24;
231
232         return 0;
233 }
234
235 static struct isst_platform_ops mbox_ops = {
236         .get_disp_freq_multiplier = mbox_get_disp_freq_multiplier,
237         .get_trl_max_levels = mbox_get_trl_max_levels,
238         .get_trl_level_name = mbox_get_trl_level_name,
239         .is_punit_valid = mbox_is_punit_valid,
240         .get_config_levels = mbox_get_config_levels,
241         .get_ctdp_control = mbox_get_ctdp_control,
242         .get_tdp_info = mbox_get_tdp_info,
243         .get_pwr_info = mbox_get_pwr_info,
244         .get_coremask_info = mbox_get_coremask_info,
245         .get_get_trl = mbox_get_get_trl,
246 };
247
248 struct isst_platform_ops *mbox_get_platform_ops(void)
249 {
250         return &mbox_ops;
251 }