File Index
Files and directories
Sign in
FILE

smu_v14_0.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c C
   1/*
   2 * Copyright 2023 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#include <linux/firmware.h>
  24#include <linux/module.h>
  25#include <linux/pci.h>
  26#include <linux/reboot.h>
  27
  28#define SWSMU_CODE_LAYER_L3
  29
  30#include "amdgpu.h"
  31#include "amdgpu_smu.h"
  32#include "atomfirmware.h"
  33#include "amdgpu_atomfirmware.h"
  34#include "amdgpu_atombios.h"
  35#include "smu_v14_0.h"
  36#include "soc15_common.h"
  37#include "atom.h"
  38#include "amdgpu_ras.h"
  39#include "smu_cmn.h"
  40
  41#include "asic_reg/thm/thm_14_0_2_offset.h"
  42#include "asic_reg/thm/thm_14_0_2_sh_mask.h"
  43#include "asic_reg/mp/mp_14_0_2_offset.h"
  44#include "asic_reg/mp/mp_14_0_2_sh_mask.h"
  45
  46#define regMP1_SMN_IH_SW_INT_mp1_14_0_0			0x0341
  47#define regMP1_SMN_IH_SW_INT_mp1_14_0_0_BASE_IDX        0
  48#define regMP1_SMN_IH_SW_INT_CTRL_mp1_14_0_0            0x0342
  49#define regMP1_SMN_IH_SW_INT_CTRL_mp1_14_0_0_BASE_IDX   0
  50
  51const int decoded_link_speed[5] = {1, 2, 3, 4, 5};
  52const int decoded_link_width[8] = {0, 1, 2, 4, 8, 12, 16, 32};
  53/*
  54 * DO NOT use these for err/warn/info/debug messages.
  55 * Use dev_err, dev_warn, dev_info and dev_dbg instead.
  56 * They are more MGPU friendly.
  57 */
  58#undef pr_err
  59#undef pr_warn
  60#undef pr_info
  61#undef pr_debug
  62
  63MODULE_FIRMWARE("amdgpu/smu_14_0_2.bin");
  64MODULE_FIRMWARE("amdgpu/smu_14_0_3.bin");
  65MODULE_FIRMWARE("amdgpu/smu_14_0_3_kicker.bin");
  66
  67#define ENABLE_IMU_ARG_GFXOFF_ENABLE		1
  68
  69int smu_v14_0_init_microcode(struct smu_context *smu)
  70{
  71	struct amdgpu_device *adev = smu->adev;
  72	char ucode_prefix[30];
  73	int err = 0;
  74	const struct smc_firmware_header_v1_0 *hdr;
  75	const struct common_firmware_header *header;
  76	struct amdgpu_firmware_info *ucode = NULL;
  77
  78	/* doesn't need to load smu firmware in IOV mode */
  79	if (amdgpu_sriov_vf(adev))
  80		return 0;
  81
  82	amdgpu_ucode_ip_version_decode(adev, MP1_HWIP, ucode_prefix, sizeof(ucode_prefix));
  83	if (amdgpu_is_kicker_fw(adev))
  84		err = amdgpu_ucode_request(adev, &adev->pm.fw, AMDGPU_UCODE_REQUIRED,
  85					   "amdgpu/%s_kicker.bin", ucode_prefix);
  86	else
  87		err = amdgpu_ucode_request(adev, &adev->pm.fw, AMDGPU_UCODE_REQUIRED,
  88					   "amdgpu/%s.bin", ucode_prefix);
  89	if (err)
  90		goto out;
  91
  92	hdr = (const struct smc_firmware_header_v1_0 *) adev->pm.fw->data;
  93	amdgpu_ucode_print_smc_hdr(&hdr->header);
  94	adev->pm.fw_version = le32_to_cpu(hdr->header.ucode_version);
  95
  96	if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
  97		ucode = &adev->firmware.ucode[AMDGPU_UCODE_ID_SMC];
  98		ucode->ucode_id = AMDGPU_UCODE_ID_SMC;
  99		ucode->fw = adev->pm.fw;
 100		header = (const struct common_firmware_header *)ucode->fw->data;
 101		adev->firmware.fw_size +=
 102			ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
 103	}
 104
 105out:
 106	if (err)
 107		amdgpu_ucode_release(&adev->pm.fw);
 108	return err;
 109}
 110
 111void smu_v14_0_fini_microcode(struct smu_context *smu)
 112{
 113	struct amdgpu_device *adev = smu->adev;
 114
 115	amdgpu_ucode_release(&adev->pm.fw);
 116	adev->pm.fw_version = 0;
 117}
 118
 119int smu_v14_0_load_microcode(struct smu_context *smu)
 120{
 121	struct amdgpu_device *adev = smu->adev;
 122	const uint32_t *src;
 123	const struct smc_firmware_header_v1_0 *hdr;
 124	uint32_t addr_start = MP1_SRAM;
 125	uint32_t i;
 126	uint32_t smc_fw_size;
 127	uint32_t mp1_fw_flags;
 128
 129	hdr = (const struct smc_firmware_header_v1_0 *) adev->pm.fw->data;
 130	src = (const uint32_t *)(adev->pm.fw->data +
 131				 le32_to_cpu(hdr->header.ucode_array_offset_bytes));
 132	smc_fw_size = hdr->header.ucode_size_bytes;
 133
 134	for (i = 1; i < smc_fw_size/4 - 1; i++) {
 135		WREG32_PCIE(addr_start, src[i]);
 136		addr_start += 4;
 137	}
 138
 139	WREG32_PCIE(MP1_Public | (smnMP1_PUB_CTRL & 0xffffffff),
 140		    1 & MP1_SMN_PUB_CTRL__LX3_RESET_MASK);
 141	WREG32_PCIE(MP1_Public | (smnMP1_PUB_CTRL & 0xffffffff),
 142		    1 & ~MP1_SMN_PUB_CTRL__LX3_RESET_MASK);
 143
 144	for (i = 0; i < adev->usec_timeout; i++) {
 145		if (smu->is_apu)
 146			mp1_fw_flags = RREG32_PCIE(MP1_Public |
 147						   (smnMP1_FIRMWARE_FLAGS_14_0_0 & 0xffffffff));
 148		else
 149			mp1_fw_flags = RREG32_PCIE(MP1_Public |
 150						   (smnMP1_FIRMWARE_FLAGS & 0xffffffff));
 151		if ((mp1_fw_flags & MP1_CRU1_MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) >>
 152		    MP1_CRU1_MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT)
 153			break;
 154		udelay(1);
 155	}
 156
 157	if (i == adev->usec_timeout)
 158		return -ETIME;
 159
 160	return 0;
 161}
 162
 163int smu_v14_0_init_pptable_microcode(struct smu_context *smu)
 164{
 165	struct amdgpu_device *adev = smu->adev;
 166	struct amdgpu_firmware_info *ucode = NULL;
 167	uint32_t size = 0, pptable_id = 0;
 168	int ret = 0;
 169	void *table;
 170
 171	/* doesn't need to load smu firmware in IOV mode */
 172	if (amdgpu_sriov_vf(adev))
 173		return 0;
 174
 175	if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
 176		return 0;
 177
 178	if (!adev->scpm_enabled)
 179		return 0;
 180
 181	if ((amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(14, 0, 2)) ||
 182	    (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(14, 0, 3)))
 183		return 0;
 184
 185	/* override pptable_id from driver parameter */
 186	if (amdgpu_smu_pptable_id >= 0) {
 187		pptable_id = amdgpu_smu_pptable_id;
 188		dev_info(adev->dev, "override pptable id %d\n", pptable_id);
 189	} else {
 190		pptable_id = smu->smu_table.boot_values.pp_table_id;
 191	}
 192
 193	/* "pptable_id == 0" means vbios carries the pptable. */
 194	if (!pptable_id)
 195		return 0;
 196
 197	ret = smu_v14_0_get_pptable_from_firmware(smu, &table, &size, pptable_id);
 198	if (ret)
 199		return ret;
 200
 201	smu->pptable_firmware.data = table;
 202	smu->pptable_firmware.size = size;
 203
 204	ucode = &adev->firmware.ucode[AMDGPU_UCODE_ID_PPTABLE];
 205	ucode->ucode_id = AMDGPU_UCODE_ID_PPTABLE;
 206	ucode->fw = &smu->pptable_firmware;
 207	adev->firmware.fw_size +=
 208		ALIGN(smu->pptable_firmware.size, PAGE_SIZE);
 209
 210	return 0;
 211}
 212
 213int smu_v14_0_check_fw_status(struct smu_context *smu)
 214{
 215	struct amdgpu_device *adev = smu->adev;
 216	uint32_t mp1_fw_flags;
 217
 218	if (smu->is_apu)
 219		mp1_fw_flags = RREG32_PCIE(MP1_Public |
 220					   (smnMP1_FIRMWARE_FLAGS_14_0_0 & 0xffffffff));
 221	else
 222		mp1_fw_flags = RREG32_PCIE(MP1_Public |
 223					   (smnMP1_FIRMWARE_FLAGS & 0xffffffff));
 224
 225	if ((mp1_fw_flags & MP1_CRU1_MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) >>
 226	    MP1_CRU1_MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT)
 227		return 0;
 228
 229	return -EIO;
 230}
 231
 232int smu_v14_0_check_fw_version(struct smu_context *smu)
 233{
 234	struct amdgpu_device *adev = smu->adev;
 235	uint32_t if_version = 0xff, smu_version = 0xff;
 236	uint8_t smu_program, smu_major, smu_minor, smu_debug;
 237	int ret = 0;
 238
 239	ret = smu_cmn_get_smc_version(smu, &if_version, &smu_version);
 240	if (ret)
 241		return ret;
 242
 243	smu_program = (smu_version >> 24) & 0xff;
 244	smu_major = (smu_version >> 16) & 0xff;
 245	smu_minor = (smu_version >> 8) & 0xff;
 246	smu_debug = (smu_version >> 0) & 0xff;
 247	if (smu->is_apu)
 248		adev->pm.fw_version = smu_version;
 249
 250	switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) {
 251	case IP_VERSION(14, 0, 0):
 252	case IP_VERSION(14, 0, 4):
 253	case IP_VERSION(14, 0, 5):
 254		smu->smc_driver_if_version = SMU14_DRIVER_IF_VERSION_SMU_V14_0_0;
 255		break;
 256	case IP_VERSION(14, 0, 1):
 257		smu->smc_driver_if_version = SMU14_DRIVER_IF_VERSION_SMU_V14_0_1;
 258		break;
 259	case IP_VERSION(14, 0, 2):
 260	case IP_VERSION(14, 0, 3):
 261		smu->smc_driver_if_version = SMU14_DRIVER_IF_VERSION_SMU_V14_0_2;
 262		break;
 263	default:
 264		dev_err(adev->dev, "smu unsupported IP version: 0x%x.\n",
 265			amdgpu_ip_version(adev, MP1_HWIP, 0));
 266		smu->smc_driver_if_version = SMU14_DRIVER_IF_VERSION_INV;
 267		break;
 268	}
 269
 270	if (adev->pm.fw)
 271		dev_dbg(smu->adev->dev, "smu fw reported program %d, version = 0x%08x (%d.%d.%d)\n",
 272			 smu_program, smu_version, smu_major, smu_minor, smu_debug);
 273
 274	/*
 275	 * 1. if_version mismatch is not critical as our fw is designed
 276	 * to be backward compatible.
 277	 * 2. New fw usually brings some optimizations. But that's visible
 278	 * only on the paired driver.
 279	 * Considering above, we just leave user a verbal message instead
 280	 * of halt driver loading.
 281	 */
 282	if (if_version != smu->smc_driver_if_version) {
 283		dev_info(adev->dev, "smu driver if version = 0x%08x, smu fw if version = 0x%08x, "
 284			 "smu fw program = %d, smu fw version = 0x%08x (%d.%d.%d)\n",
 285			 smu->smc_driver_if_version, if_version,
 286			 smu_program, smu_version, smu_major, smu_minor, smu_debug);
 287	}
 288
 289	return ret;
 290}
 291
 292static int smu_v14_0_set_pptable_v2_0(struct smu_context *smu, void **table, uint32_t *size)
 293{
 294	struct amdgpu_device *adev = smu->adev;
 295	uint32_t ppt_offset_bytes;
 296	const struct smc_firmware_header_v2_0 *v2;
 297
 298	v2 = (const struct smc_firmware_header_v2_0 *) adev->pm.fw->data;
 299
 300	ppt_offset_bytes = le32_to_cpu(v2->ppt_offset_bytes);
 301	*size = le32_to_cpu(v2->ppt_size_bytes);
 302	*table = (uint8_t *)v2 + ppt_offset_bytes;
 303
 304	return 0;
 305}
 306
 307static int smu_v14_0_set_pptable_v2_1(struct smu_context *smu, void **table,
 308				      uint32_t *size, uint32_t pptable_id)
 309{
 310	struct amdgpu_device *adev = smu->adev;
 311	const struct smc_firmware_header_v2_1 *v2_1;
 312	struct smc_soft_pptable_entry *entries;
 313	uint32_t pptable_count = 0;
 314	int i = 0;
 315
 316	v2_1 = (const struct smc_firmware_header_v2_1 *) adev->pm.fw->data;
 317	entries = (struct smc_soft_pptable_entry *)
 318		((uint8_t *)v2_1 + le32_to_cpu(v2_1->pptable_entry_offset));
 319	pptable_count = le32_to_cpu(v2_1->pptable_count);
 320	for (i = 0; i < pptable_count; i++) {
 321		if (le32_to_cpu(entries[i].id) == pptable_id) {
 322			*table = ((uint8_t *)v2_1 + le32_to_cpu(entries[i].ppt_offset_bytes));
 323			*size = le32_to_cpu(entries[i].ppt_size_bytes);
 324			break;
 325		}
 326	}
 327
 328	if (i == pptable_count)
 329		return -EINVAL;
 330
 331	return 0;
 332}
 333
 334static int smu_v14_0_get_pptable_from_vbios(struct smu_context *smu, void **table, uint32_t *size)
 335{
 336	struct amdgpu_device *adev = smu->adev;
 337	uint16_t atom_table_size;
 338	uint8_t frev, crev;
 339	int ret, index;
 340
 341	dev_info(adev->dev, "use vbios provided pptable\n");
 342	index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
 343					    powerplayinfo);
 344
 345	ret = amdgpu_atombios_get_data_table(adev, index, &atom_table_size, &frev, &crev,
 346					     (uint8_t **)table);
 347	if (ret)
 348		return ret;
 349
 350	if (size)
 351		*size = atom_table_size;
 352
 353	return 0;
 354}
 355
 356int smu_v14_0_get_pptable_from_firmware(struct smu_context *smu,
 357					void **table,
 358					uint32_t *size,
 359					uint32_t pptable_id)
 360{
 361	const struct smc_firmware_header_v1_0 *hdr;
 362	struct amdgpu_device *adev = smu->adev;
 363	uint16_t version_major, version_minor;
 364	int ret;
 365
 366	hdr = (const struct smc_firmware_header_v1_0 *) adev->pm.fw->data;
 367	if (!hdr)
 368		return -EINVAL;
 369
 370	dev_info(adev->dev, "use driver provided pptable %d\n", pptable_id);
 371
 372	version_major = le16_to_cpu(hdr->header.header_version_major);
 373	version_minor = le16_to_cpu(hdr->header.header_version_minor);
 374	if (version_major != 2) {
 375		dev_err(adev->dev, "Unsupported smu firmware version %d.%d\n",
 376			version_major, version_minor);
 377		return -EINVAL;
 378	}
 379
 380	switch (version_minor) {
 381	case 0:
 382		ret = smu_v14_0_set_pptable_v2_0(smu, table, size);
 383		break;
 384	case 1:
 385		ret = smu_v14_0_set_pptable_v2_1(smu, table, size, pptable_id);
 386		break;
 387	default:
 388		ret = -EINVAL;
 389		break;
 390	}
 391
 392	return ret;
 393}
 394
 395int smu_v14_0_setup_pptable(struct smu_context *smu)
 396{
 397	struct amdgpu_device *adev = smu->adev;
 398	uint32_t size = 0, pptable_id = 0;
 399	void *table;
 400	int ret = 0;
 401
 402	/* override pptable_id from driver parameter */
 403	if (amdgpu_smu_pptable_id >= 0) {
 404		pptable_id = amdgpu_smu_pptable_id;
 405		dev_info(adev->dev, "override pptable id %d\n", pptable_id);
 406	} else {
 407		pptable_id = smu->smu_table.boot_values.pp_table_id;
 408	}
 409
 410	/* force using vbios pptable in sriov mode */
 411	if ((amdgpu_sriov_vf(adev) || !pptable_id) && (amdgpu_emu_mode != 1))
 412		ret = smu_v14_0_get_pptable_from_vbios(smu, &table, &size);
 413	else
 414		ret = smu_v14_0_get_pptable_from_firmware(smu, &table, &size, pptable_id);
 415
 416	if (ret)
 417		return ret;
 418
 419	if (!smu->smu_table.power_play_table)
 420		smu->smu_table.power_play_table = table;
 421	if (!smu->smu_table.power_play_table_size)
 422		smu->smu_table.power_play_table_size = size;
 423
 424	return 0;
 425}
 426
 427int smu_v14_0_init_smc_tables(struct smu_context *smu)
 428{
 429	struct smu_table_context *smu_table = &smu->smu_table;
 430	struct smu_table *tables = smu_table->tables;
 431	int ret = 0;
 432
 433	smu_table->driver_pptable =
 434		kzalloc(tables[SMU_TABLE_PPTABLE].size, GFP_KERNEL);
 435	if (!smu_table->driver_pptable) {
 436		ret = -ENOMEM;
 437		goto err0_out;
 438	}
 439
 440	smu_table->max_sustainable_clocks =
 441		kzalloc(sizeof(struct smu_14_0_max_sustainable_clocks), GFP_KERNEL);
 442	if (!smu_table->max_sustainable_clocks) {
 443		ret = -ENOMEM;
 444		goto err1_out;
 445	}
 446
 447	if (tables[SMU_TABLE_OVERDRIVE].size) {
 448		smu_table->overdrive_table =
 449			kzalloc(tables[SMU_TABLE_OVERDRIVE].size, GFP_KERNEL);
 450		if (!smu_table->overdrive_table) {
 451			ret = -ENOMEM;
 452			goto err2_out;
 453		}
 454
 455		smu_table->boot_overdrive_table =
 456			kzalloc(tables[SMU_TABLE_OVERDRIVE].size, GFP_KERNEL);
 457		if (!smu_table->boot_overdrive_table) {
 458			ret = -ENOMEM;
 459			goto err3_out;
 460		}
 461
 462		smu_table->user_overdrive_table =
 463			kzalloc(tables[SMU_TABLE_OVERDRIVE].size, GFP_KERNEL);
 464		if (!smu_table->user_overdrive_table) {
 465			ret = -ENOMEM;
 466			goto err4_out;
 467		}
 468	}
 469
 470	smu_table->combo_pptable =
 471		kzalloc(tables[SMU_TABLE_COMBO_PPTABLE].size, GFP_KERNEL);
 472	if (!smu_table->combo_pptable) {
 473		ret = -ENOMEM;
 474		goto err5_out;
 475	}
 476
 477	return 0;
 478
 479err5_out:
 480	kfree(smu_table->user_overdrive_table);
 481err4_out:
 482	kfree(smu_table->boot_overdrive_table);
 483err3_out:
 484	kfree(smu_table->overdrive_table);
 485err2_out:
 486	kfree(smu_table->max_sustainable_clocks);
 487err1_out:
 488	kfree(smu_table->driver_pptable);
 489err0_out:
 490	return ret;
 491}
 492
 493int smu_v14_0_fini_smc_tables(struct smu_context *smu)
 494{
 495	struct smu_table_context *smu_table = &smu->smu_table;
 496	struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
 497
 498	kfree(smu_table->gpu_metrics_table);
 499	kfree(smu_table->combo_pptable);
 500	kfree(smu_table->boot_overdrive_table);
 501	kfree(smu_table->overdrive_table);
 502	kfree(smu_table->max_sustainable_clocks);
 503	kfree(smu_table->driver_pptable);
 504	smu_table->gpu_metrics_table = NULL;
 505	smu_table->combo_pptable = NULL;
 506	smu_table->boot_overdrive_table = NULL;
 507	smu_table->overdrive_table = NULL;
 508	smu_table->max_sustainable_clocks = NULL;
 509	smu_table->driver_pptable = NULL;
 510	kfree(smu_table->hardcode_pptable);
 511	smu_table->hardcode_pptable = NULL;
 512
 513	kfree(smu_table->ecc_table);
 514	kfree(smu_table->metrics_table);
 515	kfree(smu_table->watermarks_table);
 516	smu_table->ecc_table = NULL;
 517	smu_table->metrics_table = NULL;
 518	smu_table->watermarks_table = NULL;
 519	smu_table->metrics_time = 0;
 520
 521	kfree(smu_dpm->dpm_context);
 522	kfree(smu_dpm->golden_dpm_context);
 523	kfree(smu_dpm->dpm_current_power_state);
 524	kfree(smu_dpm->dpm_request_power_state);
 525	smu_dpm->dpm_context = NULL;
 526	smu_dpm->golden_dpm_context = NULL;
 527	smu_dpm->dpm_context_size = 0;
 528	smu_dpm->dpm_current_power_state = NULL;
 529	smu_dpm->dpm_request_power_state = NULL;
 530
 531	return 0;
 532}
 533
 534int smu_v14_0_init_power(struct smu_context *smu)
 535{
 536	struct smu_power_context *smu_power = &smu->smu_power;
 537
 538	if (smu_power->power_context || smu_power->power_context_size != 0)
 539		return -EINVAL;
 540
 541	smu_power->power_context = kzalloc(sizeof(struct smu_14_0_dpm_context),
 542					   GFP_KERNEL);
 543	if (!smu_power->power_context)
 544		return -ENOMEM;
 545	smu_power->power_context_size = sizeof(struct smu_14_0_dpm_context);
 546
 547	return 0;
 548}
 549
 550int smu_v14_0_fini_power(struct smu_context *smu)
 551{
 552	struct smu_power_context *smu_power = &smu->smu_power;
 553
 554	if (!smu_power->power_context || smu_power->power_context_size == 0)
 555		return -EINVAL;
 556
 557	kfree(smu_power->power_context);
 558	smu_power->power_context = NULL;
 559	smu_power->power_context_size = 0;
 560
 561	return 0;
 562}
 563
 564int smu_v14_0_get_vbios_bootup_values(struct smu_context *smu)
 565{
 566	int ret, index;
 567	uint16_t size;
 568	uint8_t frev, crev;
 569	struct atom_common_table_header *header;
 570	struct atom_firmware_info_v3_4 *v_3_4;
 571	struct atom_firmware_info_v3_3 *v_3_3;
 572	struct atom_firmware_info_v3_1 *v_3_1;
 573	struct atom_smu_info_v3_6 *smu_info_v3_6;
 574	struct atom_smu_info_v4_0 *smu_info_v4_0;
 575
 576	index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
 577					    firmwareinfo);
 578
 579	ret = amdgpu_atombios_get_data_table(smu->adev, index, &size, &frev, &crev,
 580					     (uint8_t **)&header);
 581	if (ret)
 582		return ret;
 583
 584	if (header->format_revision != 3) {
 585		dev_err(smu->adev->dev, "unknown atom_firmware_info version! for smu14\n");
 586		return -EINVAL;
 587	}
 588
 589	switch (header->content_revision) {
 590	case 0:
 591	case 1:
 592	case 2:
 593		v_3_1 = (struct atom_firmware_info_v3_1 *)header;
 594		smu->smu_table.boot_values.revision = v_3_1->firmware_revision;
 595		smu->smu_table.boot_values.gfxclk = v_3_1->bootup_sclk_in10khz;
 596		smu->smu_table.boot_values.uclk = v_3_1->bootup_mclk_in10khz;
 597		smu->smu_table.boot_values.socclk = 0;
 598		smu->smu_table.boot_values.dcefclk = 0;
 599		smu->smu_table.boot_values.vddc = v_3_1->bootup_vddc_mv;
 600		smu->smu_table.boot_values.vddci = v_3_1->bootup_vddci_mv;
 601		smu->smu_table.boot_values.mvddc = v_3_1->bootup_mvddc_mv;
 602		smu->smu_table.boot_values.vdd_gfx = v_3_1->bootup_vddgfx_mv;
 603		smu->smu_table.boot_values.cooling_id = v_3_1->coolingsolution_id;
 604		smu->smu_table.boot_values.pp_table_id = 0;
 605		break;
 606	case 3:
 607		v_3_3 = (struct atom_firmware_info_v3_3 *)header;
 608		smu->smu_table.boot_values.revision = v_3_3->firmware_revision;
 609		smu->smu_table.boot_values.gfxclk = v_3_3->bootup_sclk_in10khz;
 610		smu->smu_table.boot_values.uclk = v_3_3->bootup_mclk_in10khz;
 611		smu->smu_table.boot_values.socclk = 0;
 612		smu->smu_table.boot_values.dcefclk = 0;
 613		smu->smu_table.boot_values.vddc = v_3_3->bootup_vddc_mv;
 614		smu->smu_table.boot_values.vddci = v_3_3->bootup_vddci_mv;
 615		smu->smu_table.boot_values.mvddc = v_3_3->bootup_mvddc_mv;
 616		smu->smu_table.boot_values.vdd_gfx = v_3_3->bootup_vddgfx_mv;
 617		smu->smu_table.boot_values.cooling_id = v_3_3->coolingsolution_id;
 618		smu->smu_table.boot_values.pp_table_id = v_3_3->pplib_pptable_id;
 619		break;
 620	case 4:
 621	default:
 622		v_3_4 = (struct atom_firmware_info_v3_4 *)header;
 623		smu->smu_table.boot_values.revision = v_3_4->firmware_revision;
 624		smu->smu_table.boot_values.gfxclk = v_3_4->bootup_sclk_in10khz;
 625		smu->smu_table.boot_values.uclk = v_3_4->bootup_mclk_in10khz;
 626		smu->smu_table.boot_values.socclk = 0;
 627		smu->smu_table.boot_values.dcefclk = 0;
 628		smu->smu_table.boot_values.vddc = v_3_4->bootup_vddc_mv;
 629		smu->smu_table.boot_values.vddci = v_3_4->bootup_vddci_mv;
 630		smu->smu_table.boot_values.mvddc = v_3_4->bootup_mvddc_mv;
 631		smu->smu_table.boot_values.vdd_gfx = v_3_4->bootup_vddgfx_mv;
 632		smu->smu_table.boot_values.cooling_id = v_3_4->coolingsolution_id;
 633		smu->smu_table.boot_values.pp_table_id = v_3_4->pplib_pptable_id;
 634		break;
 635	}
 636
 637	smu->smu_table.boot_values.format_revision = header->format_revision;
 638	smu->smu_table.boot_values.content_revision = header->content_revision;
 639
 640	index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
 641					    smu_info);
 642	if (!amdgpu_atombios_get_data_table(smu->adev, index, &size, &frev, &crev,
 643					    (uint8_t **)&header)) {
 644
 645		if ((frev == 3) && (crev == 6)) {
 646			smu_info_v3_6 = (struct atom_smu_info_v3_6 *)header;
 647
 648			smu->smu_table.boot_values.socclk = smu_info_v3_6->bootup_socclk_10khz;
 649			smu->smu_table.boot_values.vclk = smu_info_v3_6->bootup_vclk_10khz;
 650			smu->smu_table.boot_values.dclk = smu_info_v3_6->bootup_dclk_10khz;
 651			smu->smu_table.boot_values.fclk = smu_info_v3_6->bootup_fclk_10khz;
 652		} else if ((frev == 3) && (crev == 1)) {
 653			return 0;
 654		} else if ((frev == 4) && (crev == 0)) {
 655			smu_info_v4_0 = (struct atom_smu_info_v4_0 *)header;
 656
 657			smu->smu_table.boot_values.socclk = smu_info_v4_0->bootup_socclk_10khz;
 658			smu->smu_table.boot_values.dcefclk = smu_info_v4_0->bootup_dcefclk_10khz;
 659			smu->smu_table.boot_values.vclk = smu_info_v4_0->bootup_vclk0_10khz;
 660			smu->smu_table.boot_values.dclk = smu_info_v4_0->bootup_dclk0_10khz;
 661			smu->smu_table.boot_values.fclk = smu_info_v4_0->bootup_fclk_10khz;
 662		} else {
 663			dev_warn(smu->adev->dev, "Unexpected and unhandled version: %d.%d\n",
 664						(uint32_t)frev, (uint32_t)crev);
 665		}
 666	}
 667
 668	return 0;
 669}
 670
 671
 672int smu_v14_0_notify_memory_pool_location(struct smu_context *smu)
 673{
 674	struct smu_table_context *smu_table = &smu->smu_table;
 675	struct smu_table *memory_pool = &smu_table->memory_pool;
 676	int ret = 0;
 677	uint64_t address;
 678	uint32_t address_low, address_high;
 679
 680	if (memory_pool->size == 0 || memory_pool->cpu_addr == NULL)
 681		return ret;
 682
 683	address = memory_pool->mc_address;
 684	address_high = (uint32_t)upper_32_bits(address);
 685	address_low  = (uint32_t)lower_32_bits(address);
 686
 687	ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_DramLogSetDramAddrHigh,
 688					      address_high, NULL);
 689	if (ret)
 690		return ret;
 691	ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_DramLogSetDramAddrLow,
 692					      address_low, NULL);
 693	if (ret)
 694		return ret;
 695	ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_DramLogSetDramSize,
 696					      (uint32_t)memory_pool->size, NULL);
 697	if (ret)
 698		return ret;
 699
 700	return ret;
 701}
 702
 703int smu_v14_0_set_driver_table_location(struct smu_context *smu)
 704{
 705	struct smu_table *driver_table = &smu->smu_table.driver_table;
 706	int ret = 0;
 707
 708	if (driver_table->mc_address) {
 709		ret = smu_cmn_send_smc_msg_with_param(smu,
 710						      SMU_MSG_SetDriverDramAddrHigh,
 711						      upper_32_bits(driver_table->mc_address),
 712						      NULL);
 713		if (!ret)
 714			ret = smu_cmn_send_smc_msg_with_param(smu,
 715							      SMU_MSG_SetDriverDramAddrLow,
 716							      lower_32_bits(driver_table->mc_address),
 717							      NULL);
 718	}
 719
 720	return ret;
 721}
 722
 723int smu_v14_0_set_tool_table_location(struct smu_context *smu)
 724{
 725	int ret = 0;
 726	struct smu_table *tool_table = &smu->smu_table.tables[SMU_TABLE_PMSTATUSLOG];
 727
 728	if (tool_table->mc_address) {
 729		ret = smu_cmn_send_smc_msg_with_param(smu,
 730						      SMU_MSG_SetToolsDramAddrHigh,
 731						      upper_32_bits(tool_table->mc_address),
 732						      NULL);
 733		if (!ret)
 734			ret = smu_cmn_send_smc_msg_with_param(smu,
 735							      SMU_MSG_SetToolsDramAddrLow,
 736							      lower_32_bits(tool_table->mc_address),
 737							      NULL);
 738	}
 739
 740	return ret;
 741}
 742
 743int smu_v14_0_set_allowed_mask(struct smu_context *smu)
 744{
 745	struct smu_feature *feature = &smu->smu_feature;
 746	int ret = 0;
 747	uint32_t feature_mask[2];
 748
 749	if (bitmap_empty(feature->allowed, SMU_FEATURE_MAX) ||
 750	    feature->feature_num < 64)
 751		return -EINVAL;
 752
 753	bitmap_to_arr32(feature_mask, feature->allowed, 64);
 754
 755	ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetAllowedFeaturesMaskHigh,
 756					      feature_mask[1], NULL);
 757	if (ret)
 758		return ret;
 759
 760	return smu_cmn_send_smc_msg_with_param(smu,
 761					       SMU_MSG_SetAllowedFeaturesMaskLow,
 762					       feature_mask[0],
 763					       NULL);
 764}
 765
 766int smu_v14_0_gfx_off_control(struct smu_context *smu, bool enable)
 767{
 768	int ret = 0;
 769	struct amdgpu_device *adev = smu->adev;
 770
 771	switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) {
 772	case IP_VERSION(14, 0, 0):
 773	case IP_VERSION(14, 0, 1):
 774	case IP_VERSION(14, 0, 2):
 775	case IP_VERSION(14, 0, 3):
 776	case IP_VERSION(14, 0, 4):
 777	case IP_VERSION(14, 0, 5):
 778		if (!(adev->pm.pp_feature & PP_GFXOFF_MASK))
 779			return 0;
 780		if (enable)
 781			ret = smu_cmn_send_smc_msg(smu, SMU_MSG_AllowGfxOff, NULL);
 782		else
 783			ret = smu_cmn_send_smc_msg(smu, SMU_MSG_DisallowGfxOff, NULL);
 784		break;
 785	default:
 786		break;
 787	}
 788
 789	return ret;
 790}
 791
 792int smu_v14_0_system_features_control(struct smu_context *smu,
 793				      bool en)
 794{
 795	return smu_cmn_send_smc_msg(smu, (en ? SMU_MSG_EnableAllSmuFeatures :
 796					  SMU_MSG_DisableAllSmuFeatures), NULL);
 797}
 798
 799int smu_v14_0_notify_display_change(struct smu_context *smu)
 800{
 801	int ret = 0;
 802
 803	if (!smu->pm_enabled)
 804		return ret;
 805
 806	if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT) &&
 807	    smu->adev->gmc.vram_type == AMDGPU_VRAM_TYPE_HBM)
 808		ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetUclkFastSwitch, 1, NULL);
 809
 810	return ret;
 811}
 812
 813int smu_v14_0_get_current_power_limit(struct smu_context *smu,
 814				      uint32_t *power_limit)
 815{
 816	int power_src;
 817	int ret = 0;
 818
 819	if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_PPT_BIT))
 820		return -EINVAL;
 821
 822	power_src = smu_cmn_to_asic_specific_index(smu,
 823						   CMN2ASIC_MAPPING_PWR,
 824						   smu->adev->pm.ac_power ?
 825						   SMU_POWER_SOURCE_AC :
 826						   SMU_POWER_SOURCE_DC);
 827	if (power_src < 0)
 828		return -EINVAL;
 829
 830	ret = smu_cmn_send_smc_msg_with_param(smu,
 831					      SMU_MSG_GetPptLimit,
 832					      power_src << 16,
 833					      power_limit);
 834	if (ret)
 835		dev_err(smu->adev->dev, "[%s] get PPT limit failed!", __func__);
 836
 837	return ret;
 838}
 839
 840int smu_v14_0_set_power_limit(struct smu_context *smu,
 841			      enum smu_ppt_limit_type limit_type,
 842			      uint32_t limit)
 843{
 844	int ret = 0;
 845
 846	if (limit_type != SMU_DEFAULT_PPT_LIMIT)
 847		return -EINVAL;
 848
 849	if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_PPT_BIT)) {
 850		dev_err(smu->adev->dev, "Setting new power limit is not supported!\n");
 851		return -EOPNOTSUPP;
 852	}
 853
 854	ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetPptLimit, limit, NULL);
 855	if (ret) {
 856		dev_err(smu->adev->dev, "[%s] Set power limit Failed!\n", __func__);
 857		return ret;
 858	}
 859
 860	smu->current_power_limit = limit;
 861
 862	return 0;
 863}
 864
 865static int smu_v14_0_set_irq_state(struct amdgpu_device *adev,
 866				   struct amdgpu_irq_src *source,
 867				   unsigned tyep,
 868				   enum amdgpu_interrupt_state state)
 869{
 870	struct smu_context *smu = adev->powerplay.pp_handle;
 871	uint32_t low, high;
 872	uint32_t val = 0;
 873
 874	switch (state) {
 875	case AMDGPU_IRQ_STATE_DISABLE:
 876		/* For THM irqs */
 877		val = RREG32_SOC15(THM, 0, regTHM_THERMAL_INT_CTRL);
 878		val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_INTH_MASK, 1);
 879		val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_INTL_MASK, 1);
 880		WREG32_SOC15(THM, 0, regTHM_THERMAL_INT_CTRL, val);
 881
 882		WREG32_SOC15(THM, 0, regTHM_THERMAL_INT_ENA, 0);
 883
 884		/* For MP1 SW irqs */
 885		if (smu->is_apu) {
 886			val = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL_mp1_14_0_0);
 887			val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT_CTRL, INT_MASK, 1);
 888			WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL_mp1_14_0_0, val);
 889		} else {
 890			val = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL);
 891			val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT_CTRL, INT_MASK, 1);
 892			WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL, val);
 893		}
 894
 895		break;
 896	case AMDGPU_IRQ_STATE_ENABLE:
 897		/* For THM irqs */
 898		low = max(SMU_THERMAL_MINIMUM_ALERT_TEMP,
 899			  smu->thermal_range.min / SMU_TEMPERATURE_UNITS_PER_CENTIGRADES);
 900		high = min(SMU_THERMAL_MAXIMUM_ALERT_TEMP,
 901			   smu->thermal_range.software_shutdown_temp);
 902		val = RREG32_SOC15(THM, 0, regTHM_THERMAL_INT_CTRL);
 903		val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5);
 904		val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1);
 905		val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_INTH_MASK, 0);
 906		val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_INTL_MASK, 0);
 907		val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high & 0xff));
 908		val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low & 0xff));
 909		val = val & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK);
 910		WREG32_SOC15(THM, 0, regTHM_THERMAL_INT_CTRL, val);
 911
 912		val = (1 << THM_THERMAL_INT_ENA__THERM_INTH_CLR__SHIFT);
 913		val |= (1 << THM_THERMAL_INT_ENA__THERM_INTL_CLR__SHIFT);
 914		val |= (1 << THM_THERMAL_INT_ENA__THERM_TRIGGER_CLR__SHIFT);
 915		WREG32_SOC15(THM, 0, regTHM_THERMAL_INT_ENA, val);
 916
 917		/* For MP1 SW irqs */
 918		if (smu->is_apu) {
 919			val = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_mp1_14_0_0);
 920			val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT, ID, 0xFE);
 921			val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT, VALID, 0);
 922			WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_mp1_14_0_0, val);
 923
 924			val = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL_mp1_14_0_0);
 925			val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT_CTRL, INT_MASK, 0);
 926			WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL_mp1_14_0_0, val);
 927		} else {
 928			val = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT);
 929			val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT, ID, 0xFE);
 930			val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT, VALID, 0);
 931			WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT, val);
 932
 933			val = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL);
 934			val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT_CTRL, INT_MASK, 0);
 935			WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL, val);
 936		}
 937
 938		break;
 939	default:
 940		break;
 941	}
 942
 943	return 0;
 944}
 945
 946#define THM_11_0__SRCID__THM_DIG_THERM_L2H		0		/* ASIC_TEMP > CG_THERMAL_INT.DIG_THERM_INTH  */
 947#define THM_11_0__SRCID__THM_DIG_THERM_H2L		1		/* ASIC_TEMP < CG_THERMAL_INT.DIG_THERM_INTL  */
 948
 949static int smu_v14_0_irq_process(struct amdgpu_device *adev,
 950				 struct amdgpu_irq_src *source,
 951				 struct amdgpu_iv_entry *entry)
 952{
 953	struct smu_context *smu = adev->powerplay.pp_handle;
 954	uint32_t client_id = entry->client_id;
 955	uint32_t src_id = entry->src_id;
 956
 957	/*
 958	 * ctxid is used to distinguish different
 959	 * events for SMCToHost interrupt.
 960	 */
 961	uint32_t ctxid = entry->src_data[0];
 962	uint32_t data;
 963	uint32_t high;
 964
 965	if (client_id == SOC15_IH_CLIENTID_THM) {
 966		switch (src_id) {
 967		case THM_11_0__SRCID__THM_DIG_THERM_L2H:
 968			schedule_delayed_work(&smu->swctf_delayed_work,
 969					      msecs_to_jiffies(AMDGPU_SWCTF_EXTRA_DELAY));
 970			break;
 971		case THM_11_0__SRCID__THM_DIG_THERM_H2L:
 972			dev_emerg(adev->dev, "ERROR: GPU under temperature range detected\n");
 973			break;
 974		default:
 975			dev_emerg(adev->dev, "ERROR: GPU under temperature range unknown src id (%d)\n",
 976				  src_id);
 977			break;
 978		}
 979	} else if (client_id == SOC15_IH_CLIENTID_MP1) {
 980		if (src_id == SMU_IH_INTERRUPT_ID_TO_DRIVER) {
 981			/* ACK SMUToHost interrupt */
 982			data = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL);
 983			data = REG_SET_FIELD(data, MP1_SMN_IH_SW_INT_CTRL, INT_ACK, 1);
 984			WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL, data);
 985
 986			switch (ctxid) {
 987			case SMU_IH_INTERRUPT_CONTEXT_ID_FAN_ABNORMAL:
 988				high = smu->thermal_range.software_shutdown_temp +
 989					smu->thermal_range.software_shutdown_temp_offset;
 990				high = min_t(typeof(high),
 991					     SMU_THERMAL_MAXIMUM_ALERT_TEMP,
 992					     high);
 993				dev_emerg(adev->dev, "Reduce soft CTF limit to %d (by an offset %d)\n",
 994							high,
 995							smu->thermal_range.software_shutdown_temp_offset);
 996
 997				data = RREG32_SOC15(THM, 0, regTHM_THERMAL_INT_CTRL);
 998				data = REG_SET_FIELD(data, THM_THERMAL_INT_CTRL,
 999							DIG_THERM_INTH,
1000							(high & 0xff));
1001				data = data & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK);
1002				WREG32_SOC15(THM, 0, regTHM_THERMAL_INT_CTRL, data);
1003				break;
1004			case SMU_IH_INTERRUPT_CONTEXT_ID_FAN_RECOVERY:
1005				high = min_t(typeof(high),
1006					     SMU_THERMAL_MAXIMUM_ALERT_TEMP,
1007					     smu->thermal_range.software_shutdown_temp);
1008				dev_emerg(adev->dev, "Recover soft CTF limit to %d\n", high);
1009
1010				data = RREG32_SOC15(THM, 0, regTHM_THERMAL_INT_CTRL);
1011				data = REG_SET_FIELD(data, THM_THERMAL_INT_CTRL,
1012							DIG_THERM_INTH,
1013							(high & 0xff));
1014				data = data & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK);
1015				WREG32_SOC15(THM, 0, regTHM_THERMAL_INT_CTRL, data);
1016				break;
1017			default:
1018				dev_dbg(adev->dev, "Unhandled context id %d from client:%d!\n",
1019									ctxid, client_id);
1020				break;
1021			}
1022		}
1023	}
1024
1025	return 0;
1026}
1027
1028static const struct amdgpu_irq_src_funcs smu_v14_0_irq_funcs = {
1029	.set = smu_v14_0_set_irq_state,
1030	.process = smu_v14_0_irq_process,
1031};
1032
1033int smu_v14_0_register_irq_handler(struct smu_context *smu)
1034{
1035	struct amdgpu_device *adev = smu->adev;
1036	struct amdgpu_irq_src *irq_src = &smu->irq_source;
1037	int ret = 0;
1038
1039	if (amdgpu_sriov_vf(adev))
1040		return 0;
1041
1042	irq_src->num_types = 1;
1043	irq_src->funcs = &smu_v14_0_irq_funcs;
1044
1045	ret = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_THM,
1046				THM_11_0__SRCID__THM_DIG_THERM_L2H,
1047				irq_src);
1048	if (ret)
1049		return ret;
1050
1051	ret = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_THM,
1052				THM_11_0__SRCID__THM_DIG_THERM_H2L,
1053				irq_src);
1054	if (ret)
1055		return ret;
1056
1057	ret = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_MP1,
1058				SMU_IH_INTERRUPT_ID_TO_DRIVER,
1059				irq_src);
1060	if (ret)
1061		return ret;
1062
1063	return ret;
1064}
1065
1066static int smu_v14_0_wait_for_reset_complete(struct smu_context *smu,
1067					     uint64_t event_arg)
1068{
1069	int ret = 0;
1070
1071	dev_dbg(smu->adev->dev, "waiting for smu reset complete\n");
1072	ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GfxDriverResetRecovery, NULL);
1073
1074	return ret;
1075}
1076
1077int smu_v14_0_wait_for_event(struct smu_context *smu, enum smu_event_type event,
1078			     uint64_t event_arg)
1079{
1080	int ret = -EINVAL;
1081
1082	switch (event) {
1083	case SMU_EVENT_RESET_COMPLETE:
1084		ret = smu_v14_0_wait_for_reset_complete(smu, event_arg);
1085		break;
1086	default:
1087		break;
1088	}
1089
1090	return ret;
1091}
1092
1093int smu_v14_0_get_dpm_ultimate_freq(struct smu_context *smu, enum smu_clk_type clk_type,
1094				    uint32_t *min, uint32_t *max)
1095{
1096	int ret = 0, clk_id = 0;
1097	uint32_t param = 0;
1098	uint32_t clock_limit;
1099
1100	if (!smu_cmn_clk_dpm_is_enabled(smu, clk_type)) {
1101		switch (clk_type) {
1102		case SMU_MCLK:
1103		case SMU_UCLK:
1104			clock_limit = smu->smu_table.boot_values.uclk;
1105			break;
1106		case SMU_GFXCLK:
1107		case SMU_SCLK:
1108			clock_limit = smu->smu_table.boot_values.gfxclk;
1109			break;
1110		case SMU_SOCCLK:
1111			clock_limit = smu->smu_table.boot_values.socclk;
1112			break;
1113		default:
1114			clock_limit = 0;
1115			break;
1116		}
1117
1118		/* clock in Mhz unit */
1119		if (min)
1120			*min = clock_limit / 100;
1121		if (max)
1122			*max = clock_limit / 100;
1123
1124		return 0;
1125	}
1126
1127	clk_id = smu_cmn_to_asic_specific_index(smu,
1128						CMN2ASIC_MAPPING_CLK,
1129						clk_type);
1130	if (clk_id < 0) {
1131		ret = -EINVAL;
1132		goto failed;
1133	}
1134	param = (clk_id & 0xffff) << 16;
1135
1136	if (max) {
1137		if (smu->adev->pm.ac_power)
1138			ret = smu_cmn_send_smc_msg_with_param(smu,
1139							      SMU_MSG_GetMaxDpmFreq,
1140							      param,
1141							      max);
1142		else
1143			ret = smu_cmn_send_smc_msg_with_param(smu,
1144							      SMU_MSG_GetDcModeMaxDpmFreq,
1145							      param,
1146							      max);
1147		if (ret)
1148			goto failed;
1149	}
1150
1151	if (min) {
1152		ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GetMinDpmFreq, param, min);
1153		if (ret)
1154			goto failed;
1155	}
1156
1157failed:
1158	return ret;
1159}
1160
1161int smu_v14_0_set_soft_freq_limited_range(struct smu_context *smu,
1162					  enum smu_clk_type clk_type,
1163					  uint32_t min,
1164					  uint32_t max,
1165					  bool automatic)
1166{
1167	int ret = 0, clk_id = 0;
1168	uint32_t param;
1169
1170	if (!smu_cmn_clk_dpm_is_enabled(smu, clk_type))
1171		return 0;
1172
1173	clk_id = smu_cmn_to_asic_specific_index(smu,
1174						CMN2ASIC_MAPPING_CLK,
1175						clk_type);
1176	if (clk_id < 0)
1177		return clk_id;
1178
1179	if (max > 0) {
1180		max = SMU_V14_SOFT_FREQ_ROUND(max);
1181		if (automatic)
1182			param = (uint32_t)((clk_id << 16) | 0xffff);
1183		else
1184			param = (uint32_t)((clk_id << 16) | (max & 0xffff));
1185		ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxByFreq,
1186						      param, NULL);
1187		if (ret)
1188			goto out;
1189	}
1190
1191	if (min > 0) {
1192		if (automatic)
1193			param = (uint32_t)((clk_id << 16) | 0);
1194		else
1195			param = (uint32_t)((clk_id << 16) | (min & 0xffff));
1196		ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMinByFreq,
1197						      param, NULL);
1198		if (ret)
1199			goto out;
1200	}
1201
1202out:
1203	return ret;
1204}
1205
1206int smu_v14_0_set_hard_freq_limited_range(struct smu_context *smu,
1207					  enum smu_clk_type clk_type,
1208					  uint32_t min,
1209					  uint32_t max)
1210{
1211	int ret = 0, clk_id = 0;
1212	uint32_t param;
1213
1214	if (min <= 0 && max <= 0)
1215		return -EINVAL;
1216
1217	if (!smu_cmn_clk_dpm_is_enabled(smu, clk_type))
1218		return 0;
1219
1220	clk_id = smu_cmn_to_asic_specific_index(smu,
1221						CMN2ASIC_MAPPING_CLK,
1222						clk_type);
1223	if (clk_id < 0)
1224		return clk_id;
1225
1226	if (max > 0) {
1227		param = (uint32_t)((clk_id << 16) | (max & 0xffff));
1228		ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMaxByFreq,
1229						      param, NULL);
1230		if (ret)
1231			return ret;
1232	}
1233
1234	if (min > 0) {
1235		param = (uint32_t)((clk_id << 16) | (min & 0xffff));
1236		ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinByFreq,
1237						      param, NULL);
1238		if (ret)
1239			return ret;
1240	}
1241
1242	return ret;
1243}
1244
1245int smu_v14_0_set_performance_level(struct smu_context *smu,
1246				    enum amd_dpm_forced_level level)
1247{
1248	struct smu_14_0_dpm_context *dpm_context =
1249		smu->smu_dpm.dpm_context;
1250	struct smu_14_0_dpm_table *gfx_table =
1251		&dpm_context->dpm_tables.gfx_table;
1252	struct smu_14_0_dpm_table *mem_table =
1253		&dpm_context->dpm_tables.uclk_table;
1254	struct smu_14_0_dpm_table *soc_table =
1255		&dpm_context->dpm_tables.soc_table;
1256	struct smu_14_0_dpm_table *vclk_table =
1257		&dpm_context->dpm_tables.vclk_table;
1258	struct smu_14_0_dpm_table *dclk_table =
1259		&dpm_context->dpm_tables.dclk_table;
1260	struct smu_14_0_dpm_table *fclk_table =
1261		&dpm_context->dpm_tables.fclk_table;
1262	struct smu_umd_pstate_table *pstate_table =
1263		&smu->pstate_table;
1264	struct amdgpu_device *adev = smu->adev;
1265	uint32_t sclk_min = 0, sclk_max = 0;
1266	uint32_t mclk_min = 0, mclk_max = 0;
1267	uint32_t socclk_min = 0, socclk_max = 0;
1268	uint32_t vclk_min = 0, vclk_max = 0;
1269	uint32_t dclk_min = 0, dclk_max = 0;
1270	uint32_t fclk_min = 0, fclk_max = 0;
1271	int ret = 0, i;
1272	bool auto_level = false;
1273
1274	switch (level) {
1275	case AMD_DPM_FORCED_LEVEL_HIGH:
1276		sclk_min = sclk_max = gfx_table->max;
1277		mclk_min = mclk_max = mem_table->max;
1278		socclk_min = socclk_max = soc_table->max;
1279		vclk_min = vclk_max = vclk_table->max;
1280		dclk_min = dclk_max = dclk_table->max;
1281		fclk_min = fclk_max = fclk_table->max;
1282		break;
1283	case AMD_DPM_FORCED_LEVEL_LOW:
1284		sclk_min = sclk_max = gfx_table->min;
1285		mclk_min = mclk_max = mem_table->min;
1286		socclk_min = socclk_max = soc_table->min;
1287		vclk_min = vclk_max = vclk_table->min;
1288		dclk_min = dclk_max = dclk_table->min;
1289		fclk_min = fclk_max = fclk_table->min;
1290		break;
1291	case AMD_DPM_FORCED_LEVEL_AUTO:
1292		sclk_min = gfx_table->min;
1293		sclk_max = gfx_table->max;
1294		mclk_min = mem_table->min;
1295		mclk_max = mem_table->max;
1296		socclk_min = soc_table->min;
1297		socclk_max = soc_table->max;
1298		vclk_min = vclk_table->min;
1299		vclk_max = vclk_table->max;
1300		dclk_min = dclk_table->min;
1301		dclk_max = dclk_table->max;
1302		fclk_min = fclk_table->min;
1303		fclk_max = fclk_table->max;
1304		auto_level = true;
1305		break;
1306	case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
1307		sclk_min = sclk_max = pstate_table->gfxclk_pstate.standard;
1308		mclk_min = mclk_max = pstate_table->uclk_pstate.standard;
1309		socclk_min = socclk_max = pstate_table->socclk_pstate.standard;
1310		vclk_min = vclk_max = pstate_table->vclk_pstate.standard;
1311		dclk_min = dclk_max = pstate_table->dclk_pstate.standard;
1312		fclk_min = fclk_max = pstate_table->fclk_pstate.standard;
1313		break;
1314	case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
1315		sclk_min = sclk_max = pstate_table->gfxclk_pstate.min;
1316		break;
1317	case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
1318		mclk_min = mclk_max = pstate_table->uclk_pstate.min;
1319		break;
1320	case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
1321		sclk_min = sclk_max = pstate_table->gfxclk_pstate.peak;
1322		mclk_min = mclk_max = pstate_table->uclk_pstate.peak;
1323		socclk_min = socclk_max = pstate_table->socclk_pstate.peak;
1324		vclk_min = vclk_max = pstate_table->vclk_pstate.peak;
1325		dclk_min = dclk_max = pstate_table->dclk_pstate.peak;
1326		fclk_min = fclk_max = pstate_table->fclk_pstate.peak;
1327		break;
1328	case AMD_DPM_FORCED_LEVEL_MANUAL:
1329	case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
1330		return 0;
1331	default:
1332		dev_err(adev->dev, "Invalid performance level %d\n", level);
1333		return -EINVAL;
1334	}
1335
1336	if (sclk_min && sclk_max) {
1337		ret = smu_v14_0_set_soft_freq_limited_range(smu,
1338							    SMU_GFXCLK,
1339							    sclk_min,
1340							    sclk_max,
1341							    auto_level);
1342		if (ret)
1343			return ret;
1344
1345		pstate_table->gfxclk_pstate.curr.min = sclk_min;
1346		pstate_table->gfxclk_pstate.curr.max = sclk_max;
1347	}
1348
1349	if (mclk_min && mclk_max) {
1350		ret = smu_v14_0_set_soft_freq_limited_range(smu,
1351							    SMU_MCLK,
1352							    mclk_min,
1353							    mclk_max,
1354							    auto_level);
1355		if (ret)
1356			return ret;
1357
1358		pstate_table->uclk_pstate.curr.min = mclk_min;
1359		pstate_table->uclk_pstate.curr.max = mclk_max;
1360	}
1361
1362	if (socclk_min && socclk_max) {
1363		ret = smu_v14_0_set_soft_freq_limited_range(smu,
1364							    SMU_SOCCLK,
1365							    socclk_min,
1366							    socclk_max,
1367							    auto_level);
1368		if (ret)
1369			return ret;
1370
1371		pstate_table->socclk_pstate.curr.min = socclk_min;
1372		pstate_table->socclk_pstate.curr.max = socclk_max;
1373	}
1374
1375	if (vclk_min && vclk_max) {
1376		for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
1377			if (adev->vcn.harvest_config & (1 << i))
1378				continue;
1379			ret = smu_v14_0_set_soft_freq_limited_range(smu,
1380								    i ? SMU_VCLK1 : SMU_VCLK,
1381								    vclk_min,
1382								    vclk_max,
1383								    auto_level);
1384			if (ret)
1385				return ret;
1386		}
1387		pstate_table->vclk_pstate.curr.min = vclk_min;
1388		pstate_table->vclk_pstate.curr.max = vclk_max;
1389	}
1390
1391	if (dclk_min && dclk_max) {
1392		for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
1393			if (adev->vcn.harvest_config & (1 << i))
1394				continue;
1395			ret = smu_v14_0_set_soft_freq_limited_range(smu,
1396								    i ? SMU_DCLK1 : SMU_DCLK,
1397								    dclk_min,
1398								    dclk_max,
1399								    auto_level);
1400			if (ret)
1401				return ret;
1402		}
1403		pstate_table->dclk_pstate.curr.min = dclk_min;
1404		pstate_table->dclk_pstate.curr.max = dclk_max;
1405	}
1406
1407	if (fclk_min && fclk_max) {
1408		ret = smu_v14_0_set_soft_freq_limited_range(smu,
1409							    SMU_FCLK,
1410							    fclk_min,
1411							    fclk_max,
1412							    auto_level);
1413		if (ret)
1414			return ret;
1415
1416		pstate_table->fclk_pstate.curr.min = fclk_min;
1417		pstate_table->fclk_pstate.curr.max = fclk_max;
1418	}
1419
1420	return ret;
1421}
1422
1423int smu_v14_0_set_power_source(struct smu_context *smu,
1424			       enum smu_power_src_type power_src)
1425{
1426	int pwr_source;
1427
1428	pwr_source = smu_cmn_to_asic_specific_index(smu,
1429						    CMN2ASIC_MAPPING_PWR,
1430						    (uint32_t)power_src);
1431	if (pwr_source < 0)
1432		return -EINVAL;
1433
1434	return smu_cmn_send_smc_msg_with_param(smu,
1435					       SMU_MSG_NotifyPowerSource,
1436					       pwr_source,
1437					       NULL);
1438}
1439
1440static int smu_v14_0_get_dpm_freq_by_index(struct smu_context *smu,
1441					   enum smu_clk_type clk_type,
1442					   uint16_t level,
1443					   uint32_t *value)
1444{
1445	int ret = 0, clk_id = 0;
1446	uint32_t param;
1447
1448	if (!value)
1449		return -EINVAL;
1450
1451	if (!smu_cmn_clk_dpm_is_enabled(smu, clk_type))
1452		return 0;
1453
1454	clk_id = smu_cmn_to_asic_specific_index(smu,
1455						CMN2ASIC_MAPPING_CLK,
1456						clk_type);
1457	if (clk_id < 0)
1458		return clk_id;
1459
1460	param = (uint32_t)(((clk_id & 0xffff) << 16) | (level & 0xffff));
1461
1462	ret = smu_cmn_send_smc_msg_with_param(smu,
1463					      SMU_MSG_GetDpmFreqByIndex,
1464					      param,
1465					      value);
1466	if (ret)
1467		return ret;
1468
1469	*value = *value & 0x7fffffff;
1470
1471	return ret;
1472}
1473
1474static int smu_v14_0_get_dpm_level_count(struct smu_context *smu,
1475					 enum smu_clk_type clk_type,
1476					 uint32_t *value)
1477{
1478	int ret;
1479
1480	ret = smu_v14_0_get_dpm_freq_by_index(smu, clk_type, 0xff, value);
1481
1482	return ret;
1483}
1484
1485static int smu_v14_0_get_fine_grained_status(struct smu_context *smu,
1486					     enum smu_clk_type clk_type,
1487					     bool *is_fine_grained_dpm)
1488{
1489	int ret = 0, clk_id = 0;
1490	uint32_t param;
1491	uint32_t value;
1492
1493	if (!is_fine_grained_dpm)
1494		return -EINVAL;
1495
1496	if (!smu_cmn_clk_dpm_is_enabled(smu, clk_type))
1497		return 0;
1498
1499	clk_id = smu_cmn_to_asic_specific_index(smu,
1500						CMN2ASIC_MAPPING_CLK,
1501						clk_type);
1502	if (clk_id < 0)
1503		return clk_id;
1504
1505	param = (uint32_t)(((clk_id & 0xffff) << 16) | 0xff);
1506
1507	ret = smu_cmn_send_smc_msg_with_param(smu,
1508					      SMU_MSG_GetDpmFreqByIndex,
1509					      param,
1510					      &value);
1511	if (ret)
1512		return ret;
1513
1514	/*
1515	 * BIT31:  1 - Fine grained DPM, 0 - Dicrete DPM
1516	 * now, we un-support it
1517	 */
1518	*is_fine_grained_dpm = value & 0x80000000;
1519
1520	return 0;
1521}
1522
1523int smu_v14_0_set_single_dpm_table(struct smu_context *smu,
1524				   enum smu_clk_type clk_type,
1525				   struct smu_14_0_dpm_table *single_dpm_table)
1526{
1527	int ret = 0;
1528	uint32_t clk;
1529	int i;
1530
1531	ret = smu_v14_0_get_dpm_level_count(smu,
1532					    clk_type,
1533					    &single_dpm_table->count);
1534	if (ret) {
1535		dev_err(smu->adev->dev, "[%s] failed to get dpm levels!\n", __func__);
1536		return ret;
1537	}
1538
1539	ret = smu_v14_0_get_fine_grained_status(smu,
1540						clk_type,
1541						&single_dpm_table->is_fine_grained);
1542	if (ret) {
1543		dev_err(smu->adev->dev, "[%s] failed to get fine grained status!\n", __func__);
1544		return ret;
1545	}
1546
1547	for (i = 0; i < single_dpm_table->count; i++) {
1548		ret = smu_v14_0_get_dpm_freq_by_index(smu,
1549						      clk_type,
1550						      i,
1551						      &clk);
1552		if (ret) {
1553			dev_err(smu->adev->dev, "[%s] failed to get dpm freq by index!\n", __func__);
1554			return ret;
1555		}
1556
1557		single_dpm_table->dpm_levels[i].value = clk;
1558		single_dpm_table->dpm_levels[i].enabled = true;
1559
1560		if (i == 0)
1561			single_dpm_table->min = clk;
1562		else if (i == single_dpm_table->count - 1)
1563			single_dpm_table->max = clk;
1564	}
1565
1566	return 0;
1567}
1568
1569int smu_v14_0_set_vcn_enable(struct smu_context *smu,
1570			      bool enable,
1571			      int inst)
1572{
1573	struct amdgpu_device *adev = smu->adev;
1574	int ret = 0;
1575
1576	if (adev->vcn.harvest_config & (1 << inst))
1577		return ret;
1578
1579	if (smu->is_apu) {
1580		if (inst == 0)
1581			ret = smu_cmn_send_smc_msg_with_param(smu, enable ?
1582							      SMU_MSG_PowerUpVcn0 : SMU_MSG_PowerDownVcn0,
1583							      inst << 16U, NULL);
1584		else if (inst == 1)
1585			ret = smu_cmn_send_smc_msg_with_param(smu, enable ?
1586							      SMU_MSG_PowerUpVcn1 : SMU_MSG_PowerDownVcn1,
1587							      inst << 16U, NULL);
1588	} else {
1589		ret = smu_cmn_send_smc_msg_with_param(smu, enable ?
1590						      SMU_MSG_PowerUpVcn : SMU_MSG_PowerDownVcn,
1591						      inst << 16U, NULL);
1592	}
1593
1594	return ret;
1595}
1596
1597int smu_v14_0_set_jpeg_enable(struct smu_context *smu,
1598			      bool enable)
1599{
1600	struct amdgpu_device *adev = smu->adev;
1601	int i, ret = 0;
1602
1603	for (i = 0; i < adev->jpeg.num_jpeg_inst; i++) {
1604		if (adev->jpeg.harvest_config & (1 << i))
1605			continue;
1606
1607		if (smu->is_apu) {
1608			if (i == 0)
1609				ret = smu_cmn_send_smc_msg_with_param(smu, enable ?
1610								      SMU_MSG_PowerUpJpeg0 : SMU_MSG_PowerDownJpeg0,
1611								      i << 16U, NULL);
1612			else if (i == 1 && amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(14, 0, 1))
1613				ret = smu_cmn_send_smc_msg_with_param(smu, enable ?
1614								      SMU_MSG_PowerUpJpeg1 : SMU_MSG_PowerDownJpeg1,
1615								      i << 16U, NULL);
1616		} else {
1617			ret = smu_cmn_send_smc_msg_with_param(smu, enable ?
1618							      SMU_MSG_PowerUpJpeg : SMU_MSG_PowerDownJpeg,
1619							      i << 16U, NULL);
1620		}
1621
1622		if (ret)
1623			return ret;
1624	}
1625
1626	return ret;
1627}
1628
1629int smu_v14_0_run_btc(struct smu_context *smu)
1630{
1631	int res;
1632
1633	res = smu_cmn_send_smc_msg(smu, SMU_MSG_RunDcBtc, NULL);
1634	if (res)
1635		dev_err(smu->adev->dev, "RunDcBtc failed!\n");
1636
1637	return res;
1638}
1639
1640int smu_v14_0_gpo_control(struct smu_context *smu,
1641			  bool enablement)
1642{
1643	int res;
1644
1645	res = smu_cmn_send_smc_msg_with_param(smu,
1646					      SMU_MSG_AllowGpo,
1647					      enablement ? 1 : 0,
1648					      NULL);
1649	if (res)
1650		dev_err(smu->adev->dev, "SetGpoAllow %d failed!\n", enablement);
1651
1652	return res;
1653}
1654
1655int smu_v14_0_deep_sleep_control(struct smu_context *smu,
1656				 bool enablement)
1657{
1658	struct amdgpu_device *adev = smu->adev;
1659	int ret = 0;
1660
1661	if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_GFXCLK_BIT)) {
1662		ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_DS_GFXCLK_BIT, enablement);
1663		if (ret) {
1664			dev_err(adev->dev, "Failed to %s GFXCLK DS!\n", enablement ? "enable" : "disable");
1665			return ret;
1666		}
1667	}
1668
1669	if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_UCLK_BIT)) {
1670		ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_DS_UCLK_BIT, enablement);
1671		if (ret) {
1672			dev_err(adev->dev, "Failed to %s UCLK DS!\n", enablement ? "enable" : "disable");
1673			return ret;
1674		}
1675	}
1676
1677	if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_FCLK_BIT)) {
1678		ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_DS_FCLK_BIT, enablement);
1679		if (ret) {
1680			dev_err(adev->dev, "Failed to %s FCLK DS!\n", enablement ? "enable" : "disable");
1681			return ret;
1682		}
1683	}
1684
1685	if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_SOCCLK_BIT)) {
1686		ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_DS_SOCCLK_BIT, enablement);
1687		if (ret) {
1688			dev_err(adev->dev, "Failed to %s SOCCLK DS!\n", enablement ? "enable" : "disable");
1689			return ret;
1690		}
1691	}
1692
1693	if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_LCLK_BIT)) {
1694		ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_DS_LCLK_BIT, enablement);
1695		if (ret) {
1696			dev_err(adev->dev, "Failed to %s LCLK DS!\n", enablement ? "enable" : "disable");
1697			return ret;
1698		}
1699	}
1700
1701	if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_VCN_BIT)) {
1702		ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_DS_VCN_BIT, enablement);
1703		if (ret) {
1704			dev_err(adev->dev, "Failed to %s VCN DS!\n", enablement ? "enable" : "disable");
1705			return ret;
1706		}
1707	}
1708
1709	if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_MP0CLK_BIT)) {
1710		ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_DS_MP0CLK_BIT, enablement);
1711		if (ret) {
1712			dev_err(adev->dev, "Failed to %s MP0/MPIOCLK DS!\n", enablement ? "enable" : "disable");
1713			return ret;
1714		}
1715	}
1716
1717	if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_MP1CLK_BIT)) {
1718		ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_DS_MP1CLK_BIT, enablement);
1719		if (ret) {
1720			dev_err(adev->dev, "Failed to %s MP1CLK DS!\n", enablement ? "enable" : "disable");
1721			return ret;
1722		}
1723	}
1724
1725	return ret;
1726}
1727
1728int smu_v14_0_gfx_ulv_control(struct smu_context *smu,
1729			      bool enablement)
1730{
1731	int ret = 0;
1732
1733	if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_GFX_ULV_BIT))
1734		ret = smu_cmn_feature_set_enabled(smu, SMU_FEATURE_GFX_ULV_BIT, enablement);
1735
1736	return ret;
1737}
1738
1739int smu_v14_0_baco_set_armd3_sequence(struct smu_context *smu,
1740				      enum smu_baco_seq baco_seq)
1741{
1742	struct smu_baco_context *smu_baco = &smu->smu_baco;
1743	int ret;
1744
1745	ret = smu_cmn_send_smc_msg_with_param(smu,
1746					      SMU_MSG_ArmD3,
1747					      baco_seq,
1748					      NULL);
1749	if (ret)
1750		return ret;
1751
1752	if (baco_seq == BACO_SEQ_BAMACO ||
1753	    baco_seq == BACO_SEQ_BACO)
1754		smu_baco->state = SMU_BACO_STATE_ENTER;
1755	else
1756		smu_baco->state = SMU_BACO_STATE_EXIT;
1757
1758	return 0;
1759}
1760
1761int smu_v14_0_get_bamaco_support(struct smu_context *smu)
1762{
1763	struct smu_baco_context *smu_baco = &smu->smu_baco;
1764	int bamaco_support = 0;
1765
1766	if (amdgpu_sriov_vf(smu->adev) ||
1767	    !smu_baco->platform_support)
1768		return 0;
1769
1770	if (smu_baco->maco_support)
1771		bamaco_support |= MACO_SUPPORT;
1772
1773	/* return true if ASIC is in BACO state already */
1774	if (smu_v14_0_baco_get_state(smu) == SMU_BACO_STATE_ENTER)
1775		return (bamaco_support |= BACO_SUPPORT);
1776
1777	if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_BACO_BIT) &&
1778	    !smu_cmn_feature_is_enabled(smu, SMU_FEATURE_BACO_BIT))
1779		return 0;
1780
1781	return (bamaco_support |= BACO_SUPPORT);
1782}
1783
1784enum smu_baco_state smu_v14_0_baco_get_state(struct smu_context *smu)
1785{
1786	struct smu_baco_context *smu_baco = &smu->smu_baco;
1787
1788	return smu_baco->state;
1789}
1790
1791int smu_v14_0_baco_set_state(struct smu_context *smu,
1792			     enum smu_baco_state state)
1793{
1794	struct smu_baco_context *smu_baco = &smu->smu_baco;
1795	struct amdgpu_device *adev = smu->adev;
1796	int ret = 0;
1797
1798	if (smu_v14_0_baco_get_state(smu) == state)
1799		return 0;
1800
1801	if (state == SMU_BACO_STATE_ENTER) {
1802		ret = smu_cmn_send_smc_msg_with_param(smu,
1803						      SMU_MSG_EnterBaco,
1804						      (adev->pm.rpm_mode == AMDGPU_RUNPM_BAMACO) ?
1805						      BACO_SEQ_BAMACO : BACO_SEQ_BACO,
1806						      NULL);
1807	} else {
1808		ret = smu_cmn_send_smc_msg(smu,
1809					   SMU_MSG_ExitBaco,
1810					   NULL);
1811		if (ret)
1812			return ret;
1813
1814		/* clear vbios scratch 6 and 7 for coming asic reinit */
1815		WREG32(adev->bios_scratch_reg_offset + 6, 0);
1816		WREG32(adev->bios_scratch_reg_offset + 7, 0);
1817	}
1818
1819	if (!ret)
1820		smu_baco->state = state;
1821
1822	return ret;
1823}
1824
1825int smu_v14_0_baco_enter(struct smu_context *smu)
1826{
1827	int ret = 0;
1828
1829	ret = smu_v14_0_baco_set_state(smu,
1830				       SMU_BACO_STATE_ENTER);
1831	if (ret)
1832		return ret;
1833
1834	msleep(10);
1835
1836	return ret;
1837}
1838
1839int smu_v14_0_baco_exit(struct smu_context *smu)
1840{
1841	return smu_v14_0_baco_set_state(smu,
1842					SMU_BACO_STATE_EXIT);
1843}
1844
1845int smu_v14_0_set_gfx_power_up_by_imu(struct smu_context *smu)
1846{
1847	uint16_t index;
1848	struct amdgpu_device *adev = smu->adev;
1849
1850	if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
1851		return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_EnableGfxImu,
1852						       ENABLE_IMU_ARG_GFXOFF_ENABLE, NULL);
1853	}
1854
1855	index = smu_cmn_to_asic_specific_index(smu, CMN2ASIC_MAPPING_MSG,
1856					       SMU_MSG_EnableGfxImu);
1857	return smu_cmn_send_msg_without_waiting(smu, index, ENABLE_IMU_ARG_GFXOFF_ENABLE);
1858}
1859
1860int smu_v14_0_set_default_dpm_tables(struct smu_context *smu)
1861{
1862	struct smu_table_context *smu_table = &smu->smu_table;
1863
1864	return smu_cmn_update_table(smu, SMU_TABLE_DPMCLOCKS, 0,
1865				    smu_table->clocks_table, false);
1866}
1867
1868int smu_v14_0_od_edit_dpm_table(struct smu_context *smu,
1869				enum PP_OD_DPM_TABLE_COMMAND type,
1870				long input[], uint32_t size)
1871{
1872	struct smu_dpm_context *smu_dpm = &(smu->smu_dpm);
1873	int ret = 0;
1874
1875	/* Only allowed in manual mode */
1876	if (smu_dpm->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL)
1877		return -EINVAL;
1878
1879	switch (type) {
1880	case PP_OD_EDIT_SCLK_VDDC_TABLE:
1881		if (size != 2) {
1882			dev_err(smu->adev->dev, "Input parameter number not correct\n");
1883			return -EINVAL;
1884		}
1885
1886		if (input[0] == 0) {
1887			if (input[1] < smu->gfx_default_hard_min_freq) {
1888				dev_warn(smu->adev->dev,
1889					 "Fine grain setting minimum sclk (%ld) MHz is less than the minimum allowed (%d) MHz\n",
1890					 input[1], smu->gfx_default_hard_min_freq);
1891				return -EINVAL;
1892			}
1893			smu->gfx_actual_hard_min_freq = input[1];
1894		} else if (input[0] == 1) {
1895			if (input[1] > smu->gfx_default_soft_max_freq) {
1896				dev_warn(smu->adev->dev,
1897					 "Fine grain setting maximum sclk (%ld) MHz is greater than the maximum allowed (%d) MHz\n",
1898					 input[1], smu->gfx_default_soft_max_freq);
1899				return -EINVAL;
1900			}
1901			smu->gfx_actual_soft_max_freq = input[1];
1902		} else {
1903			return -EINVAL;
1904		}
1905		break;
1906	case PP_OD_RESTORE_DEFAULT_TABLE:
1907		if (size != 0) {
1908			dev_err(smu->adev->dev, "Input parameter number not correct\n");
1909			return -EINVAL;
1910		}
1911		smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
1912		smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
1913		break;
1914	case PP_OD_COMMIT_DPM_TABLE:
1915		if (size != 0) {
1916			dev_err(smu->adev->dev, "Input parameter number not correct\n");
1917			return -EINVAL;
1918		}
1919		if (smu->gfx_actual_hard_min_freq > smu->gfx_actual_soft_max_freq) {
1920			dev_err(smu->adev->dev,
1921				"The setting minimum sclk (%d) MHz is greater than the setting maximum sclk (%d) MHz\n",
1922				smu->gfx_actual_hard_min_freq,
1923				smu->gfx_actual_soft_max_freq);
1924			return -EINVAL;
1925		}
1926
1927		ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinGfxClk,
1928						      smu->gfx_actual_hard_min_freq,
1929						      NULL);
1930		if (ret) {
1931			dev_err(smu->adev->dev, "Set hard min sclk failed!");
1932			return ret;
1933		}
1934
1935		ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk,
1936						      smu->gfx_actual_soft_max_freq,
1937						      NULL);
1938		if (ret) {
1939			dev_err(smu->adev->dev, "Set soft max sclk failed!");
1940			return ret;
1941		}
1942		if (smu->gfx_actual_hard_min_freq != smu->gfx_default_hard_min_freq ||
1943		    smu->gfx_actual_soft_max_freq != smu->gfx_default_soft_max_freq)
1944			smu->user_dpm_profile.user_od = true;
1945		else
1946			smu->user_dpm_profile.user_od = false;
1947		break;
1948	default:
1949		return -ENOSYS;
1950	}
1951
1952	return ret;
1953}
1954
1955static int smu_v14_0_allow_ih_interrupt(struct smu_context *smu)
1956{
1957	return smu_cmn_send_smc_msg(smu,
1958				    SMU_MSG_AllowIHHostInterrupt,
1959				    NULL);
1960}
1961
1962int smu_v14_0_enable_thermal_alert(struct smu_context *smu)
1963{
1964	int ret = 0;
1965
1966	if (!smu->irq_source.num_types)
1967		return 0;
1968
1969	ret = amdgpu_irq_get(smu->adev, &smu->irq_source, 0);
1970	if (ret)
1971		return ret;
1972
1973	return smu_v14_0_allow_ih_interrupt(smu);
1974}
1975
1976int smu_v14_0_disable_thermal_alert(struct smu_context *smu)
1977{
1978	if (!smu->irq_source.num_types)
1979		return 0;
1980
1981	return amdgpu_irq_put(smu->adev, &smu->irq_source, 0);
1982}
~/ Read-only file preview.