diff --git a/linux-core/radeon_atombios.c b/linux-core/radeon_atombios.c index 8bf6a7ce..4d48593b 100644 --- a/linux-core/radeon_atombios.c +++ b/linux-core/radeon_atombios.c @@ -450,6 +450,32 @@ void radeon_atom_static_pwrmgt_setup(struct drm_device *dev, int enable) atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); } +void radeon_atom_set_engine_clock(struct drm_device *dev, int eng_clock) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + struct radeon_mode_info *mode_info = &dev_priv->mode_info; + struct atom_context *ctx = mode_info->atom_context; + SET_ENGINE_CLOCK_PS_ALLOCATION args; + int index = GetIndexIntoMasterTable(COMMAND, SetEngineClock); + + args.ulTargetEngineClock = eng_clock; /* 10 khz */ + + atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); +} + +void radeon_atom_set_memory_clock(struct drm_device *dev, int mem_clock) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + struct radeon_mode_info *mode_info = &dev_priv->mode_info; + struct atom_context *ctx = mode_info->atom_context; + SET_MEMORY_CLOCK_PS_ALLOCATION args; + int index = GetIndexIntoMasterTable(COMMAND, SetMemoryClock); + + args.ulTargetMemoryClock = mem_clock; /* 10 khz */ + + atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); +} + void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev) { struct drm_radeon_private *dev_priv = dev->dev_private; diff --git a/linux-core/radeon_display.c b/linux-core/radeon_display.c index 74037191..fd0855e5 100644 --- a/linux-core/radeon_display.c +++ b/linux-core/radeon_display.c @@ -543,6 +543,51 @@ void radeon_get_clock_info(struct drm_device *dev) } +/* not sure of the best place for these */ +/* 10 khz */ +void radeon_legacy_set_engine_clock(struct drm_device *dev, int eng_clock) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + struct radeon_mode_info *mode_info = &dev_priv->mode_info; + struct radeon_pll *spll = &mode_info->spll; + uint32_t ref_div, fb_div; + uint32_t m_spll_ref_fb_div; + + /* FIXME wait for idle */ + + m_spll_ref_fb_div = RADEON_READ_PLL(dev_priv, RADEON_M_SPLL_REF_FB_DIV); + m_spll_ref_fb_div &= ((RADEON_M_SPLL_REF_DIV_MASK << RADEON_M_SPLL_REF_DIV_SHIFT) | + (RADEON_MPLL_FB_DIV_MASK << RADEON_MPLL_FB_DIV_SHIFT)); + ref_div = m_spll_ref_fb_div & RADEON_M_SPLL_REF_DIV_MASK; + + fb_div = radeon_div(eng_clock * ref_div, spll->reference_freq); + m_spll_ref_fb_div |= (fb_div & RADEON_SPLL_FB_DIV_MASK) << RADEON_SPLL_FB_DIV_SHIFT; + RADEON_WRITE_PLL(dev_priv, RADEON_M_SPLL_REF_FB_DIV, m_spll_ref_fb_div); + +} + +/* 10 khz */ +void radeon_legacy_set_memory_clock(struct drm_device *dev, int mem_clock) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + struct radeon_mode_info *mode_info = &dev_priv->mode_info; + struct radeon_pll *mpll = &mode_info->mpll; + uint32_t ref_div, fb_div; + uint32_t m_spll_ref_fb_div; + + /* FIXME wait for idle */ + + m_spll_ref_fb_div = RADEON_READ_PLL(dev_priv, RADEON_M_SPLL_REF_FB_DIV); + m_spll_ref_fb_div &= ((RADEON_M_SPLL_REF_DIV_MASK << RADEON_M_SPLL_REF_DIV_SHIFT) | + (RADEON_SPLL_FB_DIV_MASK << RADEON_SPLL_FB_DIV_SHIFT)); + ref_div = m_spll_ref_fb_div & RADEON_M_SPLL_REF_DIV_MASK; + + fb_div = radeon_div(mem_clock * ref_div, mpll->reference_freq); + m_spll_ref_fb_div |= (fb_div & RADEON_MPLL_FB_DIV_MASK) << RADEON_MPLL_FB_DIV_SHIFT; + RADEON_WRITE_PLL(dev_priv, RADEON_M_SPLL_REF_FB_DIV, m_spll_ref_fb_div); + +} + static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) { struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); diff --git a/linux-core/radeon_reg.h b/linux-core/radeon_reg.h index c4bc7a80..113a8267 100644 --- a/linux-core/radeon_reg.h +++ b/linux-core/radeon_reg.h @@ -1549,6 +1549,13 @@ #define RADEON_SC_TOP_LEFT_C 0x1c88 # define RADEON_SC_SIGN_MASK_LO 0x8000 # define RADEON_SC_SIGN_MASK_HI 0x80000000 +#define RADEON_M_SPLL_REF_FB_DIV 0x000a /* PLL */ +# define RADEON_M_SPLL_REF_DIV_SHIFT 0 +# define RADEON_M_SPLL_REF_DIV_MASK 0xff +# define RADEON_MPLL_FB_DIV_SHIFT 8 +# define RADEON_MPLL_FB_DIV_MASK 0xff +# define RADEON_SPLL_FB_DIV_SHIFT 16 +# define RADEON_SPLL_FB_DIV_MASK 0xff #define RADEON_SCLK_CNTL 0x000d /* PLL */ # define RADEON_SCLK_SRC_SEL_MASK 0x0007 # define RADEON_DYN_STOP_LAT_MASK 0x00007ff8