On 13-Oct-26 8:25 PM, Dejan Andjelkovic wrote:
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);
Does this really work?
+
+ 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);
Instead of fallback on failure, can we make use of DRIVER_SCRATCH_* +
passthrough combination to figure out the read should go through PSP
mailbox?
Thanks,
Lijo
+ }
+
+ 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 */
};