Re: [Intel-gfx] [PATCH] drm/i915: Move MCHBAR registers to their own header

2022-02-14 Thread Ville Syrjälä
On Mon, Feb 14, 2022 at 10:03:25PM -0800, Matt Roper wrote:
> On Fri, Feb 11, 2022 at 10:41:53AM +0200, Ville Syrjälä wrote:
> > On Thu, Feb 10, 2022 at 03:12:17PM -0800, Matt Roper wrote:
> > > Registers that exist within the MCH BAR and are mirrored into the GPU's
> > > MMIO space are a good candidate to separate out into their own header.
> > > 
> > > For reference, the mirror of the MCH BAR lives at the following
> > > locations in the graphics MMIO space:
> > > 
> > >  * Pre-gen6:   0x1 -  0x13000
> > 
> > Should go up to 0x14000 according to some docs I have.
> 
> I think I was looking at a gm45 PRM for this.  Given the spotty
> documentation on the older platforms and the number of different end
> points there seem to be, maybe it's a better idea to just give the
> starting offset in the commit message and say that the upper bound
> varies.

Sounds good.

> 
> > 
> > >  * Gen6-Gen11 + RKL:  0x14 - 0x14
> > 
> > Some docs say this goes up to 0x18, other docs have different
> > numbers. I suppose it doesn't matter all that much really. And
> > BXT+ clearly can't go past 0x16 since IIRC that's where some
> > of the PHY/PLL stuff lives.
> > 
> > >  * TGL, ADL:  0x14 - 0x15
> > > 
> > > Bspec: 134, 51771
> > > Cc: Ville Syrjälä 
> > > Suggested-by: Ville Syrjälä 
> > > Signed-off-by: Matt Roper 
> > 
> > > -#define GEN6_GT_PERF_STATUS  _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5948)
> > > -#define BXT_GT_PERF_STATUS  _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x7070)
> > > -#define GEN6_RP_STATE_LIMITS _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5994)
> > > -#define GEN6_RP_STATE_CAP_MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5998)
> > > -#define   RP0_CAP_MASK   REG_GENMASK(7, 0)
> > > -#define   RP1_CAP_MASK   REG_GENMASK(15, 8)
> > > -#define   RPN_CAP_MASK   REG_GENMASK(23, 16)
> > >  #define BXT_RP_STATE_CAP_MMIO(0x138170)
> > >  #define GEN9_RP_STATE_LIMITS _MMIO(0x138148)
> > >  #define XEHPSDV_RP_STATE_CAP _MMIO(0x250014)
> > 
> > :( This is a bit unfortunate. I wonder if we should make an exception
> > for these and keep them all together somewhere?
> 
> I don't really see a problem with having them in separate headers.  We
> have other stuff like ILK_GDSR / GEN6_GDRST that also used to be in the
> MCHBAR and then moved to the GT proper.

ILK_GDSR is not just about the GT but it can reset the 
display engine too. IIRC GEN6_GDRST can't do that.

> I believe the MCHBAR mirror is
> going away completely a platform or two down the road and all the
> important registers are migrating to non-MCHBAR offsets, so if we try to
> keep them all together, that defeats most of the purpose of having a
> separate MCHBAR header?

Not sure. Sadly there is no clear theme to some of the
MCHBAR registers so I'm not sure where else we'd place them
(assuming the plan is basically to hollow out i915_regs.h).

I guess we could start with what you have here and if it turns
out annoying we can always come up with something different later.

-- 
Ville Syrjälä
Intel


Re: [Intel-gfx] [RFC PATCH v2 0/1] Splitting up platform-specific calls

2022-02-14 Thread Lucas De Marchi

On Mon, Feb 14, 2022 at 10:05:56PM -0800, Casey Bowman wrote:


On 2/11/22 05:51, Tvrtko Ursulin wrote:


On 11/02/2022 11:55, Jani Nikula wrote:

On Thu, 10 Feb 2022, Casey Bowman  wrote:

In this RFC I would like to ask the community their thoughts
on how we can best handle splitting architecture-specific
calls.

I would like to address the following:

1. How do we want to split architecture calls? Different object files
per platform? Separate function calls within the same object file?

2. How do we address dummy functions? If we have a function call 
that is

used for one or more platforms, but is not used in another, what should
we do for this case?

I've given an example of splitting an architecture call
in my patch with run_as_guest() being split into different
implementations for x86 and arm64 in separate object files, sharing
a single header.

Another suggestion from Michael (michael.ch...@intel.com) involved
using a single object file, a single header, and splitting various
functions calls via ifdefs in the header file.

I would appreciate any input on how we can avoid scaling issues when
including multiple architectures and multiple functions (as the number
of function calls will inevitably increase with more architectures).

v2: Revised to use kernel's platform-splitting scheme.


I think this is overengineering.

Just add different implementations of the functions per architecture
next to where they are now, like I suggested before.

If we need to split them better later, it'll be a trivial undertaking,
and we'll be in a better position to do it because we'll know how many
functions there'll be and where they are and what they do.

Adding a bunch of overhead from the start seems like the wrong thing to
do.


I don't see it adds real complexity, which would normally be 
associated with over-engineering. As a benefit I see it helping with 
driving the clean re-design (during the porting effort) in a way 
that it will be easy to spot is something is overly hacky, split on 
the wrong level, or incorrectly placed.


And it moves run_as_guest outside of intel_vtd.[hc] which IMO shows 
immediate benefit, since it has nothing to do with intel_vtd.


I suggested to add clflush as well, since I think going for 
drm_flush_virt_range everywhere is a bit lazy given how it is a 
clear regression for older platforms.


But after that I indeed don't have a crystal ball to show me how 
many more appropriate low-level primitives would be to use the 
pattern.


So my vote would be to go with it, although the main thing is 
probably to solve the conflicting asks and let guys focus on the 
port. Put it to voting then? :)


If we can get someone else to weigh in here to break the tie, that'd 
be helpful :)


I don't like much the split with platforms because a) I don't think we
have too many users to deserve that, b) if we do have something that is
common and should be abstracted in that way, it should probably be
outside of i915: find somewhere in the kernel that is the proper place
to add that and c) usually we will have "do one thing for x86, do
another for all the rest" - and the split per platform forces us to add
an implementation for each platform (or add a generic/ to account for
the absence of something). There will usually be one (x86) that will
be very different than the rest.

So my vote is to go with Jani's proposal.

Lucas De Marchi



Regards,
Casey



[Intel-gfx] [PATCH] drm/i915: Fix cursor coordinates on bigjoiner slave

2022-02-14 Thread Ville Syrjala
From: Ville Syrjälä 

Adjust the cursor dst coordinates appripriately when it's on
the bigjoiner slave pipe. intel_atomic_plane_check_clipping()
already did this but with the cursor we discard those results
(apart from uapi.visible and error checks) since the hardware
will be doing the clipping for us.

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

diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c 
b/drivers/gpu/drm/i915/display/intel_cursor.c
index 2ade8fdd9bdd..5b600679674f 100644
--- a/drivers/gpu/drm/i915/display/intel_cursor.c
+++ b/drivers/gpu/drm/i915/display/intel_cursor.c
@@ -152,6 +152,9 @@ static int intel_check_cursor(struct intel_crtc_state 
*crtc_state,
/* Use the unclipped src/dst rectangles, which we program to hw */
plane_state->uapi.src = src;
plane_state->uapi.dst = dst;
+   if (crtc_state->bigjoiner_slave)
+   drm_rect_translate(_state->uapi.dst,
+  -crtc_state->pipe_src_w, 0);
 
ret = intel_cursor_check_surface(plane_state);
if (ret)
-- 
2.34.1



[Intel-gfx] [PATCH v2 2/2] drm/i915: Move MCHBAR registers to their own header

2022-02-14 Thread Matt Roper
Registers that exist within the MCH BAR and are mirrored into the GPU's
MMIO space are a good candidate to separate out into their own header.

For reference, the mirror of the MCH BAR starts at the following
locations in the graphics MMIO space (the end of the MCHBAR range
differs slightly on each platform):

 * Pre-gen6:   0x1
 * Gen6-Gen11 + RKL:  0x14

v2:
 - Create separate patch to swtich a few register definitions to be
   relative to the MCHBAR mirror base.
 - Drop upper bound of MCHBAR mirror from commit message; there are too
   many different combinations between various platforms to list out,
   and the documentation is spotty for the older pre-gen6 platforms
   anyway.

Bspec: 134, 51771
Cc: Ville Syrjälä 
Suggested-by: Ville Syrjälä 
Signed-off-by: Matt Roper 
---
 drivers/gpu/drm/i915/display/intel_bw.c   |   1 +
 drivers/gpu/drm/i915/display/intel_cdclk.c|   1 +
 .../drm/i915/display/intel_display_power.c|   1 +
 drivers/gpu/drm/i915/gem/i915_gem_stolen.c|   1 +
 drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c  |   1 +
 drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c |   1 +
 drivers/gpu/drm/i915/gt/intel_gt_regs.h   |   7 -
 drivers/gpu/drm/i915/gt/intel_llc.c   |   1 +
 drivers/gpu/drm/i915/gt/intel_reset.c |   1 +
 drivers/gpu/drm/i915/gt/intel_rps.c   |   1 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c   |   1 +
 drivers/gpu/drm/i915/gvt/handlers.c   |   1 +
 drivers/gpu/drm/i915/i915_debugfs.c   |   1 +
 drivers/gpu/drm/i915/i915_reg.h   | 203 
 drivers/gpu/drm/i915/intel_dram.c |   1 +
 drivers/gpu/drm/i915/intel_mchbar_regs.h  | 221 ++
 drivers/gpu/drm/i915/intel_pm.c   |   1 +
 17 files changed, 235 insertions(+), 210 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/intel_mchbar_regs.h

diff --git a/drivers/gpu/drm/i915/display/intel_bw.c 
b/drivers/gpu/drm/i915/display/intel_bw.c
index 23aa8e06de18..7bbe0dc5926b 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_bw.c
@@ -10,6 +10,7 @@
 #include "intel_bw.h"
 #include "intel_cdclk.h"
 #include "intel_display_types.h"
+#include "intel_mchbar_regs.h"
 #include "intel_pcode.h"
 #include "intel_pm.h"
 
diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c 
b/drivers/gpu/drm/i915/display/intel_cdclk.c
index 118ef391b560..fda8b701 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -32,6 +32,7 @@
 #include "intel_crtc.h"
 #include "intel_de.h"
 #include "intel_display_types.h"
+#include "intel_mchbar_regs.h"
 #include "intel_pci_config.h"
 #include "intel_pcode.h"
 #include "intel_psr.h"
diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c 
b/drivers/gpu/drm/i915/display/intel_display_power.c
index d2102cc17bb4..9ebae7ac3235 100644
--- a/drivers/gpu/drm/i915/display/intel_display_power.c
+++ b/drivers/gpu/drm/i915/display/intel_display_power.c
@@ -16,6 +16,7 @@
 #include "intel_dpio_phy.h"
 #include "intel_dpll.h"
 #include "intel_hotplug.h"
+#include "intel_mchbar_regs.h"
 #include "intel_pch_refclk.h"
 #include "intel_pcode.h"
 #include "intel_pm.h"
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c 
b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
index 1de73a644965..b9c3196b91ca 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
@@ -16,6 +16,7 @@
 #include "i915_gem_stolen.h"
 #include "i915_reg.h"
 #include "i915_vgpu.h"
+#include "intel_mchbar_regs.h"
 
 /*
  * The BIOS typically reserves some of the system's memory for the exclusive
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c 
b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c
index ee4049ee1fc9..76880fb8fc19 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c
@@ -9,6 +9,7 @@
 #include "i915_pvinfo.h"
 #include "i915_vgpu.h"
 #include "intel_gt_regs.h"
+#include "intel_mchbar_regs.h"
 
 /**
  * DOC: fence register handling
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c 
b/drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c
index 4e448c13a64c..37765919fe32 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_pm_debugfs.c
@@ -15,6 +15,7 @@
 #include "intel_gt_pm_debugfs.h"
 #include "intel_gt_regs.h"
 #include "intel_llc.h"
+#include "intel_mchbar_regs.h"
 #include "intel_pcode.h"
 #include "intel_rc6.h"
 #include "intel_rps.h"
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h 
b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
index a6f0220c2e9f..296d6425bb0a 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
@@ -8,13 +8,6 @@
 
 #include "i915_reg_defs.h"
 
-#define ILK_GDSR _MMIO(MCHBAR_MIRROR_BASE + 0x2ca4)
-#define  ILK_GRDOM_FULL(0 << 1)
-#define  ILK_GRDOM_RENDER  (1 << 1)
-#define  

[Intel-gfx] [PATCH v2 1/2] drm/i915: Define MCH registers relative to MCHBAR_MIRROR_BASE

2022-02-14 Thread Matt Roper
A few of our MCH registers are defined with absolute register offsets.
For consistency, let's switch their definitions to be relative offsets
from MCHBAR_MIRROR_BASE.

Cc: Ville Syrjälä 
Suggested-by: Ville Syrjälä 
Signed-off-by: Matt Roper 
---
 drivers/gpu/drm/i915/i915_reg.h | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 4ea1713e6b60..72cb6e13b4e2 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1922,16 +1922,16 @@
 #define HPLLVCO _MMIO(MCHBAR_MIRROR_BASE + 0xc38)
 #define HPLLVCO_MOBILE  _MMIO(MCHBAR_MIRROR_BASE + 0xc0f)
 
-#define TSC1   _MMIO(0x11001)
+#define TSC1   _MMIO(MCHBAR_MIRROR_BASE + 0x1001)
 #define   TSE  (1 << 0)
-#define TR1_MMIO(0x11006)
-#define TSFS   _MMIO(0x11020)
+#define TR1_MMIO(MCHBAR_MIRROR_BASE + 0x1006)
+#define TSFS   _MMIO(MCHBAR_MIRROR_BASE + 0x1020)
 #define   TSFS_SLOPE_MASK  0xff00
 #define   TSFS_SLOPE_SHIFT 8
 #define   TSFS_INTR_MASK   0x00ff
 
-#define CSIPLL0_MMIO(0x12c10)
-#define DDRMPLL1   _MMIO(0X12c20)
+#define CSIPLL0_MMIO(MCHBAR_MIRROR_BASE + 0x2c10)
+#define DDRMPLL1   _MMIO(MCHBAR_MIRROR_BASE + 0x2c20)
 #define PEG_BAND_GAP_DATA  _MMIO(0x14d68)
 
 #define GEN6_GT_PERF_STATUS_MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5948)
@@ -4320,7 +4320,7 @@
 ((fbc) << WM1_LP_FBC_SHIFT) | ((pri) << WM1_LP_SR_SHIFT) | (cur))
 
 /* Memory latency timer register */
-#define MLTR_ILK   _MMIO(0x11222)
+#define MLTR_ILK   _MMIO(MCHBAR_MIRROR_BASE + 0x1222)
 #define  MLTR_WM1_SHIFT0
 #define  MLTR_WM2_SHIFT8
 /* the unit of memory self-refresh latency time is 0.5us */
-- 
2.34.1



Re: [Intel-gfx] [RFC PATCH v2 0/1] Splitting up platform-specific calls

2022-02-14 Thread Casey Bowman



On 2/11/22 05:51, Tvrtko Ursulin wrote:


On 11/02/2022 11:55, Jani Nikula wrote:

On Thu, 10 Feb 2022, Casey Bowman  wrote:

In this RFC I would like to ask the community their thoughts
on how we can best handle splitting architecture-specific
calls.

I would like to address the following:

1. How do we want to split architecture calls? Different object files
per platform? Separate function calls within the same object file?

2. How do we address dummy functions? If we have a function call 
that is

used for one or more platforms, but is not used in another, what should
we do for this case?

I've given an example of splitting an architecture call
in my patch with run_as_guest() being split into different
implementations for x86 and arm64 in separate object files, sharing
a single header.

Another suggestion from Michael (michael.ch...@intel.com) involved
using a single object file, a single header, and splitting various
functions calls via ifdefs in the header file.

I would appreciate any input on how we can avoid scaling issues when
including multiple architectures and multiple functions (as the number
of function calls will inevitably increase with more architectures).

v2: Revised to use kernel's platform-splitting scheme.


I think this is overengineering.

Just add different implementations of the functions per architecture
next to where they are now, like I suggested before.

If we need to split them better later, it'll be a trivial undertaking,
and we'll be in a better position to do it because we'll know how many
functions there'll be and where they are and what they do.

Adding a bunch of overhead from the start seems like the wrong thing to
do.


I don't see it adds real complexity, which would normally be 
associated with over-engineering. As a benefit I see it helping with 
driving the clean re-design (during the porting effort) in a way that 
it will be easy to spot is something is overly hacky, split on the 
wrong level, or incorrectly placed.


And it moves run_as_guest outside of intel_vtd.[hc] which IMO shows 
immediate benefit, since it has nothing to do with intel_vtd.


I suggested to add clflush as well, since I think going for 
drm_flush_virt_range everywhere is a bit lazy given how it is a clear 
regression for older platforms.


But after that I indeed don't have a crystal ball to show me how many 
more appropriate low-level primitives would be to use the pattern.


So my vote would be to go with it, although the main thing is probably 
to solve the conflicting asks and let guys focus on the port. Put it 
to voting then? :)


If we can get someone else to weigh in here to break the tie, that'd be 
helpful :)


Regards,
Casey



Re: [Intel-gfx] [PATCH] drm/i915: Move MCHBAR registers to their own header

2022-02-14 Thread Matt Roper
On Fri, Feb 11, 2022 at 10:41:53AM +0200, Ville Syrjälä wrote:
> On Thu, Feb 10, 2022 at 03:12:17PM -0800, Matt Roper wrote:
> > Registers that exist within the MCH BAR and are mirrored into the GPU's
> > MMIO space are a good candidate to separate out into their own header.
> > 
> > For reference, the mirror of the MCH BAR lives at the following
> > locations in the graphics MMIO space:
> > 
> >  * Pre-gen6:   0x1 -  0x13000
> 
> Should go up to 0x14000 according to some docs I have.

I think I was looking at a gm45 PRM for this.  Given the spotty
documentation on the older platforms and the number of different end
points there seem to be, maybe it's a better idea to just give the
starting offset in the commit message and say that the upper bound
varies.

> 
> >  * Gen6-Gen11 + RKL:  0x14 - 0x14
> 
> Some docs say this goes up to 0x18, other docs have different
> numbers. I suppose it doesn't matter all that much really. And
> BXT+ clearly can't go past 0x16 since IIRC that's where some
> of the PHY/PLL stuff lives.
> 
> >  * TGL, ADL:  0x14 - 0x15
> > 
> > Bspec: 134, 51771
> > Cc: Ville Syrjälä 
> > Suggested-by: Ville Syrjälä 
> > Signed-off-by: Matt Roper 
> 
> > -#define GEN6_GT_PERF_STATUS_MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5948)
> > -#define BXT_GT_PERF_STATUS  _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x7070)
> > -#define GEN6_RP_STATE_LIMITS   _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5994)
> > -#define GEN6_RP_STATE_CAP  _MMIO(MCHBAR_MIRROR_BASE_SNB + 0x5998)
> > -#define   RP0_CAP_MASK REG_GENMASK(7, 0)
> > -#define   RP1_CAP_MASK REG_GENMASK(15, 8)
> > -#define   RPN_CAP_MASK REG_GENMASK(23, 16)
> >  #define BXT_RP_STATE_CAP_MMIO(0x138170)
> >  #define GEN9_RP_STATE_LIMITS   _MMIO(0x138148)
> >  #define XEHPSDV_RP_STATE_CAP   _MMIO(0x250014)
> 
> :( This is a bit unfortunate. I wonder if we should make an exception
> for these and keep them all together somewhere?

I don't really see a problem with having them in separate headers.  We
have other stuff like ILK_GDSR / GEN6_GDRST that also used to be in the
MCHBAR and then moved to the GT proper.  I believe the MCHBAR mirror is
going away completely a platform or two down the road and all the
important registers are migrating to non-MCHBAR offsets, so if we try to
keep them all together, that defeats most of the purpose of having a
separate MCHBAR header?

> 
> 
> > -/* Memory latency timer register */
> > -#define MLTR_ILK   _MMIO(0x11222)
> > +#define MLTR_ILK   _MMIO(MCHBAR_MIRROR_BASE + 
> > 0x1222)
> 
> I'd prefer to see a separate patch for the s/number/MCHBAR_MIRROR_BASE/ 
> stuff. Very hard to review those in this form.

Good point; I'll fix that.


Matt

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

-- 
Matt Roper
Graphics Software Engineer
VTT-OSGC Platform Enablement
Intel Corporation
(916) 356-2795


[Intel-gfx] [PATCH 3/3] drm/i915: Fix for PHY_MISC_TC1 offset

2022-02-14 Thread Ramalingam C
From: Jouni Högander 

Currently ICL_PHY_MISC macro is returning offset 0x64C10 for PHY_E
port. Correct offset is 0x64C14.

Fix this by handling PHY_E port seprately.

Signed-off-by: Matt Roper 
Signed-off-by: Jouni Högander 
Signed-off-by: Ramalingam C 
---
 drivers/gpu/drm/i915/display/intel_snps_phy.c | 2 +-
 drivers/gpu/drm/i915/i915_reg.h   | 6 --
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.c 
b/drivers/gpu/drm/i915/display/intel_snps_phy.c
index c60575cb5368..f08061c748b3 100644
--- a/drivers/gpu/drm/i915/display/intel_snps_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_snps_phy.c
@@ -32,7 +32,7 @@ void intel_snps_phy_wait_for_calibration(struct 
drm_i915_private *i915)
if (!intel_phy_is_snps(i915, phy))
continue;
 
-   if (intel_de_wait_for_clear(i915, ICL_PHY_MISC(phy),
+   if (intel_de_wait_for_clear(i915, DG2_PHY_MISC(phy),
DG2_PHY_DP_TX_ACK_MASK, 25))
drm_err(>drm, "SNPS PHY %c failed to calibrate 
after 25ms.\n",
phy);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 4d12abb2d7ff..354c25f483cb 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -9559,8 +9559,10 @@ enum skl_power_gate {
 
 #define _ICL_PHY_MISC_A0x64C00
 #define _ICL_PHY_MISC_B0x64C04
-#define ICL_PHY_MISC(port) _MMIO_PORT(port, _ICL_PHY_MISC_A, \
-_ICL_PHY_MISC_B)
+#define _DG2_PHY_MISC_TC1  0x64C14 /* TC1="PHY E" but offset as if "PHY F" 
*/
+#define ICL_PHY_MISC(port) _MMIO_PORT(port, _ICL_PHY_MISC_A, 
_ICL_PHY_MISC_B)
+#define DG2_PHY_MISC(port) ((port) == PHY_E ? _MMIO(_DG2_PHY_MISC_TC1) : \
+ICL_PHY_MISC(port))
 #define  ICL_PHY_MISC_MUX_DDID (1 << 28)
 #define  ICL_PHY_MISC_DE_IO_COMP_PWR_DOWN  (1 << 23)
 #define  DG2_PHY_DP_TX_ACK_MASKREG_GENMASK(23, 20)
-- 
2.20.1



[Intel-gfx] [PATCH 2/3] drm/i915/dg2: Drop 38.4 MHz MPLLB tables

2022-02-14 Thread Ramalingam C
From: Matt Roper 

Our early understanding of DG2 was incorrect; since the 5th display
isn't actually a Type-C output, 38.4 MHz input clocks are never used on
this platform and we can drop the corresponding MPLLB tables.

Cc: Anusha Srivatsa 
Cc: José Roberto de Souza 
Signed-off-by: Matt Roper 
Signed-off-by: Ramalingam C 
---
 drivers/gpu/drm/i915/display/intel_snps_phy.c | 208 +-
 1 file changed, 1 insertion(+), 207 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_snps_phy.c 
b/drivers/gpu/drm/i915/display/intel_snps_phy.c
index 8573a458811a..c60575cb5368 100644
--- a/drivers/gpu/drm/i915/display/intel_snps_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_snps_phy.c
@@ -250,197 +250,6 @@ static const struct intel_mpllb_state * const 
dg2_dp_100_tables[] = {
NULL,
 };
 
-/*
- * Basic DP link rates with 38.4 MHz reference clock.
- */
-
-static const struct intel_mpllb_state dg2_dp_rbr_38_4 = {
-   .clock = 162000,
-   .ref_control =
-   REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 1),
-   .mpllb_cp =
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 5) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 25) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
-   .mpllb_div =
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 2) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 2),
-   .mpllb_div2 =
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 304),
-   .mpllb_fracn1 =
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 1),
-   .mpllb_fracn2 =
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 49152),
-};
-
-static const struct intel_mpllb_state dg2_dp_hbr1_38_4 = {
-   .clock = 27,
-   .ref_control =
-   REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 1),
-   .mpllb_cp =
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 5) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 25) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
-   .mpllb_div =
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_TX_CLK_DIV, 1) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
-   .mpllb_div2 =
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 248),
-   .mpllb_fracn1 =
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 1),
-   .mpllb_fracn2 =
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 40960),
-};
-
-static const struct intel_mpllb_state dg2_dp_hbr2_38_4 = {
-   .clock = 54,
-   .ref_control =
-   REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 1),
-   .mpllb_cp =
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 5) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 25) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
-   .mpllb_div =
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_DIV5_CLK_EN, 1) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_PMIX_EN, 1) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_V2I, 2) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_FREQ_VCO, 3),
-   .mpllb_div2 =
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_REF_CLK_DIV, 1) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_MULTIPLIER, 248),
-   .mpllb_fracn1 =
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_CGG_UPDATE_EN, 1) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_EN, 1) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_DEN, 1),
-   .mpllb_fracn2 =
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_FRACN_QUOT, 40960),
-};
-
-static const struct intel_mpllb_state dg2_dp_hbr3_38_4 = {
-   .clock = 81,
-   .ref_control =
-   REG_FIELD_PREP(SNPS_PHY_REF_CONTROL_REF_RANGE, 1),
-   .mpllb_cp =
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT, 6) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP, 26) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_INT_GS, 65) |
-   REG_FIELD_PREP(SNPS_PHY_MPLLB_CP_PROP_GS, 127),
-   .mpllb_div =
-   

[Intel-gfx] [PATCH 1/3] drm/i915/dg2: Enable 5th display

2022-02-14 Thread Ramalingam C
From: Matt Roper 

DG2 supports a 5th display output which the hardware refers to as "TC1,"
even though it isn't a Type-C output.  This behaves similarly to the TC1
on past platforms with just a couple minor differences:

 * DG2's TC1 bit in SDEISR is at bit 25 rather than 24 as it is on
   ICP/TGP/ADP.
 * DG2 doesn't need the hpd inversion setting that we had to use on DG1

Cc: Swathi Dhanavanthri 
Cc: Lucas De Marchi 
Cc: José Roberto de Souza 
Signed-off-by: Matt Roper 
Signed-off-by: Ramalingam C 
---
 drivers/gpu/drm/i915/display/intel_gmbus.c | 16 ++--
 drivers/gpu/drm/i915/i915_irq.c|  5 -
 drivers/gpu/drm/i915/i915_reg.h|  1 +
 3 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_gmbus.c 
b/drivers/gpu/drm/i915/display/intel_gmbus.c
index 6ce8c10fe975..2fad03250661 100644
--- a/drivers/gpu/drm/i915/display/intel_gmbus.c
+++ b/drivers/gpu/drm/i915/display/intel_gmbus.c
@@ -98,11 +98,21 @@ static const struct gmbus_pin gmbus_pins_dg1[] = {
[GMBUS_PIN_4_CNP] = { "dpd", GPIOE },
 };
 
+static const struct gmbus_pin gmbus_pins_dg2[] = {
+   [GMBUS_PIN_1_BXT] = { "dpa", GPIOB },
+   [GMBUS_PIN_2_BXT] = { "dpb", GPIOC },
+   [GMBUS_PIN_3_BXT] = { "dpc", GPIOD },
+   [GMBUS_PIN_4_CNP] = { "dpd", GPIOE },
+   [GMBUS_PIN_9_TC1_ICP] = { "tc1", GPIOJ },
+};
+
 /* pin is expected to be valid */
 static const struct gmbus_pin *get_gmbus_pin(struct drm_i915_private *dev_priv,
 unsigned int pin)
 {
-   if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1)
+   if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG2)
+   return _pins_dg2[pin];
+   else if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1)
return _pins_dg1[pin];
else if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
return _pins_icp[pin];
@@ -123,7 +133,9 @@ bool intel_gmbus_is_valid_pin(struct drm_i915_private 
*dev_priv,
 {
unsigned int size;
 
-   if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1)
+   if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG2)
+   size = ARRAY_SIZE(gmbus_pins_dg2);
+   else if (INTEL_PCH_TYPE(dev_priv) >= PCH_DG1)
size = ARRAY_SIZE(gmbus_pins_dg1);
else if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
size = ARRAY_SIZE(gmbus_pins_icp);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index fdd568ba4a16..4d81063b128c 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -179,6 +179,7 @@ static const u32 hpd_sde_dg1[HPD_NUM_PINS] = {
[HPD_PORT_B] = SDE_DDI_HOTPLUG_ICP(HPD_PORT_B),
[HPD_PORT_C] = SDE_DDI_HOTPLUG_ICP(HPD_PORT_C),
[HPD_PORT_D] = SDE_DDI_HOTPLUG_ICP(HPD_PORT_D),
+   [HPD_PORT_TC1] = SDE_TC_HOTPLUG_DG2(HPD_PORT_TC1),
 };
 
 static void intel_hpd_init_pins(struct drm_i915_private *dev_priv)
