diff options
author | Dave Airlie <airlied@redhat.com> | 2010-04-19 23:11:45 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-04-19 23:11:45 -0400 |
commit | 97921a5b03d40681b3aed620a5e719710336c6df (patch) | |
tree | 33d6badc2afb50e87cbd232549c7708596ac12a7 /drivers/gpu/drm/i915/intel_dvo.c | |
parent | 01bf0b64579ead8a82e7cfc32ae44bc667e7ad0f (diff) | |
parent | e15831656778d032f3c7655949f8cc3997f2b04a (diff) |
Merge remote branch 'anholt/drm-intel-next' of /home/airlied/kernel/drm-next into drm-core-next
* 'anholt/drm-intel-next' of /home/airlied/kernel/drm-next: (48 commits)
agp/intel-gtt: kill previous_size assignments
agp/intel-gtt: kill intel_i830_tlbflush
agp/intel: split out gmch/gtt probe, part 1
agp/intel: kill mutli_gmch_chip
agp/intel: uncoditionally reconfigure driver on resume
agp/intel: split out the GTT support
agp/intel: introduce intel-agp.h header file
drm/i915: Don't touch PORT_HOTPLUG_EN in intel_dp_detect()
drm/i915/pch: Use minimal number of FDI lanes (v2)
drm/i915: Add the support of memory self-refresh on Ironlake
drm/i915: Move Pineview CxSR and watermark code into update_wm hook.
drm/i915: Only save/restore FBC on the platform that supports FBC
drm/i915: Fix the incorrect argument for SDVO SET_TV_format command
drm/i915: Add support of SDVO on Ibexpeak PCH
drm/i915: Don't enable pipe/plane/VCO early (wait for DPMS on).
drm/i915: do not read uninitialized ->dev_private
Revert "drm/i915: Use a dmi quirk to skip a broken SDVO TV output."
drm/i915: implement multifunction SDVO device support
drm/i915: remove unused intel_pipe_get_connector()
drm/i915: remove connector object in old output structure
...
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dvo.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_dvo.c | 103 |
1 files changed, 35 insertions, 68 deletions
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index ebf213c96b9c..227feca7cf8d 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
@@ -96,39 +96,11 @@ static void intel_dvo_dpms(struct drm_encoder *encoder, int mode) | |||
96 | } | 96 | } |
97 | } | 97 | } |
98 | 98 | ||
99 | static void intel_dvo_save(struct drm_connector *connector) | ||
100 | { | ||
101 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | ||
102 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | ||
103 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
104 | |||
105 | /* Each output should probably just save the registers it touches, | ||
106 | * but for now, use more overkill. | ||
107 | */ | ||
108 | dev_priv->saveDVOA = I915_READ(DVOA); | ||
109 | dev_priv->saveDVOB = I915_READ(DVOB); | ||
110 | dev_priv->saveDVOC = I915_READ(DVOC); | ||
111 | |||
112 | dvo->dev_ops->save(dvo); | ||
113 | } | ||
114 | |||
115 | static void intel_dvo_restore(struct drm_connector *connector) | ||
116 | { | ||
117 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | ||
118 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | ||
119 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
120 | |||
121 | dvo->dev_ops->restore(dvo); | ||
122 | |||
123 | I915_WRITE(DVOA, dev_priv->saveDVOA); | ||
124 | I915_WRITE(DVOB, dev_priv->saveDVOB); | ||
125 | I915_WRITE(DVOC, dev_priv->saveDVOC); | ||
126 | } | ||
127 | |||
128 | static int intel_dvo_mode_valid(struct drm_connector *connector, | 99 | static int intel_dvo_mode_valid(struct drm_connector *connector, |
129 | struct drm_display_mode *mode) | 100 | struct drm_display_mode *mode) |
130 | { | 101 | { |
131 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 102 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
103 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
132 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | 104 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; |
133 | 105 | ||
134 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | 106 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
@@ -241,7 +213,8 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, | |||
241 | */ | 213 | */ |
242 | static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector) | 214 | static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector) |
243 | { | 215 | { |
244 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 216 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
217 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
245 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | 218 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; |
246 | 219 | ||
247 | return dvo->dev_ops->detect(dvo); | 220 | return dvo->dev_ops->detect(dvo); |
@@ -249,7 +222,8 @@ static enum drm_connector_status intel_dvo_detect(struct drm_connector *connecto | |||
249 | 222 | ||
250 | static int intel_dvo_get_modes(struct drm_connector *connector) | 223 | static int intel_dvo_get_modes(struct drm_connector *connector) |
251 | { | 224 | { |
252 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 225 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
226 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
253 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | 227 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; |
254 | 228 | ||
255 | /* We should probably have an i2c driver get_modes function for those | 229 | /* We should probably have an i2c driver get_modes function for those |
@@ -257,7 +231,7 @@ static int intel_dvo_get_modes(struct drm_connector *connector) | |||
257 | * (TV-out, for example), but for now with just TMDS and LVDS, | 231 | * (TV-out, for example), but for now with just TMDS and LVDS, |
258 | * that's not the case. | 232 | * that's not the case. |
259 | */ | 233 | */ |
260 | intel_ddc_get_modes(intel_encoder); | 234 | intel_ddc_get_modes(connector, intel_encoder->ddc_bus); |
261 | if (!list_empty(&connector->probed_modes)) | 235 | if (!list_empty(&connector->probed_modes)) |
262 | return 1; | 236 | return 1; |
263 | 237 | ||
@@ -275,38 +249,10 @@ static int intel_dvo_get_modes(struct drm_connector *connector) | |||
275 | 249 | ||
276 | static void intel_dvo_destroy (struct drm_connector *connector) | 250 | static void intel_dvo_destroy (struct drm_connector *connector) |
277 | { | 251 | { |
278 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | ||
279 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
280 | |||
281 | if (dvo) { | ||
282 | if (dvo->dev_ops->destroy) | ||
283 | dvo->dev_ops->destroy(dvo); | ||
284 | if (dvo->panel_fixed_mode) | ||
285 | kfree(dvo->panel_fixed_mode); | ||
286 | /* no need, in i830_dvoices[] now */ | ||
287 | //kfree(dvo); | ||
288 | } | ||
289 | if (intel_encoder->i2c_bus) | ||
290 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
291 | if (intel_encoder->ddc_bus) | ||
292 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
293 | drm_sysfs_connector_remove(connector); | 252 | drm_sysfs_connector_remove(connector); |
294 | drm_connector_cleanup(connector); | 253 | drm_connector_cleanup(connector); |
295 | kfree(intel_encoder); | 254 | kfree(connector); |
296 | } | ||
297 | |||
298 | #ifdef RANDR_GET_CRTC_INTERFACE | ||
299 | static struct drm_crtc *intel_dvo_get_crtc(struct drm_connector *connector) | ||
300 | { | ||
301 | struct drm_device *dev = connector->dev; | ||
302 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
303 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | ||
304 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
305 | int pipe = !!(I915_READ(dvo->dvo_reg) & SDVO_PIPE_B_SELECT); | ||
306 | |||
307 | return intel_pipe_to_crtc(pScrn, pipe); | ||
308 | } | 255 | } |
309 | #endif | ||
310 | 256 | ||
311 | static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = { | 257 | static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = { |
312 | .dpms = intel_dvo_dpms, | 258 | .dpms = intel_dvo_dpms, |
@@ -318,8 +264,6 @@ static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = { | |||
318 | 264 | ||
319 | static const struct drm_connector_funcs intel_dvo_connector_funcs = { | 265 | static const struct drm_connector_funcs intel_dvo_connector_funcs = { |
320 | .dpms = drm_helper_connector_dpms, | 266 | .dpms = drm_helper_connector_dpms, |
321 | .save = intel_dvo_save, | ||
322 | .restore = intel_dvo_restore, | ||
323 | .detect = intel_dvo_detect, | 267 | .detect = intel_dvo_detect, |
324 | .destroy = intel_dvo_destroy, | 268 | .destroy = intel_dvo_destroy, |
325 | .fill_modes = drm_helper_probe_single_connector_modes, | 269 | .fill_modes = drm_helper_probe_single_connector_modes, |
@@ -328,12 +272,26 @@ static const struct drm_connector_funcs intel_dvo_connector_funcs = { | |||
328 | static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs = { | 272 | static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs = { |
329 | .mode_valid = intel_dvo_mode_valid, | 273 | .mode_valid = intel_dvo_mode_valid, |
330 | .get_modes = intel_dvo_get_modes, | 274 | .get_modes = intel_dvo_get_modes, |
331 | .best_encoder = intel_best_encoder, | 275 | .best_encoder = intel_attached_encoder, |
332 | }; | 276 | }; |
333 | 277 | ||
334 | static void intel_dvo_enc_destroy(struct drm_encoder *encoder) | 278 | static void intel_dvo_enc_destroy(struct drm_encoder *encoder) |
335 | { | 279 | { |
280 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
281 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
282 | |||
283 | if (dvo) { | ||
284 | if (dvo->dev_ops->destroy) | ||
285 | dvo->dev_ops->destroy(dvo); | ||
286 | if (dvo->panel_fixed_mode) | ||
287 | kfree(dvo->panel_fixed_mode); | ||
288 | } | ||
289 | if (intel_encoder->i2c_bus) | ||
290 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
291 | if (intel_encoder->ddc_bus) | ||
292 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
336 | drm_encoder_cleanup(encoder); | 293 | drm_encoder_cleanup(encoder); |
294 | kfree(intel_encoder); | ||
337 | } | 295 | } |
338 | 296 | ||
339 | static const struct drm_encoder_funcs intel_dvo_enc_funcs = { | 297 | static const struct drm_encoder_funcs intel_dvo_enc_funcs = { |
@@ -352,7 +310,8 @@ intel_dvo_get_current_mode (struct drm_connector *connector) | |||
352 | { | 310 | { |
353 | struct drm_device *dev = connector->dev; | 311 | struct drm_device *dev = connector->dev; |
354 | struct drm_i915_private *dev_priv = dev->dev_private; | 312 | struct drm_i915_private *dev_priv = dev->dev_private; |
355 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 313 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
314 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
356 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | 315 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; |
357 | uint32_t dvo_reg = dvo->dvo_reg; | 316 | uint32_t dvo_reg = dvo->dvo_reg; |
358 | uint32_t dvo_val = I915_READ(dvo_reg); | 317 | uint32_t dvo_val = I915_READ(dvo_reg); |
@@ -384,6 +343,7 @@ intel_dvo_get_current_mode (struct drm_connector *connector) | |||
384 | void intel_dvo_init(struct drm_device *dev) | 343 | void intel_dvo_init(struct drm_device *dev) |
385 | { | 344 | { |
386 | struct intel_encoder *intel_encoder; | 345 | struct intel_encoder *intel_encoder; |
346 | struct intel_connector *intel_connector; | ||
387 | struct intel_dvo_device *dvo; | 347 | struct intel_dvo_device *dvo; |
388 | struct i2c_adapter *i2cbus = NULL; | 348 | struct i2c_adapter *i2cbus = NULL; |
389 | int ret = 0; | 349 | int ret = 0; |
@@ -393,6 +353,12 @@ void intel_dvo_init(struct drm_device *dev) | |||
393 | if (!intel_encoder) | 353 | if (!intel_encoder) |
394 | return; | 354 | return; |
395 | 355 | ||
356 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | ||
357 | if (!intel_connector) { | ||
358 | kfree(intel_encoder); | ||
359 | return; | ||
360 | } | ||
361 | |||
396 | /* Set up the DDC bus */ | 362 | /* Set up the DDC bus */ |
397 | intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D"); | 363 | intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D"); |
398 | if (!intel_encoder->ddc_bus) | 364 | if (!intel_encoder->ddc_bus) |
@@ -400,7 +366,7 @@ void intel_dvo_init(struct drm_device *dev) | |||
400 | 366 | ||
401 | /* Now, try to find a controller */ | 367 | /* Now, try to find a controller */ |
402 | for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { | 368 | for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { |
403 | struct drm_connector *connector = &intel_encoder->base; | 369 | struct drm_connector *connector = &intel_connector->base; |
404 | int gpio; | 370 | int gpio; |
405 | 371 | ||
406 | dvo = &intel_dvo_devices[i]; | 372 | dvo = &intel_dvo_devices[i]; |
@@ -471,7 +437,7 @@ void intel_dvo_init(struct drm_device *dev) | |||
471 | drm_encoder_helper_add(&intel_encoder->enc, | 437 | drm_encoder_helper_add(&intel_encoder->enc, |
472 | &intel_dvo_helper_funcs); | 438 | &intel_dvo_helper_funcs); |
473 | 439 | ||
474 | drm_mode_connector_attach_encoder(&intel_encoder->base, | 440 | drm_mode_connector_attach_encoder(&intel_connector->base, |
475 | &intel_encoder->enc); | 441 | &intel_encoder->enc); |
476 | if (dvo->type == INTEL_DVO_CHIP_LVDS) { | 442 | if (dvo->type == INTEL_DVO_CHIP_LVDS) { |
477 | /* For our LVDS chipsets, we should hopefully be able | 443 | /* For our LVDS chipsets, we should hopefully be able |
@@ -496,4 +462,5 @@ void intel_dvo_init(struct drm_device *dev) | |||
496 | intel_i2c_destroy(i2cbus); | 462 | intel_i2c_destroy(i2cbus); |
497 | free_intel: | 463 | free_intel: |
498 | kfree(intel_encoder); | 464 | kfree(intel_encoder); |
465 | kfree(intel_connector); | ||
499 | } | 466 | } |