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
24#include <linux/firmware.h>
25#include "drmP.h"
26#include "amdgpu.h"
27#include "tonga_ppsmc.h"
28#include "tonga_smumgr.h"
29#include "smu_ucode_xfer_vi.h"
30#include "amdgpu_ucode.h"
31
32#include "smu/smu_7_1_2_d.h"
33#include "smu/smu_7_1_2_sh_mask.h"
34
35#define TONGA_SMC_SIZE 0x20000
36
37static int tonga_set_smc_sram_address(struct amdgpu_device *adev, uint32_t smc_address, uint32_t limit)
38{
39	uint32_t val;
40
41	if (smc_address & 3)
42		return -EINVAL;
43
44	if ((smc_address + 3) > limit)
45		return -EINVAL;
46
47	WREG32(mmSMC_IND_INDEX_0, smc_address);
48
49	val = RREG32(mmSMC_IND_ACCESS_CNTL);
50	val = REG_SET_FIELD(val, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0);
51	WREG32(mmSMC_IND_ACCESS_CNTL, val);
52
53	return 0;
54}
55
56static int tonga_copy_bytes_to_smc(struct amdgpu_device *adev, uint32_t smc_start_address, const uint8_t *src, uint32_t byte_count, uint32_t limit)
57{
58	uint32_t addr;
59	uint32_t data, orig_data;
60	int result = 0;
61	uint32_t extra_shift;
62	unsigned long flags;
63
64	if (smc_start_address & 3)
65		return -EINVAL;
66
67	if ((smc_start_address + byte_count) > limit)
68		return -EINVAL;
69
70	addr = smc_start_address;
71
72	spin_lock_irqsave(&adev->smc_idx_lock, flags);
73	while (byte_count >= 4) {
74		/* Bytes are written into the SMC addres space with the MSB first */
75		data = (src[0] << 24) + (src[1] << 16) + (src[2] << 8) + src[3];
76
77		result = tonga_set_smc_sram_address(adev, addr, limit);
78
79		if (result)
80			goto out;
81
82		WREG32(mmSMC_IND_DATA_0, data);
83
84		src += 4;
85		byte_count -= 4;
86		addr += 4;
87	}
88
89	if (0 != byte_count) {
90		/* Now write odd bytes left, do a read modify write cycle */
91		data = 0;
92
93		result = tonga_set_smc_sram_address(adev, addr, limit);
94		if (result)
95			goto out;
96
97		orig_data = RREG32(mmSMC_IND_DATA_0);
98		extra_shift = 8 * (4 - byte_count);
99
100		while (byte_count > 0) {
101			data = (data << 8) + *src++;
102			byte_count--;
103		}
104
105		data <<= extra_shift;
106		data |= (orig_data & ~((~0UL) << extra_shift));
107
108		result = tonga_set_smc_sram_address(adev, addr, limit);
109		if (result)
110			goto out;
111
112		WREG32(mmSMC_IND_DATA_0, data);
113	}
114
115out:
116	spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
117	return result;
118}
119
120static int tonga_program_jump_on_start(struct amdgpu_device *adev)
121{
122	static unsigned char data[] = {0xE0, 0x00, 0x80, 0x40};
123	tonga_copy_bytes_to_smc(adev, 0x0, data, 4, sizeof(data)+1);
124
125	return 0;
126}
127
128static bool tonga_is_smc_ram_running(struct amdgpu_device *adev)
129{
130	uint32_t val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
131	val = REG_GET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable);
132
133	return ((0 == val) && (0x20100 <= RREG32_SMC(ixSMC_PC_C)));
134}
135
136static int wait_smu_response(struct amdgpu_device *adev)
137{
138	int i;
139	uint32_t val;
140
141	for (i = 0; i < adev->usec_timeout; i++) {
142		val = RREG32(mmSMC_RESP_0);
143		if (REG_GET_FIELD(val, SMC_RESP_0, SMC_RESP))
144			break;
145		udelay(1);
146	}
147
148	if (i == adev->usec_timeout)
149		return -EINVAL;
150
151	return 0;
152}
153
154static int tonga_send_msg_to_smc_offset(struct amdgpu_device *adev)
155{
156	if (wait_smu_response(adev)) {
157		DRM_ERROR("Failed to send previous message\n");
158		return -EINVAL;
159	}
160
161	WREG32(mmSMC_MSG_ARG_0, 0x20000);
162	WREG32(mmSMC_MESSAGE_0, PPSMC_MSG_Test);
163
164	if (wait_smu_response(adev)) {
165		DRM_ERROR("Failed to send message\n");
166		return -EINVAL;
167	}
168
169	return 0;
170}
171
172static int tonga_send_msg_to_smc(struct amdgpu_device *adev, PPSMC_Msg msg)
173{
174	if (!tonga_is_smc_ram_running(adev))
175	{
176		return -EINVAL;;
177	}
178
179	if (wait_smu_response(adev)) {
180		DRM_ERROR("Failed to send previous message\n");
181		return -EINVAL;
182	}
183
184	WREG32(mmSMC_MESSAGE_0, msg);
185
186	if (wait_smu_response(adev)) {
187		DRM_ERROR("Failed to send message\n");
188		return -EINVAL;
189	}
190
191	return 0;
192}
193
194static int tonga_send_msg_to_smc_without_waiting(struct amdgpu_device *adev,
195						PPSMC_Msg msg)
196{
197	if (wait_smu_response(adev)) {
198		DRM_ERROR("Failed to send previous message\n");
199		return -EINVAL;
200	}
201
202	WREG32(mmSMC_MESSAGE_0, msg);
203
204	return 0;
205}
206
207static int tonga_send_msg_to_smc_with_parameter(struct amdgpu_device *adev,
208						PPSMC_Msg msg,
209						uint32_t parameter)
210{
211	if (!tonga_is_smc_ram_running(adev))
212		return -EINVAL;
213
214	if (wait_smu_response(adev)) {
215		DRM_ERROR("Failed to send previous message\n");
216		return -EINVAL;
217	}
218
219	WREG32(mmSMC_MSG_ARG_0, parameter);
220
221	return tonga_send_msg_to_smc(adev, msg);
222}
223
224static int tonga_send_msg_to_smc_with_parameter_without_waiting(
225					struct amdgpu_device *adev,
226					PPSMC_Msg msg, uint32_t parameter)
227{
228	if (wait_smu_response(adev)) {
229		DRM_ERROR("Failed to send previous message\n");
230		return -EINVAL;
231	}
232
233	WREG32(mmSMC_MSG_ARG_0, parameter);
234
235	return tonga_send_msg_to_smc_without_waiting(adev, msg);
236}
237
238#if 0 /* not used yet */
239static int tonga_wait_for_smc_inactive(struct amdgpu_device *adev)
240{
241	int i;
242	uint32_t val;
243
244	if (!tonga_is_smc_ram_running(adev))
245		return -EINVAL;
246
247	for (i = 0; i < adev->usec_timeout; i++) {
248		val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
249		if (REG_GET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, cken) == 0)
250			break;
251		udelay(1);
252	}
253
254	if (i == adev->usec_timeout)
255		return -EINVAL;
256
257	return 0;
258}
259#endif
260
261static int tonga_smu_upload_firmware_image(struct amdgpu_device *adev)
262{
263	const struct smc_firmware_header_v1_0 *hdr;
264	uint32_t ucode_size;
265	uint32_t ucode_start_address;
266	const uint8_t *src;
267	uint32_t val;
268	uint32_t byte_count;
269	uint32_t *data;
270	unsigned long flags;
271
272	if (!adev->pm.fw)
273		return -EINVAL;
274
275	hdr = (const struct smc_firmware_header_v1_0 *)adev->pm.fw->data;
276	amdgpu_ucode_print_smc_hdr(&hdr->header);
277
278	adev->pm.fw_version = le32_to_cpu(hdr->header.ucode_version);
279	ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes);
280	ucode_start_address = le32_to_cpu(hdr->ucode_start_addr);
281	src = (const uint8_t *)
282		(adev->pm.fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
283
284	if (ucode_size & 3) {
285		DRM_ERROR("SMC ucode is not 4 bytes aligned\n");
286		return -EINVAL;
287	}
288
289	if (ucode_size > TONGA_SMC_SIZE) {
290		DRM_ERROR("SMC address is beyond the SMC RAM area\n");
291		return -EINVAL;
292	}
293
294	spin_lock_irqsave(&adev->smc_idx_lock, flags);
295	WREG32(mmSMC_IND_INDEX_0, ucode_start_address);
296
297	val = RREG32(mmSMC_IND_ACCESS_CNTL);
298	val = REG_SET_FIELD(val, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 1);
299	WREG32(mmSMC_IND_ACCESS_CNTL, val);
300
301	byte_count = ucode_size;
302	data = (uint32_t *)src;
303	for (; byte_count >= 4; data++, byte_count -= 4)
304		WREG32(mmSMC_IND_DATA_0, data[0]);
305
306	val = RREG32(mmSMC_IND_ACCESS_CNTL);
307	val = REG_SET_FIELD(val, SMC_IND_ACCESS_CNTL, AUTO_INCREMENT_IND_0, 0);
308	WREG32(mmSMC_IND_ACCESS_CNTL, val);
309	spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
310
311	return 0;
312}
313
314#if 0 /* not used yet */
315static int tonga_read_smc_sram_dword(struct amdgpu_device *adev,
316				uint32_t smc_address,
317				uint32_t *value,
318				uint32_t limit)
319{
320	int result;
321	unsigned long flags;
322
323	spin_lock_irqsave(&adev->smc_idx_lock, flags);
324	result = tonga_set_smc_sram_address(adev, smc_address, limit);
325	if (result == 0)
326		*value = RREG32(mmSMC_IND_DATA_0);
327	spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
328	return result;
329}
330
331static int tonga_write_smc_sram_dword(struct amdgpu_device *adev,
332				uint32_t smc_address,
333				uint32_t value,
334				uint32_t limit)
335{
336	int result;
337	unsigned long flags;
338
339	spin_lock_irqsave(&adev->smc_idx_lock, flags);
340	result = tonga_set_smc_sram_address(adev, smc_address, limit);
341	if (result == 0)
342		WREG32(mmSMC_IND_DATA_0, value);
343	spin_unlock_irqrestore(&adev->smc_idx_lock, flags);
344	return result;
345}
346
347static int tonga_smu_stop_smc(struct amdgpu_device *adev)
348{
349	uint32_t val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL);
350	val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 1);
351	WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val);
352
353	val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
354	val = REG_SET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 1);
355	WREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0, val);
356
357	return 0;
358}
359#endif
360
361static enum AMDGPU_UCODE_ID tonga_convert_fw_type(uint32_t fw_type)
362{
363	switch (fw_type) {
364		case UCODE_ID_SDMA0:
365			return AMDGPU_UCODE_ID_SDMA0;
366		case UCODE_ID_SDMA1:
367			return AMDGPU_UCODE_ID_SDMA1;
368		case UCODE_ID_CP_CE:
369			return AMDGPU_UCODE_ID_CP_CE;
370		case UCODE_ID_CP_PFP:
371			return AMDGPU_UCODE_ID_CP_PFP;
372		case UCODE_ID_CP_ME:
373			return AMDGPU_UCODE_ID_CP_ME;
374		case UCODE_ID_CP_MEC:
375		case UCODE_ID_CP_MEC_JT1:
376			return AMDGPU_UCODE_ID_CP_MEC1;
377		case UCODE_ID_CP_MEC_JT2:
378			return AMDGPU_UCODE_ID_CP_MEC2;
379		case UCODE_ID_RLC_G:
380			return AMDGPU_UCODE_ID_RLC_G;
381		default:
382			DRM_ERROR("ucode type is out of range!\n");
383			return AMDGPU_UCODE_ID_MAXIMUM;
384	}
385}
386
387static int tonga_smu_populate_single_firmware_entry(struct amdgpu_device *adev,
388						uint32_t fw_type,
389						struct SMU_Entry *entry)
390{
391	enum AMDGPU_UCODE_ID id = tonga_convert_fw_type(fw_type);
392	struct amdgpu_firmware_info *ucode = &adev->firmware.ucode[id];
393	const struct gfx_firmware_header_v1_0 *header = NULL;
394	uint64_t gpu_addr;
395	uint32_t data_size;
396
397	if (ucode->fw == NULL)
398		return -EINVAL;
399
400	gpu_addr  = ucode->mc_addr;
401	header = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data;
402	data_size = le32_to_cpu(header->header.ucode_size_bytes);
403
404	if ((fw_type == UCODE_ID_CP_MEC_JT1) ||
405		(fw_type == UCODE_ID_CP_MEC_JT2)) {
406		gpu_addr += le32_to_cpu(header->jt_offset) << 2;
407		data_size = le32_to_cpu(header->jt_size) << 2;
408	}
409
410	entry->version = (uint16_t)le32_to_cpu(header->header.ucode_version);
411	entry->id = (uint16_t)fw_type;
412	entry->image_addr_high = upper_32_bits(gpu_addr);
413	entry->image_addr_low = lower_32_bits(gpu_addr);
414	entry->meta_data_addr_high = 0;
415	entry->meta_data_addr_low = 0;
416	entry->data_size_byte = data_size;
417	entry->num_register_entries = 0;
418
419	if (fw_type == UCODE_ID_RLC_G)
420		entry->flags = 1;
421	else
422		entry->flags = 0;
423
424	return 0;
425}
426
427static int tonga_smu_request_load_fw(struct amdgpu_device *adev)
428{
429	struct tonga_smu_private_data *private = (struct tonga_smu_private_data *)adev->smu.priv;
430	struct SMU_DRAMData_TOC *toc;
431	uint32_t fw_to_load;
432
433	WREG32_SMC(ixSOFT_REGISTERS_TABLE_28, 0);
434
435	tonga_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SMU_DRAM_ADDR_HI, private->smu_buffer_addr_high);
436	tonga_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SMU_DRAM_ADDR_LO, private->smu_buffer_addr_low);
437
438	toc = (struct SMU_DRAMData_TOC *)private->header;
439	toc->num_entries = 0;
440	toc->structure_version = 1;
441
442	if (!adev->firmware.smu_load)
443		return 0;
444
445	if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_RLC_G,
446			&toc->entry[toc->num_entries++])) {
447		DRM_ERROR("Failed to get firmware entry for RLC\n");
448		return -EINVAL;
449	}
450
451	if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_CE,
452			&toc->entry[toc->num_entries++])) {
453		DRM_ERROR("Failed to get firmware entry for CE\n");
454		return -EINVAL;
455	}
456
457	if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_PFP,
458			&toc->entry[toc->num_entries++])) {
459		DRM_ERROR("Failed to get firmware entry for PFP\n");
460		return -EINVAL;
461	}
462
463	if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_ME,
464			&toc->entry[toc->num_entries++])) {
465		DRM_ERROR("Failed to get firmware entry for ME\n");
466		return -EINVAL;
467	}
468
469	if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_MEC,
470			&toc->entry[toc->num_entries++])) {
471		DRM_ERROR("Failed to get firmware entry for MEC\n");
472		return -EINVAL;
473	}
474
475	if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_MEC_JT1,
476			&toc->entry[toc->num_entries++])) {
477		DRM_ERROR("Failed to get firmware entry for MEC_JT1\n");
478		return -EINVAL;
479	}
480
481	if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_CP_MEC_JT2,
482			&toc->entry[toc->num_entries++])) {
483		DRM_ERROR("Failed to get firmware entry for MEC_JT2\n");
484		return -EINVAL;
485	}
486
487	if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_SDMA0,
488			&toc->entry[toc->num_entries++])) {
489		DRM_ERROR("Failed to get firmware entry for SDMA0\n");
490		return -EINVAL;
491	}
492
493	if (tonga_smu_populate_single_firmware_entry(adev, UCODE_ID_SDMA1,
494			&toc->entry[toc->num_entries++])) {
495		DRM_ERROR("Failed to get firmware entry for SDMA1\n");
496		return -EINVAL;
497	}
498
499	tonga_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_DRV_DRAM_ADDR_HI, private->header_addr_high);
500	tonga_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_DRV_DRAM_ADDR_LO, private->header_addr_low);
501
502	fw_to_load = UCODE_ID_RLC_G_MASK |
503			UCODE_ID_SDMA0_MASK |
504			UCODE_ID_SDMA1_MASK |
505			UCODE_ID_CP_CE_MASK |
506			UCODE_ID_CP_ME_MASK |
507			UCODE_ID_CP_PFP_MASK |
508			UCODE_ID_CP_MEC_MASK;
509
510	if (tonga_send_msg_to_smc_with_parameter_without_waiting(adev, PPSMC_MSG_LoadUcodes, fw_to_load)) {
511		DRM_ERROR("Fail to request SMU load ucode\n");
512		return -EINVAL;
513	}
514
515	return 0;
516}
517
518static uint32_t tonga_smu_get_mask_for_fw_type(uint32_t fw_type)
519{
520	switch (fw_type) {
521		case AMDGPU_UCODE_ID_SDMA0:
522			return UCODE_ID_SDMA0_MASK;
523		case AMDGPU_UCODE_ID_SDMA1:
524			return UCODE_ID_SDMA1_MASK;
525		case AMDGPU_UCODE_ID_CP_CE:
526			return UCODE_ID_CP_CE_MASK;
527		case AMDGPU_UCODE_ID_CP_PFP:
528			return UCODE_ID_CP_PFP_MASK;
529		case AMDGPU_UCODE_ID_CP_ME:
530			return UCODE_ID_CP_ME_MASK;
531		case AMDGPU_UCODE_ID_CP_MEC1:
532			return UCODE_ID_CP_MEC_MASK;
533		case AMDGPU_UCODE_ID_CP_MEC2:
534			return UCODE_ID_CP_MEC_MASK;
535		case AMDGPU_UCODE_ID_RLC_G:
536			return UCODE_ID_RLC_G_MASK;
537		default:
538			DRM_ERROR("ucode type is out of range!\n");
539			return 0;
540	}
541}
542
543static int tonga_smu_check_fw_load_finish(struct amdgpu_device *adev,
544					uint32_t fw_type)
545{
546	uint32_t fw_mask = tonga_smu_get_mask_for_fw_type(fw_type);
547	int i;
548
549	for (i = 0; i < adev->usec_timeout; i++) {
550		if (fw_mask == (RREG32_SMC(ixSOFT_REGISTERS_TABLE_28) & fw_mask))
551			break;
552		udelay(1);
553	}
554
555	if (i == adev->usec_timeout) {
556		DRM_ERROR("check firmware loading failed\n");
557		return -EINVAL;
558	}
559
560	return 0;
561}
562
563static int tonga_smu_start_in_protection_mode(struct amdgpu_device *adev)
564{
565	int result;
566	uint32_t val;
567	int i;
568
569	/* Assert reset */
570	val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL);
571	val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 1);
572	WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val);
573
574	result = tonga_smu_upload_firmware_image(adev);
575	if (result)
576		return result;
577
578	/* Clear status */
579	WREG32_SMC(ixSMU_STATUS, 0);
580
581	/* Enable clock */
582	val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
583	val = REG_SET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0);
584	WREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0, val);
585
586	/* De-assert reset */
587	val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL);
588	val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 0);
589	WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val);
590
591	/* Set SMU Auto Start */
592	val = RREG32_SMC(ixSMU_INPUT_DATA);
593	val = REG_SET_FIELD(val, SMU_INPUT_DATA, AUTO_START, 1);
594	WREG32_SMC(ixSMU_INPUT_DATA, val);
595
596	/* Clear firmware interrupt enable flag */
597	WREG32_SMC(ixFIRMWARE_FLAGS, 0);
598
599	for (i = 0; i < adev->usec_timeout; i++) {
600		val = RREG32_SMC(ixRCU_UC_EVENTS);
601		if (REG_GET_FIELD(val, RCU_UC_EVENTS, INTERRUPTS_ENABLED))
602			break;
603		udelay(1);
604	}
605
606	if (i == adev->usec_timeout) {
607		DRM_ERROR("Interrupt is not enabled by firmware\n");
608		return -EINVAL;
609	}
610
611	/* Call Test SMU message with 0x20000 offset
612	 * to trigger SMU start
613	 */
614	tonga_send_msg_to_smc_offset(adev);
615
616	/* Wait for done bit to be set */
617	for (i = 0; i < adev->usec_timeout; i++) {
618		val = RREG32_SMC(ixSMU_STATUS);
619		if (REG_GET_FIELD(val, SMU_STATUS, SMU_DONE))
620			break;
621		udelay(1);
622	}
623
624	if (i == adev->usec_timeout) {
625		DRM_ERROR("Timeout for SMU start\n");
626		return -EINVAL;
627	}
628
629	/* Check pass/failed indicator */
630	val = RREG32_SMC(ixSMU_STATUS);
631	if (!REG_GET_FIELD(val, SMU_STATUS, SMU_PASS)) {
632		DRM_ERROR("SMU Firmware start failed\n");
633		return -EINVAL;
634	}
635
636	/* Wait for firmware to initialize */
637	for (i = 0; i < adev->usec_timeout; i++) {
638		val = RREG32_SMC(ixFIRMWARE_FLAGS);
639		if(REG_GET_FIELD(val, FIRMWARE_FLAGS, INTERRUPTS_ENABLED))
640			break;
641		udelay(1);
642	}
643
644	if (i == adev->usec_timeout) {
645		DRM_ERROR("SMU firmware initialization failed\n");
646		return -EINVAL;
647	}
648
649	return 0;
650}
651
652static int tonga_smu_start_in_non_protection_mode(struct amdgpu_device *adev)
653{
654	int i, result;
655	uint32_t val;
656
657	/* wait for smc boot up */
658	for (i = 0; i < adev->usec_timeout; i++) {
659		val = RREG32_SMC(ixRCU_UC_EVENTS);
660		val = REG_GET_FIELD(val, RCU_UC_EVENTS, boot_seq_done);
661		if (val)
662			break;
663		udelay(1);
664	}
665
666	if (i == adev->usec_timeout) {
667		DRM_ERROR("SMC boot sequence is not completed\n");
668		return -EINVAL;
669	}
670
671	/* Clear firmware interrupt enable flag */
672	WREG32_SMC(ixFIRMWARE_FLAGS, 0);
673
674	/* Assert reset */
675	val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL);
676	val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 1);
677	WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val);
678
679	result = tonga_smu_upload_firmware_image(adev);
680	if (result)
681		return result;
682
683	/* Set smc instruct start point at 0x0 */
684	tonga_program_jump_on_start(adev);
685
686	/* Enable clock */
687	val = RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0);
688	val = REG_SET_FIELD(val, SMC_SYSCON_CLOCK_CNTL_0, ck_disable, 0);
689	WREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0, val);
690
691	/* De-assert reset */
692	val = RREG32_SMC(ixSMC_SYSCON_RESET_CNTL);
693	val = REG_SET_FIELD(val, SMC_SYSCON_RESET_CNTL, rst_reg, 0);
694	WREG32_SMC(ixSMC_SYSCON_RESET_CNTL, val);
695
696	/* Wait for firmware to initialize */
697	for (i = 0; i < adev->usec_timeout; i++) {
698		val = RREG32_SMC(ixFIRMWARE_FLAGS);
699		if (REG_GET_FIELD(val, FIRMWARE_FLAGS, INTERRUPTS_ENABLED))
700			break;
701		udelay(1);
702	}
703
704	if (i == adev->usec_timeout) {
705		DRM_ERROR("Timeout for SMC firmware initialization\n");
706		return -EINVAL;
707	}
708
709	return 0;
710}
711
712int tonga_smu_start(struct amdgpu_device *adev)
713{
714	int result;
715	uint32_t val;
716
717	if (!tonga_is_smc_ram_running(adev)) {
718		val = RREG32_SMC(ixSMU_FIRMWARE);
719		if (!REG_GET_FIELD(val, SMU_FIRMWARE, SMU_MODE)) {
720			result = tonga_smu_start_in_non_protection_mode(adev);
721			if (result)
722				return result;
723		} else {
724			result = tonga_smu_start_in_protection_mode(adev);
725			if (result)
726				return result;
727		}
728	}
729
730	return tonga_smu_request_load_fw(adev);
731}
732
733static const struct amdgpu_smumgr_funcs tonga_smumgr_funcs = {
734	.check_fw_load_finish = tonga_smu_check_fw_load_finish,
735	.request_smu_load_fw = NULL,
736	.request_smu_specific_fw = NULL,
737};
738
739int tonga_smu_init(struct amdgpu_device *adev)
740{
741	struct tonga_smu_private_data *private;
742	uint32_t image_size = ((sizeof(struct SMU_DRAMData_TOC) / 4096) + 1) * 4096;
743	uint32_t smu_internal_buffer_size = 200*4096;
744	struct amdgpu_bo **toc_buf = &adev->smu.toc_buf;
745	struct amdgpu_bo **smu_buf = &adev->smu.smu_buf;
746	uint64_t mc_addr;
747	void *toc_buf_ptr;
748	void *smu_buf_ptr;
749	int ret;
750
751	private = kzalloc(sizeof(struct tonga_smu_private_data), GFP_KERNEL);
752	if (NULL == private)
753		return -ENOMEM;
754
755	/* allocate firmware buffers */
756	if (adev->firmware.smu_load)
757		amdgpu_ucode_init_bo(adev);
758
759	adev->smu.priv = private;
760	adev->smu.fw_flags = 0;
761
762	/* Allocate FW image data structure and header buffer */
763	ret = amdgpu_bo_create(adev, image_size, PAGE_SIZE,
764			       true, AMDGPU_GEM_DOMAIN_VRAM,
765			       AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
766			       NULL, NULL, toc_buf);
767	if (ret) {
768		DRM_ERROR("Failed to allocate memory for TOC buffer\n");
769		return -ENOMEM;
770	}
771
772	/* Allocate buffer for SMU internal buffer */
773	ret = amdgpu_bo_create(adev, smu_internal_buffer_size, PAGE_SIZE,
774			       true, AMDGPU_GEM_DOMAIN_VRAM,
775			       AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED,
776			       NULL, NULL, smu_buf);
777	if (ret) {
778		DRM_ERROR("Failed to allocate memory for SMU internal buffer\n");
779		return -ENOMEM;
780	}
781
782	/* Retrieve GPU address for header buffer and internal buffer */
783	ret = amdgpu_bo_reserve(adev->smu.toc_buf, false);
784	if (ret) {
785		amdgpu_bo_unref(&adev->smu.toc_buf);
786		DRM_ERROR("Failed to reserve the TOC buffer\n");
787		return -EINVAL;
788	}
789
790	ret = amdgpu_bo_pin(adev->smu.toc_buf, AMDGPU_GEM_DOMAIN_VRAM, &mc_addr);
791	if (ret) {
792		amdgpu_bo_unreserve(adev->smu.toc_buf);
793		amdgpu_bo_unref(&adev->smu.toc_buf);
794		DRM_ERROR("Failed to pin the TOC buffer\n");
795		return -EINVAL;
796	}
797
798	ret = amdgpu_bo_kmap(*toc_buf, &toc_buf_ptr);
799	if (ret) {
800		amdgpu_bo_unreserve(adev->smu.toc_buf);
801		amdgpu_bo_unref(&adev->smu.toc_buf);
802		DRM_ERROR("Failed to map the TOC buffer\n");
803		return -EINVAL;
804	}
805
806	amdgpu_bo_unreserve(adev->smu.toc_buf);
807	private->header_addr_low = lower_32_bits(mc_addr);
808	private->header_addr_high = upper_32_bits(mc_addr);
809	private->header = toc_buf_ptr;
810
811	ret = amdgpu_bo_reserve(adev->smu.smu_buf, false);
812	if (ret) {
813		amdgpu_bo_unref(&adev->smu.smu_buf);
814		amdgpu_bo_unref(&adev->smu.toc_buf);
815		DRM_ERROR("Failed to reserve the SMU internal buffer\n");
816		return -EINVAL;
817	}
818
819	ret = amdgpu_bo_pin(adev->smu.smu_buf, AMDGPU_GEM_DOMAIN_VRAM, &mc_addr);
820	if (ret) {
821		amdgpu_bo_unreserve(adev->smu.smu_buf);
822		amdgpu_bo_unref(&adev->smu.smu_buf);
823		amdgpu_bo_unref(&adev->smu.toc_buf);
824		DRM_ERROR("Failed to pin the SMU internal buffer\n");
825		return -EINVAL;
826	}
827
828	ret = amdgpu_bo_kmap(*smu_buf, &smu_buf_ptr);
829	if (ret) {
830		amdgpu_bo_unreserve(adev->smu.smu_buf);
831		amdgpu_bo_unref(&adev->smu.smu_buf);
832		amdgpu_bo_unref(&adev->smu.toc_buf);
833		DRM_ERROR("Failed to map the SMU internal buffer\n");
834		return -EINVAL;
835	}
836
837	amdgpu_bo_unreserve(adev->smu.smu_buf);
838	private->smu_buffer_addr_low = lower_32_bits(mc_addr);
839	private->smu_buffer_addr_high = upper_32_bits(mc_addr);
840
841	adev->smu.smumgr_funcs = &tonga_smumgr_funcs;
842
843	return 0;
844}
845
846int tonga_smu_fini(struct amdgpu_device *adev)
847{
848	amdgpu_bo_unref(&adev->smu.toc_buf);
849	amdgpu_bo_unref(&adev->smu.smu_buf);
850	kfree(adev->smu.priv);
851	adev->smu.priv = NULL;
852	if (adev->firmware.fw_buf)
853		amdgpu_ucode_fini_bo(adev);
854
855	return 0;
856}
857