Re: [PATCH v2 1/3] drm/msm/mdss: convert UBWC setup to use match data

2023-01-23 Thread Dmitry Baryshkov

On 24/01/2023 03:48, Abhinav Kumar wrote:



On 1/19/2023 9:26 PM, Dmitry Baryshkov wrote:
On Fri, 20 Jan 2023 at 00:54, Abhinav Kumar 
 wrote:




On 1/17/2023 5:04 PM, Dmitry Baryshkov wrote:

To simplify adding new platforms and to make settings more obvious,
rewrite the UBWC setup to use the data structure to pass platform 
config

rather than just calling the functions direcly.

Signed-off-by: Dmitry Baryshkov 


I was reviewing this series and
https://patchwork.freedesktop.org/series/111732/ together.

More I think about it, it seems like we are duplicating the same values
here and in the catalog.

Yes, these two are different drivers.

But now that you are adding the UBWC entries here using the compatible
string so you are creating something like a "catalog" here.

In that case, why dont we remove the entries from dpu catalog and in the
DPU driver get the parent's match data as we know that the msm_mdss is
the parent of DPU driver


I should give it a thought, especially since we are trying to clean up
the DPU catalog.


I just went through the cover letter of 
https://patchwork.freedesktop.org/patch/519752/ and it mentions


"My itent is to land both series and then to make
DPU request this data from the MDSS driver"

This means that the parent data suggestion will be implemented?


Yes, at some point. You probably saw the dpu_ubwc_cfg structure. As I 
wrote, I'd like to get it from MDSS. Just looking for a best way to do this.



--
With best wishes
Dmitry



Re: [PATCH v2 1/8] drm/i915: Add _PICK_EVEN_2RANGES()

2023-01-23 Thread Lucas De Marchi

(I missed this review you did before I had sent a v2.1, I will incorporate
what is missing in the next version)

On Mon, Jan 23, 2023 at 12:38:28PM +0200, Jani Nikula wrote:

On Fri, 20 Jan 2023, Lucas De Marchi  wrote:

It's a constant pattern in the driver to need to use 2 ranges of MMIOs
based on port, phy, pll, etc. When that happens, instead of using
_PICK_EVEN(), _PICK() needs to be used.  Using _PICK() is discouraged
due to some reasons like:

1) It increases the code size since the array is declared
   in each call site


Would be interesting to see what this does, and whether the compiler has
the smarts to combine these within each file:

-#define _PICK(__index, ...) (((const u32 []){ __VA_ARGS__ })[__index])
+#define _PICK(__index, ...) (((static const u32 []){ __VA_ARGS__ })[__index])


if the compiler is smart, it would be at least 1 per compilation unit.
gcc doesn't seem smart enough to even compile it though:

../drivers/gpu/drm/i915/i915_reg_defs.h:155:52: error: expected ‘)’ before ‘{’ token   
  155 | #define _PICK(__index, ...) (((static const u32 []){ __VA_ARGS__ })[__index])  
  |  ~ ^


What I'm thinking for the remaining uses of _PICK() is to be explicit
and statically define them in a good .c depending on the use.
Then use that in the macro.




2) Developers need to be careful not to incur an
   out-of-bounds array access
3) Developers need to be careful that the indexes match the
   table. For that it may be that the table needs to contain
   holes, making (1) even worse.

Add a variant of _PICK_EVEN() that works with 2 ranges and selects which
one to use depending on the index value.

Signed-off-by: Lucas De Marchi 
---
 drivers/gpu/drm/i915/i915_reg_defs.h | 28 
 1 file changed, 28 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg_defs.h 
b/drivers/gpu/drm/i915/i915_reg_defs.h
index be43580a6979..b7ec87464d69 100644
--- a/drivers/gpu/drm/i915/i915_reg_defs.h
+++ b/drivers/gpu/drm/i915/i915_reg_defs.h
@@ -119,6 +119,34 @@
  */
 #define _PICK_EVEN(__index, __a, __b) ((__a) + (__index) * ((__b) - (__a)))

+/*
+ * Like _PICK_EVEN(), but supports 2 ranges of evenly spaced address offsets.
+ * The first range is used for indexes below @__c_index, and the second
+ * range is used for anything above it. Example::


I'd like this to be clear about which range is used for index ==
__c_index, instead of saying "below" and "above".

No need for the double colon :: because this isn't a kernel-doc comment.


ok, what about this?

 * Like _PICK_EVEN(), but supports 2 ranges of evenly spaced address offsets.
 * @__c_index corresponds to the index in which the second range starts
 * to be used. Using math interval notation, the first range is used
 * for indexes [ 0, @__c_index), while the second range is used for
 * [ @__c_index, ... ). Example:





+ *
+ * #define _FOO_A  0xf000
+ * #define _FOO_B  0xf004
+ * #define _FOO_C  0xf008
+ * #define _SUPER_FOO_A0xa000
+ * #define _SUPER_FOO_B0xa100
+ * #define FOO(x)  _MMIO(_PICK_EVEN_RANGES(x, 3,   
\


The example uses a different name for the macro.


yeah, that was the previous name I was using... good catch, will fix.




+ *   _FOO_A, _FOO_B,   
\
+ *   _SUPER_FOO_A, _SUPER_FOO_B))
+ *
+ * This expands to:
+ * 0: 0xf000,
+ * 1: 0xf004,
+ * 2: 0xf008,
+ * 3: 0xa100,


With the above definitions, this would be 3: 0xa000.


fixed


thanks
Lucas De Marchi




+ * 4: 0xa200,
+ * 5: 0xa300,
+ * ...
+ */
+#define _PICK_EVEN_2RANGES(__index, __c_index, __a, __b, __c, __d) 
\
+   (BUILD_BUG_ON_ZERO(!__is_constexpr(__c_index)) +
\
+((__index) < (__c_index) ? _PICK_EVEN(__index, __a, __b) :  \
+  _PICK_EVEN((__index) - (__c_index), __c, 
__d)))
+
 /*
  * Given the arbitrary numbers in varargs, pick the 0-based __index'th number.
  *


--
Jani Nikula, Intel Open Source Graphics Center


Re: DMA-heap driver hints

2023-01-23 Thread Christian König

Am 24.01.23 um 04:56 schrieb James Jones:

On 1/23/23 08:58, Laurent Pinchart wrote:

Hi Christian,

On Mon, Jan 23, 2023 at 05:29:18PM +0100, Christian König wrote:

Am 23.01.23 um 14:55 schrieb Laurent Pinchart:

Hi Christian,

CC'ing James as I think this is related to his work on the unix device
memory allocator ([1]).


Thank you for including me.


Sorry for not having you in initially. I wasn't aware of your previous 
work in this area.




[1] 
https://lore.kernel.org/dri-devel/8b555674-1c5b-c791-4547-2ea7c16ae...@nvidia.com/


On Mon, Jan 23, 2023 at 01:37:54PM +0100, Christian König wrote:

Hi guys,

this is just an RFC! The last time we discussed the DMA-buf coherency
problem [1] we concluded that DMA-heap first needs a better way to
communicate to userspace which heap to use for a certain device.

As far as I know userspace currently just hard codes that information
which is certainly not desirable considering that we should have this
inside the kernel as well.

So what those two patches here do is to first add some
dma_heap_create_device_link() and dma_heap_remove_device_link()
function and then demonstrating the functionality with uvcvideo
driver.

The preferred DMA-heap is represented with a symlink in sysfs between
the device and the virtual DMA-heap device node.


I'll start with a few high-level comments/questions:

- Instead of tying drivers to heaps, have you considered a system 
where
    a driver would expose constraints, and a heap would then be 
selected

    based on those constraints ? A tight coupling between heaps and
    drivers means downstream patches to drivers in order to use
    vendor-specific heaps, that sounds painful.


I was wondering the same thing as well, but came to the conclusion that
just the other way around is the less painful approach.


 From a kernel point of view, sure, it's simpler and thus less painful.
 From the point of view of solving the whole issue, I'm not sure :-)


The problem is that there are so many driver specific constrains that I
don't even know where to start from.


That's where I was hoping James would have some feedback for us, based
on the work he did on the Unix device memory allocator. If that's not
the case, we can brainstorm this from scratch.


Simon Ser's and my presentation from XDC 2020 focused entirely on 
this. The idea was not to try to enumerate every constraint up front, 
but rather to develop an extensible mechanism that would be flexible 
enough to encapsulate many disparate types of constraints and perform 
set operations on them (merging sets was the only operation we tried 
to solve). Simon implemented a prototype header-only library to 
implement the mechanism:


https://gitlab.freedesktop.org/emersion/drm-constraints

The links to the presentation and talk are below, along with notes 
from the follow-up workshop.


https://lpc.events/event/9/contributions/615/attachments/704/1301/XDC_2020__Allocation_Constraints.pdf 


https://www.youtube.com/watch?v=HZEClOP5TIk
https://paste.sr.ht/~emersion/c43b30be08bab1882f1b107402074462bba3b64a

Note one of the hard parts of this was figuring out how to express a 
device or heap within the constraint structs. One of the better ideas 
proposed back then was something like heap IDs, where dma heaps would 
each have one,


We already have that. Each dma_heap has it's own unique name.

and devices could register their own heaps (or even just themselves?) 
with the heap subsystem and be assigned a locally-unique ID that 
userspace could pass around.


I was more considering that we expose some kind of flag noting that a 
certain device needs its buffer allocated from that device to utilize 
all use cases.


This sounds similar to what you're proposing. Perhaps a reasonable 
identifier is a device (major, minor) pair. Such a constraint could be 
expressed as a symlink for easy visualization/discoverability from 
userspace, but might be easier to serialize over the wire as the 
(major, minor) pair. I'm not clear which direction is better to 
express this either: As a link from heap->device, or device->heap.



    A constraint-based system would also, I think, be easier to extend
    with additional constraints in the future.

- I assume some drivers will be able to support multiple heaps. How do
    you envision this being implemented ?


I don't really see an use case for this.


One use case I know of here is same-vendor GPU local memory on 
different GPUs. NVIDIA GPUs have certain things they can only do on 
local memory, certain things they can do on all memory, and certain 
things they can only do on memory local to another NVIDIA GPU, 
especially when there exists an NVLink interface between the two. So 
they'd ideally express different constraints for heap representing 
each of those.


I strongly think that exposing this complexity is overkill. We have 
pretty much the same on AMD GPUs with XGMI, but this is so vendor 
specific that I'm pretty sure we shouldn't have that in 

Re: [PATCH v1 10/14] drm/msm/disp/dpu: add supports of DSC encoder v1.2 engine

2023-01-23 Thread Dmitry Baryshkov

On 23/01/2023 20:24, Kuogee Hsieh wrote:

DSC V1.2 encoder engine is newly added hardware module. This patch
add support functions to configure and enable DSC V1.2 encoder engine.

Signed-off-by: Kuogee Hsieh 
---
  drivers/gpu/drm/msm/Makefile   |   1 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c|   2 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |  60 +++-
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c |  23 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h |  23 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c | 371 +
  6 files changed, 463 insertions(+), 17 deletions(-)
  create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 28cf52b..271c29a15 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -65,6 +65,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \
disp/dpu1/dpu_hw_catalog.o \
disp/dpu1/dpu_hw_ctl.o \
disp/dpu1/dpu_hw_dsc.o \
+   disp/dpu1/dpu_hw_dsc_1_2.o \
disp/dpu1/dpu_dsc_helper.o \
disp/dpu1/dpu_hw_interrupts.o \
disp/dpu1/dpu_hw_intf.o \
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 7f4a439..901e317 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1821,7 +1821,7 @@ static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc 
*hw_dsc,
 u32 initial_lines)
  {
if (hw_dsc->ops.dsc_config)
-   hw_dsc->ops.dsc_config(hw_dsc, dsc, common_mode, initial_lines);
+   hw_dsc->ops.dsc_config(hw_dsc, dsc, common_mode, initial_lines, 
false);
  
  	if (hw_dsc->ops.dsc_config_thresh)

hw_dsc->ops.dsc_config_thresh(hw_dsc, dsc);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
index 978e3bd..7b0b092 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -1,6 +1,6 @@
  /* SPDX-License-Identifier: GPL-2.0-only */
  /*
- * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights 
reserved.
   * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
   */
  
@@ -11,6 +11,7 @@

  #include 
  #include 
  #include 
+#include "dpu_hw_mdss.h"
  
  /**

   * Max hardware block count: For ex: max 12 SSPP pipes or
@@ -182,6 +183,7 @@ enum {
   * @DPU_PINGPONG_TE2Additional tear check block for split pipes
   * @DPU_PINGPONG_SPLIT  PP block supports split fifo
   * @DPU_PINGPONG_SLAVE  PP block is a suitable slave for split fifo
+ * @DPU_PINGPONG_DSC,   Display stream compression blocks
   * @DPU_PINGPONG_DITHER,Dither blocks
   * @DPU_PINGPONG_MAX
   */
@@ -190,10 +192,32 @@ enum {
DPU_PINGPONG_TE2,
DPU_PINGPONG_SPLIT,
DPU_PINGPONG_SLAVE,
+   DPU_PINGPONG_DSC,
DPU_PINGPONG_DITHER,
DPU_PINGPONG_MAX
  };
  
+

+/** DSC sub-blocks/features
+ * @DPU_DSC_OUTPUT_CTRL Supports the control of the pp id which gets
+ *  the pixel output from this DSC.
+ * @DPU_DSC_HW_REV_1_1  dsc block supports dsc 1.1 only
+ * @DPU_DSC_HW_REV_1_2  dsc block supports dsc 1.1 and 1.2
+ * @DPU_DSC_NATIVE_422_EN,  Supports native422 and native420 encoding
+ * @DPU_DSC_ENC,DSC encoder sub block
+ * @DPU_DSC_CTL,DSC ctl sub block
+ * @DPU_DSC_MAX
+ */
+enum {
+   DPU_DSC_OUTPUT_CTRL = 0x1,
+   DPU_DSC_HW_REV_1_1,
+   DPU_DSC_HW_REV_1_2,
+   DPU_DSC_NATIVE_422_EN,
+   DPU_DSC_ENC,
+   DPU_DSC_CTL,
+   DPU_DSC_MAX
+};
+
  /**
   * CTL sub-blocks
   * @DPU_CTL_SPLIT_DISPLAY:CTL supports video mode split display
@@ -276,15 +300,6 @@ enum {
  };
  
  /**

- * DSC features
- * @DPU_DSC_OUTPUT_CTRL   Configure which PINGPONG block gets
- *the pixel output from this DSC.
- */
-enum {
-   DPU_DSC_OUTPUT_CTRL = 0x1,
-};
-


Any reason for this move?


-/**
   * MACRO DPU_HW_BLK_INFO - information of HW blocks inside DPU
   * @name:  string name for debug purposes
   * @id:enum identifying this block
@@ -346,6 +361,14 @@ struct dpu_pp_blk {
  };
  
  /**

+ * struct dpu_dsc_blk : DSC Encoder sub-blk information
+ * @info:   HW register and features supported by this sub-blk
+ */
+struct dpu_dsc_blk {
+   DPU_HW_SUBBLK_INFO;
+};
+
+/**
   * enum dpu_qos_lut_usage - define QoS LUT use cases
   */
  enum dpu_qos_lut_usage {
@@ -403,6 +426,7 @@ struct dpu_rotation_cfg {
   * @pixel_ram_size size of latency hiding and de-tiling buffer in bytes
   * @max_hdeci_exp  max horizontal decimation supported (max is 2^value)
   * @max_vdeci_exp  max vertical decimation 

Re: [PATCH 2/2] drm: lcdif: Add i.MX93 LCDIF support

2023-01-23 Thread Liu Ying
On Mon, 2023-01-23 at 09:13 +0100, Lothar Waßmann wrote:
> Hi,

Hi,

> 
> On Mon, 23 Jan 2023 15:23:58 +0800 Liu Ying wrote:
> > The LCDIF embedded in i.MX93 SoC is essentially the same to those
> > in i.MX8mp SoC.  However, i.MX93 LCDIF may connect with MIPI DSI
> > controller through LCDIF cross line pattern(controlled by mediamix
> > blk-ctrl) or connect with LVDS display bridge(LDB) directly or a
> > parallel display(also through mediamix blk-ctrl), so add multiple
> > encoders(with DRM_MODE_ENCODER_NONE encoder type) support in the
> > LCDIF DRM driver and find a bridge to attach the relevant encoder's
> > chain when needed.  While at it, derive lcdif_crtc_state structure
> > from drm_crtc_state structure to introduce bus_format and bus_flags
> > states so that the next downstream bridges may use consistent bus
> > format and bus flags.
> > 
> > Signed-off-by: Liu Ying 
> > ---
> >  drivers/gpu/drm/mxsfb/lcdif_drv.c |  73 +--
> >  drivers/gpu/drm/mxsfb/lcdif_drv.h |   6 +-
> >  drivers/gpu/drm/mxsfb/lcdif_kms.c | 206 
> > --
> >  3 files changed, 208 insertions(+), 77 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/mxsfb/lcdif_drv.c
> > b/drivers/gpu/drm/mxsfb/lcdif_drv.c
> > index cc2ceb301b96..4d41f6b6eb14 100644
> > --- a/drivers/gpu/drm/mxsfb/lcdif_drv.c
> > +++ b/drivers/gpu/drm/mxsfb/lcdif_drv.c
> > @@ -9,13 +9,16 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> >  
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  #include 
> >  #include 
> > @@ -38,21 +41,70 @@ static const struct
> > drm_mode_config_helper_funcs lcdif_mode_config_helpers = {
> > .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
> >  };
> >  
> > +static const struct drm_encoder_funcs lcdif_encoder_funcs = {
> > +   .destroy = drm_encoder_cleanup,
> > +};
> > +
> >  static int lcdif_attach_bridge(struct lcdif_drm_private *lcdif)
> >  {
> > -   struct drm_device *drm = lcdif->drm;
> > +   struct device *dev = lcdif->drm->dev;
> > +   struct device_node *ep;
> > struct drm_bridge *bridge;
> > int ret;
> >  
> > -   bridge = devm_drm_of_get_bridge(drm->dev, drm->dev->of_node, 0,
> > 0);
> > -   if (IS_ERR(bridge))
> > -   return PTR_ERR(bridge);
> > -
> > -   ret = drm_bridge_attach(>encoder, bridge, NULL, 0);
> > -   if (ret)
> > -   return dev_err_probe(drm->dev, ret, "Failed to attach
> > bridge\n");
> > -
> > -   lcdif->bridge = bridge;
> > +   for_each_endpoint_of_node(dev->of_node, ep) {
> > +   struct device_node *remote;
> > +   struct of_endpoint of_ep;
> > +   struct drm_encoder *encoder;
> > +
> > +   remote = of_graph_get_remote_port_parent(ep);
> > +   if (!remote || !of_device_is_available(remote)) {
> 
> '!remote ||' is redundant, since of_device_is_available already
> checks
> for a NULL pointer.

of_device_is_available() does check for a NULL pointer when it calls
__of_device_is_available() (after it takes devtree_lock raw spinlock
and then releases devtree_lock).  So, if remote is NULL, '!remote ||'
exits the if clause a bit earlier without calling
of_device_is_available() to take/release devtree_lock, which means a
little bit better performance.  But, people may say that the
performance gain is trivial. drm_of_component_probe() in drm_of.c also 
checks '!remote' before checking '!of_device_is_available(remote)'. Do
you still think that both drm_of_component_probe() and
lcdif_attach_bridge() should drop '!remote ||'?

> 
> [...]
> 
> > diff --git a/drivers/gpu/drm/mxsfb/lcdif_kms.c
> > b/drivers/gpu/drm/mxsfb/lcdif_kms.c
> > index 262bc43b1079..ba36447ed900 100644
> > --- a/drivers/gpu/drm/mxsfb/lcdif_kms.c
> > +++ b/drivers/gpu/drm/mxsfb/lcdif_kms.c
> 
> [...]
> > @@ -529,6 +580,46 @@ static void lcdif_crtc_atomic_disable(struct
> > drm_crtc *crtc,
> > pm_runtime_put_sync(drm->dev);
> >  }
> >  
> > +static void lcdif_crtc_reset(struct drm_crtc *crtc)
> > +{
> > +   struct lcdif_crtc_state *state;
> > +
> > +   if (crtc->state)
> > +   __drm_atomic_helper_crtc_destroy_state(crtc->state);
> > +
> > +   kfree(to_lcdif_crtc_state(crtc->state));
> > 
> 
> If crtc-state can be NULL at this point, this will only work as long
> as
> 'base' is the first member of the lcdif_crtc_state struct (which
> currently is the case, but there is no guarantee that this will
> always
> be this way), otherwise the if clause above is not needed.

crtc->state can be NULL when e.g. at driver load time, like kerneldoc
for drm_atomic_helper_crtc_reset() mentions.  I may add a comment for
the 'base' member to note that it should be always the first member of
the lcdif_crtc_state structure.  Do you think that will be ok?

Thanks,
Liu Ying

> 
> 
> 
> Lothar Waßmann



Re: DMA-heap driver hints

2023-01-23 Thread Christian König

Am 24.01.23 um 06:19 schrieb John Stultz:

On Mon, Jan 23, 2023 at 8:29 AM Christian König
 wrote:

Am 23.01.23 um 14:55 schrieb Laurent Pinchart:

- I assume some drivers will be able to support multiple heaps. How do
you envision this being implemented ?

I don't really see an use case for this.

We do have some drivers which say: for this use case you can use
whatever you want, but for that use case you need to use specific memory
(scan out on GPUs for example works like this).


[snipping the constraints argument, which I agree with]

What we do have is compatibility between heaps. E.g. a CMA heap is
usually compatible with the system heap or might even be a subset of
another CMA heap. But I wanted to add that as next step to the heaps
framework itself.

So the difficult question is how is userland supposed to know which
heap is compatible with which?


The heaps should know which other heap they are compatible with.

E.g. the CMA heap should have a link to the system heap because it can 
handle all system memory allocations as well.


If we have a specialized CMA heap (for example for 32bit DMA) it should 
have a link to the general CMA heap.



If you have two devices, one that points to heap "foo" and the other
points to heap "bar", how does userland know that "foo" satisfies the
constraints of "bar" but "bar" doesn't satisfy the constraints of
"foo".
(foo ="cma",  bar="system")

I think it would be much better for device 1 to list "foo" and device
2 to list "foo" and "bar", so you can find that "foo" is the common
heap which will solve both devices' needs.


I think that this would be a rather bad idea because then all devices 
need to know about all the possible different heaps they are compatible 
with.


For example a device which knows that it's compatible with system memory 
should only expose that information.


That a CMA heap is also compatible with system memory is irrelevant for 
this device and should be handled between the CMA and system heap.



- Devices could have different constraints based on particular
configurations. For instance, a device may require specific memory
layout for multi-planar YUV formats only (as in allocating the Y and C
planes of NV12 from different memory banks). A dynamic API may thus be
needed (but may also be very painful to use from userspace).

Uff, good to know. But I'm not sure how to expose stuff like that.

Yeah. These edge cases are really hard to solve generically.  And
single devices that have separate constraints for different uses are
also not going to be solvable with a simple linking approach.

But I do wonder if a generic solution to all cases is needed
(especially if it really isn't possible)? If we leave the option for
gralloc like omniscient device-specific userland policy, those edge
cases can be handled by those devices that can't run generic logic.
And those devices just won't be able to be supported by generic
distros, hopefully motivating future designs to have less odd
constraints?


Potentially yes, but I think that anything more complex than "please 
allocate from this piece of memory for me" is not something which should 
be handled inside the device independent framework.


Especially device specific memory and allocation constrains (e.g. things 
like don't put those two things on the same memory channel) is *not* 
something we should have in an inter device framework.


In those cases we should just be able to say that an allocation should 
be made from a specific device and then let the device specific drivers 
deal with the constrain.


Regards,
Christian.



thanks
-john




Re: [PATCH v6 3/5] drm/tidss: Add support to configure OLDI mode for am625-dss.

2023-01-23 Thread Aradhya Bhatia

Hi Tomi,

Thanks for reviewing the patch series. I have implemented the most of
your suggestions, but for the others, I needed to clarify things. I have
made some comments there.

On 20-Dec-22 18:22, Tomi Valkeinen wrote:

Hi,

On 19/11/2022 19:30, Aradhya Bhatia wrote:

The newer version of DSS (AM625-DSS) has 2 OLDI TXes at its disposal.
These can be configured to support the following modes:

1. OLDI_SINGLE_LINK_SINGLE_MODE
Single Output over OLDI 0.
+--+    +-+  +---+
|  |    | |  |   |
| CRTC +--->+ ENCODER +->| PANEL |
|  |    | |  |   |
+--+    +-+  +---+

2. OLDI_SINGLE_LINK_CLONE_MODE
Duplicate Output over OLDI 0 and 1.
+--+    +-+  +---+
|  |    | |  |   |
| CRTC +---+--->| ENCODER +->| PANEL |
|  |   |    | |  |   |
+--+   |    +-+  +---+
    |
    |    +-+  +---+
    |    | |  |   |
    +--->| ENCODER +->| PANEL |
 | |  |   |
 +-+  +---+

3. OLDI_DUAL_LINK_MODE
Combined Output over OLDI 0 and 1.
+--+    +-+  +---+
|  |    | +->|   |
| CRTC +--->+ ENCODER |  | PANEL |
|  |    | +->|   |
+--+    +-+  +---+

Following the above pathways for different modes, 2 encoder/panel-bridge
pipes get created for clone mode, and 1 pipe in cases of single link and
dual link mode.

Add support for confguring the OLDI modes using OF and LVDS DRM helper
functions.

Signed-off-by: Aradhya Bhatia 
---
  drivers/gpu/drm/tidss/tidss_dispc.c   |  12 ++
  drivers/gpu/drm/tidss/tidss_dispc.h   |   9 ++
  drivers/gpu/drm/tidss/tidss_drv.h |   3 +
  drivers/gpu/drm/tidss/tidss_encoder.c |   4 +-
  drivers/gpu/drm/tidss/tidss_encoder.h |   3 +-
  drivers/gpu/drm/tidss/tidss_kms.c | 188 +++---
  6 files changed, 198 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c 
b/drivers/gpu/drm/tidss/tidss_dispc.c

index dbc6a5b617ca..472226a83251 100644
--- a/drivers/gpu/drm/tidss/tidss_dispc.c
+++ b/drivers/gpu/drm/tidss/tidss_dispc.c
@@ -365,6 +365,8 @@ struct dispc_device {
  struct dss_vp_data vp_data[TIDSS_MAX_VPS];
+    enum dispc_oldi_modes oldi_mode;
+
  u32 *fourccs;
  u32 num_fourccs;
@@ -1967,6 +1969,16 @@ const u32 *dispc_plane_formats(struct 
dispc_device *dispc, unsigned int *len)

  return dispc->fourccs;
  }
+int dispc_set_oldi_mode(struct dispc_device *dispc,
+    enum dispc_oldi_modes oldi_mode)
+{
+    WARN_ON(!dispc);


This feels unnecessary. Is there even a theoretical case where we could 
get dispc == NULL?



+
+    dispc->oldi_mode = oldi_mode;
+
+    return 0;


This function could as well be void function. >

+}
+
  static s32 pixinc(int pixels, u8 ps)
  {
  if (pixels == 1)
diff --git a/drivers/gpu/drm/tidss/tidss_dispc.h 
b/drivers/gpu/drm/tidss/tidss_dispc.h

index 51db500590ee..e76a7599b544 100644
--- a/drivers/gpu/drm/tidss/tidss_dispc.h
+++ b/drivers/gpu/drm/tidss/tidss_dispc.h
@@ -64,6 +64,14 @@ enum dispc_dss_subrevision {
  DISPC_AM625,
  };
+enum dispc_oldi_modes {
+    OLDI_MODE_OFF,    /* OLDI turned off / tied off in IP. */
+    OLDI_SINGLE_LINK_SINGLE_MODE,    /* Single Output over OLDI 0. */
+    OLDI_SINGLE_LINK_CLONE_MODE,    /* Duplicate Output over OLDI 0 and 1. */
+    OLDI_DUAL_LINK_MODE,    /* Combined Output over OLDI 0 and 1. */
+    OLDI_MODE_UNSUPPORTED,    /* Unsupported OLDI Mode */
+};


What is the difference with MODE_OFF and MODE_UNSUPPORTED? Is 
MODE_UNSUPPORTED for cases where, e.g., the DT setup is wrong and the 
driver should return an error? The code doesn't quite do that, it prints 
an error but then continues.


Yes, OLDI_MODE_UNSUPPORTED is for the cases where DT setup is wrong.
I have not exited in such a cases with an error, because then the driver
will never have a chance to setup the 2nd pipeline (DPI) even if all the
DT requirements are met.




  struct dispc_features {
  int min_pclk_khz;
  int max_pclk_khz[DISPC_VP_MAX_BUS_TYPE];
@@ -133,6 +141,7 @@ int dispc_plane_setup(struct dispc_device *dispc, u32 
hw_plane,
    u32 hw_videoport);
  int dispc_plane_enable(struct dispc_device *dispc, u32 hw_plane, bool enable);
  const u32 *dispc_plane_formats(struct dispc_device *dispc, unsigned int *len);
+int dispc_set_oldi_mode(struct dispc_device *dispc, enum dispc_oldi_modes 
oldi_mode);
  int dispc_init(struct tidss_device *tidss);
  void dispc_remove(struct tidss_device *tidss);
diff --git a/drivers/gpu/drm/tidss/tidss_drv.h 
b/drivers/gpu/drm/tidss/tidss_drv.h

index 0ce7ee5ccd5b..58892f065c16 100644
--- a/drivers/gpu/drm/tidss/tidss_drv.h
+++ b/drivers/gpu/drm/tidss/tidss_drv.h
@@ -13,6 +13,9 @@
  #define 

Re: [PATCH 1/2] drm: bridge: dw-mipi-dsi: Handle NO_EOT_PACKET mode

2023-01-23 Thread Jagan Teki
On Tue, 24 Jan 2023 at 01:49, Sam Ravnborg  wrote:
>
> Hi Jagan.
>
> One small drive-by comment.
>
> On Tue, Jan 24, 2023 at 12:16:46AM +0530, Jagan Teki wrote:
> > Many downstream bridges or panels followed by dw-mipi-dsi were
> > using MIPI_DSI_MODE_NO_EOT_PACKET.
> >
> > So, handle the EOTP bits accordingly in the dw-mipi-dsi host.
> >
> > Signed-off-by: Jagan Teki 
> > ---
> >  drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 8 +++-
> >  1 file changed, 7 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c 
> > b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> > index b2efecf7d160..47bd69d5ac99 100644
> > --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> > +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> > @@ -664,7 +664,13 @@ static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi 
> > *dsi,
> >
> >  static void dw_mipi_dsi_packet_handler_config(struct dw_mipi_dsi *dsi)
> >  {
> > - dsi_write(dsi, DSI_PCKHDL_CFG, CRC_RX_EN | ECC_RX_EN | BTA_EN);
> > + u32 val;
> > +
> > + val = CRC_RX_EN | ECC_RX_EN | BTA_EN | EOTP_TX_EN;
> > + if (dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET)
> > + val &= ~EOTP_TX_EN;
>
> I had to look twice because the bit is set, and then maybe cleared.
>
> val = CRC_RX_EN | ECC_RX_EN | BTA_EN | EOTP_TX_EN;
> if (!(dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET))
> val |= EOTP_TX_EN;
> ?

What I understand is if NO_EOT means we need to disable EOTP_TX_EN bit
so the logic in the patch does the same. Enable the EOTP_TX_EN by
default and disable it if NO_EOT mode set.

Jagan.


Re: [LSF/MM/BPF proposal]: Physr discussion

2023-01-23 Thread Chaitanya Kulkarni
On 1/23/23 11:47, Bart Van Assche wrote:
> On 1/23/23 05:44, Jason Gunthorpe wrote:
>> I've gone from quite a different starting point - I've been working
>> DMA API upwards, so what does the dma_map_XX look like, what APIs do
>> we need to support the dma_map_ops implementations to iterate/etc, how
>> do we form and return the dma mapped list, how does P2P, with all the
>> checks, actually work, etc. These help inform what we want from the
>> "phyr" as an API.
> 
> I'm interested in this topic. I'm wondering whether eliminating 
> scatterlists could help to make the block layer faster.
> 
> Thanks,
> 
> Bart.
> 

I think it will be very interesting to discuss this in great detail
and come up with the plan.

+1 from me.

-ck



Assertion failure in i915 intel_display.c#assert_plane() after resume from hibernation

2023-01-23 Thread Salvatore Bonaccorso
Hi

A user in Debian, cc'ed reporte the following issue when resuming from
hibernation, tested as well on recent 6.1.7 kernel, context see
https://bugs.debian.org/971068

> Can repro on the sid kernel, uname -a of
>   Linux nabtop 6.1.0-2-686-pae #1 SMP PREEMPT_DYNAMIC Debian 6.1.7-1 
> (2023-01-18) i686 GNU/Linux
> 
> Log below. Backtrace is only trivially different.
> 
> Best,
> наб
> 
> -- >8 --
> Jan 22 14:06:46 nabtop kernel: OOM killer disabled.
> Jan 22 14:06:46 nabtop kernel: PM: hibernation: Marking nosave pages: [mem 
> 0x-0x0fff]
> Jan 22 14:06:46 nabtop kernel: PM: hibernation: Marking nosave pages: [mem 
> 0x0009f000-0x000f]
> Jan 22 14:06:46 nabtop kernel: PM: hibernation: Marking nosave pages: [mem 
> 0xb5aa1000-0xb5aa6fff]
> Jan 22 14:06:46 nabtop kernel: PM: hibernation: Marking nosave pages: [mem 
> 0xb5bba000-0xb5c0efff]
> Jan 22 14:06:46 nabtop kernel: PM: hibernation: Marking nosave pages: [mem 
> 0xb5d08000-0xb5f0efff]
> Jan 22 14:06:46 nabtop kernel: PM: hibernation: Marking nosave pages: [mem 
> 0xb5f18000-0xb5f1efff]
> Jan 22 14:06:46 nabtop kernel: PM: hibernation: Marking nosave pages: [mem 
> 0xb5f65000-0xb5f9efff]
> Jan 22 14:06:46 nabtop kernel: PM: hibernation: Marking nosave pages: [mem 
> 0xb5fe1000-0xb5ffefff]
> Jan 22 14:06:46 nabtop kernel: PM: hibernation: Marking nosave pages: [mem 
> 0xb600-0x]
> Jan 22 14:06:46 nabtop kernel: PM: hibernation: Basic memory bitmaps created
> Jan 22 14:06:46 nabtop kernel: PM: hibernation: Preallocating image memory
> Jan 22 14:06:46 nabtop kernel: PM: hibernation: Allocated 183519 pages for 
> snapshot
> Jan 22 14:06:46 nabtop kernel: PM: hibernation: Allocated 734076 kbytes in 
> 0.70 seconds (1048.68 MB/s)
> Jan 22 14:06:46 nabtop kernel: Freezing remaining freezable tasks ... 
> (elapsed 0.001 seconds) done.
> Jan 22 14:06:46 nabtop kernel: wifi1: deauthenticating from de:0d:17:ad:80:55 
> by local choice (Reason: 3=DEAUTH_LEAVING)
> Jan 22 14:06:46 nabtop kernel: ACPI: EC: interrupt blocked
> Jan 22 14:06:46 nabtop kernel: ACPI: PM: Preparing to enter system sleep 
> state S4
> Jan 22 14:06:46 nabtop kernel: ACPI: EC: event blocked
> Jan 22 14:06:46 nabtop kernel: ACPI: EC: EC stopped
> Jan 22 14:06:46 nabtop kernel: ACPI: PM: Saving platform NVS memory
> Jan 22 14:06:46 nabtop kernel: Disabling non-boot CPUs ...
> Jan 22 14:06:46 nabtop kernel: smpboot: CPU 1 is now offline
> Jan 22 14:06:46 nabtop kernel: PM: hibernation: Creating image:
> Jan 22 14:06:46 nabtop kernel: PM: hibernation: Need to copy 175700 pages
> Jan 22 14:06:46 nabtop kernel: PM: hibernation: Normal pages needed: 57765 + 
> 1024, available pages: 167322
> Jan 22 14:06:46 nabtop kernel: ACPI: PM: Restoring platform NVS memory
> Jan 22 14:06:46 nabtop kernel: ACPI: EC: EC started
> Jan 22 14:06:46 nabtop kernel: Enabling non-boot CPUs ...
> Jan 22 14:06:46 nabtop kernel: x86: Booting SMP configuration:
> Jan 22 14:06:46 nabtop kernel: smpboot: Booting Node 0 Processor 1 APIC 0x1
> Jan 22 14:06:46 nabtop kernel: CPU1 is up
> Jan 22 14:06:46 nabtop kernel: ACPI: PM: Waking up from system sleep state S4
> Jan 22 14:06:46 nabtop kernel: ACPI: EC: interrupt unblocked
> Jan 22 14:06:46 nabtop kernel: ACPI: EC: event unblocked
> Jan 22 14:06:46 nabtop kernel: usb usb1: root hub lost power or was reset
> Jan 22 14:06:46 nabtop kernel: usb usb2: root hub lost power or was reset
> Jan 22 14:06:46 nabtop kernel: usb usb4: root hub lost power or was reset
> Jan 22 14:06:46 nabtop kernel: usb usb3: root hub lost power or was reset
> Jan 22 14:06:46 nabtop kernel: usb usb6: root hub lost power or was reset
> Jan 22 14:06:46 nabtop kernel: usb usb7: root hub lost power or was reset
> Jan 22 14:06:46 nabtop kernel: usb usb8: root hub lost power or was reset
> Jan 22 14:06:46 nabtop kernel: usb usb5: root hub lost power or was reset
> Jan 22 14:06:46 nabtop kernel: sd 0:0:0:0: [sda] Starting disk
> Jan 22 14:06:46 nabtop kernel: iwlwifi :08:00.0: Radio type=0x1-0x2-0x0
> Jan 22 14:06:46 nabtop kernel: iwlwifi :08:00.0: Radio type=0x1-0x2-0x0
> Jan 22 14:06:46 nabtop kernel: [ cut here ]
> Jan 22 14:06:46 nabtop kernel: primary B assertion failure (expected off, 
> current on)
> Jan 22 14:06:46 nabtop kernel: WARNING: CPU: 0 PID: 1038 at 
> drivers/gpu/drm/i915/display/intel_display.c:476 assert_plane+0x9f/0xb0 [i915]
> Jan 22 14:06:46 nabtop kernel: Modules linked in: ghash_generic gf128mul gcm 
> ccm algif_aead des_generic libdes ecb algif_skcipher bnep cmac md4 algif_hash 
> af_alg binfmt_misc btusb btrtl btbcm btintel btmtk bluetooth 
> jitterentropy_rng sha512_generic ctr drbg joydev ansi_cprng ecdh_generic ecc 
> iwldvm mac80211 libarc4 iTCO_wdt intel_pmc_bxt snd_hda_codec_conexant 
> iTCO_vendor_support uvcvideo watchdog snd_hda_codec_generic ledtrig_audio 
> videobuf2_vmalloc videobuf2_memops i915 videobuf2_v4l2 nls_ascii 
> snd_hda_intel iwlwifi videobuf2_common snd_intel_dspcfg drm_buddy 
> snd_intel_sdw_acpi 

[PATCH v3 5/6] drm/rockchip: vop2: add support for the rgb output block

2023-01-23 Thread Michael Riesch
The Rockchip VOP2 features an internal RGB output block, which can be
attached any video port of the VOP2. Add support for this output block.

Signed-off-by: Michael Riesch 
---
v3:
 - fix commit messages (still assumed video port 2)
 - fix condition to make 0 a valid video port
v2:
 - move away from wrong assumption that the RGB block is always
   connected to video port 2 -> check devicetree to find RGB block

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 44 
 1 file changed, 44 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 06fcdfa7b885..f38ffd0ccd9f 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -39,6 +39,7 @@
 #include "rockchip_drm_gem.h"
 #include "rockchip_drm_fb.h"
 #include "rockchip_drm_vop2.h"
+#include "rockchip_rgb.h"
 
 /*
  * VOP2 architecture
@@ -212,6 +213,9 @@ struct vop2 {
struct clk *hclk;
struct clk *aclk;
 
+   /* optional internal rgb encoder */
+   struct rockchip_rgb *rgb;
+
/* must be put at the end of the struct */
struct vop2_win win[];
 };
@@ -2393,6 +2397,25 @@ static void vop2_destroy_crtcs(struct vop2 *vop2)
}
 }
 
+static int vop2_find_rgb_encoder(struct vop2 *vop2)
+{
+   struct device_node *node = vop2->dev->of_node;
+   struct device_node *endpoint;
+   int i;
+
+   for (i = 0; i < vop2->data->nr_vps; i++) {
+   endpoint = of_graph_get_endpoint_by_regs(node, i,
+ROCKCHIP_VOP2_EP_RGB0);
+   if (!endpoint)
+   continue;
+
+   of_node_put(endpoint);
+   return i;
+   }
+
+   return -ENOENT;
+}
+
 static struct reg_field vop2_cluster_regs[VOP2_WIN_MAX_REG] = {
[VOP2_WIN_ENABLE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 0, 0),
[VOP2_WIN_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 1, 5),
@@ -2698,11 +2721,29 @@ static int vop2_bind(struct device *dev, struct device 
*master, void *data)
if (ret)
return ret;
 
+   ret = vop2_find_rgb_encoder(vop2);
+   if (ret >= 0) {
+   vop2->rgb = rockchip_rgb_init(dev, >vps[ret].crtc,
+ vop2->drm, ret);
+   if (IS_ERR(vop2->rgb)) {
+   if (PTR_ERR(vop2->rgb) == -EPROBE_DEFER) {
+   ret = PTR_ERR(vop2->rgb);
+   goto err_crtcs;
+   }
+   vop2->rgb = NULL;
+   }
+   }
+
rockchip_drm_dma_init_device(vop2->drm, vop2->dev);
 
pm_runtime_enable(>dev);
 
return 0;
+
+err_crtcs:
+   vop2_destroy_crtcs(vop2);
+
+   return ret;
 }
 
 static void vop2_unbind(struct device *dev, struct device *master, void *data)
@@ -2711,6 +2752,9 @@ static void vop2_unbind(struct device *dev, struct device 
*master, void *data)
 
pm_runtime_disable(dev);
 
+   if (vop2->rgb)
+   rockchip_rgb_fini(vop2->rgb);
+
vop2_destroy_crtcs(vop2);
 }
 
-- 
2.30.2



[PATCH v3 4/6] drm/rockchip: vop2: use symmetric function pair vop2_{create, destroy}_crtcs

2023-01-23 Thread Michael Riesch
Let the function name vop2_create_crtcs reflect that the function creates
multiple CRTCS. Also, use a symmetric function pair to create and destroy
the CRTCs and the corresponding planes.

Signed-off-by: Michael Riesch 
---
v3:
 - no changes
v2:
 - no changes

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 31 ++--
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 374ef821b453..06fcdfa7b885 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -2246,7 +2246,7 @@ static struct vop2_video_port 
*find_vp_without_primary(struct vop2 *vop2)
 
 #define NR_LAYERS 6
 
-static int vop2_create_crtc(struct vop2 *vop2)
+static int vop2_create_crtcs(struct vop2 *vop2)
 {
const struct vop2_data *vop2_data = vop2->data;
struct drm_device *drm = vop2->drm;
@@ -2372,15 +2372,25 @@ static int vop2_create_crtc(struct vop2 *vop2)
return 0;
 }
 
-static void vop2_destroy_crtc(struct drm_crtc *crtc)
+static void vop2_destroy_crtcs(struct vop2 *vop2)
 {
-   of_node_put(crtc->port);
+   struct drm_device *drm = vop2->drm;
+   struct list_head *crtc_list = >mode_config.crtc_list;
+   struct list_head *plane_list = >mode_config.plane_list;
+   struct drm_crtc *crtc, *tmpc;
+   struct drm_plane *plane, *tmpp;
+
+   list_for_each_entry_safe(plane, tmpp, plane_list, head)
+   drm_plane_cleanup(plane);
 
/*
 * Destroy CRTC after vop2_plane_destroy() since vop2_disable_plane()
 * references the CRTC.
 */
-   drm_crtc_cleanup(crtc);
+   list_for_each_entry_safe(crtc, tmpc, crtc_list, head) {
+   of_node_put(crtc->port);
+   drm_crtc_cleanup(crtc);
+   }
 }
 
 static struct reg_field vop2_cluster_regs[VOP2_WIN_MAX_REG] = {
@@ -2684,7 +2694,7 @@ static int vop2_bind(struct device *dev, struct device 
*master, void *data)
if (ret)
return ret;
 
-   ret = vop2_create_crtc(vop2);
+   ret = vop2_create_crtcs(vop2);
if (ret)
return ret;
 
@@ -2698,19 +2708,10 @@ static int vop2_bind(struct device *dev, struct device 
*master, void *data)
 static void vop2_unbind(struct device *dev, struct device *master, void *data)
 {
struct vop2 *vop2 = dev_get_drvdata(dev);
-   struct drm_device *drm = vop2->drm;
-   struct list_head *plane_list = >mode_config.plane_list;
-   struct list_head *crtc_list = >mode_config.crtc_list;
-   struct drm_crtc *crtc, *tmpc;
-   struct drm_plane *plane, *tmpp;
 
pm_runtime_disable(dev);
 
-   list_for_each_entry_safe(plane, tmpp, plane_list, head)
-   drm_plane_cleanup(plane);
-
-   list_for_each_entry_safe(crtc, tmpc, crtc_list, head)
-   vop2_destroy_crtc(crtc);
+   vop2_destroy_crtcs(vop2);
 }
 
 const struct component_ops vop2_component_ops = {
-- 
2.30.2



[PATCH v3 6/6] arm64: dts: rockchip: add pinctrls for 16-bit/18-bit rgb interface to rk356x

2023-01-23 Thread Michael Riesch
The rk3568-pinctrl.dtsi only defines the 24-bit RGB interface. Add separate
nodes for the 16-bit and 18-bit version, respectively. While at it, split
off the clock/sync signals from the data signals.

The exact mapping of the data pins was discussed here:
https://lore.kernel.org/linux-rockchip/f33a0488-528c-99de-3279-3c0346a03...@wolfvision.net/T/

Signed-off-by: Michael Riesch 
---
v3:
 - no changes
v2:
 - no changes

 .../boot/dts/rockchip/rk3568-pinctrl.dtsi | 94 +++
 1 file changed, 94 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-pinctrl.dtsi 
b/arch/arm64/boot/dts/rockchip/rk3568-pinctrl.dtsi
index 8f90c66dd9e9..0a979bfb63d9 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3568-pinctrl.dtsi
@@ -3117,4 +3117,98 @@ tsadc_pin: tsadc-pin {
<0 RK_PA1 0 _pull_none>;
};
};
+
+   lcdc {
+   /omit-if-no-ref/
+   lcdc_clock: lcdc-clock {
+   rockchip,pins =
+   /* lcdc_clk */
+   <3 RK_PA0 1 _pull_none>,
+   /* lcdc_den */
+   <3 RK_PC3 1 _pull_none>,
+   /* lcdc_hsync */
+   <3 RK_PC1 1 _pull_none>,
+   /* lcdc_vsync */
+   <3 RK_PC2 1 _pull_none>;
+   };
+
+   /omit-if-no-ref/
+   lcdc_data16: lcdc-data16 {
+   rockchip,pins =
+   /* lcdc_d3 */
+   <2 RK_PD3 1 _pull_none>,
+   /* lcdc_d4 */
+   <2 RK_PD4 1 _pull_none>,
+   /* lcdc_d5 */
+   <2 RK_PD5 1 _pull_none>,
+   /* lcdc_d6 */
+   <2 RK_PD6 1 _pull_none>,
+   /* lcdc_d7 */
+   <2 RK_PD7 1 _pull_none>,
+   /* lcdc_d10 */
+   <3 RK_PA3 1 _pull_none>,
+   /* lcdc_d11 */
+   <3 RK_PA4 1 _pull_none>,
+   /* lcdc_d12 */
+   <3 RK_PA5 1 _pull_none>,
+   /* lcdc_d13 */
+   <3 RK_PA6 1 _pull_none>,
+   /* lcdc_d14 */
+   <3 RK_PA7 1 _pull_none>,
+   /* lcdc_d15 */
+   <3 RK_PB0 1 _pull_none>,
+   /* lcdc_d19 */
+   <3 RK_PB4 1 _pull_none>,
+   /* lcdc_d20 */
+   <3 RK_PB5 1 _pull_none>,
+   /* lcdc_d21 */
+   <3 RK_PB6 1 _pull_none>,
+   /* lcdc_d22 */
+   <3 RK_PB7 1 _pull_none>,
+   /* lcdc_d23 */
+   <3 RK_PC0 1 _pull_none>;
+   };
+
+   /omit-if-no-ref/
+   lcdc_data18: lcdc-data18 {
+   rockchip,pins =
+   /* lcdc_d2 */
+   <2 RK_PD2 1 _pull_none>,
+   /* lcdc_d3 */
+   <2 RK_PD3 1 _pull_none>,
+   /* lcdc_d4 */
+   <2 RK_PD4 1 _pull_none>,
+   /* lcdc_d5 */
+   <2 RK_PD5 1 _pull_none>,
+   /* lcdc_d6 */
+   <2 RK_PD6 1 _pull_none>,
+   /* lcdc_d7 */
+   <2 RK_PD7 1 _pull_none>,
+   /* lcdc_d10 */
+   <3 RK_PA3 1 _pull_none>,
+   /* lcdc_d11 */
+   <3 RK_PA4 1 _pull_none>,
+   /* lcdc_d12 */
+   <3 RK_PA5 1 _pull_none>,
+   /* lcdc_d13 */
+   <3 RK_PA6 1 _pull_none>,
+   /* lcdc_d14 */
+   <3 RK_PA7 1 _pull_none>,
+   /* lcdc_d15 */
+   <3 RK_PB0 1 _pull_none>,
+   /* lcdc_d18 */
+   <3 RK_PB3 1 _pull_none>,
+   /* lcdc_d19 */
+   <3 RK_PB4 1 _pull_none>,
+   /* lcdc_d20 */
+   <3 RK_PB5 1 _pull_none>,
+   

[PATCH v3 3/6] drm/rockchip: rgb: add video_port parameter to init function

2023-01-23 Thread Michael Riesch
The VOP2 driver has more than one video port, hence the hard-coded
port id will not work anymore. Add an extra parameter for the video
port id to the rockchip_rgb_init function.

Signed-off-by: Michael Riesch 
---
v3:
 - no changes
v2:
 - no changes

 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 2 +-
 drivers/gpu/drm/rockchip/rockchip_rgb.c | 9 +
 drivers/gpu/drm/rockchip/rockchip_rgb.h | 6 --
 3 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index fa1f4ee6d195..5d18dea5c8d6 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -2221,7 +2221,7 @@ static int vop_bind(struct device *dev, struct device 
*master, void *data)
goto err_disable_pm_runtime;
 
if (vop->data->feature & VOP_FEATURE_INTERNAL_RGB) {
-   vop->rgb = rockchip_rgb_init(dev, >crtc, vop->drm_dev);
+   vop->rgb = rockchip_rgb_init(dev, >crtc, vop->drm_dev, 0);
if (IS_ERR(vop->rgb)) {
ret = PTR_ERR(vop->rgb);
goto err_disable_pm_runtime;
diff --git a/drivers/gpu/drm/rockchip/rockchip_rgb.c 
b/drivers/gpu/drm/rockchip/rockchip_rgb.c
index 5971df4302f2..c677b71ae516 100644
--- a/drivers/gpu/drm/rockchip/rockchip_rgb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_rgb.c
@@ -72,7 +72,8 @@ struct drm_encoder_helper_funcs 
rockchip_rgb_encoder_helper_funcs = {
 
 struct rockchip_rgb *rockchip_rgb_init(struct device *dev,
   struct drm_crtc *crtc,
-  struct drm_device *drm_dev)
+  struct drm_device *drm_dev,
+  int video_port)
 {
struct rockchip_rgb *rgb;
struct drm_encoder *encoder;
@@ -90,7 +91,7 @@ struct rockchip_rgb *rockchip_rgb_init(struct device *dev,
rgb->dev = dev;
rgb->drm_dev = drm_dev;
 
-   port = of_graph_get_port_by_id(dev->of_node, 0);
+   port = of_graph_get_port_by_id(dev->of_node, video_port);
if (!port)
return ERR_PTR(-EINVAL);
 
@@ -103,8 +104,8 @@ struct rockchip_rgb *rockchip_rgb_init(struct device *dev,
continue;
 
child_count++;
-   ret = drm_of_find_panel_or_bridge(dev->of_node, 0, endpoint_id,
- , );
+   ret = drm_of_find_panel_or_bridge(dev->of_node, video_port,
+ endpoint_id, , );
if (!ret) {
of_node_put(endpoint);
break;
diff --git a/drivers/gpu/drm/rockchip/rockchip_rgb.h 
b/drivers/gpu/drm/rockchip/rockchip_rgb.h
index 27b9635124bc..1bd4e20e91eb 100644
--- a/drivers/gpu/drm/rockchip/rockchip_rgb.h
+++ b/drivers/gpu/drm/rockchip/rockchip_rgb.h
@@ -8,12 +8,14 @@
 #ifdef CONFIG_ROCKCHIP_RGB
 struct rockchip_rgb *rockchip_rgb_init(struct device *dev,
   struct drm_crtc *crtc,
-  struct drm_device *drm_dev);
+  struct drm_device *drm_dev,
+  int video_port);
 void rockchip_rgb_fini(struct rockchip_rgb *rgb);
 #else
 static inline struct rockchip_rgb *rockchip_rgb_init(struct device *dev,
 struct drm_crtc *crtc,
-struct drm_device *drm_dev)
+struct drm_device *drm_dev,
+int video_port)
 {
return NULL;
 }
-- 
2.30.2



[PATCH v3 2/6] drm/rockchip: rgb: embed drm_encoder into rockchip_encoder

2023-01-23 Thread Michael Riesch
Commit 540b8f271e53 ("drm/rockchip: Embed drm_encoder into
rockchip_decoder") provides the means to pass the endpoint ID to the
VOP2 driver, which sets the interface MUX accordingly. However, this
step has not yet been carried out for the RGB output block. Embed the
drm_encoder structure into the rockchip_encoder structure and set the
endpoint ID correctly.

Signed-off-by: Michael Riesch 
---
v3:
 - no changes
v2:
 - use endpoint id from device tree instead of hardcoded value

 drivers/gpu/drm/rockchip/rockchip_rgb.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_rgb.c 
b/drivers/gpu/drm/rockchip/rockchip_rgb.c
index 75eb7cca3d82..5971df4302f2 100644
--- a/drivers/gpu/drm/rockchip/rockchip_rgb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_rgb.c
@@ -22,13 +22,11 @@
 #include "rockchip_drm_vop.h"
 #include "rockchip_rgb.h"
 
-#define encoder_to_rgb(c) container_of(c, struct rockchip_rgb, encoder)
-
 struct rockchip_rgb {
struct device *dev;
struct drm_device *drm_dev;
struct drm_bridge *bridge;
-   struct drm_encoder encoder;
+   struct rockchip_encoder encoder;
struct drm_connector connector;
int output_mode;
 };
@@ -125,7 +123,7 @@ struct rockchip_rgb *rockchip_rgb_init(struct device *dev,
return ERR_PTR(ret);
}
 
-   encoder = >encoder;
+   encoder = >encoder.encoder;
encoder->possible_crtcs = drm_crtc_mask(crtc);
 
ret = drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_NONE);
@@ -161,6 +159,8 @@ struct rockchip_rgb *rockchip_rgb_init(struct device *dev,
goto err_free_encoder;
}
 
+   rgb->encoder.crtc_endpoint_id = endpoint_id;
+
ret = drm_connector_attach_encoder(connector, encoder);
if (ret < 0) {
DRM_DEV_ERROR(drm_dev->dev,
@@ -182,6 +182,6 @@ void rockchip_rgb_fini(struct rockchip_rgb *rgb)
 {
drm_panel_bridge_remove(rgb->bridge);
drm_connector_cleanup(>connector);
-   drm_encoder_cleanup(>encoder);
+   drm_encoder_cleanup(>encoder.encoder);
 }
 EXPORT_SYMBOL_GPL(rockchip_rgb_fini);
-- 
2.30.2



[PATCH v3 1/6] drm/rockchip: vop2: initialize possible_crtcs properly

2023-01-23 Thread Michael Riesch
The variable possible_crtcs is only initialized for primary and
overlay planes. Since the VOP2 driver only supports these plane
types at the moment, the current code is safe. However, in order
to provide a future-proof solution, fix the initialization of
the variable.

Reported-by: kernel test robot 
Reported-by: Dan Carpenter 
Signed-off-by: Michael Riesch 
---
v3:
 - no changes
v2:
 - new patch

 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 8cecf81a5ae0..374ef821b453 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -2322,10 +2322,11 @@ static int vop2_create_crtc(struct vop2 *vop2)
/* change the unused primary window to overlay 
window */
win->type = DRM_PLANE_TYPE_OVERLAY;
}
-   }
-
-   if (win->type == DRM_PLANE_TYPE_OVERLAY)
+   } else if (win->type == DRM_PLANE_TYPE_OVERLAY) {
possible_crtcs = (1 << nvps) - 1;
+   } else {
+   possible_crtcs = 0;
+   }
 
ret = vop2_plane_init(vop2, win, possible_crtcs);
if (ret) {
-- 
2.30.2



[PATCH v3 0/6] drm/rockchip: vop2: add support for the rgb output block

2023-01-23 Thread Michael Riesch
Hi all,

This series adds support for the RGB output block that can be found in the
Rockchip Video Output Processor (VOP) 2. Version 2 of this series
incorporates the feedback by Dan Carpenter and Sascha Hauer. Version 3
fixes a dumb mistake pointed out by Sascha :-) Thanks for your comments!

Patches 1-4 clean up the code and make it more general.

Patch 5 activates the support for the RGB output block in the VOP2 driver.

Patch 6 adds pinctrls for the 16-bit and 18-bit RGB data lines.

Tested on a custom board featuring the RK3568 SoC with a 18-bit RGB
display.

Looking forward to your comments!

Best regards,
Michael

Michael Riesch (6):
  drm/rockchip: vop2: initialize possible_crtcs properly
  drm/rockchip: rgb: embed drm_encoder into rockchip_encoder
  drm/rockchip: rgb: add video_port parameter to init function
  drm/rockchip: vop2: use symmetric function pair
vop2_{create,destroy}_crtcs
  drm/rockchip: vop2: add support for the rgb output block
  arm64: dts: rockchip: add pinctrls for 16-bit/18-bit rgb interface to
rk356x

 .../boot/dts/rockchip/rk3568-pinctrl.dtsi | 94 +++
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c   |  2 +-
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c  | 80 
 drivers/gpu/drm/rockchip/rockchip_rgb.c   | 19 ++--
 drivers/gpu/drm/rockchip/rockchip_rgb.h   |  6 +-
 5 files changed, 172 insertions(+), 29 deletions(-)


base-commit: 1b929c02afd37871d5afb9d498426f83432e71c2
-- 
2.30.2



[PATCH v6 2/6] drm/i915/pxp: add device link between i915 and mei_pxp

2023-01-23 Thread Alan Previn
From: Alexander Usyskin 

Add device link with i915 as consumer and mei_pxp as supplier
to ensure proper ordering of power flows.

V2: condition on absence of heci_pxp to filter out DG

Signed-off-by: Alexander Usyskin 
---
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c   | 11 +++
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h |  6 ++
 2 files changed, 17 insertions(+)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
index 73aa8015f828..cd5b86216506 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -127,6 +127,12 @@ static int i915_pxp_tee_component_bind(struct device 
*i915_kdev,
intel_wakeref_t wakeref;
int ret = 0;
 
+   if (!HAS_HECI_PXP(i915)) {
+   pxp->component_dev_link = device_link_add(i915_kdev, tee_kdev, 
DL_FLAG_STATELESS);
+   if (drm_WARN_ON(>drm, !pxp->component_dev_link))
+   return -ENODEV;
+   }
+
mutex_lock(>tee_mutex);
pxp->pxp_component = data;
pxp->pxp_component->tee_dev = tee_kdev;
@@ -169,6 +175,11 @@ static void i915_pxp_tee_component_unbind(struct device 
*i915_kdev,
mutex_lock(>tee_mutex);
pxp->pxp_component = NULL;
mutex_unlock(>tee_mutex);
+
+   if (pxp->component_dev_link) {
+   device_link_remove(i915_kdev, tee_kdev);
+   pxp->component_dev_link = NULL;
+   }
 }
 
 static const struct component_ops i915_pxp_tee_component_ops = {
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h 
b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
index 7dc5f08d1583..efd2f3915abe 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_types.h
@@ -32,6 +32,12 @@ struct intel_pxp {
 * which are protected by _mutex.
 */
struct i915_pxp_component *pxp_component;
+
+   /**
+* @component_dev_link: device link of the pxp-component enforcing i915 
as the
+* consumer. This is needed for legacy platform (TGL/ADL) full-feature 
usage.
+*/
+   struct device_link *component_dev_link;
/**
 * @pxp_component_added: track if the pxp component has been added.
 * Set and cleared in tee init and fini functions respectively.
-- 
2.39.0



[PATCH v6 5/6] drm/i915/pxp: Trigger the global teardown for before suspending

2023-01-23 Thread Alan Previn
A driver bug was recently discovered where the security firmware was
receiving internal HW signals indicating that session key expirations
had occurred. Architecturally, the firmware was expecting a response
from the GuC to acknowledge the event with the firmware side.
However the OS was in a suspended state and GuC had been reset.

Internal specifications actually required the driver to ensure
that all active sessions be properly cleaned up in such cases where
the system is suspended and the GuC potentially unable to respond.

This patch adds the global teardown code in i915's suspend_prepare
code path.

Signed-off-by: Alan Previn 
Reviewed-by: Juston Li 
---
 drivers/gpu/drm/i915/pxp/intel_pxp.c | 65 +---
 drivers/gpu/drm/i915/pxp/intel_pxp.h |  1 +
 drivers/gpu/drm/i915/pxp/intel_pxp_pm.c  |  2 +-
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c |  6 +-
 drivers/gpu/drm/i915/pxp/intel_pxp_session.h |  5 ++
 5 files changed, 66 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp.c
index cfc9af8b3d21..9d4c7724e98e 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c
@@ -270,6 +270,60 @@ static bool pxp_component_bound(struct intel_pxp *pxp)
return bound;
 }
 
+static int __pxp_global_teardown_final(struct intel_pxp *pxp)
+{
+   if (!pxp->arb_is_valid)
+   return 0;
+   /*
+* To ensure synchronous and coherent session teardown completion
+* in response to suspend or shutdown triggers, don't use a worker.
+*/
+   intel_pxp_mark_termination_in_progress(pxp);
+   intel_pxp_terminate(pxp, false);
+
+   if (!wait_for_completion_timeout(>termination, 
msecs_to_jiffies(250)))
+   return -ETIMEDOUT;
+
+   return 0;
+}
+
+static int __pxp_global_teardown_restart(struct intel_pxp *pxp)
+{
+   if (pxp->arb_is_valid)
+   return 0;
+   /*
+* The arb-session is currently inactive and we are doing a reset and 
restart
+* due to a runtime event. Use the worker that was designed for this.
+*/
+   pxp_queue_termination(pxp);
+
+   if (!wait_for_completion_timeout(>termination, 
msecs_to_jiffies(250)))
+   return -ETIMEDOUT;
+
+   return 0;
+}
+
+void intel_pxp_end(struct intel_pxp *pxp)
+{
+   struct drm_i915_private *i915 = pxp->ctrl_gt->i915;
+   intel_wakeref_t wakeref;
+
+   if (!intel_pxp_is_enabled(pxp))
+   return;
+
+   wakeref = intel_runtime_pm_get(>runtime_pm);
+
+   mutex_lock(>arb_mutex);
+
+   if (__pxp_global_teardown_final(pxp))
+   drm_dbg(>drm, "PXP end timed out\n");
+
+   mutex_unlock(>arb_mutex);
+
+   intel_pxp_fini_hw(pxp);
+   intel_runtime_pm_put(>runtime_pm, wakeref);
+}
+
 /*
  * the arb session is restarted from the irq work when we receive the
  * termination completion interrupt
@@ -286,16 +340,9 @@ int intel_pxp_start(struct intel_pxp *pxp)
 
mutex_lock(>arb_mutex);
 
-   if (pxp->arb_is_valid)
-   goto unlock;
-
-   pxp_queue_termination(pxp);
-
-   if (!wait_for_completion_timeout(>termination,
-   msecs_to_jiffies(250))) {
-   ret = -ETIMEDOUT;
+   ret = __pxp_global_teardown_restart(pxp);
+   if (ret)
goto unlock;
-   }
 
/* make sure the compiler doesn't optimize the double access */
barrier();
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h 
b/drivers/gpu/drm/i915/pxp/intel_pxp.h
index 9658d3005222..3ded0890cd27 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
@@ -27,6 +27,7 @@ void intel_pxp_mark_termination_in_progress(struct intel_pxp 
*pxp);
 void intel_pxp_tee_end_arb_fw_session(struct intel_pxp *pxp, u32 
arb_session_id);
 
 int intel_pxp_start(struct intel_pxp *pxp);
+void intel_pxp_end(struct intel_pxp *pxp);
 
 int intel_pxp_key_check(struct intel_pxp *pxp,
struct drm_i915_gem_object *obj,
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
index 892d39cc61c1..e427464aa131 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
@@ -16,7 +16,7 @@ void intel_pxp_suspend_prepare(struct intel_pxp *pxp)
if (!intel_pxp_is_enabled(pxp))
return;
 
-   pxp->arb_is_valid = false;
+   intel_pxp_end(pxp);
 
intel_pxp_invalidate(pxp);
 }
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
index 74ed7e16e481..448cacb0465d 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
@@ -115,11 +115,11 @@ static int pxp_terminate_arb_session_and_global(struct 
intel_pxp *pxp)
return ret;
 }
 
-static void pxp_terminate(struct 

[PATCH v6 1/6] mei: mei-me: resume device in prepare

2023-01-23 Thread Alan Previn
From: Alexander Usyskin 

Asynchronous runtime resume is not possible while the system
is suspending.
The power management subsystem resumes the device only in the
suspend phase, not in the prepare phase.
Force resume device in prepare to allow drivers on mei bus
to communicate in their prepare callbacks.

Signed-off-by: Alexander Usyskin 
Reviewed-by: Tomas Winkler 
---
 drivers/misc/mei/pci-me.c | 20 +++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c
index 5bf0d50d55a0..676d566f38dd 100644
--- a/drivers/misc/mei/pci-me.c
+++ b/drivers/misc/mei/pci-me.c
@@ -342,6 +342,12 @@ static void mei_me_remove(struct pci_dev *pdev)
 }
 
 #ifdef CONFIG_PM_SLEEP
+static int mei_me_pci_prepare(struct device *device)
+{
+   pm_runtime_resume(device);
+   return 0;
+}
+
 static int mei_me_pci_suspend(struct device *device)
 {
struct pci_dev *pdev = to_pci_dev(device);
@@ -398,7 +404,17 @@ static int mei_me_pci_resume(struct device *device)
 
return 0;
 }
-#endif /* CONFIG_PM_SLEEP */
+
+static void mei_me_pci_complete(struct device *device)
+{
+   pm_runtime_suspend(device);
+}
+#else /* CONFIG_PM_SLEEP */
+
+#define mei_me_pci_prepare NULL
+#define mei_me_pci_complete NULL
+
+#endif /* !CONFIG_PM_SLEEP */
 
 #ifdef CONFIG_PM
 static int mei_me_pm_runtime_idle(struct device *device)
@@ -501,6 +517,8 @@ static inline void mei_me_unset_pm_domain(struct mei_device 
*dev)
 }
 
 static const struct dev_pm_ops mei_me_pm_ops = {
+   .prepare = mei_me_pci_prepare,
+   .complete = mei_me_pci_complete,
SET_SYSTEM_SLEEP_PM_OPS(mei_me_pci_suspend,
mei_me_pci_resume)
SET_RUNTIME_PM_OPS(
-- 
2.39.0



[PATCH v6 3/6] mei: clean pending read with vtag on bus

2023-01-23 Thread Alan Previn
From: Alexander Usyskin 

Client on bus have only one vtag map slot and should disregard the vtag
value when cleaning pending read flag.
Fixes read flow control message unexpectedly generated when
clent on bus send messages with different vtags.

Signed-off-by: Alexander Usyskin 
Reviewed-by: Tomas Winkler 
---
 drivers/misc/mei/client.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
index 9ddb854b8155..5c19097266fe 100644
--- a/drivers/misc/mei/client.c
+++ b/drivers/misc/mei/client.c
@@ -1343,7 +1343,9 @@ static void mei_cl_reset_read_by_vtag(const struct mei_cl 
*cl, u8 vtag)
struct mei_cl_vtag *vtag_l;
 
list_for_each_entry(vtag_l, >vtag_map, list) {
-   if (vtag_l->vtag == vtag) {
+   /* The client on bus has one fixed vtag map */
+   if ((cl->cldev && mei_cldev_enabled(cl->cldev)) ||
+   vtag_l->vtag == vtag) {
vtag_l->pending_read = false;
break;
}
-- 
2.39.0



[PATCH v6 4/6] drm/i915/pxp: Invalidate all PXP fw sessions during teardown

2023-01-23 Thread Alan Previn
A gap was recently discovered where if an application did not
invalidate all of the stream keys (intentionally or not), and the
driver did a full PXP global teardown on the GT subsystem, we
find that future session creation would fail on the security
firmware's side of the equation. i915 is the entity that needs
ensure the sessions' state across both iGT and security firmware
are at a known clean point when performing a full global teardown.

Architecturally speaking, i915 should inspect all active sessions
and submit the invalidate-stream-key PXP command to the security
firmware for each of them. However, for the upstream i915 driver
we only support the arbitration session that can be created
so that will be the only session we will cleanup.

Signed-off-by: Alan Previn 
Reviewed-by: Juston Li 
Acked-by: Rodrigo Vivi 
---
 drivers/gpu/drm/i915/pxp/intel_pxp.h  |  1 +
 .../drm/i915/pxp/intel_pxp_cmd_interface_42.h | 15 
 .../i915/pxp/intel_pxp_cmd_interface_cmn.h|  3 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  2 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c  | 35 +++
 5 files changed, 56 insertions(+)

diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.h 
b/drivers/gpu/drm/i915/pxp/intel_pxp.h
index 04440fada711..9658d3005222 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp.h
@@ -24,6 +24,7 @@ void intel_pxp_init_hw(struct intel_pxp *pxp);
 void intel_pxp_fini_hw(struct intel_pxp *pxp);
 
 void intel_pxp_mark_termination_in_progress(struct intel_pxp *pxp);
+void intel_pxp_tee_end_arb_fw_session(struct intel_pxp *pxp, u32 
arb_session_id);
 
 int intel_pxp_start(struct intel_pxp *pxp);
 
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_42.h 
b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_42.h
index 739f9072fa5f..26f7d9f01bf3 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_42.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_42.h
@@ -12,6 +12,9 @@
 /* PXP-Opcode for Init Session */
 #define PXP42_CMDID_INIT_SESSION 0x1e
 
+/* PXP-Opcode for Invalidate Stream Key */
+#define PXP42_CMDID_INVALIDATE_STREAM_KEY 0x0007
+
 /* PXP-Input-Packet: Init Session (Arb-Session) */
 struct pxp42_create_arb_in {
struct pxp_cmd_header header;
@@ -25,4 +28,16 @@ struct pxp42_create_arb_out {
struct pxp_cmd_header header;
 } __packed;
 
+/* PXP-Input-Packet: Invalidate Stream Key */
+struct pxp42_inv_stream_key_in {
+   struct pxp_cmd_header header;
+   u32 rsvd[3];
+} __packed;
+
+/* PXP-Output-Packet: Invalidate Stream Key */
+struct pxp42_inv_stream_key_out {
+   struct pxp_cmd_header header;
+   u32 rsvd;
+} __packed;
+
 #endif /* __INTEL_PXP_FW_INTERFACE_42_H__ */
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_cmn.h 
b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_cmn.h
index aaa8187a0afb..ae9b151b7cb7 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_cmn.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_cmd_interface_cmn.h
@@ -28,6 +28,9 @@ struct pxp_cmd_header {
union {
u32 status; /* out */
u32 stream_id; /* in */
+#define PXP_CMDHDR_EXTDATA_SESSION_VALID GENMASK(0, 0)
+#define PXP_CMDHDR_EXTDATA_APP_TYPE GENMASK(1, 1)
+#define PXP_CMDHDR_EXTDATA_SESSION_ID GENMASK(17, 2)
};
/* Length of the message (excluding the header) */
u32 buffer_len;
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
index ae413580b81a..74ed7e16e481 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_session.c
@@ -110,6 +110,8 @@ static int pxp_terminate_arb_session_and_global(struct 
intel_pxp *pxp)
 
intel_uncore_write(gt->uncore, PXP_GLOBAL_TERMINATE, 1);
 
+   intel_pxp_tee_end_arb_fw_session(pxp, ARB_SESSION);
+
return ret;
 }
 
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
index cd5b86216506..aa0ad46e524b 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
@@ -319,3 +319,38 @@ int intel_pxp_tee_cmd_create_arb_session(struct intel_pxp 
*pxp,
 
return ret;
 }
+
+void intel_pxp_tee_end_arb_fw_session(struct intel_pxp *pxp, u32 session_id)
+{
+   struct drm_i915_private *i915 = pxp->ctrl_gt->i915;
+   struct pxp42_inv_stream_key_in msg_in = {0};
+   struct pxp42_inv_stream_key_out msg_out = {0};
+   int ret, trials = 0;
+
+try_again:
+   memset(_in, 0, sizeof(msg_in));
+   memset(_out, 0, sizeof(msg_out));
+   msg_in.header.api_version = PXP_APIVER(4, 2);
+   msg_in.header.command_id = PXP42_CMDID_INVALIDATE_STREAM_KEY;
+   msg_in.header.buffer_len = sizeof(msg_in) - sizeof(msg_in.header);
+
+   msg_in.header.stream_id = FIELD_PREP(PXP_CMDHDR_EXTDATA_SESSION_VALID, 
1);
+   msg_in.header.stream_id |= 

[PATCH v6 6/6] drm/i915/pxp: Pxp hw init should be in resume_complete

2023-01-23 Thread Alan Previn
During suspend flow, i915 currently achors' on the pm_suspend_prepare
callback as the location where we quiesce the entire GPU and perform
all necessary cleanup in order to go into suspend. PXP is also called
during this time to perform the arbitration session teardown (with
the assurance no additional GEM IOCTLs will come after that could
restart the session).

However, if other devices or drivers fail their suspend_prepare, the
system will not go into suspend and i915 will be expected to resume
operation. In this case, we need to re-initialize the PXP hardware
and this really should be done within the pm_resume_complete callback
which is the correct opposing function in the resume sequence to
match pm_suspend_prepare of the suspend sequence.

Because this callback is the last thing at the end of resuming
we expect little to no impact to the rest of the i915 resume sequence
with this change.

Signed-off-by: Alan Previn 
Reviewed-by: Daniele Ceraolo Spurio 
Acked-by: Rodrigo Vivi 
---
 drivers/gpu/drm/i915/i915_driver.c  | 20 ++--
 drivers/gpu/drm/i915/pxp/intel_pxp_pm.c |  2 +-
 drivers/gpu/drm/i915/pxp/intel_pxp_pm.h |  6 +++---
 3 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_driver.c 
b/drivers/gpu/drm/i915/i915_driver.c
index 6469c7c1e154..122736b48938 100644
--- a/drivers/gpu/drm/i915/i915_driver.c
+++ b/drivers/gpu/drm/i915/i915_driver.c
@@ -1167,6 +1167,13 @@ static bool suspend_to_idle(struct drm_i915_private 
*dev_priv)
return false;
 }
 
+static void i915_drm_complete(struct drm_device *dev)
+{
+   struct drm_i915_private *i915 = to_i915(dev);
+
+   intel_pxp_resume_complete(i915->pxp);
+}
+
 static int i915_drm_prepare(struct drm_device *dev)
 {
struct drm_i915_private *i915 = to_i915(dev);
@@ -1367,8 +1374,6 @@ static int i915_drm_resume(struct drm_device *dev)
 
i915_gem_resume(dev_priv);
 
-   intel_pxp_resume(dev_priv->pxp);
-
intel_modeset_init_hw(dev_priv);
intel_init_clock_gating(dev_priv);
intel_hpd_init(dev_priv);
@@ -1560,6 +1565,16 @@ static int i915_pm_resume(struct device *kdev)
return i915_drm_resume(>drm);
 }
 
+static void i915_pm_complete(struct device *kdev)
+{
+   struct drm_i915_private *i915 = kdev_to_i915(kdev);
+
+   if (i915->drm.switch_power_state == DRM_SWITCH_POWER_OFF)
+   return;
+
+   i915_drm_complete(>drm);
+}
+
 /* freeze: before creating the hibernation_image */
 static int i915_pm_freeze(struct device *kdev)
 {
@@ -1780,6 +1795,7 @@ const struct dev_pm_ops i915_pm_ops = {
.suspend_late = i915_pm_suspend_late,
.resume_early = i915_pm_resume_early,
.resume = i915_pm_resume,
+   .complete = i915_pm_complete,
 
/*
 * S4 event handlers
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c 
b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
index e427464aa131..4f836b317424 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.c
@@ -34,7 +34,7 @@ void intel_pxp_suspend(struct intel_pxp *pxp)
}
 }
 
-void intel_pxp_resume(struct intel_pxp *pxp)
+void intel_pxp_resume_complete(struct intel_pxp *pxp)
 {
if (!intel_pxp_is_enabled(pxp))
return;
diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.h 
b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.h
index 586be769104f..06b46f535b42 100644
--- a/drivers/gpu/drm/i915/pxp/intel_pxp_pm.h
+++ b/drivers/gpu/drm/i915/pxp/intel_pxp_pm.h
@@ -11,7 +11,7 @@ struct intel_pxp;
 #ifdef CONFIG_DRM_I915_PXP
 void intel_pxp_suspend_prepare(struct intel_pxp *pxp);
 void intel_pxp_suspend(struct intel_pxp *pxp);
-void intel_pxp_resume(struct intel_pxp *pxp);
+void intel_pxp_resume_complete(struct intel_pxp *pxp);
 void intel_pxp_runtime_suspend(struct intel_pxp *pxp);
 #else
 static inline void intel_pxp_suspend_prepare(struct intel_pxp *pxp)
@@ -22,7 +22,7 @@ static inline void intel_pxp_suspend(struct intel_pxp *pxp)
 {
 }
 
-static inline void intel_pxp_resume(struct intel_pxp *pxp)
+static inline void intel_pxp_resume_complete(struct intel_pxp *pxp)
 {
 }
 
@@ -32,6 +32,6 @@ static inline void intel_pxp_runtime_suspend(struct intel_pxp 
*pxp)
 #endif
 static inline void intel_pxp_runtime_resume(struct intel_pxp *pxp)
 {
-   intel_pxp_resume(pxp);
+   intel_pxp_resume_complete(pxp);
 }
 #endif /* __INTEL_PXP_PM_H__ */
-- 
2.39.0



[PATCH v6 0/6] drm/i915/pxp: Add missing cleanup steps for PXP global-teardown

2023-01-23 Thread Alan Previn
A customer issue was recently discovered and in the process a
gap in i915's PXP interaction with HW+FW architecure was also
realized. This series adds those missing pieces.

This fix includes changes where i915 calls into the mei
component interface in order to submit requests to the security
firmware during the i915's suspend_prepare flow. This change did
expose a blocking issue in the mei component side that was
discovered while testing in rev1. The issue being the mei-pxp
component driver not being able to runtime-resume while being
within the suspend_prepare callstack.


Thus, we have now included the mei patches (from Alexander) that
fixes that issue by adding a device-link based on the interface
type to ensure mei side runtime resume during the i915's
suspend_prepare call.

That said, as per request from Alexander, we seek Greg's and Tomas'
review for the mei patches (Patch 1, 2 and 3). Patch 2, although is
a change in the i915 code, is the mei component device link change.

The individual patches explain more details. Patch 7 can be ignored
as it won't be merged and is only meant to ensure the CI run's
the PXP subtests with PXP support enabled in KConfig.

Changes from prior revs:
   v1: - Dont need to teardown non-arbitration sessions (Juston).
   - Fix builds when PXP is enabled in config (Alan/CI-build).
   - Fix the broken pm-suspend-resume symmetry when we do this
 pxp-session-teardown during i915s pm_suspend_prepare by
 ensuring the init is done during i915s pm_resume_complete.
   v2: - Rebase on latest drm-tip after PXP subsytem was promoted
 to global.
   - Remove "INTEL_PXP_MAX_HWDRM_SESSIONS" unneeded (Juston Li).
   - Added mei patches that are dependencies for this series
 to successfully pass testing when PXP config is enabled.
   v3: - Added fix for mei patch when CONFIG_PM_SLEEP is off (reported
 by kernel test robot ).
   v4: - Added "DRM_SWITCH_POWER_OFF" check and removed bail-out if
 '!i915' that wont happen in i915_pm_complete (Daniele).
   - move i915_pm_complete to appear in i915_pm_resume.
   - One more fix for mei patch when CONFIG_PM_SLEEP is off
 (reported by kernel test robot ).
   v5: - Reworked Patch#2 on device link establishment. Don't hide
 triggering device-link behind drm_WARN, return -ENODEV if
 it fails and stash the returned device_link struct.

Alan Previn (3):
  drm/i915/pxp: Invalidate all PXP fw sessions during teardown
  drm/i915/pxp: Trigger the global teardown for before suspending
  drm/i915/pxp: Pxp hw init should be in resume_complete

Alexander Usyskin (3):
  mei: mei-me: resume device in prepare
  drm/i915/pxp: add device link between i915 and mei_pxp
  mei: clean pending read with vtag on bus

 drivers/gpu/drm/i915/i915_driver.c| 20 +-
 drivers/gpu/drm/i915/pxp/intel_pxp.c  | 65 ---
 drivers/gpu/drm/i915/pxp/intel_pxp.h  |  2 +
 .../drm/i915/pxp/intel_pxp_cmd_interface_42.h | 15 +
 .../i915/pxp/intel_pxp_cmd_interface_cmn.h|  3 +
 drivers/gpu/drm/i915/pxp/intel_pxp_pm.c   |  4 +-
 drivers/gpu/drm/i915/pxp/intel_pxp_pm.h   |  6 +-
 drivers/gpu/drm/i915/pxp/intel_pxp_session.c  |  8 ++-
 drivers/gpu/drm/i915/pxp/intel_pxp_session.h  |  5 ++
 drivers/gpu/drm/i915/pxp/intel_pxp_tee.c  | 46 +
 drivers/gpu/drm/i915/pxp/intel_pxp_types.h|  6 ++
 drivers/misc/mei/client.c |  4 +-
 drivers/misc/mei/pci-me.c | 20 +-
 13 files changed, 183 insertions(+), 21 deletions(-)


base-commit: 6a023df4443d313724dc96d1fff15193bb7ec5b8
-- 
2.39.0



Re: DMA-heap driver hints

2023-01-23 Thread John Stultz
On Mon, Jan 23, 2023 at 8:29 AM Christian König
 wrote:
> Am 23.01.23 um 14:55 schrieb Laurent Pinchart:
> > - I assume some drivers will be able to support multiple heaps. How do
> >you envision this being implemented ?
>
> I don't really see an use case for this.
>
> We do have some drivers which say: for this use case you can use
> whatever you want, but for that use case you need to use specific memory
> (scan out on GPUs for example works like this).
>
[snipping the constraints argument, which I agree with]
>
> What we do have is compatibility between heaps. E.g. a CMA heap is
> usually compatible with the system heap or might even be a subset of
> another CMA heap. But I wanted to add that as next step to the heaps
> framework itself.

So the difficult question is how is userland supposed to know which
heap is compatible with which?

If you have two devices, one that points to heap "foo" and the other
points to heap "bar", how does userland know that "foo" satisfies the
constraints of "bar" but "bar" doesn't satisfy the constraints of
"foo".
(foo ="cma",  bar="system")

I think it would be much better for device 1 to list "foo" and device
2 to list "foo" and "bar", so you can find that "foo" is the common
heap which will solve both devices' needs.


> > - Devices could have different constraints based on particular
> >configurations. For instance, a device may require specific memory
> >layout for multi-planar YUV formats only (as in allocating the Y and C
> >planes of NV12 from different memory banks). A dynamic API may thus be
> >needed (but may also be very painful to use from userspace).
>
> Uff, good to know. But I'm not sure how to expose stuff like that.

Yeah. These edge cases are really hard to solve generically.  And
single devices that have separate constraints for different uses are
also not going to be solvable with a simple linking approach.

But I do wonder if a generic solution to all cases is needed
(especially if it really isn't possible)? If we leave the option for
gralloc like omniscient device-specific userland policy, those edge
cases can be handled by those devices that can't run generic logic.
And those devices just won't be able to be supported by generic
distros, hopefully motivating future designs to have less odd
constraints?

thanks
-john


Re: DMA-heap driver hints

2023-01-23 Thread John Stultz
On Mon, Jan 23, 2023 at 5:55 AM Laurent Pinchart
 wrote:
>
> Hi Christian,
>
> CC'ing James as I think this is related to his work on the unix device
> memory allocator ([1]).
>
> [1] 
> https://lore.kernel.org/dri-devel/8b555674-1c5b-c791-4547-2ea7c16ae...@nvidia.com/
>
> On Mon, Jan 23, 2023 at 01:37:54PM +0100, Christian König wrote:
> > Hi guys,
> >
> > this is just an RFC! The last time we discussed the DMA-buf coherency
> > problem [1] we concluded that DMA-heap first needs a better way to
> > communicate to userspace which heap to use for a certain device.
> >
> > As far as I know userspace currently just hard codes that information
> > which is certainly not desirable considering that we should have this
> > inside the kernel as well.
> >
> > So what those two patches here do is to first add some
> > dma_heap_create_device_link() and  dma_heap_remove_device_link()
> > function and then demonstrating the functionality with uvcvideo
> > driver.
> >
> > The preferred DMA-heap is represented with a symlink in sysfs between
> > the device and the virtual DMA-heap device node.
>
> I'll start with a few high-level comments/questions:
>
> - Instead of tying drivers to heaps, have you considered a system where
>   a driver would expose constraints, and a heap would then be selected
>   based on those constraints ? A tight coupling between heaps and
>   drivers means downstream patches to drivers in order to use
>   vendor-specific heaps, that sounds painful.

Though, maybe it should be in that case. More motivation to get your
heap (and its users) upstream. :)


>   A constraint-based system would also, I think, be easier to extend
>   with additional constraints in the future.

I think the issue of enumerating and exposing constraints to userland
is just really tough.  While on any one system there is a fixed number
of constraints, it's not clear we could come up with a bounded set for
all systems.
To avoid this back in the ION days I had proposed an idea of userland
having devices share an opaque constraint cookie, which userland could
mask together between devices and then find a heap that matches the
combined cookie, which would avoid exposing specific constraints to
userland, but the processes of using it seemed like such a mess to
explain.

So I think this driver driven links approach is pretty reasonable. I
do worry we might get situations where the drivers ability to use a
heap depends on some other factor (dts iommu setup maybe?), which the
driver might not know on its own, but I think having the driver
special-case that to resolve it would be doable.


> - I assume some drivers will be able to support multiple heaps. How do
>   you envision this being implemented ?

Yeah. I also agree we need to have multiple heap links.

> - Devices could have different constraints based on particular
>   configurations. For instance, a device may require specific memory
>   layout for multi-planar YUV formats only (as in allocating the Y and C
>   planes of NV12 from different memory banks). A dynamic API may thus be
>   needed (but may also be very painful to use from userspace).

Yeah. While I know folks really don't like the static userspace config
model that Android uses, I do fret that once we get past what a
workable heap is, it still won't address what the ideal heap is.

For instance, we might find that the system heap works for a given
pipeline, but because the cpu doesn't use the buffer in one case, the
system-uncached heap is really the best choice for performance. But in
another pipeline with the same devices, if the cpu is reading and
writing the buffer quite a bit, one would want the standard system
heap.

Because userland is the only one who can know the path a buffer will
take, userland is really the best place to choose the ideal allocation
type.

So while I don't object to this link based approach just to allow a
generic userland to find a working buffer type for a given set of
devices, I don't think it will be able to replace having device
specific userland policy (like gralloc), though it's my personal hope
the policy can be formalized to a config file rather then having
device specific binaries.

thanks
-john


Re: [PATCH 1/2] dma-heap: add device link and unlink functions

2023-01-23 Thread John Stultz
On Mon, Jan 23, 2023 at 4:38 AM Christian König
 wrote:
>
> This allows device drivers to specify a DMA-heap where they want their
> buffers to be allocated from. This information is then exposed as
> sysfs link between the device and the DMA-heap.
>
> Useful for userspace when in need to decide from which provider to
> allocate a buffer.
>
> Signed-off-by: Christian König 

Hey Christian!
  Thanks so much for sending this out and also thanks for including me
(Adding TJ as well)!

This looks like a really interesting approach, but I have a few thoughts below.

> ---
>  drivers/dma-buf/dma-heap.c | 41 ++
>  include/linux/dma-heap.h   | 35 
>  2 files changed, 68 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
> index c9e41e8a9e27..0f7cf713c22f 100644
> --- a/drivers/dma-buf/dma-heap.c
> +++ b/drivers/dma-buf/dma-heap.c
> @@ -31,6 +31,7 @@
>   * @heap_devt  heap device node
>   * @list   list head connecting to list of heaps
>   * @heap_cdev  heap char device
> + * @dev:   heap device in sysfs
>   *
>   * Represents a heap of memory from which buffers can be made.
>   */
> @@ -41,6 +42,7 @@ struct dma_heap {
> dev_t heap_devt;
> struct list_head list;
> struct cdev heap_cdev;
> +   struct device *dev;
>  };
>
>  static LIST_HEAD(heap_list);
> @@ -49,6 +51,33 @@ static dev_t dma_heap_devt;
>  static struct class *dma_heap_class;
>  static DEFINE_XARRAY_ALLOC(dma_heap_minors);
>
> +int dma_heap_create_device_link(struct device *dev, const char *heap)
> +{
> +   struct dma_heap *h;
> +
> +   /* check the name is valid */
> +   mutex_lock(_list_lock);
> +   list_for_each_entry(h, _list, list) {
> +   if (!strcmp(h->name, heap))
> +   break;
> +   }
> +   mutex_unlock(_list_lock);
> +
> +   if (list_entry_is_head(h, _list, list)) {
> +   pr_err("dma_heap: Link to invalid heap requested %s\n", heap);
> +   return -EINVAL;
> +   }
> +
> +   return sysfs_create_link(>kobj, >dev->kobj, DEVNAME);
> +}

So, one concern with this (if I'm reading this right) is it seems like
a single heap link may be insufficient.

There may be multiple heaps that a driver could work with (especially
if the device isn't very constrained), so when sharing a buffer with a
second device that is more constrained we'd have the same problem we
have now where userspace just needs to know which device is the more
constrained one to allocate for.

So it might be useful to have a sysfs "dma_heaps" directory with the
supported heaps linked from there? That way userland could find across
the various devices the heap-link that was common.

This still has the downside that every driver needs to be aware of
every heap, and when new heaps are added, it may take awhile before
folks might be able to assess if a device is compatible or not to
update it, so I suspect we'll have eventually some loose
constraint-based helpers to register links. But I think this at least
moves us in a workable direction, so again, I'm really glad to see you
send this out!

thanks
-john


Re: DMA-heap driver hints

2023-01-23 Thread James Jones

On 1/23/23 08:58, Laurent Pinchart wrote:

Hi Christian,

On Mon, Jan 23, 2023 at 05:29:18PM +0100, Christian König wrote:

Am 23.01.23 um 14:55 schrieb Laurent Pinchart:

Hi Christian,

CC'ing James as I think this is related to his work on the unix device
memory allocator ([1]).


Thank you for including me.


[1] 
https://lore.kernel.org/dri-devel/8b555674-1c5b-c791-4547-2ea7c16ae...@nvidia.com/

On Mon, Jan 23, 2023 at 01:37:54PM +0100, Christian König wrote:

Hi guys,

this is just an RFC! The last time we discussed the DMA-buf coherency
problem [1] we concluded that DMA-heap first needs a better way to
communicate to userspace which heap to use for a certain device.

As far as I know userspace currently just hard codes that information
which is certainly not desirable considering that we should have this
inside the kernel as well.

So what those two patches here do is to first add some
dma_heap_create_device_link() and  dma_heap_remove_device_link()
function and then demonstrating the functionality with uvcvideo
driver.

The preferred DMA-heap is represented with a symlink in sysfs between
the device and the virtual DMA-heap device node.


I'll start with a few high-level comments/questions:

- Instead of tying drivers to heaps, have you considered a system where
a driver would expose constraints, and a heap would then be selected
based on those constraints ? A tight coupling between heaps and
drivers means downstream patches to drivers in order to use
vendor-specific heaps, that sounds painful.


I was wondering the same thing as well, but came to the conclusion that
just the other way around is the less painful approach.


 From a kernel point of view, sure, it's simpler and thus less painful.
 From the point of view of solving the whole issue, I'm not sure :-)


The problem is that there are so many driver specific constrains that I
don't even know where to start from.


That's where I was hoping James would have some feedback for us, based
on the work he did on the Unix device memory allocator. If that's not
the case, we can brainstorm this from scratch.


Simon Ser's and my presentation from XDC 2020 focused entirely on this. 
The idea was not to try to enumerate every constraint up front, but 
rather to develop an extensible mechanism that would be flexible enough 
to encapsulate many disparate types of constraints and perform set 
operations on them (merging sets was the only operation we tried to 
solve). Simon implemented a prototype header-only library to implement 
the mechanism:


https://gitlab.freedesktop.org/emersion/drm-constraints

The links to the presentation and talk are below, along with notes from 
the follow-up workshop.


https://lpc.events/event/9/contributions/615/attachments/704/1301/XDC_2020__Allocation_Constraints.pdf
https://www.youtube.com/watch?v=HZEClOP5TIk
https://paste.sr.ht/~emersion/c43b30be08bab1882f1b107402074462bba3b64a

Note one of the hard parts of this was figuring out how to express a 
device or heap within the constraint structs. One of the better ideas 
proposed back then was something like heap IDs, where dma heaps would 
each have one, and devices could register their own heaps (or even just 
themselves?) with the heap subsystem and be assigned a locally-unique ID 
that userspace could pass around. This sounds similar to what you're 
proposing. Perhaps a reasonable identifier is a device (major, minor) 
pair. Such a constraint could be expressed as a symlink for easy 
visualization/discoverability from userspace, but might be easier to 
serialize over the wire as the (major, minor) pair. I'm not clear which 
direction is better to express this either: As a link from heap->device, 
or device->heap.



A constraint-based system would also, I think, be easier to extend
with additional constraints in the future.

- I assume some drivers will be able to support multiple heaps. How do
you envision this being implemented ?


I don't really see an use case for this.


One use case I know of here is same-vendor GPU local memory on different 
GPUs. NVIDIA GPUs have certain things they can only do on local memory, 
certain things they can do on all memory, and certain things they can 
only do on memory local to another NVIDIA GPU, especially when there 
exists an NVLink interface between the two. So they'd ideally express 
different constraints for heap representing each of those.


The same thing is often true of memory on remote devices that are at 
various points in a PCIe topology. We've had situations where we could 
only get enough bandwidth between two PCIe devices when they were less 
than some number of hops away on the PCI tree. We hard-coded logic to 
detect that in our userspace drivers, but we could instead expose it as 
a constraint on heaps that would express which devices can accomplish 
certain operations as pairs.


Similarly to the last one, I would assume (But haven't yet run into in 
my personal experience) 

Re: [PATCH 2/2] media: uvcvideo: expose dma-heap hint to userspace

2023-01-23 Thread kernel test robot
Hi Christian,

I love your patch! Perhaps something to improve:

[auto build test WARNING on drm-misc/drm-misc-next]
[also build test WARNING on media-tree/master drm-tip/drm-tip linus/master 
v6.2-rc5]
[cannot apply to next-20230123]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:
https://github.com/intel-lab-lkp/linux/commits/Christian-K-nig/media-uvcvideo-expose-dma-heap-hint-to-userspace/20230123-213836
base:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link:
https://lore.kernel.org/r/20230123123756.401692-3-christian.koenig%40amd.com
patch subject: [PATCH 2/2] media: uvcvideo: expose dma-heap hint to userspace
config: i386-randconfig-a002-20230123 
(https://download.01.org/0day-ci/archive/20230124/202301241137.qt2rnq5t-...@intel.com/config)
compiler: gcc-11 (Debian 11.3.0-8) 11.3.0
reproduce (this is a W=1 build):
# 
https://github.com/intel-lab-lkp/linux/commit/adc04dccd892eec7f84c6ec112b48df376172e48
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review 
Christian-K-nig/media-uvcvideo-expose-dma-heap-hint-to-userspace/20230123-213836
git checkout adc04dccd892eec7f84c6ec112b48df376172e48
# save the config file
mkdir build_dir && cp config build_dir/.config
make W=1 O=build_dir ARCH=i386 olddefconfig
make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash drivers/media/usb/uvc/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

   In file included from drivers/media/usb/uvc/uvc_driver.c:10:
>> include/linux/dma-heap.h:92:5: warning: no previous prototype for 
>> 'dma_heap_create_device_link' [-Wmissing-prototypes]
  92 | int dma_heap_create_device_link(struct device *dev, const char *heap)
 | ^~~
>> include/linux/dma-heap.h:97:6: warning: no previous prototype for 
>> 'dma_heap_remove_device_link' [-Wmissing-prototypes]
  97 | void dma_heap_remove_device_link(struct device *dev)
 |  ^~~


vim +/dma_heap_create_device_link +92 include/linux/dma-heap.h

4ce5c5c0cf31f4 Christian König 2023-01-23   91  
4ce5c5c0cf31f4 Christian König 2023-01-23  @92  int 
dma_heap_create_device_link(struct device *dev, const char *heap)
4ce5c5c0cf31f4 Christian König 2023-01-23   93  {
4ce5c5c0cf31f4 Christian König 2023-01-23   94  return 0;
4ce5c5c0cf31f4 Christian König 2023-01-23   95  }
4ce5c5c0cf31f4 Christian König 2023-01-23   96  
4ce5c5c0cf31f4 Christian König 2023-01-23  @97  void 
dma_heap_remove_device_link(struct device *dev)
4ce5c5c0cf31f4 Christian König 2023-01-23   98  {
4ce5c5c0cf31f4 Christian König 2023-01-23   99  }
4ce5c5c0cf31f4 Christian König 2023-01-23  100  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests


Re: [Intel-gfx] [PATCH v5 2/6] drm/i915/pxp: add device link between i915 and mei_pxp

2023-01-23 Thread Teres Alexis, Alan Previn

On Mon, 2023-01-23 at 09:31 -0500, Vivi, Rodrigo wrote:
> On Sun, Jan 22, 2023 at 06:57:24AM +, Usyskin, Alexander wrote:
> > > > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
> > > b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
> > > > index d50354bfb993..bef6d7f8ac55 100644
> > > > --- a/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
> > > > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_tee.c
> > > > @@ -127,6 +127,10 @@ static int i915_pxp_tee_component_bind(struct
> > > 
alan:snip.

Thanks Jani, Rodrigo and Alex. I'll re-rev with all of Rodrigo's recommendation:
- will break down the initial code so we dont hide device-link behind 
drm_WARN_ON 
- since i didnt hear any hard objection - I will stick with Rodrigo's 
recommendation to stash the device-link.
- dont need DL_FLAG_PM_RUNTIME
- use -ENODEV

probably like this:

if (!HAS_HECI_PXP(i915)) {
pxp->component_dev_link = device_link_add(i915_kdev, tee_kdev, 
DL_FLAG_STATELESS);
if (drm_WARN_ON(>drm, !pxp->component_dev_link))
return -ENODEV;
}


alan:snip.


Re: [Freedreno] [PATCH] drm/msm/dpu: sc7180: add missing WB2 clock control

2023-01-23 Thread Jessica Zhang




On 1/16/2023 2:30 AM, Dmitry Baryshkov wrote:

Add missing DPU_CLK_CTRL_WB2 to sc7180_mdp clocks array.

Fixes: 51e4d60e6ba5 ("drm/msm/dpu: add writeback support for sc7180")
Signed-off-by: Dmitry Baryshkov 


Tested-by: Jessica Zhang  # Trogdor (sc7180)


---
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index 504a22c76412..c7103b0445b6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -546,6 +546,8 @@ static const struct dpu_mdp_cfg sc7180_mdp[] = {
.reg_off = 0x2B4, .bit_off = 8},
.clk_ctrls[DPU_CLK_CTRL_DMA2] = {
.reg_off = 0x2C4, .bit_off = 8},
+   .clk_ctrls[DPU_CLK_CTRL_WB2] = {
+   .reg_off = 0x3B8, .bit_off = 24},
},
  };
  
--

2.39.0



Re: [PATCH v2 1/3] drm/msm/mdss: convert UBWC setup to use match data

2023-01-23 Thread Abhinav Kumar




On 1/19/2023 9:26 PM, Dmitry Baryshkov wrote:

On Fri, 20 Jan 2023 at 00:54, Abhinav Kumar  wrote:




On 1/17/2023 5:04 PM, Dmitry Baryshkov wrote:

To simplify adding new platforms and to make settings more obvious,
rewrite the UBWC setup to use the data structure to pass platform config
rather than just calling the functions direcly.

Signed-off-by: Dmitry Baryshkov 


I was reviewing this series and
https://patchwork.freedesktop.org/series/111732/ together.

More I think about it, it seems like we are duplicating the same values
here and in the catalog.

Yes, these two are different drivers.

But now that you are adding the UBWC entries here using the compatible
string so you are creating something like a "catalog" here.

In that case, why dont we remove the entries from dpu catalog and in the
DPU driver get the parent's match data as we know that the msm_mdss is
the parent of DPU driver


I should give it a thought, especially since we are trying to clean up
the DPU catalog.


I just went through the cover letter of 
https://patchwork.freedesktop.org/patch/519752/ and it mentions


"My itent is to land both series and then to make
DPU request this data from the MDSS driver"

This means that the parent data suggestion will be implemented?





Let me know your thoughts.


---
   drivers/gpu/drm/msm/msm_mdss.c | 181 +++--
   1 file changed, 105 insertions(+), 76 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c
index 02646e4bb4cd..799672b88716 100644
--- a/drivers/gpu/drm/msm/msm_mdss.c
+++ b/drivers/gpu/drm/msm/msm_mdss.c
@@ -16,9 +16,6 @@
   #include "msm_drv.h"
   #include "msm_kms.h"

-/* for DPU_HW_* defines */
-#include "disp/dpu1/dpu_hw_catalog.h"
-
   #define HW_REV  0x0
   #define HW_INTR_STATUS  0x0010

@@ -29,6 +26,16 @@

   #define MIN_IB_BW   4UL /* Min ib vote 400MB */

+struct msm_mdss_data {
+ u32 ubwc_version;
+ /* can be read from register 0x58 */
+ u32 ubwc_dec_version;
+ u32 ubwc_swizzle;
+ u32 ubwc_static;
+ u32 highest_bank_bit;
+ u32 macrotile_mode;
+};
+
   struct msm_mdss {
   struct device *dev;

@@ -40,6 +47,7 @@ struct msm_mdss {
   unsigned long enabled_mask;
   struct irq_domain *domain;
   } irq_controller;
+ const struct msm_mdss_data *mdss_data;
   struct icc_path *path[2];
   u32 num_paths;
   };
@@ -182,46 +190,40 @@ static int _msm_mdss_irq_domain_add(struct msm_mdss 
*msm_mdss)
   #define UBWC_3_0 0x3000
   #define UBWC_4_0 0x4000

-static void msm_mdss_setup_ubwc_dec_20(struct msm_mdss *msm_mdss,
-u32 ubwc_static)
+static void msm_mdss_setup_ubwc_dec_20(struct msm_mdss *msm_mdss)
   {
- writel_relaxed(ubwc_static, msm_mdss->mmio + UBWC_STATIC);
+ const struct msm_mdss_data *data = msm_mdss->mdss_data;
+
+ writel_relaxed(data->ubwc_static, msm_mdss->mmio + UBWC_STATIC);
   }

-static void msm_mdss_setup_ubwc_dec_30(struct msm_mdss *msm_mdss,
-unsigned int ubwc_version,
-u32 ubwc_swizzle,
-u32 highest_bank_bit,
-u32 macrotile_mode)
+static void msm_mdss_setup_ubwc_dec_30(struct msm_mdss *msm_mdss)
   {
- u32 value = (ubwc_swizzle & 0x1) |
- (highest_bank_bit & 0x3) << 4 |
- (macrotile_mode & 0x1) << 12;
+ const struct msm_mdss_data *data = msm_mdss->mdss_data;
+ u32 value = (data->ubwc_swizzle & 0x1) |
+ (data->highest_bank_bit & 0x3) << 4 |
+ (data->macrotile_mode & 0x1) << 12;

- if (ubwc_version == UBWC_3_0)
+ if (data->ubwc_version == UBWC_3_0)
   value |= BIT(10);

- if (ubwc_version == UBWC_1_0)
+ if (data->ubwc_version == UBWC_1_0)
   value |= BIT(8);

   writel_relaxed(value, msm_mdss->mmio + UBWC_STATIC);
   }

-static void msm_mdss_setup_ubwc_dec_40(struct msm_mdss *msm_mdss,
-unsigned int ubwc_version,
-u32 ubwc_swizzle,
-u32 ubwc_static,
-u32 highest_bank_bit,
-u32 macrotile_mode)
+static void msm_mdss_setup_ubwc_dec_40(struct msm_mdss *msm_mdss)
   {
- u32 value = (ubwc_swizzle & 0x7) |
- (ubwc_static & 0x1) << 3 |
- (highest_bank_bit & 0x7) << 4 |
- (macrotile_mode & 0x1) << 12;
+ const struct msm_mdss_data *data = msm_mdss->mdss_data;
+ u32 value = (data->ubwc_swizzle & 0x7) |
+ (data->ubwc_static & 0x1) << 3 |
+ (data->highest_bank_bit & 0x7) << 4 |
+ (data->macrotile_mode & 0x1) << 12;

   writel_relaxed(value, msm_mdss->mmio + UBWC_STATIC);

- if 

Re: [PATCH] drm/msm: use strscpy instead of strncpy

2023-01-23 Thread Abhinav Kumar




On 1/17/2023 6:01 PM, Dmitry Baryshkov wrote:

Using strncpy can result in non-NULL-terminated destination string. Use
strscpy instead. This fixes following warning:

drivers/gpu/drm/msm/msm_fence.c: In function ‘msm_fence_context_alloc’:
drivers/gpu/drm/msm/msm_fence.c:25:9: warning: ‘strncpy’ specified bound 32 
equals destination size [-Wstringop-truncation]
25 | strncpy(fctx->name, name, sizeof(fctx->name));
   | ^

Fixes: f97decac5f4c ("drm/msm: Support multiple ringbuffers")
Signed-off-by: Dmitry Baryshkov 


Reviewed-by: Abhinav Kumar 


---
  drivers/gpu/drm/msm/msm_fence.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/msm_fence.c b/drivers/gpu/drm/msm/msm_fence.c
index a47e5837c528..56641408ea74 100644
--- a/drivers/gpu/drm/msm/msm_fence.c
+++ b/drivers/gpu/drm/msm/msm_fence.c
@@ -22,7 +22,7 @@ msm_fence_context_alloc(struct drm_device *dev, volatile 
uint32_t *fenceptr,
return ERR_PTR(-ENOMEM);
  
  	fctx->dev = dev;

-   strncpy(fctx->name, name, sizeof(fctx->name));
+   strscpy(fctx->name, name, sizeof(fctx->name));
fctx->context = dma_fence_context_alloc(1);
fctx->index = index++;
fctx->fenceptr = fenceptr;


Re: [PATCH v2] drm/msm/dpu: add missing ubwc_swizzle setting to catalog

2023-01-23 Thread Abhinav Kumar




On 1/22/2023 10:24 PM, Dmitry Baryshkov wrote:

Use the values from the vendor DTs to set ubwc_swizzle in the catalog.

Signed-off-by: Dmitry Baryshkov 


Matches all the vendor DTs, hence

Reviewed-by: Abhinav Kumar 


---

Changes since v1:
- Added data for sc7280 and sm8550

---
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 5 +
  1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index e45799e9fe49..b16e550fc4b6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -580,6 +580,7 @@ static const struct dpu_mdp_cfg sm6115_mdp[] = {
.base = 0x0, .len = 0x494,
.features = 0,
.highest_bank_bit = 0x1,
+   .ubwc_swizzle = 0x7,
.clk_ctrls[DPU_CLK_CTRL_VIG0] = {
.reg_off = 0x2ac, .bit_off = 0},
.clk_ctrls[DPU_CLK_CTRL_DMA0] = {
@@ -593,6 +594,7 @@ static const struct dpu_mdp_cfg sm8250_mdp[] = {
.base = 0x0, .len = 0x494,
.features = 0,
.highest_bank_bit = 0x3, /* TODO: 2 for LP_DDR4 */
+   .ubwc_swizzle = 0x6,
.clk_ctrls[DPU_CLK_CTRL_VIG0] = {
.reg_off = 0x2AC, .bit_off = 0},
.clk_ctrls[DPU_CLK_CTRL_VIG1] = {
@@ -649,6 +651,7 @@ static const struct dpu_mdp_cfg sm8450_mdp[] = {
.base = 0x0, .len = 0x494,
.features = BIT(DPU_MDP_PERIPH_0_REMOVED),
.highest_bank_bit = 0x3, /* TODO: 2 for LP_DDR4 */
+   .ubwc_swizzle = 0x6,
.clk_ctrls[DPU_CLK_CTRL_VIG0] = {
.reg_off = 0x2AC, .bit_off = 0},
.clk_ctrls[DPU_CLK_CTRL_VIG1] = {
@@ -675,6 +678,7 @@ static const struct dpu_mdp_cfg sc7280_mdp[] = {
.name = "top_0", .id = MDP_TOP,
.base = 0x0, .len = 0x2014,
.highest_bank_bit = 0x1,
+   .ubwc_swizzle = 0x6,
.clk_ctrls[DPU_CLK_CTRL_VIG0] = {
.reg_off = 0x2AC, .bit_off = 0},
.clk_ctrls[DPU_CLK_CTRL_DMA0] = {
@@ -711,6 +715,7 @@ static const struct dpu_mdp_cfg sm8550_mdp[] = {
.base = 0, .len = 0x494,
.features = BIT(DPU_MDP_PERIPH_0_REMOVED),
.highest_bank_bit = 0x3, /* TODO: 2 for LP_DDR4 */
+   .ubwc_swizzle = 0x6,
.clk_ctrls[DPU_CLK_CTRL_VIG0] = {
.reg_off = 0x4330, .bit_off = 0},
.clk_ctrls[DPU_CLK_CTRL_VIG1] = {


Re: [PATCH] drm/msm/dpu: drop stale comment from struct dpu_mdp_cfg doc

2023-01-23 Thread Abhinav Kumar




On 1/21/2023 5:54 AM, Dmitry Baryshkov wrote:

The field ubwc_static was removed from struct dpu_mdp_cfg some time ago.
Drop the corresponding kerneldoc now.

Fixes: 544d8b96150d ("drm/msm/dpu: update UBWC config for sm8150 and sm8250")
Signed-off-by: Dmitry Baryshkov 


Reviewed-by: Abhinav Kumar 


---
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 1 -
  1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
index d152fef438f9..a56581b34ddf 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -539,7 +539,6 @@ struct dpu_clk_ctrl_reg {
   * @base:  register base offset to mdss
   * @features   bit mask identifying sub-blocks/features
   * @highest_bank_bit:  UBWC parameter
- * @ubwc_static:   ubwc static configuration
   * @ubwc_swizzle:  ubwc default swizzle setting
   * @clk_ctrls  clock control register definition
   */


Re: [PATCH] drm/msm/dpu: disable features unsupported by QCM2290

2023-01-23 Thread Abhinav Kumar




On 1/22/2023 11:11 PM, Dmitry Baryshkov wrote:

QCM2290 doesn't seem to support reg-dma, smart-dma, UBWC, CDP, exclusion
rectangles and CSC. Drop corresponding features being incorrectly
enabled for qcm2290.



Can you please point me to which vendor DT you are referring to for this?

CSC is supported on the VIG SSPPs from what I can see.

QCM2290 should be using the same MDP version as 6115 from the HW version.



Cc: Loic Poulain 
Fixes: 5334087ee743 ("drm/msm: add support for QCM2290 MDSS")
Signed-off-by: Dmitry Baryshkov 
---
  .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 20 +++
  1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index 289fb11f99d1..1c3ffa922794 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -12,10 +12,14 @@
  #include "dpu_hw_catalog.h"
  #include "dpu_kms.h"
  
-#define VIG_MASK \

+#define VIG_BASE_MASK \
(BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) |\
+   BIT(DPU_SSPP_TS_PREFILL))
+
+#define VIG_MASK \
+   (VIG_BASE_MASK | \
BIT(DPU_SSPP_CSC_10BIT) | BIT(DPU_SSPP_CDP) |\
-   BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_EXCL_RECT))
+   BIT(DPU_SSPP_EXCL_RECT))
  
  #define VIG_MSM8998_MASK \

(VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
@@ -29,7 +33,7 @@
  #define VIG_SM8250_MASK \
(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3LITE))
  
-#define VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))

+#define VIG_QCM2290_MASK (VIG_BASE_MASK | BIT(DPU_SSPP_QOS_8LVL))
  
  #define DMA_MSM8998_MASK \

(BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) |\
@@ -50,6 +54,10 @@
  #define DMA_CURSOR_MSM8998_MASK \
(DMA_MSM8998_MASK | BIT(DPU_SSPP_CURSOR))
  
+#define DMA_QCM2290_MASK \

+   (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_QOS_8LVL) |\
+   BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1))
+
  #define MIXER_MSM8998_MASK \
(BIT(DPU_MIXER_SOURCESPLIT) | BIT(DPU_DIM_LAYER))
  
@@ -316,8 +324,6 @@ static const struct dpu_caps msm8998_dpu_caps = {

  static const struct dpu_caps qcm2290_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0x4,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
-   .ubwc_version = DPU_HW_UBWC_VER_20,
.has_dim_layer = true,
.has_idle_pc = true,
.max_linewidth = 2160,
@@ -1384,7 +1390,7 @@ static const struct dpu_sspp_sub_blks qcm2290_dma_sblk_0 = 
_DMA_SBLK("8", 1);
  static const struct dpu_sspp_cfg qcm2290_sspp[] = {
SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_QCM2290_MASK,
 qcm2290_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
-   SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000,  DMA_SDM845_MASK,
+   SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000,  DMA_QCM2290_MASK,
 qcm2290_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
  };
  
@@ -2836,8 +2842,6 @@ static const struct dpu_mdss_cfg qcm2290_dpu_cfg = {

.intf = qcm2290_intf,
.vbif_count = ARRAY_SIZE(sdm845_vbif),
.vbif = sdm845_vbif,
-   .reg_dma_count = 1,
-   .dma_cfg = _regdma,
.perf = _perf_data,
.mdss_irqs = IRQ_SC7180_MASK,
  };


Re: [PATCH] drm/msm/dpu: sc7180: add missing WB2 clock control

2023-01-23 Thread Abhinav Kumar




On 1/16/2023 2:30 AM, Dmitry Baryshkov wrote:

Add missing DPU_CLK_CTRL_WB2 to sc7180_mdp clocks array.

Fixes: 51e4d60e6ba5 ("drm/msm/dpu: add writeback support for sc7180")
Signed-off-by: Dmitry Baryshkov 


Reviewed-by: Abhinav Kumar 


---
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index 504a22c76412..c7103b0445b6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -546,6 +546,8 @@ static const struct dpu_mdp_cfg sc7180_mdp[] = {
.reg_off = 0x2B4, .bit_off = 8},
.clk_ctrls[DPU_CLK_CTRL_DMA2] = {
.reg_off = 0x2C4, .bit_off = 8},
+   .clk_ctrls[DPU_CLK_CTRL_WB2] = {
+   .reg_off = 0x3B8, .bit_off = 24},
},
  };
  


Re: [PATCH] drm/msm/dpu: fix sm8450 CTL configuration

2023-01-23 Thread Abhinav Kumar




On 1/23/2023 12:08 AM, Dmitry Baryshkov wrote:

Correct the CTL size on sm8450 platform. This fixes the incorrect merge
of sm8350 support, which unfortunately also touched the SM8450 setup.

Fixes: 0e91bcbb0016 ("drm/msm/dpu: Add SM8350 to hw catalog")
Signed-off-by: Dmitry Baryshkov 


Matches the vendor DT size for sm8450, hence

Reviewed-by: Abhinav Kumar 


---
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 10 +-
  1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index 63a0fa3b0a17..9060dce51e2e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -1017,31 +1017,31 @@ static const struct dpu_ctl_cfg sm8450_ctl[] = {
},
{
.name = "ctl_1", .id = CTL_1,
-   .base = 0x16000, .len = 0x1e8,
+   .base = 0x16000, .len = 0x204,
.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK,
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
},
{
.name = "ctl_2", .id = CTL_2,
-   .base = 0x17000, .len = 0x1e8,
+   .base = 0x17000, .len = 0x204,
.features = CTL_SC7280_MASK,
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
},
{
.name = "ctl_3", .id = CTL_3,
-   .base = 0x18000, .len = 0x1e8,
+   .base = 0x18000, .len = 0x204,
.features = CTL_SC7280_MASK,
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
},
{
.name = "ctl_4", .id = CTL_4,
-   .base = 0x19000, .len = 0x1e8,
+   .base = 0x19000, .len = 0x204,
.features = CTL_SC7280_MASK,
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
},
{
.name = "ctl_5", .id = CTL_5,
-   .base = 0x1a000, .len = 0x1e8,
+   .base = 0x1a000, .len = 0x204,
.features = CTL_SC7280_MASK,
.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23),
},


Re: [PATCH v1 04/14] drm/msm/dp: correct configure Colorimetry Indicator Field at MISC0

2023-01-23 Thread kernel test robot
Hi Kuogee,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on next-20230123]
[also build test WARNING on linus/master v6.2-rc5]
[cannot apply to drm-misc/drm-misc-next drm/drm-next drm-exynos/exynos-drm-next 
drm-intel/for-linux-next drm-intel/for-linux-next-fixes drm-tip/drm-tip 
v6.2-rc5 v6.2-rc4 v6.2-rc3]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:
https://github.com/intel-lab-lkp/linux/commits/Kuogee-Hsieh/drm-msm-dp-add-dpcd-read-of-both-dsc-and-fec-capability/20230124-022759
patch link:
https://lore.kernel.org/r/1674498274-6010-5-git-send-email-quic_khsieh%40quicinc.com
patch subject: [PATCH v1 04/14] drm/msm/dp: correct configure Colorimetry 
Indicator Field at MISC0
config: sparc-allyesconfig 
(https://download.01.org/0day-ci/archive/20230124/202301240836.ik3aytbc-...@intel.com/config)
compiler: sparc64-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# 
https://github.com/intel-lab-lkp/linux/commit/834f569a141af42cb93424c24e7d146f3b88405b
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review 
Kuogee-Hsieh/drm-msm-dp-add-dpcd-read-of-both-dsc-and-fec-capability/20230124-022759
git checkout 834f569a141af42cb93424c24e7d146f3b88405b
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 
O=build_dir ARCH=sparc olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 
O=build_dir ARCH=sparc SHELL=/bin/bash drivers/gpu/drm/msm/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

>> drivers/gpu/drm/msm/dp/dp_panel.c:571: warning: This comment starts with 
>> '/**', but isn't a kernel-doc comment. Refer 
>> Documentation/doc-guide/kernel-doc.rst
* Mapper function which outputs colorimetry to be used for a


vim +571 drivers/gpu/drm/msm/dp/dp_panel.c

   569  
   570  /**
 > 571   * Mapper function which outputs colorimetry to be used for a
   572   * given colorspace value when misc field of MSA is used to
   573   * change the colorimetry. Currently only RGB formats have been
   574   * added. This API will be extended to YUV once its supported on DP.
   575   */
   576  u8 dp_panel_get_misc_colorimetry_val(struct dp_panel *dp_panel)
   577  {
   578  u8 colorimetry;
   579  u32 colorspace;
   580  u32 cc;
   581  struct dp_panel_private *panel;
   582  
   583  panel = container_of(dp_panel, struct dp_panel_private, 
dp_panel);
   584  
   585  cc = dp_link_get_colorimetry_config(panel->link);
   586  /*
   587   * If there is a non-zero value then compliance test-case
   588   * is going on, otherwise we can honor the colorspace setting
   589   */
   590  if (cc)
   591  return cc;
   592  
   593  colorspace = dp_panel->connector->state->colorspace;
   594  switch (colorspace) {
   595  case DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65:
   596  case DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER:
   597  colorimetry = 0x7;
   598  break;
   599  case DRM_MODE_COLORIMETRY_RGB_WIDE_FIXED:
   600  colorimetry = 0x3;
   601  break;
   602  case DRM_MODE_COLORIMETRY_RGB_WIDE_FLOAT:
   603  colorimetry = 0xb;
   604  break;
   605  case DRM_MODE_COLORIMETRY_OPRGB:
   606  colorimetry = 0xc;
   607  break;
   608  default:
   609  colorimetry = 0;
   610  }
   611  
   612  return colorimetry;
   613  }
   614  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests


Re: [PATCH Resend v11 00/15] Add PSR support for eDP

2023-01-23 Thread Dmitry Baryshkov

On 19/01/2023 16:26, Vinod Polimera wrote:

Changes in v2:
   - Use dp bridge to set psr entry/exit instead of dpu_enocder.
   - Don't modify whitespaces.
   - Set self refresh aware from atomic_check.
   - Set self refresh aware only if psr is supported.
   - Provide a stub for msm_dp_display_set_psr.
   - Move dp functions to bridge code.

Changes in v3:
   - Change callback names to reflect atomic interfaces.
   - Move bridge callback change to separate patch as suggested by Dmitry.
   - Remove psr function declaration from msm_drv.h.
   - Set self_refresh_aware flag only if psr is supported.
   - Modify the variable names to simpler form.
   - Define bit fields for PSR settings.
   - Add comments explaining the steps to enter/exit psr.
   - Change DRM_INFO to drm_dbg_db.

Changes in v4:
   - Move the get crtc functions to drm_atomic.
   - Add atomic functions for DP bridge too.
   - Add ternary operator to choose eDP or DP ops.
   - Return true/false instead of 1/0.
   - mode_valid missing in the eDP bridge ops.
   - Move the functions to get crtc into drm_atomic.c.
   - Fix compilation issues.
   - Remove dpu_assign_crtc and get crtc from drm_enc instead of dpu_enc.
   - Check for crtc state enable while reserving resources.

Changes in v5:
   - Move the mode_valid changes into a different patch.
   - Complete psr_op_comp only when isr is set.
   - Move the DP atomic callback changes to a different patch.
   - Get crtc from drm connector state crtc.
   - Move to separate patch for check for crtc state enable while
reserving resources.

Changes in v6:
   - Remove crtc from dpu_encoder_virt struct.
   - fix crtc check during vblank toggle crtc.
   - Misc changes.

Changes in v7:
   - Add fix for underrun issue on kasan build.

Changes in v8:
   - Drop the enc spinlock as it won't serve any purpose in
protetcing conn state.(Dmitry/Doug)

Changes in v9:
   - Update commit message and fix alignment using spaces.(Marijn)
   - Misc changes.(Marijn)

Changes in v10:
   - Get crtc cached in dpu_enc during obj init.(Dmitry)

Changes in v11:
   - Remove crtc cached in dpu_enc during obj init.
   - Update dpu_enc crtc state on crtc enable/disable during self refresh.

Sankeerth Billakanti (1):
   drm/msm/dp: disable self_refresh_aware after entering psr

Vinod Polimera (14):
   drm: add helper functions to retrieve old and new crtc
   drm/msm/dp: use atomic callbacks for DP bridge ops
   drm/msm/dp: Add basic PSR support for eDP
   drm/msm/dp: use the eDP bridge ops to validate eDP modes
   drm/bridge: use atomic enable/disable callbacks for panel bridge
   drm/bridge: add psr support for panel bridge callbacks
   drm/msm/disp/dpu: use atomic enable/disable callbacks for encoder
 functions
   drm/msm/disp/dpu: check for crtc enable rather than crtc active to
 release shared resources
   drm/msm/disp/dpu: add PSR support for eDP interface in dpu driver
   drm/msm/disp/dpu: get timing engine status from intf status register
   drm/msm/disp/dpu: wait for extra vsync till timing engine status is
 disabled
   drm/msm/disp/dpu: reset the datapath after timing engine disable
   drm/msm/disp/dpu: clear active interface in the datapath cleanup
   drm/msm/disp/dpu: update dpu_enc crtc state on crtc enable/disable
 during self refresh


1) Please move core patches to the beginning of the series, so that it 
is possible to pick them up separately


2) Please follow Daniel's comment in 
https://lore.kernel.org/all/Y7bMcLHr79uhfJv2@phenom.ffwll.local/ and 
apply corresponding Reviewed-by tags.




  drivers/gpu/drm/bridge/panel.c |  68 ++-
  drivers/gpu/drm/drm_atomic.c   |  60 +++
  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c   |  42 -
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c|  29 ++-
  .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c   |  22 +++
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c |   3 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |  12 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c|   8 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c|   2 +-
  drivers/gpu/drm/msm/dp/dp_catalog.c|  80 +
  drivers/gpu/drm/msm/dp/dp_catalog.h|   4 +
  drivers/gpu/drm/msm/dp/dp_ctrl.c   |  80 +
  drivers/gpu/drm/msm/dp/dp_ctrl.h   |   3 +
  drivers/gpu/drm/msm/dp/dp_display.c|  36 ++--
  drivers/gpu/drm/msm/dp/dp_display.h|   2 +
  drivers/gpu/drm/msm/dp/dp_drm.c| 196 -
  drivers/gpu/drm/msm/dp/dp_drm.h|   9 +-
  drivers/gpu/drm/msm/dp/dp_link.c   |  36 
  drivers/gpu/drm/msm/dp/dp_panel.c  |  22 +++
  drivers/gpu/drm/msm/dp/dp_panel.h  |   6 +
  drivers/gpu/drm/msm/dp/dp_reg.h|  27 +++
  include/drm/drm_atomic.h   |   7 +
  22 files changed, 710 

Re: [PATCH Resend v11 15/15] drm/msm/disp/dpu: update dpu_enc crtc state on crtc enable/disable during self refresh

2023-01-23 Thread Dmitry Baryshkov

On 19/01/2023 16:26, Vinod Polimera wrote:

Populate the enocder software structure to reflect the updated
crtc appropriately during crtc enable/disable for a new commit
while taking care of the self refresh transitions when crtc
disable is triggered from the drm self refresh library.

Signed-off-by: Vinod Polimera 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 31 ++-
  1 file changed, 26 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index d513aeb4..e8e456a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1013,14 +1013,23 @@ static void dpu_crtc_disable(struct drm_crtc *crtc,
  
crtc);
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
-   struct drm_encoder *encoder;
+   struct drm_encoder *encoder = NULL;


Why is this chunk necessary?


unsigned long flags;
bool release_bandwidth = false;
  
  	DRM_DEBUG_KMS("crtc%d\n", crtc->base.id);
  
-	if (old_crtc_state->self_refresh_active)

+   /* If disable is triggered while in self refresh mode,
+* reset the encoder software state so that in enable
+* it won't trigger a warn while assigning crtc.
+*/
+   if (old_crtc_state->self_refresh_active) {
+   drm_for_each_encoder_mask(encoder, crtc->dev,
+   old_crtc_state->encoder_mask) {
+   dpu_encoder_assign_crtc(encoder, NULL);
+   }
return;
+   }
  
  	/* Disable/save vblank irq handling */

drm_crtc_vblank_off(crtc);
@@ -1033,7 +1042,14 @@ static void dpu_crtc_disable(struct drm_crtc *crtc,
 */
if (dpu_encoder_get_intf_mode(encoder) == INTF_MODE_VIDEO)
release_bandwidth = true;
-   dpu_encoder_assign_crtc(encoder, NULL);
+
+   /*
+* If disable is triggered during psr active(e.g: screen dim in 
PSR),
+* we will need encoder->crtc connection to process the device 
sleep &
+* preserve it during psr sequence.
+*/
+   if (!crtc->state->self_refresh_active)
+   dpu_encoder_assign_crtc(encoder, NULL);
}
  
  	/* wait for frame_event_done completion */

@@ -1081,6 +1097,9 @@ static void dpu_crtc_enable(struct drm_crtc *crtc,
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
struct drm_encoder *encoder;
bool request_bandwidth = false;
+   struct drm_crtc_state *old_crtc_state;
+
+   old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
  
  	pm_runtime_get_sync(crtc->dev->dev);
  
@@ -1103,8 +1122,10 @@ static void dpu_crtc_enable(struct drm_crtc *crtc,

trace_dpu_crtc_enable(DRMID(crtc), true, dpu_crtc);
dpu_crtc->enabled = true;
  
-	drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask)

-   dpu_encoder_assign_crtc(encoder, crtc);
+   if (!old_crtc_state->self_refresh_active) {
+   drm_for_each_encoder_mask(encoder, crtc->dev, 
crtc->state->encoder_mask)
+   dpu_encoder_assign_crtc(encoder, crtc);
+   }
  
  	/* Enable/restore vblank irq handling */

drm_crtc_vblank_on(crtc);


--
With best wishes
Dmitry



Re: [PATCH Resend v11 14/15] drm/msm/disp/dpu: clear active interface in the datapath cleanup

2023-01-23 Thread Dmitry Baryshkov

On 19/01/2023 16:26, Vinod Polimera wrote:

Clear interface active register from the datapath for a clean shutdown of
the datapath.

Signed-off-by: Vinod Polimera 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 9cf1263..30dee50 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -2085,6 +2085,9 @@ void dpu_encoder_helper_phys_cleanup(struct 
dpu_encoder_phys *phys_enc)
if (phys_enc->hw_pp->merge_3d)
intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx;
  
+	if (phys_enc->hw_intf)

+   intf_cfg.intf = phys_enc->hw_intf->idx;
+
if (ctl->ops.reset_intf_cfg)
ctl->ops.reset_intf_cfg(ctl, _cfg);
  


This is already handled as a part of the commit
9811913a6dd0 ("drm/msm/dpu: populate wb or intf before reset_intf_cfg")
--
With best wishes
Dmitry



Re: [PATCH Resend v11 13/15] drm/msm/disp/dpu: reset the datapath after timing engine disable

2023-01-23 Thread Dmitry Baryshkov

On 19/01/2023 16:26, Vinod Polimera wrote:

Reset the datapath after disabling the timing gen, such that
it can start on a clean slate when the intf is enabled back.
This was a recommended sequence from the DPU HW programming guide.

Signed-off-by: Vinod Polimera 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 1 +
  1 file changed, 1 insertion(+)


Reviewed-by: Dmitry Baryshkov 

--
With best wishes
Dmitry



Re: [PATCH Resend v11 12/15] drm/msm/disp/dpu: wait for extra vsync till timing engine status is disabled

2023-01-23 Thread Dmitry Baryshkov

On 19/01/2023 16:26, Vinod Polimera wrote:

There can be a race between timing gen disable and vblank irq. The
wait post timing gen disable may return early but intf disable sequence
might not be completed. Ensure that, intf status is disabled before
we retire the function.

Signed-off-by: Vinod Polimera 


Reviewed-by: Dmitry Baryshkov 


---
  .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c| 21 +
  1 file changed, 21 insertions(+)


--
With best wishes
Dmitry



Re: [PATCH Resend v11 11/15] drm/msm/disp/dpu: get timing engine status from intf status register

2023-01-23 Thread Dmitry Baryshkov

On 19/01/2023 16:26, Vinod Polimera wrote:

Recommended way of reading the interface timing gen status is via
status register. Timing gen status register will give a reliable status
of the interface especially during ON/OFF transitions. This support was
added from DPU version 5.0.0.


5.0.0 is sm8150. I have expected to see INTF_SC7180_MASK to be changed, 
while this patch for some reason changes only INTF_SC7280_MASK. Could 
you please clarify this?




Signed-off-by: Vinod Polimera 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c |  3 ++-
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 12 +++-
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c|  8 +++-
  3 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index 4375e72..0244a7b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -80,7 +80,8 @@
  
  #define INTF_SC7180_MASK BIT(DPU_INTF_INPUT_CTRL) | BIT(DPU_INTF_TE)
  
-#define INTF_SC7280_MASK INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN)

+#define INTF_SC7280_MASK \
+   (INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN) | 
BIT(DPU_INTF_STATUS_SUPPORTED))
  
  #define IRQ_SDM845_MASK (BIT(MDP_SSPP_TOP0_INTR) | \

 BIT(MDP_SSPP_TOP0_INTR2) | \
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
index 978e3bd..79c18fe 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -213,17 +213,19 @@ enum {
  
  /**

   * INTF sub-blocks
- * @DPU_INTF_INPUT_CTRL Supports the setting of pp block from which
- *  pixel data arrives to this INTF
- * @DPU_INTF_TE INTF block has TE configuration support
- * @DPU_DATA_HCTL_ENAllows data to be transferred at different rate
-than video timing
+ * @DPU_INTF_INPUT_CTRL Supports the setting of pp block from which
+ *  pixel data arrives to this INTF
+ * @DPU_INTF_TE INTF block has TE configuration support
+ * @DPU_DATA_HCTL_ENAllows data to be transferred at different 
rate
+ *  than video timing
+ * @DPU_INTF_STATUS_SUPPORTED   INTF block has INTF_STATUS register
   * @DPU_INTF_MAX
   */
  enum {
DPU_INTF_INPUT_CTRL = 0x1,
DPU_INTF_TE,
DPU_DATA_HCTL_EN,
+   DPU_INTF_STATUS_SUPPORTED,
DPU_INTF_MAX
  };
  
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c

index 7ce66bf..84ee2ef 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
@@ -62,6 +62,7 @@
  #define   INTF_LINE_COUNT   0x0B0
  
  #define   INTF_MUX  0x25C

+#define   INTF_STATUS   0x26C
  
  #define INTF_CFG_ACTIVE_H_EN	BIT(29)

  #define INTF_CFG_ACTIVE_V_EN  BIT(30)
@@ -297,8 +298,13 @@ static void dpu_hw_intf_get_status(
struct intf_status *s)
  {
struct dpu_hw_blk_reg_map *c = >hw;
+   unsigned long cap = intf->cap->features;
+
+   if (cap & BIT(DPU_INTF_STATUS_SUPPORTED))
+   s->is_en = DPU_REG_READ(c, INTF_STATUS) & BIT(0);
+   else
+   s->is_en = DPU_REG_READ(c, INTF_TIMING_ENGINE_EN);
  
-	s->is_en = DPU_REG_READ(c, INTF_TIMING_ENGINE_EN);

s->is_prog_fetch_en = !!(DPU_REG_READ(c, INTF_CONFIG) & BIT(31));
if (s->is_en) {
s->frame_count = DPU_REG_READ(c, INTF_FRAME_COUNT);


--
With best wishes
Dmitry



Re: [PATCH Resend v11 05/15] drm/msm/dp: disable self_refresh_aware after entering psr

2023-01-23 Thread Dmitry Baryshkov

On 19/01/2023 16:26, Vinod Polimera wrote:

From: Sankeerth Billakanti 

Updated frames get queued if self_refresh_aware is set when the
sink is in psr. To support bridge enable and avoid queuing of update
frames, reset the self_refresh_aware state after entering psr.


I'm not convinced by this change. E.g. analogix code doesn't do this. 
Could you please clarify, why do you need to toggle the 
self_refresh_aware flag?




Signed-off-by: Sankeerth Billakanti 
Signed-off-by: Vinod Polimera 
---
  drivers/gpu/drm/msm/dp/dp_drm.c | 27 ++-
  1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c
index 029e08c..92d1a1b 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -134,6 +134,8 @@ static void edp_bridge_atomic_enable(struct drm_bridge 
*drm_bridge,
struct drm_crtc_state *old_crtc_state;
struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
struct msm_dp *dp = dp_bridge->dp_display;
+   struct drm_connector *connector;
+   struct drm_connector_state *conn_state = NULL;
  
  	/*

 * Check the old state of the crtc to determine if the panel
@@ -150,10 +152,22 @@ static void edp_bridge_atomic_enable(struct drm_bridge 
*drm_bridge,
  
  	if (old_crtc_state && old_crtc_state->self_refresh_active) {

dp_display_set_psr(dp, false);
-   return;
+   goto psr_aware;
}
  
  	dp_bridge_atomic_enable(drm_bridge, old_bridge_state);

+
+psr_aware:
+   connector = drm_atomic_get_new_connector_for_encoder(atomic_state,
+   drm_bridge->encoder);
+   if (connector)
+   conn_state = drm_atomic_get_new_connector_state(atomic_state,
+   connector);
+
+   if (conn_state) {
+   conn_state->self_refresh_aware = dp->psr_supported;
+   }


No need to wrap a single line statement in brackets.


+
  }
  
  static void edp_bridge_atomic_disable(struct drm_bridge *drm_bridge,

@@ -164,6 +178,14 @@ static void edp_bridge_atomic_disable(struct drm_bridge 
*drm_bridge,
struct drm_crtc_state *new_crtc_state = NULL, *old_crtc_state = NULL;
struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
struct msm_dp *dp = dp_bridge->dp_display;
+   struct drm_connector *connector;
+   struct drm_connector_state *conn_state = NULL;
+
+   connector = drm_atomic_get_old_connector_for_encoder(atomic_state,
+   drm_bridge->encoder);
+   if (connector)
+   conn_state = drm_atomic_get_new_connector_state(atomic_state,
+   connector);
  
  	crtc = drm_atomic_get_old_crtc_for_encoder(atomic_state,

   drm_bridge->encoder);
@@ -190,6 +212,9 @@ static void edp_bridge_atomic_disable(struct drm_bridge 
*drm_bridge,
 * when display disable occurs while the sink is in psr state.
 */
if (new_crtc_state->self_refresh_active) {
+   if (conn_state)
+   conn_state->self_refresh_aware = false;
+
dp_display_set_psr(dp, true);
return;
} else if (old_crtc_state->self_refresh_active) {


--
With best wishes
Dmitry



Re: [PATCH v2 8/9] drm/i915/pxp: On MTL, KCR enabling doesn't wait on tee component

2023-01-23 Thread Teres Alexis, Alan Previn
Thanks - will go with your suggestion - ditch all the abstraction / 
consolidation ..
add only the two additional calls with the explicit runtime-takes - that 
minimizes the changes.
And won't forget to the fix the '&' -> '&&'
...alan

On Wed, 2023-01-18 at 18:17 -0800, Ceraolo Spurio, Daniele wrote:
> 
> 
> On 1/11/2023 1:42 PM, Alan Previn wrote:
> > On legacy platforms, KCR HW enabling is done at the time the mei
> > component interface is bound. It's also disabled during unbind.
> > However, for MTL onwards, we don't depend on the tee-component
> > operation before we can start sending GSC-CS firmware messages.
> > 
> > Thus, immediately enable KCR HW on PXP's init, fini and resume.
alan:snip..


Re: [PATCH drm-next 03/14] drm: manager to keep track of GPUs VA mappings

2023-01-23 Thread Danilo Krummrich

On 1/24/23 00:23, Niranjana Vishwanathapura wrote:

On Wed, Jan 18, 2023 at 07:12:45AM +0100, Danilo Krummrich wrote:

This adds the infrastructure for a manager implementation to keep track
of GPU virtual address (VA) mappings.

New UAPIs, motivated by Vulkan sparse memory bindings graphics drivers
start implementing, allow userspace applications to request multiple and
arbitrary GPU VA mappings of buffer objects. The DRM GPU VA manager is
intended to serve the following purposes in this context.

1) Provide a dedicated range allocator to track GPU VA allocations and
  mappings, making use of the drm_mm range allocator.

2) Generically connect GPU VA mappings to their backing buffers, in
  particular DRM GEM objects.

3) Provide a common implementation to perform more complex mapping
  operations on the GPU VA space. In particular splitting and merging
  of GPU VA mappings, e.g. for intersecting mapping requests or partial
  unmap requests.

Idea-suggested-by: Dave Airlie 
Signed-off-by: Danilo Krummrich 
---
Documentation/gpu/drm-mm.rst    |   31 +
drivers/gpu/drm/Makefile    |    1 +
drivers/gpu/drm/drm_gem.c   |    3 +
drivers/gpu/drm/drm_gpuva_mgr.c | 1323 +++
include/drm/drm_drv.h   |    6 +
include/drm/drm_gem.h   |   75 ++
include/drm/drm_gpuva_mgr.h |  527 
7 files changed, 1966 insertions(+)
create mode 100644 drivers/gpu/drm/drm_gpuva_mgr.c
create mode 100644 include/drm/drm_gpuva_mgr.h

diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst
index a52e6f4117d6..c9f120cfe730 100644
--- a/Documentation/gpu/drm-mm.rst
+++ b/Documentation/gpu/drm-mm.rst
@@ -466,6 +466,37 @@ DRM MM Range Allocator Function References
.. kernel-doc:: drivers/gpu/drm/drm_mm.c
   :export:

+DRM GPU VA Manager
+==
+
+Overview
+
+
+.. kernel-doc:: drivers/gpu/drm/drm_gpuva_mgr.c
+   :doc: Overview
+
+Split and Merge
+---
+
+.. kernel-doc:: drivers/gpu/drm/drm_gpuva_mgr.c
+   :doc: Split and Merge
+
+Locking
+---
+
+.. kernel-doc:: drivers/gpu/drm/drm_gpuva_mgr.c
+   :doc: Locking
+
+
+DRM GPU VA Manager Function References
+--
+
+.. kernel-doc:: include/drm/drm_gpuva_mgr.h
+   :internal:
+
+.. kernel-doc:: drivers/gpu/drm/drm_gpuva_mgr.c
+   :export:
+
DRM Buddy Allocator
===

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 4fe190aee584..de2ffca3b6e4 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -45,6 +45,7 @@ drm-y := \
drm_vblank.o \
drm_vblank_work.o \
drm_vma_manager.o \
+    drm_gpuva_mgr.o \
drm_writeback.o
drm-$(CONFIG_DRM_LEGACY) += \
drm_agpsupport.o \
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 59a0bb5ebd85..65115fe88627 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -164,6 +164,9 @@ void drm_gem_private_object_init(struct drm_device 
*dev,

if (!obj->resv)
    obj->resv = >_resv;

+    if (drm_core_check_feature(dev, DRIVER_GEM_GPUVA))
+    drm_gem_gpuva_init(obj);
+
drm_vma_node_reset(>vma_node);
INIT_LIST_HEAD(>lru_node);
}
diff --git a/drivers/gpu/drm/drm_gpuva_mgr.c 
b/drivers/gpu/drm/drm_gpuva_mgr.c

new file mode 100644
index ..e665f642689d
--- /dev/null
+++ b/drivers/gpu/drm/drm_gpuva_mgr.c
@@ -0,0 +1,1323 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 Red Hat.
+ *
+ * Permission is hereby granted, free of charge, to any person 
obtaining a
+ * copy of this software and associated documentation files (the 
"Software"),
+ * to deal in the Software without restriction, including without 
limitation
+ * the rights to use, copy, modify, merge, publish, distribute, 
sublicense,

+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be 
included in

+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT 
SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, 
DAMAGES OR

+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Danilo Krummrich 
+ *
+ */
+
+#include 
+#include 
+
+/**
+ * DOC: Overview
+ *
+ * The DRM GPU VA Manager, represented by struct drm_gpuva_manager 
keeps track
+ * of a GPU's virtual address (VA) space and manages the 
corresponding virtual
+ * mappings represented by _gpuva objects. It also keeps track of 
the

+ * mapping's backing _gem_object buffers.
+ *
+ * _gem_object buffers 

Re: [PATCH v1 00/14] add display port DSC feature

2023-01-23 Thread Dmitry Baryshkov

On 23/01/2023 20:24, Kuogee Hsieh wrote:

This patch add DSC related supporting functions into to both dp controller and 
dpu enccoder

Kuogee Hsieh (14):
   drm/msm/dp: add dpcd read of both dsc and fec capability
   drm/msm/dp: add dsc factor into calculation of supported bpp
   drm/msm/dp: add configure mainlink_levels base on lane number
   drm/msm/dp: correct configure Colorimetry Indicator Field at MISC0
   drm/msm/dp: upgrade tu calculation base on newest algorithm
   drm/msm/dp: add display compression related struct
   drm/msm/dp: add dsc helper functions
   drm/msm/dp: add dsc supporting functions to DP controller
   drm/msm/dsi: export struct msm_compression_info to dpu encoder
   drm/msm/disp/dpu: add supports of DSC encoder v1.2 engine
   drm/msm/disp/dpu1: add supports of new flush mechanism
   drm/msm/disp/dpu1: revise timing engine programming to work for DSC
   drm/msm/disp/dpu1: add dsc supporting functions to dpu encoder
   drm/msm/disp/dpu1: add sc7280 dsc block and sub block


Some generic notes regarding the series. I understand that the the 
series is complex, but following points might ease both your work and 
the review proces.


First, atomicity. If your commit message says 'do this and that', it is 
highly likely that the patch should be split into smaller parts.


Second, please pay attention to the history. If some part of the code or 
 the data structure was removed, you have to justify bringing it back. 
This is extremely important in your case, as significant parts of the 
code come from the vendor code, thut it is easy to step on the same rake 
again. And if the previous removal was incorrect, please describe why.


If we went through 10 revisions of a patch a year ago, it's not worth 
sending again a patch that closely remedies one of early iterations. It 
doesn't stand a chance of getting through.


Next. Obvious item. ./scripts/checkpatch.pl should be your friend. It is 
not.


Last, but not least. Please follow the mailing list. Less than a week 
ago one of reviews pointed out that commit messages like 'this patch 
does this and that' are not really welcomed. By sending the same kind of 
commit messages, you stand a high chance of receiveing the same 
response. Please go through the recommendations in 
Documentation/process/submitting-patches.rst.




  drivers/gpu/drm/msm/Makefile   |   2 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.c | 537 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.h |  25 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c| 341 +++--
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h|   4 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h   |   7 +-
  .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c   |  43 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c |  50 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |  74 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c |  43 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h |  21 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c |  23 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h |  23 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c | 371 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c| 132 ++--
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h|  10 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h|   3 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h |   6 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c|  10 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c |  10 +-
  drivers/gpu/drm/msm/dp/dp_catalog.c| 176 -
  drivers/gpu/drm/msm/dp/dp_catalog.h|  97 ++-
  drivers/gpu/drm/msm/dp/dp_ctrl.c   | 839 ++---
  drivers/gpu/drm/msm/dp/dp_display.c|  61 +-
  drivers/gpu/drm/msm/dp/dp_link.c   |  29 +-
  drivers/gpu/drm/msm/dp/dp_panel.c  | 749 +-
  drivers/gpu/drm/msm/dp/dp_panel.h  |  67 +-
  drivers/gpu/drm/msm/dp/dp_reg.h|  40 +-
  drivers/gpu/drm/msm/dsi/dsi.c  |   3 +-
  drivers/gpu/drm/msm/dsi/dsi.h  |   3 +-
  drivers/gpu/drm/msm/dsi/dsi_host.c |  14 +-
  drivers/gpu/drm/msm/msm_drv.h  | 113 ++-
  32 files changed, 3429 insertions(+), 497 deletions(-)
  create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.c
  create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.h
  create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c



--
With best wishes
Dmitry



Re: [PATCH v1 05/14] drm/msm/dp: upgrade tu calculation base on newest algorithm

2023-01-23 Thread kernel test robot
Hi Kuogee,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on next-20230123]
[also build test WARNING on linus/master v6.2-rc5]
[cannot apply to drm-misc/drm-misc-next drm/drm-next drm-exynos/exynos-drm-next 
drm-intel/for-linux-next drm-intel/for-linux-next-fixes drm-tip/drm-tip 
v6.2-rc5 v6.2-rc4 v6.2-rc3]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:
https://github.com/intel-lab-lkp/linux/commits/Kuogee-Hsieh/drm-msm-dp-add-dpcd-read-of-both-dsc-and-fec-capability/20230124-022759
patch link:
https://lore.kernel.org/r/1674498274-6010-6-git-send-email-quic_khsieh%40quicinc.com
patch subject: [PATCH v1 05/14] drm/msm/dp: upgrade tu calculation base on 
newest algorithm
config: m68k-allmodconfig 
(https://download.01.org/0day-ci/archive/20230124/202301240854.5yjvg3rr-...@intel.com/config)
compiler: m68k-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# 
https://github.com/intel-lab-lkp/linux/commit/286a3dd6028ada56b471b5cb977f5ed461b094e4
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review 
Kuogee-Hsieh/drm-msm-dp-add-dpcd-read-of-both-dsc-and-fec-capability/20230124-022759
git checkout 286a3dd6028ada56b471b5cb977f5ed461b094e4
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 
O=build_dir ARCH=m68k olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 
O=build_dir ARCH=m68k SHELL=/bin/bash drivers/gpu/drm/msm/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

   drivers/gpu/drm/msm/dp/dp_ctrl.c: In function '_tu_param_compare':
   drivers/gpu/drm/msm/dp/dp_ctrl.c:282:20: warning: variable 'b_frac' set but 
not used [-Wunused-but-set-variable]
 282 | u32 b_int, b_frac, b_sign;
 |^~
   drivers/gpu/drm/msm/dp/dp_ctrl.c:282:13: warning: variable 'b_int' set but 
not used [-Wunused-but-set-variable]
 282 | u32 b_int, b_frac, b_sign;
 | ^
   drivers/gpu/drm/msm/dp/dp_ctrl.c:281:20: warning: variable 'a_frac' set but 
not used [-Wunused-but-set-variable]
 281 | u32 a_int, a_frac, a_sign;
 |^~
   drivers/gpu/drm/msm/dp/dp_ctrl.c:281:13: warning: variable 'a_int' set but 
not used [-Wunused-but-set-variable]
 281 | u32 a_int, a_frac, a_sign;
 | ^
   drivers/gpu/drm/msm/dp/dp_ctrl.c: In function 'dp_panel_update_tu_timings':
   drivers/gpu/drm/msm/dp/dp_ctrl.c:344:13: warning: variable 'overhead_dsc' 
set but not used [-Wunused-but-set-variable]
 344 | s64 overhead_dsc;
 | ^~~~
   In file included from drivers/gpu/drm/msm/dp/dp_ctrl.c:18:
   drivers/gpu/drm/msm/dp/dp_ctrl.c: In function '_dp_ctrl_calc_tu':
   drivers/gpu/drm/msm/dp/dp_ctrl.c:823:27: warning: format '%d' expects 
argument of type 'int', but argument 4 has type 's64' {aka 'long long int'} 
[-Wformat=]
 823 | DRM_DEBUG("Info: increase HBLANK_MARGIN to %d. 
(PLUS%d)\n", HBLANK_MARGIN,
 |   
^~~~  ~
 |  
   |
 |  
   s64 {aka long long int}
   include/drm/drm_print.h:524:65: note: in definition of macro '__drm_dbg'
 524 | #define __drm_dbg(fmt, ...) ___drm_dbg(NULL, fmt, 
##__VA_ARGS__)
 | 
^~~
   drivers/gpu/drm/msm/dp/dp_ctrl.c:823:17: note: in expansion of macro 
'DRM_DEBUG'
 823 | DRM_DEBUG("Info: increase HBLANK_MARGIN to %d. 
(PLUS%d)\n", HBLANK_MARGIN,
 | ^
   drivers/gpu/drm/msm/dp/dp_ctrl.c:823:61: note: format string is defined here
 823 | DRM_DEBUG("Info: increase HBLANK_MARGIN to %d. 
(PLUS%d)\n", HBLANK_MARGIN,
 |~^
 | |
 | int
 |%lld
   drivers/gpu/drm/msm/dp/dp_ctrl.c:823:27: warning: format '%d' expects 
argument of type 'int', but a

Re: [PATCH 2/2] media: uvcvideo: expose dma-heap hint to userspace

2023-01-23 Thread kernel test robot
Hi Christian,

I love your patch! Perhaps something to improve:

[auto build test WARNING on drm-misc/drm-misc-next]
[also build test WARNING on media-tree/master drm-tip/drm-tip linus/master 
v6.2-rc5]
[cannot apply to next-20230123]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:
https://github.com/intel-lab-lkp/linux/commits/Christian-K-nig/media-uvcvideo-expose-dma-heap-hint-to-userspace/20230123-213836
base:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link:
https://lore.kernel.org/r/20230123123756.401692-3-christian.koenig%40amd.com
patch subject: [PATCH 2/2] media: uvcvideo: expose dma-heap hint to userspace
config: hexagon-randconfig-r032-20230123 
(https://download.01.org/0day-ci/archive/20230124/202301240717.tim1ggho-...@intel.com/config)
compiler: clang version 16.0.0 (https://github.com/llvm/llvm-project 
4196ca3278f78c6e19246e54ab0ecb364e37d66a)
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# 
https://github.com/intel-lab-lkp/linux/commit/adc04dccd892eec7f84c6ec112b48df376172e48
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review 
Christian-K-nig/media-uvcvideo-expose-dma-heap-hint-to-userspace/20230123-213836
git checkout adc04dccd892eec7f84c6ec112b48df376172e48
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 
O=build_dir ARCH=hexagon olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 
O=build_dir ARCH=hexagon SHELL=/bin/bash drivers/media/usb/uvc/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

   In file included from drivers/media/usb/uvc/uvc_driver.c:10:
>> include/linux/dma-heap.h:92:5: warning: no previous prototype for function 
>> 'dma_heap_create_device_link' [-Wmissing-prototypes]
   int dma_heap_create_device_link(struct device *dev, const char *heap)
   ^
   include/linux/dma-heap.h:92:1: note: declare 'static' if the function is not 
intended to be used outside of this translation unit
   int dma_heap_create_device_link(struct device *dev, const char *heap)
   ^
   static 
>> include/linux/dma-heap.h:97:6: warning: no previous prototype for function 
>> 'dma_heap_remove_device_link' [-Wmissing-prototypes]
   void dma_heap_remove_device_link(struct device *dev)
^
   include/linux/dma-heap.h:97:1: note: declare 'static' if the function is not 
intended to be used outside of this translation unit
   void dma_heap_remove_device_link(struct device *dev)
   ^
   static 
   In file included from drivers/media/usb/uvc/uvc_driver.c:16:
   In file included from include/linux/usb.h:16:
   In file included from include/linux/interrupt.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/hexagon/include/asm/io.h:334:
   include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a 
null pointer has undefined behavior [-Wnull-pointer-arithmetic]
   val = __raw_readb(PCI_IOBASE + addr);
 ~~ ^
   include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a 
null pointer has undefined behavior [-Wnull-pointer-arithmetic]
   val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
   ~~ ^
   include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from 
macro '__le16_to_cpu'
   #define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
 ^
   In file included from drivers/media/usb/uvc/uvc_driver.c:16:
   In file included from include/linux/usb.h:16:
   In file included from include/linux/interrupt.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/hexagon/include/asm/io.h:334:
   include/asm-generic/io.h:573:61: warning: performing pointer arithmetic on a 
null pointer has undefined behavior [-Wnull-pointer-arithmetic]
   val = __le32_to_cpu((__le32

Re: [PATCH v1 05/14] drm/msm/dp: upgrade tu calculation base on newest algorithm

2023-01-23 Thread Dmitry Baryshkov

On 23/01/2023 20:24, Kuogee Hsieh wrote:

At display port, the pixel data is packed into TU (transfer units)
which is used to carry main video stream data during its horizontal active
period. TUs are mapping into the main-Link to facilitate the support of
various lane counts regardless of the pixel bit depth and colorimetry
format. Stuffing symbols are required if packed data rate less than link
symbol rate. TU size is calculated base on factors such as, pixel rate,
BPP, main link rate, main link lane and etc, and shall be 32 to 64
link symbols per lane. Each vendor has its own algorithm to calculate
TU size. This patch upgrade TU size calculation base on newest algorithm.

Signed-off-by: Kuogee Hsieh 
---
  drivers/gpu/drm/msm/dp/dp_ctrl.c | 702 +++
  1 file changed, 416 insertions(+), 286 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
index d0d1848..ae9c2b8 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
@@ -182,18 +182,24 @@ static void dp_ctrl_configure_source_params(struct 
dp_ctrl_private *ctrl)
   */
  struct tu_algo_data {
s64 lclk_fp;
+   s64 orig_lclk_fp;
s64 pclk_fp;
+   s64 orig_pclk_fp;
s64 lwidth;
s64 lwidth_fp;
+   int orig_lwidth;
s64 hbp_relative_to_pclk;
s64 hbp_relative_to_pclk_fp;
int nlanes;
+   int orig_hbp;
int bpp;
int pixelEnc;
int dsc_en;
int async_en;
+   int fec_en;
int bpc;
  
+	int rb2;

uint delay_start_link_extra_pixclk;
int extra_buffer_margin;
s64 ratio_fp;
@@ -250,19 +256,30 @@ struct tu_algo_data {
int even_distribution_BF;
int even_distribution_legacy;
int even_distribution;
+
+   int hbp_delayStartCheck;
+   int pre_tu_hw_pipe_delay;
+   int post_tu_hw_pipe_delay;
+   int link_config_hactive_time;
+   int delay_start_link_lclk;
+   int tu_active_cycles;
+   s64 parity_symbols;
+   int resolution_line_time;
+   int last_partial_lclk;
+
int min_hblank_violated;
s64 delay_start_time_fp;
s64 hbp_time_fp;
s64 hactive_time_fp;
s64 diff_abs_fp;
-
+   int second_loop_set;
s64 ratio;
  };
  
  static int _tu_param_compare(s64 a, s64 b)

  {
-   u32 a_sign;
-   u32 b_sign;
+   u32 a_int, a_frac, a_sign;
+   u32 b_int, b_frac, b_sign;
s64 a_temp, b_temp, minus_1;
  
  	if (a == b)

@@ -270,8 +287,12 @@ static int _tu_param_compare(s64 a, s64 b)
  
  	minus_1 = drm_fixp_from_fraction(-1, 1);
  
+	a_int = (a >> 32) & 0x7FFF;

+   a_frac = a & 0x;
a_sign = (a >> 32) & 0x8000 ? 1 : 0;
  
+	b_int = (b >> 32) & 0x7FFF;

+   b_frac = b & 0x;
b_sign = (b >> 32) & 0x8000 ? 1 : 0;
  
  	if (a_sign > b_sign)

@@ -295,6 +316,21 @@ static int _tu_param_compare(s64 a, s64 b)
}
  }
  
+static s64 fixp_subtract(s64 a, s64 b)

+{
+   s64 minus_1 = drm_fixp_from_fraction(-1, 1);
+
+   if (a >= b)
+   return a - b;
+
+   return drm_fixp_mul(b - a, minus_1);
+}
+
+static inline int fixp2int_ceil(s64 a)
+{
+   return a ? drm_fixp2int_ceil(a) : 0;
+}
+
  static void dp_panel_update_tu_timings(struct dp_tu_calc_input *in,
struct tu_algo_data *tu)
  {
@@ -305,6 +341,7 @@ static void dp_panel_update_tu_timings(struct 
dp_tu_calc_input *in,
s64 pclk_dsc_fp;
s64 dwidth_dsc_fp;
s64 hbp_dsc_fp;
+   s64 overhead_dsc;
  
  	int tot_num_eoc_symbols = 0;

int tot_num_hor_bytes   = 0;
@@ -315,16 +352,22 @@ static void dp_panel_update_tu_timings(struct 
dp_tu_calc_input *in,
s64 temp1_fp, temp2_fp, temp3_fp;
  
  	tu->lclk_fp  = drm_fixp_from_fraction(in->lclk, 1);

+   tu->orig_lclk_fp = tu->lclk_fp;
tu->pclk_fp  = drm_fixp_from_fraction(in->pclk_khz, 1000);
+   tu->orig_pclk_fp = tu->pclk_fp;
tu->lwidth   = in->hactive;
tu->hbp_relative_to_pclk = in->hporch;
tu->nlanes   = in->nlanes;
tu->bpp  = in->bpp;
tu->pixelEnc = in->pixel_enc;
tu->dsc_en   = in->dsc_en;
+   tu->fec_en   = in->fec_en;
tu->async_en = in->async_en;
tu->lwidth_fp= drm_fixp_from_fraction(in->hactive, 1);
+   tu->orig_lwidth  = in->hactive;
tu->hbp_relative_to_pclk_fp = drm_fixp_from_fraction(in->hporch, 1);
+   tu->orig_hbp = in->hporch;
+   tu->rb2  = (in->hporch <= 80) ? 1 : 0;
  
  	if (tu->pixelEnc == 420) {

temp1_fp = drm_fixp_from_fraction(2, 1);
@@ -378,6 +421,7 @@ static void dp_panel_update_tu_timings(struct 
dp_tu_calc_input *in,
dwidth_dsc_bytes = (tot_num_hor_bytes +
  

Re: [ANNOUNCE] pixfmtdb

2023-01-23 Thread Sebastian Wick
On Mon, Jan 23, 2023 at 11:43 PM Simon Ser  wrote:
>
> On Monday, January 23rd, 2023 at 21:25, Sebastian Wick 
>  wrote:
>
> > Why is the TF defined for GL formats and both the primaries and TF for
> > Vulkan formats? The only exception here should be sRGB formats. Where
> > did you get the information from?
>
> This is what upstream dfdutils does [1]. Can you explain why you think
> it should be undefined instead of linear?

The channels have no meaning. You can put whatever you want in there.
It doesn't have to be linear, it doesn't have to be colors and
especially not colors with specific primaries. It's only when it's
used to form an image that the TF and primaries are known. Vulkan
specifically requires you to explicitly provide this information to
the WSI and YCC samplers (generally everywhere where knowing them is
required) and never assumes that certain pixel formats imply certain
TFs and primaries (exception being the sRGB variants).


(See also 
https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#_issues_26,
Q 23)

The problem here seems to be that the Data Format spec describes more
than the pixel format. If you want to share an image, the TF and
primaries are essential but they are not an inherent part of the pixel
format of the image. So yeah, I think what dfdutils does is...
probably not wrong but not what you're after.

>
> I was wondering what to do for DRM formats regarding these. I think it
> would be worthwhile to do like Vulkan: set TF = linear, primaries =
> BT.709, pre-multiplied alpha = yes. These are the things KMS assume
> when there is no override (ie, when there is no KMS property saying
> otherwise).

Please no. All undefined is absolutely the right thing to do. Adding
any more meaning to pixel formats is a horrible idea. The KMS
properties are also not an override, they describe the image and the
description has default values.

>
> [1]: 
> https://github.com/KhronosGroup/dfdutils/blob/5cd41cbdf63e80b00c085c6906a1152709e4c0f2/createdfd.c#L47
>



Re: [PATCH v1 02/14] drm/msm/dp: add dsc factor into calculation of supported bpp

2023-01-23 Thread kernel test robot
Hi Kuogee,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on next-20230123]
[also build test WARNING on linus/master v6.2-rc5]
[cannot apply to drm-misc/drm-misc-next drm/drm-next drm-exynos/exynos-drm-next 
drm-intel/for-linux-next drm-intel/for-linux-next-fixes drm-tip/drm-tip 
v6.2-rc5 v6.2-rc4 v6.2-rc3]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:
https://github.com/intel-lab-lkp/linux/commits/Kuogee-Hsieh/drm-msm-dp-add-dpcd-read-of-both-dsc-and-fec-capability/20230124-022759
patch link:
https://lore.kernel.org/r/1674498274-6010-3-git-send-email-quic_khsieh%40quicinc.com
patch subject: [PATCH v1 02/14] drm/msm/dp: add dsc factor into calculation of 
supported bpp
config: sparc-allyesconfig 
(https://download.01.org/0day-ci/archive/20230124/202301240748.rcxiazh1-...@intel.com/config)
compiler: sparc64-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# 
https://github.com/intel-lab-lkp/linux/commit/745d7acf9ef8affe996fce2f0658a6d95ac151fd
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review 
Kuogee-Hsieh/drm-msm-dp-add-dpcd-read-of-both-dsc-and-fec-capability/20230124-022759
git checkout 745d7acf9ef8affe996fce2f0658a6d95ac151fd
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 
O=build_dir ARCH=sparc olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 
O=build_dir ARCH=sparc SHELL=/bin/bash drivers/gpu/drm/msm/

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

   drivers/gpu/drm/msm/dp/dp_panel.c: In function 'dp_panel_get_supported_bpp':
>> drivers/gpu/drm/msm/dp/dp_panel.c:125:34: warning: variable 'panel' set but 
>> not used [-Wunused-but-set-variable]
 125 | struct dp_panel_private *panel;
 |  ^


vim +/panel +125 drivers/gpu/drm/msm/dp/dp_panel.c

   120  
   121  static u32 dp_panel_get_supported_bpp(struct dp_panel *dp_panel,
   122  u32 mode_edid_bpp, u32 mode_pclk_khz)
   123  {
   124  struct dp_link_info *link_info;
 > 125  struct dp_panel_private *panel;
   126  const u32 max_supported_bpp = 30;
   127  u32 min_supported_bpp = 18;
   128  u32 bpp = 0, link_bitrate = 0, mode_bitrate;
   129  s64 rate_fp = 0;
   130  
   131  panel = container_of(dp_panel, struct dp_panel_private, 
dp_panel);
   132  
   133  if (dp_panel->dsc_en)
   134  min_supported_bpp = 24;
   135  
   136  bpp = min_t(u32, mode_edid_bpp, max_supported_bpp);
   137  
   138  link_info = _panel->link_info;
   139  
   140  rate_fp = drm_int2fixp(link_info->num_lanes * link_info->rate * 
8);
   141  
   142  if (dp_panel->fec_en)
   143  rate_fp = drm_fixp_div(rate_fp, 
dp_panel->fec_overhead_fp);
   144  
   145  link_bitrate = drm_fixp2int(rate_fp);
   146  
   147  for (; bpp > min_supported_bpp; bpp -= 6) {
   148  if (dp_panel->dsc_en) {
   149  if (bpp == 30 && 
!(dp_panel->sink_dsc_caps.color_depth & DP_DSC_10_BPC))
   150  continue;
   151  else if (bpp == 24 && 
!(dp_panel->sink_dsc_caps.color_depth & DP_DSC_8_BPC))
   152  continue;
   153  
   154  mode_bitrate = mode_pclk_khz * DSC_TGT_BPP;
   155  } else {
   156  mode_bitrate = mode_pclk_khz * bpp;
   157  }
   158  
   159  if (mode_bitrate <= link_bitrate)
   160  break;
   161  }
   162  
   163  if (bpp < min_supported_bpp)
   164  DRM_ERROR("bpp %d is below minimum supported bpp %d\n", 
bpp,
   165  min_supported_bpp);
   166  
   167  if (dp_panel->dsc_en && bpp != 24 && bpp != 30 && bpp != 36)
   168  DRM_ERROR("bpp %d is not supported when dsc is 
enabled\n", bpp);
   169  
   170  return bpp;
   171  }
   172  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests


Re: [PATCH 1/8] drm/i915/guc: Add GuC oriented print macros

2023-01-23 Thread John Harrison

On 1/20/2023 08:40, Michal Wajdeczko wrote:

While we do have GT oriented print macros, add few more GuC
specific to have common look and feel across all messages
related to the GuC and to avoid chasing the gt pointer.

We will use these macros shortly in upcoming patches.

Signed-off-by: Michal Wajdeczko 
Cc: Tvrtko Ursulin 
Cc: John Harrison 
---
  drivers/gpu/drm/i915/gt/uc/intel_guc_print.h | 48 
  1 file changed, 48 insertions(+)
  create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_guc_print.h

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_print.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_print.h
new file mode 100644
index ..e75989d4ba06
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_print.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2023 Intel Corporation
+ */
+
+#ifndef __INTEL_GUC_PRINT__
+#define __INTEL_GUC_PRINT__
+
+#include "gt/intel_gt.h"
This necessary only for the guc_to_gt() accessor? Hmm. Maybe it is worth 
moving that to intel_guc.h? I know Jani for one would like to see all of 
that cleaned up. But maybe that's a follow up patch.


John.


+#include "gt/intel_gt_print.h"
+
+#define guc_printk(_guc, _level, _fmt, ...) \
+   gt_##_level(guc_to_gt(_guc), "GUC: " _fmt, ##__VA_ARGS__)
+
+#define guc_err(_guc, _fmt, ...) \
+   guc_printk((_guc), err, _fmt, ##__VA_ARGS__)
+
+#define guc_warn(_guc, _fmt, ...) \
+   guc_printk((_guc), warn, _fmt, ##__VA_ARGS__)
+
+#define guc_notice(_guc, _fmt, ...) \
+   guc_printk((_guc), notice, _fmt, ##__VA_ARGS__)
+
+#define guc_info(_guc, _fmt, ...) \
+   guc_printk((_guc), info, _fmt, ##__VA_ARGS__)
+
+#define guc_dbg(_guc, _fmt, ...) \
+   guc_printk((_guc), dbg, _fmt, ##__VA_ARGS__)
+
+#define guc_err_ratelimited(_guc, _fmt, ...) \
+   guc_printk((_guc), err_ratelimited, _fmt, ##__VA_ARGS__)
+
+#define guc_probe_error(_guc, _fmt, ...) \
+   guc_printk((_guc), probe_error, _fmt, ##__VA_ARGS__)
+
+#define guc_WARN(_guc, _cond, _fmt, ...) \
+   gt_WARN(guc_to_gt(_guc), _cond, "GUC: " _fmt, ##__VA_ARGS__)
+
+#define guc_WARN_ONCE(_guc, _cond, _fmt, ...) \
+   gt_WARN_ONCE(guc_to_gt(_guc), _cond, "GUC: " _fmt, ##__VA_ARGS__)
+
+#define guc_WARN_ON(_guc, _cond) \
+   gt_WARN(guc_to_gt(_guc), _cond, "%s(%s)", "guc_WARN_ON", 
__stringify(_cond))
+
+#define guc_WARN_ON_ONCE(_guc, _cond) \
+   gt_WARN_ONCE(guc_to_gt(_guc), _cond, "%s(%s)", "guc_WARN_ON_ONCE", 
__stringify(_cond))
+
+#endif /* __INTEL_GUC_PRINT__ */




Re: [PATCH drm-next 03/14] drm: manager to keep track of GPUs VA mappings

2023-01-23 Thread Niranjana Vishwanathapura

On Wed, Jan 18, 2023 at 07:12:45AM +0100, Danilo Krummrich wrote:

This adds the infrastructure for a manager implementation to keep track
of GPU virtual address (VA) mappings.

New UAPIs, motivated by Vulkan sparse memory bindings graphics drivers
start implementing, allow userspace applications to request multiple and
arbitrary GPU VA mappings of buffer objects. The DRM GPU VA manager is
intended to serve the following purposes in this context.

1) Provide a dedicated range allocator to track GPU VA allocations and
  mappings, making use of the drm_mm range allocator.

2) Generically connect GPU VA mappings to their backing buffers, in
  particular DRM GEM objects.

3) Provide a common implementation to perform more complex mapping
  operations on the GPU VA space. In particular splitting and merging
  of GPU VA mappings, e.g. for intersecting mapping requests or partial
  unmap requests.

Idea-suggested-by: Dave Airlie 
Signed-off-by: Danilo Krummrich 
---
Documentation/gpu/drm-mm.rst|   31 +
drivers/gpu/drm/Makefile|1 +
drivers/gpu/drm/drm_gem.c   |3 +
drivers/gpu/drm/drm_gpuva_mgr.c | 1323 +++
include/drm/drm_drv.h   |6 +
include/drm/drm_gem.h   |   75 ++
include/drm/drm_gpuva_mgr.h |  527 
7 files changed, 1966 insertions(+)
create mode 100644 drivers/gpu/drm/drm_gpuva_mgr.c
create mode 100644 include/drm/drm_gpuva_mgr.h

diff --git a/Documentation/gpu/drm-mm.rst b/Documentation/gpu/drm-mm.rst
index a52e6f4117d6..c9f120cfe730 100644
--- a/Documentation/gpu/drm-mm.rst
+++ b/Documentation/gpu/drm-mm.rst
@@ -466,6 +466,37 @@ DRM MM Range Allocator Function References
.. kernel-doc:: drivers/gpu/drm/drm_mm.c
   :export:

+DRM GPU VA Manager
+==
+
+Overview
+
+
+.. kernel-doc:: drivers/gpu/drm/drm_gpuva_mgr.c
+   :doc: Overview
+
+Split and Merge
+---
+
+.. kernel-doc:: drivers/gpu/drm/drm_gpuva_mgr.c
+   :doc: Split and Merge
+
+Locking
+---
+
+.. kernel-doc:: drivers/gpu/drm/drm_gpuva_mgr.c
+   :doc: Locking
+
+
+DRM GPU VA Manager Function References
+--
+
+.. kernel-doc:: include/drm/drm_gpuva_mgr.h
+   :internal:
+
+.. kernel-doc:: drivers/gpu/drm/drm_gpuva_mgr.c
+   :export:
+
DRM Buddy Allocator
===

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 4fe190aee584..de2ffca3b6e4 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -45,6 +45,7 @@ drm-y := \
drm_vblank.o \
drm_vblank_work.o \
drm_vma_manager.o \
+   drm_gpuva_mgr.o \
drm_writeback.o
drm-$(CONFIG_DRM_LEGACY) += \
drm_agpsupport.o \
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 59a0bb5ebd85..65115fe88627 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -164,6 +164,9 @@ void drm_gem_private_object_init(struct drm_device *dev,
if (!obj->resv)
obj->resv = >_resv;

+   if (drm_core_check_feature(dev, DRIVER_GEM_GPUVA))
+   drm_gem_gpuva_init(obj);
+
drm_vma_node_reset(>vma_node);
INIT_LIST_HEAD(>lru_node);
}
diff --git a/drivers/gpu/drm/drm_gpuva_mgr.c b/drivers/gpu/drm/drm_gpuva_mgr.c
new file mode 100644
index ..e665f642689d
--- /dev/null
+++ b/drivers/gpu/drm/drm_gpuva_mgr.c
@@ -0,0 +1,1323 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 Red Hat.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Danilo Krummrich 
+ *
+ */
+
+#include 
+#include 
+
+/**
+ * DOC: Overview
+ *
+ * The DRM GPU VA Manager, represented by struct drm_gpuva_manager keeps track
+ * of a GPU's virtual address (VA) space and manages the corresponding virtual
+ * mappings represented by _gpuva objects. It also keeps track of the
+ * mapping's backing _gem_object buffers.
+ *
+ * _gem_object buffers maintain a list (and 

Re: [PATCH 8/8] drm/i915/guc: Update GT/GuC messages in intel_uc.c

2023-01-23 Thread John Harrison

On 1/20/2023 08:40, Michal Wajdeczko wrote:

Use new macros to have common prefix that also include GT#.

Signed-off-by: Michal Wajdeczko 
Cc: John Harrison 
---
  drivers/gpu/drm/i915/gt/uc/intel_uc.c | 74 +--
  1 file changed, 36 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
index 9a8a1abf71d7..e94f0d7119c4 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
@@ -6,11 +6,13 @@
  #include 
  
  #include "gt/intel_gt.h"

+#include "gt/intel_gt_print.h"
  #include "gt/intel_reset.h"
  #include "intel_gsc_fw.h"
  #include "intel_gsc_uc.h"
  #include "intel_guc.h"
  #include "intel_guc_ads.h"
+#include "intel_guc_print.h"
  #include "intel_guc_submission.h"
  #include "gt/intel_rps.h"
  #include "intel_uc.h"
@@ -67,14 +69,14 @@ static int __intel_uc_reset_hw(struct intel_uc *uc)
  
  	ret = intel_reset_guc(gt);

if (ret) {
-   DRM_ERROR("Failed to reset GuC, ret = %d\n", ret);
+   gt_err(gt, "Failed to reset GuC, ret = %d\n", ret);
return ret;
}
  
  	guc_status = intel_uncore_read(gt->uncore, GUC_STATUS);

-   WARN(!(guc_status & GS_MIA_IN_RESET),
-"GuC status: 0x%x, MIA core expected to be in reset\n",
-guc_status);
+   gt_WARN(gt, !(guc_status & GS_MIA_IN_RESET),
+   "GuC status: 0x%x, MIA core expected to be in reset\n",
+   guc_status);
  
  	return ret;

  }
@@ -252,15 +254,13 @@ static int guc_enable_communication(struct intel_guc *guc)
intel_guc_ct_event_handler(>ct);
spin_unlock_irq(gt->irq_lock);
  
-	drm_dbg(>drm, "GuC communication enabled\n");

+   guc_dbg(guc, "communication enabled\n");
  
  	return 0;

  }
  
  static void guc_disable_communication(struct intel_guc *guc)

  {
-   struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
-
/*
 * Events generated during or after CT disable are logged by guc in
 * via mmio. Make sure the register is clear before disabling CT since
@@ -280,11 +280,12 @@ static void guc_disable_communication(struct intel_guc 
*guc)
 */
guc_get_mmio_msg(guc);
  
-	drm_dbg(>drm, "GuC communication disabled\n");

+   guc_dbg(guc, "communication disabled\n");
  }
  
  static void __uc_fetch_firmwares(struct intel_uc *uc)

  {
+   struct intel_gt *gt = uc_to_gt(uc);
int err;
  
  	GEM_BUG_ON(!intel_uc_wants_guc(uc));

@@ -293,15 +294,13 @@ static void __uc_fetch_firmwares(struct intel_uc *uc)
if (err) {
/* Make sure we transition out of transient "SELECTED" state */
if (intel_uc_wants_huc(uc)) {
-   drm_dbg(_to_gt(uc)->i915->drm,
-   "Failed to fetch GuC: %d disabling HuC\n", err);
+   gt_dbg(gt, "Failed to fetch GuC fw (%pe) disabling 
HuC\n", ERR_PTR(err));
intel_uc_fw_change_status(>huc.fw,
  INTEL_UC_FIRMWARE_ERROR);
}
  
  		if (intel_uc_wants_gsc_uc(uc)) {

-   drm_dbg(_to_gt(uc)->i915->drm,
-   "Failed to fetch GuC: %d disabling GSC\n", err);
+   gt_dbg(gt, "Failed to fetch GuC fw (%pe) disabling 
GSC\n", ERR_PTR(err));
intel_uc_fw_change_status(>gsc.fw,
  INTEL_UC_FIRMWARE_ERROR);
}
@@ -382,7 +381,7 @@ static int uc_init_wopcm(struct intel_uc *uc)
int err;
  
  	if (unlikely(!base || !size)) {

-   i915_probe_error(gt->i915, "Unsuccessful WOPCM partitioning\n");
+   gt_probe_error(gt, "Unsuccessful WOPCM partitioning\n");
return -E2BIG;
}
  
@@ -413,13 +412,13 @@ static int uc_init_wopcm(struct intel_uc *uc)

return 0;
  
  err_out:

-   i915_probe_error(gt->i915, "Failed to init uC WOPCM registers!\n");
-   i915_probe_error(gt->i915, "%s(%#x)=%#x\n", "DMA_GUC_WOPCM_OFFSET",
-i915_mmio_reg_offset(DMA_GUC_WOPCM_OFFSET),
-intel_uncore_read(uncore, DMA_GUC_WOPCM_OFFSET));
-   i915_probe_error(gt->i915, "%s(%#x)=%#x\n", "GUC_WOPCM_SIZE",
-i915_mmio_reg_offset(GUC_WOPCM_SIZE),
-intel_uncore_read(uncore, GUC_WOPCM_SIZE));
+   gt_probe_error(gt, "Failed to init uC WOPCM registers!\n");
+   gt_probe_error(gt, "%s(%#x)=%#x\n", "DMA_GUC_WOPCM_OFFSET",
+  i915_mmio_reg_offset(DMA_GUC_WOPCM_OFFSET),
+  intel_uncore_read(uncore, DMA_GUC_WOPCM_OFFSET));
+   gt_probe_error(gt, "%s(%#x)=%#x\n", "GUC_WOPCM_SIZE",
+  i915_mmio_reg_offset(GUC_WOPCM_SIZE),
+  intel_uncore_read(uncore, GUC_WOPCM_SIZE));
  
  	return err;

  }
@@ -451,18 +450,17 @@ 

Re: [PATCH 7/8] drm/i915/guc: Update GuC messages in intel_guc_submission.c

2023-01-23 Thread John Harrison

On 1/20/2023 08:40, Michal Wajdeczko wrote:

Use new macros to have common prefix that also include GT#.

Signed-off-by: Michal Wajdeczko 
Cc: John Harrison 
---
  .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 60 ---
  1 file changed, 26 insertions(+), 34 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 b436dd7f12e4..bb98206304ee 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -27,6 +27,7 @@
  
  #include "intel_guc_ads.h"

  #include "intel_guc_capture.h"
+#include "intel_guc_print.h"
  #include "intel_guc_submission.h"
  
  #include "i915_drv.h"

@@ -1443,8 +1444,7 @@ static void guc_init_engine_stats(struct intel_guc *guc)
int ret = guc_action_enable_usage_stats(guc);
  
  		if (ret)

-   drm_err(>i915->drm,
-   "Failed to enable usage stats: %d!\n", ret);
+   guc_err(guc, "Failed to enable usage stats: %pe\n", 
ERR_PTR(ret));
}
  }
  
@@ -3585,8 +3585,7 @@ static int guc_request_alloc(struct i915_request *rq)

intel_context_sched_disable_unpin(ce);
else if (intel_context_is_closed(ce))
if (wait_for(context_close_done(ce), 1500))
-   drm_warn(_to_gt(guc)->i915->drm,
-"timed out waiting on context sched close before 
realloc\n");
+   guc_warn(guc, "timed out waiting on context sched close 
before realloc\n");
/*
 * Call pin_guc_id here rather than in the pinning step as with
 * dma_resv, contexts can be repeatedly pinned / unpinned trashing the
@@ -4349,11 +4348,14 @@ static int __guc_action_set_scheduling_policies(struct 
intel_guc *guc,
  
  	ret = intel_guc_send(guc, (u32 *)>h2g,

 __guc_scheduling_policy_action_size(policy));
-   if (ret < 0)
+   if (ret < 0) {
+   guc_probe_error(guc, "Failed to configure global scheduling 
policies: %pe!\n",
+   ERR_PTR(ret));
return ret;
+   }
  
  	if (ret != policy->count) {

-   drm_warn(_to_gt(guc)->i915->drm, "GuC global scheduler policy 
processed %d of %d KLVs!",
+   guc_warn(guc, "global scheduler policy processed %d of %d 
KLVs!",
 ret, policy->count);
if (ret > policy->count)
return -EPROTO;
@@ -4367,7 +4369,7 @@ static int guc_init_global_schedule_policy(struct 
intel_guc *guc)
struct scheduling_policy policy;
struct intel_gt *gt = guc_to_gt(guc);
intel_wakeref_t wakeref;
-   int ret = 0;
+   int ret;
  
  	if (GUC_SUBMIT_VER(guc) < MAKE_GUC_VER(1, 1, 0))

return 0;
@@ -4385,10 +4387,6 @@ static int guc_init_global_schedule_policy(struct 
intel_guc *guc)
yield, ARRAY_SIZE(yield));
  
  		ret = __guc_action_set_scheduling_policies(guc, );

-   if (ret)
-   i915_probe_error(gt->i915,
-"Failed to configure global scheduling 
policies: %pe!\n",
-ERR_PTR(ret));
}
  
  	return ret;

@@ -4487,21 +4485,18 @@ g2h_context_lookup(struct intel_guc *guc, u32 ctx_id)
struct intel_context *ce;
  
  	if (unlikely(ctx_id >= GUC_MAX_CONTEXT_ID)) {

-   drm_err(_to_gt(guc)->i915->drm,
-   "Invalid ctx_id %u\n", ctx_id);
+   guc_err(guc, "Invalid ctx_id %u\n", ctx_id);
return NULL;
}
  
  	ce = __get_context(guc, ctx_id);

if (unlikely(!ce)) {
-   drm_err(_to_gt(guc)->i915->drm,
-   "Context is NULL, ctx_id %u\n", ctx_id);
+   guc_err(guc, "Context is NULL, ctx_id %u\n", ctx_id);
return NULL;
}
  
  	if (unlikely(intel_context_is_child(ce))) {

-   drm_err(_to_gt(guc)->i915->drm,
-   "Context is child, ctx_id %u\n", ctx_id);
+   guc_err(guc, "Context is child, ctx_id %u\n", ctx_id);
return NULL;
}
  
@@ -4516,7 +4511,7 @@ int intel_guc_deregister_done_process_msg(struct intel_guc *guc,

u32 ctx_id;
  
  	if (unlikely(len < 1)) {

-   drm_err(_to_gt(guc)->i915->drm, "Invalid length %u\n", len);
+   guc_err(guc, "Invalid length %u\n", len);
return -EPROTO;
}
ctx_id = msg[0];
@@ -4568,7 +4563,7 @@ int intel_guc_sched_done_process_msg(struct intel_guc 
*guc,
u32 ctx_id;
  
  	if (unlikely(len < 2)) {

-   drm_err(_to_gt(guc)->i915->drm, "Invalid length %u\n", len);
+   guc_err(guc, "Invalid length %u\n", len);
return -EPROTO;
}
ctx_id = 

Re: [PATCH 6/8] drm/i915/guc: Update GuC messages in intel_guc_log.c

2023-01-23 Thread John Harrison

On 1/20/2023 08:40, Michal Wajdeczko wrote:

Use new macros to have common prefix that also include GT#.

Signed-off-by: Michal Wajdeczko 
Cc: John Harrison 
---
  drivers/gpu/drm/i915/gt/uc/intel_guc_log.c | 35 +++---
  1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
index 68331c538b0a..1d76497b783c 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
@@ -12,6 +12,7 @@
  #include "i915_memcpy.h"
  #include "intel_guc_capture.h"
  #include "intel_guc_log.h"
+#include "intel_guc_print.h"
  
  #if defined(CONFIG_DRM_I915_DEBUG_GUC)

  #define GUC_LOG_DEFAULT_CRASH_BUFFER_SIZE SZ_2M
@@ -39,7 +40,6 @@ struct guc_log_section {
  static void _guc_log_init_sizes(struct intel_guc_log *log)
  {
struct intel_guc *guc = log_to_guc(log);
-   struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
static const struct guc_log_section sections[GUC_LOG_SECTIONS_LIMIT] = {
{
GUC_LOG_CRASH_MASK >> GUC_LOG_CRASH_SHIFT,
@@ -82,12 +82,12 @@ static void _guc_log_init_sizes(struct intel_guc_log *log)
}
  
  		if (!IS_ALIGNED(log->sizes[i].bytes, log->sizes[i].units))

-   drm_err(>drm, "Mis-aligned GuC log %s size: 0x%X vs 
0x%X!",
+   guc_err(guc, "Mis-aligned log %s size: 0x%X vs 0x%X!",
sections[i].name, log->sizes[i].bytes, 
log->sizes[i].units);
log->sizes[i].count = log->sizes[i].bytes / log->sizes[i].units;
  
  		if (!log->sizes[i].count) {

-   drm_err(>drm, "Zero GuC log %s size!", 
sections[i].name);
+   guc_err(guc, "Zero log %s size!", sections[i].name);
} else {
/* Size is +1 unit */
log->sizes[i].count--;
@@ -95,14 +95,14 @@ static void _guc_log_init_sizes(struct intel_guc_log *log)
  
  		/* Clip to field size */

if (log->sizes[i].count > sections[i].max) {
-   drm_err(>drm, "GuC log %s size too large: %d vs 
%d!",
+   guc_err(guc, "log %s size too large: %d vs %d!",
sections[i].name, log->sizes[i].count + 1, 
sections[i].max + 1);
log->sizes[i].count = sections[i].max;
}
}
  
  	if (log->sizes[GUC_LOG_SECTIONS_CRASH].units != log->sizes[GUC_LOG_SECTIONS_DEBUG].units) {

-   drm_err(>drm, "Unit mis-match for GuC log crash and debug 
sections: %d vs %d!",
+   guc_err(guc, "Unit mis-match for GuC log crash and debug sections: 
%d vs %d!",

-> "for log, crash and debug sections"


log->sizes[GUC_LOG_SECTIONS_CRASH].units,
log->sizes[GUC_LOG_SECTIONS_DEBUG].units);
log->sizes[GUC_LOG_SECTIONS_CRASH].units = 
log->sizes[GUC_LOG_SECTIONS_DEBUG].units;
@@ -374,6 +374,7 @@ size_t intel_guc_get_log_buffer_offset(struct intel_guc_log 
*log,
  
  static void _guc_log_copy_debuglogs_for_relay(struct intel_guc_log *log)

  {
+   struct intel_guc *guc = log_to_guc(log);
unsigned int buffer_size, read_offset, write_offset, bytes_to_copy, 
full_cnt;
struct guc_log_buffer_state *log_buf_state, *log_buf_snapshot_state;
struct guc_log_buffer_state log_buf_state_local;
@@ -383,7 +384,7 @@ static void _guc_log_copy_debuglogs_for_relay(struct 
intel_guc_log *log)
  
  	mutex_lock(>relay.lock);
  
-	if (WARN_ON(!intel_guc_log_relay_created(log)))

+   if (guc_WARN_ON(guc, !intel_guc_log_relay_created(log)))
goto out_unlock;
  
  	/* Get the pointer to shared GuC log buffer */

@@ -398,7 +399,7 @@ static void _guc_log_copy_debuglogs_for_relay(struct 
intel_guc_log *log)
 * Used rate limited to avoid deluge of messages, logs might be
 * getting consumed by User at a slow rate.
 */
-   DRM_ERROR_RATELIMITED("no sub-buffer to copy general logs\n");
+   guc_err_ratelimited(guc, "no sub-buffer to copy general 
logs\n");
log->relay.full_count++;
  
  		goto out_unlock;

@@ -451,7 +452,7 @@ static void _guc_log_copy_debuglogs_for_relay(struct 
intel_guc_log *log)
write_offset = buffer_size;
} else if (unlikely((read_offset > buffer_size) ||
(write_offset > buffer_size))) {
-   DRM_ERROR("invalid log buffer state\n");
+   guc_err(guc, "invalid log buffer state\n");
/* copy whole buffer as offsets are unreliable */
read_offset = 0;
write_offset = buffer_size;
@@ -547,7 +548,7 @@ static int guc_log_relay_create(struct intel_guc_log *log)
   

Re: [PATCH 5/8] drm/i915/guc: Update GuC messages in intel_guc_fw.c

2023-01-23 Thread John Harrison

On 1/20/2023 08:40, Michal Wajdeczko wrote:

Use new macros to have common prefix that also include GT#.

Signed-off-by: Michal Wajdeczko 
Cc: John Harrison 

Reviewed-by: John Harrison 


---
  drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c | 17 +
  1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
index 5b86b2e286e0..3d2249bda368 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
@@ -13,6 +13,7 @@
  #include "gt/intel_gt_mcr.h"
  #include "gt/intel_gt_regs.h"
  #include "intel_guc_fw.h"
+#include "intel_guc_print.h"
  #include "i915_drv.h"
  
  static void guc_prepare_xfer(struct intel_gt *gt)

@@ -103,8 +104,10 @@ static inline bool guc_ready(struct intel_uncore *uncore, 
u32 *status)
return uk_val == INTEL_GUC_LOAD_STATUS_READY;
  }
  
-static int guc_wait_ucode(struct intel_uncore *uncore)

+static int guc_wait_ucode(struct intel_guc *guc)
  {
+   struct intel_gt *gt = guc_to_gt(guc);
+   struct intel_uncore *uncore = gt->uncore;
u32 status;
int ret;
  
@@ -127,10 +130,8 @@ static int guc_wait_ucode(struct intel_uncore *uncore)

 */
ret = wait_for(guc_ready(uncore, ), 200);
if (ret) {
-   struct drm_device *drm = >i915->drm;
-
-   drm_info(drm, "GuC load failed: status = 0x%08X\n", status);
-   drm_info(drm, "GuC load failed: status: Reset = %d, "
+   guc_info(guc, "load failed: status = 0x%08X\n", status);
+   guc_info(guc, "load failed: status: Reset = %d, "
"BootROM = 0x%02X, UKernel = 0x%02X, "
"MIA = 0x%02X, Auth = 0x%02X\n",
REG_FIELD_GET(GS_MIA_IN_RESET, status),
@@ -140,12 +141,12 @@ static int guc_wait_ucode(struct intel_uncore *uncore)
REG_FIELD_GET(GS_AUTH_STATUS_MASK, status));
  
  		if ((status & GS_BOOTROM_MASK) == GS_BOOTROM_RSA_FAILED) {

-   drm_info(drm, "GuC firmware signature verification 
failed\n");
+   guc_info(guc, "firmware signature verification 
failed\n");
ret = -ENOEXEC;
}
  
  		if (REG_FIELD_GET(GS_UKERNEL_MASK, status) == INTEL_GUC_LOAD_STATUS_EXCEPTION) {

-   drm_info(drm, "GuC firmware exception. EIP: %#x\n",
+   guc_info(guc, "firmware exception. EIP: %#x\n",
 intel_uncore_read(uncore, SOFT_SCRATCH(13)));
ret = -ENXIO;
}
@@ -194,7 +195,7 @@ int intel_guc_fw_upload(struct intel_guc *guc)
if (ret)
goto out;
  
-	ret = guc_wait_ucode(uncore);

+   ret = guc_wait_ucode(guc);
if (ret)
goto out;
  




Re: [PATCH 4/8] drm/i915/guc: Update GuC messages in intel_guc_ct.c

2023-01-23 Thread John Harrison

On 1/20/2023 08:40, Michal Wajdeczko wrote:

Use new macros to have common prefix that also include GT#.

Signed-off-by: Michal Wajdeczko 
Cc: John Harrison 
---
  drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 12 
  1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
index 2b22065e87bf..89adfc4193d2 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
@@ -11,6 +11,7 @@
  
  #include "i915_drv.h"

  #include "intel_guc_ct.h"
+#include "intel_guc_print.h"
  #include "gt/intel_gt.h"
  
  static inline struct intel_guc *ct_to_guc(struct intel_guc_ct *ct)

@@ -28,21 +29,16 @@ static inline struct drm_i915_private *ct_to_i915(struct 
intel_guc_ct *ct)
return ct_to_gt(ct)->i915;
  }
  
-static inline struct drm_device *ct_to_drm(struct intel_guc_ct *ct)

-{
-   return _to_i915(ct)->drm;
-}
-
  #define CT_ERROR(_ct, _fmt, ...) \
-   drm_err(ct_to_drm(_ct), "CT: " _fmt, ##__VA_ARGS__)
+   guc_err(ct_to_guc(_ct), "CT: " _fmt, ##__VA_ARGS__)
  #ifdef CONFIG_DRM_I915_DEBUG_GUC
  #define CT_DEBUG(_ct, _fmt, ...) \
-   drm_dbg(ct_to_drm(_ct), "CT: " _fmt, ##__VA_ARGS__)
+   guc_dbg(ct_to_guc(_ct), "CT: " _fmt, ##__VA_ARGS__)
  #else
  #define CT_DEBUG(...) do { } while (0)
  #endif
  #define CT_PROBE_ERROR(_ct, _fmt, ...) \
-   i915_probe_error(ct_to_i915(ct), "CT: " _fmt, ##__VA_ARGS__)
+   guc_probe_error(ct_to_guc(ct), "CT: " _fmt, ##__VA_ARGS__)

ct_to_i915 is also now redundant and can be removed?

John.

  
  /**

   * DOC: CTB Blob




Re: [PATCH 3/8] drm/i915/guc: Update GuC messages in intel_guc_ads.c

2023-01-23 Thread John Harrison

On 1/20/2023 08:40, Michal Wajdeczko wrote:

Use new macros to have common prefix that also include GT#.

Signed-off-by: Michal Wajdeczko 
Cc: John Harrison 

Reviewed-by: John Harrison 


---
  drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 8 
  1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index a7f737c4792e..69ce06faf8cd 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -15,6 +15,7 @@
  #include "intel_guc_ads.h"
  #include "intel_guc_capture.h"
  #include "intel_guc_fwif.h"
+#include "intel_guc_print.h"
  #include "intel_uc.h"
  #include "i915_drv.h"
  
@@ -427,7 +428,7 @@ static long guc_mmio_reg_state_create(struct intel_guc *guc)
  
  	guc->ads_regset = temp_set.storage;
  
-	drm_dbg(_to_gt(guc)->i915->drm, "Used %zu KB for temporary ADS regset\n",

+   guc_dbg(guc, "Used %zu KB for temporary ADS regset\n",
(temp_set.storage_max * sizeof(struct guc_mmio_reg)) >> 10);
  
  	return total * sizeof(struct guc_mmio_reg);

@@ -621,7 +622,7 @@ static void guc_init_golden_context(struct intel_guc *guc)
  
  		engine = find_engine_state(gt, engine_class);

if (!engine) {
-   drm_err(>i915->drm, "No engine state recorded for class 
%d!\n",
+   guc_err(guc, "No engine state recorded for class %d!\n",
engine_class);
ads_blob_write(guc, ads.eng_state_size[guc_class], 0);
ads_blob_write(guc, ads.golden_context_lrca[guc_class], 
0);
@@ -646,7 +647,6 @@ static int
  guc_capture_prep_lists(struct intel_guc *guc)
  {
struct intel_gt *gt = guc_to_gt(guc);
-   struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
u32 ads_ggtt, capture_offset, null_ggtt, total_size = 0;
struct guc_gt_system_info local_info;
struct iosys_map info_map;
@@ -751,7 +751,7 @@ guc_capture_prep_lists(struct intel_guc *guc)
}
  
  	if (guc->ads_capture_size && guc->ads_capture_size != PAGE_ALIGN(total_size))

-   drm_warn(>drm, "GuC->ADS->Capture alloc size changed from %d 
to %d\n",
+   guc_warn(guc, "ADS capture alloc size changed from %d to %d\n",
 guc->ads_capture_size, PAGE_ALIGN(total_size));
  
  	return PAGE_ALIGN(total_size);




[PATCH v3.1 4/7] drm: rcar-du: lvds: Fix stop sequence

2023-01-23 Thread Laurent Pinchart
From: Koji Matsuoka 

According to hardware manual, LVDCR0 register must be cleared bit by bit
when disabling LVDS.

Signed-off-by: Koji Matsuoka 
Signed-off-by: LUU HOAI 
[tomi.valkeinen: simplified the code a bit]
Signed-off-by: Tomi Valkeinen 
Reviewed-by: Laurent Pinchart 
Signed-off-by: Laurent Pinchart 
---
Changes since v3:

- Add comment explaining the register clear sequence
---
 drivers/gpu/drm/rcar-du/rcar_lvds.c | 31 +
 1 file changed, 31 insertions(+)

diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c 
b/drivers/gpu/drm/rcar-du/rcar_lvds.c
index a11201e4d31b..260ea5d8624e 100644
--- a/drivers/gpu/drm/rcar-du/rcar_lvds.c
+++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c
@@ -83,6 +83,11 @@ struct rcar_lvds {
 #define bridge_to_rcar_lvds(b) \
container_of(b, struct rcar_lvds, bridge)
 
+static u32 rcar_lvds_read(struct rcar_lvds *lvds, u32 reg)
+{
+   return ioread32(lvds->mmio + reg);
+}
+
 static void rcar_lvds_write(struct rcar_lvds *lvds, u32 reg, u32 data)
 {
iowrite32(data, lvds->mmio + reg);
@@ -544,6 +549,32 @@ static void rcar_lvds_atomic_disable(struct drm_bridge 
*bridge,
 struct drm_bridge_state *old_bridge_state)
 {
struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
+   u32 lvdcr0;
+
+   /*
+* Clear the LVDCR0 bits in the order specified by the hardware
+* documentation, ending with a write of 0 to the full register to
+* clear all remaining bits.
+*/
+   lvdcr0 = rcar_lvds_read(lvds, LVDCR0);
+
+   lvdcr0 &= ~LVDCR0_LVRES;
+   rcar_lvds_write(lvds, LVDCR0, lvdcr0);
+
+   if (lvds->info->quirks & RCAR_LVDS_QUIRK_GEN3_LVEN) {
+   lvdcr0 &= ~LVDCR0_LVEN;
+   rcar_lvds_write(lvds, LVDCR0, lvdcr0);
+   }
+
+   if (lvds->info->quirks & RCAR_LVDS_QUIRK_PWD) {
+   lvdcr0 &= ~LVDCR0_PWD;
+   rcar_lvds_write(lvds, LVDCR0, lvdcr0);
+   }
+
+   if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)) {
+   lvdcr0 &= ~LVDCR0_PLLON;
+   rcar_lvds_write(lvds, LVDCR0, lvdcr0);
+   }
 
rcar_lvds_write(lvds, LVDCR0, 0);
rcar_lvds_write(lvds, LVDCR1, 0);
-- 
Regards,

Laurent Pinchart



Re: [PATCH 2/8] drm/i915/guc: Update GuC messages in intel_guc.c

2023-01-23 Thread John Harrison

On 1/20/2023 08:40, Michal Wajdeczko wrote:

Use new macros to have common prefix that also include GT#.

Signed-off-by: Michal Wajdeczko 
Cc: John Harrison 
---
  drivers/gpu/drm/i915/gt/uc/intel_guc.c | 31 +-
  1 file changed, 15 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index 1bccc175f9e6..be39e519b5fd 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -11,6 +11,7 @@
  #include "intel_guc.h"
  #include "intel_guc_ads.h"
  #include "intel_guc_capture.h"
+#include "intel_guc_print.h"
  #include "intel_guc_slpc.h"
  #include "intel_guc_submission.h"
  #include "i915_drv.h"
@@ -94,8 +95,8 @@ static void gen9_enable_guc_interrupts(struct intel_guc *guc)
assert_rpm_wakelock_held(>i915->runtime_pm);
  
  	spin_lock_irq(gt->irq_lock);

-   WARN_ON_ONCE(intel_uncore_read(gt->uncore, GEN8_GT_IIR(2)) &
-gt->pm_guc_events);
+   guc_WARN_ON_ONCE(guc, intel_uncore_read(gt->uncore, GEN8_GT_IIR(2)) &
+gt->pm_guc_events);
gen6_gt_pm_enable_irq(gt, gt->pm_guc_events);
spin_unlock_irq(gt->irq_lock);
  
@@ -342,7 +343,7 @@ static void guc_init_params(struct intel_guc *guc)

params[GUC_CTL_DEVID] = guc_ctl_devid(guc);
  
  	for (i = 0; i < GUC_CTL_MAX_DWORDS; i++)

-   DRM_DEBUG_DRIVER("param[%2d] = %#x\n", i, params[i]);
+   guc_dbg(guc, "param[%2d] = %#x\n", i, params[i]);
  }
  
  /*

@@ -389,7 +390,6 @@ void intel_guc_dump_time_info(struct intel_guc *guc, struct 
drm_printer *p)
  
  int intel_guc_init(struct intel_guc *guc)

  {
-   struct intel_gt *gt = guc_to_gt(guc);
int ret;
  
  	ret = intel_uc_fw_init(>fw);

@@ -451,7 +451,7 @@ int intel_guc_init(struct intel_guc *guc)
intel_uc_fw_fini(>fw);
  out:
intel_uc_fw_change_status(>fw, INTEL_UC_FIRMWARE_INIT_FAIL);
-   i915_probe_error(gt->i915, "failed with %d\n", ret);
+   guc_probe_error(guc, "failed with %pe\n", ERR_PTR(ret));
return ret;
  }
  
@@ -480,7 +480,6 @@ void intel_guc_fini(struct intel_guc *guc)

  int intel_guc_send_mmio(struct intel_guc *guc, const u32 *request, u32 len,
u32 *response_buf, u32 response_buf_size)
  {
-   struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
struct intel_uncore *uncore = guc_to_gt(guc)->uncore;
u32 header;
int i;
@@ -515,7 +514,7 @@ int intel_guc_send_mmio(struct intel_guc *guc, const u32 
*request, u32 len,
   10, 10, );
if (unlikely(ret)) {
  timeout:
-   drm_err(>drm, "mmio request %#x: no reply %x\n",
+   guc_err(guc, "mmio request %#x: no reply %x\n",
request[0], header);
goto out;
}
@@ -537,7 +536,7 @@ int intel_guc_send_mmio(struct intel_guc *guc, const u32 
*request, u32 len,
if (FIELD_GET(GUC_HXG_MSG_0_TYPE, header) == 
GUC_HXG_TYPE_NO_RESPONSE_RETRY) {
u32 reason = FIELD_GET(GUC_HXG_RETRY_MSG_0_REASON, header);
  
-		drm_dbg(>drm, "mmio request %#x: retrying, reason %u\n",

+   guc_dbg(guc, "mmio request %#x: retrying, reason %u\n",
request[0], reason);
goto retry;
}
@@ -546,7 +545,7 @@ int intel_guc_send_mmio(struct intel_guc *guc, const u32 
*request, u32 len,
u32 hint = FIELD_GET(GUC_HXG_FAILURE_MSG_0_HINT, header);
u32 error = FIELD_GET(GUC_HXG_FAILURE_MSG_0_ERROR, header);
  
-		drm_err(>drm, "mmio request %#x: failure %x/%u\n",

+   guc_err(guc, "mmio request %#x: failure %x/%u\n",
request[0], error, hint);
ret = -ENXIO;
goto out;
@@ -554,7 +553,7 @@ int intel_guc_send_mmio(struct intel_guc *guc, const u32 
*request, u32 len,
  
  	if (FIELD_GET(GUC_HXG_MSG_0_TYPE, header) != GUC_HXG_TYPE_RESPONSE_SUCCESS) {

  proto:
-   drm_err(>drm, "mmio request %#x: unexpected reply %#x\n",
+   guc_err(guc, "mmio request %#x: unexpected reply %#x\n",
request[0], header);
ret = -EPROTO;
goto out;
@@ -597,9 +596,9 @@ int intel_guc_to_host_process_recv_msg(struct intel_guc 
*guc,
msg = payload[0] & guc->msg_enabled_mask;
  
  	if (msg & INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED)

-   drm_err(_to_gt(guc)->i915->drm, "Received early GuC crash dump 
notification!\n");
+   guc_err(guc, "Received early GuC crash dump notification!\n");
if (msg & INTEL_GUC_RECV_MSG_EXCEPTION)
-   drm_err(_to_gt(guc)->i915->drm, "Received early GuC exception 
notification!\n");
+   guc_err(guc, "Received early GuC exception notification!\n");
These two should drop the 'GUC' string from the message given that it is 
now a prefix.


John.

  
  	return 0;

Re: [Lsf-pc] [LSF/MM/BPF proposal]: Physr discussion

2023-01-23 Thread Matthew Wilcox
On Mon, Jan 23, 2023 at 12:50:52PM -0800, Dan Williams wrote:
> Matthew Wilcox wrote:
> > On Mon, Jan 23, 2023 at 11:36:51AM -0800, Dan Williams wrote:
> > > Jason Gunthorpe via Lsf-pc wrote:
> > > > I would like to have a session at LSF to talk about Matthew's
> > > > physr discussion starter:
> > > > 
> > > >  https://lore.kernel.org/linux-mm/ydykweu0htv8m...@casper.infradead.org/
> > > > 
> > > > I have become interested in this with some immediacy because of
> > > > IOMMUFD and this other discussion with Christoph:
> > > > 
> > > >  
> > > > https://lore.kernel.org/kvm/4-v2-472615b3877e+28f7-vfio_dma_buf_...@nvidia.com/
> > > 
> > > I think this is a worthwhile discussion. My main hangup with 'struct
> > > page' elimination in general is that if anything needs to be allocated
> > 
> > You're the first one to bring up struct page elimination.  Neither Jason
> > nor I have that as our motivation.
> 
> Oh, ok, then maybe I misread the concern in the vfio discussion. I
> thought the summary there is debating the ongoing requirement for
> 'struct page' for P2PDMA?

My reading of that thread is that while it started out that way, it
became more about "So what would a good interface be for doing this".  And
Jason's right, he and I are approaching this from different directions.
My concern is from the GUP side where we start out by getting a folio
(which we know is physically contiguous) and decomposing it into pages.
Then we aggregate all those pages together which are physically contiguous
and stuff them into a bio_vec.  After that, I lose interest; I was
planning on having DMA mapping interfaces which took in an array of
phyr and spat out scatterlists.  Then we could shrink the scatterlist
by removing page_link and offset, leaving us with only dma_address,
length and maybe flags.



Re: [PATCH v1 06/14] drm/msm/dp: add display compression related struct

2023-01-23 Thread Dmitry Baryshkov

On 23/01/2023 20:24, Kuogee Hsieh wrote:

Add display compression related struct to support variant compression
mechanism. However, DSC is the only one supported at this moment.
VDC may be added later.

Signed-off-by: Kuogee Hsieh 
---
  drivers/gpu/drm/msm/dp/dp_panel.h | 42 ++
  drivers/gpu/drm/msm/msm_drv.h | 89 +++
  2 files changed, 131 insertions(+)

diff --git a/drivers/gpu/drm/msm/dp/dp_panel.h 
b/drivers/gpu/drm/msm/dp/dp_panel.h
index 1153e88..4c45d51 100644
--- a/drivers/gpu/drm/msm/dp/dp_panel.h
+++ b/drivers/gpu/drm/msm/dp/dp_panel.h
@@ -21,12 +21,54 @@ struct edid;
  #define DP_DOWNSTREAM_PORTS   4
  #define DP_DOWNSTREAM_CAP_SIZE4
  
+

+#define DP_PANEL_CAPS_DSC  BIT(0)
+
+enum dp_output_format {
+   DP_OUTPUT_FORMAT_RGB,
+   DP_OUTPUT_FORMAT_YCBCR420,
+   DP_OUTPUT_FORMAT_YCBCR422,
+   DP_OUTPUT_FORMAT_YCBCR444,
+   DP_OUTPUT_FORMAT_INVALID,
+};
+
+
+struct dp_panel_info {
+   u32 h_active;
+   u32 v_active;
+   u32 h_back_porch;
+   u32 h_front_porch;
+   u32 h_sync_width;
+   u32 h_active_low;
+   u32 v_back_porch;
+   u32 v_front_porch;
+   u32 v_sync_width;
+   u32 v_active_low;
+   u32 h_skew;
+   u32 refresh_rate;
+   u32 pixel_clk_khz;
+   u32 bpp;
+   bool widebus_en;
+   struct msm_compression_info comp_info;
+   s64 dsc_overhead_fp;
+};
+
  struct dp_display_mode {
struct drm_display_mode drm_mode;
+   struct dp_panel_info timing;
u32 capabilities;
+   s64 fec_overhead_fp;
+   s64 dsc_overhead_fp;
u32 bpp;
u32 h_active_low;
u32 v_active_low;
+   /**
+* @output_format:
+*
+* This is used to indicate DP output format.
+* The output format can be read from drm_mode.
+*/
+   enum dp_output_format output_format;
  };
  
  struct dp_panel_in {

diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 9f0c184..f155803 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -1,6 +1,7 @@
  /* SPDX-License-Identifier: GPL-2.0-only */
  /*
   * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023. Qualcomm Innovation Center, Inc. All rights reserved
   * Copyright (C) 2013 Red Hat
   * Author: Rob Clark 
   */
@@ -70,6 +71,16 @@ enum msm_dp_controller {
  #define MAX_H_TILES_PER_DISPLAY 2
  
  /**

+ * enum msm_display_compression_type - compression method used for pixel stream
+ * @MSM_DISPLAY_COMPRESSION_NONE: Pixel data is not compressed
+ * @MSM_DISPLAY_COMPRESSION_DSC:  DSC compresison is used
+ */
+enum msm_display_compression_type {
+   MSM_DISPLAY_COMPRESSION_NONE,
+   MSM_DISPLAY_COMPRESSION_DSC,
+};
+
+/**
   * enum msm_event_wait - type of HW events to wait for
   * @MSM_ENC_COMMIT_DONE - wait for the driver to flush the registers to HW
   * @MSM_ENC_TX_COMPLETE - wait for the HW to transfer the frame to panel
@@ -82,6 +93,84 @@ enum msm_event_wait {
  };
  
  /**

+ * struct msm_display_dsc_info - defines dsc configuration


This structure was removed. Please keep it this way. We are not going to 
reintroduce it unless it is really required for some reason. And up to 
now I don't see a good reason for adding it back.



+ * @config   DSC encoder configuration
+ * @scr_rev: DSC revision.
+ * @initial_lines:   Number of initial lines stored in encoder.
+ * @pkt_per_line:Number of packets per line.
+ * @bytes_in_slice:  Number of bytes in slice.
+ * @eol_byte_num:Valid bytes at the end of line.
+ * @bytes_per_pktNumber of bytes in DSI packet
+ * @pclk_per_line:   Compressed width.
+ * @slice_last_group_size:   Size of last group in pixels.
+ * @slice_per_pkt:   Number of slices per packet.
+ * @num_active_ss_per_enc:   Number of active soft slices per encoder.
+ * @source_color_space:  Source color space of DSC encoder
+ * @chroma_format:   Chroma_format of DSC encoder.
+ * @det_thresh_flatness: Flatness threshold.
+ * @extra_width: Extra width required in timing calculations.
+ * @pps_delay_ms:Post PPS command delay in milliseconds.
+ * @dsc_4hsmerge_en: Using DSC 4HS merge topology
+ * @dsc_4hsmerge_padding 4HS merge DSC pair padding value in bytes
+ * @dsc_4hsmerge_alignment   4HS merge DSC alignment value in bytes
+ * @half_panel_puTrue for single and dual dsc encoders if partial
+ *   update sets the roi width to half of mode width
+ *   False in all other cases
+ */
+struct msm_display_dsc_info {
+   struct drm_dsc_config drm_dsc;
+   u8 scr_rev;
+
+   int initial_lines;
+   int pkt_per_line;
+   int bytes_in_slice;
+   int bytes_per_pkt;
+   int eol_byte_num;
+   

Re: [ANNOUNCE] pixfmtdb

2023-01-23 Thread Simon Ser
On Monday, January 23rd, 2023 at 21:25, Sebastian Wick 
 wrote:

> Why is the TF defined for GL formats and both the primaries and TF for
> Vulkan formats? The only exception here should be sRGB formats. Where
> did you get the information from?

This is what upstream dfdutils does [1]. Can you explain why you think
it should be undefined instead of linear?

I was wondering what to do for DRM formats regarding these. I think it
would be worthwhile to do like Vulkan: set TF = linear, primaries =
BT.709, pre-multiplied alpha = yes. These are the things KMS assume
when there is no override (ie, when there is no KMS property saying
otherwise).

[1]: 
https://github.com/KhronosGroup/dfdutils/blob/5cd41cbdf63e80b00c085c6906a1152709e4c0f2/createdfd.c#L47


Re: [PATCH v2 1/1] Docs/subsystem-apis: Remove '[The ]Linux' prefixes from titles of listed documents

2023-01-23 Thread Winiarska, Iwona
On Sun, 2023-01-22 at 18:48 +, SeongJae Park wrote:
> Some documents that listed on subsystem-apis have 'Linux' or 'The Linux'
> title prefixes.  It's duplicated information, and makes finding the
> document of interest with human eyes not easy.  Remove the prefixes from
> the titles.
> 
> Signed-off-by: SeongJae Park 

For Documentation/peci/index.rst

Acked-by: Iwona Winiarska 

> ---
> Changes from v1
> (https://lore.kernel.org/lkml/20230114194741.115855-1...@kernel.org/)
> - Drop second patch (will post later for each subsystem)
> 
>  Documentation/PCI/index.rst    | 6 +++---
>  Documentation/cpu-freq/index.rst   | 6 +++---
>  Documentation/crypto/index.rst | 6 +++---
>  Documentation/driver-api/index.rst | 6 +++---
>  Documentation/gpu/index.rst    | 6 +++---
>  Documentation/hwmon/index.rst  | 6 +++---
>  Documentation/input/index.rst  | 6 +++---
>  Documentation/mm/index.rst | 6 +++---
>  Documentation/peci/index.rst   | 6 +++---
>  Documentation/scheduler/index.rst  | 6 +++---
>  Documentation/scsi/index.rst   | 6 +++---
>  Documentation/sound/index.rst  | 6 +++---
>  Documentation/virt/index.rst   | 6 +++---
>  Documentation/watchdog/index.rst   | 6 +++---
>  14 files changed, 42 insertions(+), 42 deletions(-)


Re: [PATCH v1 04/14] drm/msm/dp: correct configure Colorimetry Indicator Field at MISC0

2023-01-23 Thread Dmitry Baryshkov

On 23/01/2023 20:24, Kuogee Hsieh wrote:

MSA MISC0 bit 1 to 7 contains Colorimetry Indicator Field. At current
implementation, Colorimetry Indicator Field of MISC0 is not configured
correctly. This patch add support of RGB formats Colorimetry.


Any Fixes tag? Not to mention that fixes should come first.



Signed-off-by: Kuogee Hsieh 
---
  drivers/gpu/drm/msm/dp/dp_ctrl.c  |  5 +++--
  drivers/gpu/drm/msm/dp/dp_link.c  | 29 +++--
  drivers/gpu/drm/msm/dp/dp_panel.c | 45 +++
  drivers/gpu/drm/msm/dp/dp_panel.h |  1 +
  4 files changed, 71 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
index 959a78c..d0d1848 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
@@ -1,6 +1,7 @@
  // SPDX-License-Identifier: GPL-2.0-only
  /*
- * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2023, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved
   */
  
  #define pr_fmt(fmt)	"[drm-dp] %s: " fmt, __func__

@@ -169,7 +170,7 @@ static void dp_ctrl_configure_source_params(struct 
dp_ctrl_private *ctrl)
  
  	tb = dp_link_get_test_bits_depth(ctrl->link,

ctrl->panel->dp_mode.bpp);
-   cc = dp_link_get_colorimetry_config(ctrl->link);
+   cc = dp_panel_get_misc_colorimetry_val(ctrl->panel);
dp_catalog_ctrl_config_misc(ctrl->catalog, cc, tb);
dp_panel_timing_cfg(ctrl->panel);
  }
diff --git a/drivers/gpu/drm/msm/dp/dp_link.c b/drivers/gpu/drm/msm/dp/dp_link.c
index f1f1d64..e957948 100644
--- a/drivers/gpu/drm/msm/dp/dp_link.c
+++ b/drivers/gpu/drm/msm/dp/dp_link.c
@@ -1,6 +1,7 @@
  // SPDX-License-Identifier: GPL-2.0-only
  /*
- * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2023, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved
   */
  
  #define pr_fmt(fmt)	"[drm-dp] %s: " fmt, __func__

@@ -12,6 +13,12 @@
  
  #define DP_TEST_REQUEST_MASK		0x7F
  
+enum dynamic_range {

+   DP_DYNAMIC_RANGE_RGB_VESA = 0x00,
+   DP_DYNAMIC_RANGE_RGB_CEA = 0x01,
+   DP_DYNAMIC_RANGE_UNKNOWN = 0x,


No need to assign values here, unless they serve some purpose. Do they?


+};
+
  enum audio_sample_rate {
AUDIO_SAMPLE_RATE_32_KHZ= 0x00,
AUDIO_SAMPLE_RATE_44_1_KHZ  = 0x01,
@@ -1079,6 +1086,7 @@ int dp_link_process_request(struct dp_link *dp_link)
  int dp_link_get_colorimetry_config(struct dp_link *dp_link)
  {
u32 cc;
+   enum dynamic_range dr;
struct dp_link_private *link;
  
  	if (!dp_link) {

@@ -1088,14 +1096,21 @@ int dp_link_get_colorimetry_config(struct dp_link 
*dp_link)
  
  	link = container_of(dp_link, struct dp_link_private, dp_link);
  
-	/*

-* Unless a video pattern CTS test is ongoing, use RGB_VESA
-* Only RGB_VESA and RGB_CEA supported for now
-*/
+   /* unless a video pattern CTS test is ongoing, use CEA_VESA */
if (dp_link_is_video_pattern_requested(link))
-   cc = link->dp_link.test_video.test_dyn_range;
+   dr = link->dp_link.test_video.test_dyn_range;
else
-   cc = DP_TEST_DYNAMIC_RANGE_VESA;
+   dr = DP_DYNAMIC_RANGE_RGB_VESA;
+
+   /* Only RGB_VESA nd RGB_CEA supported for now */
+   switch (dr) {
+   case DP_DYNAMIC_RANGE_RGB_CEA:
+   cc = BIT(2);
+   break;
+   case DP_DYNAMIC_RANGE_RGB_VESA:
+   default:
+   cc = 0;
+   }
  
  	return cc;

  }
diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c 
b/drivers/gpu/drm/msm/dp/dp_panel.c
index 36dad05..55bb6b0 100644
--- a/drivers/gpu/drm/msm/dp/dp_panel.c
+++ b/drivers/gpu/drm/msm/dp/dp_panel.c
@@ -567,6 +567,51 @@ int dp_panel_init_panel_info(struct dp_panel *dp_panel)
return 0;
  }
  
+/**


This marks the start of kerneldoc. But the rest of the comment isn't a 
kerneldoc.



+ * Mapper function which outputs colorimetry to be used for a
+ * given colorspace value when misc field of MSA is used to
+ * change the colorimetry. Currently only RGB formats have been
+ * added. This API will be extended to YUV once its supported on DP.


its != it's


+ */
+u8 dp_panel_get_misc_colorimetry_val(struct dp_panel *dp_panel)
+{
+   u8 colorimetry;
+   u32 colorspace;
+   u32 cc;
+   struct dp_panel_private *panel;
+
+   panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
+
+   cc = dp_link_get_colorimetry_config(panel->link);
+   /*
+* If there is a non-zero value then compliance test-case
+* is going on, otherwise we can honor the colorspace setting
+*/
+   if (cc)
+   return cc;
+
+   colorspace = dp_panel->connector->state->colorspace;
+   switch 

Re: [PATCH v3 4/7] drm: rcar-du: lvds: Fix stop sequence

2023-01-23 Thread Laurent Pinchart
Hi Geert,

On Mon, Jan 23, 2023 at 03:28:08PM +0100, Geert Uytterhoeven wrote:
> On Mon, Jan 23, 2023 at 11:48 AM Tomi Valkeinen wrote:
> > From: Koji Matsuoka 
> >
> > According to hardware manual, LVDCR0 register must be cleared bit by bit
> > when disabling LVDS.
> >
> > Signed-off-by: Koji Matsuoka 
> > Signed-off-by: LUU HOAI 
> > [tomi.valkeinen: simplified the code a bit]
> > Signed-off-by: Tomi Valkeinen 
> > Reviewed-by: Laurent Pinchart 
> 
> Thanks for your patch!
> 
> > @@ -544,6 +549,27 @@ static void rcar_lvds_atomic_disable(struct drm_bridge 
> > *bridge,
> >  struct drm_bridge_state 
> > *old_bridge_state)
> >  {
> > struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
> > +   u32 lvdcr0;
> > +
> > +   lvdcr0 = rcar_lvds_read(lvds, LVDCR0);
> > +
> > +   lvdcr0 &= ~LVDCR0_LVRES;
> > +   rcar_lvds_write(lvds, LVDCR0, lvdcr0);
> > +
> > +   if (lvds->info->quirks & RCAR_LVDS_QUIRK_GEN3_LVEN) {
> > +   lvdcr0 &= ~LVDCR0_LVEN;
> > +   rcar_lvds_write(lvds, LVDCR0, lvdcr0);
> > +   }
> > +
> > +   if (lvds->info->quirks & RCAR_LVDS_QUIRK_PWD) {
> > +   lvdcr0 &= ~LVDCR0_PWD;
> > +   rcar_lvds_write(lvds, LVDCR0, lvdcr0);
> > +   }
> > +
> > +   if (!(lvds->info->quirks & RCAR_LVDS_QUIRK_EXT_PLL)) {
> > +   lvdcr0 &= ~LVDCR0_PLLON;
> > +   rcar_lvds_write(lvds, LVDCR0, lvdcr0);
> > +   }
> 
> Please add a comment explaining why there are multiple register writes,
> to avoid an over-zealous janitor "optimizing" the code later.

I'll add this comment at the top of the function:

/*
 * Clear the LVDCR0 bits in the order specified by the hardware
 * documentation, ending with a write of 0 to the full register to
 * clear all remaining bits.
 */

> >
> > rcar_lvds_write(lvds, LVDCR0, 0);
> > rcar_lvds_write(lvds, LVDCR1, 0);

-- 
Regards,

Laurent Pinchart


Re: [PATCH v1 03/14] drm/msm/dp: add configure mainlink_levels base on lane number

2023-01-23 Thread Dmitry Baryshkov

On 23/01/2023 20:24, Kuogee Hsieh wrote:

Mainlink_levels determined when two actions to take place by hardware,
a new BS sequence due to start of video and a static HW MVID is sent
to panel. This patch add function to configure mainlink level properly
base on lane number.

Signed-off-by: Kuogee Hsieh 
---
  drivers/gpu/drm/msm/dp/dp_catalog.c | 37 -
  drivers/gpu/drm/msm/dp/dp_catalog.h |  4 +++-
  drivers/gpu/drm/msm/dp/dp_ctrl.c|  4 
  3 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c 
b/drivers/gpu/drm/msm/dp/dp_catalog.c
index 676279d..7ac37d8 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
@@ -1,6 +1,7 @@
  // SPDX-License-Identifier: GPL-2.0-only
  /*
- * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2023, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021. Qualcomm Innovation Center, Inc. All rights reserved
   */
  
  #define pr_fmt(fmt)	"[drm-dp] %s: " fmt, __func__

@@ -359,6 +360,40 @@ void dp_catalog_ctrl_lane_mapping(struct dp_catalog 
*dp_catalog)
ln_mapping);
  }
  
+void dp_catalog_ctrl_mainlink_levels(struct dp_catalog *dp_catalog,

+   u8 lane_cnt)
+{
+   struct dp_catalog_private *catalog = container_of(dp_catalog,
+   struct dp_catalog_private, dp_catalog);
+
+   u32 mainlink_levels, safe_to_exit_level = 14;
+
+   switch (lane_cnt) {
+   case 1:
+   safe_to_exit_level = 14;
+   break;
+   case 2:
+   safe_to_exit_level = 8;
+   break;
+   case 4:
+   safe_to_exit_level = 5;
+   break;
+   default:
+   drm_dbg_dp(catalog->drm_dev, "setting the default 
safe_to_exit_level=%u\n",
+   safe_to_exit_level);


So, set it here rather than somewhere at the top of the function.


+   break;
+   }
+
+   mainlink_levels = dp_read_link(catalog, REG_DP_MAINLINK_LEVELS);
+   mainlink_levels &= 0xFE0;
+   mainlink_levels |= safe_to_exit_level;
+
+   drm_dbg_dp(catalog->drm_dev, "mainlink_level=0x%x, 
safe_to_exit_level=0x%x\n",
+   mainlink_levels, safe_to_exit_level);
+
+   dp_write_link(catalog, REG_DP_MAINLINK_LEVELS, mainlink_levels);
+}
+
  void dp_catalog_ctrl_mainlink_ctrl(struct dp_catalog *dp_catalog,
bool enable)
  {
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h 
b/drivers/gpu/drm/msm/dp/dp_catalog.h
index 1f717f4..990c162 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.h
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.h
@@ -1,6 +1,7 @@
  /* SPDX-License-Identifier: GPL-2.0-only */
  /*
- * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2023, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021. Qualcomm Innovation Center, Inc. All rights reserved
   */
  
  #ifndef _DP_CATALOG_H_

@@ -92,6 +93,7 @@ u32 dp_catalog_aux_get_irq(struct dp_catalog *dp_catalog);
  void dp_catalog_ctrl_state_ctrl(struct dp_catalog *dp_catalog, u32 state);
  void dp_catalog_ctrl_config_ctrl(struct dp_catalog *dp_catalog, u32 config);
  void dp_catalog_ctrl_lane_mapping(struct dp_catalog *dp_catalog);
+void dp_catalog_ctrl_mainlink_levels(struct dp_catalog *dp_catalog, u8 
lane_cnt);
  void dp_catalog_ctrl_mainlink_ctrl(struct dp_catalog *dp_catalog, bool 
enable);
  void dp_catalog_ctrl_config_misc(struct dp_catalog *dp_catalog, u32 cc, u32 
tb);
  void dp_catalog_ctrl_config_msa(struct dp_catalog *dp_catalog, u32 rate,
diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c
index dd26ca6..959a78c 100644
--- a/drivers/gpu/drm/msm/dp/dp_ctrl.c
+++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c
@@ -161,6 +161,8 @@ static void dp_ctrl_configure_source_params(struct 
dp_ctrl_private *ctrl)
u32 cc, tb;
  
  	dp_catalog_ctrl_lane_mapping(ctrl->catalog);

+   dp_catalog_ctrl_mainlink_levels(ctrl->catalog,
+   ctrl->link->link_params.num_lanes);
dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, true);
  
  	dp_ctrl_config_ctrl(ctrl);

@@ -1296,6 +1298,8 @@ static int dp_ctrl_setup_main_link(struct dp_ctrl_private 
*ctrl,
  {
int ret = 0;
  
+	dp_catalog_ctrl_mainlink_levels(ctrl->catalog,

+   ctrl->link->link_params.num_lanes);
dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, true);
  
  	if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN)


--
With best wishes
Dmitry



Re: [PATCH v1 08/14] drm/msm/dp: add dsc supporting functions to DP controller

2023-01-23 Thread Dmitry Baryshkov

On 23/01/2023 20:24, Kuogee Hsieh wrote:

This patch provides DSC required functions at DP controller to
complete DSC feature. those functions include enable fec, configure
dsc, configure dto, transmit pps and finally flush hardware registers.


Too many items for a single patch in my opinion.



Signed-off-by: Kuogee Hsieh 
---
  drivers/gpu/drm/msm/dp/dp_catalog.c | 139 -
  drivers/gpu/drm/msm/dp/dp_catalog.h |  93 ++
  drivers/gpu/drm/msm/dp/dp_ctrl.c| 132 -
  drivers/gpu/drm/msm/dp/dp_display.c |  61 +++-
  drivers/gpu/drm/msm/dp/dp_panel.c   | 570 +++-
  drivers/gpu/drm/msm/dp/dp_panel.h   |   4 +
  drivers/gpu/drm/msm/dp/dp_reg.h |  40 ++-
  drivers/gpu/drm/msm/msm_drv.h   |  16 +
  8 files changed, 1033 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c 
b/drivers/gpu/drm/msm/dp/dp_catalog.c
index 7ac37d8..20a86e7 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
@@ -48,6 +48,11 @@
  #define DP_INTERRUPT_STATUS2_MASK \
(DP_INTERRUPT_STATUS2 << DP_INTERRUPT_STATUS_MASK_SHIFT)
  
+enum dp_flush_bit {

+   DP_PPS_FLUSH,
+   DP_DHDR_FLUSH,
+};
+
  struct dp_catalog_private {
struct device *dev;
struct drm_device *drm_dev;
@@ -277,6 +282,30 @@ static void dump_regs(void __iomem *base, int len)
}
  }
  
+void dp_catalog_fec_config(struct dp_catalog *dp_catalog, bool enable)

+{
+   struct dp_catalog_private *catalog = container_of(dp_catalog,
+   struct dp_catalog_private, dp_catalog);
+   u32 reg;
+
+   reg = dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
+
+   /*
+* fec_en = BIT(12)
+* fec_seq_mode = BIT(22)
+* sde_flush = BIT(23) | BIT(24)
+* fb_boundary_sel = BIT(25)


This should go to #define's instead.


+*/
+   if (enable)
+   reg |= BIT(12) | BIT(22) | BIT(23) | BIT(24) | BIT(25);
+   else
+   reg &= ~BIT(12);
+
+   dp_write_link(catalog, REG_DP_MAINLINK_CTRL, reg);
+   /* make sure mainlink configuration is updated with fec sequence */
+   wmb();
+}
+
  void dp_catalog_dump_regs(struct dp_catalog *dp_catalog)
  {
struct dp_catalog_private *catalog = container_of(dp_catalog,
@@ -344,6 +373,54 @@ void dp_catalog_ctrl_config_ctrl(struct dp_catalog 
*dp_catalog, u32 cfg)
dp_write_link(catalog, REG_DP_CONFIGURATION_CTRL, cfg);
  }
  
+void dp_catalog_config_dsc_dto(struct dp_catalog *dp_catalog)

+{
+   struct dp_catalog_private *catalog = container_of(dp_catalog,
+   struct dp_catalog_private, dp_catalog);
+   struct dp_dsc_cfg_data *dsc_data = _catalog->dsc_data;
+   u32 reg;
+
+   dp_write_p0(catalog, MMSS_DP_DSC_DTO_COUNT, dsc_data->dto_count);
+
+   reg = dp_read_p0(catalog, MMSS_DP_DSC_DTO);
+
+   if (dsc_data->dto_en) {
+   reg |= BIT(0);
+   reg |= BIT(3);
+   reg |= (dsc_data->dto_n << 8);
+   reg |= (dsc_data->dto_d << 16);
+   }
+
+   dp_write_p0(catalog, MMSS_DP_DSC_DTO, reg);
+
+   reg = 0;
+   if (dsc_data->dsc_en) {
+   reg = BIT(0);
+   reg |= (dsc_data->eol_byte_num << 3);
+   reg |= (dsc_data->slice_per_pkt << 5);
+   reg |= (dsc_data->bytes_per_pkt << 16);
+   reg |= (dsc_data->be_in_lane << 10);
+   }
+   dp_write_link(catalog, DP_COMPRESSION_MODE_CTRL, reg);
+
+   drm_dbg_dp(catalog->drm_dev, "compression:0x%x\n", reg);
+}
+
+void dp_catalog_override_ack_dto(struct dp_catalog *dp_catalog, bool not_ack)
+{
+   struct dp_catalog_private *catalog = container_of(dp_catalog,
+   struct dp_catalog_private, dp_catalog);
+u32 dsc_dto;
+
+   dsc_dto = dp_read_p0(catalog, MMSS_DP_DSC_DTO);
+if (not_ack)
+dsc_dto &= ~BIT(1);
+else
+dsc_dto = BIT(1);
+
+   dp_write_p0(catalog, MMSS_DP_DSC_DTO, dsc_dto);


The indentation looks weird. It might be my email client. Or may be not.


+}
+
  void dp_catalog_ctrl_lane_mapping(struct dp_catalog *dp_catalog)
  {
struct dp_catalog_private *catalog = container_of(dp_catalog,
@@ -429,6 +506,15 @@ void dp_catalog_ctrl_mainlink_ctrl(struct dp_catalog 
*dp_catalog,
}
  }
  
+static void dp_catalog_sdp_update( struct dp_catalog *dp_catalog)

+{
+   struct dp_catalog_private *catalog = container_of(dp_catalog,
+   struct dp_catalog_private, dp_catalog);
+
+   dp_write_link(catalog, MMSS_DP_SDP_CFG3, 0x01);
+   dp_write_link(catalog, MMSS_DP_SDP_CFG3, 0x00);
+}
+
  void dp_catalog_ctrl_config_misc(struct dp_catalog *dp_catalog,
u32 colorimetry_cfg,
u32 test_bits_depth)
@@ -504,7 +590,6 @@ void dp_catalog_ctrl_config_msa(struct dp_catalog 

Re: [PATCH v1 01/14] drm/msm/dp: add dpcd read of both dsc and fec capability

2023-01-23 Thread Dmitry Baryshkov

On 23/01/2023 20:24, Kuogee Hsieh wrote:

FEC is pre-requirement of DSC. Therefore FEC has to be enabled
before DSC enabled. This patch add functions to read sink's DSC
and FEC related DPCD and decode them and set enable flags
accordingly.


Please split this to FEC and DSC patches.



Signed-off-by: Kuogee Hsieh 
---
  drivers/gpu/drm/msm/dp/dp_panel.c | 91 ++-
  drivers/gpu/drm/msm/dp/dp_panel.h | 20 -
  2 files changed, 109 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c 
b/drivers/gpu/drm/msm/dp/dp_panel.c
index 1800d89..5078247 100644
--- a/drivers/gpu/drm/msm/dp/dp_panel.c
+++ b/drivers/gpu/drm/msm/dp/dp_panel.c
@@ -1,14 +1,18 @@
  // SPDX-License-Identifier: GPL-2.0-only
  /*
- * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2023, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023. Qualcomm Innovation Center, Inc. All rights reserved
   */
  
  #include "dp_panel.h"
  
+#include 

  #include 
  #include 
  #include 
  
+#define DSC_TGT_BPP 8

+
  struct dp_panel_private {
struct device *dev;
struct drm_device *drm_dev;
@@ -68,6 +72,9 @@ static int dp_panel_read_dpcd(struct dp_panel *dp_panel)
goto end;
}
  
+	print_hex_dump_debug("[drm-dp] SINK DPCD: ",

+   DUMP_PREFIX_NONE, 8, 1, dp_panel->dpcd, rlen, false);


I think this can go away.


+
link_info->revision = dpcd[DP_DPCD_REV];
major = (link_info->revision >> 4) & 0x0f;
minor = link_info->revision & 0x0f;
@@ -154,6 +161,83 @@ static int dp_panel_update_modes(struct drm_connector 
*connector,
return rc;
  }
  
+static void dp_panel_decode_dsc_dpcd(struct dp_panel *dp_panel)

+{
+   if (dp_panel->dsc_dpcd[0]) {
+   dp_panel->sink_dsc_caps.dsc_capable = true;
+   dp_panel->sink_dsc_caps.version = dp_panel->dsc_dpcd[1];
+   dp_panel->sink_dsc_caps.block_pred_en =
+   dp_panel->dsc_dpcd[6] ? true : false;
+   dp_panel->sink_dsc_caps.color_depth =
+   dp_panel->dsc_dpcd[10];
+
+   if (dp_panel->sink_dsc_caps.version >= 0x11)
+   dp_panel->dsc_en = true;
+   } else {
+   dp_panel->sink_dsc_caps.dsc_capable = false;
+   dp_panel->dsc_en = false;
+   }
+}
+
+static void dp_panel_read_sink_dsc_caps(struct dp_panel *dp_panel)
+{
+   int rlen;
+   struct dp_panel_private *panel;
+   int dpcd_rev;
+
+   if (!dp_panel) {
+   DRM_ERROR("invalid input\n");
+   return;
+   }
+
+   dpcd_rev = dp_panel->dpcd[DP_DPCD_REV];
+
+   panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
+   if (dpcd_rev >= 0x14) {
+   rlen = drm_dp_dpcd_read(panel->aux, DP_DSC_SUPPORT,
+   dp_panel->dsc_dpcd, (DP_DSC_RECEIVER_CAP_SIZE + 1));
+   if (rlen < (DP_DSC_RECEIVER_CAP_SIZE + 1)) {
+   drm_dbg_dp(panel->drm_dev, "dsc dpcd read failed, 
rlen=%d\n", rlen);
+   return;
+   }
+
+   print_hex_dump_debug("[drm-dp] SINK DSC DPCD: ",
+   DUMP_PREFIX_NONE, 8, 1, dp_panel->dsc_dpcd, rlen, 
false);


Oh. An extra dump again. Can we get rid of them please? Or can we use 
the standard drm debug levels? So that it would be possible to turn them 
on and off with standard params.



+
+   dp_panel_decode_dsc_dpcd(dp_panel);
+   }
+}
+
+static void dp_panel_read_sink_fec_caps(struct dp_panel *dp_panel)
+{
+   int rlen;
+   struct dp_panel_private *panel;
+   s64 fec_overhead_fp = drm_fixp_from_fraction(1, 1);
+
+   if (!dp_panel) {
+   DRM_ERROR("invalid input\n");
+   return;
+   }
+
+   panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
+   rlen = drm_dp_dpcd_readb(panel->aux, DP_FEC_CAPABILITY,
+   _panel->fec_dpcd);
+   if (rlen < 1) {
+   DRM_ERROR("fec capability read failed, rlen=%d\n", rlen);
+   return;
+   }
+
+   print_hex_dump_debug("[drm-dp] SINK FEC DPCD: ",
+   DUMP_PREFIX_NONE, 8, 1, _panel->fec_dpcd, rlen, false);
+
+   dp_panel->fec_en = dp_panel->fec_dpcd & DP_FEC_CAPABLE;
+
+   if (dp_panel->fec_en)
+   fec_overhead_fp = drm_fixp_from_fraction(10, 97582);
+
+   dp_panel->fec_overhead_fp = fec_overhead_fp;
+}
+
  int dp_panel_read_sink_caps(struct dp_panel *dp_panel,
struct drm_connector *connector)
  {
@@ -224,6 +308,11 @@ int dp_panel_read_sink_caps(struct dp_panel *dp_panel,
}
panel->aux_cfg_update_done = false;
}
+
+   dp_panel_read_sink_fec_caps(dp_panel);
+
+   if (dp_panel->fec_en)
+   dp_panel_read_sink_dsc_caps(dp_panel);
  end:
return 

Re: [PATCH v1 07/14] drm/msm/dp: add dsc helper functions

2023-01-23 Thread Marijn Suijten
This has nothing to do with /dp, make it /dpu


On 2023-01-23 10:24:27, Kuogee Hsieh wrote:
> Add DSC related supporting functions to calculate DSC related parameters.
> In addition, DSC hardware encoder customized configuration parameters are
> also included. Algorithms used to perform calculation are derived from
> system engineer spreadsheet.
> 
> Signed-off-by: Kuogee Hsieh 
> ---
>  drivers/gpu/drm/msm/Makefile   |   1 +
>  drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.c | 537 
> +
>  drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.h |  25 ++
>  drivers/gpu/drm/msm/msm_drv.h  |   4 +
>  4 files changed, 567 insertions(+)
>  create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.c
>  create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.h
> 
> diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
> index 7274c412..28cf52b 100644
> --- a/drivers/gpu/drm/msm/Makefile
> +++ b/drivers/gpu/drm/msm/Makefile
> @@ -65,6 +65,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \
>   disp/dpu1/dpu_hw_catalog.o \
>   disp/dpu1/dpu_hw_ctl.o \
>   disp/dpu1/dpu_hw_dsc.o \
> + disp/dpu1/dpu_dsc_helper.o \
>   disp/dpu1/dpu_hw_interrupts.o \
>   disp/dpu1/dpu_hw_intf.o \
>   disp/dpu1/dpu_hw_lm.o \
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.c
> new file mode 100644
> index ..48cef23
> --- /dev/null
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.c
> @@ -0,0 +1,537 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2012-2023 The Linux Foundation. All rights reserved.
> + * Copyright (c) 2023. Qualcomm Innovation Center, Inc. All rights reserved
> + */
> +
> +#include "msm_drv.h"
> +#include "dpu_kms.h"
> +#include "dpu_hw_dsc.h"
> +#include "dpu_dsc_helper.h"
> +
> +
> +#define DPU_DSC_PPS_SIZE   128
> +
> +enum dpu_dsc_ratio_type {
> + DSC_V11_8BPC_8BPP,
> + DSC_V11_10BPC_8BPP,
> + DSC_V11_10BPC_10BPP,
> + DSC_V11_SCR1_8BPC_8BPP,
> + DSC_V11_SCR1_10BPC_8BPP,
> + DSC_V11_SCR1_10BPC_10BPP,
> + DSC_V12_444_8BPC_8BPP = DSC_V11_SCR1_8BPC_8BPP,
> + DSC_V12_444_10BPC_8BPP = DSC_V11_SCR1_10BPC_8BPP,
> + DSC_V12_444_10BPC_10BPP = DSC_V11_SCR1_10BPC_10BPP,
> + DSC_V12_422_8BPC_7BPP,
> + DSC_V12_422_8BPC_8BPP,
> + DSC_V12_422_10BPC_7BPP,
> + DSC_V12_422_10BPC_10BPP,
> + DSC_V12_420_8BPC_6BPP,
> + DSC_V12_420_10BPC_6BPP,
> + DSC_V12_420_10BPC_7_5BPP,
> + DSC_RATIO_TYPE_MAX
> +};
> +
> +
> +static u16 dpu_dsc_rc_buf_thresh[DSC_NUM_BUF_RANGES - 1] = {
> + 0x0e, 0x1c, 0x2a, 0x38, 0x46, 0x54,
> + 0x62, 0x69, 0x70, 0x77, 0x79, 0x7b, 0x7d, 0x7e
> +};
> +
> +/*
> + * Rate control - Min QP values for each ratio type in dpu_dsc_ratio_type
> + */
> +static char dpu_dsc_rc_range_min_qp[DSC_RATIO_TYPE_MAX][DSC_NUM_BUF_RANGES] 
> = {
> + /* DSC v1.1 */
> + {0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 13},
> + {0, 4, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 11, 17},
> + {0, 4, 5, 6, 7, 7, 7, 7, 7, 7, 9, 9, 9, 11, 15},
> + /* DSC v1.1 SCR and DSC v1.2 RGB 444 */
> + {0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 9, 12},
> + {0, 4, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 13, 16},
> + {0, 4, 5, 6, 7, 7, 7, 7, 7, 7, 9, 9, 9, 11, 15},
> + /* DSC v1.2 YUV422 */
> + {0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 11},
> + {0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 10},
> + {0, 4, 5, 6, 7, 7, 7, 7, 7, 7, 9, 9, 9, 11, 15},
> + {0, 2, 3, 4, 5, 5, 5, 6, 6, 7, 8, 8, 9, 11, 12},
> + /* DSC v1.2 YUV420 */
> + {0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 10},
> + {0, 2, 3, 4, 6, 7, 7, 7, 7, 7, 9, 9, 9, 11, 14},
> + {0, 2, 3, 4, 5, 5, 5, 6, 6, 7, 8, 8, 9, 11, 12},
> +};
> +
> +/*
> + * Rate control - Max QP values for each ratio type in dpu_dsc_ratio_type
> + */
> +static char dpu_dsc_rc_range_max_qp[DSC_RATIO_TYPE_MAX][DSC_NUM_BUF_RANGES] 
> = {
> + /* DSC v1.1 */
> + {4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 11, 12, 13, 13, 15},
> + {4, 8, 9, 10, 11, 11, 11, 12, 13, 14, 15, 16, 17, 17, 19},
> + {7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16},
> + /* DSC v1.1 SCR and DSC v1.2 RGB 444 */
> + {4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 10, 11, 11, 12, 13},
> + {8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 14, 15, 15, 16, 17},
> + {7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16},
> + /* DSC v1.2 YUV422 */
> + {3, 4, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 11, 11, 12},
> + {2, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 10, 11},
> + {7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16},
> + {2, 5, 5, 6, 6, 7, 7, 8, 9, 9, 10, 11, 11, 12, 13},
> + /* DSC v1.2 YUV420 */
> + {2, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 10, 12},
> + {2, 5, 7, 8, 9, 10, 11, 12, 12, 13, 13, 13, 13, 14, 15},
> + {2, 5, 5, 6, 6, 7, 7, 8, 9, 9, 10, 11, 11, 12, 13},
> + };
> +
> +/*
> + * Rate control - bpg offset 

Re: [PATCH v1 09/14] drm/msm/dsi: export struct msm_compression_info to dpu encoder

2023-01-23 Thread Dmitry Baryshkov

On 23/01/2023 20:24, Kuogee Hsieh wrote:

struct msm_compression_info is used to support several different
compression mechanisms. It also contains customized info required
to configure DSC encoder engine. This patch also make changes DSI
module to have DSI exports struct msm_compreion_info to dpu encoder
instead of struct drm_dsc_config.


Let's see how patch 07 evolves first. But generally I don't like the 
idea of passing around another wrapper structure.




Signed-off-by: Kuogee Hsieh 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c |  7 +--
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h |  4 ++--
  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 10 --
  drivers/gpu/drm/msm/dsi/dsi.c   |  3 ++-
  drivers/gpu/drm/msm/dsi/dsi.h   |  3 ++-
  drivers/gpu/drm/msm/dsi/dsi_host.c  | 14 --
  drivers/gpu/drm/msm/msm_drv.h   |  4 ++--
  7 files changed, 33 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 758261e..7f4a439 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -2,7 +2,7 @@
  /*
   * Copyright (C) 2013 Red Hat
   * Copyright (c) 2014-2018, 2020-2021 The Linux Foundation. All rights 
reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights 
reserved.
   *
   * Author: Rob Clark 
   */
@@ -210,6 +210,7 @@ struct dpu_encoder_virt {
  
  	/* DSC configuration */

struct drm_dsc_config *dsc;
+   struct msm_compression_info *comp_info;
  };
  
  #define to_dpu_encoder_virt(x) container_of(x, struct dpu_encoder_virt, base)

@@ -2275,7 +2276,9 @@ static int dpu_encoder_setup_display(struct 
dpu_encoder_virt *dpu_enc,
dpu_enc->idle_pc_supported =
dpu_kms->catalog->caps->has_idle_pc;
  
-	dpu_enc->dsc = disp_info->dsc;

+   dpu_enc->comp_info = disp_info->comp_info;
+   if (dpu_enc->comp_info)
+   dpu_enc->dsc = _enc->comp_info->msm_dsc_info.drm_dsc;
  
  	mutex_lock(_enc->enc_lock);

for (i = 0; i < disp_info->num_of_h_tiles && !ret; i++) {
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
index 9e7236e..bd2da5e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
@@ -1,6 +1,6 @@
  /* SPDX-License-Identifier: GPL-2.0-only */
  /*
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights 
reserved.
   * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
   * Copyright (C) 2013 Red Hat
   * Author: Rob Clark 
@@ -36,7 +36,7 @@ struct msm_display_info {
uint32_t h_tile_instance[MAX_H_TILES_PER_DISPLAY];
bool is_cmd_mode;
bool is_te_using_watchdog_timer;
-   struct drm_dsc_config *dsc;
+   struct msm_compression_info *comp_info;
  };
  
  /**

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index d612419..70a74ed 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -2,7 +2,7 @@
  /*
   * Copyright (C) 2013 Red Hat
   * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights 
reserved.
   *
   * Author: Rob Clark 
   */
@@ -570,7 +570,7 @@ static int _dpu_kms_initialize_dsi(struct drm_device *dev,
info.h_tile_instance[info.num_of_h_tiles++] = i;
info.is_cmd_mode = msm_dsi_is_cmd_mode(priv->dsi[i]);
  
-		info.dsc = msm_dsi_get_dsc_config(priv->dsi[i]);

+   info.comp_info = msm_dsi_get_dsc_config(priv->dsi[i]);
  
  		if (msm_dsi_is_bonded_dsi(priv->dsi[i]) && priv->dsi[other]) {

rc = msm_dsi_modeset_init(priv->dsi[other], dev, 
encoder);
@@ -622,6 +622,8 @@ static int _dpu_kms_initialize_displayport(struct 
drm_device *dev,
info.num_of_h_tiles = 1;
info.h_tile_instance[0] = i;
info.intf_type = encoder->encoder_type;
+   info.is_cmd_mode = 0; /* dp always video mode */
+   info.comp_info = NULL;
rc = dpu_encoder_setup(dev, encoder, );
if (rc) {
DPU_ERROR("failed to setup DPU encoder %d: rc:%d\n",
@@ -892,6 +894,10 @@ static void dpu_kms_mdp_snapshot(struct msm_disp_state 
*disp_state, struct msm_k
  
  	pm_runtime_get_sync(_kms->pdev->dev);
  
+	for (i = 0; i < cat->dsc_count; i++)

+   msm_disp_snapshot_add_block(disp_state, cat->dsc[i].len,
+   dpu_kms->mmio + cat->dsc[i].base, 

Re: [PATCH v1 07/14] drm/msm/dp: add dsc helper functions

2023-01-23 Thread Dmitry Baryshkov

On 23/01/2023 20:24, Kuogee Hsieh wrote:

Add DSC related supporting functions to calculate DSC related parameters.
In addition, DSC hardware encoder customized configuration parameters are
also included. Algorithms used to perform calculation are derived from
system engineer spreadsheet.


Overall impression. First rewrite this patch to use existing data 
structures and helpers. Then move the remnants to the 
drm/display/drm_dsc_helper.c.




Signed-off-by: Kuogee Hsieh 
---
  drivers/gpu/drm/msm/Makefile   |   1 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.c | 537 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.h |  25 ++
  drivers/gpu/drm/msm/msm_drv.h  |   4 +
  4 files changed, 567 insertions(+)
  create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.c
  create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.h

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 7274c412..28cf52b 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -65,6 +65,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \
disp/dpu1/dpu_hw_catalog.o \
disp/dpu1/dpu_hw_ctl.o \
disp/dpu1/dpu_hw_dsc.o \
+   disp/dpu1/dpu_dsc_helper.o \
disp/dpu1/dpu_hw_interrupts.o \
disp/dpu1/dpu_hw_intf.o \
disp/dpu1/dpu_hw_lm.o \
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.c
new file mode 100644
index ..48cef23
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_dsc_helper.c
@@ -0,0 +1,537 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2012-2023 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023. Qualcomm Innovation Center, Inc. All rights reserved
+ */
+
+#include "msm_drv.h"
+#include "dpu_kms.h"
+#include "dpu_hw_dsc.h"
+#include "dpu_dsc_helper.h"
+
+
+#define DPU_DSC_PPS_SIZE   128


doesn't sizeof(drm_dsc_picture_parameter_set) work instead?


+
+enum dpu_dsc_ratio_type {
+   DSC_V11_8BPC_8BPP,
+   DSC_V11_10BPC_8BPP,
+   DSC_V11_10BPC_10BPP,
+   DSC_V11_SCR1_8BPC_8BPP,
+   DSC_V11_SCR1_10BPC_8BPP,
+   DSC_V11_SCR1_10BPC_10BPP,
+   DSC_V12_444_8BPC_8BPP = DSC_V11_SCR1_8BPC_8BPP,
+   DSC_V12_444_10BPC_8BPP = DSC_V11_SCR1_10BPC_8BPP,
+   DSC_V12_444_10BPC_10BPP = DSC_V11_SCR1_10BPC_10BPP,
+   DSC_V12_422_8BPC_7BPP,
+   DSC_V12_422_8BPC_8BPP,
+   DSC_V12_422_10BPC_7BPP,
+   DSC_V12_422_10BPC_10BPP,
+   DSC_V12_420_8BPC_6BPP,
+   DSC_V12_420_10BPC_6BPP,
+   DSC_V12_420_10BPC_7_5BPP,
+   DSC_RATIO_TYPE_MAX
+};
+
+
+static u16 dpu_dsc_rc_buf_thresh[DSC_NUM_BUF_RANGES - 1] = {
+   0x0e, 0x1c, 0x2a, 0x38, 0x46, 0x54,
+   0x62, 0x69, 0x70, 0x77, 0x79, 0x7b, 0x7d, 0x7e
+};
+
+/*
+ * Rate control - Min QP values for each ratio type in dpu_dsc_ratio_type
+ */
+static char dpu_dsc_rc_range_min_qp[DSC_RATIO_TYPE_MAX][DSC_NUM_BUF_RANGES] = {
+   /* DSC v1.1 */
+   {0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 13},
+   {0, 4, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 11, 17},
+   {0, 4, 5, 6, 7, 7, 7, 7, 7, 7, 9, 9, 9, 11, 15},
+   /* DSC v1.1 SCR and DSC v1.2 RGB 444 */
+   {0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 9, 12},
+   {0, 4, 5, 5, 7, 7, 7, 7, 7, 7, 9, 9, 9, 13, 16},
+   {0, 4, 5, 6, 7, 7, 7, 7, 7, 7, 9, 9, 9, 11, 15},
+   /* DSC v1.2 YUV422 */
+   {0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 11},
+   {0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 10},
+   {0, 4, 5, 6, 7, 7, 7, 7, 7, 7, 9, 9, 9, 11, 15},
+   {0, 2, 3, 4, 5, 5, 5, 6, 6, 7, 8, 8, 9, 11, 12},
+   /* DSC v1.2 YUV420 */
+   {0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 10},
+   {0, 2, 3, 4, 6, 7, 7, 7, 7, 7, 9, 9, 9, 11, 14},
+   {0, 2, 3, 4, 5, 5, 5, 6, 6, 7, 8, 8, 9, 11, 12},
+};
+
+/*
+ * Rate control - Max QP values for each ratio type in dpu_dsc_ratio_type
+ */
+static char dpu_dsc_rc_range_max_qp[DSC_RATIO_TYPE_MAX][DSC_NUM_BUF_RANGES] = {
+   /* DSC v1.1 */
+   {4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 11, 12, 13, 13, 15},
+   {4, 8, 9, 10, 11, 11, 11, 12, 13, 14, 15, 16, 17, 17, 19},
+   {7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16},
+   /* DSC v1.1 SCR and DSC v1.2 RGB 444 */
+   {4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 10, 11, 11, 12, 13},
+   {8, 8, 9, 10, 11, 11, 11, 12, 13, 14, 14, 15, 15, 16, 17},
+   {7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16},
+   /* DSC v1.2 YUV422 */
+   {3, 4, 5, 6, 7, 7, 7, 8, 9, 9, 10, 10, 11, 11, 12},
+   {2, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 10, 11},
+   {7, 8, 9, 10, 11, 11, 11, 12, 13, 13, 14, 14, 15, 15, 16},
+   {2, 5, 5, 6, 6, 7, 7, 8, 9, 9, 10, 11, 11, 12, 13},
+   /* DSC v1.2 YUV420 */
+   {2, 4, 5, 6, 7, 7, 7, 8, 8, 9, 9, 9, 9, 10, 12},
+   {2, 5, 7, 8, 9, 10, 11, 12, 12, 13, 13, 13, 13, 14, 15},
+   {2, 5, 5, 6, 6, 7, 7, 8, 9, 9, 10, 11, 11, 12, 13},

Re: [PATCH v1 11/14] drm/msm/disp/dpu1: add supports of new flush mechanism

2023-01-23 Thread Dmitry Baryshkov

On 23/01/2023 20:24, Kuogee Hsieh wrote:

A new flushing mechanism is introduced to decouple peripheral metadata
flushing from timing engine related flush. This patch add peripheral
flushing functions.

Signed-off-by: Kuogee Hsieh 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c| 24 ++--
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h   |  2 +
  .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c   |  7 
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 43 --
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 21 +++
  5 files changed, 91 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 901e317..d2625b3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1472,6 +1472,12 @@ static void _dpu_encoder_trigger_flush(struct 
drm_encoder *drm_enc,
if (extra_flush_bits && ctl->ops.update_pending_flush)
ctl->ops.update_pending_flush(ctl, extra_flush_bits);
  
+	if (phys->hw_intf->cap->type == INTF_DP &&

+   phys->comp_type == MSM_DISPLAY_COMPRESSION_DSC &&
+   phys->comp_ratio) {


Do you really need to know comp_ratio here? And the comp_type?


+   ctl->ops.update_pending_flush_periph(ctl, phys->hw_intf->idx);
+   }
+
ctl->ops.trigger_flush(ctl);
  
  	if (ctl->ops.get_pending_flush)

@@ -1814,12 +1820,18 @@ dpu_encoder_dsc_initial_line_calc(struct drm_dsc_config 
*dsc,
return DIV_ROUND_UP(total_pixels, dsc->slice_width);
  }
  
-static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc,

+static void dpu_encoder_dsc_pipe_cfg(struct dpu_encoder_virt *dpu_enc,
+struct dpu_hw_dsc *hw_dsc,
 struct dpu_hw_pingpong *hw_pp,
 struct drm_dsc_config *dsc,
 u32 common_mode,
 u32 initial_lines)
  {
+   struct dpu_encoder_phys *cur_master = dpu_enc->cur_master;
+   struct dpu_hw_ctl *ctl;
+
+   ctl = cur_master->hw_ctl;
+
if (hw_dsc->ops.dsc_config)
hw_dsc->ops.dsc_config(hw_dsc, dsc, common_mode, initial_lines, 
false);
  
@@ -1834,6 +1846,10 @@ static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc,
  
  	if (hw_pp->ops.enable_dsc)

hw_pp->ops.enable_dsc(hw_pp);
+
+   if (ctl->ops.update_pending_flush_dsc)
+   ctl->ops.update_pending_flush_dsc(ctl, hw_dsc->idx);
+
  }
  
  static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc,

@@ -1877,8 +1893,10 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt 
*dpu_enc,
enc_ip_w = intf_ip_w / 2;
initial_lines = dpu_encoder_dsc_initial_line_calc(dsc, enc_ip_w);
  
-	for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)

-   dpu_encoder_dsc_pipe_cfg(hw_dsc[i], hw_pp[i], dsc, 
dsc_common_mode, initial_lines);
+   for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
+   dpu_encoder_dsc_pipe_cfg(dpu_enc, hw_dsc[i], hw_pp[i], dsc,
+   dsc_common_mode, initial_lines);
+   }
  }
  
  void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
index 1d434b2..0569b36 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -200,6 +200,8 @@ struct dpu_encoder_phys {
atomic_t pending_kickoff_cnt;
wait_queue_head_t pending_kickoff_wq;
int irq[INTR_IDX_MAX];
+   enum msm_display_compression_type comp_type;
+   u32 comp_ratio;
  };
  
  static inline int dpu_encoder_phys_inc_pending(struct dpu_encoder_phys *phys)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
index 48c4810..2d864f9 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
@@ -1,5 +1,6 @@
  // SPDX-License-Identifier: GPL-2.0-only
  /* Copyright (c) 2015-2018, 2020-2021 The Linux Foundation. All rights 
reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights 
reserved.
   */
  
  #define pr_fmt(fmt)	"[drm:%s:%d] " fmt, __func__, __LINE__

@@ -427,6 +428,12 @@ static void dpu_encoder_phys_vid_enable(struct 
dpu_encoder_phys *phys_enc)
if (ctl->ops.update_pending_flush_merge_3d && phys_enc->hw_pp->merge_3d)
ctl->ops.update_pending_flush_merge_3d(ctl, 
phys_enc->hw_pp->merge_3d->idx);
  
+	if (phys_enc->hw_intf->cap->type == INTF_DP &&

+   phys_enc->comp_type == MSM_DISPLAY_COMPRESSION_DSC &&
+   phys_enc->comp_ratio) {
+ 

Re: [PATCH v1 12/14] drm/msm/disp/dpu1: revise timing engine programming to work for DSC

2023-01-23 Thread Dmitry Baryshkov

On 23/01/2023 20:24, Kuogee Hsieh wrote:

Current implementation timing engine programming does not consider
compression factors. This patch add consideration of DSC factors
while programming timing engine.

Signed-off-by: Kuogee Hsieh 
---
  .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c   |   2 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |  14 ++-
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c| 132 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h|  10 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h |   6 +-
  5 files changed, 110 insertions(+), 54 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
index 2d864f9..3330e185 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
@@ -279,6 +279,8 @@ static void dpu_encoder_phys_vid_setup_timing_engine(
if (phys_enc->hw_pp->merge_3d)
intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx;
  
+	phys_enc->hw_intf->hw_rev = phys_enc->dpu_kms->core_rev;

+
spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
phys_enc->hw_intf->ops.setup_timing_gen(phys_enc->hw_intf,
_params, fmt);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
index 7b0b092..c6ee789 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -43,16 +43,22 @@
  #define DPU_HW_VER_500DPU_HW_VER(5, 0, 0) /* sm8150 v1.0 */
  #define DPU_HW_VER_501DPU_HW_VER(5, 0, 1) /* sm8150 v2.0 */
  #define DPU_HW_VER_510DPU_HW_VER(5, 1, 1) /* sc8180 */
-#define DPU_HW_VER_600 DPU_HW_VER(6, 0, 0) /* sm8250 */
+#define DPU_HW_VER_600 DPU_HW_VER(6, 0, 0) /* sm8250, kona */
  #define DPU_HW_VER_620DPU_HW_VER(6, 2, 0) /* sc7180 v1.0 */
  #define DPU_HW_VER_630DPU_HW_VER(6, 3, 0) /* sm6115|sm4250 */
  #define DPU_HW_VER_650DPU_HW_VER(6, 5, 0) /* qcm2290|sm4125 */
-#define DPU_HW_VER_700 DPU_HW_VER(7, 0, 0) /* sm8350 */
+#define DPU_HW_VER_700 DPU_HW_VER(7, 0, 0) /* sm8350, lahaina */
  #define DPU_HW_VER_720DPU_HW_VER(7, 2, 0) /* sc7280 */
  #define DPU_HW_VER_800DPU_HW_VER(8, 0, 0) /* sc8280xp */
-#define DPU_HW_VER_810 DPU_HW_VER(8, 1, 0) /* sm8450 */
+#define DPU_HW_VER_810 DPU_HW_VER(8, 1, 0) /* sm8450, waipio */
  #define DPU_HW_VER_900DPU_HW_VER(9, 0, 0) /* sm8550 */


No.

  
+/* Avoid using below IS_XXX macros outside catalog, use feature bit instead */

+#define IS_DPU_MAJOR_SAME(rev1, rev2)   \
+   (DPU_HW_MAJOR((rev1)) == DPU_HW_MAJOR((rev2)))
+#define IS_DPU_MAJOR_MINOR_SAME(rev1, rev2)   \
+   (DPU_HW_MAJOR_MINOR((rev1)) == DPU_HW_MAJOR_MINOR((rev2)))
+
  #define IS_MSM8996_TARGET(rev) IS_DPU_MAJOR_MINOR_SAME((rev), DPU_HW_VER_170)
  #define IS_MSM8998_TARGET(rev) IS_DPU_MAJOR_MINOR_SAME((rev), DPU_HW_VER_300)
  #define IS_SDM845_TARGET(rev) IS_DPU_MAJOR_MINOR_SAME((rev), DPU_HW_VER_400)
@@ -240,6 +246,7 @@ enum {
   * @DPU_INTF_INPUT_CTRL Supports the setting of pp block from which
   *  pixel data arrives to this INTF
   * @DPU_INTF_TE INTF block has TE configuration support
+ * @DPU_INTF_TE_ALIGN_VSYNC INTF block has POMS Align vsync support
   * @DPU_DATA_HCTL_ENAllows data to be transferred at different 
rate
  than video timing
   * @DPU_INTF_MAX
@@ -247,6 +254,7 @@ enum {
  enum {
DPU_INTF_INPUT_CTRL = 0x1,
DPU_INTF_TE,
+   DPU_INTF_TE_ALIGN_VSYNC,
DPU_DATA_HCTL_EN,
DPU_INTF_MAX
  };
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
index 7ce66bf..238efdb 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
@@ -1,6 +1,6 @@
  // SPDX-License-Identifier: GPL-2.0-only
  /*
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights 
reserved.
   * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
   */
  
@@ -44,6 +44,7 @@

  #define   INTF_DEFLICKER_STRNG_COEFF0x0F4
  #define   INTF_DEFLICKER_WEAK_COEFF 0x0F8
  
+#define   INTF_REG_SPLIT_LINK   0x080

  #define   INTF_DSI_CMD_MODE_TRIGGER_EN  0x084
  #define   INTF_PANEL_FORMAT 0x090
  #define   INTF_TPG_ENABLE   0x100
@@ -65,9 +66,9 @@
  
  #define INTF_CFG_ACTIVE_H_EN	BIT(29)

  #define INTF_CFG_ACTIVE_V_EN  BIT(30)
-
  #define INTF_CFG2_DATABUS_WIDEN   BIT(0)
  #define INTF_CFG2_DATA_HCTL_ENBIT(4)
+#define INTF_CFG2_ALIGN_VSYNC_TO_TE BIT(16)
  
  #define INTF_MISR_CTRL			0x180

  #define INTF_MISR_SIGNATURE   0x184
@@ -91,6 +92,16 @@ static const struct dpu_intf_cfg 

Re: [PATCH 2/6] dt-bindings: phy: qcom,hdmi-phy-other: mark it as clock provider

2023-01-23 Thread Rob Herring


On Thu, 19 Jan 2023 15:22:15 +0200, Dmitry Baryshkov wrote:
> Eventually all HDMI PHYs are going to provide the HDMI PLL clock to the
> MMCC. Add #clock-cells property required to provide the HDMI PLL clock to
> other devices.
> 
> Signed-off-by: Dmitry Baryshkov 
> ---
>  .../devicetree/bindings/phy/qcom,hdmi-phy-other.yaml  | 4 
>  1 file changed, 4 insertions(+)
> 

Acked-by: Rob Herring 


Re: [PATCH] dt-bindings: drop type for operating-points-v2

2023-01-23 Thread Rob Herring


On Thu, 19 Jan 2023 14:10:33 +0100, Krzysztof Kozlowski wrote:
> The type for operating-points-v2 property is coming from dtschema
> (/schemas/opp/opp.yaml), so individual bindings can just use simple
> "true".
> 
> Signed-off-by: Krzysztof Kozlowski 
> 
> ---
> 
> This depends on my pull request, at least logically:
> https://github.com/devicetree-org/dt-schema/pull/95
> 
> Patch could be applied in parallel but only if above PULL is
> accepted/correct.
> ---
>  .../devicetree/bindings/display/msm/dp-controller.yaml | 3 +--
>  .../devicetree/bindings/display/tegra/nvidia,tegra20-dc.yaml   | 3 +--
>  .../devicetree/bindings/display/tegra/nvidia,tegra20-dsi.yaml  | 3 +--
>  .../devicetree/bindings/display/tegra/nvidia,tegra20-epp.yaml  | 3 +--
>  .../devicetree/bindings/display/tegra/nvidia,tegra20-gr2d.yaml | 3 +--
>  .../devicetree/bindings/display/tegra/nvidia,tegra20-gr3d.yaml | 3 +--
>  .../devicetree/bindings/display/tegra/nvidia,tegra20-hdmi.yaml | 3 +--
>  .../bindings/display/tegra/nvidia,tegra20-host1x.yaml  | 3 +--
>  .../devicetree/bindings/display/tegra/nvidia,tegra20-mpe.yaml  | 3 +--
>  .../devicetree/bindings/display/tegra/nvidia,tegra20-tvo.yaml  | 3 +--
>  .../devicetree/bindings/display/tegra/nvidia,tegra20-vi.yaml   | 3 +--
>  .../devicetree/bindings/fuse/nvidia,tegra20-fuse.yaml  | 3 +--
>  .../devicetree/bindings/mmc/nvidia,tegra20-sdhci.yaml  | 3 +--
>  Documentation/devicetree/bindings/power/power-domain.yaml  | 3 ---
>  Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.yaml  | 3 +--
>  15 files changed, 14 insertions(+), 31 deletions(-)
> 

Applied, thanks!


Re: [PATCH v2 7/9] drm/i915/pxp: MTL-KCR interrupt ctrl's are in GT-0

2023-01-23 Thread Teres Alexis, Alan Previn
On Wed, 2023-01-18 at 18:01 -0800, Ceraolo Spurio, Daniele wrote:
> 
> 
> On 1/11/2023 1:42 PM, Alan Previn wrote:
> > Despite KCR subsystem being in the media-tile (close to the
> > GSC-CS), the IRQ controls for it are on GT-0 with other global
> > IRQ controls. Thus, add a helper for KCR hw interrupt
> > enable/disable functions to get the correct gt structure (for
> > uncore) for MTL.
> > 
> > In the helper, we get GT-0's handle for uncore when touching
> > IRQ registers despite the pxp->ctrl_gt being the media-tile.
> > No difference for legacy of course.
> > 
> > Signed-off-by: Alan Previn 
> > ---
> >   drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c |  2 +-
> >   drivers/gpu/drm/i915/pxp/intel_pxp_irq.c | 23 +---
> >   drivers/gpu/drm/i915/pxp/intel_pxp_irq.h |  8 +++
> >   3 files changed, 29 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c 
> > b/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c
> > index 4b8e70caa3ad..9f6e300486b4 100644
> > --- a/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c
> > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_debugfs.c
> > @@ -44,7 +44,7 @@ static int pxp_terminate_get(void *data, u64 *val)
> >   static int pxp_terminate_set(void *data, u64 val)
> >   {
> > struct intel_pxp *pxp = data;
> > -   struct intel_gt *gt = pxp->ctrl_gt;
> > +   struct intel_gt *gt = intel_pxp_get_irq_gt(pxp);
> 
> This doesn't seem to be required here. The only use of gt in this 
> function is an assert below and both the root and media gt point to the 
> same irq_lock, so it doesn't matter which one we're using. Should we 
> keep it anyway just for safety in case things change in the future? or 
> just add a comment instead?
> 
I rather we keep this helper for consistency: everything else in front-end
pxp code is using pxp->ctrl_gt, but if we use pxp->[root_gt] here, it would
just read like a bug without understanding the hw details.
As you have pointed out farther down, the helper could just return root gt
always (since they both point to the same IRQ register). I will go ahead and
follow your recommendation for the helper internals (with the comments
explaining in detail) but have the callers continue to use that helper.

> >   
> > if (!intel_pxp_is_active(pxp))
> > return -ENODEV;
> > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c 
> > b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
> > index 91e9622c07d0..2eef0c19e91a 100644
> > --- a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
> > +++ b/drivers/gpu/drm/i915/pxp/intel_pxp_irq.c
> > @@ -8,6 +8,7 @@
> >   #include "gt/intel_gt_regs.h"
> >   #include "gt/intel_gt_types.h"
> >   
> > +#include "i915_drv.h"
> >   #include "i915_irq.h"
> >   #include "i915_reg.h"
> >   
> > @@ -17,6 +18,22 @@
> >   #include "intel_pxp_types.h"
> >   #include "intel_runtime_pm.h"
> >   
> > +/**
> > + * intel_pxp_get_irq_gt - Find the correct GT that owns KCR interrupts
> > + * @pxp: pointer to pxp struct
> > + *
> > + * For platforms with a single GT, we return the pxp->ctrl_gt (as expected)
> > + * but for MTL+ that has a media-tile, although the KCR engine is in the
> > + * media-tile (i.e. pxp->ctrl_gt), the IRQ controls are on the root tile.
> > + */
> > +struct intel_gt *intel_pxp_get_irq_gt(struct intel_pxp *pxp)
> > +{
> > +   if (pxp->uses_gsccs)
> > +   return to_gt(pxp->ctrl_gt->i915);
> > +
> > +   return pxp->ctrl_gt;
> 
> AFAICT here we can skip the if and always return the root gt, because 
> that's what happens in both cases. If you want to make sure we don't get 
> issues in the future maybe instead add a:
> 
> GEM_BUG_ON(!i915->media_gt && !gt_is_root(pxp->ctrl_gt))

will do.

> 
> > +}
> > +
> >   /**
> >    * intel_pxp_irq_handler - Handles PXP interrupts.
> >    * @pxp: pointer to pxp struct
> > @@ -29,7 +46,7 @@ void intel_pxp_irq_handler(struct intel_pxp *pxp, u16 iir)
> > if (GEM_WARN_ON(!intel_pxp_is_enabled(pxp)))
> > return;
> >   
> > -   gt = pxp->ctrl_gt;
> > +   gt = intel_pxp_get_irq_gt(pxp);
> 
> Here also we only have the assert below
i will follow the above recommendation.
> 
> Daniele
> 
> >   
> > lockdep_assert_held(gt->irq_lock);
> >   
> > @@ -68,7 +85,7 @@ static inline void pxp_irq_reset(struct intel_gt *gt)
> >   
> >   void intel_pxp_irq_enable(struct intel_pxp *pxp)
> >   {
> > -   struct intel_gt *gt = pxp->ctrl_gt;
> > +   struct intel_gt *gt = intel_pxp_get_irq_gt(pxp);
> >   
> > spin_lock_irq(gt->irq_lock);
> >   
> > @@ -83,7 +100,7 @@ void intel_pxp_irq_enable(struct intel_pxp *pxp)
> >   
> >   void intel_pxp_irq_disable(struct intel_pxp *pxp)
> >   {
> > -   struct intel_gt *gt = pxp->ctrl_gt;
> > +   struct intel_gt *gt = intel_pxp_get_irq_gt(pxp);
> >   
> > /*
> >  * We always need to submit a global termination when we re-enable 
> > the
> > diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp_irq.h 
> > 

Re: [Lsf-pc] [LSF/MM/BPF proposal]: Physr discussion

2023-01-23 Thread Dan Williams
Matthew Wilcox wrote:
> On Mon, Jan 23, 2023 at 11:36:51AM -0800, Dan Williams wrote:
> > Jason Gunthorpe via Lsf-pc wrote:
> > > I would like to have a session at LSF to talk about Matthew's
> > > physr discussion starter:
> > > 
> > >  https://lore.kernel.org/linux-mm/ydykweu0htv8m...@casper.infradead.org/
> > > 
> > > I have become interested in this with some immediacy because of
> > > IOMMUFD and this other discussion with Christoph:
> > > 
> > >  
> > > https://lore.kernel.org/kvm/4-v2-472615b3877e+28f7-vfio_dma_buf_...@nvidia.com/
> > 
> > I think this is a worthwhile discussion. My main hangup with 'struct
> > page' elimination in general is that if anything needs to be allocated
> 
> You're the first one to bring up struct page elimination.  Neither Jason
> nor I have that as our motivation.

Oh, ok, then maybe I misread the concern in the vfio discussion. I
thought the summary there is debating the ongoing requirement for
'struct page' for P2PDMA?


Re: [PATCH 10/10] drm/fbdev-generic: Rename struct fb_info 'fbi' to 'info'

2023-01-23 Thread Sam Ravnborg
Hi Thomas,

a quick drive-by comment.

On Mon, Jan 23, 2023 at 11:05:59AM +0100, Thomas Zimmermann wrote:
> The generic fbdev emulation names variables of type struct fb_info
> both 'fbi' and 'info'. The latter seems to be more common in fbdev
> code, so name fbi accordingly.
> 
> Also replace the duplicate variable in drm_fbdev_fb_destroy().
> 
> Signed-off-by: Thomas Zimmermann 
> ---
>  drivers/gpu/drm/drm_fbdev_generic.c | 49 ++---
>  1 file changed, 24 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_fbdev_generic.c 
> b/drivers/gpu/drm/drm_fbdev_generic.c
> index 49a0bba86ce7..7633da5c13c3 100644
> --- a/drivers/gpu/drm/drm_fbdev_generic.c
> +++ b/drivers/gpu/drm/drm_fbdev_generic.c
> @@ -46,17 +46,16 @@ static int drm_fbdev_fb_release(struct fb_info *info, int 
> user)
>  static void drm_fbdev_fb_destroy(struct fb_info *info)
>  {
>   struct drm_fb_helper *fb_helper = info->par;
> - struct fb_info *fbi = fb_helper->info;
>   void *shadow = NULL;
>  
>   if (!fb_helper->dev)
>   return;
>  
> - if (fbi) {
> - if (fbi->fbdefio)
> - fb_deferred_io_cleanup(fbi);
> + if (info) {
As info is already used above to find fb_helper, this check is
redundant.

Sam

> + if (info->fbdefio)
> + fb_deferred_io_cleanup(info);
>   if (drm_fbdev_use_shadow_fb(fb_helper))
> - shadow = fbi->screen_buffer;
> + shadow = info->screen_buffer;
>   }
>  
>   drm_fb_helper_fini(fb_helper);
> @@ -173,7 +172,7 @@ static int drm_fbdev_fb_probe(struct drm_fb_helper 
> *fb_helper,
>   struct drm_device *dev = fb_helper->dev;
>   struct drm_client_buffer *buffer;
>   struct drm_framebuffer *fb;
> - struct fb_info *fbi;
> + struct fb_info *info;
>   u32 format;
>   struct iosys_map map;
>   int ret;
> @@ -192,35 +191,35 @@ static int drm_fbdev_fb_probe(struct drm_fb_helper 
> *fb_helper,
>   fb_helper->fb = buffer->fb;
>   fb = buffer->fb;
>  
> - fbi = drm_fb_helper_alloc_info(fb_helper);
> - if (IS_ERR(fbi))
> - return PTR_ERR(fbi);
> + info = drm_fb_helper_alloc_info(fb_helper);
> + if (IS_ERR(info))
> + return PTR_ERR(info);
>  
> - fbi->fbops = _fbdev_fb_ops;
> - fbi->screen_size = sizes->surface_height * fb->pitches[0];
> - fbi->fix.smem_len = fbi->screen_size;
> - fbi->flags = FBINFO_DEFAULT;
> + info->fbops = _fbdev_fb_ops;
> + info->screen_size = sizes->surface_height * fb->pitches[0];
> + info->fix.smem_len = info->screen_size;
> + info->flags = FBINFO_DEFAULT;
>  
> - drm_fb_helper_fill_info(fbi, fb_helper, sizes);
> + drm_fb_helper_fill_info(info, fb_helper, sizes);
>  
>   if (drm_fbdev_use_shadow_fb(fb_helper)) {
> - fbi->screen_buffer = vzalloc(fbi->screen_size);
> - if (!fbi->screen_buffer)
> + info->screen_buffer = vzalloc(info->screen_size);
> + if (!info->screen_buffer)
>   return -ENOMEM;
> - fbi->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST;
> + info->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST;
>  
> - fbi->fbdefio = _fbdev_defio;
> - fb_deferred_io_init(fbi);
> + info->fbdefio = _fbdev_defio;
> + fb_deferred_io_init(info);
>   } else {
>   /* buffer is mapped for HW framebuffer */
>   ret = drm_client_buffer_vmap(fb_helper->buffer, );
>   if (ret)
>   return ret;
>   if (map.is_iomem) {
> - fbi->screen_base = map.vaddr_iomem;
> + info->screen_base = map.vaddr_iomem;
>   } else {
> - fbi->screen_buffer = map.vaddr;
> - fbi->flags |= FBINFO_VIRTFB;
> + info->screen_buffer = map.vaddr;
> + info->flags |= FBINFO_VIRTFB;
>   }
>  
>   /*
> @@ -229,10 +228,10 @@ static int drm_fbdev_fb_probe(struct drm_fb_helper 
> *fb_helper,
>* case.
>*/
>  #if IS_ENABLED(CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM)
> - if (fb_helper->hint_leak_smem_start && fbi->fix.smem_start == 0 
> &&
> + if (fb_helper->hint_leak_smem_start && info->fix.smem_start == 
> 0 &&
>   !drm_WARN_ON_ONCE(dev, map.is_iomem))
> - fbi->fix.smem_start =
> - page_to_phys(virt_to_page(fbi->screen_buffer));
> + info->fix.smem_start =
> + page_to_phys(virt_to_page(info->screen_buffer));
>  #endif
>   }
>  
> -- 
> 2.39.0


Re: [PATCH 85/86] drm: move drm_timeout_abs_to_jiffies to drm_util

2023-01-23 Thread Sam Ravnborg
Hi Thomas,

On Mon, Jan 23, 2023 at 09:57:13AM +0100, Thomas Zimmermann wrote:
> Hi Sam,
> 
> please see my comment below.
> 
> Am 21.01.23 um 21:09 schrieb Sam Ravnborg via B4 Submission Endpoint:
> > From: Sam Ravnborg 
> > 
> > drm_timeout_abs_to_jiffies() was implmented in drm_syncobj where
> > it really did not belong. Create a drm_util file and move the
> > implementation. Likewise move the prototype and update all users.
> > 
> > Suggested-by: Daniel Vetter 
> > [https://lore.kernel.org/dri-devel/20190527185311.GS21222@phenom.ffwll.local/]
> > Cc: Daniel Vetter 
> > Signed-off-by: Sam Ravnborg 
> > ---
> >   drivers/accel/ivpu/ivpu_gem.c   |  2 +-
> >   drivers/gpu/drm/Makefile|  1 +
> >   drivers/gpu/drm/drm_syncobj.c   | 34 
> >   drivers/gpu/drm/drm_util.c  | 40 
> > +
> >   drivers/gpu/drm/lima/lima_gem.c |  2 +-
> >   drivers/gpu/drm/panfrost/panfrost_drv.c |  2 +-
> >   drivers/gpu/drm/tegra/uapi.c|  2 +-
> >   include/drm/drm_util.h  |  1 +
> >   include/drm/drm_utils.h |  2 --
> >   9 files changed, 46 insertions(+), 40 deletions(-)
> > 
> > diff --git a/drivers/accel/ivpu/ivpu_gem.c b/drivers/accel/ivpu/ivpu_gem.c
> > index d1f923971b4c..55aa94ba6c10 100644
> > --- a/drivers/accel/ivpu/ivpu_gem.c
> > +++ b/drivers/accel/ivpu/ivpu_gem.c
> > @@ -12,7 +12,7 @@
> >   #include 
> >   #include 
> >   #include 
> > -#include 
> > +#include 
> >   #include "ivpu_drv.h"
> >   #include "ivpu_gem.h"
> > diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> > index ab4460fcd63f..561b93d19685 100644
> > --- a/drivers/gpu/drm/Makefile
> > +++ b/drivers/gpu/drm/Makefile
> > @@ -42,6 +42,7 @@ drm-y := \
> > drm_syncobj.o \
> > drm_sysfs.o \
> > drm_trace_points.o \
> > +   drm_util.o \
> > drm_vblank.o \
> > drm_vblank_work.o \
> > drm_vma_manager.o \
> > diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
> > index 0c2be8360525..35f5416c5cfe 100644
> > --- a/drivers/gpu/drm/drm_syncobj.c
> > +++ b/drivers/gpu/drm/drm_syncobj.c
> > @@ -197,7 +197,6 @@
> >   #include 
> >   #include 
> >   #include 
> > -#include 
> >   #include "drm_internal.h"
> > @@ -1114,39 +1113,6 @@ static signed long 
> > drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
> > return timeout;
> >   }
> > -/**
> > - * drm_timeout_abs_to_jiffies - calculate jiffies timeout from absolute 
> > value
> > - *
> > - * @timeout_nsec: timeout nsec component in ns, 0 for poll
> > - *
> > - * Calculate the timeout in jiffies from an absolute time in sec/nsec.
> > - */
> > -signed long drm_timeout_abs_to_jiffies(int64_t timeout_nsec)

Thanks for the critical look at this!

> 
> This function converts an absolute timeout in nsec to a relative timeout in
> jiffies. (?)
> 
> It appears to me as if this helper should not exist. It uses a mixture of
> different time interfaces; combined with hardcoded policy for 0 and
> MAX_SCHEDULE_TIMEOUT.
> 
> There are only 3 callers of this helper. I think we should consider inlining
> it in each.
> 
> As part of this, maybe the use of ktime could go away. Convert nsecs to
> jiffies and do the rest of the computation in jiffies.

I blindly copied the existing function and did not consider the
implementation. Looking for a helper that do what we needs here turned
up empty. I also looked at your suggestion to do:
nsec in absolute => jiffies in absolute => jiffies in relative
But did not find something that is better than what we have.

I will leave it for now, and focus on the other parts of the patchset.
In the vain hope someone else takes a look.

Sam


Re: [RFC PATCH] drm: Create documentation about device resets

2023-01-23 Thread Christian König

Am 23.01.23 um 21:26 schrieb André Almeida:

Create a document that specifies how to deal with DRM device resets for
kernel and userspace drivers.

Signed-off-by: André Almeida 
---
  Documentation/gpu/drm-reset.rst | 51 +
  Documentation/gpu/index.rst |  1 +
  2 files changed, 52 insertions(+)
  create mode 100644 Documentation/gpu/drm-reset.rst

diff --git a/Documentation/gpu/drm-reset.rst b/Documentation/gpu/drm-reset.rst
new file mode 100644
index ..0dd11a469cf9
--- /dev/null
+++ b/Documentation/gpu/drm-reset.rst
@@ -0,0 +1,51 @@
+
+DRM Device Reset
+
+
+The GPU stack is really complex and is prone to errors, from hardware bugs,
+faulty applications and everything in the many layers in between. To recover
+from this kind of state, sometimes is needed to reset the GPU. Unproper 
handling
+of GPU resets can lead to an unstable userspace. This page describes what's the
+expected behaviour from DRM drivers to do in those situations, from usermode
+drivers and compositors as well.
+
+Robustness
+--
+
+First of all, application robust APIs, when available, should be used. This
+allows the application to correctly recover and continue to run after a reset.
+Apps that doesn't use this should be promptly killed when the kernel driver
+detects that it's in broken state. Specifically guidelines for some APIs:
+



+- OpenGL: During a reset, KMD kill processes that haven't ARB Robustness
+  enabled, assuming they can't recover.


This is a pretty clear NAK from my side to this approach. The KMD should 
never mess with an userspace process directly in such a way.


Instead use something like this "OpenGL: KMD signals the abortion of 
submitted commands and the UMD should then react accordingly and abort 
the application.".



+- Vulkan: Assumes that every app is able to deal with ``VK_ERROR_DEVICE_LOST``,
+  so KMD doesn't kill any. If it doesn't do it right, it's considered a broken
+  application and UMD will deal with it.


Again, pleas remove the "KMD kill" reference.


+
+Kernel mode driver
+--
+
+The KMD should be able to detect that something is wrong with the application


Please replace *should* with *must* here, this is mandatory or otherwise 
core memory management can run into deadlocks during reclaim.


Regards,
Christian.


+and that a reset is needed to take place to recover the device (e.g. an endless
+wait). It needs to properly track the context that is broken and mark it as
+dead, so any other syscalls to that context should be further rejected. The
+other contexts should be preserved when possible, avoid crashing the rest of
+userspace. KMD can ban a file descriptor that keeps causing resets, as it's
+likely in a broken loop.
+
+User mode driver
+
+
+During a reset, UMD should be aware that rejected syscalls indicates that the
+context is broken and for robust apps the recovery should happen for the
+context. Non-robust apps would be already terminated by KMD. If no new context
+is created for some time, it is assumed that the recovery didn't work, so UMD
+should terminate it.
+
+Compositors
+---
+
+(In the long term) compositors should be robust as well to properly deal with 
it
+errors. Init systems should be aware of the compositor status and reset it if 
is
+broken.
diff --git a/Documentation/gpu/index.rst b/Documentation/gpu/index.rst
index b99dede9a5b1..300b2529bd39 100644
--- a/Documentation/gpu/index.rst
+++ b/Documentation/gpu/index.rst
@@ -9,6 +9,7 @@ Linux GPU Driver Developer's Guide
 drm-mm
 drm-kms
 drm-kms-helpers
+   drm-reset
 drm-uapi
 drm-usage-stats
 driver-uapi




[PATCH v3 03/10] iommu: Add a gfp parameter to iommu_map_sg()

2023-01-23 Thread Jason Gunthorpe
Follow the pattern for iommu_map() and remove iommu_map_sg_atomic().

This allows __iommu_dma_alloc_noncontiguous() to use a GFP_KERNEL
allocation here, based on the provided gfp flags.

Reviewed-by: Kevin Tian 
Signed-off-by: Jason Gunthorpe 
---
 drivers/iommu/dma-iommu.c |  5 +++--
 drivers/iommu/iommu.c | 26 ++
 include/linux/iommu.h | 18 +-
 3 files changed, 18 insertions(+), 31 deletions(-)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 7016db569f81fc..72cfa24503b8bc 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -833,7 +833,8 @@ static struct page **__iommu_dma_alloc_noncontiguous(struct 
device *dev,
arch_dma_prep_coherent(sg_page(sg), sg->length);
}
 
-   ret = iommu_map_sg_atomic(domain, iova, sgt->sgl, sgt->orig_nents, 
ioprot);
+   ret = iommu_map_sg(domain, iova, sgt->sgl, sgt->orig_nents, ioprot,
+  GFP_ATOMIC);
if (ret < 0 || ret < size)
goto out_free_sg;
 
@@ -1281,7 +1282,7 @@ static int iommu_dma_map_sg(struct device *dev, struct 
scatterlist *sg,
 * We'll leave any physical concatenation to the IOMMU driver's
 * implementation - it knows better than we do.
 */
-   ret = iommu_map_sg_atomic(domain, iova, sg, nents, prot);
+   ret = iommu_map_sg(domain, iova, sg, nents, prot, GFP_ATOMIC);
if (ret < 0 || ret < iova_len)
goto out_free_iova;
 
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 9412b420d07257..cc6e7c6bf72758 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2470,9 +2470,9 @@ size_t iommu_unmap_fast(struct iommu_domain *domain,
 }
 EXPORT_SYMBOL_GPL(iommu_unmap_fast);
 
-static ssize_t __iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
-   struct scatterlist *sg, unsigned int nents, int prot,
-   gfp_t gfp)
+ssize_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
+struct scatterlist *sg, unsigned int nents, int prot,
+gfp_t gfp)
 {
const struct iommu_domain_ops *ops = domain->ops;
size_t len = 0, mapped = 0;
@@ -2480,6 +2480,13 @@ static ssize_t __iommu_map_sg(struct iommu_domain 
*domain, unsigned long iova,
unsigned int i = 0;
int ret;
 
+   might_sleep_if(gfpflags_allow_blocking(gfp));
+
+   /* Discourage passing strange GFP flags */
+   if (WARN_ON_ONCE(gfp & (__GFP_COMP | __GFP_DMA | __GFP_DMA32 |
+   __GFP_HIGHMEM)))
+   return -EINVAL;
+
while (i <= nents) {
phys_addr_t s_phys = sg_phys(sg);
 
@@ -2519,21 +2526,8 @@ static ssize_t __iommu_map_sg(struct iommu_domain 
*domain, unsigned long iova,
 
return ret;
 }
-
-ssize_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
-struct scatterlist *sg, unsigned int nents, int prot)
-{
-   might_sleep();
-   return __iommu_map_sg(domain, iova, sg, nents, prot, GFP_KERNEL);
-}
 EXPORT_SYMBOL_GPL(iommu_map_sg);
 
-ssize_t iommu_map_sg_atomic(struct iommu_domain *domain, unsigned long iova,
-   struct scatterlist *sg, unsigned int nents, int prot)
-{
-   return __iommu_map_sg(domain, iova, sg, nents, prot, GFP_ATOMIC);
-}
-
 /**
  * report_iommu_fault() - report about an IOMMU fault to the IOMMU framework
  * @domain: the iommu domain where the fault has happened
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 521cd79700f4d8..d5c16dc33c87de 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -474,10 +474,8 @@ extern size_t iommu_unmap_fast(struct iommu_domain *domain,
   unsigned long iova, size_t size,
   struct iommu_iotlb_gather *iotlb_gather);
 extern ssize_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
-   struct scatterlist *sg, unsigned int nents, int prot);
-extern ssize_t iommu_map_sg_atomic(struct iommu_domain *domain,
-  unsigned long iova, struct scatterlist *sg,
-  unsigned int nents, int prot);
+   struct scatterlist *sg, unsigned int nents,
+   int prot, gfp_t gfp);
 extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t 
iova);
 extern void iommu_set_fault_handler(struct iommu_domain *domain,
iommu_fault_handler_t handler, void *token);
@@ -791,14 +789,7 @@ static inline size_t iommu_unmap_fast(struct iommu_domain 
*domain,
 
 static inline ssize_t iommu_map_sg(struct iommu_domain *domain,
   unsigned long iova, struct scatterlist *sg,
-  unsigned int nents, int prot)
-{
-   return -ENODEV;
-}
-
-static inline ssize_t iommu_map_sg_atomic(struct 

[PATCH v3 09/10] iommu/s390: Push the gfp parameter to the kmem_cache_alloc()'s

2023-01-23 Thread Jason Gunthorpe
dma_alloc_cpu_table() and dma_alloc_page_table() are eventually called by
iommufd through s390_iommu_map_pages() and it should not be forced to
atomic. Thread the gfp parameter through the call chain starting from
s390_iommu_map_pages().

Reviewed-by: Niklas Schnelle 
Reviewed-by: Matthew Rosato 
Signed-off-by: Jason Gunthorpe 
---
 arch/s390/include/asm/pci_dma.h |  5 +++--
 arch/s390/pci/pci_dma.c | 31 +--
 drivers/iommu/s390-iommu.c  | 15 +--
 3 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/arch/s390/include/asm/pci_dma.h b/arch/s390/include/asm/pci_dma.h
index 91e63426bdc53f..7119c04c51c5c8 100644
--- a/arch/s390/include/asm/pci_dma.h
+++ b/arch/s390/include/asm/pci_dma.h
@@ -186,9 +186,10 @@ static inline unsigned long *get_st_pto(unsigned long 
entry)
 
 /* Prototypes */
 void dma_free_seg_table(unsigned long);
-unsigned long *dma_alloc_cpu_table(void);
+unsigned long *dma_alloc_cpu_table(gfp_t gfp);
 void dma_cleanup_tables(unsigned long *);
-unsigned long *dma_walk_cpu_trans(unsigned long *rto, dma_addr_t dma_addr);
+unsigned long *dma_walk_cpu_trans(unsigned long *rto, dma_addr_t dma_addr,
+ gfp_t gfp);
 void dma_update_cpu_trans(unsigned long *entry, phys_addr_t page_addr, int 
flags);
 
 extern const struct dma_map_ops s390_pci_dma_ops;
diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c
index ea478d11fbd132..2f6d05d6da4f76 100644
--- a/arch/s390/pci/pci_dma.c
+++ b/arch/s390/pci/pci_dma.c
@@ -27,11 +27,11 @@ static int zpci_refresh_global(struct zpci_dev *zdev)
  zdev->iommu_pages * PAGE_SIZE);
 }
 
-unsigned long *dma_alloc_cpu_table(void)
+unsigned long *dma_alloc_cpu_table(gfp_t gfp)
 {
unsigned long *table, *entry;
 
-   table = kmem_cache_alloc(dma_region_table_cache, GFP_ATOMIC);
+   table = kmem_cache_alloc(dma_region_table_cache, gfp);
if (!table)
return NULL;
 
@@ -45,11 +45,11 @@ static void dma_free_cpu_table(void *table)
kmem_cache_free(dma_region_table_cache, table);
 }
 
-static unsigned long *dma_alloc_page_table(void)
+static unsigned long *dma_alloc_page_table(gfp_t gfp)
 {
unsigned long *table, *entry;
 
-   table = kmem_cache_alloc(dma_page_table_cache, GFP_ATOMIC);
+   table = kmem_cache_alloc(dma_page_table_cache, gfp);
if (!table)
return NULL;
 
@@ -63,7 +63,7 @@ static void dma_free_page_table(void *table)
kmem_cache_free(dma_page_table_cache, table);
 }
 
-static unsigned long *dma_get_seg_table_origin(unsigned long *rtep)
+static unsigned long *dma_get_seg_table_origin(unsigned long *rtep, gfp_t gfp)
 {
unsigned long old_rte, rte;
unsigned long *sto;
@@ -72,7 +72,7 @@ static unsigned long *dma_get_seg_table_origin(unsigned long 
*rtep)
if (reg_entry_isvalid(rte)) {
sto = get_rt_sto(rte);
} else {
-   sto = dma_alloc_cpu_table();
+   sto = dma_alloc_cpu_table(gfp);
if (!sto)
return NULL;
 
@@ -90,7 +90,7 @@ static unsigned long *dma_get_seg_table_origin(unsigned long 
*rtep)
return sto;
 }
 
-static unsigned long *dma_get_page_table_origin(unsigned long *step)
+static unsigned long *dma_get_page_table_origin(unsigned long *step, gfp_t gfp)
 {
unsigned long old_ste, ste;
unsigned long *pto;
@@ -99,7 +99,7 @@ static unsigned long *dma_get_page_table_origin(unsigned long 
*step)
if (reg_entry_isvalid(ste)) {
pto = get_st_pto(ste);
} else {
-   pto = dma_alloc_page_table();
+   pto = dma_alloc_page_table(gfp);
if (!pto)
return NULL;
set_st_pto(, virt_to_phys(pto));
@@ -116,18 +116,19 @@ static unsigned long *dma_get_page_table_origin(unsigned 
long *step)
return pto;
 }
 
-unsigned long *dma_walk_cpu_trans(unsigned long *rto, dma_addr_t dma_addr)
+unsigned long *dma_walk_cpu_trans(unsigned long *rto, dma_addr_t dma_addr,
+ gfp_t gfp)
 {
unsigned long *sto, *pto;
unsigned int rtx, sx, px;
 
rtx = calc_rtx(dma_addr);
-   sto = dma_get_seg_table_origin([rtx]);
+   sto = dma_get_seg_table_origin([rtx], gfp);
if (!sto)
return NULL;
 
sx = calc_sx(dma_addr);
-   pto = dma_get_page_table_origin([sx]);
+   pto = dma_get_page_table_origin([sx], gfp);
if (!pto)
return NULL;
 
@@ -170,7 +171,8 @@ static int __dma_update_trans(struct zpci_dev *zdev, 
phys_addr_t pa,
return -EINVAL;
 
for (i = 0; i < nr_pages; i++) {
-   entry = dma_walk_cpu_trans(zdev->dma_table, dma_addr);
+   entry = dma_walk_cpu_trans(zdev->dma_table, dma_addr,
+  GFP_ATOMIC);
if (!entry) {

[PATCH v3 10/10] iommu/s390: Use GFP_KERNEL in sleepable contexts

2023-01-23 Thread Jason Gunthorpe
These contexts are sleepable, so use the proper annotation. The GFP_ATOMIC
was added mechanically in the prior patches.

Reviewed-by: Niklas Schnelle 
Reviewed-by: Matthew Rosato 
Signed-off-by: Jason Gunthorpe 
---
 arch/s390/pci/pci_dma.c| 2 +-
 drivers/iommu/s390-iommu.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c
index 2f6d05d6da4f76..2d9b01d7ca4c5c 100644
--- a/arch/s390/pci/pci_dma.c
+++ b/arch/s390/pci/pci_dma.c
@@ -579,7 +579,7 @@ int zpci_dma_init_device(struct zpci_dev *zdev)
 
spin_lock_init(>iommu_bitmap_lock);
 
-   zdev->dma_table = dma_alloc_cpu_table(GFP_ATOMIC);
+   zdev->dma_table = dma_alloc_cpu_table(GFP_KERNEL);
if (!zdev->dma_table) {
rc = -ENOMEM;
goto out;
diff --git a/drivers/iommu/s390-iommu.c b/drivers/iommu/s390-iommu.c
index 654ec4411fe36c..7dcfffed260e6b 100644
--- a/drivers/iommu/s390-iommu.c
+++ b/drivers/iommu/s390-iommu.c
@@ -52,7 +52,7 @@ static struct iommu_domain *s390_domain_alloc(unsigned 
domain_type)
if (!s390_domain)
return NULL;
 
-   s390_domain->dma_table = dma_alloc_cpu_table(GFP_ATOMIC);
+   s390_domain->dma_table = dma_alloc_cpu_table(GFP_KERNEL);
if (!s390_domain->dma_table) {
kfree(s390_domain);
return NULL;
-- 
2.39.0



[PATCH v3 01/10] iommu: Add a gfp parameter to iommu_map()

2023-01-23 Thread Jason Gunthorpe
The internal mechanisms support this, but instead of exposting the gfp to
the caller it wrappers it into iommu_map() and iommu_map_atomic()

Fix this instead of adding more variants for GFP_KERNEL_ACCOUNT.

Reviewed-by: Kevin Tian 
Signed-off-by: Jason Gunthorpe 
---
 arch/arm/mm/dma-mapping.c | 11 ++
 .../drm/nouveau/nvkm/subdev/instmem/gk20a.c   |  3 ++-
 drivers/gpu/drm/tegra/drm.c   |  2 +-
 drivers/gpu/host1x/cdma.c |  2 +-
 drivers/infiniband/hw/usnic/usnic_uiom.c  |  4 ++--
 drivers/iommu/dma-iommu.c |  2 +-
 drivers/iommu/iommu.c | 22 +--
 drivers/iommu/iommufd/pages.c |  6 +++--
 drivers/media/platform/qcom/venus/firmware.c  |  2 +-
 drivers/net/ipa/ipa_mem.c |  6 +++--
 drivers/net/wireless/ath/ath10k/snoc.c|  2 +-
 drivers/net/wireless/ath/ath11k/ahb.c |  4 ++--
 drivers/remoteproc/remoteproc_core.c  |  5 +++--
 drivers/vfio/vfio_iommu_type1.c   |  9 
 drivers/vhost/vdpa.c  |  2 +-
 include/linux/iommu.h |  4 ++--
 16 files changed, 48 insertions(+), 38 deletions(-)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index c135f6e37a00ca..8bc01071474ab7 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -984,7 +984,8 @@ __iommu_create_mapping(struct device *dev, struct page 
**pages, size_t size,
 
len = (j - i) << PAGE_SHIFT;
ret = iommu_map(mapping->domain, iova, phys, len,
-   __dma_info_to_prot(DMA_BIDIRECTIONAL, attrs));
+   __dma_info_to_prot(DMA_BIDIRECTIONAL, attrs),
+   GFP_KERNEL);
if (ret < 0)
goto fail;
iova += len;
@@ -1207,7 +1208,8 @@ static int __map_sg_chunk(struct device *dev, struct 
scatterlist *sg,
 
prot = __dma_info_to_prot(dir, attrs);
 
-   ret = iommu_map(mapping->domain, iova, phys, len, prot);
+   ret = iommu_map(mapping->domain, iova, phys, len, prot,
+   GFP_KERNEL);
if (ret < 0)
goto fail;
count += len >> PAGE_SHIFT;
@@ -1379,7 +1381,8 @@ static dma_addr_t arm_iommu_map_page(struct device *dev, 
struct page *page,
 
prot = __dma_info_to_prot(dir, attrs);
 
-   ret = iommu_map(mapping->domain, dma_addr, page_to_phys(page), len, 
prot);
+   ret = iommu_map(mapping->domain, dma_addr, page_to_phys(page), len,
+   prot, GFP_KERNEL);
if (ret < 0)
goto fail;
 
@@ -1443,7 +1446,7 @@ static dma_addr_t arm_iommu_map_resource(struct device 
*dev,
 
prot = __dma_info_to_prot(dir, attrs) | IOMMU_MMIO;
 
-   ret = iommu_map(mapping->domain, dma_addr, addr, len, prot);
+   ret = iommu_map(mapping->domain, dma_addr, addr, len, prot, GFP_KERNEL);
if (ret < 0)
goto fail;
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c 
b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
index 648ecf5a8fbc2a..a4ac94a2ab57fc 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c
@@ -475,7 +475,8 @@ gk20a_instobj_ctor_iommu(struct gk20a_instmem *imem, u32 
npages, u32 align,
u32 offset = (r->offset + i) << imem->iommu_pgshift;
 
ret = iommu_map(imem->domain, offset, node->dma_addrs[i],
-   PAGE_SIZE, IOMMU_READ | IOMMU_WRITE);
+   PAGE_SIZE, IOMMU_READ | IOMMU_WRITE,
+   GFP_KERNEL);
if (ret < 0) {
nvkm_error(subdev, "IOMMU mapping failure: %d\n", ret);
 
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 7bd2e65c2a16c5..6ca9f396e55be4 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -1057,7 +1057,7 @@ void *tegra_drm_alloc(struct tegra_drm *tegra, size_t 
size, dma_addr_t *dma)
 
*dma = iova_dma_addr(>carveout.domain, alloc);
err = iommu_map(tegra->domain, *dma, virt_to_phys(virt),
-   size, IOMMU_READ | IOMMU_WRITE);
+   size, IOMMU_READ | IOMMU_WRITE, GFP_KERNEL);
if (err < 0)
goto free_iova;
 
diff --git a/drivers/gpu/host1x/cdma.c b/drivers/gpu/host1x/cdma.c
index 103fda055394ab..4ddfcd2138c95b 100644
--- a/drivers/gpu/host1x/cdma.c
+++ b/drivers/gpu/host1x/cdma.c
@@ -105,7 +105,7 @@ static int host1x_pushbuffer_init(struct push_buffer *pb)
 
pb->dma = iova_dma_addr(>iova, alloc);
err = iommu_map(host1x->domain, pb->dma, pb->phys, size,
-   IOMMU_READ);
+   

[PATCH v3 08/10] iommu/intel: Use GFP_KERNEL in sleepable contexts

2023-01-23 Thread Jason Gunthorpe
These contexts are sleepable, so use the proper annotation. The GFP_ATOMIC
was added mechanically in the prior patches.

Reviewed-by: Lu Baolu 
Reviewed-by: Kevin Tian 
Signed-off-by: Jason Gunthorpe 
---
 drivers/iommu/intel/iommu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index e95f7703ce7b83..a1a66798e1f06c 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -2372,7 +2372,7 @@ static int iommu_domain_identity_map(struct dmar_domain 
*domain,
 
return __domain_mapping(domain, first_vpfn,
first_vpfn, last_vpfn - first_vpfn + 1,
-   DMA_PTE_READ|DMA_PTE_WRITE, GFP_ATOMIC);
+   DMA_PTE_READ|DMA_PTE_WRITE, GFP_KERNEL);
 }
 
 static int md_domain_init(struct dmar_domain *domain, int guest_width);
@@ -2680,7 +2680,7 @@ static int copy_context_table(struct intel_iommu *iommu,
if (!old_ce)
goto out;
 
-   new_ce = alloc_pgtable_page(iommu->node, GFP_ATOMIC);
+   new_ce = alloc_pgtable_page(iommu->node, GFP_KERNEL);
if (!new_ce)
goto out_unmap;
 
-- 
2.39.0



[PATCH v3 02/10] iommu: Remove iommu_map_atomic()

2023-01-23 Thread Jason Gunthorpe
There is only one call site and it can now just pass the GFP_ATOMIC to the
normal iommu_map().

Reviewed-by: Kevin Tian 
Signed-off-by: Jason Gunthorpe 
---
 drivers/iommu/dma-iommu.c | 2 +-
 drivers/iommu/iommu.c | 7 ---
 include/linux/iommu.h | 9 -
 3 files changed, 1 insertion(+), 17 deletions(-)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 8bdb65e7686ff9..7016db569f81fc 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -713,7 +713,7 @@ static dma_addr_t __iommu_dma_map(struct device *dev, 
phys_addr_t phys,
if (!iova)
return DMA_MAPPING_ERROR;
 
-   if (iommu_map_atomic(domain, iova, phys - iova_off, size, prot)) {
+   if (iommu_map(domain, iova, phys - iova_off, size, prot, GFP_ATOMIC)) {
iommu_dma_free_iova(cookie, iova, size, NULL);
return DMA_MAPPING_ERROR;
}
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 7dac062b58f039..9412b420d07257 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -2381,13 +2381,6 @@ int iommu_map(struct iommu_domain *domain, unsigned long 
iova,
 }
 EXPORT_SYMBOL_GPL(iommu_map);
 
-int iommu_map_atomic(struct iommu_domain *domain, unsigned long iova,
- phys_addr_t paddr, size_t size, int prot)
-{
-   return iommu_map(domain, iova, paddr, size, prot, GFP_ATOMIC);
-}
-EXPORT_SYMBOL_GPL(iommu_map_atomic);
-
 static size_t __iommu_unmap_pages(struct iommu_domain *domain,
  unsigned long iova, size_t size,
  struct iommu_iotlb_gather *iotlb_gather)
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index d2020994f292db..521cd79700f4d8 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -468,8 +468,6 @@ extern struct iommu_domain *iommu_get_domain_for_dev(struct 
device *dev);
 extern struct iommu_domain *iommu_get_dma_domain(struct device *dev);
 extern int iommu_map(struct iommu_domain *domain, unsigned long iova,
 phys_addr_t paddr, size_t size, int prot, gfp_t gfp);
-extern int iommu_map_atomic(struct iommu_domain *domain, unsigned long iova,
-   phys_addr_t paddr, size_t size, int prot);
 extern size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova,
  size_t size);
 extern size_t iommu_unmap_fast(struct iommu_domain *domain,
@@ -778,13 +776,6 @@ static inline int iommu_map(struct iommu_domain *domain, 
unsigned long iova,
return -ENODEV;
 }
 
-static inline int iommu_map_atomic(struct iommu_domain *domain,
-  unsigned long iova, phys_addr_t paddr,
-  size_t size, int prot)
-{
-   return -ENODEV;
-}
-
 static inline size_t iommu_unmap(struct iommu_domain *domain,
 unsigned long iova, size_t size)
 {
-- 
2.39.0



[PATCH v3 05/10] iommufd: Use GFP_KERNEL_ACCOUNT for iommu_map()

2023-01-23 Thread Jason Gunthorpe
iommufd follows the same design as KVM and uses memory cgroups to limit
the amount of kernel memory a iommufd file descriptor can pin down. The
various internal data structures already use GFP_KERNEL_ACCOUNT.

However, one of the biggest consumers of kernel memory is the IOPTEs
stored under the iommu_domain. Many drivers will allocate these at
iommu_map() time and will trivially do the right thing if we pass in
GFP_KERNEL_ACCOUNT.

Reviewed-by: Kevin Tian 
Signed-off-by: Jason Gunthorpe 
---
 drivers/iommu/iommufd/pages.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/iommufd/pages.c b/drivers/iommu/iommufd/pages.c
index 22cc3bb0c6c55a..f8d92c9bb65b60 100644
--- a/drivers/iommu/iommufd/pages.c
+++ b/drivers/iommu/iommufd/pages.c
@@ -457,7 +457,7 @@ static int batch_iommu_map_small(struct iommu_domain 
*domain,
 
while (size) {
rc = iommu_map(domain, iova, paddr, PAGE_SIZE, prot,
-  GFP_KERNEL);
+  GFP_KERNEL_ACCOUNT);
if (rc)
goto err_unmap;
iova += PAGE_SIZE;
@@ -502,7 +502,7 @@ static int batch_to_domain(struct pfn_batch *batch, struct 
iommu_domain *domain,
rc = iommu_map(domain, iova,
   PFN_PHYS(batch->pfns[cur]) + page_offset,
   next_iova - iova, area->iommu_prot,
-  GFP_KERNEL);
+  GFP_KERNEL_ACCOUNT);
if (rc)
goto err_unmap;
iova = next_iova;
-- 
2.39.0



[PATCH v3 06/10] iommu/intel: Add a gfp parameter to alloc_pgtable_page()

2023-01-23 Thread Jason Gunthorpe
This is eventually called by iommufd through intel_iommu_map_pages() and
it should not be forced to atomic. Push the GFP_ATOMIC to all callers.

Reviewed-by: Kevin Tian 
Reviewed-by: Lu Baolu 
Signed-off-by: Jason Gunthorpe 
---
 drivers/iommu/intel/iommu.c | 14 +++---
 drivers/iommu/intel/iommu.h |  2 +-
 drivers/iommu/intel/pasid.c |  2 +-
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 59df7e42fd533c..aa29561d3549b3 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -362,12 +362,12 @@ static int __init intel_iommu_setup(char *str)
 }
 __setup("intel_iommu=", intel_iommu_setup);
 
-void *alloc_pgtable_page(int node)
+void *alloc_pgtable_page(int node, gfp_t gfp)
 {
struct page *page;
void *vaddr = NULL;
 
-   page = alloc_pages_node(node, GFP_ATOMIC | __GFP_ZERO, 0);
+   page = alloc_pages_node(node, gfp | __GFP_ZERO, 0);
if (page)
vaddr = page_address(page);
return vaddr;
@@ -612,7 +612,7 @@ struct context_entry *iommu_context_addr(struct intel_iommu 
*iommu, u8 bus,
if (!alloc)
return NULL;
 
-   context = alloc_pgtable_page(iommu->node);
+   context = alloc_pgtable_page(iommu->node, GFP_ATOMIC);
if (!context)
return NULL;
 
@@ -935,7 +935,7 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain 
*domain,
if (!dma_pte_present(pte)) {
uint64_t pteval;
 
-   tmp_page = alloc_pgtable_page(domain->nid);
+   tmp_page = alloc_pgtable_page(domain->nid, GFP_ATOMIC);
 
if (!tmp_page)
return NULL;
@@ -1186,7 +1186,7 @@ static int iommu_alloc_root_entry(struct intel_iommu 
*iommu)
 {
struct root_entry *root;
 
-   root = (struct root_entry *)alloc_pgtable_page(iommu->node);
+   root = (struct root_entry *)alloc_pgtable_page(iommu->node, GFP_ATOMIC);
if (!root) {
pr_err("Allocating root entry for %s failed\n",
iommu->name);
@@ -2676,7 +2676,7 @@ static int copy_context_table(struct intel_iommu *iommu,
if (!old_ce)
goto out;
 
-   new_ce = alloc_pgtable_page(iommu->node);
+   new_ce = alloc_pgtable_page(iommu->node, GFP_ATOMIC);
if (!new_ce)
goto out_unmap;
 
@@ -4136,7 +4136,7 @@ static int md_domain_init(struct dmar_domain *domain, int 
guest_width)
domain->max_addr = 0;
 
/* always allocate the top pgd */
-   domain->pgd = alloc_pgtable_page(domain->nid);
+   domain->pgd = alloc_pgtable_page(domain->nid, GFP_ATOMIC);
if (!domain->pgd)
return -ENOMEM;
domain_flush_cache(domain, domain->pgd, PAGE_SIZE);
diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h
index 06e61e4748567a..ca9a035e0110af 100644
--- a/drivers/iommu/intel/iommu.h
+++ b/drivers/iommu/intel/iommu.h
@@ -737,7 +737,7 @@ int qi_submit_sync(struct intel_iommu *iommu, struct 
qi_desc *desc,
 
 extern int dmar_ir_support(void);
 
-void *alloc_pgtable_page(int node);
+void *alloc_pgtable_page(int node, gfp_t gfp);
 void free_pgtable_page(void *vaddr);
 void iommu_flush_write_buffer(struct intel_iommu *iommu);
 struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devfn);
diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c
index fb3c7020028d07..c5bf74e9372d62 100644
--- a/drivers/iommu/intel/pasid.c
+++ b/drivers/iommu/intel/pasid.c
@@ -200,7 +200,7 @@ static struct pasid_entry *intel_pasid_get_entry(struct 
device *dev, u32 pasid)
 retry:
entries = get_pasid_table_from_pde([dir_index]);
if (!entries) {
-   entries = alloc_pgtable_page(info->iommu->node);
+   entries = alloc_pgtable_page(info->iommu->node, GFP_ATOMIC);
if (!entries)
return NULL;
 
-- 
2.39.0



[PATCH v3 07/10] iommu/intel: Support the gfp argument to the map_pages op

2023-01-23 Thread Jason Gunthorpe
Flow it down to alloc_pgtable_page() via pfn_to_dma_pte() and
__domain_mapping().

Reviewed-by: Kevin Tian 
Reviewed-by: Lu Baolu 
Signed-off-by: Jason Gunthorpe 
---
 drivers/iommu/intel/iommu.c | 24 +++-
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index aa29561d3549b3..e95f7703ce7b83 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -908,7 +908,8 @@ void dmar_fault_dump_ptes(struct intel_iommu *iommu, u16 
source_id,
 #endif
 
 static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
- unsigned long pfn, int *target_level)
+ unsigned long pfn, int *target_level,
+ gfp_t gfp)
 {
struct dma_pte *parent, *pte;
int level = agaw_to_level(domain->agaw);
@@ -935,7 +936,7 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain 
*domain,
if (!dma_pte_present(pte)) {
uint64_t pteval;
 
-   tmp_page = alloc_pgtable_page(domain->nid, GFP_ATOMIC);
+   tmp_page = alloc_pgtable_page(domain->nid, gfp);
 
if (!tmp_page)
return NULL;
@@ -2150,7 +2151,8 @@ static void switch_to_super_page(struct dmar_domain 
*domain,
 
while (start_pfn <= end_pfn) {
if (!pte)
-   pte = pfn_to_dma_pte(domain, start_pfn, );
+   pte = pfn_to_dma_pte(domain, start_pfn, ,
+GFP_ATOMIC);
 
if (dma_pte_present(pte)) {
dma_pte_free_pagetable(domain, start_pfn,
@@ -2172,7 +2174,8 @@ static void switch_to_super_page(struct dmar_domain 
*domain,
 
 static int
 __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
-unsigned long phys_pfn, unsigned long nr_pages, int prot)
+unsigned long phys_pfn, unsigned long nr_pages, int prot,
+gfp_t gfp)
 {
struct dma_pte *first_pte = NULL, *pte = NULL;
unsigned int largepage_lvl = 0;
@@ -2202,7 +2205,8 @@ __domain_mapping(struct dmar_domain *domain, unsigned 
long iov_pfn,
largepage_lvl = hardware_largepage_caps(domain, iov_pfn,
phys_pfn, nr_pages);
 
-   pte = pfn_to_dma_pte(domain, iov_pfn, _lvl);
+   pte = pfn_to_dma_pte(domain, iov_pfn, _lvl,
+gfp);
if (!pte)
return -ENOMEM;
first_pte = pte;
@@ -2368,7 +2372,7 @@ static int iommu_domain_identity_map(struct dmar_domain 
*domain,
 
return __domain_mapping(domain, first_vpfn,
first_vpfn, last_vpfn - first_vpfn + 1,
-   DMA_PTE_READ|DMA_PTE_WRITE);
+   DMA_PTE_READ|DMA_PTE_WRITE, GFP_ATOMIC);
 }
 
 static int md_domain_init(struct dmar_domain *domain, int guest_width);
@@ -4298,7 +4302,7 @@ static int intel_iommu_map(struct iommu_domain *domain,
   the low bits of hpa would take us onto the next page */
size = aligned_nrpages(hpa, size);
return __domain_mapping(dmar_domain, iova >> VTD_PAGE_SHIFT,
-   hpa >> VTD_PAGE_SHIFT, size, prot);
+   hpa >> VTD_PAGE_SHIFT, size, prot, gfp);
 }
 
 static int intel_iommu_map_pages(struct iommu_domain *domain,
@@ -4333,7 +4337,8 @@ static size_t intel_iommu_unmap(struct iommu_domain 
*domain,
 
/* Cope with horrid API which requires us to unmap more than the
   size argument if it happens to be a large-page mapping. */
-   BUG_ON(!pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, ));
+   BUG_ON(!pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, ,
+  GFP_ATOMIC));
 
if (size < VTD_PAGE_SIZE << level_to_offset_bits(level))
size = VTD_PAGE_SIZE << level_to_offset_bits(level);
@@ -4392,7 +4397,8 @@ static phys_addr_t intel_iommu_iova_to_phys(struct 
iommu_domain *domain,
int level = 0;
u64 phys = 0;
 
-   pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, );
+   pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, ,
+GFP_ATOMIC);
if (pte && dma_pte_present(pte))
phys = dma_pte_addr(pte) +
(iova & (BIT_MASK(level_to_offset_bits(level) +
-- 
2.39.0



[PATCH v3 00/10] Let iommufd charge IOPTE allocations to the memory cgroup

2023-01-23 Thread Jason Gunthorpe
iommufd follows the same design as KVM and uses memory cgroups to limit
the amount of kernel memory a iommufd file descriptor can pin down. The
various internal data structures already use GFP_KERNEL_ACCOUNT to charge
its own memory.

However, one of the biggest consumers of kernel memory is the IOPTEs
stored under the iommu_domain and these allocations are not tracked.

This series is the first step in fixing it.

The iommu driver contract already includes a 'gfp' argument to the
map_pages op, allowing iommufd to specify GFP_KERNEL_ACCOUNT and then
having the driver allocate the IOPTE tables with that flag will capture a
significant amount of the allocations.

Update the iommu_map() API to pass in the GFP argument, and fix all call
sites. Replace iommu_map_atomic().

Audit the "enterprise" iommu drivers to make sure they do the right thing.
Intel and S390 ignore the GFP argument and always use GFP_ATOMIC. This is
problematic for iommufd anyhow, so fix it. AMD and ARM SMMUv2/3 are
already correct.

A follow up series will be needed to capture the allocations made when the
iommu_domain itself is allocated, which will complete the job.

v3:
 - Leave a GFP_ATOMIC in "Add a gfp parameter to iommu_map_sg()"
   and move the conversion to gfp argument to "Use the gfp parameter in
   __iommu_dma_alloc_noncontiguous()"
 - Mask off the zone/policy flags from gfp before doing internal
   allocations and add a comment about Robin's note that this is to keep
   the buffer and internal seperate.
v2: https://lore.kernel.org/r/0-v2-ce66f632bd0d+484-iommu_map_gfp_...@nvidia.com
 - Prohibit bad GFP flags in the iommu wrappers
 - Split out the new GFP_KERNEL usages into dedicated patches so it is
   easier to check. No code change after the full series
v1: https://lore.kernel.org/r/0-v1-6e8b3997c46d+89e-iommu_map_gfp_...@nvidia.com

Jason Gunthorpe (10):
  iommu: Add a gfp parameter to iommu_map()
  iommu: Remove iommu_map_atomic()
  iommu: Add a gfp parameter to iommu_map_sg()
  iommu/dma: Use the gfp parameter in __iommu_dma_alloc_noncontiguous()
  iommufd: Use GFP_KERNEL_ACCOUNT for iommu_map()
  iommu/intel: Add a gfp parameter to alloc_pgtable_page()
  iommu/intel: Support the gfp argument to the map_pages op
  iommu/intel: Use GFP_KERNEL in sleepable contexts
  iommu/s390: Push the gfp parameter to the kmem_cache_alloc()'s
  iommu/s390: Use GFP_KERNEL in sleepable contexts

 arch/arm/mm/dma-mapping.c | 11 ++--
 arch/s390/include/asm/pci_dma.h   |  5 +-
 arch/s390/pci/pci_dma.c   | 31 ++-
 .../drm/nouveau/nvkm/subdev/instmem/gk20a.c   |  3 +-
 drivers/gpu/drm/tegra/drm.c   |  2 +-
 drivers/gpu/host1x/cdma.c |  2 +-
 drivers/infiniband/hw/usnic/usnic_uiom.c  |  4 +-
 drivers/iommu/dma-iommu.c | 18 +--
 drivers/iommu/intel/iommu.c   | 36 +++--
 drivers/iommu/intel/iommu.h   |  2 +-
 drivers/iommu/intel/pasid.c   |  2 +-
 drivers/iommu/iommu.c | 53 +++
 drivers/iommu/iommufd/pages.c |  6 ++-
 drivers/iommu/s390-iommu.c| 15 +++---
 drivers/media/platform/qcom/venus/firmware.c  |  2 +-
 drivers/net/ipa/ipa_mem.c |  6 ++-
 drivers/net/wireless/ath/ath10k/snoc.c|  2 +-
 drivers/net/wireless/ath/ath11k/ahb.c |  4 +-
 drivers/remoteproc/remoteproc_core.c  |  5 +-
 drivers/vfio/vfio_iommu_type1.c   |  9 ++--
 drivers/vhost/vdpa.c  |  2 +-
 include/linux/iommu.h | 31 +++
 22 files changed, 126 insertions(+), 125 deletions(-)


base-commit: 5dc4c995db9eb45f6373a956eb1f69460e69e6d4
-- 
2.39.0



[PATCH v3 04/10] iommu/dma: Use the gfp parameter in __iommu_dma_alloc_noncontiguous()

2023-01-23 Thread Jason Gunthorpe
This function does an allocation of a buffer to return to the caller and
then goes on to allocate some internal memory, eg the scatterlist and
IOPTEs.

Instead of hard wiring GFP_KERNEL and a wrong GFP_ATOMIC, continue to use
the passed in gfp flags for all of the allocations. Clear the zone and
policy bits that are only relevant for the buffer allocation before
re-using them for internal allocations.

Auditing says this is never called from an atomic context, so the
GFP_ATOMIC is the incorrect flag.

Reviewed-by: Kevin Tian 
Signed-off-by: Jason Gunthorpe 
---
 drivers/iommu/dma-iommu.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 72cfa24503b8bc..c99e4bc55d8cb0 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -822,7 +822,14 @@ static struct page 
**__iommu_dma_alloc_noncontiguous(struct device *dev,
if (!iova)
goto out_free_pages;
 
-   if (sg_alloc_table_from_pages(sgt, pages, count, 0, size, GFP_KERNEL))
+   /*
+* Remove the zone/policy flags from the GFP - these are applied to the
+* __iommu_dma_alloc_pages() but are not used for the supporting
+* internal allocations that follow.
+*/
+   gfp &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM | __GFP_COMP);
+
+   if (sg_alloc_table_from_pages(sgt, pages, count, 0, size, gfp))
goto out_free_iova;
 
if (!(ioprot & IOMMU_CACHE)) {
@@ -834,7 +841,7 @@ static struct page **__iommu_dma_alloc_noncontiguous(struct 
device *dev,
}
 
ret = iommu_map_sg(domain, iova, sgt->sgl, sgt->orig_nents, ioprot,
-  GFP_ATOMIC);
+  gfp);
if (ret < 0 || ret < size)
goto out_free_sg;
 
-- 
2.39.0



Re: [PATCH v4 1/7] drm/i915: Fix request locking during error capture & debugfs dump

2023-01-23 Thread John Harrison

On 1/23/2023 09:51, Tvrtko Ursulin wrote:

On 20/01/2023 23:28, john.c.harri...@intel.com wrote:

From: John Harrison 

When GuC support was added to error capture, the locking around the
request object was broken. Fix it up.

The context based search manages the spinlocking around the search
internally. So it needs to grab the reference count internally as
well. The execlist only request based search relies on external
locking, so it needs an external reference count but within the
spinlock not outside it.

The only other caller of the context based search is the code for
dumping engine state to debugfs. That code wasn't previously getting
an explicit reference at all as it does everything while holding the
execlist specific spinlock. So, that needs updaing as well as that
spinlock doesn't help when using GuC submission. Rather than trying to
conditionally get/put depending on submission model, just change it to
always do the get/put.

In addition, intel_guc_find_hung_context() was not acquiring the
correct spinlock before searching the request list. So fix that up
too. While at it, add some extra whitespace padding for readability.


Is this part splittable into a separate patch?
I guess it could but it seems closely related to all the other locking 
fix ups in this patch.






v2: Explicitly document adding an extra blank line in some dense code
(Andy Shevchenko). Fix multiple potential null pointer derefs in case
of no request found (some spotted by Tvrtko, but there was more!).
Also fix a leaked request in case of !started and another in
__guc_reset_context now that intel_context_find_active_request is
actually reference counting the returned request.
v3: Add a _get suffix to intel_context_find_active_request now that it
grabs a reference (Daniele).

Fixes: dc0dad365c5e ("drm/i915/guc: Fix for error capture after full 
GPU reset with GuC")
Fixes: 573ba126aef3 ("drm/i915/guc: Capture error state on context 
reset")

Cc: Matthew Brost 
Cc: John Harrison 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Rodrigo Vivi 
Cc: Tvrtko Ursulin 
Cc: Daniele Ceraolo Spurio 
Cc: Andrzej Hajda 
Cc: Matthew Auld 
Cc: Matt Roper 
Cc: Umesh Nerlige Ramappa 
Cc: Michael Cheng 
Cc: Lucas De Marchi 
Cc: Tejas Upadhyay 
Cc: Andy Shevchenko 
Cc: Aravind Iddamsetty 
Cc: Alan Previn 
Cc: Bruce Chang 
Cc: intel-...@lists.freedesktop.org
Signed-off-by: John Harrison 
Reviewed-by: Daniele Ceraolo Spurio 
---
  drivers/gpu/drm/i915/gt/intel_context.c   |  4 +++-
  drivers/gpu/drm/i915/gt/intel_context.h   |  3 +--
  drivers/gpu/drm/i915/gt/intel_engine_cs.c |  6 +-
  drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 14 +-
  drivers/gpu/drm/i915/i915_gpu_error.c | 13 ++---
  5 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c

index e94365b08f1ef..4285c1c71fa12 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -528,7 +528,7 @@ struct i915_request 
*intel_context_create_request(struct intel_context *ce)

  return rq;
  }
  -struct i915_request *intel_context_find_active_request(struct 
intel_context *ce)
+struct i915_request *intel_context_find_active_request_get(struct 
intel_context *ce)


TBH I don't "dig" this name, it's a bit on the long side and feels out 
of character. I won't insist it be changed, but if get really has to 
be included in the name I would be happy with 
intel_context_get_active_request().


Personally, I see the 'find' component as meaning it is a search not 
just a dereference of an existing pointer and therefore being a useful 
part of the name. I don't think there is a simple name that encapsulates 
everything that is going on here. But I don't feel too strongly about it 
if you really think the shorter version is better.


One could add some kerneldoc... but it would be almost the only function 
in the whole of intel_context.h with such. Not sure if that is 
intentional because "obviously it should be obvious what a function is 
doing by reading the code and documentation is a waste of space that 
gets out of date and inaccurate" and we aren't meant to kerneldoc 
internal behaviour or if it's just the general lack of documentation for 
any driver code.






  {
  struct intel_context *parent = intel_context_to_parent(ce);
  struct i915_request *rq, *active = NULL;
@@ -552,6 +552,8 @@ struct i915_request 
*intel_context_find_active_request(struct intel_context *ce)

    active = rq;
  }
+    if (active)
+    active = i915_request_get_rcu(active);
  spin_unlock_irqrestore(>guc_state.lock, flags);
    return active;
diff --git a/drivers/gpu/drm/i915/gt/intel_context.h 
b/drivers/gpu/drm/i915/gt/intel_context.h

index fb62b7b8cbcda..ccc80c6607ca8 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.h
+++ b/drivers/gpu/drm/i915/gt/intel_context.h
@@ -268,8 +268,7 @@ int 

Re: [PATCH v2 1/1] Docs/subsystem-apis: Remove '[The ]Linux' prefixes from titles of listed documents

2023-01-23 Thread Bjorn Helgaas
On Sun, Jan 22, 2023 at 06:48:34PM +, SeongJae Park wrote:
> Some documents that listed on subsystem-apis have 'Linux' or 'The Linux'
> title prefixes.  It's duplicated information, and makes finding the
> document of interest with human eyes not easy.  Remove the prefixes from
> the titles.
> 
> Signed-off-by: SeongJae Park 

PCI/index.rst change is fine with me:

Acked-by: Bjorn Helgaas 

> ---
> Changes from v1
> (https://lore.kernel.org/lkml/20230114194741.115855-1...@kernel.org/)
> - Drop second patch (will post later for each subsystem)
> 
>  Documentation/PCI/index.rst| 6 +++---
>  Documentation/cpu-freq/index.rst   | 6 +++---
>  Documentation/crypto/index.rst | 6 +++---
>  Documentation/driver-api/index.rst | 6 +++---
>  Documentation/gpu/index.rst| 6 +++---
>  Documentation/hwmon/index.rst  | 6 +++---
>  Documentation/input/index.rst  | 6 +++---
>  Documentation/mm/index.rst | 6 +++---
>  Documentation/peci/index.rst   | 6 +++---
>  Documentation/scheduler/index.rst  | 6 +++---
>  Documentation/scsi/index.rst   | 6 +++---
>  Documentation/sound/index.rst  | 6 +++---
>  Documentation/virt/index.rst   | 6 +++---
>  Documentation/watchdog/index.rst   | 6 +++---
>  14 files changed, 42 insertions(+), 42 deletions(-)
> 
> diff --git a/Documentation/PCI/index.rst b/Documentation/PCI/index.rst
> index c17c87af1968..e73f84aebde3 100644
> --- a/Documentation/PCI/index.rst
> +++ b/Documentation/PCI/index.rst
> @@ -1,8 +1,8 @@
>  .. SPDX-License-Identifier: GPL-2.0
>  
> -===
> -Linux PCI Bus Subsystem
> -===
> +=
> +PCI Bus Subsystem
> +=
>  
>  .. toctree::
> :maxdepth: 2


Re: [PATCH v2 18/21] drm/amd/display: Fallback to 2020_YCBCR if the pixel encoding is not RGB

2023-01-23 Thread Sebastian Wick
A new property to control YCC and subsampling would be the more
complete path here. If we actually want to fix this in the short-term
though, we should handle the YCC and RGB Colorspace values as
equivalent, everywhere. Technically we're breaking the user space API
here so it should be documented on the KMS property and other drivers
must be adjusted accordingly as well.

On Fri, Jan 13, 2023 at 5:26 PM Harry Wentland  wrote:
>
> From: Joshua Ashton 
>
> Userspace might not aware whether we're sending RGB or YCbCr
> data to the display. If COLOR_SPACE_2020_RGB_FULLRANGE is
> requested but the output encoding is YCbCr we should
> send COLOR_SPACE_2020_YCBCR.
>
> Signed-off-by: Joshua Ashton 
> Signed-off-by: Harry Wentland 
> Cc: Pekka Paalanen 
> Cc: Sebastian Wick 
> Cc: vitaly.pros...@amd.com
> Cc: Joshua Ashton 
> Cc: dri-devel@lists.freedesktop.org
> Cc: amd-...@lists.freedesktop.org
> Reviewed-by: Harry Wentland 
> ---
>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 -
>  1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index f74b125af31f..16940ea61b59 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -5184,7 +5184,10 @@ get_output_color_space(const struct dc_crtc_timing 
> *dc_crtc_timing,
> color_space = COLOR_SPACE_ADOBERGB;
> break;
> case DRM_MODE_COLORIMETRY_BT2020_RGB:
> -   color_space = COLOR_SPACE_2020_RGB_FULLRANGE;
> +   if (dc_crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB)
> +   color_space = COLOR_SPACE_2020_RGB_FULLRANGE;
> +   else
> +   color_space = COLOR_SPACE_2020_YCBCR;
> break;
> case DRM_MODE_COLORIMETRY_BT2020_YCC:
> color_space = COLOR_SPACE_2020_YCBCR;
> --
> 2.39.0
>



[RFC PATCH] drm: Create documentation about device resets

2023-01-23 Thread André Almeida
Create a document that specifies how to deal with DRM device resets for
kernel and userspace drivers.

Signed-off-by: André Almeida 
---
 Documentation/gpu/drm-reset.rst | 51 +
 Documentation/gpu/index.rst |  1 +
 2 files changed, 52 insertions(+)
 create mode 100644 Documentation/gpu/drm-reset.rst

diff --git a/Documentation/gpu/drm-reset.rst b/Documentation/gpu/drm-reset.rst
new file mode 100644
index ..0dd11a469cf9
--- /dev/null
+++ b/Documentation/gpu/drm-reset.rst
@@ -0,0 +1,51 @@
+
+DRM Device Reset
+
+
+The GPU stack is really complex and is prone to errors, from hardware bugs,
+faulty applications and everything in the many layers in between. To recover
+from this kind of state, sometimes is needed to reset the GPU. Unproper 
handling
+of GPU resets can lead to an unstable userspace. This page describes what's the
+expected behaviour from DRM drivers to do in those situations, from usermode
+drivers and compositors as well.
+
+Robustness
+--
+
+First of all, application robust APIs, when available, should be used. This
+allows the application to correctly recover and continue to run after a reset.
+Apps that doesn't use this should be promptly killed when the kernel driver
+detects that it's in broken state. Specifically guidelines for some APIs:
+
+- OpenGL: During a reset, KMD kill processes that haven't ARB Robustness
+  enabled, assuming they can't recover.
+- Vulkan: Assumes that every app is able to deal with ``VK_ERROR_DEVICE_LOST``,
+  so KMD doesn't kill any. If it doesn't do it right, it's considered a broken
+  application and UMD will deal with it.
+
+Kernel mode driver
+--
+
+The KMD should be able to detect that something is wrong with the application
+and that a reset is needed to take place to recover the device (e.g. an endless
+wait). It needs to properly track the context that is broken and mark it as
+dead, so any other syscalls to that context should be further rejected. The
+other contexts should be preserved when possible, avoid crashing the rest of
+userspace. KMD can ban a file descriptor that keeps causing resets, as it's
+likely in a broken loop.
+
+User mode driver
+
+
+During a reset, UMD should be aware that rejected syscalls indicates that the
+context is broken and for robust apps the recovery should happen for the
+context. Non-robust apps would be already terminated by KMD. If no new context
+is created for some time, it is assumed that the recovery didn't work, so UMD
+should terminate it.
+
+Compositors
+---
+
+(In the long term) compositors should be robust as well to properly deal with 
it
+errors. Init systems should be aware of the compositor status and reset it if 
is
+broken.
diff --git a/Documentation/gpu/index.rst b/Documentation/gpu/index.rst
index b99dede9a5b1..300b2529bd39 100644
--- a/Documentation/gpu/index.rst
+++ b/Documentation/gpu/index.rst
@@ -9,6 +9,7 @@ Linux GPU Driver Developer's Guide
drm-mm
drm-kms
drm-kms-helpers
+   drm-reset
drm-uapi
drm-usage-stats
driver-uapi
-- 
2.39.1



  1   2   3   4   >