mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-09-22 09:34:56 +02:00
drm/i915/display: Mask RO bits in gen9_write_dc_state()
The DC_STATE_EN register has read-only status bits that are set by hardware on some platforms. These bits may cause the read-back verification loop in gen9_write_dc_state() to spuriously retry. Mask the RO bits from the read-back comparison to prevent unnecessary retries. Changes in v2: - Rename patch from "drm/i915/display: Use rmw in gen9_write_dc_state() to preserve non-DC bits" to "drm/i915/display: Mask RO bits in gen9_write_dc_state()" - Mask only RO bits rather than masking all non DC state bits in DC_STATE_EN. As the register has also some clear-on-write flags, like 'Display DC*CO State Status DSI'(Imre Deak) Changes in v3: - Limit ro mask to read-back comparison. Changes in v4: - Add bit definitions (Jani Nikula) BSpec: 49437,69115 Signed-off-by: Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian@intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> Signed-off-by: Animesh Manna <animesh.manna@intel.com> Link: https://patch.msgid.link/20260605155359.4116572-1-dibin.moolakadan.subrahmanian@intel.com
This commit is contained in:
committed by
Animesh Manna
parent
fe12dfaef7
commit
94c0b93dc2
@@ -726,12 +726,28 @@ static void assert_can_disable_dc9(struct intel_display *display)
|
||||
*/
|
||||
}
|
||||
|
||||
static u32 dc_state_ro_mask(struct intel_display *display)
|
||||
{
|
||||
if (DISPLAY_VER(display) >= 20)
|
||||
return DC_STATE_EN_CSR_MASK_CMTG_1 | DC_STATE_EN_CSR_MASK_CMTG_0;
|
||||
else if (DISPLAY_VER(display) >= 13 && !display->platform.dg2)
|
||||
return DC_STATE_EN_CSR_MASK_CMTG_0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gen9_write_dc_state(struct intel_display *display,
|
||||
u32 state)
|
||||
{
|
||||
int rewrites = 0;
|
||||
int rereads = 0;
|
||||
u32 v;
|
||||
/*
|
||||
* Mask out RO status bits from read-back comparison.
|
||||
* HW may set these bits independently, so exclude them
|
||||
* to prevent the verify loop from retrying due to RO bits mismatch.
|
||||
*/
|
||||
u32 ro_mask = dc_state_ro_mask(display);
|
||||
|
||||
intel_de_write(display, DC_STATE_EN, state);
|
||||
|
||||
@@ -743,7 +759,7 @@ static void gen9_write_dc_state(struct intel_display *display,
|
||||
do {
|
||||
v = intel_de_read(display, DC_STATE_EN);
|
||||
|
||||
if (v != state) {
|
||||
if ((v & ~ro_mask) != (state & ~ro_mask)) {
|
||||
intel_de_write(display, DC_STATE_EN, state);
|
||||
rewrites++;
|
||||
rereads = 0;
|
||||
@@ -753,10 +769,10 @@ static void gen9_write_dc_state(struct intel_display *display,
|
||||
|
||||
} while (rewrites < 100);
|
||||
|
||||
if (v != state)
|
||||
if ((v & ~ro_mask) != (state & ~ro_mask))
|
||||
drm_err(display->drm,
|
||||
"Writing dc state to 0x%x failed, now 0x%x\n",
|
||||
state, v);
|
||||
"Writing dc state to 0x%x failed, now 0x%x (ro_mask=0x%x)\n",
|
||||
state, v, ro_mask);
|
||||
|
||||
/* Most of the times we need one retry, avoid spam */
|
||||
if (rewrites > 1)
|
||||
|
||||
@@ -3081,6 +3081,10 @@ enum skl_power_gate {
|
||||
#define DC_STATE_EN_UPTO_DC5 REG_FIELD_PREP(DC_STATE_EN_UPTO_DC3CO_DC5_DC6_MASK, 1)
|
||||
#define DC_STATE_EN_UPTO_DC6 REG_FIELD_PREP(DC_STATE_EN_UPTO_DC3CO_DC5_DC6_MASK, 2)
|
||||
#define DC_STATE_EN_UPTO_DC3CO REG_FIELD_PREP(DC_STATE_EN_UPTO_DC3CO_DC5_DC6_MASK, 3)
|
||||
/* display version 20+ */
|
||||
#define DC_STATE_EN_CSR_MASK_CMTG_1 REG_BIT(11)
|
||||
/* display version 13+, except dg2 */
|
||||
#define DC_STATE_EN_CSR_MASK_CMTG_0 REG_BIT(10)
|
||||
|
||||
#define DC_STATE_DEBUG _MMIO(0x45520)
|
||||
#define DC_STATE_DEBUG_MASK_CORES (1 << 0)
|
||||
|
||||
Reference in New Issue
Block a user