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

Signed-off-by: Alexandre Demers <alexandre.f.dem...@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

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to