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
