aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_hdmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_hdmi.c')
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c97
1 files changed, 51 insertions, 46 deletions
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index c33451aec1bd..48cade0cf7b1 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -27,6 +27,7 @@
27 */ 27 */
28 28
29#include <linux/i2c.h> 29#include <linux/i2c.h>
30#include <linux/slab.h>
30#include <linux/delay.h> 31#include <linux/delay.h>
31#include "drmP.h" 32#include "drmP.h"
32#include "drm.h" 33#include "drm.h"
@@ -50,8 +51,8 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder,
50 struct drm_i915_private *dev_priv = dev->dev_private; 51 struct drm_i915_private *dev_priv = dev->dev_private;
51 struct drm_crtc *crtc = encoder->crtc; 52 struct drm_crtc *crtc = encoder->crtc;
52 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 53 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
53 struct intel_output *intel_output = enc_to_intel_output(encoder); 54 struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
54 struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; 55 struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
55 u32 sdvox; 56 u32 sdvox;
56 57
57 sdvox = SDVO_ENCODING_HDMI | 58 sdvox = SDVO_ENCODING_HDMI |
@@ -73,8 +74,8 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
73{ 74{
74 struct drm_device *dev = encoder->dev; 75 struct drm_device *dev = encoder->dev;
75 struct drm_i915_private *dev_priv = dev->dev_private; 76 struct drm_i915_private *dev_priv = dev->dev_private;
76 struct intel_output *intel_output = enc_to_intel_output(encoder); 77 struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder);
77 struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; 78 struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
78 u32 temp; 79 u32 temp;
79 80
80 temp = I915_READ(hdmi_priv->sdvox_reg); 81 temp = I915_READ(hdmi_priv->sdvox_reg);
@@ -82,7 +83,7 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
82 /* HW workaround, need to toggle enable bit off and on for 12bpc, but 83 /* HW workaround, need to toggle enable bit off and on for 12bpc, but
83 * we do this anyway which shows more stable in testing. 84 * we do this anyway which shows more stable in testing.
84 */ 85 */
85 if (IS_IGDNG(dev)) { 86 if (HAS_PCH_SPLIT(dev)) {
86 I915_WRITE(hdmi_priv->sdvox_reg, temp & ~SDVO_ENABLE); 87 I915_WRITE(hdmi_priv->sdvox_reg, temp & ~SDVO_ENABLE);
87 POSTING_READ(hdmi_priv->sdvox_reg); 88 POSTING_READ(hdmi_priv->sdvox_reg);
88 } 89 }
@@ -99,7 +100,7 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
99 /* HW workaround, need to write this twice for issue that may result 100 /* HW workaround, need to write this twice for issue that may result
100 * in first write getting masked. 101 * in first write getting masked.
101 */ 102 */
102 if (IS_IGDNG(dev)) { 103 if (HAS_PCH_SPLIT(dev)) {
103 I915_WRITE(hdmi_priv->sdvox_reg, temp); 104 I915_WRITE(hdmi_priv->sdvox_reg, temp);
104 POSTING_READ(hdmi_priv->sdvox_reg); 105 POSTING_READ(hdmi_priv->sdvox_reg);
105 } 106 }
@@ -109,8 +110,8 @@ static void intel_hdmi_save(struct drm_connector *connector)
109{ 110{
110 struct drm_device *dev = connector->dev; 111 struct drm_device *dev = connector->dev;
111 struct drm_i915_private *dev_priv = dev->dev_private; 112 struct drm_i915_private *dev_priv = dev->dev_private;
112 struct intel_output *intel_output = to_intel_output(connector); 113 struct intel_encoder *intel_encoder = to_intel_encoder(connector);
113 struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; 114 struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
114 115
115 hdmi_priv->save_SDVOX = I915_READ(hdmi_priv->sdvox_reg); 116 hdmi_priv->save_SDVOX = I915_READ(hdmi_priv->sdvox_reg);
116} 117}
@@ -119,8 +120,8 @@ static void intel_hdmi_restore(struct drm_connector *connector)
119{ 120{
120 struct drm_device *dev = connector->dev; 121 struct drm_device *dev = connector->dev;
121 struct drm_i915_private *dev_priv = dev->dev_private; 122 struct drm_i915_private *dev_priv = dev->dev_private;
122 struct intel_output *intel_output = to_intel_output(connector); 123 struct intel_encoder *intel_encoder = to_intel_encoder(connector);
123 struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; 124 struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
124 125
125 I915_WRITE(hdmi_priv->sdvox_reg, hdmi_priv->save_SDVOX); 126 I915_WRITE(hdmi_priv->sdvox_reg, hdmi_priv->save_SDVOX);
126 POSTING_READ(hdmi_priv->sdvox_reg); 127 POSTING_READ(hdmi_priv->sdvox_reg);
@@ -150,21 +151,21 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
150static enum drm_connector_status 151static enum drm_connector_status
151intel_hdmi_detect(struct drm_connector *connector) 152intel_hdmi_detect(struct drm_connector *connector)
152{ 153{
153 struct intel_output *intel_output = to_intel_output(connector); 154 struct intel_encoder *intel_encoder = to_intel_encoder(connector);
154 struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; 155 struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv;
155 struct edid *edid = NULL; 156 struct edid *edid = NULL;
156 enum drm_connector_status status = connector_status_disconnected; 157 enum drm_connector_status status = connector_status_disconnected;
157 158
158 hdmi_priv->has_hdmi_sink = false; 159 hdmi_priv->has_hdmi_sink = false;
159 edid = drm_get_edid(&intel_output->base, 160 edid = drm_get_edid(&intel_encoder->base,
160 intel_output->ddc_bus); 161 intel_encoder->ddc_bus);
161 162
162 if (edid) { 163 if (edid) {
163 if (edid->input & DRM_EDID_INPUT_DIGITAL) { 164 if (edid->input & DRM_EDID_INPUT_DIGITAL) {
164 status = connector_status_connected; 165 status = connector_status_connected;
165 hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid); 166 hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid);
166 } 167 }
167 intel_output->base.display_info.raw_edid = NULL; 168 intel_encoder->base.display_info.raw_edid = NULL;
168 kfree(edid); 169 kfree(edid);
169 } 170 }
170 171
@@ -173,24 +174,24 @@ intel_hdmi_detect(struct drm_connector *connector)
173 174
174static int intel_hdmi_get_modes(struct drm_connector *connector) 175static int intel_hdmi_get_modes(struct drm_connector *connector)
175{ 176{
176 struct intel_output *intel_output = to_intel_output(connector); 177 struct intel_encoder *intel_encoder = to_intel_encoder(connector);
177 178
178 /* We should parse the EDID data and find out if it's an HDMI sink so 179 /* We should parse the EDID data and find out if it's an HDMI sink so
179 * we can send audio to it. 180 * we can send audio to it.
180 */ 181 */
181 182
182 return intel_ddc_get_modes(intel_output); 183 return intel_ddc_get_modes(intel_encoder);
183} 184}
184 185
185static void intel_hdmi_destroy(struct drm_connector *connector) 186static void intel_hdmi_destroy(struct drm_connector *connector)
186{ 187{
187 struct intel_output *intel_output = to_intel_output(connector); 188 struct intel_encoder *intel_encoder = to_intel_encoder(connector);
188 189
189 if (intel_output->i2c_bus) 190 if (intel_encoder->i2c_bus)
190 intel_i2c_destroy(intel_output->i2c_bus); 191 intel_i2c_destroy(intel_encoder->i2c_bus);
191 drm_sysfs_connector_remove(connector); 192 drm_sysfs_connector_remove(connector);
192 drm_connector_cleanup(connector); 193 drm_connector_cleanup(connector);
193 kfree(intel_output); 194 kfree(intel_encoder);
194} 195}
195 196
196static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = { 197static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = {
@@ -225,63 +226,67 @@ static const struct drm_encoder_funcs intel_hdmi_enc_funcs = {
225 .destroy = intel_hdmi_enc_destroy, 226 .destroy = intel_hdmi_enc_destroy,
226}; 227};
227 228
228
229void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) 229void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
230{ 230{
231 struct drm_i915_private *dev_priv = dev->dev_private; 231 struct drm_i915_private *dev_priv = dev->dev_private;
232 struct drm_connector *connector; 232 struct drm_connector *connector;
233 struct intel_output *intel_output; 233 struct intel_encoder *intel_encoder;
234 struct intel_hdmi_priv *hdmi_priv; 234 struct intel_hdmi_priv *hdmi_priv;
235 235
236 intel_output = kcalloc(sizeof(struct intel_output) + 236 intel_encoder = kcalloc(sizeof(struct intel_encoder) +
237 sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL); 237 sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL);
238 if (!intel_output) 238 if (!intel_encoder)
239 return; 239 return;
240 hdmi_priv = (struct intel_hdmi_priv *)(intel_output + 1); 240 hdmi_priv = (struct intel_hdmi_priv *)(intel_encoder + 1);
241 241
242 connector = &intel_output->base; 242 connector = &intel_encoder->base;
243 drm_connector_init(dev, connector, &intel_hdmi_connector_funcs, 243 drm_connector_init(dev, connector, &intel_hdmi_connector_funcs,
244 DRM_MODE_CONNECTOR_HDMIA); 244 DRM_MODE_CONNECTOR_HDMIA);
245 drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs); 245 drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs);
246 246
247 intel_output->type = INTEL_OUTPUT_HDMI; 247 intel_encoder->type = INTEL_OUTPUT_HDMI;
248 248
249 connector->interlace_allowed = 0; 249 connector->interlace_allowed = 0;
250 connector->doublescan_allowed = 0; 250 connector->doublescan_allowed = 0;
251 intel_output->crtc_mask = (1 << 0) | (1 << 1); 251 intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
252 252
253 /* Set up the DDC bus. */ 253 /* Set up the DDC bus. */
254 if (sdvox_reg == SDVOB) { 254 if (sdvox_reg == SDVOB) {
255 intel_output->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT); 255 intel_encoder->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT);
256 intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB"); 256 intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB");
257 dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;
257 } else if (sdvox_reg == SDVOC) { 258 } else if (sdvox_reg == SDVOC) {
258 intel_output->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT); 259 intel_encoder->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT);
259 intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC"); 260 intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC");
261 dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
260 } else if (sdvox_reg == HDMIB) { 262 } else if (sdvox_reg == HDMIB) {
261 intel_output->clone_mask = (1 << INTEL_HDMID_CLONE_BIT); 263 intel_encoder->clone_mask = (1 << INTEL_HDMID_CLONE_BIT);
262 intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE, 264 intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOE,
263 "HDMIB"); 265 "HDMIB");
266 dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;
264 } else if (sdvox_reg == HDMIC) { 267 } else if (sdvox_reg == HDMIC) {
265 intel_output->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT); 268 intel_encoder->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT);
266 intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD, 269 intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOD,
267 "HDMIC"); 270 "HDMIC");
271 dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
268 } else if (sdvox_reg == HDMID) { 272 } else if (sdvox_reg == HDMID) {
269 intel_output->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT); 273 intel_encoder->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT);
270 intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF, 274 intel_encoder->ddc_bus = intel_i2c_create(dev, PCH_GPIOF,
271 "HDMID"); 275 "HDMID");
276 dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS;
272 } 277 }
273 if (!intel_output->ddc_bus) 278 if (!intel_encoder->ddc_bus)
274 goto err_connector; 279 goto err_connector;
275 280
276 hdmi_priv->sdvox_reg = sdvox_reg; 281 hdmi_priv->sdvox_reg = sdvox_reg;
277 intel_output->dev_priv = hdmi_priv; 282 intel_encoder->dev_priv = hdmi_priv;
278 283
279 drm_encoder_init(dev, &intel_output->enc, &intel_hdmi_enc_funcs, 284 drm_encoder_init(dev, &intel_encoder->enc, &intel_hdmi_enc_funcs,
280 DRM_MODE_ENCODER_TMDS); 285 DRM_MODE_ENCODER_TMDS);
281 drm_encoder_helper_add(&intel_output->enc, &intel_hdmi_helper_funcs); 286 drm_encoder_helper_add(&intel_encoder->enc, &intel_hdmi_helper_funcs);
282 287
283 drm_mode_connector_attach_encoder(&intel_output->base, 288 drm_mode_connector_attach_encoder(&intel_encoder->base,
284 &intel_output->enc); 289 &intel_encoder->enc);
285 drm_sysfs_connector_add(connector); 290 drm_sysfs_connector_add(connector);
286 291
287 /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written 292 /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written
@@ -297,7 +302,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
297 302
298err_connector: 303err_connector:
299 drm_connector_cleanup(connector); 304 drm_connector_cleanup(connector);
300 kfree(intel_output); 305 kfree(intel_encoder);
301 306
302 return; 307 return;
303} 308}