diff options
| -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/i915_drv.c | 9 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_crt.c | 136 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_ddi.c | 59 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 1417 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 144 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 61 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_dvo.c | 94 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_hdmi.c | 151 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_lvds.c | 95 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 164 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_tv.c | 61 |
20 files changed, 2017 insertions, 472 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/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 7f3863fb138c..a7837e556945 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
| @@ -470,6 +470,9 @@ static int i915_drm_freeze(struct drm_device *dev) | |||
| 470 | "GEM idle failed, resume might fail\n"); | 470 | "GEM idle failed, resume might fail\n"); |
| 471 | return error; | 471 | return error; |
| 472 | } | 472 | } |
| 473 | |||
| 474 | intel_modeset_disable(dev); | ||
| 475 | |||
| 473 | drm_irq_uninstall(dev); | 476 | drm_irq_uninstall(dev); |
| 474 | } | 477 | } |
| 475 | 478 | ||
| @@ -543,13 +546,9 @@ static int i915_drm_thaw(struct drm_device *dev) | |||
| 543 | mutex_unlock(&dev->struct_mutex); | 546 | mutex_unlock(&dev->struct_mutex); |
| 544 | 547 | ||
| 545 | intel_modeset_init_hw(dev); | 548 | intel_modeset_init_hw(dev); |
| 549 | intel_modeset_setup_hw_state(dev); | ||
| 546 | drm_mode_config_reset(dev); | 550 | drm_mode_config_reset(dev); |
| 547 | drm_irq_install(dev); | 551 | drm_irq_install(dev); |
| 548 | |||
| 549 | /* Resume the modeset for every activated CRTC */ | ||
| 550 | mutex_lock(&dev->mode_config.mutex); | ||
| 551 | drm_helper_resume_force_mode(dev); | ||
| 552 | mutex_unlock(&dev->mode_config.mutex); | ||
| 553 | } | 552 | } |
| 554 | 553 | ||
| 555 | intel_opregion_init(dev); | 554 | intel_opregion_init(dev); |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f16ab5e25aef..26c6959a524a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -241,7 +241,6 @@ struct drm_i915_error_state { | |||
| 241 | }; | 241 | }; |
| 242 | 242 | ||
| 243 | struct drm_i915_display_funcs { | 243 | struct drm_i915_display_funcs { |
| 244 | void (*dpms)(struct drm_crtc *crtc, int mode); | ||
| 245 | bool (*fbc_enabled)(struct drm_device *dev); | 244 | bool (*fbc_enabled)(struct drm_device *dev); |
| 246 | void (*enable_fbc)(struct drm_crtc *crtc, unsigned long interval); | 245 | void (*enable_fbc)(struct drm_crtc *crtc, unsigned long interval); |
| 247 | void (*disable_fbc)(struct drm_device *dev); | 246 | void (*disable_fbc)(struct drm_device *dev); |
| @@ -257,6 +256,8 @@ struct drm_i915_display_funcs { | |||
| 257 | struct drm_display_mode *adjusted_mode, | 256 | struct drm_display_mode *adjusted_mode, |
| 258 | int x, int y, | 257 | int x, int y, |
| 259 | struct drm_framebuffer *old_fb); | 258 | struct drm_framebuffer *old_fb); |
| 259 | void (*crtc_enable)(struct drm_crtc *crtc); | ||
| 260 | void (*crtc_disable)(struct drm_crtc *crtc); | ||
| 260 | void (*off)(struct drm_crtc *crtc); | 261 | void (*off)(struct drm_crtc *crtc); |
| 261 | void (*write_eld)(struct drm_connector *connector, | 262 | void (*write_eld)(struct drm_connector *connector, |
| 262 | struct drm_crtc *crtc); | 263 | struct drm_crtc *crtc); |
| @@ -1550,6 +1551,7 @@ extern void intel_modeset_init(struct drm_device *dev); | |||
| 1550 | extern void intel_modeset_gem_init(struct drm_device *dev); | 1551 | extern void intel_modeset_gem_init(struct drm_device *dev); |
| 1551 | extern void intel_modeset_cleanup(struct drm_device *dev); | 1552 | extern void intel_modeset_cleanup(struct drm_device *dev); |
| 1552 | extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state); | 1553 | extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state); |
| 1554 | extern void intel_modeset_setup_hw_state(struct drm_device *dev); | ||
| 1553 | extern bool intel_fbc_enabled(struct drm_device *dev); | 1555 | extern bool intel_fbc_enabled(struct drm_device *dev); |
| 1554 | extern void intel_disable_fbc(struct drm_device *dev); | 1556 | extern void intel_disable_fbc(struct drm_device *dev); |
| 1555 | extern bool ironlake_set_drps(struct drm_device *dev, u8 val); | 1557 | extern bool ironlake_set_drps(struct drm_device *dev, u8 val); |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 75dcfa4ec5ce..a828e90602b9 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
| @@ -4037,6 +4037,8 @@ | |||
| 4037 | #define PORT_TRANS_C_SEL_CPT (2<<29) | 4037 | #define PORT_TRANS_C_SEL_CPT (2<<29) |
| 4038 | #define PORT_TRANS_SEL_MASK (3<<29) | 4038 | #define PORT_TRANS_SEL_MASK (3<<29) |
| 4039 | #define PORT_TRANS_SEL_CPT(pipe) ((pipe) << 29) | 4039 | #define PORT_TRANS_SEL_CPT(pipe) ((pipe) << 29) |
| 4040 | #define PORT_TO_PIPE(val) (((val) & (1<<30)) >> 30) | ||
| 4041 | #define PORT_TO_PIPE_CPT(val) (((val) & PORT_TRANS_SEL_MASK) >> 29) | ||
| 4040 | 4042 | ||
| 4041 | #define TRANS_DP_CTL_A 0xe0300 | 4043 | #define TRANS_DP_CTL_A 0xe0300 |
| 4042 | #define TRANS_DP_CTL_B 0xe1300 | 4044 | #define TRANS_DP_CTL_B 0xe1300 |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 236191377b0f..c42b9809f86d 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
| @@ -61,42 +61,63 @@ static struct intel_crt *intel_encoder_to_crt(struct intel_encoder *encoder) | |||
| 61 | return container_of(encoder, struct intel_crt, base); | 61 | return container_of(encoder, struct intel_crt, base); |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | static void pch_crt_dpms(struct drm_encoder *encoder, int mode) | 64 | static bool intel_crt_get_hw_state(struct intel_encoder *encoder, |
| 65 | enum pipe *pipe) | ||
| 65 | { | 66 | { |
| 66 | struct drm_device *dev = encoder->dev; | 67 | struct drm_device *dev = encoder->base.dev; |
| 67 | struct drm_i915_private *dev_priv = dev->dev_private; | 68 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 69 | struct intel_crt *crt = intel_encoder_to_crt(encoder); | ||
| 70 | u32 tmp; | ||
| 71 | |||
| 72 | tmp = I915_READ(crt->adpa_reg); | ||
| 73 | |||
| 74 | if (!(tmp & ADPA_DAC_ENABLE)) | ||
| 75 | return false; | ||
| 76 | |||
| 77 | if (HAS_PCH_CPT(dev)) | ||
| 78 | *pipe = PORT_TO_PIPE_CPT(tmp); | ||
| 79 | else | ||
| 80 | *pipe = PORT_TO_PIPE(tmp); | ||
| 81 | |||
| 82 | return true; | ||
| 83 | } | ||
| 84 | |||
| 85 | static void intel_disable_crt(struct intel_encoder *encoder) | ||
| 86 | { | ||
| 87 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; | ||
| 88 | struct intel_crt *crt = intel_encoder_to_crt(encoder); | ||
| 68 | u32 temp; | 89 | u32 temp; |
| 69 | 90 | ||
| 70 | temp = I915_READ(PCH_ADPA); | 91 | temp = I915_READ(crt->adpa_reg); |
| 92 | temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); | ||
| 71 | temp &= ~ADPA_DAC_ENABLE; | 93 | temp &= ~ADPA_DAC_ENABLE; |
| 94 | I915_WRITE(crt->adpa_reg, temp); | ||
| 95 | } | ||
| 72 | 96 | ||
| 73 | switch (mode) { | 97 | static void intel_enable_crt(struct intel_encoder *encoder) |
| 74 | case DRM_MODE_DPMS_ON: | 98 | { |
| 75 | temp |= ADPA_DAC_ENABLE; | 99 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; |
| 76 | break; | 100 | struct intel_crt *crt = intel_encoder_to_crt(encoder); |
| 77 | case DRM_MODE_DPMS_STANDBY: | 101 | u32 temp; |
| 78 | case DRM_MODE_DPMS_SUSPEND: | ||
| 79 | case DRM_MODE_DPMS_OFF: | ||
| 80 | /* Just leave port enable cleared */ | ||
| 81 | break; | ||
| 82 | } | ||
| 83 | 102 | ||
| 84 | I915_WRITE(PCH_ADPA, temp); | 103 | temp = I915_READ(crt->adpa_reg); |
| 104 | temp |= ADPA_DAC_ENABLE; | ||
| 105 | I915_WRITE(crt->adpa_reg, temp); | ||
| 85 | } | 106 | } |
| 86 | 107 | ||
| 87 | static void gmch_crt_dpms(struct drm_encoder *encoder, int mode) | 108 | /* Note: The caller is required to filter out dpms modes not supported by the |
| 109 | * platform. */ | ||
| 110 | static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode) | ||
| 88 | { | 111 | { |
| 89 | struct drm_device *dev = encoder->dev; | 112 | struct drm_device *dev = encoder->base.dev; |
| 90 | struct drm_i915_private *dev_priv = dev->dev_private; | 113 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 114 | struct intel_crt *crt = intel_encoder_to_crt(encoder); | ||
| 91 | u32 temp; | 115 | u32 temp; |
| 92 | 116 | ||
| 93 | temp = I915_READ(ADPA); | 117 | temp = I915_READ(crt->adpa_reg); |
| 94 | temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); | 118 | temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); |
| 95 | temp &= ~ADPA_DAC_ENABLE; | 119 | temp &= ~ADPA_DAC_ENABLE; |
| 96 | 120 | ||
| 97 | if (IS_VALLEYVIEW(dev) && mode != DRM_MODE_DPMS_ON) | ||
| 98 | mode = DRM_MODE_DPMS_OFF; | ||
| 99 | |||
| 100 | switch (mode) { | 121 | switch (mode) { |
| 101 | case DRM_MODE_DPMS_ON: | 122 | case DRM_MODE_DPMS_ON: |
| 102 | temp |= ADPA_DAC_ENABLE; | 123 | temp |= ADPA_DAC_ENABLE; |
| @@ -112,7 +133,51 @@ static void gmch_crt_dpms(struct drm_encoder *encoder, int mode) | |||
| 112 | break; | 133 | break; |
| 113 | } | 134 | } |
| 114 | 135 | ||
| 115 | I915_WRITE(ADPA, temp); | 136 | I915_WRITE(crt->adpa_reg, temp); |
| 137 | } | ||
| 138 | |||
| 139 | static void intel_crt_dpms(struct drm_connector *connector, int mode) | ||
| 140 | { | ||
| 141 | struct drm_device *dev = connector->dev; | ||
| 142 | struct intel_encoder *encoder = intel_attached_encoder(connector); | ||
| 143 | struct drm_crtc *crtc; | ||
| 144 | int old_dpms; | ||
| 145 | |||
| 146 | /* PCH platforms and VLV only support on/off. */ | ||
| 147 | if (INTEL_INFO(dev)->gen < 5 && mode != DRM_MODE_DPMS_ON) | ||
| 148 | mode = DRM_MODE_DPMS_OFF; | ||
| 149 | |||
| 150 | if (mode == connector->dpms) | ||
| 151 | return; | ||
| 152 | |||
| 153 | old_dpms = connector->dpms; | ||
| 154 | connector->dpms = mode; | ||
| 155 | |||
| 156 | /* Only need to change hw state when actually enabled */ | ||
| 157 | crtc = encoder->base.crtc; | ||
| 158 | if (!crtc) { | ||
| 159 | encoder->connectors_active = false; | ||
| 160 | return; | ||
| 161 | } | ||
| 162 | |||
| 163 | /* We need the pipe to run for anything but OFF. */ | ||
| 164 | if (mode == DRM_MODE_DPMS_OFF) | ||
| 165 | encoder->connectors_active = false; | ||
| 166 | else | ||
| 167 | encoder->connectors_active = true; | ||
| 168 | |||
| 169 | if (mode < old_dpms) { | ||
| 170 | /* From off to on, enable the pipe first. */ | ||
| 171 | intel_crtc_update_dpms(crtc); | ||
| 172 | |||
| 173 | intel_crt_set_dpms(encoder, mode); | ||
| 174 | } else { | ||
| 175 | intel_crt_set_dpms(encoder, mode); | ||
| 176 | |||
| 177 | intel_crtc_update_dpms(crtc); | ||
| 178 | } | ||
| 179 | |||
| 180 | intel_modeset_check_state(connector->dev); | ||
| 116 | } | 181 | } |
| 117 | 182 | ||
| 118 | static int intel_crt_mode_valid(struct drm_connector *connector, | 183 | static int intel_crt_mode_valid(struct drm_connector *connector, |
| @@ -603,25 +668,15 @@ static void intel_crt_reset(struct drm_connector *connector) | |||
| 603 | * Routines for controlling stuff on the analog port | 668 | * Routines for controlling stuff on the analog port |
| 604 | */ | 669 | */ |
| 605 | 670 | ||
| 606 | static const struct drm_encoder_helper_funcs pch_encoder_funcs = { | 671 | static const struct drm_encoder_helper_funcs crt_encoder_funcs = { |
| 607 | .mode_fixup = intel_crt_mode_fixup, | 672 | .mode_fixup = intel_crt_mode_fixup, |
| 608 | .prepare = intel_encoder_prepare, | ||
| 609 | .commit = intel_encoder_commit, | ||
| 610 | .mode_set = intel_crt_mode_set, | 673 | .mode_set = intel_crt_mode_set, |
| 611 | .dpms = pch_crt_dpms, | 674 | .disable = intel_encoder_noop, |
| 612 | }; | ||
| 613 | |||
| 614 | static const struct drm_encoder_helper_funcs gmch_encoder_funcs = { | ||
| 615 | .mode_fixup = intel_crt_mode_fixup, | ||
| 616 | .prepare = intel_encoder_prepare, | ||
| 617 | .commit = intel_encoder_commit, | ||
| 618 | .mode_set = intel_crt_mode_set, | ||
| 619 | .dpms = gmch_crt_dpms, | ||
| 620 | }; | 675 | }; |
| 621 | 676 | ||
| 622 | static const struct drm_connector_funcs intel_crt_connector_funcs = { | 677 | static const struct drm_connector_funcs intel_crt_connector_funcs = { |
| 623 | .reset = intel_crt_reset, | 678 | .reset = intel_crt_reset, |
| 624 | .dpms = drm_helper_connector_dpms, | 679 | .dpms = intel_crt_dpms, |
| 625 | .detect = intel_crt_detect, | 680 | .detect = intel_crt_detect, |
| 626 | .fill_modes = drm_helper_probe_single_connector_modes, | 681 | .fill_modes = drm_helper_probe_single_connector_modes, |
| 627 | .destroy = intel_crt_destroy, | 682 | .destroy = intel_crt_destroy, |
| @@ -662,7 +717,6 @@ void intel_crt_init(struct drm_device *dev) | |||
| 662 | struct intel_crt *crt; | 717 | struct intel_crt *crt; |
| 663 | struct intel_connector *intel_connector; | 718 | struct intel_connector *intel_connector; |
| 664 | struct drm_i915_private *dev_priv = dev->dev_private; | 719 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 665 | const struct drm_encoder_helper_funcs *encoder_helper_funcs; | ||
| 666 | 720 | ||
| 667 | /* Skip machines without VGA that falsely report hotplug events */ | 721 | /* Skip machines without VGA that falsely report hotplug events */ |
| 668 | if (dmi_check_system(intel_no_crt)) | 722 | if (dmi_check_system(intel_no_crt)) |
| @@ -701,18 +755,18 @@ void intel_crt_init(struct drm_device *dev) | |||
| 701 | connector->doublescan_allowed = 0; | 755 | connector->doublescan_allowed = 0; |
| 702 | 756 | ||
| 703 | if (HAS_PCH_SPLIT(dev)) | 757 | if (HAS_PCH_SPLIT(dev)) |
| 704 | encoder_helper_funcs = &pch_encoder_funcs; | ||
| 705 | else | ||
| 706 | encoder_helper_funcs = &gmch_encoder_funcs; | ||
| 707 | |||
| 708 | if (HAS_PCH_SPLIT(dev)) | ||
| 709 | crt->adpa_reg = PCH_ADPA; | 758 | crt->adpa_reg = PCH_ADPA; |
| 710 | else if (IS_VALLEYVIEW(dev)) | 759 | else if (IS_VALLEYVIEW(dev)) |
| 711 | crt->adpa_reg = VLV_ADPA; | 760 | crt->adpa_reg = VLV_ADPA; |
| 712 | else | 761 | else |
| 713 | crt->adpa_reg = ADPA; | 762 | crt->adpa_reg = ADPA; |
| 714 | 763 | ||
| 715 | drm_encoder_helper_add(&crt->base.base, encoder_helper_funcs); | 764 | crt->base.disable = intel_disable_crt; |
| 765 | crt->base.enable = intel_enable_crt; | ||
| 766 | crt->base.get_hw_state = intel_crt_get_hw_state; | ||
| 767 | intel_connector->get_hw_state = intel_connector_get_hw_state; | ||
| 768 | |||
| 769 | drm_encoder_helper_add(&crt->base.base, &crt_encoder_funcs); | ||
| 716 | drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); | 770 | drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); |
| 717 | 771 | ||
| 718 | drm_sysfs_connector_add(connector); | 772 | drm_sysfs_connector_add(connector); |
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 170e3861aa4e..bfe375466a0e 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
| @@ -757,26 +757,63 @@ void intel_ddi_mode_set(struct drm_encoder *encoder, | |||
| 757 | intel_hdmi->set_infoframes(encoder, adjusted_mode); | 757 | intel_hdmi->set_infoframes(encoder, adjusted_mode); |
| 758 | } | 758 | } |
| 759 | 759 | ||
| 760 | void intel_ddi_dpms(struct drm_encoder *encoder, int mode) | 760 | bool intel_ddi_get_hw_state(struct intel_encoder *encoder, |
| 761 | enum pipe *pipe) | ||
| 761 | { | 762 | { |
| 762 | struct drm_device *dev = encoder->dev; | 763 | struct drm_device *dev = encoder->base.dev; |
| 763 | struct drm_i915_private *dev_priv = dev->dev_private; | 764 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 764 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | 765 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); |
| 766 | u32 tmp; | ||
| 767 | int i; | ||
| 768 | |||
| 769 | tmp = I915_READ(DDI_BUF_CTL(intel_hdmi->ddi_port)); | ||
| 770 | |||
| 771 | if (!(tmp & DDI_BUF_CTL_ENABLE)) | ||
| 772 | return false; | ||
| 773 | |||
| 774 | for_each_pipe(i) { | ||
| 775 | tmp = I915_READ(DDI_FUNC_CTL(i)); | ||
| 776 | |||
| 777 | if ((tmp & PIPE_DDI_PORT_MASK) | ||
| 778 | == PIPE_DDI_SELECT_PORT(intel_hdmi->ddi_port)) { | ||
| 779 | *pipe = i; | ||
| 780 | return true; | ||
| 781 | } | ||
| 782 | } | ||
| 783 | |||
| 784 | DRM_DEBUG_KMS("No pipe for ddi port %i found\n", intel_hdmi->ddi_port); | ||
| 785 | |||
| 786 | return true; | ||
| 787 | } | ||
| 788 | |||
| 789 | void intel_enable_ddi(struct intel_encoder *encoder) | ||
| 790 | { | ||
| 791 | struct drm_device *dev = encoder->base.dev; | ||
| 792 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 793 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); | ||
| 765 | int port = intel_hdmi->ddi_port; | 794 | int port = intel_hdmi->ddi_port; |
| 766 | u32 temp; | 795 | u32 temp; |
| 767 | 796 | ||
| 768 | temp = I915_READ(DDI_BUF_CTL(port)); | 797 | temp = I915_READ(DDI_BUF_CTL(port)); |
| 769 | 798 | temp |= DDI_BUF_CTL_ENABLE; | |
| 770 | if (mode != DRM_MODE_DPMS_ON) { | ||
| 771 | temp &= ~DDI_BUF_CTL_ENABLE; | ||
| 772 | } else { | ||
| 773 | temp |= DDI_BUF_CTL_ENABLE; | ||
| 774 | } | ||
| 775 | 799 | ||
| 776 | /* Enable DDI_BUF_CTL. In HDMI/DVI mode, the port width, | 800 | /* Enable DDI_BUF_CTL. In HDMI/DVI mode, the port width, |
| 777 | * and swing/emphasis values are ignored so nothing special needs | 801 | * and swing/emphasis values are ignored so nothing special needs |
| 778 | * to be done besides enabling the port. | 802 | * to be done besides enabling the port. |
| 779 | */ | 803 | */ |
| 780 | I915_WRITE(DDI_BUF_CTL(port), | 804 | I915_WRITE(DDI_BUF_CTL(port), temp); |
| 781 | temp); | 805 | } |
| 806 | |||
| 807 | void intel_disable_ddi(struct intel_encoder *encoder) | ||
| 808 | { | ||
| 809 | struct drm_device *dev = encoder->base.dev; | ||
| 810 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 811 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); | ||
| 812 | int port = intel_hdmi->ddi_port; | ||
| 813 | u32 temp; | ||
| 814 | |||
| 815 | temp = I915_READ(DDI_BUF_CTL(port)); | ||
| 816 | temp &= ~DDI_BUF_CTL_ENABLE; | ||
| 817 | |||
| 818 | I915_WRITE(DDI_BUF_CTL(port), temp); | ||
| 782 | } | 819 | } |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 778cbb88bddc..e061acdde45d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -1006,7 +1006,7 @@ void intel_wait_for_pipe_off(struct drm_device *dev, int pipe) | |||
| 1006 | /* Wait for the Pipe State to go off */ | 1006 | /* Wait for the Pipe State to go off */ |
| 1007 | if (wait_for((I915_READ(reg) & I965_PIPECONF_ACTIVE) == 0, | 1007 | if (wait_for((I915_READ(reg) & I965_PIPECONF_ACTIVE) == 0, |
| 1008 | 100)) | 1008 | 100)) |
| 1009 | DRM_DEBUG_KMS("pipe_off wait timed out\n"); | 1009 | WARN(1, "pipe_off wait timed out\n"); |
| 1010 | } else { | 1010 | } else { |
| 1011 | u32 last_line, line_mask; | 1011 | u32 last_line, line_mask; |
| 1012 | int reg = PIPEDSL(pipe); | 1012 | int reg = PIPEDSL(pipe); |
| @@ -1024,7 +1024,7 @@ void intel_wait_for_pipe_off(struct drm_device *dev, int pipe) | |||
| 1024 | } while (((I915_READ(reg) & line_mask) != last_line) && | 1024 | } while (((I915_READ(reg) & line_mask) != last_line) && |
| 1025 | time_after(timeout, jiffies)); | 1025 | time_after(timeout, jiffies)); |
| 1026 | if (time_after(jiffies, timeout)) | 1026 | if (time_after(jiffies, timeout)) |
| 1027 | DRM_DEBUG_KMS("pipe_off wait timed out\n"); | 1027 | WARN(1, "pipe_off wait timed out\n"); |
| 1028 | } | 1028 | } |
| 1029 | } | 1029 | } |
| 1030 | 1030 | ||
| @@ -2201,16 +2201,17 @@ intel_finish_fb(struct drm_framebuffer *old_fb) | |||
| 2201 | 2201 | ||
| 2202 | static int | 2202 | static int |
| 2203 | intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | 2203 | intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, |
| 2204 | struct drm_framebuffer *old_fb) | 2204 | struct drm_framebuffer *fb) |
| 2205 | { | 2205 | { |
| 2206 | struct drm_device *dev = crtc->dev; | 2206 | struct drm_device *dev = crtc->dev; |
| 2207 | struct drm_i915_private *dev_priv = dev->dev_private; | 2207 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 2208 | struct drm_i915_master_private *master_priv; | 2208 | struct drm_i915_master_private *master_priv; |
| 2209 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 2209 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 2210 | struct drm_framebuffer *old_fb; | ||
| 2210 | int ret; | 2211 | int ret; |
| 2211 | 2212 | ||
| 2212 | /* no fb bound */ | 2213 | /* no fb bound */ |
| 2213 | if (!crtc->fb) { | 2214 | if (!fb) { |
| 2214 | DRM_ERROR("No FB bound\n"); | 2215 | DRM_ERROR("No FB bound\n"); |
| 2215 | return 0; | 2216 | return 0; |
| 2216 | } | 2217 | } |
| @@ -2224,7 +2225,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
| 2224 | 2225 | ||
| 2225 | mutex_lock(&dev->struct_mutex); | 2226 | mutex_lock(&dev->struct_mutex); |
| 2226 | ret = intel_pin_and_fence_fb_obj(dev, | 2227 | ret = intel_pin_and_fence_fb_obj(dev, |
| 2227 | to_intel_framebuffer(crtc->fb)->obj, | 2228 | to_intel_framebuffer(fb)->obj, |
| 2228 | NULL); | 2229 | NULL); |
| 2229 | if (ret != 0) { | 2230 | if (ret != 0) { |
| 2230 | mutex_unlock(&dev->struct_mutex); | 2231 | mutex_unlock(&dev->struct_mutex); |
| @@ -2232,17 +2233,20 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
| 2232 | return ret; | 2233 | return ret; |
| 2233 | } | 2234 | } |
| 2234 | 2235 | ||
| 2235 | if (old_fb) | 2236 | if (crtc->fb) |
| 2236 | intel_finish_fb(old_fb); | 2237 | intel_finish_fb(crtc->fb); |
| 2237 | 2238 | ||
| 2238 | ret = dev_priv->display.update_plane(crtc, crtc->fb, x, y); | 2239 | ret = dev_priv->display.update_plane(crtc, fb, x, y); |
| 2239 | if (ret) { | 2240 | if (ret) { |
| 2240 | intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj); | 2241 | intel_unpin_fb_obj(to_intel_framebuffer(fb)->obj); |
| 2241 | mutex_unlock(&dev->struct_mutex); | 2242 | mutex_unlock(&dev->struct_mutex); |
| 2242 | DRM_ERROR("failed to update base address\n"); | 2243 | DRM_ERROR("failed to update base address\n"); |
| 2243 | return ret; | 2244 | return ret; |
| 2244 | } | 2245 | } |
| 2245 | 2246 | ||
| 2247 | old_fb = crtc->fb; | ||
| 2248 | crtc->fb = fb; | ||
| 2249 | |||
| 2246 | if (old_fb) { | 2250 | if (old_fb) { |
| 2247 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 2251 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
| 2248 | intel_unpin_fb_obj(to_intel_framebuffer(old_fb)->obj); | 2252 | intel_unpin_fb_obj(to_intel_framebuffer(old_fb)->obj); |
| @@ -3209,11 +3213,14 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) | |||
| 3209 | struct drm_device *dev = crtc->dev; | 3213 | struct drm_device *dev = crtc->dev; |
| 3210 | struct drm_i915_private *dev_priv = dev->dev_private; | 3214 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 3211 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 3215 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 3216 | struct intel_encoder *encoder; | ||
| 3212 | int pipe = intel_crtc->pipe; | 3217 | int pipe = intel_crtc->pipe; |
| 3213 | int plane = intel_crtc->plane; | 3218 | int plane = intel_crtc->plane; |
| 3214 | u32 temp; | 3219 | u32 temp; |
| 3215 | bool is_pch_port; | 3220 | bool is_pch_port; |
| 3216 | 3221 | ||
| 3222 | WARN_ON(!crtc->enabled); | ||
| 3223 | |||
| 3217 | if (intel_crtc->active) | 3224 | if (intel_crtc->active) |
| 3218 | return; | 3225 | return; |
| 3219 | 3226 | ||
| @@ -3262,6 +3269,12 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) | |||
| 3262 | mutex_unlock(&dev->struct_mutex); | 3269 | mutex_unlock(&dev->struct_mutex); |
| 3263 | 3270 | ||
| 3264 | intel_crtc_update_cursor(crtc, true); | 3271 | intel_crtc_update_cursor(crtc, true); |
| 3272 | |||
| 3273 | for_each_encoder_on_crtc(dev, crtc, encoder) | ||
| 3274 | encoder->enable(encoder); | ||
| 3275 | |||
| 3276 | if (HAS_PCH_CPT(dev)) | ||
| 3277 | intel_cpt_verify_modeset(dev, intel_crtc->pipe); | ||
| 3265 | } | 3278 | } |
| 3266 | 3279 | ||
| 3267 | static void ironlake_crtc_disable(struct drm_crtc *crtc) | 3280 | static void ironlake_crtc_disable(struct drm_crtc *crtc) |
| @@ -3269,13 +3282,18 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) | |||
| 3269 | struct drm_device *dev = crtc->dev; | 3282 | struct drm_device *dev = crtc->dev; |
| 3270 | struct drm_i915_private *dev_priv = dev->dev_private; | 3283 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 3271 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 3284 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 3285 | struct intel_encoder *encoder; | ||
| 3272 | int pipe = intel_crtc->pipe; | 3286 | int pipe = intel_crtc->pipe; |
| 3273 | int plane = intel_crtc->plane; | 3287 | int plane = intel_crtc->plane; |
| 3274 | u32 reg, temp; | 3288 | u32 reg, temp; |
| 3275 | 3289 | ||
| 3290 | |||
| 3276 | if (!intel_crtc->active) | 3291 | if (!intel_crtc->active) |
| 3277 | return; | 3292 | return; |
| 3278 | 3293 | ||
| 3294 | for_each_encoder_on_crtc(dev, crtc, encoder) | ||
| 3295 | encoder->disable(encoder); | ||
| 3296 | |||
| 3279 | intel_crtc_wait_for_pending_flips(crtc); | 3297 | intel_crtc_wait_for_pending_flips(crtc); |
| 3280 | drm_vblank_off(dev, pipe); | 3298 | drm_vblank_off(dev, pipe); |
| 3281 | intel_crtc_update_cursor(crtc, false); | 3299 | intel_crtc_update_cursor(crtc, false); |
| @@ -3342,30 +3360,6 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) | |||
| 3342 | mutex_unlock(&dev->struct_mutex); | 3360 | mutex_unlock(&dev->struct_mutex); |
| 3343 | } | 3361 | } |
| 3344 | 3362 | ||
| 3345 | static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | ||
| 3346 | { | ||
| 3347 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
| 3348 | int pipe = intel_crtc->pipe; | ||
| 3349 | int plane = intel_crtc->plane; | ||
| 3350 | |||
| 3351 | /* XXX: When our outputs are all unaware of DPMS modes other than off | ||
| 3352 | * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. | ||
| 3353 | */ | ||
| 3354 | switch (mode) { | ||
| 3355 | case DRM_MODE_DPMS_ON: | ||
| 3356 | case DRM_MODE_DPMS_STANDBY: | ||
| 3357 | case DRM_MODE_DPMS_SUSPEND: | ||
| 3358 | DRM_DEBUG_KMS("crtc %d/%d dpms on\n", pipe, plane); | ||
| 3359 | ironlake_crtc_enable(crtc); | ||
| 3360 | break; | ||
| 3361 | |||
| 3362 | case DRM_MODE_DPMS_OFF: | ||
| 3363 | DRM_DEBUG_KMS("crtc %d/%d dpms off\n", pipe, plane); | ||
| 3364 | ironlake_crtc_disable(crtc); | ||
| 3365 | break; | ||
| 3366 | } | ||
| 3367 | } | ||
| 3368 | |||
| 3369 | static void ironlake_crtc_off(struct drm_crtc *crtc) | 3363 | static void ironlake_crtc_off(struct drm_crtc *crtc) |
| 3370 | { | 3364 | { |
| 3371 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 3365 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| @@ -3395,9 +3389,12 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) | |||
| 3395 | struct drm_device *dev = crtc->dev; | 3389 | struct drm_device *dev = crtc->dev; |
| 3396 | struct drm_i915_private *dev_priv = dev->dev_private; | 3390 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 3397 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 3391 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 3392 | struct intel_encoder *encoder; | ||
| 3398 | int pipe = intel_crtc->pipe; | 3393 | int pipe = intel_crtc->pipe; |
| 3399 | int plane = intel_crtc->plane; | 3394 | int plane = intel_crtc->plane; |
| 3400 | 3395 | ||
| 3396 | WARN_ON(!crtc->enabled); | ||
| 3397 | |||
| 3401 | if (intel_crtc->active) | 3398 | if (intel_crtc->active) |
| 3402 | return; | 3399 | return; |
| 3403 | 3400 | ||
| @@ -3414,6 +3411,9 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) | |||
| 3414 | /* Give the overlay scaler a chance to enable if it's on this pipe */ | 3411 | /* Give the overlay scaler a chance to enable if it's on this pipe */ |
| 3415 | intel_crtc_dpms_overlay(intel_crtc, true); | 3412 | intel_crtc_dpms_overlay(intel_crtc, true); |
| 3416 | intel_crtc_update_cursor(crtc, true); | 3413 | intel_crtc_update_cursor(crtc, true); |
| 3414 | |||
| 3415 | for_each_encoder_on_crtc(dev, crtc, encoder) | ||
| 3416 | encoder->enable(encoder); | ||
| 3417 | } | 3417 | } |
| 3418 | 3418 | ||
| 3419 | static void i9xx_crtc_disable(struct drm_crtc *crtc) | 3419 | static void i9xx_crtc_disable(struct drm_crtc *crtc) |
| @@ -3421,12 +3421,17 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) | |||
| 3421 | struct drm_device *dev = crtc->dev; | 3421 | struct drm_device *dev = crtc->dev; |
| 3422 | struct drm_i915_private *dev_priv = dev->dev_private; | 3422 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 3423 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 3423 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 3424 | struct intel_encoder *encoder; | ||
| 3424 | int pipe = intel_crtc->pipe; | 3425 | int pipe = intel_crtc->pipe; |
| 3425 | int plane = intel_crtc->plane; | 3426 | int plane = intel_crtc->plane; |
| 3426 | 3427 | ||
| 3428 | |||
| 3427 | if (!intel_crtc->active) | 3429 | if (!intel_crtc->active) |
| 3428 | return; | 3430 | return; |
| 3429 | 3431 | ||
| 3432 | for_each_encoder_on_crtc(dev, crtc, encoder) | ||
| 3433 | encoder->disable(encoder); | ||
| 3434 | |||
| 3430 | /* Give the overlay scaler a chance to disable if it's on this pipe */ | 3435 | /* Give the overlay scaler a chance to disable if it's on this pipe */ |
| 3431 | intel_crtc_wait_for_pending_flips(crtc); | 3436 | intel_crtc_wait_for_pending_flips(crtc); |
| 3432 | drm_vblank_off(dev, pipe); | 3437 | drm_vblank_off(dev, pipe); |
| @@ -3445,45 +3450,17 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) | |||
| 3445 | intel_update_watermarks(dev); | 3450 | intel_update_watermarks(dev); |
| 3446 | } | 3451 | } |
| 3447 | 3452 | ||
| 3448 | static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | ||
| 3449 | { | ||
| 3450 | /* XXX: When our outputs are all unaware of DPMS modes other than off | ||
| 3451 | * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. | ||
| 3452 | */ | ||
| 3453 | switch (mode) { | ||
| 3454 | case DRM_MODE_DPMS_ON: | ||
| 3455 | case DRM_MODE_DPMS_STANDBY: | ||
| 3456 | case DRM_MODE_DPMS_SUSPEND: | ||
| 3457 | i9xx_crtc_enable(crtc); | ||
| 3458 | break; | ||
| 3459 | case DRM_MODE_DPMS_OFF: | ||
| 3460 | i9xx_crtc_disable(crtc); | ||
| 3461 | break; | ||
| 3462 | } | ||
| 3463 | } | ||
| 3464 | |||
| 3465 | static void i9xx_crtc_off(struct drm_crtc *crtc) | 3453 | static void i9xx_crtc_off(struct drm_crtc *crtc) |
| 3466 | { | 3454 | { |
| 3467 | } | 3455 | } |
| 3468 | 3456 | ||
| 3469 | /** | 3457 | static void intel_crtc_update_sarea(struct drm_crtc *crtc, |
| 3470 | * Sets the power management mode of the pipe and plane. | 3458 | bool enabled) |
| 3471 | */ | ||
| 3472 | static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) | ||
| 3473 | { | 3459 | { |
| 3474 | struct drm_device *dev = crtc->dev; | 3460 | struct drm_device *dev = crtc->dev; |
| 3475 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 3476 | struct drm_i915_master_private *master_priv; | 3461 | struct drm_i915_master_private *master_priv; |
| 3477 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 3462 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 3478 | int pipe = intel_crtc->pipe; | 3463 | int pipe = intel_crtc->pipe; |
| 3479 | bool enabled; | ||
| 3480 | |||
| 3481 | if (intel_crtc->dpms_mode == mode) | ||
| 3482 | return; | ||
| 3483 | |||
| 3484 | intel_crtc->dpms_mode = mode; | ||
| 3485 | |||
| 3486 | dev_priv->display.dpms(crtc, mode); | ||
| 3487 | 3464 | ||
| 3488 | if (!dev->primary->master) | 3465 | if (!dev->primary->master) |
| 3489 | return; | 3466 | return; |
| @@ -3492,8 +3469,6 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 3492 | if (!master_priv->sarea_priv) | 3469 | if (!master_priv->sarea_priv) |
| 3493 | return; | 3470 | return; |
| 3494 | 3471 | ||
| 3495 | enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF; | ||
| 3496 | |||
| 3497 | switch (pipe) { | 3472 | switch (pipe) { |
| 3498 | case 0: | 3473 | case 0: |
| 3499 | master_priv->sarea_priv->pipeA_w = enabled ? crtc->mode.hdisplay : 0; | 3474 | master_priv->sarea_priv->pipeA_w = enabled ? crtc->mode.hdisplay : 0; |
| @@ -3509,13 +3484,42 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 3509 | } | 3484 | } |
| 3510 | } | 3485 | } |
| 3511 | 3486 | ||
| 3487 | /** | ||
| 3488 | * Sets the power management mode of the pipe and plane. | ||
| 3489 | */ | ||
| 3490 | void intel_crtc_update_dpms(struct drm_crtc *crtc) | ||
| 3491 | { | ||
| 3492 | struct drm_device *dev = crtc->dev; | ||
| 3493 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 3494 | struct intel_encoder *intel_encoder; | ||
| 3495 | bool enable = false; | ||
| 3496 | |||
| 3497 | for_each_encoder_on_crtc(dev, crtc, intel_encoder) | ||
| 3498 | enable |= intel_encoder->connectors_active; | ||
| 3499 | |||
| 3500 | if (enable) | ||
| 3501 | dev_priv->display.crtc_enable(crtc); | ||
| 3502 | else | ||
| 3503 | dev_priv->display.crtc_disable(crtc); | ||
| 3504 | |||
| 3505 | intel_crtc_update_sarea(crtc, enable); | ||
| 3506 | } | ||
| 3507 | |||
| 3508 | static void intel_crtc_noop(struct drm_crtc *crtc) | ||
| 3509 | { | ||
| 3510 | } | ||
| 3511 | |||
| 3512 | static void intel_crtc_disable(struct drm_crtc *crtc) | 3512 | static void intel_crtc_disable(struct drm_crtc *crtc) |
| 3513 | { | 3513 | { |
| 3514 | struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; | ||
| 3515 | struct drm_device *dev = crtc->dev; | 3514 | struct drm_device *dev = crtc->dev; |
| 3515 | struct drm_connector *connector; | ||
| 3516 | struct drm_i915_private *dev_priv = dev->dev_private; | 3516 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 3517 | 3517 | ||
| 3518 | crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); | 3518 | /* crtc should still be enabled when we disable it. */ |
| 3519 | WARN_ON(!crtc->enabled); | ||
| 3520 | |||
| 3521 | dev_priv->display.crtc_disable(crtc); | ||
| 3522 | intel_crtc_update_sarea(crtc, false); | ||
| 3519 | dev_priv->display.off(crtc); | 3523 | dev_priv->display.off(crtc); |
| 3520 | 3524 | ||
| 3521 | assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane); | 3525 | assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane); |
| @@ -3525,63 +3529,128 @@ static void intel_crtc_disable(struct drm_crtc *crtc) | |||
| 3525 | mutex_lock(&dev->struct_mutex); | 3529 | mutex_lock(&dev->struct_mutex); |
| 3526 | intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj); | 3530 | intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj); |
| 3527 | mutex_unlock(&dev->struct_mutex); | 3531 | mutex_unlock(&dev->struct_mutex); |
| 3532 | crtc->fb = NULL; | ||
| 3533 | } | ||
| 3534 | |||
| 3535 | /* Update computed state. */ | ||
| 3536 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
| 3537 | if (!connector->encoder || !connector->encoder->crtc) | ||
| 3538 | continue; | ||
| 3539 | |||
| 3540 | if (connector->encoder->crtc != crtc) | ||
| 3541 | continue; | ||
| 3542 | |||
| 3543 | connector->dpms = DRM_MODE_DPMS_OFF; | ||
| 3544 | to_intel_encoder(connector->encoder)->connectors_active = false; | ||
| 3528 | } | 3545 | } |
| 3529 | } | 3546 | } |
| 3530 | 3547 | ||
| 3531 | /* Prepare for a mode set. | 3548 | void intel_modeset_disable(struct drm_device *dev) |
| 3532 | * | ||
| 3533 | * Note we could be a lot smarter here. We need to figure out which outputs | ||
| 3534 | * will be enabled, which disabled (in short, how the config will changes) | ||
| 3535 | * and perform the minimum necessary steps to accomplish that, e.g. updating | ||
| 3536 | * watermarks, FBC configuration, making sure PLLs are programmed correctly, | ||
| 3537 | * panel fitting is in the proper state, etc. | ||
| 3538 | */ | ||
| 3539 | static void i9xx_crtc_prepare(struct drm_crtc *crtc) | ||
| 3540 | { | 3549 | { |
| 3541 | i9xx_crtc_disable(crtc); | 3550 | struct drm_crtc *crtc; |
| 3551 | |||
| 3552 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | ||
| 3553 | if (crtc->enabled) | ||
| 3554 | intel_crtc_disable(crtc); | ||
| 3555 | } | ||
| 3542 | } | 3556 | } |
| 3543 | 3557 | ||
| 3544 | static void i9xx_crtc_commit(struct drm_crtc *crtc) | 3558 | void intel_encoder_noop(struct drm_encoder *encoder) |
| 3545 | { | 3559 | { |
| 3546 | i9xx_crtc_enable(crtc); | ||
| 3547 | } | 3560 | } |
| 3548 | 3561 | ||
| 3549 | static void ironlake_crtc_prepare(struct drm_crtc *crtc) | 3562 | void intel_encoder_destroy(struct drm_encoder *encoder) |
| 3550 | { | 3563 | { |
| 3551 | ironlake_crtc_disable(crtc); | 3564 | struct intel_encoder *intel_encoder = to_intel_encoder(encoder); |
| 3565 | |||
| 3566 | drm_encoder_cleanup(encoder); | ||
| 3567 | kfree(intel_encoder); | ||
| 3552 | } | 3568 | } |
| 3553 | 3569 | ||
| 3554 | static void ironlake_crtc_commit(struct drm_crtc *crtc) | 3570 | /* Simple dpms helper for encodres with just one connector, no cloning and only |
| 3571 | * one kind of off state. It clamps all !ON modes to fully OFF and changes the | ||
| 3572 | * state of the entire output pipe. */ | ||
| 3573 | void intel_encoder_dpms(struct intel_encoder *encoder, int mode) | ||
| 3555 | { | 3574 | { |
| 3556 | ironlake_crtc_enable(crtc); | 3575 | if (mode == DRM_MODE_DPMS_ON) { |
| 3576 | encoder->connectors_active = true; | ||
| 3577 | |||
| 3578 | intel_crtc_update_dpms(encoder->base.crtc); | ||
| 3579 | } else { | ||
| 3580 | encoder->connectors_active = false; | ||
| 3581 | |||
| 3582 | intel_crtc_update_dpms(encoder->base.crtc); | ||
| 3583 | } | ||
| 3557 | } | 3584 | } |
| 3558 | 3585 | ||
| 3559 | void intel_encoder_prepare(struct drm_encoder *encoder) | 3586 | /* Cross check the actual hw state with our own modeset state tracking (and it's |
| 3587 | * internal consistency). */ | ||
| 3588 | static void intel_connector_check_state(struct intel_connector *connector) | ||
| 3560 | { | 3589 | { |
| 3561 | struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; | 3590 | if (connector->get_hw_state(connector)) { |
| 3562 | /* lvds has its own version of prepare see intel_lvds_prepare */ | 3591 | struct intel_encoder *encoder = connector->encoder; |
| 3563 | encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF); | 3592 | struct drm_crtc *crtc; |
| 3593 | bool encoder_enabled; | ||
| 3594 | enum pipe pipe; | ||
| 3595 | |||
| 3596 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", | ||
| 3597 | connector->base.base.id, | ||
| 3598 | drm_get_connector_name(&connector->base)); | ||
| 3599 | |||
| 3600 | WARN(connector->base.dpms == DRM_MODE_DPMS_OFF, | ||
| 3601 | "wrong connector dpms state\n"); | ||
| 3602 | WARN(connector->base.encoder != &encoder->base, | ||
| 3603 | "active connector not linked to encoder\n"); | ||
| 3604 | WARN(!encoder->connectors_active, | ||
| 3605 | "encoder->connectors_active not set\n"); | ||
| 3606 | |||
| 3607 | encoder_enabled = encoder->get_hw_state(encoder, &pipe); | ||
| 3608 | WARN(!encoder_enabled, "encoder not enabled\n"); | ||
| 3609 | if (WARN_ON(!encoder->base.crtc)) | ||
| 3610 | return; | ||
| 3611 | |||
| 3612 | crtc = encoder->base.crtc; | ||
| 3613 | |||
| 3614 | WARN(!crtc->enabled, "crtc not enabled\n"); | ||
| 3615 | WARN(!to_intel_crtc(crtc)->active, "crtc not active\n"); | ||
| 3616 | WARN(pipe != to_intel_crtc(crtc)->pipe, | ||
| 3617 | "encoder active on the wrong pipe\n"); | ||
| 3618 | } | ||
| 3564 | } | 3619 | } |
| 3565 | 3620 | ||
| 3566 | void intel_encoder_commit(struct drm_encoder *encoder) | 3621 | /* Even simpler default implementation, if there's really no special case to |
| 3622 | * consider. */ | ||
| 3623 | void intel_connector_dpms(struct drm_connector *connector, int mode) | ||
| 3567 | { | 3624 | { |
| 3568 | struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; | 3625 | struct intel_encoder *encoder = intel_attached_encoder(connector); |
| 3569 | struct drm_device *dev = encoder->dev; | ||
| 3570 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | ||
| 3571 | 3626 | ||
| 3572 | /* lvds has its own version of commit see intel_lvds_commit */ | 3627 | /* All the simple cases only support two dpms states. */ |
| 3573 | encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); | 3628 | if (mode != DRM_MODE_DPMS_ON) |
| 3629 | mode = DRM_MODE_DPMS_OFF; | ||
| 3574 | 3630 | ||
| 3575 | if (HAS_PCH_CPT(dev)) | 3631 | if (mode == connector->dpms) |
| 3576 | intel_cpt_verify_modeset(dev, intel_crtc->pipe); | 3632 | return; |
| 3633 | |||
| 3634 | connector->dpms = mode; | ||
| 3635 | |||
| 3636 | /* Only need to change hw state when actually enabled */ | ||
| 3637 | if (encoder->base.crtc) | ||
| 3638 | intel_encoder_dpms(encoder, mode); | ||
| 3639 | else | ||
| 3640 | WARN_ON(encoder->connectors_active != false); | ||
| 3641 | |||
| 3642 | intel_modeset_check_state(connector->dev); | ||
| 3577 | } | 3643 | } |
| 3578 | 3644 | ||
| 3579 | void intel_encoder_destroy(struct drm_encoder *encoder) | 3645 | /* Simple connector->get_hw_state implementation for encoders that support only |
| 3646 | * one connector and no cloning and hence the encoder state determines the state | ||
| 3647 | * of the connector. */ | ||
| 3648 | bool intel_connector_get_hw_state(struct intel_connector *connector) | ||
| 3580 | { | 3649 | { |
| 3581 | struct intel_encoder *intel_encoder = to_intel_encoder(encoder); | 3650 | enum pipe pipe = 0; |
| 3651 | struct intel_encoder *encoder = connector->encoder; | ||
| 3582 | 3652 | ||
| 3583 | drm_encoder_cleanup(encoder); | 3653 | return encoder->get_hw_state(encoder, &pipe); |
| 3584 | kfree(intel_encoder); | ||
| 3585 | } | 3654 | } |
| 3586 | 3655 | ||
| 3587 | static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, | 3656 | static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, |
| @@ -3744,6 +3813,7 @@ static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) | |||
| 3744 | * true if they don't match). | 3813 | * true if they don't match). |
| 3745 | */ | 3814 | */ |
| 3746 | static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, | 3815 | static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, |
| 3816 | struct drm_framebuffer *fb, | ||
| 3747 | unsigned int *pipe_bpp, | 3817 | unsigned int *pipe_bpp, |
| 3748 | struct drm_display_mode *mode) | 3818 | struct drm_display_mode *mode) |
| 3749 | { | 3819 | { |
| @@ -3813,7 +3883,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, | |||
| 3813 | * also stays within the max display bpc discovered above. | 3883 | * also stays within the max display bpc discovered above. |
| 3814 | */ | 3884 | */ |
| 3815 | 3885 | ||
| 3816 | switch (crtc->fb->depth) { | 3886 | switch (fb->depth) { |
| 3817 | case 8: | 3887 | case 8: |
| 3818 | bpc = 8; /* since we go through a colormap */ | 3888 | bpc = 8; /* since we go through a colormap */ |
| 3819 | break; | 3889 | break; |
| @@ -4232,7 +4302,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, | |||
| 4232 | struct drm_display_mode *mode, | 4302 | struct drm_display_mode *mode, |
| 4233 | struct drm_display_mode *adjusted_mode, | 4303 | struct drm_display_mode *adjusted_mode, |
| 4234 | int x, int y, | 4304 | int x, int y, |
| 4235 | struct drm_framebuffer *old_fb) | 4305 | struct drm_framebuffer *fb) |
| 4236 | { | 4306 | { |
| 4237 | struct drm_device *dev = crtc->dev; | 4307 | struct drm_device *dev = crtc->dev; |
| 4238 | struct drm_i915_private *dev_priv = dev->dev_private; | 4308 | struct drm_i915_private *dev_priv = dev->dev_private; |
| @@ -4422,7 +4492,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, | |||
| 4422 | I915_WRITE(DSPCNTR(plane), dspcntr); | 4492 | I915_WRITE(DSPCNTR(plane), dspcntr); |
| 4423 | POSTING_READ(DSPCNTR(plane)); | 4493 | POSTING_READ(DSPCNTR(plane)); |
| 4424 | 4494 | ||
| 4425 | ret = intel_pipe_set_base(crtc, x, y, old_fb); | 4495 | ret = intel_pipe_set_base(crtc, x, y, fb); |
| 4426 | 4496 | ||
| 4427 | intel_update_watermarks(dev); | 4497 | intel_update_watermarks(dev); |
| 4428 | 4498 | ||
| @@ -4580,7 +4650,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
| 4580 | struct drm_display_mode *mode, | 4650 | struct drm_display_mode *mode, |
| 4581 | struct drm_display_mode *adjusted_mode, | 4651 | struct drm_display_mode *adjusted_mode, |
| 4582 | int x, int y, | 4652 | int x, int y, |
| 4583 | struct drm_framebuffer *old_fb) | 4653 | struct drm_framebuffer *fb) |
| 4584 | { | 4654 | { |
| 4585 | struct drm_device *dev = crtc->dev; | 4655 | struct drm_device *dev = crtc->dev; |
| 4586 | struct drm_i915_private *dev_priv = dev->dev_private; | 4656 | struct drm_i915_private *dev_priv = dev->dev_private; |
| @@ -4700,7 +4770,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
| 4700 | /* determine panel color depth */ | 4770 | /* determine panel color depth */ |
| 4701 | temp = I915_READ(PIPECONF(pipe)); | 4771 | temp = I915_READ(PIPECONF(pipe)); |
| 4702 | temp &= ~PIPE_BPC_MASK; | 4772 | temp &= ~PIPE_BPC_MASK; |
| 4703 | dither = intel_choose_pipe_bpp_dither(crtc, &pipe_bpp, mode); | 4773 | dither = intel_choose_pipe_bpp_dither(crtc, fb, &pipe_bpp, mode); |
| 4704 | switch (pipe_bpp) { | 4774 | switch (pipe_bpp) { |
| 4705 | case 18: | 4775 | case 18: |
| 4706 | temp |= PIPE_6BPC; | 4776 | temp |= PIPE_6BPC; |
| @@ -4969,7 +5039,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
| 4969 | I915_WRITE(DSPCNTR(plane), dspcntr); | 5039 | I915_WRITE(DSPCNTR(plane), dspcntr); |
| 4970 | POSTING_READ(DSPCNTR(plane)); | 5040 | POSTING_READ(DSPCNTR(plane)); |
| 4971 | 5041 | ||
| 4972 | ret = intel_pipe_set_base(crtc, x, y, old_fb); | 5042 | ret = intel_pipe_set_base(crtc, x, y, fb); |
| 4973 | 5043 | ||
| 4974 | intel_update_watermarks(dev); | 5044 | intel_update_watermarks(dev); |
| 4975 | 5045 | ||
| @@ -4982,7 +5052,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
| 4982 | struct drm_display_mode *mode, | 5052 | struct drm_display_mode *mode, |
| 4983 | struct drm_display_mode *adjusted_mode, | 5053 | struct drm_display_mode *adjusted_mode, |
| 4984 | int x, int y, | 5054 | int x, int y, |
| 4985 | struct drm_framebuffer *old_fb) | 5055 | struct drm_framebuffer *fb) |
| 4986 | { | 5056 | { |
| 4987 | struct drm_device *dev = crtc->dev; | 5057 | struct drm_device *dev = crtc->dev; |
| 4988 | struct drm_i915_private *dev_priv = dev->dev_private; | 5058 | struct drm_i915_private *dev_priv = dev->dev_private; |
| @@ -4993,14 +5063,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
| 4993 | drm_vblank_pre_modeset(dev, pipe); | 5063 | drm_vblank_pre_modeset(dev, pipe); |
| 4994 | 5064 | ||
| 4995 | ret = dev_priv->display.crtc_mode_set(crtc, mode, adjusted_mode, | 5065 | ret = dev_priv->display.crtc_mode_set(crtc, mode, adjusted_mode, |
| 4996 | x, y, old_fb); | 5066 | x, y, fb); |
| 4997 | drm_vblank_post_modeset(dev, pipe); | 5067 | drm_vblank_post_modeset(dev, pipe); |
| 4998 | 5068 | ||
| 4999 | if (ret) | ||
| 5000 | intel_crtc->dpms_mode = DRM_MODE_DPMS_OFF; | ||
| 5001 | else | ||
| 5002 | intel_crtc->dpms_mode = DRM_MODE_DPMS_ON; | ||
| 5003 | |||
| 5004 | return ret; | 5069 | return ret; |
| 5005 | } | 5070 | } |
| 5006 | 5071 | ||
| @@ -5434,8 +5499,6 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
| 5434 | uint32_t addr; | 5499 | uint32_t addr; |
| 5435 | int ret; | 5500 | int ret; |
| 5436 | 5501 | ||
| 5437 | DRM_DEBUG_KMS("\n"); | ||
| 5438 | |||
| 5439 | /* if we want to turn off the cursor ignore width and height */ | 5502 | /* if we want to turn off the cursor ignore width and height */ |
| 5440 | if (!handle) { | 5503 | if (!handle) { |
| 5441 | DRM_DEBUG_KMS("cursor off\n"); | 5504 | DRM_DEBUG_KMS("cursor off\n"); |
| @@ -5692,7 +5755,7 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector, | |||
| 5692 | struct drm_encoder *encoder = &intel_encoder->base; | 5755 | struct drm_encoder *encoder = &intel_encoder->base; |
| 5693 | struct drm_crtc *crtc = NULL; | 5756 | struct drm_crtc *crtc = NULL; |
| 5694 | struct drm_device *dev = encoder->dev; | 5757 | struct drm_device *dev = encoder->dev; |
| 5695 | struct drm_framebuffer *old_fb; | 5758 | struct drm_framebuffer *fb; |
| 5696 | int i = -1; | 5759 | int i = -1; |
| 5697 | 5760 | ||
| 5698 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n", | 5761 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n", |
| @@ -5742,8 +5805,8 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector, | |||
| 5742 | return false; | 5805 | return false; |
| 5743 | } | 5806 | } |
| 5744 | 5807 | ||
| 5745 | encoder->crtc = crtc; | 5808 | intel_encoder->new_crtc = to_intel_crtc(crtc); |
| 5746 | connector->encoder = encoder; | 5809 | to_intel_connector(connector)->new_encoder = intel_encoder; |
| 5747 | 5810 | ||
| 5748 | intel_crtc = to_intel_crtc(crtc); | 5811 | intel_crtc = to_intel_crtc(crtc); |
| 5749 | old->dpms_mode = connector->dpms; | 5812 | old->dpms_mode = connector->dpms; |
| @@ -5753,8 +5816,6 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector, | |||
| 5753 | if (!mode) | 5816 | if (!mode) |
| 5754 | mode = &load_detect_mode; | 5817 | mode = &load_detect_mode; |
| 5755 | 5818 | ||
| 5756 | old_fb = crtc->fb; | ||
| 5757 | |||
| 5758 | /* We need a framebuffer large enough to accommodate all accesses | 5819 | /* We need a framebuffer large enough to accommodate all accesses |
| 5759 | * that the plane may generate whilst we perform load detection. | 5820 | * that the plane may generate whilst we perform load detection. |
| 5760 | * We can not rely on the fbcon either being present (we get called | 5821 | * We can not rely on the fbcon either being present (we get called |
| @@ -5762,19 +5823,19 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector, | |||
| 5762 | * not even exist) or that it is large enough to satisfy the | 5823 | * not even exist) or that it is large enough to satisfy the |
| 5763 | * requested mode. | 5824 | * requested mode. |
| 5764 | */ | 5825 | */ |
| 5765 | crtc->fb = mode_fits_in_fbdev(dev, mode); | 5826 | fb = mode_fits_in_fbdev(dev, mode); |
| 5766 | if (crtc->fb == NULL) { | 5827 | if (fb == NULL) { |
| 5767 | DRM_DEBUG_KMS("creating tmp fb for load-detection\n"); | 5828 | DRM_DEBUG_KMS("creating tmp fb for load-detection\n"); |
| 5768 | crtc->fb = intel_framebuffer_create_for_mode(dev, mode, 24, 32); | 5829 | fb = intel_framebuffer_create_for_mode(dev, mode, 24, 32); |
| 5769 | old->release_fb = crtc->fb; | 5830 | old->release_fb = fb; |
| 5770 | } else | 5831 | } else |
| 5771 | DRM_DEBUG_KMS("reusing fbdev for load-detection framebuffer\n"); | 5832 | DRM_DEBUG_KMS("reusing fbdev for load-detection framebuffer\n"); |
| 5772 | if (IS_ERR(crtc->fb)) { | 5833 | if (IS_ERR(fb)) { |
| 5773 | DRM_DEBUG_KMS("failed to allocate framebuffer for load-detection\n"); | 5834 | DRM_DEBUG_KMS("failed to allocate framebuffer for load-detection\n"); |
| 5774 | goto fail; | 5835 | goto fail; |
| 5775 | } | 5836 | } |
| 5776 | 5837 | ||
| 5777 | if (!drm_crtc_helper_set_mode(crtc, mode, 0, 0, old_fb)) { | 5838 | if (!intel_set_mode(crtc, mode, 0, 0, fb)) { |
| 5778 | DRM_DEBUG_KMS("failed to set mode on load-detect pipe\n"); | 5839 | DRM_DEBUG_KMS("failed to set mode on load-detect pipe\n"); |
| 5779 | if (old->release_fb) | 5840 | if (old->release_fb) |
| 5780 | old->release_fb->funcs->destroy(old->release_fb); | 5841 | old->release_fb->funcs->destroy(old->release_fb); |
| @@ -5788,7 +5849,6 @@ bool intel_get_load_detect_pipe(struct drm_connector *connector, | |||
| 5788 | fail: | 5849 | fail: |
| 5789 | connector->encoder = NULL; | 5850 | connector->encoder = NULL; |
| 5790 | encoder->crtc = NULL; | 5851 | encoder->crtc = NULL; |
| 5791 | crtc->fb = old_fb; | ||
| 5792 | return false; | 5852 | return false; |
| 5793 | } | 5853 | } |
| 5794 | 5854 | ||
| @@ -5798,16 +5858,17 @@ void intel_release_load_detect_pipe(struct drm_connector *connector, | |||
| 5798 | struct intel_encoder *intel_encoder = | 5858 | struct intel_encoder *intel_encoder = |
| 5799 | intel_attached_encoder(connector); | 5859 | intel_attached_encoder(connector); |
| 5800 | struct drm_encoder *encoder = &intel_encoder->base; | 5860 | struct drm_encoder *encoder = &intel_encoder->base; |
| 5801 | struct drm_device *dev = encoder->dev; | ||
| 5802 | 5861 | ||
| 5803 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n", | 5862 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n", |
| 5804 | connector->base.id, drm_get_connector_name(connector), | 5863 | connector->base.id, drm_get_connector_name(connector), |
| 5805 | encoder->base.id, drm_get_encoder_name(encoder)); | 5864 | encoder->base.id, drm_get_encoder_name(encoder)); |
| 5806 | 5865 | ||
| 5807 | if (old->load_detect_temp) { | 5866 | if (old->load_detect_temp) { |
| 5808 | connector->encoder = NULL; | 5867 | struct drm_crtc *crtc = encoder->crtc; |
| 5809 | encoder->crtc = NULL; | 5868 | |
| 5810 | drm_helper_disable_unused_functions(dev); | 5869 | to_intel_connector(connector)->new_encoder = NULL; |
| 5870 | intel_encoder->new_crtc = NULL; | ||
| 5871 | intel_set_mode(crtc, NULL, 0, 0, NULL); | ||
| 5811 | 5872 | ||
| 5812 | if (old->release_fb) | 5873 | if (old->release_fb) |
| 5813 | old->release_fb->funcs->destroy(old->release_fb); | 5874 | old->release_fb->funcs->destroy(old->release_fb); |
| @@ -6529,81 +6590,811 @@ free_work: | |||
| 6529 | return ret; | 6590 | return ret; |
| 6530 | } | 6591 | } |
| 6531 | 6592 | ||
| 6532 | static void intel_sanitize_modesetting(struct drm_device *dev, | 6593 | static struct drm_crtc_helper_funcs intel_helper_funcs = { |
| 6533 | int pipe, int plane) | 6594 | .mode_set_base_atomic = intel_pipe_set_base_atomic, |
| 6595 | .load_lut = intel_crtc_load_lut, | ||
| 6596 | .disable = intel_crtc_noop, | ||
| 6597 | }; | ||
| 6598 | |||
| 6599 | bool intel_encoder_check_is_cloned(struct intel_encoder *encoder) | ||
| 6534 | { | 6600 | { |
| 6535 | struct drm_i915_private *dev_priv = dev->dev_private; | 6601 | struct intel_encoder *other_encoder; |
| 6536 | u32 reg, val; | 6602 | struct drm_crtc *crtc = &encoder->new_crtc->base; |
| 6537 | int i; | ||
| 6538 | 6603 | ||
| 6539 | /* Clear any frame start delays used for debugging left by the BIOS */ | 6604 | if (WARN_ON(!crtc)) |
| 6540 | for_each_pipe(i) { | 6605 | return false; |
| 6541 | reg = PIPECONF(i); | 6606 | |
| 6542 | I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK); | 6607 | list_for_each_entry(other_encoder, |
| 6608 | &crtc->dev->mode_config.encoder_list, | ||
| 6609 | base.head) { | ||
| 6610 | |||
| 6611 | if (&other_encoder->new_crtc->base != crtc || | ||
| 6612 | encoder == other_encoder) | ||
| 6613 | continue; | ||
| 6614 | else | ||
| 6615 | return true; | ||
| 6543 | } | 6616 | } |
| 6544 | 6617 | ||
| 6545 | if (HAS_PCH_SPLIT(dev)) | 6618 | return false; |
| 6546 | return; | 6619 | } |
| 6547 | 6620 | ||
| 6548 | /* Who knows what state these registers were left in by the BIOS or | 6621 | static bool intel_encoder_crtc_ok(struct drm_encoder *encoder, |
| 6549 | * grub? | 6622 | struct drm_crtc *crtc) |
| 6550 | * | 6623 | { |
| 6551 | * If we leave the registers in a conflicting state (e.g. with the | 6624 | struct drm_device *dev; |
| 6552 | * display plane reading from the other pipe than the one we intend | 6625 | struct drm_crtc *tmp; |
| 6553 | * to use) then when we attempt to teardown the active mode, we will | 6626 | int crtc_mask = 1; |
| 6554 | * not disable the pipes and planes in the correct order -- leaving | 6627 | |
| 6555 | * a plane reading from a disabled pipe and possibly leading to | 6628 | WARN(!crtc, "checking null crtc?\n"); |
| 6556 | * undefined behaviour. | 6629 | |
| 6630 | dev = crtc->dev; | ||
| 6631 | |||
| 6632 | list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) { | ||
| 6633 | if (tmp == crtc) | ||
| 6634 | break; | ||
| 6635 | crtc_mask <<= 1; | ||
| 6636 | } | ||
| 6637 | |||
| 6638 | if (encoder->possible_crtcs & crtc_mask) | ||
| 6639 | return true; | ||
| 6640 | return false; | ||
| 6641 | } | ||
| 6642 | |||
| 6643 | /** | ||
| 6644 | * intel_modeset_update_staged_output_state | ||
| 6645 | * | ||
| 6646 | * Updates the staged output configuration state, e.g. after we've read out the | ||
| 6647 | * current hw state. | ||
| 6648 | */ | ||
| 6649 | static void intel_modeset_update_staged_output_state(struct drm_device *dev) | ||
| 6650 | { | ||
| 6651 | struct intel_encoder *encoder; | ||
| 6652 | struct intel_connector *connector; | ||
| 6653 | |||
| 6654 | list_for_each_entry(connector, &dev->mode_config.connector_list, | ||
| 6655 | base.head) { | ||
| 6656 | connector->new_encoder = | ||
| 6657 | to_intel_encoder(connector->base.encoder); | ||
| 6658 | } | ||
| 6659 | |||
| 6660 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, | ||
| 6661 | base.head) { | ||
| 6662 | encoder->new_crtc = | ||
| 6663 | to_intel_crtc(encoder->base.crtc); | ||
| 6664 | } | ||
| 6665 | } | ||
| 6666 | |||
| 6667 | /** | ||
| 6668 | * intel_modeset_commit_output_state | ||
| 6669 | * | ||
| 6670 | * This function copies the stage display pipe configuration to the real one. | ||
| 6671 | */ | ||
| 6672 | static void intel_modeset_commit_output_state(struct drm_device *dev) | ||
| 6673 | { | ||
| 6674 | struct intel_encoder *encoder; | ||
| 6675 | struct intel_connector *connector; | ||
| 6676 | |||
| 6677 | list_for_each_entry(connector, &dev->mode_config.connector_list, | ||
| 6678 | base.head) { | ||
| 6679 | connector->base.encoder = &connector->new_encoder->base; | ||
| 6680 | } | ||
| 6681 | |||
| 6682 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, | ||
| 6683 | base.head) { | ||
| 6684 | encoder->base.crtc = &encoder->new_crtc->base; | ||
| 6685 | } | ||
| 6686 | } | ||
| 6687 | |||
| 6688 | static struct drm_display_mode * | ||
| 6689 | intel_modeset_adjusted_mode(struct drm_crtc *crtc, | ||
| 6690 | struct drm_display_mode *mode) | ||
| 6691 | { | ||
| 6692 | struct drm_device *dev = crtc->dev; | ||
| 6693 | struct drm_display_mode *adjusted_mode; | ||
| 6694 | struct drm_encoder_helper_funcs *encoder_funcs; | ||
| 6695 | struct intel_encoder *encoder; | ||
| 6696 | |||
| 6697 | adjusted_mode = drm_mode_duplicate(dev, mode); | ||
| 6698 | if (!adjusted_mode) | ||
| 6699 | return ERR_PTR(-ENOMEM); | ||
| 6700 | |||
| 6701 | /* Pass our mode to the connectors and the CRTC to give them a chance to | ||
| 6702 | * adjust it according to limitations or connector properties, and also | ||
| 6703 | * a chance to reject the mode entirely. | ||
| 6557 | */ | 6704 | */ |
| 6705 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, | ||
| 6706 | base.head) { | ||
| 6558 | 6707 | ||
| 6559 | reg = DSPCNTR(plane); | 6708 | if (&encoder->new_crtc->base != crtc) |
| 6560 | val = I915_READ(reg); | 6709 | continue; |
| 6710 | encoder_funcs = encoder->base.helper_private; | ||
| 6711 | if (!(encoder_funcs->mode_fixup(&encoder->base, mode, | ||
| 6712 | adjusted_mode))) { | ||
| 6713 | DRM_DEBUG_KMS("Encoder fixup failed\n"); | ||
| 6714 | goto fail; | ||
| 6715 | } | ||
| 6716 | } | ||
| 6561 | 6717 | ||
| 6562 | if ((val & DISPLAY_PLANE_ENABLE) == 0) | 6718 | if (!(intel_crtc_mode_fixup(crtc, mode, adjusted_mode))) { |
| 6563 | return; | 6719 | DRM_DEBUG_KMS("CRTC fixup failed\n"); |
| 6564 | if (!!(val & DISPPLANE_SEL_PIPE_MASK) == pipe) | 6720 | goto fail; |
| 6565 | return; | 6721 | } |
| 6722 | DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); | ||
| 6566 | 6723 | ||
| 6567 | /* This display plane is active and attached to the other CPU pipe. */ | 6724 | return adjusted_mode; |
| 6568 | pipe = !pipe; | 6725 | fail: |
| 6726 | drm_mode_destroy(dev, adjusted_mode); | ||
| 6727 | return ERR_PTR(-EINVAL); | ||
| 6728 | } | ||
| 6569 | 6729 | ||
| 6570 | /* Disable the plane and wait for it to stop reading from the pipe. */ | 6730 | /* Computes which crtcs are affected and sets the relevant bits in the mask. For |
| 6571 | intel_disable_plane(dev_priv, plane, pipe); | 6731 | * simplicity we use the crtc's pipe number (because it's easier to obtain). */ |
| 6572 | intel_disable_pipe(dev_priv, pipe); | 6732 | static void |
| 6733 | intel_modeset_affected_pipes(struct drm_crtc *crtc, unsigned *modeset_pipes, | ||
| 6734 | unsigned *prepare_pipes, unsigned *disable_pipes) | ||
| 6735 | { | ||
| 6736 | struct intel_crtc *intel_crtc; | ||
| 6737 | struct drm_device *dev = crtc->dev; | ||
| 6738 | struct intel_encoder *encoder; | ||
| 6739 | struct intel_connector *connector; | ||
| 6740 | struct drm_crtc *tmp_crtc; | ||
| 6741 | |||
| 6742 | *disable_pipes = *modeset_pipes = *prepare_pipes = 0; | ||
| 6743 | |||
| 6744 | /* Check which crtcs have changed outputs connected to them, these need | ||
| 6745 | * to be part of the prepare_pipes mask. We don't (yet) support global | ||
| 6746 | * modeset across multiple crtcs, so modeset_pipes will only have one | ||
| 6747 | * bit set at most. */ | ||
| 6748 | list_for_each_entry(connector, &dev->mode_config.connector_list, | ||
| 6749 | base.head) { | ||
| 6750 | if (connector->base.encoder == &connector->new_encoder->base) | ||
| 6751 | continue; | ||
| 6752 | |||
| 6753 | if (connector->base.encoder) { | ||
| 6754 | tmp_crtc = connector->base.encoder->crtc; | ||
| 6755 | |||
| 6756 | *prepare_pipes |= 1 << to_intel_crtc(tmp_crtc)->pipe; | ||
| 6757 | } | ||
| 6758 | |||
| 6759 | if (connector->new_encoder) | ||
| 6760 | *prepare_pipes |= | ||
| 6761 | 1 << connector->new_encoder->new_crtc->pipe; | ||
| 6762 | } | ||
| 6763 | |||
| 6764 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, | ||
| 6765 | base.head) { | ||
| 6766 | if (encoder->base.crtc == &encoder->new_crtc->base) | ||
| 6767 | continue; | ||
| 6768 | |||
| 6769 | if (encoder->base.crtc) { | ||
| 6770 | tmp_crtc = encoder->base.crtc; | ||
| 6771 | |||
| 6772 | *prepare_pipes |= 1 << to_intel_crtc(tmp_crtc)->pipe; | ||
| 6773 | } | ||
| 6774 | |||
| 6775 | if (encoder->new_crtc) | ||
| 6776 | *prepare_pipes |= 1 << encoder->new_crtc->pipe; | ||
| 6777 | } | ||
| 6778 | |||
| 6779 | /* Check for any pipes that will be fully disabled ... */ | ||
| 6780 | list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, | ||
| 6781 | base.head) { | ||
| 6782 | bool used = false; | ||
| 6783 | |||
| 6784 | /* Don't try to disable disabled crtcs. */ | ||
| 6785 | if (!intel_crtc->base.enabled) | ||
| 6786 | continue; | ||
| 6787 | |||
| 6788 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, | ||
| 6789 | base.head) { | ||
| 6790 | if (encoder->new_crtc == intel_crtc) | ||
| 6791 | used = true; | ||
| 6792 | } | ||
| 6793 | |||
| 6794 | if (!used) | ||
| 6795 | *disable_pipes |= 1 << intel_crtc->pipe; | ||
| 6796 | } | ||
| 6797 | |||
| 6798 | |||
| 6799 | /* set_mode is also used to update properties on life display pipes. */ | ||
| 6800 | intel_crtc = to_intel_crtc(crtc); | ||
| 6801 | if (crtc->enabled) | ||
| 6802 | *prepare_pipes |= 1 << intel_crtc->pipe; | ||
| 6803 | |||
| 6804 | /* We only support modeset on one single crtc, hence we need to do that | ||
| 6805 | * only for the passed in crtc iff we change anything else than just | ||
| 6806 | * disable crtcs. | ||
| 6807 | * | ||
| 6808 | * This is actually not true, to be fully compatible with the old crtc | ||
| 6809 | * helper we automatically disable _any_ output (i.e. doesn't need to be | ||
| 6810 | * connected to the crtc we're modesetting on) if it's disconnected. | ||
| 6811 | * Which is a rather nutty api (since changed the output configuration | ||
| 6812 | * without userspace's explicit request can lead to confusion), but | ||
| 6813 | * alas. Hence we currently need to modeset on all pipes we prepare. */ | ||
| 6814 | if (*prepare_pipes) | ||
| 6815 | *modeset_pipes = *prepare_pipes; | ||
| 6816 | |||
| 6817 | /* ... and mask these out. */ | ||
| 6818 | *modeset_pipes &= ~(*disable_pipes); | ||
| 6819 | *prepare_pipes &= ~(*disable_pipes); | ||
| 6573 | } | 6820 | } |
| 6574 | 6821 | ||
| 6575 | static void intel_crtc_reset(struct drm_crtc *crtc) | 6822 | static bool intel_crtc_in_use(struct drm_crtc *crtc) |
| 6576 | { | 6823 | { |
| 6824 | struct drm_encoder *encoder; | ||
| 6577 | struct drm_device *dev = crtc->dev; | 6825 | struct drm_device *dev = crtc->dev; |
| 6578 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
| 6579 | 6826 | ||
| 6580 | /* Reset flags back to the 'unknown' status so that they | 6827 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) |
| 6581 | * will be correctly set on the initial modeset. | 6828 | if (encoder->crtc == crtc) |
| 6829 | return true; | ||
| 6830 | |||
| 6831 | return false; | ||
| 6832 | } | ||
| 6833 | |||
| 6834 | static void | ||
| 6835 | intel_modeset_update_state(struct drm_device *dev, unsigned prepare_pipes) | ||
| 6836 | { | ||
| 6837 | struct intel_encoder *intel_encoder; | ||
| 6838 | struct intel_crtc *intel_crtc; | ||
| 6839 | struct drm_connector *connector; | ||
| 6840 | |||
| 6841 | list_for_each_entry(intel_encoder, &dev->mode_config.encoder_list, | ||
| 6842 | base.head) { | ||
| 6843 | if (!intel_encoder->base.crtc) | ||
| 6844 | continue; | ||
| 6845 | |||
| 6846 | intel_crtc = to_intel_crtc(intel_encoder->base.crtc); | ||
| 6847 | |||
| 6848 | if (prepare_pipes & (1 << intel_crtc->pipe)) | ||
| 6849 | intel_encoder->connectors_active = false; | ||
| 6850 | } | ||
| 6851 | |||
| 6852 | intel_modeset_commit_output_state(dev); | ||
| 6853 | |||
| 6854 | /* Update computed state. */ | ||
| 6855 | list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, | ||
| 6856 | base.head) { | ||
| 6857 | intel_crtc->base.enabled = intel_crtc_in_use(&intel_crtc->base); | ||
| 6858 | } | ||
| 6859 | |||
| 6860 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
| 6861 | if (!connector->encoder || !connector->encoder->crtc) | ||
| 6862 | continue; | ||
| 6863 | |||
| 6864 | intel_crtc = to_intel_crtc(connector->encoder->crtc); | ||
| 6865 | |||
| 6866 | if (prepare_pipes & (1 << intel_crtc->pipe)) { | ||
| 6867 | connector->dpms = DRM_MODE_DPMS_ON; | ||
| 6868 | |||
| 6869 | intel_encoder = to_intel_encoder(connector->encoder); | ||
| 6870 | intel_encoder->connectors_active = true; | ||
| 6871 | } | ||
| 6872 | } | ||
| 6873 | |||
| 6874 | } | ||
| 6875 | |||
| 6876 | #define for_each_intel_crtc_masked(dev, mask, intel_crtc) \ | ||
| 6877 | list_for_each_entry((intel_crtc), \ | ||
| 6878 | &(dev)->mode_config.crtc_list, \ | ||
| 6879 | base.head) \ | ||
| 6880 | if (mask & (1 <<(intel_crtc)->pipe)) \ | ||
| 6881 | |||
| 6882 | void | ||
| 6883 | intel_modeset_check_state(struct drm_device *dev) | ||
| 6884 | { | ||
| 6885 | struct intel_crtc *crtc; | ||
| 6886 | struct intel_encoder *encoder; | ||
| 6887 | struct intel_connector *connector; | ||
| 6888 | |||
| 6889 | list_for_each_entry(connector, &dev->mode_config.connector_list, | ||
| 6890 | base.head) { | ||
| 6891 | /* This also checks the encoder/connector hw state with the | ||
| 6892 | * ->get_hw_state callbacks. */ | ||
| 6893 | intel_connector_check_state(connector); | ||
| 6894 | |||
| 6895 | WARN(&connector->new_encoder->base != connector->base.encoder, | ||
| 6896 | "connector's staged encoder doesn't match current encoder\n"); | ||
| 6897 | } | ||
| 6898 | |||
| 6899 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, | ||
| 6900 | base.head) { | ||
| 6901 | bool enabled = false; | ||
| 6902 | bool active = false; | ||
| 6903 | enum pipe pipe, tracked_pipe; | ||
| 6904 | |||
| 6905 | DRM_DEBUG_KMS("[ENCODER:%d:%s]\n", | ||
| 6906 | encoder->base.base.id, | ||
| 6907 | drm_get_encoder_name(&encoder->base)); | ||
| 6908 | |||
| 6909 | WARN(&encoder->new_crtc->base != encoder->base.crtc, | ||
| 6910 | "encoder's stage crtc doesn't match current crtc\n"); | ||
| 6911 | WARN(encoder->connectors_active && !encoder->base.crtc, | ||
| 6912 | "encoder's active_connectors set, but no crtc\n"); | ||
| 6913 | |||
| 6914 | list_for_each_entry(connector, &dev->mode_config.connector_list, | ||
| 6915 | base.head) { | ||
| 6916 | if (connector->base.encoder != &encoder->base) | ||
| 6917 | continue; | ||
| 6918 | enabled = true; | ||
| 6919 | if (connector->base.dpms != DRM_MODE_DPMS_OFF) | ||
| 6920 | active = true; | ||
| 6921 | } | ||
| 6922 | WARN(!!encoder->base.crtc != enabled, | ||
| 6923 | "encoder's enabled state mismatch " | ||
| 6924 | "(expected %i, found %i)\n", | ||
| 6925 | !!encoder->base.crtc, enabled); | ||
| 6926 | WARN(active && !encoder->base.crtc, | ||
| 6927 | "active encoder with no crtc\n"); | ||
| 6928 | |||
| 6929 | WARN(encoder->connectors_active != active, | ||
| 6930 | "encoder's computed active state doesn't match tracked active state " | ||
| 6931 | "(expected %i, found %i)\n", active, encoder->connectors_active); | ||
| 6932 | |||
| 6933 | active = encoder->get_hw_state(encoder, &pipe); | ||
| 6934 | WARN(active != encoder->connectors_active, | ||
| 6935 | "encoder's hw state doesn't match sw tracking " | ||
| 6936 | "(expected %i, found %i)\n", | ||
| 6937 | encoder->connectors_active, active); | ||
| 6938 | |||
| 6939 | if (!encoder->base.crtc) | ||
| 6940 | continue; | ||
| 6941 | |||
| 6942 | tracked_pipe = to_intel_crtc(encoder->base.crtc)->pipe; | ||
| 6943 | WARN(active && pipe != tracked_pipe, | ||
| 6944 | "active encoder's pipe doesn't match" | ||
| 6945 | "(expected %i, found %i)\n", | ||
| 6946 | tracked_pipe, pipe); | ||
| 6947 | |||
| 6948 | } | ||
| 6949 | |||
| 6950 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, | ||
| 6951 | base.head) { | ||
| 6952 | bool enabled = false; | ||
| 6953 | bool active = false; | ||
| 6954 | |||
| 6955 | DRM_DEBUG_KMS("[CRTC:%d]\n", | ||
| 6956 | crtc->base.base.id); | ||
| 6957 | |||
| 6958 | WARN(crtc->active && !crtc->base.enabled, | ||
| 6959 | "active crtc, but not enabled in sw tracking\n"); | ||
| 6960 | |||
| 6961 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, | ||
| 6962 | base.head) { | ||
| 6963 | if (encoder->base.crtc != &crtc->base) | ||
| 6964 | continue; | ||
| 6965 | enabled = true; | ||
| 6966 | if (encoder->connectors_active) | ||
| 6967 | active = true; | ||
| 6968 | } | ||
| 6969 | WARN(active != crtc->active, | ||
| 6970 | "crtc's computed active state doesn't match tracked active state " | ||
| 6971 | "(expected %i, found %i)\n", active, crtc->active); | ||
| 6972 | WARN(enabled != crtc->base.enabled, | ||
| 6973 | "crtc's computed enabled state doesn't match tracked enabled state " | ||
| 6974 | "(expected %i, found %i)\n", enabled, crtc->base.enabled); | ||
| 6975 | |||
| 6976 | assert_pipe(dev->dev_private, crtc->pipe, crtc->active); | ||
| 6977 | } | ||
| 6978 | } | ||
| 6979 | |||
| 6980 | bool intel_set_mode(struct drm_crtc *crtc, | ||
| 6981 | struct drm_display_mode *mode, | ||
| 6982 | int x, int y, struct drm_framebuffer *fb) | ||
| 6983 | { | ||
| 6984 | struct drm_device *dev = crtc->dev; | ||
| 6985 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 6986 | struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode; | ||
| 6987 | struct drm_encoder_helper_funcs *encoder_funcs; | ||
| 6988 | struct drm_encoder *encoder; | ||
| 6989 | struct intel_crtc *intel_crtc; | ||
| 6990 | unsigned disable_pipes, prepare_pipes, modeset_pipes; | ||
| 6991 | bool ret = true; | ||
| 6992 | |||
| 6993 | intel_modeset_affected_pipes(crtc, &modeset_pipes, | ||
| 6994 | &prepare_pipes, &disable_pipes); | ||
| 6995 | |||
| 6996 | DRM_DEBUG_KMS("set mode pipe masks: modeset: %x, prepare: %x, disable: %x\n", | ||
| 6997 | modeset_pipes, prepare_pipes, disable_pipes); | ||
| 6998 | |||
| 6999 | for_each_intel_crtc_masked(dev, disable_pipes, intel_crtc) | ||
| 7000 | intel_crtc_disable(&intel_crtc->base); | ||
| 7001 | |||
| 7002 | saved_hwmode = crtc->hwmode; | ||
| 7003 | saved_mode = crtc->mode; | ||
| 7004 | |||
| 7005 | /* Hack: Because we don't (yet) support global modeset on multiple | ||
| 7006 | * crtcs, we don't keep track of the new mode for more than one crtc. | ||
| 7007 | * Hence simply check whether any bit is set in modeset_pipes in all the | ||
| 7008 | * pieces of code that are not yet converted to deal with mutliple crtcs | ||
| 7009 | * changing their mode at the same time. */ | ||
| 7010 | adjusted_mode = NULL; | ||
| 7011 | if (modeset_pipes) { | ||
| 7012 | adjusted_mode = intel_modeset_adjusted_mode(crtc, mode); | ||
| 7013 | if (IS_ERR(adjusted_mode)) { | ||
| 7014 | return false; | ||
| 7015 | } | ||
| 7016 | } | ||
| 7017 | |||
| 7018 | for_each_intel_crtc_masked(dev, prepare_pipes, intel_crtc) { | ||
| 7019 | if (intel_crtc->base.enabled) | ||
| 7020 | dev_priv->display.crtc_disable(&intel_crtc->base); | ||
| 7021 | } | ||
| 7022 | |||
| 7023 | if (modeset_pipes) { | ||
| 7024 | crtc->mode = *mode; | ||
| 7025 | crtc->x = x; | ||
| 7026 | crtc->y = y; | ||
| 7027 | } | ||
| 7028 | |||
| 7029 | /* Only after disabling all output pipelines that will be changed can we | ||
| 7030 | * update the the output configuration. */ | ||
| 7031 | intel_modeset_update_state(dev, prepare_pipes); | ||
| 7032 | |||
| 7033 | /* Set up the DPLL and any encoders state that needs to adjust or depend | ||
| 7034 | * on the DPLL. | ||
| 6582 | */ | 7035 | */ |
| 6583 | intel_crtc->dpms_mode = -1; | 7036 | for_each_intel_crtc_masked(dev, modeset_pipes, intel_crtc) { |
| 7037 | ret = !intel_crtc_mode_set(&intel_crtc->base, | ||
| 7038 | mode, adjusted_mode, | ||
| 7039 | x, y, fb); | ||
| 7040 | if (!ret) | ||
| 7041 | goto done; | ||
| 7042 | |||
| 7043 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
| 7044 | |||
| 7045 | if (encoder->crtc != &intel_crtc->base) | ||
| 7046 | continue; | ||
| 7047 | |||
| 7048 | DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%d:%s]\n", | ||
| 7049 | encoder->base.id, drm_get_encoder_name(encoder), | ||
| 7050 | mode->base.id, mode->name); | ||
| 7051 | encoder_funcs = encoder->helper_private; | ||
| 7052 | encoder_funcs->mode_set(encoder, mode, adjusted_mode); | ||
| 7053 | } | ||
| 7054 | } | ||
| 7055 | |||
| 7056 | /* Now enable the clocks, plane, pipe, and connectors that we set up. */ | ||
| 7057 | for_each_intel_crtc_masked(dev, prepare_pipes, intel_crtc) | ||
| 7058 | dev_priv->display.crtc_enable(&intel_crtc->base); | ||
| 6584 | 7059 | ||
| 6585 | /* We need to fix up any BIOS configuration that conflicts with | 7060 | if (modeset_pipes) { |
| 6586 | * our expectations. | 7061 | /* Store real post-adjustment hardware mode. */ |
| 7062 | crtc->hwmode = *adjusted_mode; | ||
| 7063 | |||
| 7064 | /* Calculate and store various constants which | ||
| 7065 | * are later needed by vblank and swap-completion | ||
| 7066 | * timestamping. They are derived from true hwmode. | ||
| 7067 | */ | ||
| 7068 | drm_calc_timestamping_constants(crtc); | ||
| 7069 | } | ||
| 7070 | |||
| 7071 | /* FIXME: add subpixel order */ | ||
| 7072 | done: | ||
| 7073 | drm_mode_destroy(dev, adjusted_mode); | ||
| 7074 | if (!ret && crtc->enabled) { | ||
| 7075 | crtc->hwmode = saved_hwmode; | ||
| 7076 | crtc->mode = saved_mode; | ||
| 7077 | } else { | ||
| 7078 | intel_modeset_check_state(dev); | ||
| 7079 | } | ||
| 7080 | |||
| 7081 | return ret; | ||
| 7082 | } | ||
| 7083 | |||
| 7084 | #undef for_each_intel_crtc_masked | ||
| 7085 | |||
| 7086 | static void intel_set_config_free(struct intel_set_config *config) | ||
| 7087 | { | ||
| 7088 | if (!config) | ||
| 7089 | return; | ||
| 7090 | |||
| 7091 | kfree(config->save_connector_encoders); | ||
| 7092 | kfree(config->save_encoder_crtcs); | ||
| 7093 | kfree(config); | ||
| 7094 | } | ||
| 7095 | |||
| 7096 | static int intel_set_config_save_state(struct drm_device *dev, | ||
| 7097 | struct intel_set_config *config) | ||
| 7098 | { | ||
| 7099 | struct drm_encoder *encoder; | ||
| 7100 | struct drm_connector *connector; | ||
| 7101 | int count; | ||
| 7102 | |||
| 7103 | config->save_encoder_crtcs = | ||
| 7104 | kcalloc(dev->mode_config.num_encoder, | ||
| 7105 | sizeof(struct drm_crtc *), GFP_KERNEL); | ||
| 7106 | if (!config->save_encoder_crtcs) | ||
| 7107 | return -ENOMEM; | ||
| 7108 | |||
| 7109 | config->save_connector_encoders = | ||
| 7110 | kcalloc(dev->mode_config.num_connector, | ||
| 7111 | sizeof(struct drm_encoder *), GFP_KERNEL); | ||
| 7112 | if (!config->save_connector_encoders) | ||
| 7113 | return -ENOMEM; | ||
| 7114 | |||
| 7115 | /* Copy data. Note that driver private data is not affected. | ||
| 7116 | * Should anything bad happen only the expected state is | ||
| 7117 | * restored, not the drivers personal bookkeeping. | ||
| 6587 | */ | 7118 | */ |
| 6588 | intel_sanitize_modesetting(dev, intel_crtc->pipe, intel_crtc->plane); | 7119 | count = 0; |
| 7120 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
| 7121 | config->save_encoder_crtcs[count++] = encoder->crtc; | ||
| 7122 | } | ||
| 7123 | |||
| 7124 | count = 0; | ||
| 7125 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
| 7126 | config->save_connector_encoders[count++] = connector->encoder; | ||
| 7127 | } | ||
| 7128 | |||
| 7129 | return 0; | ||
| 6589 | } | 7130 | } |
| 6590 | 7131 | ||
| 6591 | static struct drm_crtc_helper_funcs intel_helper_funcs = { | 7132 | static void intel_set_config_restore_state(struct drm_device *dev, |
| 6592 | .dpms = intel_crtc_dpms, | 7133 | struct intel_set_config *config) |
| 6593 | .mode_fixup = intel_crtc_mode_fixup, | 7134 | { |
| 6594 | .mode_set = intel_crtc_mode_set, | 7135 | struct intel_encoder *encoder; |
| 6595 | .mode_set_base = intel_pipe_set_base, | 7136 | struct intel_connector *connector; |
| 6596 | .mode_set_base_atomic = intel_pipe_set_base_atomic, | 7137 | int count; |
| 6597 | .load_lut = intel_crtc_load_lut, | 7138 | |
| 6598 | .disable = intel_crtc_disable, | 7139 | count = 0; |
| 6599 | }; | 7140 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) { |
| 7141 | encoder->new_crtc = | ||
| 7142 | to_intel_crtc(config->save_encoder_crtcs[count++]); | ||
| 7143 | } | ||
| 7144 | |||
| 7145 | count = 0; | ||
| 7146 | list_for_each_entry(connector, &dev->mode_config.connector_list, base.head) { | ||
| 7147 | connector->new_encoder = | ||
| 7148 | to_intel_encoder(config->save_connector_encoders[count++]); | ||
| 7149 | } | ||
| 7150 | } | ||
| 7151 | |||
| 7152 | static void | ||
| 7153 | intel_set_config_compute_mode_changes(struct drm_mode_set *set, | ||
| 7154 | struct intel_set_config *config) | ||
| 7155 | { | ||
| 7156 | |||
| 7157 | /* We should be able to check here if the fb has the same properties | ||
| 7158 | * and then just flip_or_move it */ | ||
| 7159 | if (set->crtc->fb != set->fb) { | ||
| 7160 | /* If we have no fb then treat it as a full mode set */ | ||
| 7161 | if (set->crtc->fb == NULL) { | ||
| 7162 | DRM_DEBUG_KMS("crtc has no fb, full mode set\n"); | ||
| 7163 | config->mode_changed = true; | ||
| 7164 | } else if (set->fb == NULL) { | ||
| 7165 | config->mode_changed = true; | ||
| 7166 | } else if (set->fb->depth != set->crtc->fb->depth) { | ||
| 7167 | config->mode_changed = true; | ||
| 7168 | } else if (set->fb->bits_per_pixel != | ||
| 7169 | set->crtc->fb->bits_per_pixel) { | ||
| 7170 | config->mode_changed = true; | ||
| 7171 | } else | ||
| 7172 | config->fb_changed = true; | ||
| 7173 | } | ||
| 7174 | |||
| 7175 | if (set->fb && (set->x != set->crtc->x || set->y != set->crtc->y)) | ||
| 7176 | config->fb_changed = true; | ||
| 7177 | |||
| 7178 | if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) { | ||
| 7179 | DRM_DEBUG_KMS("modes are different, full mode set\n"); | ||
| 7180 | drm_mode_debug_printmodeline(&set->crtc->mode); | ||
| 7181 | drm_mode_debug_printmodeline(set->mode); | ||
| 7182 | config->mode_changed = true; | ||
| 7183 | } | ||
| 7184 | } | ||
| 7185 | |||
| 7186 | static int | ||
| 7187 | intel_modeset_stage_output_state(struct drm_device *dev, | ||
| 7188 | struct drm_mode_set *set, | ||
| 7189 | struct intel_set_config *config) | ||
| 7190 | { | ||
| 7191 | struct drm_crtc *new_crtc; | ||
| 7192 | struct intel_connector *connector; | ||
| 7193 | struct intel_encoder *encoder; | ||
| 7194 | int count, ro; | ||
| 7195 | |||
| 7196 | /* The upper layers ensure that we either disabl a crtc or have a list | ||
| 7197 | * of connectors. For paranoia, double-check this. */ | ||
| 7198 | WARN_ON(!set->fb && (set->num_connectors != 0)); | ||
| 7199 | WARN_ON(set->fb && (set->num_connectors == 0)); | ||
| 7200 | |||
| 7201 | count = 0; | ||
| 7202 | list_for_each_entry(connector, &dev->mode_config.connector_list, | ||
| 7203 | base.head) { | ||
| 7204 | /* Otherwise traverse passed in connector list and get encoders | ||
| 7205 | * for them. */ | ||
| 7206 | for (ro = 0; ro < set->num_connectors; ro++) { | ||
| 7207 | if (set->connectors[ro] == &connector->base) { | ||
| 7208 | connector->new_encoder = connector->encoder; | ||
| 7209 | break; | ||
| 7210 | } | ||
| 7211 | } | ||
| 7212 | |||
| 7213 | /* If we disable the crtc, disable all its connectors. Also, if | ||
| 7214 | * the connector is on the changing crtc but not on the new | ||
| 7215 | * connector list, disable it. */ | ||
| 7216 | if ((!set->fb || ro == set->num_connectors) && | ||
| 7217 | connector->base.encoder && | ||
| 7218 | connector->base.encoder->crtc == set->crtc) { | ||
| 7219 | connector->new_encoder = NULL; | ||
| 7220 | |||
| 7221 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n", | ||
| 7222 | connector->base.base.id, | ||
| 7223 | drm_get_connector_name(&connector->base)); | ||
| 7224 | } | ||
| 7225 | |||
| 7226 | |||
| 7227 | if (&connector->new_encoder->base != connector->base.encoder) { | ||
| 7228 | DRM_DEBUG_KMS("encoder changed, full mode switch\n"); | ||
| 7229 | config->mode_changed = true; | ||
| 7230 | } | ||
| 7231 | |||
| 7232 | /* Disable all disconnected encoders. */ | ||
| 7233 | if (connector->base.status == connector_status_disconnected) | ||
| 7234 | connector->new_encoder = NULL; | ||
| 7235 | } | ||
| 7236 | /* connector->new_encoder is now updated for all connectors. */ | ||
| 7237 | |||
| 7238 | /* Update crtc of enabled connectors. */ | ||
| 7239 | count = 0; | ||
| 7240 | list_for_each_entry(connector, &dev->mode_config.connector_list, | ||
| 7241 | base.head) { | ||
| 7242 | if (!connector->new_encoder) | ||
| 7243 | continue; | ||
| 7244 | |||
| 7245 | new_crtc = connector->new_encoder->base.crtc; | ||
| 7246 | |||
| 7247 | for (ro = 0; ro < set->num_connectors; ro++) { | ||
| 7248 | if (set->connectors[ro] == &connector->base) | ||
| 7249 | new_crtc = set->crtc; | ||
| 7250 | } | ||
| 7251 | |||
| 7252 | /* Make sure the new CRTC will work with the encoder */ | ||
| 7253 | if (!intel_encoder_crtc_ok(&connector->new_encoder->base, | ||
| 7254 | new_crtc)) { | ||
| 7255 | return -EINVAL; | ||
| 7256 | } | ||
| 7257 | connector->encoder->new_crtc = to_intel_crtc(new_crtc); | ||
| 7258 | |||
| 7259 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d]\n", | ||
| 7260 | connector->base.base.id, | ||
| 7261 | drm_get_connector_name(&connector->base), | ||
| 7262 | new_crtc->base.id); | ||
| 7263 | } | ||
| 7264 | |||
| 7265 | /* Check for any encoders that needs to be disabled. */ | ||
| 7266 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, | ||
| 7267 | base.head) { | ||
| 7268 | list_for_each_entry(connector, | ||
| 7269 | &dev->mode_config.connector_list, | ||
| 7270 | base.head) { | ||
| 7271 | if (connector->new_encoder == encoder) { | ||
| 7272 | WARN_ON(!connector->new_encoder->new_crtc); | ||
| 7273 | |||
| 7274 | goto next_encoder; | ||
| 7275 | } | ||
| 7276 | } | ||
| 7277 | encoder->new_crtc = NULL; | ||
| 7278 | next_encoder: | ||
| 7279 | /* Only now check for crtc changes so we don't miss encoders | ||
| 7280 | * that will be disabled. */ | ||
| 7281 | if (&encoder->new_crtc->base != encoder->base.crtc) { | ||
| 7282 | DRM_DEBUG_KMS("crtc changed, full mode switch\n"); | ||
| 7283 | config->mode_changed = true; | ||
| 7284 | } | ||
| 7285 | } | ||
| 7286 | /* Now we've also updated encoder->new_crtc for all encoders. */ | ||
| 7287 | |||
| 7288 | return 0; | ||
| 7289 | } | ||
| 7290 | |||
| 7291 | static int intel_crtc_set_config(struct drm_mode_set *set) | ||
| 7292 | { | ||
| 7293 | struct drm_device *dev; | ||
| 7294 | struct drm_mode_set save_set; | ||
| 7295 | struct intel_set_config *config; | ||
| 7296 | int ret; | ||
| 7297 | int i; | ||
| 7298 | |||
| 7299 | BUG_ON(!set); | ||
| 7300 | BUG_ON(!set->crtc); | ||
| 7301 | BUG_ON(!set->crtc->helper_private); | ||
| 7302 | |||
| 7303 | if (!set->mode) | ||
| 7304 | set->fb = NULL; | ||
| 7305 | |||
| 7306 | /* The fb helper likes to play gross jokes with ->mode_set_config. | ||
| 7307 | * Unfortunately the crtc helper doesn't do much at all for this case, | ||
| 7308 | * so we have to cope with this madness until the fb helper is fixed up. */ | ||
| 7309 | if (set->fb && set->num_connectors == 0) | ||
| 7310 | return 0; | ||
| 7311 | |||
| 7312 | if (set->fb) { | ||
| 7313 | DRM_DEBUG_KMS("[CRTC:%d] [FB:%d] #connectors=%d (x y) (%i %i)\n", | ||
| 7314 | set->crtc->base.id, set->fb->base.id, | ||
| 7315 | (int)set->num_connectors, set->x, set->y); | ||
| 7316 | } else { | ||
| 7317 | DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id); | ||
| 7318 | } | ||
| 7319 | |||
| 7320 | dev = set->crtc->dev; | ||
| 7321 | |||
| 7322 | ret = -ENOMEM; | ||
| 7323 | config = kzalloc(sizeof(*config), GFP_KERNEL); | ||
| 7324 | if (!config) | ||
| 7325 | goto out_config; | ||
| 7326 | |||
| 7327 | ret = intel_set_config_save_state(dev, config); | ||
| 7328 | if (ret) | ||
| 7329 | goto out_config; | ||
| 7330 | |||
| 7331 | save_set.crtc = set->crtc; | ||
| 7332 | save_set.mode = &set->crtc->mode; | ||
| 7333 | save_set.x = set->crtc->x; | ||
| 7334 | save_set.y = set->crtc->y; | ||
| 7335 | save_set.fb = set->crtc->fb; | ||
| 7336 | |||
| 7337 | /* Compute whether we need a full modeset, only an fb base update or no | ||
| 7338 | * change at all. In the future we might also check whether only the | ||
| 7339 | * mode changed, e.g. for LVDS where we only change the panel fitter in | ||
| 7340 | * such cases. */ | ||
| 7341 | intel_set_config_compute_mode_changes(set, config); | ||
| 7342 | |||
| 7343 | ret = intel_modeset_stage_output_state(dev, set, config); | ||
| 7344 | if (ret) | ||
| 7345 | goto fail; | ||
| 7346 | |||
| 7347 | if (config->mode_changed) { | ||
| 7348 | if (set->mode) { | ||
| 7349 | DRM_DEBUG_KMS("attempting to set mode from" | ||
| 7350 | " userspace\n"); | ||
| 7351 | drm_mode_debug_printmodeline(set->mode); | ||
| 7352 | } | ||
| 7353 | |||
| 7354 | if (!intel_set_mode(set->crtc, set->mode, | ||
| 7355 | set->x, set->y, set->fb)) { | ||
| 7356 | DRM_ERROR("failed to set mode on [CRTC:%d]\n", | ||
| 7357 | set->crtc->base.id); | ||
| 7358 | ret = -EINVAL; | ||
| 7359 | goto fail; | ||
| 7360 | } | ||
| 7361 | |||
| 7362 | if (set->crtc->enabled) { | ||
| 7363 | DRM_DEBUG_KMS("Setting connector DPMS state to on\n"); | ||
| 7364 | for (i = 0; i < set->num_connectors; i++) { | ||
| 7365 | DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", set->connectors[i]->base.id, | ||
| 7366 | drm_get_connector_name(set->connectors[i])); | ||
| 7367 | set->connectors[i]->funcs->dpms(set->connectors[i], DRM_MODE_DPMS_ON); | ||
| 7368 | } | ||
| 7369 | } | ||
| 7370 | } else if (config->fb_changed) { | ||
| 7371 | ret = intel_pipe_set_base(set->crtc, | ||
| 7372 | set->x, set->y, set->fb); | ||
| 7373 | } | ||
| 7374 | |||
| 7375 | intel_set_config_free(config); | ||
| 7376 | |||
| 7377 | return 0; | ||
| 7378 | |||
| 7379 | fail: | ||
| 7380 | intel_set_config_restore_state(dev, config); | ||
| 7381 | |||
| 7382 | /* Try to restore the config */ | ||
| 7383 | if (config->mode_changed && | ||
| 7384 | !intel_set_mode(save_set.crtc, save_set.mode, | ||
| 7385 | save_set.x, save_set.y, save_set.fb)) | ||
| 7386 | DRM_ERROR("failed to restore config after modeset failure\n"); | ||
| 7387 | |||
| 7388 | out_config: | ||
| 7389 | intel_set_config_free(config); | ||
| 7390 | return ret; | ||
| 7391 | } | ||
| 6600 | 7392 | ||
| 6601 | static const struct drm_crtc_funcs intel_crtc_funcs = { | 7393 | static const struct drm_crtc_funcs intel_crtc_funcs = { |
| 6602 | .reset = intel_crtc_reset, | ||
| 6603 | .cursor_set = intel_crtc_cursor_set, | 7394 | .cursor_set = intel_crtc_cursor_set, |
| 6604 | .cursor_move = intel_crtc_cursor_move, | 7395 | .cursor_move = intel_crtc_cursor_move, |
| 6605 | .gamma_set = intel_crtc_gamma_set, | 7396 | .gamma_set = intel_crtc_gamma_set, |
| 6606 | .set_config = drm_crtc_helper_set_config, | 7397 | .set_config = intel_crtc_set_config, |
| 6607 | .destroy = intel_crtc_destroy, | 7398 | .destroy = intel_crtc_destroy, |
| 6608 | .page_flip = intel_crtc_page_flip, | 7399 | .page_flip = intel_crtc_page_flip, |
| 6609 | }; | 7400 | }; |
| @@ -6657,18 +7448,8 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) | |||
| 6657 | dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = &intel_crtc->base; | 7448 | dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = &intel_crtc->base; |
| 6658 | dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base; | 7449 | dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base; |
| 6659 | 7450 | ||
| 6660 | intel_crtc_reset(&intel_crtc->base); | ||
| 6661 | intel_crtc->active = true; /* force the pipe off on setup_init_config */ | ||
| 6662 | intel_crtc->bpp = 24; /* default for pre-Ironlake */ | 7451 | intel_crtc->bpp = 24; /* default for pre-Ironlake */ |
| 6663 | 7452 | ||
| 6664 | if (HAS_PCH_SPLIT(dev)) { | ||
| 6665 | intel_helper_funcs.prepare = ironlake_crtc_prepare; | ||
| 6666 | intel_helper_funcs.commit = ironlake_crtc_commit; | ||
| 6667 | } else { | ||
| 6668 | intel_helper_funcs.prepare = i9xx_crtc_prepare; | ||
| 6669 | intel_helper_funcs.commit = i9xx_crtc_commit; | ||
| 6670 | } | ||
| 6671 | |||
| 6672 | drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); | 7453 | drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); |
| 6673 | } | 7454 | } |
| 6674 | 7455 | ||
| @@ -6874,9 +7655,6 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
| 6874 | intel_encoder_clones(encoder); | 7655 | intel_encoder_clones(encoder); |
| 6875 | } | 7656 | } |
| 6876 | 7657 | ||
| 6877 | /* disable all the possible outputs/crtcs before entering KMS mode */ | ||
| 6878 | drm_helper_disable_unused_functions(dev); | ||
| 6879 | |||
| 6880 | if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) | 7658 | if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) |
| 6881 | ironlake_init_pch_refclk(dev); | 7659 | ironlake_init_pch_refclk(dev); |
| 6882 | } | 7660 | } |
| @@ -6978,13 +7756,15 @@ static void intel_init_display(struct drm_device *dev) | |||
| 6978 | 7756 | ||
| 6979 | /* We always want a DPMS function */ | 7757 | /* We always want a DPMS function */ |
| 6980 | if (HAS_PCH_SPLIT(dev)) { | 7758 | if (HAS_PCH_SPLIT(dev)) { |
| 6981 | dev_priv->display.dpms = ironlake_crtc_dpms; | ||
| 6982 | dev_priv->display.crtc_mode_set = ironlake_crtc_mode_set; | 7759 | dev_priv->display.crtc_mode_set = ironlake_crtc_mode_set; |
| 7760 | dev_priv->display.crtc_enable = ironlake_crtc_enable; | ||
| 7761 | dev_priv->display.crtc_disable = ironlake_crtc_disable; | ||
| 6983 | dev_priv->display.off = ironlake_crtc_off; | 7762 | dev_priv->display.off = ironlake_crtc_off; |
| 6984 | dev_priv->display.update_plane = ironlake_update_plane; | 7763 | dev_priv->display.update_plane = ironlake_update_plane; |
| 6985 | } else { | 7764 | } else { |
| 6986 | dev_priv->display.dpms = i9xx_crtc_dpms; | ||
| 6987 | dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set; | 7765 | dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set; |
| 7766 | dev_priv->display.crtc_enable = i9xx_crtc_enable; | ||
| 7767 | dev_priv->display.crtc_disable = i9xx_crtc_disable; | ||
| 6988 | dev_priv->display.off = i9xx_crtc_off; | 7768 | dev_priv->display.off = i9xx_crtc_off; |
| 6989 | dev_priv->display.update_plane = i9xx_update_plane; | 7769 | dev_priv->display.update_plane = i9xx_update_plane; |
| 6990 | } | 7770 | } |
| @@ -7233,11 +8013,258 @@ void intel_modeset_init(struct drm_device *dev) | |||
| 7233 | intel_setup_outputs(dev); | 8013 | intel_setup_outputs(dev); |
| 7234 | } | 8014 | } |
| 7235 | 8015 | ||
| 8016 | static void | ||
| 8017 | intel_connector_break_all_links(struct intel_connector *connector) | ||
| 8018 | { | ||
| 8019 | connector->base.dpms = DRM_MODE_DPMS_OFF; | ||
| 8020 | connector->base.encoder = NULL; | ||
| 8021 | connector->encoder->connectors_active = false; | ||
| 8022 | connector->encoder->base.crtc = NULL; | ||
| 8023 | } | ||
| 8024 | |||
| 8025 | static void intel_enable_pipe_a(struct drm_device *dev) | ||
| 8026 | { | ||
| 8027 | struct intel_connector *connector; | ||
| 8028 | struct drm_connector *crt = NULL; | ||
| 8029 | struct intel_load_detect_pipe load_detect_temp; | ||
| 8030 | |||
| 8031 | /* We can't just switch on the pipe A, we need to set things up with a | ||
| 8032 | * proper mode and output configuration. As a gross hack, enable pipe A | ||
| 8033 | * by enabling the load detect pipe once. */ | ||
| 8034 | list_for_each_entry(connector, | ||
| 8035 | &dev->mode_config.connector_list, | ||
| 8036 | base.head) { | ||
| 8037 | if (connector->encoder->type == INTEL_OUTPUT_ANALOG) { | ||
| 8038 | crt = &connector->base; | ||
| 8039 | break; | ||
| 8040 | } | ||
| 8041 | } | ||
| 8042 | |||
| 8043 | if (!crt) | ||
| 8044 | return; | ||
| 8045 | |||
| 8046 | if (intel_get_load_detect_pipe(crt, NULL, &load_detect_temp)) | ||
| 8047 | intel_release_load_detect_pipe(crt, &load_detect_temp); | ||
| 8048 | |||
| 8049 | |||
| 8050 | } | ||
| 8051 | |||
| 8052 | static void intel_sanitize_crtc(struct intel_crtc *crtc) | ||
| 8053 | { | ||
| 8054 | struct drm_device *dev = crtc->base.dev; | ||
| 8055 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 8056 | u32 reg, val; | ||
| 8057 | |||
| 8058 | /* Clear any frame start delays used for debugging left by the BIOS */ | ||
| 8059 | reg = PIPECONF(crtc->pipe); | ||
| 8060 | I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK); | ||
| 8061 | |||
| 8062 | /* We need to sanitize the plane -> pipe mapping first because this will | ||
| 8063 | * disable the crtc (and hence change the state) if it is wrong. */ | ||
| 8064 | if (!HAS_PCH_SPLIT(dev)) { | ||
| 8065 | struct intel_connector *connector; | ||
| 8066 | bool plane; | ||
| 8067 | |||
| 8068 | reg = DSPCNTR(crtc->plane); | ||
| 8069 | val = I915_READ(reg); | ||
| 8070 | |||
| 8071 | if ((val & DISPLAY_PLANE_ENABLE) == 0 && | ||
| 8072 | (!!(val & DISPPLANE_SEL_PIPE_MASK) == crtc->pipe)) | ||
| 8073 | goto ok; | ||
| 8074 | |||
| 8075 | DRM_DEBUG_KMS("[CRTC:%d] wrong plane connection detected!\n", | ||
| 8076 | crtc->base.base.id); | ||
| 8077 | |||
| 8078 | /* Pipe has the wrong plane attached and the plane is active. | ||
| 8079 | * Temporarily change the plane mapping and disable everything | ||
| 8080 | * ... */ | ||
| 8081 | plane = crtc->plane; | ||
| 8082 | crtc->plane = !plane; | ||
| 8083 | dev_priv->display.crtc_disable(&crtc->base); | ||
| 8084 | crtc->plane = plane; | ||
| 8085 | |||
| 8086 | /* ... and break all links. */ | ||
| 8087 | list_for_each_entry(connector, &dev->mode_config.connector_list, | ||
| 8088 | base.head) { | ||
| 8089 | if (connector->encoder->base.crtc != &crtc->base) | ||
| 8090 | continue; | ||
| 8091 | |||
| 8092 | intel_connector_break_all_links(connector); | ||
| 8093 | } | ||
| 8094 | |||
| 8095 | WARN_ON(crtc->active); | ||
| 8096 | crtc->base.enabled = false; | ||
| 8097 | } | ||
| 8098 | ok: | ||
| 8099 | |||
| 8100 | if (dev_priv->quirks & QUIRK_PIPEA_FORCE && | ||
| 8101 | crtc->pipe == PIPE_A && !crtc->active) { | ||
| 8102 | /* BIOS forgot to enable pipe A, this mostly happens after | ||
| 8103 | * resume. Force-enable the pipe to fix this, the update_dpms | ||
| 8104 | * call below we restore the pipe to the right state, but leave | ||
| 8105 | * the required bits on. */ | ||
| 8106 | intel_enable_pipe_a(dev); | ||
| 8107 | } | ||
| 8108 | |||
| 8109 | /* Adjust the state of the output pipe according to whether we | ||
| 8110 | * have active connectors/encoders. */ | ||
| 8111 | intel_crtc_update_dpms(&crtc->base); | ||
| 8112 | |||
| 8113 | if (crtc->active != crtc->base.enabled) { | ||
| 8114 | struct intel_encoder *encoder; | ||
| 8115 | |||
| 8116 | /* This can happen either due to bugs in the get_hw_state | ||
| 8117 | * functions or because the pipe is force-enabled due to the | ||
| 8118 | * pipe A quirk. */ | ||
| 8119 | DRM_DEBUG_KMS("[CRTC:%d] hw state adjusted, was %s, now %s\n", | ||
| 8120 | crtc->base.base.id, | ||
| 8121 | crtc->base.enabled ? "enabled" : "disabled", | ||
| 8122 | crtc->active ? "enabled" : "disabled"); | ||
| 8123 | |||
| 8124 | crtc->base.enabled = crtc->active; | ||
| 8125 | |||
| 8126 | /* Because we only establish the connector -> encoder -> | ||
| 8127 | * crtc links if something is active, this means the | ||
| 8128 | * crtc is now deactivated. Break the links. connector | ||
| 8129 | * -> encoder links are only establish when things are | ||
| 8130 | * actually up, hence no need to break them. */ | ||
| 8131 | WARN_ON(crtc->active); | ||
| 8132 | |||
| 8133 | for_each_encoder_on_crtc(dev, &crtc->base, encoder) { | ||
| 8134 | WARN_ON(encoder->connectors_active); | ||
| 8135 | encoder->base.crtc = NULL; | ||
| 8136 | } | ||
| 8137 | } | ||
| 8138 | } | ||
| 8139 | |||
| 8140 | static void intel_sanitize_encoder(struct intel_encoder *encoder) | ||
| 8141 | { | ||
| 8142 | struct intel_connector *connector; | ||
| 8143 | struct drm_device *dev = encoder->base.dev; | ||
| 8144 | |||
| 8145 | /* We need to check both for a crtc link (meaning that the | ||
| 8146 | * encoder is active and trying to read from a pipe) and the | ||
| 8147 | * pipe itself being active. */ | ||
| 8148 | bool has_active_crtc = encoder->base.crtc && | ||
| 8149 | to_intel_crtc(encoder->base.crtc)->active; | ||
| 8150 | |||
| 8151 | if (encoder->connectors_active && !has_active_crtc) { | ||
| 8152 | DRM_DEBUG_KMS("[ENCODER:%d:%s] has active connectors but no active pipe!\n", | ||
| 8153 | encoder->base.base.id, | ||
| 8154 | drm_get_encoder_name(&encoder->base)); | ||
| 8155 | |||
| 8156 | /* Connector is active, but has no active pipe. This is | ||
| 8157 | * fallout from our resume register restoring. Disable | ||
| 8158 | * the encoder manually again. */ | ||
| 8159 | if (encoder->base.crtc) { | ||
| 8160 | DRM_DEBUG_KMS("[ENCODER:%d:%s] manually disabled\n", | ||
| 8161 | encoder->base.base.id, | ||
| 8162 | drm_get_encoder_name(&encoder->base)); | ||
| 8163 | encoder->disable(encoder); | ||
| 8164 | } | ||
| 8165 | |||
| 8166 | /* Inconsistent output/port/pipe state happens presumably due to | ||
| 8167 | * a bug in one of the get_hw_state functions. Or someplace else | ||
| 8168 | * in our code, like the register restore mess on resume. Clamp | ||
| 8169 | * things to off as a safer default. */ | ||
| 8170 | list_for_each_entry(connector, | ||
| 8171 | &dev->mode_config.connector_list, | ||
| 8172 | base.head) { | ||
| 8173 | if (connector->encoder != encoder) | ||
| 8174 | continue; | ||
| 8175 | |||
| 8176 | intel_connector_break_all_links(connector); | ||
| 8177 | } | ||
| 8178 | } | ||
| 8179 | /* Enabled encoders without active connectors will be fixed in | ||
| 8180 | * the crtc fixup. */ | ||
| 8181 | } | ||
| 8182 | |||
| 8183 | /* Scan out the current hw modeset state, sanitizes it and maps it into the drm | ||
| 8184 | * and i915 state tracking structures. */ | ||
| 8185 | void intel_modeset_setup_hw_state(struct drm_device *dev) | ||
| 8186 | { | ||
| 8187 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 8188 | enum pipe pipe; | ||
| 8189 | u32 tmp; | ||
| 8190 | struct intel_crtc *crtc; | ||
| 8191 | struct intel_encoder *encoder; | ||
| 8192 | struct intel_connector *connector; | ||
| 8193 | |||
| 8194 | for_each_pipe(pipe) { | ||
| 8195 | crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); | ||
| 8196 | |||
| 8197 | tmp = I915_READ(PIPECONF(pipe)); | ||
| 8198 | if (tmp & PIPECONF_ENABLE) | ||
| 8199 | crtc->active = true; | ||
| 8200 | else | ||
| 8201 | crtc->active = false; | ||
| 8202 | |||
| 8203 | crtc->base.enabled = crtc->active; | ||
| 8204 | |||
| 8205 | DRM_DEBUG_KMS("[CRTC:%d] hw state readout: %s\n", | ||
| 8206 | crtc->base.base.id, | ||
| 8207 | crtc->active ? "enabled" : "disabled"); | ||
| 8208 | } | ||
| 8209 | |||
| 8210 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, | ||
| 8211 | base.head) { | ||
| 8212 | pipe = 0; | ||
| 8213 | |||
| 8214 | if (encoder->get_hw_state(encoder, &pipe)) { | ||
| 8215 | encoder->base.crtc = | ||
| 8216 | dev_priv->pipe_to_crtc_mapping[pipe]; | ||
| 8217 | } else { | ||
| 8218 | encoder->base.crtc = NULL; | ||
| 8219 | } | ||
| 8220 | |||
| 8221 | encoder->connectors_active = false; | ||
| 8222 | DRM_DEBUG_KMS("[ENCODER:%d:%s] hw state readout: %s, pipe=%i\n", | ||
| 8223 | encoder->base.base.id, | ||
| 8224 | drm_get_encoder_name(&encoder->base), | ||
| 8225 | encoder->base.crtc ? "enabled" : "disabled", | ||
| 8226 | pipe); | ||
| 8227 | } | ||
| 8228 | |||
| 8229 | list_for_each_entry(connector, &dev->mode_config.connector_list, | ||
| 8230 | base.head) { | ||
| 8231 | if (connector->get_hw_state(connector)) { | ||
| 8232 | connector->base.dpms = DRM_MODE_DPMS_ON; | ||
| 8233 | connector->encoder->connectors_active = true; | ||
| 8234 | connector->base.encoder = &connector->encoder->base; | ||
| 8235 | } else { | ||
| 8236 | connector->base.dpms = DRM_MODE_DPMS_OFF; | ||
| 8237 | connector->base.encoder = NULL; | ||
| 8238 | } | ||
| 8239 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] hw state readout: %s\n", | ||
| 8240 | connector->base.base.id, | ||
| 8241 | drm_get_connector_name(&connector->base), | ||
| 8242 | connector->base.encoder ? "enabled" : "disabled"); | ||
| 8243 | } | ||
| 8244 | |||
| 8245 | /* HW state is read out, now we need to sanitize this mess. */ | ||
| 8246 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, | ||
| 8247 | base.head) { | ||
| 8248 | intel_sanitize_encoder(encoder); | ||
| 8249 | } | ||
| 8250 | |||
| 8251 | for_each_pipe(pipe) { | ||
| 8252 | crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); | ||
| 8253 | intel_sanitize_crtc(crtc); | ||
| 8254 | } | ||
| 8255 | |||
| 8256 | intel_modeset_update_staged_output_state(dev); | ||
| 8257 | |||
| 8258 | intel_modeset_check_state(dev); | ||
| 8259 | } | ||
| 8260 | |||
| 7236 | void intel_modeset_gem_init(struct drm_device *dev) | 8261 | void intel_modeset_gem_init(struct drm_device *dev) |
| 7237 | { | 8262 | { |
| 7238 | intel_modeset_init_hw(dev); | 8263 | intel_modeset_init_hw(dev); |
| 7239 | 8264 | ||
| 7240 | intel_setup_overlay(dev); | 8265 | intel_setup_overlay(dev); |
| 8266 | |||
| 8267 | intel_modeset_setup_hw_state(dev); | ||
| 7241 | } | 8268 | } |
| 7242 | 8269 | ||
| 7243 | void intel_modeset_cleanup(struct drm_device *dev) | 8270 | void intel_modeset_cleanup(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 143d19c26752..c59710db653e 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -1248,10 +1248,57 @@ static void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode) | |||
| 1248 | } | 1248 | } |
| 1249 | } | 1249 | } |
| 1250 | 1250 | ||
| 1251 | static void intel_dp_prepare(struct drm_encoder *encoder) | 1251 | static bool intel_dp_get_hw_state(struct intel_encoder *encoder, |
| 1252 | enum pipe *pipe) | ||
| 1252 | { | 1253 | { |
| 1253 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | 1254 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); |
| 1255 | struct drm_device *dev = encoder->base.dev; | ||
| 1256 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 1257 | u32 tmp = I915_READ(intel_dp->output_reg); | ||
| 1258 | |||
| 1259 | if (!(tmp & DP_PORT_EN)) | ||
| 1260 | return false; | ||
| 1254 | 1261 | ||
| 1262 | if (is_cpu_edp(intel_dp) && IS_GEN7(dev)) { | ||
| 1263 | *pipe = PORT_TO_PIPE_CPT(tmp); | ||
| 1264 | } else if (!HAS_PCH_CPT(dev) || is_cpu_edp(intel_dp)) { | ||
| 1265 | *pipe = PORT_TO_PIPE(tmp); | ||
| 1266 | } else { | ||
| 1267 | u32 trans_sel; | ||
| 1268 | u32 trans_dp; | ||
| 1269 | int i; | ||
| 1270 | |||
| 1271 | switch (intel_dp->output_reg) { | ||
| 1272 | case PCH_DP_B: | ||
| 1273 | trans_sel = TRANS_DP_PORT_SEL_B; | ||
| 1274 | break; | ||
| 1275 | case PCH_DP_C: | ||
| 1276 | trans_sel = TRANS_DP_PORT_SEL_C; | ||
| 1277 | break; | ||
| 1278 | case PCH_DP_D: | ||
| 1279 | trans_sel = TRANS_DP_PORT_SEL_D; | ||
| 1280 | break; | ||
| 1281 | default: | ||
| 1282 | return true; | ||
| 1283 | } | ||
| 1284 | |||
| 1285 | for_each_pipe(i) { | ||
| 1286 | trans_dp = I915_READ(TRANS_DP_CTL(i)); | ||
| 1287 | if ((trans_dp & TRANS_DP_PORT_SEL_MASK) == trans_sel) { | ||
| 1288 | *pipe = i; | ||
| 1289 | return true; | ||
| 1290 | } | ||
| 1291 | } | ||
| 1292 | } | ||
| 1293 | |||
| 1294 | DRM_DEBUG_KMS("No pipe for dp port 0x%x found\n", intel_dp->output_reg); | ||
| 1295 | |||
| 1296 | return true; | ||
| 1297 | } | ||
| 1298 | |||
| 1299 | static void intel_disable_dp(struct intel_encoder *encoder) | ||
| 1300 | { | ||
| 1301 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); | ||
| 1255 | 1302 | ||
| 1256 | /* Make sure the panel is off before trying to change the mode. But also | 1303 | /* Make sure the panel is off before trying to change the mode. But also |
| 1257 | * ensure that we have vdd while we switch off the panel. */ | 1304 | * ensure that we have vdd while we switch off the panel. */ |
| @@ -1262,60 +1309,58 @@ static void intel_dp_prepare(struct drm_encoder *encoder) | |||
| 1262 | intel_dp_link_down(intel_dp); | 1309 | intel_dp_link_down(intel_dp); |
| 1263 | } | 1310 | } |
| 1264 | 1311 | ||
| 1265 | static void intel_dp_commit(struct drm_encoder *encoder) | 1312 | static void intel_enable_dp(struct intel_encoder *encoder) |
| 1266 | { | 1313 | { |
| 1267 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | 1314 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); |
| 1268 | struct drm_device *dev = encoder->dev; | 1315 | struct drm_device *dev = encoder->base.dev; |
| 1269 | struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc); | 1316 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1317 | uint32_t dp_reg = I915_READ(intel_dp->output_reg); | ||
| 1270 | 1318 | ||
| 1271 | ironlake_edp_panel_vdd_on(intel_dp); | 1319 | ironlake_edp_panel_vdd_on(intel_dp); |
| 1272 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); | 1320 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); |
| 1273 | intel_dp_start_link_train(intel_dp); | 1321 | if (!(dp_reg & DP_PORT_EN)) { |
| 1274 | ironlake_edp_panel_on(intel_dp); | 1322 | intel_dp_start_link_train(intel_dp); |
| 1275 | ironlake_edp_panel_vdd_off(intel_dp, true); | 1323 | ironlake_edp_panel_on(intel_dp); |
| 1276 | intel_dp_complete_link_train(intel_dp); | 1324 | ironlake_edp_panel_vdd_off(intel_dp, true); |
| 1325 | intel_dp_complete_link_train(intel_dp); | ||
| 1326 | } else | ||
| 1327 | ironlake_edp_panel_vdd_off(intel_dp, false); | ||
| 1277 | ironlake_edp_backlight_on(intel_dp); | 1328 | ironlake_edp_backlight_on(intel_dp); |
| 1278 | |||
| 1279 | intel_dp->dpms_mode = DRM_MODE_DPMS_ON; | ||
| 1280 | |||
| 1281 | if (HAS_PCH_CPT(dev)) | ||
| 1282 | intel_cpt_verify_modeset(dev, intel_crtc->pipe); | ||
| 1283 | } | 1329 | } |
| 1284 | 1330 | ||
| 1285 | static void | 1331 | static void |
| 1286 | intel_dp_dpms(struct drm_encoder *encoder, int mode) | 1332 | intel_dp_dpms(struct drm_connector *connector, int mode) |
| 1287 | { | 1333 | { |
| 1288 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | 1334 | struct intel_dp *intel_dp = intel_attached_dp(connector); |
| 1289 | struct drm_device *dev = encoder->dev; | 1335 | |
| 1290 | struct drm_i915_private *dev_priv = dev->dev_private; | 1336 | /* DP supports only 2 dpms states. */ |
| 1291 | uint32_t dp_reg = I915_READ(intel_dp->output_reg); | 1337 | if (mode != DRM_MODE_DPMS_ON) |
| 1338 | mode = DRM_MODE_DPMS_OFF; | ||
| 1339 | |||
| 1340 | if (mode == connector->dpms) | ||
| 1341 | return; | ||
| 1342 | |||
| 1343 | connector->dpms = mode; | ||
| 1344 | |||
| 1345 | /* Only need to change hw state when actually enabled */ | ||
| 1346 | if (!intel_dp->base.base.crtc) { | ||
| 1347 | intel_dp->base.connectors_active = false; | ||
| 1348 | return; | ||
| 1349 | } | ||
| 1292 | 1350 | ||
| 1293 | if (mode != DRM_MODE_DPMS_ON) { | 1351 | if (mode != DRM_MODE_DPMS_ON) { |
| 1294 | /* Switching the panel off requires vdd. */ | 1352 | intel_encoder_dpms(&intel_dp->base, mode); |
| 1295 | ironlake_edp_panel_vdd_on(intel_dp); | ||
| 1296 | ironlake_edp_backlight_off(intel_dp); | ||
| 1297 | intel_dp_sink_dpms(intel_dp, mode); | ||
| 1298 | ironlake_edp_panel_off(intel_dp); | ||
| 1299 | intel_dp_link_down(intel_dp); | ||
| 1300 | 1353 | ||
| 1301 | if (is_cpu_edp(intel_dp)) | 1354 | if (is_cpu_edp(intel_dp)) |
| 1302 | ironlake_edp_pll_off(encoder); | 1355 | ironlake_edp_pll_off(&intel_dp->base.base); |
| 1303 | } else { | 1356 | } else { |
| 1304 | if (is_cpu_edp(intel_dp)) | 1357 | if (is_cpu_edp(intel_dp)) |
| 1305 | ironlake_edp_pll_on(encoder); | 1358 | ironlake_edp_pll_on(&intel_dp->base.base); |
| 1306 | 1359 | ||
| 1307 | ironlake_edp_panel_vdd_on(intel_dp); | 1360 | intel_encoder_dpms(&intel_dp->base, mode); |
| 1308 | intel_dp_sink_dpms(intel_dp, mode); | ||
| 1309 | if (!(dp_reg & DP_PORT_EN)) { | ||
| 1310 | intel_dp_start_link_train(intel_dp); | ||
| 1311 | ironlake_edp_panel_on(intel_dp); | ||
| 1312 | ironlake_edp_panel_vdd_off(intel_dp, true); | ||
| 1313 | intel_dp_complete_link_train(intel_dp); | ||
| 1314 | } else | ||
| 1315 | ironlake_edp_panel_vdd_off(intel_dp, false); | ||
| 1316 | ironlake_edp_backlight_on(intel_dp); | ||
| 1317 | } | 1361 | } |
| 1318 | intel_dp->dpms_mode = mode; | 1362 | |
| 1363 | intel_modeset_check_state(connector->dev); | ||
| 1319 | } | 1364 | } |
| 1320 | 1365 | ||
| 1321 | /* | 1366 | /* |
| @@ -2016,10 +2061,10 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) | |||
| 2016 | u8 sink_irq_vector; | 2061 | u8 sink_irq_vector; |
| 2017 | u8 link_status[DP_LINK_STATUS_SIZE]; | 2062 | u8 link_status[DP_LINK_STATUS_SIZE]; |
| 2018 | 2063 | ||
| 2019 | if (intel_dp->dpms_mode != DRM_MODE_DPMS_ON) | 2064 | if (!intel_dp->base.connectors_active) |
| 2020 | return; | 2065 | return; |
| 2021 | 2066 | ||
| 2022 | if (!intel_dp->base.base.crtc) | 2067 | if (WARN_ON(!intel_dp->base.base.crtc)) |
| 2023 | return; | 2068 | return; |
| 2024 | 2069 | ||
| 2025 | /* Try to read receiver status if the link appears to be up */ | 2070 | /* Try to read receiver status if the link appears to be up */ |
| @@ -2305,9 +2350,8 @@ intel_dp_set_property(struct drm_connector *connector, | |||
| 2305 | done: | 2350 | done: |
| 2306 | if (intel_dp->base.base.crtc) { | 2351 | if (intel_dp->base.base.crtc) { |
| 2307 | struct drm_crtc *crtc = intel_dp->base.base.crtc; | 2352 | struct drm_crtc *crtc = intel_dp->base.base.crtc; |
| 2308 | drm_crtc_helper_set_mode(crtc, &crtc->mode, | 2353 | intel_set_mode(crtc, &crtc->mode, |
| 2309 | crtc->x, crtc->y, | 2354 | crtc->x, crtc->y, crtc->fb); |
| 2310 | crtc->fb); | ||
| 2311 | } | 2355 | } |
| 2312 | 2356 | ||
| 2313 | return 0; | 2357 | return 0; |
| @@ -2341,15 +2385,13 @@ static void intel_dp_encoder_destroy(struct drm_encoder *encoder) | |||
| 2341 | } | 2385 | } |
| 2342 | 2386 | ||
| 2343 | static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { | 2387 | static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { |
| 2344 | .dpms = intel_dp_dpms, | ||
| 2345 | .mode_fixup = intel_dp_mode_fixup, | 2388 | .mode_fixup = intel_dp_mode_fixup, |
| 2346 | .prepare = intel_dp_prepare, | ||
| 2347 | .mode_set = intel_dp_mode_set, | 2389 | .mode_set = intel_dp_mode_set, |
| 2348 | .commit = intel_dp_commit, | 2390 | .disable = intel_encoder_noop, |
| 2349 | }; | 2391 | }; |
| 2350 | 2392 | ||
| 2351 | static const struct drm_connector_funcs intel_dp_connector_funcs = { | 2393 | static const struct drm_connector_funcs intel_dp_connector_funcs = { |
| 2352 | .dpms = drm_helper_connector_dpms, | 2394 | .dpms = intel_dp_dpms, |
| 2353 | .detect = intel_dp_detect, | 2395 | .detect = intel_dp_detect, |
| 2354 | .fill_modes = drm_helper_probe_single_connector_modes, | 2396 | .fill_modes = drm_helper_probe_single_connector_modes, |
| 2355 | .set_property = intel_dp_set_property, | 2397 | .set_property = intel_dp_set_property, |
| @@ -2436,7 +2478,6 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) | |||
| 2436 | 2478 | ||
| 2437 | intel_dp->output_reg = output_reg; | 2479 | intel_dp->output_reg = output_reg; |
| 2438 | intel_dp->port = port; | 2480 | intel_dp->port = port; |
| 2439 | intel_dp->dpms_mode = -1; | ||
| 2440 | 2481 | ||
| 2441 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 2482 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
| 2442 | if (!intel_connector) { | 2483 | if (!intel_connector) { |
| @@ -2480,6 +2521,11 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) | |||
| 2480 | intel_connector_attach_encoder(intel_connector, intel_encoder); | 2521 | intel_connector_attach_encoder(intel_connector, intel_encoder); |
| 2481 | drm_sysfs_connector_add(connector); | 2522 | drm_sysfs_connector_add(connector); |
| 2482 | 2523 | ||
| 2524 | intel_encoder->enable = intel_enable_dp; | ||
| 2525 | intel_encoder->disable = intel_disable_dp; | ||
| 2526 | intel_encoder->get_hw_state = intel_dp_get_hw_state; | ||
| 2527 | intel_connector->get_hw_state = intel_connector_get_hw_state; | ||
| 2528 | |||
| 2483 | /* Set up the DDC bus. */ | 2529 | /* Set up the DDC bus. */ |
| 2484 | switch (port) { | 2530 | switch (port) { |
| 2485 | case PORT_A: | 2531 | case PORT_A: |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 3f7eefc5d976..4f2b2d6a2489 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
| @@ -137,6 +137,12 @@ struct intel_fbdev { | |||
| 137 | 137 | ||
| 138 | struct intel_encoder { | 138 | struct intel_encoder { |
| 139 | struct drm_encoder base; | 139 | struct drm_encoder base; |
| 140 | /* | ||
| 141 | * The new crtc this encoder will be driven from. Only differs from | ||
| 142 | * base->crtc while a modeset is in progress. | ||
| 143 | */ | ||
| 144 | struct intel_crtc *new_crtc; | ||
| 145 | |||
| 140 | int type; | 146 | int type; |
| 141 | bool needs_tv_clock; | 147 | bool needs_tv_clock; |
| 142 | /* | 148 | /* |
| @@ -144,13 +150,33 @@ struct intel_encoder { | |||
| 144 | * simple flag is enough to compute the possible_clones mask. | 150 | * simple flag is enough to compute the possible_clones mask. |
| 145 | */ | 151 | */ |
| 146 | bool cloneable; | 152 | bool cloneable; |
| 153 | bool connectors_active; | ||
| 147 | void (*hot_plug)(struct intel_encoder *); | 154 | void (*hot_plug)(struct intel_encoder *); |
| 155 | void (*enable)(struct intel_encoder *); | ||
| 156 | void (*disable)(struct intel_encoder *); | ||
| 157 | /* Read out the current hw state of this connector, returning true if | ||
| 158 | * the encoder is active. If the encoder is enabled it also set the pipe | ||
| 159 | * it is connected to in the pipe parameter. */ | ||
| 160 | bool (*get_hw_state)(struct intel_encoder *, enum pipe *pipe); | ||
| 148 | int crtc_mask; | 161 | int crtc_mask; |
| 149 | }; | 162 | }; |
| 150 | 163 | ||
| 151 | struct intel_connector { | 164 | struct intel_connector { |
| 152 | struct drm_connector base; | 165 | struct drm_connector base; |
| 166 | /* | ||
| 167 | * The fixed encoder this connector is connected to. | ||
| 168 | */ | ||
| 153 | struct intel_encoder *encoder; | 169 | struct intel_encoder *encoder; |
| 170 | |||
| 171 | /* | ||
| 172 | * The new encoder this connector will be driven. Only differs from | ||
| 173 | * encoder while a modeset is in progress. | ||
| 174 | */ | ||
| 175 | struct intel_encoder *new_encoder; | ||
| 176 | |||
| 177 | /* Reads out the current hw, returning true if the connector is enabled | ||
| 178 | * and active (i.e. dpms ON state). */ | ||
| 179 | bool (*get_hw_state)(struct intel_connector *); | ||
| 154 | }; | 180 | }; |
| 155 | 181 | ||
| 156 | struct intel_crtc { | 182 | struct intel_crtc { |
| @@ -158,8 +184,12 @@ struct intel_crtc { | |||
| 158 | enum pipe pipe; | 184 | enum pipe pipe; |
| 159 | enum plane plane; | 185 | enum plane plane; |
| 160 | u8 lut_r[256], lut_g[256], lut_b[256]; | 186 | u8 lut_r[256], lut_g[256], lut_b[256]; |
| 161 | int dpms_mode; | 187 | /* |
| 162 | bool active; /* is the crtc on? independent of the dpms mode */ | 188 | * Whether the crtc and the connected output pipeline is active. Implies |
| 189 | * that crtc->enabled is set, i.e. the current mode configuration has | ||
| 190 | * some outputs connected to this crtc. | ||
| 191 | */ | ||
| 192 | bool active; | ||
| 163 | bool primary_disabled; /* is the crtc obscured by a plane? */ | 193 | bool primary_disabled; /* is the crtc obscured by a plane? */ |
| 164 | bool lowfreq_avail; | 194 | bool lowfreq_avail; |
| 165 | struct intel_overlay *overlay; | 195 | struct intel_overlay *overlay; |
| @@ -311,7 +341,6 @@ struct intel_dp { | |||
| 311 | enum hdmi_force_audio force_audio; | 341 | enum hdmi_force_audio force_audio; |
| 312 | enum port port; | 342 | enum port port; |
| 313 | uint32_t color_range; | 343 | uint32_t color_range; |
| 314 | int dpms_mode; | ||
| 315 | uint8_t link_bw; | 344 | uint8_t link_bw; |
| 316 | uint8_t lane_count; | 345 | uint8_t lane_count; |
| 317 | uint8_t dpcd[DP_RECEIVER_CAP_SIZE]; | 346 | uint8_t dpcd[DP_RECEIVER_CAP_SIZE]; |
| @@ -413,10 +442,27 @@ extern void intel_panel_disable_backlight(struct drm_device *dev); | |||
| 413 | extern void intel_panel_destroy_backlight(struct drm_device *dev); | 442 | extern void intel_panel_destroy_backlight(struct drm_device *dev); |
| 414 | extern enum drm_connector_status intel_panel_detect(struct drm_device *dev); | 443 | extern enum drm_connector_status intel_panel_detect(struct drm_device *dev); |
| 415 | 444 | ||
| 445 | struct intel_set_config { | ||
| 446 | struct drm_encoder **save_connector_encoders; | ||
| 447 | struct drm_crtc **save_encoder_crtcs; | ||
| 448 | |||
| 449 | bool fb_changed; | ||
| 450 | bool mode_changed; | ||
| 451 | }; | ||
| 452 | |||
| 453 | extern bool intel_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode, | ||
| 454 | int x, int y, struct drm_framebuffer *old_fb); | ||
| 455 | extern void intel_modeset_disable(struct drm_device *dev); | ||
| 416 | extern void intel_crtc_load_lut(struct drm_crtc *crtc); | 456 | extern void intel_crtc_load_lut(struct drm_crtc *crtc); |
| 417 | extern void intel_encoder_prepare(struct drm_encoder *encoder); | 457 | extern void intel_crtc_update_dpms(struct drm_crtc *crtc); |
| 418 | extern void intel_encoder_commit(struct drm_encoder *encoder); | 458 | extern void intel_encoder_noop(struct drm_encoder *encoder); |
| 419 | extern void intel_encoder_destroy(struct drm_encoder *encoder); | 459 | extern void intel_encoder_destroy(struct drm_encoder *encoder); |
| 460 | extern void intel_encoder_dpms(struct intel_encoder *encoder, int mode); | ||
| 461 | extern bool intel_encoder_check_is_cloned(struct intel_encoder *encoder); | ||
| 462 | extern void intel_connector_dpms(struct drm_connector *, int mode); | ||
| 463 | extern bool intel_connector_get_hw_state(struct intel_connector *connector); | ||
| 464 | extern void intel_modeset_check_state(struct drm_device *dev); | ||
| 465 | |||
| 420 | 466 | ||
| 421 | static inline struct intel_encoder *intel_attached_encoder(struct drm_connector *connector) | 467 | static inline struct intel_encoder *intel_attached_encoder(struct drm_connector *connector) |
| 422 | { | 468 | { |
| @@ -523,7 +569,10 @@ extern void intel_disable_gt_powersave(struct drm_device *dev); | |||
| 523 | extern void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv); | 569 | extern void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv); |
| 524 | extern void ironlake_teardown_rc6(struct drm_device *dev); | 570 | extern void ironlake_teardown_rc6(struct drm_device *dev); |
| 525 | 571 | ||
| 526 | extern void intel_ddi_dpms(struct drm_encoder *encoder, int mode); | 572 | extern void intel_enable_ddi(struct intel_encoder *encoder); |
| 573 | extern void intel_disable_ddi(struct intel_encoder *encoder); | ||
| 574 | extern bool intel_ddi_get_hw_state(struct intel_encoder *encoder, | ||
| 575 | enum pipe *pipe); | ||
| 527 | extern void intel_ddi_mode_set(struct drm_encoder *encoder, | 576 | extern void intel_ddi_mode_set(struct drm_encoder *encoder, |
| 528 | struct drm_display_mode *mode, | 577 | struct drm_display_mode *mode, |
| 529 | struct drm_display_mode *adjusted_mode); | 578 | struct drm_display_mode *adjusted_mode); |
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 227551f12d25..4f1fdcc44005 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
| @@ -105,22 +105,91 @@ 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 void intel_dvo_dpms(struct drm_encoder *encoder, int mode) | 108 | static bool intel_dvo_connector_get_hw_state(struct intel_connector *connector) |
| 109 | { | 109 | { |
| 110 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; | 110 | struct intel_dvo *intel_dvo = intel_attached_dvo(&connector->base); |
| 111 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); | 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 | |||
| 133 | static void intel_disable_dvo(struct intel_encoder *encoder) | ||
| 134 | { | ||
| 135 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; | ||
| 136 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(&encoder->base); | ||
| 137 | u32 dvo_reg = intel_dvo->dev.dvo_reg; | ||
| 138 | u32 temp = I915_READ(dvo_reg); | ||
| 139 | |||
| 140 | intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, false); | ||
| 141 | I915_WRITE(dvo_reg, temp & ~DVO_ENABLE); | ||
| 142 | I915_READ(dvo_reg); | ||
| 143 | } | ||
| 144 | |||
| 145 | static void intel_enable_dvo(struct intel_encoder *encoder) | ||
| 146 | { | ||
| 147 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; | ||
| 148 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(&encoder->base); | ||
| 112 | u32 dvo_reg = intel_dvo->dev.dvo_reg; | 149 | u32 dvo_reg = intel_dvo->dev.dvo_reg; |
| 113 | u32 temp = I915_READ(dvo_reg); | 150 | u32 temp = I915_READ(dvo_reg); |
| 114 | 151 | ||
| 152 | I915_WRITE(dvo_reg, temp | DVO_ENABLE); | ||
| 153 | I915_READ(dvo_reg); | ||
| 154 | intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true); | ||
| 155 | } | ||
| 156 | |||
| 157 | static void intel_dvo_dpms(struct drm_connector *connector, int mode) | ||
| 158 | { | ||
| 159 | struct intel_dvo *intel_dvo = intel_attached_dvo(connector); | ||
| 160 | struct drm_crtc *crtc; | ||
| 161 | |||
| 162 | /* dvo supports only 2 dpms states. */ | ||
| 163 | if (mode != DRM_MODE_DPMS_ON) | ||
| 164 | mode = DRM_MODE_DPMS_OFF; | ||
| 165 | |||
| 166 | if (mode == connector->dpms) | ||
| 167 | return; | ||
| 168 | |||
| 169 | connector->dpms = mode; | ||
| 170 | |||
| 171 | /* Only need to change hw state when actually enabled */ | ||
| 172 | crtc = intel_dvo->base.base.crtc; | ||
| 173 | if (!crtc) { | ||
| 174 | intel_dvo->base.connectors_active = false; | ||
| 175 | return; | ||
| 176 | } | ||
| 177 | |||
| 115 | if (mode == DRM_MODE_DPMS_ON) { | 178 | if (mode == DRM_MODE_DPMS_ON) { |
| 116 | I915_WRITE(dvo_reg, temp | DVO_ENABLE); | 179 | intel_dvo->base.connectors_active = true; |
| 117 | I915_READ(dvo_reg); | 180 | |
| 181 | intel_crtc_update_dpms(crtc); | ||
| 182 | |||
| 118 | intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true); | 183 | intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true); |
| 119 | } else { | 184 | } else { |
| 120 | intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, false); | 185 | intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, false); |
| 121 | I915_WRITE(dvo_reg, temp & ~DVO_ENABLE); | 186 | |
| 122 | I915_READ(dvo_reg); | 187 | intel_dvo->base.connectors_active = false; |
| 188 | |||
| 189 | intel_crtc_update_dpms(crtc); | ||
| 123 | } | 190 | } |
| 191 | |||
| 192 | intel_modeset_check_state(connector->dev); | ||
| 124 | } | 193 | } |
| 125 | 194 | ||
| 126 | static int intel_dvo_mode_valid(struct drm_connector *connector, | 195 | static int intel_dvo_mode_valid(struct drm_connector *connector, |
| @@ -275,15 +344,13 @@ static void intel_dvo_destroy(struct drm_connector *connector) | |||
| 275 | } | 344 | } |
| 276 | 345 | ||
| 277 | static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = { | 346 | static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = { |
| 278 | .dpms = intel_dvo_dpms, | ||
| 279 | .mode_fixup = intel_dvo_mode_fixup, | 347 | .mode_fixup = intel_dvo_mode_fixup, |
| 280 | .prepare = intel_encoder_prepare, | ||
| 281 | .mode_set = intel_dvo_mode_set, | 348 | .mode_set = intel_dvo_mode_set, |
| 282 | .commit = intel_encoder_commit, | 349 | .disable = intel_encoder_noop, |
| 283 | }; | 350 | }; |
| 284 | 351 | ||
| 285 | static const struct drm_connector_funcs intel_dvo_connector_funcs = { | 352 | static const struct drm_connector_funcs intel_dvo_connector_funcs = { |
| 286 | .dpms = drm_helper_connector_dpms, | 353 | .dpms = intel_dvo_dpms, |
| 287 | .detect = intel_dvo_detect, | 354 | .detect = intel_dvo_detect, |
| 288 | .destroy = intel_dvo_destroy, | 355 | .destroy = intel_dvo_destroy, |
| 289 | .fill_modes = drm_helper_probe_single_connector_modes, | 356 | .fill_modes = drm_helper_probe_single_connector_modes, |
| @@ -372,6 +439,11 @@ void intel_dvo_init(struct drm_device *dev) | |||
| 372 | drm_encoder_init(dev, &intel_encoder->base, | 439 | drm_encoder_init(dev, &intel_encoder->base, |
| 373 | &intel_dvo_enc_funcs, encoder_type); | 440 | &intel_dvo_enc_funcs, encoder_type); |
| 374 | 441 | ||
| 442 | intel_encoder->disable = intel_disable_dvo; | ||
| 443 | intel_encoder->enable = intel_enable_dvo; | ||
| 444 | intel_encoder->get_hw_state = intel_dvo_get_hw_state; | ||
| 445 | intel_connector->get_hw_state = intel_dvo_connector_get_hw_state; | ||
| 446 | |||
| 375 | /* Now, try to find a controller */ | 447 | /* Now, try to find a controller */ |
| 376 | for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { | 448 | for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { |
| 377 | struct drm_connector *connector = &intel_connector->base; | 449 | struct drm_connector *connector = &intel_connector->base; |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 35a6ee7a8cca..5d02aad0de8e 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
| @@ -601,11 +601,32 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, | |||
| 601 | intel_hdmi->set_infoframes(encoder, adjusted_mode); | 601 | intel_hdmi->set_infoframes(encoder, adjusted_mode); |
| 602 | } | 602 | } |
| 603 | 603 | ||
| 604 | static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) | 604 | static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder, |
| 605 | enum pipe *pipe) | ||
| 605 | { | 606 | { |
| 606 | struct drm_device *dev = encoder->dev; | 607 | struct drm_device *dev = encoder->base.dev; |
| 607 | struct drm_i915_private *dev_priv = dev->dev_private; | 608 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 608 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | 609 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); |
| 610 | u32 tmp; | ||
| 611 | |||
| 612 | tmp = I915_READ(intel_hdmi->sdvox_reg); | ||
| 613 | |||
| 614 | if (!(tmp & SDVO_ENABLE)) | ||
| 615 | return false; | ||
| 616 | |||
| 617 | if (HAS_PCH_CPT(dev)) | ||
| 618 | *pipe = PORT_TO_PIPE_CPT(tmp); | ||
| 619 | else | ||
| 620 | *pipe = PORT_TO_PIPE(tmp); | ||
| 621 | |||
| 622 | return true; | ||
| 623 | } | ||
| 624 | |||
| 625 | static void intel_enable_hdmi(struct intel_encoder *encoder) | ||
| 626 | { | ||
| 627 | struct drm_device *dev = encoder->base.dev; | ||
| 628 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 629 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); | ||
| 609 | u32 temp; | 630 | u32 temp; |
| 610 | u32 enable_bits = SDVO_ENABLE; | 631 | u32 enable_bits = SDVO_ENABLE; |
| 611 | 632 | ||
| @@ -617,31 +638,12 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) | |||
| 617 | /* HW workaround for IBX, we need to move the port to transcoder A | 638 | /* HW workaround for IBX, we need to move the port to transcoder A |
| 618 | * before disabling it. */ | 639 | * before disabling it. */ |
| 619 | if (HAS_PCH_IBX(dev)) { | 640 | if (HAS_PCH_IBX(dev)) { |
| 620 | struct drm_crtc *crtc = encoder->crtc; | 641 | struct drm_crtc *crtc = encoder->base.crtc; |
| 621 | int pipe = crtc ? to_intel_crtc(crtc)->pipe : -1; | 642 | int pipe = crtc ? to_intel_crtc(crtc)->pipe : -1; |
| 622 | 643 | ||
| 623 | if (mode != DRM_MODE_DPMS_ON) { | 644 | /* Restore the transcoder select bit. */ |
| 624 | if (temp & SDVO_PIPE_B_SELECT) { | 645 | if (pipe == PIPE_B) |
| 625 | temp &= ~SDVO_PIPE_B_SELECT; | 646 | enable_bits |= SDVO_PIPE_B_SELECT; |
| 626 | I915_WRITE(intel_hdmi->sdvox_reg, temp); | ||
| 627 | POSTING_READ(intel_hdmi->sdvox_reg); | ||
| 628 | |||
| 629 | /* Again we need to write this twice. */ | ||
| 630 | I915_WRITE(intel_hdmi->sdvox_reg, temp); | ||
| 631 | POSTING_READ(intel_hdmi->sdvox_reg); | ||
| 632 | |||
| 633 | /* Transcoder selection bits only update | ||
| 634 | * effectively on vblank. */ | ||
| 635 | if (crtc) | ||
| 636 | intel_wait_for_vblank(dev, pipe); | ||
| 637 | else | ||
| 638 | msleep(50); | ||
| 639 | } | ||
| 640 | } else { | ||
| 641 | /* Restore the transcoder select bit. */ | ||
| 642 | if (pipe == PIPE_B) | ||
| 643 | enable_bits |= SDVO_PIPE_B_SELECT; | ||
| 644 | } | ||
| 645 | } | 647 | } |
| 646 | 648 | ||
| 647 | /* HW workaround, need to toggle enable bit off and on for 12bpc, but | 649 | /* HW workaround, need to toggle enable bit off and on for 12bpc, but |
| @@ -652,11 +654,66 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) | |||
| 652 | POSTING_READ(intel_hdmi->sdvox_reg); | 654 | POSTING_READ(intel_hdmi->sdvox_reg); |
| 653 | } | 655 | } |
| 654 | 656 | ||
| 655 | if (mode != DRM_MODE_DPMS_ON) { | 657 | temp |= enable_bits; |
| 656 | temp &= ~enable_bits; | 658 | |
| 657 | } else { | 659 | I915_WRITE(intel_hdmi->sdvox_reg, temp); |
| 658 | temp |= enable_bits; | 660 | POSTING_READ(intel_hdmi->sdvox_reg); |
| 661 | |||
| 662 | /* HW workaround, need to write this twice for issue that may result | ||
| 663 | * in first write getting masked. | ||
| 664 | */ | ||
| 665 | if (HAS_PCH_SPLIT(dev)) { | ||
| 666 | I915_WRITE(intel_hdmi->sdvox_reg, temp); | ||
| 667 | POSTING_READ(intel_hdmi->sdvox_reg); | ||
| 659 | } | 668 | } |
| 669 | } | ||
| 670 | |||
| 671 | static void intel_disable_hdmi(struct intel_encoder *encoder) | ||
| 672 | { | ||
| 673 | struct drm_device *dev = encoder->base.dev; | ||
| 674 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 675 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); | ||
| 676 | u32 temp; | ||
| 677 | u32 enable_bits = SDVO_ENABLE; | ||
| 678 | |||
| 679 | if (intel_hdmi->has_audio) | ||
| 680 | enable_bits |= SDVO_AUDIO_ENABLE; | ||
| 681 | |||
| 682 | temp = I915_READ(intel_hdmi->sdvox_reg); | ||
| 683 | |||
| 684 | /* HW workaround for IBX, we need to move the port to transcoder A | ||
| 685 | * before disabling it. */ | ||
| 686 | if (HAS_PCH_IBX(dev)) { | ||
| 687 | struct drm_crtc *crtc = encoder->base.crtc; | ||
| 688 | int pipe = crtc ? to_intel_crtc(crtc)->pipe : -1; | ||
| 689 | |||
| 690 | if (temp & SDVO_PIPE_B_SELECT) { | ||
| 691 | temp &= ~SDVO_PIPE_B_SELECT; | ||
| 692 | I915_WRITE(intel_hdmi->sdvox_reg, temp); | ||
| 693 | POSTING_READ(intel_hdmi->sdvox_reg); | ||
| 694 | |||
| 695 | /* Again we need to write this twice. */ | ||
| 696 | I915_WRITE(intel_hdmi->sdvox_reg, temp); | ||
| 697 | POSTING_READ(intel_hdmi->sdvox_reg); | ||
| 698 | |||
| 699 | /* Transcoder selection bits only update | ||
| 700 | * effectively on vblank. */ | ||
| 701 | if (crtc) | ||
| 702 | intel_wait_for_vblank(dev, pipe); | ||
| 703 | else | ||
| 704 | msleep(50); | ||
| 705 | } | ||
| 706 | } | ||
| 707 | |||
| 708 | /* HW workaround, need to toggle enable bit off and on for 12bpc, but | ||
| 709 | * we do this anyway which shows more stable in testing. | ||
| 710 | */ | ||
| 711 | if (HAS_PCH_SPLIT(dev)) { | ||
| 712 | I915_WRITE(intel_hdmi->sdvox_reg, temp & ~SDVO_ENABLE); | ||
| 713 | POSTING_READ(intel_hdmi->sdvox_reg); | ||
| 714 | } | ||
| 715 | |||
| 716 | temp &= ~enable_bits; | ||
| 660 | 717 | ||
| 661 | I915_WRITE(intel_hdmi->sdvox_reg, temp); | 718 | I915_WRITE(intel_hdmi->sdvox_reg, temp); |
| 662 | POSTING_READ(intel_hdmi->sdvox_reg); | 719 | POSTING_READ(intel_hdmi->sdvox_reg); |
| @@ -830,9 +887,8 @@ intel_hdmi_set_property(struct drm_connector *connector, | |||
| 830 | done: | 887 | done: |
| 831 | if (intel_hdmi->base.base.crtc) { | 888 | if (intel_hdmi->base.base.crtc) { |
| 832 | struct drm_crtc *crtc = intel_hdmi->base.base.crtc; | 889 | struct drm_crtc *crtc = intel_hdmi->base.base.crtc; |
| 833 | drm_crtc_helper_set_mode(crtc, &crtc->mode, | 890 | intel_set_mode(crtc, &crtc->mode, |
| 834 | crtc->x, crtc->y, | 891 | crtc->x, crtc->y, crtc->fb); |
| 835 | crtc->fb); | ||
| 836 | } | 892 | } |
| 837 | 893 | ||
| 838 | return 0; | 894 | return 0; |
| @@ -846,23 +902,19 @@ static void intel_hdmi_destroy(struct drm_connector *connector) | |||
| 846 | } | 902 | } |
| 847 | 903 | ||
| 848 | static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs_hsw = { | 904 | static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs_hsw = { |
| 849 | .dpms = intel_ddi_dpms, | ||
| 850 | .mode_fixup = intel_hdmi_mode_fixup, | 905 | .mode_fixup = intel_hdmi_mode_fixup, |
| 851 | .prepare = intel_encoder_prepare, | ||
| 852 | .mode_set = intel_ddi_mode_set, | 906 | .mode_set = intel_ddi_mode_set, |
| 853 | .commit = intel_encoder_commit, | 907 | .disable = intel_encoder_noop, |
| 854 | }; | 908 | }; |
| 855 | 909 | ||
| 856 | static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = { | 910 | static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = { |
| 857 | .dpms = intel_hdmi_dpms, | ||
| 858 | .mode_fixup = intel_hdmi_mode_fixup, | 911 | .mode_fixup = intel_hdmi_mode_fixup, |
| 859 | .prepare = intel_encoder_prepare, | ||
| 860 | .mode_set = intel_hdmi_mode_set, | 912 | .mode_set = intel_hdmi_mode_set, |
| 861 | .commit = intel_encoder_commit, | 913 | .disable = intel_encoder_noop, |
| 862 | }; | 914 | }; |
| 863 | 915 | ||
| 864 | static const struct drm_connector_funcs intel_hdmi_connector_funcs = { | 916 | static const struct drm_connector_funcs intel_hdmi_connector_funcs = { |
| 865 | .dpms = drm_helper_connector_dpms, | 917 | .dpms = intel_connector_dpms, |
| 866 | .detect = intel_hdmi_detect, | 918 | .detect = intel_hdmi_detect, |
| 867 | .fill_modes = drm_helper_probe_single_connector_modes, | 919 | .fill_modes = drm_helper_probe_single_connector_modes, |
| 868 | .set_property = intel_hdmi_set_property, | 920 | .set_property = intel_hdmi_set_property, |
| @@ -961,10 +1013,21 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg, enum port port) | |||
| 961 | intel_hdmi->set_infoframes = cpt_set_infoframes; | 1013 | intel_hdmi->set_infoframes = cpt_set_infoframes; |
| 962 | } | 1014 | } |
| 963 | 1015 | ||
| 964 | if (IS_HASWELL(dev)) | 1016 | if (IS_HASWELL(dev)) { |
| 965 | drm_encoder_helper_add(&intel_encoder->base, &intel_hdmi_helper_funcs_hsw); | 1017 | intel_encoder->enable = intel_enable_ddi; |
| 966 | else | 1018 | intel_encoder->disable = intel_disable_ddi; |
| 967 | drm_encoder_helper_add(&intel_encoder->base, &intel_hdmi_helper_funcs); | 1019 | intel_encoder->get_hw_state = intel_ddi_get_hw_state; |
| 1020 | drm_encoder_helper_add(&intel_encoder->base, | ||
| 1021 | &intel_hdmi_helper_funcs_hsw); | ||
| 1022 | } else { | ||
| 1023 | intel_encoder->enable = intel_enable_hdmi; | ||
| 1024 | intel_encoder->disable = intel_disable_hdmi; | ||
| 1025 | intel_encoder->get_hw_state = intel_hdmi_get_hw_state; | ||
| 1026 | drm_encoder_helper_add(&intel_encoder->base, | ||
| 1027 | &intel_hdmi_helper_funcs); | ||
| 1028 | } | ||
| 1029 | intel_connector->get_hw_state = intel_connector_get_hw_state; | ||
| 1030 | |||
| 968 | 1031 | ||
| 969 | intel_hdmi_add_properties(intel_hdmi, connector); | 1032 | intel_hdmi_add_properties(intel_hdmi, connector); |
| 970 | 1033 | ||
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index d789fdad5d37..564689554989 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
| @@ -65,13 +65,40 @@ static struct intel_lvds *intel_attached_lvds(struct drm_connector *connector) | |||
| 65 | struct intel_lvds, base); | 65 | struct intel_lvds, base); |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | static bool intel_lvds_get_hw_state(struct intel_encoder *encoder, | ||
| 69 | enum pipe *pipe) | ||
| 70 | { | ||
| 71 | struct drm_device *dev = encoder->base.dev; | ||
| 72 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 73 | u32 lvds_reg, tmp; | ||
| 74 | |||
| 75 | if (HAS_PCH_SPLIT(dev)) { | ||
| 76 | lvds_reg = PCH_LVDS; | ||
| 77 | } else { | ||
| 78 | lvds_reg = LVDS; | ||
| 79 | } | ||
| 80 | |||
| 81 | tmp = I915_READ(lvds_reg); | ||
| 82 | |||
| 83 | if (!(tmp & LVDS_PORT_EN)) | ||
| 84 | return false; | ||
| 85 | |||
| 86 | if (HAS_PCH_CPT(dev)) | ||
| 87 | *pipe = PORT_TO_PIPE_CPT(tmp); | ||
| 88 | else | ||
| 89 | *pipe = PORT_TO_PIPE(tmp); | ||
| 90 | |||
| 91 | return true; | ||
| 92 | } | ||
| 93 | |||
| 68 | /** | 94 | /** |
| 69 | * Sets the power state for the panel. | 95 | * Sets the power state for the panel. |
| 70 | */ | 96 | */ |
| 71 | static void intel_lvds_enable(struct intel_lvds *intel_lvds) | 97 | static void intel_enable_lvds(struct intel_encoder *encoder) |
| 72 | { | 98 | { |
| 73 | struct drm_device *dev = intel_lvds->base.base.dev; | 99 | struct drm_device *dev = encoder->base.dev; |
| 74 | struct intel_crtc *intel_crtc = to_intel_crtc(intel_lvds->base.base.crtc); | 100 | struct intel_lvds *intel_lvds = to_intel_lvds(&encoder->base); |
| 101 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); | ||
| 75 | struct drm_i915_private *dev_priv = dev->dev_private; | 102 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 76 | u32 ctl_reg, lvds_reg, stat_reg; | 103 | u32 ctl_reg, lvds_reg, stat_reg; |
| 77 | 104 | ||
| @@ -111,9 +138,10 @@ static void intel_lvds_enable(struct intel_lvds *intel_lvds) | |||
| 111 | intel_panel_enable_backlight(dev, intel_crtc->pipe); | 138 | intel_panel_enable_backlight(dev, intel_crtc->pipe); |
| 112 | } | 139 | } |
| 113 | 140 | ||
| 114 | static void intel_lvds_disable(struct intel_lvds *intel_lvds) | 141 | static void intel_disable_lvds(struct intel_encoder *encoder) |
| 115 | { | 142 | { |
| 116 | struct drm_device *dev = intel_lvds->base.base.dev; | 143 | struct drm_device *dev = encoder->base.dev; |
| 144 | struct intel_lvds *intel_lvds = to_intel_lvds(&encoder->base); | ||
| 117 | struct drm_i915_private *dev_priv = dev->dev_private; | 145 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 118 | u32 ctl_reg, lvds_reg, stat_reg; | 146 | u32 ctl_reg, lvds_reg, stat_reg; |
| 119 | 147 | ||
| @@ -142,18 +170,6 @@ static void intel_lvds_disable(struct intel_lvds *intel_lvds) | |||
| 142 | POSTING_READ(lvds_reg); | 170 | POSTING_READ(lvds_reg); |
| 143 | } | 171 | } |
| 144 | 172 | ||
| 145 | static void intel_lvds_dpms(struct drm_encoder *encoder, int mode) | ||
| 146 | { | ||
| 147 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); | ||
| 148 | |||
| 149 | if (mode == DRM_MODE_DPMS_ON) | ||
| 150 | intel_lvds_enable(intel_lvds); | ||
| 151 | else | ||
| 152 | intel_lvds_disable(intel_lvds); | ||
| 153 | |||
| 154 | /* XXX: We never power down the LVDS pairs. */ | ||
| 155 | } | ||
| 156 | |||
| 157 | static int intel_lvds_mode_valid(struct drm_connector *connector, | 173 | static int intel_lvds_mode_valid(struct drm_connector *connector, |
| 158 | struct drm_display_mode *mode) | 174 | struct drm_display_mode *mode) |
| 159 | { | 175 | { |
| @@ -234,9 +250,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
| 234 | { | 250 | { |
| 235 | struct drm_device *dev = encoder->dev; | 251 | struct drm_device *dev = encoder->dev; |
| 236 | struct drm_i915_private *dev_priv = dev->dev_private; | 252 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 237 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | ||
| 238 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); | 253 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); |
| 239 | struct intel_encoder *tmp_encoder; | 254 | struct intel_crtc *intel_crtc = intel_lvds->base.new_crtc; |
| 240 | u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; | 255 | u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; |
| 241 | int pipe; | 256 | int pipe; |
| 242 | 257 | ||
| @@ -246,14 +261,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
| 246 | return false; | 261 | return false; |
| 247 | } | 262 | } |
| 248 | 263 | ||
| 249 | /* Should never happen!! */ | 264 | if (intel_encoder_check_is_cloned(&intel_lvds->base)) |
| 250 | for_each_encoder_on_crtc(dev, encoder->crtc, tmp_encoder) { | 265 | return false; |
| 251 | if (&tmp_encoder->base != encoder) { | ||
| 252 | DRM_ERROR("Can't enable LVDS and another " | ||
| 253 | "encoder on the same pipe\n"); | ||
| 254 | return false; | ||
| 255 | } | ||
| 256 | } | ||
| 257 | 266 | ||
| 258 | /* | 267 | /* |
| 259 | * We have timings from the BIOS for the panel, put them in | 268 | * We have timings from the BIOS for the panel, put them in |
| @@ -405,23 +414,6 @@ out: | |||
| 405 | return true; | 414 | return true; |
| 406 | } | 415 | } |
| 407 | 416 | ||
| 408 | static void intel_lvds_prepare(struct drm_encoder *encoder) | ||
| 409 | { | ||
| 410 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); | ||
| 411 | |||
| 412 | intel_lvds_disable(intel_lvds); | ||
| 413 | } | ||
| 414 | |||
| 415 | static void intel_lvds_commit(struct drm_encoder *encoder) | ||
| 416 | { | ||
| 417 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); | ||
| 418 | |||
| 419 | /* Always do a full power on as we do not know what state | ||
| 420 | * we were left in. | ||
| 421 | */ | ||
| 422 | intel_lvds_enable(intel_lvds); | ||
| 423 | } | ||
| 424 | |||
| 425 | static void intel_lvds_mode_set(struct drm_encoder *encoder, | 417 | static void intel_lvds_mode_set(struct drm_encoder *encoder, |
| 426 | struct drm_display_mode *mode, | 418 | struct drm_display_mode *mode, |
| 427 | struct drm_display_mode *adjusted_mode) | 419 | struct drm_display_mode *adjusted_mode) |
| @@ -587,8 +579,8 @@ static int intel_lvds_set_property(struct drm_connector *connector, | |||
| 587 | * If the CRTC is enabled, the display will be changed | 579 | * If the CRTC is enabled, the display will be changed |
| 588 | * according to the new panel fitting mode. | 580 | * according to the new panel fitting mode. |
| 589 | */ | 581 | */ |
| 590 | drm_crtc_helper_set_mode(crtc, &crtc->mode, | 582 | intel_set_mode(crtc, &crtc->mode, |
| 591 | crtc->x, crtc->y, crtc->fb); | 583 | crtc->x, crtc->y, crtc->fb); |
| 592 | } | 584 | } |
| 593 | } | 585 | } |
| 594 | 586 | ||
| @@ -596,11 +588,9 @@ static int intel_lvds_set_property(struct drm_connector *connector, | |||
| 596 | } | 588 | } |
| 597 | 589 | ||
| 598 | static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = { | 590 | static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = { |
| 599 | .dpms = intel_lvds_dpms, | ||
| 600 | .mode_fixup = intel_lvds_mode_fixup, | 591 | .mode_fixup = intel_lvds_mode_fixup, |
| 601 | .prepare = intel_lvds_prepare, | ||
| 602 | .mode_set = intel_lvds_mode_set, | 592 | .mode_set = intel_lvds_mode_set, |
| 603 | .commit = intel_lvds_commit, | 593 | .disable = intel_encoder_noop, |
| 604 | }; | 594 | }; |
| 605 | 595 | ||
| 606 | static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = { | 596 | static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = { |
| @@ -610,7 +600,7 @@ static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs | |||
| 610 | }; | 600 | }; |
| 611 | 601 | ||
| 612 | static const struct drm_connector_funcs intel_lvds_connector_funcs = { | 602 | static const struct drm_connector_funcs intel_lvds_connector_funcs = { |
| 613 | .dpms = drm_helper_connector_dpms, | 603 | .dpms = intel_connector_dpms, |
| 614 | .detect = intel_lvds_detect, | 604 | .detect = intel_lvds_detect, |
| 615 | .fill_modes = drm_helper_probe_single_connector_modes, | 605 | .fill_modes = drm_helper_probe_single_connector_modes, |
| 616 | .set_property = intel_lvds_set_property, | 606 | .set_property = intel_lvds_set_property, |
| @@ -964,6 +954,11 @@ bool intel_lvds_init(struct drm_device *dev) | |||
| 964 | drm_encoder_init(dev, &intel_encoder->base, &intel_lvds_enc_funcs, | 954 | drm_encoder_init(dev, &intel_encoder->base, &intel_lvds_enc_funcs, |
| 965 | DRM_MODE_ENCODER_LVDS); | 955 | DRM_MODE_ENCODER_LVDS); |
| 966 | 956 | ||
| 957 | intel_encoder->enable = intel_enable_lvds; | ||
| 958 | intel_encoder->disable = intel_disable_lvds; | ||
| 959 | intel_encoder->get_hw_state = intel_lvds_get_hw_state; | ||
| 960 | intel_connector->get_hw_state = intel_connector_get_hw_state; | ||
| 961 | |||
| 967 | intel_connector_attach_encoder(intel_connector, intel_encoder); | 962 | intel_connector_attach_encoder(intel_connector, intel_encoder); |
| 968 | intel_encoder->type = INTEL_OUTPUT_LVDS; | 963 | intel_encoder->type = INTEL_OUTPUT_LVDS; |
| 969 | 964 | ||
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 6c9a85759bc3..39c319827f91 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
| @@ -628,6 +628,14 @@ static bool intel_sdvo_set_active_outputs(struct intel_sdvo *intel_sdvo, | |||
| 628 | &outputs, sizeof(outputs)); | 628 | &outputs, sizeof(outputs)); |
| 629 | } | 629 | } |
| 630 | 630 | ||
| 631 | static bool intel_sdvo_get_active_outputs(struct intel_sdvo *intel_sdvo, | ||
| 632 | u16 *outputs) | ||
| 633 | { | ||
| 634 | return intel_sdvo_get_value(intel_sdvo, | ||
| 635 | SDVO_CMD_GET_ACTIVE_OUTPUTS, | ||
| 636 | outputs, sizeof(*outputs)); | ||
| 637 | } | ||
| 638 | |||
| 631 | static bool intel_sdvo_set_encoder_power_state(struct intel_sdvo *intel_sdvo, | 639 | static bool intel_sdvo_set_encoder_power_state(struct intel_sdvo *intel_sdvo, |
| 632 | int mode) | 640 | int mode) |
| 633 | { | 641 | { |
| @@ -1142,51 +1150,132 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
| 1142 | intel_sdvo_write_sdvox(intel_sdvo, sdvox); | 1150 | intel_sdvo_write_sdvox(intel_sdvo, sdvox); |
| 1143 | } | 1151 | } |
| 1144 | 1152 | ||
| 1145 | static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) | 1153 | static bool intel_sdvo_connector_get_hw_state(struct intel_connector *connector) |
| 1146 | { | 1154 | { |
| 1147 | struct drm_device *dev = encoder->dev; | 1155 | struct intel_sdvo_connector *intel_sdvo_connector = |
| 1156 | to_intel_sdvo_connector(&connector->base); | ||
| 1157 | struct intel_sdvo *intel_sdvo = intel_attached_sdvo(&connector->base); | ||
| 1158 | u16 active_outputs; | ||
| 1159 | |||
| 1160 | intel_sdvo_get_active_outputs(intel_sdvo, &active_outputs); | ||
| 1161 | |||
| 1162 | if (active_outputs & intel_sdvo_connector->output_flag) | ||
| 1163 | return true; | ||
| 1164 | else | ||
| 1165 | return false; | ||
| 1166 | } | ||
| 1167 | |||
| 1168 | static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder, | ||
| 1169 | enum pipe *pipe) | ||
| 1170 | { | ||
| 1171 | struct drm_device *dev = encoder->base.dev; | ||
| 1148 | struct drm_i915_private *dev_priv = dev->dev_private; | 1172 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1149 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); | 1173 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); |
| 1150 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | 1174 | u32 tmp; |
| 1175 | |||
| 1176 | tmp = I915_READ(intel_sdvo->sdvo_reg); | ||
| 1177 | |||
| 1178 | if (!(tmp & SDVO_ENABLE)) | ||
| 1179 | return false; | ||
| 1180 | |||
| 1181 | if (HAS_PCH_CPT(dev)) | ||
| 1182 | *pipe = PORT_TO_PIPE_CPT(tmp); | ||
| 1183 | else | ||
| 1184 | *pipe = PORT_TO_PIPE(tmp); | ||
| 1185 | |||
| 1186 | return true; | ||
| 1187 | } | ||
| 1188 | |||
| 1189 | static void intel_disable_sdvo(struct intel_encoder *encoder) | ||
| 1190 | { | ||
| 1191 | struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; | ||
| 1192 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); | ||
| 1193 | u32 temp; | ||
| 1194 | |||
| 1195 | intel_sdvo_set_active_outputs(intel_sdvo, 0); | ||
| 1196 | if (0) | ||
| 1197 | intel_sdvo_set_encoder_power_state(intel_sdvo, | ||
| 1198 | DRM_MODE_DPMS_OFF); | ||
| 1199 | |||
| 1200 | temp = I915_READ(intel_sdvo->sdvo_reg); | ||
| 1201 | if ((temp & SDVO_ENABLE) != 0) { | ||
| 1202 | intel_sdvo_write_sdvox(intel_sdvo, temp & ~SDVO_ENABLE); | ||
| 1203 | } | ||
| 1204 | } | ||
| 1205 | |||
| 1206 | static void intel_enable_sdvo(struct intel_encoder *encoder) | ||
| 1207 | { | ||
| 1208 | struct drm_device *dev = encoder->base.dev; | ||
| 1209 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 1210 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(&encoder->base); | ||
| 1211 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); | ||
| 1151 | u32 temp; | 1212 | u32 temp; |
| 1213 | bool input1, input2; | ||
| 1214 | int i; | ||
| 1215 | u8 status; | ||
| 1216 | |||
| 1217 | temp = I915_READ(intel_sdvo->sdvo_reg); | ||
| 1218 | if ((temp & SDVO_ENABLE) == 0) | ||
| 1219 | intel_sdvo_write_sdvox(intel_sdvo, temp | SDVO_ENABLE); | ||
| 1220 | for (i = 0; i < 2; i++) | ||
| 1221 | intel_wait_for_vblank(dev, intel_crtc->pipe); | ||
| 1222 | |||
| 1223 | status = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, &input2); | ||
| 1224 | /* Warn if the device reported failure to sync. | ||
| 1225 | * A lot of SDVO devices fail to notify of sync, but it's | ||
| 1226 | * a given it the status is a success, we succeeded. | ||
| 1227 | */ | ||
| 1228 | if (status == SDVO_CMD_STATUS_SUCCESS && !input1) { | ||
| 1229 | DRM_DEBUG_KMS("First %s output reported failure to " | ||
| 1230 | "sync\n", SDVO_NAME(intel_sdvo)); | ||
| 1231 | } | ||
| 1232 | |||
| 1233 | if (0) | ||
| 1234 | intel_sdvo_set_encoder_power_state(intel_sdvo, | ||
| 1235 | DRM_MODE_DPMS_ON); | ||
| 1236 | intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output); | ||
| 1237 | } | ||
| 1238 | |||
| 1239 | static void intel_sdvo_dpms(struct drm_connector *connector, int mode) | ||
| 1240 | { | ||
| 1241 | struct drm_crtc *crtc; | ||
| 1242 | struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); | ||
| 1243 | |||
| 1244 | /* dvo supports only 2 dpms states. */ | ||
| 1245 | if (mode != DRM_MODE_DPMS_ON) | ||
| 1246 | mode = DRM_MODE_DPMS_OFF; | ||
| 1247 | |||
| 1248 | if (mode == connector->dpms) | ||
| 1249 | return; | ||
| 1250 | |||
| 1251 | connector->dpms = mode; | ||
| 1252 | |||
| 1253 | /* Only need to change hw state when actually enabled */ | ||
| 1254 | crtc = intel_sdvo->base.base.crtc; | ||
| 1255 | if (!crtc) { | ||
| 1256 | intel_sdvo->base.connectors_active = false; | ||
| 1257 | return; | ||
| 1258 | } | ||
| 1152 | 1259 | ||
| 1153 | if (mode != DRM_MODE_DPMS_ON) { | 1260 | if (mode != DRM_MODE_DPMS_ON) { |
| 1154 | intel_sdvo_set_active_outputs(intel_sdvo, 0); | 1261 | intel_sdvo_set_active_outputs(intel_sdvo, 0); |
| 1155 | if (0) | 1262 | if (0) |
| 1156 | intel_sdvo_set_encoder_power_state(intel_sdvo, mode); | 1263 | intel_sdvo_set_encoder_power_state(intel_sdvo, mode); |
| 1157 | 1264 | ||
| 1158 | if (mode == DRM_MODE_DPMS_OFF) { | 1265 | intel_sdvo->base.connectors_active = false; |
| 1159 | temp = I915_READ(intel_sdvo->sdvo_reg); | 1266 | |
| 1160 | if ((temp & SDVO_ENABLE) != 0) { | 1267 | intel_crtc_update_dpms(crtc); |
| 1161 | intel_sdvo_write_sdvox(intel_sdvo, temp & ~SDVO_ENABLE); | ||
| 1162 | } | ||
| 1163 | } | ||
| 1164 | } else { | 1268 | } else { |
| 1165 | bool input1, input2; | 1269 | intel_sdvo->base.connectors_active = true; |
| 1166 | int i; | 1270 | |
| 1167 | u8 status; | 1271 | intel_crtc_update_dpms(crtc); |
| 1168 | |||
| 1169 | temp = I915_READ(intel_sdvo->sdvo_reg); | ||
| 1170 | if ((temp & SDVO_ENABLE) == 0) | ||
| 1171 | intel_sdvo_write_sdvox(intel_sdvo, temp | SDVO_ENABLE); | ||
| 1172 | for (i = 0; i < 2; i++) | ||
| 1173 | intel_wait_for_vblank(dev, intel_crtc->pipe); | ||
| 1174 | |||
| 1175 | status = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, &input2); | ||
| 1176 | /* Warn if the device reported failure to sync. | ||
| 1177 | * A lot of SDVO devices fail to notify of sync, but it's | ||
| 1178 | * a given it the status is a success, we succeeded. | ||
| 1179 | */ | ||
| 1180 | if (status == SDVO_CMD_STATUS_SUCCESS && !input1) { | ||
| 1181 | DRM_DEBUG_KMS("First %s output reported failure to " | ||
| 1182 | "sync\n", SDVO_NAME(intel_sdvo)); | ||
| 1183 | } | ||
| 1184 | 1272 | ||
| 1185 | if (0) | 1273 | if (0) |
| 1186 | intel_sdvo_set_encoder_power_state(intel_sdvo, mode); | 1274 | intel_sdvo_set_encoder_power_state(intel_sdvo, mode); |
| 1187 | intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output); | 1275 | intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output); |
| 1188 | } | 1276 | } |
| 1189 | return; | 1277 | |
| 1278 | intel_modeset_check_state(connector->dev); | ||
| 1190 | } | 1279 | } |
| 1191 | 1280 | ||
| 1192 | static int intel_sdvo_mode_valid(struct drm_connector *connector, | 1281 | static int intel_sdvo_mode_valid(struct drm_connector *connector, |
| @@ -1838,8 +1927,8 @@ set_value: | |||
| 1838 | done: | 1927 | done: |
| 1839 | if (intel_sdvo->base.base.crtc) { | 1928 | if (intel_sdvo->base.base.crtc) { |
| 1840 | struct drm_crtc *crtc = intel_sdvo->base.base.crtc; | 1929 | struct drm_crtc *crtc = intel_sdvo->base.base.crtc; |
| 1841 | drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, | 1930 | intel_set_mode(crtc, &crtc->mode, |
| 1842 | crtc->y, crtc->fb); | 1931 | crtc->x, crtc->y, crtc->fb); |
| 1843 | } | 1932 | } |
| 1844 | 1933 | ||
| 1845 | return 0; | 1934 | return 0; |
| @@ -1847,15 +1936,13 @@ done: | |||
| 1847 | } | 1936 | } |
| 1848 | 1937 | ||
| 1849 | static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { | 1938 | static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { |
| 1850 | .dpms = intel_sdvo_dpms, | ||
| 1851 | .mode_fixup = intel_sdvo_mode_fixup, | 1939 | .mode_fixup = intel_sdvo_mode_fixup, |
| 1852 | .prepare = intel_encoder_prepare, | ||
| 1853 | .mode_set = intel_sdvo_mode_set, | 1940 | .mode_set = intel_sdvo_mode_set, |
| 1854 | .commit = intel_encoder_commit, | 1941 | .disable = intel_encoder_noop, |
| 1855 | }; | 1942 | }; |
| 1856 | 1943 | ||
| 1857 | static const struct drm_connector_funcs intel_sdvo_connector_funcs = { | 1944 | static const struct drm_connector_funcs intel_sdvo_connector_funcs = { |
| 1858 | .dpms = drm_helper_connector_dpms, | 1945 | .dpms = intel_sdvo_dpms, |
| 1859 | .detect = intel_sdvo_detect, | 1946 | .detect = intel_sdvo_detect, |
| 1860 | .fill_modes = drm_helper_probe_single_connector_modes, | 1947 | .fill_modes = drm_helper_probe_single_connector_modes, |
| 1861 | .set_property = intel_sdvo_set_property, | 1948 | .set_property = intel_sdvo_set_property, |
| @@ -2027,6 +2114,7 @@ intel_sdvo_connector_init(struct intel_sdvo_connector *connector, | |||
| 2027 | connector->base.base.interlace_allowed = 1; | 2114 | connector->base.base.interlace_allowed = 1; |
| 2028 | connector->base.base.doublescan_allowed = 0; | 2115 | connector->base.base.doublescan_allowed = 0; |
| 2029 | connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB; | 2116 | connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB; |
| 2117 | connector->base.get_hw_state = intel_sdvo_connector_get_hw_state; | ||
| 2030 | 2118 | ||
| 2031 | intel_connector_attach_encoder(&connector->base, &encoder->base); | 2119 | intel_connector_attach_encoder(&connector->base, &encoder->base); |
| 2032 | drm_sysfs_connector_add(&connector->base.base); | 2120 | drm_sysfs_connector_add(&connector->base.base); |
| @@ -2578,6 +2666,10 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | |||
| 2578 | 2666 | ||
| 2579 | drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs); | 2667 | drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs); |
| 2580 | 2668 | ||
| 2669 | intel_encoder->disable = intel_disable_sdvo; | ||
| 2670 | intel_encoder->enable = intel_enable_sdvo; | ||
| 2671 | intel_encoder->get_hw_state = intel_sdvo_get_hw_state; | ||
| 2672 | |||
| 2581 | /* In default case sdvo lvds is false */ | 2673 | /* In default case sdvo lvds is false */ |
| 2582 | if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps)) | 2674 | if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps)) |
| 2583 | goto err; | 2675 | goto err; |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 95653a508987..d2c5c8f3baf3 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
| @@ -836,22 +836,37 @@ static struct intel_tv *intel_attached_tv(struct drm_connector *connector) | |||
| 836 | base); | 836 | base); |
| 837 | } | 837 | } |
| 838 | 838 | ||
| 839 | static bool | ||
| 840 | intel_tv_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe) | ||
| 841 | { | ||
| 842 | struct drm_device *dev = encoder->base.dev; | ||
| 843 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
| 844 | u32 tmp = I915_READ(TV_CTL); | ||
| 845 | |||
| 846 | if (!(tmp & TV_ENC_ENABLE)) | ||
| 847 | return false; | ||
| 848 | |||
| 849 | *pipe = PORT_TO_PIPE(tmp); | ||
| 850 | |||
| 851 | return true; | ||
| 852 | } | ||
| 853 | |||
| 839 | static void | 854 | static void |
| 840 | intel_tv_dpms(struct drm_encoder *encoder, int mode) | 855 | intel_enable_tv(struct intel_encoder *encoder) |
| 841 | { | 856 | { |
| 842 | struct drm_device *dev = encoder->dev; | 857 | struct drm_device *dev = encoder->base.dev; |
| 843 | struct drm_i915_private *dev_priv = dev->dev_private; | 858 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 844 | 859 | ||
| 845 | switch (mode) { | 860 | I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE); |
| 846 | case DRM_MODE_DPMS_ON: | 861 | } |
| 847 | I915_WRITE(TV_CTL, I915_READ(TV_CTL) | TV_ENC_ENABLE); | 862 | |
| 848 | break; | 863 | static void |
| 849 | case DRM_MODE_DPMS_STANDBY: | 864 | intel_disable_tv(struct intel_encoder *encoder) |
| 850 | case DRM_MODE_DPMS_SUSPEND: | 865 | { |
| 851 | case DRM_MODE_DPMS_OFF: | 866 | struct drm_device *dev = encoder->base.dev; |
| 852 | I915_WRITE(TV_CTL, I915_READ(TV_CTL) & ~TV_ENC_ENABLE); | 867 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 853 | break; | 868 | |
| 854 | } | 869 | I915_WRITE(TV_CTL, I915_READ(TV_CTL) & ~TV_ENC_ENABLE); |
| 855 | } | 870 | } |
| 856 | 871 | ||
| 857 | static const struct tv_mode * | 872 | static const struct tv_mode * |
| @@ -895,17 +910,14 @@ intel_tv_mode_fixup(struct drm_encoder *encoder, | |||
| 895 | const struct drm_display_mode *mode, | 910 | const struct drm_display_mode *mode, |
| 896 | struct drm_display_mode *adjusted_mode) | 911 | struct drm_display_mode *adjusted_mode) |
| 897 | { | 912 | { |
| 898 | struct drm_device *dev = encoder->dev; | ||
| 899 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); | 913 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
| 900 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); | 914 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
| 901 | struct intel_encoder *other_encoder; | ||
| 902 | 915 | ||
| 903 | if (!tv_mode) | 916 | if (!tv_mode) |
| 904 | return false; | 917 | return false; |
| 905 | 918 | ||
| 906 | for_each_encoder_on_crtc(dev, encoder->crtc, other_encoder) | 919 | if (intel_encoder_check_is_cloned(&intel_tv->base)) |
| 907 | if (&other_encoder->base != encoder) | 920 | return false; |
| 908 | return false; | ||
| 909 | 921 | ||
| 910 | adjusted_mode->clock = tv_mode->clock; | 922 | adjusted_mode->clock = tv_mode->clock; |
| 911 | return true; | 923 | return true; |
| @@ -1471,22 +1483,20 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop | |||
| 1471 | } | 1483 | } |
| 1472 | 1484 | ||
| 1473 | if (changed && crtc) | 1485 | if (changed && crtc) |
| 1474 | drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, | 1486 | intel_set_mode(crtc, &crtc->mode, |
| 1475 | crtc->y, crtc->fb); | 1487 | crtc->x, crtc->y, crtc->fb); |
| 1476 | out: | 1488 | out: |
| 1477 | return ret; | 1489 | return ret; |
| 1478 | } | 1490 | } |
| 1479 | 1491 | ||
| 1480 | static const struct drm_encoder_helper_funcs intel_tv_helper_funcs = { | 1492 | static const struct drm_encoder_helper_funcs intel_tv_helper_funcs = { |
| 1481 | .dpms = intel_tv_dpms, | ||
| 1482 | .mode_fixup = intel_tv_mode_fixup, | 1493 | .mode_fixup = intel_tv_mode_fixup, |
| 1483 | .prepare = intel_encoder_prepare, | ||
| 1484 | .mode_set = intel_tv_mode_set, | 1494 | .mode_set = intel_tv_mode_set, |
| 1485 | .commit = intel_encoder_commit, | 1495 | .disable = intel_encoder_noop, |
| 1486 | }; | 1496 | }; |
| 1487 | 1497 | ||
| 1488 | static const struct drm_connector_funcs intel_tv_connector_funcs = { | 1498 | static const struct drm_connector_funcs intel_tv_connector_funcs = { |
| 1489 | .dpms = drm_helper_connector_dpms, | 1499 | .dpms = intel_connector_dpms, |
| 1490 | .detect = intel_tv_detect, | 1500 | .detect = intel_tv_detect, |
| 1491 | .destroy = intel_tv_destroy, | 1501 | .destroy = intel_tv_destroy, |
| 1492 | .set_property = intel_tv_set_property, | 1502 | .set_property = intel_tv_set_property, |
| @@ -1616,6 +1626,11 @@ intel_tv_init(struct drm_device *dev) | |||
| 1616 | drm_encoder_init(dev, &intel_encoder->base, &intel_tv_enc_funcs, | 1626 | drm_encoder_init(dev, &intel_encoder->base, &intel_tv_enc_funcs, |
| 1617 | DRM_MODE_ENCODER_TVDAC); | 1627 | DRM_MODE_ENCODER_TVDAC); |
| 1618 | 1628 | ||
| 1629 | intel_encoder->enable = intel_enable_tv; | ||
| 1630 | intel_encoder->disable = intel_disable_tv; | ||
| 1631 | intel_encoder->get_hw_state = intel_tv_get_hw_state; | ||
| 1632 | intel_connector->get_hw_state = intel_connector_get_hw_state; | ||
| 1633 | |||
| 1619 | intel_connector_attach_encoder(intel_connector, intel_encoder); | 1634 | intel_connector_attach_encoder(intel_connector, intel_encoder); |
| 1620 | intel_encoder->type = INTEL_OUTPUT_TVOUT; | 1635 | intel_encoder->type = INTEL_OUTPUT_TVOUT; |
| 1621 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); | 1636 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); |
