Normally we could be in a deep PkgC state all the way up to the point when DSB starts its execution at the transcoders undelayed vblank. The DSB will then have to wait for the hardware to wake up before it can execute anything. This will waste a huge chunk of the vblank time just waiting, and risks the DSB execution spilling into the vertical active period. That will be very bad, especially when programming the LUTs as the anti-collision logic will cause DSB to corrupt LUT writes during vertical active. To avoid these problems we can instruct the DSB to pre-wake the display engine on a specific scanline so that everything will be 100% ready to go when we hit the transcoder's undelayed vblank. One annoyance is that the scanline is specified as just that, a single scanline. So if we happen to start the DSB execution after passing said scanline no DEwake will happen and we may drop back into some PkgC state before reaching the transcoder's undelayed vblank. To prevent that we'll use the "force DEwake" bit to manually force the display engine to stay awake. We'll then have to clear the force bit again after the DSB is done (the force bit remains effective even when the DSB is otherwise disabled). Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20230606191504.18099-18-ville.syrjala@linux.intel.com Reviewed-by: Uma Shankar <uma.shankar@intel.com>
33 lines
904 B
C
33 lines
904 B
C
/* SPDX-License-Identifier: MIT
|
|
*
|
|
* Copyright © 2019 Intel Corporation
|
|
*/
|
|
|
|
#ifndef _INTEL_DSB_H
|
|
#define _INTEL_DSB_H
|
|
|
|
#include <linux/types.h>
|
|
|
|
#include "i915_reg_defs.h"
|
|
|
|
struct intel_crtc;
|
|
struct intel_crtc_state;
|
|
struct intel_dsb;
|
|
|
|
struct intel_dsb *intel_dsb_prepare(const struct intel_crtc_state *crtc_state,
|
|
unsigned int max_cmds);
|
|
void intel_dsb_finish(struct intel_dsb *dsb);
|
|
void intel_dsb_cleanup(struct intel_dsb *dsb);
|
|
void intel_dsb_reg_write(struct intel_dsb *dsb,
|
|
i915_reg_t reg, u32 val);
|
|
void intel_dsb_reg_write_masked(struct intel_dsb *dsb,
|
|
i915_reg_t reg, u32 mask, u32 val);
|
|
void intel_dsb_noop(struct intel_dsb *dsb, int count);
|
|
void intel_dsb_nonpost_start(struct intel_dsb *dsb);
|
|
void intel_dsb_nonpost_end(struct intel_dsb *dsb);
|
|
|
|
void intel_dsb_commit(struct intel_dsb *dsb,
|
|
bool wait_for_vblank);
|
|
void intel_dsb_wait(struct intel_dsb *dsb);
|
|
|
|
#endif
|