xref: /linux/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c (revision 8e65320d91cdc3b241d4b94855c88459b91abf66)
1 /*
2  * Copyright 2020 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  */
22 
23 #define SWSMU_CODE_LAYER_L4
24 
25 #include "amdgpu.h"
26 #include "amdgpu_smu.h"
27 #include "smu_cmn.h"
28 #include "soc15_common.h"
29 
30 /*
31  * DO NOT use these for err/warn/info/debug messages.
32  * Use dev_err, dev_warn, dev_info and dev_dbg instead.
33  * They are more MGPU friendly.
34  */
35 #undef pr_err
36 #undef pr_warn
37 #undef pr_info
38 #undef pr_debug
39 
40 #define MP1_C2PMSG_90__CONTENT_MASK                                                                    0xFFFFFFFFL
41 
42 const int link_speed[] = {25, 50, 80, 160, 320, 640};
43 
44 #undef __SMU_DUMMY_MAP
45 #define __SMU_DUMMY_MAP(type)	#type
46 static const char * const __smu_message_names[] = {
47 	SMU_MESSAGE_TYPES
48 };
49 
50 #define smu_cmn_call_asic_func(intf, smu, args...)                             \
51 	((smu)->ppt_funcs ? ((smu)->ppt_funcs->intf ?                          \
52 				     (smu)->ppt_funcs->intf(smu, ##args) :     \
53 				     -ENOTSUPP) :                              \
54 			    -EINVAL)
55 
56 #define SMU_MSG_V1_DEFAULT_RATELIMIT_INTERVAL (5 * HZ)
57 #define SMU_MSG_V1_DEFAULT_RATELIMIT_BURST 10
58 
smu_get_message_name(struct smu_context * smu,enum smu_message_type type)59 static const char *smu_get_message_name(struct smu_context *smu,
60 					enum smu_message_type type)
61 {
62 	if (type >= SMU_MSG_MAX_COUNT)
63 		return "unknown smu message";
64 
65 	return __smu_message_names[type];
66 }
67 
68 /* Redefine the SMU error codes here.
69  *
70  * Note that these definitions are redundant and should be removed
71  * when the SMU has exported a unified header file containing these
72  * macros, which header file we can just include and use the SMU's
73  * macros. At the moment, these error codes are defined by the SMU
74  * per-ASIC unfortunately, yet we're a one driver for all ASICs.
75  */
76 #define SMU_RESP_NONE           0
77 #define SMU_RESP_OK             1
78 #define SMU_RESP_CMD_FAIL       0xFF
79 #define SMU_RESP_CMD_UNKNOWN    0xFE
80 #define SMU_RESP_CMD_BAD_PREREQ 0xFD
81 #define SMU_RESP_BUSY_OTHER     0xFC
82 #define SMU_RESP_DEBUG_END      0xFB
83 
84 #define SMU_RESP_UNEXP (~0U)
85 
smu_msg_v1_send_debug_msg(struct smu_msg_ctl * ctl,u32 msg,u32 param)86 static int smu_msg_v1_send_debug_msg(struct smu_msg_ctl *ctl, u32 msg, u32 param)
87 {
88 	struct amdgpu_device *adev = ctl->smu->adev;
89 	struct smu_msg_config *cfg = &ctl->config;
90 
91 	if (!(ctl->flags & SMU_MSG_CTL_DEBUG_MAILBOX))
92 		return -EOPNOTSUPP;
93 
94 	mutex_lock(&ctl->lock);
95 
96 	WREG32(cfg->debug_param_reg, param);
97 	WREG32(cfg->debug_msg_reg, msg);
98 	WREG32(cfg->debug_resp_reg, 0);
99 
100 	mutex_unlock(&ctl->lock);
101 
102 	return 0;
103 }
104 
__smu_cmn_send_debug_msg(struct smu_msg_ctl * ctl,u32 msg,u32 param)105 static int __smu_cmn_send_debug_msg(struct smu_msg_ctl *ctl,
106 				    u32 msg,
107 				    u32 param)
108 {
109 	if (!ctl->ops || !ctl->ops->send_debug_msg)
110 		return -EOPNOTSUPP;
111 
112 	return ctl->ops->send_debug_msg(ctl, msg, param);
113 }
114 
115 /**
116  * smu_cmn_wait_for_response -- wait for response from the SMU
117  * @smu: pointer to an SMU context
118  *
119  * Wait for status from the SMU.
120  *
121  * Return 0 on success, -errno on error, indicating the execution
122  * status and result of the message being waited for. See
123  * smu_msg_v1_decode_response() for details of the -errno.
124  */
smu_cmn_wait_for_response(struct smu_context * smu)125 int smu_cmn_wait_for_response(struct smu_context *smu)
126 {
127 	return smu_msg_wait_response(&smu->msg_ctl, 0);
128 }
129 
130 /**
131  * smu_cmn_send_smc_msg_with_param -- send a message with parameter
132  * @smu: pointer to an SMU context
133  * @msg: message to send
134  * @param: parameter to send to the SMU
135  * @read_arg: pointer to u32 to return a value from the SMU back
136  *            to the caller
137  *
138  * Send the message @msg with parameter @param to the SMU, wait for
139  * completion of the command, and return back a value from the SMU in
140  * @read_arg pointer.
141  *
142  * Return 0 on success, -errno when a problem is encountered sending
143  * message or receiving reply. If there is a PCI bus recovery or
144  * the destination is a virtual GPU which does not allow this message
145  * type, the message is simply dropped and success is also returned.
146  * See smu_msg_v1_decode_response() for details of the -errno.
147  *
148  * If we weren't able to send the message to the SMU, we also print
149  * the error to the standard log.
150  *
151  * Command completion status is printed only if the -errno is
152  * -EREMOTEIO, indicating that the SMU returned back an
153  * undefined/unknown/unspecified result. All other cases are
154  * well-defined, not printed, but instead given back to the client to
155  * decide what further to do.
156  *
157  * The return value, @read_arg is read back regardless, to give back
158  * more information to the client, which on error would most likely be
159  * @param, but we can't assume that. This also eliminates more
160  * conditionals.
161  */
smu_cmn_send_smc_msg_with_param(struct smu_context * smu,enum smu_message_type msg,uint32_t param,uint32_t * read_arg)162 int smu_cmn_send_smc_msg_with_param(struct smu_context *smu,
163 				    enum smu_message_type msg,
164 				    uint32_t param,
165 				    uint32_t *read_arg)
166 {
167 	struct smu_msg_ctl *ctl = &smu->msg_ctl;
168 	struct smu_msg_args args = {
169 		.msg = msg,
170 		.args[0] = param,
171 		.num_args = 1,
172 		.num_out_args = read_arg ? 1 : 0,
173 		.flags = 0,
174 		.timeout = 0,
175 	};
176 	int ret;
177 
178 	ret = ctl->ops->send_msg(ctl, &args);
179 
180 	if (read_arg)
181 		*read_arg = args.out_args[0];
182 
183 	return ret;
184 }
185 
smu_cmn_send_smc_msg(struct smu_context * smu,enum smu_message_type msg,uint32_t * read_arg)186 int smu_cmn_send_smc_msg(struct smu_context *smu,
187 			 enum smu_message_type msg,
188 			 uint32_t *read_arg)
189 {
190 	return smu_cmn_send_smc_msg_with_param(smu,
191 					       msg,
192 					       0,
193 					       read_arg);
194 }
195 
smu_cmn_send_debug_smc_msg(struct smu_context * smu,uint32_t msg)196 int smu_cmn_send_debug_smc_msg(struct smu_context *smu,
197 			 uint32_t msg)
198 {
199 	return __smu_cmn_send_debug_msg(&smu->msg_ctl, msg, 0);
200 }
201 
smu_cmn_send_debug_smc_msg_with_param(struct smu_context * smu,uint32_t msg,uint32_t param)202 int smu_cmn_send_debug_smc_msg_with_param(struct smu_context *smu,
203 			 uint32_t msg, uint32_t param)
204 {
205 	return __smu_cmn_send_debug_msg(&smu->msg_ctl, msg, param);
206 }
207 
smu_msg_v1_decode_response(u32 resp)208 static int smu_msg_v1_decode_response(u32 resp)
209 {
210 	int res;
211 
212 	switch (resp) {
213 	case SMU_RESP_NONE:
214 		/* The SMU is busy--still executing your command.
215 		 */
216 		res = -ETIME;
217 		break;
218 	case SMU_RESP_OK:
219 		res = 0;
220 		break;
221 	case SMU_RESP_CMD_FAIL:
222 		/* Command completed successfully, but the command
223 		 * status was failure.
224 		 */
225 		res = -EIO;
226 		break;
227 	case SMU_RESP_CMD_UNKNOWN:
228 		/* Unknown command--ignored by the SMU.
229 		 */
230 		res = -EOPNOTSUPP;
231 		break;
232 	case SMU_RESP_CMD_BAD_PREREQ:
233 		/* Valid command--bad prerequisites.
234 		 */
235 		res = -EINVAL;
236 		break;
237 	case SMU_RESP_BUSY_OTHER:
238 		/* The SMU is busy with other commands. The client
239 		 * should retry in 10 us.
240 		 */
241 		res = -EBUSY;
242 		break;
243 	default:
244 		/* Unknown or debug response from the SMU.
245 		 */
246 		res = -EREMOTEIO;
247 		break;
248 	}
249 
250 	return res;
251 }
252 
__smu_msg_v1_poll_stat(struct smu_msg_ctl * ctl,u32 timeout_us)253 static u32 __smu_msg_v1_poll_stat(struct smu_msg_ctl *ctl, u32 timeout_us)
254 {
255 	struct amdgpu_device *adev = ctl->smu->adev;
256 	struct smu_msg_config *cfg = &ctl->config;
257 	u32 timeout = timeout_us ? timeout_us : ctl->default_timeout;
258 	u32 reg;
259 
260 	for (; timeout > 0; timeout--) {
261 		reg = RREG32(cfg->resp_reg);
262 		if ((reg & MP1_C2PMSG_90__CONTENT_MASK) != 0)
263 			break;
264 		udelay(1);
265 	}
266 
267 	return reg;
268 }
269 
__smu_msg_v1_send(struct smu_msg_ctl * ctl,u16 index,struct smu_msg_args * args)270 static void __smu_msg_v1_send(struct smu_msg_ctl *ctl, u16 index,
271 			      struct smu_msg_args *args)
272 {
273 	struct amdgpu_device *adev = ctl->smu->adev;
274 	struct smu_msg_config *cfg = &ctl->config;
275 	u32 arg;
276 	int i;
277 
278 	WREG32(cfg->resp_reg, 0);
279 	for (i = 0; i < cfg->num_arg_regs; i++) {
280 		/* NOTE: Clear unused argument registers to avoid stale values. */
281 		arg = i < args->num_args ? args->args[i] : 0;
282 		WREG32(cfg->arg_regs[i], arg);
283 	}
284 	WREG32(cfg->msg_reg, index);
285 }
286 
__smu_msg_v1_read_out_args(struct smu_msg_ctl * ctl,struct smu_msg_args * args)287 static void __smu_msg_v1_read_out_args(struct smu_msg_ctl *ctl,
288 				       struct smu_msg_args *args)
289 {
290 	struct amdgpu_device *adev = ctl->smu->adev;
291 	int i;
292 
293 	for (i = 0; i < args->num_out_args; i++)
294 		args->out_args[i] = RREG32(ctl->config.arg_regs[i]);
295 }
296 
__smu_msg_v1_print_err_limited(struct smu_msg_ctl * ctl,struct smu_msg_args * args,char * err_msg)297 static void __smu_msg_v1_print_err_limited(struct smu_msg_ctl *ctl,
298 					   struct smu_msg_args *args,
299 					   char *err_msg)
300 {
301 	static DEFINE_RATELIMIT_STATE(_rs,
302 				      SMU_MSG_V1_DEFAULT_RATELIMIT_INTERVAL,
303 				      SMU_MSG_V1_DEFAULT_RATELIMIT_BURST);
304 	struct smu_context *smu = ctl->smu;
305 	struct amdgpu_device *adev = smu->adev;
306 
307 	if (__ratelimit(&_rs)) {
308 		u32 in[SMU_MSG_MAX_ARGS];
309 		int i;
310 
311 		dev_err(adev->dev, "%s msg_reg: %x resp_reg: %x", err_msg,
312 			RREG32(ctl->config.msg_reg),
313 			RREG32(ctl->config.resp_reg));
314 		if (args->num_args > 0) {
315 			for (i = 0; i < args->num_args; i++)
316 				in[i] = RREG32(ctl->config.arg_regs[i]);
317 			print_hex_dump(KERN_ERR, "in params:", DUMP_PREFIX_NONE,
318 				       16, 4, in, args->num_args * sizeof(u32),
319 				       false);
320 		}
321 	}
322 }
323 
__smu_msg_v1_print_error(struct smu_msg_ctl * ctl,u32 resp,struct smu_msg_args * args)324 static void __smu_msg_v1_print_error(struct smu_msg_ctl *ctl,
325 				     u32 resp,
326 				     struct smu_msg_args *args)
327 {
328 	struct smu_context *smu = ctl->smu;
329 	struct amdgpu_device *adev = smu->adev;
330 	int index = ctl->message_map[args->msg].map_to;
331 
332 	switch (resp) {
333 	case SMU_RESP_NONE:
334 		__smu_msg_v1_print_err_limited(ctl, args, "SMU: No response");
335 		break;
336 	case SMU_RESP_OK:
337 		break;
338 	case SMU_RESP_CMD_FAIL:
339 		break;
340 	case SMU_RESP_CMD_UNKNOWN:
341 		__smu_msg_v1_print_err_limited(ctl, args,
342 					       "SMU: unknown command");
343 		break;
344 	case SMU_RESP_CMD_BAD_PREREQ:
345 		__smu_msg_v1_print_err_limited(
346 			ctl, args, "SMU: valid command, bad prerequisites");
347 		break;
348 	case SMU_RESP_BUSY_OTHER:
349 		if (args->msg != SMU_MSG_GetBadPageCount)
350 			__smu_msg_v1_print_err_limited(ctl, args,
351 						       "SMU: I'm very busy");
352 		break;
353 	case SMU_RESP_DEBUG_END:
354 		__smu_msg_v1_print_err_limited(ctl, args, "SMU: Debug Err");
355 		break;
356 	case SMU_RESP_UNEXP:
357 		if (amdgpu_device_bus_status_check(adev)) {
358 			dev_err(adev->dev,
359 				"SMU: bus error for message: %s(%d) response:0x%08X ",
360 				smu_get_message_name(smu, args->msg), index,
361 				resp);
362 			if (args->num_args > 0)
363 				print_hex_dump(KERN_ERR,
364 					       "in params:", DUMP_PREFIX_NONE,
365 					       16, 4, args->args,
366 					       args->num_args * sizeof(u32),
367 					       false);
368 		}
369 		break;
370 	default:
371 		__smu_msg_v1_print_err_limited(ctl, args,
372 					       "SMU: unknown response");
373 		break;
374 	}
375 }
376 
__smu_msg_v1_ras_filter(struct smu_msg_ctl * ctl,enum smu_message_type msg,u32 msg_flags,bool * skip_pre_poll)377 static int __smu_msg_v1_ras_filter(struct smu_msg_ctl *ctl,
378 				   enum smu_message_type msg, u32 msg_flags,
379 				   bool *skip_pre_poll)
380 {
381 	struct smu_context *smu = ctl->smu;
382 	struct amdgpu_device *adev = smu->adev;
383 	bool fed_status;
384 	u32 reg;
385 
386 	if (!(smu->smc_fw_caps & SMU_FW_CAP_RAS_PRI))
387 		return 0;
388 
389 	fed_status = amdgpu_ras_get_fed_status(adev);
390 
391 	/* Block non-RAS-priority messages during RAS error */
392 	if (fed_status && !(msg_flags & SMU_MSG_RAS_PRI)) {
393 		dev_dbg(adev->dev, "RAS error detected, skip sending %s",
394 			smu_get_message_name(smu, msg));
395 		return -EACCES;
396 	}
397 
398 	/* Skip pre-poll for priority messages or during RAS error */
399 	if ((msg_flags & SMU_MSG_NO_PRECHECK) || fed_status) {
400 		reg = RREG32(ctl->config.resp_reg);
401 		dev_dbg(adev->dev,
402 			"Sending priority message %s response status: %x",
403 			smu_get_message_name(smu, msg), reg);
404 		if (reg == 0)
405 			*skip_pre_poll = true;
406 	}
407 
408 	return 0;
409 }
410 
411 /**
412  * smu_msg_v1_send_msg - Complete V1 protocol with all filtering
413  * @ctl: Message control block
414  * @args: Message arguments
415  *
416  * Return: 0 on success, negative errno on failure
417  */
smu_msg_v1_send_msg(struct smu_msg_ctl * ctl,struct smu_msg_args * args)418 static int smu_msg_v1_send_msg(struct smu_msg_ctl *ctl,
419 			       struct smu_msg_args *args)
420 {
421 	struct smu_context *smu = ctl->smu;
422 	struct amdgpu_device *adev = smu->adev;
423 	const struct cmn2asic_msg_mapping *mapping;
424 	u32 reg, msg_flags;
425 	int ret, index;
426 	bool skip_pre_poll = false;
427 	bool lock_held = args->flags & SMU_MSG_FLAG_LOCK_HELD;
428 
429 	/* Early exit if no HW access */
430 	if (adev->no_hw_access)
431 		return 0;
432 
433 	/* Message index translation */
434 	if (args->msg >= SMU_MSG_MAX_COUNT || !ctl->message_map)
435 		return -EINVAL;
436 
437 	if (args->num_args > ctl->config.num_arg_regs ||
438 	    args->num_out_args > ctl->config.num_arg_regs)
439 		return -EINVAL;
440 
441 	mapping = &ctl->message_map[args->msg];
442 	if (!mapping->valid_mapping)
443 		return -EINVAL;
444 
445 	msg_flags = mapping->flags;
446 	index = mapping->map_to;
447 
448 	/* VF filter - skip messages not valid for VF */
449 	if (amdgpu_sriov_vf(adev) && !(msg_flags & SMU_MSG_VF_FLAG))
450 		return 0;
451 
452 	if (!lock_held)
453 		mutex_lock(&ctl->lock);
454 
455 	/* RAS priority filter */
456 	ret = __smu_msg_v1_ras_filter(ctl, args->msg, msg_flags,
457 				      &skip_pre_poll);
458 	if (ret)
459 		goto out;
460 
461 	/* FW state checks */
462 	if (smu->smc_fw_state == SMU_FW_HANG) {
463 		dev_err(adev->dev,
464 			"SMU is in hanged state, failed to send smu message!\n");
465 		ret = -EREMOTEIO;
466 		goto out;
467 	} else if (smu->smc_fw_state == SMU_FW_INIT) {
468 		skip_pre_poll = true;
469 		smu->smc_fw_state = SMU_FW_RUNTIME;
470 	}
471 
472 	/* Pre-poll: ensure previous message completed */
473 	if (!skip_pre_poll) {
474 		reg = __smu_msg_v1_poll_stat(ctl, args->timeout);
475 		ret = smu_msg_v1_decode_response(reg);
476 		if (reg == SMU_RESP_NONE || ret == -EREMOTEIO) {
477 			__smu_msg_v1_print_error(ctl, reg, args);
478 			goto out;
479 		}
480 	}
481 
482 	/* Send message */
483 	__smu_msg_v1_send(ctl, (u16)index, args);
484 
485 	/* Post-poll (skip if ASYNC) */
486 	if (args->flags & SMU_MSG_FLAG_ASYNC) {
487 		ret = 0;
488 		goto out;
489 	}
490 
491 	reg = __smu_msg_v1_poll_stat(ctl, args->timeout);
492 	ret = smu_msg_v1_decode_response(reg);
493 
494 	/* FW state update on fatal error */
495 	if (ret == -EREMOTEIO) {
496 		smu->smc_fw_state = SMU_FW_HANG;
497 		__smu_msg_v1_print_error(ctl, reg, args);
498 	} else if (ret != 0) {
499 		__smu_msg_v1_print_error(ctl, reg, args);
500 	}
501 
502 	/* Read output args */
503 	if ((ret == 0 || (args->flags & SMU_MSG_FLAG_FORCE_READ_ARG)) &&
504 	    args->num_out_args > 0) {
505 		__smu_msg_v1_read_out_args(ctl, args);
506 		dev_dbg(adev->dev, "smu send message: %s(%d) resp : 0x%08x",
507 			smu_get_message_name(smu, args->msg), index, reg);
508 		if (args->num_args > 0)
509 			print_hex_dump_debug("in params:", DUMP_PREFIX_NONE, 16,
510 					     4, args->args,
511 					     args->num_args * sizeof(u32),
512 					     false);
513 		print_hex_dump_debug("out params:", DUMP_PREFIX_NONE, 16, 4,
514 				     args->out_args,
515 				     args->num_out_args * sizeof(u32), false);
516 	} else {
517 		dev_dbg(adev->dev, "smu send message: %s(%d), resp: 0x%08x\n",
518 			smu_get_message_name(smu, args->msg), index, reg);
519 		if (args->num_args > 0)
520 			print_hex_dump_debug("in params:", DUMP_PREFIX_NONE, 16,
521 					     4, args->args,
522 					     args->num_args * sizeof(u32),
523 					     false);
524 	}
525 
526 out:
527 	/* Debug halt on error */
528 	if (unlikely(adev->pm.smu_debug_mask & SMU_DEBUG_HALT_ON_ERROR) &&
529 	    ret) {
530 		amdgpu_device_halt(adev);
531 		WARN_ON(1);
532 	}
533 
534 	if (!lock_held)
535 		mutex_unlock(&ctl->lock);
536 	return ret;
537 }
538 
smu_msg_v1_wait_response(struct smu_msg_ctl * ctl,u32 timeout_us)539 static int smu_msg_v1_wait_response(struct smu_msg_ctl *ctl, u32 timeout_us)
540 {
541 	struct smu_context *smu = ctl->smu;
542 	struct amdgpu_device *adev = smu->adev;
543 	u32 reg;
544 	int ret;
545 
546 	reg = __smu_msg_v1_poll_stat(ctl, timeout_us);
547 	ret = smu_msg_v1_decode_response(reg);
548 
549 	if (ret == -EREMOTEIO)
550 		smu->smc_fw_state = SMU_FW_HANG;
551 
552 	if (unlikely(adev->pm.smu_debug_mask & SMU_DEBUG_HALT_ON_ERROR) &&
553 	    ret && (ret != -ETIME)) {
554 		amdgpu_device_halt(adev);
555 		WARN_ON(1);
556 	}
557 
558 	return ret;
559 }
560 
561 const struct smu_msg_ops smu_msg_v1_ops = {
562 	.send_msg = smu_msg_v1_send_msg,
563 	.wait_response = smu_msg_v1_wait_response,
564 	.decode_response = smu_msg_v1_decode_response,
565 	.send_debug_msg = smu_msg_v1_send_debug_msg,
566 };
567 
smu_msg_wait_response(struct smu_msg_ctl * ctl,u32 timeout_us)568 int smu_msg_wait_response(struct smu_msg_ctl *ctl, u32 timeout_us)
569 {
570 	return ctl->ops->wait_response(ctl, timeout_us);
571 }
572 
573 /**
574  * smu_msg_send_async_locked - Send message asynchronously, caller holds lock
575  * @ctl: Message control block
576  * @msg: Message type
577  * @param: Message parameter
578  *
579  * Send an SMU message without waiting for response. Caller must hold ctl->lock
580  * and call smu_msg_wait_response() later to get the result.
581  *
582  * Return: 0 on success, negative errno on failure
583  */
smu_msg_send_async_locked(struct smu_msg_ctl * ctl,enum smu_message_type msg,u32 param)584 int smu_msg_send_async_locked(struct smu_msg_ctl *ctl,
585 			      enum smu_message_type msg, u32 param)
586 {
587 	struct smu_msg_args args = {
588 		.msg = msg,
589 		.args[0] = param,
590 		.num_args = 1,
591 		.num_out_args = 0,
592 		.flags = SMU_MSG_FLAG_ASYNC | SMU_MSG_FLAG_LOCK_HELD,
593 		.timeout = 0,
594 	};
595 
596 	return ctl->ops->send_msg(ctl, &args);
597 }
598 
smu_cmn_to_asic_specific_index(struct smu_context * smu,enum smu_cmn2asic_mapping_type type,uint32_t index)599 int smu_cmn_to_asic_specific_index(struct smu_context *smu,
600 				   enum smu_cmn2asic_mapping_type type,
601 				   uint32_t index)
602 {
603 	struct cmn2asic_msg_mapping msg_mapping;
604 	struct cmn2asic_mapping mapping;
605 
606 	switch (type) {
607 	case CMN2ASIC_MAPPING_MSG:
608 		if (index >= SMU_MSG_MAX_COUNT ||
609 		    !smu->msg_ctl.message_map)
610 			return -EINVAL;
611 
612 		msg_mapping = smu->msg_ctl.message_map[index];
613 		if (!msg_mapping.valid_mapping)
614 			return -EINVAL;
615 
616 		if (amdgpu_sriov_vf(smu->adev) &&
617 		    !(msg_mapping.flags & SMU_MSG_VF_FLAG))
618 			return -EACCES;
619 
620 		return msg_mapping.map_to;
621 
622 	case CMN2ASIC_MAPPING_CLK:
623 		if (index >= SMU_CLK_COUNT ||
624 		    !smu->clock_map)
625 			return -EINVAL;
626 
627 		mapping = smu->clock_map[index];
628 		if (!mapping.valid_mapping)
629 			return -EINVAL;
630 
631 		return mapping.map_to;
632 
633 	case CMN2ASIC_MAPPING_FEATURE:
634 		if (index >= SMU_FEATURE_COUNT ||
635 		    !smu->feature_map)
636 			return -EINVAL;
637 
638 		mapping = smu->feature_map[index];
639 		if (!mapping.valid_mapping)
640 			return -EINVAL;
641 
642 		return mapping.map_to;
643 
644 	case CMN2ASIC_MAPPING_TABLE:
645 		if (index >= SMU_TABLE_COUNT ||
646 		    !smu->table_map)
647 			return -EINVAL;
648 
649 		mapping = smu->table_map[index];
650 		if (!mapping.valid_mapping)
651 			return -EINVAL;
652 
653 		return mapping.map_to;
654 
655 	case CMN2ASIC_MAPPING_PWR:
656 		if (index >= SMU_POWER_SOURCE_COUNT ||
657 		    !smu->pwr_src_map)
658 			return -EINVAL;
659 
660 		mapping = smu->pwr_src_map[index];
661 		if (!mapping.valid_mapping)
662 			return -EINVAL;
663 
664 		return mapping.map_to;
665 
666 	case CMN2ASIC_MAPPING_WORKLOAD:
667 		if (index >= PP_SMC_POWER_PROFILE_COUNT ||
668 		    !smu->workload_map)
669 			return -EINVAL;
670 
671 		mapping = smu->workload_map[index];
672 		if (!mapping.valid_mapping)
673 			return -ENOTSUPP;
674 
675 		return mapping.map_to;
676 
677 	default:
678 		return -EINVAL;
679 	}
680 }
681 
smu_cmn_feature_is_supported(struct smu_context * smu,enum smu_feature_mask mask)682 int smu_cmn_feature_is_supported(struct smu_context *smu,
683 				 enum smu_feature_mask mask)
684 {
685 	int feature_id;
686 
687 	feature_id = smu_cmn_to_asic_specific_index(smu,
688 						    CMN2ASIC_MAPPING_FEATURE,
689 						    mask);
690 	if (feature_id < 0)
691 		return 0;
692 
693 	return smu_feature_list_is_set(smu, SMU_FEATURE_LIST_SUPPORTED,
694 				       feature_id);
695 }
696 
__smu_get_enabled_features(struct smu_context * smu,struct smu_feature_bits * enabled_features)697 static int __smu_get_enabled_features(struct smu_context *smu,
698 				      struct smu_feature_bits *enabled_features)
699 {
700 	return smu_cmn_call_asic_func(get_enabled_mask, smu, enabled_features);
701 }
702 
smu_cmn_feature_is_enabled(struct smu_context * smu,enum smu_feature_mask mask)703 int smu_cmn_feature_is_enabled(struct smu_context *smu,
704 			       enum smu_feature_mask mask)
705 {
706 	struct amdgpu_device *adev = smu->adev;
707 	struct smu_feature_bits enabled_features;
708 	int feature_id;
709 
710 	if (__smu_get_enabled_features(smu, &enabled_features)) {
711 		dev_err(adev->dev, "Failed to retrieve enabled ppfeatures!\n");
712 		return 0;
713 	}
714 
715 	/*
716 	 * For Renoir and Cyan Skillfish, they are assumed to have all features
717 	 * enabled. Also considering they have no feature_map available, the
718 	 * check here can avoid unwanted feature_map check below.
719 	 */
720 	if (smu_feature_bits_full(&enabled_features,
721 				  smu->smu_feature.feature_num))
722 		return 1;
723 
724 	feature_id = smu_cmn_to_asic_specific_index(smu,
725 						    CMN2ASIC_MAPPING_FEATURE,
726 						    mask);
727 	if (feature_id < 0)
728 		return 0;
729 
730 	return smu_feature_bits_is_set(&enabled_features, feature_id);
731 }
732 
smu_cmn_clk_dpm_is_enabled(struct smu_context * smu,enum smu_clk_type clk_type)733 bool smu_cmn_clk_dpm_is_enabled(struct smu_context *smu,
734 				enum smu_clk_type clk_type)
735 {
736 	enum smu_feature_mask feature_id = 0;
737 
738 	switch (clk_type) {
739 	case SMU_MCLK:
740 	case SMU_UCLK:
741 		feature_id = SMU_FEATURE_DPM_UCLK_BIT;
742 		break;
743 	case SMU_GFXCLK:
744 	case SMU_SCLK:
745 		feature_id = SMU_FEATURE_DPM_GFXCLK_BIT;
746 		break;
747 	case SMU_SOCCLK:
748 		feature_id = SMU_FEATURE_DPM_SOCCLK_BIT;
749 		break;
750 	case SMU_VCLK:
751 	case SMU_VCLK1:
752 		feature_id = SMU_FEATURE_DPM_VCLK_BIT;
753 		break;
754 	case SMU_DCLK:
755 	case SMU_DCLK1:
756 		feature_id = SMU_FEATURE_DPM_DCLK_BIT;
757 		break;
758 	case SMU_FCLK:
759 		feature_id = SMU_FEATURE_DPM_FCLK_BIT;
760 		break;
761 	default:
762 		return true;
763 	}
764 
765 	if (!smu_cmn_feature_is_enabled(smu, feature_id))
766 		return false;
767 
768 	return true;
769 }
770 
smu_cmn_get_enabled_mask(struct smu_context * smu,struct smu_feature_bits * feature_mask)771 int smu_cmn_get_enabled_mask(struct smu_context *smu,
772 			     struct smu_feature_bits *feature_mask)
773 {
774 	uint32_t features[2];
775 	int ret = 0, index = 0;
776 
777 	if (!feature_mask)
778 		return -EINVAL;
779 
780 	index = smu_cmn_to_asic_specific_index(smu,
781 						CMN2ASIC_MAPPING_MSG,
782 						SMU_MSG_GetEnabledSmuFeatures);
783 	if (index > 0) {
784 		ret = smu_cmn_send_smc_msg_with_param(
785 			smu, SMU_MSG_GetEnabledSmuFeatures, 0, &features[0]);
786 		if (ret)
787 			return ret;
788 
789 		ret = smu_cmn_send_smc_msg_with_param(
790 			smu, SMU_MSG_GetEnabledSmuFeatures, 1, &features[1]);
791 	} else {
792 		ret = smu_cmn_send_smc_msg(
793 			smu, SMU_MSG_GetEnabledSmuFeaturesHigh, &features[1]);
794 		if (ret)
795 			return ret;
796 
797 		ret = smu_cmn_send_smc_msg(
798 			smu, SMU_MSG_GetEnabledSmuFeaturesLow, &features[0]);
799 	}
800 
801 	if (!ret)
802 		smu_feature_bits_from_arr32(feature_mask, features,
803 					    SMU_FEATURE_NUM_DEFAULT);
804 
805 	return ret;
806 }
807 
smu_cmn_get_indep_throttler_status(const unsigned long dep_status,const uint8_t * throttler_map)808 uint64_t smu_cmn_get_indep_throttler_status(
809 					const unsigned long dep_status,
810 					const uint8_t *throttler_map)
811 {
812 	uint64_t indep_status = 0;
813 	uint8_t dep_bit = 0;
814 
815 	for_each_set_bit(dep_bit, &dep_status, 32)
816 		indep_status |= 1ULL << throttler_map[dep_bit];
817 
818 	return indep_status;
819 }
820 
smu_cmn_feature_update_enable_state(struct smu_context * smu,uint64_t feature_mask,bool enabled)821 int smu_cmn_feature_update_enable_state(struct smu_context *smu,
822 					uint64_t feature_mask,
823 					bool enabled)
824 {
825 	int ret = 0;
826 
827 	if (enabled) {
828 		ret = smu_cmn_send_smc_msg_with_param(smu,
829 						  SMU_MSG_EnableSmuFeaturesLow,
830 						  lower_32_bits(feature_mask),
831 						  NULL);
832 		if (ret)
833 			return ret;
834 		ret = smu_cmn_send_smc_msg_with_param(smu,
835 						  SMU_MSG_EnableSmuFeaturesHigh,
836 						  upper_32_bits(feature_mask),
837 						  NULL);
838 	} else {
839 		ret = smu_cmn_send_smc_msg_with_param(smu,
840 						  SMU_MSG_DisableSmuFeaturesLow,
841 						  lower_32_bits(feature_mask),
842 						  NULL);
843 		if (ret)
844 			return ret;
845 		ret = smu_cmn_send_smc_msg_with_param(smu,
846 						  SMU_MSG_DisableSmuFeaturesHigh,
847 						  upper_32_bits(feature_mask),
848 						  NULL);
849 	}
850 
851 	return ret;
852 }
853 
smu_cmn_feature_set_enabled(struct smu_context * smu,enum smu_feature_mask mask,bool enable)854 int smu_cmn_feature_set_enabled(struct smu_context *smu,
855 				enum smu_feature_mask mask,
856 				bool enable)
857 {
858 	int feature_id;
859 
860 	feature_id = smu_cmn_to_asic_specific_index(smu,
861 						    CMN2ASIC_MAPPING_FEATURE,
862 						    mask);
863 	if (feature_id < 0)
864 		return -EINVAL;
865 
866 	return smu_cmn_feature_update_enable_state(smu,
867 					       1ULL << feature_id,
868 					       enable);
869 }
870 
871 #undef __SMU_DUMMY_MAP
872 #define __SMU_DUMMY_MAP(fea)	#fea
873 static const char *__smu_feature_names[] = {
874 	SMU_FEATURE_MASKS
875 };
876 
smu_get_feature_name(struct smu_context * smu,enum smu_feature_mask feature)877 static const char *smu_get_feature_name(struct smu_context *smu,
878 					enum smu_feature_mask feature)
879 {
880 	if (feature >= SMU_FEATURE_COUNT)
881 		return "unknown smu feature";
882 	return __smu_feature_names[feature];
883 }
884 
smu_cmn_get_pp_feature_mask(struct smu_context * smu,char * buf)885 size_t smu_cmn_get_pp_feature_mask(struct smu_context *smu,
886 				   char *buf)
887 {
888 	int16_t sort_feature[MAX(SMU_FEATURE_COUNT, SMU_FEATURE_MAX)];
889 	struct smu_feature_bits feature_mask;
890 	uint32_t features[2];
891 	int i, feature_index;
892 	uint32_t count = 0;
893 	size_t size = 0;
894 
895 	if (__smu_get_enabled_features(smu, &feature_mask))
896 		return 0;
897 
898 	/* TBD: Need to handle for > 64 bits */
899 	smu_feature_bits_to_arr32(&feature_mask, features, 64);
900 	size = sysfs_emit_at(buf, size, "features high: 0x%08x low: 0x%08x\n",
901 			     features[1], features[0]);
902 
903 	memset(sort_feature, -1, sizeof(sort_feature));
904 
905 	for (i = 0; i < SMU_FEATURE_COUNT; i++) {
906 		feature_index = smu_cmn_to_asic_specific_index(smu,
907 							       CMN2ASIC_MAPPING_FEATURE,
908 							       i);
909 		if (feature_index < 0)
910 			continue;
911 
912 		sort_feature[feature_index] = i;
913 	}
914 
915 	size += sysfs_emit_at(buf, size, "%-2s. %-20s  %-3s : %-s\n",
916 			"No", "Feature", "Bit", "State");
917 
918 	for (feature_index = 0; feature_index < smu->smu_feature.feature_num;
919 	     feature_index++) {
920 		if (sort_feature[feature_index] < 0)
921 			continue;
922 
923 		size += sysfs_emit_at(
924 			buf, size, "%02d. %-20s (%2d) : %s\n", count++,
925 			smu_get_feature_name(smu, sort_feature[feature_index]),
926 			feature_index,
927 			smu_feature_bits_is_set(&feature_mask, feature_index) ?
928 				"enabled" :
929 				"disabled");
930 	}
931 
932 	return size;
933 }
934 
smu_cmn_set_pp_feature_mask(struct smu_context * smu,uint64_t new_mask)935 int smu_cmn_set_pp_feature_mask(struct smu_context *smu,
936 				uint64_t new_mask)
937 {
938 	int ret = 0;
939 	struct smu_feature_bits feature_mask;
940 	uint64_t feature_mask_u64;
941 	uint64_t feature_2_enabled = 0;
942 	uint64_t feature_2_disabled = 0;
943 
944 	ret = __smu_get_enabled_features(smu, &feature_mask);
945 	if (ret)
946 		return ret;
947 
948 	feature_mask_u64 = *(uint64_t *)feature_mask.bits;
949 	feature_2_enabled = ~feature_mask_u64 & new_mask;
950 	feature_2_disabled = feature_mask_u64 & ~new_mask;
951 
952 	if (feature_2_enabled) {
953 		ret = smu_cmn_feature_update_enable_state(smu,
954 							  feature_2_enabled,
955 							  true);
956 		if (ret)
957 			return ret;
958 	}
959 	if (feature_2_disabled) {
960 		ret = smu_cmn_feature_update_enable_state(smu,
961 							  feature_2_disabled,
962 							  false);
963 		if (ret)
964 			return ret;
965 	}
966 
967 	return ret;
968 }
969 
970 /**
971  * smu_cmn_disable_all_features_with_exception - disable all dpm features
972  *                                               except this specified by
973  *                                               @mask
974  *
975  * @smu:               smu_context pointer
976  * @mask:              the dpm feature which should not be disabled
977  *                     SMU_FEATURE_COUNT: no exception, all dpm features
978  *                     to disable
979  *
980  * Returns:
981  * 0 on success or a negative error code on failure.
982  */
smu_cmn_disable_all_features_with_exception(struct smu_context * smu,enum smu_feature_mask mask)983 int smu_cmn_disable_all_features_with_exception(struct smu_context *smu,
984 						enum smu_feature_mask mask)
985 {
986 	uint64_t features_to_disable = U64_MAX;
987 	int skipped_feature_id;
988 
989 	if (mask != SMU_FEATURE_COUNT) {
990 		skipped_feature_id = smu_cmn_to_asic_specific_index(smu,
991 								    CMN2ASIC_MAPPING_FEATURE,
992 								    mask);
993 		if (skipped_feature_id < 0)
994 			return -EINVAL;
995 
996 		features_to_disable &= ~(1ULL << skipped_feature_id);
997 	}
998 
999 	return smu_cmn_feature_update_enable_state(smu,
1000 						   features_to_disable,
1001 						   0);
1002 }
1003 
smu_cmn_get_smc_version(struct smu_context * smu,uint32_t * if_version,uint32_t * smu_version)1004 int smu_cmn_get_smc_version(struct smu_context *smu,
1005 			    uint32_t *if_version,
1006 			    uint32_t *smu_version)
1007 {
1008 	int ret = 0;
1009 
1010 	if (!if_version && !smu_version)
1011 		return -EINVAL;
1012 
1013 	if (smu->smc_fw_if_version && smu->smc_fw_version)
1014 	{
1015 		if (if_version)
1016 			*if_version = smu->smc_fw_if_version;
1017 
1018 		if (smu_version)
1019 			*smu_version = smu->smc_fw_version;
1020 
1021 		return 0;
1022 	}
1023 
1024 	if (if_version) {
1025 		ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetDriverIfVersion, if_version);
1026 		if (ret)
1027 			return ret;
1028 
1029 		smu->smc_fw_if_version = *if_version;
1030 	}
1031 
1032 	if (smu_version) {
1033 		ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetSmuVersion, smu_version);
1034 		if (ret)
1035 			return ret;
1036 
1037 		smu->smc_fw_version = *smu_version;
1038 	}
1039 
1040 	return ret;
1041 }
1042 
smu_cmn_check_fw_version(struct smu_context * smu)1043 int smu_cmn_check_fw_version(struct smu_context *smu)
1044 {
1045 	struct amdgpu_device *adev = smu->adev;
1046 	uint32_t if_version = 0xff, smu_version = 0xff;
1047 	uint8_t smu_program, smu_major, smu_minor, smu_debug;
1048 	int ret;
1049 
1050 	ret = smu_cmn_get_smc_version(smu, &if_version, &smu_version);
1051 	if (ret)
1052 		return ret;
1053 
1054 	smu_program = (smu_version >> 24) & 0xff;
1055 	smu_major = (smu_version >> 16) & 0xff;
1056 	smu_minor = (smu_version >> 8) & 0xff;
1057 	smu_debug = (smu_version >> 0) & 0xff;
1058 	adev->pm.fw_version = smu_version;
1059 
1060 	dev_info_once(adev->dev, "smu driver if version = 0x%08x, smu fw if version = 0x%08x, "
1061 		      "smu fw program = %d, smu fw version = 0x%08x (%d.%d.%d)\n",
1062 		      smu->smc_driver_if_version, if_version,
1063 		      smu_program, smu_version, smu_major, smu_minor, smu_debug);
1064 
1065 	return 0;
1066 }
1067 
smu_cmn_update_table_read_arg(struct smu_context * smu,enum smu_table_id table_index,int argument,void * table_data,uint32_t * read_arg,bool drv2smu)1068 int smu_cmn_update_table_read_arg(struct smu_context *smu,
1069 				    enum smu_table_id table_index,
1070 				    int argument,
1071 				    void *table_data,
1072 				    uint32_t *read_arg,
1073 				    bool drv2smu)
1074 {
1075 	struct amdgpu_device *adev = smu->adev;
1076 	struct smu_table_context *smu_table = &smu->smu_table;
1077 	struct smu_table *table = &smu_table->driver_table;
1078 	struct smu_msg_ctl *ctl = &smu->msg_ctl;
1079 	struct smu_msg_args args;
1080 	int table_id = smu_cmn_to_asic_specific_index(smu,
1081 						      CMN2ASIC_MAPPING_TABLE,
1082 						      table_index);
1083 	uint32_t table_size;
1084 	int ret = 0;
1085 
1086 	if (!table_data || table_index >= SMU_TABLE_COUNT || table_id < 0)
1087 		return -EINVAL;
1088 
1089 	table_size = smu_table->tables[table_index].size;
1090 
1091 	if (drv2smu) {
1092 		memcpy(table->cpu_addr, table_data, table_size);
1093 		/*
1094 		 * Flush hdp cache: to guard the content seen by
1095 		 * GPU is consitent with CPU.
1096 		 */
1097 		amdgpu_hdp_flush(adev, NULL);
1098 	}
1099 
1100 	args.msg = drv2smu ? SMU_MSG_TransferTableDram2Smu : SMU_MSG_TransferTableSmu2Dram;
1101 	args.args[0] = ((argument & 0xFFFF) << 16) | (table_id  & 0xffff);
1102 	args.num_args = 1;
1103 	args.out_args[0] = 0;
1104 	args.num_out_args = read_arg ? 1 : 0;
1105 	args.flags = read_arg ? SMU_MSG_FLAG_FORCE_READ_ARG : 0;
1106 	args.timeout = 0;
1107 
1108 	ret = ctl->ops->send_msg(ctl, &args);
1109 
1110 	if (read_arg)
1111 		*read_arg = args.out_args[0];
1112 
1113 	if (ret)
1114 		return ret;
1115 
1116 	if (!drv2smu) {
1117 		amdgpu_hdp_invalidate(adev, NULL);
1118 		memcpy(table_data, table->cpu_addr, table_size);
1119 	}
1120 
1121 	return 0;
1122 }
1123 
smu_cmn_vram_cpy(struct smu_context * smu,void * dst,const void * src,size_t len)1124 int smu_cmn_vram_cpy(struct smu_context *smu, void *dst, const void *src,
1125 		     size_t len)
1126 {
1127 	memcpy(dst, src, len);
1128 
1129 	/* Don't trust the copy operation if RAS fatal error happened. */
1130 	if (amdgpu_ras_get_fed_status(smu->adev))
1131 		return -EHWPOISON;
1132 
1133 	return 0;
1134 }
1135 
smu_cmn_write_watermarks_table(struct smu_context * smu)1136 int smu_cmn_write_watermarks_table(struct smu_context *smu)
1137 {
1138 	void *watermarks_table = smu->smu_table.watermarks_table;
1139 
1140 	if (!watermarks_table)
1141 		return -EINVAL;
1142 
1143 	return smu_cmn_update_table(smu,
1144 				    SMU_TABLE_WATERMARKS,
1145 				    0,
1146 				    watermarks_table,
1147 				    true);
1148 }
1149 
smu_cmn_write_pptable(struct smu_context * smu)1150 int smu_cmn_write_pptable(struct smu_context *smu)
1151 {
1152 	void *pptable = smu->smu_table.driver_pptable;
1153 
1154 	return smu_cmn_update_table(smu,
1155 				    SMU_TABLE_PPTABLE,
1156 				    0,
1157 				    pptable,
1158 				    true);
1159 }
1160 
smu_cmn_get_metrics_table(struct smu_context * smu,void * metrics_table,bool bypass_cache)1161 int smu_cmn_get_metrics_table(struct smu_context *smu,
1162 			      void *metrics_table,
1163 			      bool bypass_cache)
1164 {
1165 	struct smu_table_context *smu_table = &smu->smu_table;
1166 	uint32_t table_size =
1167 		smu_table->tables[SMU_TABLE_SMU_METRICS].size;
1168 	int ret = 0;
1169 
1170 	if (bypass_cache ||
1171 	    !smu_table->metrics_time ||
1172 	    time_after(jiffies, smu_table->metrics_time + msecs_to_jiffies(1))) {
1173 		ret = smu_cmn_update_table(smu,
1174 				       SMU_TABLE_SMU_METRICS,
1175 				       0,
1176 				       smu_table->metrics_table,
1177 				       false);
1178 		if (ret) {
1179 			dev_info(smu->adev->dev, "Failed to export SMU metrics table!\n");
1180 			return ret;
1181 		}
1182 		smu_table->metrics_time = jiffies;
1183 	}
1184 
1185 	if (metrics_table)
1186 		memcpy(metrics_table, smu_table->metrics_table, table_size);
1187 
1188 	return 0;
1189 }
1190 
smu_cmn_get_combo_pptable(struct smu_context * smu)1191 int smu_cmn_get_combo_pptable(struct smu_context *smu)
1192 {
1193 	void *pptable = smu->smu_table.combo_pptable;
1194 
1195 	return smu_cmn_update_table(smu,
1196 				    SMU_TABLE_COMBO_PPTABLE,
1197 				    0,
1198 				    pptable,
1199 				    false);
1200 }
1201 
smu_cmn_set_mp1_state(struct smu_context * smu,enum pp_mp1_state mp1_state)1202 int smu_cmn_set_mp1_state(struct smu_context *smu,
1203 			  enum pp_mp1_state mp1_state)
1204 {
1205 	enum smu_message_type msg;
1206 	int ret;
1207 
1208 	switch (mp1_state) {
1209 	case PP_MP1_STATE_SHUTDOWN:
1210 		msg = SMU_MSG_PrepareMp1ForShutdown;
1211 		break;
1212 	case PP_MP1_STATE_UNLOAD:
1213 		msg = SMU_MSG_PrepareMp1ForUnload;
1214 		break;
1215 	case PP_MP1_STATE_RESET:
1216 		msg = SMU_MSG_PrepareMp1ForReset;
1217 		break;
1218 	case PP_MP1_STATE_NONE:
1219 	default:
1220 		return 0;
1221 	}
1222 
1223 	ret = smu_cmn_send_smc_msg(smu, msg, NULL);
1224 	if (ret)
1225 		dev_err(smu->adev->dev, "[PrepareMp1] Failed!\n");
1226 
1227 	return ret;
1228 }
1229 
smu_cmn_is_audio_func_enabled(struct amdgpu_device * adev)1230 bool smu_cmn_is_audio_func_enabled(struct amdgpu_device *adev)
1231 {
1232 	struct pci_dev *p = NULL;
1233 	bool snd_driver_loaded;
1234 
1235 	/*
1236 	 * If the ASIC comes with no audio function, we always assume
1237 	 * it is "enabled".
1238 	 */
1239 	p = pci_get_domain_bus_and_slot(pci_domain_nr(adev->pdev->bus),
1240 			adev->pdev->bus->number, 1);
1241 	if (!p)
1242 		return true;
1243 
1244 	snd_driver_loaded = pci_is_enabled(p) ? true : false;
1245 
1246 	pci_dev_put(p);
1247 
1248 	return snd_driver_loaded;
1249 }
1250 
smu_soc_policy_get_desc(struct smu_dpm_policy * policy,int level)1251 static char *smu_soc_policy_get_desc(struct smu_dpm_policy *policy, int level)
1252 {
1253 	if (level < 0 || !(policy->level_mask & BIT(level)))
1254 		return "Invalid";
1255 
1256 	switch (level) {
1257 	case SOC_PSTATE_DEFAULT:
1258 		return "soc_pstate_default";
1259 	case SOC_PSTATE_0:
1260 		return "soc_pstate_0";
1261 	case SOC_PSTATE_1:
1262 		return "soc_pstate_1";
1263 	case SOC_PSTATE_2:
1264 		return "soc_pstate_2";
1265 	}
1266 
1267 	return "Invalid";
1268 }
1269 
1270 static struct smu_dpm_policy_desc pstate_policy_desc = {
1271 	.name = STR_SOC_PSTATE_POLICY,
1272 	.get_desc = smu_soc_policy_get_desc,
1273 };
1274 
smu_cmn_generic_soc_policy_desc(struct smu_dpm_policy * policy)1275 void smu_cmn_generic_soc_policy_desc(struct smu_dpm_policy *policy)
1276 {
1277 	policy->desc = &pstate_policy_desc;
1278 }
1279 
smu_xgmi_plpd_policy_get_desc(struct smu_dpm_policy * policy,int level)1280 static char *smu_xgmi_plpd_policy_get_desc(struct smu_dpm_policy *policy,
1281 					   int level)
1282 {
1283 	if (level < 0 || !(policy->level_mask & BIT(level)))
1284 		return "Invalid";
1285 
1286 	switch (level) {
1287 	case XGMI_PLPD_DISALLOW:
1288 		return "plpd_disallow";
1289 	case XGMI_PLPD_DEFAULT:
1290 		return "plpd_default";
1291 	case XGMI_PLPD_OPTIMIZED:
1292 		return "plpd_optimized";
1293 	}
1294 
1295 	return "Invalid";
1296 }
1297 
1298 static struct smu_dpm_policy_desc xgmi_plpd_policy_desc = {
1299 	.name = STR_XGMI_PLPD_POLICY,
1300 	.get_desc = smu_xgmi_plpd_policy_get_desc,
1301 };
1302 
smu_cmn_generic_plpd_policy_desc(struct smu_dpm_policy * policy)1303 void smu_cmn_generic_plpd_policy_desc(struct smu_dpm_policy *policy)
1304 {
1305 	policy->desc = &xgmi_plpd_policy_desc;
1306 }
1307 
smu_cmn_get_backend_workload_mask(struct smu_context * smu,u32 workload_mask,u32 * backend_workload_mask)1308 void smu_cmn_get_backend_workload_mask(struct smu_context *smu,
1309 				       u32 workload_mask,
1310 				       u32 *backend_workload_mask)
1311 {
1312 	int workload_type;
1313 	u32 profile_mode;
1314 
1315 	*backend_workload_mask = 0;
1316 
1317 	for (profile_mode = 0; profile_mode < PP_SMC_POWER_PROFILE_COUNT; profile_mode++) {
1318 		if (!(workload_mask & (1 << profile_mode)))
1319 			continue;
1320 
1321 		/* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
1322 		workload_type = smu_cmn_to_asic_specific_index(smu,
1323 							       CMN2ASIC_MAPPING_WORKLOAD,
1324 							       profile_mode);
1325 
1326 		if (workload_type < 0)
1327 			continue;
1328 
1329 		*backend_workload_mask |= 1 << workload_type;
1330 	}
1331 }
1332 
smu_cmn_reset_custom_level(struct smu_context * smu)1333 void smu_cmn_reset_custom_level(struct smu_context *smu)
1334 {
1335 	struct smu_umd_pstate_table *pstate_table = &smu->pstate_table;
1336 
1337 	pstate_table->gfxclk_pstate.custom.min = 0;
1338 	pstate_table->gfxclk_pstate.custom.max = 0;
1339 	pstate_table->uclk_pstate.custom.min = 0;
1340 	pstate_table->uclk_pstate.custom.max = 0;
1341 }
1342 
smu_cmn_freqs_match(uint32_t freq1,uint32_t freq2)1343 static inline bool smu_cmn_freqs_match(uint32_t freq1, uint32_t freq2)
1344 {
1345 	/* Frequencies within 25 MHz are considered equal */
1346 	return (abs((int)freq1 - (int)freq2) <= 25);
1347 }
1348 
smu_cmn_print_dpm_clk_levels(struct smu_context * smu,struct smu_dpm_table * dpm_table,uint32_t cur_clk,char * buf,int * offset)1349 int smu_cmn_print_dpm_clk_levels(struct smu_context *smu,
1350 				 struct smu_dpm_table *dpm_table,
1351 				 uint32_t cur_clk, char *buf, int *offset)
1352 {
1353 	uint32_t min_clk, max_clk, level_index, count;
1354 	uint32_t freq_values[3];
1355 	int size, lvl, i;
1356 	bool is_fine_grained;
1357 	bool is_deep_sleep;
1358 	bool freq_match;
1359 
1360 	if (!dpm_table || !buf)
1361 		return -EINVAL;
1362 
1363 	level_index = 0;
1364 	size = *offset;
1365 	count = dpm_table->count;
1366 	is_fine_grained = dpm_table->flags & SMU_DPM_TABLE_FINE_GRAINED;
1367 	min_clk = SMU_DPM_TABLE_MIN(dpm_table);
1368 	max_clk = SMU_DPM_TABLE_MAX(dpm_table);
1369 
1370 	/* Deep sleep - current clock < min_clock/2, TBD: cur_clk = 0 as GFXOFF */
1371 	is_deep_sleep = cur_clk < min_clk / 2;
1372 	if (is_deep_sleep) {
1373 		size += sysfs_emit_at(buf, size, "S: %uMhz *\n", cur_clk);
1374 		level_index = 1;
1375 	}
1376 
1377 	if (!is_fine_grained || count == 1) {
1378 		for (i = 0; i < count; i++) {
1379 			freq_match = !is_deep_sleep &&
1380 				     smu_cmn_freqs_match(
1381 					     cur_clk,
1382 					     dpm_table->dpm_levels[i].value);
1383 			size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n",
1384 					      level_index + i,
1385 					      dpm_table->dpm_levels[i].value,
1386 					      freq_match ? "*" : "");
1387 		}
1388 	} else {
1389 		count = 2;
1390 		freq_values[0] = min_clk;
1391 		freq_values[1] = max_clk;
1392 
1393 		if (!is_deep_sleep) {
1394 			if (smu_cmn_freqs_match(cur_clk, min_clk)) {
1395 				lvl = 0;
1396 			} else if (smu_cmn_freqs_match(cur_clk, max_clk)) {
1397 				lvl = 1;
1398 			} else {
1399 				/* NOTE: use index '1' to show current clock value */
1400 				lvl = 1;
1401 				count = 3;
1402 				freq_values[1] = cur_clk;
1403 				freq_values[2] = max_clk;
1404 			}
1405 		}
1406 
1407 		for (i = 0; i < count; i++) {
1408 			size += sysfs_emit_at(
1409 				buf, size, "%d: %uMhz %s\n", level_index + i,
1410 				freq_values[i],
1411 				(!is_deep_sleep && i == lvl) ? "*" : "");
1412 		}
1413 	}
1414 
1415 	*offset = size;
1416 
1417 	return 0;
1418 }
1419 
smu_cmn_print_pcie_levels(struct smu_context * smu,struct smu_pcie_table * pcie_table,uint32_t cur_gen,uint32_t cur_lane,char * buf,int * offset)1420 int smu_cmn_print_pcie_levels(struct smu_context *smu,
1421 			      struct smu_pcie_table *pcie_table,
1422 			      uint32_t cur_gen, uint32_t cur_lane, char *buf,
1423 			      int *offset)
1424 {
1425 	int size, i;
1426 
1427 	if (!pcie_table || !buf)
1428 		return -EINVAL;
1429 
1430 	size = *offset;
1431 
1432 	for (i = 0; i < pcie_table->lclk_levels; i++) {
1433 		size += sysfs_emit_at(
1434 			buf, size, "%d: %s %s %dMhz %s\n", i,
1435 			(pcie_table->pcie_gen[i] == 0) ? "2.5GT/s," :
1436 			(pcie_table->pcie_gen[i] == 1) ? "5.0GT/s," :
1437 			(pcie_table->pcie_gen[i] == 2) ? "8.0GT/s," :
1438 			(pcie_table->pcie_gen[i] == 3) ? "16.0GT/s," :
1439 			(pcie_table->pcie_gen[i] == 4) ? "32.0GT/s," :
1440 			(pcie_table->pcie_gen[i] == 5) ? "64.0GT/s," :
1441 							 "",
1442 			(pcie_table->pcie_lane[i] == 1) ? "x1" :
1443 			(pcie_table->pcie_lane[i] == 2) ? "x2" :
1444 			(pcie_table->pcie_lane[i] == 3) ? "x4" :
1445 			(pcie_table->pcie_lane[i] == 4) ? "x8" :
1446 			(pcie_table->pcie_lane[i] == 5) ? "x12" :
1447 			(pcie_table->pcie_lane[i] == 6) ? "x16" :
1448 			(pcie_table->pcie_lane[i] == 7) ? "x32" :
1449 							  "",
1450 			pcie_table->lclk_freq[i],
1451 			(cur_gen == pcie_table->pcie_gen[i]) &&
1452 					(cur_lane == pcie_table->pcie_lane[i]) ?
1453 				"*" :
1454 				"");
1455 	}
1456 
1457 	*offset = size;
1458 
1459 	return 0;
1460 }
1461 
smu_cmn_dpm_pcie_gen_idx(int gen)1462 int smu_cmn_dpm_pcie_gen_idx(int gen)
1463 {
1464 	int ret;
1465 
1466 	switch (gen) {
1467 	case 1 ... 5:
1468 		ret = gen - 1;
1469 		break;
1470 	default:
1471 		ret = -1;
1472 		break;
1473 	}
1474 
1475 	return ret;
1476 }
1477 
smu_cmn_dpm_pcie_width_idx(int width)1478 int smu_cmn_dpm_pcie_width_idx(int width)
1479 {
1480 	int ret;
1481 
1482 	switch (width) {
1483 	case 1:
1484 		ret = 1;
1485 		break;
1486 	case 2:
1487 		ret = 2;
1488 		break;
1489 	case 4:
1490 		ret = 3;
1491 		break;
1492 	case 8:
1493 		ret = 4;
1494 		break;
1495 	case 12:
1496 		ret = 5;
1497 		break;
1498 	case 16:
1499 		ret = 6;
1500 		break;
1501 	case 32:
1502 		ret = 7;
1503 		break;
1504 	default:
1505 		ret = -1;
1506 		break;
1507 	}
1508 
1509 	return ret;
1510 }
1511