aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_ddi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ddi.c')
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c124
1 files changed, 107 insertions, 17 deletions
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 31f4fe271388..1591576a6101 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -72,6 +72,45 @@ static const u32 hsw_ddi_translations_hdmi[] = {
72 0x80FFFFFF, 0x00030002, /* 11: 1000 1000 0 */ 72 0x80FFFFFF, 0x00030002, /* 11: 1000 1000 0 */
73}; 73};
74 74
75static const u32 bdw_ddi_translations_edp[] = {
76 0x00FFFFFF, 0x00000012, /* DP parameters */
77 0x00EBAFFF, 0x00020011,
78 0x00C71FFF, 0x0006000F,
79 0x00FFFFFF, 0x00020011,
80 0x00DB6FFF, 0x0005000F,
81 0x00BEEFFF, 0x000A000C,
82 0x00FFFFFF, 0x0005000F,
83 0x00DB6FFF, 0x000A000C,
84 0x00FFFFFF, 0x000A000C,
85 0x00FFFFFF, 0x00140006 /* HDMI parameters 800mV 0dB*/
86};
87
88static const u32 bdw_ddi_translations_dp[] = {
89 0x00FFFFFF, 0x0007000E, /* DP parameters */
90 0x00D75FFF, 0x000E000A,
91 0x00BEFFFF, 0x00140006,
92 0x00FFFFFF, 0x000E000A,
93 0x00D75FFF, 0x00180004,
94 0x80CB2FFF, 0x001B0002,
95 0x00F7DFFF, 0x00180004,
96 0x80D75FFF, 0x001B0002,
97 0x80FFFFFF, 0x001B0002,
98 0x00FFFFFF, 0x00140006 /* HDMI parameters 800mV 0dB*/
99};
100
101static const u32 bdw_ddi_translations_fdi[] = {
102 0x00FFFFFF, 0x0001000E, /* FDI parameters */
103 0x00D75FFF, 0x0004000A,
104 0x00C30FFF, 0x00070006,
105 0x00AAAFFF, 0x000C0000,
106 0x00FFFFFF, 0x0004000A,
107 0x00D75FFF, 0x00090004,
108 0x00C30FFF, 0x000C0000,
109 0x00FFFFFF, 0x00070006,
110 0x00D75FFF, 0x000C0000,
111 0x00FFFFFF, 0x00140006 /* HDMI parameters 800mV 0dB*/
112};
113
75enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder) 114enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
76{ 115{
77 struct drm_encoder *encoder = &intel_encoder->base; 116 struct drm_encoder *encoder = &intel_encoder->base;
@@ -92,8 +131,9 @@ enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder)
92 } 131 }
93} 132}
94 133
95/* On Haswell, DDI port buffers must be programmed with correct values 134/*
96 * in advance. The buffer values are different for FDI and DP modes, 135 * Starting with Haswell, DDI port buffers must be programmed with correct
136 * values in advance. The buffer values are different for FDI and DP modes,
97 * but the HDMI/DVI fields are shared among those. So we program the DDI 137 * but the HDMI/DVI fields are shared among those. So we program the DDI
98 * in either FDI or DP modes only, as HDMI connections will work with both 138 * in either FDI or DP modes only, as HDMI connections will work with both
99 * of those 139 * of those
@@ -103,10 +143,47 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port)
103 struct drm_i915_private *dev_priv = dev->dev_private; 143 struct drm_i915_private *dev_priv = dev->dev_private;
104 u32 reg; 144 u32 reg;
105 int i; 145 int i;
106 const u32 *ddi_translations = (port == PORT_E) ?
107 hsw_ddi_translations_fdi :
108 hsw_ddi_translations_dp;
109 int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift; 146 int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
147 const u32 *ddi_translations_fdi;
148 const u32 *ddi_translations_dp;
149 const u32 *ddi_translations_edp;
150 const u32 *ddi_translations;
151
152 if (IS_BROADWELL(dev)) {
153 ddi_translations_fdi = bdw_ddi_translations_fdi;
154 ddi_translations_dp = bdw_ddi_translations_dp;
155 ddi_translations_edp = bdw_ddi_translations_edp;
156 } else if (IS_HASWELL(dev)) {
157 ddi_translations_fdi = hsw_ddi_translations_fdi;
158 ddi_translations_dp = hsw_ddi_translations_dp;
159 ddi_translations_edp = hsw_ddi_translations_dp;
160 } else {
161 WARN(1, "ddi translation table missing\n");
162 ddi_translations_edp = bdw_ddi_translations_dp;
163 ddi_translations_fdi = bdw_ddi_translations_fdi;
164 ddi_translations_dp = bdw_ddi_translations_dp;
165 }
166
167 switch (port) {
168 case PORT_A:
169 ddi_translations = ddi_translations_edp;
170 break;
171 case PORT_B:
172 case PORT_C:
173 ddi_translations = ddi_translations_dp;
174 break;
175 case PORT_D:
176 if (intel_dpd_is_edp(dev))
177 ddi_translations = ddi_translations_edp;
178 else
179 ddi_translations = ddi_translations_dp;
180 break;
181 case PORT_E:
182 ddi_translations = ddi_translations_fdi;
183 break;
184 default:
185 BUG();
186 }
110 187
111 for (i = 0, reg = DDI_BUF_TRANS(port); 188 for (i = 0, reg = DDI_BUF_TRANS(port);
112 i < ARRAY_SIZE(hsw_ddi_translations_fdi); i++) { 189 i < ARRAY_SIZE(hsw_ddi_translations_fdi); i++) {
@@ -756,7 +833,8 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
756 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 833 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
757 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); 834 struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc);
758 struct drm_encoder *encoder = &intel_encoder->base; 835 struct drm_encoder *encoder = &intel_encoder->base;
759 struct drm_i915_private *dev_priv = crtc->dev->dev_private; 836 struct drm_device *dev = crtc->dev;
837 struct drm_i915_private *dev_priv = dev->dev_private;
760 enum pipe pipe = intel_crtc->pipe; 838 enum pipe pipe = intel_crtc->pipe;
761 enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; 839 enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
762 enum port port = intel_ddi_get_encoder_port(intel_encoder); 840 enum port port = intel_ddi_get_encoder_port(intel_encoder);
@@ -792,10 +870,11 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
792 if (cpu_transcoder == TRANSCODER_EDP) { 870 if (cpu_transcoder == TRANSCODER_EDP) {
793 switch (pipe) { 871 switch (pipe) {
794 case PIPE_A: 872 case PIPE_A:
795 /* Can only use the always-on power well for eDP when 873 /* On Haswell, can only use the always-on power well for
796 * not using the panel fitter, and when not using motion 874 * eDP when not using the panel fitter, and when not
797 * blur mitigation (which we don't support). */ 875 * using motion blur mitigation (which we don't
798 if (intel_crtc->config.pch_pfit.enabled) 876 * support). */
877 if (IS_HASWELL(dev) && intel_crtc->config.pch_pfit.enabled)
799 temp |= TRANS_DDI_EDP_INPUT_A_ONOFF; 878 temp |= TRANS_DDI_EDP_INPUT_A_ONOFF;
800 else 879 else
801 temp |= TRANS_DDI_EDP_INPUT_A_ON; 880 temp |= TRANS_DDI_EDP_INPUT_A_ON;
@@ -1156,18 +1235,29 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder)
1156 1235
1157int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv) 1236int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv)
1158{ 1237{
1238 struct drm_device *dev = dev_priv->dev;
1159 uint32_t lcpll = I915_READ(LCPLL_CTL); 1239 uint32_t lcpll = I915_READ(LCPLL_CTL);
1240 uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK;
1160 1241
1161 if (lcpll & LCPLL_CD_SOURCE_FCLK) 1242 if (lcpll & LCPLL_CD_SOURCE_FCLK) {
1162 return 800000; 1243 return 800000;
1163 else if (I915_READ(HSW_FUSE_STRAP) & HSW_CDCLK_LIMIT) 1244 } else if (I915_READ(HSW_FUSE_STRAP) & HSW_CDCLK_LIMIT) {
1164 return 450000; 1245 return 450000;
1165 else if ((lcpll & LCPLL_CLK_FREQ_MASK) == LCPLL_CLK_FREQ_450) 1246 } else if (freq == LCPLL_CLK_FREQ_450) {
1166 return 450000; 1247 return 450000;
1167 else if (IS_ULT(dev_priv->dev)) 1248 } else if (IS_HASWELL(dev)) {
1168 return 337500; 1249 if (IS_ULT(dev))
1169 else 1250 return 337500;
1170 return 540000; 1251 else
1252 return 540000;
1253 } else {
1254 if (freq == LCPLL_CLK_FREQ_54O_BDW)
1255 return 540000;
1256 else if (freq == LCPLL_CLK_FREQ_337_5_BDW)
1257 return 337500;
1258 else
1259 return 675000;
1260 }
1171} 1261}
1172 1262
1173void intel_ddi_pll_init(struct drm_device *dev) 1263void intel_ddi_pll_init(struct drm_device *dev)