Re: [PATCH 3/8] drm/amdgpu:Add DPG support flag
On 2018-09-26 04:02 AM, Christian König wrote: Am 25.09.2018 um 21:55 schrieb James Zhu: Add DPG support flag for VCN DPG mode. Signed-off-by: James Zhu --- drivers/gpu/drm/amd/include/amd_shared.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/amd/include/amd_shared.h b/drivers/gpu/drm/amd/include/amd_shared.h index 86b167e..2f6bdf1 100644 --- a/drivers/gpu/drm/amd/include/amd_shared.h +++ b/drivers/gpu/drm/amd/include/amd_shared.h @@ -110,6 +110,8 @@ enum amd_powergating_state { #define AMD_PG_SUPPORT_MMHUB (1 << 13) #define AMD_PG_SUPPORT_VCN (1 << 14) Looks like you added an extra empty line between AMD_PG_SUPPORT_VCN and the new entry, was that intentional? Already fixed with Alex's comments. James Apart from that the patches look good to me, but can't judge if that is really correct. Acked-by: Christian König for the series. Regards, Christian. +#define AMD_PG_SUPPORT_DPG (1 << 15) + enum PP_FEATURE_MASK { PP_SCLK_DPM_MASK = 0x1, PP_MCLK_DPM_MASK = 0x2, ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
RE: [PATCH v2 1/8] drm/amdgpu:Use register UVD_SCRATCH9 for VCN ring/ib test
> -Original Message- > From: amd-gfx [mailto:amd-gfx-boun...@lists.freedesktop.org] On Behalf > Of James Zhu > Sent: Wednesday, September 26, 2018 7:03 AM > To: amd-gfx@lists.freedesktop.org > Cc: Zhu, James > Subject: [PATCH v2 1/8] drm/amdgpu:Use register UVD_SCRATCH9 for VCN > ring/ib test > > Use register UVD_SCRATCH9 for VCN ring/ib test. Since those registers can't > be directly accessed under DPG(Dynamic Power Gate) mode. > > Signed-off-by: James Zhu > Reviewed-by: Alex Deucher Thanks James. We will give a try on Picasso. Feel free to add my RB for the series: Reviewed-by: Huang Rui > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 16 > 1 file changed, 8 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c > index a73674f..27262a8 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c > @@ -264,7 +264,7 @@ int amdgpu_vcn_dec_ring_test_ring(struct > amdgpu_ring *ring) > unsigned i; > int r; > > - WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), > 0xCAFEDEAD); > + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), > 0xCAFEDEAD); > r = amdgpu_ring_alloc(ring, 3); > if (r) { > DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n", > @@ -272,11 +272,11 @@ int amdgpu_vcn_dec_ring_test_ring(struct > amdgpu_ring *ring) > return r; > } > amdgpu_ring_write(ring, > - PACKET0(SOC15_REG_OFFSET(UVD, 0, > mmUVD_CONTEXT_ID), 0)); > + PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), > 0)); > amdgpu_ring_write(ring, 0xDEADBEEF); > amdgpu_ring_commit(ring); > for (i = 0; i < adev->usec_timeout; i++) { > - tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, > mmUVD_CONTEXT_ID)); > + tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, > mmUVD_SCRATCH9)); > if (tmp == 0xDEADBEEF) > break; > DRM_UDELAY(1); > @@ -616,7 +616,7 @@ int amdgpu_vcn_jpeg_ring_test_ring(struct > amdgpu_ring *ring) > unsigned i; > int r; > > - WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), > 0xCAFEDEAD); > + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), > 0xCAFEDEAD); > r = amdgpu_ring_alloc(ring, 3); > > if (r) { > @@ -626,12 +626,12 @@ int amdgpu_vcn_jpeg_ring_test_ring(struct > amdgpu_ring *ring) > } > > amdgpu_ring_write(ring, > - PACKETJ(SOC15_REG_OFFSET(UVD, 0, > mmUVD_CONTEXT_ID), 0, 0, 0)); > + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), > 0, 0, 0)); > amdgpu_ring_write(ring, 0xDEADBEEF); > amdgpu_ring_commit(ring); > > for (i = 0; i < adev->usec_timeout; i++) { > - tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, > mmUVD_CONTEXT_ID)); > + tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, > mmUVD_SCRATCH9)); > if (tmp == 0xDEADBEEF) > break; > DRM_UDELAY(1); > @@ -665,7 +665,7 @@ static int amdgpu_vcn_jpeg_set_reg(struct > amdgpu_ring *ring, uint32_t handle, > > ib = >ibs[0]; > > - ib->ptr[0] = PACKETJ(SOC15_REG_OFFSET(UVD, 0, > mmUVD_JPEG_PITCH), 0, 0, PACKETJ_TYPE0); > + ib->ptr[0] = PACKETJ(SOC15_REG_OFFSET(UVD, 0, > mmUVD_SCRATCH9), 0, 0, > +PACKETJ_TYPE0); > ib->ptr[1] = 0xDEADBEEF; > for (i = 2; i < 16; i += 2) { > ib->ptr[i] = PACKETJ(0, 0, 0, PACKETJ_TYPE6); @@ -714,7 > +714,7 @@ int amdgpu_vcn_jpeg_ring_test_ib(struct amdgpu_ring *ring, > long timeout) > r = 0; > > for (i = 0; i < adev->usec_timeout; i++) { > - tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, > mmUVD_JPEG_PITCH)); > + tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, > mmUVD_SCRATCH9)); > if (tmp == 0xDEADBEEF) > break; > DRM_UDELAY(1); > -- > 2.7.4 > > ___ > amd-gfx mailing list > amd-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH] drm/amdgpu: Fix copy error in uvd_v6/7_0.c
Am 26.09.2018 um 14:41 schrieb Rex Zhu: Signed-off-by: Rex Zhu Actually that code can just be removed because uvd_*_enc_get_destroy_msg is only called with direct=true. Christian. --- drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 8ef4a53..2ceab76 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -313,7 +313,7 @@ static int uvd_v6_0_enc_get_destroy_msg(struct amdgpu_ring *ring, if (direct) r = amdgpu_job_submit_direct(job, ring, ); else - r = amdgpu_job_submit(job, >adev->vce.entity, + r = amdgpu_job_submit(job, >adev->uvd.entity, AMDGPU_FENCE_OWNER_UNDEFINED, ); if (r) goto err; diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c index a289f6a..31a9665 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c @@ -320,7 +320,7 @@ int uvd_v7_0_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, if (direct) r = amdgpu_job_submit_direct(job, ring, ); else - r = amdgpu_job_submit(job, >adev->vce.entity, + r = amdgpu_job_submit(job, >adev->uvd.entity, AMDGPU_FENCE_OWNER_UNDEFINED, ); if (r) goto err; ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: Fix copy error in uvd_v6/7_0.c
Signed-off-by: Rex Zhu --- drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 8ef4a53..2ceab76 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -313,7 +313,7 @@ static int uvd_v6_0_enc_get_destroy_msg(struct amdgpu_ring *ring, if (direct) r = amdgpu_job_submit_direct(job, ring, ); else - r = amdgpu_job_submit(job, >adev->vce.entity, + r = amdgpu_job_submit(job, >adev->uvd.entity, AMDGPU_FENCE_OWNER_UNDEFINED, ); if (r) goto err; diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c index a289f6a..31a9665 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c @@ -320,7 +320,7 @@ int uvd_v7_0_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, if (direct) r = amdgpu_job_submit_direct(job, ring, ); else - r = amdgpu_job_submit(job, >adev->vce.entity, + r = amdgpu_job_submit(job, >adev->uvd.entity, AMDGPU_FENCE_OWNER_UNDEFINED, ); if (r) goto err; -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 7/7] drm/amdgpu: Change the gfx/sdma init/fini sequence
initialize gfx/sdma before dpm features enabled. and disable dpm features before gfx/sdma fini. Acked-by: Alex Deucher Signed-off-by: Rex Zhu --- drivers/gpu/drm/amd/amdgpu/cik.c | 17 + drivers/gpu/drm/amd/amdgpu/si.c| 13 +++-- drivers/gpu/drm/amd/amdgpu/soc15.c | 8 drivers/gpu/drm/amd/amdgpu/vi.c| 24 4 files changed, 32 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c index 78ab939..f41f5f5 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik.c +++ b/drivers/gpu/drm/amd/amdgpu/cik.c @@ -2002,6 +2002,8 @@ int cik_set_ip_blocks(struct amdgpu_device *adev) amdgpu_device_ip_block_add(adev, _common_ip_block); amdgpu_device_ip_block_add(adev, _v7_0_ip_block); amdgpu_device_ip_block_add(adev, _ih_ip_block); + amdgpu_device_ip_block_add(adev, _v7_2_ip_block); + amdgpu_device_ip_block_add(adev, _sdma_ip_block); if (amdgpu_dpm == -1) amdgpu_device_ip_block_add(adev, _smu_ip_block); else @@ -2014,8 +2016,6 @@ int cik_set_ip_blocks(struct amdgpu_device *adev) #endif else amdgpu_device_ip_block_add(adev, _v8_2_ip_block); - amdgpu_device_ip_block_add(adev, _v7_2_ip_block); - amdgpu_device_ip_block_add(adev, _sdma_ip_block); amdgpu_device_ip_block_add(adev, _v4_2_ip_block); amdgpu_device_ip_block_add(adev, _v2_0_ip_block); break; @@ -2023,6 +2023,8 @@ int cik_set_ip_blocks(struct amdgpu_device *adev) amdgpu_device_ip_block_add(adev, _common_ip_block); amdgpu_device_ip_block_add(adev, _v7_0_ip_block); amdgpu_device_ip_block_add(adev, _ih_ip_block); + amdgpu_device_ip_block_add(adev, _v7_3_ip_block); + amdgpu_device_ip_block_add(adev, _sdma_ip_block); if (amdgpu_dpm == -1) amdgpu_device_ip_block_add(adev, _smu_ip_block); else @@ -2035,8 +2037,6 @@ int cik_set_ip_blocks(struct amdgpu_device *adev) #endif else amdgpu_device_ip_block_add(adev, _v8_5_ip_block); - amdgpu_device_ip_block_add(adev, _v7_3_ip_block); - amdgpu_device_ip_block_add(adev, _sdma_ip_block); amdgpu_device_ip_block_add(adev, _v4_2_ip_block); amdgpu_device_ip_block_add(adev, _v2_0_ip_block); break; @@ -2044,6 +2044,8 @@ int cik_set_ip_blocks(struct amdgpu_device *adev) amdgpu_device_ip_block_add(adev, _common_ip_block); amdgpu_device_ip_block_add(adev, _v7_0_ip_block); amdgpu_device_ip_block_add(adev, _ih_ip_block); + amdgpu_device_ip_block_add(adev, _v7_1_ip_block); + amdgpu_device_ip_block_add(adev, _sdma_ip_block); amdgpu_device_ip_block_add(adev, _smu_ip_block); if (adev->enable_virtual_display) amdgpu_device_ip_block_add(adev, _virtual_ip_block); @@ -2053,8 +2055,7 @@ int cik_set_ip_blocks(struct amdgpu_device *adev) #endif else amdgpu_device_ip_block_add(adev, _v8_1_ip_block); - amdgpu_device_ip_block_add(adev, _v7_1_ip_block); - amdgpu_device_ip_block_add(adev, _sdma_ip_block); + amdgpu_device_ip_block_add(adev, _v4_2_ip_block); amdgpu_device_ip_block_add(adev, _v2_0_ip_block); break; @@ -2063,6 +2064,8 @@ int cik_set_ip_blocks(struct amdgpu_device *adev) amdgpu_device_ip_block_add(adev, _common_ip_block); amdgpu_device_ip_block_add(adev, _v7_0_ip_block); amdgpu_device_ip_block_add(adev, _ih_ip_block); + amdgpu_device_ip_block_add(adev, _v7_2_ip_block); + amdgpu_device_ip_block_add(adev, _sdma_ip_block); amdgpu_device_ip_block_add(adev, _smu_ip_block); if (adev->enable_virtual_display) amdgpu_device_ip_block_add(adev, _virtual_ip_block); @@ -2072,8 +2075,6 @@ int cik_set_ip_blocks(struct amdgpu_device *adev) #endif else amdgpu_device_ip_block_add(adev, _v8_3_ip_block); - amdgpu_device_ip_block_add(adev, _v7_2_ip_block); - amdgpu_device_ip_block_add(adev, _sdma_ip_block); amdgpu_device_ip_block_add(adev, _v4_2_ip_block); amdgpu_device_ip_block_add(adev, _v2_0_ip_block); break; diff --git a/drivers/gpu/drm/amd/amdgpu/si.c b/drivers/gpu/drm/amd/amdgpu/si.c index c364ef9..f8408f8 100644 --- a/drivers/gpu/drm/amd/amdgpu/si.c +++ b/drivers/gpu/drm/amd/amdgpu/si.c @@ -2057,13 +2057,13 @@ int si_set_ip_blocks(struct amdgpu_device *adev)
[PATCH 6/7] drm/amd/pp: Export load_firmware interface
Export this interface for the AMDGPU_FW_LOAD_SMU type. gfx/sdma can request smu to load firmware. Split the smu7/8_start_smu function into two functions 1. start_smu, used for load smu firmware in smu7/8 and check smu firmware version. 2. request_smu_load_fw, used for load other ip's firmware on smu7/8 and add firmware loading staus check. Signed-off-by: Rex Zhu --- drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 11 +++- drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 14 +++-- drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c | 4 +- .../gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c | 25 - .../drm/amd/powerplay/smumgr/polaris10_smumgr.c| 4 +- drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c | 59 +- drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h | 3 +- drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c | 46 - .../gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c| 12 - .../gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c| 4 +- 10 files changed, 79 insertions(+), 103 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 2aeef2b..f020f6f 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -4216,10 +4216,17 @@ static int gfx_v8_0_rlc_resume(struct amdgpu_device *adev) if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) { /* legacy rlc firmware loading */ r = gfx_v8_0_rlc_load_microcode(adev); - if (r) - return r; + } else if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU && adev->powerplay.pp_funcs->load_firmware) { + amdgpu_ucode_init_bo(adev); + r = adev->powerplay.pp_funcs->load_firmware(adev->powerplay.pp_handle); + } else { + r = -EINVAL; } + if (r) { + pr_err("firmware loading failed\n"); + return r; + } gfx_v8_0_rlc_start(adev); return 0; diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index aff7c14..3bc825c 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -124,9 +124,6 @@ static int pp_hw_init(void *handle) struct amdgpu_device *adev = handle; struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; - if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU) - amdgpu_ucode_init_bo(adev); - ret = hwmgr_hw_init(hwmgr); if (ret) @@ -275,7 +272,16 @@ static int pp_set_clockgating_state(void *handle, static int pp_dpm_load_fw(void *handle) { - return 0; + struct pp_hwmgr *hwmgr = handle; + int ret = 0; + + if (!hwmgr || !hwmgr->smumgr_funcs) + return -EINVAL; + + if (hwmgr->smumgr_funcs->request_smu_load_fw) + ret = hwmgr->smumgr_funcs->request_smu_load_fw(hwmgr); + + return ret; } static int pp_dpm_fw_loading_complete(void *handle) diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c index b6b62a7..ffd7d78 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c @@ -310,8 +310,6 @@ static int fiji_start_smu(struct pp_hwmgr *hwmgr) offsetof(SMU73_Firmware_Header, SoftRegisters), &(priv->smu7_data.soft_regs_start), 0x4); - result = smu7_request_smu_load_fw(hwmgr); - return result; } @@ -2643,7 +2641,7 @@ static int fiji_update_dpm_settings(struct pp_hwmgr *hwmgr, .smu_fini = _smu_fini, .start_smu = _start_smu, .check_fw_load_finish = _check_fw_load_finish, - .request_smu_load_fw = _reload_firmware, + .request_smu_load_fw = _request_smu_load_fw, .request_smu_load_specific_fw = NULL, .send_msg_to_smc = _send_msg_to_smc, .send_msg_to_smc_with_parameter = _send_msg_to_smc_with_parameter, diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c index 73aa368..68a4836 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c @@ -232,27 +232,24 @@ static int iceland_request_smu_load_specific_fw(struct pp_hwmgr *hwmgr, static int iceland_start_smu(struct pp_hwmgr *hwmgr) { - int result; - - result = iceland_smu_upload_firmware_image(hwmgr); - if (result) - return result; - result = iceland_smu_start_smc(hwmgr); - if (result) - return result; + struct iceland_smumgr *priv = hwmgr->smu_backend; + int result = 0; if (!smu7_is_smc_ram_running(hwmgr)) { - pr_info("smu not running, upload firmware again
[PATCH 5/7] drm/amd/pp: Remove useless code in smu
Signed-off-by: Rex Zhu --- drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c| 1 - drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | 1 - drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c | 5 - drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c | 5 - 4 files changed, 12 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c index 7500a3e..7844256 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c @@ -89,7 +89,6 @@ int hwmgr_early_init(struct pp_hwmgr *hwmgr) hwmgr_init_default_caps(hwmgr); hwmgr_set_user_specify_caps(hwmgr); hwmgr->fan_ctrl_is_in_default_mode = true; - hwmgr->reload_fw = 1; hwmgr_init_workload_prority(hwmgr); switch (hwmgr->chip_family) { diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h index d1183b1..b691fca 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h @@ -733,7 +733,6 @@ struct pp_hwmgr { void *smu_backend; const struct pp_smumgr_func *smumgr_funcs; bool is_kicker; - bool reload_fw; enum PP_DAL_POWERLEVEL dal_power_level; struct phm_dynamic_state_info dyn_state; diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c index 186dafc..10eb967 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c @@ -381,11 +381,6 @@ int smu7_request_smu_load_fw(struct pp_hwmgr *hwmgr) uint32_t fw_to_load; int r = 0; - if (!hwmgr->reload_fw) { - pr_info("skip reloading...\n"); - return 0; - } - if (smu_data->soft_regs_start) cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, smu_data->soft_regs_start + smum_get_offsetof(hwmgr, diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c index a74c5be..7a4c425 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c @@ -659,11 +659,6 @@ static int smu8_request_smu_load_fw(struct pp_hwmgr *hwmgr) struct smu8_smumgr *smu8_smu = hwmgr->smu_backend; uint32_t smc_address; - if (!hwmgr->reload_fw) { - pr_info("skip reloading...\n"); - return 0; - } - smu8_smu_populate_firmware_entries(hwmgr); smu8_smu_construct_toc(hwmgr); -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH] drm/amdgpu: Fix copy error in uvd_v6/7_0.c
Ok. I will remove the code. Best Regards Rex From: Christian König Sent: Wednesday, September 26, 2018 8:45 PM To: Zhu, Rex; amd-gfx@lists.freedesktop.org Subject: Re: [PATCH] drm/amdgpu: Fix copy error in uvd_v6/7_0.c Am 26.09.2018 um 14:41 schrieb Rex Zhu: > Signed-off-by: Rex Zhu Actually that code can just be removed because uvd_*_enc_get_destroy_msg is only called with direct=true. Christian. > --- > drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 2 +- > drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c | 2 +- > 2 files changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c > b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c > index 8ef4a53..2ceab76 100644 > --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c > @@ -313,7 +313,7 @@ static int uvd_v6_0_enc_get_destroy_msg(struct > amdgpu_ring *ring, >if (direct) >r = amdgpu_job_submit_direct(job, ring, ); >else > - r = amdgpu_job_submit(job, >adev->vce.entity, > + r = amdgpu_job_submit(job, >adev->uvd.entity, > AMDGPU_FENCE_OWNER_UNDEFINED, ); >if (r) >goto err; > diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c > b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c > index a289f6a..31a9665 100644 > --- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c > @@ -320,7 +320,7 @@ int uvd_v7_0_enc_get_destroy_msg(struct amdgpu_ring > *ring, uint32_t handle, >if (direct) >r = amdgpu_job_submit_direct(job, ring, ); >else > - r = amdgpu_job_submit(job, >adev->vce.entity, > + r = amdgpu_job_submit(job, >adev->uvd.entity, > AMDGPU_FENCE_OWNER_UNDEFINED, ); >if (r) >goto err; ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 1/7] drm/amd/pp: Expose the smu support for SDMA PG cntl
SDMA IP can be power up/down via smu message Signed-off-by: Rex Zhu --- drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 18 ++ drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c | 8 drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | 1 + 3 files changed, 27 insertions(+) diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c index 53d3337..aff7c14 100644 --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c @@ -1214,6 +1214,21 @@ static void pp_dpm_powergate_acp(void *handle, bool gate) hwmgr->hwmgr_func->powergate_acp(hwmgr, gate); } +static void pp_dpm_powergate_sdma(void *handle, bool gate) +{ + struct pp_hwmgr *hwmgr = handle; + + if (!hwmgr) + return; + + if (hwmgr->hwmgr_func->powergate_sdma == NULL) { + pr_info("%s was not implemented.\n", __func__); + return; + } + + hwmgr->hwmgr_func->powergate_sdma(hwmgr, gate); +} + static int pp_set_powergating_by_smu(void *handle, uint32_t block_type, bool gate) { @@ -1236,6 +1251,9 @@ static int pp_set_powergating_by_smu(void *handle, case AMD_IP_BLOCK_TYPE_ACP: pp_dpm_powergate_acp(handle, gate); break; + case AMD_IP_BLOCK_TYPE_SDMA: + pp_dpm_powergate_sdma(handle, gate); + break; default: break; } diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c index 5d1dae2..b7a9d0c 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c @@ -1153,6 +1153,14 @@ static int smu10_powergate_mmhub(struct pp_hwmgr *hwmgr) return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PowerGateMmHub); } +static int smu10_powergate_sdma(struct pp_hwmgr *hwmgr, bool gate) +{ + if (gate) + return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PowerDownSdma); + else + return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PowerUpSdma); +} + static void smu10_powergate_vcn(struct pp_hwmgr *hwmgr, bool bgate) { if (bgate) { diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h index a6d9212..d1183b1 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h @@ -328,6 +328,7 @@ struct pp_hwmgr_func { int (*set_power_limit)(struct pp_hwmgr *hwmgr, uint32_t n); int (*powergate_mmhub)(struct pp_hwmgr *hwmgr); int (*smus_notify_pwe)(struct pp_hwmgr *hwmgr); + int (*powergate_sdma)(struct pp_hwmgr *hwmgr, bool bgate); }; struct pp_table_func { -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 4/7] drm/amd/pp: Remove wrong code in fiji_start_smu
HW CG feature will be enabled after hw ip initialized Signed-off-by: Rex Zhu --- drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c | 10 -- 1 file changed, 10 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c index ec14798..b6b62a7 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c @@ -302,16 +302,6 @@ static int fiji_start_smu(struct pp_hwmgr *hwmgr) hwmgr->avfs_supported = false; } - /* To initialize all clock gating before RLC loaded and running.*/ - amdgpu_device_ip_set_clockgating_state(hwmgr->adev, - AMD_IP_BLOCK_TYPE_GFX, AMD_CG_STATE_GATE); - amdgpu_device_ip_set_clockgating_state(hwmgr->adev, - AMD_IP_BLOCK_TYPE_GMC, AMD_CG_STATE_GATE); - amdgpu_device_ip_set_clockgating_state(hwmgr->adev, - AMD_IP_BLOCK_TYPE_SDMA, AMD_CG_STATE_GATE); - amdgpu_device_ip_set_clockgating_state(hwmgr->adev, - AMD_IP_BLOCK_TYPE_COMMON, AMD_CG_STATE_GATE); - /* Setup SoftRegsStart here for register lookup in case * DummyBackEnd is used and ProcessFirmwareHeader is not executed */ -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 3/7] drm/amd/pp: Remove uncessary extra vcn pg cntl in smu
the vcn power will be controlled by VCN. Signed-off-by: Rex Zhu --- drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c | 16 +--- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c index d78d864..d0eb8ab 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c @@ -186,26 +186,12 @@ static int smu10_verify_smc_interface(struct pp_hwmgr *hwmgr) return 0; } -/* vcn is disabled by default in vbios, need to re-enable in driver */ -static void smu10_smc_enable_vcn(struct pp_hwmgr *hwmgr) -{ - smu10_send_msg_to_smc_with_parameter(hwmgr, - PPSMC_MSG_PowerUpVcn, 0); -} - -static void smu10_smc_disable_vcn(struct pp_hwmgr *hwmgr) -{ - smu10_send_msg_to_smc_with_parameter(hwmgr, - PPSMC_MSG_PowerDownVcn, 0); -} - static int smu10_smu_fini(struct pp_hwmgr *hwmgr) { struct smu10_smumgr *priv = (struct smu10_smumgr *)(hwmgr->smu_backend); if (priv) { - smu10_smc_disable_vcn(hwmgr); amdgpu_bo_free_kernel(>smu_tables.entry[SMU10_WMTABLE].handle, >smu_tables.entry[SMU10_WMTABLE].mc_addr, >smu_tables.entry[SMU10_WMTABLE].table); @@ -229,7 +215,7 @@ static int smu10_start_smu(struct pp_hwmgr *hwmgr) if (smu10_verify_smc_interface(hwmgr)) return -EINVAL; - smu10_smc_enable_vcn(hwmgr); + return 0; } -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 2/7] drm/amdgpu: Move out power up/down sdma out of smu
smu only expose interface to other ip blocks. in order to reduce dependence between smu and other ip blocks Signed-off-by: Rex Zhu --- drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 6 ++ drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c | 1 + drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c | 15 --- 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c index 12e577c..c20d413 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c @@ -1364,6 +1364,9 @@ static int sdma_v4_0_hw_init(void *handle) int r; struct amdgpu_device *adev = (struct amdgpu_device *)handle; + if (adev->asic_type == CHIP_RAVEN && adev->powerplay.pp_funcs->set_powergating_by_smu) + amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_SDMA, false); + sdma_v4_0_init_golden_registers(adev); r = sdma_v4_0_start(adev); @@ -1381,6 +1384,9 @@ static int sdma_v4_0_hw_fini(void *handle) sdma_v4_0_ctx_switch_enable(adev, false); sdma_v4_0_enable(adev, false); + if (adev->asic_type == CHIP_RAVEN && adev->powerplay.pp_funcs->set_powergating_by_smu) + amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_SDMA, true); + return 0; } diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c index b7a9d0c..dd18cb7 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c @@ -1216,6 +1216,7 @@ static void smu10_powergate_vcn(struct pp_hwmgr *hwmgr, bool bgate) .smus_notify_pwe = smu10_smus_notify_pwe, .display_clock_voltage_request = smu10_display_clock_voltage_request, .powergate_gfx = smu10_gfx_off_control, + .powergate_sdma = smu10_powergate_sdma, }; int smu10_init_function_pointers(struct pp_hwmgr *hwmgr) diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c b/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c index 6f961de..d78d864 100644 --- a/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c @@ -186,19 +186,6 @@ static int smu10_verify_smc_interface(struct pp_hwmgr *hwmgr) return 0; } -/* sdma is disabled by default in vbios, need to re-enable in driver */ -static void smu10_smc_enable_sdma(struct pp_hwmgr *hwmgr) -{ - smu10_send_msg_to_smc(hwmgr, - PPSMC_MSG_PowerUpSdma); -} - -static void smu10_smc_disable_sdma(struct pp_hwmgr *hwmgr) -{ - smu10_send_msg_to_smc(hwmgr, - PPSMC_MSG_PowerDownSdma); -} - /* vcn is disabled by default in vbios, need to re-enable in driver */ static void smu10_smc_enable_vcn(struct pp_hwmgr *hwmgr) { @@ -218,7 +205,6 @@ static int smu10_smu_fini(struct pp_hwmgr *hwmgr) (struct smu10_smumgr *)(hwmgr->smu_backend); if (priv) { - smu10_smc_disable_sdma(hwmgr); smu10_smc_disable_vcn(hwmgr); amdgpu_bo_free_kernel(>smu_tables.entry[SMU10_WMTABLE].handle, >smu_tables.entry[SMU10_WMTABLE].mc_addr, @@ -243,7 +229,6 @@ static int smu10_start_smu(struct pp_hwmgr *hwmgr) if (smu10_verify_smc_interface(hwmgr)) return -EINVAL; - smu10_smc_enable_sdma(hwmgr); smu10_smc_enable_vcn(hwmgr); return 0; } -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH v2 1/8] drm/amdgpu:Use register UVD_SCRATCH9 for VCN ring/ib test
On 2018-09-26 06:38 AM, Huang, Ray wrote: -Original Message- From: amd-gfx [mailto:amd-gfx-boun...@lists.freedesktop.org] On Behalf Of James Zhu Sent: Wednesday, September 26, 2018 7:03 AM To: amd-gfx@lists.freedesktop.org Cc: Zhu, James Subject: [PATCH v2 1/8] drm/amdgpu:Use register UVD_SCRATCH9 for VCN ring/ib test Use register UVD_SCRATCH9 for VCN ring/ib test. Since those registers can't be directly accessed under DPG(Dynamic Power Gate) mode. Signed-off-by: James Zhu Reviewed-by: Alex Deucher Thanks James. We will give a try on Picasso. Please add test cases to run dec/enc/mjpec dec together. Play dec(using DPG mode) clip continuously ASAP. run enc/mjpec dec (using DPG pause mode) with random gap. It try to make vcn switch between DPG mode and DPG pause mode. if you will boot with drm.debug=1, You will see DPG mode switching messages in syslog. James Feel free to add my RB for the series: Reviewed-by: Huang Rui --- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index a73674f..27262a8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -264,7 +264,7 @@ int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring *ring) unsigned i; int r; - WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0xCAFEDEAD); + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0xCAFEDEAD); r = amdgpu_ring_alloc(ring, 3); if (r) { DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n", @@ -272,11 +272,11 @@ int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring *ring) return r; } amdgpu_ring_write(ring, - PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0)); + PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0)); amdgpu_ring_write(ring, 0xDEADBEEF); amdgpu_ring_commit(ring); for (i = 0; i < adev->usec_timeout; i++) { - tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID)); + tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9)); if (tmp == 0xDEADBEEF) break; DRM_UDELAY(1); @@ -616,7 +616,7 @@ int amdgpu_vcn_jpeg_ring_test_ring(struct amdgpu_ring *ring) unsigned i; int r; - WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0xCAFEDEAD); + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0xCAFEDEAD); r = amdgpu_ring_alloc(ring, 3); if (r) { @@ -626,12 +626,12 @@ int amdgpu_vcn_jpeg_ring_test_ring(struct amdgpu_ring *ring) } amdgpu_ring_write(ring, - PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0, 0, 0)); + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0, 0, 0)); amdgpu_ring_write(ring, 0xDEADBEEF); amdgpu_ring_commit(ring); for (i = 0; i < adev->usec_timeout; i++) { - tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID)); + tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9)); if (tmp == 0xDEADBEEF) break; DRM_UDELAY(1); @@ -665,7 +665,7 @@ static int amdgpu_vcn_jpeg_set_reg(struct amdgpu_ring *ring, uint32_t handle, ib = >ibs[0]; - ib->ptr[0] = PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JPEG_PITCH), 0, 0, PACKETJ_TYPE0); + ib->ptr[0] = PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0, 0, +PACKETJ_TYPE0); ib->ptr[1] = 0xDEADBEEF; for (i = 2; i < 16; i += 2) { ib->ptr[i] = PACKETJ(0, 0, 0, PACKETJ_TYPE6); @@ -714,7 +714,7 @@ int amdgpu_vcn_jpeg_ring_test_ib(struct amdgpu_ring *ring, long timeout) r = 0; for (i = 0; i < adev->usec_timeout; i++) { - tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_JPEG_PITCH)); + tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9)); if (tmp == 0xDEADBEEF) break; DRM_UDELAY(1); -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdkfd: Remove the requirement for atomic Ops on vg20
From: Shaoyun Liu Firmware have the workaround to replace the atomic Ops with read-modify-write on CP side. User should not expect atomic Ops on system memory works normally if system didn't not support it. Change-Id: I89395b099fe0931b9b3627651b512dde3149fadd Signed-off-by: Shaoyun Liu Signed-off-by: Kent Russell --- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index b0c2afb..b505bf3 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -263,7 +263,7 @@ static const struct kfd_device_info vega20_device_info = { .mqd_size_aligned = MQD_SIZE_ALIGNED, .supports_cwsr = true, .needs_iommu_device = false, - .needs_pci_atomics = true, + .needs_pci_atomics = false, .num_sdma_engines = 2, .num_sdma_queues_per_engine = 8, }; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 03/12] drm/amdgpu: remove VM fault_credit handling
printk_ratelimit() is much better suited to limit the number of reported VM faults. Signed-off-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 37 - drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 5 - drivers/gpu/drm/amd/amdgpu/cik_ih.c | 18 +--- drivers/gpu/drm/amd/amdgpu/cz_ih.c | 18 +--- drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 18 +--- drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 18 +--- drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 7 ++- 7 files changed, 6 insertions(+), 115 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 6904d794d60a..570150ceeb16 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -3052,7 +3052,6 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, } INIT_KFIFO(vm->faults); - vm->fault_credit = 16; return 0; @@ -3262,42 +3261,6 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) amdgpu_vmid_free_reserved(adev, vm, i); } -/** - * amdgpu_vm_pasid_fault_credit - Check fault credit for given PASID - * - * @adev: amdgpu_device pointer - * @pasid: PASID do identify the VM - * - * This function is expected to be called in interrupt context. - * - * Returns: - * True if there was fault credit, false otherwise - */ -bool amdgpu_vm_pasid_fault_credit(struct amdgpu_device *adev, - unsigned int pasid) -{ - struct amdgpu_vm *vm; - - spin_lock(>vm_manager.pasid_lock); - vm = idr_find(>vm_manager.pasid_idr, pasid); - if (!vm) { - /* VM not found, can't track fault credit */ - spin_unlock(>vm_manager.pasid_lock); - return true; - } - - /* No lock needed. only accessed by IRQ handler */ - if (!vm->fault_credit) { - /* Too many faults in this VM */ - spin_unlock(>vm_manager.pasid_lock); - return false; - } - - vm->fault_credit--; - spin_unlock(>vm_manager.pasid_lock); - return true; -} - /** * amdgpu_vm_manager_init - init the VM manager * diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h index 2a8898d19c8b..e8dcfd59fc93 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h @@ -229,9 +229,6 @@ struct amdgpu_vm { /* Up to 128 pending retry page faults */ DECLARE_KFIFO(faults, u64, 128); - /* Limit non-retry fault storms */ - unsigned intfault_credit; - /* Points to the KFD process VM info */ struct amdkfd_process_info *process_info; @@ -299,8 +296,6 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm, unsigned int pasid); void amdgpu_vm_release_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm); void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm); -bool amdgpu_vm_pasid_fault_credit(struct amdgpu_device *adev, - unsigned int pasid); void amdgpu_vm_get_pd_bo(struct amdgpu_vm *vm, struct list_head *validated, struct amdgpu_bo_list_entry *entry); diff --git a/drivers/gpu/drm/amd/amdgpu/cik_ih.c b/drivers/gpu/drm/amd/amdgpu/cik_ih.c index b5775c6a857b..3e6c8c4067cb 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/cik_ih.c @@ -237,23 +237,7 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev) */ static bool cik_ih_prescreen_iv(struct amdgpu_device *adev) { - u32 ring_index = adev->irq.ih.rptr >> 2; - u16 pasid; - - switch (le32_to_cpu(adev->irq.ih.ring[ring_index]) & 0xff) { - case 146: - case 147: - pasid = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]) >> 16; - if (!pasid || amdgpu_vm_pasid_fault_credit(adev, pasid)) - return true; - break; - default: - /* Not a VM fault */ - return true; - } - - adev->irq.ih.rptr += 16; - return false; + return true; } /** diff --git a/drivers/gpu/drm/amd/amdgpu/cz_ih.c b/drivers/gpu/drm/amd/amdgpu/cz_ih.c index df5ac4d85a00..447b3cbc47e5 100644 --- a/drivers/gpu/drm/amd/amdgpu/cz_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/cz_ih.c @@ -216,23 +216,7 @@ static u32 cz_ih_get_wptr(struct amdgpu_device *adev) */ static bool cz_ih_prescreen_iv(struct amdgpu_device *adev) { - u32 ring_index = adev->irq.ih.rptr >> 2; - u16 pasid; - - switch (le32_to_cpu(adev->irq.ih.ring[ring_index]) & 0xff) { - case 146: - case 147: - pasid = le32_to_cpu(adev->irq.ih.ring[ring_index + 2]) >> 16; -
[PATCH 05/12] drm/amdgpu: remove IV prescreening
Not used any more. Signed-off-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 2 -- drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 4 drivers/gpu/drm/amd/amdgpu/cik_ih.c | 13 - drivers/gpu/drm/amd/amdgpu/cz_ih.c | 13 - drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 13 - drivers/gpu/drm/amd/amdgpu/si_ih.c | 14 -- drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 13 - drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 13 - 8 files changed, 85 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h index 9ce8c93ec19b..f877bb78d10a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h @@ -51,14 +51,12 @@ struct amdgpu_ih_ring { struct amdgpu_ih_funcs { /* ring read/write ptr handling, called from interrupt context */ u32 (*get_wptr)(struct amdgpu_device *adev); - bool (*prescreen_iv)(struct amdgpu_device *adev); void (*decode_iv)(struct amdgpu_device *adev, struct amdgpu_iv_entry *entry); void (*set_rptr)(struct amdgpu_device *adev); }; #define amdgpu_ih_get_wptr(adev) (adev)->irq.ih_funcs->get_wptr((adev)) -#define amdgpu_ih_prescreen_iv(adev) (adev)->irq.ih_funcs->prescreen_iv((adev)) #define amdgpu_ih_decode_iv(adev, iv) (adev)->irq.ih_funcs->decode_iv((adev), (iv)) #define amdgpu_ih_set_rptr(adev) (adev)->irq.ih_funcs->set_rptr((adev)) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index 8f0bc3f2e163..613ee1b76b25 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c @@ -162,10 +162,6 @@ static void amdgpu_irq_callback(struct amdgpu_device *adev, u32 ring_index = ih->rptr >> 2; struct amdgpu_iv_entry entry; - /* Prescreening of high-frequency interrupts */ - if (!amdgpu_ih_prescreen_iv(adev)) - return; - entry.iv_entry = (const uint32_t *)>ring[ring_index]; amdgpu_ih_decode_iv(adev, ); diff --git a/drivers/gpu/drm/amd/amdgpu/cik_ih.c b/drivers/gpu/drm/amd/amdgpu/cik_ih.c index 3e6c8c4067cb..8a8b4967a101 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/cik_ih.c @@ -228,18 +228,6 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev) * [127:96] - reserved */ -/** - * cik_ih_prescreen_iv - prescreen an interrupt vector - * - * @adev: amdgpu_device pointer - * - * Returns true if the interrupt vector should be further processed. - */ -static bool cik_ih_prescreen_iv(struct amdgpu_device *adev) -{ - return true; -} - /** * cik_ih_decode_iv - decode an interrupt vector * @@ -445,7 +433,6 @@ static const struct amd_ip_funcs cik_ih_ip_funcs = { static const struct amdgpu_ih_funcs cik_ih_funcs = { .get_wptr = cik_ih_get_wptr, - .prescreen_iv = cik_ih_prescreen_iv, .decode_iv = cik_ih_decode_iv, .set_rptr = cik_ih_set_rptr }; diff --git a/drivers/gpu/drm/amd/amdgpu/cz_ih.c b/drivers/gpu/drm/amd/amdgpu/cz_ih.c index 447b3cbc47e5..9d3ea298e116 100644 --- a/drivers/gpu/drm/amd/amdgpu/cz_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/cz_ih.c @@ -207,18 +207,6 @@ static u32 cz_ih_get_wptr(struct amdgpu_device *adev) return (wptr & adev->irq.ih.ptr_mask); } -/** - * cz_ih_prescreen_iv - prescreen an interrupt vector - * - * @adev: amdgpu_device pointer - * - * Returns true if the interrupt vector should be further processed. - */ -static bool cz_ih_prescreen_iv(struct amdgpu_device *adev) -{ - return true; -} - /** * cz_ih_decode_iv - decode an interrupt vector * @@ -426,7 +414,6 @@ static const struct amd_ip_funcs cz_ih_ip_funcs = { static const struct amdgpu_ih_funcs cz_ih_funcs = { .get_wptr = cz_ih_get_wptr, - .prescreen_iv = cz_ih_prescreen_iv, .decode_iv = cz_ih_decode_iv, .set_rptr = cz_ih_set_rptr }; diff --git a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c index 2b94a6d1550e..a3984d10b604 100644 --- a/drivers/gpu/drm/amd/amdgpu/iceland_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/iceland_ih.c @@ -207,18 +207,6 @@ static u32 iceland_ih_get_wptr(struct amdgpu_device *adev) return (wptr & adev->irq.ih.ptr_mask); } -/** - * iceland_ih_prescreen_iv - prescreen an interrupt vector - * - * @adev: amdgpu_device pointer - * - * Returns true if the interrupt vector should be further processed. - */ -static bool iceland_ih_prescreen_iv(struct amdgpu_device *adev) -{ - return true; -} - /** * iceland_ih_decode_iv - decode an interrupt vector * @@ -424,7 +412,6 @@ static const struct amd_ip_funcs iceland_ih_ip_funcs = { static const struct amdgpu_ih_funcs iceland_ih_funcs = { .get_wptr = iceland_ih_get_wptr, - .prescreen_iv = iceland_ih_prescreen_iv, .decode_iv = iceland_ih_decode_iv, .set_rptr =
[PATCH 02/12] drm/amdgpu: send IVs to the KFD only after processing them
This allows us to filter out VM faults in the GMC code. Signed-off-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 29 + drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 2 +- 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index 52c17f6219a7..8f0bc3f2e163 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c @@ -166,9 +166,6 @@ static void amdgpu_irq_callback(struct amdgpu_device *adev, if (!amdgpu_ih_prescreen_iv(adev)) return; - /* Before dispatching irq to IP blocks, send it to amdkfd */ - amdgpu_amdkfd_interrupt(adev, (const void *) >ring[ring_index]); - entry.iv_entry = (const uint32_t *)>ring[ring_index]; amdgpu_ih_decode_iv(adev, ); @@ -392,29 +389,31 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev, unsigned client_id = entry->client_id; unsigned src_id = entry->src_id; struct amdgpu_irq_src *src; + bool handled = false; int r; trace_amdgpu_iv(entry); if (client_id >= AMDGPU_IRQ_CLIENTID_MAX) { - DRM_DEBUG("Invalid client_id in IV: %d\n", client_id); + DRM_ERROR("Invalid client_id in IV: %d\n", client_id); return; } if (src_id >= AMDGPU_MAX_IRQ_SRC_ID) { - DRM_DEBUG("Invalid src_id in IV: %d\n", src_id); + DRM_ERROR("Invalid src_id in IV: %d\n", src_id); return; } if (adev->irq.virq[src_id]) { generic_handle_irq(irq_find_mapping(adev->irq.domain, src_id)); - } else { - if (!adev->irq.client[client_id].sources) { - DRM_DEBUG("Unregistered interrupt client_id: %d src_id: %d\n", - client_id, src_id); - return; - } + return; + } + if (!adev->irq.client[client_id].sources) { + DRM_DEBUG("Unregistered interrupt client_id: %d src_id: %d\n", + client_id, src_id); + return; + } else { src = adev->irq.client[client_id].sources[src_id]; if (!src) { DRM_DEBUG("Unhandled interrupt src_id: %d\n", src_id); @@ -422,9 +421,15 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev, } r = src->funcs->process(adev, src, entry); - if (r) + if (r < 0) DRM_ERROR("error processing interrupt (%d)\n", r); + else if (r) + handled = true; } + + /* Send it to amdkfd as well if it isn't already handled */ + if (!handled) + amdgpu_amdkfd_interrupt(adev, entry->iv_entry); } /** diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c index e1c2b4e9c7b2..d65bfbe21f56 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c @@ -1132,7 +1132,7 @@ static int gmc_v6_0_process_interrupt(struct amdgpu_device *adev, gmc_v6_0_vm_decode_fault(adev, status, addr, 0); } - return 0; + return 1; } static int gmc_v6_0_set_clockgating_state(void *handle, diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index 910c4ce19cb3..ca8b34bab261 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c @@ -1325,7 +1325,7 @@ static int gmc_v7_0_process_interrupt(struct amdgpu_device *adev, atomic_set(>gmc.vm_fault_info_updated, 1); } - return 0; + return 1; } static int gmc_v7_0_set_clockgating_state(void *handle, diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index 1d3265c97b70..f7547a7776a3 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c @@ -1487,7 +1487,7 @@ static int gmc_v8_0_process_interrupt(struct amdgpu_device *adev, atomic_set(>gmc.vm_fault_info_updated, 1); } - return 0; + return 1; } static void fiji_update_mc_medium_grain_clock_gating(struct amdgpu_device *adev, diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index 2420ae90047e..729a2c230f91 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -279,7 +279,7 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev, status); } - return 0; + return 1; } static const struct
[PATCH 07/12] drm/amdgpu: simplify IH programming
Calculate all the addresses and pointers in amdgpu_ih.c Signed-off-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | 34 +-- drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 23 - drivers/gpu/drm/amd/amdgpu/cik_ih.c | 9 - drivers/gpu/drm/amd/amdgpu/cz_ih.c | 11 +- drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 9 - drivers/gpu/drm/amd/amdgpu/si_ih.c | 9 - drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 27 +++-- drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 36 +++-- 8 files changed, 73 insertions(+), 85 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c index fb8dd6179926..d0a5db777b6d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c @@ -52,6 +52,8 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, ih->use_bus_addr = use_bus_addr; if (use_bus_addr) { + dma_addr_t dma_addr; + if (ih->ring) return 0; @@ -59,21 +61,26 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, * add them to the end of the ring allocation. */ ih->ring = dma_alloc_coherent(adev->dev, ih->ring_size + 8, - >rb_dma_addr, GFP_KERNEL); + _addr, GFP_KERNEL); if (ih->ring == NULL) return -ENOMEM; memset((void *)ih->ring, 0, ih->ring_size + 8); - ih->wptr_offs = (ih->ring_size / 4) + 0; - ih->rptr_offs = (ih->ring_size / 4) + 1; + ih->gpu_addr = dma_addr; + ih->wptr_addr = dma_addr + ih->ring_size; + ih->wptr_cpu = >ring[ih->ring_size / 4]; + ih->rptr_addr = dma_addr + ih->ring_size + 4; + ih->rptr_cpu = >ring[(ih->ring_size / 4) + 1]; } else { - r = amdgpu_device_wb_get(adev, >wptr_offs); + unsigned wptr_offs, rptr_offs; + + r = amdgpu_device_wb_get(adev, _offs); if (r) return r; - r = amdgpu_device_wb_get(adev, >rptr_offs); + r = amdgpu_device_wb_get(adev, _offs); if (r) { - amdgpu_device_wb_free(adev, ih->wptr_offs); + amdgpu_device_wb_free(adev, wptr_offs); return r; } @@ -82,10 +89,15 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, >ring_obj, >gpu_addr, (void **)>ring); if (r) { - amdgpu_device_wb_free(adev, ih->rptr_offs); - amdgpu_device_wb_free(adev, ih->wptr_offs); + amdgpu_device_wb_free(adev, rptr_offs); + amdgpu_device_wb_free(adev, wptr_offs); return r; } + + ih->wptr_addr = adev->wb.gpu_addr + wptr_offs * 4; + ih->wptr_cpu = >wb.wb[wptr_offs]; + ih->rptr_addr = adev->wb.gpu_addr + rptr_offs * 4; + ih->rptr_cpu = >wb.wb[rptr_offs]; } return 0; } @@ -109,13 +121,13 @@ void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih) * add them to the end of the ring allocation. */ dma_free_coherent(adev->dev, ih->ring_size + 8, - (void *)ih->ring, ih->rb_dma_addr); + (void *)ih->ring, ih->gpu_addr); ih->ring = NULL; } else { amdgpu_bo_free_kernel(>ring_obj, >gpu_addr, (void **)>ring); - amdgpu_device_wb_free(adev, ih->wptr_offs); - amdgpu_device_wb_free(adev, ih->rptr_offs); + amdgpu_device_wb_free(adev, (ih->wptr_addr - ih->gpu_addr) / 4); + amdgpu_device_wb_free(adev, (ih->rptr_addr - ih->gpu_addr) / 4); } } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h index d810fd73d574..1ccb1831382a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h @@ -31,20 +31,25 @@ struct amdgpu_iv_entry; * R6xx+ IH ring */ struct amdgpu_ih_ring { - struct amdgpu_bo*ring_obj; - volatile uint32_t *ring; - unsignedrptr; unsignedring_size; - uint64_tgpu_addr; uint32_tptr_mask; - atomic_tlock; - boolenabled; -
[PATCH 08/12] drm/amdgpu: enable IH ring 1 and ring 2 v2
The entries are ignored for now, but it at least stops crashing the hardware when somebody tries to push something to the other IH rings. v2: limit ring size, add TODO comment Signed-off-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h | 4 +- drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 129 ++-- 2 files changed, 107 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h index f6ce171cb8aa..7e06fa64321a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h @@ -87,8 +87,8 @@ struct amdgpu_irq { /* status, etc. */ boolmsi_enabled; /* msi enabled */ - /* interrupt ring */ - struct amdgpu_ih_ring ih; + /* interrupt rings */ + struct amdgpu_ih_ring ih, ih1, ih2; const struct amdgpu_ih_funcs*ih_funcs; /* gen irq stuff */ diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c index 444f64e5092b..e6af9b4c3116 100644 --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c @@ -50,6 +50,16 @@ static void vega10_ih_enable_interrupts(struct amdgpu_device *adev) ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, ENABLE_INTR, 1); WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl); adev->irq.ih.enabled = true; + + ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1); + ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1, RB_ENABLE, 1); + WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl); + adev->irq.ih1.enabled = true; + + ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2); + ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2, RB_ENABLE, 1); + WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl); + adev->irq.ih2.enabled = true; } /** @@ -71,6 +81,47 @@ static void vega10_ih_disable_interrupts(struct amdgpu_device *adev) WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR, 0); adev->irq.ih.enabled = false; adev->irq.ih.rptr = 0; + + ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1); + ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1, RB_ENABLE, 0); + WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl); + /* set rptr, wptr to 0 */ + WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, 0); + WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING1, 0); + adev->irq.ih1.enabled = false; + adev->irq.ih1.rptr = 0; + + ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2); + ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2, RB_ENABLE, 0); + WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl); + /* set rptr, wptr to 0 */ + WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, 0); + WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING2, 0); + adev->irq.ih2.enabled = false; + adev->irq.ih2.rptr = 0; +} + +static uint32_t vega10_ih_rb_cntl(struct amdgpu_ih_ring *ih, uint32_t ih_rb_cntl) +{ + int rb_bufsz = order_base_2(ih->ring_size / 4); + + ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, + MC_SPACE, ih->use_bus_addr ? 1 : 4); + ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, + WPTR_OVERFLOW_CLEAR, 1); + ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, + WPTR_OVERFLOW_ENABLE, 1); + ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_SIZE, rb_bufsz); + /* Ring Buffer write pointer writeback. If enabled, IH_RB_WPTR register +* value is written to memory +*/ + ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, + WPTR_WRITEBACK_ENABLE, 1); + ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SNOOP, 1); + ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_RO, 0); + ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_VMID, 0); + + return ih_rb_cntl; } /** @@ -86,9 +137,8 @@ static void vega10_ih_disable_interrupts(struct amdgpu_device *adev) */ static int vega10_ih_irq_init(struct amdgpu_device *adev) { - struct amdgpu_ih_ring *ih = >irq.ih; + struct amdgpu_ih_ring *ih; int ret = 0; - int rb_bufsz; u32 ih_rb_cntl, ih_doorbell_rtpr; u32 tmp; @@ -97,26 +147,15 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev) adev->nbio_funcs->ih_control(adev); - ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL); + ih = >irq.ih; /* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/ - WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE, adev->irq.ih.gpu_addr >> 8); - WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI, -(adev->irq.ih.gpu_addr >> 40) & 0xff); -
[PATCH 09/12] drm/amdgpu: add the IH to the IV trace
To distinct on which IH ring an IV was found. Signed-off-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h | 11 +++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index 613ee1b76b25..9d40ff27f0b5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c @@ -165,6 +165,8 @@ static void amdgpu_irq_callback(struct amdgpu_device *adev, entry.iv_entry = (const uint32_t *)>ring[ring_index]; amdgpu_ih_decode_iv(adev, ); + trace_amdgpu_iv(ih - >irq.ih, ); + amdgpu_irq_dispatch(adev, ); } @@ -388,8 +390,6 @@ void amdgpu_irq_dispatch(struct amdgpu_device *adev, bool handled = false; int r; - trace_amdgpu_iv(entry); - if (client_id >= AMDGPU_IRQ_CLIENTID_MAX) { DRM_ERROR("Invalid client_id in IV: %d\n", client_id); return; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h index e9bf70e2ac51..2d8f420104e5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_trace.h @@ -76,9 +76,10 @@ TRACE_EVENT(amdgpu_mm_wreg, ); TRACE_EVENT(amdgpu_iv, - TP_PROTO(struct amdgpu_iv_entry *iv), - TP_ARGS(iv), + TP_PROTO(unsigned ih, struct amdgpu_iv_entry *iv), + TP_ARGS(ih, iv), TP_STRUCT__entry( +__field(unsigned, ih) __field(unsigned, client_id) __field(unsigned, src_id) __field(unsigned, ring_id) @@ -90,6 +91,7 @@ TRACE_EVENT(amdgpu_iv, __array(unsigned, src_data, 4) ), TP_fast_assign( + __entry->ih = ih; __entry->client_id = iv->client_id; __entry->src_id = iv->src_id; __entry->ring_id = iv->ring_id; @@ -103,8 +105,9 @@ TRACE_EVENT(amdgpu_iv, __entry->src_data[2] = iv->src_data[2]; __entry->src_data[3] = iv->src_data[3]; ), - TP_printk("client_id:%u src_id:%u ring:%u vmid:%u timestamp: %llu pasid:%u src_data: %08x %08x %08x %08x", - __entry->client_id, __entry->src_id, + TP_printk("ih: %u client_id:%u src_id:%u ring:%u vmid:%u " + "timestamp: %llu pasid:%u src_data: %08x %08x %08x %08x", + __entry->ih, __entry->client_id, __entry->src_id, __entry->ring_id, __entry->vmid, __entry->timestamp, __entry->pasid, __entry->src_data[0], __entry->src_data[1], -- 2.14.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 11/12] drm/amdgpu: add support for self irq on Vega10
This finally enables processing of ring 1 & 2. Signed-off-by: Christian König --- drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 68 +++--- 1 file changed, 63 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c index e6af9b4c3116..dd155a207fdd 100644 --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c @@ -258,7 +258,7 @@ static void vega10_ih_irq_disable(struct amdgpu_device *adev) static u32 vega10_ih_get_wptr(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih) { - u32 wptr, tmp; + u32 wptr, reg, tmp; wptr = le32_to_cpu(*ih->wptr_cpu); @@ -274,9 +274,18 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev, wptr, ih->rptr, tmp); ih->rptr = tmp; - tmp = RREG32_NO_KIQ(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL)); + if (ih == >irq.ih) + reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL); + else if (ih == >irq.ih1) + reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL); + else if (ih == >irq.ih2) + reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL); + else + BUG(); + + tmp = RREG32_NO_KIQ(reg); tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); - WREG32_NO_KIQ(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL), tmp); + WREG32_NO_KIQ(reg, tmp); } return (wptr & ih->ptr_mask); } @@ -338,9 +347,52 @@ static void vega10_ih_set_rptr(struct amdgpu_device *adev, /* XXX check if swapping is necessary on BE */ *ih->rptr_cpu = ih->rptr; WDOORBELL32(ih->doorbell_index, ih->rptr); - } else { + } else if (ih == >irq.ih) { WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, ih->rptr); + } else if (ih == >irq.ih1) { + WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, ih->rptr); + } else if (ih == >irq.ih2) { + WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, ih->rptr); + } +} + +/** + * vega10_ih_self_irq - dispatch work for ring 1 and 2 + * + * @adev: amdgpu_device pointer + * @source: irq source + * @entry: IV with WPTR update + * + * Update the WPTR from the IV and schedule work to handle the entries. + */ +static int vega10_ih_self_irq(struct amdgpu_device *adev, + struct amdgpu_irq_src *source, + struct amdgpu_iv_entry *entry) +{ + uint32_t wptr = cpu_to_le32(entry->src_data[0]); + + switch (entry->ring_id) { + case 1: + *adev->irq.ih1.wptr_cpu = wptr; + schedule_work(>irq.ih1_work); + break; + case 2: + *adev->irq.ih2.wptr_cpu = wptr; + schedule_work(>irq.ih2_work); + break; + default: break; } + return 0; +} + +static const struct amdgpu_irq_src_funcs vega10_ih_self_irq_funcs = { + .process = vega10_ih_self_irq, +}; + +static void vega10_ih_set_self_irq_funcs(struct amdgpu_device *adev) +{ + adev->irq.self_irq.num_types = 0; + adev->irq.self_irq.funcs = _ih_self_irq_funcs; } static int vega10_ih_early_init(void *handle) @@ -348,13 +400,19 @@ static int vega10_ih_early_init(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; vega10_ih_set_interrupt_funcs(adev); + vega10_ih_set_self_irq_funcs(adev); return 0; } static int vega10_ih_sw_init(void *handle) { - int r; struct amdgpu_device *adev = (struct amdgpu_device *)handle; + int r; + + r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_IH, 0, + >irq.self_irq); + if (r) + return r; r = amdgpu_ih_ring_init(adev, >irq.ih, 256 * 1024, true); if (r) -- 2.14.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 10/12] drm/amdgpu: add support for processing IH ring 1 & 2
Previously we only added the ring buffer memory, now add the handling as well. Signed-off-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 32 drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h | 4 +++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index 9d40ff27f0b5..2334e85b92f5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c @@ -193,6 +193,36 @@ irqreturn_t amdgpu_irq_handler(int irq, void *arg) return ret; } +/** + * amdgpu_irq_handle_ih1 - kick of processing for IH1 + * + * @work: work structure in struct amdgpu_irq + * + * Kick of processing IH ring 1. + */ +static void amdgpu_irq_handle_ih1(struct work_struct *work) +{ + struct amdgpu_device *adev = container_of(work, struct amdgpu_device, + irq.ih1_work); + + amdgpu_ih_process(adev, >irq.ih1, amdgpu_irq_callback); +} + +/** + * amdgpu_irq_handle_ih2 - kick of processing for IH2 + * + * @work: work structure in struct amdgpu_irq + * + * Kick of processing IH ring 2. + */ +static void amdgpu_irq_handle_ih2(struct work_struct *work) +{ + struct amdgpu_device *adev = container_of(work, struct amdgpu_device, + irq.ih2_work); + + amdgpu_ih_process(adev, >irq.ih2, amdgpu_irq_callback); +} + /** * amdgpu_msi_ok - check whether MSI functionality is enabled * @@ -258,6 +288,8 @@ int amdgpu_irq_init(struct amdgpu_device *adev) } INIT_WORK(>reset_work, amdgpu_irq_reset_work_func); + INIT_WORK(>irq.ih1_work, amdgpu_irq_handle_ih1); + INIT_WORK(>irq.ih2_work, amdgpu_irq_handle_ih2); adev->irq.installed = true; r = drm_irq_install(adev->ddev, adev->ddev->pdev->irq); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h index 7e06fa64321a..c27decfda494 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h @@ -89,7 +89,9 @@ struct amdgpu_irq { /* interrupt rings */ struct amdgpu_ih_ring ih, ih1, ih2; - const struct amdgpu_ih_funcs*ih_funcs; + const struct amdgpu_ih_funcs*ih_funcs; + struct work_struct ih1_work, ih2_work; + struct amdgpu_irq_src self_irq; /* gen irq stuff */ struct irq_domain *domain; /* GPU irq controller domain */ -- 2.14.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 12/12] drm/amdgpu: disable IH ring 2 WPTR overflow on Vega10
That should add back pressure on the client. Signed-off-by: Christian König --- drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c index dd155a207fdd..c8525c29fc16 100644 --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c @@ -207,6 +207,8 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev) ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1); ih_rb_cntl = vega10_ih_rb_cntl(ih, ih_rb_cntl); + ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2, + WPTR_OVERFLOW_ENABLE, 0); WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl); /* set rptr, wptr to 0 */ -- 2.14.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 06/12] drm/amdgpu: add IH ring to ih_get_wptr/ih_set_rptr v2
Let's start to support multiple rings. v2: decode IV is needed as well Signed-off-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | 6 ++-- drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 13 drivers/gpu/drm/amd/amdgpu/cik_ih.c | 29 + drivers/gpu/drm/amd/amdgpu/cz_ih.c | 31 +- drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 29 + drivers/gpu/drm/amd/amdgpu/si_ih.c | 31 +- drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 43 + drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 56 + 8 files changed, 128 insertions(+), 110 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c index 8af67f649660..fb8dd6179926 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c @@ -137,7 +137,7 @@ int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, if (!ih->enabled || adev->shutdown) return IRQ_NONE; - wptr = amdgpu_ih_get_wptr(adev); + wptr = amdgpu_ih_get_wptr(adev, ih); restart_ih: /* is somebody else already processing irqs? */ @@ -154,11 +154,11 @@ int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, ih->rptr &= ih->ptr_mask; } - amdgpu_ih_set_rptr(adev); + amdgpu_ih_set_rptr(adev, ih); atomic_set(>lock, 0); /* make sure wptr hasn't changed while processing */ - wptr = amdgpu_ih_get_wptr(adev); + wptr = amdgpu_ih_get_wptr(adev, ih); if (wptr != ih->rptr) goto restart_ih; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h index f877bb78d10a..d810fd73d574 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h @@ -50,15 +50,16 @@ struct amdgpu_ih_ring { /* provided by the ih block */ struct amdgpu_ih_funcs { /* ring read/write ptr handling, called from interrupt context */ - u32 (*get_wptr)(struct amdgpu_device *adev); - void (*decode_iv)(struct amdgpu_device *adev, + u32 (*get_wptr)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); + void (*decode_iv)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, struct amdgpu_iv_entry *entry); - void (*set_rptr)(struct amdgpu_device *adev); + void (*set_rptr)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); }; -#define amdgpu_ih_get_wptr(adev) (adev)->irq.ih_funcs->get_wptr((adev)) -#define amdgpu_ih_decode_iv(adev, iv) (adev)->irq.ih_funcs->decode_iv((adev), (iv)) -#define amdgpu_ih_set_rptr(adev) (adev)->irq.ih_funcs->set_rptr((adev)) +#define amdgpu_ih_get_wptr(adev, ih) (adev)->irq.ih_funcs->get_wptr((adev), (ih)) +#define amdgpu_ih_decode_iv(adev, iv) \ + (adev)->irq.ih_funcs->decode_iv((adev), (ih), (iv)) +#define amdgpu_ih_set_rptr(adev, ih) (adev)->irq.ih_funcs->set_rptr((adev), (ih)) int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, unsigned ring_size, bool use_bus_addr); diff --git a/drivers/gpu/drm/amd/amdgpu/cik_ih.c b/drivers/gpu/drm/amd/amdgpu/cik_ih.c index 8a8b4967a101..884aa9b81e86 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/cik_ih.c @@ -183,11 +183,12 @@ static void cik_ih_irq_disable(struct amdgpu_device *adev) * Used by cik_irq_process(). * Returns the value of the wptr. */ -static u32 cik_ih_get_wptr(struct amdgpu_device *adev) +static u32 cik_ih_get_wptr(struct amdgpu_device *adev, + struct amdgpu_ih_ring *ih) { u32 wptr, tmp; - wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]); + wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]); if (wptr & IH_RB_WPTR__RB_OVERFLOW_MASK) { wptr &= ~IH_RB_WPTR__RB_OVERFLOW_MASK; @@ -196,13 +197,13 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev) * this should allow us to catchup. */ dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", - wptr, adev->irq.ih.rptr, (wptr + 16) & adev->irq.ih.ptr_mask); - adev->irq.ih.rptr = (wptr + 16) & adev->irq.ih.ptr_mask; +wptr, ih->rptr, (wptr + 16) & ih->ptr_mask); + ih->rptr = (wptr + 16) & ih->ptr_mask; tmp = RREG32(mmIH_RB_CNTL); tmp |= IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK; WREG32(mmIH_RB_CNTL, tmp); } - return (wptr & adev->irq.ih.ptr_mask); + return (wptr & ih->ptr_mask); } /*CIK IV Ring @@ -237,16 +238,17 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev) * position and also advance the position. */ static void cik_ih_decode_iv(struct amdgpu_device *adev, +
[PATCH 01/12] drm/amdgpu: add missing error handling
We ignored the return code here. Signed-off-by: Christian König --- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index f35d7a554ad5..2420ae90047e 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -959,6 +959,9 @@ static int gmc_v9_0_sw_init(void *handle) /* This interrupt is VMC page fault.*/ r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VMC, VMC_1_0__SRCID__VM_FAULT, >gmc.vm_fault); + if (r) + return r; + r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_UTCL2, UTCL2_1_0__SRCID__FAULT, >gmc.vm_fault); -- 2.14.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
RE: [PATCH 3/9] drm/amdgpu: cleanup amdgpu_ih.c
> -Original Message- > From: Koenig, Christian > Sent: Wednesday, September 26, 2018 4:58 PM > To: Huang, Ray > Cc: amd-gfx@lists.freedesktop.org > Subject: Re: [PATCH 3/9] drm/amdgpu: cleanup amdgpu_ih.c > > Am 26.09.2018 um 10:52 schrieb Huang, Ray: > >> -Original Message- > >> From: Christian König [mailto:ckoenig.leichtzumer...@gmail.com] > >> Sent: Tuesday, September 25, 2018 7:01 PM > >> To: Huang, Ray > >> Cc: amd-gfx@lists.freedesktop.org > >> Subject: Re: [PATCH 3/9] drm/amdgpu: cleanup amdgpu_ih.c > >> > >> Am 25.09.2018 um 12:28 schrieb Huang Rui: > >>> On Mon, Sep 24, 2018 at 02:38:14PM +0200, Christian König wrote: > Cleanup amdgpu_ih.c to be able to handle multiple interrupt rings. > > Signed-off-by: Christian König > >>> Reviewed-by: Huang Rui > >>> > >>> Will we have multiple interrupt rings in new asic? > >> Vega already has 3 of them, we just haven't activated the other yet. > >> > > Good to know. I just took a look at the spec. IH ring 1 is used for request > > log > and IH ring 2 is used for translation & invalidation log. > > They are to support the page migration feature. Do you plan to work on it? > > Yes, actually the IH is able to route any IV to any ring based on the client > ID, > e.g. who is sending the IV. > > So I'm currently looking into routing the VM faults to ring 2 as well. > That should allow us to better handle them and avoid overwhelming the CPU > with an interrupt storm in case of page faults. I see, thanks for explanation Thanks, Ray > > Regards, > Christian. > > > > > Thanks, > > Ray > > > >> Christian. > >> > >>> Thanks, > >>> Ray > >>> > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | 152 > ++--- > >> --- > drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 8 +- > drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 2 +- > drivers/gpu/drm/amd/amdgpu/cik_ih.c | 4 +- > drivers/gpu/drm/amd/amdgpu/cz_ih.c | 4 +- > drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 4 +- > drivers/gpu/drm/amd/amdgpu/si_ih.c | 4 +- > drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 4 +- > drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 4 +- > 9 files changed, 84 insertions(+), 102 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > index 4ed86218cef3..15fb0f9738ab 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > @@ -26,44 +26,20 @@ > #include "amdgpu_ih.h" > #include "amdgpu_amdkfd.h" > > -/** > - * amdgpu_ih_ring_alloc - allocate memory for the IH ring > - * > - * @adev: amdgpu_device pointer > - * > - * Allocate a ring buffer for the interrupt controller. > - * Returns 0 for success, errors for failure. > - */ > -static int amdgpu_ih_ring_alloc(struct amdgpu_device *adev) -{ > -int r; > - > -/* Allocate ring buffer */ > -if (adev->irq.ih.ring_obj == NULL) { > -r = amdgpu_bo_create_kernel(adev, > adev->irq.ih.ring_size, > -PAGE_SIZE, > >> AMDGPU_GEM_DOMAIN_GTT, > ->irq.ih.ring_obj, > ->irq.ih.gpu_addr, > -(void > **)>irq.ih.ring); > -if (r) { > -DRM_ERROR("amdgpu: failed to create ih ring > buffer > >> (%d).\n", r); > -return r; > -} > -} > -return 0; > -} > - > /** > * amdgpu_ih_ring_init - initialize the IH state > * > * @adev: amdgpu_device pointer > + * @ih: ih ring to initialize > + * @ring_size: ring size to allocate > + * @use_bus_addr: true when we can use dma_alloc_coherent > * > * Initializes the IH state and allocates a buffer > * for the IH ring buffer. > * Returns 0 for success, errors for failure. > */ > -int amdgpu_ih_ring_init(struct amdgpu_device *adev, unsigned > >> ring_size, > -bool use_bus_addr) > +int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct > >> amdgpu_ih_ring *ih, > +unsigned ring_size, bool use_bus_addr) > { > u32 rb_bufsz; > int r; > @@ -71,70 +47,76 @@ int amdgpu_ih_ring_init(struct amdgpu_device > >> *adev, unsigned ring_size, > /* Align ring size */ > rb_bufsz = order_base_2(ring_size / 4); > ring_size = (1 << rb_bufsz) * 4; > -adev->irq.ih.ring_size = ring_size; > -adev->irq.ih.ptr_mask = adev->irq.ih.ring_size - 1;
[PATCH 04/12] drm/amdgpu: move IV prescreening into the GMC code
The GMC/VM subsystem is causing the faults, so move the handling here as well. Signed-off-by: Christian König --- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 59 + drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 69 -- 2 files changed, 59 insertions(+), 69 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index 729a2c230f91..f8d69ab85fc3 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -244,6 +244,62 @@ static int gmc_v9_0_vm_fault_interrupt_state(struct amdgpu_device *adev, return 0; } +/** + * vega10_ih_prescreen_iv - prescreen an interrupt vector + * + * @adev: amdgpu_device pointer + * + * Returns true if the interrupt vector should be further processed. + */ +static bool gmc_v9_0_prescreen_iv(struct amdgpu_device *adev, + struct amdgpu_iv_entry *entry, + uint64_t addr) +{ + struct amdgpu_vm *vm; + u64 key; + int r; + + /* No PASID, can't identify faulting process */ + if (!entry->pasid) + return true; + + /* Not a retry fault */ + if (!(entry->src_data[1] & 0x80)) + return true; + + /* Track retry faults in per-VM fault FIFO. */ + spin_lock(>vm_manager.pasid_lock); + vm = idr_find(>vm_manager.pasid_idr, entry->pasid); + if (!vm) { + /* VM not found, process it normally */ + spin_unlock(>vm_manager.pasid_lock); + return true; + } + + key = AMDGPU_VM_FAULT(entry->pasid, addr); + r = amdgpu_vm_add_fault(vm->fault_hash, key); + + /* Hash table is full or the fault is already being processed, +* ignore further page faults +*/ + if (r != 0) { + spin_unlock(>vm_manager.pasid_lock); + return false; + } + /* No locking required with single writer and single reader */ + r = kfifo_put(>faults, key); + if (!r) { + /* FIFO is full. Ignore it until there is space */ + amdgpu_vm_clear_fault(vm->fault_hash, key); + spin_unlock(>vm_manager.pasid_lock); + return false; + } + + spin_unlock(>vm_manager.pasid_lock); + /* It's the first fault for this address, process it normally */ + return true; +} + static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev, struct amdgpu_irq_src *source, struct amdgpu_iv_entry *entry) @@ -255,6 +311,9 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev, addr = (u64)entry->src_data[0] << 12; addr |= ((u64)entry->src_data[1] & 0xf) << 44; + if (!gmc_v9_0_prescreen_iv(adev, entry, addr)) + return 1; + if (!amdgpu_sriov_vf(adev)) { status = RREG32(hub->vm_l2_pro_fault_status); WREG32_P(hub->vm_l2_pro_fault_cntl, 1, ~1); diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c index 0f50bef87163..0f68a0cd1fbf 100644 --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c @@ -228,76 +228,7 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev) */ static bool vega10_ih_prescreen_iv(struct amdgpu_device *adev) { - u32 ring_index = adev->irq.ih.rptr >> 2; - u32 dw0, dw3, dw4, dw5; - u16 pasid; - u64 addr, key; - struct amdgpu_vm *vm; - int r; - - dw0 = le32_to_cpu(adev->irq.ih.ring[ring_index + 0]); - dw3 = le32_to_cpu(adev->irq.ih.ring[ring_index + 3]); - dw4 = le32_to_cpu(adev->irq.ih.ring[ring_index + 4]); - dw5 = le32_to_cpu(adev->irq.ih.ring[ring_index + 5]); - - /* Filter retry page faults, let only the first one pass. If -* there are too many outstanding faults, ignore them until -* some faults get cleared. -*/ - switch (dw0 & 0xff) { - case SOC15_IH_CLIENTID_VMC: - case SOC15_IH_CLIENTID_UTCL2: - break; - default: - /* Not a VM fault */ - return true; - } - - pasid = dw3 & 0x; - /* No PASID, can't identify faulting process */ - if (!pasid) - return true; - - /* Not a retry fault */ - if (!(dw5 & 0x80)) - return true; - - /* Track retry faults in per-VM fault FIFO. */ - spin_lock(>vm_manager.pasid_lock); - vm = idr_find(>vm_manager.pasid_idr, pasid); - addr = ((u64)(dw5 & 0xf) << 44) | ((u64)dw4 << 12); - key = AMDGPU_VM_FAULT(pasid, addr); - if (!vm) { - /* VM not found, process it normally */ - spin_unlock(>vm_manager.pasid_lock); - return true; - } else { - r =
Re: [PATCH 6/7] drm/amd/pp: Export load_firmware interface
On Wed, Sep 26, 2018 at 8:53 AM Rex Zhu wrote: > > Export this interface for the AMDGPU_FW_LOAD_SMU type. > gfx/sdma can request smu to load firmware. > > Split the smu7/8_start_smu function into two functions > 1. start_smu, used for load smu firmware in smu7/8 and >check smu firmware version. > 2. request_smu_load_fw, used for load other ip's firmware >on smu7/8 and add firmware loading staus check. > > Signed-off-by: Rex Zhu Don't we need to convert sdma to use this interface as well? Alex > --- > drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 11 +++- > drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 14 +++-- > drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c | 4 +- > .../gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c | 25 - > .../drm/amd/powerplay/smumgr/polaris10_smumgr.c| 4 +- > drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c | 59 > +- > drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h | 3 +- > drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c | 46 - > .../gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c| 12 - > .../gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c| 4 +- > 10 files changed, 79 insertions(+), 103 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c > b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c > index 2aeef2b..f020f6f 100644 > --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c > @@ -4216,10 +4216,17 @@ static int gfx_v8_0_rlc_resume(struct amdgpu_device > *adev) > if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) { > /* legacy rlc firmware loading */ > r = gfx_v8_0_rlc_load_microcode(adev); > - if (r) > - return r; > + } else if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU && > adev->powerplay.pp_funcs->load_firmware) { > + amdgpu_ucode_init_bo(adev); > + r = > adev->powerplay.pp_funcs->load_firmware(adev->powerplay.pp_handle); > + } else { > + r = -EINVAL; > } > > + if (r) { > + pr_err("firmware loading failed\n"); > + return r; > + } > gfx_v8_0_rlc_start(adev); > > return 0; > diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c > b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c > index aff7c14..3bc825c 100644 > --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c > +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c > @@ -124,9 +124,6 @@ static int pp_hw_init(void *handle) > struct amdgpu_device *adev = handle; > struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; > > - if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU) > - amdgpu_ucode_init_bo(adev); > - > ret = hwmgr_hw_init(hwmgr); > > if (ret) > @@ -275,7 +272,16 @@ static int pp_set_clockgating_state(void *handle, > > static int pp_dpm_load_fw(void *handle) > { > - return 0; > + struct pp_hwmgr *hwmgr = handle; > + int ret = 0; > + > + if (!hwmgr || !hwmgr->smumgr_funcs) > + return -EINVAL; > + > + if (hwmgr->smumgr_funcs->request_smu_load_fw) > + ret = hwmgr->smumgr_funcs->request_smu_load_fw(hwmgr); > + > + return ret; > } > > static int pp_dpm_fw_loading_complete(void *handle) > diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c > b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c > index b6b62a7..ffd7d78 100644 > --- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c > +++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c > @@ -310,8 +310,6 @@ static int fiji_start_smu(struct pp_hwmgr *hwmgr) > offsetof(SMU73_Firmware_Header, SoftRegisters), > &(priv->smu7_data.soft_regs_start), 0x4); > > - result = smu7_request_smu_load_fw(hwmgr); > - > return result; > } > > @@ -2643,7 +2641,7 @@ static int fiji_update_dpm_settings(struct pp_hwmgr > *hwmgr, > .smu_fini = _smu_fini, > .start_smu = _start_smu, > .check_fw_load_finish = _check_fw_load_finish, > - .request_smu_load_fw = _reload_firmware, > + .request_smu_load_fw = _request_smu_load_fw, > .request_smu_load_specific_fw = NULL, > .send_msg_to_smc = _send_msg_to_smc, > .send_msg_to_smc_with_parameter = > _send_msg_to_smc_with_parameter, > diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c > b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c > index 73aa368..68a4836 100644 > --- a/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c > +++ b/drivers/gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c > @@ -232,27 +232,24 @@ static int iceland_request_smu_load_specific_fw(struct > pp_hwmgr *hwmgr, > > static int iceland_start_smu(struct pp_hwmgr *hwmgr) > { > - int result; > - > - result = iceland_smu_upload_firmware_image(hwmgr); >
Re: [PATCH 5/7] drm/amd/pp: Remove useless code in smu
On Wed, Sep 26, 2018 at 8:52 AM Rex Zhu wrote: > > Signed-off-by: Rex Zhu Please describe why the code is useless and can be removed. Thanks, Alex > --- > drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c| 1 - > drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | 1 - > drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c | 5 - > drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c | 5 - > 4 files changed, 12 deletions(-) > > diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c > b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c > index 7500a3e..7844256 100644 > --- a/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c > +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hwmgr.c > @@ -89,7 +89,6 @@ int hwmgr_early_init(struct pp_hwmgr *hwmgr) > hwmgr_init_default_caps(hwmgr); > hwmgr_set_user_specify_caps(hwmgr); > hwmgr->fan_ctrl_is_in_default_mode = true; > - hwmgr->reload_fw = 1; > hwmgr_init_workload_prority(hwmgr); > > switch (hwmgr->chip_family) { > diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h > b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h > index d1183b1..b691fca 100644 > --- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h > +++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h > @@ -733,7 +733,6 @@ struct pp_hwmgr { > void *smu_backend; > const struct pp_smumgr_func *smumgr_funcs; > bool is_kicker; > - bool reload_fw; > > enum PP_DAL_POWERLEVEL dal_power_level; > struct phm_dynamic_state_info dyn_state; > diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c > b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c > index 186dafc..10eb967 100644 > --- a/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c > +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c > @@ -381,11 +381,6 @@ int smu7_request_smu_load_fw(struct pp_hwmgr *hwmgr) > uint32_t fw_to_load; > int r = 0; > > - if (!hwmgr->reload_fw) { > - pr_info("skip reloading...\n"); > - return 0; > - } > - > if (smu_data->soft_regs_start) > cgs_write_ind_register(hwmgr->device, CGS_IND_REG__SMC, > smu_data->soft_regs_start + > smum_get_offsetof(hwmgr, > diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c > b/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c > index a74c5be..7a4c425 100644 > --- a/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c > +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c > @@ -659,11 +659,6 @@ static int smu8_request_smu_load_fw(struct pp_hwmgr > *hwmgr) > struct smu8_smumgr *smu8_smu = hwmgr->smu_backend; > uint32_t smc_address; > > - if (!hwmgr->reload_fw) { > - pr_info("skip reloading...\n"); > - return 0; > - } > - > smu8_smu_populate_firmware_entries(hwmgr); > > smu8_smu_construct_toc(hwmgr); > -- > 1.9.1 > > ___ > amd-gfx mailing list > amd-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 2/7] drm/amdgpu: Move out power up/down sdma out of smu
On Wed, Sep 26, 2018 at 8:52 AM Rex Zhu wrote: > > smu only expose interface to other ip blocks. > in order to reduce dependence between smu and other ip blocks > > Signed-off-by: Rex Zhu Reviewed-by: Alex Deucher > --- > drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 6 ++ > drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c | 1 + > drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c | 15 --- > 3 files changed, 7 insertions(+), 15 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c > b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c > index 12e577c..c20d413 100644 > --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c > @@ -1364,6 +1364,9 @@ static int sdma_v4_0_hw_init(void *handle) > int r; > struct amdgpu_device *adev = (struct amdgpu_device *)handle; > > + if (adev->asic_type == CHIP_RAVEN && > adev->powerplay.pp_funcs->set_powergating_by_smu) > + amdgpu_dpm_set_powergating_by_smu(adev, > AMD_IP_BLOCK_TYPE_SDMA, false); > + > sdma_v4_0_init_golden_registers(adev); > > r = sdma_v4_0_start(adev); > @@ -1381,6 +1384,9 @@ static int sdma_v4_0_hw_fini(void *handle) > sdma_v4_0_ctx_switch_enable(adev, false); > sdma_v4_0_enable(adev, false); > > + if (adev->asic_type == CHIP_RAVEN && > adev->powerplay.pp_funcs->set_powergating_by_smu) > + amdgpu_dpm_set_powergating_by_smu(adev, > AMD_IP_BLOCK_TYPE_SDMA, true); > + > return 0; > } > > diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c > b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c > index b7a9d0c..dd18cb7 100644 > --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c > +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c > @@ -1216,6 +1216,7 @@ static void smu10_powergate_vcn(struct pp_hwmgr *hwmgr, > bool bgate) > .smus_notify_pwe = smu10_smus_notify_pwe, > .display_clock_voltage_request = smu10_display_clock_voltage_request, > .powergate_gfx = smu10_gfx_off_control, > + .powergate_sdma = smu10_powergate_sdma, > }; > > int smu10_init_function_pointers(struct pp_hwmgr *hwmgr) > diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c > b/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c > index 6f961de..d78d864 100644 > --- a/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c > +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c > @@ -186,19 +186,6 @@ static int smu10_verify_smc_interface(struct pp_hwmgr > *hwmgr) > return 0; > } > > -/* sdma is disabled by default in vbios, need to re-enable in driver */ > -static void smu10_smc_enable_sdma(struct pp_hwmgr *hwmgr) > -{ > - smu10_send_msg_to_smc(hwmgr, > - PPSMC_MSG_PowerUpSdma); > -} > - > -static void smu10_smc_disable_sdma(struct pp_hwmgr *hwmgr) > -{ > - smu10_send_msg_to_smc(hwmgr, > - PPSMC_MSG_PowerDownSdma); > -} > - > /* vcn is disabled by default in vbios, need to re-enable in driver */ > static void smu10_smc_enable_vcn(struct pp_hwmgr *hwmgr) > { > @@ -218,7 +205,6 @@ static int smu10_smu_fini(struct pp_hwmgr *hwmgr) > (struct smu10_smumgr *)(hwmgr->smu_backend); > > if (priv) { > - smu10_smc_disable_sdma(hwmgr); > smu10_smc_disable_vcn(hwmgr); > > amdgpu_bo_free_kernel(>smu_tables.entry[SMU10_WMTABLE].handle, > > >smu_tables.entry[SMU10_WMTABLE].mc_addr, > @@ -243,7 +229,6 @@ static int smu10_start_smu(struct pp_hwmgr *hwmgr) > > if (smu10_verify_smc_interface(hwmgr)) > return -EINVAL; > - smu10_smc_enable_sdma(hwmgr); > smu10_smc_enable_vcn(hwmgr); > return 0; > } > -- > 1.9.1 > > ___ > amd-gfx mailing list > amd-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 3/7] drm/amd/pp: Remove uncessary extra vcn pg cntl in smu
On Wed, Sep 26, 2018 at 8:52 AM Rex Zhu wrote: > > the vcn power will be controlled by VCN. > > Signed-off-by: Rex Zhu Reviewed-by: Alex Deucher > --- > drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c | 16 +--- > 1 file changed, 1 insertion(+), 15 deletions(-) > > diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c > b/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c > index d78d864..d0eb8ab 100644 > --- a/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c > +++ b/drivers/gpu/drm/amd/powerplay/smumgr/smu10_smumgr.c > @@ -186,26 +186,12 @@ static int smu10_verify_smc_interface(struct pp_hwmgr > *hwmgr) > return 0; > } > > -/* vcn is disabled by default in vbios, need to re-enable in driver */ > -static void smu10_smc_enable_vcn(struct pp_hwmgr *hwmgr) > -{ > - smu10_send_msg_to_smc_with_parameter(hwmgr, > - PPSMC_MSG_PowerUpVcn, 0); > -} > - > -static void smu10_smc_disable_vcn(struct pp_hwmgr *hwmgr) > -{ > - smu10_send_msg_to_smc_with_parameter(hwmgr, > - PPSMC_MSG_PowerDownVcn, 0); > -} > - > static int smu10_smu_fini(struct pp_hwmgr *hwmgr) > { > struct smu10_smumgr *priv = > (struct smu10_smumgr *)(hwmgr->smu_backend); > > if (priv) { > - smu10_smc_disable_vcn(hwmgr); > > amdgpu_bo_free_kernel(>smu_tables.entry[SMU10_WMTABLE].handle, > > >smu_tables.entry[SMU10_WMTABLE].mc_addr, > > >smu_tables.entry[SMU10_WMTABLE].table); > @@ -229,7 +215,7 @@ static int smu10_start_smu(struct pp_hwmgr *hwmgr) > > if (smu10_verify_smc_interface(hwmgr)) > return -EINVAL; > - smu10_smc_enable_vcn(hwmgr); > + > return 0; > } > > -- > 1.9.1 > > ___ > amd-gfx mailing list > amd-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 4/7] drm/amd/pp: Remove wrong code in fiji_start_smu
On Wed, Sep 26, 2018 at 8:52 AM Rex Zhu wrote: > > HW CG feature will be enabled after hw ip initialized > > Signed-off-by: Rex Zhu Reviewed-by: Alex Deucher > --- > drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c | 10 -- > 1 file changed, 10 deletions(-) > > diff --git a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c > b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c > index ec14798..b6b62a7 100644 > --- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c > +++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c > @@ -302,16 +302,6 @@ static int fiji_start_smu(struct pp_hwmgr *hwmgr) > hwmgr->avfs_supported = false; > } > > - /* To initialize all clock gating before RLC loaded and running.*/ > - amdgpu_device_ip_set_clockgating_state(hwmgr->adev, > - AMD_IP_BLOCK_TYPE_GFX, AMD_CG_STATE_GATE); > - amdgpu_device_ip_set_clockgating_state(hwmgr->adev, > - AMD_IP_BLOCK_TYPE_GMC, AMD_CG_STATE_GATE); > - amdgpu_device_ip_set_clockgating_state(hwmgr->adev, > - AMD_IP_BLOCK_TYPE_SDMA, AMD_CG_STATE_GATE); > - amdgpu_device_ip_set_clockgating_state(hwmgr->adev, > - AMD_IP_BLOCK_TYPE_COMMON, AMD_CG_STATE_GATE); > - > /* Setup SoftRegsStart here for register lookup in case > * DummyBackEnd is used and ProcessFirmwareHeader is not executed > */ > -- > 1.9.1 > > ___ > amd-gfx mailing list > amd-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH -next] drm/amdgpu: remove set but not used variable 'header'
Fixes gcc '-Wunused-but-set-variable' warning: drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c: In function 'amdgpu_ucode_init_bo': drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c:431:39: warning: variable 'header' set but not used [-Wunused-but-set-variable] Signed-off-by: YueHaibing --- drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c index 1fa8bc3..afd5cf3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c @@ -428,7 +428,6 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev) uint64_t fw_offset = 0; int i, err; struct amdgpu_firmware_info *ucode = NULL; - const struct common_firmware_header *header = NULL; if (!adev->firmware.fw_size) { dev_warn(adev->dev, "No ip firmware need to load\n"); @@ -465,7 +464,6 @@ int amdgpu_ucode_init_bo(struct amdgpu_device *adev) for (i = 0; i < adev->firmware.max_ucodes; i++) { ucode = >firmware.ucode[i]; if (ucode->fw) { - header = (const struct common_firmware_header *)ucode->fw->data; amdgpu_ucode_init_single_fw(adev, ucode, adev->firmware.fw_buf_mc + fw_offset, adev->firmware.fw_buf_ptr + fw_offset); if (i == AMDGPU_UCODE_ID_CP_MEC1 && ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
RE: [PATCH 6/7] drm/amd/pp: Export load_firmware interface
> -Original Message- > From: Alex Deucher > Sent: Wednesday, September 26, 2018 10:15 PM > To: Zhu, Rex > Cc: amd-gfx list > Subject: Re: [PATCH 6/7] drm/amd/pp: Export load_firmware interface > > On Wed, Sep 26, 2018 at 8:53 AM Rex Zhu wrote: > > > > Export this interface for the AMDGPU_FW_LOAD_SMU type. > > gfx/sdma can request smu to load firmware. > > > > Split the smu7/8_start_smu function into two functions 1. start_smu, > > used for load smu firmware in smu7/8 and > >check smu firmware version. > > 2. request_smu_load_fw, used for load other ip's firmware > >on smu7/8 and add firmware loading staus check. > > > > Signed-off-by: Rex Zhu > > Don't we need to convert sdma to use this interface as well? When load firmware via smu, I load all the firmwares(rlc/ce/pfp/me/mec/sdma) at one time. So just need to call the interface when load rlc firmware. We also can load the firmware separately with ucode mask. > Alex > > > --- > > drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 11 +++- > > drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 14 +++-- > > drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c | 4 +- > > .../gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c | 25 - > > .../drm/amd/powerplay/smumgr/polaris10_smumgr.c| 4 +- > > drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c | 59 > > +- > > drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h | 3 +- > drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c | 46 -- > --- > > .../gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c| 12 - > > .../gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c| 4 +- > > 10 files changed, 79 insertions(+), 103 deletions(-) > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c > > b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c > > index 2aeef2b..f020f6f 100644 > > --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c > > +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c > > @@ -4216,10 +4216,17 @@ static int gfx_v8_0_rlc_resume(struct > amdgpu_device *adev) > > if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) { > > /* legacy rlc firmware loading */ > > r = gfx_v8_0_rlc_load_microcode(adev); > > - if (r) > > - return r; > > + } else if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU && > adev->powerplay.pp_funcs->load_firmware) { > > + amdgpu_ucode_init_bo(adev); > > + r = adev->powerplay.pp_funcs->load_firmware(adev- > >powerplay.pp_handle); > > + } else { > > + r = -EINVAL; > > } > > > > + if (r) { > > + pr_err("firmware loading failed\n"); > > + return r; > > + } > > gfx_v8_0_rlc_start(adev); > > > > return 0; > > diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c > > b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c > > index aff7c14..3bc825c 100644 > > --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c > > +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c > > @@ -124,9 +124,6 @@ static int pp_hw_init(void *handle) > > struct amdgpu_device *adev = handle; > > struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; > > > > - if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU) > > - amdgpu_ucode_init_bo(adev); > > - > > ret = hwmgr_hw_init(hwmgr); > > > > if (ret) > > @@ -275,7 +272,16 @@ static int pp_set_clockgating_state(void *handle, > > > > static int pp_dpm_load_fw(void *handle) { > > - return 0; > > + struct pp_hwmgr *hwmgr = handle; > > + int ret = 0; > > + > > + if (!hwmgr || !hwmgr->smumgr_funcs) > > + return -EINVAL; > > + > > + if (hwmgr->smumgr_funcs->request_smu_load_fw) > > + ret = hwmgr->smumgr_funcs->request_smu_load_fw(hwmgr); > > + > > + return ret; > > } > > > > static int pp_dpm_fw_loading_complete(void *handle) diff --git > > a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c > > b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c > > index b6b62a7..ffd7d78 100644 > > --- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c > > +++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c > > @@ -310,8 +310,6 @@ static int fiji_start_smu(struct pp_hwmgr *hwmgr) > > offsetof(SMU73_Firmware_Header, SoftRegisters), > > &(priv->smu7_data.soft_regs_start), 0x4); > > > > - result = smu7_request_smu_load_fw(hwmgr); > > - > > return result; > > } > > > > @@ -2643,7 +2641,7 @@ static int fiji_update_dpm_settings(struct > pp_hwmgr *hwmgr, > > .smu_fini = _smu_fini, > > .start_smu = _start_smu, > > .check_fw_load_finish = _check_fw_load_finish, > > - .request_smu_load_fw = _reload_firmware, > > + .request_smu_load_fw = _request_smu_load_fw, > > .request_smu_load_specific_fw = NULL, > > .send_msg_to_smc =
Re: [PATCH 6/7] drm/amd/pp: Export load_firmware interface
On Wed, Sep 26, 2018 at 11:21 AM Zhu, Rex wrote: > > > > > -Original Message- > > From: Alex Deucher > > Sent: Wednesday, September 26, 2018 10:15 PM > > To: Zhu, Rex > > Cc: amd-gfx list > > Subject: Re: [PATCH 6/7] drm/amd/pp: Export load_firmware interface > > > > On Wed, Sep 26, 2018 at 8:53 AM Rex Zhu wrote: > > > > > > Export this interface for the AMDGPU_FW_LOAD_SMU type. > > > gfx/sdma can request smu to load firmware. > > > > > > Split the smu7/8_start_smu function into two functions 1. start_smu, > > > used for load smu firmware in smu7/8 and > > >check smu firmware version. > > > 2. request_smu_load_fw, used for load other ip's firmware > > >on smu7/8 and add firmware loading staus check. > > > > > > Signed-off-by: Rex Zhu > > > > Don't we need to convert sdma to use this interface as well? > > When load firmware via smu, I load all the firmwares(rlc/ce/pfp/me/mec/sdma) > at one time. > So just need to call the interface when load rlc firmware. > We also can load the firmware separately with ucode mask. I see. So we rely on the call from the gfx IP to load all the FWs. It might be better to be more explicit. E.g., if someone disables the gfx IP via the ip_block_mask parameter, that would break sdma. Alex > > > > Alex > > > > > --- > > > drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 11 +++- > > > drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 14 +++-- > > > drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c | 4 +- > > > .../gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c | 25 - > > > .../drm/amd/powerplay/smumgr/polaris10_smumgr.c| 4 +- > > > drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c | 59 > > > +- > > > drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h | 3 +- > > drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c | 46 -- > > --- > > > .../gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c| 12 - > > > .../gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c| 4 +- > > > 10 files changed, 79 insertions(+), 103 deletions(-) > > > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c > > > b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c > > > index 2aeef2b..f020f6f 100644 > > > --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c > > > +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c > > > @@ -4216,10 +4216,17 @@ static int gfx_v8_0_rlc_resume(struct > > amdgpu_device *adev) > > > if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) { > > > /* legacy rlc firmware loading */ > > > r = gfx_v8_0_rlc_load_microcode(adev); > > > - if (r) > > > - return r; > > > + } else if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU && > > adev->powerplay.pp_funcs->load_firmware) { > > > + amdgpu_ucode_init_bo(adev); > > > + r = adev->powerplay.pp_funcs->load_firmware(adev- > > >powerplay.pp_handle); > > > + } else { > > > + r = -EINVAL; > > > } > > > > > > + if (r) { > > > + pr_err("firmware loading failed\n"); > > > + return r; > > > + } > > > gfx_v8_0_rlc_start(adev); > > > > > > return 0; > > > diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c > > > b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c > > > index aff7c14..3bc825c 100644 > > > --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c > > > +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c > > > @@ -124,9 +124,6 @@ static int pp_hw_init(void *handle) > > > struct amdgpu_device *adev = handle; > > > struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; > > > > > > - if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU) > > > - amdgpu_ucode_init_bo(adev); > > > - > > > ret = hwmgr_hw_init(hwmgr); > > > > > > if (ret) > > > @@ -275,7 +272,16 @@ static int pp_set_clockgating_state(void *handle, > > > > > > static int pp_dpm_load_fw(void *handle) { > > > - return 0; > > > + struct pp_hwmgr *hwmgr = handle; > > > + int ret = 0; > > > + > > > + if (!hwmgr || !hwmgr->smumgr_funcs) > > > + return -EINVAL; > > > + > > > + if (hwmgr->smumgr_funcs->request_smu_load_fw) > > > + ret = hwmgr->smumgr_funcs->request_smu_load_fw(hwmgr); > > > + > > > + return ret; > > > } > > > > > > static int pp_dpm_fw_loading_complete(void *handle) diff --git > > > a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c > > > b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c > > > index b6b62a7..ffd7d78 100644 > > > --- a/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c > > > +++ b/drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c > > > @@ -310,8 +310,6 @@ static int fiji_start_smu(struct pp_hwmgr *hwmgr) > > > offsetof(SMU73_Firmware_Header, SoftRegisters), > > > &(priv->smu7_data.soft_regs_start), 0x4); > > > > > > - result =
RE: [PATCH 6/7] drm/amd/pp: Export load_firmware interface
> -Original Message- > From: Alex Deucher > Sent: Wednesday, September 26, 2018 11:39 PM > To: Zhu, Rex > Cc: amd-gfx list > Subject: Re: [PATCH 6/7] drm/amd/pp: Export load_firmware interface > > On Wed, Sep 26, 2018 at 11:21 AM Zhu, Rex wrote: > > > > > > > > > -Original Message- > > > From: Alex Deucher > > > Sent: Wednesday, September 26, 2018 10:15 PM > > > To: Zhu, Rex > > > Cc: amd-gfx list > > > Subject: Re: [PATCH 6/7] drm/amd/pp: Export load_firmware interface > > > > > > On Wed, Sep 26, 2018 at 8:53 AM Rex Zhu wrote: > > > > > > > > Export this interface for the AMDGPU_FW_LOAD_SMU type. > > > > gfx/sdma can request smu to load firmware. > > > > > > > > Split the smu7/8_start_smu function into two functions 1. > > > > start_smu, used for load smu firmware in smu7/8 and > > > >check smu firmware version. > > > > 2. request_smu_load_fw, used for load other ip's firmware > > > >on smu7/8 and add firmware loading staus check. > > > > > > > > Signed-off-by: Rex Zhu > > > > > > Don't we need to convert sdma to use this interface as well? > > > > When load firmware via smu, I load all the > firmwares(rlc/ce/pfp/me/mec/sdma) at one time. > > So just need to call the interface when load rlc firmware. > > We also can load the firmware separately with ucode mask. > > I see. So we rely on the call from the gfx IP to load all the FWs. > It might be better to be more explicit. E.g., if someone disables the gfx IP > via > the ip_block_mask parameter, that would break sdma. I didn't consider that aspect. We can load firmware separately with ucode_id. Or just call this function again in sdma to load all the firmware. When firmware is loaded , clean the reload_fw in Patch5. Best Regards Rex > Alex > > > > > > > > Alex > > > > > > > --- > > > > drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 11 +++- > > > > drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 14 +++-- > > > > drivers/gpu/drm/amd/powerplay/smumgr/fiji_smumgr.c | 4 +- > > > > .../gpu/drm/amd/powerplay/smumgr/iceland_smumgr.c | 25 - > > > > .../drm/amd/powerplay/smumgr/polaris10_smumgr.c| 4 +- > > > > drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.c | 59 > > > > +- > > > > drivers/gpu/drm/amd/powerplay/smumgr/smu7_smumgr.h | 3 +- > > > drivers/gpu/drm/amd/powerplay/smumgr/smu8_smumgr.c | 46 > -- > > > --- > > > > .../gpu/drm/amd/powerplay/smumgr/tonga_smumgr.c| 12 - > > > > .../gpu/drm/amd/powerplay/smumgr/vegam_smumgr.c| 4 +- > > > > 10 files changed, 79 insertions(+), 103 deletions(-) > > > > > > > > diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c > > > > b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c > > > > index 2aeef2b..f020f6f 100644 > > > > --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c > > > > +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c > > > > @@ -4216,10 +4216,17 @@ static int gfx_v8_0_rlc_resume(struct > > > amdgpu_device *adev) > > > > if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) { > > > > /* legacy rlc firmware loading */ > > > > r = gfx_v8_0_rlc_load_microcode(adev); > > > > - if (r) > > > > - return r; > > > > + } else if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU > > > > + && > > > adev->powerplay.pp_funcs->load_firmware) { > > > > + amdgpu_ucode_init_bo(adev); > > > > + r = adev->powerplay.pp_funcs->load_firmware(adev- > > > >powerplay.pp_handle); > > > > + } else { > > > > + r = -EINVAL; > > > > } > > > > > > > > + if (r) { > > > > + pr_err("firmware loading failed\n"); > > > > + return r; > > > > + } > > > > gfx_v8_0_rlc_start(adev); > > > > > > > > return 0; > > > > diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c > > > > b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c > > > > index aff7c14..3bc825c 100644 > > > > --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c > > > > +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c > > > > @@ -124,9 +124,6 @@ static int pp_hw_init(void *handle) > > > > struct amdgpu_device *adev = handle; > > > > struct pp_hwmgr *hwmgr = adev->powerplay.pp_handle; > > > > > > > > - if (adev->firmware.load_type == AMDGPU_FW_LOAD_SMU) > > > > - amdgpu_ucode_init_bo(adev); > > > > - > > > > ret = hwmgr_hw_init(hwmgr); > > > > > > > > if (ret) > > > > @@ -275,7 +272,16 @@ static int pp_set_clockgating_state(void > > > > *handle, > > > > > > > > static int pp_dpm_load_fw(void *handle) { > > > > - return 0; > > > > + struct pp_hwmgr *hwmgr = handle; > > > > + int ret = 0; > > > > + > > > > + if (!hwmgr || !hwmgr->smumgr_funcs) > > > > + return -EINVAL; > > > > + > > > > + if (hwmgr->smumgr_funcs->request_smu_load_fw) > > > > + ret = > > > > +
Re: [PATCH 1/7] drm/amd/pp: Expose the smu support for SDMA PG cntl
On Wed, Sep 26, 2018 at 8:51 AM Rex Zhu wrote: > > SDMA IP can be power up/down via smu message > > Signed-off-by: Rex Zhu Reviewed-by: Alex Deucher > --- > drivers/gpu/drm/amd/powerplay/amd_powerplay.c | 18 ++ > drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c | 8 > drivers/gpu/drm/amd/powerplay/inc/hwmgr.h | 1 + > 3 files changed, 27 insertions(+) > > diff --git a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c > b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c > index 53d3337..aff7c14 100644 > --- a/drivers/gpu/drm/amd/powerplay/amd_powerplay.c > +++ b/drivers/gpu/drm/amd/powerplay/amd_powerplay.c > @@ -1214,6 +1214,21 @@ static void pp_dpm_powergate_acp(void *handle, bool > gate) > hwmgr->hwmgr_func->powergate_acp(hwmgr, gate); > } > > +static void pp_dpm_powergate_sdma(void *handle, bool gate) > +{ > + struct pp_hwmgr *hwmgr = handle; > + > + if (!hwmgr) > + return; > + > + if (hwmgr->hwmgr_func->powergate_sdma == NULL) { > + pr_info("%s was not implemented.\n", __func__); > + return; > + } > + > + hwmgr->hwmgr_func->powergate_sdma(hwmgr, gate); > +} > + > static int pp_set_powergating_by_smu(void *handle, > uint32_t block_type, bool gate) > { > @@ -1236,6 +1251,9 @@ static int pp_set_powergating_by_smu(void *handle, > case AMD_IP_BLOCK_TYPE_ACP: > pp_dpm_powergate_acp(handle, gate); > break; > + case AMD_IP_BLOCK_TYPE_SDMA: > + pp_dpm_powergate_sdma(handle, gate); > + break; > default: > break; > } > diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c > b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c > index 5d1dae2..b7a9d0c 100644 > --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c > +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c > @@ -1153,6 +1153,14 @@ static int smu10_powergate_mmhub(struct pp_hwmgr > *hwmgr) > return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PowerGateMmHub); > } > > +static int smu10_powergate_sdma(struct pp_hwmgr *hwmgr, bool gate) > +{ > + if (gate) > + return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PowerDownSdma); > + else > + return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PowerUpSdma); > +} > + > static void smu10_powergate_vcn(struct pp_hwmgr *hwmgr, bool bgate) > { > if (bgate) { > diff --git a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h > b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h > index a6d9212..d1183b1 100644 > --- a/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h > +++ b/drivers/gpu/drm/amd/powerplay/inc/hwmgr.h > @@ -328,6 +328,7 @@ struct pp_hwmgr_func { > int (*set_power_limit)(struct pp_hwmgr *hwmgr, uint32_t n); > int (*powergate_mmhub)(struct pp_hwmgr *hwmgr); > int (*smus_notify_pwe)(struct pp_hwmgr *hwmgr); > + int (*powergate_sdma)(struct pp_hwmgr *hwmgr, bool bgate); > }; > > struct pp_table_func { > -- > 1.9.1 > > ___ > amd-gfx mailing list > amd-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 2/2] drm/amdgpu/vcn: whitespace cleanup
Fix some indentation issues. Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 36 - 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index c6dd8403414f..2a2eb0143f48 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -214,7 +214,7 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev) } static int amdgpu_vcn_pause_dpg_mode(struct amdgpu_device *adev, - struct dpg_pause_state *new_state) +struct dpg_pause_state *new_state) { int ret_code; uint32_t reg_data = 0; @@ -228,23 +228,23 @@ static int amdgpu_vcn_pause_dpg_mode(struct amdgpu_device *adev, new_state->fw_based, new_state->jpeg); reg_data = RREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE) & - (~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK); + (~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK); if (new_state->fw_based == VCN_DPG_STATE__PAUSE) { ret_code = 0; if (!(reg_data & UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK)) SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS, - UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF, - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code); + UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF, + UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code); if (!ret_code) { /* pause DPG non-jpeg */ reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK; WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data); SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_DPG_PAUSE, - UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK, - UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK, ret_code); + UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK, + UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK, ret_code); /* Restore */ ring = >vcn.ring_enc[0]; @@ -252,7 +252,7 @@ static int amdgpu_vcn_pause_dpg_mode(struct amdgpu_device *adev, WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE, ring->ring_size / 4); WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR, lower_32_bits(ring->wptr)); - WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR, lower_32_bits(ring->wptr)); + WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR, lower_32_bits(ring->wptr)); ring = >vcn.ring_enc[1]; WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO2, ring->gpu_addr); @@ -263,10 +263,10 @@ static int amdgpu_vcn_pause_dpg_mode(struct amdgpu_device *adev, ring = >vcn.ring_dec; WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR, - lower_32_bits(ring->wptr) | 0x8000); +lower_32_bits(ring->wptr) | 0x8000); SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS, - UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON, - UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code); + UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON, + UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code); } } else { /* unpause dpg non-jpeg, no need to wait */ @@ -283,15 +283,15 @@ static int amdgpu_vcn_pause_dpg_mode(struct amdgpu_device *adev, new_state->fw_based, new_state->jpeg); reg_data = RREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE) & - (~UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK); + (~UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK); if (new_state->jpeg == VCN_DPG_STATE__PAUSE) { ret_code = 0; if
Re: [PATCH] drm/amdkfd: Remove the requirement for atomic Ops on vg20
Acked-by: Alex Deucher From: amd-gfx on behalf of Kent Russell Sent: Wednesday, September 26, 2018 9:41:52 AM To: amd-gfx@lists.freedesktop.org Cc: Russell, Kent; Liu, Shaoyun Subject: [PATCH] drm/amdkfd: Remove the requirement for atomic Ops on vg20 From: Shaoyun Liu Firmware have the workaround to replace the atomic Ops with read-modify-write on CP side. User should not expect atomic Ops on system memory works normally if system didn't not support it. Change-Id: I89395b099fe0931b9b3627651b512dde3149fadd Signed-off-by: Shaoyun Liu Signed-off-by: Kent Russell --- drivers/gpu/drm/amd/amdkfd/kfd_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index b0c2afb..b505bf3 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -263,7 +263,7 @@ static const struct kfd_device_info vega20_device_info = { .mqd_size_aligned = MQD_SIZE_ALIGNED, .supports_cwsr = true, .needs_iommu_device = false, - .needs_pci_atomics = true, + .needs_pci_atomics = false, .num_sdma_engines = 2, .num_sdma_queues_per_engine = 8, }; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 1/2] drm/amdgpu/soc15: fix warnings in register macro
On 2018-09-26 12:25 PM, Alex Deucher wrote: expects argument of type ‘unsigned int’ has type ‘long int’ Fixes: 52e211c1f04 ("drm/amdgpu:Add error message when register failed to reach expected value") Signed-off-by: Alex Deucher Reviewed-by: James Zhu for the series. --- drivers/gpu/drm/amd/amdgpu/soc15_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/soc15_common.h b/drivers/gpu/drm/amd/amdgpu/soc15_common.h index d35fac5b5a8a..958b10a57073 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15_common.h +++ b/drivers/gpu/drm/amd/amdgpu/soc15_common.h @@ -57,7 +57,7 @@ loop--; \ if (!loop) {\ DRM_ERROR("Register(%d) [%s] failed to reach value 0x%08x != 0x%08x\n", \ - inst, #reg, expected_value, (tmp_ & (mask))); \ + inst, #reg, (unsigned)expected_value, (unsigned)(tmp_ & (mask))); \ ret = -ETIMEDOUT; \ break; \ } \ ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 06/16] drm/amd/display: block DP YCbCr420 modes
From: Eric Yang [why] Currently not supported, will black screen when set. [How] Fail validate timing helper for those modes. Signed-off-by: Eric Yang Reviewed-by: Tony Cheng Acked-by: Leo Li --- drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c | 3 +++ drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c index 4942590..70eb9472 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c @@ -662,6 +662,9 @@ bool dce110_link_encoder_validate_dp_output( const struct dce110_link_encoder *enc110, const struct dc_crtc_timing *crtc_timing) { + if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) + return false; + /* default RGB only */ if (crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB) return true; diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c index 6f67520..bef0011 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c @@ -606,6 +606,9 @@ bool dcn10_link_encoder_validate_dp_output( const struct dcn10_link_encoder *enc10, const struct dc_crtc_timing *crtc_timing) { + if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) + return false; + /* default RGB only */ if (crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB) return true; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 04/16] drm/amd/display: Calculate swizzle mode using bpp during validation
From: Su Sung Chung [Why] Previously bandwidth validation was failing because swizzle mode was not initialized during plane_state allocation. The swizzle mode was calculated using pixed format which is how swizzle mode is initially calculated in addrlib. [How] * Set default swizzle mode for validation to DC_SW_UNKNOWN * Created new function in dcn10_assign_swizzle_mode which sets the plane swizzle mode based on selected pixed format * Added the call of assign_swizzle_mode into dc_validate_global_state * Set failsafe swizzle mode back to DC_SW_LINEAR Signed-off-by: Su Sung Chung Reviewed-by: Eric Yang Acked-by: Leo Li --- drivers/gpu/drm/amd/display/dc/core/dc.c | 30 ++ drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 37 ++ drivers/gpu/drm/amd/display/dc/dc_hw_types.h | 3 +- .../gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 21 +++- drivers/gpu/drm/amd/display/dc/inc/core_types.h| 3 ++ drivers/gpu/drm/amd/display/dc/inc/resource.h | 3 ++ 6 files changed, 67 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 99ecaeb..a0e933f 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -1113,32 +1113,6 @@ static bool is_surface_in_context( return false; } -static unsigned int pixel_format_to_bpp(enum surface_pixel_format format) -{ - switch (format) { - case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr: - case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb: - return 12; - case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555: - case SURFACE_PIXEL_FORMAT_GRPH_RGB565: - case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr: - case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb: - return 16; - case SURFACE_PIXEL_FORMAT_GRPH_ARGB: - case SURFACE_PIXEL_FORMAT_GRPH_ABGR: - case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: - case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: - return 32; - case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: - case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: - case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: - return 64; - default: - ASSERT_CRITICAL(false); - return -1; - } -} - static enum surface_update_type get_plane_info_update_type(const struct dc_surface_update *u) { union surface_update_flags *update_flags = >surface->update_flags; @@ -1172,8 +1146,8 @@ static enum surface_update_type get_plane_info_update_type(const struct dc_surfa || u->plane_info->dcc.grph.meta_pitch != u->surface->dcc.grph.meta_pitch) update_flags->bits.dcc_change = 1; - if (pixel_format_to_bpp(u->plane_info->format) != - pixel_format_to_bpp(u->surface->format)) + if (resource_pixel_format_to_bpp(u->plane_info->format) != + resource_pixel_format_to_bpp(u->surface->format)) /* different bytes per element will require full bandwidth * and DML calculation */ diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index a3fee37..b6fe29b 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -2099,6 +2099,14 @@ enum dc_status dc_validate_global_state( if (pipe_ctx->stream != stream) continue; + if (dc->res_pool->funcs->get_default_swizzle_mode && + pipe_ctx->plane_state && + pipe_ctx->plane_state->tiling_info.gfx9.swizzle == DC_SW_UNKNOWN) { + result = dc->res_pool->funcs->get_default_swizzle_mode(pipe_ctx->plane_state); + if (result != DC_OK) + return result; + } + /* Switch to dp clock source only if there is * no non dp stream that shares the same timing * with the dp stream. @@ -2888,3 +2896,32 @@ enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *pla return res; } + +unsigned int resource_pixel_format_to_bpp(enum surface_pixel_format format) +{ + switch (format) { + case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS: + return 8; + case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr: + case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb: + return 12; + case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555: + case SURFACE_PIXEL_FORMAT_GRPH_RGB565: + case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr: + case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb: +
[PATCH 05/16] drm/amd/display: Add function to fetch clock requirements
From: Eryk Brol Also add dram clock to clocks struct, for systems that uses them. Signed-off-by: Eryk Brol Reviewed-by: Jun Lei Acked-by: Leo Li --- drivers/gpu/drm/amd/display/dc/core/dc.c | 13 + drivers/gpu/drm/amd/display/dc/dc.h | 4 +++- drivers/gpu/drm/amd/display/dc/dc_types.h | 12 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index a0e933f..7c491c9 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -1836,3 +1836,16 @@ void dc_link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink) } } } + +void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx *info) +{ + info->displayClock = (unsigned int)state->bw.dcn.clk.dispclk_khz; + info->engineClock = (unsigned int)state->bw.dcn.clk.dcfclk_khz; + info->memoryClock = (unsigned int)state->bw.dcn.clk.dramclk_khz; + info->maxSupportedDppClock = (unsigned int)state->bw.dcn.clk.max_supported_dppclk_khz; + info->dppClock = (unsigned int)state->bw.dcn.clk.dppclk_khz; + info->socClock = (unsigned int)state->bw.dcn.clk.socclk_khz; + info->dcfClockDeepSleep = (unsigned int)state->bw.dcn.clk.dcfclk_deep_sleep_khz; + info->fClock= (unsigned int)state->bw.dcn.clk.fclk_khz; + info->phyClock = (unsigned int)state->bw.dcn.clk.phyclk_khz; +} \ No newline at end of file diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 5f65bea..f328483 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -44,7 +44,6 @@ #define MAX_STREAMS 6 #define MAX_SINKS_PER_LINK 4 - /*** * Display Core Interfaces **/ @@ -208,6 +207,7 @@ struct dc_clocks { int dcfclk_deep_sleep_khz; int fclk_khz; int phyclk_khz; + int dramclk_khz; }; struct dc_debug_options { @@ -601,6 +601,8 @@ struct dc_validation_set { enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *plane_state); +void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx *info); + enum dc_status dc_validate_global_state( struct dc *dc, struct dc_state *new_ctx); diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h index 4fb6278..6e12d64 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -659,4 +659,16 @@ enum i2c_mot_mode { I2C_MOT_FALSE }; +struct AsicStateEx { + unsigned int memoryClock; + unsigned int displayClock; + unsigned int engineClock; + unsigned int maxSupportedDppClock; + unsigned int dppClock; + unsigned int socClock; + unsigned int dcfClockDeepSleep; + unsigned int fClock; + unsigned int phyClock; +}; + #endif /* DC_TYPES_H_ */ -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 07/16] drm/amd/display: clean up encoding checks
From: Eric Yang [Why] All ASICS we support has YCbCr support, so the check is unnecessary, the currently logic in validate output also returns true all the time, so the unneccessary logic is removed Signed-off-by: Eric Yang Reviewed-by: Tony Cheng Acked-by: Leo Li --- drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c | 16 +--- drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c | 3 +-- drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c | 3 +-- drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c | 3 +-- drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c | 1 - drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c | 3 +-- .../gpu/drm/amd/display/dc/dcn10/dcn10_link_encoder.c | 17 + drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 3 +-- drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h| 1 - 9 files changed, 7 insertions(+), 43 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c index 70eb9472..366bc8c 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c @@ -665,21 +665,7 @@ bool dce110_link_encoder_validate_dp_output( if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) return false; - /* default RGB only */ - if (crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB) - return true; - - if (enc110->base.features.flags.bits.IS_YCBCR_CAPABLE) - return true; - - /* for DCE 8.x or later DP Y-only feature, -* we need ASIC cap + FeatureSupportDPYonly, not support 666 */ - if (crtc_timing->flags.Y_ONLY && - enc110->base.features.flags.bits.IS_YCBCR_CAPABLE && - crtc_timing->display_color_depth != COLOR_DEPTH_666) - return true; - - return false; + return true; } void dce110_link_encoder_construct( diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c index b1cc388..5b75460 100644 --- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c @@ -551,8 +551,7 @@ static const struct encoder_feature_support link_enc_feature = { .max_hdmi_deep_color = COLOR_DEPTH_121212, .max_hdmi_pixel_clock = 30, .flags.bits.IS_HBR2_CAPABLE = true, - .flags.bits.IS_TPS3_CAPABLE = true, - .flags.bits.IS_YCBCR_CAPABLE = true + .flags.bits.IS_TPS3_CAPABLE = true }; struct link_encoder *dce100_link_encoder_create( diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c index b44cc70..4607a6a 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c @@ -570,8 +570,7 @@ static const struct encoder_feature_support link_enc_feature = { .max_hdmi_deep_color = COLOR_DEPTH_121212, .max_hdmi_pixel_clock = 594000, .flags.bits.IS_HBR2_CAPABLE = true, - .flags.bits.IS_TPS3_CAPABLE = true, - .flags.bits.IS_YCBCR_CAPABLE = true + .flags.bits.IS_TPS3_CAPABLE = true }; static struct link_encoder *dce110_link_encoder_create( diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c index 0f8332e..8b5a269 100644 --- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c @@ -555,8 +555,7 @@ static const struct encoder_feature_support link_enc_feature = { .flags.bits.IS_HBR2_CAPABLE = true, .flags.bits.IS_HBR3_CAPABLE = true, .flags.bits.IS_TPS3_CAPABLE = true, - .flags.bits.IS_TPS4_CAPABLE = true, - .flags.bits.IS_YCBCR_CAPABLE = true + .flags.bits.IS_TPS4_CAPABLE = true }; struct link_encoder *dce112_link_encoder_create( diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c index 5905580..53a7a2f 100644 --- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c @@ -609,7 +609,6 @@ static const struct encoder_feature_support link_enc_feature = { .flags.bits.IS_HBR3_CAPABLE = true, .flags.bits.IS_TPS3_CAPABLE = true, .flags.bits.IS_TPS4_CAPABLE = true, - .flags.bits.IS_YCBCR_CAPABLE = true }; static struct link_encoder *dce120_link_encoder_create( diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
[PATCH 03/16] drm/amd/display: Add a check-function for virtual signal type
From: Nikola Cornij [why] Same functions exist for all other signal types. [how] Add a function that checks against virtual signal type. Signed-off-by: Nikola Cornij Reviewed-by: Leo Li --- drivers/gpu/drm/amd/display/include/signal_types.h | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/amd/display/include/signal_types.h b/drivers/gpu/drm/amd/display/include/signal_types.h index 03476b1..f56d289 100644 --- a/drivers/gpu/drm/amd/display/include/signal_types.h +++ b/drivers/gpu/drm/amd/display/include/signal_types.h @@ -102,4 +102,9 @@ static inline bool dc_is_audio_capable_signal(enum signal_type signal) dc_is_hdmi_signal(signal)); } +static inline bool dc_is_virtual_signal(enum signal_type signal) +{ + return (signal == SIGNAL_TYPE_VIRTUAL); +} + #endif -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 08/16] drm/amd/display: WA for DF keeps awake after S0i3.
From: Yongqiang Sun [Why] DF keeps awake after S0i3 resume due to DRAM_STATE_CNTL is set by bios command table during dcn init_hw. [How] As a work around, check STATE_CNTL status before init_hw, if it is 0 before init_hw and set to 1 after init_hw, change it to 0. Signed-off-by: Yongqiang Sun Reviewed-by: Tony Cheng Acked-by: Leo Li --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c | 17 + drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h | 4 .../gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 14 ++ 3 files changed, 35 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c index 1ea91e1..69345ce6 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c @@ -87,6 +87,23 @@ void hubbub1_wm_read_state(struct hubbub *hubbub, s->dram_clk_chanage = REG_READ(DCHUBBUB_ARB_ALLOW_DRAM_CLK_CHANGE_WATERMARK_D); } +void hubbub1_disable_allow_self_refresh(struct hubbub *hubbub) +{ + REG_UPDATE(DCHUBBUB_ARB_DRAM_STATE_CNTL, + DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, 0); +} + +bool hububu1_is_allow_self_refresh_enabled(struct hubbub *hubbub) +{ + uint32_t enable = 0; + + REG_GET(DCHUBBUB_ARB_DRAM_STATE_CNTL, + DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE, ); + + return true ? false : enable; +} + + bool hubbub1_verify_allow_pstate_change_high( struct hubbub *hubbub) { diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h index d6e596e..d0f03d1 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h @@ -203,6 +203,10 @@ void hubbub1_program_watermarks( unsigned int refclk_mhz, bool safe_to_lower); +void hubbub1_disable_allow_self_refresh(struct hubbub *hubbub); + +bool hububu1_is_allow_self_refresh_enabled(struct hubbub *hubub); + void hubbub1_toggle_watermark_change_req( struct hubbub *hubbub); diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index a881ff5..193184a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -997,7 +997,21 @@ static void dcn10_init_hw(struct dc *dc) } else { if (!dcb->funcs->is_accelerated_mode(dcb)) { + bool allow_self_fresh_force_enable = + hububu1_is_allow_self_refresh_enabled(dc->res_pool->hubbub); + bios_golden_init(dc); + + /* WA for making DF sleep when idle after resume from S0i3. +* DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE is set to 1 by +* command table, if DCHUBBUB_ARB_ALLOW_SELF_REFRESH_FORCE_ENABLE = 0 +* before calling command table and it changed to 1 after, +* it should be set back to 0. +*/ + if (allow_self_fresh_force_enable == false && + hububu1_is_allow_self_refresh_enabled(dc->res_pool->hubbub)) + hubbub1_disable_allow_self_refresh(dc->res_pool->hubbub); + disable_vga(dc->hwseq); } -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 09/16] drm/amd/display: Fix Edid emulation for linux
From: Bhawanpreet Lakha [Why] EDID emulation didn't work properly for linux, as we stop programming if nothing is connected physically. [How] We get a flag from DRM when we want to do edid emulation. We check if this flag is true and nothing is connected physically, if so we only program the front end using VIRTUAL_SIGNAL. Signed-off-by: Bhawanpreet Lakha Reviewed-by: Harry Wentland Acked-by: Leo Li --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 139 +- drivers/gpu/drm/amd/display/dc/core/dc_link.c | 4 +- drivers/gpu/drm/amd/display/dc/dc_link.h | 1 + 3 files changed, 137 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 8c82185..774db34 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -718,6 +718,87 @@ amdgpu_dm_find_first_crtc_matching_connector(struct drm_atomic_state *state, return NULL; } +static void emulated_link_detect(struct dc_link *link) +{ + struct dc_sink_init_data sink_init_data = { 0 }; + struct display_sink_capability sink_caps = { 0 }; + enum dc_edid_status edid_status; + struct dc_context *dc_ctx = link->ctx; + struct dc_sink *sink = NULL; + struct dc_sink *prev_sink = NULL; + + link->type = dc_connection_none; + prev_sink = link->local_sink; + + if (prev_sink != NULL) + dc_sink_retain(prev_sink); + + switch (link->connector_signal) { + case SIGNAL_TYPE_HDMI_TYPE_A: { + sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C; + sink_caps.signal = SIGNAL_TYPE_HDMI_TYPE_A; + break; + } + + case SIGNAL_TYPE_DVI_SINGLE_LINK: { + sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C; + sink_caps.signal = SIGNAL_TYPE_DVI_SINGLE_LINK; + break; + } + + case SIGNAL_TYPE_DVI_DUAL_LINK: { + sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C; + sink_caps.signal = SIGNAL_TYPE_DVI_DUAL_LINK; + break; + } + + case SIGNAL_TYPE_LVDS: { + sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C; + sink_caps.signal = SIGNAL_TYPE_LVDS; + break; + } + + case SIGNAL_TYPE_EDP: { + sink_caps.transaction_type = + DDC_TRANSACTION_TYPE_I2C_OVER_AUX; + sink_caps.signal = SIGNAL_TYPE_EDP; + break; + } + + case SIGNAL_TYPE_DISPLAY_PORT: { + sink_caps.transaction_type = + DDC_TRANSACTION_TYPE_I2C_OVER_AUX; + sink_caps.signal = SIGNAL_TYPE_VIRTUAL; + break; + } + + default: + DC_ERROR("Invalid connector type! signal:%d\n", + link->connector_signal); + return; + } + + sink_init_data.link = link; + sink_init_data.sink_signal = sink_caps.signal; + + sink = dc_sink_create(_init_data); + if (!sink) { + DC_ERROR("Failed to create sink!\n"); + return; + } + + link->local_sink = sink; + + edid_status = dm_helpers_read_local_edid( + link->ctx, + link, + sink); + + if (edid_status != EDID_OK) + DC_ERROR("Failed to read EDID"); + +} + static int dm_resume(void *handle) { struct amdgpu_device *adev = handle; @@ -731,6 +812,7 @@ static int dm_resume(void *handle) struct drm_plane *plane; struct drm_plane_state *new_plane_state; struct dm_plane_state *dm_new_plane_state; + enum dc_connection_type new_connection_type = dc_connection_none; int ret; int i; @@ -761,7 +843,13 @@ static int dm_resume(void *handle) continue; mutex_lock(>hpd_lock); - dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD); + if (!dc_link_detect_sink(aconnector->dc_link, _connection_type)) + DRM_ERROR("KMS: Failed to detect connector\n"); + + if (aconnector->base.force && new_connection_type == dc_connection_none) + emulated_link_detect(aconnector->dc_link); + else + dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD); if (aconnector->fake_enable && aconnector->dc_link->local_sink) aconnector->fake_enable = false; @@ -1006,6 +1094,7 @@ static void handle_hpd_irq(void *param) struct amdgpu_dm_connector *aconnector = (struct amdgpu_dm_connector *)param; struct drm_connector *connector = >base; struct drm_device *dev = connector->dev; + enum dc_connection_type new_connection_type =
[PATCH 10/16] drm/amd/display: dc 3.1.68
From: Tony Cheng Signed-off-by: Tony Cheng Reviewed-by: Steven Chiu Acked-by: Leo Li --- drivers/gpu/drm/amd/display/dc/dc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index f328483..1995271 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -38,7 +38,7 @@ #include "inc/compressor.h" #include "dml/display_mode_lib.h" -#define DC_VER "3.1.67" +#define DC_VER "3.1.68" #define MAX_SURFACES 3 #define MAX_STREAMS 6 -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 11/16] drm/amd/display: fix memory leak in resource pools
From: Jun Lei [why] ddc engines were recently changed to be independently tracked from pipe count. the change was reflected in resource constructor but not in destructor. this manifests as a memory leak when pipe harvesting is enabled, since not all constructed ddc engines are freed [how] make destructor symmetric with constructor for all dcX_resource Signed-off-by: Jun Lei Reviewed-by: Aric Cyr Acked-by: Leo Li --- drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c | 2 ++ drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c | 2 ++ drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c | 8 +--- drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c | 2 ++ drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c | 2 ++ drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 2 ++ 6 files changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c index 5b75460..14754a8 100644 --- a/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c @@ -689,7 +689,9 @@ static void destruct(struct dce110_resource_pool *pool) kfree(DCE110TG_FROM_TG(pool->base.timing_generators[i])); pool->base.timing_generators[i] = NULL; } + } + for (i = 0; i < pool->base.res_cap->num_ddc; i++) { if (pool->base.engines[i] != NULL) dce110_engine_destroy(>base.engines[i]); if (pool->base.hw_i2cs[i] != NULL) { diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c index 4607a6a..de19093 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c @@ -719,7 +719,9 @@ static void destruct(struct dce110_resource_pool *pool) kfree(DCE110TG_FROM_TG(pool->base.timing_generators[i])); pool->base.timing_generators[i] = NULL; } + } + for (i = 0; i < pool->base.res_cap->num_ddc; i++) { if (pool->base.engines[i] != NULL) dce110_engine_destroy(>base.engines[i]); if (pool->base.hw_i2cs[i] != NULL) { diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c index 8b5a269..3ce79c2 100644 --- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c @@ -693,9 +693,6 @@ static void destruct(struct dce110_resource_pool *pool) if (pool->base.opps[i] != NULL) dce110_opp_destroy(>base.opps[i]); - if (pool->base.engines[i] != NULL) - dce110_engine_destroy(>base.engines[i]); - if (pool->base.transforms[i] != NULL) dce112_transform_destroy(>base.transforms[i]); @@ -711,6 +708,11 @@ static void destruct(struct dce110_resource_pool *pool) kfree(DCE110TG_FROM_TG(pool->base.timing_generators[i])); pool->base.timing_generators[i] = NULL; } + } + + for (i = 0; i < pool->base.res_cap->num_ddc; i++) { + if (pool->base.engines[i] != NULL) + dce110_engine_destroy(>base.engines[i]); if (pool->base.hw_i2cs[i] != NULL) { kfree(pool->base.hw_i2cs[i]); pool->base.hw_i2cs[i] = NULL; diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c index 53a7a2f..79ab5f9 100644 --- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c @@ -533,7 +533,9 @@ static void destruct(struct dce110_resource_pool *pool) kfree(DCE110TG_FROM_TG(pool->base.timing_generators[i])); pool->base.timing_generators[i] = NULL; } + } + for (i = 0; i < pool->base.res_cap->num_ddc; i++) { if (pool->base.engines[i] != NULL) dce110_engine_destroy(>base.engines[i]); if (pool->base.hw_i2cs[i] != NULL) { diff --git a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c index 79e5c5c..d68f951 100644 --- a/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c @@ -738,7 +738,9 @@ static void destruct(struct dce110_resource_pool *pool) kfree(DCE110TG_FROM_TG(pool->base.timing_generators[i])); pool->base.timing_generators[i] = NULL; } + } +
[PATCH 12/16] drm/amd/display: Flatten irq handler data struct
From: Leo Li [Why] There is no reason why the common data needs to be kept separate. [How] Flatten the struct by moving common data into the DM IRQ struct. Signed-off-by: Leo Li Reviewed-by: David Francis Acked-by: Leo Li --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | 37 -- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c index a910f01..a212178 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c @@ -36,17 +36,13 @@ * Private declarations. */ -struct handler_common_data { +struct amdgpu_dm_irq_handler_data { struct list_head list; interrupt_handler handler; void *handler_arg; /* DM which this handler belongs to */ struct amdgpu_display_manager *dm; -}; - -struct amdgpu_dm_irq_handler_data { - struct handler_common_data hcd; /* DAL irq source which registered for this interrupt. */ enum dc_irq_source irq_source; }; @@ -61,7 +57,7 @@ struct amdgpu_dm_irq_handler_data { * Private functions. */ -static void init_handler_common_data(struct handler_common_data *hcd, +static void init_handler_common_data(struct amdgpu_dm_irq_handler_data *hcd, void (*ih)(void *), void *args, struct amdgpu_display_manager *dm) @@ -85,11 +81,9 @@ static void dm_irq_work_func(struct work_struct *work) struct amdgpu_dm_irq_handler_data *handler_data; list_for_each(entry, handler_list) { - handler_data = - list_entry( - entry, - struct amdgpu_dm_irq_handler_data, - hcd.list); + handler_data = list_entry(entry, + struct amdgpu_dm_irq_handler_data, + list); DRM_DEBUG_KMS("DM_IRQ: work_func: for dal_src=%d\n", handler_data->irq_source); @@ -97,7 +91,7 @@ static void dm_irq_work_func(struct work_struct *work) DRM_DEBUG_KMS("DM_IRQ: schedule_work: for dal_src=%d\n", handler_data->irq_source); - handler_data->hcd.handler(handler_data->hcd.handler_arg); + handler_data->handler(handler_data->handler_arg); } /* Call a DAL subcomponent which registered for interrupt notification @@ -137,11 +131,11 @@ static struct list_head *remove_irq_handler(struct amdgpu_device *adev, list_for_each_safe(entry, tmp, hnd_list) { handler = list_entry(entry, struct amdgpu_dm_irq_handler_data, - hcd.list); +list); if (ih == handler) { /* Found our handler. Remove it from the list. */ - list_del(>hcd.list); + list_del(>list); handler_removed = true; break; } @@ -230,8 +224,7 @@ void *amdgpu_dm_irq_register_interrupt(struct amdgpu_device *adev, memset(handler_data, 0, sizeof(*handler_data)); - init_handler_common_data(_data->hcd, ih, handler_args, - >dm); + init_handler_common_data(handler_data, ih, handler_args, >dm); irq_source = int_params->irq_source; @@ -250,7 +243,7 @@ void *amdgpu_dm_irq_register_interrupt(struct amdgpu_device *adev, break; } - list_add_tail(_data->hcd.list, hnd_list); + list_add_tail(_data->list, hnd_list); DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags); @@ -462,15 +455,13 @@ static void amdgpu_dm_irq_immediate_work(struct amdgpu_device *adev, entry, >dm.irq_handler_list_high_tab[irq_source]) { - handler_data = - list_entry( - entry, - struct amdgpu_dm_irq_handler_data, - hcd.list); + handler_data = list_entry(entry, + struct amdgpu_dm_irq_handler_data, + list); /* Call a subcomponent which registered for immediate * interrupt notification */ - handler_data->hcd.handler(handler_data->hcd.handler_arg); + handler_data->handler(handler_data->handler_arg); } DM_IRQ_TABLE_UNLOCK(adev, irq_table_flags); -- 2.7.4
[PATCH 13/16] drm/amd/display: fix Interlace video timing.
From: Charlene Liu [Description] interlace mode shows wrong vertical timing. Interface timing in Edid is half vertical timing as progressive timing. driver doubled the vertical timing in edid_paser, no need to double in optc again. Signed-off-by: Charlene Liu Reviewed-by: Chris Park Acked-by: Leo Li --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c | 32 +-- 1 file changed, 7 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c index 411f892..ad46294 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c @@ -98,7 +98,6 @@ static uint32_t get_start_vline(struct timing_generator *optc, const struct dc_c struct dc_crtc_timing patched_crtc_timing; int vesa_sync_start; int asic_blank_end; - int interlace_factor; int vertical_line_start; patched_crtc_timing = *dc_crtc_timing; @@ -112,16 +111,13 @@ static uint32_t get_start_vline(struct timing_generator *optc, const struct dc_c vesa_sync_start - patched_crtc_timing.h_border_left; - interlace_factor = patched_crtc_timing.flags.INTERLACE ? 2 : 1; - vesa_sync_start = patched_crtc_timing.v_addressable + patched_crtc_timing.v_border_bottom + patched_crtc_timing.v_front_porch; asic_blank_end = (patched_crtc_timing.v_total - vesa_sync_start - - patched_crtc_timing.v_border_top) - * interlace_factor; + patched_crtc_timing.v_border_top); vertical_line_start = asic_blank_end - optc->dlg_otg_param.vstartup_start + 1; if (vertical_line_start < 0) { @@ -186,7 +182,6 @@ void optc1_program_timing( uint32_t v_sync_end; uint32_t v_init, v_fp2; uint32_t h_sync_polarity, v_sync_polarity; - uint32_t interlace_factor; uint32_t start_point = 0; uint32_t field_num = 0; uint32_t h_div_2; @@ -237,16 +232,8 @@ void optc1_program_timing( REG_UPDATE(OTG_H_SYNC_A_CNTL, OTG_H_SYNC_A_POL, h_sync_polarity); - /* Load vertical timing */ + v_total = patched_crtc_timing.v_total - 1; - /* CRTC_V_TOTAL = v_total - 1 */ - if (patched_crtc_timing.flags.INTERLACE) { - interlace_factor = 2; - v_total = 2 * patched_crtc_timing.v_total; - } else { - interlace_factor = 1; - v_total = patched_crtc_timing.v_total - 1; - } REG_SET(OTG_V_TOTAL, 0, OTG_V_TOTAL, v_total); @@ -259,7 +246,7 @@ void optc1_program_timing( OTG_V_TOTAL_MIN, v_total); /* v_sync_start = 0, v_sync_end = v_sync_width */ - v_sync_end = patched_crtc_timing.v_sync_width * interlace_factor; + v_sync_end = patched_crtc_timing.v_sync_width; REG_UPDATE_2(OTG_V_SYNC_A, OTG_V_SYNC_A_START, 0, @@ -271,15 +258,13 @@ void optc1_program_timing( asic_blank_end = (patched_crtc_timing.v_total - vesa_sync_start - - patched_crtc_timing.v_border_top) - * interlace_factor; + patched_crtc_timing.v_border_top); /* v_blank_start = v_blank_end + v_active */ asic_blank_start = asic_blank_end + (patched_crtc_timing.v_border_top + patched_crtc_timing.v_addressable + - patched_crtc_timing.v_border_bottom) - * interlace_factor; + patched_crtc_timing.v_border_bottom); REG_UPDATE_2(OTG_V_BLANK_START_END, OTG_V_BLANK_START, asic_blank_start, @@ -301,7 +286,7 @@ void optc1_program_timing( 0 : 1; REG_UPDATE(OTG_V_SYNC_A_CNTL, - OTG_V_SYNC_A_POL, v_sync_polarity); + OTG_V_SYNC_A_POL, v_sync_polarity); v_init = asic_blank_start; if (optc->dlg_otg_param.signal == SIGNAL_TYPE_DISPLAY_PORT || @@ -532,7 +517,6 @@ bool optc1_validate_timing( struct timing_generator *optc, const struct dc_crtc_timing *timing) { - uint32_t interlace_factor; uint32_t v_blank; uint32_t h_blank; uint32_t min_v_blank; @@ -540,10 +524,8 @@ bool optc1_validate_timing( ASSERT(timing != NULL); - interlace_factor = timing->flags.INTERLACE ? 2 : 1; v_blank = (timing->v_total - timing->v_addressable - - timing->v_border_top - timing->v_border_bottom) * - interlace_factor; + timing->v_border_top - timing->v_border_bottom);
[PATCH 01/16] drm/amd/display: Add DC build_id to determine build type
From: Jun Lei [why] Sometimes there are indications that the incorrect driver is being loaded in automated tests. This change adds the ability for builds to be tagged with a string, and picked up by the test infrastructure. [how] dc.c will allocate const for build id, which is init-ed with default value, indicating production build. For test builds, build server will find/replace this value. The test machine will then verify this value. Signed-off-by: Jun Lei Reviewed-by: Tony Cheng Acked-by: Leo Li --- drivers/gpu/drm/amd/display/dc/core/dc.c | 3 +++ drivers/gpu/drm/amd/display/dc/dc.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 76fe5a9..99ecaeb 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -60,6 +60,7 @@ #define DC_LOGGER \ dc->ctx->logger +const static char DC_BUILD_ID[] = "production-build"; /*** * Private functions @@ -758,6 +759,8 @@ struct dc *dc_create(const struct dc_init_data *init_params) dc->config = init_params->flags; + dc->build_id = DC_BUILD_ID; + DC_LOG_DC("Display Core initialized\n"); diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 11ea2a2..5f65bea 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -315,6 +315,8 @@ struct dc { struct compressor *fbc_compressor; struct dc_debug_data debug_data; + + const char *build_id; }; enum frame_buffer_mode { -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 00/16] DC Patches Sep 26, 2018
From: Leo Li Summary of change: * Edid emulation fix * S3 resume fix on Vega10 * Add build types for internal tracking * Fix screen corruption on polaris * Interlace video timing fix Bhawanpreet Lakha (1): drm/amd/display: Fix Edid emulation for linux Charlene Liu (2): drm/amd/display: fix 4K stereo screen flash issue drm/amd/display: fix Interlace video timing. Eric Yang (2): drm/amd/display: block DP YCbCr420 modes drm/amd/display: clean up encoding checks Eryk Brol (1): drm/amd/display: Add function to fetch clock requirements Jun Lei (2): drm/amd/display: Add DC build_id to determine build type drm/amd/display: fix memory leak in resource pools Leo Li (1): drm/amd/display: Flatten irq handler data struct Murton Liu (1): drm/amd/display: HLK Periodic Frame Notification test failed Nicholas Kazlauskas (1): drm/amd/display: Raise dispclk value for dce_update_clocks Nikola Cornij (1): drm/amd/display: Add a check-function for virtual signal type Roman Li (1): drm/amd/display: Fix Vega10 lightup on S3 resume Su Sung Chung (1): drm/amd/display: Calculate swizzle mode using bpp during validation Tony Cheng (1): drm/amd/display: dc 3.1.68 Yongqiang Sun (1): drm/amd/display: WA for DF keeps awake after S0i3. drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 139 - .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | 37 +++--- drivers/gpu/drm/amd/display/dc/core/dc.c | 46 +++ drivers/gpu/drm/amd/display/dc/core/dc_link.c | 4 +- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 40 ++ drivers/gpu/drm/amd/display/dc/dc.h| 8 +- drivers/gpu/drm/amd/display/dc/dc_hw_types.h | 3 +- drivers/gpu/drm/amd/display/dc/dc_link.h | 1 + drivers/gpu/drm/amd/display/dc/dc_types.h | 12 ++ drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c| 5 + .../gpu/drm/amd/display/dc/dce/dce_link_encoder.c | 17 +-- .../drm/amd/display/dc/dce100/dce100_resource.c| 5 +- .../amd/display/dc/dce110/dce110_hw_sequencer.c| 2 +- .../amd/display/dc/dce110/dce110_hw_sequencer.h| 5 - .../drm/amd/display/dc/dce110/dce110_resource.c| 5 +- .../drm/amd/display/dc/dce112/dce112_resource.c| 11 +- .../amd/display/dc/dce120/dce120_hw_sequencer.c| 12 -- .../drm/amd/display/dc/dce120/dce120_resource.c| 3 +- .../gpu/drm/amd/display/dc/dce80/dce80_resource.c | 5 +- .../gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.c| 17 +++ .../gpu/drm/amd/display/dc/dcn10/dcn10_hubbub.h| 4 + .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 14 +++ .../drm/amd/display/dc/dcn10/dcn10_link_encoder.c | 18 +-- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c | 34 ++--- .../gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 26 +++- drivers/gpu/drm/amd/display/dc/inc/core_types.h| 3 + .../gpu/drm/amd/display/dc/inc/hw/link_encoder.h | 1 - drivers/gpu/drm/amd/display/dc/inc/resource.h | 3 + drivers/gpu/drm/amd/display/include/signal_types.h | 5 + 29 files changed, 335 insertions(+), 150 deletions(-) -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 02/16] drm/amd/display: fix 4K stereo screen flash issue
From: Charlene Liu [Why] HDMI_scramber is not enabled for pixel rate >340Mhz. [How] Calculate the phy clock to include the Hw frame packing factor. Signed-off-by: Charlene Liu Reviewed-by: Chris Park Acked-by: Leo Li --- drivers/gpu/drm/amd/display/dc/core/dc_resource.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index 2d6a430..a3fee37 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -1975,6 +1975,9 @@ static void calculate_phy_pix_clks(struct dc_stream_state *stream) else stream->phy_pix_clk = stream->timing.pix_clk_khz; + + if (stream->timing.timing_3d_format == TIMING_3D_FORMAT_HW_FRAME_PACKING) + stream->phy_pix_clk *= 2; } enum dc_status resource_map_pool_resources( -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 1/2] drm/amdgpu/soc15: fix warnings in register macro
Am 26.09.2018 um 18:25 schrieb Alex Deucher: expects argument of type ‘unsigned int’ has type ‘long int’ Fixes: 52e211c1f04 ("drm/amdgpu:Add error message when register failed to reach expected value") Signed-off-by: Alex Deucher Reviewed-by: Christian König for the series. --- drivers/gpu/drm/amd/amdgpu/soc15_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/soc15_common.h b/drivers/gpu/drm/amd/amdgpu/soc15_common.h index d35fac5b5a8a..958b10a57073 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15_common.h +++ b/drivers/gpu/drm/amd/amdgpu/soc15_common.h @@ -57,7 +57,7 @@ loop--; \ if (!loop) {\ DRM_ERROR("Register(%d) [%s] failed to reach value 0x%08x != 0x%08x\n", \ - inst, #reg, expected_value, (tmp_ & (mask))); \ + inst, #reg, (unsigned)expected_value, (unsigned)(tmp_ & (mask))); \ ret = -ETIMEDOUT; \ break; \ } \ ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 1/2] drm/amdgpu/soc15: fix warnings in register macro
expects argument of type ‘unsigned int’ has type ‘long int’ Fixes: 52e211c1f04 ("drm/amdgpu:Add error message when register failed to reach expected value") Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/soc15_common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/soc15_common.h b/drivers/gpu/drm/amd/amdgpu/soc15_common.h index d35fac5b5a8a..958b10a57073 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15_common.h +++ b/drivers/gpu/drm/amd/amdgpu/soc15_common.h @@ -57,7 +57,7 @@ loop--; \ if (!loop) {\ DRM_ERROR("Register(%d) [%s] failed to reach value 0x%08x != 0x%08x\n", \ - inst, #reg, expected_value, (tmp_ & (mask))); \ + inst, #reg, (unsigned)expected_value, (unsigned)(tmp_ & (mask))); \ ret = -ETIMEDOUT; \ break; \ } \ -- 2.13.6 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 16/16] drm/amd/display: Raise dispclk value for dce_update_clocks
From: Nicholas Kazlauskas [Why] The DISPCLK value was previously requested to be 15% higher for all ASICS that went through the dce110 bandwidth code path. As part of a refactoring of dce_clocks and dce110 set_bandwidth this was removed for power saving considerations. This changed caused corruption under certain display configurations. Originally thought to be Vega specific, it was also observed on Polaris. [How] The 15% is brought back but its placement differs from the original patch. This boost should only be enable while DFS bypass is inactive. This (like the Vega patch) is also a workaround that should be removed after the root cause is identified. Signed-off-by: Nicholas Kazlauskas Reviewed-by: Harry Wentland Acked-by: Leo Li --- drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c index d42afa0..d89a097 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clocks.c @@ -664,6 +664,11 @@ static void dce_update_clocks(struct dccg *dccg, bool safe_to_lower) { struct dm_pp_power_level_change_request level_change_req; + struct dce_dccg *clk_dce = TO_DCE_CLOCKS(dccg); + + /* TODO: Investigate why this is needed to fix display corruption. */ + if (!clk_dce->dfs_bypass_active) + new_clocks->dispclk_khz = new_clocks->dispclk_khz * 115 / 100; level_change_req.power_level = dce_get_required_clocks_state(dccg, new_clocks); /* get max clock state from PPLIB */ -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 14/16] drm/amd/display: HLK Periodic Frame Notification test failed
From: Murton Liu [Why] Due to a small pre-fetch window, the active vline timing is a couple of lines off when compared to what it should be. [How] Changed the calculation for the start vline to account for this window. Signed-off-by: Murton Liu Reviewed-by: Aric Cyr Acked-by: Leo Li --- drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c index ad46294..5462668 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_optc.c @@ -150,7 +150,7 @@ void optc1_program_vline_interrupt( req_delta_lines--; if (req_delta_lines > vsync_line) - start_line = dc_crtc_timing->v_total - (req_delta_lines - vsync_line) - 1; + start_line = dc_crtc_timing->v_total - (req_delta_lines - vsync_line) + 2; else start_line = vsync_line - req_delta_lines; -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH 15/16] drm/amd/display: Fix Vega10 lightup on S3 resume
From: Roman Li [Why] There have been a few reports of Vega10 display remaining blank after S3 resume. The regression is caused by workaround for mode change on Vega10 - skip set_bandwidth if stream count is 0. As a result we skipped dispclk reset on suspend, thus on resume we may skip the clock update assuming it hasn't been changed. On some systems it causes display blank or 'out of range'. [How] Revert "drm/amd/display: Fix Vega10 black screen after mode change" Verified that it hadn't cause mode change regression. Signed-off-by: Roman Li Reviewed-by: Sun peng Li Acked-by: Leo Li --- drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 2 +- drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h | 5 - drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.c | 12 3 files changed, 1 insertion(+), 18 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 6b7..b75ede5 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -2537,7 +2537,7 @@ static void pplib_apply_display_requirements( dc->prev_display_config = *pp_display_cfg; } -void dce110_set_bandwidth( +static void dce110_set_bandwidth( struct dc *dc, struct dc_state *context, bool decrease_allowed) diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h index e4c5db7..d6db3db 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.h @@ -68,11 +68,6 @@ void dce110_fill_display_configs( const struct dc_state *context, struct dm_pp_display_configuration *pp_display_cfg); -void dce110_set_bandwidth( - struct dc *dc, - struct dc_state *context, - bool decrease_allowed); - uint32_t dce110_get_min_vblank_time_us(const struct dc_state *context); void dp_receiver_power_ctrl(struct dc_link *link, bool on); diff --git a/drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.c index 5853522..eb0f5f9 100644 --- a/drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce120/dce120_hw_sequencer.c @@ -244,17 +244,6 @@ static void dce120_update_dchub( dh_data->dchub_info_valid = false; } -static void dce120_set_bandwidth( - struct dc *dc, - struct dc_state *context, - bool decrease_allowed) -{ - if (context->stream_count <= 0) - return; - - dce110_set_bandwidth(dc, context, decrease_allowed); -} - void dce120_hw_sequencer_construct(struct dc *dc) { /* All registers used by dce11.2 match those in dce11 in offset and @@ -263,6 +252,5 @@ void dce120_hw_sequencer_construct(struct dc *dc) dce110_hw_sequencer_construct(dc); dc->hwss.enable_display_power_gating = dce120_enable_display_power_gating; dc->hwss.update_dchub = dce120_update_dchub; - dc->hwss.set_bandwidth = dce120_set_bandwidth; } -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 02/12] drm/amdgpu: send IVs to the KFD only after processing them
On Wed, Sep 26, 2018, at 08:53, Christian König wrote: > This allows us to filter out VM faults in the GMC code. > > Signed-off-by: Christian König The KFD needs to receive notification of unhandled VM faults; when demand paging is disabled or the address is not pageable. It propagates this to the UMD (ROC runtime or the ROC debugger). Does this patch change that behavior? ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 11/12] drm/amdgpu: add support for self irq on Vega10
On Wed, Sep 26, 2018 at 9:54 AM Christian König wrote: > > This finally enables processing of ring 1 & 2. > > Signed-off-by: Christian König > --- > drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 68 > +++--- > 1 file changed, 63 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c > b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c > index e6af9b4c3116..dd155a207fdd 100644 > --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c > +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c > @@ -258,7 +258,7 @@ static void vega10_ih_irq_disable(struct amdgpu_device > *adev) > static u32 vega10_ih_get_wptr(struct amdgpu_device *adev, > struct amdgpu_ih_ring *ih) > { > - u32 wptr, tmp; > + u32 wptr, reg, tmp; > > wptr = le32_to_cpu(*ih->wptr_cpu); > > @@ -274,9 +274,18 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev, > wptr, ih->rptr, tmp); > ih->rptr = tmp; > > - tmp = RREG32_NO_KIQ(SOC15_REG_OFFSET(OSSSYS, 0, > mmIH_RB_CNTL)); > + if (ih == >irq.ih) > + reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL); > + else if (ih == >irq.ih1) > + reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL); > + else if (ih == >irq.ih2) > + reg = SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL); > + else > + BUG(); Copy paste typo? Alex > + > + tmp = RREG32_NO_KIQ(reg); > tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); > - WREG32_NO_KIQ(SOC15_REG_OFFSET(OSSSYS, 0, mmIH_RB_CNTL), tmp); > + WREG32_NO_KIQ(reg, tmp); > } > return (wptr & ih->ptr_mask); > } > @@ -338,9 +347,52 @@ static void vega10_ih_set_rptr(struct amdgpu_device > *adev, > /* XXX check if swapping is necessary on BE */ > *ih->rptr_cpu = ih->rptr; > WDOORBELL32(ih->doorbell_index, ih->rptr); > - } else { > + } else if (ih == >irq.ih) { > WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, ih->rptr); > + } else if (ih == >irq.ih1) { > + WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, ih->rptr); > + } else if (ih == >irq.ih2) { > + WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, ih->rptr); > + } > +} > + > +/** > + * vega10_ih_self_irq - dispatch work for ring 1 and 2 > + * > + * @adev: amdgpu_device pointer > + * @source: irq source > + * @entry: IV with WPTR update > + * > + * Update the WPTR from the IV and schedule work to handle the entries. > + */ > +static int vega10_ih_self_irq(struct amdgpu_device *adev, > + struct amdgpu_irq_src *source, > + struct amdgpu_iv_entry *entry) > +{ > + uint32_t wptr = cpu_to_le32(entry->src_data[0]); > + > + switch (entry->ring_id) { > + case 1: > + *adev->irq.ih1.wptr_cpu = wptr; > + schedule_work(>irq.ih1_work); > + break; > + case 2: > + *adev->irq.ih2.wptr_cpu = wptr; > + schedule_work(>irq.ih2_work); > + break; > + default: break; > } > + return 0; > +} > + > +static const struct amdgpu_irq_src_funcs vega10_ih_self_irq_funcs = { > + .process = vega10_ih_self_irq, > +}; > + > +static void vega10_ih_set_self_irq_funcs(struct amdgpu_device *adev) > +{ > + adev->irq.self_irq.num_types = 0; > + adev->irq.self_irq.funcs = _ih_self_irq_funcs; > } > > static int vega10_ih_early_init(void *handle) > @@ -348,13 +400,19 @@ static int vega10_ih_early_init(void *handle) > struct amdgpu_device *adev = (struct amdgpu_device *)handle; > > vega10_ih_set_interrupt_funcs(adev); > + vega10_ih_set_self_irq_funcs(adev); > return 0; > } > > static int vega10_ih_sw_init(void *handle) > { > - int r; > struct amdgpu_device *adev = (struct amdgpu_device *)handle; > + int r; > + > + r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_IH, 0, > + >irq.self_irq); > + if (r) > + return r; > > r = amdgpu_ih_ring_init(adev, >irq.ih, 256 * 1024, true); > if (r) > -- > 2.14.1 > > ___ > amd-gfx mailing list > amd-gfx@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amdgpu: fix a NULL check in debugfs init
The debugfs_create_file() returns error pointers if DEBUGFS isn't enabled. But here, we know that it is enabled so it returns NULL on error which could lead to a NULL dereference a few lines later. Signed-off-by: Dan Carpenter --- If someone wanted to delete the error handling as well that would also be fine, but I decided not to bother with that. diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c index f5fb93795a69..0d806dfd5eeb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c @@ -832,12 +832,12 @@ int amdgpu_debugfs_regs_init(struct amdgpu_device *adev) ent = debugfs_create_file(debugfs_regs_names[i], S_IFREG | S_IRUGO, root, adev, debugfs_regs[i]); - if (IS_ERR(ent)) { + if (!ent) { for (j = 0; j < i; j++) { debugfs_remove(adev->debugfs_regs[i]); adev->debugfs_regs[i] = NULL; } - return PTR_ERR(ent); + return -ENOMEM; } if (!i) ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH] drm/amd/powerplay: enable fan RPM and pwm settings V2
Manual fan RPM and pwm setting on vega20 are available now. V2: correct the register for fan speed setting and avoid divide-by-zero Change-Id: Iad45a169d6984acc091c4efaf46973619fe43a29 Signed-off-by: Evan Quan Reviewed-by: Alex Deucher Reviewed-by: Rex Zhu --- .../include/asic_reg/thm/thm_11_0_2_offset.h | 12 ++ .../include/asic_reg/thm/thm_11_0_2_sh_mask.h | 10 ++ .../drm/amd/powerplay/hwmgr/vega20_hwmgr.c| 27 .../drm/amd/powerplay/hwmgr/vega20_thermal.c | 151 +- .../drm/amd/powerplay/hwmgr/vega20_thermal.h | 11 +- 5 files changed, 207 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_offset.h b/drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_offset.h index 510ec3c70626..a9eb57a53e59 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_offset.h +++ b/drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_offset.h @@ -26,6 +26,18 @@ #define mmCG_MULT_THERMAL_STATUS 0x005f #define mmCG_MULT_THERMAL_STATUS_BASE_IDX 0 +#define mmCG_FDO_CTRL0 0x0067 +#define mmCG_FDO_CTRL0_BASE_IDX 0 + +#define mmCG_FDO_CTRL1 0x0068 +#define mmCG_FDO_CTRL1_BASE_IDX 0 + +#define mmCG_FDO_CTRL2 0x0069 +#define mmCG_FDO_CTRL2_BASE_IDX 0 + +#define mmCG_TACH_CTRL 0x006a +#define mmCG_TACH_CTRL_BASE_IDX 0 + #define mmTHM_THERMAL_INT_ENA 0x000a #define mmTHM_THERMAL_INT_ENA_BASE_IDX 0 #define mmTHM_THERMAL_INT_CTRL 0x000b diff --git a/drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_sh_mask.h index f69533fa6abf..d130d92aee19 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_sh_mask.h +++ b/drivers/gpu/drm/amd/include/asic_reg/thm/thm_11_0_2_sh_mask.h @@ -28,6 +28,16 @@ #define CG_MULT_THERMAL_STATUS__CTF_TEMP__SHIFT 0x9 #define CG_MULT_THERMAL_STATUS__ASIC_MAX_TEMP_MASK 0x01FFL #define CG_MULT_THERMAL_STATUS__CTF_TEMP_MASK 0x0003FE00L +#define CG_FDO_CTRL2__TMIN__SHIFT 0x0 +#define CG_FDO_CTRL2__TMIN_MASK 0x00FFL +#define CG_FDO_CTRL2__FDO_PWM_MODE__SHIFT 0xb +#define CG_FDO_CTRL2__FDO_PWM_MODE_MASK 0x3800L +#define CG_FDO_CTRL1__FMAX_DUTY100__SHIFT 0x0 +#define CG_FDO_CTRL1__FMAX_DUTY100_MASK 0x00FFL +#define CG_FDO_CTRL0__FDO_STATIC_DUTY__SHIFT 0x0 +#define CG_FDO_CTRL0__FDO_STATIC_DUTY_MASK 0x00FFL +#define CG_TACH_CTRL__TARGET_PERIOD__SHIFT 0x3 +#define CG_TACH_CTRL__TARGET_PERIOD_MASK 0xFFF8L //THM_THERMAL_INT_ENA #define THM_THERMAL_INT_ENA__THERM_INTH_SET__SHIFT 0x0 diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c index 6ece7d724a5b..ee38ed56dd51 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c @@ -2289,6 +2289,25 @@ static uint32_t vega20_get_fan_control_mode(struct pp_hwmgr *hwmgr) return AMD_FAN_CTRL_AUTO; } +static void vega20_set_fan_control_mode(struct pp_hwmgr *hwmgr, uint32_t mode) +{ + switch (mode) { + case AMD_FAN_CTRL_NONE: +
[PATCH v2 4/8] drm/amdgpu:Add DPG mode read/write macro
Some registers read/write needs program through SDRAM pool under DPG mode. Signed-off-by: James Zhu Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/soc15_common.h | 20 1 file changed, 20 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/soc15_common.h b/drivers/gpu/drm/amd/amdgpu/soc15_common.h index f5d6025..d35fac5 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15_common.h +++ b/drivers/gpu/drm/amd/amdgpu/soc15_common.h @@ -64,6 +64,26 @@ } \ } while (0) +#define RREG32_SOC15_DPG_MODE(ip, inst, reg, mask, sram_sel) \ + ({ WREG32_SOC15(ip, inst, mmUVD_DPG_LMA_MASK, mask); \ + WREG32_SOC15(ip, inst, mmUVD_DPG_LMA_CTL, \ + UVD_DPG_LMA_CTL__MASK_EN_MASK | \ + ((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) \ + << UVD_DPG_LMA_CTL__READ_WRITE_ADDR__SHIFT) | \ + (sram_sel << UVD_DPG_LMA_CTL__SRAM_SEL__SHIFT));\ + RREG32_SOC15(ip, inst, mmUVD_DPG_LMA_DATA); }) + +#define WREG32_SOC15_DPG_MODE(ip, inst, reg, value, mask, sram_sel)\ + do {\ + WREG32_SOC15(ip, inst, mmUVD_DPG_LMA_DATA, value); \ + WREG32_SOC15(ip, inst, mmUVD_DPG_LMA_MASK, mask); \ + WREG32_SOC15(ip, inst, mmUVD_DPG_LMA_CTL, \ + UVD_DPG_LMA_CTL__READ_WRITE_MASK | \ + ((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg) \ + << UVD_DPG_LMA_CTL__READ_WRITE_ADDR__SHIFT) | \ + (sram_sel << UVD_DPG_LMA_CTL__SRAM_SEL__SHIFT)); \ + } while (0) + #endif -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH v2 7/8] drm/amdgpu:Add DPG pause mode support
Add functions to support VCN DPG pause mode. Signed-off-by: James Zhu Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 161 +++- 1 file changed, 159 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index 27262a8..c6dd840 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -36,6 +36,7 @@ #include "soc15_common.h" #include "vcn/vcn_1_0_offset.h" +#include "vcn/vcn_1_0_sh_mask.h" /* 1 second timeout */ #define VCN_IDLE_TIMEOUT msecs_to_jiffies(1000) @@ -212,18 +213,158 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev) return 0; } +static int amdgpu_vcn_pause_dpg_mode(struct amdgpu_device *adev, + struct dpg_pause_state *new_state) +{ + int ret_code; + uint32_t reg_data = 0; + uint32_t reg_data2 = 0; + struct amdgpu_ring *ring; + + /* pause/unpause if state is changed */ + if (adev->vcn.pause_state.fw_based != new_state->fw_based) { + DRM_DEBUG("dpg pause state changed %d:%d -> %d:%d", + adev->vcn.pause_state.fw_based, adev->vcn.pause_state.jpeg, + new_state->fw_based, new_state->jpeg); + + reg_data = RREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE) & + (~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK); + + if (new_state->fw_based == VCN_DPG_STATE__PAUSE) { + ret_code = 0; + + if (!(reg_data & UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK)) + SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS, + UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF, + UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code); + + if (!ret_code) { + /* pause DPG non-jpeg */ + reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK; + WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data); + SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_DPG_PAUSE, + UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK, + UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK, ret_code); + + /* Restore */ + ring = >vcn.ring_enc[0]; + WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO, ring->gpu_addr); + WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr)); + WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE, ring->ring_size / 4); + WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR, lower_32_bits(ring->wptr)); + WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR, lower_32_bits(ring->wptr)); + + ring = >vcn.ring_enc[1]; + WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_LO2, ring->gpu_addr); + WREG32_SOC15(UVD, 0, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr)); + WREG32_SOC15(UVD, 0, mmUVD_RB_SIZE2, ring->ring_size / 4); + WREG32_SOC15(UVD, 0, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr)); + WREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr)); + + ring = >vcn.ring_dec; + WREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR, + lower_32_bits(ring->wptr) | 0x8000); + SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS, + UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON, + UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code); + } + } else { + /* unpause dpg non-jpeg, no need to wait */ + reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK; + WREG32_SOC15(UVD, 0, mmUVD_DPG_PAUSE, reg_data); + } + adev->vcn.pause_state.fw_based = new_state->fw_based; + } + + /* pause/unpause if state is changed */ + if (adev->vcn.pause_state.jpeg != new_state->jpeg) { + DRM_DEBUG("dpg pause state changed %d:%d -> %d:%d", + adev->vcn.pause_state.fw_based, adev->vcn.pause_state.jpeg, + new_state->fw_based, new_state->jpeg); + + reg_data =
[PATCH v2 2/8] drm/amdgpu:Add new register offset/mask to support VCN DPG mode
New register offset/mask need to be added to support VCN DPG mode. Signed-off-by: James Zhu Reviewed-by: Alex Deucher --- .../drm/amd/include/asic_reg/vcn/vcn_1_0_offset.h | 8 +++ .../drm/amd/include/asic_reg/vcn/vcn_1_0_sh_mask.h | 25 ++ 2 files changed, 33 insertions(+) diff --git a/drivers/gpu/drm/amd/include/asic_reg/vcn/vcn_1_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/vcn/vcn_1_0_offset.h index 216a401..4b7da58 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/vcn/vcn_1_0_offset.h +++ b/drivers/gpu/drm/amd/include/asic_reg/vcn/vcn_1_0_offset.h @@ -33,6 +33,14 @@ #define mmUVD_POWER_STATUS_BASE_IDX 1 #define mmCC_UVD_HARVESTING 0x00c7 #define mmCC_UVD_HARVESTING_BASE_IDX 1 +#define mmUVD_DPG_LMA_CTL 0x00d1 +#define mmUVD_DPG_LMA_CTL_BASE_IDX 1 +#define mmUVD_DPG_LMA_DATA 0x00d2 +#define mmUVD_DPG_LMA_DATA_BASE_IDX 1 +#define mmUVD_DPG_LMA_MASK 0x00d3 +#define mmUVD_DPG_LMA_MASK_BASE_IDX 1 +#define mmUVD_DPG_PAUSE 0x00d4 +#define mmUVD_DPG_PAUSE_BASE_IDX 1 #define mmUVD_SCRATCH1 0x00d5 #define mmUVD_SCRATCH1_BASE_IDX 1 #define mmUVD_SCRATCH2 0x00d6 diff --git a/drivers/gpu/drm/amd/include/asic_reg/vcn/vcn_1_0_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/vcn/vcn_1_0_sh_mask.h index 124383d..26382f5 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/vcn/vcn_1_0_sh_mask.h +++ b/drivers/gpu/drm/amd/include/asic_reg/vcn/vcn_1_0_sh_mask.h @@ -87,6 +87,26 @@ //CC_UVD_HARVESTING #define CC_UVD_HARVESTING__UVD_DISABLE__SHIFT 0x1 #define CC_UVD_HARVESTING__UVD_DISABLE_MASK 0x0002L +//UVD_DPG_LMA_CTL +#define UVD_DPG_LMA_CTL__READ_WRITE__SHIFT 0x0 +#define UVD_DPG_LMA_CTL__MASK_EN__SHIFT 0x1 +#define UVD_DPG_LMA_CTL__ADDR_AUTO_INCREMENT__SHIFT 0x2 +#define UVD_DPG_LMA_CTL__SRAM_SEL__SHIFT 0x4 +#define UVD_DPG_LMA_CTL__READ_WRITE_ADDR__SHIFT 0x10 +#define UVD_DPG_LMA_CTL__READ_WRITE_MASK 0x0001L +#define UVD_DPG_LMA_CTL__MASK_EN_MASK 0x0002L +#define UVD_DPG_LMA_CTL__ADDR_AUTO_INCREMENT_MASK 0x0004L +#define UVD_DPG_LMA_CTL__SRAM_SEL_MASK 0x0010L +#define UVD_DPG_LMA_CTL__READ_WRITE_ADDR_MASK 0xL +//UVD_DPG_PAUSE +#define UVD_DPG_PAUSE__JPEG_PAUSE_DPG_REQ__SHIFT 0x0 +#define UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK__SHIFT 0x1 +#define UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ__SHIFT 0x2 +#define UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK__SHIFT 0x3 +#define UVD_DPG_PAUSE__JPEG_PAUSE_DPG_REQ_MASK 0x0001L +#define UVD_DPG_PAUSE__JPEG_PAUSE_DPG_ACK_MASK 0x0002L +#define UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK 0x0004L +#define UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK 0x0008L //UVD_SCRATCH1 #define UVD_SCRATCH1__SCRATCH1_DATA__SHIFT
Re: [PATCH 7/9] drm/amdgpu: add IH ring to ih_get_wptr/ih_set_rptr
On Mon, Sep 24, 2018 at 02:38:18PM +0200, Christian König wrote: > Let's start to support multiple rings. > > Signed-off-by: Christian König Reviewed-by: Huang Rui > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | 6 +++--- > drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 8 > drivers/gpu/drm/amd/amdgpu/cik_ih.c | 16 +--- > drivers/gpu/drm/amd/amdgpu/cz_ih.c | 16 +--- > drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 16 +--- > drivers/gpu/drm/amd/amdgpu/si_ih.c | 16 +--- > drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 28 +++- > drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 32 +--- > 8 files changed, 75 insertions(+), 63 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > index 8af67f649660..fb8dd6179926 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > @@ -137,7 +137,7 @@ int amdgpu_ih_process(struct amdgpu_device *adev, struct > amdgpu_ih_ring *ih, > if (!ih->enabled || adev->shutdown) > return IRQ_NONE; > > - wptr = amdgpu_ih_get_wptr(adev); > + wptr = amdgpu_ih_get_wptr(adev, ih); > > restart_ih: > /* is somebody else already processing irqs? */ > @@ -154,11 +154,11 @@ int amdgpu_ih_process(struct amdgpu_device *adev, > struct amdgpu_ih_ring *ih, > ih->rptr &= ih->ptr_mask; > } > > - amdgpu_ih_set_rptr(adev); > + amdgpu_ih_set_rptr(adev, ih); > atomic_set(>lock, 0); > > /* make sure wptr hasn't changed while processing */ > - wptr = amdgpu_ih_get_wptr(adev); > + wptr = amdgpu_ih_get_wptr(adev, ih); > if (wptr != ih->rptr) > goto restart_ih; > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > index d88f82321ee4..61967e7b64a7 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > @@ -52,12 +52,12 @@ struct amdgpu_ih_ring { > /* provided by the ih block */ > struct amdgpu_ih_funcs { > /* ring read/write ptr handling, called from interrupt context */ > - u32 (*get_wptr)(struct amdgpu_device *adev); > - void (*set_rptr)(struct amdgpu_device *adev); > + u32 (*get_wptr)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); > + void (*set_rptr)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); > }; > > -#define amdgpu_ih_get_wptr(adev) (adev)->irq.ih.funcs->get_wptr((adev)) > -#define amdgpu_ih_set_rptr(adev) (adev)->irq.ih.funcs->set_rptr((adev)) > +#define amdgpu_ih_get_wptr(adev, ih) (ih)->funcs->get_wptr((adev), (ih)) > +#define amdgpu_ih_set_rptr(adev, ih) (ih)->funcs->set_rptr((adev), (ih)) > > int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring > *ih, > unsigned ring_size, bool use_bus_addr); > diff --git a/drivers/gpu/drm/amd/amdgpu/cik_ih.c > b/drivers/gpu/drm/amd/amdgpu/cik_ih.c > index 161f0225749c..341092768809 100644 > --- a/drivers/gpu/drm/amd/amdgpu/cik_ih.c > +++ b/drivers/gpu/drm/amd/amdgpu/cik_ih.c > @@ -183,11 +183,12 @@ static void cik_ih_irq_disable(struct amdgpu_device > *adev) > * Used by cik_irq_process(). > * Returns the value of the wptr. > */ > -static u32 cik_ih_get_wptr(struct amdgpu_device *adev) > +static u32 cik_ih_get_wptr(struct amdgpu_device *adev, > +struct amdgpu_ih_ring *ih) > { > u32 wptr, tmp; > > - wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]); > + wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]); > > if (wptr & IH_RB_WPTR__RB_OVERFLOW_MASK) { > wptr &= ~IH_RB_WPTR__RB_OVERFLOW_MASK; > @@ -196,13 +197,13 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev) >* this should allow us to catchup. >*/ > dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, > 0x%08X)\n", > - wptr, adev->irq.ih.rptr, (wptr + 16) & > adev->irq.ih.ptr_mask); > - adev->irq.ih.rptr = (wptr + 16) & adev->irq.ih.ptr_mask; > + wptr, ih->rptr, (wptr + 16) & ih->ptr_mask); > + ih->rptr = (wptr + 16) & ih->ptr_mask; > tmp = RREG32(mmIH_RB_CNTL); > tmp |= IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK; > WREG32(mmIH_RB_CNTL, tmp); > } > - return (wptr & adev->irq.ih.ptr_mask); > + return (wptr & ih->ptr_mask); > } > > /*CIK IV Ring > @@ -294,9 +295,10 @@ static void cik_ih_decode_iv(struct amdgpu_device *adev, > * > * Set the IH ring buffer rptr. > */ > -static void cik_ih_set_rptr(struct amdgpu_device *adev) > +static void cik_ih_set_rptr(struct amdgpu_device *adev, > + struct amdgpu_ih_ring *ih) > { > - WREG32(mmIH_RB_RPTR, adev->irq.ih.rptr); > + WREG32(mmIH_RB_RPTR, ih->rptr); > } >
[PATCH v2 6/8] drm/amdgpu:Add DPG pause state
Add DPG pause state to support VCN DPG mode. Signed-off-by: James Zhu Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h | 11 +++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h index d2219ab..0b88a46 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h @@ -56,6 +56,16 @@ enum engine_status_constants { UVD_STATUS__RBC_BUSY = 0x1, }; +enum internal_dpg_state { + VCN_DPG_STATE__UNPAUSE = 0, + VCN_DPG_STATE__PAUSE, +}; + +struct dpg_pause_state { + enum internal_dpg_state fw_based; + enum internal_dpg_state jpeg; +}; + struct amdgpu_vcn { struct amdgpu_bo*vcpu_bo; void*cpu_addr; @@ -70,6 +80,7 @@ struct amdgpu_vcn { struct amdgpu_irq_src irq; unsignednum_enc_rings; enum amd_powergating_state cur_state; + struct dpg_pause_state pause_state; }; int amdgpu_vcn_sw_init(struct amdgpu_device *adev); -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH v2 1/8] drm/amdgpu:Use register UVD_SCRATCH9 for VCN ring/ib test
Use register UVD_SCRATCH9 for VCN ring/ib test. Since those registers can't be directly accessed under DPG(Dynamic Power Gate) mode. Signed-off-by: James Zhu Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c index a73674f..27262a8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c @@ -264,7 +264,7 @@ int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring *ring) unsigned i; int r; - WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0xCAFEDEAD); + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0xCAFEDEAD); r = amdgpu_ring_alloc(ring, 3); if (r) { DRM_ERROR("amdgpu: cp failed to lock ring %d (%d).\n", @@ -272,11 +272,11 @@ int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring *ring) return r; } amdgpu_ring_write(ring, - PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0)); + PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0)); amdgpu_ring_write(ring, 0xDEADBEEF); amdgpu_ring_commit(ring); for (i = 0; i < adev->usec_timeout; i++) { - tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID)); + tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9)); if (tmp == 0xDEADBEEF) break; DRM_UDELAY(1); @@ -616,7 +616,7 @@ int amdgpu_vcn_jpeg_ring_test_ring(struct amdgpu_ring *ring) unsigned i; int r; - WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0xCAFEDEAD); + WREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0xCAFEDEAD); r = amdgpu_ring_alloc(ring, 3); if (r) { @@ -626,12 +626,12 @@ int amdgpu_vcn_jpeg_ring_test_ring(struct amdgpu_ring *ring) } amdgpu_ring_write(ring, - PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID), 0, 0, 0)); + PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0, 0, 0)); amdgpu_ring_write(ring, 0xDEADBEEF); amdgpu_ring_commit(ring); for (i = 0; i < adev->usec_timeout; i++) { - tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_CONTEXT_ID)); + tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9)); if (tmp == 0xDEADBEEF) break; DRM_UDELAY(1); @@ -665,7 +665,7 @@ static int amdgpu_vcn_jpeg_set_reg(struct amdgpu_ring *ring, uint32_t handle, ib = >ibs[0]; - ib->ptr[0] = PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_JPEG_PITCH), 0, 0, PACKETJ_TYPE0); + ib->ptr[0] = PACKETJ(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9), 0, 0, PACKETJ_TYPE0); ib->ptr[1] = 0xDEADBEEF; for (i = 2; i < 16; i += 2) { ib->ptr[i] = PACKETJ(0, 0, 0, PACKETJ_TYPE6); @@ -714,7 +714,7 @@ int amdgpu_vcn_jpeg_ring_test_ib(struct amdgpu_ring *ring, long timeout) r = 0; for (i = 0; i < adev->usec_timeout; i++) { - tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_JPEG_PITCH)); + tmp = RREG32(SOC15_REG_OFFSET(UVD, 0, mmUVD_SCRATCH9)); if (tmp == 0xDEADBEEF) break; DRM_UDELAY(1); -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH v2 8/8] drm/amdgpu:Enable DPG mode on PCO
Add flag AMD_PG_SUPPORT_DPG to enable DPG mode on Picasso Signed-off-by: James Zhu Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/soc15.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c index 138c481..fb26039 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.c +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c @@ -739,7 +739,8 @@ static int soc15_common_early_init(void *handle) adev->pg_flags = AMD_PG_SUPPORT_SDMA | AMD_PG_SUPPORT_MMHUB | - AMD_PG_SUPPORT_VCN; + AMD_PG_SUPPORT_VCN | + AMD_PG_SUPPORT_VCN_DPG; } else { adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | AMD_CG_SUPPORT_GFX_MGLS | -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH v2 3/8] drm/amdgpu:Add DPG support flag
Add DPG support flag for VCN DPG mode. Signed-off-by: James Zhu Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/include/amd_shared.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/include/amd_shared.h b/drivers/gpu/drm/amd/include/amd_shared.h index 86b167e..2083c30 100644 --- a/drivers/gpu/drm/amd/include/amd_shared.h +++ b/drivers/gpu/drm/amd/include/amd_shared.h @@ -109,6 +109,7 @@ enum amd_powergating_state { #define AMD_PG_SUPPORT_GFX_PIPELINE(1 << 12) #define AMD_PG_SUPPORT_MMHUB (1 << 13) #define AMD_PG_SUPPORT_VCN (1 << 14) +#define AMD_PG_SUPPORT_VCN_DPG (1 << 15) enum PP_FEATURE_MASK { PP_SCLK_DPM_MASK = 0x1, -- 2.7.4 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
[PATCH v2 5/8] drm/amdgpu:Add DPG mode support for vcn 1.0
Add DPG mode start/stop/mc_resume/clock_gating to support vcn 1.0 DPG mode. Signed-off-by: James Zhu Reviewed-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 319 +- 1 file changed, 313 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c index 2cde0b4..63d7f97 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c @@ -198,7 +198,8 @@ static int vcn_v1_0_hw_init(void *handle) done: if (!r) - DRM_INFO("VCN decode and encode initialized successfully.\n"); + DRM_INFO("VCN decode and encode initialized successfully(under %s).\n", + (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)?"DPG Mode":"SPG Mode"); return r; } @@ -266,13 +267,13 @@ static int vcn_v1_0_resume(void *handle) } /** - * vcn_v1_0_mc_resume - memory controller programming + * vcn_v1_0_mc_resume_spg_mode - memory controller programming * * @adev: amdgpu_device pointer * * Let the VCN memory controller know it's offsets */ -static void vcn_v1_0_mc_resume(struct amdgpu_device *adev) +static void vcn_v1_0_mc_resume_spg_mode(struct amdgpu_device *adev) { uint32_t size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4); uint32_t offset; @@ -319,6 +320,65 @@ static void vcn_v1_0_mc_resume(struct amdgpu_device *adev) adev->gfx.config.gb_addr_config); } +static void vcn_v1_0_mc_resume_dpg_mode(struct amdgpu_device *adev) +{ + uint32_t size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4); + uint32_t offset; + + if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { + WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, + (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_lo), +0x, 0); + WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, + (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_hi), +0x, 0); + WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_VCPU_CACHE_OFFSET0, 0, +0x, 0); + offset = 0; + } else { + WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW, + lower_32_bits(adev->vcn.gpu_addr), 0x, 0); + WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH, + upper_32_bits(adev->vcn.gpu_addr), 0x, 0); + offset = size; + WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_VCPU_CACHE_OFFSET0, +AMDGPU_UVD_FIRMWARE_OFFSET >> 3, 0x, 0); + } + + WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_VCPU_CACHE_SIZE0, size, 0x, 0); + + WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW, +lower_32_bits(adev->vcn.gpu_addr + offset), 0x, 0); + WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH, +upper_32_bits(adev->vcn.gpu_addr + offset), 0x, 0); + WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_VCPU_CACHE_OFFSET1, 0, +0x, 0); + WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_VCPU_CACHE_SIZE1, AMDGPU_VCN_HEAP_SIZE, +0x, 0); + + WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW, +lower_32_bits(adev->vcn.gpu_addr + offset + AMDGPU_VCN_HEAP_SIZE), +0x, 0); + WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH, +upper_32_bits(adev->vcn.gpu_addr + offset + AMDGPU_VCN_HEAP_SIZE), +0x, 0); + WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_VCPU_CACHE_OFFSET2, 0, 0x, 0); + WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_VCPU_CACHE_SIZE2, + AMDGPU_VCN_STACK_SIZE + (AMDGPU_VCN_SESSION_SIZE * 40), +0x, 0); + + WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_UDEC_ADDR_CONFIG, + adev->gfx.config.gb_addr_config, 0x, 0); + WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_UDEC_DB_ADDR_CONFIG, + adev->gfx.config.gb_addr_config, 0x, 0); + WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_UDEC_DBW_ADDR_CONFIG, + adev->gfx.config.gb_addr_config, 0x, 0); + WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_JPEG_ADDR_CONFIG, + adev->gfx.config.gb_addr_config, 0x, 0); + WREG32_SOC15_DPG_MODE(UVD, 0, mmUVD_JPEG_UV_ADDR_CONFIG, + adev->gfx.config.gb_addr_config, 0x, 0); +} + /** * vcn_v1_0_disable_clock_gating - disable VCN clock gating * @@ -519,6 +579,62 @@ static void
Re: [PATCH 7/9] drm/amdgpu: add IH ring to ih_get_wptr/ih_set_rptr
On Mon, Sep 24, 2018 at 02:38:18PM +0200, Christian König wrote: > Let's start to support multiple rings. > > Signed-off-by: Christian König Reviewed-by: Huang Rui > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | 6 +++--- > drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 8 > drivers/gpu/drm/amd/amdgpu/cik_ih.c | 16 +--- > drivers/gpu/drm/amd/amdgpu/cz_ih.c | 16 +--- > drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 16 +--- > drivers/gpu/drm/amd/amdgpu/si_ih.c | 16 +--- > drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 28 +++- > drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 32 +--- > 8 files changed, 75 insertions(+), 63 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > index 8af67f649660..fb8dd6179926 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > @@ -137,7 +137,7 @@ int amdgpu_ih_process(struct amdgpu_device *adev, struct > amdgpu_ih_ring *ih, > if (!ih->enabled || adev->shutdown) > return IRQ_NONE; > > - wptr = amdgpu_ih_get_wptr(adev); > + wptr = amdgpu_ih_get_wptr(adev, ih); > > restart_ih: > /* is somebody else already processing irqs? */ > @@ -154,11 +154,11 @@ int amdgpu_ih_process(struct amdgpu_device *adev, > struct amdgpu_ih_ring *ih, > ih->rptr &= ih->ptr_mask; > } > > - amdgpu_ih_set_rptr(adev); > + amdgpu_ih_set_rptr(adev, ih); > atomic_set(>lock, 0); > > /* make sure wptr hasn't changed while processing */ > - wptr = amdgpu_ih_get_wptr(adev); > + wptr = amdgpu_ih_get_wptr(adev, ih); > if (wptr != ih->rptr) > goto restart_ih; > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > index d88f82321ee4..61967e7b64a7 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > @@ -52,12 +52,12 @@ struct amdgpu_ih_ring { > /* provided by the ih block */ > struct amdgpu_ih_funcs { > /* ring read/write ptr handling, called from interrupt context */ > - u32 (*get_wptr)(struct amdgpu_device *adev); > - void (*set_rptr)(struct amdgpu_device *adev); > + u32 (*get_wptr)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); > + void (*set_rptr)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); > }; > > -#define amdgpu_ih_get_wptr(adev) (adev)->irq.ih.funcs->get_wptr((adev)) > -#define amdgpu_ih_set_rptr(adev) (adev)->irq.ih.funcs->set_rptr((adev)) > +#define amdgpu_ih_get_wptr(adev, ih) (ih)->funcs->get_wptr((adev), (ih)) > +#define amdgpu_ih_set_rptr(adev, ih) (ih)->funcs->set_rptr((adev), (ih)) > > int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring > *ih, > unsigned ring_size, bool use_bus_addr); > diff --git a/drivers/gpu/drm/amd/amdgpu/cik_ih.c > b/drivers/gpu/drm/amd/amdgpu/cik_ih.c > index 161f0225749c..341092768809 100644 > --- a/drivers/gpu/drm/amd/amdgpu/cik_ih.c > +++ b/drivers/gpu/drm/amd/amdgpu/cik_ih.c > @@ -183,11 +183,12 @@ static void cik_ih_irq_disable(struct amdgpu_device > *adev) > * Used by cik_irq_process(). > * Returns the value of the wptr. > */ > -static u32 cik_ih_get_wptr(struct amdgpu_device *adev) > +static u32 cik_ih_get_wptr(struct amdgpu_device *adev, > +struct amdgpu_ih_ring *ih) > { > u32 wptr, tmp; > > - wptr = le32_to_cpu(adev->wb.wb[adev->irq.ih.wptr_offs]); > + wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]); > > if (wptr & IH_RB_WPTR__RB_OVERFLOW_MASK) { > wptr &= ~IH_RB_WPTR__RB_OVERFLOW_MASK; > @@ -196,13 +197,13 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev) >* this should allow us to catchup. >*/ > dev_warn(adev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, > 0x%08X)\n", > - wptr, adev->irq.ih.rptr, (wptr + 16) & > adev->irq.ih.ptr_mask); > - adev->irq.ih.rptr = (wptr + 16) & adev->irq.ih.ptr_mask; > + wptr, ih->rptr, (wptr + 16) & ih->ptr_mask); > + ih->rptr = (wptr + 16) & ih->ptr_mask; > tmp = RREG32(mmIH_RB_CNTL); > tmp |= IH_RB_CNTL__WPTR_OVERFLOW_CLEAR_MASK; > WREG32(mmIH_RB_CNTL, tmp); > } > - return (wptr & adev->irq.ih.ptr_mask); > + return (wptr & ih->ptr_mask); > } > > /*CIK IV Ring > @@ -294,9 +295,10 @@ static void cik_ih_decode_iv(struct amdgpu_device *adev, > * > * Set the IH ring buffer rptr. > */ > -static void cik_ih_set_rptr(struct amdgpu_device *adev) > +static void cik_ih_set_rptr(struct amdgpu_device *adev, > + struct amdgpu_ih_ring *ih) > { > - WREG32(mmIH_RB_RPTR, adev->irq.ih.rptr); > + WREG32(mmIH_RB_RPTR, ih->rptr); > } >
Re: [PATCH 6/9] drm/amdgpu: separate IH and IRQ funcs
On Mon, Sep 24, 2018 at 02:38:17PM +0200, Christian König wrote: > One for the ring buffer and one for the IV handling. > > Signed-off-by: Christian König Reviewed-by: Huang Rui How about merge amdgpu_ih.c into amdgpu_irq.c? As I think, we don't need two common interrupt handle files. IH is actually the hw ip block name, and the meaning is actually the same with irq. We can put all common irq handle include ih ring init functions into irq.c. If you also agree, I will file the patch. Thanks, Ray > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 11 --- > drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 4 ++-- > drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h | 11 ++- > drivers/gpu/drm/amd/amdgpu/cik_ih.c | 8 ++-- > drivers/gpu/drm/amd/amdgpu/cz_ih.c | 8 ++-- > drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 8 ++-- > drivers/gpu/drm/amd/amdgpu/si_ih.c | 8 ++-- > drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 8 ++-- > drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 8 ++-- > 9 files changed, 52 insertions(+), 22 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > index 9ce8c93ec19b..d88f82321ee4 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > @@ -45,22 +45,19 @@ struct amdgpu_ih_ring { > booluse_doorbell; > booluse_bus_addr; > dma_addr_t rb_dma_addr; /* only used when use_bus_addr = > true */ > + > + const struct amdgpu_ih_funcs*funcs; > }; > > /* provided by the ih block */ > struct amdgpu_ih_funcs { > /* ring read/write ptr handling, called from interrupt context */ > u32 (*get_wptr)(struct amdgpu_device *adev); > - bool (*prescreen_iv)(struct amdgpu_device *adev); > - void (*decode_iv)(struct amdgpu_device *adev, > - struct amdgpu_iv_entry *entry); > void (*set_rptr)(struct amdgpu_device *adev); > }; > > -#define amdgpu_ih_get_wptr(adev) (adev)->irq.ih_funcs->get_wptr((adev)) > -#define amdgpu_ih_prescreen_iv(adev) > (adev)->irq.ih_funcs->prescreen_iv((adev)) > -#define amdgpu_ih_decode_iv(adev, iv) > (adev)->irq.ih_funcs->decode_iv((adev), (iv)) > -#define amdgpu_ih_set_rptr(adev) (adev)->irq.ih_funcs->set_rptr((adev)) > +#define amdgpu_ih_get_wptr(adev) (adev)->irq.ih.funcs->get_wptr((adev)) > +#define amdgpu_ih_set_rptr(adev) (adev)->irq.ih.funcs->set_rptr((adev)) > > int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring > *ih, > unsigned ring_size, bool use_bus_addr); > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c > index 52c17f6219a7..8e5ce25f3fe1 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c > @@ -163,14 +163,14 @@ static void amdgpu_irq_callback(struct amdgpu_device > *adev, > struct amdgpu_iv_entry entry; > > /* Prescreening of high-frequency interrupts */ > - if (!amdgpu_ih_prescreen_iv(adev)) > + if (!amdgpu_irq_prescreen_iv(adev)) > return; > > /* Before dispatching irq to IP blocks, send it to amdkfd */ > amdgpu_amdkfd_interrupt(adev, (const void *) >ring[ring_index]); > > entry.iv_entry = (const uint32_t *)>ring[ring_index]; > - amdgpu_ih_decode_iv(adev, ); > + amdgpu_irq_decode_iv(adev, ); > > amdgpu_irq_dispatch(adev, ); > } > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h > index f6ce171cb8aa..3cc0e7ce40a0 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h > @@ -68,6 +68,12 @@ struct amdgpu_irq_client { > struct amdgpu_irq_src **sources; > }; > > +struct amdgpu_irq_funcs { > + bool (*prescreen_iv)(struct amdgpu_device *adev); > + void (*decode_iv)(struct amdgpu_device *adev, > + struct amdgpu_iv_entry *entry); > +}; > + > /* provided by interrupt generating IP blocks */ > struct amdgpu_irq_src_funcs { > int (*set)(struct amdgpu_device *adev, struct amdgpu_irq_src *source, > @@ -89,12 +95,12 @@ struct amdgpu_irq { > > /* interrupt ring */ > struct amdgpu_ih_ring ih; > - const struct amdgpu_ih_funcs*ih_funcs; > > /* gen irq stuff */ > struct irq_domain *domain; /* GPU irq controller domain */ > unsignedvirq[AMDGPU_MAX_IRQ_SRC_ID]; > uint32_tsrbm_soft_reset; > + const struct amdgpu_irq_funcs *funcs; > }; > > void amdgpu_irq_disable_all(struct amdgpu_device *adev); > @@ -121,4 +127,7 @@ int amdgpu_irq_add_domain(struct amdgpu_device *adev); > void amdgpu_irq_remove_domain(struct amdgpu_device *adev); > unsigned amdgpu_irq_create_mapping(struct amdgpu_device *adev, unsigned > src_id); > >
Re: [PATCH 3/8] drm/amdgpu:Add DPG support flag
Am 25.09.2018 um 21:55 schrieb James Zhu: Add DPG support flag for VCN DPG mode. Signed-off-by: James Zhu --- drivers/gpu/drm/amd/include/amd_shared.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/amd/include/amd_shared.h b/drivers/gpu/drm/amd/include/amd_shared.h index 86b167e..2f6bdf1 100644 --- a/drivers/gpu/drm/amd/include/amd_shared.h +++ b/drivers/gpu/drm/amd/include/amd_shared.h @@ -110,6 +110,8 @@ enum amd_powergating_state { #define AMD_PG_SUPPORT_MMHUB (1 << 13) #define AMD_PG_SUPPORT_VCN(1 << 14) Looks like you added an extra empty line between AMD_PG_SUPPORT_VCN and the new entry, was that intentional? Apart from that the patches look good to me, but can't judge if that is really correct. Acked-by: Christian König for the series. Regards, Christian. +#define AMD_PG_SUPPORT_DPG (1 << 15) + enum PP_FEATURE_MASK { PP_SCLK_DPM_MASK = 0x1, PP_MCLK_DPM_MASK = 0x2, ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 6/9] drm/amdgpu: separate IH and IRQ funcs
Am 26.09.2018 um 08:05 schrieb Huang Rui: On Mon, Sep 24, 2018 at 02:38:17PM +0200, Christian König wrote: One for the ring buffer and one for the IV handling. Signed-off-by: Christian König Reviewed-by: Huang Rui How about merge amdgpu_ih.c into amdgpu_irq.c? As I think, we don't need two common interrupt handle files. IH is actually the hw ip block name, and the meaning is actually the same with irq. We can put all common irq handle include ih ring init functions into irq.c. If you also agree, I will file the patch. I actually dropped this patch, but we certainly need two different files. The one is for the IH ring buffer, which Vega10 actually has 3 of. The other one is for the IRQ handling which does the tracking how often interrupt sources are enabled, how to route them etc... E.g. for that we would still have one instance per device. Regards, Christian. Thanks, Ray --- drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 11 --- drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h | 11 ++- drivers/gpu/drm/amd/amdgpu/cik_ih.c | 8 ++-- drivers/gpu/drm/amd/amdgpu/cz_ih.c | 8 ++-- drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 8 ++-- drivers/gpu/drm/amd/amdgpu/si_ih.c | 8 ++-- drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 8 ++-- drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 8 ++-- 9 files changed, 52 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h index 9ce8c93ec19b..d88f82321ee4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h @@ -45,22 +45,19 @@ struct amdgpu_ih_ring { booluse_doorbell; booluse_bus_addr; dma_addr_t rb_dma_addr; /* only used when use_bus_addr = true */ + + const struct amdgpu_ih_funcs*funcs; }; /* provided by the ih block */ struct amdgpu_ih_funcs { /* ring read/write ptr handling, called from interrupt context */ u32 (*get_wptr)(struct amdgpu_device *adev); - bool (*prescreen_iv)(struct amdgpu_device *adev); - void (*decode_iv)(struct amdgpu_device *adev, - struct amdgpu_iv_entry *entry); void (*set_rptr)(struct amdgpu_device *adev); }; -#define amdgpu_ih_get_wptr(adev) (adev)->irq.ih_funcs->get_wptr((adev)) -#define amdgpu_ih_prescreen_iv(adev) (adev)->irq.ih_funcs->prescreen_iv((adev)) -#define amdgpu_ih_decode_iv(adev, iv) (adev)->irq.ih_funcs->decode_iv((adev), (iv)) -#define amdgpu_ih_set_rptr(adev) (adev)->irq.ih_funcs->set_rptr((adev)) +#define amdgpu_ih_get_wptr(adev) (adev)->irq.ih.funcs->get_wptr((adev)) +#define amdgpu_ih_set_rptr(adev) (adev)->irq.ih.funcs->set_rptr((adev)) int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, unsigned ring_size, bool use_bus_addr); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index 52c17f6219a7..8e5ce25f3fe1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c @@ -163,14 +163,14 @@ static void amdgpu_irq_callback(struct amdgpu_device *adev, struct amdgpu_iv_entry entry; /* Prescreening of high-frequency interrupts */ - if (!amdgpu_ih_prescreen_iv(adev)) + if (!amdgpu_irq_prescreen_iv(adev)) return; /* Before dispatching irq to IP blocks, send it to amdkfd */ amdgpu_amdkfd_interrupt(adev, (const void *) >ring[ring_index]); entry.iv_entry = (const uint32_t *)>ring[ring_index]; - amdgpu_ih_decode_iv(adev, ); + amdgpu_irq_decode_iv(adev, ); amdgpu_irq_dispatch(adev, ); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h index f6ce171cb8aa..3cc0e7ce40a0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h @@ -68,6 +68,12 @@ struct amdgpu_irq_client { struct amdgpu_irq_src **sources; }; +struct amdgpu_irq_funcs { + bool (*prescreen_iv)(struct amdgpu_device *adev); + void (*decode_iv)(struct amdgpu_device *adev, + struct amdgpu_iv_entry *entry); +}; + /* provided by interrupt generating IP blocks */ struct amdgpu_irq_src_funcs { int (*set)(struct amdgpu_device *adev, struct amdgpu_irq_src *source, @@ -89,12 +95,12 @@ struct amdgpu_irq { /* interrupt ring */ struct amdgpu_ih_ring ih; - const struct amdgpu_ih_funcs*ih_funcs; /* gen irq stuff */ struct irq_domain *domain; /* GPU irq controller domain */ unsignedvirq[AMDGPU_MAX_IRQ_SRC_ID]; uint32_tsrbm_soft_reset; + const struct amdgpu_irq_funcs *funcs; }; void
[PATCH] drm/amd/powerplay: Enable/Disable NBPSTATE on On/OFF of UVD
From: Akshu Agrawal We observe black lines (underflow) on display when playing a 4K video with UVD. On Disabling Low memory P state this issue is not seen. Multiple runs of power measurement shows no imapct. Change-Id: I6171ced550ee244e6b9a961fb50247d12f4168a0 Signed-off-by: Akshu Agrawal Signed-off-by: Satyajit Sahu Acked-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c index b863704..86b6a43 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/smu8_hwmgr.c @@ -1227,14 +1227,17 @@ static int smu8_dpm_force_dpm_level(struct pp_hwmgr *hwmgr, static int smu8_dpm_powerdown_uvd(struct pp_hwmgr *hwmgr) { - if (PP_CAP(PHM_PlatformCaps_UVDPowerGating)) + if (PP_CAP(PHM_PlatformCaps_UVDPowerGating)) { + smu8_nbdpm_pstate_enable_disable(hwmgr, true, true); return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_UVDPowerOFF); + } return 0; } static int smu8_dpm_powerup_uvd(struct pp_hwmgr *hwmgr) { if (PP_CAP(PHM_PlatformCaps_UVDPowerGating)) { + smu8_nbdpm_pstate_enable_disable(hwmgr, false, true); return smum_send_msg_to_smc_with_parameter( hwmgr, PPSMC_MSG_UVDPowerON, -- 1.9.1 ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
Re: [PATCH 5/6] drm/amdgpu: add timeline support in amdgpu CS
static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 1ceec56de015..412359b446f1 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -517,6 +517,8 @@ struct drm_amdgpu_gem_va { #define AMDGPU_CHUNK_ID_SYNCOBJ_IN 0x04 #define AMDGPU_CHUNK_ID_SYNCOBJ_OUT 0x05 #define AMDGPU_CHUNK_ID_BO_HANDLES 0x06 +#define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT0x07 +#define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL 0x08 struct drm_amdgpu_cs_chunk { __u32 chunk_id; @@ -592,6 +594,14 @@ struct drm_amdgpu_cs_chunk_sem { __u32 handle; }; +struct drm_amdgpu_cs_chunk_syncobj { + __u32 handle; + __u32 pad; + __u64 point; + __u64 flags; +}; Sure it's nice to be forward-looking, but can't we just put the flags into the padding? Cheers, Nicolai + + #define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ0 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ_FD 1 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNC_FILE_FD 2 -- Lerne, wie die Welt wirklich ist, Aber vergiss niemals, wie sie sein sollte. ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
RE: [PATCH 8/9] drm/amdgpu: simplify IH programming
> -Original Message- > From: amd-gfx [mailto:amd-gfx-boun...@lists.freedesktop.org] On Behalf > Of Christian K?nig > Sent: Monday, September 24, 2018 8:38 PM > To: amd-gfx@lists.freedesktop.org > Subject: [PATCH 8/9] drm/amdgpu: simplify IH programming > > Calculate all the addresses and pointers in amdgpu_ih.c > > Signed-off-by: Christian König > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | 34 > +-- > drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 23 - > drivers/gpu/drm/amd/amdgpu/cik_ih.c | 9 - > drivers/gpu/drm/amd/amdgpu/cz_ih.c | 11 +- > drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 9 - > drivers/gpu/drm/amd/amdgpu/si_ih.c | 9 - > drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 27 +++-- > drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 36 +++--- > --- > 8 files changed, 73 insertions(+), 85 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > index fb8dd6179926..d0a5db777b6d 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > @@ -52,6 +52,8 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, > struct amdgpu_ih_ring *ih, > ih->use_bus_addr = use_bus_addr; > > if (use_bus_addr) { > + dma_addr_t dma_addr; > + > if (ih->ring) > return 0; > > @@ -59,21 +61,26 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, > struct amdgpu_ih_ring *ih, >* add them to the end of the ring allocation. >*/ > ih->ring = dma_alloc_coherent(adev->dev, ih->ring_size + 8, > - >rb_dma_addr, GFP_KERNEL); > + _addr, GFP_KERNEL); > if (ih->ring == NULL) > return -ENOMEM; > > memset((void *)ih->ring, 0, ih->ring_size + 8); > - ih->wptr_offs = (ih->ring_size / 4) + 0; > - ih->rptr_offs = (ih->ring_size / 4) + 1; > + ih->gpu_addr = dma_addr; I am thinking if program the dma_addr as the member of gpu_addr, it might cause confusion. I know it can avoid the checking when we program the mmIH_RB_BASE. How about use another name for this member? Thanks, Ray > + ih->wptr_addr = dma_addr + ih->ring_size; > + ih->wptr_cpu = >ring[ih->ring_size / 4]; > + ih->rptr_addr = dma_addr + ih->ring_size + 4; > + ih->rptr_cpu = >ring[(ih->ring_size / 4) + 1]; > } else { > - r = amdgpu_device_wb_get(adev, >wptr_offs); > + unsigned wptr_offs, rptr_offs; > + > + r = amdgpu_device_wb_get(adev, _offs); > if (r) > return r; > > - r = amdgpu_device_wb_get(adev, >rptr_offs); > + r = amdgpu_device_wb_get(adev, _offs); > if (r) { > - amdgpu_device_wb_free(adev, ih->wptr_offs); > + amdgpu_device_wb_free(adev, wptr_offs); > return r; > } > > @@ -82,10 +89,15 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, > struct amdgpu_ih_ring *ih, > >ring_obj, >gpu_addr, > (void **)>ring); > if (r) { > - amdgpu_device_wb_free(adev, ih->rptr_offs); > - amdgpu_device_wb_free(adev, ih->wptr_offs); > + amdgpu_device_wb_free(adev, rptr_offs); > + amdgpu_device_wb_free(adev, wptr_offs); > return r; > } > + > + ih->wptr_addr = adev->wb.gpu_addr + wptr_offs * 4; > + ih->wptr_cpu = >wb.wb[wptr_offs]; > + ih->rptr_addr = adev->wb.gpu_addr + rptr_offs * 4; > + ih->rptr_cpu = >wb.wb[rptr_offs]; > } > return 0; > } > @@ -109,13 +121,13 @@ void amdgpu_ih_ring_fini(struct amdgpu_device > *adev, struct amdgpu_ih_ring *ih) >* add them to the end of the ring allocation. >*/ > dma_free_coherent(adev->dev, ih->ring_size + 8, > - (void *)ih->ring, ih->rb_dma_addr); > + (void *)ih->ring, ih->gpu_addr); > ih->ring = NULL; > } else { > amdgpu_bo_free_kernel(>ring_obj, >gpu_addr, > (void **)>ring); > - amdgpu_device_wb_free(adev, ih->wptr_offs); > - amdgpu_device_wb_free(adev, ih->rptr_offs); > + amdgpu_device_wb_free(adev, (ih->wptr_addr - ih- > >gpu_addr) / 4); > + amdgpu_device_wb_free(adev, (ih->rptr_addr - ih- > >gpu_addr) / 4); > } > } > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h >
RE: [PATCH 9/9] drm/amdgpu: enable IH ring 1 and ring 2
> -Original Message- > From: amd-gfx [mailto:amd-gfx-boun...@lists.freedesktop.org] On Behalf > Of Christian K?nig > Sent: Monday, September 24, 2018 8:38 PM > To: amd-gfx@lists.freedesktop.org > Subject: [PATCH 9/9] drm/amdgpu: enable IH ring 1 and ring 2 > > The entries are ignored for now, but it at least stops crashing the hardware > when somebody tries to push something to the other IH rings. > > Signed-off-by: Christian König Reviewed-by: Huang Rui > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h | 4 +- > drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 129 > +--- > 2 files changed, 106 insertions(+), 27 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h > index 3cc0e7ce40a0..0c6af0b38490 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h > @@ -93,8 +93,8 @@ struct amdgpu_irq { > /* status, etc. */ > boolmsi_enabled; /* msi enabled */ > > - /* interrupt ring */ > - struct amdgpu_ih_ring ih; > + /* interrupt rings */ > + struct amdgpu_ih_ring ih, ih1, ih2; > > /* gen irq stuff */ > struct irq_domain *domain; /* GPU irq controller > domain */ > diff --git a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c > b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c > index b4330eccee04..2d2036e0c8b1 100644 > --- a/drivers/gpu/drm/amd/amdgpu/vega10_ih.c > +++ b/drivers/gpu/drm/amd/amdgpu/vega10_ih.c > @@ -50,6 +50,16 @@ static void vega10_ih_enable_interrupts(struct > amdgpu_device *adev) > ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, ENABLE_INTR, > 1); > WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl); > adev->irq.ih.enabled = true; > + > + ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1); > + ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1, > RB_ENABLE, 1); > + WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl); > + adev->irq.ih1.enabled = true; > + > + ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2); > + ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2, > RB_ENABLE, 1); > + WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl); > + adev->irq.ih2.enabled = true; > } > > /** > @@ -71,6 +81,47 @@ static void vega10_ih_disable_interrupts(struct > amdgpu_device *adev) > WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR, 0); > adev->irq.ih.enabled = false; > adev->irq.ih.rptr = 0; > + > + ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1); > + ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1, > RB_ENABLE, 0); > + WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl); > + /* set rptr, wptr to 0 */ > + WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING1, 0); > + WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING1, 0); > + adev->irq.ih1.enabled = false; > + adev->irq.ih1.rptr = 0; > + > + ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2); > + ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2, > RB_ENABLE, 0); > + WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl); > + /* set rptr, wptr to 0 */ > + WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR_RING2, 0); > + WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_RING2, 0); > + adev->irq.ih2.enabled = false; > + adev->irq.ih2.rptr = 0; > +} > + > +static uint32_t vega10_ih_rb_cntl(struct amdgpu_ih_ring *ih, uint32_t > +ih_rb_cntl) { > + int rb_bufsz = order_base_2(ih->ring_size / 4); > + > + ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, > +MC_SPACE, ih->use_bus_addr ? 1 : 4); > + ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, > +WPTR_OVERFLOW_CLEAR, 1); > + ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, > +WPTR_OVERFLOW_ENABLE, 1); > + ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, RB_SIZE, > rb_bufsz); > + /* Ring Buffer write pointer writeback. If enabled, IH_RB_WPTR > register > + * value is written to memory > + */ > + ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, > +WPTR_WRITEBACK_ENABLE, 1); > + ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SNOOP, 1); > + ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_RO, 0); > + ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_VMID, 0); > + > + return ih_rb_cntl; > } > > /** > @@ -86,9 +137,8 @@ static void vega10_ih_disable_interrupts(struct > amdgpu_device *adev) > */ > static int vega10_ih_irq_init(struct amdgpu_device *adev) { > - struct amdgpu_ih_ring *ih = >irq.ih; > + struct amdgpu_ih_ring *ih; > int ret = 0; > - int rb_bufsz; > u32 ih_rb_cntl, ih_doorbell_rtpr; > u32 tmp; > > @@ -97,26 +147,15 @@ static int vega10_ih_irq_init(struct amdgpu_device > *adev) > >
Re: [PATCH 5/9] drm/amdgpu: move more defines into amdgpu_irq.h
On Mon, Sep 24, 2018 at 02:38:16PM +0200, Christian König wrote: > Everything that isn't related to the IH ring. > > Signed-off-by: Christian König Reviewed-by: Huang Rui > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h| 22 +--- > drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 10 - > drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h | 25 > --- > drivers/gpu/drm/amd/amdgpu/ci_dpm.c | 4 ++-- > drivers/gpu/drm/amd/amdgpu/cik_ih.c | 2 +- > drivers/gpu/drm/amd/amdgpu/cik_sdma.c | 6 +++--- > drivers/gpu/drm/amd/amdgpu/cz_ih.c| 2 +- > drivers/gpu/drm/amd/amdgpu/dce_v10_0.c| 6 +++--- > drivers/gpu/drm/amd/amdgpu/dce_v11_0.c| 6 +++--- > drivers/gpu/drm/amd/amdgpu/dce_v6_0.c | 6 +++--- > drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 6 +++--- > drivers/gpu/drm/amd/amdgpu/dce_virtual.c | 2 +- > drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c | 6 +++--- > drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | 6 +++--- > drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 12 +-- > drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c | 4 ++-- > drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | 4 ++-- > drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | 4 ++-- > drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 2 +- > drivers/gpu/drm/amd/amdgpu/kv_dpm.c | 4 ++-- > drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c | 4 ++-- > drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c| 6 +++--- > drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c| 6 +++--- > drivers/gpu/drm/amd/amdgpu/si_dma.c | 4 ++-- > drivers/gpu/drm/amd/amdgpu/si_dpm.c | 4 ++-- > drivers/gpu/drm/amd/amdgpu/si_ih.c| 2 +- > drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 2 +- > drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c | 2 +- > drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c | 2 +- > drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 4 ++-- > drivers/gpu/drm/amd/amdgpu/vce_v2_0.c | 2 +- > drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | 2 +- > drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- > drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c | 6 +++--- > drivers/gpu/drm/amd/powerplay/hwmgr/smu_helper.c | 2 +- > 35 files changed, 94 insertions(+), 95 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > index fd2bbaa20ab4..9ce8c93ec19b 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > @@ -24,12 +24,8 @@ > #ifndef __AMDGPU_IH_H__ > #define __AMDGPU_IH_H__ > > -#include "soc15_ih_clientid.h" > - > struct amdgpu_device; > - > -#define AMDGPU_IH_CLIENTID_LEGACY 0 > -#define AMDGPU_IH_CLIENTID_MAX SOC15_IH_CLIENTID_MAX > +struct amdgpu_iv_entry; > > /* > * R6xx+ IH ring > @@ -51,22 +47,6 @@ struct amdgpu_ih_ring { > dma_addr_t rb_dma_addr; /* only used when use_bus_addr = > true */ > }; > > -#define AMDGPU_IH_SRC_DATA_MAX_SIZE_DW 4 > - > -struct amdgpu_iv_entry { > - unsigned client_id; > - unsigned src_id; > - unsigned ring_id; > - unsigned vmid; > - unsigned vmid_src; > - uint64_t timestamp; > - unsigned timestamp_src; > - unsigned pasid; > - unsigned pasid_src; > - unsigned src_data[AMDGPU_IH_SRC_DATA_MAX_SIZE_DW]; > - const uint32_t *iv_entry; > -}; > - > /* provided by the ih block */ > struct amdgpu_ih_funcs { > /* ring read/write ptr handling, called from interrupt context */ > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c > index 2fca08e130b6..52c17f6219a7 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c > @@ -124,7 +124,7 @@ void amdgpu_irq_disable_all(struct amdgpu_device *adev) > int r; > > spin_lock_irqsave(>irq.lock, irqflags); > - for (i = 0; i < AMDGPU_IH_CLIENTID_MAX; ++i) { > + for (i = 0; i < AMDGPU_IRQ_CLIENTID_MAX; ++i) { > if (!adev->irq.client[i].sources) > continue; > > @@ -302,7 +302,7 @@ void amdgpu_irq_fini(struct amdgpu_device *adev) > cancel_work_sync(>reset_work); > } > > - for (i = 0; i < AMDGPU_IH_CLIENTID_MAX; ++i) { > + for (i = 0; i < AMDGPU_IRQ_CLIENTID_MAX; ++i) { > if (!adev->irq.client[i].sources) > continue; > > @@ -342,7 +342,7 @@ int amdgpu_irq_add_id(struct amdgpu_device *adev, > unsigned client_id, unsigned src_id, > struct amdgpu_irq_src *source) > { > - if (client_id >= AMDGPU_IH_CLIENTID_MAX) > + if (client_id >= AMDGPU_IRQ_CLIENTID_MAX) > return -EINVAL; > > if (src_id >=
Re: [PATCH 5/6] drm/amdgpu: add timeline support in amdgpu CS
Hey Chunming, On 20.09.2018 13:03, Chunming Zhou wrote: @@ -1113,48 +1117,91 @@ static int amdgpu_syncobj_lookup_and_add_to_sync(struct amdgpu_cs_parser *p, } static int amdgpu_cs_process_syncobj_in_dep(struct amdgpu_cs_parser *p, - struct amdgpu_cs_chunk *chunk) + struct amdgpu_cs_chunk *chunk, + bool timeline) { unsigned num_deps; int i, r; - struct drm_amdgpu_cs_chunk_sem *deps; - deps = (struct drm_amdgpu_cs_chunk_sem *)chunk->kdata; - num_deps = chunk->length_dw * 4 / - sizeof(struct drm_amdgpu_cs_chunk_sem); + if (!timeline) { + struct drm_amdgpu_cs_chunk_sem *deps; - for (i = 0; i < num_deps; ++i) { - r = amdgpu_syncobj_lookup_and_add_to_sync(p, deps[i].handle); + deps = (struct drm_amdgpu_cs_chunk_sem *)chunk->kdata; + num_deps = chunk->length_dw * 4 / + sizeof(struct drm_amdgpu_cs_chunk_sem); + for (i = 0; i < num_deps; ++i) { + r = amdgpu_syncobj_lookup_and_add_to_sync(p, deps[i].handle, + 0, 0); if (r) return r; The indentation looks wrong. + } + } else { + struct drm_amdgpu_cs_chunk_syncobj *syncobj_deps; + + syncobj_deps = (struct drm_amdgpu_cs_chunk_syncobj *)chunk->kdata; + num_deps = chunk->length_dw * 4 / + sizeof(struct drm_amdgpu_cs_chunk_syncobj); + for (i = 0; i < num_deps; ++i) { + r = amdgpu_syncobj_lookup_and_add_to_sync(p, syncobj_deps[i].handle, + syncobj_deps[i].point, + syncobj_deps[i].flags); + if (r) + return r; Here as well. So I'm wondering a bit about this uapi. Specifically, what happens if you try to use timeline syncobjs here as dependencies _without_ DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT? My understanding is, it'll just return -EINVAL without any indication as to which syncobj actually failed. What's the caller supposed to do then? Cheers, Nicolai -- Lerne, wie die Welt wirklich ist, Aber vergiss niemals, wie sie sein sollte. ___ amd-gfx mailing list amd-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/amd-gfx
RE: [PATCH 3/9] drm/amdgpu: cleanup amdgpu_ih.c
> -Original Message- > From: Christian König [mailto:ckoenig.leichtzumer...@gmail.com] > Sent: Tuesday, September 25, 2018 7:01 PM > To: Huang, Ray > Cc: amd-gfx@lists.freedesktop.org > Subject: Re: [PATCH 3/9] drm/amdgpu: cleanup amdgpu_ih.c > > Am 25.09.2018 um 12:28 schrieb Huang Rui: > > On Mon, Sep 24, 2018 at 02:38:14PM +0200, Christian König wrote: > >> Cleanup amdgpu_ih.c to be able to handle multiple interrupt rings. > >> > >> Signed-off-by: Christian König > > Reviewed-by: Huang Rui > > > > Will we have multiple interrupt rings in new asic? > > Vega already has 3 of them, we just haven't activated the other yet. > Good to know. I just took a look at the spec. IH ring 1 is used for request log and IH ring 2 is used for translation & invalidation log. They are to support the page migration feature. Do you plan to work on it? Thanks, Ray > Christian. > > > > > Thanks, > > Ray > > > >> --- > >> drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | 152 ++--- > --- > >> drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 8 +- > >> drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 2 +- > >> drivers/gpu/drm/amd/amdgpu/cik_ih.c | 4 +- > >> drivers/gpu/drm/amd/amdgpu/cz_ih.c | 4 +- > >> drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 4 +- > >> drivers/gpu/drm/amd/amdgpu/si_ih.c | 4 +- > >> drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 4 +- > >> drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 4 +- > >> 9 files changed, 84 insertions(+), 102 deletions(-) > >> > >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > >> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > >> index 4ed86218cef3..15fb0f9738ab 100644 > >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > >> @@ -26,44 +26,20 @@ > >> #include "amdgpu_ih.h" > >> #include "amdgpu_amdkfd.h" > >> > >> -/** > >> - * amdgpu_ih_ring_alloc - allocate memory for the IH ring > >> - * > >> - * @adev: amdgpu_device pointer > >> - * > >> - * Allocate a ring buffer for the interrupt controller. > >> - * Returns 0 for success, errors for failure. > >> - */ > >> -static int amdgpu_ih_ring_alloc(struct amdgpu_device *adev) -{ > >> - int r; > >> - > >> - /* Allocate ring buffer */ > >> - if (adev->irq.ih.ring_obj == NULL) { > >> - r = amdgpu_bo_create_kernel(adev, adev->irq.ih.ring_size, > >> - PAGE_SIZE, > AMDGPU_GEM_DOMAIN_GTT, > >> - >irq.ih.ring_obj, > >> - >irq.ih.gpu_addr, > >> - (void **)>irq.ih.ring); > >> - if (r) { > >> - DRM_ERROR("amdgpu: failed to create ih ring buffer > (%d).\n", r); > >> - return r; > >> - } > >> - } > >> - return 0; > >> -} > >> - > >> /** > >>* amdgpu_ih_ring_init - initialize the IH state > >>* > >>* @adev: amdgpu_device pointer > >> + * @ih: ih ring to initialize > >> + * @ring_size: ring size to allocate > >> + * @use_bus_addr: true when we can use dma_alloc_coherent > >>* > >>* Initializes the IH state and allocates a buffer > >>* for the IH ring buffer. > >>* Returns 0 for success, errors for failure. > >>*/ > >> -int amdgpu_ih_ring_init(struct amdgpu_device *adev, unsigned > ring_size, > >> - bool use_bus_addr) > >> +int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct > amdgpu_ih_ring *ih, > >> + unsigned ring_size, bool use_bus_addr) > >> { > >>u32 rb_bufsz; > >>int r; > >> @@ -71,70 +47,76 @@ int amdgpu_ih_ring_init(struct amdgpu_device > *adev, unsigned ring_size, > >>/* Align ring size */ > >>rb_bufsz = order_base_2(ring_size / 4); > >>ring_size = (1 << rb_bufsz) * 4; > >> - adev->irq.ih.ring_size = ring_size; > >> - adev->irq.ih.ptr_mask = adev->irq.ih.ring_size - 1; > >> - adev->irq.ih.rptr = 0; > >> - adev->irq.ih.use_bus_addr = use_bus_addr; > >> - > >> - if (adev->irq.ih.use_bus_addr) { > >> - if (!adev->irq.ih.ring) { > >> - /* add 8 bytes for the rptr/wptr shadows and > >> - * add them to the end of the ring allocation. > >> - */ > >> - adev->irq.ih.ring = pci_alloc_consistent(adev->pdev, > >> - adev- > >irq.ih.ring_size + 8, > >> - > >irq.ih.rb_dma_addr); > >> - if (adev->irq.ih.ring == NULL) > >> - return -ENOMEM; > >> - memset((void *)adev->irq.ih.ring, 0, adev- > >irq.ih.ring_size + 8); > >> - adev->irq.ih.wptr_offs = (adev->irq.ih.ring_size / 4) + > 0; > >> - adev->irq.ih.rptr_offs = (adev->irq.ih.ring_size / 4) + > 1; > >> - } > >> - return 0; > >> + ih->ring_size = ring_size; > >> + ih->ptr_mask =
Re: [PATCH 3/9] drm/amdgpu: cleanup amdgpu_ih.c
Am 26.09.2018 um 10:52 schrieb Huang, Ray: -Original Message- From: Christian König [mailto:ckoenig.leichtzumer...@gmail.com] Sent: Tuesday, September 25, 2018 7:01 PM To: Huang, Ray Cc: amd-gfx@lists.freedesktop.org Subject: Re: [PATCH 3/9] drm/amdgpu: cleanup amdgpu_ih.c Am 25.09.2018 um 12:28 schrieb Huang Rui: On Mon, Sep 24, 2018 at 02:38:14PM +0200, Christian König wrote: Cleanup amdgpu_ih.c to be able to handle multiple interrupt rings. Signed-off-by: Christian König Reviewed-by: Huang Rui Will we have multiple interrupt rings in new asic? Vega already has 3 of them, we just haven't activated the other yet. Good to know. I just took a look at the spec. IH ring 1 is used for request log and IH ring 2 is used for translation & invalidation log. They are to support the page migration feature. Do you plan to work on it? Yes, actually the IH is able to route any IV to any ring based on the client ID, e.g. who is sending the IV. So I'm currently looking into routing the VM faults to ring 2 as well. That should allow us to better handle them and avoid overwhelming the CPU with an interrupt storm in case of page faults. Regards, Christian. Thanks, Ray Christian. Thanks, Ray --- drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | 152 ++--- --- drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 8 +- drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 2 +- drivers/gpu/drm/amd/amdgpu/cik_ih.c | 4 +- drivers/gpu/drm/amd/amdgpu/cz_ih.c | 4 +- drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 4 +- drivers/gpu/drm/amd/amdgpu/si_ih.c | 4 +- drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 4 +- drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 4 +- 9 files changed, 84 insertions(+), 102 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c index 4ed86218cef3..15fb0f9738ab 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c @@ -26,44 +26,20 @@ #include "amdgpu_ih.h" #include "amdgpu_amdkfd.h" -/** - * amdgpu_ih_ring_alloc - allocate memory for the IH ring - * - * @adev: amdgpu_device pointer - * - * Allocate a ring buffer for the interrupt controller. - * Returns 0 for success, errors for failure. - */ -static int amdgpu_ih_ring_alloc(struct amdgpu_device *adev) -{ - int r; - - /* Allocate ring buffer */ - if (adev->irq.ih.ring_obj == NULL) { - r = amdgpu_bo_create_kernel(adev, adev->irq.ih.ring_size, - PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT, - >irq.ih.ring_obj, - >irq.ih.gpu_addr, - (void **)>irq.ih.ring); - if (r) { - DRM_ERROR("amdgpu: failed to create ih ring buffer (%d).\n", r); - return r; - } - } - return 0; -} - /** * amdgpu_ih_ring_init - initialize the IH state * * @adev: amdgpu_device pointer + * @ih: ih ring to initialize + * @ring_size: ring size to allocate + * @use_bus_addr: true when we can use dma_alloc_coherent * * Initializes the IH state and allocates a buffer * for the IH ring buffer. * Returns 0 for success, errors for failure. */ -int amdgpu_ih_ring_init(struct amdgpu_device *adev, unsigned ring_size, - bool use_bus_addr) +int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, + unsigned ring_size, bool use_bus_addr) { u32 rb_bufsz; int r; @@ -71,70 +47,76 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, unsigned ring_size, /* Align ring size */ rb_bufsz = order_base_2(ring_size / 4); ring_size = (1 << rb_bufsz) * 4; - adev->irq.ih.ring_size = ring_size; - adev->irq.ih.ptr_mask = adev->irq.ih.ring_size - 1; - adev->irq.ih.rptr = 0; - adev->irq.ih.use_bus_addr = use_bus_addr; - - if (adev->irq.ih.use_bus_addr) { - if (!adev->irq.ih.ring) { - /* add 8 bytes for the rptr/wptr shadows and -* add them to the end of the ring allocation. -*/ - adev->irq.ih.ring = pci_alloc_consistent(adev->pdev, -adev- irq.ih.ring_size + 8, - irq.ih.rb_dma_addr); - if (adev->irq.ih.ring == NULL) - return -ENOMEM; - memset((void *)adev->irq.ih.ring, 0, adev- irq.ih.ring_size + 8); - adev->irq.ih.wptr_offs = (adev->irq.ih.ring_size / 4) + 0; - adev->irq.ih.rptr_offs = (adev->irq.ih.ring_size / 4) + 1; - } -
RE: [PATCH 6/9] drm/amdgpu: separate IH and IRQ funcs
> -Original Message- > From: Christian König [mailto:ckoenig.leichtzumer...@gmail.com] > Sent: Wednesday, September 26, 2018 4:09 PM > To: Huang, Ray > Cc: amd-gfx@lists.freedesktop.org > Subject: Re: [PATCH 6/9] drm/amdgpu: separate IH and IRQ funcs > > Am 26.09.2018 um 08:05 schrieb Huang Rui: > > On Mon, Sep 24, 2018 at 02:38:17PM +0200, Christian König wrote: > >> One for the ring buffer and one for the IV handling. > >> > >> Signed-off-by: Christian König > > Reviewed-by: Huang Rui > > > > How about merge amdgpu_ih.c into amdgpu_irq.c? As I think, we don't > > need two common interrupt handle files. IH is actually the hw ip block > > name, and the meaning is actually the same with irq. We can put all > > common irq handle include ih ring init functions into irq.c. If you > > also agree, I will file the patch. > > I actually dropped this patch, but we certainly need two different files. > > The one is for the IH ring buffer, which Vega10 actually has 3 of. > > The other one is for the IRQ handling which does the tracking how often > interrupt sources are enabled, how to route them etc... > > E.g. for that we would still have one instance per device. > So you want to separate the hardware-layer abstraction function and IRQ handling for upper-layer on different file? That's also fine. Thanks, Ray > Regards, > Christian. > > > > > Thanks, > > Ray > > > >> --- > >> drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 11 --- > >> drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 4 ++-- > >> drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h | 11 ++- > >> drivers/gpu/drm/amd/amdgpu/cik_ih.c | 8 ++-- > >> drivers/gpu/drm/amd/amdgpu/cz_ih.c | 8 ++-- > >> drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 8 ++-- > >> drivers/gpu/drm/amd/amdgpu/si_ih.c | 8 ++-- > >> drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 8 ++-- > >> drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 8 ++-- > >> 9 files changed, 52 insertions(+), 22 deletions(-) > >> > >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > >> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > >> index 9ce8c93ec19b..d88f82321ee4 100644 > >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > >> @@ -45,22 +45,19 @@ struct amdgpu_ih_ring { > >>booluse_doorbell; > >>booluse_bus_addr; > >>dma_addr_t rb_dma_addr; /* only used when > use_bus_addr = true */ > >> + > >> + const struct amdgpu_ih_funcs*funcs; > >> }; > >> > >> /* provided by the ih block */ > >> struct amdgpu_ih_funcs { > >>/* ring read/write ptr handling, called from interrupt context */ > >>u32 (*get_wptr)(struct amdgpu_device *adev); > >> - bool (*prescreen_iv)(struct amdgpu_device *adev); > >> - void (*decode_iv)(struct amdgpu_device *adev, > >> -struct amdgpu_iv_entry *entry); > >>void (*set_rptr)(struct amdgpu_device *adev); > >> }; > >> > >> -#define amdgpu_ih_get_wptr(adev) > >> (adev)->irq.ih_funcs->get_wptr((adev)) > >> -#define amdgpu_ih_prescreen_iv(adev) > >> (adev)->irq.ih_funcs->prescreen_iv((adev)) > >> -#define amdgpu_ih_decode_iv(adev, iv) > >> (adev)->irq.ih_funcs->decode_iv((adev), (iv)) -#define > >> amdgpu_ih_set_rptr(adev) (adev)->irq.ih_funcs->set_rptr((adev)) > >> +#define amdgpu_ih_get_wptr(adev) > >> +(adev)->irq.ih.funcs->get_wptr((adev)) > >> +#define amdgpu_ih_set_rptr(adev) > >> +(adev)->irq.ih.funcs->set_rptr((adev)) > >> > >> int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct > amdgpu_ih_ring *ih, > >>unsigned ring_size, bool use_bus_addr); diff --git > >> a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c > >> b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c > >> index 52c17f6219a7..8e5ce25f3fe1 100644 > >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c > >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c > >> @@ -163,14 +163,14 @@ static void amdgpu_irq_callback(struct > amdgpu_device *adev, > >>struct amdgpu_iv_entry entry; > >> > >>/* Prescreening of high-frequency interrupts */ > >> - if (!amdgpu_ih_prescreen_iv(adev)) > >> + if (!amdgpu_irq_prescreen_iv(adev)) > >>return; > >> > >>/* Before dispatching irq to IP blocks, send it to amdkfd */ > >>amdgpu_amdkfd_interrupt(adev, (const void *) > >> >ring[ring_index]); > >> > >>entry.iv_entry = (const uint32_t *)>ring[ring_index]; > >> - amdgpu_ih_decode_iv(adev, ); > >> + amdgpu_irq_decode_iv(adev, ); > >> > >>amdgpu_irq_dispatch(adev, ); > >> } > >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h > >> b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h > >> index f6ce171cb8aa..3cc0e7ce40a0 100644 > >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h > >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h > >> @@ -68,6 +68,12 @@ struct amdgpu_irq_client { > >>struct amdgpu_irq_src **sources; > >> }; > >> > >> +struct amdgpu_irq_funcs { > >> + bool (*prescreen_iv)(struct
Re: [PATCH 6/9] drm/amdgpu: separate IH and IRQ funcs
Am 26.09.2018 um 11:16 schrieb Huang, Ray: -Original Message- From: Christian König [mailto:ckoenig.leichtzumer...@gmail.com] Sent: Wednesday, September 26, 2018 4:09 PM To: Huang, Ray Cc: amd-gfx@lists.freedesktop.org Subject: Re: [PATCH 6/9] drm/amdgpu: separate IH and IRQ funcs Am 26.09.2018 um 08:05 schrieb Huang Rui: On Mon, Sep 24, 2018 at 02:38:17PM +0200, Christian König wrote: One for the ring buffer and one for the IV handling. Signed-off-by: Christian König Reviewed-by: Huang Rui How about merge amdgpu_ih.c into amdgpu_irq.c? As I think, we don't need two common interrupt handle files. IH is actually the hw ip block name, and the meaning is actually the same with irq. We can put all common irq handle include ih ring init functions into irq.c. If you also agree, I will file the patch. I actually dropped this patch, but we certainly need two different files. The one is for the IH ring buffer, which Vega10 actually has 3 of. The other one is for the IRQ handling which does the tracking how often interrupt sources are enabled, how to route them etc... E.g. for that we would still have one instance per device. So you want to separate the hardware-layer abstraction function and IRQ handling for upper-layer on different file? Yes, exactly. That's also fine. I'm just not sure about the naming of files, functions and structures. Any better suggestion would be welcome. Christian. Thanks, Ray Regards, Christian. Thanks, Ray --- drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 11 --- drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h | 11 ++- drivers/gpu/drm/amd/amdgpu/cik_ih.c | 8 ++-- drivers/gpu/drm/amd/amdgpu/cz_ih.c | 8 ++-- drivers/gpu/drm/amd/amdgpu/iceland_ih.c | 8 ++-- drivers/gpu/drm/amd/amdgpu/si_ih.c | 8 ++-- drivers/gpu/drm/amd/amdgpu/tonga_ih.c | 8 ++-- drivers/gpu/drm/amd/amdgpu/vega10_ih.c | 8 ++-- 9 files changed, 52 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h index 9ce8c93ec19b..d88f82321ee4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h @@ -45,22 +45,19 @@ struct amdgpu_ih_ring { booluse_doorbell; booluse_bus_addr; dma_addr_t rb_dma_addr; /* only used when use_bus_addr = true */ + + const struct amdgpu_ih_funcs*funcs; }; /* provided by the ih block */ struct amdgpu_ih_funcs { /* ring read/write ptr handling, called from interrupt context */ u32 (*get_wptr)(struct amdgpu_device *adev); - bool (*prescreen_iv)(struct amdgpu_device *adev); - void (*decode_iv)(struct amdgpu_device *adev, - struct amdgpu_iv_entry *entry); void (*set_rptr)(struct amdgpu_device *adev); }; -#define amdgpu_ih_get_wptr(adev) (adev)->irq.ih_funcs->get_wptr((adev)) -#define amdgpu_ih_prescreen_iv(adev) (adev)->irq.ih_funcs->prescreen_iv((adev)) -#define amdgpu_ih_decode_iv(adev, iv) (adev)->irq.ih_funcs->decode_iv((adev), (iv)) -#define amdgpu_ih_set_rptr(adev) (adev)->irq.ih_funcs->set_rptr((adev)) +#define amdgpu_ih_get_wptr(adev) +(adev)->irq.ih.funcs->get_wptr((adev)) +#define amdgpu_ih_set_rptr(adev) +(adev)->irq.ih.funcs->set_rptr((adev)) int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, unsigned ring_size, bool use_bus_addr); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index 52c17f6219a7..8e5ce25f3fe1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c @@ -163,14 +163,14 @@ static void amdgpu_irq_callback(struct amdgpu_device *adev, struct amdgpu_iv_entry entry; /* Prescreening of high-frequency interrupts */ - if (!amdgpu_ih_prescreen_iv(adev)) + if (!amdgpu_irq_prescreen_iv(adev)) return; /* Before dispatching irq to IP blocks, send it to amdkfd */ amdgpu_amdkfd_interrupt(adev, (const void *) >ring[ring_index]); entry.iv_entry = (const uint32_t *)>ring[ring_index]; - amdgpu_ih_decode_iv(adev, ); + amdgpu_irq_decode_iv(adev, ); amdgpu_irq_dispatch(adev, ); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h index f6ce171cb8aa..3cc0e7ce40a0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h @@ -68,6 +68,12 @@ struct amdgpu_irq_client { struct amdgpu_irq_src **sources; }; +struct amdgpu_irq_funcs { + bool (*prescreen_iv)(struct amdgpu_device *adev); + void (*decode_iv)(struct amdgpu_device *adev, + struct amdgpu_iv_entry *entry); }; + /* provided by interrupt
Re: [PATCH 4/9] drm/amdgpu: move more interrupt processing into amdgpu_irq.c
On Mon, Sep 24, 2018 at 02:38:15PM +0200, Christian König wrote: > Add a callback to amdgpu_ih_process to remove most of the IV logic. > > Signed-off-by: Christian König Acked-by: Huang Rui > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | 24 +--- > drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 4 +++- > drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 31 ++- > 3 files changed, 38 insertions(+), 21 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > index 15fb0f9738ab..8af67f649660 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c > @@ -24,7 +24,6 @@ > #include > #include "amdgpu.h" > #include "amdgpu_ih.h" > -#include "amdgpu_amdkfd.h" > > /** > * amdgpu_ih_ring_init - initialize the IH state > @@ -129,9 +128,10 @@ void amdgpu_ih_ring_fini(struct amdgpu_device *adev, > struct amdgpu_ih_ring *ih) > * Interrupt hander (VI), walk the IH ring. > * Returns irq process return code. > */ > -int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih) > +int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, > + void (*callback)(struct amdgpu_device *adev, > +struct amdgpu_ih_ring *ih)) > { > - struct amdgpu_iv_entry entry; > u32 wptr; > > if (!ih->enabled || adev->shutdown) > @@ -150,24 +150,10 @@ int amdgpu_ih_process(struct amdgpu_device *adev, > struct amdgpu_ih_ring *ih) > rmb(); > > while (ih->rptr != wptr) { > - u32 ring_index = ih->rptr >> 2; > - > - /* Prescreening of high-frequency interrupts */ > - if (!amdgpu_ih_prescreen_iv(adev)) { > - ih->rptr &= ih->ptr_mask; > - continue; > - } > - > - /* Before dispatching irq to IP blocks, send it to amdkfd */ > - amdgpu_amdkfd_interrupt(adev, > - (const void *) >ring[ring_index]); > - > - entry.iv_entry = (const uint32_t *)>ring[ring_index]; > - amdgpu_ih_decode_iv(adev, ); > + callback(adev, ih); > ih->rptr &= ih->ptr_mask; > - > - amdgpu_irq_dispatch(adev, ); > } > + > amdgpu_ih_set_rptr(adev); > atomic_set(>lock, 0); > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > index 3e55f985005c..fd2bbaa20ab4 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h > @@ -85,6 +85,8 @@ struct amdgpu_ih_funcs { > int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring > *ih, > unsigned ring_size, bool use_bus_addr); > void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring > *ih); > -int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih); > +int amdgpu_ih_process(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih, > + void (*callback)(struct amdgpu_device *adev, > +struct amdgpu_ih_ring *ih)); > > #endif > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c > index aaa8545e458a..2fca08e130b6 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c > @@ -51,6 +51,7 @@ > #include "atom.h" > #include "amdgpu_connectors.h" > #include "amdgpu_trace.h" > +#include "amdgpu_amdkfd.h" > > #include > > @@ -146,6 +147,34 @@ void amdgpu_irq_disable_all(struct amdgpu_device *adev) > spin_unlock_irqrestore(>irq.lock, irqflags); > } > > +/** > + * amdgpu_irq_callback - callback from the IH ring > + * > + * @adev: amdgpu device pointer > + * @ih: amdgpu ih ring > + * > + * Callback from IH ring processing to handle the entry at the current > position > + * and advance the read pointer. > + */ > +static void amdgpu_irq_callback(struct amdgpu_device *adev, > + struct amdgpu_ih_ring *ih) > +{ > + u32 ring_index = ih->rptr >> 2; > + struct amdgpu_iv_entry entry; > + > + /* Prescreening of high-frequency interrupts */ > + if (!amdgpu_ih_prescreen_iv(adev)) > + return; > + > + /* Before dispatching irq to IP blocks, send it to amdkfd */ > + amdgpu_amdkfd_interrupt(adev, (const void *) >ring[ring_index]); > + > + entry.iv_entry = (const uint32_t *)>ring[ring_index]; > + amdgpu_ih_decode_iv(adev, ); > + > + amdgpu_irq_dispatch(adev, ); > +} > + > /** > * amdgpu_irq_handler - IRQ handler > * > @@ -163,7 +192,7 @@ irqreturn_t amdgpu_irq_handler(int irq, void *arg) > struct amdgpu_device *adev = dev->dev_private; > irqreturn_t ret; > > - ret = amdgpu_ih_process(adev, >irq.ih); > + ret = amdgpu_ih_process(adev, >irq.ih,