13fb4f7cdSSrinivas Pandruvada // SPDX-License-Identifier: GPL-2.0
23fb4f7cdSSrinivas Pandruvada /*
33fb4f7cdSSrinivas Pandruvada * Intel Speed Select -- Enumerate and control features
43fb4f7cdSSrinivas Pandruvada * Copyright (c) 2019 Intel Corporation.
53fb4f7cdSSrinivas Pandruvada */
63fb4f7cdSSrinivas Pandruvada
73fb4f7cdSSrinivas Pandruvada #include "isst.h"
83fb4f7cdSSrinivas Pandruvada
9d0d1a603SZhang Rui static struct isst_platform_ops *isst_ops;
10d0d1a603SZhang Rui
11d0d1a603SZhang Rui #define CHECK_CB(_name) \
12d0d1a603SZhang Rui do { \
13d0d1a603SZhang Rui if (!isst_ops || !isst_ops->_name) { \
14d0d1a603SZhang Rui fprintf(stderr, "Invalid ops\n"); \
15d0d1a603SZhang Rui exit(0); \
16d0d1a603SZhang Rui } \
17d0d1a603SZhang Rui } while (0)
18d0d1a603SZhang Rui
isst_set_platform_ops(int api_version)1905aab5b8SZhang Rui int isst_set_platform_ops(int api_version)
20d0d1a603SZhang Rui {
2105aab5b8SZhang Rui switch (api_version) {
2205aab5b8SZhang Rui case 1:
23d0d1a603SZhang Rui isst_ops = mbox_get_platform_ops();
2405aab5b8SZhang Rui break;
2579554aaaSZhang Rui case 2:
2679554aaaSZhang Rui isst_ops = tpmi_get_platform_ops();
2779554aaaSZhang Rui break;
2805aab5b8SZhang Rui default:
2905aab5b8SZhang Rui isst_ops = NULL;
3005aab5b8SZhang Rui break;
3105aab5b8SZhang Rui }
32d0d1a603SZhang Rui
33d0d1a603SZhang Rui if (!isst_ops)
34d0d1a603SZhang Rui return -1;
35d0d1a603SZhang Rui return 0;
36d0d1a603SZhang Rui }
37d0d1a603SZhang Rui
isst_update_platform_param(enum isst_platform_param param,int value)382042c0abSZhang Rui void isst_update_platform_param(enum isst_platform_param param, int value)
392042c0abSZhang Rui {
402b86ed22SZhang Rui CHECK_CB(update_platform_param);
412b86ed22SZhang Rui
422b86ed22SZhang Rui isst_ops->update_platform_param(param, value);
432042c0abSZhang Rui }
442042c0abSZhang Rui
isst_get_disp_freq_multiplier(void)4513b868f8SZhang Rui int isst_get_disp_freq_multiplier(void)
4613b868f8SZhang Rui {
47d0d1a603SZhang Rui CHECK_CB(get_disp_freq_multiplier);
48d0d1a603SZhang Rui return isst_ops->get_disp_freq_multiplier();
4913b868f8SZhang Rui }
5013b868f8SZhang Rui
isst_get_trl_max_levels(void)517c7e7c0dSZhang Rui int isst_get_trl_max_levels(void)
527c7e7c0dSZhang Rui {
53d0d1a603SZhang Rui CHECK_CB(get_trl_max_levels);
54d0d1a603SZhang Rui return isst_ops->get_trl_max_levels();
557c7e7c0dSZhang Rui }
567c7e7c0dSZhang Rui
isst_get_trl_level_name(int level)577c7e7c0dSZhang Rui char *isst_get_trl_level_name(int level)
587c7e7c0dSZhang Rui {
59d0d1a603SZhang Rui CHECK_CB(get_trl_level_name);
60d0d1a603SZhang Rui return isst_ops->get_trl_level_name(level);
617c7e7c0dSZhang Rui }
627c7e7c0dSZhang Rui
isst_is_punit_valid(struct isst_id * id)6357ef2436SZhang Rui int isst_is_punit_valid(struct isst_id *id)
6457ef2436SZhang Rui {
65143584e8SZhang Rui CHECK_CB(is_punit_valid);
66143584e8SZhang Rui return isst_ops->is_punit_valid(id);
6757ef2436SZhang Rui }
6857ef2436SZhang Rui
isst_send_msr_command(unsigned int cpu,unsigned int msr,int write,unsigned long long * req_resp)692042c0abSZhang Rui int isst_send_msr_command(unsigned int cpu, unsigned int msr, int write,
702042c0abSZhang Rui unsigned long long *req_resp)
712042c0abSZhang Rui {
722042c0abSZhang Rui struct isst_if_msr_cmds msr_cmds;
732042c0abSZhang Rui const char *pathname = "/dev/isst_interface";
742042c0abSZhang Rui FILE *outf = get_output_file();
752042c0abSZhang Rui int fd;
762042c0abSZhang Rui
772042c0abSZhang Rui fd = open(pathname, O_RDWR);
782042c0abSZhang Rui if (fd < 0)
792042c0abSZhang Rui err(-1, "%s open failed", pathname);
802042c0abSZhang Rui
812042c0abSZhang Rui msr_cmds.cmd_count = 1;
822042c0abSZhang Rui msr_cmds.msr_cmd[0].logical_cpu = cpu;
832042c0abSZhang Rui msr_cmds.msr_cmd[0].msr = msr;
842042c0abSZhang Rui msr_cmds.msr_cmd[0].read_write = write;
852042c0abSZhang Rui if (write)
862042c0abSZhang Rui msr_cmds.msr_cmd[0].data = *req_resp;
872042c0abSZhang Rui
882042c0abSZhang Rui if (ioctl(fd, ISST_IF_MSR_COMMAND, &msr_cmds) == -1) {
892042c0abSZhang Rui perror("ISST_IF_MSR_COMMAND");
902042c0abSZhang Rui fprintf(outf, "Error: msr_cmd cpu:%d msr:%x read_write:%d\n",
912042c0abSZhang Rui cpu, msr, write);
922042c0abSZhang Rui } else {
932042c0abSZhang Rui if (!write)
942042c0abSZhang Rui *req_resp = msr_cmds.msr_cmd[0].data;
952042c0abSZhang Rui
962042c0abSZhang Rui debug_printf(
972042c0abSZhang Rui "msr_cmd response: cpu:%d msr:%x rd_write:%x resp:%llx %llx\n",
982042c0abSZhang Rui cpu, msr, write, *req_resp, msr_cmds.msr_cmd[0].data);
992042c0abSZhang Rui }
1002042c0abSZhang Rui
1012042c0abSZhang Rui close(fd);
1022042c0abSZhang Rui
1032042c0abSZhang Rui return 0;
1042042c0abSZhang Rui }
1052042c0abSZhang Rui
isst_read_pm_config(struct isst_id * id,int * cp_state,int * cp_cap)106850337ecSZhang Rui int isst_read_pm_config(struct isst_id *id, int *cp_state, int *cp_cap)
107645feeb2SSrinivas Pandruvada {
1088f54104fSZhang Rui CHECK_CB(read_pm_config);
1098f54104fSZhang Rui return isst_ops->read_pm_config(id, cp_state, cp_cap);
110645feeb2SSrinivas Pandruvada }
111645feeb2SSrinivas Pandruvada
isst_get_ctdp_levels(struct isst_id * id,struct isst_pkg_ctdp * pkg_dev)112850337ecSZhang Rui int isst_get_ctdp_levels(struct isst_id *id, struct isst_pkg_ctdp *pkg_dev)
1133fb4f7cdSSrinivas Pandruvada {
11472438744SZhang Rui CHECK_CB(get_config_levels);
11572438744SZhang Rui return isst_ops->get_config_levels(id, pkg_dev);
1163fb4f7cdSSrinivas Pandruvada }
1173fb4f7cdSSrinivas Pandruvada
isst_get_ctdp_control(struct isst_id * id,int config_index,struct isst_pkg_ctdp_level_info * ctdp_level)118850337ecSZhang Rui int isst_get_ctdp_control(struct isst_id *id, int config_index,
1193fb4f7cdSSrinivas Pandruvada struct isst_pkg_ctdp_level_info *ctdp_level)
1203fb4f7cdSSrinivas Pandruvada {
121bbe32d87SZhang Rui CHECK_CB(get_ctdp_control);
122bbe32d87SZhang Rui return isst_ops->get_ctdp_control(id, config_index, ctdp_level);
1233fb4f7cdSSrinivas Pandruvada }
1243fb4f7cdSSrinivas Pandruvada
isst_get_tdp_info(struct isst_id * id,int config_index,struct isst_pkg_ctdp_level_info * ctdp_level)125850337ecSZhang Rui int isst_get_tdp_info(struct isst_id *id, int config_index,
1263fb4f7cdSSrinivas Pandruvada struct isst_pkg_ctdp_level_info *ctdp_level)
1273fb4f7cdSSrinivas Pandruvada {
128645b6605SZhang Rui CHECK_CB(get_tdp_info);
129645b6605SZhang Rui return isst_ops->get_tdp_info(id, config_index, ctdp_level);
1303fb4f7cdSSrinivas Pandruvada }
1313fb4f7cdSSrinivas Pandruvada
isst_get_pwr_info(struct isst_id * id,int config_index,struct isst_pkg_ctdp_level_info * ctdp_level)132850337ecSZhang Rui int isst_get_pwr_info(struct isst_id *id, int config_index,
1333fb4f7cdSSrinivas Pandruvada struct isst_pkg_ctdp_level_info *ctdp_level)
1343fb4f7cdSSrinivas Pandruvada {
135e107dec9SZhang Rui CHECK_CB(get_pwr_info);
136e107dec9SZhang Rui return isst_ops->get_pwr_info(id, config_index, ctdp_level);
1373fb4f7cdSSrinivas Pandruvada }
1383fb4f7cdSSrinivas Pandruvada
isst_get_coremask_info(struct isst_id * id,int config_index,struct isst_pkg_ctdp_level_info * ctdp_level)139850337ecSZhang Rui int isst_get_coremask_info(struct isst_id *id, int config_index,
1403fb4f7cdSSrinivas Pandruvada struct isst_pkg_ctdp_level_info *ctdp_level)
1413fb4f7cdSSrinivas Pandruvada {
142668cc16cSZhang Rui CHECK_CB(get_coremask_info);
143668cc16cSZhang Rui return isst_ops->get_coremask_info(id, config_index, ctdp_level);
1443fb4f7cdSSrinivas Pandruvada }
1453fb4f7cdSSrinivas Pandruvada
isst_get_get_trl_from_msr(struct isst_id * id,int * trl)146850337ecSZhang Rui int isst_get_get_trl_from_msr(struct isst_id *id, int *trl)
1477af5a95bSSrinivas Pandruvada {
1487af5a95bSSrinivas Pandruvada unsigned long long msr_trl;
1497af5a95bSSrinivas Pandruvada int ret;
1507af5a95bSSrinivas Pandruvada
151850337ecSZhang Rui ret = isst_send_msr_command(id->cpu, 0x1AD, 0, &msr_trl);
1527af5a95bSSrinivas Pandruvada if (ret)
1537af5a95bSSrinivas Pandruvada return ret;
1547af5a95bSSrinivas Pandruvada
1557af5a95bSSrinivas Pandruvada trl[0] = msr_trl & GENMASK(7, 0);
1567af5a95bSSrinivas Pandruvada trl[1] = (msr_trl & GENMASK(15, 8)) >> 8;
1577af5a95bSSrinivas Pandruvada trl[2] = (msr_trl & GENMASK(23, 16)) >> 16;
1587af5a95bSSrinivas Pandruvada trl[3] = (msr_trl & GENMASK(31, 24)) >> 24;
1597af5a95bSSrinivas Pandruvada trl[4] = (msr_trl & GENMASK(39, 32)) >> 32;
1607af5a95bSSrinivas Pandruvada trl[5] = (msr_trl & GENMASK(47, 40)) >> 40;
1617af5a95bSSrinivas Pandruvada trl[6] = (msr_trl & GENMASK(55, 48)) >> 48;
1627af5a95bSSrinivas Pandruvada trl[7] = (msr_trl & GENMASK(63, 56)) >> 56;
1637af5a95bSSrinivas Pandruvada
1647af5a95bSSrinivas Pandruvada return 0;
1657af5a95bSSrinivas Pandruvada }
1667af5a95bSSrinivas Pandruvada
isst_get_get_trl(struct isst_id * id,int level,int avx_level,int * trl)167850337ecSZhang Rui int isst_get_get_trl(struct isst_id *id, int level, int avx_level, int *trl)
1683fb4f7cdSSrinivas Pandruvada {
16939f768c3SZhang Rui CHECK_CB(get_get_trl);
17039f768c3SZhang Rui return isst_ops->get_get_trl(id, level, avx_level, trl);
1713fb4f7cdSSrinivas Pandruvada }
1723fb4f7cdSSrinivas Pandruvada
isst_get_get_trls(struct isst_id * id,int level,struct isst_pkg_ctdp_level_info * ctdp_level)1734a17b291SZhang Rui int isst_get_get_trls(struct isst_id *id, int level, struct isst_pkg_ctdp_level_info *ctdp_level)
1744a17b291SZhang Rui {
1754a17b291SZhang Rui CHECK_CB(get_get_trls);
1764a17b291SZhang Rui return isst_ops->get_get_trls(id, level, ctdp_level);
1774a17b291SZhang Rui }
1784a17b291SZhang Rui
isst_get_trl_bucket_info(struct isst_id * id,int level,unsigned long long * buckets_info)1791e37f1b2SZhang Rui int isst_get_trl_bucket_info(struct isst_id *id, int level, unsigned long long *buckets_info)
1801233c7b9SSrinivas Pandruvada {
1811e37f1b2SZhang Rui CHECK_CB(get_trl_bucket_info);
1821e37f1b2SZhang Rui return isst_ops->get_trl_bucket_info(id, level, buckets_info);
1831233c7b9SSrinivas Pandruvada }
1841233c7b9SSrinivas Pandruvada
isst_set_tdp_level(struct isst_id * id,int tdp_level)185850337ecSZhang Rui int isst_set_tdp_level(struct isst_id *id, int tdp_level)
1863fb4f7cdSSrinivas Pandruvada {
187f88c3c4bSZhang Rui CHECK_CB(set_tdp_level);
188f88c3c4bSZhang Rui return isst_ops->set_tdp_level(id, tdp_level);
1893fb4f7cdSSrinivas Pandruvada }
1903fb4f7cdSSrinivas Pandruvada
isst_get_pbf_info(struct isst_id * id,int level,struct isst_pbf_info * pbf_info)191850337ecSZhang Rui int isst_get_pbf_info(struct isst_id *id, int level, struct isst_pbf_info *pbf_info)
1923fb4f7cdSSrinivas Pandruvada {
1936c8edba3SSrinivas Pandruvada struct isst_pkg_ctdp_level_info ctdp_level;
19439bae0fcSSrinivas Pandruvada struct isst_pkg_ctdp pkg_dev;
1957a196290SZhang Rui int ret;
1963fb4f7cdSSrinivas Pandruvada
197850337ecSZhang Rui ret = isst_get_ctdp_levels(id, &pkg_dev);
19839bae0fcSSrinivas Pandruvada if (ret) {
19939bae0fcSSrinivas Pandruvada isst_display_error_info_message(1, "Failed to get number of levels", 0, 0);
20039bae0fcSSrinivas Pandruvada return ret;
20139bae0fcSSrinivas Pandruvada }
20239bae0fcSSrinivas Pandruvada
20339bae0fcSSrinivas Pandruvada if (level > pkg_dev.levels) {
20439bae0fcSSrinivas Pandruvada isst_display_error_info_message(1, "Invalid level", 1, level);
20539bae0fcSSrinivas Pandruvada return -1;
20639bae0fcSSrinivas Pandruvada }
20739bae0fcSSrinivas Pandruvada
208850337ecSZhang Rui ret = isst_get_ctdp_control(id, level, &ctdp_level);
2096c8edba3SSrinivas Pandruvada if (ret)
2106c8edba3SSrinivas Pandruvada return ret;
2116c8edba3SSrinivas Pandruvada
2126c8edba3SSrinivas Pandruvada if (!ctdp_level.pbf_support) {
21339bae0fcSSrinivas Pandruvada isst_display_error_info_message(1, "base-freq feature is not present at this level", 1, level);
2146c8edba3SSrinivas Pandruvada return -1;
2156c8edba3SSrinivas Pandruvada }
2166c8edba3SSrinivas Pandruvada
2173fb4f7cdSSrinivas Pandruvada pbf_info->core_cpumask_size = alloc_cpu_set(&pbf_info->core_cpumask);
2183fb4f7cdSSrinivas Pandruvada
2197a196290SZhang Rui CHECK_CB(get_pbf_info);
2207a196290SZhang Rui return isst_ops->get_pbf_info(id, level, pbf_info);
2213fb4f7cdSSrinivas Pandruvada }
2223fb4f7cdSSrinivas Pandruvada
isst_set_pbf_fact_status(struct isst_id * id,int pbf,int enable)223850337ecSZhang Rui int isst_set_pbf_fact_status(struct isst_id *id, int pbf, int enable)
2243fb4f7cdSSrinivas Pandruvada {
2255843f217SZhang Rui CHECK_CB(set_pbf_fact_status);
2265843f217SZhang Rui return isst_ops->set_pbf_fact_status(id, pbf, enable);
2273fb4f7cdSSrinivas Pandruvada }
2283fb4f7cdSSrinivas Pandruvada
2293fb4f7cdSSrinivas Pandruvada
2303fb4f7cdSSrinivas Pandruvada
isst_get_fact_info(struct isst_id * id,int level,int fact_bucket,struct isst_fact_info * fact_info)231850337ecSZhang Rui int isst_get_fact_info(struct isst_id *id, int level, int fact_bucket, struct isst_fact_info *fact_info)
2323fb4f7cdSSrinivas Pandruvada {
2336c8edba3SSrinivas Pandruvada struct isst_pkg_ctdp_level_info ctdp_level;
234a9fd6ae7SSrinivas Pandruvada struct isst_pkg_ctdp pkg_dev;
2357b5f586dSZhang Rui int ret;
236a9fd6ae7SSrinivas Pandruvada
237850337ecSZhang Rui ret = isst_get_ctdp_levels(id, &pkg_dev);
238a9fd6ae7SSrinivas Pandruvada if (ret) {
239a9fd6ae7SSrinivas Pandruvada isst_display_error_info_message(1, "Failed to get number of levels", 0, 0);
240a9fd6ae7SSrinivas Pandruvada return ret;
241a9fd6ae7SSrinivas Pandruvada }
242a9fd6ae7SSrinivas Pandruvada
243a9fd6ae7SSrinivas Pandruvada if (level > pkg_dev.levels) {
244a9fd6ae7SSrinivas Pandruvada isst_display_error_info_message(1, "Invalid level", 1, level);
245a9fd6ae7SSrinivas Pandruvada return -1;
246a9fd6ae7SSrinivas Pandruvada }
2473fb4f7cdSSrinivas Pandruvada
248850337ecSZhang Rui ret = isst_get_ctdp_control(id, level, &ctdp_level);
2496c8edba3SSrinivas Pandruvada if (ret)
2506c8edba3SSrinivas Pandruvada return ret;
2516c8edba3SSrinivas Pandruvada
2526c8edba3SSrinivas Pandruvada if (!ctdp_level.fact_support) {
253a9fd6ae7SSrinivas Pandruvada isst_display_error_info_message(1, "turbo-freq feature is not present at this level", 1, level);
2546c8edba3SSrinivas Pandruvada return -1;
2556c8edba3SSrinivas Pandruvada }
2567b5f586dSZhang Rui CHECK_CB(get_fact_info);
2577b5f586dSZhang Rui return isst_ops->get_fact_info(id, level, fact_bucket, fact_info);
2583fb4f7cdSSrinivas Pandruvada }
2593fb4f7cdSSrinivas Pandruvada
isst_get_trl(struct isst_id * id,unsigned long long * trl)260850337ecSZhang Rui int isst_get_trl(struct isst_id *id, unsigned long long *trl)
2612c7dc57eSSrinivas Pandruvada {
2622c7dc57eSSrinivas Pandruvada int ret;
2632c7dc57eSSrinivas Pandruvada
264850337ecSZhang Rui ret = isst_send_msr_command(id->cpu, 0x1AD, 0, trl);
2652c7dc57eSSrinivas Pandruvada if (ret)
2662c7dc57eSSrinivas Pandruvada return ret;
2672c7dc57eSSrinivas Pandruvada
2682c7dc57eSSrinivas Pandruvada return 0;
2692c7dc57eSSrinivas Pandruvada }
2702c7dc57eSSrinivas Pandruvada
isst_set_trl(struct isst_id * id,unsigned long long trl)271850337ecSZhang Rui int isst_set_trl(struct isst_id *id, unsigned long long trl)
2723fb4f7cdSSrinivas Pandruvada {
2733fb4f7cdSSrinivas Pandruvada int ret;
2743fb4f7cdSSrinivas Pandruvada
2753fb4f7cdSSrinivas Pandruvada if (!trl)
2763fb4f7cdSSrinivas Pandruvada trl = 0xFFFFFFFFFFFFFFFFULL;
2773fb4f7cdSSrinivas Pandruvada
278850337ecSZhang Rui ret = isst_send_msr_command(id->cpu, 0x1AD, 1, &trl);
2793fb4f7cdSSrinivas Pandruvada if (ret)
2803fb4f7cdSSrinivas Pandruvada return ret;
2813fb4f7cdSSrinivas Pandruvada
2823fb4f7cdSSrinivas Pandruvada return 0;
2833fb4f7cdSSrinivas Pandruvada }
2843fb4f7cdSSrinivas Pandruvada
isst_set_trl_from_current_tdp(struct isst_id * id,unsigned long long trl)285850337ecSZhang Rui int isst_set_trl_from_current_tdp(struct isst_id *id, unsigned long long trl)
2863fb4f7cdSSrinivas Pandruvada {
2873fb4f7cdSSrinivas Pandruvada unsigned long long msr_trl;
2883fb4f7cdSSrinivas Pandruvada int ret;
2893fb4f7cdSSrinivas Pandruvada
290*d0e12c46SZhang Rui if (id->cpu < 0)
291*d0e12c46SZhang Rui return 0;
292*d0e12c46SZhang Rui
2933fb4f7cdSSrinivas Pandruvada if (trl) {
2943fb4f7cdSSrinivas Pandruvada msr_trl = trl;
2953fb4f7cdSSrinivas Pandruvada } else {
2963fb4f7cdSSrinivas Pandruvada struct isst_pkg_ctdp pkg_dev;
2973fb4f7cdSSrinivas Pandruvada int trl[8];
2983fb4f7cdSSrinivas Pandruvada int i;
2993fb4f7cdSSrinivas Pandruvada
300850337ecSZhang Rui ret = isst_get_ctdp_levels(id, &pkg_dev);
3013fb4f7cdSSrinivas Pandruvada if (ret)
3023fb4f7cdSSrinivas Pandruvada return ret;
3033fb4f7cdSSrinivas Pandruvada
304850337ecSZhang Rui ret = isst_get_get_trl(id, pkg_dev.current_level, 0, trl);
3053fb4f7cdSSrinivas Pandruvada if (ret)
3063fb4f7cdSSrinivas Pandruvada return ret;
3073fb4f7cdSSrinivas Pandruvada
3083fb4f7cdSSrinivas Pandruvada msr_trl = 0;
3093fb4f7cdSSrinivas Pandruvada for (i = 0; i < 8; ++i) {
3103fb4f7cdSSrinivas Pandruvada unsigned long long _trl = trl[i];
3113fb4f7cdSSrinivas Pandruvada
3123fb4f7cdSSrinivas Pandruvada msr_trl |= (_trl << (i * 8));
3133fb4f7cdSSrinivas Pandruvada }
3143fb4f7cdSSrinivas Pandruvada }
315850337ecSZhang Rui ret = isst_send_msr_command(id->cpu, 0x1AD, 1, &msr_trl);
3163fb4f7cdSSrinivas Pandruvada if (ret)
3173fb4f7cdSSrinivas Pandruvada return ret;
3183fb4f7cdSSrinivas Pandruvada
3193fb4f7cdSSrinivas Pandruvada return 0;
3203fb4f7cdSSrinivas Pandruvada }
3213fb4f7cdSSrinivas Pandruvada
3223fb4f7cdSSrinivas Pandruvada /* Return 1 if locked */
isst_get_config_tdp_lock_status(struct isst_id * id)323850337ecSZhang Rui int isst_get_config_tdp_lock_status(struct isst_id *id)
3243fb4f7cdSSrinivas Pandruvada {
3253fb4f7cdSSrinivas Pandruvada unsigned long long tdp_control = 0;
3263fb4f7cdSSrinivas Pandruvada int ret;
3273fb4f7cdSSrinivas Pandruvada
328850337ecSZhang Rui ret = isst_send_msr_command(id->cpu, 0x64b, 0, &tdp_control);
3293fb4f7cdSSrinivas Pandruvada if (ret)
3303fb4f7cdSSrinivas Pandruvada return ret;
3313fb4f7cdSSrinivas Pandruvada
3323fb4f7cdSSrinivas Pandruvada ret = !!(tdp_control & BIT(31));
3333fb4f7cdSSrinivas Pandruvada
3343fb4f7cdSSrinivas Pandruvada return ret;
3353fb4f7cdSSrinivas Pandruvada }
3363fb4f7cdSSrinivas Pandruvada
isst_get_process_ctdp_complete(struct isst_id * id,struct isst_pkg_ctdp * pkg_dev)337850337ecSZhang Rui void isst_get_process_ctdp_complete(struct isst_id *id, struct isst_pkg_ctdp *pkg_dev)
3383fb4f7cdSSrinivas Pandruvada {
3393fb4f7cdSSrinivas Pandruvada int i;
3403fb4f7cdSSrinivas Pandruvada
3413fb4f7cdSSrinivas Pandruvada if (!pkg_dev->processed)
3423fb4f7cdSSrinivas Pandruvada return;
3433fb4f7cdSSrinivas Pandruvada
3443fb4f7cdSSrinivas Pandruvada for (i = 0; i < pkg_dev->levels; ++i) {
3453fb4f7cdSSrinivas Pandruvada struct isst_pkg_ctdp_level_info *ctdp_level;
3463fb4f7cdSSrinivas Pandruvada
3473fb4f7cdSSrinivas Pandruvada ctdp_level = &pkg_dev->ctdp_level[i];
3483fb4f7cdSSrinivas Pandruvada if (ctdp_level->pbf_support)
3493fb4f7cdSSrinivas Pandruvada free_cpu_set(ctdp_level->pbf_info.core_cpumask);
3503fb4f7cdSSrinivas Pandruvada free_cpu_set(ctdp_level->core_cpumask);
3513fb4f7cdSSrinivas Pandruvada }
3523fb4f7cdSSrinivas Pandruvada }
3533fb4f7cdSSrinivas Pandruvada
isst_adjust_uncore_freq(struct isst_id * id,int config_index,struct isst_pkg_ctdp_level_info * ctdp_level)35473452cccSZhang Rui void isst_adjust_uncore_freq(struct isst_id *id, int config_index,
355e4cbd0f1SZhang Rui struct isst_pkg_ctdp_level_info *ctdp_level)
356e4cbd0f1SZhang Rui {
35773452cccSZhang Rui CHECK_CB(adjust_uncore_freq);
35873452cccSZhang Rui return isst_ops->adjust_uncore_freq(id, config_index, ctdp_level);
359e4cbd0f1SZhang Rui }
360e4cbd0f1SZhang Rui
isst_get_process_ctdp(struct isst_id * id,int tdp_level,struct isst_pkg_ctdp * pkg_dev)361850337ecSZhang Rui int isst_get_process_ctdp(struct isst_id *id, int tdp_level, struct isst_pkg_ctdp *pkg_dev)
3623fb4f7cdSSrinivas Pandruvada {
363ac9d05eaSSrinivas Pandruvada int i, ret, valid = 0;
3643fb4f7cdSSrinivas Pandruvada
3653fb4f7cdSSrinivas Pandruvada if (pkg_dev->processed)
3663fb4f7cdSSrinivas Pandruvada return 0;
3673fb4f7cdSSrinivas Pandruvada
368850337ecSZhang Rui ret = isst_get_ctdp_levels(id, pkg_dev);
3693fb4f7cdSSrinivas Pandruvada if (ret)
3703fb4f7cdSSrinivas Pandruvada return ret;
3713fb4f7cdSSrinivas Pandruvada
3723fb4f7cdSSrinivas Pandruvada debug_printf("cpu: %d ctdp enable:%d current level: %d levels:%d\n",
373850337ecSZhang Rui id->cpu, pkg_dev->enabled, pkg_dev->current_level,
3743fb4f7cdSSrinivas Pandruvada pkg_dev->levels);
3753fb4f7cdSSrinivas Pandruvada
376ac9d05eaSSrinivas Pandruvada if (tdp_level != 0xff && tdp_level > pkg_dev->levels) {
377ac9d05eaSSrinivas Pandruvada isst_display_error_info_message(1, "Invalid level", 0, 0);
378ac9d05eaSSrinivas Pandruvada return -1;
379ac9d05eaSSrinivas Pandruvada }
380ac9d05eaSSrinivas Pandruvada
381ac9d05eaSSrinivas Pandruvada if (!pkg_dev->enabled)
382ac9d05eaSSrinivas Pandruvada isst_display_error_info_message(0, "perf-profile feature is not supported, just base-config level 0 is valid", 0, 0);
383ac9d05eaSSrinivas Pandruvada
3843fb4f7cdSSrinivas Pandruvada for (i = 0; i <= pkg_dev->levels; ++i) {
3853fb4f7cdSSrinivas Pandruvada struct isst_pkg_ctdp_level_info *ctdp_level;
3863fb4f7cdSSrinivas Pandruvada
3873fb4f7cdSSrinivas Pandruvada if (tdp_level != 0xff && i != tdp_level)
3883fb4f7cdSSrinivas Pandruvada continue;
3893fb4f7cdSSrinivas Pandruvada
390850337ecSZhang Rui debug_printf("cpu:%d Get Information for TDP level:%d\n", id->cpu,
3913fb4f7cdSSrinivas Pandruvada i);
3923fb4f7cdSSrinivas Pandruvada ctdp_level = &pkg_dev->ctdp_level[i];
3933fb4f7cdSSrinivas Pandruvada
3943fb4f7cdSSrinivas Pandruvada ctdp_level->level = i;
395850337ecSZhang Rui ctdp_level->control_cpu = id->cpu;
39656d64692SZhang Rui ctdp_level->pkg_id = id->pkg;
39756d64692SZhang Rui ctdp_level->die_id = id->die;
3983fb4f7cdSSrinivas Pandruvada
399850337ecSZhang Rui ret = isst_get_ctdp_control(id, i, ctdp_level);
4003fb4f7cdSSrinivas Pandruvada if (ret)
40120183ccdSSrinivas Pandruvada continue;
40220183ccdSSrinivas Pandruvada
403ac9d05eaSSrinivas Pandruvada valid = 1;
40420183ccdSSrinivas Pandruvada pkg_dev->processed = 1;
40520183ccdSSrinivas Pandruvada ctdp_level->processed = 1;
4063fb4f7cdSSrinivas Pandruvada
4077af5a95bSSrinivas Pandruvada if (ctdp_level->pbf_support) {
408850337ecSZhang Rui ret = isst_get_pbf_info(id, i, &ctdp_level->pbf_info);
4097af5a95bSSrinivas Pandruvada if (!ret)
4107af5a95bSSrinivas Pandruvada ctdp_level->pbf_found = 1;
4117af5a95bSSrinivas Pandruvada }
4127af5a95bSSrinivas Pandruvada
4137af5a95bSSrinivas Pandruvada if (ctdp_level->fact_support) {
414850337ecSZhang Rui ret = isst_get_fact_info(id, i, 0xff,
4157af5a95bSSrinivas Pandruvada &ctdp_level->fact_info);
4167af5a95bSSrinivas Pandruvada if (ret)
4177af5a95bSSrinivas Pandruvada return ret;
4187af5a95bSSrinivas Pandruvada }
4197af5a95bSSrinivas Pandruvada
42007f262d8SSrinivas Pandruvada if (!pkg_dev->enabled && is_skx_based_platform()) {
4217af5a95bSSrinivas Pandruvada int freq;
4227af5a95bSSrinivas Pandruvada
423850337ecSZhang Rui freq = get_cpufreq_base_freq(id->cpu);
4247af5a95bSSrinivas Pandruvada if (freq > 0) {
4257af5a95bSSrinivas Pandruvada ctdp_level->sse_p1 = freq / 100000;
4267af5a95bSSrinivas Pandruvada ctdp_level->tdp_ratio = ctdp_level->sse_p1;
4277af5a95bSSrinivas Pandruvada }
4287af5a95bSSrinivas Pandruvada
4297c7e7c0dSZhang Rui isst_get_get_trl_from_msr(id, ctdp_level->trl_ratios[0]);
4301e37f1b2SZhang Rui isst_get_trl_bucket_info(id, i, &ctdp_level->trl_cores);
4317af5a95bSSrinivas Pandruvada continue;
4327af5a95bSSrinivas Pandruvada }
4337af5a95bSSrinivas Pandruvada
434850337ecSZhang Rui ret = isst_get_tdp_info(id, i, ctdp_level);
4353fb4f7cdSSrinivas Pandruvada if (ret)
4363fb4f7cdSSrinivas Pandruvada return ret;
4373fb4f7cdSSrinivas Pandruvada
438850337ecSZhang Rui ret = isst_get_pwr_info(id, i, ctdp_level);
4393fb4f7cdSSrinivas Pandruvada if (ret)
4403fb4f7cdSSrinivas Pandruvada return ret;
4413fb4f7cdSSrinivas Pandruvada
4423fb4f7cdSSrinivas Pandruvada ctdp_level->core_cpumask_size =
4433fb4f7cdSSrinivas Pandruvada alloc_cpu_set(&ctdp_level->core_cpumask);
444850337ecSZhang Rui ret = isst_get_coremask_info(id, i, ctdp_level);
4453fb4f7cdSSrinivas Pandruvada if (ret)
4463fb4f7cdSSrinivas Pandruvada return ret;
4473fb4f7cdSSrinivas Pandruvada
4481e37f1b2SZhang Rui ret = isst_get_trl_bucket_info(id, i, &ctdp_level->trl_cores);
4491233c7b9SSrinivas Pandruvada if (ret)
4501233c7b9SSrinivas Pandruvada return ret;
4511233c7b9SSrinivas Pandruvada
4524a17b291SZhang Rui ret = isst_get_get_trls(id, i, ctdp_level);
4533fb4f7cdSSrinivas Pandruvada if (ret)
4543fb4f7cdSSrinivas Pandruvada return ret;
4557c7e7c0dSZhang Rui }
4563fb4f7cdSSrinivas Pandruvada
457ac9d05eaSSrinivas Pandruvada if (!valid)
458850337ecSZhang Rui isst_display_error_info_message(0, "Invalid level, Can't get TDP control information at specified levels on cpu", 1, id->cpu);
459ac9d05eaSSrinivas Pandruvada
4603fb4f7cdSSrinivas Pandruvada return 0;
4613fb4f7cdSSrinivas Pandruvada }
4623fb4f7cdSSrinivas Pandruvada
isst_clos_get_clos_information(struct isst_id * id,int * enable,int * type)463850337ecSZhang Rui int isst_clos_get_clos_information(struct isst_id *id, int *enable, int *type)
464188afed9SSrinivas Pandruvada {
465a07bdb81SZhang Rui CHECK_CB(get_clos_information);
466a07bdb81SZhang Rui return isst_ops->get_clos_information(id, enable, type);
467188afed9SSrinivas Pandruvada }
468188afed9SSrinivas Pandruvada
isst_pm_qos_config(struct isst_id * id,int enable_clos,int priority_type)469850337ecSZhang Rui int isst_pm_qos_config(struct isst_id *id, int enable_clos, int priority_type)
4703fb4f7cdSSrinivas Pandruvada {
471904d2baaSZhang Rui CHECK_CB(pm_qos_config);
472904d2baaSZhang Rui return isst_ops->pm_qos_config(id, enable_clos, priority_type);
4733fb4f7cdSSrinivas Pandruvada }
4743fb4f7cdSSrinivas Pandruvada
isst_pm_get_clos(struct isst_id * id,int clos,struct isst_clos_config * clos_config)475850337ecSZhang Rui int isst_pm_get_clos(struct isst_id *id, int clos, struct isst_clos_config *clos_config)
4763fb4f7cdSSrinivas Pandruvada {
47743314e79SZhang Rui CHECK_CB(pm_get_clos);
47843314e79SZhang Rui return isst_ops->pm_get_clos(id, clos, clos_config);
4793fb4f7cdSSrinivas Pandruvada }
4803fb4f7cdSSrinivas Pandruvada
isst_set_clos(struct isst_id * id,int clos,struct isst_clos_config * clos_config)481850337ecSZhang Rui int isst_set_clos(struct isst_id *id, int clos, struct isst_clos_config *clos_config)
4823fb4f7cdSSrinivas Pandruvada {
48333dbf360SZhang Rui CHECK_CB(set_clos);
48433dbf360SZhang Rui return isst_ops->set_clos(id, clos, clos_config);
4853fb4f7cdSSrinivas Pandruvada }
4863fb4f7cdSSrinivas Pandruvada
isst_clos_get_assoc_status(struct isst_id * id,int * clos_id)487850337ecSZhang Rui int isst_clos_get_assoc_status(struct isst_id *id, int *clos_id)
4883fb4f7cdSSrinivas Pandruvada {
489b161bbadSZhang Rui CHECK_CB(clos_get_assoc_status);
490b161bbadSZhang Rui return isst_ops->clos_get_assoc_status(id, clos_id);
4913fb4f7cdSSrinivas Pandruvada }
4923fb4f7cdSSrinivas Pandruvada
isst_clos_associate(struct isst_id * id,int clos_id)493850337ecSZhang Rui int isst_clos_associate(struct isst_id *id, int clos_id)
4943fb4f7cdSSrinivas Pandruvada {
495a59a6c0cSZhang Rui CHECK_CB(clos_associate);
496a59a6c0cSZhang Rui return isst_ops->clos_associate(id, clos_id);
4973fb4f7cdSSrinivas Pandruvada
4983fb4f7cdSSrinivas Pandruvada }
499