aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915
diff options
context:
space:
mode:
authorPradeep Bhat <pradeep.bhat@intel.com>2014-04-05 02:42:31 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-04-10 04:54:44 -0400
commit4f9db5b51cb1dfa9b6d5060dc4316e82d53e1b6c (patch)
tree3c3fd4a147afa72e945e9b2cd9e002f5df2c83c1 /drivers/gpu/drm/i915
parentfc1744ff7ba63cabf858c55217382104e9dd94ed (diff)
drm/i915: Parse EDID probed modes for DRRS support
This patch and finds out the lowest refresh rate supported for the resolution same as the fixed_mode. It also checks the VBT fields to see if panel supports seamless DRRS or not. Based on above data it marks whether eDP panel supports seamless DRRS or not. This information is needed for supporting seamless DRRS switch for certain power saving usecases. This patch is tested by enabling the DRM logs and user should see whether Seamless DRRS is supported or not. v2: Daniel's review comments Modified downclock deduction based on intel_find_panel_downclock v3: Chris's review comments Moved edp_downclock_avail and edp_downclock to intel_panel v4: Jani's review comments. Changed name of the enum edp_panel_type to drrs_support type. Change is_drrs_supported to drrs_support of type enum drrs_support_type. v5: Incorporated Jani's review comments Modify intel_dp_drrs_initialize to return downclock mode. Support for Gen7 and above. v6: Incorporated Chris's review comments. Changed initialize to init in intel_drrs_initialize v7: Incorporated Jani's review comments. Removed edp_downclock and edp_downclock_avail. Return NULL explicitly. Make drrs_state and unnamed struct. Move Gen based check inside drrs_init. v8: Made changes to track PSR enable/disable throughout system use (instead of just in the init sequence) for disabling/enabling DRRS. Jani's review comments. v9: PSR tracking will be done as part of idleness detection patch. Removed PSR state tracker in i915_drrs. Jani's review comments. v10: Added log for DRRS not supported in drrs_init v11: Modification in drrs_init. suggested by Jani Signed-off-by: Pradeep Bhat <pradeep.bhat@intel.com> Signed-off-by: Vandana Kannan <vandana.kannan@intel.com> Cc: Jani Nikula <jani.nikula@linux.intel.com> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c44
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h16
2 files changed, 59 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index e48d47ced57b..517a8cc27bec 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -3632,6 +3632,42 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
3632 I915_READ(pp_div_reg)); 3632 I915_READ(pp_div_reg));
3633} 3633}
3634 3634
3635static struct drm_display_mode *
3636intel_dp_drrs_init(struct intel_digital_port *intel_dig_port,
3637 struct intel_connector *intel_connector,
3638 struct drm_display_mode *fixed_mode)
3639{
3640 struct drm_connector *connector = &intel_connector->base;
3641 struct intel_dp *intel_dp = &intel_dig_port->dp;
3642 struct drm_device *dev = intel_dig_port->base.base.dev;
3643 struct drm_i915_private *dev_priv = dev->dev_private;
3644 struct drm_display_mode *downclock_mode = NULL;
3645
3646 if (INTEL_INFO(dev)->gen <= 6) {
3647 DRM_DEBUG_KMS("DRRS supported for Gen7 and above\n");
3648 return NULL;
3649 }
3650
3651 if (dev_priv->vbt.drrs_type != SEAMLESS_DRRS_SUPPORT) {
3652 DRM_INFO("VBT doesn't support DRRS\n");
3653 return NULL;
3654 }
3655
3656 downclock_mode = intel_find_panel_downclock
3657 (dev, fixed_mode, connector);
3658
3659 if (!downclock_mode) {
3660 DRM_INFO("DRRS not supported\n");
3661 return NULL;
3662 }
3663
3664 intel_dp->drrs_state.type = dev_priv->vbt.drrs_type;
3665
3666 intel_dp->drrs_state.refresh_rate_type = DRRS_HIGH_RR;
3667 DRM_INFO("seamless DRRS supported for eDP panel.\n");
3668 return downclock_mode;
3669}
3670
3635static bool intel_edp_init_connector(struct intel_dp *intel_dp, 3671static bool intel_edp_init_connector(struct intel_dp *intel_dp,
3636 struct intel_connector *intel_connector, 3672 struct intel_connector *intel_connector,
3637 struct edp_power_seq *power_seq) 3673 struct edp_power_seq *power_seq)
@@ -3641,10 +3677,13 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
3641 struct drm_device *dev = intel_dig_port->base.base.dev; 3677 struct drm_device *dev = intel_dig_port->base.base.dev;
3642 struct drm_i915_private *dev_priv = dev->dev_private; 3678 struct drm_i915_private *dev_priv = dev->dev_private;
3643 struct drm_display_mode *fixed_mode = NULL; 3679 struct drm_display_mode *fixed_mode = NULL;
3680 struct drm_display_mode *downclock_mode = NULL;
3644 bool has_dpcd; 3681 bool has_dpcd;
3645 struct drm_display_mode *scan; 3682 struct drm_display_mode *scan;
3646 struct edid *edid; 3683 struct edid *edid;
3647 3684
3685 intel_dp->drrs_state.type = DRRS_NOT_SUPPORTED;
3686
3648 if (!is_edp(intel_dp)) 3687 if (!is_edp(intel_dp))
3649 return true; 3688 return true;
3650 3689
@@ -3687,6 +3726,9 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
3687 list_for_each_entry(scan, &connector->probed_modes, head) { 3726 list_for_each_entry(scan, &connector->probed_modes, head) {
3688 if ((scan->type & DRM_MODE_TYPE_PREFERRED)) { 3727 if ((scan->type & DRM_MODE_TYPE_PREFERRED)) {
3689 fixed_mode = drm_mode_duplicate(dev, scan); 3728 fixed_mode = drm_mode_duplicate(dev, scan);
3729 downclock_mode = intel_dp_drrs_init(
3730 intel_dig_port,
3731 intel_connector, fixed_mode);
3690 break; 3732 break;
3691 } 3733 }
3692 } 3734 }
@@ -3700,7 +3742,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
3700 } 3742 }
3701 mutex_unlock(&dev->mode_config.mutex); 3743 mutex_unlock(&dev->mode_config.mutex);
3702 3744
3703 intel_panel_init(&intel_connector->panel, fixed_mode, NULL); 3745 intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode);
3704 intel_panel_setup_backlight(connector); 3746 intel_panel_setup_backlight(connector);
3705 3747
3706 return true; 3748 return true;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 6b512607b2f5..41038d9b434f 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -485,6 +485,17 @@ struct intel_hdmi {
485 485
486#define DP_MAX_DOWNSTREAM_PORTS 0x10 486#define DP_MAX_DOWNSTREAM_PORTS 0x10
487 487
488/**
489 * HIGH_RR is the highest eDP panel refresh rate read from EDID
490 * LOW_RR is the lowest eDP panel refresh rate found from EDID
491 * parsing for same resolution.
492 */
493enum edp_drrs_refresh_rate_type {
494 DRRS_HIGH_RR,
495 DRRS_LOW_RR,
496 DRRS_MAX_RR, /* RR count */
497};
498
488struct intel_dp { 499struct intel_dp {
489 uint32_t output_reg; 500 uint32_t output_reg;
490 uint32_t aux_ch_ctl_reg; 501 uint32_t aux_ch_ctl_reg;
@@ -523,6 +534,11 @@ struct intel_dp {
523 bool has_aux_irq, 534 bool has_aux_irq,
524 int send_bytes, 535 int send_bytes,
525 uint32_t aux_clock_divider); 536 uint32_t aux_clock_divider);
537 struct {
538 enum drrs_support_type type;
539 enum edp_drrs_refresh_rate_type refresh_rate_type;
540 } drrs_state;
541
526}; 542};
527 543
528struct intel_digital_port { 544struct intel_digital_port {