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