All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jerome Glisse <j.glisse@gmail.com>
To: Alex Deucher <alexdeucher@gmail.com>
Cc: Alex Deucher <alexander.deucher@amd.com>,
	dri-devel@lists.freedesktop.org
Subject: Re: [PATCH 075/165] drm/radeon/kms: add dpm support for rs780/rs880
Date: Wed, 26 Jun 2013 09:18:05 -0400	[thread overview]
Message-ID: <20130626131804.GI2480@gmail.com> (raw)
In-Reply-To: <CADnq5_ODH3h3p5CVwNjB3XMQuOEeR6=OP_W8m_40+c=qeF4pfQ@mail.gmail.com>

On Wed, Jun 26, 2013 at 02:19:23PM -0400, Alex Deucher wrote:
> On Wed, Jun 26, 2013 at 6:46 AM, Jerome Glisse <j.glisse@gmail.com> wrote:
> > On Wed, Jun 26, 2013 at 09:22:35AM -0400, alexdeucher@gmail.com wrote:
> >> From: Alex Deucher <alexander.deucher@amd.com>
> >>
> >> This adds dpm support for rs780/rs880 asics.  This includes:
> >> - clockgating
> >> - dynamic engine clock scaling
> >> - dynamic voltage scaling
> >>
> >> set radeon.dpm=1 to enable it.
> >>
> >> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
> >
> > Depending on the answer to inline question :
> >
> > Reviewed-by: Jerome Glisse <jglisse@redhat.com>
> >
> >> ---
> >>  drivers/gpu/drm/radeon/Makefile      |    2 +-
> >>  drivers/gpu/drm/radeon/radeon_asic.c |   12 +
> >>  drivers/gpu/drm/radeon/radeon_asic.h |   12 +
> >>  drivers/gpu/drm/radeon/radeon_pm.c   |    7 +
> >>  drivers/gpu/drm/radeon/rs780_dpm.c   |  894 ++++++++++++++++++++++++++++++++++
> >>  drivers/gpu/drm/radeon/rs780_dpm.h   |  109 ++++
> >>  drivers/gpu/drm/radeon/rs780d.h      |  168 +++++++
> >>  7 files changed, 1203 insertions(+), 1 deletions(-)
> >>  create mode 100644 drivers/gpu/drm/radeon/rs780_dpm.c
> >>  create mode 100644 drivers/gpu/drm/radeon/rs780_dpm.h
> >>  create mode 100644 drivers/gpu/drm/radeon/rs780d.h
> >>
> >> diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
> >> index a131a13..e44b046 100644
> >> --- a/drivers/gpu/drm/radeon/Makefile
> >> +++ b/drivers/gpu/drm/radeon/Makefile
> >> @@ -77,7 +77,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
> >>       evergreen_hdmi.o radeon_trace_points.o ni.o cayman_blit_shaders.o \
> >>       atombios_encoders.o radeon_semaphore.o radeon_sa.o atombios_i2c.o si.o \
> >>       si_blit_shaders.o radeon_prime.o radeon_uvd.o cik.o cik_blit_shaders.o \
> >> -     r600_dpm.o
> >> +     r600_dpm.o rs780_dpm.o
> >>
> >>  radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
> >>  radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
> >> diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
> >> index d9c8e9a..db3c930 100644
> >> --- a/drivers/gpu/drm/radeon/radeon_asic.c
> >> +++ b/drivers/gpu/drm/radeon/radeon_asic.c
> >> @@ -1194,6 +1194,18 @@ static struct radeon_asic rs780_asic = {
> >>               .set_clock_gating = NULL,
> >>               .get_temperature = &rv6xx_get_temp,
> >>       },
> >> +     .dpm = {
> >> +             .init = &rs780_dpm_init,
> >> +             .setup_asic = &rs780_dpm_setup_asic,
> >> +             .enable = &rs780_dpm_enable,
> >> +             .disable = &rs780_dpm_disable,
> >> +             .set_power_state = &rs780_dpm_set_power_state,
> >> +             .display_configuration_changed = &rs780_dpm_display_configuration_changed,
> >> +             .fini = &rs780_dpm_fini,
> >> +             .get_sclk = &rs780_dpm_get_sclk,
> >> +             .get_mclk = &rs780_dpm_get_mclk,
> >> +             .print_power_state = &rs780_dpm_print_power_state,
> >> +     },
> >>       .pflip = {
> >>               .pre_page_flip = &rs600_pre_page_flip,
> >>               .page_flip = &rs600_page_flip,
> >> diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
> >> index 8507cae..134bf57 100644
> >> --- a/drivers/gpu/drm/radeon/radeon_asic.h
> >> +++ b/drivers/gpu/drm/radeon/radeon_asic.h
> >> @@ -396,6 +396,18 @@ int r600_mc_wait_for_idle(struct radeon_device *rdev);
> >>  u32 r600_get_xclk(struct radeon_device *rdev);
> >>  uint64_t r600_get_gpu_clock_counter(struct radeon_device *rdev);
> >>  int rv6xx_get_temp(struct radeon_device *rdev);
> >> +/* rs780 dpm */
> >> +int rs780_dpm_init(struct radeon_device *rdev);
> >> +int rs780_dpm_enable(struct radeon_device *rdev);
> >> +void rs780_dpm_disable(struct radeon_device *rdev);
> >> +int rs780_dpm_set_power_state(struct radeon_device *rdev);
> >> +void rs780_dpm_setup_asic(struct radeon_device *rdev);
> >> +void rs780_dpm_display_configuration_changed(struct radeon_device *rdev);
> >> +void rs780_dpm_fini(struct radeon_device *rdev);
> >> +u32 rs780_dpm_get_sclk(struct radeon_device *rdev, bool low);
> >> +u32 rs780_dpm_get_mclk(struct radeon_device *rdev, bool low);
> >> +void rs780_dpm_print_power_state(struct radeon_device *rdev,
> >> +                              struct radeon_ps *ps);
> >>
> >>  /* uvd */
> >>  int r600_uvd_init(struct radeon_device *rdev);
> >> diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
> >> index 4f5422e..853a8a2 100644
> >> --- a/drivers/gpu/drm/radeon/radeon_pm.c
> >> +++ b/drivers/gpu/drm/radeon/radeon_pm.c
> >> @@ -1030,6 +1030,13 @@ int radeon_pm_init(struct radeon_device *rdev)
> >>  {
> >>       /* enable dpm on rv6xx+ */
> >>       switch (rdev->family) {
> >> +     case CHIP_RS780:
> >> +     case CHIP_RS880:
> >> +             if (radeon_dpm == 1)
> >> +                     rdev->pm.pm_method = PM_METHOD_DPM;
> >> +             else
> >> +                     rdev->pm.pm_method = PM_METHOD_PROFILE;
> >> +             break;
> >>       default:
> >>               /* default to profile method */
> >>               rdev->pm.pm_method = PM_METHOD_PROFILE;
> >> diff --git a/drivers/gpu/drm/radeon/rs780_dpm.c b/drivers/gpu/drm/radeon/rs780_dpm.c
> >> new file mode 100644
> >> index 0000000..f594900
> >> --- /dev/null
> >> +++ b/drivers/gpu/drm/radeon/rs780_dpm.c
> >> @@ -0,0 +1,894 @@
> >> +/*
> >> + * Copyright 2011 Advanced Micro Devices, Inc.
> >> + *
> >> + * Permission is hereby granted, free of charge, to any person obtaining a
> >> + * copy of this software and associated documentation files (the "Software"),
> >> + * to deal in the Software without restriction, including without limitation
> >> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> >> + * and/or sell copies of the Software, and to permit persons to whom the
> >> + * Software is furnished to do so, subject to the following conditions:
> >> + *
> >> + * The above copyright notice and this permission notice shall be included in
> >> + * all copies or substantial portions of the Software.
> >> + *
> >> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> >> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> >> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> >> + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
> >> + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> >> + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> >> + * OTHER DEALINGS IN THE SOFTWARE.
> >> + *
> >> + * Authors: Alex Deucher
> >> + */
> >> +
> >> +#include "drmP.h"
> >> +#include "radeon.h"
> >> +#include "rs780d.h"
> >> +#include "r600_dpm.h"
> >> +#include "rs780_dpm.h"
> >> +#include "atom.h"
> >> +
> >> +static struct igp_ps *rs780_get_ps(struct radeon_ps *rps)
> >> +{
> >> +     struct igp_ps *ps = rps->ps_priv;
> >> +
> >> +     return ps;
> >> +}
> >> +
> >> +static struct igp_power_info *rs780_get_pi(struct radeon_device *rdev)
> >> +{
> >> +     struct igp_power_info *pi = rdev->pm.dpm.priv;
> >> +
> >> +     return pi;
> >> +}
> >> +
> >> +static void rs780_get_pm_mode_parameters(struct radeon_device *rdev)
> >> +{
> >> +     struct igp_power_info *pi = rs780_get_pi(rdev);
> >> +     struct radeon_mode_info *minfo = &rdev->mode_info;
> >> +     struct drm_crtc *crtc;
> >> +     struct radeon_crtc *radeon_crtc;
> >> +     int i;
> >> +
> >> +     /* defaults */
> >> +     pi->crtc_id = 0;
> >> +     pi->refresh_rate = 60;
> >> +
> >> +     for (i = 0; i < rdev->num_crtc; i++) {
> >> +             crtc = (struct drm_crtc *)minfo->crtcs[i];
> >> +             if (crtc && crtc->enabled) {
> >> +                     radeon_crtc = to_radeon_crtc(crtc);
> >> +                     pi->crtc_id = radeon_crtc->crtc_id;
> >> +                     if (crtc->mode.htotal && crtc->mode.vtotal)
> >> +                             pi->refresh_rate =
> >> +                                     (crtc->mode.clock * 1000) /
> >> +                                     (crtc->mode.htotal * crtc->mode.vtotal);
> >> +                     break;
> >> +             }
> >> +     }
> >
> > Ok this looks wrong to me you look for the first enabled crtc but on those iirc
> > there could be 2 so first one might be a low refresh rate and second one an higher
> > one. Thus returning the first one might lead to PM decision that are wrong.
> >

So what happens when 2 are active ? Flickering on the unsync one ?

Cheers,
Jerome

> 
> On RS780/RS880, the hardware can only synchronize with a single crtc,
> so it doesn't really matter which one we pick as long as it's active.
> 
> 
> >> +}
> >> +
> >> +static void rs780_voltage_scaling_enable(struct radeon_device *rdev, bool enable);
> >> +
> >> +static int rs780_initialize_dpm_power_state(struct radeon_device *rdev)
> >> +{
> >> +     struct atom_clock_dividers dividers;
> >> +     struct igp_ps *default_state = rs780_get_ps(rdev->pm.dpm.boot_ps);
> >> +     int i, ret;
> >> +
> >> +     ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
> >> +                                          default_state->sclk_low, false, &dividers);
> >> +     if (ret)
> >> +             return ret;
> >> +
> >> +     r600_engine_clock_entry_set_reference_divider(rdev, 0, dividers.ref_div);
> >> +     r600_engine_clock_entry_set_feedback_divider(rdev, 0, dividers.fb_div);
> >> +     r600_engine_clock_entry_set_post_divider(rdev, 0, dividers.post_div);
> >> +
> >> +     if (dividers.enable_post_div)
> >> +             r600_engine_clock_entry_enable_post_divider(rdev, 0, true);
> >> +     else
> >> +             r600_engine_clock_entry_enable_post_divider(rdev, 0, false);
> >> +
> >> +     r600_engine_clock_entry_set_step_time(rdev, 0, R600_SST_DFLT);
> >> +     r600_engine_clock_entry_enable_pulse_skipping(rdev, 0, false);
> >> +
> >> +     r600_engine_clock_entry_enable(rdev, 0, true);
> >> +     for (i = 1; i < R600_PM_NUMBER_OF_SCLKS; i++)
> >> +             r600_engine_clock_entry_enable(rdev, i, false);
> >> +
> >> +     r600_enable_mclk_control(rdev, false);
> >> +     r600_voltage_control_enable_pins(rdev, 0);
> >> +
> >> +     return 0;
> >> +}
> >> +
> >> +static int rs780_initialize_dpm_parameters(struct radeon_device *rdev)
> >> +{
> >> +     int ret = 0;
> >> +     int i;
> >> +
> >> +     r600_set_bsp(rdev, R600_BSU_DFLT, R600_BSP_DFLT);
> >> +
> >> +     r600_set_at(rdev, 0, 0, 0, 0);
> >> +
> >> +     r600_set_git(rdev, R600_GICST_DFLT);
> >> +
> >> +     for (i = 0; i < R600_PM_NUMBER_OF_TC; i++)
> >> +             r600_set_tc(rdev, i, 0, 0);
> >> +
> >> +     r600_select_td(rdev, R600_TD_DFLT);
> >> +     r600_set_vrc(rdev, 0);
> >> +
> >> +     r600_set_tpu(rdev, R600_TPU_DFLT);
> >> +     r600_set_tpc(rdev, R600_TPC_DFLT);
> >> +
> >> +     r600_set_sstu(rdev, R600_SSTU_DFLT);
> >> +     r600_set_sst(rdev, R600_SST_DFLT);
> >> +
> >> +     r600_set_fctu(rdev, R600_FCTU_DFLT);
> >> +     r600_set_fct(rdev, R600_FCT_DFLT);
> >> +
> >> +     r600_set_vddc3d_oorsu(rdev, R600_VDDC3DOORSU_DFLT);
> >> +     r600_set_vddc3d_oorphc(rdev, R600_VDDC3DOORPHC_DFLT);
> >> +     r600_set_vddc3d_oorsdc(rdev, R600_VDDC3DOORSDC_DFLT);
> >> +     r600_set_ctxcgtt3d_rphc(rdev, R600_CTXCGTT3DRPHC_DFLT);
> >> +     r600_set_ctxcgtt3d_rsdc(rdev, R600_CTXCGTT3DRSDC_DFLT);
> >> +
> >> +     r600_vid_rt_set_vru(rdev, R600_VRU_DFLT);
> >> +     r600_vid_rt_set_vrt(rdev, R600_VOLTAGERESPONSETIME_DFLT);
> >> +     r600_vid_rt_set_ssu(rdev, R600_SPLLSTEPUNIT_DFLT);
> >> +
> >> +     ret = rs780_initialize_dpm_power_state(rdev);
> >> +
> >> +     r600_power_level_set_voltage_index(rdev, R600_POWER_LEVEL_LOW,     0);
> >> +     r600_power_level_set_voltage_index(rdev, R600_POWER_LEVEL_MEDIUM,  0);
> >> +     r600_power_level_set_voltage_index(rdev, R600_POWER_LEVEL_HIGH,    0);
> >> +
> >> +     r600_power_level_set_mem_clock_index(rdev, R600_POWER_LEVEL_LOW,    0);
> >> +     r600_power_level_set_mem_clock_index(rdev, R600_POWER_LEVEL_MEDIUM, 0);
> >> +     r600_power_level_set_mem_clock_index(rdev, R600_POWER_LEVEL_HIGH,   0);
> >> +
> >> +     r600_power_level_set_eng_clock_index(rdev, R600_POWER_LEVEL_LOW,    0);
> >> +     r600_power_level_set_eng_clock_index(rdev, R600_POWER_LEVEL_MEDIUM, 0);
> >> +     r600_power_level_set_eng_clock_index(rdev, R600_POWER_LEVEL_HIGH,   0);
> >> +
> >> +     r600_power_level_set_watermark_id(rdev, R600_POWER_LEVEL_LOW,    R600_DISPLAY_WATERMARK_HIGH);
> >> +     r600_power_level_set_watermark_id(rdev, R600_POWER_LEVEL_MEDIUM, R600_DISPLAY_WATERMARK_HIGH);
> >> +     r600_power_level_set_watermark_id(rdev, R600_POWER_LEVEL_HIGH,   R600_DISPLAY_WATERMARK_HIGH);
> >> +
> >> +     r600_power_level_enable(rdev, R600_POWER_LEVEL_CTXSW, false);
> >> +     r600_power_level_enable(rdev, R600_POWER_LEVEL_HIGH, false);
> >> +     r600_power_level_enable(rdev, R600_POWER_LEVEL_MEDIUM, false);
> >> +     r600_power_level_enable(rdev, R600_POWER_LEVEL_LOW, true);
> >> +
> >> +     r600_power_level_set_enter_index(rdev, R600_POWER_LEVEL_LOW);
> >> +
> >> +     r600_set_vrc(rdev, RS780_CGFTV_DFLT);
> >> +
> >> +     return ret;
> >> +}
> >> +
> >> +static void rs780_start_dpm(struct radeon_device *rdev)
> >> +{
> >> +     r600_enable_sclk_control(rdev, false);
> >> +     r600_enable_mclk_control(rdev, false);
> >> +
> >> +     r600_dynamicpm_enable(rdev, true);
> >> +
> >> +     radeon_wait_for_vblank(rdev, 0);
> >> +     radeon_wait_for_vblank(rdev, 1);
> >> +
> >> +     r600_enable_spll_bypass(rdev, true);
> >> +     r600_wait_for_spll_change(rdev);
> >> +     r600_enable_spll_bypass(rdev, false);
> >> +     r600_wait_for_spll_change(rdev);
> >> +
> >> +     r600_enable_spll_bypass(rdev, true);
> >> +     r600_wait_for_spll_change(rdev);
> >> +     r600_enable_spll_bypass(rdev, false);
> >> +     r600_wait_for_spll_change(rdev);
> >> +
> >> +     r600_enable_sclk_control(rdev, true);
> >> +}
> >> +
> >> +
> >> +static void rs780_preset_ranges_slow_clk_fbdiv_en(struct radeon_device *rdev)
> >> +{
> >> +     WREG32_P(FVTHROT_SLOW_CLK_FEEDBACK_DIV_REG1, RANGE_SLOW_CLK_FEEDBACK_DIV_EN,
> >> +              ~RANGE_SLOW_CLK_FEEDBACK_DIV_EN);
> >> +
> >> +     WREG32_P(FVTHROT_SLOW_CLK_FEEDBACK_DIV_REG1,
> >> +              RANGE0_SLOW_CLK_FEEDBACK_DIV(RS780_SLOWCLKFEEDBACKDIV_DFLT),
> >> +              ~RANGE0_SLOW_CLK_FEEDBACK_DIV_MASK);
> >> +}
> >> +
> >> +static void rs780_preset_starting_fbdiv(struct radeon_device *rdev)
> >> +{
> >> +     u32 fbdiv = (RREG32(CG_SPLL_FUNC_CNTL) & SPLL_FB_DIV_MASK) >> SPLL_FB_DIV_SHIFT;
> >> +
> >> +     WREG32_P(FVTHROT_FBDIV_REG1, STARTING_FEEDBACK_DIV(fbdiv),
> >> +              ~STARTING_FEEDBACK_DIV_MASK);
> >> +
> >> +     WREG32_P(FVTHROT_FBDIV_REG2, FORCED_FEEDBACK_DIV(fbdiv),
> >> +              ~FORCED_FEEDBACK_DIV_MASK);
> >> +
> >> +     WREG32_P(FVTHROT_FBDIV_REG1, FORCE_FEEDBACK_DIV, ~FORCE_FEEDBACK_DIV);
> >> +}
> >> +
> >> +static void rs780_voltage_scaling_init(struct radeon_device *rdev)
> >> +{
> >> +     struct igp_power_info *pi = rs780_get_pi(rdev);
> >> +     struct drm_device *dev = rdev->ddev;
> >> +     u32 fv_throt_pwm_fb_div_range[3];
> >> +     u32 fv_throt_pwm_range[4];
> >> +
> >> +     if (dev->pdev->device == 0x9614) {
> >> +             fv_throt_pwm_fb_div_range[0] = RS780D_FVTHROTPWMFBDIVRANGEREG0_DFLT;
> >> +             fv_throt_pwm_fb_div_range[1] = RS780D_FVTHROTPWMFBDIVRANGEREG1_DFLT;
> >> +             fv_throt_pwm_fb_div_range[2] = RS780D_FVTHROTPWMFBDIVRANGEREG2_DFLT;
> >> +     } else if ((dev->pdev->device == 0x9714) ||
> >> +                (dev->pdev->device == 0x9715)) {
> >> +             fv_throt_pwm_fb_div_range[0] = RS880D_FVTHROTPWMFBDIVRANGEREG0_DFLT;
> >> +             fv_throt_pwm_fb_div_range[1] = RS880D_FVTHROTPWMFBDIVRANGEREG1_DFLT;
> >> +             fv_throt_pwm_fb_div_range[2] = RS880D_FVTHROTPWMFBDIVRANGEREG2_DFLT;
> >> +     } else {
> >> +             fv_throt_pwm_fb_div_range[0] = RS780_FVTHROTPWMFBDIVRANGEREG0_DFLT;
> >> +             fv_throt_pwm_fb_div_range[1] = RS780_FVTHROTPWMFBDIVRANGEREG1_DFLT;
> >> +             fv_throt_pwm_fb_div_range[2] = RS780_FVTHROTPWMFBDIVRANGEREG2_DFLT;
> >> +     }
> >> +
> >> +     if (pi->pwm_voltage_control) {
> >> +             fv_throt_pwm_range[0] = pi->min_voltage;
> >> +             fv_throt_pwm_range[1] = pi->min_voltage;
> >> +             fv_throt_pwm_range[2] = pi->max_voltage;
> >> +             fv_throt_pwm_range[3] = pi->max_voltage;
> >> +     } else {
> >> +             fv_throt_pwm_range[0] = pi->invert_pwm_required ?
> >> +                     RS780_FVTHROTPWMRANGE3_GPIO_DFLT : RS780_FVTHROTPWMRANGE0_GPIO_DFLT;
> >> +             fv_throt_pwm_range[1] = pi->invert_pwm_required ?
> >> +                     RS780_FVTHROTPWMRANGE2_GPIO_DFLT : RS780_FVTHROTPWMRANGE1_GPIO_DFLT;
> >> +             fv_throt_pwm_range[2] = pi->invert_pwm_required ?
> >> +                     RS780_FVTHROTPWMRANGE1_GPIO_DFLT : RS780_FVTHROTPWMRANGE2_GPIO_DFLT;
> >> +             fv_throt_pwm_range[3] = pi->invert_pwm_required ?
> >> +                     RS780_FVTHROTPWMRANGE0_GPIO_DFLT : RS780_FVTHROTPWMRANGE3_GPIO_DFLT;
> >> +     }
> >> +
> >> +     WREG32_P(FVTHROT_PWM_CTRL_REG0,
> >> +              STARTING_PWM_HIGHTIME(pi->max_voltage),
> >> +              ~STARTING_PWM_HIGHTIME_MASK);
> >> +
> >> +     WREG32_P(FVTHROT_PWM_CTRL_REG0,
> >> +              NUMBER_OF_CYCLES_IN_PERIOD(pi->num_of_cycles_in_period),
> >> +              ~NUMBER_OF_CYCLES_IN_PERIOD_MASK);
> >> +
> >> +     WREG32_P(FVTHROT_PWM_CTRL_REG0, FORCE_STARTING_PWM_HIGHTIME,
> >> +              ~FORCE_STARTING_PWM_HIGHTIME);
> >> +
> >> +     if (pi->invert_pwm_required)
> >> +             WREG32_P(FVTHROT_PWM_CTRL_REG0, INVERT_PWM_WAVEFORM, ~INVERT_PWM_WAVEFORM);
> >> +     else
> >> +             WREG32_P(FVTHROT_PWM_CTRL_REG0, 0, ~INVERT_PWM_WAVEFORM);
> >> +
> >> +     rs780_voltage_scaling_enable(rdev, true);
> >> +
> >> +     WREG32(FVTHROT_PWM_CTRL_REG1,
> >> +            (MIN_PWM_HIGHTIME(pi->min_voltage) |
> >> +             MAX_PWM_HIGHTIME(pi->max_voltage)));
> >> +
> >> +     WREG32(FVTHROT_PWM_US_REG0, RS780_FVTHROTPWMUSREG0_DFLT);
> >> +     WREG32(FVTHROT_PWM_US_REG1, RS780_FVTHROTPWMUSREG1_DFLT);
> >> +     WREG32(FVTHROT_PWM_DS_REG0, RS780_FVTHROTPWMDSREG0_DFLT);
> >> +     WREG32(FVTHROT_PWM_DS_REG1, RS780_FVTHROTPWMDSREG1_DFLT);
> >> +
> >> +     WREG32_P(FVTHROT_PWM_FEEDBACK_DIV_REG1,
> >> +              RANGE0_PWM_FEEDBACK_DIV(fv_throt_pwm_fb_div_range[0]),
> >> +              ~RANGE0_PWM_FEEDBACK_DIV_MASK);
> >> +
> >> +     WREG32(FVTHROT_PWM_FEEDBACK_DIV_REG2,
> >> +            (RANGE1_PWM_FEEDBACK_DIV(fv_throt_pwm_fb_div_range[1]) |
> >> +             RANGE2_PWM_FEEDBACK_DIV(fv_throt_pwm_fb_div_range[2])));
> >> +
> >> +     WREG32(FVTHROT_PWM_FEEDBACK_DIV_REG3,
> >> +            (RANGE0_PWM(fv_throt_pwm_range[1]) |
> >> +             RANGE1_PWM(fv_throt_pwm_range[2])));
> >> +     WREG32(FVTHROT_PWM_FEEDBACK_DIV_REG4,
> >> +            (RANGE2_PWM(fv_throt_pwm_range[1]) |
> >> +             RANGE3_PWM(fv_throt_pwm_range[2])));
> >> +}
> >> +
> >> +static void rs780_clk_scaling_enable(struct radeon_device *rdev, bool enable)
> >> +{
> >> +     if (enable)
> >> +             WREG32_P(FVTHROT_CNTRL_REG, ENABLE_FV_THROT | ENABLE_FV_UPDATE,
> >> +                      ~(ENABLE_FV_THROT | ENABLE_FV_UPDATE));
> >> +     else
> >> +             WREG32_P(FVTHROT_CNTRL_REG, 0,
> >> +                      ~(ENABLE_FV_THROT | ENABLE_FV_UPDATE));
> >> +}
> >> +
> >> +static void rs780_voltage_scaling_enable(struct radeon_device *rdev, bool enable)
> >> +{
> >> +     if (enable)
> >> +             WREG32_P(FVTHROT_CNTRL_REG, ENABLE_FV_THROT_IO, ~ENABLE_FV_THROT_IO);
> >> +     else
> >> +             WREG32_P(FVTHROT_CNTRL_REG, 0, ~ENABLE_FV_THROT_IO);
> >> +}
> >> +
> >> +static void rs780_set_engine_clock_wfc(struct radeon_device *rdev)
> >> +{
> >> +     WREG32(FVTHROT_UTC0, RS780_FVTHROTUTC0_DFLT);
> >> +     WREG32(FVTHROT_UTC1, RS780_FVTHROTUTC1_DFLT);
> >> +     WREG32(FVTHROT_UTC2, RS780_FVTHROTUTC2_DFLT);
> >> +     WREG32(FVTHROT_UTC3, RS780_FVTHROTUTC3_DFLT);
> >> +     WREG32(FVTHROT_UTC4, RS780_FVTHROTUTC4_DFLT);
> >> +
> >> +     WREG32(FVTHROT_DTC0, RS780_FVTHROTDTC0_DFLT);
> >> +     WREG32(FVTHROT_DTC1, RS780_FVTHROTDTC1_DFLT);
> >> +     WREG32(FVTHROT_DTC2, RS780_FVTHROTDTC2_DFLT);
> >> +     WREG32(FVTHROT_DTC3, RS780_FVTHROTDTC3_DFLT);
> >> +     WREG32(FVTHROT_DTC4, RS780_FVTHROTDTC4_DFLT);
> >> +}
> >> +
> >> +static void rs780_set_engine_clock_sc(struct radeon_device *rdev)
> >> +{
> >> +     WREG32_P(FVTHROT_FBDIV_REG2,
> >> +              FB_DIV_TIMER_VAL(RS780_FBDIVTIMERVAL_DFLT),
> >> +              ~FB_DIV_TIMER_VAL_MASK);
> >> +
> >> +     WREG32_P(FVTHROT_CNTRL_REG,
> >> +              REFRESH_RATE_DIVISOR(0) | MINIMUM_CIP(0xf),
> >> +              ~(REFRESH_RATE_DIVISOR_MASK | MINIMUM_CIP_MASK));
> >> +}
> >> +
> >> +static void rs780_set_engine_clock_tdc(struct radeon_device *rdev)
> >> +{
> >> +     WREG32_P(FVTHROT_CNTRL_REG, 0, ~(FORCE_TREND_SEL | TREND_SEL_MODE));
> >> +}
> >> +
> >> +static void rs780_set_engine_clock_ssc(struct radeon_device *rdev)
> >> +{
> >> +     WREG32(FVTHROT_FB_US_REG0, RS780_FVTHROTFBUSREG0_DFLT);
> >> +     WREG32(FVTHROT_FB_US_REG1, RS780_FVTHROTFBUSREG1_DFLT);
> >> +     WREG32(FVTHROT_FB_DS_REG0, RS780_FVTHROTFBDSREG0_DFLT);
> >> +     WREG32(FVTHROT_FB_DS_REG1, RS780_FVTHROTFBDSREG1_DFLT);
> >> +
> >> +     WREG32_P(FVTHROT_FBDIV_REG1, MAX_FEEDBACK_STEP(1), ~MAX_FEEDBACK_STEP_MASK);
> >> +}
> >> +
> >> +static void rs780_program_at(struct radeon_device *rdev)
> >> +{
> >> +     struct igp_power_info *pi = rs780_get_pi(rdev);
> >> +
> >> +     WREG32(FVTHROT_TARGET_REG, 30000000 / pi->refresh_rate);
> >> +     WREG32(FVTHROT_CB1, 1000000 * 5 / pi->refresh_rate);
> >> +     WREG32(FVTHROT_CB2, 1000000 * 10 / pi->refresh_rate);
> >> +     WREG32(FVTHROT_CB3, 1000000 * 30 / pi->refresh_rate);
> >> +     WREG32(FVTHROT_CB4, 1000000 * 50 / pi->refresh_rate);
> >> +}
> >> +
> >> +static void rs780_disable_vbios_powersaving(struct radeon_device *rdev)
> >> +{
> >> +     WREG32_P(CG_INTGFX_MISC, 0, ~0xFFF00000);
> >> +}
> >> +
> >> +static void rs780_force_voltage_to_high(struct radeon_device *rdev)
> >> +{
> >> +     struct igp_power_info *pi = rs780_get_pi(rdev);
> >> +     struct igp_ps *current_state = rs780_get_ps(rdev->pm.dpm.current_ps);
> >> +
> >> +     if ((current_state->max_voltage == RS780_VDDC_LEVEL_HIGH) &&
> >> +         (current_state->min_voltage == RS780_VDDC_LEVEL_HIGH))
> >> +             return;
> >> +
> >> +     WREG32_P(GFX_MACRO_BYPASS_CNTL, SPLL_BYPASS_CNTL, ~SPLL_BYPASS_CNTL);
> >> +
> >> +     udelay(1);
> >> +
> >> +     WREG32_P(FVTHROT_PWM_CTRL_REG0,
> >> +              STARTING_PWM_HIGHTIME(pi->max_voltage),
> >> +              ~STARTING_PWM_HIGHTIME_MASK);
> >> +
> >> +     WREG32_P(FVTHROT_PWM_CTRL_REG0,
> >> +              FORCE_STARTING_PWM_HIGHTIME, ~FORCE_STARTING_PWM_HIGHTIME);
> >> +
> >> +     WREG32_P(FVTHROT_PWM_FEEDBACK_DIV_REG1, 0,
> >> +             ~RANGE_PWM_FEEDBACK_DIV_EN);
> >> +
> >> +     udelay(1);
> >> +
> >> +     WREG32_P(GFX_MACRO_BYPASS_CNTL, 0, ~SPLL_BYPASS_CNTL);
> >> +}
> >> +
> >> +static int rs780_set_engine_clock_scaling(struct radeon_device *rdev)
> >> +{
> >> +     struct atom_clock_dividers min_dividers, max_dividers, current_max_dividers;
> >> +     struct igp_ps *new_state = rs780_get_ps(rdev->pm.dpm.requested_ps);
> >> +     struct igp_ps *old_state = rs780_get_ps(rdev->pm.dpm.current_ps);
> >> +     int ret;
> >> +
> >> +     if ((new_state->sclk_high == old_state->sclk_high) &&
> >> +         (new_state->sclk_low == old_state->sclk_low))
> >> +             return 0;
> >> +
> >> +     ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
> >> +                                          new_state->sclk_low, false, &min_dividers);
> >> +     if (ret)
> >> +             return ret;
> >> +
> >> +     ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
> >> +                                          new_state->sclk_high, false, &max_dividers);
> >> +     if (ret)
> >> +             return ret;
> >> +
> >> +     ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
> >> +                                          old_state->sclk_high, false, &current_max_dividers);
> >> +     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);
> >> +
> >> +     if (max_dividers.fb_div > min_dividers.fb_div) {
> >> +             WREG32_P(FVTHROT_FBDIV_REG0,
> >> +                      MIN_FEEDBACK_DIV(min_dividers.fb_div) |
> >> +                      MAX_FEEDBACK_DIV(max_dividers.fb_div),
> >> +                      ~(MIN_FEEDBACK_DIV_MASK | MAX_FEEDBACK_DIV_MASK));
> >> +
> >> +             WREG32_P(FVTHROT_FBDIV_REG1, 0, ~FORCE_FEEDBACK_DIV);
> >> +     }
> >> +
> >> +     return 0;
> >> +}
> >> +
> >> +static void rs780_set_engine_clock_spc(struct radeon_device *rdev)
> >> +{
> >> +     struct igp_ps *new_state = rs780_get_ps(rdev->pm.dpm.requested_ps);
> >> +     struct igp_ps *old_state = rs780_get_ps(rdev->pm.dpm.current_ps);
> >> +     struct igp_power_info *pi = rs780_get_pi(rdev);
> >> +
> >> +     if ((new_state->sclk_high == old_state->sclk_high) &&
> >> +         (new_state->sclk_low == old_state->sclk_low))
> >> +             return;
> >> +
> >> +     if (pi->crtc_id == 0)
> >> +             WREG32_P(CG_INTGFX_MISC, 0, ~FVTHROT_VBLANK_SEL);
> >> +     else
> >> +             WREG32_P(CG_INTGFX_MISC, FVTHROT_VBLANK_SEL, ~FVTHROT_VBLANK_SEL);
> >> +
> >> +}
> >> +
> >> +static void rs780_activate_engine_clk_scaling(struct radeon_device *rdev)
> >> +{
> >> +     struct igp_ps *new_state = rs780_get_ps(rdev->pm.dpm.requested_ps);
> >> +     struct igp_ps *old_state = rs780_get_ps(rdev->pm.dpm.current_ps);
> >> +
> >> +     if ((new_state->sclk_high == old_state->sclk_high) &&
> >> +         (new_state->sclk_low == old_state->sclk_low))
> >> +             return;
> >> +
> >> +     rs780_clk_scaling_enable(rdev, true);
> >> +}
> >> +
> >> +static u32 rs780_get_voltage_for_vddc_level(struct radeon_device *rdev,
> >> +                                         enum rs780_vddc_level vddc)
> >> +{
> >> +     struct igp_power_info *pi = rs780_get_pi(rdev);
> >> +
> >> +     if (vddc == RS780_VDDC_LEVEL_HIGH)
> >> +             return pi->max_voltage;
> >> +     else if (vddc == RS780_VDDC_LEVEL_LOW)
> >> +             return pi->min_voltage;
> >> +     else
> >> +             return pi->max_voltage;
> >> +}
> >> +
> >> +static void rs780_enable_voltage_scaling(struct radeon_device *rdev)
> >> +{
> >> +     struct igp_ps *new_state = rs780_get_ps(rdev->pm.dpm.requested_ps);
> >> +     struct igp_power_info *pi = rs780_get_pi(rdev);
> >> +     enum rs780_vddc_level vddc_high, vddc_low;
> >> +
> >> +     udelay(100);
> >> +
> >> +     if ((new_state->max_voltage == RS780_VDDC_LEVEL_HIGH) &&
> >> +         (new_state->min_voltage == RS780_VDDC_LEVEL_HIGH))
> >> +             return;
> >> +
> >> +     vddc_high = rs780_get_voltage_for_vddc_level(rdev,
> >> +                                                  new_state->max_voltage);
> >> +     vddc_low = rs780_get_voltage_for_vddc_level(rdev,
> >> +                                                 new_state->min_voltage);
> >> +
> >> +     WREG32_P(GFX_MACRO_BYPASS_CNTL, SPLL_BYPASS_CNTL, ~SPLL_BYPASS_CNTL);
> >> +
> >> +     udelay(1);
> >> +     if (vddc_high > vddc_low) {
> >> +             WREG32_P(FVTHROT_PWM_FEEDBACK_DIV_REG1,
> >> +                      RANGE_PWM_FEEDBACK_DIV_EN, ~RANGE_PWM_FEEDBACK_DIV_EN);
> >> +
> >> +             WREG32_P(FVTHROT_PWM_CTRL_REG0, 0, ~FORCE_STARTING_PWM_HIGHTIME);
> >> +     } else if (vddc_high == vddc_low) {
> >> +             if (pi->max_voltage != vddc_high) {
> >> +                     WREG32_P(FVTHROT_PWM_CTRL_REG0,
> >> +                              STARTING_PWM_HIGHTIME(vddc_high),
> >> +                              ~STARTING_PWM_HIGHTIME_MASK);
> >> +
> >> +                     WREG32_P(FVTHROT_PWM_CTRL_REG0,
> >> +                              FORCE_STARTING_PWM_HIGHTIME,
> >> +                              ~FORCE_STARTING_PWM_HIGHTIME);
> >> +             }
> >> +     }
> >> +
> >> +     WREG32_P(GFX_MACRO_BYPASS_CNTL, 0, ~SPLL_BYPASS_CNTL);
> >> +}
> >> +
> >> +int rs780_dpm_enable(struct radeon_device *rdev)
> >> +{
> >> +     struct igp_power_info *pi = rs780_get_pi(rdev);
> >> +
> >> +     rs780_get_pm_mode_parameters(rdev);
> >> +     rs780_disable_vbios_powersaving(rdev);
> >> +
> >> +     if (r600_dynamicpm_enabled(rdev))
> >> +             return -EINVAL;
> >> +     if (rs780_initialize_dpm_parameters(rdev))
> >> +             return -EINVAL;
> >> +     rs780_start_dpm(rdev);
> >> +
> >> +     rs780_preset_ranges_slow_clk_fbdiv_en(rdev);
> >> +     rs780_preset_starting_fbdiv(rdev);
> >> +     if (pi->voltage_control)
> >> +             rs780_voltage_scaling_init(rdev);
> >> +     rs780_clk_scaling_enable(rdev, true);
> >> +     rs780_set_engine_clock_sc(rdev);
> >> +     rs780_set_engine_clock_wfc(rdev);
> >> +     rs780_program_at(rdev);
> >> +     rs780_set_engine_clock_tdc(rdev);
> >> +     rs780_set_engine_clock_ssc(rdev);
> >> +
> >> +     if (pi->gfx_clock_gating)
> >> +             r600_gfx_clockgating_enable(rdev, true);
> >> +
> >> +     return 0;
> >> +}
> >> +
> >> +void rs780_dpm_disable(struct radeon_device *rdev)
> >> +{
> >> +     struct igp_power_info *pi = rs780_get_pi(rdev);
> >> +
> >> +     r600_dynamicpm_enable(rdev, false);
> >> +
> >> +     rs780_clk_scaling_enable(rdev, false);
> >> +     rs780_voltage_scaling_enable(rdev, false);
> >> +
> >> +     if (pi->gfx_clock_gating)
> >> +             r600_gfx_clockgating_enable(rdev, false);
> >> +}
> >> +
> >> +int rs780_dpm_set_power_state(struct radeon_device *rdev)
> >> +{
> >> +     struct igp_power_info *pi = rs780_get_pi(rdev);
> >> +
> >> +     rs780_get_pm_mode_parameters(rdev);
> >> +
> >> +     if (pi->voltage_control) {
> >> +             rs780_force_voltage_to_high(rdev);
> >> +             mdelay(5);
> >> +     }
> >> +
> >> +     rs780_set_engine_clock_scaling(rdev);
> >> +     rs780_set_engine_clock_spc(rdev);
> >> +
> >> +     rs780_activate_engine_clk_scaling(rdev);
> >> +
> >> +     if (pi->voltage_control)
> >> +             rs780_enable_voltage_scaling(rdev);
> >> +
> >> +     return 0;
> >> +}
> >> +
> >> +void rs780_dpm_setup_asic(struct radeon_device *rdev)
> >> +{
> >> +
> >> +}
> >> +
> >> +void rs780_dpm_display_configuration_changed(struct radeon_device *rdev)
> >> +{
> >> +     rs780_get_pm_mode_parameters(rdev);
> >> +     rs780_program_at(rdev);
> >> +}
> >> +
> >> +union igp_info {
> >> +     struct _ATOM_INTEGRATED_SYSTEM_INFO info;
> >> +     struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2;
> >> +};
> >> +
> >> +union power_info {
> >> +     struct _ATOM_POWERPLAY_INFO info;
> >> +     struct _ATOM_POWERPLAY_INFO_V2 info_2;
> >> +     struct _ATOM_POWERPLAY_INFO_V3 info_3;
> >> +     struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
> >> +     struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
> >> +     struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
> >> +};
> >> +
> >> +union pplib_clock_info {
> >> +     struct _ATOM_PPLIB_R600_CLOCK_INFO r600;
> >> +     struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780;
> >> +     struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;
> >> +     struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;
> >> +};
> >> +
> >> +union pplib_power_state {
> >> +     struct _ATOM_PPLIB_STATE v1;
> >> +     struct _ATOM_PPLIB_STATE_V2 v2;
> >> +};
> >> +
> >> +static void rs780_parse_pplib_non_clock_info(struct radeon_device *rdev,
> >> +                                          struct radeon_ps *rps,
> >> +                                          struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info,
> >> +                                          u8 table_rev)
> >> +{
> >> +     rps->caps = le32_to_cpu(non_clock_info->ulCapsAndSettings);
> >> +     rps->class = le16_to_cpu(non_clock_info->usClassification);
> >> +     rps->class2 = le16_to_cpu(non_clock_info->usClassification2);
> >> +
> >> +     if (ATOM_PPLIB_NONCLOCKINFO_VER1 < table_rev) {
> >> +             rps->vclk = le32_to_cpu(non_clock_info->ulVCLK);
> >> +             rps->dclk = le32_to_cpu(non_clock_info->ulDCLK);
> >> +     } else if (r600_is_uvd_state(rps->class, rps->class2)) {
> >> +             rps->vclk = RS780_DEFAULT_VCLK_FREQ;
> >> +             rps->dclk = RS780_DEFAULT_DCLK_FREQ;
> >> +     } else {
> >> +             rps->vclk = 0;
> >> +             rps->dclk = 0;
> >> +     }
> >> +
> >> +     if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT)
> >> +             rdev->pm.dpm.boot_ps = rps;
> >> +     if (rps->class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
> >> +             rdev->pm.dpm.uvd_ps = rps;
> >> +}
> >> +
> >> +static void rs780_parse_pplib_clock_info(struct radeon_device *rdev,
> >> +                                      struct radeon_ps *rps,
> >> +                                      union pplib_clock_info *clock_info)
> >> +{
> >> +     struct igp_ps *ps = rs780_get_ps(rps);
> >> +     u32 sclk;
> >> +
> >> +     sclk = le16_to_cpu(clock_info->rs780.usLowEngineClockLow);
> >> +     sclk |= clock_info->rs780.ucLowEngineClockHigh << 16;
> >> +     ps->sclk_low = sclk;
> >> +     sclk = le16_to_cpu(clock_info->rs780.usHighEngineClockLow);
> >> +     sclk |= clock_info->rs780.ucHighEngineClockHigh << 16;
> >> +     ps->sclk_high = sclk;
> >> +     switch (le16_to_cpu(clock_info->rs780.usVDDC)) {
> >> +     case ATOM_PPLIB_RS780_VOLTAGE_NONE:
> >> +     default:
> >> +             ps->min_voltage = RS780_VDDC_LEVEL_UNKNOWN;
> >> +             ps->max_voltage = RS780_VDDC_LEVEL_UNKNOWN;
> >> +             break;
> >> +     case ATOM_PPLIB_RS780_VOLTAGE_LOW:
> >> +             ps->min_voltage = RS780_VDDC_LEVEL_LOW;
> >> +             ps->max_voltage = RS780_VDDC_LEVEL_LOW;
> >> +             break;
> >> +     case ATOM_PPLIB_RS780_VOLTAGE_HIGH:
> >> +             ps->min_voltage = RS780_VDDC_LEVEL_HIGH;
> >> +             ps->max_voltage = RS780_VDDC_LEVEL_HIGH;
> >> +             break;
> >> +     case ATOM_PPLIB_RS780_VOLTAGE_VARIABLE:
> >> +             ps->min_voltage = RS780_VDDC_LEVEL_LOW;
> >> +             ps->max_voltage = RS780_VDDC_LEVEL_HIGH;
> >> +             break;
> >> +     }
> >> +     ps->flags = le32_to_cpu(clock_info->rs780.ulFlags);
> >> +
> >> +     if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT) {
> >> +             ps->sclk_low = rdev->clock.default_sclk;
> >> +             ps->sclk_high = rdev->clock.default_sclk;
> >> +             ps->min_voltage = RS780_VDDC_LEVEL_HIGH;
> >> +             ps->max_voltage = RS780_VDDC_LEVEL_HIGH;
> >> +     }
> >> +}
> >> +
> >> +static int rs780_parse_power_table(struct radeon_device *rdev)
> >> +{
> >> +     struct radeon_mode_info *mode_info = &rdev->mode_info;
> >> +     struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
> >> +     union pplib_power_state *power_state;
> >> +     int i;
> >> +     union pplib_clock_info *clock_info;
> >> +     union power_info *power_info;
> >> +     int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
> >> +        u16 data_offset;
> >> +     u8 frev, crev;
> >> +     struct igp_ps *ps;
> >> +
> >> +     if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
> >> +                                &frev, &crev, &data_offset))
> >> +             return -EINVAL;
> >> +     power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
> >> +
> >> +     rdev->pm.dpm.ps = kzalloc(sizeof(struct radeon_ps) *
> >> +                               power_info->pplib.ucNumStates, GFP_KERNEL);
> >> +     if (!rdev->pm.dpm.ps)
> >> +             return -ENOMEM;
> >> +     rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps);
> >> +     rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime);
> >> +     rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime);
> >> +
> >> +     for (i = 0; i < power_info->pplib.ucNumStates; i++) {
> >> +             power_state = (union pplib_power_state *)
> >> +                     (mode_info->atom_context->bios + data_offset +
> >> +                      le16_to_cpu(power_info->pplib.usStateArrayOffset) +
> >> +                      i * power_info->pplib.ucStateEntrySize);
> >> +             non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
> >> +                     (mode_info->atom_context->bios + data_offset +
> >> +                      le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) +
> >> +                      (power_state->v1.ucNonClockStateIndex *
> >> +                       power_info->pplib.ucNonClockSize));
> >> +             if (power_info->pplib.ucStateEntrySize - 1) {
> >> +                     clock_info = (union pplib_clock_info *)
> >> +                             (mode_info->atom_context->bios + data_offset +
> >> +                              le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) +
> >> +                              (power_state->v1.ucClockStateIndices[0] *
> >> +                               power_info->pplib.ucClockInfoSize));
> >> +                     ps = kzalloc(sizeof(struct igp_ps), GFP_KERNEL);
> >> +                     if (ps == NULL) {
> >> +                             kfree(rdev->pm.dpm.ps);
> >> +                             return -ENOMEM;
> >> +                     }
> >> +                     rdev->pm.dpm.ps[i].ps_priv = ps;
> >> +                     rs780_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i],
> >> +                                                      non_clock_info,
> >> +                                                      power_info->pplib.ucNonClockSize);
> >> +                     rs780_parse_pplib_clock_info(rdev,
> >> +                                                  &rdev->pm.dpm.ps[i],
> >> +                                                  clock_info);
> >> +             }
> >> +     }
> >> +     rdev->pm.dpm.num_ps = power_info->pplib.ucNumStates;
> >> +     return 0;
> >> +}
> >> +
> >> +int rs780_dpm_init(struct radeon_device *rdev)
> >> +{
> >> +     struct igp_power_info *pi;
> >> +     int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
> >> +     union igp_info *info;
> >> +     u16 data_offset;
> >> +     u8 frev, crev;
> >> +     int ret;
> >> +
> >> +     pi = kzalloc(sizeof(struct igp_power_info), GFP_KERNEL);
> >> +     if (pi == NULL)
> >> +             return -ENOMEM;
> >> +     rdev->pm.dpm.priv = pi;
> >> +
> >> +     ret = rs780_parse_power_table(rdev);
> >> +     if (ret)
> >> +             return ret;
> >> +
> >> +     pi->voltage_control = false;
> >> +     pi->gfx_clock_gating = true;
> >> +
> >> +     if (atom_parse_data_header(rdev->mode_info.atom_context, index, NULL,
> >> +                                &frev, &crev, &data_offset)) {
> >> +             info = (union igp_info *)(rdev->mode_info.atom_context->bios + data_offset);
> >> +
> >> +             /* Get various system informations from bios */
> >> +             switch (crev) {
> >> +             case 1:
> >> +                     pi->num_of_cycles_in_period =
> >> +                             info->info.ucNumberOfCyclesInPeriod;
> >> +                     pi->num_of_cycles_in_period |=
> >> +                             info->info.ucNumberOfCyclesInPeriodHi << 8;
> >> +                     pi->invert_pwm_required =
> >> +                             (pi->num_of_cycles_in_period & 0x8000) ? true : false;
> >> +                     pi->boot_voltage = info->info.ucStartingPWM_HighTime;
> >> +                     pi->max_voltage = info->info.ucMaxNBVoltage;
> >> +                     pi->max_voltage |= info->info.ucMaxNBVoltageHigh << 8;
> >> +                     pi->min_voltage = info->info.ucMinNBVoltage;
> >> +                     pi->min_voltage |= info->info.ucMinNBVoltageHigh << 8;
> >> +                     pi->inter_voltage_low =
> >> +                             le16_to_cpu(info->info.usInterNBVoltageLow);
> >> +                     pi->inter_voltage_high =
> >> +                             le16_to_cpu(info->info.usInterNBVoltageHigh);
> >> +                     pi->voltage_control = true;
> >> +                     pi->bootup_uma_clk = info->info.usK8MemoryClock * 100;
> >> +                     break;
> >> +             case 2:
> >> +                     pi->num_of_cycles_in_period =
> >> +                             le16_to_cpu(info->info_2.usNumberOfCyclesInPeriod);
> >> +                     pi->invert_pwm_required =
> >> +                             (pi->num_of_cycles_in_period & 0x8000) ? true : false;
> >> +                     pi->boot_voltage =
> >> +                             le16_to_cpu(info->info_2.usBootUpNBVoltage);
> >> +                     pi->max_voltage =
> >> +                             le16_to_cpu(info->info_2.usMaxNBVoltage);
> >> +                     pi->min_voltage =
> >> +                             le16_to_cpu(info->info_2.usMinNBVoltage);
> >> +                     pi->system_config =
> >> +                             le32_to_cpu(info->info_2.ulSystemConfig);
> >> +                     pi->pwm_voltage_control =
> >> +                             (pi->system_config & 0x4) ? true : false;
> >> +                     pi->voltage_control = true;
> >> +                     pi->bootup_uma_clk = le32_to_cpu(info->info_2.ulBootUpUMAClock);
> >> +                     break;
> >> +             default:
> >> +                     DRM_ERROR("No integrated system info for your GPU\n");
> >> +                     return -EINVAL;
> >> +             }
> >> +             if (pi->min_voltage > pi->max_voltage)
> >> +                     pi->voltage_control = false;
> >> +             if (pi->pwm_voltage_control) {
> >> +                     if ((pi->num_of_cycles_in_period == 0) ||
> >> +                         (pi->max_voltage == 0) ||
> >> +                         (pi->min_voltage == 0))
> >> +                             pi->voltage_control = false;
> >> +             } else {
> >> +                     if ((pi->num_of_cycles_in_period == 0) ||
> >> +                         (pi->max_voltage == 0))
> >> +                             pi->voltage_control = false;
> >> +             }
> >> +
> >> +             return 0;
> >> +     }
> >> +     radeon_dpm_fini(rdev);
> >> +     return -EINVAL;
> >> +}
> >> +
> >> +void rs780_dpm_print_power_state(struct radeon_device *rdev,
> >> +                              struct radeon_ps *rps)
> >> +{
> >> +     struct igp_ps *ps = rs780_get_ps(rps);
> >> +
> >> +     r600_dpm_print_class_info(rps->class, rps->class2);
> >> +     r600_dpm_print_cap_info(rps->caps);
> >> +     printk("\tuvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
> >> +     printk("\t\tpower level 0    sclk: %u vddc_index: %d\n",
> >> +            ps->sclk_low, ps->min_voltage);
> >> +     printk("\t\tpower level 1    sclk: %u vddc_index: %d\n",
> >> +            ps->sclk_high, ps->max_voltage);
> >> +     r600_dpm_print_ps_status(rdev, rps);
> >> +}
> >> +
> >> +void rs780_dpm_fini(struct radeon_device *rdev)
> >> +{
> >> +     int i;
> >> +
> >> +     for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
> >> +             kfree(rdev->pm.dpm.ps[i].ps_priv);
> >> +     }
> >> +     kfree(rdev->pm.dpm.ps);
> >> +     kfree(rdev->pm.dpm.priv);
> >> +}
> >> +
> >> +u32 rs780_dpm_get_sclk(struct radeon_device *rdev, bool low)
> >> +{
> >> +     struct igp_ps *requested_state = rs780_get_ps(rdev->pm.dpm.requested_ps);
> >> +
> >> +     if (low)
> >> +             return requested_state->sclk_low;
> >> +     else
> >> +             return requested_state->sclk_high;
> >> +}
> >> +
> >> +u32 rs780_dpm_get_mclk(struct radeon_device *rdev, bool low)
> >> +{
> >> +     struct igp_power_info *pi = rs780_get_pi(rdev);
> >> +
> >> +     return pi->bootup_uma_clk;
> >> +}
> >> diff --git a/drivers/gpu/drm/radeon/rs780_dpm.h b/drivers/gpu/drm/radeon/rs780_dpm.h
> >> new file mode 100644
> >> index 0000000..47a40b1
> >> --- /dev/null
> >> +++ b/drivers/gpu/drm/radeon/rs780_dpm.h
> >> @@ -0,0 +1,109 @@
> >> +/*
> >> + * Copyright 2011 Advanced Micro Devices, Inc.
> >> + *
> >> + * Permission is hereby granted, free of charge, to any person obtaining a
> >> + * copy of this software and associated documentation files (the "Software"),
> >> + * to deal in the Software without restriction, including without limitation
> >> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> >> + * and/or sell copies of the Software, and to permit persons to whom the
> >> + * Software is furnished to do so, subject to the following conditions:
> >> + *
> >> + * The above copyright notice and this permission notice shall be included in
> >> + * all copies or substantial portions of the Software.
> >> + *
> >> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> >> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> >> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> >> + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
> >> + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> >> + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> >> + * OTHER DEALINGS IN THE SOFTWARE.
> >> + *
> >> + */
> >> +#ifndef __RS780_DPM_H__
> >> +#define __RS780_DPM_H__
> >> +
> >> +enum rs780_vddc_level {
> >> +     RS780_VDDC_LEVEL_UNKNOWN = 0,
> >> +     RS780_VDDC_LEVEL_LOW = 1,
> >> +     RS780_VDDC_LEVEL_HIGH = 2,
> >> +};
> >> +
> >> +struct igp_power_info {
> >> +     /* flags */
> >> +     bool invert_pwm_required;
> >> +     bool pwm_voltage_control;
> >> +     bool voltage_control;
> >> +     bool gfx_clock_gating;
> >> +     /* stored values */
> >> +     u32 system_config;
> >> +     u32 bootup_uma_clk;
> >> +     u16 max_voltage;
> >> +     u16 min_voltage;
> >> +     u16 boot_voltage;
> >> +     u16 inter_voltage_low;
> >> +     u16 inter_voltage_high;
> >> +     u16 num_of_cycles_in_period;
> >> +     /* variable */
> >> +     int crtc_id;
> >> +     int refresh_rate;
> >> +};
> >> +
> >> +struct igp_ps {
> >> +     enum rs780_vddc_level min_voltage;
> >> +     enum rs780_vddc_level max_voltage;
> >> +     u32 sclk_low;
> >> +     u32 sclk_high;
> >> +     u32 flags;
> >> +};
> >> +
> >> +#define RS780_CGFTV_DFLT                 0x0303000f
> >> +#define RS780_FBDIVTIMERVAL_DFLT         0x2710
> >> +
> >> +#define RS780_FVTHROTUTC0_DFLT   0x04010040
> >> +#define RS780_FVTHROTUTC1_DFLT   0x04010040
> >> +#define RS780_FVTHROTUTC2_DFLT   0x04010040
> >> +#define RS780_FVTHROTUTC3_DFLT   0x04010040
> >> +#define RS780_FVTHROTUTC4_DFLT   0x04010040
> >> +
> >> +#define RS780_FVTHROTDTC0_DFLT 0x04010040
> >> +#define RS780_FVTHROTDTC1_DFLT 0x04010040
> >> +#define RS780_FVTHROTDTC2_DFLT 0x04010040
> >> +#define RS780_FVTHROTDTC3_DFLT 0x04010040
> >> +#define RS780_FVTHROTDTC4_DFLT 0x04010040
> >> +
> >> +#define RS780_FVTHROTFBUSREG0_DFLT       0x00001001
> >> +#define RS780_FVTHROTFBUSREG1_DFLT       0x00002002
> >> +#define RS780_FVTHROTFBDSREG0_DFLT       0x00004001
> >> +#define RS780_FVTHROTFBDSREG1_DFLT       0x00020010
> >> +
> >> +#define RS780_FVTHROTPWMUSREG0_DFLT      0x00002001
> >> +#define RS780_FVTHROTPWMUSREG1_DFLT      0x00004003
> >> +#define RS780_FVTHROTPWMDSREG0_DFLT      0x00002001
> >> +#define RS780_FVTHROTPWMDSREG1_DFLT      0x00004003
> >> +
> >> +#define RS780_FVTHROTPWMFBDIVRANGEREG0_DFLT  0x37
> >> +#define RS780_FVTHROTPWMFBDIVRANGEREG1_DFLT  0x4b
> >> +#define RS780_FVTHROTPWMFBDIVRANGEREG2_DFLT  0x8b
> >> +
> >> +#define RS780D_FVTHROTPWMFBDIVRANGEREG0_DFLT  0x8b
> >> +#define RS780D_FVTHROTPWMFBDIVRANGEREG1_DFLT  0x8c
> >> +#define RS780D_FVTHROTPWMFBDIVRANGEREG2_DFLT  0xb5
> >> +
> >> +#define RS880D_FVTHROTPWMFBDIVRANGEREG0_DFLT  0x8d
> >> +#define RS880D_FVTHROTPWMFBDIVRANGEREG1_DFLT  0x8e
> >> +#define RS880D_FVTHROTPWMFBDIVRANGEREG2_DFLT  0xBa
> >> +
> >> +#define RS780_FVTHROTPWMRANGE0_GPIO_DFLT  0x1a
> >> +#define RS780_FVTHROTPWMRANGE1_GPIO_DFLT  0x1a
> >> +#define RS780_FVTHROTPWMRANGE2_GPIO_DFLT  0x0
> >> +#define RS780_FVTHROTPWMRANGE3_GPIO_DFLT  0x0
> >> +
> >> +#define RS780_SLOWCLKFEEDBACKDIV_DFLT 110
> >> +
> >> +#define RS780_CGCLKGATING_DFLT           0x0000E204
> >> +
> >> +#define RS780_DEFAULT_VCLK_FREQ  53300 /* 10 khz */
> >> +#define RS780_DEFAULT_DCLK_FREQ  40000 /* 10 khz */
> >> +
> >> +#endif
> >> diff --git a/drivers/gpu/drm/radeon/rs780d.h b/drivers/gpu/drm/radeon/rs780d.h
> >> new file mode 100644
> >> index 0000000..b1142ed
> >> --- /dev/null
> >> +++ b/drivers/gpu/drm/radeon/rs780d.h
> >> @@ -0,0 +1,168 @@
> >> +/*
> >> + * Copyright 2011 Advanced Micro Devices, Inc.
> >> + *
> >> + * Permission is hereby granted, free of charge, to any person obtaining a
> >> + * copy of this software and associated documentation files (the "Software"),
> >> + * to deal in the Software without restriction, including without limitation
> >> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> >> + * and/or sell copies of the Software, and to permit persons to whom the
> >> + * Software is furnished to do so, subject to the following conditions:
> >> + *
> >> + * The above copyright notice and this permission notice shall be included in
> >> + * all copies or substantial portions of the Software.
> >> + *
> >> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> >> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> >> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> >> + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
> >> + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> >> + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> >> + * OTHER DEALINGS IN THE SOFTWARE.
> >> + *
> >> + */
> >> +#ifndef __RS780D_H__
> >> +#define __RS780D_H__
> >> +
> >> +#define CG_SPLL_FUNC_CNTL                                 0x600
> >> +#       define SPLL_RESET                                (1 << 0)
> >> +#       define SPLL_SLEEP                                (1 << 1)
> >> +#       define SPLL_REF_DIV(x)                           ((x) << 2)
> >> +#       define SPLL_REF_DIV_MASK                         (7 << 2)
> >> +#       define SPLL_FB_DIV(x)                            ((x) << 5)
> >> +#       define SPLL_FB_DIV_MASK                          (0xff << 2)
> >> +#       define SPLL_FB_DIV_SHIFT                         2
> >> +#       define SPLL_PULSEEN                              (1 << 13)
> >> +#       define SPLL_PULSENUM(x)                          ((x) << 14)
> >> +#       define SPLL_PULSENUM_MASK                        (3 << 14)
> >> +#       define SPLL_SW_HILEN(x)                          ((x) << 16)
> >> +#       define SPLL_SW_HILEN_MASK                        (0xf << 16)
> >> +#       define SPLL_SW_LOLEN(x)                          ((x) << 20)
> >> +#       define SPLL_SW_LOLEN_MASK                        (0xf << 20)
> >> +#       define SPLL_DIVEN                                (1 << 24)
> >> +#       define SPLL_BYPASS_EN                            (1 << 25)
> >> +#       define SPLL_CHG_STATUS                           (1 << 29)
> >> +#       define SPLL_CTLREQ                               (1 << 30)
> >> +#       define SPLL_CTLACK                               (1 << 31)
> >> +
> >> +/* RS780/RS880 PM */
> >> +#define      FVTHROT_CNTRL_REG                               0x3000
> >> +#define              DONT_WAIT_FOR_FBDIV_WRAP                (1 << 0)
> >> +#define              MINIMUM_CIP(x)                          ((x) << 1)
> >> +#define              MINIMUM_CIP_SHIFT                       1
> >> +#define              MINIMUM_CIP_MASK                        0x1fffffe
> >> +#define              REFRESH_RATE_DIVISOR(x)                 ((x) << 25)
> >> +#define              REFRESH_RATE_DIVISOR_SHIFT              25
> >> +#define              REFRESH_RATE_DIVISOR_MASK               (0x3 << 25)
> >> +#define              ENABLE_FV_THROT                         (1 << 27)
> >> +#define              ENABLE_FV_UPDATE                        (1 << 28)
> >> +#define              TREND_SEL_MODE                          (1 << 29)
> >> +#define              FORCE_TREND_SEL                         (1 << 30)
> >> +#define              ENABLE_FV_THROT_IO                      (1 << 31)
> >> +#define      FVTHROT_TARGET_REG                              0x3004
> >> +#define              TARGET_IDLE_COUNT(x)                    ((x) << 0)
> >> +#define              TARGET_IDLE_COUNT_MASK                  0xffffff
> >> +#define              TARGET_IDLE_COUNT_SHIFT                 0
> >> +#define      FVTHROT_CB1                                     0x3008
> >> +#define      FVTHROT_CB2                                     0x300c
> >> +#define      FVTHROT_CB3                                     0x3010
> >> +#define      FVTHROT_CB4                                     0x3014
> >> +#define      FVTHROT_UTC0                                    0x3018
> >> +#define      FVTHROT_UTC1                                    0x301c
> >> +#define      FVTHROT_UTC2                                    0x3020
> >> +#define      FVTHROT_UTC3                                    0x3024
> >> +#define      FVTHROT_UTC4                                    0x3028
> >> +#define      FVTHROT_DTC0                                    0x302c
> >> +#define      FVTHROT_DTC1                                    0x3030
> >> +#define      FVTHROT_DTC2                                    0x3034
> >> +#define      FVTHROT_DTC3                                    0x3038
> >> +#define      FVTHROT_DTC4                                    0x303c
> >> +#define      FVTHROT_FBDIV_REG0                              0x3040
> >> +#define              MIN_FEEDBACK_DIV(x)                     ((x) << 0)
> >> +#define              MIN_FEEDBACK_DIV_MASK                   0xfff
> >> +#define              MIN_FEEDBACK_DIV_SHIFT                  0
> >> +#define              MAX_FEEDBACK_DIV(x)                     ((x) << 12)
> >> +#define              MAX_FEEDBACK_DIV_MASK                   (0xfff << 12)
> >> +#define              MAX_FEEDBACK_DIV_SHIFT                  12
> >> +#define      FVTHROT_FBDIV_REG1                              0x3044
> >> +#define              MAX_FEEDBACK_STEP(x)                    ((x) << 0)
> >> +#define              MAX_FEEDBACK_STEP_MASK                  0xfff
> >> +#define              MAX_FEEDBACK_STEP_SHIFT                 0
> >> +#define              STARTING_FEEDBACK_DIV(x)                ((x) << 12)
> >> +#define              STARTING_FEEDBACK_DIV_MASK              (0xfff << 12)
> >> +#define              STARTING_FEEDBACK_DIV_SHIFT             12
> >> +#define              FORCE_FEEDBACK_DIV                      (1 << 24)
> >> +#define      FVTHROT_FBDIV_REG2                              0x3048
> >> +#define              FORCED_FEEDBACK_DIV(x)                  ((x) << 0)
> >> +#define              FORCED_FEEDBACK_DIV_MASK                0xfff
> >> +#define              FORCED_FEEDBACK_DIV_SHIFT               0
> >> +#define              FB_DIV_TIMER_VAL(x)                     ((x) << 12)
> >> +#define              FB_DIV_TIMER_VAL_MASK                   (0xffff << 12)
> >> +#define              FB_DIV_TIMER_VAL_SHIFT                  12
> >> +#define      FVTHROT_FB_US_REG0                              0x304c
> >> +#define      FVTHROT_FB_US_REG1                              0x3050
> >> +#define      FVTHROT_FB_DS_REG0                              0x3054
> >> +#define      FVTHROT_FB_DS_REG1                              0x3058
> >> +#define      FVTHROT_PWM_CTRL_REG0                           0x305c
> >> +#define              STARTING_PWM_HIGHTIME(x)                ((x) << 0)
> >> +#define              STARTING_PWM_HIGHTIME_MASK              0xfff
> >> +#define              STARTING_PWM_HIGHTIME_SHIFT             0
> >> +#define              NUMBER_OF_CYCLES_IN_PERIOD(x)           ((x) << 12)
> >> +#define              NUMBER_OF_CYCLES_IN_PERIOD_MASK         (0xfff << 12)
> >> +#define              NUMBER_OF_CYCLES_IN_PERIOD_SHIFT        12
> >> +#define              FORCE_STARTING_PWM_HIGHTIME             (1 << 24)
> >> +#define              INVERT_PWM_WAVEFORM                     (1 << 25)
> >> +#define      FVTHROT_PWM_CTRL_REG1                           0x3060
> >> +#define              MIN_PWM_HIGHTIME(x)                     ((x) << 0)
> >> +#define              MIN_PWM_HIGHTIME_MASK                   0xfff
> >> +#define              MIN_PWM_HIGHTIME_SHIFT                  0
> >> +#define              MAX_PWM_HIGHTIME(x)                     ((x) << 12)
> >> +#define              MAX_PWM_HIGHTIME_MASK                   (0xfff << 12)
> >> +#define              MAX_PWM_HIGHTIME_SHIFT                  12
> >> +#define      FVTHROT_PWM_US_REG0                             0x3064
> >> +#define      FVTHROT_PWM_US_REG1                             0x3068
> >> +#define      FVTHROT_PWM_DS_REG0                             0x306c
> >> +#define      FVTHROT_PWM_DS_REG1                             0x3070
> >> +#define      FVTHROT_STATUS_REG0                             0x3074
> >> +#define              CURRENT_FEEDBACK_DIV_MASK               0xfff
> >> +#define              CURRENT_FEEDBACK_DIV_SHIFT              0
> >> +#define      FVTHROT_STATUS_REG1                             0x3078
> >> +#define      FVTHROT_STATUS_REG2                             0x307c
> >> +#define      CG_INTGFX_MISC                                  0x3080
> >> +#define              FVTHROT_VBLANK_SEL                      (1 << 9)
> >> +#define      FVTHROT_PWM_FEEDBACK_DIV_REG1                   0x308c
> >> +#define              RANGE0_PWM_FEEDBACK_DIV(x)              ((x) << 0)
> >> +#define              RANGE0_PWM_FEEDBACK_DIV_MASK            0xfff
> >> +#define              RANGE0_PWM_FEEDBACK_DIV_SHIFT           0
> >> +#define              RANGE_PWM_FEEDBACK_DIV_EN               (1 << 12)
> >> +#define      FVTHROT_PWM_FEEDBACK_DIV_REG2                   0x3090
> >> +#define              RANGE1_PWM_FEEDBACK_DIV(x)              ((x) << 0)
> >> +#define              RANGE1_PWM_FEEDBACK_DIV_MASK            0xfff
> >> +#define              RANGE1_PWM_FEEDBACK_DIV_SHIFT           0
> >> +#define              RANGE2_PWM_FEEDBACK_DIV(x)              ((x) << 12)
> >> +#define              RANGE2_PWM_FEEDBACK_DIV_MASK            (0xfff << 12)
> >> +#define              RANGE2_PWM_FEEDBACK_DIV_SHIFT           12
> >> +#define      FVTHROT_PWM_FEEDBACK_DIV_REG3                   0x3094
> >> +#define              RANGE0_PWM(x)                           ((x) << 0)
> >> +#define              RANGE0_PWM_MASK                         0xfff
> >> +#define              RANGE0_PWM_SHIFT                        0
> >> +#define              RANGE1_PWM(x)                           ((x) << 12)
> >> +#define              RANGE1_PWM_MASK                         (0xfff << 12)
> >> +#define              RANGE1_PWM_SHIFT                        12
> >> +#define      FVTHROT_PWM_FEEDBACK_DIV_REG4                   0x3098
> >> +#define              RANGE2_PWM(x)                           ((x) << 0)
> >> +#define              RANGE2_PWM_MASK                         0xfff
> >> +#define              RANGE2_PWM_SHIFT                        0
> >> +#define              RANGE3_PWM(x)                           ((x) << 12)
> >> +#define              RANGE3_PWM_MASK                         (0xfff << 12)
> >> +#define              RANGE3_PWM_SHIFT                        12
> >> +#define      FVTHROT_SLOW_CLK_FEEDBACK_DIV_REG1              0x30ac
> >> +#define              RANGE0_SLOW_CLK_FEEDBACK_DIV(x)         ((x) << 0)
> >> +#define              RANGE0_SLOW_CLK_FEEDBACK_DIV_MASK       0xfff
> >> +#define              RANGE0_SLOW_CLK_FEEDBACK_DIV_SHIFT      0
> >> +#define              RANGE_SLOW_CLK_FEEDBACK_DIV_EN          (1 << 12)
> >> +
> >> +#define      GFX_MACRO_BYPASS_CNTL                           0x30c0
> >> +#define              SPLL_BYPASS_CNTL                        (1 << 0)
> >> +#define              UPLL_BYPASS_CNTL                        (1 << 1)
> >> +
> >> +#endif
> >> --
> >> 1.7.7.5
> >>
> >> _______________________________________________
> >> dri-devel mailing list
> >> dri-devel@lists.freedesktop.org
> >> http://lists.freedesktop.org/mailman/listinfo/dri-devel

  reply	other threads:[~2013-06-26 18:22 UTC|newest]

