[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