Adds support for IP discovery via PSP mailbox using guest phys
addr for passthrough A+A.

Signed-off-by: Dejan Andjelkovic <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 58 +++++++++++++++++--
 drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h       |  1 +
 2 files changed, 55 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index 5564850e3ff4..3372de34149c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -28,6 +28,7 @@
 #include "amdgpu_discovery.h"
 #include "amdgpu_ualink.h"
 #include "soc15_hw_ip.h"
+#include "psp_gfx_if.h"
 #include "discovery.h"
 #include "amdgpu_ras.h"
 
@@ -149,6 +150,10 @@ MODULE_FIRMWARE("amdgpu/aldebaran_ip_discovery.bin");
 #define mmRCC_CONFIG_MEMSIZE   0xde3
 #define mmRCC_HW_DEBUG         0x10c01
 #define mmMP0_SMN_C2PMSG_33    0x16061
+#define mmMP0_SMN_C2PMSG_64    0x16080
+#define mmMP0_SMN_C2PMSG_69    0x16085
+#define mmMP0_SMN_C2PMSG_70    0x16086
+#define mmMP0_SMN_C2PMSG_71    0x16087
 #define mmMM_INDEX             0x0
 #define mmMM_INDEX_HI          0x6
 #define mmMM_DATA              0x1
@@ -410,6 +415,46 @@ static int amdgpu_discovery_read_binary_from_sysmem(struct 
amdgpu_device *adev,
        return -ENOENT;
 }
 
+static int amdgpu_discovery_wait_psp_gfx_ctrl_resp(struct amdgpu_device *adev)
+{
+       u32 val;
+       int i;
+
+       for (i = 0; i < adev->usec_timeout; i++) {
+               val = RREG32(mmMP0_SMN_C2PMSG_64);
+               if ((val & 0x8000FFFF) == 0x80000000)
+                       return 0;
+               udelay(1);
+       }
+
+       return -ETIMEDOUT;
+}
+
+static int amdgpu_discovery_read_binary_from_psp_mailbox(struct amdgpu_device 
*adev,
+                                                        uint8_t *binary)
+{
+       phys_addr_t phys_addr;
+       uint32_t length;
+       int ret;
+
+       phys_addr = virt_to_phys(binary);
+
+       length = adev->discovery.size;
+       length = (length & 0x0fffffffU) | (0x4U << 28);
+
+       WREG32(mmMP0_SMN_C2PMSG_69, lower_32_bits((u64)phys_addr));
+       WREG32(mmMP0_SMN_C2PMSG_70, upper_32_bits((u64)phys_addr));
+       WREG32(mmMP0_SMN_C2PMSG_71, length);
+
+       WREG32(mmMP0_SMN_C2PMSG_64, GFX_CTRL_CMD_ID_GET_IP_DISCOVERY);
+
+       ret = amdgpu_discovery_wait_psp_gfx_ctrl_resp(adev);
+       if (ret)
+               dev_err(adev->dev, "ip_discovery: PSP wait timed out\n");
+
+       return ret;
+}
+
 #define IP_DISCOVERY_V2                2
 #define IP_DISCOVERY_V4                4
 
@@ -768,16 +813,21 @@ static int amdgpu_discovery_init(struct amdgpu_device 
*adev)
                drm_dbg(&adev->ddev, "use ip discovery information from 
file\n");
                r = amdgpu_discovery_read_binary_from_file(adev, discovery_bin,
                                                           fw_name);
-               if (r)
-                       goto out;
        } else {
                drm_dbg(&adev->ddev, "use ip discovery information from 
memory\n");
                r = amdgpu_discovery_read_binary_from_mem(adev, discovery_bin,
                                                          is_tmr_in_sysmem);
-               if (r)
-                       goto out;
        }
 
+       if ((r || !amdgpu_discovery_verify_binary_signature(discovery_bin)) &&
+               amdgpu_passthrough(adev)) {
+               drm_dbg(&adev->ddev, "use ip discovery information from psp 
mailbox");
+               r = amdgpu_discovery_read_binary_from_psp_mailbox(adev, 
discovery_bin);
+       }
+
+       if (r)
+               goto out;
+
        /* check the ip discovery binary signature */
        if (!amdgpu_discovery_verify_binary_signature(discovery_bin)) {
                amdgpu_discovery_log_bad_signature(adev, discovery_bin, 
fw_name);
diff --git a/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h 
b/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h
index 49aa95c76745..bc777f53a193 100644
--- a/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h
+++ b/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h
@@ -49,6 +49,7 @@ enum psp_gfx_crtl_cmd_id
     GFX_CTRL_CMD_ID_GBR_IH_SET      = 0x00080000,   /* set Gbr IH_RB_CNTL 
registers */
     GFX_CTRL_CMD_ID_CONSUME_CMD     = 0x00090000,   /* send interrupt to psp 
for updating write pointer of vf */
     GFX_CTRL_CMD_ID_DESTROY_GPCOM_RING = 0x000C0000, /* destroy GPCOM ring */
+    GFX_CTRL_CMD_ID_GET_IP_DISCOVERY   = 0x000D0000,   /**< Copy 
IP_DISCOVERY_DATA to host-specified address */
 
     GFX_CTRL_CMD_ID_MAX             = 0x000F0000,   /* max command ID */
 };
-- 
2.43.0

Reply via email to