@@ -4424,7 +4425,9 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
if (I915_HAS_HOTPLUG(dev_priv))
dev_priv->hotplug_funcs = _hpd_funcs;
} else {
-   if (HAS_PCH_DG1(dev_priv))
+   if (HAS_PCH_DG2(dev_priv))
+   dev_priv->hotplug_funcs = _hpd_funcs;
+   else if (HAS_PCH_DG1(dev_priv))
dev_priv->hotplug_funcs = _hpd_funcs;
else if (DISPLAY_VER(dev_priv) >= 11)
dev_priv->hotplug_funcs = _hpd_funcs;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 4ea1713e6b60..4d12abb2d7ff 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6182,6 +6182,7 @@
 /* south display engine interrupt: ICP/TGP */
 #define SDE_GMBUS_ICP  (1 << 23)
 #define SDE_TC_HOTPLUG_ICP(hpd_pin)REG_BIT(24 + _HPD_PIN_TC(hpd_pin))
+#define SDE_TC_HOTPLUG_DG2(hpd_pin)REG_BIT(25 + _HPD_PIN_TC(hpd_pin)) /* 
sigh */
 #define SDE_DDI_HOTPLUG_ICP(hpd_pin)   REG_BIT(16 + _HPD_PIN_DDI(hpd_pin))
 #define SDE_DDI_HOTPLUG_MASK_ICP   (SDE_DDI_HOTPLUG_ICP(HPD_PORT_D) | \
 SDE_DDI_HOTPLUG_ICP(HPD_PORT_C) | \
-- 
2.20.1



[Intel-gfx] [PATCH 0/3] drm/i915/dg2: 5th Display output

2022-02-14 Thread Ramalingam C
Fixing the 5th Display output for DG2.

Jouni Högander (1):
  drm/i915: Fix for PHY_MISC_TC1 offset

Matt Roper (2):
  drm/i915/dg2: Enable 5th display
  drm/i915/dg2: Drop 38.4 MHz MPLLB tables

 drivers/gpu/drm/i915/display/intel_gmbus.c|  16 +-
 drivers/gpu/drm/i915/display/intel_snps_phy.c | 210 +-
 drivers/gpu/drm/i915/i915_irq.c   |   5 +-
 drivers/gpu/drm/i915/i915_reg.h   |   7 +-
 4 files changed, 25 insertions(+), 213 deletions(-)

-- 
2.20.1



[Intel-gfx] [PATCH] drm/i915/perf: Skip the i915_perf_init for dg2

2022-02-14 Thread Ramalingam C
i915_perf is not enabled for dg2 yet, hence skip the feature
initialization.

Signed-off-by: Ramalingam C 
cc: Umesh Nerlige Ramappa 
---
 drivers/gpu/drm/i915/i915_perf.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
index 36f1325baa7d..5ac9604d07b3 100644
--- a/drivers/gpu/drm/i915/i915_perf.c
+++ b/drivers/gpu/drm/i915/i915_perf.c
@@ -4373,6 +4373,10 @@ void i915_perf_init(struct drm_i915_private *i915)
 
/* XXX const struct i915_perf_ops! */
 
+   /* i915_perf is not enabled for DG2 yet */
+   if (IS_DG2(i915))
+   return;
+
perf->oa_formats = oa_formats;
if (IS_HASWELL(i915)) {
perf->ops.is_valid_b_counter_reg = gen7_is_valid_b_counter_addr;
-- 
2.20.1



Re: [Intel-gfx] ✗ Fi.CI.IGT: failure for drm/i915/dg1: Update DMC_DEBUG3 register

2022-02-14 Thread Matt Roper
On Thu, Feb 10, 2022 at 07:10:32AM +, Patchwork wrote:
> == Series Details ==
> 
> Series: drm/i915/dg1: Update DMC_DEBUG3 register
> URL   : https://patchwork.freedesktop.org/series/99942/
> State : failure
> 
> == Summary ==
> 
> CI Bug Log - changes from CI_DRM_11207_full -> Patchwork_22233_full
> 
> 
> Summary
> ---
> 
>   **FAILURE**
> 
>   Serious unknown changes coming with Patchwork_22233_full absolutely need to 
> be
>   verified manually.
>   
>   If you think the reported changes have nothing to do with the changes
>   introduced in Patchwork_22233_full, please notify your bug team to allow 
> them
>   to document this new failure mode, which will reduce false positives in CI.
> 
>   
> 
> Participating hosts (11 -> 12)
> --
> 
>   Additional (1): shard-rkl 
> 
> Possible new issues
> ---
> 
>   Here are the unknown changes that may have been introduced in 
> Patchwork_22233_full:
> 
> ### IGT changes ###
> 
>  Possible regressions 
> 
>   * igt@i915_pm_rpm@system-suspend-execbuf:
> - shard-iclb: [PASS][1] -> [INCOMPLETE][2]
>[1]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11207/shard-iclb2/igt@i915_pm_...@system-suspend-execbuf.html
>[2]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22233/shard-iclb7/igt@i915_pm_...@system-suspend-execbuf.html

Seems like a crash in the filesystem code, unrelated to the graphics
driver.  Might be related to
https://gitlab.freedesktop.org/drm/intel/-/issues/5096 which is also a
crash in the filesystem code (although with a different signature).

> 
>   * igt@kms_cursor_legacy@cursor-vs-flip-toggle:
> - shard-iclb: [PASS][3] -> [FAIL][4]
>[3]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11207/shard-iclb6/igt@kms_cursor_leg...@cursor-vs-flip-toggle.html
>[4]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22233/shard-iclb7/igt@kms_cursor_leg...@cursor-vs-flip-toggle.html

Appears to be https://gitlab.freedesktop.org/drm/intel/-/issues/2370


> 
>   * igt@kms_flip@flip-vs-fences-interruptible@a-vga1:
> - shard-snb:  [PASS][5] -> [INCOMPLETE][6]
>[5]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11207/shard-snb5/igt@kms_flip@flip-vs-fences-interrupti...@a-vga1.html
>[6]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22233/shard-snb4/igt@kms_flip@flip-vs-fences-interrupti...@a-vga1.html

Appears to be https://gitlab.freedesktop.org/drm/intel/-/issues/5000


None of these failures are caused by this series.  Merging v2 (which is
just a commit message tweak) to drm-intel-next.  CI for v2 failed
because a KBL system failed to boot, but that's not caused by this
series.  Thanks for the patch.


Matt

> 
>   
>  Suppressed 
> 
>   The following results come from untrusted machines, tests, or statuses.
>   They do not affect the overall result.
> 
>   * igt@syncobj_timeline@invalid-transfer-non-existent-point:
> - {shard-rkl}:NOTRUN -> [DMESG-WARN][7]
>[7]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22233/shard-rkl-2/igt@syncobj_timel...@invalid-transfer-non-existent-point.html
> 
>   
> Known issues
> 
> 
>   Here are the changes found in Patchwork_22233_full that come from known 
> issues:
> 
> ### IGT changes ###
> 
>  Issues hit 
> 
>   * igt@feature_discovery@psr2:
> - shard-iclb: NOTRUN -> [SKIP][8] ([i915#658])
>[8]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22233/shard-iclb8/igt@feature_discov...@psr2.html
> 
>   * igt@gem_exec_balancer@parallel-contexts:
> - shard-iclb: NOTRUN -> [SKIP][9] ([i915#4525]) +1 similar issue
>[9]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22233/shard-iclb8/igt@gem_exec_balan...@parallel-contexts.html
> 
>   * igt@gem_exec_capture@pi@rcs0:
> - shard-skl:  [PASS][10] -> [INCOMPLETE][11] ([i915#4547])
>[10]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11207/shard-skl2/igt@gem_exec_capture@p...@rcs0.html
>[11]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22233/shard-skl2/igt@gem_exec_capture@p...@rcs0.html
> 
>   * igt@gem_exec_fair@basic-flow@rcs0:
> - shard-tglb: [PASS][12] -> [FAIL][13] ([i915#2842])
>[12]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11207/shard-tglb6/igt@gem_exec_fair@basic-f...@rcs0.html
>[13]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22233/shard-tglb8/igt@gem_exec_fair@basic-f...@rcs0.html
> 
>   * igt@gem_exec_fair@basic-none-vip@rcs0:
> - shard-kbl:  [PASS][14] -> [FAIL][15] ([i915#2842]) +2 similar 
> issues
>[14]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_11207/shard-kbl4/igt@gem_exec_fair@basic-none-...@rcs0.html
>[15]: 
> https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_22233/shard-kbl6/igt@gem_exec_fair@basic-none-...@rcs0.html
> 
>   * igt@gem_exec_fair@basic-pace@vcs1:
> - 

Re: [Intel-gfx] [PATCH v8 1/3] gpu: drm: separate panel orientation property creating and value setting

2022-02-14 Thread Hsin-Yi Wang
On Tue, Feb 15, 2022 at 9:17 AM Gabriel Krisman Bertazi
 wrote:
>
> Hsin-Yi Wang  writes:
>
> > drm_dev_register() sets connector->registration_state to
> > DRM_CONNECTOR_REGISTERED and dev->registered to true. If
> > drm_connector_set_panel_orientation() is first called after
> > drm_dev_register(), it will fail several checks and results in following
> > warning.
>
> Hi,
>
> I stumbled upon this when investigating the same WARN_ON on amdgpu.
> Thanks for the patch :)
>
> > diff --git a/drivers/gpu/drm/drm_connector.c 
> > b/drivers/gpu/drm/drm_connector.c
> > index a50c82bc2b2fec..572ead7ac10690 100644
> > --- a/drivers/gpu/drm/drm_connector.c
> > +++ b/drivers/gpu/drm/drm_connector.c
> > @@ -1252,7 +1252,7 @@ static const struct drm_prop_enum_list 
> > dp_colorspaces[] = {
> >   *   INPUT_PROP_DIRECT) will still map 1:1 to the actual LCD panel
> >   *   coordinates, so if userspace rotates the picture to adjust for
> >   *   the orientation it must also apply the same transformation to the
> > - *   touchscreen input coordinates. This property is initialized by calling
> > + *   touchscreen input coordinates. This property value is set by calling
> >   *   drm_connector_set_panel_orientation() or
> >   *   drm_connector_set_panel_orientation_with_quirk()
> >   *
> > @@ -2341,8 +2341,8 @@ EXPORT_SYMBOL(drm_connector_set_vrr_capable_property);
> >   * @connector: connector for which to set the panel-orientation property.
> >   * @panel_orientation: drm_panel_orientation value to set
> >   *
> > - * This function sets the connector's panel_orientation and attaches
> > - * a "panel orientation" property to the connector.
> > + * This function sets the connector's panel_orientation value. If the 
> > property
> > + * doesn't exist, it will try to create one.
> >   *
> >   * Calling this function on a connector where the panel_orientation has
> >   * already been set is a no-op (e.g. the orientation has been overridden 
> > with
> > @@ -2373,19 +2373,12 @@ int drm_connector_set_panel_orientation(
> >   info->panel_orientation = panel_orientation;
> >
> >   prop = dev->mode_config.panel_orientation_property;
> > - if (!prop) {
> > - prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
> > - "panel orientation",
> > - drm_panel_orientation_enum_list,
> > - ARRAY_SIZE(drm_panel_orientation_enum_list));
> > - if (!prop)
> > - return -ENOMEM;
> > -
> > - dev->mode_config.panel_orientation_property = prop;
> > - }
> > + if (!prop &&
> > + drm_connector_init_panel_orientation_property(connector) < 0)
> > + return -ENOMEM;
> >
>
> In the case where the property has not been created beforehand, you
> forgot to reinitialize prop here, after calling
> drm_connector_init_panel_orientation_property().  This means
hi Gabriel,

drm_connector_init_panel_orientation_property() will create prop if
it's null. If prop fails to be created there, it will return -ENOMEM.

> drm_object_property_set_value() will be called with a NULL second argument
> and Oops the kernel.
>
>
> > - drm_object_attach_property(>base, prop,
> > -info->panel_orientation);
> > + drm_object_property_set_value(>base, prop,
> > +   info->panel_orientation);
>
>
> --
> Gabriel Krisman Bertazi


Re: [Intel-gfx] [PATCH v5 06/10] drm/i915/guc: Update GuC's log-buffer-state access for error capture.

2022-02-14 Thread Teres Alexis, Alan Previn
Looks like trying to move the vma up into guc-upper is impacting many other 
functions
in intel_guc_log and intel_guc_log_debugfs. I'll have to take it back (the 
level of
redesign i shall attempt with this series).

I'll just move the log_stats back into intel_guc_log and have intel_guc_capture
have its own stats structure - but keep the VMA allocation of this shared 
buffer in
intel_guc_log (like it was in the prior revs) and have intel_guc_capture "reach 
across"
into intel_guc_log to get the vma ptr (like it was in the prior revs).

...alan


On Mon, 2022-02-14 at 11:22 -0800, Alan Previn Teres Alexis wrote:
> Matt, just a final confirmation on below
> 
> > > > > > On Fri, 2022-02-04 at 10:19 -0800, Matthew Brost wrote:
> > > > > > > On Wed, Jan 26, 2022 at 02:48:18AM -0800, Alan Previn wrote:
> > > If the object lives at the GuC level, operate on it at the GuC level.
> > > 
> > > e.g.
> > > intel_guc_log_init_early calls mutex init on guc->log_state - that is
> > > wrong and breaks the layering. intel_guc_log_init_early should only
> > > operate on guc_log or below objects, not above it.
> > > 
> > > The key here is consisteny, if the GuC level owns the object it should
> > > be initialized there + passed into the lower levels if possible. The
> > > lower levels should avoid reaching back to GuC level for objects
> > > whenever possible.
> > > 
> > > You could have 2 intel_guc_log_stats objects below the guc_log object
> > > and 1 intel_guc_log_stats object for capture at the GuC level. That's
> > > likely the right approach here.
> > 
> > Thanks Matt - I'm in agreement... I was concerned about too much of
> > change - but you're right, I should be focusing on the design consistency.
> > Above sounds like the correct design (these stats and locks should belong
> > to their sole user).
> > 
> > ...alan
> > 
> 
> So this means:
> 1. guc[upper] allocates the shared-logging-buffer
>- but would ask the lower level components for the sizes before
>  buffering-up or capping-down to match interface spec.
> 2. guc-log and guc-error-capture requests guc for a vmap at their init.
> 3. guc-log and guc-error-capture owns independent log-stats and
>(and separate locks if needed).
> 4. when lower level components are done, they relinquish access to
>their region by requesting guc[upper] to unmap and free
> 
> A super clean separation like above could mean ripping apart enums
> and other #defines to split them across guc_log and guc_error_capture
> headers (such as region sizes).
> 
> I believe that separation complicates the understanding of the fw interface
> for logging as we break that picture into independant files / components.
> For now I want to keep guc[upper] aware of the individual sub-region
> allocation requirements (no ripping apart of enums but moving them around)
> but only keep the requesting of vmap and independant log-region-stats
> within the lower level?
> 
> Are you okay with this?
> 
> side note: error-capture no longer need locks after the recent G2H triggered
> linked-list extraction redesign.
> 
> 



[Intel-gfx] [PATCH] drm/i915/guc: Initialize GuC submission locks and queues early

2022-02-14 Thread Daniele Ceraolo Spurio
Move initialization of submission-related spinlock, lists and workers to
init_early. This fixes an issue where if the GuC init fails we might
still try to get the lock in the context cleanup code. Note that it is
safe to call the GuC context cleanup code even if the init failed
because all contexts are initialized with an invalid GuC ID, which will
cause the GuC side of the cleanup to be skipped, so it is easier to just
make sure the variables are initialized than to special case the cleanup
to handle the case when they're not.

References: https://gitlab.freedesktop.org/drm/intel/-/issues/4932
Signed-off-by: Daniele Ceraolo Spurio 
Cc: Matthew Brost 
Cc: John Harrison 
---
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 27 ++-
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index b3a429a92c0da..2160da2c83cbf 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1818,24 +1818,11 @@ int intel_guc_submission_init(struct intel_guc *guc)
 */
GEM_BUG_ON(!guc->lrc_desc_pool);
 
-   xa_init_flags(>context_lookup, XA_FLAGS_LOCK_IRQ);
-
-   spin_lock_init(>submission_state.lock);
-   INIT_LIST_HEAD(>submission_state.guc_id_list);
-   ida_init(>submission_state.guc_ids);
-   INIT_LIST_HEAD(>submission_state.destroyed_contexts);
-   INIT_WORK(>submission_state.destroyed_worker,
- destroyed_worker_func);
-   INIT_WORK(>submission_state.reset_fail_worker,
- reset_fail_worker_func);
-
guc->submission_state.guc_ids_bitmap =
bitmap_zalloc(NUMBER_MULTI_LRC_GUC_ID(guc), GFP_KERNEL);
if (!guc->submission_state.guc_ids_bitmap)
return -ENOMEM;
 
-   spin_lock_init(>timestamp.lock);
-   INIT_DELAYED_WORK(>timestamp.work, guc_timestamp_ping);
guc->timestamp.ping_delay = (POLL_TIME_CLKS / gt->clock_frequency + 1) 
* HZ;
guc->timestamp.shift = gpm_timestamp_shift(gt);
 
@@ -3831,6 +3818,20 @@ static bool __guc_submission_selected(struct intel_guc 
*guc)
 
 void intel_guc_submission_init_early(struct intel_guc *guc)
 {
+   xa_init_flags(>context_lookup, XA_FLAGS_LOCK_IRQ);
+
+   spin_lock_init(>submission_state.lock);
+   INIT_LIST_HEAD(>submission_state.guc_id_list);
+   ida_init(>submission_state.guc_ids);
+   INIT_LIST_HEAD(>submission_state.destroyed_contexts);
+   INIT_WORK(>submission_state.destroyed_worker,
+ destroyed_worker_func);
+   INIT_WORK(>submission_state.reset_fail_worker,
+ reset_fail_worker_func);
+
+   spin_lock_init(>timestamp.lock);
+   INIT_DELAYED_WORK(>timestamp.work, guc_timestamp_ping);
+
guc->submission_state.num_guc_ids = GUC_MAX_LRC_DESCRIPTORS;
guc->submission_supported = __guc_submission_supported(guc);
guc->submission_selected = __guc_submission_selected(guc);
-- 
2.25.1



[Intel-gfx] linux-next: build failure after merge of the drm-intel tree

2022-02-14 Thread Stephen Rothwell
Hi all,

After merging the drm-intel tree, today's linux-next build (x86_64
allmodconfig) failed like this:

drivers/gpu/drm/i915/gvt/kvmgt.c: In function 'handle_edid_regs':
drivers/gpu/drm/i915/gvt/kvmgt.c:595:38: error: implicit declaration of 
function 'drm_edid_block_valid' [-Werror=implicit-function-declaration]
  595 | if (!drm_edid_block_valid(
  |  ^~~~

Presumably caused by commit

  14da21cc4671 ("drm/i915: axe lots of unnecessary includes from i915_drv.h")

I am beginning to wonder if you guys run stuff through your CI before
relasing to linux-next.  Especially important when removing #include
statements from include files :-)

I have used the drm-intel tree from next-20220214 for today.

-- 
Cheers,
Stephen Rothwell


pgpEN1JYDctRF.pgp
Description: OpenPGP digital signature


[Intel-gfx] [PATCH 2/2] drm/i915/gem: Don't try to map and fence large scanout buffers (v7)

2022-02-14 Thread Vivek Kasireddy
On platforms capable of allowing 8K (7680 x 4320) modes, pinning 2 or
more framebuffers/scanout buffers results in only one that is mappable/
fenceable. Therefore, pageflipping between these 2 FBs where only one
is mappable/fenceable creates latencies large enough to miss alternate
vblanks thereby producing less optimal framerate.

This mainly happens because when i915_gem_object_pin_to_display_plane()
is called to pin one of the FB objs, the associated vma is identified
as misplaced and therefore i915_vma_unbind() is called which unbinds and
evicts it. This misplaced vma gets subseqently pinned only when
i915_gem_object_ggtt_pin_ww() is called without PIN_MAPPABLE. This
results in a latency of ~10ms and happens every other vblank/repaint cycle.
Therefore, to fix this issue, we try to see if there is space to map
at-least two objects of a given size and return early if there isn't. This
would ensure that we do not try with PIN_MAPPABLE for any objects that
are too big to map thereby preventing unncessary unbind.

Testcase:
Running Weston and weston-simple-egl on an Alderlake_S (ADLS) platform
with a 8K@60 mode results in only ~40 FPS. Since upstream Weston submits
a frame ~7ms before the next vblank, the latencies seen between atomic
commit and flip event are 7, 24 (7 + 16.66), 7, 24. suggesting that
it misses the vblank every other frame.

Here is the ftrace snippet that shows the source of the ~10ms latency:
  i915_gem_object_pin_to_display_plane() {
0.102 us   |i915_gem_object_set_cache_level();
i915_gem_object_ggtt_pin_ww() {
0.390 us   |  i915_vma_instance();
0.178 us   |  i915_vma_misplaced();
  i915_vma_unbind() {
  __i915_active_wait() {
0.082 us   |i915_active_acquire_if_busy();
0.475 us   |  }
  intel_runtime_pm_get() {
0.087 us   |intel_runtime_pm_acquire();
0.259 us   |  }
  __i915_active_wait() {
0.085 us   |i915_active_acquire_if_busy();
0.240 us   |  }
  __i915_vma_evict() {
ggtt_unbind_vma() {
  gen8_ggtt_clear_range() {
10507.255 us |}
10507.689 us |  }
10508.516 us |   }

v2: Instead of using bigjoiner checks, determine whether a scanout
buffer is too big by checking to see if it is possible to map
two of them into the ggtt.

v3 (Ville):
- Count how many fb objects can be fit into the available holes
  instead of checking for a hole twice the object size.
- Take alignment constraints into account.
- Limit this large scanout buffer check to >= Gen 11 platforms.

v4:
- Remove existing heuristic that checks just for size. (Ville)
- Return early if we find space to map at-least two objects. (Tvrtko)
- Slightly update the commit message.

v5: (Tvrtko)
- Rename the function to indicate that the object may be too big to
  map into the aperture.
- Account for guard pages while calculating the total size required
  for the object.
- Do not subject all objects to the heuristic check and instead
  consider objects only of a certain size.
- Do the hole walk using the rbtree.
- Preserve the existing PIN_NONBLOCK logic.
- Drop the PIN_MAPPABLE check while pinning the VMA.

v6: (Tvrtko)
- Return 0 on success and the specific error code on failure to
  preserve the existing behavior.

v7: (Ville)
- Drop the HAS_GMCH(i915), DISPLAY_VER(i915) < 11 and
  size < ggtt->mappable_end / 4 checks.
- Drop the redundant check that is based on previous heuristic.

Cc: Ville Syrjälä 
Cc: Maarten Lankhorst 
Cc: Tvrtko Ursulin 
Cc: Manasi Navare 
Reviewed-by: Tvrtko Ursulin 
Signed-off-by: Vivek Kasireddy 
---
 drivers/gpu/drm/i915/i915_gem.c | 120 +++-
 1 file changed, 86 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 2e10187cd0a0..260cd3961ca1 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -49,6 +49,7 @@
 #include "gem/i915_gem_pm.h"
 #include "gem/i915_gem_region.h"
 #include "gem/i915_gem_userptr.h"
+#include "gem/i915_gem_tiling.h"
 #include "gt/intel_engine_user.h"
 #include "gt/intel_gt.h"
 #include "gt/intel_gt_pm.h"
@@ -879,6 +880,88 @@ static void discard_ggtt_vma(struct i915_vma *vma)
spin_unlock(>vma.lock);
 }
 
+static int
+i915_gem_object_fits_in_aperture(struct drm_i915_gem_object *obj,
+u64 alignment, u64 flags)
+{
+   struct drm_i915_private *i915 = to_i915(obj->base.dev);
+   struct i915_ggtt *ggtt = to_gt(i915)->ggtt;
+   struct drm_mm_node *hole;
+   u64 hole_start, hole_end, start, end;
+   u64 fence_size, fence_alignment;
+   unsigned int count = 0;
+
+   /*
+* If the required space is larger than the available
+* aperture, we will not able to find a slot for the
+* object and unbinding the object now will be in
+* vain. Worse, doing so may cause 

[Intel-gfx] [PATCH 1/2] drm/mm: Add an iterator to optimally walk over holes for an allocation (v3)

2022-02-14 Thread Vivek Kasireddy
This iterator relies on drm_mm_first_hole() and drm_mm_next_hole()
functions to identify suitable holes for an allocation of a given
size by efficiently traversing the rbtree associated with the given
allocator.

It replaces the for loop in drm_mm_insert_node_in_range() and can
also be used by drm drivers to quickly identify holes of a certain
size within a given range.

v2: (Tvrtko)
- Prepend a double underscore for the newly exported first/next_hole
- s/each_best_hole/each_suitable_hole/g
- Mask out DRM_MM_INSERT_ONCE from the mode before calling
  first/next_hole and elsewhere.

v3: (Tvrtko)
- Reduce the number of hunks by retaining the "mode" variable name

Reviewed-by: Tvrtko Ursulin 
Suggested-by: Tvrtko Ursulin 
Signed-off-by: Vivek Kasireddy 
---
 drivers/gpu/drm/drm_mm.c | 32 +++-
 include/drm/drm_mm.h | 36 
 2 files changed, 51 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 8257f9d4f619..8efea548ae9f 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -352,10 +352,10 @@ static struct drm_mm_node *find_hole_addr(struct drm_mm 
*mm, u64 addr, u64 size)
return node;
 }
 
-static struct drm_mm_node *
-first_hole(struct drm_mm *mm,
-  u64 start, u64 end, u64 size,
-  enum drm_mm_insert_mode mode)
+struct drm_mm_node *
+__drm_mm_first_hole(struct drm_mm *mm,
+   u64 start, u64 end, u64 size,
+   enum drm_mm_insert_mode mode)
 {
switch (mode) {
default:
@@ -374,6 +374,7 @@ first_hole(struct drm_mm *mm,
hole_stack);
}
 }
+EXPORT_SYMBOL(__drm_mm_first_hole);
 
 /**
  * DECLARE_NEXT_HOLE_ADDR - macro to declare next hole functions
@@ -410,11 +411,11 @@ static struct drm_mm_node *name(struct drm_mm_node 
*entry, u64 size)  \
 DECLARE_NEXT_HOLE_ADDR(next_hole_high_addr, rb_left, rb_right)
 DECLARE_NEXT_HOLE_ADDR(next_hole_low_addr, rb_right, rb_left)
 
-static struct drm_mm_node *
-next_hole(struct drm_mm *mm,
- struct drm_mm_node *node,
- u64 size,
- enum drm_mm_insert_mode mode)
+struct drm_mm_node *
+__drm_mm_next_hole(struct drm_mm *mm,
+  struct drm_mm_node *node,
+  u64 size,
+  enum drm_mm_insert_mode mode)
 {
switch (mode) {
default:
@@ -432,6 +433,7 @@ next_hole(struct drm_mm *mm,
return >hole_stack == >hole_stack ? NULL : node;
}
 }
+EXPORT_SYMBOL(__drm_mm_next_hole);
 
 /**
  * drm_mm_reserve_node - insert an pre-initialized node
@@ -516,11 +518,11 @@ int drm_mm_insert_node_in_range(struct drm_mm * const mm,
u64 size, u64 alignment,
unsigned long color,
u64 range_start, u64 range_end,
-   enum drm_mm_insert_mode mode)
+   enum drm_mm_insert_mode caller_mode)
 {
struct drm_mm_node *hole;
u64 remainder_mask;
-   bool once;
+   enum drm_mm_insert_mode mode = caller_mode & ~DRM_MM_INSERT_ONCE;
 
DRM_MM_BUG_ON(range_start > range_end);
 
@@ -533,13 +535,9 @@ int drm_mm_insert_node_in_range(struct drm_mm * const mm,
if (alignment <= 1)
alignment = 0;
 
-   once = mode & DRM_MM_INSERT_ONCE;
-   mode &= ~DRM_MM_INSERT_ONCE;
-
remainder_mask = is_power_of_2(alignment) ? alignment - 1 : 0;
-   for (hole = first_hole(mm, range_start, range_end, size, mode);
-hole;
-hole = once ? NULL : next_hole(mm, hole, size, mode)) {
+   drm_mm_for_each_suitable_hole(hole, mm, range_start, range_end,
+ size, mode) {
u64 hole_start = __drm_mm_hole_node_start(hole);
u64 hole_end = hole_start + hole->hole_size;
u64 adj_start, adj_end;
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h
index ac33ba1b18bc..777f659f9692 100644
--- a/include/drm/drm_mm.h
+++ b/include/drm/drm_mm.h
@@ -400,6 +400,42 @@ static inline u64 drm_mm_hole_node_end(const struct 
drm_mm_node *hole_node)
 1 : 0; \
 pos = list_next_entry(pos, hole_stack))
 
+struct drm_mm_node *
+__drm_mm_first_hole(struct drm_mm *mm,
+   u64 start, u64 end, u64 size,
+   enum drm_mm_insert_mode mode);
+
+struct drm_mm_node *
+__drm_mm_next_hole(struct drm_mm *mm,
+  struct drm_mm_node *node,
+  u64 size,
+  enum drm_mm_insert_mode mode);
+
+/**
+ * drm_mm_for_each_suitable_hole - iterator to optimally walk over all
+ * holes that can fit an allocation of the given @size.
+ * @pos: _mm_node used internally to track progress
+ * @mm: _mm allocator to walk
+ * @range_start: start of the allowed range for the allocation
+ * @range_end: end of the allowed 

[Intel-gfx] [PATCH 0/2] drm/mm: Add an iterator to optimally walk over holes suitable for an allocation

2022-02-14 Thread Vivek Kasireddy
The first patch is a drm core patch that replaces the for loop in
drm_mm_insert_node_in_range() with the iterator and would not
cause any functional changes. The second patch is a i915 driver
specific patch that also uses the iterator but solves a different
problem.

Cc: Tvrtko Ursulin 
Cc: Nirmoy Das 
Cc: Christian König 

Vivek Kasireddy (2):
  drm/mm: Add an iterator to optimally walk over holes for an allocation
(v3)
  drm/i915/gem: Don't try to map and fence large scanout buffers (v7)

 drivers/gpu/drm/drm_mm.c|  32 -
 drivers/gpu/drm/i915/i915_gem.c | 120 +++-
 include/drm/drm_mm.h|  36 ++
 3 files changed, 137 insertions(+), 51 deletions(-)

-- 
2.34.1



Re: [Intel-gfx] [PATCH 1/2] drm/i915/fbdev: add intel_fbdev_to_framebuffer() helper

2022-02-14 Thread Ville Syrjälä
On Mon, Feb 14, 2022 at 05:02:06PM +0200, Jani Nikula wrote:
> Wrap accessing struct intel_fbdev guts in a helper.
> 
> Signed-off-by: Jani Nikula 
> ---
>  drivers/gpu/drm/i915/display/intel_display_debugfs.c | 6 +++---
>  drivers/gpu/drm/i915/display/intel_fbdev.c   | 8 
>  drivers/gpu/drm/i915/display/intel_fbdev.h   | 7 +++
>  3 files changed, 18 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c 
> b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> index f4de004d470f..b0bcf4d54a74 100644
> --- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> @@ -16,6 +16,7 @@
>  #include "intel_dp_mst.h"
>  #include "intel_drrs.h"
>  #include "intel_fbc.h"
> +#include "intel_fbdev.h"
>  #include "intel_hdcp.h"
>  #include "intel_hdmi.h"
>  #include "intel_pm.h"
> @@ -124,9 +125,8 @@ static int i915_gem_framebuffer_info(struct seq_file *m, 
> void *data)
>   struct drm_framebuffer *drm_fb;
>  
>  #ifdef CONFIG_DRM_FBDEV_EMULATION
> - if (dev_priv->fbdev && dev_priv->fbdev->helper.fb) {
> - fbdev_fb = to_intel_framebuffer(dev_priv->fbdev->helper.fb);
> -
> + fbdev_fb = intel_fbdev_to_framebuffer(dev_priv->fbdev);

The "_to_" implies to me that this is just some kind of cast,
which it is not. So I would drop the "_to_".

Otherwise the series seems fine
Reviewed-by: Ville Syrjälä 

> + if (fbdev_fb) {
>   seq_printf(m, "fbcon size: %d x %d, depth %d, %d bpp, modifier 
> 0x%llx, refcount %d, obj ",
>  fbdev_fb->base.width,
>  fbdev_fb->base.height,
> diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c 
> b/drivers/gpu/drm/i915/display/intel_fbdev.c
> index 41d279db2be6..3ef683916ba6 100644
> --- a/drivers/gpu/drm/i915/display/intel_fbdev.c
> +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
> @@ -680,3 +680,11 @@ void intel_fbdev_restore_mode(struct drm_device *dev)
>   if (drm_fb_helper_restore_fbdev_mode_unlocked(>helper) == 0)
>   intel_fbdev_invalidate(ifbdev);
>  }
> +
> +struct intel_framebuffer *intel_fbdev_to_framebuffer(struct intel_fbdev 
> *fbdev)
> +{
> + if (!fbdev || !fbdev->helper.fb)
> + return NULL;
> +
> + return to_intel_framebuffer(fbdev->helper.fb);
> +}
> diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.h 
> b/drivers/gpu/drm/i915/display/intel_fbdev.h
> index de7c84250eb5..8e86c08d544f 100644
> --- a/drivers/gpu/drm/i915/display/intel_fbdev.h
> +++ b/drivers/gpu/drm/i915/display/intel_fbdev.h
> @@ -10,6 +10,8 @@
>  
>  struct drm_device;
>  struct drm_i915_private;
> +struct intel_fbdev;
> +struct intel_framebuffer;
>  
>  #ifdef CONFIG_DRM_FBDEV_EMULATION
>  int intel_fbdev_init(struct drm_device *dev);
> @@ -19,6 +21,7 @@ void intel_fbdev_fini(struct drm_i915_private *dev_priv);
>  void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool 
> synchronous);
>  void intel_fbdev_output_poll_changed(struct drm_device *dev);
>  void intel_fbdev_restore_mode(struct drm_device *dev);
> +struct intel_framebuffer *intel_fbdev_to_framebuffer(struct intel_fbdev 
> *fbdev);
>  #else
>  static inline int intel_fbdev_init(struct drm_device *dev)
>  {
> @@ -48,6 +51,10 @@ static inline void intel_fbdev_output_poll_changed(struct 
> drm_device *dev)
>  static inline void intel_fbdev_restore_mode(struct drm_device *dev)
>  {
>  }
> +static inline struct intel_framebuffer *intel_fbdev_to_framebuffer(struct 
> intel_fbdev *fbdev)
> +{
> + return NULL;
> +}
>  #endif
>  
>  #endif /* __INTEL_FBDEV_H__ */
> -- 
> 2.30.2

-- 
Ville Syrjälä
Intel


Re: [Intel-gfx] [PATCH 2/6] drm/i915: Fix bw atomic check when switching between SAGV vs. no SAGV

2022-02-14 Thread Ville Syrjälä
On Mon, Feb 14, 2022 at 07:03:05PM +0200, Lisovskiy, Stanislav wrote:
> On Mon, Feb 14, 2022 at 12:24:57PM +0200, Ville Syrjälä wrote:
> > On Mon, Feb 14, 2022 at 12:05:36PM +0200, Lisovskiy, Stanislav wrote:
> > > On Mon, Feb 14, 2022 at 11:18:07AM +0200, Ville Syrjala wrote:
> > > > From: Ville Syrjälä 
> > > > 
> > > > If the only thing that is changing is SAGV vs. no SAGV but
> > > > the number of active planes and the total data rates end up
> > > > unchanged we currently bail out of intel_bw_atomic_check()
> > > > early and forget to actually compute the new WGV point
> > > > mask and thus won't actually enable/disable SAGV as requested.
> > > > This ends up poorly if we end up running with SAGV enabled
> > > > when we shouldn't. Usually ends up in underruns.
> > > > To fix this let's go through the QGV point mask computation
> > > > if anyone else already added the bw state for us.
> > > 
> > > Haven't been looking this in a while. Despite we have been
> > > looking like few revisions together still some bugs :(
> > > 
> > > I thought SAGV vs No SAGV can't change if active planes 
> > > or data rate didn't change? Because it means we probably
> > > still have same ddb allocations, which means SAGV state
> > > will just stay the same.
> > 
> > SAGV can change due to watermarks/ddb allocations. The easiest
> > way to trip this up is to try to use the async flip wm0/ddb 
> > optimization. That immediately forgets to turn off SAGV and
> > we get underruns, whcih is how I noticed this. And I don't
> > immediately see any easy proof that this couldn't also happen
> > due to some other plane changes.
> 
> Thats the way it was initially implemented even before SAGV was added.

Yeah, it wasn't a problem as long as SAGV was not enabled.

> I think it can be dated back to the very first bw check was implemented.
> 
> commit c457d9cf256e942138a54a2e80349ee7fe20c391
> Author: Ville Syrjälä 
> Date:   Fri May 24 18:36:14 2019 +0300
> 
> drm/i915: Make sure we have enough memory bandwidth on ICL
> 
> +int intel_bw_atomic_check(struct intel_atomic_state *state)
> +{
> +   struct drm_i915_private *dev_priv = to_i915(state->base.dev);
> +   struct intel_crtc_state *new_crtc_state, *old_crtc_state;
> +   struct intel_bw_state *bw_state = NULL;
> +   unsigned int data_rate, max_data_rate;
> +   unsigned int num_active_planes;
> +   struct intel_crtc *crtc;
> +   int i;
> +
> +   /* FIXME earlier gens need some checks too */
> +   if (INTEL_GEN(dev_priv) < 11)
> +   return 0;
> +
> +   for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
> +   new_crtc_state, i) {
> +   unsigned int old_data_rate =
> +   intel_bw_crtc_data_rate(old_crtc_state);
> +   unsigned int new_data_rate =
> +   intel_bw_crtc_data_rate(new_crtc_state);
> +   unsigned int old_active_planes =
> +   intel_bw_crtc_num_active_planes(old_crtc_state);
> +   unsigned int new_active_planes =
> +   intel_bw_crtc_num_active_planes(new_crtc_state);
> +
> +   /*
> +* Avoid locking the bw state when
> +* nothing significant has changed.
> +*/
> +   if (old_data_rate == new_data_rate &&
> +   old_active_planes == new_active_planes)
> +   continue;
> +
> +   bw_state  = intel_atomic_get_bw_state(state);
> +   if (IS_ERR(bw_state))
> +   return PTR_ERR(bw_state);
> 
> However, what can cause watermarks/ddb to change, besides plane state change
> and/or active planes change? We change watermarks, when we change ddb 
> allocations
> and we change ddb allocations when active planes had changed and/or data rate
> had changed.

The bw code only cares about the aggregate numbers from all the planes.
The planes could still change in some funny way where eg. some plane
frees up some bandwidth, but the other planes gobble up the exact same
amount and thus the aggregate numbers the bw atomic check cares about
do not change but the watermarks/ddb do.

And as mentiioned, the async flip wm0/ddb optimization makes this trivial
to trip up since it will want to disable SAGV as there is not enough ddb
for the SAGV watermark. And async flip specifically isn't even allowed
to change anything that would affect the bandwidth utilization, and neither
is it allowed to enable/disable planes.

-- 
Ville Syrjälä
Intel


Re: [Intel-gfx] [PATCH v5 06/10] drm/i915/guc: Update GuC's log-buffer-state access for error capture.

2022-02-14 Thread Teres Alexis, Alan Previn
Matt, just a final confirmation on below

> > > > > 
> > > > > On Fri, 2022-02-04 at 10:19 -0800, Matthew Brost wrote:
> > > > > > On Wed, Jan 26, 2022 at 02:48:18AM -0800, Alan Previn wrote:
> > > > > > > 
> > If the object lives at the GuC level, operate on it at the GuC level.
> > 
> > e.g.
> > intel_guc_log_init_early calls mutex init on guc->log_state - that is
> > wrong and breaks the layering. intel_guc_log_init_early should only
> > operate on guc_log or below objects, not above it.
> > 
> > The key here is consisteny, if the GuC level owns the object it should
> > be initialized there + passed into the lower levels if possible. The
> > lower levels should avoid reaching back to GuC level for objects
> > whenever possible.
> > 
> > You could have 2 intel_guc_log_stats objects below the guc_log object
> > and 1 intel_guc_log_stats object for capture at the GuC level. That's
> > likely the right approach here.
> 
> Thanks Matt - I'm in agreement... I was concerned about too much of
> change - but you're right, I should be focusing on the design consistency.
> Above sounds like the correct design (these stats and locks should belong
> to their sole user).
> 
> ...alan
> 

So this means:
1. guc[upper] allocates the shared-logging-buffer
   - but would ask the lower level components for the sizes before
 buffering-up or capping-down to match interface spec.
2. guc-log and guc-error-capture requests guc for a vmap at their init.
3. guc-log and guc-error-capture owns independent log-stats and
   (and separate locks if needed).
4. when lower level components are done, they relinquish access to
   their region by requesting guc[upper] to unmap and free

A super clean separation like above could mean ripping apart enums
and other #defines to split them across guc_log and guc_error_capture
headers (such as region sizes).

I believe that separation complicates the understanding of the fw interface
for logging as we break that picture into independant files / components.
For now I want to keep guc[upper] aware of the individual sub-region
allocation requirements (no ripping apart of enums but moving them around)
but only keep the requesting of vmap and independant log-region-stats
within the lower level?

Are you okay with this?

side note: error-capture no longer need locks after the recent G2H triggered
linked-list extraction redesign.




[Intel-gfx] [PATCH] drm/i915: Depend on !PREEMPT_RT.

2022-02-14 Thread Sebastian Andrzej Siewior
There are a few sections in the driver which are not compatible with
PREEMPT_RT. They trigger warnings and can lead to deadlocks at runtime.

Disable the i915 driver on a PREEMPT_RT enabled kernel. This way
PREEMPT_RT itself can be enabled without needing to address the i915
issues first. The RT related patches are still in RT queue and will be
handled later.

Signed-off-by: Sebastian Andrzej Siewior 
---
 drivers/gpu/drm/i915/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index a4c94dc2e2164..3aa719d5a0f0d 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -3,6 +3,7 @@ config DRM_I915
tristate "Intel 8xx/9xx/G3x/G4x/HD Graphics"
depends on DRM
depends on X86 && PCI
+   depends on !PREEMPT_RT
select INTEL_GTT
select INTERVAL_TREE
# we need shmfs for the swappable backing store, and in particular
-- 
2.34.1



Re: [Intel-gfx] [PATCH 4/8] drm/i915: Use preempt_disable/enable_rt() where recommended

2022-02-14 Thread Mario Kleiner
On Fri, Feb 11, 2022 at 9:44 AM Sebastian Andrzej Siewior
 wrote:
>
> On 2022-01-27 00:29:37 [+0100], Mario Kleiner wrote:
> > Hi, first thank you for implementing these preempt disables according to
> Hi Mario,
>
> > the markers i left long ago. And sorry for the rather late reply.
> >
> > I had a look at the code, as of Linux 5.16, and did also a little test run
> > (of a standard kernel, not with PREEMPT_RT, only
> > CONFIG_PREEMPT_VOLUNTARY=y) on my Intel Kabylake GT2, so some thoughts:
> >
> > The area covers only register reads and writes. The part that worries me
> > > is:
> > > - __intel_get_crtc_scanline() the worst case is 100us if no match is
> > >   found.
> > >
> >
> > This one can be a problem indeed on (maybe all?) modern Intel gpu's since
> > Haswell, ie. the last ~10 years. I was able to reproduce it on my Kabylake
> > Intel gpu.
> >
> > Most of the time that for-loop with up to 100 repetitions (~ 100
> > udelay(1) + one mmio register read) (cfe.
> > https://elixir.bootlin.com/linux/v5.17-rc1/source/drivers/gpu/drm/i915/i915_irq.c#L856)
> > will not execute, because most of the time that function gets called from
> > the vblank irq handler and then that trigger condition (if
> > (HAS_DDI(dev_priv) && !position)) is not true. However, it also gets called
> > as part of power-saving on behalf of userspace context, whenever the
> > desktop graphics goes idle for two video refresh cycles. If the desktop
> > shows graphics activity again, and vblank interrupts need to get reenabled,
> > the probability of hitting that case is then ~1-4% depending on video mode.
> > How many loops it runs also varies.
> >
> > On my little Intel(R) Core(TM) i5-8250U CPU machine with a mostly idle
> > desktop, I observed about one hit every couple of seconds of regular use,
> > and each hit took between 125 usecs and almost 250 usecs. I guess udelay(1)
> > can take a bit longer than 1 usec?
>
> it should get very close to this. Maybe something else extended the time
> depending on what you observe.
>

Probably all the other stuff in that for-loop adds a microsecond. I
don't have a good feeling how long a typical mmio register read is
expected to take, except for quite a bit less than 1 usec from my
experience.

> > So that's too much for preempt-rt. What one could do is the following:
> >
> > 1. In the for-loop in __intel_get_crtc_scanline(), add a preempt_enable()
> > before the udelay(1); and a preempt_disable() again after it. Or
> > potentially around the whole for-loop if the overhead of
> > preempt_en/disable() is significant?
>
> It is very optimized on x86 ;)

Good! So adding a disable/enable pair into each of those loop
iterations won't hurt.

>
> > 2. In intel_get_crtc_scanline() also wrap the call to
> > __intel_get_crtc_scanline() into a preempt_disable() and preempt_enable(),
> > so we can be sure that __intel_get_crtc_scanline() always gets called with
> > preemption disabled.
> >
> > Why should this work ok'ish? The point of the original preempt disable
> > inside i915_get_crtc_scanoutpos
> > 
> > is that those two *stime = ktime_get() and *etime = ktime_get() clock
> > queries happen as close to the scanout position query as possible to get a
> > small confidence interval for when exactly the scanoutpos was
> > read/determined from the display hardware. error = (etime - stime) is the
> > error margin. If that margin becomes greater than 20 usecs, then the
> > higher-level code will consider the measurement invalid and repeat the
> > whole procedure up to 3 times before giving up.
>
> The preempt-disable is needed then? The task is preemptible here on
> PREEMPT_RT but it _may_ not come to this. The difference vs !RT is that
> an interrupt will preempt this code without it.
>

Yes, it is needed, as that chunk of code between the two ktime_get()
requires should ideally not get interrupted by anything.
The "try up to three times" higher level logic in calling code is just
to cover the hopefully rare cases where something still preempts,
e.g., a NMI or such.

I have not ever tested this on a PREEMPT_RT kernel in at least a
decade, but on regular kernels, e.g., Ubuntu generic or Ubuntu
low-latency kernels I haven't observed more than one retry when it
mattered, and usually the code executes in 0-2 usecs on my test
machines, way below the limit of 20 usecs at which a measurement is
considered failed and then retried. So the retries are sufficient as
long as all preventable preemption is prevented. Hence the
preempt_disable() annotations to make sure it continues to work on
PREEMPT_RT.

The exception, as I learned after your mail, is when that for-loop is
hit. Then it can take hundreds of microseconds, and even spoil all
three retries, resulting in a rather inaccurate measurement. But the
"good news" is that that for-loop will very likely only be hit in
cases where the code is not called from (Vblank/Pageflip-completion)
hardware 

Re: [Intel-gfx] [PATCH 6/6] drm/i915: Pimp icl+ sagv pre/post update

2022-02-14 Thread Lisovskiy, Stanislav
On Mon, Feb 14, 2022 at 12:27:30PM +0200, Ville Syrjälä wrote:
> On Mon, Feb 14, 2022 at 12:00:11PM +0200, Lisovskiy, Stanislav wrote:
> > On Mon, Feb 14, 2022 at 11:18:11AM +0200, Ville Syrjala wrote:
> > > From: Ville Syrjälä 
> > > 
> > > Add some debugs on what exactly we're doing to the QGV point mask
> > > in the icl+ sagv pre/post plane update hooks. Currently we're just
> > > guessing.
> > > 
> > > Cc: Stanislav Lisovskiy 
> > > Signed-off-by: Ville Syrjälä 
> > > ---
> > >  drivers/gpu/drm/i915/intel_pm.c | 37 -
> > >  1 file changed, 18 insertions(+), 19 deletions(-)
> > 
> > Weird I think, I had those debugs initially. Definitely remember
> > there was something similar. Was it kinda removed later?
> 
> Can't immediately see any such debugs being added or removed
> by any commit.

Ah, now actually I remember. It was initially added to intel_bw_atomic_check
to show the new qgv mask, however in one of the reviews was asked to remove
that debug as redundant.

Stan

> 
> > 
> > Stan
> > 
> > Reviewed-by: Stanislav Lisovskiy 
> >  
> > > 
> > > diff --git a/drivers/gpu/drm/i915/intel_pm.c 
> > > b/drivers/gpu/drm/i915/intel_pm.c
> > > index 8b70cdc3b58b..5d1f1a9988bb 100644
> > > --- a/drivers/gpu/drm/i915/intel_pm.c
> > > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > > @@ -3818,26 +3818,22 @@ static void icl_sagv_pre_plane_update(struct 
> > > intel_atomic_state *state)
> > >   intel_atomic_get_old_bw_state(state);
> > >   const struct intel_bw_state *new_bw_state =
> > >   intel_atomic_get_new_bw_state(state);
> > > - u32 new_mask;
> > > + u32 old_mask, new_mask;
> > >  
> > >   if (!new_bw_state)
> > >   return;
> > >  
> > > - /*
> > > -  * Nothing to mask
> > > -  */
> > > - if (new_bw_state->qgv_points_mask == old_bw_state->qgv_points_mask)
> > > - return;
> > > -
> > > + old_mask = old_bw_state->qgv_points_mask;
> > >   new_mask = old_bw_state->qgv_points_mask | 
> > > new_bw_state->qgv_points_mask;
> > >  
> > > - /*
> > > -  * If new mask is zero - means there is nothing to mask,
> > > -  * we can only unmask, which should be done in unmask.
> > > -  */
> > > - if (!new_mask)
> > > + if (old_mask == new_mask)
> > >   return;
> > >  
> > > + WARN_ON(!new_bw_state->base.changed);
> > > +
> > > + drm_dbg_kms(_priv->drm, "Restricting QGV points: 0x%x -> 0x%x\n",
> > > + old_mask, new_mask);
> > > +
> > >   /*
> > >* Restrict required qgv points before updating the configuration.
> > >* According to BSpec we can't mask and unmask qgv points at the same
> > > @@ -3854,19 +3850,22 @@ static void icl_sagv_post_plane_update(struct 
> > > intel_atomic_state *state)
> > >   intel_atomic_get_old_bw_state(state);
> > >   const struct intel_bw_state *new_bw_state =
> > >   intel_atomic_get_new_bw_state(state);
> > > - u32 new_mask = 0;
> > > + u32 old_mask, new_mask;
> > >  
> > >   if (!new_bw_state)
> > >   return;
> > >  
> > > - /*
> > > -  * Nothing to unmask
> > > -  */
> > > - if (new_bw_state->qgv_points_mask == old_bw_state->qgv_points_mask)
> > > - return;
> > > -
> > > + old_mask = old_bw_state->qgv_points_mask | 
> > > new_bw_state->qgv_points_mask;
> > >   new_mask = new_bw_state->qgv_points_mask;
> > >  
> > > + if (old_mask == new_mask)
> > > + return;
> > > +
> > > + WARN_ON(!new_bw_state->base.changed);
> > > +
> > > + drm_dbg_kms(_priv->drm, "Relaxing QGV points: 0x%x -> 0x%x\n",
> > > + old_mask, new_mask);
> > > +
> > >   /*
> > >* Allow required qgv points after updating the configuration.
> > >* According to BSpec we can't mask and unmask qgv points at the same
> > > -- 
> > > 2.34.1
> > > 
> 
> -- 
> Ville Syrjälä
> Intel


Re: [Intel-gfx] [PATCH 1/2] drm: Add HPD state to drm_connector_oob_hotplug_event()

2022-02-14 Thread Imre Deak
On Mon, Feb 07, 2022 at 08:43:27PM -0800, Bjorn Andersson wrote:
> In some implementations, such as the Qualcomm platforms, the display
> driver has no way to query the current HPD state and as such it's
> impossible to distinguish between disconnect and attention events.
> 
> Add a parameter to drm_connector_oob_hotplug_event() to pass the HPD
> state.
> 
> Also push the test for unchanged state in the displayport altmode driver
> into the i915 driver, to allow other drivers to act upon each update.
> 
> Signed-off-by: Bjorn Andersson 
> ---
> 
> Note that the Intel driver has only been compile tested with this patch.
> 
>  drivers/gpu/drm/drm_connector.c  |  6 --
>  drivers/gpu/drm/i915/display/intel_dp.c  | 14 +++---
>  drivers/gpu/drm/i915/i915_drv.h  |  3 +++
>  drivers/usb/typec/altmodes/displayport.c |  9 ++---
>  include/drm/drm_connector.h  |  5 +++--
>  5 files changed, 23 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index a50c82bc2b2f..ad7295597c0f 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -2825,6 +2825,7 @@ struct drm_connector 
> *drm_connector_find_by_fwnode(struct fwnode_handle *fwnode)
>  /**
>   * drm_connector_oob_hotplug_event - Report out-of-band hotplug event to 
> connector
>   * @connector_fwnode: fwnode_handle to report the event on
> + * @hpd_state: number of data lanes available
>   *
>   * On some hardware a hotplug event notification may come from outside the 
> display
>   * driver / device. An example of this is some USB Type-C setups where the 
> hardware
> @@ -2834,7 +2835,8 @@ struct drm_connector 
> *drm_connector_find_by_fwnode(struct fwnode_handle *fwnode)
>   * This function can be used to report these out-of-band events after 
> obtaining
>   * a drm_connector reference through calling drm_connector_find_by_fwnode().
>   */
> -void drm_connector_oob_hotplug_event(struct fwnode_handle *connector_fwnode)
> +void drm_connector_oob_hotplug_event(struct fwnode_handle *connector_fwnode,
> +  bool hpd_state)
>  {
>   struct drm_connector *connector;
>  
> @@ -2843,7 +2845,7 @@ void drm_connector_oob_hotplug_event(struct 
> fwnode_handle *connector_fwnode)
>   return;
>  
>   if (connector->funcs->oob_hotplug_event)
> - connector->funcs->oob_hotplug_event(connector);
> + connector->funcs->oob_hotplug_event(connector, hpd_state);
>  
>   drm_connector_put(connector);
>  }
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> b/drivers/gpu/drm/i915/display/intel_dp.c
> index 146b83916005..00520867d37b 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -4816,15 +4816,23 @@ static int intel_dp_connector_atomic_check(struct 
> drm_connector *conn,
>   return intel_modeset_synced_crtcs(state, conn);
>  }
>  
> -static void intel_dp_oob_hotplug_event(struct drm_connector *connector)
> +static void intel_dp_oob_hotplug_event(struct drm_connector *connector, bool 
> hpd_state)
>  {
>   struct intel_encoder *encoder = 
> intel_attached_encoder(to_intel_connector(connector));
>   struct drm_i915_private *i915 = to_i915(connector->dev);
> + bool need_work = false;
>  
>   spin_lock_irq(>irq_lock);
> - i915->hotplug.event_bits |= BIT(encoder->hpd_pin);
> + if (hpd_state != i915->hotplug.oob_hotplug_state) {

hpd_state is speific to the encoder (pin) so similarly to event_bits
oob_hotplug_state should be a bitmask as well.

> + i915->hotplug.event_bits |= BIT(encoder->hpd_pin);
> +
> + i915->hotplug.oob_hotplug_state = hpd_state;
> + need_work = true;
> + }
>   spin_unlock_irq(>irq_lock);
> - queue_delayed_work(system_wq, >hotplug.hotplug_work, 0);
> +
> + if (need_work)
> + queue_delayed_work(system_wq, >hotplug.hotplug_work, 0);
>  }
>  
>  static const struct drm_connector_funcs intel_dp_connector_funcs = {
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index 8c1706fd81f9..543ebf1cfcf4 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -149,6 +149,9 @@ struct i915_hotplug {
>   /* Whether or not to count short HPD IRQs in HPD storms */
>   u8 hpd_short_storm_enabled;
>  
> + /* Last state reported by oob_hotplug_event */
> + bool oob_hotplug_state;
> +
>   /*
>* if we get a HPD irq from DP and a HPD irq from non-DP
>* the non-DP HPD could block the workqueue on a mode config
> diff --git a/drivers/usb/typec/altmodes/displayport.c 
> b/drivers/usb/typec/altmodes/displayport.c
> index c1d8c23baa39..a4596be4d34a 100644
> --- a/drivers/usb/typec/altmodes/displayport.c
> +++ b/drivers/usb/typec/altmodes/displayport.c
> @@ -59,7 +59,6 @@ struct dp_altmode {
>   struct 

Re: [Intel-gfx] [PATCH 6/6] drm/i915: Pimp icl+ sagv pre/post update

2022-02-14 Thread Lisovskiy, Stanislav
On Mon, Feb 14, 2022 at 12:27:30PM +0200, Ville Syrjälä wrote:
> On Mon, Feb 14, 2022 at 12:00:11PM +0200, Lisovskiy, Stanislav wrote:
> > On Mon, Feb 14, 2022 at 11:18:11AM +0200, Ville Syrjala wrote:
> > > From: Ville Syrjälä 
> > > 
> > > Add some debugs on what exactly we're doing to the QGV point mask
> > > in the icl+ sagv pre/post plane update hooks. Currently we're just
> > > guessing.
> > > 
> > > Cc: Stanislav Lisovskiy 
> > > Signed-off-by: Ville Syrjälä 
> > > ---
> > >  drivers/gpu/drm/i915/intel_pm.c | 37 -
> > >  1 file changed, 18 insertions(+), 19 deletions(-)
> > 
> > Weird I think, I had those debugs initially. Definitely remember
> > there was something similar. Was it kinda removed later?
> 
> Can't immediately see any such debugs being added or removed
> by any commit.

Definitely was there, either during restriction itself or in
intel_bw_atomic_check. Don't remember, if it was excessive debugs
someone was complaining or someother reason, why it was removed.

Stan

> 
> > 
> > Stan
> > 
> > Reviewed-by: Stanislav Lisovskiy 
> >  
> > > 
> > > diff --git a/drivers/gpu/drm/i915/intel_pm.c 
> > > b/drivers/gpu/drm/i915/intel_pm.c
> > > index 8b70cdc3b58b..5d1f1a9988bb 100644
> > > --- a/drivers/gpu/drm/i915/intel_pm.c
> > > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > > @@ -3818,26 +3818,22 @@ static void icl_sagv_pre_plane_update(struct 
> > > intel_atomic_state *state)
> > >   intel_atomic_get_old_bw_state(state);
> > >   const struct intel_bw_state *new_bw_state =
> > >   intel_atomic_get_new_bw_state(state);
> > > - u32 new_mask;
> > > + u32 old_mask, new_mask;
> > >  
> > >   if (!new_bw_state)
> > >   return;
> > >  
> > > - /*
> > > -  * Nothing to mask
> > > -  */
> > > - if (new_bw_state->qgv_points_mask == old_bw_state->qgv_points_mask)
> > > - return;
> > > -
> > > + old_mask = old_bw_state->qgv_points_mask;
> > >   new_mask = old_bw_state->qgv_points_mask | 
> > > new_bw_state->qgv_points_mask;
> > >  
> > > - /*
> > > -  * If new mask is zero - means there is nothing to mask,
> > > -  * we can only unmask, which should be done in unmask.
> > > -  */
> > > - if (!new_mask)
> > > + if (old_mask == new_mask)
> > >   return;
> > >  
> > > + WARN_ON(!new_bw_state->base.changed);
> > > +
> > > + drm_dbg_kms(_priv->drm, "Restricting QGV points: 0x%x -> 0x%x\n",
> > > + old_mask, new_mask);
> > > +
> > >   /*
> > >* Restrict required qgv points before updating the configuration.
> > >* According to BSpec we can't mask and unmask qgv points at the same
> > > @@ -3854,19 +3850,22 @@ static void icl_sagv_post_plane_update(struct 
> > > intel_atomic_state *state)
> > >   intel_atomic_get_old_bw_state(state);
> > >   const struct intel_bw_state *new_bw_state =
> > >   intel_atomic_get_new_bw_state(state);
> > > - u32 new_mask = 0;
> > > + u32 old_mask, new_mask;
> > >  
> > >   if (!new_bw_state)
> > >   return;
> > >  
> > > - /*
> > > -  * Nothing to unmask
> > > -  */
> > > - if (new_bw_state->qgv_points_mask == old_bw_state->qgv_points_mask)
> > > - return;
> > > -
> > > + old_mask = old_bw_state->qgv_points_mask | 
> > > new_bw_state->qgv_points_mask;
> > >   new_mask = new_bw_state->qgv_points_mask;
> > >  
> > > + if (old_mask == new_mask)
> > > + return;
> > > +
> > > + WARN_ON(!new_bw_state->base.changed);
> > > +
> > > + drm_dbg_kms(_priv->drm, "Relaxing QGV points: 0x%x -> 0x%x\n",
> > > + old_mask, new_mask);
> > > +
> > >   /*
> > >* Allow required qgv points after updating the configuration.
> > >* According to BSpec we can't mask and unmask qgv points at the same
> > > -- 
> > > 2.34.1
> > > 
> 
> -- 
> Ville Syrjälä
> Intel


[Intel-gfx] [stanislav.lisovs...@intel.com: Re: [PATCH 4/6] drm/i915: Unconfuse pre-icl vs. icl+ intel_sagv_{pre, post}_plane_update()]

2022-02-14 Thread Lisovskiy, Stanislav
Date: Mon, 14 Feb 2022 19:39:28 +0200
From: "Lisovskiy, Stanislav" 
To: Ville Syrjala 
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH 4/6] drm/i915: Unconfuse pre-icl vs. icl+ 
intel_sagv_{pre,post}_plane_update()
User-Agent: Mutt/1.9.4 (2018-02-28)

On Mon, Feb 14, 2022 at 11:18:09AM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> intel_sagv_{pre,post}_plane_update() can accidentally forget
> to bail out early on pre-icl and proceed down the icl+ codepath
> at the end of the function. Fortunately it'll bail out before
> it gets too far due to old_qgv_mask==new_qgv_mask==0 so no real
> bug here. But lets make the code less confusing anyway.
> 
> Cc: Stanislav Lisovskiy 
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 10 ++
>  1 file changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index d8eb553ffad3..068870b17c43 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3806,8 +3806,9 @@ void intel_sagv_pre_plane_update(struct 
> intel_atomic_state *state)
>   if (!new_bw_state)
>   return;
>  
> - if (DISPLAY_VER(dev_priv) < 11 && !intel_can_enable_sagv(dev_priv, 
> new_bw_state)) {
> - intel_disable_sagv(dev_priv);
> + if (DISPLAY_VER(dev_priv) < 11) {
> + if (!intel_can_enable_sagv(dev_priv, new_bw_state))
> + intel_disable_sagv(dev_priv);
>   return;
>   }

Reviewed-by: Stanislav Lisovskiy 

Agree, I think that was my original code as well. However to be honest, don't 
like
the whole idea of splitting the code flow and bailing our prematurely for gen < 
11 here.
Would be nice to have some unified approach, so that we have common main logic 
for all platforms,
like 
if (intel_bw_state_equals(new, old))
return

intel_bw_state_apply_restrictions(...)  -> here we would add 
intel_enable/disable_sagv for gen <11 and
   qgv point restrictions for gen >= 11

Stan

>  
> @@ -3857,8 +3858,9 @@ void intel_sagv_post_plane_update(struct 
> intel_atomic_state *state)
>   if (!new_bw_state)
>   return;
>  
> - if (DISPLAY_VER(dev_priv) < 11 && intel_can_enable_sagv(dev_priv, 
> new_bw_state)) {
> - intel_enable_sagv(dev_priv);
> + if (DISPLAY_VER(dev_priv) < 11) {
> + if (intel_can_enable_sagv(dev_priv, new_bw_state))
> + intel_enable_sagv(dev_priv);
>   return;
>   }
>  
> -- 
> 2.34.1
> 

- End forwarded message -


Re: [Intel-gfx] [PATCH 4/6] drm/i915: Unconfuse pre-icl vs. icl+ intel_sagv_{pre, post}_plane_update()

2022-02-14 Thread Lisovskiy, Stanislav
On Mon, Feb 14, 2022 at 11:18:09AM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> intel_sagv_{pre,post}_plane_update() can accidentally forget
> to bail out early on pre-icl and proceed down the icl+ codepath
> at the end of the function. Fortunately it'll bail out before
> it gets too far due to old_qgv_mask==new_qgv_mask==0 so no real
> bug here. But lets make the code less confusing anyway.
> 
> Cc: Stanislav Lisovskiy 
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 10 ++
>  1 file changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index d8eb553ffad3..068870b17c43 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3806,8 +3806,9 @@ void intel_sagv_pre_plane_update(struct 
> intel_atomic_state *state)
>   if (!new_bw_state)
>   return;
>  
> - if (DISPLAY_VER(dev_priv) < 11 && !intel_can_enable_sagv(dev_priv, 
> new_bw_state)) {
> - intel_disable_sagv(dev_priv);
> + if (DISPLAY_VER(dev_priv) < 11) {
> + if (!intel_can_enable_sagv(dev_priv, new_bw_state))
> + intel_disable_sagv(dev_priv);
>   return;
>   }

Reviewed-by: Stanislav Lisovskiy 

Agree, I think that was my original code as well. However to be honest, don't 
like
the whole idea of splitting the code flow and bailing our prematurely for gen < 
11 here.
Would be nice to have some unified approach, so that we have common main logic 
for all platforms,
like 
if (intel_bw_state_equals(new, old))
return

intel_bw_state_apply_restrictions(...)  -> here we would add 
intel_enable/disable_sagv for gen <11 and
   qgv point restrictions for gen >= 11

Stan

>  
> @@ -3857,8 +3858,9 @@ void intel_sagv_post_plane_update(struct 
> intel_atomic_state *state)
>   if (!new_bw_state)
>   return;
>  
> - if (DISPLAY_VER(dev_priv) < 11 && intel_can_enable_sagv(dev_priv, 
> new_bw_state)) {
> - intel_enable_sagv(dev_priv);
> + if (DISPLAY_VER(dev_priv) < 11) {
> + if (intel_can_enable_sagv(dev_priv, new_bw_state))
> + intel_enable_sagv(dev_priv);
>   return;
>   }
>  
> -- 
> 2.34.1
> 


[Intel-gfx] [PATCH 2/2] drm/i915/lrc: replace include with forward declarations

2022-02-14 Thread Jani Nikula
Prefer forward declarations over includes if possible.

Signed-off-by: Jani Nikula 
---
 drivers/gpu/drm/i915/gt/intel_lrc.c | 2 ++
 drivers/gpu/drm/i915/gt/intel_lrc.h | 5 +++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c 
b/drivers/gpu/drm/i915/gt/intel_lrc.c
index 5b107b698b65..004e1216e654 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -8,6 +8,8 @@
 #include "gen8_engine_cs.h"
 #include "i915_drv.h"
 #include "i915_perf.h"
+#include "i915_reg.h"
+#include "intel_context.h"
 #include "intel_engine.h"
 #include "intel_engine_regs.h"
 #include "intel_gpu_commands.h"
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.h 
b/drivers/gpu/drm/i915/gt/intel_lrc.h
index 2af85a15a370..0b76f096b559 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.h
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.h
@@ -8,11 +8,12 @@
 
 #include 
 
-#include "intel_context.h"
-
 struct drm_i915_gem_object;
+struct i915_gem_ww_ctx;
+struct intel_context;
 struct intel_engine_cs;
 struct intel_ring;
+struct kref;
 
 /* At the start of the context image is its per-process HWS page */
 #define LRC_PPHWSP_PN  (0)
-- 
2.30.2



[Intel-gfx] [PATCH 1/2] drm/i915/lrc: move lrc_get_runtime() to intel_lrc.c

2022-02-14 Thread Jani Nikula
Move the static inline next to the only caller.

Signed-off-by: Jani Nikula 
---
 drivers/gpu/drm/i915/gt/intel_context_sseu.c |  1 +
 drivers/gpu/drm/i915/gt/intel_lrc.c  | 11 +++
 drivers/gpu/drm/i915/gt/intel_lrc.h  | 11 ---
 drivers/gpu/drm/i915/i915_perf.c |  1 +
 4 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context_sseu.c 
b/drivers/gpu/drm/i915/gt/intel_context_sseu.c
index e86d8255feec..ece16c2b5b8e 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_sseu.c
+++ b/drivers/gpu/drm/i915/gt/intel_context_sseu.c
@@ -9,6 +9,7 @@
 #include "intel_engine_pm.h"
 #include "intel_gpu_commands.h"
 #include "intel_lrc.h"
+#include "intel_lrc_reg.h"
 #include "intel_ring.h"
 #include "intel_sseu.h"
 
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.c 
b/drivers/gpu/drm/i915/gt/intel_lrc.c
index 8189bc8a16ec..5b107b698b65 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.c
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.c
@@ -1720,6 +1720,17 @@ static void st_update_runtime_underflow(struct 
intel_context *ce, s32 dt)
 #endif
 }
 
+static u32 lrc_get_runtime(const struct intel_context *ce)
+{
+   /*
+* We can use either ppHWSP[16] which is recorded before the context
+* switch (and so excludes the cost of context switches) or use the
+* value from the context image itself, which is saved/restored earlier
+* and so includes the cost of the save.
+*/
+   return READ_ONCE(ce->lrc_reg_state[CTX_TIMESTAMP]);
+}
+
 void lrc_update_runtime(struct intel_context *ce)
 {
u32 old;
diff --git a/drivers/gpu/drm/i915/gt/intel_lrc.h 
b/drivers/gpu/drm/i915/gt/intel_lrc.h
index 7f697845c4cf..2af85a15a370 100644
--- a/drivers/gpu/drm/i915/gt/intel_lrc.h
+++ b/drivers/gpu/drm/i915/gt/intel_lrc.h
@@ -9,7 +9,6 @@
 #include 
 
 #include "intel_context.h"
-#include "intel_lrc_reg.h"
 
 struct drm_i915_gem_object;
 struct intel_engine_cs;
@@ -68,15 +67,5 @@ void lrc_check_regs(const struct intel_context *ce,
const char *when);
 
 void lrc_update_runtime(struct intel_context *ce);
-static inline u32 lrc_get_runtime(const struct intel_context *ce)
-{
-   /*
-* We can use either ppHWSP[16] which is recorded before the context
-* switch (and so excludes the cost of context switches) or use the
-* value from the context image itself, which is saved/restored earlier
-* and so includes the cost of the save.
-*/
-   return READ_ONCE(ce->lrc_reg_state[CTX_TIMESTAMP]);
-}
 
 #endif /* __INTEL_LRC_H__ */
diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
index 36f1325baa7d..00fb40029f43 100644
--- a/drivers/gpu/drm/i915/i915_perf.c
+++ b/drivers/gpu/drm/i915/i915_perf.c
@@ -206,6 +206,7 @@
 #include "gt/intel_gt_clock_utils.h"
 #include "gt/intel_gt_regs.h"
 #include "gt/intel_lrc.h"
+#include "gt/intel_lrc_reg.h"
 #include "gt/intel_ring.h"
 
 #include "i915_drv.h"
-- 
2.30.2



[Intel-gfx] [PATCH] drm/i915/pxp: prefer forward declaration over includes

2022-02-14 Thread Jani Nikula
Always use forward declarations instead of includes in headers if
possible.

Signed-off-by: Jani Nikula 
---
 drivers/gpu/drm/i915/pxp/intel_pxp_pm.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.h 
b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.h
index 16990a3f2f85..586be769104f 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.h
@@ -6,7 +6,7 @@
 #ifndef __INTEL_PXP_PM_H__
 #define __INTEL_PXP_PM_H__
 
-#include "intel_pxp_types.h"
+struct intel_pxp;
 
 #ifdef CONFIG_DRM_I915_PXP
 void intel_pxp_suspend_prepare(struct intel_pxp *pxp);
-- 
2.30.2



Re: [Intel-gfx] [PATCH 3/6] drm/i915: Widen the QGV point mask

2022-02-14 Thread Lisovskiy, Stanislav
On Mon, Feb 14, 2022 at 11:18:08AM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> adlp+ adds some extra bits to the QGV point mask. The code attempts
> to handle that but forgot to actually make sure we can store those
> bits in the bw state. Fix it.
> 
> Cc: sta...@vger.kernel.org
> Cc: Stanislav Lisovskiy 
> Fixes: 192fbfb76744 ("drm/i915: Implement PSF GV point support")
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/display/intel_bw.h | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_bw.h 
> b/drivers/gpu/drm/i915/display/intel_bw.h
> index 46c6eecbd917..0ceaed1c9656 100644
> --- a/drivers/gpu/drm/i915/display/intel_bw.h
> +++ b/drivers/gpu/drm/i915/display/intel_bw.h
> @@ -30,19 +30,19 @@ struct intel_bw_state {
>*/
>   u8 pipe_sagv_reject;
>  
> + /* bitmask of active pipes */
> + u8 active_pipes;
> +
>   /*
>* Current QGV points mask, which restricts
>* some particular SAGV states, not to confuse
>* with pipe_sagv_mask.
>*/
> - u8 qgv_points_mask;
> + u16 qgv_points_mask;

Weird, that this went unnoticed. Don't we have static analyzer for such
purposes? Wonder if it should catch and warn about this, because in
intel_bw_atomic_check we have u32 bitmask, which is then getting packed
in 8 bit field.
Probably bitmask type width used in intel_bw_atomic_check should match
that one, so that there would be less room for confusion.

Reviewed-by: Stanislav Lisovskiy 

>  
>   unsigned int data_rate[I915_MAX_PIPES];
>   u8 num_active_planes[I915_MAX_PIPES];
>  
> - /* bitmask of active pipes */
> - u8 active_pipes;
> -
>   int min_cdclk;
>  };
>  
> -- 
> 2.34.1
> 


Re: [Intel-gfx] [PATCH 2/6] drm/i915: Fix bw atomic check when switching between SAGV vs. no SAGV

2022-02-14 Thread Lisovskiy, Stanislav
On Mon, Feb 14, 2022 at 12:24:57PM +0200, Ville Syrjälä wrote:
> On Mon, Feb 14, 2022 at 12:05:36PM +0200, Lisovskiy, Stanislav wrote:
> > On Mon, Feb 14, 2022 at 11:18:07AM +0200, Ville Syrjala wrote:
> > > From: Ville Syrjälä 
> > > 
> > > If the only thing that is changing is SAGV vs. no SAGV but
> > > the number of active planes and the total data rates end up
> > > unchanged we currently bail out of intel_bw_atomic_check()
> > > early and forget to actually compute the new WGV point
> > > mask and thus won't actually enable/disable SAGV as requested.
> > > This ends up poorly if we end up running with SAGV enabled
> > > when we shouldn't. Usually ends up in underruns.
> > > To fix this let's go through the QGV point mask computation
> > > if anyone else already added the bw state for us.
> > 
> > Haven't been looking this in a while. Despite we have been
> > looking like few revisions together still some bugs :(
> > 
> > I thought SAGV vs No SAGV can't change if active planes 
> > or data rate didn't change? Because it means we probably
> > still have same ddb allocations, which means SAGV state
> > will just stay the same.
> 
> SAGV can change due to watermarks/ddb allocations. The easiest
> way to trip this up is to try to use the async flip wm0/ddb 
> optimization. That immediately forgets to turn off SAGV and
> we get underruns, whcih is how I noticed this. And I don't
> immediately see any easy proof that this couldn't also happen
> due to some other plane changes.

Thats the way it was initially implemented even before SAGV was added.
I think it can be dated back to the very first bw check was implemented.

commit c457d9cf256e942138a54a2e80349ee7fe20c391
Author: Ville Syrjälä 
Date:   Fri May 24 18:36:14 2019 +0300

drm/i915: Make sure we have enough memory bandwidth on ICL

+int intel_bw_atomic_check(struct intel_atomic_state *state)
+{
+   struct drm_i915_private *dev_priv = to_i915(state->base.dev);
+   struct intel_crtc_state *new_crtc_state, *old_crtc_state;
+   struct intel_bw_state *bw_state = NULL;
+   unsigned int data_rate, max_data_rate;
+   unsigned int num_active_planes;
+   struct intel_crtc *crtc;
+   int i;
+
+   /* FIXME earlier gens need some checks too */
+   if (INTEL_GEN(dev_priv) < 11)
+   return 0;
+
+   for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
+   new_crtc_state, i) {
+   unsigned int old_data_rate =
+   intel_bw_crtc_data_rate(old_crtc_state);
+   unsigned int new_data_rate =
+   intel_bw_crtc_data_rate(new_crtc_state);
+   unsigned int old_active_planes =
+   intel_bw_crtc_num_active_planes(old_crtc_state);
+   unsigned int new_active_planes =
+   intel_bw_crtc_num_active_planes(new_crtc_state);
+
+   /*
+* Avoid locking the bw state when
+* nothing significant has changed.
+*/
+   if (old_data_rate == new_data_rate &&
+   old_active_planes == new_active_planes)
+   continue;
+
+   bw_state  = intel_atomic_get_bw_state(state);
+   if (IS_ERR(bw_state))
+   return PTR_ERR(bw_state);

However, what can cause watermarks/ddb to change, besides plane state change
and/or active planes change? We change watermarks, when we change ddb 
allocations
and we change ddb allocations when active planes had changed and/or data rate
had changed.

Stan

> 
> > 
> > Stan
> > 
> > > 
> > > Cc: sta...@vger.kernel.org
> > > Cc: Stanislav Lisovskiy 
> > > Fixes: 20f505f22531 ("drm/i915: Restrict qgv points which don't have 
> > > enough bandwidth.")
> > > Signed-off-by: Ville Syrjälä 
> > > ---
> > >  drivers/gpu/drm/i915/display/intel_bw.c | 7 +++
> > >  1 file changed, 7 insertions(+)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_bw.c 
> > > b/drivers/gpu/drm/i915/display/intel_bw.c
> > > index 23aa8e06de18..d72ccee7d53b 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_bw.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_bw.c
> > > @@ -846,6 +846,13 @@ int intel_bw_atomic_check(struct intel_atomic_state 
> > > *state)
> > >   if (num_psf_gv_points > 0)
> > >   mask |= REG_GENMASK(num_psf_gv_points - 1, 0) << 
> > > ADLS_PSF_PT_SHIFT;
> > >  
> > > + /*
> > > +  * If we already have the bw state then recompute everything
> > > +  * even if pipe data_rate / active_planes didn't change.
> > > +  * Other things (such as SAGV) may have changed.
> > > +  */
> > > + new_bw_state = intel_atomic_get_new_bw_state(state);
> > > +
> > >   for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
> > >   new_crtc_state, i) {
> > >   unsigned int old_data_rate =
> > > -- 
> > > 2.34.1
> > > 
> 
> -- 
> Ville Syrjälä
> Intel


Re: [Intel-gfx] [PATCH v12 1/5] drm: improve drm_buddy_alloc function

2022-02-14 Thread Christian König

Am 13.02.22 um 09:52 schrieb Arunpravin:

- Make drm_buddy_alloc a single function to handle
   range allocation and non-range allocation demands

- Implemented a new function alloc_range() which allocates
   the requested power-of-two block comply with range limitations

- Moved order computation and memory alignment logic from
   i915 driver to drm buddy

v2:
   merged below changes to keep the build unbroken
- drm_buddy_alloc_range() becomes obsolete and may be removed
- enable ttm range allocation (fpfn / lpfn) support in i915 driver
- apply enhanced drm_buddy_alloc() function to i915 driver

v3(Matthew Auld):
   - Fix alignment issues and remove unnecessary list_empty check
   - add more validation checks for input arguments
   - make alloc_range() block allocations as bottom-up
   - optimize order computation logic
   - replace uint64_t with u64, which is preferred in the kernel

v4(Matthew Auld):
   - keep drm_buddy_alloc_range() function implementation for generic
 actual range allocations
   - keep alloc_range() implementation for end bias allocations

v5(Matthew Auld):
   - modify drm_buddy_alloc() passing argument place->lpfn to lpfn
 as place->lpfn will currently always be zero for i915

v6(Matthew Auld):
   - fixup potential uaf - If we are unlucky and can't allocate
 enough memory when splitting blocks, where we temporarily
 end up with the given block and its buddy on the respective
 free list, then we need to ensure we delete both blocks,
 and no just the buddy, before potentially freeing them

   - fix warnings reported by kernel test robot 

v7(Matthew Auld):
   - revert fixup potential uaf
   - keep __alloc_range() add node to the list logic same as
 drm_buddy_alloc_blocks() by having a temporary list variable
   - at drm_buddy_alloc_blocks() keep i915 range_overflows macro
 and add a new check for end variable

v8:
   - fix warnings reported by kernel test robot 

v9(Matthew Auld):
   - remove DRM_BUDDY_RANGE_ALLOCATION flag
   - remove unnecessary function description

Signed-off-by: Arunpravin 
Reviewed-by: Matthew Auld 


As long as nobody objects I'm going to push patches 1-3 to drm-misc-next 
in the next hour or so:


Then going to take a deeper look into patches 4 and 5 to get them reviewed.

Thanks,
Christian.


---
  drivers/gpu/drm/drm_buddy.c   | 292 +-
  drivers/gpu/drm/i915/i915_ttm_buddy_manager.c |  63 ++--
  drivers/gpu/drm/i915/i915_ttm_buddy_manager.h |   2 +
  include/drm/drm_buddy.h   |  11 +-
  4 files changed, 250 insertions(+), 118 deletions(-)

diff --git a/drivers/gpu/drm/drm_buddy.c b/drivers/gpu/drm/drm_buddy.c
index d60878bc9c20..e0c0d786a572 100644
--- a/drivers/gpu/drm/drm_buddy.c
+++ b/drivers/gpu/drm/drm_buddy.c
@@ -282,23 +282,97 @@ void drm_buddy_free_list(struct drm_buddy *mm, struct 
list_head *objects)
  }
  EXPORT_SYMBOL(drm_buddy_free_list);
  
-/**

- * drm_buddy_alloc_blocks - allocate power-of-two blocks
- *
- * @mm: DRM buddy manager to allocate from
- * @order: size of the allocation
- *
- * The order value here translates to:
- *
- * 0 = 2^0 * mm->chunk_size
- * 1 = 2^1 * mm->chunk_size
- * 2 = 2^2 * mm->chunk_size
- *
- * Returns:
- * allocated ptr to the _buddy_block on success
- */
-struct drm_buddy_block *
-drm_buddy_alloc_blocks(struct drm_buddy *mm, unsigned int order)
+static inline bool overlaps(u64 s1, u64 e1, u64 s2, u64 e2)
+{
+   return s1 <= e2 && e1 >= s2;
+}
+
+static inline bool contains(u64 s1, u64 e1, u64 s2, u64 e2)
+{
+   return s1 <= s2 && e1 >= e2;
+}
+
+static struct drm_buddy_block *
+alloc_range_bias(struct drm_buddy *mm,
+u64 start, u64 end,
+unsigned int order)
+{
+   struct drm_buddy_block *block;
+   struct drm_buddy_block *buddy;
+   LIST_HEAD(dfs);
+   int err;
+   int i;
+
+   end = end - 1;
+
+   for (i = 0; i < mm->n_roots; ++i)
+   list_add_tail(>roots[i]->tmp_link, );
+
+   do {
+   u64 block_start;
+   u64 block_end;
+
+   block = list_first_entry_or_null(,
+struct drm_buddy_block,
+tmp_link);
+   if (!block)
+   break;
+
+   list_del(>tmp_link);
+
+   if (drm_buddy_block_order(block) < order)
+   continue;
+
+   block_start = drm_buddy_block_offset(block);
+   block_end = block_start + drm_buddy_block_size(mm, block) - 1;
+
+   if (!overlaps(start, end, block_start, block_end))
+   continue;
+
+   if (drm_buddy_block_is_allocated(block))
+   continue;
+
+   if (contains(start, end, block_start, block_end) &&
+   order == drm_buddy_block_order(block)) {
+   /*
+* Find 

[Intel-gfx] [PATCH V2 4/13] gpu: drm: radeon: use time_is_before_jiffies() instead of jiffies judgment

2022-02-14 Thread Qing Wang
From: Wang Qing 

It is better to use time_xxx() directly instead of jiffies judgment
for understanding.

Signed-off-by: Wang Qing 
---
 drivers/gpu/drm/radeon/radeon_pm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/radeon/radeon_pm.c 
b/drivers/gpu/drm/radeon/radeon_pm.c
index c67b6dd..53d536a
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -1899,7 +1900,7 @@ static void radeon_dynpm_idle_work_handler(struct 
work_struct *work)
 * to false since we want to wait for vbl to avoid flicker.
 */
if (rdev->pm.dynpm_planned_action != DYNPM_ACTION_NONE &&
-   jiffies > rdev->pm.dynpm_action_timeout) {
+   time_is_before_jiffies(rdev->pm.dynpm_action_timeout)) {
radeon_pm_get_dynpm_state(rdev);
radeon_pm_set_clocks(rdev);
}
-- 
2.7.4



Re: [Intel-gfx] [RFC 00/12] locking: Separate lock tracepoints from lockdep/lock_stat (v1)

2022-02-14 Thread Mathieu Desnoyers
- On Feb 9, 2022, at 2:02 PM, Waiman Long long...@redhat.com wrote:

> On 2/9/22 13:29, Mathieu Desnoyers wrote:
>> - On Feb 9, 2022, at 1:19 PM, Waiman Long long...@redhat.com wrote:
>>
>>> On 2/9/22 04:09, Peter Zijlstra wrote:
 On Tue, Feb 08, 2022 at 10:41:56AM -0800, Namhyung Kim wrote:

> Eventually I'm mostly interested in the contended locks only and I
> want to reduce the overhead in the fast path.  By moving that, it'd be
> easy to track contended locks with timing by using two tracepoints.
 So why not put in two new tracepoints and call it a day?

 Why muck about with all that lockdep stuff just to preserve the name
 (and in the process continue to blow up data structures etc..). This
 leaves distros in a bind, will they enable this config and provide
 tracepoints while bloating the data structures and destroying things
 like lockref (which relies on sizeof(spinlock_t)), or not provide this
 at all.

 Yes, the name is convenient, but it's just not worth it IMO. It makes
 the whole proposition too much of a trade-off.

 Would it not be possible to reconstruct enough useful information from
 the lock callsite?

>>> I second that as I don't want to see the size of a spinlock exceeds 4
>>> bytes in a production system.
>>>
>>> Instead of storing additional information (e.g. lock name) directly into
>>> the lock itself. Maybe we can store it elsewhere and use the lock
>>> address as the key to locate it in a hash table. We can certainly extend
>>> the various lock init functions to do that. It will be trickier for
>>> statically initialized locks, but we can probably find a way to do that too.
>> If we go down that route, it would be nice if we can support a few different
>> use-cases for various tracers out there.
>>
>> One use-case (a) requires the ability to query the lock name based on its
>> address as key.
>> For this a hash table is a good fit. This would allow tracers like ftrace to
>> output lock names in its human-readable output which is formatted within the
>> kernel.
>>
>> Another use-case (b) is to be able to "dump" the lock { name, address } 
>> tuples
>> into the trace stream (we call this statedump events in lttng), and do the
>> translation from address to name at post-processing. This simply requires
>> that this information is available for iteration for both the core kernel
>> and module locks, so the tracer can dump this information on trace start
>> and module load.
>>
>> Use-case (b) is very similar to what is done for the kernel tracepoints. 
>> Based
>> on this, implementing the init code that iterates on those sections and
>> populates
>> a hash table for use-case (a) should be easy enough.
> 
> Yes, that are good use cases for this type of functionality. I do need
> to think about how to do it for statically initialized lock first.

Tracepoints already solved that problem.

Look at the macro DEFINE_TRACE_FN() in include/linux/tracepoint.h. You will 
notice that
it statically defines a struct tracepoint in a separate section and a 
tracepoint_ptr_t
in a __tracepoints_ptrs section.

Then the other parts of the picture are in kernel/tracepoint.c:

extern tracepoint_ptr_t __start___tracepoints_ptrs[];
extern tracepoint_ptr_t __stop___tracepoints_ptrs[];

and kernel/module.c:find_module_sections()

#ifdef CONFIG_TRACEPOINTS
mod->tracepoints_ptrs = section_objs(info, "__tracepoints_ptrs",
 sizeof(*mod->tracepoints_ptrs),
 >num_tracepoints);
#endif

and the iteration code over kernel and modules in kernel/tracepoint.c.

All you need in addition is in include/asm-generic/vmlinux.lds.h, we add
to the DATA_DATA define an entry such as:

STRUCT_ALIGN(); \
*(__tracepoints)\

and in RO_DATA:

. = ALIGN(8);   \
__start___tracepoints_ptrs = .; \
KEEP(*(__tracepoints_ptrs)) /* Tracepoints: pointer array */ \
__stop___tracepoints_ptrs = .; 

AFAIU, if you do something similar for a structure that contains your relevant
lock information, it should be straightforward to handle statically initialized
locks.

Thanks,

Mathieu


> 
> Thanks,
> Longman

-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com


[Intel-gfx] [PATCH] drm/i915: fix build issue when using clang

2022-02-14 Thread Tong Zhang
drm/i915 target adds some extra cflags, especially it does re-apply -Wall.
In clang this will override -Wno-format-security and cause the build to
fail when CONFIG_DRM_I915_WERROR=y. While with GCC this does not happen.
We reapply -Wno-format-security here to get around this issue.

drivers/gpu/drm/i915/gt/intel_gt.c:983:2: error: format string is not a string 
literal (potentially insecure) [-Werror,-Wformat-security]
GEM_TRACE("ERROR\n");
^~~~
./drivers/gpu/drm/i915/i915_gem.h:76:24: note: expanded from macro 'GEM_TRACE'
 #define GEM_TRACE(...) trace_printk(__VA_ARGS__)
   ^
./include/linux/kernel.h:369:3: note: expanded from macro 'trace_printk'
do_trace_printk(fmt, ##__VA_ARGS__);\
^~~
./include/linux/kernel.h:383:30: note: expanded from macro 'do_trace_printk'
__trace_bprintk(_THIS_IP_, trace_printk_fmt, ##args);   \
   ^~~~
drivers/gpu/drm/i915/gt/intel_gt.c:983:2: note: treat the string as an argument 
to avoid this

Signed-off-by: Tong Zhang 
---
 drivers/gpu/drm/i915/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 1b62b9f65196..c04e05a3d39f 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -13,6 +13,7 @@
 # will most likely get a sudden build breakage... Hopefully we will fix
 # new warnings before CI updates!
 subdir-ccflags-y := -Wall -Wextra
+subdir-ccflags-y += -Wno-format-security
 subdir-ccflags-y += -Wno-unused-parameter
 subdir-ccflags-y += -Wno-type-limits
 subdir-ccflags-y += -Wno-missing-field-initializers
-- 
2.25.1



[Intel-gfx] [PATCH V2 12/13] media: wl128x: use time_is_before_jiffies() instead of jiffies judgment

2022-02-14 Thread Qing Wang
From: Wang Qing 

It is better to use time_xxx() directly instead of jiffies judgment
for understanding.

Signed-off-by: Wang Qing 
---
 drivers/media/radio/wl128x/fmdrv_common.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/media/radio/wl128x/fmdrv_common.c 
b/drivers/media/radio/wl128x/fmdrv_common.c
index 6142484d..a599d08
--- a/drivers/media/radio/wl128x/fmdrv_common.c
+++ b/drivers/media/radio/wl128x/fmdrv_common.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "fmdrv.h"
 #include "fmdrv_v4l2.h"
@@ -342,7 +343,7 @@ static void send_tasklet(struct tasklet_struct *t)
return;
 
/* Check, is there any timeout happened to last transmitted packet */
-   if ((jiffies - fmdev->last_tx_jiffies) > FM_DRV_TX_TIMEOUT) {
+   if (time_is_before_jiffies(fmdev->last_tx_jiffies + FM_DRV_TX_TIMEOUT)) 
{
fmerr("TX timeout occurred\n");
atomic_set(>tx_cnt, 1);
}
-- 
2.7.4



Re: [Intel-gfx] [RFC 00/12] locking: Separate lock tracepoints from lockdep/lock_stat (v1)

2022-02-14 Thread Mathieu Desnoyers
- On Feb 9, 2022, at 1:19 PM, Waiman Long long...@redhat.com wrote:

> On 2/9/22 04:09, Peter Zijlstra wrote:
>> On Tue, Feb 08, 2022 at 10:41:56AM -0800, Namhyung Kim wrote:
>>
>>> Eventually I'm mostly interested in the contended locks only and I
>>> want to reduce the overhead in the fast path.  By moving that, it'd be
>>> easy to track contended locks with timing by using two tracepoints.
>> So why not put in two new tracepoints and call it a day?
>>
>> Why muck about with all that lockdep stuff just to preserve the name
>> (and in the process continue to blow up data structures etc..). This
>> leaves distros in a bind, will they enable this config and provide
>> tracepoints while bloating the data structures and destroying things
>> like lockref (which relies on sizeof(spinlock_t)), or not provide this
>> at all.
>>
>> Yes, the name is convenient, but it's just not worth it IMO. It makes
>> the whole proposition too much of a trade-off.
>>
>> Would it not be possible to reconstruct enough useful information from
>> the lock callsite?
>>
> I second that as I don't want to see the size of a spinlock exceeds 4
> bytes in a production system.
> 
> Instead of storing additional information (e.g. lock name) directly into
> the lock itself. Maybe we can store it elsewhere and use the lock
> address as the key to locate it in a hash table. We can certainly extend
> the various lock init functions to do that. It will be trickier for
> statically initialized locks, but we can probably find a way to do that too.

If we go down that route, it would be nice if we can support a few different
use-cases for various tracers out there.

One use-case (a) requires the ability to query the lock name based on its 
address as key.
For this a hash table is a good fit. This would allow tracers like ftrace to
output lock names in its human-readable output which is formatted within the 
kernel.

Another use-case (b) is to be able to "dump" the lock { name, address } tuples
into the trace stream (we call this statedump events in lttng), and do the
translation from address to name at post-processing. This simply requires
that this information is available for iteration for both the core kernel
and module locks, so the tracer can dump this information on trace start
and module load.

Use-case (b) is very similar to what is done for the kernel tracepoints. Based
on this, implementing the init code that iterates on those sections and 
populates
a hash table for use-case (a) should be easy enough.

Thanks,

Mathieu

-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com


[Intel-gfx] [PATCH V2 2/13] clk: mvebu: use time_is_before_eq_jiffies() instead of jiffies judgment

2022-02-14 Thread Qing Wang
From: Wang Qing 

It is better use time_xxx() directly instead of jiffies judgment
for understanding.

Signed-off-by: Wang Qing 
---
 drivers/clk/mvebu/armada-37xx-periph.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/mvebu/armada-37xx-periph.c 
b/drivers/clk/mvebu/armada-37xx-periph.c
index 32ac6b6..14d73f8
--- a/drivers/clk/mvebu/armada-37xx-periph.c
+++ b/drivers/clk/mvebu/armada-37xx-periph.c
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define TBG_SEL0x0
 #define DIV_SEL0   0x4
@@ -541,7 +542,7 @@ static void clk_pm_cpu_set_rate_wa(struct clk_pm_cpu 
*pm_cpu,
 * We are going to L0 with rate >= 1GHz. Check whether we have been at
 * L1 for long enough time. If not, go to L1 for 20ms.
 */
-   if (pm_cpu->l1_expiration && jiffies >= pm_cpu->l1_expiration)
+   if (pm_cpu->l1_expiration && 
time_is_before_eq_jiffies(pm_cpu->l1_expiration))
goto invalidate_l1_exp;
 
regmap_update_bits(base, ARMADA_37XX_NB_CPU_LOAD,
-- 
2.7.4



[Intel-gfx] [PATCH V2 00/13] use time_is_xxx() instead of jiffies judgment

2022-02-14 Thread Qing Wang
From: Wang Qing 

It is better to use time_is_xxx() directly instead of jiffies judgment
for understanding.

Batch them in a series suggested by Joe.

Wang Qing (14):
  block: xen: use time_is_before_eq_jiffies() instead of jiffies judgment
  clk: mvebu: use time_is_before_eq_jiffies() instead of jiffies judgment
  gpu: drm: i915: use time_is_after_jiffies() instead of jiffies judgment
  gpu: drm: radeon: use time_is_before_jiffies() instead of jiffies judgment
  hid: use time_is_after_jiffies() instead of jiffies judgment
  input: serio: use time_is_before_jiffies() instead of jiffies judgment
  md: use time_is_before_jiffies(() instead of jiffies judgment
  md: use time_is_before_eq_jiffies() instead of jiffies judgment
  media: si21xx: use time_is_before_jiffies() instead of jiffies judgment
  media: stv0299: use time_is_before_jiffies() instead of jiffies judgment
  media: tda8083: use time_is_after_jiffies() instead of jiffies judgment
  media: wl128x: use time_is_before_jiffies() instead of jiffies judgment
  media: vivid: use time_is_after_jiffies() instead of jiffies judgment

 drivers/block/xen-blkback/blkback.c| 5 +++--
 drivers/clk/mvebu/armada-37xx-periph.c | 3 ++-
 drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c | 2 +-
 drivers/gpu/drm/radeon/radeon_pm.c | 3 ++-
 drivers/hid/intel-ish-hid/ipc/ipc.c| 2 +-
 drivers/input/serio/ps2-gpio.c | 4 ++--
 drivers/md/dm-thin.c   | 2 +-
 drivers/md/dm-writecache.c | 5 +++--
 drivers/media/dvb-frontends/si21xx.c   | 2 +-
 drivers/media/dvb-frontends/stv0299.c  | 4 ++--
 drivers/media/dvb-frontends/tda8083.c  | 2 +-
 drivers/media/radio/wl128x/fmdrv_common.c  | 3 ++-
 drivers/media/test-drivers/vivid/vivid-kthread-cap.c   | 3 ++-
 drivers/media/test-drivers/vivid/vivid-kthread-out.c   | 3 ++-
 drivers/media/test-drivers/vivid/vivid-kthread-touch.c | 3 ++-
 drivers/media/test-drivers/vivid/vivid-sdr-cap.c   | 3 ++-
 17 files changed, 31 insertions(+), 22 deletions(-)

-- 
2.7.4



Re: [Intel-gfx] [PATCH 1/2] drm: Add HPD state to drm_connector_oob_hotplug_event()

2022-02-14 Thread Bjorn Andersson
On Tue 08 Feb 02:39 PST 2022, Greg Kroah-Hartman wrote:

> On Mon, Feb 07, 2022 at 08:43:27PM -0800, Bjorn Andersson wrote:
> > In some implementations, such as the Qualcomm platforms, the display
> > driver has no way to query the current HPD state and as such it's
> > impossible to distinguish between disconnect and attention events.
> > 
> > Add a parameter to drm_connector_oob_hotplug_event() to pass the HPD
> > state.
> > 
> > Also push the test for unchanged state in the displayport altmode driver
> > into the i915 driver, to allow other drivers to act upon each update.
> > 
> > Signed-off-by: Bjorn Andersson 
> > ---
> > 
> > Note that the Intel driver has only been compile tested with this patch.
> > 
> >  drivers/gpu/drm/drm_connector.c  |  6 --
> >  drivers/gpu/drm/i915/display/intel_dp.c  | 14 +++---
> >  drivers/gpu/drm/i915/i915_drv.h  |  3 +++
> >  drivers/usb/typec/altmodes/displayport.c |  9 ++---
> >  include/drm/drm_connector.h  |  5 +++--
> >  5 files changed, 23 insertions(+), 14 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_connector.c 
> > b/drivers/gpu/drm/drm_connector.c
> > index a50c82bc2b2f..ad7295597c0f 100644
> > --- a/drivers/gpu/drm/drm_connector.c
> > +++ b/drivers/gpu/drm/drm_connector.c
> > @@ -2825,6 +2825,7 @@ struct drm_connector 
> > *drm_connector_find_by_fwnode(struct fwnode_handle *fwnode)
> >  /**
> >   * drm_connector_oob_hotplug_event - Report out-of-band hotplug event to 
> > connector
> >   * @connector_fwnode: fwnode_handle to report the event on
> > + * @hpd_state: number of data lanes available
> 
> "number"?
> 
> >   *
> >   * On some hardware a hotplug event notification may come from outside the 
> > display
> >   * driver / device. An example of this is some USB Type-C setups where the 
> > hardware
> > @@ -2834,7 +2835,8 @@ struct drm_connector 
> > *drm_connector_find_by_fwnode(struct fwnode_handle *fwnode)
> >   * This function can be used to report these out-of-band events after 
> > obtaining
> >   * a drm_connector reference through calling 
> > drm_connector_find_by_fwnode().
> >   */
> > -void drm_connector_oob_hotplug_event(struct fwnode_handle 
> > *connector_fwnode)
> > +void drm_connector_oob_hotplug_event(struct fwnode_handle 
> > *connector_fwnode,
> > +bool hpd_state)
> 
> This is a boolean, how can it be a number?
> 

The kerneldoc wasn't appropriately updated as this went from being
"number of data lanes" to "the hot plug detect (hpd) state".

> And having a "flag" like this is a pain, how do you know what the
> parameter really means?
> 

You're right, "state" isn't a boolean property, let's rename it
"hpd_high" to clarify it.

> >  {
> > struct drm_connector *connector;
> >  
> > @@ -2843,7 +2845,7 @@ void drm_connector_oob_hotplug_event(struct 
> > fwnode_handle *connector_fwnode)
> > return;
> >  
> > if (connector->funcs->oob_hotplug_event)
> > -   connector->funcs->oob_hotplug_event(connector);
> > +   connector->funcs->oob_hotplug_event(connector, hpd_state);
> >  
> > drm_connector_put(connector);
> >  }
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> > b/drivers/gpu/drm/i915/display/intel_dp.c
> > index 146b83916005..00520867d37b 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > @@ -4816,15 +4816,23 @@ static int intel_dp_connector_atomic_check(struct 
> > drm_connector *conn,
> > return intel_modeset_synced_crtcs(state, conn);
> >  }
> >  
> > -static void intel_dp_oob_hotplug_event(struct drm_connector *connector)
> > +static void intel_dp_oob_hotplug_event(struct drm_connector *connector, 
> > bool hpd_state)
> >  {
> > struct intel_encoder *encoder = 
> > intel_attached_encoder(to_intel_connector(connector));
> > struct drm_i915_private *i915 = to_i915(connector->dev);
> > +   bool need_work = false;
> >  
> > spin_lock_irq(>irq_lock);
> > -   i915->hotplug.event_bits |= BIT(encoder->hpd_pin);
> > +   if (hpd_state != i915->hotplug.oob_hotplug_state) {
> > +   i915->hotplug.event_bits |= BIT(encoder->hpd_pin);
> > +
> > +   i915->hotplug.oob_hotplug_state = hpd_state;
> > +   need_work = true;
> > +   }
> > spin_unlock_irq(>irq_lock);
> > -   queue_delayed_work(system_wq, >hotplug.hotplug_work, 0);
> > +
> > +   if (need_work)
> > +   queue_delayed_work(system_wq, >hotplug.hotplug_work, 0);
> >  }
> >  
> >  static const struct drm_connector_funcs intel_dp_connector_funcs = {
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h 
> > b/drivers/gpu/drm/i915/i915_drv.h
> > index 8c1706fd81f9..543ebf1cfcf4 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -149,6 +149,9 @@ struct i915_hotplug {
> > /* Whether or not to count short HPD IRQs in HPD storms */
> > u8 hpd_short_storm_enabled;
> >  
> > +   /* Last state reported by 

Re: [Intel-gfx] [PATCH 1/2] drm: Add HPD state to drm_connector_oob_hotplug_event()

2022-02-14 Thread Dmitry Baryshkov
On Thu, 10 Feb 2022 at 23:54, Bjorn Andersson
 wrote:
>
> On Tue 08 Feb 02:39 PST 2022, Greg Kroah-Hartman wrote:
>
> > On Mon, Feb 07, 2022 at 08:43:27PM -0800, Bjorn Andersson wrote:
> > > In some implementations, such as the Qualcomm platforms, the display
> > > driver has no way to query the current HPD state and as such it's
> > > impossible to distinguish between disconnect and attention events.
> > >
> > > Add a parameter to drm_connector_oob_hotplug_event() to pass the HPD
> > > state.
> > >
> > > Also push the test for unchanged state in the displayport altmode driver
> > > into the i915 driver, to allow other drivers to act upon each update.
> > >
> > > Signed-off-by: Bjorn Andersson 
> > > ---
> > >
> > > Note that the Intel driver has only been compile tested with this patch.
> > >
> > >  drivers/gpu/drm/drm_connector.c  |  6 --
> > >  drivers/gpu/drm/i915/display/intel_dp.c  | 14 +++---
> > >  drivers/gpu/drm/i915/i915_drv.h  |  3 +++
> > >  drivers/usb/typec/altmodes/displayport.c |  9 ++---
> > >  include/drm/drm_connector.h  |  5 +++--
> > >  5 files changed, 23 insertions(+), 14 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/drm_connector.c 
> > > b/drivers/gpu/drm/drm_connector.c
> > > index a50c82bc2b2f..ad7295597c0f 100644
> > > --- a/drivers/gpu/drm/drm_connector.c
> > > +++ b/drivers/gpu/drm/drm_connector.c
> > > @@ -2825,6 +2825,7 @@ struct drm_connector 
> > > *drm_connector_find_by_fwnode(struct fwnode_handle *fwnode)
> > >  /**
> > >   * drm_connector_oob_hotplug_event - Report out-of-band hotplug event to 
> > > connector
> > >   * @connector_fwnode: fwnode_handle to report the event on
> > > + * @hpd_state: number of data lanes available
> >
> > "number"?
> >
> > >   *
> > >   * On some hardware a hotplug event notification may come from outside 
> > > the display
> > >   * driver / device. An example of this is some USB Type-C setups where 
> > > the hardware
> > > @@ -2834,7 +2835,8 @@ struct drm_connector 
> > > *drm_connector_find_by_fwnode(struct fwnode_handle *fwnode)
> > >   * This function can be used to report these out-of-band events after 
> > > obtaining
> > >   * a drm_connector reference through calling 
> > > drm_connector_find_by_fwnode().
> > >   */
> > > -void drm_connector_oob_hotplug_event(struct fwnode_handle 
> > > *connector_fwnode)
> > > +void drm_connector_oob_hotplug_event(struct fwnode_handle 
> > > *connector_fwnode,
> > > +bool hpd_state)
> >
> > This is a boolean, how can it be a number?
> >
>
> The kerneldoc wasn't appropriately updated as this went from being
> "number of data lanes" to "the hot plug detect (hpd) state".
>
> > And having a "flag" like this is a pain, how do you know what the
> > parameter really means?
> >
>
> You're right, "state" isn't a boolean property, let's rename it
> "hpd_high" to clarify it.

"connected" ?

>
> > >  {
> > > struct drm_connector *connector;
> > >
> > > @@ -2843,7 +2845,7 @@ void drm_connector_oob_hotplug_event(struct 
> > > fwnode_handle *connector_fwnode)
> > > return;
> > >
> > > if (connector->funcs->oob_hotplug_event)
> > > -   connector->funcs->oob_hotplug_event(connector);
> > > +   connector->funcs->oob_hotplug_event(connector, hpd_state);
> > >
> > > drm_connector_put(connector);
> > >  }
> > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> > > b/drivers/gpu/drm/i915/display/intel_dp.c
> > > index 146b83916005..00520867d37b 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > > @@ -4816,15 +4816,23 @@ static int intel_dp_connector_atomic_check(struct 
> > > drm_connector *conn,
> > > return intel_modeset_synced_crtcs(state, conn);
> > >  }
> > >
> > > -static void intel_dp_oob_hotplug_event(struct drm_connector *connector)
> > > +static void intel_dp_oob_hotplug_event(struct drm_connector *connector, 
> > > bool hpd_state)
> > >  {
> > > struct intel_encoder *encoder = 
> > > intel_attached_encoder(to_intel_connector(connector));
> > > struct drm_i915_private *i915 = to_i915(connector->dev);
> > > +   bool need_work = false;
> > >
> > > spin_lock_irq(>irq_lock);
> > > -   i915->hotplug.event_bits |= BIT(encoder->hpd_pin);
> > > +   if (hpd_state != i915->hotplug.oob_hotplug_state) {
> > > +   i915->hotplug.event_bits |= BIT(encoder->hpd_pin);
> > > +
> > > +   i915->hotplug.oob_hotplug_state = hpd_state;
> > > +   need_work = true;
> > > +   }
> > > spin_unlock_irq(>irq_lock);
> > > -   queue_delayed_work(system_wq, >hotplug.hotplug_work, 0);
> > > +
> > > +   if (need_work)
> > > +   queue_delayed_work(system_wq, >hotplug.hotplug_work, 0);
> > >  }
> > >
> > >  static const struct drm_connector_funcs intel_dp_connector_funcs = {
> > > diff --git a/drivers/gpu/drm/i915/i915_drv.h 
> > > b/drivers/gpu/drm/i915/i915_drv.h
> > > index 

[Intel-gfx] [PATCH 18/49] drm/i915/pmu: replace cpumask_weight with cpumask_empty where appropriate

2022-02-14 Thread Yury Norov
i915_pmu_cpu_online() calls cpumask_weight() to check if any bit of a
given cpumask is set. We can do it more efficiently with cpumask_empty()
because cpumask_empty() stops traversing the cpumask as soon as it finds
first set bit, while cpumask_weight() counts all bits unconditionally.

Signed-off-by: Yury Norov 
Reviewed-by: Tvrtko Ursulin 
---
 drivers/gpu/drm/i915/i915_pmu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c
index cfc21042499d..7299ed9937dd 100644
--- a/drivers/gpu/drm/i915/i915_pmu.c
+++ b/drivers/gpu/drm/i915/i915_pmu.c
@@ -1050,7 +1050,7 @@ static int i915_pmu_cpu_online(unsigned int cpu, struct 
hlist_node *node)
GEM_BUG_ON(!pmu->base.event_init);
 
/* Select the first online CPU as a designated reader. */
-   if (!cpumask_weight(_pmu_cpumask))
+   if (cpumask_empty(_pmu_cpumask))
cpumask_set_cpu(cpu, _pmu_cpumask);
 
return 0;
-- 
2.32.0



[Intel-gfx] [PATCH V2 5/13] hid: use time_is_after_jiffies() instead of jiffies judgment

2022-02-14 Thread Qing Wang
From: Wang Qing 

It is better to use time_xxx() directly instead of jiffies judgment
for understanding.

Signed-off-by: Wang Qing 
---
 drivers/hid/intel-ish-hid/ipc/ipc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hid/intel-ish-hid/ipc/ipc.c 
b/drivers/hid/intel-ish-hid/ipc/ipc.c
index 8ccb246..15e1423
--- a/drivers/hid/intel-ish-hid/ipc/ipc.c
+++ b/drivers/hid/intel-ish-hid/ipc/ipc.c
@@ -578,7 +578,7 @@ static void _ish_sync_fw_clock(struct ishtp_device *dev)
static unsigned longprev_sync;
uint64_tusec;
 
-   if (prev_sync && jiffies - prev_sync < 20 * HZ)
+   if (prev_sync && time_is_after_jiffies(prev_sync + 20 * HZ))
return;
 
prev_sync = jiffies;
-- 
2.7.4



Re: [Intel-gfx] [PATCH v12 1/5] drm: improve drm_buddy_alloc function

2022-02-14 Thread Christian König




Am 14.02.22 um 09:36 schrieb Matthew Auld:

On Mon, 14 Feb 2022 at 06:32, Christian König
 wrote:

Am 13.02.22 um 09:52 schrieb Arunpravin:

- Make drm_buddy_alloc a single function to handle
range allocation and non-range allocation demands

- Implemented a new function alloc_range() which allocates
the requested power-of-two block comply with range limitations

- Moved order computation and memory alignment logic from
i915 driver to drm buddy

v2:
merged below changes to keep the build unbroken
 - drm_buddy_alloc_range() becomes obsolete and may be removed
 - enable ttm range allocation (fpfn / lpfn) support in i915 driver
 - apply enhanced drm_buddy_alloc() function to i915 driver

v3(Matthew Auld):
- Fix alignment issues and remove unnecessary list_empty check
- add more validation checks for input arguments
- make alloc_range() block allocations as bottom-up
- optimize order computation logic
- replace uint64_t with u64, which is preferred in the kernel

v4(Matthew Auld):
- keep drm_buddy_alloc_range() function implementation for generic
  actual range allocations
- keep alloc_range() implementation for end bias allocations

v5(Matthew Auld):
- modify drm_buddy_alloc() passing argument place->lpfn to lpfn
  as place->lpfn will currently always be zero for i915

v6(Matthew Auld):
- fixup potential uaf - If we are unlucky and can't allocate
  enough memory when splitting blocks, where we temporarily
  end up with the given block and its buddy on the respective
  free list, then we need to ensure we delete both blocks,
  and no just the buddy, before potentially freeing them

- fix warnings reported by kernel test robot 

v7(Matthew Auld):
- revert fixup potential uaf
- keep __alloc_range() add node to the list logic same as
  drm_buddy_alloc_blocks() by having a temporary list variable
- at drm_buddy_alloc_blocks() keep i915 range_overflows macro
  and add a new check for end variable

v8:
- fix warnings reported by kernel test robot 

v9(Matthew Auld):
- remove DRM_BUDDY_RANGE_ALLOCATION flag
- remove unnecessary function description

Signed-off-by: Arunpravin 
Reviewed-by: Matthew Auld 

As long as nobody objects I'm going to push patches 1-3 to drm-misc-next
in the next hour or so:

As part of this could you also push
https://patchwork.freedesktop.org/series/99842/ ?


Sure, but Arun said in our internal chat that I should wait with that 
anyway since he wanted to sort out one more issue.


Christian.




Then going to take a deeper look into patches 4 and 5 to get them reviewed.

Thanks,
Christian.


---
   drivers/gpu/drm/drm_buddy.c   | 292 +-
   drivers/gpu/drm/i915/i915_ttm_buddy_manager.c |  63 ++--
   drivers/gpu/drm/i915/i915_ttm_buddy_manager.h |   2 +
   include/drm/drm_buddy.h   |  11 +-
   4 files changed, 250 insertions(+), 118 deletions(-)

diff --git a/drivers/gpu/drm/drm_buddy.c b/drivers/gpu/drm/drm_buddy.c
index d60878bc9c20..e0c0d786a572 100644
--- a/drivers/gpu/drm/drm_buddy.c
+++ b/drivers/gpu/drm/drm_buddy.c
@@ -282,23 +282,97 @@ void drm_buddy_free_list(struct drm_buddy *mm, struct 
list_head *objects)
   }
   EXPORT_SYMBOL(drm_buddy_free_list);

-/**
- * drm_buddy_alloc_blocks - allocate power-of-two blocks
- *
- * @mm: DRM buddy manager to allocate from
- * @order: size of the allocation
- *
- * The order value here translates to:
- *
- * 0 = 2^0 * mm->chunk_size
- * 1 = 2^1 * mm->chunk_size
- * 2 = 2^2 * mm->chunk_size
- *
- * Returns:
- * allocated ptr to the _buddy_block on success
- */
-struct drm_buddy_block *
-drm_buddy_alloc_blocks(struct drm_buddy *mm, unsigned int order)
+static inline bool overlaps(u64 s1, u64 e1, u64 s2, u64 e2)
+{
+ return s1 <= e2 && e1 >= s2;
+}
+
+static inline bool contains(u64 s1, u64 e1, u64 s2, u64 e2)
+{
+ return s1 <= s2 && e1 >= e2;
+}
+
+static struct drm_buddy_block *
+alloc_range_bias(struct drm_buddy *mm,
+  u64 start, u64 end,
+  unsigned int order)
+{
+ struct drm_buddy_block *block;
+ struct drm_buddy_block *buddy;
+ LIST_HEAD(dfs);
+ int err;
+ int i;
+
+ end = end - 1;
+
+ for (i = 0; i < mm->n_roots; ++i)
+ list_add_tail(>roots[i]->tmp_link, );
+
+ do {
+ u64 block_start;
+ u64 block_end;
+
+ block = list_first_entry_or_null(,
+  struct drm_buddy_block,
+  tmp_link);
+ if (!block)
+ break;
+
+ list_del(>tmp_link);
+
+ if (drm_buddy_block_order(block) < order)
+ continue;
+
+ block_start = drm_buddy_block_offset(block);
+ block_end = block_start + drm_buddy_block_size(mm, block) - 1;
+
+ if (!overlaps(start, end, block_start, block_end))
+   

[Intel-gfx] [PATCH V2 3/13] gpu: drm: i915: use time_is_after_jiffies() instead of jiffies judgment

2022-02-14 Thread Qing Wang
From: Wang Qing 

It is better use time_xxx() directly instead of jiffies judgment
for understanding.

Signed-off-by: Wang Qing 
---
 drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c 
b/drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c
index 9db3dcb..b289abb
--- a/drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c
@@ -56,7 +56,7 @@ static bool pool_free_older_than(struct intel_gt_buffer_pool 
*pool, long keep)
node = list_entry(pos, typeof(*node), link);
 
age = READ_ONCE(node->age);
-   if (!age || jiffies - age < keep)
+   if (!age || time_is_after_jiffies(age + keep))
break;
 
/* Check we are the first to claim this node */
-- 
2.7.4



[Intel-gfx] [PATCH] gpu: drm: i915: use time_after_eq() instead of jiffies judgment

2022-02-14 Thread Qing Wang
From: Wang Qing 

It is better use time_xxx() directly instead of jiffies judgment
for understanding.

Signed-off-by: Wang Qing 
---
 drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c 
b/drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c
index 9db3dcb..b289abb
--- a/drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c
@@ -56,7 +56,7 @@ static bool pool_free_older_than(struct intel_gt_buffer_pool 
*pool, long keep)
node = list_entry(pos, typeof(*node), link);
 
age = READ_ONCE(node->age);
-   if (!age || jiffies - age < keep)
+   if (!age || time_before(jiffies, age + keep))
break;
 
/* Check we are the first to claim this node */
-- 
2.7.4



Re: [Intel-gfx] [RFC 00/12] locking: Separate lock tracepoints from lockdep/lock_stat (v1)

2022-02-14 Thread Mathieu Desnoyers
- On Feb 9, 2022, at 2:22 PM, Namhyung Kim namhy...@kernel.org wrote:

> Hello,
> 
> On Wed, Feb 9, 2022 at 11:02 AM Waiman Long  wrote:
>>
>> On 2/9/22 13:29, Mathieu Desnoyers wrote:
>> > - On Feb 9, 2022, at 1:19 PM, Waiman Long long...@redhat.com wrote:
>> >
>> >> On 2/9/22 04:09, Peter Zijlstra wrote:
>> >>> On Tue, Feb 08, 2022 at 10:41:56AM -0800, Namhyung Kim wrote:
>> >>>
>>  Eventually I'm mostly interested in the contended locks only and I
>>  want to reduce the overhead in the fast path.  By moving that, it'd be
>>  easy to track contended locks with timing by using two tracepoints.
>> >>> So why not put in two new tracepoints and call it a day?
>> >>>
>> >>> Why muck about with all that lockdep stuff just to preserve the name
>> >>> (and in the process continue to blow up data structures etc..). This
>> >>> leaves distros in a bind, will they enable this config and provide
>> >>> tracepoints while bloating the data structures and destroying things
>> >>> like lockref (which relies on sizeof(spinlock_t)), or not provide this
>> >>> at all.
>> >>>
>> >>> Yes, the name is convenient, but it's just not worth it IMO. It makes
>> >>> the whole proposition too much of a trade-off.
>> >>>
>> >>> Would it not be possible to reconstruct enough useful information from
>> >>> the lock callsite?
>> >>>
>> >> I second that as I don't want to see the size of a spinlock exceeds 4
>> >> bytes in a production system.
>> >>
>> >> Instead of storing additional information (e.g. lock name) directly into
>> >> the lock itself. Maybe we can store it elsewhere and use the lock
>> >> address as the key to locate it in a hash table. We can certainly extend
>> >> the various lock init functions to do that. It will be trickier for
>> >> statically initialized locks, but we can probably find a way to do that 
>> >> too.
>> > If we go down that route, it would be nice if we can support a few 
>> > different
>> > use-cases for various tracers out there.
>> >
>> > One use-case (a) requires the ability to query the lock name based on its
>> > address as key.
>> > For this a hash table is a good fit. This would allow tracers like ftrace 
>> > to
>> > output lock names in its human-readable output which is formatted within 
>> > the
>> > kernel.
>> >
>> > Another use-case (b) is to be able to "dump" the lock { name, address } 
>> > tuples
>> > into the trace stream (we call this statedump events in lttng), and do the
>> > translation from address to name at post-processing. This simply requires
>> > that this information is available for iteration for both the core kernel
>> > and module locks, so the tracer can dump this information on trace start
>> > and module load.
>> >
>> > Use-case (b) is very similar to what is done for the kernel tracepoints. 
>> > Based
>> > on this, implementing the init code that iterates on those sections and
>> > populates
>> > a hash table for use-case (a) should be easy enough.
>>
>> Yes, that are good use cases for this type of functionality. I do need
>> to think about how to do it for statically initialized lock first.
> 
> Thank you all for the review and good suggestions.
> 
> I'm also concerning dynamic allocated locks in a data structure.
> If we keep the info in a hash table, we should delete it when the
> lock is gone.  I'm not sure we have a good place to hook it up all.

I was wondering about this use case as well. Can we make it mandatory to
declare the lock "class" (including the name) statically, even though the
lock per-se is allocated dynamically ? Then the initialization of the lock
embedded within the data structure would simply refer to the lock class
definition.

But perhaps I am missing something here.

Thanks,

Mathieu


-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com


Re: [Intel-gfx] [PATCH 2/2] drm/msm/dp: Implement oob_hotplug_event()

2022-02-14 Thread Bjorn Andersson
On Mon 07 Feb 23:40 PST 2022, Greg Kroah-Hartman wrote:

> On Mon, Feb 07, 2022 at 08:43:28PM -0800, Bjorn Andersson wrote:
> > The Qualcomm DisplayPort driver contains traces of the necessary
> > plumbing to hook up USB HPD, in the form of the dp_hpd module and the
> > dp_usbpd_cb struct. Use this as basis for implementing the
> > oob_hotplug_event() callback, by amending the dp_hpd module with the
> > missing logic.
> > 
> > Overall the solution is similar to what's done downstream, but upstream
> > all the code to disect the HPD notification lives on the calling side of
> > drm_connector_oob_hotplug_event().
> > 
> > drm_connector_oob_hotplug_event() performs the lookup of the
> > drm_connector based on fwnode, hence the need to assign the fwnode in
> > dp_drm_connector_init().
> > 
> > Signed-off-by: Bjorn Andersson 
> > ---
> >  drivers/gpu/drm/msm/dp/dp_display.c |  8 
> >  drivers/gpu/drm/msm/dp/dp_display.h |  2 ++
> >  drivers/gpu/drm/msm/dp/dp_drm.c | 10 ++
> >  drivers/gpu/drm/msm/dp/dp_hpd.c | 19 +++
> >  drivers/gpu/drm/msm/dp/dp_hpd.h |  4 
> >  5 files changed, 43 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
> > b/drivers/gpu/drm/msm/dp/dp_display.c
> > index 7cc4d21f2091..124a2f794382 100644
> > --- a/drivers/gpu/drm/msm/dp/dp_display.c
> > +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> > @@ -414,6 +414,13 @@ static int dp_display_usbpd_configure_cb(struct device 
> > *dev)
> > return dp_display_process_hpd_high(dp);
> >  }
> >  
> > +void dp_display_oob_hotplug_event(struct msm_dp *dp_display, bool 
> > hpd_state)
> > +{
> > +   struct dp_display_private *dp = container_of(dp_display, struct 
> > dp_display_private, dp_display);
> > +
> > +   dp->usbpd->oob_event(dp->usbpd, hpd_state);
> > +}
> > +
> >  static int dp_display_usbpd_disconnect_cb(struct device *dev)
> >  {
> > struct dp_display_private *dp = dev_get_dp_display_private(dev);
> > @@ -1251,6 +1258,7 @@ static int dp_display_probe(struct platform_device 
> > *pdev)
> > dp->pdev = pdev;
> > dp->name = "drm_dp";
> > dp->dp_display.connector_type = desc->connector_type;
> > +   dp->dp_display.dev = >dev;
> 
> You did not properly reference count this pointer you just saved.  What
> is to keep that pointer from going away without you knowing about it?
> 

The "dp" object only lives while >dev is alive, both logically and
as its devres allocated on  So for this reference I don't see
that we should refcount it.

> And you already have a pointer to pdev, why save another one here?
> 

The Qualcomm DisplayPort driver has per-c-file private context structs
and "dp" is one such object. So I simply can't dereference it and get to
pdev from the other c-file in the same driver...

But I only need it in dp_drm.c to during initialization to get a
reference to the associated fwnode, so it seems that I can rework this
and pass the pointer as a parameter to dp_drm_connector_init().

That looks to be cleaner as well.

Thanks,
Bjorn


[Intel-gfx] [PATCH V2 6/13] input: serio: use time_is_before_jiffies() instead of jiffies judgment

2022-02-14 Thread Qing Wang
From: Wang Qing 

It is better to use time_xxx() directly instead of jiffies judgment
for understanding.

Signed-off-by: Wang Qing 
---
 drivers/input/serio/ps2-gpio.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/input/serio/ps2-gpio.c b/drivers/input/serio/ps2-gpio.c
index 8970b49..7834296
--- a/drivers/input/serio/ps2-gpio.c
+++ b/drivers/input/serio/ps2-gpio.c
@@ -136,7 +136,7 @@ static irqreturn_t ps2_gpio_irq_rx(struct ps2_gpio_data 
*drvdata)
if (old_jiffies == 0)
old_jiffies = jiffies;
 
-   if ((jiffies - old_jiffies) > usecs_to_jiffies(100)) {
+   if (time_is_before_jiffies(old_jiffies + usecs_to_jiffies(100))) {
dev_err(drvdata->dev,
"RX: timeout, probably we missed an interrupt\n");
goto err;
@@ -237,7 +237,7 @@ static irqreturn_t ps2_gpio_irq_tx(struct ps2_gpio_data 
*drvdata)
if (old_jiffies == 0)
old_jiffies = jiffies;
 
-   if ((jiffies - old_jiffies) > usecs_to_jiffies(100)) {
+   if (time_is_before_jiffies(old_jiffies + usecs_to_jiffies(100))) {
dev_err(drvdata->dev,
"TX: timeout, probably we missed an interrupt\n");
goto err;
-- 
2.7.4



[Intel-gfx] [PATCH V2 11/13] media: tda8083: use time_is_after_jiffies() instead of jiffies judgment

2022-02-14 Thread Qing Wang
From: Wang Qing 

It is better to use time_xxx() directly instead of jiffies judgment
for understanding.

Signed-off-by: Wang Qing 
---
 drivers/media/dvb-frontends/tda8083.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/dvb-frontends/tda8083.c 
b/drivers/media/dvb-frontends/tda8083.c
index 5be11fd..49c4fe1
--- a/drivers/media/dvb-frontends/tda8083.c
+++ b/drivers/media/dvb-frontends/tda8083.c
@@ -162,7 +162,7 @@ static void tda8083_wait_diseqc_fifo (struct tda8083_state* 
state, int timeout)
 {
unsigned long start = jiffies;
 
-   while (jiffies - start < timeout &&
+   while (time_is_after_jiffies(start + timeout) &&
   !(tda8083_readreg(state, 0x02) & 0x80))
{
msleep(50);
-- 
2.7.4



[Intel-gfx] [PATCH V2 13/13] media: vivid: use time_is_after_jiffies() instead of jiffies judgment

2022-02-14 Thread Qing Wang
From: Wang Qing 

It is better to use time_xxx() directly instead of jiffies judgment
for understanding.

Signed-off-by: Wang Qing 
---
 drivers/media/test-drivers/vivid/vivid-kthread-cap.c   | 3 ++-
 drivers/media/test-drivers/vivid/vivid-kthread-out.c   | 3 ++-
 drivers/media/test-drivers/vivid/vivid-kthread-touch.c | 3 ++-
 drivers/media/test-drivers/vivid/vivid-sdr-cap.c   | 3 ++-
 4 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/media/test-drivers/vivid/vivid-kthread-cap.c 
b/drivers/media/test-drivers/vivid/vivid-kthread-cap.c
index 6baa046..295f4a3
--- a/drivers/media/test-drivers/vivid/vivid-kthread-cap.c
+++ b/drivers/media/test-drivers/vivid/vivid-kthread-cap.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -893,7 +894,7 @@ static int vivid_thread_vid_cap(void *data)
next_jiffies_since_start = jiffies_since_start;
 
wait_jiffies = next_jiffies_since_start - jiffies_since_start;
-   while (jiffies - cur_jiffies < wait_jiffies &&
+   while (time_is_after_jiffies(cur_jiffies + wait_jiffies) &&
   !kthread_should_stop())
schedule();
}
diff --git a/drivers/media/test-drivers/vivid/vivid-kthread-out.c 
b/drivers/media/test-drivers/vivid/vivid-kthread-out.c
index b6d4316..13f737e
--- a/drivers/media/test-drivers/vivid/vivid-kthread-out.c
+++ b/drivers/media/test-drivers/vivid/vivid-kthread-out.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -234,7 +235,7 @@ static int vivid_thread_vid_out(void *data)
next_jiffies_since_start = jiffies_since_start;
 
wait_jiffies = next_jiffies_since_start - jiffies_since_start;
-   while (jiffies - cur_jiffies < wait_jiffies &&
+   while (time_is_after_jiffies(cur_jiffies + wait_jiffies) &&
   !kthread_should_stop())
schedule();
}
diff --git a/drivers/media/test-drivers/vivid/vivid-kthread-touch.c 
b/drivers/media/test-drivers/vivid/vivid-kthread-touch.c
index f065faae..8828243
--- a/drivers/media/test-drivers/vivid/vivid-kthread-touch.c
+++ b/drivers/media/test-drivers/vivid/vivid-kthread-touch.c
@@ -5,6 +5,7 @@
  */
 
 #include 
+#include 
 #include "vivid-core.h"
 #include "vivid-kthread-touch.h"
 #include "vivid-touch-cap.h"
@@ -134,7 +135,7 @@ static int vivid_thread_touch_cap(void *data)
next_jiffies_since_start = jiffies_since_start;
 
wait_jiffies = next_jiffies_since_start - jiffies_since_start;
-   while (jiffies - cur_jiffies < wait_jiffies &&
+   while (time_is_after_jiffies(cur_jiffies + wait_jiffies) &&
   !kthread_should_stop())
schedule();
}
diff --git a/drivers/media/test-drivers/vivid/vivid-sdr-cap.c 
b/drivers/media/test-drivers/vivid/vivid-sdr-cap.c
index 59fd508..f82856b
--- a/drivers/media/test-drivers/vivid/vivid-sdr-cap.c
+++ b/drivers/media/test-drivers/vivid/vivid-sdr-cap.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "vivid-core.h"
 #include "vivid-ctrls.h"
@@ -205,7 +206,7 @@ static int vivid_thread_sdr_cap(void *data)
next_jiffies_since_start = jiffies_since_start;
 
wait_jiffies = next_jiffies_since_start - jiffies_since_start;
-   while (jiffies - cur_jiffies < wait_jiffies &&
+   while (time_is_after_jiffies(cur_jiffies + wait_jiffies) &&
   !kthread_should_stop())
schedule();
}
-- 
2.7.4



[Intel-gfx] [PATCH V2 9/13] media: si21xx: use time_is_before_jiffies() instead of jiffies judgment

2022-02-14 Thread Qing Wang
From: Wang Qing 

It is better to use time_xxx() directly instead of jiffies judgment
for understanding.

Signed-off-by: Wang Qing 
---
 drivers/media/dvb-frontends/si21xx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/dvb-frontends/si21xx.c 
b/drivers/media/dvb-frontends/si21xx.c
index 001b235..1c6cf76
--- a/drivers/media/dvb-frontends/si21xx.c
+++ b/drivers/media/dvb-frontends/si21xx.c
@@ -336,7 +336,7 @@ static int si21xx_wait_diseqc_idle(struct si21xx_state 
*state, int timeout)
dprintk("%s\n", __func__);
 
while ((si21_readreg(state, LNB_CTRL_REG_1) & 0x8) == 8) {
-   if (jiffies - start > timeout) {
+   if (time_is_before_jiffies(start + timeout)) {
dprintk("%s: timeout!!\n", __func__);
return -ETIMEDOUT;
}
-- 
2.7.4



Re: [Intel-gfx] [RFC 00/12] locking: Separate lock tracepoints from lockdep/lock_stat (v1)

2022-02-14 Thread Mathieu Desnoyers
- On Feb 9, 2022, at 2:45 PM, Namhyung Kim namhy...@kernel.org wrote:

> On Wed, Feb 9, 2022 at 11:28 AM Mathieu Desnoyers
>  wrote:
>>
>> - On Feb 9, 2022, at 2:22 PM, Namhyung Kim namhy...@kernel.org wrote:
>> > I'm also concerning dynamic allocated locks in a data structure.
>> > If we keep the info in a hash table, we should delete it when the
>> > lock is gone.  I'm not sure we have a good place to hook it up all.
>>
>> I was wondering about this use case as well. Can we make it mandatory to
>> declare the lock "class" (including the name) statically, even though the
>> lock per-se is allocated dynamically ? Then the initialization of the lock
>> embedded within the data structure would simply refer to the lock class
>> definition.
> 
> Isn't it still the same if we have static lock classes that the entry needs
> to be deleted from the hash table when it frees the data structure?
> I'm more concerned about free than alloc as there seems to be no
> API to track that in a place.

If the lock class is defined statically, even for dynamically initialized
locks, then its associated object sits either in the core kernel or within
a module.

So if it's in the core kernel, it could be added to the hash table at kernel
init and stay there forever.

If it's in a module, it would be added to the hash table on module load and
removed on module unload. We would have to be careful about how the ftrace
printout to human readable text deals with missing hash table data, because
that printout will happen after buffering, so an untimely module unload could
make this address to string mapping unavailable for a few events. If we care
about getting this corner case right there are a few things we could do as
well.

Thanks,

Mathieu

-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com


Re: [Intel-gfx] [PATCH v4 14/14] drm/msm: Implement HDCP 1.x using the new drm HDCP helpers

2022-02-14 Thread Dmitry Baryshkov

On 05/11/2021 06:04, Sean Paul wrote:

From: Sean Paul 

This patch adds HDCP 1.x support to msm DP connectors using the new HDCP
helpers.


Sean, is this something that you'd like to pursue further?
We have picked up patches 8-11, which were independent from the rest of 
the changes. The rest seems to have dependencies on core changes (which 
were not acked)




Cc: Stephen Boyd 
Cc: Abhinav Kumar 
Signed-off-by: Sean Paul 
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-15-s...@poorly.run
 #v1
Link: 
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-14-s...@poorly.run
 #v2
Link: 
https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-15-s...@poorly.run
 #v3

Changes in v2:
-Squash [1] into this patch with the following changes (Stephen)
   -Update the sc7180 dtsi file
   -Remove resource names and just use index (Stephen)
Changes in v3:
-Split out the dtsi change from v2 (Stephen)
-Fix set-but-unused warning identified by 0-day
-Fix up a couple of style nits (Stephen)
-Store HDCP key directly in dp_hdcp struct (Stephen)
-Remove wmb in HDCP key initialization, move an_seed (Stephen)
-Use FIELD_PREP for bstatus/bcaps (Stephen)
-#define read_poll_timeout values (Stephen)
-Remove unnecessary parentheses in dp_hdcp_store_ksv_fifo (Stephen)
-Add compatible string for hdcp (Stephen)
-Rename dp_hdcp_write_* functions (Abhinav)
-Add 1us delay between An reads (Abhinav)
-Delete unused dp_hdcp_read_* functions
Changes in v4:
-Rebase on Bjorn's multi-dp patchset

[1] 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-14-s...@poorly.run
---
  drivers/gpu/drm/msm/Makefile|   1 +
  drivers/gpu/drm/msm/dp/dp_debug.c   |  46 ++-
  drivers/gpu/drm/msm/dp/dp_debug.h   |   6 +-
  drivers/gpu/drm/msm/dp/dp_display.c |  46 ++-
  drivers/gpu/drm/msm/dp/dp_display.h |   5 +
  drivers/gpu/drm/msm/dp/dp_drm.c |  68 +++-
  drivers/gpu/drm/msm/dp/dp_drm.h |   5 +
  drivers/gpu/drm/msm/dp/dp_hdcp.c| 462 
  drivers/gpu/drm/msm/dp/dp_hdcp.h|  27 ++
  drivers/gpu/drm/msm/dp/dp_parser.c  |  20 +-
  drivers/gpu/drm/msm/dp/dp_parser.h  |   4 +
  drivers/gpu/drm/msm/dp/dp_reg.h |  32 +-
  drivers/gpu/drm/msm/msm_atomic.c|  15 +
  13 files changed, 729 insertions(+), 8 deletions(-)
  create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.c
  create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.h

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 40577f8856d8..fb3411a74e61 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -108,6 +108,7 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \
dp/dp_ctrl.o \
dp/dp_display.o \
dp/dp_drm.o \
+   dp/dp_hdcp.o \
dp/dp_hpd.o \
dp/dp_link.o \
dp/dp_panel.o \
diff --git a/drivers/gpu/drm/msm/dp/dp_debug.c 
b/drivers/gpu/drm/msm/dp/dp_debug.c
index da4323556ef3..c16fce17d096 100644
--- a/drivers/gpu/drm/msm/dp/dp_debug.c
+++ b/drivers/gpu/drm/msm/dp/dp_debug.c
@@ -8,6 +8,7 @@
  #include 
  #include 
  #include 
+#include 
  
  #include "dp_parser.h"

  #include "dp_catalog.h"
@@ -15,6 +16,7 @@
  #include "dp_ctrl.h"
  #include "dp_debug.h"
  #include "dp_display.h"
+#include "dp_hdcp.h"
  
  #define DEBUG_NAME "msm_dp"
  
@@ -25,6 +27,7 @@ struct dp_debug_private {

struct dp_link *link;
struct dp_panel *panel;
struct drm_connector *connector;
+   struct dp_hdcp *hdcp;
struct device *dev;
struct drm_device *drm_dev;
  
@@ -198,6 +201,35 @@ static int dp_test_active_open(struct inode *inode,

inode->i_private);
  }
  
+static ssize_t dp_hdcp_key_write(struct file *file, const char __user *ubuf,

+size_t len, loff_t *offp)
+{
+   char *input_buffer;
+   int ret;
+   struct dp_debug_private *debug = file->private_data;
+
+   if (len != (DRM_HDCP_KSV_LEN + DP_HDCP_NUM_KEYS * DP_HDCP_KEY_LEN))
+   return -EINVAL;
+
+   if (!debug->hdcp)
+   return -ENOENT;
+
+   input_buffer = memdup_user_nul(ubuf, len);
+   if (IS_ERR(input_buffer))
+   return PTR_ERR(input_buffer);
+
+   ret = dp_hdcp_ingest_key(debug->hdcp, input_buffer, len);
+
+   kfree(input_buffer);
+   if (ret < 0) {
+   DRM_ERROR("Could not ingest HDCP key, ret=%d\n", ret);
+   return ret;
+   }
+
+   *offp += len;
+   return len;
+}
+
  static const struct file_operations test_active_fops = {
.owner = THIS_MODULE,
.open = dp_test_active_open,
@@ -207,6 +239,12 @@ static const struct file_operations test_active_fops = {
.write = dp_test_active_write
  };
  
+static const struct file_operations dp_hdcp_key_fops = {

+   .owner = THIS_MODULE,
+   .open = simple_open,
+   .write = dp_hdcp_key_write,
+};
+
  static int dp_debug_init(struct dp_debug *dp_debug, struct drm_minor *minor)
  {
  

[Intel-gfx] [PATCH V2 7/13] md: use time_is_before_jiffies(() instead of jiffies judgment

2022-02-14 Thread Qing Wang
From: Wang Qing 

It is better to use time_xxx() directly instead of jiffies judgment
for understanding.

Signed-off-by: Wang Qing 
---
 drivers/md/dm-thin.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
index f4234d6..dced764
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -161,7 +161,7 @@ static void throttle_work_start(struct throttle *t)
 
 static void throttle_work_update(struct throttle *t)
 {
-   if (!t->throttle_applied && jiffies > t->threshold) {
+   if (!t->throttle_applied && time_is_before_jiffies(t->threshold)) {
down_write(>lock);
t->throttle_applied = true;
}
-- 
2.7.4



Re: [Intel-gfx] [PATCH] drm/i915: fix build issue when using clang

2022-02-14 Thread Nathan Chancellor
On Sat, Feb 12, 2022 at 10:51:06PM -0800, Tong Zhang wrote:
> drm/i915 target adds some extra cflags, especially it does re-apply -Wall.
> In clang this will override -Wno-format-security and cause the build to
> fail when CONFIG_DRM_I915_WERROR=y. While with GCC this does not happen.
> We reapply -Wno-format-security here to get around this issue.

For what it's worth, GCC would warn in the exact same way if
-Wformat-security was included within -Wall like it is for clang:

drivers/gpu/drm/i915/gt/intel_gt.c: In function ‘intel_gt_invalidate_tlbs’:
drivers/gpu/drm/i915/gt/intel_gt.c:988:9: error: format not a string literal 
and no format arguments [-Werror=format-security]
  988 | GEM_TRACE("\n");
  | ^
cc1: all warnings being treated as errors

drivers/gpu/drm/i915/gt/selftest_execlists.c: In function ‘live_sanitycheck’:
drivers/gpu/drm/i915/gt/selftest_execlists.c:142:25: error: format not a string 
literal and no format arguments [-Werror=format-security]
  142 | GEM_TRACE("spinner failed to start\n");
  | ^
drivers/gpu/drm/i915/gt/selftest_execlists.c: In function ‘live_preempt’:
drivers/gpu/drm/i915/gt/selftest_execlists.c:1775:25: error: format not a 
string literal and no format arguments [-Werror=format-security]
 1775 | GEM_TRACE("lo spinner failed to start\n");
  | ^
drivers/gpu/drm/i915/gt/selftest_execlists.c:1792:25: error: format not a 
string literal and no format arguments [-Werror=format-security]
 1792 | GEM_TRACE("hi spinner failed to start\n");
  | ^
cc1: all warnings being treated as errors

If fixing these warnings instead of just disabling the warning is
undesirable (since I feel like the entire point of the i195 cflags
situation is to enable more warnings than the main Makefile), I think
the commit message should be rewritten to something along the lines of:

"drm/i915 adds some extra cflags, namely -Wall, which causes
instances of -Wformat-security to appear when building with clang, even
though this warning is turned off kernel-wide in the main Makefile:"

> drivers/gpu/drm/i915/gt/intel_gt.c:983:2: error: format string is not a 
> string literal (potentially insecure) [-Werror,-Wformat-security]
> GEM_TRACE("ERROR\n");
> ^~~~
> ./drivers/gpu/drm/i915/i915_gem.h:76:24: note: expanded from macro 'GEM_TRACE'
>  #define GEM_TRACE(...) trace_printk(__VA_ARGS__)
>^
> ./include/linux/kernel.h:369:3: note: expanded from macro 'trace_printk'
> do_trace_printk(fmt, ##__VA_ARGS__);\
> ^~~
> ./include/linux/kernel.h:383:30: note: expanded from macro 'do_trace_printk'
> __trace_bprintk(_THIS_IP_, trace_printk_fmt, ##args);   \
>^~~~
> drivers/gpu/drm/i915/gt/intel_gt.c:983:2: note: treat the string as an 
> argument to avoid this

"This does not happen with GCC because it does not enable
-Wformat-security with -Wall. Disable -Wformat-security within the i915
Makefile so that these warnings do not show up with clang."

The actual diff itself looks fine to me.

Cheers,
Nathan

> Signed-off-by: Tong Zhang 
> ---
>  drivers/gpu/drm/i915/Makefile | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 1b62b9f65196..c04e05a3d39f 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -13,6 +13,7 @@
>  # will most likely get a sudden build breakage... Hopefully we will fix
>  # new warnings before CI updates!
>  subdir-ccflags-y := -Wall -Wextra
> +subdir-ccflags-y += -Wno-format-security
>  subdir-ccflags-y += -Wno-unused-parameter
>  subdir-ccflags-y += -Wno-type-limits
>  subdir-ccflags-y += -Wno-missing-field-initializers
> -- 
> 2.25.1
> 


Re: [Intel-gfx] [PATCH V2 00/13] use time_is_xxx() instead of jiffies judgment

2022-02-14 Thread 王擎
 
>>On Thu, Feb 10, 2022 at 06:30:23PM -0800, Qing Wang wrote:
>> From: Wang Qing 
>> 
>> It is better to use time_is_xxx() directly instead of jiffies judgment
>> for understanding.
>
>Hi Wang,
>
>"judgement" doesn't really make sense as a description to an English
>speaker.  The following a commit desription (for all of these series)
>is probably going to be a bit more understable:
>
>Use the helper function time_is_{before,after}_jiffies() to improve
>code readability.
>
>Cheers,
>
>   - Ted

I see, it will be corrected in V3.
I'll wait a few days if there are any other disagreements.

Thanks,
Qing

[Intel-gfx] [PATCH V2 10/13] md: use time_is_before_eq_jiffies() instead of jiffies judgment

2022-02-14 Thread Qing Wang
From: Wang Qing 

It is better to use time_xxx() directly instead of jiffies judgment
for understanding.

Signed-off-by: Wang Qing 
---
 drivers/md/dm-writecache.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c
index 5630b47..125bb5d
--- a/drivers/md/dm-writecache.c
+++ b/drivers/md/dm-writecache.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "dm-io-tracker.h"
 
 #define DM_MSG_PREFIX "writecache"
@@ -1971,8 +1972,8 @@ static void writecache_writeback(struct work_struct *work)
while (!list_empty(>lru) &&
   (wc->writeback_all ||
wc->freelist_size + wc->writeback_size <= 
wc->freelist_low_watermark ||
-   (jiffies - container_of(wc->lru.prev, struct wc_entry, 
lru)->age >=
-wc->max_age - wc->max_age / MAX_AGE_DIV))) {
+   time_is_before_eq_jiffies(container_of(wc->lru.prev, struct 
wc_entry, lru)->age
+ + wc->max_age - wc->max_age / MAX_AGE_DIV)) {
 
n_walked++;
if (unlikely(n_walked > WRITEBACK_LATENCY) &&
-- 
2.7.4



Re: [Intel-gfx] [PATCH 1/2] drm: Add HPD state to drm_connector_oob_hotplug_event()

2022-02-14 Thread Bjorn Andersson
On Thu 10 Feb 13:12 PST 2022, Dmitry Baryshkov wrote:

> On Thu, 10 Feb 2022 at 23:54, Bjorn Andersson
>  wrote:
> >
> > On Tue 08 Feb 02:39 PST 2022, Greg Kroah-Hartman wrote:
> >
> > > On Mon, Feb 07, 2022 at 08:43:27PM -0800, Bjorn Andersson wrote:
> > > > In some implementations, such as the Qualcomm platforms, the display
> > > > driver has no way to query the current HPD state and as such it's
> > > > impossible to distinguish between disconnect and attention events.
> > > >
> > > > Add a parameter to drm_connector_oob_hotplug_event() to pass the HPD
> > > > state.
> > > >
> > > > Also push the test for unchanged state in the displayport altmode driver
> > > > into the i915 driver, to allow other drivers to act upon each update.
> > > >
> > > > Signed-off-by: Bjorn Andersson 
> > > > ---
> > > >
> > > > Note that the Intel driver has only been compile tested with this patch.
> > > >
> > > >  drivers/gpu/drm/drm_connector.c  |  6 --
> > > >  drivers/gpu/drm/i915/display/intel_dp.c  | 14 +++---
> > > >  drivers/gpu/drm/i915/i915_drv.h  |  3 +++
> > > >  drivers/usb/typec/altmodes/displayport.c |  9 ++---
> > > >  include/drm/drm_connector.h  |  5 +++--
> > > >  5 files changed, 23 insertions(+), 14 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/drm_connector.c 
> > > > b/drivers/gpu/drm/drm_connector.c
> > > > index a50c82bc2b2f..ad7295597c0f 100644
> > > > --- a/drivers/gpu/drm/drm_connector.c
> > > > +++ b/drivers/gpu/drm/drm_connector.c
> > > > @@ -2825,6 +2825,7 @@ struct drm_connector 
> > > > *drm_connector_find_by_fwnode(struct fwnode_handle *fwnode)
> > > >  /**
> > > >   * drm_connector_oob_hotplug_event - Report out-of-band hotplug event 
> > > > to connector
> > > >   * @connector_fwnode: fwnode_handle to report the event on
> > > > + * @hpd_state: number of data lanes available
> > >
> > > "number"?
> > >
> > > >   *
> > > >   * On some hardware a hotplug event notification may come from outside 
> > > > the display
> > > >   * driver / device. An example of this is some USB Type-C setups where 
> > > > the hardware
> > > > @@ -2834,7 +2835,8 @@ struct drm_connector 
> > > > *drm_connector_find_by_fwnode(struct fwnode_handle *fwnode)
> > > >   * This function can be used to report these out-of-band events after 
> > > > obtaining
> > > >   * a drm_connector reference through calling 
> > > > drm_connector_find_by_fwnode().
> > > >   */
> > > > -void drm_connector_oob_hotplug_event(struct fwnode_handle 
> > > > *connector_fwnode)
> > > > +void drm_connector_oob_hotplug_event(struct fwnode_handle 
> > > > *connector_fwnode,
> > > > +bool hpd_state)
> > >
> > > This is a boolean, how can it be a number?
> > >
> >
> > The kerneldoc wasn't appropriately updated as this went from being
> > "number of data lanes" to "the hot plug detect (hpd) state".
> >
> > > And having a "flag" like this is a pain, how do you know what the
> > > parameter really means?
> > >
> >
> > You're right, "state" isn't a boolean property, let's rename it
> > "hpd_high" to clarify it.
> 
> "connected" ?
> 

I've been trying to find some references to point to, but my
understanding is that in a DisplayPort or HDMI connector/cable you have
a dedicated HPD pin, which when high denotes the sink is alive _and_
EDID can be read.

So in a situation where you have a multifunction USB & DP/HDMI hub where
you connect a display, you might have the USB hub connected to the host
and you might even have your sink connected, but HPD could still be low
until the display is ready to talk to you. So physically everything is
connected, but this property will still be "not connected".

As such I don't think it's appropriate to name it "connected".

Regards,
Bjorn

> >
> > > >  {
> > > > struct drm_connector *connector;
> > > >
> > > > @@ -2843,7 +2845,7 @@ void drm_connector_oob_hotplug_event(struct 
> > > > fwnode_handle *connector_fwnode)
> > > > return;
> > > >
> > > > if (connector->funcs->oob_hotplug_event)
> > > > -   connector->funcs->oob_hotplug_event(connector);
> > > > +   connector->funcs->oob_hotplug_event(connector, hpd_state);
> > > >
> > > > drm_connector_put(connector);
> > > >  }
> > > > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> > > > b/drivers/gpu/drm/i915/display/intel_dp.c
> > > > index 146b83916005..00520867d37b 100644
> > > > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > > > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > > > @@ -4816,15 +4816,23 @@ static int 
> > > > intel_dp_connector_atomic_check(struct drm_connector *conn,
> > > > return intel_modeset_synced_crtcs(state, conn);
> > > >  }
> > > >
> > > > -static void intel_dp_oob_hotplug_event(struct drm_connector *connector)
> > > > +static void intel_dp_oob_hotplug_event(struct drm_connector 
> > > > *connector, bool hpd_state)
> > > >  {
> > > > struct intel_encoder *encoder = 
> > > > 

[Intel-gfx] [PATCH V2 10/13] media: stv0299: use time_is_before_jiffies() instead of jiffies judgment

2022-02-14 Thread Qing Wang
From: Wang Qing 

It is better to use time_xxx() directly instead of jiffies judgment
for understanding.

Signed-off-by: Wang Qing 
---
 drivers/media/dvb-frontends/stv0299.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/dvb-frontends/stv0299.c 
b/drivers/media/dvb-frontends/stv0299.c
index 421395e..867ae04
--- a/drivers/media/dvb-frontends/stv0299.c
+++ b/drivers/media/dvb-frontends/stv0299.c
@@ -183,7 +183,7 @@ static int stv0299_wait_diseqc_fifo (struct stv0299_state* 
state, int timeout)
dprintk ("%s\n", __func__);
 
while (stv0299_readreg(state, 0x0a) & 1) {
-   if (jiffies - start > timeout) {
+   if (time_is_before_jiffies(start + timeout)) {
dprintk ("%s: timeout!!\n", __func__);
return -ETIMEDOUT;
}
@@ -200,7 +200,7 @@ static int stv0299_wait_diseqc_idle (struct stv0299_state* 
state, int timeout)
dprintk ("%s\n", __func__);
 
while ((stv0299_readreg(state, 0x0a) & 3) != 2 ) {
-   if (jiffies - start > timeout) {
+   if (time_is_before_jiffies(start + timeout)) {
dprintk ("%s: timeout!!\n", __func__);
return -ETIMEDOUT;
}
-- 
2.7.4



[Intel-gfx] [PATCH] drm/syncobj: flatten dma_fence_chains on transfer

2022-02-14 Thread Christian König
It is illegal to add a dma_fence_chain as timeline point. Flatten out
the fences into a dma_fence_array instead.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/drm_syncobj.c | 61 ---
 1 file changed, 56 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index c313a5b4549c..7e48dcd1bee4 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -853,12 +853,57 @@ drm_syncobj_fd_to_handle_ioctl(struct drm_device *dev, 
void *data,
>handle);
 }
 
+
+/*
+ * Try to flatten a dma_fence_chain into a dma_fence_array so that it can be
+ * added as timeline fence to a chain again.
+ */
+static int drm_syncobj_flatten_chain(struct dma_fence **f)
+{
+   struct dma_fence_chain *chain = to_dma_fence_chain(*f);
+   struct dma_fence *tmp, **fences;
+   struct dma_fence_array *array;
+   unsigned int count;
+
+   if (!chain)
+   return 0;
+
+   count = 0;
+   dma_fence_chain_for_each(tmp, >base)
+   ++count;
+
+   fences = kmalloc_array(count, sizeof(*fences), GFP_KERNEL);
+   if (!fences)
+   return -ENOMEM;
+
+   count = 0;
+   dma_fence_chain_for_each(tmp, >base)
+   fences[count++] = dma_fence_get(tmp);
+
+   array = dma_fence_array_create(count, fences,
+  dma_fence_context_alloc(1),
+  1, false);
+   if (!array)
+   goto free_fences;
+
+   dma_fence_put(*f);
+   *f = >base;
+   return 0;
+
+free_fences:
+   while (count--)
+   dma_fence_put(fences[count]);
+
+   kfree(fences);
+   return -ENOMEM;
+}
+
 static int drm_syncobj_transfer_to_timeline(struct drm_file *file_private,
struct drm_syncobj_transfer *args)
 {
struct drm_syncobj *timeline_syncobj = NULL;
-   struct dma_fence *fence;
struct dma_fence_chain *chain;
+   struct dma_fence *fence;
int ret;
 
timeline_syncobj = drm_syncobj_find(file_private, args->dst_handle);
@@ -869,16 +914,22 @@ static int drm_syncobj_transfer_to_timeline(struct 
drm_file *file_private,
 args->src_point, args->flags,
 );
if (ret)
-   goto err;
+   goto err_put_timeline;
+
+   ret = drm_syncobj_flatten_chain();
+   if (ret)
+   goto err_free_fence;
+
chain = dma_fence_chain_alloc();
if (!chain) {
ret = -ENOMEM;
-   goto err1;
+   goto err_free_fence;
}
+
drm_syncobj_add_point(timeline_syncobj, chain, fence, args->dst_point);
-err1:
+err_free_fence:
dma_fence_put(fence);
-err:
+err_put_timeline:
drm_syncobj_put(timeline_syncobj);
 
return ret;
-- 
2.25.1



[Intel-gfx] [PATCH V2 1/13] block: xen: use time_is_before_eq_jiffies() instead of jiffies judgment

2022-02-14 Thread Qing Wang
From: Wang Qing 

It is better to use time_xxx() directly instead of jiffies judgment
for understanding.

Signed-off-by: Wang Qing 
---
 drivers/block/xen-blkback/blkback.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/block/xen-blkback/blkback.c 
b/drivers/block/xen-blkback/blkback.c
index d1e2646..aecc1f4
--- a/drivers/block/xen-blkback/blkback.c
+++ b/drivers/block/xen-blkback/blkback.c
@@ -42,6 +42,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -134,8 +135,8 @@ module_param(log_stats, int, 0644);
 
 static inline bool persistent_gnt_timeout(struct persistent_gnt 
*persistent_gnt)
 {
-   return pgrant_timeout && (jiffies - persistent_gnt->last_used >=
-   HZ * pgrant_timeout);
+   return pgrant_timeout && time_is_before_eq_jiffies(
+   persistent_gnt->last_used + HZ * pgrant_timeout);
 }
 
 #define vaddr(page) ((unsigned long)pfn_to_kaddr(page_to_pfn(page)))
-- 
2.7.4



[Intel-gfx] [PATCH 0/2] drm/i915/fbdev: hide struct intel_fbdev

2022-02-14 Thread Jani Nikula
Jani Nikula (2):
  drm/i915/fbdev: add intel_fbdev_to_framebuffer() helper
  drm/i915/fbdev: hide struct intel_fbdev in intel_fbdev.c

 .../drm/i915/display/intel_display_debugfs.c  |  6 ++---
 .../drm/i915/display/intel_display_types.h| 21 
 drivers/gpu/drm/i915/display/intel_fbdev.c| 25 +++
 drivers/gpu/drm/i915/display/intel_fbdev.h|  7 ++
 4 files changed, 35 insertions(+), 24 deletions(-)

-- 
2.30.2



[Intel-gfx] [PATCH 2/2] drm/i915/fbdev: hide struct intel_fbdev in intel_fbdev.c

2022-02-14 Thread Jani Nikula
As all access to struct intel_fbdev guts is nicely stowed away in
intel_fbdev.c, we can hide the struct definition there too.

Signed-off-by: Jani Nikula 
---
 .../drm/i915/display/intel_display_types.h| 21 ---
 drivers/gpu/drm/i915/display/intel_fbdev.c| 17 +++
 2 files changed, 17 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 60e15226a8cb..ff9288eea541 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -26,7 +26,6 @@
 #ifndef __INTEL_DISPLAY_TYPES_H__
 #define __INTEL_DISPLAY_TYPES_H__
 
-#include 
 #include 
 #include 
 #include 
@@ -38,7 +37,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -145,25 +143,6 @@ struct intel_framebuffer {
struct i915_address_space *dpt_vm;
 };
 
-struct intel_fbdev {
-   struct drm_fb_helper helper;
-   struct intel_framebuffer *fb;
-   struct i915_vma *vma;
-   unsigned long vma_flags;
-   async_cookie_t cookie;
-   int preferred_bpp;
-
-   /* Whether or not fbdev hpd processing is temporarily suspended */
-   bool hpd_suspended : 1;
-   /* Set when a hotplug was received while HPD processing was
-* suspended
-*/
-   bool hpd_waiting : 1;
-
-   /* Protects hpd_suspended */
-   struct mutex hpd_lock;
-};
-
 enum intel_hotplug_state {
INTEL_HOTPLUG_UNCHANGED,
INTEL_HOTPLUG_CHANGED,
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c 
b/drivers/gpu/drm/i915/display/intel_fbdev.c
index 3ef683916ba6..4ec88807166c 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
@@ -50,6 +50,23 @@
 #include "intel_fbdev.h"
 #include "intel_frontbuffer.h"
 
+struct intel_fbdev {
+   struct drm_fb_helper helper;
+   struct intel_framebuffer *fb;
+   struct i915_vma *vma;
+   unsigned long vma_flags;
+   async_cookie_t cookie;
+   int preferred_bpp;
+
+   /* Whether or not fbdev hpd processing is temporarily suspended */
+   bool hpd_suspended: 1;
+   /* Set when a hotplug was received while HPD processing was suspended */
+   bool hpd_waiting: 1;
+
+   /* Protects hpd_suspended */
+   struct mutex hpd_lock;
+};
+
 static struct intel_frontbuffer *to_frontbuffer(struct intel_fbdev *ifbdev)
 {
return ifbdev->fb->frontbuffer;
-- 
2.30.2



[Intel-gfx] [PATCH 1/2] drm/i915/fbdev: add intel_fbdev_to_framebuffer() helper

2022-02-14 Thread Jani Nikula
Wrap accessing struct intel_fbdev guts in a helper.

Signed-off-by: Jani Nikula 
---
 drivers/gpu/drm/i915/display/intel_display_debugfs.c | 6 +++---
 drivers/gpu/drm/i915/display/intel_fbdev.c   | 8 
 drivers/gpu/drm/i915/display/intel_fbdev.h   | 7 +++
 3 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c 
b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
index f4de004d470f..b0bcf4d54a74 100644
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -16,6 +16,7 @@
 #include "intel_dp_mst.h"
 #include "intel_drrs.h"
 #include "intel_fbc.h"
+#include "intel_fbdev.h"
 #include "intel_hdcp.h"
 #include "intel_hdmi.h"
 #include "intel_pm.h"
@@ -124,9 +125,8 @@ static int i915_gem_framebuffer_info(struct seq_file *m, 
void *data)
struct drm_framebuffer *drm_fb;
 
 #ifdef CONFIG_DRM_FBDEV_EMULATION
-   if (dev_priv->fbdev && dev_priv->fbdev->helper.fb) {
-   fbdev_fb = to_intel_framebuffer(dev_priv->fbdev->helper.fb);
-
+   fbdev_fb = intel_fbdev_to_framebuffer(dev_priv->fbdev);
+   if (fbdev_fb) {
seq_printf(m, "fbcon size: %d x %d, depth %d, %d bpp, modifier 
0x%llx, refcount %d, obj ",
   fbdev_fb->base.width,
   fbdev_fb->base.height,
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c 
b/drivers/gpu/drm/i915/display/intel_fbdev.c
index 41d279db2be6..3ef683916ba6 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
@@ -680,3 +680,11 @@ void intel_fbdev_restore_mode(struct drm_device *dev)
if (drm_fb_helper_restore_fbdev_mode_unlocked(>helper) == 0)
intel_fbdev_invalidate(ifbdev);
 }
+
+struct intel_framebuffer *intel_fbdev_to_framebuffer(struct intel_fbdev *fbdev)
+{
+   if (!fbdev || !fbdev->helper.fb)
+   return NULL;
+
+   return to_intel_framebuffer(fbdev->helper.fb);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.h 
b/drivers/gpu/drm/i915/display/intel_fbdev.h
index de7c84250eb5..8e86c08d544f 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.h
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.h
@@ -10,6 +10,8 @@
 
 struct drm_device;
 struct drm_i915_private;
+struct intel_fbdev;
+struct intel_framebuffer;
 
 #ifdef CONFIG_DRM_FBDEV_EMULATION
 int intel_fbdev_init(struct drm_device *dev);
@@ -19,6 +21,7 @@ void intel_fbdev_fini(struct drm_i915_private *dev_priv);
 void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool 
synchronous);
 void intel_fbdev_output_poll_changed(struct drm_device *dev);
 void intel_fbdev_restore_mode(struct drm_device *dev);
+struct intel_framebuffer *intel_fbdev_to_framebuffer(struct intel_fbdev 
*fbdev);
 #else
 static inline int intel_fbdev_init(struct drm_device *dev)
 {
@@ -48,6 +51,10 @@ static inline void intel_fbdev_output_poll_changed(struct 
drm_device *dev)
 static inline void intel_fbdev_restore_mode(struct drm_device *dev)
 {
 }
+static inline struct intel_framebuffer *intel_fbdev_to_framebuffer(struct 
intel_fbdev *fbdev)
+{
+   return NULL;
+}
 #endif
 
 #endif /* __INTEL_FBDEV_H__ */
-- 
2.30.2



Re: [Intel-gfx] [PATCH] drm/i915: move i915_gem_object_needs_bit17_swizzle() to intel_ggtt_fencing.[ch]

2022-02-14 Thread Tvrtko Ursulin



On 14/02/2022 13:24, Jani Nikula wrote:

Move i915_gem_object_needs_bit17_swizzle() next to the other
bit_17_swizzle functions. Also un-inline while at it; does not seem like
this is a function needed in hot paths.

Cc: Tvrtko Ursulin 
Signed-off-by: Jani Nikula 
---
  drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c | 8 
  drivers/gpu/drm/i915/gt/intel_ggtt_fencing.h | 1 +
  drivers/gpu/drm/i915/i915_drv.h  | 9 -
  3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c 
b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c
index ee4049ee1fc9..55d525c562df 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c
@@ -755,6 +755,14 @@ static void swizzle_page(struct page *page)
kunmap(page);
  }
  
+bool i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj)

+{
+   struct drm_i915_private *i915 = to_i915(obj->base.dev);
+
+   return to_gt(i915)->ggtt->bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 
&&
+   i915_gem_object_is_tiled(obj);
+}
+
  /**
   * i915_gem_object_do_bit_17_swizzle - fixup bit 17 swizzling
   * @obj: i915 GEM buffer object
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.h 
b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.h
index 25340be5ecf0..fa0734fd4749 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.h
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.h
@@ -46,6 +46,7 @@ void i915_unreserve_fence(struct i915_fence_reg *fence);
  
  void intel_ggtt_restore_fences(struct i915_ggtt *ggtt);
  
+bool i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj);

  void i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj,
   struct sg_table *pages);
  void i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 418091484e02..395c53d4955e 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1495,15 +1495,6 @@ void i915_gem_driver_release(struct drm_i915_private 
*dev_priv);
  
  int i915_gem_open(struct drm_i915_private *i915, struct drm_file *file);
  
-/* i915_gem_tiling.c */

-static inline bool i915_gem_object_needs_bit17_swizzle(struct 
drm_i915_gem_object *obj)
-{
-   struct drm_i915_private *i915 = to_i915(obj->base.dev);
-
-   return to_gt(i915)->ggtt->bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 
&&
-   i915_gem_object_is_tiled(obj);
-}
-
  /* intel_device_info.c */
  static inline struct intel_device_info *
  mkwrite_device_info(struct drm_i915_private *dev_priv)


Reviewed-by: Tvrtko Ursulin 

Regards,

Tvrtko


[Intel-gfx] [PATCH] drm/i915: move i915_gem_object_needs_bit17_swizzle() to intel_ggtt_fencing.[ch]

2022-02-14 Thread Jani Nikula
Move i915_gem_object_needs_bit17_swizzle() next to the other
bit_17_swizzle functions. Also un-inline while at it; does not seem like
this is a function needed in hot paths.

Cc: Tvrtko Ursulin 
Signed-off-by: Jani Nikula 
---
 drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c | 8 
 drivers/gpu/drm/i915/gt/intel_ggtt_fencing.h | 1 +
 drivers/gpu/drm/i915/i915_drv.h  | 9 -
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c 
b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c
index ee4049ee1fc9..55d525c562df 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c
@@ -755,6 +755,14 @@ static void swizzle_page(struct page *page)
kunmap(page);
 }
 
+bool i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj)
+{
+   struct drm_i915_private *i915 = to_i915(obj->base.dev);
+
+   return to_gt(i915)->ggtt->bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 
&&
+   i915_gem_object_is_tiled(obj);
+}
+
 /**
  * i915_gem_object_do_bit_17_swizzle - fixup bit 17 swizzling
  * @obj: i915 GEM buffer object
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.h 
b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.h
index 25340be5ecf0..fa0734fd4749 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.h
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.h
@@ -46,6 +46,7 @@ void i915_unreserve_fence(struct i915_fence_reg *fence);
 
 void intel_ggtt_restore_fences(struct i915_ggtt *ggtt);
 
+bool i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj);
 void i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj,
   struct sg_table *pages);
 void i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 418091484e02..395c53d4955e 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1495,15 +1495,6 @@ void i915_gem_driver_release(struct drm_i915_private 
*dev_priv);
 
 int i915_gem_open(struct drm_i915_private *i915, struct drm_file *file);
 
-/* i915_gem_tiling.c */
-static inline bool i915_gem_object_needs_bit17_swizzle(struct 
drm_i915_gem_object *obj)
-{
-   struct drm_i915_private *i915 = to_i915(obj->base.dev);
-
-   return to_gt(i915)->ggtt->bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 
&&
-   i915_gem_object_is_tiled(obj);
-}
-
 /* intel_device_info.c */
 static inline struct intel_device_info *
 mkwrite_device_info(struct drm_i915_private *dev_priv)
-- 
2.30.2



Re: [Intel-gfx] [PATCH v4 00/14] drm/i915: drm_i915.h cleanup

2022-02-14 Thread Jani Nikula
On Thu, 10 Feb 2022, Tvrtko Ursulin  wrote:
> On 10/02/2022 15:45, Jani Nikula wrote:
>> I've sent parts of this before. Another rebase round.
>
> All look good to me.
>
> Acked-by: Tvrtko Ursulin 

Thanks a bunch, pushed the lot!

> Going forward you can maybe impress the readers even more by including 
> the before/after of your header tree / depth counter script. :)

Then they'll insist on me publishing the hacks I have. :p

BR,
Jani.

-- 
Jani Nikula, Intel Open Source Graphics Center


[Intel-gfx] [PATCH 2/4] drm/i915: Check async flip capability early on

2022-02-14 Thread Ville Syrjala
From: Ville Syrjälä 

Since the async flip state check is done very late and
thus it can see potentially all the planes in the state
(due to the wm/ddb optimization) we need to move the
"can the requested plane do async flips at all?" check
much earlier. For this purpose we introduce
intel_async_flip_check_uapi() that gets called early during
the atomic check.

And for good measure we'll throw in a couple of basic checks:
- is the crtc active?
- was a modeset flagged?
- is+was the plane enabled?
Though atm all of those should be guaranteed by the fact
that the async flip can only be requested through the legacy
page flip ioctl.

Cc: Stanislav Lisovskiy 
Fixes: c3639f3be480 ("drm/i915: Use wm0 only during async flips for DG2")
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_display.c | 79 ++--
 1 file changed, 72 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index baa291e4943f..5a8c7816d29e 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -7463,7 +7463,7 @@ static void kill_bigjoiner_slave(struct 
intel_atomic_state *state,
  * Correspondingly, support is currently added for primary plane only.
  *
  * Async flip can only change the plane surface address, so anything else
- * changing is rejected from the intel_atomic_check_async() function.
+ * changing is rejected from the intel_async_flip_check_hw() function.
  * Once this check is cleared, flip done interrupt is enabled using
  * the intel_crtc_enable_flip_done() function.
  *
@@ -7473,7 +7473,65 @@ static void kill_bigjoiner_slave(struct 
intel_atomic_state *state,
  * correspond to the last vblank and have no relation to the actual time when
  * the flip done event was sent.
  */
-static int intel_atomic_check_async(struct intel_atomic_state *state, struct 
intel_crtc *crtc)
+static int intel_async_flip_check_uapi(struct intel_atomic_state *state,
+  struct intel_crtc *crtc)
+{
+   struct drm_i915_private *i915 = to_i915(state->base.dev);
+   const struct intel_crtc_state *new_crtc_state =
+   intel_atomic_get_new_crtc_state(state, crtc);
+   const struct intel_plane_state *old_plane_state;
+   struct intel_plane_state *new_plane_state;
+   struct intel_plane *plane;
+   int i;
+
+   if (!new_crtc_state->uapi.async_flip)
+   return 0;
+
+   if (!new_crtc_state->uapi.active) {
+   drm_dbg_kms(>drm,
+   "[CRTC:%d:%s] not active\n",
+   crtc->base.base.id, crtc->base.name);
+   return -EINVAL;
+   }
+
+   if (intel_crtc_needs_modeset(new_crtc_state)) {
+   drm_dbg_kms(>drm,
+   "[CRTC:%d:%s] modeset required\n",
+   crtc->base.base.id, crtc->base.name);
+   return -EINVAL;
+   }
+
+   for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state,
+new_plane_state, i) {
+   if (plane->pipe != crtc->pipe)
+   continue;
+
+   /*
+* TODO: Async flip is only supported through the page flip 
IOCTL
+* as of now. So support currently added for primary plane only.
+* Support for other planes on platforms on which supports
+* this(vlv/chv and icl+) should be added when async flip is
+* enabled in the atomic IOCTL path.
+*/
+   if (!plane->async_flip) {
+   drm_dbg_kms(>drm,
+   "[PLANE:%d:%s] async flip not supported\n",
+   plane->base.base.id, plane->base.name);
+   return -EINVAL;
+   }
+
+   if (!old_plane_state->uapi.fb || !new_plane_state->uapi.fb) {
+   drm_dbg_kms(>drm,
+   "[PLANE:%d:%s] no old or new framebuffer\n",
+   plane->base.base.id, plane->base.name);
+   return -EINVAL;
+   }
+   }
+
+   return 0;
+}
+
+static int intel_async_flip_check_hw(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, *new_crtc_state;
@@ -7484,6 +7542,9 @@ static int intel_atomic_check_async(struct 
intel_atomic_state *state, struct int
old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
 
+   if (!new_crtc_state->uapi.async_flip)
+   return 0;
+
if (intel_crtc_needs_modeset(new_crtc_state)) {
drm_dbg_kms(>drm, "Modeset Required. Async 

[Intel-gfx] [PATCH 0/4] drm/i915: Fix async flip wm0/ddb optimization

2022-02-14 Thread Ville Syrjala
From: Ville Syrjälä 

Turns out the async flip wm0/ddb optimization doesn't work
at all currently. Let's fix it. It also had problems with
leaving SAGV on mistakenly but those were handled via a
separate series since it was a more generic issue.

Cc: Stanislav Lisovskiy 

Ville Syrjälä (4):
  drm/i915: Don't skip ddb allocation if data_rate==0
  drm/i915: Check async flip capability early on
  drm/i915: Fix the async flip wm0/ddb optimization
  drm/i915: Pimp async flip debugs

 drivers/gpu/drm/i915/display/intel_atomic.c   |   1 +
 .../gpu/drm/i915/display/intel_atomic_plane.c |   5 +-
 drivers/gpu/drm/i915/display/intel_crtc.c |   4 +-
 drivers/gpu/drm/i915/display/intel_display.c  | 180 ++
 .../drm/i915/display/intel_display_types.h|   6 +-
 drivers/gpu/drm/i915/intel_pm.c   |  30 ++-
 6 files changed, 158 insertions(+), 68 deletions(-)

-- 
2.34.1



[Intel-gfx] [PATCH 1/4] drm/i915: Don't skip ddb allocation if data_rate==0

2022-02-14 Thread Ville Syrjala
From: Ville Syrjälä 

data_rate==0 no longer means a plane is disabled, it could
also mean we want to use the minimum ddb allocation for it.
Hence we can't bail out early during ddb allocation or
else we'll simply forget to allocate any ddb for such planes.

Cc: Stanislav Lisovskiy 
Fixes: 6a4d8cc6bbbf ("drm/i915: Don't allocate extra ddb during async flip for 
DG2")
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/intel_pm.c | 30 --
 1 file changed, 12 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 1179bf31f743..ec2de4f13b5e 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -5114,12 +5114,15 @@ skl_allocate_plane_ddb(struct skl_plane_ddb_iter *iter,
   const struct skl_wm_level *wm,
   u64 data_rate)
 {
-   u16 extra;
+   u16 extra = 0;
 
-   extra = min_t(u16, iter->size,
- DIV64_U64_ROUND_UP(iter->size * data_rate, 
iter->data_rate));
-   iter->size -= extra;
-   iter->data_rate -= data_rate;
+   if (data_rate) {
+   extra = min_t(u16, iter->size,
+ DIV64_U64_ROUND_UP(iter->size * data_rate,
+iter->data_rate));
+   iter->size -= extra;
+   iter->data_rate -= data_rate;
+   }
 
return wm->min_ddb_alloc + extra;
 }
@@ -5162,9 +5165,6 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state 
*state,
skl_ddb_entry_init(_state->wm.skl.plane_ddb_y[PLANE_CURSOR],
   alloc->end - iter.total[PLANE_CURSOR], alloc->end);
 
-   if (iter.data_rate == 0)
-   return 0;
-
/*
 * Find the highest watermark level for which we can satisfy the block
 * requirement of active planes.
@@ -5203,6 +5203,10 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state 
*state,
return -EINVAL;
}
 
+   /* avoid the WARN later when we don't allocate any extra DDB */
+   if (iter.data_rate == 0)
+   iter.size = 0;
+
/*
 * Grant each plane the blocks it requires at the highest achievable
 * watermark level, plus an extra share of the leftover blocks
@@ -5215,20 +5219,10 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state 
*state,
if (plane_id == PLANE_CURSOR)
continue;
 
-   /*
-* We've accounted for all active planes; remaining planes are
-* all disabled.
-*/
-   if (iter.data_rate == 0)
-   break;
-
iter.total[plane_id] =
skl_allocate_plane_ddb(, >wm[level],
   
crtc_state->plane_data_rate[plane_id]);
 
-   if (iter.data_rate == 0)
-   break;
-
iter.uv_total[plane_id] =
skl_allocate_plane_ddb(, >uv_wm[level],
   
crtc_state->uv_plane_data_rate[plane_id]);
-- 
2.34.1



[Intel-gfx] [PATCH 4/4] drm/i915: Pimp async flip debugs

2022-02-14 Thread Ville Syrjala
From: Ville Syrjälä 

Print the offending plane/crtc id+name in the async flip debugs.

Cc: Stanislav Lisovskiy 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_display.c | 63 ++--
 1 file changed, 44 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 93db8ffa54f8..51ef393ff87b 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -7541,18 +7541,24 @@ static int intel_async_flip_check_hw(struct 
intel_atomic_state *state, struct in
if (!new_crtc_state->uapi.async_flip)
return 0;
 
-   if (intel_crtc_needs_modeset(new_crtc_state)) {
-   drm_dbg_kms(>drm, "Modeset Required. Async flip not 
supported\n");
-   return -EINVAL;
-   }
-
if (!new_crtc_state->hw.active) {
-   drm_dbg_kms(>drm, "CRTC inactive\n");
+   drm_dbg_kms(>drm,
+   "[CRTC:%d:%s] not active\n",
+   crtc->base.base.id, crtc->base.name);
return -EINVAL;
}
+
+   if (intel_crtc_needs_modeset(new_crtc_state)) {
+   drm_dbg_kms(>drm,
+   "[CRTC:%d:%s] modeset required\n",
+   crtc->base.base.id, crtc->base.name);
+   return -EINVAL;
+   }
+
if (old_crtc_state->active_planes != new_crtc_state->active_planes) {
drm_dbg_kms(>drm,
-   "Active planes cannot be changed during async 
flip\n");
+   "[CRTC:%d:%s] Active planes cannot be in async 
flip\n",
+   crtc->base.base.id, crtc->base.name);
return -EINVAL;
}
 
@@ -7593,75 +7599,94 @@ static int intel_async_flip_check_hw(struct 
intel_atomic_state *state, struct in
break;
default:
drm_dbg_kms(>drm,
-   "Linear memory/CCS does not support async 
flips\n");
+   "[PLANE:%d:%s] Modifier does not support 
async flips\n",
+   plane->base.base.id, plane->base.name);
return -EINVAL;
}
 
if (new_plane_state->hw.fb->format->num_planes > 1) {
drm_dbg_kms(>drm,
-   "Planar formats not supported with async 
flips\n");
+   "[PLANE:%d:%s] Planar formats do not 
support async flips\n",
+   plane->base.base.id, plane->base.name);
return -EINVAL;
}
 
if (old_plane_state->view.color_plane[0].mapping_stride !=
new_plane_state->view.color_plane[0].mapping_stride) {
-   drm_dbg_kms(>drm, "Stride cannot be changed in 
async flip\n");
+   drm_dbg_kms(>drm,
+   "[PLANE:%d:%s] Stride cannot be changed in 
async flip\n",
+   plane->base.base.id, plane->base.name);
return -EINVAL;
}
 
if (old_plane_state->hw.fb->modifier !=
new_plane_state->hw.fb->modifier) {
drm_dbg_kms(>drm,
-   "Framebuffer modifiers cannot be changed in 
async flip\n");
+   "[PLANE:%d:%s] Modifier cannot be changed 
in async flip\n",
+   plane->base.base.id, plane->base.name);
return -EINVAL;
}
 
if (old_plane_state->hw.fb->format !=
new_plane_state->hw.fb->format) {
drm_dbg_kms(>drm,
-   "Framebuffer format cannot be changed in 
async flip\n");
+   "[PLANE:%d:%s] Pixel format cannot be 
changed in async flip\n",
+   plane->base.base.id, plane->base.name);
return -EINVAL;
}
 
if (old_plane_state->hw.rotation !=
new_plane_state->hw.rotation) {
-   drm_dbg_kms(>drm, "Rotation cannot be changed in 
async flip\n");
+   drm_dbg_kms(>drm,
+   "[PLANE:%d:%s] Rotation cannot be changed 
in async flip\n",
+   plane->base.base.id, plane->base.name);
return -EINVAL;
}
 
if (!drm_rect_equals(_plane_state->uapi.src, 
_plane_state->uapi.src) ||
!drm_rect_equals(_plane_state->uapi.dst, 
_plane_state->uapi.dst)) {
drm_dbg_kms(>drm,
-   

[Intel-gfx] [PATCH 3/4] drm/i915: Fix the async flip wm0/ddb optimization

2022-02-14 Thread Ville Syrjala
From: Ville Syrjälä 

The current implementation of the async flip wm0/ddb optimization
does not work at all. The biggest problem is that we skip the
whole intel_pipe_update_{start,end}() dance and thus never actually
complete the commit that is trying to do the wm/ddb change.

To fix this we need to move the do_async_flip flag to the crtc
state since we handle commits per-pipe, not per-plane.

Also since all planes can now be included in the first/last
"async flip" (which gets converted to a sync flip to do the
wm/ddb mangling) we need to be more careful when checking if
the plane state is async flip comptatible. Only planes doing
the async flip should be checked and other planes are perfectly
fine not adhereing to any async flip related limitations.

However for subsequent commits which are actually going do the
async flip in hardware we want to make sure no other planes
are in the state. That should never happen assuming we did our
job correctly, so we'll toss in a WARN to make sure we catch
any bugs here.

Cc: Stanislav Lisovskiy 
Fixes: c3639f3be480 ("drm/i915: Use wm0 only during async flips for DG2")
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_atomic.c   |  1 +
 .../gpu/drm/i915/display/intel_atomic_plane.c |  5 +--
 drivers/gpu/drm/i915/display/intel_crtc.c |  4 +-
 drivers/gpu/drm/i915/display/intel_display.c  | 40 +++
 .../drm/i915/display/intel_display_types.h|  6 +--
 5 files changed, 31 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c 
b/drivers/gpu/drm/i915/display/intel_atomic.c
index e0667d163266..40da7910f845 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -262,6 +262,7 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
crtc_state->preload_luts = false;
crtc_state->inherited = false;
crtc_state->wm.need_postvbl_update = false;
+   crtc_state->do_async_flip = false;
crtc_state->fb_bits = 0;
crtc_state->update_planes = 0;
crtc_state->dsb = NULL;
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c 
b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index bec02333bdeb..df92cb9c7ff6 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -109,7 +109,6 @@ intel_plane_duplicate_state(struct drm_plane *plane)
intel_state->ggtt_vma = NULL;
intel_state->dpt_vma = NULL;
intel_state->flags = 0;
-   intel_state->do_async_flip = false;
 
/* add reference to fb */
if (intel_state->hw.fb)
@@ -492,7 +491,7 @@ void intel_plane_update_arm(struct intel_plane *plane,
 
trace_intel_plane_update_arm(>base, crtc);
 
-   if (plane_state->do_async_flip)
+   if (crtc_state->do_async_flip && plane->async_flip)
plane->async_flip(plane, crtc_state, plane_state, true);
else
plane->update_arm(plane, crtc_state, plane_state);
@@ -517,7 +516,7 @@ void intel_update_planes_on_crtc(struct intel_atomic_state 
*state,
struct intel_plane *plane;
int i;
 
-   if (new_crtc_state->uapi.async_flip)
+   if (new_crtc_state->do_async_flip)
return;
 
/*
diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c 
b/drivers/gpu/drm/i915/display/intel_crtc.c
index 08ee3e17ee5c..65827481c1b1 100644
--- a/drivers/gpu/drm/i915/display/intel_crtc.c
+++ b/drivers/gpu/drm/i915/display/intel_crtc.c
@@ -485,7 +485,7 @@ void intel_pipe_update_start(struct intel_crtc_state 
*new_crtc_state)
intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI);
DEFINE_WAIT(wait);
 
-   if (new_crtc_state->uapi.async_flip)
+   if (new_crtc_state->do_async_flip)
return;
 
if (intel_crtc_needs_vblank_work(new_crtc_state))
@@ -630,7 +630,7 @@ void intel_pipe_update_end(struct intel_crtc_state 
*new_crtc_state)
ktime_t end_vbl_time = ktime_get();
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 
-   if (new_crtc_state->uapi.async_flip)
+   if (new_crtc_state->do_async_flip)
return;
 
trace_intel_pipe_update_end(crtc, end_vbl_count, scanline_end);
diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 5a8c7816d29e..93db8ffa54f8 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -1231,10 +1231,8 @@ static void intel_crtc_enable_flip_done(struct 
intel_atomic_state *state,
int i;
 
for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
-   if (plane->enable_flip_done &&
-   plane->pipe == crtc->pipe &&
-   update_planes & BIT(plane->id) &&
-   plane_state->do_async_flip)
+   if (plane->pipe == crtc->pipe &&
+  

Re: [Intel-gfx] [PATCH 6/6] drm/i915: Pimp icl+ sagv pre/post update

2022-02-14 Thread Ville Syrjälä
On Mon, Feb 14, 2022 at 12:00:11PM +0200, Lisovskiy, Stanislav wrote:
> On Mon, Feb 14, 2022 at 11:18:11AM +0200, Ville Syrjala wrote:
> > From: Ville Syrjälä 
> > 
> > Add some debugs on what exactly we're doing to the QGV point mask
> > in the icl+ sagv pre/post plane update hooks. Currently we're just
> > guessing.
> > 
> > Cc: Stanislav Lisovskiy 
> > Signed-off-by: Ville Syrjälä 
> > ---
> >  drivers/gpu/drm/i915/intel_pm.c | 37 -
> >  1 file changed, 18 insertions(+), 19 deletions(-)
> 
> Weird I think, I had those debugs initially. Definitely remember
> there was something similar. Was it kinda removed later?

Can't immediately see any such debugs being added or removed
by any commit.

> 
> Stan
> 
> Reviewed-by: Stanislav Lisovskiy 
>  
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_pm.c 
> > b/drivers/gpu/drm/i915/intel_pm.c
> > index 8b70cdc3b58b..5d1f1a9988bb 100644
> > --- a/drivers/gpu/drm/i915/intel_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_pm.c
> > @@ -3818,26 +3818,22 @@ static void icl_sagv_pre_plane_update(struct 
> > intel_atomic_state *state)
> > intel_atomic_get_old_bw_state(state);
> > const struct intel_bw_state *new_bw_state =
> > intel_atomic_get_new_bw_state(state);
> > -   u32 new_mask;
> > +   u32 old_mask, new_mask;
> >  
> > if (!new_bw_state)
> > return;
> >  
> > -   /*
> > -* Nothing to mask
> > -*/
> > -   if (new_bw_state->qgv_points_mask == old_bw_state->qgv_points_mask)
> > -   return;
> > -
> > +   old_mask = old_bw_state->qgv_points_mask;
> > new_mask = old_bw_state->qgv_points_mask | 
> > new_bw_state->qgv_points_mask;
> >  
> > -   /*
> > -* If new mask is zero - means there is nothing to mask,
> > -* we can only unmask, which should be done in unmask.
> > -*/
> > -   if (!new_mask)
> > +   if (old_mask == new_mask)
> > return;
> >  
> > +   WARN_ON(!new_bw_state->base.changed);
> > +
> > +   drm_dbg_kms(_priv->drm, "Restricting QGV points: 0x%x -> 0x%x\n",
> > +   old_mask, new_mask);
> > +
> > /*
> >  * Restrict required qgv points before updating the configuration.
> >  * According to BSpec we can't mask and unmask qgv points at the same
> > @@ -3854,19 +3850,22 @@ static void icl_sagv_post_plane_update(struct 
> > intel_atomic_state *state)
> > intel_atomic_get_old_bw_state(state);
> > const struct intel_bw_state *new_bw_state =
> > intel_atomic_get_new_bw_state(state);
> > -   u32 new_mask = 0;
> > +   u32 old_mask, new_mask;
> >  
> > if (!new_bw_state)
> > return;
> >  
> > -   /*
> > -* Nothing to unmask
> > -*/
> > -   if (new_bw_state->qgv_points_mask == old_bw_state->qgv_points_mask)
> > -   return;
> > -
> > +   old_mask = old_bw_state->qgv_points_mask | 
> > new_bw_state->qgv_points_mask;
> > new_mask = new_bw_state->qgv_points_mask;
> >  
> > +   if (old_mask == new_mask)
> > +   return;
> > +
> > +   WARN_ON(!new_bw_state->base.changed);
> > +
> > +   drm_dbg_kms(_priv->drm, "Relaxing QGV points: 0x%x -> 0x%x\n",
> > +   old_mask, new_mask);
> > +
> > /*
> >  * Allow required qgv points after updating the configuration.
> >  * According to BSpec we can't mask and unmask qgv points at the same
> > -- 
> > 2.34.1
> > 

-- 
Ville Syrjälä
Intel


Re: [Intel-gfx] [PATCH 2/6] drm/i915: Fix bw atomic check when switching between SAGV vs. no SAGV

2022-02-14 Thread Ville Syrjälä
On Mon, Feb 14, 2022 at 12:05:36PM +0200, Lisovskiy, Stanislav wrote:
> On Mon, Feb 14, 2022 at 11:18:07AM +0200, Ville Syrjala wrote:
> > From: Ville Syrjälä 
> > 
> > If the only thing that is changing is SAGV vs. no SAGV but
> > the number of active planes and the total data rates end up
> > unchanged we currently bail out of intel_bw_atomic_check()
> > early and forget to actually compute the new WGV point
> > mask and thus won't actually enable/disable SAGV as requested.
> > This ends up poorly if we end up running with SAGV enabled
> > when we shouldn't. Usually ends up in underruns.
> > To fix this let's go through the QGV point mask computation
> > if anyone else already added the bw state for us.
> 
> Haven't been looking this in a while. Despite we have been
> looking like few revisions together still some bugs :(
> 
> I thought SAGV vs No SAGV can't change if active planes 
> or data rate didn't change? Because it means we probably
> still have same ddb allocations, which means SAGV state
> will just stay the same.

SAGV can change due to watermarks/ddb allocations. The easiest
way to trip this up is to try to use the async flip wm0/ddb 
optimization. That immediately forgets to turn off SAGV and
we get underruns, whcih is how I noticed this. And I don't
immediately see any easy proof that this couldn't also happen
due to some other plane changes.

> 
> Stan
> 
> > 
> > Cc: sta...@vger.kernel.org
> > Cc: Stanislav Lisovskiy 
> > Fixes: 20f505f22531 ("drm/i915: Restrict qgv points which don't have enough 
> > bandwidth.")
> > Signed-off-by: Ville Syrjälä 
> > ---
> >  drivers/gpu/drm/i915/display/intel_bw.c | 7 +++
> >  1 file changed, 7 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_bw.c 
> > b/drivers/gpu/drm/i915/display/intel_bw.c
> > index 23aa8e06de18..d72ccee7d53b 100644
> > --- a/drivers/gpu/drm/i915/display/intel_bw.c
> > +++ b/drivers/gpu/drm/i915/display/intel_bw.c
> > @@ -846,6 +846,13 @@ int intel_bw_atomic_check(struct intel_atomic_state 
> > *state)
> > if (num_psf_gv_points > 0)
> > mask |= REG_GENMASK(num_psf_gv_points - 1, 0) << 
> > ADLS_PSF_PT_SHIFT;
> >  
> > +   /*
> > +* If we already have the bw state then recompute everything
> > +* even if pipe data_rate / active_planes didn't change.
> > +* Other things (such as SAGV) may have changed.
> > +*/
> > +   new_bw_state = intel_atomic_get_new_bw_state(state);
> > +
> > for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
> > new_crtc_state, i) {
> > unsigned int old_data_rate =
> > -- 
> > 2.34.1
> > 

-- 
Ville Syrjälä
Intel


Re: [Intel-gfx] [PATCH 1/6] drm/i915: Correctly populate use_sagv_wm for all pipes

2022-02-14 Thread Lisovskiy, Stanislav
On Mon, Feb 14, 2022 at 11:18:06AM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> When changing between SAGV vs. no SAGV on tgl+ we have to
> update the use_sagv_wm flag for all the crtcs or else
> an active pipe not already in the state will end up using
> the wrong watermarks. That is especially bad when we end up
> with the tighter non-SAGV watermarks with SAGV enabled.
> Usually ends up in underruns.

Probably valid point. Just noticed that we have this constant 
confusion, between cases when we have to update only crtc
which are added to the state(i.e only those which changed)
versus cases when everything has to be updated, regardless 
if its in the state or not.

I think it didn't ever caused underruns however, which is
strange - currently we mostly hit underruns once due to 
some PSR magic. Might be we just are lucky enough to get
all crtcs added to the state for some other reasons.

Reviewed-by: Stanislav Lisovskiy 

Stan

> 
> Cc: sta...@vger.kernel.org
> Cc: Stanislav Lisovskiy 
> Fixes: 7241c57d3140 ("drm/i915: Add TGL+ SAGV support")
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 22 +++---
>  1 file changed, 11 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 1179bf31f743..d8eb553ffad3 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -4009,6 +4009,17 @@ static int intel_compute_sagv_mask(struct 
> intel_atomic_state *state)
>   return ret;
>   }
>  
> + if (intel_can_enable_sagv(dev_priv, new_bw_state) !=
> + intel_can_enable_sagv(dev_priv, old_bw_state)) {
> + ret = intel_atomic_serialize_global_state(_bw_state->base);
> + if (ret)
> + return ret;
> + } else if (new_bw_state->pipe_sagv_reject != 
> old_bw_state->pipe_sagv_reject) {
> + ret = intel_atomic_lock_global_state(_bw_state->base);
> + if (ret)
> + 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;
> @@ -4024,17 +4035,6 @@ static int intel_compute_sagv_mask(struct 
> intel_atomic_state *state)
>   intel_can_enable_sagv(dev_priv, new_bw_state);
>   }
>  
> - if (intel_can_enable_sagv(dev_priv, new_bw_state) !=
> - intel_can_enable_sagv(dev_priv, old_bw_state)) {
> - ret = intel_atomic_serialize_global_state(_bw_state->base);
> - if (ret)
> - return ret;
> - } else if (new_bw_state->pipe_sagv_reject != 
> old_bw_state->pipe_sagv_reject) {
> - ret = intel_atomic_lock_global_state(_bw_state->base);
> - if (ret)
> - return ret;
> - }
> -
>   return 0;
>  }
>  
> -- 
> 2.34.1
> 


Re: [Intel-gfx] [PATCH 2/6] drm/i915: Fix bw atomic check when switching between SAGV vs. no SAGV

2022-02-14 Thread Lisovskiy, Stanislav
On Mon, Feb 14, 2022 at 11:18:07AM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> If the only thing that is changing is SAGV vs. no SAGV but
> the number of active planes and the total data rates end up
> unchanged we currently bail out of intel_bw_atomic_check()
> early and forget to actually compute the new WGV point
> mask and thus won't actually enable/disable SAGV as requested.
> This ends up poorly if we end up running with SAGV enabled
> when we shouldn't. Usually ends up in underruns.
> To fix this let's go through the QGV point mask computation
> if anyone else already added the bw state for us.

Haven't been looking this in a while. Despite we have been
looking like few revisions together still some bugs :(

I thought SAGV vs No SAGV can't change if active planes 
or data rate didn't change? Because it means we probably
still have same ddb allocations, which means SAGV state
will just stay the same.

Stan

> 
> Cc: sta...@vger.kernel.org
> Cc: Stanislav Lisovskiy 
> Fixes: 20f505f22531 ("drm/i915: Restrict qgv points which don't have enough 
> bandwidth.")
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/display/intel_bw.c | 7 +++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_bw.c 
> b/drivers/gpu/drm/i915/display/intel_bw.c
> index 23aa8e06de18..d72ccee7d53b 100644
> --- a/drivers/gpu/drm/i915/display/intel_bw.c
> +++ b/drivers/gpu/drm/i915/display/intel_bw.c
> @@ -846,6 +846,13 @@ int intel_bw_atomic_check(struct intel_atomic_state 
> *state)
>   if (num_psf_gv_points > 0)
>   mask |= REG_GENMASK(num_psf_gv_points - 1, 0) << 
> ADLS_PSF_PT_SHIFT;
>  
> + /*
> +  * If we already have the bw state then recompute everything
> +  * even if pipe data_rate / active_planes didn't change.
> +  * Other things (such as SAGV) may have changed.
> +  */
> + new_bw_state = intel_atomic_get_new_bw_state(state);
> +
>   for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
>   new_crtc_state, i) {
>   unsigned int old_data_rate =
> -- 
> 2.34.1
> 


[Intel-gfx] [RFC v2 5/5] drm/hdmi21: Add frl_dfm_helper to Makefile

2022-02-14 Thread Vandita Kulkarni
Add the new frl_dfm_helper file to drm Makefile

Signed-off-by: Vandita Kulkarni 
---
 drivers/gpu/drm/Makefile | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 8675c2af7ae1..81fe3df8bfda 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -57,7 +57,9 @@ drm_kms_helper-y := drm_bridge_connector.o drm_crtc_helper.o \
drm_scdc_helper.o drm_gem_atomic_helper.o \
drm_gem_framebuffer_helper.o \
drm_atomic_state_helper.o drm_damage_helper.o \
-   drm_format_helper.o drm_self_refresh_helper.o drm_rect.o
+   drm_format_helper.o drm_self_refresh_helper.o drm_rect.o \
+   drm_frl_dfm_helper.o
+
 drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o
 drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
 
-- 
2.32.0



[Intel-gfx] [RFC v2 4/5] drm/hdmi21: Add support for DFM calculation with DSC

2022-02-14 Thread Vandita Kulkarni
From: Ankit Nautiyal 

Add helper functions for calculating FRL capacity and DFM
requirements with given compressed bpp.

Signed-off-by: Ankit Nautiyal 
Signed-off-by: Vandita Kulkarni 
---
 drivers/gpu/drm/drm_frl_dfm_helper.c | 297 +++
 include/drm/drm_frl_dfm_helper.h |   3 +
 2 files changed, 300 insertions(+)

diff --git a/drivers/gpu/drm/drm_frl_dfm_helper.c 
b/drivers/gpu/drm/drm_frl_dfm_helper.c
index b8f4f8ee50d3..9eb91dd4e21e 100644
--- a/drivers/gpu/drm/drm_frl_dfm_helper.c
+++ b/drivers/gpu/drm/drm_frl_dfm_helper.c
@@ -555,3 +555,300 @@ drm_frl_dfm_nondsc_requirement_met(struct 
drm_hdmi_frl_dfm *frl_dfm)
return false;
 }
 EXPORT_SYMBOL(drm_frl_dfm_nondsc_requirement_met);
+
+/* DSC DFM functions */
+/* Get FRL Available characters */
+static unsigned int
+drm_get_frl_available_chars(unsigned int overhead_max, unsigned int cfrl_line)
+{
+   unsigned int frl_char_avlb = ((EFFICIENCY_MULTIPLIER - overhead_max) * 
cfrl_line);
+
+   return frl_char_avlb / EFFICIENCY_MULTIPLIER;
+}
+
+/* Get required no. of tribytes during HCActive */
+static unsigned int
+drm_get_frl_hcactive_tb_target(unsigned int dsc_bpp_x16, unsigned int 
slice_width, unsigned int num_slices)
+{
+   unsigned int bytes_target;
+
+   bytes_target = num_slices * DIV_ROUND_UP(dsc_bpp_x16 * slice_width,
+8 * BPP_MULTIPLIER);
+
+   return DIV_ROUND_UP(bytes_target, 3);
+}
+
+/* Get required no. of tribytes (estimate1) during HCBlank */
+static unsigned int
+drm_get_frl_hcblank_tb_est1_target(unsigned int hcactive_target_tb,
+  unsigned int hactive, unsigned int hblank)
+{
+   return DIV_ROUND_UP(hcactive_target_tb * hblank, hactive);
+}
+
+/* Get required no. of tribytes during HCBlank */
+static unsigned int
+drm_get_frl_hcblank_tb_target(unsigned int hcactive_target_tb, unsigned int 
hactive, unsigned int hblank,
+ unsigned int hcblank_audio_min, unsigned int 
cfrl_available)
+{
+   unsigned int hcblank_target_tb1 = 
drm_get_frl_hcblank_tb_est1_target(hcactive_target_tb,
+   hactive, 
hblank);
+   unsigned int hcblank_target_tb2 = max(hcblank_target_tb1, 
hcblank_audio_min);
+
+   return 4 * (min(hcblank_target_tb2,
+   (2 * cfrl_available - 3 * hcactive_target_tb) / 2) / 4);
+}
+
+/* Get the avg no of tribytes sent per sec (Kbps) */
+static unsigned int
+drm_frl_dsc_get_ftb_avg(unsigned int hcactive_target_tb, unsigned int 
hcblank_target_tb,
+   unsigned int hactive, unsigned int hblank,
+   unsigned int fpixelclock_max_khz)
+{
+   return (hcactive_target_tb + hcblank_target_tb) * (fpixelclock_max_khz 
/ (hactive + hblank));
+}
+
+/* Time to send Active tribytes in nanoseconds */
+static unsigned int
+drm_frl_dsc_get_tactive_ref_ns(unsigned int line_time_ns, unsigned int 
hactive, unsigned int hblank)
+{
+   return (line_time_ns * hactive) / (hactive + hblank);
+}
+
+/* Time to send Blanking tribytes in nanoseconds  */
+static unsigned int
+drm_frl_dsc_get_tblank_ref_ns(unsigned int line_time_ns, unsigned int hactive, 
unsigned int hblank)
+{
+   return (line_time_ns * hblank) / (hactive + hblank);
+}
+
+/* Get time to send all tribytes in hcactive region in nsec*/
+static unsigned int
+drm_frl_dsc_tactive_target_ns(unsigned int frl_lanes, unsigned int 
hcactive_target_tb, unsigned int ftb_avg_k,
+ unsigned int min_frl_char_rate_k, unsigned int 
overhead_max)
+{
+   unsigned int avg_tribyte_time_ns, tribyte_time_ns;
+   unsigned int num_chars_hcactive;
+   unsigned int frl_char_rate_k;
+
+   /* Avg time to transmit all active region tribytes */
+   avg_tribyte_time_ns = (hcactive_target_tb * FRL_TIMING_NS_MULTIPLIER) /
+ (ftb_avg_k * 1000);
+
+   /*
+* 2 bytes in active region = 1 FRL characters
+* 1 Tribyte in active region = 3/2 FRL characters
+*/
+
+   num_chars_hcactive = (hcactive_target_tb * 3) / 2;
+
+   /*
+* FRL rate = lanes * frl character rate
+* But actual bandwidth wil be less, due to FRL limitations so account
+* for the overhead involved.
+* FRL rate with overhead = FRL rate * (100 - overhead %) / 100
+*/
+   frl_char_rate_k = frl_lanes * min_frl_char_rate_k;
+   frl_char_rate_k = (frl_char_rate_k * (EFFICIENCY_MULTIPLIER - 
overhead_max)) /
+ EFFICIENCY_MULTIPLIER;
+
+   /* Time to transmit all characters with FRL limitations */
+   tribyte_time_ns = (num_chars_hcactive * FRL_TIMING_NS_MULTIPLIER) /
+ frl_char_rate_k * 1000;
+
+   return max(avg_tribyte_time_ns, tribyte_time_ns);
+}
+
+/* Get no. of tri bytes borrowed with DSC enabled */
+static unsigned int

[Intel-gfx] [RFC v2 3/5] drm/hdmi21: Add helpers to verify non-dsc DFM requirements

2022-02-14 Thread Vandita Kulkarni
Add helpers to compute DFM variables and to verify if the
DFM requirements are met or not in non dsc cases.

Signed-off-by: Vandita Kulkarni 
---
 drivers/gpu/drm/drm_frl_dfm_helper.c | 161 +++
 include/drm/drm_frl_dfm_helper.h |   2 +
 2 files changed, 163 insertions(+)

diff --git a/drivers/gpu/drm/drm_frl_dfm_helper.c 
b/drivers/gpu/drm/drm_frl_dfm_helper.c
index d3ae35653370..b8f4f8ee50d3 100644
--- a/drivers/gpu/drm/drm_frl_dfm_helper.c
+++ b/drivers/gpu/drm/drm_frl_dfm_helper.c
@@ -394,3 +394,164 @@ drm_compute_payload_utilization(unsigned int 
frl_char_payload_actual, unsigned i
utilization = (frl_char_payload_actual * EFFICIENCY_MULTIPLIER) / 
frl_char_per_line_period;
return utilization;
 }
+
+/* Collect link characteristics */
+static void
+drm_frl_dfm_compute_link_characteristics(struct drm_hdmi_frl_dfm *frl_dfm)
+{
+   unsigned int frl_bit_rate_min_kbps;
+
+   frl_dfm->params.pixel_clock_max_khz =
+   
drm_get_max_legal_pixel_rate(frl_dfm->config.pixel_clock_nominal_khz);
+   frl_dfm->params.line_time_ns =
+   drm_get_min_video_line_period(frl_dfm->config.hblank,
+ frl_dfm->config.hactive,
+ 
frl_dfm->params.pixel_clock_max_khz);
+   frl_bit_rate_min_kbps = 
drm_get_min_frl_bit_rate(frl_dfm->config.bit_rate_kbps);
+   frl_dfm->params.char_rate_min_kbps = 
drm_get_min_frl_char_rate(frl_bit_rate_min_kbps);
+   frl_dfm->params.cfrl_line =
+   
drm_get_total_frl_char_per_line_period(frl_dfm->params.line_time_ns,
+  
frl_dfm->params.char_rate_min_kbps,
+  frl_dfm->config.lanes);
+}
+
+/* Determine FRL link overhead */
+static void drm_frl_dfm_compute_max_frl_link_overhead(struct drm_hdmi_frl_dfm 
*frl_dfm)
+{
+   unsigned int overhead_min;
+
+   overhead_min = drm_get_total_minimum_overhead(frl_dfm->config.lanes);
+   frl_dfm->params.overhead_max = drm_get_max_overhead(overhead_min);
+}
+
+/* Audio support Verification computations */
+static void
+drm_frl_dfm_compute_audio_hblank_min(struct drm_hdmi_frl_dfm *frl_dfm)
+{
+   unsigned int num_audio_pkt, audio_pkt_rate;
+
+   /*
+* TBD: get the actual audio pkt type as described in
+* table 6.44 of HDMI2.1 spec to find the num_audio_pkt,
+* for now assume audio sample packet and audio packet
+* layout as 1, resulting in number of audio packets
+* required to carry each audio sample or audio frame
+* as 1
+*/
+   num_audio_pkt = 1;
+   audio_pkt_rate = drm_get_audio_pkt_rate(frl_dfm->config.audio_hz, 
num_audio_pkt);
+   frl_dfm->params.num_audio_pkts_line =
+drm_get_audio_pkts_hblank(audio_pkt_rate, 
frl_dfm->params.line_time_ns);
+   frl_dfm->params.hblank_audio_min =
+   
drm_get_audio_hblank_min(frl_dfm->params.num_audio_pkts_line);
+}
+
+/*
+ * Determine the number of tribytes required for active video , blanking period
+ * with the pixel configuration
+ */
+static void
+drm_frl_dfm_compute_tbactive_tbblank(struct drm_hdmi_frl_dfm *frl_dfm)
+{
+   unsigned int bpp, bytes_per_line;
+
+   bpp = drm_get_frl_bits_per_pixel(frl_dfm->config.color_format, 
frl_dfm->config.bpc);
+   bytes_per_line = drm_get_video_bytes_per_line(bpp, 
frl_dfm->config.hactive);
+
+   frl_dfm->params.tb_active = 
drm_get_active_video_tribytes_reqd(bytes_per_line);
+   frl_dfm->params.tb_blank =
+   drm_get_blanking_tribytes_avail(frl_dfm->config.color_format,
+   frl_dfm->config.hblank,
+   frl_dfm->config.bpc);
+}
+
+/* Verify the configuration meets the capacity requirements for the FRL 
configuration*/
+static bool
+drm_frl_dfm_verify_frl_capacity_requirement(struct drm_hdmi_frl_dfm *frl_dfm)
+{
+   unsigned int tactive_ref_ns, tblank_ref_ns, tactive_min_ns, 
tblank_min_ns;
+   unsigned int tborrowed_ns;
+
+   frl_dfm->params.ftb_avg_k =
+   
drm_get_avg_tribyte_rate(frl_dfm->params.pixel_clock_max_khz,
+frl_dfm->params.tb_active, 
frl_dfm->params.tb_blank,
+frl_dfm->config.hactive, 
frl_dfm->config.hblank);
+   tactive_ref_ns = drm_get_tactive_ref(frl_dfm->params.line_time_ns,
+frl_dfm->config.hblank,
+frl_dfm->config.hactive);
+   tblank_ref_ns = drm_get_tblank_ref(frl_dfm->params.line_time_ns,
+  frl_dfm->config.hblank,
+  frl_dfm->config.hactive);
+   tactive_min_ns = drm_get_tactive_min(frl_dfm->config.lanes,
+ 

[Intel-gfx] [RFC v2 2/5] drm/hdmi21: Add non dsc frl capacity computation helpers

2022-02-14 Thread Vandita Kulkarni
Add helper functions for computing non dsc frl
link characteristics

Signed-off-by: Vandita Kulkarni 
---
 drivers/gpu/drm/drm_frl_dfm_helper.c | 396 +++
 1 file changed, 396 insertions(+)
 create mode 100644 drivers/gpu/drm/drm_frl_dfm_helper.c

diff --git a/drivers/gpu/drm/drm_frl_dfm_helper.c 
b/drivers/gpu/drm/drm_frl_dfm_helper.c
new file mode 100644
index ..d3ae35653370
--- /dev/null
+++ b/drivers/gpu/drm/drm_frl_dfm_helper.c
@@ -0,0 +1,396 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2022 Intel Corp
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+/* Total frl charecters per super block */
+static unsigned int drm_get_frl_char_per_super_blk(unsigned int lanes)
+{
+   unsigned int frl_char_per_sb;
+
+   frl_char_per_sb = (4 * FRL_CHAR_PER_CHAR_BLK) + lanes;
+   return frl_char_per_sb;
+}
+
+/*
+ * Determine the overhead due to the inclusion of
+ * the SR and SSB FRL charecters used for
+ * super block framing
+ */
+static unsigned int drm_get_overhead_super_blk(unsigned int lanes)
+{
+   return (lanes * EFFICIENCY_MULTIPLIER) / 
drm_get_frl_char_per_super_blk(lanes);
+}
+
+/*
+ * Determine the overhead due to the inclusion of RS FEC pairity
+ * symbols. Each charecter block uses 8 FRL charecters for RS Pairity
+ * and there are 4 charecter blocks per super block
+ */
+static unsigned int drm_get_overhead_rs(unsigned int lanes)
+{
+   return (8 * 4 * EFFICIENCY_MULTIPLIER) /  
drm_get_frl_char_per_super_blk(lanes);
+}
+
+/* Determine the overhead due to FRL Map charecters.
+ * In a bandwidth constrained application, the FRL packets will be long,
+ * there will typically be two FRL Map Charecters per Super Block most of the 
time.
+ * When a tracnsition occurs between Hactive and Hblank (uncomperssed video) or
+ * HCactive and HCblank (compressed video transport), there may be a
+ * third FRL Map Charected. Therefore this spec assumes 2.5 FRL Map Charecters
+ * per Super Block.
+ */
+static unsigned int drm_get_overhead_frl_map_char(unsigned int lanes)
+{
+   return (25  * EFFICIENCY_MULTIPLIER) / (10 * 
drm_get_frl_char_per_super_blk(lanes));
+}
+
+/* Total minimum overhead multiplied by EFFICIENCY_MULIPLIER */
+static unsigned int drm_get_total_minimum_overhead(unsigned int lanes)
+{
+   unsigned int total_overhead_min;
+   unsigned int overhead_sb = drm_get_overhead_super_blk(lanes);
+   unsigned int overhead_rs = drm_get_overhead_rs(lanes);
+   unsigned int overhead_map = drm_get_overhead_frl_map_char(lanes);
+
+   total_overhead_min = overhead_sb + overhead_rs + overhead_map;
+
+   return total_overhead_min;
+}
+
+/*
+ * Additional margin to the overhead is provided to account for the possibility
+ * of more Map Charecters, zero padding at the end of HCactive, and other minor
+ * items
+ */
+static unsigned int drm_get_max_overhead(unsigned int total_overhead_min)
+{
+   unsigned int total_overhead_max;
+
+   total_overhead_max = total_overhead_min + OVERHEAD_M;
+   return total_overhead_max;
+}
+
+/* Collect the link charecteristics */
+
+/* Determine the maximum legal pixel rate */
+static unsigned int drm_get_max_legal_pixel_rate(unsigned int 
fpixel_clock_nominal_k)
+{
+   unsigned int fpixel_clock_max_k = (fpixel_clock_nominal_k *
+ (1000 + TOLERANCE_PIXEL_CLOCK)) / 1000;
+   return fpixel_clock_max_k;
+}
+
+/* Determine the minimum Video Line period */
+static unsigned int drm_get_min_video_line_period(unsigned int hactive, 
unsigned int hblank,
+ unsigned int 
fpixel_clock_max_k)
+{
+   unsigned int line_time_ns;
+
+   line_time_ns = ((hactive + hblank) * FRL_TIMING_NS_MULTIPLIER) /
+  fpixel_clock_max_k;
+   return line_time_ns;
+}
+
+/* Determine the worst-case slow FRL Bit Rate in kbps*/
+static unsigned int drm_get_min_frl_bit_rate(unsigned int 
frl_bit_rate_nominal_k)
+{
+   unsigned int frl_bit_rate_min_k;
+
+   frl_bit_rate_min_k = (frl_bit_rate_nominal_k / 100) *
+(100 - TOLERANCE_FRL_BIT_RATE);
+   return frl_bit_rate_min_k;
+}
+
+/* Determine the worst-case slow FRL Charecter Rate */
+static unsigned int drm_get_min_frl_char_rate(unsigned int frl_bit_rate_min_k)
+{
+   unsigned int frl_char_rate_min_k;
+
+   frl_char_rate_min_k = frl_bit_rate_min_k / 18;
+   return frl_char_rate_min_k;
+}
+
+/* Determine the Minimum Total FRL charecters per line period */
+static unsigned int
+drm_get_total_frl_char_per_line_period(unsigned int line_time_ns, unsigned int 
frl_char_rate_min_k,
+  unsigned int lanes)
+{
+   unsigned int frl_char_per_line_period;
+
+   frl_char_per_line_period = (line_time_ns * frl_char_rate_min_k * lanes *
+   1000) / FRL_TIMING_NS_MULTIPLIER;
+   return frl_char_per_line_period;
+}
+
+/* Audio 

[Intel-gfx] [RFC v2 1/5] drm/hdmi21: Define frl_dfm structure

2022-02-14 Thread Vandita Kulkarni
Define frl_dfm structure to hold frl characteristics
needed for frl capacity computation in order to
meet the data flow metering requirement.

Signed-off-by: Vandita Kulkarni 
---
 include/drm/drm_frl_dfm_helper.h | 124 +++
 1 file changed, 124 insertions(+)
 create mode 100644 include/drm/drm_frl_dfm_helper.h

diff --git a/include/drm/drm_frl_dfm_helper.h b/include/drm/drm_frl_dfm_helper.h
new file mode 100644
index ..5cab102fe25f
--- /dev/null
+++ b/include/drm/drm_frl_dfm_helper.h
@@ -0,0 +1,124 @@
+/* SPDX-License-Identifier: MIT
+ * Copyright © 2022 Intel Corp
+ */
+
+#ifndef DRM_FRL_DFM_H_
+#define DRM_FRL_DFM_H_
+
+/* DFM constraints and tolerance values from HDMI2.1 spec */
+#define TB_BORROWED_MAX400
+#define FRL_CHAR_PER_CHAR_BLK  510
+/* Tolerance pixel clock unit is in  mHz */
+#define TOLERANCE_PIXEL_CLOCK  5
+#define TOLERANCE_FRL_BIT_RATE 300
+#define TOLERANCE_AUDIO_CLOCK  1000
+#define ACR_RATE_MAX   1500
+#define EFFICIENCY_MULTIPLIER  1000
+#define OVERHEAD_M (3 * EFFICIENCY_MULTIPLIER / 1000)
+#define BPP_MULTIPLIER 16
+#define FRL_TIMING_NS_MULTIPLIER   10
+
+/* ALl the input config needed to compute DFM requirements */
+struct drm_frl_dfm_input_config {
+   /*
+* Pixel clock rate kHz, when FVA is
+* enabled this rate is the rate after adjustment
+*/
+   unsigned int pixel_clock_nominal_khz;
+
+   /* active pixels per line */
+   unsigned int hactive;
+
+   /* Blanking pixels per line */
+   unsigned int hblank;
+
+   /* Bits per component */
+   unsigned int bpc;
+
+   /* Pixel encoding */
+   unsigned int color_format;
+
+   /* FRL bit rate in kbps */
+   unsigned int bit_rate_kbps;
+
+   /* FRL lanes */
+   unsigned int lanes;
+
+   /* Number of audio channels */
+   unsigned int audio_channels;
+
+   /* Audio rate in Hz */
+   unsigned int audio_hz;
+
+   /* Selected bpp target value */
+   unsigned int target_bpp_16;
+
+   /*
+* Number of horizontal pixels in a slice.
+* Equivalent to PPS parameter slice_width
+*/
+   unsigned int slice_width;
+};
+
+/* Computed dfm parameters as per the HDMI2.1 spec */
+struct drm_frl_dfm_params {
+   /*
+* Link overhead in percentage
+* multiplied by 1000 (efficiency multiplier)
+*/
+   unsigned int overhead_max;
+
+   /* Maximum pixel rate in kHz */
+   unsigned int pixel_clock_max_khz;
+
+   /* Minimum video line period in nano sec */
+   unsigned int line_time_ns;
+
+   /* worst case slow frl character rate in kbps */
+   unsigned int char_rate_min_kbps;
+
+   /* minimum total frl charecters per line perios */
+   unsigned int cfrl_line;
+
+   /* Average tribyte rate in khz */
+   unsigned int ftb_avg_k;
+
+   /* Audio characteristics */
+
+   /*  number of audio packets needed during hblank */
+   unsigned int num_audio_pkts_line;
+
+   /*
+*  Minimum required hblank assuming no control preiod
+*  RC compression
+*/
+   unsigned int hblank_audio_min;
+
+   /* Number of tribytes required to carry active video */
+   unsigned int tb_active;
+
+   /* Total available tribytes during the blanking period */
+   unsigned int tb_blank;
+
+   /*
+* Number of tribytes required to be transmitted during
+* the hblank period
+*/
+   unsigned int tb_borrowed;
+
+   /* DSC frl characteristics */
+
+   /* Tribytes required to carry the target bpp */
+   unsigned int hcactive_target;
+
+   /* tribytes available during blanking with target bpp */
+   unsigned int hcblank_target;
+};
+
+/* FRL DFM structure to hold involved in DFM computation */
+struct drm_hdmi_frl_dfm {
+   struct drm_frl_dfm_input_config config;
+   struct drm_frl_dfm_params params;
+};
+
+#endif
-- 
2.32.0



[Intel-gfx] [RFC v2 0/5] Add data flow metering support for HDMI2.1

2022-02-14 Thread Vandita Kulkarni
The below patches add support for data flow metering
as mentioned in the section 6.5.6 FRL data flow metering
of HDMI 2.1 specification.

Add functions to calclulate the DFM parameters
for the given frl config, which is further used to evaluate the
data flow metering requirement as specified in the spec.

As per the spec the below patches implement the frl capacity computation
functions for both compressed and uncompressed video.
Finally exposing 1 function each for compressed and uncompressed video
to figure out if the data flow metering requirement is met or not.

v2: Changed u32 to unsigned int, corrected patch 4 to address build
issue, addressed checkpatch issues, moved the drm_frl_dfm_helper under
kms_helpers section for compilation in the Makefile.

Ankit Nautiyal (1):
  drm/hdmi21: Add support for DFM calculation with DSC

Vandita Kulkarni (4):
  drm/hdmi21: Define frl_dfm structure
  drm/hdmi21: Add non dsc frl capacity computation helpers
  drm/hdmi21: Add helpers to verify non-dsc DFM requirements
  drm/hdmi21: Add frl_dfm_helper to Makefile

 drivers/gpu/drm/Makefile |   4 +-
 drivers/gpu/drm/drm_frl_dfm_helper.c | 854 +++
 include/drm/drm_frl_dfm_helper.h | 129 
 3 files changed, 986 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/drm_frl_dfm_helper.c
 create mode 100644 include/drm/drm_frl_dfm_helper.h

-- 
2.32.0



Re: [Intel-gfx] [PATCH 6/6] drm/i915: Pimp icl+ sagv pre/post update

2022-02-14 Thread Lisovskiy, Stanislav
On Mon, Feb 14, 2022 at 11:18:11AM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> Add some debugs on what exactly we're doing to the QGV point mask
> in the icl+ sagv pre/post plane update hooks. Currently we're just
> guessing.
> 
> Cc: Stanislav Lisovskiy 
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/intel_pm.c | 37 -
>  1 file changed, 18 insertions(+), 19 deletions(-)

Weird I think, I had those debugs initially. Definitely remember
there was something similar. Was it kinda removed later?

Stan

Reviewed-by: Stanislav Lisovskiy 
 
> 
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index 8b70cdc3b58b..5d1f1a9988bb 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3818,26 +3818,22 @@ static void icl_sagv_pre_plane_update(struct 
> intel_atomic_state *state)
>   intel_atomic_get_old_bw_state(state);
>   const struct intel_bw_state *new_bw_state =
>   intel_atomic_get_new_bw_state(state);
> - u32 new_mask;
> + u32 old_mask, new_mask;
>  
>   if (!new_bw_state)
>   return;
>  
> - /*
> -  * Nothing to mask
> -  */
> - if (new_bw_state->qgv_points_mask == old_bw_state->qgv_points_mask)
> - return;
> -
> + old_mask = old_bw_state->qgv_points_mask;
>   new_mask = old_bw_state->qgv_points_mask | 
> new_bw_state->qgv_points_mask;
>  
> - /*
> -  * If new mask is zero - means there is nothing to mask,
> -  * we can only unmask, which should be done in unmask.
> -  */
> - if (!new_mask)
> + if (old_mask == new_mask)
>   return;
>  
> + WARN_ON(!new_bw_state->base.changed);
> +
> + drm_dbg_kms(_priv->drm, "Restricting QGV points: 0x%x -> 0x%x\n",
> + old_mask, new_mask);
> +
>   /*
>* Restrict required qgv points before updating the configuration.
>* According to BSpec we can't mask and unmask qgv points at the same
> @@ -3854,19 +3850,22 @@ static void icl_sagv_post_plane_update(struct 
> intel_atomic_state *state)
>   intel_atomic_get_old_bw_state(state);
>   const struct intel_bw_state *new_bw_state =
>   intel_atomic_get_new_bw_state(state);
> - u32 new_mask = 0;
> + u32 old_mask, new_mask;
>  
>   if (!new_bw_state)
>   return;
>  
> - /*
> -  * Nothing to unmask
> -  */
> - if (new_bw_state->qgv_points_mask == old_bw_state->qgv_points_mask)
> - return;
> -
> + old_mask = old_bw_state->qgv_points_mask | 
> new_bw_state->qgv_points_mask;
>   new_mask = new_bw_state->qgv_points_mask;
>  
> + if (old_mask == new_mask)
> + return;
> +
> + WARN_ON(!new_bw_state->base.changed);
> +
> + drm_dbg_kms(_priv->drm, "Relaxing QGV points: 0x%x -> 0x%x\n",
> + old_mask, new_mask);
> +
>   /*
>* Allow required qgv points after updating the configuration.
>* According to BSpec we can't mask and unmask qgv points at the same
> -- 
> 2.34.1
> 


[Intel-gfx] [PATCH 5/6] drm/i915: Split pre-icl vs. icl+ SAGV hooks apart

2022-02-14 Thread Ville Syrjala
From: Ville Syrjälä 

To further reduce the confusion between the pre-icl vs. icl+
SAGV codepaths let's do a full split.

Cc: Stanislav Lisovskiy 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/intel_pm.c | 120 
 1 file changed, 77 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 068870b17c43..8b70cdc3b58b 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3785,34 +3785,44 @@ intel_disable_sagv(struct drm_i915_private *dev_priv)
return 0;
 }
 
-void intel_sagv_pre_plane_update(struct intel_atomic_state *state)
+static void skl_sagv_pre_plane_update(struct intel_atomic_state *state)
+{
+   struct drm_i915_private *i915 = to_i915(state->base.dev);
+   const struct intel_bw_state *new_bw_state =
+   intel_atomic_get_new_bw_state(state);
+
+   if (!new_bw_state)
+   return;
+
+   if (!intel_can_enable_sagv(i915, new_bw_state))
+   intel_disable_sagv(i915);
+}
+
+static void skl_sagv_post_plane_update(struct intel_atomic_state *state)
+{
+   struct drm_i915_private *i915 = to_i915(state->base.dev);
+   const struct intel_bw_state *new_bw_state =
+   intel_atomic_get_new_bw_state(state);
+
+   if (!new_bw_state)
+   return;
+
+   if (intel_can_enable_sagv(i915, new_bw_state))
+   intel_enable_sagv(i915);
+}
+
+static void icl_sagv_pre_plane_update(struct intel_atomic_state *state)
 {
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
-   const struct intel_bw_state *new_bw_state;
-   const struct intel_bw_state *old_bw_state;
-   u32 new_mask = 0;
+   const struct intel_bw_state *old_bw_state =
+   intel_atomic_get_old_bw_state(state);
+   const struct intel_bw_state *new_bw_state =
+   intel_atomic_get_new_bw_state(state);
+   u32 new_mask;
 
-   /*
-* Just return if we can't control SAGV or don't have it.
-* This is different from situation when we have SAGV but just can't
-* afford it due to DBuf limitation - in case if SAGV is completely
-* disabled in a BIOS, we are not even allowed to send a PCode request,
-* as it will throw an error. So have to check it here.
-*/
-   if (!intel_has_sagv(dev_priv))
-   return;
-
-   new_bw_state = intel_atomic_get_new_bw_state(state);
if (!new_bw_state)
return;
 
-   if (DISPLAY_VER(dev_priv) < 11) {
-   if (!intel_can_enable_sagv(dev_priv, new_bw_state))
-   intel_disable_sagv(dev_priv);
-   return;
-   }
-
-   old_bw_state = intel_atomic_get_old_bw_state(state);
/*
 * Nothing to mask
 */
@@ -3837,34 +3847,18 @@ void intel_sagv_pre_plane_update(struct 
intel_atomic_state *state)
icl_pcode_restrict_qgv_points(dev_priv, new_mask);
 }
 
-void intel_sagv_post_plane_update(struct intel_atomic_state *state)
+static void icl_sagv_post_plane_update(struct intel_atomic_state *state)
 {
struct drm_i915_private *dev_priv = to_i915(state->base.dev);
-   const struct intel_bw_state *new_bw_state;
-   const struct intel_bw_state *old_bw_state;
+   const struct intel_bw_state *old_bw_state =
+   intel_atomic_get_old_bw_state(state);
+   const struct intel_bw_state *new_bw_state =
+   intel_atomic_get_new_bw_state(state);
u32 new_mask = 0;
 
-   /*
-* Just return if we can't control SAGV or don't have it.
-* This is different from situation when we have SAGV but just can't
-* afford it due to DBuf limitation - in case if SAGV is completely
-* disabled in a BIOS, we are not even allowed to send a PCode request,
-* as it will throw an error. So have to check it here.
-*/
-   if (!intel_has_sagv(dev_priv))
-   return;
-
-   new_bw_state = intel_atomic_get_new_bw_state(state);
if (!new_bw_state)
return;
 
-   if (DISPLAY_VER(dev_priv) < 11) {
-   if (intel_can_enable_sagv(dev_priv, new_bw_state))
-   intel_enable_sagv(dev_priv);
-   return;
-   }
-
-   old_bw_state = intel_atomic_get_old_bw_state(state);
/*
 * Nothing to unmask
 */
@@ -3882,6 +3876,46 @@ void intel_sagv_post_plane_update(struct 
intel_atomic_state *state)
icl_pcode_restrict_qgv_points(dev_priv, new_mask);
 }
 
+void intel_sagv_pre_plane_update(struct intel_atomic_state *state)
+{
+   struct drm_i915_private *i915 = to_i915(state->base.dev);
+
+   /*
+* Just return if we can't control SAGV or don't have it.
+* This is different from situation when we have SAGV but just can't
+* afford it due to DBuf limitation - in case if SAGV is completely
+* 

[Intel-gfx] [PATCH 6/6] drm/i915: Pimp icl+ sagv pre/post update

2022-02-14 Thread Ville Syrjala
From: Ville Syrjälä 

Add some debugs on what exactly we're doing to the QGV point mask
in the icl+ sagv pre/post plane update hooks. Currently we're just
guessing.

Cc: Stanislav Lisovskiy 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/intel_pm.c | 37 -
 1 file changed, 18 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 8b70cdc3b58b..5d1f1a9988bb 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3818,26 +3818,22 @@ static void icl_sagv_pre_plane_update(struct 
intel_atomic_state *state)
intel_atomic_get_old_bw_state(state);
const struct intel_bw_state *new_bw_state =
intel_atomic_get_new_bw_state(state);
-   u32 new_mask;
+   u32 old_mask, new_mask;
 
if (!new_bw_state)
return;
 
-   /*
-* Nothing to mask
-*/
-   if (new_bw_state->qgv_points_mask == old_bw_state->qgv_points_mask)
-   return;
-
+   old_mask = old_bw_state->qgv_points_mask;
new_mask = old_bw_state->qgv_points_mask | 
new_bw_state->qgv_points_mask;
 
-   /*
-* If new mask is zero - means there is nothing to mask,
-* we can only unmask, which should be done in unmask.
-*/
-   if (!new_mask)
+   if (old_mask == new_mask)
return;
 
+   WARN_ON(!new_bw_state->base.changed);
+
+   drm_dbg_kms(_priv->drm, "Restricting QGV points: 0x%x -> 0x%x\n",
+   old_mask, new_mask);
+
/*
 * Restrict required qgv points before updating the configuration.
 * According to BSpec we can't mask and unmask qgv points at the same
@@ -3854,19 +3850,22 @@ static void icl_sagv_post_plane_update(struct 
intel_atomic_state *state)
intel_atomic_get_old_bw_state(state);
const struct intel_bw_state *new_bw_state =
intel_atomic_get_new_bw_state(state);
-   u32 new_mask = 0;
+   u32 old_mask, new_mask;
 
if (!new_bw_state)
return;
 
-   /*
-* Nothing to unmask
-*/
-   if (new_bw_state->qgv_points_mask == old_bw_state->qgv_points_mask)
-   return;
-
+   old_mask = old_bw_state->qgv_points_mask | 
new_bw_state->qgv_points_mask;
new_mask = new_bw_state->qgv_points_mask;
 
+   if (old_mask == new_mask)
+   return;
+
+   WARN_ON(!new_bw_state->base.changed);
+
+   drm_dbg_kms(_priv->drm, "Relaxing QGV points: 0x%x -> 0x%x\n",
+   old_mask, new_mask);
+
/*
 * Allow required qgv points after updating the configuration.
 * According to BSpec we can't mask and unmask qgv points at the same
-- 
2.34.1



[Intel-gfx] [PATCH 4/6] drm/i915: Unconfuse pre-icl vs. icl+ intel_sagv_{pre, post}_plane_update()

2022-02-14 Thread Ville Syrjala
From: Ville Syrjälä 

intel_sagv_{pre,post}_plane_update() can accidentally forget
to bail out early on pre-icl and proceed down the icl+ codepath
at the end of the function. Fortunately it'll bail out before
it gets too far due to old_qgv_mask==new_qgv_mask==0 so no real
bug here. But lets make the code less confusing anyway.

Cc: Stanislav Lisovskiy 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/intel_pm.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index d8eb553ffad3..068870b17c43 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3806,8 +3806,9 @@ void intel_sagv_pre_plane_update(struct 
intel_atomic_state *state)
if (!new_bw_state)
return;
 
-   if (DISPLAY_VER(dev_priv) < 11 && !intel_can_enable_sagv(dev_priv, 
new_bw_state)) {
-   intel_disable_sagv(dev_priv);
+   if (DISPLAY_VER(dev_priv) < 11) {
+   if (!intel_can_enable_sagv(dev_priv, new_bw_state))
+   intel_disable_sagv(dev_priv);
return;
}
 
@@ -3857,8 +3858,9 @@ void intel_sagv_post_plane_update(struct 
intel_atomic_state *state)
if (!new_bw_state)
return;
 
-   if (DISPLAY_VER(dev_priv) < 11 && intel_can_enable_sagv(dev_priv, 
new_bw_state)) {
-   intel_enable_sagv(dev_priv);
+   if (DISPLAY_VER(dev_priv) < 11) {
+   if (intel_can_enable_sagv(dev_priv, new_bw_state))
+   intel_enable_sagv(dev_priv);
return;
}
 
-- 
2.34.1



[Intel-gfx] [PATCH 3/6] drm/i915: Widen the QGV point mask

2022-02-14 Thread Ville Syrjala
From: Ville Syrjälä 

adlp+ adds some extra bits to the QGV point mask. The code attempts
to handle that but forgot to actually make sure we can store those
bits in the bw state. Fix it.

Cc: sta...@vger.kernel.org
Cc: Stanislav Lisovskiy 
Fixes: 192fbfb76744 ("drm/i915: Implement PSF GV point support")
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_bw.h | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_bw.h 
b/drivers/gpu/drm/i915/display/intel_bw.h
index 46c6eecbd917..0ceaed1c9656 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.h
+++ b/drivers/gpu/drm/i915/display/intel_bw.h
@@ -30,19 +30,19 @@ struct intel_bw_state {
 */
u8 pipe_sagv_reject;
 
+   /* bitmask of active pipes */
+   u8 active_pipes;
+
/*
 * Current QGV points mask, which restricts
 * some particular SAGV states, not to confuse
 * with pipe_sagv_mask.
 */
-   u8 qgv_points_mask;
+   u16 qgv_points_mask;
 
unsigned int data_rate[I915_MAX_PIPES];
u8 num_active_planes[I915_MAX_PIPES];
 
-   /* bitmask of active pipes */
-   u8 active_pipes;
-
int min_cdclk;
 };
 
-- 
2.34.1



[Intel-gfx] [PATCH 1/6] drm/i915: Correctly populate use_sagv_wm for all pipes

2022-02-14 Thread Ville Syrjala
From: Ville Syrjälä 

When changing between SAGV vs. no SAGV on tgl+ we have to
update the use_sagv_wm flag for all the crtcs or else
an active pipe not already in the state will end up using
the wrong watermarks. That is especially bad when we end up
with the tighter non-SAGV watermarks with SAGV enabled.
Usually ends up in underruns.

Cc: sta...@vger.kernel.org
Cc: Stanislav Lisovskiy 
Fixes: 7241c57d3140 ("drm/i915: Add TGL+ SAGV support")
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/intel_pm.c | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 1179bf31f743..d8eb553ffad3 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4009,6 +4009,17 @@ static int intel_compute_sagv_mask(struct 
intel_atomic_state *state)
return ret;
}
 
+   if (intel_can_enable_sagv(dev_priv, new_bw_state) !=
+   intel_can_enable_sagv(dev_priv, old_bw_state)) {
+   ret = intel_atomic_serialize_global_state(_bw_state->base);
+   if (ret)
+   return ret;
+   } else if (new_bw_state->pipe_sagv_reject != 
old_bw_state->pipe_sagv_reject) {
+   ret = intel_atomic_lock_global_state(_bw_state->base);
+   if (ret)
+   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;
@@ -4024,17 +4035,6 @@ static int intel_compute_sagv_mask(struct 
intel_atomic_state *state)
intel_can_enable_sagv(dev_priv, new_bw_state);
}
 
-   if (intel_can_enable_sagv(dev_priv, new_bw_state) !=
-   intel_can_enable_sagv(dev_priv, old_bw_state)) {
-   ret = intel_atomic_serialize_global_state(_bw_state->base);
-   if (ret)
-   return ret;
-   } else if (new_bw_state->pipe_sagv_reject != 
old_bw_state->pipe_sagv_reject) {
-   ret = intel_atomic_lock_global_state(_bw_state->base);
-   if (ret)
-   return ret;
-   }
-
return 0;
 }
 
-- 
2.34.1



[Intel-gfx] [PATCH 2/6] drm/i915: Fix bw atomic check when switching between SAGV vs. no SAGV

2022-02-14 Thread Ville Syrjala
From: Ville Syrjälä 

If the only thing that is changing is SAGV vs. no SAGV but
the number of active planes and the total data rates end up
unchanged we currently bail out of intel_bw_atomic_check()
early and forget to actually compute the new WGV point
mask and thus won't actually enable/disable SAGV as requested.
This ends up poorly if we end up running with SAGV enabled
when we shouldn't. Usually ends up in underruns.
To fix this let's go through the QGV point mask computation
if anyone else already added the bw state for us.

Cc: sta...@vger.kernel.org
Cc: Stanislav Lisovskiy 
Fixes: 20f505f22531 ("drm/i915: Restrict qgv points which don't have enough 
bandwidth.")
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/display/intel_bw.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_bw.c 
b/drivers/gpu/drm/i915/display/intel_bw.c
index 23aa8e06de18..d72ccee7d53b 100644
--- a/drivers/gpu/drm/i915/display/intel_bw.c
+++ b/drivers/gpu/drm/i915/display/intel_bw.c
@@ -846,6 +846,13 @@ int intel_bw_atomic_check(struct intel_atomic_state *state)
if (num_psf_gv_points > 0)
mask |= REG_GENMASK(num_psf_gv_points - 1, 0) << 
ADLS_PSF_PT_SHIFT;
 
+   /*
+* If we already have the bw state then recompute everything
+* even if pipe data_rate / active_planes didn't change.
+* Other things (such as SAGV) may have changed.
+*/
+   new_bw_state = intel_atomic_get_new_bw_state(state);
+
for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
new_crtc_state, i) {
unsigned int old_data_rate =
-- 
2.34.1



[Intel-gfx] [PATCH 0/6] drm/i915: SAGV fixes

2022-02-14 Thread Ville Syrjala
From: Ville Syrjälä 

While pokingaround the watermarks/etc. I noticed our SAGV code
has a bunch of bugs. Let's try to fix it.

Cc: Stanislav Lisovskiy 

Ville Syrjälä (6):
  drm/i915: Correctly populate use_sagv_wm for all pipes
  drm/i915: Fix bw atomic check when switching between SAGV vs. no SAGV
  drm/i915: Widen the QGV point mask
  drm/i915: Unconfuse pre-icl vs. icl+
intel_sagv_{pre,post}_plane_update()
  drm/i915: Split pre-icl vs. icl+ SAGV hooks apart
  drm/i915: Pimp icl+ sagv pre/post update

 drivers/gpu/drm/i915/display/intel_bw.c |   7 +
 drivers/gpu/drm/i915/display/intel_bw.h |   8 +-
 drivers/gpu/drm/i915/intel_pm.c | 175 ++--
 3 files changed, 116 insertions(+), 74 deletions(-)

-- 
2.34.1



Re: [Intel-gfx] [PATCH v12 1/5] drm: improve drm_buddy_alloc function

2022-02-14 Thread Matthew Auld
On Mon, 14 Feb 2022 at 06:32, Christian König
 wrote:
>
> Am 13.02.22 um 09:52 schrieb Arunpravin:
> > - Make drm_buddy_alloc a single function to handle
> >range allocation and non-range allocation demands
> >
> > - Implemented a new function alloc_range() which allocates
> >the requested power-of-two block comply with range limitations
> >
> > - Moved order computation and memory alignment logic from
> >i915 driver to drm buddy
> >
> > v2:
> >merged below changes to keep the build unbroken
> > - drm_buddy_alloc_range() becomes obsolete and may be removed
> > - enable ttm range allocation (fpfn / lpfn) support in i915 driver
> > - apply enhanced drm_buddy_alloc() function to i915 driver
> >
> > v3(Matthew Auld):
> >- Fix alignment issues and remove unnecessary list_empty check
> >- add more validation checks for input arguments
> >- make alloc_range() block allocations as bottom-up
> >- optimize order computation logic
> >- replace uint64_t with u64, which is preferred in the kernel
> >
> > v4(Matthew Auld):
> >- keep drm_buddy_alloc_range() function implementation for generic
> >  actual range allocations
> >- keep alloc_range() implementation for end bias allocations
> >
> > v5(Matthew Auld):
> >- modify drm_buddy_alloc() passing argument place->lpfn to lpfn
> >  as place->lpfn will currently always be zero for i915
> >
> > v6(Matthew Auld):
> >- fixup potential uaf - If we are unlucky and can't allocate
> >  enough memory when splitting blocks, where we temporarily
> >  end up with the given block and its buddy on the respective
> >  free list, then we need to ensure we delete both blocks,
> >  and no just the buddy, before potentially freeing them
> >
> >- fix warnings reported by kernel test robot 
> >
> > v7(Matthew Auld):
> >- revert fixup potential uaf
> >- keep __alloc_range() add node to the list logic same as
> >  drm_buddy_alloc_blocks() by having a temporary list variable
> >- at drm_buddy_alloc_blocks() keep i915 range_overflows macro
> >  and add a new check for end variable
> >
> > v8:
> >- fix warnings reported by kernel test robot 
> >
> > v9(Matthew Auld):
> >- remove DRM_BUDDY_RANGE_ALLOCATION flag
> >- remove unnecessary function description
> >
> > Signed-off-by: Arunpravin 
> > Reviewed-by: Matthew Auld 
>
> As long as nobody objects I'm going to push patches 1-3 to drm-misc-next
> in the next hour or so:

As part of this could you also push
https://patchwork.freedesktop.org/series/99842/ ?

>
> Then going to take a deeper look into patches 4 and 5 to get them reviewed.
>
> Thanks,
> Christian.
>
> > ---
> >   drivers/gpu/drm/drm_buddy.c   | 292 +-
> >   drivers/gpu/drm/i915/i915_ttm_buddy_manager.c |  63 ++--
> >   drivers/gpu/drm/i915/i915_ttm_buddy_manager.h |   2 +
> >   include/drm/drm_buddy.h   |  11 +-
> >   4 files changed, 250 insertions(+), 118 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_buddy.c b/drivers/gpu/drm/drm_buddy.c
> > index d60878bc9c20..e0c0d786a572 100644
> > --- a/drivers/gpu/drm/drm_buddy.c
> > +++ b/drivers/gpu/drm/drm_buddy.c
> > @@ -282,23 +282,97 @@ void drm_buddy_free_list(struct drm_buddy *mm, struct 
> > list_head *objects)
> >   }
> >   EXPORT_SYMBOL(drm_buddy_free_list);
> >
> > -/**
> > - * drm_buddy_alloc_blocks - allocate power-of-two blocks
> > - *
> > - * @mm: DRM buddy manager to allocate from
> > - * @order: size of the allocation
> > - *
> > - * The order value here translates to:
> > - *
> > - * 0 = 2^0 * mm->chunk_size
> > - * 1 = 2^1 * mm->chunk_size
> > - * 2 = 2^2 * mm->chunk_size
> > - *
> > - * Returns:
> > - * allocated ptr to the _buddy_block on success
> > - */
> > -struct drm_buddy_block *
> > -drm_buddy_alloc_blocks(struct drm_buddy *mm, unsigned int order)
> > +static inline bool overlaps(u64 s1, u64 e1, u64 s2, u64 e2)
> > +{
> > + return s1 <= e2 && e1 >= s2;
> > +}
> > +
> > +static inline bool contains(u64 s1, u64 e1, u64 s2, u64 e2)
> > +{
> > + return s1 <= s2 && e1 >= e2;
> > +}
> > +
> > +static struct drm_buddy_block *
> > +alloc_range_bias(struct drm_buddy *mm,
> > +  u64 start, u64 end,
> > +  unsigned int order)
> > +{
> > + struct drm_buddy_block *block;
> > + struct drm_buddy_block *buddy;
> > + LIST_HEAD(dfs);
> > + int err;
> > + int i;
> > +
> > + end = end - 1;
> > +
> > + for (i = 0; i < mm->n_roots; ++i)
> > + list_add_tail(>roots[i]->tmp_link, );
> > +
> > + do {
> > + u64 block_start;
> > + u64 block_end;
> > +
> > + block = list_first_entry_or_null(,
> > +  struct drm_buddy_block,
> > +  tmp_link);
> > + if (!block)
> > + break;
> > +
> > + list_del(>tmp_link);
> > +
> > +