diff options
| author | Vandana Kannan <vandana.kannan@intel.com> | 2015-02-13 05:03:03 -0500 |
|---|---|---|
| committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2015-02-24 05:51:38 -0500 |
| commit | b33a281544980f9cba22aaeaa4a945254326a8c0 (patch) | |
| tree | 9550390c8b420734cfa4ea502f4ec5924e01abfc | |
| parent | 44395bfe2f2a22ec769eb51ea1908082cf9aa16d (diff) | |
Documentation/drm: DocBook integration for DRRS
Adding an overview of DRRS in general and the implementation for eDP DRRS.
Also, describing the functions related to eDP DRRS.
Signed-off-by: Vandana Kannan <vandana.kannan@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
| -rw-r--r-- | Documentation/DocBook/drm.tmpl | 11 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 95 |
2 files changed, 106 insertions, 0 deletions
diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 249f0c9ede40..7a45775518f6 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl | |||
| @@ -4053,6 +4053,17 @@ int num_ioctls;</synopsis> | |||
| 4053 | !Idrivers/gpu/drm/i915/intel_fbc.c | 4053 | !Idrivers/gpu/drm/i915/intel_fbc.c |
| 4054 | </sect2> | 4054 | </sect2> |
| 4055 | <sect2> | 4055 | <sect2> |
| 4056 | <title>Display Refresh Rate Switching (DRRS)</title> | ||
| 4057 | !Pdrivers/gpu/drm/i915/intel_dp.c Display Refresh Rate Switching (DRRS) | ||
| 4058 | !Fdrivers/gpu/drm/i915/intel_dp.c intel_dp_set_drrs_state | ||
| 4059 | !Fdrivers/gpu/drm/i915/intel_dp.c intel_edp_drrs_enable | ||
| 4060 | !Fdrivers/gpu/drm/i915/intel_dp.c intel_edp_drrs_disable | ||
| 4061 | !Fdrivers/gpu/drm/i915/intel_dp.c intel_edp_drrs_invalidate | ||
| 4062 | !Fdrivers/gpu/drm/i915/intel_dp.c intel_edp_drrs_flush | ||
| 4063 | !Fdrivers/gpu/drm/i915/intel_dp.c intel_dp_drrs_init | ||
| 4064 | |||
| 4065 | </sect2> | ||
| 4066 | <sect2> | ||
| 4056 | <title>DPIO</title> | 4067 | <title>DPIO</title> |
| 4057 | !Pdrivers/gpu/drm/i915/i915_reg.h DPIO | 4068 | !Pdrivers/gpu/drm/i915/i915_reg.h DPIO |
| 4058 | <table id="dpiox2"> | 4069 | <table id="dpiox2"> |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 686c3d5c3769..b5d6eb011422 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -4751,6 +4751,18 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, | |||
| 4751 | I915_READ(pp_div_reg)); | 4751 | I915_READ(pp_div_reg)); |
| 4752 | } | 4752 | } |
| 4753 | 4753 | ||
| 4754 | /** | ||
| 4755 | * intel_dp_set_drrs_state - program registers for RR switch to take effect | ||
| 4756 | * @dev: DRM device | ||
| 4757 | * @refresh_rate: RR to be programmed | ||
| 4758 | * | ||
| 4759 | * This function gets called when refresh rate (RR) has to be changed from | ||
| 4760 | * one frequency to another. Switches can be between high and low RR | ||
| 4761 | * supported by the panel or to any other RR based on media playback (in | ||
| 4762 | * this case, RR value needs to be passed from user space). | ||
| 4763 | * | ||
| 4764 | * The caller of this function needs to take a lock on dev_priv->drrs. | ||
| 4765 | */ | ||
| 4754 | static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate) | 4766 | static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate) |
| 4755 | { | 4767 | { |
| 4756 | struct drm_i915_private *dev_priv = dev->dev_private; | 4768 | struct drm_i915_private *dev_priv = dev->dev_private; |
| @@ -4843,6 +4855,12 @@ static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate) | |||
| 4843 | DRM_DEBUG_KMS("eDP Refresh Rate set to : %dHz\n", refresh_rate); | 4855 | DRM_DEBUG_KMS("eDP Refresh Rate set to : %dHz\n", refresh_rate); |
| 4844 | } | 4856 | } |
| 4845 | 4857 | ||
| 4858 | /** | ||
| 4859 | * intel_edp_drrs_enable - init drrs struct if supported | ||
| 4860 | * @intel_dp: DP struct | ||
| 4861 | * | ||
| 4862 | * Initializes frontbuffer_bits and drrs.dp | ||
| 4863 | */ | ||
| 4846 | void intel_edp_drrs_enable(struct intel_dp *intel_dp) | 4864 | void intel_edp_drrs_enable(struct intel_dp *intel_dp) |
| 4847 | { | 4865 | { |
| 4848 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 4866 | struct drm_device *dev = intel_dp_to_dev(intel_dp); |
| @@ -4870,6 +4888,11 @@ unlock: | |||
| 4870 | mutex_unlock(&dev_priv->drrs.mutex); | 4888 | mutex_unlock(&dev_priv->drrs.mutex); |
| 4871 | } | 4889 | } |
| 4872 | 4890 | ||
| 4891 | /** | ||
| 4892 | * intel_edp_drrs_disable - Disable DRRS | ||
| 4893 | * @intel_dp: DP struct | ||
| 4894 | * | ||
| 4895 | */ | ||
| 4873 | void intel_edp_drrs_disable(struct intel_dp *intel_dp) | 4896 | void intel_edp_drrs_disable(struct intel_dp *intel_dp) |
| 4874 | { | 4897 | { |
| 4875 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | 4898 | struct drm_device *dev = intel_dp_to_dev(intel_dp); |
| @@ -4929,6 +4952,17 @@ unlock: | |||
| 4929 | mutex_unlock(&dev_priv->drrs.mutex); | 4952 | mutex_unlock(&dev_priv->drrs.mutex); |
| 4930 | } | 4953 | } |
| 4931 | 4954 | ||
| 4955 | /** | ||
| 4956 | * intel_edp_drrs_invalidate - Invalidate DRRS | ||
| 4957 | * @dev: DRM device | ||
| 4958 | * @frontbuffer_bits: frontbuffer plane tracking bits | ||
| 4959 | * | ||
| 4960 | * When there is a disturbance on screen (due to cursor movement/time | ||
| 4961 | * update etc), DRRS needs to be invalidated, i.e. need to switch to | ||
| 4962 | * high RR. | ||
| 4963 | * | ||
| 4964 | * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits. | ||
| 4965 | */ | ||
| 4932 | void intel_edp_drrs_invalidate(struct drm_device *dev, | 4966 | void intel_edp_drrs_invalidate(struct drm_device *dev, |
| 4933 | unsigned frontbuffer_bits) | 4967 | unsigned frontbuffer_bits) |
| 4934 | { | 4968 | { |
| @@ -4956,6 +4990,17 @@ void intel_edp_drrs_invalidate(struct drm_device *dev, | |||
| 4956 | mutex_unlock(&dev_priv->drrs.mutex); | 4990 | mutex_unlock(&dev_priv->drrs.mutex); |
| 4957 | } | 4991 | } |
| 4958 | 4992 | ||
| 4993 | /** | ||
| 4994 | * intel_edp_drrs_flush - Flush DRRS | ||
| 4995 | * @dev: DRM device | ||
| 4996 | * @frontbuffer_bits: frontbuffer plane tracking bits | ||
| 4997 | * | ||
| 4998 | * When there is no movement on screen, DRRS work can be scheduled. | ||
| 4999 | * This DRRS work is responsible for setting relevant registers after a | ||
| 5000 | * timeout of 1 second. | ||
| 5001 | * | ||
| 5002 | * Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits. | ||
| 5003 | */ | ||
| 4959 | void intel_edp_drrs_flush(struct drm_device *dev, | 5004 | void intel_edp_drrs_flush(struct drm_device *dev, |
| 4960 | unsigned frontbuffer_bits) | 5005 | unsigned frontbuffer_bits) |
| 4961 | { | 5006 | { |
| @@ -4980,6 +5025,56 @@ void intel_edp_drrs_flush(struct drm_device *dev, | |||
| 4980 | mutex_unlock(&dev_priv->drrs.mutex); | 5025 | mutex_unlock(&dev_priv->drrs.mutex); |
| 4981 | } | 5026 | } |
| 4982 | 5027 | ||
| 5028 | /** | ||
| 5029 | * DOC: Display Refresh Rate Switching (DRRS) | ||
| 5030 | * | ||
| 5031 | * Display Refresh Rate Switching (DRRS) is a power conservation feature | ||
| 5032 | * which enables swtching between low and high refresh rates, | ||
| 5033 | * dynamically, based on the usage scenario. This feature is applicable | ||
| 5034 | * for internal panels. | ||
| 5035 | * | ||
| 5036 | * Indication that the panel supports DRRS is given by the panel EDID, which | ||
| 5037 | * would list multiple refresh rates for one resolution. | ||
| 5038 | * | ||
| 5039 | * DRRS is of 2 types - static and seamless. | ||
| 5040 | * Static DRRS involves changing refresh rate (RR) by doing a full modeset | ||
| 5041 | * (may appear as a blink on screen) and is used in dock-undock scenario. | ||
| 5042 | * Seamless DRRS involves changing RR without any visual effect to the user | ||
| 5043 | * and can be used during normal system usage. This is done by programming | ||
| 5044 | * certain registers. | ||
| 5045 | * | ||
| 5046 | * Support for static/seamless DRRS may be indicated in the VBT based on | ||
| 5047 | * inputs from the panel spec. | ||
| 5048 | * | ||
| 5049 | * DRRS saves power by switching to low RR based on usage scenarios. | ||
| 5050 | * | ||
| 5051 | * eDP DRRS:- | ||
| 5052 | * The implementation is based on frontbuffer tracking implementation. | ||
| 5053 | * When there is a disturbance on the screen triggered by user activity or a | ||
| 5054 | * periodic system activity, DRRS is disabled (RR is changed to high RR). | ||
| 5055 | * When there is no movement on screen, after a timeout of 1 second, a switch | ||
| 5056 | * to low RR is made. | ||
| 5057 | * For integration with frontbuffer tracking code, | ||
| 5058 | * intel_edp_drrs_invalidate() and intel_edp_drrs_flush() are called. | ||
| 5059 | * | ||
| 5060 | * DRRS can be further extended to support other internal panels and also | ||
| 5061 | * the scenario of video playback wherein RR is set based on the rate | ||
| 5062 | * requested by userspace. | ||
| 5063 | */ | ||
| 5064 | |||
| 5065 | /** | ||
| 5066 | * intel_dp_drrs_init - Init basic DRRS work and mutex. | ||
| 5067 | * @intel_connector: eDP connector | ||
| 5068 | * @fixed_mode: preferred mode of panel | ||
| 5069 | * | ||
| 5070 | * This function is called only once at driver load to initialize basic | ||
| 5071 | * DRRS stuff. | ||
| 5072 | * | ||
| 5073 | * Returns: | ||
| 5074 | * Downclock mode if panel supports it, else return NULL. | ||
| 5075 | * DRRS support is determined by the presence of downclock mode (apart | ||
| 5076 | * from VBT setting). | ||
| 5077 | */ | ||
| 4983 | static struct drm_display_mode * | 5078 | static struct drm_display_mode * |
| 4984 | intel_dp_drrs_init(struct intel_connector *intel_connector, | 5079 | intel_dp_drrs_init(struct intel_connector *intel_connector, |
| 4985 | struct drm_display_mode *fixed_mode) | 5080 | struct drm_display_mode *fixed_mode) |
