Re: [PATCH 2/5] drm/i915: Implement basic functions for ultrajoiner support

2024-05-24 Thread Lisovskiy, Stanislav
On Wed, May 22, 2024 at 02:40:56PM +0300, Ville Syrjälä wrote:
> On Wed, May 22, 2024 at 11:01:32AM +0300, Lisovskiy, Stanislav wrote:
> > On Tue, May 21, 2024 at 09:09:16PM +0300, Ville Syrjälä wrote:
> > > On Tue, May 21, 2024 at 11:25:31AM +0300, Lisovskiy, Stanislav wrote:
> > > > On Mon, May 20, 2024 at 09:24:45PM +0300, Ville Syrjälä wrote:
> > > > > On Mon, May 20, 2024 at 10:38:36AM +0300, Stanislav Lisovskiy wrote:
> > > > > > Lets implement or change basic functions required for ultrajoiner
> > > > > > support from atomic commit/modesetting point of view.
> > > > > > 
> > > > > > Signed-off-by: Stanislav Lisovskiy 
> > > > > > ---
> > > > > >  drivers/gpu/drm/i915/display/intel_display.c | 66 
> > > > > > +---
> > > > > >  1 file changed, 56 insertions(+), 10 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> > > > > > b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > index c74721188e59..c390b79a43d6 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > > @@ -242,33 +242,65 @@ is_trans_port_sync_mode(const struct 
> > > > > > intel_crtc_state *crtc_state)
> > > > > > is_trans_port_sync_slave(crtc_state);
> > > > > >  }
> > > > > >  
> > > > > > -static enum pipe joiner_master_pipe(const struct intel_crtc_state 
> > > > > > *crtc_state)
> > > > > > +static u8 joiner_master_pipes(const struct intel_crtc_state 
> > > > > > *crtc_state)
> > > > > >  {
> > > > > > -   return ffs(crtc_state->joiner_pipes) - 1;
> > > > > > +   return BIT(PIPE_A) | BIT(PIPE_C);
> > > > > 
> > > > > Not a fan of the hardcoded pipes.
> > > > > 
> > > > > We could just do something like 
> > > > > joiner_pipes & ((BIT(2) | BIT(0)) << joiner_master_pipe())
> > > > > or some variant of that.
> > > > 
> > > > Well, here we need to decide whats worse: hardcoded bits/shifts versus 
> > > > harcoded pipes..
> > > > I would vote for pipes then, with reasoning that they are at least more 
> > > > obvious and easy to read.
> > > > It is anyway quite easy to change those here or make it platform based, 
> > > > if needed.
> > > 
> > > Hardcoded pipes aren't going to allow us to make the rest of the
> > > code generic because the overall master pipe can be anything when
> > > ultrajoiner isn't used.
> > 
> > joiner_master_pipes in current revision isn't supposed to calculate
> > master pipe for given crtc_state it just returns overall mask of the
> > pipes, which are allowed to be master. 
> 
> Then it seems misnamed, and also why is it taking a crtc_state?

Yeah, crtc_state isn't necessary here, I think.

> 
> > 
> > For actual calculation another function is supposed to be used, which is
> > intel_crtc_master_pipe. 
> > That will determine, if its ultrajoiner or bigjoiner and return 
> > correspondent
> > pipe. It is also based now on assumption that master pipe is always the
> > slave pipe - 1, which I also don't like, if one day BSpec decides to make 
> > it 
> > possible to have like master to be pipe B and slave to be pipe A,
> > then we are screwed with that approach. 
> > Thats why I would prefer overall to set all those relations by some platform
> > based or programmatically set table mappings, however I guess that won't go
> > through reviews :)
> > 
> > > 
> > > Eg. the way we assign the bigjoiner_pipes is by simply setting a
> > > some number (either two or four) of consecutive bits in the mask.
> > > In order for that to keep working universally these functions must 
> > > be able to answer questions based on that bitmask, no matter which
> > > consecutive set of bits are set.
> > 
> > You probably mean that stuff:
> > 
> > <-->if (intel_dp_need_ultrajoiner(intel_dp, adjusted_mode->crtc_clock))
> > <--><-->pipe_config->joiner_pipes = GENMASK(crtc->pipe + 3, 
> > crtc->pipe);
> > <-->else if (intel_dp_need_bigjoiner(intel_dp, connector,
> > <-

Re: [PATCH 2/5] drm/i915: Implement basic functions for ultrajoiner support

2024-05-22 Thread Lisovskiy, Stanislav
On Tue, May 21, 2024 at 09:09:16PM +0300, Ville Syrjälä wrote:
> On Tue, May 21, 2024 at 11:25:31AM +0300, Lisovskiy, Stanislav wrote:
> > On Mon, May 20, 2024 at 09:24:45PM +0300, Ville Syrjälä wrote:
> > > On Mon, May 20, 2024 at 10:38:36AM +0300, Stanislav Lisovskiy wrote:
> > > > Lets implement or change basic functions required for ultrajoiner
> > > > support from atomic commit/modesetting point of view.
> > > > 
> > > > Signed-off-by: Stanislav Lisovskiy 
> > > > ---
> > > >  drivers/gpu/drm/i915/display/intel_display.c | 66 +---
> > > >  1 file changed, 56 insertions(+), 10 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> > > > b/drivers/gpu/drm/i915/display/intel_display.c
> > > > index c74721188e59..c390b79a43d6 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > @@ -242,33 +242,65 @@ is_trans_port_sync_mode(const struct 
> > > > intel_crtc_state *crtc_state)
> > > > is_trans_port_sync_slave(crtc_state);
> > > >  }
> > > >  
> > > > -static enum pipe joiner_master_pipe(const struct intel_crtc_state 
> > > > *crtc_state)
> > > > +static u8 joiner_master_pipes(const struct intel_crtc_state 
> > > > *crtc_state)
> > > >  {
> > > > -   return ffs(crtc_state->joiner_pipes) - 1;
> > > > +   return BIT(PIPE_A) | BIT(PIPE_C);
> > > 
> > > Not a fan of the hardcoded pipes.
> > > 
> > > We could just do something like 
> > > joiner_pipes & ((BIT(2) | BIT(0)) << joiner_master_pipe())
> > > or some variant of that.
> > 
> > Well, here we need to decide whats worse: hardcoded bits/shifts versus 
> > harcoded pipes..
> > I would vote for pipes then, with reasoning that they are at least more 
> > obvious and easy to read.
> > It is anyway quite easy to change those here or make it platform based, if 
> > needed.
> 
> Hardcoded pipes aren't going to allow us to make the rest of the
> code generic because the overall master pipe can be anything when
> ultrajoiner isn't used.

joiner_master_pipes in current revision isn't supposed to calculate
master pipe for given crtc_state it just returns overall mask of the
pipes, which are allowed to be master. 

For actual calculation another function is supposed to be used, which is
intel_crtc_master_pipe. 
That will determine, if its ultrajoiner or bigjoiner and return correspondent
pipe. It is also based now on assumption that master pipe is always the
slave pipe - 1, which I also don't like, if one day BSpec decides to make it 
possible to have like master to be pipe B and slave to be pipe A,
then we are screwed with that approach. 
Thats why I would prefer overall to set all those relations by some platform
based or programmatically set table mappings, however I guess that won't go
through reviews :)

> 
> Eg. the way we assign the bigjoiner_pipes is by simply setting a
> some number (either two or four) of consecutive bits in the mask.
> In order for that to keep working universally these functions must 
> be able to answer questions based on that bitmask, no matter which
> consecutive set of bits are set.

You probably mean that stuff:

<-->if (intel_dp_need_ultrajoiner(intel_dp, adjusted_mode->crtc_clock))
<--><-->pipe_config->joiner_pipes = GENMASK(crtc->pipe + 3, crtc->pipe);
<-->else if (intel_dp_need_bigjoiner(intel_dp, connector,
<--><--><--><--><--> adjusted_mode->crtc_hdisplay,
<--><--><--><--><--> adjusted_mode->crtc_clock))
<--><-->pipe_config->joiner_pipes = GENMASK(crtc->pipe + 1, crtc->pipe);

That one is also about the same, in fact I think we should be able
to set this in a more meaningful way - what if some platform will support
3 but not all 4 pipes for joiner, or 5 pipes..
Best approach would be to use something like joiner_master_pipes | 
joiner_slave_pipes
functions there, which return platform based masks of pipes, because
this GENMASK is kinda hardcoded and not explicit enough.

> 
> > 
> > > 
> > > > +}
> > > > +
> > > > +static u8 joiner_primary_master_pipes(const struct intel_crtc_state 
> > > > *crtc_state)
> > > > +{
> > > > +   return BIT(PIPE_A);
> > > 
> > > This is just the joiner_master_pipe() we already have.
> > 
> >

Re: [PATCH 2/5] drm/i915: Implement basic functions for ultrajoiner support

2024-05-21 Thread Lisovskiy, Stanislav
On Mon, May 20, 2024 at 09:24:45PM +0300, Ville Syrjälä wrote:
> On Mon, May 20, 2024 at 10:38:36AM +0300, Stanislav Lisovskiy wrote:
> > Lets implement or change basic functions required for ultrajoiner
> > support from atomic commit/modesetting point of view.
> > 
> > Signed-off-by: Stanislav Lisovskiy 
> > ---
> >  drivers/gpu/drm/i915/display/intel_display.c | 66 +---
> >  1 file changed, 56 insertions(+), 10 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> > b/drivers/gpu/drm/i915/display/intel_display.c
> > index c74721188e59..c390b79a43d6 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -242,33 +242,65 @@ is_trans_port_sync_mode(const struct intel_crtc_state 
> > *crtc_state)
> > is_trans_port_sync_slave(crtc_state);
> >  }
> >  
> > -static enum pipe joiner_master_pipe(const struct intel_crtc_state 
> > *crtc_state)
> > +static u8 joiner_master_pipes(const struct intel_crtc_state *crtc_state)
> >  {
> > -   return ffs(crtc_state->joiner_pipes) - 1;
> > +   return BIT(PIPE_A) | BIT(PIPE_C);
> 
> Not a fan of the hardcoded pipes.
> 
> We could just do something like 
> joiner_pipes & ((BIT(2) | BIT(0)) << joiner_master_pipe())
> or some variant of that.

Well, here we need to decide whats worse: hardcoded bits/shifts versus harcoded 
pipes..
I would vote for pipes then, with reasoning that they are at least more obvious 
and easy to read.
It is anyway quite easy to change those here or make it platform based, if 
needed.

> 
> > +}
> > +
> > +static u8 joiner_primary_master_pipes(const struct intel_crtc_state 
> > *crtc_state)
> > +{
> > +   return BIT(PIPE_A);
> 
> This is just the joiner_master_pipe() we already have.

I decided to convert joiner_master_pipe to joiner_master_pipes which should 
return a mask,
instead of a pipe.
That approach makes it more generic: for bigjoiner we still get only a single 
bit set in a mask,
however for ultrajoiner case we have now 2 master pipes, so we need a mask here.

joiner_primary_master_pipes is indeed supposed to return only a single primary 
master pipe,
however I decided that operating with masks instead of enum, seems more generic 
and practical approach,
for example if we need to get all pipes, which are not primary master, as below.

> 
> >  }
> >  
> >  u8 intel_crtc_joiner_slave_pipes(const struct intel_crtc_state *crtc_state)
> >  {
> > -   if (crtc_state->joiner_pipes)
> > -   return crtc_state->joiner_pipes & 
> > ~BIT(joiner_master_pipe(crtc_state));
> > +   if (intel_is_ultrajoiner(crtc_state))
> > +   return crtc_state->joiner_pipes & 
> > ~joiner_primary_master_pipes(crtc_state);
> > +   else if (intel_is_bigjoiner(crtc_state))
> > +   return crtc_state->joiner_pipes & 
> > ~joiner_master_pipes(crtc_state);
> > else
> > return 0;
> 
> I don't see why this should make any distinction between bigjoiner
> and ultrajoiner.
> 
> Either it returns everything that isn't the overall master,

For ultrajoiner that is slave pipes + secondary master pipe.
I.e it is everything that is below primary master.

> returns just all the bigjoiner slave pipes. Which one we want
> depends on the use case I guess. So we might need both variants.

Yeah, we need both ways: sometimes we need to get all pipes except primary 
master.
And sometimes we need to get only slave pipes in Bigjoiner terminology.
There are use cases for both.

However definition of slave pipe is a bit tricky here, because technically 
secondary
master pipe is also a slave pipe in relation to primary master pipe.

> 
> >  }
> >  
> > -bool intel_crtc_is_joiner_slave(const struct intel_crtc_state *crtc_state)
> > +bool intel_crtc_is_bigjoiner_slave(const struct intel_crtc_state 
> > *crtc_state)
> >  {
> > struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> >  
> > return crtc_state->joiner_pipes &&
> > -   crtc->pipe != joiner_master_pipe(crtc_state);
> > +   !(BIT(crtc->pipe) & joiner_master_pipes(crtc_state));
> 
> I'd probably add a joiner_slave_pipes() so that the logic is less
> convoluted.

Yeah, then joiner_slave_pipes would have to return only slave pipes in
bigjoiner terminology.

> 
> But I think first we need a solid agreement on the terminology,
> and stick to it consistently.
> 
> Perhaps we need names for?
> - the single master within the overall set of joined pipes
>   (be it ultrajoiner master or the bigjoiner/uncompressed
>joiner master when ultrajoiner isn't used).
>   Just call this joiner_master perhaps? Or perhaps just call it
>   ultrajoiner_master but document that it is valid to use it
>   also for the non-ultrajoiner cases.

I think it would be quite natural to call it a primary master.

Initially BSpec called it that way and it sounds logical.

I.e now we have not only master/slave hierarchy, but also 
second level of hierarchy between masters: secondary 

Re: [PATCH v10 6/6] drm/i915/display: force qgv check after the hw state readout

2024-04-22 Thread Lisovskiy, Stanislav
On Fri, Apr 05, 2024 at 02:35:33PM +0300, Vinod Govindapillai wrote:
> The current intel_bw_atomic_check do not check the possbility
> of a sagv configuration change after the hw state readout.
> Hence cannot update the sagv configuration until some other
> relevant changes like data rates, number of planes etc. happen.
> Introduce a flag to force qgv check in such cases.
> 
> Signed-off-by: Vinod Govindapillai 

Hmmm.. the whole point of that series is actually to put HW/SW
in sync, before we actually are able to calculate the real requirements.

When we initially for QGV/PSF GV to the highest point(thus disabling SAGV),
we exactly want to make sure that HW/SW are in sync(which wasn't the case
before that). Then later when the real plane bw requirements are calculated,
we can possibly relax the QGV point requirements, enabling more points.

I don't see why we need to force the recalculation here.

Or am I missing something?

Stan

> ---
>  drivers/gpu/drm/i915/display/intel_bw.c | 8 ++--
>  drivers/gpu/drm/i915/display/intel_bw.h | 6 ++
>  2 files changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_bw.c 
> b/drivers/gpu/drm/i915/display/intel_bw.c
> index 6fb228a1a28f..1b190be745a0 100644
> --- a/drivers/gpu/drm/i915/display/intel_bw.c
> +++ b/drivers/gpu/drm/i915/display/intel_bw.c
> @@ -755,6 +755,7 @@ void intel_bw_crtc_update(struct intel_bw_state *bw_state,
>   intel_bw_crtc_data_rate(crtc_state);
>   bw_state->num_active_planes[crtc->pipe] =
>   intel_bw_crtc_num_active_planes(crtc_state);
> + bw_state->force_check_qgv = true;
>  
>   drm_dbg_kms(>drm, "pipe %c data rate %u num active planes %u\n",
>   pipe_name(crtc->pipe),
> @@ -1339,8 +1340,9 @@ int intel_bw_atomic_check(struct intel_atomic_state 
> *state)
>   new_bw_state = intel_atomic_get_new_bw_state(state);
>  
>   if (new_bw_state &&
> - intel_can_enable_sagv(i915, old_bw_state) !=
> - intel_can_enable_sagv(i915, new_bw_state))
> + (intel_can_enable_sagv(i915, old_bw_state) !=
> +  intel_can_enable_sagv(i915, new_bw_state) ||
> +  new_bw_state->force_check_qgv))
>   changed = true;
>  
>   /*
> @@ -1354,6 +1356,8 @@ int intel_bw_atomic_check(struct intel_atomic_state 
> *state)
>   if (ret)
>   return ret;
>  
> + new_bw_state->force_check_qgv = false;
> +
>   return 0;
>  }
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_bw.h 
> b/drivers/gpu/drm/i915/display/intel_bw.h
> index fa1e924ec961..161813cca473 100644
> --- a/drivers/gpu/drm/i915/display/intel_bw.h
> +++ b/drivers/gpu/drm/i915/display/intel_bw.h
> @@ -47,6 +47,12 @@ struct intel_bw_state {
>*/
>   u16 qgv_points_mask;
>  
> + /*
> +  * Flag to force the QGV comparison in atomic check right after the
> +  * hw state readout
> +  */
> + bool force_check_qgv;
> +
>   int min_cdclk[I915_MAX_PIPES];
>   unsigned int data_rate[I915_MAX_PIPES];
>   u8 num_active_planes[I915_MAX_PIPES];
> -- 
> 2.34.1
> 


Re: [PATCH v10 2/6] drm/i915/display: Extract code required to calculate max qgv/psf gv point

2024-04-08 Thread Lisovskiy, Stanislav
On Fri, Apr 05, 2024 at 02:35:29PM +0300, Vinod Govindapillai wrote:
> From: Stanislav Lisovskiy 
> 
> We need that in order to force disable SAGV in next patch.
> Also it is beneficial to separate that code, as in majority cases,
> when SAGV is enabled, we don't even need those calculations.
> Also we probably need to determine max PSF GV point as well, however
> currently we don't do that when we disable SAGV, which might be
> actually causing some issues in that case.
> 
> v2: - Introduce helper adl_qgv_bw(counterpart to adl_psf_bw)
>   (Ville Syrjälä)
> - Don't restrict psf gv points for SAGV disable case
>   (Ville Syrjälä)
> v3: - Update icl_max_bw_qgv_point_mask to return max qgv point
>   mask (Vinod)
> v4: - Minor changes in icl_find_qgv_points (Vinod)
> 
> Signed-off-by: Stanislav Lisovskiy 
> Signed-off-by: Vinod Govindapillai 
> ---
>  drivers/gpu/drm/i915/display/intel_bw.c | 80 +++--
>  1 file changed, 50 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_bw.c 
> b/drivers/gpu/drm/i915/display/intel_bw.c
> index 77886cc21211..c00094e5f11c 100644
> --- a/drivers/gpu/drm/i915/display/intel_bw.c
> +++ b/drivers/gpu/drm/i915/display/intel_bw.c
> @@ -661,6 +661,22 @@ static unsigned int adl_psf_bw(struct drm_i915_private 
> *dev_priv,
>   return bi->psf_bw[psf_gv_point];
>  }
>  
> +static unsigned int icl_qgv_bw(struct drm_i915_private *i915,
> +int num_active_planes, int qgv_point)
> +{
> + unsigned int idx;
> +
> + if (DISPLAY_VER(i915) >= 12)
> + idx = tgl_max_bw_index(i915, num_active_planes, qgv_point);
> + else
> + idx = icl_max_bw_index(i915, num_active_planes, qgv_point);
> +
> + if (idx >= ARRAY_SIZE(i915->display.bw.max))
> + return 0;
> +
> + return i915->display.bw.max[idx].deratedbw[qgv_point];
> +}
> +
>  void intel_bw_init_hw(struct drm_i915_private *dev_priv)
>  {
>   if (!HAS_DISPLAY(dev_priv))
> @@ -806,6 +822,35 @@ intel_atomic_get_bw_state(struct intel_atomic_state 
> *state)
>   return to_intel_bw_state(bw_state);
>  }
>  
> +static unsigned int icl_max_bw_qgv_point_mask(struct drm_i915_private *i915,
> +   int num_active_planes)
> +{
> + unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points;
> + unsigned int max_bw_point_mask = 0;
> + unsigned int max_bw = 0;
> + int i;
> +
> + for (i = 0; i < num_qgv_points; i++) {
> + unsigned int max_data_rate =
> + icl_qgv_bw(i915, num_active_planes, i);
> +
> + /*
> +  * We need to know which qgv point gives us
> +  * maximum bandwidth in order to disable SAGV
> +  * if we find that we exceed SAGV block time
> +  * with watermarks. By that moment we already
> +  * have those, as it is calculated earlier in
> +  * intel_atomic_check,
> +  */
> + if (max_data_rate > max_bw) {
> + max_bw_point_mask = BIT(i);
> + max_bw = max_data_rate;
> + }
> + }
> +
> + return max_bw_point_mask;
> +}
> +

Wondering, why we just don't call it "max_bw_point", of course "mask"
could be applied to single point as well, however in most cases it still
kind of implies that there are few of those, however we always find
a single one here.

Stan

>  static int mtl_find_qgv_points(struct drm_i915_private *i915,
>  unsigned int data_rate,
>  unsigned int num_active_planes,
> @@ -883,8 +928,6 @@ static int icl_find_qgv_points(struct drm_i915_private 
> *i915,
>  const struct intel_bw_state *old_bw_state,
>  struct intel_bw_state *new_bw_state)
>  {
> - unsigned int max_bw_point = 0;
> - unsigned int max_bw = 0;
>   unsigned int num_psf_gv_points = 
> i915->display.bw.max[0].num_psf_gv_points;
>   unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points;
>   u16 psf_points = 0;
> @@ -897,31 +940,8 @@ static int icl_find_qgv_points(struct drm_i915_private 
> *i915,
>   return ret;
>  
>   for (i = 0; i < num_qgv_points; i++) {
> - unsigned int idx;
> - unsigned int max_data_rate;
> -
> - if (DISPLAY_VER(i915) >= 12)
> - idx = tgl_max_bw_index(i915, num_active_planes, i);
> - else
> - idx = icl_max_bw_index(i915, num_active_planes, i);
> -
> - if (idx >= ARRAY_SIZE(i915->display.bw.max))
> - continue;
> -
> - max_data_rate = i915->display.bw.max[idx].deratedbw[i];
> -
> - /*
> -  * We need to know which qgv point gives us
> -  * maximum bandwidth in order to disable SAGV
> -  * if we find that we exceed 

Re: [PATCH v10 5/6] drm/i915/display: handle systems with duplicate psf gv points

2024-04-08 Thread Lisovskiy, Stanislav
On Fri, Apr 05, 2024 at 02:35:32PM +0300, Vinod Govindapillai wrote:
> From: Stanislav Lisovskiy 
> 
> There could be multiple qgv and psf gv points with similar values.
> Apparently pcode's handling og psf and qgv points are different. For
> qgv case, pcode sets whatever is asked by the driver. But in case
> of psf gv points, it compares the bw from points before setting the
> mask. This can cause problems in scenarios where we have to disable
> sagv by setting the highest bw point and there could be multiple
> points with highest bw. So to set the maximum psf gv point, find
> out all the points with the highest bw and set all together.
> 
> v1: - use the same treatment to qgv points as well (Vinod)
> 
> v2: - pcode confirms that for qgv points, it sets whatever the
>   driver sets (Vinod)
> 
> Signed-off-by: Stanislav Lisovskiy 
> Signed-off-by: Vinod Govindapillai 
> ---
>  drivers/gpu/drm/i915/display/intel_bw.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_bw.c 
> b/drivers/gpu/drm/i915/display/intel_bw.c
> index 5f4f93524bef..6fb228a1a28f 100644
> --- a/drivers/gpu/drm/i915/display/intel_bw.c
> +++ b/drivers/gpu/drm/i915/display/intel_bw.c
> @@ -874,6 +874,8 @@ static unsigned int icl_max_bw_psf_gv_point_mask(struct 
> drm_i915_private *i915)
>   if (max_data_rate > max_bw) {
>   max_bw_point_mask = BIT(i);
>   max_bw = max_data_rate;
> + } else if (max_data_rate == max_bw) {
> + max_bw_point_mask |= BIT(i);

So we just came back to where we started. Wondering still, why it even bothers 
to expose
two equal PSF GV points. Not only having duplicate points doesn't make much 
sense for 
the driver(since the BW they provide is the same), but also requires some 
additional
logic on top to handle those.

Stan

>   }
>   }
>  
> -- 
> 2.34.1
> 


Re: [PATCH 1/4] drm/i915: Update mbus in intel_dbuf_mbus_update and do it properly

2024-03-25 Thread Lisovskiy, Stanislav
On Mon, Mar 25, 2024 at 08:43:10PM +0200, Ville Syrjälä wrote:
> On Mon, Mar 25, 2024 at 08:29:56PM +0200, Lisovskiy, Stanislav wrote:
> > On Mon, Mar 25, 2024 at 07:11:21PM +0200, Ville Syrjälä wrote:
> > > On Mon, Mar 25, 2024 at 07:01:03PM +0200, Lisovskiy, Stanislav wrote:
> > > > On Mon, Mar 25, 2024 at 04:45:49PM +0200, Ville Syrjälä wrote:
> > > > > On Mon, Mar 25, 2024 at 01:23:26PM +0200, Stanislav Lisovskiy wrote:
> > > > > > According to BSpec we need to do correspondent MBUS updates before
> > > > > > or after DBUF reallocation, depending on whether we are enabling
> > > > > > or disabling mbus joining(typical scenario is swithing between
> > > > > > multiple and single displays).
> > > > > > 
> > > > > > Also we need to be able to update dbuf min tracker and mdclk ratio
> > > > > > separately if mbus_join state didn't change, so lets add one
> > > > > > degree of freedom and make it possible.
> > > > > > 
> > > > > > Reviewed-by: Ville Syrjälä 
> > > > > > Signed-off-by: Stanislav Lisovskiy 
> > > > > > ---
> > > > > >  drivers/gpu/drm/i915/display/skl_watermark.c | 54 
> > > > > > +---
> > > > > >  1 file changed, 35 insertions(+), 19 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c 
> > > > > > b/drivers/gpu/drm/i915/display/skl_watermark.c
> > > > > > index bc341abcab2fe..2b947870527fc 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/skl_watermark.c
> > > > > > +++ b/drivers/gpu/drm/i915/display/skl_watermark.c
> > > > > > @@ -3570,16 +3570,38 @@ void 
> > > > > > intel_dbuf_mdclk_cdclk_ratio_update(struct drm_i915_private *i915, 
> > > > > > u8 ratio
> > > > > >  DBUF_MIN_TRACKER_STATE_SERVICE(ratio - 1));
> > > > > >  }
> > > > > >  
> > > > > > +static void intel_dbuf_mdclk_min_tracker_update(struct 
> > > > > > intel_atomic_state *state)
> > > > > > +{
> > > > > > +   struct drm_i915_private *i915 = to_i915(state->base.dev);
> > > > > > +   const struct intel_dbuf_state *old_dbuf_state =
> > > > > > +   intel_atomic_get_old_dbuf_state(state);
> > > > > > +   const struct intel_dbuf_state *new_dbuf_state =
> > > > > > +   intel_atomic_get_new_dbuf_state(state);
> > > > > > +
> > > > > > +   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;
> > > > > > +   }
> > > > > 
> > > > > That still needs to be removed or else we'll not update the ratio at
> > > > > all during the mbus_join changes. I don't think I saw any removal
> > > > > in subsequent patches.
> > > > > 
> > > > > > +
> > > > > > +   intel_dbuf_mdclk_cdclk_ratio_update(i915, 
> > > > > > new_dbuf_state->mdclk_cdclk_ratio,
> > > > 
> > > > I don't get what is happening here.
> > > > 
> > > > "That whole condition I think needs to go. We want to update the ratio
> > > > also when changing mbus joining. But that behavioural change doesn't
> > > > really belong in this patch, so this is
> > > > 
> > > > Reviewed-by: Ville Syrjälä "
> > > > 
> > > > Now it again needs to be changed or changed in other patch(in this 
> > > > series or which one), 

Re: [PATCH 2/4] drm/i915: Use old mbus_join value when increasing CDCLK

2024-03-25 Thread Lisovskiy, Stanislav
On Mon, Mar 25, 2024 at 08:22:41PM +0200, Ville Syrjälä wrote:
> On Mon, Mar 25, 2024 at 08:16:55PM +0200, Lisovskiy, Stanislav wrote:
> > On Mon, Mar 25, 2024 at 07:01:48PM +0200, Ville Syrjälä wrote:
> > > On Mon, Mar 25, 2024 at 06:55:21PM +0200, Lisovskiy, Stanislav wrote:
> > > > On Mon, Mar 25, 2024 at 04:30:14PM +0200, Ville Syrjälä wrote:
> > > > > On Mon, Mar 25, 2024 at 01:23:27PM +0200, Stanislav Lisovskiy wrote:
> > > > > > In order to make sure we are not breaking the proper sequence
> > > > > > lets to 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: Ville Syrjälä 
> > > > > > Signed-off-by: Stanislav Lisovskiy 
> > > > > > ---
> > > > > >  drivers/gpu/drm/i915/display/intel_cdclk.c | 12 +++-
> > > > > >  1 file changed, 11 insertions(+), 1 deletion(-)
> > > > > > 
> > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c 
> > > > > > b/drivers/gpu/drm/i915/display/intel_cdclk.c
> > > > > > index 31aaa9780dfcf..c7813d433c424 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_cdclk.c
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
> > > > > > @@ -2611,9 +2611,19 @@ intel_set_cdclk_pre_plane_update(struct 
> > > > > > intel_atomic_state *state)
> > > > > >  
> > > > > > if (pipe == INVALID_PIPE ||
> > > > > > old_cdclk_state->actual.cdclk <= 
> > > > > > new_cdclk_state->actual.cdclk) {
> > > > > > +   struct intel_cdclk_config cdclk_config;
> > > > > > +
> > > > > > drm_WARN_ON(>drm, !new_cdclk_state->base.changed);
> > > > > >  
> > > > > > -   intel_set_cdclk(i915, _cdclk_state->actual, pipe);
> > > > > > +   /*
> > > > > > +* By this hack we want to prevent mbus_join to be 
> > > > > > changed
> > > > > > +* beforehand
> > > > > 
> > > > > That sentence is still confusing.
> > > > 
> > > > Write it yourself then. I'm not going to rephrase it anymore.
> > > 
> > > You didn't rephrase it at all AFAIK.
> > > 
> > > Something like
> > > "MBUS joining will be changed later by
> > >  intel_dbuf_mbus_{pre,post}_ddb_update(), thus
> > >  keep using the old joined_mbus state during cdclk
> > >  programming to match the actual hardware state."
> > 
> > Basically my comment says exactly same stuff but with other
> > words, i.e preventing changing mbus join value beforehand,
> > until intel_dbuf_mbus_post_ddb_update takes care of that.
> 
> To me your comment literally says
> "we massage cdclk_config in order to prevent mbus
>  joining changes from happening here"
> Which is a lie; mbus joining will not change here
> no matter what we do to the cdclk_config.
> 
> What we do is make sure the cdclk_config actually
> matches the real hardware state of mbus joining.

Couple of revisions ago we discussed that here we use
old_cdclk state in order to prevent mbus join state to be
changed here so that we kind of do it in steps.
That is what I exactly meant.
To be honest I had some kind of impression from your words
that eventually it might get changed here as well, otherwise
it seems to be quite too much hassle for just keeping
hw/sw in sync.
Arguing about comments is of course really required here.

> 
> > 
> > > 
> > > > 
> > > > > 
> > > > > > - we will take care of this later in
> > > > > > +* intel_dbuf_mbus_post_ddb_update
> > > > > > +*/
> > > > > > +   cdclk_config = new_cdclk_state->actual;
> > > > > > +   cdclk_config.joined_mbus = 
> > > > > > old_cdclk_state->actual.joined_mbus;
> > > > > > +
> > > > > > +   intel_set_cdclk(i915, _config, pipe);
> > > > > > }
> > > > > >  }
> > > > > >  
> > > > > > -- 
> > > > > > 2.37.3
> > > > > 
> > > > > -- 
> > > > > Ville Syrjälä
> > > > > Intel
> > > 
> > > -- 
> > > Ville Syrjälä
> > > Intel
> 
> -- 
> Ville Syrjälä
> Intel


Re: [PATCH 1/4] drm/i915: Update mbus in intel_dbuf_mbus_update and do it properly

2024-03-25 Thread Lisovskiy, Stanislav
On Mon, Mar 25, 2024 at 07:11:21PM +0200, Ville Syrjälä wrote:
> On Mon, Mar 25, 2024 at 07:01:03PM +0200, Lisovskiy, Stanislav wrote:
> > On Mon, Mar 25, 2024 at 04:45:49PM +0200, Ville Syrjälä wrote:
> > > On Mon, Mar 25, 2024 at 01:23:26PM +0200, Stanislav Lisovskiy wrote:
> > > > According to BSpec we need to do correspondent MBUS updates before
> > > > or after DBUF reallocation, depending on whether we are enabling
> > > > or disabling mbus joining(typical scenario is swithing between
> > > > multiple and single displays).
> > > > 
> > > > Also we need to be able to update dbuf min tracker and mdclk ratio
> > > > separately if mbus_join state didn't change, so lets add one
> > > > degree of freedom and make it possible.
> > > > 
> > > > Reviewed-by: Ville Syrjälä 
> > > > Signed-off-by: Stanislav Lisovskiy 
> > > > ---
> > > >  drivers/gpu/drm/i915/display/skl_watermark.c | 54 +---
> > > >  1 file changed, 35 insertions(+), 19 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c 
> > > > b/drivers/gpu/drm/i915/display/skl_watermark.c
> > > > index bc341abcab2fe..2b947870527fc 100644
> > > > --- a/drivers/gpu/drm/i915/display/skl_watermark.c
> > > > +++ b/drivers/gpu/drm/i915/display/skl_watermark.c
> > > > @@ -3570,16 +3570,38 @@ void intel_dbuf_mdclk_cdclk_ratio_update(struct 
> > > > drm_i915_private *i915, u8 ratio
> > > >  DBUF_MIN_TRACKER_STATE_SERVICE(ratio - 1));
> > > >  }
> > > >  
> > > > +static void intel_dbuf_mdclk_min_tracker_update(struct 
> > > > intel_atomic_state *state)
> > > > +{
> > > > +   struct drm_i915_private *i915 = to_i915(state->base.dev);
> > > > +   const struct intel_dbuf_state *old_dbuf_state =
> > > > +   intel_atomic_get_old_dbuf_state(state);
> > > > +   const struct intel_dbuf_state *new_dbuf_state =
> > > > +   intel_atomic_get_new_dbuf_state(state);
> > > > +
> > > > +   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;
> > > > +   }
> > > 
> > > That still needs to be removed or else we'll not update the ratio at
> > > all during the mbus_join changes. I don't think I saw any removal
> > > in subsequent patches.
> > > 
> > > > +
> > > > +   intel_dbuf_mdclk_cdclk_ratio_update(i915, 
> > > > new_dbuf_state->mdclk_cdclk_ratio,
> > 
> > I don't get what is happening here.
> > 
> > "That whole condition I think needs to go. We want to update the ratio
> > also when changing mbus joining. But that behavioural change doesn't
> > really belong in this patch, so this is
> > 
> > Reviewed-by: Ville Syrjälä "
> > 
> > Now it again needs to be changed or changed in other patch(in this series 
> > or which one), 
> > I don't follow.
> > Should it be the patch changing MBUS join value?
> 
> Yeah, probably should be in the last patch. Perhaps we
> could change it before that, but that would need some
> extra brain power to make sure it doesn't temporarily
> break something. So probably not worth the hassle
> to do as a separate patch.
> 
> > 
> > Stan
> > 
> > > 
> > > And it just occurred to me that this thing will in fact be wrong
> > > during the pre/post ddb hooks *and* cdclk is getting decreased
> > > from the post plane update hook.
> > > 
> > > I can't immediately think of a super nice way to handle this.

First of all why that
condition above prevents update when mbus join changes?
It exits when mdclk_cdclk ratio is changed not mbus_join?

That review

Re: [PATCH 2/4] drm/i915: Use old mbus_join value when increasing CDCLK

2024-03-25 Thread Lisovskiy, Stanislav
On Mon, Mar 25, 2024 at 07:01:48PM +0200, Ville Syrjälä wrote:
> On Mon, Mar 25, 2024 at 06:55:21PM +0200, Lisovskiy, Stanislav wrote:
> > On Mon, Mar 25, 2024 at 04:30:14PM +0200, Ville Syrjälä wrote:
> > > On Mon, Mar 25, 2024 at 01:23:27PM +0200, Stanislav Lisovskiy wrote:
> > > > In order to make sure we are not breaking the proper sequence
> > > > lets to 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: Ville Syrjälä 
> > > > Signed-off-by: Stanislav Lisovskiy 
> > > > ---
> > > >  drivers/gpu/drm/i915/display/intel_cdclk.c | 12 +++-
> > > >  1 file changed, 11 insertions(+), 1 deletion(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c 
> > > > b/drivers/gpu/drm/i915/display/intel_cdclk.c
> > > > index 31aaa9780dfcf..c7813d433c424 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_cdclk.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
> > > > @@ -2611,9 +2611,19 @@ intel_set_cdclk_pre_plane_update(struct 
> > > > intel_atomic_state *state)
> > > >  
> > > > if (pipe == INVALID_PIPE ||
> > > > old_cdclk_state->actual.cdclk <= 
> > > > new_cdclk_state->actual.cdclk) {
> > > > +   struct intel_cdclk_config cdclk_config;
> > > > +
> > > > drm_WARN_ON(>drm, !new_cdclk_state->base.changed);
> > > >  
> > > > -   intel_set_cdclk(i915, _cdclk_state->actual, pipe);
> > > > +   /*
> > > > +* By this hack we want to prevent mbus_join to be 
> > > > changed
> > > > +* beforehand
> > > 
> > > That sentence is still confusing.
> > 
> > Write it yourself then. I'm not going to rephrase it anymore.
> 
> You didn't rephrase it at all AFAIK.
> 
> Something like
> "MBUS joining will be changed later by
>  intel_dbuf_mbus_{pre,post}_ddb_update(), thus
>  keep using the old joined_mbus state during cdclk
>  programming to match the actual hardware state."

Basically my comment says exactly same stuff but with other
words, i.e preventing changing mbus join value beforehand,
until intel_dbuf_mbus_post_ddb_update takes care of that.

> 
> > 
> > > 
> > > > - we will take care of this later in
> > > > +* intel_dbuf_mbus_post_ddb_update
> > > > +*/
> > > > +   cdclk_config = new_cdclk_state->actual;
> > > > +   cdclk_config.joined_mbus = 
> > > > old_cdclk_state->actual.joined_mbus;
> > > > +
> > > > +   intel_set_cdclk(i915, _config, pipe);
> > > > }
> > > >  }
> > > >  
> > > > -- 
> > > > 2.37.3
> > > 
> > > -- 
> > > Ville Syrjälä
> > > Intel
> 
> -- 
> Ville Syrjälä
> Intel


Re: [PATCH 1/4] drm/i915: Update mbus in intel_dbuf_mbus_update and do it properly

2024-03-25 Thread Lisovskiy, Stanislav
On Mon, Mar 25, 2024 at 04:45:49PM +0200, Ville Syrjälä wrote:
> On Mon, Mar 25, 2024 at 01:23:26PM +0200, Stanislav Lisovskiy wrote:
> > According to BSpec we need to do correspondent MBUS updates before
> > or after DBUF reallocation, depending on whether we are enabling
> > or disabling mbus joining(typical scenario is swithing between
> > multiple and single displays).
> > 
> > Also we need to be able to update dbuf min tracker and mdclk ratio
> > separately if mbus_join state didn't change, so lets add one
> > degree of freedom and make it possible.
> > 
> > Reviewed-by: Ville Syrjälä 
> > Signed-off-by: Stanislav Lisovskiy 
> > ---
> >  drivers/gpu/drm/i915/display/skl_watermark.c | 54 +---
> >  1 file changed, 35 insertions(+), 19 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c 
> > b/drivers/gpu/drm/i915/display/skl_watermark.c
> > index bc341abcab2fe..2b947870527fc 100644
> > --- a/drivers/gpu/drm/i915/display/skl_watermark.c
> > +++ b/drivers/gpu/drm/i915/display/skl_watermark.c
> > @@ -3570,16 +3570,38 @@ void intel_dbuf_mdclk_cdclk_ratio_update(struct 
> > drm_i915_private *i915, u8 ratio
> >  DBUF_MIN_TRACKER_STATE_SERVICE(ratio - 1));
> >  }
> >  
> > +static void intel_dbuf_mdclk_min_tracker_update(struct intel_atomic_state 
> > *state)
> > +{
> > +   struct drm_i915_private *i915 = to_i915(state->base.dev);
> > +   const struct intel_dbuf_state *old_dbuf_state =
> > +   intel_atomic_get_old_dbuf_state(state);
> > +   const struct intel_dbuf_state *new_dbuf_state =
> > +   intel_atomic_get_new_dbuf_state(state);
> > +
> > +   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;
> > +   }
> 
> That still needs to be removed or else we'll not update the ratio at
> all during the mbus_join changes. I don't think I saw any removal
> in subsequent patches.
> 
> > +
> > +   intel_dbuf_mdclk_cdclk_ratio_update(i915, 
> > new_dbuf_state->mdclk_cdclk_ratio,

I don't get what is happening here.

"That whole condition I think needs to go. We want to update the ratio
also when changing mbus joining. But that behavioural change doesn't
really belong in this patch, so this is

Reviewed-by: Ville Syrjälä "

Now it again needs to be changed or changed in other patch(in this series or 
which one), 
I don't follow.
Should it be the patch changing MBUS join value?

Stan

> 
> And it just occurred to me that this thing will in fact be wrong
> during the pre/post ddb hooks *and* cdclk is getting decreased
> from the post plane update hook.
> 
> I can't immediately think of a super nice way to handle this.
> 
> Perhaps the most stragithforward idea is to just get the mdclk/cdclk
> ratio from i915->display.cdclk.hw during the pre/post ddb hooks.
> cdclk serialization should guard against parallel updates from
> two both places and thus isplay.cdclk.hw should be safe to use.
> 
> The other option would be to determine if a cdclk decrease
> is going to happen or not, and depending on that use the
> old vs. new dbuf_state when updating the ratio in the
> pre/post ddb hooks.
> 
> > +   new_dbuf_state->joined_mbus);
> > +}
> > +
> >  /*
> >   * Configure MBUS_CTL and all DBUF_CTL_S of each slice to join_mbus state 
> > before
> >   * update the request state of all DBUS slices.
> >   */
> > -static void update_mbus_pre_enable(struct intel_atomic_state *state)
> > +static void intel_dbuf_mbus_join_update(struct intel_atomic_state *state)
> >  {
> > struct drm_i915_private *i915 = to_i915(state->base.dev);
> > u32 mbus_ctl;
> > -   const struct intel_dbuf_state *old_dbuf_state =
> > -   intel_atomic_get_old_dbuf_state(state);
> > const struct intel_dbuf_state *new_dbuf_state =
> > intel_atomic_get_new_dbuf_state(state);
> >  
> > @@ -3600,21 +3622,6 @@ static void update_mbus_pre_enable(struct 
> > intel_atomic_state *state)
> > intel_de_rmw(i915, MBUS_CTL,
> >  MBUS_HASHING_MODE_MASK | MBUS_JOIN |
> >  MBUS_JOIN_PIPE_SELECT_MASK, mbus_ctl);
> > -
> > -   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
> > - 

Re: [PATCH 2/4] drm/i915: Use old mbus_join value when increasing CDCLK

2024-03-25 Thread Lisovskiy, Stanislav
On Mon, Mar 25, 2024 at 04:30:14PM +0200, Ville Syrjälä wrote:
> On Mon, Mar 25, 2024 at 01:23:27PM +0200, Stanislav Lisovskiy wrote:
> > In order to make sure we are not breaking the proper sequence
> > lets to 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: Ville Syrjälä 
> > Signed-off-by: Stanislav Lisovskiy 
> > ---
> >  drivers/gpu/drm/i915/display/intel_cdclk.c | 12 +++-
> >  1 file changed, 11 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c 
> > b/drivers/gpu/drm/i915/display/intel_cdclk.c
> > index 31aaa9780dfcf..c7813d433c424 100644
> > --- a/drivers/gpu/drm/i915/display/intel_cdclk.c
> > +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
> > @@ -2611,9 +2611,19 @@ intel_set_cdclk_pre_plane_update(struct 
> > intel_atomic_state *state)
> >  
> > if (pipe == INVALID_PIPE ||
> > old_cdclk_state->actual.cdclk <= new_cdclk_state->actual.cdclk) {
> > +   struct intel_cdclk_config cdclk_config;
> > +
> > drm_WARN_ON(>drm, !new_cdclk_state->base.changed);
> >  
> > -   intel_set_cdclk(i915, _cdclk_state->actual, pipe);
> > +   /*
> > +* By this hack we want to prevent mbus_join to be changed
> > +* beforehand
> 
> That sentence is still confusing.

Write it yourself then. I'm not going to rephrase it anymore.

> 
> > - we will take care of this later in
> > +* intel_dbuf_mbus_post_ddb_update
> > +*/
> > +   cdclk_config = new_cdclk_state->actual;
> > +   cdclk_config.joined_mbus = old_cdclk_state->actual.joined_mbus;
> > +
> > +   intel_set_cdclk(i915, _config, pipe);
> > }
> >  }
> >  
> > -- 
> > 2.37.3
> 
> -- 
> Ville Syrjälä
> Intel


Re: [PATCH 5/5] drm/i915: Implement vblank synchronized MBUS join changes

2024-03-25 Thread Lisovskiy, Stanislav
On Fri, Mar 22, 2024 at 08:06:46PM +0200, Ville Syrjälä wrote:
> On Fri, Mar 22, 2024 at 01:40:46PM +0200, Stanislav Lisovskiy wrote:
> > 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.
> > 
> > Signed-off-by: Stanislav Lisovskiy 
> > ---
> >  drivers/gpu/drm/i915/display/intel_display.c |   6 +-
> >  drivers/gpu/drm/i915/display/skl_watermark.c | 108 +++
> >  drivers/gpu/drm/i915/display/skl_watermark.h |   2 +
> >  3 files changed, 94 insertions(+), 22 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> > b/drivers/gpu/drm/i915/display/intel_display.c
> > index b88f214e111ae..d5351f6fa2eb4 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -6895,6 +6895,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) {
> > @@ -6925,6 +6927,8 @@ static void skl_commit_modeset_enables(struct 
> > intel_atomic_state *state)
> > }
> > }
> >  
> > +   intel_dbuf_mbus_post_ddb_update(state);
> > +
> > update_pipes = modeset_pipes;
> >  
> > /*
> > @@ -7169,9 +7173,7 @@ 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 7eb78e0c8c8e3..eee13b57d4830 100644
> > --- a/drivers/gpu/drm/i915/display/skl_watermark.c
> > +++ b/drivers/gpu/drm/i915/display/skl_watermark.c
> > @@ -4,6 +4,7 @@
> >   */
> >  
> >  #include 
> > +#include 
> >  
> >  #include "i915_drv.h"
> >  #include "i915_fixed.h"
> > @@ -2636,13 +2637,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,
> > @@ -3594,30 +3588,57 @@ static void 
> > intel_dbuf_mdclk_min_tracker_update(struct intel_atomic_state *state
> > new_dbuf_state->joined_mbus);
> >  }
> >  
> > +static enum pipe intel_mbus_joined_pipe(struct intel_atomic_state *state,
> > +   const struct intel_dbuf_state 
> > *dbuf_state)
> > +{
> > +   struct drm_i915_private *i915 = to_i915(state->base.dev);
> > +   enum pipe sync_pipe = ffs(dbuf_state->active_pipes) - 1;
> > +   struct intel_crtc_state *new_crtc_state;
> 
> const
> 
> > +   struct intel_crtc *crtc;
> > +
> > +   drm_WARN_ON(>drm, !dbuf_state->joined_mbus);
> > +   drm_WARN_ON(>drm, !is_power_of_2(dbuf_state->active_pipes));
> > +
> > +   crtc = intel_crtc_for_pipe(i915, sync_pipe);
> > +   new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
> > +
> > +   if (new_crtc_state && !intel_crtc_needs_modeset(new_crtc_state))
> > +   return sync_pipe;
> > +   else
> > +   return INVALID_PIPE;
> > +}
> > +
> >  /*
> >   * Configure MBUS_CTL and all DBUF_CTL_S of each slice to join_mbus state 
> > before
> >   * update the request state of all DBUS slices.
> >   */
> > -static void intel_dbuf_mbus_join_update(struct intel_atomic_state *state)
> > +static void intel_dbuf_mbus_ctl_update(struct intel_atomic_state *state,
> > +  enum pipe sync_pipe)
> >  {
> > struct drm_i915_private *i915 = to_i915(state->base.dev);
> > u32 mbus_ctl;
> > const struct intel_dbuf_state 

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

2024-03-13 Thread Lisovskiy, Stanislav
On Tue, Mar 12, 2024 at 09:48:33PM -0700, Manasi Navare wrote:
> Now when we enable bigjoiner for MST, in MST case
> intel_ddi_post_disable_hdmi_or_sst() function wont get called,
> Do we need similar changes for MST case to loop over the joined pipes
> in MST bigjoiner case?
> 
> Manasi

Hi Manasi, check now my latest series, that should handle this.


Stan

> 
> On Fri, Mar 8, 2024 at 5:12 AM Stanislav Lisovskiy
>  wrote:
> >
> > 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 
> >
> > Signed-off-by: Vidya Srinivas 
> > Reviewed-by: Manasi Navare 
> > ---
> >  drivers/gpu/drm/i915/display/intel_ddi.c|  6 --
> >  drivers/gpu/drm/i915/display/intel_dp_mst.c | 17 +
> >  2 files changed, 13 insertions(+), 10 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
> > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > index 3756975bd561c..3bf8941107473 100644
> > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > @@ -3924,9 +3924,11 @@ static void intel_ddi_read_func_ctl(struct 
> > intel_encoder *encoder,
> > pipe_config->lane_count =
> > ((temp & DDI_PORT_WIDTH_MASK) >> 
> > DDI_PORT_WIDTH_SHIFT) + 1;
> >
> > -   if (DISPLAY_VER(dev_priv) >= 12)
> > -   pipe_config->mst_master_transcoder =
> > +   if (DISPLAY_VER(dev_priv) >= 12) {
> > +   if (!intel_crtc_is_bigjoiner_slave(pipe_config))
> > +   pipe_config->mst_master_transcoder =
> > 
> > REG_FIELD_GET(TRANS_DDI_MST_TRANSPORT_SELECT_MASK, temp);
> > +   }
> >
> > intel_cpu_transcoder_get_m1_n1(crtc, cpu_transcoder,
> >_config->dp_m_n);
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
> > b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > index 53aec023ce92f..3e6e2cd08d3ab 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;
> > const struct intel_connector *connector =
> > @@ -542,6 +543,10 @@ 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, 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;
> > @@ -1330,12 +1335,6 @@ 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 (mode->clock < 1) {
> > *status = MODE_CLOCK_LOW;
> > return 0;
> > @@ -1349,8 +1348,10 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector 
> > *connector,
> > if (intel_dp_need_bigjoiner(intel_dp, mode->hdisplay, 
> > target_clock)) {
> > bigjoiner = true;
> > max_dotclk *= 2;
> > +   }
> >
> > -   /* TODO: add support for bigjoiner */
> > +   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;
> > }
> > @@ -1397,7 +1398,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector 
> > *connector,
> > return 0;
> > }
> >
> > -   *status = 

Re: [PATCH 2/6] drm/i915: Extract intel_ddi_post_disable_hdmi_or_sst()

2024-03-13 Thread Lisovskiy, Stanislav
On Tue, Mar 12, 2024 at 09:36:22PM -0700, Manasi Navare wrote:
> Thanks Stan for the cleanup around post disable non MST case, one comment 
> below
> 
> On Fri, Mar 8, 2024 at 5:11 AM Stanislav Lisovskiy
>  wrote:
> >
> > 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.
> 
> 
> >
> > Signed-off-by: Ville Syrjälä 
> > Signed-off-by: Stanislav Lisovskiy 
> > Credits-to: Ville Syrjälä 
> > ---
> >  drivers/gpu/drm/i915/display/intel_ddi.c | 37 +++-
> >  1 file changed, 23 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
> > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > index bbce74f011d40..5628a4ab608d4 100644
> > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > @@ -3095,28 +3095,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_master_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)) {
> 
> This bigjoiner slave handling for MST path will be added later to the
> intel_ddi_post_post_disable()
> when we enable bigjoiner for MST?
> 
> Manasi

Hi Manasi, yes, currently I'm evaluating what would be the best way
to do that.


Stan

> 
> > @@ -3128,6 +3126,17 @@ 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.37.3
> >


Re: [PATCH 6/8] drm/i915/xe2lpd: Support MDCLK:CDCLK ratio changes

2024-03-12 Thread Lisovskiy, Stanislav
On Mon, Mar 11, 2024 at 06:13:29PM -0300, Gustavo Sousa wrote:
> Quoting Lisovskiy, Stanislav (2024-03-11 18:01:04-03:00)
> >On Mon, Mar 04, 2024 at 03:30:25PM -0300, Gustavo Sousa wrote:
> >> Commit 394b4b7df9f7 ("drm/i915/lnl: Add CDCLK table") and commit
> >> 3d3696c0fed1 ("drm/i915/lnl: Start using CDCLK through PLL") started
> >> adding support for CDCLK programming support for Xe2LPD. One final piece
> >> is missing, which is the programming necessary for changed in the ratio
> >> between MDCLK and CDCLK. Let's do that now.
> >> 
> >> BSpec instructs us to update MBUS_CTL and DBUF_CTL_S* registers when the
> >> ratio between MDCLK and CDCLK changes. The updates must be done before
> >> changing the CDCLK when decreasing the frequency; or after it when
> >> increasing the frequency.
> >> 
> >> Ratio-related updates to MBUS_CTL also depend on the state of MBus
> >> joining, so they are performed by either CDCLK change sequence or by
> >> changes in MBus joining. Since one might happen independently of the
> >> other, we need to make sure that both logics see the necessary state
> >> values when programming that register. MBus joining logic needs to know
> >> the MDCLK:CDCLK ratio and that's already provided via mdclk_cdclk_ratio
> >> field of struct intel_dbuf_state.
> >> 
> >> For the CDCLK logic, we need to have something similar: we need to
> >> propagate the status of MBus joining to struct intel_cdclk_state. Do
> >> that by adding the field joined_mbus to struct intel_cdclk_config.
> >> (Preferably, that field would be added to intel_cdclk_state, however
> >> currently only intel_cdclk_config is passed down to the functions that
> >> do the register programming. We might revisit this decision if we find
> >> that refactoring the code to pass the whole intel_cdclk_state is worth
> >> it.)
> >> 
> >> Bspec: 68864, 68868, 69090, 69482
> >> Signed-off-by: Gustavo Sousa 
> >> ---
> >>  drivers/gpu/drm/i915/display/intel_cdclk.c| 31 ++
> >>  drivers/gpu/drm/i915/display/intel_cdclk.h|  3 ++
> >>  drivers/gpu/drm/i915/display/skl_watermark.c  | 40 +++
> >>  drivers/gpu/drm/i915/display/skl_watermark.h  |  1 +
> >>  .../gpu/drm/i915/display/skl_watermark_regs.h | 18 +
> >>  5 files changed, 77 insertions(+), 16 deletions(-)
> >> 
> >> diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c 
> >> b/drivers/gpu/drm/i915/display/intel_cdclk.c
> >> index 04a6e9806254..12753589072d 100644
> >> --- a/drivers/gpu/drm/i915/display/intel_cdclk.c
> >> +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
> >> @@ -40,6 +40,7 @@
> >>  #include "intel_psr.h"
> >>  #include "intel_vdsc.h"
> >>  #include "skl_watermark.h"
> >> +#include "skl_watermark_regs.h"
> >>  #include "vlv_sideband.h"
> >>  
> >>  /**
> >> @@ -1683,6 +1684,8 @@ static void bxt_get_cdclk(struct drm_i915_private 
> >> *dev_priv,
> >>  }
> >>  
> >>   out:
> >> +if (DISPLAY_VER(dev_priv) >= 20)
> >> +cdclk_config->joined_mbus = intel_de_read(dev_priv, 
> >> MBUS_CTL) & MBUS_JOIN;
> >>  /*
> >>   * Can't read this out :( Let's assume it's
> >>   * at least what the CDCLK frequency requires.
> >> @@ -1908,6 +1911,14 @@ u8 intel_mdclk_cdclk_ratio(struct drm_i915_private 
> >> *i915,
> >>  }
> >>  }
> >>  
> >> +static void xe2lpd_mdclk_cdclk_ratio_program(struct drm_i915_private 
> >> *i915,
> >> + const struct 
> >> intel_cdclk_config *cdclk_config)
> >> +{
> >> +intel_dbuf_mdclk_cdclk_ratio_update(i915,
> >> +intel_mdclk_cdclk_ratio(i915, 
> >> cdclk_config),
> >> +cdclk_config->joined_mbus);
> >> +}
> >> +
> >>  static bool cdclk_compute_crawl_and_squash_midpoint(struct 
> >> drm_i915_private *i915,
> >>  const struct 
> >> intel_cdclk_config *old_cdclk_config,
> >>  const struct 
> >> intel_cdclk_config *new_cdclk_config,
> >> @@ -2089,6 +2

Re: [PATCH 6/8] drm/i915/xe2lpd: Support MDCLK:CDCLK ratio changes

2024-03-11 Thread Lisovskiy, Stanislav
On Mon, Mar 04, 2024 at 03:30:25PM -0300, Gustavo Sousa wrote:
> Commit 394b4b7df9f7 ("drm/i915/lnl: Add CDCLK table") and commit
> 3d3696c0fed1 ("drm/i915/lnl: Start using CDCLK through PLL") started
> adding support for CDCLK programming support for Xe2LPD. One final piece
> is missing, which is the programming necessary for changed in the ratio
> between MDCLK and CDCLK. Let's do that now.
> 
> BSpec instructs us to update MBUS_CTL and DBUF_CTL_S* registers when the
> ratio between MDCLK and CDCLK changes. The updates must be done before
> changing the CDCLK when decreasing the frequency; or after it when
> increasing the frequency.
> 
> Ratio-related updates to MBUS_CTL also depend on the state of MBus
> joining, so they are performed by either CDCLK change sequence or by
> changes in MBus joining. Since one might happen independently of the
> other, we need to make sure that both logics see the necessary state
> values when programming that register. MBus joining logic needs to know
> the MDCLK:CDCLK ratio and that's already provided via mdclk_cdclk_ratio
> field of struct intel_dbuf_state.
> 
> For the CDCLK logic, we need to have something similar: we need to
> propagate the status of MBus joining to struct intel_cdclk_state. Do
> that by adding the field joined_mbus to struct intel_cdclk_config.
> (Preferably, that field would be added to intel_cdclk_state, however
> currently only intel_cdclk_config is passed down to the functions that
> do the register programming. We might revisit this decision if we find
> that refactoring the code to pass the whole intel_cdclk_state is worth
> it.)
> 
> Bspec: 68864, 68868, 69090, 69482
> Signed-off-by: Gustavo Sousa 
> ---
>  drivers/gpu/drm/i915/display/intel_cdclk.c| 31 ++
>  drivers/gpu/drm/i915/display/intel_cdclk.h|  3 ++
>  drivers/gpu/drm/i915/display/skl_watermark.c  | 40 +++
>  drivers/gpu/drm/i915/display/skl_watermark.h  |  1 +
>  .../gpu/drm/i915/display/skl_watermark_regs.h | 18 +
>  5 files changed, 77 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c 
> b/drivers/gpu/drm/i915/display/intel_cdclk.c
> index 04a6e9806254..12753589072d 100644
> --- a/drivers/gpu/drm/i915/display/intel_cdclk.c
> +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
> @@ -40,6 +40,7 @@
>  #include "intel_psr.h"
>  #include "intel_vdsc.h"
>  #include "skl_watermark.h"
> +#include "skl_watermark_regs.h"
>  #include "vlv_sideband.h"
>  
>  /**
> @@ -1683,6 +1684,8 @@ static void bxt_get_cdclk(struct drm_i915_private 
> *dev_priv,
>   }
>  
>   out:
> + if (DISPLAY_VER(dev_priv) >= 20)
> + cdclk_config->joined_mbus = intel_de_read(dev_priv, MBUS_CTL) & 
> MBUS_JOIN;
>   /*
>* Can't read this out :( Let's assume it's
>* at least what the CDCLK frequency requires.
> @@ -1908,6 +1911,14 @@ u8 intel_mdclk_cdclk_ratio(struct drm_i915_private 
> *i915,
>   }
>  }
>  
> +static void xe2lpd_mdclk_cdclk_ratio_program(struct drm_i915_private *i915,
> +  const struct intel_cdclk_config 
> *cdclk_config)
> +{
> + intel_dbuf_mdclk_cdclk_ratio_update(i915,
> + intel_mdclk_cdclk_ratio(i915, 
> cdclk_config),
> + cdclk_config->joined_mbus);
> +}
> +
>  static bool cdclk_compute_crawl_and_squash_midpoint(struct drm_i915_private 
> *i915,
>   const struct 
> intel_cdclk_config *old_cdclk_config,
>   const struct 
> intel_cdclk_config *new_cdclk_config,
> @@ -2089,6 +2100,9 @@ static void bxt_set_cdclk(struct drm_i915_private 
> *dev_priv,
>   return;
>   }
>  
> + if (DISPLAY_VER(dev_priv) >= 20 && cdclk < 
> dev_priv->display.cdclk.hw.cdclk)
> + xe2lpd_mdclk_cdclk_ratio_program(dev_priv, cdclk_config);
> +
>   if (cdclk_compute_crawl_and_squash_midpoint(dev_priv, 
> _priv->display.cdclk.hw,
>   cdclk_config, 
> _cdclk_config)) {
>   _bxt_set_cdclk(dev_priv, _cdclk_config, pipe);
> @@ -2097,6 +2111,9 @@ static void bxt_set_cdclk(struct drm_i915_private 
> *dev_priv,
>   _bxt_set_cdclk(dev_priv, cdclk_config, pipe);
>   }
>  
> + if (DISPLAY_VER(dev_priv) >= 20 && cdclk > 
> dev_priv->display.cdclk.hw.cdclk)
> + xe2lpd_mdclk_cdclk_ratio_program(dev_priv, cdclk_config);
> +
>   if (DISPLAY_VER(dev_priv) >= 14)
>   /*
>* NOOP - No Pcode communication needed for
> @@ -3179,6 +3196,20 @@ int intel_cdclk_atomic_check(struct intel_atomic_state 
> *state,
>   return 0;
>  }
>  
> +int intel_cdclk_state_set_joined_mbus(struct intel_atomic_state *state, bool 
> joined_mbus)
> +{
> + struct intel_cdclk_state *cdclk_state;
> +
> + cdclk_state = intel_atomic_get_cdclk_state(state);
> + if 

Re: [PATCH 2/2] drm/i915: Implement vblank synchronized MBUS join changes

2024-03-11 Thread Lisovskiy, Stanislav
On Fri, Mar 08, 2024 at 05:11:42PM +0200, Ville Syrjälä wrote:
> On Fri, Mar 08, 2024 at 03:43:35PM +0200, Lisovskiy, Stanislav wrote:
> > On Fri, Mar 08, 2024 at 12:07:19PM +0200, Ville Syrjälä wrote:
> > > On Wed, Feb 28, 2024 at 10:02:13AM +0200, Stanislav Lisovskiy wrote:
> > > > 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.
> > > > 
> > > > v2: Implement additional changes according to BSpec.
> > > > Vblank wait is needed after MBus/Dbuf programming in case if
> > > > no modeset is done and we are switching from single to multiple
> > > > displays, i.e mbus join state switches from "joined" to  
> > > > "non-joined"
> > > > state. Otherwise vblank wait is not needed according to spec.
> > > > 
> > > > v3: Split mbus and dbox programming into to pre/post plane update parts,
> > > > how it should be done according to BSpec.
> > > > 
> > > > v4: - Place "single display to multiple displays scenario" MBUS/DBOX 
> > > > programming
> > > >   after DDB reallocation, but before crtc enabling(that is where is 
> > > > has
> > > >   to be according to spec).
> > > > - Check if crtc is still active, not only the old state.
> > > > - Do a vblank wait if MBUX DBOX register was modified.
> > > > - And of course do vblank wait only if crtc was active.
> > > > - Do vblank wait only if we are not doing a modeset, if we are doing
> > > >   something before *commit_modeset_enables, because all crtcs might 
> > > > be
> > > >   disabled at this moment, so we will get WARN if try waiting for 
> > > > vblank
> > > >   then.
> > > > - Still getting FIFO underrun so try waiting for vblank in 
> > > > pre_plane update
> > > >   as well.
> > > > - Write also pipe that we need to sync with to MBUS_CTL register.
> > > > 
> > > > v5: - Do vblank wait only for the first pipe, if mbus is joined
> > > > - Check also if new/old_dbuf_state is not NULL, before getting 
> > > > single pipe
> > > >   and active pipes.
> > > > 
> > > > Signed-off-by: Stanislav Lisovskiy 
> > > > ---
> > > >  drivers/gpu/drm/i915/display/intel_display.c |  13 ++-
> > > >  drivers/gpu/drm/i915/display/skl_watermark.c | 104 +++
> > > >  drivers/gpu/drm/i915/display/skl_watermark.h |   1 +
> > > >  3 files changed, 96 insertions(+), 22 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> > > > b/drivers/gpu/drm/i915/display/intel_display.c
> > > > index 00ac65a140298..989818f5d342f 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > @@ -6906,6 +6906,17 @@ static void skl_commit_modeset_enables(struct 
> > > > intel_atomic_state *state)
> > > > }
> > > > }
> > > >  
> > > > +   /*
> > > > +* Some MBUS/DBuf update scenarios(mbus join disable) require 
> > > > that
> > > > +* changes are done _after_ DDB reallocation, but _before_ crtc 
> > > > enabling.
> > > > +* Typically we are disabling resources in 
> > > > post_plane/crtc_enable hooks,
> > > > +* however in that case BSpec explicitly states that this 
> > > > should be done
> > > > +* before we enable additional displays.
> > > > +* FIXME: Should we still call this also there(post_plane hook)
> > > > +* for extra-safety? If so, how to make sure, we don't call it 
> > > > twice?
> > > > +*/
> > > > +   intel_db

Re: [PATCH 2/2] drm/i915: Implement vblank synchronized MBUS join changes

2024-03-08 Thread Lisovskiy, Stanislav
On Fri, Mar 08, 2024 at 12:07:19PM +0200, Ville Syrjälä wrote:
> On Wed, Feb 28, 2024 at 10:02:13AM +0200, Stanislav Lisovskiy wrote:
> > 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.
> > 
> > v2: Implement additional changes according to BSpec.
> > Vblank wait is needed after MBus/Dbuf programming in case if
> > no modeset is done and we are switching from single to multiple
> > displays, i.e mbus join state switches from "joined" to  "non-joined"
> > state. Otherwise vblank wait is not needed according to spec.
> > 
> > v3: Split mbus and dbox programming into to pre/post plane update parts,
> > how it should be done according to BSpec.
> > 
> > v4: - Place "single display to multiple displays scenario" MBUS/DBOX 
> > programming
> >   after DDB reallocation, but before crtc enabling(that is where is has
> >   to be according to spec).
> > - Check if crtc is still active, not only the old state.
> > - Do a vblank wait if MBUX DBOX register was modified.
> > - And of course do vblank wait only if crtc was active.
> > - Do vblank wait only if we are not doing a modeset, if we are doing
> >   something before *commit_modeset_enables, because all crtcs might be
> >   disabled at this moment, so we will get WARN if try waiting for vblank
> >   then.
> > - Still getting FIFO underrun so try waiting for vblank in pre_plane 
> > update
> >   as well.
> > - Write also pipe that we need to sync with to MBUS_CTL register.
> > 
> > v5: - Do vblank wait only for the first pipe, if mbus is joined
> > - Check also if new/old_dbuf_state is not NULL, before getting single 
> > pipe
> >   and active pipes.
> > 
> > Signed-off-by: Stanislav Lisovskiy 
> > ---
> >  drivers/gpu/drm/i915/display/intel_display.c |  13 ++-
> >  drivers/gpu/drm/i915/display/skl_watermark.c | 104 +++
> >  drivers/gpu/drm/i915/display/skl_watermark.h |   1 +
> >  3 files changed, 96 insertions(+), 22 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> > b/drivers/gpu/drm/i915/display/intel_display.c
> > index 00ac65a140298..989818f5d342f 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -6906,6 +6906,17 @@ static void skl_commit_modeset_enables(struct 
> > intel_atomic_state *state)
> > }
> > }
> >  
> > +   /*
> > +* Some MBUS/DBuf update scenarios(mbus join disable) require that
> > +* changes are done _after_ DDB reallocation, but _before_ crtc 
> > enabling.
> > +* Typically we are disabling resources in post_plane/crtc_enable hooks,
> > +* however in that case BSpec explicitly states that this should be done
> > +* before we enable additional displays.
> > +* FIXME: Should we still call this also there(post_plane hook)
> > +* for extra-safety? If so, how to make sure, we don't call it twice?
> > +*/
> > +   intel_dbuf_mbus_post_ddb_update(state);
> > +
> > update_pipes = modeset_pipes;
> >  
> > /*
> > @@ -7148,9 +7159,7 @@ 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 606b7ba9db9ce..f0604ede399f7 100644
> > --- a/drivers/gpu/drm/i915/display/skl_watermark.c
> > +++ b/drivers/gpu/drm/i915/display/skl_watermark.c
> > @@ -2628,13 +2628,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,
> > @@ -3539,8 +3532,9 @@ static 

Re: [PATCH 1/8] drm/i915: Rename the crtc/crtc_states in the top level DDI hooks/etc

2024-03-05 Thread Lisovskiy, Stanislav
On Tue, Mar 05, 2024 at 10:50:01AM +0200, Ville Syrjälä wrote:
> On Tue, Mar 05, 2024 at 10:41:49AM +0200, Lisovskiy, Stanislav wrote:
> > On Fri, Mar 01, 2024 at 04:35:53PM +0200, Ville Syrjala wrote:
> > > From: Ville Syrjälä 
> > > 
> > > In preparation for doing a more sensible pipe vs. transcoder
> > > handling for bigjoiner let's rename the crtc/crtc_state in the
> > > top level crtc_enable/disable and the DDI encoder hooks to
> > > include "master" in the name. This way they won't collide with
> > > the per-pipe stuff.
> > > 
> > > Note that at this point this is (at least partially) telling
> > > lies as we still run through some of these for slave pipes as
> > > well. But I wanted to get the huge rename out of the way so
> > > it won't clutter the functional patches so much.
> > > 
> > > TODO: or perhaps use some other names for the per-pipe stuff instead?
> > > 
> > > Signed-off-by: Ville Syrjälä 
> > 
> > I will then review now the patches which you could merge before the 
> > bigjoiner
> > stuff could be finished.
> 
> I just sent a separate series with the disable_pipes bitmask
> stuff.

I already reviewed all the patches, including that one, if there were
no changes, I guess you can apply that r-b there as well.

> 
> > Checked this patch I guess, you were also talking that this renaming might
> > be not the best idea.
> > I also wonder whether should we really emphasize things like 
> > "master"/"slave"
> > in function names. I thought that one idea in our refactoring was to unify
> > joined pipes handling so that there are no(or at least almost no) explicit 
> > code
> > paths/function names for masters/slaves.
> 
> There are no master vs. slave functions. The split is going to be
> transcoder/port vs. pipe.

In practice thats what you want to achieve, the functions which also include 
encoder
programming and/or handling joined pipes you wanted to add master in the name.

I think we should try to mention master/slave explicitly as less as possible.

Stan

> 
> -- 
> Ville Syrjälä
> Intel


Re: [PATCH 7/8] drm/i915: Simplify intel_old_crtc_state_disables() calling convention

2024-03-05 Thread Lisovskiy, Stanislav
On Fri, Mar 01, 2024 at 04:35:59PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> Stop passing in so much redundant stuff to
> intel_old_crtc_state_disables(). Top level atomic state + crtc
> is all we need.
> 
> Signed-off-by: Ville Syrjälä 

Reviewed-by: Stanislav Lisovskiy 

> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 18 +++---
>  1 file changed, 7 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> b/drivers/gpu/drm/i915/display/intel_display.c
> index 01d7e91cb1bc..1df3923cc30d 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -6753,11 +6753,11 @@ static void intel_update_crtc(struct 
> intel_atomic_state *state,
>  }
>  
>  static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
> -   struct intel_crtc_state 
> *old_crtc_state,
> -   struct intel_crtc_state 
> *new_crtc_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);
>  
>   /*
>* We need to disable pipe CRC before disabling the pipe,
> @@ -6776,7 +6776,7 @@ static void intel_old_crtc_state_disables(struct 
> intel_atomic_state *state,
>  static void intel_commit_modeset_disables(struct intel_atomic_state *state)
>  {
>   struct drm_i915_private *i915 = to_i915(state->base.dev);
> - struct intel_crtc_state *new_crtc_state, *old_crtc_state;
> + const struct intel_crtc_state *new_crtc_state, *old_crtc_state;
>   struct intel_crtc *crtc;
>   u8 disable_pipes = 0;
>   int i;
> @@ -6806,8 +6806,7 @@ static void intel_commit_modeset_disables(struct 
> intel_atomic_state *state)
>   }
>  
>   /* Only disable port sync and MST slaves */
> - for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
> - new_crtc_state, i) {
> + for_each_old_intel_crtc_in_state(state, crtc, old_crtc_state, i) {
>   if ((disable_pipes & BIT(crtc->pipe)) == 0)
>   continue;
>  
> @@ -6821,20 +6820,17 @@ static void intel_commit_modeset_disables(struct 
> intel_atomic_state *state)
>   !intel_crtc_is_bigjoiner_slave(old_crtc_state))
>   continue;
>  
> - intel_old_crtc_state_disables(state, old_crtc_state,
> -   new_crtc_state, crtc);
> + intel_old_crtc_state_disables(state, crtc);
>  
>   disable_pipes &= ~BIT(crtc->pipe);
>   }
>  
>   /* Disable everything else left on */
> - for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
> - new_crtc_state, i) {
> + for_each_old_intel_crtc_in_state(state, crtc, old_crtc_state, i) {
>   if ((disable_pipes & BIT(crtc->pipe)) == 0)
>   continue;
>  
> - intel_old_crtc_state_disables(state, old_crtc_state,
> -   new_crtc_state, crtc);
> + intel_old_crtc_state_disables(state, crtc);
>  
>   disable_pipes &= ~BIT(crtc->pipe);
>   }
> -- 
> 2.43.0
> 


Re: [PATCH 6/8] drm/i915: Disable planes more atomically during modesets

2024-03-05 Thread Lisovskiy, Stanislav
On Fri, Mar 01, 2024 at 04:35:58PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> Follow in the footsteps of commit c610e841f19d ("drm/i915:
> Do plane/etc. updates more atomically across pipes") and
> do the plane disables back to back for all pipes also when
> we are disabling pipes.
> 
> This should provide for a potentially more atomic user
> experience, which might be especially nice when using
> joiner or tiled displays.

Okay, so the difference is that previously we did call 
intel_pre_plane_update/intel_crtc_disable_planes per crtc, but
now we first call first intel_pre_plane_update for each crtc
and then call intel_crtc_disable_planes per crtc.

So in cases when there are some cross pipe dependencies, that might be
more proper way. Just to clarify that I understood this right.

Reviewed-by: Stanislav Lisovskiy 

> 
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 9 +++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> b/drivers/gpu/drm/i915/display/intel_display.c
> index 2351ee52d16e..01d7e91cb1bc 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -6795,11 +6795,16 @@ static void intel_commit_modeset_disables(struct 
> intel_atomic_state *state)
>   if (!old_crtc_state->hw.active)
>   continue;
>  
> - intel_crtc_disable_planes(state, crtc);
> -
>   disable_pipes |= BIT(crtc->pipe);
>   }
>  
> + for_each_old_intel_crtc_in_state(state, crtc, old_crtc_state, i) {
> + if ((disable_pipes & BIT(crtc->pipe)) == 0)
> + continue;
> +
> + intel_crtc_disable_planes(state, crtc);
> + }
> +
>   /* Only disable port sync and MST slaves */
>   for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
>   new_crtc_state, i) {
> -- 
> 2.43.0
> 


Re: [PATCH 5/8] drm/i915: Precompute disable_pipes bitmask in intel_commit_modeset_disables()

2024-03-05 Thread Lisovskiy, Stanislav
On Fri, Mar 01, 2024 at 04:35:57PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> Copy the pipe bitmask based approach skl_commit_modeset_enables()
> into intel_commit_modeset_disables(). This avoids doing so many
> duplicated checks in all the loops, and also let's us WARN at the
> end if we screwed up somewhere and forgot to disable some pipe.

Reviewed-by: Stanislav Lisovskiy 

> 
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 27 
>  1 file changed, 16 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> b/drivers/gpu/drm/i915/display/intel_display.c
> index 8cc5de31c1dd..2351ee52d16e 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -6775,9 +6775,10 @@ static void intel_old_crtc_state_disables(struct 
> intel_atomic_state *state,
>  
>  static void intel_commit_modeset_disables(struct intel_atomic_state *state)
>  {
> + struct drm_i915_private *i915 = to_i915(state->base.dev);
>   struct intel_crtc_state *new_crtc_state, *old_crtc_state;
>   struct intel_crtc *crtc;
> - u32 handled = 0;
> + u8 disable_pipes = 0;
>   int i;
>  
>   for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
> @@ -6785,21 +6786,24 @@ static void intel_commit_modeset_disables(struct 
> intel_atomic_state *state)
>   if (!intel_crtc_needs_modeset(new_crtc_state))
>   continue;
>  
> + /*
> +  * Needs to be done even for pipes
> +  * that weren't enabled previously.
> +  */
>   intel_pre_plane_update(state, crtc);
>  
>   if (!old_crtc_state->hw.active)
>   continue;
>  
>   intel_crtc_disable_planes(state, crtc);
> +
> + disable_pipes |= BIT(crtc->pipe);
>   }
>  
>   /* Only disable port sync and MST slaves */
>   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 (!old_crtc_state->hw.active)
> + if ((disable_pipes & BIT(crtc->pipe)) == 0)
>   continue;
>  
>   /* In case of Transcoder port Sync master slave CRTCs can be
> @@ -6814,22 +6818,23 @@ static void intel_commit_modeset_disables(struct 
> intel_atomic_state *state)
>  
>   intel_old_crtc_state_disables(state, old_crtc_state,
> new_crtc_state, crtc);
> - handled |= BIT(crtc->pipe);
> +
> + disable_pipes &= ~BIT(crtc->pipe);
>   }
>  
>   /* Disable everything else left on */
>   for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
>   new_crtc_state, i) {
> - if (!intel_crtc_needs_modeset(new_crtc_state) ||
> - (handled & BIT(crtc->pipe)))
> - continue;
> -
> - if (!old_crtc_state->hw.active)
> + if ((disable_pipes & BIT(crtc->pipe)) == 0)
>   continue;
>  
>   intel_old_crtc_state_disables(state, old_crtc_state,
> new_crtc_state, crtc);
> +
> + disable_pipes &= ~BIT(crtc->pipe);
>   }
> +
> + drm_WARN_ON(>drm, disable_pipes);
>  }
>  
>  static void intel_commit_modeset_enables(struct intel_atomic_state *state)
> -- 
> 2.43.0
> 


Re: [PATCH 3/8] drm/i915: Extract intel_ddi_post_disable_hdmi_or_sst()

2024-03-05 Thread Lisovskiy, Stanislav
On Fri, Mar 01, 2024 at 04:35:55PM +0200, Ville Syrjala wrote:
> 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.

Had same idea. Was really wondering why we handle it that way here.
But I guess for MST case, we need to add similar handling then?

Reviewed-by: Stanislav Lisovskiy 

> 
> 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 0e5834f8af6e..f3f8ecf1a87e 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -3095,28 +3095,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_master_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_master_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_master_crtc_state, INTEL_OUTPUT_DP_MST)) {
> - intel_crtc_vblank_off(old_master_crtc_state);
> + intel_crtc_vblank_off(old_master_crtc_state);
>  
> - intel_disable_transcoder(old_master_crtc_state);
> + intel_disable_transcoder(old_master_crtc_state);
>  
> - intel_ddi_disable_transcoder_func(old_master_crtc_state);
> + intel_ddi_disable_transcoder_func(old_master_crtc_state);
>  
> - intel_dsc_disable(old_master_crtc_state);
> + intel_dsc_disable(old_master_crtc_state);
>  
> - if (DISPLAY_VER(dev_priv) >= 9)
> - skl_scaler_disable(old_master_crtc_state);
> - else
> - ilk_pfit_disable(old_master_crtc_state);
> - }
> + if (DISPLAY_VER(dev_priv) >= 9)
> + skl_scaler_disable(old_master_crtc_state);
> + else
> + ilk_pfit_disable(old_master_crtc_state);
>  
>   for_each_intel_crtc_in_pipe_mask(_priv->drm, slave_crtc,
>
> intel_crtc_bigjoiner_slave_pipes(old_master_crtc_state)) {
> @@ -3128,6 +3126,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_master_crtc_state,
> +const struct drm_connector_state 
> *old_conn_state)
> +{
> + if (!intel_crtc_has_type(old_master_crtc_state, INTEL_OUTPUT_DP_MST))
> + intel_ddi_post_disable_hdmi_or_sst(state, encoder,
> +old_master_crtc_state, 
> old_conn_state);
>  
>   /*
>* When called from DP MST code:
> -- 
> 2.43.0
> 


Re: [PATCH 1/8] drm/i915: Rename the crtc/crtc_states in the top level DDI hooks/etc

2024-03-05 Thread Lisovskiy, Stanislav
On Fri, Mar 01, 2024 at 04:35:53PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> In preparation for doing a more sensible pipe vs. transcoder
> handling for bigjoiner let's rename the crtc/crtc_state in the
> top level crtc_enable/disable and the DDI encoder hooks to
> include "master" in the name. This way they won't collide with
> the per-pipe stuff.
> 
> Note that at this point this is (at least partially) telling
> lies as we still run through some of these for slave pipes as
> well. But I wanted to get the huge rename out of the way so
> it won't clutter the functional patches so much.
> 
> TODO: or perhaps use some other names for the per-pipe stuff instead?
> 
> Signed-off-by: Ville Syrjälä 

I will then review now the patches which you could merge before the bigjoiner
stuff could be finished.
Checked this patch I guess, you were also talking that this renaming might
be not the best idea.
I also wonder whether should we really emphasize things like "master"/"slave"
in function names. I thought that one idea in our refactoring was to unify
joined pipes handling so that there are no(or at least almost no) explicit code
paths/function names for masters/slaves.

Stan

> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c | 326 +--
>  drivers/gpu/drm/i915/display/intel_display.c | 100 +++---
>  drivers/gpu/drm/i915/display/intel_dp_mst.c  |  91 +++---
>  3 files changed, 258 insertions(+), 259 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
> b/drivers/gpu/drm/i915/display/intel_ddi.c
> index c587a8efeafc..6287629f9e77 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -2490,21 +2490,21 @@ static void mtl_port_buf_ctl_io_selection(struct 
> intel_encoder *encoder)
>  
>  static void mtl_ddi_pre_enable_dp(struct intel_atomic_state *state,
> struct intel_encoder *encoder,
> -   const struct intel_crtc_state *crtc_state,
> +   const struct intel_crtc_state 
> *master_crtc_state,
> const struct drm_connector_state *conn_state)
>  {
>   struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> - bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST);
> + bool is_mst = intel_crtc_has_type(master_crtc_state, 
> INTEL_OUTPUT_DP_MST);
>  
>   intel_dp_set_link_params(intel_dp,
> -  crtc_state->port_clock,
> -  crtc_state->lane_count);
> +  master_crtc_state->port_clock,
> +  master_crtc_state->lane_count);
>  
>   /*
>* We only configure what the register value will be here.  Actual
>* enabling happens during link training farther down.
>*/
> - intel_ddi_init_dp_buf_reg(encoder, crtc_state);
> + intel_ddi_init_dp_buf_reg(encoder, master_crtc_state);
>  
>   /*
>* 1. Enable Power Wells
> @@ -2522,48 +2522,48 @@ static void mtl_ddi_pre_enable_dp(struct 
> intel_atomic_state *state,
>   intel_pps_on(intel_dp);
>  
>   /* 5. Enable the port PLL */
> - intel_ddi_enable_clock(encoder, crtc_state);
> + intel_ddi_enable_clock(encoder, master_crtc_state);
>  
>   /*
>* 6.a Configure Transcoder Clock Select to direct the Port clock to the
>* Transcoder.
>*/
> - intel_ddi_enable_transcoder_clock(encoder, crtc_state);
> + intel_ddi_enable_transcoder_clock(encoder, master_crtc_state);
>  
>   /*
>* 6.b If DP v2.0/128b mode - Configure TRANS_DP2_CTL register settings.
>*/
> - intel_ddi_config_transcoder_dp2(encoder, crtc_state);
> + intel_ddi_config_transcoder_dp2(encoder, master_crtc_state);
>  
>   /*
>* 6.c Configure TRANS_DDI_FUNC_CTL DDI Select, DDI Mode Select & MST
>* Transport Select
>*/
> - intel_ddi_config_transcoder_func(encoder, crtc_state);
> + intel_ddi_config_transcoder_func(encoder, master_crtc_state);
>  
>   /*
>* 6.e Program CoG/MSO configuration bits in DSS_CTL1 if selected.
>*/
> - intel_ddi_mso_configure(crtc_state);
> + intel_ddi_mso_configure(master_crtc_state);
>  
>   if (!is_mst)
>   intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
>  
> - intel_dp_configure_protocol_converter(intel_dp, crtc_state);
> + intel_dp_configure_protocol_converter(intel_dp, master_crtc_state);
>   if (!is_mst)
>   intel_dp_sink_enable_decompression(state,
>  
> to_intel_connector(conn_state->connector),
> -crtc_state);
> +master_crtc_state);
>  
>   /*
>* DDI FEC: "anticipates enabling FEC encoding sets the FEC_READY bit
>* in the FEC_CONFIGURATION register to 1 before 

Re: [PATCH v2 8/8] drm/i915: Handle joined pipes inside hsw_crtc_disable()

2024-03-04 Thread Lisovskiy, Stanislav
On Mon, Mar 04, 2024 at 08:44:35AM +0200, Srinivas, Vidya wrote:
> Thank you very much Ville and Stan.
> With https://patchwork.freedesktop.org/series/130619/ and 
> https://patchwork.freedesktop.org/series/130449/ tested that 6K works
> Tested-by: Vidya Srinivas 

The thing is that we still don't handle crtc enable(i.e actual enabling of 
displays)
here at all, only disabling part. So fact that it works could be also related 
to this.

Ville, should I use your series, plus the things we had discussed in my series 
to implement
hsw_crtc_enable on top of your series?
Of course things related to transcoder have to be clarified still. 
Or do you plan to do it yourself?

Stan

> 
> > -Original Message-
> > From: Intel-gfx  On Behalf Of Ville
> > Syrjala
> > Sent: Friday, March 1, 2024 10:54 PM
> > To: intel-gfx@lists.freedesktop.org
> > Cc: Lisovskiy, Stanislav 
> > Subject: [PATCH v2 8/8] drm/i915: Handle joined pipes inside
> > hsw_crtc_disable()
> > 
> > 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: Pass the correct crtc pointer to .crtc_disable()
> > 
> > Signed-off-by: Ville Syrjälä 
> > ---
> >  drivers/gpu/drm/i915/display/intel_display.c | 66 
> >  1 file changed, 39 insertions(+), 27 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> > b/drivers/gpu/drm/i915/display/intel_display.c
> > index 1df3923cc30d..e01536983303 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -1793,29 +1793,27 @@ static void hsw_crtc_disable(struct
> > intel_atomic_state *state,
> > const struct intel_crtc_state *old_master_crtc_state =
> > intel_atomic_get_old_crtc_state(state, master_crtc);
> > struct drm_i915_private *i915 = to_i915(master_crtc->base.dev);
> > +   u8 pipe_mask = intel_crtc_joined_pipe_mask(old_master_crtc_state);
> > +   struct intel_crtc *crtc;
> > 
> > /*
> >  * FIXME collapse everything to one hook.
> >  * Need care with mst->ddi interactions.
> >  */
> > -   if (!intel_crtc_is_bigjoiner_slave(old_master_crtc_state)) {
> > -   intel_encoders_disable(state, master_crtc);
> > -   intel_encoders_post_disable(state, master_crtc);
> > -   }
> > -
> > -   intel_disable_shared_dpll(old_master_crtc_state);
> > +   intel_encoders_disable(state, master_crtc);
> > +   intel_encoders_post_disable(state, master_crtc);
> > 
> > -   if (!intel_crtc_is_bigjoiner_slave(old_master_crtc_state)) {
> > -   struct intel_crtc *slave_crtc;
> > +   for_each_intel_crtc_in_pipe_mask(>drm, crtc, pipe_mask) {
> > +   const struct intel_crtc_state *old_crtc_state =
> > +   intel_atomic_get_old_crtc_state(state, crtc);
> > 
> > -   intel_encoders_post_pll_disable(state, master_crtc);
> > +   intel_disable_shared_dpll(old_crtc_state);
> > +   }
> > 
> > -   intel_dmc_disable_pipe(i915, master_crtc->pipe);
> > +   intel_encoders_post_pll_disable(state, master_crtc);
> > 
> > -   for_each_intel_crtc_in_pipe_mask(>drm, slave_crtc,
> > -
> > intel_crtc_bigjoiner_slave_pipes(old_master_crtc_state))
> > -   intel_dmc_disable_pipe(i915, slave_crtc->pipe);
> > -   }
> > +   for_each_intel_crtc_in_pipe_mask(>drm, crtc, pipe_mask)
> > +   intel_dmc_disable_pipe(i915, crtc->pipe);
> >  }
> > 
> >  static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state) @@ 
> > -
> > 6753,24 +6751,33 @@ static void intel_update_crtc(struct intel_atomic_state
> > *state,  }
> > 
> >  static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
> > - struct intel_crtc *crtc)
> > + struct intel_crtc *master_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_master_crtc_state =
> > +   

Re: [PATCH 8/8] drm/i915: Handle joined pipes inside hsw_crtc_disable()

2024-03-04 Thread Lisovskiy, Stanislav
On Fri, Mar 01, 2024 at 06:47:54PM +0200, Ville Syrjälä wrote:
> On Fri, Mar 01, 2024 at 06:22:19PM +0200, Lisovskiy, Stanislav wrote:
> > On Fri, Mar 01, 2024 at 06:10:25PM +0200, Ville Syrjälä wrote:
> > > On Fri, Mar 01, 2024 at 06:04:27PM +0200, Lisovskiy, Stanislav wrote:
> > > > On Fri, Mar 01, 2024 at 04:36:00PM +0200, Ville Syrjala wrote:
> > > > > 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.
> > > > > 
> > > > > Signed-off-by: Ville Syrjälä 
> > > > > ---
> > > > >  drivers/gpu/drm/i915/display/intel_display.c | 64 
> > > > > 
> > > > >  1 file changed, 38 insertions(+), 26 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> > > > > b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > index 1df3923cc30d..07239c1ce9df 100644
> > > > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > > > @@ -1793,29 +1793,27 @@ static void hsw_crtc_disable(struct 
> > > > > intel_atomic_state *state,
> > > > >   const struct intel_crtc_state *old_master_crtc_state =
> > > > >   intel_atomic_get_old_crtc_state(state, master_crtc);
> > > > >   struct drm_i915_private *i915 = to_i915(master_crtc->base.dev);
> > > > > + u8 pipe_mask = 
> > > > > intel_crtc_joined_pipe_mask(old_master_crtc_state);
> > > > > + struct intel_crtc *crtc;
> > > > >  
> > > > >   /*
> > > > >* FIXME collapse everything to one hook.
> > > > >* Need care with mst->ddi interactions.
> > > > >*/
> > > > > - if (!intel_crtc_is_bigjoiner_slave(old_master_crtc_state)) {
> > > > > - intel_encoders_disable(state, master_crtc);
> > > > > - intel_encoders_post_disable(state, master_crtc);
> > > > > - }
> > > > > -
> > > > > - intel_disable_shared_dpll(old_master_crtc_state);
> > > > > + intel_encoders_disable(state, master_crtc);
> > > > > + intel_encoders_post_disable(state, master_crtc);
> > > > >  
> > > > > - if (!intel_crtc_is_bigjoiner_slave(old_master_crtc_state)) {
> > > > > - struct intel_crtc *slave_crtc;
> > > > > + for_each_intel_crtc_in_pipe_mask(>drm, crtc, pipe_mask) {
> > > > > + const struct intel_crtc_state *old_crtc_state =
> > > > > + intel_atomic_get_old_crtc_state(state, crtc);
> > > > >  
> > > > > - intel_encoders_post_pll_disable(state, master_crtc);
> > > > > + intel_disable_shared_dpll(old_crtc_state);
> > > > > + }
> > > > >  
> > > > > - intel_dmc_disable_pipe(i915, master_crtc->pipe);
> > > > > + intel_encoders_post_pll_disable(state, master_crtc);
> > > > >  
> > > > > - for_each_intel_crtc_in_pipe_mask(>drm, slave_crtc,
> > > > > -  
> > > > > intel_crtc_bigjoiner_slave_pipes(old_master_crtc_state))
> > > > > - intel_dmc_disable_pipe(i915, slave_crtc->pipe);
> > > > > - }
> > > > > + for_each_intel_crtc_in_pipe_mask(>drm, crtc, pipe_mask)
> > > > > + intel_dmc_disable_pipe(i915, crtc->pipe);
> > > > >  }
> > > > 
> > > > Okay the only difference from hsw_crtc_disable part from my patch is 
> > > > that
> > > > I don't have intel_crtc_joined_pipe_mask and encoder calls are outside 
> > > > the pipe
> > > > loop. Ok. You could of course just communicate this to me, it is quite 
> > > > a small
> > > > thing to change.
> > > > 
> > > 

Re: [PATCH 8/8] drm/i915: Handle joined pipes inside hsw_crtc_disable()

2024-03-01 Thread Lisovskiy, Stanislav
On Fri, Mar 01, 2024 at 06:10:25PM +0200, Ville Syrjälä wrote:
> On Fri, Mar 01, 2024 at 06:04:27PM +0200, Lisovskiy, Stanislav wrote:
> > On Fri, Mar 01, 2024 at 04:36:00PM +0200, Ville Syrjala wrote:
> > > 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.
> > > 
> > > Signed-off-by: Ville Syrjälä 
> > > ---
> > >  drivers/gpu/drm/i915/display/intel_display.c | 64 
> > >  1 file changed, 38 insertions(+), 26 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> > > b/drivers/gpu/drm/i915/display/intel_display.c
> > > index 1df3923cc30d..07239c1ce9df 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > @@ -1793,29 +1793,27 @@ static void hsw_crtc_disable(struct 
> > > intel_atomic_state *state,
> > >   const struct intel_crtc_state *old_master_crtc_state =
> > >   intel_atomic_get_old_crtc_state(state, master_crtc);
> > >   struct drm_i915_private *i915 = to_i915(master_crtc->base.dev);
> > > + u8 pipe_mask = intel_crtc_joined_pipe_mask(old_master_crtc_state);
> > > + struct intel_crtc *crtc;
> > >  
> > >   /*
> > >* FIXME collapse everything to one hook.
> > >* Need care with mst->ddi interactions.
> > >*/
> > > - if (!intel_crtc_is_bigjoiner_slave(old_master_crtc_state)) {
> > > - intel_encoders_disable(state, master_crtc);
> > > - intel_encoders_post_disable(state, master_crtc);
> > > - }
> > > -
> > > - intel_disable_shared_dpll(old_master_crtc_state);
> > > + intel_encoders_disable(state, master_crtc);
> > > + intel_encoders_post_disable(state, master_crtc);
> > >  
> > > - if (!intel_crtc_is_bigjoiner_slave(old_master_crtc_state)) {
> > > - struct intel_crtc *slave_crtc;
> > > + for_each_intel_crtc_in_pipe_mask(>drm, crtc, pipe_mask) {
> > > + const struct intel_crtc_state *old_crtc_state =
> > > + intel_atomic_get_old_crtc_state(state, crtc);
> > >  
> > > - intel_encoders_post_pll_disable(state, master_crtc);
> > > + intel_disable_shared_dpll(old_crtc_state);
> > > + }
> > >  
> > > - intel_dmc_disable_pipe(i915, master_crtc->pipe);
> > > + intel_encoders_post_pll_disable(state, master_crtc);
> > >  
> > > - for_each_intel_crtc_in_pipe_mask(>drm, slave_crtc,
> > > -  
> > > intel_crtc_bigjoiner_slave_pipes(old_master_crtc_state))
> > > - intel_dmc_disable_pipe(i915, slave_crtc->pipe);
> > > - }
> > > + for_each_intel_crtc_in_pipe_mask(>drm, crtc, pipe_mask)
> > > + intel_dmc_disable_pipe(i915, crtc->pipe);
> > >  }
> > 
> > Okay the only difference from hsw_crtc_disable part from my patch is that
> > I don't have intel_crtc_joined_pipe_mask and encoder calls are outside the 
> > pipe
> > loop. Ok. You could of course just communicate this to me, it is quite a 
> > small
> > thing to change.
> > 
> > And still there is a question about how to handle the crtc enable side, 
> > since
> > extracting transcoder programming from the pipe loop, will break the 
> > sequence,
> > as I described. Either it is ok that we will partly program slave/master 
> > pipe, then
> > program transcoder then again program slave/master pipes or it has to be
> > in a pipe loop.
> 
> Transcoder stuff shouldn't be in pipe loops. That's what
> I've been saying all along.

Yep, I realize you kept saying this and I described you the problem what 
happens if 
we extract it from there.
Either it is ok to have 2 loops and have transcoder programming in between or 
you
first program pipes then program the transcoder - in both cases that would 
change
the sequence of how it is done now.
My question was if this is ok or not.

Stan

> 
> -- 
> Ville Syrjälä
> Intel


Re: [PATCH 8/8] drm/i915: Handle joined pipes inside hsw_crtc_disable()

2024-03-01 Thread Lisovskiy, Stanislav
On Fri, Mar 01, 2024 at 04:36:00PM +0200, Ville Syrjala wrote:
> 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.
> 
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 64 
>  1 file changed, 38 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> b/drivers/gpu/drm/i915/display/intel_display.c
> index 1df3923cc30d..07239c1ce9df 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -1793,29 +1793,27 @@ static void hsw_crtc_disable(struct 
> intel_atomic_state *state,
>   const struct intel_crtc_state *old_master_crtc_state =
>   intel_atomic_get_old_crtc_state(state, master_crtc);
>   struct drm_i915_private *i915 = to_i915(master_crtc->base.dev);
> + u8 pipe_mask = intel_crtc_joined_pipe_mask(old_master_crtc_state);
> + struct intel_crtc *crtc;
>  
>   /*
>* FIXME collapse everything to one hook.
>* Need care with mst->ddi interactions.
>*/
> - if (!intel_crtc_is_bigjoiner_slave(old_master_crtc_state)) {
> - intel_encoders_disable(state, master_crtc);
> - intel_encoders_post_disable(state, master_crtc);
> - }
> -
> - intel_disable_shared_dpll(old_master_crtc_state);
> + intel_encoders_disable(state, master_crtc);
> + intel_encoders_post_disable(state, master_crtc);
>  
> - if (!intel_crtc_is_bigjoiner_slave(old_master_crtc_state)) {
> - struct intel_crtc *slave_crtc;
> + for_each_intel_crtc_in_pipe_mask(>drm, crtc, pipe_mask) {
> + const struct intel_crtc_state *old_crtc_state =
> + intel_atomic_get_old_crtc_state(state, crtc);
>  
> - intel_encoders_post_pll_disable(state, master_crtc);
> + intel_disable_shared_dpll(old_crtc_state);
> + }
>  
> - intel_dmc_disable_pipe(i915, master_crtc->pipe);
> + intel_encoders_post_pll_disable(state, master_crtc);
>  
> - for_each_intel_crtc_in_pipe_mask(>drm, slave_crtc,
> -  
> intel_crtc_bigjoiner_slave_pipes(old_master_crtc_state))
> - intel_dmc_disable_pipe(i915, slave_crtc->pipe);
> - }
> + for_each_intel_crtc_in_pipe_mask(>drm, crtc, pipe_mask)
> + intel_dmc_disable_pipe(i915, crtc->pipe);
>  }
>  
>  static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state)
> @@ -6753,24 +6751,33 @@ static void intel_update_crtc(struct 
> intel_atomic_state *state,
>  }
>  
>  static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
> -   struct intel_crtc *crtc)
> +   struct intel_crtc *master_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_master_crtc_state =
> + intel_atomic_get_old_crtc_state(state, master_crtc);
> + u8 pipe_mask = intel_crtc_joined_pipe_mask(old_master_crtc_state);
> + struct intel_crtc *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, crtc, pipe_mask)
> + intel_crtc_disable_pipe_crc(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, crtc, pipe_mask) {
> + const struct intel_crtc_state *new_crtc_state =
> + intel_atomic_get_new_crtc_state(state, crtc);
> +
> + crtc->active = false;
> + intel_fbc_disable(crtc);
> +
> + if (!new_crtc_state->hw.active)
> + intel_initial_watermarks(state, crtc);
> + }
>  }
>  
>  static void intel_commit_modeset_disables(struct intel_atomic_state *state)
> @@ -6810,19 +6817,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
> 

Re: [PATCH 8/8] drm/i915: Handle joined pipes inside hsw_crtc_disable()

2024-03-01 Thread Lisovskiy, Stanislav
On Fri, Mar 01, 2024 at 04:36:00PM +0200, Ville Syrjala wrote:
> 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.
> 
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 64 
>  1 file changed, 38 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> b/drivers/gpu/drm/i915/display/intel_display.c
> index 1df3923cc30d..07239c1ce9df 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -1793,29 +1793,27 @@ static void hsw_crtc_disable(struct 
> intel_atomic_state *state,
>   const struct intel_crtc_state *old_master_crtc_state =
>   intel_atomic_get_old_crtc_state(state, master_crtc);
>   struct drm_i915_private *i915 = to_i915(master_crtc->base.dev);
> + u8 pipe_mask = intel_crtc_joined_pipe_mask(old_master_crtc_state);
> + struct intel_crtc *crtc;
>  
>   /*
>* FIXME collapse everything to one hook.
>* Need care with mst->ddi interactions.
>*/
> - if (!intel_crtc_is_bigjoiner_slave(old_master_crtc_state)) {
> - intel_encoders_disable(state, master_crtc);
> - intel_encoders_post_disable(state, master_crtc);
> - }
> -
> - intel_disable_shared_dpll(old_master_crtc_state);
> + intel_encoders_disable(state, master_crtc);
> + intel_encoders_post_disable(state, master_crtc);
>  
> - if (!intel_crtc_is_bigjoiner_slave(old_master_crtc_state)) {
> - struct intel_crtc *slave_crtc;
> + for_each_intel_crtc_in_pipe_mask(>drm, crtc, pipe_mask) {
> + const struct intel_crtc_state *old_crtc_state =
> + intel_atomic_get_old_crtc_state(state, crtc);
>  
> - intel_encoders_post_pll_disable(state, master_crtc);
> + intel_disable_shared_dpll(old_crtc_state);
> + }
>  
> - intel_dmc_disable_pipe(i915, master_crtc->pipe);
> + intel_encoders_post_pll_disable(state, master_crtc);
>  
> - for_each_intel_crtc_in_pipe_mask(>drm, slave_crtc,
> -  
> intel_crtc_bigjoiner_slave_pipes(old_master_crtc_state))
> - intel_dmc_disable_pipe(i915, slave_crtc->pipe);
> - }
> + for_each_intel_crtc_in_pipe_mask(>drm, crtc, pipe_mask)
> + intel_dmc_disable_pipe(i915, crtc->pipe);
>  }

Okay the only difference from hsw_crtc_disable part from my patch is that
I don't have intel_crtc_joined_pipe_mask and encoder calls are outside the pipe
loop. Ok. You could of course just communicate this to me, it is quite a small
thing to change.

And still there is a question about how to handle the crtc enable side, since
extracting transcoder programming from the pipe loop, will break the sequence,
as I described. Either it is ok that we will partly program slave/master pipe, 
then
program transcoder then again program slave/master pipes or it has to be
in a pipe loop.

Stan

>  
>  static void i9xx_pfit_enable(const struct intel_crtc_state *crtc_state)
> @@ -6753,24 +6751,33 @@ static void intel_update_crtc(struct 
> intel_atomic_state *state,
>  }
>  
>  static void intel_old_crtc_state_disables(struct intel_atomic_state *state,
> -   struct intel_crtc *crtc)
> +   struct intel_crtc *master_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_master_crtc_state =
> + intel_atomic_get_old_crtc_state(state, master_crtc);
> + u8 pipe_mask = intel_crtc_joined_pipe_mask(old_master_crtc_state);
> + struct intel_crtc *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, crtc, pipe_mask)
> + intel_crtc_disable_pipe_crc(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, crtc, pipe_mask) {
> + const struct intel_crtc_state *new_crtc_state =
> + intel_atomic_get_new_crtc_state(state, crtc);
> +
> + crtc->active = false;
> + intel_fbc_disable(crtc);
> +
> +   

Re: [PATCH 2/3] Start separating pipe vs transcoder set logic for bigjoiner during modeset

2024-03-01 Thread Lisovskiy, Stanislav
On Fri, Mar 01, 2024 at 05:26:19PM +0200, Ville Syrjälä wrote:
> On Fri, Mar 01, 2024 at 05:17:41PM +0200, Lisovskiy, Stanislav wrote:
> > On Fri, Mar 01, 2024 at 04:40:28PM +0200, Ville Syrjälä wrote:
> > > On Fri, Mar 01, 2024 at 02:29:28PM +0200, Lisovskiy, Stanislav wrote:
> > > > On Fri, Mar 01, 2024 at 12:43:46PM +0200, Ville Syrjälä wrote:
> > > > > On Fri, Mar 01, 2024 at 12:27:18PM +0200, Lisovskiy, Stanislav wrote:
> > > > > > On Fri, Mar 01, 2024 at 12:10:52PM +0200, Ville Syrjälä wrote:
> > > > > > > On Wed, Feb 21, 2024 at 09:20:09PM +0200, Stanislav Lisovskiy 
> > > > > > > wrote:
> > > > > > > > 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: Get rid of master vs slave checks and separation in crtc 
> > > > > > > > enable/disable hooks.
> > > > > > > > Use unified iteration cycle for all of those, while 
> > > > > > > > enabling/disabling
> > > > > > > > transcoder only for those pipes where its needed(Ville 
> > > > > > > > Syrjälä)
> > > > > > > > 
> > > > > > > > v3: Move all the intel_encoder_* calls under transcoder code 
> > > > > > > > path(Ville Syrjälä)
> > > > > > > > 
> > > > > > > > v4:  - Call intel_crtc_vblank_on from hsw_crtc_enable only for 
> > > > > > > > non-transcoder path
> > > > > > > >(for master pipe that will be called from 
> > > > > > > > intel_encoders_enable/intel_enable_ddi)
> > > > > > > >  - Fix stupid mistake with using crtc->pipe for the mask, 
> > > > > > > > instead of BIT(crtc->pipe)
> > > > > > > > 
> > > > > > > > Signed-off-by: Stanislav Lisovskiy 
> > > > > > > > 
> > > > > > > > ---
> > > > > > > >  drivers/gpu/drm/i915/display/intel_ddi.c |  21 +--
> > > > > > > >  drivers/gpu/drm/i915/display/intel_display.c | 183 
> > > > > > > > ---
> > > > > > > >  drivers/gpu/drm/i915/display/intel_display.h |   6 +
> > > > > > > >  3 files changed, 121 insertions(+), 89 deletions(-)
> > > > > > > > 
> > > > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
> > > > > > > > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > > > index bea4415902044..6071e9f500871 100644
> > > > > > > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > > > @@ -3100,7 +3100,6 @@ static void intel_ddi_post_disable(struct 
> > > > > > > > intel_atomic_state *state,
> > > > > > > >const struct 
> > > > > > > > drm_connector_state *old_conn_state)
> > > > > > > >  {
> > > > > > > > struct drm_i915_private *dev_priv = 
> > > > > > > > to_i915(encoder->base.dev);
> > > > > > > > -   struct intel_crtc *slave_crtc;
> > > > > > > >  
> > > > > > > > if (!intel_crtc_has_type(old_crtc_state, 
> > > > > > > > INTEL_OUTPUT_DP_MST)) {
> > > > > > > > intel_crtc_vblank_off(old_crtc_state);
> > > > > > > > @@ -3117,17 +3116,6 @@ static void 
> > > > > > > > intel_ddi_post_disable(struct intel_atomic_state *state,
> > > > > > > > ilk_pfit_disable(old_crtc_state);
> > > > > > > > }
> > > > > > > 
> > > > > > > The master pipe stuff is right here ^ ...
> > > > > > > 
> > > > > > > >  
> > > > > > &

Re: [PATCH 2/3] Start separating pipe vs transcoder set logic for bigjoiner during modeset

2024-03-01 Thread Lisovskiy, Stanislav
On Fri, Mar 01, 2024 at 04:40:28PM +0200, Ville Syrjälä wrote:
> On Fri, Mar 01, 2024 at 02:29:28PM +0200, Lisovskiy, Stanislav wrote:
> > On Fri, Mar 01, 2024 at 12:43:46PM +0200, Ville Syrjälä wrote:
> > > On Fri, Mar 01, 2024 at 12:27:18PM +0200, Lisovskiy, Stanislav wrote:
> > > > On Fri, Mar 01, 2024 at 12:10:52PM +0200, Ville Syrjälä wrote:
> > > > > On Wed, Feb 21, 2024 at 09:20:09PM +0200, Stanislav Lisovskiy wrote:
> > > > > > 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: Get rid of master vs slave checks and separation in crtc 
> > > > > > enable/disable hooks.
> > > > > > Use unified iteration cycle for all of those, while 
> > > > > > enabling/disabling
> > > > > > transcoder only for those pipes where its needed(Ville Syrjälä)
> > > > > > 
> > > > > > v3: Move all the intel_encoder_* calls under transcoder code 
> > > > > > path(Ville Syrjälä)
> > > > > > 
> > > > > > v4:  - Call intel_crtc_vblank_on from hsw_crtc_enable only for 
> > > > > > non-transcoder path
> > > > > >(for master pipe that will be called from 
> > > > > > intel_encoders_enable/intel_enable_ddi)
> > > > > >  - Fix stupid mistake with using crtc->pipe for the mask, 
> > > > > > instead of BIT(crtc->pipe)
> > > > > > 
> > > > > > Signed-off-by: Stanislav Lisovskiy 
> > > > > > ---
> > > > > >  drivers/gpu/drm/i915/display/intel_ddi.c |  21 +--
> > > > > >  drivers/gpu/drm/i915/display/intel_display.c | 183 
> > > > > > ---
> > > > > >  drivers/gpu/drm/i915/display/intel_display.h |   6 +
> > > > > >  3 files changed, 121 insertions(+), 89 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
> > > > > > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > index bea4415902044..6071e9f500871 100644
> > > > > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > > > @@ -3100,7 +3100,6 @@ static void intel_ddi_post_disable(struct 
> > > > > > intel_atomic_state *state,
> > > > > >const struct drm_connector_state 
> > > > > > *old_conn_state)
> > > > > >  {
> > > > > > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> > > > > > -   struct intel_crtc *slave_crtc;
> > > > > >  
> > > > > > if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST)) {
> > > > > > intel_crtc_vblank_off(old_crtc_state);
> > > > > > @@ -3117,17 +3116,6 @@ static void intel_ddi_post_disable(struct 
> > > > > > intel_atomic_state *state,
> > > > > > ilk_pfit_disable(old_crtc_state);
> > > > > > }
> > > > > 
> > > > > The master pipe stuff is right here ^ ...
> > > > > 
> > > > > >  
> > > > > > -   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);
> > > > > > -   }
> > > > > 
> > > > > .. but now you're moving the slave pipe stuff somewhere else?
> > > > > 
> > > > > We should be just itera

Re: [PATCH 2/3] Start separating pipe vs transcoder set logic for bigjoiner during modeset

2024-03-01 Thread Lisovskiy, Stanislav
On Fri, Mar 01, 2024 at 12:43:46PM +0200, Ville Syrjälä wrote:
> On Fri, Mar 01, 2024 at 12:27:18PM +0200, Lisovskiy, Stanislav wrote:
> > On Fri, Mar 01, 2024 at 12:10:52PM +0200, Ville Syrjälä wrote:
> > > On Wed, Feb 21, 2024 at 09:20:09PM +0200, Stanislav Lisovskiy wrote:
> > > > 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: Get rid of master vs slave checks and separation in crtc 
> > > > enable/disable hooks.
> > > > Use unified iteration cycle for all of those, while 
> > > > enabling/disabling
> > > > transcoder only for those pipes where its needed(Ville Syrjälä)
> > > > 
> > > > v3: Move all the intel_encoder_* calls under transcoder code path(Ville 
> > > > Syrjälä)
> > > > 
> > > > v4:  - Call intel_crtc_vblank_on from hsw_crtc_enable only for 
> > > > non-transcoder path
> > > >(for master pipe that will be called from 
> > > > intel_encoders_enable/intel_enable_ddi)
> > > >  - Fix stupid mistake with using crtc->pipe for the mask, instead 
> > > > of BIT(crtc->pipe)
> > > > 
> > > > Signed-off-by: Stanislav Lisovskiy 
> > > > ---
> > > >  drivers/gpu/drm/i915/display/intel_ddi.c |  21 +--
> > > >  drivers/gpu/drm/i915/display/intel_display.c | 183 ---
> > > >  drivers/gpu/drm/i915/display/intel_display.h |   6 +
> > > >  3 files changed, 121 insertions(+), 89 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
> > > > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > index bea4415902044..6071e9f500871 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > > > @@ -3100,7 +3100,6 @@ static void intel_ddi_post_disable(struct 
> > > > intel_atomic_state *state,
> > > >const struct drm_connector_state 
> > > > *old_conn_state)
> > > >  {
> > > > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> > > > -   struct intel_crtc *slave_crtc;
> > > >  
> > > > if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST)) {
> > > > intel_crtc_vblank_off(old_crtc_state);
> > > > @@ -3117,17 +3116,6 @@ static void intel_ddi_post_disable(struct 
> > > > intel_atomic_state *state,
> > > > ilk_pfit_disable(old_crtc_state);
> > > > }
> > > 
> > > The master pipe stuff is right here ^ ...
> > > 
> > > >  
> > > > -   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);
> > > > -   }
> > > 
> > > .. but now you're moving the slave pipe stuff somewhere else?
> > > 
> > > We should be just iterating the pipes here (assuming this 
> > > is the correct spot to do these steps).
> > > 
> > > > -
> > > > /*
> > > >  * When called from DP MST code:
> > > >  * - old_conn_state will be NULL
> > > > @@ -3363,8 +3351,7 @@ static void intel_enable_ddi(struct 
> > > > intel_atomic_state *state,
> > > >  {
> > > > drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
> > > >  
> > > > -   if (!intel_crtc_is_bigjoiner_slave(crtc_state))
> > > > -   intel_ddi_enable_transcoder_func(encoder, crtc_state);
> > > > +   intel_ddi_enable_transcoder_func(encoder, crtc_state);
&

Re: [PATCH 2/3] Start separating pipe vs transcoder set logic for bigjoiner during modeset

2024-03-01 Thread Lisovskiy, Stanislav
On Fri, Mar 01, 2024 at 12:10:52PM +0200, Ville Syrjälä wrote:
> On Wed, Feb 21, 2024 at 09:20:09PM +0200, Stanislav Lisovskiy wrote:
> > 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: Get rid of master vs slave checks and separation in crtc enable/disable 
> > hooks.
> > Use unified iteration cycle for all of those, while enabling/disabling
> > transcoder only for those pipes where its needed(Ville Syrjälä)
> > 
> > v3: Move all the intel_encoder_* calls under transcoder code path(Ville 
> > Syrjälä)
> > 
> > v4:  - Call intel_crtc_vblank_on from hsw_crtc_enable only for 
> > non-transcoder path
> >(for master pipe that will be called from 
> > intel_encoders_enable/intel_enable_ddi)
> >  - Fix stupid mistake with using crtc->pipe for the mask, instead of 
> > BIT(crtc->pipe)
> > 
> > Signed-off-by: Stanislav Lisovskiy 
> > ---
> >  drivers/gpu/drm/i915/display/intel_ddi.c |  21 +--
> >  drivers/gpu/drm/i915/display/intel_display.c | 183 ---
> >  drivers/gpu/drm/i915/display/intel_display.h |   6 +
> >  3 files changed, 121 insertions(+), 89 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
> > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > index bea4415902044..6071e9f500871 100644
> > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > @@ -3100,7 +3100,6 @@ static void intel_ddi_post_disable(struct 
> > intel_atomic_state *state,
> >const struct drm_connector_state 
> > *old_conn_state)
> >  {
> > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> > -   struct intel_crtc *slave_crtc;
> >  
> > if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST)) {
> > intel_crtc_vblank_off(old_crtc_state);
> > @@ -3117,17 +3116,6 @@ static void intel_ddi_post_disable(struct 
> > intel_atomic_state *state,
> > ilk_pfit_disable(old_crtc_state);
> > }
> 
> The master pipe stuff is right here ^ ...
> 
> >  
> > -   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);
> > -   }
> 
> .. but now you're moving the slave pipe stuff somewhere else?
> 
> We should be just iterating the pipes here (assuming this 
> is the correct spot to do these steps).
> 
> > -
> > /*
> >  * When called from DP MST code:
> >  * - old_conn_state will be NULL
> > @@ -3363,8 +3351,7 @@ static void intel_enable_ddi(struct 
> > intel_atomic_state *state,
> >  {
> > drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
> >  
> > -   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);
> > @@ -3469,9 +3456,6 @@ 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 =
> > -   intel_atomic_get_new_crtc_state(state, crtc);
> > -   struct intel_crtc *slave_crtc;
> > enum phy phy = intel_port_to_phy(i915, encoder->port);
> >  
> > /* FIXME: Add MTL pll_mgr */
> > @@ -3479,9 +3463,6 @@ void intel_ddi_update_active_dpll(struct 
> > intel_atomic_state *state,
> > 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);
> >  }
> >  
> >  static void
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> > b/drivers/gpu/drm/i915/display/intel_display.c
> > index 916c13a149fd5..e1ea53fd6a288 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -1631,31 +1631,12 @@ static void hsw_configure_cpu_transcoder(const 
> > struct intel_crtc_state *crtc_sta
> > hsw_set_transconf(crtc_state);
> >  }
> >  
> > -static void hsw_crtc_enable(struct intel_atomic_state *state,
> > -   struct intel_crtc *crtc)
> > +static 

Re: [PATCH 1/3] drm/i915/bigjoiner: Refactor bigjoiner state readout

2024-03-01 Thread Lisovskiy, Stanislav
On Fri, Mar 01, 2024 at 12:10:19PM +0200, Ville Syrjälä wrote:
> On Wed, Feb 21, 2024 at 09:20:08PM +0200, Stanislav Lisovskiy wrote:
> > Don't call enabled_bigjoiner_pipes twice, lets just move
> > intel_get_bigjoiner_config earlier, because it is anyway
> > calling same function.
> > Also cleanup hsw_enabled_transcoders from irrelevant bigjoiner code.
> 
> I still don't like this.

As of current state of things, I didn't touch this since our last discussion.
This is not critical improvement, so lets drop this until the main issues are
solved.

> 
> > 
> > Signed-off-by: Stanislav Lisovskiy 
> > ---
> >  drivers/gpu/drm/i915/display/intel_display.c | 22 ++--
> >  1 file changed, 11 insertions(+), 11 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> > b/drivers/gpu/drm/i915/display/intel_display.c
> > index 00ac65a140298..916c13a149fd5 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -3535,7 +3535,6 @@ static u8 hsw_enabled_transcoders(struct intel_crtc 
> > *crtc)
> > struct drm_i915_private *dev_priv = to_i915(dev);
> > u8 panel_transcoder_mask = hsw_panel_transcoders(dev_priv);
> > enum transcoder cpu_transcoder;
> > -   u8 master_pipes, slave_pipes;
> > u8 enabled_transcoders = 0;
> >  
> > /*
> > @@ -3586,15 +3585,6 @@ static u8 hsw_enabled_transcoders(struct intel_crtc 
> > *crtc)
> > if (transcoder_ddi_func_is_enabled(dev_priv, cpu_transcoder))
> > enabled_transcoders |= BIT(cpu_transcoder);
> >  
> > -   /* bigjoiner slave -> consider the master pipe's transcoder as well */
> > -   enabled_bigjoiner_pipes(dev_priv, _pipes, _pipes);
> > -   if (slave_pipes & BIT(crtc->pipe)) {
> > -   cpu_transcoder = (enum transcoder)
> > -   get_bigjoiner_master_pipe(crtc->pipe, master_pipes, 
> > slave_pipes);
> > -   if (transcoder_ddi_func_is_enabled(dev_priv, cpu_transcoder))
> > -   enabled_transcoders |= BIT(cpu_transcoder);
> > -   }
> > -
> > return enabled_transcoders;
> >  }
> >  
> > @@ -3641,6 +3631,15 @@ static bool hsw_get_transcoder_state(struct 
> > intel_crtc *crtc,
> > u32 tmp;
> >  
> > enabled_transcoders = hsw_enabled_transcoders(crtc);
> > +
> > +   /* bigjoiner slave -> consider the master pipe's transcoder as well */
> > +   if (intel_crtc_is_bigjoiner_slave(pipe_config)) {
> > +   unsigned long cpu_transcoder = (enum transcoder)
> > +   bigjoiner_master_pipe(pipe_config);
> > +   if (transcoder_ddi_func_is_enabled(dev_priv, cpu_transcoder))
> > +   enabled_transcoders |= BIT(cpu_transcoder);
> > +   }
> > +
> > if (!enabled_transcoders)
> > return false;
> >  
> > @@ -3745,6 +3744,8 @@ static bool hsw_get_pipe_config(struct intel_crtc 
> > *crtc,
> >  
> > pipe_config->shared_dpll = NULL;
> >  
> > +   intel_bigjoiner_get_config(pipe_config);
> > +
> > active = hsw_get_transcoder_state(crtc, pipe_config, 
> > >hw_readout_power_domains);
> >  
> > if ((IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) &&
> > @@ -3756,7 +3757,6 @@ static bool hsw_get_pipe_config(struct intel_crtc 
> > *crtc,
> > if (!active)
> > goto out;
> >  
> > -   intel_bigjoiner_get_config(pipe_config);
> > intel_dsc_get_config(pipe_config);
> >  
> > if (!transcoder_is_dsi(pipe_config->cpu_transcoder) ||
> > -- 
> > 2.37.3
> 
> -- 
> Ville Syrjälä
> Intel


Re: [PATCH 3/3] drm/i915: Fix bigjoiner case for DP2.0

2024-02-27 Thread Lisovskiy, Stanislav
On Tue, Feb 27, 2024 at 11:06:16AM +0200, Srinivas, Vidya wrote:
> 
> 
> > -Original Message-
> > From: Lisovskiy, Stanislav 
> > Sent: Tuesday, February 27, 2024 2:34 PM
> > To: Jani Nikula 
> > Cc: intel-gfx@lists.freedesktop.org; Saarinen, Jani 
> > ;
> > ville.syrj...@linux.intel.com; Srinivas, Vidya 
> > Subject: Re: [PATCH 3/3] drm/i915: Fix bigjoiner case for DP2.0
> > 
> > On Mon, Feb 26, 2024 at 09:56:10PM +0200, Jani Nikula wrote:
> > > On Wed, 21 Feb 2024, Stanislav Lisovskiy 
> > wrote:
> > > > Patch calculates bigjoiner pipes in mst compute.
> > > > Patch also passes bigjoiner bool to validate plane max size.
> > >
> > > Please use the imperative mood in commit messages, e.g. "calculate"
> > > intead of "calculates".
> > >
> > > Please do not refer to "patch". We know it's a patch, until it isn't,
> > > and then it's a commit.
> > >
> > > Please explain *why* the changes are being done, not just *what* is
> > > being done.
> > >
> > > In the subject, what is "bigjoiner case for DP2.0"? DP 2.0 is a spec
> > > version, and as such irrelevant for the changes being done.
> > >
> > > > Signed-off-by: vsrini4 
> > >
> > > ?
> > 
> > Hi Jani, I just added that patch from Vidya to my series, to be honest, 
> > didn't
> > have time at all to look much into it.
> > Looks like its me who is going to fix that.
> 
> Hello Stan
> My sincere apologies. I dint want to disturb your series, so I did not fix it.
> Please let me know if I should fix it. Sorry again.
> Thank you Jani for the comments.
> 
> Regards
> Vidya

Hi Vidya,

it is a bit unclear for me as well now, how do we proceed, since your patch is 
part
of my series, I was explicitly asked to add it, does it mean you are fixing it 
now or me?
Well if you address Jani's comments, I definitely dont mind :)

> > 
> > >
> > > > Signed-off-by: Stanislav Lisovskiy 
> > > > ---
> > > >  drivers/gpu/drm/i915/display/intel_dp_mst.c | 19
> > > > ---
> > > >  1 file changed, 12 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 5307ddd4edcf5..fd27d9976c050 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > > @@ -523,6 +523,7 @@ static int intel_dp_mst_compute_config(struct
> > intel_encoder *encoder,
> > > >struct drm_connector_state 
> > > > *conn_state)
> > {
> > > > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> > > > +   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;
> > > > const struct intel_connector *connector = @@ -540,6 +541,10 @@
> > > > 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, 
> > > > 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; @@ -1318,12 +1323,6 @@
> > > > 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 

Re: [PATCH 2/3] Start separating pipe vs transcoder set logic for bigjoiner during modeset

2024-02-27 Thread Lisovskiy, Stanislav
On Tue, Feb 27, 2024 at 06:40:23AM +0200, Srinivas, Vidya wrote:
> 
> 
> > -Original Message-
> > From: Lisovskiy, Stanislav 
> > Sent: Thursday, February 22, 2024 12:50 AM
> > To: intel-gfx@lists.freedesktop.org
> > Cc: Lisovskiy, Stanislav ; Saarinen, Jani
> > ; ville.syrj...@linux.intel.com; Srinivas, Vidya
> > 
> > Subject: [PATCH 2/3] Start separating pipe vs transcoder set logic for 
> > bigjoiner
> > during modeset
> > 
> > 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: Get rid of master vs slave checks and separation in crtc enable/disable
> > hooks.
> > Use unified iteration cycle for all of those, while enabling/disabling
> > transcoder only for those pipes where its needed(Ville Syrjälä)
> > 
> > v3: Move all the intel_encoder_* calls under transcoder code path(Ville
> > Syrjälä)
> > 
> > v4:  - Call intel_crtc_vblank_on from hsw_crtc_enable only for 
> > non-transcoder
> > path
> >(for master pipe that will be called from
> > intel_encoders_enable/intel_enable_ddi)
> >  - Fix stupid mistake with using crtc->pipe for the mask, instead of 
> > BIT(crtc-
> > >pipe)
> > 
> > Signed-off-by: Stanislav Lisovskiy 
> > ---
> >  drivers/gpu/drm/i915/display/intel_ddi.c |  21 +--
> >  drivers/gpu/drm/i915/display/intel_display.c | 183 ---
> >  drivers/gpu/drm/i915/display/intel_display.h |   6 +
> >  3 files changed, 121 insertions(+), 89 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c
> > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > index bea4415902044..6071e9f500871 100644
> > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > @@ -3100,7 +3100,6 @@ static void intel_ddi_post_disable(struct
> > intel_atomic_state *state,
> >const struct drm_connector_state
> > *old_conn_state)  {
> > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> > -   struct intel_crtc *slave_crtc;
> > 
> > if (!intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST)) {
> > intel_crtc_vblank_off(old_crtc_state);
> > @@ -3117,17 +3116,6 @@ static void intel_ddi_post_disable(struct
> > intel_atomic_state *state,
> > 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);
> > -   }
> > -
> > /*
> >  * When called from DP MST code:
> >  * - old_conn_state will be NULL
> > @@ -3363,8 +3351,7 @@ static void intel_enable_ddi(struct
> > intel_atomic_state *state,  {
> > drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
> > 
> > -   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);
> > @@ -3469,9 +3456,6 @@ 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 =
> > -   intel_atomic_get_new_crtc_state(state, crtc);
> > -   struct intel_crtc *slave_crtc;
> > enum phy phy = intel_port_to_phy(i915, encoder->port);
> > 
> > /* FIXME: Add MTL pll_mgr */
> > @@ -3479,9 +3463,6 @@ void intel_ddi_update_active_dpll(struct
> > intel_atomic_state *state,
> > 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))
> > -  

Re: [PATCH 3/3] drm/i915: Fix bigjoiner case for DP2.0

2024-02-27 Thread Lisovskiy, Stanislav
On Mon, Feb 26, 2024 at 09:56:10PM +0200, Jani Nikula wrote:
> On Wed, 21 Feb 2024, Stanislav Lisovskiy  
> wrote:
> > Patch calculates bigjoiner pipes in mst compute.
> > Patch also passes bigjoiner bool to validate plane
> > max size.
> 
> Please use the imperative mood in commit messages, e.g. "calculate"
> intead of "calculates".
> 
> Please do not refer to "patch". We know it's a patch, until it isn't,
> and then it's a commit.
> 
> Please explain *why* the changes are being done, not just *what* is
> being done.
> 
> In the subject, what is "bigjoiner case for DP2.0"? DP 2.0 is a spec
> version, and as such irrelevant for the changes being done.
> 
> > Signed-off-by: vsrini4 
> 
> ?

Hi Jani, I just added that patch from Vidya to my series, to be honest,
didn't have time at all to look much into it.
Looks like its me who is going to fix that.

> 
> > Signed-off-by: Stanislav Lisovskiy 
> > ---
> >  drivers/gpu/drm/i915/display/intel_dp_mst.c | 19 ---
> >  1 file changed, 12 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 5307ddd4edcf5..fd27d9976c050 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > @@ -523,6 +523,7 @@ static int intel_dp_mst_compute_config(struct 
> > intel_encoder *encoder,
> >struct drm_connector_state *conn_state)
> >  {
> > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> > +   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;
> > const struct intel_connector *connector =
> > @@ -540,6 +541,10 @@ 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, 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;
> > @@ -1318,12 +1323,6 @@ 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 (mode->clock < 1) {
> > *status = MODE_CLOCK_LOW;
> > return 0;
> > @@ -1343,6 +1342,12 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector 
> > *connector,
> > return 0;
> > }
> >  
> > +   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 (DISPLAY_VER(dev_priv) >= 10 &&
> > drm_dp_sink_supports_dsc(intel_connector->dp.dsc_dpcd)) {
> > /*
> > @@ -1385,7 +1390,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;
> >  }
> 
> -- 
> Jani Nikula, Intel


Re: [PATCH] drm/i915: Add bigjoiner force enable option to debugfs

2024-02-14 Thread Lisovskiy, Stanislav
On Tue, Feb 13, 2024 at 10:33:56AM -0500, Rodrigo Vivi wrote:
> On Tue, Feb 13, 2024 at 05:21:26PM +0200, Lisovskiy, Stanislav wrote:
> > On Tue, Feb 13, 2024 at 05:11:37PM +0200, Shankar, Uma wrote:
> > > 
> > > 
> > > > -Original Message-
> > > > From: Rodrigo Vivi 
> > > > Sent: Tuesday, February 13, 2024 8:26 PM
> > > > To: Shankar, Uma 
> > > > Cc: intel-gfx@lists.freedesktop.org; Lisovskiy, Stanislav
> > > > ; ville.syrj...@linux.intel.com;
> > > > jani.nik...@linux.intel.com
> > > > Subject: Re: [PATCH] drm/i915: Add bigjoiner force enable option to 
> > > > debugfs
> > > > 
> > > > On Mon, Feb 12, 2024 at 06:20:11PM +0530, Uma Shankar wrote:
> > > > > From: Stanislav Lisovskiy 
> > > > >
> > > > > For validation purposes, it might be useful to be able to force
> > > > > Bigjoiner mode, even if current dotclock/resolution do not require
> > > > > that.
> > > > > Lets add such to option to debugfs.
> > > > >
> > > > > v2: - Apparently intel_dp_need_bigjoiner can't be used, when
> > > > >   debugfs entry is created so lets just check manually
> > > > >   the DISPLAY_VER.
> > > > >
> > > > > v3: - Switch to intel_connector from drm_connector(Jani Nikula)
> > > > > - Remove redundant modeset lock(Jani Nikula)
> > > > > - Use kstrtobool_from_user for boolean value(Jani Nikula)
> > > > >
> > > > > v4: - Apply the changes to proper function(Jani Nikula)
> > > > >
> > > > > v5: - Removed unnecessary check from i915_bigjoiner_enable_show
> > > > >   (Ville Syrjälä)
> > > > > - Added eDP connector check to intel_connector_debugfs_add
> > > > >   (Ville Syrjälä)
> > > > > - Removed debug message in order to prevent dmesg flooding
> > > > >   (Ville Syrjälä)
> > > > >
> > > > > v6: - Assume now always that m->private is intel_connector
> > > > > - Fixed other similar conflicts
> > > > >
> > > > > v7: - Move bigjoiner force option to intel_connector(Ville Syrjälä)
> > > > > - Use DEFINE_SHOW_STORE_ATTRIBUTE instead of defining fops
> > > > >   manually.(Ville Syrjälä)
> > > > >
> > > > > v8: - Pass intel_connector to debugfs_create_file, instead of 
> > > > > drm_connector.
> > > > >   (Jani Nikula)
> > > > >
> > > > > Signed-off-by: Stanislav Lisovskiy 
> > > > 
> > > > please remind to sign-off when sending someone else's patch.
> > > 
> > > Oh yeah, sorry missed it. Was filling in for Stan while he was OOO.
> > > @Lisovskiy, Stanislav Please address rest of the comments raised by 
> > > Rodrigo.
> > 
> > Sorry, had that pushed already in the morning, since it was Acked and I was 
> > asked
> > to do it asap.
> 
> no worries. if you are confident that the _show function magically works I 
> trust
> your tests more then my eyes and greps.

Well _definitely_ it should not be about trust, confidence or beliefs :)

See:

#define DEFINE_SHOW_STORE_ATTRIBUTE(__name) \
static int __name ## _open(struct inode *inode, struct file *file)  \
{   \
return single_open(file, __name ## _show, inode->i_private);\
}   \
\
static const struct file_operations __name ## _fops = { \
.owner  = THIS_MODULE,  \
.open   = __name ## _open,  \
.read   = seq_read, \
.write  = __name ## _write, \
.llseek = seq_lseek,\
.release= single_release,   \
}

In the patch:

+DEFINE_SHOW_STORE_ATTRIBUTE(i915_bigjoiner_enable);
+

means it will use i915_bigjoiner_enable_show function.

which is defined just as it expects in the patch:

+static int i915_bigjoiner_enable_show(struct seq_file *m, void *data)
+{
+   struct intel_connector *connector = m->private;
+   struct drm_crtc *crtc;
+
+   crtc = connector->base.state->crtc;
+   

Re: [PATCH] drm/i915: Add bigjoiner force enable option to debugfs

2024-02-13 Thread Lisovskiy, Stanislav
On Tue, Feb 13, 2024 at 05:11:37PM +0200, Shankar, Uma wrote:
> 
> 
> > -Original Message-
> > From: Rodrigo Vivi 
> > Sent: Tuesday, February 13, 2024 8:26 PM
> > To: Shankar, Uma 
> > Cc: intel-gfx@lists.freedesktop.org; Lisovskiy, Stanislav
> > ; ville.syrj...@linux.intel.com;
> > jani.nik...@linux.intel.com
> > Subject: Re: [PATCH] drm/i915: Add bigjoiner force enable option to debugfs
> > 
> > On Mon, Feb 12, 2024 at 06:20:11PM +0530, Uma Shankar wrote:
> > > From: Stanislav Lisovskiy 
> > >
> > > For validation purposes, it might be useful to be able to force
> > > Bigjoiner mode, even if current dotclock/resolution do not require
> > > that.
> > > Lets add such to option to debugfs.
> > >
> > > v2: - Apparently intel_dp_need_bigjoiner can't be used, when
> > >   debugfs entry is created so lets just check manually
> > >   the DISPLAY_VER.
> > >
> > > v3: - Switch to intel_connector from drm_connector(Jani Nikula)
> > > - Remove redundant modeset lock(Jani Nikula)
> > > - Use kstrtobool_from_user for boolean value(Jani Nikula)
> > >
> > > v4: - Apply the changes to proper function(Jani Nikula)
> > >
> > > v5: - Removed unnecessary check from i915_bigjoiner_enable_show
> > >   (Ville Syrjälä)
> > > - Added eDP connector check to intel_connector_debugfs_add
> > >   (Ville Syrjälä)
> > > - Removed debug message in order to prevent dmesg flooding
> > >   (Ville Syrjälä)
> > >
> > > v6: - Assume now always that m->private is intel_connector
> > > - Fixed other similar conflicts
> > >
> > > v7: - Move bigjoiner force option to intel_connector(Ville Syrjälä)
> > > - Use DEFINE_SHOW_STORE_ATTRIBUTE instead of defining fops
> > >   manually.(Ville Syrjälä)
> > >
> > > v8: - Pass intel_connector to debugfs_create_file, instead of 
> > > drm_connector.
> > >   (Jani Nikula)
> > >
> > > Signed-off-by: Stanislav Lisovskiy 
> > 
> > please remind to sign-off when sending someone else's patch.
> 
> Oh yeah, sorry missed it. Was filling in for Stan while he was OOO.
> @Lisovskiy, Stanislav Please address rest of the comments raised by Rodrigo.

Sorry, had that pushed already in the morning, since it was Acked and I was 
asked
to do it asap.

Stan

> 
> Regards,
> Uma Shankar
> 
> > > ---
> > >  .../drm/i915/display/intel_display_debugfs.c  | 47 +++
> > >  .../drm/i915/display/intel_display_types.h|  2 +
> > >  drivers/gpu/drm/i915/display/intel_dp.c   |  4 +-
> > >  3 files changed, 52 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > index 6f2d13c8ccf7..a962b48bcf13 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > > @@ -1391,6 +1391,20 @@ out:   drm_modeset_unlock(
> > >drm.mode_config.connection_mutex);
> > >   return ret;
> > >  }
> > >
> > > +static int i915_bigjoiner_enable_show(struct seq_file *m, void *data)
> > > +{
> > > + struct intel_connector *connector = m->private;
> > > + struct drm_crtc *crtc;
> > > +
> > > + crtc = connector->base.state->crtc;
> > > + if (connector->base.status != connector_status_connected || !crtc)
> > > + return -ENODEV;
> > > +
> > > + seq_printf(m, "Bigjoiner enable: %d\n",
> > > +connector->force_bigjoiner_enable);
> > 
> > probably better with a yes_or_no string?
> > 
> > > +
> > > + return 0;
> > > +}
> > > +
> > >  static ssize_t i915_dsc_output_format_write(struct file *file,
> > >   const char __user *ubuf,
> > >   size_t len, loff_t *offp)
> > > @@ -1412,6 +1426,30 @@ static ssize_t i915_dsc_output_format_write(struct
> > file *file,
> > >   return len;
> > >  }
> > >
> > > +static ssize_t i915_bigjoiner_enable_write(struct file *file,
> > > +const char __user *ubuf,
> > > +size_t len, loff_t *offp)
> > > +{
> > > + struct seq_file *m = file->private_dat

Re: [PATCH 3/3] drm/i915: Disable SAGV on bw init, to force QGV point recalculation

2024-02-01 Thread Lisovskiy, Stanislav
On Thu, Jan 18, 2024 at 11:07:23AM +0200, Ville Syrjälä wrote:
> On Thu, Jan 18, 2024 at 10:50:30AM +0200, Lisovskiy, Stanislav wrote:
> > On Thu, Jan 18, 2024 at 10:35:56AM +0200, Ville Syrjälä wrote:
> > > On Wed, Jan 17, 2024 at 05:57:18PM +0200, Stanislav Lisovskiy wrote:
> > > > Problem is that on some platforms, we do get QGV point mask in wrong
> > > > state on boot. However driver assumes it is set to 0
> > > > (i.e all points allowed), however in reality we might get them all 
> > > > restricted,
> > > > causing issues.
> > > > Lets disable SAGV initially to force proper QGV point state.
> > > > If more QGV points are available, driver will recalculate and update
> > > > those then after next commit.
> > > > 
> > > > v2: - Added trace to see which QGV/PSF GV point is used when SAGV is
> > > >   disabled.
> > > > v3: - Move force disable function to intel_bw_init in order to 
> > > > initialize
> > > >   bw state as well, so that hw/sw are immediately in sync after 
> > > > init.
> > > > v4: - Don't try sending PCode request, seems like it is not possible at
> > > >   intel_bw_init, however assigning bw->state to be restricted as if
> > > >   SAGV is off, still forces driveer to send PCode request anyway on
> > > >   next modeset, so the solution still works.
> > > >   However we still need to address the case, when no display is 
> > > > connected,
> > > >   which anyway requires much more changes.
> > > > 
> > > > Signed-off-by: Stanislav Lisovskiy 
> > > > ---
> > > >  drivers/gpu/drm/i915/display/intel_bw.c | 24 
> > > >  drivers/gpu/drm/i915/display/intel_bw.h |  2 ++
> > > >  2 files changed, 26 insertions(+)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_bw.c 
> > > > b/drivers/gpu/drm/i915/display/intel_bw.c
> > > > index 7baa1c13eccd..36a6304207ba 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_bw.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_bw.c
> > > > @@ -852,6 +852,27 @@ static unsigned int icl_max_bw_qgv_point(struct 
> > > > drm_i915_private *i915,
> > > > return max_bw_point;
> > > >  }
> > > >  
> > > > +void icl_force_disable_sagv(struct drm_i915_private *i915, struct 
> > > > intel_bw_state *bw_state)
> > > > +{
> > > > +   unsigned int max_bw_qgv_point = icl_max_bw_qgv_point(i915, 0);
> > > > +   unsigned int qgv_points;
> > > > +   unsigned int psf_points;
> > > > +
> > > > +   qgv_points = BIT(max_bw_qgv_point);
> > > > +
> > > > +   /*
> > > > +* We don't restrict PSF GV points, when disabling SAGV
> > > > +*/
> > > > +   psf_points = 0;
> > > 
> > > Using 0 looks very wrong here. Since we have no idea how much
> > > bandwidth the display is consuming at this time we should
> > > restrict this to the max psf gv point as well.
> > 
> > Didn't we just agree that we are not restricting to max PSF GV
> > point, in the last revision?..
> 
> That was about restricting PSF GV points during normal SAGV disable,
> which is all about the SAGV latency and nothing to do with bandwidth.
> 
> > 
> > "
> > > Yep, but I really suspect we should. BSpec states that we should restrict 
> > > all the GV points
> > > except highest one, also that some PSF GV points aren't same or usable, 
> > > depending on BW reqs.
> > > So I would restrict that as well, in case if SAGV is off, just to be on 
> > > safe side.
> > 
> > Pretty sure it's explicitly noted that PSF doesn't cause issues with
> > latency and hence doesn't need this.
> > 
> > In any case, a change like this has no business being in a patch
> > that's just supposed to refactor code.
> > "
> > 
> > 
> > 
> > > 
> > > > +
> > > > +   bw_state->qgv_points_mask = ~(ICL_PCODE_REQ_QGV_PT(qgv_points) |
> > > > + 
> > > > ADLS_PCODE_REQ_PSF_PT(psf_points)) &
> > > > + icl_qgv_points_mask(i915);
> > > > +
> > > > +   drm_dbg_kms(>drm, "Forcing SAGV disable: leaving QGV 
> > > > point

Re: [PATCH 2/3] drm/i915: Rework global state serializaiton

2024-02-01 Thread Lisovskiy, Stanislav
On Tue, Dec 19, 2023 at 03:07:55PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> Instead of injecting extra crtc commits to serialize the global
> state let's hand roll a but of commit machinery to take care of
> the hardware synchronization.
> 
> Rather than basing everything on the crtc commits we track these
> as their own thing. I think this makes more sense as the hardware
> blocks we are working with are not in any way tied to the pipes,
> so the completion should not be tied in with the vblank machinery
> either.
> 
> The difference to the old behaviour is that:
> - we no longer pull extra crtcs into the commit which should
>   make drm_atomic_check_only() happier
> - since those crtcs don't get pulled in we also don't end up
>   reprogamming them and thus don't need to wait their vblanks
>   to pass/etc. So this should be tad faster as well.
> 
> TODO: perhaps have each global object complete its own commit
> once the post-plane update phase is done?
> 
> Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/6728
> Signed-off-by: Ville Syrjälä 

Reviewed-by: Stanislav Lisovskiy 

> ---
>  drivers/gpu/drm/i915/display/intel_display.c  |  19 ++-
>  .../gpu/drm/i915/display/intel_global_state.c | 137 --
>  .../gpu/drm/i915/display/intel_global_state.h |   9 +-
>  3 files changed, 152 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> b/drivers/gpu/drm/i915/display/intel_display.c
> index b10aad15a63d..46eff0ee5519 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -7068,6 +7068,7 @@ static void intel_atomic_commit_tail(struct 
> intel_atomic_state *state)
>  
>   drm_atomic_helper_wait_for_dependencies(>base);
>   drm_dp_mst_atomic_wait_for_dependencies(>base);
> + intel_atomic_global_state_wait_for_dependencies(state);
>  
>   /*
>* During full modesets we write a lot of registers, wait
> @@ -7244,6 +7245,7 @@ static void intel_atomic_commit_tail(struct 
> intel_atomic_state *state)
>   intel_pmdemand_post_plane_update(state);
>  
>   drm_atomic_helper_commit_hw_done(>base);
> + intel_atomic_global_state_commit_done(state);
>  
>   if (state->modeset) {
>   /* As one of the primary mmio accessors, KMS has a high
> @@ -7294,6 +7296,21 @@ static void intel_atomic_track_fbs(struct 
> intel_atomic_state *state)
>   plane->frontbuffer_bit);
>  }
>  
> +static int intel_atomic_setup_commit(struct intel_atomic_state *state, bool 
> nonblock)
> +{
> + int ret;
> +
> + ret = drm_atomic_helper_setup_commit(>base, nonblock);
> + if (ret)
> + return ret;
> +
> + ret = intel_atomic_global_state_setup_commit(state);
> + if (ret)
> + return ret;
> +
> + return 0;
> +}
> +
>  int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state 
> *_state,
>   bool nonblock)
>  {
> @@ -7339,7 +7356,7 @@ int intel_atomic_commit(struct drm_device *dev, struct 
> drm_atomic_state *_state,
>   return ret;
>   }
>  
> - ret = drm_atomic_helper_setup_commit(>base, nonblock);
> + ret = intel_atomic_setup_commit(state, nonblock);
>   if (!ret)
>   ret = drm_atomic_helper_swap_state(>base, true);
>   if (!ret)
> diff --git a/drivers/gpu/drm/i915/display/intel_global_state.c 
> b/drivers/gpu/drm/i915/display/intel_global_state.c
> index e8e8be54143b..cbcd1e91b7be 100644
> --- a/drivers/gpu/drm/i915/display/intel_global_state.c
> +++ b/drivers/gpu/drm/i915/display/intel_global_state.c
> @@ -10,12 +10,55 @@
>  #include "intel_display_types.h"
>  #include "intel_global_state.h"
>  
> +struct intel_global_commit {
> + struct kref ref;
> + struct completion done;
> +};
> +
> +static struct intel_global_commit *commit_new(void)
> +{
> + struct intel_global_commit *commit;
> +
> + commit = kzalloc(sizeof(*commit), GFP_KERNEL);
> + if (!commit)
> + return NULL;
> +
> + init_completion(>done);
> + kref_init(>ref);
> +
> + return commit;
> +}
> +
> +static void __commit_free(struct kref *kref)
> +{
> + struct intel_global_commit *commit =
> + container_of(kref, typeof(*commit), ref);
> +
> + kfree(commit);
> +}
> +
> +static struct intel_global_commit *commit_get(struct intel_global_commit 
> *commit)
> +{
> + if (commit)
> + kref_get(>ref);
> +
> + return commit;
> +}
> +
> +static void commit_put(struct intel_global_commit *commit)
> +{
> + if (commit)
> + kref_put(>ref, __commit_free);
> +}
> +
>  static void __intel_atomic_global_state_free(struct kref *kref)
>  {
>   struct intel_global_state *obj_state =
>   container_of(kref, struct intel_global_state, ref);
>   struct intel_global_obj *obj = obj_state->obj;
>  
> + commit_put(obj_state->commit);
> +
>   

Re: [PATCH 1/3] drm/i915: Compute use_sagv_wm differently

2024-02-01 Thread Lisovskiy, Stanislav
On Tue, Dec 19, 2023 at 03:07:54PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> drm_atomic_check_only() gets upset if we try to add extra crtcs
> to any commit that isn't flagged with DRM_MODE_ATOMIC_ALLOW_MODESET.
> This conflicts with how SAGV watermarks work on pre-ADL as we
> need to manually switch over the SAGV watermarks before we can
> safely enable SAGV.
> 
> So in order to make SAGV usage possible we need to compute each
> pipe's use of SAGV watermarks as if there aren't any other
> active pipes. Ie. if the current pipe isn't the one blocking
> SAGV then we make it use the SAGV watermarks, even if some
> other pipe prevents SAGV from actually being used. Otherwise
> we could end up with a pipes using the normal watermarks (but
> not blocking SAGV), and some other pipe in parallel enabling
> SAGV, which would likely cause underruns.
> 
> The alternative approach of preventing SAGV usage until all
> pipes simultanously end up using SAGV watermarks would only
> really work if userspace always adds all pipes to every
> commits, which isn't the case typically.
> 
> The downside of this is that we will end up using the less
> optimal SAGV watermarks even if some other pipe prevents
> SAGV from actually being enabled. In which case the system
> won't achieve the minimum possible power consumption.

This is quite sad, that we have to do that, basically means
we might end up using SAGV watermarks, which use a bit more 
DBuf(taking into account SAGV related memory latency) just
because we can't sync properly with drm commit architecture
(as I understand the main problem is that crtc addition to the commit).
This is not catastrophical of course, but we are now basically
using the solution which we know for sure, that isn't optimal.

But as me personally and you probably as well, don't really 
have time resource to spend for solving it more efficiently,
lets use this as a solution.

Reviewed-by: Stanislav Lisovskiy 

> 
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/display/skl_watermark.c | 38 
>  1 file changed, 23 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c 
> b/drivers/gpu/drm/i915/display/skl_watermark.c
> index 56588d6e24ae..9cee19cbe253 100644
> --- a/drivers/gpu/drm/i915/display/skl_watermark.c
> +++ b/drivers/gpu/drm/i915/display/skl_watermark.c
> @@ -443,12 +443,35 @@ static int intel_compute_sagv_mask(struct 
> intel_atomic_state *state)
>  
>   for_each_new_intel_crtc_in_state(state, crtc,
>new_crtc_state, i) {
> + struct skl_pipe_wm *pipe_wm = _crtc_state->wm.skl.optimal;
> +
>   new_bw_state = intel_atomic_get_bw_state(state);
>   if (IS_ERR(new_bw_state))
>   return PTR_ERR(new_bw_state);
>  
>   old_bw_state = intel_atomic_get_old_bw_state(state);
>  
> + /*
> +  * We store use_sagv_wm in the crtc state rather than relying on
> +  * that bw state since we have no convenient way to get at the
> +  * latter from the plane commit hooks (especially in the legacy
> +  * cursor case).
> +  *
> +  * drm_atomic_check_only() gets upset if we pull more crtcs
> +  * into the state, so we have to calculate this based on the
> +  * individual intel_crtc_can_enable_sagv() rather than
> +  * the overall intel_crtc_can_enable_sagv(). Otherwise the
> +  * crtcs not included in the commit would not switch to the
> +  * SAGV watermarks when we are about to enable SAGV, and that
> +  * would lead to underruns. This does mean extra power draw
> +  * when only a subset of the crtcs are blocking SAGV as the
> +  * other crtcs can't be allowed to use the more optimal
> +  * normal (ie. non-SAGV) watermarks.
> +  */
> + pipe_wm->use_sagv_wm = !HAS_HW_SAGV_WM(i915) &&
> + DISPLAY_VER(i915) >= 12 &&
> + intel_crtc_can_enable_sagv(new_crtc_state);
> +
>   if (intel_crtc_can_enable_sagv(new_crtc_state))
>   new_bw_state->pipe_sagv_reject &= ~BIT(crtc->pipe);
>   else
> @@ -478,21 +501,6 @@ static int intel_compute_sagv_mask(struct 
> intel_atomic_state *state)
>   return ret;
>   }
>  
> - for_each_new_intel_crtc_in_state(state, crtc,
> -  new_crtc_state, i) {
> - struct skl_pipe_wm *pipe_wm = _crtc_state->wm.skl.optimal;
> -
> - /*
> -  * We store use_sagv_wm in the crtc state rather than relying on
> -  * that bw state since we have no convenient way to get at the
> -  * latter from the plane commit hooks (especially in the legacy
> -  * cursor case)
> -  */
> - 

Re: [PATCH 3/3] Start separating pipe vs transcoder set logic for bigjoiner during modeset

2024-01-29 Thread Lisovskiy, Stanislav
On Fri, Jan 12, 2024 at 06:47:10PM +0200, Ville Syrjälä wrote:
> On Mon, Jan 08, 2024 at 02:07:25PM +0200, Stanislav Lisovskiy wrote:
> > 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.
> > 
> > Signed-off-by: Stanislav Lisovskiy 
> > ---
> >  drivers/gpu/drm/i915/display/intel_ddi.c |   3 +-
> >  drivers/gpu/drm/i915/display/intel_display.c | 148 ---
> >  2 files changed, 128 insertions(+), 23 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
> > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > index 2746655bcb264..9723f1b49cf95 100644
> > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > @@ -3340,8 +3340,7 @@ static void intel_enable_ddi(struct 
> > intel_atomic_state *state,
> >  {
> > drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
> >  
> > -   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);
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> > b/drivers/gpu/drm/i915/display/intel_display.c
> > index eec76ec167069..24388226db465 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -1630,6 +1630,93 @@ static void hsw_configure_cpu_transcoder(const 
> > struct intel_crtc_state *crtc_sta
> > hsw_set_transconf(crtc_state);
> >  }
> >  
> > +static void hsw_crtc_enable_slave(struct intel_atomic_state *state,
> > + struct intel_crtc *crtc)
> > +{
> > +   const struct intel_crtc_state *new_crtc_state =
> > +   intel_atomic_get_new_crtc_state(state, crtc);
> > +   struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > +   enum pipe pipe = crtc->pipe, hsw_workaround_pipe;
> > +   bool psl_clkgate_wa;
> > +
> > +   if (drm_WARN_ON(_priv->drm, crtc->active))
> > +   return;
> > +
> > +   intel_dmc_enable_pipe(dev_priv, crtc->pipe);
> > +
> > +   if (!new_crtc_state->bigjoiner_pipes) {
> > +   intel_encoders_pre_pll_enable(state, crtc);
> > +
> > +   if (new_crtc_state->shared_dpll)
> > +   intel_enable_shared_dpll(new_crtc_state);
> > +
> > +   intel_encoders_pre_enable(state, crtc);
> > +   } else {
> > +   icl_ddi_bigjoiner_pre_enable(state, new_crtc_state);
> > +   }
> > +
> > +   intel_dsc_enable(new_crtc_state);
> > +
> > +   if (DISPLAY_VER(dev_priv) >= 13)
> > +   intel_uncompressed_joiner_enable(new_crtc_state);
> > +
> > +   intel_set_pipe_src_size(new_crtc_state);
> > +   if (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
> > +   bdw_set_pipe_misc(new_crtc_state);
> > +
> > +   crtc->active = true;
> > +
> > +   /* Display WA #1180: WaDisableScalarClockGating: glk */
> > +   psl_clkgate_wa = DISPLAY_VER(dev_priv) == 10 &&
> > +   new_crtc_state->pch_pfit.enabled;
> > +   if (psl_clkgate_wa)
> > +   glk_pipe_scaler_clock_gating_wa(dev_priv, pipe, true);
> > +
> > +   if (DISPLAY_VER(dev_priv) >= 9)
> > +   skl_pfit_enable(new_crtc_state);
> > +   else
> > +   ilk_pfit_enable(new_crtc_state);
> > +
> > +   /*
> > +* On ILK+ LUT must be loaded before the pipe is running but with
> > +* clocks enabled
> > +*/
> > +   intel_color_load_luts(new_crtc_state);
> > +   intel_color_commit_noarm(new_crtc_state);
> > +   intel_color_commit_arm(new_crtc_state);
> > +   /* update DSPCNTR to configure gamma/csc for pipe bottom color */
> > +   if (DISPLAY_VER(dev_priv) < 9)
> > +   intel_disable_primary_plane(new_crtc_state);
> > +
> > +   hsw_set_linetime_wm(new_crtc_state);
> > +
> > +   if (DISPLAY_VER(dev_priv) >= 11)
> > +   icl_set_pipe_chicken(new_crtc_state);
> > +
> > +   intel_initial_watermarks(state, crtc);
> > +
> > +   intel_crtc_vblank_on(new_crtc_state);
> > +
> > +   intel_encoders_enable(state, crtc);
> > +
> > +   if (psl_clkgate_wa) {
> > +   intel_crtc_wait_for_next_vblank(crtc);
> > +   glk_pipe_scaler_clock_gating_wa(dev_priv, pipe, false);
> > +   }
> > +
> > +   /* If we change the relative order between pipe/planes enabling, we need
> > +* to change the workaround. */
> > +   hsw_workaround_pipe = new_crtc_state->hsw_workaround_pipe;
> > +   if (IS_HASWELL(dev_priv) && hsw_workaround_pipe != INVALID_PIPE) {
> > +   struct intel_crtc *wa_crtc;
> > +
> > +   wa_crtc = intel_crtc_for_pipe(dev_priv, hsw_workaround_pipe);
> > +
> > +   intel_crtc_wait_for_next_vblank(wa_crtc);
> > +   intel_crtc_wait_for_next_vblank(wa_crtc);
> > +   

Re: [PATCH 1/3] drm/i915: Add bigjoiner force enable option to debugfs

2024-01-18 Thread Lisovskiy, Stanislav
On Thu, Jan 18, 2024 at 01:53:41PM +0200, Jani Nikula wrote:
> On Thu, 18 Jan 2024, Stanislav Lisovskiy  
> wrote:
> > For validation purposes, it might be useful to be able to
> > force Bigjoiner mode, even if current dotclock/resolution
> > do not require that.
> > Lets add such to option to debugfs.
> >
> > v2: - Apparently intel_dp_need_bigjoiner can't be used, when
> >   debugfs entry is created so lets just check manually
> >   the DISPLAY_VER.
> >
> > v3: - Switch to intel_connector from drm_connector(Jani Nikula)
> > - Remove redundant modeset lock(Jani Nikula)
> > - Use kstrtobool_from_user for boolean value(Jani Nikula)
> >
> > v4: - Apply the changes to proper function(Jani Nikula)
> >
> > v5: - Removed unnecessary check from i915_bigjoiner_enable_show
> >   (Ville Syrjälä)
> > - Added eDP connector check to intel_connector_debugfs_add
> >   (Ville Syrjälä)
> > - Removed debug message in order to prevent dmesg flooding
> >   (Ville Syrjälä)
> >
> > v6: - Assume now always that m->private is intel_connector
> > - Fixed other similar conflicts
> >
> > v7: - Move bigjoiner force option to intel_connector(Ville Syrjälä)
> > - Use DEFINE_SHOW_STORE_ATTRIBUTE instead of defining fops
> >   manually.(Ville Syrjälä)
> >
> > Signed-off-by: Stanislav Lisovskiy 
> > ---
> >  .../drm/i915/display/intel_display_debugfs.c  | 47 +++
> >  .../drm/i915/display/intel_display_types.h|  2 +
> >  drivers/gpu/drm/i915/display/intel_dp.c   |  4 +-
> >  3 files changed, 52 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c 
> > b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > index d951edb366871..ff0c7dfae89a3 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > @@ -1413,6 +1413,20 @@ out: 
> > drm_modeset_unlock(>drm.mode_config.connection_mutex);
> > return ret;
> >  }
> >  
> > +static int i915_bigjoiner_enable_show(struct seq_file *m, void *data)
> > +{
> > +   struct intel_connector *connector = m->private;
> > +   struct drm_crtc *crtc;
> > +
> > +   crtc = connector->base.state->crtc;
> > +   if (connector->base.status != connector_status_connected || !crtc)
> > +   return -ENODEV;
> > +
> > +   seq_printf(m, "Bigjoiner enable: %d\n", 
> > connector->force_bigjoiner_enable);
> > +
> > +   return 0;
> > +}
> > +
> >  static ssize_t i915_dsc_output_format_write(struct file *file,
> > const char __user *ubuf,
> > size_t len, loff_t *offp)
> > @@ -1434,6 +1448,30 @@ static ssize_t i915_dsc_output_format_write(struct 
> > file *file,
> > return len;
> >  }
> >  
> > +static ssize_t i915_bigjoiner_enable_write(struct file *file,
> > +   const char __user *ubuf,
> > +   size_t len, loff_t *offp)
> > +{
> > +   struct seq_file *m = file->private_data;
> > +   struct intel_connector *connector = m->private;
> > +   struct drm_crtc *crtc;
> > +   bool bigjoiner_en = 0;
> > +   int ret;
> > +
> > +   crtc = connector->base.state->crtc;
> > +   if (connector->base.status != connector_status_connected || !crtc)
> > +   return -ENODEV;
> > +
> > +   ret = kstrtobool_from_user(ubuf, len, _en);
> > +   if (ret < 0)
> > +   return ret;
> > +
> > +   connector->force_bigjoiner_enable = bigjoiner_en;
> > +   *offp += len;
> > +
> > +   return len;
> > +}
> > +
> >  static int i915_dsc_output_format_open(struct inode *inode,
> >struct file *file)
> >  {
> > @@ -1527,6 +1565,8 @@ static const struct file_operations 
> > i915_dsc_fractional_bpp_fops = {
> > .write = i915_dsc_fractional_bpp_write
> >  };
> >  
> > +DEFINE_SHOW_STORE_ATTRIBUTE(i915_bigjoiner_enable);
> > +
> >  /*
> >   * Returns the Current CRTC's bpc.
> >   * Example usage: cat /sys/kernel/debug/dri/0/crtc-0/i915_current_bpc
> > @@ -1608,6 +1648,13 @@ void intel_connector_debugfs_add(struct 
> > intel_connector *connector)
> > connector, _dsc_fractional_bpp_fops);
> > }
> >  
> > +   if (DISPLAY_VER(i915) >= 11 &&
> > +   (connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
> > +connector_type == DRM_MODE_CONNECTOR_eDP)) {
> > +   debugfs_create_file("i915_bigjoiner_force_enable", 0644, root,
> > +   >base, 
> > _bigjoiner_enable_fops);
> 
> I've replied to an earlier version of this patch telling you to pass
> struct intel_connector * to debugfs_create_file() when your show/write
> hooks expect that. This only works because offset of base member is 0,
> and the private pointer is void *.
> 
> BR,
> Jani.

Ahh.. I've seen but forgot to change that.
Anyways I will fix that, will now wait for feedback from Ville as well here, if
something else 

Re: [PATCH 3/3] drm/i915: Disable SAGV on bw init, to force QGV point recalculation

2024-01-18 Thread Lisovskiy, Stanislav
On Thu, Jan 18, 2024 at 11:07:23AM +0200, Ville Syrjälä wrote:
> On Thu, Jan 18, 2024 at 10:50:30AM +0200, Lisovskiy, Stanislav wrote:
> > On Thu, Jan 18, 2024 at 10:35:56AM +0200, Ville Syrjälä wrote:
> > > On Wed, Jan 17, 2024 at 05:57:18PM +0200, Stanislav Lisovskiy wrote:
> > > > Problem is that on some platforms, we do get QGV point mask in wrong
> > > > state on boot. However driver assumes it is set to 0
> > > > (i.e all points allowed), however in reality we might get them all 
> > > > restricted,
> > > > causing issues.
> > > > Lets disable SAGV initially to force proper QGV point state.
> > > > If more QGV points are available, driver will recalculate and update
> > > > those then after next commit.
> > > > 
> > > > v2: - Added trace to see which QGV/PSF GV point is used when SAGV is
> > > >   disabled.
> > > > v3: - Move force disable function to intel_bw_init in order to 
> > > > initialize
> > > >   bw state as well, so that hw/sw are immediately in sync after 
> > > > init.
> > > > v4: - Don't try sending PCode request, seems like it is not possible at
> > > >   intel_bw_init, however assigning bw->state to be restricted as if
> > > >   SAGV is off, still forces driveer to send PCode request anyway on
> > > >   next modeset, so the solution still works.
> > > >   However we still need to address the case, when no display is 
> > > > connected,
> > > >   which anyway requires much more changes.
> > > > 
> > > > Signed-off-by: Stanislav Lisovskiy 
> > > > ---
> > > >  drivers/gpu/drm/i915/display/intel_bw.c | 24 
> > > >  drivers/gpu/drm/i915/display/intel_bw.h |  2 ++
> > > >  2 files changed, 26 insertions(+)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_bw.c 
> > > > b/drivers/gpu/drm/i915/display/intel_bw.c
> > > > index 7baa1c13eccd..36a6304207ba 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_bw.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_bw.c
> > > > @@ -852,6 +852,27 @@ static unsigned int icl_max_bw_qgv_point(struct 
> > > > drm_i915_private *i915,
> > > > return max_bw_point;
> > > >  }
> > > >  
> > > > +void icl_force_disable_sagv(struct drm_i915_private *i915, struct 
> > > > intel_bw_state *bw_state)
> > > > +{
> > > > +   unsigned int max_bw_qgv_point = icl_max_bw_qgv_point(i915, 0);
> > > > +   unsigned int qgv_points;
> > > > +   unsigned int psf_points;
> > > > +
> > > > +   qgv_points = BIT(max_bw_qgv_point);
> > > > +
> > > > +   /*
> > > > +* We don't restrict PSF GV points, when disabling SAGV
> > > > +*/
> > > > +   psf_points = 0;
> > > 
> > > Using 0 looks very wrong here. Since we have no idea how much
> > > bandwidth the display is consuming at this time we should
> > > restrict this to the max psf gv point as well.
> > 
> > Didn't we just agree that we are not restricting to max PSF GV
> > point, in the last revision?..
> 
> That was about restricting PSF GV points during normal SAGV disable,
> which is all about the SAGV latency and nothing to do with bandwidth.

Ah, right. In normal case we are disabling SAGV because of the latency.

> 
> > 
> > "
> > > Yep, but I really suspect we should. BSpec states that we should restrict 
> > > all the GV points
> > > except highest one, also that some PSF GV points aren't same or usable, 
> > > depending on BW reqs.
> > > So I would restrict that as well, in case if SAGV is off, just to be on 
> > > safe side.
> > 
> > Pretty sure it's explicitly noted that PSF doesn't cause issues with
> > latency and hence doesn't need this.
> > 
> > In any case, a change like this has no business being in a patch
> > that's just supposed to refactor code.
> > "
> > 
> > 
> > 
> > > 
> > > > +
> > > > +   bw_state->qgv_points_mask = ~(ICL_PCODE_REQ_QGV_PT(qgv_points) |
> > > > + 
> > > > ADLS_PCODE_REQ_PSF_PT(psf_points)) &
> > > > + icl_qgv_points_mask(i915);
> > > > +
> > > > +   drm_dbg_kms(>drm

Re: [PATCH 3/3] drm/i915: Disable SAGV on bw init, to force QGV point recalculation

2024-01-18 Thread Lisovskiy, Stanislav
On Thu, Jan 18, 2024 at 10:35:56AM +0200, Ville Syrjälä wrote:
> On Wed, Jan 17, 2024 at 05:57:18PM +0200, Stanislav Lisovskiy wrote:
> > Problem is that on some platforms, we do get QGV point mask in wrong
> > state on boot. However driver assumes it is set to 0
> > (i.e all points allowed), however in reality we might get them all 
> > restricted,
> > causing issues.
> > Lets disable SAGV initially to force proper QGV point state.
> > If more QGV points are available, driver will recalculate and update
> > those then after next commit.
> > 
> > v2: - Added trace to see which QGV/PSF GV point is used when SAGV is
> >   disabled.
> > v3: - Move force disable function to intel_bw_init in order to initialize
> >   bw state as well, so that hw/sw are immediately in sync after init.
> > v4: - Don't try sending PCode request, seems like it is not possible at
> >   intel_bw_init, however assigning bw->state to be restricted as if
> >   SAGV is off, still forces driveer to send PCode request anyway on
> >   next modeset, so the solution still works.
> >   However we still need to address the case, when no display is 
> > connected,
> >   which anyway requires much more changes.
> > 
> > Signed-off-by: Stanislav Lisovskiy 
> > ---
> >  drivers/gpu/drm/i915/display/intel_bw.c | 24 
> >  drivers/gpu/drm/i915/display/intel_bw.h |  2 ++
> >  2 files changed, 26 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_bw.c 
> > b/drivers/gpu/drm/i915/display/intel_bw.c
> > index 7baa1c13eccd..36a6304207ba 100644
> > --- a/drivers/gpu/drm/i915/display/intel_bw.c
> > +++ b/drivers/gpu/drm/i915/display/intel_bw.c
> > @@ -852,6 +852,27 @@ static unsigned int icl_max_bw_qgv_point(struct 
> > drm_i915_private *i915,
> > return max_bw_point;
> >  }
> >  
> > +void icl_force_disable_sagv(struct drm_i915_private *i915, struct 
> > intel_bw_state *bw_state)
> > +{
> > +   unsigned int max_bw_qgv_point = icl_max_bw_qgv_point(i915, 0);
> > +   unsigned int qgv_points;
> > +   unsigned int psf_points;
> > +
> > +   qgv_points = BIT(max_bw_qgv_point);
> > +
> > +   /*
> > +* We don't restrict PSF GV points, when disabling SAGV
> > +*/
> > +   psf_points = 0;
> 
> Using 0 looks very wrong here. Since we have no idea how much
> bandwidth the display is consuming at this time we should
> restrict this to the max psf gv point as well.

Didn't we just agree that we are not restricting to max PSF GV
point, in the last revision?..

"
> Yep, but I really suspect we should. BSpec states that we should restrict all 
> the GV points
> except highest one, also that some PSF GV points aren't same or usable, 
> depending on BW reqs.
> So I would restrict that as well, in case if SAGV is off, just to be on safe 
> side.

Pretty sure it's explicitly noted that PSF doesn't cause issues with
latency and hence doesn't need this.

In any case, a change like this has no business being in a patch
that's just supposed to refactor code.
"



> 
> > +
> > +   bw_state->qgv_points_mask = ~(ICL_PCODE_REQ_QGV_PT(qgv_points) |
> > + ADLS_PCODE_REQ_PSF_PT(psf_points)) &
> > + icl_qgv_points_mask(i915);
> > +
> > +   drm_dbg_kms(>drm, "Forcing SAGV disable: leaving QGV point %d\n",
> > +   max_bw_qgv_point);
> 
> You didn't actually poke the hardware to disable anything.

I know, problem is that PCode request doesn't work at this stage.
Need to figure out why, but apparently it seems a bit too early.
PCode just rejects that request.

However that still works, because if more QGV points are available, driver
will send a new request anyway on next modeset.

Stan

> 
> > +}
> > +
> >  static int mtl_find_qgv_points(struct drm_i915_private *i915,
> >unsigned int data_rate,
> >unsigned int num_active_planes,
> > @@ -1351,5 +1372,8 @@ int intel_bw_init(struct drm_i915_private *dev_priv)
> > intel_atomic_global_obj_init(dev_priv, _priv->display.bw.obj,
> >  >base, _bw_funcs);
> >  
> > +   if (DISPLAY_VER(dev_priv) < 14)
> 
> Should be some kind of range check to avoid putting garbage in there on
> old platforms that don't support QGV.
> 
> > +   icl_force_disable_sagv(dev_priv, state);
> > +
> > return 0;
> >  }
> > diff --git a/drivers/gpu/drm/i915/display/intel_bw.h 
> > b/drivers/gpu/drm/i915/display/intel_bw.h
> > index 59cb4fc5db76..243192fd4cae 100644
> > --- a/drivers/gpu/drm/i915/display/intel_bw.h
> > +++ b/drivers/gpu/drm/i915/display/intel_bw.h
> > @@ -74,5 +74,7 @@ int intel_bw_calc_min_cdclk(struct intel_atomic_state 
> > *state,
> > bool *need_cdclk_calc);
> >  int intel_bw_min_cdclk(struct drm_i915_private *i915,
> >const struct intel_bw_state *bw_state);
> > +void icl_force_disable_sagv(struct drm_i915_private *dev_priv,
> > +   

Re: [PATCH 2/3] drm/i915: Extract code required to calculate max qgv/psf gv point

2024-01-17 Thread Lisovskiy, Stanislav
On Wed, Jan 17, 2024 at 01:12:49PM +0200, Ville Syrjälä wrote:
> On Wed, Jan 17, 2024 at 12:12:18PM +0200, Lisovskiy, Stanislav wrote:
> > On Fri, Jan 12, 2024 at 07:35:24PM +0200, Ville Syrjälä wrote:
> > > On Tue, Nov 28, 2023 at 10:37:53AM +0200, Stanislav Lisovskiy wrote:
> > > > We need that in order to force disable SAGV in next patch.
> > > > Also it is beneficial to separate that code, as in majority cases,
> > > > when SAGV is enabled, we don't even need those calculations.
> > > > Also we probably need to determine max PSF GV point as well, however
> > > > currently we don't do that when we disable SAGV, which might be
> > > > actually causing some issues in that case.
> > > > 
> > > > Signed-off-by: Stanislav Lisovskiy 
> > > > ---
> > > >  drivers/gpu/drm/i915/display/intel_bw.c | 82 -
> > > >  1 file changed, 65 insertions(+), 17 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_bw.c 
> > > > b/drivers/gpu/drm/i915/display/intel_bw.c
> > > > index 583cd2ebdf89..efd408e96e8a 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_bw.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_bw.c
> > > > @@ -805,6 +805,64 @@ intel_atomic_get_bw_state(struct 
> > > > intel_atomic_state *state)
> > > > return to_intel_bw_state(bw_state);
> > > >  }
> > > >  
> > > > +static unsigned int icl_max_bw_qgv_point(struct drm_i915_private *i915,
> > > > +int num_active_planes)
> > > > +{
> > > > +   unsigned int max_bw_point = 0;
> > > > +   unsigned int max_bw = 0;
> > > > +   unsigned int num_qgv_points = 
> > > > i915->display.bw.max[0].num_qgv_points;
> > > > +   int i;
> > > > +
> > > > +   for (i = 0; i < num_qgv_points; i++) {
> > > > +   unsigned int idx;
> > > > +   unsigned int max_data_rate;
> > > > +
> > > > +   if (DISPLAY_VER(i915) > 11)
> > > > +   idx = tgl_max_bw_index(i915, num_active_planes, 
> > > > i);
> > > > +   else
> > > > +   idx = icl_max_bw_index(i915, num_active_planes, 
> > > > i);
> > > > +
> > > > +   if (idx >= ARRAY_SIZE(i915->display.bw.max))
> > > > +   continue;
> > > > +
> > > > +   max_data_rate = i915->display.bw.max[idx].deratedbw[i];
> > > 
> > > Looks like that that part could be extracted to a helper
> > > to be used by both codepaths (would be a natural counterpart
> > > to adl_psf_bw()).
> > > 
> > > > +
> > > > +   /*
> > > > +* We need to know which qgv point gives us
> > > > +* maximum bandwidth in order to disable SAGV
> > > > +* if we find that we exceed SAGV block time
> > > > +* with watermarks. By that moment we already
> > > > +* have those, as it is calculated earlier in
> > > > +* intel_atomic_check,
> > > > +*/
> > > > +   if (max_data_rate > max_bw) {
> > > > +   max_bw_point = i;
> > > > +   max_bw = max_data_rate;
> > > > +   }
> > > > +   }
> > > > +
> > > > +   return max_bw_point;
> > > > +}
> > > > +
> > > > +unsigned int icl_max_bw_psf_gv_point(struct drm_i915_private *i915)
> > > > +{
> > > > +   unsigned int num_psf_gv_points = 
> > > > i915->display.bw.max[0].num_psf_gv_points;
> > > > +   unsigned int max_bw = 0;
> > > > +   unsigned int max_bw_point = 0;
> > > > +   int i;
> > > > +
> > > > +   for (i = 0; i < num_psf_gv_points; i++) {
> > > > +   unsigned int max_data_rate = adl_psf_bw(i915, i);
> > > > +
> > > > +   if (max_data_rate > max_bw) {
> > > > +   max_bw_point = i;
> > > > +   max_bw = max_data_rate;
> > > > +   }
> > > > +   }
>

Re: [PATCH 2/3] drm/i915: Extract code required to calculate max qgv/psf gv point

2024-01-17 Thread Lisovskiy, Stanislav
On Fri, Jan 12, 2024 at 07:35:24PM +0200, Ville Syrjälä wrote:
> On Tue, Nov 28, 2023 at 10:37:53AM +0200, Stanislav Lisovskiy wrote:
> > We need that in order to force disable SAGV in next patch.
> > Also it is beneficial to separate that code, as in majority cases,
> > when SAGV is enabled, we don't even need those calculations.
> > Also we probably need to determine max PSF GV point as well, however
> > currently we don't do that when we disable SAGV, which might be
> > actually causing some issues in that case.
> > 
> > Signed-off-by: Stanislav Lisovskiy 
> > ---
> >  drivers/gpu/drm/i915/display/intel_bw.c | 82 -
> >  1 file changed, 65 insertions(+), 17 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_bw.c 
> > b/drivers/gpu/drm/i915/display/intel_bw.c
> > index 583cd2ebdf89..efd408e96e8a 100644
> > --- a/drivers/gpu/drm/i915/display/intel_bw.c
> > +++ b/drivers/gpu/drm/i915/display/intel_bw.c
> > @@ -805,6 +805,64 @@ intel_atomic_get_bw_state(struct intel_atomic_state 
> > *state)
> > return to_intel_bw_state(bw_state);
> >  }
> >  
> > +static unsigned int icl_max_bw_qgv_point(struct drm_i915_private *i915,
> > +int num_active_planes)
> > +{
> > +   unsigned int max_bw_point = 0;
> > +   unsigned int max_bw = 0;
> > +   unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points;
> > +   int i;
> > +
> > +   for (i = 0; i < num_qgv_points; i++) {
> > +   unsigned int idx;
> > +   unsigned int max_data_rate;
> > +
> > +   if (DISPLAY_VER(i915) > 11)
> > +   idx = tgl_max_bw_index(i915, num_active_planes, i);
> > +   else
> > +   idx = icl_max_bw_index(i915, num_active_planes, i);
> > +
> > +   if (idx >= ARRAY_SIZE(i915->display.bw.max))
> > +   continue;
> > +
> > +   max_data_rate = i915->display.bw.max[idx].deratedbw[i];
> 
> Looks like that that part could be extracted to a helper
> to be used by both codepaths (would be a natural counterpart
> to adl_psf_bw()).
> 
> > +
> > +   /*
> > +* We need to know which qgv point gives us
> > +* maximum bandwidth in order to disable SAGV
> > +* if we find that we exceed SAGV block time
> > +* with watermarks. By that moment we already
> > +* have those, as it is calculated earlier in
> > +* intel_atomic_check,
> > +*/
> > +   if (max_data_rate > max_bw) {
> > +   max_bw_point = i;
> > +   max_bw = max_data_rate;
> > +   }
> > +   }
> > +
> > +   return max_bw_point;
> > +}
> > +
> > +unsigned int icl_max_bw_psf_gv_point(struct drm_i915_private *i915)
> > +{
> > +   unsigned int num_psf_gv_points = 
> > i915->display.bw.max[0].num_psf_gv_points;
> > +   unsigned int max_bw = 0;
> > +   unsigned int max_bw_point = 0;
> > +   int i;
> > +
> > +   for (i = 0; i < num_psf_gv_points; i++) {
> > +   unsigned int max_data_rate = adl_psf_bw(i915, i);
> > +
> > +   if (max_data_rate > max_bw) {
> > +   max_bw_point = i;
> > +   max_bw = max_data_rate;
> > +   }
> > +   }
> > +
> > +   return max_bw_point;
> > +}
> > +
> >  static int mtl_find_qgv_points(struct drm_i915_private *i915,
> >unsigned int data_rate,
> >unsigned int num_active_planes,
> > @@ -882,8 +940,6 @@ static int icl_find_qgv_points(struct drm_i915_private 
> > *i915,
> >const struct intel_bw_state *old_bw_state,
> >struct intel_bw_state *new_bw_state)
> >  {
> > -   unsigned int max_bw_point = 0;
> > -   unsigned int max_bw = 0;
> > unsigned int num_psf_gv_points = 
> > i915->display.bw.max[0].num_psf_gv_points;
> > unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points;
> > u16 psf_points = 0;
> > @@ -909,18 +965,6 @@ static int icl_find_qgv_points(struct drm_i915_private 
> > *i915,
> >  
> > max_data_rate = i915->display.bw.max[idx].deratedbw[i];
> >  
> > -   /*
> > -* We need to know which qgv point gives us
> > -* maximum bandwidth in order to disable SAGV
> > -* if we find that we exceed SAGV block time
> > -* with watermarks. By that moment we already
> > -* have those, as it is calculated earlier in
> > -* intel_atomic_check,
> > -*/
> > -   if (max_data_rate > max_bw) {
> > -   max_bw_point = i;
> > -   max_bw = max_data_rate;
> > -   }
> > if (max_data_rate >= data_rate)
> > qgv_points |= BIT(i);
> >  
> > @@ -964,9 +1008,13 @@ static int icl_find_qgv_points(struct 
> > drm_i915_private *i915,
> >  * cause.
> >  */
> > if (!intel_can_enable_sagv(i915, new_bw_state)) {
> > -

Re: [PATCH 3/3] drm/i915: Extract intel_atomic_swap_state()

2024-01-15 Thread Lisovskiy, Stanislav
On Tue, Dec 19, 2023 at 03:07:56PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> Pull all the state swap stuff into its own function to declutter
> intel_atomic_commit() a bit.
> 
> Note that currently the state swap is spread across both
> sides of the unprepare branch in intel_atomic_commit(), but
> we can pull all of it ahead a bit since we bail on the first
> error, and thus there is no change in behaviour from the
> reordering.

For that one, guess can give r-b rightaway, will check
global state serialize then, seems to be major change..

Reviewed-by: Stanislav Lisovskiy 

> 
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 23 +++-
>  1 file changed, 18 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> b/drivers/gpu/drm/i915/display/intel_display.c
> index 46eff0ee5519..bf37bfcf350e 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -7311,6 +7311,23 @@ static int intel_atomic_setup_commit(struct 
> intel_atomic_state *state, bool nonb
>   return 0;
>  }
>  
> +static int intel_atomic_swap_state(struct intel_atomic_state *state)
> +{
> + int ret;
> +
> + ret = drm_atomic_helper_swap_state(>base, true);
> + if (ret)
> + return ret;
> +
> + intel_atomic_swap_global_state(state);
> +
> + intel_shared_dpll_swap_state(state);
> +
> + intel_atomic_track_fbs(state);
> +
> + return 0;
> +}
> +
>  int intel_atomic_commit(struct drm_device *dev, struct drm_atomic_state 
> *_state,
>   bool nonblock)
>  {
> @@ -7358,9 +7375,7 @@ int intel_atomic_commit(struct drm_device *dev, struct 
> drm_atomic_state *_state,
>  
>   ret = intel_atomic_setup_commit(state, nonblock);
>   if (!ret)
> - ret = drm_atomic_helper_swap_state(>base, true);
> - if (!ret)
> - intel_atomic_swap_global_state(state);
> + ret = intel_atomic_swap_state(state);
>  
>   if (ret) {
>   struct intel_crtc_state *new_crtc_state;
> @@ -7374,8 +7389,6 @@ int intel_atomic_commit(struct drm_device *dev, struct 
> drm_atomic_state *_state,
>   intel_runtime_pm_put(_priv->runtime_pm, state->wakeref);
>   return ret;
>   }
> - intel_shared_dpll_swap_state(state);
> - intel_atomic_track_fbs(state);
>  
>   drm_atomic_state_get(>base);
>   INIT_WORK(>base.commit_work, intel_atomic_commit_work);
> -- 
> 2.41.0
> 


Re: [PATCH 3/3] Start separating pipe vs transcoder set logic for bigjoiner during modeset

2024-01-15 Thread Lisovskiy, Stanislav
On Fri, Jan 12, 2024 at 06:47:10PM +0200, Ville Syrjälä wrote:
> On Mon, Jan 08, 2024 at 02:07:25PM +0200, Stanislav Lisovskiy wrote:
> > 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.
> > 
> > Signed-off-by: Stanislav Lisovskiy 
> > ---
> >  drivers/gpu/drm/i915/display/intel_ddi.c |   3 +-
> >  drivers/gpu/drm/i915/display/intel_display.c | 148 ---
> >  2 files changed, 128 insertions(+), 23 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
> > b/drivers/gpu/drm/i915/display/intel_ddi.c
> > index 2746655bcb264..9723f1b49cf95 100644
> > --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> > @@ -3340,8 +3340,7 @@ static void intel_enable_ddi(struct 
> > intel_atomic_state *state,
> >  {
> > drm_WARN_ON(state->base.dev, crtc_state->has_pch_encoder);
> >  
> > -   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);
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> > b/drivers/gpu/drm/i915/display/intel_display.c
> > index eec76ec167069..24388226db465 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -1630,6 +1630,93 @@ static void hsw_configure_cpu_transcoder(const 
> > struct intel_crtc_state *crtc_sta
> > hsw_set_transconf(crtc_state);
> >  }
> >  
> > +static void hsw_crtc_enable_slave(struct intel_atomic_state *state,
> > + struct intel_crtc *crtc)
> > +{
> > +   const struct intel_crtc_state *new_crtc_state =
> > +   intel_atomic_get_new_crtc_state(state, crtc);
> > +   struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> > +   enum pipe pipe = crtc->pipe, hsw_workaround_pipe;
> > +   bool psl_clkgate_wa;
> > +
> > +   if (drm_WARN_ON(_priv->drm, crtc->active))
> > +   return;
> > +
> > +   intel_dmc_enable_pipe(dev_priv, crtc->pipe);
> > +
> > +   if (!new_crtc_state->bigjoiner_pipes) {
> > +   intel_encoders_pre_pll_enable(state, crtc);
> > +
> > +   if (new_crtc_state->shared_dpll)
> > +   intel_enable_shared_dpll(new_crtc_state);
> > +
> > +   intel_encoders_pre_enable(state, crtc);
> > +   } else {
> > +   icl_ddi_bigjoiner_pre_enable(state, new_crtc_state);
> > +   }
> > +
> > +   intel_dsc_enable(new_crtc_state);
> > +
> > +   if (DISPLAY_VER(dev_priv) >= 13)
> > +   intel_uncompressed_joiner_enable(new_crtc_state);
> > +
> > +   intel_set_pipe_src_size(new_crtc_state);
> > +   if (DISPLAY_VER(dev_priv) >= 9 || IS_BROADWELL(dev_priv))
> > +   bdw_set_pipe_misc(new_crtc_state);
> > +
> > +   crtc->active = true;
> > +
> > +   /* Display WA #1180: WaDisableScalarClockGating: glk */
> > +   psl_clkgate_wa = DISPLAY_VER(dev_priv) == 10 &&
> > +   new_crtc_state->pch_pfit.enabled;
> > +   if (psl_clkgate_wa)
> > +   glk_pipe_scaler_clock_gating_wa(dev_priv, pipe, true);
> > +
> > +   if (DISPLAY_VER(dev_priv) >= 9)
> > +   skl_pfit_enable(new_crtc_state);
> > +   else
> > +   ilk_pfit_enable(new_crtc_state);
> > +
> > +   /*
> > +* On ILK+ LUT must be loaded before the pipe is running but with
> > +* clocks enabled
> > +*/
> > +   intel_color_load_luts(new_crtc_state);
> > +   intel_color_commit_noarm(new_crtc_state);
> > +   intel_color_commit_arm(new_crtc_state);
> > +   /* update DSPCNTR to configure gamma/csc for pipe bottom color */
> > +   if (DISPLAY_VER(dev_priv) < 9)
> > +   intel_disable_primary_plane(new_crtc_state);
> > +
> > +   hsw_set_linetime_wm(new_crtc_state);
> > +
> > +   if (DISPLAY_VER(dev_priv) >= 11)
> > +   icl_set_pipe_chicken(new_crtc_state);
> > +
> > +   intel_initial_watermarks(state, crtc);
> > +
> > +   intel_crtc_vblank_on(new_crtc_state);
> > +
> > +   intel_encoders_enable(state, crtc);
> > +
> > +   if (psl_clkgate_wa) {
> > +   intel_crtc_wait_for_next_vblank(crtc);
> > +   glk_pipe_scaler_clock_gating_wa(dev_priv, pipe, false);
> > +   }
> > +
> > +   /* If we change the relative order between pipe/planes enabling, we need
> > +* to change the workaround. */
> > +   hsw_workaround_pipe = new_crtc_state->hsw_workaround_pipe;
> > +   if (IS_HASWELL(dev_priv) && hsw_workaround_pipe != INVALID_PIPE) {
> > +   struct intel_crtc *wa_crtc;
> > +
> > +   wa_crtc = intel_crtc_for_pipe(dev_priv, hsw_workaround_pipe);
> > +
> > +   intel_crtc_wait_for_next_vblank(wa_crtc);
> > +   intel_crtc_wait_for_next_vblank(wa_crtc);
> > +   

Re: [PATCH 2/3] drm/i915/bigjoiner: Refactor bigjoiner state readout

2024-01-15 Thread Lisovskiy, Stanislav
On Fri, Jan 12, 2024 at 06:42:15PM +0200, Ville Syrjälä wrote:
> On Mon, Jan 08, 2024 at 02:07:24PM +0200, Stanislav Lisovskiy wrote:
> > Don't call enabled_bigjoiner_pipes twice, lets just move
> > intel_get_bigjoiner_config earlier, because it is anyway
> > calling same function.
> > Also cleanup hsw_enabled_transcoders from irrelevant bigjoiner code.
> 
> It's not irrelevant. The function is supposed to return the set of
> enabled transcoders associated with the pipe. With this change the
> function no longer does what it says on the tin.

Yes, but I guess it is just a matter what we define to be higher in a
logical hierarchy: a pipe or a bigjoiner?
I thought it won't harm hsw_enabled_transcoders won't have any excess
logic and will return only transcoders naturally associated with a
physical pipe, while for higher complexity level constructs like bigjoiner
we would have some logic on top. 
In fact my main motivation was to avoid calling enabled_bigjoiner_pipe as 
it is quite heavy and call intel_crtc_is_bigjoiner_slave here instead. 

enabled_bigjoiner_pipes reads too much information, which 
we don't need in that function(here we just need to know if we are slave or 
master)

The absolute need for calling enabled_bigjoiner_pipes happens in 
intel_bigjoiner_get_config, which we moved earlier, which seems to be
logical since hsw_get_transcoder_state needs to have bigjoiner info and
now we can use its results to call more lightweight 
intel_crtc_is_bigjoiner_slave there
because pipe_config->bigjoiner_pipes is now initialized, so we avoid calling 
enabled_bigjoiner_pipes
second time..

> 
> > 
> > Signed-off-by: Stanislav Lisovskiy 
> > ---
> >  drivers/gpu/drm/i915/display/intel_display.c | 22 ++--
> >  1 file changed, 11 insertions(+), 11 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> > b/drivers/gpu/drm/i915/display/intel_display.c
> > index 927d124457b61..eec76ec167069 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -3525,7 +3525,6 @@ static u8 hsw_enabled_transcoders(struct intel_crtc 
> > *crtc)
> > struct drm_i915_private *dev_priv = to_i915(dev);
> > u8 panel_transcoder_mask = hsw_panel_transcoders(dev_priv);
> > enum transcoder cpu_transcoder;
> > -   u8 master_pipes, slave_pipes;
> > u8 enabled_transcoders = 0;
> >  
> > /*
> > @@ -3576,15 +3575,6 @@ static u8 hsw_enabled_transcoders(struct intel_crtc 
> > *crtc)
> > if (transcoder_ddi_func_is_enabled(dev_priv, cpu_transcoder))
> > enabled_transcoders |= BIT(cpu_transcoder);
> >  
> > -   /* bigjoiner slave -> consider the master pipe's transcoder as well */
> > -   enabled_bigjoiner_pipes(dev_priv, _pipes, _pipes);
> > -   if (slave_pipes & BIT(crtc->pipe)) {
> > -   cpu_transcoder = (enum transcoder)
> > -   get_bigjoiner_master_pipe(crtc->pipe, master_pipes, 
> > slave_pipes);
> > -   if (transcoder_ddi_func_is_enabled(dev_priv, cpu_transcoder))
> > -   enabled_transcoders |= BIT(cpu_transcoder);
> > -   }
> > -
> > return enabled_transcoders;
> >  }
> >  
> > @@ -3631,6 +3621,15 @@ static bool hsw_get_transcoder_state(struct 
> > intel_crtc *crtc,
> > u32 tmp;
> >  
> > enabled_transcoders = hsw_enabled_transcoders(crtc);
> > +
> > +   /* bigjoiner slave -> consider the master pipe's transcoder as well */
> > +   if (intel_crtc_is_bigjoiner_slave(pipe_config)) {
> > +   unsigned long cpu_transcoder = (enum transcoder)
> > +   bigjoiner_master_pipe(pipe_config);
> > +   if (transcoder_ddi_func_is_enabled(dev_priv, cpu_transcoder))
> > +   enabled_transcoders |= BIT(cpu_transcoder);
> > +   }
> > +
> > if (!enabled_transcoders)
> > return false;
> >  
> > @@ -3735,6 +3734,8 @@ static bool hsw_get_pipe_config(struct intel_crtc 
> > *crtc,
> >  
> > pipe_config->shared_dpll = NULL;
> >  
> > +   intel_bigjoiner_get_config(pipe_config);
> 
> So this is what avoids the "call it twice" part, but it also makes the
> state potentially inconsistent as in all other cases we leave everything
> zeroed if the transcoder is not enabled. So I'm not sure this is
> entirely safe or whether we could end up with some weird state
> mismatches due to the inconsistency.

Isn't it vice versa? intel_bigjoiner_get_config is now called way earlier,
before hsw_get_transcoder_state is called(previously it was called later),
the only difference is just that we now have pipe_config->bigjoiner_pipes
filled and enabled_bigjoiner_pipes was called there, so we can now
use that info to call intel_crtc_is_bigjoiner_slave in hsw_get_transcoder_state,
as I mentioned above.

Also if none of the transcoders are enabled, we now in fact have more 
information
filled than before this change(before we had only enabled_bigjoiner_pipes called
in hsw_get_transcoder_state, but now we have also 

Re: [PATCH 1/3] drm/i915: Add bigjoiner force enable option to debugfs

2024-01-15 Thread Lisovskiy, Stanislav
On Fri, Jan 12, 2024 at 06:25:05PM +0200, Ville Syrjälä wrote:
> On Mon, Jan 08, 2024 at 02:07:23PM +0200, Stanislav Lisovskiy wrote:
> > For validation purposes, it might be useful to be able to
> > force Bigjoiner mode, even if current dotclock/resolution
> > do not require that.
> > Lets add such to option to debugfs.
> > 
> > v2: - Apparently intel_dp_need_bigjoiner can't be used, when
> >   debugfs entry is created so lets just check manually
> >   the DISPLAY_VER.
> > 
> > v3: - Switch to intel_connector from drm_connector(Jani Nikula)
> > - Remove redundant modeset lock(Jani Nikula)
> > - Use kstrtobool_from_user for boolean value(Jani Nikula)
> > 
> > v4: - Apply the changes to proper function(Jani Nikula)
> > 
> > v5: - Removed unnecessary check from i915_bigjoiner_enable_show
> >   (Ville Syrjälä)
> > - Added eDP connector check to intel_connector_debugfs_add
> >   (Ville Syrjälä)
> > - Removed debug message in order to prevent dmesg flooding
> >   (Ville Syrjälä)
> > 
> > v6: - Assume now always that m->private is intel_connector
> > - Fixed other similar conflicts
> > 
> > Signed-off-by: Stanislav Lisovskiy 
> > ---
> >  .../drm/i915/display/intel_display_debugfs.c  | 59 +++
> >  .../drm/i915/display/intel_display_types.h|  2 +
> >  drivers/gpu/drm/i915/display/intel_dp.c   |  3 +-
> >  3 files changed, 63 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c 
> > b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > index d951edb366871..353e71b4e1db2 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > @@ -1413,6 +1413,22 @@ out: 
> > drm_modeset_unlock(>drm.mode_config.connection_mutex);
> > return ret;
> >  }
> >  
> > +static int i915_bigjoiner_enable_show(struct seq_file *m, void *data)
> > +{
> > +   struct intel_connector *connector = m->private;
> > +   struct intel_encoder *encoder = intel_attached_encoder(connector);
> > +   struct intel_dp *intel_dp;
> > +
> > +   if (!encoder)
> > +   return -ENODEV;
> > +
> > +   intel_dp = enc_to_intel_dp(encoder);
> > +
> > +   seq_printf(m, "Bigjoiner enable: %d\n", 
> > intel_dp->force_bigjoiner_enable);
> 
> So it's a per-connector debugfs knob but we track it in the
> SST DP encoder? That's rather odd, and not going to work for MST.

I guess you mean, I should move it to the connector instead, makes sense.

> 
> > +
> > +   return 0;
> > +}
> > +
> >  static ssize_t i915_dsc_output_format_write(struct file *file,
> > const char __user *ubuf,
> > size_t len, loff_t *offp)
> > @@ -1434,12 +1450,39 @@ static ssize_t i915_dsc_output_format_write(struct 
> > file *file,
> > return len;
> >  }
> >  
> > +static ssize_t i915_bigjoiner_enable_fops_write(struct file *file,
> > +   const char __user *ubuf,
> > +   size_t len, loff_t *offp)
> > +{
> > +   struct seq_file *m = file->private_data;
> > +   struct intel_connector *connector = m->private;
> > +   struct intel_encoder *encoder = intel_attached_encoder(connector);
> > +   struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> > +   bool bigjoiner_en = 0;
> > +   int ret;
> > +
> > +   ret = kstrtobool_from_user(ubuf, len, _en);
> > +   if (ret < 0)
> > +   return ret;
> > +
> > +   intel_dp->force_bigjoiner_enable = bigjoiner_en;
> > +   *offp += len;
> > +
> > +   return len;
> > +}
> > +
> >  static int i915_dsc_output_format_open(struct inode *inode,
> >struct file *file)
> >  {
> > return single_open(file, i915_dsc_output_format_show, inode->i_private);
> >  }
> >  
> > +static int i915_bigjoiner_enable_open(struct inode *inode,
> > + struct file *file)
> > +{
> > +   return single_open(file, i915_bigjoiner_enable_show, inode->i_private);
> > +}
> > +
> >  static const struct file_operations i915_dsc_output_format_fops = {
> > .owner = THIS_MODULE,
> > .open = i915_dsc_output_format_open,
> > @@ -1527,6 +1570,15 @@ static const struct file_operations 
> > i915_dsc_fractional_bpp_fops = {
> > .write = i915_dsc_fractional_bpp_write
> >  };
> >  
> > +static const struct file_operations i915_bigjoiner_enable_fops = {
> > +   .owner = THIS_MODULE,
> > +   .open = i915_bigjoiner_enable_open,
> > +   .read = seq_read,
> > +   .llseek = seq_lseek,
> > +   .release = single_release,
> > +   .write = i915_bigjoiner_enable_fops_write
> > +};
> 
> Why are we implementing this long-hand for a simple boolean flag?

Will check, thought thats the only way..

> 
> > +
> >  /*
> >   * Returns the Current CRTC's bpc.
> >   * Example usage: cat /sys/kernel/debug/dri/0/crtc-0/i915_current_bpc
> > @@ -1608,6 +1660,13 @@ void 

Re: [PATCH 2/2] drm/i915/psr: CAN_PSR and CAN_PANEL_REPLAY can be now local defines

2024-01-10 Thread Lisovskiy, Stanislav
On Tue, Jan 09, 2024 at 12:05:17PM +0200, Jouni Högander wrote:
> CAN_PSR and CAN_PANEL_REPLAY are not used outside intel_psr.c anymore. Make
> them as intel_psr.c local defines.
> 
> Signed-off-by: Jouni Högander 

Reviewed-by: Stanislav Lisovskiy 

> ---
>  drivers/gpu/drm/i915/display/intel_psr.c | 6 ++
>  drivers/gpu/drm/i915/display/intel_psr.h | 6 --
>  2 files changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.c 
> b/drivers/gpu/drm/i915/display/intel_psr.c
> index 54120b45958b..34c0a5a14455 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.c
> +++ b/drivers/gpu/drm/i915/display/intel_psr.c
> @@ -173,6 +173,12 @@
>   * irrelevant for normal operation.
>   */
>  
> +#define CAN_PSR(intel_dp) ((intel_dp)->psr.sink_support && \
> +(intel_dp)->psr.source_support)
> +
> +#define CAN_PANEL_REPLAY(intel_dp) 
> ((intel_dp)->psr.sink_panel_replay_support && \
> + (intel_dp)->psr.source_panel_replay_support)
> +
>  bool intel_encoder_can_psr(struct intel_encoder *encoder)
>  {
>   if (intel_encoder_is_dp(encoder) || encoder->type == 
> INTEL_OUTPUT_DP_MST)
> diff --git a/drivers/gpu/drm/i915/display/intel_psr.h 
> b/drivers/gpu/drm/i915/display/intel_psr.h
> index 143e0595c097..cde781df84d5 100644
> --- a/drivers/gpu/drm/i915/display/intel_psr.h
> +++ b/drivers/gpu/drm/i915/display/intel_psr.h
> @@ -21,12 +21,6 @@ struct intel_encoder;
>  struct intel_plane;
>  struct intel_plane_state;
>  
> -#define CAN_PSR(intel_dp) ((intel_dp)->psr.sink_support && \
> -(intel_dp)->psr.source_support)
> -
> -#define CAN_PANEL_REPLAY(intel_dp) 
> ((intel_dp)->psr.sink_panel_replay_support && \
> - (intel_dp)->psr.source_panel_replay_support)
> -
>  bool intel_encoder_can_psr(struct intel_encoder *encoder);
>  void intel_psr_init_dpcd(struct intel_dp *intel_dp);
>  void intel_psr_pre_plane_update(struct intel_atomic_state *state,
> -- 
> 2.34.1
> 


Re: [PATCH 1/2] drm/i915/display: No need for full modeset due to psr

2024-01-10 Thread Lisovskiy, Stanislav
On Tue, Jan 09, 2024 at 12:05:16PM +0200, Jouni Högander wrote:
> There is no specific reason to force full modeset if psr is enabled.
> 
> Signed-off-by: Jouni Högander 
> Tested-by: Paz Zcharya 


Reviewed-by: Stanislav Lisovskiy 

> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 7 ---
>  drivers/gpu/drm/i915/display/intel_dp.c  | 7 ---
>  2 files changed, 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> b/drivers/gpu/drm/i915/display/intel_display.c
> index 31a6a82c1261..0cccf6df6718 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -5202,13 +5202,6 @@ intel_pipe_config_compare(const struct 
> intel_crtc_state *current_config,
>  
>   PIPE_CONF_CHECK_CSC(csc);
>   PIPE_CONF_CHECK_CSC(output_csc);
> -
> - if (current_config->active_planes) {
> - PIPE_CONF_CHECK_BOOL(has_psr);
> - PIPE_CONF_CHECK_BOOL(has_psr2);
> - PIPE_CONF_CHECK_BOOL(enable_psr2_sel_fetch);
> - PIPE_CONF_CHECK_I(dc3co_exitline);
> - }
>   }
>  
>   PIPE_CONF_CHECK_BOOL(double_wide);
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index 7e4b7d5606d4..ab415f41924d 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -3326,13 +3326,6 @@ bool intel_dp_initial_fastset_check(struct 
> intel_encoder *encoder,
>   fastset = false;
>   }
>  
> - if (CAN_PSR(intel_dp)) {
> - drm_dbg_kms(>drm, "[ENCODER:%d:%s] Forcing full modeset 
> to compute PSR state\n",
> - encoder->base.base.id, encoder->base.name);
> - crtc_state->uapi.mode_changed = true;
> - fastset = false;
> - }
> -
>   return fastset;
>  }
>  
> -- 
> 2.34.1
> 


Re: [Intel-gfx] [PATCH] drm/i915: Fix bigjoiner case for DP2.0

2024-01-10 Thread Lisovskiy, Stanislav
On Fri, Oct 13, 2023 at 01:43:46PM +0300, Ville Syrjälä wrote:
> On Fri, Oct 13, 2023 at 01:00:00AM +0530, vsrini4 wrote:
> > Patch calculates bigjoiner pipes in mst compute.
> > Patch also passes bigjoiner bool to validate plane
> > max size.
> 
> I doubt this is sufficient. The modeset sequence is still all
> wrong for bigjoiner+mst.

Should that be now enough with my series also?

https://patchwork.freedesktop.org/series/128311/

Stan

> 
> > 
> > Signed-off-by: vsrini4 
> > ---
> >  drivers/gpu/drm/i915/display/intel_dp_mst.c | 19 ---
> >  1 file changed, 12 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 e3f176a093d2..f499ce39b2a8 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > @@ -308,6 +308,7 @@ static int intel_dp_mst_compute_config(struct 
> > intel_encoder *encoder,
> >struct drm_connector_state *conn_state)
> >  {
> > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> > +   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;
> > const struct drm_display_mode *adjusted_mode =
> > @@ -318,6 +319,10 @@ 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, 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;
> > @@ -936,12 +941,6 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector 
> > *connector,
> > if (ret)
> > return ret;
> >  
> > -   if (mode_rate > max_rate || mode->clock > max_dotclk ||
> > -   drm_dp_calc_pbn_mode(mode->clock, min_bpp, false) > port->full_pbn) 
> > {
> > -   *status = MODE_CLOCK_HIGH;
> > -   return 0;
> > -   }
> > -
> > if (mode->clock < 1) {
> > *status = MODE_CLOCK_LOW;
> > return 0;
> > @@ -957,6 +956,12 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector 
> > *connector,
> > max_dotclk *= 2;
> > }
> >  
> > +   if (mode_rate > max_rate || mode->clock > max_dotclk ||
> > +   drm_dp_calc_pbn_mode(mode->clock, min_bpp, false) > port->full_pbn) 
> > {
> > +   *status = MODE_CLOCK_HIGH;
> > +   return 0;
> > +   }
> > +
> > if (DISPLAY_VER(dev_priv) >= 10 &&
> > drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd)) {
> > /*
> > @@ -994,7 +999,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector 
> > *connector,
> > if (mode_rate > max_rate && !dsc)
> > return MODE_CLOCK_HIGH;
> >  
> > -   *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.33.0
> 
> -- 
> Ville Syrjälä
> Intel


Re: [PATCH 9/9] Revert "drm/i915/xe2lpd: Treat cursor plane as regular plane for DDB allocation"

2024-01-09 Thread Lisovskiy, Stanislav
On Fri, Dec 15, 2023 at 01:15:16PM +0200, Ville Syrjälä wrote:
> On Wed, Dec 13, 2023 at 05:29:12PM +0200, Ville Syrjälä wrote:
> > On Wed, Dec 13, 2023 at 05:15:06PM +0200, Ville Syrjälä wrote:
> > > On Wed, Dec 13, 2023 at 01:28:15PM +0200, Lisovskiy, Stanislav wrote:
> > > > On Wed, Dec 13, 2023 at 12:25:19PM +0200, Ville Syrjala wrote:
> > > > > From: Ville Syrjälä 
> > > > > 
> > > > > This reverts commit cfeff354f70bb1d0deb0279506e3f7989bc16e28.
> > > > > 
> > > > > A core design consideration with legacy cursor updates is that the
> > > > > cursor must not touch any other plane, even if we were to force it
> > > > > to take the slow path. That is the real reason why the cursor uses
> > > > > a fixed ddb allocation, not because bspec says so.
> > > > > 
> > > > > Treating cursors as any other plane during ddb allocation
> > > > > violates that, which means we can now pull other planes into
> > > > > fully unsynced legacy cursor mailbox commits. That is
> > > > > definitely not something we've ever considered when designing
> > > > > the rest of the code. The noarm+arm register write split in
> > > > > particular makes that dangerous as previous updates can get
> > > > > disarmed pretty much at any random time, and not necessarily
> > > > > in an order that is actually safe (eg. against ddb overlaps).
> > > > > 
> > > > > So if we were to do this then:
> > > > > - someone needs to expend the appropriate amount of brain
> > > > >   cells thinking through all the tricky details
> > > > 
> > > > So question is how can we avoid pulling other planes to the commit?..
> > > 
> > > By preallocating the ddb, as we do already.
> > 
> > I guess one thing we could consider is allcating the cursor ddb
> > based on the cursors real size (as opposed to always allocating for
> > 256x256 cursor), and not doing a mailbox update when changing size.
> > But as we learn in https://gitlab.freedesktop.org/drm/intel/-/issues/7687:
> > - current userspace always uses 256x256 until the PLANE_SIZE_HINTS
> >   stuff (or something similar) lands, so there is no point
> > - it would lead to worse power consumption with smaller cursors
> >   as there isn't enough extra ddb. The fact that we currently 
> >   allocate the minimum for 256x256 means smallers cursor sizes
> >   are more efficient. Some tests I did also indicated that the
> >   current code does not give optimal values even if we let it
> >   fully calculate the extra ddb like in the reverted commit here.
> >   We really need someone to take a proper look at how to tune
> >   the ddb allocation for optimal power consumption...
> 
> Oh, and another random idea I keep having occasionally would
> be to by default assume that legacy cursor uapi wouldn't be
> used, and then massage stuff sufficiently when the first use
> appears to make it work well from that point onwards. That 
> way we could try to be a bit more optimal with ddb/other
> stuff for userspace that never uses the legacy cursor uapi.
> But haven't really thought through the details on this one.

Reviewed-by: Stanislav Lisovskiy 

> 
> -- 
> Ville Syrjälä
> Intel


Re: [PATCH] drm/i915: clear the QGV mask set by GOP while booting

2024-01-04 Thread Lisovskiy, Stanislav
On Wed, Jan 03, 2024 at 06:57:45PM -0800, George D Sworo wrote:
> From: George D Sworo 
> 
> GOP driver in the firmware is masking the QGV points except the one
> which can
> provide high Bandwidth required for panel.
> 
> On boot to the OS the mask is already set, and is not cleared anywhere
> in the i915 driver
> even though sagv is enabled. This means Pcode is unable to switch to
> other QGV work points
> except the one enabled by default in the GOP driver at boot time.
> 
> This change resets the mask, when i915 driver is finding the QGV
> points at the boot time. So that Pcode can switch to QGV work points
> based
> on the Workloads.
> 
> Signed-off-by: George D Sworo 


Hi,

We already have a case similar to this, you might want to check this out:

https://patchwork.freedesktop.org/series/126962/

Stan


> ---
>  drivers/gpu/drm/i915/display/intel_bw.c | 6 ++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_bw.c 
> b/drivers/gpu/drm/i915/display/intel_bw.c
> index bef96db62c80..e2576c0fb729 100644
> --- a/drivers/gpu/drm/i915/display/intel_bw.c
> +++ b/drivers/gpu/drm/i915/display/intel_bw.c
> @@ -212,6 +212,7 @@ static int icl_get_qgv_points(struct drm_i915_private 
> *dev_priv,
> bool is_y_tile)
>  {
>   const struct dram_info *dram_info = _priv->dram_info;
> + u32 val = 0x00, val2 = 0;
>   int i, ret;
>  
>   qi->num_points = dram_info->num_qgv_points;
> @@ -311,6 +312,11 @@ static int icl_get_qgv_points(struct drm_i915_private 
> *dev_priv,
>   i, qi->psf_points[i].clk);
>   }
>  
> + /* clear the QGV points mask set by the GOP driver while booting */
> + ret = snb_pcode_read(_priv->uncore, 
> ICL_PCODE_SAGV_DE_MEM_SS_CONFIG, , );
> + if (ret)
> + return ret;
> +
>   return 0;
>  }
>  
> -- 
> 2.34.1
> 


Re: [PATCH] drm/i915: clear the QGV mask set by GOP while booting

2024-01-04 Thread Lisovskiy, Stanislav
On Wed, Jan 03, 2024 at 06:57:45PM -0800, George D Sworo wrote:
> From: George D Sworo 
> 
> GOP driver in the firmware is masking the QGV points except the one
> which can
> provide high Bandwidth required for panel.
> 
> On boot to the OS the mask is already set, and is not cleared anywhere
> in the i915 driver
> even though sagv is enabled. This means Pcode is unable to switch to
> other QGV work points
> except the one enabled by default in the GOP driver at boot time.
> 
> This change resets the mask, when i915 driver is finding the QGV
> points at the boot time. So that Pcode can switch to QGV work points
> based
> on the Workloads.
> 
> Signed-off-by: George D Sworo 

Hi,

We already have a case similar to this, you might want to check this out:

https://patchwork.freedesktop.org/series/126962/

Stan

> ---
>  drivers/gpu/drm/i915/display/intel_bw.c | 6 ++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_bw.c 
> b/drivers/gpu/drm/i915/display/intel_bw.c
> index bef96db62c80..e2576c0fb729 100644
> --- a/drivers/gpu/drm/i915/display/intel_bw.c
> +++ b/drivers/gpu/drm/i915/display/intel_bw.c
> @@ -212,6 +212,7 @@ static int icl_get_qgv_points(struct drm_i915_private 
> *dev_priv,
> bool is_y_tile)
>  {
>   const struct dram_info *dram_info = _priv->dram_info;
> + u32 val = 0x00, val2 = 0;
>   int i, ret;
>  
>   qi->num_points = dram_info->num_qgv_points;
> @@ -311,6 +312,11 @@ static int icl_get_qgv_points(struct drm_i915_private 
> *dev_priv,
>   i, qi->psf_points[i].clk);
>   }
>  
> + /* clear the QGV points mask set by the GOP driver while booting */
> + ret = snb_pcode_read(_priv->uncore, 
> ICL_PCODE_SAGV_DE_MEM_SS_CONFIG, , );
> + if (ret)
> + return ret;
> +
>   return 0;
>  }
>  
> -- 
> 2.34.1
> 


Re: [PATCH] drm/i915: Reject async flips with bigjoiner

2023-12-13 Thread Lisovskiy, Stanislav
On Mon, Dec 11, 2023 at 10:11:34AM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> Currently async flips are busted when bigjoiner is in use.
> As a short term fix simply reject async flips in that case.
> 
> Cc: sta...@vger.kernel.org
> Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/9769
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 11 +++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> b/drivers/gpu/drm/i915/display/intel_display.c
> index d955957b7d18..61053c19f4cc 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -5926,6 +5926,17 @@ static int intel_async_flip_check_uapi(struct 
> intel_atomic_state *state,
>   return -EINVAL;
>   }
>  
> + /*
> +  * FIXME: Bigjoiner+async flip is busted currently.
> +  * Remove this check once the issues are fixed.
> +  */
> + if (new_crtc_state->bigjoiner_pipes) {
> + drm_dbg_kms(>drm,
> + "[CRTC:%d:%s] async flip disallowed with 
> bigjoiner\n",
> + crtc->base.base.id, crtc->base.name);
> + return -EINVAL;
> + }
> +

Was recently wondering, whether should we add some kind of helper
func for that check to look more readable, i.e instead of just
checking if crtc_state->bigjoiner_pipes != 0, call smth like
is_bigjoiner_used(new_crtc_state)..

Reviewed-by: Stanislav Lisovskiy 

>   for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state,
>new_plane_state, i) {
>   if (plane->pipe != crtc->pipe)
> -- 
> 2.41.0
> 


Re: [PATCH 9/9] Revert "drm/i915/xe2lpd: Treat cursor plane as regular plane for DDB allocation"

2023-12-13 Thread Lisovskiy, Stanislav
On Wed, Dec 13, 2023 at 12:25:19PM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> This reverts commit cfeff354f70bb1d0deb0279506e3f7989bc16e28.
> 
> A core design consideration with legacy cursor updates is that the
> cursor must not touch any other plane, even if we were to force it
> to take the slow path. That is the real reason why the cursor uses
> a fixed ddb allocation, not because bspec says so.
> 
> Treating cursors as any other plane during ddb allocation
> violates that, which means we can now pull other planes into
> fully unsynced legacy cursor mailbox commits. That is
> definitely not something we've ever considered when designing
> the rest of the code. The noarm+arm register write split in
> particular makes that dangerous as previous updates can get
> disarmed pretty much at any random time, and not necessarily
> in an order that is actually safe (eg. against ddb overlaps).
> 
> So if we were to do this then:
> - someone needs to expend the appropriate amount of brain
>   cells thinking through all the tricky details

So question is how can we avoid pulling other planes to the commit?..


Stan

> - we should do it for all skl+ platforms since all
>   of those have double buffered wm/ddb registers. The current
>   arbitrary mtl+ cutoff doesn't really make sense
> 
> For the moment just go back to the original behaviour where
> the cursor's ddb alloation does not change outside of
> modeset/fastset. As of now anything else isn't safe.
> 
> Cc: Stanislav Lisovskiy 
> Cc: Matt Roper 
> Cc: Lucas De Marchi 
> Signed-off-by: Ville Syrjälä 
> ---
>  .../gpu/drm/i915/display/intel_atomic_plane.c|  6 +++---
>  drivers/gpu/drm/i915/display/skl_watermark.c | 16 +++-
>  2 files changed, 10 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c 
> b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> index 06c2455bdd78..76d77d5a0409 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> @@ -217,6 +217,9 @@ intel_plane_relative_data_rate(const struct 
> intel_crtc_state *crtc_state,
>   int width, height;
>   unsigned int rel_data_rate;
>  
> + if (plane->id == PLANE_CURSOR)
> + return 0;
> +
>   if (!plane_state->uapi.visible)
>   return 0;
>  
> @@ -244,9 +247,6 @@ intel_plane_relative_data_rate(const struct 
> intel_crtc_state *crtc_state,
>  
>   rel_data_rate = width * height * fb->format->cpp[color_plane];
>  
> - if (plane->id == PLANE_CURSOR)
> - return rel_data_rate;
> -
>   return intel_adjusted_rate(_state->uapi.src,
>  _state->uapi.dst,
>  rel_data_rate);
> diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c 
> b/drivers/gpu/drm/i915/display/skl_watermark.c
> index 56588d6e24ae..051a02ac01a4 100644
> --- a/drivers/gpu/drm/i915/display/skl_watermark.c
> +++ b/drivers/gpu/drm/i915/display/skl_watermark.c
> @@ -1367,7 +1367,7 @@ skl_total_relative_data_rate(const struct 
> intel_crtc_state *crtc_state)
>   u64 data_rate = 0;
>  
>   for_each_plane_id_on_crtc(crtc, plane_id) {
> - if (plane_id == PLANE_CURSOR && DISPLAY_VER(i915) < 20)
> + if (plane_id == PLANE_CURSOR)
>   continue;
>  
>   data_rate += crtc_state->rel_data_rate[plane_id];
> @@ -1514,12 +1514,10 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state 
> *state,
>   return 0;
>  
>   /* Allocate fixed number of blocks for cursor. */
> - if (DISPLAY_VER(i915) < 20) {
> - cursor_size = skl_cursor_allocation(crtc_state, num_active);
> - iter.size -= cursor_size;
> - skl_ddb_entry_init(_state->wm.skl.plane_ddb[PLANE_CURSOR],
> -alloc->end - cursor_size, alloc->end);
> - }
> + cursor_size = skl_cursor_allocation(crtc_state, num_active);
> + iter.size -= cursor_size;
> + skl_ddb_entry_init(_state->wm.skl.plane_ddb[PLANE_CURSOR],
> +alloc->end - cursor_size, alloc->end);
>  
>   iter.data_rate = skl_total_relative_data_rate(crtc_state);
>  
> @@ -1533,7 +1531,7 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state 
> *state,
>   const struct skl_plane_wm *wm =
>   _state->wm.skl.optimal.planes[plane_id];
>  
> - if (plane_id == PLANE_CURSOR && DISPLAY_VER(i915) < 20) 
> {
> + if (plane_id == PLANE_CURSOR) {
>   const struct skl_ddb_entry *ddb =
>   _state->wm.skl.plane_ddb[plane_id];
>  
> @@ -1581,7 +1579,7 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state 
> *state,
>   const struct skl_plane_wm *wm =
>   _state->wm.skl.optimal.planes[plane_id];
>  
> - if (plane_id 

Re: [Intel-gfx] [PATCH] drm/i915/cdclk: Remove divider field from tables

2023-11-28 Thread Lisovskiy, Stanislav
On Tue, Nov 28, 2023 at 10:43:36AM +0200, Ville Syrjälä wrote:
> On Mon, Nov 27, 2023 at 08:21:46AM -0800, Matt Roper wrote:
> > On Fri, Nov 24, 2023 at 05:55:23PM -0300, Gustavo Sousa wrote:
> > > The cdclk tables were introduced with commit 736da8112fee ("drm/i915:
> > > Use literal representation of cdclk tables"). It has been almost 4 years
> > > and the divider field was not really used yet. Let's remove it.
> > 
> > I think we need to go the other way and actually start using it instead
> > of (incorrectly) trying to re-derive it from cdclk->vco.  The logic the
> > driver is using today doesn't account for the potential use of
> > squashing, which means we program the wrong divider value into CDCLK_CTL
> > in some cases.  I pointed that out during the LNL code reviews a couple
> > months ago, and I believe Stan is working on fixing that.
> 
> The code should be correct as is, but it does assume that the cd2x
> divider is 2 when squashing is used. If that no longer holds then we
> have to change something.

So we need to have some kind of a consensus/agreement here, whether are we 
modify the
calculation function and remove divider from the table, or do we just
use the value from the table.

So which approach is better?

Stan

> 
> > 
> > I wonder if the misprogramming we're doing today is what requires the
> > "HACK" at the bottom of intel_crtc_compute_min_cdclk for DG2?
> > 
> > 
> > Matt
> > 
> > > 
> > > Cc: Matt Roper 
> > > Cc: Ville Syrjälä 
> > > Signed-off-by: Gustavo Sousa 
> > > ---
> > >  drivers/gpu/drm/i915/display/intel_cdclk.c | 269 ++---
> > >  1 file changed, 134 insertions(+), 135 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c 
> > > b/drivers/gpu/drm/i915/display/intel_cdclk.c
> > > index b93d1ad7936d..7f85a216ff5c 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_cdclk.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
> > > @@ -1227,183 +1227,182 @@ struct intel_cdclk_vals {
> > >   u32 cdclk;
> > >   u16 refclk;
> > >   u16 waveform;
> > > - u8 divider; /* CD2X divider * 2 */
> > >   u8 ratio;
> > >  };
> > >  
> > >  static const struct intel_cdclk_vals bxt_cdclk_table[] = {
> > > - { .refclk = 19200, .cdclk = 144000, .divider = 8, .ratio = 60 },
> > > - { .refclk = 19200, .cdclk = 288000, .divider = 4, .ratio = 60 },
> > > - { .refclk = 19200, .cdclk = 384000, .divider = 3, .ratio = 60 },
> > > - { .refclk = 19200, .cdclk = 576000, .divider = 2, .ratio = 60 },
> > > - { .refclk = 19200, .cdclk = 624000, .divider = 2, .ratio = 65 },
> > > + { .refclk = 19200, .cdclk = 144000, .ratio = 60 },
> > > + { .refclk = 19200, .cdclk = 288000, .ratio = 60 },
> > > + { .refclk = 19200, .cdclk = 384000, .ratio = 60 },
> > > + { .refclk = 19200, .cdclk = 576000, .ratio = 60 },
> > > + { .refclk = 19200, .cdclk = 624000, .ratio = 65 },
> > >   {}
> > >  };
> > >  
> > >  static const struct intel_cdclk_vals glk_cdclk_table[] = {
> > > - { .refclk = 19200, .cdclk =  79200, .divider = 8, .ratio = 33 },
> > > - { .refclk = 19200, .cdclk = 158400, .divider = 4, .ratio = 33 },
> > > - { .refclk = 19200, .cdclk = 316800, .divider = 2, .ratio = 33 },
> > > + { .refclk = 19200, .cdclk =  79200, .ratio = 33 },
> > > + { .refclk = 19200, .cdclk = 158400, .ratio = 33 },
> > > + { .refclk = 19200, .cdclk = 316800, .ratio = 33 },
> > >   {}
> > >  };
> > >  
> > >  static const struct intel_cdclk_vals icl_cdclk_table[] = {
> > > - { .refclk = 19200, .cdclk = 172800, .divider = 2, .ratio = 18 },
> > > - { .refclk = 19200, .cdclk = 192000, .divider = 2, .ratio = 20 },
> > > - { .refclk = 19200, .cdclk = 307200, .divider = 2, .ratio = 32 },
> > > - { .refclk = 19200, .cdclk = 326400, .divider = 4, .ratio = 68 },
> > > - { .refclk = 19200, .cdclk = 556800, .divider = 2, .ratio = 58 },
> > > - { .refclk = 19200, .cdclk = 652800, .divider = 2, .ratio = 68 },
> > > -
> > > - { .refclk = 24000, .cdclk = 18, .divider = 2, .ratio = 15 },
> > > - { .refclk = 24000, .cdclk = 192000, .divider = 2, .ratio = 16 },
> > > - { .refclk = 24000, .cdclk = 312000, .divider = 2, .ratio = 26 },
> > > - { .refclk = 24000, .cdclk = 324000, .divider = 4, .ratio = 54 },
> > > - { .refclk = 24000, .cdclk = 552000, .divider = 2, .ratio = 46 },
> > > - { .refclk = 24000, .cdclk = 648000, .divider = 2, .ratio = 54 },
> > > -
> > > - { .refclk = 38400, .cdclk = 172800, .divider = 2, .ratio =  9 },
> > > - { .refclk = 38400, .cdclk = 192000, .divider = 2, .ratio = 10 },
> > > - { .refclk = 38400, .cdclk = 307200, .divider = 2, .ratio = 16 },
> > > - { .refclk = 38400, .cdclk = 326400, .divider = 4, .ratio = 34 },
> > > - { .refclk = 38400, .cdclk = 556800, .divider = 2, .ratio = 29 },
> > > - { .refclk = 38400, .cdclk = 652800, .divider = 2, .ratio = 34 },
> > > + { .refclk = 19200, .cdclk = 172800, .ratio = 18 },
> > > + { .refclk = 19200, .cdclk = 192000, .ratio = 20 },
> > > + { .refclk = 19200, .cdclk = 307200, .ratio = 32 },
> > > + { .refclk = 19200, .cdclk = 

Re: [Intel-gfx] [PATCH v2 09/11] drm/i915/dp: Report a rounded-down value as the maximum data rate

2023-11-17 Thread Lisovskiy, Stanislav
On Thu, Nov 16, 2023 at 03:18:39PM +0200, Imre Deak wrote:
> Callers of intel_dp_max_data_rate() use the return value as an upper
> bound for the BW a given mode requires. As such the rounding shouldn't
> result in a bigger value than the actual upper bound. Use round-down
> instead of -closest accordingly.
> 
> Cc: Jani Nikula 
> Signed-off-by: Imre Deak 

LGTM,

Reviewed-by: Stanislav Lisovskiy 

> ---
>  drivers/gpu/drm/i915/display/intel_dp.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index 120d435d27ff1..209c27167e057 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -413,7 +413,7 @@ intel_dp_max_data_rate(int max_link_rate, int max_lanes)
>*/
>   int max_link_rate_kbps = max_link_rate * 10;
>  
> - max_link_rate_kbps = 
> DIV_ROUND_CLOSEST_ULL(mul_u32_u32(max_link_rate_kbps, 9671), 1);
> + max_link_rate_kbps = 
> DIV_ROUND_DOWN_ULL(mul_u32_u32(max_link_rate_kbps, 9671), 1);
>   max_link_rate = max_link_rate_kbps / 8;
>   }
>  
> @@ -423,7 +423,7 @@ intel_dp_max_data_rate(int max_link_rate, int max_lanes)
>* out to be a nop by coincidence, and can be skipped:
>*
>*  int max_link_rate_kbps = max_link_rate * 10;
> -  *  max_link_rate_kbps = DIV_ROUND_CLOSEST_ULL(max_link_rate_kbps * 
> 8, 10);
> +  *  max_link_rate_kbps = DIV_ROUND_DOWN_ULL(max_link_rate_kbps * 8, 
> 10);
>*  max_link_rate = max_link_rate_kbps / 8;
>*/
>  
> -- 
> 2.39.2
> 


Re: [Intel-gfx] [PATCH 2/3] drm/i915: Split intel_update_crtc() into two parts

2023-11-08 Thread Lisovskiy, Stanislav
On Thu, Sep 07, 2023 at 03:25:40PM +0300, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> Split intel_update_crtc() into two parts such that the first
> part performs all the non-vblank evasion preparatory stuff,
> and the second part just does the vblank evasion stuff.
> 
> For now we just call these back to back so that there is
> no funcitonal change.
> 
> Signed-off-by: Ville Syrjälä 

Reviewed-by: Stanislav Lisovskiy 

> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 16 ++--
>  1 file changed, 14 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> b/drivers/gpu/drm/i915/display/intel_display.c
> index 526f38b502be..7c19a0f380ca 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -6542,8 +6542,8 @@ static void intel_enable_crtc(struct intel_atomic_state 
> *state,
>   intel_crtc_enable_pipe_crc(crtc);
>  }
>  
> -static void intel_update_crtc(struct intel_atomic_state *state,
> -   struct intel_crtc *crtc)
> +static void intel_pre_update_crtc(struct intel_atomic_state *state,
> +   struct intel_crtc *crtc)
>  {
>   struct drm_i915_private *i915 = to_i915(state->base.dev);
>   const struct intel_crtc_state *old_crtc_state =
> @@ -6588,6 +6588,15 @@ static void intel_update_crtc(struct 
> intel_atomic_state *state,
>   intel_color_commit_noarm(new_crtc_state);
>  
>   intel_crtc_planes_update_noarm(state, crtc);
> +}
> +
> +static void intel_update_crtc(struct intel_atomic_state *state,
> +   struct intel_crtc *crtc)
> +{
> + const struct intel_crtc_state *old_crtc_state =
> + intel_atomic_get_old_crtc_state(state, crtc);
> + struct intel_crtc_state *new_crtc_state =
> + intel_atomic_get_new_crtc_state(state, crtc);
>  
>   /* Perform vblank evasion around commit operation */
>   intel_pipe_update_start(new_crtc_state);
> @@ -6701,6 +6710,7 @@ static void intel_commit_modeset_enables(struct 
> intel_atomic_state *state)
>   continue;
>  
>   intel_enable_crtc(state, crtc);
> + intel_pre_update_crtc(state, crtc);
>   intel_update_crtc(state, crtc);
>   }
>  }
> @@ -6753,6 +6763,7 @@ static void skl_commit_modeset_enables(struct 
> intel_atomic_state *state)
>   entries[pipe] = new_crtc_state->wm.skl.ddb;
>   update_pipes &= ~BIT(pipe);
>  
> + intel_pre_update_crtc(state, crtc);
>   intel_update_crtc(state, crtc);
>  
>   /*
> @@ -6820,6 +6831,7 @@ static void skl_commit_modeset_enables(struct 
> intel_atomic_state *state)
>   entries[pipe] = new_crtc_state->wm.skl.ddb;
>   update_pipes &= ~BIT(pipe);
>  
> + intel_pre_update_crtc(state, crtc);
>   intel_update_crtc(state, crtc);
>   }
>  
> -- 
> 2.41.0
> 


Re: [Intel-gfx] [PATCH v5 25/30] drm/i915/dp_mst: Enable MST DSC decompression for all streams

2023-11-08 Thread Lisovskiy, Stanislav
On Tue, Nov 07, 2023 at 02:15:03AM +0200, Imre Deak wrote:
> Enable DSC decompression for all streams. In particular atm if a sink is
> connected to a last branch device that is downstream of the first branch
> device connected to the source, decompression is not enabled for it.
> Similarly it's not enabled if the sink supports this with the last
> branch device passing through the compressed stream to it.
> 
> Enable DSC in the above cases as well. Since last branch devices may
> handle the decompression for multiple ports, toggling DSC needs to be
> refcounted, add this using the DSC AUX device as a reference.
> 
> v2:
> - Fix refcounting, setting/clearing
>   connector->dp.dsc_decompression_enabled always as needed. (Stan)
> - Make the refcounting more uniform for the SST vs. MST case.
> - Add state checks for connector->dp.dsc_decompression_enabled and
>   connector crtc.
> - Sanitize connector DSC decompression state during HW setup.
> - s/use_count/ref_count/
> v3:
> - Remove stale TODO: comment to set the actual decompression_aux.

Reviewed-by: Stanislav Lisovskiy 

> 
> Cc: Stanislav Lisovskiy 
> Signed-off-by: Imre Deak 
> ---
>  .../drm/i915/display/intel_display_types.h|  1 +
>  drivers/gpu/drm/i915/display/intel_dp.c   | 72 ++-
>  drivers/gpu/drm/i915/display/intel_dp_mst.c   | 24 ++-
>  .../drm/i915/display/intel_modeset_setup.c|  6 ++
>  4 files changed, 82 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
> b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 6c2f18ef543e4..0a5508c90e8bc 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -626,6 +626,7 @@ struct intel_connector {
>   u8 fec_capability;
>  
>   u8 dsc_hblank_expansion_quirk:1;
> + u8 dsc_decompression_enabled:1;
>   } dp;
>  
>   /* Work struct to schedule a uevent on link train failure */
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index bea0c03b94835..3fee371529f17 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -1403,6 +1403,7 @@ static bool intel_dp_supports_dsc(const struct 
> intel_connector *connector,
>   return false;
>  
>   return intel_dsc_source_support(crtc_state) &&
> + connector->dp.dsc_decompression_aux &&
>   drm_dp_sink_supports_dsc(connector->dp.dsc_dpcd);
>  }
>  
> @@ -2986,6 +2987,65 @@ intel_dp_sink_set_dsc_passthrough(const struct 
> intel_connector *connector,
>   str_enable_disable(enable));
>  }
>  
> +static int intel_dp_dsc_aux_ref_count(struct intel_atomic_state *state,
> +   const struct intel_connector *connector,
> +   bool for_get_ref)
> +{
> + struct drm_i915_private *i915 = to_i915(state->base.dev);
> + struct drm_connector *_connector_iter;
> + struct drm_connector_state *old_conn_state;
> + struct drm_connector_state *new_conn_state;
> + int ref_count = 0;
> + int i;
> +
> + /*
> +  * On SST the decompression AUX device won't be shared, each connector
> +  * uses for this its own AUX targeting the sink device.
> +  */
> + if (!connector->mst_port)
> + return connector->dp.dsc_decompression_enabled ? 1 : 0;
> +
> + for_each_oldnew_connector_in_state(>base, _connector_iter,
> +old_conn_state, new_conn_state, i) {
> + const struct intel_connector *
> + connector_iter = to_intel_connector(_connector_iter);
> +
> + if (connector_iter->mst_port != connector->mst_port)
> + continue;
> +
> + if (!connector_iter->dp.dsc_decompression_enabled)
> + continue;
> +
> + drm_WARN_ON(>drm,
> + (for_get_ref && !new_conn_state->crtc) ||
> + (!for_get_ref && !old_conn_state->crtc));
> +
> + if (connector_iter->dp.dsc_decompression_aux ==
> + connector->dp.dsc_decompression_aux)
> + ref_count++;
> + }
> +
> + return ref_count;
> +}
> +
> +static bool intel_dp_dsc_aux_get_ref(struct intel_atomic_state *state,
> +  struct intel_connector *connector)
> +{
> + bool ret = intel_dp_dsc_aux_ref_count(state, connector, true) == 0;
> +
> + connector->dp.dsc_decompression_enabled = true;
> +
> + return ret;
> +}
> +
> +static bool intel_dp_dsc_aux_put_ref(struct intel_atomic_state *state,
> +  struct intel_connector *connector)
> +{
> + connector->dp.dsc_decompression_enabled = false;
> +
> + return intel_dp_dsc_aux_ref_count(state, connector, false) == 0;
> +}
> +
>  /**
>   * 

Re: [Intel-gfx] [PATCH v4 01/30] drm/i915/dp_mst: Fix race between connector registration and setup

2023-10-31 Thread Lisovskiy, Stanislav
On Mon, Oct 30, 2023 at 05:58:14PM +0200, Imre Deak wrote:
> After drm_connector_init() is called the connector is visible to the
> rest of the kernel via the drm_mode_config::connector_list. Make
> sure that the DSC AUX device and capabilities are setup by that time.
> 
> Another race condition is adding the connector to the connector list
> before drm_connector_helper_add() sets the connector helper functions.
> That's an unrelated issue, for which the fix is for a follow-up. One
> solution would be adding the connector to the connector list only
> during its registration in drm_connector_register().

Reviewed-by: Stanislav Lisovskiy 

> 
> Cc: Stanislav Lisovskiy 
> Cc: Ville Syrjälä 
> Fixes: 808b43fa7e56 ("drm/i915/dp_mst: Set connector DSC capabilities and 
> decompression AUX")
> Signed-off-by: Imre Deak 
> ---
>  drivers/gpu/drm/i915/display/intel_dp_mst.c | 16 
>  1 file changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index 7b4628f4f1240..851b312bd8449 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -1161,6 +1161,14 @@ static struct drm_connector 
> *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
>   intel_connector->port = port;
>   drm_dp_mst_get_port_malloc(port);
>  
> + /*
> +  * TODO: set the AUX for the actual MST port decompressing the stream.
> +  * At the moment the driver only supports enabling this globally in the
> +  * first downstream MST branch, via intel_dp's (root port) AUX.
> +  */
> + intel_connector->dp.dsc_decompression_aux = _dp->aux;
> + intel_dp_mst_read_decompression_port_dsc_caps(intel_dp, 
> intel_connector);
> +
>   connector = _connector->base;
>   ret = drm_connector_init(dev, connector, _dp_mst_connector_funcs,
>DRM_MODE_CONNECTOR_DisplayPort);
> @@ -1172,14 +1180,6 @@ static struct drm_connector 
> *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
>  
>   drm_connector_helper_add(connector, 
> _dp_mst_connector_helper_funcs);
>  
> - /*
> -  * TODO: set the AUX for the actual MST port decompressing the stream.
> -  * At the moment the driver only supports enabling this globally in the
> -  * first downstream MST branch, via intel_dp's (root port) AUX.
> -  */
> - intel_connector->dp.dsc_decompression_aux = _dp->aux;
> - intel_dp_mst_read_decompression_port_dsc_caps(intel_dp, 
> intel_connector);
> -
>   for_each_pipe(dev_priv, pipe) {
>   struct drm_encoder *enc =
>   _dp->mst_encoders[pipe]->base.base;
> -- 
> 2.39.2
> 


Re: [Intel-gfx] [PATCH v4 25/30] drm/i915/dp_mst: Enable MST DSC decompression for all streams

2023-10-31 Thread Lisovskiy, Stanislav
On Mon, Oct 30, 2023 at 05:58:38PM +0200, Imre Deak wrote:
> Enable DSC decompression for all streams. In particular atm if a sink is
> connected to a last branch device that is downstream of the first branch
> device connected to the source, decompression is not enabled for it.
> Similarly it's not enabled if the sink supports this with the last
> branch device passing through the compressed stream to it.
> 
> Enable DSC in the above cases as well. Since last branch devices may
> handle the decompression for multiple ports, toggling DSC needs to be
> refcounted, add this using the DSC AUX device as a reference.
> 
> v2:
> 
> - Fix refcounting, setting/clearing
>   connector->dp.dsc_decompression_enabled always as needed. (Stan)
> - Make the refcounting more uniform for the SST vs. MST case.
> - Add state checks for connector->dp.dsc_decompression_enabled and
>   connector crtc.
> - Sanitize connector DSC decompression state during HW setup.
> - s/use_count/ref_count/

Reviewed-by: Stanislav Lisovskiy 

> 
> Cc: Stanislav Lisovskiy 
> Signed-off-by: Imre Deak 
> ---
>  .../drm/i915/display/intel_display_types.h|  1 +
>  drivers/gpu/drm/i915/display/intel_dp.c   | 72 ++-
>  drivers/gpu/drm/i915/display/intel_dp_mst.c   | 19 ++---
>  .../drm/i915/display/intel_modeset_setup.c|  6 ++
>  4 files changed, 82 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
> b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 409dbf8a2a1cd..b2744a9b4678c 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -626,6 +626,7 @@ struct intel_connector {
>   u8 fec_capability;
>  
>   u8 dsc_hblank_expansion_quirk:1;
> + u8 dsc_decompression_enabled:1;
>   } dp;
>  
>   /* Work struct to schedule a uevent on link train failure */
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index 8bc4faa142a62..6d2fd068b8359 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -1403,6 +1403,7 @@ static bool intel_dp_supports_dsc(const struct 
> intel_connector *connector,
>   return false;
>  
>   return intel_dsc_source_support(crtc_state) &&
> + connector->dp.dsc_decompression_aux &&
>   drm_dp_sink_supports_dsc(connector->dp.dsc_dpcd);
>  }
>  
> @@ -2986,6 +2987,65 @@ intel_dp_sink_set_dsc_passthrough(const struct 
> intel_connector *connector,
>   str_enable_disable(enable));
>  }
>  
> +static int intel_dp_dsc_aux_ref_count(struct intel_atomic_state *state,
> +   const struct intel_connector *connector,
> +   bool for_get_ref)
> +{
> + struct drm_i915_private *i915 = to_i915(state->base.dev);
> + struct drm_connector *_connector_iter;
> + struct drm_connector_state *old_conn_state;
> + struct drm_connector_state *new_conn_state;
> + int ref_count = 0;
> + int i;
> +
> + /*
> +  * On SST the decompression AUX device won't be shared, each connector
> +  * uses for this its own AUX targeting the sink device.
> +  */
> + if (!connector->mst_port)
> + return connector->dp.dsc_decompression_enabled ? 1 : 0;
> +
> + for_each_oldnew_connector_in_state(>base, _connector_iter,
> +old_conn_state, new_conn_state, i) {
> + const struct intel_connector *
> + connector_iter = to_intel_connector(_connector_iter);
> +
> + if (connector_iter->mst_port != connector->mst_port)
> + continue;
> +
> + if (!connector_iter->dp.dsc_decompression_enabled)
> + continue;
> +
> + drm_WARN_ON(>drm,
> + (for_get_ref && !new_conn_state->crtc) ||
> + (!for_get_ref && !old_conn_state->crtc));
> +
> + if (connector_iter->dp.dsc_decompression_aux ==
> + connector->dp.dsc_decompression_aux)
> + ref_count++;
> + }
> +
> + return ref_count;
> +}
> +
> +static bool intel_dp_dsc_aux_get_ref(struct intel_atomic_state *state,
> +  struct intel_connector *connector)
> +{
> + bool ret = intel_dp_dsc_aux_ref_count(state, connector, true) == 0;
> +
> + connector->dp.dsc_decompression_enabled = true;
> +
> + return ret;
> +}
> +
> +static bool intel_dp_dsc_aux_put_ref(struct intel_atomic_state *state,
> +  struct intel_connector *connector)
> +{
> + connector->dp.dsc_decompression_enabled = false;
> +
> + return intel_dp_dsc_aux_ref_count(state, connector, false) == 0;
> +}
> +
>  /**
>   * intel_dp_sink_enable_decompression - Enable DSC decompression in 
> 

Re: [Intel-gfx] [PATCH 24/29] drm/i915/dp_mst: Enable MST DSC decompression for all streams

2023-10-30 Thread Lisovskiy, Stanislav
On Fri, Oct 27, 2023 at 05:53:17PM +0300, Imre Deak wrote:
> On Fri, Oct 27, 2023 at 05:45:30PM +0300, Lisovskiy, Stanislav wrote:
> > On Tue, Oct 24, 2023 at 04:09:20AM +0300, Imre Deak wrote:
> > > Enable DSC decompression for all streams. In particular atm if a sink is
> > > connected to a last branch device that is downstream of the first branch
> > > device connected to the source, decompression is not enabled for it.
> > > Similarly it's not enabled if the sink supports this with the last
> > > branch device passing through the compressed stream to it.
> > > 
> > > Enable DSC in the above cases as well. Since last branch devices may
> > > handle the decompression for multiple ports, toggling DSC needs to be
> > > refcounted, add this using the DSC AUX device as a reference.
> > > 
> > > Signed-off-by: Imre Deak 
> > > ---
> > >  .../drm/i915/display/intel_display_types.h|  1 +
> > >  drivers/gpu/drm/i915/display/intel_dp.c   |  3 +
> > >  drivers/gpu/drm/i915/display/intel_dp_mst.c   | 57 ---
> > >  3 files changed, 42 insertions(+), 19 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
> > > b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > index 409dbf8a2a1cd..b2744a9b4678c 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> > > +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> > > @@ -626,6 +626,7 @@ struct intel_connector {
> > >   u8 fec_capability;
> > >  
> > >   u8 dsc_hblank_expansion_quirk:1;
> > > + u8 dsc_decompression_enabled:1;
> > >   } dp;
> > >  
> > >   /* Work struct to schedule a uevent on link train failure */
> > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> > > b/drivers/gpu/drm/i915/display/intel_dp.c
> > > index bb8951f89f61f..c89e1a4393d0f 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > > @@ -1403,6 +1403,7 @@ static bool intel_dp_supports_dsc(const struct 
> > > intel_connector *connector,
> > >   return false;
> > >  
> > >   return intel_dsc_source_support(crtc_state) &&
> > > + connector->dp.dsc_decompression_aux &&
> > >   drm_dp_sink_supports_dsc(connector->dp.dsc_dpcd);
> > >  }
> > >  
> > > @@ -2948,6 +2949,8 @@ intel_dp_sink_set_dsc_decompression(struct 
> > > intel_connector *connector,
> > >   drm_dbg_kms(>drm,
> > >   "Failed to %s sink decompression state\n",
> > >   str_enable_disable(enable));
> > > +
> > > + connector->dp.dsc_decompression_enabled = enable;
> > >  }
> > >  
> > >  static void
> > > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
> > > b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > index 8ef3a2611207c..9f4894c2e7860 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > > @@ -660,6 +660,39 @@ intel_dp_mst_atomic_topology_check(struct 
> > > intel_connector *connector,
> > >   return ret;
> > >  }
> > >  
> > > +static int intel_dp_mst_dsc_aux_use_count(struct intel_atomic_state 
> > > *state,
> > > +   const struct intel_connector 
> > > *connector)
> > > +{
> > > + struct intel_connector *connector_iter;
> > > + struct intel_digital_connector_state *conn_state;
> > > + int use_count = 0;
> > > + int i;
> > > +
> > > + for_each_new_intel_connector_in_state(state, connector_iter, 
> > > conn_state, i) {
> > > + if (connector_iter->mst_port != connector->mst_port ||
> > > + !conn_state->base.crtc)
> > > + continue;
> > > +
> > > + if (!connector_iter->dp.dsc_decompression_enabled)
> > > + continue;
> > > +
> > > + if (connector_iter->dp.dsc_decompression_aux ==
> > > + connector->dp.dsc_decompression_aux)
> > > + use_count++;
> > > + }
> > > +
> > > + return use_count;
> > > +}
> > > +
> > > +static void intel_dp_mst_sink_set_decompression_state(struct 
> > > intel_atomic_st

Re: [Intel-gfx] [PATCH 25/29] drm/i915: Factor out function to clear pipe update flags

2023-10-27 Thread Lisovskiy, Stanislav
On Tue, Oct 24, 2023 at 04:09:21AM +0300, Imre Deak wrote:
> Factor out a helper to clear the pipe update flags, used by a follow-up
> patch to modeset an MST topology.
> 
> Signed-off-by: Imre Deak 


Was willing to do that myself :)) Spotted when doing bigjoiner related
refactoring, thanks for doing.

Reviewed-by: Stanislav Lisovskiy 

> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 52 ++--
>  1 file changed, 27 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> b/drivers/gpu/drm/i915/display/intel_display.c
> index de352d9c43439..22f88389035bd 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -5551,6 +5551,16 @@ int intel_modeset_pipes_in_mask_early(struct 
> intel_atomic_state *state,
>   return 0;
>  }
>  
> +static void clear_pipe_update_flags_on_modeset_crtc(struct intel_crtc_state 
> *crtc_state)
> +{
> + if (!intel_crtc_needs_modeset(crtc_state))
> + return;
> +
> + crtc_state->update_pipe = false;
> + crtc_state->update_m_n = false;
> + crtc_state->update_lrr = false;
> +}
> +
>  /**
>   * intel_modeset_all_pipes_late - force a full modeset on all pipes
>   * @state: intel atomic state
> @@ -5584,9 +5594,8 @@ int intel_modeset_all_pipes_late(struct 
> intel_atomic_state *state,
>   if (ret)
>   return ret;
>  
> - crtc_state->update_pipe = false;
> - crtc_state->update_m_n = false;
> - crtc_state->update_lrr = false;
> + clear_pipe_update_flags_on_modeset_crtc(crtc_state);
> +
>   crtc_state->update_planes |= crtc_state->active_planes;
>   crtc_state->async_flip_planes = 0;
>   crtc_state->do_async_flip = false;
> @@ -5699,13 +5708,13 @@ static void intel_crtc_check_fastset(const struct 
> intel_crtc_state *old_crtc_sta
>   else
>   new_crtc_state->uapi.mode_changed = false;
>  
> - if (intel_crtc_needs_modeset(new_crtc_state) ||
> - intel_compare_link_m_n(_crtc_state->dp_m_n,
> + clear_pipe_update_flags_on_modeset_crtc(new_crtc_state);
> +
> + if (intel_compare_link_m_n(_crtc_state->dp_m_n,
>  _crtc_state->dp_m_n))
>   new_crtc_state->update_m_n = false;
>  
> - if (intel_crtc_needs_modeset(new_crtc_state) ||
> - (old_crtc_state->hw.adjusted_mode.crtc_vtotal == 
> new_crtc_state->hw.adjusted_mode.crtc_vtotal &&
> + if ((old_crtc_state->hw.adjusted_mode.crtc_vtotal == 
> new_crtc_state->hw.adjusted_mode.crtc_vtotal &&
>old_crtc_state->hw.adjusted_mode.crtc_vblank_end == 
> new_crtc_state->hw.adjusted_mode.crtc_vblank_end))
>   new_crtc_state->update_lrr = false;
>  
> @@ -6484,12 +6493,9 @@ int intel_atomic_check(struct drm_device *dev,
>   if (intel_dp_mst_is_slave_trans(new_crtc_state)) {
>   enum transcoder master = 
> new_crtc_state->mst_master_transcoder;
>  
> - if (intel_cpu_transcoders_need_modeset(state, 
> BIT(master))) {
> - new_crtc_state->uapi.mode_changed = true;
> - new_crtc_state->update_pipe = false;
> - new_crtc_state->update_m_n = false;
> - new_crtc_state->update_lrr = false;
> - }
> + if (intel_cpu_transcoders_need_modeset(state, 
> BIT(master)))
> + intel_modeset_pipes_in_mask_early(state, "MST 
> master transcoder",
> +   
> BIT(crtc->pipe));
>   }
>  
>   if (is_trans_port_sync_mode(new_crtc_state)) {
> @@ -6498,22 +6504,18 @@ int intel_atomic_check(struct drm_device *dev,
>   if (new_crtc_state->master_transcoder != 
> INVALID_TRANSCODER)
>   trans |= BIT(new_crtc_state->master_transcoder);
>  
> - if (intel_cpu_transcoders_need_modeset(state, trans)) {
> - new_crtc_state->uapi.mode_changed = true;
> - new_crtc_state->update_pipe = false;
> - new_crtc_state->update_m_n = false;
> - new_crtc_state->update_lrr = false;
> - }
> + if (intel_cpu_transcoders_need_modeset(state, trans))
> + intel_modeset_pipes_in_mask_early(state, "port 
> sync",
> +   
> BIT(crtc->pipe));
>   }
>  
>   if (new_crtc_state->bigjoiner_pipes) {
> - if (intel_pipes_need_modeset(state, 
> new_crtc_state->bigjoiner_pipes)) {
> - new_crtc_state->uapi.mode_changed = true;
> - 

Re: [Intel-gfx] [PATCH 10/29] drm/i915/dp: Specify the FEC overhead as an increment vs. a remainder

2023-10-27 Thread Lisovskiy, Stanislav
On Tue, Oct 24, 2023 at 04:09:06AM +0300, Imre Deak wrote:
> A follow-up patch will add up all the overheads on a DP link, where it
> makes more sense to specify each overhead factor in terms of the added
> overhead amount vs. the reciprocal remainder (of usable BW remaining
> after deducting the overhead). Prepare for that here, keeping the
> existing behavior.
> 
> Signed-off-by: Imre Deak 

Reviewed-by: Stanislav Lisovskiy 

> ---
>  drivers/gpu/drm/i915/display/intel_dp.c | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index 2048649b420b2..0c0f026fb3161 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -85,8 +85,8 @@
>  #define DP_DSC_MAX_ENC_THROUGHPUT_0  34
>  #define DP_DSC_MAX_ENC_THROUGHPUT_1  40
>  
> -/* DP DSC FEC Overhead factor = 1/(0.972261) */
> -#define DP_DSC_FEC_OVERHEAD_FACTOR   972261
> +/* DP DSC FEC Overhead factor = 1/(0.972261) = 1.028530 ppm */
> +#define DP_DSC_FEC_OVERHEAD_FACTOR   1028530
>  
>  /* Compliance test status bits  */
>  #define INTEL_DP_RESOLUTION_SHIFT_MASK   0
> @@ -680,8 +680,8 @@ int intel_dp_get_link_train_fallback_values(struct 
> intel_dp *intel_dp,
>  
>  u32 intel_dp_mode_to_fec_clock(u32 mode_clock)
>  {
> - return div_u64(mul_u32_u32(mode_clock, 100U),
> -DP_DSC_FEC_OVERHEAD_FACTOR);
> + return div_u64(mul_u32_u32(mode_clock, DP_DSC_FEC_OVERHEAD_FACTOR),
> +100U);
>  }
>  
>  static int
> -- 
> 2.39.2
> 


Re: [Intel-gfx] [PATCH 12/29] drm/i915/dp_mst: Account for FEC and DSC overhead during BW allocation

2023-10-27 Thread Lisovskiy, Stanislav
On Tue, Oct 24, 2023 at 04:09:08AM +0300, Imre Deak wrote:
> Atm, the BW allocated for an MST stream doesn't take into account the
> DSC control symbol (EOC) and data alignment overhead on the local (first
> downstream) MST link (reflected by the data M/N/TU values) and - besides
> the above overheads - the FEC symbol overhead on 8b/10b remote
> (after a downstream branch device) MST links.
> 
> In addition the FEC overhead used on the local link is a fixed amount,
> which only applies to certain modes, but not enough for all modes; add a
> code comment clarifying this.
> 
> Fix the above by calculating the data M/N values with the total BW
> overhead (not including the SSC overhead, since this isn't enabled by
> the source device) and using this the PBN and TU values for the local
> link and PBN for remote links (including SSC, since this is mandatory
> for links after downstream branch devices).
> 
> For now keep the current fixed FEC overhead as a minimum, since this is
> what bspec requires for audio functionality.
> 
> Calculate the effective link BW in a clearer way, applying the channel
> coding efficiency based on the coding type. The calculation was correct
> for 8b/10b, but not for 128b/132b links; this patch leaves the behavior
> for this unchanged, leaving the fix for a follow-up.
> 
> Signed-off-by: Imre Deak 

Reviewed-by: Stanislav Lisovskiy 

> ---
>  drivers/gpu/drm/i915/display/intel_dp_mst.c | 99 +++--
>  1 file changed, 74 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index da496f383f163..2fbb6022e0c25 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -66,6 +66,63 @@ static int intel_dp_mst_check_constraints(struct 
> drm_i915_private *i915, int bpp
>   return 0;
>  }
>  
> +static int intel_dp_mst_bw_overhead(const struct intel_crtc_state 
> *crtc_state,
> + const struct intel_connector *connector,
> + bool ssc, bool dsc, int bpp)
> +{
> + const struct drm_display_mode *adjusted_mode =
> + _state->hw.adjusted_mode;
> + unsigned long flags = DRM_DP_BW_OVERHEAD_MST;
> + int dsc_slice_count = 0;
> + int overhead;
> +
> + flags |= intel_dp_is_uhbr(crtc_state) ? DRM_DP_BW_OVERHEAD_UHBR : 0;
> + flags |= ssc ? DRM_DP_BW_OVERHEAD_SSC : 0;
> + flags |= crtc_state->fec_enable ? DRM_DP_BW_OVERHEAD_FEC : 0;
> +
> + 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);
> + }
> +
> + overhead = drm_dp_bw_overhead(crtc_state->lane_count,
> +   adjusted_mode->hdisplay,
> +   dsc_slice_count,
> +   to_bpp_x16(bpp),
> +   flags);
> +
> + /*
> +  * TODO: clarify whether a minimum required by the fixed FEC overhead
> +  * in the bspec audio programming sequence is required here.
> +  */
> + return max(overhead, intel_dp_bw_fec_overhead(crtc_state->fec_enable));
> +}
> +
> +static void intel_dp_mst_compute_m_n(const struct intel_crtc_state 
> *crtc_state,
> +  const struct intel_connector *connector,
> +  bool ssc, bool dsc,
> +  int bpp,
> +  struct intel_link_m_n *m_n)
> +{
> + const struct drm_display_mode *adjusted_mode =
> + _state->hw.adjusted_mode;
> + int overhead = intel_dp_mst_bw_overhead(crtc_state,
> + connector,
> + ssc, dsc, bpp);
> +
> + intel_link_compute_m_n(bpp, crtc_state->lane_count,
> +adjusted_mode->crtc_clock,
> +crtc_state->port_clock,
> +overhead,
> +m_n);
> +
> + m_n->tu = DIV_ROUND_UP_ULL(mul_u32_u32(m_n->data_m, 64), m_n->data_n);
> +}
> +
>  static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder 
> *encoder,
>   struct intel_crtc_state 
> *crtc_state,
>   int max_bpp,
> @@ -99,14 +156,26 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct 
> intel_encoder *encoder,
> crtc_state->lane_count);
>  
>   for (bpp = max_bpp; bpp >= min_bpp; bpp -= step) {

Re: [Intel-gfx] [PATCH 24/29] drm/i915/dp_mst: Enable MST DSC decompression for all streams

2023-10-27 Thread Lisovskiy, Stanislav
On Tue, Oct 24, 2023 at 04:09:20AM +0300, Imre Deak wrote:
> Enable DSC decompression for all streams. In particular atm if a sink is
> connected to a last branch device that is downstream of the first branch
> device connected to the source, decompression is not enabled for it.
> Similarly it's not enabled if the sink supports this with the last
> branch device passing through the compressed stream to it.
> 
> Enable DSC in the above cases as well. Since last branch devices may
> handle the decompression for multiple ports, toggling DSC needs to be
> refcounted, add this using the DSC AUX device as a reference.
> 
> Signed-off-by: Imre Deak 
> ---
>  .../drm/i915/display/intel_display_types.h|  1 +
>  drivers/gpu/drm/i915/display/intel_dp.c   |  3 +
>  drivers/gpu/drm/i915/display/intel_dp_mst.c   | 57 ---
>  3 files changed, 42 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
> b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 409dbf8a2a1cd..b2744a9b4678c 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -626,6 +626,7 @@ struct intel_connector {
>   u8 fec_capability;
>  
>   u8 dsc_hblank_expansion_quirk:1;
> + u8 dsc_decompression_enabled:1;
>   } dp;
>  
>   /* Work struct to schedule a uevent on link train failure */
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index bb8951f89f61f..c89e1a4393d0f 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -1403,6 +1403,7 @@ static bool intel_dp_supports_dsc(const struct 
> intel_connector *connector,
>   return false;
>  
>   return intel_dsc_source_support(crtc_state) &&
> + connector->dp.dsc_decompression_aux &&
>   drm_dp_sink_supports_dsc(connector->dp.dsc_dpcd);
>  }
>  
> @@ -2948,6 +2949,8 @@ intel_dp_sink_set_dsc_decompression(struct 
> intel_connector *connector,
>   drm_dbg_kms(>drm,
>   "Failed to %s sink decompression state\n",
>   str_enable_disable(enable));
> +
> + connector->dp.dsc_decompression_enabled = enable;
>  }
>  
>  static void
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index 8ef3a2611207c..9f4894c2e7860 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -660,6 +660,39 @@ intel_dp_mst_atomic_topology_check(struct 
> intel_connector *connector,
>   return ret;
>  }
>  
> +static int intel_dp_mst_dsc_aux_use_count(struct intel_atomic_state *state,
> +   const struct intel_connector 
> *connector)
> +{
> + struct intel_connector *connector_iter;
> + struct intel_digital_connector_state *conn_state;
> + int use_count = 0;
> + int i;
> +
> + for_each_new_intel_connector_in_state(state, connector_iter, 
> conn_state, i) {
> + if (connector_iter->mst_port != connector->mst_port ||
> + !conn_state->base.crtc)
> + continue;
> +
> + if (!connector_iter->dp.dsc_decompression_enabled)
> + continue;
> +
> + if (connector_iter->dp.dsc_decompression_aux ==
> + connector->dp.dsc_decompression_aux)
> + use_count++;
> + }
> +
> + return use_count;
> +}
> +
> +static void intel_dp_mst_sink_set_decompression_state(struct 
> intel_atomic_state *state,
> +   struct intel_connector 
> *connector,
> +   const struct 
> intel_crtc_state *crtc_state,
> +   bool enable)
> +{
> + if (!intel_dp_mst_dsc_aux_use_count(state, connector))
> + intel_dp_sink_set_decompression_state(connector, crtc_state, 
> enable);

But where the use count is decremented?
As I understand we will be able to set this with enable==false also when 
use_count is 0.

For that we need to have intel_connector->dp.dsc_decompression_aux NULLed 
somewhere?

Stan
> +}
> +
>  static int
>  intel_dp_mst_atomic_check(struct drm_connector *connector,
> struct drm_atomic_state *_state)
> @@ -730,12 +763,7 @@ static void intel_mst_disable_dp(struct 
> intel_atomic_state *state,
>  
>   intel_audio_codec_disable(encoder, old_crtc_state, old_conn_state);
>  
> - if (intel_dp->active_mst_links == 1) /* last stream ? */
> - /*
> -  * TODO: disable decompression for all streams/in any MST 
> ports, not
> -  * only in the first downstream branch device.
> -  */
> - intel_dp_sink_set_decompression_state(connector, 
> 

Re: [Intel-gfx] [PATCH v2 22/29] drm/i915/dp: Enable DSC via the connector decompression AUX

2023-10-27 Thread Lisovskiy, Stanislav
On Tue, Oct 24, 2023 at 01:22:18PM +0300, Imre Deak wrote:
> Enable DSC using the DSC AUX device stored for this purpose in the
> connector. This prepares for a follow-up patch which toggles DSC for
> each stream as needed, but for now keeps the current behavior, as DSC is
> still only enabled for the first MST stream.
> 
> While at it set/clear only the DP_DECOMPRESSION_EN flag in the
> DP_DSC_ENABLE DPCD register, preserving the reserved register bits.
> 
> v2:
> - Add a helper function setting/clearing the decompression flag,
>   preserving the reserved register bits.

Reviewed-by: Stanislav Lisovskiy 

> 
> Signed-off-by: Imre Deak 
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c| 14 ---
>  drivers/gpu/drm/i915/display/intel_dp.c | 46 +
>  drivers/gpu/drm/i915/display/intel_dp.h |  2 +-
>  drivers/gpu/drm/i915/display/intel_dp_mst.c |  4 +-
>  4 files changed, 49 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
> b/drivers/gpu/drm/i915/display/intel_ddi.c
> index bc438272d6d1a..79e36939d92d1 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -2539,7 +2539,8 @@ static void mtl_ddi_pre_enable_dp(struct 
> intel_atomic_state *state,
>  
>   intel_dp_configure_protocol_converter(intel_dp, crtc_state);
>   if (!is_mst)
> - intel_dp_sink_set_decompression_state(intel_dp, crtc_state, 
> true);
> + 
> intel_dp_sink_set_decompression_state(to_intel_connector(conn_state->connector),
> +   crtc_state, true);
>  
>   /*
>* DDI FEC: "anticipates enabling FEC encoding sets the FEC_READY bit
> @@ -2692,7 +2693,8 @@ static void tgl_ddi_pre_enable_dp(struct 
> intel_atomic_state *state,
>  
>   intel_dp_configure_protocol_converter(intel_dp, crtc_state);
>   if (!is_mst)
> - intel_dp_sink_set_decompression_state(intel_dp, crtc_state, 
> true);
> + 
> intel_dp_sink_set_decompression_state(to_intel_connector(conn_state->connector),
> +   crtc_state, true);
>   /*
>* DDI FEC: "anticipates enabling FEC encoding sets the FEC_READY bit
>* in the FEC_CONFIGURATION register to 1 before initiating link
> @@ -2773,8 +2775,8 @@ static void hsw_ddi_pre_enable_dp(struct 
> intel_atomic_state *state,
>   intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
>   intel_dp_configure_protocol_converter(intel_dp, crtc_state);
>   if (!is_mst)
> - intel_dp_sink_set_decompression_state(intel_dp, crtc_state,
> -   true);
> + 
> intel_dp_sink_set_decompression_state(to_intel_connector(conn_state->connector),
> +   crtc_state, true);
>   intel_dp_sink_set_fec_ready(intel_dp, crtc_state, true);
>   intel_dp_start_link_train(intel_dp, crtc_state);
>   if ((port != PORT_A || DISPLAY_VER(dev_priv) >= 9) &&
> @@ -3354,6 +3356,8 @@ static void intel_disable_ddi_dp(struct 
> intel_atomic_state *state,
>const struct drm_connector_state 
> *old_conn_state)
>  {
>   struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> + struct intel_connector *connector =
> + to_intel_connector(old_conn_state->connector);
>  
>   intel_dp->link_trained = false;
>  
> @@ -3362,7 +3366,7 @@ static void intel_disable_ddi_dp(struct 
> intel_atomic_state *state,
>   intel_psr_disable(intel_dp, old_crtc_state);
>   intel_edp_backlight_off(old_conn_state);
>   /* Disable the decompression in DP Sink */
> - intel_dp_sink_set_decompression_state(intel_dp, old_crtc_state,
> + intel_dp_sink_set_decompression_state(connector, old_crtc_state,
> false);
>   /* Disable Ignore_MSA bit in DP Sink */
>   intel_dp_sink_set_msa_timing_par_ignore_state(intel_dp, old_crtc_state,
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index 7d185d6b2fe9d..0101e17515b33 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -2937,22 +2937,50 @@ static bool downstream_hpd_needs_d0(struct intel_dp 
> *intel_dp)
>   intel_dp->downstream_ports[0] & DP_DS_PORT_HPD;
>  }
>  
> -void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp,
> +static int
> +write_dsc_decompression_flag(struct drm_dp_aux *aux, u8 flag, bool set)
> +{
> + int err;
> + u8 val;
> +
> + err = drm_dp_dpcd_readb(aux, DP_DSC_ENABLE, );
> + if (err < 0)
> + return err;
> +
> + if (set)
> + val |= flag;
> + else
> + val &= ~flag;
> +
> + return drm_dp_dpcd_writeb(aux, DP_DSC_ENABLE, val);
> +}
> +
> +static void
> 

Re: [Intel-gfx] [PATCH v2 23/29] drm/i915/dp_mst: Enable DSC passthrough

2023-10-27 Thread Lisovskiy, Stanislav
On Tue, Oct 24, 2023 at 01:22:19PM +0300, Imre Deak wrote:
> Enable passing through DSC streams to the sink in last branch devices.
> 
> v2:
> - Fix the DPCD register address while setting/clearing the passthrough
>   flag.
> 
> Signed-off-by: Imre Deak 

Reviewed-by: Stanislav Lisovskiy 

> ---
>  drivers/gpu/drm/i915/display/intel_dp.c | 26 -
>  1 file changed, 25 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index 0101e17515b33..51d6ab170a894 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -2968,6 +2968,24 @@ intel_dp_sink_set_dsc_decompression(struct 
> intel_connector *connector,
>   str_enable_disable(enable));
>  }
>  
> +static void
> +intel_dp_sink_set_dsc_passthrough(const struct intel_connector *connector,
> +   bool enable)
> +{
> + struct drm_i915_private *i915 = to_i915(connector->base.dev);
> + struct drm_dp_aux *aux = connector->port ?
> +  connector->port->passthrough_aux : NULL;
> +
> + if (!aux)
> + return;
> +
> + if (write_dsc_decompression_flag(aux,
> +  DP_DSC_PASSTHROUGH_EN, enable) < 0)
> + drm_dbg_kms(>drm,
> + "Failed to %s sink compression passthrough state\n",
> + str_enable_disable(enable));
> +}
> +
>  void intel_dp_sink_set_decompression_state(struct intel_connector *connector,
>  const struct intel_crtc_state 
> *crtc_state,
>  bool enable)
> @@ -2980,7 +2998,13 @@ void intel_dp_sink_set_decompression_state(struct 
> intel_connector *connector,
>   if (drm_WARN_ON(>drm, !connector->dp.dsc_decompression_aux))
>   return;
>  
> - intel_dp_sink_set_dsc_decompression(connector, enable);
> + if (enable) {
> + intel_dp_sink_set_dsc_passthrough(connector, true);
> + intel_dp_sink_set_dsc_decompression(connector, true);
> + } else {
> + intel_dp_sink_set_dsc_decompression(connector, false);
> + intel_dp_sink_set_dsc_passthrough(connector, false);
> + }
>  }
>  
>  static void
> -- 
> 2.39.2
> 


Re: [Intel-gfx] [PATCH 22/29] drm/i915/dp: Enable DSC via the connector decompression AUX

2023-10-27 Thread Lisovskiy, Stanislav
On Tue, Oct 24, 2023 at 04:09:18AM +0300, Imre Deak wrote:
> Enable DSC using the DSC AUX device stored for this purpose in the
> connector. This prepares for a follow-up patch which toggles DSC for
> each stream as needed, but for now keeps the current behavior, as DSC is
> still only enabled for the first MST stream.
> 
> Signed-off-by: Imre Deak 

Reviewed-by: Stanislav Lisovskiy 

> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c| 14 +++
>  drivers/gpu/drm/i915/display/intel_dp.c | 28 ++---
>  drivers/gpu/drm/i915/display/intel_dp.h |  2 +-
>  drivers/gpu/drm/i915/display/intel_dp_mst.c |  4 +--
>  4 files changed, 31 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
> b/drivers/gpu/drm/i915/display/intel_ddi.c
> index bc438272d6d1a..79e36939d92d1 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -2539,7 +2539,8 @@ static void mtl_ddi_pre_enable_dp(struct 
> intel_atomic_state *state,
>  
>   intel_dp_configure_protocol_converter(intel_dp, crtc_state);
>   if (!is_mst)
> - intel_dp_sink_set_decompression_state(intel_dp, crtc_state, 
> true);
> + 
> intel_dp_sink_set_decompression_state(to_intel_connector(conn_state->connector),
> +   crtc_state, true);
>  
>   /*
>* DDI FEC: "anticipates enabling FEC encoding sets the FEC_READY bit
> @@ -2692,7 +2693,8 @@ static void tgl_ddi_pre_enable_dp(struct 
> intel_atomic_state *state,
>  
>   intel_dp_configure_protocol_converter(intel_dp, crtc_state);
>   if (!is_mst)
> - intel_dp_sink_set_decompression_state(intel_dp, crtc_state, 
> true);
> + 
> intel_dp_sink_set_decompression_state(to_intel_connector(conn_state->connector),
> +   crtc_state, true);
>   /*
>* DDI FEC: "anticipates enabling FEC encoding sets the FEC_READY bit
>* in the FEC_CONFIGURATION register to 1 before initiating link
> @@ -2773,8 +2775,8 @@ static void hsw_ddi_pre_enable_dp(struct 
> intel_atomic_state *state,
>   intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
>   intel_dp_configure_protocol_converter(intel_dp, crtc_state);
>   if (!is_mst)
> - intel_dp_sink_set_decompression_state(intel_dp, crtc_state,
> -   true);
> + 
> intel_dp_sink_set_decompression_state(to_intel_connector(conn_state->connector),
> +   crtc_state, true);
>   intel_dp_sink_set_fec_ready(intel_dp, crtc_state, true);
>   intel_dp_start_link_train(intel_dp, crtc_state);
>   if ((port != PORT_A || DISPLAY_VER(dev_priv) >= 9) &&
> @@ -3354,6 +3356,8 @@ static void intel_disable_ddi_dp(struct 
> intel_atomic_state *state,
>const struct drm_connector_state 
> *old_conn_state)
>  {
>   struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> + struct intel_connector *connector =
> + to_intel_connector(old_conn_state->connector);
>  
>   intel_dp->link_trained = false;
>  
> @@ -3362,7 +3366,7 @@ static void intel_disable_ddi_dp(struct 
> intel_atomic_state *state,
>   intel_psr_disable(intel_dp, old_crtc_state);
>   intel_edp_backlight_off(old_conn_state);
>   /* Disable the decompression in DP Sink */
> - intel_dp_sink_set_decompression_state(intel_dp, old_crtc_state,
> + intel_dp_sink_set_decompression_state(connector, old_crtc_state,
> false);
>   /* Disable Ignore_MSA bit in DP Sink */
>   intel_dp_sink_set_msa_timing_par_ignore_state(intel_dp, old_crtc_state,
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index 7d185d6b2fe9d..a7eb31b489947 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -2937,22 +2937,32 @@ static bool downstream_hpd_needs_d0(struct intel_dp 
> *intel_dp)
>   intel_dp->downstream_ports[0] & DP_DS_PORT_HPD;
>  }
>  
> -void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp,
> +static void
> +intel_dp_sink_set_dsc_decompression(struct intel_connector *connector,
> + bool enable)
> +{
> + struct drm_i915_private *i915 = to_i915(connector->base.dev);
> +
> + if (drm_dp_dpcd_writeb(connector->dp.dsc_decompression_aux, 
> DP_DSC_ENABLE,
> +enable ? DP_DECOMPRESSION_EN : 0) < 0)
> + drm_dbg_kms(>drm,
> + "Failed to %s sink decompression state\n",
> + str_enable_disable(enable));
> +}
> +
> +void intel_dp_sink_set_decompression_state(struct intel_connector *connector,
>  const struct intel_crtc_state 
> 

Re: [Intel-gfx] [PATCH 21/29] drm/i915/dp_mst: Enable decompression in the sink from the MST encoder hooks

2023-10-27 Thread Lisovskiy, Stanislav
On Tue, Oct 24, 2023 at 04:09:17AM +0300, Imre Deak wrote:
> Enable/disable the DSC decompression in the sink/branch from the MST
> encoder hooks. This prepares for an upcoming patch toggling DSC for each
> stream as needed, but for now keeps the current behavior, as DSC is only
> enabled for the first MST stream.

Reviewed-by: Stanislav Lisovskiy 

> 
> Signed-off-by: Imre Deak 
> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c| 12 
>  drivers/gpu/drm/i915/display/intel_dp_mst.c | 15 ++-
>  2 files changed, 22 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
> b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 99d96762fa29c..bc438272d6d1a 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -2538,7 +2538,9 @@ static void mtl_ddi_pre_enable_dp(struct 
> intel_atomic_state *state,
>   intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
>  
>   intel_dp_configure_protocol_converter(intel_dp, crtc_state);
> - intel_dp_sink_set_decompression_state(intel_dp, crtc_state, true);
> + if (!is_mst)
> + intel_dp_sink_set_decompression_state(intel_dp, crtc_state, 
> true);
> +
>   /*
>* DDI FEC: "anticipates enabling FEC encoding sets the FEC_READY bit
>* in the FEC_CONFIGURATION register to 1 before initiating link
> @@ -2689,7 +2691,8 @@ static void tgl_ddi_pre_enable_dp(struct 
> intel_atomic_state *state,
>   intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
>  
>   intel_dp_configure_protocol_converter(intel_dp, crtc_state);
> - intel_dp_sink_set_decompression_state(intel_dp, crtc_state, true);
> + if (!is_mst)
> + intel_dp_sink_set_decompression_state(intel_dp, crtc_state, 
> true);
>   /*
>* DDI FEC: "anticipates enabling FEC encoding sets the FEC_READY bit
>* in the FEC_CONFIGURATION register to 1 before initiating link
> @@ -2769,8 +2772,9 @@ static void hsw_ddi_pre_enable_dp(struct 
> intel_atomic_state *state,
>   if (!is_mst)
>   intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
>   intel_dp_configure_protocol_converter(intel_dp, crtc_state);
> - intel_dp_sink_set_decompression_state(intel_dp, crtc_state,
> -   true);
> + if (!is_mst)
> + intel_dp_sink_set_decompression_state(intel_dp, crtc_state,
> +   true);
>   intel_dp_sink_set_fec_ready(intel_dp, crtc_state, true);
>   intel_dp_start_link_train(intel_dp, crtc_state);
>   if ((port != PORT_A || DISPLAY_VER(dev_priv) >= 9) &&
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index 9124e9cdf4c79..b0310f464c1cd 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -729,6 +729,13 @@ static void intel_mst_disable_dp(struct 
> intel_atomic_state *state,
>   drm_dp_remove_payload_part1(_dp->mst_mgr, new_mst_state, 
> new_payload);
>  
>   intel_audio_codec_disable(encoder, old_crtc_state, old_conn_state);
> +
> + if (intel_dp->active_mst_links == 1) /* last stream ? */
> + /*
> +  * TODO: disable decompression for all streams/in any MST 
> ports, not
> +  * only in the first downstream branch device.
> +  */
> + intel_dp_sink_set_decompression_state(intel_dp, old_crtc_state, 
> false);
>  }
>  
>  static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
> @@ -883,9 +890,15 @@ static void intel_mst_pre_enable_dp(struct 
> intel_atomic_state *state,
>  
>   drm_dp_send_power_updown_phy(_dp->mst_mgr, connector->port, true);
>  
> - if (first_mst_stream)
> + if (first_mst_stream) {
> + /*
> +  * TODO: enable decompression for all streams/in any MST ports, 
> not
> +  * only in the first downstream branch device.
> +  */
> + intel_dp_sink_set_decompression_state(intel_dp, pipe_config, 
> true);
>   dig_port->base.pre_enable(state, _port->base,
>   pipe_config, NULL);
> + }
>  
>   intel_dp->active_mst_links++;
>  
> -- 
> 2.39.2
> 


Re: [Intel-gfx] [PATCH 07/29] drm/dp_mst: Add HBLANK expansion quirk for Synaptics MST hubs

2023-10-27 Thread Lisovskiy, Stanislav
On Tue, Oct 24, 2023 at 04:09:03AM +0300, Imre Deak wrote:
> Add a quirk for Synaptics MST hubs, which require a workaround - at leat
> on i915 - for some modes, on which the hub applies HBLANK expansion.
> These modes will only work by enabling DSC decompression for them, a
> follow-up patch will do this in i915.
> 
> Cc: Lyude Paul 
> Signed-off-by: Imre Deak 

Reviewed-by: Stanislav Lisovskiy 

> ---
>  drivers/gpu/drm/display/drm_dp_helper.c | 2 ++
>  include/drm/display/drm_dp_helper.h | 7 +++
>  2 files changed, 9 insertions(+)
> 
> diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
> b/drivers/gpu/drm/display/drm_dp_helper.c
> index f3680f4e69708..e5d7970a9ddd0 100644
> --- a/drivers/gpu/drm/display/drm_dp_helper.c
> +++ b/drivers/gpu/drm/display/drm_dp_helper.c
> @@ -2245,6 +2245,8 @@ static const struct dpcd_quirk dpcd_quirk_list[] = {
>   { OUI(0x00, 0x00, 0x00), DEVICE_ID('C', 'H', '7', '5', '1', '1'), 
> false, BIT(DP_DPCD_QUIRK_NO_SINK_COUNT) },
>   /* Synaptics DP1.4 MST hubs can support DSC without virtual DPCD */
>   { OUI(0x90, 0xCC, 0x24), DEVICE_ID_ANY, true, 
> BIT(DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD) },
> + /* Synaptics DP1.4 MST hubs require DSC for some modes on which it 
> applies HBLANK expansion. */
> + { OUI(0x90, 0xCC, 0x24), DEVICE_ID_ANY, true, 
> BIT(DP_DPCD_QUIRK_HBLANK_EXPANSION_REQUIRES_DSC) },
>   /* Apple MacBookPro 2017 15 inch eDP Retina panel reports too low 
> DP_MAX_LINK_RATE */
>   { OUI(0x00, 0x10, 0xfa), DEVICE_ID(101, 68, 21, 101, 98, 97), false, 
> BIT(DP_DPCD_QUIRK_CAN_DO_MAX_LINK_RATE_3_24_GBPS) },
>  };
> diff --git a/include/drm/display/drm_dp_helper.h 
> b/include/drm/display/drm_dp_helper.h
> index 3d74b2cec72fd..351f38d5cc351 100644
> --- a/include/drm/display/drm_dp_helper.h
> +++ b/include/drm/display/drm_dp_helper.h
> @@ -632,6 +632,13 @@ enum drm_dp_quirk {
>* the DP_MAX_LINK_RATE register reporting a lower max multiplier.
>*/
>   DP_DPCD_QUIRK_CAN_DO_MAX_LINK_RATE_3_24_GBPS,
> + /**
> +  * @DP_DPCD_QUIRK_HBLANK_EXPANSION_NEEDS_DSC:
> +  *
> +  * The device applies HBLANK expansion for some modes, but this
> +  * requires enabling DSC.
> +  */
> + DP_DPCD_QUIRK_HBLANK_EXPANSION_REQUIRES_DSC,
>  };
>  
>  /**
> -- 
> 2.39.2
> 


Re: [Intel-gfx] [PATCH v2 08/29] drm/dp: Add helpers to calculate the link BW overhead

2023-10-27 Thread Lisovskiy, Stanislav
On Tue, Oct 24, 2023 at 01:22:17PM +0300, Imre Deak wrote:
> Add helpers drivers can use to calculate the BW allocation overhead -
> due to SSC, FEC, DSC and data alignment on symbol cycles - and the
> channel coding efficiency - due to the 8b/10b, 128b/132b encoding. On
> 128b/132b links the FEC overhead is part of the coding efficiency, so
> not accounted for in the BW allocation overhead.
> 
> The drivers can use these functions to calculate a ratio, controlling
> the stream symbol insertion rate of the source device in each SST TU
> or MST MTP frame. Drivers can calculate this
> 
> m/n = (pixel_data_rate * drm_dp_bw_overhead()) /
>   (link_data_rate * drm_dp_bw_channel_coding_efficiency())
> 
> ratio for a given link and pixel stream and with that the
> 
> mtp_count = CEIL(64 * m / n)
> 
> allocated MTPs for the stream in a link frame and
> 
> pbn = CEIL(64 * dm_mst_get_pbn_divider() * m / n)
> 
> allocated PBNs for the stream on the MST link path.
> 
> Take drm_dp_bw_overhead() into use in drm_dp_calc_pbn_mode(), for
> drivers calculating the PBN value directly.
> 
> v2:
> - Add dockbook description to drm_dp_bw_channel_coding_efficiency().
>   (LKP).
> - Clarify the way m/n ratio is calculated in the commit log.

Could not spot any obivous issues here, but wondering, whether someone
could also take a look, as this seems to be affecting quite a lot.

Anyways, from my side:

Reviewed-by: Stanislav Lisovskiy 

> 
> Cc: Lyude Paul 
> Cc: kernel test robot 
> Cc: dri-de...@lists.freedesktop.org
> Signed-off-by: Imre Deak 
> ---
>  drivers/gpu/drm/display/drm_dp_helper.c   | 124 ++
>  drivers/gpu/drm/display/drm_dp_mst_topology.c |  23 +++-
>  include/drm/display/drm_dp_helper.h   |  11 ++
>  3 files changed, 152 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
> b/drivers/gpu/drm/display/drm_dp_helper.c
> index e5d7970a9ddd0..79629bf7547bf 100644
> --- a/drivers/gpu/drm/display/drm_dp_helper.c
> +++ b/drivers/gpu/drm/display/drm_dp_helper.c
> @@ -3899,4 +3899,128 @@ int drm_panel_dp_aux_backlight(struct drm_panel 
> *panel, struct drm_dp_aux *aux)
>  }
>  EXPORT_SYMBOL(drm_panel_dp_aux_backlight);
>  
> +/* See DP Standard v2.1 2.6.4.4.1.1, 2.8.4.4, 2.8.7 */
> +static int drm_dp_link_symbol_cycles(int lane_count, int pixels, int bpp_x16,
> +  int symbol_size, bool is_mst)
> +{
> + int cycles = DIV_ROUND_UP(pixels * bpp_x16, 16 * symbol_size * 
> lane_count);
> + int align = is_mst ? 4 / lane_count : 1;
> +
> + return ALIGN(cycles, align);
> +}
> +
> +static int drm_dp_link_dsc_symbol_cycles(int lane_count, int pixels, int 
> slice_count,
> +  int bpp_x16, int symbol_size, bool 
> is_mst)
> +{
> + int slice_pixels = DIV_ROUND_UP(pixels, slice_count);
> + int slice_data_cycles = drm_dp_link_symbol_cycles(lane_count, 
> slice_pixels,
> +   bpp_x16, symbol_size, 
> is_mst);
> + int slice_eoc_cycles = is_mst ? 4 / lane_count : 1;
> +
> + return slice_count * (slice_data_cycles + slice_eoc_cycles);
> +}
> +
> +/**
> + * drm_dp_bw_overhead - Calculate the BW overhead of a DP link stream
> + * @lane_count: DP link lane count
> + * @hactive: pixel count of the active period in one scanline of the stream
> + * @dsc_slice_count: DSC slice count if @flags/DRM_DP_LINK_BW_OVERHEAD_DSC 
> is set
> + * @bpp_x16: bits per pixel in .4 binary fixed point
> + * @flags: DRM_DP_OVERHEAD_x flags
> + *
> + * Calculate the BW allocation overhead of a DP link stream, depending
> + * on the link's
> + * - @lane_count
> + * - SST/MST mode (@flags / %DRM_DP_OVERHEAD_MST)
> + * - symbol size (@flags / %DRM_DP_OVERHEAD_UHBR)
> + * - FEC mode (@flags / %DRM_DP_OVERHEAD_FEC)
> + * - SSC mode (@flags / %DRM_DP_OVERHEAD_SSC)
> + * as well as the stream's
> + * - @hactive timing
> + * - @bpp_x16 color depth
> + * - compression mode (@flags / %DRM_DP_OVERHEAD_DSC).
> + * Note that this overhead doesn't account for the 8b/10b, 128b/132b
> + * channel coding efficiency, for that see
> + * @drm_dp_link_bw_channel_coding_efficiency().
> + *
> + * Returns the overhead as 100% + overhead% in 1ppm units.
> + */
> +int drm_dp_bw_overhead(int lane_count, int hactive,
> +int dsc_slice_count,
> +int bpp_x16, unsigned long flags)
> +{
> + int symbol_size = flags & DRM_DP_BW_OVERHEAD_UHBR ? 32 : 8;
> + bool is_mst = flags & DRM_DP_BW_OVERHEAD_MST;
> + u32 overhead = 100;
> + int symbol_cycles;
> +
> + /*
> +  * DP Standard v2.1 2.6.4.1
> +  * SSC downspread and ref clock variation margin:
> +  *   5300ppm + 300ppm ~ 0.6%
> +  */
> + if (flags & DRM_DP_BW_OVERHEAD_SSC)
> + overhead += 6000;
> +
> + /*
> +  * DP Standard v2.1 2.6.4.1.1:
> +  * FEC symbol insertions for 8b/10b channel coding:
> +  *   2.4%
> +  */
> + if 

Re: [Intel-gfx] [PATCH 07/29] drm/dp_mst: Add HBLANK expansion quirk for Synaptics MST hubs

2023-10-27 Thread Lisovskiy, Stanislav
On Tue, Oct 24, 2023 at 04:09:03AM +0300, Imre Deak wrote:
> Add a quirk for Synaptics MST hubs, which require a workaround - at leat
> on i915 - for some modes, on which the hub applies HBLANK expansion.
> These modes will only work by enabling DSC decompression for them, a
> follow-up patch will do this in i915.

Reviewed-by: Stanislav Lisovskiy 

> 
> Cc: Lyude Paul 
> Signed-off-by: Imre Deak 
> ---
>  drivers/gpu/drm/display/drm_dp_helper.c | 2 ++
>  include/drm/display/drm_dp_helper.h | 7 +++
>  2 files changed, 9 insertions(+)
> 
> diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
> b/drivers/gpu/drm/display/drm_dp_helper.c
> index f3680f4e69708..e5d7970a9ddd0 100644
> --- a/drivers/gpu/drm/display/drm_dp_helper.c
> +++ b/drivers/gpu/drm/display/drm_dp_helper.c
> @@ -2245,6 +2245,8 @@ static const struct dpcd_quirk dpcd_quirk_list[] = {
>   { OUI(0x00, 0x00, 0x00), DEVICE_ID('C', 'H', '7', '5', '1', '1'), 
> false, BIT(DP_DPCD_QUIRK_NO_SINK_COUNT) },
>   /* Synaptics DP1.4 MST hubs can support DSC without virtual DPCD */
>   { OUI(0x90, 0xCC, 0x24), DEVICE_ID_ANY, true, 
> BIT(DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD) },
> + /* Synaptics DP1.4 MST hubs require DSC for some modes on which it 
> applies HBLANK expansion. */
> + { OUI(0x90, 0xCC, 0x24), DEVICE_ID_ANY, true, 
> BIT(DP_DPCD_QUIRK_HBLANK_EXPANSION_REQUIRES_DSC) },
>   /* Apple MacBookPro 2017 15 inch eDP Retina panel reports too low 
> DP_MAX_LINK_RATE */
>   { OUI(0x00, 0x10, 0xfa), DEVICE_ID(101, 68, 21, 101, 98, 97), false, 
> BIT(DP_DPCD_QUIRK_CAN_DO_MAX_LINK_RATE_3_24_GBPS) },
>  };
> diff --git a/include/drm/display/drm_dp_helper.h 
> b/include/drm/display/drm_dp_helper.h
> index 3d74b2cec72fd..351f38d5cc351 100644
> --- a/include/drm/display/drm_dp_helper.h
> +++ b/include/drm/display/drm_dp_helper.h
> @@ -632,6 +632,13 @@ enum drm_dp_quirk {
>* the DP_MAX_LINK_RATE register reporting a lower max multiplier.
>*/
>   DP_DPCD_QUIRK_CAN_DO_MAX_LINK_RATE_3_24_GBPS,
> + /**
> +  * @DP_DPCD_QUIRK_HBLANK_EXPANSION_NEEDS_DSC:
> +  *
> +  * The device applies HBLANK expansion for some modes, but this
> +  * requires enabling DSC.
> +  */
> + DP_DPCD_QUIRK_HBLANK_EXPANSION_REQUIRES_DSC,
>  };
>  
>  /**
> -- 
> 2.39.2
> 


Re: [Intel-gfx] [PATCH 06/29] drm/dp: Add DP_HBLANK_EXPANSION_CAPABLE and DSC_PASSTHROUGH_EN DPCD flags

2023-10-27 Thread Lisovskiy, Stanislav
On Tue, Oct 24, 2023 at 04:09:02AM +0300, Imre Deak wrote:
> Add the DPCD flag to enable DSC passthrough in a last branch device,
> used in a follow-up i915 patch.
> 
> Also add a flag to detect HBLANK expansion support in a branch device,
> used by a workaround in a follow-up i915 patch.
> 
> Cc: Lyude Paul 
> Signed-off-by: Imre Deak 

Reviewed-by: Stanislav Lisovskiy 

> ---
>  include/drm/display/drm_dp.h | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h
> index e69cece404b3c..763d45a612f35 100644
> --- a/include/drm/display/drm_dp.h
> +++ b/include/drm/display/drm_dp.h
> @@ -148,6 +148,7 @@
>  #define DP_RECEIVE_PORT_0_CAP_0  0x008
>  # define DP_LOCAL_EDID_PRESENT   (1 << 1)
>  # define DP_ASSOCIATED_TO_PRECEDING_PORT(1 << 2)
> +# define DP_HBLANK_EXPANSION_CAPABLE(1 << 3)
>  
>  #define DP_RECEIVE_PORT_0_BUFFER_SIZE0x009
>  
> @@ -699,6 +700,7 @@
>  
>  #define DP_DSC_ENABLE   0x160   /* DP 1.4 */
>  # define DP_DECOMPRESSION_EN(1 << 0)
> +# define DP_DSC_PASSTHROUGH_EN   (1 << 1)
>  #define DP_DSC_CONFIGURATION 0x161   /* DP 2.0 */
>  
>  #define DP_PSR_EN_CFG0x170   /* XXX 1.2? */
> -- 
> 2.39.2
> 


Re: [Intel-gfx] [PATCH 05/29] drm/dp_mst: Allow DSC in any Synaptics last branch device

2023-10-27 Thread Lisovskiy, Stanislav
On Tue, Oct 24, 2023 at 04:09:01AM +0300, Imre Deak wrote:
> The Synaptics MST branch deivces support DSC decompression on all their

devices

> output ports, provided that they are last branch devices (with their
> output ports connected to the sinks). The Thinkpad 40B0 TBT dock for
> instance has two such branch devices, a secondary one connected to one
> of the output ports of the primary; hence the decompression needs to be
> enabled in both branch devices to enable decompression for all the
> sinks.
> 
> Based on the above add support for enabling decompression in last
> Synaptics branch devices.
> 
> Cc: Lyude Paul 
> Signed-off-by: Imre Deak 

Reviewed-by: Stanislav Lisovskiy 

> ---
>  drivers/gpu/drm/display/drm_dp_mst_topology.c | 21 ---
>  1 file changed, 13 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c 
> b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> index 5972c93615f18..cc0a8fe84d290 100644
> --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c
> @@ -5994,6 +5994,7 @@ static bool drm_dp_mst_is_virtual_dpcd(struct 
> drm_dp_mst_port *port)
>  struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct drm_dp_mst_port *port)
>  {
>   struct drm_dp_mst_port *immediate_upstream_port;
> + struct drm_dp_aux *immediate_upstream_aux;
>   struct drm_dp_mst_port *fec_port;
>   struct drm_dp_desc desc = {};
>   u8 endpoint_fec;
> @@ -6058,21 +6059,25 @@ struct drm_dp_aux *drm_dp_mst_dsc_aux_for_port(struct 
> drm_dp_mst_port *port)
>* - Port is on primary branch device
>* - Not a VGA adapter (DP_DWN_STRM_PORT_TYPE_ANALOG)
>*/
> - if (drm_dp_read_desc(port->mgr->aux, , true))
> + if (immediate_upstream_port)
> + immediate_upstream_aux = _upstream_port->aux;
> + else
> + immediate_upstream_aux = port->mgr->aux;
> +
> + if (drm_dp_read_desc(immediate_upstream_aux, , true))
>   return NULL;
>  
> - if (drm_dp_has_quirk(, DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD) &&
> - port->mgr->dpcd[DP_DPCD_REV] >= DP_DPCD_REV_14 &&
> - port->parent == port->mgr->mst_primary) {
> + if (drm_dp_has_quirk(, DP_DPCD_QUIRK_DSC_WITHOUT_VIRTUAL_DPCD)) {
>   u8 dpcd_ext[DP_RECEIVER_CAP_SIZE];
>  
> - if (drm_dp_read_dpcd_caps(port->mgr->aux, dpcd_ext) < 0)
> + if (drm_dp_read_dpcd_caps(immediate_upstream_aux, dpcd_ext) < 0)
>   return NULL;
>  
> - if ((dpcd_ext[DP_DOWNSTREAMPORT_PRESENT] & 
> DP_DWN_STRM_PORT_PRESENT) &&
> + if (dpcd_ext[DP_DPCD_REV] >= DP_DPCD_REV_14 &&
> + ((dpcd_ext[DP_DOWNSTREAMPORT_PRESENT] & 
> DP_DWN_STRM_PORT_PRESENT) &&
>   ((dpcd_ext[DP_DOWNSTREAMPORT_PRESENT] & 
> DP_DWN_STRM_PORT_TYPE_MASK)
> -  != DP_DWN_STRM_PORT_TYPE_ANALOG))
> - return port->mgr->aux;
> +  != DP_DWN_STRM_PORT_TYPE_ANALOG)))
> + return immediate_upstream_aux;
>   }
>  
>   /*
> -- 
> 2.39.2
> 


Re: [Intel-gfx] [PATCH 26/29] drm/i915/dp_mst: Force modeset CRTC if DSC toggling requires it

2023-10-27 Thread Lisovskiy, Stanislav
On Tue, Oct 24, 2023 at 04:09:22AM +0300, Imre Deak wrote:
> Enabling / disabling DSC decompression in the branch device downstream
> of the source may reset the while branch device. To avoid this while the

"may reset the whOle branch device" I guess?

> streams are still active, force a modeset on all CRTC/ports connected to
> this branch device.
> 
> Signed-off-by: Imre Deak 

Reviewed-by: Stanislav Lisovskiy 

> ---
>  drivers/gpu/drm/i915/display/intel_display.c |  4 ++
>  drivers/gpu/drm/i915/display/intel_dp_mst.c  | 72 
>  drivers/gpu/drm/i915/display/intel_dp_mst.h  |  2 +
>  3 files changed, 78 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> b/drivers/gpu/drm/i915/display/intel_display.c
> index 22f88389035bd..a33e5bbf5165a 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -6490,6 +6490,10 @@ int intel_atomic_check(struct drm_device *dev,
>   if (!new_crtc_state->hw.enable || 
> intel_crtc_needs_modeset(new_crtc_state))
>   continue;
>  
> + if (intel_dp_mst_crtc_needs_modeset(state, crtc))
> + intel_modeset_pipes_in_mask_early(state, "MST topology",
> +   BIT(crtc->pipe));
> +
>   if (intel_dp_mst_is_slave_trans(new_crtc_state)) {
>   enum transcoder master = 
> new_crtc_state->mst_master_transcoder;
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index 9f4894c2e7860..d4dcfb2c09b2a 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -1606,3 +1606,75 @@ int intel_dp_mst_add_topology_state_for_crtc(struct 
> intel_atomic_state *state,
>  
>   return 0;
>  }
> +
> +static struct intel_connector *
> +get_connector_in_state_for_crtc(struct intel_atomic_state *state,
> + const struct intel_crtc *crtc)
> +{
> + struct drm_connector_state *old_conn_state;
> + struct drm_connector_state *new_conn_state;
> + struct drm_connector *_connector;
> + int i;
> +
> + for_each_oldnew_connector_in_state(>base, _connector,
> +old_conn_state, new_conn_state, i) {
> + struct intel_connector *connector =
> + to_intel_connector(_connector);
> +
> + if (old_conn_state->crtc == >base ||
> + new_conn_state->crtc == >base)
> + return connector;
> + }
> +
> + return NULL;
> +}
> +
> +bool intel_dp_mst_crtc_needs_modeset(struct intel_atomic_state *state,
> +  struct intel_crtc *crtc)
> +{
> + const struct intel_connector *crtc_connector;
> + const struct drm_connector_state *conn_state;
> + const struct drm_connector *_connector;
> + int i;
> +
> + if (!intel_crtc_has_type(intel_atomic_get_new_crtc_state(state, crtc),
> +  INTEL_OUTPUT_DP_MST))
> + return false;
> +
> + crtc_connector = get_connector_in_state_for_crtc(state, crtc);
> +
> + if (!crtc_connector)
> + /* None of the connectors in the topology needs modeset */
> + return false;
> +
> + for_each_new_connector_in_state(>base, _connector, conn_state, 
> i) {
> + const struct intel_connector *connector =
> + to_intel_connector(_connector);
> + 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);
> +
> + if (connector->mst_port != crtc_connector->mst_port)
> + continue;
> +
> + if (!intel_crtc_needs_modeset(new_crtc_state))
> + continue;
> +
> + if (old_crtc_state->dsc.compression_enable ==
> + new_crtc_state->dsc.compression_enable)
> + continue;
> +
> + /*
> +  * Toggling the compression flag because of this stream in the 
> first
> +  * downstream branch device's UFP DPCD may reset the whole 
> branch
> +  * device. To avoid the reset while other streams are also
> +  * active modeset the whole MST topology in this case.
> +  */
> + if (connector->dp.dsc_decompression_aux ==
> + >mst_port->aux)
> + return true;
> + }
> +
> + return false;
> +}
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.h 
> b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> index f1815bb722672..fc5e85776a858 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.h
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.h
> 

Re: [Intel-gfx] [PATCH 20/29] drm/i915/dp_mst: Handle the Synaptics HBlank expansion quirk

2023-10-27 Thread Lisovskiy, Stanislav
On Tue, Oct 24, 2023 at 04:09:16AM +0300, Imre Deak wrote:
> The Synaptics MST hubs expose some sink EDID modes with a reduced HBLANK
> period, presumedly to save BW, which the hub expands before forwarding
> the stream to the sink. In particular a 4k mode with a standard CVT
> HBLANK period is exposed with either a CVT reduced blank RBv1 (80 pixel)
> or a non-CVT 56 pixel HBLANK period. The DP standard describes the above
> HBLANK expansion functionality, but it requires enabling this explicitly,
> whereas these hubs apply the expansion transparently.
> 
> Such modes will work okay until DSC decompression is enabled in the hub
> for the given sink, but after this the same mode will not work reliably
> in decompressed mode. As a workaround force enable DSC for such modes.
> OTOH DSC for these modes will only work above a certain compressed bpp
> threshold which depends on the link rate, so apply this limit as well
> in the workaround.
> 
> Apply the workaround only for Synaptics hubs which support the HBLANK
> expansion.
> 
> Signed-off-by: Imre Deak 

Reviewed-by: Stanislav Lisovskiy 

> ---
>  .../drm/i915/display/intel_display_types.h|   2 +
>  drivers/gpu/drm/i915/display/intel_dp_mst.c   | 109 +-
>  2 files changed, 107 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
> b/drivers/gpu/drm/i915/display/intel_display_types.h
> index 65ea37fe8cff3..409dbf8a2a1cd 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_types.h
> +++ b/drivers/gpu/drm/i915/display/intel_display_types.h
> @@ -624,6 +624,8 @@ struct intel_connector {
>   struct drm_dp_aux *dsc_decompression_aux;
>   u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE];
>   u8 fec_capability;
> +
> + u8 dsc_hblank_expansion_quirk:1;
>   } dp;
>  
>   /* Work struct to schedule a uevent on link train failure */
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index a1ea75cd5ea84..9124e9cdf4c79 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -345,8 +345,69 @@ static int intel_dp_mst_update_slots(struct 
> intel_encoder *encoder,
>   return 0;
>  }
>  
> +static bool
> +hblank_expansion_quirk_needs_dsc(const struct intel_connector *connector,
> +  const struct intel_crtc_state *crtc_state)
> +{
> + const struct drm_display_mode *adjusted_mode =
> + _state->hw.adjusted_mode;
> +
> + if (!connector->dp.dsc_hblank_expansion_quirk)
> + return false;
> +
> + if (adjusted_mode->htotal - adjusted_mode->hdisplay > 80)
> + return false;
> +
> + return true;
> +}
> +
> +static bool
> +adjust_limits_for_dsc_hblank_expansion_quirk(const struct intel_connector 
> *connector,
> +  const struct intel_crtc_state 
> *crtc_state,
> +  struct link_config_limits *limits,
> +  bool dsc)
> +{
> + struct drm_i915_private *i915 = to_i915(connector->base.dev);
> + const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> + int min_bpp_x16 = limits->link.min_bpp_x16;
> +
> + if (!hblank_expansion_quirk_needs_dsc(connector, crtc_state))
> + return true;
> +
> + if (!dsc) {
> + drm_dbg_kms(>drm,
> + "[CRTC:%d:%s][CONNECTOR:%d:%s] DSC required by 
> hblank expansion quirk\n",
> + crtc->base.base.id, crtc->base.name,
> + connector->base.base.id, connector->base.name);
> + return false;
> + }
> +
> + drm_WARN_ON(>drm, limits->min_rate != limits->max_rate);
> +
> + if (limits->max_rate < 54)
> + min_bpp_x16 = to_bpp_x16(13);
> + else if (limits->max_rate < 81)
> + min_bpp_x16 = to_bpp_x16(10);
> +
> + if (limits->link.min_bpp_x16 < min_bpp_x16) {
> + drm_dbg_kms(>drm,
> + "[CRTC:%d:%s][CONNECTOR:%d:%s] Increasing link min 
> bpp to " BPP_X16_FMT " due to hblank expansion quirk\n",
> + crtc->base.base.id, crtc->base.name,
> + connector->base.base.id, connector->base.name,
> + BPP_X16_ARGS(min_bpp_x16));
> +
> + if (limits->link.max_bpp_x16 < min_bpp_x16)
> + return false;
> +
> + limits->link.min_bpp_x16 = min_bpp_x16;
> + }
> +
> + return true;
> +}
> +
>  static bool
>  intel_dp_mst_compute_config_limits(struct intel_dp *intel_dp,
> +const struct intel_connector *connector,
>  struct intel_crtc_state *crtc_state,
>  bool dsc,
>  struct link_config_limits *limits)
> 

Re: [Intel-gfx] [PATCH 22/29] drm/i915/dp: Enable DSC via the connector decompression AUX

2023-10-25 Thread Lisovskiy, Stanislav
On Tue, Oct 24, 2023 at 04:09:18AM +0300, Imre Deak wrote:
> Enable DSC using the DSC AUX device stored for this purpose in the
> connector. This prepares for a follow-up patch which toggles DSC for
> each stream as needed, but for now keeps the current behavior, as DSC is
> still only enabled for the first MST stream.
> 
> Signed-off-by: Imre Deak 

Reviewed-by: Stanislav Lisovskiy 

> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c| 14 +++
>  drivers/gpu/drm/i915/display/intel_dp.c | 28 ++---
>  drivers/gpu/drm/i915/display/intel_dp.h |  2 +-
>  drivers/gpu/drm/i915/display/intel_dp_mst.c |  4 +--
>  4 files changed, 31 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
> b/drivers/gpu/drm/i915/display/intel_ddi.c
> index bc438272d6d1a..79e36939d92d1 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -2539,7 +2539,8 @@ static void mtl_ddi_pre_enable_dp(struct 
> intel_atomic_state *state,
>  
>   intel_dp_configure_protocol_converter(intel_dp, crtc_state);
>   if (!is_mst)
> - intel_dp_sink_set_decompression_state(intel_dp, crtc_state, 
> true);
> + 
> intel_dp_sink_set_decompression_state(to_intel_connector(conn_state->connector),
> +   crtc_state, true);
>  
>   /*
>* DDI FEC: "anticipates enabling FEC encoding sets the FEC_READY bit
> @@ -2692,7 +2693,8 @@ static void tgl_ddi_pre_enable_dp(struct 
> intel_atomic_state *state,
>  
>   intel_dp_configure_protocol_converter(intel_dp, crtc_state);
>   if (!is_mst)
> - intel_dp_sink_set_decompression_state(intel_dp, crtc_state, 
> true);
> + 
> intel_dp_sink_set_decompression_state(to_intel_connector(conn_state->connector),
> +   crtc_state, true);
>   /*
>* DDI FEC: "anticipates enabling FEC encoding sets the FEC_READY bit
>* in the FEC_CONFIGURATION register to 1 before initiating link
> @@ -2773,8 +2775,8 @@ static void hsw_ddi_pre_enable_dp(struct 
> intel_atomic_state *state,
>   intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
>   intel_dp_configure_protocol_converter(intel_dp, crtc_state);
>   if (!is_mst)
> - intel_dp_sink_set_decompression_state(intel_dp, crtc_state,
> -   true);
> + 
> intel_dp_sink_set_decompression_state(to_intel_connector(conn_state->connector),
> +   crtc_state, true);
>   intel_dp_sink_set_fec_ready(intel_dp, crtc_state, true);
>   intel_dp_start_link_train(intel_dp, crtc_state);
>   if ((port != PORT_A || DISPLAY_VER(dev_priv) >= 9) &&
> @@ -3354,6 +3356,8 @@ static void intel_disable_ddi_dp(struct 
> intel_atomic_state *state,
>const struct drm_connector_state 
> *old_conn_state)
>  {
>   struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> + struct intel_connector *connector =
> + to_intel_connector(old_conn_state->connector);
>  
>   intel_dp->link_trained = false;
>  
> @@ -3362,7 +3366,7 @@ static void intel_disable_ddi_dp(struct 
> intel_atomic_state *state,
>   intel_psr_disable(intel_dp, old_crtc_state);
>   intel_edp_backlight_off(old_conn_state);
>   /* Disable the decompression in DP Sink */
> - intel_dp_sink_set_decompression_state(intel_dp, old_crtc_state,
> + intel_dp_sink_set_decompression_state(connector, old_crtc_state,
> false);
>   /* Disable Ignore_MSA bit in DP Sink */
>   intel_dp_sink_set_msa_timing_par_ignore_state(intel_dp, old_crtc_state,
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index 7d185d6b2fe9d..a7eb31b489947 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -2937,22 +2937,32 @@ static bool downstream_hpd_needs_d0(struct intel_dp 
> *intel_dp)
>   intel_dp->downstream_ports[0] & DP_DS_PORT_HPD;
>  }
>  
> -void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp,
> +static void
> +intel_dp_sink_set_dsc_decompression(struct intel_connector *connector,
> + bool enable)
> +{
> + struct drm_i915_private *i915 = to_i915(connector->base.dev);
> +
> + if (drm_dp_dpcd_writeb(connector->dp.dsc_decompression_aux, 
> DP_DSC_ENABLE,
> +enable ? DP_DECOMPRESSION_EN : 0) < 0)
> + drm_dbg_kms(>drm,
> + "Failed to %s sink decompression state\n",
> + str_enable_disable(enable));
> +}
> +
> +void intel_dp_sink_set_decompression_state(struct intel_connector *connector,
>  const struct intel_crtc_state 
> 

Re: [Intel-gfx] [PATCH 19/29] drm/i915/dp: Disable FEC ready flag in the sink

2023-10-25 Thread Lisovskiy, Stanislav
On Tue, Oct 24, 2023 at 04:09:15AM +0300, Imre Deak wrote:
> Disable the FEC ready flag in the sink during a disabling modeset.
> 
> Signed-off-by: Imre Deak 

Reviewed-by: Stanislav Lisovskiy 

> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c | 21 +
>  1 file changed, 13 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
> b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 6f9d0f2ff3d9a..99d96762fa29c 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -2211,18 +2211,21 @@ static void 
> intel_dp_sink_set_msa_timing_par_ignore_state(struct intel_dp *intel
>  }
>  
>  static void intel_dp_sink_set_fec_ready(struct intel_dp *intel_dp,
> - const struct intel_crtc_state 
> *crtc_state)
> + const struct intel_crtc_state 
> *crtc_state,
> + bool enable)
>  {
>   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
>  
>   if (!crtc_state->fec_enable)
>   return;
>  
> - if (drm_dp_dpcd_writeb(_dp->aux, DP_FEC_CONFIGURATION, 
> DP_FEC_READY) <= 0)
> - drm_dbg_kms(>drm,
> - "Failed to set FEC_READY in the sink\n");
> + if (drm_dp_dpcd_writeb(_dp->aux, DP_FEC_CONFIGURATION,
> +enable ? DP_FEC_READY : 0) <= 0)
> + drm_dbg_kms(>drm, "Failed to set FEC_READY to %s in the 
> sink\n",
> + enable ? "enabled" : "disabled");
>  
> - if (drm_dp_dpcd_writeb(_dp->aux, DP_FEC_STATUS,
> + if (enable &&
> + drm_dp_dpcd_writeb(_dp->aux, DP_FEC_STATUS,
>  DP_FEC_DECODE_EN_DETECTED | 
> DP_FEC_DECODE_DIS_DETECTED) <= 0)
>   drm_dbg_kms(>drm, "Failed to clear FEC detected flags\n");
>  }
> @@ -2541,7 +2544,7 @@ static void mtl_ddi_pre_enable_dp(struct 
> intel_atomic_state *state,
>* in the FEC_CONFIGURATION register to 1 before initiating link
>* training
>*/
> - intel_dp_sink_set_fec_ready(intel_dp, crtc_state);
> + intel_dp_sink_set_fec_ready(intel_dp, crtc_state, true);
>  
>   intel_dp_check_frl_training(intel_dp);
>   intel_dp_pcon_dsc_configure(intel_dp, crtc_state);
> @@ -2692,7 +2695,7 @@ static void tgl_ddi_pre_enable_dp(struct 
> intel_atomic_state *state,
>* in the FEC_CONFIGURATION register to 1 before initiating link
>* training
>*/
> - intel_dp_sink_set_fec_ready(intel_dp, crtc_state);
> + intel_dp_sink_set_fec_ready(intel_dp, crtc_state, true);
>  
>   intel_dp_check_frl_training(intel_dp);
>   intel_dp_pcon_dsc_configure(intel_dp, crtc_state);
> @@ -2768,7 +2771,7 @@ static void hsw_ddi_pre_enable_dp(struct 
> intel_atomic_state *state,
>   intel_dp_configure_protocol_converter(intel_dp, crtc_state);
>   intel_dp_sink_set_decompression_state(intel_dp, crtc_state,
> true);
> - intel_dp_sink_set_fec_ready(intel_dp, crtc_state);
> + intel_dp_sink_set_fec_ready(intel_dp, crtc_state, true);
>   intel_dp_start_link_train(intel_dp, crtc_state);
>   if ((port != PORT_A || DISPLAY_VER(dev_priv) >= 9) &&
>   !is_trans_port_sync_mode(crtc_state))
> @@ -2997,6 +3000,8 @@ static void intel_ddi_post_disable_dp(struct 
> intel_atomic_state *state,
>  
>   intel_disable_ddi_buf(encoder, old_crtc_state);
>  
> + intel_dp_sink_set_fec_ready(intel_dp, old_crtc_state, false);
> +
>   /*
>* From TGL spec: "If single stream or multi-stream master transcoder:
>* Configure Transcoder Clock select to direct no clock to the
> -- 
> 2.39.2
> 


Re: [Intel-gfx] [PATCH 17/29] drm/i915/dp: Rename intel_ddi_disable_fec_state() to intel_ddi_disable_fec()

2023-10-25 Thread Lisovskiy, Stanislav
On Tue, Oct 24, 2023 at 04:09:13AM +0300, Imre Deak wrote:
> Rename intel_ddi_disable_fec_state() to intel_ddi_disable_fec(), for
> symmetry with intel_ddi_enable_fec().
> 
> Signed-off-by: Imre Deak 

Reviewed-by: Stanislav Lisovskiy 

> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c | 9 -
>  1 file changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
> b/drivers/gpu/drm/i915/display/intel_ddi.c
> index 721a5f28be808..dac3b59758af7 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -2234,8 +2234,8 @@ static void intel_ddi_enable_fec(struct intel_encoder 
> *encoder,
>0, DP_TP_CTL_FEC_ENABLE);
>  }
>  
> -static void intel_ddi_disable_fec_state(struct intel_encoder *encoder,
> - const struct intel_crtc_state 
> *crtc_state)
> +static void intel_ddi_disable_fec(struct intel_encoder *encoder,
> +   const struct intel_crtc_state *crtc_state)
>  {
>   struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>  
> @@ -2868,8 +2868,7 @@ static void disable_ddi_buf(struct intel_encoder 
> *encoder,
>   intel_de_rmw(dev_priv, dp_tp_ctl_reg(encoder, crtc_state),
>DP_TP_CTL_ENABLE, 0);
>  
> - /* Disable FEC in DP Sink */
> - intel_ddi_disable_fec_state(encoder, crtc_state);
> + intel_ddi_disable_fec(encoder, crtc_state);
>  
>   if (wait)
>   intel_wait_ddi_buf_idle(dev_priv, port);
> @@ -2884,7 +2883,7 @@ static void intel_disable_ddi_buf(struct intel_encoder 
> *encoder,
>   mtl_disable_ddi_buf(encoder, crtc_state);
>  
>   /* 3.f Disable DP_TP_CTL FEC Enable if it is needed */
> - intel_ddi_disable_fec_state(encoder, crtc_state);
> + intel_ddi_disable_fec(encoder, crtc_state);
>   } else {
>   disable_ddi_buf(encoder, crtc_state);
>   }
> -- 
> 2.39.2
> 


Re: [Intel-gfx] [PATCH 11/29] drm/i915/dp: Pass actual BW overhead to m_n calculation

2023-10-24 Thread Lisovskiy, Stanislav
On Tue, Oct 24, 2023 at 04:09:07AM +0300, Imre Deak wrote:
> A follow-up MST patch will need to specify the total BW allocation
> overhead, prepare for that here by passing the amount of overhead
> to intel_link_compute_m_n(), keeping the existing behavior.
> 
> Signed-off-by: Imre Deak 

Reviewed-by: Stanislav Lisovskiy 

> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 40 +---
>  drivers/gpu/drm/i915/display/intel_display.h |  4 +-
>  drivers/gpu/drm/i915/display/intel_dp.c  | 30 ---
>  drivers/gpu/drm/i915/display/intel_dp.h  |  2 +
>  drivers/gpu/drm/i915/display/intel_dp_mst.c  |  8 ++--
>  drivers/gpu/drm/i915/display/intel_fdi.c |  5 ++-
>  6 files changed, 71 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> b/drivers/gpu/drm/i915/display/intel_display.c
> index 28d85e1e858ea..de352d9c43439 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -2396,17 +2396,45 @@ static void compute_m_n(u32 *ret_m, u32 *ret_n,
>   intel_reduce_m_n_ratio(ret_m, ret_n);
>  }
>  
> +static void
> +add_bw_alloc_overhead(int link_clock, int bw_overhead,
> +   int pixel_data_rate, int link_data_rate,
> +   u32 *data_m, u32 *data_n)
> +{
> + bool is_uhbr = intel_dp_is_uhbr_rate(link_clock);
> + int ch_coding_efficiency =
> + drm_dp_bw_channel_coding_efficiency(is_uhbr);
> +
> + /*
> +  * TODO: adjust for actual UHBR channel coding efficiency and BW
> +  * overhead.
> +  */
> + if (is_uhbr) {
> + *data_m = pixel_data_rate;
> + *data_n = link_data_rate * 8 / 10;
> + return;
> + }
> +
> + *data_m = DIV_ROUND_UP_ULL(mul_u32_u32(pixel_data_rate, bw_overhead),
> +100);
> + *data_n = DIV_ROUND_DOWN_ULL(mul_u32_u32(link_data_rate, 
> ch_coding_efficiency),
> +  100);
> +}
> +
>  void
>  intel_link_compute_m_n(u16 bits_per_pixel, int nlanes,
>  int pixel_clock, int link_clock,
> -struct intel_link_m_n *m_n,
> -bool fec_enable)
> +int bw_overhead,
> +struct intel_link_m_n *m_n)
>  {
>   u32 data_clock = bits_per_pixel * pixel_clock;
> + u32 data_m;
> + u32 data_n;
>  
> - if (fec_enable)
> - data_clock = intel_dp_mode_to_fec_clock(data_clock);
> -
> + add_bw_alloc_overhead(link_clock, bw_overhead,
> +   data_clock,
> +   link_clock * 10 * nlanes,
> +   _m, _n);
>   /*
>* Windows/BIOS uses fixed M/N values always. Follow suit.
>*
> @@ -2416,7 +2444,7 @@ intel_link_compute_m_n(u16 bits_per_pixel, int nlanes,
>*/
>   m_n->tu = 64;
>   compute_m_n(_n->data_m, _n->data_n,
> - data_clock, link_clock * nlanes * 8,
> + data_m, data_n,
>   0x800);
>  
>   compute_m_n(_n->link_m, _n->link_n,
> diff --git a/drivers/gpu/drm/i915/display/intel_display.h 
> b/drivers/gpu/drm/i915/display/intel_display.h
> index 0e5dffe8f0189..dea3202849e72 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.h
> +++ b/drivers/gpu/drm/i915/display/intel_display.h
> @@ -395,8 +395,8 @@ u8 intel_calc_active_pipes(struct intel_atomic_state 
> *state,
>  u8 active_pipes);
>  void intel_link_compute_m_n(u16 bpp, int nlanes,
>   int pixel_clock, int link_clock,
> - struct intel_link_m_n *m_n,
> - bool fec_enable);
> + int bw_overhead,
> + struct intel_link_m_n *m_n);
>  u32 intel_plane_fb_max_stride(struct drm_i915_private *dev_priv,
> u32 pixel_format, u64 modifier);
>  enum drm_mode_status
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index 0c0f026fb3161..0235de5bb8cd1 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -121,10 +121,15 @@ bool intel_dp_is_edp(struct intel_dp *intel_dp)
>  
>  static void intel_dp_unset_edid(struct intel_dp *intel_dp);
>  
> +bool intel_dp_is_uhbr_rate(int rate)
> +{
> + return rate >= 100;
> +}
> +
>  /* Is link rate UHBR and thus 128b/132b? */
>  bool intel_dp_is_uhbr(const struct intel_crtc_state *crtc_state)
>  {
> - return crtc_state->port_clock >= 100;
> + return intel_dp_is_uhbr_rate(crtc_state->port_clock);
>  }
>  
>  static void intel_dp_set_default_sink_rates(struct intel_dp *intel_dp)
> @@ -684,6 +689,20 @@ u32 intel_dp_mode_to_fec_clock(u32 mode_clock)
>  100U);
>  }
>  
> +int intel_dp_bw_fec_overhead(bool fec_enabled)
> +{
> + /*
> +  * TODO: 

Re: [Intel-gfx] [PATCH 09/29] drm/i915/dp_mst: Enable FEC early once it's known DSC is needed

2023-10-24 Thread Lisovskiy, Stanislav
On Tue, Oct 24, 2023 at 04:09:05AM +0300, Imre Deak wrote:
> Enable FEC in crtc_state, as soon as it's known it will be needed by
> DSC. This fixes the calculation of BW allocation overhead, in case DSC
> is enabled by falling back to it during the encoder compute config
> phase (vs. enabling FEC due to DSC being enabled on other streams).
> 
> Signed-off-by: Imre Deak 

Reviewed-by: Stanislav Lisovskiy 

> ---
>  drivers/gpu/drm/i915/display/intel_dp.c | 6 +++---
>  drivers/gpu/drm/i915/display/intel_dp.h | 5 +
>  drivers/gpu/drm/i915/display/intel_dp_mst.c | 7 +++
>  3 files changed, 15 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index 1891c0cc187d1..2048649b420b2 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -1369,9 +1369,9 @@ static bool intel_dp_source_supports_fec(struct 
> intel_dp *intel_dp,
>   return false;
>  }
>  
> -static bool intel_dp_supports_fec(struct intel_dp *intel_dp,
> -   const struct intel_connector *connector,
> -   const struct intel_crtc_state *pipe_config)
> +bool intel_dp_supports_fec(struct intel_dp *intel_dp,
> +const struct intel_connector *connector,
> +const struct intel_crtc_state *pipe_config)
>  {
>   return intel_dp_source_supports_fec(intel_dp, pipe_config) &&
>   drm_dp_sink_supports_fec(connector->dp.fec_capability);
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
> b/drivers/gpu/drm/i915/display/intel_dp.h
> index 484aea215a251..0258580a6aadc 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.h
> +++ b/drivers/gpu/drm/i915/display/intel_dp.h
> @@ -137,6 +137,11 @@ static inline unsigned int intel_dp_unused_lane_mask(int 
> lane_count)
>  }
>  
>  u32 intel_dp_mode_to_fec_clock(u32 mode_clock);
> +
> +bool intel_dp_supports_fec(struct intel_dp *intel_dp,
> +const struct intel_connector *connector,
> +const struct intel_crtc_state *pipe_config);
> +
>  u32 intel_dp_dsc_nearest_valid_bpp(struct drm_i915_private *i915, u32 bpp, 
> u32 pipe_bpp);
>  
>  void intel_ddi_update_pipe(struct intel_atomic_state *state,
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index 80b3df6d51fc8..98d775d862ac4 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -338,6 +338,8 @@ static int intel_dp_mst_compute_config(struct 
> intel_encoder *encoder,
>   struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>   struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
>   struct intel_dp *intel_dp = _mst->primary->dp;
> + const struct intel_connector *connector =
> + to_intel_connector(conn_state->connector);
>   const struct drm_display_mode *adjusted_mode =
>   _config->hw.adjusted_mode;
>   struct link_config_limits limits;
> @@ -380,6 +382,11 @@ static int intel_dp_mst_compute_config(struct 
> intel_encoder *encoder,
>   ))
>   return -EINVAL;
>  
> + if (!intel_dp_supports_fec(intel_dp, connector, pipe_config))
> + return -EINVAL;
> +
> + pipe_config->fec_enable = !intel_dp_is_uhbr(pipe_config);
> +
>   /*
>* FIXME: As bpc is hardcoded to 8, as mentioned above,
>* WARN and ignore the debug flag force_dsc_bpc for now.
> -- 
> 2.39.2
> 


Re: [Intel-gfx] [PATCH 18/29] drm/i915/dp: Wait for FEC detected status in the sink

2023-10-24 Thread Lisovskiy, Stanislav
On Tue, Oct 24, 2023 at 04:09:14AM +0300, Imre Deak wrote:
> As required by the DP standard wait for the sink to detect the FEC
> decode enabling symbol sent by the source.
> 
> Signed-off-by: Imre Deak 

Reviewed-by: Stanislav Lisovskiy 

> ---
>  drivers/gpu/drm/i915/display/intel_ddi.c| 73 +
>  drivers/gpu/drm/i915/display/intel_ddi.h|  3 +
>  drivers/gpu/drm/i915/display/intel_dp_mst.c |  4 ++
>  3 files changed, 80 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c 
> b/drivers/gpu/drm/i915/display/intel_ddi.c
> index dac3b59758af7..6f9d0f2ff3d9a 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -25,6 +25,7 @@
>   *
>   */
>  
> +#include 
>  #include 
>  
>  #include 
> @@ -2220,6 +2221,74 @@ static void intel_dp_sink_set_fec_ready(struct 
> intel_dp *intel_dp,
>   if (drm_dp_dpcd_writeb(_dp->aux, DP_FEC_CONFIGURATION, 
> DP_FEC_READY) <= 0)
>   drm_dbg_kms(>drm,
>   "Failed to set FEC_READY in the sink\n");
> +
> + if (drm_dp_dpcd_writeb(_dp->aux, DP_FEC_STATUS,
> +DP_FEC_DECODE_EN_DETECTED | 
> DP_FEC_DECODE_DIS_DETECTED) <= 0)
> + drm_dbg_kms(>drm, "Failed to clear FEC detected flags\n");
> +}
> +
> +static int read_fec_detected_status(struct drm_dp_aux *aux)
> +{
> + int ret;
> + u8 status;
> +
> + ret = drm_dp_dpcd_readb(aux, DP_FEC_STATUS, );
> + if (ret < 0)
> + return ret;
> +
> + return status;
> +}
> +
> +static void wait_for_fec_detected(struct drm_dp_aux *aux, bool enabled)
> +{
> + struct drm_i915_private *i915 = to_i915(aux->drm_dev);
> + int mask = enabled ? DP_FEC_DECODE_EN_DETECTED : 
> DP_FEC_DECODE_DIS_DETECTED;
> + int status;
> + int err;
> +
> + err = readx_poll_timeout(read_fec_detected_status, aux, status,
> +  status & mask || status < 0,
> +  1, 20);
> +
> + if (!err && status >= 0)
> + return;
> +
> + if (err == -ETIMEDOUT)
> + drm_err(>drm, "Timeout waiting for FEC %s to get 
> detected\n",
> + str_enabled_disabled(enabled));
> + else
> + drm_dbg_kms(>drm, "FEC detected status read error: %d\n", 
> status);
> +}
> +
> +void intel_ddi_wait_for_fec_status(struct intel_encoder *encoder,
> +const struct intel_crtc_state *crtc_state,
> +bool enabled)
> +{
> + struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
> + struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> + int ret;
> +
> + if (!crtc_state->fec_enable)
> + return;
> +
> + if (enabled)
> + ret = intel_de_wait_for_set(i915, dp_tp_status_reg(encoder, 
> crtc_state),
> + DP_TP_STATUS_FEC_ENABLE_LIVE, 1);
> + else
> + ret = intel_de_wait_for_clear(i915, dp_tp_status_reg(encoder, 
> crtc_state),
> +   DP_TP_STATUS_FEC_ENABLE_LIVE, 1);
> +
> + if (ret)
> + drm_err(>drm,
> + "Timeout waiting for FEC live state to get %s\n",
> + str_enabled_disabled(enabled));
> +
> + /*
> +  * At least the Synoptics MST hub doesn't set the detected flag for
> +  * FEC decoding disabling so skip waiting for that.
> +  */
> + if (enabled)
> + wait_for_fec_detected(_dp->aux, enabled);
>  }
>  
>  static void intel_ddi_enable_fec(struct intel_encoder *encoder,
> @@ -2887,6 +2956,8 @@ static void intel_disable_ddi_buf(struct intel_encoder 
> *encoder,
>   } else {
>   disable_ddi_buf(encoder, crtc_state);
>   }
> +
> + intel_ddi_wait_for_fec_status(encoder, crtc_state, false);
>  }
>  
>  static void intel_ddi_post_disable_dp(struct intel_atomic_state *state,
> @@ -3248,6 +3319,8 @@ static void intel_enable_ddi(struct intel_atomic_state 
> *state,
>   if (!intel_crtc_is_bigjoiner_slave(crtc_state))
>   intel_ddi_enable_transcoder_func(encoder, crtc_state);
>  
> + intel_ddi_wait_for_fec_status(encoder, crtc_state, true);
> +
>   /* Enable/Disable DP2.0 SDP split config before transcoder */
>   intel_audio_sdp_split_update(crtc_state);
>  
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.h 
> b/drivers/gpu/drm/i915/display/intel_ddi.h
> index 4999c0ee229bd..e939b93fc81c2 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.h
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.h
> @@ -60,6 +60,9 @@ void intel_ddi_disable_transcoder_func(const struct 
> intel_crtc_state *crtc_state
>  void intel_ddi_enable_transcoder_clock(struct intel_encoder *encoder,
>  const struct intel_crtc_state 
> *crtc_state);
>  void intel_ddi_disable_transcoder_clock(const  struct intel_crtc_state 
> 

Re: [Intel-gfx] [PATCH] drm/i915/adl: Initialize all GV points as restricted in bw_state

2023-10-24 Thread Lisovskiy, Stanislav
On Tue, Oct 24, 2023 at 05:01:22PM +0300, Ville Syrjälä wrote:
> On Tue, Oct 24, 2023 at 03:52:56PM +0300, Stanislav Lisovskiy wrote:
> > In some customer cases, machine can start up with all
> > GV points restricted. However we don't ever read those
> > from hw and initial driver qgv_points_mask is initialized
> > as 0, which would make driver think that all points are unrestricted,
> > so we never update them with proper value, unless
> > some demanding scenario is requested or we have to toggle SAGV
> > and we have to restrict some of those.
> > Lets fix that by initializing all points as restricted,
> > then on first modeset, that will make sure driver will naturally
> > calculate, which of those need to be relaxed and do correspondent update.
> > 
> > Signed-off-by: Stanislav Lisovskiy 
> > ---
> >  drivers/gpu/drm/i915/display/intel_bw.c|  7 ---
> >  drivers/gpu/drm/i915/display/intel_bw.h|  1 +
> >  drivers/gpu/drm/i915/display/intel_modeset_setup.c | 13 +
> >  3 files changed, 18 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_bw.c 
> > b/drivers/gpu/drm/i915/display/intel_bw.c
> > index bef96db62c80..fbfa01f38db8 100644
> > --- a/drivers/gpu/drm/i915/display/intel_bw.c
> > +++ b/drivers/gpu/drm/i915/display/intel_bw.c
> > @@ -119,7 +119,7 @@ static int adls_pcode_read_psf_gv_point_info(struct 
> > drm_i915_private *dev_priv,
> > return 0;
> >  }
> >  
> > -static u16 icl_qgv_points_mask(struct drm_i915_private *i915)
> > +u16 icl_qgv_points_mask(struct drm_i915_private *i915)
> >  {
> > unsigned int num_psf_gv_points = 
> > i915->display.bw.max[0].num_psf_gv_points;
> > unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points;
> > @@ -1277,9 +1277,10 @@ int intel_bw_atomic_check(struct intel_atomic_state 
> > *state)
> >  
> > /*
> >  * If none of our inputs (data rates, number of active
> > -* planes, SAGV yes/no) changed then nothing to do here.
> > +* planes, SAGV yes/no) changed then nothing to do here,
> > +* except if mask turns out to be in wrong state initially.
> >  */
> > -   if (!changed)
> > +   if (!changed && (new_bw_state->qgv_points_mask != 
> > icl_qgv_points_mask(i915)))
> 
> There doesn't seem to be any guarantee that the bw state is
> actually present here. So this could oops.
> 
> But I'm thinking a better fix might be to do what we on
> older platforms and just force SAGV off at the start. That
> way we actually know what state the hardware will be in.

If you mean that by forcing SAGV off, we will also update
QGV point mask, leaving only the highest enabled, then yeah
that could be better solution.
Thing is that, as we can't read QGV point mask directly from
HW, it is better to always update it initially, to avoid
that kind of issues.

Stan

> 
> > return 0;
> >  
> > ret = intel_bw_check_qgv_points(i915, old_bw_state, new_bw_state);
> > diff --git a/drivers/gpu/drm/i915/display/intel_bw.h 
> > b/drivers/gpu/drm/i915/display/intel_bw.h
> > index 59cb4fc5db76..0a706ec79ce3 100644
> > --- a/drivers/gpu/drm/i915/display/intel_bw.h
> > +++ b/drivers/gpu/drm/i915/display/intel_bw.h
> > @@ -70,6 +70,7 @@ void intel_bw_crtc_update(struct intel_bw_state *bw_state,
> >   const struct intel_crtc_state *crtc_state);
> >  int icl_pcode_restrict_qgv_points(struct drm_i915_private *dev_priv,
> >   u32 points_mask);
> > +u16 icl_qgv_points_mask(struct drm_i915_private *i915);
> >  int intel_bw_calc_min_cdclk(struct intel_atomic_state *state,
> > bool *need_cdclk_calc);
> >  int intel_bw_min_cdclk(struct drm_i915_private *i915,
> > diff --git a/drivers/gpu/drm/i915/display/intel_modeset_setup.c 
> > b/drivers/gpu/drm/i915/display/intel_modeset_setup.c
> > index b8f43efb0ab5..230090c6e994 100644
> > --- a/drivers/gpu/drm/i915/display/intel_modeset_setup.c
> > +++ b/drivers/gpu/drm/i915/display/intel_modeset_setup.c
> > @@ -871,6 +871,19 @@ static void intel_modeset_readout_hw_state(struct 
> > drm_i915_private *i915)
> > intel_pmdemand_update_port_clock(i915, pmdemand_state, pipe,
> >  crtc_state->port_clock);
> >  
> > +   /*
> > +* In some customer cases, machine can start up with all
> > +* GV points restricted. However we don't ever read those
> > +* from hw and qgv_points_mask initialized as 0, would
> > +* make driver think that all points are unrestricted,
> > +* so we never update them with proper value, unless
> > +* some demanding scenario is requested and we have to
> > +* restrict some of those. Lets fix that by initializing
> > +* all points as restricted, then on first modeset, driver
> > +* will naturally calculate, which of those need to be
> > +* relaxed and do correspondent update.

Re: [Intel-gfx] [PATCH] drm/i915: Add bigjoiner force enable option to debugfs

2023-10-13 Thread Lisovskiy, Stanislav
On Thu, Oct 12, 2023 at 05:59:18PM +0300, Jani Nikula wrote:
> On Thu, 12 Oct 2023, Stanislav Lisovskiy  
> wrote:
> > For validation purposes, it might be useful to be able to
> > force Bigjoiner mode, even if current dotclock/resolution
> > do not require that.
> > Lets add such to option to debugfs.
> >
> > v2: - Apparently intel_dp_need_bigjoiner can't be used, when
> >   debugfs entry is created so lets just check manually
> >   the DISPLAY_VER.
> >
> > v3: - Switch to intel_connector from drm_connector(Jani Nikula)
> > - Remove redundant modeset lock(Jani Nikula)
> > - Use kstrtobool_from_user for boolean value(Jani Nikula)
> >
> > Signed-off-by: Stanislav Lisovskiy 
> > ---
> >  .../drm/i915/display/intel_display_debugfs.c  | 72 ++-
> >  .../drm/i915/display/intel_display_types.h|  2 +
> >  drivers/gpu/drm/i915/display/intel_dp.c   |  6 +-
> >  3 files changed, 76 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 fbe75d47a165..dea7bbea83ba 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > @@ -1398,13 +1398,37 @@ out:
> > drm_modeset_unlock(>mode_config.connection_mutex);
> > return ret;
> >  }
> >  
> > +static int i915_bigjoiner_enable_show(struct seq_file *m, void *data)
> > +{
> > +   struct intel_connector *connector = to_intel_connector(m->private);
> > +   struct drm_crtc *crtc;
> > +   struct intel_encoder *encoder = intel_attached_encoder(connector);
> > +   struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> > +   int ret;
> > +
> > +   if (!encoder)
> > +   return -ENODEV;
> > +
> > +   crtc = connector->base.state->crtc;
> > +   if (connector->base.status != connector_status_connected || !crtc) {
> > +   ret = -ENODEV;
> > +   goto out;
> > +   }
> > +
> > +   seq_printf(m, "Bigjoiner enable: %d\n", 
> > intel_dp->force_bigjoiner_enable);
> > +
> > +out:
> > +
> > +   return ret;
> > +}
> > +
> >  static ssize_t i915_dsc_output_format_write(struct file *file,
> > const char __user *ubuf,
> > size_t len, loff_t *offp)
> >  {
> > -   struct drm_connector *connector =
> > -   ((struct seq_file *)file->private_data)->private;
> > -   struct intel_encoder *encoder = 
> > intel_attached_encoder(to_intel_connector(connector));
> > +   struct seq_file *m = file->private_data;
> > +struct intel_connector *connector = m->private;
> > +   struct intel_encoder *encoder = intel_attached_encoder(connector);
> 
> Ooops, I think you made those changes to the wrong function there. ;)

Ouch, they looked exactly identical! I would say this could have been changed 
too,
but not in that patch indeed :)))
Thanks for spotting..probably really time to think about starting using glasses.

> 
> > struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> > int dsc_output_format = 0;
> > int ret;
> > @@ -1419,12 +1443,39 @@ static ssize_t i915_dsc_output_format_write(struct 
> > file *file,
> > return len;
> >  }
> >  
> > +static ssize_t i915_bigjoiner_enable_fops_write(struct file *file,
> > +   const char __user *ubuf,
> > +   size_t len, loff_t *offp)
> > +{
> > +   struct drm_connector *connector =
> > +   ((struct seq_file *)file->private_data)->private;
> > +   struct intel_encoder *encoder = 
> > intel_attached_encoder(to_intel_connector(connector));
> 
> Should be here.
> 
> > +   struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> > +   bool bigjoiner_en = 0;
> > +   int ret;
> > +
> > +   ret = kstrtobool_from_user(ubuf, len, _en);
> > +   if (ret < 0)
> > +   return ret;
> > +
> > +   intel_dp->force_bigjoiner_enable = bigjoiner_en;
> > +   *offp += len;
> > +
> > +   return len;
> > +}
> > +
> >  static int i915_dsc_output_format_open(struct inode *inode,
> >struct file *file)
> >  {
> > return single_open(file, i915_dsc_output_format_show, inode->i_private);
> >  }
> >  
> > +static int i915_bigjoiner_enable_open(struct inode *inode,
> > + struct file *file)
> > +{
> > +   return single_open(file, i915_bigjoiner_enable_show, inode->i_private);
> > +}
> > +
> >  static const struct file_operations i915_dsc_output_format_fops = {
> > .owner = THIS_MODULE,
> > .open = i915_dsc_output_format_open,
> > @@ -1434,6 +1485,15 @@ static const struct file_operations 
> > i915_dsc_output_format_fops = {
> > .write = i915_dsc_output_format_write
> >  };
> >  
> > +static const struct file_operations i915_bigjoiner_enable_fops = {
> > +   .owner = THIS_MODULE,
> > +   .open = i915_bigjoiner_enable_open,
> > +   .read = seq_read,
> > +   

Re: [Intel-gfx] [PATCH 1/3] drm/i915: Drop redundant !modeset check

2023-10-11 Thread Lisovskiy, Stanislav
On Wed, Oct 11, 2023 at 06:50:05PM +0300, Ville Syrjälä wrote:
> On Wed, Oct 11, 2023 at 04:47:00PM +0300, Lisovskiy, Stanislav wrote:
> > On Thu, Sep 07, 2023 at 03:25:39PM +0300, Ville Syrjala wrote:
> > > From: Ville Syrjälä 
> > > 
> > > Since commit 7de5b6b54630 ("drm/i915: Don't flag both full
> > > modeset and fastset at the same time")
> > > intel_crtc_needs_fastset() and intel_crtc_needs_modeset() have
> > > been mutually exclusive. Drop the redundant check.
> > > 
> > > Signed-off-by: Ville Syrjälä 
> > 
> > Let's see if the crash returns, however if it does then anyway
> > its time to change/refactor bigjoiner logic(as we suspected it
> > to be bigjoiner issue)
> 
> You must be thinking of some other patch.

Yeah right, it was about another one.
Anyways that change is ok for me.

Stan

> 
> > 
> > Reviewed-by: Stanislav Lisovskiy 
> > 
> > > ---
> > >  drivers/gpu/drm/i915/display/intel_display.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> > > b/drivers/gpu/drm/i915/display/intel_display.c
> > > index 83e1bc858b9f..526f38b502be 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > @@ -6606,7 +6606,7 @@ static void intel_update_crtc(struct 
> > > intel_atomic_state *state,
> > >* valid pipe configuration from the BIOS we need to take care
> > >* of enabling them on the CRTC's first fastset.
> > >*/
> > > - if (intel_crtc_needs_fastset(new_crtc_state) && !modeset &&
> > > + if (intel_crtc_needs_fastset(new_crtc_state) &&
> > >   old_crtc_state->inherited)
> > >   intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
> > >  }
> > > -- 
> > > 2.41.0
> > > 
> 
> -- 
> Ville Syrjälä
> Intel


Re: [Intel-gfx] [PATCH 3/3] drm/i915: Do plane/etc. updates more atomically across pipes

2023-10-11 Thread Lisovskiy, Stanislav
On Thu, Sep 07, 2023 at 03:25:41PM +0300, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> Perform all the intel_pre_update_crtc() stuff for all pipes first,
> and only then do the intel_update_crtc() vblank evasion stuff for
> every pipe back to back. This should make it more likely that
> the plane updates from multiple pipes happen on the same frame
> (assuming the pipes are running in sync, eg. due to bigjoiner
> or port sync).

Reviewed-by: Stanislav Lisovskiy 

> 
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 26 ++--
>  1 file changed, 24 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> b/drivers/gpu/drm/i915/display/intel_display.c
> index 7c19a0f380ca..f96230232a47 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -6711,6 +6711,12 @@ static void intel_commit_modeset_enables(struct 
> intel_atomic_state *state)
>  
>   intel_enable_crtc(state, crtc);
>   intel_pre_update_crtc(state, crtc);
> + }
> +
> + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
> + if (!new_crtc_state->hw.active)
> + continue;
> +
>   intel_update_crtc(state, crtc);
>   }
>  }
> @@ -6748,6 +6754,15 @@ static void skl_commit_modeset_enables(struct 
> intel_atomic_state *state)
>* So first lets enable all pipes that do not need a fullmodeset as
>* those don't have any external dependency.
>*/
> + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
> + enum pipe pipe = crtc->pipe;
> +
> + if ((update_pipes & BIT(pipe)) == 0)
> + continue;
> +
> + intel_pre_update_crtc(state, crtc);
> + }
> +
>   while (update_pipes) {
>   for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
>   new_crtc_state, i) {
> @@ -6763,7 +6778,6 @@ static void skl_commit_modeset_enables(struct 
> intel_atomic_state *state)
>   entries[pipe] = new_crtc_state->wm.skl.ddb;
>   update_pipes &= ~BIT(pipe);
>  
> - intel_pre_update_crtc(state, crtc);
>   intel_update_crtc(state, crtc);
>  
>   /*
> @@ -6819,6 +6833,15 @@ static void skl_commit_modeset_enables(struct 
> intel_atomic_state *state)
>   /*
>* Finally we do the plane updates/etc. for all pipes that got enabled.
>*/
> + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
> + enum pipe pipe = crtc->pipe;
> +
> + if ((update_pipes & BIT(pipe)) == 0)
> + continue;
> +
> + intel_pre_update_crtc(state, crtc);
> + }
> +
>   for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
>   enum pipe pipe = crtc->pipe;
>  
> @@ -6831,7 +6854,6 @@ static void skl_commit_modeset_enables(struct 
> intel_atomic_state *state)
>   entries[pipe] = new_crtc_state->wm.skl.ddb;
>   update_pipes &= ~BIT(pipe);
>  
> - intel_pre_update_crtc(state, crtc);
>   intel_update_crtc(state, crtc);
>   }
>  
> -- 
> 2.41.0
> 


Re: [Intel-gfx] [PATCH 1/3] drm/i915: Drop redundant !modeset check

2023-10-11 Thread Lisovskiy, Stanislav
On Thu, Sep 07, 2023 at 03:25:39PM +0300, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> Since commit 7de5b6b54630 ("drm/i915: Don't flag both full
> modeset and fastset at the same time")
> intel_crtc_needs_fastset() and intel_crtc_needs_modeset() have
> been mutually exclusive. Drop the redundant check.
> 
> Signed-off-by: Ville Syrjälä 

Let's see if the crash returns, however if it does then anyway
its time to change/refactor bigjoiner logic(as we suspected it
to be bigjoiner issue)

Reviewed-by: Stanislav Lisovskiy 

> ---
>  drivers/gpu/drm/i915/display/intel_display.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
> b/drivers/gpu/drm/i915/display/intel_display.c
> index 83e1bc858b9f..526f38b502be 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -6606,7 +6606,7 @@ static void intel_update_crtc(struct intel_atomic_state 
> *state,
>* valid pipe configuration from the BIOS we need to take care
>* of enabling them on the CRTC's first fastset.
>*/
> - if (intel_crtc_needs_fastset(new_crtc_state) && !modeset &&
> + if (intel_crtc_needs_fastset(new_crtc_state) &&
>   old_crtc_state->inherited)
>   intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
>  }
> -- 
> 2.41.0
> 


Re: [Intel-gfx] [PATCH] drm/i915: Add bigjoiner force enable option to debugfs

2023-10-11 Thread Lisovskiy, Stanislav
On Wed, Oct 11, 2023 at 11:49:38AM +0300, Jani Nikula wrote:
> On Mon, 09 Oct 2023, Stanislav Lisovskiy  
> wrote:
> > For validation purposes, it might be useful to be able to
> > force Bigjoiner mode, even if current dotclock/resolution
> > do not require that.
> > Lets add such to option to debugfs.
> >
> > v2: - Apparently intel_dp_need_bigjoiner can't be used, when
> >   debugfs entry is created so lets just check manually
> >   the DISPLAY_VER.
> >
> > Signed-off-by: Stanislav Lisovskiy 
> > ---
> >  .../drm/i915/display/intel_display_debugfs.c  | 71 +++
> >  .../drm/i915/display/intel_display_types.h|  2 +
> >  drivers/gpu/drm/i915/display/intel_dp.c   |  6 +-
> >  3 files changed, 78 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c 
> > b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > index f6d7c4d45fae..c806957cb902 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> > @@ -1399,6 +1399,35 @@ out: 
> > drm_modeset_unlock(>mode_config.connection_mutex);
> > return ret;
> >  }
> >  
> > +static int i915_bigjoiner_enable_show(struct seq_file *m, void *data)
> > +{
> > +   struct drm_connector *connector = m->private;
> 
> struct intel_connector *connector, please. Yeah, this is copy-paste from
> other files, but they should be changed too.
> 
> > +   struct drm_device *dev = connector->dev;
> 
> struct drm_i915_private *i915, please.
> 
> > +   struct drm_crtc *crtc;
> > +   struct intel_encoder *encoder = 
> > intel_attached_encoder(to_intel_connector(connector));
> > +   struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> > +   int ret;
> > +
> > +   if (!encoder)
> > +   return -ENODEV;
> > +
> > +   ret = 
> > drm_modeset_lock_single_interruptible(>mode_config.connection_mutex);
> > +   if (ret)
> > +   return ret;
> 
> Why does show need locking but write doesn't?
> 
> > +
> > +   crtc = connector->state->crtc;
> > +   if (connector->status != connector_status_connected || !crtc) {
> > +   ret = -ENODEV;
> > +   goto out;
> > +   }
> 
> I guess because of the above, but... do we need it? Or is this just
> copy-pasted from some other debugfs files, which copy-pasted from other
> debugfs files, which... ;)

Yeah, I would be honest here, had same question both for bool/int and crtc 
locking
however decided just to copy same approach, from other debugfs entries, assuming
that was done with some purpose :)

> 
> > +
> > +   seq_printf(m, "Bigjoiner enable: %d\n", intel_dp->force_bigjoiner_en);
> > +
> > +out:   drm_modeset_unlock(>mode_config.connection_mutex);
> > +
> > +   return ret;
> > +}
> > +
> >  static ssize_t i915_dsc_output_format_write(struct file *file,
> > const char __user *ubuf,
> > size_t len, loff_t *offp)
> > @@ -1420,12 +1449,39 @@ static ssize_t i915_dsc_output_format_write(struct 
> > file *file,
> > return len;
> >  }
> >  
> > +static ssize_t i915_bigjoiner_enable_fops_write(struct file *file,
> > +   const char __user *ubuf,
> > +   size_t len, loff_t *offp)
> > +{
> > +   struct drm_connector *connector =
> > +   ((struct seq_file *)file->private_data)->private;
> 
> I think this reads better with
> 
>   struct seq_file *m = file->private_data;
> struct intel_connector *connector = m->private;
> 
> > +   struct intel_encoder *encoder = 
> > intel_attached_encoder(to_intel_connector(connector));
> > +   struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> > +   int bigjoiner_en = 0;
> > +   int ret;
> > +
> > +   ret = kstrtoint_from_user(ubuf, len, 0, _en);
> > +   if (ret < 0)
> > +   return ret;
> 
> If it's a bool, why kstrtoint? Yeah, because copy-paste, but why keep
> percolating the same mistakes?

Yeah, as I said above..

> 
> > +
> > +   intel_dp->force_bigjoiner_en = bigjoiner_en;
> > +   *offp += len;
> > +
> > +   return len;
> > +}
> > +
> >  static int i915_dsc_output_format_open(struct inode *inode,
> >struct file *file)
> >  {
> > return single_open(file, i915_dsc_output_format_show, inode->i_private);
> >  }
> >  
> > +static int i915_bigjoiner_enable_open(struct inode *inode,
> > + struct file *file)
> > +{
> > +   return single_open(file, i915_bigjoiner_enable_show, inode->i_private);
> > +}
> > +
> >  static const struct file_operations i915_dsc_output_format_fops = {
> > .owner = THIS_MODULE,
> > .open = i915_dsc_output_format_open,
> > @@ -1435,6 +1491,15 @@ static const struct file_operations 
> > i915_dsc_output_format_fops = {
> > .write = i915_dsc_output_format_write
> >  };
> >  
> > +static const struct file_operations i915_bigjoiner_enable_fops = {
> > +  

Re: [Intel-gfx] [PATCH 09/19] drm/i915/dp: Use connector DSC DPCD in intel_dp_dsc_max_sink_compressed_bppx16()

2023-10-09 Thread Lisovskiy, Stanislav
On Fri, Oct 06, 2023 at 04:37:17PM +0300, Imre Deak wrote:
> Use the connector's DSC DPCD capabilities in
> intel_dp_dsc_max_sink_compressed_bppx16().
> 
> Signed-off-by: Imre Deak 

Reviewed-by: Stanislav Lisovskiy 

> ---
>  drivers/gpu/drm/i915/display/intel_dp.c | 19 +++
>  1 file changed, 11 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index 437bd972fb040..ff4090a602b4b 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -1767,11 +1767,11 @@ static int dsc_compute_link_config(struct intel_dp 
> *intel_dp,
>  }
>  
>  static
> -u16 intel_dp_dsc_max_sink_compressed_bppx16(struct intel_dp *intel_dp,
> +u16 intel_dp_dsc_max_sink_compressed_bppx16(const struct intel_connector 
> *connector,
>   struct intel_crtc_state 
> *pipe_config,
>   int bpc)
>  {
> - u16 max_bppx16 = drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd);
> + u16 max_bppx16 = drm_edp_dsc_sink_output_bpp(connector->dp.dsc_dpcd);
>  
>   if (max_bppx16)
>   return max_bppx16;
> @@ -1810,11 +1810,11 @@ static int dsc_sink_min_compressed_bpp(struct 
> intel_crtc_state *pipe_config)
>   return 0;
>  }
>  
> -static int dsc_sink_max_compressed_bpp(struct intel_dp *intel_dp,
> +static int dsc_sink_max_compressed_bpp(const struct intel_connector 
> *connector,
>  struct intel_crtc_state *pipe_config,
>  int bpc)
>  {
> - return intel_dp_dsc_max_sink_compressed_bppx16(intel_dp,
> + return intel_dp_dsc_max_sink_compressed_bppx16(connector,
>  pipe_config, bpc) >> 4;
>  }
>  
> @@ -1913,6 +1913,7 @@ xelpd_dsc_compute_link_config(struct intel_dp *intel_dp,
>  }
>  
>  static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp,
> +   const struct intel_connector *connector,
> struct intel_crtc_state *pipe_config,
> struct link_config_limits *limits,
> int pipe_bpp,
> @@ -1930,7 +1931,7 @@ static int dsc_compute_compressed_bpp(struct intel_dp 
> *intel_dp,
>   dsc_min_bpp = max(dsc_min_bpp, 
> to_bpp_int_roundup(limits->link.min_bpp_x16));
>  
>   dsc_src_max_bpp = dsc_src_max_compressed_bpp(intel_dp);
> - dsc_sink_max_bpp = dsc_sink_max_compressed_bpp(intel_dp, pipe_config, 
> pipe_bpp / 3);
> + dsc_sink_max_bpp = dsc_sink_max_compressed_bpp(connector, pipe_config, 
> pipe_bpp / 3);
>   dsc_max_bpp = dsc_sink_max_bpp ? min(dsc_sink_max_bpp, dsc_src_max_bpp) 
> : dsc_src_max_bpp;
>  
>   dsc_joiner_max_bpp = get_max_compressed_bpp_with_joiner(i915, 
> adjusted_mode->clock,
> @@ -2002,6 +2003,8 @@ static int intel_dp_dsc_compute_pipe_bpp(struct 
> intel_dp *intel_dp,
>int timeslots)
>  {
>   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> + const struct intel_connector *connector =
> + to_intel_connector(conn_state->connector);
>   u8 max_req_bpc = conn_state->max_requested_bpc;
>   u8 dsc_max_bpc, dsc_max_bpp;
>   u8 dsc_min_bpc, dsc_min_bpp;
> @@ -2012,7 +2015,7 @@ static int intel_dp_dsc_compute_pipe_bpp(struct 
> intel_dp *intel_dp,
>   forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, conn_state, limits);
>  
>   if (forced_bpp) {
> - ret = dsc_compute_compressed_bpp(intel_dp, pipe_config,
> + ret = dsc_compute_compressed_bpp(intel_dp, connector, 
> pipe_config,
>limits, forced_bpp, timeslots);
>   if (ret == 0) {
>   pipe_config->pipe_bpp = forced_bpp;
> @@ -2041,7 +2044,7 @@ static int intel_dp_dsc_compute_pipe_bpp(struct 
> intel_dp *intel_dp,
>   break;
>   if (pipe_bpp > dsc_max_bpp)
>   continue;
> - ret = dsc_compute_compressed_bpp(intel_dp, pipe_config,
> + ret = dsc_compute_compressed_bpp(intel_dp, connector, 
> pipe_config,
>limits, pipe_bpp, timeslots);
>   if (ret == 0) {
>   pipe_config->pipe_bpp = pipe_bpp;
> @@ -2088,7 +2091,7 @@ static int intel_edp_dsc_compute_pipe_bpp(struct 
> intel_dp *intel_dp,
>   dsc_min_bpp = max(dsc_min_bpp, 
> to_bpp_int_roundup(limits->link.min_bpp_x16));
>  
>   dsc_src_max_bpp = dsc_src_max_compressed_bpp(intel_dp);
> - dsc_sink_max_bpp = dsc_sink_max_compressed_bpp(intel_dp, pipe_config, 
> pipe_bpp / 3);
> + dsc_sink_max_bpp = dsc_sink_max_compressed_bpp(connector, pipe_config, 
> pipe_bpp / 3);
>   dsc_max_bpp = dsc_sink_max_bpp ? min(dsc_sink_max_bpp, dsc_src_max_bpp) 
> : 

Re: [Intel-gfx] [PATCH 08/19] drm/i915/dp: Use connector DSC DPCD in intel_dp_supports_dsc()

2023-10-09 Thread Lisovskiy, Stanislav
On Fri, Oct 06, 2023 at 04:37:16PM +0300, Imre Deak wrote:
> Use the connector's DSC DPCD capabilities in intel_dp_supports_dsc().
> 
> Signed-off-by: Imre Deak 

Reviewed-by: Stanislav Lisovskiy 

> ---
>  drivers/gpu/drm/i915/display/intel_dp.c | 6 +++---
>  1 file 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 8450856e5618d..437bd972fb040 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -1377,14 +1377,14 @@ static bool intel_dp_supports_fec(struct intel_dp 
> *intel_dp,
>   drm_dp_sink_supports_fec(connector->dp.fec_capability);
>  }
>  
> -static bool intel_dp_supports_dsc(struct intel_dp *intel_dp,
> +static bool intel_dp_supports_dsc(const struct intel_connector *connector,
> const struct intel_crtc_state *crtc_state)
>  {
>   if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP) && 
> !crtc_state->fec_enable)
>   return false;
>  
>   return intel_dsc_source_support(crtc_state) &&
> - drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd);
> + drm_dp_sink_supports_dsc(connector->dp.dsc_dpcd);
>  }
>  
>  static int intel_dp_hdmi_compute_bpc(struct intel_dp *intel_dp,
> @@ -2120,7 +2120,7 @@ int intel_dp_dsc_compute_config(struct intel_dp 
> *intel_dp,
>   pipe_config->fec_enable = !intel_dp_is_edp(intel_dp) &&
>   intel_dp_supports_fec(intel_dp, connector, pipe_config);
>  
> - if (!intel_dp_supports_dsc(intel_dp, pipe_config))
> + if (!intel_dp_supports_dsc(connector, pipe_config))
>   return -EINVAL;
>  
>   if (!intel_dp_dsc_supports_format(intel_dp, pipe_config->output_format))
> -- 
> 2.39.2
> 


Re: [Intel-gfx] [PATCH 07/19] drm/i915/dp: Use connector DSC DPCD in intel_dp_supports_fec()

2023-10-09 Thread Lisovskiy, Stanislav
On Fri, Oct 06, 2023 at 04:37:15PM +0300, Imre Deak wrote:
> Use the connector's DSC DPCD capabilities in intel_dp_supports_fec().
> 
> Signed-off-by: Imre Deak 

Reviewed-by: Stanislav Lisovskiy 

> ---
>  drivers/gpu/drm/i915/display/intel_dp.c | 7 +--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index 00f5fecdbf386..8450856e5618d 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -1370,10 +1370,11 @@ static bool intel_dp_source_supports_fec(struct 
> intel_dp *intel_dp,
>  }
>  
>  static bool intel_dp_supports_fec(struct intel_dp *intel_dp,
> +   const struct intel_connector *connector,
> const struct intel_crtc_state *pipe_config)
>  {
>   return intel_dp_source_supports_fec(intel_dp, pipe_config) &&
> - drm_dp_sink_supports_fec(intel_dp->fec_capable);
> + drm_dp_sink_supports_fec(connector->dp.fec_capability);
>  }
>  
>  static bool intel_dp_supports_dsc(struct intel_dp *intel_dp,
> @@ -2110,12 +2111,14 @@ int intel_dp_dsc_compute_config(struct intel_dp 
> *intel_dp,
>  {
>   struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
>   struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
> + const struct intel_connector *connector =
> + to_intel_connector(conn_state->connector);
>   const struct drm_display_mode *adjusted_mode =
>   _config->hw.adjusted_mode;
>   int ret;
>  
>   pipe_config->fec_enable = !intel_dp_is_edp(intel_dp) &&
> - intel_dp_supports_fec(intel_dp, pipe_config);
> + intel_dp_supports_fec(intel_dp, connector, pipe_config);
>  
>   if (!intel_dp_supports_dsc(intel_dp, pipe_config))
>   return -EINVAL;
> -- 
> 2.39.2
> 


Re: [Intel-gfx] [PATCH 06/19] drm/i915/dp: Use connector DSC DPCD in intel_dp_dsc_compute_max_bpp()

2023-10-09 Thread Lisovskiy, Stanislav
On Fri, Oct 06, 2023 at 04:37:14PM +0300, Imre Deak wrote:
> Use the connector's DSC DPCD capabilities in intel_dp_dsc_compute_max_bpp()
> instead of the version stored in the encoder.
> 
> Signed-off-by: Imre Deak 

Reviewed-by: Stanislav Lisovskiy 

> ---
>  drivers/gpu/drm/i915/display/intel_dp.c | 13 -
>  drivers/gpu/drm/i915/display/intel_dp.h |  3 ++-
>  drivers/gpu/drm/i915/display/intel_dp_mst.c |  2 +-
>  3 files changed, 11 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index 6e6b3fe593453..00f5fecdbf386 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -1215,7 +1215,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
>* TBD pass the connector BPC,
>* for now U8_MAX so that max BPC on that platform would be 
> picked
>*/
> - pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, U8_MAX);
> + pipe_bpp = intel_dp_dsc_compute_max_bpp(connector, U8_MAX);
>  
>   /*
>* Output bpp is stored in 6.4 format so right shift by 4 to 
> get the
> @@ -1577,9 +1577,10 @@ u8 intel_dp_dsc_max_src_input_bpc(struct 
> drm_i915_private *i915)
>   return 0;
>  }
>  
> -int intel_dp_dsc_compute_max_bpp(struct intel_dp *intel_dp, u8 max_req_bpc)
> +int intel_dp_dsc_compute_max_bpp(const struct intel_connector *connector,
> +  u8 max_req_bpc)
>  {
> - struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> + struct drm_i915_private *i915 = to_i915(connector->base.dev);
>   int i, num_bpc;
>   u8 dsc_bpc[3] = {0};
>   u8 dsc_max_bpc;
> @@ -1591,7 +1592,7 @@ int intel_dp_dsc_compute_max_bpp(struct intel_dp 
> *intel_dp, u8 max_req_bpc)
>  
>   dsc_max_bpc = min_t(u8, dsc_max_bpc, max_req_bpc);
>  
> - num_bpc = drm_dp_dsc_sink_supported_input_bpcs(intel_dp->dsc_dpcd,
> + num_bpc = drm_dp_dsc_sink_supported_input_bpcs(connector->dp.dsc_dpcd,
>  dsc_bpc);
>   for (i = 0; i < num_bpc; i++) {
>   if (dsc_max_bpc >= dsc_bpc[i])
> @@ -2056,6 +2057,8 @@ static int intel_edp_dsc_compute_pipe_bpp(struct 
> intel_dp *intel_dp,
> struct link_config_limits *limits)
>  {
>   struct drm_i915_private *i915 = dp_to_i915(intel_dp);
> + struct intel_connector *connector =
> + to_intel_connector(conn_state->connector);
>   int pipe_bpp, forced_bpp;
>   int dsc_src_min_bpp, dsc_sink_min_bpp, dsc_min_bpp;
>   int dsc_src_max_bpp, dsc_sink_max_bpp, dsc_max_bpp;
> @@ -2068,7 +2071,7 @@ static int intel_edp_dsc_compute_pipe_bpp(struct 
> intel_dp *intel_dp,
>   int max_bpc = min(limits->pipe.max_bpp / 3, 
> (int)conn_state->max_requested_bpc);
>  
>   /* For eDP use max bpp that can be supported with DSC. */
> - pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, max_bpc);
> + pipe_bpp = intel_dp_dsc_compute_max_bpp(connector, max_bpc);
>   if (!is_dsc_pipe_bpp_sufficient(i915, conn_state, limits, 
> pipe_bpp)) {
>   drm_dbg_kms(>drm,
>   "Computed BPC is not in DSC BPC limits\n");
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.h 
> b/drivers/gpu/drm/i915/display/intel_dp.h
> index bd9cb9680b4cd..af87aa2a5ed67 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.h
> +++ b/drivers/gpu/drm/i915/display/intel_dp.h
> @@ -116,7 +116,8 @@ void intel_read_dp_sdp(struct intel_encoder *encoder,
>  struct intel_crtc_state *crtc_state,
>  unsigned int type);
>  bool intel_digital_port_connected(struct intel_encoder *encoder);
> -int intel_dp_dsc_compute_max_bpp(struct intel_dp *intel_dp, u8 dsc_max_bpc);
> +int intel_dp_dsc_compute_max_bpp(const struct intel_connector *connector,
> +  u8 dsc_max_bpc);
>  u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915,
>   u32 link_clock, u32 lane_count,
>   u32 mode_clock, u32 mode_hdisplay,
> diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
> b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> index e01f669d2c8a1..3ff429c30f300 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> @@ -1003,7 +1003,7 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector 
> *connector,
>* TBD pass the connector BPC,
>* for now U8_MAX so that max BPC on that platform would be 
> picked
>*/
> - int pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, U8_MAX);
> + int pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_connector, 
> U8_MAX);
>  
>   if 

Re: [Intel-gfx] [PATCH 05/19] drm/i915/dp: Use connector DSC DPCD in i915_dsc_fec_support_show()

2023-10-09 Thread Lisovskiy, Stanislav
On Fri, Oct 06, 2023 at 04:37:13PM +0300, Imre Deak wrote:
> Use the connector's DSC DPCD capabilities in i915_dsc_fec_support_show()
> instead of the version stored in the encoder. Atm the two are identical,
> but a follow-up patch will store the (MST) connector specific version
> in the connector.
> 
> Signed-off-by: Imre Deak 

Reviewed-by: Stanislav Lisovskiy 

> ---
>  drivers/gpu/drm/i915/display/intel_display_debugfs.c | 10 +-
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c 
> b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> index 834a8e50ea4fb..2836826f8c05f 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> @@ -1234,19 +1234,19 @@ static int i915_dsc_fec_support_show(struct seq_file 
> *m, void *data)
>   seq_printf(m, "DSC_Enabled: %s\n",
>  str_yes_no(crtc_state->dsc.compression_enable));
>   seq_printf(m, "DSC_Sink_Support: %s\n",
> -
> str_yes_no(drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd)));
> +
> str_yes_no(drm_dp_sink_supports_dsc(connector->dp.dsc_dpcd)));
>   seq_printf(m, "DSC_Output_Format_Sink_Support: RGB: %s 
> YCBCR420: %s YCBCR444: %s\n",
> -
> str_yes_no(drm_dp_dsc_sink_supports_format(intel_dp->dsc_dpcd,
> +
> str_yes_no(drm_dp_dsc_sink_supports_format(connector->dp.dsc_dpcd,
> 
> DP_DSC_RGB)),
> -
> str_yes_no(drm_dp_dsc_sink_supports_format(intel_dp->dsc_dpcd,
> +
> str_yes_no(drm_dp_dsc_sink_supports_format(connector->dp.dsc_dpcd,
> 
> DP_DSC_YCbCr420_Native)),
> -
> str_yes_no(drm_dp_dsc_sink_supports_format(intel_dp->dsc_dpcd,
> +
> str_yes_no(drm_dp_dsc_sink_supports_format(connector->dp.dsc_dpcd,
> 
> DP_DSC_YCbCr444)));
>   seq_printf(m, "Force_DSC_Enable: %s\n",
>  str_yes_no(intel_dp->force_dsc_en));
>   if (!intel_dp_is_edp(intel_dp))
>   seq_printf(m, "FEC_Sink_Support: %s\n",
> -
> str_yes_no(drm_dp_sink_supports_fec(intel_dp->fec_capable)));
> +
> str_yes_no(drm_dp_sink_supports_fec(connector->dp.fec_capability)));
>   } while (try_again);
>  
>   drm_modeset_drop_locks();
> -- 
> 2.39.2
> 


  1   2   3   4   5   6   7   8   >