drm/amd: Load MES microcode during early_init
authorjsg <jsg@openbsd.org>
Tue, 13 Jun 2023 03:34:36 +0000 (03:34 +0000)
committerjsg <jsg@openbsd.org>
Tue, 13 Jun 2023 03:34:36 +0000 (03:34 +0000)
From Mario Limonciello
3e1fa150e79897cc00db8348de267abf4c6c35be in linux-6.1.y/6.1.29
cc42e76e7de5190a7da5dac9d7b2bbb458e050bf in mainline linux

sys/dev/pci/drm/amd/amdgpu/amdgpu_mes.c
sys/dev/pci/drm/amd/amdgpu/amdgpu_mes.h
sys/dev/pci/drm/amd/amdgpu/mes_v10_1.c
sys/dev/pci/drm/amd/amdgpu/mes_v11_0.c

index dd478b9..32dc743 100644 (file)
@@ -21,6 +21,8 @@
  *
  */
 
+#include <linux/firmware.h>
+
 #include "amdgpu_mes.h"
 #include "amdgpu.h"
 #include "soc15_common.h"
@@ -1423,3 +1425,66 @@ error_pasid:
        kfree(vm);
        return 0;
 }
+
+int amdgpu_mes_init_microcode(struct amdgpu_device *adev, int pipe)
+{
+       const struct mes_firmware_header_v1_0 *mes_hdr;
+       struct amdgpu_firmware_info *info;
+       char ucode_prefix[30];
+       char fw_name[40];
+       int r;
+
+       amdgpu_ucode_ip_version_decode(adev, GC_HWIP, ucode_prefix, sizeof(ucode_prefix));
+       snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mes%s.bin",
+               ucode_prefix,
+               pipe == AMDGPU_MES_SCHED_PIPE ? "" : "1");
+       r = request_firmware(&adev->mes.fw[pipe], fw_name, adev->dev);
+       if (r)
+               goto out;
+
+       r = amdgpu_ucode_validate(adev->mes.fw[pipe]);
+       if (r)
+               goto out;
+
+       mes_hdr = (const struct mes_firmware_header_v1_0 *)
+               adev->mes.fw[pipe]->data;
+       adev->mes.uc_start_addr[pipe] =
+               le32_to_cpu(mes_hdr->mes_uc_start_addr_lo) |
+               ((uint64_t)(le32_to_cpu(mes_hdr->mes_uc_start_addr_hi)) << 32);
+       adev->mes.data_start_addr[pipe] =
+               le32_to_cpu(mes_hdr->mes_data_start_addr_lo) |
+               ((uint64_t)(le32_to_cpu(mes_hdr->mes_data_start_addr_hi)) << 32);
+
+       if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
+               int ucode, ucode_data;
+
+               if (pipe == AMDGPU_MES_SCHED_PIPE) {
+                       ucode = AMDGPU_UCODE_ID_CP_MES;
+                       ucode_data = AMDGPU_UCODE_ID_CP_MES_DATA;
+               } else {
+                       ucode = AMDGPU_UCODE_ID_CP_MES1;
+                       ucode_data = AMDGPU_UCODE_ID_CP_MES1_DATA;
+               }
+
+               info = &adev->firmware.ucode[ucode];
+               info->ucode_id = ucode;
+               info->fw = adev->mes.fw[pipe];
+               adev->firmware.fw_size +=
+                       roundup2(le32_to_cpu(mes_hdr->mes_ucode_size_bytes),
+                             PAGE_SIZE);
+
+               info = &adev->firmware.ucode[ucode_data];
+               info->ucode_id = ucode_data;
+               info->fw = adev->mes.fw[pipe];
+               adev->firmware.fw_size +=
+                       roundup2(le32_to_cpu(mes_hdr->mes_ucode_data_size_bytes),
+                             PAGE_SIZE);
+       }
+
+       return 0;
+
+out:
+       release_firmware(adev->mes.fw[pipe]);
+       adev->mes.fw[pipe] = NULL;
+       return r;
+}
index 6999d35..1743f5b 100644 (file)
@@ -308,6 +308,7 @@ struct amdgpu_mes_funcs {
 
 int amdgpu_mes_ctx_get_offs(struct amdgpu_ring *ring, unsigned int id_offs);
 
+int amdgpu_mes_init_microcode(struct amdgpu_device *adev, int pipe);
 int amdgpu_mes_init(struct amdgpu_device *adev);
 void amdgpu_mes_fini(struct amdgpu_device *adev);
 
index 863ed6b..b6d4a62 100644 (file)
@@ -375,82 +375,6 @@ static const struct amdgpu_mes_funcs mes_v10_1_funcs = {
        .resume_gang = mes_v10_1_resume_gang,
 };
 
-static int mes_v10_1_init_microcode(struct amdgpu_device *adev,
-                                   enum admgpu_mes_pipe pipe)
-{
-       const char *chip_name;
-       char fw_name[30];
-       int err;
-       const struct mes_firmware_header_v1_0 *mes_hdr;
-       struct amdgpu_firmware_info *info;
-
-       switch (adev->ip_versions[GC_HWIP][0]) {
-       case IP_VERSION(10, 1, 10):
-               chip_name = "navi10";
-               break;
-       case IP_VERSION(10, 3, 0):
-               chip_name = "sienna_cichlid";
-               break;
-       default:
-               BUG();
-       }
-
-       if (pipe == AMDGPU_MES_SCHED_PIPE)
-               snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mes.bin",
-                        chip_name);
-       else
-               snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mes1.bin",
-                        chip_name);
-
-       err = request_firmware(&adev->mes.fw[pipe], fw_name, adev->dev);
-       if (err)
-               return err;
-
-       err = amdgpu_ucode_validate(adev->mes.fw[pipe]);
-       if (err) {
-               release_firmware(adev->mes.fw[pipe]);
-               adev->mes.fw[pipe] = NULL;
-               return err;
-       }
-
-       mes_hdr = (const struct mes_firmware_header_v1_0 *)
-               adev->mes.fw[pipe]->data;
-       adev->mes.uc_start_addr[pipe] =
-               le32_to_cpu(mes_hdr->mes_uc_start_addr_lo) |
-               ((uint64_t)(le32_to_cpu(mes_hdr->mes_uc_start_addr_hi)) << 32);
-       adev->mes.data_start_addr[pipe] =
-               le32_to_cpu(mes_hdr->mes_data_start_addr_lo) |
-               ((uint64_t)(le32_to_cpu(mes_hdr->mes_data_start_addr_hi)) << 32);
-
-       if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
-               int ucode, ucode_data;
-
-               if (pipe == AMDGPU_MES_SCHED_PIPE) {
-                       ucode = AMDGPU_UCODE_ID_CP_MES;
-                       ucode_data = AMDGPU_UCODE_ID_CP_MES_DATA;
-               } else {
-                       ucode = AMDGPU_UCODE_ID_CP_MES1;
-                       ucode_data = AMDGPU_UCODE_ID_CP_MES1_DATA;
-               }
-
-               info = &adev->firmware.ucode[ucode];
-               info->ucode_id = ucode;
-               info->fw = adev->mes.fw[pipe];
-               adev->firmware.fw_size +=
-                       roundup2(le32_to_cpu(mes_hdr->mes_ucode_size_bytes),
-                             PAGE_SIZE);
-
-               info = &adev->firmware.ucode[ucode_data];
-               info->ucode_id = ucode_data;
-               info->fw = adev->mes.fw[pipe];
-               adev->firmware.fw_size +=
-                       roundup2(le32_to_cpu(mes_hdr->mes_ucode_data_size_bytes),
-                             PAGE_SIZE);
-       }
-
-       return 0;
-}
-
 static void mes_v10_1_free_microcode(struct amdgpu_device *adev,
                                     enum admgpu_mes_pipe pipe)
 {
@@ -1015,10 +939,6 @@ static int mes_v10_1_sw_init(void *handle)
                if (!adev->enable_mes_kiq && pipe == AMDGPU_MES_KIQ_PIPE)
                        continue;
 
-               r = mes_v10_1_init_microcode(adev, pipe);
-               if (r)
-                       return r;
-
                r = mes_v10_1_allocate_eop_buf(adev, pipe);
                if (r)
                        return r;
@@ -1225,6 +1145,22 @@ static int mes_v10_1_resume(void *handle)
        return amdgpu_mes_resume(adev);
 }
 
