diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 12 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 5 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_lvds.c | 9 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_opregion.c | 38 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_panel.c | 86 |
7 files changed, 122 insertions, 37 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 8b37b3531c27..b2023d7c1d6b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -54,6 +54,7 @@ | |||
| 54 | #define DRIVER_DATE "20080730" | 54 | #define DRIVER_DATE "20080730" |
| 55 | 55 | ||
| 56 | enum pipe { | 56 | enum pipe { |
| 57 | INVALID_PIPE = -1, | ||
| 57 | PIPE_A = 0, | 58 | PIPE_A = 0, |
| 58 | PIPE_B, | 59 | PIPE_B, |
| 59 | PIPE_C, | 60 | PIPE_C, |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e31a740e1663..73f036bddb6f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -9874,6 +9874,18 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) | |||
| 9874 | drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); | 9874 | drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); |
| 9875 | } | 9875 | } |
| 9876 | 9876 | ||
| 9877 | enum pipe intel_get_pipe_from_connector(struct intel_connector *connector) | ||
| 9878 | { | ||
| 9879 | struct drm_encoder *encoder = connector->base.encoder; | ||
| 9880 | |||
| 9881 | WARN_ON(!mutex_is_locked(&connector->base.dev->mode_config.mutex)); | ||
| 9882 | |||
| 9883 | if (!encoder) | ||
| 9884 | return INVALID_PIPE; | ||
| 9885 | |||
| 9886 | return to_intel_crtc(encoder->crtc)->pipe; | ||
| 9887 | } | ||
| 9888 | |||
| 9877 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, | 9889 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, |
| 9878 | struct drm_file *file) | 9890 | struct drm_file *file) |
| 9879 | { | 9891 | { |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index d58fbb6b5ffd..4609eedf52aa 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -1249,7 +1249,6 @@ void ironlake_edp_backlight_on(struct intel_dp *intel_dp) | |||
| 1249 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | 1249 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
| 1250 | struct drm_device *dev = intel_dig_port->base.base.dev; | 1250 | struct drm_device *dev = intel_dig_port->base.base.dev; |
| 1251 | struct drm_i915_private *dev_priv = dev->dev_private; | 1251 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1252 | int pipe = to_intel_crtc(intel_dig_port->base.base.crtc)->pipe; | ||
| 1253 | u32 pp; | 1252 | u32 pp; |
| 1254 | u32 pp_ctrl_reg; | 1253 | u32 pp_ctrl_reg; |
| 1255 | 1254 | ||
| @@ -1272,7 +1271,7 @@ void ironlake_edp_backlight_on(struct intel_dp *intel_dp) | |||
| 1272 | I915_WRITE(pp_ctrl_reg, pp); | 1271 | I915_WRITE(pp_ctrl_reg, pp); |
| 1273 | POSTING_READ(pp_ctrl_reg); | 1272 | POSTING_READ(pp_ctrl_reg); |
| 1274 | 1273 | ||
| 1275 | intel_panel_enable_backlight(dev, pipe); | 1274 | intel_panel_enable_backlight(intel_dp->attached_connector); |
| 1276 | } | 1275 | } |
| 1277 | 1276 | ||
| 1278 | void ironlake_edp_backlight_off(struct intel_dp *intel_dp) | 1277 | void ironlake_edp_backlight_off(struct intel_dp *intel_dp) |
| @@ -1285,7 +1284,7 @@ void ironlake_edp_backlight_off(struct intel_dp *intel_dp) | |||
| 1285 | if (!is_edp(intel_dp)) | 1284 | if (!is_edp(intel_dp)) |
| 1286 | return; | 1285 | return; |
| 1287 | 1286 | ||
| 1288 | intel_panel_disable_backlight(dev); | 1287 | intel_panel_disable_backlight(intel_dp->attached_connector); |
| 1289 | 1288 | ||
| 1290 | DRM_DEBUG_KMS("\n"); | 1289 | DRM_DEBUG_KMS("\n"); |
| 1291 | pp = ironlake_get_pp_control(intel_dp); | 1290 | pp = ironlake_get_pp_control(intel_dp); |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 9d2624fd92c2..1e49aa8f5377 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
| @@ -630,6 +630,7 @@ void intel_connector_attach_encoder(struct intel_connector *connector, | |||
| 630 | struct drm_encoder *intel_best_encoder(struct drm_connector *connector); | 630 | struct drm_encoder *intel_best_encoder(struct drm_connector *connector); |
| 631 | struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, | 631 | struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, |
| 632 | struct drm_crtc *crtc); | 632 | struct drm_crtc *crtc); |
| 633 | enum pipe intel_get_pipe_from_connector(struct intel_connector *connector); | ||
| 633 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, | 634 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, |
| 634 | struct drm_file *file_priv); | 635 | struct drm_file *file_priv); |
| 635 | enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv, | 636 | enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv, |
| @@ -802,10 +803,11 @@ void intel_pch_panel_fitting(struct intel_crtc *crtc, | |||
| 802 | void intel_gmch_panel_fitting(struct intel_crtc *crtc, | 803 | void intel_gmch_panel_fitting(struct intel_crtc *crtc, |
| 803 | struct intel_crtc_config *pipe_config, | 804 | struct intel_crtc_config *pipe_config, |
| 804 | int fitting_mode); | 805 | int fitting_mode); |
| 805 | void intel_panel_set_backlight(struct drm_device *dev, u32 level, u32 max); | 806 | void intel_panel_set_backlight(struct intel_connector *connector, u32 level, |
| 807 | u32 max); | ||
| 806 | int intel_panel_setup_backlight(struct drm_connector *connector); | 808 | int intel_panel_setup_backlight(struct drm_connector *connector); |
| 807 | void intel_panel_enable_backlight(struct drm_device *dev, enum pipe pipe); | 809 | void intel_panel_enable_backlight(struct intel_connector *connector); |
| 808 | void intel_panel_disable_backlight(struct drm_device *dev); | 810 | void intel_panel_disable_backlight(struct intel_connector *connector); |
| 809 | void intel_panel_destroy_backlight(struct drm_device *dev); | 811 | void intel_panel_destroy_backlight(struct drm_device *dev); |
| 810 | enum drm_connector_status intel_panel_detect(struct drm_device *dev); | 812 | enum drm_connector_status intel_panel_detect(struct drm_device *dev); |
| 811 | 813 | ||
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index b0ef55833087..c3b4da7895ed 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
| @@ -206,7 +206,8 @@ static void intel_enable_lvds(struct intel_encoder *encoder) | |||
| 206 | { | 206 | { |
| 207 | struct drm_device *dev = encoder->base.dev; | 207 | struct drm_device *dev = encoder->base.dev; |
| 208 | struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); | 208 | struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); |
| 209 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); | 209 | struct intel_connector *intel_connector = |
| 210 | &lvds_encoder->attached_connector->base; | ||
| 210 | struct drm_i915_private *dev_priv = dev->dev_private; | 211 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 211 | u32 ctl_reg, stat_reg; | 212 | u32 ctl_reg, stat_reg; |
| 212 | 213 | ||
| @@ -225,13 +226,15 @@ static void intel_enable_lvds(struct intel_encoder *encoder) | |||
| 225 | if (wait_for((I915_READ(stat_reg) & PP_ON) != 0, 1000)) | 226 | if (wait_for((I915_READ(stat_reg) & PP_ON) != 0, 1000)) |
| 226 | DRM_ERROR("timed out waiting for panel to power on\n"); | 227 | DRM_ERROR("timed out waiting for panel to power on\n"); |
| 227 | 228 | ||
| 228 | intel_panel_enable_backlight(dev, intel_crtc->pipe); | 229 | intel_panel_enable_backlight(intel_connector); |
| 229 | } | 230 | } |
| 230 | 231 | ||
| 231 | static void intel_disable_lvds(struct intel_encoder *encoder) | 232 | static void intel_disable_lvds(struct intel_encoder *encoder) |
| 232 | { | 233 | { |
| 233 | struct drm_device *dev = encoder->base.dev; | 234 | struct drm_device *dev = encoder->base.dev; |
| 234 | struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); | 235 | struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base); |
| 236 | struct intel_connector *intel_connector = | ||
| 237 | &lvds_encoder->attached_connector->base; | ||
| 235 | struct drm_i915_private *dev_priv = dev->dev_private; | 238 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 236 | u32 ctl_reg, stat_reg; | 239 | u32 ctl_reg, stat_reg; |
| 237 | 240 | ||
| @@ -243,7 +246,7 @@ static void intel_disable_lvds(struct intel_encoder *encoder) | |||
| 243 | stat_reg = PP_STATUS; | 246 | stat_reg = PP_STATUS; |
| 244 | } | 247 | } |
| 245 | 248 | ||
| 246 | intel_panel_disable_backlight(dev); | 249 | intel_panel_disable_backlight(intel_connector); |
| 247 | 250 | ||
| 248 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON); | 251 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON); |
| 249 | if (wait_for((I915_READ(stat_reg) & PP_ON) == 0, 1000)) | 252 | if (wait_for((I915_READ(stat_reg) & PP_ON) == 0, 1000)) |
diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index 892d520175d8..91b68dca0641 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c | |||
| @@ -396,7 +396,13 @@ int intel_opregion_notify_adapter(struct drm_device *dev, pci_power_t state) | |||
| 396 | static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) | 396 | static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) |
| 397 | { | 397 | { |
| 398 | struct drm_i915_private *dev_priv = dev->dev_private; | 398 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 399 | struct drm_encoder *encoder; | ||
| 400 | struct drm_connector *connector; | ||
| 401 | struct intel_connector *intel_connector = NULL; | ||
| 402 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[0]; | ||
| 399 | struct opregion_asle __iomem *asle = dev_priv->opregion.asle; | 403 | struct opregion_asle __iomem *asle = dev_priv->opregion.asle; |
| 404 | u32 ret = 0; | ||
| 405 | bool found = false; | ||
| 400 | 406 | ||
| 401 | DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp); | 407 | DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp); |
| 402 | 408 | ||
| @@ -407,11 +413,39 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) | |||
| 407 | if (bclp > 255) | 413 | if (bclp > 255) |
| 408 | return ASLC_BACKLIGHT_FAILED; | 414 | return ASLC_BACKLIGHT_FAILED; |
| 409 | 415 | ||
| 416 | mutex_lock(&dev->mode_config.mutex); | ||
| 417 | /* | ||
| 418 | * Could match the OpRegion connector here instead, but we'd also need | ||
| 419 | * to verify the connector could handle a backlight call. | ||
| 420 | */ | ||
| 421 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) | ||
| 422 | if (encoder->crtc == crtc) { | ||
| 423 | found = true; | ||
| 424 | break; | ||
| 425 | } | ||
| 426 | |||
| 427 | if (!found) { | ||
| 428 | ret = ASLC_BACKLIGHT_FAILED; | ||
| 429 | goto out; | ||
| 430 | } | ||
| 431 | |||
| 432 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) | ||
| 433 | if (connector->encoder == encoder) | ||
| 434 | intel_connector = to_intel_connector(connector); | ||
| 435 | |||
| 436 | if (!intel_connector) { | ||
| 437 | ret = ASLC_BACKLIGHT_FAILED; | ||
| 438 | goto out; | ||
| 439 | } | ||
| 440 | |||
| 410 | DRM_DEBUG_KMS("updating opregion backlight %d/255\n", bclp); | 441 | DRM_DEBUG_KMS("updating opregion backlight %d/255\n", bclp); |
| 411 | intel_panel_set_backlight(dev, bclp, 255); | 442 | intel_panel_set_backlight(intel_connector, bclp, 255); |
| 412 | iowrite32(DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID, &asle->cblv); | 443 | iowrite32(DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID, &asle->cblv); |
| 413 | 444 | ||
| 414 | return 0; | 445 | out: |
| 446 | mutex_unlock(&dev->mode_config.mutex); | ||
| 447 | |||
| 448 | return ret; | ||
| 415 | } | 449 | } |
| 416 | 450 | ||
| 417 | static u32 asle_set_als_illum(struct drm_device *dev, u32 alsi) | 451 | static u32 asle_set_als_illum(struct drm_device *dev, u32 alsi) |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index de1518614827..17ddcb00bd26 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
| @@ -341,7 +341,7 @@ static int is_backlight_combination_mode(struct drm_device *dev) | |||
| 341 | /* XXX: query mode clock or hardware clock and program max PWM appropriately | 341 | /* XXX: query mode clock or hardware clock and program max PWM appropriately |
| 342 | * when it's 0. | 342 | * when it's 0. |
| 343 | */ | 343 | */ |
| 344 | static u32 i915_read_blc_pwm_ctl(struct drm_device *dev) | 344 | static u32 i915_read_blc_pwm_ctl(struct drm_device *dev, enum pipe pipe) |
| 345 | { | 345 | { |
| 346 | struct drm_i915_private *dev_priv = dev->dev_private; | 346 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 347 | u32 val; | 347 | u32 val; |
| @@ -380,11 +380,12 @@ static u32 i915_read_blc_pwm_ctl(struct drm_device *dev) | |||
| 380 | return val; | 380 | return val; |
| 381 | } | 381 | } |
| 382 | 382 | ||
| 383 | static u32 intel_panel_get_max_backlight(struct drm_device *dev) | 383 | static u32 intel_panel_get_max_backlight(struct drm_device *dev, |
| 384 | enum pipe pipe) | ||
| 384 | { | 385 | { |
| 385 | u32 max; | 386 | u32 max; |
| 386 | 387 | ||
| 387 | max = i915_read_blc_pwm_ctl(dev); | 388 | max = i915_read_blc_pwm_ctl(dev, pipe); |
| 388 | 389 | ||
| 389 | if (HAS_PCH_SPLIT(dev)) { | 390 | if (HAS_PCH_SPLIT(dev)) { |
| 390 | max >>= 16; | 391 | max >>= 16; |
| @@ -410,7 +411,8 @@ MODULE_PARM_DESC(invert_brightness, "Invert backlight brightness " | |||
| 410 | "to dri-devel@lists.freedesktop.org, if your machine needs it. " | 411 | "to dri-devel@lists.freedesktop.org, if your machine needs it. " |
| 411 | "It will then be included in an upcoming module version."); | 412 | "It will then be included in an upcoming module version."); |
| 412 | module_param_named(invert_brightness, i915_panel_invert_brightness, int, 0600); | 413 | module_param_named(invert_brightness, i915_panel_invert_brightness, int, 0600); |
| 413 | static u32 intel_panel_compute_brightness(struct drm_device *dev, u32 val) | 414 | static u32 intel_panel_compute_brightness(struct drm_device *dev, |
| 415 | enum pipe pipe, u32 val) | ||
| 414 | { | 416 | { |
| 415 | struct drm_i915_private *dev_priv = dev->dev_private; | 417 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 416 | 418 | ||
| @@ -419,7 +421,7 @@ static u32 intel_panel_compute_brightness(struct drm_device *dev, u32 val) | |||
| 419 | 421 | ||
| 420 | if (i915_panel_invert_brightness > 0 || | 422 | if (i915_panel_invert_brightness > 0 || |
| 421 | dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) { | 423 | dev_priv->quirks & QUIRK_INVERT_BRIGHTNESS) { |
| 422 | u32 max = intel_panel_get_max_backlight(dev); | 424 | u32 max = intel_panel_get_max_backlight(dev, pipe); |
| 423 | if (max) | 425 | if (max) |
| 424 | return max - val; | 426 | return max - val; |
| 425 | } | 427 | } |
| @@ -427,7 +429,8 @@ static u32 intel_panel_compute_brightness(struct drm_device *dev, u32 val) | |||
| 427 | return val; | 429 | return val; |
| 428 | } | 430 | } |
| 429 | 431 | ||
| 430 | static u32 intel_panel_get_backlight(struct drm_device *dev) | 432 | static u32 intel_panel_get_backlight(struct drm_device *dev, |
| 433 | enum pipe pipe) | ||
| 431 | { | 434 | { |
| 432 | struct drm_i915_private *dev_priv = dev->dev_private; | 435 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 433 | u32 val; | 436 | u32 val; |
| @@ -450,7 +453,7 @@ static u32 intel_panel_get_backlight(struct drm_device *dev) | |||
| 450 | } | 453 | } |
| 451 | } | 454 | } |
| 452 | 455 | ||
| 453 | val = intel_panel_compute_brightness(dev, val); | 456 | val = intel_panel_compute_brightness(dev, pipe, val); |
| 454 | 457 | ||
| 455 | spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); | 458 | spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); |
| 456 | 459 | ||
| @@ -466,19 +469,19 @@ static void intel_pch_panel_set_backlight(struct drm_device *dev, u32 level) | |||
| 466 | } | 469 | } |
| 467 | 470 | ||
| 468 | static void intel_panel_actually_set_backlight(struct drm_device *dev, | 471 | static void intel_panel_actually_set_backlight(struct drm_device *dev, |
| 469 | u32 level) | 472 | enum pipe pipe, u32 level) |
| 470 | { | 473 | { |
| 471 | struct drm_i915_private *dev_priv = dev->dev_private; | 474 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 472 | u32 tmp; | 475 | u32 tmp; |
| 473 | 476 | ||
| 474 | DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level); | 477 | DRM_DEBUG_DRIVER("set backlight PWM = %d\n", level); |
| 475 | level = intel_panel_compute_brightness(dev, level); | 478 | level = intel_panel_compute_brightness(dev, pipe, level); |
| 476 | 479 | ||
| 477 | if (HAS_PCH_SPLIT(dev)) | 480 | if (HAS_PCH_SPLIT(dev)) |
| 478 | return intel_pch_panel_set_backlight(dev, level); | 481 | return intel_pch_panel_set_backlight(dev, level); |
| 479 | 482 | ||
| 480 | if (is_backlight_combination_mode(dev)) { | 483 | if (is_backlight_combination_mode(dev)) { |
| 481 | u32 max = intel_panel_get_max_backlight(dev); | 484 | u32 max = intel_panel_get_max_backlight(dev, pipe); |
| 482 | u8 lbpc; | 485 | u8 lbpc; |
| 483 | 486 | ||
| 484 | /* we're screwed, but keep behaviour backwards compatible */ | 487 | /* we're screwed, but keep behaviour backwards compatible */ |
| @@ -498,15 +501,21 @@ static void intel_panel_actually_set_backlight(struct drm_device *dev, | |||
| 498 | } | 501 | } |
| 499 | 502 | ||
| 500 | /* set backlight brightness to level in range [0..max] */ | 503 | /* set backlight brightness to level in range [0..max] */ |
| 501 | void intel_panel_set_backlight(struct drm_device *dev, u32 level, u32 max) | 504 | void intel_panel_set_backlight(struct intel_connector *connector, u32 level, |
| 505 | u32 max) | ||
| 502 | { | 506 | { |
| 507 | struct drm_device *dev = connector->base.dev; | ||
| 503 | struct drm_i915_private *dev_priv = dev->dev_private; | 508 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 509 | enum pipe pipe = intel_get_pipe_from_connector(connector); | ||
| 504 | u32 freq; | 510 | u32 freq; |
| 505 | unsigned long flags; | 511 | unsigned long flags; |
| 506 | 512 | ||
| 513 | if (pipe == INVALID_PIPE) | ||
| 514 | return; | ||
| 515 | |||
| 507 | spin_lock_irqsave(&dev_priv->backlight.lock, flags); | 516 | spin_lock_irqsave(&dev_priv->backlight.lock, flags); |
| 508 | 517 | ||
| 509 | freq = intel_panel_get_max_backlight(dev); | 518 | freq = intel_panel_get_max_backlight(dev, pipe); |
| 510 | if (!freq) { | 519 | if (!freq) { |
| 511 | /* we are screwed, bail out */ | 520 | /* we are screwed, bail out */ |
| 512 | goto out; | 521 | goto out; |
| @@ -523,16 +532,21 @@ void intel_panel_set_backlight(struct drm_device *dev, u32 level, u32 max) | |||
| 523 | dev_priv->backlight.device->props.brightness = level; | 532 | dev_priv->backlight.device->props.brightness = level; |
| 524 | 533 | ||
| 525 | if (dev_priv->backlight.enabled) | 534 | if (dev_priv->backlight.enabled) |
| 526 | intel_panel_actually_set_backlight(dev, level); | 535 | intel_panel_actually_set_backlight(dev, pipe, level); |
| 527 | out: | 536 | out: |
| 528 | spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); | 537 | spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); |
| 529 | } | 538 | } |
| 530 | 539 | ||
| 531 | void intel_panel_disable_backlight(struct drm_device *dev) | 540 | void intel_panel_disable_backlight(struct intel_connector *connector) |
| 532 | { | 541 | { |
| 542 | struct drm_device *dev = connector->base.dev; | ||
| 533 | struct drm_i915_private *dev_priv = dev->dev_private; | 543 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 544 | enum pipe pipe = intel_get_pipe_from_connector(connector); | ||
| 534 | unsigned long flags; | 545 | unsigned long flags; |
| 535 | 546 | ||
| 547 | if (pipe == INVALID_PIPE) | ||
| 548 | return; | ||
| 549 | |||
| 536 | /* | 550 | /* |
| 537 | * Do not disable backlight on the vgaswitcheroo path. When switching | 551 | * Do not disable backlight on the vgaswitcheroo path. When switching |
| 538 | * away from i915, the other client may depend on i915 to handle the | 552 | * away from i915, the other client may depend on i915 to handle the |
| @@ -547,7 +561,7 @@ void intel_panel_disable_backlight(struct drm_device *dev) | |||
| 547 | spin_lock_irqsave(&dev_priv->backlight.lock, flags); | 561 | spin_lock_irqsave(&dev_priv->backlight.lock, flags); |
| 548 | 562 | ||
| 549 | dev_priv->backlight.enabled = false; | 563 | dev_priv->backlight.enabled = false; |
| 550 | intel_panel_actually_set_backlight(dev, 0); | 564 | intel_panel_actually_set_backlight(dev, pipe, 0); |
| 551 | 565 | ||
| 552 | if (INTEL_INFO(dev)->gen >= 4) { | 566 | if (INTEL_INFO(dev)->gen >= 4) { |
| 553 | uint32_t reg, tmp; | 567 | uint32_t reg, tmp; |
| @@ -566,20 +580,25 @@ void intel_panel_disable_backlight(struct drm_device *dev) | |||
| 566 | spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); | 580 | spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); |
| 567 | } | 581 | } |
| 568 | 582 | ||
| 569 | void intel_panel_enable_backlight(struct drm_device *dev, | 583 | void intel_panel_enable_backlight(struct intel_connector *connector) |
| 570 | enum pipe pipe) | ||
| 571 | { | 584 | { |
| 585 | struct drm_device *dev = connector->base.dev; | ||
| 572 | struct drm_i915_private *dev_priv = dev->dev_private; | 586 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 587 | enum pipe pipe = intel_get_pipe_from_connector(connector); | ||
| 573 | enum transcoder cpu_transcoder = | 588 | enum transcoder cpu_transcoder = |
| 574 | intel_pipe_to_cpu_transcoder(dev_priv, pipe); | 589 | intel_pipe_to_cpu_transcoder(dev_priv, pipe); |
| 575 | unsigned long flags; | 590 | unsigned long flags; |
| 576 | 591 | ||
| 592 | if (pipe == INVALID_PIPE) | ||
| 593 | return; | ||
| 594 | |||
| 577 | DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe)); | 595 | DRM_DEBUG_KMS("pipe %c\n", pipe_name(pipe)); |
| 578 | 596 | ||
| 579 | spin_lock_irqsave(&dev_priv->backlight.lock, flags); | 597 | spin_lock_irqsave(&dev_priv->backlight.lock, flags); |
| 580 | 598 | ||
| 581 | if (dev_priv->backlight.level == 0) { | 599 | if (dev_priv->backlight.level == 0) { |
| 582 | dev_priv->backlight.level = intel_panel_get_max_backlight(dev); | 600 | dev_priv->backlight.level = intel_panel_get_max_backlight(dev, |
| 601 | pipe); | ||
| 583 | if (dev_priv->backlight.device) | 602 | if (dev_priv->backlight.device) |
| 584 | dev_priv->backlight.device->props.brightness = | 603 | dev_priv->backlight.device->props.brightness = |
| 585 | dev_priv->backlight.level; | 604 | dev_priv->backlight.level; |
| @@ -629,7 +648,8 @@ set_level: | |||
| 629 | * registers are set. | 648 | * registers are set. |
| 630 | */ | 649 | */ |
| 631 | dev_priv->backlight.enabled = true; | 650 | dev_priv->backlight.enabled = true; |
| 632 | intel_panel_actually_set_backlight(dev, dev_priv->backlight.level); | 651 | intel_panel_actually_set_backlight(dev, pipe, |
| 652 | dev_priv->backlight.level); | ||
| 633 | 653 | ||
| 634 | spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); | 654 | spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); |
| 635 | } | 655 | } |
| @@ -652,7 +672,7 @@ static void intel_panel_init_backlight(struct drm_device *dev) | |||
| 652 | 672 | ||
| 653 | intel_panel_init_backlight_regs(dev); | 673 | intel_panel_init_backlight_regs(dev); |
| 654 | 674 | ||
| 655 | dev_priv->backlight.level = intel_panel_get_backlight(dev); | 675 | dev_priv->backlight.level = intel_panel_get_backlight(dev, 0); |
| 656 | dev_priv->backlight.enabled = dev_priv->backlight.level != 0; | 676 | dev_priv->backlight.enabled = dev_priv->backlight.level != 0; |
| 657 | } | 677 | } |
| 658 | 678 | ||
| @@ -681,18 +701,31 @@ intel_panel_detect(struct drm_device *dev) | |||
| 681 | #if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) | 701 | #if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE) |
| 682 | static int intel_panel_update_status(struct backlight_device *bd) | 702 | static int intel_panel_update_status(struct backlight_device *bd) |
| 683 | { | 703 | { |
| 684 | struct drm_device *dev = bl_get_data(bd); | 704 | struct intel_connector *connector = bl_get_data(bd); |
| 705 | struct drm_device *dev = connector->base.dev; | ||
| 706 | |||
| 707 | mutex_lock(&dev->mode_config.mutex); | ||
| 685 | DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n", | 708 | DRM_DEBUG_KMS("updating intel_backlight, brightness=%d/%d\n", |
| 686 | bd->props.brightness, bd->props.max_brightness); | 709 | bd->props.brightness, bd->props.max_brightness); |
| 687 | intel_panel_set_backlight(dev, bd->props.brightness, | 710 | intel_panel_set_backlight(connector, bd->props.brightness, |
| 688 | bd->props.max_brightness); | 711 | bd->props.max_brightness); |
| 712 | mutex_unlock(&dev->mode_config.mutex); | ||
| 689 | return 0; | 713 | return 0; |
| 690 | } | 714 | } |
| 691 | 715 | ||
| 692 | static int intel_panel_get_brightness(struct backlight_device *bd) | 716 | static int intel_panel_get_brightness(struct backlight_device *bd) |
| 693 | { | 717 | { |
| 694 | struct drm_device *dev = bl_get_data(bd); | 718 | struct intel_connector *connector = bl_get_data(bd); |
| 695 | return intel_panel_get_backlight(dev); | 719 | struct drm_device *dev = connector->base.dev; |
| 720 | enum pipe pipe; | ||
| 721 | |||
| 722 | mutex_lock(&dev->mode_config.mutex); | ||
| 723 | pipe = intel_get_pipe_from_connector(connector); | ||
| 724 | mutex_unlock(&dev->mode_config.mutex); | ||
| 725 | if (pipe == INVALID_PIPE) | ||
| 726 | return 0; | ||
| 727 | |||
| 728 | return intel_panel_get_backlight(connector->base.dev, pipe); | ||
| 696 | } | 729 | } |
| 697 | 730 | ||
| 698 | static const struct backlight_ops intel_panel_bl_ops = { | 731 | static const struct backlight_ops intel_panel_bl_ops = { |
| @@ -717,7 +750,7 @@ int intel_panel_setup_backlight(struct drm_connector *connector) | |||
| 717 | props.brightness = dev_priv->backlight.level; | 750 | props.brightness = dev_priv->backlight.level; |
| 718 | 751 | ||
| 719 | spin_lock_irqsave(&dev_priv->backlight.lock, flags); | 752 | spin_lock_irqsave(&dev_priv->backlight.lock, flags); |
| 720 | props.max_brightness = intel_panel_get_max_backlight(dev); | 753 | props.max_brightness = intel_panel_get_max_backlight(dev, 0); |
| 721 | spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); | 754 | spin_unlock_irqrestore(&dev_priv->backlight.lock, flags); |
| 722 | 755 | ||
| 723 | if (props.max_brightness == 0) { | 756 | if (props.max_brightness == 0) { |
| @@ -726,7 +759,8 @@ int intel_panel_setup_backlight(struct drm_connector *connector) | |||
| 726 | } | 759 | } |
| 727 | dev_priv->backlight.device = | 760 | dev_priv->backlight.device = |
| 728 | backlight_device_register("intel_backlight", | 761 | backlight_device_register("intel_backlight", |
| 729 | &connector->kdev, dev, | 762 | &connector->kdev, |
| 763 | to_intel_connector(connector), | ||
| 730 | &intel_panel_bl_ops, &props); | 764 | &intel_panel_bl_ops, &props); |
| 731 | 765 | ||
| 732 | if (IS_ERR(dev_priv->backlight.device)) { | 766 | if (IS_ERR(dev_priv->backlight.device)) { |
