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}
1001