OSDN Git Service

radeon: Add functions to set mem/eng clocks
authorAlex Deucher <alexdeucher@gmail.com>
Thu, 18 Sep 2008 20:42:22 +0000 (16:42 -0400)
committerAlex Deucher <alexdeucher@gmail.com>
Thu, 18 Sep 2008 20:42:22 +0000 (16:42 -0400)
linux-core/radeon_atombios.c
linux-core/radeon_display.c
linux-core/radeon_reg.h

index 8bf6a7c..4d48593 100644 (file)
@@ -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;
index 7403719..fd0855e 100644 (file)
@@ -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);
index c4bc7a8..113a826 100644 (file)
 #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