Message ID | 1366291559-7672-1-git-send-email-deathsimple@vodafone.de (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Thu, Apr 18, 2013 at 9:25 AM, Christian König <deathsimple@vodafone.de> wrote: > From: Christian König <christian.koenig@amd.com> > > Just power down the PLL when we get a VCLK or DCLK of zero. > Enabling the bypass mode early should also allow us to > switch UVD clocks on the fly. > > Signed-off-by: Christian König <christian.koenig@amd.com> Looks good. both applied. Alex > --- > drivers/gpu/drm/radeon/evergreen.c | 22 ++++++++++++++-------- > drivers/gpu/drm/radeon/rv770.c | 20 +++++++++++++------- > drivers/gpu/drm/radeon/si.c | 22 ++++++++++++++-------- > 3 files changed, 41 insertions(+), 23 deletions(-) > > diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c > index 124c193..facfa84 100644 > --- a/drivers/gpu/drm/radeon/evergreen.c > +++ b/drivers/gpu/drm/radeon/evergreen.c > @@ -189,6 +189,20 @@ int evergreen_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk) > unsigned vco_freq; > int r; > > + /* bypass vclk and dclk with bclk */ > + WREG32_P(CG_UPLL_FUNC_CNTL_2, > + VCLK_SRC_SEL(1) | DCLK_SRC_SEL(1), > + ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK)); > + > + /* put PLL in bypass mode */ > + WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~UPLL_BYPASS_EN_MASK); > + > + if (!vclk || !dclk) { > + /* keep the Bypass mode, put PLL to sleep */ > + WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_SLEEP_MASK, ~UPLL_SLEEP_MASK); > + return 0; > + } > + > /* loop through vco from low to high */ > for (vco_freq = 125000; vco_freq <= 250000; vco_freq += 100) { > unsigned fb_div = vco_freq / rdev->clock.spll.reference_freq * 16384; > @@ -236,14 +250,6 @@ int evergreen_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk) > > mdelay(1); > > - /* bypass vclk and dclk with bclk */ > - WREG32_P(CG_UPLL_FUNC_CNTL_2, > - VCLK_SRC_SEL(1) | DCLK_SRC_SEL(1), > - ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK)); > - > - /* put PLL in bypass mode */ > - WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~UPLL_BYPASS_EN_MASK); > - > r = evergreen_uvd_send_upll_ctlreq(rdev); > if (r) > return r; > diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c > index 777f537..59065ba 100644 > --- a/drivers/gpu/drm/radeon/rv770.c > +++ b/drivers/gpu/drm/radeon/rv770.c > @@ -100,6 +100,17 @@ int rv770_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk) > if (rdev->family == CHIP_RV740) > return evergreen_set_uvd_clocks(rdev, vclk, dclk); > > + /* bypass vclk and dclk with bclk */ > + WREG32_P(CG_UPLL_FUNC_CNTL_2, > + VCLK_SRC_SEL(1) | DCLK_SRC_SEL(1), > + ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK)); > + > + if (!vclk || !dclk) { > + /* keep the Bypass mode, put PLL to sleep */ > + WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_SLEEP_MASK, ~UPLL_SLEEP_MASK); > + return 0; > + } > + > /* loop through vco from low to high */ > vco_min = max(max(vco_min, vclk), dclk); > for (vco_freq = vco_min; vco_freq <= vco_max; vco_freq += 500) { > @@ -139,16 +150,11 @@ int rv770_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk) > } > } > > - /* bypass vclk and dclk with bclk */ > - WREG32_P(CG_UPLL_FUNC_CNTL_2, > - VCLK_SRC_SEL(1) | DCLK_SRC_SEL(1), > - ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK)); > - > /* set UPLL_FB_DIV to 0x50000 */ > WREG32_P(CG_UPLL_FUNC_CNTL_3, UPLL_FB_DIV(0x50000), ~UPLL_FB_DIV_MASK); > > - /* deassert UPLL_RESET */ > - WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_RESET_MASK); > + /* deassert UPLL_RESET and UPLL_SLEEP */ > + WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~(UPLL_RESET_MASK | UPLL_SLEEP_MASK)); > > /* assert BYPASS EN and FB_DIV[0] <- ??? why? */ > WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~UPLL_BYPASS_EN_MASK); > diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c > index aa2c555..b7d78f2 100644 > --- a/drivers/gpu/drm/radeon/si.c > +++ b/drivers/gpu/drm/radeon/si.c > @@ -4680,6 +4680,20 @@ int si_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk) > unsigned vco_freq; > int r; > > + /* bypass vclk and dclk with bclk */ > + WREG32_P(CG_UPLL_FUNC_CNTL_2, > + VCLK_SRC_SEL(1) | DCLK_SRC_SEL(1), > + ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK)); > + > + /* put PLL in bypass mode */ > + WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~UPLL_BYPASS_EN_MASK); > + > + if (!vclk || !dclk) { > + /* keep the Bypass mode, put PLL to sleep */ > + WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_SLEEP_MASK, ~UPLL_SLEEP_MASK); > + return 0; > + } > + > /* loop through vco from low to high */ > for (vco_freq = 125000; vco_freq <= 250000; vco_freq += 100) { > unsigned fb_div = vco_freq / rdev->clock.spll.reference_freq * 16384; > @@ -4730,14 +4744,6 @@ int si_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk) > > mdelay(1); > > - /* bypass vclk and dclk with bclk */ > - WREG32_P(CG_UPLL_FUNC_CNTL_2, > - VCLK_SRC_SEL(1) | DCLK_SRC_SEL(1), > - ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK)); > - > - /* put PLL in bypass mode */ > - WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~UPLL_BYPASS_EN_MASK); > - > r = si_uvd_send_upll_ctlreq(rdev); > if (r) > return r; > -- > 1.7.10.4 > > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/dri-devel
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 124c193..facfa84 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -189,6 +189,20 @@ int evergreen_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk) unsigned vco_freq; int r; + /* bypass vclk and dclk with bclk */ + WREG32_P(CG_UPLL_FUNC_CNTL_2, + VCLK_SRC_SEL(1) | DCLK_SRC_SEL(1), + ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK)); + + /* put PLL in bypass mode */ + WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~UPLL_BYPASS_EN_MASK); + + if (!vclk || !dclk) { + /* keep the Bypass mode, put PLL to sleep */ + WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_SLEEP_MASK, ~UPLL_SLEEP_MASK); + return 0; + } + /* loop through vco from low to high */ for (vco_freq = 125000; vco_freq <= 250000; vco_freq += 100) { unsigned fb_div = vco_freq / rdev->clock.spll.reference_freq * 16384; @@ -236,14 +250,6 @@ int evergreen_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk) mdelay(1); - /* bypass vclk and dclk with bclk */ - WREG32_P(CG_UPLL_FUNC_CNTL_2, - VCLK_SRC_SEL(1) | DCLK_SRC_SEL(1), - ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK)); - - /* put PLL in bypass mode */ - WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~UPLL_BYPASS_EN_MASK); - r = evergreen_uvd_send_upll_ctlreq(rdev); if (r) return r; diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 777f537..59065ba 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -100,6 +100,17 @@ int rv770_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk) if (rdev->family == CHIP_RV740) return evergreen_set_uvd_clocks(rdev, vclk, dclk); + /* bypass vclk and dclk with bclk */ + WREG32_P(CG_UPLL_FUNC_CNTL_2, + VCLK_SRC_SEL(1) | DCLK_SRC_SEL(1), + ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK)); + + if (!vclk || !dclk) { + /* keep the Bypass mode, put PLL to sleep */ + WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_SLEEP_MASK, ~UPLL_SLEEP_MASK); + return 0; + } + /* loop through vco from low to high */ vco_min = max(max(vco_min, vclk), dclk); for (vco_freq = vco_min; vco_freq <= vco_max; vco_freq += 500) { @@ -139,16 +150,11 @@ int rv770_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk) } } - /* bypass vclk and dclk with bclk */ - WREG32_P(CG_UPLL_FUNC_CNTL_2, - VCLK_SRC_SEL(1) | DCLK_SRC_SEL(1), - ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK)); - /* set UPLL_FB_DIV to 0x50000 */ WREG32_P(CG_UPLL_FUNC_CNTL_3, UPLL_FB_DIV(0x50000), ~UPLL_FB_DIV_MASK); - /* deassert UPLL_RESET */ - WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_RESET_MASK); + /* deassert UPLL_RESET and UPLL_SLEEP */ + WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~(UPLL_RESET_MASK | UPLL_SLEEP_MASK)); /* assert BYPASS EN and FB_DIV[0] <- ??? why? */ WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~UPLL_BYPASS_EN_MASK); diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index aa2c555..b7d78f2 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -4680,6 +4680,20 @@ int si_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk) unsigned vco_freq; int r; + /* bypass vclk and dclk with bclk */ + WREG32_P(CG_UPLL_FUNC_CNTL_2, + VCLK_SRC_SEL(1) | DCLK_SRC_SEL(1), + ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK)); + + /* put PLL in bypass mode */ + WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~UPLL_BYPASS_EN_MASK); + + if (!vclk || !dclk) { + /* keep the Bypass mode, put PLL to sleep */ + WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_SLEEP_MASK, ~UPLL_SLEEP_MASK); + return 0; + } + /* loop through vco from low to high */ for (vco_freq = 125000; vco_freq <= 250000; vco_freq += 100) { unsigned fb_div = vco_freq / rdev->clock.spll.reference_freq * 16384; @@ -4730,14 +4744,6 @@ int si_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk) mdelay(1); - /* bypass vclk and dclk with bclk */ - WREG32_P(CG_UPLL_FUNC_CNTL_2, - VCLK_SRC_SEL(1) | DCLK_SRC_SEL(1), - ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK)); - - /* put PLL in bypass mode */ - WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~UPLL_BYPASS_EN_MASK); - r = si_uvd_send_upll_ctlreq(rdev); if (r) return r;