// SPDX-License-Identifier: GPL-2.0
/*
* Intel Speed Select -- Enumerate and control features
* Copyright (c) 2019 Intel Corporation.
*/
#include "isst.h"
int isst_write_pm_config(int cpu, int cp_state)
{
unsigned int req, resp;
int ret;
if (cp_state)
req = BIT(16);
else
req = 0;
ret = isst_send_mbox_command(cpu, WRITE_PM_CONFIG, PM_FEATURE, 0, req,
&resp);
if (ret)
return ret;
debug_printf("cpu:%d WRITE_PM_CONFIG resp:%x\n", cpu, resp);
return 0;
}
int isst_read_pm_config(int cpu, int *cp_state, int *cp_cap)
{
unsigned int resp;
int ret;
ret = isst_send_mbox_command(cpu, READ_PM_CONFIG, PM_FEATURE, 0, 0,
&resp);
if (ret)
return ret;
debug_printf("cpu:%d READ_PM_CONFIG resp:%x\n", cpu, resp);
*cp_state = resp & BIT(16);
*cp_cap = resp & BIT(0) ? 1 : 0;
return 0;
}
int isst_get_ctdp_levels(int cpu, struct isst_pkg_ctdp *pkg_dev)
{
unsigned int resp;
int ret;
ret = isst_send_mbox_command(cpu, CONFIG_TDP,
CONFIG_TDP_GET_LEVELS_INFO, 0, 0, &resp);
if (ret) {
pkg_dev->levels = 0;
pkg_dev->locked = 1;
pkg_dev->current_level = 0;
pkg_dev->version = 0;
pkg_dev->enabled = 0;
return 0;
}
debug_printf("cpu:%d CONFIG_TDP_GET_LEVELS_INFO resp:%x\n", cpu, resp);
pkg_dev->version = resp & 0xff;
pkg_dev->levels = (resp >> 8) & 0xff;
pkg_dev->current_level = (resp >> 16) & 0xff;
pkg_dev->locked = !!(resp & BIT(24));
pkg_dev->enabled = !!(resp & BIT(31));
return 0;
}
int isst_get_ctdp_control(int cpu, int config_index,
struct isst_pkg_ctdp_level_info *ctdp_level)
{
int cp_state, cp_cap;
unsigned int resp;
int ret;
ret = isst_send_mbox_command(cpu, CONFIG_TDP,
CONFIG_TDP_GET_TDP_CONTROL, 0,
config_index, &resp);
if (ret)
return ret;
ctdp_level->fact_support = resp & BIT(0);
ctdp_level->pbf_support = !!(resp & BIT(1));
ctdp_level->fact_enabled = !!(resp & BIT(16));
ctdp_level->pbf_enabled = !!(resp & BIT(17));
ret = isst_read_pm_config(cpu, &cp_state, &cp_cap);
if (ret) {
debug_printf("cpu:%d pm_config is not supported \n", cpu);
} else {
debug_printf("cpu:%d pm_config SST-CP state:%d cap:%d \n", cpu, cp_state, cp_cap);
ctdp_level->sst_cp_support = cp_cap;
ctdp_level->sst_cp_enabled = cp_state;
}
debug_printf(
"cpu:%d CONFIG_TDP_GET_TDP_CONTROL resp:%x fact_support:%d pbf_support: %d fact_enabled:%d pbf_enabled:%d\n",
cpu, resp, ctdp_level->fact_support, ctdp_level->pbf_support,
ctdp_level->fact_enabled, ctdp_level->pbf_enabled);
return 0;
}
int isst_get_tdp_info(int cpu, int config_index,
struct isst_pkg_ctdp_level_info *ctdp_level)
{
unsigned int resp;
int ret;
ret = isst_send_mbox_command(cpu, CONFIG_TDP, CONFIG_TDP_GET_TDP_INFO,
0, config_index, &resp);
if (ret)
return ret;
ctdp_level->pkg_tdp = resp & GENMASK(14, 0);
ctdp_level->tdp_ratio = (resp & GENMASK(23, 16)) >> 16;
debug_printf(
"cpu:%d ctdp:%d CONFIG_TDP_GET_TDP_INFO resp:%x tdp_ratio:%d pkg_tdp:%d\n",
cpu, config_index, resp, ctdp_level->tdp_ratio,
ctdp_level->pkg_tdp);
return 0;
}
int isst_get_pwr_info(int cpu, int config_index,
struct isst_pkg_ctdp_level_info *ctdp_level)
{
unsigned int resp;