> -----Original Message----- > From: amd-gfx [mailto:amd-gfx-bounces at lists.freedesktop.org] On Behalf > Of Rex Zhu > Sent: Wednesday, November 09, 2016 2:42 AM > To: amd-gfx at lists.freedesktop.org > Cc: Zhu, Rex > Subject: [PATCH 4/5] drm/amdgpu: refine uvd 6.0 clock gate feature. > > Change-Id: I3b665f26689dd35750e1a6521cd5fac5456f7556 > Signed-off-by: Rex Zhu <Rex.Zhu at amd.com> Can someone make sure this doesn't regress CZ and ST? As long as they are still ok, the patches 4, 5 are: Reviewed-by: Alex Deucher <alexander.deucher at amd.com> > --- > drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 112 > ++++++++++++++++++++++++++++------ > 1 file changed, 92 insertions(+), 20 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c > b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c > index 00fad69..c697a73 100644 > --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c > @@ -42,6 +42,10 @@ static void uvd_v6_0_set_irq_funcs(struct > amdgpu_device *adev); > static int uvd_v6_0_start(struct amdgpu_device *adev); > static void uvd_v6_0_stop(struct amdgpu_device *adev); > static void uvd_v6_0_set_sw_clock_gating(struct amdgpu_device *adev); > +static int uvd_v6_0_set_clockgating_state(void *handle, > + enum amd_clockgating_state state); > +static void uvd_v6_0_enable_mgcg(struct amdgpu_device *adev, > + bool enable); > > /** > * uvd_v6_0_ring_get_rptr - get read pointer > @@ -151,8 +155,6 @@ static int uvd_v6_0_hw_init(void *handle) > uint32_t tmp; > int r; > > - amdgpu_asic_set_uvd_clocks(adev, 10000, 10000); > - > r = uvd_v6_0_start(adev); > if (r) > goto done; > @@ -395,11 +397,11 @@ static int uvd_v6_0_start(struct amdgpu_device > *adev) > lmi_swap_cntl = 0; > mp_swap_cntl = 0; > > + amdgpu_asic_set_uvd_clocks(adev, 10000, 10000); > + uvd_v6_0_set_clockgating_state(adev, AMD_CG_STATE_UNGATE); > + uvd_v6_0_enable_mgcg(adev, true); > uvd_v6_0_mc_resume(adev); > > - /* disable clock gating */ > - WREG32_FIELD(UVD_CGC_CTRL, DYN_CLOCK_MODE, 0); > - > /* disable interupt */ > WREG32_FIELD(UVD_MASTINT_EN, VCPU_EN, 0); > > @@ -838,22 +840,69 @@ static int uvd_v6_0_process_interrupt(struct > amdgpu_device *adev, > return 0; > } > > +static void uvd_v6_0_enable_clock_gating(struct amdgpu_device *adev, > bool enable) > +{ > + uint32_t data1, data3; > + > + data1 = RREG32(mmUVD_SUVD_CGC_GATE); > + data3 = RREG32(mmUVD_CGC_GATE); > + > + data1 |= UVD_SUVD_CGC_GATE__SRE_MASK | > + UVD_SUVD_CGC_GATE__SIT_MASK | > + UVD_SUVD_CGC_GATE__SMP_MASK | > + UVD_SUVD_CGC_GATE__SCM_MASK | > + UVD_SUVD_CGC_GATE__SDB_MASK | > + UVD_SUVD_CGC_GATE__SRE_H264_MASK | > + UVD_SUVD_CGC_GATE__SRE_HEVC_MASK | > + UVD_SUVD_CGC_GATE__SIT_H264_MASK | > + UVD_SUVD_CGC_GATE__SIT_HEVC_MASK | > + UVD_SUVD_CGC_GATE__SCM_H264_MASK | > + UVD_SUVD_CGC_GATE__SCM_HEVC_MASK | > + UVD_SUVD_CGC_GATE__SDB_H264_MASK | > + UVD_SUVD_CGC_GATE__SDB_HEVC_MASK; > + > + if (enable) { > + data3 |= (UVD_CGC_GATE__SYS_MASK | > + UVD_CGC_GATE__UDEC_MASK | > + UVD_CGC_GATE__MPEG2_MASK | > + UVD_CGC_GATE__RBC_MASK | > + UVD_CGC_GATE__LMI_MC_MASK | > + UVD_CGC_GATE__LMI_UMC_MASK | > + UVD_CGC_GATE__IDCT_MASK | > + UVD_CGC_GATE__MPRD_MASK | > + UVD_CGC_GATE__MPC_MASK | > + UVD_CGC_GATE__LBSI_MASK | > + UVD_CGC_GATE__LRBBM_MASK | > + UVD_CGC_GATE__UDEC_RE_MASK | > + UVD_CGC_GATE__UDEC_CM_MASK | > + UVD_CGC_GATE__UDEC_IT_MASK | > + UVD_CGC_GATE__UDEC_DB_MASK | > + UVD_CGC_GATE__UDEC_MP_MASK | > + UVD_CGC_GATE__WCB_MASK | > + UVD_CGC_GATE__VCPU_MASK | > + UVD_CGC_GATE__JPEG_MASK | > + UVD_CGC_GATE__SCPU_MASK | > + UVD_CGC_GATE__JPEG2_MASK); > + data3 &= ~UVD_CGC_GATE__REGS_MASK; > + } else { > + data3 = 0; > + } > + > + WREG32(mmUVD_SUVD_CGC_GATE, data1); > + WREG32(mmUVD_CGC_GATE, data3); > +} > + > static void uvd_v6_0_set_sw_clock_gating(struct amdgpu_device *adev) > { > - uint32_t data, data1, data2, suvd_flags; > + uint32_t data, data2; > > data = RREG32(mmUVD_CGC_CTRL); > - data1 = RREG32(mmUVD_SUVD_CGC_GATE); > data2 = RREG32(mmUVD_SUVD_CGC_CTRL); > > + > data &= ~(UVD_CGC_CTRL__CLK_OFF_DELAY_MASK | > UVD_CGC_CTRL__CLK_GATE_DLY_TIMER_MASK); > > - suvd_flags = UVD_SUVD_CGC_GATE__SRE_MASK | > - UVD_SUVD_CGC_GATE__SIT_MASK | > - UVD_SUVD_CGC_GATE__SMP_MASK | > - UVD_SUVD_CGC_GATE__SCM_MASK | > - UVD_SUVD_CGC_GATE__SDB_MASK; > > data |= UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK | > (1 << REG_FIELD_SHIFT(UVD_CGC_CTRL, > CLK_GATE_DLY_TIMER)) | > @@ -886,11 +935,8 @@ static void uvd_v6_0_set_sw_clock_gating(struct > amdgpu_device *adev) > UVD_SUVD_CGC_CTRL__SMP_MODE_MASK | > UVD_SUVD_CGC_CTRL__SCM_MODE_MASK | > UVD_SUVD_CGC_CTRL__SDB_MODE_MASK); > - data1 |= suvd_flags; > > WREG32(mmUVD_CGC_CTRL, data); > - WREG32(mmUVD_CGC_GATE, 0); > - WREG32(mmUVD_SUVD_CGC_GATE, data1); > WREG32(mmUVD_SUVD_CGC_CTRL, data2); > } > > @@ -937,6 +983,32 @@ static void uvd_v6_0_set_hw_clock_gating(struct > amdgpu_device *adev) > } > #endif > > +static void uvd_v6_0_enable_mgcg(struct amdgpu_device *adev, > + bool enable) > +{ > + u32 orig, data; > + > + if (enable && (adev->cg_flags & AMD_CG_SUPPORT_UVD_MGCG)) > { > + data = RREG32_UVD_CTX(ixUVD_CGC_MEM_CTRL); > + data |= 0xfff; > + WREG32_UVD_CTX(ixUVD_CGC_MEM_CTRL, data); > + > + orig = data = RREG32(mmUVD_CGC_CTRL); > + data |= UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK; > + if (orig != data) > + WREG32(mmUVD_CGC_CTRL, data); > + } else { > + data = RREG32_UVD_CTX(ixUVD_CGC_MEM_CTRL); > + data &= ~0xfff; > + WREG32_UVD_CTX(ixUVD_CGC_MEM_CTRL, data); > + > + orig = data = RREG32(mmUVD_CGC_CTRL); > + data &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK; > + if (orig != data) > + WREG32(mmUVD_CGC_CTRL, data); > + } > +} > + > static int uvd_v6_0_set_clockgating_state(void *handle, > enum amd_clockgating_state state) > { > @@ -947,17 +1019,17 @@ static int uvd_v6_0_set_clockgating_state(void > *handle, > return 0; > > if (enable) { > - /* disable HW gating and enable Sw gating */ > - uvd_v6_0_set_sw_clock_gating(adev); > - } else { > /* wait for STATUS to clear */ > if (uvd_v6_0_wait_for_idle(handle)) > return -EBUSY; > - > + uvd_v6_0_enable_clock_gating(adev, true); > /* enable HW gates because UVD is idle */ > /* uvd_v6_0_set_hw_clock_gating(adev); */ > + } else { > + /* disable HW gating and enable Sw gating */ > + uvd_v6_0_enable_clock_gating(adev, false); > } > - > + uvd_v6_0_set_sw_clock_gating(adev); > return 0; > } > > -- > 1.9.1 > > _______________________________________________ > amd-gfx mailing list > amd-gfx at lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/amd-gfx