Commit b33a2815 authored by Vandana Kannan's avatar Vandana Kannan Committed by Daniel Vetter

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: default avatarVandana Kannan <vandana.kannan@intel.com>
Reviewed-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 44395bfe
...@@ -4051,6 +4051,17 @@ int num_ioctls;</synopsis> ...@@ -4051,6 +4051,17 @@ int num_ioctls;</synopsis>
<title>Frame Buffer Compression (FBC)</title> <title>Frame Buffer Compression (FBC)</title>
!Pdrivers/gpu/drm/i915/intel_fbc.c Frame Buffer Compression (FBC) !Pdrivers/gpu/drm/i915/intel_fbc.c Frame Buffer Compression (FBC)
!Idrivers/gpu/drm/i915/intel_fbc.c !Idrivers/gpu/drm/i915/intel_fbc.c
</sect2>
<sect2>
<title>Display Refresh Rate Switching (DRRS)</title>
!Pdrivers/gpu/drm/i915/intel_dp.c Display Refresh Rate Switching (DRRS)
!Fdrivers/gpu/drm/i915/intel_dp.c intel_dp_set_drrs_state
!Fdrivers/gpu/drm/i915/intel_dp.c intel_edp_drrs_enable
!Fdrivers/gpu/drm/i915/intel_dp.c intel_edp_drrs_disable
!Fdrivers/gpu/drm/i915/intel_dp.c intel_edp_drrs_invalidate
!Fdrivers/gpu/drm/i915/intel_dp.c intel_edp_drrs_flush
!Fdrivers/gpu/drm/i915/intel_dp.c intel_dp_drrs_init
</sect2> </sect2>
<sect2> <sect2>
<title>DPIO</title> <title>DPIO</title>
......
...@@ -4751,6 +4751,18 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, ...@@ -4751,6 +4751,18 @@ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
I915_READ(pp_div_reg)); I915_READ(pp_div_reg));
} }
/**
* intel_dp_set_drrs_state - program registers for RR switch to take effect
* @dev: DRM device
* @refresh_rate: RR to be programmed
*
* This function gets called when refresh rate (RR) has to be changed from
* one frequency to another. Switches can be between high and low RR
* supported by the panel or to any other RR based on media playback (in
* this case, RR value needs to be passed from user space).
*
* The caller of this function needs to take a lock on dev_priv->drrs.
*/
static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate) static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; 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,6 +4855,12 @@ static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate)
DRM_DEBUG_KMS("eDP Refresh Rate set to : %dHz\n", refresh_rate); DRM_DEBUG_KMS("eDP Refresh Rate set to : %dHz\n", refresh_rate);
} }
/**
* intel_edp_drrs_enable - init drrs struct if supported
* @intel_dp: DP struct
*
* Initializes frontbuffer_bits and drrs.dp
*/
void intel_edp_drrs_enable(struct intel_dp *intel_dp) void intel_edp_drrs_enable(struct intel_dp *intel_dp)
{ {
struct drm_device *dev = intel_dp_to_dev(intel_dp); struct drm_device *dev = intel_dp_to_dev(intel_dp);
...@@ -4870,6 +4888,11 @@ void intel_edp_drrs_enable(struct intel_dp *intel_dp) ...@@ -4870,6 +4888,11 @@ void intel_edp_drrs_enable(struct intel_dp *intel_dp)
mutex_unlock(&dev_priv->drrs.mutex); mutex_unlock(&dev_priv->drrs.mutex);
} }
/**
* intel_edp_drrs_disable - Disable DRRS
* @intel_dp: DP struct
*
*/
void intel_edp_drrs_disable(struct intel_dp *intel_dp) void intel_edp_drrs_disable(struct intel_dp *intel_dp)
{ {
struct drm_device *dev = intel_dp_to_dev(intel_dp); struct drm_device *dev = intel_dp_to_dev(intel_dp);
...@@ -4929,6 +4952,17 @@ static void intel_edp_drrs_downclock_work(struct work_struct *work) ...@@ -4929,6 +4952,17 @@ static void intel_edp_drrs_downclock_work(struct work_struct *work)
mutex_unlock(&dev_priv->drrs.mutex); mutex_unlock(&dev_priv->drrs.mutex);
} }
/**
* intel_edp_drrs_invalidate - Invalidate DRRS
* @dev: DRM device
* @frontbuffer_bits: frontbuffer plane tracking bits
*
* When there is a disturbance on screen (due to cursor movement/time
* update etc), DRRS needs to be invalidated, i.e. need to switch to
* high RR.
*
* Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
*/
void intel_edp_drrs_invalidate(struct drm_device *dev, void intel_edp_drrs_invalidate(struct drm_device *dev,
unsigned frontbuffer_bits) unsigned frontbuffer_bits)
{ {
...@@ -4956,6 +4990,17 @@ void intel_edp_drrs_invalidate(struct drm_device *dev, ...@@ -4956,6 +4990,17 @@ void intel_edp_drrs_invalidate(struct drm_device *dev,
mutex_unlock(&dev_priv->drrs.mutex); mutex_unlock(&dev_priv->drrs.mutex);
} }
/**
* intel_edp_drrs_flush - Flush DRRS
* @dev: DRM device
* @frontbuffer_bits: frontbuffer plane tracking bits
*
* When there is no movement on screen, DRRS work can be scheduled.
* This DRRS work is responsible for setting relevant registers after a
* timeout of 1 second.
*
* Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.
*/
void intel_edp_drrs_flush(struct drm_device *dev, void intel_edp_drrs_flush(struct drm_device *dev,
unsigned frontbuffer_bits) unsigned frontbuffer_bits)
{ {
...@@ -4980,6 +5025,56 @@ void intel_edp_drrs_flush(struct drm_device *dev, ...@@ -4980,6 +5025,56 @@ void intel_edp_drrs_flush(struct drm_device *dev,
mutex_unlock(&dev_priv->drrs.mutex); mutex_unlock(&dev_priv->drrs.mutex);
} }
/**
* DOC: Display Refresh Rate Switching (DRRS)
*
* Display Refresh Rate Switching (DRRS) is a power conservation feature
* which enables swtching between low and high refresh rates,
* dynamically, based on the usage scenario. This feature is applicable
* for internal panels.
*
* Indication that the panel supports DRRS is given by the panel EDID, which
* would list multiple refresh rates for one resolution.
*
* DRRS is of 2 types - static and seamless.
* Static DRRS involves changing refresh rate (RR) by doing a full modeset
* (may appear as a blink on screen) and is used in dock-undock scenario.
* Seamless DRRS involves changing RR without any visual effect to the user
* and can be used during normal system usage. This is done by programming
* certain registers.
*
* Support for static/seamless DRRS may be indicated in the VBT based on
* inputs from the panel spec.
*
* DRRS saves power by switching to low RR based on usage scenarios.
*
* eDP DRRS:-
* The implementation is based on frontbuffer tracking implementation.
* When there is a disturbance on the screen triggered by user activity or a
* periodic system activity, DRRS is disabled (RR is changed to high RR).
* When there is no movement on screen, after a timeout of 1 second, a switch
* to low RR is made.
* For integration with frontbuffer tracking code,
* intel_edp_drrs_invalidate() and intel_edp_drrs_flush() are called.
*
* DRRS can be further extended to support other internal panels and also
* the scenario of video playback wherein RR is set based on the rate
* requested by userspace.
*/
/**
* intel_dp_drrs_init - Init basic DRRS work and mutex.
* @intel_connector: eDP connector
* @fixed_mode: preferred mode of panel
*
* This function is called only once at driver load to initialize basic
* DRRS stuff.
*
* Returns:
* Downclock mode if panel supports it, else return NULL.
* DRRS support is determined by the presence of downclock mode (apart
* from VBT setting).
*/
static struct drm_display_mode * static struct drm_display_mode *
intel_dp_drrs_init(struct intel_connector *intel_connector, intel_dp_drrs_init(struct intel_connector *intel_connector,
struct drm_display_mode *fixed_mode) struct drm_display_mode *fixed_mode)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment