aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-03-26 19:33:04 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-04-02 14:25:34 -0400
commit74cfd7ac5e1119ec3275d769ed9e27bcd97cf896 (patch)
treeae085468d69dce81d81a5eebe801b8e01f347001 /drivers/gpu/drm
parent31ad8ec6a6145f9ac978a112801dbde33d44b9d1 (diff)
drm/i915: Skip modifying PCH DREF if not changing clock sources
Modifying the clock sources (via the DREF control on the PCH) is a slow multi-stage process as we need to let the clocks stabilise between each stage. If we are not actually changing the clock sources, then we can return early. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Jani Nikula <jani.nikula@intel.com> [danvet: Appease checkpatch by deleting a space after a ~] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c83
1 files changed, 61 insertions, 22 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 5e8b91f2c529..0e172ced8f0e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4701,7 +4701,7 @@ static void ironlake_init_pch_refclk(struct drm_device *dev)
4701 struct drm_i915_private *dev_priv = dev->dev_private; 4701 struct drm_i915_private *dev_priv = dev->dev_private;
4702 struct drm_mode_config *mode_config = &dev->mode_config; 4702 struct drm_mode_config *mode_config = &dev->mode_config;
4703 struct intel_encoder *encoder; 4703 struct intel_encoder *encoder;
4704 u32 temp; 4704 u32 val, final;
4705 bool has_lvds = false; 4705 bool has_lvds = false;
4706 bool has_cpu_edp = false; 4706 bool has_cpu_edp = false;
4707 bool has_pch_edp = false; 4707 bool has_pch_edp = false;
@@ -4744,70 +4744,109 @@ static void ironlake_init_pch_refclk(struct drm_device *dev)
4744 * PCH B stepping, previous chipset stepping should be 4744 * PCH B stepping, previous chipset stepping should be
4745 * ignoring this setting. 4745 * ignoring this setting.
4746 */ 4746 */
4747 temp = I915_READ(PCH_DREF_CONTROL); 4747 val = I915_READ(PCH_DREF_CONTROL);
4748
4749 /* As we must carefully and slowly disable/enable each source in turn,
4750 * compute the final state we want first and check if we need to
4751 * make any changes at all.
4752 */
4753 final = val;
4754 final &= ~DREF_NONSPREAD_SOURCE_MASK;
4755 if (has_ck505)
4756 final |= DREF_NONSPREAD_CK505_ENABLE;
4757 else
4758 final |= DREF_NONSPREAD_SOURCE_ENABLE;
4759
4760 final &= ~DREF_SSC_SOURCE_MASK;
4761 final &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
4762 final &= ~DREF_SSC1_ENABLE;
4763
4764 if (has_panel) {
4765 final |= DREF_SSC_SOURCE_ENABLE;
4766
4767 if (intel_panel_use_ssc(dev_priv) && can_ssc)
4768 final |= DREF_SSC1_ENABLE;
4769
4770 if (has_cpu_edp) {
4771 if (intel_panel_use_ssc(dev_priv) && can_ssc)
4772 final |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD;
4773 else
4774 final |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
4775 } else
4776 final |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
4777 } else {
4778 final |= DREF_SSC_SOURCE_DISABLE;
4779 final |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
4780 }
4781
4782 if (final == val)
4783 return;
4784
4748 /* Always enable nonspread source */ 4785 /* Always enable nonspread source */
4749 temp &= ~DREF_NONSPREAD_SOURCE_MASK; 4786 val &= ~DREF_NONSPREAD_SOURCE_MASK;
4750 4787
4751 if (has_ck505) 4788 if (has_ck505)
4752 temp |= DREF_NONSPREAD_CK505_ENABLE; 4789 val |= DREF_NONSPREAD_CK505_ENABLE;
4753 else 4790 else
4754 temp |= DREF_NONSPREAD_SOURCE_ENABLE; 4791 val |= DREF_NONSPREAD_SOURCE_ENABLE;
4755 4792
4756 if (has_panel) { 4793 if (has_panel) {
4757 temp &= ~DREF_SSC_SOURCE_MASK; 4794 val &= ~DREF_SSC_SOURCE_MASK;
4758 temp |= DREF_SSC_SOURCE_ENABLE; 4795 val |= DREF_SSC_SOURCE_ENABLE;
4759 4796
4760 /* SSC must be turned on before enabling the CPU output */ 4797 /* SSC must be turned on before enabling the CPU output */
4761 if (intel_panel_use_ssc(dev_priv) && can_ssc) { 4798 if (intel_panel_use_ssc(dev_priv) && can_ssc) {
4762 DRM_DEBUG_KMS("Using SSC on panel\n"); 4799 DRM_DEBUG_KMS("Using SSC on panel\n");
4763 temp |= DREF_SSC1_ENABLE; 4800 val |= DREF_SSC1_ENABLE;
4764 } else 4801 } else
4765 temp &= ~DREF_SSC1_ENABLE; 4802 val &= ~DREF_SSC1_ENABLE;
4766 4803
4767 /* Get SSC going before enabling the outputs */ 4804 /* Get SSC going before enabling the outputs */
4768 I915_WRITE(PCH_DREF_CONTROL, temp); 4805 I915_WRITE(PCH_DREF_CONTROL, val);
4769 POSTING_READ(PCH_DREF_CONTROL); 4806 POSTING_READ(PCH_DREF_CONTROL);
4770 udelay(200); 4807 udelay(200);
4771 4808
4772 temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK; 4809 val &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
4773 4810
4774 /* Enable CPU source on CPU attached eDP */ 4811 /* Enable CPU source on CPU attached eDP */
4775 if (has_cpu_edp) { 4812 if (has_cpu_edp) {
4776 if (intel_panel_use_ssc(dev_priv) && can_ssc) { 4813 if (intel_panel_use_ssc(dev_priv) && can_ssc) {
4777 DRM_DEBUG_KMS("Using SSC on eDP\n"); 4814 DRM_DEBUG_KMS("Using SSC on eDP\n");
4778 temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD; 4815 val |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD;
4779 } 4816 }
4780 else 4817 else
4781 temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; 4818 val |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
4782 } else 4819 } else
4783 temp |= DREF_CPU_SOURCE_OUTPUT_DISABLE; 4820 val |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
4784 4821
4785 I915_WRITE(PCH_DREF_CONTROL, temp); 4822 I915_WRITE(PCH_DREF_CONTROL, val);
4786 POSTING_READ(PCH_DREF_CONTROL); 4823 POSTING_READ(PCH_DREF_CONTROL);
4787 udelay(200); 4824 udelay(200);
4788 } else { 4825 } else {
4789 DRM_DEBUG_KMS("Disabling SSC entirely\n"); 4826 DRM_DEBUG_KMS("Disabling SSC entirely\n");
4790 4827
4791 temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK; 4828 val &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
4792 4829
4793 /* Turn off CPU output */ 4830 /* Turn off CPU output */
4794 temp |= DREF_CPU_SOURCE_OUTPUT_DISABLE; 4831 val |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
4795 4832
4796 I915_WRITE(PCH_DREF_CONTROL, temp); 4833 I915_WRITE(PCH_DREF_CONTROL, val);
4797 POSTING_READ(PCH_DREF_CONTROL); 4834 POSTING_READ(PCH_DREF_CONTROL);
4798 udelay(200); 4835 udelay(200);
4799 4836
4800 /* Turn off the SSC source */ 4837 /* Turn off the SSC source */
4801 temp &= ~DREF_SSC_SOURCE_MASK; 4838 val &= ~DREF_SSC_SOURCE_MASK;
4802 temp |= DREF_SSC_SOURCE_DISABLE; 4839 val |= DREF_SSC_SOURCE_DISABLE;
4803 4840
4804 /* Turn off SSC1 */ 4841 /* Turn off SSC1 */
4805 temp &= ~ DREF_SSC1_ENABLE; 4842 val &= ~DREF_SSC1_ENABLE;
4806 4843
4807 I915_WRITE(PCH_DREF_CONTROL, temp); 4844 I915_WRITE(PCH_DREF_CONTROL, val);
4808 POSTING_READ(PCH_DREF_CONTROL); 4845 POSTING_READ(PCH_DREF_CONTROL);
4809 udelay(200); 4846 udelay(200);
4810 } 4847 }
4848
4849 BUG_ON(val != final);
4811} 4850}
4812 4851
4813/* Sequence to enable CLKOUT_DP for FDI usage and configure PCH FDI I/O. */ 4852/* Sequence to enable CLKOUT_DP for FDI usage and configure PCH FDI I/O. */