xref: /linux/drivers/platform/x86/amd/pmf/cnqf.c (revision 1738061c9ec854db2db76be8bb968f550d9bdddc)
1*1738061cSShyam Sundar S K // SPDX-License-Identifier: GPL-2.0
2*1738061cSShyam Sundar S K /*
3*1738061cSShyam Sundar S K  * AMD Platform Management Framework Driver
4*1738061cSShyam Sundar S K  *
5*1738061cSShyam Sundar S K  * Copyright (c) 2022, Advanced Micro Devices, Inc.
6*1738061cSShyam Sundar S K  * All Rights Reserved.
7*1738061cSShyam Sundar S K  *
8*1738061cSShyam Sundar S K  * Author: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
9*1738061cSShyam Sundar S K  */
10*1738061cSShyam Sundar S K 
11*1738061cSShyam Sundar S K #include <linux/workqueue.h>
12*1738061cSShyam Sundar S K #include "pmf.h"
13*1738061cSShyam Sundar S K 
14*1738061cSShyam Sundar S K static struct cnqf_config config_store;
15*1738061cSShyam Sundar S K 
16*1738061cSShyam Sundar S K static int amd_pmf_set_cnqf(struct amd_pmf_dev *dev, int src, int idx,
17*1738061cSShyam Sundar S K 			    struct cnqf_config *table)
18*1738061cSShyam Sundar S K {
19*1738061cSShyam Sundar S K 	struct power_table_control *pc;
20*1738061cSShyam Sundar S K 
21*1738061cSShyam Sundar S K 	pc = &config_store.mode_set[src][idx].power_control;
22*1738061cSShyam Sundar S K 
23*1738061cSShyam Sundar S K 	amd_pmf_send_cmd(dev, SET_SPL, false, pc->spl, NULL);
24*1738061cSShyam Sundar S K 	amd_pmf_send_cmd(dev, SET_FPPT, false, pc->fppt, NULL);
25*1738061cSShyam Sundar S K 	amd_pmf_send_cmd(dev, SET_SPPT, false, pc->sppt, NULL);
26*1738061cSShyam Sundar S K 	amd_pmf_send_cmd(dev, SET_SPPT_APU_ONLY, false, pc->sppt_apu_only, NULL);
27*1738061cSShyam Sundar S K 	amd_pmf_send_cmd(dev, SET_STT_MIN_LIMIT, false, pc->stt_min, NULL);
28*1738061cSShyam Sundar S K 	amd_pmf_send_cmd(dev, SET_STT_LIMIT_APU, false, pc->stt_skin_temp[STT_TEMP_APU],
29*1738061cSShyam Sundar S K 			 NULL);
30*1738061cSShyam Sundar S K 	amd_pmf_send_cmd(dev, SET_STT_LIMIT_HS2, false, pc->stt_skin_temp[STT_TEMP_HS2],
31*1738061cSShyam Sundar S K 			 NULL);
32*1738061cSShyam Sundar S K 
33*1738061cSShyam Sundar S K 	if (is_apmf_func_supported(dev, APMF_FUNC_SET_FAN_IDX))
34*1738061cSShyam Sundar S K 		apmf_update_fan_idx(dev,
35*1738061cSShyam Sundar S K 				    config_store.mode_set[src][idx].fan_control.manual,
36*1738061cSShyam Sundar S K 				    config_store.mode_set[src][idx].fan_control.fan_id);
37*1738061cSShyam Sundar S K 
38*1738061cSShyam Sundar S K 	return 0;
39*1738061cSShyam Sundar S K }
40*1738061cSShyam Sundar S K 
41*1738061cSShyam Sundar S K static void amd_pmf_update_power_threshold(int src)
42*1738061cSShyam Sundar S K {
43*1738061cSShyam Sundar S K 	struct cnqf_mode_settings *ts;
44*1738061cSShyam Sundar S K 	struct cnqf_tran_params *tp;
45*1738061cSShyam Sundar S K 
46*1738061cSShyam Sundar S K 	tp = &config_store.trans_param[src][CNQF_TRANSITION_TO_QUIET];
47*1738061cSShyam Sundar S K 	ts = &config_store.mode_set[src][CNQF_MODE_BALANCE];
48*1738061cSShyam Sundar S K 	tp->power_threshold = ts->power_floor - tp->power_delta;
49*1738061cSShyam Sundar S K 
50*1738061cSShyam Sundar S K 	tp = &config_store.trans_param[src][CNQF_TRANSITION_TO_TURBO];
51*1738061cSShyam Sundar S K 	ts = &config_store.mode_set[src][CNQF_MODE_PERFORMANCE];
52*1738061cSShyam Sundar S K 	tp->power_threshold = ts->power_floor - tp->power_delta;
53*1738061cSShyam Sundar S K 
54*1738061cSShyam Sundar S K 	tp = &config_store.trans_param[src][CNQF_TRANSITION_FROM_BALANCE_TO_PERFORMANCE];
55*1738061cSShyam Sundar S K 	ts = &config_store.mode_set[src][CNQF_MODE_BALANCE];
56*1738061cSShyam Sundar S K 	tp->power_threshold = ts->power_floor - tp->power_delta;
57*1738061cSShyam Sundar S K 
58*1738061cSShyam Sundar S K 	tp = &config_store.trans_param[src][CNQF_TRANSITION_FROM_PERFORMANCE_TO_BALANCE];
59*1738061cSShyam Sundar S K 	ts = &config_store.mode_set[src][CNQF_MODE_PERFORMANCE];
60*1738061cSShyam Sundar S K 	tp->power_threshold = ts->power_floor - tp->power_delta;
61*1738061cSShyam Sundar S K 
62*1738061cSShyam Sundar S K 	tp = &config_store.trans_param[src][CNQF_TRANSITION_FROM_QUIET_TO_BALANCE];
63*1738061cSShyam Sundar S K 	ts = &config_store.mode_set[src][CNQF_MODE_QUIET];
64*1738061cSShyam Sundar S K 	tp->power_threshold = ts->power_floor - tp->power_delta;
65*1738061cSShyam Sundar S K 
66*1738061cSShyam Sundar S K 	tp = &config_store.trans_param[src][CNQF_TRANSITION_FROM_TURBO_TO_PERFORMANCE];
67*1738061cSShyam Sundar S K 	ts = &config_store.mode_set[src][CNQF_MODE_TURBO];
68*1738061cSShyam Sundar S K 	tp->power_threshold = ts->power_floor - tp->power_delta;
69*1738061cSShyam Sundar S K }
70*1738061cSShyam Sundar S K 
71*1738061cSShyam Sundar S K static const char *state_as_str(unsigned int state)
72*1738061cSShyam Sundar S K {
73*1738061cSShyam Sundar S K 	switch (state) {
74*1738061cSShyam Sundar S K 	case CNQF_MODE_QUIET:
75*1738061cSShyam Sundar S K 		return "QUIET";
76*1738061cSShyam Sundar S K 	case CNQF_MODE_BALANCE:
77*1738061cSShyam Sundar S K 		return "BALANCED";
78*1738061cSShyam Sundar S K 	case CNQF_MODE_TURBO:
79*1738061cSShyam Sundar S K 		return "TURBO";
80*1738061cSShyam Sundar S K 	case CNQF_MODE_PERFORMANCE:
81*1738061cSShyam Sundar S K 		return "PERFORMANCE";
82*1738061cSShyam Sundar S K 	default:
83*1738061cSShyam Sundar S K 		return "Unknown CnQF mode";
84*1738061cSShyam Sundar S K 	}
85*1738061cSShyam Sundar S K }
86*1738061cSShyam Sundar S K 
87*1738061cSShyam Sundar S K static int amd_pmf_cnqf_get_power_source(struct amd_pmf_dev *dev)
88*1738061cSShyam Sundar S K {
89*1738061cSShyam Sundar S K 	if (is_apmf_func_supported(dev, APMF_FUNC_DYN_SLIDER_AC) &&
90*1738061cSShyam Sundar S K 	    is_apmf_func_supported(dev, APMF_FUNC_DYN_SLIDER_DC))
91*1738061cSShyam Sundar S K 		return amd_pmf_get_power_source();
92*1738061cSShyam Sundar S K 	else if (is_apmf_func_supported(dev, APMF_FUNC_DYN_SLIDER_DC))
93*1738061cSShyam Sundar S K 		return POWER_SOURCE_DC;
94*1738061cSShyam Sundar S K 	else
95*1738061cSShyam Sundar S K 		return POWER_SOURCE_AC;
96*1738061cSShyam Sundar S K }
97*1738061cSShyam Sundar S K 
98*1738061cSShyam Sundar S K int amd_pmf_trans_cnqf(struct amd_pmf_dev *dev, int socket_power, ktime_t time_lapsed_ms)
99*1738061cSShyam Sundar S K {
100*1738061cSShyam Sundar S K 	struct cnqf_tran_params *tp;
101*1738061cSShyam Sundar S K 	int src, i, j;
102*1738061cSShyam Sundar S K 	u32 avg_power = 0;
103*1738061cSShyam Sundar S K 
104*1738061cSShyam Sundar S K 	src = amd_pmf_cnqf_get_power_source(dev);
105*1738061cSShyam Sundar S K 
106*1738061cSShyam Sundar S K 	if (dev->current_profile == PLATFORM_PROFILE_BALANCED) {
107*1738061cSShyam Sundar S K 		amd_pmf_set_cnqf(dev, src, config_store.current_mode, NULL);
108*1738061cSShyam Sundar S K 	} else {
109*1738061cSShyam Sundar S K 		/*
110*1738061cSShyam Sundar S K 		 * Return from here if the platform_profile is not balanced
111*1738061cSShyam Sundar S K 		 * so that preference is given to user mode selection, rather
112*1738061cSShyam Sundar S K 		 * than enforcing CnQF to run all the time (if enabled)
113*1738061cSShyam Sundar S K 		 */
114*1738061cSShyam Sundar S K 		return -EINVAL;
115*1738061cSShyam Sundar S K 	}
116*1738061cSShyam Sundar S K 
117*1738061cSShyam Sundar S K 	for (i = 0; i < CNQF_TRANSITION_MAX; i++) {
118*1738061cSShyam Sundar S K 		config_store.trans_param[src][i].timer += time_lapsed_ms;
119*1738061cSShyam Sundar S K 		config_store.trans_param[src][i].total_power += socket_power;
120*1738061cSShyam Sundar S K 		config_store.trans_param[src][i].count++;
121*1738061cSShyam Sundar S K 
122*1738061cSShyam Sundar S K 		tp = &config_store.trans_param[src][i];
123*1738061cSShyam Sundar S K 		if (tp->timer >= tp->time_constant && tp->count) {
124*1738061cSShyam Sundar S K 			avg_power = tp->total_power / tp->count;
125*1738061cSShyam Sundar S K 
126*1738061cSShyam Sundar S K 			/* Reset the indices */
127*1738061cSShyam Sundar S K 			tp->timer = 0;
128*1738061cSShyam Sundar S K 			tp->total_power = 0;
129*1738061cSShyam Sundar S K 			tp->count = 0;
130*1738061cSShyam Sundar S K 
131*1738061cSShyam Sundar S K 			if ((tp->shifting_up && avg_power >= tp->power_threshold) ||
132*1738061cSShyam Sundar S K 			    (!tp->shifting_up && avg_power <= tp->power_threshold)) {
133*1738061cSShyam Sundar S K 				tp->priority = true;
134*1738061cSShyam Sundar S K 			} else {
135*1738061cSShyam Sundar S K 				tp->priority = false;
136*1738061cSShyam Sundar S K 			}
137*1738061cSShyam Sundar S K 		}
138*1738061cSShyam Sundar S K 	}
139*1738061cSShyam Sundar S K 
140*1738061cSShyam Sundar S K 	dev_dbg(dev->dev, "[CNQF] Avg power: %u mW socket power: %u mW mode:%s\n",
141*1738061cSShyam Sundar S K 		avg_power, socket_power, state_as_str(config_store.current_mode));
142*1738061cSShyam Sundar S K 
143*1738061cSShyam Sundar S K 	for (j = 0; j < CNQF_TRANSITION_MAX; j++) {
144*1738061cSShyam Sundar S K 		/* apply the highest priority */
145*1738061cSShyam Sundar S K 		if (config_store.trans_param[src][j].priority) {
146*1738061cSShyam Sundar S K 			if (config_store.current_mode !=
147*1738061cSShyam Sundar S K 			    config_store.trans_param[src][j].target_mode) {
148*1738061cSShyam Sundar S K 				config_store.current_mode =
149*1738061cSShyam Sundar S K 						config_store.trans_param[src][j].target_mode;
150*1738061cSShyam Sundar S K 				dev_dbg(dev->dev, "Moving to Mode :%s\n",
151*1738061cSShyam Sundar S K 					state_as_str(config_store.current_mode));
152*1738061cSShyam Sundar S K 				amd_pmf_set_cnqf(dev, src,
153*1738061cSShyam Sundar S K 						 config_store.current_mode, NULL);
154*1738061cSShyam Sundar S K 			}
155*1738061cSShyam Sundar S K 			break;
156*1738061cSShyam Sundar S K 		}
157*1738061cSShyam Sundar S K 	}
158*1738061cSShyam Sundar S K 	return 0;
159*1738061cSShyam Sundar S K }
160*1738061cSShyam Sundar S K 
161*1738061cSShyam Sundar S K static void amd_pmf_update_trans_data(int idx, struct apmf_dyn_slider_output out)
162*1738061cSShyam Sundar S K {
163*1738061cSShyam Sundar S K 	struct cnqf_tran_params *tp;
164*1738061cSShyam Sundar S K 
165*1738061cSShyam Sundar S K 	tp = &config_store.trans_param[idx][CNQF_TRANSITION_TO_QUIET];
166*1738061cSShyam Sundar S K 	tp->time_constant = out.t_balanced_to_quiet;
167*1738061cSShyam Sundar S K 	tp->target_mode = CNQF_MODE_QUIET;
168*1738061cSShyam Sundar S K 	tp->shifting_up = false;
169*1738061cSShyam Sundar S K 
170*1738061cSShyam Sundar S K 	tp = &config_store.trans_param[idx][CNQF_TRANSITION_FROM_BALANCE_TO_PERFORMANCE];
171*1738061cSShyam Sundar S K 	tp->time_constant = out.t_balanced_to_perf;
172*1738061cSShyam Sundar S K 	tp->target_mode = CNQF_MODE_PERFORMANCE;
173*1738061cSShyam Sundar S K 	tp->shifting_up = true;
174*1738061cSShyam Sundar S K 
175*1738061cSShyam Sundar S K 	tp = &config_store.trans_param[idx][CNQF_TRANSITION_FROM_QUIET_TO_BALANCE];
176*1738061cSShyam Sundar S K 	tp->time_constant = out.t_quiet_to_balanced;
177*1738061cSShyam Sundar S K 	tp->target_mode = CNQF_MODE_BALANCE;
178*1738061cSShyam Sundar S K 	tp->shifting_up = true;
179*1738061cSShyam Sundar S K 
180*1738061cSShyam Sundar S K 	tp = &config_store.trans_param[idx][CNQF_TRANSITION_FROM_PERFORMANCE_TO_BALANCE];
181*1738061cSShyam Sundar S K 	tp->time_constant = out.t_perf_to_balanced;
182*1738061cSShyam Sundar S K 	tp->target_mode = CNQF_MODE_BALANCE;
183*1738061cSShyam Sundar S K 	tp->shifting_up = false;
184*1738061cSShyam Sundar S K 
185*1738061cSShyam Sundar S K 	tp = &config_store.trans_param[idx][CNQF_TRANSITION_FROM_TURBO_TO_PERFORMANCE];
186*1738061cSShyam Sundar S K 	tp->time_constant = out.t_turbo_to_perf;
187*1738061cSShyam Sundar S K 	tp->target_mode = CNQF_MODE_PERFORMANCE;
188*1738061cSShyam Sundar S K 	tp->shifting_up = false;
189*1738061cSShyam Sundar S K 
190*1738061cSShyam Sundar S K 	tp = &config_store.trans_param[idx][CNQF_TRANSITION_TO_TURBO];
191*1738061cSShyam Sundar S K 	tp->time_constant = out.t_perf_to_turbo;
192*1738061cSShyam Sundar S K 	tp->target_mode = CNQF_MODE_TURBO;
193*1738061cSShyam Sundar S K 	tp->shifting_up = true;
194*1738061cSShyam Sundar S K }
195*1738061cSShyam Sundar S K 
196*1738061cSShyam Sundar S K static void amd_pmf_update_mode_set(int idx, struct apmf_dyn_slider_output out)
197*1738061cSShyam Sundar S K {
198*1738061cSShyam Sundar S K 	struct cnqf_mode_settings *ms;
199*1738061cSShyam Sundar S K 
200*1738061cSShyam Sundar S K 	/* Quiet Mode */
201*1738061cSShyam Sundar S K 	ms = &config_store.mode_set[idx][CNQF_MODE_QUIET];
202*1738061cSShyam Sundar S K 	ms->power_floor = out.ps[APMF_CNQF_QUIET].pfloor;
203*1738061cSShyam Sundar S K 	ms->power_control.fppt = out.ps[APMF_CNQF_QUIET].fppt;
204*1738061cSShyam Sundar S K 	ms->power_control.sppt = out.ps[APMF_CNQF_QUIET].sppt;
205*1738061cSShyam Sundar S K 	ms->power_control.sppt_apu_only = out.ps[APMF_CNQF_QUIET].sppt_apu_only;
206*1738061cSShyam Sundar S K 	ms->power_control.spl = out.ps[APMF_CNQF_QUIET].spl;
207*1738061cSShyam Sundar S K 	ms->power_control.stt_min = out.ps[APMF_CNQF_QUIET].stt_min_limit;
208*1738061cSShyam Sundar S K 	ms->power_control.stt_skin_temp[STT_TEMP_APU] =
209*1738061cSShyam Sundar S K 		out.ps[APMF_CNQF_QUIET].stt_skintemp[STT_TEMP_APU];
210*1738061cSShyam Sundar S K 	ms->power_control.stt_skin_temp[STT_TEMP_HS2] =
211*1738061cSShyam Sundar S K 		out.ps[APMF_CNQF_QUIET].stt_skintemp[STT_TEMP_HS2];
212*1738061cSShyam Sundar S K 	ms->fan_control.fan_id = out.ps[APMF_CNQF_QUIET].fan_id;
213*1738061cSShyam Sundar S K 
214*1738061cSShyam Sundar S K 	/* Balance Mode */
215*1738061cSShyam Sundar S K 	ms = &config_store.mode_set[idx][CNQF_MODE_BALANCE];
216*1738061cSShyam Sundar S K 	ms->power_floor = out.ps[APMF_CNQF_BALANCE].pfloor;
217*1738061cSShyam Sundar S K 	ms->power_control.fppt = out.ps[APMF_CNQF_BALANCE].fppt;
218*1738061cSShyam Sundar S K 	ms->power_control.sppt = out.ps[APMF_CNQF_BALANCE].sppt;
219*1738061cSShyam Sundar S K 	ms->power_control.sppt_apu_only = out.ps[APMF_CNQF_BALANCE].sppt_apu_only;
220*1738061cSShyam Sundar S K 	ms->power_control.spl = out.ps[APMF_CNQF_BALANCE].spl;
221*1738061cSShyam Sundar S K 	ms->power_control.stt_min = out.ps[APMF_CNQF_BALANCE].stt_min_limit;
222*1738061cSShyam Sundar S K 	ms->power_control.stt_skin_temp[STT_TEMP_APU] =
223*1738061cSShyam Sundar S K 		out.ps[APMF_CNQF_BALANCE].stt_skintemp[STT_TEMP_APU];
224*1738061cSShyam Sundar S K 	ms->power_control.stt_skin_temp[STT_TEMP_HS2] =
225*1738061cSShyam Sundar S K 		out.ps[APMF_CNQF_BALANCE].stt_skintemp[STT_TEMP_HS2];
226*1738061cSShyam Sundar S K 	ms->fan_control.fan_id = out.ps[APMF_CNQF_BALANCE].fan_id;
227*1738061cSShyam Sundar S K 
228*1738061cSShyam Sundar S K 	/* Performance Mode */
229*1738061cSShyam Sundar S K 	ms = &config_store.mode_set[idx][CNQF_MODE_PERFORMANCE];
230*1738061cSShyam Sundar S K 	ms->power_floor = out.ps[APMF_CNQF_PERFORMANCE].pfloor;
231*1738061cSShyam Sundar S K 	ms->power_control.fppt = out.ps[APMF_CNQF_PERFORMANCE].fppt;
232*1738061cSShyam Sundar S K 	ms->power_control.sppt = out.ps[APMF_CNQF_PERFORMANCE].sppt;
233*1738061cSShyam Sundar S K 	ms->power_control.sppt_apu_only = out.ps[APMF_CNQF_PERFORMANCE].sppt_apu_only;
234*1738061cSShyam Sundar S K 	ms->power_control.spl = out.ps[APMF_CNQF_PERFORMANCE].spl;
235*1738061cSShyam Sundar S K 	ms->power_control.stt_min = out.ps[APMF_CNQF_PERFORMANCE].stt_min_limit;
236*1738061cSShyam Sundar S K 	ms->power_control.stt_skin_temp[STT_TEMP_APU] =
237*1738061cSShyam Sundar S K 		out.ps[APMF_CNQF_PERFORMANCE].stt_skintemp[STT_TEMP_APU];
238*1738061cSShyam Sundar S K 	ms->power_control.stt_skin_temp[STT_TEMP_HS2] =
239*1738061cSShyam Sundar S K 		out.ps[APMF_CNQF_PERFORMANCE].stt_skintemp[STT_TEMP_HS2];
240*1738061cSShyam Sundar S K 	ms->fan_control.fan_id = out.ps[APMF_CNQF_PERFORMANCE].fan_id;
241*1738061cSShyam Sundar S K 
242*1738061cSShyam Sundar S K 	/* Turbo Mode */
243*1738061cSShyam Sundar S K 	ms = &config_store.mode_set[idx][CNQF_MODE_TURBO];
244*1738061cSShyam Sundar S K 	ms->power_floor = out.ps[APMF_CNQF_TURBO].pfloor;
245*1738061cSShyam Sundar S K 	ms->power_control.fppt = out.ps[APMF_CNQF_TURBO].fppt;
246*1738061cSShyam Sundar S K 	ms->power_control.sppt = out.ps[APMF_CNQF_TURBO].sppt;
247*1738061cSShyam Sundar S K 	ms->power_control.sppt_apu_only = out.ps[APMF_CNQF_TURBO].sppt_apu_only;
248*1738061cSShyam Sundar S K 	ms->power_control.spl = out.ps[APMF_CNQF_TURBO].spl;
249*1738061cSShyam Sundar S K 	ms->power_control.stt_min = out.ps[APMF_CNQF_TURBO].stt_min_limit;
250*1738061cSShyam Sundar S K 	ms->power_control.stt_skin_temp[STT_TEMP_APU] =
251*1738061cSShyam Sundar S K 		out.ps[APMF_CNQF_TURBO].stt_skintemp[STT_TEMP_APU];
252*1738061cSShyam Sundar S K 	ms->power_control.stt_skin_temp[STT_TEMP_HS2] =
253*1738061cSShyam Sundar S K 		out.ps[APMF_CNQF_TURBO].stt_skintemp[STT_TEMP_HS2];
254*1738061cSShyam Sundar S K 	ms->fan_control.fan_id = out.ps[APMF_CNQF_TURBO].fan_id;
255*1738061cSShyam Sundar S K }
256*1738061cSShyam Sundar S K 
257*1738061cSShyam Sundar S K static int amd_pmf_check_flags(struct amd_pmf_dev *dev)
258*1738061cSShyam Sundar S K {
259*1738061cSShyam Sundar S K 	struct apmf_dyn_slider_output out = {};
260*1738061cSShyam Sundar S K 
261*1738061cSShyam Sundar S K 	if (is_apmf_func_supported(dev, APMF_FUNC_DYN_SLIDER_AC))
262*1738061cSShyam Sundar S K 		apmf_get_dyn_slider_def_ac(dev, &out);
263*1738061cSShyam Sundar S K 	else if (is_apmf_func_supported(dev, APMF_FUNC_DYN_SLIDER_DC))
264*1738061cSShyam Sundar S K 		apmf_get_dyn_slider_def_dc(dev, &out);
265*1738061cSShyam Sundar S K 
266*1738061cSShyam Sundar S K 	return out.flags;
267*1738061cSShyam Sundar S K }
268*1738061cSShyam Sundar S K 
269*1738061cSShyam Sundar S K static int amd_pmf_load_defaults_cnqf(struct amd_pmf_dev *dev)
270*1738061cSShyam Sundar S K {
271*1738061cSShyam Sundar S K 	struct apmf_dyn_slider_output out;
272*1738061cSShyam Sundar S K 	int i, j, ret;
273*1738061cSShyam Sundar S K 
274*1738061cSShyam Sundar S K 	for (i = 0; i < POWER_SOURCE_MAX; i++) {
275*1738061cSShyam Sundar S K 		if (!is_apmf_func_supported(dev, APMF_FUNC_DYN_SLIDER_AC + i))
276*1738061cSShyam Sundar S K 			continue;
277*1738061cSShyam Sundar S K 
278*1738061cSShyam Sundar S K 		if (i == POWER_SOURCE_AC)
279*1738061cSShyam Sundar S K 			ret = apmf_get_dyn_slider_def_ac(dev, &out);
280*1738061cSShyam Sundar S K 		else
281*1738061cSShyam Sundar S K 			ret = apmf_get_dyn_slider_def_dc(dev, &out);
282*1738061cSShyam Sundar S K 		if (ret) {
283*1738061cSShyam Sundar S K 			dev_err(dev->dev, "APMF apmf_get_dyn_slider_def_dc failed :%d\n", ret);
284*1738061cSShyam Sundar S K 			return ret;
285*1738061cSShyam Sundar S K 		}
286*1738061cSShyam Sundar S K 
287*1738061cSShyam Sundar S K 		amd_pmf_update_mode_set(i, out);
288*1738061cSShyam Sundar S K 		amd_pmf_update_trans_data(i, out);
289*1738061cSShyam Sundar S K 		amd_pmf_update_power_threshold(i);
290*1738061cSShyam Sundar S K 
291*1738061cSShyam Sundar S K 		for (j = 0; j < CNQF_MODE_MAX; j++) {
292*1738061cSShyam Sundar S K 			if (config_store.mode_set[i][j].fan_control.fan_id == FAN_INDEX_AUTO)
293*1738061cSShyam Sundar S K 				config_store.mode_set[i][j].fan_control.manual = false;
294*1738061cSShyam Sundar S K 			else
295*1738061cSShyam Sundar S K 				config_store.mode_set[i][j].fan_control.manual = true;
296*1738061cSShyam Sundar S K 		}
297*1738061cSShyam Sundar S K 	}
298*1738061cSShyam Sundar S K 
299*1738061cSShyam Sundar S K 	/* set to initial default values */
300*1738061cSShyam Sundar S K 	config_store.current_mode = CNQF_MODE_BALANCE;
301*1738061cSShyam Sundar S K 
302*1738061cSShyam Sundar S K 	return 0;
303*1738061cSShyam Sundar S K }
304*1738061cSShyam Sundar S K 
305*1738061cSShyam Sundar S K void amd_pmf_deinit_cnqf(struct amd_pmf_dev *dev)
306*1738061cSShyam Sundar S K {
307*1738061cSShyam Sundar S K 	cancel_delayed_work_sync(&dev->work_buffer);
308*1738061cSShyam Sundar S K }
309*1738061cSShyam Sundar S K 
310*1738061cSShyam Sundar S K int amd_pmf_init_cnqf(struct amd_pmf_dev *dev)
311*1738061cSShyam Sundar S K {
312*1738061cSShyam Sundar S K 	int ret, src;
313*1738061cSShyam Sundar S K 
314*1738061cSShyam Sundar S K 	/*
315*1738061cSShyam Sundar S K 	 * Note the caller of this function has already checked that both
316*1738061cSShyam Sundar S K 	 * APMF_FUNC_DYN_SLIDER_AC and APMF_FUNC_DYN_SLIDER_DC are supported.
317*1738061cSShyam Sundar S K 	 */
318*1738061cSShyam Sundar S K 
319*1738061cSShyam Sundar S K 	ret = amd_pmf_load_defaults_cnqf(dev);
320*1738061cSShyam Sundar S K 	if (ret < 0)
321*1738061cSShyam Sundar S K 		return ret;
322*1738061cSShyam Sundar S K 
323*1738061cSShyam Sundar S K 	amd_pmf_init_metrics_table(dev);
324*1738061cSShyam Sundar S K 
325*1738061cSShyam Sundar S K 	dev->cnqf_supported = true;
326*1738061cSShyam Sundar S K 	dev->cnqf_enabled = amd_pmf_check_flags(dev);
327*1738061cSShyam Sundar S K 
328*1738061cSShyam Sundar S K 	/* update the thermal for CnQF */
329*1738061cSShyam Sundar S K 	if (dev->cnqf_enabled && dev->current_profile == PLATFORM_PROFILE_BALANCED) {
330*1738061cSShyam Sundar S K 		src = amd_pmf_cnqf_get_power_source(dev);
331*1738061cSShyam Sundar S K 		amd_pmf_set_cnqf(dev, src, config_store.current_mode, NULL);
332*1738061cSShyam Sundar S K 	}
333*1738061cSShyam Sundar S K 
334*1738061cSShyam Sundar S K 	return 0;
335*1738061cSShyam Sundar S K }
336