diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-07-02 09:09:45 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-09-06 01:58:52 -0400 |
commit | 732ce74f4adfcdac84862fb74c6897b4a152d5e1 (patch) | |
tree | dd7f9c2f30d4038f113973c17bb81788ee96f319 /drivers/gpu/drm/i915 | |
parent | 4ac41f47f8f6ba1d05b39783ea0819435074ef37 (diff) |
drm/i915/dvo: implement get_hw_state
Similar to the sdvo code we poke the dvo encoder whether the output is
active. Safe that dvo encoders are not standardized, so this requires
a new callback into the dvo chip driver.
Hence implement that for all 6 dvo drivers.
v2: With the newly added ns2501 we now have 6 dvo drivers instead of
just 5 ...
Acked-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r-- | drivers/gpu/drm/i915/dvo.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/dvo_ch7017.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/dvo_ch7xxx.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/dvo_ivch.c | 15 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/dvo_ns2501.c | 15 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/dvo_sil164.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/dvo_tfp410.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_dvo.c | 27 |
8 files changed, 119 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/dvo.h b/drivers/gpu/drm/i915/dvo.h index 0fa839e439b3..74b5efccfdb1 100644 --- a/drivers/gpu/drm/i915/dvo.h +++ b/drivers/gpu/drm/i915/dvo.h | |||
@@ -114,6 +114,12 @@ struct intel_dvo_dev_ops { | |||
114 | */ | 114 | */ |
115 | enum drm_connector_status (*detect)(struct intel_dvo_device *dvo); | 115 | enum drm_connector_status (*detect)(struct intel_dvo_device *dvo); |
116 | 116 | ||
117 | /* | ||
118 | * Probe the current hw status, returning true if the connected output | ||
119 | * is active. | ||
120 | */ | ||
121 | bool (*get_hw_state)(struct intel_dvo_device *dev); | ||
122 | |||
117 | /** | 123 | /** |
118 | * Query the device for the modes it provides. | 124 | * Query the device for the modes it provides. |
119 | * | 125 | * |
diff --git a/drivers/gpu/drm/i915/dvo_ch7017.c b/drivers/gpu/drm/i915/dvo_ch7017.c index 71e7650a2994..86b27d1d90c2 100644 --- a/drivers/gpu/drm/i915/dvo_ch7017.c +++ b/drivers/gpu/drm/i915/dvo_ch7017.c | |||
@@ -359,6 +359,18 @@ static void ch7017_dpms(struct intel_dvo_device *dvo, bool enable) | |||
359 | msleep(20); | 359 | msleep(20); |
360 | } | 360 | } |
361 | 361 | ||
362 | static bool ch7017_get_hw_state(struct intel_dvo_device *dvo) | ||
363 | { | ||
364 | uint8_t val; | ||
365 | |||
366 | ch7017_read(dvo, CH7017_LVDS_POWER_DOWN, &val); | ||
367 | |||
368 | if (val & CH7017_LVDS_POWER_DOWN_EN) | ||
369 | return false; | ||
370 | else | ||
371 | return true; | ||
372 | } | ||
373 | |||
362 | static void ch7017_dump_regs(struct intel_dvo_device *dvo) | 374 | static void ch7017_dump_regs(struct intel_dvo_device *dvo) |
363 | { | 375 | { |
364 | uint8_t val; | 376 | uint8_t val; |
@@ -396,6 +408,7 @@ struct intel_dvo_dev_ops ch7017_ops = { | |||
396 | .mode_valid = ch7017_mode_valid, | 408 | .mode_valid = ch7017_mode_valid, |
397 | .mode_set = ch7017_mode_set, | 409 | .mode_set = ch7017_mode_set, |
398 | .dpms = ch7017_dpms, | 410 | .dpms = ch7017_dpms, |
411 | .get_hw_state = ch7017_get_hw_state, | ||
399 | .dump_regs = ch7017_dump_regs, | 412 | .dump_regs = ch7017_dump_regs, |
400 | .destroy = ch7017_destroy, | 413 | .destroy = ch7017_destroy, |
401 | }; | 414 | }; |
diff --git a/drivers/gpu/drm/i915/dvo_ch7xxx.c b/drivers/gpu/drm/i915/dvo_ch7xxx.c index c1dea5b11f91..38f3a6cb8c7d 100644 --- a/drivers/gpu/drm/i915/dvo_ch7xxx.c +++ b/drivers/gpu/drm/i915/dvo_ch7xxx.c | |||
@@ -297,6 +297,18 @@ static void ch7xxx_dpms(struct intel_dvo_device *dvo, bool enable) | |||
297 | ch7xxx_writeb(dvo, CH7xxx_PM, CH7xxx_PM_FPD); | 297 | ch7xxx_writeb(dvo, CH7xxx_PM, CH7xxx_PM_FPD); |
298 | } | 298 | } |
299 | 299 | ||
300 | static bool ch7xxx_get_hw_state(struct intel_dvo_device *dvo) | ||
301 | { | ||
302 | u8 val; | ||
303 | |||
304 | ch7xxx_readb(dvo, CH7xxx_PM, &val); | ||
305 | |||
306 | if (val & CH7xxx_PM_FPD) | ||
307 | return false; | ||
308 | else | ||
309 | return true; | ||
310 | } | ||
311 | |||
300 | static void ch7xxx_dump_regs(struct intel_dvo_device *dvo) | 312 | static void ch7xxx_dump_regs(struct intel_dvo_device *dvo) |
301 | { | 313 | { |
302 | int i; | 314 | int i; |
@@ -326,6 +338,7 @@ struct intel_dvo_dev_ops ch7xxx_ops = { | |||
326 | .mode_valid = ch7xxx_mode_valid, | 338 | .mode_valid = ch7xxx_mode_valid, |
327 | .mode_set = ch7xxx_mode_set, | 339 | .mode_set = ch7xxx_mode_set, |
328 | .dpms = ch7xxx_dpms, | 340 | .dpms = ch7xxx_dpms, |
341 | .get_hw_state = ch7xxx_get_hw_state, | ||
329 | .dump_regs = ch7xxx_dump_regs, | 342 | .dump_regs = ch7xxx_dump_regs, |
330 | .destroy = ch7xxx_destroy, | 343 | .destroy = ch7xxx_destroy, |
331 | }; | 344 | }; |
diff --git a/drivers/gpu/drm/i915/dvo_ivch.c b/drivers/gpu/drm/i915/dvo_ivch.c index fa8ff6b050fa..baaf65bf0bdd 100644 --- a/drivers/gpu/drm/i915/dvo_ivch.c +++ b/drivers/gpu/drm/i915/dvo_ivch.c | |||
@@ -323,6 +323,20 @@ static void ivch_dpms(struct intel_dvo_device *dvo, bool enable) | |||
323 | udelay(16 * 1000); | 323 | udelay(16 * 1000); |
324 | } | 324 | } |
325 | 325 | ||
326 | static bool ivch_get_hw_state(struct intel_dvo_device *dvo) | ||
327 | { | ||
328 | uint16_t vr01; | ||
329 | |||
330 | /* Set the new power state of the panel. */ | ||
331 | if (!ivch_read(dvo, VR01, &vr01)) | ||
332 | return false; | ||
333 | |||
334 | if (vr01 & VR01_LCD_ENABLE) | ||
335 | return true; | ||
336 | else | ||
337 | return false; | ||
338 | } | ||
339 | |||
326 | static void ivch_mode_set(struct intel_dvo_device *dvo, | 340 | static void ivch_mode_set(struct intel_dvo_device *dvo, |
327 | struct drm_display_mode *mode, | 341 | struct drm_display_mode *mode, |
328 | struct drm_display_mode *adjusted_mode) | 342 | struct drm_display_mode *adjusted_mode) |
@@ -413,6 +427,7 @@ static void ivch_destroy(struct intel_dvo_device *dvo) | |||
413 | struct intel_dvo_dev_ops ivch_ops = { | 427 | struct intel_dvo_dev_ops ivch_ops = { |
414 | .init = ivch_init, | 428 | .init = ivch_init, |
415 | .dpms = ivch_dpms, | 429 | .dpms = ivch_dpms, |
430 | .get_hw_state = ivch_get_hw_state, | ||
416 | .mode_valid = ivch_mode_valid, | 431 | .mode_valid = ivch_mode_valid, |
417 | .mode_set = ivch_mode_set, | 432 | .mode_set = ivch_mode_set, |
418 | .detect = ivch_detect, | 433 | .detect = ivch_detect, |
diff --git a/drivers/gpu/drm/i915/dvo_ns2501.c b/drivers/gpu/drm/i915/dvo_ns2501.c index c4d9f2f395e6..c4a255be6979 100644 --- a/drivers/gpu/drm/i915/dvo_ns2501.c +++ b/drivers/gpu/drm/i915/dvo_ns2501.c | |||
@@ -493,6 +493,20 @@ static void ns2501_mode_set(struct intel_dvo_device *dvo, | |||
493 | } | 493 | } |
494 | 494 | ||
495 | /* set the NS2501 power state */ | 495 | /* set the NS2501 power state */ |
496 | static bool ns2501_get_hw_state(struct intel_dvo_device *dvo) | ||
497 | { | ||
498 | unsigned char ch; | ||
499 | |||
500 | if (!ns2501_readb(dvo, NS2501_REG8, &ch)) | ||
501 | return false; | ||
502 | |||
503 | if (ch & NS2501_8_PD) | ||
504 | return true; | ||
505 | else | ||
506 | return false; | ||
507 | } | ||
508 | |||
509 | /* set the NS2501 power state */ | ||
496 | static void ns2501_dpms(struct intel_dvo_device *dvo, bool enable) | 510 | static void ns2501_dpms(struct intel_dvo_device *dvo, bool enable) |
497 | { | 511 | { |
498 | bool ok; | 512 | bool ok; |
@@ -568,6 +582,7 @@ struct intel_dvo_dev_ops ns2501_ops = { | |||
568 | .mode_valid = ns2501_mode_valid, | 582 | .mode_valid = ns2501_mode_valid, |
569 | .mode_set = ns2501_mode_set, | 583 | .mode_set = ns2501_mode_set, |
570 | .dpms = ns2501_dpms, | 584 | .dpms = ns2501_dpms, |
585 | .get_hw_state = ns2501_get_hw_state, | ||
571 | .dump_regs = ns2501_dump_regs, | 586 | .dump_regs = ns2501_dump_regs, |
572 | .destroy = ns2501_destroy, | 587 | .destroy = ns2501_destroy, |
573 | }; | 588 | }; |
diff --git a/drivers/gpu/drm/i915/dvo_sil164.c b/drivers/gpu/drm/i915/dvo_sil164.c index cc24c1cabecd..4debd32e3e4c 100644 --- a/drivers/gpu/drm/i915/dvo_sil164.c +++ b/drivers/gpu/drm/i915/dvo_sil164.c | |||
@@ -226,6 +226,21 @@ static void sil164_dpms(struct intel_dvo_device *dvo, bool enable) | |||
226 | return; | 226 | return; |
227 | } | 227 | } |
228 | 228 | ||
229 | static bool sil164_get_hw_state(struct intel_dvo_device *dvo) | ||
230 | { | ||
231 | int ret; | ||
232 | unsigned char ch; | ||
233 | |||
234 | ret = sil164_readb(dvo, SIL164_REG8, &ch); | ||
235 | if (ret == false) | ||
236 | return false; | ||
237 | |||
238 | if (ch & SIL164_8_PD) | ||
239 | return true; | ||
240 | else | ||
241 | return false; | ||
242 | } | ||
243 | |||
229 | static void sil164_dump_regs(struct intel_dvo_device *dvo) | 244 | static void sil164_dump_regs(struct intel_dvo_device *dvo) |
230 | { | 245 | { |
231 | uint8_t val; | 246 | uint8_t val; |
@@ -258,6 +273,7 @@ struct intel_dvo_dev_ops sil164_ops = { | |||
258 | .mode_valid = sil164_mode_valid, | 273 | .mode_valid = sil164_mode_valid, |
259 | .mode_set = sil164_mode_set, | 274 | .mode_set = sil164_mode_set, |
260 | .dpms = sil164_dpms, | 275 | .dpms = sil164_dpms, |
276 | .get_hw_state = sil164_get_hw_state, | ||
261 | .dump_regs = sil164_dump_regs, | 277 | .dump_regs = sil164_dump_regs, |
262 | .destroy = sil164_destroy, | 278 | .destroy = sil164_destroy, |
263 | }; | 279 | }; |
diff --git a/drivers/gpu/drm/i915/dvo_tfp410.c b/drivers/gpu/drm/i915/dvo_tfp410.c index 097b3e82b00f..e17f1b07e915 100644 --- a/drivers/gpu/drm/i915/dvo_tfp410.c +++ b/drivers/gpu/drm/i915/dvo_tfp410.c | |||
@@ -249,6 +249,19 @@ static void tfp410_dpms(struct intel_dvo_device *dvo, bool enable) | |||
249 | tfp410_writeb(dvo, TFP410_CTL_1, ctl1); | 249 | tfp410_writeb(dvo, TFP410_CTL_1, ctl1); |
250 | } | 250 | } |
251 | 251 | ||
252 | static bool tfp410_get_hw_state(struct intel_dvo_device *dvo) | ||
253 | { | ||
254 | uint8_t ctl1; | ||
255 | |||
256 | if (!tfp410_readb(dvo, TFP410_CTL_1, &ctl1)) | ||
257 | return false; | ||
258 | |||
259 | if (ctl1 & TFP410_CTL_1_PD) | ||
260 | return true; | ||
261 | else | ||
262 | return false; | ||
263 | } | ||
264 | |||
252 | static void tfp410_dump_regs(struct intel_dvo_device *dvo) | 265 | static void tfp410_dump_regs(struct intel_dvo_device *dvo) |
253 | { | 266 | { |
254 | uint8_t val, val2; | 267 | uint8_t val, val2; |
@@ -299,6 +312,7 @@ struct intel_dvo_dev_ops tfp410_ops = { | |||
299 | .mode_valid = tfp410_mode_valid, | 312 | .mode_valid = tfp410_mode_valid, |
300 | .mode_set = tfp410_mode_set, | 313 | .mode_set = tfp410_mode_set, |
301 | .dpms = tfp410_dpms, | 314 | .dpms = tfp410_dpms, |
315 | .get_hw_state = tfp410_get_hw_state, | ||
302 | .dump_regs = tfp410_dump_regs, | 316 | .dump_regs = tfp410_dump_regs, |
303 | .destroy = tfp410_destroy, | 317 | .destroy = tfp410_destroy, |
304 | }; | 318 | }; |
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 84c0867e212b..e9397b72b4f3 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
@@ -105,6 +105,31 @@ static struct intel_dvo *intel_attached_dvo(struct drm_connector *connector) | |||
105 | struct intel_dvo, base); | 105 | struct intel_dvo, base); |
106 | } | 106 | } |
107 | 107 | ||
108 | static bool intel_dvo_connector_get_hw_state(struct intel_connector *connector) | ||
109 | { | ||
110 | struct intel_dvo *intel_dvo = intel_attached_dvo(&connector->base); | ||
111 | |||
112 | return intel_dvo->dev.dev_ops->get_hw_state(&intel_dvo->dev); | ||
113 | } | ||
114 | |||
115 | static bool intel_dvo_get_hw_state(struct intel_encoder *encoder, | ||
116 | enum pipe *pipe) | ||
117 | { | ||
118 | struct drm_device *dev = encoder->base.dev; | ||
119 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
120 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(&encoder->base); | ||
121 | u32 tmp; | ||
122 | |||
123 | tmp = I915_READ(intel_dvo->dev.dvo_reg); | ||
124 | |||
125 | if (!(tmp & DVO_ENABLE)) | ||
126 | return false; | ||
127 | |||
128 | *pipe = PORT_TO_PIPE(tmp); | ||
129 | |||
130 | return true; | ||
131 | } | ||
132 | |||
108 | static void intel_disable_dvo(struct intel_encoder *encoder) | 133 | static void intel_disable_dvo(struct intel_encoder *encoder) |
109 | { | 134 | { |
110 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; | 135 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; |
@@ -414,6 +439,8 @@ void intel_dvo_init(struct drm_device *dev) | |||
414 | 439 | ||
415 | intel_encoder->disable = intel_disable_dvo; | 440 | intel_encoder->disable = intel_disable_dvo; |
416 | intel_encoder->enable = intel_enable_dvo; | 441 | intel_encoder->enable = intel_enable_dvo; |
442 | intel_encoder->get_hw_state = intel_dvo_get_hw_state; | ||
443 | intel_connector->get_hw_state = intel_dvo_connector_get_hw_state; | ||
417 | 444 | ||
418 | /* Now, try to find a controller */ | 445 | /* Now, try to find a controller */ |
419 | for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { | 446 | for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { |