RE: [PATCH] drm/amdgpu: Read PSPv13 OS version from register
[AMD Official Use Only - General] Reviewed-by: Hawking Zhang Regards, Hawking -Original Message- From: Lazar, Lijo Sent: Wednesday, October 11, 2023 14:51 To: amd-gfx@lists.freedesktop.org Cc: Zhang, Hawking ; Deucher, Alexander ; Wang, Yang(Kevin) Subject: [PATCH] drm/amdgpu: Read PSPv13 OS version from register PSP OS updates the version information in register. On APUs with PSPv13, PSP OS will already be loaded with SBIOS. Hence use the version register instead of using information in driver binary header. Signed-off-by: Lijo Lazar Reviewed-by: Yang Wang --- drivers/gpu/drm/amd/amdgpu/psp_v13_0.c | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c index b7bc00d4c696..573046702861 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c @@ -263,6 +263,12 @@ static int psp_v13_0_bootloader_load_ras_drv(struct psp_context *psp) return psp_v13_0_bootloader_load_component(psp, &psp->ras_drv, PSP_BL__LOAD_RASDRV); } +static inline void psp_v13_0_init_sos_version(struct psp_context *psp) +{ + struct amdgpu_device *adev = psp->adev; + + psp->sos.fw_version = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_58); } static int psp_v13_0_bootloader_load_sos(struct psp_context *psp) { @@ -273,8 +279,10 @@ static int psp_v13_0_bootloader_load_sos(struct psp_context *psp) /* Check sOS sign of life register to confirm sys driver and sOS * are already been loaded. */ - if (psp_v13_0_is_sos_alive(psp)) + if (psp_v13_0_is_sos_alive(psp)) { + psp_v13_0_init_sos_version(psp); return 0; + } ret = psp_v13_0_wait_for_bootloader(psp); if (ret) @@ -298,6 +306,9 @@ static int psp_v13_0_bootloader_load_sos(struct psp_context *psp) RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_81), 0, true); + if (!ret) + psp_v13_0_init_sos_version(psp); + return ret; } -- 2.25.1
[PATCH] drm/radeon: fix a possible null pointer dereference
In radeon_tv_get_modes(), the return value of drm_cvt_mode() is assigned to mode, which will lead to a NULL pointer dereference on failure of drm_cvt_mode(). Add a check to avoid null point dereference. Signed-off-by: Ma Ke --- drivers/gpu/drm/radeon/radeon_connectors.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index d2f02c3dfce2..b84b58926106 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -1119,6 +1119,8 @@ static int radeon_tv_get_modes(struct drm_connector *connector) else { /* only 800x600 is supported right now on pre-avivo chips */ tv_mode = drm_cvt_mode(dev, 800, 600, 60, false, false, false); + if (!tv_mode) + return 0; tv_mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; drm_mode_probed_add(connector, tv_mode); } -- 2.37.2
[PATCH] drm/amdgpu: disable GFXOFF and PG during compute for GFX9
Temporary workaround to fix issues observed in some compute applications when GFXOFF is enabled on GFX9. Signed-off-by: Jesse Zhang --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c index d3805d6f..fef93d4edcbc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c @@ -683,12 +683,16 @@ int amdgpu_amdkfd_submit_ib(struct amdgpu_device *adev, void amdgpu_amdkfd_set_compute_idle(struct amdgpu_device *adev, bool idle) { + enum amd_powergating_state state = idle ? AMD_PG_STATE_GATE : AMD_PG_STATE_UNGATE; /* Temporary workaround to fix issues observed in some * compute applications when GFXOFF is enabled on GFX11. */ if (IP_VERSION_MAJ(amdgpu_ip_version(adev, GC_HWIP, 0)) == 11) { pr_debug("GFXOFF is %s\n", idle ? "enabled" : "disabled"); amdgpu_gfx_off_ctrl(adev, idle); + } else if ((IP_VERSION_MAJ(amdgpu_ip_version(adev, GC_HWIP, 0)) == 9) && + (adev->flags & AMD_IS_APU)) { + adev->ip_blocks[AMD_IP_BLOCK_TYPE_GFX].version->funcs->set_powergating_state((void *)adev, state); } amdgpu_dpm_switch_power_profile(adev, PP_SMC_POWER_PROFILE_COMPUTE, -- 2.25.1
[PATCH v2] drm/amdgpu: Expose ras version & schema info
Expose ras table version & schema info to sysfs v2: Updated schema to get poison support info from ras context, removed asic specific checks Signed-off-by: Asad Kamal --- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 51 +++-- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h | 3 ++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index 9c8203e87859..cb9e48fb40d2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -1370,6 +1370,22 @@ static ssize_t amdgpu_ras_sysfs_features_read(struct device *dev, return sysfs_emit(buf, "feature mask: 0x%x\n", con->features); } +static ssize_t amdgpu_ras_sysfs_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct amdgpu_ras *con = + container_of(attr, struct amdgpu_ras, version_attr); + return sysfs_emit(buf, "table version: 0x%x\n", con->eeprom_control.tbl_hdr.version); +} + +static ssize_t amdgpu_ras_sysfs_schema_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct amdgpu_ras *con = + container_of(attr, struct amdgpu_ras, schema_attr); + return sysfs_emit(buf, "schema: 0x%x\n", con->schema); +} + static void amdgpu_ras_sysfs_remove_bad_page_node(struct amdgpu_device *adev) { struct amdgpu_ras *con = amdgpu_ras_get_context(adev); @@ -1379,11 +1395,13 @@ static void amdgpu_ras_sysfs_remove_bad_page_node(struct amdgpu_device *adev) RAS_FS_NAME); } -static int amdgpu_ras_sysfs_remove_feature_node(struct amdgpu_device *adev) +static int amdgpu_ras_sysfs_remove_dev_attr_node(struct amdgpu_device *adev) { struct amdgpu_ras *con = amdgpu_ras_get_context(adev); struct attribute *attrs[] = { &con->features_attr.attr, + &con->version_attr.attr, + &con->schema_attr.attr, NULL }; struct attribute_group group = { @@ -1459,7 +1477,7 @@ static int amdgpu_ras_sysfs_remove_all(struct amdgpu_device *adev) if (amdgpu_bad_page_threshold != 0) amdgpu_ras_sysfs_remove_bad_page_node(adev); - amdgpu_ras_sysfs_remove_feature_node(adev); + amdgpu_ras_sysfs_remove_dev_attr_node(adev); return 0; } @@ -1582,6 +1600,10 @@ static BIN_ATTR(gpu_vram_bad_pages, S_IRUGO, amdgpu_ras_sysfs_badpages_read, NULL, 0); static DEVICE_ATTR(features, S_IRUGO, amdgpu_ras_sysfs_features_read, NULL); +static DEVICE_ATTR(version, 0444, + amdgpu_ras_sysfs_version_show, NULL); +static DEVICE_ATTR(schema, 0444, + amdgpu_ras_sysfs_schema_show, NULL); static int amdgpu_ras_fs_init(struct amdgpu_device *adev) { struct amdgpu_ras *con = amdgpu_ras_get_context(adev); @@ -1590,6 +1612,8 @@ static int amdgpu_ras_fs_init(struct amdgpu_device *adev) }; struct attribute *attrs[] = { &con->features_attr.attr, + &con->version_attr.attr, + &con->schema_attr.attr, NULL }; struct bin_attribute *bin_attrs[] = { @@ -1598,11 +1622,20 @@ static int amdgpu_ras_fs_init(struct amdgpu_device *adev) }; int r; + group.attrs = attrs; + /* add features entry */ con->features_attr = dev_attr_features; - group.attrs = attrs; sysfs_attr_init(attrs[0]); + /* add version entry */ + con->version_attr = dev_attr_version; + sysfs_attr_init(attrs[1]); + + /* add schema entry */ + con->schema_attr = dev_attr_schema; + sysfs_attr_init(attrs[2]); + if (amdgpu_bad_page_threshold != 0) { /* add bad_page_features entry */ bin_attr_gpu_vram_bad_pages.private = NULL; @@ -2594,6 +2627,14 @@ static void amdgpu_ras_query_poison_mode(struct amdgpu_device *adev) } } +static int amdgpu_get_ras_schema(struct amdgpu_device *adev) +{ + return (amdgpu_ras_is_poison_mode_supported(adev) << (ffs(AMDGPU_RAS_ERROR__POISON) - 1)) | + AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE | + AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE | + AMDGPU_RAS_ERROR__PARITY; +} + int amdgpu_ras_init(struct amdgpu_device *adev) { struct amdgpu_ras *con = amdgpu_ras_get_context(adev); @@ -2636,6 +2677,7 @@ int amdgpu_ras_init(struct amdgpu_device *adev) con->update_channel_flag = false; con->features = 0; + con->schema = 0; INIT_LIST_HEAD(&con->head); /* Might need get this flag from vbios. */ con->flags = RAS_DEFAULT_FLAGS; @@ -2691,6 +2733,9 @@ int amdgpu_ras_init(struct amdgpu_device *adev) amdgpu_ras_query_poison_mode(adev); + /* Get RAS schema for particular SOC */ +
[PATCH] Revert "drm/amdgpu: Program xcp_ctl registers as needed"
This reverts commit 3cf01336313894419498a0d5eb367f092a436195. XCP_CTL register is programmed by firmware and register access is protected. Signed-off-by: Mangesh Gadre Reviewed-by: Lijo Lazar --- drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c | 23 +++ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c index fbfe0a1c4b19..39bc441695f9 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c @@ -623,7 +623,7 @@ static int gfx_v9_4_3_switch_compute_partition(struct amdgpu_device *adev, int num_xccs_per_xcp) { int ret, i, num_xcc; - u32 tmp = 0, regval; + u32 tmp = 0; if (adev->psp.funcs) { ret = psp_spatial_partition(&adev->psp, @@ -631,24 +631,23 @@ static int gfx_v9_4_3_switch_compute_partition(struct amdgpu_device *adev, num_xccs_per_xcp); if (ret) return ret; - } - - num_xcc = NUM_XCC(adev->gfx.xcc_mask); + } else { + num_xcc = NUM_XCC(adev->gfx.xcc_mask); - for (i = 0; i < num_xcc; i++) { - tmp = REG_SET_FIELD(tmp, CP_HYP_XCP_CTL, NUM_XCC_IN_XCP, - num_xccs_per_xcp); - tmp = REG_SET_FIELD(tmp, CP_HYP_XCP_CTL, VIRTUAL_XCC_ID, - i % num_xccs_per_xcp); - regval = RREG32_SOC15(GC, GET_INST(GC, i), regCP_HYP_XCP_CTL); - if (regval != tmp) + for (i = 0; i < num_xcc; i++) { + tmp = REG_SET_FIELD(tmp, CP_HYP_XCP_CTL, NUM_XCC_IN_XCP, + num_xccs_per_xcp); + tmp = REG_SET_FIELD(tmp, CP_HYP_XCP_CTL, VIRTUAL_XCC_ID, + i % num_xccs_per_xcp); WREG32_SOC15(GC, GET_INST(GC, i), regCP_HYP_XCP_CTL, tmp); + } + ret = 0; } adev->gfx.num_xcc_per_xcp = num_xccs_per_xcp; - return 0; + return ret; } static int gfx_v9_4_3_ih_to_xcc_inst(struct amdgpu_device *adev, int ih_node) -- 2.34.1
Re: [PATCH v2] drm/amdgpu: Expose ras version & schema info
On 10/11/2023 2:55 PM, Asad Kamal wrote: Expose ras table version & schema info to sysfs v2: Updated schema to get poison support info from ras context, removed asic specific checks Signed-off-by: Asad Kamal One nit inline. With/without that change, Reviewed-by: Lijo Lazar --- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 51 +++-- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h | 3 ++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index 9c8203e87859..cb9e48fb40d2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -1370,6 +1370,22 @@ static ssize_t amdgpu_ras_sysfs_features_read(struct device *dev, return sysfs_emit(buf, "feature mask: 0x%x\n", con->features); } +static ssize_t amdgpu_ras_sysfs_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct amdgpu_ras *con = + container_of(attr, struct amdgpu_ras, version_attr); + return sysfs_emit(buf, "table version: 0x%x\n", con->eeprom_control.tbl_hdr.version); +} + +static ssize_t amdgpu_ras_sysfs_schema_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct amdgpu_ras *con = + container_of(attr, struct amdgpu_ras, schema_attr); + return sysfs_emit(buf, "schema: 0x%x\n", con->schema); +} + static void amdgpu_ras_sysfs_remove_bad_page_node(struct amdgpu_device *adev) { struct amdgpu_ras *con = amdgpu_ras_get_context(adev); @@ -1379,11 +1395,13 @@ static void amdgpu_ras_sysfs_remove_bad_page_node(struct amdgpu_device *adev) RAS_FS_NAME); } -static int amdgpu_ras_sysfs_remove_feature_node(struct amdgpu_device *adev) +static int amdgpu_ras_sysfs_remove_dev_attr_node(struct amdgpu_device *adev) { struct amdgpu_ras *con = amdgpu_ras_get_context(adev); struct attribute *attrs[] = { &con->features_attr.attr, + &con->version_attr.attr, + &con->schema_attr.attr, NULL }; struct attribute_group group = { @@ -1459,7 +1477,7 @@ static int amdgpu_ras_sysfs_remove_all(struct amdgpu_device *adev) if (amdgpu_bad_page_threshold != 0) amdgpu_ras_sysfs_remove_bad_page_node(adev); - amdgpu_ras_sysfs_remove_feature_node(adev); + amdgpu_ras_sysfs_remove_dev_attr_node(adev); return 0; } @@ -1582,6 +1600,10 @@ static BIN_ATTR(gpu_vram_bad_pages, S_IRUGO, amdgpu_ras_sysfs_badpages_read, NULL, 0); static DEVICE_ATTR(features, S_IRUGO, amdgpu_ras_sysfs_features_read, NULL); +static DEVICE_ATTR(version, 0444, + amdgpu_ras_sysfs_version_show, NULL); +static DEVICE_ATTR(schema, 0444, + amdgpu_ras_sysfs_schema_show, NULL); static int amdgpu_ras_fs_init(struct amdgpu_device *adev) { struct amdgpu_ras *con = amdgpu_ras_get_context(adev); @@ -1590,6 +1612,8 @@ static int amdgpu_ras_fs_init(struct amdgpu_device *adev) }; struct attribute *attrs[] = { &con->features_attr.attr, + &con->version_attr.attr, + &con->schema_attr.attr, NULL }; struct bin_attribute *bin_attrs[] = { @@ -1598,11 +1622,20 @@ static int amdgpu_ras_fs_init(struct amdgpu_device *adev) }; int r; + group.attrs = attrs; + /* add features entry */ con->features_attr = dev_attr_features; - group.attrs = attrs; sysfs_attr_init(attrs[0]); + /* add version entry */ + con->version_attr = dev_attr_version; + sysfs_attr_init(attrs[1]); + + /* add schema entry */ + con->schema_attr = dev_attr_schema; + sysfs_attr_init(attrs[2]); + if (amdgpu_bad_page_threshold != 0) { /* add bad_page_features entry */ bin_attr_gpu_vram_bad_pages.private = NULL; @@ -2594,6 +2627,14 @@ static void amdgpu_ras_query_poison_mode(struct amdgpu_device *adev) } } +static int amdgpu_get_ras_schema(struct amdgpu_device *adev) +{ + return (amdgpu_ras_is_poison_mode_supported(adev) << (ffs(AMDGPU_RAS_ERROR__POISON) - 1)) | It's simpler and more readable with a ternary operator. Thanks, Lijo + AMDGPU_RAS_ERROR__SINGLE_CORRECTABLE | + AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE | + AMDGPU_RAS_ERROR__PARITY; +} + int amdgpu_ras_init(struct amdgpu_device *adev) { struct amdgpu_ras *con = amdgpu_ras_get_context(adev); @@ -2636,6 +2677,7 @@ int amdgpu_ras_init(struct amdgpu_device *adev) con->update_channel_flag = false; con->features = 0; + con->schema = 0; INIT_LIST_HEAD(&con->head); /* Might need get this flag from vbios. */ c
RE: [PATCH] Revert "drm/amdgpu: Program xcp_ctl registers as needed"
[AMD Official Use Only - General] Reviewed-by: Asad Kamal Thanks & Regards Asad -Original Message- From: Gadre, Mangesh Sent: Wednesday, October 11, 2023 3:11 PM To: amd-gfx@lists.freedesktop.org; Zhang, Hawking ; Lazar, Lijo ; Ma, Le ; Zhang, Morris ; Kamal, Asad Cc: Gadre, Mangesh ; Lazar, Lijo Subject: [PATCH] Revert "drm/amdgpu: Program xcp_ctl registers as needed" This reverts commit 3cf01336313894419498a0d5eb367f092a436195. XCP_CTL register is programmed by firmware and register access is protected. Signed-off-by: Mangesh Gadre Reviewed-by: Lijo Lazar --- drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c | 23 +++ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c index fbfe0a1c4b19..39bc441695f9 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c @@ -623,7 +623,7 @@ static int gfx_v9_4_3_switch_compute_partition(struct amdgpu_device *adev, int num_xccs_per_xcp) { int ret, i, num_xcc; - u32 tmp = 0, regval; + u32 tmp = 0; if (adev->psp.funcs) { ret = psp_spatial_partition(&adev->psp, @@ -631,24 +631,23 @@ static int gfx_v9_4_3_switch_compute_partition(struct amdgpu_device *adev, num_xccs_per_xcp); if (ret) return ret; - } - - num_xcc = NUM_XCC(adev->gfx.xcc_mask); + } else { + num_xcc = NUM_XCC(adev->gfx.xcc_mask); - for (i = 0; i < num_xcc; i++) { - tmp = REG_SET_FIELD(tmp, CP_HYP_XCP_CTL, NUM_XCC_IN_XCP, - num_xccs_per_xcp); - tmp = REG_SET_FIELD(tmp, CP_HYP_XCP_CTL, VIRTUAL_XCC_ID, - i % num_xccs_per_xcp); - regval = RREG32_SOC15(GC, GET_INST(GC, i), regCP_HYP_XCP_CTL); - if (regval != tmp) + for (i = 0; i < num_xcc; i++) { + tmp = REG_SET_FIELD(tmp, CP_HYP_XCP_CTL, NUM_XCC_IN_XCP, + num_xccs_per_xcp); + tmp = REG_SET_FIELD(tmp, CP_HYP_XCP_CTL, VIRTUAL_XCC_ID, + i % num_xccs_per_xcp); WREG32_SOC15(GC, GET_INST(GC, i), regCP_HYP_XCP_CTL, tmp); + } + ret = 0; } adev->gfx.num_xcc_per_xcp = num_xccs_per_xcp; - return 0; + return ret; } static int gfx_v9_4_3_ih_to_xcc_inst(struct amdgpu_device *adev, int ih_node) -- 2.34.1
Re: [PATCH] drm/amdgpu: disable GFXOFF and PG during compute for GFX9
On Wed, Oct 11, 2023 at 3:52 AM Jesse Zhang wrote: > > Temporary workaround to fix issues observed in some compute applications > when GFXOFF is enabled on GFX9. > > Signed-off-by: Jesse Zhang > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | 4 > 1 file changed, 4 insertions(+) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c > index d3805d6f..fef93d4edcbc 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c > @@ -683,12 +683,16 @@ int amdgpu_amdkfd_submit_ib(struct amdgpu_device *adev, > > void amdgpu_amdkfd_set_compute_idle(struct amdgpu_device *adev, bool idle) > { > + enum amd_powergating_state state = idle ? AMD_PG_STATE_GATE : > AMD_PG_STATE_UNGATE; > /* Temporary workaround to fix issues observed in some > * compute applications when GFXOFF is enabled on GFX11. > */ > if (IP_VERSION_MAJ(amdgpu_ip_version(adev, GC_HWIP, 0)) == 11) { > pr_debug("GFXOFF is %s\n", idle ? "enabled" : "disabled"); > amdgpu_gfx_off_ctrl(adev, idle); > + } else if ((IP_VERSION_MAJ(amdgpu_ip_version(adev, GC_HWIP, 0)) == 9) > && > + (adev->flags & AMD_IS_APU)) { > + > adev->ip_blocks[AMD_IP_BLOCK_TYPE_GFX].version->funcs->set_powergating_state((void > *)adev, state); Why not use amdgpu_gfx_off_ctrl(adev, idle); for consistency? Alex > } > amdgpu_dpm_switch_power_profile(adev, > PP_SMC_POWER_PROFILE_COMPUTE, > -- > 2.25.1 >
[PATCH 1/3] drm/amdgpu: Update PSP interface header
Adds FW id for P2S table. Signed-off-by: Lijo Lazar --- drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h b/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h index dfd60db97012..4bb5e10217bb 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h +++ b/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h @@ -296,6 +296,7 @@ enum psp_gfx_fw_type { GFX_FW_TYPE_VPEC_FW1= 100, /* VPEC FW1 To Save VPE */ GFX_FW_TYPE_VPEC_FW2= 101, /* VPEC FW2 To Save VPE */ GFX_FW_TYPE_VPE = 102, + GFX_FW_TYPE_P2S_TABLE = 129, GFX_FW_TYPE_MAX }; -- 2.25.1
[PATCH 3/3] drm/amd/pm: Add P2S tables for SMU v13.0.6
Add P2S table load support on SMU v13.0.6 ASICs. Signed-off-by: Lijo Lazar --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 7 ++ .../drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c | 71 +++ 2 files changed, 78 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index c41bd07f3f98..49e914ee6efe 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -2516,6 +2516,13 @@ static int psp_load_p2s_table(struct psp_context *psp) if (adev->in_runpm && (adev->pm.rpm_mode == AMDGPU_RUNPM_BACO)) return 0; + if (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(11, 0, 6)) { + uint32_t supp_vers = adev->flags & AMD_IS_APU ? 0x0036013D : + 0x0036003C; + if (psp->sos.fw_version < supp_vers) + return 0; + } + if (!ucode->fw || amdgpu_sriov_vf(psp->adev)) return 0; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c index 8220bdcbd927..a295403e2a09 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c @@ -65,6 +65,8 @@ #undef pr_info #undef pr_debug +MODULE_FIRMWARE("amdgpu/smu_13_0_6.bin"); + #define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c)) #define SMU_13_0_6_FEA_MAP(smu_feature, smu_13_0_6_feature) \ @@ -123,6 +125,9 @@ struct mca_ras_info { enum amdgpu_mca_error_type type, int idx, uint32_t *count); }; +#define P2S_TABLE_ID_A 0x50325341 +#define P2S_TABLE_ID_X 0x50325358 + static const struct cmn2asic_msg_mapping smu_v13_0_6_message_map[SMU_MSG_MAX_COUNT] = { MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 0), MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1), @@ -256,6 +261,70 @@ struct smu_v13_0_6_dpm_map { uint32_t *freq_table; }; +static int smu_v13_0_6_init_microcode(struct smu_context *smu) +{ + const struct smc_firmware_header_v2_1 *v2_1; + const struct smc_firmware_header_v1_0 *hdr; + struct amdgpu_firmware_info *ucode = NULL; + struct smc_soft_pptable_entry *entries; + struct amdgpu_device *adev = smu->adev; + uint32_t p2s_table_id = P2S_TABLE_ID_A; + int ret = 0, i, p2stable_count; + char ucode_prefix[30]; + char fw_name[30]; + + /* No need to load P2S tables in IOV mode */ + if (amdgpu_sriov_vf(adev)) + return 0; + + if (!(adev->flags & AMD_IS_APU)) + p2s_table_id = P2S_TABLE_ID_X; + + amdgpu_ucode_ip_version_decode(adev, MP1_HWIP, ucode_prefix, + sizeof(ucode_prefix)); + + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", ucode_prefix); + + ret = amdgpu_ucode_request(adev, &adev->pm.fw, fw_name); + if (ret) + goto out; + + hdr = (const struct smc_firmware_header_v1_0 *)adev->pm.fw->data; + amdgpu_ucode_print_smc_hdr(&hdr->header); + + /* SMU v13.0.6 binary file doesn't carry pptables, instead the entries +* are used to carry p2s tables. +*/ + v2_1 = (const struct smc_firmware_header_v2_1 *)adev->pm.fw->data; + entries = (struct smc_soft_pptable_entry + *)((uint8_t *)v2_1 + + le32_to_cpu(v2_1->pptable_entry_offset)); + p2stable_count = le32_to_cpu(v2_1->pptable_count); + for (i = 0; i < p2stable_count; i++) { + if (le32_to_cpu(entries[i].id) == p2s_table_id) { + smu->pptable_firmware.data = + ((uint8_t *)v2_1 + +le32_to_cpu(entries[i].ppt_offset_bytes)); + smu->pptable_firmware.size = + le32_to_cpu(entries[i].ppt_size_bytes); + break; + } + } + + if (smu->pptable_firmware.data && smu->pptable_firmware.size) { + ucode = &adev->firmware.ucode[AMDGPU_UCODE_ID_P2S_TABLE]; + ucode->ucode_id = AMDGPU_UCODE_ID_P2S_TABLE; + ucode->fw = &smu->pptable_firmware; + adev->firmware.fw_size += ALIGN(ucode->fw->size, PAGE_SIZE); + } + + return 0; +out: + amdgpu_ucode_release(&adev->pm.fw); + + return ret; +} + static int smu_v13_0_6_tables_init(struct smu_context *smu) { struct smu_table_context *smu_table = &smu->smu_table; @@ -2787,6 +2856,8 @@ static const struct pptable_funcs smu_v13_0_6_ppt_funcs = { .get_power_limit = smu_v13_0_6_get_power_limit, .is_dpm_running = smu_v13_0_6_is_dpm_running, .get
[PATCH 2/3] drm/amdgpu: Add support to load P2S tables
Add support to load P2S tables through PSP. Signed-off-by: Lijo Lazar --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 27 +++ drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | 6 + drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h | 1 + 3 files changed, 34 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 72ee66db182c..c41bd07f3f98 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -2412,6 +2412,9 @@ static int psp_get_fw_type(struct amdgpu_firmware_info *ucode, case AMDGPU_UCODE_ID_UMSCH_MM_CMD_BUFFER: *type = GFX_FW_TYPE_UMSCH_CMD_BUFFER; break; + case AMDGPU_UCODE_ID_P2S_TABLE: + *type = GFX_FW_TYPE_P2S_TABLE; + break; case AMDGPU_UCODE_ID_MAXIMUM: default: return -EINVAL; @@ -2503,6 +2506,24 @@ int psp_execute_ip_fw_load(struct psp_context *psp, return ret; } +static int psp_load_p2s_table(struct psp_context *psp) +{ + int ret; + struct amdgpu_device *adev = psp->adev; + struct amdgpu_firmware_info *ucode = + &adev->firmware.ucode[AMDGPU_UCODE_ID_P2S_TABLE]; + + if (adev->in_runpm && (adev->pm.rpm_mode == AMDGPU_RUNPM_BACO)) + return 0; + + if (!ucode->fw || amdgpu_sriov_vf(psp->adev)) + return 0; + + ret = psp_execute_ip_fw_load(psp, ucode); + + return ret; +} + static int psp_load_smu_fw(struct psp_context *psp) { int ret; @@ -2543,6 +2564,9 @@ static bool fw_load_skip_check(struct psp_context *psp, if (!ucode->fw || !ucode->ucode_size) return true; + if (ucode->ucode_id == AMDGPU_UCODE_ID_P2S_TABLE) + return true; + if (ucode->ucode_id == AMDGPU_UCODE_ID_SMC && (psp_smu_reload_quirk(psp) || psp->autoload_supported || @@ -2591,6 +2615,9 @@ static int psp_load_non_psp_fw(struct psp_context *psp) return ret; } + /* Load P2S table first if it's available */ + psp_load_p2s_table(psp); + for (i = 0; i < adev->firmware.max_ucodes; i++) { ucode = &adev->firmware.ucode[i]; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c index 771ef8017a98..606406c88677 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c @@ -642,6 +642,8 @@ const char *amdgpu_ucode_name(enum AMDGPU_UCODE_ID ucode_id) return "SMC"; case AMDGPU_UCODE_ID_PPTABLE: return "PPTABLE"; + case AMDGPU_UCODE_ID_P2S_TABLE: + return "P2STABLE"; case AMDGPU_UCODE_ID_UVD: return "UVD"; case AMDGPU_UCODE_ID_UVD1: @@ -922,6 +924,10 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev, ucode->ucode_size = ucode->fw->size; ucode_addr = (u8 *)ucode->fw->data; break; + case AMDGPU_UCODE_ID_P2S_TABLE: + ucode->ucode_size = ucode->fw->size; + ucode_addr = (u8 *)ucode->fw->data; + break; case AMDGPU_UCODE_ID_IMU_I: ucode->ucode_size = le32_to_cpu(imu_hdr->imu_iram_ucode_size_bytes); ucode_addr = (u8 *)ucode->fw->data + diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h index ae5fa61d2890..4244a13f9f22 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h @@ -510,6 +510,7 @@ enum AMDGPU_UCODE_ID { AMDGPU_UCODE_ID_UMSCH_MM_UCODE, AMDGPU_UCODE_ID_UMSCH_MM_DATA, AMDGPU_UCODE_ID_UMSCH_MM_CMD_BUFFER, + AMDGPU_UCODE_ID_P2S_TABLE, AMDGPU_UCODE_ID_MAXIMUM, }; -- 2.25.1
[PATCH 1/2] drm/amdgpu: Acquire ttm locks for dmaunmap
dmaunmap can call ttm_bo_validate, which expects the ttm dma_resv to be held. Acquire the locks in amdgpu_amdkfd_gpuvm_dmaunmap_mem. Signed-off-by: David Francis --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 12 +++- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 7 ++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h index 3ad8dc523b42..dba4f6b7a2f9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h @@ -302,7 +302,7 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv); int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu( struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv); -void amdgpu_amdkfd_gpuvm_dmaunmap_mem(struct kgd_mem *mem, void *drm_priv); +int amdgpu_amdkfd_gpuvm_dmaunmap_mem(struct kgd_mem *mem, void *drm_priv); int amdgpu_amdkfd_gpuvm_sync_memory( struct amdgpu_device *adev, struct kgd_mem *mem, bool intr); int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct kgd_mem *mem, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index a15e59abe70a..808deec8aa58 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -2094,21 +2094,31 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu( return ret; } -void amdgpu_amdkfd_gpuvm_dmaunmap_mem(struct kgd_mem *mem, void *drm_priv) +int amdgpu_amdkfd_gpuvm_dmaunmap_mem(struct kgd_mem *mem, void *drm_priv) { struct kfd_mem_attachment *entry; struct amdgpu_vm *vm; + struct bo_vm_reservation_context ctx; + int ret; vm = drm_priv_to_vm(drm_priv); mutex_lock(&mem->lock); + ret = reserve_bo_and_cond_vms(mem, vm, BO_VM_MAPPED, &ctx); + if (ret) + goto out; + list_for_each_entry(entry, &mem->attachments, list) { if (entry->bo_va->base.vm == vm) kfd_mem_dmaunmap_attachment(mem, entry); } + unreserve_bo_and_vms(&ctx, false, false); + +out: mutex_unlock(&mem->lock); + return ret; } int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu( diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 06988cf1db51..21d4e7d46238 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -1442,7 +1442,11 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep, kfd_flush_tlb(peer_pdd, TLB_FLUSH_HEAVYWEIGHT); /* Remove dma mapping after tlb flush to avoid IO_PAGE_FAULT */ - amdgpu_amdkfd_gpuvm_dmaunmap_mem(mem, peer_pdd->drm_priv); + err = amdgpu_amdkfd_gpuvm_dmaunmap_mem(mem, peer_pdd->drm_priv); + if (err) { + pr_debug("DMA unmapping failed\n"); + goto dmaunmap_failed; + } } mutex_unlock(&p->mutex); @@ -1455,6 +1459,7 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep, get_mem_obj_from_handle_failed: unmap_memory_from_gpu_failed: sync_memory_failed: +dmaunmap_failed: mutex_unlock(&p->mutex); copy_from_user_failed: kfree(devices_arr); -- 2.34.1
[PATCH 2/2] drm/amdgpu: Permit PCIe transfer over links with XGMI
When the CPU is XGMI connected, the PCIe links should not be enumerated for topology purposes. However, PCIe transfer should still be a valid option for memory attachment that requires it. Move the XGMI connection check out of the shared helper function amdgpu_device_is_peer_accessible and into the topology path. Signed-off-by: David Francis --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 4 +--- drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 3 +++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index bad2b5577e96..b47cb7f8cfbd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -5753,9 +5753,7 @@ bool amdgpu_device_is_peer_accessible(struct amdgpu_device *adev, ~*peer_adev->dev->dma_mask : ~((1ULL << 32) - 1); resource_size_t aper_limit = adev->gmc.aper_base + adev->gmc.aper_size - 1; - bool p2p_access = - !adev->gmc.xgmi.connected_to_cpu && - !(pci_p2pdma_distance(adev->pdev, peer_adev->dev, false) < 0); + bool p2p_access = !(pci_p2pdma_distance(adev->pdev, peer_adev->dev, false) < 0); return pcie_p2p && p2p_access && (adev->gmc.visible_vram_size && adev->gmc.real_vram_size == adev->gmc.visible_vram_size && diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index 4e530791507e..f0cff5072736 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c @@ -1423,6 +1423,9 @@ static int kfd_add_peer_prop(struct kfd_topology_device *kdev, peer->gpu->adev)) return ret; + if (kdev->gpu->adev->gmc.xgmi.connected_to_cpu) + return ret; + iolink1 = list_first_entry(&kdev->io_link_props, struct kfd_iolink_properties, list); if (!iolink1) -- 2.34.1
[PATCH] drm/amdgpu/mes11: remove aggregated doorbell code
It's not enabled in hardware so the code is dead. Remove it. Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 86 +- drivers/gpu/drm/amd/amdgpu/mes_v11_0.c | 56 - drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c | 83 - 3 files changed, 40 insertions(+), 185 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c index 27b224b0688a..91c07ab4f14e 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c @@ -5170,45 +5170,17 @@ static u64 gfx_v11_0_ring_get_wptr_gfx(struct amdgpu_ring *ring) static void gfx_v11_0_ring_set_wptr_gfx(struct amdgpu_ring *ring) { struct amdgpu_device *adev = ring->adev; - uint32_t *wptr_saved; - uint32_t *is_queue_unmap; - uint64_t aggregated_db_index; - uint32_t mqd_size = adev->mqds[AMDGPU_HW_IP_GFX].mqd_size; - uint64_t wptr_tmp; - if (ring->is_mes_queue) { - wptr_saved = (uint32_t *)(ring->mqd_ptr + mqd_size); - is_queue_unmap = (uint32_t *)(ring->mqd_ptr + mqd_size + - sizeof(uint32_t)); - aggregated_db_index = - amdgpu_mes_get_aggregated_doorbell_index(adev, -ring->hw_prio); - - wptr_tmp = ring->wptr & ring->buf_mask; - atomic64_set((atomic64_t *)ring->wptr_cpu_addr, wptr_tmp); - *wptr_saved = wptr_tmp; - /* assume doorbell always being used by mes mapped queue */ - if (*is_queue_unmap) { - WDOORBELL64(aggregated_db_index, wptr_tmp); - WDOORBELL64(ring->doorbell_index, wptr_tmp); - } else { - WDOORBELL64(ring->doorbell_index, wptr_tmp); - - if (*is_queue_unmap) - WDOORBELL64(aggregated_db_index, wptr_tmp); - } + if (ring->use_doorbell) { + /* XXX check if swapping is necessary on BE */ + atomic64_set((atomic64_t *)ring->wptr_cpu_addr, +ring->wptr); + WDOORBELL64(ring->doorbell_index, ring->wptr); } else { - if (ring->use_doorbell) { - /* XXX check if swapping is necessary on BE */ - atomic64_set((atomic64_t *)ring->wptr_cpu_addr, -ring->wptr); - WDOORBELL64(ring->doorbell_index, ring->wptr); - } else { - WREG32_SOC15(GC, 0, regCP_RB0_WPTR, -lower_32_bits(ring->wptr)); - WREG32_SOC15(GC, 0, regCP_RB0_WPTR_HI, -upper_32_bits(ring->wptr)); - } + WREG32_SOC15(GC, 0, regCP_RB0_WPTR, +lower_32_bits(ring->wptr)); + WREG32_SOC15(GC, 0, regCP_RB0_WPTR_HI, +upper_32_bits(ring->wptr)); } } @@ -5233,42 +5205,14 @@ static u64 gfx_v11_0_ring_get_wptr_compute(struct amdgpu_ring *ring) static void gfx_v11_0_ring_set_wptr_compute(struct amdgpu_ring *ring) { struct amdgpu_device *adev = ring->adev; - uint32_t *wptr_saved; - uint32_t *is_queue_unmap; - uint64_t aggregated_db_index; - uint32_t mqd_size = adev->mqds[AMDGPU_HW_IP_COMPUTE].mqd_size; - uint64_t wptr_tmp; - if (ring->is_mes_queue) { - wptr_saved = (uint32_t *)(ring->mqd_ptr + mqd_size); - is_queue_unmap = (uint32_t *)(ring->mqd_ptr + mqd_size + - sizeof(uint32_t)); - aggregated_db_index = - amdgpu_mes_get_aggregated_doorbell_index(adev, -ring->hw_prio); - - wptr_tmp = ring->wptr & ring->buf_mask; - atomic64_set((atomic64_t *)ring->wptr_cpu_addr, wptr_tmp); - *wptr_saved = wptr_tmp; - /* assume doorbell always used by mes mapped queue */ - if (*is_queue_unmap) { - WDOORBELL64(aggregated_db_index, wptr_tmp); - WDOORBELL64(ring->doorbell_index, wptr_tmp); - } else { - WDOORBELL64(ring->doorbell_index, wptr_tmp); - - if (*is_queue_unmap) - WDOORBELL64(aggregated_db_index, wptr_tmp); - } + /* XXX check if swapping is necessary on BE */ + if (ring->use_doorbell) { + atomic64_set((atomic64_t *)ring->wptr_cpu_addr, +ring->wptr); + WDOORBELL64(ring->doorbell_index, ring->wptr); } else { - /* XXX
Re: [PATCH v2 1/7] drm/amdkfd: Wait vm update fence after retry fault recovered
On 10/10/2023 9:40 AM, Philip Yang wrote: Caution: This message originated from an External Source. Use proper caution when opening attachments, clicking links, or responding. If using sdma update GPU page table, kfd flush tlb does nothing if vm update fence callback doesn't update vm->tlb_seq. This works now because retry fault keep coming and will be handled to update page table again after AMDGPU_SVM_RANGE_RETRY_FAULT_PENDING timeout and flush tlb. With the following patch to add bitmap_mapped flag, the retry fault recover will only update GPU page table once, need wait vm udate fence and then flush tlb. No change if using CPU update GPU page table because no vm update fence. Remove wait parameter in svm_range_validate_and_map because it is always called with true now. I think it is better to add sdma at this patch title, like " Wait sdma vm update fence after retry fault recovered" as this patch only applies to using sdma to update page table in page fault recovery. It can improve performance in this case. Waiting fence would delay page fault recovery process, we may need to look how it affects IH sw ring overflow in future. Regards Xiaogang Signed-off-by: Philip Yang --- drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 15 +++ 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c index 2b4ccc0531e8..e195106a77cb 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c @@ -1454,7 +1454,7 @@ svm_range_map_to_gpu(struct kfd_process_device *pdd, struct svm_range *prange, static int svm_range_map_to_gpus(struct svm_range *prange, unsigned long offset, unsigned long npages, bool readonly, - unsigned long *bitmap, bool wait, bool flush_tlb) + unsigned long *bitmap, bool flush_tlb) { struct kfd_process_device *pdd; struct amdgpu_device *bo_adev = NULL; @@ -1487,8 +1487,7 @@ svm_range_map_to_gpus(struct svm_range *prange, unsigned long offset, r = svm_range_map_to_gpu(pdd, prange, offset, npages, readonly, prange->dma_addr[gpuidx], -bo_adev, wait ? &fence : NULL, -flush_tlb); +bo_adev, &fence, flush_tlb); if (r) break; @@ -1612,7 +1611,7 @@ static void *kfd_svm_page_owner(struct kfd_process *p, int32_t gpuidx) */ static int svm_range_validate_and_map(struct mm_struct *mm, struct svm_range *prange, int32_t gpuidx, - bool intr, bool wait, bool flush_tlb) + bool intr, bool flush_tlb) { struct svm_validate_context *ctx; unsigned long start, end, addr; @@ -1741,7 +1740,7 @@ static int svm_range_validate_and_map(struct mm_struct *mm, if (!r) r = svm_range_map_to_gpus(prange, offset, npages, readonly, - ctx->bitmap, wait, flush_tlb); + ctx->bitmap, flush_tlb); if (!r && next == end) prange->mapped_to_gpu = true; @@ -1848,7 +1847,7 @@ static void svm_range_restore_work(struct work_struct *work) mutex_lock(&prange->migrate_mutex); r = svm_range_validate_and_map(mm, prange, MAX_GPU_INSTANCE, - false, true, false); + false, false); if (r) pr_debug("failed %d to map 0x%lx to gpus\n", r, prange->start); @@ -3094,7 +3093,7 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid, } } - r = svm_range_validate_and_map(mm, prange, gpuidx, false, false, false); + r = svm_range_validate_and_map(mm, prange, gpuidx, false, false); if (r) pr_debug("failed %d to map svms 0x%p [0x%lx 0x%lx] to gpus\n", r, svms, prange->start, prange->last); @@ -3643,7 +3642,7 @@ svm_range_set_attr(struct kfd_process *p, struct mm_struct *mm, flush_tlb = !migrated && update_mapping && prange->mapped_to_gpu; r = svm_range_validate_and_map(mm, prange, MAX_GPU_INSTANCE, - true, true, flush_tlb); + true, flush_tlb); if (r) pr_debug("failed %d to map svm range\n", r); -- 2.35.1
Re: [PATCH v2 3/7] amd/amdkfd: Add granularity bitmap mapped to gpu flag
On 10/10/2023 9:40 AM, Philip Yang wrote: Caution: This message originated from an External Source. Use proper caution when opening attachments, clicking links, or responding. Replace prange->mapped_to_gpu with prange->bitmap_mapped[], which is per GPU flag and based on prange granularity, updated when map to GPUS or unmap from GPUs, to optimize multiple GPU map, unmap and retry fault recover. svm_range_partial_mapped is false only if no part of the range mapping on any GPUs. Signed-off-by: Philip Yang --- drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 256 +-- drivers/gpu/drm/amd/amdkfd/kfd_svm.h | 8 +- 2 files changed, 213 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c index fb22b857adbc..4e1af4b181ea 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c @@ -296,12 +296,12 @@ static void svm_range_free(struct svm_range *prange, bool do_unmap) KFD_IOC_ALLOC_MEM_FLAGS_USERPTR, 0); } - /* free dma_addr array for each gpu */ + /* free dma_addr array, bitmap_mapped for each gpu */ for (gpuidx = 0; gpuidx < MAX_GPU_INSTANCE; gpuidx++) { - if (prange->dma_addr[gpuidx]) { + if (prange->dma_addr[gpuidx]) kvfree(prange->dma_addr[gpuidx]); - prange->dma_addr[gpuidx] = NULL; I do not know why remove this line. - } + if (prange->bitmap_mapped[gpuidx]) + bitmap_free(prange->bitmap_mapped[gpuidx]); } mutex_destroy(&prange->lock); @@ -327,19 +327,38 @@ svm_range *svm_range_new(struct svm_range_list *svms, uint64_t start, uint64_t size = last - start + 1; struct svm_range *prange; struct kfd_process *p; - - prange = kzalloc(sizeof(*prange), GFP_KERNEL); - if (!prange) - return NULL; + unsigned int nbits; + uint32_t gpuidx; p = container_of(svms, struct kfd_process, svms); if (!p->xnack_enabled && update_mem_usage && amdgpu_amdkfd_reserve_mem_limit(NULL, size << PAGE_SHIFT, KFD_IOC_ALLOC_MEM_FLAGS_USERPTR, 0)) { pr_info("SVM mapping failed, exceeds resident system memory limit\n"); - kfree(prange); return NULL; } + + prange = kzalloc(sizeof(*prange), GFP_KERNEL); + if (!prange) + return NULL; + + svm_range_set_default_attributes(&prange->preferred_loc, +&prange->prefetch_loc, +&prange->granularity, &prange->flags); + + nbits = svm_range_mapped_nbits(start, last, prange->granularity); + pr_debug("prange 0x%p [0x%llx 0x%llx] bitmap_mapped nbits %d\n", prange, +start, last, nbits); + for_each_set_bit(gpuidx, p->svms.bitmap_supported, p->n_pdds) { + prange->bitmap_mapped[gpuidx] = bitmap_zalloc(nbits, GFP_KERNEL); + if (!prange->bitmap_mapped[gpuidx]) { + while (gpuidx--) + bitmap_free(prange->bitmap_mapped[gpuidx]); + kfree(prange); + return NULL; + } + } + prange->npages = size; prange->svms = svms; prange->start = start; @@ -359,10 +378,6 @@ svm_range *svm_range_new(struct svm_range_list *svms, uint64_t start, bitmap_copy(prange->bitmap_access, svms->bitmap_supported, MAX_GPU_INSTANCE); - svm_range_set_default_attributes(&prange->preferred_loc, -&prange->prefetch_loc, -&prange->granularity, &prange->flags); - pr_debug("svms 0x%p [0x%llx 0x%llx]\n", svms, start, last); return prange; @@ -984,6 +999,47 @@ svm_range_split_nodes(struct svm_range *new, struct svm_range *old, return 0; } +static int +svm_range_split_bitmap_mapped(struct svm_range *new, struct svm_range *old, + uint64_t start, uint64_t last) +{ + struct kfd_process *p = container_of(new->svms, struct kfd_process, svms); + unsigned int nbits, old_nbits, old_nbits2; + unsigned long *bits; + uint32_t gpuidx; + + nbits = svm_range_mapped_nbits(new->start, new->last, new->granularity); + old_nbits = svm_range_mapped_nbits(old->start, old->last, old->granularity); + old_nbits2 = svm_range_mapped_nbits(start, last, old->granularity); + + pr_debug("old 0x%p [0x%lx 0x%lx] => [0x%llx 0x%llx] nbits %d => %d\n", +old, old->start, old->last, start, last, old_nbits, old_nbits2); + pr_debug("new 0x%p [0x%lx 0x%lx] nbits %d\n", new, new->start, new
Re: [PATCH v2 5/7] drm/amdkfd: Check bitmap_mapped flag to skip retry fault
On 10/10/2023 9:40 AM, Philip Yang wrote: Caution: This message originated from an External Source. Use proper caution when opening attachments, clicking links, or responding. Remove prange validate_timestamp which is not accurate for multiple GPUs. Use the bitmap_mapped flag to skip the retry fault from different pages of the same range if the range is already mapped on the specific GPU. This should be "different pages of same granularity range" as comments inside function svm_range_restore_page. Signed-off-by: Philip Yang Reviewed-by: Felix Kuehling --- drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 24 drivers/gpu/drm/amd/amdkfd/kfd_svm.h | 1 - 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c index daa996d7039d..0ee5633c8972 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c @@ -43,10 +43,6 @@ #define AMDGPU_SVM_RANGE_RESTORE_DELAY_MS 1 -/* Long enough to ensure no retry fault comes after svm range is restored and - * page table is updated. - */ -#define AMDGPU_SVM_RANGE_RETRY_FAULT_PENDING (2UL * NSEC_PER_MSEC) #if IS_ENABLED(CONFIG_DYNAMIC_DEBUG) #define dynamic_svm_range_dump(svms) \ _dynamic_func_call_no_desc("svm_range_dump", svm_range_debug_dump, svms) @@ -369,7 +365,6 @@ svm_range *svm_range_new(struct svm_range_list *svms, uint64_t start, INIT_LIST_HEAD(&prange->deferred_list); INIT_LIST_HEAD(&prange->child_list); atomic_set(&prange->invalid, 0); - prange->validate_timestamp = 0; prange->vram_pages = 0; mutex_init(&prange->migrate_mutex); mutex_init(&prange->lock); @@ -1938,8 +1933,6 @@ static int svm_range_validate_and_map(struct mm_struct *mm, } svm_range_unreserve_bos(ctx); - if (!r) - prange->validate_timestamp = ktime_get_boottime(); free_ctx: kfree(ctx); @@ -3214,15 +3207,6 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid, goto out_unlock_range; } - /* skip duplicate vm fault on different pages of same range */ - if (ktime_before(timestamp, ktime_add_ns(prange->validate_timestamp, - AMDGPU_SVM_RANGE_RETRY_FAULT_PENDING))) { - pr_debug("svms 0x%p [0x%lx %lx] already restored\n", -svms, prange->start, prange->last); - r = 0; - goto out_unlock_range; - } - /* __do_munmap removed VMA, return success as we are handling stale * retry fault. */ @@ -3248,6 +3232,14 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid, goto out_unlock_range; } + /* skip duplicate vm fault on different pages of same granularity range */ + if (svm_range_partial_mapped_dev(gpuidx, prange, addr, addr)) { should use svm_range_complete_mapped on gpuidx, instead of svm_range_partial_mapped_dev? Regards Xiaogang + pr_debug("svms 0x%p [0x%lx %lx] addr 0x%llx already mapped on gpu %d\n", +svms, prange->start, prange->last, addr, gpuidx); + r = 0; + goto out_unlock_range; + } + pr_debug("svms %p [0x%lx 0x%lx] best restore 0x%x, actual loc 0x%x\n", svms, prange->start, prange->last, best_loc, prange->actual_loc); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h index 7e165854bc0e..7a12be42cf16 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.h @@ -129,7 +129,6 @@ struct svm_range { uint32_tactual_loc; uint8_t granularity; atomic_tinvalid; - ktime_t validate_timestamp; struct mmu_interval_notifiernotifier; struct svm_work_list_item work_item; struct list_headdeferred_list; -- 2.35.1
Re: [PATCH 1/2] drm/amdgpu: Acquire ttm locks for dmaunmap
On 2023-10-11 14:22, David Francis wrote: dmaunmap can call ttm_bo_validate, which expects the ttm dma_resv to be held. Acquire the locks in amdgpu_amdkfd_gpuvm_dmaunmap_mem. Signed-off-by: David Francis --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 12 +++- drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 7 ++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h index 3ad8dc523b42..dba4f6b7a2f9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h @@ -302,7 +302,7 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu(struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv); int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu( struct amdgpu_device *adev, struct kgd_mem *mem, void *drm_priv); -void amdgpu_amdkfd_gpuvm_dmaunmap_mem(struct kgd_mem *mem, void *drm_priv); +int amdgpu_amdkfd_gpuvm_dmaunmap_mem(struct kgd_mem *mem, void *drm_priv); int amdgpu_amdkfd_gpuvm_sync_memory( struct amdgpu_device *adev, struct kgd_mem *mem, bool intr); int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct kgd_mem *mem, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index a15e59abe70a..808deec8aa58 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -2094,21 +2094,31 @@ int amdgpu_amdkfd_gpuvm_map_memory_to_gpu( return ret; } -void amdgpu_amdkfd_gpuvm_dmaunmap_mem(struct kgd_mem *mem, void *drm_priv) +int amdgpu_amdkfd_gpuvm_dmaunmap_mem(struct kgd_mem *mem, void *drm_priv) { struct kfd_mem_attachment *entry; struct amdgpu_vm *vm; + struct bo_vm_reservation_context ctx; + int ret; vm = drm_priv_to_vm(drm_priv); mutex_lock(&mem->lock); + ret = reserve_bo_and_cond_vms(mem, vm, BO_VM_MAPPED, &ctx); Looks like you copied this from somewhere else. Do you really need to reserve the VM here, or just the BO? If you only need to reserve the BO, just use amdgpu_bo_reserve. + if (ret) + goto out; + list_for_each_entry(entry, &mem->attachments, list) { if (entry->bo_va->base.vm == vm) kfd_mem_dmaunmap_attachment(mem, entry); } + unreserve_bo_and_vms(&ctx, false, false); + +out: mutex_unlock(&mem->lock); + return ret; } int amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu( diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 06988cf1db51..21d4e7d46238 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -1442,7 +1442,11 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep, kfd_flush_tlb(peer_pdd, TLB_FLUSH_HEAVYWEIGHT); /* Remove dma mapping after tlb flush to avoid IO_PAGE_FAULT */ - amdgpu_amdkfd_gpuvm_dmaunmap_mem(mem, peer_pdd->drm_priv); + err = amdgpu_amdkfd_gpuvm_dmaunmap_mem(mem, peer_pdd->drm_priv); + if (err) { This is probably not correct. The only failure case I know of is, that the reservation is interrupted by a signal and returns -ERESTARTSYS. When this happens, the ioctl will automatically get restarted after handling the signal. We need to make sure that we handle this restart case correctly. When this happens, all the unmapping is already done from the first time the function ran. All we need to repeat is the dmaunmap. We already handled this scenario for amdgpu_amdkfd_gpuvm_sync_memory. Make sure it also works correctly for this new dmaunmap case. Basically, we don't want to accidentally dmaunmap the same thing twice. And we need to make sure that amdgpu_amdkfd_gpuvm_sync_memory is harmless if it's called multiple times due to restarts. There is a test in KFDTest specifically to try to recreate this scenario where amdgpu_amdkfd_gpuvm_sync_memory gets interrupted by a signal: KFDMemoryTest.SignalHandling. It probably won't be able to trigger a signal interrupting an amdgpu_bo_reserve, though, because that's very fast if there is no lock contention. So we may just have to rely on code review. Or you can try to recreate the scenario manually by returning -ERESTARTSYS under some conditions. Regards, Felix + pr_debug("DMA unmapping failed\n"); + goto dmaunmap_failed; + } } mutex_unlock(&p->mutex); @@ -1455,6 +1459,7 @@ static int kfd_ioctl_unmap_memory_from_gpu(struct file *filep, get_mem_obj_from_handle_failed: unmap_memory_from_gpu_failed: sync_memory_failed: +dmaunmap_failed: mutex_unlock(&p->mutex); copy_from_u
Re: [PATCH 2/2] drm/amdgpu: Permit PCIe transfer over links with XGMI
On 2023-10-11 14:22, David Francis wrote: When the CPU is XGMI connected, the PCIe links should not be enumerated for topology purposes. However, PCIe transfer should still be a valid option for memory attachment that requires it. You could be more specific here. This is for remote doorbells and MMIO mappings. Move the XGMI connection check out of the shared helper function amdgpu_device_is_peer_accessible and into the topology path. Signed-off-by: David Francis --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 4 +--- drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 3 +++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index bad2b5577e96..b47cb7f8cfbd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -5753,9 +5753,7 @@ bool amdgpu_device_is_peer_accessible(struct amdgpu_device *adev, ~*peer_adev->dev->dma_mask : ~((1ULL << 32) - 1); resource_size_t aper_limit = adev->gmc.aper_base + adev->gmc.aper_size - 1; - bool p2p_access = - !adev->gmc.xgmi.connected_to_cpu && - !(pci_p2pdma_distance(adev->pdev, peer_adev->dev, false) < 0); + bool p2p_access = !(pci_p2pdma_distance(adev->pdev, peer_adev->dev, false) < 0); return pcie_p2p && p2p_access && (adev->gmc.visible_vram_size && adev->gmc.real_vram_size == adev->gmc.visible_vram_size && diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index 4e530791507e..f0cff5072736 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c @@ -1423,6 +1423,9 @@ static int kfd_add_peer_prop(struct kfd_topology_device *kdev, peer->gpu->adev)) return ret; + if (kdev->gpu->adev->gmc.xgmi.connected_to_cpu) + return ret; + I believe this is only needed for the case that XGMI is disabled via the module param. When XGMI is enabled, you shouldn't get here because kfd_dev_create_p2p_links doesn't call kfd_add_peer_prop if the GPUs are themselves in an XGMI hive. In fact, it may be clearer to move this condition into kfd_dev_create_p2p_links. Regards, Felix iolink1 = list_first_entry(&kdev->io_link_props, struct kfd_iolink_properties, list); if (!iolink1)
[PATCH] Find bo_va before create it when map bo into compute VM
From: Xiaogang Chen This is needed to correctly handle BOs imported into compute VM from gfx. Both kfd and gfx should use same bo_va when map the Bos into same VM, otherwise we may trigger kernel general protection when iterate mappings from bo_va. Signed-off-by: Felix Kuehling Acked-by: Christian König Reviewed-by: Ramesh Errabolu Reviewed-By: Xiaogang Chen Tested-By: Xiaogang Chen --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 12 ++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index a15e59abe70a..c1ec93cc50ae 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -832,6 +832,7 @@ static int kfd_mem_attach(struct amdgpu_device *adev, struct kgd_mem *mem, uint64_t va = mem->va; struct kfd_mem_attachment *attachment[2] = {NULL, NULL}; struct amdgpu_bo *bo[2] = {NULL, NULL}; + struct amdgpu_bo_va *bo_va; bool same_hive = false; int i, ret; @@ -919,7 +920,13 @@ static int kfd_mem_attach(struct amdgpu_device *adev, struct kgd_mem *mem, pr_debug("Unable to reserve BO during memory attach"); goto unwind; } - attachment[i]->bo_va = amdgpu_vm_bo_add(adev, vm, bo[i]); + bo_va = amdgpu_vm_bo_find(vm, bo[i]); + if (!bo_va) + bo_va = amdgpu_vm_bo_add(adev, vm, bo[i]); + else + ++bo_va->ref_count; + attachment[i]->bo_va = bo_va; + amdgpu_bo_unreserve(bo[i]); if (unlikely(!attachment[i]->bo_va)) { ret = -ENOMEM; @@ -943,7 +950,8 @@ static int kfd_mem_attach(struct amdgpu_device *adev, struct kgd_mem *mem, continue; if (attachment[i]->bo_va) { amdgpu_bo_reserve(bo[i], true); - amdgpu_vm_bo_del(adev, attachment[i]->bo_va); + if (--attachment[i]->bo_va->ref_count == 0) + amdgpu_vm_bo_del(adev, attachment[i]->bo_va); amdgpu_bo_unreserve(bo[i]); list_del(&attachment[i]->list); } -- 2.25.1
RE: [PATCH] drm/amdgpu:Check gfx poweron when skip flush_gpu_tlb
[AMD Official Use Only - General] Hi, Can I get the RB for this patch? To fix the reset failure with following calltrace? [ 72.743001] amdgpu :03:00.0: amdgpu: [gfxhub] page fault (src_id:0 ring:160 vmid:0 pasid:0, for process pid 0 thread pid 0) [ 72.743009] [drm] ring compute_32769.2.2 was added [ 72.743024] amdgpu :03:00.0: amdgpu: in page starting at address 0x004a2000 from client 10 [ 72.743038] amdgpu :03:00.0: amdgpu: GCVM_L2_PROTECTION_FAULT_STATUS:0x00040B40 [ 72.743050] amdgpu :03:00.0: amdgpu: Faulty UTCL2 client ID: CPC (0x5) [ 72.743056] [drm] ring sdma_32769.3.3 was added [ 72.743061] amdgpu :03:00.0: amdgpu: MORE_FAULTS: 0x0 [ 72.743069] amdgpu :03:00.0: amdgpu: WALKER_ERROR: 0x0 [ 72.743077] amdgpu :03:00.0: amdgpu: PERMISSION_FAULTS: 0x4 [ 72.743086] amdgpu :03:00.0: amdgpu: MAPPING_ERROR: 0x1 [ 72.743095] amdgpu :03:00.0: amdgpu: RW: 0x1 [ 72.743105] amdgpu :03:00.0: amdgpu: [gfxhub] page fault (src_id:0 ring:144 vmid:0 pasid:0, for process pid 0 thread pid 0) [ 72.743122] amdgpu :03:00.0: amdgpu: in page starting at address 0x004a2000 from client 10 [ 72.743135] amdgpu :03:00.0: amdgpu: GCVM_L2_PROTECTION_FAULT_STATUS:0x0B21 [ 72.743145] amdgpu :03:00.0: amdgpu: Faulty UTCL2 client ID: CPC (0x5) [ 72.743155] amdgpu :03:00.0: amdgpu: MORE_FAULTS: 0x1 [ 72.743164] amdgpu :03:00.0: amdgpu: WALKER_ERROR: 0x0 [ 72.743173] amdgpu :03:00.0: amdgpu: PERMISSION_FAULTS: 0x2 [ 72.743181] amdgpu :03:00.0: amdgpu: MAPPING_ERROR: 0x1 [ 72.743189] amdgpu :03:00.0: amdgpu: RW: 0x0 Thanks, Feifei -Original Message- From: Xu, Feifei Sent: Tuesday, October 10, 2023 6:14 PM To: Koenig, Christian ; Zhang, Hawking ; Wang, Yang(Kevin) ; amd-gfx@lists.freedesktop.org Subject: RE: [PATCH] drm/amdgpu:Check gfx poweron when skip flush_gpu_tlb If the behavior is correct, this patch looks like workaround HW reset not flushed the TLB or something can be workaround by adding a gpu TLB flush. Thanks, Feifei -Original Message- From: Koenig, Christian Sent: Tuesday, October 10, 2023 5:07 PM To: Xu, Feifei ; Zhang, Hawking ; Wang, Yang(Kevin) ; amd-gfx@lists.freedesktop.org Subject: Re: [PATCH] drm/amdgpu:Check gfx poweron when skip flush_gpu_tlb Hi Feifei, yeah, that is correct behavior. The GMC callback should *not* get called during resume in a reset, because the reset needs to take care of invalidating the TLB anyway. If the later doesn't work any more we need to re-iterate the reset procedure and not mess with this here. Regards, Christian. Am 10.10.23 um 04:27 schrieb Xu, Feifei: > [AMD Official Use Only - General] > > Yes, adev->gfx.is_poweron check will be applied in gmc_v11 callback, which > will be called after the generic gmc part: amdgpu_gmc_flush_gpu_tlb() > function. > But in commit: d0c860f33553 ("drm/amdgpu: rework lock handling for flush_tlb > v2"), the flush is moved at a higher level amdgpu_gmc_flush_gpu_tlb() > function. > > Thus the gmc_v11 callback will never be called in the resume because > adev->reset_domain->sem not released and returned ahead. Adding a check of > adev->gfx.is_poweron will let GFX11 not breaking ahead, like following: > > if (!down_read_trylock(&adev->reset_domain->sem) && //--> true in > gfx11 > +!adev->gfx.is_poweron) //-->false in gfx11, and the whole if > statement will be false, not return ahead. The following gmc v11 callback > will be executed later. > > Thanks, > Feifei > > -Original Message- > From: Zhang, Hawking > Sent: Monday, October 9, 2023 4:58 PM > To: Xu, Feifei ; Wang, Yang(Kevin) > ; amd-gfx@lists.freedesktop.org > Cc: Koenig, Christian > Subject: RE: [PATCH] drm/amdgpu:Check gfx poweron when skip > flush_gpu_tlb > > [AMD Official Use Only - General] > > adev->gfx.is_poweron check should already be applied in IP specific (gmc v11) > callback. If gfx is not power on, it does nothing but just returns. I didn't > see how it helps resolve the issue if we just move the check from one > function to another. > > Regards, > Hawking > > -Original Message- > From: Xu, Feifei > Sent: Monday, October 9, 2023 09:51 > To: Wang, Yang(Kevin) ; > amd-gfx@lists.freedesktop.org > Cc: Koenig, Christian ; Zhang, Hawking > > Subject: RE: [PATCH] drm/amdgpu:Check gfx poweron when skip > flush_gpu_tlb > > [AMD Official Use Only - General] > > Hi, > >>> Based on your description, the above code should use "||" instead of >>> "&&", > && is to add more restriction here. To avoid skipping necessary TLB flush by > return. > For Asics < GFX11, !adev->gfx.is_poweron is always true (this paremeter is > intrudoced from GFX11), only depends on reset_domain->sem; For Asics = GFX11, > !adev->gfx.is_poweron might be false (which gfx might already poweron in the > reset), this will make the if () not ture, return
[PATCH] drm/amdgpu: fix software pci_unplug on some chips
From: Vitaly Prosyak When software 'pci unplug' using IGT is executed we got a sysfs directory entry is NULL for differant ras blocks like hdp, umc, etc. Before call 'sysfs_remove_file_from_group' and 'sysfs_remove_group' check that 'sd' is not NULL. [ +0.01] RIP: 0010:sysfs_remove_group+0x83/0x90 [ +0.02] Code: 31 c0 31 d2 31 f6 31 ff e9 9a a8 b4 00 4c 89 e7 e8 f2 a2 ff ff eb c2 49 8b 55 00 48 8b 33 48 c7 c7 80 65 94 82 e8 cd 82 bb ff <0f> 0b eb cc 66 0f 1f 84 00 00 00 00 00 90 90 90 90 90 90 90 90 90 [ +0.01] RSP: 0018:c90002067c90 EFLAGS: 00010246 [ +0.02] RAX: RBX: 824ea180 RCX: [ +0.01] RDX: RSI: RDI: [ +0.01] RBP: c90002067ca8 R08: R09: [ +0.01] R10: R11: R12: [ +0.01] R13: 88810a395f48 R14: 888101aab0d0 R15: [ +0.01] FS: 7f5ddaa43a00() GS:88841e80() knlGS: [ +0.02] CS: 0010 DS: ES: CR0: 80050033 [ +0.01] CR2: 7f8ffa61ba50 CR3: 000106432000 CR4: 00350ef0 [ +0.01] Call Trace: [ +0.01] [ +0.01] ? show_regs+0x72/0x90 [ +0.02] ? sysfs_remove_group+0x83/0x90 [ +0.02] ? __warn+0x8d/0x160 [ +0.01] ? sysfs_remove_group+0x83/0x90 [ +0.01] ? report_bug+0x1bb/0x1d0 [ +0.03] ? handle_bug+0x46/0x90 [ +0.01] ? exc_invalid_op+0x19/0x80 [ +0.02] ? asm_exc_invalid_op+0x1b/0x20 [ +0.03] ? sysfs_remove_group+0x83/0x90 [ +0.01] dpm_sysfs_remove+0x61/0x70 [ +0.02] device_del+0xa3/0x3d0 [ +0.02] ? ktime_get_mono_fast_ns+0x46/0xb0 [ +0.02] device_unregister+0x18/0x70 [ +0.01] i2c_del_adapter+0x26d/0x330 [ +0.02] arcturus_i2c_control_fini+0x25/0x50 [amdgpu] [ +0.000236] smu_sw_fini+0x38/0x260 [amdgpu] [ +0.000241] amdgpu_device_fini_sw+0x116/0x670 [amdgpu] [ +0.000186] ? mutex_lock+0x13/0x50 [ +0.03] amdgpu_driver_release_kms+0x16/0x40 [amdgpu] [ +0.000192] drm_minor_release+0x4f/0x80 [drm] [ +0.25] drm_release+0xfe/0x150 [drm] [ +0.27] __fput+0x9f/0x290 [ +0.02] fput+0xe/0x20 [ +0.02] task_work_run+0x61/0xa0 [ +0.02] exit_to_user_mode_prepare+0x150/0x170 [ +0.02] syscall_exit_to_user_mode+0x2a/0x50 Cc: Hawking Zhang Cc: Luben Tuikov Cc: Alex Deucher Cc: Christian Koenig Signed-off-by: Vitaly Prosyak --- drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index 5fb57419ef77..1673a10835a1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -1390,7 +1390,8 @@ static void amdgpu_ras_sysfs_remove_bad_page_node(struct amdgpu_device *adev) { struct amdgpu_ras *con = amdgpu_ras_get_context(adev); - sysfs_remove_file_from_group(&adev->dev->kobj, + if (adev->dev->kobj.sd) + sysfs_remove_file_from_group(&adev->dev->kobj, &con->badpages_attr.attr, RAS_FS_NAME); } @@ -1409,7 +1410,8 @@ static int amdgpu_ras_sysfs_remove_dev_attr_node(struct amdgpu_device *adev) .attrs = attrs, }; - sysfs_remove_group(&adev->dev->kobj, &group); + if (adev->dev->kobj.sd) + sysfs_remove_group(&adev->dev->kobj, &group); return 0; } @@ -1456,7 +1458,8 @@ int amdgpu_ras_sysfs_remove(struct amdgpu_device *adev, if (!obj || !obj->attr_inuse) return -EINVAL; - sysfs_remove_file_from_group(&adev->dev->kobj, + if (adev->dev->kobj.sd) + sysfs_remove_file_from_group(&adev->dev->kobj, &obj->sysfs_attr.attr, RAS_FS_NAME); obj->attr_inuse = 0; -- 2.25.1
RE: [PATCH] drm/amdgpu: disable GFXOFF and PG during compute for GFX9
[AMD Official Use Only - General] -Original Message- From: Alex Deucher Sent: Wednesday, October 11, 2023 10:20 PM To: Zhang, Jesse(Jie) Cc: amd-gfx@lists.freedesktop.org; Deucher, Alexander ; Yang, Philip ; Kuehling, Felix ; Zhang, Yifan Subject: Re: [PATCH] drm/amdgpu: disable GFXOFF and PG during compute for GFX9 On Wed, Oct 11, 2023 at 3:52 AM Jesse Zhang wrote: > > Temporary workaround to fix issues observed in some compute > applications when GFXOFF is enabled on GFX9. > > Signed-off-by: Jesse Zhang > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | 4 > 1 file changed, 4 insertions(+) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c > index d3805d6f..fef93d4edcbc 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c > @@ -683,12 +683,16 @@ int amdgpu_amdkfd_submit_ib(struct amdgpu_device > *adev, > > void amdgpu_amdkfd_set_compute_idle(struct amdgpu_device *adev, bool > idle) { > + enum amd_powergating_state state = idle ? AMD_PG_STATE_GATE : > + AMD_PG_STATE_UNGATE; > /* Temporary workaround to fix issues observed in some > * compute applications when GFXOFF is enabled on GFX11. > */ > if (IP_VERSION_MAJ(amdgpu_ip_version(adev, GC_HWIP, 0)) == 11) { > pr_debug("GFXOFF is %s\n", idle ? "enabled" : "disabled"); > amdgpu_gfx_off_ctrl(adev, idle); > + } else if ((IP_VERSION_MAJ(amdgpu_ip_version(adev, GC_HWIP, 0)) == 9) > && > + (adev->flags & AMD_IS_APU)) { > + > + adev->ip_blocks[AMD_IP_BLOCK_TYPE_GFX].version->funcs->set_powergati > + ng_state((void *)adev, state); Why not use amdgpu_gfx_off_ctrl(adev, idle); for consistency? [Zhang, Jesse(Jie)] Hi Alex, amdgpu_gfx_off_ctrl only disable gfxoff. It also need to disable gfx9's powergating to workaround. So use the set_powergating_state to disable gfxoff and PG. Jesse Alex > } > amdgpu_dpm_switch_power_profile(adev, > PP_SMC_POWER_PROFILE_COMPUTE, > -- > 2.25.1 >
Re: [PATCH] drm/amdgpu: fix software pci_unplug on some chips
On 2023-10-11 21:31, vitaly.pros...@amd.com wrote: > From: Vitaly Prosyak > > When software 'pci unplug' using IGT is executed we got a sysfs directory > entry is NULL for differant ras blocks like hdp, umc, etc. > Before call 'sysfs_remove_file_from_group' and 'sysfs_remove_group' > check that 'sd' is not NULL. > > [ +0.01] RIP: 0010:sysfs_remove_group+0x83/0x90 > [ +0.02] Code: 31 c0 31 d2 31 f6 31 ff e9 9a a8 b4 00 4c 89 e7 e8 f2 a2 > ff ff eb c2 49 8b 55 00 48 8b 33 48 c7 c7 80 65 94 82 e8 cd 82 bb ff <0f> 0b > eb cc 66 0f 1f 84 00 00 00 00 00 90 90 90 90 90 90 90 90 90 > [ +0.01] RSP: 0018:c90002067c90 EFLAGS: 00010246 > [ +0.02] RAX: RBX: 824ea180 RCX: > > [ +0.01] RDX: RSI: RDI: > > [ +0.01] RBP: c90002067ca8 R08: R09: > > [ +0.01] R10: R11: R12: > > [ +0.01] R13: 88810a395f48 R14: 888101aab0d0 R15: > > [ +0.01] FS: 7f5ddaa43a00() GS:88841e80() > knlGS: > [ +0.02] CS: 0010 DS: ES: CR0: 80050033 > [ +0.01] CR2: 7f8ffa61ba50 CR3: 000106432000 CR4: > 00350ef0 > [ +0.01] Call Trace: > [ +0.01] > [ +0.01] ? show_regs+0x72/0x90 > [ +0.02] ? sysfs_remove_group+0x83/0x90 > [ +0.02] ? __warn+0x8d/0x160 > [ +0.01] ? sysfs_remove_group+0x83/0x90 > [ +0.01] ? report_bug+0x1bb/0x1d0 > [ +0.03] ? handle_bug+0x46/0x90 > [ +0.01] ? exc_invalid_op+0x19/0x80 > [ +0.02] ? asm_exc_invalid_op+0x1b/0x20 > [ +0.03] ? sysfs_remove_group+0x83/0x90 > [ +0.01] dpm_sysfs_remove+0x61/0x70 > [ +0.02] device_del+0xa3/0x3d0 > [ +0.02] ? ktime_get_mono_fast_ns+0x46/0xb0 > [ +0.02] device_unregister+0x18/0x70 > [ +0.01] i2c_del_adapter+0x26d/0x330 > [ +0.02] arcturus_i2c_control_fini+0x25/0x50 [amdgpu] > [ +0.000236] smu_sw_fini+0x38/0x260 [amdgpu] > [ +0.000241] amdgpu_device_fini_sw+0x116/0x670 [amdgpu] > [ +0.000186] ? mutex_lock+0x13/0x50 > [ +0.03] amdgpu_driver_release_kms+0x16/0x40 [amdgpu] > [ +0.000192] drm_minor_release+0x4f/0x80 [drm] > [ +0.25] drm_release+0xfe/0x150 [drm] > [ +0.27] __fput+0x9f/0x290 > [ +0.02] fput+0xe/0x20 > [ +0.02] task_work_run+0x61/0xa0 > [ +0.02] exit_to_user_mode_prepare+0x150/0x170 > [ +0.02] syscall_exit_to_user_mode+0x2a/0x50 > > Cc: Hawking Zhang > Cc: Luben Tuikov > Cc: Alex Deucher > Cc: Christian Koenig > Signed-off-by: Vitaly Prosyak Reviewed-by: Luben Tuikov Regards, Luben > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 9 ++--- > 1 file changed, 6 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c > index 5fb57419ef77..1673a10835a1 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c > @@ -1390,7 +1390,8 @@ static void > amdgpu_ras_sysfs_remove_bad_page_node(struct amdgpu_device *adev) > { > struct amdgpu_ras *con = amdgpu_ras_get_context(adev); > > - sysfs_remove_file_from_group(&adev->dev->kobj, > + if (adev->dev->kobj.sd) > + sysfs_remove_file_from_group(&adev->dev->kobj, > &con->badpages_attr.attr, > RAS_FS_NAME); > } > @@ -1409,7 +1410,8 @@ static int amdgpu_ras_sysfs_remove_dev_attr_node(struct > amdgpu_device *adev) > .attrs = attrs, > }; > > - sysfs_remove_group(&adev->dev->kobj, &group); > + if (adev->dev->kobj.sd) > + sysfs_remove_group(&adev->dev->kobj, &group); > > return 0; > } > @@ -1456,7 +1458,8 @@ int amdgpu_ras_sysfs_remove(struct amdgpu_device *adev, > if (!obj || !obj->attr_inuse) > return -EINVAL; > > - sysfs_remove_file_from_group(&adev->dev->kobj, > + if (adev->dev->kobj.sd) > + sysfs_remove_file_from_group(&adev->dev->kobj, > &obj->sysfs_attr.attr, > RAS_FS_NAME); > obj->attr_inuse = 0;
RE: [PATCH 3/3] drm/amd/pm: Add P2S tables for SMU v13.0.6
[AMD Official Use Only - General] + if (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(11, 0, 6)) { Typo? 11, 0, 6 -> 13, 0, 6 Regards, Hawking -Original Message- From: Lazar, Lijo Sent: Wednesday, October 11, 2023 23:32 To: amd-gfx@lists.freedesktop.org Cc: Zhang, Hawking ; Deucher, Alexander Subject: [PATCH 3/3] drm/amd/pm: Add P2S tables for SMU v13.0.6 Add P2S table load support on SMU v13.0.6 ASICs. Signed-off-by: Lijo Lazar --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 7 ++ .../drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c | 71 +++ 2 files changed, 78 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index c41bd07f3f98..49e914ee6efe 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -2516,6 +2516,13 @@ static int psp_load_p2s_table(struct psp_context *psp) if (adev->in_runpm && (adev->pm.rpm_mode == AMDGPU_RUNPM_BACO)) return 0; + if (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(11, 0, 6)) { + uint32_t supp_vers = adev->flags & AMD_IS_APU ? 0x0036013D : + 0x0036003C; + if (psp->sos.fw_version < supp_vers) + return 0; + } + if (!ucode->fw || amdgpu_sriov_vf(psp->adev)) return 0; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c index 8220bdcbd927..a295403e2a09 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c @@ -65,6 +65,8 @@ #undef pr_info #undef pr_debug +MODULE_FIRMWARE("amdgpu/smu_13_0_6.bin"); + #define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c)) #define SMU_13_0_6_FEA_MAP(smu_feature, smu_13_0_6_feature) \ @@ -123,6 +125,9 @@ struct mca_ras_info { enum amdgpu_mca_error_type type, int idx, uint32_t *count); }; +#define P2S_TABLE_ID_A 0x50325341 +#define P2S_TABLE_ID_X 0x50325358 + static const struct cmn2asic_msg_mapping smu_v13_0_6_message_map[SMU_MSG_MAX_COUNT] = { MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 0), MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1), @@ -256,6 +261,70 @@ struct smu_v13_0_6_dpm_map { uint32_t *freq_table; }; +static int smu_v13_0_6_init_microcode(struct smu_context *smu) { + const struct smc_firmware_header_v2_1 *v2_1; + const struct smc_firmware_header_v1_0 *hdr; + struct amdgpu_firmware_info *ucode = NULL; + struct smc_soft_pptable_entry *entries; + struct amdgpu_device *adev = smu->adev; + uint32_t p2s_table_id = P2S_TABLE_ID_A; + int ret = 0, i, p2stable_count; + char ucode_prefix[30]; + char fw_name[30]; + + /* No need to load P2S tables in IOV mode */ + if (amdgpu_sriov_vf(adev)) + return 0; + + if (!(adev->flags & AMD_IS_APU)) + p2s_table_id = P2S_TABLE_ID_X; + + amdgpu_ucode_ip_version_decode(adev, MP1_HWIP, ucode_prefix, + sizeof(ucode_prefix)); + + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", ucode_prefix); + + ret = amdgpu_ucode_request(adev, &adev->pm.fw, fw_name); + if (ret) + goto out; + + hdr = (const struct smc_firmware_header_v1_0 *)adev->pm.fw->data; + amdgpu_ucode_print_smc_hdr(&hdr->header); + + /* SMU v13.0.6 binary file doesn't carry pptables, instead the entries +* are used to carry p2s tables. +*/ + v2_1 = (const struct smc_firmware_header_v2_1 *)adev->pm.fw->data; + entries = (struct smc_soft_pptable_entry + *)((uint8_t *)v2_1 + + le32_to_cpu(v2_1->pptable_entry_offset)); + p2stable_count = le32_to_cpu(v2_1->pptable_count); + for (i = 0; i < p2stable_count; i++) { + if (le32_to_cpu(entries[i].id) == p2s_table_id) { + smu->pptable_firmware.data = + ((uint8_t *)v2_1 + +le32_to_cpu(entries[i].ppt_offset_bytes)); + smu->pptable_firmware.size = + le32_to_cpu(entries[i].ppt_size_bytes); + break; + } + } + + if (smu->pptable_firmware.data && smu->pptable_firmware.size) { + ucode = &adev->firmware.ucode[AMDGPU_UCODE_ID_P2S_TABLE]; + ucode->ucode_id = AMDGPU_UCODE_ID_P2S_TABLE; + ucode->fw = &smu->pptable_firmware; + adev->firmware.fw_size += ALIGN(ucode->fw->size, PAGE_SIZE); + } + + return 0; +out: + amdgpu_ucode_rele
[pull] amdgpu drm-fixes-6.6
Hi Dave, Daniel, Fixes for 6.6. The following changes since commit 94f6f0550c625fab1f373bb86a6669b45e9748b3: Linux 6.6-rc5 (2023-10-08 13:49:43 -0700) are available in the Git repository at: https://gitlab.freedesktop.org/agd5f/linux.git tags/amd-drm-fixes-6.6-2023-10-11 for you to fetch changes up to 3806a8c64794661b15ff5ed28180ff9a5f79fce8: drm/amdgpu: fix SI failure due to doorbells allocation (2023-10-09 17:59:29 -0400) amd-drm-fixes-6.6-2023-10-11: amdgpu: - Seemless boot fix - Fix TTM BO resource check - SI fix for doorbell handling Christian König (1): drm/amdgpu: add missing NULL check Daniel Miess (1): drm/amd/display: Don't set dpms_off for seamless boot Icenowy Zheng (1): drm/amdgpu: fix SI failure due to doorbells allocation drivers/gpu/drm/amd/amdgpu/amdgpu_doorbell_mgr.c | 4 drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | 2 +- drivers/gpu/drm/amd/display/dc/core/dc.c | 3 +++ 3 files changed, 8 insertions(+), 1 deletion(-)
Re: [PATCH 3/3] drm/amd/pm: Add P2S tables for SMU v13.0.6
On 10/12/2023 7:43 AM, Zhang, Hawking wrote: [AMD Official Use Only - General] + if (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(11, 0, 6)) { Typo? 11, 0, 6 -> 13, 0, 6 Thanks for the catch. Will send a v2. Thanks, Lijo Regards, Hawking -Original Message- From: Lazar, Lijo Sent: Wednesday, October 11, 2023 23:32 To: amd-gfx@lists.freedesktop.org Cc: Zhang, Hawking ; Deucher, Alexander Subject: [PATCH 3/3] drm/amd/pm: Add P2S tables for SMU v13.0.6 Add P2S table load support on SMU v13.0.6 ASICs. Signed-off-by: Lijo Lazar --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 7 ++ .../drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c | 71 +++ 2 files changed, 78 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index c41bd07f3f98..49e914ee6efe 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -2516,6 +2516,13 @@ static int psp_load_p2s_table(struct psp_context *psp) if (adev->in_runpm && (adev->pm.rpm_mode == AMDGPU_RUNPM_BACO)) return 0; + if (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(11, 0, 6)) { + uint32_t supp_vers = adev->flags & AMD_IS_APU ? 0x0036013D : + 0x0036003C; + if (psp->sos.fw_version < supp_vers) + return 0; + } + if (!ucode->fw || amdgpu_sriov_vf(psp->adev)) return 0; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c index 8220bdcbd927..a295403e2a09 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c @@ -65,6 +65,8 @@ #undef pr_info #undef pr_debug +MODULE_FIRMWARE("amdgpu/smu_13_0_6.bin"); + #define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c)) #define SMU_13_0_6_FEA_MAP(smu_feature, smu_13_0_6_feature) \ @@ -123,6 +125,9 @@ struct mca_ras_info { enum amdgpu_mca_error_type type, int idx, uint32_t *count); }; +#define P2S_TABLE_ID_A 0x50325341 +#define P2S_TABLE_ID_X 0x50325358 + static const struct cmn2asic_msg_mapping smu_v13_0_6_message_map[SMU_MSG_MAX_COUNT] = { MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 0), MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1), @@ -256,6 +261,70 @@ struct smu_v13_0_6_dpm_map { uint32_t *freq_table; }; +static int smu_v13_0_6_init_microcode(struct smu_context *smu) { + const struct smc_firmware_header_v2_1 *v2_1; + const struct smc_firmware_header_v1_0 *hdr; + struct amdgpu_firmware_info *ucode = NULL; + struct smc_soft_pptable_entry *entries; + struct amdgpu_device *adev = smu->adev; + uint32_t p2s_table_id = P2S_TABLE_ID_A; + int ret = 0, i, p2stable_count; + char ucode_prefix[30]; + char fw_name[30]; + + /* No need to load P2S tables in IOV mode */ + if (amdgpu_sriov_vf(adev)) + return 0; + + if (!(adev->flags & AMD_IS_APU)) + p2s_table_id = P2S_TABLE_ID_X; + + amdgpu_ucode_ip_version_decode(adev, MP1_HWIP, ucode_prefix, + sizeof(ucode_prefix)); + + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", ucode_prefix); + + ret = amdgpu_ucode_request(adev, &adev->pm.fw, fw_name); + if (ret) + goto out; + + hdr = (const struct smc_firmware_header_v1_0 *)adev->pm.fw->data; + amdgpu_ucode_print_smc_hdr(&hdr->header); + + /* SMU v13.0.6 binary file doesn't carry pptables, instead the entries +* are used to carry p2s tables. +*/ + v2_1 = (const struct smc_firmware_header_v2_1 *)adev->pm.fw->data; + entries = (struct smc_soft_pptable_entry + *)((uint8_t *)v2_1 + + le32_to_cpu(v2_1->pptable_entry_offset)); + p2stable_count = le32_to_cpu(v2_1->pptable_count); + for (i = 0; i < p2stable_count; i++) { + if (le32_to_cpu(entries[i].id) == p2s_table_id) { + smu->pptable_firmware.data = + ((uint8_t *)v2_1 + +le32_to_cpu(entries[i].ppt_offset_bytes)); + smu->pptable_firmware.size = + le32_to_cpu(entries[i].ppt_size_bytes); + break; + } + } + + if (smu->pptable_firmware.data && smu->pptable_firmware.size) { + ucode = &adev->firmware.ucode[AMDGPU_UCODE_ID_P2S_TABLE]; + ucode->ucode_id = AMDGPU_UCODE_ID_P2S_TABLE; + ucode->fw = &smu->pptable_firmware; +
[PATCH v2 1/3] drm/amdgpu: Update PSP interface header
Adds FW id for P2S table. Signed-off-by: Lijo Lazar --- drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h b/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h index dfd60db97012..4bb5e10217bb 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h +++ b/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h @@ -296,6 +296,7 @@ enum psp_gfx_fw_type { GFX_FW_TYPE_VPEC_FW1= 100, /* VPEC FW1 To Save VPE */ GFX_FW_TYPE_VPEC_FW2= 101, /* VPEC FW2 To Save VPE */ GFX_FW_TYPE_VPE = 102, + GFX_FW_TYPE_P2S_TABLE = 129, GFX_FW_TYPE_MAX }; -- 2.25.1
[PATCH v2 2/3] drm/amdgpu: Add support to load P2S tables
Add support to load P2S tables through PSP. Signed-off-by: Lijo Lazar --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 27 +++ drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | 6 + drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h | 1 + 3 files changed, 34 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 72ee66db182c..c41bd07f3f98 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -2412,6 +2412,9 @@ static int psp_get_fw_type(struct amdgpu_firmware_info *ucode, case AMDGPU_UCODE_ID_UMSCH_MM_CMD_BUFFER: *type = GFX_FW_TYPE_UMSCH_CMD_BUFFER; break; + case AMDGPU_UCODE_ID_P2S_TABLE: + *type = GFX_FW_TYPE_P2S_TABLE; + break; case AMDGPU_UCODE_ID_MAXIMUM: default: return -EINVAL; @@ -2503,6 +2506,24 @@ int psp_execute_ip_fw_load(struct psp_context *psp, return ret; } +static int psp_load_p2s_table(struct psp_context *psp) +{ + int ret; + struct amdgpu_device *adev = psp->adev; + struct amdgpu_firmware_info *ucode = + &adev->firmware.ucode[AMDGPU_UCODE_ID_P2S_TABLE]; + + if (adev->in_runpm && (adev->pm.rpm_mode == AMDGPU_RUNPM_BACO)) + return 0; + + if (!ucode->fw || amdgpu_sriov_vf(psp->adev)) + return 0; + + ret = psp_execute_ip_fw_load(psp, ucode); + + return ret; +} + static int psp_load_smu_fw(struct psp_context *psp) { int ret; @@ -2543,6 +2564,9 @@ static bool fw_load_skip_check(struct psp_context *psp, if (!ucode->fw || !ucode->ucode_size) return true; + if (ucode->ucode_id == AMDGPU_UCODE_ID_P2S_TABLE) + return true; + if (ucode->ucode_id == AMDGPU_UCODE_ID_SMC && (psp_smu_reload_quirk(psp) || psp->autoload_supported || @@ -2591,6 +2615,9 @@ static int psp_load_non_psp_fw(struct psp_context *psp) return ret; } + /* Load P2S table first if it's available */ + psp_load_p2s_table(psp); + for (i = 0; i < adev->firmware.max_ucodes; i++) { ucode = &adev->firmware.ucode[i]; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c index 771ef8017a98..606406c88677 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c @@ -642,6 +642,8 @@ const char *amdgpu_ucode_name(enum AMDGPU_UCODE_ID ucode_id) return "SMC"; case AMDGPU_UCODE_ID_PPTABLE: return "PPTABLE"; + case AMDGPU_UCODE_ID_P2S_TABLE: + return "P2STABLE"; case AMDGPU_UCODE_ID_UVD: return "UVD"; case AMDGPU_UCODE_ID_UVD1: @@ -922,6 +924,10 @@ static int amdgpu_ucode_init_single_fw(struct amdgpu_device *adev, ucode->ucode_size = ucode->fw->size; ucode_addr = (u8 *)ucode->fw->data; break; + case AMDGPU_UCODE_ID_P2S_TABLE: + ucode->ucode_size = ucode->fw->size; + ucode_addr = (u8 *)ucode->fw->data; + break; case AMDGPU_UCODE_ID_IMU_I: ucode->ucode_size = le32_to_cpu(imu_hdr->imu_iram_ucode_size_bytes); ucode_addr = (u8 *)ucode->fw->data + diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h index ae5fa61d2890..4244a13f9f22 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h @@ -510,6 +510,7 @@ enum AMDGPU_UCODE_ID { AMDGPU_UCODE_ID_UMSCH_MM_UCODE, AMDGPU_UCODE_ID_UMSCH_MM_DATA, AMDGPU_UCODE_ID_UMSCH_MM_CMD_BUFFER, + AMDGPU_UCODE_ID_P2S_TABLE, AMDGPU_UCODE_ID_MAXIMUM, }; -- 2.25.1
[PATCH v2 3/3] drm/amd/pm: Add P2S tables for SMU v13.0.6
Add P2S table load support on SMU v13.0.6 ASICs. Signed-off-by: Lijo Lazar --- v2: Fixed MP0 IP version check (Hawking) drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 7 ++ .../drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c | 71 +++ 2 files changed, 78 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index c41bd07f3f98..7158d478eeea 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -2516,6 +2516,13 @@ static int psp_load_p2s_table(struct psp_context *psp) if (adev->in_runpm && (adev->pm.rpm_mode == AMDGPU_RUNPM_BACO)) return 0; + if (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 6)) { + uint32_t supp_vers = adev->flags & AMD_IS_APU ? 0x0036013D : + 0x0036003C; + if (psp->sos.fw_version < supp_vers) + return 0; + } + if (!ucode->fw || amdgpu_sriov_vf(psp->adev)) return 0; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c index 8220bdcbd927..d29740bcdc8f 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c @@ -65,6 +65,8 @@ #undef pr_info #undef pr_debug +MODULE_FIRMWARE("amdgpu/smu_13_0_6.bin"); + #define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c)) #define SMU_13_0_6_FEA_MAP(smu_feature, smu_13_0_6_feature) \ @@ -123,6 +125,9 @@ struct mca_ras_info { enum amdgpu_mca_error_type type, int idx, uint32_t *count); }; +#define P2S_TABLE_ID_A 0x50325341 +#define P2S_TABLE_ID_X 0x50325358 + static const struct cmn2asic_msg_mapping smu_v13_0_6_message_map[SMU_MSG_MAX_COUNT] = { MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 0), MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1), @@ -256,6 +261,70 @@ struct smu_v13_0_6_dpm_map { uint32_t *freq_table; }; +static int smu_v13_0_6_init_microcode(struct smu_context *smu) +{ + const struct smc_firmware_header_v2_1 *v2_1; + const struct common_firmware_header *hdr; + struct amdgpu_firmware_info *ucode = NULL; + struct smc_soft_pptable_entry *entries; + struct amdgpu_device *adev = smu->adev; + uint32_t p2s_table_id = P2S_TABLE_ID_A; + int ret = 0, i, p2stable_count; + char ucode_prefix[30]; + char fw_name[30]; + + /* No need to load P2S tables in IOV mode */ + if (amdgpu_sriov_vf(adev)) + return 0; + + if (!(adev->flags & AMD_IS_APU)) + p2s_table_id = P2S_TABLE_ID_X; + + amdgpu_ucode_ip_version_decode(adev, MP1_HWIP, ucode_prefix, + sizeof(ucode_prefix)); + + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", ucode_prefix); + + ret = amdgpu_ucode_request(adev, &adev->pm.fw, fw_name); + if (ret) + goto out; + + hdr = (const struct common_firmware_header *)adev->pm.fw->data; + amdgpu_ucode_print_smc_hdr(hdr); + + /* SMU v13.0.6 binary file doesn't carry pptables, instead the entries +* are used to carry p2s tables. +*/ + v2_1 = (const struct smc_firmware_header_v2_1 *)adev->pm.fw->data; + entries = (struct smc_soft_pptable_entry + *)((uint8_t *)v2_1 + + le32_to_cpu(v2_1->pptable_entry_offset)); + p2stable_count = le32_to_cpu(v2_1->pptable_count); + for (i = 0; i < p2stable_count; i++) { + if (le32_to_cpu(entries[i].id) == p2s_table_id) { + smu->pptable_firmware.data = + ((uint8_t *)v2_1 + +le32_to_cpu(entries[i].ppt_offset_bytes)); + smu->pptable_firmware.size = + le32_to_cpu(entries[i].ppt_size_bytes); + break; + } + } + + if (smu->pptable_firmware.data && smu->pptable_firmware.size) { + ucode = &adev->firmware.ucode[AMDGPU_UCODE_ID_P2S_TABLE]; + ucode->ucode_id = AMDGPU_UCODE_ID_P2S_TABLE; + ucode->fw = &smu->pptable_firmware; + adev->firmware.fw_size += ALIGN(ucode->fw->size, PAGE_SIZE); + } + + return 0; +out: + amdgpu_ucode_release(&adev->pm.fw); + + return ret; +} + static int smu_v13_0_6_tables_init(struct smu_context *smu) { struct smu_table_context *smu_table = &smu->smu_table; @@ -2787,6 +2856,8 @@ static const struct pptable_funcs smu_v13_0_6_ppt_funcs = { .get_power_limit = smu_v13_0_6_get_power_limit, .is_dpm_running = smu_v13_0_6
RE: [PATCH v2 1/3] drm/amdgpu: Update PSP interface header
[AMD Official Use Only - General] Series is. Reviewed-by: Yang Wang Best Regards, Kevin -Original Message- From: amd-gfx On Behalf Of Lijo Lazar Sent: Thursday, October 12, 2023 12:58 PM To: amd-gfx@lists.freedesktop.org Cc: Deucher, Alexander ; Zhang, Hawking Subject: [PATCH v2 1/3] drm/amdgpu: Update PSP interface header Adds FW id for P2S table. Signed-off-by: Lijo Lazar --- drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h b/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h index dfd60db97012..4bb5e10217bb 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h +++ b/drivers/gpu/drm/amd/amdgpu/psp_gfx_if.h @@ -296,6 +296,7 @@ enum psp_gfx_fw_type { GFX_FW_TYPE_VPEC_FW1= 100, /* VPEC FW1 To Save VPE */ GFX_FW_TYPE_VPEC_FW2= 101, /* VPEC FW2 To Save VPE */ GFX_FW_TYPE_VPE = 102, + GFX_FW_TYPE_P2S_TABLE = 129, GFX_FW_TYPE_MAX }; -- 2.25.1
[PATCH] drm/amdgpu: Restrict PSP OS version read to PF
Only physical function can read PSP OS version register on PSP v13.x SOCs. Signed-off-by: Lijo Lazar --- drivers/gpu/drm/amd/amdgpu/psp_v13_0.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c index 1997260a8156..96ea64e1bf37 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c @@ -280,6 +280,9 @@ static inline void psp_v13_0_init_sos_version(struct psp_context *psp) { struct amdgpu_device *adev = psp->adev; + if (amdgpu_sriov_vf(adev)) + return; + psp->sos.fw_version = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_58); } -- 2.25.1
RE: [PATCH] drm/amdgpu: Restrict PSP OS version read to PF
[AMD Official Use Only - General] Reviewed-by: Hawking Zhang Regards, Hawking -Original Message- From: Lazar, Lijo Sent: Thursday, October 12, 2023 13:51 To: amd-gfx@lists.freedesktop.org Cc: Zhang, Hawking ; Deucher, Alexander Subject: [PATCH] drm/amdgpu: Restrict PSP OS version read to PF Only physical function can read PSP OS version register on PSP v13.x SOCs. Signed-off-by: Lijo Lazar --- drivers/gpu/drm/amd/amdgpu/psp_v13_0.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c index 1997260a8156..96ea64e1bf37 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c @@ -280,6 +280,9 @@ static inline void psp_v13_0_init_sos_version(struct psp_context *psp) { struct amdgpu_device *adev = psp->adev; + if (amdgpu_sriov_vf(adev)) + return; + psp->sos.fw_version = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_58); } -- 2.25.1
RE: [PATCH] drm/amdgpu: Restrict PSP OS version read to PF
[AMD Official Use Only - General] Please ignore this patch as tOS is not loaded on VF and hence the path is not taken. Thanks, Lijo -Original Message- From: amd-gfx On Behalf Of Lijo Lazar Sent: Thursday, October 12, 2023 11:21 AM To: amd-gfx@lists.freedesktop.org Cc: Deucher, Alexander ; Zhang, Hawking Subject: [PATCH] drm/amdgpu: Restrict PSP OS version read to PF Only physical function can read PSP OS version register on PSP v13.x SOCs. Signed-off-by: Lijo Lazar --- drivers/gpu/drm/amd/amdgpu/psp_v13_0.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c index 1997260a8156..96ea64e1bf37 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c @@ -280,6 +280,9 @@ static inline void psp_v13_0_init_sos_version(struct psp_context *psp) { struct amdgpu_device *adev = psp->adev; + if (amdgpu_sriov_vf(adev)) + return; + psp->sos.fw_version = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_58); } -- 2.25.1
RE: [PATCH v2 3/3] drm/amd/pm: Add P2S tables for SMU v13.0.6
[AMD Official Use Only - General] Series is Reviewed-by: Hawking Zhang Regards, Hawking -Original Message- From: Lazar, Lijo Sent: Thursday, October 12, 2023 12:58 To: amd-gfx@lists.freedesktop.org Cc: Zhang, Hawking ; Deucher, Alexander Subject: [PATCH v2 3/3] drm/amd/pm: Add P2S tables for SMU v13.0.6 Add P2S table load support on SMU v13.0.6 ASICs. Signed-off-by: Lijo Lazar --- v2: Fixed MP0 IP version check (Hawking) drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 7 ++ .../drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c | 71 +++ 2 files changed, 78 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index c41bd07f3f98..7158d478eeea 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -2516,6 +2516,13 @@ static int psp_load_p2s_table(struct psp_context *psp) if (adev->in_runpm && (adev->pm.rpm_mode == AMDGPU_RUNPM_BACO)) return 0; + if (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 6)) { + uint32_t supp_vers = adev->flags & AMD_IS_APU ? 0x0036013D : + 0x0036003C; + if (psp->sos.fw_version < supp_vers) + return 0; + } + if (!ucode->fw || amdgpu_sriov_vf(psp->adev)) return 0; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c index 8220bdcbd927..d29740bcdc8f 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c @@ -65,6 +65,8 @@ #undef pr_info #undef pr_debug +MODULE_FIRMWARE("amdgpu/smu_13_0_6.bin"); + #define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c)) #define SMU_13_0_6_FEA_MAP(smu_feature, smu_13_0_6_feature) \ @@ -123,6 +125,9 @@ struct mca_ras_info { enum amdgpu_mca_error_type type, int idx, uint32_t *count); }; +#define P2S_TABLE_ID_A 0x50325341 +#define P2S_TABLE_ID_X 0x50325358 + static const struct cmn2asic_msg_mapping smu_v13_0_6_message_map[SMU_MSG_MAX_COUNT] = { MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 0), MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1), @@ -256,6 +261,70 @@ struct smu_v13_0_6_dpm_map { uint32_t *freq_table; }; +static int smu_v13_0_6_init_microcode(struct smu_context *smu) { + const struct smc_firmware_header_v2_1 *v2_1; + const struct common_firmware_header *hdr; + struct amdgpu_firmware_info *ucode = NULL; + struct smc_soft_pptable_entry *entries; + struct amdgpu_device *adev = smu->adev; + uint32_t p2s_table_id = P2S_TABLE_ID_A; + int ret = 0, i, p2stable_count; + char ucode_prefix[30]; + char fw_name[30]; + + /* No need to load P2S tables in IOV mode */ + if (amdgpu_sriov_vf(adev)) + return 0; + + if (!(adev->flags & AMD_IS_APU)) + p2s_table_id = P2S_TABLE_ID_X; + + amdgpu_ucode_ip_version_decode(adev, MP1_HWIP, ucode_prefix, + sizeof(ucode_prefix)); + + snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", ucode_prefix); + + ret = amdgpu_ucode_request(adev, &adev->pm.fw, fw_name); + if (ret) + goto out; + + hdr = (const struct common_firmware_header *)adev->pm.fw->data; + amdgpu_ucode_print_smc_hdr(hdr); + + /* SMU v13.0.6 binary file doesn't carry pptables, instead the entries +* are used to carry p2s tables. +*/ + v2_1 = (const struct smc_firmware_header_v2_1 *)adev->pm.fw->data; + entries = (struct smc_soft_pptable_entry + *)((uint8_t *)v2_1 + + le32_to_cpu(v2_1->pptable_entry_offset)); + p2stable_count = le32_to_cpu(v2_1->pptable_count); + for (i = 0; i < p2stable_count; i++) { + if (le32_to_cpu(entries[i].id) == p2s_table_id) { + smu->pptable_firmware.data = + ((uint8_t *)v2_1 + +le32_to_cpu(entries[i].ppt_offset_bytes)); + smu->pptable_firmware.size = + le32_to_cpu(entries[i].ppt_size_bytes); + break; + } + } + + if (smu->pptable_firmware.data && smu->pptable_firmware.size) { + ucode = &adev->firmware.ucode[AMDGPU_UCODE_ID_P2S_TABLE]; + ucode->ucode_id = AMDGPU_UCODE_ID_P2S_TABLE; + ucode->fw = &smu->pptable_firmware; + adev->firmware.fw_size += ALIGN(ucode->fw->size, PAGE_SIZE); + } + + return 0; +out: + amdgpu_ucode_release(&adev->pm.fw); + + return