[PATCH v2 4/5] drm/i915: Eliminate extra frame from skl-glk sync->async flip change

2024-04-30 Thread Ville Syrjala
From: Ville Syrjälä 

On bdw-glk the sync->async flip change takes an extra frame due to
the double buffering behaviour of the async flip plane control bit.

Since on skl+ we are now explicitly converting the first async flip
to a sync flip (in order to allow changing the modifier and/or
ddb/watermarks) we are now taking two extra frames until async flips
are actually active. We can drop that back down to one frame by
setting the async flip bit already during the sync flip.

Note that on bdw we don't currently do the extra sync flip (see
intel_plane_do_async_flip()) so technically we wouldn't have
to deal with this in i9xx_plane_update_arm(). But I added the
relevant snippet of code there as well, just in case we ever
decide to go for the extra sync flip on pre-skl platforms as
well (we might, for example, want to change the fb stride).

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/i9xx_plane.c |  5 +
 drivers/gpu/drm/i915/display/intel_atomic_plane.c | 15 +++
 .../gpu/drm/i915/display/skl_universal_plane.c|  5 +
 3 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c 
b/drivers/gpu/drm/i915/display/i9xx_plane.c
index 0279c8aabdd1..76fc7626051b 100644
--- a/drivers/gpu/drm/i915/display/i9xx_plane.c
+++ b/drivers/gpu/drm/i915/display/i9xx_plane.c
@@ -455,6 +455,11 @@ static void i9xx_plane_update_arm(struct intel_plane 
*plane,
 
dspcntr = plane_state->ctl | i9xx_plane_ctl_crtc(crtc_state);
 
+   /* see intel_plane_atomic_calc_changes() */
+   if (plane->need_async_flip_disable_wa &&
+   crtc_state->async_flip_planes & BIT(plane->id))
+   dspcntr |= DISP_ASYNC_FLIP;
+
linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
 
if (DISPLAY_VER(dev_priv) >= 4)
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c 
b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 769010d0ebc4..7098a34a17c8 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -437,10 +437,6 @@ static bool intel_plane_do_async_flip(struct intel_plane 
*plane,
 * only X-tile is supported with async flips, though we could
 * extend this so other scanout parameters (stride/etc) could
 * be changed as well...
-*
-* FIXME: Platforms with need_async_flip_disable_wa==true will
-* now end up doing two sync flips initially. Would be nice to
-* combine those into just the one sync flip...
 */
return DISPLAY_VER(i915) < 9 || old_crtc_state->uapi.async_flip;
 }
@@ -604,6 +600,17 @@ static int intel_plane_atomic_calc_changes(const struct 
intel_crtc_state *old_cr
if (intel_plane_do_async_flip(plane, old_crtc_state, new_crtc_state)) {
new_crtc_state->do_async_flip = true;
new_crtc_state->async_flip_planes |= BIT(plane->id);
+   } else if (plane->need_async_flip_disable_wa &&
+  new_crtc_state->uapi.async_flip) {
+   /*
+* On platforms with double buffered async flip bit we
+* set the bit already one frame early during the sync
+* flip (see {i9xx,skl}_plane_update_arm()). The
+* hardware will therefore be ready to perform a real
+* async flip during the next commit, without having
+* to wait yet another frame for the bit to latch.
+*/
+   new_crtc_state->async_flip_planes |= BIT(plane->id);
}
 
return 0;
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c 
b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 860574d04f88..ad4c90344f68 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -1174,6 +1174,11 @@ skl_plane_update_arm(struct intel_plane *plane,
plane_ctl = plane_state->ctl |
skl_plane_ctl_crtc(crtc_state);
 
+   /* see intel_plane_atomic_calc_changes() */
+   if (plane->need_async_flip_disable_wa &&
+   crtc_state->async_flip_planes & BIT(plane->id))
+   plane_ctl |= PLANE_CTL_ASYNC_FLIP;
+
if (DISPLAY_VER(dev_priv) >= 10)
plane_color_ctl = plane_state->color_ctl |
glk_plane_color_ctl_crtc(crtc_state);
-- 
2.43.2



[PATCH v2 5/5] drm/i915: s/need_async_flip_disable_wa/need_async_flip_toggle_wa/

2024-04-30 Thread Ville Syrjala
From: Ville Syrjälä 

Rename need_async_flip_disable_wa to need_async_flip_toggle_wa to
better reflect the fact that we need to deal with the bad
PLANE_CTL_ASYNC_FLIP double buffering behaviour going both
ways.

Reviewed-by: Arun R Murthy 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/i9xx_plane.c  | 4 ++--
 drivers/gpu/drm/i915/display/intel_atomic_plane.c  | 2 +-
 drivers/gpu/drm/i915/display/intel_display.c   | 2 +-
 drivers/gpu/drm/i915/display/intel_display_types.h | 2 +-
 drivers/gpu/drm/i915/display/skl_universal_plane.c | 5 ++---
 5 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c 
b/drivers/gpu/drm/i915/display/i9xx_plane.c
index 76fc7626051b..3442264443e5 100644
--- a/drivers/gpu/drm/i915/display/i9xx_plane.c
+++ b/drivers/gpu/drm/i915/display/i9xx_plane.c
@@ -456,7 +456,7 @@ static void i9xx_plane_update_arm(struct intel_plane *plane,
dspcntr = plane_state->ctl | i9xx_plane_ctl_crtc(crtc_state);
 
/* see intel_plane_atomic_calc_changes() */
-   if (plane->need_async_flip_disable_wa &&
+   if (plane->need_async_flip_toggle_wa &&
crtc_state->async_flip_planes & BIT(plane->id))
dspcntr |= DISP_ASYNC_FLIP;
 
@@ -878,7 +878,7 @@ intel_primary_plane_create(struct drm_i915_private 
*dev_priv, enum pipe pipe)
plane->enable_flip_done = vlv_primary_enable_flip_done;
plane->disable_flip_done = vlv_primary_disable_flip_done;
} else if (IS_BROADWELL(dev_priv)) {
-   plane->need_async_flip_disable_wa = true;
+   plane->need_async_flip_toggle_wa = true;
plane->async_flip = g4x_primary_async_flip;
plane->enable_flip_done = bdw_primary_enable_flip_done;
plane->disable_flip_done = bdw_primary_disable_flip_done;
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c 
b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 7098a34a17c8..b083b985d170 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -600,7 +600,7 @@ static int intel_plane_atomic_calc_changes(const struct 
intel_crtc_state *old_cr
if (intel_plane_do_async_flip(plane, old_crtc_state, new_crtc_state)) {
new_crtc_state->do_async_flip = true;
new_crtc_state->async_flip_planes |= BIT(plane->id);
-   } else if (plane->need_async_flip_disable_wa &&
+   } else if (plane->need_async_flip_toggle_wa &&
   new_crtc_state->uapi.async_flip) {
/*
 * On platforms with double buffered async flip bit we
diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index fa1ddb558f48..34f168e4e371 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -1139,7 +1139,7 @@ static void intel_crtc_async_flip_disable_wa(struct 
intel_atomic_state *state,
int i;
 
for_each_old_intel_plane_in_state(state, plane, old_plane_state, i) {
-   if (plane->need_async_flip_disable_wa &&
+   if (plane->need_async_flip_toggle_wa &&
plane->pipe == crtc->pipe &&
disable_async_flip_planes & BIT(plane->id)) {
/*
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index 62f7a30c37dc..00eba3fbcdc6 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1521,7 +1521,7 @@ struct intel_plane {
enum i9xx_plane_id i9xx_plane;
enum plane_id id;
enum pipe pipe;
-   bool need_async_flip_disable_wa;
+   bool need_async_flip_toggle_wa;
u32 frontbuffer_bit;
 
struct {
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c 
b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index ad4c90344f68..0a8e781a3648 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -1175,7 +1175,7 @@ skl_plane_update_arm(struct intel_plane *plane,
skl_plane_ctl_crtc(crtc_state);
 
/* see intel_plane_atomic_calc_changes() */
-   if (plane->need_async_flip_disable_wa &&
+   if (plane->need_async_flip_toggle_wa &&
crtc_state->async_flip_planes & BIT(plane->id))
plane_ctl |= PLANE_CTL_ASYNC_FLIP;
 
@@ -2371,8 +2371,7 @@ skl_universal_plane_create(struct drm_i915_private 
*dev_priv,
plane->check_plane = skl_plane_check;
 
if (plane_id == PLANE_PRIMARY) {
-   plane->need_async_flip_disable_wa = IS_DISPLAY_VER(dev_priv,
-  9, 10);
+   plane->need_async_flip_toggle_wa = IS_DISPLAY_VER(dev_priv, 

[PATCH v2 3/5] drm/i915: Allow the initial async flip to change modifier

2024-04-30 Thread Ville Syrjala
From: Ville Syrjälä 

With Xorg+modesetting on skl+ we see the following behaviour:
1. root pixmap is X-tiled
2. client submitted buffers can be Y-tiled (w/ 'Option "dmabuf_capable"')
3. we try to switch from the X-tiled buffer to the Y-tiled buffer
   using an async flip (when vsync is disabled).
4. the async flip will be rejected by i915 due to the modifier change

Relax the rules a bit by turning the first async flip into a sync
flip so that we can change the modifier if necessary. Note that
we already convert the first async flip into a sync flip on adl+
in order to reprogram the watermarks.

Reviewed-by: Vandita Kulkarni 
Signed-off-by: Ville Syrjälä 
---
 .../gpu/drm/i915/display/intel_atomic_plane.c| 16 +---
 drivers/gpu/drm/i915/display/intel_display.c |  7 +++
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c 
b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index 76d77d5a0409..769010d0ebc4 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -429,10 +429,20 @@ static bool intel_plane_do_async_flip(struct intel_plane 
*plane,
 * In platforms after DISPLAY13, we might need to override
 * first async flip in order to change watermark levels
 * as part of optimization.
-* So for those, we are checking if this is a first async flip.
-* For platforms earlier than DISPLAY13 we always do async flip.
+*
+* And let's do this for all skl+ so that we can eg. change the
+* modifier as well.
+*
+* TODO: For older platforms there is less reason to do this as
+* only X-tile is supported with async flips, though we could
+* extend this so other scanout parameters (stride/etc) could
+* be changed as well...
+*
+* FIXME: Platforms with need_async_flip_disable_wa==true will
+* now end up doing two sync flips initially. Would be nice to
+* combine those into just the one sync flip...
 */
-   return DISPLAY_VER(i915) < 13 || old_crtc_state->uapi.async_flip;
+   return DISPLAY_VER(i915) < 9 || old_crtc_state->uapi.async_flip;
 }
 
 static bool i9xx_must_disable_cxsr(const struct intel_crtc_state 
*new_crtc_state,
diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index f45e5f02096d..fa1ddb558f48 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -6165,6 +6165,13 @@ static int intel_async_flip_check_hw(struct 
intel_atomic_state *state, struct in
return -EINVAL;
}
 
+   /*
+* We turn the first async flip request into a sync flip
+* so that we can reconfigure the plane (eg. change modifier).
+*/
+   if (!new_crtc_state->do_async_flip)
+   continue;
+
if (old_plane_state->view.color_plane[0].mapping_stride !=
new_plane_state->view.color_plane[0].mapping_stride) {
drm_dbg_kms(>drm,
-- 
2.43.2



[PATCH v2 2/5] drm/i915: Reject async flips if we need to change DDB/watermarks

2024-04-30 Thread Ville Syrjala
From: Ville Syrjälä 

DDB/watermarks are always double buffered on the vblank, so we
can't safely change them during async flips. Currently this never
happens, but we'll be making changing between sync and async
flips a bit more flexible, in which case we can actually end up
here.

Reviewed-by: Vandita Kulkarni 
Reviewed-by: Arun R Murthy 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/skl_watermark.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c 
b/drivers/gpu/drm/i915/display/skl_watermark.c
index 7c6187b4479f..e6476aa621a7 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark.c
+++ b/drivers/gpu/drm/i915/display/skl_watermark.c
@@ -2540,6 +2540,12 @@ skl_ddb_add_affected_planes(const struct 
intel_crtc_state *old_crtc_state,

_crtc_state->wm.skl.plane_ddb_y[plane_id]))
continue;
 
+   if (new_crtc_state->do_async_flip) {
+   drm_dbg_kms(>drm, "[PLANE:%d:%s] Can't change DDB 
during async flip\n",
+   plane->base.base.id, plane->base.name);
+   return -EINVAL;
+   }
+
plane_state = intel_atomic_get_plane_state(state, plane);
if (IS_ERR(plane_state))
return PTR_ERR(plane_state);
@@ -2899,6 +2905,12 @@ static int skl_wm_add_affected_planes(struct 
intel_atomic_state *state,
 
_crtc_state->wm.skl.optimal))
continue;
 
+   if (new_crtc_state->do_async_flip) {
+   drm_dbg_kms(>drm, "[PLANE:%d:%s] Can't change 
watermarks during async flip\n",
+   plane->base.base.id, plane->base.name);
+   return -EINVAL;
+   }
+
plane_state = intel_atomic_get_plane_state(state, plane);
if (IS_ERR(plane_state))
return PTR_ERR(plane_state);
-- 
2.43.2



[PATCH v2 1/5] drm/i915: Align PLANE_SURF to 16k on ADL for async flips

2024-04-30 Thread Ville Syrjala
From: Ville Syrjälä 

On ADL async flips apparently generate DMAR and GGTT faults
(with accompanying visual glitches) unless PLANE_SURF is
aligned to at least 16k. Bump up the alignment to 16k.

TODO: analyze things better to figure out what is really
  going on here

Reviewed-by: Arun R Murthy 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpt.c|  7 ---
 drivers/gpu/drm/i915/display/intel_dpt.h|  3 ++-
 drivers/gpu/drm/i915/display/intel_fb.c | 17 -
 drivers/gpu/drm/i915/display/intel_fb_pin.c | 10 +-
 4 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c 
b/drivers/gpu/drm/i915/display/intel_dpt.c
index b29bceff73f2..786d3f2e94c7 100644
--- a/drivers/gpu/drm/i915/display/intel_dpt.c
+++ b/drivers/gpu/drm/i915/display/intel_dpt.c
@@ -121,7 +121,8 @@ static void dpt_cleanup(struct i915_address_space *vm)
i915_gem_object_put(dpt->obj);
 }
 
-struct i915_vma *intel_dpt_pin(struct i915_address_space *vm)
+struct i915_vma *intel_dpt_pin(struct i915_address_space *vm,
+  unsigned int alignment)
 {
struct drm_i915_private *i915 = vm->i915;
struct i915_dpt *dpt = i915_vm_to_dpt(vm);
@@ -143,8 +144,8 @@ struct i915_vma *intel_dpt_pin(struct i915_address_space 
*vm)
if (err)
continue;
 
-   vma = i915_gem_object_ggtt_pin_ww(dpt->obj, , NULL, 0, 4096,
- pin_flags);
+   vma = i915_gem_object_ggtt_pin_ww(dpt->obj, , NULL, 0,
+ alignment, pin_flags);
if (IS_ERR(vma)) {
err = PTR_ERR(vma);
continue;
diff --git a/drivers/gpu/drm/i915/display/intel_dpt.h 
b/drivers/gpu/drm/i915/display/intel_dpt.h
index e18a9f767b11..f467578a4950 100644
--- a/drivers/gpu/drm/i915/display/intel_dpt.h
+++ b/drivers/gpu/drm/i915/display/intel_dpt.h
@@ -13,7 +13,8 @@ struct i915_vma;
 struct intel_framebuffer;
 
 void intel_dpt_destroy(struct i915_address_space *vm);
-struct i915_vma *intel_dpt_pin(struct i915_address_space *vm);
+struct i915_vma *intel_dpt_pin(struct i915_address_space *vm,
+  unsigned int alignment);
 void intel_dpt_unpin(struct i915_address_space *vm);
 void intel_dpt_suspend(struct drm_i915_private *i915);
 void intel_dpt_resume(struct drm_i915_private *i915);
diff --git a/drivers/gpu/drm/i915/display/intel_fb.c 
b/drivers/gpu/drm/i915/display/intel_fb.c
index 86b443433e8b..bf24f48a1e76 100644
--- a/drivers/gpu/drm/i915/display/intel_fb.c
+++ b/drivers/gpu/drm/i915/display/intel_fb.c
@@ -805,8 +805,23 @@ unsigned int intel_surf_alignment(const struct 
drm_framebuffer *fb,
 {
struct drm_i915_private *dev_priv = to_i915(fb->dev);
 
-   if (intel_fb_uses_dpt(fb))
+   if (intel_fb_uses_dpt(fb)) {
+   /* AUX_DIST needs only 4K alignment */
+   if (intel_fb_is_ccs_aux_plane(fb, color_plane))
+   return 512 * 4096;
+
+   /*
+* FIXME ADL sees GGTT/DMAR faults with async
+* flips unless we align to 16k at least.
+* Figure out what's going on here...
+*/
+   if (IS_ALDERLAKE_P(dev_priv) &&
+   !intel_fb_is_ccs_modifier(fb->modifier) &&
+   HAS_ASYNC_FLIPS(dev_priv))
+   return 512 * 16 * 1024;
+
return 512 * 4096;
+   }
 
/* AUX_DIST needs only 4K alignment */
if (intel_fb_is_ccs_aux_plane(fb, color_plane))
diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.c 
b/drivers/gpu/drm/i915/display/intel_fb_pin.c
index b6df9baf481b..be095cc696ba 100644
--- a/drivers/gpu/drm/i915/display/intel_fb_pin.c
+++ b/drivers/gpu/drm/i915/display/intel_fb_pin.c
@@ -19,6 +19,7 @@
 static struct i915_vma *
 intel_pin_fb_obj_dpt(struct drm_framebuffer *fb,
 const struct i915_gtt_view *view,
+unsigned int alignment,
 bool uses_fence,
 unsigned long *out_flags,
 struct i915_address_space *vm)
@@ -28,7 +29,6 @@ intel_pin_fb_obj_dpt(struct drm_framebuffer *fb,
struct drm_i915_gem_object *obj = intel_fb_obj(fb);
struct i915_gem_ww_ctx ww;
struct i915_vma *vma;
-   u32 alignment;
int ret;
 
/*
@@ -41,8 +41,6 @@ intel_pin_fb_obj_dpt(struct drm_framebuffer *fb,
if (WARN_ON(!i915_gem_object_is_framebuffer(obj)))
return ERR_PTR(-EINVAL);
 
-   alignment = 4096 * 512;
-
atomic_inc(_priv->gpu_error.pending_fb_pin);
 
for_i915_gem_ww(, ret, true) {
@@ -267,14 +265,16 @@ int intel_plane_pin_fb(struct intel_plane_state 
*plane_state)

i915_gem_object_get_dma_address(intel_fb_obj(fb), 0);
} 

[PATCH v2 0/5] drm/i915: Allow the first async flip to change modifier

2024-04-30 Thread Ville Syrjala
From: Ville Syrjälä 

Xorg/modesetting expects to be able to change the modifier already
when submitting the first async flip. Let's convert the first async
flip to a sync flip so that we can accommodate it. For now I limit
this behaviour to skl+ since earlier platforms don't support async
flips with anything but X-tile anyway, but we could extend this if
needed to allow eg. stride changes/etc.

We already convert the first async flip to a sync flip on ADL+
to reprogram the watermarks/DDB, and on BDW-GLK the hardware
anyway converts the first async flip to a sync flip (due to the
double buffering behaviour of the async flip bit). So actually
this will only slow down the first async flip on ICL and TGL.

I've also included a workaround for async flip GGTT/DMAR faults
on ADL. Just bumping the alignment to 16k seems effective, and
so that seems like a reasonable enough solution for the moment.
But this probably needs further analysis later.

v2: Drop the ILK LP_WM refactoring for now as it's unrelated
Otherwise a repost to test against a fixed IGT series

Test-with: 20240322203726.16637-1-ville.syrj...@linux.intel.com

Ville Syrjälä (5):
  drm/i915: Align PLANE_SURF to 16k on ADL for async flips
  drm/i915: Reject async flips if we need to change DDB/watermarks
  drm/i915: Allow the initial async flip to change modifier
  drm/i915: Eliminate extra frame from skl-glk sync->async flip change
  drm/i915: s/need_async_flip_disable_wa/need_async_flip_toggle_wa/

 drivers/gpu/drm/i915/display/i9xx_plane.c |  7 +-
 .../gpu/drm/i915/display/intel_atomic_plane.c | 23 ---
 drivers/gpu/drm/i915/display/intel_display.c  |  9 +++-
 .../drm/i915/display/intel_display_types.h|  2 +-
 drivers/gpu/drm/i915/display/intel_dpt.c  |  7 +++---
 drivers/gpu/drm/i915/display/intel_dpt.h  |  3 ++-
 drivers/gpu/drm/i915/display/intel_fb.c   | 17 +-
 drivers/gpu/drm/i915/display/intel_fb_pin.c   | 10 
 .../drm/i915/display/skl_universal_plane.c|  8 +--
 drivers/gpu/drm/i915/display/skl_watermark.c  | 12 ++
 10 files changed, 80 insertions(+), 18 deletions(-)

-- 
2.43.2



[PATCH 14/14] drm/i915/dpio: Extract vlv_dpio_phy_regs.h

2024-04-22 Thread Ville Syrjala
From: Ville Syrjälä 

Pull the VLV/CHV DPIO PHY sideband registers to their own file.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_display.c  |   1 +
 .../i915/display/intel_display_power_well.c   |   1 +
 drivers/gpu/drm/i915/display/intel_dpio_phy.c |   1 +
 drivers/gpu/drm/i915/display/intel_dpll.c |   1 +
 .../gpu/drm/i915/display/vlv_dpio_phy_regs.h  | 309 ++
 drivers/gpu/drm/i915/i915_reg.h   | 298 -
 6 files changed, 313 insertions(+), 298 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/display/vlv_dpio_phy_regs.h

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 96ed1490fec7..59f989207c74 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -120,6 +120,7 @@
 #include "skl_scaler.h"
 #include "skl_universal_plane.h"
 #include "skl_watermark.h"
+#include "vlv_dpio_phy_regs.h"
 #include "vlv_dsi.h"
 #include "vlv_dsi_pll.h"
 #include "vlv_dsi_regs.h"
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 e4ba6efc90e6..83f616097a29 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power_well.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c
@@ -27,6 +27,7 @@
 #include "intel_tc.h"
 #include "intel_vga.h"
 #include "skl_watermark.h"
+#include "vlv_dpio_phy_regs.h"
 #include "vlv_sideband.h"
 #include "vlv_sideband_reg.h"
 
diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c 
b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
index 11875d18a8fc..d20e4e9cf7f7 100644
--- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
@@ -30,6 +30,7 @@
 #include "intel_display_types.h"
 #include "intel_dp.h"
 #include "intel_dpio_phy.h"
+#include "vlv_dpio_phy_regs.h"
 #include "vlv_sideband.h"
 
 /**
diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c 
b/drivers/gpu/drm/i915/display/intel_dpll.c
index c2ee95993a96..a981f45facb3 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll.c
@@ -20,6 +20,7 @@
 #include "intel_panel.h"
 #include "intel_pps.h"
 #include "intel_snps_phy.h"
+#include "vlv_dpio_phy_regs.h"
 #include "vlv_sideband.h"
 
 struct intel_dpll_funcs {
diff --git a/drivers/gpu/drm/i915/display/vlv_dpio_phy_regs.h 
b/drivers/gpu/drm/i915/display/vlv_dpio_phy_regs.h
new file mode 100644
index ..477506f0b2cc
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/vlv_dpio_phy_regs.h
@@ -0,0 +1,309 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#ifndef __VLV_DPIO_PHY_REGS_H__
+#define __VLV_DPIO_PHY_REGS_H__
+
+#include "intel_display_reg_defs.h"
+
+#define _VLV_CMN(dw) (0x8100 + (dw) * 4)
+#define _CHV_CMN(cl, dw) (0x8100 - (cl) * 0x80 + (dw) * 4)
+#define _VLV_PLL(ch, dw) (0x8000 + (ch) * 0x20 + (dw) * 4) /* dw 0-7,16-23 */
+#define _CHV_PLL(ch, dw) (0x8000 + (ch) * 0x180 + (dw) * 4)
+#define _VLV_REF(dw) (0x80a0 + ((dw) - 8) * 4) /* dw 8-15 */
+#define _VLV_PCS(ch, spline, dw) (0x200 + (ch) * 0x2400 + (spline) * 0x200 + 
(dw) * 4)
+#define _VLV_PCS_GRP(ch, dw) (0x8200 + (ch) * 0x200 + (dw) * 4)
+#define _VLV_PCS_BCAST(dw) (0xc000 + (dw) * 4)
+#define _VLV_TX(ch, lane, dw) (0x80 + (ch) * 0x2400 + (lane) * 0x200 + (dw) * 
4)
+#define _VLV_TX_GRP(ch, dw) (0x8280 + (ch) * 0x200 + (dw) * 4)
+#define _VLV_TX_BCAST(dw) (0xc080 + (dw) * 4)
+
+/*
+ * Per pipe/PLL DPIO regs
+ */
+#define VLV_PLL_DW3(ch)_VLV_PLL((ch), 3)
+#define   DPIO_S1_DIV_MASK REG_GENMASK(30, 28)
+#define   DPIO_S1_DIV(s1)  REG_FIELD_PREP(DPIO_S1_DIV_MASK, (s1))
+#define   DPIO_S1_DIV_DAC  0 /* 10, DAC 25-225M rate */
+#define   DPIO_S1_DIV_HDMIDP   1 /* 5, DAC 225-400M rate */
+#define   DPIO_S1_DIV_LVDS12 /* 14 */
+#define   DPIO_S1_DIV_LVDS23 /* 7 */
+#define   DPIO_K_DIV_MASK  REG_GENMASK(27, 24)
+#define   DPIO_K_DIV(k)REG_FIELD_PREP(DPIO_K_DIV_MASK, 
(k))
+#define   DPIO_P1_DIV_MASK REG_GENMASK(23, 21)
+#define   DPIO_P1_DIV(p1)  REG_FIELD_PREP(DPIO_P1_DIV_MASK, (p1))
+#define   DPIO_P2_DIV_MASK REG_GENMASK(20, 16)
+#define   DPIO_P2_DIV(p2)  REG_FIELD_PREP(DPIO_P2_DIV_MASK, (p2))
+#define   DPIO_N_DIV_MASK  REG_GENMASK(15, 12)
+#define   DPIO_N_DIV(n)REG_FIELD_PREP(DPIO_N_DIV_MASK, 
(n))
+#define   DPIO_ENABLE_CALIBRATION  REG_BIT(11)
+#define   DPIO_M1_DIV_MASK REG_GENMASK(10, 8)
+#define   DPIO_M1_DIV(m1)  REG_FIELD_PREP(DPIO_M1_DIV_MASK, (m1))
+#define   DPIO_M2_DIV_MASK REG_GENMASK(7, 0)
+#define   DPIO_M2_DIV(m2)  REG_FIELD_PREP(DPIO_M2_DIV_MASK, (m2))
+
+#define VLV_PLL_DW5(ch)_VLV_PLL((ch), 5)
+#define   

[PATCH 13/14] drm/i915/dpio: Clean up the vlv/chv PHY register bits

2024-04-22 Thread Ville Syrjala
From: Ville Syrjälä 

Use REG_BIT() & co. for the vlv/chv DPIO PHY registers.

Signed-off-by: Ville Syrjälä 
---
 .../i915/display/intel_display_power_well.c   |   7 +-
 drivers/gpu/drm/i915/display/intel_dpio_phy.c |  59 ++--
 drivers/gpu/drm/i915/display/intel_dpll.c |  85 +++--
 drivers/gpu/drm/i915/i915_reg.h   | 294 ++
 4 files changed, 236 insertions(+), 209 deletions(-)

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 49114afc9a61..e4ba6efc90e6 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power_well.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c
@@ -1553,10 +1553,11 @@ static void assert_chv_phy_powergate(struct 
drm_i915_private *dev_priv, enum dpi
}
 
if (ch == DPIO_CH0)
-   actual = val >> DPIO_ANYDL_POWERDOWN_SHIFT_CH0;
+   actual = REG_FIELD_GET(DPIO_ANYDL_POWERDOWN_CH0 |
+  DPIO_ALLDL_POWERDOWN_CH0, val);
else
-   actual = val >> DPIO_ANYDL_POWERDOWN_SHIFT_CH1;
-   actual &= DPIO_ALLDL_POWERDOWN | DPIO_ANYDL_POWERDOWN;
+   actual = REG_FIELD_GET(DPIO_ANYDL_POWERDOWN_CH1 |
+  DPIO_ALLDL_POWERDOWN_CH1, val);
 
drm_WARN(_priv->drm, actual != expected,
 "Unexpected DPIO lane power down: all %d, any %d. Expected: 
all %d, any %d. (0x%x = 0x%08x)\n",
diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c 
b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
index fa665d353df9..11875d18a8fc 100644
--- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
@@ -757,7 +757,7 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
for (i = 0; i < crtc_state->lane_count; i++) {
val = vlv_dpio_read(dev_priv, phy, CHV_TX_DW4(ch, i));
val &= ~DPIO_SWING_DEEMPH9P5_MASK;
-   val |= deemph_reg_value << DPIO_SWING_DEEMPH9P5_SHIFT;
+   val |= DPIO_SWING_DEEMPH9P5(deemph_reg_value);
vlv_dpio_write(dev_priv, phy, CHV_TX_DW4(ch, i), val);
}
 
@@ -766,15 +766,15 @@ void chv_set_phy_signal_level(struct intel_encoder 
*encoder,
val = vlv_dpio_read(dev_priv, phy, CHV_TX_DW2(ch, i));
 
val &= ~DPIO_SWING_MARGIN000_MASK;
-   val |= margin_reg_value << DPIO_SWING_MARGIN000_SHIFT;
+   val |= DPIO_SWING_MARGIN000(margin_reg_value);
 
/*
 * Supposedly this value shouldn't matter when unique transition
 * scale is disabled, but in fact it does matter. Let's just
 * always program the same value and hope it's OK.
 */
-   val &= ~(0xff << DPIO_UNIQ_TRANS_SCALE_SHIFT);
-   val |= 0x9a << DPIO_UNIQ_TRANS_SCALE_SHIFT;
+   val &= ~DPIO_UNIQ_TRANS_SCALE_MASK;
+   val |= DPIO_UNIQ_TRANS_SCALE(0x9a);
 
vlv_dpio_write(dev_priv, phy, CHV_TX_DW2(ch, i), val);
}
@@ -902,20 +902,20 @@ void chv_phy_pre_pll_enable(struct intel_encoder *encoder,
 
/* program clock channel usage */
val = vlv_dpio_read(dev_priv, phy, VLV_PCS01_DW8(ch));
-   val |= CHV_PCS_USEDCLKCHANNEL_OVRRIDE;
-   if (pipe != PIPE_B)
-   val &= ~CHV_PCS_USEDCLKCHANNEL;
+   val |= DPIO_PCS_USEDCLKCHANNEL_OVRRIDE;
+   if (pipe == PIPE_B)
+   val |= DPIO_PCS_USEDCLKCHANNEL;
else
-   val |= CHV_PCS_USEDCLKCHANNEL;
+   val &= ~DPIO_PCS_USEDCLKCHANNEL;
vlv_dpio_write(dev_priv, phy, VLV_PCS01_DW8(ch), val);
 
if (crtc_state->lane_count > 2) {
val = vlv_dpio_read(dev_priv, phy, VLV_PCS23_DW8(ch));
-   val |= CHV_PCS_USEDCLKCHANNEL_OVRRIDE;
-   if (pipe != PIPE_B)
-   val &= ~CHV_PCS_USEDCLKCHANNEL;
+   val |= DPIO_PCS_USEDCLKCHANNEL_OVRRIDE;
+   if (pipe == PIPE_B)
+   val |= DPIO_PCS_USEDCLKCHANNEL;
else
-   val |= CHV_PCS_USEDCLKCHANNEL;
+   val &= ~DPIO_PCS_USEDCLKCHANNEL;
vlv_dpio_write(dev_priv, phy, VLV_PCS23_DW8(ch), val);
}
 
@@ -925,10 +925,10 @@ void chv_phy_pre_pll_enable(struct intel_encoder *encoder,
 * pick the CL based on the port.
 */
val = vlv_dpio_read(dev_priv, phy, CHV_CMN_DW19(ch));
-   if (pipe != PIPE_B)
-   val &= ~CHV_CMN_USEDCLKCHANNEL;
-   else
+   if (pipe == PIPE_B)
val |= CHV_CMN_USEDCLKCHANNEL;
+   else
+   val &= ~CHV_CMN_USEDCLKCHANNEL;
vlv_dpio_write(dev_priv, phy, CHV_CMN_DW19(ch), val);
 
vlv_dpio_put(dev_priv);
@@ -962,11 +962,10 @@ void chv_phy_pre_encoder_enable(struct intel_encoder 
*encoder,
for (i = 0; i 

[PATCH 12/14] drm/i915/dpio: Clean up VLV/CHV DPIO PHY register defines

2024-04-22 Thread Ville Syrjala
From: Ville Syrjälä 

The DPIO PHY registers follow clear numbering rules. Express
those in a few macros to get rid of the hand calculated
final offsets.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpio_phy.c |   2 +-
 drivers/gpu/drm/i915/i915_reg.h   | 271 +++---
 2 files changed, 99 insertions(+), 174 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c 
b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
index 89a51b420075..fa665d353df9 100644
--- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
@@ -1078,7 +1078,7 @@ void vlv_set_phy_signal_level(struct intel_encoder 
*encoder,
vlv_dpio_write(dev_priv, phy, VLV_TX_DW3_GRP(ch), 0x0C782040);
 
if (tx3_demph)
-   vlv_dpio_write(dev_priv, phy, VLV_TX3_DW4(ch), tx3_demph);
+   vlv_dpio_write(dev_priv, phy, VLV_TX_DW4(ch, 3), tx3_demph);
 
vlv_dpio_write(dev_priv, phy, VLV_PCS_DW11_GRP(ch), 0x0003);
vlv_dpio_write(dev_priv, phy, VLV_PCS_DW9_GRP(ch), preemph_reg_value);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index b24ce3cff1a0..6d16f9944eff 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -195,10 +195,22 @@
 #define  DPIO_SFR_BYPASS   (1 << 1)
 #define  DPIO_CMNRST   (1 << 0)
 
+#define _VLV_CMN(dw) (0x8100 + (dw) * 4)
+#define _CHV_CMN(cl, dw) (0x8100 - (cl) * 0x80 + (dw) * 4)
+#define _VLV_PLL(ch, dw) (0x8000 + (ch) * 0x20 + (dw) * 4) /* dw 0-7,16-23 */
+#define _CHV_PLL(ch, dw) (0x8000 + (ch) * 0x180 + (dw) * 4)
+#define _VLV_REF(dw) (0x80a0 + ((dw) - 8) * 4) /* dw 8-15 */
+#define _VLV_PCS(ch, spline, dw) (0x200 + (ch) * 0x2400 + (spline) * 0x200 + 
(dw) * 4)
+#define _VLV_PCS_GRP(ch, dw) (0x8200 + (ch) * 0x200 + (dw) * 4)
+#define _VLV_PCS_BCAST(dw) (0xc000 + (dw) * 4)
+#define _VLV_TX(ch, lane, dw) (0x80 + (ch) * 0x2400 + (lane) * 0x200 + (dw) * 
4)
+#define _VLV_TX_GRP(ch, dw) (0x8280 + (ch) * 0x200 + (dw) * 4)
+#define _VLV_TX_BCAST(dw) (0xc080 + (dw) * 4)
+
 /*
  * Per pipe/PLL DPIO regs
  */
-#define _VLV_PLL_DW3_CH0   0x800c
+#define VLV_PLL_DW3(ch)_VLV_PLL((ch), 3)
 #define   DPIO_POST_DIV_SHIFT  (28) /* 3 bits */
 #define   DPIO_POST_DIV_DAC0
 #define   DPIO_POST_DIV_HDMIDP 1 /* DAC 225-400M rate */
@@ -211,10 +223,8 @@
 #define   DPIO_ENABLE_CALIBRATION  (1 << 11)
 #define   DPIO_M1DIV_SHIFT (8) /* 3 bits */
 #define   DPIO_M2DIV_MASK  0xff
-#define _VLV_PLL_DW3_CH1   0x802c
-#define VLV_PLL_DW3(ch) _PIPE(ch, _VLV_PLL_DW3_CH0, _VLV_PLL_DW3_CH1)
 
-#define _VLV_PLL_DW5_CH0   0x8014
+#define VLV_PLL_DW5(ch)_VLV_PLL((ch), 5)
 #define   DPIO_REFSEL_OVERRIDE 27
 #define   DPIO_PLL_MODESEL_SHIFT   24 /* 3 bits */
 #define   DPIO_BIAS_CURRENT_CTL_SHIFT  21 /* 3 bits, always 0x7 */
@@ -222,101 +232,60 @@
 #define   DPIO_PLL_REFCLK_SEL_MASK 3
 #define   DPIO_DRIVER_CTL_SHIFT12 /* always set to 0x8 */
 #define   DPIO_CLK_BIAS_CTL_SHIFT  8 /* always set to 0x5 */
-#define _VLV_PLL_DW5_CH1   0x8034
-#define VLV_PLL_DW5(ch) _PIPE(ch, _VLV_PLL_DW5_CH0, _VLV_PLL_DW5_CH1)
 
-#define _VLV_PLL_DW7_CH0   0x801c
-#define _VLV_PLL_DW7_CH1   0x803c
-#define VLV_PLL_DW7(ch) _PIPE(ch, _VLV_PLL_DW7_CH0, _VLV_PLL_DW7_CH1)
+#define VLV_PLL_DW7(ch)_VLV_PLL((ch), 7)
 
-#define _VLV_PLL_DW16_CH0  0x8040
-#define _VLV_PLL_DW16_CH1  0x8060
-#define VLV_PLL_DW16(ch) _PIPE(ch, _VLV_PLL_DW16_CH0, _VLV_PLL_DW16_CH1)
+#define VLV_PLL_DW16(ch)   _VLV_PLL((ch), 16)
 
-#define _VLV_PLL_DW17_CH0  0x8044
-#define _VLV_PLL_DW17_CH1  0x8064
-#define VLV_PLL_DW17(ch) _PIPE(ch, _VLV_PLL_DW17_CH0, _VLV_PLL_DW17_CH1)
+#define VLV_PLL_DW17(ch)   _VLV_PLL((ch), 17)
 
-#define _VLV_PLL_DW18_CH0  0x8048
-#define _VLV_PLL_DW18_CH1  0x8068
-#define VLV_PLL_DW18(ch) _PIPE(ch, _VLV_PLL_DW18_CH0, _VLV_PLL_DW18_CH1)
+#define VLV_PLL_DW18(ch)   _VLV_PLL((ch), 18)
 
-#define _VLV_PLL_DW19_CH0  0x804c
-#define _VLV_PLL_DW19_CH1  0x806c
-#define VLV_PLL_DW19(ch) _PIPE(ch, _VLV_PLL_DW19_CH0, _VLV_PLL_DW19_CH1)
+#define VLV_PLL_DW19(ch)   _VLV_PLL((ch), 19)
 
-/* Spec for ref block start counts at DW8 */
-#define VLV_REF_DW11   0x80ac
+#define VLV_REF_DW11   _VLV_REF(11)
 
-#define VLV_CMN_DW00x8100
+#define VLV_CMN_DW0_VLV_CMN(0)
 
 /*
  * Per DDI channel DPIO regs
  */
-
-#define _VLV_PCS_DW0_CH0_GRP   0x8200
-#define _VLV_PCS_DW0_CH1_GRP   0x8400
+#define VLV_PCS_DW0_GRP(ch)_VLV_PCS_GRP((ch), 0)
+#define VLV_PCS01_DW0(ch)  _VLV_PCS((ch), 0, 0)

[PATCH 11/14] drm/i915/dpio: Rename a few CHV DPIO PHY registers

2024-04-22 Thread Ville Syrjala
From: Ville Syrjälä 

Drop the leading underscore from the CHV PHY common lane
register definitons. We use these directly from actual
code so the underscore here is misleading as usually it indicates
an intermediate define that shouldn't be used directly.

Signed-off-by: Ville Syrjälä 
---
 .../i915/display/intel_display_power_well.c   |  8 +++
 drivers/gpu/drm/i915/display/intel_dpio_phy.c | 16 ++---
 drivers/gpu/drm/i915/i915_reg.h   | 23 +--
 3 files changed, 23 insertions(+), 24 deletions(-)

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 e8a6e53fd551..49114afc9a61 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power_well.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c
@@ -1442,9 +1442,9 @@ static void chv_dpio_cmn_power_well_enable(struct 
drm_i915_private *dev_priv,
vlv_dpio_write(dev_priv, phy, CHV_CMN_DW28, tmp);
 
if (id == VLV_DISP_PW_DPIO_CMN_BC) {
-   tmp = vlv_dpio_read(dev_priv, phy, _CHV_CMN_DW6_CH1);
+   tmp = vlv_dpio_read(dev_priv, phy, CHV_CMN_DW6_CH1);
tmp |= DPIO_DYNPWRDOWNEN_CH1;
-   vlv_dpio_write(dev_priv, phy, _CHV_CMN_DW6_CH1, tmp);
+   vlv_dpio_write(dev_priv, phy, CHV_CMN_DW6_CH1, tmp);
} else {
/*
 * Force the non-existing CL2 off. BXT does this
@@ -1520,9 +1520,9 @@ static void assert_chv_phy_powergate(struct 
drm_i915_private *dev_priv, enum dpi
return;
 
if (ch == DPIO_CH0)
-   reg = _CHV_CMN_DW0_CH0;
+   reg = CHV_CMN_DW0_CH0;
else
-   reg = _CHV_CMN_DW6_CH1;
+   reg = CHV_CMN_DW6_CH1;
 
vlv_dpio_get(dev_priv);
val = vlv_dpio_read(dev_priv, phy, reg);
diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c 
b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
index 791902ba729c..89a51b420075 100644
--- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
@@ -883,21 +883,21 @@ void chv_phy_pre_pll_enable(struct intel_encoder *encoder,
 
/* program left/right clock distribution */
if (pipe != PIPE_B) {
-   val = vlv_dpio_read(dev_priv, phy, _CHV_CMN_DW5_CH0);
+   val = vlv_dpio_read(dev_priv, phy, CHV_CMN_DW5_CH0);
val &= ~(CHV_BUFLEFTENA1_MASK | CHV_BUFRIGHTENA1_MASK);
if (ch == DPIO_CH0)
val |= CHV_BUFLEFTENA1_FORCE;
if (ch == DPIO_CH1)
val |= CHV_BUFRIGHTENA1_FORCE;
-   vlv_dpio_write(dev_priv, phy, _CHV_CMN_DW5_CH0, val);
+   vlv_dpio_write(dev_priv, phy, CHV_CMN_DW5_CH0, val);
} else {
-   val = vlv_dpio_read(dev_priv, phy, _CHV_CMN_DW1_CH1);
+   val = vlv_dpio_read(dev_priv, phy, CHV_CMN_DW1_CH1);
val &= ~(CHV_BUFLEFTENA2_MASK | CHV_BUFRIGHTENA2_MASK);
if (ch == DPIO_CH0)
val |= CHV_BUFLEFTENA2_FORCE;
if (ch == DPIO_CH1)
val |= CHV_BUFRIGHTENA2_FORCE;
-   vlv_dpio_write(dev_priv, phy, _CHV_CMN_DW1_CH1, val);
+   vlv_dpio_write(dev_priv, phy, CHV_CMN_DW1_CH1, val);
}
 
/* program clock channel usage */
@@ -1036,13 +1036,13 @@ void chv_phy_post_pll_disable(struct intel_encoder 
*encoder,
 
/* disable left/right clock distribution */
if (pipe != PIPE_B) {
-   val = vlv_dpio_read(dev_priv, phy, _CHV_CMN_DW5_CH0);
+   val = vlv_dpio_read(dev_priv, phy, CHV_CMN_DW5_CH0);
val &= ~(CHV_BUFLEFTENA1_MASK | CHV_BUFRIGHTENA1_MASK);
-   vlv_dpio_write(dev_priv, phy, _CHV_CMN_DW5_CH0, val);
+   vlv_dpio_write(dev_priv, phy, CHV_CMN_DW5_CH0, val);
} else {
-   val = vlv_dpio_read(dev_priv, phy, _CHV_CMN_DW1_CH1);
+   val = vlv_dpio_read(dev_priv, phy, CHV_CMN_DW1_CH1);
val &= ~(CHV_BUFLEFTENA2_MASK | CHV_BUFRIGHTENA2_MASK);
-   vlv_dpio_write(dev_priv, phy, _CHV_CMN_DW1_CH1, val);
+   vlv_dpio_write(dev_priv, phy, CHV_CMN_DW1_CH1, val);
}
 
vlv_dpio_put(dev_priv);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 3804ef4697d5..b24ce3cff1a0 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -459,13 +459,13 @@
 #define  DPIO_CHV_INT_LOCK_THRESHOLD_SEL_COARSE1 /* 1: coarse & 0 : 
fine  */
 #define CHV_PLL_DW9(ch) _PIPE(ch, _CHV_PLL_DW9_CH0, _CHV_PLL_DW9_CH1)
 
-#define _CHV_CMN_DW0_CH0   0x8100
+#define CHV_CMN_DW0_CH00x8100
 #define   DPIO_ALLDL_POWERDOWN_SHIFT_CH0   19
 #define   DPIO_ANYDL_POWERDOWN_SHIFT_CH0   18
 #define   DPIO_ALLDL_POWERDOWN (1 << 1)
 

[PATCH 09/14] drm/i915/dpio: Derive the phy from the port rather than pipe in encoder hooks

2024-04-22 Thread Ville Syrjala
From: Ville Syrjälä 

In the encoder hooks we are dealing primarily with the encoder,
so derive the DPIO PHY from the encoder rather than the pipe.
Technically this doesn't matter as we can't cross connect
pipes<->port across PHY boundaries, but it does conveny the
intention more accurately.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpio_phy.c | 27 ---
 drivers/gpu/drm/i915/vlv_sideband.c   |  1 -
 2 files changed, 11 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c 
b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
index e4a04c9b5b19..4fafac534967 100644
--- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
@@ -719,9 +719,8 @@ void chv_set_phy_signal_level(struct intel_encoder *encoder,
 {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
-   struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
enum dpio_channel ch = vlv_dig_port_to_channel(dig_port);
-   enum dpio_phy phy = vlv_pipe_to_phy(crtc->pipe);
+   enum dpio_phy phy = vlv_dig_port_to_phy(dig_port);
u32 val;
int i;
 
@@ -814,9 +813,9 @@ void chv_data_lane_soft_reset(struct intel_encoder *encoder,
  bool reset)
 {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-   struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-   enum dpio_channel ch = 
vlv_dig_port_to_channel(enc_to_dig_port(encoder));
-   enum dpio_phy phy = vlv_pipe_to_phy(crtc->pipe);
+   struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+   enum dpio_channel ch = vlv_dig_port_to_channel(dig_port);
+   enum dpio_phy phy = vlv_dig_port_to_phy(dig_port);
u32 val;
 
val = vlv_dpio_read(dev_priv, phy, VLV_PCS01_DW0(ch));
@@ -861,7 +860,7 @@ void chv_phy_pre_pll_enable(struct intel_encoder *encoder,
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
enum dpio_channel ch = vlv_dig_port_to_channel(dig_port);
-   enum dpio_phy phy = vlv_pipe_to_phy(crtc->pipe);
+   enum dpio_phy phy = vlv_dig_port_to_phy(dig_port);
enum pipe pipe = crtc->pipe;
unsigned int lane_mask =
intel_dp_unused_lane_mask(crtc_state->lane_count);
@@ -941,9 +940,8 @@ void chv_phy_pre_encoder_enable(struct intel_encoder 
*encoder,
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-   struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
enum dpio_channel ch = vlv_dig_port_to_channel(dig_port);
-   enum dpio_phy phy = vlv_pipe_to_phy(crtc->pipe);
+   enum dpio_phy phy = vlv_dig_port_to_phy(dig_port);
int data, i, stagger;
u32 val;
 
@@ -1030,8 +1028,8 @@ void chv_phy_post_pll_disable(struct intel_encoder 
*encoder,
  const struct intel_crtc_state *old_crtc_state)
 {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+   enum dpio_phy phy = vlv_dig_port_to_phy(enc_to_dig_port(encoder));
enum pipe pipe = to_intel_crtc(old_crtc_state->uapi.crtc)->pipe;
-   enum dpio_phy phy = vlv_pipe_to_phy(pipe);
u32 val;
 
vlv_dpio_get(dev_priv);
@@ -1068,9 +1066,8 @@ void vlv_set_phy_signal_level(struct intel_encoder 
*encoder,
 {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
-   struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
enum dpio_channel ch = vlv_dig_port_to_channel(dig_port);
-   enum dpio_phy phy = vlv_pipe_to_phy(crtc->pipe);
+   enum dpio_phy phy = vlv_dig_port_to_phy(dig_port);
 
vlv_dpio_get(dev_priv);
 
@@ -1095,9 +1092,8 @@ void vlv_phy_pre_pll_enable(struct intel_encoder *encoder,
 {
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-   struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
enum dpio_channel ch = vlv_dig_port_to_channel(dig_port);
-   enum dpio_phy phy = vlv_pipe_to_phy(crtc->pipe);
+   enum dpio_phy phy = vlv_dig_port_to_phy(dig_port);
 
/* Program Tx lane resets to default */
vlv_dpio_get(dev_priv);
@@ -1127,8 +1123,8 @@ void vlv_phy_pre_encoder_enable(struct intel_encoder 
*encoder,
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
enum dpio_channel ch = vlv_dig_port_to_channel(dig_port);
+   enum dpio_phy phy = 

[PATCH 10/14] drm/i915/dpio: Give VLV DPIO group register a clearer name

2024-04-22 Thread Ville Syrjala
From: Ville Syrjälä 

Include _GRP in VLV DPOP PHY group access register define
names. Makes it more obvious where the accesses will land.
Also matches the naming used by BXT already.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpio_phy.c | 34 +++
 drivers/gpu/drm/i915/i915_reg.h   | 90 +--
 2 files changed, 62 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c 
b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
index 4fafac534967..791902ba729c 100644
--- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
@@ -1071,18 +1071,18 @@ void vlv_set_phy_signal_level(struct intel_encoder 
*encoder,
 
vlv_dpio_get(dev_priv);
 
-   vlv_dpio_write(dev_priv, phy, VLV_TX_DW5(ch), 0x);
-   vlv_dpio_write(dev_priv, phy, VLV_TX_DW4(ch), demph_reg_value);
-   vlv_dpio_write(dev_priv, phy, VLV_TX_DW2(ch),
+   vlv_dpio_write(dev_priv, phy, VLV_TX_DW5_GRP(ch), 0x);
+   vlv_dpio_write(dev_priv, phy, VLV_TX_DW4_GRP(ch), demph_reg_value);
+   vlv_dpio_write(dev_priv, phy, VLV_TX_DW2_GRP(ch),
 uniqtranscale_reg_value);
-   vlv_dpio_write(dev_priv, phy, VLV_TX_DW3(ch), 0x0C782040);
+   vlv_dpio_write(dev_priv, phy, VLV_TX_DW3_GRP(ch), 0x0C782040);
 
if (tx3_demph)
vlv_dpio_write(dev_priv, phy, VLV_TX3_DW4(ch), tx3_demph);
 
-   vlv_dpio_write(dev_priv, phy, VLV_PCS_DW11(ch), 0x0003);
-   vlv_dpio_write(dev_priv, phy, VLV_PCS_DW9(ch), preemph_reg_value);
-   vlv_dpio_write(dev_priv, phy, VLV_TX_DW5(ch), DPIO_TX_OCALINIT_EN);
+   vlv_dpio_write(dev_priv, phy, VLV_PCS_DW11_GRP(ch), 0x0003);
+   vlv_dpio_write(dev_priv, phy, VLV_PCS_DW9_GRP(ch), preemph_reg_value);
+   vlv_dpio_write(dev_priv, phy, VLV_TX_DW5_GRP(ch), DPIO_TX_OCALINIT_EN);
 
vlv_dpio_put(dev_priv);
 }
@@ -1098,19 +1098,19 @@ void vlv_phy_pre_pll_enable(struct intel_encoder 
*encoder,
/* Program Tx lane resets to default */
vlv_dpio_get(dev_priv);
 
-   vlv_dpio_write(dev_priv, phy, VLV_PCS_DW0(ch),
+   vlv_dpio_write(dev_priv, phy, VLV_PCS_DW0_GRP(ch),
 DPIO_PCS_TX_LANE2_RESET |
 DPIO_PCS_TX_LANE1_RESET);
-   vlv_dpio_write(dev_priv, phy, VLV_PCS_DW1(ch),
+   vlv_dpio_write(dev_priv, phy, VLV_PCS_DW1_GRP(ch),
 DPIO_PCS_CLK_CRI_RXEB_EIOS_EN |
 DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN |
 (1<

[PATCH 06/14] drm/i915/dpio: Rename some variables

2024-04-22 Thread Ville Syrjala
From: Ville Syrjälä 

Use a constent 'tmp' as the variable name for the register
values during rmw when we don't deal with multiple registers
in parallel.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpll.c | 97 +++
 1 file changed, 48 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c 
b/drivers/gpu/drm/i915/display/intel_dpll.c
index 01f800b6b30e..0a738b491c40 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll.c
@@ -514,23 +514,23 @@ void vlv_crtc_clock_get(struct intel_crtc_state 
*crtc_state)
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum dpio_phy phy = vlv_pipe_to_phy(crtc->pipe);
const struct i9xx_dpll_hw_state *hw_state = 
_state->dpll_hw_state.i9xx;
-   struct dpll clock;
-   u32 mdiv;
int refclk = 10;
+   struct dpll clock;
+   u32 tmp;
 
/* In case of DSI, DPLL will not be used */
if ((hw_state->dpll & DPLL_VCO_ENABLE) == 0)
return;
 
vlv_dpio_get(dev_priv);
-   mdiv = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW3(crtc->pipe));
+   tmp = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW3(crtc->pipe));
vlv_dpio_put(dev_priv);
 
-   clock.m1 = (mdiv >> DPIO_M1DIV_SHIFT) & 7;
-   clock.m2 = mdiv & DPIO_M2DIV_MASK;
-   clock.n = (mdiv >> DPIO_N_SHIFT) & 0xf;
-   clock.p1 = (mdiv >> DPIO_P1_SHIFT) & 7;
-   clock.p2 = (mdiv >> DPIO_P2_SHIFT) & 0x1f;
+   clock.m1 = (tmp >> DPIO_M1DIV_SHIFT) & 7;
+   clock.m2 = tmp & DPIO_M2DIV_MASK;
+   clock.n = (tmp >> DPIO_N_SHIFT) & 0xf;
+   clock.p1 = (tmp >> DPIO_P1_SHIFT) & 7;
+   clock.p2 = (tmp >> DPIO_P2_SHIFT) & 0x1f;
 
crtc_state->port_clock = vlv_calc_dpll_params(refclk, );
 }
@@ -1869,30 +1869,30 @@ void i9xx_enable_pll(const struct intel_crtc_state 
*crtc_state)
 static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv,
 enum dpio_phy phy)
 {
-   u32 reg_val;
+   u32 tmp;
 
/*
 * PLLB opamp always calibrates to max value of 0x3f, force enable it
 * and set it to a reasonable value instead.
 */
-   reg_val = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW17(1));
-   reg_val &= 0xff00;
-   reg_val |= 0x0030;
-   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW17(1), reg_val);
+   tmp = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW17(1));
+   tmp &= 0xff00;
+   tmp |= 0x0030;
+   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW17(1), tmp);
 
-   reg_val = vlv_dpio_read(dev_priv, phy, VLV_REF_DW11);
-   reg_val &= 0x00ff;
-   reg_val |= 0x8c00;
-   vlv_dpio_write(dev_priv, phy, VLV_REF_DW11, reg_val);
+   tmp = vlv_dpio_read(dev_priv, phy, VLV_REF_DW11);
+   tmp &= 0x00ff;
+   tmp |= 0x8c00;
+   vlv_dpio_write(dev_priv, phy, VLV_REF_DW11, tmp);
 
-   reg_val = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW17(1));
-   reg_val &= 0xff00;
-   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW17(1), reg_val);
+   tmp = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW17(1));
+   tmp &= 0xff00;
+   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW17(1), tmp);
 
-   reg_val = vlv_dpio_read(dev_priv, phy, VLV_REF_DW11);
-   reg_val &= 0x00ff;
-   reg_val |= 0xb000;
-   vlv_dpio_write(dev_priv, phy, VLV_REF_DW11, reg_val);
+   tmp = vlv_dpio_read(dev_priv, phy, VLV_REF_DW11);
+   tmp &= 0x00ff;
+   tmp |= 0xb000;
+   vlv_dpio_write(dev_priv, phy, VLV_REF_DW11, tmp);
 }
 
 static void vlv_prepare_pll(const struct intel_crtc_state *crtc_state)
@@ -1902,7 +1902,7 @@ static void vlv_prepare_pll(const struct intel_crtc_state 
*crtc_state)
const struct dpll *clock = _state->dpll;
enum dpio_phy phy = vlv_pipe_to_phy(crtc->pipe);
enum pipe pipe = crtc->pipe;
-   u32 mdiv, coreclk, reg_val;
+   u32 tmp, coreclk;
 
vlv_dpio_get(dev_priv);
 
@@ -1916,15 +1916,15 @@ static void vlv_prepare_pll(const struct 
intel_crtc_state *crtc_state)
vlv_dpio_write(dev_priv, phy, VLV_PCS_DW17_BCAST, 0x010f);
 
/* Disable target IRef on PLL */
-   reg_val = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW16(pipe));
-   reg_val &= 0x00ff;
-   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW16(pipe), reg_val);
+   tmp = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW16(pipe));
+   tmp &= 0x00ff;
+   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW16(pipe), tmp);
 
/* Disable fast lock */
vlv_dpio_write(dev_priv, phy, VLV_CMN_DW0, 0x610);
 
/* Set idtafcrecal before PLL is enabled */
-   mdiv = (clock->m1 << DPIO_M1DIV_SHIFT) |
+   tmp = (clock->m1 << DPIO_M1DIV_SHIFT) |
(clock->m2 & DPIO_M2DIV_MASK) |
(clock->p1 << DPIO_P1_SHIFT) |
(clock->p2 << DPIO_P2_SHIFT) |
@@ -1936,11 +1936,11 

[PATCH 08/14] drm/i915/dpio: s/pipe/ch/

2024-04-22 Thread Ville Syrjala
From: Ville Syrjälä 

Stop using 'pipe' directly as the DPIO PHY channel. This
does happen to work on VLV since it just has the one PHY
with CH0==pipe A and CH1==pipe B. But explicitly converting
the thing to the right enum makes the whole thing less
confusing.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpll.c | 49 ---
 1 file changed, 25 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c 
b/drivers/gpu/drm/i915/display/intel_dpll.c
index 743cc466ee39..861f4a735251 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll.c
@@ -512,6 +512,7 @@ void vlv_crtc_clock_get(struct intel_crtc_state *crtc_state)
 {
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+   enum dpio_channel ch = vlv_pipe_to_channel(crtc->pipe);
enum dpio_phy phy = vlv_pipe_to_phy(crtc->pipe);
const struct i9xx_dpll_hw_state *hw_state = 
_state->dpll_hw_state.i9xx;
int refclk = 10;
@@ -523,7 +524,7 @@ void vlv_crtc_clock_get(struct intel_crtc_state *crtc_state)
return;
 
vlv_dpio_get(dev_priv);
-   tmp = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW3(crtc->pipe));
+   tmp = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW3(ch));
vlv_dpio_put(dev_priv);
 
clock.m1 = (tmp >> DPIO_M1DIV_SHIFT) & 7;
@@ -1867,7 +1868,7 @@ void i9xx_enable_pll(const struct intel_crtc_state 
*crtc_state)
 }
 
 static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv,
-enum dpio_phy phy)
+enum dpio_phy phy, enum dpio_channel ch)
 {
u32 tmp;
 
@@ -1875,19 +1876,19 @@ static void vlv_pllb_recal_opamp(struct 
drm_i915_private *dev_priv,
 * PLLB opamp always calibrates to max value of 0x3f, force enable it
 * and set it to a reasonable value instead.
 */
-   tmp = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW17(1));
+   tmp = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW17(ch));
tmp &= 0xff00;
tmp |= 0x0030;
-   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW17(1), tmp);
+   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW17(ch), tmp);
 
tmp = vlv_dpio_read(dev_priv, phy, VLV_REF_DW11);
tmp &= 0x00ff;
tmp |= 0x8c00;
vlv_dpio_write(dev_priv, phy, VLV_REF_DW11, tmp);
 
-   tmp = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW17(1));
+   tmp = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW17(ch));
tmp &= 0xff00;
-   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW17(1), tmp);
+   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW17(ch), tmp);
 
tmp = vlv_dpio_read(dev_priv, phy, VLV_REF_DW11);
tmp &= 0x00ff;
@@ -1900,6 +1901,7 @@ static void vlv_prepare_pll(const struct intel_crtc_state 
*crtc_state)
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
const struct dpll *clock = _state->dpll;
+   enum dpio_channel ch = vlv_pipe_to_channel(crtc->pipe);
enum dpio_phy phy = vlv_pipe_to_phy(crtc->pipe);
enum pipe pipe = crtc->pipe;
u32 tmp, coreclk;
@@ -1910,15 +1912,15 @@ static void vlv_prepare_pll(const struct 
intel_crtc_state *crtc_state)
 
/* PLL B needs special handling */
if (pipe == PIPE_B)
-   vlv_pllb_recal_opamp(dev_priv, phy);
+   vlv_pllb_recal_opamp(dev_priv, phy, ch);
 
/* Set up Tx target for periodic Rcomp update */
vlv_dpio_write(dev_priv, phy, VLV_PCS_DW17_BCAST, 0x010f);
 
/* Disable target IRef on PLL */
-   tmp = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW16(pipe));
+   tmp = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW16(ch));
tmp &= 0x00ff;
-   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW16(pipe), tmp);
+   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW16(ch), tmp);
 
/* Disable fast lock */
vlv_dpio_write(dev_priv, phy, VLV_CMN_DW0, 0x610);
@@ -1937,46 +1939,46 @@ static void vlv_prepare_pll(const struct 
intel_crtc_state *crtc_state)
 * Note: don't use the DAC post divider as it seems unstable.
 */
tmp |= (DPIO_POST_DIV_HDMIDP << DPIO_POST_DIV_SHIFT);
-   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW3(pipe), tmp);
+   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW3(ch), tmp);
 
tmp |= DPIO_ENABLE_CALIBRATION;
-   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW3(pipe), tmp);
+   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW3(ch), tmp);
 
/* Set HBR and RBR LPF coefficients */
if (crtc_state->port_clock == 162000 ||
intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG) ||
intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
-   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW18(pipe),
+   

[PATCH 07/14] drm/i915/dpio: s/port/ch/

2024-04-22 Thread Ville Syrjala
From: Ville Syrjälä 

Stop calling the DPIO PHY channel "port". Just say "ch", which
is already used in a bunch of places.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpio_phy.c | 44 +++
 drivers/gpu/drm/i915/display/intel_dpll.c | 54 +--
 2 files changed, 49 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c 
b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
index 6cbee88e608f..e4a04c9b5b19 100644
--- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
@@ -1069,23 +1069,23 @@ void vlv_set_phy_signal_level(struct intel_encoder 
*encoder,
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-   enum dpio_channel port = vlv_dig_port_to_channel(dig_port);
+   enum dpio_channel ch = vlv_dig_port_to_channel(dig_port);
enum dpio_phy phy = vlv_pipe_to_phy(crtc->pipe);
 
vlv_dpio_get(dev_priv);
 
-   vlv_dpio_write(dev_priv, phy, VLV_TX_DW5(port), 0x);
-   vlv_dpio_write(dev_priv, phy, VLV_TX_DW4(port), demph_reg_value);
-   vlv_dpio_write(dev_priv, phy, VLV_TX_DW2(port),
+   vlv_dpio_write(dev_priv, phy, VLV_TX_DW5(ch), 0x);
+   vlv_dpio_write(dev_priv, phy, VLV_TX_DW4(ch), demph_reg_value);
+   vlv_dpio_write(dev_priv, phy, VLV_TX_DW2(ch),
 uniqtranscale_reg_value);
-   vlv_dpio_write(dev_priv, phy, VLV_TX_DW3(port), 0x0C782040);
+   vlv_dpio_write(dev_priv, phy, VLV_TX_DW3(ch), 0x0C782040);
 
if (tx3_demph)
-   vlv_dpio_write(dev_priv, phy, VLV_TX3_DW4(port), tx3_demph);
+   vlv_dpio_write(dev_priv, phy, VLV_TX3_DW4(ch), tx3_demph);
 
-   vlv_dpio_write(dev_priv, phy, VLV_PCS_DW11(port), 0x0003);
-   vlv_dpio_write(dev_priv, phy, VLV_PCS_DW9(port), preemph_reg_value);
-   vlv_dpio_write(dev_priv, phy, VLV_TX_DW5(port), DPIO_TX_OCALINIT_EN);
+   vlv_dpio_write(dev_priv, phy, VLV_PCS_DW11(ch), 0x0003);
+   vlv_dpio_write(dev_priv, phy, VLV_PCS_DW9(ch), preemph_reg_value);
+   vlv_dpio_write(dev_priv, phy, VLV_TX_DW5(ch), DPIO_TX_OCALINIT_EN);
 
vlv_dpio_put(dev_priv);
 }
@@ -1096,25 +1096,25 @@ void vlv_phy_pre_pll_enable(struct intel_encoder 
*encoder,
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-   enum dpio_channel port = vlv_dig_port_to_channel(dig_port);
+   enum dpio_channel ch = vlv_dig_port_to_channel(dig_port);
enum dpio_phy phy = vlv_pipe_to_phy(crtc->pipe);
 
/* Program Tx lane resets to default */
vlv_dpio_get(dev_priv);
 
-   vlv_dpio_write(dev_priv, phy, VLV_PCS_DW0(port),
+   vlv_dpio_write(dev_priv, phy, VLV_PCS_DW0(ch),
 DPIO_PCS_TX_LANE2_RESET |
 DPIO_PCS_TX_LANE1_RESET);
-   vlv_dpio_write(dev_priv, phy, VLV_PCS_DW1(port),
+   vlv_dpio_write(dev_priv, phy, VLV_PCS_DW1(ch),
 DPIO_PCS_CLK_CRI_RXEB_EIOS_EN |
 DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN |
 (1uapi.crtc);
-   enum dpio_channel port = vlv_dig_port_to_channel(dig_port);
+   enum dpio_channel ch = vlv_dig_port_to_channel(dig_port);
enum pipe pipe = crtc->pipe;
enum dpio_phy phy = vlv_pipe_to_phy(pipe);
u32 val;
@@ -1140,11 +1140,11 @@ void vlv_phy_pre_encoder_enable(struct intel_encoder 
*encoder,
else
val &= ~(1<<21);
val |= 0x001000c4;
-   vlv_dpio_write(dev_priv, phy, VLV_PCS_DW8(port), val);
+   vlv_dpio_write(dev_priv, phy, VLV_PCS_DW8(ch), val);
 
/* Program lane clock */
-   vlv_dpio_write(dev_priv, phy, VLV_PCS_DW14(port), 0x00760018);
-   vlv_dpio_write(dev_priv, phy, VLV_PCS_DW23(port), 0x00400888);
+   vlv_dpio_write(dev_priv, phy, VLV_PCS_DW14(ch), 0x00760018);
+   vlv_dpio_write(dev_priv, phy, VLV_PCS_DW23(ch), 0x00400888);
 
vlv_dpio_put(dev_priv);
 }
@@ -1155,11 +1155,11 @@ void vlv_phy_reset_lanes(struct intel_encoder *encoder,
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
-   enum dpio_channel port = vlv_dig_port_to_channel(dig_port);
+   enum dpio_channel ch = vlv_dig_port_to_channel(dig_port);
enum dpio_phy phy = vlv_pipe_to_phy(crtc->pipe);
 
vlv_dpio_get(dev_priv);
-   vlv_dpio_write(dev_priv, phy, VLV_PCS_DW0(port), 0x);
-   

[PATCH 05/14] drm/i915/dpio: Remove pointless variables from vlv/chv DPLL code

2024-04-22 Thread Ville Syrjala
From: Ville Syrjälä 

Drop all the local variables for the DPLL dividers for vlv/chv
and just consult the state directly.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpll.c | 62 ++-
 1 file changed, 27 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c 
b/drivers/gpu/drm/i915/display/intel_dpll.c
index b95032651da0..01f800b6b30e 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll.c
@@ -1899,20 +1899,13 @@ static void vlv_prepare_pll(const struct 
intel_crtc_state *crtc_state)
 {
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+   const struct dpll *clock = _state->dpll;
enum dpio_phy phy = vlv_pipe_to_phy(crtc->pipe);
enum pipe pipe = crtc->pipe;
-   u32 mdiv;
-   u32 bestn, bestm1, bestm2, bestp1, bestp2;
-   u32 coreclk, reg_val;
+   u32 mdiv, coreclk, reg_val;
 
vlv_dpio_get(dev_priv);
 
-   bestn = crtc_state->dpll.n;
-   bestm1 = crtc_state->dpll.m1;
-   bestm2 = crtc_state->dpll.m2;
-   bestp1 = crtc_state->dpll.p1;
-   bestp2 = crtc_state->dpll.p2;
-
/* See eDP HDMI DPIO driver vbios notes doc */
 
/* PLL B needs special handling */
@@ -1931,10 +1924,12 @@ static void vlv_prepare_pll(const struct 
intel_crtc_state *crtc_state)
vlv_dpio_write(dev_priv, phy, VLV_CMN_DW0, 0x610);
 
/* Set idtafcrecal before PLL is enabled */
-   mdiv = ((bestm1 << DPIO_M1DIV_SHIFT) | (bestm2 & DPIO_M2DIV_MASK));
-   mdiv |= ((bestp1 << DPIO_P1_SHIFT) | (bestp2 << DPIO_P2_SHIFT));
-   mdiv |= ((bestn << DPIO_N_SHIFT));
-   mdiv |= (1 << DPIO_K_SHIFT);
+   mdiv = (clock->m1 << DPIO_M1DIV_SHIFT) |
+   (clock->m2 & DPIO_M2DIV_MASK) |
+   (clock->p1 << DPIO_P1_SHIFT) |
+   (clock->p2 << DPIO_P2_SHIFT) |
+   (clock->n << DPIO_N_SHIFT) |
+   (1 << DPIO_K_SHIFT);
 
/*
 * Post divider depends on pixel clock rate, DAC vs digital (and LVDS,
@@ -2030,19 +2025,14 @@ static void chv_prepare_pll(const struct 
intel_crtc_state *crtc_state)
 {
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+   const struct dpll *clock = _state->dpll;
enum pipe pipe = crtc->pipe;
enum dpio_channel port = vlv_pipe_to_channel(pipe);
enum dpio_phy phy = vlv_pipe_to_phy(crtc->pipe);
-   u32 loopfilter, tribuf_calcntr;
-   u32 bestm2, bestp1, bestp2, bestm2_frac;
-   u32 dpio_val;
-   int vco;
+   u32 dpio_val, loopfilter, tribuf_calcntr;
+   u32 m2_frac;
 
-   bestm2_frac = crtc_state->dpll.m2 & 0x3f;
-   bestm2 = crtc_state->dpll.m2 >> 22;
-   bestp1 = crtc_state->dpll.p1;
-   bestp2 = crtc_state->dpll.p2;
-   vco = crtc_state->dpll.vco;
+   m2_frac = clock->m2 & 0x3f;
dpio_val = 0;
loopfilter = 0;
 
@@ -2050,27 +2040,29 @@ static void chv_prepare_pll(const struct 
intel_crtc_state *crtc_state)
 
/* p1 and p2 divider */
vlv_dpio_write(dev_priv, phy, CHV_CMN_DW13(port),
-   5 << DPIO_CHV_S1_DIV_SHIFT |
-   bestp1 << DPIO_CHV_P1_DIV_SHIFT |
-   bestp2 << DPIO_CHV_P2_DIV_SHIFT |
-   1 << DPIO_CHV_K_DIV_SHIFT);
+  5 << DPIO_CHV_S1_DIV_SHIFT |
+  clock->p1 << DPIO_CHV_P1_DIV_SHIFT |
+  clock->p2 << DPIO_CHV_P2_DIV_SHIFT |
+  1 << DPIO_CHV_K_DIV_SHIFT);
 
/* Feedback post-divider - m2 */
-   vlv_dpio_write(dev_priv, phy, CHV_PLL_DW0(port), bestm2);
+   vlv_dpio_write(dev_priv, phy, CHV_PLL_DW0(port),
+  clock->m2 >> 22);
 
/* Feedback refclk divider - n and m1 */
vlv_dpio_write(dev_priv, phy, CHV_PLL_DW1(port),
-   DPIO_CHV_M1_DIV_BY_2 |
-   1 << DPIO_CHV_N_DIV_SHIFT);
+  DPIO_CHV_M1_DIV_BY_2 |
+  1 << DPIO_CHV_N_DIV_SHIFT);
 
/* M2 fraction division */
-   vlv_dpio_write(dev_priv, phy, CHV_PLL_DW2(port), bestm2_frac);
+   vlv_dpio_write(dev_priv, phy, CHV_PLL_DW2(port),
+  m2_frac);
 
/* M2 fraction division enable */
dpio_val = vlv_dpio_read(dev_priv, phy, CHV_PLL_DW3(port));
dpio_val &= ~(DPIO_CHV_FEEDFWD_GAIN_MASK | DPIO_CHV_FRAC_DIV_EN);
dpio_val |= (2 << DPIO_CHV_FEEDFWD_GAIN_SHIFT);
-   if (bestm2_frac)
+   if (m2_frac)
dpio_val |= DPIO_CHV_FRAC_DIV_EN;
vlv_dpio_write(dev_priv, phy, CHV_PLL_DW3(port), dpio_val);
 
@@ -2079,22 +2071,22 @@ static void chv_prepare_pll(const struct 
intel_crtc_state *crtc_state)
dpio_val &= 

[PATCH 04/14] drm/i915/dpio: Fix VLV DPIO PLL register dword numbering

2024-04-22 Thread Ville Syrjala
From: Ville Syrjälä 

The spreadsheet defines the PLL register block as having
the dwords in the following order:

block   dwordsoffsets
PLL10x0-0x7   0x00-0x1f
PLL20x0-0x7   0x20-0x2f
PLL1ext 0x10-0x1f 0x40-0x5f
PLL2ext 0x10-0x1f 0x60-0x7f

So dword indexes 0x8-0xf don't even exist. Renumber
our register defines to match.

Note that the spreadsheet used hex numbering whereas our
defiens are in decimal. Perhaps we should change that?

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpll.c | 18 -
 drivers/gpu/drm/i915/i915_reg.h   | 24 +++
 2 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c 
b/drivers/gpu/drm/i915/display/intel_dpll.c
index 7e8aca3c87ec..b95032651da0 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll.c
@@ -1875,19 +1875,19 @@ static void vlv_pllb_recal_opamp(struct 
drm_i915_private *dev_priv,
 * PLLB opamp always calibrates to max value of 0x3f, force enable it
 * and set it to a reasonable value instead.
 */
-   reg_val = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW9(1));
+   reg_val = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW17(1));
reg_val &= 0xff00;
reg_val |= 0x0030;
-   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW9(1), reg_val);
+   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW17(1), reg_val);
 
reg_val = vlv_dpio_read(dev_priv, phy, VLV_REF_DW11);
reg_val &= 0x00ff;
reg_val |= 0x8c00;
vlv_dpio_write(dev_priv, phy, VLV_REF_DW11, reg_val);
 
-   reg_val = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW9(1));
+   reg_val = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW17(1));
reg_val &= 0xff00;
-   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW9(1), reg_val);
+   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW17(1), reg_val);
 
reg_val = vlv_dpio_read(dev_priv, phy, VLV_REF_DW11);
reg_val &= 0x00ff;
@@ -1923,9 +1923,9 @@ static void vlv_prepare_pll(const struct intel_crtc_state 
*crtc_state)
vlv_dpio_write(dev_priv, phy, VLV_PCS_DW17_BCAST, 0x010f);
 
/* Disable target IRef on PLL */
-   reg_val = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW8(pipe));
+   reg_val = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW16(pipe));
reg_val &= 0x00ff;
-   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW8(pipe), reg_val);
+   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW16(pipe), reg_val);
 
/* Disable fast lock */
vlv_dpio_write(dev_priv, phy, VLV_CMN_DW0, 0x610);
@@ -1951,10 +1951,10 @@ static void vlv_prepare_pll(const struct 
intel_crtc_state *crtc_state)
if (crtc_state->port_clock == 162000 ||
intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG) ||
intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
-   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW10(pipe),
+   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW18(pipe),
 0x009f0003);
else
-   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW10(pipe),
+   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW18(pipe),
 0x00df);
 
if (intel_crtc_has_dp_encoder(crtc_state)) {
@@ -1981,7 +1981,7 @@ static void vlv_prepare_pll(const struct intel_crtc_state 
*crtc_state)
coreclk |= 0x0100;
vlv_dpio_write(dev_priv, phy, VLV_PLL_DW7(pipe), coreclk);
 
-   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW11(pipe), 0x87871000);
+   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW19(pipe), 0x87871000);
 
vlv_dpio_put(dev_priv);
 }
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 8f3c83d2ab8d..747221f8ac72 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -229,21 +229,21 @@
 #define _VLV_PLL_DW7_CH1   0x803c
 #define VLV_PLL_DW7(ch) _PIPE(ch, _VLV_PLL_DW7_CH0, _VLV_PLL_DW7_CH1)
 
-#define _VLV_PLL_DW8_CH0   0x8040
-#define _VLV_PLL_DW8_CH1   0x8060
-#define VLV_PLL_DW8(ch) _PIPE(ch, _VLV_PLL_DW8_CH0, _VLV_PLL_DW8_CH1)
+#define _VLV_PLL_DW16_CH0  0x8040
+#define _VLV_PLL_DW16_CH1  0x8060
+#define VLV_PLL_DW16(ch) _PIPE(ch, _VLV_PLL_DW16_CH0, _VLV_PLL_DW16_CH1)
 
-#define _VLV_PLL_DW9_CH0   0x8044
-#define _VLV_PLL_DW9_CH1   0x8064
-#define VLV_PLL_DW9(ch) _PIPE(ch, _VLV_PLL_DW9_CH0, _VLV_PLL_DW9_CH1)
+#define _VLV_PLL_DW17_CH0  0x8044
+#define _VLV_PLL_DW17_CH1  0x8064
+#define VLV_PLL_DW17(ch) _PIPE(ch, _VLV_PLL_DW17_CH0, _VLV_PLL_DW17_CH1)
 
-#define _VLV_PLL_DW10_CH0  0x8048
-#define _VLV_PLL_DW10_CH1  0x8068
-#define VLV_PLL_DW10(ch) _PIPE(ch, _VLV_PLL_DW10_CH0, _VLV_PLL_DW10_CH1)
+#define _VLV_PLL_DW18_CH0  0x8048
+#define _VLV_PLL_DW18_CH1  0x8068

[PATCH 03/14] drm/i915/dpio: s/VLV_PLL_DW9_BCAST/VLV_PCS_DW17_BCAST/

2024-04-22 Thread Ville Syrjala
From: Ville Syrjälä 

VLV_PLL_DW9_BCAST is actually VLV_PCS_DW17_BCAST. The address
does kinda look like it goes to the PLL block on a first glance,
but broadcast is special and doesn't even exist for the PLL
(only PCS and TX have it).

The fact that we use a broadcast write here is a bit sketchy
IMO since we're now blasting the register to all PCS splines
across the whole PHY. So the PCS registers in the other channel
(ie. other pipe/port) will also be written. But I guess the
fact that we always write the same value should make this a nop
even if the other channel is already enabled (assuming the VBIOS/GOP
didn't screw up and use some other value...).

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpll.c | 2 +-
 drivers/gpu/drm/i915/i915_reg.h   | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c 
b/drivers/gpu/drm/i915/display/intel_dpll.c
index 6693beafe9c0..7e8aca3c87ec 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll.c
@@ -1920,7 +1920,7 @@ static void vlv_prepare_pll(const struct intel_crtc_state 
*crtc_state)
vlv_pllb_recal_opamp(dev_priv, phy);
 
/* Set up Tx target for periodic Rcomp update */
-   vlv_dpio_write(dev_priv, phy, VLV_PLL_DW9_BCAST, 0x010f);
+   vlv_dpio_write(dev_priv, phy, VLV_PCS_DW17_BCAST, 0x010f);
 
/* Disable target IRef on PLL */
reg_val = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW8(pipe));
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index a2fadcbe0932..8f3c83d2ab8d 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -233,7 +233,6 @@
 #define _VLV_PLL_DW8_CH1   0x8060
 #define VLV_PLL_DW8(ch) _PIPE(ch, _VLV_PLL_DW8_CH0, _VLV_PLL_DW8_CH1)
 
-#define VLV_PLL_DW9_BCAST  0xc044
 #define _VLV_PLL_DW9_CH0   0x8044
 #define _VLV_PLL_DW9_CH1   0x8064
 #define VLV_PLL_DW9(ch) _PIPE(ch, _VLV_PLL_DW9_CH0, _VLV_PLL_DW9_CH1)
@@ -370,6 +369,8 @@
 #define _VLV_PCS_DW14_CH1  0x8438
 #defineVLV_PCS_DW14(ch) _PORT(ch, _VLV_PCS_DW14_CH0, _VLV_PCS_DW14_CH1)
 
+#define VLV_PCS_DW17_BCAST 0xc044
+
 #define _VLV_PCS_DW23_CH0  0x825c
 #define _VLV_PCS_DW23_CH1  0x845c
 #define VLV_PCS_DW23(ch) _PORT(ch, _VLV_PCS_DW23_CH0, _VLV_PCS_DW23_CH1)
-- 
2.43.2



[PATCH 02/14] drm/i915/dpio: s/VLV_REF_DW13/VLV_REF_DW11/

2024-04-22 Thread Ville Syrjala
From: Ville Syrjälä 

Our VLV_REF_DW13 is actually VLV_REF_DW11. Rename it.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpll.c | 8 
 drivers/gpu/drm/i915/i915_reg.h   | 4 ++--
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c 
b/drivers/gpu/drm/i915/display/intel_dpll.c
index 49274d632716..6693beafe9c0 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll.c
@@ -1880,19 +1880,19 @@ static void vlv_pllb_recal_opamp(struct 
drm_i915_private *dev_priv,
reg_val |= 0x0030;
vlv_dpio_write(dev_priv, phy, VLV_PLL_DW9(1), reg_val);
 
-   reg_val = vlv_dpio_read(dev_priv, phy, VLV_REF_DW13);
+   reg_val = vlv_dpio_read(dev_priv, phy, VLV_REF_DW11);
reg_val &= 0x00ff;
reg_val |= 0x8c00;
-   vlv_dpio_write(dev_priv, phy, VLV_REF_DW13, reg_val);
+   vlv_dpio_write(dev_priv, phy, VLV_REF_DW11, reg_val);
 
reg_val = vlv_dpio_read(dev_priv, phy, VLV_PLL_DW9(1));
reg_val &= 0xff00;
vlv_dpio_write(dev_priv, phy, VLV_PLL_DW9(1), reg_val);
 
-   reg_val = vlv_dpio_read(dev_priv, phy, VLV_REF_DW13);
+   reg_val = vlv_dpio_read(dev_priv, phy, VLV_REF_DW11);
reg_val &= 0x00ff;
reg_val |= 0xb000;
-   vlv_dpio_write(dev_priv, phy, VLV_REF_DW13, reg_val);
+   vlv_dpio_write(dev_priv, phy, VLV_REF_DW11, reg_val);
 }
 
 static void vlv_prepare_pll(const struct intel_crtc_state *crtc_state)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 8eb6c2bf4557..a2fadcbe0932 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -246,8 +246,8 @@
 #define _VLV_PLL_DW11_CH1  0x806c
 #define VLV_PLL_DW11(ch) _PIPE(ch, _VLV_PLL_DW11_CH0, _VLV_PLL_DW11_CH1)
 
-/* Spec for ref block start counts at DW10 */
-#define VLV_REF_DW13   0x80ac
+/* Spec for ref block start counts at DW8 */
+#define VLV_REF_DW11   0x80ac
 
 #define VLV_CMN_DW00x8100
 
-- 
2.43.2



[PATCH 01/14] drm/i915/dpio: Remove pointless VLV_PCS01_DW8 read

2024-04-22 Thread Ville Syrjala
From: Ville Syrjälä 

We don't use the result of the VLV_PCS01_DW8 read at all,
so don't read.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpio_phy.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c 
b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
index c72b76b61dff..6cbee88e608f 100644
--- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
@@ -1134,7 +1134,6 @@ void vlv_phy_pre_encoder_enable(struct intel_encoder 
*encoder,
vlv_dpio_get(dev_priv);
 
/* Enable clock channels for this port */
-   val = vlv_dpio_read(dev_priv, phy, VLV_PCS01_DW8(port));
val = 0;
if (pipe)
val |= (1<<21);
-- 
2.43.2



[PATCH 00/14] drm/i915: VLV/CHV DPIO register cleanup

2024-04-22 Thread Ville Syrjala
From: Ville Syrjälä 

Polish the VLV/CHV DPIO stuff and extract vlv_dpio_phy_regs.h
to declutter i915_reg.h a bit.

Ville Syrjälä (14):
  drm/i915/dpio: Remove pointless VLV_PCS01_DW8 read
  drm/i915/dpio: s/VLV_REF_DW13/VLV_REF_DW11/
  drm/i915/dpio: s/VLV_PLL_DW9_BCAST/VLV_PCS_DW17_BCAST/
  drm/i915/dpio: Fix VLV DPIO PLL register dword numbering
  drm/i915/dpio: Remove pointless variables from vlv/chv DPLL code
  drm/i915/dpio: Rename some variables
  drm/i915/dpio: s/port/ch/
  drm/i915/dpio: s/pipe/ch/
  drm/i915/dpio: Derive the phy from the port rather than pipe in
encoder hooks
  drm/i915/dpio: Give VLV DPIO group register a clearer name
  drm/i915/dpio: Rename a few CHV DPIO PHY registers
  drm/i915/dpio: Clean up VLV/CHV DPIO PHY register defines
  drm/i915/dpio: Clean up the vlv/chv PHY register bits
  drm/i915/dpio: Extract vlv_dpio_phy_regs.h

 drivers/gpu/drm/i915/display/intel_display.c  |   1 +
 .../i915/display/intel_display_power_well.c   |  16 +-
 drivers/gpu/drm/i915/display/intel_dpio_phy.c | 148 
 drivers/gpu/drm/i915/display/intel_dpll.c | 260 +++--
 .../gpu/drm/i915/display/vlv_dpio_phy_regs.h  | 309 
 drivers/gpu/drm/i915/i915_reg.h   | 343 --
 drivers/gpu/drm/i915/vlv_sideband.c   |   1 -
 7 files changed, 515 insertions(+), 563 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/display/vlv_dpio_phy_regs.h

-- 
2.43.2



[PATCH v2 3/8] drm/i915/dpio: Extract bxt_dpio_phy_regs.h

2024-04-17 Thread Ville Syrjala
From: Ville Syrjälä 

Extract the BXT/GLK DPIO PHY register definitions into their own file.

v2: Adjust gvt accordingly

Reviewed-by: Jani Nikula 
Signed-off-by: Ville Syrjälä 
---
 .../gpu/drm/i915/display/bxt_dpio_phy_regs.h  | 273 ++
 drivers/gpu/drm/i915/display/intel_dpio_phy.c |   1 +
 drivers/gpu/drm/i915/display/intel_dpll_mgr.c |   1 +
 drivers/gpu/drm/i915/gvt/display.c|   1 +
 drivers/gpu/drm/i915/gvt/handlers.c   |   1 +
 drivers/gpu/drm/i915/gvt/mmio.c   |   1 +
 drivers/gpu/drm/i915/i915_reg.h   | 262 -
 drivers/gpu/drm/i915/intel_gvt_mmio_table.c   |   1 +
 8 files changed, 279 insertions(+), 262 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/display/bxt_dpio_phy_regs.h

diff --git a/drivers/gpu/drm/i915/display/bxt_dpio_phy_regs.h 
b/drivers/gpu/drm/i915/display/bxt_dpio_phy_regs.h
new file mode 100644
index ..275f4d9c3fb0
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/bxt_dpio_phy_regs.h
@@ -0,0 +1,273 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#ifndef __BXT_DPIO_PHY_REGS_H__
+#define __BXT_DPIO_PHY_REGS_H__
+
+#include "intel_display_reg_defs.h"
+
+/* BXT PHY registers */
+#define _BXT_PHY0_BASE 0x6C000
+#define _BXT_PHY1_BASE 0x162000
+#define _BXT_PHY2_BASE 0x163000
+#define BXT_PHY_BASE(phy) \
+_PICK_EVEN_2RANGES(phy, 1, \
+   _BXT_PHY0_BASE, _BXT_PHY0_BASE, \
+   _BXT_PHY1_BASE, _BXT_PHY2_BASE)
+
+#define _BXT_PHY(phy, reg) \
+   _MMIO(BXT_PHY_BASE(phy) - _BXT_PHY0_BASE + (reg))
+
+#define _BXT_PHY_CH(phy, ch, reg_ch0, reg_ch1) \
+   (BXT_PHY_BASE(phy) + _PIPE((ch), (reg_ch0) - _BXT_PHY0_BASE, \
+(reg_ch1) - _BXT_PHY0_BASE))
+#define _MMIO_BXT_PHY_CH(phy, ch, reg_ch0, reg_ch1) \
+   _MMIO(_BXT_PHY_CH(phy, ch, reg_ch0, reg_ch1))
+#define _BXT_LANE_OFFSET(lane)   (((lane) >> 1) * 0x200 + \
+ ((lane) & 1) * 0x80)
+#define _MMIO_BXT_PHY_CH_LN(phy, ch, lane, reg_ch0, reg_ch1) \
+   _MMIO(_BXT_PHY_CH(phy, ch, reg_ch0, reg_ch1) + _BXT_LANE_OFFSET(lane))
+
+/* BXT PHY PLL registers */
+#define _PORT_PLL_A0x46074
+#define _PORT_PLL_B0x46078
+#define _PORT_PLL_C0x4607c
+#define   PORT_PLL_ENABLE  REG_BIT(31)
+#define   PORT_PLL_LOCKREG_BIT(30)
+#define   PORT_PLL_REF_SEL REG_BIT(27)
+#define   PORT_PLL_POWER_ENABLEREG_BIT(26)
+#define   PORT_PLL_POWER_STATE REG_BIT(25)
+#define BXT_PORT_PLL_ENABLE(port)  _MMIO_PORT(port, _PORT_PLL_A, 
_PORT_PLL_B)
+
+#define _PORT_PLL_EBB_0_A  0x162034
+#define _PORT_PLL_EBB_0_B  0x6C034
+#define _PORT_PLL_EBB_0_C  0x6C340
+#define   PORT_PLL_P1_MASK REG_GENMASK(15, 13)
+#define   PORT_PLL_P1(p1)  REG_FIELD_PREP(PORT_PLL_P1_MASK, (p1))
+#define   PORT_PLL_P2_MASK REG_GENMASK(12, 8)
+#define   PORT_PLL_P2(p2)  REG_FIELD_PREP(PORT_PLL_P2_MASK, (p2))
+#define BXT_PORT_PLL_EBB_0(phy, ch)_MMIO_BXT_PHY_CH(phy, ch, \
+_PORT_PLL_EBB_0_B, \
+_PORT_PLL_EBB_0_C)
+
+#define _PORT_PLL_EBB_4_A  0x162038
+#define _PORT_PLL_EBB_4_B  0x6C038
+#define _PORT_PLL_EBB_4_C  0x6C344
+#define   PORT_PLL_RECALIBRATE REG_BIT(14)
+#define   PORT_PLL_10BIT_CLK_ENABLEREG_BIT(13)
+#define BXT_PORT_PLL_EBB_4(phy, ch)_MMIO_BXT_PHY_CH(phy, ch, \
+_PORT_PLL_EBB_4_B, \
+_PORT_PLL_EBB_4_C)
+
+#define _PORT_PLL_0_A  0x162100
+#define _PORT_PLL_0_B  0x6C100
+#define _PORT_PLL_0_C  0x6C380
+/* PORT_PLL_0_A */
+#define   PORT_PLL_M2_INT_MASK REG_GENMASK(7, 0)
+#define   PORT_PLL_M2_INT(m2_int)  REG_FIELD_PREP(PORT_PLL_M2_INT_MASK, 
(m2_int))
+/* PORT_PLL_1_A */
+#define   PORT_PLL_N_MASK  REG_GENMASK(11, 8)
+#define   PORT_PLL_N(n)REG_FIELD_PREP(PORT_PLL_N_MASK, 
(n))
+/* PORT_PLL_2_A */
+#define   PORT_PLL_M2_FRAC_MASKREG_GENMASK(21, 0)
+#define   PORT_PLL_M2_FRAC(m2_frac)REG_FIELD_PREP(PORT_PLL_M2_FRAC_MASK, 
(m2_frac))
+/* PORT_PLL_3_A */
+#define   PORT_PLL_M2_FRAC_ENABLE  REG_BIT(16)
+/* PORT_PLL_6_A */
+#define   PORT_PLL_GAIN_CTL_MASK   REG_GENMASK(18, 16)
+#define   PORT_PLL_GAIN_CTL(x) REG_FIELD_PREP(PORT_PLL_GAIN_CTL_MASK, 
(x))
+#define   PORT_PLL_INT_COEFF_MASK  REG_GENMASK(12, 8)
+#define   PORT_PLL_INT_COEFF(x)
REG_FIELD_PREP(PORT_PLL_INT_COEFF_MASK, (x))
+#define   PORT_PLL_PROP_COEFF_MASK 

[PATCH v2 2/8] drm/i915/dpio: Add per-lane PHY TX register definitons for bxt/glk

2024-04-17 Thread Ville Syrjala
From: Ville Syrjälä 

Add consistent definitions for the per-lane PHY TX registers
on bxt/glk. The current situation is a slight mess with some
registers having a LN0 define, while others have a parametrized
per-lane definition.

v2: Adjust gvt accordingly

Reviewed-by: Jani Nikula 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpio_phy.c |  6 +--
 drivers/gpu/drm/i915/display/intel_dpll_mgr.c |  2 +-
 drivers/gpu/drm/i915/gvt/handlers.c   |  6 +--
 drivers/gpu/drm/i915/i915_reg.h   | 38 +--
 drivers/gpu/drm/i915/intel_gvt_mmio_table.c   | 18 -
 5 files changed, 35 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c 
b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
index d14e80ece8aa..50d6b412d652 100644
--- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
@@ -294,13 +294,13 @@ void bxt_ddi_phy_set_signal_levels(struct intel_encoder 
*encoder,
val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
intel_de_write(dev_priv, BXT_PORT_PCS_DW10_GRP(phy, ch), val);
 
-   val = intel_de_read(dev_priv, BXT_PORT_TX_DW2_LN0(phy, ch));
+   val = intel_de_read(dev_priv, BXT_PORT_TX_DW2_LN(phy, ch, 0));
val &= ~(MARGIN_000_MASK | UNIQ_TRANS_SCALE_MASK);
val |= MARGIN_000(trans->entries[level].bxt.margin) |
UNIQ_TRANS_SCALE(trans->entries[level].bxt.scale);
intel_de_write(dev_priv, BXT_PORT_TX_DW2_GRP(phy, ch), val);
 
-   val = intel_de_read(dev_priv, BXT_PORT_TX_DW3_LN0(phy, ch));
+   val = intel_de_read(dev_priv, BXT_PORT_TX_DW3_LN(phy, ch, 0));
val &= ~SCALE_DCOMP_METHOD;
if (trans->entries[level].bxt.enable)
val |= SCALE_DCOMP_METHOD;
@@ -311,7 +311,7 @@ void bxt_ddi_phy_set_signal_levels(struct intel_encoder 
*encoder,
 
intel_de_write(dev_priv, BXT_PORT_TX_DW3_GRP(phy, ch), val);
 
-   val = intel_de_read(dev_priv, BXT_PORT_TX_DW4_LN0(phy, ch));
+   val = intel_de_read(dev_priv, BXT_PORT_TX_DW4_LN(phy, ch, 0));
val &= ~DE_EMPHASIS_MASK;
val |= DE_EMPHASIS(trans->entries[level].bxt.deemphasis);
intel_de_write(dev_priv, BXT_PORT_TX_DW4_GRP(phy, ch), val);
diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c 
b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
index 9ff6c4cc2e4b..cc3acdafdbf8 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
@@ -2071,7 +2071,7 @@ static void bxt_ddi_pll_enable(struct drm_i915_private 
*i915,
drm_err(>drm, "PLL %d not locked\n", port);
 
if (IS_GEMINILAKE(i915)) {
-   temp = intel_de_read(i915, BXT_PORT_TX_DW5_LN0(phy, ch));
+   temp = intel_de_read(i915, BXT_PORT_TX_DW5_LN(phy, ch, 0));
temp |= DCC_DELAY_RANGE_2;
intel_de_write(i915, BXT_PORT_TX_DW5_GRP(phy, ch), temp);
}
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c 
b/drivers/gpu/drm/i915/gvt/handlers.c
index efcb00472be2..d36092615ae3 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -2763,15 +2763,15 @@ static int init_bxt_mmio_info(struct intel_gvt *gvt)
 
MMIO_DH(BXT_PORT_PCS_DW12_GRP(DPIO_PHY0, DPIO_CH0), D_BXT,
NULL, bxt_pcs_dw12_grp_write);
-   MMIO_DH(BXT_PORT_TX_DW3_LN0(DPIO_PHY0, DPIO_CH0), D_BXT,
+   MMIO_DH(BXT_PORT_TX_DW3_LN(DPIO_PHY0, DPIO_CH0, 0), D_BXT,
bxt_port_tx_dw3_read, NULL);
MMIO_DH(BXT_PORT_PCS_DW12_GRP(DPIO_PHY0, DPIO_CH1), D_BXT,
NULL, bxt_pcs_dw12_grp_write);
-   MMIO_DH(BXT_PORT_TX_DW3_LN0(DPIO_PHY0, DPIO_CH1), D_BXT,
+   MMIO_DH(BXT_PORT_TX_DW3_LN(DPIO_PHY0, DPIO_CH1, 0), D_BXT,
bxt_port_tx_dw3_read, NULL);
MMIO_DH(BXT_PORT_PCS_DW12_GRP(DPIO_PHY1, DPIO_CH0), D_BXT,
NULL, bxt_pcs_dw12_grp_write);
-   MMIO_DH(BXT_PORT_TX_DW3_LN0(DPIO_PHY1, DPIO_CH0), D_BXT,
+   MMIO_DH(BXT_PORT_TX_DW3_LN(DPIO_PHY1, DPIO_CH0, 0), D_BXT,
bxt_port_tx_dw3_read, NULL);
MMIO_DH(BXT_DE_PLL_ENABLE, D_BXT, NULL, bxt_de_pll_enable_write);
MMIO_DFH(GEN8_L3SQCREG1, D_BXT, F_CMD_ACCESS, NULL, NULL);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 9701aad57e3a..261b520da399 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -555,6 +555,10 @@
 (reg_ch1) - _BXT_PHY0_BASE))
 #define _MMIO_BXT_PHY_CH(phy, ch, reg_ch0, reg_ch1)\
_MMIO(_BXT_PHY_CH(phy, ch, reg_ch0, reg_ch1))
+#define _BXT_LANE_OFFSET(lane)   (((lane) >> 1) * 0x200 + \
+ ((lane) & 1) * 0x80)
+#define _MMIO_BXT_PHY_CH_LN(phy, ch, lane, reg_ch0, reg_ch1) \
+   _MMIO(_BXT_PHY_CH(phy, ch, reg_ch0, reg_ch1) + _BXT_LANE_OFFSET(lane))
 
 #define 

[PATCH 16/18] drm/i915: Carve up struct intel_dpll_hw_state

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

struct intel_dpll_hw_state has a spot for all possible
PLL registers across all platforms (well, apart from
cx0/snps). This makes it rather confusing when trying to
figure out which members belong to which platform(s).

Split the struct up into five different platform specific
sub-structures. For now this will actually increase the size
a little bit as we have to duplicate a few members from
skl to icl, but that will be remedied soon when we turn
the thing into a union.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_display.c  |   4 +-
 drivers/gpu/drm/i915/display/intel_dpll.c |  35 ++--
 drivers/gpu/drm/i915/display/intel_dpll.h |   2 +-
 drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 183 --
 drivers/gpu/drm/i915/display/intel_dpll_mgr.h |  33 ++--
 .../gpu/drm/i915/display/intel_pch_display.c  |   2 +-
 6 files changed, 162 insertions(+), 97 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 806595cf8f97..96ed1490fec7 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -3074,13 +3074,13 @@ static bool i9xx_get_pipe_config(struct intel_crtc 
*crtc,
i9xx_dpll_get_hw_state(crtc, _config->dpll_hw_state);
 
if (DISPLAY_VER(dev_priv) >= 4) {
-   tmp = pipe_config->dpll_hw_state.dpll_md;
+   tmp = pipe_config->dpll_hw_state.i9xx.dpll_md;
pipe_config->pixel_multiplier =
((tmp & DPLL_MD_UDI_MULTIPLIER_MASK)
 >> DPLL_MD_UDI_MULTIPLIER_SHIFT) + 1;
} else if (IS_I945G(dev_priv) || IS_I945GM(dev_priv) ||
   IS_G33(dev_priv) || IS_PINEVIEW(dev_priv)) {
-   tmp = pipe_config->dpll_hw_state.dpll;
+   tmp = pipe_config->dpll_hw_state.i9xx.dpll;
pipe_config->pixel_multiplier =
((tmp & SDVO_MULTIPLIER_MASK)
 >> SDVO_MULTIPLIER_SHIFT_HIRES) + 1;
diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c 
b/drivers/gpu/drm/i915/display/intel_dpll.c
index b6fbc481c9e5..b9f1c5370598 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll.c
@@ -372,7 +372,7 @@ int chv_calc_dpll_params(int refclk, struct dpll *clock)
 static int i9xx_pll_refclk(const struct intel_crtc_state *crtc_state)
 {
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
-   const struct intel_dpll_hw_state *hw_state = _state->dpll_hw_state;
+   const struct i9xx_dpll_hw_state *hw_state = 
_state->dpll_hw_state.i9xx;
 
if ((hw_state->dpll & PLL_REF_INPUT_MASK) == 
PLLB_REF_INPUT_SPREADSPECTRUMIN)
return i915->display.vbt.lvds_ssc_freq;
@@ -385,9 +385,10 @@ static int i9xx_pll_refclk(const struct intel_crtc_state 
*crtc_state)
 }
 
 void i9xx_dpll_get_hw_state(struct intel_crtc *crtc,
-   struct intel_dpll_hw_state *hw_state)
+   struct intel_dpll_hw_state *dpll_hw_state)
 {
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+   struct i9xx_dpll_hw_state *hw_state = _hw_state->i9xx;
 
if (DISPLAY_VER(dev_priv) >= 4) {
u32 tmp;
@@ -419,7 +420,7 @@ void i9xx_crtc_clock_get(struct intel_crtc_state 
*crtc_state)
 {
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-   const struct intel_dpll_hw_state *hw_state = _state->dpll_hw_state;
+   const struct i9xx_dpll_hw_state *hw_state = 
_state->dpll_hw_state.i9xx;
u32 dpll = hw_state->dpll;
u32 fp;
struct dpll clock;
@@ -427,9 +428,9 @@ void i9xx_crtc_clock_get(struct intel_crtc_state 
*crtc_state)
int refclk = i9xx_pll_refclk(crtc_state);
 
if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
-   fp = crtc_state->dpll_hw_state.fp0;
+   fp = hw_state->fp0;
else
-   fp = crtc_state->dpll_hw_state.fp1;
+   fp = hw_state->fp1;
 
clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
if (IS_PINEVIEW(dev_priv)) {
@@ -512,7 +513,7 @@ void vlv_crtc_clock_get(struct intel_crtc_state *crtc_state)
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum dpio_phy phy = vlv_pipe_to_phy(crtc->pipe);
-   const struct intel_dpll_hw_state *hw_state = _state->dpll_hw_state;
+   const struct i9xx_dpll_hw_state *hw_state = 
_state->dpll_hw_state.i9xx;
struct dpll clock;
u32 mdiv;
int refclk = 10;
@@ -540,7 +541,7 @@ void chv_crtc_clock_get(struct intel_crtc_state *crtc_state)
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum dpio_channel port = 

[PATCH 15/18] drm/i915: Add local DPLL 'hw_state' variables

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

Add some local 'hw_state' variables to the old DPLL code.
Will help with unionizing the dpll_hw_state later.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpll.c | 98 +--
 1 file changed, 54 insertions(+), 44 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c 
b/drivers/gpu/drm/i915/display/intel_dpll.c
index 4df40a14d0f1..b6fbc481c9e5 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll.c
@@ -372,9 +372,9 @@ int chv_calc_dpll_params(int refclk, struct dpll *clock)
 static int i9xx_pll_refclk(const struct intel_crtc_state *crtc_state)
 {
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
-   u32 dpll = crtc_state->dpll_hw_state.dpll;
+   const struct intel_dpll_hw_state *hw_state = _state->dpll_hw_state;
 
-   if ((dpll & PLL_REF_INPUT_MASK) == PLLB_REF_INPUT_SPREADSPECTRUMIN)
+   if ((hw_state->dpll & PLL_REF_INPUT_MASK) == 
PLLB_REF_INPUT_SPREADSPECTRUMIN)
return i915->display.vbt.lvds_ssc_freq;
else if (HAS_PCH_SPLIT(i915))
return 12;
@@ -419,7 +419,8 @@ void i9xx_crtc_clock_get(struct intel_crtc_state 
*crtc_state)
 {
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-   u32 dpll = crtc_state->dpll_hw_state.dpll;
+   const struct intel_dpll_hw_state *hw_state = _state->dpll_hw_state;
+   u32 dpll = hw_state->dpll;
u32 fp;
struct dpll clock;
int port_clock;
@@ -511,12 +512,13 @@ void vlv_crtc_clock_get(struct intel_crtc_state 
*crtc_state)
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum dpio_phy phy = vlv_pipe_to_phy(crtc->pipe);
+   const struct intel_dpll_hw_state *hw_state = _state->dpll_hw_state;
struct dpll clock;
u32 mdiv;
int refclk = 10;
 
/* In case of DSI, DPLL will not be used */
-   if ((crtc_state->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
+   if ((hw_state->dpll & DPLL_VCO_ENABLE) == 0)
return;
 
vlv_dpio_get(dev_priv);
@@ -538,12 +540,13 @@ void chv_crtc_clock_get(struct intel_crtc_state 
*crtc_state)
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum dpio_channel port = vlv_pipe_to_channel(crtc->pipe);
enum dpio_phy phy = vlv_pipe_to_phy(crtc->pipe);
+   const struct intel_dpll_hw_state *hw_state = _state->dpll_hw_state;
struct dpll clock;
u32 cmn_dw13, pll_dw0, pll_dw1, pll_dw2, pll_dw3;
int refclk = 10;
 
/* In case of DSI, DPLL will not be used */
-   if ((crtc_state->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
+   if ((hw_state->dpll & DPLL_VCO_ENABLE) == 0)
return;
 
vlv_dpio_get(dev_priv);
@@ -1065,19 +1068,20 @@ static void i9xx_compute_dpll(struct intel_crtc_state 
*crtc_state,
 {
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+   struct intel_dpll_hw_state *hw_state = _state->dpll_hw_state;
 
if (IS_PINEVIEW(dev_priv)) {
-   crtc_state->dpll_hw_state.fp0 = pnv_dpll_compute_fp(clock);
-   crtc_state->dpll_hw_state.fp1 = 
pnv_dpll_compute_fp(reduced_clock);
+   hw_state->fp0 = pnv_dpll_compute_fp(clock);
+   hw_state->fp1 = pnv_dpll_compute_fp(reduced_clock);
} else {
-   crtc_state->dpll_hw_state.fp0 = i9xx_dpll_compute_fp(clock);
-   crtc_state->dpll_hw_state.fp1 = 
i9xx_dpll_compute_fp(reduced_clock);
+   hw_state->fp0 = i9xx_dpll_compute_fp(clock);
+   hw_state->fp1 = i9xx_dpll_compute_fp(reduced_clock);
}
 
-   crtc_state->dpll_hw_state.dpll = i9xx_dpll(crtc_state, clock, 
reduced_clock);
+   hw_state->dpll = i9xx_dpll(crtc_state, clock, reduced_clock);
 
if (DISPLAY_VER(dev_priv) >= 4)
-   crtc_state->dpll_hw_state.dpll_md = i965_dpll_md(crtc_state);
+   hw_state->dpll_md = i965_dpll_md(crtc_state);
 }
 
 static u32 i8xx_dpll(const struct intel_crtc_state *crtc_state,
@@ -1132,10 +1136,12 @@ static void i8xx_compute_dpll(struct intel_crtc_state 
*crtc_state,
  const struct dpll *clock,
  const struct dpll *reduced_clock)
 {
-   crtc_state->dpll_hw_state.fp0 = i9xx_dpll_compute_fp(clock);
-   crtc_state->dpll_hw_state.fp1 = i9xx_dpll_compute_fp(reduced_clock);
+   struct intel_dpll_hw_state *hw_state = _state->dpll_hw_state;
 
-   crtc_state->dpll_hw_state.dpll = i8xx_dpll(crtc_state, clock, 
reduced_clock);
+   hw_state->fp0 = i9xx_dpll_compute_fp(clock);
+   hw_state->fp1 = i9xx_dpll_compute_fp(reduced_clock);
+
+

[PATCH 14/18] drm/i915: s/pipe_config/crtc_state/ in legacy PLL code

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

Rename all the ye olde 'pipe_config's to the modern
'crtc_state' name in the legacy DPLL code.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpll.c | 30 +++
 drivers/gpu/drm/i915/display/intel_dpll.h |  6 ++---
 2 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c 
b/drivers/gpu/drm/i915/display/intel_dpll.c
index 9d57262ac577..4df40a14d0f1 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll.c
@@ -415,20 +415,20 @@ void i9xx_dpll_get_hw_state(struct intel_crtc *crtc,
 }
 
 /* Returns the clock of the currently programmed mode of the given pipe. */
-void i9xx_crtc_clock_get(struct intel_crtc_state *pipe_config)
+void i9xx_crtc_clock_get(struct intel_crtc_state *crtc_state)
 {
-   struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
+   struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-   u32 dpll = pipe_config->dpll_hw_state.dpll;
+   u32 dpll = crtc_state->dpll_hw_state.dpll;
u32 fp;
struct dpll clock;
int port_clock;
-   int refclk = i9xx_pll_refclk(pipe_config);
+   int refclk = i9xx_pll_refclk(crtc_state);
 
if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
-   fp = pipe_config->dpll_hw_state.fp0;
+   fp = crtc_state->dpll_hw_state.fp0;
else
-   fp = pipe_config->dpll_hw_state.fp1;
+   fp = crtc_state->dpll_hw_state.fp1;
 
clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
if (IS_PINEVIEW(dev_priv)) {
@@ -503,12 +503,12 @@ void i9xx_crtc_clock_get(struct intel_crtc_state 
*pipe_config)
 * port_clock to compute adjusted_mode.crtc_clock in the
 * encoder's get_config() function.
 */
-   pipe_config->port_clock = port_clock;
+   crtc_state->port_clock = port_clock;
 }
 
-void vlv_crtc_clock_get(struct intel_crtc_state *pipe_config)
+void vlv_crtc_clock_get(struct intel_crtc_state *crtc_state)
 {
-   struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
+   struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum dpio_phy phy = vlv_pipe_to_phy(crtc->pipe);
struct dpll clock;
@@ -516,7 +516,7 @@ void vlv_crtc_clock_get(struct intel_crtc_state 
*pipe_config)
int refclk = 10;
 
/* In case of DSI, DPLL will not be used */
-   if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
+   if ((crtc_state->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
return;
 
vlv_dpio_get(dev_priv);
@@ -529,12 +529,12 @@ void vlv_crtc_clock_get(struct intel_crtc_state 
*pipe_config)
clock.p1 = (mdiv >> DPIO_P1_SHIFT) & 7;
clock.p2 = (mdiv >> DPIO_P2_SHIFT) & 0x1f;
 
-   pipe_config->port_clock = vlv_calc_dpll_params(refclk, );
+   crtc_state->port_clock = vlv_calc_dpll_params(refclk, );
 }
 
-void chv_crtc_clock_get(struct intel_crtc_state *pipe_config)
+void chv_crtc_clock_get(struct intel_crtc_state *crtc_state)
 {
-   struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
+   struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum dpio_channel port = vlv_pipe_to_channel(crtc->pipe);
enum dpio_phy phy = vlv_pipe_to_phy(crtc->pipe);
@@ -543,7 +543,7 @@ void chv_crtc_clock_get(struct intel_crtc_state 
*pipe_config)
int refclk = 10;
 
/* In case of DSI, DPLL will not be used */
-   if ((pipe_config->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
+   if ((crtc_state->dpll_hw_state.dpll & DPLL_VCO_ENABLE) == 0)
return;
 
vlv_dpio_get(dev_priv);
@@ -562,7 +562,7 @@ void chv_crtc_clock_get(struct intel_crtc_state 
*pipe_config)
clock.p1 = (cmn_dw13 >> DPIO_CHV_P1_DIV_SHIFT) & 0x7;
clock.p2 = (cmn_dw13 >> DPIO_CHV_P2_DIV_SHIFT) & 0x1f;
 
-   pipe_config->port_clock = chv_calc_dpll_params(refclk, );
+   crtc_state->port_clock = chv_calc_dpll_params(refclk, );
 }
 
 /*
diff --git a/drivers/gpu/drm/i915/display/intel_dpll.h 
b/drivers/gpu/drm/i915/display/intel_dpll.h
index dc47affba2ba..49591bda7f8b 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.h
+++ b/drivers/gpu/drm/i915/display/intel_dpll.h
@@ -42,9 +42,9 @@ bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state,
struct dpll *best_clock);
 int chv_calc_dpll_params(int refclk, struct dpll *pll_clock);
 
-void i9xx_crtc_clock_get(struct intel_crtc_state *pipe_config);
-void vlv_crtc_clock_get(struct intel_crtc_state *pipe_config);
-void chv_crtc_clock_get(struct intel_crtc_state *pipe_config);
+void i9xx_crtc_clock_get(struct intel_crtc_state *crtc_state);

[PATCH 18/18] drm/i915: Suck snps/cx0 PLL states into dpll_hw_state

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

For some reason the snps/cx0 PLL states were added into
a union alongside dpll_hw_state. Just suck them into
dpll_hw_state so that we don't have so many levels of
unions/etc.

TODO: Get rid of 'clock' from the snps/cx0 PLL states
  as it is not a register values and thus doesn't
  belong there

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_cx0_phy.c  | 20 -
 drivers/gpu/drm/i915/display/intel_ddi.c  |  8 ++--
 .../drm/i915/display/intel_display_types.h| 43 +--
 drivers/gpu/drm/i915/display/intel_dpll.c |  2 +-
 drivers/gpu/drm/i915/display/intel_dpll_mgr.h | 39 +
 drivers/gpu/drm/i915/display/intel_snps_phy.c |  6 +--
 6 files changed, 58 insertions(+), 60 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c 
b/drivers/gpu/drm/i915/display/intel_cx0_phy.c
index a2c4bf33155f..8e3b13884bb8 100644
--- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c
@@ -1827,7 +1827,7 @@ static void intel_c10pll_update_pll(struct 
intel_crtc_state *crtc_state,
struct intel_encoder *encoder)
 {
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
-   struct intel_cx0pll_state *pll_state = _state->cx0pll_state;
+   struct intel_cx0pll_state *pll_state = 
_state->dpll_hw_state.cx0pll;
int i;
 
if (intel_crtc_has_dp_encoder(crtc_state)) {
@@ -1859,7 +1859,7 @@ static int intel_c10pll_calc_state(struct 
intel_crtc_state *crtc_state,
 
for (i = 0; tables[i]; i++) {
if (crtc_state->port_clock == tables[i]->clock) {
-   crtc_state->cx0pll_state.c10 = *tables[i];
+   crtc_state->dpll_hw_state.cx0pll.c10 = *tables[i];
intel_c10pll_update_pll(crtc_state, encoder);
 
return 0;
@@ -1899,7 +1899,7 @@ static void intel_c10_pll_program(struct drm_i915_private 
*i915,
  const struct intel_crtc_state *crtc_state,
  struct intel_encoder *encoder)
 {
-   const struct intel_c10pll_state *pll_state = 
_state->cx0pll_state.c10;
+   const struct intel_c10pll_state *pll_state = 
_state->dpll_hw_state.cx0pll.c10;
int i;
 
intel_cx0_rmw(encoder, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_CONTROL(1),
@@ -2079,7 +2079,7 @@ static int intel_c20pll_calc_state(struct 
intel_crtc_state *crtc_state,
/* try computed C20 HDMI tables before using consolidated tables */
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
if (intel_c20_compute_hdmi_tmds_pll(crtc_state->port_clock,
-   
_state->cx0pll_state.c20) == 0)
+   
_state->dpll_hw_state.cx0pll.c20) == 0)
return 0;
}
 
@@ -2089,7 +2089,7 @@ static int intel_c20pll_calc_state(struct 
intel_crtc_state *crtc_state,
 
for (i = 0; tables[i]; i++) {
if (crtc_state->port_clock == tables[i]->clock) {
-   crtc_state->cx0pll_state.c20 = *tables[i];
+   crtc_state->dpll_hw_state.cx0pll.c20 = *tables[i];
return 0;
}
}
@@ -2335,7 +2335,7 @@ static void intel_c20_pll_program(struct drm_i915_private 
*i915,
  const struct intel_crtc_state *crtc_state,
  struct intel_encoder *encoder)
 {
-   const struct intel_c20pll_state *pll_state = 
_state->cx0pll_state.c20;
+   const struct intel_c20pll_state *pll_state = 
_state->dpll_hw_state.cx0pll.c20;
bool dp = false;
int lane = crtc_state->lane_count > 2 ? INTEL_CX0_BOTH_LANES : 
INTEL_CX0_LANE0;
u32 clock = crtc_state->port_clock;
@@ -2484,9 +2484,9 @@ static void intel_program_port_clock_ctl(struct 
intel_encoder *encoder,
/* TODO: HDMI FRL */
/* DP2.0 10G and 20G rates enable MPLLA*/
if (crtc_state->port_clock == 100 || crtc_state->port_clock == 
200)
-   val |= crtc_state->cx0pll_state.ssc_enabled ? 
XELPDP_SSC_ENABLE_PLLA : 0;
+   val |= crtc_state->dpll_hw_state.cx0pll.ssc_enabled ? 
XELPDP_SSC_ENABLE_PLLA : 0;
else
-   val |= crtc_state->cx0pll_state.ssc_enabled ? 
XELPDP_SSC_ENABLE_PLLB : 0;
+   val |= crtc_state->dpll_hw_state.cx0pll.ssc_enabled ? 
XELPDP_SSC_ENABLE_PLLB : 0;
 
intel_de_rmw(i915, XELPDP_PORT_CLOCK_CTL(i915, encoder->port),
 XELPDP_LANE1_PHY_CLOCK_SELECT | 
XELPDP_FORWARD_CLOCK_UNGATE |
@@ -3025,7 +3025,7 @@ static void intel_c10pll_state_verify(const struct 
intel_crtc_state *state,
  struct intel_c10pll_state *mpllb_hw_state)
 {
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
-   

[PATCH 13/18] drm/i915: Drop pointless 'crtc' argument from *_crtc_clock_get()

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

We are alreayd passing the crtc_state to *_crtc_clock_get().
Passing the crtc as well is 100% redundant, so don't do it.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_display.c  |  6 +++---
 drivers/gpu/drm/i915/display/intel_dpll.c | 21 ---
 drivers/gpu/drm/i915/display/intel_dpll.h |  9 +++-
 .../gpu/drm/i915/display/intel_pch_display.c  |  2 +-
 4 files changed, 16 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 70ba8a9c671e..806595cf8f97 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -3092,11 +3092,11 @@ static bool i9xx_get_pipe_config(struct intel_crtc 
*crtc,
}
 
if (IS_CHERRYVIEW(dev_priv))
-   chv_crtc_clock_get(crtc, pipe_config);
+   chv_crtc_clock_get(pipe_config);
else if (IS_VALLEYVIEW(dev_priv))
-   vlv_crtc_clock_get(crtc, pipe_config);
+   vlv_crtc_clock_get(pipe_config);
else
-   i9xx_crtc_clock_get(crtc, pipe_config);
+   i9xx_crtc_clock_get(pipe_config);
 
/*
 * Normally the dotclock is filled in by the encoder .get_config()
diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c 
b/drivers/gpu/drm/i915/display/intel_dpll.c
index 5246b8a8d461..9d57262ac577 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll.c
@@ -415,11 +415,10 @@ void i9xx_dpll_get_hw_state(struct intel_crtc *crtc,
 }
 
 /* Returns the clock of the currently programmed mode of the given pipe. */
-void i9xx_crtc_clock_get(struct intel_crtc *crtc,
-struct intel_crtc_state *pipe_config)
+void i9xx_crtc_clock_get(struct intel_crtc_state *pipe_config)
 {
-   struct drm_device *dev = crtc->base.dev;
-   struct drm_i915_private *dev_priv = to_i915(dev);
+   struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
+   struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
u32 dpll = pipe_config->dpll_hw_state.dpll;
u32 fp;
struct dpll clock;
@@ -507,11 +506,10 @@ void i9xx_crtc_clock_get(struct intel_crtc *crtc,
pipe_config->port_clock = port_clock;
 }
 
-void vlv_crtc_clock_get(struct intel_crtc *crtc,
-   struct intel_crtc_state *pipe_config)
+void vlv_crtc_clock_get(struct intel_crtc_state *pipe_config)
 {
-   struct drm_device *dev = crtc->base.dev;
-   struct drm_i915_private *dev_priv = to_i915(dev);
+   struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
+   struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum dpio_phy phy = vlv_pipe_to_phy(crtc->pipe);
struct dpll clock;
u32 mdiv;
@@ -534,11 +532,10 @@ void vlv_crtc_clock_get(struct intel_crtc *crtc,
pipe_config->port_clock = vlv_calc_dpll_params(refclk, );
 }
 
-void chv_crtc_clock_get(struct intel_crtc *crtc,
-   struct intel_crtc_state *pipe_config)
+void chv_crtc_clock_get(struct intel_crtc_state *pipe_config)
 {
-   struct drm_device *dev = crtc->base.dev;
-   struct drm_i915_private *dev_priv = to_i915(dev);
+   struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
+   struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum dpio_channel port = vlv_pipe_to_channel(crtc->pipe);
enum dpio_phy phy = vlv_pipe_to_phy(crtc->pipe);
struct dpll clock;
diff --git a/drivers/gpu/drm/i915/display/intel_dpll.h 
b/drivers/gpu/drm/i915/display/intel_dpll.h
index c11c18277266..dc47affba2ba 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.h
+++ b/drivers/gpu/drm/i915/display/intel_dpll.h
@@ -42,12 +42,9 @@ bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state,
struct dpll *best_clock);
 int chv_calc_dpll_params(int refclk, struct dpll *pll_clock);
 
-void i9xx_crtc_clock_get(struct intel_crtc *crtc,
-struct intel_crtc_state *pipe_config);
-void vlv_crtc_clock_get(struct intel_crtc *crtc,
-   struct intel_crtc_state *pipe_config);
-void chv_crtc_clock_get(struct intel_crtc *crtc,
-   struct intel_crtc_state *pipe_config);
+void i9xx_crtc_clock_get(struct intel_crtc_state *pipe_config);
+void vlv_crtc_clock_get(struct intel_crtc_state *pipe_config);
+void chv_crtc_clock_get(struct intel_crtc_state *pipe_config);
 
 void assert_pll_enabled(struct drm_i915_private *i915, enum pipe pipe);
 void assert_pll_disabled(struct drm_i915_private *i915, enum pipe pipe);
diff --git a/drivers/gpu/drm/i915/display/intel_pch_display.c 
b/drivers/gpu/drm/i915/display/intel_pch_display.c
index baf679759e00..252483581c96 100644
--- a/drivers/gpu/drm/i915/display/intel_pch_display.c
+++ b/drivers/gpu/drm/i915/display/intel_pch_display.c
@@ -474,7 +474,7 

[PATCH 17/18] drm/i915: Unionize dpll_hw_state

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

intel_dpll_hw_state contains space for all possible PLL
register values across all platforms. That is rather wasteful
as each machine only needs to store the registers values
that are appropriate for the platform.

Turn intel_dpll_hw_state into a union so that we don't
waste memory for the register values of other platforms.

And let's use an anonymous union so that we don't have
to do tons of s/struct/union/ all over the place.

pahole:
 struct intel_dpll_hw_state {
-   struct i9xx_dpll_hw_state  i9xx; /* 016 */
-   struct hsw_dpll_hw_state   hsw;  /*16 8 */
-   struct skl_dpll_hw_state   skl;  /*2412 */
-   struct bxt_dpll_hw_state   bxt;  /*3644 */
-   /* --- cacheline 1 boundary (64 bytes) was 16 bytes ago --- */
-   struct icl_dpll_hw_state   icl;  /*8060 */
+   union {
+   struct i9xx_dpll_hw_state i9xx;  /* 016 */
+   struct hsw_dpll_hw_state hsw;/* 0 8 */
+   struct skl_dpll_hw_state skl;/* 012 */
+   struct bxt_dpll_hw_state bxt;/* 044 */
+   struct icl_dpll_hw_state icl;/* 060 */
+   };   /* 060 */

-   /* size: 140, cachelines: 3, members: 5 */
-   /* last cacheline: 12 bytes */
+   /* size: 60, cachelines: 1, members: 1 */
+   /* last cacheline: 60 bytes */

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpll_mgr.h | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h 
b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h
index 95438f12c4f0..d0ec6196d398 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h
+++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h
@@ -230,11 +230,13 @@ struct icl_dpll_hw_state {
 };
 
 struct intel_dpll_hw_state {
-   struct i9xx_dpll_hw_state i9xx;
-   struct hsw_dpll_hw_state hsw;
-   struct skl_dpll_hw_state skl;
-   struct bxt_dpll_hw_state bxt;
-   struct icl_dpll_hw_state icl;
+   union {
+   struct i9xx_dpll_hw_state i9xx;
+   struct hsw_dpll_hw_state hsw;
+   struct skl_dpll_hw_state skl;
+   struct bxt_dpll_hw_state bxt;
+   struct icl_dpll_hw_state icl;
+   };
 };
 
 /**
-- 
2.43.2



[PATCH 12/18] drm/i915: Modernize i9xx_pll_refclk()

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

Drop the redundant 'dev' argument from i9xx_pll_refclk()
and rename its variables to conform to modern standards.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpll.c | 15 +++
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c 
b/drivers/gpu/drm/i915/display/intel_dpll.c
index 43d36ea56798..5246b8a8d461 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll.c
@@ -369,17 +369,16 @@ int chv_calc_dpll_params(int refclk, struct dpll *clock)
return clock->dot;
 }
 
-static int i9xx_pll_refclk(struct drm_device *dev,
-  const struct intel_crtc_state *pipe_config)
+static int i9xx_pll_refclk(const struct intel_crtc_state *crtc_state)
 {
-   struct drm_i915_private *dev_priv = to_i915(dev);
-   u32 dpll = pipe_config->dpll_hw_state.dpll;
+   struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+   u32 dpll = crtc_state->dpll_hw_state.dpll;
 
if ((dpll & PLL_REF_INPUT_MASK) == PLLB_REF_INPUT_SPREADSPECTRUMIN)
-   return dev_priv->display.vbt.lvds_ssc_freq;
-   else if (HAS_PCH_SPLIT(dev_priv))
+   return i915->display.vbt.lvds_ssc_freq;
+   else if (HAS_PCH_SPLIT(i915))
return 12;
-   else if (DISPLAY_VER(dev_priv) != 2)
+   else if (DISPLAY_VER(i915) != 2)
return 96000;
else
return 48000;
@@ -425,7 +424,7 @@ void i9xx_crtc_clock_get(struct intel_crtc *crtc,
u32 fp;
struct dpll clock;
int port_clock;
-   int refclk = i9xx_pll_refclk(dev, pipe_config);
+   int refclk = i9xx_pll_refclk(pipe_config);
 
if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
fp = pipe_config->dpll_hw_state.fp0;
-- 
2.43.2



[PATCH 09/18] drm/i915: Extract i965_dpll_md()

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

We have three copies of the DPLL_MD value computation.
Share it.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpll.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c 
b/drivers/gpu/drm/i915/display/intel_dpll.c
index 693e22f06aee..9e1f94a2ce92 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll.c
@@ -1008,6 +1008,11 @@ static void i9xx_update_pll_dividers(struct 
intel_crtc_state *crtc_state,
crtc_state->dpll_hw_state.fp1 = fp2;
 }
 
+static u32 i965_dpll_md(const struct intel_crtc_state *crtc_state)
+{
+   return (crtc_state->pixel_multiplier - 1) << 
DPLL_MD_UDI_MULTIPLIER_SHIFT;
+}
+
 static void i9xx_compute_dpll(struct intel_crtc_state *crtc_state,
  const struct dpll *clock,
  const struct dpll *reduced_clock)
@@ -1080,11 +1085,8 @@ static void i9xx_compute_dpll(struct intel_crtc_state 
*crtc_state,
dpll |= DPLL_VCO_ENABLE;
crtc_state->dpll_hw_state.dpll = dpll;
 
-   if (DISPLAY_VER(dev_priv) >= 4) {
-   u32 dpll_md = (crtc_state->pixel_multiplier - 1)
-   << DPLL_MD_UDI_MULTIPLIER_SHIFT;
-   crtc_state->dpll_hw_state.dpll_md = dpll_md;
-   }
+   if (DISPLAY_VER(dev_priv) >= 4)
+   crtc_state->dpll_hw_state.dpll_md = i965_dpll_md(crtc_state);
 }
 
 static void i8xx_compute_dpll(struct intel_crtc_state *crtc_state,
@@ -1425,8 +1427,7 @@ void vlv_compute_dpll(struct intel_crtc_state *crtc_state)
crtc_state->dpll_hw_state.dpll |= DPLL_VCO_ENABLE |
DPLL_EXT_BUFFER_ENABLE_VLV;
 
-   crtc_state->dpll_hw_state.dpll_md =
-   (crtc_state->pixel_multiplier - 1) << 
DPLL_MD_UDI_MULTIPLIER_SHIFT;
+   crtc_state->dpll_hw_state.dpll_md = i965_dpll_md(crtc_state);
 }
 
 void chv_compute_dpll(struct intel_crtc_state *crtc_state)
@@ -1442,8 +1443,7 @@ void chv_compute_dpll(struct intel_crtc_state *crtc_state)
if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
crtc_state->dpll_hw_state.dpll |= DPLL_VCO_ENABLE;
 
-   crtc_state->dpll_hw_state.dpll_md =
-   (crtc_state->pixel_multiplier - 1) << 
DPLL_MD_UDI_MULTIPLIER_SHIFT;
+   crtc_state->dpll_hw_state.dpll_md = i965_dpll_md(crtc_state);
 }
 
 static int chv_crtc_compute_clock(struct intel_atomic_state *state,
-- 
2.43.2



[PATCH 10/18] drm/i915: Extract {i9xx,i8xx,ilk}_dpll()

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

The *_compute_dpll() functions generally contain
two things:
- huge pile of inline code to calculate the DPLL
  register value
- a few calls to helpers to calculate the
  DPLL_MD and FP register values

Pull the DPLL register value calculations into a helpers
as well, so that *_compute_dpll() can focus on higher
level tasks.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpll.c | 115 ++
 1 file changed, 75 insertions(+), 40 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c 
b/drivers/gpu/drm/i915/display/intel_dpll.c
index 9e1f94a2ce92..0625b9c436c2 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll.c
@@ -1013,17 +1013,15 @@ static u32 i965_dpll_md(const struct intel_crtc_state 
*crtc_state)
return (crtc_state->pixel_multiplier - 1) << 
DPLL_MD_UDI_MULTIPLIER_SHIFT;
 }
 
-static void i9xx_compute_dpll(struct intel_crtc_state *crtc_state,
- const struct dpll *clock,
- const struct dpll *reduced_clock)
+static u32 i9xx_dpll(const struct intel_crtc_state *crtc_state,
+const struct dpll *clock,
+const struct dpll *reduced_clock)
 {
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
u32 dpll;
 
-   i9xx_update_pll_dividers(crtc_state, clock, reduced_clock);
-
-   dpll = DPLL_VGA_MODE_DIS;
+   dpll = DPLL_VCO_ENABLE | DPLL_VGA_MODE_DIS;
 
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS))
dpll |= DPLLB_MODE_LVDS;
@@ -1082,24 +1080,33 @@ static void i9xx_compute_dpll(struct intel_crtc_state 
*crtc_state,
else
dpll |= PLL_REF_INPUT_DREFCLK;
 
-   dpll |= DPLL_VCO_ENABLE;
-   crtc_state->dpll_hw_state.dpll = dpll;
+   return dpll;
+}
+
+static void i9xx_compute_dpll(struct intel_crtc_state *crtc_state,
+ const struct dpll *clock,
+ const struct dpll *reduced_clock)
+{
+   struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+   struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+
+   i9xx_update_pll_dividers(crtc_state, clock, reduced_clock);
+
+   crtc_state->dpll_hw_state.dpll = i9xx_dpll(crtc_state, clock, 
reduced_clock);
 
if (DISPLAY_VER(dev_priv) >= 4)
crtc_state->dpll_hw_state.dpll_md = i965_dpll_md(crtc_state);
 }
 
-static void i8xx_compute_dpll(struct intel_crtc_state *crtc_state,
- const struct dpll *clock,
- const struct dpll *reduced_clock)
+static u32 i8xx_dpll(const struct intel_crtc_state *crtc_state,
+const struct dpll *clock,
+const struct dpll *reduced_clock)
 {
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
u32 dpll;
 
-   i9xx_update_pll_dividers(crtc_state, clock, reduced_clock);
-
-   dpll = DPLL_VGA_MODE_DIS;
+   dpll = DPLL_VCO_ENABLE | DPLL_VGA_MODE_DIS;
 
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
dpll |= (1 << (clock->p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
@@ -1136,8 +1143,16 @@ static void i8xx_compute_dpll(struct intel_crtc_state 
*crtc_state,
else
dpll |= PLL_REF_INPUT_DREFCLK;
 
-   dpll |= DPLL_VCO_ENABLE;
-   crtc_state->dpll_hw_state.dpll = dpll;
+   return dpll;
+}
+
+static void i8xx_compute_dpll(struct intel_crtc_state *crtc_state,
+ const struct dpll *clock,
+ const struct dpll *reduced_clock)
+{
+   i9xx_update_pll_dividers(crtc_state, clock, reduced_clock);
+
+   crtc_state->dpll_hw_state.dpll = i8xx_dpll(crtc_state, clock, 
reduced_clock);
 }
 
 static int hsw_crtc_compute_clock(struct intel_atomic_state *state,
@@ -1266,17 +1281,15 @@ static void ilk_update_pll_dividers(struct 
intel_crtc_state *crtc_state,
crtc_state->dpll_hw_state.fp1 = ilk_dpll_compute_fp(reduced_clock, 
factor);
 }
 
-static void ilk_compute_dpll(struct intel_crtc_state *crtc_state,
-const struct dpll *clock,
-const struct dpll *reduced_clock)
+static u32 ilk_dpll(const struct intel_crtc_state *crtc_state,
+   const struct dpll *clock,
+   const struct dpll *reduced_clock)
 {
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
u32 dpll;
 
-   ilk_update_pll_dividers(crtc_state, clock, reduced_clock);
-
-   dpll = 0;
+   dpll = DPLL_VCO_ENABLE;
 
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS))
dpll |= 

[PATCH 08/18] drm/i915: Pass the PLL hw_state to pll->enable()

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

Stop rummaging around inside pll->state directly in the low
level pll->enable() functions, and instead let the higher level
code figure out where the correct state is stored and pass it in.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 69 ++-
 1 file changed, 37 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c 
b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
index 51a7d8df0ca3..1a78093e41f5 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
@@ -64,7 +64,8 @@ struct intel_shared_dpll_funcs {
 * the pll is not already enabled.
 */
void (*enable)(struct drm_i915_private *i915,
-  struct intel_shared_dpll *pll);
+  struct intel_shared_dpll *pll,
+  const struct intel_dpll_hw_state *dpll_hw_state);
 
/*
 * Hook for disabling the pll, called from intel_disable_shared_dpll()
@@ -227,7 +228,7 @@ static void _intel_enable_shared_dpll(struct 
drm_i915_private *i915,
if (pll->info->power_domain)
pll->wakeref = intel_display_power_get(i915, 
pll->info->power_domain);
 
-   pll->info->funcs->enable(i915, pll);
+   pll->info->funcs->enable(i915, pll, >state.hw_state);
pll->on = true;
 }
 
@@ -553,9 +554,9 @@ static void ibx_assert_pch_refclk_enabled(struct 
drm_i915_private *i915)
 }
 
 static void ibx_pch_dpll_enable(struct drm_i915_private *i915,
-   struct intel_shared_dpll *pll)
+   struct intel_shared_dpll *pll,
+   const struct intel_dpll_hw_state *hw_state)
 {
-   const struct intel_dpll_hw_state *hw_state = >state.hw_state;
const enum intel_dpll_id id = pll->info->id;
 
/* PCH refclock must be enabled first */
@@ -677,9 +678,9 @@ static const struct intel_dpll_mgr pch_pll_mgr = {
 };
 
 static void hsw_ddi_wrpll_enable(struct drm_i915_private *i915,
-struct intel_shared_dpll *pll)
+struct intel_shared_dpll *pll,
+const struct intel_dpll_hw_state *hw_state)
 {
-   const struct intel_dpll_hw_state *hw_state = >state.hw_state;
const enum intel_dpll_id id = pll->info->id;
 
intel_de_write(i915, WRPLL_CTL(id), hw_state->wrpll);
@@ -688,10 +689,9 @@ static void hsw_ddi_wrpll_enable(struct drm_i915_private 
*i915,
 }
 
 static void hsw_ddi_spll_enable(struct drm_i915_private *i915,
-   struct intel_shared_dpll *pll)
+   struct intel_shared_dpll *pll,
+   const struct intel_dpll_hw_state *hw_state)
 {
-   const struct intel_dpll_hw_state *hw_state = >state.hw_state;
-
intel_de_write(i915, SPLL_CTL, hw_state->spll);
intel_de_posting_read(i915, SPLL_CTL);
udelay(20);
@@ -1259,7 +1259,8 @@ static const struct intel_shared_dpll_funcs 
hsw_ddi_spll_funcs = {
 };
 
 static void hsw_ddi_lcpll_enable(struct drm_i915_private *i915,
-struct intel_shared_dpll *pll)
+struct intel_shared_dpll *pll,
+const struct intel_dpll_hw_state *hw_state)
 {
 }
 
@@ -1337,9 +1338,9 @@ static const struct skl_dpll_regs skl_dpll_regs[4] = {
 };
 
 static void skl_ddi_pll_write_ctrl1(struct drm_i915_private *i915,
-   struct intel_shared_dpll *pll)
+   struct intel_shared_dpll *pll,
+   const struct intel_dpll_hw_state *hw_state)
 {
-   const struct intel_dpll_hw_state *hw_state = >state.hw_state;
const enum intel_dpll_id id = pll->info->id;
 
intel_de_rmw(i915, DPLL_CTRL1,
@@ -1351,13 +1352,13 @@ static void skl_ddi_pll_write_ctrl1(struct 
drm_i915_private *i915,
 }
 
 static void skl_ddi_pll_enable(struct drm_i915_private *i915,
-  struct intel_shared_dpll *pll)
+  struct intel_shared_dpll *pll,
+  const struct intel_dpll_hw_state *hw_state)
 {
-   const struct intel_dpll_hw_state *hw_state = >state.hw_state;
const struct skl_dpll_regs *regs = skl_dpll_regs;
const enum intel_dpll_id id = pll->info->id;
 
-   skl_ddi_pll_write_ctrl1(i915, pll);
+   skl_ddi_pll_write_ctrl1(i915, pll, hw_state);
 
intel_de_write(i915, regs[id].cfgcr1, hw_state->cfgcr1);
intel_de_write(i915, regs[id].cfgcr2, hw_state->cfgcr2);
@@ -1372,9 +1373,10 @@ static void skl_ddi_pll_enable(struct drm_i915_private 
*i915,
 }
 
 static void skl_ddi_dpll0_enable(struct drm_i915_private *i915,
-struct intel_shared_dpll *pll)
+struct 

[PATCH 11/18] drm/i915: Inline {i9xx,ilk}_update_pll_dividers()

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

Now that *_compute_dpll() are no longer a mess
{i9xx,ilk}_update_pll_dividers() don't serve any real
purpose anymore. Just inline them into the callers.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpll.c | 46 +++
 1 file changed, 13 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c 
b/drivers/gpu/drm/i915/display/intel_dpll.c
index 0625b9c436c2..43d36ea56798 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll.c
@@ -988,26 +988,6 @@ static u32 pnv_dpll_compute_fp(const struct dpll *dpll)
return (1 << dpll->n) << 16 | dpll->m2;
 }
 
-static void i9xx_update_pll_dividers(struct intel_crtc_state *crtc_state,
-const struct dpll *clock,
-const struct dpll *reduced_clock)
-{
-   struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-   struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-   u32 fp, fp2;
-
-   if (IS_PINEVIEW(dev_priv)) {
-   fp = pnv_dpll_compute_fp(clock);
-   fp2 = pnv_dpll_compute_fp(reduced_clock);
-   } else {
-   fp = i9xx_dpll_compute_fp(clock);
-   fp2 = i9xx_dpll_compute_fp(reduced_clock);
-   }
-
-   crtc_state->dpll_hw_state.fp0 = fp;
-   crtc_state->dpll_hw_state.fp1 = fp2;
-}
-
 static u32 i965_dpll_md(const struct intel_crtc_state *crtc_state)
 {
return (crtc_state->pixel_multiplier - 1) << 
DPLL_MD_UDI_MULTIPLIER_SHIFT;
@@ -1090,7 +1070,13 @@ static void i9xx_compute_dpll(struct intel_crtc_state 
*crtc_state,
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 
-   i9xx_update_pll_dividers(crtc_state, clock, reduced_clock);
+   if (IS_PINEVIEW(dev_priv)) {
+   crtc_state->dpll_hw_state.fp0 = pnv_dpll_compute_fp(clock);
+   crtc_state->dpll_hw_state.fp1 = 
pnv_dpll_compute_fp(reduced_clock);
+   } else {
+   crtc_state->dpll_hw_state.fp0 = i9xx_dpll_compute_fp(clock);
+   crtc_state->dpll_hw_state.fp1 = 
i9xx_dpll_compute_fp(reduced_clock);
+   }
 
crtc_state->dpll_hw_state.dpll = i9xx_dpll(crtc_state, clock, 
reduced_clock);
 
@@ -1150,7 +1136,8 @@ static void i8xx_compute_dpll(struct intel_crtc_state 
*crtc_state,
  const struct dpll *clock,
  const struct dpll *reduced_clock)
 {
-   i9xx_update_pll_dividers(crtc_state, clock, reduced_clock);
+   crtc_state->dpll_hw_state.fp0 = i9xx_dpll_compute_fp(clock);
+   crtc_state->dpll_hw_state.fp1 = i9xx_dpll_compute_fp(reduced_clock);
 
crtc_state->dpll_hw_state.dpll = i8xx_dpll(crtc_state, clock, 
reduced_clock);
 }
@@ -1271,16 +1258,6 @@ static u32 ilk_dpll_compute_fp(const struct dpll *clock, 
int factor)
return fp;
 }
 
-static void ilk_update_pll_dividers(struct intel_crtc_state *crtc_state,
-   const struct dpll *clock,
-   const struct dpll *reduced_clock)
-{
-   int factor = ilk_fb_cb_factor(crtc_state);
-
-   crtc_state->dpll_hw_state.fp0 = ilk_dpll_compute_fp(clock, factor);
-   crtc_state->dpll_hw_state.fp1 = ilk_dpll_compute_fp(reduced_clock, 
factor);
-}
-
 static u32 ilk_dpll(const struct intel_crtc_state *crtc_state,
const struct dpll *clock,
const struct dpll *reduced_clock)
@@ -1358,7 +1335,10 @@ static void ilk_compute_dpll(struct intel_crtc_state 
*crtc_state,
 const struct dpll *clock,
 const struct dpll *reduced_clock)
 {
-   ilk_update_pll_dividers(crtc_state, clock, reduced_clock);
+   int factor = ilk_fb_cb_factor(crtc_state);
+
+   crtc_state->dpll_hw_state.fp0 = ilk_dpll_compute_fp(clock, factor);
+   crtc_state->dpll_hw_state.fp1 = ilk_dpll_compute_fp(reduced_clock, 
factor);
 
crtc_state->dpll_hw_state.dpll = ilk_dpll(crtc_state, clock, 
reduced_clock);
 }
-- 
2.43.2



[PATCH 07/18] drm/i915: Extract i9xx_dpll_get_hw_state()

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

Start making the GMCH DPLL code a bit more like the more modern
platforms by separating out the DPLL hw state readout from the
rest of the pipe readout.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_display.c | 24 +++-
 drivers/gpu/drm/i915/display/intel_dpll.c| 30 
 drivers/gpu/drm/i915/display/intel_dpll.h|  3 ++
 3 files changed, 37 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index a92b67adee9c..70ba8a9c671e 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -3071,19 +3071,16 @@ static bool i9xx_get_pipe_config(struct intel_crtc 
*crtc,
 
i9xx_get_pfit_config(pipe_config);
 
+   i9xx_dpll_get_hw_state(crtc, _config->dpll_hw_state);
+
if (DISPLAY_VER(dev_priv) >= 4) {
-   /* No way to read it out on pipes B and C */
-   if (IS_CHERRYVIEW(dev_priv) && crtc->pipe != PIPE_A)
-   tmp = dev_priv->display.state.chv_dpll_md[crtc->pipe];
-   else
-   tmp = intel_de_read(dev_priv, DPLL_MD(crtc->pipe));
+   tmp = pipe_config->dpll_hw_state.dpll_md;
pipe_config->pixel_multiplier =
((tmp & DPLL_MD_UDI_MULTIPLIER_MASK)
 >> DPLL_MD_UDI_MULTIPLIER_SHIFT) + 1;
-   pipe_config->dpll_hw_state.dpll_md = tmp;
} else if (IS_I945G(dev_priv) || IS_I945GM(dev_priv) ||
   IS_G33(dev_priv) || IS_PINEVIEW(dev_priv)) {
-   tmp = intel_de_read(dev_priv, DPLL(crtc->pipe));
+   tmp = pipe_config->dpll_hw_state.dpll;
pipe_config->pixel_multiplier =
((tmp & SDVO_MULTIPLIER_MASK)
 >> SDVO_MULTIPLIER_SHIFT_HIRES) + 1;
@@ -3093,19 +3090,6 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
 * function. */
pipe_config->pixel_multiplier = 1;
}
-   pipe_config->dpll_hw_state.dpll = intel_de_read(dev_priv,
-   DPLL(crtc->pipe));
-   if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) {
-   pipe_config->dpll_hw_state.fp0 = intel_de_read(dev_priv,
-  FP0(crtc->pipe));
-   pipe_config->dpll_hw_state.fp1 = intel_de_read(dev_priv,
-  FP1(crtc->pipe));
-   } else {
-   /* Mask out read-only status bits. */
-   pipe_config->dpll_hw_state.dpll &= ~(DPLL_LOCK_VLV |
-DPLL_PORTC_READY_MASK |
-DPLL_PORTB_READY_MASK);
-   }
 
if (IS_CHERRYVIEW(dev_priv))
chv_crtc_clock_get(crtc, pipe_config);
diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c 
b/drivers/gpu/drm/i915/display/intel_dpll.c
index aa46e9e80786..693e22f06aee 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll.c
@@ -385,6 +385,36 @@ static int i9xx_pll_refclk(struct drm_device *dev,
return 48000;
 }
 
+void i9xx_dpll_get_hw_state(struct intel_crtc *crtc,
+   struct intel_dpll_hw_state *hw_state)
+{
+   struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+
+   if (DISPLAY_VER(dev_priv) >= 4) {
+   u32 tmp;
+
+   /* No way to read it out on pipes B and C */
+   if (IS_CHERRYVIEW(dev_priv) && crtc->pipe != PIPE_A)
+   tmp = dev_priv->display.state.chv_dpll_md[crtc->pipe];
+   else
+   tmp = intel_de_read(dev_priv, DPLL_MD(crtc->pipe));
+
+   hw_state->dpll_md = tmp;
+   }
+
+   hw_state->dpll = intel_de_read(dev_priv, DPLL(crtc->pipe));
+
+   if (!IS_VALLEYVIEW(dev_priv) && !IS_CHERRYVIEW(dev_priv)) {
+   hw_state->fp0 = intel_de_read(dev_priv, FP0(crtc->pipe));
+   hw_state->fp1 = intel_de_read(dev_priv, FP1(crtc->pipe));
+   } else {
+   /* Mask out read-only status bits. */
+   hw_state->dpll &= ~(DPLL_LOCK_VLV |
+   DPLL_PORTC_READY_MASK |
+   DPLL_PORTB_READY_MASK);
+   }
+}
+
 /* Returns the clock of the currently programmed mode of the given pipe. */
 void i9xx_crtc_clock_get(struct intel_crtc *crtc,
 struct intel_crtc_state *pipe_config)
diff --git a/drivers/gpu/drm/i915/display/intel_dpll.h 
b/drivers/gpu/drm/i915/display/intel_dpll.h
index ac01bb19cc6c..c11c18277266 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.h
+++ b/drivers/gpu/drm/i915/display/intel_dpll.h
@@ -13,6 +13,7 @@ struct 

[PATCH 06/18] drm/i915: Extract ilk_dpll_compute_fp()

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

Let's not repeat ourselves so much and pull the entire
PCH DPLL FP register value calculation into its own
function.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpll.c | 24 ---
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c 
b/drivers/gpu/drm/i915/display/intel_dpll.c
index 3278ca7a3be0..aa46e9e80786 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll.c
@@ -1213,23 +1213,25 @@ static bool ilk_needs_fb_cb_tune(const struct dpll 
*dpll, int factor)
return dpll->m < factor * dpll->n;
 }
 
+static u32 ilk_dpll_compute_fp(const struct dpll *clock, int factor)
+{
+   u32 fp;
+
+   fp = i9xx_dpll_compute_fp(clock);
+   if (ilk_needs_fb_cb_tune(clock, factor))
+   fp |= FP_CB_TUNE;
+
+   return fp;
+}
+
 static void ilk_update_pll_dividers(struct intel_crtc_state *crtc_state,
const struct dpll *clock,
const struct dpll *reduced_clock)
 {
int factor = ilk_fb_cb_factor(crtc_state);
-   u32 fp, fp2;
 
-   fp = i9xx_dpll_compute_fp(clock);
-   if (ilk_needs_fb_cb_tune(clock, factor))
-   fp |= FP_CB_TUNE;
-
-   fp2 = i9xx_dpll_compute_fp(reduced_clock);
-   if (ilk_needs_fb_cb_tune(reduced_clock, factor))
-   fp2 |= FP_CB_TUNE;
-
-   crtc_state->dpll_hw_state.fp0 = fp;
-   crtc_state->dpll_hw_state.fp1 = fp2;
+   crtc_state->dpll_hw_state.fp0 = ilk_dpll_compute_fp(clock, factor);
+   crtc_state->dpll_hw_state.fp1 = ilk_dpll_compute_fp(reduced_clock, 
factor);
 }
 
 static void ilk_compute_dpll(struct intel_crtc_state *crtc_state,
-- 
2.43.2



[PATCH 05/18] drm/i915: Extract ilk_fb_cb_factor()

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

Pull the code to calculate PCH DPLL tuning factor
into its own function. Helps declutter ilk_update_pll_dividers().

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpll.c | 32 ---
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c 
b/drivers/gpu/drm/i915/display/intel_dpll.c
index 3038655377ea..3278ca7a3be0 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll.c
@@ -1192,6 +1192,22 @@ static int mtl_crtc_compute_clock(struct 
intel_atomic_state *state,
return 0;
 }
 
+static int ilk_fb_cb_factor(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 (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS) &&
+   ((intel_panel_use_ssc(i915) && i915->display.vbt.lvds_ssc_freq == 
10) ||
+(HAS_PCH_IBX(i915) && intel_is_dual_link_lvds(i915
+   return 25;
+
+   if (crtc_state->sdvo_tv_clock)
+   return 20;
+
+   return 21;
+}
+
 static bool ilk_needs_fb_cb_tune(const struct dpll *dpll, int factor)
 {
return dpll->m < factor * dpll->n;
@@ -1201,22 +1217,8 @@ static void ilk_update_pll_dividers(struct 
intel_crtc_state *crtc_state,
const struct dpll *clock,
const struct dpll *reduced_clock)
 {
-   struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
-   struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+   int factor = ilk_fb_cb_factor(crtc_state);
u32 fp, fp2;
-   int factor;
-
-   /* Enable autotuning of the PLL clock (if permissible) */
-   factor = 21;
-   if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) {
-   if ((intel_panel_use_ssc(dev_priv) &&
-dev_priv->display.vbt.lvds_ssc_freq == 10) ||
-   (HAS_PCH_IBX(dev_priv) &&
-intel_is_dual_link_lvds(dev_priv)))
-   factor = 25;
-   } else if (crtc_state->sdvo_tv_clock) {
-   factor = 20;
-   }
 
fp = i9xx_dpll_compute_fp(clock);
if (ilk_needs_fb_cb_tune(clock, factor))
-- 
2.43.2



[PATCH 04/18] drm/i915: Introduce some local PLL state variables

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

Spinkle local PLL hw_state variables into various low
level PLL functions. Will make subsequent changes cleaner
when we don't have to touch so many places when renaming
struct members and whatnot.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 94 ++-
 1 file changed, 52 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c 
b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
index 5203c538672c..51a7d8df0ca3 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
@@ -555,15 +555,16 @@ static void ibx_assert_pch_refclk_enabled(struct 
drm_i915_private *i915)
 static void ibx_pch_dpll_enable(struct drm_i915_private *i915,
struct intel_shared_dpll *pll)
 {
+   const struct intel_dpll_hw_state *hw_state = >state.hw_state;
const enum intel_dpll_id id = pll->info->id;
 
/* PCH refclock must be enabled first */
ibx_assert_pch_refclk_enabled(i915);
 
-   intel_de_write(i915, PCH_FP0(id), pll->state.hw_state.fp0);
-   intel_de_write(i915, PCH_FP1(id), pll->state.hw_state.fp1);
+   intel_de_write(i915, PCH_FP0(id), hw_state->fp0);
+   intel_de_write(i915, PCH_FP1(id), hw_state->fp1);
 
-   intel_de_write(i915, PCH_DPLL(id), pll->state.hw_state.dpll);
+   intel_de_write(i915, PCH_DPLL(id), hw_state->dpll);
 
/* Wait for the clocks to stabilize. */
intel_de_posting_read(i915, PCH_DPLL(id));
@@ -574,7 +575,7 @@ static void ibx_pch_dpll_enable(struct drm_i915_private 
*i915,
 *
 * So write it again.
 */
-   intel_de_write(i915, PCH_DPLL(id), pll->state.hw_state.dpll);
+   intel_de_write(i915, PCH_DPLL(id), hw_state->dpll);
intel_de_posting_read(i915, PCH_DPLL(id));
udelay(200);
 }
@@ -678,9 +679,10 @@ static const struct intel_dpll_mgr pch_pll_mgr = {
 static void hsw_ddi_wrpll_enable(struct drm_i915_private *i915,
 struct intel_shared_dpll *pll)
 {
+   const struct intel_dpll_hw_state *hw_state = >state.hw_state;
const enum intel_dpll_id id = pll->info->id;
 
-   intel_de_write(i915, WRPLL_CTL(id), pll->state.hw_state.wrpll);
+   intel_de_write(i915, WRPLL_CTL(id), hw_state->wrpll);
intel_de_posting_read(i915, WRPLL_CTL(id));
udelay(20);
 }
@@ -688,7 +690,9 @@ static void hsw_ddi_wrpll_enable(struct drm_i915_private 
*i915,
 static void hsw_ddi_spll_enable(struct drm_i915_private *i915,
struct intel_shared_dpll *pll)
 {
-   intel_de_write(i915, SPLL_CTL, pll->state.hw_state.spll);
+   const struct intel_dpll_hw_state *hw_state = >state.hw_state;
+
+   intel_de_write(i915, SPLL_CTL, hw_state->spll);
intel_de_posting_read(i915, SPLL_CTL);
udelay(20);
 }
@@ -1019,11 +1023,12 @@ hsw_ddi_wrpll_compute_dpll(struct intel_atomic_state 
*state,
struct drm_i915_private *i915 = to_i915(state->base.dev);
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
+   struct intel_dpll_hw_state *hw_state = _state->dpll_hw_state;
unsigned int p, n2, r2;
 
hsw_ddi_calculate_wrpll(crtc_state->port_clock * 1000, , , );
 
-   crtc_state->dpll_hw_state.wrpll =
+   hw_state->wrpll =
WRPLL_PLL_ENABLE | WRPLL_REF_LCPLL |
WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) |
WRPLL_DIVIDER_POST(p);
@@ -1126,11 +1131,12 @@ hsw_ddi_spll_compute_dpll(struct intel_atomic_state 
*state,
 {
struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
+   struct intel_dpll_hw_state *hw_state = _state->dpll_hw_state;
 
if (drm_WARN_ON(crtc->base.dev, crtc_state->port_clock / 2 != 135000))
return -EINVAL;
 
-   crtc_state->dpll_hw_state.spll =
+   hw_state->spll =
SPLL_PLL_ENABLE | SPLL_FREQ_1350MHz | SPLL_REF_MUXED_SSC;
 
return 0;
@@ -1333,24 +1339,28 @@ static const struct skl_dpll_regs skl_dpll_regs[4] = {
 static void skl_ddi_pll_write_ctrl1(struct drm_i915_private *i915,
struct intel_shared_dpll *pll)
 {
+   const struct intel_dpll_hw_state *hw_state = >state.hw_state;
const enum intel_dpll_id id = pll->info->id;
 
intel_de_rmw(i915, DPLL_CTRL1,
-DPLL_CTRL1_HDMI_MODE(id) | DPLL_CTRL1_SSC(id) | 
DPLL_CTRL1_LINK_RATE_MASK(id),
-pll->state.hw_state.ctrl1 << (id * 6));
+DPLL_CTRL1_HDMI_MODE(id) |
+DPLL_CTRL1_SSC(id) |
+DPLL_CTRL1_LINK_RATE_MASK(id),
+hw_state->ctrl1 << (id * 6));
intel_de_posting_read(i915, DPLL_CTRL1);
 }
 
 static void skl_ddi_pll_enable(struct drm_i915_private *i915,
 

[PATCH 03/18] drm/i915: Rename PLL hw_state variables/arguments

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

We have zero consistency in out PLL state naming scheme. Try
to unify things a bit by using 'dpll_hw_state' for high level
stuff and just 'hw_state' for low level stuff. Currently both
are the same, but I want to unionize intel_dpll_hw_state at
which point using different names can make it more clear whether
we're talking about the whole union or just the embedded platform
specific struct.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 223 +-
 drivers/gpu/drm/i915/display/intel_dpll_mgr.h |   6 +-
 2 files changed, 115 insertions(+), 114 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c 
b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
index 9ff6c4cc2e4b..5203c538672c 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
@@ -81,7 +81,7 @@ struct intel_shared_dpll_funcs {
 */
bool (*get_hw_state)(struct drm_i915_private *i915,
 struct intel_shared_dpll *pll,
-struct intel_dpll_hw_state *hw_state);
+struct intel_dpll_hw_state *dpll_hw_state);
 
/*
 * Hook for calculating the pll's output frequency based on its passed
@@ -89,7 +89,7 @@ struct intel_shared_dpll_funcs {
 */
int (*get_freq)(struct drm_i915_private *i915,
const struct intel_shared_dpll *pll,
-   const struct intel_dpll_hw_state *pll_state);
+   const struct intel_dpll_hw_state *dpll_hw_state);
 };
 
 struct intel_dpll_mgr {
@@ -108,7 +108,7 @@ struct intel_dpll_mgr {
   struct intel_encoder *encoder);
void (*update_ref_clks)(struct drm_i915_private *i915);
void (*dump_hw_state)(struct drm_printer *p,
- const struct intel_dpll_hw_state *hw_state);
+ const struct intel_dpll_hw_state *dpll_hw_state);
bool (*compare_hw_state)(const struct intel_dpll_hw_state *a,
 const struct intel_dpll_hw_state *b);
 };
@@ -352,7 +352,7 @@ intel_dpll_mask_all(struct drm_i915_private *i915)
 static struct intel_shared_dpll *
 intel_find_shared_dpll(struct intel_atomic_state *state,
   const struct intel_crtc *crtc,
-  const struct intel_dpll_hw_state *pll_state,
+  const struct intel_dpll_hw_state *dpll_hw_state,
   unsigned long dpll_mask)
 {
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
@@ -379,9 +379,9 @@ intel_find_shared_dpll(struct intel_atomic_state *state,
continue;
}
 
-   if (memcmp(pll_state,
+   if (memcmp(dpll_hw_state,
   _dpll[pll->index].hw_state,
-  sizeof(*pll_state)) == 0) {
+  sizeof(*dpll_hw_state)) == 0) {
drm_dbg_kms(>drm,
"[CRTC:%d:%s] sharing existing %s (pipe 
mask 0x%x, active 0x%x)\n",
crtc->base.base.id, crtc->base.name,
@@ -430,14 +430,14 @@ static void
 intel_reference_shared_dpll(struct intel_atomic_state *state,
const struct intel_crtc *crtc,
const struct intel_shared_dpll *pll,
-   const struct intel_dpll_hw_state *pll_state)
+   const struct intel_dpll_hw_state *dpll_hw_state)
 {
struct intel_shared_dpll_state *shared_dpll;
 
shared_dpll = intel_atomic_get_shared_dpll_state(>base);
 
if (shared_dpll[pll->index].pipe_mask == 0)
-   shared_dpll[pll->index].hw_state = *pll_state;
+   shared_dpll[pll->index].hw_state = *dpll_hw_state;
 
intel_reference_shared_dpll_crtc(crtc, pll, _dpll[pll->index]);
 }
@@ -974,11 +974,11 @@ hsw_ddi_calculate_wrpll(int clock /* in Hz */,
 
 static int hsw_ddi_wrpll_get_freq(struct drm_i915_private *i915,
  const struct intel_shared_dpll *pll,
- const struct intel_dpll_hw_state *pll_state)
+ const struct intel_dpll_hw_state *hw_state)
 {
int refclk;
int n, p, r;
-   u32 wrpll = pll_state->wrpll;
+   u32 wrpll = hw_state->wrpll;
 
switch (wrpll & WRPLL_REF_MASK) {
case WRPLL_REF_SPECIAL_HSW:
@@ -1098,7 +1098,7 @@ hsw_ddi_lcpll_get_dpll(struct intel_crtc_state 
*crtc_state)
 
 static int hsw_ddi_lcpll_get_freq(struct drm_i915_private *i915,
  const struct intel_shared_dpll *pll,
- const struct intel_dpll_hw_state *pll_state)
+ const struct intel_dpll_hw_state *hw_state)
 {
int link_clock = 0;
 
@@ 

[PATCH 02/18] drm/i915: Use printer for the rest of PLL debugfs dump

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

Since we now have the printer around for intel_dpll_dump_hw_state()
use it for all the other PLL prints as well. Just to make the thing
looks less crazy.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_display_debugfs.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c 
b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index 73be72bf3f5c..35f9f86ef70f 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -644,17 +644,17 @@ static int i915_shared_dplls_info(struct seq_file *m, 
void *unused)
 
drm_modeset_lock_all(_priv->drm);
 
-   seq_printf(m, "PLL refclks: non-SSC: %d kHz, SSC: %d kHz\n",
+   drm_printf(, "PLL refclks: non-SSC: %d kHz, SSC: %d kHz\n",
   dev_priv->display.dpll.ref_clks.nssc,
   dev_priv->display.dpll.ref_clks.ssc);
 
for_each_shared_dpll(dev_priv, pll, i) {
-   seq_printf(m, "DPLL%i: %s, id: %i\n", pll->index,
+   drm_printf(, "DPLL%i: %s, id: %i\n", pll->index,
   pll->info->name, pll->info->id);
-   seq_printf(m, " pipe_mask: 0x%x, active: 0x%x, on: %s\n",
+   drm_printf(, " pipe_mask: 0x%x, active: 0x%x, on: %s\n",
   pll->state.pipe_mask, pll->active_mask,
   str_yes_no(pll->on));
-   seq_printf(m, " tracked hardware state:\n");
+   drm_printf(, " tracked hardware state:\n");
intel_dpll_dump_hw_state(dev_priv, , >state.hw_state);
}
drm_modeset_unlock_all(_priv->drm);
-- 
2.43.2



[PATCH 01/18] drm/i915: Replace hand rolled PLL state dump with intel_dpll_dump_hw_state()

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

Just use intel_dpll_dump_hw_state() instead of hand rolling it.

Signed-off-by: Ville Syrjälä 
---
 .../drm/i915/display/intel_display_debugfs.c  | 31 ++-
 1 file changed, 2 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c 
b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index 0feffe8d4e45..73be72bf3f5c 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -638,6 +638,7 @@ static int i915_display_capabilities(struct seq_file *m, 
void *unused)
 static int i915_shared_dplls_info(struct seq_file *m, void *unused)
 {
struct drm_i915_private *dev_priv = node_to_i915(m->private);
+   struct drm_printer p = drm_seq_file_printer(m);
struct intel_shared_dpll *pll;
int i;
 
@@ -654,35 +655,7 @@ static int i915_shared_dplls_info(struct seq_file *m, void 
*unused)
   pll->state.pipe_mask, pll->active_mask,
   str_yes_no(pll->on));
seq_printf(m, " tracked hardware state:\n");
-   seq_printf(m, " dpll:0x%08x\n", pll->state.hw_state.dpll);
-   seq_printf(m, " dpll_md: 0x%08x\n",
-  pll->state.hw_state.dpll_md);
-   seq_printf(m, " fp0: 0x%08x\n", pll->state.hw_state.fp0);
-   seq_printf(m, " fp1: 0x%08x\n", pll->state.hw_state.fp1);
-   seq_printf(m, " wrpll:   0x%08x\n", pll->state.hw_state.wrpll);
-   seq_printf(m, " cfgcr0:  0x%08x\n", pll->state.hw_state.cfgcr0);
-   seq_printf(m, " cfgcr1:  0x%08x\n", pll->state.hw_state.cfgcr1);
-   seq_printf(m, " div0:0x%08x\n", pll->state.hw_state.div0);
-   seq_printf(m, " mg_refclkin_ctl:0x%08x\n",
-  pll->state.hw_state.mg_refclkin_ctl);
-   seq_printf(m, " mg_clktop2_coreclkctl1: 0x%08x\n",
-  pll->state.hw_state.mg_clktop2_coreclkctl1);
-   seq_printf(m, " mg_clktop2_hsclkctl:0x%08x\n",
-  pll->state.hw_state.mg_clktop2_hsclkctl);
-   seq_printf(m, " mg_pll_div0:  0x%08x\n",
-  pll->state.hw_state.mg_pll_div0);
-   seq_printf(m, " mg_pll_div1:  0x%08x\n",
-  pll->state.hw_state.mg_pll_div1);
-   seq_printf(m, " mg_pll_lf:0x%08x\n",
-  pll->state.hw_state.mg_pll_lf);
-   seq_printf(m, " mg_pll_frac_lock: 0x%08x\n",
-  pll->state.hw_state.mg_pll_frac_lock);
-   seq_printf(m, " mg_pll_ssc:   0x%08x\n",
-  pll->state.hw_state.mg_pll_ssc);
-   seq_printf(m, " mg_pll_bias:  0x%08x\n",
-  pll->state.hw_state.mg_pll_bias);
-   seq_printf(m, " mg_pll_tdc_coldst_bias: 0x%08x\n",
-  pll->state.hw_state.mg_pll_tdc_coldst_bias);
+   intel_dpll_dump_hw_state(dev_priv, , >state.hw_state);
}
drm_modeset_unlock_all(_priv->drm);
 
-- 
2.43.2



[PATCH 00/18] drm/i915: PLL refactoring

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

A bunch of refactoring around PLLs. Main feature is 
the unionization of dpll_hw_state. The eventual goal
is to unify the approach for PLLs across all platforms
instead of the current "shared PLLs are somehow
different than other PLLs" approach.

Ville Syrjälä (18):
  drm/i915: Replace hand rolled PLL state dump with
intel_dpll_dump_hw_state()
  drm/i915: Use printer for the rest of PLL debugfs dump
  drm/i915: Rename PLL hw_state variables/arguments
  drm/i915: Introduce some local PLL state variables
  drm/i915: Extract ilk_fb_cb_factor()
  drm/i915: Extract ilk_dpll_compute_fp()
  drm/i915: Extract i9xx_dpll_get_hw_state()
  drm/i915: Pass the PLL hw_state to pll->enable()
  drm/i915: Extract i965_dpll_md()
  drm/i915: Extract {i9xx,i8xx,ilk}_dpll()
  drm/i915: Inline {i9xx,ilk}_update_pll_dividers()
  drm/i915: Modernize i9xx_pll_refclk()
  drm/i915: Drop pointless 'crtc' argument from *_crtc_clock_get()
  drm/i915: s/pipe_config/crtc_state/ in legacy PLL code
  drm/i915: Add local DPLL 'hw_state' variables
  drm/i915: Carve up struct intel_dpll_hw_state
  drm/i915: Unionize dpll_hw_state
  drm/i915: Suck snps/cx0 PLL states into dpll_hw_state

 drivers/gpu/drm/i915/display/intel_cx0_phy.c  |  20 +-
 drivers/gpu/drm/i915/display/intel_ddi.c  |   8 +-
 drivers/gpu/drm/i915/display/intel_display.c  |  30 +-
 .../drm/i915/display/intel_display_debugfs.c  |  39 +-
 .../drm/i915/display/intel_display_types.h|  43 +-
 drivers/gpu/drm/i915/display/intel_dpll.c | 338 +++-
 drivers/gpu/drm/i915/display/intel_dpll.h |  12 +-
 drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 489 ++
 drivers/gpu/drm/i915/display/intel_dpll_mgr.h |  80 ++-
 .../gpu/drm/i915/display/intel_pch_display.c  |   4 +-
 drivers/gpu/drm/i915/display/intel_snps_phy.c |   6 +-
 11 files changed, 581 insertions(+), 488 deletions(-)

-- 
2.43.2



[PATCH 8/8] drm/i915: Enable per-lane DP drive settings for bxt/glk

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

Now the bxt/glk PHY code is ready for per-lane drive settings
so enable it.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dp_link_training.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c 
b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
index fb84ca98bb7a..947575140059 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -334,7 +334,7 @@ static bool has_per_lane_signal_levels(struct intel_dp 
*intel_dp,
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 
return !intel_dp_phy_is_downstream_of_source(intel_dp, dp_phy) ||
-   DISPLAY_VER(i915) >= 11;
+   DISPLAY_VER(i915) >= 10 || IS_BROXTON(i915);
 }
 
 /* 128b/132b */
-- 
2.43.2



[PATCH 4/8] drm/i915/dpio: Introdude bxt_ddi_phy_rmw_grp()

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

Add a helper to do the "read from one per-lane register
and write to the group register" rmw cycle.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpio_phy.c | 59 ---
 1 file changed, 38 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c 
b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
index a793a872dfa3..3d1295da1106 100644
--- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
@@ -270,6 +270,24 @@ void bxt_port_to_phy_channel(struct drm_i915_private 
*dev_priv, enum port port,
*ch = DPIO_CH0;
 }
 
+/*
+ * Like intel_de_rmw() but reads from a single per-lane register and
+ * writes to the group register to write the same value to all the lanes.
+ */
+static u32 bxt_ddi_phy_rmw_grp(struct drm_i915_private *i915,
+  i915_reg_t reg_single,
+  i915_reg_t reg_group,
+  u32 clear, u32 set)
+{
+   u32 old, val;
+
+   old = intel_de_read(i915, reg_single);
+   val = (old & ~clear) | set;
+   intel_de_write(i915, reg_group, val);
+
+   return old;
+}
+
 void bxt_ddi_phy_set_signal_levels(struct intel_encoder *encoder,
   const struct intel_crtc_state *crtc_state)
 {
@@ -291,35 +309,34 @@ void bxt_ddi_phy_set_signal_levels(struct intel_encoder 
*encoder,
 * While we write to the group register to program all lanes at once we
 * can read only lane registers and we pick lanes 0/1 for that.
 */
-   val = intel_de_read(dev_priv, BXT_PORT_PCS_DW10_LN01(phy, ch));
-   val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
-   intel_de_write(dev_priv, BXT_PORT_PCS_DW10_GRP(phy, ch), val);
+   bxt_ddi_phy_rmw_grp(dev_priv, BXT_PORT_PCS_DW10_LN01(phy, ch),
+   BXT_PORT_PCS_DW10_GRP(phy, ch),
+   TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT, 0);
 
-   val = intel_de_read(dev_priv, BXT_PORT_TX_DW2_LN(phy, ch, 0));
-   val &= ~(MARGIN_000_MASK | UNIQ_TRANS_SCALE_MASK);
-   val |= MARGIN_000(trans->entries[level].bxt.margin) |
-   UNIQ_TRANS_SCALE(trans->entries[level].bxt.scale);
-   intel_de_write(dev_priv, BXT_PORT_TX_DW2_GRP(phy, ch), val);
+   bxt_ddi_phy_rmw_grp(dev_priv, BXT_PORT_TX_DW2_LN(phy, ch, 0),
+   BXT_PORT_TX_DW2_GRP(phy, ch),
+   MARGIN_000_MASK | UNIQ_TRANS_SCALE_MASK,
+   MARGIN_000(trans->entries[level].bxt.margin) |
+   UNIQ_TRANS_SCALE(trans->entries[level].bxt.scale));
+
+   bxt_ddi_phy_rmw_grp(dev_priv, BXT_PORT_TX_DW3_LN(phy, ch, 0),
+   BXT_PORT_TX_DW3_GRP(phy, ch),
+   SCALE_DCOMP_METHOD,
+   trans->entries[level].bxt.enable ?
+   SCALE_DCOMP_METHOD : 0);
 
val = intel_de_read(dev_priv, BXT_PORT_TX_DW3_LN(phy, ch, 0));
-   val &= ~SCALE_DCOMP_METHOD;
-   if (trans->entries[level].bxt.enable)
-   val |= SCALE_DCOMP_METHOD;
-
if ((val & UNIQUE_TRANGE_EN_METHOD) && !(val & SCALE_DCOMP_METHOD))
drm_err(_priv->drm,
"Disabled scaling while ouniqetrangenmethod was set");
 
-   intel_de_write(dev_priv, BXT_PORT_TX_DW3_GRP(phy, ch), val);
+   bxt_ddi_phy_rmw_grp(dev_priv, BXT_PORT_TX_DW4_LN(phy, ch, 0),
+   BXT_PORT_TX_DW4_GRP(phy, ch), DE_EMPHASIS_MASK,
+   DE_EMPHASIS(trans->entries[level].bxt.deemphasis));
 
-   val = intel_de_read(dev_priv, BXT_PORT_TX_DW4_LN(phy, ch, 0));
-   val &= ~DE_EMPHASIS_MASK;
-   val |= DE_EMPHASIS(trans->entries[level].bxt.deemphasis);
-   intel_de_write(dev_priv, BXT_PORT_TX_DW4_GRP(phy, ch), val);
-
-   val = intel_de_read(dev_priv, BXT_PORT_PCS_DW10_LN01(phy, ch));
-   val |= TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT;
-   intel_de_write(dev_priv, BXT_PORT_PCS_DW10_GRP(phy, ch), val);
+   bxt_ddi_phy_rmw_grp(dev_priv, BXT_PORT_PCS_DW10_LN01(phy, ch),
+   BXT_PORT_PCS_DW10_GRP(phy, ch),
+   0, TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
 }
 
 bool bxt_ddi_phy_is_enabled(struct drm_i915_private *dev_priv,
-- 
2.43.2



[PATCH 7/8] drm/i915/dpio: Program bxt/glk PHY TX registers per-lane

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

Program each bxt/glk PHY TX lane with its own settings
instead of blasting them all with the same stuff via
group access.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpio_phy.c | 35 ---
 1 file changed, 22 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c 
b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
index 77597edb391c..c72b76b61dff 100644
--- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
@@ -292,12 +292,10 @@ void bxt_dpio_phy_set_signal_levels(struct intel_encoder 
*encoder,
const struct intel_crtc_state *crtc_state)
 {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-   int level = intel_ddi_level(encoder, crtc_state, 0);
const struct intel_ddi_buf_trans *trans;
enum dpio_channel ch;
enum dpio_phy phy;
-   int n_entries;
-   u32 val;
+   int lane, n_entries;
 
trans = encoder->get_buf_trans(encoder, crtc_state, _entries);
if (drm_WARN_ON_ONCE(_priv->drm, !trans))
@@ -313,26 +311,37 @@ void bxt_dpio_phy_set_signal_levels(struct intel_encoder 
*encoder,
 BXT_PORT_PCS_DW10_GRP(phy, ch),
 TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT, 0);
 
-   bxt_dpio_phy_rmw_grp(dev_priv, BXT_PORT_TX_DW2_LN(phy, ch, 0),
-BXT_PORT_TX_DW2_GRP(phy, ch),
+   for (lane = 0; lane < crtc_state->lane_count; lane++) {
+   int level = intel_ddi_level(encoder, crtc_state, lane);
+
+   intel_de_rmw(dev_priv, BXT_PORT_TX_DW2_LN(phy, ch, lane),
 MARGIN_000_MASK | UNIQ_TRANS_SCALE_MASK,
 MARGIN_000(trans->entries[level].bxt.margin) |
 UNIQ_TRANS_SCALE(trans->entries[level].bxt.scale));
+   }
 
-   bxt_dpio_phy_rmw_grp(dev_priv, BXT_PORT_TX_DW3_LN(phy, ch, 0),
-BXT_PORT_TX_DW3_GRP(phy, ch),
+   for (lane = 0; lane < crtc_state->lane_count; lane++) {
+   int level = intel_ddi_level(encoder, crtc_state, lane);
+   u32 val;
+
+   intel_de_rmw(dev_priv, BXT_PORT_TX_DW3_LN(phy, ch, lane),
 SCALE_DCOMP_METHOD,
 trans->entries[level].bxt.enable ?
 SCALE_DCOMP_METHOD : 0);
 
-   val = intel_de_read(dev_priv, BXT_PORT_TX_DW3_LN(phy, ch, 0));
-   if ((val & UNIQUE_TRANGE_EN_METHOD) && !(val & SCALE_DCOMP_METHOD))
-   drm_err(_priv->drm,
-   "Disabled scaling while ouniqetrangenmethod was set");
+   val = intel_de_read(dev_priv, BXT_PORT_TX_DW3_LN(phy, ch, 
lane));
+   if ((val & UNIQUE_TRANGE_EN_METHOD) && !(val & 
SCALE_DCOMP_METHOD))
+   drm_err(_priv->drm,
+   "Disabled scaling while ouniqetrangenmethod was 
set");
+   }
 
-   bxt_dpio_phy_rmw_grp(dev_priv, BXT_PORT_TX_DW4_LN(phy, ch, 0),
-BXT_PORT_TX_DW4_GRP(phy, ch), DE_EMPHASIS_MASK,
+   for (lane = 0; lane < crtc_state->lane_count; lane++) {
+   int level = intel_ddi_level(encoder, crtc_state, lane);
+
+   intel_de_rmw(dev_priv, BXT_PORT_TX_DW4_LN(phy, ch, lane),
+DE_EMPHASIS_MASK,
 DE_EMPHASIS(trans->entries[level].bxt.deemphasis));
+   }
 
bxt_dpio_phy_rmw_grp(dev_priv, BXT_PORT_PCS_DW10_LN01(phy, ch),
 BXT_PORT_PCS_DW10_GRP(phy, ch),
-- 
2.43.2



[PATCH 6/8] drm/i915/dpio: s/ddi/dpio/ for bxt/glk PHY stuff

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

Since all of this lives in intel_dpio_phy.c let's rename the
bxt/glk functions to have bxt_dpio_phy_ namespace.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_ddi.c  |  10 +-
 .../i915/display/intel_display_power_well.c   |  18 +--
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |   2 +-
 drivers/gpu/drm/i915/display/intel_dpio_phy.c | 122 +-
 drivers/gpu/drm/i915/display/intel_dpio_phy.h |  48 +++
 5 files changed, 100 insertions(+), 100 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index 3255d4e375af..a42c7f8abba0 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3517,8 +3517,8 @@ intel_ddi_pre_pll_enable(struct intel_atomic_state *state,
 */
intel_tc_port_set_fia_lane_count(dig_port, 
crtc_state->lane_count);
else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
-   bxt_ddi_phy_set_lane_optim_mask(encoder,
-   
crtc_state->lane_lat_optim_mask);
+   bxt_dpio_phy_set_lane_optim_mask(encoder,
+
crtc_state->lane_lat_optim_mask);
 }
 
 static void adlp_tbt_to_dp_alt_switch_wa(struct intel_encoder *encoder)
@@ -3950,7 +3950,7 @@ static void intel_ddi_get_config(struct intel_encoder 
*encoder,
 
if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
pipe_config->lane_lat_optim_mask =
-   bxt_ddi_phy_get_lane_lat_optim_mask(encoder);
+   bxt_dpio_phy_get_lane_lat_optim_mask(encoder);
 
intel_ddi_compute_min_voltage_level(pipe_config);
 
@@ -4227,7 +4227,7 @@ static int intel_ddi_compute_config(struct intel_encoder 
*encoder,
 
if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv))
pipe_config->lane_lat_optim_mask =
-   
bxt_ddi_phy_calc_lane_lat_optim_mask(pipe_config->lane_count);
+   
bxt_dpio_phy_calc_lane_lat_optim_mask(pipe_config->lane_count);
 
intel_ddi_compute_min_voltage_level(pipe_config);
 
@@ -5079,7 +5079,7 @@ void intel_ddi_init(struct drm_i915_private *dev_priv,
else
encoder->set_signal_levels = 
icl_mg_phy_set_signal_levels;
} else if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) {
-   encoder->set_signal_levels = bxt_ddi_phy_set_signal_levels;
+   encoder->set_signal_levels = bxt_dpio_phy_set_signal_levels;
} else {
encoder->set_signal_levels = hsw_set_signal_levels;
}
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 e4de40228997..95609467664f 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power_well.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power_well.c
@@ -900,39 +900,39 @@ static void hsw_power_well_sync_hw(struct 
drm_i915_private *dev_priv,
 static void bxt_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv,
   struct i915_power_well *power_well)
 {
-   bxt_ddi_phy_init(dev_priv, 
i915_power_well_instance(power_well)->bxt.phy);
+   bxt_dpio_phy_init(dev_priv, 
i915_power_well_instance(power_well)->bxt.phy);
 }
 
 static void bxt_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
 {
-   bxt_ddi_phy_uninit(dev_priv, 
i915_power_well_instance(power_well)->bxt.phy);
+   bxt_dpio_phy_uninit(dev_priv, 
i915_power_well_instance(power_well)->bxt.phy);
 }
 
 static bool bxt_dpio_cmn_power_well_enabled(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
 {
-   return bxt_ddi_phy_is_enabled(dev_priv, 
i915_power_well_instance(power_well)->bxt.phy);
+   return bxt_dpio_phy_is_enabled(dev_priv, 
i915_power_well_instance(power_well)->bxt.phy);
 }
 
-static void bxt_verify_ddi_phy_power_wells(struct drm_i915_private *dev_priv)
+static void bxt_verify_dpio_phy_power_wells(struct drm_i915_private *dev_priv)
 {
struct i915_power_well *power_well;
 
power_well = lookup_power_well(dev_priv, BXT_DISP_PW_DPIO_CMN_A);
if (intel_power_well_refcount(power_well) > 0)
-   bxt_ddi_phy_verify_state(dev_priv, 
i915_power_well_instance(power_well)->bxt.phy);
+   bxt_dpio_phy_verify_state(dev_priv, 
i915_power_well_instance(power_well)->bxt.phy);
 
power_well = lookup_power_well(dev_priv, VLV_DISP_PW_DPIO_CMN_BC);
if (intel_power_well_refcount(power_well) > 0)
-   bxt_ddi_phy_verify_state(dev_priv, 
i915_power_well_instance(power_well)->bxt.phy);
+   bxt_dpio_phy_verify_state(dev_priv, 

[PATCH 5/8] drm/i915/dpio: Use intel_de_rmw() for BXT DPIO latency optim setup

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

Replace the hand rolled intel_de_rmw() with the real thing.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpio_phy.c | 12 +++-
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c 
b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
index 3d1295da1106..377963c0ed5f 100644
--- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
@@ -613,19 +613,13 @@ void bxt_ddi_phy_set_lane_optim_mask(struct intel_encoder 
*encoder,
bxt_port_to_phy_channel(dev_priv, port, , );
 
for (lane = 0; lane < 4; lane++) {
-   u32 val = intel_de_read(dev_priv,
-   BXT_PORT_TX_DW14_LN(phy, ch, lane));
-
/*
 * Note that on CHV this flag is called UPAR, but has
 * the same function.
 */
-   val &= ~LATENCY_OPTIM;
-   if (lane_lat_optim_mask & BIT(lane))
-   val |= LATENCY_OPTIM;
-
-   intel_de_write(dev_priv, BXT_PORT_TX_DW14_LN(phy, ch, lane),
-  val);
+   intel_de_rmw(dev_priv, BXT_PORT_TX_DW14_LN(phy, ch, lane),
+LATENCY_OPTIM,
+lane_lat_optim_mask & BIT(lane) ? LATENCY_OPTIM : 
0);
}
 }
 
-- 
2.43.2



[PATCH 3/8] drm/i915/dpio: Extract bxt_dpio_phy_regs.h

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

Extract the BXT/GLK DPIO PHY register definitions into their own file.

Signed-off-by: Ville Syrjälä 
---
 .../gpu/drm/i915/display/bxt_dpio_phy_regs.h  | 273 ++
 drivers/gpu/drm/i915/display/intel_dpio_phy.c |   1 +
 drivers/gpu/drm/i915/display/intel_dpll_mgr.c |   1 +
 drivers/gpu/drm/i915/i915_reg.h   | 262 -
 4 files changed, 275 insertions(+), 262 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/display/bxt_dpio_phy_regs.h

diff --git a/drivers/gpu/drm/i915/display/bxt_dpio_phy_regs.h 
b/drivers/gpu/drm/i915/display/bxt_dpio_phy_regs.h
new file mode 100644
index ..275f4d9c3fb0
--- /dev/null
+++ b/drivers/gpu/drm/i915/display/bxt_dpio_phy_regs.h
@@ -0,0 +1,273 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#ifndef __BXT_DPIO_PHY_REGS_H__
+#define __BXT_DPIO_PHY_REGS_H__
+
+#include "intel_display_reg_defs.h"
+
+/* BXT PHY registers */
+#define _BXT_PHY0_BASE 0x6C000
+#define _BXT_PHY1_BASE 0x162000
+#define _BXT_PHY2_BASE 0x163000
+#define BXT_PHY_BASE(phy) \
+_PICK_EVEN_2RANGES(phy, 1, \
+   _BXT_PHY0_BASE, _BXT_PHY0_BASE, \
+   _BXT_PHY1_BASE, _BXT_PHY2_BASE)
+
+#define _BXT_PHY(phy, reg) \
+   _MMIO(BXT_PHY_BASE(phy) - _BXT_PHY0_BASE + (reg))
+
+#define _BXT_PHY_CH(phy, ch, reg_ch0, reg_ch1) \
+   (BXT_PHY_BASE(phy) + _PIPE((ch), (reg_ch0) - _BXT_PHY0_BASE, \
+(reg_ch1) - _BXT_PHY0_BASE))
+#define _MMIO_BXT_PHY_CH(phy, ch, reg_ch0, reg_ch1) \
+   _MMIO(_BXT_PHY_CH(phy, ch, reg_ch0, reg_ch1))
+#define _BXT_LANE_OFFSET(lane)   (((lane) >> 1) * 0x200 + \
+ ((lane) & 1) * 0x80)
+#define _MMIO_BXT_PHY_CH_LN(phy, ch, lane, reg_ch0, reg_ch1) \
+   _MMIO(_BXT_PHY_CH(phy, ch, reg_ch0, reg_ch1) + _BXT_LANE_OFFSET(lane))
+
+/* BXT PHY PLL registers */
+#define _PORT_PLL_A0x46074
+#define _PORT_PLL_B0x46078
+#define _PORT_PLL_C0x4607c
+#define   PORT_PLL_ENABLE  REG_BIT(31)
+#define   PORT_PLL_LOCKREG_BIT(30)
+#define   PORT_PLL_REF_SEL REG_BIT(27)
+#define   PORT_PLL_POWER_ENABLEREG_BIT(26)
+#define   PORT_PLL_POWER_STATE REG_BIT(25)
+#define BXT_PORT_PLL_ENABLE(port)  _MMIO_PORT(port, _PORT_PLL_A, 
_PORT_PLL_B)
+
+#define _PORT_PLL_EBB_0_A  0x162034
+#define _PORT_PLL_EBB_0_B  0x6C034
+#define _PORT_PLL_EBB_0_C  0x6C340
+#define   PORT_PLL_P1_MASK REG_GENMASK(15, 13)
+#define   PORT_PLL_P1(p1)  REG_FIELD_PREP(PORT_PLL_P1_MASK, (p1))
+#define   PORT_PLL_P2_MASK REG_GENMASK(12, 8)
+#define   PORT_PLL_P2(p2)  REG_FIELD_PREP(PORT_PLL_P2_MASK, (p2))
+#define BXT_PORT_PLL_EBB_0(phy, ch)_MMIO_BXT_PHY_CH(phy, ch, \
+_PORT_PLL_EBB_0_B, \
+_PORT_PLL_EBB_0_C)
+
+#define _PORT_PLL_EBB_4_A  0x162038
+#define _PORT_PLL_EBB_4_B  0x6C038
+#define _PORT_PLL_EBB_4_C  0x6C344
+#define   PORT_PLL_RECALIBRATE REG_BIT(14)
+#define   PORT_PLL_10BIT_CLK_ENABLEREG_BIT(13)
+#define BXT_PORT_PLL_EBB_4(phy, ch)_MMIO_BXT_PHY_CH(phy, ch, \
+_PORT_PLL_EBB_4_B, \
+_PORT_PLL_EBB_4_C)
+
+#define _PORT_PLL_0_A  0x162100
+#define _PORT_PLL_0_B  0x6C100
+#define _PORT_PLL_0_C  0x6C380
+/* PORT_PLL_0_A */
+#define   PORT_PLL_M2_INT_MASK REG_GENMASK(7, 0)
+#define   PORT_PLL_M2_INT(m2_int)  REG_FIELD_PREP(PORT_PLL_M2_INT_MASK, 
(m2_int))
+/* PORT_PLL_1_A */
+#define   PORT_PLL_N_MASK  REG_GENMASK(11, 8)
+#define   PORT_PLL_N(n)REG_FIELD_PREP(PORT_PLL_N_MASK, 
(n))
+/* PORT_PLL_2_A */
+#define   PORT_PLL_M2_FRAC_MASKREG_GENMASK(21, 0)
+#define   PORT_PLL_M2_FRAC(m2_frac)REG_FIELD_PREP(PORT_PLL_M2_FRAC_MASK, 
(m2_frac))
+/* PORT_PLL_3_A */
+#define   PORT_PLL_M2_FRAC_ENABLE  REG_BIT(16)
+/* PORT_PLL_6_A */
+#define   PORT_PLL_GAIN_CTL_MASK   REG_GENMASK(18, 16)
+#define   PORT_PLL_GAIN_CTL(x) REG_FIELD_PREP(PORT_PLL_GAIN_CTL_MASK, 
(x))
+#define   PORT_PLL_INT_COEFF_MASK  REG_GENMASK(12, 8)
+#define   PORT_PLL_INT_COEFF(x)
REG_FIELD_PREP(PORT_PLL_INT_COEFF_MASK, (x))
+#define   PORT_PLL_PROP_COEFF_MASK REG_GENMASK(3, 0)
+#define   PORT_PLL_PROP_COEFF(x)   
REG_FIELD_PREP(PORT_PLL_PROP_COEFF_MASK, (x))
+/* PORT_PLL_8_A */
+#define   PORT_PLL_TARGET_CNT_MASK REG_GENMASK(9, 0)
+#define   PORT_PLL_TARGET_CNT(x)   
REG_FIELD_PREP(PORT_PLL_TARGET_CNT_MASK, (x))
+/* 

[PATCH 2/8] drm/i915/dpio: Add per-lane PHY TX register definitons for bxt/glk

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

Add consistent definitions for the per-lane PHY TX registers
on bxt/glk. The current situation is a slight mess with some
registers having a LN0 define, while others have a parametrized
per-lane definition.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpio_phy.c |  6 +--
 drivers/gpu/drm/i915/display/intel_dpll_mgr.c |  2 +-
 drivers/gpu/drm/i915/i915_reg.h   | 38 +--
 3 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c 
b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
index d14e80ece8aa..50d6b412d652 100644
--- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
@@ -294,13 +294,13 @@ void bxt_ddi_phy_set_signal_levels(struct intel_encoder 
*encoder,
val &= ~(TX2_SWING_CALC_INIT | TX1_SWING_CALC_INIT);
intel_de_write(dev_priv, BXT_PORT_PCS_DW10_GRP(phy, ch), val);
 
-   val = intel_de_read(dev_priv, BXT_PORT_TX_DW2_LN0(phy, ch));
+   val = intel_de_read(dev_priv, BXT_PORT_TX_DW2_LN(phy, ch, 0));
val &= ~(MARGIN_000_MASK | UNIQ_TRANS_SCALE_MASK);
val |= MARGIN_000(trans->entries[level].bxt.margin) |
UNIQ_TRANS_SCALE(trans->entries[level].bxt.scale);
intel_de_write(dev_priv, BXT_PORT_TX_DW2_GRP(phy, ch), val);
 
-   val = intel_de_read(dev_priv, BXT_PORT_TX_DW3_LN0(phy, ch));
+   val = intel_de_read(dev_priv, BXT_PORT_TX_DW3_LN(phy, ch, 0));
val &= ~SCALE_DCOMP_METHOD;
if (trans->entries[level].bxt.enable)
val |= SCALE_DCOMP_METHOD;
@@ -311,7 +311,7 @@ void bxt_ddi_phy_set_signal_levels(struct intel_encoder 
*encoder,
 
intel_de_write(dev_priv, BXT_PORT_TX_DW3_GRP(phy, ch), val);
 
-   val = intel_de_read(dev_priv, BXT_PORT_TX_DW4_LN0(phy, ch));
+   val = intel_de_read(dev_priv, BXT_PORT_TX_DW4_LN(phy, ch, 0));
val &= ~DE_EMPHASIS_MASK;
val |= DE_EMPHASIS(trans->entries[level].bxt.deemphasis);
intel_de_write(dev_priv, BXT_PORT_TX_DW4_GRP(phy, ch), val);
diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c 
b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
index 9ff6c4cc2e4b..cc3acdafdbf8 100644
--- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
+++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
@@ -2071,7 +2071,7 @@ static void bxt_ddi_pll_enable(struct drm_i915_private 
*i915,
drm_err(>drm, "PLL %d not locked\n", port);
 
if (IS_GEMINILAKE(i915)) {
-   temp = intel_de_read(i915, BXT_PORT_TX_DW5_LN0(phy, ch));
+   temp = intel_de_read(i915, BXT_PORT_TX_DW5_LN(phy, ch, 0));
temp |= DCC_DELAY_RANGE_2;
intel_de_write(i915, BXT_PORT_TX_DW5_GRP(phy, ch), temp);
}
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 9701aad57e3a..261b520da399 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -555,6 +555,10 @@
 (reg_ch1) - _BXT_PHY0_BASE))
 #define _MMIO_BXT_PHY_CH(phy, ch, reg_ch0, reg_ch1)\
_MMIO(_BXT_PHY_CH(phy, ch, reg_ch0, reg_ch1))
+#define _BXT_LANE_OFFSET(lane)   (((lane) >> 1) * 0x200 + \
+ ((lane) & 1) * 0x80)
+#define _MMIO_BXT_PHY_CH_LN(phy, ch, lane, reg_ch0, reg_ch1) \
+   _MMIO(_BXT_PHY_CH(phy, ch, reg_ch0, reg_ch1) + _BXT_LANE_OFFSET(lane))
 
 #define BXT_P_CR_GT_DISP_PWRON _MMIO(0x138090)
 #define  MIPIO_RST_CTRL(1 << 2)
@@ -747,18 +751,15 @@
 _PORT_PCS_DW12_GRP_C)
 
 /* BXT PHY TX registers */
-#define _BXT_LANE_OFFSET(lane)   (((lane) >> 1) * 0x200 +  \
- ((lane) & 1) * 0x80)
-
 #define _PORT_TX_DW2_LN0_A 0x162508
 #define _PORT_TX_DW2_LN0_B 0x6C508
 #define _PORT_TX_DW2_LN0_C 0x6C908
 #define _PORT_TX_DW2_GRP_A 0x162D08
 #define _PORT_TX_DW2_GRP_B 0x6CD08
 #define _PORT_TX_DW2_GRP_C 0x6CF08
-#define BXT_PORT_TX_DW2_LN0(phy, ch)   _MMIO_BXT_PHY_CH(phy, ch, \
-_PORT_TX_DW2_LN0_B, \
-_PORT_TX_DW2_LN0_C)
+#define BXT_PORT_TX_DW2_LN(phy, ch, lane)  _MMIO_BXT_PHY_CH_LN(phy, ch, 
lane, \
+   
_PORT_TX_DW2_LN0_B, \
+   
_PORT_TX_DW2_LN0_C)
 #define BXT_PORT_TX_DW2_GRP(phy, ch)   _MMIO_BXT_PHY_CH(phy, ch, \
 _PORT_TX_DW2_GRP_B, \
 _PORT_TX_DW2_GRP_C)
@@ -773,9 +774,9 @@
 #define _PORT_TX_DW3_GRP_A 0x162D0C
 #define _PORT_TX_DW3_GRP_B  

[PATCH 1/8] drm/i915/dpio: Clean up bxt/glk PHY registers

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

Use REG_BIT() & co. for the bxt/glk PHY register definitons.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dpio_phy.c | 44 +--
 drivers/gpu/drm/i915/i915_reg.h   | 74 +--
 2 files changed, 59 insertions(+), 59 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dpio_phy.c 
b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
index 2d7a71c8c69c..d14e80ece8aa 100644
--- a/drivers/gpu/drm/i915/display/intel_dpio_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_dpio_phy.c
@@ -295,9 +295,9 @@ void bxt_ddi_phy_set_signal_levels(struct intel_encoder 
*encoder,
intel_de_write(dev_priv, BXT_PORT_PCS_DW10_GRP(phy, ch), val);
 
val = intel_de_read(dev_priv, BXT_PORT_TX_DW2_LN0(phy, ch));
-   val &= ~(MARGIN_000 | UNIQ_TRANS_SCALE);
-   val |= trans->entries[level].bxt.margin << MARGIN_000_SHIFT |
-   trans->entries[level].bxt.scale << UNIQ_TRANS_SCALE_SHIFT;
+   val &= ~(MARGIN_000_MASK | UNIQ_TRANS_SCALE_MASK);
+   val |= MARGIN_000(trans->entries[level].bxt.margin) |
+   UNIQ_TRANS_SCALE(trans->entries[level].bxt.scale);
intel_de_write(dev_priv, BXT_PORT_TX_DW2_GRP(phy, ch), val);
 
val = intel_de_read(dev_priv, BXT_PORT_TX_DW3_LN0(phy, ch));
@@ -312,8 +312,8 @@ void bxt_ddi_phy_set_signal_levels(struct intel_encoder 
*encoder,
intel_de_write(dev_priv, BXT_PORT_TX_DW3_GRP(phy, ch), val);
 
val = intel_de_read(dev_priv, BXT_PORT_TX_DW4_LN0(phy, ch));
-   val &= ~DE_EMPHASIS;
-   val |= trans->entries[level].bxt.deemphasis << DEEMPH_SHIFT;
+   val &= ~DE_EMPHASIS_MASK;
+   val |= DE_EMPHASIS(trans->entries[level].bxt.deemphasis);
intel_de_write(dev_priv, BXT_PORT_TX_DW4_GRP(phy, ch), val);
 
val = intel_de_read(dev_priv, BXT_PORT_PCS_DW10_LN01(phy, ch));
@@ -353,7 +353,7 @@ static u32 bxt_get_grc(struct drm_i915_private *dev_priv, 
enum dpio_phy phy)
 {
u32 val = intel_de_read(dev_priv, BXT_PORT_REF_DW6(phy));
 
-   return (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT;
+   return REG_FIELD_GET(GRC_CODE_MASK, val);
 }
 
 static void bxt_phy_wait_grc_done(struct drm_i915_private *dev_priv,
@@ -405,11 +405,11 @@ static void _bxt_ddi_phy_init(struct drm_i915_private 
*dev_priv,
phy);
 
/* Program PLL Rcomp code offset */
-   intel_de_rmw(dev_priv, BXT_PORT_CL1CM_DW9(phy), IREF0RC_OFFSET_MASK,
-0xE4 << IREF0RC_OFFSET_SHIFT);
+   intel_de_rmw(dev_priv, BXT_PORT_CL1CM_DW9(phy),
+IREF0RC_OFFSET_MASK, IREF0RC_OFFSET(0xE4));
 
-   intel_de_rmw(dev_priv, BXT_PORT_CL1CM_DW10(phy), IREF1RC_OFFSET_MASK,
-0xE4 << IREF1RC_OFFSET_SHIFT);
+   intel_de_rmw(dev_priv, BXT_PORT_CL1CM_DW10(phy),
+IREF1RC_OFFSET_MASK, IREF1RC_OFFSET(0xE4));
 
/* Program power gating */
intel_de_rmw(dev_priv, BXT_PORT_CL1CM_DW28(phy), 0,
@@ -432,9 +432,9 @@ static void _bxt_ddi_phy_init(struct drm_i915_private 
*dev_priv,
val = bxt_get_grc(dev_priv, phy_info->rcomp_phy);
dev_priv->display.state.bxt_phy_grc = val;
 
-   grc_code = val << GRC_CODE_FAST_SHIFT |
-  val << GRC_CODE_SLOW_SHIFT |
-  val;
+   grc_code = GRC_CODE_FAST(val) |
+   GRC_CODE_SLOW(val) |
+   GRC_CODE_NOM(val);
intel_de_write(dev_priv, BXT_PORT_REF_DW6(phy), grc_code);
intel_de_rmw(dev_priv, BXT_PORT_REF_DW8(phy),
 0, GRC_DIS | GRC_RDY_OVRD);
@@ -530,16 +530,16 @@ bool bxt_ddi_phy_verify_state(struct drm_i915_private 
*dev_priv,
 
/* PLL Rcomp code offset */
ok &= _CHK(BXT_PORT_CL1CM_DW9(phy),
-   IREF0RC_OFFSET_MASK, 0xe4 << IREF0RC_OFFSET_SHIFT,
-   "BXT_PORT_CL1CM_DW9(%d)", phy);
+  IREF0RC_OFFSET_MASK, IREF0RC_OFFSET(0xe4),
+  "BXT_PORT_CL1CM_DW9(%d)", phy);
ok &= _CHK(BXT_PORT_CL1CM_DW10(phy),
-   IREF1RC_OFFSET_MASK, 0xe4 << IREF1RC_OFFSET_SHIFT,
-   "BXT_PORT_CL1CM_DW10(%d)", phy);
+  IREF1RC_OFFSET_MASK, IREF1RC_OFFSET(0xe4),
+  "BXT_PORT_CL1CM_DW10(%d)", phy);
 
/* Power gating */
mask = OCL1_POWER_DOWN_EN | DW28_OLDO_DYN_PWR_DOWN_EN | SUS_CLK_CONFIG;
ok &= _CHK(BXT_PORT_CL1CM_DW28(phy), mask, mask,
-   "BXT_PORT_CL1CM_DW28(%d)", phy);
+  "BXT_PORT_CL1CM_DW28(%d)", phy);
 
if (phy_info->dual_channel)
ok &= _CHK(BXT_PORT_CL2CM_DW6(phy),
@@ -549,9 +549,9 @@ bool bxt_ddi_phy_verify_state(struct drm_i915_private 
*dev_priv,
if (phy_info->rcomp_phy != -1) {
u32 grc_code = dev_priv->display.state.bxt_phy_grc;
 
-   grc_code = grc_code << GRC_CODE_FAST_SHIFT |
-  

[PATCH 0/8] drm/i915: BXT/GLK per-lane vswing and PHY reg cleanup

2024-04-12 Thread Ville Syrjala
From: Ville Syrjälä 

Start off with a bit of cleanup around the BXT/GLK DPIO
PHY registers, and finish off with per-lane vswing
programming.

Ville Syrjälä (8):
  drm/i915/dpio: Clean up bxt/glk PHY registers
  drm/i915/dpio: Add per-lane PHY TX register definitons for bxt/glk
  drm/i915/dpio: Extract bxt_dpio_phy_regs.h
  drm/i915/dpio: Introdude bxt_ddi_phy_rmw_grp()
  drm/i915/dpio: Use intel_de_rmw() for BXT DPIO latency optim setup
  drm/i915/dpio: s/ddi/dpio/ for bxt/glk PHY stuff
  drm/i915/dpio: Program bxt/glk PHY TX registers per-lane
  drm/i915: Enable per-lane DP drive settings for bxt/glk

 .../gpu/drm/i915/display/bxt_dpio_phy_regs.h  | 273 ++
 drivers/gpu/drm/i915/display/intel_ddi.c  |  10 +-
 .../i915/display/intel_display_power_well.c   |  18 +-
 .../drm/i915/display/intel_dp_link_training.c |   2 +-
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |   2 +-
 drivers/gpu/drm/i915/display/intel_dpio_phy.c | 213 --
 drivers/gpu/drm/i915/display/intel_dpio_phy.h |  48 +--
 drivers/gpu/drm/i915/display/intel_dpll_mgr.c |   3 +-
 drivers/gpu/drm/i915/i915_reg.h   | 262 -
 9 files changed, 432 insertions(+), 399 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/display/bxt_dpio_phy_regs.h

-- 
2.43.2



[PATCH] drm/edid: Parse topology block for all DispID structure v1.x

2024-04-10 Thread Ville Syrjala
From: Ville Syrjälä 

DisplayID spec v1.3 revision history notes do claim that
the toplogy block was added in v1.3 so requiring structure
v1.2 would seem correct, but there is at least one EDID in
edid.tv with a topology block and structure v1.0. And
there are also EDIDs with DisplayID structure v1.3 which
seems to be totally incorrect as DisplayID spec v1.3 lists
structure v1.2 as the only legal value.

Unfortunately I couldn't find copies of DisplayID spec
v1.0-v1.2 anywhere (even on vesa.org), so I'll have to
go on empirical evidence alone.

We used to parse the topology block on all v1.x
structures until the check for structure v2.0 was added.
Let's go back to doing that as the evidence does suggest
that there are DisplayIDs in the wild that would miss
out on the topology stuff otherwise.

Also toss out DISPLAY_ID_STRUCTURE_VER_12 entirely as
it doesn't appear we can really use it for anything.

I *think* we could technically skip all the structure
version checks as the block tags shouldn't conflict
between v2.0 and v1.x. But no harm in having a bit of
extra sanity checks I guess.

So far I'm not aware of any user reported regressions
from overly strict check, but I do know that it broke
igt/kms_tiled_display's fake DisplayID as that one
gets generated with structure v1.0.

Cc: Jani Nikula 
Cc: Dmitry Osipenko 
Fixes: c5a486af9df7 ("drm/edid: parse Tiled Display Topology Data Block for 
DisplayID 2.0")
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_edid.c  | 2 +-
 include/drm/drm_displayid.h | 1 -
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index ea77577a3786..f0948ab214b3 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -7405,7 +7405,7 @@ static void drm_parse_tiled_block(struct drm_connector 
*connector,
 static bool displayid_is_tiled_block(const struct displayid_iter *iter,
 const struct displayid_block *block)
 {
-   return (displayid_version(iter) == DISPLAY_ID_STRUCTURE_VER_12 &&
+   return (displayid_version(iter) < DISPLAY_ID_STRUCTURE_VER_20 &&
block->tag == DATA_BLOCK_TILED_DISPLAY) ||
(displayid_version(iter) == DISPLAY_ID_STRUCTURE_VER_20 &&
 block->tag == DATA_BLOCK_2_TILED_DISPLAY_TOPOLOGY);
diff --git a/include/drm/drm_displayid.h b/include/drm/drm_displayid.h
index 566497eeb3b8..bc1f6b378195 100644
--- a/include/drm/drm_displayid.h
+++ b/include/drm/drm_displayid.h
@@ -30,7 +30,6 @@ struct drm_edid;
 #define VESA_IEEE_OUI  0x3a0292
 
 /* DisplayID Structure versions */
-#define DISPLAY_ID_STRUCTURE_VER_120x12
 #define DISPLAY_ID_STRUCTURE_VER_200x20
 
 /* DisplayID Structure v1r2 Data Blocks */
-- 
2.43.2



[PATCH v3 6/6] drm/i915: Allow bigjoiner for MST

2024-04-09 Thread Ville Syrjala
From: Vidya Srinivas 

We need bigjoiner support with MST functionality
for MST monitor resolutions > 5K to work.
Adding support for the same.

v2: Addressed review comments from Jani.
Revert rejection of MST bigjoiner modes and add
functionality

v3: Fixed pipe_mismatch WARN for mst_master_transcoder
Credits-to: Manasi Navare 

v4: Utilize intel_crtc_joined_pipe_mask() also for handling
bigjoiner slave pipes for MST case(Stan)
[v5: vsyrjala: chunked the modeset squence stuff out,
   removed bogus mst master transcoder hack,
   keep mgr_lock near the full_pbn check]
[v6: vsyrjala: Calculate DSC slices correctly for bigjoiner (Imre)]

Reviewed-by: Manasi Navare 
Reviewed-by: Arun R Murthy 
Signed-off-by: Vidya Srinivas 
Co-developed-by: Ville Syrjälä 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 28 +++--
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index b1c95e04a45c..9084641e33f5 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -88,11 +88,10 @@ static int intel_dp_mst_bw_overhead(const struct 
intel_crtc_state *crtc_state,
 
if (dsc) {
flags |= DRM_DP_BW_OVERHEAD_DSC;
-   /* TODO: add support for bigjoiner */
dsc_slice_count = intel_dp_dsc_get_slice_count(connector,
   
adjusted_mode->clock,
   
adjusted_mode->hdisplay,
-  false);
+  
crtc_state->bigjoiner_pipes);
}
 
overhead = drm_dp_bw_overhead(crtc_state->lane_count,
@@ -525,6 +524,7 @@ static int intel_dp_mst_compute_config(struct intel_encoder 
*encoder,
 {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_atomic_state *state = 
to_intel_atomic_state(conn_state->state);
+   struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
struct intel_dp *intel_dp = _mst->primary->dp;
struct intel_connector *connector =
@@ -542,6 +542,11 @@ static int intel_dp_mst_compute_config(struct 
intel_encoder *encoder,
if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
return -EINVAL;
 
+   if (intel_dp_need_bigjoiner(intel_dp, connector,
+   adjusted_mode->crtc_hdisplay,
+   adjusted_mode->crtc_clock))
+   pipe_config->bigjoiner_pipes = GENMASK(crtc->pipe + 1, 
crtc->pipe);
+
pipe_config->sink_format = INTEL_OUTPUT_FORMAT_RGB;
pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
pipe_config->has_pch_encoder = false;
@@ -1341,10 +1346,6 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector 
*connector,
   max_link_clock, max_lanes);
mode_rate = intel_dp_link_required(mode->clock, min_bpp);
 
-   ret = drm_modeset_lock(>base.lock, ctx);
-   if (ret)
-   return ret;
-
/*
 * TODO:
 * - Also check if compression would allow for the mode
@@ -1357,17 +1358,18 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector 
*connector,
 *   corresponding link capabilities of the sink) in case the
 *   stream is uncompressed for it by the last branch device.
 */
-   if (mode_rate > max_rate || mode->clock > max_dotclk ||
-   drm_dp_calc_pbn_mode(mode->clock, min_bpp << 4) > port->full_pbn) {
-   *status = MODE_CLOCK_HIGH;
-   return 0;
-   }
if (intel_dp_need_bigjoiner(intel_dp, intel_connector,
mode->hdisplay, target_clock)) {
bigjoiner = true;
max_dotclk *= 2;
+   }
 
-   /* TODO: add support for bigjoiner */
+   ret = drm_modeset_lock(>base.lock, ctx);
+   if (ret)
+   return ret;
+
+   if (mode_rate > max_rate || mode->clock > max_dotclk ||
+   drm_dp_calc_pbn_mode(mode->clock, min_bpp << 4) > port->full_pbn) {
*status = MODE_CLOCK_HIGH;
return 0;
}
@@ -1410,7 +1412,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector 
*connector,
return 0;
}
 
-   *status = intel_mode_valid_max_plane_size(dev_priv, mode, false);
+   *status = intel_mode_valid_max_plane_size(dev_priv, mode, bigjoiner);
return 0;
 }
 
-- 
2.43.2



[PATCH v3 5/6] drm/i915/mst: Add bigjoiner handling to MST modeset sequence

2024-04-09 Thread Ville Syrjala
From: Ville Syrjälä 

Loop over all joined pipes at relevant points in the MST
modeset sequence.

Carved out from Vidya's earlier big patch, with naming/etc.
changed to match the earlier hsw_crtc_enable() stuff.

Reviewed-by: Arun R Murthy 
Co-developed-by: Vidya Srinivas 
Signed-off-by: Vidya Srinivas 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 34 -
 1 file changed, 27 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index b4d663703e72..b1c95e04a45c 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -956,6 +956,7 @@ static void intel_mst_post_disable_dp(struct 
intel_atomic_state *state,
struct drm_dp_mst_atomic_payload *new_payload =
drm_atomic_get_mst_payload_state(new_mst_state, 
connector->port);
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+   struct intel_crtc *pipe_crtc;
bool last_mst_stream;
 
intel_dp->active_mst_links--;
@@ -964,7 +965,13 @@ static void intel_mst_post_disable_dp(struct 
intel_atomic_state *state,
DISPLAY_VER(dev_priv) >= 12 && last_mst_stream &&
!intel_dp_mst_is_master_trans(old_crtc_state));
 
-   intel_crtc_vblank_off(old_crtc_state);
+   for_each_intel_crtc_in_pipe_mask(_priv->drm, pipe_crtc,
+
intel_crtc_joined_pipe_mask(old_crtc_state)) {
+   const struct intel_crtc_state *old_pipe_crtc_state =
+   intel_atomic_get_old_crtc_state(state, pipe_crtc);
+
+   intel_crtc_vblank_off(old_pipe_crtc_state);
+   }
 
intel_disable_transcoder(old_crtc_state);
 
@@ -982,12 +989,18 @@ static void intel_mst_post_disable_dp(struct 
intel_atomic_state *state,
 
intel_ddi_disable_transcoder_func(old_crtc_state);
 
-   intel_dsc_disable(old_crtc_state);
+   for_each_intel_crtc_in_pipe_mask(_priv->drm, pipe_crtc,
+
intel_crtc_joined_pipe_mask(old_crtc_state)) {
+   const struct intel_crtc_state *old_pipe_crtc_state =
+   intel_atomic_get_old_crtc_state(state, pipe_crtc);
 
-   if (DISPLAY_VER(dev_priv) >= 9)
-   skl_scaler_disable(old_crtc_state);
-   else
-   ilk_pfit_disable(old_crtc_state);
+   intel_dsc_disable(old_pipe_crtc_state);
+
+   if (DISPLAY_VER(dev_priv) >= 9)
+   skl_scaler_disable(old_pipe_crtc_state);
+   else
+   ilk_pfit_disable(old_pipe_crtc_state);
+   }
 
/*
 * Power down mst path before disabling the port, otherwise we end
@@ -1133,6 +1146,7 @@ static void intel_mst_enable_dp(struct intel_atomic_state 
*state,
drm_atomic_get_new_mst_topology_state(>base, 
_dp->mst_mgr);
enum transcoder trans = pipe_config->cpu_transcoder;
bool first_mst_stream = intel_dp->active_mst_links == 1;
+   struct intel_crtc *pipe_crtc;
 
drm_WARN_ON(_priv->drm, pipe_config->has_pch_encoder);
 
@@ -1174,7 +1188,13 @@ static void intel_mst_enable_dp(struct 
intel_atomic_state *state,
 
intel_enable_transcoder(pipe_config);
 
-   intel_crtc_vblank_on(pipe_config);
+   for_each_intel_crtc_in_pipe_mask_reverse(_priv->drm, pipe_crtc,
+
intel_crtc_joined_pipe_mask(pipe_config)) {
+   const struct intel_crtc_state *pipe_crtc_state =
+   intel_atomic_get_new_crtc_state(state, pipe_crtc);
+
+   intel_crtc_vblank_on(pipe_crtc_state);
+   }
 
intel_hdcp_enable(state, encoder, pipe_config, conn_state);
 }
-- 
2.43.2



[PATCH v3 4/6] drm/i915: Handle joined pipes inside hsw_crtc_enable()

2024-04-09 Thread Ville Syrjala
From: Stanislav Lisovskiy 

Handle only bigjoiner masters in skl_commit_modeset_enables/disables,
slave crtcs should be handled by master hooks. Same for encoders.
That way we can also remove a bunch of checks like 
intel_crtc_is_bigjoiner_slave.

v2: - Moved skl_pfit_enable, intel_dsc_enable, intel_crtc_vblank_on to 
intel_enable_ddi,
  so that it is now finally symmetrical with the disable case, because 
currently
  for some weird reason we are calling those from 
skl_commit_modeset_enables, while
  for the disable case those are called from the ddi disable hooks.
v3: - Create intel_ddi_enable_hdmi_or_sst symmetrical to
  intel_ddi_post_disable_hdmi_or_sst and move it also under non-mst check.
v4: - Fix intel_enable_ddi sequence
- Call intel_crtc_update_active_timings for slave pipes as well
[v5: vsyrjala: Use the name 'pipe_crtc' for the per-pipe crtc pointer
   Use consistent style and naming
   Protect macro arguments properly
   Drop superfluous changes to the modeset sequence,
   this now follows the old non-joiner sequence 100%
   apart from just looping in places]

Signed-off-by: Stanislav Lisovskiy 
Tested-by: Vidya Srinivas 
Reviewed-by: Manasi Navare  #v4?
Co-developed-by: Ville Syrjälä 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_ddi.c |  14 +-
 drivers/gpu/drm/i915/display/intel_display.c | 188 ++-
 drivers/gpu/drm/i915/display/intel_display.h |   6 +
 3 files changed, 116 insertions(+), 92 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index deaed9ff3f95..3255d4e375af 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3363,10 +3363,10 @@ static void intel_enable_ddi(struct intel_atomic_state 
*state,
 const struct intel_crtc_state *crtc_state,
 const struct drm_connector_state *conn_state)
 {
-   drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
+   struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+   struct intel_crtc *pipe_crtc;
 
-   if (!intel_crtc_is_bigjoiner_slave(crtc_state))
-   intel_ddi_enable_transcoder_func(encoder, crtc_state);
+   intel_ddi_enable_transcoder_func(encoder, crtc_state);
 
/* Enable/Disable DP2.0 SDP split config before transcoder */
intel_audio_sdp_split_update(crtc_state);
@@ -3375,7 +3375,13 @@ static void intel_enable_ddi(struct intel_atomic_state 
*state,
 
intel_ddi_wait_for_fec_status(encoder, crtc_state, true);
 
-   intel_crtc_vblank_on(crtc_state);
+   for_each_intel_crtc_in_pipe_mask_reverse(>drm, pipe_crtc,
+
intel_crtc_joined_pipe_mask(crtc_state)) {
+   const struct intel_crtc_state *pipe_crtc_state =
+   intel_atomic_get_new_crtc_state(state, pipe_crtc);
+
+   intel_crtc_vblank_on(pipe_crtc_state);
+   }
 
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
intel_enable_ddi_hdmi(state, encoder, crtc_state, conn_state);
diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index b944248598b3..0c53f9c0a76f 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -1595,24 +1595,6 @@ static void hsw_set_frame_start_delay(const struct 
intel_crtc_state *crtc_state)
 HSW_FRAME_START_DELAY(crtc_state->framestart_delay - 1));
 }
 
-static void icl_ddi_bigjoiner_pre_enable(struct intel_atomic_state *state,
-const struct intel_crtc_state 
*crtc_state)
-{
-   struct intel_crtc *master_crtc = intel_master_crtc(crtc_state);
-
-   /*
-* Enable sequence steps 1-7 on bigjoiner master
-*/
-   if (intel_crtc_is_bigjoiner_slave(crtc_state))
-   intel_encoders_pre_pll_enable(state, master_crtc);
-
-   if (crtc_state->shared_dpll)
-   intel_enable_shared_dpll(crtc_state);
-
-   if (intel_crtc_is_bigjoiner_slave(crtc_state))
-   intel_encoders_pre_enable(state, master_crtc);
-}
-
 static void hsw_configure_cpu_transcoder(const struct intel_crtc_state 
*crtc_state)
 {
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
@@ -1649,85 +1631,106 @@ static void hsw_crtc_enable(struct intel_atomic_state 
*state,
intel_atomic_get_new_crtc_state(state, crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum transcoder cpu_transcoder = new_crtc_state->cpu_transcoder;
-   enum pipe hsw_workaround_pipe;
+   struct intel_crtc *pipe_crtc;
 
if (drm_WARN_ON(_priv->drm, crtc->active))
return;
 
-   intel_dmc_enable_pipe(dev_priv, crtc->pipe);
+  

[PATCH v3 2/6] drm/i915: Utilize intel_crtc_joined_pipe_mask() more

2024-04-09 Thread Ville Syrjala
From: Ville Syrjälä 

Unify the master vs. slave handling in
intel_ddi_post_disable_hdmi_or_sst() by looping over all the
pipes in one go.

This also lets us move the intel_crtc_vblank_off() calls to
happen in a consistent place vs. the transcoder disable.
Previously we did the master vs. slaves on different sides
of that.

v2: Use the name 'pipe_crtc' for the per-pipe crtc pointer

Tested-by: Vidya Srinivas 
Reviewed-by: Arun R Murthy 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_ddi.c | 33 
 1 file changed, 17 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index 6d1b3de3045b..deaed9ff3f95 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3097,30 +3097,31 @@ static void intel_ddi_post_disable_hdmi_or_sst(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_crtc *slave_crtc;
+   struct intel_crtc *pipe_crtc;
 
-   intel_crtc_vblank_off(old_crtc_state);
+   for_each_intel_crtc_in_pipe_mask(_priv->drm, pipe_crtc,
+
intel_crtc_joined_pipe_mask(old_crtc_state)) {
+   const struct intel_crtc_state *old_pipe_crtc_state =
+   intel_atomic_get_old_crtc_state(state, pipe_crtc);
+
+   intel_crtc_vblank_off(old_pipe_crtc_state);
+   }
 
intel_disable_transcoder(old_crtc_state);
 
intel_ddi_disable_transcoder_func(old_crtc_state);
 
-   intel_dsc_disable(old_crtc_state);
+   for_each_intel_crtc_in_pipe_mask(_priv->drm, pipe_crtc,
+
intel_crtc_joined_pipe_mask(old_crtc_state)) {
+   const struct intel_crtc_state *old_pipe_crtc_state =
+   intel_atomic_get_old_crtc_state(state, pipe_crtc);
 
-   if (DISPLAY_VER(dev_priv) >= 9)
-   skl_scaler_disable(old_crtc_state);
-   else
-   ilk_pfit_disable(old_crtc_state);
+   intel_dsc_disable(old_pipe_crtc_state);
 
-   for_each_intel_crtc_in_pipe_mask(_priv->drm, slave_crtc,
-
intel_crtc_bigjoiner_slave_pipes(old_crtc_state)) {
-   const struct intel_crtc_state *old_slave_crtc_state =
-   intel_atomic_get_old_crtc_state(state, slave_crtc);
-
-   intel_crtc_vblank_off(old_slave_crtc_state);
-
-   intel_dsc_disable(old_slave_crtc_state);
-   skl_scaler_disable(old_slave_crtc_state);
+   if (DISPLAY_VER(dev_priv) >= 9)
+   skl_scaler_disable(old_pipe_crtc_state);
+   else
+   ilk_pfit_disable(old_pipe_crtc_state);
}
 }
 
-- 
2.43.2



[PATCH v3 3/6] drm/i915: Handle joined pipes inside hsw_crtc_disable()

2024-04-09 Thread Ville Syrjala
From: Ville Syrjälä 

Reorganize the crtc disable path to only deal with the
master pipes/transcoders in intel_old_crtc_state_disables()
and offload the handling of joined pipes to hsw_crtc_disable().
This makes the whole thing much more sensible since we can
actually control the order in which we do the per-pipe vs.
per-transcoder modeset steps.

v2: Use the name 'pipe_crtc' for the per-pipe crtc pointer

Tested-by: Vidya Srinivas 
Reviewed-by: Arun R Murthy 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_display.c | 64 
 1 file changed, 39 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 912213ee0250..b944248598b3 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -1791,29 +1791,28 @@ static void hsw_crtc_disable(struct intel_atomic_state 
*state,
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+   struct intel_crtc *pipe_crtc;
 
/*
 * FIXME collapse everything to one hook.
 * Need care with mst->ddi interactions.
 */
-   if (!intel_crtc_is_bigjoiner_slave(old_crtc_state)) {
-   intel_encoders_disable(state, crtc);
-   intel_encoders_post_disable(state, crtc);
-   }
-
-   intel_disable_shared_dpll(old_crtc_state);
+   intel_encoders_disable(state, crtc);
+   intel_encoders_post_disable(state, crtc);
 
-   if (!intel_crtc_is_bigjoiner_slave(old_crtc_state)) {
-   struct intel_crtc *slave_crtc;
+   for_each_intel_crtc_in_pipe_mask(>drm, pipe_crtc,
+
intel_crtc_joined_pipe_mask(old_crtc_state)) {
+   const struct intel_crtc_state *old_pipe_crtc_state =
+   intel_atomic_get_old_crtc_state(state, pipe_crtc);
 
-   intel_encoders_post_pll_disable(state, crtc);
+   intel_disable_shared_dpll(old_pipe_crtc_state);
+   }
 
-   intel_dmc_disable_pipe(i915, crtc->pipe);
+   intel_encoders_post_pll_disable(state, crtc);
 
-   for_each_intel_crtc_in_pipe_mask(>drm, slave_crtc,
-
intel_crtc_bigjoiner_slave_pipes(old_crtc_state))
-   intel_dmc_disable_pipe(i915, slave_crtc->pipe);
-   }
+   for_each_intel_crtc_in_pipe_mask(>drm, pipe_crtc,
+
intel_crtc_joined_pipe_mask(old_crtc_state))
+   intel_dmc_disable_pipe(i915, pipe_crtc->pipe);
 }
 
 static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state)
@@ -6844,21 +6843,31 @@ static void intel_old_crtc_state_disables(struct 
intel_atomic_state *state,
  struct intel_crtc *crtc)
 {
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
-   const struct intel_crtc_state *new_crtc_state =
-   intel_atomic_get_new_crtc_state(state, crtc);
+   const struct intel_crtc_state *old_crtc_state =
+   intel_atomic_get_old_crtc_state(state, crtc);
+   struct intel_crtc *pipe_crtc;
 
/*
 * We need to disable pipe CRC before disabling the pipe,
 * or we race against vblank off.
 */
-   intel_crtc_disable_pipe_crc(crtc);
+   for_each_intel_crtc_in_pipe_mask(_priv->drm, pipe_crtc,
+
intel_crtc_joined_pipe_mask(old_crtc_state))
+   intel_crtc_disable_pipe_crc(pipe_crtc);
 
dev_priv->display.funcs.display->crtc_disable(state, crtc);
-   crtc->active = false;
-   intel_fbc_disable(crtc);
 
-   if (!new_crtc_state->hw.active)
-   intel_initial_watermarks(state, crtc);
+   for_each_intel_crtc_in_pipe_mask(_priv->drm, pipe_crtc,
+
intel_crtc_joined_pipe_mask(old_crtc_state)) {
+   const struct intel_crtc_state *new_pipe_crtc_state =
+   intel_atomic_get_new_crtc_state(state, pipe_crtc);
+
+   pipe_crtc->active = false;
+   intel_fbc_disable(pipe_crtc);
+
+   if (!new_pipe_crtc_state->hw.active)
+   intel_initial_watermarks(state, pipe_crtc);
+   }
 }
 
 static void intel_commit_modeset_disables(struct intel_atomic_state *state)
@@ -6898,19 +6907,21 @@ static void intel_commit_modeset_disables(struct 
intel_atomic_state *state)
if ((disable_pipes & BIT(crtc->pipe)) == 0)
continue;
 
+   if (intel_crtc_is_bigjoiner_slave(old_crtc_state))
+   continue;
+
/* In case of Transcoder port Sync master slave CRTCs can be
 * assigned in any order and we need to make 

[PATCH v3 1/6] drm/i915: Extract intel_ddi_post_disable_hdmi_or_sst()

2024-04-09 Thread Ville Syrjala
From: Ville Syrjälä 

Extract the "not-MST" stuff from intel_ddi_post_disable() so that
the whole thing isn't so cluttered.

The bigjoiner slave handling was outside of the !MST check,
but it really should have been inside it as its the counterpart
to the master handling inside the check. So we pull that
in as well. There is no functional change here as we don't
currently support bigjoiner+MST anyway.

v2: Rebase
v3: Actually extract the slave code as claimed in
the commit message (presumably a rebase fail in v2)

Tested-by: Vidya Srinivas 
Reviewed-by: Arun R Murthy 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_ddi.c | 36 +++-
 1 file changed, 22 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index 312e90da78bf..6d1b3de3045b 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3091,28 +3091,26 @@ static void intel_ddi_post_disable_hdmi(struct 
intel_atomic_state *state,
intel_dp_dual_mode_set_tmds_output(intel_hdmi, false);
 }
 
-static void intel_ddi_post_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)
+static void intel_ddi_post_disable_hdmi_or_sst(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 *dev_priv = to_i915(encoder->base.dev);
struct intel_crtc *slave_crtc;
 
-   if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST)) {
-   intel_crtc_vblank_off(old_crtc_state);
+   intel_crtc_vblank_off(old_crtc_state);
 
-   intel_disable_transcoder(old_crtc_state);
+   intel_disable_transcoder(old_crtc_state);
 
-   intel_ddi_disable_transcoder_func(old_crtc_state);
+   intel_ddi_disable_transcoder_func(old_crtc_state);
 
-   intel_dsc_disable(old_crtc_state);
+   intel_dsc_disable(old_crtc_state);
 
-   if (DISPLAY_VER(dev_priv) >= 9)
-   skl_scaler_disable(old_crtc_state);
-   else
-   ilk_pfit_disable(old_crtc_state);
-   }
+   if (DISPLAY_VER(dev_priv) >= 9)
+   skl_scaler_disable(old_crtc_state);
+   else
+   ilk_pfit_disable(old_crtc_state);
 
for_each_intel_crtc_in_pipe_mask(_priv->drm, slave_crtc,
 
intel_crtc_bigjoiner_slave_pipes(old_crtc_state)) {
@@ -3124,6 +3122,16 @@ static void intel_ddi_post_disable(struct 
intel_atomic_state *state,
intel_dsc_disable(old_slave_crtc_state);
skl_scaler_disable(old_slave_crtc_state);
}
+}
+
+static void intel_ddi_post_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)
+{
+   if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST))
+   intel_ddi_post_disable_hdmi_or_sst(state, encoder, 
old_crtc_state,
+  old_conn_state);
 
/*
 * When called from DP MST code:
-- 
2.43.2



[PATCH v3 0/6] drm/i915: Bigjoiner modeset sequence redesign and MST support

2024-04-09 Thread Ville Syrjala
From: Ville Syrjälä 

Final pieces of the MST/bigjoiner modedest redesign.

Changes in v2:
- Reject PSR+bigjoiner combo
- Commit pipes in reverse order to avoid issues with
  slave pipe commits being completed prematurely.
  Should fix the gamma/DSB problems of v1.
- Address review comments
- Part of v1 was merged already separately

Changes in v3:
- Fix a rebase fail in function extraction
- Calculate DSC slices correctly for MST+bigjoiner (Imre)
- Most of v2 already merged

Stanislav Lisovskiy (1):
  drm/i915: Handle joined pipes inside hsw_crtc_enable()

Vidya Srinivas (1):
  drm/i915: Allow bigjoiner for MST

Ville Syrjälä (4):
  drm/i915: Extract intel_ddi_post_disable_hdmi_or_sst()
  drm/i915: Utilize intel_crtc_joined_pipe_mask() more
  drm/i915: Handle joined pipes inside hsw_crtc_disable()
  drm/i915/mst: Add bigjoiner handling to MST modeset sequence

 drivers/gpu/drm/i915/display/intel_ddi.c |  67 +++--
 drivers/gpu/drm/i915/display/intel_display.c | 252 ++-
 drivers/gpu/drm/i915/display/intel_display.h |   6 +
 drivers/gpu/drm/i915/display/intel_dp_mst.c  |  62 +++--
 4 files changed, 228 insertions(+), 159 deletions(-)

-- 
2.43.2



[PATCH 5/5] drm/vkms: Use drm_crtc_vblank_crtc()

2024-04-08 Thread Ville Syrjala
From: Ville Syrjälä 

Replace the open coded drm_crtc_vblank_crtc() with the real
thing.

Cc: Rodrigo Siqueira 
Cc: Melissa Wen 
Cc: "Maíra Canal" 
Cc: Haneen Mohammed 
Cc: Daniel Vetter 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/vkms/vkms_crtc.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
index 61e500b8c9da..40b4d084e3ce 100644
--- a/drivers/gpu/drm/vkms/vkms_crtc.c
+++ b/drivers/gpu/drm/vkms/vkms_crtc.c
@@ -61,9 +61,7 @@ static enum hrtimer_restart vkms_vblank_simulate(struct 
hrtimer *timer)
 
 static int vkms_enable_vblank(struct drm_crtc *crtc)
 {
-   struct drm_device *dev = crtc->dev;
-   unsigned int pipe = drm_crtc_index(crtc);
-   struct drm_vblank_crtc *vblank = >vblank[pipe];
+   struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
struct vkms_output *out = drm_crtc_to_vkms_output(crtc);
 
drm_calc_timestamping_constants(crtc, >mode);
@@ -88,10 +86,9 @@ static bool vkms_get_vblank_timestamp(struct drm_crtc *crtc,
  bool in_vblank_irq)
 {
struct drm_device *dev = crtc->dev;
-   unsigned int pipe = crtc->index;
struct vkms_device *vkmsdev = drm_device_to_vkms_device(dev);
struct vkms_output *output = >output;
-   struct drm_vblank_crtc *vblank = >vblank[pipe];
+   struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
 
if (!READ_ONCE(vblank->enabled)) {
*vblank_time = ktime_get();
-- 
2.43.2



[PATCH 4/5] drm/nouveau: Use drm_crtc_vblank_crtc()

2024-04-08 Thread Ville Syrjala
From: Ville Syrjälä 

Replace the open coded drm_crtc_vblank_crtc() with the real
thing.

Cc: Karol Herbst 
Cc: Lyude Paul 
Cc: Danilo Krummrich 
Cc: nouv...@lists.freedesktop.org
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/nouveau/nouveau_display.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c 
b/drivers/gpu/drm/nouveau/nouveau_display.c
index f28f9a857458..aed5d5b51b43 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -83,7 +83,7 @@ static bool
 nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos,
ktime_t *stime, ktime_t *etime)
 {
-   struct drm_vblank_crtc *vblank = 
>dev->vblank[drm_crtc_index(crtc)];
+   struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
struct nvif_head *head = _crtc(crtc)->head;
struct nvif_head_scanoutpos_v0 args;
int retry = 20;
-- 
2.43.2



[PATCH 2/5] drm/amdgpu: Use drm_crtc_vblank_crtc()

2024-04-08 Thread Ville Syrjala
From: Ville Syrjälä 

Replace the open coded drm_crtc_vblank_crtc() with the real
thing.

Cc: Alex Deucher 
Cc: "Christian König" 
Cc: "Pan, Xinhui" 
Cc: amd-...@lists.freedesktop.org
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c  | 8 ++--
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +-
 2 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
index 8baa2e0935cc..258703145161 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
@@ -65,9 +65,7 @@ static enum hrtimer_restart 
amdgpu_vkms_vblank_simulate(struct hrtimer *timer)
 
 static int amdgpu_vkms_enable_vblank(struct drm_crtc *crtc)
 {
-   struct drm_device *dev = crtc->dev;
-   unsigned int pipe = drm_crtc_index(crtc);
-   struct drm_vblank_crtc *vblank = >vblank[pipe];
+   struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
struct amdgpu_vkms_output *out = drm_crtc_to_amdgpu_vkms_output(crtc);
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
 
@@ -91,10 +89,8 @@ static bool amdgpu_vkms_get_vblank_timestamp(struct drm_crtc 
*crtc,
 ktime_t *vblank_time,
 bool in_vblank_irq)
 {
-   struct drm_device *dev = crtc->dev;
-   unsigned int pipe = crtc->index;
struct amdgpu_vkms_output *output = 
drm_crtc_to_amdgpu_vkms_output(crtc);
-   struct drm_vblank_crtc *vblank = >vblank[pipe];
+   struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
 
if (!READ_ONCE(vblank->enabled)) {
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 71d2d44681b2..662d2d83473b 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -528,7 +528,7 @@ static void dm_vupdate_high_irq(void *interrupt_params)
if (acrtc) {
vrr_active = amdgpu_dm_crtc_vrr_active_irq(acrtc);
drm_dev = acrtc->base.dev;
-   vblank = _dev->vblank[acrtc->base.index];
+   vblank = drm_crtc_vblank_crtc(>base);
previous_timestamp = 
atomic64_read(_params->previous_timestamp);
frame_duration_ns = vblank->time - previous_timestamp;
 
-- 
2.43.2



[PATCH 3/5] drm/i915: Use drm_crtc_vblank_crtc()

2024-04-08 Thread Ville Syrjala
From: Ville Syrjälä 

Replace the open coded drm_crtc_vblank_crtc() with the real
thing.

Cc: intel-gfx@lists.freedesktop.org
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_crtc.c   |  3 +--
 drivers/gpu/drm/i915/display/intel_vblank.c | 16 +---
 2 files changed, 6 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c 
b/drivers/gpu/drm/i915/display/intel_crtc.c
index 25593f6aae7d..339010384b86 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc.c
+++ b/drivers/gpu/drm/i915/display/intel_crtc.c
@@ -78,8 +78,7 @@ void intel_wait_for_vblank_if_active(struct drm_i915_private 
*i915,
 
 u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc)
 {
-   struct drm_device *dev = crtc->base.dev;
-   struct drm_vblank_crtc *vblank = 
>vblank[drm_crtc_index(>base)];
+   struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(>base);
 
if (!crtc->active)
return 0;
diff --git a/drivers/gpu/drm/i915/display/intel_vblank.c 
b/drivers/gpu/drm/i915/display/intel_vblank.c
index baf7354cb6e2..951190bcbc50 100644
--- a/drivers/gpu/drm/i915/display/intel_vblank.c
+++ b/drivers/gpu/drm/i915/display/intel_vblank.c
@@ -132,8 +132,7 @@ u32 g4x_get_vblank_counter(struct drm_crtc *crtc)
 static u32 intel_crtc_scanlines_since_frame_timestamp(struct intel_crtc *crtc)
 {
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
-   struct drm_vblank_crtc *vblank =
-   >base.dev->vblank[drm_crtc_index(>base)];
+   struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(>base);
const struct drm_display_mode *mode = >hwmode;
u32 htotal = mode->crtc_htotal;
u32 clock = mode->crtc_clock;
@@ -178,8 +177,7 @@ static u32 
intel_crtc_scanlines_since_frame_timestamp(struct intel_crtc *crtc)
  */
 static u32 __intel_get_crtc_scanline_from_timestamp(struct intel_crtc *crtc)
 {
-   struct drm_vblank_crtc *vblank =
-   >base.dev->vblank[drm_crtc_index(>base)];
+   struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(>base);
const struct drm_display_mode *mode = >hwmode;
u32 vblank_start = mode->crtc_vblank_start;
u32 vtotal = mode->crtc_vtotal;
@@ -200,17 +198,14 @@ static int __intel_get_crtc_scanline(struct intel_crtc 
*crtc)
 {
struct drm_device *dev = crtc->base.dev;
struct drm_i915_private *dev_priv = to_i915(dev);
-   const struct drm_display_mode *mode;
-   struct drm_vblank_crtc *vblank;
+   struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(>base);
+   const struct drm_display_mode *mode = >hwmode;
enum pipe pipe = crtc->pipe;
int position, vtotal;
 
if (!crtc->active)
return 0;
 
-   vblank = >base.dev->vblank[drm_crtc_index(>base)];
-   mode = >hwmode;
-
if (crtc->mode_flags & I915_MODE_FLAG_GET_SCANLINE_FROM_TIMESTAMP)
return __intel_get_crtc_scanline_from_timestamp(crtc);
 
@@ -254,8 +249,7 @@ static int __intel_get_crtc_scanline(struct intel_crtc 
*crtc)
 
 int intel_crtc_scanline_to_hw(struct intel_crtc *crtc, int scanline)
 {
-   const struct drm_vblank_crtc *vblank =
-   >base.dev->vblank[drm_crtc_index(>base)];
+   const struct drm_vblank_crtc *vblank = 
drm_crtc_vblank_crtc(>base);
const struct drm_display_mode *mode = >hwmode;
int vtotal;
 
-- 
2.43.2



[PATCH 1/5] drm/vblank: Introduce drm_crtc_vblank_crtc()

2024-04-08 Thread Ville Syrjala
From: Ville Syrjälä 

Make life easier by providing a function that hands
out the the correct drm_vblank_crtc for a given a drm_crtc.

Also abstract the lower level internals of the vblank
code in a similar fashion.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_vblank.c  | 58 ++-
 drivers/gpu/drm/drm_vblank_work.c |  2 +-
 include/drm/drm_vblank.h  |  1 +
 3 files changed, 36 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 702a12bc93bd..cc3571e25a9a 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -166,11 +166,24 @@ module_param_named(timestamp_precision_usec, 
drm_timestamp_precision, int, 0600)
 MODULE_PARM_DESC(vblankoffdelay, "Delay until vblank irq auto-disable [msecs] 
(0: never disable, <0: disable immediately)");
 MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]");
 
+static struct drm_vblank_crtc *
+drm_vblank_crtc(struct drm_device *dev, unsigned int pipe)
+{
+   return >vblank[pipe];
+}
+
+struct drm_vblank_crtc *
+drm_crtc_vblank_crtc(struct drm_crtc *crtc)
+{
+   return drm_vblank_crtc(crtc->dev, drm_crtc_index(crtc));
+}
+EXPORT_SYMBOL(drm_crtc_vblank_crtc);
+
 static void store_vblank(struct drm_device *dev, unsigned int pipe,
 u32 vblank_count_inc,
 ktime_t t_vblank, u32 last)
 {
-   struct drm_vblank_crtc *vblank = >vblank[pipe];
+   struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
 
assert_spin_locked(>vblank_time_lock);
 
@@ -184,7 +197,7 @@ static void store_vblank(struct drm_device *dev, unsigned 
int pipe,
 
 static u32 drm_max_vblank_count(struct drm_device *dev, unsigned int pipe)
 {
-   struct drm_vblank_crtc *vblank = >vblank[pipe];
+   struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
 
return vblank->max_vblank_count ?: dev->max_vblank_count;
 }
@@ -273,7 +286,7 @@ static void drm_reset_vblank_timestamp(struct drm_device 
*dev, unsigned int pipe
 static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe,
bool in_vblank_irq)
 {
-   struct drm_vblank_crtc *vblank = >vblank[pipe];
+   struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
u32 cur_vblank, diff;
bool rc;
ktime_t t_vblank;
@@ -364,7 +377,7 @@ static void drm_update_vblank_count(struct drm_device *dev, 
unsigned int pipe,
 
 u64 drm_vblank_count(struct drm_device *dev, unsigned int pipe)
 {
-   struct drm_vblank_crtc *vblank = >vblank[pipe];
+   struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
u64 count;
 
if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
@@ -438,7 +451,7 @@ static void __disable_vblank(struct drm_device *dev, 
unsigned int pipe)
  */
 void drm_vblank_disable_and_save(struct drm_device *dev, unsigned int pipe)
 {
-   struct drm_vblank_crtc *vblank = >vblank[pipe];
+   struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
unsigned long irqflags;
 
assert_spin_locked(>vbl_lock);
@@ -600,7 +613,7 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc,
 {
struct drm_device *dev = crtc->dev;
unsigned int pipe = drm_crtc_index(crtc);
-   struct drm_vblank_crtc *vblank = >vblank[pipe];
+   struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
int linedur_ns = 0, framedur_ns = 0;
int dotclock = mode->crtc_clock;
 
@@ -930,7 +943,7 @@ EXPORT_SYMBOL(drm_crtc_vblank_count);
 static u64 drm_vblank_count_and_time(struct drm_device *dev, unsigned int pipe,
 ktime_t *vblanktime)
 {
-   struct drm_vblank_crtc *vblank = >vblank[pipe];
+   struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
u64 vblank_count;
unsigned int seq;
 
@@ -985,7 +998,6 @@ EXPORT_SYMBOL(drm_crtc_vblank_count_and_time);
  */
 int drm_crtc_next_vblank_start(struct drm_crtc *crtc, ktime_t *vblanktime)
 {
-   unsigned int pipe = drm_crtc_index(crtc);
struct drm_vblank_crtc *vblank;
struct drm_display_mode *mode;
u64 vblank_start;
@@ -993,7 +1005,7 @@ int drm_crtc_next_vblank_start(struct drm_crtc *crtc, 
ktime_t *vblanktime)
if (!drm_dev_has_vblank(crtc->dev))
return -EINVAL;
 
-   vblank = >dev->vblank[pipe];
+   vblank = drm_crtc_vblank_crtc(crtc);
mode = >hwmode;
 
if (!vblank->framedur_ns || !vblank->linedur_ns)
@@ -1147,7 +1159,7 @@ static int __enable_vblank(struct drm_device *dev, 
unsigned int pipe)
 
 static int drm_vblank_enable(struct drm_device *dev, unsigned int pipe)
 {
-   struct drm_vblank_crtc *vblank = >vblank[pipe];
+   struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
int ret = 0;
 
assert_spin_locked(>vbl_lock);
@@ -1185,7 +1197,7 @@ static int 

[PATCH v2 17/17] drm/i915: Allow bigjoiner for MST

2024-04-04 Thread Ville Syrjala
From: Vidya Srinivas 

We need bigjoiner support with MST functionality
for MST monitor resolutions > 5K to work.
Adding support for the same.

v2: Addressed review comments from Jani.
Revert rejection of MST bigjoiner modes and add
functionality

v3: Fixed pipe_mismatch WARN for mst_master_transcoder
Credits-to: Manasi Navare 

v4: Utilize intel_crtc_joined_pipe_mask() also for handling
bigjoiner slave pipes for MST case(Stan)
[v5: vsyrjala: chunked the modeset squence stuff out,
   removed bogus mst master transcoder hack,
   keep mgr_lock near the full_pbn check]

Reviewed-by: Manasi Navare 
Reviewed-by: Arun R Murthy 
Signed-off-by: Vidya Srinivas 
Co-developed-by: Ville Syrjälä 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 25 -
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 2d601d214915..c1530c01f541 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -525,6 +525,7 @@ static int intel_dp_mst_compute_config(struct intel_encoder 
*encoder,
 {
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct intel_atomic_state *state = 
to_intel_atomic_state(conn_state->state);
+   struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
struct intel_dp *intel_dp = _mst->primary->dp;
struct intel_connector *connector =
@@ -542,6 +543,11 @@ static int intel_dp_mst_compute_config(struct 
intel_encoder *encoder,
if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
return -EINVAL;
 
+   if (intel_dp_need_bigjoiner(intel_dp, connector,
+   adjusted_mode->crtc_hdisplay,
+   adjusted_mode->crtc_clock))
+   pipe_config->bigjoiner_pipes = GENMASK(crtc->pipe + 1, 
crtc->pipe);
+
pipe_config->sink_format = INTEL_OUTPUT_FORMAT_RGB;
pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
pipe_config->has_pch_encoder = false;
@@ -1341,10 +1347,6 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector 
*connector,
   max_link_clock, max_lanes);
mode_rate = intel_dp_link_required(mode->clock, min_bpp);
 
-   ret = drm_modeset_lock(>base.lock, ctx);
-   if (ret)
-   return ret;
-
/*
 * TODO:
 * - Also check if compression would allow for the mode
@@ -1357,17 +1359,18 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector 
*connector,
 *   corresponding link capabilities of the sink) in case the
 *   stream is uncompressed for it by the last branch device.
 */
-   if (mode_rate > max_rate || mode->clock > max_dotclk ||
-   drm_dp_calc_pbn_mode(mode->clock, min_bpp << 4) > port->full_pbn) {
-   *status = MODE_CLOCK_HIGH;
-   return 0;
-   }
if (intel_dp_need_bigjoiner(intel_dp, intel_connector,
mode->hdisplay, target_clock)) {
bigjoiner = true;
max_dotclk *= 2;
+   }
 
-   /* TODO: add support for bigjoiner */
+   ret = drm_modeset_lock(>base.lock, ctx);
+   if (ret)
+   return ret;
+
+   if (mode_rate > max_rate || mode->clock > max_dotclk ||
+   drm_dp_calc_pbn_mode(mode->clock, min_bpp << 4) > port->full_pbn) {
*status = MODE_CLOCK_HIGH;
return 0;
}
@@ -1410,7 +1413,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector 
*connector,
return 0;
}
 
-   *status = intel_mode_valid_max_plane_size(dev_priv, mode, false);
+   *status = intel_mode_valid_max_plane_size(dev_priv, mode, bigjoiner);
return 0;
 }
 
-- 
2.43.2



[PATCH v2 15/17] drm/i915: Handle joined pipes inside hsw_crtc_enable()

2024-04-04 Thread Ville Syrjala
From: Stanislav Lisovskiy 

Handle only bigjoiner masters in skl_commit_modeset_enables/disables,
slave crtcs should be handled by master hooks. Same for encoders.
That way we can also remove a bunch of checks like 
intel_crtc_is_bigjoiner_slave.

v2: - Moved skl_pfit_enable, intel_dsc_enable, intel_crtc_vblank_on to 
intel_enable_ddi,
  so that it is now finally symmetrical with the disable case, because 
currently
  for some weird reason we are calling those from 
skl_commit_modeset_enables, while
  for the disable case those are called from the ddi disable hooks.
v3: - Create intel_ddi_enable_hdmi_or_sst symmetrical to
  intel_ddi_post_disable_hdmi_or_sst and move it also under non-mst check.
v4: - Fix intel_enable_ddi sequence
- Call intel_crtc_update_active_timings for slave pipes as well
[v5: vsyrjala: Use the name 'pipe_crtc' for the per-pipe crtc pointer
   Use consistent style and naming
   Protect macro arguments properly
   Drop superfluous changes to the modeset sequence,
   this now follows the old non-joiner sequence 100%
   apart from just looping in places]

Signed-off-by: Stanislav Lisovskiy 
Tested-by: Vidya Srinivas 
Reviewed-by: Manasi Navare  #v4?
Co-developed-by: Ville Syrjälä 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_ddi.c |  14 +-
 drivers/gpu/drm/i915/display/intel_display.c | 188 ++-
 drivers/gpu/drm/i915/display/intel_display.h |   6 +
 3 files changed, 116 insertions(+), 92 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index a7512e8e2630..b694fa6d9918 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3364,10 +3364,10 @@ static void intel_enable_ddi(struct intel_atomic_state 
*state,
 const struct intel_crtc_state *crtc_state,
 const struct drm_connector_state *conn_state)
 {
-   drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
+   struct drm_i915_private *i915 = to_i915(encoder->base.dev);
+   struct intel_crtc *pipe_crtc;
 
-   if (!intel_crtc_is_bigjoiner_slave(crtc_state))
-   intel_ddi_enable_transcoder_func(encoder, crtc_state);
+   intel_ddi_enable_transcoder_func(encoder, crtc_state);
 
/* Enable/Disable DP2.0 SDP split config before transcoder */
intel_audio_sdp_split_update(crtc_state);
@@ -3376,7 +3376,13 @@ static void intel_enable_ddi(struct intel_atomic_state 
*state,
 
intel_ddi_wait_for_fec_status(encoder, crtc_state, true);
 
-   intel_crtc_vblank_on(crtc_state);
+   for_each_intel_crtc_in_pipe_mask_reverse(>drm, pipe_crtc,
+
intel_crtc_joined_pipe_mask(crtc_state)) {
+   const struct intel_crtc_state *pipe_crtc_state =
+   intel_atomic_get_new_crtc_state(state, pipe_crtc);
+
+   intel_crtc_vblank_on(pipe_crtc_state);
+   }
 
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
intel_enable_ddi_hdmi(state, encoder, crtc_state, conn_state);
diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 7bd7b059ac7d..e74f6d2aa2ff 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -1595,24 +1595,6 @@ static void hsw_set_frame_start_delay(const struct 
intel_crtc_state *crtc_state)
 HSW_FRAME_START_DELAY(crtc_state->framestart_delay - 1));
 }
 
-static void icl_ddi_bigjoiner_pre_enable(struct intel_atomic_state *state,
-const struct intel_crtc_state 
*crtc_state)
-{
-   struct intel_crtc *master_crtc = intel_master_crtc(crtc_state);
-
-   /*
-* Enable sequence steps 1-7 on bigjoiner master
-*/
-   if (intel_crtc_is_bigjoiner_slave(crtc_state))
-   intel_encoders_pre_pll_enable(state, master_crtc);
-
-   if (crtc_state->shared_dpll)
-   intel_enable_shared_dpll(crtc_state);
-
-   if (intel_crtc_is_bigjoiner_slave(crtc_state))
-   intel_encoders_pre_enable(state, master_crtc);
-}
-
 static void hsw_configure_cpu_transcoder(const struct intel_crtc_state 
*crtc_state)
 {
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
@@ -1649,85 +1631,106 @@ static void hsw_crtc_enable(struct intel_atomic_state 
*state,
intel_atomic_get_new_crtc_state(state, crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
enum transcoder cpu_transcoder = new_crtc_state->cpu_transcoder;
-   enum pipe hsw_workaround_pipe;
+   struct intel_crtc *pipe_crtc;
 
if (drm_WARN_ON(_priv->drm, crtc->active))
return;
 
-   intel_dmc_enable_pipe(dev_priv, crtc->pipe);
+  

[PATCH v2 14/17] drm/i915: Handle joined pipes inside hsw_crtc_disable()

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

Reorganize the crtc disable path to only deal with the
master pipes/transcoders in intel_old_crtc_state_disables()
and offload the handling of joined pipes to hsw_crtc_disable().
This makes the whole thing much more sensible since we can
actually control the order in which we do the per-pipe vs.
per-transcoder modeset steps.

v2: Use the name 'pipe_crtc' for the per-pipe crtc pointer

Tested-by: Vidya Srinivas 
Reviewed-by: Arun R Murthy 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_display.c | 64 
 1 file changed, 39 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 9f5ff11d74b8..7bd7b059ac7d 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -1791,29 +1791,28 @@ static void hsw_crtc_disable(struct intel_atomic_state 
*state,
const struct intel_crtc_state *old_crtc_state =
intel_atomic_get_old_crtc_state(state, crtc);
struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+   struct intel_crtc *pipe_crtc;
 
/*
 * FIXME collapse everything to one hook.
 * Need care with mst->ddi interactions.
 */
-   if (!intel_crtc_is_bigjoiner_slave(old_crtc_state)) {
-   intel_encoders_disable(state, crtc);
-   intel_encoders_post_disable(state, crtc);
-   }
-
-   intel_disable_shared_dpll(old_crtc_state);
+   intel_encoders_disable(state, crtc);
+   intel_encoders_post_disable(state, crtc);
 
-   if (!intel_crtc_is_bigjoiner_slave(old_crtc_state)) {
-   struct intel_crtc *slave_crtc;
+   for_each_intel_crtc_in_pipe_mask(>drm, pipe_crtc,
+
intel_crtc_joined_pipe_mask(old_crtc_state)) {
+   const struct intel_crtc_state *old_pipe_crtc_state =
+   intel_atomic_get_old_crtc_state(state, pipe_crtc);
 
-   intel_encoders_post_pll_disable(state, crtc);
+   intel_disable_shared_dpll(old_pipe_crtc_state);
+   }
 
-   intel_dmc_disable_pipe(i915, crtc->pipe);
+   intel_encoders_post_pll_disable(state, crtc);
 
-   for_each_intel_crtc_in_pipe_mask(>drm, slave_crtc,
-
intel_crtc_bigjoiner_slave_pipes(old_crtc_state))
-   intel_dmc_disable_pipe(i915, slave_crtc->pipe);
-   }
+   for_each_intel_crtc_in_pipe_mask(>drm, pipe_crtc,
+
intel_crtc_joined_pipe_mask(old_crtc_state))
+   intel_dmc_disable_pipe(i915, pipe_crtc->pipe);
 }
 
 static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state)
@@ -6832,21 +6831,31 @@ static void intel_old_crtc_state_disables(struct 
intel_atomic_state *state,
  struct intel_crtc *crtc)
 {
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
-   const struct intel_crtc_state *new_crtc_state =
-   intel_atomic_get_new_crtc_state(state, crtc);
+   const struct intel_crtc_state *old_crtc_state =
+   intel_atomic_get_old_crtc_state(state, crtc);
+   struct intel_crtc *pipe_crtc;
 
/*
 * We need to disable pipe CRC before disabling the pipe,
 * or we race against vblank off.
 */
-   intel_crtc_disable_pipe_crc(crtc);
+   for_each_intel_crtc_in_pipe_mask(_priv->drm, pipe_crtc,
+
intel_crtc_joined_pipe_mask(old_crtc_state))
+   intel_crtc_disable_pipe_crc(pipe_crtc);
 
dev_priv->display.funcs.display->crtc_disable(state, crtc);
-   crtc->active = false;
-   intel_fbc_disable(crtc);
 
-   if (!new_crtc_state->hw.active)
-   intel_initial_watermarks(state, crtc);
+   for_each_intel_crtc_in_pipe_mask(_priv->drm, pipe_crtc,
+
intel_crtc_joined_pipe_mask(old_crtc_state)) {
+   const struct intel_crtc_state *new_pipe_crtc_state =
+   intel_atomic_get_new_crtc_state(state, pipe_crtc);
+
+   pipe_crtc->active = false;
+   intel_fbc_disable(pipe_crtc);
+
+   if (!new_pipe_crtc_state->hw.active)
+   intel_initial_watermarks(state, pipe_crtc);
+   }
 }
 
 static void intel_commit_modeset_disables(struct intel_atomic_state *state)
@@ -6886,19 +6895,21 @@ static void intel_commit_modeset_disables(struct 
intel_atomic_state *state)
if ((disable_pipes & BIT(crtc->pipe)) == 0)
continue;
 
+   if (intel_crtc_is_bigjoiner_slave(old_crtc_state))
+   continue;
+
/* In case of Transcoder port Sync master slave CRTCs can be
 * assigned in any order and we need to make 

[PATCH v2 16/17] drm/i915/mst: Add bigjoiner handling to MST modeset sequence

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

Loop over all joined pipes at relevant points in the MST
modeset sequence.

Carved out from Vidya's earlier big patch, with naming/etc.
changed to match the earlier hsw_crtc_enable() stuff.

Reviewed-by: Arun R Murthy 
Co-developed-by: Vidya Srinivas 
Signed-off-by: Vidya Srinivas 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 34 -
 1 file changed, 27 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index de364ed77c08..2d601d214915 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -956,6 +956,7 @@ static void intel_mst_post_disable_dp(struct 
intel_atomic_state *state,
struct drm_dp_mst_atomic_payload *new_payload =
drm_atomic_get_mst_payload_state(new_mst_state, 
connector->port);
struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+   struct intel_crtc *pipe_crtc;
bool last_mst_stream;
 
intel_dp->active_mst_links--;
@@ -964,7 +965,13 @@ static void intel_mst_post_disable_dp(struct 
intel_atomic_state *state,
DISPLAY_VER(dev_priv) >= 12 && last_mst_stream &&
!intel_dp_mst_is_master_trans(old_crtc_state));
 
-   intel_crtc_vblank_off(old_crtc_state);
+   for_each_intel_crtc_in_pipe_mask(_priv->drm, pipe_crtc,
+
intel_crtc_joined_pipe_mask(old_crtc_state)) {
+   const struct intel_crtc_state *old_pipe_crtc_state =
+   intel_atomic_get_old_crtc_state(state, pipe_crtc);
+
+   intel_crtc_vblank_off(old_pipe_crtc_state);
+   }
 
intel_disable_transcoder(old_crtc_state);
 
@@ -982,12 +989,18 @@ static void intel_mst_post_disable_dp(struct 
intel_atomic_state *state,
 
intel_ddi_disable_transcoder_func(old_crtc_state);
 
-   intel_dsc_disable(old_crtc_state);
+   for_each_intel_crtc_in_pipe_mask(_priv->drm, pipe_crtc,
+
intel_crtc_joined_pipe_mask(old_crtc_state)) {
+   const struct intel_crtc_state *old_pipe_crtc_state =
+   intel_atomic_get_old_crtc_state(state, pipe_crtc);
 
-   if (DISPLAY_VER(dev_priv) >= 9)
-   skl_scaler_disable(old_crtc_state);
-   else
-   ilk_pfit_disable(old_crtc_state);
+   intel_dsc_disable(old_pipe_crtc_state);
+
+   if (DISPLAY_VER(dev_priv) >= 9)
+   skl_scaler_disable(old_pipe_crtc_state);
+   else
+   ilk_pfit_disable(old_pipe_crtc_state);
+   }
 
/*
 * Power down mst path before disabling the port, otherwise we end
@@ -1133,6 +1146,7 @@ static void intel_mst_enable_dp(struct intel_atomic_state 
*state,
drm_atomic_get_new_mst_topology_state(>base, 
_dp->mst_mgr);
enum transcoder trans = pipe_config->cpu_transcoder;
bool first_mst_stream = intel_dp->active_mst_links == 1;
+   struct intel_crtc *pipe_crtc;
 
drm_WARN_ON(_priv->drm, pipe_config->has_pch_encoder);
 
@@ -1174,7 +1188,13 @@ static void intel_mst_enable_dp(struct 
intel_atomic_state *state,
 
intel_enable_transcoder(pipe_config);
 
-   intel_crtc_vblank_on(pipe_config);
+   for_each_intel_crtc_in_pipe_mask_reverse(_priv->drm, pipe_crtc,
+
intel_crtc_joined_pipe_mask(pipe_config)) {
+   const struct intel_crtc_state *pipe_crtc_state =
+   intel_atomic_get_new_crtc_state(state, pipe_crtc);
+
+   intel_crtc_vblank_on(pipe_crtc_state);
+   }
 
intel_hdcp_enable(state, encoder, pipe_config, conn_state);
 }
-- 
2.43.2



[PATCH v2 13/17] drm/i915: Utilize intel_crtc_joined_pipe_mask() more

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

Unify the master vs. slave handling in
intel_ddi_post_disable_hdmi_or_sst() by looping over all the
pipes in one go.

This also lets us move the intel_crtc_vblank_off() calls to
happen in a consistent place vs. the transcoder disable.
Previously we did the master vs. slaves on different sides
of that.

v2: Use the name 'pipe_crtc' for the per-pipe crtc pointer

Tested-by: Vidya Srinivas 
Reviewed-by: Arun R Murthy 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_ddi.c | 25 ++--
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index 0846d005fa16..a7512e8e2630 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3098,19 +3098,32 @@ static void intel_ddi_post_disable_hdmi_or_sst(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_crtc *pipe_crtc;
 
-   intel_crtc_vblank_off(old_crtc_state);
+   for_each_intel_crtc_in_pipe_mask(_priv->drm, pipe_crtc,
+
intel_crtc_joined_pipe_mask(old_crtc_state)) {
+   const struct intel_crtc_state *old_pipe_crtc_state =
+   intel_atomic_get_old_crtc_state(state, pipe_crtc);
+
+   intel_crtc_vblank_off(old_pipe_crtc_state);
+   }
 
intel_disable_transcoder(old_crtc_state);
 
intel_ddi_disable_transcoder_func(old_crtc_state);
 
-   intel_dsc_disable(old_crtc_state);
+   for_each_intel_crtc_in_pipe_mask(_priv->drm, pipe_crtc,
+
intel_crtc_joined_pipe_mask(old_crtc_state)) {
+   const struct intel_crtc_state *old_pipe_crtc_state =
+   intel_atomic_get_old_crtc_state(state, pipe_crtc);
 
-   if (DISPLAY_VER(dev_priv) >= 9)
-   skl_scaler_disable(old_crtc_state);
-   else
-   ilk_pfit_disable(old_crtc_state);
+   intel_dsc_disable(old_pipe_crtc_state);
+
+   if (DISPLAY_VER(dev_priv) >= 9)
+   skl_scaler_disable(old_pipe_crtc_state);
+   else
+   ilk_pfit_disable(old_pipe_crtc_state);
+   }
 }
 
 static void intel_ddi_post_disable(struct intel_atomic_state *state,
-- 
2.43.2



[PATCH v2 12/17] drm/i915: Extract intel_ddi_post_disable_hdmi_or_sst()

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

Extract the "not-MST" stuff from intel_ddi_post_disable() so that
the whole thing isn't so cluttered.

The bigjoiner slave handling was outside of the !MST check,
but it really should have been inside it as its the counterpart
to the master handling inside the check. So we pull that
in as well. There is no functional change here as we don't
currently support bigjoiner+MST anyway.

v2: Rebase

Tested-by: Vidya Srinivas 
Reviewed-by: Arun R Murthy 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_ddi.c | 52 +++-
 1 file changed, 24 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index 9bfe0fd3cffc..0846d005fa16 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3092,39 +3092,35 @@ static void intel_ddi_post_disable_hdmi(struct 
intel_atomic_state *state,
intel_dp_dual_mode_set_tmds_output(intel_hdmi, false);
 }
 
+static void intel_ddi_post_disable_hdmi_or_sst(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 *dev_priv = to_i915(encoder->base.dev);
+
+   intel_crtc_vblank_off(old_crtc_state);
+
+   intel_disable_transcoder(old_crtc_state);
+
+   intel_ddi_disable_transcoder_func(old_crtc_state);
+
+   intel_dsc_disable(old_crtc_state);
+
+   if (DISPLAY_VER(dev_priv) >= 9)
+   skl_scaler_disable(old_crtc_state);
+   else
+   ilk_pfit_disable(old_crtc_state);
+}
+
 static void intel_ddi_post_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 *dev_priv = to_i915(encoder->base.dev);
-   struct intel_crtc *slave_crtc;
-
-   if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST)) {
-   intel_crtc_vblank_off(old_crtc_state);
-
-   intel_disable_transcoder(old_crtc_state);
-
-   intel_ddi_disable_transcoder_func(old_crtc_state);
-
-   intel_dsc_disable(old_crtc_state);
-
-   if (DISPLAY_VER(dev_priv) >= 9)
-   skl_scaler_disable(old_crtc_state);
-   else
-   ilk_pfit_disable(old_crtc_state);
-   }
-
-   for_each_intel_crtc_in_pipe_mask(_priv->drm, slave_crtc,
-
intel_crtc_bigjoiner_slave_pipes(old_crtc_state)) {
-   const struct intel_crtc_state *old_slave_crtc_state =
-   intel_atomic_get_old_crtc_state(state, slave_crtc);
-
-   intel_crtc_vblank_off(old_slave_crtc_state);
-
-   intel_dsc_disable(old_slave_crtc_state);
-   skl_scaler_disable(old_slave_crtc_state);
-   }
+   if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST))
+   intel_ddi_post_disable_hdmi_or_sst(state, encoder,
+  old_crtc_state, 
old_conn_state);
 
/*
 * When called from DP MST code:
-- 
2.43.2



[PATCH v2 08/17] drm/i915: Extract intel_dp_joiner_needs_dsc()

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

Pull the "does joiner need DSC?" check into a helper. MST will
want to use this too at some point.

Tested-by: Vidya Srinivas 
Reviewed-by: Uma Shankar 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 26 ++---
 drivers/gpu/drm/i915/display/intel_dp.h |  1 +
 drivers/gpu/drm/i915/display/intel_dp_mst.c |  6 +
 3 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 4553c0c41bc6..4f15529212a1 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1310,11 +1310,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
dsc = dsc_max_compressed_bpp && dsc_slice_count;
}
 
-   /*
-* Big joiner configuration needs DSC for TGL which is not true for
-* XE_LPD where uncompressed joiner is supported.
-*/
-   if (DISPLAY_VER(dev_priv) < 13 && bigjoiner && !dsc)
+   if (intel_dp_joiner_needs_dsc(dev_priv, bigjoiner) && !dsc)
return MODE_CLOCK_HIGH;
 
if (mode_rate > max_rate && !dsc)
@@ -2405,6 +2401,16 @@ int intel_dp_config_required_rate(const struct 
intel_crtc_state *crtc_state)
return intel_dp_link_required(adjusted_mode->crtc_clock, bpp);
 }
 
+bool intel_dp_joiner_needs_dsc(struct drm_i915_private *i915, bool use_joiner)
+{
+   /*
+* Pipe joiner needs compression up to display 12 due to bandwidth
+* limitation. DG2 onwards pipe joiner can be enabled without
+* compression.
+*/
+   return DISPLAY_VER(i915) < 13 && use_joiner;
+}
+
 static int
 intel_dp_compute_link_config(struct intel_encoder *encoder,
 struct intel_crtc_state *pipe_config,
@@ -2419,8 +2425,7 @@ intel_dp_compute_link_config(struct intel_encoder 
*encoder,
_config->hw.adjusted_mode;
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct link_config_limits limits;
-   bool joiner_needs_dsc = false;
-   bool dsc_needed;
+   bool dsc_needed, joiner_needs_dsc;
int ret = 0;
 
if (pipe_config->fec_enable &&
@@ -2431,12 +2436,7 @@ intel_dp_compute_link_config(struct intel_encoder 
*encoder,
adjusted_mode->crtc_clock))
pipe_config->bigjoiner_pipes = GENMASK(crtc->pipe + 1, 
crtc->pipe);
 
-   /*
-* Pipe joiner needs compression up to display 12 due to bandwidth
-* limitation. DG2 onwards pipe joiner can be enabled without
-* compression.
-*/
-   joiner_needs_dsc = DISPLAY_VER(i915) < 13 && 
pipe_config->bigjoiner_pipes;
+   joiner_needs_dsc = intel_dp_joiner_needs_dsc(i915, 
pipe_config->bigjoiner_pipes);
 
dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en ||
 !intel_dp_compute_config_limits(intel_dp, pipe_config,
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
b/drivers/gpu/drm/i915/display/intel_dp.h
index 8d1c3ca28159..9f6be562fa08 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -120,6 +120,7 @@ int intel_dp_effective_data_rate(int pixel_clock, int 
bpp_x16,
 int bw_overhead);
 int intel_dp_max_link_data_rate(struct intel_dp *intel_dp,
int max_dprx_rate, int max_dprx_lanes);
+bool intel_dp_joiner_needs_dsc(struct drm_i915_private *i915, bool use_joiner);
 bool intel_dp_has_bigjoiner(struct intel_dp *intel_dp);
 bool intel_dp_needs_vsc_sdp(const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state);
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 6497542e3e65..da731dc503aa 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -1377,11 +1377,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector 
*connector,
dsc = dsc_max_compressed_bpp && dsc_slice_count;
}
 
-   /*
-* Big joiner configuration needs DSC for TGL which is not true for
-* XE_LPD where uncompressed joiner is supported.
-*/
-   if (DISPLAY_VER(dev_priv) < 13 && bigjoiner && !dsc) {
+   if (intel_dp_joiner_needs_dsc(dev_priv, bigjoiner) && !dsc) {
*status = MODE_CLOCK_HIGH;
return 0;
}
-- 
2.43.2



[PATCH v2 11/17] drm/i915: Introduce intel_crtc_joined_pipe_mask()

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

Add a small helper to compute the set of pipes that the current
crtc is using.

And we have at least one trivial place in
intel_ddi_update_active_dpll() where we can use it
immediately, so let's do that.

v2: Use the name 'pipe_crtc' for the per-pipe crtc pointer

Tested-by: Vidya Srinivas 
Reviewed-by: Arun R Murthy 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_ddi.c | 11 +--
 drivers/gpu/drm/i915/display/intel_display.c |  7 +++
 drivers/gpu/drm/i915/display/intel_display.h |  1 +
 3 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index 909c0102c865..9bfe0fd3cffc 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -3463,18 +3463,17 @@ void intel_ddi_update_active_dpll(struct 
intel_atomic_state *state,
  struct intel_crtc *crtc)
 {
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
-   struct intel_crtc_state *crtc_state =
+   const struct intel_crtc_state *crtc_state =
intel_atomic_get_new_crtc_state(state, crtc);
-   struct intel_crtc *slave_crtc;
+   struct intel_crtc *pipe_crtc;
 
/* FIXME: Add MTL pll_mgr */
if (DISPLAY_VER(i915) >= 14 || !intel_encoder_is_tc(encoder))
return;
 
-   intel_update_active_dpll(state, crtc, encoder);
-   for_each_intel_crtc_in_pipe_mask(>drm, slave_crtc,
-
intel_crtc_bigjoiner_slave_pipes(crtc_state))
-   intel_update_active_dpll(state, slave_crtc, encoder);
+   for_each_intel_crtc_in_pipe_mask(>drm, pipe_crtc,
+
intel_crtc_joined_pipe_mask(crtc_state))
+   intel_update_active_dpll(state, pipe_crtc, encoder);
 }
 
 static void
diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 449dd8667685..9f5ff11d74b8 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -275,6 +275,13 @@ static int intel_bigjoiner_num_pipes(const struct 
intel_crtc_state *crtc_state)
return hweight8(crtc_state->bigjoiner_pipes);
 }
 
+u8 intel_crtc_joined_pipe_mask(const struct intel_crtc_state *crtc_state)
+{
+   struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+
+   return BIT(crtc->pipe) | crtc_state->bigjoiner_pipes;
+}
+
 struct intel_crtc *intel_master_crtc(const struct intel_crtc_state *crtc_state)
 {
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
diff --git a/drivers/gpu/drm/i915/display/intel_display.h 
b/drivers/gpu/drm/i915/display/intel_display.h
index 423074d6947a..898b11663377 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -416,6 +416,7 @@ intel_cpu_transcoder_mode_valid(struct drm_i915_private 
*i915,
 enum phy intel_port_to_phy(struct drm_i915_private *i915, enum port port);
 bool is_trans_port_sync_mode(const struct intel_crtc_state *state);
 bool is_trans_port_sync_master(const struct intel_crtc_state *state);
+u8 intel_crtc_joined_pipe_mask(const struct intel_crtc_state *crtc_state);
 bool intel_crtc_is_bigjoiner_slave(const struct intel_crtc_state *crtc_state);
 bool intel_crtc_is_bigjoiner_master(const struct intel_crtc_state *crtc_state);
 u8 intel_crtc_bigjoiner_slave_pipes(const struct intel_crtc_state *crtc_state);
-- 
2.43.2



[PATCH v2 10/17] drm/i915: Pass connector to intel_dp_need_bigjoiner()

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

Pass the connector explicitly to intel_dp_need_bigjoiner()
so that it'll actually check the correct place for the
bigjoiner force flag.

Tested-by: Vidya Srinivas 
Reviewed-by: Uma Shankar 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 10 ++
 drivers/gpu/drm/i915/display/intel_dp.h |  1 +
 drivers/gpu/drm/i915/display/intel_dp_mst.c |  5 +++--
 3 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 4f15529212a1..66568bb1a0b0 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1202,10 +1202,10 @@ intel_dp_mode_valid_downstream(struct intel_connector 
*connector,
 }
 
 bool intel_dp_need_bigjoiner(struct intel_dp *intel_dp,
+struct intel_connector *connector,
 int hdisplay, int clock)
 {
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
-   struct intel_connector *connector = intel_dp->attached_connector;
 
if (!intel_dp_has_bigjoiner(intel_dp))
return false;
@@ -1249,7 +1249,8 @@ intel_dp_mode_valid(struct drm_connector *_connector,
target_clock = fixed_mode->clock;
}
 
-   if (intel_dp_need_bigjoiner(intel_dp, mode->hdisplay, target_clock)) {
+   if (intel_dp_need_bigjoiner(intel_dp, connector,
+   mode->hdisplay, target_clock)) {
bigjoiner = true;
max_dotclk *= 2;
}
@@ -2419,7 +2420,7 @@ intel_dp_compute_link_config(struct intel_encoder 
*encoder,
 {
struct drm_i915_private *i915 = to_i915(encoder->base.dev);
struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
-   const struct intel_connector *connector =
+   struct intel_connector *connector =
to_intel_connector(conn_state->connector);
const struct drm_display_mode *adjusted_mode =
_config->hw.adjusted_mode;
@@ -2432,7 +2433,8 @@ intel_dp_compute_link_config(struct intel_encoder 
*encoder,
!intel_dp_supports_fec(intel_dp, connector, pipe_config))
return -EINVAL;
 
-   if (intel_dp_need_bigjoiner(intel_dp, adjusted_mode->crtc_hdisplay,
+   if (intel_dp_need_bigjoiner(intel_dp, connector,
+   adjusted_mode->crtc_hdisplay,
adjusted_mode->crtc_clock))
pipe_config->bigjoiner_pipes = GENMASK(crtc->pipe + 1, 
crtc->pipe);
 
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
b/drivers/gpu/drm/i915/display/intel_dp.h
index 9f6be562fa08..106ecfde36d9 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -151,6 +151,7 @@ u8 intel_dp_dsc_get_slice_count(const struct 
intel_connector *connector,
int mode_clock, int mode_hdisplay,
bool bigjoiner);
 bool intel_dp_need_bigjoiner(struct intel_dp *intel_dp,
+struct intel_connector *connector,
 int hdisplay, int clock);
 
 static inline unsigned int intel_dp_unused_lane_mask(int lane_count)
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index aac66c2f65a1..de364ed77c08 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -527,7 +527,7 @@ static int intel_dp_mst_compute_config(struct intel_encoder 
*encoder,
struct intel_atomic_state *state = 
to_intel_atomic_state(conn_state->state);
struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
struct intel_dp *intel_dp = _mst->primary->dp;
-   const struct intel_connector *connector =
+   struct intel_connector *connector =
to_intel_connector(conn_state->connector);
const struct drm_display_mode *adjusted_mode =
_config->hw.adjusted_mode;
@@ -1342,7 +1342,8 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector 
*connector,
*status = MODE_CLOCK_HIGH;
return 0;
}
-   if (intel_dp_need_bigjoiner(intel_dp, mode->hdisplay, target_clock)) {
+   if (intel_dp_need_bigjoiner(intel_dp, intel_connector,
+   mode->hdisplay, target_clock)) {
bigjoiner = true;
max_dotclk *= 2;
 
-- 
2.43.2



[PATCH v2 09/17] drm/i915/mst: Check intel_dp_joiner_needs_dsc()

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

intel_dp_mst_compute_config() is missing the "does the
joiner need DSC?" check despite claiming to have a lot
of other joiner/dsc stuff in there (albeit disabled).
Replicate the logic from the SST side.

TODO: refactor all this duplicated code!

Tested-by: Vidya Srinivas 
Reviewed-by: Uma Shankar 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index da731dc503aa..aac66c2f65a1 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -532,7 +532,7 @@ static int intel_dp_mst_compute_config(struct intel_encoder 
*encoder,
const struct drm_display_mode *adjusted_mode =
_config->hw.adjusted_mode;
struct link_config_limits limits;
-   bool dsc_needed;
+   bool dsc_needed, joiner_needs_dsc;
int ret = 0;
 
if (pipe_config->fec_enable &&
@@ -546,7 +546,9 @@ static int intel_dp_mst_compute_config(struct intel_encoder 
*encoder,
pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
pipe_config->has_pch_encoder = false;
 
-   dsc_needed = intel_dp->force_dsc_en ||
+   joiner_needs_dsc = intel_dp_joiner_needs_dsc(dev_priv, 
pipe_config->bigjoiner_pipes);
+
+   dsc_needed = joiner_needs_dsc || intel_dp->force_dsc_en ||
 !intel_dp_mst_compute_config_limits(intel_dp,
 connector,
 pipe_config,
@@ -566,8 +568,8 @@ static int intel_dp_mst_compute_config(struct intel_encoder 
*encoder,
 
/* enable compression if the mode doesn't fit available BW */
if (dsc_needed) {
-   drm_dbg_kms(_priv->drm, "Try DSC (fallback=%s, force=%s)\n",
-   str_yes_no(ret),
+   drm_dbg_kms(_priv->drm, "Try DSC (fallback=%s, joiner=%s, 
force=%s)\n",
+   str_yes_no(ret), str_yes_no(joiner_needs_dsc),
str_yes_no(intel_dp->force_dsc_en));
 
if (!intel_dp_mst_dsc_source_support(pipe_config))
-- 
2.43.2



[PATCH v2 07/17] drm/i915: s/intel_dp_can_bigjoiner()/intel_dp_has_bigjoiner()/

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

Rename intel_dp_can_bigjoiner() to intel_dp_has_bigjoiner()
to better reflect its function.

Tested-by: Vidya Srinivas 
Reviewed-by: Vandita Kulkarni 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 4 ++--
 drivers/gpu/drm/i915/display/intel_dp.h | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 4552005caae2..4553c0c41bc6 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -433,7 +433,7 @@ int intel_dp_max_link_data_rate(struct intel_dp *intel_dp,
return max_rate;
 }
 
-bool intel_dp_can_bigjoiner(struct intel_dp *intel_dp)
+bool intel_dp_has_bigjoiner(struct intel_dp *intel_dp)
 {
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
struct intel_encoder *encoder = _dig_port->base;
@@ -1207,7 +1207,7 @@ bool intel_dp_need_bigjoiner(struct intel_dp *intel_dp,
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
struct intel_connector *connector = intel_dp->attached_connector;
 
-   if (!intel_dp_can_bigjoiner(intel_dp))
+   if (!intel_dp_has_bigjoiner(intel_dp))
return false;
 
return clock > i915->max_dotclk_freq || hdisplay > 5120 ||
diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
b/drivers/gpu/drm/i915/display/intel_dp.h
index 9f880d7865d1..8d1c3ca28159 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.h
+++ b/drivers/gpu/drm/i915/display/intel_dp.h
@@ -120,7 +120,7 @@ int intel_dp_effective_data_rate(int pixel_clock, int 
bpp_x16,
 int bw_overhead);
 int intel_dp_max_link_data_rate(struct intel_dp *intel_dp,
int max_dprx_rate, int max_dprx_lanes);
-bool intel_dp_can_bigjoiner(struct intel_dp *intel_dp);
+bool intel_dp_has_bigjoiner(struct intel_dp *intel_dp);
 bool intel_dp_needs_vsc_sdp(const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state);
 void intel_dp_set_infoframes(struct intel_encoder *encoder, bool enable,
-- 
2.43.2



[PATCH v2 06/17] drm/i915: Fix intel_modeset_pipe_config_late() for bigjoiner

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

Currently intel_modeset_pipe_config_late() is called after the
bigjoiner state copy, and it will actually not do anything for
bigjoiner slaves. This can lead to a mismatched state between
the master and slave.

The two things that we do in the encoder .compute_config_late()
hook are mst master transcoder and port sync master transcoder
elections. So if either of either MST or port sync is combined
with bigjoiner then we can see the mismatch.

Currently this problem is more or less theoretical; MST+bigjoiner
has not been implemented yet, and port sync+bigjoiner would
require a tiled display with >5k tiles (or a very high
dotclock per tile). Although we do have kms_tiled_display in
igt which can fake a tiled display, and we can now force bigjoiner
via debugfs, so it is possible to trigger this if you try hard
enough.

Reorder the code such that intel_modeset_pipe_config_late()
will be called before the bigjoiner state copy happens so
that both pipes will end up with the same state.

Tested-by: Vidya Srinivas 
Reviewed-by: Vandita Kulkarni 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_display.c | 46 ++--
 1 file changed, 32 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 0086a7422e86..449dd8667685 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -4752,8 +4752,6 @@ intel_modeset_pipe_config_late(struct intel_atomic_state 
*state,
struct drm_connector *connector;
int i;
 
-   intel_bigjoiner_adjust_pipe_src(crtc_state);
-
for_each_new_connector_in_state(>base, connector,
conn_state, i) {
struct intel_encoder *encoder =
@@ -6295,27 +6293,37 @@ static int intel_atomic_check_config(struct 
intel_atomic_state *state,
continue;
}
 
-   if (intel_crtc_is_bigjoiner_slave(new_crtc_state)) {
-   drm_WARN_ON(>drm, new_crtc_state->uapi.enable);
+   if (drm_WARN_ON(>drm, 
intel_crtc_is_bigjoiner_slave(new_crtc_state)))
continue;
-   }
 
ret = intel_crtc_prepare_cleared_state(state, crtc);
if (ret)
-   break;
+   goto fail;
 
if (!new_crtc_state->hw.enable)
continue;
 
ret = intel_modeset_pipe_config(state, crtc, limits);
if (ret)
-   break;
+   goto fail;
+   }
 
-   ret = intel_atomic_check_bigjoiner(state, crtc);
+   for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+   if (!intel_crtc_needs_modeset(new_crtc_state))
+   continue;
+
+   if (drm_WARN_ON(>drm, 
intel_crtc_is_bigjoiner_slave(new_crtc_state)))
+   continue;
+
+   if (!new_crtc_state->hw.enable)
+   continue;
+
+   ret = intel_modeset_pipe_config_late(state, crtc);
if (ret)
-   break;
+   goto fail;
}
 
+fail:
if (ret)
*failed_pipe = crtc->pipe;
 
@@ -6411,16 +6419,26 @@ int intel_atomic_check(struct drm_device *dev,
if (ret)
goto fail;
 
+   for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+   if (!intel_crtc_needs_modeset(new_crtc_state))
+   continue;
+
+   if (intel_crtc_is_bigjoiner_slave(new_crtc_state)) {
+   drm_WARN_ON(_priv->drm, 
new_crtc_state->uapi.enable);
+   continue;
+   }
+
+   ret = intel_atomic_check_bigjoiner(state, crtc);
+   if (ret)
+   goto fail;
+   }
+
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
new_crtc_state, i) {
if (!intel_crtc_needs_modeset(new_crtc_state))
continue;
 
-   if (new_crtc_state->hw.enable) {
-   ret = intel_modeset_pipe_config_late(state, crtc);
-   if (ret)
-   goto fail;
-   }
+   intel_bigjoiner_adjust_pipe_src(new_crtc_state);
 
intel_crtc_check_fastset(old_crtc_state, new_crtc_state);
}
-- 
2.43.2



[PATCH v2 05/17] drm/i915/vrr: Disable VRR when using bigjoiner

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

All joined pipes share the same transcoder/timing generator.
Currently we just do the commits per-pipe, which doesn't really
work if we need to change switch between non-VRR and VRR timings
generators on the fly, or even when sending the push to the
transcoder. For now just disable VRR when bigjoiner is needed.

Tested-by: Vidya Srinivas 
Reviewed-by: Vandita Kulkarni 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_vrr.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c 
b/drivers/gpu/drm/i915/display/intel_vrr.c
index 856378f8b90e..894ee97b3e1b 100644
--- a/drivers/gpu/drm/i915/display/intel_vrr.c
+++ b/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -119,6 +119,13 @@ intel_vrr_compute_config(struct intel_crtc_state 
*crtc_state,
const struct drm_display_info *info = >base.display_info;
int vmin, vmax;
 
+   /*
+* FIXME all joined pipes share the same transcoder.
+* Need to account for that during VRR toggle/push/etc.
+*/
+   if (crtc_state->bigjoiner_pipes)
+   return;
+
if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
return;
 
-- 
2.43.2



[PATCH v2 04/17] drm/i915: Disable live M/N updates when using bigjoiner

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

All joined pipes share the same transcoder/timing generator.
Currently we just do the commits per-pipe, which doesn't really
work if we need to change the timings at the same time. For
now just disable live M/N updates when bigjoiner is needed.

Tested-by: Vidya Srinivas 
Reviewed-by: Arun R Murthy 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_dp.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
b/drivers/gpu/drm/i915/display/intel_dp.c
index 8b67cd62f188..4552005caae2 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -2752,7 +2752,11 @@ intel_dp_drrs_compute_config(struct intel_connector 
*connector,
intel_panel_downclock_mode(connector, 
_config->hw.adjusted_mode);
int pixel_clock;
 
-   if (has_seamless_m_n(connector))
+   /*
+* FIXME all joined pipes share the same transcoder.
+* Need to account for that when updating M/N live.
+*/
+   if (has_seamless_m_n(connector) && !pipe_config->bigjoiner_pipes)
pipe_config->update_m_n = true;
 
if (!can_enable_drrs(connector, pipe_config, downclock_mode)) {
-- 
2.43.2



[PATCH v2 03/17] drm/i915: Disable port sync when bigjoiner is used

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

The current modeset sequence can't handle port sync and bigjoiner
at the same time. Refuse port sync when bigjoiner is needed,
at least until we fix the modeset sequence.

v2: Add a FIXME (Vandite)

Tested-by: Vidya Srinivas 
Reviewed-by: Vandita Kulkarni 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_ddi.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
b/drivers/gpu/drm/i915/display/intel_ddi.c
index 0654e989f45f..909c0102c865 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -4244,7 +4244,12 @@ static bool m_n_equal(const struct intel_link_m_n *m_n_1,
 static bool crtcs_port_sync_compatible(const struct intel_crtc_state 
*crtc_state1,
   const struct intel_crtc_state 
*crtc_state2)
 {
+   /*
+* FIXME the modeset sequence is currently wrong and
+* can't deal with bigjoiner + port sync at the same time.
+*/
return crtc_state1->hw.active && crtc_state2->hw.active &&
+   !crtc_state1->bigjoiner_pipes && !crtc_state2->bigjoiner_pipes 
&&
crtc_state1->output_types == crtc_state2->output_types &&
crtc_state1->output_format == crtc_state2->output_format &&
crtc_state1->lane_count == crtc_state2->lane_count &&
-- 
2.43.2



[PATCH v2 02/17] drm/i915/psr: Disable PSR when bigjoiner is used

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

Bigjoiner seem to be causing all kinds of grief to the PSR
code currently. I don't believe there is any hardware issue
but the code simply not handling this correctly. For now
just disable PSR when bigjoiner is needed.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_psr.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_psr.c 
b/drivers/gpu/drm/i915/display/intel_psr.c
index eef62983e9db..a3ff916b53f9 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -1584,6 +1584,17 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
return;
}
 
+   /*
+* FIXME figure out what is wrong with PSR+bigjoiner and
+* fix it. Presumably something related to the fact that
+* PSR is a transcoder level feature.
+*/
+   if (crtc_state->bigjoiner_pipes) {
+   drm_dbg_kms(_priv->drm,
+   "PSR disabled due to bigjoiner\n");
+   return;
+   }
+
if (CAN_PANEL_REPLAY(intel_dp))
crtc_state->has_panel_replay = true;
else
-- 
2.43.2



[PATCH v2 01/17] drm/i915: Update pipes in reverse order for bigjoiner

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

With bigjoiner the master crtc is the one that will send out the
uapi event/etc. We want that to happen after all the slaves are
done, so let's try to do the commits in reverse order so that
the master comes last.

Even worse, the modeset helper will simply complete the commit
on the slave pipe immediately as it consider the crtc to be inactive
(it can't see our crtc_state->hw.active/etc.).

With regular sync updates this generally doesn't matter all that
much as the slave pipe should typically finish its work during the
same frame as the master pipe. However in case the slave pipe's commit
slips into the next frame we end up in a bit of trouble. This is most
visible with either async flips (currently disabled with bigjoiner
exactly for this reason), and DSB gamma updates. With DSB the problem
happens because the DSB itself will wait until the next start vblank
before starting to execute. So if the master pipe already finished its
commit and the DSB on the slave pipe is still waiting for the next
vblank we will assume the DSB as gotten stuck and terminate it.

Reversing the commit order should ameliarate this for the most part
as the master pipe is guaranteed to start its commit after the slave
pipe started. The one thing that can still screw us over is the fact
that we aren't necessarily going to commit the pipes in the reverse
order as the actual order is dictated by the DDB overlap avoidance.
But that can only happen while other pipes are being enabled/disabled,
and so in the normal steady state we should be safe.

The full fix will involve making the commit machinery aware of the
slave pipes and not finish their commits prematurely. But that
will involve a bit more work than this. And this commit order
reversal will still be beneficial to avoid userspace getting an
-EBUSY from the following page flip if the second pipe's commit
does stretch into the next frame.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_display.c | 14 +++---
 drivers/gpu/drm/i915/display/intel_display.h |  8 
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index a481c9218138..0086a7422e86 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -6956,8 +6956,12 @@ static void skl_commit_modeset_enables(struct 
intel_atomic_state *state)
intel_dbuf_mbus_pre_ddb_update(state);
 
while (update_pipes) {
-   for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
-   new_crtc_state, i) {
+   /*
+* Commit in reverse order to make bigjoiner master
+* send the uapi events after slaves are done.
+*/
+   for_each_oldnew_intel_crtc_in_state_reverse(state, crtc, 
old_crtc_state,
+   new_crtc_state, i) {
enum pipe pipe = crtc->pipe;
 
if ((update_pipes & BIT(pipe)) == 0)
@@ -7036,7 +7040,11 @@ static void skl_commit_modeset_enables(struct 
intel_atomic_state *state)
intel_pre_update_crtc(state, crtc);
}
 
-   for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
+   /*
+* Commit in reverse order to make bigjoiner master
+* send the uapi events after slaves are done.
+*/
+   for_each_new_intel_crtc_in_state_reverse(state, crtc, new_crtc_state, 
i) {
enum pipe pipe = crtc->pipe;
 
if ((update_pipes & BIT(pipe)) == 0)
diff --git a/drivers/gpu/drm/i915/display/intel_display.h 
b/drivers/gpu/drm/i915/display/intel_display.h
index 986ec77490de..423074d6947a 100644
--- a/drivers/gpu/drm/i915/display/intel_display.h
+++ b/drivers/gpu/drm/i915/display/intel_display.h
@@ -344,6 +344,14 @@ enum phy_fia {
 (__i)++) \
for_each_if(crtc)
 
+#define for_each_new_intel_crtc_in_state_reverse(__state, crtc, 
new_crtc_state, __i) \
+   for ((__i) = (__state)->base.dev->mode_config.num_crtc - 1; \
+(__i) >= 0  && \
+((crtc) = to_intel_crtc((__state)->base.crtcs[__i].ptr), \
+ (new_crtc_state) = 
to_intel_crtc_state((__state)->base.crtcs[__i].new_state), 1); \
+(__i)--) \
+   for_each_if(crtc)
+
 #define for_each_oldnew_intel_plane_in_state(__state, plane, old_plane_state, 
new_plane_state, __i) \
for ((__i) = 0; \
 (__i) < (__state)->base.dev->mode_config.num_total_plane && \
-- 
2.43.2



[PATCH v2 00/17] drm/i915: Bigjoiner modeset sequence redesign and MST support

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

New revision of the bigjoiner modeset sequence redesign.

Changes in v2:
- Reject PSR+bigjoiner combo
- Commit pipes in reverse order to avoid issues with
  slave pipe commits being completed prematurely.
  Should fix the gamma/DSB problems of v1.
- Address review comments
- Part of v1 was merged already separately

Pushed the whole thing here:
https://github.com/vsyrjala/linux.git bigjoiner_mst_etc_2

Stanislav Lisovskiy (1):
  drm/i915: Handle joined pipes inside hsw_crtc_enable()

Vidya Srinivas (1):
  drm/i915: Allow bigjoiner for MST

Ville Syrjälä (15):
  drm/i915: Update pipes in reverse order for bigjoiner
  drm/i915/psr: Disable PSR when bigjoiner is used
  drm/i915: Disable port sync when bigjoiner is used
  drm/i915: Disable live M/N updates when using bigjoiner
  drm/i915/vrr: Disable VRR when using bigjoiner
  drm/i915: Fix intel_modeset_pipe_config_late() for bigjoiner
  drm/i915: s/intel_dp_can_bigjoiner()/intel_dp_has_bigjoiner()/
  drm/i915: Extract intel_dp_joiner_needs_dsc()
  drm/i915/mst: Check intel_dp_joiner_needs_dsc()
  drm/i915: Pass connector to intel_dp_need_bigjoiner()
  drm/i915: Introduce intel_crtc_joined_pipe_mask()
  drm/i915: Extract intel_ddi_post_disable_hdmi_or_sst()
  drm/i915: Utilize intel_crtc_joined_pipe_mask() more
  drm/i915: Handle joined pipes inside hsw_crtc_disable()
  drm/i915/mst: Add bigjoiner handling to MST modeset sequence

 drivers/gpu/drm/i915/display/intel_ddi.c |  83 +++--
 drivers/gpu/drm/i915/display/intel_display.c | 319 +++
 drivers/gpu/drm/i915/display/intel_display.h |  15 +
 drivers/gpu/drm/i915/display/intel_dp.c  |  46 +--
 drivers/gpu/drm/i915/display/intel_dp.h  |   4 +-
 drivers/gpu/drm/i915/display/intel_dp_mst.c  |  80 +++--
 drivers/gpu/drm/i915/display/intel_psr.c |  11 +
 drivers/gpu/drm/i915/display/intel_vrr.c |   7 +
 8 files changed, 353 insertions(+), 212 deletions(-)

-- 
2.43.2



[PATCH 10/12] drm/client: Use [CONNECTOR:%d:%s] formatting

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

Switch to the canonical [CONNECTOR:%d:%s] etc. format for
printing out kms objects.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_client_modeset.c | 65 +++-
 1 file changed, 35 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/drm_client_modeset.c 
b/drivers/gpu/drm/drm_client_modeset.c
index 1751162b7d5c..415d1799337b 100644
--- a/drivers/gpu/drm/drm_client_modeset.c
+++ b/drivers/gpu/drm/drm_client_modeset.c
@@ -251,8 +251,10 @@ static void drm_client_connectors_enabled(struct 
drm_device *dev,
for (i = 0; i < connector_count; i++) {
connector = connectors[i];
enabled[i] = drm_connector_enabled(connector, true);
-   drm_dbg_kms(dev, "connector %d enabled? %s\n", 
connector->base.id,
-   connector->display_info.non_desktop ? "non desktop" 
: str_yes_no(enabled[i]));
+   drm_dbg_kms(dev, "[CONNECTOR:%d:%s] enabled? %s\n",
+   connector->base.id, connector->name,
+   connector->display_info.non_desktop ?
+   "non desktop" : str_yes_no(enabled[i]));
 
any_enabled |= enabled[i];
}
@@ -368,8 +370,8 @@ static int drm_client_get_tile_offsets(struct drm_device 
*dev,
continue;
 
if (!modes[i] && (h_idx || v_idx)) {
-   drm_dbg_kms(dev, "no modes for connector tiled %d %d\n",
-   i, connector->base.id);
+   drm_dbg_kms(dev, "no modes for tiled 
[CONNECTOR:%d:%s]\n",
+   connector->base.id, connector->name);
continue;
}
if (connector->tile_h_loc < h_idx)
@@ -438,14 +440,15 @@ static bool drm_client_target_preferred(struct drm_device 
*dev,
drm_client_get_tile_offsets(dev, connectors, 
connector_count, modes, offsets, i,
connector->tile_h_loc, 
connector->tile_v_loc);
}
-   drm_dbg_kms(dev, "looking for cmdline mode on connector %d\n",
-   connector->base.id);
+   drm_dbg_kms(dev, "looking for cmdline mode on 
[CONNECTOR:%d:%s]\n",
+   connector->base.id, connector->name);
 
/* got for command line mode first */
modes[i] = drm_connector_pick_cmdline_mode(connector);
if (!modes[i]) {
-   drm_dbg_kms(dev, "looking for preferred mode on 
connector %d %d\n",
-   connector->base.id, connector->tile_group ? 
connector->tile_group->id : 0);
+   drm_dbg_kms(dev, "looking for preferred mode on 
[CONNECTOR:%d:%s] (tile group: %d)\n",
+   connector->base.id, connector->name,
+   connector->tile_group ? 
connector->tile_group->id : 0);
modes[i] = drm_connector_preferred_mode(connector, 
width, height);
}
/* No preferred modes, pick one off the list */
@@ -465,8 +468,8 @@ static bool drm_client_target_preferred(struct drm_device 
*dev,
(connector->tile_h_loc == 0 &&
 connector->tile_v_loc == 0 &&
 !drm_connector_get_tiled_mode(connector))) {
-   drm_dbg_kms(dev, "Falling back to non tiled 
mode on Connector %d\n",
-   connector->base.id);
+   drm_dbg_kms(dev, "Falling back to non tiled 
mode on [CONNECTOR:%d:%s]\n",
+   connector->base.id, 
connector->name);
modes[i] = 
drm_connector_fallback_non_tiled_mode(connector);
} else {
modes[i] = 
drm_connector_get_tiled_mode(connector);
@@ -634,15 +637,15 @@ static bool drm_client_firmware_config(struct 
drm_client_dev *client,
num_connectors_detected++;
 
if (!enabled[i]) {
-   drm_dbg_kms(dev, "connector %s not enabled, skipping\n",
-   connector->name);
+   drm_dbg_kms(dev, "[CONNECTOR:%d:%s] not enabled, 
skipping\n",
+   connector->base.id, connector->name);
conn_configured |= BIT(i);
continue;
}
 
if (connector->force == DRM_FORCE_OFF) {
-   drm_dbg_kms(dev, "connector %s is disabled by user, 
skipping\n",
-   connector->name);
+   drm_dbg_kms(dev, "[CONNECTOR:%d:%s] is disabled by 
user, skipping\n",
+   

[PATCH 12/12] drm/probe-helper: Switch to per-device debugs

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

Switch to per-device debugs so that we know which
device we're dealing with.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_probe_helper.c | 35 ++
 1 file changed, 16 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/drm_probe_helper.c 
b/drivers/gpu/drm/drm_probe_helper.c
index 968a3ee66b1e..0860f7367511 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -567,8 +567,8 @@ int drm_helper_probe_single_connector_modes(struct 
drm_connector *connector,
 
drm_modeset_acquire_init(, 0);
 
-   DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
-   connector->name);
+   drm_dbg_kms(dev, "[CONNECTOR:%d:%s]\n",
+   connector->base.id, connector->name);
 
 retry:
ret = drm_modeset_lock(>mode_config.connection_mutex, );
@@ -611,11 +611,10 @@ int drm_helper_probe_single_connector_modes(struct 
drm_connector *connector,
 * check here, and if anything changed start the hotplug code.
 */
if (old_status != connector->status) {
-   DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to 
%s\n",
- connector->base.id,
- connector->name,
- drm_get_connector_status_name(old_status),
- drm_get_connector_status_name(connector->status));
+   drm_dbg_kms(dev, "[CONNECTOR:%d:%s] status updated from %s to 
%s\n",
+   connector->base.id, connector->name,
+   drm_get_connector_status_name(old_status),
+   drm_get_connector_status_name(connector->status));
 
/*
 * The hotplug event code might call into the fb
@@ -638,8 +637,8 @@ int drm_helper_probe_single_connector_modes(struct 
drm_connector *connector,
drm_kms_helper_poll_enable(dev);
 
if (connector->status == connector_status_disconnected) {
-   DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
-   connector->base.id, connector->name);
+   drm_dbg_kms(dev, "[CONNECTOR:%d:%s] disconnected\n",
+   connector->base.id, connector->name);
drm_connector_update_edid_property(connector, NULL);
drm_mode_prune_invalid(dev, >modes, false);
goto exit;
@@ -697,8 +696,8 @@ int drm_helper_probe_single_connector_modes(struct 
drm_connector *connector,
 
drm_mode_sort(>modes);
 
-   DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id,
-   connector->name);
+   drm_dbg_kms(dev, "[CONNECTOR:%d:%s] probed modes :\n",
+   connector->base.id, connector->name);
list_for_each_entry(mode, >modes, head) {
drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
drm_mode_debug_printmodeline(mode);
@@ -834,14 +833,12 @@ static void output_poll_execute(struct work_struct *work)
old = drm_get_connector_status_name(old_status);
new = drm_get_connector_status_name(connector->status);
 
-   DRM_DEBUG_KMS("[CONNECTOR:%d:%s] "
- "status updated from %s to %s\n",
- connector->base.id,
- connector->name,
- old, new);
-   DRM_DEBUG_KMS("[CONNECTOR:%d:%s] epoch counter %llu -> 
%llu\n",
- connector->base.id, connector->name,
- old_epoch_counter, 
connector->epoch_counter);
+   drm_dbg_kms(dev, "[CONNECTOR:%d:%s] status updated from 
%s to %s\n",
+   connector->base.id, connector->name,
+   old, new);
+   drm_dbg_kms(dev, "[CONNECTOR:%d:%s] epoch counter %llu 
-> %llu\n",
+   connector->base.id, connector->name,
+   old_epoch_counter, 
connector->epoch_counter);
 
changed = true;
}
-- 
2.43.2



[PATCH 11/12] drm/client: Streamline mode selection debugs

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

Get rid of all the redundant debugs and just wait until the end
to print which mode (and of which type) we picked.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_client_modeset.c | 65 +---
 1 file changed, 31 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/drm_client_modeset.c 
b/drivers/gpu/drm/drm_client_modeset.c
index 415d1799337b..ad88c11037d8 100644
--- a/drivers/gpu/drm/drm_client_modeset.c
+++ b/drivers/gpu/drm/drm_client_modeset.c
@@ -408,6 +408,8 @@ static bool drm_client_target_preferred(struct drm_device 
*dev,
 
 retry:
for (i = 0; i < connector_count; i++) {
+   const char *mode_type;
+
connector = connectors[i];
 
if (conn_configured & BIT_ULL(i))
@@ -440,20 +442,20 @@ static bool drm_client_target_preferred(struct drm_device 
*dev,
drm_client_get_tile_offsets(dev, connectors, 
connector_count, modes, offsets, i,
connector->tile_h_loc, 
connector->tile_v_loc);
}
-   drm_dbg_kms(dev, "looking for cmdline mode on 
[CONNECTOR:%d:%s]\n",
-   connector->base.id, connector->name);
 
-   /* got for command line mode first */
+   mode_type = "cmdline";
modes[i] = drm_connector_pick_cmdline_mode(connector);
+
if (!modes[i]) {
-   drm_dbg_kms(dev, "looking for preferred mode on 
[CONNECTOR:%d:%s] (tile group: %d)\n",
-   connector->base.id, connector->name,
-   connector->tile_group ? 
connector->tile_group->id : 0);
+   mode_type = "preferred";
modes[i] = drm_connector_preferred_mode(connector, 
width, height);
}
-   /* No preferred modes, pick one off the list */
-   if (!modes[i])
+
+   if (!modes[i]) {
+   mode_type = "first";
modes[i] = drm_connector_first_mode(connector);
+   }
+
/*
 * In case of tiled mode if all tiles not present fallback to
 * first available non tiled mode.
@@ -468,16 +470,20 @@ static bool drm_client_target_preferred(struct drm_device 
*dev,
(connector->tile_h_loc == 0 &&
 connector->tile_v_loc == 0 &&
 !drm_connector_get_tiled_mode(connector))) {
-   drm_dbg_kms(dev, "Falling back to non tiled 
mode on [CONNECTOR:%d:%s]\n",
-   connector->base.id, 
connector->name);
+   mode_type = "non tiled";
modes[i] = 
drm_connector_fallback_non_tiled_mode(connector);
} else {
+   mode_type = "tiled";
modes[i] = 
drm_connector_get_tiled_mode(connector);
}
}
 
-   drm_dbg_kms(dev, "found mode %s\n",
-   modes[i] ? modes[i]->name : "none");
+   if (!modes[i])
+   mode_type = "no";
+
+   drm_dbg_kms(dev, "[CONNECTOR:%d:%s] found %s mode: %s\n",
+   connector->base.id, connector->name,
+   mode_type, modes[i] ? modes[i]->name : "none");
conn_configured |= BIT_ULL(i);
}
 
@@ -624,6 +630,7 @@ static bool drm_client_firmware_config(struct 
drm_client_dev *client,
struct drm_connector *connector;
struct drm_encoder *encoder;
struct drm_crtc *new_crtc;
+   const char *mode_type;
 
connector = connectors[i];
 
@@ -673,29 +680,22 @@ static bool drm_client_firmware_config(struct 
drm_client_dev *client,
 */
for (j = 0; j < count; j++) {
if (crtcs[j] == new_crtc) {
-   drm_dbg_kms(dev, "fallback: cloned 
configuration\n");
+   drm_dbg_kms(dev, "[CONNECTOR:%d:%s] fallback: 
cloned configuration\n",
+   connector->base.id, 
connector->name);
goto bail;
}
}
 
-   drm_dbg_kms(dev, "looking for cmdline mode on 
[CONNECTOR:%d:%s]\n",
-   connector->base.id, connector->name);
-
-   /* go for command line mode first */
+   mode_type = "cmdline";
modes[i] = drm_connector_pick_cmdline_mode(connector);
 
-   /* try for preferred next */
if (!modes[i]) {
-   drm_dbg_kms(dev, "looking for preferred mode on 
[CONNECTOR:%d:%s] (tiled? 

[PATCH 08/12] drm/client: Extract drm_connector_first_mode()

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

Use a consistent method for picking the first mode from the
connnector's mode list.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_client_modeset.c | 17 ++---
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_client_modeset.c 
b/drivers/gpu/drm/drm_client_modeset.c
index 08fc896885dd..1fba6cd8d761 100644
--- a/drivers/gpu/drm/drm_client_modeset.c
+++ b/drivers/gpu/drm/drm_client_modeset.c
@@ -159,6 +159,13 @@ drm_connector_preferred_mode(struct drm_connector 
*connector, int width, int hei
return NULL;
 }
 
+static const struct drm_display_mode *
+drm_connector_first_mode(struct drm_connector *connector)
+{
+   return list_first_entry_or_null(>modes,
+   struct drm_display_mode, head);
+}
+
 static const struct drm_display_mode *
 drm_connector_pick_cmdline_mode(struct drm_connector *connector)
 {
@@ -439,10 +446,8 @@ static bool drm_client_target_preferred(struct 
drm_connector *connectors[],
modes[i] = drm_connector_preferred_mode(connector, 
width, height);
}
/* No preferred modes, pick one off the list */
-   if (!modes[i] && !list_empty(>modes)) {
-   list_for_each_entry(modes[i], >modes, head)
-   break;
-   }
+   if (!modes[i])
+   modes[i] = drm_connector_first_mode(connector);
/*
 * In case of tiled mode if all tiles not present fallback to
 * first available non tiled mode.
@@ -684,9 +689,7 @@ static bool drm_client_firmware_config(struct 
drm_client_dev *client,
if (!modes[i] && !list_empty(>modes)) {
DRM_DEBUG_KMS("using first mode listed on connector 
%s\n",
  connector->name);
-   modes[i] = list_first_entry(>modes,
-   struct drm_display_mode,
-   head);
+   modes[i] = drm_connector_first_mode(connector);
}
 
/* last resort: use current mode */
-- 
2.43.2



[PATCH 07/12] drm/client: Use array notation for function arguments

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

Use the array notation rather that the pointer notation for
function arguments. This makes it clear to the reader that
we are in fact dealing with an array rather than a single
pointer. Functionally the two are equivalent.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_client_modeset.c | 42 ++--
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/drm_client_modeset.c 
b/drivers/gpu/drm/drm_client_modeset.c
index 384a9f8227a0..08fc896885dd 100644
--- a/drivers/gpu/drm/drm_client_modeset.c
+++ b/drivers/gpu/drm/drm_client_modeset.c
@@ -232,9 +232,9 @@ static bool drm_connector_enabled(struct drm_connector 
*connector, bool strict)
return enable;
 }
 
-static void drm_client_connectors_enabled(struct drm_connector **connectors,
+static void drm_client_connectors_enabled(struct drm_connector *connectors[],
  unsigned int connector_count,
- bool *enabled)
+ bool enabled[])
 {
bool any_enabled = false;
struct drm_connector *connector;
@@ -257,11 +257,11 @@ static void drm_client_connectors_enabled(struct 
drm_connector **connectors,
 }
 
 static bool drm_client_target_cloned(struct drm_device *dev,
-struct drm_connector **connectors,
+struct drm_connector *connectors[],
 unsigned int connector_count,
-const struct drm_display_mode **modes,
-struct drm_client_offset *offsets,
-bool *enabled, int width, int height)
+const struct drm_display_mode *modes[],
+struct drm_client_offset offsets[],
+bool enabled[], int width, int height)
 {
int count, i, j;
bool can_clone = false;
@@ -342,10 +342,10 @@ static bool drm_client_target_cloned(struct drm_device 
*dev,
return false;
 }
 
-static int drm_client_get_tile_offsets(struct drm_connector **connectors,
+static int drm_client_get_tile_offsets(struct drm_connector *connectors[],
   unsigned int connector_count,
-  const struct drm_display_mode **modes,
-  struct drm_client_offset *offsets,
+  const struct drm_display_mode *modes[],
+  struct drm_client_offset offsets[],
   int idx,
   int h_idx, int v_idx)
 {
@@ -375,11 +375,11 @@ static int drm_client_get_tile_offsets(struct 
drm_connector **connectors,
return 0;
 }
 
-static bool drm_client_target_preferred(struct drm_connector **connectors,
+static bool drm_client_target_preferred(struct drm_connector *connectors[],
unsigned int connector_count,
-   const struct drm_display_mode **modes,
-   struct drm_client_offset *offsets,
-   bool *enabled, int width, int height)
+   const struct drm_display_mode *modes[],
+   struct drm_client_offset offsets[],
+   bool enabled[], int width, int height)
 {
const u64 mask = BIT_ULL(connector_count) - 1;
struct drm_connector *connector;
@@ -491,10 +491,10 @@ static bool connector_has_possible_crtc(struct 
drm_connector *connector,
 }
 
 static int drm_client_pick_crtcs(struct drm_client_dev *client,
-struct drm_connector **connectors,
+struct drm_connector *connectors[],
 unsigned int connector_count,
-struct drm_crtc **best_crtcs,
-const struct drm_display_mode **modes,
+struct drm_crtc *best_crtcs[],
+const struct drm_display_mode *modes[],
 int n, int width, int height)
 {
struct drm_device *dev = client->dev;
@@ -566,12 +566,12 @@ static int drm_client_pick_crtcs(struct drm_client_dev 
*client,
 
 /* Try to read the BIOS display configuration and use it for the initial 
config */
 static bool drm_client_firmware_config(struct drm_client_dev *client,
-  struct drm_connector **connectors,
+  struct drm_connector *connectors[],
   unsigned int connector_count,
-  struct drm_crtc **crtcs,
-

[PATCH 09/12] drm/client: Switch to per-device debugs

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

Use drm_dev_dbg() & co. so that we know which device we're
dealing with.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_client_modeset.c | 117 ++-
 1 file changed, 60 insertions(+), 57 deletions(-)

diff --git a/drivers/gpu/drm/drm_client_modeset.c 
b/drivers/gpu/drm/drm_client_modeset.c
index 1fba6cd8d761..1751162b7d5c 100644
--- a/drivers/gpu/drm/drm_client_modeset.c
+++ b/drivers/gpu/drm/drm_client_modeset.c
@@ -239,7 +239,8 @@ static bool drm_connector_enabled(struct drm_connector 
*connector, bool strict)
return enable;
 }
 
-static void drm_client_connectors_enabled(struct drm_connector *connectors[],
+static void drm_client_connectors_enabled(struct drm_device *dev,
+ struct drm_connector *connectors[],
  unsigned int connector_count,
  bool enabled[])
 {
@@ -250,8 +251,8 @@ static void drm_client_connectors_enabled(struct 
drm_connector *connectors[],
for (i = 0; i < connector_count; i++) {
connector = connectors[i];
enabled[i] = drm_connector_enabled(connector, true);
-   DRM_DEBUG_KMS("connector %d enabled? %s\n", connector->base.id,
- connector->display_info.non_desktop ? "non 
desktop" : str_yes_no(enabled[i]));
+   drm_dbg_kms(dev, "connector %d enabled? %s\n", 
connector->base.id,
+   connector->display_info.non_desktop ? "non desktop" 
: str_yes_no(enabled[i]));
 
any_enabled |= enabled[i];
}
@@ -312,7 +313,7 @@ static bool drm_client_target_cloned(struct drm_device *dev,
}
 
if (can_clone) {
-   DRM_DEBUG_KMS("can clone using command line\n");
+   drm_dbg_kms(dev, "can clone using command line\n");
return true;
}
 
@@ -341,15 +342,16 @@ static bool drm_client_target_cloned(struct drm_device 
*dev,
drm_mode_destroy(dev, dmt_mode);
 
if (can_clone) {
-   DRM_DEBUG_KMS("can clone using 1024x768\n");
+   drm_dbg_kms(dev, "can clone using 1024x768\n");
return true;
}
 fail:
-   DRM_INFO("kms: can't enable cloning when we probably wanted to.\n");
+   drm_info(dev, "kms: can't enable cloning when we probably wanted 
to.\n");
return false;
 }
 
-static int drm_client_get_tile_offsets(struct drm_connector *connectors[],
+static int drm_client_get_tile_offsets(struct drm_device *dev,
+  struct drm_connector *connectors[],
   unsigned int connector_count,
   const struct drm_display_mode *modes[],
   struct drm_client_offset offsets[],
@@ -366,8 +368,8 @@ static int drm_client_get_tile_offsets(struct drm_connector 
*connectors[],
continue;
 
if (!modes[i] && (h_idx || v_idx)) {
-   DRM_DEBUG_KMS("no modes for connector tiled %d %d\n", i,
- connector->base.id);
+   drm_dbg_kms(dev, "no modes for connector tiled %d %d\n",
+   i, connector->base.id);
continue;
}
if (connector->tile_h_loc < h_idx)
@@ -378,11 +380,12 @@ static int drm_client_get_tile_offsets(struct 
drm_connector *connectors[],
}
offsets[idx].x = hoffset;
offsets[idx].y = voffset;
-   DRM_DEBUG_KMS("returned %d %d for %d %d\n", hoffset, voffset, h_idx, 
v_idx);
+   drm_dbg_kms(dev, "returned %d %d for %d %d\n", hoffset, voffset, h_idx, 
v_idx);
return 0;
 }
 
-static bool drm_client_target_preferred(struct drm_connector *connectors[],
+static bool drm_client_target_preferred(struct drm_device *dev,
+   struct drm_connector *connectors[],
unsigned int connector_count,
const struct drm_display_mode *modes[],
struct drm_client_offset offsets[],
@@ -432,17 +435,17 @@ static bool drm_client_target_preferred(struct 
drm_connector *connectors[],
 * find the tile offsets for this pass - need to find
 * all tiles left and above
 */
-   drm_client_get_tile_offsets(connectors, 
connector_count, modes, offsets, i,
+   drm_client_get_tile_offsets(dev, connectors, 
connector_count, modes, offsets, i,
connector->tile_h_loc, 
connector->tile_v_loc);
}
-   DRM_DEBUG_KMS("looking for cmdline mode on connector %d\n",
- connector->base.id);
+  

[PATCH 06/12] drm/client: Constify modes

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

The modes used by the client code live on the connectors' mode
lists, which are not owned by the client code, and thus it has
no business modifying the modes. Mark the modes const to make
that fact abundantly clear.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_client_modeset.c | 36 +++-
 1 file changed, 19 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/drm_client_modeset.c 
b/drivers/gpu/drm/drm_client_modeset.c
index cf1de06f99aa..384a9f8227a0 100644
--- a/drivers/gpu/drm/drm_client_modeset.c
+++ b/drivers/gpu/drm/drm_client_modeset.c
@@ -117,10 +117,10 @@ drm_client_find_modeset(struct drm_client_dev *client, 
struct drm_crtc *crtc)
return NULL;
 }
 
-static struct drm_display_mode *
+static const struct drm_display_mode *
 drm_connector_get_tiled_mode(struct drm_connector *connector)
 {
-   struct drm_display_mode *mode;
+   const struct drm_display_mode *mode;
 
list_for_each_entry(mode, >modes, head) {
if (mode->hdisplay == connector->tile_h_size &&
@@ -130,10 +130,10 @@ drm_connector_get_tiled_mode(struct drm_connector 
*connector)
return NULL;
 }
 
-static struct drm_display_mode *
+static const struct drm_display_mode *
 drm_connector_fallback_non_tiled_mode(struct drm_connector *connector)
 {
-   struct drm_display_mode *mode;
+   const struct drm_display_mode *mode;
 
list_for_each_entry(mode, >modes, head) {
if (mode->hdisplay == connector->tile_h_size &&
@@ -144,10 +144,10 @@ drm_connector_fallback_non_tiled_mode(struct 
drm_connector *connector)
return NULL;
 }
 
-static struct drm_display_mode *
+static const struct drm_display_mode *
 drm_connector_preferred_mode(struct drm_connector *connector, int width, int 
height)
 {
-   struct drm_display_mode *mode;
+   const struct drm_display_mode *mode;
 
list_for_each_entry(mode, >modes, head) {
if (mode->hdisplay > width ||
@@ -159,10 +159,11 @@ drm_connector_preferred_mode(struct drm_connector 
*connector, int width, int hei
return NULL;
 }
 
-static struct drm_display_mode *drm_connector_pick_cmdline_mode(struct 
drm_connector *connector)
+static const struct drm_display_mode *
+drm_connector_pick_cmdline_mode(struct drm_connector *connector)
 {
-   struct drm_cmdline_mode *cmdline_mode;
-   struct drm_display_mode *mode;
+   const struct drm_cmdline_mode *cmdline_mode;
+   const struct drm_display_mode *mode;
bool prefer_non_interlace;
 
/*
@@ -258,13 +259,14 @@ static void drm_client_connectors_enabled(struct 
drm_connector **connectors,
 static bool drm_client_target_cloned(struct drm_device *dev,
 struct drm_connector **connectors,
 unsigned int connector_count,
-struct drm_display_mode **modes,
+const struct drm_display_mode **modes,
 struct drm_client_offset *offsets,
 bool *enabled, int width, int height)
 {
int count, i, j;
bool can_clone = false;
-   struct drm_display_mode *dmt_mode, *mode;
+   const struct drm_display_mode *mode;
+   struct drm_display_mode *dmt_mode;
 
/* only contemplate cloning in the single crtc case */
if (dev->mode_config.num_crtc > 1)
@@ -342,7 +344,7 @@ static bool drm_client_target_cloned(struct drm_device *dev,
 
 static int drm_client_get_tile_offsets(struct drm_connector **connectors,
   unsigned int connector_count,
-  struct drm_display_mode **modes,
+  const struct drm_display_mode **modes,
   struct drm_client_offset *offsets,
   int idx,
   int h_idx, int v_idx)
@@ -375,7 +377,7 @@ static int drm_client_get_tile_offsets(struct drm_connector 
**connectors,
 
 static bool drm_client_target_preferred(struct drm_connector **connectors,
unsigned int connector_count,
-   struct drm_display_mode **modes,
+   const struct drm_display_mode **modes,
struct drm_client_offset *offsets,
bool *enabled, int width, int height)
 {
@@ -492,7 +494,7 @@ static int drm_client_pick_crtcs(struct drm_client_dev 
*client,
 struct drm_connector **connectors,
 unsigned int connector_count,
 struct drm_crtc **best_crtcs,
-struct drm_display_mode **modes,
+const struct drm_display_mode 

[PATCH 05/12] drm/client: Nuke outdated fastboot comment

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

Remove the tall tale about fastboot vs. user mode vs.
adjusted mode. crtc->mode == crtc->state->mode, so none
of this makes any sense. I suppose it may have been true
long ago in the past.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_client_modeset.c | 10 --
 1 file changed, 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_client_modeset.c 
b/drivers/gpu/drm/drm_client_modeset.c
index 8ef03608b424..cf1de06f99aa 100644
--- a/drivers/gpu/drm/drm_client_modeset.c
+++ b/drivers/gpu/drm/drm_client_modeset.c
@@ -690,16 +690,6 @@ static bool drm_client_firmware_config(struct 
drm_client_dev *client,
/* last resort: use current mode */
if (!modes[i]) {
/*
-* IMPORTANT: We want to use the adjusted mode (i.e.
-* after the panel fitter upscaling) as the initial
-* config, not the input mode, which is what crtc->mode
-* usually contains. But since our current
-* code puts a mode derived from the post-pfit timings
-* into crtc->mode this works out correctly.
-*
-* This is crtc->mode and not crtc->state->mode for the
-* fastboot check to work correctly.
-*
 * FIXME using legacy crtc->mode with atomic drivers
 * is dodgy. Switch to crtc->state->mode, after taking
 * care of the resulting locking/lifetime issues.
-- 
2.43.2



[PATCH 04/12] drm/client: Add a FIXME around crtc->mode usage

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

crtc->mode is legacy junk and shouldn't really be used with
atomic drivers.

Most (all?) atomic drivers do end up still calling
drm_atomic_helper_update_legacy_modeset_state() at some
point, so crtc->mode does still get populated, and this
does work for now. But eventually would be nice to eliminate
all the legacy stuff from atomic drivers.

Switching to crtc->state->mode would require some bigger
changes however, as we currently drop the crtc->mutex
before we're done using the mode. So leave the junk in
for now and just add a FIXME to remind us that this
needs fixing.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_client_modeset.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/drm_client_modeset.c 
b/drivers/gpu/drm/drm_client_modeset.c
index 2b7d0be04911..8ef03608b424 100644
--- a/drivers/gpu/drm/drm_client_modeset.c
+++ b/drivers/gpu/drm/drm_client_modeset.c
@@ -699,6 +699,10 @@ static bool drm_client_firmware_config(struct 
drm_client_dev *client,
 *
 * This is crtc->mode and not crtc->state->mode for the
 * fastboot check to work correctly.
+*
+* FIXME using legacy crtc->mode with atomic drivers
+* is dodgy. Switch to crtc->state->mode, after taking
+* care of the resulting locking/lifetime issues.
 */
DRM_DEBUG_KMS("looking for current mode on connector 
%s\n",
  connector->name);
-- 
2.43.2



[PATCH 03/12] drm/client: Use drm_mode_destroy()

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

Prefer drm_mode_destroy() over bare kfree(), for consistency
and setting a good example.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_client_modeset.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_client_modeset.c 
b/drivers/gpu/drm/drm_client_modeset.c
index 1c3aeb2dfa57..2b7d0be04911 100644
--- a/drivers/gpu/drm/drm_client_modeset.c
+++ b/drivers/gpu/drm/drm_client_modeset.c
@@ -329,7 +329,7 @@ static bool drm_client_target_cloned(struct drm_device *dev,
if (!modes[i])
can_clone = false;
}
-   kfree(dmt_mode);
+   drm_mode_destroy(dev, dmt_mode);
 
if (can_clone) {
DRM_DEBUG_KMS("can clone using 1024x768\n");
@@ -867,7 +867,7 @@ int drm_client_modeset_probe(struct drm_client_dev *client, 
unsigned int width,
break;
}
 
-   kfree(modeset->mode);
+   drm_mode_destroy(dev, modeset->mode);
modeset->mode = drm_mode_duplicate(dev, mode);
drm_connector_get(connector);
modeset->connectors[modeset->num_connectors++] = 
connector;
-- 
2.43.2



[PATCH 02/12] drm/client: s/drm_connector_has_preferred_mode/drm_connector_preferred_mode/

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

Drop the "has" from drm_connector_has_preferred_mode() to better
describe what it does.

Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_client_modeset.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_client_modeset.c 
b/drivers/gpu/drm/drm_client_modeset.c
index 0683a129b362..1c3aeb2dfa57 100644
--- a/drivers/gpu/drm/drm_client_modeset.c
+++ b/drivers/gpu/drm/drm_client_modeset.c
@@ -145,7 +145,7 @@ drm_connector_fallback_non_tiled_mode(struct drm_connector 
*connector)
 }
 
 static struct drm_display_mode *
-drm_connector_has_preferred_mode(struct drm_connector *connector, int width, 
int height)
+drm_connector_preferred_mode(struct drm_connector *connector, int width, int 
height)
 {
struct drm_display_mode *mode;
 
@@ -434,7 +434,7 @@ static bool drm_client_target_preferred(struct 
drm_connector **connectors,
if (!modes[i]) {
DRM_DEBUG_KMS("looking for preferred mode on connector 
%d %d\n",
  connector->base.id, connector->tile_group 
? connector->tile_group->id : 0);
-   modes[i] = drm_connector_has_preferred_mode(connector, 
width, height);
+   modes[i] = drm_connector_preferred_mode(connector, 
width, height);
}
/* No preferred modes, pick one off the list */
if (!modes[i] && !list_empty(>modes)) {
@@ -522,7 +522,7 @@ static int drm_client_pick_crtcs(struct drm_client_dev 
*client,
my_score++;
if (connector->cmdline_mode.specified)
my_score++;
-   if (drm_connector_has_preferred_mode(connector, width, height))
+   if (drm_connector_preferred_mode(connector, width, height))
my_score++;
 
/*
@@ -675,7 +675,7 @@ static bool drm_client_firmware_config(struct 
drm_client_dev *client,
if (!modes[i]) {
DRM_DEBUG_KMS("looking for preferred mode on connector 
%s %d\n",
  connector->name, connector->has_tile);
-   modes[i] = drm_connector_has_preferred_mode(connector, 
width, height);
+   modes[i] = drm_connector_preferred_mode(connector, 
width, height);
}
 
/* No preferred mode marked by the EDID? Are there any modes? */
-- 
2.43.2



[PATCH 01/12] drm/client: Fully protect modes[] with dev->mode_config.mutex

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

The modes[] array contains pointers to modes on the connectors'
mode lists, which are protected by dev->mode_config.mutex.
Thus we need to extend modes[] the same protection or by the
time we use it the elements may already be pointing to
freed/reused memory.

Cc: sta...@vger.kernel.org
Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/10583
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/drm_client_modeset.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_client_modeset.c 
b/drivers/gpu/drm/drm_client_modeset.c
index 871e4e2129d6..0683a129b362 100644
--- a/drivers/gpu/drm/drm_client_modeset.c
+++ b/drivers/gpu/drm/drm_client_modeset.c
@@ -777,6 +777,7 @@ int drm_client_modeset_probe(struct drm_client_dev *client, 
unsigned int width,
unsigned int total_modes_count = 0;
struct drm_client_offset *offsets;
unsigned int connector_count = 0;
+   /* points to modes protected by mode_config.mutex */
struct drm_display_mode **modes;
struct drm_crtc **crtcs;
int i, ret = 0;
@@ -845,7 +846,6 @@ int drm_client_modeset_probe(struct drm_client_dev *client, 
unsigned int width,
drm_client_pick_crtcs(client, connectors, connector_count,
  crtcs, modes, 0, width, height);
}
-   mutex_unlock(>mode_config.mutex);
 
drm_client_modeset_release(client);
 
@@ -875,6 +875,7 @@ int drm_client_modeset_probe(struct drm_client_dev *client, 
unsigned int width,
modeset->y = offset->y;
}
}
+   mutex_unlock(>mode_config.mutex);
 
mutex_unlock(>modeset_mutex);
 out:
-- 
2.43.2



[PATCH 00/12] drm/client: Use after free and debug improvements

2024-04-04 Thread Ville Syrjala
From: Ville Syrjälä 

Various improvements to the drm/client code:
- Fix a use after free (fairly routinely hit by i915 CI)
- Debug print improvements
- Cleanups/etc.

Ville Syrjälä (12):
  drm/client: Fully protect modes[] with dev->mode_config.mutex
  drm/client:
s/drm_connector_has_preferred_mode/drm_connector_preferred_mode/
  drm/client: Use drm_mode_destroy()
  drm/client: Add a FIXME around crtc->mode usage
  drm/client: Nuke outdated fastboot comment
  drm/client: Constify modes
  drm/client: Use array notation for function arguments
  drm/client: Extract drm_connector_first_mode()
  drm/client: Switch to per-device debugs
  drm/client: Use [CONNECTOR:%d:%s] formatting
  drm/client: Streamline mode selection debugs
  drm/probe-helper: Switch to per-device debugs

 drivers/gpu/drm/drm_client_modeset.c | 237 ++-
 drivers/gpu/drm/drm_probe_helper.c   |  35 ++--
 2 files changed, 137 insertions(+), 135 deletions(-)

-- 
2.43.2



[PATCH v2 14/14] drm/i915: Optimize out redundant dbuf slice updates

2024-04-02 Thread Ville Syrjala
From: Ville Syrjälä 

if the new dbuf slices are a superset of the old
dbuf slices then we don't have to do anything in
intel_dbuf_post_plane_update(). Restructure the code
to skip such redundant dbuf slice updates. The main
benefit is slightly less confusing logs.

Reviewed-by: Uma Shankar 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/skl_watermark.c | 27 +---
 1 file changed, 18 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c 
b/drivers/gpu/drm/i915/display/skl_watermark.c
index 1b48009efe2b..50ec51065118 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark.c
+++ b/drivers/gpu/drm/i915/display/skl_watermark.c
@@ -3788,16 +3788,20 @@ void intel_dbuf_pre_plane_update(struct 
intel_atomic_state *state)
intel_atomic_get_new_dbuf_state(state);
const struct intel_dbuf_state *old_dbuf_state =
intel_atomic_get_old_dbuf_state(state);
+   u8 old_slices, new_slices;
 
-   if (!new_dbuf_state ||
-   new_dbuf_state->enabled_slices == old_dbuf_state->enabled_slices)
+   if (!new_dbuf_state)
+   return;
+
+   old_slices = old_dbuf_state->enabled_slices;
+   new_slices = old_dbuf_state->enabled_slices | 
new_dbuf_state->enabled_slices;
+
+   if (old_slices == new_slices)
return;
 
WARN_ON(!new_dbuf_state->base.changed);
 
-   gen9_dbuf_slices_update(i915,
-   old_dbuf_state->enabled_slices |
-   new_dbuf_state->enabled_slices);
+   gen9_dbuf_slices_update(i915, new_slices);
 }
 
 void intel_dbuf_post_plane_update(struct intel_atomic_state *state)
@@ -3807,15 +3811,20 @@ void intel_dbuf_post_plane_update(struct 
intel_atomic_state *state)
intel_atomic_get_new_dbuf_state(state);
const struct intel_dbuf_state *old_dbuf_state =
intel_atomic_get_old_dbuf_state(state);
+   u8 old_slices, new_slices;
 
-   if (!new_dbuf_state ||
-   new_dbuf_state->enabled_slices == old_dbuf_state->enabled_slices)
+   if (!new_dbuf_state)
+   return;
+
+   old_slices = old_dbuf_state->enabled_slices | 
new_dbuf_state->enabled_slices;
+   new_slices = new_dbuf_state->enabled_slices;
+
+   if (old_slices == new_slices)
return;
 
WARN_ON(!new_dbuf_state->base.changed);
 
-   gen9_dbuf_slices_update(i915,
-   new_dbuf_state->enabled_slices);
+   gen9_dbuf_slices_update(i915, new_slices);
 }
 
 static int skl_watermark_ipc_status_show(struct seq_file *m, void *data)
-- 
2.43.2



[PATCH v2 13/14] drm/i915: Use a plain old int for the cdclk/mdclk ratio

2024-04-02 Thread Ville Syrjala
From: Ville Syrjälä 

No point in throwing around u8 when we're dealing with
just an integer. Use a plain old boring 'int'.

Reviewed-by: Uma Shankar 
Reviewed-by: Gustavo Sousa 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_cdclk.c   | 6 +++---
 drivers/gpu/drm/i915/display/intel_cdclk.h   | 4 ++--
 drivers/gpu/drm/i915/display/skl_watermark.c | 6 --
 drivers/gpu/drm/i915/display/skl_watermark.h | 6 --
 4 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c 
b/drivers/gpu/drm/i915/display/intel_cdclk.c
index c23b7ee2837c..d61aa5b7cbdb 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -1893,8 +1893,8 @@ static u32 xe2lpd_mdclk_source_sel(struct 
drm_i915_private *i915)
return MDCLK_SOURCE_SEL_CD2XCLK;
 }
 
-u8 intel_mdclk_cdclk_ratio(struct drm_i915_private *i915,
-  const struct intel_cdclk_config *cdclk_config)
+int intel_mdclk_cdclk_ratio(struct drm_i915_private *i915,
+   const struct intel_cdclk_config *cdclk_config)
 {
if (mdclk_source_is_cdclk_pll(i915))
return DIV_ROUND_UP(cdclk_config->vco, cdclk_config->cdclk);
@@ -,7 +,7 @@ int intel_modeset_calc_cdclk(struct intel_atomic_state 
*state)
 
if (intel_mdclk_cdclk_ratio(dev_priv, _cdclk_state->actual) !=
intel_mdclk_cdclk_ratio(dev_priv, _cdclk_state->actual)) {
-   u8 ratio = intel_mdclk_cdclk_ratio(dev_priv, 
_cdclk_state->actual);
+   int ratio = intel_mdclk_cdclk_ratio(dev_priv, 
_cdclk_state->actual);
 
ret = intel_dbuf_state_set_mdclk_cdclk_ratio(state, ratio);
if (ret)
diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.h 
b/drivers/gpu/drm/i915/display/intel_cdclk.h
index 5d4faf401774..cfdcdec07a4d 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.h
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.h
@@ -67,8 +67,8 @@ void intel_update_cdclk(struct drm_i915_private *dev_priv);
 u32 intel_read_rawclk(struct drm_i915_private *dev_priv);
 bool intel_cdclk_clock_changed(const struct intel_cdclk_config *a,
   const struct intel_cdclk_config *b);
-u8 intel_mdclk_cdclk_ratio(struct drm_i915_private *i915,
-  const struct intel_cdclk_config *cdclk_config);
+int intel_mdclk_cdclk_ratio(struct drm_i915_private *i915,
+   const struct intel_cdclk_config *cdclk_config);
 bool intel_cdclk_is_decreasing_later(struct intel_atomic_state *state);
 void intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state);
 void intel_set_cdclk_post_plane_update(struct intel_atomic_state *state);
diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c 
b/drivers/gpu/drm/i915/display/skl_watermark.c
index ca0f1f89e6d9..1b48009efe2b 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark.c
+++ b/drivers/gpu/drm/i915/display/skl_watermark.c
@@ -3616,7 +3616,8 @@ static void intel_mbus_dbox_update(struct 
intel_atomic_state *state)
}
 }
 
-int intel_dbuf_state_set_mdclk_cdclk_ratio(struct intel_atomic_state *state, 
u8 ratio)
+int intel_dbuf_state_set_mdclk_cdclk_ratio(struct intel_atomic_state *state,
+  int ratio)
 {
struct intel_dbuf_state *dbuf_state;
 
@@ -3629,7 +3630,8 @@ int intel_dbuf_state_set_mdclk_cdclk_ratio(struct 
intel_atomic_state *state, u8
return intel_atomic_lock_global_state(_state->base);
 }
 
-void intel_dbuf_mdclk_cdclk_ratio_update(struct drm_i915_private *i915, u8 
ratio, bool joined_mbus)
+void intel_dbuf_mdclk_cdclk_ratio_update(struct drm_i915_private *i915,
+int ratio, bool joined_mbus)
 {
enum dbuf_slice slice;
 
diff --git a/drivers/gpu/drm/i915/display/skl_watermark.h 
b/drivers/gpu/drm/i915/display/skl_watermark.h
index 3323a1d973f9..ef1a008466be 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark.h
+++ b/drivers/gpu/drm/i915/display/skl_watermark.h
@@ -74,11 +74,13 @@ intel_atomic_get_dbuf_state(struct intel_atomic_state 
*state);
to_intel_dbuf_state(intel_atomic_get_new_global_obj_state(state, 
_i915(state->base.dev)->display.dbuf.obj))
 
 int intel_dbuf_init(struct drm_i915_private *i915);
-int intel_dbuf_state_set_mdclk_cdclk_ratio(struct intel_atomic_state *state, 
u8 ratio);
+int intel_dbuf_state_set_mdclk_cdclk_ratio(struct intel_atomic_state *state,
+  int ratio);
 
 void intel_dbuf_pre_plane_update(struct intel_atomic_state *state);
 void intel_dbuf_post_plane_update(struct intel_atomic_state *state);
-void intel_dbuf_mdclk_cdclk_ratio_update(struct drm_i915_private *i915, u8 
ratio, bool joined_mbus);
+void intel_dbuf_mdclk_cdclk_ratio_update(struct drm_i915_private *i915,
+int ratio, bool joined_mbus);
 void 

[PATCH v2 12/14] drm/i915: Implement vblank synchronized MBUS join changes

2024-04-02 Thread Ville Syrjala
From: Stanislav Lisovskiy 

Currently we can't change MBUS join status without doing a modeset,
because we are lacking mechanism to synchronize those with vblank.
However then this means that we can't do a fastset, if there is a need
to change MBUS join state. Fix that by implementing such change.
We already call correspondent check and update at pre_plane dbuf update,
so the only thing left is to have a non-modeset version of that.
If active pipes stay the same then fastset is possible and only MBUS
join state/ddb allocation updates would be committed.

The full mbus/cdclk sequence will look as follows:
1. disable pipes
2. increase cdclk if necessary
 2.1 reprogram cdclk
 2.2 update dbuf tracker value
3. enable mbus joining if necessary
 3.1 update mbus_ctl
 3.2 update dbuf tracker value
4. reallocate dbuf for planes on active pipes
5. disable mbus joining if necessary
 5.1 update dbuf tracker value
 5.2 update mbus_ctl
6. enable pipes
7. decrease cdclk if necessary
  7.1 update dbuf tracker value
  7.2 reprogram cdclk

And in order to keep things in sync we need:
Step 2:
- mbus_join == old
- mdclk/cdclk ratio == new
Step 3:
- mbus_join == new
- mdclk/cdclk ratio == old when cdclk is changing in step 7
- mdclk/cdclk ratio == new when cdclk is changing in step 2
Step 5:
- mbus_join == new
- mdclk/cdclk ratio == old when cdclk is changing in step 7
- mdclk/cdclk ratio == new when cdclk is changing in step 2
Step 7:
- mbus_join == new
- mdclk/cdclk ratio == new

v2: - Removed redundant parentheses(Ville Syrjälä)
- Constified new_crtc_state in intel_mbus_joined_pipe(Ville Syrjälä)
- Removed pipe_select variable(Ville Syrjälä)
[v3: vsyrjala: Correctly sequence vs. cdclk updates,
   properly describe the full sequence,
   shuffle code around to make the diff more legible,
   streamline a few things]
[v4: vsyrjala: Move the intel_cdclk_is_decreasing_later() stuff
   to a separate patch]

Cc: Gustavo Sousa 
Reviewed-by: Uma Shankar  #v3
Signed-off-by: Stanislav Lisovskiy 
Co-developed-by: Ville Syrjälä 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_display.c |   5 +-
 drivers/gpu/drm/i915/display/skl_watermark.c | 122 +--
 drivers/gpu/drm/i915/display/skl_watermark.h |   3 +-
 3 files changed, 92 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 614e60420a29..e0616f3e4d27 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -6906,6 +6906,8 @@ static void skl_commit_modeset_enables(struct 
intel_atomic_state *state)
intel_pre_update_crtc(state, crtc);
}
 
+   intel_dbuf_mbus_pre_ddb_update(state);
+
while (update_pipes) {
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
new_crtc_state, i) {
@@ -6936,6 +6938,8 @@ static void skl_commit_modeset_enables(struct 
intel_atomic_state *state)
}
}
 
+   intel_dbuf_mbus_post_ddb_update(state);
+
update_pipes = modeset_pipes;
 
/*
@@ -7182,7 +7186,6 @@ static void intel_atomic_commit_tail(struct 
intel_atomic_state *state)
intel_encoders_update_prepare(state);
 
intel_dbuf_pre_plane_update(state);
-   intel_mbus_dbox_update(state);
 
for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
if (new_crtc_state->do_async_flip)
diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c 
b/drivers/gpu/drm/i915/display/skl_watermark.c
index 028c3e6d6b1d..ca0f1f89e6d9 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark.c
+++ b/drivers/gpu/drm/i915/display/skl_watermark.c
@@ -2636,13 +2636,6 @@ skl_compute_ddb(struct intel_atomic_state *state)
if (ret)
return ret;
 
-   if (old_dbuf_state->joined_mbus != new_dbuf_state->joined_mbus) 
{
-   /* TODO: Implement vblank synchronized MBUS joining 
changes */
-   ret = intel_modeset_all_pipes_late(state, "MBUS joining 
change");
-   if (ret)
-   return ret;
-   }
-
drm_dbg_kms(>drm,
"Enabled dbuf slices 0x%x -> 0x%x (total dbuf 
slices 0x%x), mbus joined? %s->%s\n",
old_dbuf_state->enabled_slices,
@@ -3559,7 +3552,7 @@ static bool xelpdp_is_only_pipe_per_dbuf_bank(enum pipe 
pipe, u8 active_pipes)
return false;
 }
 
-void intel_mbus_dbox_update(struct intel_atomic_state *state)
+static void intel_mbus_dbox_update(struct intel_atomic_state *state)
 {
struct drm_i915_private *i915 = to_i915(state->base.dev);
const struct intel_dbuf_state *new_dbuf_state, *old_dbuf_state;
@@ -3640,6 +3633,9 @@ void 

[PATCH v2 11/14] drm/i915: Use the correct mdclk/cdclk ratio in MBUS updates

2024-04-02 Thread Ville Syrjala
From: Ville Syrjälä 

The current cdclk/mbus programming sequence is as follows:
1. intel_set_cdclk_pre_plane_update()
2. update_mbus_pre_enable()
3. intel_set_cdclk_post_plane_update()

when the actual mdclk/cdclk programming is postponed to
intel_set_cdclk_post_plane_update() we must keep using
the old mdclk/cdclk ratio during update_mbus_pre_enable().
This guarantees the programmed ratio matches the rest of
the hardware state (mdlk/cdclk/mbus joining).

v2: Extracted from the vblank synchronized mbus programming patch

Cc: Gustavo Sousa 
Reviewed-by: Uma Shankar  #v1
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_cdclk.c   | 11 +++
 drivers/gpu/drm/i915/display/intel_cdclk.h   |  1 +
 drivers/gpu/drm/i915/display/skl_watermark.c | 19 ---
 3 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c 
b/drivers/gpu/drm/i915/display/intel_cdclk.c
index e0c69d85e733..c23b7ee2837c 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -2576,6 +2576,17 @@ static void intel_cdclk_pcode_post_notify(struct 
intel_atomic_state *state)
   update_cdclk, update_pipe_count);
 }
 
+bool intel_cdclk_is_decreasing_later(struct intel_atomic_state *state)
+{
+   const struct intel_cdclk_state *old_cdclk_state =
+   intel_atomic_get_old_cdclk_state(state);
+   const struct intel_cdclk_state *new_cdclk_state =
+   intel_atomic_get_new_cdclk_state(state);
+
+   return new_cdclk_state && !new_cdclk_state->disable_pipes &&
+   new_cdclk_state->actual.cdclk < old_cdclk_state->actual.cdclk;
+}
+
 /**
  * intel_set_cdclk_pre_plane_update - Push the CDCLK state to the hardware
  * @state: intel atomic state
diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.h 
b/drivers/gpu/drm/i915/display/intel_cdclk.h
index 2843fc091086..5d4faf401774 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.h
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.h
@@ -69,6 +69,7 @@ bool intel_cdclk_clock_changed(const struct 
intel_cdclk_config *a,
   const struct intel_cdclk_config *b);
 u8 intel_mdclk_cdclk_ratio(struct drm_i915_private *i915,
   const struct intel_cdclk_config *cdclk_config);
+bool intel_cdclk_is_decreasing_later(struct intel_atomic_state *state);
 void intel_set_cdclk_pre_plane_update(struct intel_atomic_state *state);
 void intel_set_cdclk_post_plane_update(struct intel_atomic_state *state);
 void intel_cdclk_dump_config(struct drm_i915_private *i915,
diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c 
b/drivers/gpu/drm/i915/display/skl_watermark.c
index a118ecf9e532..028c3e6d6b1d 100644
--- a/drivers/gpu/drm/i915/display/skl_watermark.c
+++ b/drivers/gpu/drm/i915/display/skl_watermark.c
@@ -3663,20 +3663,17 @@ static void intel_dbuf_mdclk_min_tracker_update(struct 
intel_atomic_state *state
intel_atomic_get_old_dbuf_state(state);
const struct intel_dbuf_state *new_dbuf_state =
intel_atomic_get_new_dbuf_state(state);
+   int mdclk_cdclk_ratio;
 
-   if (DISPLAY_VER(i915) >= 20 &&
-   old_dbuf_state->mdclk_cdclk_ratio != 
new_dbuf_state->mdclk_cdclk_ratio) {
-   /*
-* For Xe2LPD and beyond, when there is a change in the ratio
-* between MDCLK and CDCLK, updates to related registers need to
-* happen at a specific point in the CDCLK change sequence. In
-* that case, we defer to the call to
-* intel_dbuf_mdclk_cdclk_ratio_update() to the CDCLK logic.
-*/
-   return;
+   if (intel_cdclk_is_decreasing_later(state)) {
+   /* cdclk/mdclk will be changed later by 
intel_set_cdclk_post_plane_update() */
+   mdclk_cdclk_ratio = old_dbuf_state->mdclk_cdclk_ratio;
+   } else {
+   /* cdclk/mdclk already changed by 
intel_set_cdclk_pre_plane_update() */
+   mdclk_cdclk_ratio = new_dbuf_state->mdclk_cdclk_ratio;
}
 
-   intel_dbuf_mdclk_cdclk_ratio_update(i915, 
new_dbuf_state->mdclk_cdclk_ratio,
+   intel_dbuf_mdclk_cdclk_ratio_update(i915, mdclk_cdclk_ratio,
new_dbuf_state->joined_mbus);
 }
 
-- 
2.43.2



[PATCH v2 10/14] drm/i915: Use old mbus_join value when increasing CDCLK

2024-04-02 Thread Ville Syrjala
From: Stanislav Lisovskiy 

In order to make sure we are not breaking the proper sequence
let's do updates step by step and don't change MBUS join value
during MDCLK/CDCLK programming stage.
MBUS join programming would be taken care by pre/post ddb hooks.

v2: - Reworded comment about using old mbus_join value in
  intel_set_cdclk(Ville Syrjälä)

Reviewed-by: Uma Shankar 
Signed-off-by: Stanislav Lisovskiy 
[v3: vsyrjala: rebase on top of cdclk changes, reword a bit more]
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_cdclk.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c 
b/drivers/gpu/drm/i915/display/intel_cdclk.c
index ed8d9ee094b8..e0c69d85e733 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -2617,6 +2617,12 @@ intel_set_cdclk_pre_plane_update(struct 
intel_atomic_state *state)
 
old_cdclk_state->actual.voltage_level);
}
 
+   /*
+* mbus joining will be changed later by
+* intel_dbuf_mbus_{pre,post}_ddb_update()
+*/
+   cdclk_config.joined_mbus = old_cdclk_state->actual.joined_mbus;
+
drm_WARN_ON(>drm, !new_cdclk_state->base.changed);
 
intel_set_cdclk(i915, _config, pipe,
-- 
2.43.2



  1   2   3   4   5   6   7   8   9   10   >