[PATCH 5/6] Add support for SI's VCE firmwares (with and without header)

Alexandre Demers alexandre.f.demers at gmail.com
Fri Sep 8 02:48:34 UTC 2017


Inspired on how it is done under radeon for UVD firmwares.

Signed-off-by: Alexandre Demers <alexandre.f.demers at gmail.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 100 ++++++++++++++++++++++++--------
 1 file changed, 75 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
index 735c38d7db0d..6d65fab6a4af 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
@@ -39,6 +39,10 @@
 #define VCE_IDLE_TIMEOUT	msecs_to_jiffies(1000)
 
 /* Firmware Names */
+#ifdef CONFIG_DRM_AMDGPU_SI
+#define FIRMWARE_TAHITI_LEGACY	"radeon/TAHITI_vce.bin"
+#define FIRMWARE_TAHITI	"radeon/tahiti_vce.bin"
+#endif
 #ifdef CONFIG_DRM_AMDGPU_CIK
 #define FIRMWARE_BONAIRE	"radeon/bonaire_vce.bin"
 #define FIRMWARE_KABINI	"radeon/kabini_vce.bin"
@@ -56,6 +60,10 @@
 
 #define FIRMWARE_VEGA10		"amdgpu/vega10_vce.bin"
 
+#ifdef CONFIG_DRM_AMDGPU_SI
+MODULE_FIRMWARE(FIRMWARE_TAHITI_LEGACY);
+MODULE_FIRMWARE(FIRMWARE_TAHITI);
+#endif
 #ifdef CONFIG_DRM_AMDGPU_CIK
 MODULE_FIRMWARE(FIRMWARE_BONAIRE);
 MODULE_FIRMWARE(FIRMWARE_KABINI);
@@ -86,12 +94,21 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size)
 {
 	struct amdgpu_ring *ring;
 	struct amd_sched_rq *rq;
-	const char *fw_name;
+	const char *fw_name = NULL, *legacy_fw_name = NULL;
 	const struct common_firmware_header *hdr;
 	unsigned ucode_version, version_major, version_minor, binary_id;
 	int i, r;
 
 	switch (adev->asic_type) {
+#ifdef CONFIG_DRM_AMDGPU_SI
+	case CHIP_TAHITI:
+	case CHIP_VERDE:
+	case CHIP_PITCAIRN:
+	case CHIP_OLAND:
+		legacy_fw_name = FIRMWARE_TAHITI_LEGACY;
+		fw_name = FIRMWARE_TAHITI;
+		break;
+#endif
 #ifdef CONFIG_DRM_AMDGPU_CIK
 	case CHIP_BONAIRE:
 		fw_name = FIRMWARE_BONAIRE;
@@ -138,32 +155,55 @@ int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size)
 		return -EINVAL;
 	}
 
-	r = request_firmware(&adev->vce.fw, fw_name, adev->dev);
-	if (r) {
-		dev_err(adev->dev, "amdgpu_vce: Can't load firmware \"%s\"\n",
-			fw_name);
-		return r;
-	}
+	if (fw_name) {
+		/* Let's try to load the newer firmware first */
+		r = request_firmware(&adev->vce.fw, fw_name, adev->dev);
+		if (r) {
+			dev_err(adev->dev, "amdgpu_vce: Can't load firmware \"%s\"\n",
+				fw_name);
+			// return r;
+		} else {
 
-	r = amdgpu_ucode_validate(adev->vce.fw);
-	if (r) {
-		dev_err(adev->dev, "amdgpu_vce: Can't validate firmware \"%s\"\n",
-			fw_name);
-		release_firmware(adev->vce.fw);
-		adev->vce.fw = NULL;
-		return r;
-	}
+			r = amdgpu_ucode_validate(adev->vce.fw);
+			if (r) {
+				dev_err(adev->dev, "amdgpu_vce: Can't validate firmware \"%s\"\n",
+					fw_name);
+				release_firmware(adev->vce.fw);
+				adev->vce.fw = NULL;
+				return r;
+			}
 
-	hdr = (const struct common_firmware_header *)adev->vce.fw->data;
+			hdr = (const struct common_firmware_header *)adev->vce.fw->data;
 
-	ucode_version = le32_to_cpu(hdr->ucode_version);
-	version_major = (ucode_version >> 20) & 0xfff;
-	version_minor = (ucode_version >> 8) & 0xfff;
-	binary_id = ucode_version & 0xff;
-	DRM_INFO("Found VCE firmware Version: %hhd.%hhd Binary ID: %hhd\n",
-		version_major, version_minor, binary_id);
-	adev->vce.fw_version = ((version_major << 24) | (version_minor << 16) |
+			ucode_version = le32_to_cpu(hdr->ucode_version);
+			version_major = (ucode_version >> 20) & 0xfff;
+			version_minor = (ucode_version >> 8) & 0xfff;
+			binary_id = ucode_version & 0xff;
+			DRM_INFO("Found VCE firmware Version: %hhd.%hhd Binary ID: %hhd\n",
+				version_major, version_minor, binary_id);
+			adev->vce.fw_version = ((version_major << 24) | (version_minor << 16) |
 				(binary_id << 8));
+		}
+	}
+
+	/*
+	 * In case there is only a legacy firmware, or we encountered an error
+	 * while loading the new firmware, we fall back to loading the legacy
+	 * firmware now.
+	 */
+	if (!fw_name || r) {
+		r = request_firmware(&adev->vce.fw, legacy_fw_name, adev->dev);
+		if (r) {
+			dev_err(adev->dev, "amdgpu_vce: Can't load legacy firmware \"%s\"\n",
+				legacy_fw_name);
+			return r;
+		}
+
+		// Portage debug
+		else {
+			DRM_INFO("VCE legacy firmware loaded.\n");
+		}
+	}
 
 	/* allocate firmware, stack and heap BO */
 
@@ -296,9 +336,17 @@ int amdgpu_vce_resume(struct amdgpu_device *adev)
 	}
 
 	hdr = (const struct common_firmware_header *)adev->vce.fw->data;
-	offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
+
+	/* Are we using a legacy firmware with no header? */
+	if ((le32_to_cpu(hdr->ucode_array_offset_bytes) != 256) || (le32_to_cpu(hdr->header_size_bytes) != 32)) {
+		offset = 0;
+	}
+	else {
+		offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
+	}
+
 	memcpy_toio(cpu_addr, adev->vce.fw->data + offset,
-		    adev->vce.fw->size - offset);
+				adev->vce.fw->size - offset);
 
 	amdgpu_bo_kunmap(adev->vce.vcpu_bo);
 
@@ -732,6 +780,8 @@ int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx)
 
 		case 0x0500000c: /* hw config */
 			switch (p->adev->asic_type) {
+#ifdef CONFIG_DRM_AMDGPU_SI
+#endif
 #ifdef CONFIG_DRM_AMDGPU_CIK
 			case CHIP_KAVERI:
 			case CHIP_MULLINS:
-- 
2.14.1



More information about the amd-gfx mailing list