From 779cb5ba64ec7df80675a956c9022929514f517a Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 20 Mar 2023 11:05:17 +0200 Subject: drm/i915/dpt: Treat the DPT BO as a framebuffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently i915_gem_object_is_framebuffer() doesn't treat the BO containing the framebuffer's DPT as a framebuffer itself. This means eg. that the shrinker can evict the DPT BO while leaving the actual FB BO bound, when the DPT is allocated from regular shmem. That causes an immediate oops during hibernate as we try to rewrite the PTEs inside the already evicted DPT obj. TODO: presumably this might also be the reason for the DPT related display faults under heavy memory pressure, but I'm still not sure how that would happen as the object should be pinned by intel_dpt_pin() while in active use by the display engine... Cc: stable@vger.kernel.org Cc: Juha-Pekka Heikkila Cc: Matthew Auld Cc: Imre Deak Fixes: 0dc987b699ce ("drm/i915/display: Add smem fallback allocation for dpt") Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230320090522.9909-2-ville.syrjala@linux.intel.com Reviewed-by: Juha-Pekka Heikkila --- drivers/gpu/drm/i915/display/intel_dpt.c | 2 ++ drivers/gpu/drm/i915/gem/i915_gem_object.h | 2 +- drivers/gpu/drm/i915/gem/i915_gem_object_types.h | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c b/drivers/gpu/drm/i915/display/intel_dpt.c index ad1a37b515fb..2a9f40a2b3ed 100644 --- a/drivers/gpu/drm/i915/display/intel_dpt.c +++ b/drivers/gpu/drm/i915/display/intel_dpt.c @@ -301,6 +301,7 @@ intel_dpt_create(struct intel_framebuffer *fb) vm->pte_encode = gen8_ggtt_pte_encode; dpt->obj = dpt_obj; + dpt->obj->is_dpt = true; return &dpt->vm; } @@ -309,5 +310,6 @@ void intel_dpt_destroy(struct i915_address_space *vm) { struct i915_dpt *dpt = i915_vm_to_dpt(vm); + dpt->obj->is_dpt = false; i915_vm_put(&dpt->vm); } diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index f9a8acbba715..885ccde9dc3c 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h @@ -303,7 +303,7 @@ i915_gem_object_never_mmap(const struct drm_i915_gem_object *obj) static inline bool i915_gem_object_is_framebuffer(const struct drm_i915_gem_object *obj) { - return READ_ONCE(obj->frontbuffer); + return READ_ONCE(obj->frontbuffer) || obj->is_dpt; } static inline unsigned int diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h index 19c9bdd8f905..5dcbbef31d44 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h @@ -491,6 +491,9 @@ struct drm_i915_gem_object { */ unsigned int cache_dirty:1; + /* @is_dpt: Object houses a display page table (DPT) */ + unsigned int is_dpt:1; + /** * @read_domains: Read memory domains. * -- cgit v1.2.3-59-g8ed1b From ef5cb493a9acd7d97870d6e542020980ae3f3483 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 20 Mar 2023 11:05:18 +0200 Subject: drm/i915/dpt: Only do the POT stride remap when using DPT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we want to test with DPT disabled on ADL the POT stride remap stuff needs to be disabled. Make it depend on actual DPT usage instead of just assuming it based on the modifier. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230320090522.9909-3-ville.syrjala@linux.intel.com Reviewed-by: Juha-Pekka Heikkila --- drivers/gpu/drm/i915/display/intel_fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 799bdc81a6a9..26ad5fc0c2c1 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -1189,7 +1189,7 @@ bool intel_fb_needs_pot_stride_remap(const struct intel_framebuffer *fb) { struct drm_i915_private *i915 = to_i915(fb->base.dev); - return IS_ALDERLAKE_P(i915) && fb->base.modifier != DRM_FORMAT_MOD_LINEAR; + return IS_ALDERLAKE_P(i915) && intel_fb_uses_dpt(&fb->base); } static int intel_fb_pitch(const struct intel_framebuffer *fb, int color_plane, unsigned int rotation) -- cgit v1.2.3-59-g8ed1b From bb8494423e2e4dbac9ece7eebba421011bafe389 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 20 Mar 2023 11:05:19 +0200 Subject: drm/i915/dpt: Introduce HAS_DPT() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the hand rolled DISPLAY_VER check for a more descriptive HAS_DPT() macro. Will be used on more than one place later. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230320090522.9909-4-ville.syrjala@linux.intel.com Reviewed-by: Juha-Pekka Heikkila --- drivers/gpu/drm/i915/display/intel_fb.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 26ad5fc0c2c1..9609c5de3f91 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -718,7 +718,7 @@ static unsigned int intel_fb_modifier_to_tiling(u64 fb_modifier) static bool intel_modifier_uses_dpt(struct drm_i915_private *i915, u64 modifier) { - return DISPLAY_VER(i915) >= 13 && modifier != DRM_FORMAT_MOD_LINEAR; + return HAS_DPT(i915) && modifier != DRM_FORMAT_MOD_LINEAR; } bool intel_fb_uses_dpt(const struct drm_framebuffer *fb) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index de1977ef4ddd..52122228222f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -809,6 +809,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915, #define HAS_FBC(dev_priv) (RUNTIME_INFO(dev_priv)->fbc_mask != 0) #define HAS_CUR_FBC(dev_priv) (!HAS_GMCH(dev_priv) && DISPLAY_VER(dev_priv) >= 7) +#define HAS_DPT(dev_priv) (DISPLAY_VER(dev_priv) >= 13) + #define HAS_IPS(dev_priv) (IS_HSW_ULT(dev_priv) || IS_BROADWELL(dev_priv)) #define HAS_DP_MST(dev_priv) (INTEL_INFO(dev_priv)->display.has_dp_mst) -- cgit v1.2.3-59-g8ed1b From 5a08585d38d66dd64b8ae22229bdfae3fdc1ef3e Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 20 Mar 2023 11:05:20 +0200 Subject: drm/i915: Add PLANE_CHICKEN registers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define the PLANE_CHICKEN register offsets. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230320090522.9909-5-ville.syrjala@linux.intel.com Reviewed-by: Juha-Pekka Heikkila --- drivers/gpu/drm/i915/i915_reg.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index ce7dec4c24f2..86a8860e610b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4644,6 +4644,8 @@ #define PLANE_COLOR_ALPHA_DISABLE REG_FIELD_PREP(PLANE_COLOR_ALPHA_MASK, 0) #define PLANE_COLOR_ALPHA_SW_PREMULTIPLY REG_FIELD_PREP(PLANE_COLOR_ALPHA_MASK, 2) #define PLANE_COLOR_ALPHA_HW_PREMULTIPLY REG_FIELD_PREP(PLANE_COLOR_ALPHA_MASK, 3) +#define _PLANE_CHICKEN_1_A 0x7026C +#define _PLANE_CHICKEN_2_A 0x7036C #define _PLANE_BUF_CFG_1_A 0x7027c #define _PLANE_BUF_CFG_2_A 0x7037c #define _PLANE_NV12_BUF_CFG_1_A 0x70278 @@ -4789,6 +4791,13 @@ #define PLANE_SURFLIVE(pipe, plane) \ _MMIO_PLANE(plane, _PLANE_SURFLIVE_1(pipe), _PLANE_SURFLIVE_2(pipe)) +#define _PLANE_CHICKEN_1_B 0x7126c +#define _PLANE_CHICKEN_2_B 0x7136c +#define _PLANE_CHICKEN_1(pipe) _PIPE(pipe, _PLANE_CHICKEN_1_A, _PLANE_CHICKEN_1_B) +#define _PLANE_CHICKEN_2(pipe) _PIPE(pipe, _PLANE_CHICKEN_2_A, _PLANE_CHICKEN_2_B) +#define PLANE_CHICKEN(pipe, plane) \ + _MMIO_PLANE(plane, _PLANE_CHICKEN_1(pipe), _PLANE_CHICKEN_2(pipe)) + #define _PLANE_BUF_CFG_1_B 0x7127c #define _PLANE_BUF_CFG_2_B 0x7137c /* skl+: 10 bits, icl+ 11 bits, adlp+ 12 bits */ -- cgit v1.2.3-59-g8ed1b From c5de248484afeb6de259239a23645790038d9df3 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 20 Mar 2023 11:05:21 +0200 Subject: drm/i915/dpt: Add a modparam to disable DPT via the chicken bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add i915.enable_dpt modparam to allow disabling the DPT usage in hardware via the chicken bit. Useful when debugging potential DPT issues. Quickly smoke tested on ADL. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230320090522.9909-6-ville.syrjala@linux.intel.com Reviewed-by: Juha-Pekka Heikkila --- drivers/gpu/drm/i915/display/intel_display.c | 6 ++++++ drivers/gpu/drm/i915/display/intel_dpt.c | 21 +++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_dpt.h | 2 ++ drivers/gpu/drm/i915/display/intel_fb.c | 7 ++++--- drivers/gpu/drm/i915/display/intel_fb.h | 1 + drivers/gpu/drm/i915/display/skl_universal_plane.c | 6 ++++++ drivers/gpu/drm/i915/i915_params.c | 3 +++ drivers/gpu/drm/i915/i915_params.h | 1 + drivers/gpu/drm/i915/i915_reg.h | 2 ++ 9 files changed, 46 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 31585f4aa163..37d03380b844 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -6968,6 +6968,12 @@ static void intel_update_crtc(struct intel_atomic_state *state, intel_atomic_get_new_crtc_state(state, crtc); bool modeset = intel_crtc_needs_modeset(new_crtc_state); + if (old_crtc_state->inherited || + intel_crtc_needs_modeset(new_crtc_state)) { + if (HAS_DPT(i915)) + intel_dpt_configure(crtc); + } + if (!modeset) { if (new_crtc_state->preload_luts && intel_crtc_needs_color_update(new_crtc_state)) diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c b/drivers/gpu/drm/i915/display/intel_dpt.c index 2a9f40a2b3ed..2bf5cce232d5 100644 --- a/drivers/gpu/drm/i915/display/intel_dpt.c +++ b/drivers/gpu/drm/i915/display/intel_dpt.c @@ -9,6 +9,8 @@ #include "gt/gen8_ppgtt.h" #include "i915_drv.h" +#include "i915_reg.h" +#include "intel_de.h" #include "intel_display_types.h" #include "intel_dpt.h" #include "intel_fb.h" @@ -313,3 +315,22 @@ void intel_dpt_destroy(struct i915_address_space *vm) dpt->obj->is_dpt = false; i915_vm_put(&dpt->vm); } + +void intel_dpt_configure(struct intel_crtc *crtc) +{ + struct drm_i915_private *i915 = to_i915(crtc->base.dev); + + if (DISPLAY_VER(i915) == 14) { + enum pipe pipe = crtc->pipe; + enum plane_id plane_id; + + for_each_plane_id_on_crtc(crtc, plane_id) + intel_de_rmw(i915, PLANE_CHICKEN(pipe, plane_id), + PLANE_CHICKEN_DISABLE_DPT, + i915->params.enable_dpt ? 0 : PLANE_CHICKEN_DISABLE_DPT); + } else if (DISPLAY_VER(i915) == 13) { + intel_de_rmw(i915, CHICKEN_MISC_2, + CHICKEN_MISC_DISABLE_DPT, + i915->params.enable_dpt ? 0 : CHICKEN_MISC_DISABLE_DPT); + } +} diff --git a/drivers/gpu/drm/i915/display/intel_dpt.h b/drivers/gpu/drm/i915/display/intel_dpt.h index e18a9f767b11..d9a166550185 100644 --- a/drivers/gpu/drm/i915/display/intel_dpt.h +++ b/drivers/gpu/drm/i915/display/intel_dpt.h @@ -10,6 +10,7 @@ struct drm_i915_private; struct i915_address_space; struct i915_vma; +struct intel_crtc; struct intel_framebuffer; void intel_dpt_destroy(struct i915_address_space *vm); @@ -19,5 +20,6 @@ void intel_dpt_suspend(struct drm_i915_private *i915); void intel_dpt_resume(struct drm_i915_private *i915); struct i915_address_space * intel_dpt_create(struct intel_framebuffer *fb); +void intel_dpt_configure(struct intel_crtc *crtc); #endif /* __INTEL_DPT_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index 9609c5de3f91..e5f637897b5e 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -716,14 +716,15 @@ static unsigned int intel_fb_modifier_to_tiling(u64 fb_modifier) } } -static bool intel_modifier_uses_dpt(struct drm_i915_private *i915, u64 modifier) +bool intel_fb_modifier_uses_dpt(struct drm_i915_private *i915, u64 modifier) { return HAS_DPT(i915) && modifier != DRM_FORMAT_MOD_LINEAR; } bool intel_fb_uses_dpt(const struct drm_framebuffer *fb) { - return fb && intel_modifier_uses_dpt(to_i915(fb->dev), fb->modifier); + return fb && to_i915(fb->dev)->params.enable_dpt && + intel_fb_modifier_uses_dpt(to_i915(fb->dev), fb->modifier); } unsigned int intel_cursor_alignment(const struct drm_i915_private *i915) @@ -1705,7 +1706,7 @@ u32 intel_fb_max_stride(struct drm_i915_private *dev_priv, * The new CCS hash mode makes remapping impossible */ if (DISPLAY_VER(dev_priv) < 4 || intel_fb_is_ccs_modifier(modifier) || - intel_modifier_uses_dpt(dev_priv, modifier)) + intel_fb_modifier_uses_dpt(dev_priv, modifier)) return intel_plane_fb_max_stride(dev_priv, pixel_format, modifier); else if (DISPLAY_VER(dev_priv) >= 7) return 256 * 1024; diff --git a/drivers/gpu/drm/i915/display/intel_fb.h b/drivers/gpu/drm/i915/display/intel_fb.h index 4662b812b934..e85167d6bc34 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.h +++ b/drivers/gpu/drm/i915/display/intel_fb.h @@ -92,6 +92,7 @@ intel_user_framebuffer_create(struct drm_device *dev, struct drm_file *filp, const struct drm_mode_fb_cmd2 *user_mode_cmd); +bool intel_fb_modifier_uses_dpt(struct drm_i915_private *i915, u64 modifier); bool intel_fb_uses_dpt(const struct drm_framebuffer *fb); #endif /* __INTEL_FB_H__ */ diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index fd0065a46ec5..8ea0598a5a07 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -2475,6 +2475,12 @@ skl_get_initial_plane_config(struct intel_crtc *crtc, goto error; } + if (!dev_priv->params.enable_dpt && + intel_fb_modifier_uses_dpt(dev_priv, fb->modifier)) { + drm_dbg_kms(&dev_priv->drm, "DPT disabled, skipping initial FB\n"); + goto error; + } + /* * DRM_MODE_ROTATE_ is counter clockwise to stay compatible with Xrandr * while i915 HW rotation is clockwise, thats why this swapping. diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index ade744cccfea..bec94feb512d 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -131,6 +131,9 @@ i915_param_named_unsafe(disable_power_well, int, 0400, i915_param_named_unsafe(enable_ips, int, 0400, "Enable IPS (default: true)"); +i915_param_named_unsafe(enable_dpt, bool, 0400, + "Enable display page table (DPT) (default: true)"); + i915_param_named(fastboot, int, 0400, "Try to skip unnecessary mode sets at boot time " "(0=disabled, 1=enabled) " diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h index 3f51f90145b6..d824fe6d266e 100644 --- a/drivers/gpu/drm/i915/i915_params.h +++ b/drivers/gpu/drm/i915/i915_params.h @@ -54,6 +54,7 @@ struct drm_printer; param(int, enable_dc, -1, 0400) \ param(int, enable_fbc, -1, 0600) \ param(int, enable_psr, -1, 0600) \ + param(bool, enable_dpt, true, 0400) \ param(bool, psr_safest_params, false, 0400) \ param(bool, enable_psr2_sel_fetch, true, 0400) \ param(int, disable_power_well, -1, 0400) \ diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 86a8860e610b..053986029c6a 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4646,6 +4646,7 @@ #define PLANE_COLOR_ALPHA_HW_PREMULTIPLY REG_FIELD_PREP(PLANE_COLOR_ALPHA_MASK, 3) #define _PLANE_CHICKEN_1_A 0x7026C #define _PLANE_CHICKEN_2_A 0x7036C +#define PLANE_CHICKEN_DISABLE_DPT REG_BIT(19) /* mtl+ */ #define _PLANE_BUF_CFG_1_A 0x7027c #define _PLANE_BUF_CFG_2_A 0x7037c #define _PLANE_NV12_BUF_CFG_1_A 0x70278 @@ -5510,6 +5511,7 @@ #define KVM_CONFIG_CHANGE_NOTIFICATION_SELECT (1 << 14) #define CHICKEN_MISC_2 _MMIO(0x42084) +#define CHICKEN_MISC_DISABLE_DPT REG_BIT(30) /* adl,dg2 */ #define KBL_ARB_FILL_SPARE_14 REG_BIT(14) #define KBL_ARB_FILL_SPARE_13 REG_BIT(13) #define GLK_CL2_PWR_DOWN (1 << 12) -- cgit v1.2.3-59-g8ed1b From 2e4026a1a24d53651c80aca7e683cc86c96ed9c4 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 20 Mar 2023 11:05:22 +0200 Subject: drm/i915: Move PLANE_BUG_CFG bit definitions to the correct place MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All other skl+ universal plane register bit definitions are next to the pipe A register definition. Move the PLANE_BUF_CFG bit definitions there as well. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230320090522.9909-7-ville.syrjala@linux.intel.com Reviewed-by: Juha-Pekka Heikkila --- drivers/gpu/drm/i915/i915_reg.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 053986029c6a..0e1e3a6fd1cb 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4649,6 +4649,11 @@ #define PLANE_CHICKEN_DISABLE_DPT REG_BIT(19) /* mtl+ */ #define _PLANE_BUF_CFG_1_A 0x7027c #define _PLANE_BUF_CFG_2_A 0x7037c +/* skl+: 10 bits, icl+ 11 bits, adlp+ 12 bits */ +#define PLANE_BUF_END_MASK REG_GENMASK(27, 16) +#define PLANE_BUF_END(end) REG_FIELD_PREP(PLANE_BUF_END_MASK, (end)) +#define PLANE_BUF_START_MASK REG_GENMASK(11, 0) +#define PLANE_BUF_START(start) REG_FIELD_PREP(PLANE_BUF_START_MASK, (start)) #define _PLANE_NV12_BUF_CFG_1_A 0x70278 #define _PLANE_NV12_BUF_CFG_2_A 0x70378 @@ -4801,11 +4806,6 @@ #define _PLANE_BUF_CFG_1_B 0x7127c #define _PLANE_BUF_CFG_2_B 0x7137c -/* skl+: 10 bits, icl+ 11 bits, adlp+ 12 bits */ -#define PLANE_BUF_END_MASK REG_GENMASK(27, 16) -#define PLANE_BUF_END(end) REG_FIELD_PREP(PLANE_BUF_END_MASK, (end)) -#define PLANE_BUF_START_MASK REG_GENMASK(11, 0) -#define PLANE_BUF_START(start) REG_FIELD_PREP(PLANE_BUF_START_MASK, (start)) #define _PLANE_BUF_CFG_1(pipe) \ _PIPE(pipe, _PLANE_BUF_CFG_1_A, _PLANE_BUF_CFG_1_B) #define _PLANE_BUF_CFG_2(pipe) \ -- cgit v1.2.3-59-g8ed1b From 419e505dab203b85facc782ec34d2d98601644ff Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 22 Mar 2023 20:12:19 +0200 Subject: drm/i915: Add i915.enable_sagv modparam MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently we have no sane way to forcibly disable SAGV, which makes debugging things a PITA. Manually poking at the pcode mailbox with it's various SAGV/QGV/PSF formats is no fun, and likely to be clobbered by the driver anyway. Let's add a modparam for this. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230322181219.5511-1-ville.syrjala@linux.intel.com Reviewed-by: Rodrigo Vivi --- drivers/gpu/drm/i915/display/skl_watermark.c | 4 ++++ drivers/gpu/drm/i915/i915_params.c | 3 +++ drivers/gpu/drm/i915/i915_params.h | 1 + 3 files changed, 8 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index 50a9a6adbe32..ff70225c0263 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -411,6 +411,9 @@ static bool intel_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *i915 = to_i915(crtc->base.dev); + if (!i915->params.enable_sagv) + return false; + if (DISPLAY_VER(i915) >= 12) return tgl_crtc_can_enable_sagv(crtc_state); else @@ -3696,6 +3699,7 @@ static int intel_sagv_status_show(struct seq_file *m, void *unused) }; seq_printf(m, "SAGV available: %s\n", str_yes_no(intel_has_sagv(i915))); + seq_printf(m, "SAGV modparam: %s\n", str_enabled_disabled(i915->params.enable_sagv)); seq_printf(m, "SAGV status: %s\n", sagv_status[i915->display.sagv.status]); seq_printf(m, "SAGV block time: %d usec\n", i915->display.sagv.block_time_us); diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index bec94feb512d..0a171b57fd8f 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -121,6 +121,9 @@ i915_param_named_unsafe(enable_psr2_sel_fetch, bool, 0400, "(0=disabled, 1=enabled) " "Default: 0"); +i915_param_named_unsafe(enable_sagv, bool, 0600, + "Enable system agent voltage/frequency scaling (SAGV) (default: true)"); + i915_param_named_unsafe(force_probe, charp, 0400, "Force probe options for specified supported devices. " "See CONFIG_DRM_I915_FORCE_PROBE for details."); diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h index d824fe6d266e..68abf0ad6c00 100644 --- a/drivers/gpu/drm/i915/i915_params.h +++ b/drivers/gpu/drm/i915/i915_params.h @@ -57,6 +57,7 @@ struct drm_printer; param(bool, enable_dpt, true, 0400) \ param(bool, psr_safest_params, false, 0400) \ param(bool, enable_psr2_sel_fetch, true, 0400) \ + param(bool, enable_sagv, true, 0600) \ param(int, disable_power_well, -1, 0400) \ param(int, enable_ips, 1, 0600) \ param(int, invert_brightness, 0, 0600) \ -- cgit v1.2.3-59-g8ed1b From ff168b37a96736c892007730e703e74d5a23ca48 Mon Sep 17 00:00:00 2001 From: Vinod Govindapillai Date: Thu, 23 Mar 2023 13:44:25 +0200 Subject: drm/i915/reg: fix QGV points register access offsets Wrong offsets are calculated to read QGV point registers. Fix it to read from the correct registers. Bspec: 64602 Reviewed-by: Stanislav Lisovskiy Signed-off-by: Vinod Govindapillai Signed-off-by: Stanislav Lisovskiy Link: https://patchwork.freedesktop.org/patch/msgid/20230323114426.41136-2-vinod.govindapillai@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 0e1e3a6fd1cb..3abfda4c7a3f 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7748,12 +7748,13 @@ enum skl_power_gate { #define MTL_N_OF_POPULATED_CH_MASK REG_GENMASK(7, 4) #define MTL_DDR_TYPE_MASK REG_GENMASK(3, 0) -#define MTL_MEM_SS_INFO_QGV_POINT_LOW(point) _MMIO(0x45710 + (point) * 2) +#define MTL_MEM_SS_INFO_QGV_POINT_OFFSET 0x45710 +#define MTL_MEM_SS_INFO_QGV_POINT_LOW(point) _MMIO(MTL_MEM_SS_INFO_QGV_POINT_OFFSET + (point) * 8) #define MTL_TRCD_MASK REG_GENMASK(31, 24) #define MTL_TRP_MASK REG_GENMASK(23, 16) #define MTL_DCLK_MASK REG_GENMASK(15, 0) -#define MTL_MEM_SS_INFO_QGV_POINT_HIGH(point) _MMIO(0x45714 + (point) * 2) +#define MTL_MEM_SS_INFO_QGV_POINT_HIGH(point) _MMIO(MTL_MEM_SS_INFO_QGV_POINT_OFFSET + (point) * 8 + 4) #define MTL_TRAS_MASK REG_GENMASK(16, 8) #define MTL_TRDPRE_MASK REG_GENMASK(7, 0) -- cgit v1.2.3-59-g8ed1b From fd6435ea32d9243d116dbf50e7f1a8b33e01262b Mon Sep 17 00:00:00 2001 From: Vinod Govindapillai Date: Thu, 23 Mar 2023 13:44:26 +0200 Subject: drm/i915/reg: use the correct register to access SAGV block time Wrong register address is used to read the SAG block time. Fix the register address according to the bspec. Bspec: 64608 Signed-off-by: Vinod Govindapillai Reviewed-by: Stanislav Lisovskiy Signed-off-by: Stanislav Lisovskiy Link: https://patchwork.freedesktop.org/patch/msgid/20230323114426.41136-3-vinod.govindapillai@intel.com --- drivers/gpu/drm/i915/i915_reg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 3abfda4c7a3f..f0f7b578b726 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -7740,7 +7740,7 @@ enum skl_power_gate { #define MTL_LATENCY_LEVEL_EVEN_MASK REG_GENMASK(12, 0) #define MTL_LATENCY_LEVEL_ODD_MASK REG_GENMASK(28, 16) -#define MTL_LATENCY_SAGV _MMIO(0x4578b) +#define MTL_LATENCY_SAGV _MMIO(0x4578c) #define MTL_LATENCY_QCLK_SAGV REG_GENMASK(12, 0) #define MTL_MEM_SS_INFO_GLOBAL _MMIO(0x45700) -- cgit v1.2.3-59-g8ed1b From 1fb4da5f7858d78570a9f726e98f96797447b32e Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 27 Mar 2023 16:39:41 +0300 Subject: drm/i915/ips: Make IPS debugfs per-crtc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit IPS is a per-pipe feature, so let's move the debugfs stuff under the crtc directory, and only register it when IPS is actually available. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230327133942.22063-1-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/hsw_ips.c | 15 +++++++-------- drivers/gpu/drm/i915/display/hsw_ips.h | 3 +-- drivers/gpu/drm/i915/display/intel_display_debugfs.c | 2 +- 3 files changed, 9 insertions(+), 11 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/hsw_ips.c b/drivers/gpu/drm/i915/display/hsw_ips.c index 2910f5d0f3e2..47209c858c32 100644 --- a/drivers/gpu/drm/i915/display/hsw_ips.c +++ b/drivers/gpu/drm/i915/display/hsw_ips.c @@ -270,12 +270,10 @@ void hsw_ips_get_config(struct intel_crtc_state *crtc_state) static int hsw_ips_debugfs_status_show(struct seq_file *m, void *unused) { - struct drm_i915_private *i915 = m->private; + struct intel_crtc *crtc = m->private; + struct drm_i915_private *i915 = to_i915(crtc->base.dev); intel_wakeref_t wakeref; - if (!HAS_IPS(i915)) - return -ENODEV; - wakeref = intel_runtime_pm_get(&i915->runtime_pm); seq_printf(m, "Enabled by kernel parameter: %s\n", @@ -297,10 +295,11 @@ static int hsw_ips_debugfs_status_show(struct seq_file *m, void *unused) DEFINE_SHOW_ATTRIBUTE(hsw_ips_debugfs_status); -void hsw_ips_debugfs_register(struct drm_i915_private *i915) +void hsw_ips_crtc_debugfs_add(struct intel_crtc *crtc) { - struct drm_minor *minor = i915->drm.primary; + if (!hsw_crtc_supports_ips(crtc)) + return; - debugfs_create_file("i915_ips_status", 0444, minor->debugfs_root, - i915, &hsw_ips_debugfs_status_fops); + debugfs_create_file("i915_ips_status", 0444, crtc->base.debugfs_entry, + crtc, &hsw_ips_debugfs_status_fops); } diff --git a/drivers/gpu/drm/i915/display/hsw_ips.h b/drivers/gpu/drm/i915/display/hsw_ips.h index 7ed6061874f7..4eb83b350791 100644 --- a/drivers/gpu/drm/i915/display/hsw_ips.h +++ b/drivers/gpu/drm/i915/display/hsw_ips.h @@ -8,7 +8,6 @@ #include -struct drm_i915_private; struct intel_atomic_state; struct intel_crtc; struct intel_crtc_state; @@ -23,6 +22,6 @@ bool hsw_crtc_state_ips_capable(const struct intel_crtc_state *crtc_state); int hsw_ips_compute_config(struct intel_atomic_state *state, struct intel_crtc *crtc); void hsw_ips_get_config(struct intel_crtc_state *crtc_state); -void hsw_ips_debugfs_register(struct drm_i915_private *i915); +void hsw_ips_crtc_debugfs_add(struct intel_crtc *crtc); #endif /* __HSW_IPS_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index cc5026272558..d5715ccc37f0 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -1092,7 +1092,6 @@ void intel_display_debugfs_register(struct drm_i915_private *i915) ARRAY_SIZE(intel_display_debugfs_list), minor->debugfs_root, minor); - hsw_ips_debugfs_register(i915); intel_dmc_debugfs_register(i915); intel_fbc_debugfs_register(i915); intel_hpd_debugfs_register(i915); @@ -1461,6 +1460,7 @@ void intel_crtc_debugfs_add(struct intel_crtc *crtc) crtc_updates_add(crtc); intel_drrs_crtc_debugfs_add(crtc); intel_fbc_crtc_debugfs_add(crtc); + hsw_ips_crtc_debugfs_add(crtc); debugfs_create_file("i915_current_bpc", 0444, root, crtc, &i915_current_bpc_fops); -- cgit v1.2.3-59-g8ed1b From 42b4c479025d92b2a4869bd233f20159ae9ce692 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Mon, 27 Mar 2023 16:39:42 +0300 Subject: drm/i915/ips: Add i915_ips_false_color debugfs file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Similar to FBC let's expose an debugfs file to control IPS false color. Enabling this provides an immediate visual feedback on whether IPS is working or not. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230327133942.22063-2-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/hsw_ips.c | 58 ++++++++++++++++++++++- drivers/gpu/drm/i915/display/intel_display_core.h | 4 ++ drivers/gpu/drm/i915/i915_reg.h | 3 +- 3 files changed, 62 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/hsw_ips.c b/drivers/gpu/drm/i915/display/hsw_ips.c index 47209c858c32..8eca0de065b6 100644 --- a/drivers/gpu/drm/i915/display/hsw_ips.c +++ b/drivers/gpu/drm/i915/display/hsw_ips.c @@ -14,6 +14,7 @@ static void hsw_ips_enable(const struct intel_crtc_state *crtc_state) { struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); struct drm_i915_private *i915 = to_i915(crtc->base.dev); + u32 val; if (!crtc_state->ips_enabled) return; @@ -26,10 +27,15 @@ static void hsw_ips_enable(const struct intel_crtc_state *crtc_state) drm_WARN_ON(&i915->drm, !(crtc_state->active_planes & ~BIT(PLANE_CURSOR))); + val = IPS_ENABLE; + + if (i915->display.ips.false_color) + val |= IPS_FALSE_COLOR; + if (IS_BROADWELL(i915)) { drm_WARN_ON(&i915->drm, snb_pcode_write(&i915->uncore, DISPLAY_IPS_CONTROL, - IPS_ENABLE | IPS_PCODE_CONTROL)); + val | IPS_PCODE_CONTROL)); /* * Quoting Art Runyan: "its not safe to expect any particular * value in IPS_CTL bit 31 after enabling IPS through the @@ -37,7 +43,7 @@ static void hsw_ips_enable(const struct intel_crtc_state *crtc_state) * so we need to just enable it and continue on. */ } else { - intel_de_write(i915, IPS_CTL, IPS_ENABLE); + intel_de_write(i915, IPS_CTL, val); /* * The bit only becomes 1 in the next vblank, so this wait here * is essentially intel_wait_for_vblank. If we don't have this @@ -268,6 +274,51 @@ void hsw_ips_get_config(struct intel_crtc_state *crtc_state) } } +static int hsw_ips_debugfs_false_color_get(void *data, u64 *val) +{ + struct intel_crtc *crtc = data; + struct drm_i915_private *i915 = to_i915(crtc->base.dev); + + *val = i915->display.ips.false_color; + + return 0; +} + +static int hsw_ips_debugfs_false_color_set(void *data, u64 val) +{ + struct intel_crtc *crtc = data; + struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct intel_crtc_state *crtc_state; + int ret; + + ret = drm_modeset_lock(&crtc->base.mutex, NULL); + if (ret) + return ret; + + i915->display.ips.false_color = val; + + crtc_state = to_intel_crtc_state(crtc->base.state); + + if (!crtc_state->hw.active) + goto unlock; + + if (crtc_state->uapi.commit && + !try_wait_for_completion(&crtc_state->uapi.commit->hw_done)) + goto unlock; + + hsw_ips_enable(crtc_state); + + unlock: + drm_modeset_unlock(&crtc->base.mutex); + + return ret; +} + +DEFINE_DEBUGFS_ATTRIBUTE(hsw_ips_debugfs_false_color_fops, + hsw_ips_debugfs_false_color_get, + hsw_ips_debugfs_false_color_set, + "%llu\n"); + static int hsw_ips_debugfs_status_show(struct seq_file *m, void *unused) { struct intel_crtc *crtc = m->private; @@ -300,6 +351,9 @@ void hsw_ips_crtc_debugfs_add(struct intel_crtc *crtc) if (!hsw_crtc_supports_ips(crtc)) return; + debugfs_create_file("i915_ips_false_color", 0644, crtc->base.debugfs_entry, + crtc, &hsw_ips_debugfs_false_color_fops); + debugfs_create_file("i915_ips_status", 0444, crtc->base.debugfs_entry, crtc, &hsw_ips_debugfs_status_fops); } diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h index 0b5509f268a7..e36f88a39b86 100644 --- a/drivers/gpu/drm/i915/display/intel_display_core.h +++ b/drivers/gpu/drm/i915/display/intel_display_core.h @@ -418,6 +418,10 @@ struct intel_display { u32 state; } hti; + struct { + bool false_color; + } ips; + struct { struct i915_power_domains domains; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f0f7b578b726..431505314927 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1397,7 +1397,8 @@ #define IVB_FBC_RT_BASE_UPPER _MMIO(0x7024) #define IPS_CTL _MMIO(0x43408) -#define IPS_ENABLE (1 << 31) +#define IPS_ENABLE REG_BIT(31) +#define IPS_FALSE_COLOR REG_BIT(4) #define MSG_FBC_REND_STATE(fbc_id) _MMIO_PIPE((fbc_id), 0x50380, 0x50384) #define FBC_REND_NUKE REG_BIT(2) -- cgit v1.2.3-59-g8ed1b From 99e067637862c902f741744eaafe1472091937a5 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 27 Mar 2023 13:53:30 +0300 Subject: drm/i915: remove unused config DRM_I915_UNSTABLE Essentially this is a revert of commit d9d54a530a70 ("drm/i915: Put future HW and their uAPIs under STAGING & BROKEN"). We currently have no users for this config option. The last one was removed in commit 8c26491f5853 ("drm/i915: Kill the fake lmem support"). Drop it altogether; it's easy enough to resurrect if need arises. Cc: Joonas Lahtinen Cc: Rodrigo Vivi Cc: Tvrtko Ursulin Signed-off-by: Jani Nikula Reviewed-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20230327105330.312131-2-jani.nikula@intel.com --- drivers/gpu/drm/i915/Kconfig | 6 ------ drivers/gpu/drm/i915/Kconfig.unstable | 21 --------------------- 2 files changed, 27 deletions(-) delete mode 100644 drivers/gpu/drm/i915/Kconfig.unstable (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig index 98f4e44976e0..06a0ca157e89 100644 --- a/drivers/gpu/drm/i915/Kconfig +++ b/drivers/gpu/drm/i915/Kconfig @@ -164,11 +164,5 @@ menu "drm/i915 Profile Guided Optimisation" source "drivers/gpu/drm/i915/Kconfig.profile" endmenu -menu "drm/i915 Unstable Evolution" - visible if EXPERT && STAGING && BROKEN - depends on DRM_I915 - source "drivers/gpu/drm/i915/Kconfig.unstable" -endmenu - config DRM_I915_GVT bool diff --git a/drivers/gpu/drm/i915/Kconfig.unstable b/drivers/gpu/drm/i915/Kconfig.unstable deleted file mode 100644 index cf151a297ed7..000000000000 --- a/drivers/gpu/drm/i915/Kconfig.unstable +++ /dev/null @@ -1,21 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -config DRM_I915_UNSTABLE - bool "Enable unstable API for early prototype development" - depends on EXPERT - depends on STAGING - depends on BROKEN # should never be enabled by distros! - # We use the dependency on !COMPILE_TEST to not be enabled in - # allmodconfig or allyesconfig configurations - depends on !COMPILE_TEST - default n - help - Enable prototype uAPI under general discussion before they are - finalized. Such prototypes may be withdrawn or substantially - changed before release. They are only enabled here so that a wide - number of interested parties (userspace driver developers) can - verify that the uAPI meet their expectations. These uAPI should - never be used in production. - - Recommended for driver developers _only_. - - If in the slightest bit of doubt, say "N". -- cgit v1.2.3-59-g8ed1b From ea1deabc6f11575eb3375b454457eaa3c9837abc Mon Sep 17 00:00:00 2001 From: Stanislav Lisovskiy Date: Mon, 27 Mar 2023 09:42:17 +0300 Subject: drm/i915: Use compressed bpp when calculating m/n value for DP MST DSC For obvious reasons, we use compressed bpp instead of pipe bpp for DSC DP SST case. Lets be consistent and use compressed bpp instead of pipe bpp, also in DP MST DSC case. Signed-off-by: Stanislav Lisovskiy Reviewed-by: Vinod Govindapillai Fixes: d51f25eb479a ("drm/i915: Add DSC support to MST path") Link: https://patchwork.freedesktop.org/patch/msgid/20230327064217.24033-1-stanislav.lisovskiy@intel.com --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index a860cbc5dbea..c3e8db943e9c 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -232,7 +232,7 @@ static int intel_dp_dsc_mst_compute_link_config(struct intel_encoder *encoder, return slots; } - intel_link_compute_m_n(crtc_state->pipe_bpp, + intel_link_compute_m_n(crtc_state->dsc.compressed_bpp, crtc_state->lane_count, adjusted_mode->crtc_clock, crtc_state->port_clock, -- cgit v1.2.3-59-g8ed1b From 287bfaf6fee974caba7dc7b874b29c27b1a2dde9 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Tue, 28 Mar 2023 19:49:38 +0300 Subject: drm/i915: Make utility pin asserts more accurate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only the PWM output mode of the utility pin is incompatible with DC6/LCPLL disable. Check for that specifically. References: https://gitlab.freedesktop.org/drm/intel/-/issues/6609 Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230328164938.8193-1-ville.syrjala@linux.intel.com Reviewed-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_display_power.c | 6 ++++-- drivers/gpu/drm/i915/display/intel_display_power_well.c | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index f86060195987..ff787bd42573 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -1182,8 +1182,10 @@ static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv) "CPU PWM2 enabled\n"); I915_STATE_WARN(intel_de_read(dev_priv, BLC_PWM_PCH_CTL1) & BLM_PCH_PWM_ENABLE, "PCH PWM1 enabled\n"); - I915_STATE_WARN(intel_de_read(dev_priv, UTIL_PIN_CTL) & UTIL_PIN_ENABLE, - "Utility pin enabled\n"); + I915_STATE_WARN((intel_de_read(dev_priv, UTIL_PIN_CTL) & + (UTIL_PIN_ENABLE | UTIL_PIN_MODE_MASK)) == + (UTIL_PIN_ENABLE | UTIL_PIN_MODE_PWM), + "Utility pin enabled in PWM mode\n"); I915_STATE_WARN(intel_de_read(dev_priv, PCH_GTC_CTL) & PCH_GTC_ENABLE, "PCH GTC enabled\n"); diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.c b/drivers/gpu/drm/i915/display/intel_display_power_well.c index 1676df1dc066..c694f28e6b2e 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c @@ -818,8 +818,10 @@ void gen9_enable_dc5(struct drm_i915_private *dev_priv) static void assert_can_enable_dc6(struct drm_i915_private *dev_priv) { drm_WARN_ONCE(&dev_priv->drm, - intel_de_read(dev_priv, UTIL_PIN_CTL) & UTIL_PIN_ENABLE, - "Backlight is not disabled.\n"); + (intel_de_read(dev_priv, UTIL_PIN_CTL) & + (UTIL_PIN_ENABLE | UTIL_PIN_MODE_MASK)) == + (UTIL_PIN_ENABLE | UTIL_PIN_MODE_PWM), + "Utility pin enabled in PWM mode\n"); drm_WARN_ONCE(&dev_priv->drm, (intel_de_read(dev_priv, DC_STATE_EN) & DC_STATE_EN_UPTO_DC6), -- cgit v1.2.3-59-g8ed1b From 065695b3da984aa1ed5d619f3c307be1f564bec2 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 16 Mar 2023 15:29:30 +0200 Subject: drm/i915/pps: split out PPS regs to a separate file Clean up i915_reg.h by splitting out PPS regs to display/intel_pps_regs.h. Signed-off-by: Jani Nikula Reviewed-by: Nirmoy Das Link: https://patchwork.freedesktop.org/patch/msgid/80d66ee6d7e56153a0ab25640ac2dad239b1ef6e.1678973282.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display_power.c | 1 + drivers/gpu/drm/i915/display/intel_dsi_vbt.c | 1 + drivers/gpu/drm/i915/display/intel_lvds.c | 1 + drivers/gpu/drm/i915/display/intel_pps.c | 1 + drivers/gpu/drm/i915/display/intel_pps_regs.h | 78 ++++++++++++++++++++++ drivers/gpu/drm/i915/gvt/handlers.c | 1 + drivers/gpu/drm/i915/i915_reg.h | 67 ------------------- 7 files changed, 83 insertions(+), 67 deletions(-) create mode 100644 drivers/gpu/drm/i915/display/intel_pps_regs.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index ff787bd42573..5e85572dc8e4 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -19,6 +19,7 @@ #include "intel_mchbar_regs.h" #include "intel_pch_refclk.h" #include "intel_pcode.h" +#include "intel_pps_regs.h" #include "intel_snps_phy.h" #include "skl_watermark.h" #include "vlv_sideband.h" diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c index 2cbc1292ab38..695b0d69a4cb 100644 --- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c @@ -46,6 +46,7 @@ #include "intel_dsi.h" #include "intel_dsi_vbt.h" #include "intel_gmbus_regs.h" +#include "intel_pps_regs.h" #include "vlv_dsi.h" #include "vlv_dsi_regs.h" #include "vlv_sideband.h" diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c index a504b3a7fbd5..0de44b3631cd 100644 --- a/drivers/gpu/drm/i915/display/intel_lvds.c +++ b/drivers/gpu/drm/i915/display/intel_lvds.c @@ -51,6 +51,7 @@ #include "intel_lvds.h" #include "intel_lvds_regs.h" #include "intel_panel.h" +#include "intel_pps_regs.h" /* Private structure for the integrated LVDS support */ struct intel_lvds_pps { diff --git a/drivers/gpu/drm/i915/display/intel_pps.c b/drivers/gpu/drm/i915/display/intel_pps.c index 24b5b12f7732..7f9926672a6a 100644 --- a/drivers/gpu/drm/i915/display/intel_pps.c +++ b/drivers/gpu/drm/i915/display/intel_pps.c @@ -15,6 +15,7 @@ #include "intel_lvds.h" #include "intel_lvds_regs.h" #include "intel_pps.h" +#include "intel_pps_regs.h" #include "intel_quirks.h" static void vlv_steal_power_sequencer(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/display/intel_pps_regs.h b/drivers/gpu/drm/i915/display/intel_pps_regs.h new file mode 100644 index 000000000000..60edd2a27100 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_pps_regs.h @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2023 Intel Corporation + */ + +#ifndef __INTEL_PPS_REGS_H__ +#define __INTEL_PPS_REGS_H__ + +#include "intel_display_reg_defs.h" + +/* Panel power sequencing */ +#define PPS_BASE 0x61200 +#define VLV_PPS_BASE (VLV_DISPLAY_BASE + PPS_BASE) +#define PCH_PPS_BASE 0xC7200 + +#define _MMIO_PPS(pps_idx, reg) _MMIO(dev_priv->display.pps.mmio_base - \ + PPS_BASE + (reg) + \ + (pps_idx) * 0x100) + +#define _PP_STATUS 0x61200 +#define PP_STATUS(pps_idx) _MMIO_PPS(pps_idx, _PP_STATUS) +#define PP_ON REG_BIT(31) +/* + * Indicates that all dependencies of the panel are on: + * + * - PLL enabled + * - pipe enabled + * - LVDS/DVOB/DVOC on + */ +#define PP_READY REG_BIT(30) +#define PP_SEQUENCE_MASK REG_GENMASK(29, 28) +#define PP_SEQUENCE_NONE REG_FIELD_PREP(PP_SEQUENCE_MASK, 0) +#define PP_SEQUENCE_POWER_UP REG_FIELD_PREP(PP_SEQUENCE_MASK, 1) +#define PP_SEQUENCE_POWER_DOWN REG_FIELD_PREP(PP_SEQUENCE_MASK, 2) +#define PP_CYCLE_DELAY_ACTIVE REG_BIT(27) +#define PP_SEQUENCE_STATE_MASK REG_GENMASK(3, 0) +#define PP_SEQUENCE_STATE_OFF_IDLE REG_FIELD_PREP(PP_SEQUENCE_STATE_MASK, 0x0) +#define PP_SEQUENCE_STATE_OFF_S0_1 REG_FIELD_PREP(PP_SEQUENCE_STATE_MASK, 0x1) +#define PP_SEQUENCE_STATE_OFF_S0_2 REG_FIELD_PREP(PP_SEQUENCE_STATE_MASK, 0x2) +#define PP_SEQUENCE_STATE_OFF_S0_3 REG_FIELD_PREP(PP_SEQUENCE_STATE_MASK, 0x3) +#define PP_SEQUENCE_STATE_ON_IDLE REG_FIELD_PREP(PP_SEQUENCE_STATE_MASK, 0x8) +#define PP_SEQUENCE_STATE_ON_S1_1 REG_FIELD_PREP(PP_SEQUENCE_STATE_MASK, 0x9) +#define PP_SEQUENCE_STATE_ON_S1_2 REG_FIELD_PREP(PP_SEQUENCE_STATE_MASK, 0xa) +#define PP_SEQUENCE_STATE_ON_S1_3 REG_FIELD_PREP(PP_SEQUENCE_STATE_MASK, 0xb) +#define PP_SEQUENCE_STATE_RESET REG_FIELD_PREP(PP_SEQUENCE_STATE_MASK, 0xf) + +#define _PP_CONTROL 0x61204 +#define PP_CONTROL(pps_idx) _MMIO_PPS(pps_idx, _PP_CONTROL) +#define PANEL_UNLOCK_MASK REG_GENMASK(31, 16) +#define PANEL_UNLOCK_REGS REG_FIELD_PREP(PANEL_UNLOCK_MASK, 0xabcd) +#define BXT_POWER_CYCLE_DELAY_MASK REG_GENMASK(8, 4) +#define EDP_FORCE_VDD REG_BIT(3) +#define EDP_BLC_ENABLE REG_BIT(2) +#define PANEL_POWER_RESET REG_BIT(1) +#define PANEL_POWER_ON REG_BIT(0) + +#define _PP_ON_DELAYS 0x61208 +#define PP_ON_DELAYS(pps_idx) _MMIO_PPS(pps_idx, _PP_ON_DELAYS) +#define PANEL_PORT_SELECT_MASK REG_GENMASK(31, 30) +#define PANEL_PORT_SELECT_LVDS REG_FIELD_PREP(PANEL_PORT_SELECT_MASK, 0) +#define PANEL_PORT_SELECT_DPA REG_FIELD_PREP(PANEL_PORT_SELECT_MASK, 1) +#define PANEL_PORT_SELECT_DPC REG_FIELD_PREP(PANEL_PORT_SELECT_MASK, 2) +#define PANEL_PORT_SELECT_DPD REG_FIELD_PREP(PANEL_PORT_SELECT_MASK, 3) +#define PANEL_PORT_SELECT_VLV(port) REG_FIELD_PREP(PANEL_PORT_SELECT_MASK, port) +#define PANEL_POWER_UP_DELAY_MASK REG_GENMASK(28, 16) +#define PANEL_LIGHT_ON_DELAY_MASK REG_GENMASK(12, 0) + +#define _PP_OFF_DELAYS 0x6120C +#define PP_OFF_DELAYS(pps_idx) _MMIO_PPS(pps_idx, _PP_OFF_DELAYS) +#define PANEL_POWER_DOWN_DELAY_MASK REG_GENMASK(28, 16) +#define PANEL_LIGHT_OFF_DELAY_MASK REG_GENMASK(12, 0) + +#define _PP_DIVISOR 0x61210 +#define PP_DIVISOR(pps_idx) _MMIO_PPS(pps_idx, _PP_DIVISOR) +#define PP_REFERENCE_DIVIDER_MASK REG_GENMASK(31, 8) +#define PANEL_POWER_CYCLE_DELAY_MASK REG_GENMASK(4, 0) + +#endif /* __INTEL_PPS_REGS_H__ */ diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 3c8e0d198c4f..d670abd2e6f9 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -45,6 +45,7 @@ #include "display/intel_dmc_regs.h" #include "display/intel_dpio_phy.h" #include "display/intel_fbc.h" +#include "display/intel_pps_regs.h" #include "display/vlv_dsi_pll_regs.h" #include "gt/intel_gt_regs.h" diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f80c36233a77..2116511b4b41 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2557,73 +2557,6 @@ #define VIDEO_DIP_ENABLE_GMP_HSW (1 << 4) #define VIDEO_DIP_ENABLE_SPD_HSW (1 << 0) -/* Panel power sequencing */ -#define PPS_BASE 0x61200 -#define VLV_PPS_BASE (VLV_DISPLAY_BASE + PPS_BASE) -#define PCH_PPS_BASE 0xC7200 - -#define _MMIO_PPS(pps_idx, reg) _MMIO(dev_priv->display.pps.mmio_base - \ - PPS_BASE + (reg) + \ - (pps_idx) * 0x100) - -#define _PP_STATUS 0x61200 -#define PP_STATUS(pps_idx) _MMIO_PPS(pps_idx, _PP_STATUS) -#define PP_ON REG_BIT(31) -/* - * Indicates that all dependencies of the panel are on: - * - * - PLL enabled - * - pipe enabled - * - LVDS/DVOB/DVOC on - */ -#define PP_READY REG_BIT(30) -#define PP_SEQUENCE_MASK REG_GENMASK(29, 28) -#define PP_SEQUENCE_NONE REG_FIELD_PREP(PP_SEQUENCE_MASK, 0) -#define PP_SEQUENCE_POWER_UP REG_FIELD_PREP(PP_SEQUENCE_MASK, 1) -#define PP_SEQUENCE_POWER_DOWN REG_FIELD_PREP(PP_SEQUENCE_MASK, 2) -#define PP_CYCLE_DELAY_ACTIVE REG_BIT(27) -#define PP_SEQUENCE_STATE_MASK REG_GENMASK(3, 0) -#define PP_SEQUENCE_STATE_OFF_IDLE REG_FIELD_PREP(PP_SEQUENCE_STATE_MASK, 0x0) -#define PP_SEQUENCE_STATE_OFF_S0_1 REG_FIELD_PREP(PP_SEQUENCE_STATE_MASK, 0x1) -#define PP_SEQUENCE_STATE_OFF_S0_2 REG_FIELD_PREP(PP_SEQUENCE_STATE_MASK, 0x2) -#define PP_SEQUENCE_STATE_OFF_S0_3 REG_FIELD_PREP(PP_SEQUENCE_STATE_MASK, 0x3) -#define PP_SEQUENCE_STATE_ON_IDLE REG_FIELD_PREP(PP_SEQUENCE_STATE_MASK, 0x8) -#define PP_SEQUENCE_STATE_ON_S1_1 REG_FIELD_PREP(PP_SEQUENCE_STATE_MASK, 0x9) -#define PP_SEQUENCE_STATE_ON_S1_2 REG_FIELD_PREP(PP_SEQUENCE_STATE_MASK, 0xa) -#define PP_SEQUENCE_STATE_ON_S1_3 REG_FIELD_PREP(PP_SEQUENCE_STATE_MASK, 0xb) -#define PP_SEQUENCE_STATE_RESET REG_FIELD_PREP(PP_SEQUENCE_STATE_MASK, 0xf) - -#define _PP_CONTROL 0x61204 -#define PP_CONTROL(pps_idx) _MMIO_PPS(pps_idx, _PP_CONTROL) -#define PANEL_UNLOCK_MASK REG_GENMASK(31, 16) -#define PANEL_UNLOCK_REGS REG_FIELD_PREP(PANEL_UNLOCK_MASK, 0xabcd) -#define BXT_POWER_CYCLE_DELAY_MASK REG_GENMASK(8, 4) -#define EDP_FORCE_VDD REG_BIT(3) -#define EDP_BLC_ENABLE REG_BIT(2) -#define PANEL_POWER_RESET REG_BIT(1) -#define PANEL_POWER_ON REG_BIT(0) - -#define _PP_ON_DELAYS 0x61208 -#define PP_ON_DELAYS(pps_idx) _MMIO_PPS(pps_idx, _PP_ON_DELAYS) -#define PANEL_PORT_SELECT_MASK REG_GENMASK(31, 30) -#define PANEL_PORT_SELECT_LVDS REG_FIELD_PREP(PANEL_PORT_SELECT_MASK, 0) -#define PANEL_PORT_SELECT_DPA REG_FIELD_PREP(PANEL_PORT_SELECT_MASK, 1) -#define PANEL_PORT_SELECT_DPC REG_FIELD_PREP(PANEL_PORT_SELECT_MASK, 2) -#define PANEL_PORT_SELECT_DPD REG_FIELD_PREP(PANEL_PORT_SELECT_MASK, 3) -#define PANEL_PORT_SELECT_VLV(port) REG_FIELD_PREP(PANEL_PORT_SELECT_MASK, port) -#define PANEL_POWER_UP_DELAY_MASK REG_GENMASK(28, 16) -#define PANEL_LIGHT_ON_DELAY_MASK REG_GENMASK(12, 0) - -#define _PP_OFF_DELAYS 0x6120C -#define PP_OFF_DELAYS(pps_idx) _MMIO_PPS(pps_idx, _PP_OFF_DELAYS) -#define PANEL_POWER_DOWN_DELAY_MASK REG_GENMASK(28, 16) -#define PANEL_LIGHT_OFF_DELAY_MASK REG_GENMASK(12, 0) - -#define _PP_DIVISOR 0x61210 -#define PP_DIVISOR(pps_idx) _MMIO_PPS(pps_idx, _PP_DIVISOR) -#define PP_REFERENCE_DIVIDER_MASK REG_GENMASK(31, 8) -#define PANEL_POWER_CYCLE_DELAY_MASK REG_GENMASK(4, 0) - /* Panel fitting */ #define PFIT_CONTROL _MMIO(DISPLAY_MMIO_BASE(dev_priv) + 0x61230) #define PFIT_ENABLE (1 << 31) -- cgit v1.2.3-59-g8ed1b From f84a27f9eea51df5c704ca16a00c6df85a31f805 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 16 Mar 2023 15:29:31 +0200 Subject: drm/i915/tv: split out TV regs to a separate file Clean up i915_reg.h by splitting out TV regs to display/intel_tv_regs.h. Signed-off-by: Jani Nikula Reviewed-by: Nirmoy Das Link: https://patchwork.freedesktop.org/patch/msgid/be4a946a7772f5b4483ad9e078cb62158849683e.1678973282.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_tv.c | 3 +- drivers/gpu/drm/i915/display/intel_tv_regs.h | 490 +++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_reg.h | 479 -------------------------- 3 files changed, 492 insertions(+), 480 deletions(-) create mode 100644 drivers/gpu/drm/i915/display/intel_tv_regs.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_tv.c b/drivers/gpu/drm/i915/display/intel_tv.c index 3b5ff84dc615..557ec5b62afa 100644 --- a/drivers/gpu/drm/i915/display/intel_tv.c +++ b/drivers/gpu/drm/i915/display/intel_tv.c @@ -35,8 +35,8 @@ #include #include "i915_drv.h" -#include "i915_reg.h" #include "i915_irq.h" +#include "i915_reg.h" #include "intel_connector.h" #include "intel_crtc.h" #include "intel_de.h" @@ -44,6 +44,7 @@ #include "intel_dpll.h" #include "intel_hotplug.h" #include "intel_tv.h" +#include "intel_tv_regs.h" enum tv_margin { TV_MARGIN_LEFT, TV_MARGIN_TOP, diff --git a/drivers/gpu/drm/i915/display/intel_tv_regs.h b/drivers/gpu/drm/i915/display/intel_tv_regs.h new file mode 100644 index 000000000000..ab25aeb3c423 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_tv_regs.h @@ -0,0 +1,490 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2023 Intel Corporation + */ + +#ifndef __INTEL_TV_REGS_H__ +#define __INTEL_TV_REGS_H__ + +#include "intel_display_reg_defs.h" + +/* TV port control */ +#define TV_CTL _MMIO(0x68000) +/* Enables the TV encoder */ +# define TV_ENC_ENABLE (1 << 31) +/* Sources the TV encoder input from pipe B instead of A. */ +# define TV_ENC_PIPE_SEL_SHIFT 30 +# define TV_ENC_PIPE_SEL_MASK (1 << 30) +# define TV_ENC_PIPE_SEL(pipe) ((pipe) << 30) +/* Outputs composite video (DAC A only) */ +# define TV_ENC_OUTPUT_COMPOSITE (0 << 28) +/* Outputs SVideo video (DAC B/C) */ +# define TV_ENC_OUTPUT_SVIDEO (1 << 28) +/* Outputs Component video (DAC A/B/C) */ +# define TV_ENC_OUTPUT_COMPONENT (2 << 28) +/* Outputs Composite and SVideo (DAC A/B/C) */ +# define TV_ENC_OUTPUT_SVIDEO_COMPOSITE (3 << 28) +# define TV_TRILEVEL_SYNC (1 << 21) +/* Enables slow sync generation (945GM only) */ +# define TV_SLOW_SYNC (1 << 20) +/* Selects 4x oversampling for 480i and 576p */ +# define TV_OVERSAMPLE_4X (0 << 18) +/* Selects 2x oversampling for 720p and 1080i */ +# define TV_OVERSAMPLE_2X (1 << 18) +/* Selects no oversampling for 1080p */ +# define TV_OVERSAMPLE_NONE (2 << 18) +/* Selects 8x oversampling */ +# define TV_OVERSAMPLE_8X (3 << 18) +# define TV_OVERSAMPLE_MASK (3 << 18) +/* Selects progressive mode rather than interlaced */ +# define TV_PROGRESSIVE (1 << 17) +/* Sets the colorburst to PAL mode. Required for non-M PAL modes. */ +# define TV_PAL_BURST (1 << 16) +/* Field for setting delay of Y compared to C */ +# define TV_YC_SKEW_MASK (7 << 12) +/* Enables a fix for 480p/576p standard definition modes on the 915GM only */ +# define TV_ENC_SDP_FIX (1 << 11) +/* + * Enables a fix for the 915GM only. + * + * Not sure what it does. + */ +# define TV_ENC_C0_FIX (1 << 10) +/* Bits that must be preserved by software */ +# define TV_CTL_SAVE ((1 << 11) | (3 << 9) | (7 << 6) | 0xf) +# define TV_FUSE_STATE_MASK (3 << 4) +/* Read-only state that reports all features enabled */ +# define TV_FUSE_STATE_ENABLED (0 << 4) +/* Read-only state that reports that Macrovision is disabled in hardware*/ +# define TV_FUSE_STATE_NO_MACROVISION (1 << 4) +/* Read-only state that reports that TV-out is disabled in hardware. */ +# define TV_FUSE_STATE_DISABLED (2 << 4) +/* Normal operation */ +# define TV_TEST_MODE_NORMAL (0 << 0) +/* Encoder test pattern 1 - combo pattern */ +# define TV_TEST_MODE_PATTERN_1 (1 << 0) +/* Encoder test pattern 2 - full screen vertical 75% color bars */ +# define TV_TEST_MODE_PATTERN_2 (2 << 0) +/* Encoder test pattern 3 - full screen horizontal 75% color bars */ +# define TV_TEST_MODE_PATTERN_3 (3 << 0) +/* Encoder test pattern 4 - random noise */ +# define TV_TEST_MODE_PATTERN_4 (4 << 0) +/* Encoder test pattern 5 - linear color ramps */ +# define TV_TEST_MODE_PATTERN_5 (5 << 0) +/* + * This test mode forces the DACs to 50% of full output. + * + * This is used for load detection in combination with TVDAC_SENSE_MASK + */ +# define TV_TEST_MODE_MONITOR_DETECT (7 << 0) +# define TV_TEST_MODE_MASK (7 << 0) + +#define TV_DAC _MMIO(0x68004) +# define TV_DAC_SAVE 0x00ffff00 +/* + * Reports that DAC state change logic has reported change (RO). + * + * This gets cleared when TV_DAC_STATE_EN is cleared +*/ +# define TVDAC_STATE_CHG (1 << 31) +# define TVDAC_SENSE_MASK (7 << 28) +/* Reports that DAC A voltage is above the detect threshold */ +# define TVDAC_A_SENSE (1 << 30) +/* Reports that DAC B voltage is above the detect threshold */ +# define TVDAC_B_SENSE (1 << 29) +/* Reports that DAC C voltage is above the detect threshold */ +# define TVDAC_C_SENSE (1 << 28) +/* + * Enables DAC state detection logic, for load-based TV detection. + * + * The PLL of the chosen pipe (in TV_CTL) must be running, and the encoder set + * to off, for load detection to work. + */ +# define TVDAC_STATE_CHG_EN (1 << 27) +/* Sets the DAC A sense value to high */ +# define TVDAC_A_SENSE_CTL (1 << 26) +/* Sets the DAC B sense value to high */ +# define TVDAC_B_SENSE_CTL (1 << 25) +/* Sets the DAC C sense value to high */ +# define TVDAC_C_SENSE_CTL (1 << 24) +/* Overrides the ENC_ENABLE and DAC voltage levels */ +# define DAC_CTL_OVERRIDE (1 << 7) +/* Sets the slew rate. Must be preserved in software */ +# define ENC_TVDAC_SLEW_FAST (1 << 6) +# define DAC_A_1_3_V (0 << 4) +# define DAC_A_1_1_V (1 << 4) +# define DAC_A_0_7_V (2 << 4) +# define DAC_A_MASK (3 << 4) +# define DAC_B_1_3_V (0 << 2) +# define DAC_B_1_1_V (1 << 2) +# define DAC_B_0_7_V (2 << 2) +# define DAC_B_MASK (3 << 2) +# define DAC_C_1_3_V (0 << 0) +# define DAC_C_1_1_V (1 << 0) +# define DAC_C_0_7_V (2 << 0) +# define DAC_C_MASK (3 << 0) + +/* + * CSC coefficients are stored in a floating point format with 9 bits of + * mantissa and 2 or 3 bits of exponent. The exponent is represented as 2**-n, + * where 2-bit exponents are unsigned n, and 3-bit exponents are signed n with + * -1 (0x3) being the only legal negative value. + */ +#define TV_CSC_Y _MMIO(0x68010) +# define TV_RY_MASK 0x07ff0000 +# define TV_RY_SHIFT 16 +# define TV_GY_MASK 0x00000fff +# define TV_GY_SHIFT 0 + +#define TV_CSC_Y2 _MMIO(0x68014) +# define TV_BY_MASK 0x07ff0000 +# define TV_BY_SHIFT 16 +/* + * Y attenuation for component video. + * + * Stored in 1.9 fixed point. + */ +# define TV_AY_MASK 0x000003ff +# define TV_AY_SHIFT 0 + +#define TV_CSC_U _MMIO(0x68018) +# define TV_RU_MASK 0x07ff0000 +# define TV_RU_SHIFT 16 +# define TV_GU_MASK 0x000007ff +# define TV_GU_SHIFT 0 + +#define TV_CSC_U2 _MMIO(0x6801c) +# define TV_BU_MASK 0x07ff0000 +# define TV_BU_SHIFT 16 +/* + * U attenuation for component video. + * + * Stored in 1.9 fixed point. + */ +# define TV_AU_MASK 0x000003ff +# define TV_AU_SHIFT 0 + +#define TV_CSC_V _MMIO(0x68020) +# define TV_RV_MASK 0x0fff0000 +# define TV_RV_SHIFT 16 +# define TV_GV_MASK 0x000007ff +# define TV_GV_SHIFT 0 + +#define TV_CSC_V2 _MMIO(0x68024) +# define TV_BV_MASK 0x07ff0000 +# define TV_BV_SHIFT 16 +/* + * V attenuation for component video. + * + * Stored in 1.9 fixed point. + */ +# define TV_AV_MASK 0x000007ff +# define TV_AV_SHIFT 0 + +#define TV_CLR_KNOBS _MMIO(0x68028) +/* 2s-complement brightness adjustment */ +# define TV_BRIGHTNESS_MASK 0xff000000 +# define TV_BRIGHTNESS_SHIFT 24 +/* Contrast adjustment, as a 2.6 unsigned floating point number */ +# define TV_CONTRAST_MASK 0x00ff0000 +# define TV_CONTRAST_SHIFT 16 +/* Saturation adjustment, as a 2.6 unsigned floating point number */ +# define TV_SATURATION_MASK 0x0000ff00 +# define TV_SATURATION_SHIFT 8 +/* Hue adjustment, as an integer phase angle in degrees */ +# define TV_HUE_MASK 0x000000ff +# define TV_HUE_SHIFT 0 + +#define TV_CLR_LEVEL _MMIO(0x6802c) +/* Controls the DAC level for black */ +# define TV_BLACK_LEVEL_MASK 0x01ff0000 +# define TV_BLACK_LEVEL_SHIFT 16 +/* Controls the DAC level for blanking */ +# define TV_BLANK_LEVEL_MASK 0x000001ff +# define TV_BLANK_LEVEL_SHIFT 0 + +#define TV_H_CTL_1 _MMIO(0x68030) +/* Number of pixels in the hsync. */ +# define TV_HSYNC_END_MASK 0x1fff0000 +# define TV_HSYNC_END_SHIFT 16 +/* Total number of pixels minus one in the line (display and blanking). */ +# define TV_HTOTAL_MASK 0x00001fff +# define TV_HTOTAL_SHIFT 0 + +#define TV_H_CTL_2 _MMIO(0x68034) +/* Enables the colorburst (needed for non-component color) */ +# define TV_BURST_ENA (1 << 31) +/* Offset of the colorburst from the start of hsync, in pixels minus one. */ +# define TV_HBURST_START_SHIFT 16 +# define TV_HBURST_START_MASK 0x1fff0000 +/* Length of the colorburst */ +# define TV_HBURST_LEN_SHIFT 0 +# define TV_HBURST_LEN_MASK 0x0001fff + +#define TV_H_CTL_3 _MMIO(0x68038) +/* End of hblank, measured in pixels minus one from start of hsync */ +# define TV_HBLANK_END_SHIFT 16 +# define TV_HBLANK_END_MASK 0x1fff0000 +/* Start of hblank, measured in pixels minus one from start of hsync */ +# define TV_HBLANK_START_SHIFT 0 +# define TV_HBLANK_START_MASK 0x0001fff + +#define TV_V_CTL_1 _MMIO(0x6803c) +/* XXX */ +# define TV_NBR_END_SHIFT 16 +# define TV_NBR_END_MASK 0x07ff0000 +/* XXX */ +# define TV_VI_END_F1_SHIFT 8 +# define TV_VI_END_F1_MASK 0x00003f00 +/* XXX */ +# define TV_VI_END_F2_SHIFT 0 +# define TV_VI_END_F2_MASK 0x0000003f + +#define TV_V_CTL_2 _MMIO(0x68040) +/* Length of vsync, in half lines */ +# define TV_VSYNC_LEN_MASK 0x07ff0000 +# define TV_VSYNC_LEN_SHIFT 16 +/* Offset of the start of vsync in field 1, measured in one less than the + * number of half lines. + */ +# define TV_VSYNC_START_F1_MASK 0x00007f00 +# define TV_VSYNC_START_F1_SHIFT 8 +/* + * Offset of the start of vsync in field 2, measured in one less than the + * number of half lines. + */ +# define TV_VSYNC_START_F2_MASK 0x0000007f +# define TV_VSYNC_START_F2_SHIFT 0 + +#define TV_V_CTL_3 _MMIO(0x68044) +/* Enables generation of the equalization signal */ +# define TV_EQUAL_ENA (1 << 31) +/* Length of vsync, in half lines */ +# define TV_VEQ_LEN_MASK 0x007f0000 +# define TV_VEQ_LEN_SHIFT 16 +/* Offset of the start of equalization in field 1, measured in one less than + * the number of half lines. + */ +# define TV_VEQ_START_F1_MASK 0x0007f00 +# define TV_VEQ_START_F1_SHIFT 8 +/* + * Offset of the start of equalization in field 2, measured in one less than + * the number of half lines. + */ +# define TV_VEQ_START_F2_MASK 0x000007f +# define TV_VEQ_START_F2_SHIFT 0 + +#define TV_V_CTL_4 _MMIO(0x68048) +/* + * Offset to start of vertical colorburst, measured in one less than the + * number of lines from vertical start. + */ +# define TV_VBURST_START_F1_MASK 0x003f0000 +# define TV_VBURST_START_F1_SHIFT 16 +/* + * Offset to the end of vertical colorburst, measured in one less than the + * number of lines from the start of NBR. + */ +# define TV_VBURST_END_F1_MASK 0x000000ff +# define TV_VBURST_END_F1_SHIFT 0 + +#define TV_V_CTL_5 _MMIO(0x6804c) +/* + * Offset to start of vertical colorburst, measured in one less than the + * number of lines from vertical start. + */ +# define TV_VBURST_START_F2_MASK 0x003f0000 +# define TV_VBURST_START_F2_SHIFT 16 +/* + * Offset to the end of vertical colorburst, measured in one less than the + * number of lines from the start of NBR. + */ +# define TV_VBURST_END_F2_MASK 0x000000ff +# define TV_VBURST_END_F2_SHIFT 0 + +#define TV_V_CTL_6 _MMIO(0x68050) +/* + * Offset to start of vertical colorburst, measured in one less than the + * number of lines from vertical start. + */ +# define TV_VBURST_START_F3_MASK 0x003f0000 +# define TV_VBURST_START_F3_SHIFT 16 +/* + * Offset to the end of vertical colorburst, measured in one less than the + * number of lines from the start of NBR. + */ +# define TV_VBURST_END_F3_MASK 0x000000ff +# define TV_VBURST_END_F3_SHIFT 0 + +#define TV_V_CTL_7 _MMIO(0x68054) +/* + * Offset to start of vertical colorburst, measured in one less than the + * number of lines from vertical start. + */ +# define TV_VBURST_START_F4_MASK 0x003f0000 +# define TV_VBURST_START_F4_SHIFT 16 +/* + * Offset to the end of vertical colorburst, measured in one less than the + * number of lines from the start of NBR. + */ +# define TV_VBURST_END_F4_MASK 0x000000ff +# define TV_VBURST_END_F4_SHIFT 0 + +#define TV_SC_CTL_1 _MMIO(0x68060) +/* Turns on the first subcarrier phase generation DDA */ +# define TV_SC_DDA1_EN (1 << 31) +/* Turns on the first subcarrier phase generation DDA */ +# define TV_SC_DDA2_EN (1 << 30) +/* Turns on the first subcarrier phase generation DDA */ +# define TV_SC_DDA3_EN (1 << 29) +/* Sets the subcarrier DDA to reset frequency every other field */ +# define TV_SC_RESET_EVERY_2 (0 << 24) +/* Sets the subcarrier DDA to reset frequency every fourth field */ +# define TV_SC_RESET_EVERY_4 (1 << 24) +/* Sets the subcarrier DDA to reset frequency every eighth field */ +# define TV_SC_RESET_EVERY_8 (2 << 24) +/* Sets the subcarrier DDA to never reset the frequency */ +# define TV_SC_RESET_NEVER (3 << 24) +/* Sets the peak amplitude of the colorburst.*/ +# define TV_BURST_LEVEL_MASK 0x00ff0000 +# define TV_BURST_LEVEL_SHIFT 16 +/* Sets the increment of the first subcarrier phase generation DDA */ +# define TV_SCDDA1_INC_MASK 0x00000fff +# define TV_SCDDA1_INC_SHIFT 0 + +#define TV_SC_CTL_2 _MMIO(0x68064) +/* Sets the rollover for the second subcarrier phase generation DDA */ +# define TV_SCDDA2_SIZE_MASK 0x7fff0000 +# define TV_SCDDA2_SIZE_SHIFT 16 +/* Sets the increent of the second subcarrier phase generation DDA */ +# define TV_SCDDA2_INC_MASK 0x00007fff +# define TV_SCDDA2_INC_SHIFT 0 + +#define TV_SC_CTL_3 _MMIO(0x68068) +/* Sets the rollover for the third subcarrier phase generation DDA */ +# define TV_SCDDA3_SIZE_MASK 0x7fff0000 +# define TV_SCDDA3_SIZE_SHIFT 16 +/* Sets the increent of the third subcarrier phase generation DDA */ +# define TV_SCDDA3_INC_MASK 0x00007fff +# define TV_SCDDA3_INC_SHIFT 0 + +#define TV_WIN_POS _MMIO(0x68070) +/* X coordinate of the display from the start of horizontal active */ +# define TV_XPOS_MASK 0x1fff0000 +# define TV_XPOS_SHIFT 16 +/* Y coordinate of the display from the start of vertical active (NBR) */ +# define TV_YPOS_MASK 0x00000fff +# define TV_YPOS_SHIFT 0 + +#define TV_WIN_SIZE _MMIO(0x68074) +/* Horizontal size of the display window, measured in pixels*/ +# define TV_XSIZE_MASK 0x1fff0000 +# define TV_XSIZE_SHIFT 16 +/* + * Vertical size of the display window, measured in pixels. + * + * Must be even for interlaced modes. + */ +# define TV_YSIZE_MASK 0x00000fff +# define TV_YSIZE_SHIFT 0 + +#define TV_FILTER_CTL_1 _MMIO(0x68080) +/* + * Enables automatic scaling calculation. + * + * If set, the rest of the registers are ignored, and the calculated values can + * be read back from the register. + */ +# define TV_AUTO_SCALE (1 << 31) +/* + * Disables the vertical filter. + * + * This is required on modes more than 1024 pixels wide */ +# define TV_V_FILTER_BYPASS (1 << 29) +/* Enables adaptive vertical filtering */ +# define TV_VADAPT (1 << 28) +# define TV_VADAPT_MODE_MASK (3 << 26) +/* Selects the least adaptive vertical filtering mode */ +# define TV_VADAPT_MODE_LEAST (0 << 26) +/* Selects the moderately adaptive vertical filtering mode */ +# define TV_VADAPT_MODE_MODERATE (1 << 26) +/* Selects the most adaptive vertical filtering mode */ +# define TV_VADAPT_MODE_MOST (3 << 26) +/* + * Sets the horizontal scaling factor. + * + * This should be the fractional part of the horizontal scaling factor divided + * by the oversampling rate. TV_HSCALE should be less than 1, and set to: + * + * (src width - 1) / ((oversample * dest width) - 1) + */ +# define TV_HSCALE_FRAC_MASK 0x00003fff +# define TV_HSCALE_FRAC_SHIFT 0 + +#define TV_FILTER_CTL_2 _MMIO(0x68084) +/* + * Sets the integer part of the 3.15 fixed-point vertical scaling factor. + * + * TV_VSCALE should be (src height - 1) / ((interlace * dest height) - 1) + */ +# define TV_VSCALE_INT_MASK 0x00038000 +# define TV_VSCALE_INT_SHIFT 15 +/* + * Sets the fractional part of the 3.15 fixed-point vertical scaling factor. + * + * \sa TV_VSCALE_INT_MASK + */ +# define TV_VSCALE_FRAC_MASK 0x00007fff +# define TV_VSCALE_FRAC_SHIFT 0 + +#define TV_FILTER_CTL_3 _MMIO(0x68088) +/* + * Sets the integer part of the 3.15 fixed-point vertical scaling factor. + * + * TV_VSCALE should be (src height - 1) / (1/4 * (dest height - 1)) + * + * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes. + */ +# define TV_VSCALE_IP_INT_MASK 0x00038000 +# define TV_VSCALE_IP_INT_SHIFT 15 +/* + * Sets the fractional part of the 3.15 fixed-point vertical scaling factor. + * + * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes. + * + * \sa TV_VSCALE_IP_INT_MASK + */ +# define TV_VSCALE_IP_FRAC_MASK 0x00007fff +# define TV_VSCALE_IP_FRAC_SHIFT 0 + +#define TV_CC_CONTROL _MMIO(0x68090) +# define TV_CC_ENABLE (1 << 31) +/* + * Specifies which field to send the CC data in. + * + * CC data is usually sent in field 0. + */ +# define TV_CC_FID_MASK (1 << 27) +# define TV_CC_FID_SHIFT 27 +/* Sets the horizontal position of the CC data. Usually 135. */ +# define TV_CC_HOFF_MASK 0x03ff0000 +# define TV_CC_HOFF_SHIFT 16 +/* Sets the vertical position of the CC data. Usually 21 */ +# define TV_CC_LINE_MASK 0x0000003f +# define TV_CC_LINE_SHIFT 0 + +#define TV_CC_DATA _MMIO(0x68094) +# define TV_CC_RDY (1 << 31) +/* Second word of CC data to be transmitted. */ +# define TV_CC_DATA_2_MASK 0x007f0000 +# define TV_CC_DATA_2_SHIFT 16 +/* First word of CC data to be transmitted. */ +# define TV_CC_DATA_1_MASK 0x0000007f +# define TV_CC_DATA_1_SHIFT 0 + +#define TV_H_LUMA(i) _MMIO(0x68100 + (i) * 4) /* 60 registers */ +#define TV_H_CHROMA(i) _MMIO(0x68200 + (i) * 4) /* 60 registers */ +#define TV_V_LUMA(i) _MMIO(0x68300 + (i) * 4) /* 43 registers */ +#define TV_V_CHROMA(i) _MMIO(0x68400 + (i) * 4) /* 43 registers */ + +#endif /* __INTEL_TV_REGS_H__ */ diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 2116511b4b41..5b7869001492 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2594,485 +2594,6 @@ #define PCH_GTC_CTL _MMIO(0xe7000) #define PCH_GTC_ENABLE (1 << 31) -/* TV port control */ -#define TV_CTL _MMIO(0x68000) -/* Enables the TV encoder */ -# define TV_ENC_ENABLE (1 << 31) -/* Sources the TV encoder input from pipe B instead of A. */ -# define TV_ENC_PIPE_SEL_SHIFT 30 -# define TV_ENC_PIPE_SEL_MASK (1 << 30) -# define TV_ENC_PIPE_SEL(pipe) ((pipe) << 30) -/* Outputs composite video (DAC A only) */ -# define TV_ENC_OUTPUT_COMPOSITE (0 << 28) -/* Outputs SVideo video (DAC B/C) */ -# define TV_ENC_OUTPUT_SVIDEO (1 << 28) -/* Outputs Component video (DAC A/B/C) */ -# define TV_ENC_OUTPUT_COMPONENT (2 << 28) -/* Outputs Composite and SVideo (DAC A/B/C) */ -# define TV_ENC_OUTPUT_SVIDEO_COMPOSITE (3 << 28) -# define TV_TRILEVEL_SYNC (1 << 21) -/* Enables slow sync generation (945GM only) */ -# define TV_SLOW_SYNC (1 << 20) -/* Selects 4x oversampling for 480i and 576p */ -# define TV_OVERSAMPLE_4X (0 << 18) -/* Selects 2x oversampling for 720p and 1080i */ -# define TV_OVERSAMPLE_2X (1 << 18) -/* Selects no oversampling for 1080p */ -# define TV_OVERSAMPLE_NONE (2 << 18) -/* Selects 8x oversampling */ -# define TV_OVERSAMPLE_8X (3 << 18) -# define TV_OVERSAMPLE_MASK (3 << 18) -/* Selects progressive mode rather than interlaced */ -# define TV_PROGRESSIVE (1 << 17) -/* Sets the colorburst to PAL mode. Required for non-M PAL modes. */ -# define TV_PAL_BURST (1 << 16) -/* Field for setting delay of Y compared to C */ -# define TV_YC_SKEW_MASK (7 << 12) -/* Enables a fix for 480p/576p standard definition modes on the 915GM only */ -# define TV_ENC_SDP_FIX (1 << 11) -/* - * Enables a fix for the 915GM only. - * - * Not sure what it does. - */ -# define TV_ENC_C0_FIX (1 << 10) -/* Bits that must be preserved by software */ -# define TV_CTL_SAVE ((1 << 11) | (3 << 9) | (7 << 6) | 0xf) -# define TV_FUSE_STATE_MASK (3 << 4) -/* Read-only state that reports all features enabled */ -# define TV_FUSE_STATE_ENABLED (0 << 4) -/* Read-only state that reports that Macrovision is disabled in hardware*/ -# define TV_FUSE_STATE_NO_MACROVISION (1 << 4) -/* Read-only state that reports that TV-out is disabled in hardware. */ -# define TV_FUSE_STATE_DISABLED (2 << 4) -/* Normal operation */ -# define TV_TEST_MODE_NORMAL (0 << 0) -/* Encoder test pattern 1 - combo pattern */ -# define TV_TEST_MODE_PATTERN_1 (1 << 0) -/* Encoder test pattern 2 - full screen vertical 75% color bars */ -# define TV_TEST_MODE_PATTERN_2 (2 << 0) -/* Encoder test pattern 3 - full screen horizontal 75% color bars */ -# define TV_TEST_MODE_PATTERN_3 (3 << 0) -/* Encoder test pattern 4 - random noise */ -# define TV_TEST_MODE_PATTERN_4 (4 << 0) -/* Encoder test pattern 5 - linear color ramps */ -# define TV_TEST_MODE_PATTERN_5 (5 << 0) -/* - * This test mode forces the DACs to 50% of full output. - * - * This is used for load detection in combination with TVDAC_SENSE_MASK - */ -# define TV_TEST_MODE_MONITOR_DETECT (7 << 0) -# define TV_TEST_MODE_MASK (7 << 0) - -#define TV_DAC _MMIO(0x68004) -# define TV_DAC_SAVE 0x00ffff00 -/* - * Reports that DAC state change logic has reported change (RO). - * - * This gets cleared when TV_DAC_STATE_EN is cleared -*/ -# define TVDAC_STATE_CHG (1 << 31) -# define TVDAC_SENSE_MASK (7 << 28) -/* Reports that DAC A voltage is above the detect threshold */ -# define TVDAC_A_SENSE (1 << 30) -/* Reports that DAC B voltage is above the detect threshold */ -# define TVDAC_B_SENSE (1 << 29) -/* Reports that DAC C voltage is above the detect threshold */ -# define TVDAC_C_SENSE (1 << 28) -/* - * Enables DAC state detection logic, for load-based TV detection. - * - * The PLL of the chosen pipe (in TV_CTL) must be running, and the encoder set - * to off, for load detection to work. - */ -# define TVDAC_STATE_CHG_EN (1 << 27) -/* Sets the DAC A sense value to high */ -# define TVDAC_A_SENSE_CTL (1 << 26) -/* Sets the DAC B sense value to high */ -# define TVDAC_B_SENSE_CTL (1 << 25) -/* Sets the DAC C sense value to high */ -# define TVDAC_C_SENSE_CTL (1 << 24) -/* Overrides the ENC_ENABLE and DAC voltage levels */ -# define DAC_CTL_OVERRIDE (1 << 7) -/* Sets the slew rate. Must be preserved in software */ -# define ENC_TVDAC_SLEW_FAST (1 << 6) -# define DAC_A_1_3_V (0 << 4) -# define DAC_A_1_1_V (1 << 4) -# define DAC_A_0_7_V (2 << 4) -# define DAC_A_MASK (3 << 4) -# define DAC_B_1_3_V (0 << 2) -# define DAC_B_1_1_V (1 << 2) -# define DAC_B_0_7_V (2 << 2) -# define DAC_B_MASK (3 << 2) -# define DAC_C_1_3_V (0 << 0) -# define DAC_C_1_1_V (1 << 0) -# define DAC_C_0_7_V (2 << 0) -# define DAC_C_MASK (3 << 0) - -/* - * CSC coefficients are stored in a floating point format with 9 bits of - * mantissa and 2 or 3 bits of exponent. The exponent is represented as 2**-n, - * where 2-bit exponents are unsigned n, and 3-bit exponents are signed n with - * -1 (0x3) being the only legal negative value. - */ -#define TV_CSC_Y _MMIO(0x68010) -# define TV_RY_MASK 0x07ff0000 -# define TV_RY_SHIFT 16 -# define TV_GY_MASK 0x00000fff -# define TV_GY_SHIFT 0 - -#define TV_CSC_Y2 _MMIO(0x68014) -# define TV_BY_MASK 0x07ff0000 -# define TV_BY_SHIFT 16 -/* - * Y attenuation for component video. - * - * Stored in 1.9 fixed point. - */ -# define TV_AY_MASK 0x000003ff -# define TV_AY_SHIFT 0 - -#define TV_CSC_U _MMIO(0x68018) -# define TV_RU_MASK 0x07ff0000 -# define TV_RU_SHIFT 16 -# define TV_GU_MASK 0x000007ff -# define TV_GU_SHIFT 0 - -#define TV_CSC_U2 _MMIO(0x6801c) -# define TV_BU_MASK 0x07ff0000 -# define TV_BU_SHIFT 16 -/* - * U attenuation for component video. - * - * Stored in 1.9 fixed point. - */ -# define TV_AU_MASK 0x000003ff -# define TV_AU_SHIFT 0 - -#define TV_CSC_V _MMIO(0x68020) -# define TV_RV_MASK 0x0fff0000 -# define TV_RV_SHIFT 16 -# define TV_GV_MASK 0x000007ff -# define TV_GV_SHIFT 0 - -#define TV_CSC_V2 _MMIO(0x68024) -# define TV_BV_MASK 0x07ff0000 -# define TV_BV_SHIFT 16 -/* - * V attenuation for component video. - * - * Stored in 1.9 fixed point. - */ -# define TV_AV_MASK 0x000007ff -# define TV_AV_SHIFT 0 - -#define TV_CLR_KNOBS _MMIO(0x68028) -/* 2s-complement brightness adjustment */ -# define TV_BRIGHTNESS_MASK 0xff000000 -# define TV_BRIGHTNESS_SHIFT 24 -/* Contrast adjustment, as a 2.6 unsigned floating point number */ -# define TV_CONTRAST_MASK 0x00ff0000 -# define TV_CONTRAST_SHIFT 16 -/* Saturation adjustment, as a 2.6 unsigned floating point number */ -# define TV_SATURATION_MASK 0x0000ff00 -# define TV_SATURATION_SHIFT 8 -/* Hue adjustment, as an integer phase angle in degrees */ -# define TV_HUE_MASK 0x000000ff -# define TV_HUE_SHIFT 0 - -#define TV_CLR_LEVEL _MMIO(0x6802c) -/* Controls the DAC level for black */ -# define TV_BLACK_LEVEL_MASK 0x01ff0000 -# define TV_BLACK_LEVEL_SHIFT 16 -/* Controls the DAC level for blanking */ -# define TV_BLANK_LEVEL_MASK 0x000001ff -# define TV_BLANK_LEVEL_SHIFT 0 - -#define TV_H_CTL_1 _MMIO(0x68030) -/* Number of pixels in the hsync. */ -# define TV_HSYNC_END_MASK 0x1fff0000 -# define TV_HSYNC_END_SHIFT 16 -/* Total number of pixels minus one in the line (display and blanking). */ -# define TV_HTOTAL_MASK 0x00001fff -# define TV_HTOTAL_SHIFT 0 - -#define TV_H_CTL_2 _MMIO(0x68034) -/* Enables the colorburst (needed for non-component color) */ -# define TV_BURST_ENA (1 << 31) -/* Offset of the colorburst from the start of hsync, in pixels minus one. */ -# define TV_HBURST_START_SHIFT 16 -# define TV_HBURST_START_MASK 0x1fff0000 -/* Length of the colorburst */ -# define TV_HBURST_LEN_SHIFT 0 -# define TV_HBURST_LEN_MASK 0x0001fff - -#define TV_H_CTL_3 _MMIO(0x68038) -/* End of hblank, measured in pixels minus one from start of hsync */ -# define TV_HBLANK_END_SHIFT 16 -# define TV_HBLANK_END_MASK 0x1fff0000 -/* Start of hblank, measured in pixels minus one from start of hsync */ -# define TV_HBLANK_START_SHIFT 0 -# define TV_HBLANK_START_MASK 0x0001fff - -#define TV_V_CTL_1 _MMIO(0x6803c) -/* XXX */ -# define TV_NBR_END_SHIFT 16 -# define TV_NBR_END_MASK 0x07ff0000 -/* XXX */ -# define TV_VI_END_F1_SHIFT 8 -# define TV_VI_END_F1_MASK 0x00003f00 -/* XXX */ -# define TV_VI_END_F2_SHIFT 0 -# define TV_VI_END_F2_MASK 0x0000003f - -#define TV_V_CTL_2 _MMIO(0x68040) -/* Length of vsync, in half lines */ -# define TV_VSYNC_LEN_MASK 0x07ff0000 -# define TV_VSYNC_LEN_SHIFT 16 -/* Offset of the start of vsync in field 1, measured in one less than the - * number of half lines. - */ -# define TV_VSYNC_START_F1_MASK 0x00007f00 -# define TV_VSYNC_START_F1_SHIFT 8 -/* - * Offset of the start of vsync in field 2, measured in one less than the - * number of half lines. - */ -# define TV_VSYNC_START_F2_MASK 0x0000007f -# define TV_VSYNC_START_F2_SHIFT 0 - -#define TV_V_CTL_3 _MMIO(0x68044) -/* Enables generation of the equalization signal */ -# define TV_EQUAL_ENA (1 << 31) -/* Length of vsync, in half lines */ -# define TV_VEQ_LEN_MASK 0x007f0000 -# define TV_VEQ_LEN_SHIFT 16 -/* Offset of the start of equalization in field 1, measured in one less than - * the number of half lines. - */ -# define TV_VEQ_START_F1_MASK 0x0007f00 -# define TV_VEQ_START_F1_SHIFT 8 -/* - * Offset of the start of equalization in field 2, measured in one less than - * the number of half lines. - */ -# define TV_VEQ_START_F2_MASK 0x000007f -# define TV_VEQ_START_F2_SHIFT 0 - -#define TV_V_CTL_4 _MMIO(0x68048) -/* - * Offset to start of vertical colorburst, measured in one less than the - * number of lines from vertical start. - */ -# define TV_VBURST_START_F1_MASK 0x003f0000 -# define TV_VBURST_START_F1_SHIFT 16 -/* - * Offset to the end of vertical colorburst, measured in one less than the - * number of lines from the start of NBR. - */ -# define TV_VBURST_END_F1_MASK 0x000000ff -# define TV_VBURST_END_F1_SHIFT 0 - -#define TV_V_CTL_5 _MMIO(0x6804c) -/* - * Offset to start of vertical colorburst, measured in one less than the - * number of lines from vertical start. - */ -# define TV_VBURST_START_F2_MASK 0x003f0000 -# define TV_VBURST_START_F2_SHIFT 16 -/* - * Offset to the end of vertical colorburst, measured in one less than the - * number of lines from the start of NBR. - */ -# define TV_VBURST_END_F2_MASK 0x000000ff -# define TV_VBURST_END_F2_SHIFT 0 - -#define TV_V_CTL_6 _MMIO(0x68050) -/* - * Offset to start of vertical colorburst, measured in one less than the - * number of lines from vertical start. - */ -# define TV_VBURST_START_F3_MASK 0x003f0000 -# define TV_VBURST_START_F3_SHIFT 16 -/* - * Offset to the end of vertical colorburst, measured in one less than the - * number of lines from the start of NBR. - */ -# define TV_VBURST_END_F3_MASK 0x000000ff -# define TV_VBURST_END_F3_SHIFT 0 - -#define TV_V_CTL_7 _MMIO(0x68054) -/* - * Offset to start of vertical colorburst, measured in one less than the - * number of lines from vertical start. - */ -# define TV_VBURST_START_F4_MASK 0x003f0000 -# define TV_VBURST_START_F4_SHIFT 16 -/* - * Offset to the end of vertical colorburst, measured in one less than the - * number of lines from the start of NBR. - */ -# define TV_VBURST_END_F4_MASK 0x000000ff -# define TV_VBURST_END_F4_SHIFT 0 - -#define TV_SC_CTL_1 _MMIO(0x68060) -/* Turns on the first subcarrier phase generation DDA */ -# define TV_SC_DDA1_EN (1 << 31) -/* Turns on the first subcarrier phase generation DDA */ -# define TV_SC_DDA2_EN (1 << 30) -/* Turns on the first subcarrier phase generation DDA */ -# define TV_SC_DDA3_EN (1 << 29) -/* Sets the subcarrier DDA to reset frequency every other field */ -# define TV_SC_RESET_EVERY_2 (0 << 24) -/* Sets the subcarrier DDA to reset frequency every fourth field */ -# define TV_SC_RESET_EVERY_4 (1 << 24) -/* Sets the subcarrier DDA to reset frequency every eighth field */ -# define TV_SC_RESET_EVERY_8 (2 << 24) -/* Sets the subcarrier DDA to never reset the frequency */ -# define TV_SC_RESET_NEVER (3 << 24) -/* Sets the peak amplitude of the colorburst.*/ -# define TV_BURST_LEVEL_MASK 0x00ff0000 -# define TV_BURST_LEVEL_SHIFT 16 -/* Sets the increment of the first subcarrier phase generation DDA */ -# define TV_SCDDA1_INC_MASK 0x00000fff -# define TV_SCDDA1_INC_SHIFT 0 - -#define TV_SC_CTL_2 _MMIO(0x68064) -/* Sets the rollover for the second subcarrier phase generation DDA */ -# define TV_SCDDA2_SIZE_MASK 0x7fff0000 -# define TV_SCDDA2_SIZE_SHIFT 16 -/* Sets the increent of the second subcarrier phase generation DDA */ -# define TV_SCDDA2_INC_MASK 0x00007fff -# define TV_SCDDA2_INC_SHIFT 0 - -#define TV_SC_CTL_3 _MMIO(0x68068) -/* Sets the rollover for the third subcarrier phase generation DDA */ -# define TV_SCDDA3_SIZE_MASK 0x7fff0000 -# define TV_SCDDA3_SIZE_SHIFT 16 -/* Sets the increent of the third subcarrier phase generation DDA */ -# define TV_SCDDA3_INC_MASK 0x00007fff -# define TV_SCDDA3_INC_SHIFT 0 - -#define TV_WIN_POS _MMIO(0x68070) -/* X coordinate of the display from the start of horizontal active */ -# define TV_XPOS_MASK 0x1fff0000 -# define TV_XPOS_SHIFT 16 -/* Y coordinate of the display from the start of vertical active (NBR) */ -# define TV_YPOS_MASK 0x00000fff -# define TV_YPOS_SHIFT 0 - -#define TV_WIN_SIZE _MMIO(0x68074) -/* Horizontal size of the display window, measured in pixels*/ -# define TV_XSIZE_MASK 0x1fff0000 -# define TV_XSIZE_SHIFT 16 -/* - * Vertical size of the display window, measured in pixels. - * - * Must be even for interlaced modes. - */ -# define TV_YSIZE_MASK 0x00000fff -# define TV_YSIZE_SHIFT 0 - -#define TV_FILTER_CTL_1 _MMIO(0x68080) -/* - * Enables automatic scaling calculation. - * - * If set, the rest of the registers are ignored, and the calculated values can - * be read back from the register. - */ -# define TV_AUTO_SCALE (1 << 31) -/* - * Disables the vertical filter. - * - * This is required on modes more than 1024 pixels wide */ -# define TV_V_FILTER_BYPASS (1 << 29) -/* Enables adaptive vertical filtering */ -# define TV_VADAPT (1 << 28) -# define TV_VADAPT_MODE_MASK (3 << 26) -/* Selects the least adaptive vertical filtering mode */ -# define TV_VADAPT_MODE_LEAST (0 << 26) -/* Selects the moderately adaptive vertical filtering mode */ -# define TV_VADAPT_MODE_MODERATE (1 << 26) -/* Selects the most adaptive vertical filtering mode */ -# define TV_VADAPT_MODE_MOST (3 << 26) -/* - * Sets the horizontal scaling factor. - * - * This should be the fractional part of the horizontal scaling factor divided - * by the oversampling rate. TV_HSCALE should be less than 1, and set to: - * - * (src width - 1) / ((oversample * dest width) - 1) - */ -# define TV_HSCALE_FRAC_MASK 0x00003fff -# define TV_HSCALE_FRAC_SHIFT 0 - -#define TV_FILTER_CTL_2 _MMIO(0x68084) -/* - * Sets the integer part of the 3.15 fixed-point vertical scaling factor. - * - * TV_VSCALE should be (src height - 1) / ((interlace * dest height) - 1) - */ -# define TV_VSCALE_INT_MASK 0x00038000 -# define TV_VSCALE_INT_SHIFT 15 -/* - * Sets the fractional part of the 3.15 fixed-point vertical scaling factor. - * - * \sa TV_VSCALE_INT_MASK - */ -# define TV_VSCALE_FRAC_MASK 0x00007fff -# define TV_VSCALE_FRAC_SHIFT 0 - -#define TV_FILTER_CTL_3 _MMIO(0x68088) -/* - * Sets the integer part of the 3.15 fixed-point vertical scaling factor. - * - * TV_VSCALE should be (src height - 1) / (1/4 * (dest height - 1)) - * - * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes. - */ -# define TV_VSCALE_IP_INT_MASK 0x00038000 -# define TV_VSCALE_IP_INT_SHIFT 15 -/* - * Sets the fractional part of the 3.15 fixed-point vertical scaling factor. - * - * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes. - * - * \sa TV_VSCALE_IP_INT_MASK - */ -# define TV_VSCALE_IP_FRAC_MASK 0x00007fff -# define TV_VSCALE_IP_FRAC_SHIFT 0 - -#define TV_CC_CONTROL _MMIO(0x68090) -# define TV_CC_ENABLE (1 << 31) -/* - * Specifies which field to send the CC data in. - * - * CC data is usually sent in field 0. - */ -# define TV_CC_FID_MASK (1 << 27) -# define TV_CC_FID_SHIFT 27 -/* Sets the horizontal position of the CC data. Usually 135. */ -# define TV_CC_HOFF_MASK 0x03ff0000 -# define TV_CC_HOFF_SHIFT 16 -/* Sets the vertical position of the CC data. Usually 21 */ -# define TV_CC_LINE_MASK 0x0000003f -# define TV_CC_LINE_SHIFT 0 - -#define TV_CC_DATA _MMIO(0x68094) -# define TV_CC_RDY (1 << 31) -/* Second word of CC data to be transmitted. */ -# define TV_CC_DATA_2_MASK 0x007f0000 -# define TV_CC_DATA_2_SHIFT 16 -/* First word of CC data to be transmitted. */ -# define TV_CC_DATA_1_MASK 0x0000007f -# define TV_CC_DATA_1_SHIFT 0 - -#define TV_H_LUMA(i) _MMIO(0x68100 + (i) * 4) /* 60 registers */ -#define TV_H_CHROMA(i) _MMIO(0x68200 + (i) * 4) /* 60 registers */ -#define TV_V_LUMA(i) _MMIO(0x68300 + (i) * 4) /* 43 registers */ -#define TV_V_CHROMA(i) _MMIO(0x68400 + (i) * 4) /* 43 registers */ - /* Display Port */ #define DP_A _MMIO(0x64000) /* eDP */ #define DP_B _MMIO(0x64100) -- cgit v1.2.3-59-g8ed1b From 89e790ec1a1ed930b58b0aebe50792acad90723d Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 16 Mar 2023 15:29:32 +0200 Subject: drm/i915/aux: split out DP AUX regs to a separate file Clean up i915_reg.h by splitting out DP AUX regs to display/intel_dp_aux_regs.h. Signed-off-by: Jani Nikula Reviewed-by: Nirmoy Das Link: https://patchwork.freedesktop.org/patch/msgid/aa93b34e786c5566acf8f053ffed96c160a23898.1678973282.git.jani.nikula@intel.com --- .../drm/i915/display/intel_display_power_well.c | 1 + drivers/gpu/drm/i915/display/intel_dp_aux.c | 1 + drivers/gpu/drm/i915/display/intel_dp_aux_regs.h | 84 ++++++++++++++++++++++ drivers/gpu/drm/i915/gvt/edid.c | 1 + drivers/gpu/drm/i915/gvt/handlers.c | 1 + drivers/gpu/drm/i915/i915_reg.h | 73 ------------------- drivers/gpu/drm/i915/intel_gvt_mmio_table.c | 1 + 7 files changed, 89 insertions(+), 73 deletions(-) create mode 100644 drivers/gpu/drm/i915/display/intel_dp_aux_regs.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_display_power_well.c b/drivers/gpu/drm/i915/display/intel_display_power_well.c index c694f28e6b2e..62bafcbc7937 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_well.c +++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c @@ -15,6 +15,7 @@ #include "intel_dkl_phy.h" #include "intel_dkl_phy_regs.h" #include "intel_dmc.h" +#include "intel_dp_aux_regs.h" #include "intel_dpio_phy.h" #include "intel_dpll.h" #include "intel_hotplug.h" diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux.c b/drivers/gpu/drm/i915/display/intel_dp_aux.c index eb07dc5d8709..fbdca7bd725d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux.c @@ -10,6 +10,7 @@ #include "intel_de.h" #include "intel_display_types.h" #include "intel_dp_aux.h" +#include "intel_dp_aux_regs.h" #include "intel_pps.h" #include "intel_tc.h" diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_regs.h b/drivers/gpu/drm/i915/display/intel_dp_aux_regs.h new file mode 100644 index 000000000000..5702f318d537 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_dp_aux_regs.h @@ -0,0 +1,84 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2023 Intel Corporation + */ + +#ifndef __INTEL_DP_AUX_REGS_H__ +#define __INTEL_DP_AUX_REGS_H__ + +#include "intel_display_reg_defs.h" + +/* + * The aux channel provides a way to talk to the signal sink for DDC etc. Max + * packet size supported is 20 bytes in each direction, hence the 5 fixed data + * registers + */ +#define _DPA_AUX_CH_CTL (DISPLAY_MMIO_BASE(dev_priv) + 0x64010) +#define _DPA_AUX_CH_DATA1 (DISPLAY_MMIO_BASE(dev_priv) + 0x64014) + +#define _DPB_AUX_CH_CTL (DISPLAY_MMIO_BASE(dev_priv) + 0x64110) +#define _DPB_AUX_CH_DATA1 (DISPLAY_MMIO_BASE(dev_priv) + 0x64114) + +#define DP_AUX_CH_CTL(aux_ch) _MMIO_PORT(aux_ch, _DPA_AUX_CH_CTL, _DPB_AUX_CH_CTL) +#define DP_AUX_CH_DATA(aux_ch, i) _MMIO(_PORT(aux_ch, _DPA_AUX_CH_DATA1, _DPB_AUX_CH_DATA1) + (i) * 4) /* 5 registers */ + +#define _XELPDP_USBC1_AUX_CH_CTL 0x16F210 +#define _XELPDP_USBC2_AUX_CH_CTL 0x16F410 +#define _XELPDP_USBC3_AUX_CH_CTL 0x16F610 +#define _XELPDP_USBC4_AUX_CH_CTL 0x16F810 + +#define XELPDP_DP_AUX_CH_CTL(aux_ch) _MMIO(_PICK(aux_ch, \ + _DPA_AUX_CH_CTL, \ + _DPB_AUX_CH_CTL, \ + 0, /* port/aux_ch C is non-existent */ \ + _XELPDP_USBC1_AUX_CH_CTL, \ + _XELPDP_USBC2_AUX_CH_CTL, \ + _XELPDP_USBC3_AUX_CH_CTL, \ + _XELPDP_USBC4_AUX_CH_CTL)) + +#define _XELPDP_USBC1_AUX_CH_DATA1 0x16F214 +#define _XELPDP_USBC2_AUX_CH_DATA1 0x16F414 +#define _XELPDP_USBC3_AUX_CH_DATA1 0x16F614 +#define _XELPDP_USBC4_AUX_CH_DATA1 0x16F814 + +#define XELPDP_DP_AUX_CH_DATA(aux_ch, i) _MMIO(_PICK(aux_ch, \ + _DPA_AUX_CH_DATA1, \ + _DPB_AUX_CH_DATA1, \ + 0, /* port/aux_ch C is non-existent */ \ + _XELPDP_USBC1_AUX_CH_DATA1, \ + _XELPDP_USBC2_AUX_CH_DATA1, \ + _XELPDP_USBC3_AUX_CH_DATA1, \ + _XELPDP_USBC4_AUX_CH_DATA1) + (i) * 4) + +#define DP_AUX_CH_CTL_SEND_BUSY (1 << 31) +#define DP_AUX_CH_CTL_DONE (1 << 30) +#define DP_AUX_CH_CTL_INTERRUPT (1 << 29) +#define DP_AUX_CH_CTL_TIME_OUT_ERROR (1 << 28) +#define DP_AUX_CH_CTL_TIME_OUT_400us (0 << 26) +#define DP_AUX_CH_CTL_TIME_OUT_600us (1 << 26) +#define DP_AUX_CH_CTL_TIME_OUT_800us (2 << 26) +#define DP_AUX_CH_CTL_TIME_OUT_MAX (3 << 26) /* Varies per platform */ +#define DP_AUX_CH_CTL_TIME_OUT_MASK (3 << 26) +#define DP_AUX_CH_CTL_RECEIVE_ERROR (1 << 25) +#define DP_AUX_CH_CTL_MESSAGE_SIZE_MASK (0x1f << 20) +#define DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT 20 +#define XELPDP_DP_AUX_CH_CTL_POWER_REQUEST REG_BIT(19) +#define XELPDP_DP_AUX_CH_CTL_POWER_STATUS REG_BIT(18) +#define DP_AUX_CH_CTL_PRECHARGE_2US_MASK (0xf << 16) +#define DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT 16 +#define DP_AUX_CH_CTL_AUX_AKSV_SELECT (1 << 15) +#define DP_AUX_CH_CTL_MANCHESTER_TEST (1 << 14) +#define DP_AUX_CH_CTL_SYNC_TEST (1 << 13) +#define DP_AUX_CH_CTL_DEGLITCH_TEST (1 << 12) +#define DP_AUX_CH_CTL_PRECHARGE_TEST (1 << 11) +#define DP_AUX_CH_CTL_BIT_CLOCK_2X_MASK (0x7ff) +#define DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT 0 +#define DP_AUX_CH_CTL_PSR_DATA_AUX_REG_SKL (1 << 14) +#define DP_AUX_CH_CTL_FS_DATA_AUX_REG_SKL (1 << 13) +#define DP_AUX_CH_CTL_GTC_DATA_AUX_REG_SKL (1 << 12) +#define DP_AUX_CH_CTL_TBT_IO (1 << 11) +#define DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL_MASK (0x1f << 5) +#define DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(c) (((c) - 1) << 5) +#define DP_AUX_CH_CTL_SYNC_PULSE_SKL(c) ((c) - 1) + +#endif /* __INTEL_DP_AUX_REGS_H__ */ diff --git a/drivers/gpu/drm/i915/gvt/edid.c b/drivers/gpu/drm/i915/gvt/edid.c index 1b509c1a1e33..7c49a3d673a5 100644 --- a/drivers/gpu/drm/i915/gvt/edid.c +++ b/drivers/gpu/drm/i915/gvt/edid.c @@ -32,6 +32,7 @@ * */ +#include "display/intel_dp_aux_regs.h" #include "display/intel_gmbus_regs.h" #include "gvt.h" #include "i915_drv.h" diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index d670abd2e6f9..70f8e35aa0af 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -43,6 +43,7 @@ #include "intel_mchbar_regs.h" #include "display/intel_display_types.h" #include "display/intel_dmc_regs.h" +#include "display/intel_dp_aux_regs.h" #include "display/intel_dpio_phy.h" #include "display/intel_fbc.h" #include "display/intel_pps_regs.h" diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5b7869001492..92333d2fb3ac 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2687,79 +2687,6 @@ /* A fantasy */ #define DP_DETECTED (1 << 2) -/* The aux channel provides a way to talk to the - * signal sink for DDC etc. Max packet size supported - * is 20 bytes in each direction, hence the 5 fixed - * data registers - */ -#define _DPA_AUX_CH_CTL (DISPLAY_MMIO_BASE(dev_priv) + 0x64010) -#define _DPA_AUX_CH_DATA1 (DISPLAY_MMIO_BASE(dev_priv) + 0x64014) - -#define _DPB_AUX_CH_CTL (DISPLAY_MMIO_BASE(dev_priv) + 0x64110) -#define _DPB_AUX_CH_DATA1 (DISPLAY_MMIO_BASE(dev_priv) + 0x64114) - -#define DP_AUX_CH_CTL(aux_ch) _MMIO_PORT(aux_ch, _DPA_AUX_CH_CTL, _DPB_AUX_CH_CTL) -#define DP_AUX_CH_DATA(aux_ch, i) _MMIO(_PORT(aux_ch, _DPA_AUX_CH_DATA1, _DPB_AUX_CH_DATA1) + (i) * 4) /* 5 registers */ - -#define _XELPDP_USBC1_AUX_CH_CTL 0x16F210 -#define _XELPDP_USBC2_AUX_CH_CTL 0x16F410 -#define _XELPDP_USBC3_AUX_CH_CTL 0x16F610 -#define _XELPDP_USBC4_AUX_CH_CTL 0x16F810 - -#define XELPDP_DP_AUX_CH_CTL(aux_ch) _MMIO(_PICK(aux_ch, \ - _DPA_AUX_CH_CTL, \ - _DPB_AUX_CH_CTL, \ - 0, /* port/aux_ch C is non-existent */ \ - _XELPDP_USBC1_AUX_CH_CTL, \ - _XELPDP_USBC2_AUX_CH_CTL, \ - _XELPDP_USBC3_AUX_CH_CTL, \ - _XELPDP_USBC4_AUX_CH_CTL)) - -#define _XELPDP_USBC1_AUX_CH_DATA1 0x16F214 -#define _XELPDP_USBC2_AUX_CH_DATA1 0x16F414 -#define _XELPDP_USBC3_AUX_CH_DATA1 0x16F614 -#define _XELPDP_USBC4_AUX_CH_DATA1 0x16F814 - -#define XELPDP_DP_AUX_CH_DATA(aux_ch, i) _MMIO(_PICK(aux_ch, \ - _DPA_AUX_CH_DATA1, \ - _DPB_AUX_CH_DATA1, \ - 0, /* port/aux_ch C is non-existent */ \ - _XELPDP_USBC1_AUX_CH_DATA1, \ - _XELPDP_USBC2_AUX_CH_DATA1, \ - _XELPDP_USBC3_AUX_CH_DATA1, \ - _XELPDP_USBC4_AUX_CH_DATA1) + (i) * 4) - -#define DP_AUX_CH_CTL_SEND_BUSY (1 << 31) -#define DP_AUX_CH_CTL_DONE (1 << 30) -#define DP_AUX_CH_CTL_INTERRUPT (1 << 29) -#define DP_AUX_CH_CTL_TIME_OUT_ERROR (1 << 28) -#define DP_AUX_CH_CTL_TIME_OUT_400us (0 << 26) -#define DP_AUX_CH_CTL_TIME_OUT_600us (1 << 26) -#define DP_AUX_CH_CTL_TIME_OUT_800us (2 << 26) -#define DP_AUX_CH_CTL_TIME_OUT_MAX (3 << 26) /* Varies per platform */ -#define DP_AUX_CH_CTL_TIME_OUT_MASK (3 << 26) -#define DP_AUX_CH_CTL_RECEIVE_ERROR (1 << 25) -#define DP_AUX_CH_CTL_MESSAGE_SIZE_MASK (0x1f << 20) -#define DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT 20 -#define XELPDP_DP_AUX_CH_CTL_POWER_REQUEST REG_BIT(19) -#define XELPDP_DP_AUX_CH_CTL_POWER_STATUS REG_BIT(18) -#define DP_AUX_CH_CTL_PRECHARGE_2US_MASK (0xf << 16) -#define DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT 16 -#define DP_AUX_CH_CTL_AUX_AKSV_SELECT (1 << 15) -#define DP_AUX_CH_CTL_MANCHESTER_TEST (1 << 14) -#define DP_AUX_CH_CTL_SYNC_TEST (1 << 13) -#define DP_AUX_CH_CTL_DEGLITCH_TEST (1 << 12) -#define DP_AUX_CH_CTL_PRECHARGE_TEST (1 << 11) -#define DP_AUX_CH_CTL_BIT_CLOCK_2X_MASK (0x7ff) -#define DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT 0 -#define DP_AUX_CH_CTL_PSR_DATA_AUX_REG_SKL (1 << 14) -#define DP_AUX_CH_CTL_FS_DATA_AUX_REG_SKL (1 << 13) -#define DP_AUX_CH_CTL_GTC_DATA_AUX_REG_SKL (1 << 12) -#define DP_AUX_CH_CTL_TBT_IO (1 << 11) -#define DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL_MASK (0x1f << 5) -#define DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(c) (((c) - 1) << 5) -#define DP_AUX_CH_CTL_SYNC_PULSE_SKL(c) ((c) - 1) - /* * Computing GMCH M and N values for the Display Port link * diff --git a/drivers/gpu/drm/i915/intel_gvt_mmio_table.c b/drivers/gpu/drm/i915/intel_gvt_mmio_table.c index 091743e32e17..529ebc51ca8a 100644 --- a/drivers/gpu/drm/i915/intel_gvt_mmio_table.c +++ b/drivers/gpu/drm/i915/intel_gvt_mmio_table.c @@ -7,6 +7,7 @@ #include "display/intel_backlight_regs.h" #include "display/intel_display_types.h" #include "display/intel_dmc_regs.h" +#include "display/intel_dp_aux_regs.h" #include "display/intel_dpio_phy.h" #include "display/intel_lvds_regs.h" #include "display/vlv_dsi_pll_regs.h" -- cgit v1.2.3-59-g8ed1b From 04500bfd7053482a1a4a81f86b57faff5c788199 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 16 Mar 2023 15:29:33 +0200 Subject: drm/i915/fdi: split out FDI regs to a separate file Clean up i915_reg.h by splitting out FDI regs to display/intel_fdi_regs.h. Signed-off-by: Jani Nikula Reviewed-by: Nirmoy Das Link: https://patchwork.freedesktop.org/patch/msgid/bba37e46d767e2193d49d1d2e289040c6bf8229b.1678973282.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_crt.c | 1 + drivers/gpu/drm/i915/display/intel_fdi.c | 1 + drivers/gpu/drm/i915/display/intel_fdi_regs.h | 151 +++++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_pch_display.c | 1 + drivers/gpu/drm/i915/gvt/handlers.c | 1 + drivers/gpu/drm/i915/i915_irq.c | 1 + drivers/gpu/drm/i915/i915_reg.h | 141 --------------------- drivers/gpu/drm/i915/intel_gvt_mmio_table.c | 1 + 8 files changed, 157 insertions(+), 141 deletions(-) create mode 100644 drivers/gpu/drm/i915/display/intel_fdi_regs.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_crt.c b/drivers/gpu/drm/i915/display/intel_crt.c index 8f2ebead0826..38e9c61c2344 100644 --- a/drivers/gpu/drm/i915/display/intel_crt.c +++ b/drivers/gpu/drm/i915/display/intel_crt.c @@ -44,6 +44,7 @@ #include "intel_de.h" #include "intel_display_types.h" #include "intel_fdi.h" +#include "intel_fdi_regs.h" #include "intel_fifo_underrun.h" #include "intel_gmbus.h" #include "intel_hotplug.h" diff --git a/drivers/gpu/drm/i915/display/intel_fdi.c b/drivers/gpu/drm/i915/display/intel_fdi.c index c08c26a321b3..55283677c45a 100644 --- a/drivers/gpu/drm/i915/display/intel_fdi.c +++ b/drivers/gpu/drm/i915/display/intel_fdi.c @@ -12,6 +12,7 @@ #include "intel_de.h" #include "intel_display_types.h" #include "intel_fdi.h" +#include "intel_fdi_regs.h" struct intel_fdi_funcs { void (*fdi_link_train)(struct intel_crtc *crtc, diff --git a/drivers/gpu/drm/i915/display/intel_fdi_regs.h b/drivers/gpu/drm/i915/display/intel_fdi_regs.h new file mode 100644 index 000000000000..853b834c35a9 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_fdi_regs.h @@ -0,0 +1,151 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2023 Intel Corporation + */ + +#ifndef __INTEL_FDI_REGS_H__ +#define __INTEL_FDI_REGS_H__ + +#include "intel_display_reg_defs.h" + +#define FDI_PLL_BIOS_0 _MMIO(0x46000) +#define FDI_PLL_FB_CLOCK_MASK 0xff +#define FDI_PLL_BIOS_1 _MMIO(0x46004) +#define FDI_PLL_BIOS_2 _MMIO(0x46008) +#define DISPLAY_PORT_PLL_BIOS_0 _MMIO(0x4600c) +#define DISPLAY_PORT_PLL_BIOS_1 _MMIO(0x46010) +#define DISPLAY_PORT_PLL_BIOS_2 _MMIO(0x46014) + +#define FDI_PLL_FREQ_CTL _MMIO(0x46030) +#define FDI_PLL_FREQ_CHANGE_REQUEST (1 << 24) +#define FDI_PLL_FREQ_LOCK_LIMIT_MASK 0xfff00 +#define FDI_PLL_FREQ_DISABLE_COUNT_LIMIT_MASK 0xff + +#define _FDI_RXA_CHICKEN 0xc200c +#define _FDI_RXB_CHICKEN 0xc2010 +#define FDI_RX_PHASE_SYNC_POINTER_OVR (1 << 1) +#define FDI_RX_PHASE_SYNC_POINTER_EN (1 << 0) +#define FDI_RX_CHICKEN(pipe) _MMIO_PIPE(pipe, _FDI_RXA_CHICKEN, _FDI_RXB_CHICKEN) + +/* CPU: FDI_TX */ +#define _FDI_TXA_CTL 0x60100 +#define _FDI_TXB_CTL 0x61100 +#define FDI_TX_CTL(pipe) _MMIO_PIPE(pipe, _FDI_TXA_CTL, _FDI_TXB_CTL) +#define FDI_TX_DISABLE (0 << 31) +#define FDI_TX_ENABLE (1 << 31) +#define FDI_LINK_TRAIN_PATTERN_1 (0 << 28) +#define FDI_LINK_TRAIN_PATTERN_2 (1 << 28) +#define FDI_LINK_TRAIN_PATTERN_IDLE (2 << 28) +#define FDI_LINK_TRAIN_NONE (3 << 28) +#define FDI_LINK_TRAIN_VOLTAGE_0_4V (0 << 25) +#define FDI_LINK_TRAIN_VOLTAGE_0_6V (1 << 25) +#define FDI_LINK_TRAIN_VOLTAGE_0_8V (2 << 25) +#define FDI_LINK_TRAIN_VOLTAGE_1_2V (3 << 25) +#define FDI_LINK_TRAIN_PRE_EMPHASIS_NONE (0 << 22) +#define FDI_LINK_TRAIN_PRE_EMPHASIS_1_5X (1 << 22) +#define FDI_LINK_TRAIN_PRE_EMPHASIS_2X (2 << 22) +#define FDI_LINK_TRAIN_PRE_EMPHASIS_3X (3 << 22) +/* ILK always use 400mV 0dB for voltage swing and pre-emphasis level. + SNB has different settings. */ +/* SNB A-stepping */ +#define FDI_LINK_TRAIN_400MV_0DB_SNB_A (0x38 << 22) +#define FDI_LINK_TRAIN_400MV_6DB_SNB_A (0x02 << 22) +#define FDI_LINK_TRAIN_600MV_3_5DB_SNB_A (0x01 << 22) +#define FDI_LINK_TRAIN_800MV_0DB_SNB_A (0x0 << 22) +/* SNB B-stepping */ +#define FDI_LINK_TRAIN_400MV_0DB_SNB_B (0x0 << 22) +#define FDI_LINK_TRAIN_400MV_6DB_SNB_B (0x3a << 22) +#define FDI_LINK_TRAIN_600MV_3_5DB_SNB_B (0x39 << 22) +#define FDI_LINK_TRAIN_800MV_0DB_SNB_B (0x38 << 22) +#define FDI_LINK_TRAIN_VOL_EMP_MASK (0x3f << 22) +#define FDI_DP_PORT_WIDTH_SHIFT 19 +#define FDI_DP_PORT_WIDTH_MASK (7 << FDI_DP_PORT_WIDTH_SHIFT) +#define FDI_DP_PORT_WIDTH(width) (((width) - 1) << FDI_DP_PORT_WIDTH_SHIFT) +#define FDI_TX_ENHANCE_FRAME_ENABLE (1 << 18) +/* Ironlake: hardwired to 1 */ +#define FDI_TX_PLL_ENABLE (1 << 14) + +/* Ivybridge has different bits for lolz */ +#define FDI_LINK_TRAIN_PATTERN_1_IVB (0 << 8) +#define FDI_LINK_TRAIN_PATTERN_2_IVB (1 << 8) +#define FDI_LINK_TRAIN_PATTERN_IDLE_IVB (2 << 8) +#define FDI_LINK_TRAIN_NONE_IVB (3 << 8) + +/* both Tx and Rx */ +#define FDI_COMPOSITE_SYNC (1 << 11) +#define FDI_LINK_TRAIN_AUTO (1 << 10) +#define FDI_SCRAMBLING_ENABLE (0 << 7) +#define FDI_SCRAMBLING_DISABLE (1 << 7) + +/* FDI_RX, FDI_X is hard-wired to Transcoder_X */ +#define _FDI_RXA_CTL 0xf000c +#define _FDI_RXB_CTL 0xf100c +#define FDI_RX_CTL(pipe) _MMIO_PIPE(pipe, _FDI_RXA_CTL, _FDI_RXB_CTL) +#define FDI_RX_ENABLE (1 << 31) +/* train, dp width same as FDI_TX */ +#define FDI_FS_ERRC_ENABLE (1 << 27) +#define FDI_FE_ERRC_ENABLE (1 << 26) +#define FDI_RX_POLARITY_REVERSED_LPT (1 << 16) +#define FDI_8BPC (0 << 16) +#define FDI_10BPC (1 << 16) +#define FDI_6BPC (2 << 16) +#define FDI_12BPC (3 << 16) +#define FDI_RX_LINK_REVERSAL_OVERRIDE (1 << 15) +#define FDI_DMI_LINK_REVERSE_MASK (1 << 14) +#define FDI_RX_PLL_ENABLE (1 << 13) +#define FDI_FS_ERR_CORRECT_ENABLE (1 << 11) +#define FDI_FE_ERR_CORRECT_ENABLE (1 << 10) +#define FDI_FS_ERR_REPORT_ENABLE (1 << 9) +#define FDI_FE_ERR_REPORT_ENABLE (1 << 8) +#define FDI_RX_ENHANCE_FRAME_ENABLE (1 << 6) +#define FDI_PCDCLK (1 << 4) +/* CPT */ +#define FDI_AUTO_TRAINING (1 << 10) +#define FDI_LINK_TRAIN_PATTERN_1_CPT (0 << 8) +#define FDI_LINK_TRAIN_PATTERN_2_CPT (1 << 8) +#define FDI_LINK_TRAIN_PATTERN_IDLE_CPT (2 << 8) +#define FDI_LINK_TRAIN_NORMAL_CPT (3 << 8) +#define FDI_LINK_TRAIN_PATTERN_MASK_CPT (3 << 8) + +#define _FDI_RXA_MISC 0xf0010 +#define _FDI_RXB_MISC 0xf1010 +#define FDI_RX_PWRDN_LANE1_MASK (3 << 26) +#define FDI_RX_PWRDN_LANE1_VAL(x) ((x) << 26) +#define FDI_RX_PWRDN_LANE0_MASK (3 << 24) +#define FDI_RX_PWRDN_LANE0_VAL(x) ((x) << 24) +#define FDI_RX_TP1_TO_TP2_48 (2 << 20) +#define FDI_RX_TP1_TO_TP2_64 (3 << 20) +#define FDI_RX_FDI_DELAY_90 (0x90 << 0) +#define FDI_RX_MISC(pipe) _MMIO_PIPE(pipe, _FDI_RXA_MISC, _FDI_RXB_MISC) + +#define _FDI_RXA_TUSIZE1 0xf0030 +#define _FDI_RXA_TUSIZE2 0xf0038 +#define _FDI_RXB_TUSIZE1 0xf1030 +#define _FDI_RXB_TUSIZE2 0xf1038 +#define FDI_RX_TUSIZE1(pipe) _MMIO_PIPE(pipe, _FDI_RXA_TUSIZE1, _FDI_RXB_TUSIZE1) +#define FDI_RX_TUSIZE2(pipe) _MMIO_PIPE(pipe, _FDI_RXA_TUSIZE2, _FDI_RXB_TUSIZE2) + +/* FDI_RX interrupt register format */ +#define FDI_RX_INTER_LANE_ALIGN (1 << 10) +#define FDI_RX_SYMBOL_LOCK (1 << 9) /* train 2 */ +#define FDI_RX_BIT_LOCK (1 << 8) /* train 1 */ +#define FDI_RX_TRAIN_PATTERN_2_FAIL (1 << 7) +#define FDI_RX_FS_CODE_ERR (1 << 6) +#define FDI_RX_FE_CODE_ERR (1 << 5) +#define FDI_RX_SYMBOL_ERR_RATE_ABOVE (1 << 4) +#define FDI_RX_HDCP_LINK_FAIL (1 << 3) +#define FDI_RX_PIXEL_FIFO_OVERFLOW (1 << 2) +#define FDI_RX_CROSS_CLOCK_OVERFLOW (1 << 1) +#define FDI_RX_SYMBOL_QUEUE_OVERFLOW (1 << 0) + +#define _FDI_RXA_IIR 0xf0014 +#define _FDI_RXA_IMR 0xf0018 +#define _FDI_RXB_IIR 0xf1014 +#define _FDI_RXB_IMR 0xf1018 +#define FDI_RX_IIR(pipe) _MMIO_PIPE(pipe, _FDI_RXA_IIR, _FDI_RXB_IIR) +#define FDI_RX_IMR(pipe) _MMIO_PIPE(pipe, _FDI_RXA_IMR, _FDI_RXB_IMR) + +#define FDI_PLL_CTL_1 _MMIO(0xfe000) +#define FDI_PLL_CTL_2 _MMIO(0xfe004) + +#endif /* __INTEL_FDI_REGS_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_pch_display.c b/drivers/gpu/drm/i915/display/intel_pch_display.c index 22507da0b5f0..2411fe4dee8b 100644 --- a/drivers/gpu/drm/i915/display/intel_pch_display.c +++ b/drivers/gpu/drm/i915/display/intel_pch_display.c @@ -9,6 +9,7 @@ #include "intel_de.h" #include "intel_display_types.h" #include "intel_fdi.h" +#include "intel_fdi_regs.h" #include "intel_lvds.h" #include "intel_lvds_regs.h" #include "intel_pch_display.h" diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 70f8e35aa0af..ea6a21dc8322 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -46,6 +46,7 @@ #include "display/intel_dp_aux_regs.h" #include "display/intel_dpio_phy.h" #include "display/intel_fbc.h" +#include "display/intel_fdi_regs.h" #include "display/intel_pps_regs.h" #include "display/vlv_dsi_pll_regs.h" #include "gt/intel_gt_regs.h" diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 31271c30a8cf..c0888cc88d04 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -37,6 +37,7 @@ #include "display/intel_de.h" #include "display/intel_display_trace.h" #include "display/intel_display_types.h" +#include "display/intel_fdi_regs.h" #include "display/intel_fifo_underrun.h" #include "display/intel_hotplug.h" #include "display/intel_lpe_audio.h" diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 92333d2fb3ac..7c80f5d856a9 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4320,14 +4320,6 @@ #define RR_HW_LOW_POWER_FRAMES_MASK 0xff #define RR_HW_HIGH_POWER_FRAMES_MASK 0xff00 -#define FDI_PLL_BIOS_0 _MMIO(0x46000) -#define FDI_PLL_FB_CLOCK_MASK 0xff -#define FDI_PLL_BIOS_1 _MMIO(0x46004) -#define FDI_PLL_BIOS_2 _MMIO(0x46008) -#define DISPLAY_PORT_PLL_BIOS_0 _MMIO(0x4600c) -#define DISPLAY_PORT_PLL_BIOS_1 _MMIO(0x46010) -#define DISPLAY_PORT_PLL_BIOS_2 _MMIO(0x46014) - #define PCH_3DCGDIS0 _MMIO(0x46020) # define MARIUNIT_CLOCK_GATE_DISABLE (1 << 18) # define SVSMUNIT_CLOCK_GATE_DISABLE (1 << 1) @@ -4335,12 +4327,6 @@ #define PCH_3DCGDIS1 _MMIO(0x46024) # define VFMUNIT_CLOCK_GATE_DISABLE (1 << 11) -#define FDI_PLL_FREQ_CTL _MMIO(0x46030) -#define FDI_PLL_FREQ_CHANGE_REQUEST (1 << 24) -#define FDI_PLL_FREQ_LOCK_LIMIT_MASK 0xfff00 -#define FDI_PLL_FREQ_DISABLE_COUNT_LIMIT_MASK 0xff - - #define _PIPEA_DATA_M1 0x60030 #define _PIPEA_DATA_N1 0x60034 #define _PIPEA_DATA_M2 0x60038 @@ -5531,12 +5517,6 @@ #define LPT_PWM_GRANULARITY (1 << 5) #define DPLS_EDP_PPS_FIX_DIS (1 << 0) -#define _FDI_RXA_CHICKEN 0xc200c -#define _FDI_RXB_CHICKEN 0xc2010 -#define FDI_RX_PHASE_SYNC_POINTER_OVR (1 << 1) -#define FDI_RX_PHASE_SYNC_POINTER_EN (1 << 0) -#define FDI_RX_CHICKEN(pipe) _MMIO_PIPE(pipe, _FDI_RXA_CHICKEN, _FDI_RXB_CHICKEN) - #define SOUTH_DSPCLK_GATE_D _MMIO(0xc2020) #define PCH_GMBUSUNIT_CLOCK_GATE_DISABLE (1 << 31) #define PCH_DPLUNIT_CLOCK_GATE_DISABLE (1 << 30) @@ -5546,127 +5526,6 @@ #define CNP_PWM_CGE_GATING_DISABLE (1 << 13) #define PCH_LP_PARTITION_LEVEL_DISABLE (1 << 12) -/* CPU: FDI_TX */ -#define _FDI_TXA_CTL 0x60100 -#define _FDI_TXB_CTL 0x61100 -#define FDI_TX_CTL(pipe) _MMIO_PIPE(pipe, _FDI_TXA_CTL, _FDI_TXB_CTL) -#define FDI_TX_DISABLE (0 << 31) -#define FDI_TX_ENABLE (1 << 31) -#define FDI_LINK_TRAIN_PATTERN_1 (0 << 28) -#define FDI_LINK_TRAIN_PATTERN_2 (1 << 28) -#define FDI_LINK_TRAIN_PATTERN_IDLE (2 << 28) -#define FDI_LINK_TRAIN_NONE (3 << 28) -#define FDI_LINK_TRAIN_VOLTAGE_0_4V (0 << 25) -#define FDI_LINK_TRAIN_VOLTAGE_0_6V (1 << 25) -#define FDI_LINK_TRAIN_VOLTAGE_0_8V (2 << 25) -#define FDI_LINK_TRAIN_VOLTAGE_1_2V (3 << 25) -#define FDI_LINK_TRAIN_PRE_EMPHASIS_NONE (0 << 22) -#define FDI_LINK_TRAIN_PRE_EMPHASIS_1_5X (1 << 22) -#define FDI_LINK_TRAIN_PRE_EMPHASIS_2X (2 << 22) -#define FDI_LINK_TRAIN_PRE_EMPHASIS_3X (3 << 22) -/* ILK always use 400mV 0dB for voltage swing and pre-emphasis level. - SNB has different settings. */ -/* SNB A-stepping */ -#define FDI_LINK_TRAIN_400MV_0DB_SNB_A (0x38 << 22) -#define FDI_LINK_TRAIN_400MV_6DB_SNB_A (0x02 << 22) -#define FDI_LINK_TRAIN_600MV_3_5DB_SNB_A (0x01 << 22) -#define FDI_LINK_TRAIN_800MV_0DB_SNB_A (0x0 << 22) -/* SNB B-stepping */ -#define FDI_LINK_TRAIN_400MV_0DB_SNB_B (0x0 << 22) -#define FDI_LINK_TRAIN_400MV_6DB_SNB_B (0x3a << 22) -#define FDI_LINK_TRAIN_600MV_3_5DB_SNB_B (0x39 << 22) -#define FDI_LINK_TRAIN_800MV_0DB_SNB_B (0x38 << 22) -#define FDI_LINK_TRAIN_VOL_EMP_MASK (0x3f << 22) -#define FDI_DP_PORT_WIDTH_SHIFT 19 -#define FDI_DP_PORT_WIDTH_MASK (7 << FDI_DP_PORT_WIDTH_SHIFT) -#define FDI_DP_PORT_WIDTH(width) (((width) - 1) << FDI_DP_PORT_WIDTH_SHIFT) -#define FDI_TX_ENHANCE_FRAME_ENABLE (1 << 18) -/* Ironlake: hardwired to 1 */ -#define FDI_TX_PLL_ENABLE (1 << 14) - -/* Ivybridge has different bits for lolz */ -#define FDI_LINK_TRAIN_PATTERN_1_IVB (0 << 8) -#define FDI_LINK_TRAIN_PATTERN_2_IVB (1 << 8) -#define FDI_LINK_TRAIN_PATTERN_IDLE_IVB (2 << 8) -#define FDI_LINK_TRAIN_NONE_IVB (3 << 8) - -/* both Tx and Rx */ -#define FDI_COMPOSITE_SYNC (1 << 11) -#define FDI_LINK_TRAIN_AUTO (1 << 10) -#define FDI_SCRAMBLING_ENABLE (0 << 7) -#define FDI_SCRAMBLING_DISABLE (1 << 7) - -/* FDI_RX, FDI_X is hard-wired to Transcoder_X */ -#define _FDI_RXA_CTL 0xf000c -#define _FDI_RXB_CTL 0xf100c -#define FDI_RX_CTL(pipe) _MMIO_PIPE(pipe, _FDI_RXA_CTL, _FDI_RXB_CTL) -#define FDI_RX_ENABLE (1 << 31) -/* train, dp width same as FDI_TX */ -#define FDI_FS_ERRC_ENABLE (1 << 27) -#define FDI_FE_ERRC_ENABLE (1 << 26) -#define FDI_RX_POLARITY_REVERSED_LPT (1 << 16) -#define FDI_8BPC (0 << 16) -#define FDI_10BPC (1 << 16) -#define FDI_6BPC (2 << 16) -#define FDI_12BPC (3 << 16) -#define FDI_RX_LINK_REVERSAL_OVERRIDE (1 << 15) -#define FDI_DMI_LINK_REVERSE_MASK (1 << 14) -#define FDI_RX_PLL_ENABLE (1 << 13) -#define FDI_FS_ERR_CORRECT_ENABLE (1 << 11) -#define FDI_FE_ERR_CORRECT_ENABLE (1 << 10) -#define FDI_FS_ERR_REPORT_ENABLE (1 << 9) -#define FDI_FE_ERR_REPORT_ENABLE (1 << 8) -#define FDI_RX_ENHANCE_FRAME_ENABLE (1 << 6) -#define FDI_PCDCLK (1 << 4) -/* CPT */ -#define FDI_AUTO_TRAINING (1 << 10) -#define FDI_LINK_TRAIN_PATTERN_1_CPT (0 << 8) -#define FDI_LINK_TRAIN_PATTERN_2_CPT (1 << 8) -#define FDI_LINK_TRAIN_PATTERN_IDLE_CPT (2 << 8) -#define FDI_LINK_TRAIN_NORMAL_CPT (3 << 8) -#define FDI_LINK_TRAIN_PATTERN_MASK_CPT (3 << 8) - -#define _FDI_RXA_MISC 0xf0010 -#define _FDI_RXB_MISC 0xf1010 -#define FDI_RX_PWRDN_LANE1_MASK (3 << 26) -#define FDI_RX_PWRDN_LANE1_VAL(x) ((x) << 26) -#define FDI_RX_PWRDN_LANE0_MASK (3 << 24) -#define FDI_RX_PWRDN_LANE0_VAL(x) ((x) << 24) -#define FDI_RX_TP1_TO_TP2_48 (2 << 20) -#define FDI_RX_TP1_TO_TP2_64 (3 << 20) -#define FDI_RX_FDI_DELAY_90 (0x90 << 0) -#define FDI_RX_MISC(pipe) _MMIO_PIPE(pipe, _FDI_RXA_MISC, _FDI_RXB_MISC) - -#define _FDI_RXA_TUSIZE1 0xf0030 -#define _FDI_RXA_TUSIZE2 0xf0038 -#define _FDI_RXB_TUSIZE1 0xf1030 -#define _FDI_RXB_TUSIZE2 0xf1038 -#define FDI_RX_TUSIZE1(pipe) _MMIO_PIPE(pipe, _FDI_RXA_TUSIZE1, _FDI_RXB_TUSIZE1) -#define FDI_RX_TUSIZE2(pipe) _MMIO_PIPE(pipe, _FDI_RXA_TUSIZE2, _FDI_RXB_TUSIZE2) - -/* FDI_RX interrupt register format */ -#define FDI_RX_INTER_LANE_ALIGN (1 << 10) -#define FDI_RX_SYMBOL_LOCK (1 << 9) /* train 2 */ -#define FDI_RX_BIT_LOCK (1 << 8) /* train 1 */ -#define FDI_RX_TRAIN_PATTERN_2_FAIL (1 << 7) -#define FDI_RX_FS_CODE_ERR (1 << 6) -#define FDI_RX_FE_CODE_ERR (1 << 5) -#define FDI_RX_SYMBOL_ERR_RATE_ABOVE (1 << 4) -#define FDI_RX_HDCP_LINK_FAIL (1 << 3) -#define FDI_RX_PIXEL_FIFO_OVERFLOW (1 << 2) -#define FDI_RX_CROSS_CLOCK_OVERFLOW (1 << 1) -#define FDI_RX_SYMBOL_QUEUE_OVERFLOW (1 << 0) - -#define _FDI_RXA_IIR 0xf0014 -#define _FDI_RXA_IMR 0xf0018 -#define _FDI_RXB_IIR 0xf1014 -#define _FDI_RXB_IMR 0xf1018 -#define FDI_RX_IIR(pipe) _MMIO_PIPE(pipe, _FDI_RXA_IIR, _FDI_RXB_IIR) -#define FDI_RX_IMR(pipe) _MMIO_PIPE(pipe, _FDI_RXA_IMR, _FDI_RXB_IMR) - -#define FDI_PLL_CTL_1 _MMIO(0xfe000) -#define FDI_PLL_CTL_2 _MMIO(0xfe004) - #define _PCH_DP_B 0xe4100 #define PCH_DP_B _MMIO(_PCH_DP_B) #define _PCH_DPB_AUX_CH_CTL 0xe4110 diff --git a/drivers/gpu/drm/i915/intel_gvt_mmio_table.c b/drivers/gpu/drm/i915/intel_gvt_mmio_table.c index 529ebc51ca8a..4bee209da425 100644 --- a/drivers/gpu/drm/i915/intel_gvt_mmio_table.c +++ b/drivers/gpu/drm/i915/intel_gvt_mmio_table.c @@ -9,6 +9,7 @@ #include "display/intel_dmc_regs.h" #include "display/intel_dp_aux_regs.h" #include "display/intel_dpio_phy.h" +#include "display/intel_fdi_regs.h" #include "display/intel_lvds_regs.h" #include "display/vlv_dsi_pll_regs.h" #include "gt/intel_gt_regs.h" -- cgit v1.2.3-59-g8ed1b From 9df56e5632c5055ba2bbb6c8c593a4da15181be2 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Thu, 16 Mar 2023 15:29:36 +0200 Subject: drm/i915/dsb: split out DSB regs to a separate file Clean up i915_reg.h by splitting out DSB regs to display/intel_dsb_regs.h. Signed-off-by: Jani Nikula Reviewed-by: Nirmoy Das Link: https://patchwork.freedesktop.org/patch/msgid/d74b3c564b2d080bf689b3360f1a5e62e47f2e7c.1678973283.git.jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_dsb.c | 1 + drivers/gpu/drm/i915/display/intel_dsb_regs.h | 67 +++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_reg.h | 56 ---------------------- 3 files changed, 68 insertions(+), 56 deletions(-) create mode 100644 drivers/gpu/drm/i915/display/intel_dsb_regs.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index 19e422da57dc..bed058d2c3ac 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -11,6 +11,7 @@ #include "intel_de.h" #include "intel_display_types.h" #include "intel_dsb.h" +#include "intel_dsb_regs.h" struct i915_vma; diff --git a/drivers/gpu/drm/i915/display/intel_dsb_regs.h b/drivers/gpu/drm/i915/display/intel_dsb_regs.h new file mode 100644 index 000000000000..12535d478775 --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_dsb_regs.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2023 Intel Corporation + */ + +#ifndef __INTEL_DSB_REGS_H__ +#define __INTEL_DSB_REGS_H__ + +#include "intel_display_reg_defs.h" + +/* This register controls the Display State Buffer (DSB) engines. */ +#define _DSBSL_INSTANCE_BASE 0x70B00 +#define DSBSL_INSTANCE(pipe, id) (_DSBSL_INSTANCE_BASE + \ + (pipe) * 0x1000 + (id) * 0x100) +#define DSB_HEAD(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x0) +#define DSB_TAIL(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x4) +#define DSB_CTRL(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x8) +#define DSB_ENABLE REG_BIT(31) +#define DSB_BUF_REITERATE REG_BIT(29) +#define DSB_WAIT_FOR_VBLANK REG_BIT(28) +#define DSB_WAIT_FOR_LINE_IN REG_BIT(27) +#define DSB_HALT REG_BIT(16) +#define DSB_NON_POSTED REG_BIT(8) +#define DSB_STATUS_BUSY REG_BIT(0) +#define DSB_MMIOCTRL(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0xc) +#define DSB_MMIO_DEAD_CLOCKS_ENABLE REG_BIT(31) +#define DSB_MMIO_DEAD_CLOCKS_COUNT_MASK REG_GENMASK(15, 8) +#define DSB_MMIO_DEAD_CLOCKS_COUNT(x) REG_FIELD_PREP(DSB_MMIO_DEAD_CLOCK_COUNT_MASK, (x)) +#define DSB_MMIO_CYCLES_MASK REG_GENMASK(7, 0) +#define DSB_MMIO_CYCLES(x) REG_FIELD_PREP(DSB_MMIO_CYCLES_MASK, (x)) +#define DSB_POLLFUNC(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x10) +#define DSB_POLL_ENABLE REG_BIT(31) +#define DSB_POLL_WAIT_MASK REG_GENMASK(30, 23) +#define DSB_POLL_WAIT(x) REG_FIELD_PREP(DSB_POLL_WAIT_MASK, (x)) /* usec */ +#define DSB_POLL_COUNT_MASK REG_GENMASK(22, 15) +#define DSB_POLL_COUNT(x) REG_FIELD_PREP(DSB_POLL_COUNT_MASK, (x)) +#define DSB_DEBUG(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x14) +#define DSB_POLLMASK(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x1c) +#define DSB_STATUS(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x24) +#define DSB_INTERRUPT(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x28) +#define DSB_ATS_FAULT_INT_EN REG_BIT(20) +#define DSB_GTT_FAULT_INT_EN REG_BIT(19) +#define DSB_RSPTIMEOUT_INT_EN REG_BIT(18) +#define DSB_POLL_ERR_INT_EN REG_BIT(17) +#define DSB_PROG_INT_EN REG_BIT(16) +#define DSB_ATS_FAULT_INT_STATUS REG_BIT(4) +#define DSB_GTT_FAULT_INT_STATUS REG_BIT(3) +#define DSB_RSPTIMEOUT_INT_STATUS REG_BIT(2) +#define DSB_POLL_ERR_INT_STATUS REG_BIT(1) +#define DSB_PROG_INT_STATUS REG_BIT(0) +#define DSB_CURRENT_HEAD(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x2c) +#define DSB_RM_TIMEOUT(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x30) +#define DSB_RM_CLAIM_TIMEOUT REG_BIT(31) +#define DSB_RM_READY_TIMEOUT REG_BIT(30) +#define DSB_RM_CLAIM_TIMEOUT_COUNT_MASK REG_GENMASK(23, 16) +#define DSB_RM_CLAIM_TIMEOUT_COUNT(x) REG_FIELD_PREP(DSB_RM_CLAIM_TIMEOUT_COUNT_MASK, (x)) /* clocks */ +#define DSB_RM_READY_TIMEOUT_VALUE_MASK REG_GENMASK(15, 0) +#define DSB_RM_READY_TIMEOUT_VALUE(x) REG_FIELD_PREP(DSB_RM_READY_TIMEOUT_VALUE, (x)) /* usec */ +#define DSB_RMTIMEOUTREG_CAPTURE(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x34) +#define DSB_PMCTRL(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x38) +#define DSB_PMCTRL_2(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x3c) +#define DSB_PF_LN_LOWER(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x40) +#define DSB_PF_LN_UPPER(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x44) +#define DSB_BUFRPT_CNT(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x48) +#define DSB_CHICKEN(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0xf0) + +#endif /* __INTEL_DSB_REGS_H__ */ diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 7c80f5d856a9..2b8751178f8b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6895,62 +6895,6 @@ enum skl_power_gate { #define OROM_OFFSET _MMIO(0x1020c0) #define OROM_OFFSET_MASK REG_GENMASK(20, 16) -/* This register controls the Display State Buffer (DSB) engines. */ -#define _DSBSL_INSTANCE_BASE 0x70B00 -#define DSBSL_INSTANCE(pipe, id) (_DSBSL_INSTANCE_BASE + \ - (pipe) * 0x1000 + (id) * 0x100) -#define DSB_HEAD(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x0) -#define DSB_TAIL(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x4) -#define DSB_CTRL(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x8) -#define DSB_ENABLE REG_BIT(31) -#define DSB_BUF_REITERATE REG_BIT(29) -#define DSB_WAIT_FOR_VBLANK REG_BIT(28) -#define DSB_WAIT_FOR_LINE_IN REG_BIT(27) -#define DSB_HALT REG_BIT(16) -#define DSB_NON_POSTED REG_BIT(8) -#define DSB_STATUS_BUSY REG_BIT(0) -#define DSB_MMIOCTRL(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0xc) -#define DSB_MMIO_DEAD_CLOCKS_ENABLE REG_BIT(31) -#define DSB_MMIO_DEAD_CLOCKS_COUNT_MASK REG_GENMASK(15, 8) -#define DSB_MMIO_DEAD_CLOCKS_COUNT(x) REG_FIELD_PREP(DSB_MMIO_DEAD_CLOCK_COUNT_MASK, (x)) -#define DSB_MMIO_CYCLES_MASK REG_GENMASK(7, 0) -#define DSB_MMIO_CYCLES(x) REG_FIELD_PREP(DSB_MMIO_CYCLES_MASK, (x)) -#define DSB_POLLFUNC(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x10) -#define DSB_POLL_ENABLE REG_BIT(31) -#define DSB_POLL_WAIT_MASK REG_GENMASK(30, 23) -#define DSB_POLL_WAIT(x) REG_FIELD_PREP(DSB_POLL_WAIT_MASK, (x)) /* usec */ -#define DSB_POLL_COUNT_MASK REG_GENMASK(22, 15) -#define DSB_POLL_COUNT(x) REG_FIELD_PREP(DSB_POLL_COUNT_MASK, (x)) -#define DSB_DEBUG(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x14) -#define DSB_POLLMASK(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x1c) -#define DSB_STATUS(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x24) -#define DSB_INTERRUPT(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x28) -#define DSB_ATS_FAULT_INT_EN REG_BIT(20) -#define DSB_GTT_FAULT_INT_EN REG_BIT(19) -#define DSB_RSPTIMEOUT_INT_EN REG_BIT(18) -#define DSB_POLL_ERR_INT_EN REG_BIT(17) -#define DSB_PROG_INT_EN REG_BIT(16) -#define DSB_ATS_FAULT_INT_STATUS REG_BIT(4) -#define DSB_GTT_FAULT_INT_STATUS REG_BIT(3) -#define DSB_RSPTIMEOUT_INT_STATUS REG_BIT(2) -#define DSB_POLL_ERR_INT_STATUS REG_BIT(1) -#define DSB_PROG_INT_STATUS REG_BIT(0) -#define DSB_CURRENT_HEAD(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x2c) -#define DSB_RM_TIMEOUT(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x30) -#define DSB_RM_CLAIM_TIMEOUT REG_BIT(31) -#define DSB_RM_READY_TIMEOUT REG_BIT(30) -#define DSB_RM_CLAIM_TIMEOUT_COUNT_MASK REG_GENMASK(23, 16) -#define DSB_RM_CLAIM_TIMEOUT_COUNT(x) REG_FIELD_PREP(DSB_RM_CLAIM_TIMEOUT_COUNT_MASK, (x)) /* clocks */ -#define DSB_RM_READY_TIMEOUT_VALUE_MASK REG_GENMASK(15, 0) -#define DSB_RM_READY_TIMEOUT_VALUE(x) REG_FIELD_PREP(DSB_RM_READY_TIMEOUT_VALUE, (x)) /* usec */ -#define DSB_RMTIMEOUTREG_CAPTURE(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x34) -#define DSB_PMCTRL(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x38) -#define DSB_PMCTRL_2(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x3c) -#define DSB_PF_LN_LOWER(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x40) -#define DSB_PF_LN_UPPER(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x44) -#define DSB_BUFRPT_CNT(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0x48) -#define DSB_CHICKEN(pipe, id) _MMIO(DSBSL_INSTANCE(pipe, id) + 0xf0) - #define CLKREQ_POLICY _MMIO(0x101038) #define CLKREQ_POLICY_MEM_UP_OVRD REG_BIT(1) -- cgit v1.2.3-59-g8ed1b From 8d8d062be6b96b1ba95a3f1a9ecaf218c9458497 Mon Sep 17 00:00:00 2001 From: Daniele Ceraolo Spurio Date: Mon, 27 Mar 2023 18:24:30 -0700 Subject: drm/i915/mtl: Fix MTL stolen memory GGTT mapping The PTEs expect the offset from the base of the fake LMEM region (i.e. the base of stolen) and not from the base of the DSM. Quoting the specs: "Driver will set the Device Memory bit = 1 in the PTE when pointing to a page in DSM and program the PTE with offset from LMEM_BAR. Device Memory Offset from LMEM_BAR is same as offset from BGSM." DSM starts 8MBs from BGSM, so we set dsm_base = 8MB. Signed-off-by: Daniele Ceraolo Spurio Cc: Aravind Iddamsetty Cc: Matt Roper Cc: Lucas De Marchi Cc: Jani Nikula Cc: Nirmoy Das Cc: Fei Yang Cc: Radhakrishna Sripada Reviewed-by: Andi Shyti Reviewed-by: Nirmoy Das Link: https://patchwork.freedesktop.org/patch/msgid/20230328012430.2524330-1-daniele.ceraolospurio@intel.com --- drivers/gpu/drm/i915/gem/i915_gem_stolen.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c index d8e06e783e30..8ac376c24aa2 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c @@ -890,8 +890,9 @@ i915_gem_stolen_lmem_setup(struct drm_i915_private *i915, u16 type, if (HAS_LMEMBAR_SMEM_STOLEN(i915)) { /* * MTL dsm size is in GGC register. - * Also MTL uses offset to DSMBASE in ptes, so i915 - * uses dsm_base = 0 to setup stolen region. + * Also MTL uses offset to GSMBASE in ptes, so i915 + * uses dsm_base = 8MBs to setup stolen region, since + * DSMBASE = GSMBASE + 8MB. */ ret = mtl_get_gms_size(uncore); if (ret < 0) { @@ -899,11 +900,11 @@ i915_gem_stolen_lmem_setup(struct drm_i915_private *i915, u16 type, return ERR_PTR(ret); } - dsm_base = 0; + dsm_base = SZ_8M; dsm_size = (resource_size_t)(ret * SZ_1M); GEM_BUG_ON(pci_resource_len(pdev, GEN12_LMEM_BAR) != SZ_256M); - GEM_BUG_ON((dsm_size + SZ_8M) > lmem_size); + GEM_BUG_ON((dsm_base + dsm_size) > lmem_size); } else { /* Use DSM base address instead for stolen memory */ dsm_base = intel_uncore_read64(uncore, GEN12_DSMBASE) & GEN12_BDSM_MASK; @@ -912,14 +913,12 @@ i915_gem_stolen_lmem_setup(struct drm_i915_private *i915, u16 type, dsm_size = ALIGN_DOWN(lmem_size - dsm_base, SZ_1M); } - io_size = dsm_size; - if (HAS_LMEMBAR_SMEM_STOLEN(i915)) { - io_start = pci_resource_start(pdev, GEN12_LMEM_BAR) + SZ_8M; - } else if (pci_resource_len(pdev, GEN12_LMEM_BAR) < lmem_size) { + if (pci_resource_len(pdev, GEN12_LMEM_BAR) < lmem_size) { io_start = 0; io_size = 0; } else { io_start = pci_resource_start(pdev, GEN12_LMEM_BAR) + dsm_base; + io_size = dsm_size; } min_page_size = HAS_64K_PAGES(i915) ? I915_GTT_PAGE_SIZE_64K : -- cgit v1.2.3-59-g8ed1b From 19d06582c47572be9635cf126195135df0720118 Mon Sep 17 00:00:00 2001 From: Jouni Högander Date: Wed, 29 Mar 2023 18:06:58 +0300 Subject: drm/i915/psr: Unify pre/post hooks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pre/post hooks are doing things differently. Unify them. Signed-off-by: Jouni Högander Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230329150703.432072-2-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 31084d95711d..8dbf452d63c2 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1954,23 +1954,22 @@ static void _intel_psr_post_plane_update(const struct intel_atomic_state *state, crtc_state->uapi.encoder_mask) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_psr *psr = &intel_dp->psr; + bool keep_disabled = false; mutex_lock(&psr->lock); - if (psr->sink_not_reliable) - goto exit; - drm_WARN_ON(&dev_priv->drm, psr->enabled && !crtc_state->active_planes); - /* Only enable if there is active planes */ - if (!psr->enabled && crtc_state->active_planes) + keep_disabled |= psr->sink_not_reliable; + keep_disabled |= !crtc_state->active_planes; + + if (!psr->enabled && !keep_disabled) intel_psr_enable_locked(intel_dp, crtc_state); /* Force a PSR exit when enabling CRC to avoid CRC timeouts */ if (crtc_state->crc_enabled && psr->enabled) psr_force_hw_tracking_exit(intel_dp); -exit: mutex_unlock(&psr->lock); } } -- cgit v1.2.3-59-g8ed1b From 44222656ecff73974c637b6b9c9bb5415978ed08 Mon Sep 17 00:00:00 2001 From: Jouni Högander Date: Wed, 29 Mar 2023 18:06:59 +0300 Subject: drm/i915/psr: Modify/Fix Wa_16013835468 and prepare for Wa_14015648006 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wa_16013835468 is a separate from Wa_14015648006 and needs to be applied for display version 12. Fix this by removing all the references to Wa_14015648006 and apply Wa_16013835468 according to Bspec. Also move workaround into separate function as a preparation for Wa_14015648006 implementation. Bspec: 55378 v3: - apply for display version 12 only v2: - keep applying the wa in intel_psr_enable_source Signed-off-by: Jouni Högander Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230329150703.432072-3-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 35 ++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 11 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 8dbf452d63c2..770f6fea5499 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1134,6 +1134,28 @@ static u32 wa_16013835468_bit_get(struct intel_dp *intel_dp) } } +/* + * Wa_16013835468 + */ +static void wm_optimization_wa(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state) +{ + struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); + bool set_wa_bit = false; + + /* Wa_16013835468 */ + if (DISPLAY_VER(dev_priv) == 12) + set_wa_bit |= crtc_state->hw.adjusted_mode.crtc_vblank_start != + crtc_state->hw.adjusted_mode.crtc_vdisplay; + + if (set_wa_bit) + intel_de_rmw(dev_priv, GEN8_CHICKEN_DCPR_1, + 0, wa_16013835468_bit_get(intel_dp)); + else + intel_de_rmw(dev_priv, GEN8_CHICKEN_DCPR_1, + wa_16013835468_bit_get(intel_dp), 0); +} + static void intel_psr_enable_source(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { @@ -1175,15 +1197,8 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp, /* * Wa_16013835468 - * Wa_14015648006 */ - if (IS_MTL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0) || - IS_DISPLAY_VER(dev_priv, 12, 13)) { - if (crtc_state->hw.adjusted_mode.crtc_vblank_start != - crtc_state->hw.adjusted_mode.crtc_vdisplay) - intel_de_rmw(dev_priv, GEN8_CHICKEN_DCPR_1, 0, - wa_16013835468_bit_get(intel_dp)); - } + wm_optimization_wa(intel_dp, crtc_state); if (intel_dp->psr.psr2_enabled) { if (DISPLAY_VER(dev_priv) == 9) @@ -1359,10 +1374,8 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp) /* * Wa_16013835468 - * Wa_14015648006 */ - if (IS_MTL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0) || - IS_DISPLAY_VER(dev_priv, 12, 13)) + if (DISPLAY_VER(dev_priv) == 12) intel_de_rmw(dev_priv, GEN8_CHICKEN_DCPR_1, wa_16013835468_bit_get(intel_dp), 0); -- cgit v1.2.3-59-g8ed1b From cdb015a61190060094152ff8ff6c6f34b616c13c Mon Sep 17 00:00:00 2001 From: Jouni Högander Date: Wed, 29 Mar 2023 18:07:00 +0300 Subject: drm/i915/psr: Implement Wa_14015648006 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PSR WM optimization should be disabled based on any wm level being disabled. Also same WA should be applied for ICL as well. Bspec: 71580 v5: - Set in pre plane hook and clear in post plane hook v4: - Handle mode change in psr enable/disable - Handle wm_level_disable changes separately in pre plane hook v3: - Split patch v2: - set/clear chicken bit in post_plane_update - apply for ICL as well Signed-off-by: Jouni Högander Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230329150703.432072-4-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_display_types.h | 1 + drivers/gpu/drm/i915/display/intel_psr.c | 16 +++++++++++++++- drivers/gpu/drm/i915/display/skl_watermark.c | 7 +++++-- 3 files changed, 21 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index ab146b5b68bd..4236ad751c2c 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1157,6 +1157,7 @@ struct intel_crtc_state { bool has_psr2; bool enable_psr2_sel_fetch; bool req_psr2_sdp_prior_scanline; + bool wm_level_disabled; u32 dc3co_exitline; u16 su_y_granularity; struct drm_dp_vsc_sdp psr_vsc; diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 770f6fea5499..98f48eb10c44 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1136,6 +1136,7 @@ static u32 wa_16013835468_bit_get(struct intel_dp *intel_dp) /* * Wa_16013835468 + * Wa_14015648006 */ static void wm_optimization_wa(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) @@ -1143,6 +1144,11 @@ static void wm_optimization_wa(struct intel_dp *intel_dp, struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); bool set_wa_bit = false; + /* Wa_14015648006 */ + if (IS_MTL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B0) || + IS_DISPLAY_VER(dev_priv, 11, 13)) + set_wa_bit |= crtc_state->wm_level_disabled; + /* Wa_16013835468 */ if (DISPLAY_VER(dev_priv) == 12) set_wa_bit |= crtc_state->hw.adjusted_mode.crtc_vblank_start != @@ -1197,6 +1203,7 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp, /* * Wa_16013835468 + * Wa_14015648006 */ wm_optimization_wa(intel_dp, crtc_state); @@ -1374,8 +1381,9 @@ static void intel_psr_disable_locked(struct intel_dp *intel_dp) /* * Wa_16013835468 + * Wa_14015648006 */ - if (DISPLAY_VER(dev_priv) == 12) + if (DISPLAY_VER(dev_priv) >= 11) intel_de_rmw(dev_priv, GEN8_CHICKEN_DCPR_1, wa_16013835468_bit_get(intel_dp), 0); @@ -1949,6 +1957,9 @@ void intel_psr_pre_plane_update(struct intel_atomic_state *state, if (psr->enabled && needs_to_disable) intel_psr_disable_locked(intel_dp); + else if (psr->enabled && new_crtc_state->wm_level_disabled) + /* Wa_14015648006 */ + wm_optimization_wa(intel_dp, new_crtc_state); mutex_unlock(&psr->lock); } @@ -1978,6 +1989,9 @@ static void _intel_psr_post_plane_update(const struct intel_atomic_state *state, if (!psr->enabled && !keep_disabled) intel_psr_enable_locked(intel_dp, crtc_state); + else if (psr->enabled && !crtc_state->wm_level_disabled) + /* Wa_14015648006 */ + wm_optimization_wa(intel_dp, crtc_state); /* Force a PSR exit when enabling CRC to avoid CRC timeouts */ if (crtc_state->crc_enabled && psr->enabled) diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index ff70225c0263..7e2e76afbf2a 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -2276,9 +2276,12 @@ static int skl_wm_check_vblank(struct intel_crtc_state *crtc_state) return level; /* - * FIXME PSR needs to toggle LATENCY_REPORTING_REMOVED_PIPE_* + * PSR needs to toggle LATENCY_REPORTING_REMOVED_PIPE_* * based on whether we're limited by the vblank duration. - * + */ + crtc_state->wm_level_disabled = level < i915->display.wm.num_levels - 1; + + /* * FIXME also related to skl+ w/a 1136 (also unimplemented as of * now) perhaps? */ -- cgit v1.2.3-59-g8ed1b From f389e7ac8d8a9a17bf59507d02ffb756c19b4af5 Mon Sep 17 00:00:00 2001 From: Jouni Högander Date: Wed, 29 Mar 2023 18:07:01 +0300 Subject: drm/i915/psr: Add helpers for block count number handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add helpers to make it more clear how PSR2_CTL[Block Count Number] is configured. Signed-off-by: Jouni Högander Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230329150703.432072-5-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 98f48eb10c44..07b0c016e78a 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -519,6 +519,17 @@ static u32 intel_psr2_get_tp_time(struct intel_dp *intel_dp) return val; } +static int psr2_block_count_lines(struct intel_dp *intel_dp) +{ + return intel_dp->psr.io_wake_lines < 9 && + intel_dp->psr.fast_wake_lines < 9 ? 8 : 12; +} + +static int psr2_block_count(struct intel_dp *intel_dp) +{ + return psr2_block_count_lines(intel_dp) / 4; +} + static void hsw_activate_psr2(struct intel_dp *intel_dp) { struct drm_i915_private *dev_priv = dp_to_i915(intel_dp); @@ -536,11 +547,10 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp) val |= intel_psr2_get_tp_time(intel_dp); if (DISPLAY_VER(dev_priv) >= 12) { - if (intel_dp->psr.io_wake_lines < 9 && - intel_dp->psr.fast_wake_lines < 9) - val |= TGL_EDP_PSR2_BLOCK_COUNT_NUM_2; - else + if (psr2_block_count(intel_dp) > 2) val |= TGL_EDP_PSR2_BLOCK_COUNT_NUM_3; + else + val |= TGL_EDP_PSR2_BLOCK_COUNT_NUM_2; } /* Wa_22012278275:adl-p */ -- cgit v1.2.3-59-g8ed1b From 8d18373a0ef91845781755492510e00b5a912a0a Mon Sep 17 00:00:00 2001 From: Jouni Högander Date: Wed, 29 Mar 2023 18:07:02 +0300 Subject: drm/i915/psr: Check that vblank is long enough for psr2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ensure vblank >= psr2 vblank where Psr2 vblank = PSR2_CTL Block Count Number maximum line count. Bspec: 71580, 49274 v2: Use calculated block count number maximum line count Signed-off-by: Jouni Högander Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230329150703.432072-6-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 07b0c016e78a..446c8acc265b 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -968,6 +968,15 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp, return false; } + /* Vblank >= PSR2_CTL Block Count Number maximum line count */ + if (crtc_state->hw.adjusted_mode.crtc_vblank_end - + crtc_state->hw.adjusted_mode.crtc_vblank_start < + psr2_block_count_lines(intel_dp)) { + drm_dbg_kms(&dev_priv->drm, + "PSR2 not enabled, too short vblank time\n"); + return false; + } + if (HAS_PSR2_SEL_FETCH(dev_priv)) { if (!intel_psr2_sel_fetch_config_valid(intel_dp, crtc_state) && !HAS_PSR_HW_TRACKING(dev_priv)) { -- cgit v1.2.3-59-g8ed1b From 1164c92b2d13648fb156fe547dd1273111f05e3d Mon Sep 17 00:00:00 2001 From: Jouni Högander Date: Wed, 29 Mar 2023 18:07:03 +0300 Subject: drm/i915/psr: Implement Display WA #1136 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement Display WA #1136 for Pre-ICL. Bspec: 21664 v2: Handle disable psr in pre/post plane hooks Signed-off-by: Jouni Högander Reviewed-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230329150703.432072-7-jouni.hogander@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 7 +++++++ drivers/gpu/drm/i915/display/skl_watermark.c | 5 ----- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 446c8acc265b..ecf1781c1556 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1968,11 +1968,14 @@ void intel_psr_pre_plane_update(struct intel_atomic_state *state, * - PSR disabled in new state * - All planes will go inactive * - Changing between PSR versions + * - Display WA #1136: skl, bxt */ needs_to_disable |= intel_crtc_needs_modeset(new_crtc_state); needs_to_disable |= !new_crtc_state->has_psr; needs_to_disable |= !new_crtc_state->active_planes; needs_to_disable |= new_crtc_state->has_psr2 != psr->psr2_enabled; + needs_to_disable |= DISPLAY_VER(i915) < 11 && + new_crtc_state->wm_level_disabled; if (psr->enabled && needs_to_disable) intel_psr_disable_locked(intel_dp); @@ -2006,6 +2009,10 @@ static void _intel_psr_post_plane_update(const struct intel_atomic_state *state, keep_disabled |= psr->sink_not_reliable; keep_disabled |= !crtc_state->active_planes; + /* Display WA #1136: skl, bxt */ + keep_disabled |= DISPLAY_VER(dev_priv) < 11 && + crtc_state->wm_level_disabled; + if (!psr->enabled && !keep_disabled) intel_psr_enable_locked(intel_dp, crtc_state); else if (psr->enabled && !crtc_state->wm_level_disabled) diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index 7e2e76afbf2a..5296a20d62d3 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -2281,11 +2281,6 @@ static int skl_wm_check_vblank(struct intel_crtc_state *crtc_state) */ crtc_state->wm_level_disabled = level < i915->display.wm.num_levels - 1; - /* - * FIXME also related to skl+ w/a 1136 (also unimplemented as of - * now) perhaps? - */ - for (level++; level < i915->display.wm.num_levels; level++) { enum plane_id plane_id; -- cgit v1.2.3-59-g8ed1b From bd80b0dd6a431aa23b70ff91b6905c1b1eed2f9c Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 29 Mar 2023 22:04:43 +0300 Subject: drm/i915: Skip cursor when writing PLANE_CHICKEN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cursor is not a universal plane and thus doesn't have the PLANE_CHICKEN register. Skip it. Fixes: c5de248484af ("drm/i915/dpt: Add a modparam to disable DPT via the chicken bit") Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230329190445.13456-1-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/display/intel_dpt.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c b/drivers/gpu/drm/i915/display/intel_dpt.c index 2bf5cce232d5..b8027392144d 100644 --- a/drivers/gpu/drm/i915/display/intel_dpt.c +++ b/drivers/gpu/drm/i915/display/intel_dpt.c @@ -324,10 +324,14 @@ void intel_dpt_configure(struct intel_crtc *crtc) enum pipe pipe = crtc->pipe; enum plane_id plane_id; - for_each_plane_id_on_crtc(crtc, plane_id) + for_each_plane_id_on_crtc(crtc, plane_id) { + if (plane_id == PLANE_CURSOR) + continue; + intel_de_rmw(i915, PLANE_CHICKEN(pipe, plane_id), PLANE_CHICKEN_DISABLE_DPT, i915->params.enable_dpt ? 0 : PLANE_CHICKEN_DISABLE_DPT); + } } else if (DISPLAY_VER(i915) == 13) { intel_de_rmw(i915, CHICKEN_MISC_2, CHICKEN_MISC_DISABLE_DPT, -- cgit v1.2.3-59-g8ed1b From 7732e289c557809a4a92a218abe04a5f658ea5c2 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 29 Mar 2023 22:04:44 +0300 Subject: drm/i915: Document that PLANE_CHICKEN are for tgl+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add tgl+ comments to the PLANE_CHICKEN registers which I apparently forgot to add when defining the registers. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230329190445.13456-2-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/i915_reg.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 2b8751178f8b..6d9c0e37e9b7 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4026,8 +4026,8 @@ #define PLANE_COLOR_ALPHA_DISABLE REG_FIELD_PREP(PLANE_COLOR_ALPHA_MASK, 0) #define PLANE_COLOR_ALPHA_SW_PREMULTIPLY REG_FIELD_PREP(PLANE_COLOR_ALPHA_MASK, 2) #define PLANE_COLOR_ALPHA_HW_PREMULTIPLY REG_FIELD_PREP(PLANE_COLOR_ALPHA_MASK, 3) -#define _PLANE_CHICKEN_1_A 0x7026C -#define _PLANE_CHICKEN_2_A 0x7036C +#define _PLANE_CHICKEN_1_A 0x7026C /* tgl+ */ +#define _PLANE_CHICKEN_2_A 0x7036C /* tgl+ */ #define PLANE_CHICKEN_DISABLE_DPT REG_BIT(19) /* mtl+ */ #define _PLANE_BUF_CFG_1_A 0x7027c #define _PLANE_BUF_CFG_2_A 0x7037c -- cgit v1.2.3-59-g8ed1b From 1119f009005ea89dafac298aeb3231cf2cf2a9ef Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 29 Mar 2023 22:04:45 +0300 Subject: drm/i915: Define cursor chicken reg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Define CUR_CHICKEN so we don't have to remember the offset. Looks like it's getting introduced in mtl. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230329190445.13456-3-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak --- drivers/gpu/drm/i915/i915_reg.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 6d9c0e37e9b7..a350ee2288f2 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3360,6 +3360,7 @@ #define CUR_FBC_EN REG_BIT(31) #define CUR_FBC_HEIGHT_MASK REG_GENMASK(7, 0) #define CUR_FBC_HEIGHT(h) REG_FIELD_PREP(CUR_FBC_HEIGHT_MASK, (h)) +#define _CUR_CHICKEN_A 0x700a4 /* mtl+ */ #define _CURASURFLIVE 0x700ac /* g4x+ */ #define _CURBCNTR 0x700c0 #define _CURBBASE 0x700c4 @@ -3374,6 +3375,7 @@ #define CURPOS(pipe) _MMIO_CURSOR2(pipe, _CURAPOS) #define CURSIZE(pipe) _MMIO_CURSOR2(pipe, _CURASIZE) #define CUR_FBC_CTL(pipe) _MMIO_CURSOR2(pipe, _CUR_FBC_CTL_A) +#define CUR_CHICKEN(pipe) _MMIO_CURSOR2(pipe, _CUR_CHICKEN_A) #define CURSURFLIVE(pipe) _MMIO_CURSOR2(pipe, _CURASURFLIVE) #define CURSOR_A_OFFSET 0x70080 -- cgit v1.2.3-59-g8ed1b From 5011f2915b70703a0347f97b8f2ca0b56ab49978 Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Thu, 9 Mar 2023 11:58:50 +0530 Subject: drm/i915/dp: Check if DSC supports the given output_format Go with DSC only if the given output_format is supported. v2: Use drm helper to get DSC format support for sink. v3: remove drm_dp_dsc_compute_bpp. Cc: Uma Shankar Signed-off-by: Ankit Nautiyal Reviewed-by: Uma Shankar Signed-off-by: Uma Shankar Link: https://patchwork.freedesktop.org/patch/msgid/20230309062855.393087-3-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_dp.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index da1c00ee92fb..777d10aedbb1 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1515,6 +1515,31 @@ static int intel_dp_dsc_compute_params(struct intel_encoder *encoder, return drm_dsc_compute_rc_parameters(vdsc_cfg); } +static bool intel_dp_dsc_supports_format(struct intel_dp *intel_dp, + enum intel_output_format output_format) +{ + u8 sink_dsc_format; + + switch (output_format) { + case INTEL_OUTPUT_FORMAT_RGB: + sink_dsc_format = DP_DSC_RGB; + break; + case INTEL_OUTPUT_FORMAT_YCBCR444: + sink_dsc_format = DP_DSC_YCbCr444; + break; + case INTEL_OUTPUT_FORMAT_YCBCR420: + if (min(intel_dp_source_dsc_version_minor(intel_dp), + intel_dp_sink_dsc_version_minor(intel_dp)) < 2) + return false; + sink_dsc_format = DP_DSC_YCbCr420_Native; + break; + default: + return false; + } + + return drm_dp_dsc_sink_supports_format(intel_dp->dsc_dpcd, sink_dsc_format); +} + int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *pipe_config, struct drm_connector_state *conn_state, @@ -1535,6 +1560,9 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, if (!intel_dp_supports_dsc(intel_dp, pipe_config)) return -EINVAL; + if (!intel_dp_dsc_supports_format(intel_dp, pipe_config->output_format)) + return -EINVAL; + if (compute_pipe_bpp) pipe_bpp = intel_dp_dsc_compute_bpp(intel_dp, conn_state->max_requested_bpc); else -- cgit v1.2.3-59-g8ed1b From ac754358c68214f9945bdf9cc565fa18ce1b0185 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Thu, 9 Mar 2023 11:58:51 +0530 Subject: drm/i915/dsc: Adding the new registers for DSC Adding new DSC register which are introducted MTL onwards Signed-off-by: Suraj Kandpal Reviewed-by: Vandita Kulkarni Reviewed-by: Uma Shankar Signed-off-by: Uma Shankar Link: https://patchwork.freedesktop.org/patch/msgid/20230309062855.393087-4-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_vdsc_regs.h | 28 ++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_vdsc_regs.h b/drivers/gpu/drm/i915/display/intel_vdsc_regs.h index 4fd883463752..b71f00b5c761 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc_regs.h +++ b/drivers/gpu/drm/i915/display/intel_vdsc_regs.h @@ -46,6 +46,32 @@ _ICL_PIPE_DSS_CTL2_PB, \ _ICL_PIPE_DSS_CTL2_PC) +/* MTL Display Stream Compression registers */ +#define _MTL_DSC0_PICTURE_PARAMETER_SET_17_PB 0x782B4 +#define _MTL_DSC1_PICTURE_PARAMETER_SET_17_PB 0x783B4 +#define _MTL_DSC0_PICTURE_PARAMETER_SET_17_PC 0x784B4 +#define _MTL_DSC1_PICTURE_PARAMETER_SET_17_PC 0x785B4 +#define MTL_DSC0_PICTURE_PARAMETER_SET_17(pipe) _MMIO_PIPE((pipe) - PIPE_B, \ + _MTL_DSC0_PICTURE_PARAMETER_SET_17_PB, \ + _MTL_DSC0_PICTURE_PARAMETER_SET_17_PC) +#define MTL_DSC1_PICTURE_PARAMETER_SET_17(pipe) _MMIO_PIPE((pipe) - PIPE_B, \ + _MTL_DSC1_PICTURE_PARAMETER_SET_17_PB, \ + _MTL_DSC1_PICTURE_PARAMETER_SET_17_PC) +#define DSC_SL_BPG_OFFSET(offset) ((offset) << 27) + +#define _MTL_DSC0_PICTURE_PARAMETER_SET_18_PB 0x782B8 +#define _MTL_DSC1_PICTURE_PARAMETER_SET_18_PB 0x783B8 +#define _MTL_DSC0_PICTURE_PARAMETER_SET_18_PC 0x784B8 +#define _MTL_DSC1_PICTURE_PARAMETER_SET_18_PC 0x785B8 +#define MTL_DSC0_PICTURE_PARAMETER_SET_18(pipe) _MMIO_PIPE((pipe) - PIPE_B, \ + _MTL_DSC0_PICTURE_PARAMETER_SET_18_PB, \ + _MTL_DSC0_PICTURE_PARAMETER_SET_18_PC) +#define MTL_DSC1_PICTURE_PARAMETER_SET_18(pipe) _MMIO_PIPE((pipe) - PIPE_B, \ + _MTL_DSC1_PICTURE_PARAMETER_SET_18_PB, \ + _MTL_DSC1_PICTURE_PARAMETER_SET_18_PC) +#define DSC_NSL_BPG_OFFSET(offset) ((offset) << 16) +#define DSC_SL_OFFSET_ADJ(offset) ((offset) << 0) + /* Icelake Display Stream Compression Registers */ #define DSCA_PICTURE_PARAMETER_SET_0 _MMIO(0x6B200) #define DSCC_PICTURE_PARAMETER_SET_0 _MMIO(0x6BA00) @@ -59,6 +85,8 @@ #define ICL_DSC1_PICTURE_PARAMETER_SET_0(pipe) _MMIO_PIPE((pipe) - PIPE_B, \ _ICL_DSC1_PICTURE_PARAMETER_SET_0_PB, \ _ICL_DSC1_PICTURE_PARAMETER_SET_0_PC) +#define DSC_NATIVE_422_ENABLE BIT(23) +#define DSC_NATIVE_420_ENABLE BIT(22) #define DSC_ALT_ICH_SEL (1 << 20) #define DSC_VBR_ENABLE (1 << 19) #define DSC_422_ENABLE (1 << 18) -- cgit v1.2.3-59-g8ed1b From dd4d6791eb0164ba59d3e105135188c355d80fa2 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Thu, 9 Mar 2023 11:58:52 +0530 Subject: drm/i915/dsc: Enable YCbCr420 for VDSC Implementation of VDSC for YCbCr420. Add QP tables for 8,10,12 BPC from rc_tables.h in intel_qp_tables.c (Derived from C-Model, which is given along with DSC1.2a Spec from Vesa) intel_lookup_range_min/max_qp functons need to take into account the output format. Based on that appropriate qp table need to be chosen. Other rc_parameters need to be set where currently values for 444 format is hardcoded in calculate_rc_parameters( ). vdsc_cfg struct needs to be filled with output format information, where these are hardcoded for 444 format. Bspec: 49259 Signed-off-by: Suraj Kandpal Reviewed-by: Vandita Kulkarni Reviewed-by: Uma Shankar Signed-off-by: Uma Shankar Link: https://patchwork.freedesktop.org/patch/msgid/20230309062855.393087-5-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_qp_tables.c | 187 +++++++++++++++++++++++-- drivers/gpu/drm/i915/display/intel_qp_tables.h | 4 +- drivers/gpu/drm/i915/display/intel_vdsc.c | 4 +- 3 files changed, 180 insertions(+), 15 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_qp_tables.c b/drivers/gpu/drm/i915/display/intel_qp_tables.c index 6f8e4ec5c0fb..6e86c0971d24 100644 --- a/drivers/gpu/drm/i915/display/intel_qp_tables.c +++ b/drivers/gpu/drm/i915/display/intel_qp_tables.c @@ -17,6 +17,15 @@ /* from BPP 6 to 36 in steps of 0.5 */ #define RC_RANGE_QP444_12BPC_MAX_NUM_BPP 61 +/* from BPP 6 to 24 in steps of 0.5 */ +#define RC_RANGE_QP420_8BPC_MAX_NUM_BPP 17 + +/* from BPP 6 to 30 in steps of 0.5 */ +#define RC_RANGE_QP420_10BPC_MAX_NUM_BPP 23 + +/* from BPP 6 to 36 in steps of 0.5 */ +#define RC_RANGE_QP420_12BPC_MAX_NUM_BPP 29 + /* * These qp tables are as per the C model * and it has the rows pointing to bpps which increment @@ -283,26 +292,182 @@ static const u8 rc_range_maxqp444_12bpc[DSC_NUM_BUF_RANGES][RC_RANGE_QP444_12BPC 11, 11, 10, 10, 10, 10, 10, 9, 9, 8, 8, 8, 8, 8, 7, 7, 6, 6, 6, 6, 5, 5, 4 } }; -#define PARAM_TABLE(_minmax, _bpc, _row, _col) do { \ - if (bpc == (_bpc)) \ - return rc_range_##_minmax##qp444_##_bpc##bpc[_row][_col]; \ +static const u8 rc_range_minqp420_8bpc[DSC_NUM_BUF_RANGES][RC_RANGE_QP420_8BPC_MAX_NUM_BPP] = { + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 3, 3, 3, 3, 3, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 }, + { 3, 3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 }, + { 3, 3, 3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, + { 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 0 }, + { 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 0 }, + { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 1, 1 }, + { 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 3, 3, 3, 3, 2, 1, 1 }, + { 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 3, 2, 2, 1 }, + { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 3, 3, 2, 1 }, + { 9, 8, 8, 7, 7, 7, 7, 7, 7, 6, 5, 5, 4, 3, 3, 3, 2 }, + { 13, 12, 12, 11, 10, 10, 9, 8, 8, 7, 6, 6, 5, 5, 4, 4, 3 } +}; + +static const u8 rc_range_maxqp420_8bpc[DSC_NUM_BUF_RANGES][RC_RANGE_QP420_8BPC_MAX_NUM_BPP] = { + { 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 4, 4, 4, 4, 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0 }, + { 5, 5, 5, 5, 5, 4, 3, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0 }, + { 6, 6, 6, 6, 6, 5, 4, 3, 2, 2, 2, 1, 1, 1, 1, 0, 0 }, + { 7, 7, 7, 7, 7, 5, 4, 3, 2, 2, 2, 2, 2, 1, 1, 1, 0 }, + { 7, 7, 7, 7, 7, 6, 5, 4, 3, 3, 3, 2, 2, 2, 1, 1, 0 }, + { 7, 7, 7, 7, 7, 6, 5, 4, 3, 3, 3, 3, 2, 2, 2, 1, 1 }, + { 8, 8, 8, 8, 8, 7, 6, 5, 4, 4, 4, 3, 3, 2, 2, 2, 1 }, + { 9, 9, 9, 8, 8, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1 }, + { 10, 10, 9, 9, 9, 8, 7, 6, 5, 5, 5, 4, 4, 3, 3, 2, 2 }, + { 10, 10, 10, 9, 9, 8, 8, 7, 6, 6, 5, 5, 4, 4, 3, 2, 2 }, + { 11, 11, 10, 10, 9, 9, 8, 7, 7, 6, 6, 5, 5, 4, 3, 3, 2 }, + { 11, 11, 11, 10, 9, 9, 9, 8, 7, 7, 6, 5, 5, 4, 4, 3, 2 }, + { 13, 12, 12, 11, 10, 10, 9, 8, 8, 7, 6, 6, 5, 4, 4, 4, 3 }, + { 14, 13, 13, 12, 11, 11, 10, 9, 9, 8, 7, 7, 6, 6, 5, 5, 4 } +}; + +static const u8 rc_range_minqp420_10bpc[DSC_NUM_BUF_RANGES][RC_RANGE_QP420_10BPC_MAX_NUM_BPP] = { + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 4, 4, 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 4, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 5, 5, 5, 4, 4, 4, 4, 4, 4, 3, 3, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0 }, + { 7, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0 }, + { 7, 7, 7, 7, 7, 6, 5, 5, 5, 5, 5, 4, 3, 3, 2, 2, 1, 1, 1, 1, 1, 0, 0 }, + { 7, 7, 7, 7, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 3, 2, 2, 2, 2, 1, 1, 1, 0 }, + { 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 5, 4, 4, 4, 3, 2, 2, 2, 1, 1, 1, 0 }, + { 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 2, 1, 1 }, + { 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1 }, + { 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1 }, + { 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 7, 6, 6, 5, 4, 4, 3, 3, 2, 1 }, + { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 7, 7, 6, 5, 4, 4, 3, 3, 2, 1 }, + { 13, 12, 12, 11, 11, 11, 11, 11, 11, 10, 9, 9, 8, 7, 7, 6, 5, 5, 4, 3, 3, + 2, 2 }, + { 17, 16, 16, 15, 14, 14, 13, 12, 12, 11, 10, 10, 10, 9, 8, 8, 7, 6, 6, 5, + 5, 4, 4 } +}; + +static const u8 rc_range_maxqp420_10bpc[DSC_NUM_BUF_RANGES][RC_RANGE_QP420_10BPC_MAX_NUM_BPP] = { + { 8, 8, 7, 6, 4, 4, 3, 3, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 8, 8, 8, 7, 6, 5, 4, 4, 3, 3, 3, 3, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }, + { 9, 9, 9, 8, 8, 7, 6, 5, 4, 3, 3, 3, 3, 3, 2, 1, 1, 1, 0, 0, 0, 0, 0 }, + { 10, 10, 10, 9, 9, 8, 7, 6, 5, 4, 4, 3, 3, 3, 3, 2, 1, 1, 1, 1, 1, 0, + 0 }, + { 11, 11, 11, 10, 10, 8, 7, 6, 5, 4, 4, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1, + 0 }, + { 11, 11, 11, 10, 10, 9, 8, 7, 6, 6, 6, 5, 4, 4, 3, 3, 2, 2, 2, 2, 2, 1, + 1 }, + { 11, 11, 11, 11, 11, 10, 9, 8, 7, 7, 7, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, + 1 }, + { 12, 12, 12, 12, 12, 11, 10, 9, 8, 8, 8, 7, 6, 5, 5, 4, 3, 3, 3, 2, 2, + 2, 1 }, + { 13, 13, 13, 12, 12, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 5, 4, 4, 3, 3, 3, + 2, 2 }, + { 14, 14, 13, 13, 13, 12, 11, 10, 9, 9, 9, 8, 8, 7, 7, 6, 5, 4, 4, 3, 3, + 2, 2 }, + { 14, 14, 14, 13, 13, 12, 12, 11, 10, 10, 9, 9, 8, 8, 7, 6, 5, 5, 4, 4, + 3, 3, 2 }, + { 15, 15, 14, 14, 13, 13, 12, 11, 11, 10, 10, 9, 9, 8, 7, 7, 6, 5, 5, 4, + 4, 3, 2 }, + { 15, 15, 15, 14, 13, 13, 13, 12, 11, 11, 10, 9, 9, 8, 8, 7, 6, 5, 5, 4, + 4, 3, 2 }, + { 17, 16, 16, 15, 14, 14, 13, 12, 12, 11, 10, 10, 9, 8, 8, 7, 6, 6, 5, 4, + 4, 3, 3 }, + { 18, 17, 17, 16, 15, 15, 14, 13, 13, 12, 11, 11, 11, 10, 9, 9, 8, 7, 7, + 6, 6, 5, 5 } +}; + +static const u8 rc_range_minqp420_12bpc[DSC_NUM_BUF_RANGES][RC_RANGE_QP420_12BPC_MAX_NUM_BPP] = { + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 }, + { 4, 4, 4, 4, 4, 4, 3, 3, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 }, + { 9, 8, 8, 7, 7, 6, 5, 5, 4, 4, 4, 4, 3, 3, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 }, + { 10, 9, 9, 8, 8, 8, 7, 7, 6, 6, 6, 5, 5, 4, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0 }, + { 11, 10, 10, 10, 10, 9, 9, 8, 7, 6, 6, 6, 6, 5, 5, 4, 3, 3, 3, 2, 2, 1, + 0, 0, 0, 0, 0, 0, 0 }, + { 11, 11, 11, 11, 11, 10, 10, 9, 9, 9, 9, 8, 7, 6, 5, 5, 4, 4, 3, 3, 3, 2, + 1, 1, 0, 0, 0, 0, 0 }, + { 11, 11, 11, 11, 11, 11, 10, 10, 9, 9, 9, 8, 8, 7, 6, 5, 5, 5, 5, 4, 3, 3, + 2, 1, 1, 1, 1, 1, 0 }, + { 11, 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 9, 8, 8, 8, 7, 6, 6, 5, 4, 4, + 3, 2, 2, 1, 1, 1, 1, 1 }, + { 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, 5, + 5, 4, 4, 2, 2, 1, 1, 1, 1 }, + { 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, 6, + 5, 4, 4, 3, 2, 2, 1, 1, 1 }, + { 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8, 7, 7, + 6, 5, 4, 3, 3, 2, 2, 1, 1 }, + { 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 11, 10, 10, 9, 8, 8, + 7, 7, 6, 5, 4, 3, 3, 2, 2, 1 }, + { 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 11, 11, 10, 9, 8, 8, + 7, 7, 6, 5, 4, 4, 3, 2, 2, 1 }, + { 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 13, 13, 12, 11, 11, 10, 9, 9, 8, + 8, 7, 6, 6, 5, 4, 4, 3, 3, 2 }, + { 21, 20, 20, 19, 18, 18, 17, 16, 16, 15, 14, 14, 14, 13, 12, 12, 11, 10, + 10, 10, 9, 8, 8, 7, 6, 6, 5, 5, 4 } +}; + +static const u8 rc_range_maxqp420_12bpc[DSC_NUM_BUF_RANGES][RC_RANGE_QP420_12BPC_MAX_NUM_BPP] = { + { 11, 10, 9, 8, 6, 6, 5, 5, 4, 3, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0 }, + { 12, 11, 11, 10, 9, 8, 7, 7, 6, 6, 5, 5, 4, 3, 3, 2, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0 }, + { 13, 12, 12, 11, 11, 10, 9, 8, 7, 6, 6, 6, 5, 5, 4, 3, 3, 2, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0 }, + { 14, 13, 13, 12, 12, 11, 10, 9, 8, 7, 7, 6, 6, 5, 5, 4, 3, 3, 2, 2, 2, 1, + 1, 1, 0, 0, 0, 0, 0 }, + { 15, 14, 14, 13, 13, 11, 10, 9, 8, 7, 7, 7, 7, 6, 6, 5, 4, 4, 4, 3, 3, 2, + 1, 1, 1, 0, 0, 0, 0 }, + { 15, 15, 15, 14, 14, 13, 12, 11, 10, 10, 10, 9, 8, 7, 6, 6, 5, 5, 4, 4, + 4, 3, 2, 2, 1, 1, 0, 0, 0 }, + { 15, 15, 15, 15, 15, 14, 13, 12, 11, 11, 11, 10, 9, 8, 7, 6, 6, 6, 6, 5, + 4, 4, 3, 2, 2, 2, 1, 1, 0 }, + { 16, 16, 16, 16, 16, 15, 14, 13, 12, 12, 12, 11, 10, 9, 9, 8, 7, 7, 6, 5, + 5, 4, 3, 3, 2, 2, 2, 1, 1 }, + { 17, 17, 17, 16, 16, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 9, 8, 8, 7, + 6, 6, 5, 5, 3, 3, 2, 2, 1, 1 }, + { 18, 18, 17, 17, 17, 16, 15, 14, 13, 13, 13, 12, 12, 11, 11, 10, 9, 8, 8, + 7, 6, 5, 5, 4, 3, 3, 2, 2, 1 }, + { 18, 18, 18, 17, 17, 16, 16, 15, 14, 14, 13, 13, 12, 12, 11, 10, 9, 9, 8, + 8, 7, 6, 5, 4, 4, 3, 3, 2, 2 }, + { 19, 19, 18, 18, 17, 17, 16, 15, 15, 14, 14, 13, 13, 12, 11, 11, 10, 9, + 9, 8, 8, 7, 6, 5, 4, 4, 3, 3, 2 }, + { 19, 19, 19, 18, 17, 17, 17, 16, 15, 15, 14, 13, 13, 12, 12, 11, 10, 9, + 9, 8, 8, 7, 6, 5, 5, 4, 3, 3, 2 }, + { 21, 20, 20, 19, 18, 18, 17, 16, 16, 15, 14, 14, 13, 12, 12, 11, 10, 10, + 9, 9, 8, 7, 7, 6, 5, 5, 4, 4, 3 }, + { 22, 21, 21, 20, 19, 19, 18, 17, 17, 16, 15, 15, 15, 14, 13, 13, 12, 11, + 11, 11, 10, 9, 9, 8, 7, 7, 6, 6, 5 } +}; + +#define PARAM_TABLE(_minmax, _bpc, _row, _col, _is_420) do { \ + if (bpc == (_bpc)) { \ + if (_is_420) \ + return rc_range_##_minmax##qp420_##_bpc##bpc[_row][_col]; \ + else \ + return rc_range_##_minmax##qp444_##_bpc##bpc[_row][_col]; \ + } \ } while (0) -u8 intel_lookup_range_min_qp(int bpc, int buf_i, int bpp_i) +u8 intel_lookup_range_min_qp(int bpc, int buf_i, int bpp_i, bool is_420) { - PARAM_TABLE(min, 8, buf_i, bpp_i); - PARAM_TABLE(min, 10, buf_i, bpp_i); - PARAM_TABLE(min, 12, buf_i, bpp_i); + PARAM_TABLE(min, 8, buf_i, bpp_i, is_420); + PARAM_TABLE(min, 10, buf_i, bpp_i, is_420); + PARAM_TABLE(min, 12, buf_i, bpp_i, is_420); MISSING_CASE(bpc); return 0; } -u8 intel_lookup_range_max_qp(int bpc, int buf_i, int bpp_i) +u8 intel_lookup_range_max_qp(int bpc, int buf_i, int bpp_i, bool is_420) { - PARAM_TABLE(max, 8, buf_i, bpp_i); - PARAM_TABLE(max, 10, buf_i, bpp_i); - PARAM_TABLE(max, 12, buf_i, bpp_i); + PARAM_TABLE(max, 8, buf_i, bpp_i, is_420); + PARAM_TABLE(max, 10, buf_i, bpp_i, is_420); + PARAM_TABLE(max, 12, buf_i, bpp_i, is_420); MISSING_CASE(bpc); return 0; diff --git a/drivers/gpu/drm/i915/display/intel_qp_tables.h b/drivers/gpu/drm/i915/display/intel_qp_tables.h index 9fb3c36bd7c6..a9ff9ca29938 100644 --- a/drivers/gpu/drm/i915/display/intel_qp_tables.h +++ b/drivers/gpu/drm/i915/display/intel_qp_tables.h @@ -8,7 +8,7 @@ #include -u8 intel_lookup_range_min_qp(int bpc, int buf_i, int bpp_i); -u8 intel_lookup_range_max_qp(int bpc, int buf_i, int bpp_i); +u8 intel_lookup_range_min_qp(int bpc, int buf_i, int bpp_i, bool is_420); +u8 intel_lookup_range_max_qp(int bpc, int buf_i, int bpp_i, bool is_420); #endif diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c index 09b32ffdc552..6fa70f3c074b 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc.c +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c @@ -423,9 +423,9 @@ calculate_rc_params(struct rc_parameters *rc, for (buf_i = 0; buf_i < DSC_NUM_BUF_RANGES; buf_i++) { /* Read range_minqp and range_max_qp from qp tables */ rc->rc_range_params[buf_i].range_min_qp = - intel_lookup_range_min_qp(bpc, buf_i, bpp_i); + intel_lookup_range_min_qp(bpc, buf_i, bpp_i, vdsc_cfg->native_420); rc->rc_range_params[buf_i].range_max_qp = - intel_lookup_range_max_qp(bpc, buf_i, bpp_i); + intel_lookup_range_max_qp(bpc, buf_i, bpp_i, vdsc_cfg->native_420); /* Calculate range_bgp_offset */ if (bpp <= 6) { -- cgit v1.2.3-59-g8ed1b From 9aeabe1988551f797f6e0cba0e7c2d4549cc3a4b Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Thu, 9 Mar 2023 11:58:53 +0530 Subject: drm/i915/dsc: Fill in native_420 field Now that we have laid the groundwork for YUV420 Enablement we fill up native_420 field in vdsc_cfg and add appropriate checks wherever required. ---v2 -adding native_422 field as 0 [Vandita] -filling in second_line_bpg_offset, second_line_offset_adj and nsl_bpg_offset in vds_cfg when native_420 is true ---v3 -adding display version check to solve igt issue --v7 -remove is_pipe_dsc check as its always true for D14 [Jani] --v10 -keep sink capability check [Jani] -move from !(x == y || w == z) to x !=y && w != z [Jani] --v11 -avoid native_420 computation if not gen14 [Uma] --v12 -fix state mismatch issue of compressed_bpp Cc: Uma Shankar Cc: Jani Nikula Signed-off-by: Suraj Kandpal Reviewed-by: Uma Shankar Signed-off-by: Uma Shankar Link: https://patchwork.freedesktop.org/patch/msgid/20230309062855.393087-6-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/icl_dsi.c | 2 - drivers/gpu/drm/i915/display/intel_dp.c | 16 ++++- drivers/gpu/drm/i915/display/intel_vdsc.c | 98 +++++++++++++++++++++++++++---- 3 files changed, 100 insertions(+), 16 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index 4ff10b00ffbd..ad78148e0788 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -1552,8 +1552,6 @@ static int gen11_dsi_dsc_compute_config(struct intel_encoder *encoder, if (crtc_state->dsc.slice_count > 1) crtc_state->dsc.dsc_split = true; - vdsc_cfg->convert_rgb = true; - /* FIXME: initialize from VBT */ vdsc_cfg->rc_model_size = DSC_RC_MODEL_SIZE_CONST; diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 777d10aedbb1..4a909087ea49 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -1490,9 +1490,10 @@ static int intel_dp_dsc_compute_params(struct intel_encoder *encoder, vdsc_cfg->dsc_version_minor = min(intel_dp_source_dsc_version_minor(intel_dp), intel_dp_sink_dsc_version_minor(intel_dp)); - - vdsc_cfg->convert_rgb = intel_dp->dsc_dpcd[DP_DSC_DEC_COLOR_FORMAT_CAP - DP_DSC_SUPPORT] & - DP_DSC_RGB; + if (vdsc_cfg->convert_rgb) + vdsc_cfg->convert_rgb = + intel_dp->dsc_dpcd[DP_DSC_DEC_COLOR_FORMAT_CAP - DP_DSC_SUPPORT] & + DP_DSC_RGB; line_buf_depth = drm_dp_dsc_sink_line_buf_depth(intel_dp->dsc_dpcd); if (!line_buf_depth) { @@ -1610,6 +1611,15 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp, pipe_config->bigjoiner_pipes, pipe_bpp, timeslots); + /* + * According to DSC 1.2a Section 4.1.1 Table 4.1 the maximum + * supported PPS value can be 63.9375 and with the further + * mention that bpp should be programmed double the target bpp + * restricting our target bpp to be 31.9375 at max + */ + if (pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) + dsc_max_output_bpp = min_t(u16, dsc_max_output_bpp, 31 << 4); + if (!dsc_max_output_bpp) { drm_dbg_kms(&dev_priv->drm, "Compressed BPP not supported\n"); diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c index 6fa70f3c074b..0388efb49b92 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc.c +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c @@ -461,14 +461,50 @@ int intel_dsc_compute_params(struct intel_crtc_state *pipe_config) vdsc_cfg->pic_width = pipe_config->hw.adjusted_mode.crtc_hdisplay; vdsc_cfg->slice_width = DIV_ROUND_UP(vdsc_cfg->pic_width, pipe_config->dsc.slice_count); - - /* Gen 11 does not support YCbCr */ + /* + * According to DSC 1.2 specs if colorspace is YCbCr then convert_rgb is 0 + * else 1 + */ + vdsc_cfg->convert_rgb = pipe_config->output_format != INTEL_OUTPUT_FORMAT_YCBCR420 && + pipe_config->output_format != INTEL_OUTPUT_FORMAT_YCBCR444; + + if (DISPLAY_VER(dev_priv) >= 14 && + pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) + vdsc_cfg->native_420 = true; + /* We do not support YcBCr422 as of now */ + vdsc_cfg->native_422 = false; vdsc_cfg->simple_422 = false; /* Gen 11 does not support VBR */ vdsc_cfg->vbr_enable = false; /* Gen 11 only supports integral values of bpp */ vdsc_cfg->bits_per_pixel = compressed_bpp << 4; + + /* + * According to DSC 1.2 specs in Section 4.1 if native_420 is set: + * -We need to double the current bpp. + * -second_line_bpg_offset is 12 in general and equal to 2*(slice_height-1) if slice + * height < 8. + * -second_line_offset_adj is 512 as shown by emperical values to yeild best chroma + * preservation in second line. + * -nsl_bpg_offset is calculated as second_line_offset/slice_height -1 then rounded + * up to 16 fractional bits, we left shift second line offset by 11 to preserve 11 + * fractional bits. + */ + if (vdsc_cfg->native_420) { + vdsc_cfg->bits_per_pixel <<= 1; + + if (vdsc_cfg->slice_height >= 8) + vdsc_cfg->second_line_bpg_offset = 12; + else + vdsc_cfg->second_line_bpg_offset = + 2 * (vdsc_cfg->slice_height - 1); + + vdsc_cfg->second_line_offset_adj = 512; + vdsc_cfg->nsl_bpg_offset = DIV_ROUND_UP(vdsc_cfg->second_line_bpg_offset << 11, + vdsc_cfg->slice_height - 1); + } + vdsc_cfg->bits_per_component = pipe_config->pipe_bpp / 3; for (i = 0; i < DSC_NUM_BUF_RANGES - 1; i++) { @@ -595,8 +631,13 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state) DSC_VER_MIN_SHIFT | vdsc_cfg->bits_per_component << DSC_BPC_SHIFT | vdsc_cfg->line_buf_depth << DSC_LINE_BUF_DEPTH_SHIFT; - if (vdsc_cfg->dsc_version_minor == 2) + if (vdsc_cfg->dsc_version_minor == 2) { pps_val |= DSC_ALT_ICH_SEL; + if (vdsc_cfg->native_420) + pps_val |= DSC_NATIVE_420_ENABLE; + if (vdsc_cfg->native_422) + pps_val |= DSC_NATIVE_422_ENABLE; + } if (vdsc_cfg->block_pred_enable) pps_val |= DSC_BLOCK_PREDICTION; if (vdsc_cfg->convert_rgb) @@ -907,6 +948,33 @@ static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state) pps_val); } + if (DISPLAY_VER(dev_priv) >= 14) { + /* Populate PICTURE_PARAMETER_SET_17 registers */ + pps_val = 0; + pps_val |= DSC_SL_BPG_OFFSET(vdsc_cfg->second_line_bpg_offset); + drm_dbg_kms(&dev_priv->drm, "PPS17 = 0x%08x\n", pps_val); + intel_de_write(dev_priv, + MTL_DSC0_PICTURE_PARAMETER_SET_17(pipe), + pps_val); + if (crtc_state->dsc.dsc_split) + intel_de_write(dev_priv, + MTL_DSC1_PICTURE_PARAMETER_SET_17(pipe), + pps_val); + + /* Populate PICTURE_PARAMETER_SET_18 registers */ + pps_val = 0; + pps_val |= DSC_NSL_BPG_OFFSET(vdsc_cfg->nsl_bpg_offset) | + DSC_SL_OFFSET_ADJ(vdsc_cfg->second_line_offset_adj); + drm_dbg_kms(&dev_priv->drm, "PPS18 = 0x%08x\n", pps_val); + intel_de_write(dev_priv, + MTL_DSC0_PICTURE_PARAMETER_SET_18(pipe), + pps_val); + if (crtc_state->dsc.dsc_split) + intel_de_write(dev_priv, + MTL_DSC1_PICTURE_PARAMETER_SET_18(pipe), + pps_val); + } + /* Populate the RC_BUF_THRESH registers */ memset(rc_buf_thresh_dword, 0, sizeof(rc_buf_thresh_dword)); for (i = 0; i < DSC_NUM_BUF_RANGES - 1; i++) { @@ -1181,7 +1249,7 @@ void intel_dsc_get_config(struct intel_crtc_state *crtc_state) enum pipe pipe = crtc->pipe; enum intel_display_power_domain power_domain; intel_wakeref_t wakeref; - u32 dss_ctl1, dss_ctl2, val; + u32 dss_ctl1, dss_ctl2, pps0 = 0, pps1 = 0; if (!intel_dsc_source_support(crtc_state)) return; @@ -1204,13 +1272,21 @@ void intel_dsc_get_config(struct intel_crtc_state *crtc_state) /* FIXME: add more state readout as needed */ - /* PPS1 */ - if (!is_pipe_dsc(crtc, cpu_transcoder)) - val = intel_de_read(dev_priv, DSCA_PICTURE_PARAMETER_SET_1); - else - val = intel_de_read(dev_priv, - ICL_DSC0_PICTURE_PARAMETER_SET_1(pipe)); - vdsc_cfg->bits_per_pixel = val; + /* PPS0 & PPS1 */ + if (!is_pipe_dsc(crtc, cpu_transcoder)) { + pps1 = intel_de_read(dev_priv, DSCA_PICTURE_PARAMETER_SET_1); + } else { + pps0 = intel_de_read(dev_priv, + ICL_DSC0_PICTURE_PARAMETER_SET_0(pipe)); + pps1 = intel_de_read(dev_priv, + ICL_DSC0_PICTURE_PARAMETER_SET_1(pipe)); + } + + vdsc_cfg->bits_per_pixel = pps1; + + if (pps0 & DSC_NATIVE_420_ENABLE) + vdsc_cfg->bits_per_pixel >>= 1; + crtc_state->dsc.compressed_bpp = vdsc_cfg->bits_per_pixel >> 4; out: intel_display_power_put(dev_priv, power_domain, wakeref); -- cgit v1.2.3-59-g8ed1b From 16e7a0db6ec9426fea36313b95c36624d983258b Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Thu, 9 Mar 2023 11:58:54 +0530 Subject: drm/i915/vdsc: Check slice design requirement Add function to check if slice design requirements are being met as defined in Bspec: 49259 in the section Slice Design Requirement --v7 -remove full bspec link [Jani] -rename intel_dsc_check_slice_design_req to intel_dsc_slice_dimensions_valid [Jani] --v8 -fix condition to check if slice width and height are of two -fix minimum pixel in slice condition --v10 -condition should be < rather then >= [Uma] Cc: Uma Shankar Signed-off-by: Suraj Kandpal Reviewed-by: Uma Shankar Signed-off-by: Uma Shankar Link: https://patchwork.freedesktop.org/patch/msgid/20230309062855.393087-7-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_vdsc.c | 32 +++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c index 0388efb49b92..8e787c13d26d 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc.c +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c @@ -448,6 +448,29 @@ calculate_rc_params(struct rc_parameters *rc, } } +static int intel_dsc_slice_dimensions_valid(struct intel_crtc_state *pipe_config, + struct drm_dsc_config *vdsc_cfg) +{ + if (pipe_config->output_format == INTEL_OUTPUT_FORMAT_RGB || + pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR444) { + if (vdsc_cfg->slice_height > 4095) + return -EINVAL; + if (vdsc_cfg->slice_height * vdsc_cfg->slice_width < 15000) + return -EINVAL; + } else if (pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) { + if (vdsc_cfg->slice_width % 2) + return -EINVAL; + if (vdsc_cfg->slice_height % 2) + return -EINVAL; + if (vdsc_cfg->slice_height > 4094) + return -EINVAL; + if (vdsc_cfg->slice_height * vdsc_cfg->slice_width < 30000) + return -EINVAL; + } + + return 0; +} + int intel_dsc_compute_params(struct intel_crtc_state *pipe_config) { struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc); @@ -456,11 +479,20 @@ int intel_dsc_compute_params(struct intel_crtc_state *pipe_config) u16 compressed_bpp = pipe_config->dsc.compressed_bpp; const struct rc_parameters *rc_params; struct rc_parameters *rc = NULL; + int err; u8 i = 0; vdsc_cfg->pic_width = pipe_config->hw.adjusted_mode.crtc_hdisplay; vdsc_cfg->slice_width = DIV_ROUND_UP(vdsc_cfg->pic_width, pipe_config->dsc.slice_count); + + err = intel_dsc_slice_dimensions_valid(pipe_config, vdsc_cfg); + + if (err) { + drm_dbg_kms(&dev_priv->drm, "Slice dimension requirements not met\n"); + return err; + } + /* * According to DSC 1.2 specs if colorspace is YCbCr then convert_rgb is 0 * else 1 -- cgit v1.2.3-59-g8ed1b From d4d17377e01f017fd5a22f68f13e7ab342f97551 Mon Sep 17 00:00:00 2001 From: Swati Sharma Date: Thu, 9 Mar 2023 11:58:55 +0530 Subject: drm/i915/dsc: Add debugfs entry to validate DSC output formats DSC_Output_Format_Sink_Support entry is added to i915_dsc_fec_support_show to depict if sink supports DSC output formats (RGB/YCbCr420/YCbCr444). Also, new debugfs entry is created to enforce output format. This is required because of our driver policy. For ex. if a mode is supported in both RGB and YCbCr420 output formats by the sink, our policy is to try RGB first and fall back to YCbCr420, if mode cannot be shown using RGB. So, to test other output formats like YCbCr420 or YCbCr444, we need a debugfs entry (force_dsc_output_format) to force this output format. v2: -Func name changed to intel_output_format_name() (Jani N) -Return forced o/p format from intel_dp_output_format() (Jani N) v3: -output_format_str[] to remain static (Jani N) Signed-off-by: Swati Sharma Reviewed-by: Uma Shankar Signed-off-by: Uma Shankar Link: https://patchwork.freedesktop.org/patch/msgid/20230309062855.393087-8-suraj.kandpal@intel.com --- .../gpu/drm/i915/display/intel_crtc_state_dump.c | 4 +- .../gpu/drm/i915/display/intel_crtc_state_dump.h | 2 + .../gpu/drm/i915/display/intel_display_debugfs.c | 78 ++++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_display_types.h | 1 + drivers/gpu/drm/i915/display/intel_dp.c | 4 ++ 5 files changed, 87 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c index 766633566fd6..54c8adc0702e 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c +++ b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.c @@ -123,7 +123,7 @@ static const char * const output_format_str[] = { [INTEL_OUTPUT_FORMAT_YCBCR444] = "YCBCR4:4:4", }; -static const char *output_formats(enum intel_output_format format) +const char *intel_output_format_name(enum intel_output_format format) { if (format >= ARRAY_SIZE(output_format_str)) return "invalid"; @@ -181,7 +181,7 @@ void intel_crtc_state_dump(const struct intel_crtc_state *pipe_config, "active: %s, output_types: %s (0x%x), output format: %s\n", str_yes_no(pipe_config->hw.active), buf, pipe_config->output_types, - output_formats(pipe_config->output_format)); + intel_output_format_name(pipe_config->output_format)); drm_dbg_kms(&i915->drm, "cpu_transcoder: %s, pipe bpp: %i, dithering: %i\n", diff --git a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.h b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.h index 9399c35b7e5e..780f3f1190d7 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc_state_dump.h +++ b/drivers/gpu/drm/i915/display/intel_crtc_state_dump.h @@ -8,9 +8,11 @@ struct intel_crtc_state; struct intel_atomic_state; +enum intel_output_format; void intel_crtc_state_dump(const struct intel_crtc_state *crtc_state, struct intel_atomic_state *state, const char *context); +const char *intel_output_format_name(enum intel_output_format format); #endif /* __INTEL_CRTC_STATE_H__ */ diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index d5715ccc37f0..bad29cdd139d 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -13,6 +13,7 @@ #include "i915_irq.h" #include "i915_reg.h" #include "intel_de.h" +#include "intel_crtc_state_dump.h" #include "intel_display_debugfs.h" #include "intel_display_power.h" #include "intel_display_power_well.h" @@ -1234,6 +1235,13 @@ static int i915_dsc_fec_support_show(struct seq_file *m, void *data) str_yes_no(crtc_state->dsc.compression_enable)); seq_printf(m, "DSC_Sink_Support: %s\n", str_yes_no(drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd))); + seq_printf(m, "DSC_Output_Format_Sink_Support: RGB: %s YCBCR420: %s YCBCR444: %s\n", + str_yes_no(drm_dp_dsc_sink_supports_format(intel_dp->dsc_dpcd, + DP_DSC_RGB)), + str_yes_no(drm_dp_dsc_sink_supports_format(intel_dp->dsc_dpcd, + DP_DSC_YCbCr420_Native)), + str_yes_no(drm_dp_dsc_sink_supports_format(intel_dp->dsc_dpcd, + DP_DSC_YCbCr444))); seq_printf(m, "Force_DSC_Enable: %s\n", str_yes_no(intel_dp->force_dsc_en)); if (!intel_dp_is_edp(intel_dp)) @@ -1359,6 +1367,73 @@ static const struct file_operations i915_dsc_bpc_fops = { .write = i915_dsc_bpc_write }; +static int i915_dsc_output_format_show(struct seq_file *m, void *data) +{ + struct drm_connector *connector = m->private; + struct drm_device *dev = connector->dev; + struct drm_crtc *crtc; + struct intel_crtc_state *crtc_state; + struct intel_encoder *encoder = intel_attached_encoder(to_intel_connector(connector)); + int ret; + + if (!encoder) + return -ENODEV; + + ret = drm_modeset_lock_single_interruptible(&dev->mode_config.connection_mutex); + if (ret) + return ret; + + crtc = connector->state->crtc; + if (connector->status != connector_status_connected || !crtc) { + ret = -ENODEV; + goto out; + } + + crtc_state = to_intel_crtc_state(crtc->state); + seq_printf(m, "DSC_Output_Format: %s\n", + intel_output_format_name(crtc_state->output_format)); + +out: drm_modeset_unlock(&dev->mode_config.connection_mutex); + + return ret; +} + +static ssize_t i915_dsc_output_format_write(struct file *file, + const char __user *ubuf, + size_t len, loff_t *offp) +{ + struct drm_connector *connector = + ((struct seq_file *)file->private_data)->private; + struct intel_encoder *encoder = intel_attached_encoder(to_intel_connector(connector)); + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + int dsc_output_format = 0; + int ret; + + ret = kstrtoint_from_user(ubuf, len, 0, &dsc_output_format); + if (ret < 0) + return ret; + + intel_dp->force_dsc_output_format = dsc_output_format; + *offp += len; + + return len; +} + +static int i915_dsc_output_format_open(struct inode *inode, + struct file *file) +{ + return single_open(file, i915_dsc_output_format_show, inode->i_private); +} + +static const struct file_operations i915_dsc_output_format_fops = { + .owner = THIS_MODULE, + .open = i915_dsc_output_format_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = i915_dsc_output_format_write +}; + /* * Returns the Current CRTC's bpc. * Example usage: cat /sys/kernel/debug/dri/0/crtc-0/i915_current_bpc @@ -1433,6 +1508,9 @@ void intel_connector_debugfs_add(struct intel_connector *intel_connector) debugfs_create_file("i915_dsc_bpc", 0644, root, connector, &i915_dsc_bpc_fops); + + debugfs_create_file("i915_dsc_output_format", 0644, root, + connector, &i915_dsc_output_format_fops); } if (connector->connector_type == DRM_MODE_CONNECTOR_DSI || diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 4236ad751c2c..d84818fc94a4 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -1741,6 +1741,7 @@ struct intel_dp { /* Display stream compression testing */ bool force_dsc_en; + int force_dsc_output_format; int force_dsc_bpc; bool hobl_failed; diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 4a909087ea49..f0bace9d98a1 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -76,6 +76,7 @@ #include "intel_tc.h" #include "intel_vdsc.h" #include "intel_vrr.h" +#include "intel_crtc_state_dump.h" /* DP DSC throughput values used for slice count calculations KPixels/s */ #define DP_DSC_PEAK_PIXEL_RATE 2720000 @@ -833,6 +834,9 @@ intel_dp_output_format(struct intel_connector *connector, { struct intel_dp *intel_dp = intel_attached_dp(connector); + if (intel_dp->force_dsc_output_format) + return intel_dp->force_dsc_output_format; + if (!connector->base.ycbcr_420_allowed || !ycbcr_420_output) return INTEL_OUTPUT_FORMAT_RGB; -- cgit v1.2.3-59-g8ed1b From a33c8f71d3d85ff1c0284270f710b071d480d547 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:07 +0200 Subject: drm/i915/tc: Group the TC PHY setup/query functions per platform Arrange the TC PHY HW state setup/query functions into platform specific and generic groups. This prepares for upcoming patches adding generic TC PHY handlers and platform specific hooks for these, replacing the corresponding if ladders. No functional changes. v2: Fix non kernel-doc multiline comments. (Jani) Cc: Jani Nikula Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-2-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 244 +++++++++++++++++--------------- 1 file changed, 130 insertions(+), 114 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index bd8c9df5f98f..37b1f174301e 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -15,6 +15,10 @@ #include "intel_mg_phy_regs.h" #include "intel_tc.h" +static u32 tc_port_live_status_mask(struct intel_digital_port *dig_port); +static bool tc_phy_status_complete(struct intel_digital_port *dig_port); +static bool tc_phy_take_ownership(struct intel_digital_port *dig_port, bool take); + static const char *tc_port_mode_name(enum tc_port_mode mode) { static const char * const names[] = { @@ -256,6 +260,10 @@ static void tc_port_fixup_legacy_flag(struct intel_digital_port *dig_port, dig_port->tc_legacy_port = !dig_port->tc_legacy_port; } +/* + * ICL TC PHY handlers + * ------------------- + */ static u32 icl_tc_port_live_status_mask(struct intel_digital_port *dig_port) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); @@ -287,44 +295,6 @@ static u32 icl_tc_port_live_status_mask(struct intel_digital_port *dig_port) return mask; } -static u32 adl_tc_port_live_status_mask(struct intel_digital_port *dig_port) -{ - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); - enum tc_port tc_port = intel_port_to_tc(i915, dig_port->base.port); - u32 isr_bit = i915->display.hotplug.pch_hpd[dig_port->base.hpd_pin]; - u32 val, mask = 0; - - /* - * On ADL-P HW/FW will wake from TCCOLD to complete the read access of - * registers in IOM. Note that this doesn't apply to PHY and FIA - * registers. - */ - val = intel_de_read(i915, TCSS_DDI_STATUS(tc_port)); - if (val & TCSS_DDI_STATUS_HPD_LIVE_STATUS_ALT) - mask |= BIT(TC_PORT_DP_ALT); - if (val & TCSS_DDI_STATUS_HPD_LIVE_STATUS_TBT) - mask |= BIT(TC_PORT_TBT_ALT); - - if (intel_de_read(i915, SDEISR) & isr_bit) - mask |= BIT(TC_PORT_LEGACY); - - /* The sink can be connected only in a single mode. */ - if (!drm_WARN_ON(&i915->drm, hweight32(mask) > 1)) - tc_port_fixup_legacy_flag(dig_port, mask); - - return mask; -} - -static u32 tc_port_live_status_mask(struct intel_digital_port *dig_port) -{ - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); - - if (IS_ALDERLAKE_P(i915)) - return adl_tc_port_live_status_mask(dig_port); - - return icl_tc_port_live_status_mask(dig_port); -} - /* * Return the PHY status complete flag indicating that display can acquire the * PHY ownership. The IOM firmware sets this flag when a DP-alt or legacy sink @@ -349,40 +319,6 @@ static bool icl_tc_phy_status_complete(struct intel_digital_port *dig_port) return val & DP_PHY_MODE_STATUS_COMPLETED(dig_port->tc_phy_fia_idx); } -/* - * Return the PHY status complete flag indicating that display can acquire the - * PHY ownership. The IOM firmware sets this flag when it's ready to switch - * the ownership to display, regardless of what sink is connected (TBT-alt, - * DP-alt, legacy or nothing). For TBT-alt sinks the PHY is owned by the TBT - * subsystem and so switching the ownership to display is not required. - */ -static bool adl_tc_phy_status_complete(struct intel_digital_port *dig_port) -{ - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); - enum tc_port tc_port = intel_port_to_tc(i915, dig_port->base.port); - u32 val; - - val = intel_de_read(i915, TCSS_DDI_STATUS(tc_port)); - if (val == 0xffffffff) { - drm_dbg_kms(&i915->drm, - "Port %s: PHY in TCCOLD, assuming not complete\n", - dig_port->tc_port_name); - return false; - } - - return val & TCSS_DDI_STATUS_READY; -} - -static bool tc_phy_status_complete(struct intel_digital_port *dig_port) -{ - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); - - if (IS_ALDERLAKE_P(i915)) - return adl_tc_phy_status_complete(dig_port); - - return icl_tc_phy_status_complete(dig_port); -} - static bool icl_tc_phy_take_ownership(struct intel_digital_port *dig_port, bool take) { @@ -407,28 +343,6 @@ static bool icl_tc_phy_take_ownership(struct intel_digital_port *dig_port, return true; } -static bool adl_tc_phy_take_ownership(struct intel_digital_port *dig_port, - bool take) -{ - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); - enum port port = dig_port->base.port; - - intel_de_rmw(i915, DDI_BUF_CTL(port), DDI_BUF_CTL_TC_PHY_OWNERSHIP, - take ? DDI_BUF_CTL_TC_PHY_OWNERSHIP : 0); - - return true; -} - -static bool tc_phy_take_ownership(struct intel_digital_port *dig_port, bool take) -{ - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); - - if (IS_ALDERLAKE_P(i915)) - return adl_tc_phy_take_ownership(dig_port, take); - - return icl_tc_phy_take_ownership(dig_port, take); -} - static bool icl_tc_phy_is_owned(struct intel_digital_port *dig_port) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); @@ -445,26 +359,6 @@ static bool icl_tc_phy_is_owned(struct intel_digital_port *dig_port) return val & DP_PHY_MODE_STATUS_NOT_SAFE(dig_port->tc_phy_fia_idx); } -static bool adl_tc_phy_is_owned(struct intel_digital_port *dig_port) -{ - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); - enum port port = dig_port->base.port; - u32 val; - - val = intel_de_read(i915, DDI_BUF_CTL(port)); - return val & DDI_BUF_CTL_TC_PHY_OWNERSHIP; -} - -static bool tc_phy_is_owned(struct intel_digital_port *dig_port) -{ - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); - - if (IS_ALDERLAKE_P(i915)) - return adl_tc_phy_is_owned(dig_port); - - return icl_tc_phy_is_owned(dig_port); -} - /* * This function implements the first part of the Connect Flow described by our * specification, Gen11 TypeC Programming chapter. The rest of the flow (reading @@ -559,6 +453,128 @@ static void icl_tc_phy_disconnect(struct intel_digital_port *dig_port) } } +/* + * ADLP TC PHY handlers + * -------------------- + */ +static u32 adl_tc_port_live_status_mask(struct intel_digital_port *dig_port) +{ + struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + enum tc_port tc_port = intel_port_to_tc(i915, dig_port->base.port); + u32 isr_bit = i915->display.hotplug.pch_hpd[dig_port->base.hpd_pin]; + u32 val, mask = 0; + + /* + * On ADL-P HW/FW will wake from TCCOLD to complete the read access of + * registers in IOM. Note that this doesn't apply to PHY and FIA + * registers. + */ + val = intel_de_read(i915, TCSS_DDI_STATUS(tc_port)); + if (val & TCSS_DDI_STATUS_HPD_LIVE_STATUS_ALT) + mask |= BIT(TC_PORT_DP_ALT); + if (val & TCSS_DDI_STATUS_HPD_LIVE_STATUS_TBT) + mask |= BIT(TC_PORT_TBT_ALT); + + if (intel_de_read(i915, SDEISR) & isr_bit) + mask |= BIT(TC_PORT_LEGACY); + + /* The sink can be connected only in a single mode. */ + if (!drm_WARN_ON(&i915->drm, hweight32(mask) > 1)) + tc_port_fixup_legacy_flag(dig_port, mask); + + return mask; +} + +/* + * Return the PHY status complete flag indicating that display can acquire the + * PHY ownership. The IOM firmware sets this flag when it's ready to switch + * the ownership to display, regardless of what sink is connected (TBT-alt, + * DP-alt, legacy or nothing). For TBT-alt sinks the PHY is owned by the TBT + * subsystem and so switching the ownership to display is not required. + */ +static bool adl_tc_phy_status_complete(struct intel_digital_port *dig_port) +{ + struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + enum tc_port tc_port = intel_port_to_tc(i915, dig_port->base.port); + u32 val; + + val = intel_de_read(i915, TCSS_DDI_STATUS(tc_port)); + if (val == 0xffffffff) { + drm_dbg_kms(&i915->drm, + "Port %s: PHY in TCCOLD, assuming not complete\n", + dig_port->tc_port_name); + return false; + } + + return val & TCSS_DDI_STATUS_READY; +} + +static bool adl_tc_phy_take_ownership(struct intel_digital_port *dig_port, + bool take) +{ + struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + enum port port = dig_port->base.port; + + intel_de_rmw(i915, DDI_BUF_CTL(port), DDI_BUF_CTL_TC_PHY_OWNERSHIP, + take ? DDI_BUF_CTL_TC_PHY_OWNERSHIP : 0); + + return true; +} + +static bool adl_tc_phy_is_owned(struct intel_digital_port *dig_port) +{ + struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + enum port port = dig_port->base.port; + u32 val; + + val = intel_de_read(i915, DDI_BUF_CTL(port)); + return val & DDI_BUF_CTL_TC_PHY_OWNERSHIP; +} + +/* + * Generic TC PHY handlers + * ----------------------- + */ +static u32 tc_port_live_status_mask(struct intel_digital_port *dig_port) +{ + struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + + if (IS_ALDERLAKE_P(i915)) + return adl_tc_port_live_status_mask(dig_port); + + return icl_tc_port_live_status_mask(dig_port); +} + +static bool tc_phy_status_complete(struct intel_digital_port *dig_port) +{ + struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + + if (IS_ALDERLAKE_P(i915)) + return adl_tc_phy_status_complete(dig_port); + + return icl_tc_phy_status_complete(dig_port); +} + +static bool tc_phy_is_owned(struct intel_digital_port *dig_port) +{ + struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + + if (IS_ALDERLAKE_P(i915)) + return adl_tc_phy_is_owned(dig_port); + + return icl_tc_phy_is_owned(dig_port); +} + +static bool tc_phy_take_ownership(struct intel_digital_port *dig_port, bool take) +{ + struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + + if (IS_ALDERLAKE_P(i915)) + return adl_tc_phy_take_ownership(dig_port, take); + + return icl_tc_phy_take_ownership(dig_port, take); +} + static bool tc_phy_is_ready_and_owned(struct intel_digital_port *dig_port, bool phy_is_ready, bool phy_is_owned) { -- cgit v1.2.3-59-g8ed1b From 359d36e67da9de877c13c4b4ea6209a5e07264b3 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:08 +0200 Subject: drm/i915/tc: Use the adlp prefix for ADLP TC PHY functions Use the usual adlp prefix for all ADLP specific TC PHY functions. Other ADL platforms don't support TC. Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-3-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 37b1f174301e..09b834d781b1 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -457,7 +457,7 @@ static void icl_tc_phy_disconnect(struct intel_digital_port *dig_port) * ADLP TC PHY handlers * -------------------- */ -static u32 adl_tc_port_live_status_mask(struct intel_digital_port *dig_port) +static u32 adlp_tc_port_live_status_mask(struct intel_digital_port *dig_port) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); enum tc_port tc_port = intel_port_to_tc(i915, dig_port->base.port); @@ -492,7 +492,7 @@ static u32 adl_tc_port_live_status_mask(struct intel_digital_port *dig_port) * DP-alt, legacy or nothing). For TBT-alt sinks the PHY is owned by the TBT * subsystem and so switching the ownership to display is not required. */ -static bool adl_tc_phy_status_complete(struct intel_digital_port *dig_port) +static bool adlp_tc_phy_status_complete(struct intel_digital_port *dig_port) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); enum tc_port tc_port = intel_port_to_tc(i915, dig_port->base.port); @@ -509,8 +509,8 @@ static bool adl_tc_phy_status_complete(struct intel_digital_port *dig_port) return val & TCSS_DDI_STATUS_READY; } -static bool adl_tc_phy_take_ownership(struct intel_digital_port *dig_port, - bool take) +static bool adlp_tc_phy_take_ownership(struct intel_digital_port *dig_port, + bool take) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); enum port port = dig_port->base.port; @@ -521,7 +521,7 @@ static bool adl_tc_phy_take_ownership(struct intel_digital_port *dig_port, return true; } -static bool adl_tc_phy_is_owned(struct intel_digital_port *dig_port) +static bool adlp_tc_phy_is_owned(struct intel_digital_port *dig_port) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); enum port port = dig_port->base.port; @@ -540,7 +540,7 @@ static u32 tc_port_live_status_mask(struct intel_digital_port *dig_port) struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); if (IS_ALDERLAKE_P(i915)) - return adl_tc_port_live_status_mask(dig_port); + return adlp_tc_port_live_status_mask(dig_port); return icl_tc_port_live_status_mask(dig_port); } @@ -550,7 +550,7 @@ static bool tc_phy_status_complete(struct intel_digital_port *dig_port) struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); if (IS_ALDERLAKE_P(i915)) - return adl_tc_phy_status_complete(dig_port); + return adlp_tc_phy_status_complete(dig_port); return icl_tc_phy_status_complete(dig_port); } @@ -560,7 +560,7 @@ static bool tc_phy_is_owned(struct intel_digital_port *dig_port) struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); if (IS_ALDERLAKE_P(i915)) - return adl_tc_phy_is_owned(dig_port); + return adlp_tc_phy_is_owned(dig_port); return icl_tc_phy_is_owned(dig_port); } @@ -570,7 +570,7 @@ static bool tc_phy_take_ownership(struct intel_digital_port *dig_port, bool take struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); if (IS_ALDERLAKE_P(i915)) - return adl_tc_phy_take_ownership(dig_port, take); + return adlp_tc_phy_take_ownership(dig_port, take); return icl_tc_phy_take_ownership(dig_port, take); } -- cgit v1.2.3-59-g8ed1b From 89b154091ab44098668614b52553ae3917eb8215 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:09 +0200 Subject: drm/i915/tc: Rename tc_phy_status_complete() to tc_phy_is_ready() For consistency rename tc_phy_status_complete() to tc_phy_is_ready() following the terminology of new platforms. Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-4-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 09b834d781b1..1705ca4d3ebc 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -16,7 +16,7 @@ #include "intel_tc.h" static u32 tc_port_live_status_mask(struct intel_digital_port *dig_port); -static bool tc_phy_status_complete(struct intel_digital_port *dig_port); +static bool tc_phy_is_ready(struct intel_digital_port *dig_port); static bool tc_phy_take_ownership(struct intel_digital_port *dig_port, bool take); static const char *tc_port_mode_name(enum tc_port_mode mode) @@ -303,7 +303,7 @@ static u32 icl_tc_port_live_status_mask(struct intel_digital_port *dig_port) * owned by the TBT subsystem and so switching the ownership to display is not * required. */ -static bool icl_tc_phy_status_complete(struct intel_digital_port *dig_port) +static bool icl_tc_phy_is_ready(struct intel_digital_port *dig_port) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); u32 val; @@ -311,7 +311,7 @@ static bool icl_tc_phy_status_complete(struct intel_digital_port *dig_port) val = intel_de_read(i915, PORT_TX_DFLEXDPPMS(dig_port->tc_phy_fia)); if (val == 0xffffffff) { drm_dbg_kms(&i915->drm, - "Port %s: PHY in TCCOLD, assuming not complete\n", + "Port %s: PHY in TCCOLD, assuming not ready\n", dig_port->tc_port_name); return false; } @@ -377,7 +377,7 @@ static void icl_tc_phy_connect(struct intel_digital_port *dig_port, u32 live_status_mask; int max_lanes; - if (!tc_phy_status_complete(dig_port) && + if (!tc_phy_is_ready(dig_port) && !drm_WARN_ON(&i915->drm, dig_port->tc_legacy_port)) { drm_dbg_kms(&i915->drm, "Port %s: PHY not ready\n", dig_port->tc_port_name); @@ -492,7 +492,7 @@ static u32 adlp_tc_port_live_status_mask(struct intel_digital_port *dig_port) * DP-alt, legacy or nothing). For TBT-alt sinks the PHY is owned by the TBT * subsystem and so switching the ownership to display is not required. */ -static bool adlp_tc_phy_status_complete(struct intel_digital_port *dig_port) +static bool adlp_tc_phy_is_ready(struct intel_digital_port *dig_port) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); enum tc_port tc_port = intel_port_to_tc(i915, dig_port->base.port); @@ -501,7 +501,7 @@ static bool adlp_tc_phy_status_complete(struct intel_digital_port *dig_port) val = intel_de_read(i915, TCSS_DDI_STATUS(tc_port)); if (val == 0xffffffff) { drm_dbg_kms(&i915->drm, - "Port %s: PHY in TCCOLD, assuming not complete\n", + "Port %s: PHY in TCCOLD, assuming not ready\n", dig_port->tc_port_name); return false; } @@ -545,14 +545,14 @@ static u32 tc_port_live_status_mask(struct intel_digital_port *dig_port) return icl_tc_port_live_status_mask(dig_port); } -static bool tc_phy_status_complete(struct intel_digital_port *dig_port) +static bool tc_phy_is_ready(struct intel_digital_port *dig_port) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); if (IS_ALDERLAKE_P(i915)) - return adlp_tc_phy_status_complete(dig_port); + return adlp_tc_phy_is_ready(dig_port); - return icl_tc_phy_status_complete(dig_port); + return icl_tc_phy_is_ready(dig_port); } static bool tc_phy_is_owned(struct intel_digital_port *dig_port) @@ -590,7 +590,7 @@ static bool tc_phy_is_connected(struct intel_digital_port *dig_port, { struct intel_encoder *encoder = &dig_port->base; struct drm_i915_private *i915 = to_i915(encoder->base.dev); - bool phy_is_ready = tc_phy_status_complete(dig_port); + bool phy_is_ready = tc_phy_is_ready(dig_port); bool phy_is_owned = tc_phy_is_owned(dig_port); bool is_connected; @@ -614,7 +614,7 @@ static void tc_phy_wait_for_ready(struct intel_digital_port *dig_port) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); - if (wait_for(tc_phy_status_complete(dig_port), 100)) + if (wait_for(tc_phy_is_ready(dig_port), 100)) drm_err(&i915->drm, "Port %s: timeout waiting for PHY ready\n", dig_port->tc_port_name); } @@ -694,7 +694,7 @@ intel_tc_port_get_current_mode(struct intel_digital_port *dig_port) if (dig_port->tc_legacy_port) tc_phy_wait_for_ready(dig_port); - phy_is_ready = tc_phy_status_complete(dig_port); + phy_is_ready = tc_phy_is_ready(dig_port); phy_is_owned = tc_phy_is_owned(dig_port); if (!tc_phy_is_ready_and_owned(dig_port, phy_is_ready, phy_is_owned)) { -- cgit v1.2.3-59-g8ed1b From 39feb7b16b107625a0071e5bb8ea19ee89be2a9f Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:10 +0200 Subject: drm/i915/tc: Use the tc_phy prefix for all TC PHY functions For consistency use the tc_phy prefix for all TC PHY functions. Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-5-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 1705ca4d3ebc..129e360bd36c 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -15,7 +15,7 @@ #include "intel_mg_phy_regs.h" #include "intel_tc.h" -static u32 tc_port_live_status_mask(struct intel_digital_port *dig_port); +static u32 tc_phy_hpd_live_status(struct intel_digital_port *dig_port); static bool tc_phy_is_ready(struct intel_digital_port *dig_port); static bool tc_phy_take_ownership(struct intel_digital_port *dig_port, bool take); @@ -264,7 +264,7 @@ static void tc_port_fixup_legacy_flag(struct intel_digital_port *dig_port, * ICL TC PHY handlers * ------------------- */ -static u32 icl_tc_port_live_status_mask(struct intel_digital_port *dig_port) +static u32 icl_tc_phy_hpd_live_status(struct intel_digital_port *dig_port) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); u32 isr_bit = i915->display.hotplug.pch_hpd[dig_port->base.hpd_pin]; @@ -384,7 +384,7 @@ static void icl_tc_phy_connect(struct intel_digital_port *dig_port, goto out_set_tbt_alt_mode; } - live_status_mask = tc_port_live_status_mask(dig_port); + live_status_mask = tc_phy_hpd_live_status(dig_port); if (!(live_status_mask & (BIT(TC_PORT_DP_ALT) | BIT(TC_PORT_LEGACY))) && !dig_port->tc_legacy_port) { drm_dbg_kms(&i915->drm, "Port %s: PHY ownership not required (live status %02x)\n", @@ -408,7 +408,7 @@ static void icl_tc_phy_connect(struct intel_digital_port *dig_port, * Now we have to re-check the live state, in case the port recently * became disconnected. Not necessary for legacy mode. */ - if (!(tc_port_live_status_mask(dig_port) & BIT(TC_PORT_DP_ALT))) { + if (!(tc_phy_hpd_live_status(dig_port) & BIT(TC_PORT_DP_ALT))) { drm_dbg_kms(&i915->drm, "Port %s: PHY sudden disconnect\n", dig_port->tc_port_name); goto out_release_phy; @@ -457,7 +457,7 @@ static void icl_tc_phy_disconnect(struct intel_digital_port *dig_port) * ADLP TC PHY handlers * -------------------- */ -static u32 adlp_tc_port_live_status_mask(struct intel_digital_port *dig_port) +static u32 adlp_tc_phy_hpd_live_status(struct intel_digital_port *dig_port) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); enum tc_port tc_port = intel_port_to_tc(i915, dig_port->base.port); @@ -535,14 +535,14 @@ static bool adlp_tc_phy_is_owned(struct intel_digital_port *dig_port) * Generic TC PHY handlers * ----------------------- */ -static u32 tc_port_live_status_mask(struct intel_digital_port *dig_port) +static u32 tc_phy_hpd_live_status(struct intel_digital_port *dig_port) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); if (IS_ALDERLAKE_P(i915)) - return adlp_tc_port_live_status_mask(dig_port); + return adlp_tc_phy_hpd_live_status(dig_port); - return icl_tc_port_live_status_mask(dig_port); + return icl_tc_phy_hpd_live_status(dig_port); } static bool tc_phy_is_ready(struct intel_digital_port *dig_port) @@ -631,7 +631,7 @@ hpd_mask_to_tc_mode(u32 live_status_mask) static enum tc_port_mode tc_phy_hpd_live_mode(struct intel_digital_port *dig_port) { - u32 live_status_mask = tc_port_live_status_mask(dig_port); + u32 live_status_mask = tc_phy_hpd_live_status(dig_port); return hpd_mask_to_tc_mode(live_status_mask); } @@ -678,7 +678,7 @@ get_tc_mode_in_phy_not_owned_state(struct intel_digital_port *dig_port, } static enum tc_port_mode -intel_tc_port_get_current_mode(struct intel_digital_port *dig_port) +tc_phy_get_current_mode(struct intel_digital_port *dig_port) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); enum tc_port_mode live_mode = tc_phy_hpd_live_mode(dig_port); @@ -735,9 +735,9 @@ hpd_mask_to_target_mode(struct intel_digital_port *dig_port, u32 live_status_mas } static enum tc_port_mode -intel_tc_port_get_target_mode(struct intel_digital_port *dig_port) +tc_phy_get_target_mode(struct intel_digital_port *dig_port) { - u32 live_status_mask = tc_port_live_status_mask(dig_port); + u32 live_status_mask = tc_phy_hpd_live_status(dig_port); return hpd_mask_to_target_mode(dig_port, live_status_mask); } @@ -770,7 +770,7 @@ static void intel_tc_port_reset_mode(struct intel_digital_port *dig_port, static bool intel_tc_port_needs_reset(struct intel_digital_port *dig_port) { - return intel_tc_port_get_target_mode(dig_port) != dig_port->tc_mode; + return tc_phy_get_target_mode(dig_port) != dig_port->tc_mode; } static void intel_tc_port_update_mode(struct intel_digital_port *dig_port, @@ -847,7 +847,7 @@ void intel_tc_port_init_mode(struct intel_digital_port *dig_port) tc_cold_wref = tc_cold_block(dig_port, &domain); - dig_port->tc_mode = intel_tc_port_get_current_mode(dig_port); + dig_port->tc_mode = tc_phy_get_current_mode(dig_port); /* * Save the initial mode for the state check in * intel_tc_port_sanitize_mode(). @@ -976,7 +976,7 @@ bool intel_tc_port_connected_locked(struct intel_encoder *encoder) drm_WARN_ON(&i915->drm, !intel_tc_port_ref_held(dig_port)); - return tc_port_live_status_mask(dig_port) & BIT(dig_port->tc_mode); + return tc_phy_hpd_live_status(dig_port) & BIT(dig_port->tc_mode); } bool intel_tc_port_connected(struct intel_encoder *encoder) -- cgit v1.2.3-59-g8ed1b From 3eafcddf766b6bb8e6308ec2d587d4ef7a4381e4 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:11 +0200 Subject: drm/i915/tc: Move TC port fields to a new intel_tc_port struct Move the TC port specific fields from intel_digital_port to a new intel_tc_port struct. Pass an intel_tc_port pointer to all static functions in intel_tc.c keeping dig_port accessible for these via a pointer stored in the new struct. The next patch will allocate the intel_tc_port dynamically, allowing moving the struct definition to intel_tc.c. Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-6-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_display.h | 7 - drivers/gpu/drm/i915/display/intel_display_types.h | 13 +- drivers/gpu/drm/i915/display/intel_tc.c | 578 +++++++++++---------- drivers/gpu/drm/i915/display/intel_tc.h | 26 + 4 files changed, 335 insertions(+), 289 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h index 596fd3ec1983..287159bdeb0d 100644 --- a/drivers/gpu/drm/i915/display/intel_display.h +++ b/drivers/gpu/drm/i915/display/intel_display.h @@ -164,13 +164,6 @@ enum tc_port { I915_MAX_TC_PORTS }; -enum tc_port_mode { - TC_PORT_DISCONNECTED, - TC_PORT_TBT_ALT, - TC_PORT_DP_ALT, - TC_PORT_LEGACY, -}; - enum aux_ch { AUX_CH_NONE = -1, diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index d84818fc94a4..3dfc8eb45020 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -54,6 +54,7 @@ #include "intel_display_power.h" #include "intel_dpll_mgr.h" #include "intel_wm_types.h" +#include "intel_tc.h" struct drm_printer; struct __intel_global_objs_state; @@ -1782,17 +1783,7 @@ struct intel_digital_port { intel_wakeref_t ddi_io_wakeref; intel_wakeref_t aux_wakeref; - struct mutex tc_lock; /* protects the TypeC port mode */ - intel_wakeref_t tc_lock_wakeref; - enum intel_display_power_domain tc_lock_power_domain; - struct delayed_work tc_disconnect_phy_work; - int tc_link_refcount; - bool tc_legacy_port:1; - char tc_port_name[8]; - enum tc_port_mode tc_mode; - enum tc_port_mode tc_init_mode; - enum phy_fia tc_phy_fia; - u8 tc_phy_fia_idx; + struct intel_tc_port tc; /* protects num_hdcp_streams reference count, hdcp_port_data and hdcp_auth_status */ struct mutex hdcp_mutex; diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 129e360bd36c..d6fc9c5bd979 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -15,9 +15,9 @@ #include "intel_mg_phy_regs.h" #include "intel_tc.h" -static u32 tc_phy_hpd_live_status(struct intel_digital_port *dig_port); -static bool tc_phy_is_ready(struct intel_digital_port *dig_port); -static bool tc_phy_take_ownership(struct intel_digital_port *dig_port, bool take); +static u32 tc_phy_hpd_live_status(struct intel_tc_port *tc); +static bool tc_phy_is_ready(struct intel_tc_port *tc); +static bool tc_phy_take_ownership(struct intel_tc_port *tc, bool take); static const char *tc_port_mode_name(enum tc_port_mode mode) { @@ -34,13 +34,24 @@ static const char *tc_port_mode_name(enum tc_port_mode mode) return names[mode]; } +static struct intel_tc_port *to_tc_port(struct intel_digital_port *dig_port) +{ + return &dig_port->tc; +} + +static struct drm_i915_private *tc_to_i915(struct intel_tc_port *tc) +{ + return to_i915(tc->dig_port->base.base.dev); +} + static bool intel_tc_port_in_mode(struct intel_digital_port *dig_port, enum tc_port_mode mode) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); enum phy phy = intel_port_to_phy(i915, dig_port->base.port); + struct intel_tc_port *tc = to_tc_port(dig_port); - return intel_phy_is_tc(i915, phy) && dig_port->tc_mode == mode; + return intel_phy_is_tc(i915, phy) && tc->mode == mode; } bool intel_tc_port_in_tbt_alt_mode(struct intel_digital_port *dig_port) @@ -61,15 +72,17 @@ bool intel_tc_port_in_legacy_mode(struct intel_digital_port *dig_port) bool intel_tc_cold_requires_aux_pw(struct intel_digital_port *dig_port) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_tc_port *tc = to_tc_port(dig_port); - return (DISPLAY_VER(i915) == 11 && dig_port->tc_legacy_port) || + return (DISPLAY_VER(i915) == 11 && tc->legacy_port) || IS_ALDERLAKE_P(i915); } static enum intel_display_power_domain -tc_cold_get_power_domain(struct intel_digital_port *dig_port, enum tc_port_mode mode) +tc_cold_get_power_domain(struct intel_tc_port *tc, enum tc_port_mode mode) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_digital_port *dig_port = tc->dig_port; if (mode == TC_PORT_TBT_ALT || !intel_tc_cold_requires_aux_pw(dig_port)) return POWER_DOMAIN_TC_COLD_OFF; @@ -78,27 +91,27 @@ tc_cold_get_power_domain(struct intel_digital_port *dig_port, enum tc_port_mode } static intel_wakeref_t -tc_cold_block_in_mode(struct intel_digital_port *dig_port, enum tc_port_mode mode, +tc_cold_block_in_mode(struct intel_tc_port *tc, enum tc_port_mode mode, enum intel_display_power_domain *domain) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct drm_i915_private *i915 = tc_to_i915(tc); - *domain = tc_cold_get_power_domain(dig_port, mode); + *domain = tc_cold_get_power_domain(tc, mode); return intel_display_power_get(i915, *domain); } static intel_wakeref_t -tc_cold_block(struct intel_digital_port *dig_port, enum intel_display_power_domain *domain) +tc_cold_block(struct intel_tc_port *tc, enum intel_display_power_domain *domain) { - return tc_cold_block_in_mode(dig_port, dig_port->tc_mode, domain); + return tc_cold_block_in_mode(tc, tc->mode, domain); } static void -tc_cold_unblock(struct intel_digital_port *dig_port, enum intel_display_power_domain domain, +tc_cold_unblock(struct intel_tc_port *tc, enum intel_display_power_domain domain, intel_wakeref_t wakeref) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct drm_i915_private *i915 = tc_to_i915(tc); /* * wakeref == -1, means some error happened saving save_depot_stack but @@ -112,73 +125,76 @@ tc_cold_unblock(struct intel_digital_port *dig_port, enum intel_display_power_do } static void -assert_tc_cold_blocked(struct intel_digital_port *dig_port) +assert_tc_cold_blocked(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct drm_i915_private *i915 = tc_to_i915(tc); bool enabled; enabled = intel_display_power_is_enabled(i915, - tc_cold_get_power_domain(dig_port, - dig_port->tc_mode)); + tc_cold_get_power_domain(tc, + tc->mode)); drm_WARN_ON(&i915->drm, !enabled); } static enum intel_display_power_domain -tc_port_power_domain(struct intel_digital_port *dig_port) +tc_port_power_domain(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); - enum tc_port tc_port = intel_port_to_tc(i915, dig_port->base.port); + struct drm_i915_private *i915 = tc_to_i915(tc); + enum tc_port tc_port = intel_port_to_tc(i915, tc->dig_port->base.port); return POWER_DOMAIN_PORT_DDI_LANES_TC1 + tc_port - TC_PORT_1; } static void -assert_tc_port_power_enabled(struct intel_digital_port *dig_port) +assert_tc_port_power_enabled(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct drm_i915_private *i915 = tc_to_i915(tc); drm_WARN_ON(&i915->drm, - !intel_display_power_is_enabled(i915, tc_port_power_domain(dig_port))); + !intel_display_power_is_enabled(i915, tc_port_power_domain(tc))); } u32 intel_tc_port_get_lane_mask(struct intel_digital_port *dig_port) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_tc_port *tc = to_tc_port(dig_port); u32 lane_mask; - lane_mask = intel_de_read(i915, PORT_TX_DFLEXDPSP(dig_port->tc_phy_fia)); + lane_mask = intel_de_read(i915, PORT_TX_DFLEXDPSP(tc->phy_fia)); drm_WARN_ON(&i915->drm, lane_mask == 0xffffffff); - assert_tc_cold_blocked(dig_port); + assert_tc_cold_blocked(tc); - lane_mask &= DP_LANE_ASSIGNMENT_MASK(dig_port->tc_phy_fia_idx); - return lane_mask >> DP_LANE_ASSIGNMENT_SHIFT(dig_port->tc_phy_fia_idx); + lane_mask &= DP_LANE_ASSIGNMENT_MASK(tc->phy_fia_idx); + return lane_mask >> DP_LANE_ASSIGNMENT_SHIFT(tc->phy_fia_idx); } u32 intel_tc_port_get_pin_assignment_mask(struct intel_digital_port *dig_port) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_tc_port *tc = to_tc_port(dig_port); u32 pin_mask; - pin_mask = intel_de_read(i915, PORT_TX_DFLEXPA1(dig_port->tc_phy_fia)); + pin_mask = intel_de_read(i915, PORT_TX_DFLEXPA1(tc->phy_fia)); drm_WARN_ON(&i915->drm, pin_mask == 0xffffffff); - assert_tc_cold_blocked(dig_port); + assert_tc_cold_blocked(tc); - return (pin_mask & DP_PIN_ASSIGNMENT_MASK(dig_port->tc_phy_fia_idx)) >> - DP_PIN_ASSIGNMENT_SHIFT(dig_port->tc_phy_fia_idx); + return (pin_mask & DP_PIN_ASSIGNMENT_MASK(tc->phy_fia_idx)) >> + DP_PIN_ASSIGNMENT_SHIFT(tc->phy_fia_idx); } int intel_tc_port_fia_max_lane_count(struct intel_digital_port *dig_port) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_tc_port *tc = to_tc_port(dig_port); intel_wakeref_t wakeref; u32 lane_mask; - if (dig_port->tc_mode != TC_PORT_DP_ALT) + if (tc->mode != TC_PORT_DP_ALT) return 4; - assert_tc_cold_blocked(dig_port); + assert_tc_cold_blocked(tc); lane_mask = 0; with_intel_display_power(i915, POWER_DOMAIN_DISPLAY_CORE, wakeref) @@ -205,45 +221,46 @@ void intel_tc_port_set_fia_lane_count(struct intel_digital_port *dig_port, int required_lanes) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_tc_port *tc = to_tc_port(dig_port); bool lane_reversal = dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL; u32 val; drm_WARN_ON(&i915->drm, - lane_reversal && dig_port->tc_mode != TC_PORT_LEGACY); + lane_reversal && tc->mode != TC_PORT_LEGACY); - assert_tc_cold_blocked(dig_port); + assert_tc_cold_blocked(tc); - val = intel_de_read(i915, PORT_TX_DFLEXDPMLE1(dig_port->tc_phy_fia)); - val &= ~DFLEXDPMLE1_DPMLETC_MASK(dig_port->tc_phy_fia_idx); + val = intel_de_read(i915, PORT_TX_DFLEXDPMLE1(tc->phy_fia)); + val &= ~DFLEXDPMLE1_DPMLETC_MASK(tc->phy_fia_idx); switch (required_lanes) { case 1: val |= lane_reversal ? - DFLEXDPMLE1_DPMLETC_ML3(dig_port->tc_phy_fia_idx) : - DFLEXDPMLE1_DPMLETC_ML0(dig_port->tc_phy_fia_idx); + DFLEXDPMLE1_DPMLETC_ML3(tc->phy_fia_idx) : + DFLEXDPMLE1_DPMLETC_ML0(tc->phy_fia_idx); break; case 2: val |= lane_reversal ? - DFLEXDPMLE1_DPMLETC_ML3_2(dig_port->tc_phy_fia_idx) : - DFLEXDPMLE1_DPMLETC_ML1_0(dig_port->tc_phy_fia_idx); + DFLEXDPMLE1_DPMLETC_ML3_2(tc->phy_fia_idx) : + DFLEXDPMLE1_DPMLETC_ML1_0(tc->phy_fia_idx); break; case 4: - val |= DFLEXDPMLE1_DPMLETC_ML3_0(dig_port->tc_phy_fia_idx); + val |= DFLEXDPMLE1_DPMLETC_ML3_0(tc->phy_fia_idx); break; default: MISSING_CASE(required_lanes); } - intel_de_write(i915, PORT_TX_DFLEXDPMLE1(dig_port->tc_phy_fia), val); + intel_de_write(i915, PORT_TX_DFLEXDPMLE1(tc->phy_fia), val); } -static void tc_port_fixup_legacy_flag(struct intel_digital_port *dig_port, +static void tc_port_fixup_legacy_flag(struct intel_tc_port *tc, u32 live_status_mask) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct drm_i915_private *i915 = tc_to_i915(tc); u32 valid_hpd_mask; - if (dig_port->tc_legacy_port) + if (tc->legacy_port) valid_hpd_mask = BIT(TC_PORT_LEGACY); else valid_hpd_mask = BIT(TC_PORT_DP_ALT) | @@ -255,34 +272,35 @@ static void tc_port_fixup_legacy_flag(struct intel_digital_port *dig_port, /* If live status mismatches the VBT flag, trust the live status. */ drm_dbg_kms(&i915->drm, "Port %s: live status %08x mismatches the legacy port flag %08x, fixing flag\n", - dig_port->tc_port_name, live_status_mask, valid_hpd_mask); + tc->port_name, live_status_mask, valid_hpd_mask); - dig_port->tc_legacy_port = !dig_port->tc_legacy_port; + tc->legacy_port = !tc->legacy_port; } /* * ICL TC PHY handlers * ------------------- */ -static u32 icl_tc_phy_hpd_live_status(struct intel_digital_port *dig_port) +static u32 icl_tc_phy_hpd_live_status(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_digital_port *dig_port = tc->dig_port; u32 isr_bit = i915->display.hotplug.pch_hpd[dig_port->base.hpd_pin]; u32 mask = 0; u32 val; - val = intel_de_read(i915, PORT_TX_DFLEXDPSP(dig_port->tc_phy_fia)); + val = intel_de_read(i915, PORT_TX_DFLEXDPSP(tc->phy_fia)); if (val == 0xffffffff) { drm_dbg_kms(&i915->drm, "Port %s: PHY in TCCOLD, nothing connected\n", - dig_port->tc_port_name); + tc->port_name); return mask; } - if (val & TC_LIVE_STATE_TBT(dig_port->tc_phy_fia_idx)) + if (val & TC_LIVE_STATE_TBT(tc->phy_fia_idx)) mask |= BIT(TC_PORT_TBT_ALT); - if (val & TC_LIVE_STATE_TC(dig_port->tc_phy_fia_idx)) + if (val & TC_LIVE_STATE_TC(tc->phy_fia_idx)) mask |= BIT(TC_PORT_DP_ALT); if (intel_de_read(i915, SDEISR) & isr_bit) @@ -290,7 +308,7 @@ static u32 icl_tc_phy_hpd_live_status(struct intel_digital_port *dig_port) /* The sink can be connected only in a single mode. */ if (!drm_WARN_ON_ONCE(&i915->drm, hweight32(mask) > 1)) - tc_port_fixup_legacy_flag(dig_port, mask); + tc_port_fixup_legacy_flag(tc, mask); return mask; } @@ -303,60 +321,60 @@ static u32 icl_tc_phy_hpd_live_status(struct intel_digital_port *dig_port) * owned by the TBT subsystem and so switching the ownership to display is not * required. */ -static bool icl_tc_phy_is_ready(struct intel_digital_port *dig_port) +static bool icl_tc_phy_is_ready(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct drm_i915_private *i915 = tc_to_i915(tc); u32 val; - val = intel_de_read(i915, PORT_TX_DFLEXDPPMS(dig_port->tc_phy_fia)); + val = intel_de_read(i915, PORT_TX_DFLEXDPPMS(tc->phy_fia)); if (val == 0xffffffff) { drm_dbg_kms(&i915->drm, "Port %s: PHY in TCCOLD, assuming not ready\n", - dig_port->tc_port_name); + tc->port_name); return false; } - return val & DP_PHY_MODE_STATUS_COMPLETED(dig_port->tc_phy_fia_idx); + return val & DP_PHY_MODE_STATUS_COMPLETED(tc->phy_fia_idx); } -static bool icl_tc_phy_take_ownership(struct intel_digital_port *dig_port, +static bool icl_tc_phy_take_ownership(struct intel_tc_port *tc, bool take) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct drm_i915_private *i915 = tc_to_i915(tc); u32 val; - val = intel_de_read(i915, PORT_TX_DFLEXDPCSSS(dig_port->tc_phy_fia)); + val = intel_de_read(i915, PORT_TX_DFLEXDPCSSS(tc->phy_fia)); if (val == 0xffffffff) { drm_dbg_kms(&i915->drm, "Port %s: PHY in TCCOLD, can't %s ownership\n", - dig_port->tc_port_name, take ? "take" : "release"); + tc->port_name, take ? "take" : "release"); return false; } - val &= ~DP_PHY_MODE_STATUS_NOT_SAFE(dig_port->tc_phy_fia_idx); + val &= ~DP_PHY_MODE_STATUS_NOT_SAFE(tc->phy_fia_idx); if (take) - val |= DP_PHY_MODE_STATUS_NOT_SAFE(dig_port->tc_phy_fia_idx); + val |= DP_PHY_MODE_STATUS_NOT_SAFE(tc->phy_fia_idx); - intel_de_write(i915, PORT_TX_DFLEXDPCSSS(dig_port->tc_phy_fia), val); + intel_de_write(i915, PORT_TX_DFLEXDPCSSS(tc->phy_fia), val); return true; } -static bool icl_tc_phy_is_owned(struct intel_digital_port *dig_port) +static bool icl_tc_phy_is_owned(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct drm_i915_private *i915 = tc_to_i915(tc); u32 val; - val = intel_de_read(i915, PORT_TX_DFLEXDPCSSS(dig_port->tc_phy_fia)); + val = intel_de_read(i915, PORT_TX_DFLEXDPCSSS(tc->phy_fia)); if (val == 0xffffffff) { drm_dbg_kms(&i915->drm, "Port %s: PHY in TCCOLD, assume not owned\n", - dig_port->tc_port_name); + tc->port_name); return false; } - return val & DP_PHY_MODE_STATUS_NOT_SAFE(dig_port->tc_phy_fia_idx); + return val & DP_PHY_MODE_STATUS_NOT_SAFE(tc->phy_fia_idx); } /* @@ -370,36 +388,37 @@ static bool icl_tc_phy_is_owned(struct intel_digital_port *dig_port) * connect and disconnect to cleanly transfer ownership with the controller and * set the type-C power state. */ -static void icl_tc_phy_connect(struct intel_digital_port *dig_port, +static void icl_tc_phy_connect(struct intel_tc_port *tc, int required_lanes) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_digital_port *dig_port = tc->dig_port; u32 live_status_mask; int max_lanes; - if (!tc_phy_is_ready(dig_port) && - !drm_WARN_ON(&i915->drm, dig_port->tc_legacy_port)) { + if (!tc_phy_is_ready(tc) && + !drm_WARN_ON(&i915->drm, tc->legacy_port)) { drm_dbg_kms(&i915->drm, "Port %s: PHY not ready\n", - dig_port->tc_port_name); + tc->port_name); goto out_set_tbt_alt_mode; } - live_status_mask = tc_phy_hpd_live_status(dig_port); + live_status_mask = tc_phy_hpd_live_status(tc); if (!(live_status_mask & (BIT(TC_PORT_DP_ALT) | BIT(TC_PORT_LEGACY))) && - !dig_port->tc_legacy_port) { + !tc->legacy_port) { drm_dbg_kms(&i915->drm, "Port %s: PHY ownership not required (live status %02x)\n", - dig_port->tc_port_name, live_status_mask); + tc->port_name, live_status_mask); goto out_set_tbt_alt_mode; } - if (!tc_phy_take_ownership(dig_port, true) && - !drm_WARN_ON(&i915->drm, dig_port->tc_legacy_port)) + if (!tc_phy_take_ownership(tc, true) && + !drm_WARN_ON(&i915->drm, tc->legacy_port)) goto out_set_tbt_alt_mode; max_lanes = intel_tc_port_fia_max_lane_count(dig_port); - if (dig_port->tc_legacy_port) { + if (tc->legacy_port) { drm_WARN_ON(&i915->drm, max_lanes != 4); - dig_port->tc_mode = TC_PORT_LEGACY; + tc->mode = TC_PORT_LEGACY; return; } @@ -408,48 +427,48 @@ static void icl_tc_phy_connect(struct intel_digital_port *dig_port, * Now we have to re-check the live state, in case the port recently * became disconnected. Not necessary for legacy mode. */ - if (!(tc_phy_hpd_live_status(dig_port) & BIT(TC_PORT_DP_ALT))) { + if (!(tc_phy_hpd_live_status(tc) & BIT(TC_PORT_DP_ALT))) { drm_dbg_kms(&i915->drm, "Port %s: PHY sudden disconnect\n", - dig_port->tc_port_name); + tc->port_name); goto out_release_phy; } if (max_lanes < required_lanes) { drm_dbg_kms(&i915->drm, "Port %s: PHY max lanes %d < required lanes %d\n", - dig_port->tc_port_name, + tc->port_name, max_lanes, required_lanes); goto out_release_phy; } - dig_port->tc_mode = TC_PORT_DP_ALT; + tc->mode = TC_PORT_DP_ALT; return; out_release_phy: - tc_phy_take_ownership(dig_port, false); + tc_phy_take_ownership(tc, false); out_set_tbt_alt_mode: - dig_port->tc_mode = TC_PORT_TBT_ALT; + tc->mode = TC_PORT_TBT_ALT; } /* * See the comment at the connect function. This implements the Disconnect * Flow. */ -static void icl_tc_phy_disconnect(struct intel_digital_port *dig_port) +static void icl_tc_phy_disconnect(struct intel_tc_port *tc) { - switch (dig_port->tc_mode) { + switch (tc->mode) { case TC_PORT_LEGACY: case TC_PORT_DP_ALT: - tc_phy_take_ownership(dig_port, false); + tc_phy_take_ownership(tc, false); fallthrough; case TC_PORT_TBT_ALT: - dig_port->tc_mode = TC_PORT_DISCONNECTED; + tc->mode = TC_PORT_DISCONNECTED; fallthrough; case TC_PORT_DISCONNECTED: break; default: - MISSING_CASE(dig_port->tc_mode); + MISSING_CASE(tc->mode); } } @@ -457,9 +476,10 @@ static void icl_tc_phy_disconnect(struct intel_digital_port *dig_port) * ADLP TC PHY handlers * -------------------- */ -static u32 adlp_tc_phy_hpd_live_status(struct intel_digital_port *dig_port) +static u32 adlp_tc_phy_hpd_live_status(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_digital_port *dig_port = tc->dig_port; enum tc_port tc_port = intel_port_to_tc(i915, dig_port->base.port); u32 isr_bit = i915->display.hotplug.pch_hpd[dig_port->base.hpd_pin]; u32 val, mask = 0; @@ -480,7 +500,7 @@ static u32 adlp_tc_phy_hpd_live_status(struct intel_digital_port *dig_port) /* The sink can be connected only in a single mode. */ if (!drm_WARN_ON(&i915->drm, hweight32(mask) > 1)) - tc_port_fixup_legacy_flag(dig_port, mask); + tc_port_fixup_legacy_flag(tc, mask); return mask; } @@ -492,28 +512,28 @@ static u32 adlp_tc_phy_hpd_live_status(struct intel_digital_port *dig_port) * DP-alt, legacy or nothing). For TBT-alt sinks the PHY is owned by the TBT * subsystem and so switching the ownership to display is not required. */ -static bool adlp_tc_phy_is_ready(struct intel_digital_port *dig_port) +static bool adlp_tc_phy_is_ready(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); - enum tc_port tc_port = intel_port_to_tc(i915, dig_port->base.port); + struct drm_i915_private *i915 = tc_to_i915(tc); + enum tc_port tc_port = intel_port_to_tc(i915, tc->dig_port->base.port); u32 val; val = intel_de_read(i915, TCSS_DDI_STATUS(tc_port)); if (val == 0xffffffff) { drm_dbg_kms(&i915->drm, "Port %s: PHY in TCCOLD, assuming not ready\n", - dig_port->tc_port_name); + tc->port_name); return false; } return val & TCSS_DDI_STATUS_READY; } -static bool adlp_tc_phy_take_ownership(struct intel_digital_port *dig_port, +static bool adlp_tc_phy_take_ownership(struct intel_tc_port *tc, bool take) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); - enum port port = dig_port->base.port; + struct drm_i915_private *i915 = tc_to_i915(tc); + enum port port = tc->dig_port->base.port; intel_de_rmw(i915, DDI_BUF_CTL(port), DDI_BUF_CTL_TC_PHY_OWNERSHIP, take ? DDI_BUF_CTL_TC_PHY_OWNERSHIP : 0); @@ -521,10 +541,10 @@ static bool adlp_tc_phy_take_ownership(struct intel_digital_port *dig_port, return true; } -static bool adlp_tc_phy_is_owned(struct intel_digital_port *dig_port) +static bool adlp_tc_phy_is_owned(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); - enum port port = dig_port->base.port; + struct drm_i915_private *i915 = tc_to_i915(tc); + enum port port = tc->dig_port->base.port; u32 val; val = intel_de_read(i915, DDI_BUF_CTL(port)); @@ -535,73 +555,73 @@ static bool adlp_tc_phy_is_owned(struct intel_digital_port *dig_port) * Generic TC PHY handlers * ----------------------- */ -static u32 tc_phy_hpd_live_status(struct intel_digital_port *dig_port) +static u32 tc_phy_hpd_live_status(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct drm_i915_private *i915 = tc_to_i915(tc); if (IS_ALDERLAKE_P(i915)) - return adlp_tc_phy_hpd_live_status(dig_port); + return adlp_tc_phy_hpd_live_status(tc); - return icl_tc_phy_hpd_live_status(dig_port); + return icl_tc_phy_hpd_live_status(tc); } -static bool tc_phy_is_ready(struct intel_digital_port *dig_port) +static bool tc_phy_is_ready(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct drm_i915_private *i915 = tc_to_i915(tc); if (IS_ALDERLAKE_P(i915)) - return adlp_tc_phy_is_ready(dig_port); + return adlp_tc_phy_is_ready(tc); - return icl_tc_phy_is_ready(dig_port); + return icl_tc_phy_is_ready(tc); } -static bool tc_phy_is_owned(struct intel_digital_port *dig_port) +static bool tc_phy_is_owned(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct drm_i915_private *i915 = tc_to_i915(tc); if (IS_ALDERLAKE_P(i915)) - return adlp_tc_phy_is_owned(dig_port); + return adlp_tc_phy_is_owned(tc); - return icl_tc_phy_is_owned(dig_port); + return icl_tc_phy_is_owned(tc); } -static bool tc_phy_take_ownership(struct intel_digital_port *dig_port, bool take) +static bool tc_phy_take_ownership(struct intel_tc_port *tc, bool take) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct drm_i915_private *i915 = tc_to_i915(tc); if (IS_ALDERLAKE_P(i915)) - return adlp_tc_phy_take_ownership(dig_port, take); + return adlp_tc_phy_take_ownership(tc, take); - return icl_tc_phy_take_ownership(dig_port, take); + return icl_tc_phy_take_ownership(tc, take); } -static bool tc_phy_is_ready_and_owned(struct intel_digital_port *dig_port, +static bool tc_phy_is_ready_and_owned(struct intel_tc_port *tc, bool phy_is_ready, bool phy_is_owned) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct drm_i915_private *i915 = tc_to_i915(tc); drm_WARN_ON(&i915->drm, phy_is_owned && !phy_is_ready); return phy_is_ready && phy_is_owned; } -static bool tc_phy_is_connected(struct intel_digital_port *dig_port, +static bool tc_phy_is_connected(struct intel_tc_port *tc, enum icl_port_dpll_id port_pll_type) { - struct intel_encoder *encoder = &dig_port->base; + struct intel_encoder *encoder = &tc->dig_port->base; struct drm_i915_private *i915 = to_i915(encoder->base.dev); - bool phy_is_ready = tc_phy_is_ready(dig_port); - bool phy_is_owned = tc_phy_is_owned(dig_port); + bool phy_is_ready = tc_phy_is_ready(tc); + bool phy_is_owned = tc_phy_is_owned(tc); bool is_connected; - if (tc_phy_is_ready_and_owned(dig_port, phy_is_ready, phy_is_owned)) + if (tc_phy_is_ready_and_owned(tc, phy_is_ready, phy_is_owned)) is_connected = port_pll_type == ICL_PORT_DPLL_MG_PHY; else is_connected = port_pll_type == ICL_PORT_DPLL_DEFAULT; drm_dbg_kms(&i915->drm, "Port %s: PHY connected: %s (ready: %s, owned: %s, pll_type: %s)\n", - dig_port->tc_port_name, + tc->port_name, str_yes_no(is_connected), str_yes_no(phy_is_ready), str_yes_no(phy_is_owned), @@ -610,13 +630,13 @@ static bool tc_phy_is_connected(struct intel_digital_port *dig_port, return is_connected; } -static void tc_phy_wait_for_ready(struct intel_digital_port *dig_port) +static void tc_phy_wait_for_ready(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct drm_i915_private *i915 = tc_to_i915(tc); - if (wait_for(tc_phy_is_ready(dig_port), 100)) + if (wait_for(tc_phy_is_ready(tc), 100)) drm_err(&i915->drm, "Port %s: timeout waiting for PHY ready\n", - dig_port->tc_port_name); + tc->port_name); } static enum tc_port_mode @@ -629,15 +649,15 @@ hpd_mask_to_tc_mode(u32 live_status_mask) } static enum tc_port_mode -tc_phy_hpd_live_mode(struct intel_digital_port *dig_port) +tc_phy_hpd_live_mode(struct intel_tc_port *tc) { - u32 live_status_mask = tc_phy_hpd_live_status(dig_port); + u32 live_status_mask = tc_phy_hpd_live_status(tc); return hpd_mask_to_tc_mode(live_status_mask); } static enum tc_port_mode -get_tc_mode_in_phy_owned_state(struct intel_digital_port *dig_port, +get_tc_mode_in_phy_owned_state(struct intel_tc_port *tc, enum tc_port_mode live_mode) { switch (live_mode) { @@ -649,7 +669,7 @@ get_tc_mode_in_phy_owned_state(struct intel_digital_port *dig_port, fallthrough; case TC_PORT_TBT_ALT: case TC_PORT_DISCONNECTED: - if (dig_port->tc_legacy_port) + if (tc->legacy_port) return TC_PORT_LEGACY; else return TC_PORT_DP_ALT; @@ -657,7 +677,7 @@ get_tc_mode_in_phy_owned_state(struct intel_digital_port *dig_port, } static enum tc_port_mode -get_tc_mode_in_phy_not_owned_state(struct intel_digital_port *dig_port, +get_tc_mode_in_phy_not_owned_state(struct intel_tc_port *tc, enum tc_port_mode live_mode) { switch (live_mode) { @@ -670,7 +690,7 @@ get_tc_mode_in_phy_not_owned_state(struct intel_digital_port *dig_port, MISSING_CASE(live_mode); fallthrough; case TC_PORT_DISCONNECTED: - if (dig_port->tc_legacy_port) + if (tc->legacy_port) return TC_PORT_DISCONNECTED; else return TC_PORT_TBT_ALT; @@ -678,10 +698,10 @@ get_tc_mode_in_phy_not_owned_state(struct intel_digital_port *dig_port, } static enum tc_port_mode -tc_phy_get_current_mode(struct intel_digital_port *dig_port) +tc_phy_get_current_mode(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); - enum tc_port_mode live_mode = tc_phy_hpd_live_mode(dig_port); + struct drm_i915_private *i915 = tc_to_i915(tc); + enum tc_port_mode live_mode = tc_phy_hpd_live_mode(tc); bool phy_is_ready; bool phy_is_owned; enum tc_port_mode mode; @@ -691,22 +711,22 @@ tc_phy_get_current_mode(struct intel_digital_port *dig_port) * and system resume whether or not a sink is connected. Wait here for * the initialization to get ready. */ - if (dig_port->tc_legacy_port) - tc_phy_wait_for_ready(dig_port); + if (tc->legacy_port) + tc_phy_wait_for_ready(tc); - phy_is_ready = tc_phy_is_ready(dig_port); - phy_is_owned = tc_phy_is_owned(dig_port); + phy_is_ready = tc_phy_is_ready(tc); + phy_is_owned = tc_phy_is_owned(tc); - if (!tc_phy_is_ready_and_owned(dig_port, phy_is_ready, phy_is_owned)) { - mode = get_tc_mode_in_phy_not_owned_state(dig_port, live_mode); + if (!tc_phy_is_ready_and_owned(tc, phy_is_ready, phy_is_owned)) { + mode = get_tc_mode_in_phy_not_owned_state(tc, live_mode); } else { drm_WARN_ON(&i915->drm, live_mode == TC_PORT_TBT_ALT); - mode = get_tc_mode_in_phy_owned_state(dig_port, live_mode); + mode = get_tc_mode_in_phy_owned_state(tc, live_mode); } drm_dbg_kms(&i915->drm, "Port %s: PHY mode: %s (ready: %s, owned: %s, HPD: %s)\n", - dig_port->tc_port_name, + tc->port_name, tc_port_mode_name(mode), str_yes_no(phy_is_ready), str_yes_no(phy_is_owned), @@ -715,38 +735,39 @@ tc_phy_get_current_mode(struct intel_digital_port *dig_port) return mode; } -static enum tc_port_mode default_tc_mode(struct intel_digital_port *dig_port) +static enum tc_port_mode default_tc_mode(struct intel_tc_port *tc) { - if (dig_port->tc_legacy_port) + if (tc->legacy_port) return TC_PORT_LEGACY; return TC_PORT_TBT_ALT; } static enum tc_port_mode -hpd_mask_to_target_mode(struct intel_digital_port *dig_port, u32 live_status_mask) +hpd_mask_to_target_mode(struct intel_tc_port *tc, u32 live_status_mask) { enum tc_port_mode mode = hpd_mask_to_tc_mode(live_status_mask); if (mode != TC_PORT_DISCONNECTED) return mode; - return default_tc_mode(dig_port); + return default_tc_mode(tc); } static enum tc_port_mode -tc_phy_get_target_mode(struct intel_digital_port *dig_port) +tc_phy_get_target_mode(struct intel_tc_port *tc) { - u32 live_status_mask = tc_phy_hpd_live_status(dig_port); + u32 live_status_mask = tc_phy_hpd_live_status(tc); - return hpd_mask_to_target_mode(dig_port, live_status_mask); + return hpd_mask_to_target_mode(tc, live_status_mask); } -static void intel_tc_port_reset_mode(struct intel_digital_port *dig_port, +static void intel_tc_port_reset_mode(struct intel_tc_port *tc, int required_lanes, bool force_disconnect) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); - enum tc_port_mode old_tc_mode = dig_port->tc_mode; + struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_digital_port *dig_port = tc->dig_port; + enum tc_port_mode old_tc_mode = tc->mode; intel_display_power_flush_work(i915); if (!intel_tc_cold_requires_aux_pw(dig_port)) { @@ -758,22 +779,22 @@ static void intel_tc_port_reset_mode(struct intel_digital_port *dig_port, drm_WARN_ON(&i915->drm, aux_powered); } - icl_tc_phy_disconnect(dig_port); + icl_tc_phy_disconnect(tc); if (!force_disconnect) - icl_tc_phy_connect(dig_port, required_lanes); + icl_tc_phy_connect(tc, required_lanes); drm_dbg_kms(&i915->drm, "Port %s: TC port mode reset (%s -> %s)\n", - dig_port->tc_port_name, + tc->port_name, tc_port_mode_name(old_tc_mode), - tc_port_mode_name(dig_port->tc_mode)); + tc_port_mode_name(tc->mode)); } -static bool intel_tc_port_needs_reset(struct intel_digital_port *dig_port) +static bool intel_tc_port_needs_reset(struct intel_tc_port *tc) { - return tc_phy_get_target_mode(dig_port) != dig_port->tc_mode; + return tc_phy_get_target_mode(tc) != tc->mode; } -static void intel_tc_port_update_mode(struct intel_digital_port *dig_port, +static void intel_tc_port_update_mode(struct intel_tc_port *tc, int required_lanes, bool force_disconnect) { enum intel_display_power_domain domain; @@ -782,44 +803,44 @@ static void intel_tc_port_update_mode(struct intel_digital_port *dig_port, if (!needs_reset) { /* Get power domain required to check the hotplug live status. */ - wref = tc_cold_block(dig_port, &domain); - needs_reset = intel_tc_port_needs_reset(dig_port); - tc_cold_unblock(dig_port, domain, wref); + wref = tc_cold_block(tc, &domain); + needs_reset = intel_tc_port_needs_reset(tc); + tc_cold_unblock(tc, domain, wref); } if (!needs_reset) return; /* Get power domain required for resetting the mode. */ - wref = tc_cold_block_in_mode(dig_port, TC_PORT_DISCONNECTED, &domain); + wref = tc_cold_block_in_mode(tc, TC_PORT_DISCONNECTED, &domain); - intel_tc_port_reset_mode(dig_port, required_lanes, force_disconnect); + intel_tc_port_reset_mode(tc, required_lanes, force_disconnect); /* Get power domain matching the new mode after reset. */ - tc_cold_unblock(dig_port, dig_port->tc_lock_power_domain, - fetch_and_zero(&dig_port->tc_lock_wakeref)); - if (dig_port->tc_mode != TC_PORT_DISCONNECTED) - dig_port->tc_lock_wakeref = tc_cold_block(dig_port, - &dig_port->tc_lock_power_domain); + tc_cold_unblock(tc, tc->lock_power_domain, + fetch_and_zero(&tc->lock_wakeref)); + if (tc->mode != TC_PORT_DISCONNECTED) + tc->lock_wakeref = tc_cold_block(tc, &tc->lock_power_domain); - tc_cold_unblock(dig_port, domain, wref); + tc_cold_unblock(tc, domain, wref); } -static void __intel_tc_port_get_link(struct intel_digital_port *dig_port) +static void __intel_tc_port_get_link(struct intel_tc_port *tc) { - dig_port->tc_link_refcount++; + tc->link_refcount++; } -static void __intel_tc_port_put_link(struct intel_digital_port *dig_port) +static void __intel_tc_port_put_link(struct intel_tc_port *tc) { - dig_port->tc_link_refcount--; + tc->link_refcount--; } -static bool tc_port_is_enabled(struct intel_digital_port *dig_port) +static bool tc_port_is_enabled(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_digital_port *dig_port = tc->dig_port; - assert_tc_port_power_enabled(dig_port); + assert_tc_port_power_enabled(tc); return intel_de_read(i915, DDI_BUF_CTL(dig_port->base.port)) & DDI_BUF_CTL_ENABLE; @@ -835,27 +856,28 @@ static bool tc_port_is_enabled(struct intel_digital_port *dig_port) void intel_tc_port_init_mode(struct intel_digital_port *dig_port) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_tc_port *tc = to_tc_port(dig_port); intel_wakeref_t tc_cold_wref; enum intel_display_power_domain domain; bool update_mode = false; - mutex_lock(&dig_port->tc_lock); + mutex_lock(&tc->lock); - drm_WARN_ON(&i915->drm, dig_port->tc_mode != TC_PORT_DISCONNECTED); - drm_WARN_ON(&i915->drm, dig_port->tc_lock_wakeref); - drm_WARN_ON(&i915->drm, dig_port->tc_link_refcount); + drm_WARN_ON(&i915->drm, tc->mode != TC_PORT_DISCONNECTED); + drm_WARN_ON(&i915->drm, tc->lock_wakeref); + drm_WARN_ON(&i915->drm, tc->link_refcount); - tc_cold_wref = tc_cold_block(dig_port, &domain); + tc_cold_wref = tc_cold_block(tc, &domain); - dig_port->tc_mode = tc_phy_get_current_mode(dig_port); + tc->mode = tc_phy_get_current_mode(tc); /* * Save the initial mode for the state check in * intel_tc_port_sanitize_mode(). */ - dig_port->tc_init_mode = dig_port->tc_mode; - if (dig_port->tc_mode != TC_PORT_DISCONNECTED) - dig_port->tc_lock_wakeref = - tc_cold_block(dig_port, &dig_port->tc_lock_power_domain); + tc->init_mode = tc->mode; + if (tc->mode != TC_PORT_DISCONNECTED) + tc->lock_wakeref = + tc_cold_block(tc, &tc->lock_power_domain); /* * The PHY needs to be connected for AUX to work during HW readout and @@ -868,31 +890,32 @@ void intel_tc_port_init_mode(struct intel_digital_port *dig_port) * cause a problem as the PHY ownership state is ignored by the * IOM/TCSS firmware (only display can own the PHY in that case). */ - if (!tc_port_is_enabled(dig_port)) { + if (!tc_port_is_enabled(tc)) { update_mode = true; - } else if (dig_port->tc_mode == TC_PORT_DISCONNECTED) { - drm_WARN_ON(&i915->drm, !dig_port->tc_legacy_port); + } else if (tc->mode == TC_PORT_DISCONNECTED) { + drm_WARN_ON(&i915->drm, !tc->legacy_port); drm_err(&i915->drm, "Port %s: PHY disconnected on enabled port, connecting it\n", - dig_port->tc_port_name); + tc->port_name); update_mode = true; } if (update_mode) - intel_tc_port_update_mode(dig_port, 1, false); + intel_tc_port_update_mode(tc, 1, false); - /* Prevent changing dig_port->tc_mode until intel_tc_port_sanitize_mode() is called. */ - __intel_tc_port_get_link(dig_port); + /* Prevent changing tc->mode until intel_tc_port_sanitize_mode() is called. */ + __intel_tc_port_get_link(tc); - tc_cold_unblock(dig_port, domain, tc_cold_wref); + tc_cold_unblock(tc, domain, tc_cold_wref); - mutex_unlock(&dig_port->tc_lock); + mutex_unlock(&tc->lock); } -static bool tc_port_has_active_links(struct intel_digital_port *dig_port, +static bool tc_port_has_active_links(struct intel_tc_port *tc, const struct intel_crtc_state *crtc_state) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_digital_port *dig_port = tc->dig_port; enum icl_port_dpll_id pll_type = ICL_PORT_DPLL_DEFAULT; int active_links = 0; @@ -904,10 +927,10 @@ static bool tc_port_has_active_links(struct intel_digital_port *dig_port, active_links = 1; } - if (active_links && !tc_phy_is_connected(dig_port, pll_type)) + if (active_links && !tc_phy_is_connected(tc, pll_type)) drm_err(&i915->drm, "Port %s: PHY disconnected with %d active link(s)\n", - dig_port->tc_port_name, active_links); + tc->port_name, active_links); return active_links; } @@ -928,35 +951,36 @@ void intel_tc_port_sanitize_mode(struct intel_digital_port *dig_port, const struct intel_crtc_state *crtc_state) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_tc_port *tc = to_tc_port(dig_port); - mutex_lock(&dig_port->tc_lock); + mutex_lock(&tc->lock); - drm_WARN_ON(&i915->drm, dig_port->tc_link_refcount != 1); - if (!tc_port_has_active_links(dig_port, crtc_state)) { + drm_WARN_ON(&i915->drm, tc->link_refcount != 1); + if (!tc_port_has_active_links(tc, crtc_state)) { /* * TBT-alt is the default mode in any case the PHY ownership is not * held (regardless of the sink's connected live state), so * we'll just switch to disconnected mode from it here without * a note. */ - if (dig_port->tc_init_mode != TC_PORT_TBT_ALT && - dig_port->tc_init_mode != TC_PORT_DISCONNECTED) + if (tc->init_mode != TC_PORT_TBT_ALT && + tc->init_mode != TC_PORT_DISCONNECTED) drm_dbg_kms(&i915->drm, "Port %s: PHY left in %s mode on disabled port, disconnecting it\n", - dig_port->tc_port_name, - tc_port_mode_name(dig_port->tc_init_mode)); - icl_tc_phy_disconnect(dig_port); - __intel_tc_port_put_link(dig_port); + tc->port_name, + tc_port_mode_name(tc->init_mode)); + icl_tc_phy_disconnect(tc); + __intel_tc_port_put_link(tc); - tc_cold_unblock(dig_port, dig_port->tc_lock_power_domain, - fetch_and_zero(&dig_port->tc_lock_wakeref)); + tc_cold_unblock(tc, tc->lock_power_domain, + fetch_and_zero(&tc->lock_wakeref)); } drm_dbg_kms(&i915->drm, "Port %s: sanitize mode (%s)\n", - dig_port->tc_port_name, - tc_port_mode_name(dig_port->tc_mode)); + tc->port_name, + tc_port_mode_name(tc->mode)); - mutex_unlock(&dig_port->tc_lock); + mutex_unlock(&tc->lock); } /* @@ -973,10 +997,11 @@ bool intel_tc_port_connected_locked(struct intel_encoder *encoder) { struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_tc_port *tc = to_tc_port(dig_port); drm_WARN_ON(&i915->drm, !intel_tc_port_ref_held(dig_port)); - return tc_phy_hpd_live_status(dig_port) & BIT(dig_port->tc_mode); + return tc_phy_hpd_live_status(tc) & BIT(tc->mode); } bool intel_tc_port_connected(struct intel_encoder *encoder) @@ -991,27 +1016,27 @@ bool intel_tc_port_connected(struct intel_encoder *encoder) return is_connected; } -static void __intel_tc_port_lock(struct intel_digital_port *dig_port, +static void __intel_tc_port_lock(struct intel_tc_port *tc, int required_lanes) { - struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct drm_i915_private *i915 = tc_to_i915(tc); - mutex_lock(&dig_port->tc_lock); + mutex_lock(&tc->lock); - cancel_delayed_work(&dig_port->tc_disconnect_phy_work); + cancel_delayed_work(&tc->disconnect_phy_work); - if (!dig_port->tc_link_refcount) - intel_tc_port_update_mode(dig_port, required_lanes, + if (!tc->link_refcount) + intel_tc_port_update_mode(tc, required_lanes, false); - drm_WARN_ON(&i915->drm, dig_port->tc_mode == TC_PORT_DISCONNECTED); - drm_WARN_ON(&i915->drm, dig_port->tc_mode != TC_PORT_TBT_ALT && - !tc_phy_is_owned(dig_port)); + drm_WARN_ON(&i915->drm, tc->mode == TC_PORT_DISCONNECTED); + drm_WARN_ON(&i915->drm, tc->mode != TC_PORT_TBT_ALT && + !tc_phy_is_owned(tc)); } void intel_tc_port_lock(struct intel_digital_port *dig_port) { - __intel_tc_port_lock(dig_port, 1); + __intel_tc_port_lock(to_tc_port(dig_port), 1); } /** @@ -1024,15 +1049,15 @@ void intel_tc_port_lock(struct intel_digital_port *dig_port) */ static void intel_tc_port_disconnect_phy_work(struct work_struct *work) { - struct intel_digital_port *dig_port = - container_of(work, struct intel_digital_port, tc_disconnect_phy_work.work); + struct intel_tc_port *tc = + container_of(work, struct intel_tc_port, disconnect_phy_work.work); - mutex_lock(&dig_port->tc_lock); + mutex_lock(&tc->lock); - if (!dig_port->tc_link_refcount) - intel_tc_port_update_mode(dig_port, 1, true); + if (!tc->link_refcount) + intel_tc_port_update_mode(tc, 1, true); - mutex_unlock(&dig_port->tc_lock); + mutex_unlock(&tc->lock); } /** @@ -1043,36 +1068,44 @@ static void intel_tc_port_disconnect_phy_work(struct work_struct *work) */ void intel_tc_port_flush_work(struct intel_digital_port *dig_port) { - flush_delayed_work(&dig_port->tc_disconnect_phy_work); + flush_delayed_work(&to_tc_port(dig_port)->disconnect_phy_work); } void intel_tc_port_unlock(struct intel_digital_port *dig_port) { - if (!dig_port->tc_link_refcount && dig_port->tc_mode != TC_PORT_DISCONNECTED) - queue_delayed_work(system_unbound_wq, &dig_port->tc_disconnect_phy_work, + struct intel_tc_port *tc = to_tc_port(dig_port); + + if (!tc->link_refcount && tc->mode != TC_PORT_DISCONNECTED) + queue_delayed_work(system_unbound_wq, &tc->disconnect_phy_work, msecs_to_jiffies(1000)); - mutex_unlock(&dig_port->tc_lock); + mutex_unlock(&tc->lock); } bool intel_tc_port_ref_held(struct intel_digital_port *dig_port) { - return mutex_is_locked(&dig_port->tc_lock) || - dig_port->tc_link_refcount; + struct intel_tc_port *tc = to_tc_port(dig_port); + + return mutex_is_locked(&tc->lock) || + tc->link_refcount; } void intel_tc_port_get_link(struct intel_digital_port *dig_port, int required_lanes) { - __intel_tc_port_lock(dig_port, required_lanes); - __intel_tc_port_get_link(dig_port); + struct intel_tc_port *tc = to_tc_port(dig_port); + + __intel_tc_port_lock(tc, required_lanes); + __intel_tc_port_get_link(tc); intel_tc_port_unlock(dig_port); } void intel_tc_port_put_link(struct intel_digital_port *dig_port) { + struct intel_tc_port *tc = to_tc_port(dig_port); + intel_tc_port_lock(dig_port); - __intel_tc_port_put_link(dig_port); + __intel_tc_port_put_link(tc); intel_tc_port_unlock(dig_port); /* @@ -1085,7 +1118,7 @@ void intel_tc_port_put_link(struct intel_digital_port *dig_port) } static bool -tc_has_modular_fia(struct drm_i915_private *i915, struct intel_digital_port *dig_port) +tc_has_modular_fia(struct drm_i915_private *i915, struct intel_tc_port *tc) { enum intel_display_power_domain domain; intel_wakeref_t wakeref; @@ -1094,11 +1127,11 @@ tc_has_modular_fia(struct drm_i915_private *i915, struct intel_digital_port *dig if (!INTEL_INFO(i915)->display.has_modular_fia) return false; - mutex_lock(&dig_port->tc_lock); - wakeref = tc_cold_block(dig_port, &domain); + mutex_lock(&tc->lock); + wakeref = tc_cold_block(tc, &domain); val = intel_de_read(i915, PORT_TX_DFLEXDPSP(FIA1)); - tc_cold_unblock(dig_port, domain, wakeref); - mutex_unlock(&dig_port->tc_lock); + tc_cold_unblock(tc, domain, wakeref); + mutex_unlock(&tc->lock); drm_WARN_ON(&i915->drm, val == 0xffffffff); @@ -1106,42 +1139,45 @@ tc_has_modular_fia(struct drm_i915_private *i915, struct intel_digital_port *dig } static void -tc_port_load_fia_params(struct drm_i915_private *i915, struct intel_digital_port *dig_port) +tc_port_load_fia_params(struct drm_i915_private *i915, struct intel_tc_port *tc) { - enum port port = dig_port->base.port; + enum port port = tc->dig_port->base.port; enum tc_port tc_port = intel_port_to_tc(i915, port); /* * Each Modular FIA instance houses 2 TC ports. In SOC that has more * than two TC ports, there are multiple instances of Modular FIA. */ - if (tc_has_modular_fia(i915, dig_port)) { - dig_port->tc_phy_fia = tc_port / 2; - dig_port->tc_phy_fia_idx = tc_port % 2; + if (tc_has_modular_fia(i915, tc)) { + tc->phy_fia = tc_port / 2; + tc->phy_fia_idx = tc_port % 2; } else { - dig_port->tc_phy_fia = FIA1; - dig_port->tc_phy_fia_idx = tc_port; + tc->phy_fia = FIA1; + tc->phy_fia_idx = tc_port; } } void intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); + struct intel_tc_port *tc = to_tc_port(dig_port); enum port port = dig_port->base.port; enum tc_port tc_port = intel_port_to_tc(i915, port); if (drm_WARN_ON(&i915->drm, tc_port == TC_PORT_NONE)) return; - snprintf(dig_port->tc_port_name, sizeof(dig_port->tc_port_name), + tc->dig_port = dig_port; + + snprintf(tc->port_name, sizeof(tc->port_name), "%c/TC#%d", port_name(port), tc_port + 1); - mutex_init(&dig_port->tc_lock); - INIT_DELAYED_WORK(&dig_port->tc_disconnect_phy_work, intel_tc_port_disconnect_phy_work); - dig_port->tc_legacy_port = is_legacy; - dig_port->tc_mode = TC_PORT_DISCONNECTED; - dig_port->tc_link_refcount = 0; - tc_port_load_fia_params(i915, dig_port); + mutex_init(&tc->lock); + INIT_DELAYED_WORK(&tc->disconnect_phy_work, intel_tc_port_disconnect_phy_work); + tc->legacy_port = is_legacy; + tc->mode = TC_PORT_DISCONNECTED; + tc->link_refcount = 0; + tc_port_load_fia_params(i915, tc); intel_tc_port_init_mode(dig_port); } diff --git a/drivers/gpu/drm/i915/display/intel_tc.h b/drivers/gpu/drm/i915/display/intel_tc.h index 79667d977508..cc3a7fd4ac10 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.h +++ b/drivers/gpu/drm/i915/display/intel_tc.h @@ -9,10 +9,36 @@ #include #include +#include "intel_display.h" +#include "intel_display_power.h" +#include "intel_wakeref.h" + struct intel_crtc_state; struct intel_digital_port; struct intel_encoder; +enum tc_port_mode { + TC_PORT_DISCONNECTED, + TC_PORT_TBT_ALT, + TC_PORT_DP_ALT, + TC_PORT_LEGACY, +}; + +struct intel_tc_port { + struct intel_digital_port *dig_port; + struct mutex lock; /* protects the TypeC port mode */ + intel_wakeref_t lock_wakeref; + enum intel_display_power_domain lock_power_domain; + struct delayed_work disconnect_phy_work; + int link_refcount; + bool legacy_port:1; + char port_name[8]; + enum tc_port_mode mode; + enum tc_port_mode init_mode; + enum phy_fia phy_fia; + u8 phy_fia_idx; +}; + bool intel_tc_port_in_tbt_alt_mode(struct intel_digital_port *dig_port); bool intel_tc_port_in_dp_alt_mode(struct intel_digital_port *dig_port); bool intel_tc_port_in_legacy_mode(struct intel_digital_port *dig_port); -- cgit v1.2.3-59-g8ed1b From 711762415ddacf54b1c973b208073438de5879b4 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:12 +0200 Subject: drm/i915/tc: Check for TC PHY explicitly in intel_tc_port_fia_max_lane_count() Check explicitly if the port passed to intel_tc_port_fia_max_lane_count() has a TC PHY, instead of relying on the default TC mode value set for non-TC PHY ports. Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-7-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index d6fc9c5bd979..4995c635d445 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -188,10 +188,11 @@ int intel_tc_port_fia_max_lane_count(struct intel_digital_port *dig_port) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); struct intel_tc_port *tc = to_tc_port(dig_port); + enum phy phy = intel_port_to_phy(i915, dig_port->base.port); intel_wakeref_t wakeref; u32 lane_mask; - if (tc->mode != TC_PORT_DP_ALT) + if (!intel_phy_is_tc(i915, phy) || tc->mode != TC_PORT_DP_ALT) return 4; assert_tc_cold_blocked(tc); -- cgit v1.2.3-59-g8ed1b From c5879999641f7860495cb9655de6775c96999103 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:13 +0200 Subject: drm/i915/tc: Move the intel_tc_port struct declaration to intel_tc.c Move the intel_tc_port struct to intel_tc.c for better isolation. This requires allocating the struct dynamically. Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-8-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 7 ++-- drivers/gpu/drm/i915/display/intel_display_types.h | 4 +- drivers/gpu/drm/i915/display/intel_tc.c | 45 ++++++++++++++++++++-- drivers/gpu/drm/i915/display/intel_tc.h | 30 +-------------- 4 files changed, 49 insertions(+), 37 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 73240cf78c8b..dac3ec8fbbc1 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3843,7 +3843,7 @@ static void intel_ddi_encoder_destroy(struct drm_encoder *encoder) intel_dp_encoder_flush_work(encoder); if (intel_phy_is_tc(i915, phy)) - intel_tc_port_flush_work(dig_port); + intel_tc_port_cleanup(dig_port); intel_display_power_flush_work(i915); drm_encoder_cleanup(encoder); @@ -4284,7 +4284,7 @@ static void intel_ddi_encoder_shutdown(struct intel_encoder *encoder) if (!intel_phy_is_tc(i915, phy)) return; - intel_tc_port_flush_work(dig_port); + intel_tc_port_cleanup(dig_port); } #define port_tc_name(port) ((port) - PORT_TC1 + '1') @@ -4541,7 +4541,8 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) is_legacy ? "legacy" : "non-legacy"); } - intel_tc_port_init(dig_port, is_legacy); + if (intel_tc_port_init(dig_port, is_legacy) < 0) + goto err; encoder->update_prepare = intel_ddi_update_prepare; encoder->update_complete = intel_ddi_update_complete; diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index 3dfc8eb45020..a3ea929b0535 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -54,13 +54,13 @@ #include "intel_display_power.h" #include "intel_dpll_mgr.h" #include "intel_wm_types.h" -#include "intel_tc.h" struct drm_printer; struct __intel_global_objs_state; struct intel_ddi_buf_trans; struct intel_fbc; struct intel_connector; +struct intel_tc_port; /* * Display related stuff @@ -1783,7 +1783,7 @@ struct intel_digital_port { intel_wakeref_t ddi_io_wakeref; intel_wakeref_t aux_wakeref; - struct intel_tc_port tc; + struct intel_tc_port *tc; /* protects num_hdcp_streams reference count, hdcp_port_data and hdcp_auth_status */ struct mutex hdcp_mutex; diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 4995c635d445..f43e48c9a067 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -15,6 +15,28 @@ #include "intel_mg_phy_regs.h" #include "intel_tc.h" +enum tc_port_mode { + TC_PORT_DISCONNECTED, + TC_PORT_TBT_ALT, + TC_PORT_DP_ALT, + TC_PORT_LEGACY, +}; + +struct intel_tc_port { + struct intel_digital_port *dig_port; + struct mutex lock; /* protects the TypeC port mode */ + intel_wakeref_t lock_wakeref; + enum intel_display_power_domain lock_power_domain; + struct delayed_work disconnect_phy_work; + int link_refcount; + bool legacy_port:1; + char port_name[8]; + enum tc_port_mode mode; + enum tc_port_mode init_mode; + enum phy_fia phy_fia; + u8 phy_fia_idx; +}; + static u32 tc_phy_hpd_live_status(struct intel_tc_port *tc); static bool tc_phy_is_ready(struct intel_tc_port *tc); static bool tc_phy_take_ownership(struct intel_tc_port *tc, bool take); @@ -36,7 +58,7 @@ static const char *tc_port_mode_name(enum tc_port_mode mode) static struct intel_tc_port *to_tc_port(struct intel_digital_port *dig_port) { - return &dig_port->tc; + return dig_port->tc; } static struct drm_i915_private *tc_to_i915(struct intel_tc_port *tc) @@ -1158,16 +1180,21 @@ tc_port_load_fia_params(struct drm_i915_private *i915, struct intel_tc_port *tc) } } -void intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy) +int intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); - struct intel_tc_port *tc = to_tc_port(dig_port); + struct intel_tc_port *tc; enum port port = dig_port->base.port; enum tc_port tc_port = intel_port_to_tc(i915, port); if (drm_WARN_ON(&i915->drm, tc_port == TC_PORT_NONE)) - return; + return -EINVAL; + + tc = kzalloc(sizeof(*tc), GFP_KERNEL); + if (!tc) + return -ENOMEM; + dig_port->tc = tc; tc->dig_port = dig_port; snprintf(tc->port_name, sizeof(tc->port_name), @@ -1181,4 +1208,14 @@ void intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy) tc_port_load_fia_params(i915, tc); intel_tc_port_init_mode(dig_port); + + return 0; +} + +void intel_tc_port_cleanup(struct intel_digital_port *dig_port) +{ + intel_tc_port_flush_work(dig_port); + + kfree(dig_port->tc); + dig_port->tc = NULL; } diff --git a/drivers/gpu/drm/i915/display/intel_tc.h b/drivers/gpu/drm/i915/display/intel_tc.h index cc3a7fd4ac10..dd0810f9ea95 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.h +++ b/drivers/gpu/drm/i915/display/intel_tc.h @@ -6,39 +6,12 @@ #ifndef __INTEL_TC_H__ #define __INTEL_TC_H__ -#include #include -#include "intel_display.h" -#include "intel_display_power.h" -#include "intel_wakeref.h" - struct intel_crtc_state; struct intel_digital_port; struct intel_encoder; -enum tc_port_mode { - TC_PORT_DISCONNECTED, - TC_PORT_TBT_ALT, - TC_PORT_DP_ALT, - TC_PORT_LEGACY, -}; - -struct intel_tc_port { - struct intel_digital_port *dig_port; - struct mutex lock; /* protects the TypeC port mode */ - intel_wakeref_t lock_wakeref; - enum intel_display_power_domain lock_power_domain; - struct delayed_work disconnect_phy_work; - int link_refcount; - bool legacy_port:1; - char port_name[8]; - enum tc_port_mode mode; - enum tc_port_mode init_mode; - enum phy_fia phy_fia; - u8 phy_fia_idx; -}; - bool intel_tc_port_in_tbt_alt_mode(struct intel_digital_port *dig_port); bool intel_tc_port_in_dp_alt_mode(struct intel_digital_port *dig_port); bool intel_tc_port_in_legacy_mode(struct intel_digital_port *dig_port); @@ -63,7 +36,8 @@ void intel_tc_port_get_link(struct intel_digital_port *dig_port, void intel_tc_port_put_link(struct intel_digital_port *dig_port); bool intel_tc_port_ref_held(struct intel_digital_port *dig_port); -void intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy); +int intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy); +void intel_tc_port_cleanup(struct intel_digital_port *dig_port); bool intel_tc_cold_requires_aux_pw(struct intel_digital_port *dig_port); -- cgit v1.2.3-59-g8ed1b From 34a658b7e7128b35daf71cc003fbb659f914f7a7 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:14 +0200 Subject: drm/i915/tc: Add TC PHY hook to get the PHY HPD live status Add a table of TC PHY hooks which can be used to call platform specific TC PHY handlers, replacing the corresponding if ladders. Add the hook to retrieve the PHY's HPD live status. Move the common part fixing up the VBT legacy port flag to the generic helper. Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-9-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 40 ++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 11 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index f43e48c9a067..2556fea500d7 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -22,8 +22,17 @@ enum tc_port_mode { TC_PORT_LEGACY, }; +struct intel_tc_port; + +struct intel_tc_phy_ops { + u32 (*hpd_live_status)(struct intel_tc_port *tc); +}; + struct intel_tc_port { struct intel_digital_port *dig_port; + + const struct intel_tc_phy_ops *phy_ops; + struct mutex lock; /* protects the TypeC port mode */ intel_wakeref_t lock_wakeref; enum intel_display_power_domain lock_power_domain; @@ -329,10 +338,6 @@ static u32 icl_tc_phy_hpd_live_status(struct intel_tc_port *tc) if (intel_de_read(i915, SDEISR) & isr_bit) mask |= BIT(TC_PORT_LEGACY); - /* The sink can be connected only in a single mode. */ - if (!drm_WARN_ON_ONCE(&i915->drm, hweight32(mask) > 1)) - tc_port_fixup_legacy_flag(tc, mask); - return mask; } @@ -495,6 +500,10 @@ static void icl_tc_phy_disconnect(struct intel_tc_port *tc) } } +static const struct intel_tc_phy_ops icl_tc_phy_ops = { + .hpd_live_status = icl_tc_phy_hpd_live_status, +}; + /* * ADLP TC PHY handlers * -------------------- @@ -521,10 +530,6 @@ static u32 adlp_tc_phy_hpd_live_status(struct intel_tc_port *tc) if (intel_de_read(i915, SDEISR) & isr_bit) mask |= BIT(TC_PORT_LEGACY); - /* The sink can be connected only in a single mode. */ - if (!drm_WARN_ON(&i915->drm, hweight32(mask) > 1)) - tc_port_fixup_legacy_flag(tc, mask); - return mask; } @@ -574,6 +579,10 @@ static bool adlp_tc_phy_is_owned(struct intel_tc_port *tc) return val & DDI_BUF_CTL_TC_PHY_OWNERSHIP; } +static const struct intel_tc_phy_ops adlp_tc_phy_ops = { + .hpd_live_status = adlp_tc_phy_hpd_live_status, +}; + /* * Generic TC PHY handlers * ----------------------- @@ -581,11 +590,15 @@ static bool adlp_tc_phy_is_owned(struct intel_tc_port *tc) static u32 tc_phy_hpd_live_status(struct intel_tc_port *tc) { struct drm_i915_private *i915 = tc_to_i915(tc); + u32 mask; - if (IS_ALDERLAKE_P(i915)) - return adlp_tc_phy_hpd_live_status(tc); + mask = tc->phy_ops->hpd_live_status(tc); + + /* The sink can be connected only in a single mode. */ + if (!drm_WARN_ON_ONCE(&i915->drm, hweight32(mask) > 1)) + tc_port_fixup_legacy_flag(tc, mask); - return icl_tc_phy_hpd_live_status(tc); + return mask; } static bool tc_phy_is_ready(struct intel_tc_port *tc) @@ -1197,6 +1210,11 @@ int intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy) dig_port->tc = tc; tc->dig_port = dig_port; + if (DISPLAY_VER(i915) >= 13) + tc->phy_ops = &adlp_tc_phy_ops; + else + tc->phy_ops = &icl_tc_phy_ops; + snprintf(tc->port_name, sizeof(tc->port_name), "%c/TC#%d", port_name(port), tc_port + 1); -- cgit v1.2.3-59-g8ed1b From 87107261bb73d7a8945f3cd37a6abc7befc327bf Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:15 +0200 Subject: drm/i915/tc: Add TC PHY hooks to get the PHY ready/owned state Add TC PHY hooks to get the PHY ready/owned state on each platform, replacing the corresponding if ladder. Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-10-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 2556fea500d7..052103c87a39 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -26,6 +26,8 @@ struct intel_tc_port; struct intel_tc_phy_ops { u32 (*hpd_live_status)(struct intel_tc_port *tc); + bool (*is_ready)(struct intel_tc_port *tc); + bool (*is_owned)(struct intel_tc_port *tc); }; struct intel_tc_port { @@ -502,6 +504,8 @@ static void icl_tc_phy_disconnect(struct intel_tc_port *tc) static const struct intel_tc_phy_ops icl_tc_phy_ops = { .hpd_live_status = icl_tc_phy_hpd_live_status, + .is_ready = icl_tc_phy_is_ready, + .is_owned = icl_tc_phy_is_owned, }; /* @@ -581,6 +585,8 @@ static bool adlp_tc_phy_is_owned(struct intel_tc_port *tc) static const struct intel_tc_phy_ops adlp_tc_phy_ops = { .hpd_live_status = adlp_tc_phy_hpd_live_status, + .is_ready = adlp_tc_phy_is_ready, + .is_owned = adlp_tc_phy_is_owned, }; /* @@ -603,22 +609,12 @@ static u32 tc_phy_hpd_live_status(struct intel_tc_port *tc) static bool tc_phy_is_ready(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = tc_to_i915(tc); - - if (IS_ALDERLAKE_P(i915)) - return adlp_tc_phy_is_ready(tc); - - return icl_tc_phy_is_ready(tc); + return tc->phy_ops->is_ready(tc); } static bool tc_phy_is_owned(struct intel_tc_port *tc) { - struct drm_i915_private *i915 = tc_to_i915(tc); - - if (IS_ALDERLAKE_P(i915)) - return adlp_tc_phy_is_owned(tc); - - return icl_tc_phy_is_owned(tc); + return tc->phy_ops->is_owned(tc); } static bool tc_phy_take_ownership(struct intel_tc_port *tc, bool take) -- cgit v1.2.3-59-g8ed1b From ab639f326e48385eeaf65fd129d3ff6d006cbeef Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:16 +0200 Subject: drm/i915/tc: Add TC PHY hook to read out the PHY HW state Add a TC PHY hook to read out the PHY HW state on each platform, move the common parts to the generic helper. Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-11-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 34 +++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 052103c87a39..433f3c435126 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -28,6 +28,7 @@ struct intel_tc_phy_ops { u32 (*hpd_live_status)(struct intel_tc_port *tc); bool (*is_ready)(struct intel_tc_port *tc); bool (*is_owned)(struct intel_tc_port *tc); + void (*get_hw_state)(struct intel_tc_port *tc); }; struct intel_tc_port { @@ -51,6 +52,7 @@ struct intel_tc_port { static u32 tc_phy_hpd_live_status(struct intel_tc_port *tc); static bool tc_phy_is_ready(struct intel_tc_port *tc); static bool tc_phy_take_ownership(struct intel_tc_port *tc, bool take); +static enum tc_port_mode tc_phy_get_current_mode(struct intel_tc_port *tc); static const char *tc_port_mode_name(enum tc_port_mode mode) { @@ -407,6 +409,20 @@ static bool icl_tc_phy_is_owned(struct intel_tc_port *tc) return val & DP_PHY_MODE_STATUS_NOT_SAFE(tc->phy_fia_idx); } +static void icl_tc_phy_get_hw_state(struct intel_tc_port *tc) +{ + enum intel_display_power_domain domain; + intel_wakeref_t tc_cold_wref; + + tc_cold_wref = tc_cold_block(tc, &domain); + + tc->mode = tc_phy_get_current_mode(tc); + if (tc->mode != TC_PORT_DISCONNECTED) + tc->lock_wakeref = tc_cold_block(tc, &tc->lock_power_domain); + + tc_cold_unblock(tc, domain, tc_cold_wref); +} + /* * This function implements the first part of the Connect Flow described by our * specification, Gen11 TypeC Programming chapter. The rest of the flow (reading @@ -506,6 +522,7 @@ static const struct intel_tc_phy_ops icl_tc_phy_ops = { .hpd_live_status = icl_tc_phy_hpd_live_status, .is_ready = icl_tc_phy_is_ready, .is_owned = icl_tc_phy_is_owned, + .get_hw_state = icl_tc_phy_get_hw_state, }; /* @@ -587,6 +604,7 @@ static const struct intel_tc_phy_ops adlp_tc_phy_ops = { .hpd_live_status = adlp_tc_phy_hpd_live_status, .is_ready = adlp_tc_phy_is_ready, .is_owned = adlp_tc_phy_is_owned, + .get_hw_state = icl_tc_phy_get_hw_state, }; /* @@ -617,6 +635,11 @@ static bool tc_phy_is_owned(struct intel_tc_port *tc) return tc->phy_ops->is_owned(tc); } +static void tc_phy_get_hw_state(struct intel_tc_port *tc) +{ + tc->phy_ops->get_hw_state(tc); +} + static bool tc_phy_take_ownership(struct intel_tc_port *tc, bool take) { struct drm_i915_private *i915 = tc_to_i915(tc); @@ -889,8 +912,6 @@ void intel_tc_port_init_mode(struct intel_digital_port *dig_port) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); struct intel_tc_port *tc = to_tc_port(dig_port); - intel_wakeref_t tc_cold_wref; - enum intel_display_power_domain domain; bool update_mode = false; mutex_lock(&tc->lock); @@ -899,17 +920,12 @@ void intel_tc_port_init_mode(struct intel_digital_port *dig_port) drm_WARN_ON(&i915->drm, tc->lock_wakeref); drm_WARN_ON(&i915->drm, tc->link_refcount); - tc_cold_wref = tc_cold_block(tc, &domain); - - tc->mode = tc_phy_get_current_mode(tc); + tc_phy_get_hw_state(tc); /* * Save the initial mode for the state check in * intel_tc_port_sanitize_mode(). */ tc->init_mode = tc->mode; - if (tc->mode != TC_PORT_DISCONNECTED) - tc->lock_wakeref = - tc_cold_block(tc, &tc->lock_power_domain); /* * The PHY needs to be connected for AUX to work during HW readout and @@ -938,8 +954,6 @@ void intel_tc_port_init_mode(struct intel_digital_port *dig_port) /* Prevent changing tc->mode until intel_tc_port_sanitize_mode() is called. */ __intel_tc_port_get_link(tc); - tc_cold_unblock(tc, domain, tc_cold_wref); - mutex_unlock(&tc->lock); } -- cgit v1.2.3-59-g8ed1b From d1fc4e391fbd321dff166208e58e30d3196626ba Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:17 +0200 Subject: drm/i915/tc: Add generic TC PHY connect/disconnect handlers Add generic handlers to connect/disconnect a PHY. Setting the TC mode to the target mode deducted from the HPD state and - if connecting to this mode fails - falling back to connecting to the default (TBT) mode are common to all platforms; move the logic for this from the ICL specific connect / disconnect handlers to the generic ones. Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-12-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 65 ++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 26 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 433f3c435126..2910921483c0 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -434,41 +434,35 @@ static void icl_tc_phy_get_hw_state(struct intel_tc_port *tc) * connect and disconnect to cleanly transfer ownership with the controller and * set the type-C power state. */ -static void icl_tc_phy_connect(struct intel_tc_port *tc, +static bool icl_tc_phy_connect(struct intel_tc_port *tc, int required_lanes) { struct drm_i915_private *i915 = tc_to_i915(tc); struct intel_digital_port *dig_port = tc->dig_port; - u32 live_status_mask; int max_lanes; + if (tc->mode == TC_PORT_TBT_ALT) + return true; + if (!tc_phy_is_ready(tc) && !drm_WARN_ON(&i915->drm, tc->legacy_port)) { drm_dbg_kms(&i915->drm, "Port %s: PHY not ready\n", tc->port_name); - goto out_set_tbt_alt_mode; - } - - live_status_mask = tc_phy_hpd_live_status(tc); - if (!(live_status_mask & (BIT(TC_PORT_DP_ALT) | BIT(TC_PORT_LEGACY))) && - !tc->legacy_port) { - drm_dbg_kms(&i915->drm, "Port %s: PHY ownership not required (live status %02x)\n", - tc->port_name, live_status_mask); - goto out_set_tbt_alt_mode; + return false; } if (!tc_phy_take_ownership(tc, true) && !drm_WARN_ON(&i915->drm, tc->legacy_port)) - goto out_set_tbt_alt_mode; + return false; max_lanes = intel_tc_port_fia_max_lane_count(dig_port); if (tc->legacy_port) { drm_WARN_ON(&i915->drm, max_lanes != 4); - tc->mode = TC_PORT_LEGACY; - - return; + return true; } + drm_WARN_ON(&i915->drm, tc->mode != TC_PORT_DP_ALT); + /* * Now we have to re-check the live state, in case the port recently * became disconnected. Not necessary for legacy mode. @@ -487,14 +481,12 @@ static void icl_tc_phy_connect(struct intel_tc_port *tc, goto out_release_phy; } - tc->mode = TC_PORT_DP_ALT; - - return; + return true; out_release_phy: tc_phy_take_ownership(tc, false); -out_set_tbt_alt_mode: - tc->mode = TC_PORT_TBT_ALT; + + return false; } /* @@ -509,9 +501,6 @@ static void icl_tc_phy_disconnect(struct intel_tc_port *tc) tc_phy_take_ownership(tc, false); fallthrough; case TC_PORT_TBT_ALT: - tc->mode = TC_PORT_DISCONNECTED; - fallthrough; - case TC_PORT_DISCONNECTED: break; default: MISSING_CASE(tc->mode); @@ -817,6 +806,30 @@ tc_phy_get_target_mode(struct intel_tc_port *tc) return hpd_mask_to_target_mode(tc, live_status_mask); } +static void tc_phy_connect(struct intel_tc_port *tc, int required_lanes) +{ + struct drm_i915_private *i915 = tc_to_i915(tc); + bool connected; + + tc->mode = tc_phy_get_target_mode(tc); + + connected = icl_tc_phy_connect(tc, required_lanes); + if (!connected && tc->mode != default_tc_mode(tc)) { + tc->mode = default_tc_mode(tc); + connected = icl_tc_phy_connect(tc, required_lanes); + } + + drm_WARN_ON(&i915->drm, !connected); +} + +static void tc_phy_disconnect(struct intel_tc_port *tc) +{ + if (tc->mode != TC_PORT_DISCONNECTED) { + icl_tc_phy_disconnect(tc); + tc->mode = TC_PORT_DISCONNECTED; + } +} + static void intel_tc_port_reset_mode(struct intel_tc_port *tc, int required_lanes, bool force_disconnect) { @@ -834,9 +847,9 @@ static void intel_tc_port_reset_mode(struct intel_tc_port *tc, drm_WARN_ON(&i915->drm, aux_powered); } - icl_tc_phy_disconnect(tc); + tc_phy_disconnect(tc); if (!force_disconnect) - icl_tc_phy_connect(tc, required_lanes); + tc_phy_connect(tc, required_lanes); drm_dbg_kms(&i915->drm, "Port %s: TC port mode reset (%s -> %s)\n", tc->port_name, @@ -1015,7 +1028,7 @@ void intel_tc_port_sanitize_mode(struct intel_digital_port *dig_port, "Port %s: PHY left in %s mode on disabled port, disconnecting it\n", tc->port_name, tc_port_mode_name(tc->init_mode)); - icl_tc_phy_disconnect(tc); + tc_phy_disconnect(tc); __intel_tc_port_put_link(tc); tc_cold_unblock(tc, tc->lock_power_domain, -- cgit v1.2.3-59-g8ed1b From 712f422ed70c6778018152896d6b4e5ff70fb2b4 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:18 +0200 Subject: drm/i915/tc: Factor out tc_phy_verify_legacy_or_dp_alt_mode() Factor out a function verifying the PHY connected state in legacy or DP-alt mode. This is common to all platforms, which can be reused in platform specific connect hooks added in follow-up patches. No functional changes. Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-13-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 47 ++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 18 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 2910921483c0..bf83e6794054 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -434,27 +434,13 @@ static void icl_tc_phy_get_hw_state(struct intel_tc_port *tc) * connect and disconnect to cleanly transfer ownership with the controller and * set the type-C power state. */ -static bool icl_tc_phy_connect(struct intel_tc_port *tc, - int required_lanes) +static bool tc_phy_verify_legacy_or_dp_alt_mode(struct intel_tc_port *tc, + int required_lanes) { struct drm_i915_private *i915 = tc_to_i915(tc); struct intel_digital_port *dig_port = tc->dig_port; int max_lanes; - if (tc->mode == TC_PORT_TBT_ALT) - return true; - - if (!tc_phy_is_ready(tc) && - !drm_WARN_ON(&i915->drm, tc->legacy_port)) { - drm_dbg_kms(&i915->drm, "Port %s: PHY not ready\n", - tc->port_name); - return false; - } - - if (!tc_phy_take_ownership(tc, true) && - !drm_WARN_ON(&i915->drm, tc->legacy_port)) - return false; - max_lanes = intel_tc_port_fia_max_lane_count(dig_port); if (tc->legacy_port) { drm_WARN_ON(&i915->drm, max_lanes != 4); @@ -470,7 +456,7 @@ static bool icl_tc_phy_connect(struct intel_tc_port *tc, if (!(tc_phy_hpd_live_status(tc) & BIT(TC_PORT_DP_ALT))) { drm_dbg_kms(&i915->drm, "Port %s: PHY sudden disconnect\n", tc->port_name); - goto out_release_phy; + return false; } if (max_lanes < required_lanes) { @@ -478,9 +464,34 @@ static bool icl_tc_phy_connect(struct intel_tc_port *tc, "Port %s: PHY max lanes %d < required lanes %d\n", tc->port_name, max_lanes, required_lanes); - goto out_release_phy; + return false; + } + + return true; +} + +static bool icl_tc_phy_connect(struct intel_tc_port *tc, + int required_lanes) +{ + struct drm_i915_private *i915 = tc_to_i915(tc); + + if (tc->mode == TC_PORT_TBT_ALT) + return true; + + if (!tc_phy_is_ready(tc) && + !drm_WARN_ON(&i915->drm, tc->legacy_port)) { + drm_dbg_kms(&i915->drm, "Port %s: PHY not ready\n", + tc->port_name); + return false; } + if (!tc_phy_take_ownership(tc, true) && + !drm_WARN_ON(&i915->drm, tc->legacy_port)) + return false; + + if (!tc_phy_verify_legacy_or_dp_alt_mode(tc, required_lanes)) + goto out_release_phy; + return true; out_release_phy: -- cgit v1.2.3-59-g8ed1b From bd0fdd31c1023b9d94a470ed5bc301c3f9d80519 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:19 +0200 Subject: drm/i915/tc: Add TC PHY hooks to connect/disconnect the PHY Add TC PHY hooks to connect/disconnect the PHY. A follow-up patch will add the ADLP specific hooks for these. Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-14-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index bf83e6794054..cdac808aac3c 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -29,6 +29,8 @@ struct intel_tc_phy_ops { bool (*is_ready)(struct intel_tc_port *tc); bool (*is_owned)(struct intel_tc_port *tc); void (*get_hw_state)(struct intel_tc_port *tc); + bool (*connect)(struct intel_tc_port *tc, int required_lanes); + void (*disconnect)(struct intel_tc_port *tc); }; struct intel_tc_port { @@ -523,6 +525,8 @@ static const struct intel_tc_phy_ops icl_tc_phy_ops = { .is_ready = icl_tc_phy_is_ready, .is_owned = icl_tc_phy_is_owned, .get_hw_state = icl_tc_phy_get_hw_state, + .connect = icl_tc_phy_connect, + .disconnect = icl_tc_phy_disconnect, }; /* @@ -605,6 +609,8 @@ static const struct intel_tc_phy_ops adlp_tc_phy_ops = { .is_ready = adlp_tc_phy_is_ready, .is_owned = adlp_tc_phy_is_owned, .get_hw_state = icl_tc_phy_get_hw_state, + .connect = icl_tc_phy_connect, + .disconnect = icl_tc_phy_disconnect, }; /* @@ -824,10 +830,10 @@ static void tc_phy_connect(struct intel_tc_port *tc, int required_lanes) tc->mode = tc_phy_get_target_mode(tc); - connected = icl_tc_phy_connect(tc, required_lanes); + connected = tc->phy_ops->connect(tc, required_lanes); if (!connected && tc->mode != default_tc_mode(tc)) { tc->mode = default_tc_mode(tc); - connected = icl_tc_phy_connect(tc, required_lanes); + connected = tc->phy_ops->connect(tc, required_lanes); } drm_WARN_ON(&i915->drm, !connected); @@ -836,7 +842,7 @@ static void tc_phy_connect(struct intel_tc_port *tc, int required_lanes) static void tc_phy_disconnect(struct intel_tc_port *tc) { if (tc->mode != TC_PORT_DISCONNECTED) { - icl_tc_phy_disconnect(tc); + tc->phy_ops->disconnect(tc); tc->mode = TC_PORT_DISCONNECTED; } } -- cgit v1.2.3-59-g8ed1b From 3b7d5663702373358d58987a3684f6c59443d9d4 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:20 +0200 Subject: drm/i915/tc: Fix up the legacy VBT flag only in disconnected mode A follow-up patch simplifies the tc_cold_block()/unblock() functions, dropping the power domain parameter. For this it must be ensured that the power domain - which depends on the actual TC mode and so the VBT legacy port flag - can't change while the PHY is in a connected state and accordingly TC-cold is blocked. Make this so, by fixing up the VBT legacy flag only in the disconnected TC mode, instead of whenever the HPD state is retrieved. Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-15-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index cdac808aac3c..b4e5de676816 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -298,6 +298,11 @@ static void tc_port_fixup_legacy_flag(struct intel_tc_port *tc, struct drm_i915_private *i915 = tc_to_i915(tc); u32 valid_hpd_mask; + drm_WARN_ON(&i915->drm, tc->mode != TC_PORT_DISCONNECTED); + + if (hweight32(live_status_mask) != 1) + return; + if (tc->legacy_port) valid_hpd_mask = BIT(TC_PORT_LEGACY); else @@ -625,8 +630,7 @@ static u32 tc_phy_hpd_live_status(struct intel_tc_port *tc) mask = tc->phy_ops->hpd_live_status(tc); /* The sink can be connected only in a single mode. */ - if (!drm_WARN_ON_ONCE(&i915->drm, hweight32(mask) > 1)) - tc_port_fixup_legacy_flag(tc, mask); + drm_WARN_ON_ONCE(&i915->drm, hweight32(mask) > 1); return mask; } @@ -826,9 +830,12 @@ tc_phy_get_target_mode(struct intel_tc_port *tc) static void tc_phy_connect(struct intel_tc_port *tc, int required_lanes) { struct drm_i915_private *i915 = tc_to_i915(tc); + u32 live_status_mask = tc_phy_hpd_live_status(tc); bool connected; - tc->mode = tc_phy_get_target_mode(tc); + tc_port_fixup_legacy_flag(tc, live_status_mask); + + tc->mode = hpd_mask_to_target_mode(tc, live_status_mask); connected = tc->phy_ops->connect(tc, required_lanes); if (!connected && tc->mode != default_tc_mode(tc)) { -- cgit v1.2.3-59-g8ed1b From e0b1ef58d98ae0feba98190c9faf192aabceb811 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:21 +0200 Subject: drm/i915/tc: Check TC mode instead of the VBT legacy flag After the previous patch the TC mode in the connect/disconnect functions is always in sync with the VBT legacy port flag, so for consistency with the rest of the function check the TC mode instead of the VBT flag. Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-16-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index b4e5de676816..8cae650d2880 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -449,7 +449,7 @@ static bool tc_phy_verify_legacy_or_dp_alt_mode(struct intel_tc_port *tc, int max_lanes; max_lanes = intel_tc_port_fia_max_lane_count(dig_port); - if (tc->legacy_port) { + if (tc->mode == TC_PORT_LEGACY) { drm_WARN_ON(&i915->drm, max_lanes != 4); return true; } @@ -485,16 +485,15 @@ static bool icl_tc_phy_connect(struct intel_tc_port *tc, if (tc->mode == TC_PORT_TBT_ALT) return true; - if (!tc_phy_is_ready(tc) && - !drm_WARN_ON(&i915->drm, tc->legacy_port)) { - drm_dbg_kms(&i915->drm, "Port %s: PHY not ready\n", - tc->port_name); + if ((!tc_phy_is_ready(tc) || + !tc_phy_take_ownership(tc, true)) && + !drm_WARN_ON(&i915->drm, tc->mode == TC_PORT_LEGACY)) { + drm_dbg_kms(&i915->drm, "Port %s: can't take PHY ownership (ready %s)\n", + tc->port_name, + str_yes_no(tc_phy_is_ready(tc))); return false; } - if (!tc_phy_take_ownership(tc, true) && - !drm_WARN_ON(&i915->drm, tc->legacy_port)) - return false; if (!tc_phy_verify_legacy_or_dp_alt_mode(tc, required_lanes)) goto out_release_phy; -- cgit v1.2.3-59-g8ed1b From 976a368b7198bf666ad3d273e10ed82b3713af3b Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:22 +0200 Subject: drm/i915/tc: Block/unblock TC-cold in the PHY connect/disconnect hooks Move blocking/unblocking the TC-cold power state to the platform specific PHY connect / disconnect hooks. This allows for adjusting the connect/disconnect sequence as required for each platform. Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-17-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 43 ++++++++++----------------------- 1 file changed, 13 insertions(+), 30 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 8cae650d2880..7b1b4d68753d 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -482,6 +482,8 @@ static bool icl_tc_phy_connect(struct intel_tc_port *tc, { struct drm_i915_private *i915 = tc_to_i915(tc); + tc->lock_wakeref = tc_cold_block(tc, &tc->lock_power_domain); + if (tc->mode == TC_PORT_TBT_ALT) return true; @@ -491,7 +493,7 @@ static bool icl_tc_phy_connect(struct intel_tc_port *tc, drm_dbg_kms(&i915->drm, "Port %s: can't take PHY ownership (ready %s)\n", tc->port_name, str_yes_no(tc_phy_is_ready(tc))); - return false; + goto out_unblock_tc_cold; } @@ -502,6 +504,10 @@ static bool icl_tc_phy_connect(struct intel_tc_port *tc, out_release_phy: tc_phy_take_ownership(tc, false); +out_unblock_tc_cold: + tc_cold_unblock(tc, + tc->lock_power_domain, + fetch_and_zero(&tc->lock_wakeref)); return false; } @@ -518,6 +524,9 @@ static void icl_tc_phy_disconnect(struct intel_tc_port *tc) tc_phy_take_ownership(tc, false); fallthrough; case TC_PORT_TBT_ALT: + tc_cold_unblock(tc, + tc->lock_power_domain, + fetch_and_zero(&tc->lock_wakeref)); break; default: MISSING_CASE(tc->mode); @@ -888,32 +897,9 @@ static bool intel_tc_port_needs_reset(struct intel_tc_port *tc) static void intel_tc_port_update_mode(struct intel_tc_port *tc, int required_lanes, bool force_disconnect) { - enum intel_display_power_domain domain; - intel_wakeref_t wref; - bool needs_reset = force_disconnect; - - if (!needs_reset) { - /* Get power domain required to check the hotplug live status. */ - wref = tc_cold_block(tc, &domain); - needs_reset = intel_tc_port_needs_reset(tc); - tc_cold_unblock(tc, domain, wref); - } - - if (!needs_reset) - return; - - /* Get power domain required for resetting the mode. */ - wref = tc_cold_block_in_mode(tc, TC_PORT_DISCONNECTED, &domain); - - intel_tc_port_reset_mode(tc, required_lanes, force_disconnect); - - /* Get power domain matching the new mode after reset. */ - tc_cold_unblock(tc, tc->lock_power_domain, - fetch_and_zero(&tc->lock_wakeref)); - if (tc->mode != TC_PORT_DISCONNECTED) - tc->lock_wakeref = tc_cold_block(tc, &tc->lock_power_domain); - - tc_cold_unblock(tc, domain, wref); + if (force_disconnect || + intel_tc_port_needs_reset(tc)) + intel_tc_port_reset_mode(tc, required_lanes, force_disconnect); } static void __intel_tc_port_get_link(struct intel_tc_port *tc) @@ -1053,9 +1039,6 @@ void intel_tc_port_sanitize_mode(struct intel_digital_port *dig_port, tc_port_mode_name(tc->init_mode)); tc_phy_disconnect(tc); __intel_tc_port_put_link(tc); - - tc_cold_unblock(tc, tc->lock_power_domain, - fetch_and_zero(&tc->lock_wakeref)); } drm_dbg_kms(&i915->drm, "Port %s: sanitize mode (%s)\n", -- cgit v1.2.3-59-g8ed1b From 430ce0c7d3a3b2cdfdafb527d2f89be4267ac45c Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:23 +0200 Subject: drm/i915/tc: Remove redundant wakeref=0 check from unblock_tc_cold() After the previous patch unblock_tc_cold() will not be called in a disconnected mode, so the wakeref passed to it will be always non-zero. Remove the redundant check. Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-18-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 7b1b4d68753d..02fdb8d37f3e 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -150,14 +150,6 @@ tc_cold_unblock(struct intel_tc_port *tc, enum intel_display_power_domain domain { struct drm_i915_private *i915 = tc_to_i915(tc); - /* - * wakeref == -1, means some error happened saving save_depot_stack but - * power should still be put down and 0 is a invalid save_depot_stack - * id so can be used to skip it for non TC legacy ports. - */ - if (wakeref == 0) - return; - intel_display_power_put(i915, domain, wakeref); } -- cgit v1.2.3-59-g8ed1b From bc5f983a3d8d8e5a5eddfaf11275bbcef04017f5 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:24 +0200 Subject: drm/i915/tc: Drop tc_cold_block()/unblock()'s power domain parameter Simplify tc_cold_block()/unblock() by dropping their power domain parameter. The power domain depends on the current TC mode, which - after the previous patch - can't change while the PHY is connected, holding a TC-cold-off power domain reference. Based on this the domain can be deducted from the current TC mode instead of having to pass this as a parameter. Blocking TC-cold for the PHY HW readout happens before the current TC mode is determined, so here the initial power domain must be still manually passed. For debugging still keep track of the domain used for tc_cold_block() and verify that it remained the same until tc_cold_unblock(). While at it rename tc_cold_get_power_domain() to tc_phy_cold_off_domain(), reflecting the name of platform specific hook added in the next patch. Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-19-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 61 ++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 24 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 02fdb8d37f3e..63886d719fa4 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -40,7 +40,9 @@ struct intel_tc_port { struct mutex lock; /* protects the TypeC port mode */ intel_wakeref_t lock_wakeref; +#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) enum intel_display_power_domain lock_power_domain; +#endif struct delayed_work disconnect_phy_work; int link_refcount; bool legacy_port:1; @@ -116,43 +118,60 @@ bool intel_tc_cold_requires_aux_pw(struct intel_digital_port *dig_port) } static enum intel_display_power_domain -tc_cold_get_power_domain(struct intel_tc_port *tc, enum tc_port_mode mode) +tc_phy_cold_off_domain(struct intel_tc_port *tc) { struct drm_i915_private *i915 = tc_to_i915(tc); struct intel_digital_port *dig_port = tc->dig_port; - if (mode == TC_PORT_TBT_ALT || !intel_tc_cold_requires_aux_pw(dig_port)) + if (tc->mode == TC_PORT_TBT_ALT || !intel_tc_cold_requires_aux_pw(dig_port)) return POWER_DOMAIN_TC_COLD_OFF; return intel_display_power_legacy_aux_domain(i915, dig_port->aux_ch); } static intel_wakeref_t -tc_cold_block_in_mode(struct intel_tc_port *tc, enum tc_port_mode mode, - enum intel_display_power_domain *domain) +__tc_cold_block(struct intel_tc_port *tc, enum intel_display_power_domain *domain) { struct drm_i915_private *i915 = tc_to_i915(tc); - *domain = tc_cold_get_power_domain(tc, mode); + *domain = tc_phy_cold_off_domain(tc); return intel_display_power_get(i915, *domain); } static intel_wakeref_t -tc_cold_block(struct intel_tc_port *tc, enum intel_display_power_domain *domain) +tc_cold_block(struct intel_tc_port *tc) { - return tc_cold_block_in_mode(tc, tc->mode, domain); + enum intel_display_power_domain domain; + intel_wakeref_t wakeref; + + wakeref = __tc_cold_block(tc, &domain); +#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) + tc->lock_power_domain = domain; +#endif + return wakeref; } static void -tc_cold_unblock(struct intel_tc_port *tc, enum intel_display_power_domain domain, - intel_wakeref_t wakeref) +__tc_cold_unblock(struct intel_tc_port *tc, enum intel_display_power_domain domain, + intel_wakeref_t wakeref) { struct drm_i915_private *i915 = tc_to_i915(tc); intel_display_power_put(i915, domain, wakeref); } +static void +tc_cold_unblock(struct intel_tc_port *tc, intel_wakeref_t wakeref) +{ + enum intel_display_power_domain domain = tc_phy_cold_off_domain(tc); + +#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM) + drm_WARN_ON(&tc_to_i915(tc)->drm, tc->lock_power_domain != domain); +#endif + __tc_cold_unblock(tc, domain, wakeref); +} + static void assert_tc_cold_blocked(struct intel_tc_port *tc) { @@ -160,8 +179,7 @@ assert_tc_cold_blocked(struct intel_tc_port *tc) bool enabled; enabled = intel_display_power_is_enabled(i915, - tc_cold_get_power_domain(tc, - tc->mode)); + tc_phy_cold_off_domain(tc)); drm_WARN_ON(&i915->drm, !enabled); } @@ -413,13 +431,13 @@ static void icl_tc_phy_get_hw_state(struct intel_tc_port *tc) enum intel_display_power_domain domain; intel_wakeref_t tc_cold_wref; - tc_cold_wref = tc_cold_block(tc, &domain); + tc_cold_wref = __tc_cold_block(tc, &domain); tc->mode = tc_phy_get_current_mode(tc); if (tc->mode != TC_PORT_DISCONNECTED) - tc->lock_wakeref = tc_cold_block(tc, &tc->lock_power_domain); + tc->lock_wakeref = tc_cold_block(tc); - tc_cold_unblock(tc, domain, tc_cold_wref); + __tc_cold_unblock(tc, domain, tc_cold_wref); } /* @@ -474,7 +492,7 @@ static bool icl_tc_phy_connect(struct intel_tc_port *tc, { struct drm_i915_private *i915 = tc_to_i915(tc); - tc->lock_wakeref = tc_cold_block(tc, &tc->lock_power_domain); + tc->lock_wakeref = tc_cold_block(tc); if (tc->mode == TC_PORT_TBT_ALT) return true; @@ -497,9 +515,7 @@ static bool icl_tc_phy_connect(struct intel_tc_port *tc, out_release_phy: tc_phy_take_ownership(tc, false); out_unblock_tc_cold: - tc_cold_unblock(tc, - tc->lock_power_domain, - fetch_and_zero(&tc->lock_wakeref)); + tc_cold_unblock(tc, fetch_and_zero(&tc->lock_wakeref)); return false; } @@ -516,9 +532,7 @@ static void icl_tc_phy_disconnect(struct intel_tc_port *tc) tc_phy_take_ownership(tc, false); fallthrough; case TC_PORT_TBT_ALT: - tc_cold_unblock(tc, - tc->lock_power_domain, - fetch_and_zero(&tc->lock_wakeref)); + tc_cold_unblock(tc, fetch_and_zero(&tc->lock_wakeref)); break; default: MISSING_CASE(tc->mode); @@ -1177,7 +1191,6 @@ void intel_tc_port_put_link(struct intel_digital_port *dig_port) static bool tc_has_modular_fia(struct drm_i915_private *i915, struct intel_tc_port *tc) { - enum intel_display_power_domain domain; intel_wakeref_t wakeref; u32 val; @@ -1185,9 +1198,9 @@ tc_has_modular_fia(struct drm_i915_private *i915, struct intel_tc_port *tc) return false; mutex_lock(&tc->lock); - wakeref = tc_cold_block(tc, &domain); + wakeref = tc_cold_block(tc); val = intel_de_read(i915, PORT_TX_DFLEXDPSP(FIA1)); - tc_cold_unblock(tc, domain, wakeref); + tc_cold_unblock(tc, wakeref); mutex_unlock(&tc->lock); drm_WARN_ON(&i915->drm, val == 0xffffffff); -- cgit v1.2.3-59-g8ed1b From 16cf693e31bdb423f35ab24081575ec9699303fc Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:25 +0200 Subject: drm/i915/tc: Add TC PHY hook to get the TC-cold blocking power domain Instead of the corresponding if ladder, add a TC PHY hook to get the platform and TC mode specific power domain used for blocking the TC-cold power state. Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-20-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 73 ++++++++++++++++++++++++++------- 1 file changed, 59 insertions(+), 14 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 63886d719fa4..3972b2457d11 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -25,6 +25,7 @@ enum tc_port_mode { struct intel_tc_port; struct intel_tc_phy_ops { + enum intel_display_power_domain (*cold_off_domain)(struct intel_tc_port *tc); u32 (*hpd_live_status)(struct intel_tc_port *tc); bool (*is_ready)(struct intel_tc_port *tc); bool (*is_owned)(struct intel_tc_port *tc); @@ -53,6 +54,8 @@ struct intel_tc_port { u8 phy_fia_idx; }; +static enum intel_display_power_domain +tc_phy_cold_off_domain(struct intel_tc_port *); static u32 tc_phy_hpd_live_status(struct intel_tc_port *tc); static bool tc_phy_is_ready(struct intel_tc_port *tc); static bool tc_phy_take_ownership(struct intel_tc_port *tc, bool take); @@ -113,20 +116,8 @@ bool intel_tc_cold_requires_aux_pw(struct intel_digital_port *dig_port) struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); struct intel_tc_port *tc = to_tc_port(dig_port); - return (DISPLAY_VER(i915) == 11 && tc->legacy_port) || - IS_ALDERLAKE_P(i915); -} - -static enum intel_display_power_domain -tc_phy_cold_off_domain(struct intel_tc_port *tc) -{ - struct drm_i915_private *i915 = tc_to_i915(tc); - struct intel_digital_port *dig_port = tc->dig_port; - - if (tc->mode == TC_PORT_TBT_ALT || !intel_tc_cold_requires_aux_pw(dig_port)) - return POWER_DOMAIN_TC_COLD_OFF; - - return intel_display_power_legacy_aux_domain(i915, dig_port->aux_ch); + return tc_phy_cold_off_domain(tc) == + intel_display_power_legacy_aux_domain(i915, dig_port->aux_ch); } static intel_wakeref_t @@ -334,6 +325,18 @@ static void tc_port_fixup_legacy_flag(struct intel_tc_port *tc, * ICL TC PHY handlers * ------------------- */ +static enum intel_display_power_domain +icl_tc_phy_cold_off_domain(struct intel_tc_port *tc) +{ + struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_digital_port *dig_port = tc->dig_port; + + if (tc->legacy_port) + return intel_display_power_legacy_aux_domain(i915, dig_port->aux_ch); + + return POWER_DOMAIN_TC_COLD_OFF; +} + static u32 icl_tc_phy_hpd_live_status(struct intel_tc_port *tc) { struct drm_i915_private *i915 = tc_to_i915(tc); @@ -540,6 +543,27 @@ static void icl_tc_phy_disconnect(struct intel_tc_port *tc) } static const struct intel_tc_phy_ops icl_tc_phy_ops = { + .cold_off_domain = icl_tc_phy_cold_off_domain, + .hpd_live_status = icl_tc_phy_hpd_live_status, + .is_ready = icl_tc_phy_is_ready, + .is_owned = icl_tc_phy_is_owned, + .get_hw_state = icl_tc_phy_get_hw_state, + .connect = icl_tc_phy_connect, + .disconnect = icl_tc_phy_disconnect, +}; + +/* + * TGL TC PHY handlers + * ------------------- + */ +static enum intel_display_power_domain +tgl_tc_phy_cold_off_domain(struct intel_tc_port *tc) +{ + return POWER_DOMAIN_TC_COLD_OFF; +} + +static const struct intel_tc_phy_ops tgl_tc_phy_ops = { + .cold_off_domain = tgl_tc_phy_cold_off_domain, .hpd_live_status = icl_tc_phy_hpd_live_status, .is_ready = icl_tc_phy_is_ready, .is_owned = icl_tc_phy_is_owned, @@ -552,6 +576,18 @@ static const struct intel_tc_phy_ops icl_tc_phy_ops = { * ADLP TC PHY handlers * -------------------- */ +static enum intel_display_power_domain +adlp_tc_phy_cold_off_domain(struct intel_tc_port *tc) +{ + struct drm_i915_private *i915 = tc_to_i915(tc); + struct intel_digital_port *dig_port = tc->dig_port; + + if (tc->mode != TC_PORT_TBT_ALT) + return intel_display_power_legacy_aux_domain(i915, dig_port->aux_ch); + + return POWER_DOMAIN_TC_COLD_OFF; +} + static u32 adlp_tc_phy_hpd_live_status(struct intel_tc_port *tc) { struct drm_i915_private *i915 = tc_to_i915(tc); @@ -624,6 +660,7 @@ static bool adlp_tc_phy_is_owned(struct intel_tc_port *tc) } static const struct intel_tc_phy_ops adlp_tc_phy_ops = { + .cold_off_domain = adlp_tc_phy_cold_off_domain, .hpd_live_status = adlp_tc_phy_hpd_live_status, .is_ready = adlp_tc_phy_is_ready, .is_owned = adlp_tc_phy_is_owned, @@ -636,6 +673,12 @@ static const struct intel_tc_phy_ops adlp_tc_phy_ops = { * Generic TC PHY handlers * ----------------------- */ +static enum intel_display_power_domain +tc_phy_cold_off_domain(struct intel_tc_port *tc) +{ + return tc->phy_ops->cold_off_domain(tc); +} + static u32 tc_phy_hpd_live_status(struct intel_tc_port *tc) { struct drm_i915_private *i915 = tc_to_i915(tc); @@ -1246,6 +1289,8 @@ int intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy) if (DISPLAY_VER(i915) >= 13) tc->phy_ops = &adlp_tc_phy_ops; + else if (DISPLAY_VER(i915) >= 12) + tc->phy_ops = &tgl_tc_phy_ops; else tc->phy_ops = &icl_tc_phy_ops; -- cgit v1.2.3-59-g8ed1b From 7e696546353f659f60fd10616e04a2aa59ab2ac0 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:26 +0200 Subject: drm/i915/tc: Add asserts in TC PHY hooks that the required power is on Add an assert to each TC PHY hook that their required power domain is enabled. While at it add a comment describing the domains used on each platform and TC mode. v2: Fix non kernel-doc multiline comments. (Jani) Cc: Jani Nikula Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-21-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 61 +++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 3972b2457d11..391a4111fcfd 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -111,6 +111,46 @@ bool intel_tc_port_in_legacy_mode(struct intel_digital_port *dig_port) return intel_tc_port_in_mode(dig_port, TC_PORT_LEGACY); } +/* + * The display power domains used for TC ports depending on the + * platform and TC mode (legacy, DP-alt, TBT): + * + * POWER_DOMAIN_DISPLAY_CORE: + * -------------------------- + * ADLP/all modes: + * - TCSS/IOM access for PHY ready state. + * ADLP+/all modes: + * - DE/north-,south-HPD ISR access for HPD live state. + * + * POWER_DOMAIN_PORT_DDI_LANES_: + * ----------------------------------- + * ICL+/all modes: + * - DE/DDI_BUF access for port enabled state. + * ADLP/all modes: + * - DE/DDI_BUF access for PHY owned state. + * + * POWER_DOMAIN_AUX_USBC: + * ------------------------------------- + * ICL/legacy mode: + * - TCSS/IOM,FIA access for PHY ready, owned and HPD live state + * - TCSS/PHY: block TC-cold power state for using the PHY AUX and + * main lanes. + * ADLP/legacy, DP-alt modes: + * - TCSS/PHY: block TC-cold power state for using the PHY AUX and + * main lanes. + * + * POWER_DOMAIN_TC_COLD_OFF: + * ------------------------- + * TGL/legacy, DP-alt modes: + * - TCSS/IOM,FIA access for PHY ready, owned and HPD live state + * - TCSS/PHY: block TC-cold power state for using the PHY AUX and + * main lanes. + * + * ICL, TGL, ADLP/TBT mode: + * - TCSS/IOM,FIA access for HPD live state + * - TCSS/TBT: block TC-cold power state for using the (TBT DP-IN) + * AUX and main lanes. + */ bool intel_tc_cold_requires_aux_pw(struct intel_digital_port *dig_port) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); @@ -163,6 +203,15 @@ tc_cold_unblock(struct intel_tc_port *tc, intel_wakeref_t wakeref) __tc_cold_unblock(tc, domain, wakeref); } +static void +assert_display_core_power_enabled(struct intel_tc_port *tc) +{ + struct drm_i915_private *i915 = tc_to_i915(tc); + + drm_WARN_ON(&i915->drm, + !intel_display_power_is_enabled(i915, POWER_DOMAIN_DISPLAY_CORE)); +} + static void assert_tc_cold_blocked(struct intel_tc_port *tc) { @@ -378,6 +427,8 @@ static bool icl_tc_phy_is_ready(struct intel_tc_port *tc) struct drm_i915_private *i915 = tc_to_i915(tc); u32 val; + assert_tc_cold_blocked(tc); + val = intel_de_read(i915, PORT_TX_DFLEXDPPMS(tc->phy_fia)); if (val == 0xffffffff) { drm_dbg_kms(&i915->drm, @@ -395,6 +446,8 @@ static bool icl_tc_phy_take_ownership(struct intel_tc_port *tc, struct drm_i915_private *i915 = tc_to_i915(tc); u32 val; + assert_tc_cold_blocked(tc); + val = intel_de_read(i915, PORT_TX_DFLEXDPCSSS(tc->phy_fia)); if (val == 0xffffffff) { drm_dbg_kms(&i915->drm, @@ -418,6 +471,8 @@ static bool icl_tc_phy_is_owned(struct intel_tc_port *tc) struct drm_i915_private *i915 = tc_to_i915(tc); u32 val; + assert_tc_cold_blocked(tc); + val = intel_de_read(i915, PORT_TX_DFLEXDPCSSS(tc->phy_fia)); if (val == 0xffffffff) { drm_dbg_kms(&i915->drm, @@ -626,6 +681,8 @@ static bool adlp_tc_phy_is_ready(struct intel_tc_port *tc) enum tc_port tc_port = intel_port_to_tc(i915, tc->dig_port->base.port); u32 val; + assert_display_core_power_enabled(tc); + val = intel_de_read(i915, TCSS_DDI_STATUS(tc_port)); if (val == 0xffffffff) { drm_dbg_kms(&i915->drm, @@ -643,6 +700,8 @@ static bool adlp_tc_phy_take_ownership(struct intel_tc_port *tc, struct drm_i915_private *i915 = tc_to_i915(tc); enum port port = tc->dig_port->base.port; + assert_tc_port_power_enabled(tc); + intel_de_rmw(i915, DDI_BUF_CTL(port), DDI_BUF_CTL_TC_PHY_OWNERSHIP, take ? DDI_BUF_CTL_TC_PHY_OWNERSHIP : 0); @@ -655,6 +714,8 @@ static bool adlp_tc_phy_is_owned(struct intel_tc_port *tc) enum port port = tc->dig_port->base.port; u32 val; + assert_tc_port_power_enabled(tc); + val = intel_de_read(i915, DDI_BUF_CTL(port)); return val & DDI_BUF_CTL_TC_PHY_OWNERSHIP; } -- cgit v1.2.3-59-g8ed1b From c55b73f391a726a45cc014464ba7ebea5f1d7386 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:27 +0200 Subject: drm/i915/tc: Add TC PHY hook to init the PHY Add a hook for platform specific PHY initialization. Move the detection of modular FIAs to the TGL handler, skipping this on ADLP+ where the FIAs are always modular, not requiring a detection. Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-22-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 96 +++++++++++++++++++------------- drivers/gpu/drm/i915/i915_pci.c | 3 - drivers/gpu/drm/i915/intel_device_info.h | 1 - 3 files changed, 56 insertions(+), 44 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 391a4111fcfd..2cbdecead522 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -32,6 +32,7 @@ struct intel_tc_phy_ops { void (*get_hw_state)(struct intel_tc_port *tc); bool (*connect)(struct intel_tc_port *tc, int required_lanes); void (*disconnect)(struct intel_tc_port *tc); + void (*init)(struct intel_tc_port *tc); }; struct intel_tc_port { @@ -370,6 +371,25 @@ static void tc_port_fixup_legacy_flag(struct intel_tc_port *tc, tc->legacy_port = !tc->legacy_port; } +static void tc_phy_load_fia_params(struct intel_tc_port *tc, bool modular_fia) +{ + struct drm_i915_private *i915 = tc_to_i915(tc); + enum port port = tc->dig_port->base.port; + enum tc_port tc_port = intel_port_to_tc(i915, port); + + /* + * Each Modular FIA instance houses 2 TC ports. In SOC that has more + * than two TC ports, there are multiple instances of Modular FIA. + */ + if (modular_fia) { + tc->phy_fia = tc_port / 2; + tc->phy_fia_idx = tc_port % 2; + } else { + tc->phy_fia = FIA1; + tc->phy_fia_idx = tc_port; + } +} + /* * ICL TC PHY handlers * ------------------- @@ -597,6 +617,11 @@ static void icl_tc_phy_disconnect(struct intel_tc_port *tc) } } +static void icl_tc_phy_init(struct intel_tc_port *tc) +{ + tc_phy_load_fia_params(tc, false); +} + static const struct intel_tc_phy_ops icl_tc_phy_ops = { .cold_off_domain = icl_tc_phy_cold_off_domain, .hpd_live_status = icl_tc_phy_hpd_live_status, @@ -605,6 +630,7 @@ static const struct intel_tc_phy_ops icl_tc_phy_ops = { .get_hw_state = icl_tc_phy_get_hw_state, .connect = icl_tc_phy_connect, .disconnect = icl_tc_phy_disconnect, + .init = icl_tc_phy_init, }; /* @@ -617,6 +643,20 @@ tgl_tc_phy_cold_off_domain(struct intel_tc_port *tc) return POWER_DOMAIN_TC_COLD_OFF; } +static void tgl_tc_phy_init(struct intel_tc_port *tc) +{ + struct drm_i915_private *i915 = tc_to_i915(tc); + intel_wakeref_t wakeref; + u32 val; + + with_intel_display_power(i915, tc_phy_cold_off_domain(tc), wakeref) + val = intel_de_read(i915, PORT_TX_DFLEXDPSP(FIA1)); + + drm_WARN_ON(&i915->drm, val == 0xffffffff); + + tc_phy_load_fia_params(tc, val & MODULAR_FIA_MASK); +} + static const struct intel_tc_phy_ops tgl_tc_phy_ops = { .cold_off_domain = tgl_tc_phy_cold_off_domain, .hpd_live_status = icl_tc_phy_hpd_live_status, @@ -625,6 +665,7 @@ static const struct intel_tc_phy_ops tgl_tc_phy_ops = { .get_hw_state = icl_tc_phy_get_hw_state, .connect = icl_tc_phy_connect, .disconnect = icl_tc_phy_disconnect, + .init = tgl_tc_phy_init, }; /* @@ -720,6 +761,11 @@ static bool adlp_tc_phy_is_owned(struct intel_tc_port *tc) return val & DDI_BUF_CTL_TC_PHY_OWNERSHIP; } +static void adlp_tc_phy_init(struct intel_tc_port *tc) +{ + tc_phy_load_fia_params(tc, true); +} + static const struct intel_tc_phy_ops adlp_tc_phy_ops = { .cold_off_domain = adlp_tc_phy_cold_off_domain, .hpd_live_status = adlp_tc_phy_hpd_live_status, @@ -728,6 +774,7 @@ static const struct intel_tc_phy_ops adlp_tc_phy_ops = { .get_hw_state = icl_tc_phy_get_hw_state, .connect = icl_tc_phy_connect, .disconnect = icl_tc_phy_disconnect, + .init = adlp_tc_phy_init, }; /* @@ -972,6 +1019,13 @@ static void tc_phy_disconnect(struct intel_tc_port *tc) } } +static void tc_phy_init(struct intel_tc_port *tc) +{ + mutex_lock(&tc->lock); + tc->phy_ops->init(tc); + mutex_unlock(&tc->lock); +} + static void intel_tc_port_reset_mode(struct intel_tc_port *tc, int required_lanes, bool force_disconnect) { @@ -1292,45 +1346,6 @@ void intel_tc_port_put_link(struct intel_digital_port *dig_port) intel_tc_port_flush_work(dig_port); } -static bool -tc_has_modular_fia(struct drm_i915_private *i915, struct intel_tc_port *tc) -{ - intel_wakeref_t wakeref; - u32 val; - - if (!INTEL_INFO(i915)->display.has_modular_fia) - return false; - - mutex_lock(&tc->lock); - wakeref = tc_cold_block(tc); - val = intel_de_read(i915, PORT_TX_DFLEXDPSP(FIA1)); - tc_cold_unblock(tc, wakeref); - mutex_unlock(&tc->lock); - - drm_WARN_ON(&i915->drm, val == 0xffffffff); - - return val & MODULAR_FIA_MASK; -} - -static void -tc_port_load_fia_params(struct drm_i915_private *i915, struct intel_tc_port *tc) -{ - enum port port = tc->dig_port->base.port; - enum tc_port tc_port = intel_port_to_tc(i915, port); - - /* - * Each Modular FIA instance houses 2 TC ports. In SOC that has more - * than two TC ports, there are multiple instances of Modular FIA. - */ - if (tc_has_modular_fia(i915, tc)) { - tc->phy_fia = tc_port / 2; - tc->phy_fia_idx = tc_port % 2; - } else { - tc->phy_fia = FIA1; - tc->phy_fia_idx = tc_port; - } -} - int intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy) { struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); @@ -1363,7 +1378,8 @@ int intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy) tc->legacy_port = is_legacy; tc->mode = TC_PORT_DISCONNECTED; tc->link_refcount = 0; - tc_port_load_fia_params(i915, tc); + + tc_phy_init(tc); intel_tc_port_init_mode(dig_port); diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index a8d942b16223..bbc4d62e490e 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -896,7 +896,6 @@ static const struct intel_device_info jsl_info = { static const struct intel_device_info tgl_info = { GEN12_FEATURES, PLATFORM(INTEL_TIGERLAKE), - .display.has_modular_fia = 1, .__runtime.platform_engine_mask = BIT(RCS0) | BIT(BCS0) | BIT(VECS0) | BIT(VCS0) | BIT(VCS2), }; @@ -996,7 +995,6 @@ static const struct intel_device_info adl_p_info = { BIT(TRANSCODER_C) | BIT(TRANSCODER_D) | BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1), .display.has_cdclk_crawl = 1, - .display.has_modular_fia = 1, .display.has_psr_hw_tracking = 0, .__runtime.platform_engine_mask = BIT(RCS0) | BIT(BCS0) | BIT(VECS0) | BIT(VCS0) | BIT(VCS2), @@ -1143,7 +1141,6 @@ static const struct intel_device_info mtl_info = { .__runtime.graphics.ip.rel = 70, .__runtime.media.ip.ver = 13, PLATFORM(INTEL_METEORLAKE), - .display.has_modular_fia = 1, .extra_gt_list = xelpmp_extra_gt, .has_flat_ccs = 0, .has_gmd_id = 1, diff --git a/drivers/gpu/drm/i915/intel_device_info.h b/drivers/gpu/drm/i915/intel_device_info.h index b30cc8b97c3a..dd8b17c15566 100644 --- a/drivers/gpu/drm/i915/intel_device_info.h +++ b/drivers/gpu/drm/i915/intel_device_info.h @@ -192,7 +192,6 @@ enum intel_ppgtt_type { func(has_hotplug); \ func(has_hti); \ func(has_ipc); \ - func(has_modular_fia); \ func(has_overlay); \ func(has_psr); \ func(has_psr_hw_tracking); \ -- cgit v1.2.3-59-g8ed1b From 825535f44fef606e5b4484ebb8cb3827db59037e Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:28 +0200 Subject: drm/i915/adlp/tc: Use the DE HPD ISR register for hotplug detection The spec says to use the CPU ISR registers for DP-alt/TBT HPD detection on ADLP, so do that instead of using the related IOM/TCSS registers. Bspec: 55480, 55482, 49212, 49305 Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-23-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 2cbdecead522..24cee1b5629b 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -688,22 +688,19 @@ static u32 adlp_tc_phy_hpd_live_status(struct intel_tc_port *tc) { struct drm_i915_private *i915 = tc_to_i915(tc); struct intel_digital_port *dig_port = tc->dig_port; - enum tc_port tc_port = intel_port_to_tc(i915, dig_port->base.port); - u32 isr_bit = i915->display.hotplug.pch_hpd[dig_port->base.hpd_pin]; - u32 val, mask = 0; + enum hpd_pin hpd_pin = dig_port->base.hpd_pin; + u32 cpu_isr_bits = i915->display.hotplug.hpd[hpd_pin]; + u32 pch_isr_bit = i915->display.hotplug.pch_hpd[hpd_pin]; + u32 cpu_isr; + u32 mask = 0; - /* - * On ADL-P HW/FW will wake from TCCOLD to complete the read access of - * registers in IOM. Note that this doesn't apply to PHY and FIA - * registers. - */ - val = intel_de_read(i915, TCSS_DDI_STATUS(tc_port)); - if (val & TCSS_DDI_STATUS_HPD_LIVE_STATUS_ALT) + cpu_isr = intel_de_read(i915, GEN11_DE_HPD_ISR); + if (cpu_isr & (cpu_isr_bits & GEN11_DE_TC_HOTPLUG_MASK)) mask |= BIT(TC_PORT_DP_ALT); - if (val & TCSS_DDI_STATUS_HPD_LIVE_STATUS_TBT) + if (cpu_isr & (cpu_isr_bits & GEN11_DE_TBT_HOTPLUG_MASK)) mask |= BIT(TC_PORT_TBT_ALT); - if (intel_de_read(i915, SDEISR) & isr_bit) + if (intel_de_read(i915, SDEISR) & pch_isr_bit) mask |= BIT(TC_PORT_LEGACY); return mask; -- cgit v1.2.3-59-g8ed1b From 8979918af711b057620c7c5f9d29a0043f927753 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:29 +0200 Subject: drm/i915/tc: Get power ref for reading the HPD live status register Enable the power required for the HPD live status register access instead of depending on the caller blocking the TC-cold power state (during HW readout and connector probing). A follow up patch will remove connecting/disconnecting the PHY around connector probing, so querying the HPD status can happen in this case without TC-cold being blocked. Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-24-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 24cee1b5629b..f9a09b1bb329 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -411,24 +411,29 @@ static u32 icl_tc_phy_hpd_live_status(struct intel_tc_port *tc) struct drm_i915_private *i915 = tc_to_i915(tc); struct intel_digital_port *dig_port = tc->dig_port; u32 isr_bit = i915->display.hotplug.pch_hpd[dig_port->base.hpd_pin]; + intel_wakeref_t wakeref; + u32 fia_isr; + u32 pch_isr; u32 mask = 0; - u32 val; - val = intel_de_read(i915, PORT_TX_DFLEXDPSP(tc->phy_fia)); + with_intel_display_power(i915, tc_phy_cold_off_domain(tc), wakeref) { + fia_isr = intel_de_read(i915, PORT_TX_DFLEXDPSP(tc->phy_fia)); + pch_isr = intel_de_read(i915, SDEISR); + } - if (val == 0xffffffff) { + if (fia_isr == 0xffffffff) { drm_dbg_kms(&i915->drm, "Port %s: PHY in TCCOLD, nothing connected\n", tc->port_name); return mask; } - if (val & TC_LIVE_STATE_TBT(tc->phy_fia_idx)) + if (fia_isr & TC_LIVE_STATE_TBT(tc->phy_fia_idx)) mask |= BIT(TC_PORT_TBT_ALT); - if (val & TC_LIVE_STATE_TC(tc->phy_fia_idx)) + if (fia_isr & TC_LIVE_STATE_TC(tc->phy_fia_idx)) mask |= BIT(TC_PORT_DP_ALT); - if (intel_de_read(i915, SDEISR) & isr_bit) + if (pch_isr & isr_bit) mask |= BIT(TC_PORT_LEGACY); return mask; @@ -691,16 +696,22 @@ static u32 adlp_tc_phy_hpd_live_status(struct intel_tc_port *tc) enum hpd_pin hpd_pin = dig_port->base.hpd_pin; u32 cpu_isr_bits = i915->display.hotplug.hpd[hpd_pin]; u32 pch_isr_bit = i915->display.hotplug.pch_hpd[hpd_pin]; + intel_wakeref_t wakeref; u32 cpu_isr; + u32 pch_isr; u32 mask = 0; - cpu_isr = intel_de_read(i915, GEN11_DE_HPD_ISR); + with_intel_display_power(i915, POWER_DOMAIN_DISPLAY_CORE, wakeref) { + cpu_isr = intel_de_read(i915, GEN11_DE_HPD_ISR); + pch_isr = intel_de_read(i915, SDEISR); + } + if (cpu_isr & (cpu_isr_bits & GEN11_DE_TC_HOTPLUG_MASK)) mask |= BIT(TC_PORT_DP_ALT); if (cpu_isr & (cpu_isr_bits & GEN11_DE_TBT_HOTPLUG_MASK)) mask |= BIT(TC_PORT_TBT_ALT); - if (intel_de_read(i915, SDEISR) & pch_isr_bit) + if (pch_isr & pch_isr_bit) mask |= BIT(TC_PORT_LEGACY); return mask; -- cgit v1.2.3-59-g8ed1b From ebcabb8b15708023b71b7044fdf928454613d118 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:30 +0200 Subject: drm/i915/tc: Don't connect the PHY in intel_tc_port_connected() Connecting the PHY for connector probing - also blocking TC-cold - isn't required and has some overhead. Taking only the mutex is sufficient, so do that. Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-25-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index f9a09b1bb329..40bd34a633c4 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -1235,20 +1235,25 @@ bool intel_tc_port_connected_locked(struct intel_encoder *encoder) struct intel_digital_port *dig_port = enc_to_dig_port(encoder); struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); struct intel_tc_port *tc = to_tc_port(dig_port); + u32 mask = ~0; drm_WARN_ON(&i915->drm, !intel_tc_port_ref_held(dig_port)); - return tc_phy_hpd_live_status(tc) & BIT(tc->mode); + if (tc->mode != TC_PORT_DISCONNECTED) + mask = BIT(tc->mode); + + return tc_phy_hpd_live_status(tc) & mask; } bool intel_tc_port_connected(struct intel_encoder *encoder) { struct intel_digital_port *dig_port = enc_to_dig_port(encoder); + struct intel_tc_port *tc = to_tc_port(dig_port); bool is_connected; - intel_tc_port_lock(dig_port); + mutex_lock(&tc->lock); is_connected = intel_tc_port_connected_locked(encoder); - intel_tc_port_unlock(dig_port); + mutex_unlock(&tc->lock); return is_connected; } -- cgit v1.2.3-59-g8ed1b From 9796a5b2725d1b3ddbbe7b1f3dec56af8cc6af22 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:31 +0200 Subject: drm/i915/adlp/tc: Align the connect/disconnect PHY sequence with bspec Bspec has updated the TC connect/disconnect sequences, add the required platform hooks for these. The difference wrt. the old sequence is the order of taking the PHY ownership - while holding a port power reference this requires - and blocking the TC-cold power state. Bspec: 49294 Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-26-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 111 +++++++++++++++++++++++++++----- 1 file changed, 94 insertions(+), 17 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 40bd34a633c4..0f147f94341d 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -59,7 +59,6 @@ static enum intel_display_power_domain tc_phy_cold_off_domain(struct intel_tc_port *); static u32 tc_phy_hpd_live_status(struct intel_tc_port *tc); static bool tc_phy_is_ready(struct intel_tc_port *tc); -static bool tc_phy_take_ownership(struct intel_tc_port *tc, bool take); static enum tc_port_mode tc_phy_get_current_mode(struct intel_tc_port *tc); static const char *tc_port_mode_name(enum tc_port_mode mode) @@ -581,7 +580,7 @@ static bool icl_tc_phy_connect(struct intel_tc_port *tc, return true; if ((!tc_phy_is_ready(tc) || - !tc_phy_take_ownership(tc, true)) && + !icl_tc_phy_take_ownership(tc, true)) && !drm_WARN_ON(&i915->drm, tc->mode == TC_PORT_LEGACY)) { drm_dbg_kms(&i915->drm, "Port %s: can't take PHY ownership (ready %s)\n", tc->port_name, @@ -596,7 +595,7 @@ static bool icl_tc_phy_connect(struct intel_tc_port *tc, return true; out_release_phy: - tc_phy_take_ownership(tc, false); + icl_tc_phy_take_ownership(tc, false); out_unblock_tc_cold: tc_cold_unblock(tc, fetch_and_zero(&tc->lock_wakeref)); @@ -612,7 +611,7 @@ static void icl_tc_phy_disconnect(struct intel_tc_port *tc) switch (tc->mode) { case TC_PORT_LEGACY: case TC_PORT_DP_ALT: - tc_phy_take_ownership(tc, false); + icl_tc_phy_take_ownership(tc, false); fallthrough; case TC_PORT_TBT_ALT: tc_cold_unblock(tc, fetch_and_zero(&tc->lock_wakeref)); @@ -769,6 +768,94 @@ static bool adlp_tc_phy_is_owned(struct intel_tc_port *tc) return val & DDI_BUF_CTL_TC_PHY_OWNERSHIP; } +static void adlp_tc_phy_get_hw_state(struct intel_tc_port *tc) +{ + struct drm_i915_private *i915 = tc_to_i915(tc); + enum intel_display_power_domain port_power_domain = + tc_port_power_domain(tc); + intel_wakeref_t port_wakeref; + + port_wakeref = intel_display_power_get(i915, port_power_domain); + + tc->mode = tc_phy_get_current_mode(tc); + if (tc->mode != TC_PORT_DISCONNECTED) + tc->lock_wakeref = tc_cold_block(tc); + + intel_display_power_put(i915, port_power_domain, port_wakeref); +} + +static bool adlp_tc_phy_connect(struct intel_tc_port *tc, int required_lanes) +{ + struct drm_i915_private *i915 = tc_to_i915(tc); + enum intel_display_power_domain port_power_domain = + tc_port_power_domain(tc); + intel_wakeref_t port_wakeref; + + if (tc->mode == TC_PORT_TBT_ALT) { + tc->lock_wakeref = tc_cold_block(tc); + return true; + } + + port_wakeref = intel_display_power_get(i915, port_power_domain); + + if (!adlp_tc_phy_take_ownership(tc, true) && + !drm_WARN_ON(&i915->drm, tc->mode == TC_PORT_LEGACY)) { + drm_dbg_kms(&i915->drm, "Port %s: can't take PHY ownership\n", + tc->port_name); + goto out_put_port_power; + } + + if (!tc_phy_is_ready(tc) && + !drm_WARN_ON(&i915->drm, tc->mode == TC_PORT_LEGACY)) { + drm_dbg_kms(&i915->drm, "Port %s: PHY not ready\n", + tc->port_name); + goto out_release_phy; + } + + tc->lock_wakeref = tc_cold_block(tc); + + if (!tc_phy_verify_legacy_or_dp_alt_mode(tc, required_lanes)) + goto out_unblock_tc_cold; + + intel_display_power_put(i915, port_power_domain, port_wakeref); + + return true; + +out_unblock_tc_cold: + tc_cold_unblock(tc, fetch_and_zero(&tc->lock_wakeref)); +out_release_phy: + adlp_tc_phy_take_ownership(tc, false); +out_put_port_power: + intel_display_power_put(i915, port_power_domain, port_wakeref); + + return false; +} + +static void adlp_tc_phy_disconnect(struct intel_tc_port *tc) +{ + struct drm_i915_private *i915 = tc_to_i915(tc); + enum intel_display_power_domain port_power_domain = + tc_port_power_domain(tc); + intel_wakeref_t port_wakeref; + + port_wakeref = intel_display_power_get(i915, port_power_domain); + + tc_cold_unblock(tc, fetch_and_zero(&tc->lock_wakeref)); + + switch (tc->mode) { + case TC_PORT_LEGACY: + case TC_PORT_DP_ALT: + adlp_tc_phy_take_ownership(tc, false); + fallthrough; + case TC_PORT_TBT_ALT: + break; + default: + MISSING_CASE(tc->mode); + } + + intel_display_power_put(i915, port_power_domain, port_wakeref); +} + static void adlp_tc_phy_init(struct intel_tc_port *tc) { tc_phy_load_fia_params(tc, true); @@ -779,9 +866,9 @@ static const struct intel_tc_phy_ops adlp_tc_phy_ops = { .hpd_live_status = adlp_tc_phy_hpd_live_status, .is_ready = adlp_tc_phy_is_ready, .is_owned = adlp_tc_phy_is_owned, - .get_hw_state = icl_tc_phy_get_hw_state, - .connect = icl_tc_phy_connect, - .disconnect = icl_tc_phy_disconnect, + .get_hw_state = adlp_tc_phy_get_hw_state, + .connect = adlp_tc_phy_connect, + .disconnect = adlp_tc_phy_disconnect, .init = adlp_tc_phy_init, }; @@ -823,16 +910,6 @@ static void tc_phy_get_hw_state(struct intel_tc_port *tc) tc->phy_ops->get_hw_state(tc); } -static bool tc_phy_take_ownership(struct intel_tc_port *tc, bool take) -{ - struct drm_i915_private *i915 = tc_to_i915(tc); - - if (IS_ALDERLAKE_P(i915)) - return adlp_tc_phy_take_ownership(tc, take); - - return icl_tc_phy_take_ownership(tc, take); -} - static bool tc_phy_is_ready_and_owned(struct intel_tc_port *tc, bool phy_is_ready, bool phy_is_owned) { -- cgit v1.2.3-59-g8ed1b From 3acac2d06a7e0f0b182b86b25bb8a2e9b3300406 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:32 +0200 Subject: drm/i915: Move shared DPLL disabling into CRTC disable hook The spec requires disabling the PLL on TC ports before disconnecting the port's PHY. Prepare for that by moving the PLL disabling to the CRTC disable hook, while disconnecting the PHY will be moved to the post_pll_disable() encoder hook in the next patch. v2: Move the call from intel_crtc_disable_noatomic() as well. Reviewed-by: Mika Kahola # v1 Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-27-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 5 ++++- drivers/gpu/drm/i915/display/intel_modeset_setup.c | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index b53a1d969344..1ed584d04c10 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1905,6 +1905,8 @@ static void ilk_crtc_disable(struct intel_atomic_state *state, intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, true); intel_set_pch_fifo_underrun_reporting(dev_priv, pipe, true); + + intel_disable_shared_dpll(old_crtc_state); } static void hsw_crtc_disable(struct intel_atomic_state *state, @@ -1923,6 +1925,8 @@ static void hsw_crtc_disable(struct intel_atomic_state *state, intel_encoders_post_disable(state, crtc); } + intel_disable_shared_dpll(old_crtc_state); + intel_dmc_disable_pipe(i915, crtc->pipe); } @@ -7041,7 +7045,6 @@ static void intel_old_crtc_state_disables(struct intel_atomic_state *state, dev_priv->display.funcs.display->crtc_disable(state, crtc); crtc->active = false; intel_fbc_disable(crtc); - intel_disable_shared_dpll(old_crtc_state); if (!new_crtc_state->hw.active) intel_initial_watermarks(state, crtc); diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c b/drivers/gpu/drm/i915/display/intel_modeset_setup.c index 4558d02641fe..134b943f1953 100644 --- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c +++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c @@ -100,7 +100,6 @@ static void intel_crtc_disable_noatomic(struct intel_crtc *crtc, intel_fbc_disable(crtc); intel_update_watermarks(i915); - intel_disable_shared_dpll(crtc_state); intel_display_power_put_all_in_set(i915, &crtc->enabled_power_domains); -- cgit v1.2.3-59-g8ed1b From b108bdd0e22a402bd3e4a6391acbb6aefad31a9e Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:33 +0200 Subject: drm/i915: Disable DPLLs before disconnecting the TC PHY Bspec requires disabling the DPLLs on TC ports before disconnecting the port's PHY. Add a post_pll_disable encoder hook and move the call to disconnect the port's PHY from the post_disable hook to the new hook. Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-28-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 15 ++++++++++++--- drivers/gpu/drm/i915/display/intel_display.c | 2 ++ drivers/gpu/drm/i915/display/intel_dp_mst.c | 15 +++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index dac3ec8fbbc1..62bd4196dc46 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -2720,9 +2720,6 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state, const struct drm_connector_state *old_conn_state) { struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); - struct intel_digital_port *dig_port = enc_to_dig_port(encoder); - enum phy phy = intel_port_to_phy(dev_priv, encoder->port); - bool is_tc_port = intel_phy_is_tc(dev_priv, phy); struct intel_crtc *slave_crtc; if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST)) { @@ -2772,6 +2769,17 @@ static void intel_ddi_post_disable(struct intel_atomic_state *state, else intel_ddi_post_disable_dp(state, encoder, old_crtc_state, old_conn_state); +} + +static void intel_ddi_post_pll_disable(struct intel_atomic_state *state, + struct intel_encoder *encoder, + const struct intel_crtc_state *old_crtc_state, + const struct drm_connector_state *old_conn_state) +{ + struct drm_i915_private *i915 = to_i915(encoder->base.dev); + struct intel_digital_port *dig_port = enc_to_dig_port(encoder); + enum phy phy = intel_port_to_phy(i915, encoder->port); + bool is_tc_port = intel_phy_is_tc(i915, phy); main_link_aux_power_domain_put(dig_port, old_crtc_state); @@ -4398,6 +4406,7 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) encoder->pre_pll_enable = intel_ddi_pre_pll_enable; encoder->pre_enable = intel_ddi_pre_enable; encoder->disable = intel_disable_ddi; + encoder->post_pll_disable = intel_ddi_post_pll_disable; encoder->post_disable = intel_ddi_post_disable; encoder->update_pipe = intel_ddi_update_pipe; encoder->get_hw_state = intel_ddi_get_hw_state; diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 1ed584d04c10..ca0db2332ded 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1927,6 +1927,8 @@ static void hsw_crtc_disable(struct intel_atomic_state *state, intel_disable_shared_dpll(old_crtc_state); + intel_encoders_post_pll_disable(state, crtc); + intel_dmc_disable_pipe(i915, crtc->pipe); } diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index c3e8db943e9c..fe01fdf36cfd 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -623,6 +623,20 @@ static void intel_mst_post_disable_dp(struct intel_atomic_state *state, intel_dp->active_mst_links); } +static void intel_mst_post_pll_disable_dp(struct intel_atomic_state *state, + struct intel_encoder *encoder, + const struct intel_crtc_state *old_crtc_state, + const struct drm_connector_state *old_conn_state) +{ + struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder); + struct intel_digital_port *dig_port = intel_mst->primary; + struct intel_dp *intel_dp = &dig_port->dp; + + if (intel_dp->active_mst_links == 0 && + dig_port->base.post_pll_disable) + dig_port->base.post_pll_disable(state, encoder, old_crtc_state, old_conn_state); +} + static void intel_mst_pre_pll_enable_dp(struct intel_atomic_state *state, struct intel_encoder *encoder, const struct intel_crtc_state *pipe_config, @@ -1146,6 +1160,7 @@ intel_dp_create_fake_mst_encoder(struct intel_digital_port *dig_port, enum pipe intel_encoder->compute_config_late = intel_dp_mst_compute_config_late; intel_encoder->disable = intel_mst_disable_dp; intel_encoder->post_disable = intel_mst_post_disable_dp; + intel_encoder->post_pll_disable = intel_mst_post_pll_disable_dp; intel_encoder->update_pipe = intel_ddi_update_pipe; intel_encoder->pre_pll_enable = intel_mst_pre_pll_enable_dp; intel_encoder->pre_enable = intel_mst_pre_enable_dp; -- cgit v1.2.3-59-g8ed1b From 450c27fc9e9cf74ff9b96dd813817133e0f50cf1 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:34 +0200 Subject: drm/i915: Remove TC PHY disconnect workaround After the previous patch the workaround for a TC PHY hang issue is not required any more, remove it. Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-29-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 0f147f94341d..2bb02d4e6859 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -1426,14 +1426,6 @@ void intel_tc_port_put_link(struct intel_digital_port *dig_port) intel_tc_port_lock(dig_port); __intel_tc_port_put_link(tc); intel_tc_port_unlock(dig_port); - - /* - * Disconnecting the PHY after the PHY's PLL gets disabled may - * hang the system on ADL-P, so disconnect the PHY here synchronously. - * TODO: remove this once the root cause of the ordering requirement - * is found/fixed. - */ - intel_tc_port_flush_work(dig_port); } int intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy) -- cgit v1.2.3-59-g8ed1b From 0f752b2178c988117927154fe3b1d2e619c80c57 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Thu, 23 Mar 2023 16:20:35 +0200 Subject: drm/i915: Remove the encoder update_prepare()/complete() hooks The encoder update_prepare()/complete() hooks were added to hold a TC port link reference for all outputs in the atomic state around the whole modeset enable sequence - thus locking the ports' TC mode - and set the TBT/DP-alt PLL type corresponding to the current TC mode. Since nothing depends on the PLL selection before/after then encoder's pre_pll_enable/post_pll_disable hooks are called, the above steps can be moved to these hooks, so do that and remove the update_prepare()/complete() hooks. Reviewed-by: Mika Kahola Signed-off-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/20230323142035.1432621-30-imre.deak@intel.com --- drivers/gpu/drm/i915/display/intel_ddi.c | 49 ++++---------- drivers/gpu/drm/i915/display/intel_display.c | 78 ---------------------- drivers/gpu/drm/i915/display/intel_display_types.h | 6 -- 3 files changed, 12 insertions(+), 121 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index 62bd4196dc46..dc294717bcdf 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -3060,39 +3060,6 @@ void intel_ddi_update_pipe(struct intel_atomic_state *state, intel_hdcp_update_pipe(state, encoder, crtc_state, conn_state); } -static void -intel_ddi_update_prepare(struct intel_atomic_state *state, - struct intel_encoder *encoder, - struct intel_crtc *crtc) -{ - struct drm_i915_private *i915 = to_i915(state->base.dev); - struct intel_crtc_state *crtc_state = - crtc ? intel_atomic_get_new_crtc_state(state, crtc) : NULL; - int required_lanes = crtc_state ? crtc_state->lane_count : 1; - - drm_WARN_ON(state->base.dev, crtc && crtc->active); - - intel_tc_port_get_link(enc_to_dig_port(encoder), - required_lanes); - if (crtc_state && crtc_state->hw.active) { - struct intel_crtc *slave_crtc; - - intel_update_active_dpll(state, crtc, encoder); - - for_each_intel_crtc_in_pipe_mask(&i915->drm, slave_crtc, - intel_crtc_bigjoiner_slave_pipes(crtc_state)) - intel_update_active_dpll(state, slave_crtc, encoder); - } -} - -static void -intel_ddi_update_complete(struct intel_atomic_state *state, - struct intel_encoder *encoder, - struct intel_crtc *crtc) -{ - intel_tc_port_put_link(enc_to_dig_port(encoder)); -} - static void intel_ddi_pre_pll_enable(struct intel_atomic_state *state, struct intel_encoder *encoder, @@ -3104,9 +3071,20 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state, enum phy phy = intel_port_to_phy(dev_priv, encoder->port); bool is_tc_port = intel_phy_is_tc(dev_priv, phy); - if (is_tc_port) + if (is_tc_port) { + struct intel_crtc *master_crtc = + to_intel_crtc(crtc_state->uapi.crtc); + struct intel_crtc *slave_crtc; + intel_tc_port_get_link(dig_port, crtc_state->lane_count); + intel_update_active_dpll(state, master_crtc, encoder); + + for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, slave_crtc, + intel_crtc_bigjoiner_slave_pipes(crtc_state)) + intel_update_active_dpll(state, slave_crtc, encoder); + } + main_link_aux_power_domain_get(dig_port, crtc_state); if (is_tc_port && !intel_tc_port_in_tbt_alt_mode(dig_port)) @@ -4552,9 +4530,6 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port) if (intel_tc_port_init(dig_port, is_legacy) < 0) goto err; - - encoder->update_prepare = intel_ddi_update_prepare; - encoder->update_complete = intel_ddi_update_complete; } drm_WARN_ON(&dev_priv->drm, port > PORT_I); diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index ca0db2332ded..810156099b02 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1320,36 +1320,11 @@ static void intel_crtc_disable_planes(struct intel_atomic_state *state, intel_frontbuffer_flip(dev_priv, fb_bits); } -/* - * intel_connector_primary_encoder - get the primary encoder for a connector - * @connector: connector for which to return the encoder - * - * Returns the primary encoder for a connector. There is a 1:1 mapping from - * all connectors to their encoder, except for DP-MST connectors which have - * both a virtual and a primary encoder. These DP-MST primary encoders can be - * pointed to by as many DP-MST connectors as there are pipes. - */ -static struct intel_encoder * -intel_connector_primary_encoder(struct intel_connector *connector) -{ - struct intel_encoder *encoder; - - if (connector->mst_port) - return &dp_to_dig_port(connector->mst_port)->base; - - encoder = intel_attached_encoder(connector); - drm_WARN_ON(connector->base.dev, !encoder); - - return encoder; -} - static void intel_encoders_update_prepare(struct intel_atomic_state *state) { struct drm_i915_private *i915 = to_i915(state->base.dev); struct intel_crtc_state *new_crtc_state, *old_crtc_state; struct intel_crtc *crtc; - struct drm_connector_state *new_conn_state; - struct drm_connector *connector; int i; /* @@ -1365,57 +1340,6 @@ static void intel_encoders_update_prepare(struct intel_atomic_state *state) new_crtc_state->dpll_hw_state = old_crtc_state->dpll_hw_state; } } - - if (!state->modeset) - return; - - for_each_new_connector_in_state(&state->base, connector, new_conn_state, - i) { - struct intel_connector *intel_connector; - struct intel_encoder *encoder; - struct intel_crtc *crtc; - - if (!intel_connector_needs_modeset(state, connector)) - continue; - - intel_connector = to_intel_connector(connector); - encoder = intel_connector_primary_encoder(intel_connector); - if (!encoder->update_prepare) - continue; - - crtc = new_conn_state->crtc ? - to_intel_crtc(new_conn_state->crtc) : NULL; - encoder->update_prepare(state, encoder, crtc); - } -} - -static void intel_encoders_update_complete(struct intel_atomic_state *state) -{ - struct drm_connector_state *new_conn_state; - struct drm_connector *connector; - int i; - - if (!state->modeset) - return; - - for_each_new_connector_in_state(&state->base, connector, new_conn_state, - i) { - struct intel_connector *intel_connector; - struct intel_encoder *encoder; - struct intel_crtc *crtc; - - if (!intel_connector_needs_modeset(state, connector)) - continue; - - intel_connector = to_intel_connector(connector); - encoder = intel_connector_primary_encoder(intel_connector); - if (!encoder->update_complete) - continue; - - crtc = new_conn_state->crtc ? - to_intel_crtc(new_conn_state->crtc) : NULL; - encoder->update_complete(state, encoder, crtc); - } } static void intel_encoders_pre_pll_enable(struct intel_atomic_state *state, @@ -7445,8 +7369,6 @@ static void intel_atomic_commit_tail(struct intel_atomic_state *state) /* Now enable the clocks, plane, pipe, and connectors that we set up. */ dev_priv->display.funcs.display->commit_modeset_enables(state); - intel_encoders_update_complete(state); - if (state->modeset) intel_set_cdclk_post_plane_update(state); diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index a3ea929b0535..47395b39c8f4 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h @@ -170,9 +170,6 @@ struct intel_encoder { int (*compute_config_late)(struct intel_encoder *, struct intel_crtc_state *, struct drm_connector_state *); - void (*update_prepare)(struct intel_atomic_state *, - struct intel_encoder *, - struct intel_crtc *); void (*pre_pll_enable)(struct intel_atomic_state *, struct intel_encoder *, const struct intel_crtc_state *, @@ -185,9 +182,6 @@ struct intel_encoder { struct intel_encoder *, const struct intel_crtc_state *, const struct drm_connector_state *); - void (*update_complete)(struct intel_atomic_state *, - struct intel_encoder *, - struct intel_crtc *); void (*disable)(struct intel_atomic_state *, struct intel_encoder *, const struct intel_crtc_state *, -- cgit v1.2.3-59-g8ed1b From 98a07b82d8ac43f1cdb4fee8c340b020372c9392 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 31 Mar 2023 10:25:52 +0100 Subject: drm/i915/display/intel_display_debugfs: Fix incorrect param naming for 'intel_connector' Fixes the following W=1 kernel build warning(s): drivers/gpu/drm/i915/display/intel_display_debugfs.c:1668: warning: Function parameter or member 'intel_connector' not described in 'intel_connector_debugfs_add' drivers/gpu/drm/i915/display/intel_display_debugfs.c:1668: warning: Excess function parameter 'connector' description in 'intel_connector_debugfs_add' Cc: Jani Nikula Cc: Joonas Lahtinen Cc: Rodrigo Vivi Cc: Tvrtko Ursulin Cc: David Airlie Cc: Daniel Vetter Cc: intel-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org Signed-off-by: Lee Jones Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20230331092607.700644-5-lee@kernel.org --- drivers/gpu/drm/i915/display/intel_display_debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index bad29cdd139d..a9ef3a17b4f5 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -1470,7 +1470,7 @@ DEFINE_SHOW_ATTRIBUTE(intel_crtc_pipe); /** * intel_connector_debugfs_add - add i915 specific connector debugfs files - * @connector: pointer to a registered drm_connector + * @intel_connector: pointer to a registered drm_connector * * Cleanup will be done by drm_connector_unregister() through a call to * drm_debugfs_connector_remove(). -- cgit v1.2.3-59-g8ed1b From 63c154a0445aa58a1ecb933e6117327b67b6dfa0 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 31 Mar 2023 10:26:05 +0100 Subject: drm/i915/display/intel_display_power: Fix incorrectly documented function __intel_display_power_put_async() Fixes the following W=1 kernel build warning(s): drivers/gpu/drm/i915/display/intel_display_power.c:712: warning: expecting prototype for intel_display_power_put_async(). Prototype was for __intel_display_power_put_async() instead Cc: Jani Nikula Cc: Joonas Lahtinen Cc: Rodrigo Vivi Cc: Tvrtko Ursulin Cc: David Airlie Cc: Daniel Vetter Cc: Imre Deak Cc: intel-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org Signed-off-by: Lee Jones Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20230331092607.700644-18-lee@kernel.org --- drivers/gpu/drm/i915/display/intel_display_power.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 5e85572dc8e4..757bb1e2d07f 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -698,7 +698,7 @@ out_verify: } /** - * intel_display_power_put_async - release a power domain reference asynchronously + * __intel_display_power_put_async - release a power domain reference asynchronously * @i915: i915 device instance * @domain: power domain to reference * @wakeref: wakeref acquired for the reference that is being released -- cgit v1.2.3-59-g8ed1b From 75a252be27300c84c83c96399fa36fb5f6364124 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 31 Mar 2023 10:26:07 +0100 Subject: drm/i915/display/intel_wm: Fix a little doc-rot in intel_update_watermarks() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the following W=1 kernel build warning(s): drivers/gpu/drm/i915/display/intel_wm.c:46: warning: Function parameter or member 'i915' not described in 'intel_update_watermarks' drivers/gpu/drm/i915/display/intel_wm.c:46: warning: Excess function parameter 'dev_priv' description in 'intel_update_watermarks' Cc: Jani Nikula Cc: Joonas Lahtinen Cc: Rodrigo Vivi Cc: Tvrtko Ursulin Cc: David Airlie Cc: Daniel Vetter Cc: "Ville Syrjälä" Cc: intel-gfx@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org Signed-off-by: Lee Jones Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20230331092607.700644-20-lee@kernel.org --- drivers/gpu/drm/i915/display/intel_wm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_wm.c b/drivers/gpu/drm/i915/display/intel_wm.c index bb99179cd5fd..b615449e70b4 100644 --- a/drivers/gpu/drm/i915/display/intel_wm.c +++ b/drivers/gpu/drm/i915/display/intel_wm.c @@ -11,7 +11,7 @@ /** * intel_update_watermarks - update FIFO watermark values based on current modes - * @dev_priv: i915 device + * @i915: i915 device * * Calculate watermark values for the various WM regs based on current mode * and plane configuration. -- cgit v1.2.3-59-g8ed1b From 4ed22f1e52426635873416007d2c12e09615165f Mon Sep 17 00:00:00 2001 From: Ashutosh Dixit Date: Fri, 31 Mar 2023 19:41:46 -0700 Subject: drm/i915/hwmon: Use 0 to designate disabled PL1 power limit On ATSM the PL1 limit is disabled at power up. The previous uapi assumed that the PL1 limit is always enabled and therefore did not have a notion of a disabled PL1 limit. This results in erroneous PL1 limit values when the PL1 limit is disabled. For example at power up, the disabled ATSM PL1 limit was previously shown as 0 which means a low PL1 limit whereas the limit being disabled actually implies a high effective PL1 limit value. To get round this problem, the PL1 limit uapi is expanded to include a special value 0 to designate a disabled PL1 limit. A read value of 0 means that the PL1 power limit is disabled, writing 0 disables the limit. The link between this patch and the bugs mentioned below is as follows: * Because on ATSM the PL1 power limit is disabled on power up and there were no means to enable it, we previously implemented the means to enable the limit when the PL1 hwmon entry (power1_max) was written to. * Now there is a IGT igt@i915_hwmon@hwmon_write which (a) reads orig value from all hwmon sysfs (b) does a bunch of random writes and finally (c) restores the orig value read. On ATSM since the orig value is 0, when the IGT restores the 0 value, the PL1 limit is now enabled with a value of 0. * PL1 limit of 0 implies a low PL1 limit which causes GPU freq to fall to 100 MHz. This causes GuC FW load and several IGT's to start timing out and gives rise to these Intel CI bugs. After this patch, writing 0 would disable the PL1 limit instead of enabling it, avoiding the freq drop issue. v2: Add explanation for bugs mentioned below (Rodrigo) v3: Eliminate race during PL1 disable and verify (Tvrtko) Change return to -ENODEV if verify fails (Tvrtko) Link: https://gitlab.freedesktop.org/drm/intel/-/issues/8062 Link: https://gitlab.freedesktop.org/drm/intel/-/issues/8060 Signed-off-by: Ashutosh Dixit Reviewed-by: Rodrigo Vivi Signed-off-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20230401024146.1826092-1-ashutosh.dixit@intel.com --- .../ABI/testing/sysfs-driver-intel-i915-hwmon | 4 +++- drivers/gpu/drm/i915/i915_hwmon.c | 26 ++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon b/Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon index 2d6a472eef88..8d7d8f05f6cd 100644 --- a/Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon +++ b/Documentation/ABI/testing/sysfs-driver-intel-i915-hwmon @@ -14,7 +14,9 @@ Description: RW. Card reactive sustained (PL1/Tau) power limit in microwatts. The power controller will throttle the operating frequency if the power averaged over a window (typically seconds) - exceeds this limit. + exceeds this limit. A read value of 0 means that the PL1 + power limit is disabled, writing 0 disables the + limit. Writing values > 0 will enable the power limit. Only supported for particular Intel i915 graphics platforms. diff --git a/drivers/gpu/drm/i915/i915_hwmon.c b/drivers/gpu/drm/i915/i915_hwmon.c index 596dd2c07010..8e7dccc8d3a0 100644 --- a/drivers/gpu/drm/i915/i915_hwmon.c +++ b/drivers/gpu/drm/i915/i915_hwmon.c @@ -349,6 +349,8 @@ hwm_power_is_visible(const struct hwm_drvdata *ddat, u32 attr, int chan) } } +#define PL1_DISABLE 0 + /* * HW allows arbitrary PL1 limits to be set but silently clamps these values to * "typical but not guaranteed" min/max values in rg.pkg_power_sku. Follow the @@ -362,6 +364,14 @@ hwm_power_max_read(struct hwm_drvdata *ddat, long *val) intel_wakeref_t wakeref; u64 r, min, max; + /* Check if PL1 limit is disabled */ + with_intel_runtime_pm(ddat->uncore->rpm, wakeref) + r = intel_uncore_read(ddat->uncore, hwmon->rg.pkg_rapl_limit); + if (!(r & PKG_PWR_LIM_1_EN)) { + *val = PL1_DISABLE; + return 0; + } + *val = hwm_field_read_and_scale(ddat, hwmon->rg.pkg_rapl_limit, PKG_PWR_LIM_1, @@ -385,8 +395,24 @@ static int hwm_power_max_write(struct hwm_drvdata *ddat, long val) { struct i915_hwmon *hwmon = ddat->hwmon; + intel_wakeref_t wakeref; u32 nval; + /* Disable PL1 limit and verify, because the limit cannot be disabled on all platforms */ + if (val == PL1_DISABLE) { + mutex_lock(&hwmon->hwmon_lock); + with_intel_runtime_pm(ddat->uncore->rpm, wakeref) { + intel_uncore_rmw(ddat->uncore, hwmon->rg.pkg_rapl_limit, + PKG_PWR_LIM_1_EN, 0); + nval = intel_uncore_read(ddat->uncore, hwmon->rg.pkg_rapl_limit); + } + mutex_unlock(&hwmon->hwmon_lock); + + if (nval & PKG_PWR_LIM_1_EN) + return -ENODEV; + return 0; + } + /* Computation in 64-bits to avoid overflow. Round to nearest. */ nval = DIV_ROUND_CLOSEST_ULL((u64)val << hwmon->scl_shift_power, SF_POWER); nval = PKG_PWR_LIM_1_EN | REG_FIELD_PREP(PKG_PWR_LIM_1, nval); -- cgit v1.2.3-59-g8ed1b From 605f7c73133341d4b762cbd9a22174cc22d4c38b Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 29 Mar 2023 20:24:33 +0300 Subject: drm/i915: Fix fast wake AUX sync len MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fast wake should use 8 SYNC pulses for the preamble and 10-16 SYNC pulses for the precharge. Reduce our fast wake SYNC count to match the maximum value. We also use the maximum precharge length for normal AUX transactions. Cc: Jouni Högander Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230329172434.18744-1-ville.syrjala@linux.intel.com Reviewed-by: Jouni Högander --- drivers/gpu/drm/i915/display/intel_dp_aux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux.c b/drivers/gpu/drm/i915/display/intel_dp_aux.c index fbdca7bd725d..fa1fbac6f543 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux.c @@ -165,7 +165,7 @@ static u32 skl_get_aux_send_ctl(struct intel_dp *intel_dp, DP_AUX_CH_CTL_TIME_OUT_MAX | DP_AUX_CH_CTL_RECEIVE_ERROR | (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | - DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(32) | + DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(24) | DP_AUX_CH_CTL_SYNC_PULSE_SKL(32); if (intel_tc_port_in_tbt_alt_mode(dig_port)) -- cgit v1.2.3-59-g8ed1b From 26bfc3f36f2104c174dfc72415547d5c28ef3f1c Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Wed, 29 Mar 2023 20:24:34 +0300 Subject: drm/i915: Explain the magic numbers for AUX SYNC/precharge length MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the hardcoded final numbers in the AUX SYNC/precharge setup, and derive those from numbers from the (e)DP specs. The new functions can serve as the single point of truth for the number of SYNC pulses we use. Cc: Jouni Högander Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20230329172434.18744-2-ville.syrjala@linux.intel.com Reviewed-by: Jouni Högander --- drivers/gpu/drm/i915/display/intel_dp_aux.c | 32 ++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux.c b/drivers/gpu/drm/i915/display/intel_dp_aux.c index fa1fbac6f543..705915d50565 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_aux.c +++ b/drivers/gpu/drm/i915/display/intel_dp_aux.c @@ -119,6 +119,32 @@ static u32 skl_get_aux_clock_divider(struct intel_dp *intel_dp, int index) return index ? 0 : 1; } +static int intel_dp_aux_sync_len(void) +{ + int precharge = 16; /* 10-16 */ + int preamble = 16; + + return precharge + preamble; +} + +static int intel_dp_aux_fw_sync_len(void) +{ + int precharge = 16; /* 10-16 */ + int preamble = 8; + + return precharge + preamble; +} + +static int g4x_dp_aux_precharge_len(void) +{ + int precharge_min = 10; + int preamble = 16; + + /* HW wants the length of the extra precharge in 2us units */ + return (intel_dp_aux_sync_len() - + precharge_min - preamble) / 2; +} + static u32 g4x_get_aux_send_ctl(struct intel_dp *intel_dp, int send_bytes, u32 aux_clock_divider) @@ -141,7 +167,7 @@ static u32 g4x_get_aux_send_ctl(struct intel_dp *intel_dp, timeout | DP_AUX_CH_CTL_RECEIVE_ERROR | (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | - (3 << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | + (g4x_dp_aux_precharge_len() << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT); } @@ -165,8 +191,8 @@ static u32 skl_get_aux_send_ctl(struct intel_dp *intel_dp, DP_AUX_CH_CTL_TIME_OUT_MAX | DP_AUX_CH_CTL_RECEIVE_ERROR | (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | - DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(24) | - DP_AUX_CH_CTL_SYNC_PULSE_SKL(32); + DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(intel_dp_aux_fw_sync_len()) | + DP_AUX_CH_CTL_SYNC_PULSE_SKL(intel_dp_aux_sync_len()); if (intel_tc_port_in_tbt_alt_mode(dig_port)) ret |= DP_AUX_CH_CTL_TBT_IO; -- cgit v1.2.3-59-g8ed1b From 689e61a4fd6872537913b998101f364fe79a4f70 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 31 Mar 2023 12:09:48 +0300 Subject: drm/i915/wm: split out SKL+ watermark regs to a separate file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clean up i915_reg.h by splitting out SKL+ watermark regs to display/skl_watermark_regs.h. v2: Rebased Cc: Ville Syrjälä Reviewed-by: Nirmoy Das # v1 Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20230331090949.2858951-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_display_power.c | 1 + drivers/gpu/drm/i915/display/skl_watermark.c | 1 + drivers/gpu/drm/i915/display/skl_watermark_regs.h | 160 +++++++++++++++++++++ drivers/gpu/drm/i915/gvt/handlers.c | 1 + drivers/gpu/drm/i915/i915_reg.h | 149 ------------------- drivers/gpu/drm/i915/intel_gvt_mmio_table.c | 1 + 6 files changed, 164 insertions(+), 149 deletions(-) create mode 100644 drivers/gpu/drm/i915/display/skl_watermark_regs.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 757bb1e2d07f..7c9f4288329e 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -22,6 +22,7 @@ #include "intel_pps_regs.h" #include "intel_snps_phy.h" #include "skl_watermark.h" +#include "skl_watermark_regs.h" #include "vlv_sideband.h" #define for_each_power_domain_well(__dev_priv, __power_well, __domain) \ diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index 5296a20d62d3..1c7e6468f3e3 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -21,6 +21,7 @@ #include "intel_pcode.h" #include "intel_wm.h" #include "skl_watermark.h" +#include "skl_watermark_regs.h" static void skl_sagv_disable(struct drm_i915_private *i915); diff --git a/drivers/gpu/drm/i915/display/skl_watermark_regs.h b/drivers/gpu/drm/i915/display/skl_watermark_regs.h new file mode 100644 index 000000000000..628c5920ad49 --- /dev/null +++ b/drivers/gpu/drm/i915/display/skl_watermark_regs.h @@ -0,0 +1,160 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2023 Intel Corporation + */ + +#ifndef __SKL_WATERMARK_REGS_H__ +#define __SKL_WATERMARK_REGS_H__ + +#include "intel_display_reg_defs.h" + +#define _PIPEA_MBUS_DBOX_CTL 0x7003C +#define _PIPEB_MBUS_DBOX_CTL 0x7103C +#define PIPE_MBUS_DBOX_CTL(pipe) _MMIO_PIPE(pipe, _PIPEA_MBUS_DBOX_CTL, \ + _PIPEB_MBUS_DBOX_CTL) +#define MBUS_DBOX_B2B_TRANSACTIONS_MAX_MASK REG_GENMASK(24, 20) /* tgl+ */ +#define MBUS_DBOX_B2B_TRANSACTIONS_MAX(x) REG_FIELD_PREP(MBUS_DBOX_B2B_TRANSACTIONS_MAX_MASK, x) +#define MBUS_DBOX_B2B_TRANSACTIONS_DELAY_MASK REG_GENMASK(19, 17) /* tgl+ */ +#define MBUS_DBOX_B2B_TRANSACTIONS_DELAY(x) REG_FIELD_PREP(MBUS_DBOX_B2B_TRANSACTIONS_DELAY_MASK, x) +#define MBUS_DBOX_REGULATE_B2B_TRANSACTIONS_EN REG_BIT(16) /* tgl+ */ +#define MBUS_DBOX_BW_CREDIT_MASK REG_GENMASK(15, 14) +#define MBUS_DBOX_BW_CREDIT(x) REG_FIELD_PREP(MBUS_DBOX_BW_CREDIT_MASK, x) +#define MBUS_DBOX_BW_4CREDITS_MTL REG_FIELD_PREP(MBUS_DBOX_BW_CREDIT_MASK, 0x2) +#define MBUS_DBOX_BW_8CREDITS_MTL REG_FIELD_PREP(MBUS_DBOX_BW_CREDIT_MASK, 0x3) +#define MBUS_DBOX_B_CREDIT_MASK REG_GENMASK(12, 8) +#define MBUS_DBOX_B_CREDIT(x) REG_FIELD_PREP(MBUS_DBOX_B_CREDIT_MASK, x) +#define MBUS_DBOX_I_CREDIT_MASK REG_GENMASK(7, 5) +#define MBUS_DBOX_I_CREDIT(x) REG_FIELD_PREP(MBUS_DBOX_I_CREDIT_MASK, x) +#define MBUS_DBOX_A_CREDIT_MASK REG_GENMASK(3, 0) +#define MBUS_DBOX_A_CREDIT(x) REG_FIELD_PREP(MBUS_DBOX_A_CREDIT_MASK, x) + +#define MBUS_UBOX_CTL _MMIO(0x4503C) +#define MBUS_BBOX_CTL_S1 _MMIO(0x45040) +#define MBUS_BBOX_CTL_S2 _MMIO(0x45044) + +#define MBUS_CTL _MMIO(0x4438C) +#define MBUS_JOIN REG_BIT(31) +#define MBUS_HASHING_MODE_MASK REG_BIT(30) +#define MBUS_HASHING_MODE_2x2 REG_FIELD_PREP(MBUS_HASHING_MODE_MASK, 0) +#define MBUS_HASHING_MODE_1x4 REG_FIELD_PREP(MBUS_HASHING_MODE_MASK, 1) +#define MBUS_JOIN_PIPE_SELECT_MASK REG_GENMASK(28, 26) +#define MBUS_JOIN_PIPE_SELECT(pipe) REG_FIELD_PREP(MBUS_JOIN_PIPE_SELECT_MASK, pipe) +#define MBUS_JOIN_PIPE_SELECT_NONE MBUS_JOIN_PIPE_SELECT(7) + +/* Watermark register definitions for SKL */ +#define _CUR_WM_A_0 0x70140 +#define _CUR_WM_B_0 0x71140 +#define _CUR_WM_SAGV_A 0x70158 +#define _CUR_WM_SAGV_B 0x71158 +#define _CUR_WM_SAGV_TRANS_A 0x7015C +#define _CUR_WM_SAGV_TRANS_B 0x7115C +#define _CUR_WM_TRANS_A 0x70168 +#define _CUR_WM_TRANS_B 0x71168 +#define _PLANE_WM_1_A_0 0x70240 +#define _PLANE_WM_1_B_0 0x71240 +#define _PLANE_WM_2_A_0 0x70340 +#define _PLANE_WM_2_B_0 0x71340 +#define _PLANE_WM_SAGV_1_A 0x70258 +#define _PLANE_WM_SAGV_1_B 0x71258 +#define _PLANE_WM_SAGV_2_A 0x70358 +#define _PLANE_WM_SAGV_2_B 0x71358 +#define _PLANE_WM_SAGV_TRANS_1_A 0x7025C +#define _PLANE_WM_SAGV_TRANS_1_B 0x7125C +#define _PLANE_WM_SAGV_TRANS_2_A 0x7035C +#define _PLANE_WM_SAGV_TRANS_2_B 0x7135C +#define _PLANE_WM_TRANS_1_A 0x70268 +#define _PLANE_WM_TRANS_1_B 0x71268 +#define _PLANE_WM_TRANS_2_A 0x70368 +#define _PLANE_WM_TRANS_2_B 0x71368 +#define PLANE_WM_EN (1 << 31) +#define PLANE_WM_IGNORE_LINES (1 << 30) +#define PLANE_WM_LINES_MASK REG_GENMASK(26, 14) +#define PLANE_WM_BLOCKS_MASK REG_GENMASK(11, 0) + +#define _CUR_WM_0(pipe) _PIPE(pipe, _CUR_WM_A_0, _CUR_WM_B_0) +#define CUR_WM(pipe, level) _MMIO(_CUR_WM_0(pipe) + ((4) * (level))) +#define CUR_WM_SAGV(pipe) _MMIO_PIPE(pipe, _CUR_WM_SAGV_A, _CUR_WM_SAGV_B) +#define CUR_WM_SAGV_TRANS(pipe) _MMIO_PIPE(pipe, _CUR_WM_SAGV_TRANS_A, _CUR_WM_SAGV_TRANS_B) +#define CUR_WM_TRANS(pipe) _MMIO_PIPE(pipe, _CUR_WM_TRANS_A, _CUR_WM_TRANS_B) +#define _PLANE_WM_1(pipe) _PIPE(pipe, _PLANE_WM_1_A_0, _PLANE_WM_1_B_0) +#define _PLANE_WM_2(pipe) _PIPE(pipe, _PLANE_WM_2_A_0, _PLANE_WM_2_B_0) +#define _PLANE_WM_BASE(pipe, plane) \ + _PLANE(plane, _PLANE_WM_1(pipe), _PLANE_WM_2(pipe)) +#define PLANE_WM(pipe, plane, level) \ + _MMIO(_PLANE_WM_BASE(pipe, plane) + ((4) * (level))) +#define _PLANE_WM_SAGV_1(pipe) \ + _PIPE(pipe, _PLANE_WM_SAGV_1_A, _PLANE_WM_SAGV_1_B) +#define _PLANE_WM_SAGV_2(pipe) \ + _PIPE(pipe, _PLANE_WM_SAGV_2_A, _PLANE_WM_SAGV_2_B) +#define PLANE_WM_SAGV(pipe, plane) \ + _MMIO(_PLANE(plane, _PLANE_WM_SAGV_1(pipe), _PLANE_WM_SAGV_2(pipe))) +#define _PLANE_WM_SAGV_TRANS_1(pipe) \ + _PIPE(pipe, _PLANE_WM_SAGV_TRANS_1_A, _PLANE_WM_SAGV_TRANS_1_B) +#define _PLANE_WM_SAGV_TRANS_2(pipe) \ + _PIPE(pipe, _PLANE_WM_SAGV_TRANS_2_A, _PLANE_WM_SAGV_TRANS_2_B) +#define PLANE_WM_SAGV_TRANS(pipe, plane) \ + _MMIO(_PLANE(plane, _PLANE_WM_SAGV_TRANS_1(pipe), _PLANE_WM_SAGV_TRANS_2(pipe))) +#define _PLANE_WM_TRANS_1(pipe) \ + _PIPE(pipe, _PLANE_WM_TRANS_1_A, _PLANE_WM_TRANS_1_B) +#define _PLANE_WM_TRANS_2(pipe) \ + _PIPE(pipe, _PLANE_WM_TRANS_2_A, _PLANE_WM_TRANS_2_B) +#define PLANE_WM_TRANS(pipe, plane) \ + _MMIO(_PLANE(plane, _PLANE_WM_TRANS_1(pipe), _PLANE_WM_TRANS_2(pipe))) + +#define _PLANE_BUF_CFG_1_B 0x7127c +#define _PLANE_BUF_CFG_2_B 0x7137c +#define _PLANE_BUF_CFG_1(pipe) \ + _PIPE(pipe, _PLANE_BUF_CFG_1_A, _PLANE_BUF_CFG_1_B) +#define _PLANE_BUF_CFG_2(pipe) \ + _PIPE(pipe, _PLANE_BUF_CFG_2_A, _PLANE_BUF_CFG_2_B) +#define PLANE_BUF_CFG(pipe, plane) \ + _MMIO_PLANE(plane, _PLANE_BUF_CFG_1(pipe), _PLANE_BUF_CFG_2(pipe)) + +#define _PLANE_NV12_BUF_CFG_1_B 0x71278 +#define _PLANE_NV12_BUF_CFG_2_B 0x71378 +#define _PLANE_NV12_BUF_CFG_1(pipe) \ + _PIPE(pipe, _PLANE_NV12_BUF_CFG_1_A, _PLANE_NV12_BUF_CFG_1_B) +#define _PLANE_NV12_BUF_CFG_2(pipe) \ + _PIPE(pipe, _PLANE_NV12_BUF_CFG_2_A, _PLANE_NV12_BUF_CFG_2_B) +#define PLANE_NV12_BUF_CFG(pipe, plane) \ + _MMIO_PLANE(plane, _PLANE_NV12_BUF_CFG_1(pipe), _PLANE_NV12_BUF_CFG_2(pipe)) + +/* SKL new cursor registers */ +#define _CUR_BUF_CFG_A 0x7017c +#define _CUR_BUF_CFG_B 0x7117c +#define CUR_BUF_CFG(pipe) _MMIO_PIPE(pipe, _CUR_BUF_CFG_A, _CUR_BUF_CFG_B) + +/* + * The below are numbered starting from "S1" on gen11/gen12, but starting + * with display 13, the bspec switches to a 0-based numbering scheme + * (although the addresses stay the same so new S0 = old S1, new S1 = old S2). + * We'll just use the 0-based numbering here for all platforms since it's the + * way things will be named by the hardware team going forward, plus it's more + * consistent with how most of the rest of our registers are named. + */ +#define _DBUF_CTL_S0 0x45008 +#define _DBUF_CTL_S1 0x44FE8 +#define _DBUF_CTL_S2 0x44300 +#define _DBUF_CTL_S3 0x44304 +#define DBUF_CTL_S(slice) _MMIO(_PICK(slice, \ + _DBUF_CTL_S0, \ + _DBUF_CTL_S1, \ + _DBUF_CTL_S2, \ + _DBUF_CTL_S3)) +#define DBUF_POWER_REQUEST REG_BIT(31) +#define DBUF_POWER_STATE REG_BIT(30) +#define DBUF_TRACKER_STATE_SERVICE_MASK REG_GENMASK(23, 19) +#define DBUF_TRACKER_STATE_SERVICE(x) REG_FIELD_PREP(DBUF_TRACKER_STATE_SERVICE_MASK, x) +#define DBUF_MIN_TRACKER_STATE_SERVICE_MASK REG_GENMASK(18, 16) /* ADL-P+ */ +#define DBUF_MIN_TRACKER_STATE_SERVICE(x) REG_FIELD_PREP(DBUF_MIN_TRACKER_STATE_SERVICE_MASK, x) /* ADL-P+ */ + +#define MTL_LATENCY_LP0_LP1 _MMIO(0x45780) +#define MTL_LATENCY_LP2_LP3 _MMIO(0x45784) +#define MTL_LATENCY_LP4_LP5 _MMIO(0x45788) +#define MTL_LATENCY_LEVEL_EVEN_MASK REG_GENMASK(12, 0) +#define MTL_LATENCY_LEVEL_ODD_MASK REG_GENMASK(28, 16) + +#define MTL_LATENCY_SAGV _MMIO(0x4578c) +#define MTL_LATENCY_QCLK_SAGV REG_GENMASK(12, 0) + +#endif /* __SKL_WATERMARK_REGS_H__ */ diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index ea6a21dc8322..8bfccae7e026 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -48,6 +48,7 @@ #include "display/intel_fbc.h" #include "display/intel_fdi_regs.h" #include "display/intel_pps_regs.h" +#include "display/skl_watermark_regs.h" #include "display/vlv_dsi_pll_regs.h" #include "gt/intel_gt_regs.h" diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index a350ee2288f2..3519b1ac4160 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1057,39 +1057,6 @@ #define MBUS_ABOX_BT_CREDIT_POOL1_MASK (0x1F << 0) #define MBUS_ABOX_BT_CREDIT_POOL1(x) ((x) << 0) -#define _PIPEA_MBUS_DBOX_CTL 0x7003C -#define _PIPEB_MBUS_DBOX_CTL 0x7103C -#define PIPE_MBUS_DBOX_CTL(pipe) _MMIO_PIPE(pipe, _PIPEA_MBUS_DBOX_CTL, \ - _PIPEB_MBUS_DBOX_CTL) -#define MBUS_DBOX_B2B_TRANSACTIONS_MAX_MASK REG_GENMASK(24, 20) /* tgl+ */ -#define MBUS_DBOX_B2B_TRANSACTIONS_MAX(x) REG_FIELD_PREP(MBUS_DBOX_B2B_TRANSACTIONS_MAX_MASK, x) -#define MBUS_DBOX_B2B_TRANSACTIONS_DELAY_MASK REG_GENMASK(19, 17) /* tgl+ */ -#define MBUS_DBOX_B2B_TRANSACTIONS_DELAY(x) REG_FIELD_PREP(MBUS_DBOX_B2B_TRANSACTIONS_DELAY_MASK, x) -#define MBUS_DBOX_REGULATE_B2B_TRANSACTIONS_EN REG_BIT(16) /* tgl+ */ -#define MBUS_DBOX_BW_CREDIT_MASK REG_GENMASK(15, 14) -#define MBUS_DBOX_BW_CREDIT(x) REG_FIELD_PREP(MBUS_DBOX_BW_CREDIT_MASK, x) -#define MBUS_DBOX_BW_4CREDITS_MTL REG_FIELD_PREP(MBUS_DBOX_BW_CREDIT_MASK, 0x2) -#define MBUS_DBOX_BW_8CREDITS_MTL REG_FIELD_PREP(MBUS_DBOX_BW_CREDIT_MASK, 0x3) -#define MBUS_DBOX_B_CREDIT_MASK REG_GENMASK(12, 8) -#define MBUS_DBOX_B_CREDIT(x) REG_FIELD_PREP(MBUS_DBOX_B_CREDIT_MASK, x) -#define MBUS_DBOX_I_CREDIT_MASK REG_GENMASK(7, 5) -#define MBUS_DBOX_I_CREDIT(x) REG_FIELD_PREP(MBUS_DBOX_I_CREDIT_MASK, x) -#define MBUS_DBOX_A_CREDIT_MASK REG_GENMASK(3, 0) -#define MBUS_DBOX_A_CREDIT(x) REG_FIELD_PREP(MBUS_DBOX_A_CREDIT_MASK, x) - -#define MBUS_UBOX_CTL _MMIO(0x4503C) -#define MBUS_BBOX_CTL_S1 _MMIO(0x45040) -#define MBUS_BBOX_CTL_S2 _MMIO(0x45044) - -#define MBUS_CTL _MMIO(0x4438C) -#define MBUS_JOIN REG_BIT(31) -#define MBUS_HASHING_MODE_MASK REG_BIT(30) -#define MBUS_HASHING_MODE_2x2 REG_FIELD_PREP(MBUS_HASHING_MODE_MASK, 0) -#define MBUS_HASHING_MODE_1x4 REG_FIELD_PREP(MBUS_HASHING_MODE_MASK, 1) -#define MBUS_JOIN_PIPE_SELECT_MASK REG_GENMASK(28, 26) -#define MBUS_JOIN_PIPE_SELECT(pipe) REG_FIELD_PREP(MBUS_JOIN_PIPE_SELECT_MASK, pipe) -#define MBUS_JOIN_PIPE_SELECT_NONE MBUS_JOIN_PIPE_SELECT(7) - /* Make render/texture TLB fetches lower priorty than associated data * fetches. This is not turned on by default */ @@ -3191,66 +3158,6 @@ #define I965_CURSOR_MAX_WM 32 #define I965_CURSOR_DFT_WM 8 -/* Watermark register definitions for SKL */ -#define _CUR_WM_A_0 0x70140 -#define _CUR_WM_B_0 0x71140 -#define _CUR_WM_SAGV_A 0x70158 -#define _CUR_WM_SAGV_B 0x71158 -#define _CUR_WM_SAGV_TRANS_A 0x7015C -#define _CUR_WM_SAGV_TRANS_B 0x7115C -#define _CUR_WM_TRANS_A 0x70168 -#define _CUR_WM_TRANS_B 0x71168 -#define _PLANE_WM_1_A_0 0x70240 -#define _PLANE_WM_1_B_0 0x71240 -#define _PLANE_WM_2_A_0 0x70340 -#define _PLANE_WM_2_B_0 0x71340 -#define _PLANE_WM_SAGV_1_A 0x70258 -#define _PLANE_WM_SAGV_1_B 0x71258 -#define _PLANE_WM_SAGV_2_A 0x70358 -#define _PLANE_WM_SAGV_2_B 0x71358 -#define _PLANE_WM_SAGV_TRANS_1_A 0x7025C -#define _PLANE_WM_SAGV_TRANS_1_B 0x7125C -#define _PLANE_WM_SAGV_TRANS_2_A 0x7035C -#define _PLANE_WM_SAGV_TRANS_2_B 0x7135C -#define _PLANE_WM_TRANS_1_A 0x70268 -#define _PLANE_WM_TRANS_1_B 0x71268 -#define _PLANE_WM_TRANS_2_A 0x70368 -#define _PLANE_WM_TRANS_2_B 0x71368 -#define PLANE_WM_EN (1 << 31) -#define PLANE_WM_IGNORE_LINES (1 << 30) -#define PLANE_WM_LINES_MASK REG_GENMASK(26, 14) -#define PLANE_WM_BLOCKS_MASK REG_GENMASK(11, 0) - -#define _CUR_WM_0(pipe) _PIPE(pipe, _CUR_WM_A_0, _CUR_WM_B_0) -#define CUR_WM(pipe, level) _MMIO(_CUR_WM_0(pipe) + ((4) * (level))) -#define CUR_WM_SAGV(pipe) _MMIO_PIPE(pipe, _CUR_WM_SAGV_A, _CUR_WM_SAGV_B) -#define CUR_WM_SAGV_TRANS(pipe) _MMIO_PIPE(pipe, _CUR_WM_SAGV_TRANS_A, _CUR_WM_SAGV_TRANS_B) -#define CUR_WM_TRANS(pipe) _MMIO_PIPE(pipe, _CUR_WM_TRANS_A, _CUR_WM_TRANS_B) -#define _PLANE_WM_1(pipe) _PIPE(pipe, _PLANE_WM_1_A_0, _PLANE_WM_1_B_0) -#define _PLANE_WM_2(pipe) _PIPE(pipe, _PLANE_WM_2_A_0, _PLANE_WM_2_B_0) -#define _PLANE_WM_BASE(pipe, plane) \ - _PLANE(plane, _PLANE_WM_1(pipe), _PLANE_WM_2(pipe)) -#define PLANE_WM(pipe, plane, level) \ - _MMIO(_PLANE_WM_BASE(pipe, plane) + ((4) * (level))) -#define _PLANE_WM_SAGV_1(pipe) \ - _PIPE(pipe, _PLANE_WM_SAGV_1_A, _PLANE_WM_SAGV_1_B) -#define _PLANE_WM_SAGV_2(pipe) \ - _PIPE(pipe, _PLANE_WM_SAGV_2_A, _PLANE_WM_SAGV_2_B) -#define PLANE_WM_SAGV(pipe, plane) \ - _MMIO(_PLANE(plane, _PLANE_WM_SAGV_1(pipe), _PLANE_WM_SAGV_2(pipe))) -#define _PLANE_WM_SAGV_TRANS_1(pipe) \ - _PIPE(pipe, _PLANE_WM_SAGV_TRANS_1_A, _PLANE_WM_SAGV_TRANS_1_B) -#define _PLANE_WM_SAGV_TRANS_2(pipe) \ - _PIPE(pipe, _PLANE_WM_SAGV_TRANS_2_A, _PLANE_WM_SAGV_TRANS_2_B) -#define PLANE_WM_SAGV_TRANS(pipe, plane) \ - _MMIO(_PLANE(plane, _PLANE_WM_SAGV_TRANS_1(pipe), _PLANE_WM_SAGV_TRANS_2(pipe))) -#define _PLANE_WM_TRANS_1(pipe) \ - _PIPE(pipe, _PLANE_WM_TRANS_1_A, _PLANE_WM_TRANS_1_B) -#define _PLANE_WM_TRANS_2(pipe) \ - _PIPE(pipe, _PLANE_WM_TRANS_2_A, _PLANE_WM_TRANS_2_B) -#define PLANE_WM_TRANS(pipe, plane) \ - _MMIO(_PLANE(plane, _PLANE_WM_TRANS_1(pipe), _PLANE_WM_TRANS_2(pipe))) - /* define the Watermark register on Ironlake */ #define _WM0_PIPEA_ILK 0x45100 #define _WM0_PIPEB_ILK 0x45104 @@ -4188,24 +4095,6 @@ #define PLANE_CHICKEN(pipe, plane) \ _MMIO_PLANE(plane, _PLANE_CHICKEN_1(pipe), _PLANE_CHICKEN_2(pipe)) -#define _PLANE_BUF_CFG_1_B 0x7127c -#define _PLANE_BUF_CFG_2_B 0x7137c -#define _PLANE_BUF_CFG_1(pipe) \ - _PIPE(pipe, _PLANE_BUF_CFG_1_A, _PLANE_BUF_CFG_1_B) -#define _PLANE_BUF_CFG_2(pipe) \ - _PIPE(pipe, _PLANE_BUF_CFG_2_A, _PLANE_BUF_CFG_2_B) -#define PLANE_BUF_CFG(pipe, plane) \ - _MMIO_PLANE(plane, _PLANE_BUF_CFG_1(pipe), _PLANE_BUF_CFG_2(pipe)) - -#define _PLANE_NV12_BUF_CFG_1_B 0x71278 -#define _PLANE_NV12_BUF_CFG_2_B 0x71378 -#define _PLANE_NV12_BUF_CFG_1(pipe) \ - _PIPE(pipe, _PLANE_NV12_BUF_CFG_1_A, _PLANE_NV12_BUF_CFG_1_B) -#define _PLANE_NV12_BUF_CFG_2(pipe) \ - _PIPE(pipe, _PLANE_NV12_BUF_CFG_2_A, _PLANE_NV12_BUF_CFG_2_B) -#define PLANE_NV12_BUF_CFG(pipe, plane) \ - _MMIO_PLANE(plane, _PLANE_NV12_BUF_CFG_1(pipe), _PLANE_NV12_BUF_CFG_2(pipe)) - #define _PLANE_AUX_DIST_1_B 0x711c0 #define _PLANE_AUX_DIST_2_B 0x712c0 #define _PLANE_AUX_DIST_1(pipe) \ @@ -4288,11 +4177,6 @@ _SEL_FETCH_PLANE_OFFSET_1_A - \ _SEL_FETCH_PLANE_BASE_1_A) -/* SKL new cursor registers */ -#define _CUR_BUF_CFG_A 0x7017c -#define _CUR_BUF_CFG_B 0x7117c -#define CUR_BUF_CFG(pipe) _MMIO_PIPE(pipe, _CUR_BUF_CFG_A, _CUR_BUF_CFG_B) - /* VBIOS regs */ #define VGACNTRL _MMIO(0x71400) # define VGA_DISP_DISABLE (1 << 31) @@ -4952,30 +4836,6 @@ #define DISP_DATA_PARTITION_5_6 (1 << 6) #define DISP_IPC_ENABLE (1 << 3) -/* - * The below are numbered starting from "S1" on gen11/gen12, but starting - * with display 13, the bspec switches to a 0-based numbering scheme - * (although the addresses stay the same so new S0 = old S1, new S1 = old S2). - * We'll just use the 0-based numbering here for all platforms since it's the - * way things will be named by the hardware team going forward, plus it's more - * consistent with how most of the rest of our registers are named. - */ -#define _DBUF_CTL_S0 0x45008 -#define _DBUF_CTL_S1 0x44FE8 -#define _DBUF_CTL_S2 0x44300 -#define _DBUF_CTL_S3 0x44304 -#define DBUF_CTL_S(slice) _MMIO(_PICK(slice, \ - _DBUF_CTL_S0, \ - _DBUF_CTL_S1, \ - _DBUF_CTL_S2, \ - _DBUF_CTL_S3)) -#define DBUF_POWER_REQUEST REG_BIT(31) -#define DBUF_POWER_STATE REG_BIT(30) -#define DBUF_TRACKER_STATE_SERVICE_MASK REG_GENMASK(23, 19) -#define DBUF_TRACKER_STATE_SERVICE(x) REG_FIELD_PREP(DBUF_TRACKER_STATE_SERVICE_MASK, x) -#define DBUF_MIN_TRACKER_STATE_SERVICE_MASK REG_GENMASK(18, 16) /* ADL-P+ */ -#define DBUF_MIN_TRACKER_STATE_SERVICE(x) REG_FIELD_PREP(DBUF_MIN_TRACKER_STATE_SERVICE_MASK, x) /* ADL-P+ */ - #define GEN7_MSG_CTL _MMIO(0x45010) #define WAIT_FOR_PCH_RESET_ACK (1 << 1) #define WAIT_FOR_PCH_FLR_ACK (1 << 0) @@ -6908,15 +6768,6 @@ enum skl_power_gate { #define MTL_CLKGATE_DIS_TRANS(trans) _MMIO_TRANS2(trans, _MTL_CLKGATE_DIS_TRANS_A) #define MTL_CLKGATE_DIS_TRANS_DMASC_GATING_DIS REG_BIT(7) -#define MTL_LATENCY_LP0_LP1 _MMIO(0x45780) -#define MTL_LATENCY_LP2_LP3 _MMIO(0x45784) -#define MTL_LATENCY_LP4_LP5 _MMIO(0x45788) -#define MTL_LATENCY_LEVEL_EVEN_MASK REG_GENMASK(12, 0) -#define MTL_LATENCY_LEVEL_ODD_MASK REG_GENMASK(28, 16) - -#define MTL_LATENCY_SAGV _MMIO(0x4578c) -#define MTL_LATENCY_QCLK_SAGV REG_GENMASK(12, 0) - #define MTL_MEM_SS_INFO_GLOBAL _MMIO(0x45700) #define MTL_N_OF_ENABLED_QGV_POINTS_MASK REG_GENMASK(11, 8) #define MTL_N_OF_POPULATED_CH_MASK REG_GENMASK(7, 4) diff --git a/drivers/gpu/drm/i915/intel_gvt_mmio_table.c b/drivers/gpu/drm/i915/intel_gvt_mmio_table.c index 4bee209da425..3b49d2e6a66f 100644 --- a/drivers/gpu/drm/i915/intel_gvt_mmio_table.c +++ b/drivers/gpu/drm/i915/intel_gvt_mmio_table.c @@ -11,6 +11,7 @@ #include "display/intel_dpio_phy.h" #include "display/intel_fdi_regs.h" #include "display/intel_lvds_regs.h" +#include "display/skl_watermark_regs.h" #include "display/vlv_dsi_pll_regs.h" #include "gt/intel_gt_regs.h" #include "gvt/gvt.h" -- cgit v1.2.3-59-g8ed1b From 7f6947fd36f2c562040ad5a2d3d1783440a4aeb6 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 31 Mar 2023 12:09:49 +0300 Subject: drm/i915/psr: split out PSR regs to a separate file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clean up i915_reg.h by splitting out PSR regs to display/intel_psr_regs.h. Cc: Ville Syrjälä Reviewed-by: Nirmoy Das Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20230331090949.2858951-2-jani.nikula@intel.com --- .../gpu/drm/i915/display/intel_display_debugfs.c | 1 + drivers/gpu/drm/i915/display/intel_psr.c | 1 + drivers/gpu/drm/i915/display/intel_psr_regs.h | 260 +++++++++++++++++++++ drivers/gpu/drm/i915/gvt/handlers.c | 1 + drivers/gpu/drm/i915/i915_irq.c | 1 + drivers/gpu/drm/i915/i915_reg.h | 249 -------------------- drivers/gpu/drm/i915/intel_gvt_mmio_table.c | 1 + 7 files changed, 265 insertions(+), 249 deletions(-) create mode 100644 drivers/gpu/drm/i915/display/intel_psr_regs.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c index a9ef3a17b4f5..45113ae107ba 100644 --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c @@ -29,6 +29,7 @@ #include "intel_hotplug.h" #include "intel_panel.h" #include "intel_psr.h" +#include "intel_psr_regs.h" #include "intel_sprite.h" #include "intel_wm.h" diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index ecf1781c1556..6badfff2b4a2 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -34,6 +34,7 @@ #include "intel_dp_aux.h" #include "intel_hdmi.h" #include "intel_psr.h" +#include "intel_psr_regs.h" #include "intel_snps_phy.h" #include "skl_universal_plane.h" diff --git a/drivers/gpu/drm/i915/display/intel_psr_regs.h b/drivers/gpu/drm/i915/display/intel_psr_regs.h new file mode 100644 index 000000000000..958d8cabc44b --- /dev/null +++ b/drivers/gpu/drm/i915/display/intel_psr_regs.h @@ -0,0 +1,260 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2023 Intel Corporation + */ + +#ifndef __INTEL_PSR_REGS_H__ +#define __INTEL_PSR_REGS_H__ + +#include "intel_display_reg_defs.h" + +#define TRANS_EXITLINE(trans) _MMIO_TRANS2((trans), _TRANS_EXITLINE_A) +#define EXITLINE_ENABLE REG_BIT(31) +#define EXITLINE_MASK REG_GENMASK(12, 0) +#define EXITLINE_SHIFT 0 + +/* + * HSW+ eDP PSR registers + * + * HSW PSR registers are relative to DDIA(_DDI_BUF_CTL_A + 0x800) with just one + * instance of it + */ +#define _SRD_CTL_A 0x60800 +#define _SRD_CTL_EDP 0x6f800 +#define EDP_PSR_CTL(tran) _MMIO_TRANS2(tran, _SRD_CTL_A) +#define EDP_PSR_ENABLE (1 << 31) +#define BDW_PSR_SINGLE_FRAME (1 << 30) +#define EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK (1 << 29) /* SW can't modify */ +#define EDP_PSR_LINK_STANDBY (1 << 27) +#define EDP_PSR_MIN_LINK_ENTRY_TIME_MASK (3 << 25) +#define EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES (0 << 25) +#define EDP_PSR_MIN_LINK_ENTRY_TIME_4_LINES (1 << 25) +#define EDP_PSR_MIN_LINK_ENTRY_TIME_2_LINES (2 << 25) +#define EDP_PSR_MIN_LINK_ENTRY_TIME_0_LINES (3 << 25) +#define EDP_PSR_MAX_SLEEP_TIME_SHIFT 20 +#define EDP_PSR_SKIP_AUX_EXIT (1 << 12) +#define EDP_PSR_TP1_TP2_SEL (0 << 11) +#define EDP_PSR_TP1_TP3_SEL (1 << 11) +#define EDP_PSR_CRC_ENABLE (1 << 10) /* BDW+ */ +#define EDP_PSR_TP2_TP3_TIME_500us (0 << 8) +#define EDP_PSR_TP2_TP3_TIME_100us (1 << 8) +#define EDP_PSR_TP2_TP3_TIME_2500us (2 << 8) +#define EDP_PSR_TP2_TP3_TIME_0us (3 << 8) +#define EDP_PSR_TP4_TIME_0US (3 << 6) /* ICL+ */ +#define EDP_PSR_TP1_TIME_500us (0 << 4) +#define EDP_PSR_TP1_TIME_100us (1 << 4) +#define EDP_PSR_TP1_TIME_2500us (2 << 4) +#define EDP_PSR_TP1_TIME_0us (3 << 4) +#define EDP_PSR_IDLE_FRAME_SHIFT 0 + +/* + * Until TGL, IMR/IIR are fixed at 0x648xx. On TGL+ those registers are relative + * to transcoder and bits defined for each one as if using no shift (i.e. as if + * it was for TRANSCODER_EDP) + */ +#define EDP_PSR_IMR _MMIO(0x64834) +#define EDP_PSR_IIR _MMIO(0x64838) +#define _PSR_IMR_A 0x60814 +#define _PSR_IIR_A 0x60818 +#define TRANS_PSR_IMR(tran) _MMIO_TRANS2(tran, _PSR_IMR_A) +#define TRANS_PSR_IIR(tran) _MMIO_TRANS2(tran, _PSR_IIR_A) +#define _EDP_PSR_TRANS_SHIFT(trans) ((trans) == TRANSCODER_EDP ? \ + 0 : ((trans) - TRANSCODER_A + 1) * 8) +#define TGL_PSR_MASK REG_GENMASK(2, 0) +#define TGL_PSR_ERROR REG_BIT(2) +#define TGL_PSR_POST_EXIT REG_BIT(1) +#define TGL_PSR_PRE_ENTRY REG_BIT(0) +#define EDP_PSR_MASK(trans) (TGL_PSR_MASK << \ + _EDP_PSR_TRANS_SHIFT(trans)) +#define EDP_PSR_ERROR(trans) (TGL_PSR_ERROR << \ + _EDP_PSR_TRANS_SHIFT(trans)) +#define EDP_PSR_POST_EXIT(trans) (TGL_PSR_POST_EXIT << \ + _EDP_PSR_TRANS_SHIFT(trans)) +#define EDP_PSR_PRE_ENTRY(trans) (TGL_PSR_PRE_ENTRY << \ + _EDP_PSR_TRANS_SHIFT(trans)) + +#define _SRD_AUX_DATA_A 0x60814 +#define _SRD_AUX_DATA_EDP 0x6f814 +#define EDP_PSR_AUX_DATA(tran, i) _MMIO_TRANS2(tran, _SRD_AUX_DATA_A + (i) + 4) /* 5 registers */ + +#define _SRD_STATUS_A 0x60840 +#define _SRD_STATUS_EDP 0x6f840 +#define EDP_PSR_STATUS(tran) _MMIO_TRANS2(tran, _SRD_STATUS_A) +#define EDP_PSR_STATUS_STATE_MASK (7 << 29) +#define EDP_PSR_STATUS_STATE_SHIFT 29 +#define EDP_PSR_STATUS_STATE_IDLE (0 << 29) +#define EDP_PSR_STATUS_STATE_SRDONACK (1 << 29) +#define EDP_PSR_STATUS_STATE_SRDENT (2 << 29) +#define EDP_PSR_STATUS_STATE_BUFOFF (3 << 29) +#define EDP_PSR_STATUS_STATE_BUFON (4 << 29) +#define EDP_PSR_STATUS_STATE_AUXACK (5 << 29) +#define EDP_PSR_STATUS_STATE_SRDOFFACK (6 << 29) +#define EDP_PSR_STATUS_LINK_MASK (3 << 26) +#define EDP_PSR_STATUS_LINK_FULL_OFF (0 << 26) +#define EDP_PSR_STATUS_LINK_FULL_ON (1 << 26) +#define EDP_PSR_STATUS_LINK_STANDBY (2 << 26) +#define EDP_PSR_STATUS_MAX_SLEEP_TIMER_SHIFT 20 +#define EDP_PSR_STATUS_MAX_SLEEP_TIMER_MASK 0x1f +#define EDP_PSR_STATUS_COUNT_SHIFT 16 +#define EDP_PSR_STATUS_COUNT_MASK 0xf +#define EDP_PSR_STATUS_AUX_ERROR (1 << 15) +#define EDP_PSR_STATUS_AUX_SENDING (1 << 12) +#define EDP_PSR_STATUS_SENDING_IDLE (1 << 9) +#define EDP_PSR_STATUS_SENDING_TP2_TP3 (1 << 8) +#define EDP_PSR_STATUS_SENDING_TP1 (1 << 4) +#define EDP_PSR_STATUS_IDLE_MASK 0xf + +#define _SRD_PERF_CNT_A 0x60844 +#define _SRD_PERF_CNT_EDP 0x6f844 +#define EDP_PSR_PERF_CNT(tran) _MMIO_TRANS2(tran, _SRD_PERF_CNT_A) +#define EDP_PSR_PERF_CNT_MASK 0xffffff + +/* PSR_MASK on SKL+ */ +#define _SRD_DEBUG_A 0x60860 +#define _SRD_DEBUG_EDP 0x6f860 +#define EDP_PSR_DEBUG(tran) _MMIO_TRANS2(tran, _SRD_DEBUG_A) +#define EDP_PSR_DEBUG_MASK_MAX_SLEEP (1 << 28) +#define EDP_PSR_DEBUG_MASK_LPSP (1 << 27) +#define EDP_PSR_DEBUG_MASK_MEMUP (1 << 26) +#define EDP_PSR_DEBUG_MASK_HPD (1 << 25) +#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) /* up to adl-p */ +#define TGL_EDP_PSR2_BLOCK_COUNT_NUM_2 (0 << 28) +#define TGL_EDP_PSR2_BLOCK_COUNT_NUM_3 (1 << 28) +#define EDP_Y_COORDINATE_ENABLE REG_BIT(25) /* display 10, 11 and 12 */ +#define EDP_PSR2_SU_SDP_SCANLINE REG_BIT(25) /* display 13+ */ +#define EDP_MAX_SU_DISABLE_TIME(t) ((t) << 20) +#define EDP_MAX_SU_DISABLE_TIME_MASK (0x1f << 20) +#define EDP_PSR2_IO_BUFFER_WAKE_MAX_LINES 8 +#define EDP_PSR2_IO_BUFFER_WAKE(lines) ((EDP_PSR2_IO_BUFFER_WAKE_MAX_LINES - (lines)) << 13) +#define EDP_PSR2_IO_BUFFER_WAKE_MASK (3 << 13) +#define TGL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES 5 +#define TGL_EDP_PSR2_IO_BUFFER_WAKE_SHIFT 13 +#define TGL_EDP_PSR2_IO_BUFFER_WAKE(lines) (((lines) - TGL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES) << TGL_EDP_PSR2_IO_BUFFER_WAKE_SHIFT) +#define TGL_EDP_PSR2_IO_BUFFER_WAKE_MASK (7 << 13) +#define EDP_PSR2_FAST_WAKE_MAX_LINES 8 +#define EDP_PSR2_FAST_WAKE(lines) ((EDP_PSR2_FAST_WAKE_MAX_LINES - (lines)) << 11) +#define EDP_PSR2_FAST_WAKE_MASK (3 << 11) +#define TGL_EDP_PSR2_FAST_WAKE_MIN_LINES 5 +#define TGL_EDP_PSR2_FAST_WAKE_MIN_SHIFT 10 +#define TGL_EDP_PSR2_FAST_WAKE(lines) (((lines) - TGL_EDP_PSR2_FAST_WAKE_MIN_LINES) << TGL_EDP_PSR2_FAST_WAKE_MIN_SHIFT) +#define TGL_EDP_PSR2_FAST_WAKE_MASK (7 << 10) +#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 +#define _PSR_EVENT_TRANS_C 0x62848 +#define _PSR_EVENT_TRANS_D 0x63848 +#define _PSR_EVENT_TRANS_EDP 0x6f848 +#define PSR_EVENT(tran) _MMIO_TRANS2(tran, _PSR_EVENT_TRANS_A) +#define PSR_EVENT_PSR2_WD_TIMER_EXPIRE (1 << 17) +#define PSR_EVENT_PSR2_DISABLED (1 << 16) +#define PSR_EVENT_SU_DIRTY_FIFO_UNDERRUN (1 << 15) +#define PSR_EVENT_SU_CRC_FIFO_UNDERRUN (1 << 14) +#define PSR_EVENT_GRAPHICS_RESET (1 << 12) +#define PSR_EVENT_PCH_INTERRUPT (1 << 11) +#define PSR_EVENT_MEMORY_UP (1 << 10) +#define PSR_EVENT_FRONT_BUFFER_MODIFY (1 << 9) +#define PSR_EVENT_WD_TIMER_EXPIRE (1 << 8) +#define PSR_EVENT_PIPE_REGISTERS_UPDATE (1 << 6) +#define PSR_EVENT_REGISTER_UPDATE (1 << 5) /* Reserved in ICL+ */ +#define PSR_EVENT_HDCP_ENABLE (1 << 4) +#define PSR_EVENT_KVMR_SESSION_ENABLE (1 << 3) +#define PSR_EVENT_VBI_ENABLE (1 << 2) +#define PSR_EVENT_LPSP_MODE_EXIT (1 << 1) +#define PSR_EVENT_PSR_DISABLE (1 << 0) + +#define _PSR2_STATUS_A 0x60940 +#define _PSR2_STATUS_EDP 0x6f940 +#define EDP_PSR2_STATUS(tran) _MMIO_TRANS2(tran, _PSR2_STATUS_A) +#define EDP_PSR2_STATUS_STATE_MASK REG_GENMASK(31, 28) +#define EDP_PSR2_STATUS_STATE_DEEP_SLEEP REG_FIELD_PREP(EDP_PSR2_STATUS_STATE_MASK, 0x8) + +#define _PSR2_SU_STATUS_A 0x60914 +#define _PSR2_SU_STATUS_EDP 0x6f914 +#define _PSR2_SU_STATUS(tran, index) _MMIO_TRANS2(tran, _PSR2_SU_STATUS_A + (index) * 4) +#define PSR2_SU_STATUS(tran, frame) (_PSR2_SU_STATUS(tran, (frame) / 3)) +#define PSR2_SU_STATUS_SHIFT(frame) (((frame) % 3) * 10) +#define PSR2_SU_STATUS_MASK(frame) (0x3ff << PSR2_SU_STATUS_SHIFT(frame)) +#define PSR2_SU_STATUS_FRAMES 8 + +#define _PSR2_MAN_TRK_CTL_A 0x60910 +#define _PSR2_MAN_TRK_CTL_EDP 0x6f910 +#define PSR2_MAN_TRK_CTL(tran) _MMIO_TRANS2(tran, _PSR2_MAN_TRK_CTL_A) +#define PSR2_MAN_TRK_CTL_ENABLE REG_BIT(31) +#define PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR_MASK REG_GENMASK(30, 21) +#define PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(val) REG_FIELD_PREP(PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR_MASK, val) +#define PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR_MASK REG_GENMASK(20, 11) +#define PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR(val) REG_FIELD_PREP(PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR_MASK, val) +#define PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME REG_BIT(3) +#define PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME REG_BIT(2) +#define PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_UPDATE REG_BIT(1) +#define ADLP_PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR_MASK REG_GENMASK(28, 16) +#define ADLP_PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(val) REG_FIELD_PREP(ADLP_PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR_MASK, val) +#define ADLP_PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR_MASK REG_GENMASK(12, 0) +#define ADLP_PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR(val) REG_FIELD_PREP(ADLP_PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR_MASK, val) +#define ADLP_PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_UPDATE REG_BIT(31) +#define ADLP_PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME REG_BIT(14) +#define ADLP_PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME REG_BIT(13) + +#define _SEL_FETCH_PLANE_BASE_1_A 0x70890 +#define _SEL_FETCH_PLANE_BASE_2_A 0x708B0 +#define _SEL_FETCH_PLANE_BASE_3_A 0x708D0 +#define _SEL_FETCH_PLANE_BASE_4_A 0x708F0 +#define _SEL_FETCH_PLANE_BASE_5_A 0x70920 +#define _SEL_FETCH_PLANE_BASE_6_A 0x70940 +#define _SEL_FETCH_PLANE_BASE_7_A 0x70960 +#define _SEL_FETCH_PLANE_BASE_CUR_A 0x70880 +#define _SEL_FETCH_PLANE_BASE_1_B 0x71890 + +#define _SEL_FETCH_PLANE_BASE_A(plane) _PICK(plane, \ + _SEL_FETCH_PLANE_BASE_1_A, \ + _SEL_FETCH_PLANE_BASE_2_A, \ + _SEL_FETCH_PLANE_BASE_3_A, \ + _SEL_FETCH_PLANE_BASE_4_A, \ + _SEL_FETCH_PLANE_BASE_5_A, \ + _SEL_FETCH_PLANE_BASE_6_A, \ + _SEL_FETCH_PLANE_BASE_7_A, \ + _SEL_FETCH_PLANE_BASE_CUR_A) +#define _SEL_FETCH_PLANE_BASE_1(pipe) _PIPE(pipe, _SEL_FETCH_PLANE_BASE_1_A, _SEL_FETCH_PLANE_BASE_1_B) +#define _SEL_FETCH_PLANE_BASE(pipe, plane) (_SEL_FETCH_PLANE_BASE_1(pipe) - \ + _SEL_FETCH_PLANE_BASE_1_A + \ + _SEL_FETCH_PLANE_BASE_A(plane)) + +#define _SEL_FETCH_PLANE_CTL_1_A 0x70890 +#define PLANE_SEL_FETCH_CTL(pipe, plane) _MMIO(_SEL_FETCH_PLANE_BASE(pipe, plane) + \ + _SEL_FETCH_PLANE_CTL_1_A - \ + _SEL_FETCH_PLANE_BASE_1_A) +#define PLANE_SEL_FETCH_CTL_ENABLE REG_BIT(31) + +#define _SEL_FETCH_PLANE_POS_1_A 0x70894 +#define PLANE_SEL_FETCH_POS(pipe, plane) _MMIO(_SEL_FETCH_PLANE_BASE(pipe, plane) + \ + _SEL_FETCH_PLANE_POS_1_A - \ + _SEL_FETCH_PLANE_BASE_1_A) + +#define _SEL_FETCH_PLANE_SIZE_1_A 0x70898 +#define PLANE_SEL_FETCH_SIZE(pipe, plane) _MMIO(_SEL_FETCH_PLANE_BASE(pipe, plane) + \ + _SEL_FETCH_PLANE_SIZE_1_A - \ + _SEL_FETCH_PLANE_BASE_1_A) + +#define _SEL_FETCH_PLANE_OFFSET_1_A 0x7089C +#define PLANE_SEL_FETCH_OFFSET(pipe, plane) _MMIO(_SEL_FETCH_PLANE_BASE(pipe, plane) + \ + _SEL_FETCH_PLANE_OFFSET_1_A - \ + _SEL_FETCH_PLANE_BASE_1_A) + +#endif /* __INTEL_PSR_REGS_H__ */ diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 8bfccae7e026..4b45a041ac5c 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -48,6 +48,7 @@ #include "display/intel_fbc.h" #include "display/intel_fdi_regs.h" #include "display/intel_pps_regs.h" +#include "display/intel_psr_regs.h" #include "display/skl_watermark_regs.h" #include "display/vlv_dsi_pll_regs.h" #include "gt/intel_gt_regs.h" diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index c0888cc88d04..d24bdea65a3d 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -42,6 +42,7 @@ #include "display/intel_hotplug.h" #include "display/intel_lpe_audio.h" #include "display/intel_psr.h" +#include "display/intel_psr_regs.h" #include "gt/intel_breadcrumbs.h" #include "gt/intel_gt.h" diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 3519b1ac4160..0e6dfdfcda8a 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1971,11 +1971,6 @@ #define PIPESRC(pipe) _MMIO_TRANS2((pipe), _PIPEASRC) #define TRANS_MULT(trans) _MMIO_TRANS2((trans), _TRANS_MULT_A) -#define TRANS_EXITLINE(trans) _MMIO_TRANS2((trans), _TRANS_EXITLINE_A) -#define EXITLINE_ENABLE REG_BIT(31) -#define EXITLINE_MASK REG_GENMASK(12, 0) -#define EXITLINE_SHIFT 0 - /* VRR registers */ #define _TRANS_VRR_CTL_A 0x60420 #define _TRANS_VRR_CTL_B 0x61420 @@ -2069,205 +2064,6 @@ #define TRANS_PUSH_EN REG_BIT(31) #define TRANS_PUSH_SEND REG_BIT(30) -/* - * HSW+ eDP PSR registers - * - * HSW PSR registers are relative to DDIA(_DDI_BUF_CTL_A + 0x800) with just one - * instance of it - */ -#define _SRD_CTL_A 0x60800 -#define _SRD_CTL_EDP 0x6f800 -#define EDP_PSR_CTL(tran) _MMIO_TRANS2(tran, _SRD_CTL_A) -#define EDP_PSR_ENABLE (1 << 31) -#define BDW_PSR_SINGLE_FRAME (1 << 30) -#define EDP_PSR_RESTORE_PSR_ACTIVE_CTX_MASK (1 << 29) /* SW can't modify */ -#define EDP_PSR_LINK_STANDBY (1 << 27) -#define EDP_PSR_MIN_LINK_ENTRY_TIME_MASK (3 << 25) -#define EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES (0 << 25) -#define EDP_PSR_MIN_LINK_ENTRY_TIME_4_LINES (1 << 25) -#define EDP_PSR_MIN_LINK_ENTRY_TIME_2_LINES (2 << 25) -#define EDP_PSR_MIN_LINK_ENTRY_TIME_0_LINES (3 << 25) -#define EDP_PSR_MAX_SLEEP_TIME_SHIFT 20 -#define EDP_PSR_SKIP_AUX_EXIT (1 << 12) -#define EDP_PSR_TP1_TP2_SEL (0 << 11) -#define EDP_PSR_TP1_TP3_SEL (1 << 11) -#define EDP_PSR_CRC_ENABLE (1 << 10) /* BDW+ */ -#define EDP_PSR_TP2_TP3_TIME_500us (0 << 8) -#define EDP_PSR_TP2_TP3_TIME_100us (1 << 8) -#define EDP_PSR_TP2_TP3_TIME_2500us (2 << 8) -#define EDP_PSR_TP2_TP3_TIME_0us (3 << 8) -#define EDP_PSR_TP4_TIME_0US (3 << 6) /* ICL+ */ -#define EDP_PSR_TP1_TIME_500us (0 << 4) -#define EDP_PSR_TP1_TIME_100us (1 << 4) -#define EDP_PSR_TP1_TIME_2500us (2 << 4) -#define EDP_PSR_TP1_TIME_0us (3 << 4) -#define EDP_PSR_IDLE_FRAME_SHIFT 0 - -/* - * Until TGL, IMR/IIR are fixed at 0x648xx. On TGL+ those registers are relative - * to transcoder and bits defined for each one as if using no shift (i.e. as if - * it was for TRANSCODER_EDP) - */ -#define EDP_PSR_IMR _MMIO(0x64834) -#define EDP_PSR_IIR _MMIO(0x64838) -#define _PSR_IMR_A 0x60814 -#define _PSR_IIR_A 0x60818 -#define TRANS_PSR_IMR(tran) _MMIO_TRANS2(tran, _PSR_IMR_A) -#define TRANS_PSR_IIR(tran) _MMIO_TRANS2(tran, _PSR_IIR_A) -#define _EDP_PSR_TRANS_SHIFT(trans) ((trans) == TRANSCODER_EDP ? \ - 0 : ((trans) - TRANSCODER_A + 1) * 8) -#define TGL_PSR_MASK REG_GENMASK(2, 0) -#define TGL_PSR_ERROR REG_BIT(2) -#define TGL_PSR_POST_EXIT REG_BIT(1) -#define TGL_PSR_PRE_ENTRY REG_BIT(0) -#define EDP_PSR_MASK(trans) (TGL_PSR_MASK << \ - _EDP_PSR_TRANS_SHIFT(trans)) -#define EDP_PSR_ERROR(trans) (TGL_PSR_ERROR << \ - _EDP_PSR_TRANS_SHIFT(trans)) -#define EDP_PSR_POST_EXIT(trans) (TGL_PSR_POST_EXIT << \ - _EDP_PSR_TRANS_SHIFT(trans)) -#define EDP_PSR_PRE_ENTRY(trans) (TGL_PSR_PRE_ENTRY << \ - _EDP_PSR_TRANS_SHIFT(trans)) - -#define _SRD_AUX_DATA_A 0x60814 -#define _SRD_AUX_DATA_EDP 0x6f814 -#define EDP_PSR_AUX_DATA(tran, i) _MMIO_TRANS2(tran, _SRD_AUX_DATA_A + (i) + 4) /* 5 registers */ - -#define _SRD_STATUS_A 0x60840 -#define _SRD_STATUS_EDP 0x6f840 -#define EDP_PSR_STATUS(tran) _MMIO_TRANS2(tran, _SRD_STATUS_A) -#define EDP_PSR_STATUS_STATE_MASK (7 << 29) -#define EDP_PSR_STATUS_STATE_SHIFT 29 -#define EDP_PSR_STATUS_STATE_IDLE (0 << 29) -#define EDP_PSR_STATUS_STATE_SRDONACK (1 << 29) -#define EDP_PSR_STATUS_STATE_SRDENT (2 << 29) -#define EDP_PSR_STATUS_STATE_BUFOFF (3 << 29) -#define EDP_PSR_STATUS_STATE_BUFON (4 << 29) -#define EDP_PSR_STATUS_STATE_AUXACK (5 << 29) -#define EDP_PSR_STATUS_STATE_SRDOFFACK (6 << 29) -#define EDP_PSR_STATUS_LINK_MASK (3 << 26) -#define EDP_PSR_STATUS_LINK_FULL_OFF (0 << 26) -#define EDP_PSR_STATUS_LINK_FULL_ON (1 << 26) -#define EDP_PSR_STATUS_LINK_STANDBY (2 << 26) -#define EDP_PSR_STATUS_MAX_SLEEP_TIMER_SHIFT 20 -#define EDP_PSR_STATUS_MAX_SLEEP_TIMER_MASK 0x1f -#define EDP_PSR_STATUS_COUNT_SHIFT 16 -#define EDP_PSR_STATUS_COUNT_MASK 0xf -#define EDP_PSR_STATUS_AUX_ERROR (1 << 15) -#define EDP_PSR_STATUS_AUX_SENDING (1 << 12) -#define EDP_PSR_STATUS_SENDING_IDLE (1 << 9) -#define EDP_PSR_STATUS_SENDING_TP2_TP3 (1 << 8) -#define EDP_PSR_STATUS_SENDING_TP1 (1 << 4) -#define EDP_PSR_STATUS_IDLE_MASK 0xf - -#define _SRD_PERF_CNT_A 0x60844 -#define _SRD_PERF_CNT_EDP 0x6f844 -#define EDP_PSR_PERF_CNT(tran) _MMIO_TRANS2(tran, _SRD_PERF_CNT_A) -#define EDP_PSR_PERF_CNT_MASK 0xffffff - -/* PSR_MASK on SKL+ */ -#define _SRD_DEBUG_A 0x60860 -#define _SRD_DEBUG_EDP 0x6f860 -#define EDP_PSR_DEBUG(tran) _MMIO_TRANS2(tran, _SRD_DEBUG_A) -#define EDP_PSR_DEBUG_MASK_MAX_SLEEP (1 << 28) -#define EDP_PSR_DEBUG_MASK_LPSP (1 << 27) -#define EDP_PSR_DEBUG_MASK_MEMUP (1 << 26) -#define EDP_PSR_DEBUG_MASK_HPD (1 << 25) -#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) /* up to adl-p */ -#define TGL_EDP_PSR2_BLOCK_COUNT_NUM_2 (0 << 28) -#define TGL_EDP_PSR2_BLOCK_COUNT_NUM_3 (1 << 28) -#define EDP_Y_COORDINATE_ENABLE REG_BIT(25) /* display 10, 11 and 12 */ -#define EDP_PSR2_SU_SDP_SCANLINE REG_BIT(25) /* display 13+ */ -#define EDP_MAX_SU_DISABLE_TIME(t) ((t) << 20) -#define EDP_MAX_SU_DISABLE_TIME_MASK (0x1f << 20) -#define EDP_PSR2_IO_BUFFER_WAKE_MAX_LINES 8 -#define EDP_PSR2_IO_BUFFER_WAKE(lines) ((EDP_PSR2_IO_BUFFER_WAKE_MAX_LINES - (lines)) << 13) -#define EDP_PSR2_IO_BUFFER_WAKE_MASK (3 << 13) -#define TGL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES 5 -#define TGL_EDP_PSR2_IO_BUFFER_WAKE_SHIFT 13 -#define TGL_EDP_PSR2_IO_BUFFER_WAKE(lines) (((lines) - TGL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES) << TGL_EDP_PSR2_IO_BUFFER_WAKE_SHIFT) -#define TGL_EDP_PSR2_IO_BUFFER_WAKE_MASK (7 << 13) -#define EDP_PSR2_FAST_WAKE_MAX_LINES 8 -#define EDP_PSR2_FAST_WAKE(lines) ((EDP_PSR2_FAST_WAKE_MAX_LINES - (lines)) << 11) -#define EDP_PSR2_FAST_WAKE_MASK (3 << 11) -#define TGL_EDP_PSR2_FAST_WAKE_MIN_LINES 5 -#define TGL_EDP_PSR2_FAST_WAKE_MIN_SHIFT 10 -#define TGL_EDP_PSR2_FAST_WAKE(lines) (((lines) - TGL_EDP_PSR2_FAST_WAKE_MIN_LINES) << TGL_EDP_PSR2_FAST_WAKE_MIN_SHIFT) -#define TGL_EDP_PSR2_FAST_WAKE_MASK (7 << 10) -#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 -#define _PSR_EVENT_TRANS_C 0x62848 -#define _PSR_EVENT_TRANS_D 0x63848 -#define _PSR_EVENT_TRANS_EDP 0x6f848 -#define PSR_EVENT(tran) _MMIO_TRANS2(tran, _PSR_EVENT_TRANS_A) -#define PSR_EVENT_PSR2_WD_TIMER_EXPIRE (1 << 17) -#define PSR_EVENT_PSR2_DISABLED (1 << 16) -#define PSR_EVENT_SU_DIRTY_FIFO_UNDERRUN (1 << 15) -#define PSR_EVENT_SU_CRC_FIFO_UNDERRUN (1 << 14) -#define PSR_EVENT_GRAPHICS_RESET (1 << 12) -#define PSR_EVENT_PCH_INTERRUPT (1 << 11) -#define PSR_EVENT_MEMORY_UP (1 << 10) -#define PSR_EVENT_FRONT_BUFFER_MODIFY (1 << 9) -#define PSR_EVENT_WD_TIMER_EXPIRE (1 << 8) -#define PSR_EVENT_PIPE_REGISTERS_UPDATE (1 << 6) -#define PSR_EVENT_REGISTER_UPDATE (1 << 5) /* Reserved in ICL+ */ -#define PSR_EVENT_HDCP_ENABLE (1 << 4) -#define PSR_EVENT_KVMR_SESSION_ENABLE (1 << 3) -#define PSR_EVENT_VBI_ENABLE (1 << 2) -#define PSR_EVENT_LPSP_MODE_EXIT (1 << 1) -#define PSR_EVENT_PSR_DISABLE (1 << 0) - -#define _PSR2_STATUS_A 0x60940 -#define _PSR2_STATUS_EDP 0x6f940 -#define EDP_PSR2_STATUS(tran) _MMIO_TRANS2(tran, _PSR2_STATUS_A) -#define EDP_PSR2_STATUS_STATE_MASK REG_GENMASK(31, 28) -#define EDP_PSR2_STATUS_STATE_DEEP_SLEEP REG_FIELD_PREP(EDP_PSR2_STATUS_STATE_MASK, 0x8) - -#define _PSR2_SU_STATUS_A 0x60914 -#define _PSR2_SU_STATUS_EDP 0x6f914 -#define _PSR2_SU_STATUS(tran, index) _MMIO_TRANS2(tran, _PSR2_SU_STATUS_A + (index) * 4) -#define PSR2_SU_STATUS(tran, frame) (_PSR2_SU_STATUS(tran, (frame) / 3)) -#define PSR2_SU_STATUS_SHIFT(frame) (((frame) % 3) * 10) -#define PSR2_SU_STATUS_MASK(frame) (0x3ff << PSR2_SU_STATUS_SHIFT(frame)) -#define PSR2_SU_STATUS_FRAMES 8 - -#define _PSR2_MAN_TRK_CTL_A 0x60910 -#define _PSR2_MAN_TRK_CTL_EDP 0x6f910 -#define PSR2_MAN_TRK_CTL(tran) _MMIO_TRANS2(tran, _PSR2_MAN_TRK_CTL_A) -#define PSR2_MAN_TRK_CTL_ENABLE REG_BIT(31) -#define PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR_MASK REG_GENMASK(30, 21) -#define PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(val) REG_FIELD_PREP(PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR_MASK, val) -#define PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR_MASK REG_GENMASK(20, 11) -#define PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR(val) REG_FIELD_PREP(PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR_MASK, val) -#define PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME REG_BIT(3) -#define PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME REG_BIT(2) -#define PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_UPDATE REG_BIT(1) -#define ADLP_PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR_MASK REG_GENMASK(28, 16) -#define ADLP_PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR(val) REG_FIELD_PREP(ADLP_PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR_MASK, val) -#define ADLP_PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR_MASK REG_GENMASK(12, 0) -#define ADLP_PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR(val) REG_FIELD_PREP(ADLP_PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR_MASK, val) -#define ADLP_PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_UPDATE REG_BIT(31) -#define ADLP_PSR2_MAN_TRK_CTL_SF_SINGLE_FULL_FRAME REG_BIT(14) -#define ADLP_PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME REG_BIT(13) - /* VGA port control */ #define ADPA _MMIO(0x61100) #define PCH_ADPA _MMIO(0xe1100) @@ -4132,51 +3928,6 @@ #define PLANE_COLOR_CTL(pipe, plane) \ _MMIO_PLANE(plane, _PLANE_COLOR_CTL_1(pipe), _PLANE_COLOR_CTL_2(pipe)) -#define _SEL_FETCH_PLANE_BASE_1_A 0x70890 -#define _SEL_FETCH_PLANE_BASE_2_A 0x708B0 -#define _SEL_FETCH_PLANE_BASE_3_A 0x708D0 -#define _SEL_FETCH_PLANE_BASE_4_A 0x708F0 -#define _SEL_FETCH_PLANE_BASE_5_A 0x70920 -#define _SEL_FETCH_PLANE_BASE_6_A 0x70940 -#define _SEL_FETCH_PLANE_BASE_7_A 0x70960 -#define _SEL_FETCH_PLANE_BASE_CUR_A 0x70880 -#define _SEL_FETCH_PLANE_BASE_1_B 0x71890 - -#define _SEL_FETCH_PLANE_BASE_A(plane) _PICK(plane, \ - _SEL_FETCH_PLANE_BASE_1_A, \ - _SEL_FETCH_PLANE_BASE_2_A, \ - _SEL_FETCH_PLANE_BASE_3_A, \ - _SEL_FETCH_PLANE_BASE_4_A, \ - _SEL_FETCH_PLANE_BASE_5_A, \ - _SEL_FETCH_PLANE_BASE_6_A, \ - _SEL_FETCH_PLANE_BASE_7_A, \ - _SEL_FETCH_PLANE_BASE_CUR_A) -#define _SEL_FETCH_PLANE_BASE_1(pipe) _PIPE(pipe, _SEL_FETCH_PLANE_BASE_1_A, _SEL_FETCH_PLANE_BASE_1_B) -#define _SEL_FETCH_PLANE_BASE(pipe, plane) (_SEL_FETCH_PLANE_BASE_1(pipe) - \ - _SEL_FETCH_PLANE_BASE_1_A + \ - _SEL_FETCH_PLANE_BASE_A(plane)) - -#define _SEL_FETCH_PLANE_CTL_1_A 0x70890 -#define PLANE_SEL_FETCH_CTL(pipe, plane) _MMIO(_SEL_FETCH_PLANE_BASE(pipe, plane) + \ - _SEL_FETCH_PLANE_CTL_1_A - \ - _SEL_FETCH_PLANE_BASE_1_A) -#define PLANE_SEL_FETCH_CTL_ENABLE REG_BIT(31) - -#define _SEL_FETCH_PLANE_POS_1_A 0x70894 -#define PLANE_SEL_FETCH_POS(pipe, plane) _MMIO(_SEL_FETCH_PLANE_BASE(pipe, plane) + \ - _SEL_FETCH_PLANE_POS_1_A - \ - _SEL_FETCH_PLANE_BASE_1_A) - -#define _SEL_FETCH_PLANE_SIZE_1_A 0x70898 -#define PLANE_SEL_FETCH_SIZE(pipe, plane) _MMIO(_SEL_FETCH_PLANE_BASE(pipe, plane) + \ - _SEL_FETCH_PLANE_SIZE_1_A - \ - _SEL_FETCH_PLANE_BASE_1_A) - -#define _SEL_FETCH_PLANE_OFFSET_1_A 0x7089C -#define PLANE_SEL_FETCH_OFFSET(pipe, plane) _MMIO(_SEL_FETCH_PLANE_BASE(pipe, plane) + \ - _SEL_FETCH_PLANE_OFFSET_1_A - \ - _SEL_FETCH_PLANE_BASE_1_A) - /* VBIOS regs */ #define VGACNTRL _MMIO(0x71400) # define VGA_DISP_DISABLE (1 << 31) diff --git a/drivers/gpu/drm/i915/intel_gvt_mmio_table.c b/drivers/gpu/drm/i915/intel_gvt_mmio_table.c index 3b49d2e6a66f..5d08774029cc 100644 --- a/drivers/gpu/drm/i915/intel_gvt_mmio_table.c +++ b/drivers/gpu/drm/i915/intel_gvt_mmio_table.c @@ -11,6 +11,7 @@ #include "display/intel_dpio_phy.h" #include "display/intel_fdi_regs.h" #include "display/intel_lvds_regs.h" +#include "display/intel_psr_regs.h" #include "display/skl_watermark_regs.h" #include "display/vlv_dsi_pll_regs.h" #include "gt/intel_gt_regs.h" -- cgit v1.2.3-59-g8ed1b From aaee4bbe8a1aa6833d6c42c7015ae63c489fdeeb Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 3 Apr 2023 15:57:10 +0300 Subject: drm/i915: enable kernel-doc warnings for CONFIG_DRM_I915_WERROR=y Increase awareness of kernel-doc issues by enabling doc check locally when CONFIG_DRM_I915_WERROR=y is enabled. Once the warnings have been fixed, we can pass -Werror to kernel-doc locally, and fail the build when there are kernel-doc warnings in i915. v2: Don't check for KBUILD_EXTRA_WARN (Masahiro) Cc: Masahiro Yamada Signed-off-by: Jani Nikula Acked-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20230403125710.3617230-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 057ef22fa9c6..831e42175165 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -369,6 +369,13 @@ include $(src)/gvt/Makefile obj-$(CONFIG_DRM_I915) += i915.o obj-$(CONFIG_DRM_I915_GVT_KVMGT) += kvmgt.o +# kernel-doc test +# +# Enable locally for CONFIG_DRM_I915_WERROR=y. See also scripts/Makefile.build +ifdef CONFIG_DRM_I915_WERROR + cmd_checkdoc = $(srctree)/scripts/kernel-doc -none $< +endif + # header test # exclude some broken headers from the test coverage -- cgit v1.2.3-59-g8ed1b From 764b1c8df40daf618b293b367f9be1f4fcd1b6fb Mon Sep 17 00:00:00 2001 From: Stanislav Lisovskiy Date: Fri, 24 Mar 2023 15:51:25 +0200 Subject: drm/i915: Implement UHBR bandwidth check According to spec, we should check if output_bpp * pixel_rate is less than DDI clock * 72, if UHBR is used. v2: - s/pipe_config/crtc_state/ (Jani Nikula) - Merged previous patch into that one, to remove empty function(Jani Nikula) v3: - Make that constraint check to be DSC-related only - Limit this to only DISPLAY_VER <= 13 v4: - Move constraint check to the top(Vinod Govindapillai) HSDES: 1406899791 BSPEC: 49259 Signed-off-by: Stanislav Lisovskiy Reviewed-by: Vinod Govindapillai Link: https://patchwork.freedesktop.org/patch/msgid/20230324135125.6720-1-stanislav.lisovskiy@intel.com --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 33 +++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index fe01fdf36cfd..a88b852c437c 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -45,6 +45,27 @@ #include "intel_hotplug.h" #include "skl_scaler.h" +static int intel_dp_mst_check_constraints(struct drm_i915_private *i915, int bpp, + const struct drm_display_mode *adjusted_mode, + struct intel_crtc_state *crtc_state, + bool dsc) +{ + if (intel_dp_is_uhbr(crtc_state) && DISPLAY_VER(i915) <= 13 && dsc) { + int output_bpp = bpp; + /* DisplayPort 2 128b/132b, bits per lane is always 32 */ + int symbol_clock = crtc_state->port_clock / 32; + + if (output_bpp * adjusted_mode->crtc_clock >= + symbol_clock * 72) { + drm_dbg_kms(&i915->drm, "UHBR check failed(required bw %d available %d)\n", + output_bpp * adjusted_mode->crtc_clock, symbol_clock * 72); + return -EINVAL; + } + } + + return 0; +} + static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, struct intel_crtc_state *crtc_state, int max_bpp, @@ -81,12 +102,16 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, } for (bpp = max_bpp; bpp >= min_bpp; bpp -= step) { + drm_dbg_kms(&i915->drm, "Trying bpp %d\n", bpp); + + ret = intel_dp_mst_check_constraints(i915, bpp, adjusted_mode, crtc_state, dsc); + if (ret) + continue; + crtc_state->pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock, dsc ? bpp << 4 : bpp, dsc); - drm_dbg_kms(&i915->drm, "Trying bpp %d\n", bpp); - slots = drm_dp_atomic_find_time_slots(state, &intel_dp->mst_mgr, connector->port, crtc_state->pbn); @@ -104,8 +129,8 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, } } - /* Despite slots are non-zero, we still failed the atomic check */ - if (ret && slots >= 0) + /* We failed to find a proper bpp/timeslots, return error */ + if (ret) slots = ret; if (slots < 0) { -- cgit v1.2.3-59-g8ed1b From 899ff790d1a94dda9bd09a4a6bde01fb7ff0bec8 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Tue, 4 Apr 2023 12:05:28 +0300 Subject: drm/i915: run kernel-doc on headers as part of HDRTEST Enabling kernel-doc warnings in commit aaee4bbe8a1a ("drm/i915: enable kernel-doc warnings for CONFIG_DRM_I915_WERROR=y") actually only covers the .c files. And it's good for avoiding warnings in W= builds. However, we need something more to check for kernel-doc issues in headers. Add it as part of the existing HDRTEST. We have tons of issues, and this unleashes warnings galore on CONFIG_DRM_I915_WERROR=y. It doesn't fail the build because (at least for now) we don't pass -Werror to kernel-doc. Cc: Rodrigo Vivi Signed-off-by: Jani Nikula Reviewed-by: Rodrigo Vivi Acked-by: Nirmoy Das Link: https://patchwork.freedesktop.org/patch/msgid/20230404090528.173075-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 831e42175165..b739300267c2 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -387,7 +387,8 @@ always-$(CONFIG_DRM_I915_WERROR) += \ $(shell cd $(srctree)/$(src) && find * -name '*.h'))) quiet_cmd_hdrtest = HDRTEST $(patsubst %.hdrtest,%.h,$@) - cmd_hdrtest = $(CC) $(filter-out $(CFLAGS_GCOV), $(c_flags)) -S -o /dev/null -x c /dev/null -include $<; touch $@ + cmd_hdrtest = $(CC) $(filter-out $(CFLAGS_GCOV), $(c_flags)) -S -o /dev/null -x c /dev/null -include $<; \ + $(srctree)/scripts/kernel-doc -none $<; touch $@ $(obj)/%.hdrtest: $(src)/%.h FORCE $(call if_changed_dep,hdrtest) -- cgit v1.2.3-59-g8ed1b From 69e6dd149212cdd681201352a79e6634665004e8 Mon Sep 17 00:00:00 2001 From: Alan Previn Date: Thu, 23 Mar 2023 11:41:56 -0700 Subject: drm/i915/pxp: limit drm-errors or warning on firmware API failures MESA driver is creating protected context on every driver handle creation to query caps bits for app. So when running CI tests, they are observing hundreds of drm_errors when enabling PXP in .config but using SOC fusing or BIOS configuration that cannot support PXP sessions. The fixes tag referenced below was to resolve a related issue where we wanted to silence error messages, but that case was due to outdated IFWI (firmware) that definitely needed an upgrade and was, at that point, considered a one-off case as opposed to today's realization that default CI was enabling PXP in kernel config for all testing. So with this patch, let's strike a balance between issues that is critical but are root-caused from HW/platform gaps (louder drm-warn but just ONCE) vs other cases where it could also come from session state machine (which cannot be a WARN_ONCE since it can be triggered due to runtime operation events). Let's use helpers for these so as more functions are added in future features / HW (or as FW designers continue to bless upstreaming of the error codes and meanings), we only need to update the helpers. NOTE: Don't completely remove FW errors (via drm_debug) or else cusomer apps that really needs to know that content protection failed won't be aware of it. v2: - Add fixes tag (Trvtko) v3: - Break multi-line drm_dbg strings into separate drm_dbg (Daniele) - Fix couple of typecasting nits (Daniele) v4: - Unsuccessful PXP FW cmd due to platform configuration shouldn't use drm_WARN_once (Tvrtko), Switched to use drm_info_once. v5: - Added "reported-and-tested" by Eero. Reported-and-tested-by: Eero Tamminen Fixes: b762787bf767 ("drm/i915/pxp: Use drm_dbg if arb session failed due to fw version") Signed-off-by: Alan Previn Reviewed-by: Daniele Ceraolo Spurio Signed-off-by: Daniele Ceraolo Spurio Link: https://patchwork.freedesktop.org/patch/msgid/20230323184156.4140659-1-alan.previn.teres.alexis@intel.com --- .../gpu/drm/i915/pxp/intel_pxp_cmd_interface_cmn.h | 3 + drivers/gpu/drm/i915/pxp/intel_pxp_session.c | 2 +- drivers/gpu/drm/i915/pxp/intel_pxp_tee.c | 77 ++++++++++++++++++---- 3 files changed, 67 insertions(+), 15 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_cmn.h b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_cmn.h index ae9b151b7cb7..6f6541d5e49a 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_cmn.h +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_cmn.h @@ -18,6 +18,9 @@ enum pxp_status { PXP_STATUS_SUCCESS = 0x0, PXP_STATUS_ERROR_API_VERSION = 0x1002, + PXP_STATUS_NOT_READY = 0x100e, + PXP_STATUS_PLATFCONFIG_KF1_NOVERIF = 0x101a, + PXP_STATUS_PLATFCONFIG_KF1_BAD = 0x101f, PXP_STATUS_OP_NOT_PERMITTED = 0x4013 }; diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c index 448cacb0465d..7de849cb6c47 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c @@ -74,7 +74,7 @@ static int pxp_create_arb_session(struct intel_pxp *pxp) ret = pxp_wait_for_session_state(pxp, ARB_SESSION, true); if (ret) { - drm_err(>->i915->drm, "arb session failed to go in play\n"); + drm_dbg(>->i915->drm, "arb session failed to go in play\n"); return ret; } drm_dbg(>->i915->drm, "PXP ARB session is alive\n"); diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c index d9d248b48093..a2846b1dbbee 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c @@ -19,6 +19,37 @@ #include "intel_pxp_tee.h" #include "intel_pxp_types.h" +static bool +is_fw_err_platform_config(u32 type) +{ + switch (type) { + case PXP_STATUS_ERROR_API_VERSION: + case PXP_STATUS_PLATFCONFIG_KF1_NOVERIF: + case PXP_STATUS_PLATFCONFIG_KF1_BAD: + return true; + default: + break; + } + return false; +} + +static const char * +fw_err_to_string(u32 type) +{ + switch (type) { + case PXP_STATUS_ERROR_API_VERSION: + return "ERR_API_VERSION"; + case PXP_STATUS_NOT_READY: + return "ERR_NOT_READY"; + case PXP_STATUS_PLATFCONFIG_KF1_NOVERIF: + case PXP_STATUS_PLATFCONFIG_KF1_BAD: + return "ERR_PLATFORM_CONFIG"; + default: + break; + } + return NULL; +} + static int intel_pxp_tee_io_message(struct intel_pxp *pxp, void *msg_in, u32 msg_in_size, void *msg_out, u32 msg_out_max_size, @@ -307,15 +338,22 @@ int intel_pxp_tee_cmd_create_arb_session(struct intel_pxp *pxp, &msg_out, sizeof(msg_out), NULL); - if (ret) - drm_err(&i915->drm, "Failed to send tee msg ret=[%d]\n", ret); - else if (msg_out.header.status == PXP_STATUS_ERROR_API_VERSION) - drm_dbg(&i915->drm, "PXP firmware version unsupported, requested: " - "CMD-ID-[0x%08x] on API-Ver-[0x%08x]\n", - msg_in.header.command_id, msg_in.header.api_version); - else if (msg_out.header.status != 0x0) - drm_warn(&i915->drm, "PXP firmware failed arb session init request ret=[0x%08x]\n", - msg_out.header.status); + if (ret) { + drm_err(&i915->drm, "Failed to send tee msg init arb session, ret=[%d]\n", ret); + } else if (msg_out.header.status != 0) { + if (is_fw_err_platform_config(msg_out.header.status)) { + drm_info_once(&i915->drm, + "PXP init-arb-session-%d failed due to BIOS/SOC:0x%08x:%s\n", + arb_session_id, msg_out.header.status, + fw_err_to_string(msg_out.header.status)); + } else { + drm_dbg(&i915->drm, "PXP init-arb-session--%d failed 0x%08x:%st:\n", + arb_session_id, msg_out.header.status, + fw_err_to_string(msg_out.header.status)); + drm_dbg(&i915->drm, " cmd-detail: ID=[0x%08x],API-Ver-[0x%08x]\n", + msg_in.header.command_id, msg_in.header.api_version); + } + } return ret; } @@ -347,10 +385,21 @@ try_again: if ((ret || msg_out.header.status != 0x0) && ++trials < 3) goto try_again; - if (ret) - drm_err(&i915->drm, "Failed to send tee msg for inv-stream-key-%d, ret=[%d]\n", + if (ret) { + drm_err(&i915->drm, "Failed to send tee msg for inv-stream-key-%u, ret=[%d]\n", session_id, ret); - else if (msg_out.header.status != 0x0) - drm_warn(&i915->drm, "PXP firmware failed inv-stream-key-%d with status 0x%08x\n", - session_id, msg_out.header.status); + } else if (msg_out.header.status != 0) { + if (is_fw_err_platform_config(msg_out.header.status)) { + drm_info_once(&i915->drm, + "PXP inv-stream-key-%u failed due to BIOS/SOC :0x%08x:%s\n", + session_id, msg_out.header.status, + fw_err_to_string(msg_out.header.status)); + } else { + drm_dbg(&i915->drm, "PXP inv-stream-key-%u failed 0x%08x:%s:\n", + session_id, msg_out.header.status, + fw_err_to_string(msg_out.header.status)); + drm_dbg(&i915->drm, " cmd-detail: ID=[0x%08x],API-Ver-[0x%08x]\n", + msg_in.header.command_id, msg_in.header.api_version); + } + } } -- cgit v1.2.3-59-g8ed1b From d670c78ea7564f9baf915c8e1dc5898a9e6c360b Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 3 Apr 2023 15:24:27 +0300 Subject: drm/i915: rename intel_pm.[ch] to intel_clock_gating.[ch] Observe that intel_pm.[ch] is now purely about clock gating, so rename them to intel_clock_gating.[ch]. Rename the functions to intel_clock_gating_*() to follow coding conventions. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20230403122428.3526263-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/Makefile | 2 +- drivers/gpu/drm/i915/display/intel_display.c | 4 +- drivers/gpu/drm/i915/i915_driver.c | 8 +- drivers/gpu/drm/i915/i915_gem.c | 8 +- drivers/gpu/drm/i915/intel_clock_gating.c | 885 +++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_clock_gating.h | 14 + drivers/gpu/drm/i915/intel_pm.c | 885 --------------------------- drivers/gpu/drm/i915/intel_pm.h | 18 - drivers/gpu/drm/i915/vlv_suspend.c | 4 +- 9 files changed, 912 insertions(+), 916 deletions(-) create mode 100644 drivers/gpu/drm/i915/intel_clock_gating.c create mode 100644 drivers/gpu/drm/i915/intel_clock_gating.h delete mode 100644 drivers/gpu/drm/i915/intel_pm.c delete mode 100644 drivers/gpu/drm/i915/intel_pm.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index b739300267c2..97b0d4ae221a 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -47,10 +47,10 @@ i915-y += i915_driver.o \ i915_switcheroo.o \ i915_sysfs.o \ i915_utils.o \ + intel_clock_gating.o \ intel_device_info.o \ intel_memory_region.o \ intel_pcode.o \ - intel_pm.o \ intel_region_ttm.o \ intel_runtime_pm.o \ intel_sbi.o \ diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 810156099b02..010ee793e1ff 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -63,6 +63,7 @@ #include "intel_audio.h" #include "intel_bw.h" #include "intel_cdclk.h" +#include "intel_clock_gating.h" #include "intel_color.h" #include "intel_crt.h" #include "intel_crtc.h" @@ -105,7 +106,6 @@ #include "intel_pcode.h" #include "intel_pipe_crc.h" #include "intel_plane_initial.h" -#include "intel_pm.h" #include "intel_pps.h" #include "intel_psr.h" #include "intel_quirks.h" @@ -850,7 +850,7 @@ void intel_display_finish_reset(struct drm_i915_private *i915) */ intel_pps_unlock_regs_wa(i915); intel_modeset_init_hw(i915); - intel_init_clock_gating(i915); + intel_clock_gating_init(i915); intel_hpd_init(i915); ret = __intel_display_resume(i915, state, ctx); diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index da249337c23b..fb5fbda70ad9 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -79,11 +79,11 @@ #include "soc/intel_dram.h" #include "soc/intel_gmch.h" -#include "i915_file_private.h" #include "i915_debugfs.h" #include "i915_driver.h" #include "i915_drm_client.h" #include "i915_drv.h" +#include "i915_file_private.h" #include "i915_getparam.h" #include "i915_hwmon.h" #include "i915_ioc32.h" @@ -97,11 +97,11 @@ #include "i915_sysfs.h" #include "i915_utils.h" #include "i915_vgpu.h" +#include "intel_clock_gating.h" #include "intel_gvt.h" #include "intel_memory_region.h" #include "intel_pci_config.h" #include "intel_pcode.h" -#include "intel_pm.h" #include "intel_region_ttm.h" #include "vlv_suspend.h" @@ -252,7 +252,7 @@ static int i915_driver_early_probe(struct drm_i915_private *dev_priv) intel_irq_init(dev_priv); intel_init_display_hooks(dev_priv); - intel_init_clock_gating_hooks(dev_priv); + intel_clock_gating_hooks_init(dev_priv); intel_detect_preproduction_hw(dev_priv); @@ -1242,7 +1242,7 @@ static int i915_drm_resume(struct drm_device *dev) i915_gem_resume(dev_priv); intel_modeset_init_hw(dev_priv); - intel_init_clock_gating(dev_priv); + intel_clock_gating_init(dev_priv); intel_hpd_init(dev_priv); /* MST sideband requires HPD interrupts enabled */ diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 35950fa91406..6b6b0e575ef3 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -58,7 +58,7 @@ #include "i915_file_private.h" #include "i915_trace.h" #include "i915_vgpu.h" -#include "intel_pm.h" +#include "intel_clock_gating.h" static int insert_mappable_node(struct i915_ggtt *ggtt, struct drm_mm_node *node, u32 size) @@ -1164,7 +1164,7 @@ int i915_gem_init(struct drm_i915_private *dev_priv) } /* - * Despite its name intel_init_clock_gating applies both display + * Despite its name intel_clock_gating_init applies both display * clock gating workarounds; GT mmio workarounds and the occasional * GT power context workaround. Worse, sometimes it includes a context * register workaround which we need to apply before we record the @@ -1172,7 +1172,7 @@ int i915_gem_init(struct drm_i915_private *dev_priv) * * FIXME: break up the workarounds and apply them at the right time! */ - intel_init_clock_gating(dev_priv); + intel_clock_gating_init(dev_priv); for_each_gt(gt, dev_priv, i) { ret = intel_gt_init(gt); @@ -1216,7 +1216,7 @@ err_unlock: /* Minimal basic recovery for KMS */ ret = i915_ggtt_enable_hw(dev_priv); i915_ggtt_resume(to_gt(dev_priv)->ggtt); - intel_init_clock_gating(dev_priv); + intel_clock_gating_init(dev_priv); } i915_gem_drain_freed_objects(dev_priv); diff --git a/drivers/gpu/drm/i915/intel_clock_gating.c b/drivers/gpu/drm/i915/intel_clock_gating.c new file mode 100644 index 000000000000..8cfc19b48760 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_clock_gating.c @@ -0,0 +1,885 @@ +/* + * Copyright © 2012 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eugeni Dodonov + * + */ + +#include "display/intel_de.h" +#include "display/intel_display.h" +#include "display/intel_display_trace.h" +#include "display/skl_watermark.h" + +#include "gt/intel_engine_regs.h" +#include "gt/intel_gt.h" +#include "gt/intel_gt_mcr.h" +#include "gt/intel_gt_regs.h" + +#include "i915_drv.h" +#include "intel_clock_gating.h" +#include "intel_mchbar_regs.h" +#include "vlv_sideband.h" + +struct drm_i915_clock_gating_funcs { + void (*init_clock_gating)(struct drm_i915_private *i915); +}; + +static void gen9_init_clock_gating(struct drm_i915_private *dev_priv) +{ + if (HAS_LLC(dev_priv)) { + /* + * WaCompressedResourceDisplayNewHashMode:skl,kbl + * Display WA #0390: skl,kbl + * + * Must match Sampler, Pixel Back End, and Media. See + * WaCompressedResourceSamplerPbeMediaNewHashMode. + */ + intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PAR1_1, 0, SKL_DE_COMPRESSED_HASH_MODE); + } + + /* See Bspec note for PSR2_CTL bit 31, Wa#828:skl,bxt,kbl,cfl */ + intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PAR1_1, 0, SKL_EDP_PSR_FIX_RDWRAP); + + /* WaEnableChickenDCPR:skl,bxt,kbl,glk,cfl */ + intel_uncore_rmw(&dev_priv->uncore, GEN8_CHICKEN_DCPR_1, 0, MASK_WAKEMEM); + + /* + * WaFbcWakeMemOn:skl,bxt,kbl,glk,cfl + * Display WA #0859: skl,bxt,kbl,glk,cfl + */ + intel_uncore_rmw(&dev_priv->uncore, DISP_ARB_CTL, 0, DISP_FBC_MEMORY_WAKE); +} + +static void bxt_init_clock_gating(struct drm_i915_private *dev_priv) +{ + gen9_init_clock_gating(dev_priv); + + /* WaDisableSDEUnitClockGating:bxt */ + intel_uncore_rmw(&dev_priv->uncore, GEN8_UCGCTL6, 0, GEN8_SDEUNIT_CLOCK_GATE_DISABLE); + + /* + * FIXME: + * GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ applies on 3x6 GT SKUs only. + */ + intel_uncore_rmw(&dev_priv->uncore, GEN8_UCGCTL6, 0, GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ); + + /* + * Wa: Backlight PWM may stop in the asserted state, causing backlight + * to stay fully on. + */ + intel_uncore_write(&dev_priv->uncore, GEN9_CLKGATE_DIS_0, intel_uncore_read(&dev_priv->uncore, GEN9_CLKGATE_DIS_0) | + PWM1_GATING_DIS | PWM2_GATING_DIS); + + /* + * Lower the display internal timeout. + * This is needed to avoid any hard hangs when DSI port PLL + * is off and a MMIO access is attempted by any privilege + * application, using batch buffers or any other means. + */ + intel_uncore_write(&dev_priv->uncore, RM_TIMEOUT, MMIO_TIMEOUT_US(950)); + + /* + * WaFbcTurnOffFbcWatermark:bxt + * Display WA #0562: bxt + */ + intel_uncore_rmw(&dev_priv->uncore, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS); + + /* + * WaFbcHighMemBwCorruptionAvoidance:bxt + * Display WA #0883: bxt + */ + intel_uncore_rmw(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), 0, DPFC_DISABLE_DUMMY0); +} + +static void glk_init_clock_gating(struct drm_i915_private *dev_priv) +{ + gen9_init_clock_gating(dev_priv); + + /* + * WaDisablePWMClockGating:glk + * Backlight PWM may stop in the asserted state, causing backlight + * to stay fully on. + */ + intel_uncore_write(&dev_priv->uncore, GEN9_CLKGATE_DIS_0, intel_uncore_read(&dev_priv->uncore, GEN9_CLKGATE_DIS_0) | + PWM1_GATING_DIS | PWM2_GATING_DIS); +} + +static void ibx_init_clock_gating(struct drm_i915_private *dev_priv) +{ + /* + * On Ibex Peak and Cougar Point, we need to disable clock + * gating for the panel power sequencer or it will fail to + * start up when no ports are active. + */ + intel_uncore_write(&dev_priv->uncore, SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE); +} + +static void g4x_disable_trickle_feed(struct drm_i915_private *dev_priv) +{ + enum pipe pipe; + + for_each_pipe(dev_priv, pipe) { + intel_uncore_rmw(&dev_priv->uncore, DSPCNTR(pipe), 0, DISP_TRICKLE_FEED_DISABLE); + + intel_uncore_rmw(&dev_priv->uncore, DSPSURF(pipe), 0, 0); + intel_uncore_posting_read(&dev_priv->uncore, DSPSURF(pipe)); + } +} + +static void ilk_init_clock_gating(struct drm_i915_private *dev_priv) +{ + u32 dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE; + + /* + * Required for FBC + * WaFbcDisableDpfcClockGating:ilk + */ + dspclk_gate |= ILK_DPFCRUNIT_CLOCK_GATE_DISABLE | + ILK_DPFCUNIT_CLOCK_GATE_DISABLE | + ILK_DPFDUNIT_CLOCK_GATE_ENABLE; + + intel_uncore_write(&dev_priv->uncore, PCH_3DCGDIS0, + MARIUNIT_CLOCK_GATE_DISABLE | + SVSMUNIT_CLOCK_GATE_DISABLE); + intel_uncore_write(&dev_priv->uncore, PCH_3DCGDIS1, + VFMUNIT_CLOCK_GATE_DISABLE); + + /* + * According to the spec the following bits should be set in + * order to enable memory self-refresh + * The bit 22/21 of 0x42004 + * The bit 5 of 0x42020 + * The bit 15 of 0x45000 + */ + intel_uncore_write(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2, + (intel_uncore_read(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2) | + ILK_DPARB_GATE | ILK_VSDPFD_FULL)); + dspclk_gate |= ILK_DPARBUNIT_CLOCK_GATE_ENABLE; + intel_uncore_write(&dev_priv->uncore, DISP_ARB_CTL, + (intel_uncore_read(&dev_priv->uncore, DISP_ARB_CTL) | + DISP_FBC_WM_DIS)); + + /* + * Based on the document from hardware guys the following bits + * should be set unconditionally in order to enable FBC. + * The bit 22 of 0x42000 + * The bit 22 of 0x42004 + * The bit 7,8,9 of 0x42020. + */ + if (IS_IRONLAKE_M(dev_priv)) { + /* WaFbcAsynchFlipDisableFbcQueue:ilk */ + intel_uncore_rmw(&dev_priv->uncore, ILK_DISPLAY_CHICKEN1, 0, ILK_FBCQ_DIS); + intel_uncore_rmw(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2, 0, ILK_DPARB_GATE); + } + + intel_uncore_write(&dev_priv->uncore, ILK_DSPCLK_GATE_D, dspclk_gate); + + intel_uncore_rmw(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2, 0, ILK_ELPIN_409_SELECT); + + g4x_disable_trickle_feed(dev_priv); + + ibx_init_clock_gating(dev_priv); +} + +static void cpt_init_clock_gating(struct drm_i915_private *dev_priv) +{ + enum pipe pipe; + u32 val; + + /* + * On Ibex Peak and Cougar Point, we need to disable clock + * gating for the panel power sequencer or it will fail to + * start up when no ports are active. + */ + intel_uncore_write(&dev_priv->uncore, SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE | + PCH_DPLUNIT_CLOCK_GATE_DISABLE | + PCH_CPUNIT_CLOCK_GATE_DISABLE); + intel_uncore_rmw(&dev_priv->uncore, SOUTH_CHICKEN2, 0, DPLS_EDP_PPS_FIX_DIS); + /* The below fixes the weird display corruption, a few pixels shifted + * downward, on (only) LVDS of some HP laptops with IVY. + */ + for_each_pipe(dev_priv, pipe) { + val = intel_uncore_read(&dev_priv->uncore, TRANS_CHICKEN2(pipe)); + val |= TRANS_CHICKEN2_TIMING_OVERRIDE; + val &= ~TRANS_CHICKEN2_FDI_POLARITY_REVERSED; + if (dev_priv->display.vbt.fdi_rx_polarity_inverted) + val |= TRANS_CHICKEN2_FDI_POLARITY_REVERSED; + val &= ~TRANS_CHICKEN2_DISABLE_DEEP_COLOR_COUNTER; + val &= ~TRANS_CHICKEN2_DISABLE_DEEP_COLOR_MODESWITCH; + intel_uncore_write(&dev_priv->uncore, TRANS_CHICKEN2(pipe), val); + } + /* WADP0ClockGatingDisable */ + for_each_pipe(dev_priv, pipe) { + intel_uncore_write(&dev_priv->uncore, TRANS_CHICKEN1(pipe), + TRANS_CHICKEN1_DP0UNIT_GC_DISABLE); + } +} + +static void gen6_check_mch_setup(struct drm_i915_private *dev_priv) +{ + u32 tmp; + + tmp = intel_uncore_read(&dev_priv->uncore, MCH_SSKPD); + if (REG_FIELD_GET(SSKPD_WM0_MASK_SNB, tmp) != 12) + drm_dbg_kms(&dev_priv->drm, + "Wrong MCH_SSKPD value: 0x%08x This can cause underruns.\n", + tmp); +} + +static void gen6_init_clock_gating(struct drm_i915_private *dev_priv) +{ + u32 dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE; + + intel_uncore_write(&dev_priv->uncore, ILK_DSPCLK_GATE_D, dspclk_gate); + + intel_uncore_rmw(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2, 0, ILK_ELPIN_409_SELECT); + + intel_uncore_write(&dev_priv->uncore, GEN6_UCGCTL1, + intel_uncore_read(&dev_priv->uncore, GEN6_UCGCTL1) | + GEN6_BLBUNIT_CLOCK_GATE_DISABLE | + GEN6_CSUNIT_CLOCK_GATE_DISABLE); + + /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock + * gating disable must be set. Failure to set it results in + * flickering pixels due to Z write ordering failures after + * some amount of runtime in the Mesa "fire" demo, and Unigine + * Sanctuary and Tropics, and apparently anything else with + * alpha test or pixel discard. + * + * According to the spec, bit 11 (RCCUNIT) must also be set, + * but we didn't debug actual testcases to find it out. + * + * WaDisableRCCUnitClockGating:snb + * WaDisableRCPBUnitClockGating:snb + */ + intel_uncore_write(&dev_priv->uncore, GEN6_UCGCTL2, + GEN6_RCPBUNIT_CLOCK_GATE_DISABLE | + GEN6_RCCUNIT_CLOCK_GATE_DISABLE); + + /* + * According to the spec the following bits should be + * set in order to enable memory self-refresh and fbc: + * The bit21 and bit22 of 0x42000 + * The bit21 and bit22 of 0x42004 + * The bit5 and bit7 of 0x42020 + * The bit14 of 0x70180 + * The bit14 of 0x71180 + * + * WaFbcAsynchFlipDisableFbcQueue:snb + */ + intel_uncore_write(&dev_priv->uncore, ILK_DISPLAY_CHICKEN1, + intel_uncore_read(&dev_priv->uncore, ILK_DISPLAY_CHICKEN1) | + ILK_FBCQ_DIS | ILK_PABSTRETCH_DIS); + intel_uncore_write(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2, + intel_uncore_read(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2) | + ILK_DPARB_GATE | ILK_VSDPFD_FULL); + intel_uncore_write(&dev_priv->uncore, ILK_DSPCLK_GATE_D, + intel_uncore_read(&dev_priv->uncore, ILK_DSPCLK_GATE_D) | + ILK_DPARBUNIT_CLOCK_GATE_ENABLE | + ILK_DPFDUNIT_CLOCK_GATE_ENABLE); + + g4x_disable_trickle_feed(dev_priv); + + cpt_init_clock_gating(dev_priv); + + gen6_check_mch_setup(dev_priv); +} + +static void lpt_init_clock_gating(struct drm_i915_private *dev_priv) +{ + /* + * TODO: this bit should only be enabled when really needed, then + * disabled when not needed anymore in order to save power. + */ + if (HAS_PCH_LPT_LP(dev_priv)) + intel_uncore_rmw(&dev_priv->uncore, SOUTH_DSPCLK_GATE_D, + 0, PCH_LP_PARTITION_LEVEL_DISABLE); + + /* WADPOClockGatingDisable:hsw */ + intel_uncore_rmw(&dev_priv->uncore, TRANS_CHICKEN1(PIPE_A), + 0, TRANS_CHICKEN1_DP0UNIT_GC_DISABLE); +} + +static void gen8_set_l3sqc_credits(struct drm_i915_private *dev_priv, + int general_prio_credits, + int high_prio_credits) +{ + u32 misccpctl; + u32 val; + + /* WaTempDisableDOPClkGating:bdw */ + misccpctl = intel_uncore_rmw(&dev_priv->uncore, GEN7_MISCCPCTL, + GEN7_DOP_CLOCK_GATE_ENABLE, 0); + + val = intel_gt_mcr_read_any(to_gt(dev_priv), GEN8_L3SQCREG1); + val &= ~L3_PRIO_CREDITS_MASK; + val |= L3_GENERAL_PRIO_CREDITS(general_prio_credits); + val |= L3_HIGH_PRIO_CREDITS(high_prio_credits); + intel_gt_mcr_multicast_write(to_gt(dev_priv), GEN8_L3SQCREG1, val); + + /* + * Wait at least 100 clocks before re-enabling clock gating. + * See the definition of L3SQCREG1 in BSpec. + */ + intel_gt_mcr_read_any(to_gt(dev_priv), GEN8_L3SQCREG1); + udelay(1); + intel_uncore_write(&dev_priv->uncore, GEN7_MISCCPCTL, misccpctl); +} + +static void icl_init_clock_gating(struct drm_i915_private *dev_priv) +{ + /* Wa_1409120013:icl,ehl */ + intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), + DPFC_CHICKEN_COMP_DUMMY_PIXEL); + + /*Wa_14010594013:icl, ehl */ + intel_uncore_rmw(&dev_priv->uncore, GEN8_CHICKEN_DCPR_1, + 0, ICL_DELAY_PMRSP); +} + +static void gen12lp_init_clock_gating(struct drm_i915_private *dev_priv) +{ + /* Wa_1409120013 */ + if (DISPLAY_VER(dev_priv) == 12) + intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), + DPFC_CHICKEN_COMP_DUMMY_PIXEL); + + /* Wa_14013723622:tgl,rkl,dg1,adl-s */ + if (DISPLAY_VER(dev_priv) == 12) + intel_uncore_rmw(&dev_priv->uncore, CLKREQ_POLICY, + CLKREQ_POLICY_MEM_UP_OVRD, 0); +} + +static void adlp_init_clock_gating(struct drm_i915_private *dev_priv) +{ + gen12lp_init_clock_gating(dev_priv); + + /* Wa_22011091694:adlp */ + intel_de_rmw(dev_priv, GEN9_CLKGATE_DIS_5, 0, DPCE_GATING_DIS); + + /* Bspec/49189 Initialize Sequence */ + intel_de_rmw(dev_priv, GEN8_CHICKEN_DCPR_1, DDI_CLOCK_REG_ACCESS, 0); +} + +static void xehpsdv_init_clock_gating(struct drm_i915_private *dev_priv) +{ + /* Wa_22010146351:xehpsdv */ + if (IS_XEHPSDV_GRAPHICS_STEP(dev_priv, STEP_A0, STEP_B0)) + intel_uncore_rmw(&dev_priv->uncore, XEHP_CLOCK_GATE_DIS, 0, SGR_DIS); +} + +static void dg2_init_clock_gating(struct drm_i915_private *i915) +{ + /* Wa_22010954014:dg2 */ + intel_uncore_rmw(&i915->uncore, XEHP_CLOCK_GATE_DIS, 0, + SGSI_SIDECLK_DIS); + + /* + * Wa_14010733611:dg2_g10 + * Wa_22010146351:dg2_g10 + */ + if (IS_DG2_GRAPHICS_STEP(i915, G10, STEP_A0, STEP_B0)) + intel_uncore_rmw(&i915->uncore, XEHP_CLOCK_GATE_DIS, 0, + SGR_DIS | SGGI_DIS); +} + +static void pvc_init_clock_gating(struct drm_i915_private *dev_priv) +{ + /* Wa_14012385139:pvc */ + if (IS_PVC_BD_STEP(dev_priv, STEP_A0, STEP_B0)) + intel_uncore_rmw(&dev_priv->uncore, XEHP_CLOCK_GATE_DIS, 0, SGR_DIS); + + /* Wa_22010954014:pvc */ + if (IS_PVC_BD_STEP(dev_priv, STEP_A0, STEP_B0)) + intel_uncore_rmw(&dev_priv->uncore, XEHP_CLOCK_GATE_DIS, 0, SGSI_SIDECLK_DIS); +} + +static void cnp_init_clock_gating(struct drm_i915_private *dev_priv) +{ + if (!HAS_PCH_CNP(dev_priv)) + return; + + /* Display WA #1181 WaSouthDisplayDisablePWMCGEGating: cnp */ + intel_uncore_rmw(&dev_priv->uncore, SOUTH_DSPCLK_GATE_D, 0, CNP_PWM_CGE_GATING_DISABLE); +} + +static void cfl_init_clock_gating(struct drm_i915_private *dev_priv) +{ + cnp_init_clock_gating(dev_priv); + gen9_init_clock_gating(dev_priv); + + /* WAC6entrylatency:cfl */ + intel_uncore_rmw(&dev_priv->uncore, FBC_LLC_READ_CTRL, 0, FBC_LLC_FULLY_OPEN); + + /* + * WaFbcTurnOffFbcWatermark:cfl + * Display WA #0562: cfl + */ + intel_uncore_rmw(&dev_priv->uncore, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS); + + /* + * WaFbcNukeOnHostModify:cfl + * Display WA #0873: cfl + */ + intel_uncore_rmw(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), + 0, DPFC_NUKE_ON_ANY_MODIFICATION); +} + +static void kbl_init_clock_gating(struct drm_i915_private *dev_priv) +{ + gen9_init_clock_gating(dev_priv); + + /* WAC6entrylatency:kbl */ + intel_uncore_rmw(&dev_priv->uncore, FBC_LLC_READ_CTRL, 0, FBC_LLC_FULLY_OPEN); + + /* WaDisableSDEUnitClockGating:kbl */ + if (IS_KBL_GRAPHICS_STEP(dev_priv, 0, STEP_C0)) + intel_uncore_rmw(&dev_priv->uncore, GEN8_UCGCTL6, + 0, GEN8_SDEUNIT_CLOCK_GATE_DISABLE); + + /* WaDisableGamClockGating:kbl */ + if (IS_KBL_GRAPHICS_STEP(dev_priv, 0, STEP_C0)) + intel_uncore_rmw(&dev_priv->uncore, GEN6_UCGCTL1, + 0, GEN6_GAMUNIT_CLOCK_GATE_DISABLE); + + /* + * WaFbcTurnOffFbcWatermark:kbl + * Display WA #0562: kbl + */ + intel_uncore_rmw(&dev_priv->uncore, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS); + + /* + * WaFbcNukeOnHostModify:kbl + * Display WA #0873: kbl + */ + intel_uncore_rmw(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), + 0, DPFC_NUKE_ON_ANY_MODIFICATION); +} + +static void skl_init_clock_gating(struct drm_i915_private *dev_priv) +{ + gen9_init_clock_gating(dev_priv); + + /* WaDisableDopClockGating:skl */ + intel_uncore_rmw(&dev_priv->uncore, GEN7_MISCCPCTL, + GEN7_DOP_CLOCK_GATE_ENABLE, 0); + + /* WAC6entrylatency:skl */ + intel_uncore_rmw(&dev_priv->uncore, FBC_LLC_READ_CTRL, 0, FBC_LLC_FULLY_OPEN); + + /* + * WaFbcTurnOffFbcWatermark:skl + * Display WA #0562: skl + */ + intel_uncore_rmw(&dev_priv->uncore, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS); + + /* + * WaFbcNukeOnHostModify:skl + * Display WA #0873: skl + */ + intel_uncore_rmw(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), + 0, DPFC_NUKE_ON_ANY_MODIFICATION); + + /* + * WaFbcHighMemBwCorruptionAvoidance:skl + * Display WA #0883: skl + */ + intel_uncore_rmw(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), 0, DPFC_DISABLE_DUMMY0); +} + +static void bdw_init_clock_gating(struct drm_i915_private *dev_priv) +{ + enum pipe pipe; + + /* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */ + intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PIPESL_1(PIPE_A), 0, HSW_FBCQ_DIS); + + /* WaSwitchSolVfFArbitrationPriority:bdw */ + intel_uncore_rmw(&dev_priv->uncore, GAM_ECOCHK, 0, HSW_ECOCHK_ARB_PRIO_SOL); + + /* WaPsrDPAMaskVBlankInSRD:bdw */ + intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PAR1_1, 0, DPA_MASK_VBLANK_SRD); + + for_each_pipe(dev_priv, pipe) { + /* WaPsrDPRSUnmaskVBlankInSRD:bdw */ + intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PIPESL_1(pipe), + 0, BDW_DPRS_MASK_VBLANK_SRD); + } + + /* WaVSRefCountFullforceMissDisable:bdw */ + /* WaDSRefCountFullforceMissDisable:bdw */ + intel_uncore_rmw(&dev_priv->uncore, GEN7_FF_THREAD_MODE, + GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME, 0); + + intel_uncore_write(&dev_priv->uncore, RING_PSMI_CTL(RENDER_RING_BASE), + _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE)); + + /* WaDisableSDEUnitClockGating:bdw */ + intel_uncore_rmw(&dev_priv->uncore, GEN8_UCGCTL6, 0, GEN8_SDEUNIT_CLOCK_GATE_DISABLE); + + /* WaProgramL3SqcReg1Default:bdw */ + gen8_set_l3sqc_credits(dev_priv, 30, 2); + + /* WaKVMNotificationOnConfigChange:bdw */ + intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PAR2_1, + 0, KVM_CONFIG_CHANGE_NOTIFICATION_SELECT); + + lpt_init_clock_gating(dev_priv); + + /* WaDisableDopClockGating:bdw + * + * Also see the CHICKEN2 write in bdw_init_workarounds() to disable DOP + * clock gating. + */ + intel_uncore_rmw(&dev_priv->uncore, GEN6_UCGCTL1, 0, GEN6_EU_TCUNIT_CLOCK_GATE_DISABLE); +} + +static void hsw_init_clock_gating(struct drm_i915_private *dev_priv) +{ + /* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */ + intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PIPESL_1(PIPE_A), 0, HSW_FBCQ_DIS); + + /* This is required by WaCatErrorRejectionIssue:hsw */ + intel_uncore_rmw(&dev_priv->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, + 0, GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); + + /* WaSwitchSolVfFArbitrationPriority:hsw */ + intel_uncore_rmw(&dev_priv->uncore, GAM_ECOCHK, 0, HSW_ECOCHK_ARB_PRIO_SOL); + + lpt_init_clock_gating(dev_priv); +} + +static void ivb_init_clock_gating(struct drm_i915_private *dev_priv) +{ + intel_uncore_write(&dev_priv->uncore, ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE); + + /* WaFbcAsynchFlipDisableFbcQueue:ivb */ + intel_uncore_rmw(&dev_priv->uncore, ILK_DISPLAY_CHICKEN1, 0, ILK_FBCQ_DIS); + + /* WaDisableBackToBackFlipFix:ivb */ + intel_uncore_write(&dev_priv->uncore, IVB_CHICKEN3, + CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | + CHICKEN3_DGMG_DONE_FIX_DISABLE); + + if (IS_IVB_GT1(dev_priv)) + intel_uncore_write(&dev_priv->uncore, GEN7_ROW_CHICKEN2, + _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); + else { + /* must write both registers */ + intel_uncore_write(&dev_priv->uncore, GEN7_ROW_CHICKEN2, + _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); + intel_uncore_write(&dev_priv->uncore, GEN7_ROW_CHICKEN2_GT2, + _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); + } + + /* + * According to the spec, bit 13 (RCZUNIT) must be set on IVB. + * This implements the WaDisableRCZUnitClockGating:ivb workaround. + */ + intel_uncore_write(&dev_priv->uncore, GEN6_UCGCTL2, + GEN6_RCZUNIT_CLOCK_GATE_DISABLE); + + /* This is required by WaCatErrorRejectionIssue:ivb */ + intel_uncore_rmw(&dev_priv->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, + 0, GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); + + g4x_disable_trickle_feed(dev_priv); + + intel_uncore_rmw(&dev_priv->uncore, GEN6_MBCUNIT_SNPCR, GEN6_MBC_SNPCR_MASK, + GEN6_MBC_SNPCR_MED); + + if (!HAS_PCH_NOP(dev_priv)) + cpt_init_clock_gating(dev_priv); + + gen6_check_mch_setup(dev_priv); +} + +static void vlv_init_clock_gating(struct drm_i915_private *dev_priv) +{ + /* WaDisableBackToBackFlipFix:vlv */ + intel_uncore_write(&dev_priv->uncore, IVB_CHICKEN3, + CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | + CHICKEN3_DGMG_DONE_FIX_DISABLE); + + /* WaDisableDopClockGating:vlv */ + intel_uncore_write(&dev_priv->uncore, GEN7_ROW_CHICKEN2, + _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); + + /* This is required by WaCatErrorRejectionIssue:vlv */ + intel_uncore_rmw(&dev_priv->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, + 0, GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); + + /* + * According to the spec, bit 13 (RCZUNIT) must be set on IVB. + * This implements the WaDisableRCZUnitClockGating:vlv workaround. + */ + intel_uncore_write(&dev_priv->uncore, GEN6_UCGCTL2, + GEN6_RCZUNIT_CLOCK_GATE_DISABLE); + + /* WaDisableL3Bank2xClockGate:vlv + * Disabling L3 clock gating- MMIO 940c[25] = 1 + * Set bit 25, to disable L3_BANK_2x_CLK_GATING */ + intel_uncore_rmw(&dev_priv->uncore, GEN7_UCGCTL4, 0, GEN7_L3BANK2X_CLOCK_GATE_DISABLE); + + /* + * WaDisableVLVClockGating_VBIIssue:vlv + * Disable clock gating on th GCFG unit to prevent a delay + * in the reporting of vblank events. + */ + intel_uncore_write(&dev_priv->uncore, VLV_GUNIT_CLOCK_GATE, GCFG_DIS); +} + +static void chv_init_clock_gating(struct drm_i915_private *dev_priv) +{ + /* WaVSRefCountFullforceMissDisable:chv */ + /* WaDSRefCountFullforceMissDisable:chv */ + intel_uncore_rmw(&dev_priv->uncore, GEN7_FF_THREAD_MODE, + GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME, 0); + + /* WaDisableSemaphoreAndSyncFlipWait:chv */ + intel_uncore_write(&dev_priv->uncore, RING_PSMI_CTL(RENDER_RING_BASE), + _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE)); + + /* WaDisableCSUnitClockGating:chv */ + intel_uncore_rmw(&dev_priv->uncore, GEN6_UCGCTL1, 0, GEN6_CSUNIT_CLOCK_GATE_DISABLE); + + /* WaDisableSDEUnitClockGating:chv */ + intel_uncore_rmw(&dev_priv->uncore, GEN8_UCGCTL6, 0, GEN8_SDEUNIT_CLOCK_GATE_DISABLE); + + /* + * WaProgramL3SqcReg1Default:chv + * See gfxspecs/Related Documents/Performance Guide/ + * LSQC Setting Recommendations. + */ + gen8_set_l3sqc_credits(dev_priv, 38, 2); +} + +static void g4x_init_clock_gating(struct drm_i915_private *dev_priv) +{ + u32 dspclk_gate; + + intel_uncore_write(&dev_priv->uncore, RENCLK_GATE_D1, 0); + intel_uncore_write(&dev_priv->uncore, RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | + GS_UNIT_CLOCK_GATE_DISABLE | + CL_UNIT_CLOCK_GATE_DISABLE); + intel_uncore_write(&dev_priv->uncore, RAMCLK_GATE_D, 0); + dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE | + OVRUNIT_CLOCK_GATE_DISABLE | + OVCUNIT_CLOCK_GATE_DISABLE; + if (IS_GM45(dev_priv)) + dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE; + intel_uncore_write(&dev_priv->uncore, DSPCLK_GATE_D(dev_priv), dspclk_gate); + + g4x_disable_trickle_feed(dev_priv); +} + +static void i965gm_init_clock_gating(struct drm_i915_private *dev_priv) +{ + struct intel_uncore *uncore = &dev_priv->uncore; + + intel_uncore_write(uncore, RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE); + intel_uncore_write(uncore, RENCLK_GATE_D2, 0); + intel_uncore_write(uncore, DSPCLK_GATE_D(dev_priv), 0); + intel_uncore_write(uncore, RAMCLK_GATE_D, 0); + intel_uncore_write16(uncore, DEUC, 0); + intel_uncore_write(uncore, + MI_ARB_STATE, + _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE)); +} + +static void i965g_init_clock_gating(struct drm_i915_private *dev_priv) +{ + intel_uncore_write(&dev_priv->uncore, RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE | + I965_RCC_CLOCK_GATE_DISABLE | + I965_RCPB_CLOCK_GATE_DISABLE | + I965_ISC_CLOCK_GATE_DISABLE | + I965_FBC_CLOCK_GATE_DISABLE); + intel_uncore_write(&dev_priv->uncore, RENCLK_GATE_D2, 0); + intel_uncore_write(&dev_priv->uncore, MI_ARB_STATE, + _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE)); +} + +static void gen3_init_clock_gating(struct drm_i915_private *dev_priv) +{ + u32 dstate = intel_uncore_read(&dev_priv->uncore, D_STATE); + + dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING | + DSTATE_DOT_CLOCK_GATING; + intel_uncore_write(&dev_priv->uncore, D_STATE, dstate); + + if (IS_PINEVIEW(dev_priv)) + intel_uncore_write(&dev_priv->uncore, ECOSKPD(RENDER_RING_BASE), + _MASKED_BIT_ENABLE(ECO_GATING_CX_ONLY)); + + /* IIR "flip pending" means done if this bit is set */ + intel_uncore_write(&dev_priv->uncore, ECOSKPD(RENDER_RING_BASE), + _MASKED_BIT_DISABLE(ECO_FLIP_DONE)); + + /* interrupts should cause a wake up from C3 */ + intel_uncore_write(&dev_priv->uncore, INSTPM, _MASKED_BIT_ENABLE(INSTPM_AGPBUSY_INT_EN)); + + /* On GEN3 we really need to make sure the ARB C3 LP bit is set */ + intel_uncore_write(&dev_priv->uncore, MI_ARB_STATE, _MASKED_BIT_ENABLE(MI_ARB_C3_LP_WRITE_ENABLE)); + + intel_uncore_write(&dev_priv->uncore, MI_ARB_STATE, + _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE)); +} + +static void i85x_init_clock_gating(struct drm_i915_private *dev_priv) +{ + intel_uncore_write(&dev_priv->uncore, RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE); + + /* interrupts should cause a wake up from C3 */ + intel_uncore_write(&dev_priv->uncore, MI_STATE, _MASKED_BIT_ENABLE(MI_AGPBUSY_INT_EN) | + _MASKED_BIT_DISABLE(MI_AGPBUSY_830_MODE)); + + intel_uncore_write(&dev_priv->uncore, MEM_MODE, + _MASKED_BIT_ENABLE(MEM_DISPLAY_TRICKLE_FEED_DISABLE)); + + /* + * Have FBC ignore 3D activity since we use software + * render tracking, and otherwise a pure 3D workload + * (even if it just renders a single frame and then does + * abosultely nothing) would not allow FBC to recompress + * until a 2D blit occurs. + */ + intel_uncore_write(&dev_priv->uncore, SCPD0, + _MASKED_BIT_ENABLE(SCPD_FBC_IGNORE_3D)); +} + +static void i830_init_clock_gating(struct drm_i915_private *dev_priv) +{ + intel_uncore_write(&dev_priv->uncore, MEM_MODE, + _MASKED_BIT_ENABLE(MEM_DISPLAY_A_TRICKLE_FEED_DISABLE) | + _MASKED_BIT_ENABLE(MEM_DISPLAY_B_TRICKLE_FEED_DISABLE)); +} + +void intel_clock_gating_init(struct drm_i915_private *dev_priv) +{ + dev_priv->clock_gating_funcs->init_clock_gating(dev_priv); +} + +static void nop_init_clock_gating(struct drm_i915_private *dev_priv) +{ + drm_dbg_kms(&dev_priv->drm, + "No clock gating settings or workarounds applied.\n"); +} + +#define CG_FUNCS(platform) \ +static const struct drm_i915_clock_gating_funcs platform##_clock_gating_funcs = { \ + .init_clock_gating = platform##_init_clock_gating, \ +} + +CG_FUNCS(pvc); +CG_FUNCS(dg2); +CG_FUNCS(xehpsdv); +CG_FUNCS(adlp); +CG_FUNCS(gen12lp); +CG_FUNCS(icl); +CG_FUNCS(cfl); +CG_FUNCS(skl); +CG_FUNCS(kbl); +CG_FUNCS(bxt); +CG_FUNCS(glk); +CG_FUNCS(bdw); +CG_FUNCS(chv); +CG_FUNCS(hsw); +CG_FUNCS(ivb); +CG_FUNCS(vlv); +CG_FUNCS(gen6); +CG_FUNCS(ilk); +CG_FUNCS(g4x); +CG_FUNCS(i965gm); +CG_FUNCS(i965g); +CG_FUNCS(gen3); +CG_FUNCS(i85x); +CG_FUNCS(i830); +CG_FUNCS(nop); +#undef CG_FUNCS + +/** + * intel_clock_gating_hooks_init - setup the clock gating hooks + * @dev_priv: device private + * + * Setup the hooks that configure which clocks of a given platform can be + * gated and also apply various GT and display specific workarounds for these + * platforms. Note that some GT specific workarounds are applied separately + * when GPU contexts or batchbuffers start their execution. + */ +void intel_clock_gating_hooks_init(struct drm_i915_private *dev_priv) +{ + if (IS_METEORLAKE(dev_priv)) + dev_priv->clock_gating_funcs = &nop_clock_gating_funcs; + else if (IS_PONTEVECCHIO(dev_priv)) + dev_priv->clock_gating_funcs = &pvc_clock_gating_funcs; + else if (IS_DG2(dev_priv)) + dev_priv->clock_gating_funcs = &dg2_clock_gating_funcs; + else if (IS_XEHPSDV(dev_priv)) + dev_priv->clock_gating_funcs = &xehpsdv_clock_gating_funcs; + else if (IS_ALDERLAKE_P(dev_priv)) + dev_priv->clock_gating_funcs = &adlp_clock_gating_funcs; + else if (GRAPHICS_VER(dev_priv) == 12) + dev_priv->clock_gating_funcs = &gen12lp_clock_gating_funcs; + else if (GRAPHICS_VER(dev_priv) == 11) + dev_priv->clock_gating_funcs = &icl_clock_gating_funcs; + else if (IS_COFFEELAKE(dev_priv) || IS_COMETLAKE(dev_priv)) + dev_priv->clock_gating_funcs = &cfl_clock_gating_funcs; + else if (IS_SKYLAKE(dev_priv)) + dev_priv->clock_gating_funcs = &skl_clock_gating_funcs; + else if (IS_KABYLAKE(dev_priv)) + dev_priv->clock_gating_funcs = &kbl_clock_gating_funcs; + else if (IS_BROXTON(dev_priv)) + dev_priv->clock_gating_funcs = &bxt_clock_gating_funcs; + else if (IS_GEMINILAKE(dev_priv)) + dev_priv->clock_gating_funcs = &glk_clock_gating_funcs; + else if (IS_BROADWELL(dev_priv)) + dev_priv->clock_gating_funcs = &bdw_clock_gating_funcs; + else if (IS_CHERRYVIEW(dev_priv)) + dev_priv->clock_gating_funcs = &chv_clock_gating_funcs; + else if (IS_HASWELL(dev_priv)) + dev_priv->clock_gating_funcs = &hsw_clock_gating_funcs; + else if (IS_IVYBRIDGE(dev_priv)) + dev_priv->clock_gating_funcs = &ivb_clock_gating_funcs; + else if (IS_VALLEYVIEW(dev_priv)) + dev_priv->clock_gating_funcs = &vlv_clock_gating_funcs; + else if (GRAPHICS_VER(dev_priv) == 6) + dev_priv->clock_gating_funcs = &gen6_clock_gating_funcs; + else if (GRAPHICS_VER(dev_priv) == 5) + dev_priv->clock_gating_funcs = &ilk_clock_gating_funcs; + else if (IS_G4X(dev_priv)) + dev_priv->clock_gating_funcs = &g4x_clock_gating_funcs; + else if (IS_I965GM(dev_priv)) + dev_priv->clock_gating_funcs = &i965gm_clock_gating_funcs; + else if (IS_I965G(dev_priv)) + dev_priv->clock_gating_funcs = &i965g_clock_gating_funcs; + else if (GRAPHICS_VER(dev_priv) == 3) + dev_priv->clock_gating_funcs = &gen3_clock_gating_funcs; + else if (IS_I85X(dev_priv) || IS_I865G(dev_priv)) + dev_priv->clock_gating_funcs = &i85x_clock_gating_funcs; + else if (GRAPHICS_VER(dev_priv) == 2) + dev_priv->clock_gating_funcs = &i830_clock_gating_funcs; + else { + MISSING_CASE(INTEL_DEVID(dev_priv)); + dev_priv->clock_gating_funcs = &nop_clock_gating_funcs; + } +} diff --git a/drivers/gpu/drm/i915/intel_clock_gating.h b/drivers/gpu/drm/i915/intel_clock_gating.h new file mode 100644 index 000000000000..5b4e4c55b2c2 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_clock_gating.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2019 Intel Corporation + */ + +#ifndef __INTEL_CLOCK_GATING_H__ +#define __INTEL_CLOCK_GATING_H__ + +struct drm_i915_private; + +void intel_clock_gating_init(struct drm_i915_private *i915); +void intel_clock_gating_hooks_init(struct drm_i915_private *i915); + +#endif /* __INTEL_CLOCK_GATING_H__ */ diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c deleted file mode 100644 index c45af0d981fd..000000000000 --- a/drivers/gpu/drm/i915/intel_pm.c +++ /dev/null @@ -1,885 +0,0 @@ -/* - * Copyright © 2012 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Eugeni Dodonov - * - */ - -#include "display/intel_de.h" -#include "display/intel_display.h" -#include "display/intel_display_trace.h" -#include "display/skl_watermark.h" - -#include "gt/intel_engine_regs.h" -#include "gt/intel_gt.h" -#include "gt/intel_gt_mcr.h" -#include "gt/intel_gt_regs.h" - -#include "i915_drv.h" -#include "intel_mchbar_regs.h" -#include "intel_pm.h" -#include "vlv_sideband.h" - -struct drm_i915_clock_gating_funcs { - void (*init_clock_gating)(struct drm_i915_private *i915); -}; - -static void gen9_init_clock_gating(struct drm_i915_private *dev_priv) -{ - if (HAS_LLC(dev_priv)) { - /* - * WaCompressedResourceDisplayNewHashMode:skl,kbl - * Display WA #0390: skl,kbl - * - * Must match Sampler, Pixel Back End, and Media. See - * WaCompressedResourceSamplerPbeMediaNewHashMode. - */ - intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PAR1_1, 0, SKL_DE_COMPRESSED_HASH_MODE); - } - - /* See Bspec note for PSR2_CTL bit 31, Wa#828:skl,bxt,kbl,cfl */ - intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PAR1_1, 0, SKL_EDP_PSR_FIX_RDWRAP); - - /* WaEnableChickenDCPR:skl,bxt,kbl,glk,cfl */ - intel_uncore_rmw(&dev_priv->uncore, GEN8_CHICKEN_DCPR_1, 0, MASK_WAKEMEM); - - /* - * WaFbcWakeMemOn:skl,bxt,kbl,glk,cfl - * Display WA #0859: skl,bxt,kbl,glk,cfl - */ - intel_uncore_rmw(&dev_priv->uncore, DISP_ARB_CTL, 0, DISP_FBC_MEMORY_WAKE); -} - -static void bxt_init_clock_gating(struct drm_i915_private *dev_priv) -{ - gen9_init_clock_gating(dev_priv); - - /* WaDisableSDEUnitClockGating:bxt */ - intel_uncore_rmw(&dev_priv->uncore, GEN8_UCGCTL6, 0, GEN8_SDEUNIT_CLOCK_GATE_DISABLE); - - /* - * FIXME: - * GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ applies on 3x6 GT SKUs only. - */ - intel_uncore_rmw(&dev_priv->uncore, GEN8_UCGCTL6, 0, GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ); - - /* - * Wa: Backlight PWM may stop in the asserted state, causing backlight - * to stay fully on. - */ - intel_uncore_write(&dev_priv->uncore, GEN9_CLKGATE_DIS_0, intel_uncore_read(&dev_priv->uncore, GEN9_CLKGATE_DIS_0) | - PWM1_GATING_DIS | PWM2_GATING_DIS); - - /* - * Lower the display internal timeout. - * This is needed to avoid any hard hangs when DSI port PLL - * is off and a MMIO access is attempted by any privilege - * application, using batch buffers or any other means. - */ - intel_uncore_write(&dev_priv->uncore, RM_TIMEOUT, MMIO_TIMEOUT_US(950)); - - /* - * WaFbcTurnOffFbcWatermark:bxt - * Display WA #0562: bxt - */ - intel_uncore_rmw(&dev_priv->uncore, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS); - - /* - * WaFbcHighMemBwCorruptionAvoidance:bxt - * Display WA #0883: bxt - */ - intel_uncore_rmw(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), 0, DPFC_DISABLE_DUMMY0); -} - -static void glk_init_clock_gating(struct drm_i915_private *dev_priv) -{ - gen9_init_clock_gating(dev_priv); - - /* - * WaDisablePWMClockGating:glk - * Backlight PWM may stop in the asserted state, causing backlight - * to stay fully on. - */ - intel_uncore_write(&dev_priv->uncore, GEN9_CLKGATE_DIS_0, intel_uncore_read(&dev_priv->uncore, GEN9_CLKGATE_DIS_0) | - PWM1_GATING_DIS | PWM2_GATING_DIS); -} - -static void ibx_init_clock_gating(struct drm_i915_private *dev_priv) -{ - /* - * On Ibex Peak and Cougar Point, we need to disable clock - * gating for the panel power sequencer or it will fail to - * start up when no ports are active. - */ - intel_uncore_write(&dev_priv->uncore, SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE); -} - -static void g4x_disable_trickle_feed(struct drm_i915_private *dev_priv) -{ - enum pipe pipe; - - for_each_pipe(dev_priv, pipe) { - intel_uncore_rmw(&dev_priv->uncore, DSPCNTR(pipe), 0, DISP_TRICKLE_FEED_DISABLE); - - intel_uncore_rmw(&dev_priv->uncore, DSPSURF(pipe), 0, 0); - intel_uncore_posting_read(&dev_priv->uncore, DSPSURF(pipe)); - } -} - -static void ilk_init_clock_gating(struct drm_i915_private *dev_priv) -{ - u32 dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE; - - /* - * Required for FBC - * WaFbcDisableDpfcClockGating:ilk - */ - dspclk_gate |= ILK_DPFCRUNIT_CLOCK_GATE_DISABLE | - ILK_DPFCUNIT_CLOCK_GATE_DISABLE | - ILK_DPFDUNIT_CLOCK_GATE_ENABLE; - - intel_uncore_write(&dev_priv->uncore, PCH_3DCGDIS0, - MARIUNIT_CLOCK_GATE_DISABLE | - SVSMUNIT_CLOCK_GATE_DISABLE); - intel_uncore_write(&dev_priv->uncore, PCH_3DCGDIS1, - VFMUNIT_CLOCK_GATE_DISABLE); - - /* - * According to the spec the following bits should be set in - * order to enable memory self-refresh - * The bit 22/21 of 0x42004 - * The bit 5 of 0x42020 - * The bit 15 of 0x45000 - */ - intel_uncore_write(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2, - (intel_uncore_read(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2) | - ILK_DPARB_GATE | ILK_VSDPFD_FULL)); - dspclk_gate |= ILK_DPARBUNIT_CLOCK_GATE_ENABLE; - intel_uncore_write(&dev_priv->uncore, DISP_ARB_CTL, - (intel_uncore_read(&dev_priv->uncore, DISP_ARB_CTL) | - DISP_FBC_WM_DIS)); - - /* - * Based on the document from hardware guys the following bits - * should be set unconditionally in order to enable FBC. - * The bit 22 of 0x42000 - * The bit 22 of 0x42004 - * The bit 7,8,9 of 0x42020. - */ - if (IS_IRONLAKE_M(dev_priv)) { - /* WaFbcAsynchFlipDisableFbcQueue:ilk */ - intel_uncore_rmw(&dev_priv->uncore, ILK_DISPLAY_CHICKEN1, 0, ILK_FBCQ_DIS); - intel_uncore_rmw(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2, 0, ILK_DPARB_GATE); - } - - intel_uncore_write(&dev_priv->uncore, ILK_DSPCLK_GATE_D, dspclk_gate); - - intel_uncore_rmw(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2, 0, ILK_ELPIN_409_SELECT); - - g4x_disable_trickle_feed(dev_priv); - - ibx_init_clock_gating(dev_priv); -} - -static void cpt_init_clock_gating(struct drm_i915_private *dev_priv) -{ - enum pipe pipe; - u32 val; - - /* - * On Ibex Peak and Cougar Point, we need to disable clock - * gating for the panel power sequencer or it will fail to - * start up when no ports are active. - */ - intel_uncore_write(&dev_priv->uncore, SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE | - PCH_DPLUNIT_CLOCK_GATE_DISABLE | - PCH_CPUNIT_CLOCK_GATE_DISABLE); - intel_uncore_rmw(&dev_priv->uncore, SOUTH_CHICKEN2, 0, DPLS_EDP_PPS_FIX_DIS); - /* The below fixes the weird display corruption, a few pixels shifted - * downward, on (only) LVDS of some HP laptops with IVY. - */ - for_each_pipe(dev_priv, pipe) { - val = intel_uncore_read(&dev_priv->uncore, TRANS_CHICKEN2(pipe)); - val |= TRANS_CHICKEN2_TIMING_OVERRIDE; - val &= ~TRANS_CHICKEN2_FDI_POLARITY_REVERSED; - if (dev_priv->display.vbt.fdi_rx_polarity_inverted) - val |= TRANS_CHICKEN2_FDI_POLARITY_REVERSED; - val &= ~TRANS_CHICKEN2_DISABLE_DEEP_COLOR_COUNTER; - val &= ~TRANS_CHICKEN2_DISABLE_DEEP_COLOR_MODESWITCH; - intel_uncore_write(&dev_priv->uncore, TRANS_CHICKEN2(pipe), val); - } - /* WADP0ClockGatingDisable */ - for_each_pipe(dev_priv, pipe) { - intel_uncore_write(&dev_priv->uncore, TRANS_CHICKEN1(pipe), - TRANS_CHICKEN1_DP0UNIT_GC_DISABLE); - } -} - -static void gen6_check_mch_setup(struct drm_i915_private *dev_priv) -{ - u32 tmp; - - tmp = intel_uncore_read(&dev_priv->uncore, MCH_SSKPD); - if (REG_FIELD_GET(SSKPD_WM0_MASK_SNB, tmp) != 12) - drm_dbg_kms(&dev_priv->drm, - "Wrong MCH_SSKPD value: 0x%08x This can cause underruns.\n", - tmp); -} - -static void gen6_init_clock_gating(struct drm_i915_private *dev_priv) -{ - u32 dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE; - - intel_uncore_write(&dev_priv->uncore, ILK_DSPCLK_GATE_D, dspclk_gate); - - intel_uncore_rmw(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2, 0, ILK_ELPIN_409_SELECT); - - intel_uncore_write(&dev_priv->uncore, GEN6_UCGCTL1, - intel_uncore_read(&dev_priv->uncore, GEN6_UCGCTL1) | - GEN6_BLBUNIT_CLOCK_GATE_DISABLE | - GEN6_CSUNIT_CLOCK_GATE_DISABLE); - - /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock - * gating disable must be set. Failure to set it results in - * flickering pixels due to Z write ordering failures after - * some amount of runtime in the Mesa "fire" demo, and Unigine - * Sanctuary and Tropics, and apparently anything else with - * alpha test or pixel discard. - * - * According to the spec, bit 11 (RCCUNIT) must also be set, - * but we didn't debug actual testcases to find it out. - * - * WaDisableRCCUnitClockGating:snb - * WaDisableRCPBUnitClockGating:snb - */ - intel_uncore_write(&dev_priv->uncore, GEN6_UCGCTL2, - GEN6_RCPBUNIT_CLOCK_GATE_DISABLE | - GEN6_RCCUNIT_CLOCK_GATE_DISABLE); - - /* - * According to the spec the following bits should be - * set in order to enable memory self-refresh and fbc: - * The bit21 and bit22 of 0x42000 - * The bit21 and bit22 of 0x42004 - * The bit5 and bit7 of 0x42020 - * The bit14 of 0x70180 - * The bit14 of 0x71180 - * - * WaFbcAsynchFlipDisableFbcQueue:snb - */ - intel_uncore_write(&dev_priv->uncore, ILK_DISPLAY_CHICKEN1, - intel_uncore_read(&dev_priv->uncore, ILK_DISPLAY_CHICKEN1) | - ILK_FBCQ_DIS | ILK_PABSTRETCH_DIS); - intel_uncore_write(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2, - intel_uncore_read(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2) | - ILK_DPARB_GATE | ILK_VSDPFD_FULL); - intel_uncore_write(&dev_priv->uncore, ILK_DSPCLK_GATE_D, - intel_uncore_read(&dev_priv->uncore, ILK_DSPCLK_GATE_D) | - ILK_DPARBUNIT_CLOCK_GATE_ENABLE | - ILK_DPFDUNIT_CLOCK_GATE_ENABLE); - - g4x_disable_trickle_feed(dev_priv); - - cpt_init_clock_gating(dev_priv); - - gen6_check_mch_setup(dev_priv); -} - -static void lpt_init_clock_gating(struct drm_i915_private *dev_priv) -{ - /* - * TODO: this bit should only be enabled when really needed, then - * disabled when not needed anymore in order to save power. - */ - if (HAS_PCH_LPT_LP(dev_priv)) - intel_uncore_rmw(&dev_priv->uncore, SOUTH_DSPCLK_GATE_D, - 0, PCH_LP_PARTITION_LEVEL_DISABLE); - - /* WADPOClockGatingDisable:hsw */ - intel_uncore_rmw(&dev_priv->uncore, TRANS_CHICKEN1(PIPE_A), - 0, TRANS_CHICKEN1_DP0UNIT_GC_DISABLE); -} - -static void gen8_set_l3sqc_credits(struct drm_i915_private *dev_priv, - int general_prio_credits, - int high_prio_credits) -{ - u32 misccpctl; - u32 val; - - /* WaTempDisableDOPClkGating:bdw */ - misccpctl = intel_uncore_rmw(&dev_priv->uncore, GEN7_MISCCPCTL, - GEN7_DOP_CLOCK_GATE_ENABLE, 0); - - val = intel_gt_mcr_read_any(to_gt(dev_priv), GEN8_L3SQCREG1); - val &= ~L3_PRIO_CREDITS_MASK; - val |= L3_GENERAL_PRIO_CREDITS(general_prio_credits); - val |= L3_HIGH_PRIO_CREDITS(high_prio_credits); - intel_gt_mcr_multicast_write(to_gt(dev_priv), GEN8_L3SQCREG1, val); - - /* - * Wait at least 100 clocks before re-enabling clock gating. - * See the definition of L3SQCREG1 in BSpec. - */ - intel_gt_mcr_read_any(to_gt(dev_priv), GEN8_L3SQCREG1); - udelay(1); - intel_uncore_write(&dev_priv->uncore, GEN7_MISCCPCTL, misccpctl); -} - -static void icl_init_clock_gating(struct drm_i915_private *dev_priv) -{ - /* Wa_1409120013:icl,ehl */ - intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), - DPFC_CHICKEN_COMP_DUMMY_PIXEL); - - /*Wa_14010594013:icl, ehl */ - intel_uncore_rmw(&dev_priv->uncore, GEN8_CHICKEN_DCPR_1, - 0, ICL_DELAY_PMRSP); -} - -static void gen12lp_init_clock_gating(struct drm_i915_private *dev_priv) -{ - /* Wa_1409120013 */ - if (DISPLAY_VER(dev_priv) == 12) - intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), - DPFC_CHICKEN_COMP_DUMMY_PIXEL); - - /* Wa_14013723622:tgl,rkl,dg1,adl-s */ - if (DISPLAY_VER(dev_priv) == 12) - intel_uncore_rmw(&dev_priv->uncore, CLKREQ_POLICY, - CLKREQ_POLICY_MEM_UP_OVRD, 0); -} - -static void adlp_init_clock_gating(struct drm_i915_private *dev_priv) -{ - gen12lp_init_clock_gating(dev_priv); - - /* Wa_22011091694:adlp */ - intel_de_rmw(dev_priv, GEN9_CLKGATE_DIS_5, 0, DPCE_GATING_DIS); - - /* Bspec/49189 Initialize Sequence */ - intel_de_rmw(dev_priv, GEN8_CHICKEN_DCPR_1, DDI_CLOCK_REG_ACCESS, 0); -} - -static void xehpsdv_init_clock_gating(struct drm_i915_private *dev_priv) -{ - /* Wa_22010146351:xehpsdv */ - if (IS_XEHPSDV_GRAPHICS_STEP(dev_priv, STEP_A0, STEP_B0)) - intel_uncore_rmw(&dev_priv->uncore, XEHP_CLOCK_GATE_DIS, 0, SGR_DIS); -} - -static void dg2_init_clock_gating(struct drm_i915_private *i915) -{ - /* Wa_22010954014:dg2 */ - intel_uncore_rmw(&i915->uncore, XEHP_CLOCK_GATE_DIS, 0, - SGSI_SIDECLK_DIS); - - /* - * Wa_14010733611:dg2_g10 - * Wa_22010146351:dg2_g10 - */ - if (IS_DG2_GRAPHICS_STEP(i915, G10, STEP_A0, STEP_B0)) - intel_uncore_rmw(&i915->uncore, XEHP_CLOCK_GATE_DIS, 0, - SGR_DIS | SGGI_DIS); -} - -static void pvc_init_clock_gating(struct drm_i915_private *dev_priv) -{ - /* Wa_14012385139:pvc */ - if (IS_PVC_BD_STEP(dev_priv, STEP_A0, STEP_B0)) - intel_uncore_rmw(&dev_priv->uncore, XEHP_CLOCK_GATE_DIS, 0, SGR_DIS); - - /* Wa_22010954014:pvc */ - if (IS_PVC_BD_STEP(dev_priv, STEP_A0, STEP_B0)) - intel_uncore_rmw(&dev_priv->uncore, XEHP_CLOCK_GATE_DIS, 0, SGSI_SIDECLK_DIS); -} - -static void cnp_init_clock_gating(struct drm_i915_private *dev_priv) -{ - if (!HAS_PCH_CNP(dev_priv)) - return; - - /* Display WA #1181 WaSouthDisplayDisablePWMCGEGating: cnp */ - intel_uncore_rmw(&dev_priv->uncore, SOUTH_DSPCLK_GATE_D, 0, CNP_PWM_CGE_GATING_DISABLE); -} - -static void cfl_init_clock_gating(struct drm_i915_private *dev_priv) -{ - cnp_init_clock_gating(dev_priv); - gen9_init_clock_gating(dev_priv); - - /* WAC6entrylatency:cfl */ - intel_uncore_rmw(&dev_priv->uncore, FBC_LLC_READ_CTRL, 0, FBC_LLC_FULLY_OPEN); - - /* - * WaFbcTurnOffFbcWatermark:cfl - * Display WA #0562: cfl - */ - intel_uncore_rmw(&dev_priv->uncore, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS); - - /* - * WaFbcNukeOnHostModify:cfl - * Display WA #0873: cfl - */ - intel_uncore_rmw(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), - 0, DPFC_NUKE_ON_ANY_MODIFICATION); -} - -static void kbl_init_clock_gating(struct drm_i915_private *dev_priv) -{ - gen9_init_clock_gating(dev_priv); - - /* WAC6entrylatency:kbl */ - intel_uncore_rmw(&dev_priv->uncore, FBC_LLC_READ_CTRL, 0, FBC_LLC_FULLY_OPEN); - - /* WaDisableSDEUnitClockGating:kbl */ - if (IS_KBL_GRAPHICS_STEP(dev_priv, 0, STEP_C0)) - intel_uncore_rmw(&dev_priv->uncore, GEN8_UCGCTL6, - 0, GEN8_SDEUNIT_CLOCK_GATE_DISABLE); - - /* WaDisableGamClockGating:kbl */ - if (IS_KBL_GRAPHICS_STEP(dev_priv, 0, STEP_C0)) - intel_uncore_rmw(&dev_priv->uncore, GEN6_UCGCTL1, - 0, GEN6_GAMUNIT_CLOCK_GATE_DISABLE); - - /* - * WaFbcTurnOffFbcWatermark:kbl - * Display WA #0562: kbl - */ - intel_uncore_rmw(&dev_priv->uncore, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS); - - /* - * WaFbcNukeOnHostModify:kbl - * Display WA #0873: kbl - */ - intel_uncore_rmw(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), - 0, DPFC_NUKE_ON_ANY_MODIFICATION); -} - -static void skl_init_clock_gating(struct drm_i915_private *dev_priv) -{ - gen9_init_clock_gating(dev_priv); - - /* WaDisableDopClockGating:skl */ - intel_uncore_rmw(&dev_priv->uncore, GEN7_MISCCPCTL, - GEN7_DOP_CLOCK_GATE_ENABLE, 0); - - /* WAC6entrylatency:skl */ - intel_uncore_rmw(&dev_priv->uncore, FBC_LLC_READ_CTRL, 0, FBC_LLC_FULLY_OPEN); - - /* - * WaFbcTurnOffFbcWatermark:skl - * Display WA #0562: skl - */ - intel_uncore_rmw(&dev_priv->uncore, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS); - - /* - * WaFbcNukeOnHostModify:skl - * Display WA #0873: skl - */ - intel_uncore_rmw(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), - 0, DPFC_NUKE_ON_ANY_MODIFICATION); - - /* - * WaFbcHighMemBwCorruptionAvoidance:skl - * Display WA #0883: skl - */ - intel_uncore_rmw(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), 0, DPFC_DISABLE_DUMMY0); -} - -static void bdw_init_clock_gating(struct drm_i915_private *dev_priv) -{ - enum pipe pipe; - - /* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */ - intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PIPESL_1(PIPE_A), 0, HSW_FBCQ_DIS); - - /* WaSwitchSolVfFArbitrationPriority:bdw */ - intel_uncore_rmw(&dev_priv->uncore, GAM_ECOCHK, 0, HSW_ECOCHK_ARB_PRIO_SOL); - - /* WaPsrDPAMaskVBlankInSRD:bdw */ - intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PAR1_1, 0, DPA_MASK_VBLANK_SRD); - - for_each_pipe(dev_priv, pipe) { - /* WaPsrDPRSUnmaskVBlankInSRD:bdw */ - intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PIPESL_1(pipe), - 0, BDW_DPRS_MASK_VBLANK_SRD); - } - - /* WaVSRefCountFullforceMissDisable:bdw */ - /* WaDSRefCountFullforceMissDisable:bdw */ - intel_uncore_rmw(&dev_priv->uncore, GEN7_FF_THREAD_MODE, - GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME, 0); - - intel_uncore_write(&dev_priv->uncore, RING_PSMI_CTL(RENDER_RING_BASE), - _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE)); - - /* WaDisableSDEUnitClockGating:bdw */ - intel_uncore_rmw(&dev_priv->uncore, GEN8_UCGCTL6, 0, GEN8_SDEUNIT_CLOCK_GATE_DISABLE); - - /* WaProgramL3SqcReg1Default:bdw */ - gen8_set_l3sqc_credits(dev_priv, 30, 2); - - /* WaKVMNotificationOnConfigChange:bdw */ - intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PAR2_1, - 0, KVM_CONFIG_CHANGE_NOTIFICATION_SELECT); - - lpt_init_clock_gating(dev_priv); - - /* WaDisableDopClockGating:bdw - * - * Also see the CHICKEN2 write in bdw_init_workarounds() to disable DOP - * clock gating. - */ - intel_uncore_rmw(&dev_priv->uncore, GEN6_UCGCTL1, 0, GEN6_EU_TCUNIT_CLOCK_GATE_DISABLE); -} - -static void hsw_init_clock_gating(struct drm_i915_private *dev_priv) -{ - /* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */ - intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PIPESL_1(PIPE_A), 0, HSW_FBCQ_DIS); - - /* This is required by WaCatErrorRejectionIssue:hsw */ - intel_uncore_rmw(&dev_priv->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, - 0, GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); - - /* WaSwitchSolVfFArbitrationPriority:hsw */ - intel_uncore_rmw(&dev_priv->uncore, GAM_ECOCHK, 0, HSW_ECOCHK_ARB_PRIO_SOL); - - lpt_init_clock_gating(dev_priv); -} - -static void ivb_init_clock_gating(struct drm_i915_private *dev_priv) -{ - intel_uncore_write(&dev_priv->uncore, ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE); - - /* WaFbcAsynchFlipDisableFbcQueue:ivb */ - intel_uncore_rmw(&dev_priv->uncore, ILK_DISPLAY_CHICKEN1, 0, ILK_FBCQ_DIS); - - /* WaDisableBackToBackFlipFix:ivb */ - intel_uncore_write(&dev_priv->uncore, IVB_CHICKEN3, - CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | - CHICKEN3_DGMG_DONE_FIX_DISABLE); - - if (IS_IVB_GT1(dev_priv)) - intel_uncore_write(&dev_priv->uncore, GEN7_ROW_CHICKEN2, - _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); - else { - /* must write both registers */ - intel_uncore_write(&dev_priv->uncore, GEN7_ROW_CHICKEN2, - _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); - intel_uncore_write(&dev_priv->uncore, GEN7_ROW_CHICKEN2_GT2, - _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); - } - - /* - * According to the spec, bit 13 (RCZUNIT) must be set on IVB. - * This implements the WaDisableRCZUnitClockGating:ivb workaround. - */ - intel_uncore_write(&dev_priv->uncore, GEN6_UCGCTL2, - GEN6_RCZUNIT_CLOCK_GATE_DISABLE); - - /* This is required by WaCatErrorRejectionIssue:ivb */ - intel_uncore_rmw(&dev_priv->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, - 0, GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); - - g4x_disable_trickle_feed(dev_priv); - - intel_uncore_rmw(&dev_priv->uncore, GEN6_MBCUNIT_SNPCR, GEN6_MBC_SNPCR_MASK, - GEN6_MBC_SNPCR_MED); - - if (!HAS_PCH_NOP(dev_priv)) - cpt_init_clock_gating(dev_priv); - - gen6_check_mch_setup(dev_priv); -} - -static void vlv_init_clock_gating(struct drm_i915_private *dev_priv) -{ - /* WaDisableBackToBackFlipFix:vlv */ - intel_uncore_write(&dev_priv->uncore, IVB_CHICKEN3, - CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | - CHICKEN3_DGMG_DONE_FIX_DISABLE); - - /* WaDisableDopClockGating:vlv */ - intel_uncore_write(&dev_priv->uncore, GEN7_ROW_CHICKEN2, - _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); - - /* This is required by WaCatErrorRejectionIssue:vlv */ - intel_uncore_rmw(&dev_priv->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, - 0, GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); - - /* - * According to the spec, bit 13 (RCZUNIT) must be set on IVB. - * This implements the WaDisableRCZUnitClockGating:vlv workaround. - */ - intel_uncore_write(&dev_priv->uncore, GEN6_UCGCTL2, - GEN6_RCZUNIT_CLOCK_GATE_DISABLE); - - /* WaDisableL3Bank2xClockGate:vlv - * Disabling L3 clock gating- MMIO 940c[25] = 1 - * Set bit 25, to disable L3_BANK_2x_CLK_GATING */ - intel_uncore_rmw(&dev_priv->uncore, GEN7_UCGCTL4, 0, GEN7_L3BANK2X_CLOCK_GATE_DISABLE); - - /* - * WaDisableVLVClockGating_VBIIssue:vlv - * Disable clock gating on th GCFG unit to prevent a delay - * in the reporting of vblank events. - */ - intel_uncore_write(&dev_priv->uncore, VLV_GUNIT_CLOCK_GATE, GCFG_DIS); -} - -static void chv_init_clock_gating(struct drm_i915_private *dev_priv) -{ - /* WaVSRefCountFullforceMissDisable:chv */ - /* WaDSRefCountFullforceMissDisable:chv */ - intel_uncore_rmw(&dev_priv->uncore, GEN7_FF_THREAD_MODE, - GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME, 0); - - /* WaDisableSemaphoreAndSyncFlipWait:chv */ - intel_uncore_write(&dev_priv->uncore, RING_PSMI_CTL(RENDER_RING_BASE), - _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE)); - - /* WaDisableCSUnitClockGating:chv */ - intel_uncore_rmw(&dev_priv->uncore, GEN6_UCGCTL1, 0, GEN6_CSUNIT_CLOCK_GATE_DISABLE); - - /* WaDisableSDEUnitClockGating:chv */ - intel_uncore_rmw(&dev_priv->uncore, GEN8_UCGCTL6, 0, GEN8_SDEUNIT_CLOCK_GATE_DISABLE); - - /* - * WaProgramL3SqcReg1Default:chv - * See gfxspecs/Related Documents/Performance Guide/ - * LSQC Setting Recommendations. - */ - gen8_set_l3sqc_credits(dev_priv, 38, 2); -} - -static void g4x_init_clock_gating(struct drm_i915_private *dev_priv) -{ - u32 dspclk_gate; - - intel_uncore_write(&dev_priv->uncore, RENCLK_GATE_D1, 0); - intel_uncore_write(&dev_priv->uncore, RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | - GS_UNIT_CLOCK_GATE_DISABLE | - CL_UNIT_CLOCK_GATE_DISABLE); - intel_uncore_write(&dev_priv->uncore, RAMCLK_GATE_D, 0); - dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE | - OVRUNIT_CLOCK_GATE_DISABLE | - OVCUNIT_CLOCK_GATE_DISABLE; - if (IS_GM45(dev_priv)) - dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE; - intel_uncore_write(&dev_priv->uncore, DSPCLK_GATE_D(dev_priv), dspclk_gate); - - g4x_disable_trickle_feed(dev_priv); -} - -static void i965gm_init_clock_gating(struct drm_i915_private *dev_priv) -{ - struct intel_uncore *uncore = &dev_priv->uncore; - - intel_uncore_write(uncore, RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE); - intel_uncore_write(uncore, RENCLK_GATE_D2, 0); - intel_uncore_write(uncore, DSPCLK_GATE_D(dev_priv), 0); - intel_uncore_write(uncore, RAMCLK_GATE_D, 0); - intel_uncore_write16(uncore, DEUC, 0); - intel_uncore_write(uncore, - MI_ARB_STATE, - _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE)); -} - -static void i965g_init_clock_gating(struct drm_i915_private *dev_priv) -{ - intel_uncore_write(&dev_priv->uncore, RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE | - I965_RCC_CLOCK_GATE_DISABLE | - I965_RCPB_CLOCK_GATE_DISABLE | - I965_ISC_CLOCK_GATE_DISABLE | - I965_FBC_CLOCK_GATE_DISABLE); - intel_uncore_write(&dev_priv->uncore, RENCLK_GATE_D2, 0); - intel_uncore_write(&dev_priv->uncore, MI_ARB_STATE, - _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE)); -} - -static void gen3_init_clock_gating(struct drm_i915_private *dev_priv) -{ - u32 dstate = intel_uncore_read(&dev_priv->uncore, D_STATE); - - dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING | - DSTATE_DOT_CLOCK_GATING; - intel_uncore_write(&dev_priv->uncore, D_STATE, dstate); - - if (IS_PINEVIEW(dev_priv)) - intel_uncore_write(&dev_priv->uncore, ECOSKPD(RENDER_RING_BASE), - _MASKED_BIT_ENABLE(ECO_GATING_CX_ONLY)); - - /* IIR "flip pending" means done if this bit is set */ - intel_uncore_write(&dev_priv->uncore, ECOSKPD(RENDER_RING_BASE), - _MASKED_BIT_DISABLE(ECO_FLIP_DONE)); - - /* interrupts should cause a wake up from C3 */ - intel_uncore_write(&dev_priv->uncore, INSTPM, _MASKED_BIT_ENABLE(INSTPM_AGPBUSY_INT_EN)); - - /* On GEN3 we really need to make sure the ARB C3 LP bit is set */ - intel_uncore_write(&dev_priv->uncore, MI_ARB_STATE, _MASKED_BIT_ENABLE(MI_ARB_C3_LP_WRITE_ENABLE)); - - intel_uncore_write(&dev_priv->uncore, MI_ARB_STATE, - _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE)); -} - -static void i85x_init_clock_gating(struct drm_i915_private *dev_priv) -{ - intel_uncore_write(&dev_priv->uncore, RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE); - - /* interrupts should cause a wake up from C3 */ - intel_uncore_write(&dev_priv->uncore, MI_STATE, _MASKED_BIT_ENABLE(MI_AGPBUSY_INT_EN) | - _MASKED_BIT_DISABLE(MI_AGPBUSY_830_MODE)); - - intel_uncore_write(&dev_priv->uncore, MEM_MODE, - _MASKED_BIT_ENABLE(MEM_DISPLAY_TRICKLE_FEED_DISABLE)); - - /* - * Have FBC ignore 3D activity since we use software - * render tracking, and otherwise a pure 3D workload - * (even if it just renders a single frame and then does - * abosultely nothing) would not allow FBC to recompress - * until a 2D blit occurs. - */ - intel_uncore_write(&dev_priv->uncore, SCPD0, - _MASKED_BIT_ENABLE(SCPD_FBC_IGNORE_3D)); -} - -static void i830_init_clock_gating(struct drm_i915_private *dev_priv) -{ - intel_uncore_write(&dev_priv->uncore, MEM_MODE, - _MASKED_BIT_ENABLE(MEM_DISPLAY_A_TRICKLE_FEED_DISABLE) | - _MASKED_BIT_ENABLE(MEM_DISPLAY_B_TRICKLE_FEED_DISABLE)); -} - -void intel_init_clock_gating(struct drm_i915_private *dev_priv) -{ - dev_priv->clock_gating_funcs->init_clock_gating(dev_priv); -} - -static void nop_init_clock_gating(struct drm_i915_private *dev_priv) -{ - drm_dbg_kms(&dev_priv->drm, - "No clock gating settings or workarounds applied.\n"); -} - -#define CG_FUNCS(platform) \ -static const struct drm_i915_clock_gating_funcs platform##_clock_gating_funcs = { \ - .init_clock_gating = platform##_init_clock_gating, \ -} - -CG_FUNCS(pvc); -CG_FUNCS(dg2); -CG_FUNCS(xehpsdv); -CG_FUNCS(adlp); -CG_FUNCS(gen12lp); -CG_FUNCS(icl); -CG_FUNCS(cfl); -CG_FUNCS(skl); -CG_FUNCS(kbl); -CG_FUNCS(bxt); -CG_FUNCS(glk); -CG_FUNCS(bdw); -CG_FUNCS(chv); -CG_FUNCS(hsw); -CG_FUNCS(ivb); -CG_FUNCS(vlv); -CG_FUNCS(gen6); -CG_FUNCS(ilk); -CG_FUNCS(g4x); -CG_FUNCS(i965gm); -CG_FUNCS(i965g); -CG_FUNCS(gen3); -CG_FUNCS(i85x); -CG_FUNCS(i830); -CG_FUNCS(nop); -#undef CG_FUNCS - -/** - * intel_init_clock_gating_hooks - setup the clock gating hooks - * @dev_priv: device private - * - * Setup the hooks that configure which clocks of a given platform can be - * gated and also apply various GT and display specific workarounds for these - * platforms. Note that some GT specific workarounds are applied separately - * when GPU contexts or batchbuffers start their execution. - */ -void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv) -{ - if (IS_METEORLAKE(dev_priv)) - dev_priv->clock_gating_funcs = &nop_clock_gating_funcs; - else if (IS_PONTEVECCHIO(dev_priv)) - dev_priv->clock_gating_funcs = &pvc_clock_gating_funcs; - else if (IS_DG2(dev_priv)) - dev_priv->clock_gating_funcs = &dg2_clock_gating_funcs; - else if (IS_XEHPSDV(dev_priv)) - dev_priv->clock_gating_funcs = &xehpsdv_clock_gating_funcs; - else if (IS_ALDERLAKE_P(dev_priv)) - dev_priv->clock_gating_funcs = &adlp_clock_gating_funcs; - else if (GRAPHICS_VER(dev_priv) == 12) - dev_priv->clock_gating_funcs = &gen12lp_clock_gating_funcs; - else if (GRAPHICS_VER(dev_priv) == 11) - dev_priv->clock_gating_funcs = &icl_clock_gating_funcs; - else if (IS_COFFEELAKE(dev_priv) || IS_COMETLAKE(dev_priv)) - dev_priv->clock_gating_funcs = &cfl_clock_gating_funcs; - else if (IS_SKYLAKE(dev_priv)) - dev_priv->clock_gating_funcs = &skl_clock_gating_funcs; - else if (IS_KABYLAKE(dev_priv)) - dev_priv->clock_gating_funcs = &kbl_clock_gating_funcs; - else if (IS_BROXTON(dev_priv)) - dev_priv->clock_gating_funcs = &bxt_clock_gating_funcs; - else if (IS_GEMINILAKE(dev_priv)) - dev_priv->clock_gating_funcs = &glk_clock_gating_funcs; - else if (IS_BROADWELL(dev_priv)) - dev_priv->clock_gating_funcs = &bdw_clock_gating_funcs; - else if (IS_CHERRYVIEW(dev_priv)) - dev_priv->clock_gating_funcs = &chv_clock_gating_funcs; - else if (IS_HASWELL(dev_priv)) - dev_priv->clock_gating_funcs = &hsw_clock_gating_funcs; - else if (IS_IVYBRIDGE(dev_priv)) - dev_priv->clock_gating_funcs = &ivb_clock_gating_funcs; - else if (IS_VALLEYVIEW(dev_priv)) - dev_priv->clock_gating_funcs = &vlv_clock_gating_funcs; - else if (GRAPHICS_VER(dev_priv) == 6) - dev_priv->clock_gating_funcs = &gen6_clock_gating_funcs; - else if (GRAPHICS_VER(dev_priv) == 5) - dev_priv->clock_gating_funcs = &ilk_clock_gating_funcs; - else if (IS_G4X(dev_priv)) - dev_priv->clock_gating_funcs = &g4x_clock_gating_funcs; - else if (IS_I965GM(dev_priv)) - dev_priv->clock_gating_funcs = &i965gm_clock_gating_funcs; - else if (IS_I965G(dev_priv)) - dev_priv->clock_gating_funcs = &i965g_clock_gating_funcs; - else if (GRAPHICS_VER(dev_priv) == 3) - dev_priv->clock_gating_funcs = &gen3_clock_gating_funcs; - else if (IS_I85X(dev_priv) || IS_I865G(dev_priv)) - dev_priv->clock_gating_funcs = &i85x_clock_gating_funcs; - else if (GRAPHICS_VER(dev_priv) == 2) - dev_priv->clock_gating_funcs = &i830_clock_gating_funcs; - else { - MISSING_CASE(INTEL_DEVID(dev_priv)); - dev_priv->clock_gating_funcs = &nop_clock_gating_funcs; - } -} diff --git a/drivers/gpu/drm/i915/intel_pm.h b/drivers/gpu/drm/i915/intel_pm.h deleted file mode 100644 index f774bddcdca6..000000000000 --- a/drivers/gpu/drm/i915/intel_pm.h +++ /dev/null @@ -1,18 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2019 Intel Corporation - */ - -#ifndef __INTEL_PM_H__ -#define __INTEL_PM_H__ - -#include - -struct drm_i915_private; -struct intel_crtc_state; -struct intel_plane_state; - -void intel_init_clock_gating(struct drm_i915_private *dev_priv); -void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv); - -#endif /* __INTEL_PM_H__ */ diff --git a/drivers/gpu/drm/i915/vlv_suspend.c b/drivers/gpu/drm/i915/vlv_suspend.c index 02e63ed77f60..94595dde2b96 100644 --- a/drivers/gpu/drm/i915/vlv_suspend.c +++ b/drivers/gpu/drm/i915/vlv_suspend.c @@ -12,7 +12,7 @@ #include "i915_reg.h" #include "i915_trace.h" #include "i915_utils.h" -#include "intel_pm.h" +#include "intel_clock_gating.h" #include "vlv_suspend.h" #include "gt/intel_gt_regs.h" @@ -451,7 +451,7 @@ int vlv_resume_prepare(struct drm_i915_private *dev_priv, bool rpm_resume) vlv_check_no_gt_access(dev_priv); if (rpm_resume) - intel_init_clock_gating(dev_priv); + intel_clock_gating_init(dev_priv); return ret; } -- cgit v1.2.3-59-g8ed1b From 1d1e434dbe58ef31abc60135957e0735b62fdcad Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 3 Apr 2023 15:24:28 +0300 Subject: drm/i915/clock: mass rename dev_priv to i915 Follow the contemporary naming style. Include some indentation fixes while at it on the affected statements. One function needs to keep using dev_priv due to implicit dev_priv usage in a macro. Reviewed-by: Rodrigo Vivi Signed-off-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20230403122428.3526263-2-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_clock_gating.c | 589 +++++++++++++++--------------- 1 file changed, 296 insertions(+), 293 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_clock_gating.c b/drivers/gpu/drm/i915/intel_clock_gating.c index 8cfc19b48760..2c5302bcba19 100644 --- a/drivers/gpu/drm/i915/intel_clock_gating.c +++ b/drivers/gpu/drm/i915/intel_clock_gating.c @@ -44,9 +44,9 @@ struct drm_i915_clock_gating_funcs { void (*init_clock_gating)(struct drm_i915_private *i915); }; -static void gen9_init_clock_gating(struct drm_i915_private *dev_priv) +static void gen9_init_clock_gating(struct drm_i915_private *i915) { - if (HAS_LLC(dev_priv)) { + if (HAS_LLC(i915)) { /* * WaCompressedResourceDisplayNewHashMode:skl,kbl * Display WA #0390: skl,kbl @@ -54,41 +54,42 @@ static void gen9_init_clock_gating(struct drm_i915_private *dev_priv) * Must match Sampler, Pixel Back End, and Media. See * WaCompressedResourceSamplerPbeMediaNewHashMode. */ - intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PAR1_1, 0, SKL_DE_COMPRESSED_HASH_MODE); + intel_uncore_rmw(&i915->uncore, CHICKEN_PAR1_1, 0, SKL_DE_COMPRESSED_HASH_MODE); } /* See Bspec note for PSR2_CTL bit 31, Wa#828:skl,bxt,kbl,cfl */ - intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PAR1_1, 0, SKL_EDP_PSR_FIX_RDWRAP); + intel_uncore_rmw(&i915->uncore, CHICKEN_PAR1_1, 0, SKL_EDP_PSR_FIX_RDWRAP); /* WaEnableChickenDCPR:skl,bxt,kbl,glk,cfl */ - intel_uncore_rmw(&dev_priv->uncore, GEN8_CHICKEN_DCPR_1, 0, MASK_WAKEMEM); + intel_uncore_rmw(&i915->uncore, GEN8_CHICKEN_DCPR_1, 0, MASK_WAKEMEM); /* * WaFbcWakeMemOn:skl,bxt,kbl,glk,cfl * Display WA #0859: skl,bxt,kbl,glk,cfl */ - intel_uncore_rmw(&dev_priv->uncore, DISP_ARB_CTL, 0, DISP_FBC_MEMORY_WAKE); + intel_uncore_rmw(&i915->uncore, DISP_ARB_CTL, 0, DISP_FBC_MEMORY_WAKE); } -static void bxt_init_clock_gating(struct drm_i915_private *dev_priv) +static void bxt_init_clock_gating(struct drm_i915_private *i915) { - gen9_init_clock_gating(dev_priv); + gen9_init_clock_gating(i915); /* WaDisableSDEUnitClockGating:bxt */ - intel_uncore_rmw(&dev_priv->uncore, GEN8_UCGCTL6, 0, GEN8_SDEUNIT_CLOCK_GATE_DISABLE); + intel_uncore_rmw(&i915->uncore, GEN8_UCGCTL6, 0, GEN8_SDEUNIT_CLOCK_GATE_DISABLE); /* * FIXME: * GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ applies on 3x6 GT SKUs only. */ - intel_uncore_rmw(&dev_priv->uncore, GEN8_UCGCTL6, 0, GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ); + intel_uncore_rmw(&i915->uncore, GEN8_UCGCTL6, 0, GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ); /* * Wa: Backlight PWM may stop in the asserted state, causing backlight * to stay fully on. */ - intel_uncore_write(&dev_priv->uncore, GEN9_CLKGATE_DIS_0, intel_uncore_read(&dev_priv->uncore, GEN9_CLKGATE_DIS_0) | - PWM1_GATING_DIS | PWM2_GATING_DIS); + intel_uncore_write(&i915->uncore, GEN9_CLKGATE_DIS_0, + intel_uncore_read(&i915->uncore, GEN9_CLKGATE_DIS_0) | + PWM1_GATING_DIS | PWM2_GATING_DIS); /* * Lower the display internal timeout. @@ -96,42 +97,43 @@ static void bxt_init_clock_gating(struct drm_i915_private *dev_priv) * is off and a MMIO access is attempted by any privilege * application, using batch buffers or any other means. */ - intel_uncore_write(&dev_priv->uncore, RM_TIMEOUT, MMIO_TIMEOUT_US(950)); + intel_uncore_write(&i915->uncore, RM_TIMEOUT, MMIO_TIMEOUT_US(950)); /* * WaFbcTurnOffFbcWatermark:bxt * Display WA #0562: bxt */ - intel_uncore_rmw(&dev_priv->uncore, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS); + intel_uncore_rmw(&i915->uncore, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS); /* * WaFbcHighMemBwCorruptionAvoidance:bxt * Display WA #0883: bxt */ - intel_uncore_rmw(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), 0, DPFC_DISABLE_DUMMY0); + intel_uncore_rmw(&i915->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), 0, DPFC_DISABLE_DUMMY0); } -static void glk_init_clock_gating(struct drm_i915_private *dev_priv) +static void glk_init_clock_gating(struct drm_i915_private *i915) { - gen9_init_clock_gating(dev_priv); + gen9_init_clock_gating(i915); /* * WaDisablePWMClockGating:glk * Backlight PWM may stop in the asserted state, causing backlight * to stay fully on. */ - intel_uncore_write(&dev_priv->uncore, GEN9_CLKGATE_DIS_0, intel_uncore_read(&dev_priv->uncore, GEN9_CLKGATE_DIS_0) | - PWM1_GATING_DIS | PWM2_GATING_DIS); + intel_uncore_write(&i915->uncore, GEN9_CLKGATE_DIS_0, + intel_uncore_read(&i915->uncore, GEN9_CLKGATE_DIS_0) | + PWM1_GATING_DIS | PWM2_GATING_DIS); } -static void ibx_init_clock_gating(struct drm_i915_private *dev_priv) +static void ibx_init_clock_gating(struct drm_i915_private *i915) { /* * On Ibex Peak and Cougar Point, we need to disable clock * gating for the panel power sequencer or it will fail to * start up when no ports are active. */ - intel_uncore_write(&dev_priv->uncore, SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE); + intel_uncore_write(&i915->uncore, SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE); } static void g4x_disable_trickle_feed(struct drm_i915_private *dev_priv) @@ -146,7 +148,7 @@ static void g4x_disable_trickle_feed(struct drm_i915_private *dev_priv) } } -static void ilk_init_clock_gating(struct drm_i915_private *dev_priv) +static void ilk_init_clock_gating(struct drm_i915_private *i915) { u32 dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE; @@ -158,11 +160,11 @@ static void ilk_init_clock_gating(struct drm_i915_private *dev_priv) ILK_DPFCUNIT_CLOCK_GATE_DISABLE | ILK_DPFDUNIT_CLOCK_GATE_ENABLE; - intel_uncore_write(&dev_priv->uncore, PCH_3DCGDIS0, - MARIUNIT_CLOCK_GATE_DISABLE | - SVSMUNIT_CLOCK_GATE_DISABLE); - intel_uncore_write(&dev_priv->uncore, PCH_3DCGDIS1, - VFMUNIT_CLOCK_GATE_DISABLE); + intel_uncore_write(&i915->uncore, PCH_3DCGDIS0, + MARIUNIT_CLOCK_GATE_DISABLE | + SVSMUNIT_CLOCK_GATE_DISABLE); + intel_uncore_write(&i915->uncore, PCH_3DCGDIS1, + VFMUNIT_CLOCK_GATE_DISABLE); /* * According to the spec the following bits should be set in @@ -171,13 +173,13 @@ static void ilk_init_clock_gating(struct drm_i915_private *dev_priv) * The bit 5 of 0x42020 * The bit 15 of 0x45000 */ - intel_uncore_write(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2, - (intel_uncore_read(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2) | - ILK_DPARB_GATE | ILK_VSDPFD_FULL)); + intel_uncore_write(&i915->uncore, ILK_DISPLAY_CHICKEN2, + (intel_uncore_read(&i915->uncore, ILK_DISPLAY_CHICKEN2) | + ILK_DPARB_GATE | ILK_VSDPFD_FULL)); dspclk_gate |= ILK_DPARBUNIT_CLOCK_GATE_ENABLE; - intel_uncore_write(&dev_priv->uncore, DISP_ARB_CTL, - (intel_uncore_read(&dev_priv->uncore, DISP_ARB_CTL) | - DISP_FBC_WM_DIS)); + intel_uncore_write(&i915->uncore, DISP_ARB_CTL, + (intel_uncore_read(&i915->uncore, DISP_ARB_CTL) | + DISP_FBC_WM_DIS)); /* * Based on the document from hardware guys the following bits @@ -186,22 +188,22 @@ static void ilk_init_clock_gating(struct drm_i915_private *dev_priv) * The bit 22 of 0x42004 * The bit 7,8,9 of 0x42020. */ - if (IS_IRONLAKE_M(dev_priv)) { + if (IS_IRONLAKE_M(i915)) { /* WaFbcAsynchFlipDisableFbcQueue:ilk */ - intel_uncore_rmw(&dev_priv->uncore, ILK_DISPLAY_CHICKEN1, 0, ILK_FBCQ_DIS); - intel_uncore_rmw(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2, 0, ILK_DPARB_GATE); + intel_uncore_rmw(&i915->uncore, ILK_DISPLAY_CHICKEN1, 0, ILK_FBCQ_DIS); + intel_uncore_rmw(&i915->uncore, ILK_DISPLAY_CHICKEN2, 0, ILK_DPARB_GATE); } - intel_uncore_write(&dev_priv->uncore, ILK_DSPCLK_GATE_D, dspclk_gate); + intel_uncore_write(&i915->uncore, ILK_DSPCLK_GATE_D, dspclk_gate); - intel_uncore_rmw(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2, 0, ILK_ELPIN_409_SELECT); + intel_uncore_rmw(&i915->uncore, ILK_DISPLAY_CHICKEN2, 0, ILK_ELPIN_409_SELECT); - g4x_disable_trickle_feed(dev_priv); + g4x_disable_trickle_feed(i915); - ibx_init_clock_gating(dev_priv); + ibx_init_clock_gating(i915); } -static void cpt_init_clock_gating(struct drm_i915_private *dev_priv) +static void cpt_init_clock_gating(struct drm_i915_private *i915) { enum pipe pipe; u32 val; @@ -211,53 +213,53 @@ static void cpt_init_clock_gating(struct drm_i915_private *dev_priv) * gating for the panel power sequencer or it will fail to * start up when no ports are active. */ - intel_uncore_write(&dev_priv->uncore, SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE | - PCH_DPLUNIT_CLOCK_GATE_DISABLE | - PCH_CPUNIT_CLOCK_GATE_DISABLE); - intel_uncore_rmw(&dev_priv->uncore, SOUTH_CHICKEN2, 0, DPLS_EDP_PPS_FIX_DIS); + intel_uncore_write(&i915->uncore, SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE | + PCH_DPLUNIT_CLOCK_GATE_DISABLE | + PCH_CPUNIT_CLOCK_GATE_DISABLE); + intel_uncore_rmw(&i915->uncore, SOUTH_CHICKEN2, 0, DPLS_EDP_PPS_FIX_DIS); /* The below fixes the weird display corruption, a few pixels shifted * downward, on (only) LVDS of some HP laptops with IVY. */ - for_each_pipe(dev_priv, pipe) { - val = intel_uncore_read(&dev_priv->uncore, TRANS_CHICKEN2(pipe)); + for_each_pipe(i915, pipe) { + val = intel_uncore_read(&i915->uncore, TRANS_CHICKEN2(pipe)); val |= TRANS_CHICKEN2_TIMING_OVERRIDE; val &= ~TRANS_CHICKEN2_FDI_POLARITY_REVERSED; - if (dev_priv->display.vbt.fdi_rx_polarity_inverted) + if (i915->display.vbt.fdi_rx_polarity_inverted) val |= TRANS_CHICKEN2_FDI_POLARITY_REVERSED; val &= ~TRANS_CHICKEN2_DISABLE_DEEP_COLOR_COUNTER; val &= ~TRANS_CHICKEN2_DISABLE_DEEP_COLOR_MODESWITCH; - intel_uncore_write(&dev_priv->uncore, TRANS_CHICKEN2(pipe), val); + intel_uncore_write(&i915->uncore, TRANS_CHICKEN2(pipe), val); } /* WADP0ClockGatingDisable */ - for_each_pipe(dev_priv, pipe) { - intel_uncore_write(&dev_priv->uncore, TRANS_CHICKEN1(pipe), - TRANS_CHICKEN1_DP0UNIT_GC_DISABLE); + for_each_pipe(i915, pipe) { + intel_uncore_write(&i915->uncore, TRANS_CHICKEN1(pipe), + TRANS_CHICKEN1_DP0UNIT_GC_DISABLE); } } -static void gen6_check_mch_setup(struct drm_i915_private *dev_priv) +static void gen6_check_mch_setup(struct drm_i915_private *i915) { u32 tmp; - tmp = intel_uncore_read(&dev_priv->uncore, MCH_SSKPD); + tmp = intel_uncore_read(&i915->uncore, MCH_SSKPD); if (REG_FIELD_GET(SSKPD_WM0_MASK_SNB, tmp) != 12) - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(&i915->drm, "Wrong MCH_SSKPD value: 0x%08x This can cause underruns.\n", tmp); } -static void gen6_init_clock_gating(struct drm_i915_private *dev_priv) +static void gen6_init_clock_gating(struct drm_i915_private *i915) { u32 dspclk_gate = ILK_VRHUNIT_CLOCK_GATE_DISABLE; - intel_uncore_write(&dev_priv->uncore, ILK_DSPCLK_GATE_D, dspclk_gate); + intel_uncore_write(&i915->uncore, ILK_DSPCLK_GATE_D, dspclk_gate); - intel_uncore_rmw(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2, 0, ILK_ELPIN_409_SELECT); + intel_uncore_rmw(&i915->uncore, ILK_DISPLAY_CHICKEN2, 0, ILK_ELPIN_409_SELECT); - intel_uncore_write(&dev_priv->uncore, GEN6_UCGCTL1, - intel_uncore_read(&dev_priv->uncore, GEN6_UCGCTL1) | - GEN6_BLBUNIT_CLOCK_GATE_DISABLE | - GEN6_CSUNIT_CLOCK_GATE_DISABLE); + intel_uncore_write(&i915->uncore, GEN6_UCGCTL1, + intel_uncore_read(&i915->uncore, GEN6_UCGCTL1) | + GEN6_BLBUNIT_CLOCK_GATE_DISABLE | + GEN6_CSUNIT_CLOCK_GATE_DISABLE); /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock * gating disable must be set. Failure to set it results in @@ -272,9 +274,9 @@ static void gen6_init_clock_gating(struct drm_i915_private *dev_priv) * WaDisableRCCUnitClockGating:snb * WaDisableRCPBUnitClockGating:snb */ - intel_uncore_write(&dev_priv->uncore, GEN6_UCGCTL2, - GEN6_RCPBUNIT_CLOCK_GATE_DISABLE | - GEN6_RCCUNIT_CLOCK_GATE_DISABLE); + intel_uncore_write(&i915->uncore, GEN6_UCGCTL2, + GEN6_RCPBUNIT_CLOCK_GATE_DISABLE | + GEN6_RCCUNIT_CLOCK_GATE_DISABLE); /* * According to the spec the following bits should be @@ -287,40 +289,40 @@ static void gen6_init_clock_gating(struct drm_i915_private *dev_priv) * * WaFbcAsynchFlipDisableFbcQueue:snb */ - intel_uncore_write(&dev_priv->uncore, ILK_DISPLAY_CHICKEN1, - intel_uncore_read(&dev_priv->uncore, ILK_DISPLAY_CHICKEN1) | - ILK_FBCQ_DIS | ILK_PABSTRETCH_DIS); - intel_uncore_write(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2, - intel_uncore_read(&dev_priv->uncore, ILK_DISPLAY_CHICKEN2) | - ILK_DPARB_GATE | ILK_VSDPFD_FULL); - intel_uncore_write(&dev_priv->uncore, ILK_DSPCLK_GATE_D, - intel_uncore_read(&dev_priv->uncore, ILK_DSPCLK_GATE_D) | - ILK_DPARBUNIT_CLOCK_GATE_ENABLE | - ILK_DPFDUNIT_CLOCK_GATE_ENABLE); + intel_uncore_write(&i915->uncore, ILK_DISPLAY_CHICKEN1, + intel_uncore_read(&i915->uncore, ILK_DISPLAY_CHICKEN1) | + ILK_FBCQ_DIS | ILK_PABSTRETCH_DIS); + intel_uncore_write(&i915->uncore, ILK_DISPLAY_CHICKEN2, + intel_uncore_read(&i915->uncore, ILK_DISPLAY_CHICKEN2) | + ILK_DPARB_GATE | ILK_VSDPFD_FULL); + intel_uncore_write(&i915->uncore, ILK_DSPCLK_GATE_D, + intel_uncore_read(&i915->uncore, ILK_DSPCLK_GATE_D) | + ILK_DPARBUNIT_CLOCK_GATE_ENABLE | + ILK_DPFDUNIT_CLOCK_GATE_ENABLE); - g4x_disable_trickle_feed(dev_priv); + g4x_disable_trickle_feed(i915); - cpt_init_clock_gating(dev_priv); + cpt_init_clock_gating(i915); - gen6_check_mch_setup(dev_priv); + gen6_check_mch_setup(i915); } -static void lpt_init_clock_gating(struct drm_i915_private *dev_priv) +static void lpt_init_clock_gating(struct drm_i915_private *i915) { /* * TODO: this bit should only be enabled when really needed, then * disabled when not needed anymore in order to save power. */ - if (HAS_PCH_LPT_LP(dev_priv)) - intel_uncore_rmw(&dev_priv->uncore, SOUTH_DSPCLK_GATE_D, + if (HAS_PCH_LPT_LP(i915)) + intel_uncore_rmw(&i915->uncore, SOUTH_DSPCLK_GATE_D, 0, PCH_LP_PARTITION_LEVEL_DISABLE); /* WADPOClockGatingDisable:hsw */ - intel_uncore_rmw(&dev_priv->uncore, TRANS_CHICKEN1(PIPE_A), + intel_uncore_rmw(&i915->uncore, TRANS_CHICKEN1(PIPE_A), 0, TRANS_CHICKEN1_DP0UNIT_GC_DISABLE); } -static void gen8_set_l3sqc_credits(struct drm_i915_private *dev_priv, +static void gen8_set_l3sqc_credits(struct drm_i915_private *i915, int general_prio_credits, int high_prio_credits) { @@ -328,64 +330,64 @@ static void gen8_set_l3sqc_credits(struct drm_i915_private *dev_priv, u32 val; /* WaTempDisableDOPClkGating:bdw */ - misccpctl = intel_uncore_rmw(&dev_priv->uncore, GEN7_MISCCPCTL, + misccpctl = intel_uncore_rmw(&i915->uncore, GEN7_MISCCPCTL, GEN7_DOP_CLOCK_GATE_ENABLE, 0); - val = intel_gt_mcr_read_any(to_gt(dev_priv), GEN8_L3SQCREG1); + val = intel_gt_mcr_read_any(to_gt(i915), GEN8_L3SQCREG1); val &= ~L3_PRIO_CREDITS_MASK; val |= L3_GENERAL_PRIO_CREDITS(general_prio_credits); val |= L3_HIGH_PRIO_CREDITS(high_prio_credits); - intel_gt_mcr_multicast_write(to_gt(dev_priv), GEN8_L3SQCREG1, val); + intel_gt_mcr_multicast_write(to_gt(i915), GEN8_L3SQCREG1, val); /* * Wait at least 100 clocks before re-enabling clock gating. * See the definition of L3SQCREG1 in BSpec. */ - intel_gt_mcr_read_any(to_gt(dev_priv), GEN8_L3SQCREG1); + intel_gt_mcr_read_any(to_gt(i915), GEN8_L3SQCREG1); udelay(1); - intel_uncore_write(&dev_priv->uncore, GEN7_MISCCPCTL, misccpctl); + intel_uncore_write(&i915->uncore, GEN7_MISCCPCTL, misccpctl); } -static void icl_init_clock_gating(struct drm_i915_private *dev_priv) +static void icl_init_clock_gating(struct drm_i915_private *i915) { /* Wa_1409120013:icl,ehl */ - intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), + intel_uncore_write(&i915->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), DPFC_CHICKEN_COMP_DUMMY_PIXEL); /*Wa_14010594013:icl, ehl */ - intel_uncore_rmw(&dev_priv->uncore, GEN8_CHICKEN_DCPR_1, + intel_uncore_rmw(&i915->uncore, GEN8_CHICKEN_DCPR_1, 0, ICL_DELAY_PMRSP); } -static void gen12lp_init_clock_gating(struct drm_i915_private *dev_priv) +static void gen12lp_init_clock_gating(struct drm_i915_private *i915) { /* Wa_1409120013 */ - if (DISPLAY_VER(dev_priv) == 12) - intel_uncore_write(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), + if (DISPLAY_VER(i915) == 12) + intel_uncore_write(&i915->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), DPFC_CHICKEN_COMP_DUMMY_PIXEL); /* Wa_14013723622:tgl,rkl,dg1,adl-s */ - if (DISPLAY_VER(dev_priv) == 12) - intel_uncore_rmw(&dev_priv->uncore, CLKREQ_POLICY, + if (DISPLAY_VER(i915) == 12) + intel_uncore_rmw(&i915->uncore, CLKREQ_POLICY, CLKREQ_POLICY_MEM_UP_OVRD, 0); } -static void adlp_init_clock_gating(struct drm_i915_private *dev_priv) +static void adlp_init_clock_gating(struct drm_i915_private *i915) { - gen12lp_init_clock_gating(dev_priv); + gen12lp_init_clock_gating(i915); /* Wa_22011091694:adlp */ - intel_de_rmw(dev_priv, GEN9_CLKGATE_DIS_5, 0, DPCE_GATING_DIS); + intel_de_rmw(i915, GEN9_CLKGATE_DIS_5, 0, DPCE_GATING_DIS); /* Bspec/49189 Initialize Sequence */ - intel_de_rmw(dev_priv, GEN8_CHICKEN_DCPR_1, DDI_CLOCK_REG_ACCESS, 0); + intel_de_rmw(i915, GEN8_CHICKEN_DCPR_1, DDI_CLOCK_REG_ACCESS, 0); } -static void xehpsdv_init_clock_gating(struct drm_i915_private *dev_priv) +static void xehpsdv_init_clock_gating(struct drm_i915_private *i915) { /* Wa_22010146351:xehpsdv */ - if (IS_XEHPSDV_GRAPHICS_STEP(dev_priv, STEP_A0, STEP_B0)) - intel_uncore_rmw(&dev_priv->uncore, XEHP_CLOCK_GATE_DIS, 0, SGR_DIS); + if (IS_XEHPSDV_GRAPHICS_STEP(i915, STEP_A0, STEP_B0)) + intel_uncore_rmw(&i915->uncore, XEHP_CLOCK_GATE_DIS, 0, SGR_DIS); } static void dg2_init_clock_gating(struct drm_i915_private *i915) @@ -403,303 +405,303 @@ static void dg2_init_clock_gating(struct drm_i915_private *i915) SGR_DIS | SGGI_DIS); } -static void pvc_init_clock_gating(struct drm_i915_private *dev_priv) +static void pvc_init_clock_gating(struct drm_i915_private *i915) { /* Wa_14012385139:pvc */ - if (IS_PVC_BD_STEP(dev_priv, STEP_A0, STEP_B0)) - intel_uncore_rmw(&dev_priv->uncore, XEHP_CLOCK_GATE_DIS, 0, SGR_DIS); + if (IS_PVC_BD_STEP(i915, STEP_A0, STEP_B0)) + intel_uncore_rmw(&i915->uncore, XEHP_CLOCK_GATE_DIS, 0, SGR_DIS); /* Wa_22010954014:pvc */ - if (IS_PVC_BD_STEP(dev_priv, STEP_A0, STEP_B0)) - intel_uncore_rmw(&dev_priv->uncore, XEHP_CLOCK_GATE_DIS, 0, SGSI_SIDECLK_DIS); + if (IS_PVC_BD_STEP(i915, STEP_A0, STEP_B0)) + intel_uncore_rmw(&i915->uncore, XEHP_CLOCK_GATE_DIS, 0, SGSI_SIDECLK_DIS); } -static void cnp_init_clock_gating(struct drm_i915_private *dev_priv) +static void cnp_init_clock_gating(struct drm_i915_private *i915) { - if (!HAS_PCH_CNP(dev_priv)) + if (!HAS_PCH_CNP(i915)) return; /* Display WA #1181 WaSouthDisplayDisablePWMCGEGating: cnp */ - intel_uncore_rmw(&dev_priv->uncore, SOUTH_DSPCLK_GATE_D, 0, CNP_PWM_CGE_GATING_DISABLE); + intel_uncore_rmw(&i915->uncore, SOUTH_DSPCLK_GATE_D, 0, CNP_PWM_CGE_GATING_DISABLE); } -static void cfl_init_clock_gating(struct drm_i915_private *dev_priv) +static void cfl_init_clock_gating(struct drm_i915_private *i915) { - cnp_init_clock_gating(dev_priv); - gen9_init_clock_gating(dev_priv); + cnp_init_clock_gating(i915); + gen9_init_clock_gating(i915); /* WAC6entrylatency:cfl */ - intel_uncore_rmw(&dev_priv->uncore, FBC_LLC_READ_CTRL, 0, FBC_LLC_FULLY_OPEN); + intel_uncore_rmw(&i915->uncore, FBC_LLC_READ_CTRL, 0, FBC_LLC_FULLY_OPEN); /* * WaFbcTurnOffFbcWatermark:cfl * Display WA #0562: cfl */ - intel_uncore_rmw(&dev_priv->uncore, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS); + intel_uncore_rmw(&i915->uncore, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS); /* * WaFbcNukeOnHostModify:cfl * Display WA #0873: cfl */ - intel_uncore_rmw(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), + intel_uncore_rmw(&i915->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), 0, DPFC_NUKE_ON_ANY_MODIFICATION); } -static void kbl_init_clock_gating(struct drm_i915_private *dev_priv) +static void kbl_init_clock_gating(struct drm_i915_private *i915) { - gen9_init_clock_gating(dev_priv); + gen9_init_clock_gating(i915); /* WAC6entrylatency:kbl */ - intel_uncore_rmw(&dev_priv->uncore, FBC_LLC_READ_CTRL, 0, FBC_LLC_FULLY_OPEN); + intel_uncore_rmw(&i915->uncore, FBC_LLC_READ_CTRL, 0, FBC_LLC_FULLY_OPEN); /* WaDisableSDEUnitClockGating:kbl */ - if (IS_KBL_GRAPHICS_STEP(dev_priv, 0, STEP_C0)) - intel_uncore_rmw(&dev_priv->uncore, GEN8_UCGCTL6, + if (IS_KBL_GRAPHICS_STEP(i915, 0, STEP_C0)) + intel_uncore_rmw(&i915->uncore, GEN8_UCGCTL6, 0, GEN8_SDEUNIT_CLOCK_GATE_DISABLE); /* WaDisableGamClockGating:kbl */ - if (IS_KBL_GRAPHICS_STEP(dev_priv, 0, STEP_C0)) - intel_uncore_rmw(&dev_priv->uncore, GEN6_UCGCTL1, + if (IS_KBL_GRAPHICS_STEP(i915, 0, STEP_C0)) + intel_uncore_rmw(&i915->uncore, GEN6_UCGCTL1, 0, GEN6_GAMUNIT_CLOCK_GATE_DISABLE); /* * WaFbcTurnOffFbcWatermark:kbl * Display WA #0562: kbl */ - intel_uncore_rmw(&dev_priv->uncore, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS); + intel_uncore_rmw(&i915->uncore, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS); /* * WaFbcNukeOnHostModify:kbl * Display WA #0873: kbl */ - intel_uncore_rmw(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), + intel_uncore_rmw(&i915->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), 0, DPFC_NUKE_ON_ANY_MODIFICATION); } -static void skl_init_clock_gating(struct drm_i915_private *dev_priv) +static void skl_init_clock_gating(struct drm_i915_private *i915) { - gen9_init_clock_gating(dev_priv); + gen9_init_clock_gating(i915); /* WaDisableDopClockGating:skl */ - intel_uncore_rmw(&dev_priv->uncore, GEN7_MISCCPCTL, + intel_uncore_rmw(&i915->uncore, GEN7_MISCCPCTL, GEN7_DOP_CLOCK_GATE_ENABLE, 0); /* WAC6entrylatency:skl */ - intel_uncore_rmw(&dev_priv->uncore, FBC_LLC_READ_CTRL, 0, FBC_LLC_FULLY_OPEN); + intel_uncore_rmw(&i915->uncore, FBC_LLC_READ_CTRL, 0, FBC_LLC_FULLY_OPEN); /* * WaFbcTurnOffFbcWatermark:skl * Display WA #0562: skl */ - intel_uncore_rmw(&dev_priv->uncore, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS); + intel_uncore_rmw(&i915->uncore, DISP_ARB_CTL, 0, DISP_FBC_WM_DIS); /* * WaFbcNukeOnHostModify:skl * Display WA #0873: skl */ - intel_uncore_rmw(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), + intel_uncore_rmw(&i915->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), 0, DPFC_NUKE_ON_ANY_MODIFICATION); /* * WaFbcHighMemBwCorruptionAvoidance:skl * Display WA #0883: skl */ - intel_uncore_rmw(&dev_priv->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), 0, DPFC_DISABLE_DUMMY0); + intel_uncore_rmw(&i915->uncore, ILK_DPFC_CHICKEN(INTEL_FBC_A), 0, DPFC_DISABLE_DUMMY0); } -static void bdw_init_clock_gating(struct drm_i915_private *dev_priv) +static void bdw_init_clock_gating(struct drm_i915_private *i915) { enum pipe pipe; /* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */ - intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PIPESL_1(PIPE_A), 0, HSW_FBCQ_DIS); + intel_uncore_rmw(&i915->uncore, CHICKEN_PIPESL_1(PIPE_A), 0, HSW_FBCQ_DIS); /* WaSwitchSolVfFArbitrationPriority:bdw */ - intel_uncore_rmw(&dev_priv->uncore, GAM_ECOCHK, 0, HSW_ECOCHK_ARB_PRIO_SOL); + intel_uncore_rmw(&i915->uncore, GAM_ECOCHK, 0, HSW_ECOCHK_ARB_PRIO_SOL); /* WaPsrDPAMaskVBlankInSRD:bdw */ - intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PAR1_1, 0, DPA_MASK_VBLANK_SRD); + intel_uncore_rmw(&i915->uncore, CHICKEN_PAR1_1, 0, DPA_MASK_VBLANK_SRD); - for_each_pipe(dev_priv, pipe) { + for_each_pipe(i915, pipe) { /* WaPsrDPRSUnmaskVBlankInSRD:bdw */ - intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PIPESL_1(pipe), + intel_uncore_rmw(&i915->uncore, CHICKEN_PIPESL_1(pipe), 0, BDW_DPRS_MASK_VBLANK_SRD); } /* WaVSRefCountFullforceMissDisable:bdw */ /* WaDSRefCountFullforceMissDisable:bdw */ - intel_uncore_rmw(&dev_priv->uncore, GEN7_FF_THREAD_MODE, + intel_uncore_rmw(&i915->uncore, GEN7_FF_THREAD_MODE, GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME, 0); - intel_uncore_write(&dev_priv->uncore, RING_PSMI_CTL(RENDER_RING_BASE), - _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE)); + intel_uncore_write(&i915->uncore, RING_PSMI_CTL(RENDER_RING_BASE), + _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE)); /* WaDisableSDEUnitClockGating:bdw */ - intel_uncore_rmw(&dev_priv->uncore, GEN8_UCGCTL6, 0, GEN8_SDEUNIT_CLOCK_GATE_DISABLE); + intel_uncore_rmw(&i915->uncore, GEN8_UCGCTL6, 0, GEN8_SDEUNIT_CLOCK_GATE_DISABLE); /* WaProgramL3SqcReg1Default:bdw */ - gen8_set_l3sqc_credits(dev_priv, 30, 2); + gen8_set_l3sqc_credits(i915, 30, 2); /* WaKVMNotificationOnConfigChange:bdw */ - intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PAR2_1, + intel_uncore_rmw(&i915->uncore, CHICKEN_PAR2_1, 0, KVM_CONFIG_CHANGE_NOTIFICATION_SELECT); - lpt_init_clock_gating(dev_priv); + lpt_init_clock_gating(i915); /* WaDisableDopClockGating:bdw * * Also see the CHICKEN2 write in bdw_init_workarounds() to disable DOP * clock gating. */ - intel_uncore_rmw(&dev_priv->uncore, GEN6_UCGCTL1, 0, GEN6_EU_TCUNIT_CLOCK_GATE_DISABLE); + intel_uncore_rmw(&i915->uncore, GEN6_UCGCTL1, 0, GEN6_EU_TCUNIT_CLOCK_GATE_DISABLE); } -static void hsw_init_clock_gating(struct drm_i915_private *dev_priv) +static void hsw_init_clock_gating(struct drm_i915_private *i915) { /* WaFbcAsynchFlipDisableFbcQueue:hsw,bdw */ - intel_uncore_rmw(&dev_priv->uncore, CHICKEN_PIPESL_1(PIPE_A), 0, HSW_FBCQ_DIS); + intel_uncore_rmw(&i915->uncore, CHICKEN_PIPESL_1(PIPE_A), 0, HSW_FBCQ_DIS); /* This is required by WaCatErrorRejectionIssue:hsw */ - intel_uncore_rmw(&dev_priv->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, + intel_uncore_rmw(&i915->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, 0, GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); /* WaSwitchSolVfFArbitrationPriority:hsw */ - intel_uncore_rmw(&dev_priv->uncore, GAM_ECOCHK, 0, HSW_ECOCHK_ARB_PRIO_SOL); + intel_uncore_rmw(&i915->uncore, GAM_ECOCHK, 0, HSW_ECOCHK_ARB_PRIO_SOL); - lpt_init_clock_gating(dev_priv); + lpt_init_clock_gating(i915); } -static void ivb_init_clock_gating(struct drm_i915_private *dev_priv) +static void ivb_init_clock_gating(struct drm_i915_private *i915) { - intel_uncore_write(&dev_priv->uncore, ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE); + intel_uncore_write(&i915->uncore, ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE); /* WaFbcAsynchFlipDisableFbcQueue:ivb */ - intel_uncore_rmw(&dev_priv->uncore, ILK_DISPLAY_CHICKEN1, 0, ILK_FBCQ_DIS); + intel_uncore_rmw(&i915->uncore, ILK_DISPLAY_CHICKEN1, 0, ILK_FBCQ_DIS); /* WaDisableBackToBackFlipFix:ivb */ - intel_uncore_write(&dev_priv->uncore, IVB_CHICKEN3, - CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | - CHICKEN3_DGMG_DONE_FIX_DISABLE); + intel_uncore_write(&i915->uncore, IVB_CHICKEN3, + CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | + CHICKEN3_DGMG_DONE_FIX_DISABLE); - if (IS_IVB_GT1(dev_priv)) - intel_uncore_write(&dev_priv->uncore, GEN7_ROW_CHICKEN2, - _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); + if (IS_IVB_GT1(i915)) + intel_uncore_write(&i915->uncore, GEN7_ROW_CHICKEN2, + _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); else { /* must write both registers */ - intel_uncore_write(&dev_priv->uncore, GEN7_ROW_CHICKEN2, - _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); - intel_uncore_write(&dev_priv->uncore, GEN7_ROW_CHICKEN2_GT2, - _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); + intel_uncore_write(&i915->uncore, GEN7_ROW_CHICKEN2, + _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); + intel_uncore_write(&i915->uncore, GEN7_ROW_CHICKEN2_GT2, + _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); } /* * According to the spec, bit 13 (RCZUNIT) must be set on IVB. * This implements the WaDisableRCZUnitClockGating:ivb workaround. */ - intel_uncore_write(&dev_priv->uncore, GEN6_UCGCTL2, - GEN6_RCZUNIT_CLOCK_GATE_DISABLE); + intel_uncore_write(&i915->uncore, GEN6_UCGCTL2, + GEN6_RCZUNIT_CLOCK_GATE_DISABLE); /* This is required by WaCatErrorRejectionIssue:ivb */ - intel_uncore_rmw(&dev_priv->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, + intel_uncore_rmw(&i915->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, 0, GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); - g4x_disable_trickle_feed(dev_priv); + g4x_disable_trickle_feed(i915); - intel_uncore_rmw(&dev_priv->uncore, GEN6_MBCUNIT_SNPCR, GEN6_MBC_SNPCR_MASK, + intel_uncore_rmw(&i915->uncore, GEN6_MBCUNIT_SNPCR, GEN6_MBC_SNPCR_MASK, GEN6_MBC_SNPCR_MED); - if (!HAS_PCH_NOP(dev_priv)) - cpt_init_clock_gating(dev_priv); + if (!HAS_PCH_NOP(i915)) + cpt_init_clock_gating(i915); - gen6_check_mch_setup(dev_priv); + gen6_check_mch_setup(i915); } -static void vlv_init_clock_gating(struct drm_i915_private *dev_priv) +static void vlv_init_clock_gating(struct drm_i915_private *i915) { /* WaDisableBackToBackFlipFix:vlv */ - intel_uncore_write(&dev_priv->uncore, IVB_CHICKEN3, - CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | - CHICKEN3_DGMG_DONE_FIX_DISABLE); + intel_uncore_write(&i915->uncore, IVB_CHICKEN3, + CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | + CHICKEN3_DGMG_DONE_FIX_DISABLE); /* WaDisableDopClockGating:vlv */ - intel_uncore_write(&dev_priv->uncore, GEN7_ROW_CHICKEN2, - _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); + intel_uncore_write(&i915->uncore, GEN7_ROW_CHICKEN2, + _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE)); /* This is required by WaCatErrorRejectionIssue:vlv */ - intel_uncore_rmw(&dev_priv->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, + intel_uncore_rmw(&i915->uncore, GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, 0, GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); /* * According to the spec, bit 13 (RCZUNIT) must be set on IVB. * This implements the WaDisableRCZUnitClockGating:vlv workaround. */ - intel_uncore_write(&dev_priv->uncore, GEN6_UCGCTL2, - GEN6_RCZUNIT_CLOCK_GATE_DISABLE); + intel_uncore_write(&i915->uncore, GEN6_UCGCTL2, + GEN6_RCZUNIT_CLOCK_GATE_DISABLE); /* WaDisableL3Bank2xClockGate:vlv * Disabling L3 clock gating- MMIO 940c[25] = 1 * Set bit 25, to disable L3_BANK_2x_CLK_GATING */ - intel_uncore_rmw(&dev_priv->uncore, GEN7_UCGCTL4, 0, GEN7_L3BANK2X_CLOCK_GATE_DISABLE); + intel_uncore_rmw(&i915->uncore, GEN7_UCGCTL4, 0, GEN7_L3BANK2X_CLOCK_GATE_DISABLE); /* * WaDisableVLVClockGating_VBIIssue:vlv * Disable clock gating on th GCFG unit to prevent a delay * in the reporting of vblank events. */ - intel_uncore_write(&dev_priv->uncore, VLV_GUNIT_CLOCK_GATE, GCFG_DIS); + intel_uncore_write(&i915->uncore, VLV_GUNIT_CLOCK_GATE, GCFG_DIS); } -static void chv_init_clock_gating(struct drm_i915_private *dev_priv) +static void chv_init_clock_gating(struct drm_i915_private *i915) { /* WaVSRefCountFullforceMissDisable:chv */ /* WaDSRefCountFullforceMissDisable:chv */ - intel_uncore_rmw(&dev_priv->uncore, GEN7_FF_THREAD_MODE, + intel_uncore_rmw(&i915->uncore, GEN7_FF_THREAD_MODE, GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME, 0); /* WaDisableSemaphoreAndSyncFlipWait:chv */ - intel_uncore_write(&dev_priv->uncore, RING_PSMI_CTL(RENDER_RING_BASE), - _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE)); + intel_uncore_write(&i915->uncore, RING_PSMI_CTL(RENDER_RING_BASE), + _MASKED_BIT_ENABLE(GEN8_RC_SEMA_IDLE_MSG_DISABLE)); /* WaDisableCSUnitClockGating:chv */ - intel_uncore_rmw(&dev_priv->uncore, GEN6_UCGCTL1, 0, GEN6_CSUNIT_CLOCK_GATE_DISABLE); + intel_uncore_rmw(&i915->uncore, GEN6_UCGCTL1, 0, GEN6_CSUNIT_CLOCK_GATE_DISABLE); /* WaDisableSDEUnitClockGating:chv */ - intel_uncore_rmw(&dev_priv->uncore, GEN8_UCGCTL6, 0, GEN8_SDEUNIT_CLOCK_GATE_DISABLE); + intel_uncore_rmw(&i915->uncore, GEN8_UCGCTL6, 0, GEN8_SDEUNIT_CLOCK_GATE_DISABLE); /* * WaProgramL3SqcReg1Default:chv * See gfxspecs/Related Documents/Performance Guide/ * LSQC Setting Recommendations. */ - gen8_set_l3sqc_credits(dev_priv, 38, 2); + gen8_set_l3sqc_credits(i915, 38, 2); } -static void g4x_init_clock_gating(struct drm_i915_private *dev_priv) +static void g4x_init_clock_gating(struct drm_i915_private *i915) { u32 dspclk_gate; - intel_uncore_write(&dev_priv->uncore, RENCLK_GATE_D1, 0); - intel_uncore_write(&dev_priv->uncore, RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | - GS_UNIT_CLOCK_GATE_DISABLE | - CL_UNIT_CLOCK_GATE_DISABLE); - intel_uncore_write(&dev_priv->uncore, RAMCLK_GATE_D, 0); + intel_uncore_write(&i915->uncore, RENCLK_GATE_D1, 0); + intel_uncore_write(&i915->uncore, RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | + GS_UNIT_CLOCK_GATE_DISABLE | + CL_UNIT_CLOCK_GATE_DISABLE); + intel_uncore_write(&i915->uncore, RAMCLK_GATE_D, 0); dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE | OVRUNIT_CLOCK_GATE_DISABLE | OVCUNIT_CLOCK_GATE_DISABLE; - if (IS_GM45(dev_priv)) + if (IS_GM45(i915)) dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE; - intel_uncore_write(&dev_priv->uncore, DSPCLK_GATE_D(dev_priv), dspclk_gate); + intel_uncore_write(&i915->uncore, DSPCLK_GATE_D(i915), dspclk_gate); - g4x_disable_trickle_feed(dev_priv); + g4x_disable_trickle_feed(i915); } -static void i965gm_init_clock_gating(struct drm_i915_private *dev_priv) +static void i965gm_init_clock_gating(struct drm_i915_private *i915) { - struct intel_uncore *uncore = &dev_priv->uncore; + struct intel_uncore *uncore = &i915->uncore; intel_uncore_write(uncore, RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE); intel_uncore_write(uncore, RENCLK_GATE_D2, 0); - intel_uncore_write(uncore, DSPCLK_GATE_D(dev_priv), 0); + intel_uncore_write(uncore, DSPCLK_GATE_D(i915), 0); intel_uncore_write(uncore, RAMCLK_GATE_D, 0); intel_uncore_write16(uncore, DEUC, 0); intel_uncore_write(uncore, @@ -707,54 +709,55 @@ static void i965gm_init_clock_gating(struct drm_i915_private *dev_priv) _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE)); } -static void i965g_init_clock_gating(struct drm_i915_private *dev_priv) +static void i965g_init_clock_gating(struct drm_i915_private *i915) { - intel_uncore_write(&dev_priv->uncore, RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE | - I965_RCC_CLOCK_GATE_DISABLE | - I965_RCPB_CLOCK_GATE_DISABLE | - I965_ISC_CLOCK_GATE_DISABLE | - I965_FBC_CLOCK_GATE_DISABLE); - intel_uncore_write(&dev_priv->uncore, RENCLK_GATE_D2, 0); - intel_uncore_write(&dev_priv->uncore, MI_ARB_STATE, - _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE)); + intel_uncore_write(&i915->uncore, RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE | + I965_RCC_CLOCK_GATE_DISABLE | + I965_RCPB_CLOCK_GATE_DISABLE | + I965_ISC_CLOCK_GATE_DISABLE | + I965_FBC_CLOCK_GATE_DISABLE); + intel_uncore_write(&i915->uncore, RENCLK_GATE_D2, 0); + intel_uncore_write(&i915->uncore, MI_ARB_STATE, + _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE)); } -static void gen3_init_clock_gating(struct drm_i915_private *dev_priv) +static void gen3_init_clock_gating(struct drm_i915_private *i915) { - u32 dstate = intel_uncore_read(&dev_priv->uncore, D_STATE); + u32 dstate = intel_uncore_read(&i915->uncore, D_STATE); dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING | DSTATE_DOT_CLOCK_GATING; - intel_uncore_write(&dev_priv->uncore, D_STATE, dstate); + intel_uncore_write(&i915->uncore, D_STATE, dstate); - if (IS_PINEVIEW(dev_priv)) - intel_uncore_write(&dev_priv->uncore, ECOSKPD(RENDER_RING_BASE), + if (IS_PINEVIEW(i915)) + intel_uncore_write(&i915->uncore, ECOSKPD(RENDER_RING_BASE), _MASKED_BIT_ENABLE(ECO_GATING_CX_ONLY)); /* IIR "flip pending" means done if this bit is set */ - intel_uncore_write(&dev_priv->uncore, ECOSKPD(RENDER_RING_BASE), + intel_uncore_write(&i915->uncore, ECOSKPD(RENDER_RING_BASE), _MASKED_BIT_DISABLE(ECO_FLIP_DONE)); /* interrupts should cause a wake up from C3 */ - intel_uncore_write(&dev_priv->uncore, INSTPM, _MASKED_BIT_ENABLE(INSTPM_AGPBUSY_INT_EN)); + intel_uncore_write(&i915->uncore, INSTPM, _MASKED_BIT_ENABLE(INSTPM_AGPBUSY_INT_EN)); /* On GEN3 we really need to make sure the ARB C3 LP bit is set */ - intel_uncore_write(&dev_priv->uncore, MI_ARB_STATE, _MASKED_BIT_ENABLE(MI_ARB_C3_LP_WRITE_ENABLE)); + intel_uncore_write(&i915->uncore, MI_ARB_STATE, + _MASKED_BIT_ENABLE(MI_ARB_C3_LP_WRITE_ENABLE)); - intel_uncore_write(&dev_priv->uncore, MI_ARB_STATE, - _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE)); + intel_uncore_write(&i915->uncore, MI_ARB_STATE, + _MASKED_BIT_ENABLE(MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE)); } -static void i85x_init_clock_gating(struct drm_i915_private *dev_priv) +static void i85x_init_clock_gating(struct drm_i915_private *i915) { - intel_uncore_write(&dev_priv->uncore, RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE); + intel_uncore_write(&i915->uncore, RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE); /* interrupts should cause a wake up from C3 */ - intel_uncore_write(&dev_priv->uncore, MI_STATE, _MASKED_BIT_ENABLE(MI_AGPBUSY_INT_EN) | - _MASKED_BIT_DISABLE(MI_AGPBUSY_830_MODE)); + intel_uncore_write(&i915->uncore, MI_STATE, _MASKED_BIT_ENABLE(MI_AGPBUSY_INT_EN) | + _MASKED_BIT_DISABLE(MI_AGPBUSY_830_MODE)); - intel_uncore_write(&dev_priv->uncore, MEM_MODE, - _MASKED_BIT_ENABLE(MEM_DISPLAY_TRICKLE_FEED_DISABLE)); + intel_uncore_write(&i915->uncore, MEM_MODE, + _MASKED_BIT_ENABLE(MEM_DISPLAY_TRICKLE_FEED_DISABLE)); /* * Have FBC ignore 3D activity since we use software @@ -763,25 +766,25 @@ static void i85x_init_clock_gating(struct drm_i915_private *dev_priv) * abosultely nothing) would not allow FBC to recompress * until a 2D blit occurs. */ - intel_uncore_write(&dev_priv->uncore, SCPD0, - _MASKED_BIT_ENABLE(SCPD_FBC_IGNORE_3D)); + intel_uncore_write(&i915->uncore, SCPD0, + _MASKED_BIT_ENABLE(SCPD_FBC_IGNORE_3D)); } -static void i830_init_clock_gating(struct drm_i915_private *dev_priv) +static void i830_init_clock_gating(struct drm_i915_private *i915) { - intel_uncore_write(&dev_priv->uncore, MEM_MODE, - _MASKED_BIT_ENABLE(MEM_DISPLAY_A_TRICKLE_FEED_DISABLE) | - _MASKED_BIT_ENABLE(MEM_DISPLAY_B_TRICKLE_FEED_DISABLE)); + intel_uncore_write(&i915->uncore, MEM_MODE, + _MASKED_BIT_ENABLE(MEM_DISPLAY_A_TRICKLE_FEED_DISABLE) | + _MASKED_BIT_ENABLE(MEM_DISPLAY_B_TRICKLE_FEED_DISABLE)); } -void intel_clock_gating_init(struct drm_i915_private *dev_priv) +void intel_clock_gating_init(struct drm_i915_private *i915) { - dev_priv->clock_gating_funcs->init_clock_gating(dev_priv); + i915->clock_gating_funcs->init_clock_gating(i915); } -static void nop_init_clock_gating(struct drm_i915_private *dev_priv) +static void nop_init_clock_gating(struct drm_i915_private *i915) { - drm_dbg_kms(&dev_priv->drm, + drm_dbg_kms(&i915->drm, "No clock gating settings or workarounds applied.\n"); } @@ -819,67 +822,67 @@ CG_FUNCS(nop); /** * intel_clock_gating_hooks_init - setup the clock gating hooks - * @dev_priv: device private + * @i915: device private * * Setup the hooks that configure which clocks of a given platform can be * gated and also apply various GT and display specific workarounds for these * platforms. Note that some GT specific workarounds are applied separately * when GPU contexts or batchbuffers start their execution. */ -void intel_clock_gating_hooks_init(struct drm_i915_private *dev_priv) -{ - if (IS_METEORLAKE(dev_priv)) - dev_priv->clock_gating_funcs = &nop_clock_gating_funcs; - else if (IS_PONTEVECCHIO(dev_priv)) - dev_priv->clock_gating_funcs = &pvc_clock_gating_funcs; - else if (IS_DG2(dev_priv)) - dev_priv->clock_gating_funcs = &dg2_clock_gating_funcs; - else if (IS_XEHPSDV(dev_priv)) - dev_priv->clock_gating_funcs = &xehpsdv_clock_gating_funcs; - else if (IS_ALDERLAKE_P(dev_priv)) - dev_priv->clock_gating_funcs = &adlp_clock_gating_funcs; - else if (GRAPHICS_VER(dev_priv) == 12) - dev_priv->clock_gating_funcs = &gen12lp_clock_gating_funcs; - else if (GRAPHICS_VER(dev_priv) == 11) - dev_priv->clock_gating_funcs = &icl_clock_gating_funcs; - else if (IS_COFFEELAKE(dev_priv) || IS_COMETLAKE(dev_priv)) - dev_priv->clock_gating_funcs = &cfl_clock_gating_funcs; - else if (IS_SKYLAKE(dev_priv)) - dev_priv->clock_gating_funcs = &skl_clock_gating_funcs; - else if (IS_KABYLAKE(dev_priv)) - dev_priv->clock_gating_funcs = &kbl_clock_gating_funcs; - else if (IS_BROXTON(dev_priv)) - dev_priv->clock_gating_funcs = &bxt_clock_gating_funcs; - else if (IS_GEMINILAKE(dev_priv)) - dev_priv->clock_gating_funcs = &glk_clock_gating_funcs; - else if (IS_BROADWELL(dev_priv)) - dev_priv->clock_gating_funcs = &bdw_clock_gating_funcs; - else if (IS_CHERRYVIEW(dev_priv)) - dev_priv->clock_gating_funcs = &chv_clock_gating_funcs; - else if (IS_HASWELL(dev_priv)) - dev_priv->clock_gating_funcs = &hsw_clock_gating_funcs; - else if (IS_IVYBRIDGE(dev_priv)) - dev_priv->clock_gating_funcs = &ivb_clock_gating_funcs; - else if (IS_VALLEYVIEW(dev_priv)) - dev_priv->clock_gating_funcs = &vlv_clock_gating_funcs; - else if (GRAPHICS_VER(dev_priv) == 6) - dev_priv->clock_gating_funcs = &gen6_clock_gating_funcs; - else if (GRAPHICS_VER(dev_priv) == 5) - dev_priv->clock_gating_funcs = &ilk_clock_gating_funcs; - else if (IS_G4X(dev_priv)) - dev_priv->clock_gating_funcs = &g4x_clock_gating_funcs; - else if (IS_I965GM(dev_priv)) - dev_priv->clock_gating_funcs = &i965gm_clock_gating_funcs; - else if (IS_I965G(dev_priv)) - dev_priv->clock_gating_funcs = &i965g_clock_gating_funcs; - else if (GRAPHICS_VER(dev_priv) == 3) - dev_priv->clock_gating_funcs = &gen3_clock_gating_funcs; - else if (IS_I85X(dev_priv) || IS_I865G(dev_priv)) - dev_priv->clock_gating_funcs = &i85x_clock_gating_funcs; - else if (GRAPHICS_VER(dev_priv) == 2) - dev_priv->clock_gating_funcs = &i830_clock_gating_funcs; +void intel_clock_gating_hooks_init(struct drm_i915_private *i915) +{ + if (IS_METEORLAKE(i915)) + i915->clock_gating_funcs = &nop_clock_gating_funcs; + else if (IS_PONTEVECCHIO(i915)) + i915->clock_gating_funcs = &pvc_clock_gating_funcs; + else if (IS_DG2(i915)) + i915->clock_gating_funcs = &dg2_clock_gating_funcs; + else if (IS_XEHPSDV(i915)) + i915->clock_gating_funcs = &xehpsdv_clock_gating_funcs; + else if (IS_ALDERLAKE_P(i915)) + i915->clock_gating_funcs = &adlp_clock_gating_funcs; + else if (GRAPHICS_VER(i915) == 12) + i915->clock_gating_funcs = &gen12lp_clock_gating_funcs; + else if (GRAPHICS_VER(i915) == 11) + i915->clock_gating_funcs = &icl_clock_gating_funcs; + else if (IS_COFFEELAKE(i915) || IS_COMETLAKE(i915)) + i915->clock_gating_funcs = &cfl_clock_gating_funcs; + else if (IS_SKYLAKE(i915)) + i915->clock_gating_funcs = &skl_clock_gating_funcs; + else if (IS_KABYLAKE(i915)) + i915->clock_gating_funcs = &kbl_clock_gating_funcs; + else if (IS_BROXTON(i915)) + i915->clock_gating_funcs = &bxt_clock_gating_funcs; + else if (IS_GEMINILAKE(i915)) + i915->clock_gating_funcs = &glk_clock_gating_funcs; + else if (IS_BROADWELL(i915)) + i915->clock_gating_funcs = &bdw_clock_gating_funcs; + else if (IS_CHERRYVIEW(i915)) + i915->clock_gating_funcs = &chv_clock_gating_funcs; + else if (IS_HASWELL(i915)) + i915->clock_gating_funcs = &hsw_clock_gating_funcs; + else if (IS_IVYBRIDGE(i915)) + i915->clock_gating_funcs = &ivb_clock_gating_funcs; + else if (IS_VALLEYVIEW(i915)) + i915->clock_gating_funcs = &vlv_clock_gating_funcs; + else if (GRAPHICS_VER(i915) == 6) + i915->clock_gating_funcs = &gen6_clock_gating_funcs; + else if (GRAPHICS_VER(i915) == 5) + i915->clock_gating_funcs = &ilk_clock_gating_funcs; + else if (IS_G4X(i915)) + i915->clock_gating_funcs = &g4x_clock_gating_funcs; + else if (IS_I965GM(i915)) + i915->clock_gating_funcs = &i965gm_clock_gating_funcs; + else if (IS_I965G(i915)) + i915->clock_gating_funcs = &i965g_clock_gating_funcs; + else if (GRAPHICS_VER(i915) == 3) + i915->clock_gating_funcs = &gen3_clock_gating_funcs; + else if (IS_I85X(i915) || IS_I865G(i915)) + i915->clock_gating_funcs = &i85x_clock_gating_funcs; + else if (GRAPHICS_VER(i915) == 2) + i915->clock_gating_funcs = &i830_clock_gating_funcs; else { - MISSING_CASE(INTEL_DEVID(dev_priv)); - dev_priv->clock_gating_funcs = &nop_clock_gating_funcs; + MISSING_CASE(INTEL_DEVID(i915)); + i915->clock_gating_funcs = &nop_clock_gating_funcs; } } -- cgit v1.2.3-59-g8ed1b From efd8127454054d6d52040c17f7fa1656ac3befdc Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 5 Apr 2023 13:41:41 +0300 Subject: drm/i915/tc: demote a kernel-doc comment to a regular comment There's not much point in a static work function having a kernel-doc comment. Just clean it up and make it a regular comment. This fixes the kernel-doc warnings: drivers/gpu/drm/i915/display/intel_tc.c:1370: warning: Function parameter or member 'work' not described in 'intel_tc_port_disconnect_phy_work' drivers/gpu/drm/i915/display/intel_tc.c:1370: warning: Excess function parameter 'dig_port' description in 'intel_tc_port_disconnect_phy_work' Signed-off-by: Jani Nikula Reviewed-by: Vinod Govindapillai Link: https://patchwork.freedesktop.org/patch/msgid/20230405104142.766598-1-jani.nikula@intel.com --- drivers/gpu/drm/i915/display/intel_tc.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 2bb02d4e6859..3b60995e9dfb 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -1358,10 +1358,7 @@ void intel_tc_port_lock(struct intel_digital_port *dig_port) __intel_tc_port_lock(to_tc_port(dig_port), 1); } -/** - * intel_tc_port_disconnect_phy_work: disconnect TypeC PHY from display port - * @dig_port: digital port - * +/* * Disconnect the given digital port from its TypeC PHY (handing back the * control of the PHY to the TypeC subsystem). This will happen in a delayed * manner after each aux transactions and modeset disables. -- cgit v1.2.3-59-g8ed1b From b358793c3bf231c455c55e0173256a86483997a8 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 5 Apr 2023 13:41:42 +0300 Subject: drm/i915/wakeref: fix kernel-doc comment Fix the warning: drivers/gpu/drm/i915/intel_wakeref.h:118: warning: expecting prototype for intel_wakeref_get_if_in_use(). Prototype was for intel_wakeref_get_if_active() instead Signed-off-by: Jani Nikula Reviewed-by: Vinod Govindapillai Link: https://patchwork.freedesktop.org/patch/msgid/20230405104142.766598-2-jani.nikula@intel.com --- drivers/gpu/drm/i915/intel_wakeref.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu') diff --git a/drivers/gpu/drm/i915/intel_wakeref.h b/drivers/gpu/drm/i915/intel_wakeref.h index 71b8a63f6f10..0b6b4852ab23 100644 --- a/drivers/gpu/drm/i915/intel_wakeref.h +++ b/drivers/gpu/drm/i915/intel_wakeref.h @@ -105,7 +105,7 @@ __intel_wakeref_get(struct intel_wakeref *wf) } /** - * intel_wakeref_get_if_in_use: Acquire the wakeref + * intel_wakeref_get_if_active: Acquire the wakeref * @wf: the wakeref * * Acquire a hold on the wakeref, but only if the wakeref is already -- cgit v1.2.3-59-g8ed1b