14c71ae41SShyam Sundar S K // SPDX-License-Identifier: GPL-2.0 24c71ae41SShyam Sundar S K /* 34c71ae41SShyam Sundar S K * AMD Platform Management Framework (PMF) Driver 44c71ae41SShyam Sundar S K * 54c71ae41SShyam Sundar S K * Copyright (c) 2022, Advanced Micro Devices, Inc. 64c71ae41SShyam Sundar S K * All Rights Reserved. 74c71ae41SShyam Sundar S K * 84c71ae41SShyam Sundar S K * Author: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> 94c71ae41SShyam Sundar S K */ 104c71ae41SShyam Sundar S K 114c71ae41SShyam Sundar S K #include "pmf.h" 124c71ae41SShyam Sundar S K 1348d38f56SShyam Sundar S K static struct amd_pmf_static_slider_granular_v2 config_store_v2; 144c71ae41SShyam Sundar S K static struct amd_pmf_static_slider_granular config_store; 15*3eecb434SShyam Sundar S K static struct amd_pmf_apts_granular apts_config_store; 164c71ae41SShyam Sundar S K 17a82ebb3dSShyam Sundar S K #ifdef CONFIG_AMD_PMF_DEBUG 1848d38f56SShyam Sundar S K static const char *slider_v2_as_str(unsigned int state) 1948d38f56SShyam Sundar S K { 2048d38f56SShyam Sundar S K switch (state) { 2148d38f56SShyam Sundar S K case POWER_MODE_BEST_PERFORMANCE: 2248d38f56SShyam Sundar S K return "Best Performance"; 2348d38f56SShyam Sundar S K case POWER_MODE_BALANCED: 2448d38f56SShyam Sundar S K return "Balanced"; 2548d38f56SShyam Sundar S K case POWER_MODE_BEST_POWER_EFFICIENCY: 2648d38f56SShyam Sundar S K return "Best Power Efficiency"; 2748d38f56SShyam Sundar S K case POWER_MODE_ENERGY_SAVE: 2848d38f56SShyam Sundar S K return "Energy Save"; 2948d38f56SShyam Sundar S K default: 3048d38f56SShyam Sundar S K return "Unknown Power Mode"; 3148d38f56SShyam Sundar S K } 3248d38f56SShyam Sundar S K } 3348d38f56SShyam Sundar S K 34506ed33dSShyam Sundar S K static const char *slider_as_str(unsigned int state) 35a82ebb3dSShyam Sundar S K { 36a82ebb3dSShyam Sundar S K switch (state) { 37a82ebb3dSShyam Sundar S K case POWER_MODE_PERFORMANCE: 38a82ebb3dSShyam Sundar S K return "PERFORMANCE"; 39a82ebb3dSShyam Sundar S K case POWER_MODE_BALANCED_POWER: 40a82ebb3dSShyam Sundar S K return "BALANCED_POWER"; 41a82ebb3dSShyam Sundar S K case POWER_MODE_POWER_SAVER: 42a82ebb3dSShyam Sundar S K return "POWER_SAVER"; 43a82ebb3dSShyam Sundar S K default: 44a82ebb3dSShyam Sundar S K return "Unknown Slider State"; 45a82ebb3dSShyam Sundar S K } 46a82ebb3dSShyam Sundar S K } 47a82ebb3dSShyam Sundar S K 484984dbb6SShyam Sundar S K const char *amd_pmf_source_as_str(unsigned int state) 49a82ebb3dSShyam Sundar S K { 50a82ebb3dSShyam Sundar S K switch (state) { 51a82ebb3dSShyam Sundar S K case POWER_SOURCE_AC: 52a82ebb3dSShyam Sundar S K return "AC"; 53a82ebb3dSShyam Sundar S K case POWER_SOURCE_DC: 54a82ebb3dSShyam Sundar S K return "DC"; 55a82ebb3dSShyam Sundar S K default: 56a82ebb3dSShyam Sundar S K return "Unknown Power State"; 57a82ebb3dSShyam Sundar S K } 58a82ebb3dSShyam Sundar S K } 59a82ebb3dSShyam Sundar S K 60a82ebb3dSShyam Sundar S K static void amd_pmf_dump_sps_defaults(struct amd_pmf_static_slider_granular *data) 61a82ebb3dSShyam Sundar S K { 62a82ebb3dSShyam Sundar S K int i, j; 63a82ebb3dSShyam Sundar S K 64a82ebb3dSShyam Sundar S K pr_debug("Static Slider Data - BEGIN\n"); 65a82ebb3dSShyam Sundar S K 66a82ebb3dSShyam Sundar S K for (i = 0; i < POWER_SOURCE_MAX; i++) { 67a82ebb3dSShyam Sundar S K for (j = 0; j < POWER_MODE_MAX; j++) { 684984dbb6SShyam Sundar S K pr_debug("--- Source:%s Mode:%s ---\n", amd_pmf_source_as_str(i), 694984dbb6SShyam Sundar S K slider_as_str(j)); 70a82ebb3dSShyam Sundar S K pr_debug("SPL: %u mW\n", data->prop[i][j].spl); 71a82ebb3dSShyam Sundar S K pr_debug("SPPT: %u mW\n", data->prop[i][j].sppt); 72a82ebb3dSShyam Sundar S K pr_debug("SPPT_ApuOnly: %u mW\n", data->prop[i][j].sppt_apu_only); 73a82ebb3dSShyam Sundar S K pr_debug("FPPT: %u mW\n", data->prop[i][j].fppt); 74a82ebb3dSShyam Sundar S K pr_debug("STTMinLimit: %u mW\n", data->prop[i][j].stt_min); 75a82ebb3dSShyam Sundar S K pr_debug("STT_SkinTempLimit_APU: %u C\n", 76a82ebb3dSShyam Sundar S K data->prop[i][j].stt_skin_temp[STT_TEMP_APU]); 77a82ebb3dSShyam Sundar S K pr_debug("STT_SkinTempLimit_HS2: %u C\n", 78a82ebb3dSShyam Sundar S K data->prop[i][j].stt_skin_temp[STT_TEMP_HS2]); 79a82ebb3dSShyam Sundar S K } 80a82ebb3dSShyam Sundar S K } 81a82ebb3dSShyam Sundar S K 82a82ebb3dSShyam Sundar S K pr_debug("Static Slider Data - END\n"); 83a82ebb3dSShyam Sundar S K } 8448d38f56SShyam Sundar S K 8548d38f56SShyam Sundar S K static void amd_pmf_dump_sps_defaults_v2(struct amd_pmf_static_slider_granular_v2 *data) 8648d38f56SShyam Sundar S K { 8748d38f56SShyam Sundar S K unsigned int i, j; 8848d38f56SShyam Sundar S K 8948d38f56SShyam Sundar S K pr_debug("Static Slider APTS state index data - BEGIN"); 9048d38f56SShyam Sundar S K pr_debug("size: %u\n", data->size); 9148d38f56SShyam Sundar S K 9248d38f56SShyam Sundar S K for (i = 0; i < POWER_SOURCE_MAX; i++) 9348d38f56SShyam Sundar S K for (j = 0; j < POWER_MODE_V2_MAX; j++) 9448d38f56SShyam Sundar S K pr_debug("%s %s: %u\n", amd_pmf_source_as_str(i), slider_v2_as_str(j), 9548d38f56SShyam Sundar S K data->sps_idx.power_states[i][j]); 9648d38f56SShyam Sundar S K 9748d38f56SShyam Sundar S K pr_debug("Static Slider APTS state index data - END\n"); 9848d38f56SShyam Sundar S K } 99*3eecb434SShyam Sundar S K 100*3eecb434SShyam Sundar S K static void amd_pmf_dump_apts_sps_defaults(struct amd_pmf_apts_granular *info) 101*3eecb434SShyam Sundar S K { 102*3eecb434SShyam Sundar S K int i; 103*3eecb434SShyam Sundar S K 104*3eecb434SShyam Sundar S K pr_debug("Static Slider APTS index default values data - BEGIN"); 105*3eecb434SShyam Sundar S K 106*3eecb434SShyam Sundar S K for (i = 0; i < APTS_MAX_STATES; i++) { 107*3eecb434SShyam Sundar S K pr_debug("Table Version[%d] = %u\n", i, info->val[i].table_version); 108*3eecb434SShyam Sundar S K pr_debug("Fan Index[%d] = %u\n", i, info->val[i].fan_table_idx); 109*3eecb434SShyam Sundar S K pr_debug("PPT[%d] = %u\n", i, info->val[i].pmf_ppt); 110*3eecb434SShyam Sundar S K pr_debug("PPT APU[%d] = %u\n", i, info->val[i].ppt_pmf_apu_only); 111*3eecb434SShyam Sundar S K pr_debug("STT Min[%d] = %u\n", i, info->val[i].stt_min_limit); 112*3eecb434SShyam Sundar S K pr_debug("STT APU[%d] = %u\n", i, info->val[i].stt_skin_temp_limit_apu); 113*3eecb434SShyam Sundar S K pr_debug("STT HS2[%d] = %u\n", i, info->val[i].stt_skin_temp_limit_hs2); 114*3eecb434SShyam Sundar S K } 115*3eecb434SShyam Sundar S K 116*3eecb434SShyam Sundar S K pr_debug("Static Slider APTS index default values data - END"); 117*3eecb434SShyam Sundar S K } 118a82ebb3dSShyam Sundar S K #else 119a82ebb3dSShyam Sundar S K static void amd_pmf_dump_sps_defaults(struct amd_pmf_static_slider_granular *data) {} 12048d38f56SShyam Sundar S K static void amd_pmf_dump_sps_defaults_v2(struct amd_pmf_static_slider_granular_v2 *data) {} 121*3eecb434SShyam Sundar S K static void amd_pmf_dump_apts_sps_defaults(struct amd_pmf_apts_granular *info) {} 122a82ebb3dSShyam Sundar S K #endif 123a82ebb3dSShyam Sundar S K 124*3eecb434SShyam Sundar S K static void amd_pmf_load_apts_defaults_sps_v2(struct amd_pmf_dev *pdev) 125*3eecb434SShyam Sundar S K { 126*3eecb434SShyam Sundar S K struct amd_pmf_apts_granular_output output; 127*3eecb434SShyam Sundar S K struct amd_pmf_apts_output *ps; 128*3eecb434SShyam Sundar S K int i; 129*3eecb434SShyam Sundar S K 130*3eecb434SShyam Sundar S K memset(&apts_config_store, 0, sizeof(apts_config_store)); 131*3eecb434SShyam Sundar S K 132*3eecb434SShyam Sundar S K ps = apts_config_store.val; 133*3eecb434SShyam Sundar S K 134*3eecb434SShyam Sundar S K for (i = 0; i < APTS_MAX_STATES; i++) { 135*3eecb434SShyam Sundar S K apts_get_static_slider_granular_v2(pdev, &output, i); 136*3eecb434SShyam Sundar S K ps[i].table_version = output.val.table_version; 137*3eecb434SShyam Sundar S K ps[i].fan_table_idx = output.val.fan_table_idx; 138*3eecb434SShyam Sundar S K ps[i].pmf_ppt = output.val.pmf_ppt; 139*3eecb434SShyam Sundar S K ps[i].ppt_pmf_apu_only = output.val.ppt_pmf_apu_only; 140*3eecb434SShyam Sundar S K ps[i].stt_min_limit = output.val.stt_min_limit; 141*3eecb434SShyam Sundar S K ps[i].stt_skin_temp_limit_apu = output.val.stt_skin_temp_limit_apu; 142*3eecb434SShyam Sundar S K ps[i].stt_skin_temp_limit_hs2 = output.val.stt_skin_temp_limit_hs2; 143*3eecb434SShyam Sundar S K } 144*3eecb434SShyam Sundar S K 145*3eecb434SShyam Sundar S K amd_pmf_dump_apts_sps_defaults(&apts_config_store); 146*3eecb434SShyam Sundar S K } 147*3eecb434SShyam Sundar S K 14848d38f56SShyam Sundar S K static void amd_pmf_load_defaults_sps_v2(struct amd_pmf_dev *dev) 14948d38f56SShyam Sundar S K { 15048d38f56SShyam Sundar S K struct apmf_static_slider_granular_output_v2 output; 15148d38f56SShyam Sundar S K unsigned int i, j; 15248d38f56SShyam Sundar S K 15348d38f56SShyam Sundar S K memset(&config_store_v2, 0, sizeof(config_store_v2)); 15448d38f56SShyam Sundar S K apmf_get_static_slider_granular_v2(dev, &output); 15548d38f56SShyam Sundar S K 15648d38f56SShyam Sundar S K config_store_v2.size = output.size; 15748d38f56SShyam Sundar S K 15848d38f56SShyam Sundar S K for (i = 0; i < POWER_SOURCE_MAX; i++) 15948d38f56SShyam Sundar S K for (j = 0; j < POWER_MODE_V2_MAX; j++) 16048d38f56SShyam Sundar S K config_store_v2.sps_idx.power_states[i][j] = 16148d38f56SShyam Sundar S K output.sps_idx.power_states[i][j]; 16248d38f56SShyam Sundar S K 16348d38f56SShyam Sundar S K amd_pmf_dump_sps_defaults_v2(&config_store_v2); 16448d38f56SShyam Sundar S K } 16548d38f56SShyam Sundar S K 1664c71ae41SShyam Sundar S K static void amd_pmf_load_defaults_sps(struct amd_pmf_dev *dev) 1674c71ae41SShyam Sundar S K { 1684c71ae41SShyam Sundar S K struct apmf_static_slider_granular_output output; 1694c71ae41SShyam Sundar S K int i, j, idx = 0; 1704c71ae41SShyam Sundar S K 1714c71ae41SShyam Sundar S K memset(&config_store, 0, sizeof(config_store)); 1724c71ae41SShyam Sundar S K apmf_get_static_slider_granular(dev, &output); 1734c71ae41SShyam Sundar S K 1744c71ae41SShyam Sundar S K for (i = 0; i < POWER_SOURCE_MAX; i++) { 1754c71ae41SShyam Sundar S K for (j = 0; j < POWER_MODE_MAX; j++) { 1764c71ae41SShyam Sundar S K config_store.prop[i][j].spl = output.prop[idx].spl; 1774c71ae41SShyam Sundar S K config_store.prop[i][j].sppt = output.prop[idx].sppt; 1784c71ae41SShyam Sundar S K config_store.prop[i][j].sppt_apu_only = 1794c71ae41SShyam Sundar S K output.prop[idx].sppt_apu_only; 1804c71ae41SShyam Sundar S K config_store.prop[i][j].fppt = output.prop[idx].fppt; 1814c71ae41SShyam Sundar S K config_store.prop[i][j].stt_min = output.prop[idx].stt_min; 1824c71ae41SShyam Sundar S K config_store.prop[i][j].stt_skin_temp[STT_TEMP_APU] = 1834c71ae41SShyam Sundar S K output.prop[idx].stt_skin_temp[STT_TEMP_APU]; 1844c71ae41SShyam Sundar S K config_store.prop[i][j].stt_skin_temp[STT_TEMP_HS2] = 1854c71ae41SShyam Sundar S K output.prop[idx].stt_skin_temp[STT_TEMP_HS2]; 1864c71ae41SShyam Sundar S K config_store.prop[i][j].fan_id = output.prop[idx].fan_id; 1874c71ae41SShyam Sundar S K idx++; 1884c71ae41SShyam Sundar S K } 1894c71ae41SShyam Sundar S K } 190a82ebb3dSShyam Sundar S K amd_pmf_dump_sps_defaults(&config_store); 1914c71ae41SShyam Sundar S K } 1924c71ae41SShyam Sundar S K 1934c71ae41SShyam Sundar S K void amd_pmf_update_slider(struct amd_pmf_dev *dev, bool op, int idx, 1944c71ae41SShyam Sundar S K struct amd_pmf_static_slider_granular *table) 1954c71ae41SShyam Sundar S K { 1964c71ae41SShyam Sundar S K int src = amd_pmf_get_power_source(); 1974c71ae41SShyam Sundar S K 1984c71ae41SShyam Sundar S K if (op == SLIDER_OP_SET) { 1994c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, SET_SPL, false, config_store.prop[src][idx].spl, NULL); 2004c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, SET_FPPT, false, config_store.prop[src][idx].fppt, NULL); 2014c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, SET_SPPT, false, config_store.prop[src][idx].sppt, NULL); 2024c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, SET_SPPT_APU_ONLY, false, 2034c71ae41SShyam Sundar S K config_store.prop[src][idx].sppt_apu_only, NULL); 2044c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, SET_STT_MIN_LIMIT, false, 2054c71ae41SShyam Sundar S K config_store.prop[src][idx].stt_min, NULL); 2064c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, SET_STT_LIMIT_APU, false, 2074c71ae41SShyam Sundar S K config_store.prop[src][idx].stt_skin_temp[STT_TEMP_APU], NULL); 2084c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, SET_STT_LIMIT_HS2, false, 2094c71ae41SShyam Sundar S K config_store.prop[src][idx].stt_skin_temp[STT_TEMP_HS2], NULL); 2104c71ae41SShyam Sundar S K } else if (op == SLIDER_OP_GET) { 2114c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, GET_SPL, true, ARG_NONE, &table->prop[src][idx].spl); 2124c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, GET_FPPT, true, ARG_NONE, &table->prop[src][idx].fppt); 2134c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, GET_SPPT, true, ARG_NONE, &table->prop[src][idx].sppt); 2144c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, GET_SPPT_APU_ONLY, true, ARG_NONE, 2154c71ae41SShyam Sundar S K &table->prop[src][idx].sppt_apu_only); 2164c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, GET_STT_MIN_LIMIT, true, ARG_NONE, 2174c71ae41SShyam Sundar S K &table->prop[src][idx].stt_min); 2184c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, GET_STT_LIMIT_APU, true, ARG_NONE, 2194c71ae41SShyam Sundar S K (u32 *)&table->prop[src][idx].stt_skin_temp[STT_TEMP_APU]); 2204c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, GET_STT_LIMIT_HS2, true, ARG_NONE, 2214c71ae41SShyam Sundar S K (u32 *)&table->prop[src][idx].stt_skin_temp[STT_TEMP_HS2]); 2224c71ae41SShyam Sundar S K } 2234c71ae41SShyam Sundar S K } 2244c71ae41SShyam Sundar S K 225c5258d39SShyam Sundar S K int amd_pmf_set_sps_power_limits(struct amd_pmf_dev *pmf) 226c5258d39SShyam Sundar S K { 227c5258d39SShyam Sundar S K int mode; 228c5258d39SShyam Sundar S K 229c5258d39SShyam Sundar S K mode = amd_pmf_get_pprof_modes(pmf); 230c5258d39SShyam Sundar S K if (mode < 0) 231c5258d39SShyam Sundar S K return mode; 232c5258d39SShyam Sundar S K 233c5258d39SShyam Sundar S K amd_pmf_update_slider(pmf, SLIDER_OP_SET, mode, NULL); 234c5258d39SShyam Sundar S K 235c5258d39SShyam Sundar S K return 0; 236c5258d39SShyam Sundar S K } 237c5258d39SShyam Sundar S K 23816909aa8SShyam Sundar S K bool is_pprof_balanced(struct amd_pmf_dev *pmf) 23916909aa8SShyam Sundar S K { 24016909aa8SShyam Sundar S K return (pmf->current_profile == PLATFORM_PROFILE_BALANCED) ? true : false; 24116909aa8SShyam Sundar S K } 24216909aa8SShyam Sundar S K 2434c71ae41SShyam Sundar S K static int amd_pmf_profile_get(struct platform_profile_handler *pprof, 2444c71ae41SShyam Sundar S K enum platform_profile_option *profile) 2454c71ae41SShyam Sundar S K { 2464c71ae41SShyam Sundar S K struct amd_pmf_dev *pmf = container_of(pprof, struct amd_pmf_dev, pprof); 2474c71ae41SShyam Sundar S K 2484c71ae41SShyam Sundar S K *profile = pmf->current_profile; 2494c71ae41SShyam Sundar S K return 0; 2504c71ae41SShyam Sundar S K } 2514c71ae41SShyam Sundar S K 252ea522b80SShyam Sundar S K int amd_pmf_get_pprof_modes(struct amd_pmf_dev *pmf) 2534c71ae41SShyam Sundar S K { 254ea522b80SShyam Sundar S K int mode; 2554c71ae41SShyam Sundar S K 2564c71ae41SShyam Sundar S K switch (pmf->current_profile) { 2574c71ae41SShyam Sundar S K case PLATFORM_PROFILE_PERFORMANCE: 2584c71ae41SShyam Sundar S K mode = POWER_MODE_PERFORMANCE; 2594c71ae41SShyam Sundar S K break; 2604c71ae41SShyam Sundar S K case PLATFORM_PROFILE_BALANCED: 2614c71ae41SShyam Sundar S K mode = POWER_MODE_BALANCED_POWER; 2624c71ae41SShyam Sundar S K break; 2634c71ae41SShyam Sundar S K case PLATFORM_PROFILE_LOW_POWER: 2644c71ae41SShyam Sundar S K mode = POWER_MODE_POWER_SAVER; 2654c71ae41SShyam Sundar S K break; 2664c71ae41SShyam Sundar S K default: 2674c71ae41SShyam Sundar S K dev_err(pmf->dev, "Unknown Platform Profile.\n"); 268ea522b80SShyam Sundar S K return -EOPNOTSUPP; 2694c71ae41SShyam Sundar S K } 2704c71ae41SShyam Sundar S K 2714c71ae41SShyam Sundar S K return mode; 2724c71ae41SShyam Sundar S K } 2734c71ae41SShyam Sundar S K 27433c9ab5bSShyam Sundar S K int amd_pmf_power_slider_update_event(struct amd_pmf_dev *dev) 27533c9ab5bSShyam Sundar S K { 276785c0099SYang Li u8 flag = 0; 277785c0099SYang Li int mode; 27833c9ab5bSShyam Sundar S K int src; 27933c9ab5bSShyam Sundar S K 28033c9ab5bSShyam Sundar S K mode = amd_pmf_get_pprof_modes(dev); 28133c9ab5bSShyam Sundar S K if (mode < 0) 28233c9ab5bSShyam Sundar S K return mode; 28333c9ab5bSShyam Sundar S K 28433c9ab5bSShyam Sundar S K src = amd_pmf_get_power_source(); 28533c9ab5bSShyam Sundar S K 28633c9ab5bSShyam Sundar S K if (src == POWER_SOURCE_AC) { 28733c9ab5bSShyam Sundar S K switch (mode) { 28833c9ab5bSShyam Sundar S K case POWER_MODE_PERFORMANCE: 28933c9ab5bSShyam Sundar S K flag |= BIT(AC_BEST_PERF); 29033c9ab5bSShyam Sundar S K break; 29133c9ab5bSShyam Sundar S K case POWER_MODE_BALANCED_POWER: 29233c9ab5bSShyam Sundar S K flag |= BIT(AC_BETTER_PERF); 29333c9ab5bSShyam Sundar S K break; 29433c9ab5bSShyam Sundar S K case POWER_MODE_POWER_SAVER: 29533c9ab5bSShyam Sundar S K flag |= BIT(AC_BETTER_BATTERY); 29633c9ab5bSShyam Sundar S K break; 29733c9ab5bSShyam Sundar S K default: 29833c9ab5bSShyam Sundar S K dev_err(dev->dev, "unsupported platform profile\n"); 29933c9ab5bSShyam Sundar S K return -EOPNOTSUPP; 30033c9ab5bSShyam Sundar S K } 30133c9ab5bSShyam Sundar S K 30233c9ab5bSShyam Sundar S K } else if (src == POWER_SOURCE_DC) { 30333c9ab5bSShyam Sundar S K switch (mode) { 30433c9ab5bSShyam Sundar S K case POWER_MODE_PERFORMANCE: 30533c9ab5bSShyam Sundar S K flag |= BIT(DC_BEST_PERF); 30633c9ab5bSShyam Sundar S K break; 30733c9ab5bSShyam Sundar S K case POWER_MODE_BALANCED_POWER: 30833c9ab5bSShyam Sundar S K flag |= BIT(DC_BETTER_PERF); 30933c9ab5bSShyam Sundar S K break; 31033c9ab5bSShyam Sundar S K case POWER_MODE_POWER_SAVER: 31133c9ab5bSShyam Sundar S K flag |= BIT(DC_BATTERY_SAVER); 31233c9ab5bSShyam Sundar S K break; 31333c9ab5bSShyam Sundar S K default: 31433c9ab5bSShyam Sundar S K dev_err(dev->dev, "unsupported platform profile\n"); 31533c9ab5bSShyam Sundar S K return -EOPNOTSUPP; 31633c9ab5bSShyam Sundar S K } 31733c9ab5bSShyam Sundar S K } 31833c9ab5bSShyam Sundar S K 31933c9ab5bSShyam Sundar S K apmf_os_power_slider_update(dev, flag); 32033c9ab5bSShyam Sundar S K 32133c9ab5bSShyam Sundar S K return 0; 32233c9ab5bSShyam Sundar S K } 32333c9ab5bSShyam Sundar S K 3244c71ae41SShyam Sundar S K static int amd_pmf_profile_set(struct platform_profile_handler *pprof, 3254c71ae41SShyam Sundar S K enum platform_profile_option profile) 3264c71ae41SShyam Sundar S K { 3274c71ae41SShyam Sundar S K struct amd_pmf_dev *pmf = container_of(pprof, struct amd_pmf_dev, pprof); 32833c9ab5bSShyam Sundar S K int ret = 0; 3294c71ae41SShyam Sundar S K 3304c71ae41SShyam Sundar S K pmf->current_profile = profile; 331ea522b80SShyam Sundar S K 33233c9ab5bSShyam Sundar S K /* Notify EC about the slider position change */ 33333c9ab5bSShyam Sundar S K if (is_apmf_func_supported(pmf, APMF_FUNC_OS_POWER_SLIDER_UPDATE)) { 33433c9ab5bSShyam Sundar S K ret = amd_pmf_power_slider_update_event(pmf); 33533c9ab5bSShyam Sundar S K if (ret) 33633c9ab5bSShyam Sundar S K return ret; 33733c9ab5bSShyam Sundar S K } 33833c9ab5bSShyam Sundar S K 33933c9ab5bSShyam Sundar S K if (is_apmf_func_supported(pmf, APMF_FUNC_STATIC_SLIDER_GRANULAR)) { 34033c9ab5bSShyam Sundar S K ret = amd_pmf_set_sps_power_limits(pmf); 34133c9ab5bSShyam Sundar S K if (ret) 34233c9ab5bSShyam Sundar S K return ret; 34333c9ab5bSShyam Sundar S K } 34433c9ab5bSShyam Sundar S K 34533c9ab5bSShyam Sundar S K return 0; 3464c71ae41SShyam Sundar S K } 3474c71ae41SShyam Sundar S K 3484c71ae41SShyam Sundar S K int amd_pmf_init_sps(struct amd_pmf_dev *dev) 3494c71ae41SShyam Sundar S K { 3504c71ae41SShyam Sundar S K int err; 3514c71ae41SShyam Sundar S K 3524c71ae41SShyam Sundar S K dev->current_profile = PLATFORM_PROFILE_BALANCED; 35333c9ab5bSShyam Sundar S K 35433c9ab5bSShyam Sundar S K if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR)) { 355*3eecb434SShyam Sundar S K if (dev->pmf_if_version == PMF_IF_V2) { 35648d38f56SShyam Sundar S K amd_pmf_load_defaults_sps_v2(dev); 357*3eecb434SShyam Sundar S K amd_pmf_load_apts_defaults_sps_v2(dev); 358*3eecb434SShyam Sundar S K } else { 3594c71ae41SShyam Sundar S K amd_pmf_load_defaults_sps(dev); 360*3eecb434SShyam Sundar S K } 3614c71ae41SShyam Sundar S K 362635f79bcSShyam Sundar S K /* update SPS balanced power mode thermals */ 363635f79bcSShyam Sundar S K amd_pmf_set_sps_power_limits(dev); 36433c9ab5bSShyam Sundar S K } 365635f79bcSShyam Sundar S K 3664c71ae41SShyam Sundar S K dev->pprof.profile_get = amd_pmf_profile_get; 3674c71ae41SShyam Sundar S K dev->pprof.profile_set = amd_pmf_profile_set; 3684c71ae41SShyam Sundar S K 3694c71ae41SShyam Sundar S K /* Setup supported modes */ 3704c71ae41SShyam Sundar S K set_bit(PLATFORM_PROFILE_LOW_POWER, dev->pprof.choices); 3714c71ae41SShyam Sundar S K set_bit(PLATFORM_PROFILE_BALANCED, dev->pprof.choices); 3724c71ae41SShyam Sundar S K set_bit(PLATFORM_PROFILE_PERFORMANCE, dev->pprof.choices); 3734c71ae41SShyam Sundar S K 3744c71ae41SShyam Sundar S K /* Create platform_profile structure and register */ 3754c71ae41SShyam Sundar S K err = platform_profile_register(&dev->pprof); 3764c71ae41SShyam Sundar S K if (err) 3774c71ae41SShyam Sundar S K dev_err(dev->dev, "Failed to register SPS support, this is most likely an SBIOS bug: %d\n", 3784c71ae41SShyam Sundar S K err); 3794c71ae41SShyam Sundar S K 3804c71ae41SShyam Sundar S K return err; 3814c71ae41SShyam Sundar S K } 3824c71ae41SShyam Sundar S K 3834c71ae41SShyam Sundar S K void amd_pmf_deinit_sps(struct amd_pmf_dev *dev) 3844c71ae41SShyam Sundar S K { 3854c71ae41SShyam Sundar S K platform_profile_remove(); 3864c71ae41SShyam Sundar S K } 387