Linux Audio

Check our new training course

Linux BSP development engineering services

Need help to port Linux and bootloaders to your hardware?
Loading...
Note: File does not exist in v6.9.4.
   1/*
   2 * Copyright 2014 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 "drmP.h"
  25#include "amdgpu.h"
  26#include "smu8.h"
  27#include "smu8_fusion.h"
  28#include "cz_ppsmc.h"
  29#include "cz_smumgr.h"
  30#include "smu_ucode_xfer_cz.h"
  31#include "amdgpu_ucode.h"
  32
  33#include "smu/smu_8_0_d.h"
  34#include "smu/smu_8_0_sh_mask.h"
  35#include "gca/gfx_8_0_d.h"
  36#include "gca/gfx_8_0_sh_mask.h"
  37
  38uint32_t cz_get_argument(struct amdgpu_device *adev)
  39{
  40	return RREG32(mmSMU_MP1_SRBM2P_ARG_0);
  41}
  42
  43static struct cz_smu_private_data *cz_smu_get_priv(struct amdgpu_device *adev)
  44{
  45	struct cz_smu_private_data *priv =
  46			(struct cz_smu_private_data *)(adev->smu.priv);
  47
  48	return priv;
  49}
  50
  51int cz_send_msg_to_smc_async(struct amdgpu_device *adev, u16 msg)
  52{
  53	int i;
  54	u32 content = 0, tmp;
  55
  56	for (i = 0; i < adev->usec_timeout; i++) {
  57		tmp = REG_GET_FIELD(RREG32(mmSMU_MP1_SRBM2P_RESP_0),
  58				SMU_MP1_SRBM2P_RESP_0, CONTENT);
  59		if (content != tmp)
  60			break;
  61		udelay(1);
  62	}
  63
  64	/* timeout means wrong logic*/
  65	if (i == adev->usec_timeout)
  66		return -EINVAL;
  67
  68	WREG32(mmSMU_MP1_SRBM2P_RESP_0, 0);
  69	WREG32(mmSMU_MP1_SRBM2P_MSG_0, msg);
  70
  71	return 0;
  72}
  73
  74int cz_send_msg_to_smc(struct amdgpu_device *adev, u16 msg)
  75{
  76	int i;
  77	u32 content = 0, tmp = 0;
  78
  79	if (cz_send_msg_to_smc_async(adev, msg))
  80		return -EINVAL;
  81
  82	for (i = 0; i < adev->usec_timeout; i++) {
  83		tmp = REG_GET_FIELD(RREG32(mmSMU_MP1_SRBM2P_RESP_0),
  84				SMU_MP1_SRBM2P_RESP_0, CONTENT);
  85		if (content != tmp)
  86			break;
  87		udelay(1);
  88	}
  89
  90	/* timeout means wrong logic*/
  91	if (i == adev->usec_timeout)
  92		return -EINVAL;
  93
  94	if (PPSMC_Result_OK != tmp) {
  95		dev_err(adev->dev, "SMC Failed to send Message.\n");
  96		return -EINVAL;
  97	}
  98
  99	return 0;
 100}
 101
 102int cz_send_msg_to_smc_with_parameter_async(struct amdgpu_device *adev,
 103						u16 msg, u32 parameter)
 104{
 105	WREG32(mmSMU_MP1_SRBM2P_ARG_0, parameter);
 106	return cz_send_msg_to_smc_async(adev, msg);
 107}
 108
 109int cz_send_msg_to_smc_with_parameter(struct amdgpu_device *adev,
 110						u16 msg, u32 parameter)
 111{
 112	WREG32(mmSMU_MP1_SRBM2P_ARG_0, parameter);
 113	return cz_send_msg_to_smc(adev, msg);
 114}
 115
 116static int cz_set_smc_sram_address(struct amdgpu_device *adev,
 117						u32 smc_address, u32 limit)
 118{
 119	if (smc_address & 3)
 120		return -EINVAL;
 121	if ((smc_address + 3) > limit)
 122		return -EINVAL;
 123
 124	WREG32(mmMP0PUB_IND_INDEX_0, SMN_MP1_SRAM_START_ADDR + smc_address);
 125
 126	return 0;
 127}
 128
 129int cz_read_smc_sram_dword(struct amdgpu_device *adev, u32 smc_address,
 130						u32 *value, u32 limit)
 131{
 132	int ret;
 133
 134	ret = cz_set_smc_sram_address(adev, smc_address, limit);
 135	if (ret)
 136		return ret;
 137
 138	*value = RREG32(mmMP0PUB_IND_DATA_0);
 139
 140	return 0;
 141}
 142
 143int cz_write_smc_sram_dword(struct amdgpu_device *adev, u32 smc_address,
 144						u32 value, u32 limit)
 145{
 146	int ret;
 147
 148	ret = cz_set_smc_sram_address(adev, smc_address, limit);
 149	if (ret)
 150		return ret;
 151
 152	WREG32(mmMP0PUB_IND_DATA_0, value);
 153
 154	return 0;
 155}
 156
 157static int cz_smu_request_load_fw(struct amdgpu_device *adev)
 158{
 159	struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
 160
 161	uint32_t smc_addr = SMU8_FIRMWARE_HEADER_LOCATION +
 162			offsetof(struct SMU8_Firmware_Header, UcodeLoadStatus);
 163
 164	cz_write_smc_sram_dword(adev, smc_addr, 0, smc_addr + 4);
 165
 166	/*prepare toc buffers*/
 167	cz_send_msg_to_smc_with_parameter(adev,
 168				PPSMC_MSG_DriverDramAddrHi,
 169				priv->toc_buffer.mc_addr_high);
 170	cz_send_msg_to_smc_with_parameter(adev,
 171				PPSMC_MSG_DriverDramAddrLo,
 172				priv->toc_buffer.mc_addr_low);
 173	cz_send_msg_to_smc(adev, PPSMC_MSG_InitJobs);
 174
 175	/*execute jobs*/
 176	cz_send_msg_to_smc_with_parameter(adev,
 177				PPSMC_MSG_ExecuteJob,
 178				priv->toc_entry_aram);
 179
 180	cz_send_msg_to_smc_with_parameter(adev,
 181				PPSMC_MSG_ExecuteJob,
 182				priv->toc_entry_power_profiling_index);
 183
 184	cz_send_msg_to_smc_with_parameter(adev,
 185				PPSMC_MSG_ExecuteJob,
 186				priv->toc_entry_initialize_index);
 187
 188	return 0;
 189}
 190
 191/*
 192 *Check if the FW has been loaded, SMU will not return if loading
 193 *has not finished.
 194 */
 195static int cz_smu_check_fw_load_finish(struct amdgpu_device *adev,
 196						uint32_t fw_mask)
 197{
 198	int i;
 199	uint32_t index = SMN_MP1_SRAM_START_ADDR +
 200			SMU8_FIRMWARE_HEADER_LOCATION +
 201			offsetof(struct SMU8_Firmware_Header, UcodeLoadStatus);
 202
 203	WREG32(mmMP0PUB_IND_INDEX, index);
 204
 205	for (i = 0; i < adev->usec_timeout; i++) {
 206		if (fw_mask == (RREG32(mmMP0PUB_IND_DATA) & fw_mask))
 207			break;
 208		udelay(1);
 209	}
 210
 211	if (i >= adev->usec_timeout) {
 212		dev_err(adev->dev,
 213		"SMU check loaded firmware failed, expecting 0x%x, getting 0x%x",
 214		fw_mask, RREG32(mmMP0PUB_IND_DATA));
 215		return -EINVAL;
 216	}
 217
 218	return 0;
 219}
 220
 221/*
 222 * interfaces for different ip blocks to check firmware loading status
 223 * 0 for success otherwise failed
 224 */
 225static int cz_smu_check_finished(struct amdgpu_device *adev,
 226							enum AMDGPU_UCODE_ID id)
 227{
 228	switch (id) {
 229	case AMDGPU_UCODE_ID_SDMA0:
 230		if (adev->smu.fw_flags & AMDGPU_SDMA0_UCODE_LOADED)
 231			return 0;
 232		break;
 233	case AMDGPU_UCODE_ID_SDMA1:
 234		if (adev->smu.fw_flags & AMDGPU_SDMA1_UCODE_LOADED)
 235			return 0;
 236		break;
 237	case AMDGPU_UCODE_ID_CP_CE:
 238		if (adev->smu.fw_flags & AMDGPU_CPCE_UCODE_LOADED)
 239			return 0;
 240		break;
 241	case AMDGPU_UCODE_ID_CP_PFP:
 242		if (adev->smu.fw_flags & AMDGPU_CPPFP_UCODE_LOADED)
 243			return 0;
 244	case AMDGPU_UCODE_ID_CP_ME:
 245		if (adev->smu.fw_flags & AMDGPU_CPME_UCODE_LOADED)
 246			return 0;
 247		break;
 248	case AMDGPU_UCODE_ID_CP_MEC1:
 249		if (adev->smu.fw_flags & AMDGPU_CPMEC1_UCODE_LOADED)
 250			return 0;
 251		break;
 252	case AMDGPU_UCODE_ID_CP_MEC2:
 253		if (adev->smu.fw_flags & AMDGPU_CPMEC2_UCODE_LOADED)
 254			return 0;
 255		break;
 256	case AMDGPU_UCODE_ID_RLC_G:
 257		if (adev->smu.fw_flags & AMDGPU_CPRLC_UCODE_LOADED)
 258			return 0;
 259		break;
 260	case AMDGPU_UCODE_ID_MAXIMUM:
 261	default:
 262		break;
 263	}
 264
 265	return 1;
 266}
 267
 268static int cz_load_mec_firmware(struct amdgpu_device *adev)
 269{
 270	struct amdgpu_firmware_info *ucode =
 271				&adev->firmware.ucode[AMDGPU_UCODE_ID_CP_MEC1];
 272	uint32_t reg_data;
 273	uint32_t tmp;
 274
 275	if (ucode->fw == NULL)
 276		return -EINVAL;
 277
 278	/* Disable MEC parsing/prefetching */
 279	tmp = RREG32(mmCP_MEC_CNTL);
 280	tmp = REG_SET_FIELD(tmp, CP_MEC_CNTL, MEC_ME1_HALT, 1);
 281	tmp = REG_SET_FIELD(tmp, CP_MEC_CNTL, MEC_ME2_HALT, 1);
 282	WREG32(mmCP_MEC_CNTL, tmp);
 283
 284	tmp = RREG32(mmCP_CPC_IC_BASE_CNTL);
 285	tmp = REG_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, VMID, 0);
 286	tmp = REG_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, ATC, 0);
 287	tmp = REG_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, CACHE_POLICY, 0);
 288	tmp = REG_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, MTYPE, 1);
 289	WREG32(mmCP_CPC_IC_BASE_CNTL, tmp);
 290
 291	reg_data = lower_32_bits(ucode->mc_addr) &
 292			REG_FIELD_MASK(CP_CPC_IC_BASE_LO, IC_BASE_LO);
 293	WREG32(mmCP_CPC_IC_BASE_LO, reg_data);
 294
 295	reg_data = upper_32_bits(ucode->mc_addr) &
 296			REG_FIELD_MASK(CP_CPC_IC_BASE_HI, IC_BASE_HI);
 297	WREG32(mmCP_CPC_IC_BASE_HI, reg_data);
 298
 299	return 0;
 300}
 301
 302int cz_smu_start(struct amdgpu_device *adev)
 303{
 304	int ret = 0;
 305
 306	uint32_t fw_to_check = UCODE_ID_RLC_G_MASK |
 307				UCODE_ID_SDMA0_MASK |
 308				UCODE_ID_SDMA1_MASK |
 309				UCODE_ID_CP_CE_MASK |
 310				UCODE_ID_CP_ME_MASK |
 311				UCODE_ID_CP_PFP_MASK |
 312				UCODE_ID_CP_MEC_JT1_MASK |
 313				UCODE_ID_CP_MEC_JT2_MASK;
 314
 315	if (adev->asic_type == CHIP_STONEY)
 316		fw_to_check &= ~(UCODE_ID_SDMA1_MASK | UCODE_ID_CP_MEC_JT2_MASK);
 317
 318	cz_smu_request_load_fw(adev);
 319	ret = cz_smu_check_fw_load_finish(adev, fw_to_check);
 320	if (ret)
 321		return ret;
 322
 323	/* manually load MEC firmware for CZ */
 324	if (adev->asic_type == CHIP_CARRIZO || adev->asic_type == CHIP_STONEY) {
 325		ret = cz_load_mec_firmware(adev);
 326		if (ret) {
 327			dev_err(adev->dev, "(%d) Mec Firmware load failed\n", ret);
 328			return ret;
 329		}
 330	}
 331
 332	/* setup fw load flag */
 333	adev->smu.fw_flags = AMDGPU_SDMA0_UCODE_LOADED |
 334				AMDGPU_SDMA1_UCODE_LOADED |
 335				AMDGPU_CPCE_UCODE_LOADED |
 336				AMDGPU_CPPFP_UCODE_LOADED |
 337				AMDGPU_CPME_UCODE_LOADED |
 338				AMDGPU_CPMEC1_UCODE_LOADED |
 339				AMDGPU_CPMEC2_UCODE_LOADED |
 340				AMDGPU_CPRLC_UCODE_LOADED;
 341
 342	if (adev->asic_type == CHIP_STONEY)
 343		adev->smu.fw_flags &= ~(AMDGPU_SDMA1_UCODE_LOADED | AMDGPU_CPMEC2_UCODE_LOADED);
 344
 345	return ret;
 346}
 347
 348static uint32_t cz_convert_fw_type(uint32_t fw_type)
 349{
 350	enum AMDGPU_UCODE_ID result = AMDGPU_UCODE_ID_MAXIMUM;
 351
 352	switch (fw_type) {
 353	case UCODE_ID_SDMA0:
 354		result = AMDGPU_UCODE_ID_SDMA0;
 355		break;
 356	case UCODE_ID_SDMA1:
 357		result = AMDGPU_UCODE_ID_SDMA1;
 358		break;
 359	case UCODE_ID_CP_CE:
 360		result = AMDGPU_UCODE_ID_CP_CE;
 361		break;
 362	case UCODE_ID_CP_PFP:
 363		result = AMDGPU_UCODE_ID_CP_PFP;
 364		break;
 365	case UCODE_ID_CP_ME:
 366		result = AMDGPU_UCODE_ID_CP_ME;
 367		break;
 368	case UCODE_ID_CP_MEC_JT1:
 369	case UCODE_ID_CP_MEC_JT2:
 370		result = AMDGPU_UCODE_ID_CP_MEC1;
 371		break;
 372	case UCODE_ID_RLC_G:
 373		result = AMDGPU_UCODE_ID_RLC_G;
 374		break;
 375	default:
 376		DRM_ERROR("UCode type is out of range!");
 377	}
 378
 379	return result;
 380}
 381
 382static uint8_t cz_smu_translate_firmware_enum_to_arg(
 383			enum cz_scratch_entry firmware_enum)
 384{
 385	uint8_t ret = 0;
 386
 387	switch (firmware_enum) {
 388	case CZ_SCRATCH_ENTRY_UCODE_ID_SDMA0:
 389		ret = UCODE_ID_SDMA0;
 390		break;
 391	case CZ_SCRATCH_ENTRY_UCODE_ID_SDMA1:
 392		ret = UCODE_ID_SDMA1;
 393		break;
 394	case CZ_SCRATCH_ENTRY_UCODE_ID_CP_CE:
 395		ret = UCODE_ID_CP_CE;
 396		break;
 397	case CZ_SCRATCH_ENTRY_UCODE_ID_CP_PFP:
 398		ret = UCODE_ID_CP_PFP;
 399		break;
 400	case CZ_SCRATCH_ENTRY_UCODE_ID_CP_ME:
 401		ret = UCODE_ID_CP_ME;
 402		break;
 403	case CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1:
 404		ret = UCODE_ID_CP_MEC_JT1;
 405		break;
 406	case CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2:
 407		ret = UCODE_ID_CP_MEC_JT2;
 408		break;
 409	case CZ_SCRATCH_ENTRY_UCODE_ID_GMCON_RENG:
 410		ret = UCODE_ID_GMCON_RENG;
 411		break;
 412	case CZ_SCRATCH_ENTRY_UCODE_ID_RLC_G:
 413		ret = UCODE_ID_RLC_G;
 414		break;
 415	case CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SCRATCH:
 416		ret = UCODE_ID_RLC_SCRATCH;
 417		break;
 418	case CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_ARAM:
 419		ret = UCODE_ID_RLC_SRM_ARAM;
 420		break;
 421	case CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_DRAM:
 422		ret = UCODE_ID_RLC_SRM_DRAM;
 423		break;
 424	case CZ_SCRATCH_ENTRY_UCODE_ID_DMCU_ERAM:
 425		ret = UCODE_ID_DMCU_ERAM;
 426		break;
 427	case CZ_SCRATCH_ENTRY_UCODE_ID_DMCU_IRAM:
 428		ret = UCODE_ID_DMCU_IRAM;
 429		break;
 430	case CZ_SCRATCH_ENTRY_UCODE_ID_POWER_PROFILING:
 431		ret = TASK_ARG_INIT_MM_PWR_LOG;
 432		break;
 433	case CZ_SCRATCH_ENTRY_DATA_ID_SDMA_HALT:
 434	case CZ_SCRATCH_ENTRY_DATA_ID_SYS_CLOCKGATING:
 435	case CZ_SCRATCH_ENTRY_DATA_ID_SDMA_RING_REGS:
 436	case CZ_SCRATCH_ENTRY_DATA_ID_NONGFX_REINIT:
 437	case CZ_SCRATCH_ENTRY_DATA_ID_SDMA_START:
 438	case CZ_SCRATCH_ENTRY_DATA_ID_IH_REGISTERS:
 439		ret = TASK_ARG_REG_MMIO;
 440		break;
 441	case CZ_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE:
 442		ret = TASK_ARG_INIT_CLK_TABLE;
 443		break;
 444	}
 445
 446	return ret;
 447}
 448
 449static int cz_smu_populate_single_firmware_entry(struct amdgpu_device *adev,
 450					enum cz_scratch_entry firmware_enum,
 451					struct cz_buffer_entry *entry)
 452{
 453	uint64_t gpu_addr;
 454	uint32_t data_size;
 455	uint8_t ucode_id = cz_smu_translate_firmware_enum_to_arg(firmware_enum);
 456	enum AMDGPU_UCODE_ID id = cz_convert_fw_type(ucode_id);
 457	struct amdgpu_firmware_info *ucode = &adev->firmware.ucode[id];
 458	const struct gfx_firmware_header_v1_0 *header;
 459
 460	if (ucode->fw == NULL)
 461		return -EINVAL;
 462
 463	gpu_addr  = ucode->mc_addr;
 464	header = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data;
 465	data_size = le32_to_cpu(header->header.ucode_size_bytes);
 466
 467	if ((firmware_enum == CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1) ||
 468	    (firmware_enum == CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2)) {
 469		gpu_addr += le32_to_cpu(header->jt_offset) << 2;
 470		data_size = le32_to_cpu(header->jt_size) << 2;
 471	}
 472
 473	entry->mc_addr_low = lower_32_bits(gpu_addr);
 474	entry->mc_addr_high = upper_32_bits(gpu_addr);
 475	entry->data_size = data_size;
 476	entry->firmware_ID = firmware_enum;
 477
 478	return 0;
 479}
 480
 481static int cz_smu_populate_single_scratch_entry(struct amdgpu_device *adev,
 482					enum cz_scratch_entry scratch_type,
 483					uint32_t size_in_byte,
 484					struct cz_buffer_entry *entry)
 485{
 486	struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
 487	uint64_t mc_addr = (((uint64_t) priv->smu_buffer.mc_addr_high) << 32) |
 488						priv->smu_buffer.mc_addr_low;
 489	mc_addr += size_in_byte;
 490
 491	priv->smu_buffer_used_bytes += size_in_byte;
 492	entry->data_size = size_in_byte;
 493	entry->kaddr = priv->smu_buffer.kaddr + priv->smu_buffer_used_bytes;
 494	entry->mc_addr_low = lower_32_bits(mc_addr);
 495	entry->mc_addr_high = upper_32_bits(mc_addr);
 496	entry->firmware_ID = scratch_type;
 497
 498	return 0;
 499}
 500
 501static int cz_smu_populate_single_ucode_load_task(struct amdgpu_device *adev,
 502						enum cz_scratch_entry firmware_enum,
 503						bool is_last)
 504{
 505	uint8_t i;
 506	struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
 507	struct TOC *toc = (struct TOC *)priv->toc_buffer.kaddr;
 508	struct SMU_Task *task = &toc->tasks[priv->toc_entry_used_count++];
 509
 510	task->type = TASK_TYPE_UCODE_LOAD;
 511	task->arg = cz_smu_translate_firmware_enum_to_arg(firmware_enum);
 512	task->next = is_last ? END_OF_TASK_LIST : priv->toc_entry_used_count;
 513
 514	for (i = 0; i < priv->driver_buffer_length; i++)
 515		if (priv->driver_buffer[i].firmware_ID == firmware_enum)
 516			break;
 517
 518	if (i >= priv->driver_buffer_length) {
 519		dev_err(adev->dev, "Invalid Firmware Type\n");
 520		return -EINVAL;
 521	}
 522
 523	task->addr.low = priv->driver_buffer[i].mc_addr_low;
 524	task->addr.high = priv->driver_buffer[i].mc_addr_high;
 525	task->size_bytes = priv->driver_buffer[i].data_size;
 526
 527	return 0;
 528}
 529
 530static int cz_smu_populate_single_scratch_task(struct amdgpu_device *adev,
 531						enum cz_scratch_entry firmware_enum,
 532						uint8_t type, bool is_last)
 533{
 534	uint8_t i;
 535	struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
 536	struct TOC *toc = (struct TOC *)priv->toc_buffer.kaddr;
 537	struct SMU_Task *task = &toc->tasks[priv->toc_entry_used_count++];
 538
 539	task->type = type;
 540	task->arg = cz_smu_translate_firmware_enum_to_arg(firmware_enum);
 541	task->next = is_last ? END_OF_TASK_LIST : priv->toc_entry_used_count;
 542
 543	for (i = 0; i < priv->scratch_buffer_length; i++)
 544		if (priv->scratch_buffer[i].firmware_ID == firmware_enum)
 545			break;
 546
 547	if (i >= priv->scratch_buffer_length) {
 548		dev_err(adev->dev, "Invalid Firmware Type\n");
 549		return -EINVAL;
 550	}
 551
 552	task->addr.low = priv->scratch_buffer[i].mc_addr_low;
 553	task->addr.high = priv->scratch_buffer[i].mc_addr_high;
 554	task->size_bytes = priv->scratch_buffer[i].data_size;
 555
 556	if (CZ_SCRATCH_ENTRY_DATA_ID_IH_REGISTERS == firmware_enum) {
 557		struct cz_ih_meta_data *pIHReg_restore =
 558			(struct cz_ih_meta_data *)priv->scratch_buffer[i].kaddr;
 559		pIHReg_restore->command =
 560			METADATA_CMD_MODE0 | METADATA_PERFORM_ON_LOAD;
 561	}
 562
 563	return 0;
 564}
 565
 566static int cz_smu_construct_toc_for_rlc_aram_save(struct amdgpu_device *adev)
 567{
 568	struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
 569	priv->toc_entry_aram = priv->toc_entry_used_count;
 570	cz_smu_populate_single_scratch_task(adev,
 571			CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_ARAM,
 572			TASK_TYPE_UCODE_SAVE, true);
 573
 574	return 0;
 575}
 576
 577static int cz_smu_construct_toc_for_vddgfx_enter(struct amdgpu_device *adev)
 578{
 579	struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
 580	struct TOC *toc = (struct TOC *)priv->toc_buffer.kaddr;
 581
 582	toc->JobList[JOB_GFX_SAVE] = (uint8_t)priv->toc_entry_used_count;
 583	cz_smu_populate_single_scratch_task(adev,
 584				CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SCRATCH,
 585				TASK_TYPE_UCODE_SAVE, false);
 586	cz_smu_populate_single_scratch_task(adev,
 587				CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_DRAM,
 588				TASK_TYPE_UCODE_SAVE, true);
 589
 590	return 0;
 591}
 592
 593static int cz_smu_construct_toc_for_vddgfx_exit(struct amdgpu_device *adev)
 594{
 595	struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
 596	struct TOC *toc = (struct TOC *)priv->toc_buffer.kaddr;
 597
 598	toc->JobList[JOB_GFX_RESTORE] = (uint8_t)priv->toc_entry_used_count;
 599
 600	/* populate ucode */
 601	if (adev->firmware.smu_load) {
 602		cz_smu_populate_single_ucode_load_task(adev,
 603				CZ_SCRATCH_ENTRY_UCODE_ID_CP_CE, false);
 604		cz_smu_populate_single_ucode_load_task(adev,
 605				CZ_SCRATCH_ENTRY_UCODE_ID_CP_PFP, false);
 606		cz_smu_populate_single_ucode_load_task(adev,
 607				CZ_SCRATCH_ENTRY_UCODE_ID_CP_ME, false);
 608		cz_smu_populate_single_ucode_load_task(adev,
 609				CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1, false);
 610		if (adev->asic_type == CHIP_STONEY) {
 611			cz_smu_populate_single_ucode_load_task(adev,
 612				CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1, false);
 613		} else {
 614			cz_smu_populate_single_ucode_load_task(adev,
 615				CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2, false);
 616		}
 617		cz_smu_populate_single_ucode_load_task(adev,
 618				CZ_SCRATCH_ENTRY_UCODE_ID_RLC_G, false);
 619	}
 620
 621	/* populate scratch */
 622	cz_smu_populate_single_scratch_task(adev,
 623				CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SCRATCH,
 624				TASK_TYPE_UCODE_LOAD, false);
 625	cz_smu_populate_single_scratch_task(adev,
 626				CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_ARAM,
 627				TASK_TYPE_UCODE_LOAD, false);
 628	cz_smu_populate_single_scratch_task(adev,
 629				CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_DRAM,
 630				TASK_TYPE_UCODE_LOAD, true);
 631
 632	return 0;
 633}
 634
 635static int cz_smu_construct_toc_for_power_profiling(struct amdgpu_device *adev)
 636{
 637	struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
 638
 639	priv->toc_entry_power_profiling_index = priv->toc_entry_used_count;
 640
 641	cz_smu_populate_single_scratch_task(adev,
 642				CZ_SCRATCH_ENTRY_UCODE_ID_POWER_PROFILING,
 643				TASK_TYPE_INITIALIZE, true);
 644	return 0;
 645}
 646
 647static int cz_smu_construct_toc_for_bootup(struct amdgpu_device *adev)
 648{
 649	struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
 650
 651	priv->toc_entry_initialize_index = priv->toc_entry_used_count;
 652
 653	if (adev->firmware.smu_load) {
 654		cz_smu_populate_single_ucode_load_task(adev,
 655				CZ_SCRATCH_ENTRY_UCODE_ID_SDMA0, false);
 656		if (adev->asic_type == CHIP_STONEY) {
 657			cz_smu_populate_single_ucode_load_task(adev,
 658				CZ_SCRATCH_ENTRY_UCODE_ID_SDMA0, false);
 659		} else {
 660			cz_smu_populate_single_ucode_load_task(adev,
 661				CZ_SCRATCH_ENTRY_UCODE_ID_SDMA1, false);
 662		}
 663		cz_smu_populate_single_ucode_load_task(adev,
 664				CZ_SCRATCH_ENTRY_UCODE_ID_CP_CE, false);
 665		cz_smu_populate_single_ucode_load_task(adev,
 666				CZ_SCRATCH_ENTRY_UCODE_ID_CP_PFP, false);
 667		cz_smu_populate_single_ucode_load_task(adev,
 668				CZ_SCRATCH_ENTRY_UCODE_ID_CP_ME, false);
 669		cz_smu_populate_single_ucode_load_task(adev,
 670				CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1, false);
 671		if (adev->asic_type == CHIP_STONEY) {
 672			cz_smu_populate_single_ucode_load_task(adev,
 673				CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1, false);
 674		} else {
 675			cz_smu_populate_single_ucode_load_task(adev,
 676				CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2, false);
 677		}
 678		cz_smu_populate_single_ucode_load_task(adev,
 679				CZ_SCRATCH_ENTRY_UCODE_ID_RLC_G, true);
 680	}
 681
 682	return 0;
 683}
 684
 685static int cz_smu_construct_toc_for_clock_table(struct amdgpu_device *adev)
 686{
 687	struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
 688
 689	priv->toc_entry_clock_table = priv->toc_entry_used_count;
 690
 691	cz_smu_populate_single_scratch_task(adev,
 692				CZ_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE,
 693				TASK_TYPE_INITIALIZE, true);
 694
 695	return 0;
 696}
 697
 698static int cz_smu_initialize_toc_empty_job_list(struct amdgpu_device *adev)
 699{
 700	int i;
 701	struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
 702	struct TOC *toc = (struct TOC *)priv->toc_buffer.kaddr;
 703
 704	for (i = 0; i < NUM_JOBLIST_ENTRIES; i++)
 705		toc->JobList[i] = (uint8_t)IGNORE_JOB;
 706
 707	return 0;
 708}
 709
 710/*
 711 * cz smu uninitialization
 712 */
 713int cz_smu_fini(struct amdgpu_device *adev)
 714{
 715	amdgpu_bo_unref(&adev->smu.toc_buf);
 716	amdgpu_bo_unref(&adev->smu.smu_buf);
 717	kfree(adev->smu.priv);
 718	adev->smu.priv = NULL;
 719	if (adev->firmware.smu_load)
 720		amdgpu_ucode_fini_bo(adev);
 721
 722	return 0;
 723}
 724
 725int cz_smu_download_pptable(struct amdgpu_device *adev, void **table)
 726{
 727	uint8_t i;
 728	struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
 729
 730	for (i = 0; i < priv->scratch_buffer_length; i++)
 731		if (priv->scratch_buffer[i].firmware_ID ==
 732				CZ_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE)
 733			break;
 734
 735	if (i >= priv->scratch_buffer_length) {
 736		dev_err(adev->dev, "Invalid Scratch Type\n");
 737		return -EINVAL;
 738	}
 739
 740	*table = (struct SMU8_Fusion_ClkTable *)priv->scratch_buffer[i].kaddr;
 741
 742	/* prepare buffer for pptable */
 743	cz_send_msg_to_smc_with_parameter(adev,
 744				PPSMC_MSG_SetClkTableAddrHi,
 745				priv->scratch_buffer[i].mc_addr_high);
 746	cz_send_msg_to_smc_with_parameter(adev,
 747				PPSMC_MSG_SetClkTableAddrLo,
 748				priv->scratch_buffer[i].mc_addr_low);
 749	cz_send_msg_to_smc_with_parameter(adev,
 750				PPSMC_MSG_ExecuteJob,
 751				priv->toc_entry_clock_table);
 752
 753	/* actual downloading */
 754	cz_send_msg_to_smc(adev, PPSMC_MSG_ClkTableXferToDram);
 755
 756	return 0;
 757}
 758
 759int cz_smu_upload_pptable(struct amdgpu_device *adev)
 760{
 761	uint8_t i;
 762	struct cz_smu_private_data *priv = cz_smu_get_priv(adev);
 763
 764	for (i = 0; i < priv->scratch_buffer_length; i++)
 765		if (priv->scratch_buffer[i].firmware_ID ==
 766				CZ_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE)
 767			break;
 768
 769	if (i >= priv->scratch_buffer_length) {
 770		dev_err(adev->dev, "Invalid Scratch Type\n");
 771		return -EINVAL;
 772	}
 773
 774	/* prepare SMU */
 775	cz_send_msg_to_smc_with_parameter(adev,
 776				PPSMC_MSG_SetClkTableAddrHi,
 777				priv->scratch_buffer[i].mc_addr_high);
 778	cz_send_msg_to_smc_with_parameter(adev,
 779				PPSMC_MSG_SetClkTableAddrLo,
 780				priv->scratch_buffer[i].mc_addr_low);
 781	cz_send_msg_to_smc_with_parameter(adev,
 782				PPSMC_MSG_ExecuteJob,
 783				priv->toc_entry_clock_table);
 784
 785	/* actual uploading */
 786	cz_send_msg_to_smc(adev, PPSMC_MSG_ClkTableXferToSmu);
 787
 788	return 0;
 789}
 790
 791/*
 792 * cz smumgr functions initialization
 793 */
 794static const struct amdgpu_smumgr_funcs cz_smumgr_funcs = {
 795	.check_fw_load_finish = cz_smu_check_finished,
 796	.request_smu_load_fw = NULL,
 797	.request_smu_specific_fw = NULL,
 798};
 799
 800/*
 801 * cz smu initialization
 802 */
 803int cz_smu_init(struct amdgpu_device *adev)
 804{
 805	int ret = -EINVAL;
 806	uint64_t mc_addr = 0;
 807	struct amdgpu_bo **toc_buf = &adev->smu.toc_buf;
 808	struct amdgpu_bo **smu_buf = &adev->smu.smu_buf;
 809	void *toc_buf_ptr = NULL;
 810	void *smu_buf_ptr = NULL;
 811
 812	struct cz_smu_private_data *priv =
 813		kzalloc(sizeof(struct cz_smu_private_data), GFP_KERNEL);
 814	if (priv == NULL)
 815		return -ENOMEM;
 816
 817	/* allocate firmware buffers */
 818	if (adev->firmware.smu_load)
 819		amdgpu_ucode_init_bo(adev);
 820
 821	adev->smu.priv = priv;
 822	adev->smu.fw_flags = 0;
 823	priv->toc_buffer.data_size = 4096;
 824
 825	priv->smu_buffer.data_size =
 826				ALIGN(UCODE_ID_RLC_SCRATCH_SIZE_BYTE, 32) +
 827				ALIGN(UCODE_ID_RLC_SRM_ARAM_SIZE_BYTE, 32) +
 828				ALIGN(UCODE_ID_RLC_SRM_DRAM_SIZE_BYTE, 32) +
 829				ALIGN(sizeof(struct SMU8_MultimediaPowerLogData), 32) +
 830				ALIGN(sizeof(struct SMU8_Fusion_ClkTable), 32);
 831
 832	/* prepare toc buffer and smu buffer:
 833	* 1. create amdgpu_bo for toc buffer and smu buffer
 834	* 2. pin mc address
 835	* 3. map kernel virtual address
 836	*/
 837	ret = amdgpu_bo_create(adev, priv->toc_buffer.data_size, PAGE_SIZE,
 838			       true, AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL,
 839			       toc_buf);
 840
 841	if (ret) {
 842		dev_err(adev->dev, "(%d) SMC TOC buffer allocation failed\n", ret);
 843		return ret;
 844	}
 845
 846	ret = amdgpu_bo_create(adev, priv->smu_buffer.data_size, PAGE_SIZE,
 847			       true, AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL,
 848			       smu_buf);
 849
 850	if (ret) {
 851		dev_err(adev->dev, "(%d) SMC Internal buffer allocation failed\n", ret);
 852		return ret;
 853	}
 854
 855	/* toc buffer reserve/pin/map */
 856	ret = amdgpu_bo_reserve(adev->smu.toc_buf, false);
 857	if (ret) {
 858		amdgpu_bo_unref(&adev->smu.toc_buf);
 859		dev_err(adev->dev, "(%d) SMC TOC buffer reserve failed\n", ret);
 860		return ret;
 861	}
 862
 863	ret = amdgpu_bo_pin(adev->smu.toc_buf, AMDGPU_GEM_DOMAIN_GTT, &mc_addr);
 864	if (ret) {
 865		amdgpu_bo_unreserve(adev->smu.toc_buf);
 866		amdgpu_bo_unref(&adev->smu.toc_buf);
 867		dev_err(adev->dev, "(%d) SMC TOC buffer pin failed\n", ret);
 868		return ret;
 869	}
 870
 871	ret = amdgpu_bo_kmap(*toc_buf, &toc_buf_ptr);
 872	if (ret)
 873		goto smu_init_failed;
 874
 875	amdgpu_bo_unreserve(adev->smu.toc_buf);
 876
 877	priv->toc_buffer.mc_addr_low = lower_32_bits(mc_addr);
 878	priv->toc_buffer.mc_addr_high = upper_32_bits(mc_addr);
 879	priv->toc_buffer.kaddr = toc_buf_ptr;
 880
 881	/* smu buffer reserve/pin/map */
 882	ret = amdgpu_bo_reserve(adev->smu.smu_buf, false);
 883	if (ret) {
 884		amdgpu_bo_unref(&adev->smu.smu_buf);
 885		dev_err(adev->dev, "(%d) SMC Internal buffer reserve failed\n", ret);
 886		return ret;
 887	}
 888
 889	ret = amdgpu_bo_pin(adev->smu.smu_buf, AMDGPU_GEM_DOMAIN_GTT, &mc_addr);
 890	if (ret) {
 891		amdgpu_bo_unreserve(adev->smu.smu_buf);
 892		amdgpu_bo_unref(&adev->smu.smu_buf);
 893		dev_err(adev->dev, "(%d) SMC Internal buffer pin failed\n", ret);
 894		return ret;
 895	}
 896
 897	ret = amdgpu_bo_kmap(*smu_buf, &smu_buf_ptr);
 898	if (ret)
 899		goto smu_init_failed;
 900
 901	amdgpu_bo_unreserve(adev->smu.smu_buf);
 902
 903	priv->smu_buffer.mc_addr_low = lower_32_bits(mc_addr);
 904	priv->smu_buffer.mc_addr_high = upper_32_bits(mc_addr);
 905	priv->smu_buffer.kaddr = smu_buf_ptr;
 906
 907	if (adev->firmware.smu_load) {
 908		if (cz_smu_populate_single_firmware_entry(adev,
 909				CZ_SCRATCH_ENTRY_UCODE_ID_SDMA0,
 910				&priv->driver_buffer[priv->driver_buffer_length++]))
 911			goto smu_init_failed;
 912
 913		if (adev->asic_type == CHIP_STONEY) {
 914			if (cz_smu_populate_single_firmware_entry(adev,
 915					CZ_SCRATCH_ENTRY_UCODE_ID_SDMA0,
 916					&priv->driver_buffer[priv->driver_buffer_length++]))
 917				goto smu_init_failed;
 918		} else {
 919			if (cz_smu_populate_single_firmware_entry(adev,
 920					CZ_SCRATCH_ENTRY_UCODE_ID_SDMA1,
 921					&priv->driver_buffer[priv->driver_buffer_length++]))
 922				goto smu_init_failed;
 923		}
 924		if (cz_smu_populate_single_firmware_entry(adev,
 925				CZ_SCRATCH_ENTRY_UCODE_ID_CP_CE,
 926				&priv->driver_buffer[priv->driver_buffer_length++]))
 927			goto smu_init_failed;
 928		if (cz_smu_populate_single_firmware_entry(adev,
 929				CZ_SCRATCH_ENTRY_UCODE_ID_CP_PFP,
 930				&priv->driver_buffer[priv->driver_buffer_length++]))
 931			goto smu_init_failed;
 932		if (cz_smu_populate_single_firmware_entry(adev,
 933				CZ_SCRATCH_ENTRY_UCODE_ID_CP_ME,
 934				&priv->driver_buffer[priv->driver_buffer_length++]))
 935			goto smu_init_failed;
 936		if (cz_smu_populate_single_firmware_entry(adev,
 937				CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1,
 938				&priv->driver_buffer[priv->driver_buffer_length++]))
 939			goto smu_init_failed;
 940		if (adev->asic_type == CHIP_STONEY) {
 941			if (cz_smu_populate_single_firmware_entry(adev,
 942					CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT1,
 943					&priv->driver_buffer[priv->driver_buffer_length++]))
 944				goto smu_init_failed;
 945		} else {
 946			if (cz_smu_populate_single_firmware_entry(adev,
 947					CZ_SCRATCH_ENTRY_UCODE_ID_CP_MEC_JT2,
 948					&priv->driver_buffer[priv->driver_buffer_length++]))
 949				goto smu_init_failed;
 950		}
 951		if (cz_smu_populate_single_firmware_entry(adev,
 952				CZ_SCRATCH_ENTRY_UCODE_ID_RLC_G,
 953				&priv->driver_buffer[priv->driver_buffer_length++]))
 954			goto smu_init_failed;
 955	}
 956
 957	if (cz_smu_populate_single_scratch_entry(adev,
 958				CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SCRATCH,
 959				UCODE_ID_RLC_SCRATCH_SIZE_BYTE,
 960				&priv->scratch_buffer[priv->scratch_buffer_length++]))
 961		goto smu_init_failed;
 962	if (cz_smu_populate_single_scratch_entry(adev,
 963				CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_ARAM,
 964				UCODE_ID_RLC_SRM_ARAM_SIZE_BYTE,
 965				&priv->scratch_buffer[priv->scratch_buffer_length++]))
 966		goto smu_init_failed;
 967	if (cz_smu_populate_single_scratch_entry(adev,
 968				CZ_SCRATCH_ENTRY_UCODE_ID_RLC_SRM_DRAM,
 969				UCODE_ID_RLC_SRM_DRAM_SIZE_BYTE,
 970				&priv->scratch_buffer[priv->scratch_buffer_length++]))
 971		goto smu_init_failed;
 972	if (cz_smu_populate_single_scratch_entry(adev,
 973				CZ_SCRATCH_ENTRY_UCODE_ID_POWER_PROFILING,
 974				sizeof(struct SMU8_MultimediaPowerLogData),
 975				&priv->scratch_buffer[priv->scratch_buffer_length++]))
 976		goto smu_init_failed;
 977	if (cz_smu_populate_single_scratch_entry(adev,
 978				CZ_SCRATCH_ENTRY_SMU8_FUSION_CLKTABLE,
 979				sizeof(struct SMU8_Fusion_ClkTable),
 980				&priv->scratch_buffer[priv->scratch_buffer_length++]))
 981		goto smu_init_failed;
 982
 983	cz_smu_initialize_toc_empty_job_list(adev);
 984	cz_smu_construct_toc_for_rlc_aram_save(adev);
 985	cz_smu_construct_toc_for_vddgfx_enter(adev);
 986	cz_smu_construct_toc_for_vddgfx_exit(adev);
 987	cz_smu_construct_toc_for_power_profiling(adev);
 988	cz_smu_construct_toc_for_bootup(adev);
 989	cz_smu_construct_toc_for_clock_table(adev);
 990	/* init the smumgr functions */
 991	adev->smu.smumgr_funcs = &cz_smumgr_funcs;
 992
 993	return 0;
 994
 995smu_init_failed:
 996	amdgpu_bo_unref(toc_buf);
 997	amdgpu_bo_unref(smu_buf);
 998
 999	return ret;
1000}