aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915
diff options
context:
space:
mode:
authorPaulo Zanoni <paulo.r.zanoni@intel.com>2012-12-01 09:04:25 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-12-10 05:14:29 -0500
commitdde86e2db54545ef981b64805097a7b4c3156d6e (patch)
tree636b940145e9bc2fd434a7bc35b210eba73c33cb /drivers/gpu/drm/i915
parent988d6ee8b2e8694830036821933372b22f3d1935 (diff)
drm/i915: add lpt_init_pch_refclk
We need this code to init the PCH SSC refclk and the FDI registers. The BIOS does this too and that's why VGA worked before this patch, until you tried to suspend the machine... This patch implements the "Sequence to enable CLKOUT_DP for FDI usage and configure PCH FDI/IO" from our documentation. v2: - Squash Damien Lespiau's reset spelling fix on top. - Add a comment that we don't need to bother about the ULT special case Damien noticed, since ULT won't have VGA. - Add a comment to rip out the SDV codepaths once haswell ships for real. Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> (v1) Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c3
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h2
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h6
-rw-r--r--drivers/gpu/drm/i915/intel_display.c184
4 files changed, 185 insertions, 10 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index a12921892446..530db83ef320 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -554,8 +554,7 @@ static int __i915_drm_thaw(struct drm_device *dev)
554 554
555 /* KMS EnterVT equivalent */ 555 /* KMS EnterVT equivalent */
556 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 556 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
557 if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) 557 intel_init_pch_refclk(dev);
558 ironlake_init_pch_refclk(dev);
559 558
560 mutex_lock(&dev->struct_mutex); 559 mutex_lock(&dev->struct_mutex);
561 dev_priv->mm.suspended = 0; 560 dev_priv->mm.suspended = 0;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8513e1cd221c..65213bc2f3c6 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1662,7 +1662,7 @@ extern void intel_modeset_setup_hw_state(struct drm_device *dev,
1662extern bool intel_fbc_enabled(struct drm_device *dev); 1662extern bool intel_fbc_enabled(struct drm_device *dev);
1663extern void intel_disable_fbc(struct drm_device *dev); 1663extern void intel_disable_fbc(struct drm_device *dev);
1664extern bool ironlake_set_drps(struct drm_device *dev, u8 val); 1664extern bool ironlake_set_drps(struct drm_device *dev, u8 val);
1665extern void ironlake_init_pch_refclk(struct drm_device *dev); 1665extern void intel_init_pch_refclk(struct drm_device *dev);
1666extern void gen6_set_rps(struct drm_device *dev, u8 val); 1666extern void gen6_set_rps(struct drm_device *dev, u8 val);
1667extern void intel_detect_pch(struct drm_device *dev); 1667extern void intel_detect_pch(struct drm_device *dev);
1668extern int intel_trans_dp_port_sel(struct drm_crtc *crtc); 1668extern int intel_trans_dp_port_sel(struct drm_crtc *crtc);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 0760425c892e..acf768d0a5d1 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -3843,7 +3843,9 @@
3843#define FDI_PHASE_SYNC_EN(pipe) (1<<(FDIA_PHASE_SYNC_SHIFT_EN - ((pipe) * 2))) 3843#define FDI_PHASE_SYNC_EN(pipe) (1<<(FDIA_PHASE_SYNC_SHIFT_EN - ((pipe) * 2)))
3844#define FDI_BC_BIFURCATION_SELECT (1 << 12) 3844#define FDI_BC_BIFURCATION_SELECT (1 << 12)
3845#define SOUTH_CHICKEN2 0xc2004 3845#define SOUTH_CHICKEN2 0xc2004
3846#define DPLS_EDP_PPS_FIX_DIS (1<<0) 3846#define FDI_MPHY_IOSFSB_RESET_STATUS (1<<13)
3847#define FDI_MPHY_IOSFSB_RESET_CTL (1<<12)
3848#define DPLS_EDP_PPS_FIX_DIS (1<<0)
3847 3849
3848#define _FDI_RXA_CHICKEN 0xc200c 3850#define _FDI_RXA_CHICKEN 0xc200c
3849#define _FDI_RXB_CHICKEN 0xc2010 3851#define _FDI_RXB_CHICKEN 0xc2010
@@ -4555,10 +4557,12 @@
4555#define SBI_SSCDIVINTPHASE_PROPAGATE (1<<0) 4557#define SBI_SSCDIVINTPHASE_PROPAGATE (1<<0)
4556#define SBI_SSCCTL 0x020c 4558#define SBI_SSCCTL 0x020c
4557#define SBI_SSCCTL6 0x060C 4559#define SBI_SSCCTL6 0x060C
4560#define SBI_SSCCTL_PATHALT (1<<3)
4558#define SBI_SSCCTL_DISABLE (1<<0) 4561#define SBI_SSCCTL_DISABLE (1<<0)
4559#define SBI_SSCAUXDIV6 0x0610 4562#define SBI_SSCAUXDIV6 0x0610
4560#define SBI_SSCAUXDIV_FINALDIV2SEL(x) ((x)<<4) 4563#define SBI_SSCAUXDIV_FINALDIV2SEL(x) ((x)<<4)
4561#define SBI_DBUFF0 0x2a00 4564#define SBI_DBUFF0 0x2a00
4565#define SBI_DBUFF0_ENABLE (1<<0)
4562 4566
4563/* LPT PIXCLK_GATE */ 4567/* LPT PIXCLK_GATE */
4564#define PIXCLK_GATE 0xC6020 4568#define PIXCLK_GATE 0xC6020
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 64993ecacf93..ce7fc519f614 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4864,10 +4864,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
4864 return ret; 4864 return ret;
4865} 4865}
4866 4866
4867/* 4867static void ironlake_init_pch_refclk(struct drm_device *dev)
4868 * Initialize reference clocks when the driver loads
4869 */
4870void ironlake_init_pch_refclk(struct drm_device *dev)
4871{ 4868{
4872 struct drm_i915_private *dev_priv = dev->dev_private; 4869 struct drm_i915_private *dev_priv = dev->dev_private;
4873 struct drm_mode_config *mode_config = &dev->mode_config; 4870 struct drm_mode_config *mode_config = &dev->mode_config;
@@ -4981,6 +4978,182 @@ void ironlake_init_pch_refclk(struct drm_device *dev)
4981 } 4978 }
4982} 4979}
4983 4980
4981/* Sequence to enable CLKOUT_DP for FDI usage and configure PCH FDI I/O. */
4982static void lpt_init_pch_refclk(struct drm_device *dev)
4983{
4984 struct drm_i915_private *dev_priv = dev->dev_private;
4985 struct drm_mode_config *mode_config = &dev->mode_config;
4986 struct intel_encoder *encoder;
4987 bool has_vga = false;
4988 bool is_sdv = false;
4989 u32 tmp;
4990
4991 list_for_each_entry(encoder, &mode_config->encoder_list, base.head) {
4992 switch (encoder->type) {
4993 case INTEL_OUTPUT_ANALOG:
4994 has_vga = true;
4995 break;
4996 }
4997 }
4998
4999 if (!has_vga)
5000 return;
5001
5002 /* XXX: Rip out SDV support once Haswell ships for real. */
5003 if (IS_HASWELL(dev) && (dev->pci_device & 0xFF00) == 0x0C00)
5004 is_sdv = true;
5005
5006 tmp = intel_sbi_read(dev_priv, SBI_SSCCTL, SBI_ICLK);
5007 tmp &= ~SBI_SSCCTL_DISABLE;
5008 tmp |= SBI_SSCCTL_PATHALT;
5009 intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK);
5010
5011 udelay(24);
5012
5013 tmp = intel_sbi_read(dev_priv, SBI_SSCCTL, SBI_ICLK);
5014 tmp &= ~SBI_SSCCTL_PATHALT;
5015 intel_sbi_write(dev_priv, SBI_SSCCTL, tmp, SBI_ICLK);
5016
5017 if (!is_sdv) {
5018 tmp = I915_READ(SOUTH_CHICKEN2);
5019 tmp |= FDI_MPHY_IOSFSB_RESET_CTL;
5020 I915_WRITE(SOUTH_CHICKEN2, tmp);
5021
5022 if (wait_for_atomic_us(I915_READ(SOUTH_CHICKEN2) &
5023 FDI_MPHY_IOSFSB_RESET_STATUS, 100))
5024 DRM_ERROR("FDI mPHY reset assert timeout\n");
5025
5026 tmp = I915_READ(SOUTH_CHICKEN2);
5027 tmp &= ~FDI_MPHY_IOSFSB_RESET_CTL;
5028 I915_WRITE(SOUTH_CHICKEN2, tmp);
5029
5030 if (wait_for_atomic_us((I915_READ(SOUTH_CHICKEN2) &
5031 FDI_MPHY_IOSFSB_RESET_STATUS) == 0,
5032 100))
5033 DRM_ERROR("FDI mPHY reset de-assert timeout\n");
5034 }
5035
5036 tmp = intel_sbi_read(dev_priv, 0x8008, SBI_MPHY);
5037 tmp &= ~(0xFF << 24);
5038 tmp |= (0x12 << 24);
5039 intel_sbi_write(dev_priv, 0x8008, tmp, SBI_MPHY);
5040
5041 if (!is_sdv) {
5042 tmp = intel_sbi_read(dev_priv, 0x808C, SBI_MPHY);
5043 tmp &= ~(0x3 << 6);
5044 tmp |= (1 << 6) | (1 << 0);
5045 intel_sbi_write(dev_priv, 0x808C, tmp, SBI_MPHY);
5046 }
5047
5048 if (is_sdv) {
5049 tmp = intel_sbi_read(dev_priv, 0x800C, SBI_MPHY);
5050 tmp |= 0x7FFF;
5051 intel_sbi_write(dev_priv, 0x800C, tmp, SBI_MPHY);
5052 }
5053
5054 tmp = intel_sbi_read(dev_priv, 0x2008, SBI_MPHY);
5055 tmp |= (1 << 11);
5056 intel_sbi_write(dev_priv, 0x2008, tmp, SBI_MPHY);
5057
5058 tmp = intel_sbi_read(dev_priv, 0x2108, SBI_MPHY);
5059 tmp |= (1 << 11);
5060 intel_sbi_write(dev_priv, 0x2108, tmp, SBI_MPHY);
5061
5062 if (is_sdv) {
5063 tmp = intel_sbi_read(dev_priv, 0x2038, SBI_MPHY);
5064 tmp |= (0x3F << 24) | (0xF << 20) | (0xF << 16);
5065 intel_sbi_write(dev_priv, 0x2038, tmp, SBI_MPHY);
5066
5067 tmp = intel_sbi_read(dev_priv, 0x2138, SBI_MPHY);
5068 tmp |= (0x3F << 24) | (0xF << 20) | (0xF << 16);
5069 intel_sbi_write(dev_priv, 0x2138, tmp, SBI_MPHY);
5070
5071 tmp = intel_sbi_read(dev_priv, 0x203C, SBI_MPHY);
5072 tmp |= (0x3F << 8);
5073 intel_sbi_write(dev_priv, 0x203C, tmp, SBI_MPHY);
5074
5075 tmp = intel_sbi_read(dev_priv, 0x213C, SBI_MPHY);
5076 tmp |= (0x3F << 8);
5077 intel_sbi_write(dev_priv, 0x213C, tmp, SBI_MPHY);
5078 }
5079
5080 tmp = intel_sbi_read(dev_priv, 0x206C, SBI_MPHY);
5081 tmp |= (1 << 24) | (1 << 21) | (1 << 18);
5082 intel_sbi_write(dev_priv, 0x206C, tmp, SBI_MPHY);
5083
5084 tmp = intel_sbi_read(dev_priv, 0x216C, SBI_MPHY);
5085 tmp |= (1 << 24) | (1 << 21) | (1 << 18);
5086 intel_sbi_write(dev_priv, 0x216C, tmp, SBI_MPHY);
5087
5088 if (!is_sdv) {
5089 tmp = intel_sbi_read(dev_priv, 0x2080, SBI_MPHY);
5090 tmp &= ~(7 << 13);
5091 tmp |= (5 << 13);
5092 intel_sbi_write(dev_priv, 0x2080, tmp, SBI_MPHY);
5093
5094 tmp = intel_sbi_read(dev_priv, 0x2180, SBI_MPHY);
5095 tmp &= ~(7 << 13);
5096 tmp |= (5 << 13);
5097 intel_sbi_write(dev_priv, 0x2180, tmp, SBI_MPHY);
5098 }
5099
5100 tmp = intel_sbi_read(dev_priv, 0x208C, SBI_MPHY);
5101 tmp &= ~0xFF;
5102 tmp |= 0x1C;
5103 intel_sbi_write(dev_priv, 0x208C, tmp, SBI_MPHY);
5104
5105 tmp = intel_sbi_read(dev_priv, 0x218C, SBI_MPHY);
5106 tmp &= ~0xFF;
5107 tmp |= 0x1C;
5108 intel_sbi_write(dev_priv, 0x218C, tmp, SBI_MPHY);
5109
5110 tmp = intel_sbi_read(dev_priv, 0x2098, SBI_MPHY);
5111 tmp &= ~(0xFF << 16);
5112 tmp |= (0x1C << 16);
5113 intel_sbi_write(dev_priv, 0x2098, tmp, SBI_MPHY);
5114
5115 tmp = intel_sbi_read(dev_priv, 0x2198, SBI_MPHY);
5116 tmp &= ~(0xFF << 16);
5117 tmp |= (0x1C << 16);
5118 intel_sbi_write(dev_priv, 0x2198, tmp, SBI_MPHY);
5119
5120 if (!is_sdv) {
5121 tmp = intel_sbi_read(dev_priv, 0x20C4, SBI_MPHY);
5122 tmp |= (1 << 27);
5123 intel_sbi_write(dev_priv, 0x20C4, tmp, SBI_MPHY);
5124
5125 tmp = intel_sbi_read(dev_priv, 0x21C4, SBI_MPHY);
5126 tmp |= (1 << 27);
5127 intel_sbi_write(dev_priv, 0x21C4, tmp, SBI_MPHY);
5128
5129 tmp = intel_sbi_read(dev_priv, 0x20EC, SBI_MPHY);
5130 tmp &= ~(0xF << 28);
5131 tmp |= (4 << 28);
5132 intel_sbi_write(dev_priv, 0x20EC, tmp, SBI_MPHY);
5133
5134 tmp = intel_sbi_read(dev_priv, 0x21EC, SBI_MPHY);
5135 tmp &= ~(0xF << 28);
5136 tmp |= (4 << 28);
5137 intel_sbi_write(dev_priv, 0x21EC, tmp, SBI_MPHY);
5138 }
5139
5140 /* ULT uses SBI_GEN0, but ULT doesn't have VGA, so we don't care. */
5141 tmp = intel_sbi_read(dev_priv, SBI_DBUFF0, SBI_ICLK);
5142 tmp |= SBI_DBUFF0_ENABLE;
5143 intel_sbi_write(dev_priv, SBI_DBUFF0, tmp, SBI_ICLK);
5144}
5145
5146/*
5147 * Initialize reference clocks when the driver loads
5148 */
5149void intel_init_pch_refclk(struct drm_device *dev)
5150{
5151 if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
5152 ironlake_init_pch_refclk(dev);
5153 else if (HAS_PCH_LPT(dev))
5154 lpt_init_pch_refclk(dev);
5155}
5156
4984static int ironlake_get_refclk(struct drm_crtc *crtc) 5157static int ironlake_get_refclk(struct drm_crtc *crtc)
4985{ 5158{
4986 struct drm_device *dev = crtc->dev; 5159 struct drm_device *dev = crtc->dev;
@@ -8410,8 +8583,7 @@ static void intel_setup_outputs(struct drm_device *dev)
8410 intel_encoder_clones(encoder); 8583 intel_encoder_clones(encoder);
8411 } 8584 }
8412 8585
8413 if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) 8586 intel_init_pch_refclk(dev);
8414 ironlake_init_pch_refclk(dev);
8415 8587
8416 drm_helper_move_panel_connectors_to_head(dev); 8588 drm_helper_move_panel_connectors_to_head(dev);
8417} 8589}