Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1/*
  2 * Copyright 2015 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/list.h>
 25#include <linux/pci.h>
 26#include <linux/slab.h>
 27
 28#include <linux/firmware.h>
 29#include <drm/amdgpu_drm.h>
 30#include "amdgpu.h"
 31#include "atom.h"
 32#include "amdgpu_ucode.h"
 33
 34struct amdgpu_cgs_device {
 35	struct cgs_device base;
 36	struct amdgpu_device *adev;
 37};
 38
 39#define CGS_FUNC_ADEV							\
 40	struct amdgpu_device *adev =					\
 41		((struct amdgpu_cgs_device *)cgs_device)->adev
 42
 43
 44static uint32_t amdgpu_cgs_read_register(struct cgs_device *cgs_device, unsigned int offset)
 45{
 46	CGS_FUNC_ADEV;
 47	return RREG32(offset);
 48}
 49
 50static void amdgpu_cgs_write_register(struct cgs_device *cgs_device, unsigned int offset,
 51				      uint32_t value)
 52{
 53	CGS_FUNC_ADEV;
 54	WREG32(offset, value);
 55}
 56
 57static uint32_t amdgpu_cgs_read_ind_register(struct cgs_device *cgs_device,
 58					     enum cgs_ind_reg space,
 59					     unsigned int index)
 60{
 61	CGS_FUNC_ADEV;
 62	switch (space) {
 63	case CGS_IND_REG__PCIE:
 64		return RREG32_PCIE(index);
 65	case CGS_IND_REG__SMC:
 66		return RREG32_SMC(index);
 67	case CGS_IND_REG__UVD_CTX:
 68		return RREG32_UVD_CTX(index);
 69	case CGS_IND_REG__DIDT:
 70		return RREG32_DIDT(index);
 71	case CGS_IND_REG_GC_CAC:
 72		return RREG32_GC_CAC(index);
 73	case CGS_IND_REG_SE_CAC:
 74		return RREG32_SE_CAC(index);
 75	case CGS_IND_REG__AUDIO_ENDPT:
 76		DRM_ERROR("audio endpt register access not implemented.\n");
 77		return 0;
 78	default:
 79		BUG();
 80	}
 81	WARN(1, "Invalid indirect register space");
 82	return 0;
 83}
 84
 85static void amdgpu_cgs_write_ind_register(struct cgs_device *cgs_device,
 86					  enum cgs_ind_reg space,
 87					  unsigned int index, uint32_t value)
 88{
 89	CGS_FUNC_ADEV;
 90	switch (space) {
 91	case CGS_IND_REG__PCIE:
 92		return WREG32_PCIE(index, value);
 93	case CGS_IND_REG__SMC:
 94		return WREG32_SMC(index, value);
 95	case CGS_IND_REG__UVD_CTX:
 96		return WREG32_UVD_CTX(index, value);
 97	case CGS_IND_REG__DIDT:
 98		return WREG32_DIDT(index, value);
 99	case CGS_IND_REG_GC_CAC:
100		return WREG32_GC_CAC(index, value);
101	case CGS_IND_REG_SE_CAC:
102		return WREG32_SE_CAC(index, value);
103	case CGS_IND_REG__AUDIO_ENDPT:
104		DRM_ERROR("audio endpt register access not implemented.\n");
105		return;
106	default:
107		BUG();
108	}
109	WARN(1, "Invalid indirect register space");
110}
111
112static uint32_t fw_type_convert(struct cgs_device *cgs_device, uint32_t fw_type)
113{
114	CGS_FUNC_ADEV;
115	enum AMDGPU_UCODE_ID result = AMDGPU_UCODE_ID_MAXIMUM;
116
117	switch (fw_type) {
118	case CGS_UCODE_ID_SDMA0:
119		result = AMDGPU_UCODE_ID_SDMA0;
120		break;
121	case CGS_UCODE_ID_SDMA1:
122		result = AMDGPU_UCODE_ID_SDMA1;
123		break;
124	case CGS_UCODE_ID_CP_CE:
125		result = AMDGPU_UCODE_ID_CP_CE;
126		break;
127	case CGS_UCODE_ID_CP_PFP:
128		result = AMDGPU_UCODE_ID_CP_PFP;
129		break;
130	case CGS_UCODE_ID_CP_ME:
131		result = AMDGPU_UCODE_ID_CP_ME;
132		break;
133	case CGS_UCODE_ID_CP_MEC:
134	case CGS_UCODE_ID_CP_MEC_JT1:
135		result = AMDGPU_UCODE_ID_CP_MEC1;
136		break;
137	case CGS_UCODE_ID_CP_MEC_JT2:
138		/* for VI. JT2 should be the same as JT1, because:
139			1, MEC2 and MEC1 use exactly same FW.
140			2, JT2 is not pached but JT1 is.
141		*/
142		if (adev->asic_type >= CHIP_TOPAZ)
143			result = AMDGPU_UCODE_ID_CP_MEC1;
144		else
145			result = AMDGPU_UCODE_ID_CP_MEC2;
146		break;
147	case CGS_UCODE_ID_RLC_G:
148		result = AMDGPU_UCODE_ID_RLC_G;
149		break;
150	case CGS_UCODE_ID_STORAGE:
151		result = AMDGPU_UCODE_ID_STORAGE;
152		break;
153	default:
154		DRM_ERROR("Firmware type not supported\n");
155	}
156	return result;
157}
158
159static uint16_t amdgpu_get_firmware_version(struct cgs_device *cgs_device,
160					enum cgs_ucode_id type)
161{
162	CGS_FUNC_ADEV;
163	uint16_t fw_version = 0;
164
165	switch (type) {
166	case CGS_UCODE_ID_SDMA0:
167		fw_version = adev->sdma.instance[0].fw_version;
168		break;
169	case CGS_UCODE_ID_SDMA1:
170		fw_version = adev->sdma.instance[1].fw_version;
171		break;
172	case CGS_UCODE_ID_CP_CE:
173		fw_version = adev->gfx.ce_fw_version;
174		break;
175	case CGS_UCODE_ID_CP_PFP:
176		fw_version = adev->gfx.pfp_fw_version;
177		break;
178	case CGS_UCODE_ID_CP_ME:
179		fw_version = adev->gfx.me_fw_version;
180		break;
181	case CGS_UCODE_ID_CP_MEC:
182		fw_version = adev->gfx.mec_fw_version;
183		break;
184	case CGS_UCODE_ID_CP_MEC_JT1:
185		fw_version = adev->gfx.mec_fw_version;
186		break;
187	case CGS_UCODE_ID_CP_MEC_JT2:
188		fw_version = adev->gfx.mec_fw_version;
189		break;
190	case CGS_UCODE_ID_RLC_G:
191		fw_version = adev->gfx.rlc_fw_version;
192		break;
193	case CGS_UCODE_ID_STORAGE:
194		break;
195	default:
196		DRM_ERROR("firmware type %d do not have version\n", type);
197		break;
198	}
199	return fw_version;
200}
201
202static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
203					enum cgs_ucode_id type,
204					struct cgs_firmware_info *info)
205{
206	CGS_FUNC_ADEV;
207
208	if (type != CGS_UCODE_ID_SMU && type != CGS_UCODE_ID_SMU_SK) {
209		uint64_t gpu_addr;
210		uint32_t data_size;
211		const struct gfx_firmware_header_v1_0 *header;
212		enum AMDGPU_UCODE_ID id;
213		struct amdgpu_firmware_info *ucode;
214
215		id = fw_type_convert(cgs_device, type);
216		ucode = &adev->firmware.ucode[id];
217		if (ucode->fw == NULL)
218			return -EINVAL;
219
220		gpu_addr  = ucode->mc_addr;
221		header = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data;
222		data_size = le32_to_cpu(header->header.ucode_size_bytes);
223
224		if ((type == CGS_UCODE_ID_CP_MEC_JT1) ||
225		    (type == CGS_UCODE_ID_CP_MEC_JT2)) {
226			gpu_addr += ALIGN(le32_to_cpu(header->header.ucode_size_bytes), PAGE_SIZE);
227			data_size = le32_to_cpu(header->jt_size) << 2;
228		}
229
230		info->kptr = ucode->kaddr;
231		info->image_size = data_size;
232		info->mc_addr = gpu_addr;
233		info->version = (uint16_t)le32_to_cpu(header->header.ucode_version);
234
235		if (type == CGS_UCODE_ID_CP_MEC)
236			info->image_size = le32_to_cpu(header->jt_offset) << 2;
237
238		info->fw_version = amdgpu_get_firmware_version(cgs_device, type);
239		info->feature_version = (uint16_t)le32_to_cpu(header->ucode_feature_version);
240	} else {
241		char fw_name[30] = {0};
242		int err = 0;
243		uint32_t ucode_size;
244		uint32_t ucode_start_address;
245		const uint8_t *src;
246		const struct smc_firmware_header_v1_0 *hdr;
247		const struct common_firmware_header *header;
248		struct amdgpu_firmware_info *ucode = NULL;
249
250		if (!adev->pm.fw) {
251			switch (adev->asic_type) {
252			case CHIP_TAHITI:
253				strcpy(fw_name, "radeon/tahiti_smc.bin");
254				break;
255			case CHIP_PITCAIRN:
256				if ((adev->pdev->revision == 0x81) &&
257				    ((adev->pdev->device == 0x6810) ||
258				    (adev->pdev->device == 0x6811))) {
259					info->is_kicker = true;
260					strcpy(fw_name, "radeon/pitcairn_k_smc.bin");
261				} else {
262					strcpy(fw_name, "radeon/pitcairn_smc.bin");
263				}
264				break;
265			case CHIP_VERDE:
266				if (((adev->pdev->device == 0x6820) &&
267					((adev->pdev->revision == 0x81) ||
268					(adev->pdev->revision == 0x83))) ||
269				    ((adev->pdev->device == 0x6821) &&
270					((adev->pdev->revision == 0x83) ||
271					(adev->pdev->revision == 0x87))) ||
272				    ((adev->pdev->revision == 0x87) &&
273					((adev->pdev->device == 0x6823) ||
274					(adev->pdev->device == 0x682b)))) {
275					info->is_kicker = true;
276					strcpy(fw_name, "radeon/verde_k_smc.bin");
277				} else {
278					strcpy(fw_name, "radeon/verde_smc.bin");
279				}
280				break;
281			case CHIP_OLAND:
282				if (((adev->pdev->revision == 0x81) &&
283					((adev->pdev->device == 0x6600) ||
284					(adev->pdev->device == 0x6604) ||
285					(adev->pdev->device == 0x6605) ||
286					(adev->pdev->device == 0x6610))) ||
287				    ((adev->pdev->revision == 0x83) &&
288					(adev->pdev->device == 0x6610))) {
289					info->is_kicker = true;
290					strcpy(fw_name, "radeon/oland_k_smc.bin");
291				} else {
292					strcpy(fw_name, "radeon/oland_smc.bin");
293				}
294				break;
295			case CHIP_HAINAN:
296				if (((adev->pdev->revision == 0x81) &&
297					(adev->pdev->device == 0x6660)) ||
298				    ((adev->pdev->revision == 0x83) &&
299					((adev->pdev->device == 0x6660) ||
300					(adev->pdev->device == 0x6663) ||
301					(adev->pdev->device == 0x6665) ||
302					 (adev->pdev->device == 0x6667)))) {
303					info->is_kicker = true;
304					strcpy(fw_name, "radeon/hainan_k_smc.bin");
305				} else if ((adev->pdev->revision == 0xc3) &&
306					 (adev->pdev->device == 0x6665)) {
307					info->is_kicker = true;
308					strcpy(fw_name, "radeon/banks_k_2_smc.bin");
309				} else {
310					strcpy(fw_name, "radeon/hainan_smc.bin");
311				}
312				break;
313			case CHIP_BONAIRE:
314				if ((adev->pdev->revision == 0x80) ||
315					(adev->pdev->revision == 0x81) ||
316					(adev->pdev->device == 0x665f)) {
317					info->is_kicker = true;
318					strcpy(fw_name, "amdgpu/bonaire_k_smc.bin");
319				} else {
320					strcpy(fw_name, "amdgpu/bonaire_smc.bin");
321				}
322				break;
323			case CHIP_HAWAII:
324				if (adev->pdev->revision == 0x80) {
325					info->is_kicker = true;
326					strcpy(fw_name, "amdgpu/hawaii_k_smc.bin");
327				} else {
328					strcpy(fw_name, "amdgpu/hawaii_smc.bin");
329				}
330				break;
331			case CHIP_TOPAZ:
332				if (((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x81)) ||
333				    ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0x83)) ||
334				    ((adev->pdev->device == 0x6907) && (adev->pdev->revision == 0x87)) ||
335				    ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0xD1)) ||
336				    ((adev->pdev->device == 0x6900) && (adev->pdev->revision == 0xD3))) {
337					info->is_kicker = true;
338					strcpy(fw_name, "amdgpu/topaz_k_smc.bin");
339				} else
340					strcpy(fw_name, "amdgpu/topaz_smc.bin");
341				break;
342			case CHIP_TONGA:
343				if (((adev->pdev->device == 0x6939) && (adev->pdev->revision == 0xf1)) ||
344				    ((adev->pdev->device == 0x6938) && (adev->pdev->revision == 0xf1))) {
345					info->is_kicker = true;
346					strcpy(fw_name, "amdgpu/tonga_k_smc.bin");
347				} else
348					strcpy(fw_name, "amdgpu/tonga_smc.bin");
349				break;
350			case CHIP_FIJI:
351				strcpy(fw_name, "amdgpu/fiji_smc.bin");
352				break;
353			case CHIP_POLARIS11:
354				if (type == CGS_UCODE_ID_SMU) {
355					if (ASICID_IS_P21(adev->pdev->device, adev->pdev->revision)) {
356						info->is_kicker = true;
357						strcpy(fw_name, "amdgpu/polaris11_k_smc.bin");
358					} else if (ASICID_IS_P31(adev->pdev->device, adev->pdev->revision)) {
359						info->is_kicker = true;
360						strcpy(fw_name, "amdgpu/polaris11_k2_smc.bin");
361					} else {
362						strcpy(fw_name, "amdgpu/polaris11_smc.bin");
363					}
364				} else if (type == CGS_UCODE_ID_SMU_SK) {
365					strcpy(fw_name, "amdgpu/polaris11_smc_sk.bin");
366				}
367				break;
368			case CHIP_POLARIS10:
369				if (type == CGS_UCODE_ID_SMU) {
370					if (ASICID_IS_P20(adev->pdev->device, adev->pdev->revision)) {
371						info->is_kicker = true;
372						strcpy(fw_name, "amdgpu/polaris10_k_smc.bin");
373					} else if (ASICID_IS_P30(adev->pdev->device, adev->pdev->revision)) {
374						info->is_kicker = true;
375						strcpy(fw_name, "amdgpu/polaris10_k2_smc.bin");
376					} else {
377						strcpy(fw_name, "amdgpu/polaris10_smc.bin");
378					}
379				} else if (type == CGS_UCODE_ID_SMU_SK) {
380					strcpy(fw_name, "amdgpu/polaris10_smc_sk.bin");
381				}
382				break;
383			case CHIP_POLARIS12:
384				if (ASICID_IS_P23(adev->pdev->device, adev->pdev->revision)) {
385					info->is_kicker = true;
386					strcpy(fw_name, "amdgpu/polaris12_k_smc.bin");
387				} else {
388					strcpy(fw_name, "amdgpu/polaris12_smc.bin");
389				}
390				break;
391			case CHIP_VEGAM:
392				strcpy(fw_name, "amdgpu/vegam_smc.bin");
393				break;
394			case CHIP_VEGA10:
395				if ((adev->pdev->device == 0x687f) &&
396					((adev->pdev->revision == 0xc0) ||
397					(adev->pdev->revision == 0xc1) ||
398					(adev->pdev->revision == 0xc3)))
399					strcpy(fw_name, "amdgpu/vega10_acg_smc.bin");
400				else
401					strcpy(fw_name, "amdgpu/vega10_smc.bin");
402				break;
403			case CHIP_VEGA12:
404				strcpy(fw_name, "amdgpu/vega12_smc.bin");
405				break;
406			case CHIP_VEGA20:
407				strcpy(fw_name, "amdgpu/vega20_smc.bin");
408				break;
409			default:
410				DRM_ERROR("SMC firmware not supported\n");
411				return -EINVAL;
412			}
413
414			err = amdgpu_ucode_request(adev, &adev->pm.fw, fw_name);
415			if (err) {
416				DRM_ERROR("Failed to load firmware \"%s\"", fw_name);
417				amdgpu_ucode_release(&adev->pm.fw);
418				return err;
419			}
420
421			if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
422				ucode = &adev->firmware.ucode[AMDGPU_UCODE_ID_SMC];
423				ucode->ucode_id = AMDGPU_UCODE_ID_SMC;
424				ucode->fw = adev->pm.fw;
425				header = (const struct common_firmware_header *)ucode->fw->data;
426				adev->firmware.fw_size +=
427					ALIGN(le32_to_cpu(header->ucode_size_bytes), PAGE_SIZE);
428			}
429		}
430
431		hdr = (const struct smc_firmware_header_v1_0 *)	adev->pm.fw->data;
432		amdgpu_ucode_print_smc_hdr(&hdr->header);
433		adev->pm.fw_version = le32_to_cpu(hdr->header.ucode_version);
434		ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes);
435		ucode_start_address = le32_to_cpu(hdr->ucode_start_addr);
436		src = (const uint8_t *)(adev->pm.fw->data +
437		       le32_to_cpu(hdr->header.ucode_array_offset_bytes));
438
439		info->version = adev->pm.fw_version;
440		info->image_size = ucode_size;
441		info->ucode_start_address = ucode_start_address;
442		info->kptr = (void *)src;
443	}
444	return 0;
445}
446
447static const struct cgs_ops amdgpu_cgs_ops = {
448	.read_register = amdgpu_cgs_read_register,
449	.write_register = amdgpu_cgs_write_register,
450	.read_ind_register = amdgpu_cgs_read_ind_register,
451	.write_ind_register = amdgpu_cgs_write_ind_register,
452	.get_firmware_info = amdgpu_cgs_get_firmware_info,
453};
454
455struct cgs_device *amdgpu_cgs_create_device(struct amdgpu_device *adev)
456{
457	struct amdgpu_cgs_device *cgs_device =
458		kmalloc(sizeof(*cgs_device), GFP_KERNEL);
459
460	if (!cgs_device) {
461		DRM_ERROR("Couldn't allocate CGS device structure\n");
462		return NULL;
463	}
464
465	cgs_device->base.ops = &amdgpu_cgs_ops;
466	cgs_device->adev = adev;
467
468	return (struct cgs_device *)cgs_device;
469}
470
471void amdgpu_cgs_destroy_device(struct cgs_device *cgs_device)
472{
473	kfree(cgs_device);
474}