Thread overview: 142+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-26 13:21 [PATCH 000/165] radeon drm-next patches alexdeucher
2013-06-26 12:55 ` Jerome Glisse
2013-06-26 13:21 ` [PATCH 001/165] drm/radeon: fix AVI infoframe generation alexdeucher
2013-06-26 13:21 ` [PATCH 002/165] drm/radeon: add backlight quirk for hybrid mac alexdeucher
2013-06-26 13:21 ` [PATCH 003/165] drm/radeon: add a reset work handler alexdeucher
2013-06-26 13:21 ` [PATCH 004/165] drm/radeon: add CIK chip families alexdeucher
2013-06-26 13:21 ` [PATCH 005/165] drm/radeon: add DCE8 macro for CIK alexdeucher
2013-06-26 13:21 ` [PATCH 006/165] drm/radeon: adapt to PCI BAR changes on CIK alexdeucher
2013-06-26 13:21 ` [PATCH 007/165] drm/radeon: add gpu init support for CIK (v9) alexdeucher
2013-06-26 13:21 ` [PATCH 008/165] drm/radeon: Add support for CIK GPU reset (v2) alexdeucher
2013-06-26 13:21 ` [PATCH 009/165] drm/radeon: add support for MC/VM setup on CIK (v6) alexdeucher
2013-06-26 13:21 ` [PATCH 010/165] drm/radeon/cik: stop page faults from hanging the system (v2) alexdeucher
2013-06-26 13:21 ` [PATCH 011/165] drm/radeon: add initial ucode loading for CIK (v5) alexdeucher
2013-06-26 13:21 ` [PATCH 012/165] drm/radeon: add support mc ucode loading on CIK (v2) alexdeucher
2013-06-26 13:21 ` [PATCH 013/165] drm/radeon: Add CP init for CIK (v7) alexdeucher
2013-06-26 13:21 ` [PATCH 014/165] drm/radeon: add IB and fence dispatch functions for CIK gfx (v7) alexdeucher
2013-06-26 13:21 ` [PATCH 015/165] drm/radeon: add ring and IB tests for CIK (v3) alexdeucher
2013-06-26 13:21 ` [PATCH 016/165] drm/radeon: implement async vm_flush for the CP (v7) alexdeucher
2013-06-26 13:21 ` [PATCH 017/165] drm/radeon: Add support for RLC init on CIK (v4) alexdeucher
2013-06-26 13:21 ` [PATCH 018/165] drm/radeon: add support for interrupts on CIK (v5) alexdeucher
2013-06-26 13:21 ` [PATCH 019/165] drm/radeon/cik: log and handle VM page fault interrupts alexdeucher
2013-06-26 13:21 ` [PATCH 020/165] drm/radeon/cik: add support for sDMA dma engines (v8) alexdeucher
2013-06-26 13:21 ` [PATCH 021/165] drm/radeon: implement async vm_flush for the sDMA (v6) alexdeucher
2013-06-26 13:21 ` [PATCH 022/165] drm/radeon/cik: add support for doing async VM pt updates (v5) alexdeucher
2013-06-26 13:21 ` [PATCH 023/165] drm/radeon/cik: fill in startup/shutdown callbacks (v4) alexdeucher
2013-06-26 15:03   ` Christian König
2013-06-26 13:21 ` [PATCH 024/165] drm/radeon: upstream ObjectID.h updates (v2) alexdeucher
2013-06-26 13:21 ` [PATCH 025/165] drm/radeon: upstream atombios.h " alexdeucher
2013-06-26 13:21 ` [PATCH 026/165] drm/radeon: atombios power table " alexdeucher
2013-06-26 13:21 ` [PATCH 027/165] drm/radeon: handle the integrated thermal controller on CI alexdeucher
2013-06-26 13:21 ` [PATCH 028/165] drm/radeon: update power state parsing for CI alexdeucher
2013-06-26 13:21 ` [PATCH 029/165] drm/radeon/dce8: add support for display watermark setup alexdeucher
2013-06-26 13:21 ` [PATCH 030/165] drm/radeon/cik: add hw cursor support (v2) alexdeucher
2013-06-26 13:21 ` [PATCH 031/165] drm/radeon/dce8: properly handle interlaced timing alexdeucher
2013-06-26 13:21 ` [PATCH 032/165] drm/radeon/dce8: crtc_set_base updates alexdeucher
2013-06-26 13:21 ` [PATCH 033/165] drm/radeon/atom: add DCE8 encoder support alexdeucher
2013-06-26 13:21 ` [PATCH 034/165] drm/radeon/atom: add support for new DVO tables alexdeucher
2013-06-26 13:21 ` [PATCH 035/165] drm/radeon: update DISPCLK programming for DCE8 alexdeucher
2013-06-26 13:21 ` [PATCH 036/165] drm/radeon: add support pll selection for DCE8 (v4) alexdeucher
2013-06-26 13:21 ` [PATCH 037/165] drm/radeon: Handle PPLL0 powerdown on DCE8 alexdeucher
2013-06-26 13:21 ` [PATCH 038/165] drm/radeon: use frac fb div " alexdeucher
2013-06-26 13:21 ` [PATCH 039/165] drm/radeon: add SS override support for KB/KV alexdeucher
2013-06-26 13:22 ` [PATCH 040/165] drm/radeon: Update radeon_info_ioctl for CIK (v2) alexdeucher
2013-06-26 13:22 ` [PATCH 041/165] drm/radeon: add get_gpu_clock_counter() callback for cik alexdeucher
2013-06-26 13:22 ` [PATCH 042/165] drm/radeon: update CIK soft reset alexdeucher
2013-06-26 13:22 ` [PATCH 043/165] drm/radeon: add indirect register accessors for SMC registers alexdeucher
2013-06-26 13:22 ` [PATCH 044/165] drm/radeon: add get_xclk() callback for CIK alexdeucher
2013-06-26 13:22 ` [PATCH 045/165] drm/radeon/cik: add pcie_port indirect register accessors alexdeucher
2013-06-26 13:22 ` [PATCH 046/165] drm/radeon: update radeon_atom_get_clock_dividers() for SI alexdeucher
2013-06-26 13:22 ` [PATCH 047/165] drm/radeon: update radeon_atom_get_clock_dividers for CIK alexdeucher
2013-06-26 13:22 ` [PATCH 048/165] drm/radeon: add UVD support for CIK (v3) alexdeucher
2013-06-26 13:22 ` [PATCH 049/165] drm/radeon/cik: add srbm_select function alexdeucher
2013-06-26 13:22 ` [PATCH 050/165] drm/radeon: use callbacks for ring pointer handling alexdeucher
2013-06-26 15:31   ` Christian König
2013-06-26 13:22 ` [PATCH 051/165] drm/radeon: implement simple doorbell page allocator alexdeucher
2013-06-26 12:57   ` Jerome Glisse
2013-06-26 18:38     ` Alex Deucher
2013-06-26 13:22 ` [PATCH 052/165] drm/radeon/cik: Add support for compute queues (v2) alexdeucher
2013-06-26 10:08   ` Jerome Glisse
2013-06-26 13:22 ` [PATCH 053/165] drm/radeon/cik: switch to type3 nop packet for compute rings alexdeucher
2013-06-26 10:10   ` Jerome Glisse
2013-06-26 13:22 ` [PATCH 054/165] drm/radeon: fix up ring functions " alexdeucher
2013-06-26 13:22 ` [PATCH 055/165] drm/radeon/cik: add support for compute interrupts alexdeucher
2013-06-26 13:22 ` [PATCH 056/165] drm/radeon/cik: add support for golden register init alexdeucher
2013-06-26 13:22 ` [PATCH 057/165] drm/radeon: add radeon_asic struct for CIK (v11) alexdeucher
2013-06-26 13:22 ` [PATCH 058/165] drm/radeon: add cik tile mode array query alexdeucher
2013-06-26 13:22 ` [PATCH 059/165] drm/radeon: add current Bonaire PCI ids alexdeucher
2013-06-26 13:22 ` [PATCH 060/165] drm/radeon: add current KB pci ids alexdeucher
2013-06-26 13:22 ` [PATCH 061/165] drm/radeon/kms: add accessors for RCU indirect space alexdeucher
2013-06-26 13:22 ` [PATCH 062/165] drm/radeon/evergreen: add indirect register accessors for CG registers alexdeucher
2013-06-26 13:22 ` [PATCH 063/165] drm/radeon: make get_temperature functions a callback alexdeucher
2013-06-26 13:22 ` [PATCH 064/165] drm/radeon: add support for thermal sensor on tn alexdeucher
2013-06-26 13:22 ` [PATCH 065/165] drm/radeon/kms: move ucode defines to a separate header alexdeucher
2013-06-26 13:22 ` [PATCH 066/165] drm/radeon: properly set up the RLC on ON/LN/TN (v3) alexdeucher
2013-06-26 13:22 ` [PATCH 067/165] drm/radeon/kms: add atom helper functions for dpm (v3) alexdeucher
2013-06-26 13:22 ` [PATCH 068/165] drm/radeon/kms: add new asic struct for rv6xx (v3) alexdeucher
2013-06-26 13:22 ` [PATCH 069/165] drm/radeon/kms: add common dpm infrastructure alexdeucher
2013-06-26 10:27   ` Jerome Glisse
2013-06-27 13:52   ` K. Schnass
2013-06-26 13:22 ` [PATCH 070/165] drm/radeon/kms: fix up rs780/rs880 display watermark calc for dpm alexdeucher
2013-06-26 13:22 ` [PATCH 071/165] drm/radeon/kms: fix up 6xx/7xx " alexdeucher
2013-06-26 13:22 ` [PATCH 072/165] drm/radeon/kms: fix up dce4/5 " alexdeucher
2013-06-26 13:22 ` [PATCH 073/165] drm/radeon/kms: fix up dce6 " alexdeucher
2013-06-26 13:22 ` [PATCH 074/165] drm/radeon/kms: add common r600 dpm functions alexdeucher
2013-06-26 13:22 ` [PATCH 075/165] drm/radeon/kms: add dpm support for rs780/rs880 alexdeucher
2013-06-26 10:46   ` Jerome Glisse
2013-06-26 18:19     ` Alex Deucher
2013-06-26 13:18       ` Jerome Glisse [this message]
2013-06-26 18:41         ` Alex Deucher
2013-06-26 13:22 ` [PATCH 076/165] drm/radeon/kms: add dpm support for rv6xx alexdeucher
2013-06-26 16:45   ` Christian König
2013-06-26 13:22 ` [PATCH 077/165] drm/radeon/kms: add dpm support for rv7xx (v2) alexdeucher
2013-06-26 13:22 ` [PATCH 078/165] drm/radeon/kms: add dpm support for evergreen (v2) alexdeucher
2013-06-26 13:22 ` [PATCH 079/165] drm/radeon/kms: add dpm support for btc (v2) alexdeucher
2013-06-26 13:22 ` [PATCH 080/165] drm/radeon/kms: add dpm support for sumo asics alexdeucher
2013-06-26 11:19   ` Jerome Glisse
2013-06-26 13:22 ` [PATCH 081/165] drm/radeon/kms: add dpm support for trinity asics alexdeucher
2013-06-26 13:22 ` [PATCH 082/165] drm/radeon/dpm: let atom control display phy powergating alexdeucher
2013-06-26 13:22 ` [PATCH 083/165] drm/radeon: add dpm UVD handling for r7xx asics alexdeucher
2013-06-26 13:22 ` [PATCH 084/165] drm/radeon: add dpm UVD handling for evergreen/btc asics alexdeucher
2013-06-26 13:22 ` [PATCH 085/165] drm/radeon: add dpm UVD handling for sumo asics alexdeucher
2013-06-26 13:22 ` [PATCH 086/165] drm/radeon: add dpm UVD handling for TN asics (v2) alexdeucher
2013-06-26 13:22 ` [PATCH 087/165] drm/radeon/kms: enable UVD as needed (v9) alexdeucher
2013-06-26 13:22 ` [PATCH 088/165] drm/radeon/dpm: add helpers for extended power tables (v2) alexdeucher
2013-06-26 13:22 ` [PATCH 089/165] drm/radeon/dpm: track whether we are on AC or battery alexdeucher
2013-06-26 13:22 ` [PATCH 090/165] drm/radeon/dpm: fixup dynamic state adjust for sumo alexdeucher
2013-06-26 13:22 ` [PATCH 091/165] drm/radeon/dpm: fixup dynamic state adjust for TN alexdeucher
2013-06-26 13:22 ` [PATCH 092/165] drm/radeon/dpm: fixup dynamic state adjust for btc (v2) alexdeucher
2013-06-26 13:22 ` [PATCH 093/165] drm/radeon/kms: add dpm support for cayman alexdeucher
2013-06-26 11:29   ` Jerome Glisse
2013-06-26 13:22 ` [PATCH 094/165] drm/radeon/cayman: update tdp limits in set_power_state alexdeucher
2013-06-26 13:22 ` [PATCH 095/165] drm/radeon/dpm/rs780: restructure code alexdeucher
2013-06-26 13:22 ` [PATCH 096/165] drm/radeon/dpm/rv6xx: " alexdeucher
2013-06-26 13:22 ` [PATCH 097/165] drm/radeon/dpm/rv7xx: " alexdeucher
2013-06-26 13:22 ` [PATCH 098/165] drm/radeon/dpm/evergreen: " alexdeucher
2013-06-26 13:22 ` [PATCH 099/165] drm/radeon/dpm/btc: " alexdeucher
2013-06-26 13:23 ` [PATCH 100/165] drm/radeon/dpm/cayman: " alexdeucher
2013-06-26 13:23 ` [PATCH 101/165] drm/radeon/dpm/sumo: " alexdeucher
2013-06-26 13:23 ` [PATCH 102/165] drm/radeon/dpm/tn: " alexdeucher
2013-06-26 13:23 ` [PATCH 103/165] drm/radeon/dpm: add new pre/post_set_power_state callbacks alexdeucher
2013-06-26 13:23 ` [PATCH 104/165] drm/radeon/dpm: add pre/post_set_power_state callbacks (6xx-eg) alexdeucher
2013-06-26 13:23 ` [PATCH 105/165] drm/radeon/dpm: add pre/post_set_power_state callback (sumo) alexdeucher
2013-06-26 13:23 ` [PATCH 106/165] drm/radeon/dpm: add pre/post_set_power_state callback (TN) alexdeucher
2013-06-26 13:23 ` [PATCH 107/165] drm/radeon/dpm: add pre/post_set_power_state callback (BTC) alexdeucher
2013-06-26 13:23 ` [PATCH 108/165] drm/radeon/dpm: add pre/post_set_power_state callback (cayman) alexdeucher
2013-06-26 13:23 ` [PATCH 109/165] drm/radeon/dpm: remove broken dyn state remnants alexdeucher
2013-06-26 13:23 ` [PATCH 110/165] drm/radeon: add missing UVD clock set in cayman dpm code alexdeucher
2013-06-26 13:23 ` [PATCH 111/165] drm/radeon/dpm: remove local sumo_get_xclk() alexdeucher
2013-06-26 21:57 ` [PATCH 000/165] radeon drm-next patches Julian Wollrath
2013-06-26 22:51   ` Julian Wollrath
2013-06-27 14:21     ` Jerome Glisse
2013-06-27 21:26       ` Julian Wollrath
2013-06-29 17:37   ` Grigori Goronzy
2013-06-26 22:23 ` Alex Deucher
2013-06-27 13:12   ` Andy Furniss
2013-06-27 14:55     ` Alex Deucher
2013-06-27 22:19       ` James Cloos
2013-06-27 22:52         ` Jerome Glisse
2013-06-27 23:55     ` Alex Deucher
2013-06-28 13:00       ` Laurent Carlier
2013-06-29  9:28       ` Andy Furniss
2013-06-29 10:23         ` Ilyes Gouta

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130626131804.GI2480@gmail.com \
    --to=j.glisse@gmail.com \
    --cc=alexander.deucher@amd.com \
    --cc=alexdeucher@gmail.com \
    --cc=dri-devel@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.