+static int mes_v10_0_early_init(void *handle)
+{
+       struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+       int pipe, r;
+
+       for (pipe = 0; pipe < AMDGPU_MAX_MES_PIPES; pipe++) {
+               if (!adev->enable_mes_kiq && pipe == AMDGPU_MES_KIQ_PIPE)
+                       continue;
+               r = amdgpu_mes_init_microcode(adev, pipe);
+               if (r)
+                       return r;
+       }
+
+       return 0;
+}
+
 static int mes_v10_0_late_init(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
@@ -1237,6 +1173,7 @@ static int mes_v10_0_late_init(void *handle)
 
 static const struct amd_ip_funcs mes_v10_1_ip_funcs = {
        .name = "mes_v10_1",
+       .early_init = mes_v10_0_early_init,
        .late_init = mes_v10_0_late_init,
        .sw_init = mes_v10_1_sw_init,
        .sw_fini = mes_v10_1_sw_fini,
index e3f1fa0..55a5370 100644 (file)
@@ -453,73 +453,6 @@ static const struct amdgpu_mes_funcs mes_v11_0_funcs = {
        .misc_op = mes_v11_0_misc_op,
 };
 
-static int mes_v11_0_init_microcode(struct amdgpu_device *adev,
-                                   enum admgpu_mes_pipe pipe)
-{
-       char fw_name[30];
-       char ucode_prefix[30];
-       int err;
-       const struct mes_firmware_header_v1_0 *mes_hdr;
-       struct amdgpu_firmware_info *info;
-
-       amdgpu_ucode_ip_version_decode(adev, GC_HWIP, ucode_prefix, sizeof(ucode_prefix));
-
-       if (pipe == AMDGPU_MES_SCHED_PIPE)
-               snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mes.bin",
-                        ucode_prefix);
-       else
-               snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_mes1.bin",
-                        ucode_prefix);
-
-       err = request_firmware(&adev->mes.fw[pipe], fw_name, adev->dev);
-       if (err)
-               return err;
-
-       err = amdgpu_ucode_validate(adev->mes.fw[pipe]);
-       if (err) {
-               release_firmware(adev->mes.fw[pipe]);
-               adev->mes.fw[pipe] = NULL;
-               return err;
-       }
-
-       mes_hdr = (const struct mes_firmware_header_v1_0 *)
-               adev->mes.fw[pipe]->data;
-       adev->mes.uc_start_addr[pipe] =
-               le32_to_cpu(mes_hdr->mes_uc_start_addr_lo) |
-               ((uint64_t)(le32_to_cpu(mes_hdr->mes_uc_start_addr_hi)) << 32);
-       adev->mes.data_start_addr[pipe] =
-               le32_to_cpu(mes_hdr->mes_data_start_addr_lo) |
-               ((uint64_t)(le32_to_cpu(mes_hdr->mes_data_start_addr_hi)) << 32);
-
-       if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
-               int ucode, ucode_data;
-
-               if (pipe == AMDGPU_MES_SCHED_PIPE) {
-                       ucode = AMDGPU_UCODE_ID_CP_MES;
-                       ucode_data = AMDGPU_UCODE_ID_CP_MES_DATA;
-               } else {
-                       ucode = AMDGPU_UCODE_ID_CP_MES1;
-                       ucode_data = AMDGPU_UCODE_ID_CP_MES1_DATA;
-               }
-
-               info = &adev->firmware.ucode[ucode];
-               info->ucode_id = ucode;
-               info->fw = adev->mes.fw[pipe];
-               adev->firmware.fw_size +=
-                       roundup2(le32_to_cpu(mes_hdr->mes_ucode_size_bytes),
-                             PAGE_SIZE);
-
-               info = &adev->firmware.ucode[ucode_data];
-               info->ucode_id = ucode_data;
-               info->fw = adev->mes.fw[pipe];
-               adev->firmware.fw_size +=
-                       roundup2(le32_to_cpu(mes_hdr->mes_ucode_data_size_bytes),
-                             PAGE_SIZE);
-       }
-
-       return 0;
-}
-
 static void mes_v11_0_free_microcode(struct amdgpu_device *adev,
                                     enum admgpu_mes_pipe pipe)
 {
@@ -1094,10 +1027,6 @@ static int mes_v11_0_sw_init(void *handle)
                if (!adev->enable_mes_kiq && pipe == AMDGPU_MES_KIQ_PIPE)
                        continue;
 
-               r = mes_v11_0_init_microcode(adev, pipe);
-               if (r)
-                       return r;
-
                r = mes_v11_0_allocate_eop_buf(adev, pipe);
                if (r)
                        return r;
@@ -1330,6 +1259,22 @@ static int mes_v11_0_resume(void *handle)
        return amdgpu_mes_resume(adev);
 }
 
+static int mes_v11_0_early_init(void *handle)
+{
+       struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+       int pipe, r;
+
+       for (pipe = 0; pipe < AMDGPU_MAX_MES_PIPES; pipe++) {
+               if (!adev->enable_mes_kiq && pipe == AMDGPU_MES_KIQ_PIPE)
+                       continue;
+               r = amdgpu_mes_init_microcode(adev, pipe);
+               if (r)
+                       return r;
+       }
+
+       return 0;
+}
+
 static int mes_v11_0_late_init(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
@@ -1344,6 +1289,7 @@ static int mes_v11_0_late_init(void *handle)
 
 static const struct amd_ip_funcs mes_v11_0_ip_funcs = {
        .name = "mes_v11_0",
+       .early_init = mes_v11_0_early_init,
        .late_init = mes_v11_0_late_init,
        .sw_init = mes_v11_0_sw_init,
        .sw_fini = mes_v11_0_sw_fini,