From 05bb3495110143a04568246b23bb6f797275b18b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Roberto=20de=20Souza?= Date: Thu, 19 Sep 2019 14:54:32 -0700 Subject: [PATCH] wip: drm/i915/psr: Implement IO buffer wake and fast wake lines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Roberto de Souza --- drivers/gpu/drm/i915/display/intel_psr.c | 20 +++++++++- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_reg.h | 48 ++++++++++++++---------- 3 files changed, 49 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index b3c7eef53bf3..312616d64f70 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -488,7 +488,7 @@ static void hsw_activate_psr1(struct intel_dp *intel_dp) static void hsw_activate_psr2(struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); - u32 val; + u32 val, lines; /* Let's use 6 as the minimum to cover all known cases including the * off-by-one issue that HW has in some cases. @@ -514,12 +514,29 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp) else val |= EDP_PSR2_TP2_TIME_2500us; + lines = DIV_ROUND_UP(50, dev_priv->psr.wm_linetime_usec); + DRM_DEBUG_KMS("IO buffer wake lines %i\n", lines); + if (lines > EDP_PSR2_IO_BUFFER_WAKE_LINES_MAX) + lines = EDP_PSR2_IO_BUFFER_WAKE_LINES_MAX; + else if (lines < EDP_PSR2_IO_BUFFER_WAKE_LINES_MIN) + lines = EDP_PSR2_IO_BUFFER_WAKE_LINES_MIN; + val |= EDP_PSR2_IO_BUFFER_WAKE_LINES(lines); + + lines = DIV_ROUND_UP(32, dev_priv->psr.wm_linetime_usec); + DRM_DEBUG_KMS("Fast Wake lines %i | wm_linetime_usec=%i\n", lines, dev_priv->psr.wm_linetime_usec); + if (lines > EDP_PSR2_FAST_WAKE_LINES_MAX) + lines = EDP_PSR2_FAST_WAKE_LINES_MAX; + else if (lines < EDP_PSR2_FAST_WAKE_LINES_MIN) + lines = EDP_PSR2_FAST_WAKE_LINES_MIN; + val |= EDP_PSR2_FAST_WAKE_LINES(lines); + /* * PSR2 HW is incorrectly using EDP_PSR_TP1_TP3_SEL and BSpec is * recommending keep this bit unset while PSR2 is enabled. */ I915_WRITE(EDP_PSR_CTL(dev_priv->psr.transcoder), 0); + DRM_DEBUG_KMS("PSR2_CTL val=0x%x\n", val); I915_WRITE(EDP_PSR2_CTL(dev_priv->psr.transcoder), val); } @@ -747,6 +764,7 @@ static void intel_psr_enable_locked(struct drm_i915_private *dev_priv, dev_priv->psr.busy_frontbuffer_bits = 0; dev_priv->psr.pipe = to_intel_crtc(crtc_state->base.crtc)->pipe; dev_priv->psr.transcoder = crtc_state->cpu_transcoder; + dev_priv->psr.wm_linetime_usec = crtc_state->wm.skl.optimal.linetime; /* * If a PSR error happened and the driver is reloaded, the EDP_PSR_IIR diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4faec2f94e19..f14c61d9865e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -499,6 +499,7 @@ struct i915_psr { bool sink_not_reliable; bool irq_aux_error; u16 su_x_granularity; + u32 wm_linetime_usec; }; #define QUIRK_LVDS_SSC_DISABLE (1<<1) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5e3a6178aff4..575884a9595b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4299,25 +4299,35 @@ enum { #define EDP_PSR_DEBUG_MASK_DISP_REG_WRITE (1 << 16) /* Reserved in ICL+ */ #define EDP_PSR_DEBUG_EXIT_ON_PIXEL_UNDERRUN (1 << 15) /* SKL+ */ -#define _PSR2_CTL_A 0x60900 -#define _PSR2_CTL_EDP 0x6f900 -#define EDP_PSR2_CTL(tran) _MMIO_TRANS2(tran, _PSR2_CTL_A) -#define EDP_PSR2_ENABLE (1 << 31) -#define EDP_SU_TRACK_ENABLE (1 << 30) -#define EDP_Y_COORDINATE_VALID (1 << 26) /* GLK and CNL+ */ -#define EDP_Y_COORDINATE_ENABLE (1 << 25) /* GLK and CNL+ */ -#define EDP_MAX_SU_DISABLE_TIME(t) ((t) << 20) -#define EDP_MAX_SU_DISABLE_TIME_MASK (0x1f << 20) -#define EDP_PSR2_TP2_TIME_500us (0 << 8) -#define EDP_PSR2_TP2_TIME_100us (1 << 8) -#define EDP_PSR2_TP2_TIME_2500us (2 << 8) -#define EDP_PSR2_TP2_TIME_50us (3 << 8) -#define EDP_PSR2_TP2_TIME_MASK (3 << 8) -#define EDP_PSR2_FRAME_BEFORE_SU_SHIFT 4 -#define EDP_PSR2_FRAME_BEFORE_SU_MASK (0xf << 4) -#define EDP_PSR2_FRAME_BEFORE_SU(a) ((a) << 4) -#define EDP_PSR2_IDLE_FRAME_MASK 0xf -#define EDP_PSR2_IDLE_FRAME_SHIFT 0 +#define _PSR2_CTL_A 0x60900 +#define _PSR2_CTL_EDP 0x6f900 +#define EDP_PSR2_CTL(tran) _MMIO_TRANS2(tran, _PSR2_CTL_A) +#define EDP_PSR2_ENABLE (1 << 31) +#define EDP_SU_TRACK_ENABLE (1 << 30) +#define EDP_Y_COORDINATE_VALID (1 << 26) /* GLK and CNL+ */ +#define EDP_Y_COORDINATE_ENABLE (1 << 25) /* GLK and CNL+ */ +#define EDP_MAX_SU_DISABLE_TIME(t) ((t) << 20) +#define EDP_MAX_SU_DISABLE_TIME_MASK (0x1f << 20) +#define EDP_PSR2_IO_BUFFER_WAKE_SHIFT (13) +#define EDP_PSR2_IO_BUFFER_WAKE_MASK (0x3 << EDP_PSR2_IO_BUFFER_WAKE_SHIFT) +#define EDP_PSR2_IO_BUFFER_WAKE_LINES_MIN (0x5) +#define EDP_PSR2_IO_BUFFER_WAKE_LINES_MAX (0x8) +#define EDP_PSR2_IO_BUFFER_WAKE_LINES(x) ((0x8 - (x)) << EDP_PSR2_IO_BUFFER_WAKE_SHIFT) +#define EDP_PSR2_FAST_WAKE_SHIFT (11) +#define EDP_PSR2_FAST_WAKE_MASK (0x3 << EDP_PSR2_FAST_WAKE_SHIFT) +#define EDP_PSR2_FAST_WAKE_LINES_MIN (0x5) +#define EDP_PSR2_FAST_WAKE_LINES_MAX (0x8) +#define EDP_PSR2_FAST_WAKE_LINES(x) ((0x8 - (x)) << EDP_PSR2_FAST_WAKE_SHIFT) +#define EDP_PSR2_TP2_TIME_500us (0 << 8) +#define EDP_PSR2_TP2_TIME_100us (1 << 8) +#define EDP_PSR2_TP2_TIME_2500us (2 << 8) +#define EDP_PSR2_TP2_TIME_50us (3 << 8) +#define EDP_PSR2_TP2_TIME_MASK (3 << 8) +#define EDP_PSR2_FRAME_BEFORE_SU_SHIFT 4 +#define EDP_PSR2_FRAME_BEFORE_SU_MASK (0xf << 4) +#define EDP_PSR2_FRAME_BEFORE_SU(a) ((a) << 4) +#define EDP_PSR2_IDLE_FRAME_MASK 0xf +#define EDP_PSR2_IDLE_FRAME_SHIFT 0 #define _PSR_EVENT_TRANS_A 0x60848 #define _PSR_EVENT_TRANS_B 0x61848 -- 2.23.0