Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+119
+6
drivers/gpu/drm/i915/dvo.h
··· 114 114 */ 115 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 124 * Query the device for the modes it provides. 119 125 *
+13
drivers/gpu/drm/i915/dvo_ch7017.c
··· 359 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 374 static void ch7017_dump_regs(struct intel_dvo_device *dvo) 363 375 { 364 376 uint8_t val; ··· 408 396 .mode_valid = ch7017_mode_valid, 409 397 .mode_set = ch7017_mode_set, 410 398 .dpms = ch7017_dpms, 399 + .get_hw_state = ch7017_get_hw_state, 411 400 .dump_regs = ch7017_dump_regs, 412 401 .destroy = ch7017_destroy, 413 402 };
+13
drivers/gpu/drm/i915/dvo_ch7xxx.c
··· 297 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 312 static void ch7xxx_dump_regs(struct intel_dvo_device *dvo) 301 313 { 302 314 int i; ··· 338 326 .mode_valid = ch7xxx_mode_valid, 339 327 .mode_set = ch7xxx_mode_set, 340 328 .dpms = ch7xxx_dpms, 329 + .get_hw_state = ch7xxx_get_hw_state, 341 330 .dump_regs = ch7xxx_dump_regs, 342 331 .destroy = ch7xxx_destroy, 343 332 };
+15
drivers/gpu/drm/i915/dvo_ivch.c
··· 323 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 340 static void ivch_mode_set(struct intel_dvo_device *dvo, 327 341 struct drm_display_mode *mode, 328 342 struct drm_display_mode *adjusted_mode) ··· 427 413 struct intel_dvo_dev_ops ivch_ops = { 428 414 .init = ivch_init, 429 415 .dpms = ivch_dpms, 416 + .get_hw_state = ivch_get_hw_state, 430 417 .mode_valid = ivch_mode_valid, 431 418 .mode_set = ivch_mode_set, 432 419 .detect = ivch_detect,
+15
drivers/gpu/drm/i915/dvo_ns2501.c
··· 493 493 } 494 494 495 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 510 static void ns2501_dpms(struct intel_dvo_device *dvo, bool enable) 497 511 { 498 512 bool ok; ··· 582 568 .mode_valid = ns2501_mode_valid, 583 569 .mode_set = ns2501_mode_set, 584 570 .dpms = ns2501_dpms, 571 + .get_hw_state = ns2501_get_hw_state, 585 572 .dump_regs = ns2501_dump_regs, 586 573 .destroy = ns2501_destroy, 587 574 };
+16
drivers/gpu/drm/i915/dvo_sil164.c
··· 226 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 244 static void sil164_dump_regs(struct intel_dvo_device *dvo) 230 245 { 231 246 uint8_t val; ··· 273 258 .mode_valid = sil164_mode_valid, 274 259 .mode_set = sil164_mode_set, 275 260 .dpms = sil164_dpms, 261 + .get_hw_state = sil164_get_hw_state, 276 262 .dump_regs = sil164_dump_regs, 277 263 .destroy = sil164_destroy, 278 264 };
+14
drivers/gpu/drm/i915/dvo_tfp410.c
··· 249 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 265 static void tfp410_dump_regs(struct intel_dvo_device *dvo) 253 266 { 254 267 uint8_t val, val2; ··· 312 299 .mode_valid = tfp410_mode_valid, 313 300 .mode_set = tfp410_mode_set, 314 301 .dpms = tfp410_dpms, 302 + .get_hw_state = tfp410_get_hw_state, 315 303 .dump_regs = tfp410_dump_regs, 316 304 .destroy = tfp410_destroy, 317 305 };
+27
drivers/gpu/drm/i915/intel_dvo.c
··· 105 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 133 static void intel_disable_dvo(struct intel_encoder *encoder) 109 134 { 110 135 struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; ··· 439 414 440 415 intel_encoder->disable = intel_disable_dvo; 441 416 intel_encoder->enable = intel_enable_dvo; 417 + intel_encoder->get_hw_state = intel_dvo_get_hw_state; 418 + intel_connector->get_hw_state = intel_dvo_connector_get_hw_state; 442 419 443 420 /* Now, try to find a controller */ 444 421 for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) {