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 return 0; 126 } 127 128 static int mbox_get_pwr_info(struct isst_id *id, int config_index, 129 struct isst_pkg_ctdp_level_info *ctdp_level) 130 { 131 unsigned int resp; 132 int ret; 133 134 ret = isst_send_mbox_command(id->cpu, CONFIG_TDP, CONFIG_TDP_GET_PWR_INFO, 135 0, config_index, &resp); 136 if (ret) 137 return ret; 138 139 ctdp_level->pkg_max_power = resp & GENMASK(14, 0); 140 ctdp_level->pkg_min_power = (resp & GENMASK(30, 16)) >> 16; 141 142 debug_printf( 143 "cpu:%d ctdp:%d CONFIG_TDP_GET_PWR_INFO resp:%x pkg_max_power:%d pkg_min_power:%d\n", 144 id->cpu, config_index, resp, ctdp_level->pkg_max_power, 145 ctdp_level->pkg_min_power); 146 147 return 0; 148 } 149 150 151 static struct isst_platform_ops mbox_ops = { 152 .get_disp_freq_multiplier = mbox_get_disp_freq_multiplier, 153 .get_trl_max_levels = mbox_get_trl_max_levels, 154 .get_trl_level_name = mbox_get_trl_level_name, 155 .is_punit_valid = mbox_is_punit_valid, 156 .get_config_levels = mbox_get_config_levels, 157 .get_ctdp_control = mbox_get_ctdp_control, 158 .get_tdp_info = mbox_get_tdp_info, 159 .get_pwr_info = mbox_get_pwr_info, 160 }; 161 162 struct isst_platform_ops *mbox_get_platform_ops(void) 163 { 164 return &mbox_ops; 165 } 166