1 // SPDX-License-Identifier: GPL-2.0
3 * Intel Speed Select -- Enumerate and control features for Mailbox Interface
4 * Copyright (c) 2023 Intel Corporation.
8 static int mbox_get_disp_freq_multiplier(void)
10 return DISP_FREQ_MULTIPLIER;
13 static int mbox_get_trl_max_levels(void)
18 static char *mbox_get_trl_level_name(int level)
32 static int mbox_is_punit_valid(struct isst_id *id)
37 if (id->pkg < 0 || id->die < 0 || id->punit)
43 static int mbox_get_config_levels(struct isst_id *id, struct isst_pkg_ctdp *pkg_dev)
48 ret = isst_send_mbox_command(id->cpu, CONFIG_TDP,
49 CONFIG_TDP_GET_LEVELS_INFO, 0, 0, &resp);
53 pkg_dev->current_level = 0;
59 debug_printf("cpu:%d CONFIG_TDP_GET_LEVELS_INFO resp:%x\n", id->cpu, resp);
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));
70 static int mbox_get_ctdp_control(struct isst_id *id, int config_index,
71 struct isst_pkg_ctdp_level_info *ctdp_level)
77 ret = isst_send_mbox_command(id->cpu, CONFIG_TDP,
78 CONFIG_TDP_GET_TDP_CONTROL, 0,
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));
88 ret = isst_read_pm_config(id, &cp_state, &cp_cap);
90 debug_printf("cpu:%d pm_config is not supported\n", id->cpu);
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;
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);
105 static int mbox_get_tdp_info(struct isst_id *id, int config_index,
106 struct isst_pkg_ctdp_level_info *ctdp_level)
111 ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_TDP_INFO,
112 0, config_index, &resp);
114 isst_display_error_info_message(1, "Invalid level, Can't get TDP information at level", 1, config_index);
118 ctdp_level->pkg_tdp = resp & GENMASK(14, 0);
119 ctdp_level->tdp_ratio = (resp & GENMASK(23, 16)) >> 16;
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);
126 ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_TJMAX_INFO,
127 0, config_index, &resp);
131 ctdp_level->t_proc_hot = resp & GENMASK(7, 0);
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);
140 static int mbox_get_pwr_info(struct isst_id *id, int config_index,
141 struct isst_pkg_ctdp_level_info *ctdp_level)
146 ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_PWR_INFO,
147 0, config_index, &resp);
151 ctdp_level->pkg_max_power = resp & GENMASK(14, 0);
152 ctdp_level->pkg_min_power = (resp & GENMASK(30, 16)) >> 16;
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);
162 static int mbox_get_coremask_info(struct isst_id *id, int config_index,
163 struct isst_pkg_ctdp_level_info *ctdp_level)
168 ctdp_level->cpu_count = 0;
169 for (i = 0; i < 2; ++i) {
170 unsigned long long mask;
173 ret = isst_send_mbox_command(id->cpu, CONFIG_TDP,
174 CONFIG_TDP_GET_CORE_MASK, 0,
175 (i << 8) | config_index, &resp);
180 "cpu:%d ctdp:%d mask:%d CONFIG_TDP_GET_CORE_MASK resp:%x\n",
181 id->cpu, config_index, i, resp);
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,
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);
196 static int mbox_get_get_trl(struct isst_id *id, int level, int avx_level, int *trl)
198 unsigned int req, resp;
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,
209 "cpu:%d CONFIG_TDP_GET_TURBO_LIMIT_RATIOS req:%x resp:%x\n",
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;
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,
224 debug_printf("cpu:%d CONFIG_TDP_GET_TURBO_LIMIT req:%x resp:%x\n", id->cpu,
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;
235 static int mbox_get_trl_bucket_info(struct isst_id *id, int level, unsigned long long *buckets_info)
239 debug_printf("cpu:%d bucket info via MSR\n", id->cpu);
243 ret = isst_send_msr_command(id->cpu, 0x1ae, 0, buckets_info);
247 debug_printf("cpu:%d bucket info via MSR successful 0x%llx\n", id->cpu,
253 static struct isst_platform_ops mbox_ops = {
254 .get_disp_freq_multiplier = mbox_get_disp_freq_multiplier,
255 .get_trl_max_levels = mbox_get_trl_max_levels,
256 .get_trl_level_name = mbox_get_trl_level_name,
257 .is_punit_valid = mbox_is_punit_valid,
258 .get_config_levels = mbox_get_config_levels,
259 .get_ctdp_control = mbox_get_ctdp_control,
260 .get_tdp_info = mbox_get_tdp_info,
261 .get_pwr_info = mbox_get_pwr_info,
262 .get_coremask_info = mbox_get_coremask_info,
263 .get_get_trl = mbox_get_get_trl,
264 .get_trl_bucket_info = mbox_get_trl_bucket_info,
267 struct isst_platform_ops *mbox_get_platform_ops(void)