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.

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_drrs_invalidate() and intel_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.

void intel_drrs_activate(const struct intel_crtc_state *crtc_state)

activate DRRS

Parameters

const struct intel_crtc_state *crtc_state

the crtc state

Description

Activates DRRS on the crtc.

void intel_drrs_deactivate(const struct intel_crtc_state *old_crtc_state)

deactivate DRRS

Parameters

const struct intel_crtc_state *old_crtc_state

the old crtc state

Description

Deactivates DRRS on the crtc.

void intel_drrs_invalidate(struct intel_display *display, unsigned int frontbuffer_bits)

Disable Idleness DRRS

Parameters

struct intel_display *display

display device

unsigned int frontbuffer_bits

frontbuffer plane tracking bits

Description

This function gets called everytime rendering on the given planes start. Hence DRRS needs to be Upclocked, i.e. (LOW_RR -> HIGH_RR).

Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.

void intel_drrs_flush(struct intel_display *display, unsigned int frontbuffer_bits)

Restart Idleness DRRS

Parameters

struct intel_display *display

display device

unsigned int frontbuffer_bits

frontbuffer plane tracking bits

Description

This function gets called every time rendering on the given planes has completed or flip on a crtc is completed. So DRRS should be upclocked (LOW_RR -> HIGH_RR). And also Idleness detection should be started again, if no other planes are dirty.

Dirty frontbuffers relevant to DRRS are tracked in busy_frontbuffer_bits.

void intel_drrs_crtc_init(struct intel_crtc *crtc)

Init DRRS for CRTC

Parameters

struct intel_crtc *crtc

crtc

Description

This function is called only once at driver load to initialize basic DRRS stuff.