Linux Audio

Check our new training course

Linux kernel drivers training

May 6-19, 2025
Register
Loading...
v6.9.4
  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}
v4.6
   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/slab.h>
  26#include <linux/pci.h>
  27#include <linux/acpi.h>
  28#include <drm/drmP.h>
  29#include <linux/firmware.h>
  30#include <drm/amdgpu_drm.h>
  31#include "amdgpu.h"
  32#include "cgs_linux.h"
  33#include "atom.h"
  34#include "amdgpu_ucode.h"
  35
  36struct amdgpu_cgs_device {
  37	struct cgs_device base;
  38	struct amdgpu_device *adev;
  39};
  40
  41#define CGS_FUNC_ADEV							\
  42	struct amdgpu_device *adev =					\
  43		((struct amdgpu_cgs_device *)cgs_device)->adev
  44
  45static int amdgpu_cgs_gpu_mem_info(void *cgs_device, enum cgs_gpu_mem_type type,
  46				   uint64_t *mc_start, uint64_t *mc_size,
  47				   uint64_t *mem_size)
  48{
  49	CGS_FUNC_ADEV;
  50	switch(type) {
  51	case CGS_GPU_MEM_TYPE__VISIBLE_CONTIG_FB:
  52	case CGS_GPU_MEM_TYPE__VISIBLE_FB:
  53		*mc_start = 0;
  54		*mc_size = adev->mc.visible_vram_size;
  55		*mem_size = adev->mc.visible_vram_size - adev->vram_pin_size;
  56		break;
  57	case CGS_GPU_MEM_TYPE__INVISIBLE_CONTIG_FB:
  58	case CGS_GPU_MEM_TYPE__INVISIBLE_FB:
  59		*mc_start = adev->mc.visible_vram_size;
  60		*mc_size = adev->mc.real_vram_size - adev->mc.visible_vram_size;
  61		*mem_size = *mc_size;
  62		break;
  63	case CGS_GPU_MEM_TYPE__GART_CACHEABLE:
  64	case CGS_GPU_MEM_TYPE__GART_WRITECOMBINE:
  65		*mc_start = adev->mc.gtt_start;
  66		*mc_size = adev->mc.gtt_size;
  67		*mem_size = adev->mc.gtt_size - adev->gart_pin_size;
  68		break;
  69	default:
  70		return -EINVAL;
  71	}
  72
  73	return 0;
  74}
  75
  76static int amdgpu_cgs_gmap_kmem(void *cgs_device, void *kmem,
  77				uint64_t size,
  78				uint64_t min_offset, uint64_t max_offset,
  79				cgs_handle_t *kmem_handle, uint64_t *mcaddr)
  80{
  81	CGS_FUNC_ADEV;
  82	int ret;
  83	struct amdgpu_bo *bo;
  84	struct page *kmem_page = vmalloc_to_page(kmem);
  85	int npages = ALIGN(size, PAGE_SIZE) >> PAGE_SHIFT;
  86
  87	struct sg_table *sg = drm_prime_pages_to_sg(&kmem_page, npages);
  88	ret = amdgpu_bo_create(adev, size, PAGE_SIZE, false,
  89			       AMDGPU_GEM_DOMAIN_GTT, 0, sg, NULL, &bo);
  90	if (ret)
  91		return ret;
  92	ret = amdgpu_bo_reserve(bo, false);
  93	if (unlikely(ret != 0))
  94		return ret;
  95
  96	/* pin buffer into GTT */
  97	ret = amdgpu_bo_pin_restricted(bo, AMDGPU_GEM_DOMAIN_GTT,
  98				       min_offset, max_offset, mcaddr);
  99	amdgpu_bo_unreserve(bo);
 100
 101	*kmem_handle = (cgs_handle_t)bo;
 102	return ret;
 103}
 104
 105static int amdgpu_cgs_gunmap_kmem(void *cgs_device, cgs_handle_t kmem_handle)
 106{
 107	struct amdgpu_bo *obj = (struct amdgpu_bo *)kmem_handle;
 108
 109	if (obj) {
 110		int r = amdgpu_bo_reserve(obj, false);
 111		if (likely(r == 0)) {
 112			amdgpu_bo_unpin(obj);
 113			amdgpu_bo_unreserve(obj);
 114		}
 115		amdgpu_bo_unref(&obj);
 116
 117	}
 118	return 0;
 119}
 120
 121static int amdgpu_cgs_alloc_gpu_mem(void *cgs_device,
 122				    enum cgs_gpu_mem_type type,
 123				    uint64_t size, uint64_t align,
 124				    uint64_t min_offset, uint64_t max_offset,
 125				    cgs_handle_t *handle)
 126{
 127	CGS_FUNC_ADEV;
 128	uint16_t flags = 0;
 129	int ret = 0;
 130	uint32_t domain = 0;
 131	struct amdgpu_bo *obj;
 132	struct ttm_placement placement;
 133	struct ttm_place place;
 134
 135	if (min_offset > max_offset) {
 136		BUG_ON(1);
 137		return -EINVAL;
 138	}
 139
 140	/* fail if the alignment is not a power of 2 */
 141	if (((align != 1) && (align & (align - 1)))
 142	    || size == 0 || align == 0)
 143		return -EINVAL;
 144
 145
 146	switch(type) {
 147	case CGS_GPU_MEM_TYPE__VISIBLE_CONTIG_FB:
 148	case CGS_GPU_MEM_TYPE__VISIBLE_FB:
 149		flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
 150		domain = AMDGPU_GEM_DOMAIN_VRAM;
 151		if (max_offset > adev->mc.real_vram_size)
 152			return -EINVAL;
 153		place.fpfn = min_offset >> PAGE_SHIFT;
 154		place.lpfn = max_offset >> PAGE_SHIFT;
 155		place.flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED |
 156			TTM_PL_FLAG_VRAM;
 157		break;
 158	case CGS_GPU_MEM_TYPE__INVISIBLE_CONTIG_FB:
 159	case CGS_GPU_MEM_TYPE__INVISIBLE_FB:
 160		flags = AMDGPU_GEM_CREATE_NO_CPU_ACCESS;
 161		domain = AMDGPU_GEM_DOMAIN_VRAM;
 162		if (adev->mc.visible_vram_size < adev->mc.real_vram_size) {
 163			place.fpfn =
 164				max(min_offset, adev->mc.visible_vram_size) >> PAGE_SHIFT;
 165			place.lpfn =
 166				min(max_offset, adev->mc.real_vram_size) >> PAGE_SHIFT;
 167			place.flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED |
 168				TTM_PL_FLAG_VRAM;
 169		}
 170
 171		break;
 172	case CGS_GPU_MEM_TYPE__GART_CACHEABLE:
 173		domain = AMDGPU_GEM_DOMAIN_GTT;
 174		place.fpfn = min_offset >> PAGE_SHIFT;
 175		place.lpfn = max_offset >> PAGE_SHIFT;
 176		place.flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_TT;
 177		break;
 178	case CGS_GPU_MEM_TYPE__GART_WRITECOMBINE:
 179		flags = AMDGPU_GEM_CREATE_CPU_GTT_USWC;
 180		domain = AMDGPU_GEM_DOMAIN_GTT;
 181		place.fpfn = min_offset >> PAGE_SHIFT;
 182		place.lpfn = max_offset >> PAGE_SHIFT;
 183		place.flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_TT |
 184			TTM_PL_FLAG_UNCACHED;
 185		break;
 186	default:
 187		return -EINVAL;
 188	}
 189
 190
 191	*handle = 0;
 192
 193	placement.placement = &place;
 194	placement.num_placement = 1;
 195	placement.busy_placement = &place;
 196	placement.num_busy_placement = 1;
 197
 198	ret = amdgpu_bo_create_restricted(adev, size, PAGE_SIZE,
 199					  true, domain, flags,
 200					  NULL, &placement, NULL,
 201					  &obj);
 202	if (ret) {
 203		DRM_ERROR("(%d) bo create failed\n", ret);
 204		return ret;
 205	}
 206	*handle = (cgs_handle_t)obj;
 207
 208	return ret;
 209}
 210
 211static int amdgpu_cgs_free_gpu_mem(void *cgs_device, cgs_handle_t handle)
 212{
 213	struct amdgpu_bo *obj = (struct amdgpu_bo *)handle;
 214
 215	if (obj) {
 216		int r = amdgpu_bo_reserve(obj, false);
 217		if (likely(r == 0)) {
 218			amdgpu_bo_kunmap(obj);
 219			amdgpu_bo_unpin(obj);
 220			amdgpu_bo_unreserve(obj);
 221		}
 222		amdgpu_bo_unref(&obj);
 223
 224	}
 225	return 0;
 226}
 227
 228static int amdgpu_cgs_gmap_gpu_mem(void *cgs_device, cgs_handle_t handle,
 229				   uint64_t *mcaddr)
 230{
 231	int r;
 232	u64 min_offset, max_offset;
 233	struct amdgpu_bo *obj = (struct amdgpu_bo *)handle;
 234
 235	WARN_ON_ONCE(obj->placement.num_placement > 1);
 236
 237	min_offset = obj->placements[0].fpfn << PAGE_SHIFT;
 238	max_offset = obj->placements[0].lpfn << PAGE_SHIFT;
 239
 240	r = amdgpu_bo_reserve(obj, false);
 241	if (unlikely(r != 0))
 242		return r;
 243	r = amdgpu_bo_pin_restricted(obj, AMDGPU_GEM_DOMAIN_GTT,
 244				     min_offset, max_offset, mcaddr);
 245	amdgpu_bo_unreserve(obj);
 246	return r;
 247}
 248
 249static int amdgpu_cgs_gunmap_gpu_mem(void *cgs_device, cgs_handle_t handle)
 250{
 251	int r;
 252	struct amdgpu_bo *obj = (struct amdgpu_bo *)handle;
 253	r = amdgpu_bo_reserve(obj, false);
 254	if (unlikely(r != 0))
 255		return r;
 256	r = amdgpu_bo_unpin(obj);
 257	amdgpu_bo_unreserve(obj);
 258	return r;
 259}
 260
 261static int amdgpu_cgs_kmap_gpu_mem(void *cgs_device, cgs_handle_t handle,
 262				   void **map)
 263{
 264	int r;
 265	struct amdgpu_bo *obj = (struct amdgpu_bo *)handle;
 266	r = amdgpu_bo_reserve(obj, false);
 267	if (unlikely(r != 0))
 268		return r;
 269	r = amdgpu_bo_kmap(obj, map);
 270	amdgpu_bo_unreserve(obj);
 271	return r;
 272}
 273
 274static int amdgpu_cgs_kunmap_gpu_mem(void *cgs_device, cgs_handle_t handle)
 275{
 276	int r;
 277	struct amdgpu_bo *obj = (struct amdgpu_bo *)handle;
 278	r = amdgpu_bo_reserve(obj, false);
 279	if (unlikely(r != 0))
 280		return r;
 281	amdgpu_bo_kunmap(obj);
 282	amdgpu_bo_unreserve(obj);
 283	return r;
 284}
 285
 286static uint32_t amdgpu_cgs_read_register(void *cgs_device, unsigned offset)
 287{
 288	CGS_FUNC_ADEV;
 289	return RREG32(offset);
 290}
 291
 292static void amdgpu_cgs_write_register(void *cgs_device, unsigned offset,
 293				      uint32_t value)
 294{
 295	CGS_FUNC_ADEV;
 296	WREG32(offset, value);
 297}
 298
 299static uint32_t amdgpu_cgs_read_ind_register(void *cgs_device,
 300					     enum cgs_ind_reg space,
 301					     unsigned index)
 302{
 303	CGS_FUNC_ADEV;
 304	switch (space) {
 305	case CGS_IND_REG__MMIO:
 306		return RREG32_IDX(index);
 307	case CGS_IND_REG__PCIE:
 308		return RREG32_PCIE(index);
 309	case CGS_IND_REG__SMC:
 310		return RREG32_SMC(index);
 311	case CGS_IND_REG__UVD_CTX:
 312		return RREG32_UVD_CTX(index);
 313	case CGS_IND_REG__DIDT:
 314		return RREG32_DIDT(index);
 
 
 
 
 315	case CGS_IND_REG__AUDIO_ENDPT:
 316		DRM_ERROR("audio endpt register access not implemented.\n");
 317		return 0;
 
 
 318	}
 319	WARN(1, "Invalid indirect register space");
 320	return 0;
 321}
 322
 323static void amdgpu_cgs_write_ind_register(void *cgs_device,
 324					  enum cgs_ind_reg space,
 325					  unsigned index, uint32_t value)
 326{
 327	CGS_FUNC_ADEV;
 328	switch (space) {
 329	case CGS_IND_REG__MMIO:
 330		return WREG32_IDX(index, value);
 331	case CGS_IND_REG__PCIE:
 332		return WREG32_PCIE(index, value);
 333	case CGS_IND_REG__SMC:
 334		return WREG32_SMC(index, value);
 335	case CGS_IND_REG__UVD_CTX:
 336		return WREG32_UVD_CTX(index, value);
 337	case CGS_IND_REG__DIDT:
 338		return WREG32_DIDT(index, value);
 
 
 
 
 339	case CGS_IND_REG__AUDIO_ENDPT:
 340		DRM_ERROR("audio endpt register access not implemented.\n");
 341		return;
 
 
 342	}
 343	WARN(1, "Invalid indirect register space");
 344}
 345
 346static uint8_t amdgpu_cgs_read_pci_config_byte(void *cgs_device, unsigned addr)
 347{
 348	CGS_FUNC_ADEV;
 349	uint8_t val;
 350	int ret = pci_read_config_byte(adev->pdev, addr, &val);
 351	if (WARN(ret, "pci_read_config_byte error"))
 352		return 0;
 353	return val;
 354}
 355
 356static uint16_t amdgpu_cgs_read_pci_config_word(void *cgs_device, unsigned addr)
 357{
 358	CGS_FUNC_ADEV;
 359	uint16_t val;
 360	int ret = pci_read_config_word(adev->pdev, addr, &val);
 361	if (WARN(ret, "pci_read_config_word error"))
 362		return 0;
 363	return val;
 364}
 365
 366static uint32_t amdgpu_cgs_read_pci_config_dword(void *cgs_device,
 367						 unsigned addr)
 368{
 369	CGS_FUNC_ADEV;
 370	uint32_t val;
 371	int ret = pci_read_config_dword(adev->pdev, addr, &val);
 372	if (WARN(ret, "pci_read_config_dword error"))
 373		return 0;
 374	return val;
 375}
 376
 377static void amdgpu_cgs_write_pci_config_byte(void *cgs_device, unsigned addr,
 378					     uint8_t value)
 379{
 380	CGS_FUNC_ADEV;
 381	int ret = pci_write_config_byte(adev->pdev, addr, value);
 382	WARN(ret, "pci_write_config_byte error");
 383}
 384
 385static void amdgpu_cgs_write_pci_config_word(void *cgs_device, unsigned addr,
 386					     uint16_t value)
 387{
 388	CGS_FUNC_ADEV;
 389	int ret = pci_write_config_word(adev->pdev, addr, value);
 390	WARN(ret, "pci_write_config_word error");
 391}
 392
 393static void amdgpu_cgs_write_pci_config_dword(void *cgs_device, unsigned addr,
 394					      uint32_t value)
 395{
 396	CGS_FUNC_ADEV;
 397	int ret = pci_write_config_dword(adev->pdev, addr, value);
 398	WARN(ret, "pci_write_config_dword error");
 399}
 400
 401
 402static int amdgpu_cgs_get_pci_resource(void *cgs_device,
 403				       enum cgs_resource_type resource_type,
 404				       uint64_t size,
 405				       uint64_t offset,
 406				       uint64_t *resource_base)
 407{
 408	CGS_FUNC_ADEV;
 409
 410	if (resource_base == NULL)
 411		return -EINVAL;
 412
 413	switch (resource_type) {
 414	case CGS_RESOURCE_TYPE_MMIO:
 415		if (adev->rmmio_size == 0)
 416			return -ENOENT;
 417		if ((offset + size) > adev->rmmio_size)
 418			return -EINVAL;
 419		*resource_base = adev->rmmio_base;
 420		return 0;
 421	case CGS_RESOURCE_TYPE_DOORBELL:
 422		if (adev->doorbell.size == 0)
 423			return -ENOENT;
 424		if ((offset + size) > adev->doorbell.size)
 425			return -EINVAL;
 426		*resource_base = adev->doorbell.base;
 427		return 0;
 428	case CGS_RESOURCE_TYPE_FB:
 429	case CGS_RESOURCE_TYPE_IO:
 430	case CGS_RESOURCE_TYPE_ROM:
 431	default:
 432		return -EINVAL;
 433	}
 434}
 435
 436static const void *amdgpu_cgs_atom_get_data_table(void *cgs_device,
 437						  unsigned table, uint16_t *size,
 438						  uint8_t *frev, uint8_t *crev)
 439{
 440	CGS_FUNC_ADEV;
 441	uint16_t data_start;
 442
 443	if (amdgpu_atom_parse_data_header(
 444		    adev->mode_info.atom_context, table, size,
 445		    frev, crev, &data_start))
 446		return (uint8_t*)adev->mode_info.atom_context->bios +
 447			data_start;
 448
 449	return NULL;
 450}
 451
 452static int amdgpu_cgs_atom_get_cmd_table_revs(void *cgs_device, unsigned table,
 453					      uint8_t *frev, uint8_t *crev)
 454{
 455	CGS_FUNC_ADEV;
 456
 457	if (amdgpu_atom_parse_cmd_header(
 458		    adev->mode_info.atom_context, table,
 459		    frev, crev))
 460		return 0;
 461
 462	return -EINVAL;
 463}
 464
 465static int amdgpu_cgs_atom_exec_cmd_table(void *cgs_device, unsigned table,
 466					  void *args)
 467{
 468	CGS_FUNC_ADEV;
 469
 470	return amdgpu_atom_execute_table(
 471		adev->mode_info.atom_context, table, args);
 472}
 473
 474static int amdgpu_cgs_create_pm_request(void *cgs_device, cgs_handle_t *request)
 475{
 476	/* TODO */
 477	return 0;
 478}
 479
 480static int amdgpu_cgs_destroy_pm_request(void *cgs_device, cgs_handle_t request)
 481{
 482	/* TODO */
 483	return 0;
 484}
 485
 486static int amdgpu_cgs_set_pm_request(void *cgs_device, cgs_handle_t request,
 487				     int active)
 488{
 489	/* TODO */
 490	return 0;
 491}
 492
 493static int amdgpu_cgs_pm_request_clock(void *cgs_device, cgs_handle_t request,
 494				       enum cgs_clock clock, unsigned freq)
 495{
 496	/* TODO */
 497	return 0;
 498}
 499
 500static int amdgpu_cgs_pm_request_engine(void *cgs_device, cgs_handle_t request,
 501					enum cgs_engine engine, int powered)
 502{
 503	/* TODO */
 504	return 0;
 505}
 506
 507
 508
 509static int amdgpu_cgs_pm_query_clock_limits(void *cgs_device,
 510					    enum cgs_clock clock,
 511					    struct cgs_clock_limits *limits)
 512{
 513	/* TODO */
 514	return 0;
 515}
 516
 517static int amdgpu_cgs_set_camera_voltages(void *cgs_device, uint32_t mask,
 518					  const uint32_t *voltages)
 519{
 520	DRM_ERROR("not implemented");
 521	return -EPERM;
 522}
 523
 524struct cgs_irq_params {
 525	unsigned src_id;
 526	cgs_irq_source_set_func_t set;
 527	cgs_irq_handler_func_t handler;
 528	void *private_data;
 529};
 530
 531static int cgs_set_irq_state(struct amdgpu_device *adev,
 532			     struct amdgpu_irq_src *src,
 533			     unsigned type,
 534			     enum amdgpu_interrupt_state state)
 535{
 536	struct cgs_irq_params *irq_params =
 537		(struct cgs_irq_params *)src->data;
 538	if (!irq_params)
 539		return -EINVAL;
 540	if (!irq_params->set)
 541		return -EINVAL;
 542	return irq_params->set(irq_params->private_data,
 543			       irq_params->src_id,
 544			       type,
 545			       (int)state);
 546}
 547
 548static int cgs_process_irq(struct amdgpu_device *adev,
 549			   struct amdgpu_irq_src *source,
 550			   struct amdgpu_iv_entry *entry)
 551{
 552	struct cgs_irq_params *irq_params =
 553		(struct cgs_irq_params *)source->data;
 554	if (!irq_params)
 555		return -EINVAL;
 556	if (!irq_params->handler)
 557		return -EINVAL;
 558	return irq_params->handler(irq_params->private_data,
 559				   irq_params->src_id,
 560				   entry->iv_entry);
 561}
 562
 563static const struct amdgpu_irq_src_funcs cgs_irq_funcs = {
 564	.set = cgs_set_irq_state,
 565	.process = cgs_process_irq,
 566};
 567
 568static int amdgpu_cgs_add_irq_source(void *cgs_device, unsigned src_id,
 569				     unsigned num_types,
 570				     cgs_irq_source_set_func_t set,
 571				     cgs_irq_handler_func_t handler,
 572				     void *private_data)
 573{
 574	CGS_FUNC_ADEV;
 575	int ret = 0;
 576	struct cgs_irq_params *irq_params;
 577	struct amdgpu_irq_src *source =
 578		kzalloc(sizeof(struct amdgpu_irq_src), GFP_KERNEL);
 579	if (!source)
 580		return -ENOMEM;
 581	irq_params =
 582		kzalloc(sizeof(struct cgs_irq_params), GFP_KERNEL);
 583	if (!irq_params) {
 584		kfree(source);
 585		return -ENOMEM;
 586	}
 587	source->num_types = num_types;
 588	source->funcs = &cgs_irq_funcs;
 589	irq_params->src_id = src_id;
 590	irq_params->set = set;
 591	irq_params->handler = handler;
 592	irq_params->private_data = private_data;
 593	source->data = (void *)irq_params;
 594	ret = amdgpu_irq_add_id(adev, src_id, source);
 595	if (ret) {
 596		kfree(irq_params);
 597		kfree(source);
 598	}
 599
 600	return ret;
 601}
 602
 603static int amdgpu_cgs_irq_get(void *cgs_device, unsigned src_id, unsigned type)
 604{
 605	CGS_FUNC_ADEV;
 606	return amdgpu_irq_get(adev, adev->irq.sources[src_id], type);
 607}
 608
 609static int amdgpu_cgs_irq_put(void *cgs_device, unsigned src_id, unsigned type)
 610{
 611	CGS_FUNC_ADEV;
 612	return amdgpu_irq_put(adev, adev->irq.sources[src_id], type);
 613}
 614
 615int amdgpu_cgs_set_clockgating_state(void *cgs_device,
 616				  enum amd_ip_block_type block_type,
 617				  enum amd_clockgating_state state)
 618{
 619	CGS_FUNC_ADEV;
 620	int i, r = -1;
 621
 622	for (i = 0; i < adev->num_ip_blocks; i++) {
 623		if (!adev->ip_block_status[i].valid)
 624			continue;
 625
 626		if (adev->ip_blocks[i].type == block_type) {
 627			r = adev->ip_blocks[i].funcs->set_clockgating_state(
 628								(void *)adev,
 629									state);
 630			break;
 631		}
 632	}
 633	return r;
 634}
 635
 636int amdgpu_cgs_set_powergating_state(void *cgs_device,
 637				  enum amd_ip_block_type block_type,
 638				  enum amd_powergating_state state)
 639{
 640	CGS_FUNC_ADEV;
 641	int i, r = -1;
 642
 643	for (i = 0; i < adev->num_ip_blocks; i++) {
 644		if (!adev->ip_block_status[i].valid)
 645			continue;
 646
 647		if (adev->ip_blocks[i].type == block_type) {
 648			r = adev->ip_blocks[i].funcs->set_powergating_state(
 649								(void *)adev,
 650									state);
 651			break;
 652		}
 653	}
 654	return r;
 655}
 656
 657
 658static uint32_t fw_type_convert(void *cgs_device, uint32_t fw_type)
 659{
 660	CGS_FUNC_ADEV;
 661	enum AMDGPU_UCODE_ID result = AMDGPU_UCODE_ID_MAXIMUM;
 662
 663	switch (fw_type) {
 664	case CGS_UCODE_ID_SDMA0:
 665		result = AMDGPU_UCODE_ID_SDMA0;
 666		break;
 667	case CGS_UCODE_ID_SDMA1:
 668		result = AMDGPU_UCODE_ID_SDMA1;
 669		break;
 670	case CGS_UCODE_ID_CP_CE:
 671		result = AMDGPU_UCODE_ID_CP_CE;
 672		break;
 673	case CGS_UCODE_ID_CP_PFP:
 674		result = AMDGPU_UCODE_ID_CP_PFP;
 675		break;
 676	case CGS_UCODE_ID_CP_ME:
 677		result = AMDGPU_UCODE_ID_CP_ME;
 678		break;
 679	case CGS_UCODE_ID_CP_MEC:
 680	case CGS_UCODE_ID_CP_MEC_JT1:
 681		result = AMDGPU_UCODE_ID_CP_MEC1;
 682		break;
 683	case CGS_UCODE_ID_CP_MEC_JT2:
 684		if (adev->asic_type == CHIP_TONGA)
 
 
 
 
 
 
 685			result = AMDGPU_UCODE_ID_CP_MEC2;
 686		else if (adev->asic_type == CHIP_CARRIZO)
 687			result = AMDGPU_UCODE_ID_CP_MEC1;
 688		break;
 689	case CGS_UCODE_ID_RLC_G:
 690		result = AMDGPU_UCODE_ID_RLC_G;
 691		break;
 
 
 
 692	default:
 693		DRM_ERROR("Firmware type not supported\n");
 694	}
 695	return result;
 696}
 697
 698static int amdgpu_cgs_get_firmware_info(void *cgs_device,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 699					enum cgs_ucode_id type,
 700					struct cgs_firmware_info *info)
 701{
 702	CGS_FUNC_ADEV;
 703
 704	if (CGS_UCODE_ID_SMU != type) {
 705		uint64_t gpu_addr;
 706		uint32_t data_size;
 707		const struct gfx_firmware_header_v1_0 *header;
 708		enum AMDGPU_UCODE_ID id;
 709		struct amdgpu_firmware_info *ucode;
 710
 711		id = fw_type_convert(cgs_device, type);
 712		ucode = &adev->firmware.ucode[id];
 713		if (ucode->fw == NULL)
 714			return -EINVAL;
 715
 716		gpu_addr  = ucode->mc_addr;
 717		header = (const struct gfx_firmware_header_v1_0 *)ucode->fw->data;
 718		data_size = le32_to_cpu(header->header.ucode_size_bytes);
 719
 720		if ((type == CGS_UCODE_ID_CP_MEC_JT1) ||
 721		    (type == CGS_UCODE_ID_CP_MEC_JT2)) {
 722			gpu_addr += le32_to_cpu(header->jt_offset) << 2;
 723			data_size = le32_to_cpu(header->jt_size) << 2;
 724		}
 
 
 
 725		info->mc_addr = gpu_addr;
 726		info->image_size = data_size;
 727		info->version = (uint16_t)le32_to_cpu(header->header.ucode_version);
 
 
 
 
 
 728		info->feature_version = (uint16_t)le32_to_cpu(header->ucode_feature_version);
 729	} else {
 730		char fw_name[30] = {0};
 731		int err = 0;
 732		uint32_t ucode_size;
 733		uint32_t ucode_start_address;
 734		const uint8_t *src;
 735		const struct smc_firmware_header_v1_0 *hdr;
 
 
 736
 737		switch (adev->asic_type) {
 738		case CHIP_TONGA:
 739			strcpy(fw_name, "amdgpu/tonga_smc.bin");
 740			break;
 741		case CHIP_FIJI:
 742			strcpy(fw_name, "amdgpu/fiji_smc.bin");
 743			break;
 744		default:
 745			DRM_ERROR("SMC firmware not supported\n");
 746			return -EINVAL;
 747		}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 748
 749		err = request_firmware(&adev->pm.fw, fw_name, adev->dev);
 750		if (err) {
 751			DRM_ERROR("Failed to request firmware\n");
 752			return err;
 753		}
 
 754
 755		err = amdgpu_ucode_validate(adev->pm.fw);
 756		if (err) {
 757			DRM_ERROR("Failed to load firmware \"%s\"", fw_name);
 758			release_firmware(adev->pm.fw);
 759			adev->pm.fw = NULL;
 760			return err;
 
 
 761		}
 762
 763		hdr = (const struct smc_firmware_header_v1_0 *)	adev->pm.fw->data;
 
 764		adev->pm.fw_version = le32_to_cpu(hdr->header.ucode_version);
 765		ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes);
 766		ucode_start_address = le32_to_cpu(hdr->ucode_start_addr);
 767		src = (const uint8_t *)(adev->pm.fw->data +
 768		       le32_to_cpu(hdr->header.ucode_array_offset_bytes));
 769
 770		info->version = adev->pm.fw_version;
 771		info->image_size = ucode_size;
 
 772		info->kptr = (void *)src;
 773	}
 774	return 0;
 775}
 776
 777static int amdgpu_cgs_query_system_info(void *cgs_device,
 778				struct cgs_system_info *sys_info)
 779{
 780	CGS_FUNC_ADEV;
 781
 782	if (NULL == sys_info)
 783		return -ENODEV;
 784
 785	if (sizeof(struct cgs_system_info) != sys_info->size)
 786		return -ENODEV;
 787
 788	switch (sys_info->info_id) {
 789	case CGS_SYSTEM_INFO_ADAPTER_BDF_ID:
 790		sys_info->value = adev->pdev->devfn | (adev->pdev->bus->number << 8);
 791		break;
 792	case CGS_SYSTEM_INFO_PCIE_GEN_INFO:
 793		sys_info->value = adev->pm.pcie_gen_mask;
 794		break;
 795	case CGS_SYSTEM_INFO_PCIE_MLW:
 796		sys_info->value = adev->pm.pcie_mlw_mask;
 797		break;
 798	case CGS_SYSTEM_INFO_CG_FLAGS:
 799		sys_info->value = adev->cg_flags;
 800		break;
 801	case CGS_SYSTEM_INFO_PG_FLAGS:
 802		sys_info->value = adev->pg_flags;
 803		break;
 804	default:
 805		return -ENODEV;
 806	}
 807
 808	return 0;
 809}
 810
 811static int amdgpu_cgs_get_active_displays_info(void *cgs_device,
 812					  struct cgs_display_info *info)
 813{
 814	CGS_FUNC_ADEV;
 815	struct amdgpu_crtc *amdgpu_crtc;
 816	struct drm_device *ddev = adev->ddev;
 817	struct drm_crtc *crtc;
 818	uint32_t line_time_us, vblank_lines;
 819	struct cgs_mode_info *mode_info;
 820
 821	if (info == NULL)
 822		return -EINVAL;
 823
 824	mode_info = info->mode_info;
 825
 826	if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
 827		list_for_each_entry(crtc,
 828				&ddev->mode_config.crtc_list, head) {
 829			amdgpu_crtc = to_amdgpu_crtc(crtc);
 830			if (crtc->enabled) {
 831				info->active_display_mask |= (1 << amdgpu_crtc->crtc_id);
 832				info->display_count++;
 833			}
 834			if (mode_info != NULL &&
 835				crtc->enabled && amdgpu_crtc->enabled &&
 836				amdgpu_crtc->hw_mode.clock) {
 837				line_time_us = (amdgpu_crtc->hw_mode.crtc_htotal * 1000) /
 838							amdgpu_crtc->hw_mode.clock;
 839				vblank_lines = amdgpu_crtc->hw_mode.crtc_vblank_end -
 840							amdgpu_crtc->hw_mode.crtc_vdisplay +
 841							(amdgpu_crtc->v_border * 2);
 842				mode_info->vblank_time_us = vblank_lines * line_time_us;
 843				mode_info->refresh_rate = drm_mode_vrefresh(&amdgpu_crtc->hw_mode);
 844				mode_info->ref_clock = adev->clock.spll.reference_freq;
 845				mode_info = NULL;
 846			}
 847		}
 848	}
 849
 850	return 0;
 851}
 852
 853
 854static int amdgpu_cgs_notify_dpm_enabled(void *cgs_device, bool enabled)
 855{
 856	CGS_FUNC_ADEV;
 857
 858	adev->pm.dpm_enabled = enabled;
 859
 860	return 0;
 861}
 862
 863/** \brief evaluate acpi namespace object, handle or pathname must be valid
 864 *  \param cgs_device
 865 *  \param info input/output arguments for the control method
 866 *  \return status
 867 */
 868
 869#if defined(CONFIG_ACPI)
 870static int amdgpu_cgs_acpi_eval_object(void *cgs_device,
 871				    struct cgs_acpi_method_info *info)
 872{
 873	CGS_FUNC_ADEV;
 874	acpi_handle handle;
 875	struct acpi_object_list input;
 876	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
 877	union acpi_object *params = NULL;
 878	union acpi_object *obj = NULL;
 879	uint8_t name[5] = {'\0'};
 880	struct cgs_acpi_method_argument *argument = NULL;
 881	uint32_t i, count;
 882	acpi_status status;
 883	int result;
 884	uint32_t func_no = 0xFFFFFFFF;
 885
 886	handle = ACPI_HANDLE(&adev->pdev->dev);
 887	if (!handle)
 888		return -ENODEV;
 889
 890	memset(&input, 0, sizeof(struct acpi_object_list));
 891
 892	/* validate input info */
 893	if (info->size != sizeof(struct cgs_acpi_method_info))
 894		return -EINVAL;
 895
 896	input.count = info->input_count;
 897	if (info->input_count > 0) {
 898		if (info->pinput_argument == NULL)
 899			return -EINVAL;
 900		argument = info->pinput_argument;
 901		func_no = argument->value;
 902		for (i = 0; i < info->input_count; i++) {
 903			if (((argument->type == ACPI_TYPE_STRING) ||
 904			     (argument->type == ACPI_TYPE_BUFFER)) &&
 905			    (argument->pointer == NULL))
 906				return -EINVAL;
 907			argument++;
 908		}
 909	}
 910
 911	if (info->output_count > 0) {
 912		if (info->poutput_argument == NULL)
 913			return -EINVAL;
 914		argument = info->poutput_argument;
 915		for (i = 0; i < info->output_count; i++) {
 916			if (((argument->type == ACPI_TYPE_STRING) ||
 917				(argument->type == ACPI_TYPE_BUFFER))
 918				&& (argument->pointer == NULL))
 919				return -EINVAL;
 920			argument++;
 921		}
 922	}
 923
 924	/* The path name passed to acpi_evaluate_object should be null terminated */
 925	if ((info->field & CGS_ACPI_FIELD_METHOD_NAME) != 0) {
 926		strncpy(name, (char *)&(info->name), sizeof(uint32_t));
 927		name[4] = '\0';
 928	}
 929
 930	/* parse input parameters */
 931	if (input.count > 0) {
 932		input.pointer = params =
 933				kzalloc(sizeof(union acpi_object) * input.count, GFP_KERNEL);
 934		if (params == NULL)
 935			return -EINVAL;
 936
 937		argument = info->pinput_argument;
 938
 939		for (i = 0; i < input.count; i++) {
 940			params->type = argument->type;
 941			switch (params->type) {
 942			case ACPI_TYPE_INTEGER:
 943				params->integer.value = argument->value;
 944				break;
 945			case ACPI_TYPE_STRING:
 946				params->string.length = argument->method_length;
 947				params->string.pointer = argument->pointer;
 948				break;
 949			case ACPI_TYPE_BUFFER:
 950				params->buffer.length = argument->method_length;
 951				params->buffer.pointer = argument->pointer;
 952				break;
 953			default:
 954				break;
 955			}
 956			params++;
 957			argument++;
 958		}
 959	}
 960
 961	/* parse output info */
 962	count = info->output_count;
 963	argument = info->poutput_argument;
 964
 965	/* evaluate the acpi method */
 966	status = acpi_evaluate_object(handle, name, &input, &output);
 967
 968	if (ACPI_FAILURE(status)) {
 969		result = -EIO;
 970		goto error;
 971	}
 972
 973	/* return the output info */
 974	obj = output.pointer;
 975
 976	if (count > 1) {
 977		if ((obj->type != ACPI_TYPE_PACKAGE) ||
 978			(obj->package.count != count)) {
 979			result = -EIO;
 980			goto error;
 981		}
 982		params = obj->package.elements;
 983	} else
 984		params = obj;
 985
 986	if (params == NULL) {
 987		result = -EIO;
 988		goto error;
 989	}
 990
 991	for (i = 0; i < count; i++) {
 992		if (argument->type != params->type) {
 993			result = -EIO;
 994			goto error;
 995		}
 996		switch (params->type) {
 997		case ACPI_TYPE_INTEGER:
 998			argument->value = params->integer.value;
 999			break;
1000		case ACPI_TYPE_STRING:
1001			if ((params->string.length != argument->data_length) ||
1002				(params->string.pointer == NULL)) {
1003				result = -EIO;
1004				goto error;
1005			}
1006			strncpy(argument->pointer,
1007				params->string.pointer,
1008				params->string.length);
1009			break;
1010		case ACPI_TYPE_BUFFER:
1011			if (params->buffer.pointer == NULL) {
1012				result = -EIO;
1013				goto error;
1014			}
1015			memcpy(argument->pointer,
1016				params->buffer.pointer,
1017				argument->data_length);
1018			break;
1019		default:
1020			break;
1021		}
1022		argument++;
1023		params++;
1024	}
1025
1026error:
1027	if (obj != NULL)
1028		kfree(obj);
1029	kfree((void *)input.pointer);
1030	return result;
1031}
1032#else
1033static int amdgpu_cgs_acpi_eval_object(void *cgs_device,
1034				struct cgs_acpi_method_info *info)
1035{
1036	return -EIO;
1037}
1038#endif
1039
1040int amdgpu_cgs_call_acpi_method(void *cgs_device,
1041					uint32_t acpi_method,
1042					uint32_t acpi_function,
1043					void *pinput, void *poutput,
1044					uint32_t output_count,
1045					uint32_t input_size,
1046					uint32_t output_size)
1047{
1048	struct cgs_acpi_method_argument acpi_input[2] = { {0}, {0} };
1049	struct cgs_acpi_method_argument acpi_output = {0};
1050	struct cgs_acpi_method_info info = {0};
1051
1052	acpi_input[0].type = CGS_ACPI_TYPE_INTEGER;
1053	acpi_input[0].method_length = sizeof(uint32_t);
1054	acpi_input[0].data_length = sizeof(uint32_t);
1055	acpi_input[0].value = acpi_function;
1056
1057	acpi_input[1].type = CGS_ACPI_TYPE_BUFFER;
1058	acpi_input[1].method_length = CGS_ACPI_MAX_BUFFER_SIZE;
1059	acpi_input[1].data_length = input_size;
1060	acpi_input[1].pointer = pinput;
1061
1062	acpi_output.type = CGS_ACPI_TYPE_BUFFER;
1063	acpi_output.method_length = CGS_ACPI_MAX_BUFFER_SIZE;
1064	acpi_output.data_length = output_size;
1065	acpi_output.pointer = poutput;
1066
1067	info.size = sizeof(struct cgs_acpi_method_info);
1068	info.field = CGS_ACPI_FIELD_METHOD_NAME | CGS_ACPI_FIELD_INPUT_ARGUMENT_COUNT;
1069	info.input_count = 2;
1070	info.name = acpi_method;
1071	info.pinput_argument = acpi_input;
1072	info.output_count = output_count;
1073	info.poutput_argument = &acpi_output;
1074
1075	return amdgpu_cgs_acpi_eval_object(cgs_device, &info);
1076}
1077
1078static const struct cgs_ops amdgpu_cgs_ops = {
1079	amdgpu_cgs_gpu_mem_info,
1080	amdgpu_cgs_gmap_kmem,
1081	amdgpu_cgs_gunmap_kmem,
1082	amdgpu_cgs_alloc_gpu_mem,
1083	amdgpu_cgs_free_gpu_mem,
1084	amdgpu_cgs_gmap_gpu_mem,
1085	amdgpu_cgs_gunmap_gpu_mem,
1086	amdgpu_cgs_kmap_gpu_mem,
1087	amdgpu_cgs_kunmap_gpu_mem,
1088	amdgpu_cgs_read_register,
1089	amdgpu_cgs_write_register,
1090	amdgpu_cgs_read_ind_register,
1091	amdgpu_cgs_write_ind_register,
1092	amdgpu_cgs_read_pci_config_byte,
1093	amdgpu_cgs_read_pci_config_word,
1094	amdgpu_cgs_read_pci_config_dword,
1095	amdgpu_cgs_write_pci_config_byte,
1096	amdgpu_cgs_write_pci_config_word,
1097	amdgpu_cgs_write_pci_config_dword,
1098	amdgpu_cgs_get_pci_resource,
1099	amdgpu_cgs_atom_get_data_table,
1100	amdgpu_cgs_atom_get_cmd_table_revs,
1101	amdgpu_cgs_atom_exec_cmd_table,
1102	amdgpu_cgs_create_pm_request,
1103	amdgpu_cgs_destroy_pm_request,
1104	amdgpu_cgs_set_pm_request,
1105	amdgpu_cgs_pm_request_clock,
1106	amdgpu_cgs_pm_request_engine,
1107	amdgpu_cgs_pm_query_clock_limits,
1108	amdgpu_cgs_set_camera_voltages,
1109	amdgpu_cgs_get_firmware_info,
1110	amdgpu_cgs_set_powergating_state,
1111	amdgpu_cgs_set_clockgating_state,
1112	amdgpu_cgs_get_active_displays_info,
1113	amdgpu_cgs_notify_dpm_enabled,
1114	amdgpu_cgs_call_acpi_method,
1115	amdgpu_cgs_query_system_info,
1116};
1117
1118static const struct cgs_os_ops amdgpu_cgs_os_ops = {
1119	amdgpu_cgs_add_irq_source,
1120	amdgpu_cgs_irq_get,
1121	amdgpu_cgs_irq_put
1122};
1123
1124void *amdgpu_cgs_create_device(struct amdgpu_device *adev)
1125{
1126	struct amdgpu_cgs_device *cgs_device =
1127		kmalloc(sizeof(*cgs_device), GFP_KERNEL);
1128
1129	if (!cgs_device) {
1130		DRM_ERROR("Couldn't allocate CGS device structure\n");
1131		return NULL;
1132	}
1133
1134	cgs_device->base.ops = &amdgpu_cgs_ops;
1135	cgs_device->base.os_ops = &amdgpu_cgs_os_ops;
1136	cgs_device->adev = adev;
1137
1138	return cgs_device;
1139}
1140
1141void amdgpu_cgs_destroy_device(void *cgs_device)
1142{
1143	kfree(cgs_device);
1144}