2013/8/1 Deucher, Alexander <alexander.deuc...@amd.com> > > -----Original Message----- > > From: Anthoine Bourgeois [mailto:anthoine.bourge...@gmail.com] > > Sent: Wednesday, July 31, 2013 6:34 PM > > To: Deucher, Alexander; Koenig, Christian; Jerome Glisse; Anthoine > > Bourgeois > > Cc: dri-devel@lists.freedesktop.org > > Subject: [PATCH] drm/radeon/dpm: implement force performance levels for > > rs780 > > > > Allows you to limit the selected power levels via sysfs. > > > > Force the feedback divider to select a power level. > > Nice work. A few comments below. > > Alex > > > > > Signed-off-by: Anthoine Bourgeois <anthoine.bourge...@gmail.com> > > --- > > drivers/gpu/drm/radeon/radeon_asic.c | 1 + > > drivers/gpu/drm/radeon/radeon_asic.h | 2 ++ > > drivers/gpu/drm/radeon/rs780_dpm.c | 67 > > ++++++++++++++++++++++++++++++------ > > 3 files changed, 59 insertions(+), 11 deletions(-) > > > > diff --git a/drivers/gpu/drm/radeon/radeon_asic.c > > b/drivers/gpu/drm/radeon/radeon_asic.c > > index f8f8b31..437d357 100644 > > --- a/drivers/gpu/drm/radeon/radeon_asic.c > > +++ b/drivers/gpu/drm/radeon/radeon_asic.c > > @@ -1272,6 +1272,7 @@ static struct radeon_asic rs780_asic = { > > .get_mclk = &rs780_dpm_get_mclk, > > .print_power_state = &rs780_dpm_print_power_state, > > .debugfs_print_current_performance_level = > > &rs780_dpm_debugfs_print_current_performance_level, > > + .force_performance_level = > > &rs780_dpm_force_performance_level, > > }, > > .pflip = { > > .pre_page_flip = &rs600_pre_page_flip, > > diff --git a/drivers/gpu/drm/radeon/radeon_asic.h > > b/drivers/gpu/drm/radeon/radeon_asic.h > > index 902479f..09841fc 100644 > > --- a/drivers/gpu/drm/radeon/radeon_asic.h > > +++ b/drivers/gpu/drm/radeon/radeon_asic.h > > @@ -437,6 +437,8 @@ void rs780_dpm_print_power_state(struct > > radeon_device *rdev, > > struct radeon_ps *ps); > > void rs780_dpm_debugfs_print_current_performance_level(struct > > radeon_device *rdev, > > struct seq_file *m); > > +int rs780_dpm_force_performance_level(struct radeon_device *rdev, > > + enum radeon_dpm_forced_level level); > > > > /* uvd */ > > int r600_uvd_init(struct radeon_device *rdev); > > diff --git a/drivers/gpu/drm/radeon/rs780_dpm.c > > b/drivers/gpu/drm/radeon/rs780_dpm.c > > index d1a1ce7..df58e34 100644 > > --- a/drivers/gpu/drm/radeon/rs780_dpm.c > > +++ b/drivers/gpu/drm/radeon/rs780_dpm.c > > @@ -404,6 +404,27 @@ static void rs780_force_voltage_to_high(struct > > radeon_device *rdev) > > WREG32_P(GFX_MACRO_BYPASS_CNTL, 0, ~SPLL_BYPASS_CNTL); > > } > > > > +static void rs780_force_fbdiv(struct radeon_device *rdev, u32 fb_div) > > +{ > > + struct igp_ps *current_state = rs780_get_ps(rdev- > > >pm.dpm.current_ps); > > + > > + if ((current_state->sclk_low == fb_div) && > > + (current_state->sclk_high == fb_div)) > > + return; > > I'm not quite sure what you are checking here. >
Oh yes, my mistake, fb_div shouldn't be in that condition. In my memory, I just wanted to check that sclk_low is equal to sclk_high. In that case, no need to force the fbdiv because there are the same. > > > + > > + WREG32_P(GFX_MACRO_BYPASS_CNTL, SPLL_BYPASS_CNTL, > > ~SPLL_BYPASS_CNTL); > > + > > + WREG32_P(FVTHROT_FBDIV_REG2, > > FORCED_FEEDBACK_DIV(fb_div), > > + ~FORCED_FEEDBACK_DIV_MASK); > > + WREG32_P(FVTHROT_FBDIV_REG1, > > STARTING_FEEDBACK_DIV(fb_div), > > + ~STARTING_FEEDBACK_DIV_MASK); > > + WREG32_P(FVTHROT_FBDIV_REG1, FORCE_FEEDBACK_DIV, > > ~FORCE_FEEDBACK_DIV); > > + > > + udelay(100); > > + > > + WREG32_P(GFX_MACRO_BYPASS_CNTL, 0, ~SPLL_BYPASS_CNTL); > > +} > > + > > static int rs780_set_engine_clock_scaling(struct radeon_device *rdev, > > struct radeon_ps *new_ps, > > struct radeon_ps *old_ps) > > @@ -432,17 +453,7 @@ static int rs780_set_engine_clock_scaling(struct > > radeon_device *rdev, > > if (ret) > > return ret; > > > > - WREG32_P(GFX_MACRO_BYPASS_CNTL, SPLL_BYPASS_CNTL, > > ~SPLL_BYPASS_CNTL); > > - > > - WREG32_P(FVTHROT_FBDIV_REG2, > > FORCED_FEEDBACK_DIV(max_dividers.fb_div), > > - ~FORCED_FEEDBACK_DIV_MASK); > > - WREG32_P(FVTHROT_FBDIV_REG1, > > STARTING_FEEDBACK_DIV(max_dividers.fb_div), > > - ~STARTING_FEEDBACK_DIV_MASK); > > - WREG32_P(FVTHROT_FBDIV_REG1, FORCE_FEEDBACK_DIV, > > ~FORCE_FEEDBACK_DIV); > > - > > - udelay(100); > > - > > - WREG32_P(GFX_MACRO_BYPASS_CNTL, 0, ~SPLL_BYPASS_CNTL); > > + rs780_force_fbdiv(rdev, max_dividers.fb_div); > > > > if (max_dividers.fb_div > min_dividers.fb_div) { > > WREG32_P(FVTHROT_FBDIV_REG0, > > @@ -986,3 +997,37 @@ void > > rs780_dpm_debugfs_print_current_performance_level(struct > > radeon_device *rde > > seq_printf(m, "power level 1 sclk: %u vddc_index: %d\n", > > ps->sclk_high, ps->max_voltage); > > } > > + > > +int rs780_dpm_force_performance_level(struct radeon_device *rdev, > > + enum radeon_dpm_forced_level level) > > +{ > > + struct radeon_ps *rps = rdev->pm.dpm.current_ps; > > + struct igp_ps *ps = rs780_get_ps(rps); > > + struct atom_clock_dividers min_dividers, max_dividers; > > You can drop the separate min and max and just use a single dividers > struct. OK. > Also, > You are only forcing the sclk. It would probably also be a good idea to > force the voltage levels. > OK, I'm working on it but I can't test it, my board (RS880) doesn't seem to support the voltage scaling. I'll do my best. Anthoine > > > + int ret; > > + > > + rs780_clk_scaling_enable(rdev, false); > > + > > + if (level == RADEON_DPM_FORCED_LEVEL_HIGH) { > > + ret = radeon_atom_get_clock_dividers(rdev, > > COMPUTE_ENGINE_PLL_PARAM, > > + ps->sclk_high, false, > > &max_dividers); > > + if (ret) > > + return ret; > > + > > + rs780_force_fbdiv(rdev, max_dividers.fb_div); > > + } else if (level == RADEON_DPM_FORCED_LEVEL_LOW) { > > + ret = radeon_atom_get_clock_dividers(rdev, > > COMPUTE_ENGINE_PLL_PARAM, > > + ps->sclk_low, false, > > &min_dividers); > > + if (ret) > > + return ret; > > + > > + rs780_force_fbdiv(rdev, min_dividers.fb_div); > > + } else { > > + WREG32_P(FVTHROT_FBDIV_REG1, 0, > > ~FORCE_FEEDBACK_DIV); > > + rs780_clk_scaling_enable(rdev, true); > > + } > > + > > + rdev->pm.dpm.forced_level = level; > > + > > + return 0; > > +} > > -- > > 1.8.1.5 > > > > >
_______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel