diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 05cb65b9882554f232d0607980a8ffe8c87328db..c981881cacb6714e4a51278fb18b78d98522f09a 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -85,6 +85,91 @@ * use page flips. */ +/* + * Description of PSR mask bits: + * + * EDP_PSR_DEBUG[16]/EDP_PSR_DEBUG_MASK_DISP_REG_WRITE (hsw-skl): + * + * When unmasked (nearly) all display register writes (eg. even + * SWF) trigger a PSR exit. Some registers are excluded from this + * and they have a more specific mask (described below). On icl+ + * this bit no longer exists and is effectively always set. + * + * PIPE_MISC[21]/PIPE_MISC_PSR_MASK_PIPE_REG_WRITE (skl+): + * + * When unmasked (nearly) all pipe/plane register writes + * trigger a PSR exit. Some plane registers are excluded from this + * and they have a more specific mask (described below). + * + * CHICKEN_PIPESL_1[11]/SKL_PSR_MASK_PLANE_FLIP (skl+): + * PIPE_MISC[23]/PIPE_MISC_PSR_MASK_PRIMARY_FLIP (bdw): + * EDP_PSR_DEBUG[23]/EDP_PSR_DEBUG_MASK_PRIMARY_FLIP (hsw): + * + * When unmasked PRI_SURF/PLANE_SURF writes trigger a PSR exit. + * SPR_SURF/CURBASE are not included in this and instead are + * controlled by PIPE_MISC_PSR_MASK_PIPE_REG_WRITE (skl+) or + * EDP_PSR_DEBUG_MASK_DISP_REG_WRITE (hsw/bdw). + * + * PIPE_MISC[22]/PIPE_MISC_PSR_MASK_SPRITE_ENABLE (bdw): + * EDP_PSR_DEBUG[21]/EDP_PSR_DEBUG_MASK_SPRITE_ENABLE (hsw): + * + * When unmasked PSR is blocked as long as the sprite + * plane is enabled. skl+ with their universal planes no + * longer have a mask bit like this, and no plane being + * enabledb blocks PSR. + * + * PIPE_MISC[21]/PIPE_MISC_PSR_MASK_CURSOR_MOVE (bdw): + * EDP_PSR_DEBUG[20]/EDP_PSR_DEBUG_MASK_CURSOR_MOVE (hsw): + * + * When umasked CURPOS writes trigger a PSR exit. On skl+ + * this doesn't exit but CURPOS is included in the + * PIPE_MISC_PSR_MASK_PIPE_REG_WRITE mask. + * + * PIPE_MISC[20]/PIPE_MISC_PSR_MASK_VBLANK_VSYNC_INT (bdw+): + * EDP_PSR_DEBUG[19]/EDP_PSR_DEBUG_MASK_VBLANK_VSYNC_INT (hsw): + * + * When unmasked PSR is blocked as long as vblank and/or vsync + * interrupt is unmasked in IMR *and* enabled in IER. + * + * CHICKEN_TRANS[30]/SKL_UNMASK_VBL_TO_PIPE_IN_SRD (skl+): + * CHICKEN_PAR1_1[15]/HSW_MASK_VBL_TO_PIPE_IN_SRD (hsw/bdw): + * + * Selectcs whether PSR exit generates an extra vblank before + * the first frame is transmitted. Also note the opposite polarity + * if the bit on hsw/bdw vs. skl+ (masked==generate the extra vblank, + * unmasked==do not generate the extra vblank). + * + * With DC states enabled the extra vblank happens after link training, + * with DC states disabled it happens immediately upuon PSR exit trigger. + * No idea as of now why there is a difference. HSW/BDW (which don't + * even have DMC) always generate it after link training. Go figure. + * + * Unfortunately CHICKEN_TRANS itself seems to be double buffered + * and thus won't latch until the first vblank. So with DC states + * enabled the register effctively uses the reset value during DC5 + * exit+PSR exit sequence, and thus the bit does nothing until + * latched by the vblank that it was trying to prevent from being + * generated in the first place. So we should probably call this + * one a chicken/egg bit instead on skl+. + * + * In standby mode (as opposed to link-off) this makes no difference + * as the timing generator keeps running the whole time generating + * normal periodic vblanks. + * + * WaPsrDPAMaskVBlankInSRD asks us to set the bit on hsw/bdw, + * and doing so makes the behaviour match the skl+ reset value. + * + * CHICKEN_PIPESL_1[0]/BDW_UNMASK_VBL_TO_REGS_IN_SRD (bdw): + * CHICKEN_PIPESL_1[15]/HSW_UNMASK_VBL_TO_REGS_IN_SRD (hsw): + * + * On BDW without this bit is no vblanks whatsoever are + * generated after PSR exit. On HSW this has no apparant effect. + * WaPsrDPRSUnmaskVBlankInSRD says to set this. + * + * The rest of the bits are more self-explanatory and/or + * irrelevant for normal operation. + */ + static bool psr_global_enabled(struct intel_dp *intel_dp) { struct intel_connector *connector = intel_dp->attached_connector; diff --git a/drivers/gpu/drm/i915/display/intel_psr_regs.h b/drivers/gpu/drm/i915/display/intel_psr_regs.h index 4cef32f47402e23c9294dd878277d25f04507d88..0f7db617425a357dc361ff3bbeac5cc5b63ff115 100644 --- a/drivers/gpu/drm/i915/display/intel_psr_regs.h +++ b/drivers/gpu/drm/i915/display/intel_psr_regs.h @@ -120,8 +120,18 @@ #define EDP_PSR_DEBUG_MASK_LPSP REG_BIT(27) #define EDP_PSR_DEBUG_MASK_MEMUP REG_BIT(26) #define EDP_PSR_DEBUG_MASK_HPD REG_BIT(25) -#define EDP_PSR_DEBUG_MASK_DISP_REG_WRITE REG_BIT(16) /* Reserved in ICL+ */ -#define EDP_PSR_DEBUG_EXIT_ON_PIXEL_UNDERRUN REG_BIT(15) /* SKL+ */ +#define EDP_PSR_DEBUG_MASK_FBC_MODIFY REG_BIT(24) +#define EDP_PSR_DEBUG_MASK_PRIMARY_FLIP REG_BIT(23) /* hsw */ +#define EDP_PSR_DEBUG_MASK_HDCP_ENABLE REG_BIT(22) /* hsw/bdw */ +#define EDP_PSR_DEBUG_MASK_SPRITE_ENABLE REG_BIT(21) /* hsw */ +#define EDP_PSR_DEBUG_MASK_CURSOR_MOVE REG_BIT(20) /* hsw */ +#define EDP_PSR_DEBUG_MASK_VBLANK_VSYNC_INT REG_BIT(19) /* hsw */ +#define EDP_PSR_DEBUG_MASK_DPST_PHASE_IN REG_BIT(18) /* hsw */ +#define EDP_PSR_DEBUG_MASK_KVMR_SESSION_EN REG_BIT(17) +#define EDP_PSR_DEBUG_MASK_DISP_REG_WRITE REG_BIT(16) /* hsw-skl */ +#define EDP_PSR_DEBUG_EXIT_ON_PIXEL_UNDERRUN REG_BIT(15) /* skl+ */ +#define EDP_PSR_DEBUG_RFB_UPDATE_SENT REG_BIT(2) /* bdw */ +#define EDP_PSR_DEBUG_ENTRY_COMPLETION REG_BIT(1) /* hsw/bdw */ #define _PSR2_CTL_A 0x60900 #define _PSR2_CTL_EDP 0x6f900 diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 366efba8796f71d69a34b0096e9a1a674d5eb6f2..831a89841934e6f7112999c80475cf916a94847c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2648,6 +2648,11 @@ #define PIPE_MISC_YUV420_ENABLE REG_BIT(27) /* glk+ */ #define PIPE_MISC_YUV420_MODE_FULL_BLEND REG_BIT(26) /* glk+ */ #define PIPE_MISC_HDR_MODE_PRECISION REG_BIT(23) /* icl+ */ +#define PIPE_MISC_PSR_MASK_PRIMARY_FLIP REG_BIT(23) /* bdw */ +#define PIPE_MISC_PSR_MASK_SPRITE_ENABLE REG_BIT(22) /* bdw */ +#define PIPE_MISC_PSR_MASK_PIPE_REG_WRITE REG_BIT(21) /* skl+ */ +#define PIPE_MISC_PSR_MASK_CURSOR_MOVE REG_BIT(21) /* bdw */ +#define PIPE_MISC_PSR_MASK_VBLANK_VSYNC_INT REG_BIT(20) #define PIPE_MISC_OUTPUT_COLORSPACE_YUV REG_BIT(11) #define PIPE_MISC_PIXEL_ROUNDING_TRUNC REG_BIT(8) /* tgl+ */ /* @@ -4533,7 +4538,7 @@ #define KBL_ARB_FILL_SPARE_22 REG_BIT(22) #define DIS_RAM_BYPASS_PSR2_MAN_TRACK REG_BIT(16) #define SKL_DE_COMPRESSED_HASH_MODE REG_BIT(15) -#define DPA_MASK_VBLANK_SRD REG_BIT(15) +#define HSW_MASK_VBL_TO_PIPE_IN_SRD REG_BIT(15) /* hsw/bdw */ #define FORCE_ARB_IDLE_PLANES REG_BIT(14) #define SKL_EDP_PSR_FIX_RDWRAP REG_BIT(3) #define IGNORE_PSR2_HW_TRACKING REG_BIT(1) @@ -4568,12 +4573,14 @@ #define HSW_SPR_STRETCH_MAX_X2 REG_FIELD_PREP(HSW_SPR_STRETCH_MAX_MASK, 2) #define HSW_SPR_STRETCH_MAX_X1 REG_FIELD_PREP(HSW_SPR_STRETCH_MAX_MASK, 3) #define HSW_FBCQ_DIS REG_BIT(22) +#define HSW_UNMASK_VBL_TO_REGS_IN_SRD REG_BIT(15) /* hsw */ +#define SKL_PSR_MASK_PLANE_FLIP REG_BIT(11) /* skl+ */ #define SKL_PLANE1_STRETCH_MAX_MASK REG_GENMASK(1, 0) #define SKL_PLANE1_STRETCH_MAX_X8 REG_FIELD_PREP(SKL_PLANE1_STRETCH_MAX_MASK, 0) #define SKL_PLANE1_STRETCH_MAX_X4 REG_FIELD_PREP(SKL_PLANE1_STRETCH_MAX_MASK, 1) #define SKL_PLANE1_STRETCH_MAX_X2 REG_FIELD_PREP(SKL_PLANE1_STRETCH_MAX_MASK, 2) #define SKL_PLANE1_STRETCH_MAX_X1 REG_FIELD_PREP(SKL_PLANE1_STRETCH_MAX_MASK, 3) -#define BDW_DPRS_MASK_VBLANK_SRD REG_BIT(0) +#define BDW_UNMASK_VBL_TO_REGS_IN_SRD REG_BIT(0) /* bdw */ #define _CHICKEN_TRANS_A 0x420c0 #define _CHICKEN_TRANS_B 0x420c4 @@ -4592,6 +4599,7 @@ _MTL_CHICKEN_TRANS_A, \ _MTL_CHICKEN_TRANS_B) #define PIPE_VBLANK_WITH_DELAY REG_BIT(31) /* ADL/DG2 */ +#define SKL_UNMASK_VBL_TO_PIPE_IN_SRD REG_BIT(30) /* skl+ */ #define HSW_FRAME_START_DELAY_MASK REG_GENMASK(28, 27) #define HSW_FRAME_START_DELAY(x) REG_FIELD_PREP(HSW_FRAME_START_DELAY_MASK, x) #define VSC_DATA_SEL_SOFTWARE_CONTROL REG_BIT(25) /* GLK */ diff --git a/drivers/gpu/drm/i915/intel_clock_gating.c b/drivers/gpu/drm/i915/intel_clock_gating.c index 1d796b76f71b9821b8d39fa494a5efd194c4d97a..a27600bc597663b06ee3d549371de37c71896080 100644 --- a/drivers/gpu/drm/i915/intel_clock_gating.c +++ b/drivers/gpu/drm/i915/intel_clock_gating.c @@ -521,12 +521,12 @@ static void bdw_init_clock_gating(struct drm_i915_private *i915) intel_uncore_rmw(&i915->uncore, GAM_ECOCHK, 0, HSW_ECOCHK_ARB_PRIO_SOL); /* WaPsrDPAMaskVBlankInSRD:bdw */ - intel_uncore_rmw(&i915->uncore, CHICKEN_PAR1_1, 0, DPA_MASK_VBLANK_SRD); + intel_uncore_rmw(&i915->uncore, CHICKEN_PAR1_1, 0, HSW_MASK_VBL_TO_PIPE_IN_SRD); for_each_pipe(i915, pipe) { /* WaPsrDPRSUnmaskVBlankInSRD:bdw */ intel_uncore_rmw(&i915->uncore, CHICKEN_PIPESL_1(pipe), - 0, BDW_DPRS_MASK_VBLANK_SRD); + 0, BDW_UNMASK_VBL_TO_REGS_IN_SRD); } /* WaVSRefCountFullforceMissDisable:bdw */