1*4c71ae41SShyam Sundar S K // SPDX-License-Identifier: GPL-2.0 2*4c71ae41SShyam Sundar S K /* 3*4c71ae41SShyam Sundar S K * AMD Platform Management Framework (PMF) Driver 4*4c71ae41SShyam Sundar S K * 5*4c71ae41SShyam Sundar S K * Copyright (c) 2022, Advanced Micro Devices, Inc. 6*4c71ae41SShyam Sundar S K * All Rights Reserved. 7*4c71ae41SShyam Sundar S K * 8*4c71ae41SShyam Sundar S K * Author: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> 9*4c71ae41SShyam Sundar S K */ 10*4c71ae41SShyam Sundar S K 11*4c71ae41SShyam Sundar S K #include "pmf.h" 12*4c71ae41SShyam Sundar S K 13*4c71ae41SShyam Sundar S K static struct amd_pmf_static_slider_granular config_store; 14*4c71ae41SShyam Sundar S K 15*4c71ae41SShyam Sundar S K static void amd_pmf_load_defaults_sps(struct amd_pmf_dev *dev) 16*4c71ae41SShyam Sundar S K { 17*4c71ae41SShyam Sundar S K struct apmf_static_slider_granular_output output; 18*4c71ae41SShyam Sundar S K int i, j, idx = 0; 19*4c71ae41SShyam Sundar S K 20*4c71ae41SShyam Sundar S K memset(&config_store, 0, sizeof(config_store)); 21*4c71ae41SShyam Sundar S K apmf_get_static_slider_granular(dev, &output); 22*4c71ae41SShyam Sundar S K 23*4c71ae41SShyam Sundar S K for (i = 0; i < POWER_SOURCE_MAX; i++) { 24*4c71ae41SShyam Sundar S K for (j = 0; j < POWER_MODE_MAX; j++) { 25*4c71ae41SShyam Sundar S K config_store.prop[i][j].spl = output.prop[idx].spl; 26*4c71ae41SShyam Sundar S K config_store.prop[i][j].sppt = output.prop[idx].sppt; 27*4c71ae41SShyam Sundar S K config_store.prop[i][j].sppt_apu_only = 28*4c71ae41SShyam Sundar S K output.prop[idx].sppt_apu_only; 29*4c71ae41SShyam Sundar S K config_store.prop[i][j].fppt = output.prop[idx].fppt; 30*4c71ae41SShyam Sundar S K config_store.prop[i][j].stt_min = output.prop[idx].stt_min; 31*4c71ae41SShyam Sundar S K config_store.prop[i][j].stt_skin_temp[STT_TEMP_APU] = 32*4c71ae41SShyam Sundar S K output.prop[idx].stt_skin_temp[STT_TEMP_APU]; 33*4c71ae41SShyam Sundar S K config_store.prop[i][j].stt_skin_temp[STT_TEMP_HS2] = 34*4c71ae41SShyam Sundar S K output.prop[idx].stt_skin_temp[STT_TEMP_HS2]; 35*4c71ae41SShyam Sundar S K config_store.prop[i][j].fan_id = output.prop[idx].fan_id; 36*4c71ae41SShyam Sundar S K idx++; 37*4c71ae41SShyam Sundar S K } 38*4c71ae41SShyam Sundar S K } 39*4c71ae41SShyam Sundar S K } 40*4c71ae41SShyam Sundar S K 41*4c71ae41SShyam Sundar S K void amd_pmf_update_slider(struct amd_pmf_dev *dev, bool op, int idx, 42*4c71ae41SShyam Sundar S K struct amd_pmf_static_slider_granular *table) 43*4c71ae41SShyam Sundar S K { 44*4c71ae41SShyam Sundar S K int src = amd_pmf_get_power_source(); 45*4c71ae41SShyam Sundar S K 46*4c71ae41SShyam Sundar S K if (op == SLIDER_OP_SET) { 47*4c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, SET_SPL, false, config_store.prop[src][idx].spl, NULL); 48*4c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, SET_FPPT, false, config_store.prop[src][idx].fppt, NULL); 49*4c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, SET_SPPT, false, config_store.prop[src][idx].sppt, NULL); 50*4c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, SET_SPPT_APU_ONLY, false, 51*4c71ae41SShyam Sundar S K config_store.prop[src][idx].sppt_apu_only, NULL); 52*4c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, SET_STT_MIN_LIMIT, false, 53*4c71ae41SShyam Sundar S K config_store.prop[src][idx].stt_min, NULL); 54*4c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, SET_STT_LIMIT_APU, false, 55*4c71ae41SShyam Sundar S K config_store.prop[src][idx].stt_skin_temp[STT_TEMP_APU], NULL); 56*4c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, SET_STT_LIMIT_HS2, false, 57*4c71ae41SShyam Sundar S K config_store.prop[src][idx].stt_skin_temp[STT_TEMP_HS2], NULL); 58*4c71ae41SShyam Sundar S K } else if (op == SLIDER_OP_GET) { 59*4c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, GET_SPL, true, ARG_NONE, &table->prop[src][idx].spl); 60*4c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, GET_FPPT, true, ARG_NONE, &table->prop[src][idx].fppt); 61*4c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, GET_SPPT, true, ARG_NONE, &table->prop[src][idx].sppt); 62*4c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, GET_SPPT_APU_ONLY, true, ARG_NONE, 63*4c71ae41SShyam Sundar S K &table->prop[src][idx].sppt_apu_only); 64*4c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, GET_STT_MIN_LIMIT, true, ARG_NONE, 65*4c71ae41SShyam Sundar S K &table->prop[src][idx].stt_min); 66*4c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, GET_STT_LIMIT_APU, true, ARG_NONE, 67*4c71ae41SShyam Sundar S K (u32 *)&table->prop[src][idx].stt_skin_temp[STT_TEMP_APU]); 68*4c71ae41SShyam Sundar S K amd_pmf_send_cmd(dev, GET_STT_LIMIT_HS2, true, ARG_NONE, 69*4c71ae41SShyam Sundar S K (u32 *)&table->prop[src][idx].stt_skin_temp[STT_TEMP_HS2]); 70*4c71ae41SShyam Sundar S K } 71*4c71ae41SShyam Sundar S K } 72*4c71ae41SShyam Sundar S K 73*4c71ae41SShyam Sundar S K static int amd_pmf_profile_get(struct platform_profile_handler *pprof, 74*4c71ae41SShyam Sundar S K enum platform_profile_option *profile) 75*4c71ae41SShyam Sundar S K { 76*4c71ae41SShyam Sundar S K struct amd_pmf_dev *pmf = container_of(pprof, struct amd_pmf_dev, pprof); 77*4c71ae41SShyam Sundar S K 78*4c71ae41SShyam Sundar S K *profile = pmf->current_profile; 79*4c71ae41SShyam Sundar S K return 0; 80*4c71ae41SShyam Sundar S K } 81*4c71ae41SShyam Sundar S K 82*4c71ae41SShyam Sundar S K u8 amd_pmf_get_pprof_modes(struct amd_pmf_dev *pmf) 83*4c71ae41SShyam Sundar S K { 84*4c71ae41SShyam Sundar S K u8 mode; 85*4c71ae41SShyam Sundar S K 86*4c71ae41SShyam Sundar S K switch (pmf->current_profile) { 87*4c71ae41SShyam Sundar S K case PLATFORM_PROFILE_PERFORMANCE: 88*4c71ae41SShyam Sundar S K mode = POWER_MODE_PERFORMANCE; 89*4c71ae41SShyam Sundar S K break; 90*4c71ae41SShyam Sundar S K case PLATFORM_PROFILE_BALANCED: 91*4c71ae41SShyam Sundar S K mode = POWER_MODE_BALANCED_POWER; 92*4c71ae41SShyam Sundar S K break; 93*4c71ae41SShyam Sundar S K case PLATFORM_PROFILE_LOW_POWER: 94*4c71ae41SShyam Sundar S K mode = POWER_MODE_POWER_SAVER; 95*4c71ae41SShyam Sundar S K break; 96*4c71ae41SShyam Sundar S K default: 97*4c71ae41SShyam Sundar S K dev_err(pmf->dev, "Unknown Platform Profile.\n"); 98*4c71ae41SShyam Sundar S K break; 99*4c71ae41SShyam Sundar S K } 100*4c71ae41SShyam Sundar S K 101*4c71ae41SShyam Sundar S K return mode; 102*4c71ae41SShyam Sundar S K } 103*4c71ae41SShyam Sundar S K 104*4c71ae41SShyam Sundar S K static int amd_pmf_profile_set(struct platform_profile_handler *pprof, 105*4c71ae41SShyam Sundar S K enum platform_profile_option profile) 106*4c71ae41SShyam Sundar S K { 107*4c71ae41SShyam Sundar S K struct amd_pmf_dev *pmf = container_of(pprof, struct amd_pmf_dev, pprof); 108*4c71ae41SShyam Sundar S K u8 mode; 109*4c71ae41SShyam Sundar S K 110*4c71ae41SShyam Sundar S K pmf->current_profile = profile; 111*4c71ae41SShyam Sundar S K mode = amd_pmf_get_pprof_modes(pmf); 112*4c71ae41SShyam Sundar S K amd_pmf_update_slider(pmf, SLIDER_OP_SET, mode, NULL); 113*4c71ae41SShyam Sundar S K return 0; 114*4c71ae41SShyam Sundar S K } 115*4c71ae41SShyam Sundar S K 116*4c71ae41SShyam Sundar S K int amd_pmf_init_sps(struct amd_pmf_dev *dev) 117*4c71ae41SShyam Sundar S K { 118*4c71ae41SShyam Sundar S K int err; 119*4c71ae41SShyam Sundar S K 120*4c71ae41SShyam Sundar S K dev->current_profile = PLATFORM_PROFILE_BALANCED; 121*4c71ae41SShyam Sundar S K amd_pmf_load_defaults_sps(dev); 122*4c71ae41SShyam Sundar S K 123*4c71ae41SShyam Sundar S K dev->pprof.profile_get = amd_pmf_profile_get; 124*4c71ae41SShyam Sundar S K dev->pprof.profile_set = amd_pmf_profile_set; 125*4c71ae41SShyam Sundar S K 126*4c71ae41SShyam Sundar S K /* Setup supported modes */ 127*4c71ae41SShyam Sundar S K set_bit(PLATFORM_PROFILE_LOW_POWER, dev->pprof.choices); 128*4c71ae41SShyam Sundar S K set_bit(PLATFORM_PROFILE_BALANCED, dev->pprof.choices); 129*4c71ae41SShyam Sundar S K set_bit(PLATFORM_PROFILE_PERFORMANCE, dev->pprof.choices); 130*4c71ae41SShyam Sundar S K 131*4c71ae41SShyam Sundar S K /* Create platform_profile structure and register */ 132*4c71ae41SShyam Sundar S K err = platform_profile_register(&dev->pprof); 133*4c71ae41SShyam Sundar S K if (err) 134*4c71ae41SShyam Sundar S K dev_err(dev->dev, "Failed to register SPS support, this is most likely an SBIOS bug: %d\n", 135*4c71ae41SShyam Sundar S K err); 136*4c71ae41SShyam Sundar S K 137*4c71ae41SShyam Sundar S K return err; 138*4c71ae41SShyam Sundar S K } 139*4c71ae41SShyam Sundar S K 140*4c71ae41SShyam Sundar S K void amd_pmf_deinit_sps(struct amd_pmf_dev *dev) 141*4c71ae41SShyam Sundar S K { 142*4c71ae41SShyam Sundar S K platform_profile_remove(); 143*4c71ae41SShyam Sundar S K } 144