Re: [PATCH] dt-bindings: vendor-prefixes: add Densitron

2022-07-20 Thread Laurent Pinchart
Hi Marek,

Thank you for the patch.

On Thu, Jul 21, 2022 at 05:03:27AM +0200, Marek Vasut wrote:
> Densitron is a manufacturer of LCD panels.
> https://www.densitron.com
> 
> Signed-off-by: Marek Vasut 
> Cc: Guido Günther 
> Cc: Jagan Teki 
> Cc: Laurent Pinchart 
> Cc: Linus Walleij 
> Cc: Rob Herring 
> Cc: Sam Ravnborg 
> Cc: Thierry Reding 
> ---
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml 
> b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> index 88859dd4040ee..6277240536b44 100644
> --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
> +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> @@ -312,6 +312,8 @@ patternProperties:
>  description: Dell Inc.
>"^delta,.*":
>  description: Delta Electronics, Inc.
> +  "^densitron,.*":

How about "dsn", to follow the practice of using stock names as vendor
prefixes ?

> +description: Densitron Technologies Ltd
>"^denx,.*":
>  description: Denx Software Engineering
>"^devantech,.*":

-- 
Regards,

Laurent Pinchart


Re: [PATCH v2] drm/bridge: it6505: Add i2c api power on check

2022-07-20 Thread Pin-yen Lin
Hi Robert,

The same patch has been reviewed and applied as
86088f88a25c76baac304b6f887e5da2c30c4e07 in "drm/bridge: it6505: Fixes
bugs" series.

We accidentally sent this out as an individual patch and forgot to
revoke this after sending out the complete series.

Sorry about that.

Regards,
Pin-yen

On Tue, Jul 19, 2022 at 11:26 PM Robert Foss  wrote:
>
> On Wed, 13 Jul 2022 at 05:16, allen  wrote:
> >
> > From: allen chen 
> >
> > Use i2c bus to read/write when it6505 power off will occur i2c error.
> > Add this check will prevent i2c error when it6505 power off.
> >
> > Signed-off-by: Pin-Yen Lin 
> > Signed-off-by: Allen Chen 
> > Reviewed-by: Robert Foss 
> > ---
> >  drivers/gpu/drm/bridge/ite-it6505.c | 12 ++--
> >  1 file changed, 10 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/bridge/ite-it6505.c 
> > b/drivers/gpu/drm/bridge/ite-it6505.c
> > index aa5e0aa1af85..cfd2c3275dc5 100644
> > --- a/drivers/gpu/drm/bridge/ite-it6505.c
> > +++ b/drivers/gpu/drm/bridge/ite-it6505.c
> > @@ -518,6 +518,9 @@ static int it6505_read(struct it6505 *it6505, unsigned 
> > int reg_addr)
> > int err;
> > struct device *dev = >client->dev;
> >
> > +   if (!it6505->powered)
> > +   return -ENODEV;
> > +
> > err = regmap_read(it6505->regmap, reg_addr, );
> > if (err < 0) {
> > dev_err(dev, "read failed reg[0x%x] err: %d", reg_addr, 
> > err);
> > @@ -533,6 +536,9 @@ static int it6505_write(struct it6505 *it6505, unsigned 
> > int reg_addr,
> > int err;
> > struct device *dev = >client->dev;
> >
> > +   if (!it6505->powered)
> > +   return -ENODEV;
> > +
> > err = regmap_write(it6505->regmap, reg_addr, reg_val);
> >
> > if (err < 0) {
> > @@ -550,6 +556,9 @@ static int it6505_set_bits(struct it6505 *it6505, 
> > unsigned int reg,
> > int err;
> > struct device *dev = >client->dev;
> >
> > +   if (!it6505->powered)
> > +   return -ENODEV;
> > +
> > err = regmap_update_bits(it6505->regmap, reg, mask, value);
> > if (err < 0) {
> > dev_err(dev, "write reg[0x%x] = 0x%x mask = 0x%x failed err 
> > %d",
> > @@ -2553,13 +2562,12 @@ static int it6505_poweron(struct it6505 *it6505)
> > usleep_range(1, 2);
> > }
> >
> > +   it6505->powered = true;
> > it6505_reset_logic(it6505);
> > it6505_int_mask_enable(it6505);
> > it6505_init(it6505);
> > it6505_lane_off(it6505);
> >
> > -   it6505->powered = true;
> > -
> > return 0;
> >  }
> >
> > --
> > 2.25.1
> >
>
> This patch no longer applies to the drm-misc-next tree, could you
> rebase it and send out a v3?


[PATCH] dt-bindings: vendor-prefixes: add Densitron

2022-07-20 Thread Marek Vasut
Densitron is a manufacturer of LCD panels.
https://www.densitron.com

Signed-off-by: Marek Vasut 
Cc: Guido Günther 
Cc: Jagan Teki 
Cc: Laurent Pinchart 
Cc: Linus Walleij 
Cc: Rob Herring 
Cc: Sam Ravnborg 
Cc: Thierry Reding 
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml 
b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 88859dd4040ee..6277240536b44 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -312,6 +312,8 @@ patternProperties:
 description: Dell Inc.
   "^delta,.*":
 description: Delta Electronics, Inc.
+  "^densitron,.*":
+description: Densitron Technologies Ltd
   "^denx,.*":
 description: Denx Software Engineering
   "^devantech,.*":
-- 
2.35.1



[PATCH] mm/gup.c: Fix formating in check_and_migrate_movable_page()

2022-07-20 Thread Alistair Popple
Commit b05a79d4377f ("mm/gup: migrate device coherent pages when pinning
instead of failing") added a badly formatted if statement. Fix it.

Signed-off-by: Alistair Popple 
Reported-by: David Hildenbrand 
---

Apologies Andrew for missing this. Hopefully this fixes things.

 mm/gup.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/mm/gup.c b/mm/gup.c
index 364b274a10c2..c6d060dee9e0 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -1980,8 +1980,8 @@ static long check_and_migrate_movable_pages(unsigned long 
nr_pages,
folio_nr_pages(folio));
}
 
-   if (!list_empty(_page_list) || isolation_error_count
-   || coherent_pages)
+   if (!list_empty(_page_list) || isolation_error_count ||
+   coherent_pages)
goto unpin_pages;
 
/*
-- 
2.35.1



[PATCH] mm/gup.c: Fix formating in check_and_migrate_movable_page()

2022-07-20 Thread Alistair Popple
Commit b05a79d4377f ("mm/gup: migrate device coherent pages when pinning
instead of failing") added a badly formatted if statement. Fix it.

Signed-off-by: Alistair Popple 
Reported-by: David Hildenbrand 
---

Apologies Andrew for missing this. Hopefully this fixes things.

 mm/gup.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/mm/gup.c b/mm/gup.c
index 364b274a10c2..c6d060dee9e0 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -1980,8 +1980,8 @@ static long check_and_migrate_movable_pages(unsigned long 
nr_pages,
folio_nr_pages(folio));
}
 
-   if (!list_empty(_page_list) || isolation_error_count
-   || coherent_pages)
+   if (!list_empty(_page_list) || isolation_error_count ||
+   coherent_pages)
goto unpin_pages;
 
/*
-- 
2.35.1



Re: [Intel-gfx] [PATCH 01/12] drm/i915: Remove bogus GEM_BUG_ON in unpark

2022-07-20 Thread John Harrison




On 7/19/2022 02:42, Tvrtko Ursulin wrote:


On 19/07/2022 01:05, John Harrison wrote:

On 7/18/2022 05:15, Tvrtko Ursulin wrote:


On 13/07/2022 00:31, john.c.harri...@intel.com wrote:

From: Matthew Brost 

Remove bogus GEM_BUG_ON which compared kernel context timeline 
seqno to
seqno in memory on engine PM unpark. If a GT reset occurred these 
values

might not match as a kernel context could be skipped. This bug was
hidden by always switching to a kernel context on park (execlists
requirement).


Reset of the kernel context? Under which circumstances does that 
happen?

As per description, the issue is with full GT reset.



It is unclear if the claim is this to be a general problem or the 
assert is only invalid with the GuC. Lack of a CI reported issue 
suggests it is not a generic problem?
Currently it is not an issue because we always switch to the kernel 
context because that's how execlists works and the entire driver is 
fundamentally based on execlist operation. When we stop using the 
kernel context as a (non-functional) barrier when using GuC 
submission, then you would see an issue without this fix.


Issue is with GuC, GuC and full reset, or with full reset regardless 
of the backend?
The issue is with code making invalid assumptions. The assumption is 
currently not failing because the execlist backend requires the use of a 
barrier context for a bunch of operations. The GuC backend does not 
require this. In fact, the barrier context does not function as a 
barrier when the scheduler is external to i915. Hence the desire to 
remove the use of the barrier context from generic i915 operation and 
make it only used when in execlist mode. At that point, the invalid 
assumption will no longer work and the BUG will fire.




If issue is only with GuC patch should have drm/i915/guc prefix as 
minimum. But if it actually only becomes a problem when GuC backend 
stops parking with the kernel context when I think the whole unpark 
code should be refactored in a cleaner way than just removing the one 
assert. Otherwise what is the point of leaving everything else in there?


Or if the issue is backend agnostic, *if* full reset happens to hit 
during parking, then it is different. Wouldn't that be a race with 
parking and reset which probably shouldn't happen to start with.


The issue is neither with GuC nor with resets, GT or otherwise. The 
issue is with generic i915 code making assumptions about backend 
implementations that are only correct for the execlist implementation.


John.



Regards,

Tvrtko



John.




Regards,

Tvrtko


Signed-off-by: Matthew Brost 
---
  drivers/gpu/drm/i915/gt/intel_engine_pm.c | 2 --
  1 file changed, 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_pm.c 
b/drivers/gpu/drm/i915/gt/intel_engine_pm.c

index b0a4a2dbe3ee9..fb3e1599d04ec 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_pm.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_pm.c
@@ -68,8 +68,6 @@ static int __engine_unpark(struct intel_wakeref *wf)
   ce->timeline->seqno,
   READ_ONCE(*ce->timeline->hwsp_seqno),
   ce->ring->emit);
-    GEM_BUG_ON(ce->timeline->seqno !=
-   READ_ONCE(*ce->timeline->hwsp_seqno));
  }
    if (engine->unpark)






Re: [PATCH 2/8] dt-bindings: display: ti,am65x-dss: Add IO CTRL property for AM625 OLDI

2022-07-20 Thread Rob Herring
On Tue, Jul 19, 2022 at 01:38:39PM +0530, Aradhya Bhatia wrote:
> Add am625-io-ctrl dt property to provide access to the control MMR
> registers for the OLDI TXes.
> 
> These registers are used to control the power input to the OLDI TXes as
> well as to configure them in the Loopback test mode.
> 
> The MMR IO controller device has been updated since the AM65x SoC and
> hence a newer property is needed to describe the one in AM625 SoC.
> 
> Signed-off-by: Aradhya Bhatia 
> ---
>  .../bindings/display/ti/ti,am65x-dss.yaml | 21 +++
>  1 file changed, 21 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml 
> b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
> index 11d9b3821409..672765ad1f30 100644
> --- a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
> +++ b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
> @@ -118,12 +118,33 @@ properties:
>and OLDI_CLK_IO_CTRL registers. This property is needed for OLDI
>interface to work.
>  
> +  ti,am625-oldi-io-ctrl:
> +$ref: "/schemas/types.yaml#/definitions/phandle"
> +description:
> +  phandle to syscon device node mapping OLDI IO_CTRL registers, for
> +  AM625 SoC. The mapped range should point to OLDI0_DAT0_IO_CTRL,
> +  and map the registers up till OLDI_LB_CTRL. This property allows
> +  the driver to control the power delivery to the OLDI TXes and
> +  their loopback control as well.

What's wrong with the existing ti,am65x-oldi-io-ctrl other than the less 
than ideal naming? And you just continued with the same issue so the 
next part will need yet another property. Sorry, no. Just use the 
existing property.

> +
>max-memory-bandwidth:
>  $ref: /schemas/types.yaml#/definitions/uint32
>  description:
>Input memory (from main memory to dispc) bandwidth limit in
>bytes per second
>  
> +if:
> +  properties:
> +compatible:
> +  contains:
> +const: ti,am65x-dss
> +then:
> +  properties:
> +ti,am625-oldi-io-ctrl: false
> +else:
> +  properties:
> +ti,am65x-oldi-io-ctrl: false
> +
>  required:
>- compatible
>- reg
> -- 
> 2.37.0
> 
> 


Re: [PATCH 1/8] dt-bindings: display: ti,am65x-dss: Add port properties for DSS

2022-07-20 Thread Rob Herring
On Tue, Jul 19, 2022 at 01:38:38PM +0530, Aradhya Bhatia wrote:
> Add "ti,oldi-mode" property to indicate the tidss driver the OLDI output
> mode. The 2 OLDI TXes on am625-dss allow a 3 different types of panel
> connections with the board.
> 
> 1. Single Link / Single Mode on OLDI TX 0 OR 1.
> 2. Single Link / Duplicate Mode on OLDI TX 0 and 1.
> 3. Dual Link / Single Mode on OLDI TX 0 and 1.
> 
> Add "ti,rgb565-to-888" property to override 16bit output from a videoport
> for a bridge that only accepts 24bit RGB888 DPI input.
> 
> On some boards the HDMI bridge takes a 24bit DPI input, but only 16 data
> pins are actually enabled from the SoC.  This new property forces the
> output to be RGB565 on a specific video port if the bridge requests a
> 24bit RGB color space.
> 
> This assumes that the video port is connected like so:
> 
> SoC : Bridge
> R0 ->   R3
> R1 ->   R4
> R2 ->   R5
> R3 ->   R6
> R4 ->   R7
> G0 ->   G2
> G1 ->   G3
> G2 ->   G4
> G3 ->   G5
> G4 ->   G6
> G5 ->   G7
> B0 ->   B3
> B1 ->   B4
> B2 ->   B5
> B3 ->   B6
> B4 ->   B7
> 
> On the bridge side R0->R2, G0->G1, B0->B2 would be tied to ground.
> The bridge sees 24bits of data,  but the lsb's are always zero.

Unless the bridge ignores the LSBs, that's not the right way to do 16 to 
24 bit. The LSBs should be connected to the MSB of the color component 
to get full color range.

> 
> Signed-off-by: Aradhya Bhatia 
> ---
>  .../bindings/display/ti/ti,am65x-dss.yaml | 25 +--
>  1 file changed, 23 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml 
> b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
> index 6bbce921479d..11d9b3821409 100644
> --- a/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
> +++ b/Documentation/devicetree/bindings/display/ti/ti,am65x-dss.yaml
> @@ -80,15 +80,35 @@ properties:
>  
>  properties:
>port@0:
> -$ref: /schemas/graph.yaml#/properties/port
> +$ref: /schemas/graph.yaml#/$defs/port-base
> +unevaluatedProperties: false
>  description:
>The DSS OLDI output port node form video port 1
>  
> +properties:
> +  ti,oldi-mode:
> +description: TI specific property to indicate the mode the OLDI 
> TXes
> +  and the display panel are connected in.
> +  0 -> OLDI TXes OFF (driver default for am625-dss)
> +  1 -> Single link, Single Mode (OLDI0) (driver default for 
> am65x-dss)
> +  2 -> Single link, Single Mode (OLDI1)
> +  3 -> Single link, Duplicate Mode
> +  4 -> Dual link (Only Single Mode)
> +$ref: /schemas/types.yaml#/definitions/uint32
> +enum: [0, 1, 2, 3, 4]

Wouldn't 'data-lanes' property work for this purpose.

Generally, we don't put properties in port nodes.

> +
>port@1:
> -$ref: /schemas/graph.yaml#/properties/port
> +$ref: /schemas/graph.yaml#/$defs/port-base
> +unevaluatedProperties: false
>  description:
>The DSS DPI output port node from video port 2
>  
> +properties:
> +  ti,rgb565-to-888:
> +description:
> +  property to override DPI output to 16bit for 24bit bridge
> +type: boolean

There's work underway for standard way to handle interface formats[1]. 
Please help/comment on that to make sure it works for you. 

Rob

[1] https://lore.kernel.org/all/20220628181838.2031-3-max.oss...@gmail.com/


[PATCH] drm/panel-edp: Fix typo in kerneldoc comment (appers=>appears)

2022-07-20 Thread Douglas Anderson
Ever since I got the spell-check working in my editor this one has
been bugging me. Fix it.

Signed-off-by: Douglas Anderson 
---

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

diff --git a/drivers/gpu/drm/panel/panel-edp.c 
b/drivers/gpu/drm/panel/panel-edp.c
index e6645d6e9b59..07a383dff548 100644
--- a/drivers/gpu/drm/panel/panel-edp.c
+++ b/drivers/gpu/drm/panel/panel-edp.c
@@ -53,7 +53,7 @@ struct panel_delay {
 * before the HPD signal is reliable. Ideally this is 0 but some panels,
 * board designs, or bad pulldown configs can cause a glitch here.
 *
-* NOTE: on some old panel data this number appers to be much too big.
+* NOTE: on some old panel data this number appears to be much too big.
 * Presumably some old panels simply didn't have HPD hooked up and put
 * the hpd_absent here because this field predates the
 * hpd_absent. While that works, it's non-ideal.
-- 
2.37.0.170.g444d1eabd0-goog



Re: [PATCH v4 1/2] vfio: Replace the DMA unmapping notifier with a callback

2022-07-20 Thread Alex Williamson
On Wed, 20 Jul 2022 17:08:29 -0300
Jason Gunthorpe  wrote:

> On Wed, Jul 20, 2022 at 01:41:13PM -0600, Alex Williamson wrote:
>  
> > ie. we don't need the gfn, we only need the iova.  
> 
> Right, that makes sense
>  
> > However then I start to wonder why we're passing in 1 for the number of
> > pages because this previously notifier, now callback is called for the
> > entire vfio_dma range when we find any pinned pages.
> 
> Well, it is doing this because it only ever pins one page.

Of course that page is not necessarily the page it unpins given the
contract misunderstanding below.
 
> The drivers are confused about what the contract is. vfio is calling
> the notifier with the entire IOVA range that is being unmapped and the
> drivers are expecting to receive notifications only for the IOVA they
> have actually pinned.
> 
> > Should ap and ccw implementations of .dma_unmap just be replaced with a
> > BUG_ON(1)?  
> 
> The point of these callbacks is to halt concurrent DMA, and ccw does
> that today.

ccw essentially only checks whether the starting iova of the unmap is
currently mapped.  If not it does nothing, if it is it tries to reset
the device and unpin everything.  Chances are the first iova is not the
one pinned, so we don't end up removing the pinned page and type1 will
eventually BUG_ON after a few tries.

> It looks like AP is missing a call to ap_aqic(), so it is
> probably double wrong.

Thankfully the type1 unpinning path can't be tricked into unpinning
something that wasn't pinned, so chances are the unpin call does
nothing, with a small risk that it unpins another driver's pinned page,
which might not yet have been notified and could still be using the
page.  In the end, if ap did have a page pinned in the range, we'll hit
the same BUG_ON as above.

> What I'd suggest is adding a WARN_ON that the dma->pfn_list is not
> empty and leave these functions alone.

The BUG_ON still exists in type1.

Eric, Matt, Tony, Halil, JasonH, any quick fixes here?  ccw looks like
it would be pretty straightforward to test against a range rather than
a single iova.
 
> Most likely AP should be fixed to call vfio_ap_irq_disable() and to
> check the q->saved_pfn against the IOVA.

Right, the q->saved_iova, perhaps calling vfio_ap_irq_disable() on
finding a matching queue.

> But I'm inclined to leave this as-is for this series given we are at
> rc7.

On the grounds that it's no worse, maybe, but given the changes
around this code hopefully we can submit fixes patches to stable if the
backport isn't obvious and the BUG_ON in type1 is reachable.  Thanks,

Alex



Re: [PATCH 4/4] Documentation/gpu/amdgpu/amdgpu_dm: add DM docs for pixel blend mode

2022-07-20 Thread Melissa Wen
On 07/17, Tales Lelo da Aparecida wrote:
> On 16/07/2022 19:25, Melissa Wen wrote:
> > AMD GPU display manager (DM) maps DRM pixel blend modes (None,
> > Pre-multiplied, Coverage) to MPC hw blocks through blend configuration
> > options. Describe relevant elements and how to set and test them to get
> > the expected DRM blend mode on DCN hw.
> > 
> > Signed-off-by: Melissa Wen 
> > ---
> >   .../gpu/amdgpu/display/display-manager.rst| 98 +++
> >   Documentation/gpu/drm-kms.rst |  2 +
> >   2 files changed, 100 insertions(+)
> > 
> > diff --git a/Documentation/gpu/amdgpu/display/display-manager.rst 
> > b/Documentation/gpu/amdgpu/display/display-manager.rst
> > index 8960a5f1fa66..7a495ed1f69e 100644
> > --- a/Documentation/gpu/amdgpu/display/display-manager.rst
> > +++ b/Documentation/gpu/amdgpu/display/display-manager.rst
> > @@ -84,3 +84,101 @@ families below.
> >   **DCN 3.0 family color caps and mapping**
> >   .. kernel-figure:: dcn3_cm_drm_current.svg
> > +
> > +Blend Mode Properties
> > +=
> > +
> > +Pixel blend mode is a DRM plane composition property of 
> > :c:type:`drm_plane` used to
> > +describes how pixels from a foreground plane (fg) are composited with the
> > +background plane (bg). Here, we present main concepts of DRM blend mode to 
> > help
> > +to understand how this property is mapped to AMD DC interface. See more 
> > about
> > +this DRM property and the alpha blending equations in :ref:`DRM Plane
> > +Composition Properties `.
> > +
> > +Basically, a blend mode sets the alpha blending equation for plane
> > +composition that fits the mode in which the alpha channel affects the 
> > state of
> > +pixel color values and, therefore, the resulted pixel color. For
> > +example, consider the following elements of the alpha blending equation:
> > +
> > +- *fg.rgb*: Each of the RGB component values from the foreground's pixel.
> > +- *fg.alpha*: Alpha component value from the foreground's pixel.
> > +- *bg.rgb*: Each of the RGB component values from the background.
> > +- *plane_alpha*: Plane alpha value set by the **plane "alpha" property**, 
> > see
> > +  more in `DRM Plane Composition Properties 
> > `.
> 
> You forgot to use :ref: in here.
> 
> > +
> > +in the basic alpha blending equation::
> > +
> > +   out.rgb = alpha * fg.rgb + (1 - alpha) * bg.rgb
> > +
> > +the alpha channel value of each pixel in a plane is ignored and only the 
> > plane
> > +alpha affects the resulted pixel color values.
> > +
> > +DRM has three blend mode to define the blend formula in the plane 
> > composition:
> > +
> > +* **None**: Blend formula that ignores the pixel alpha.
> > +
> > +* **Pre-multiplied**: Blend formula that assumes the pixel color values in 
> > a
> > +  plane was already pre-multiplied by its own alpha channel before storage.
> > +
> > +* **Coverage**: Blend formula that assumes the pixel color values were not
> > +  pre-multiplied with the alpha channel values.
> > +
> > +and pre-multiplied is the default pixel blend mode, that means, when no 
> > blend
> > +mode property is created or defined, DRM considers the plane's pixels has
> > +pre-multiplied color values. On IGT GPU tools, the kms_plane_alpha_blend 
> > test
> > +provides a set of subtests to verify plane alpha and blend mode properties.
> > +
> > +The DRM blend mode and its elements are then mapped by AMDGPU display 
> > manager
> > +(DM) to program the blending configuration of the Multiple Pipe/Plane 
> > Combined
> > +(MPC), as follows:
> > +
> > +.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
> > +   :doc: mpc-overview
> > +
> > +.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
> > +   :functions: mpcc_blnd_cfg
> > +
> > +Therefore, the blending configuration for a single MPCC instance on the MPC
> > +tree is defined by :c:type:`mpcc_blnd_cfg`, where
> > +:c:type:`pre_multiplied_alpha` is the alpha pre-multiplied mode flag used 
> > to
> > +set :c:type:`MPCC_ALPHA_MULTIPLIED_MODE`. It controls whether alpha is
> > +multiplied (true/false), being only true for DRM pre-multiplied blend mode.
> > +:c:type:`mpcc_alpha_blend_mode` defines the alpha blend mode regarding 
> > pixel
> > +alpha and plane alpha values. It sets one of the three modes for
> > +:c:type:`MPCC_ALPHA_BLND_MODE`, as described below.
> > +
> > +.. kernel-doc:: drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
> > +   :functions: mpcc_alpha_blend_mode
> > +
> > +DM then maps the elements of `enum mpcc_alpha_blend_mode` to those in the 
> > DRM
> > +blend formula, as follows:
> > +
> > +* *MPC pixel alpha* matches *DRM fg.alpha* as the alpha component value
> > +  from the plane's pixel
> > +* *MPC global alpha* matches *DRM plane_alpha* when the pixel alpha should
> > +  be ignored and, therefore, pixel values are not pre-multiplied
> > +* *MPC global gain* assumes *MPC global alpha* value when both *DRM
> > +  fg.alpha* and *DRM plane_alpha* participate in the blend equation
> > +

[RFC PATCH 2/2] drm/panel: atna33xc20: Allow overriding the eDP EDID

2022-07-20 Thread Douglas Anderson
The atna33xc20 has the same problem as panel-edp where it was caching
the EDID. Let's copy the fix over. See the patch ("drm/panel-edp:
Allow overriding the eDP EDID")

NOTE: the question will of course be asked why we've got a copy of
this code. panel-samsung-atna33xc20 was purposely _copied_ from the
generic eDP panel code in response to worries that the generic code
was becoming a tangled mess (described as panel-panacea).

It should also be noted that at some point I attempted to move the
EDID caching into the core [1] but was told not to.

[1] 
https://lore.kernel.org/all/20210329195255.v2.9.Ia7e9bb7cf6c51d960b9455fb0fa447cc68ece99d@changeid/

Signed-off-by: Douglas Anderson 
---

 .../gpu/drm/panel/panel-samsung-atna33xc20.c| 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c 
b/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c
index 5a8b978c6415..2ae62cd7c416 100644
--- a/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c
+++ b/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* T3 VCC to HPD high is max 200 ms */
 #define HPD_MAX_MS 200
@@ -36,8 +37,6 @@ struct atana33xc20_panel {
struct gpio_desc *el_on3_gpio;
struct drm_dp_aux *aux;
 
-   struct edid *edid;
-
ktime_t powered_off_time;
ktime_t powered_on_time;
ktime_t el_on3_off_time;
@@ -241,15 +240,19 @@ static int atana33xc20_prepare(struct drm_panel *panel)
 static int atana33xc20_get_modes(struct drm_panel *panel,
 struct drm_connector *connector)
 {
-   struct atana33xc20_panel *p = to_atana33xc20(panel);
struct dp_aux_ep_device *aux_ep = to_dp_aux_ep_dev(panel->dev);
int num = 0;
 
pm_runtime_get_sync(panel->dev);
 
-   if (!p->edid)
-   p->edid = drm_get_edid(connector, _ep->aux->ddc);
-   num = drm_add_edid_modes(connector, p->edid);
+   /*
+* We read the EDID and then immediately free it, relying on the side
+* effect of drm_get_edid() to store a copy in connector->edid_blob_ptr.
+* We always use the copy cached in the connector since that allows the
+* edid_override to work.
+*/
+   kfree(drm_get_edid(connector, _ep->aux->ddc));
+   num = drm_add_edid_modes(connector, connector->edid_blob_ptr->data);
 
pm_runtime_mark_last_busy(panel->dev);
pm_runtime_put_autosuspend(panel->dev);
@@ -339,8 +342,6 @@ static void atana33xc20_remove(struct dp_aux_ep_device 
*aux_ep)
drm_panel_remove(>base);
drm_panel_disable(>base);
drm_panel_unprepare(>base);
-
-   kfree(panel->edid);
 }
 
 static void atana33xc20_shutdown(struct dp_aux_ep_device *aux_ep)
-- 
2.37.0.170.g444d1eabd0-goog



[RFC PATCH 1/2] drm/panel-edp: Allow overriding the eDP EDID

2022-07-20 Thread Douglas Anderson
I found that writing to `/sys/kernel/debug/dri/*/eDP*/edid_override`
wasn't working for me. I could see the new EDID take effect in
`/sys/class/drm/card*-eDP*/edid` but userspace wasn't seeing it..

The problem was that panel-edp was caching the EDID that it read and
using that over and over again.

Let's change panel-edp to look at the EDID that's stored in the
connector. This is still a cache, which is important since this
function is called multiple times and readin the EDID is slow, but
this property is automatically updated by drm_get_edid() (which reads
the EDID) and also updated when writing the edid_override in debugfs.

Fixes: 63358e24ee79 ("drm/panel: panel-simple: Cache the EDID as long as we 
retain power")
Signed-off-by: Douglas Anderson 
---

 drivers/gpu/drm/panel/panel-edp.c | 21 -
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-edp.c 
b/drivers/gpu/drm/panel/panel-edp.c
index 3626469c4cc2..12241c1e32f7 100644
--- a/drivers/gpu/drm/panel/panel-edp.c
+++ b/drivers/gpu/drm/panel/panel-edp.c
@@ -226,8 +226,6 @@ struct panel_edp {
 
const struct edp_panel_entry *detected_panel;
 
-   struct edid *edid;
-
struct drm_display_mode override_mode;
 
enum drm_panel_orientation orientation;
@@ -580,11 +578,19 @@ static int panel_edp_get_modes(struct drm_panel *panel,
if (p->ddc) {
pm_runtime_get_sync(panel->dev);
 
-   if (!p->edid)
-   p->edid = drm_get_edid(connector, p->ddc);
+   if (!connector->edid_blob_ptr) {
+   /*
+* We read the EDID and then immediately free it,
+* relying on the side effect of drm_get_edid() to store
+* a copy in connector->edid_blob_ptr. We always use
+* the copy cached in the connector since that allows
+* the edid_override to work.
+*/
+   kfree(drm_get_edid(connector, p->ddc));
+   }
 
-   if (p->edid)
-   num += drm_add_edid_modes(connector, p->edid);
+   if (connector->edid_blob_ptr)
+   num += drm_add_edid_modes(connector, 
connector->edid_blob_ptr->data);
 
pm_runtime_mark_last_busy(panel->dev);
pm_runtime_put_autosuspend(panel->dev);
@@ -926,9 +932,6 @@ static int panel_edp_remove(struct device *dev)
if (panel->ddc && (!panel->aux || panel->ddc != >aux->ddc))
put_device(>ddc->dev);
 
-   kfree(panel->edid);
-   panel->edid = NULL;
-
return 0;
 }
 
-- 
2.37.0.170.g444d1eabd0-goog



Re: [PATCH 1/4] Documentation/amdgpu_dm: Add DM color correction documentation

2022-07-20 Thread Melissa Wen
On 07/17, Tales Lelo da Aparecida wrote:
> On 16/07/2022 19:25, Melissa Wen wrote:
> > AMDGPU DM maps DRM color management properties (degamma, ctm and gamma)
> > to DC color correction entities. Part of this mapping is already
> > documented as code comments and can be converted as kernel docs.
> > 
> > v2:
> > - rebase to amd-staging-drm-next
> > 
> > Reviewed-by: Harry Wentland 
> > Signed-off-by: Melissa Wen 
> > ---
> >   .../gpu/amdgpu/display/display-manager.rst|   9 ++
> >   .../amd/display/amdgpu_dm/amdgpu_dm_color.c   | 121 +-
> >   2 files changed, 98 insertions(+), 32 deletions(-)
> > 
> > diff --git a/Documentation/gpu/amdgpu/display/display-manager.rst 
> > b/Documentation/gpu/amdgpu/display/display-manager.rst
> > index 7ce31f89d9a0..b1b0f11aed83 100644
> > --- a/Documentation/gpu/amdgpu/display/display-manager.rst
> > +++ b/Documentation/gpu/amdgpu/display/display-manager.rst
> > @@ -40,3 +40,12 @@ Atomic Implementation
> >   .. kernel-doc:: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> >  :functions: amdgpu_dm_atomic_check amdgpu_dm_atomic_commit_tail
> > +
> > +Color Management Properties
> > +===
> > +
> > +.. kernel-doc:: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
> > +   :doc: overview
> > +
> > +.. kernel-doc:: drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
> > +   :internal:
> > diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c 
> > b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
> > index a71177305bcd..93c813089bff 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
> > @@ -29,7 +29,9 @@
> >   #include "modules/color/color_gamma.h"
> >   #include "basics/conversion.h"
> > -/*
> > +/**
> > + * DOC: overview
> > + *
> >* The DC interface to HW gives us the following color management blocks
> >* per pipe (surface):
> >*
> > @@ -71,8 +73,8 @@
> >   #define MAX_DRM_LUT_VALUE 0x
> > -/*
> > - * Initialize the color module.
> > +/**
> > + * amdgpu_dm_init_color_mod - Initialize the color module.
> >*
> >* We're not using the full color module, only certain components.
> >* Only call setup functions for components that we need.
> > @@ -82,7 +84,14 @@ void amdgpu_dm_init_color_mod(void)
> > setup_x_points_distribution();
> >   }
> > -/* Extracts the DRM lut and lut size from a blob. */
> > +/**
> > + * __extract_blob_lut - Extracts the DRM lut and lut size from a blob.
> > + * @blob: DRM color mgmt property blob
> > + * @size: lut size
> > + *
> > + * Returns:
> > + * DRM LUT or NULL
> > + */
> >   static const struct drm_color_lut *
> >   __extract_blob_lut(const struct drm_property_blob *blob, uint32_t *size)
> >   {
> > @@ -90,13 +99,18 @@ __extract_blob_lut(const struct drm_property_blob 
> > *blob, uint32_t *size)
> > return blob ? (struct drm_color_lut *)blob->data : NULL;
> >   }
> 
> I don't think everyone would approve using actual kernel-doc for these
> static functions, but I can appreciate they being formatted as such.
> Consider replacing /** with /*.

IMHO, although they are static, they provide info to understand the AMD
DM programming of DRM color correction properties. I see the value for
external contributors, but I'm not sure about kernel-doc rules about it.

> 
> > -/*
> > - * Return true if the given lut is a linear mapping of values, i.e. it acts
> > - * like a bypass LUT.
> > +/**
> > + * __is_lut_linear - check if the given lut is a linear mapping of values
> > + * @lut: given lut to check values
> > + * @size: lut size
> >*
> >* It is considered linear if the lut represents:
> > - * f(a) = (0xFF00/MAX_COLOR_LUT_ENTRIES-1)a; for integer a in
> > - *   [0, MAX_COLOR_LUT_ENTRIES)
> > + * f(a) = (0xFF00/MAX_COLOR_LUT_ENTRIES-1)a; for integer a in [0,
> > + * MAX_COLOR_LUT_ENTRIES)
> > + *
> > + * Returns:
> > + * True if the given lut is a linear mapping of values, i.e. it acts like a
> > + * bypass LUT. Otherwise, false.
> >*/
> >   static bool __is_lut_linear(const struct drm_color_lut *lut, uint32_t 
> > size)
> >   {
> > @@ -119,9 +133,13 @@ static bool __is_lut_linear(const struct drm_color_lut 
> > *lut, uint32_t size)
> > return true;
> >   }
> > -/*
> > - * Convert the drm_color_lut to dc_gamma. The conversion depends on the 
> > size
> > - * of the lut - whether or not it's legacy.
> > +/**
> > + * __drm_lut_to_dc_gamma - convert the drm_color_lut to dc_gamma.
> > + * @lut: DRM lookup table for color conversion
> > + * @gamma: DC gamma to set entries
> > + * @is_legacy: legacy or atomic gamma
> > + *
> > + * The conversion depends on the size of the lut - whether or not it's 
> > legacy.
> >*/
> >   static void __drm_lut_to_dc_gamma(const struct drm_color_lut *lut,
> >   struct dc_gamma *gamma, bool is_legacy)
> > @@ -154,8 +172,11 @@ static void 

Re: [PATCH v2] drm/panel-edp: Add panel entry for B120XAN01.0

2022-07-20 Thread Doug Anderson
Hi,

On Wed, Jul 20, 2022 at 12:12 PM Nícolas F. R. A. Prado
 wrote:
>
> Add panel identification entry for the AUO B120XAN01.0 (product ID:
> 0x1062) panel.
>
> Signed-off-by: Nícolas F. R. A. Prado 
>
> ---
> v1: 
> https://lore.kernel.org/all/20220719203857.1488831-3-nfrapr...@collabora.com
>
> Changes in v2:
> - Move entry to the top so it respects the sorting
>
>  drivers/gpu/drm/panel/panel-edp.c | 1 +
>  1 file changed, 1 insertion(+)

Reviewed-by: Douglas Anderson 


Nothing controversial here, so I went ahead and pushed to drm-misc-next:

b68735e8ef58 drm/panel-edp: Add panel entry for B120XAN01.0

-Doug


Re: [PATCH 1/3] drm/panel-edp: Add panel entry for R140NWF5 RH

2022-07-20 Thread Doug Anderson
Hi,

On Wed, Jul 20, 2022 at 11:52 AM Nícolas F. R. A. Prado
 wrote:
>
> On Wed, Jul 20, 2022 at 09:49:35AM +0200, AngeloGioacchino Del Regno wrote:
> > Il 20/07/22 00:40, Doug Anderson ha scritto:
> > > Hi,
> > >
> > > On Tue, Jul 19, 2022 at 1:39 PM Nícolas F. R. A. Prado
> > >  wrote:
> > > >
> > > > Add panel identification entry for the IVO R140NWF5 RH (product ID:
> > > > 0x057d) panel.
> > > >
> > > > Signed-off-by: Nícolas F. R. A. Prado 
> > > >
> > > > ---
> > > > The comments on the driver indicate that the T3 timing should be set on
> > > > hpd_absent, while hpd_reliable would have a shorter time just while the
> > > > HPD line stabilizes on low after power is supplied.
> > >
> > > Right. Ideally hpd_reliable is 0 unless you've got a badly-designed panel.
> > >
> > >
> > > > But can we really assume that the HPD line will be reliable at all
> > > > before the DDIC is done booting up, at which point the HPD line is
> > > > brought up? IOW, shouldn't we always delay T3 (by setting hpd_reliable =
> > > > T3), since only then we're really sure that the DDIC is done setting up
> > > > and the HPD line is reliable?
> > >
> > > If the panel is hooked up properly, then the HPD pin should be pulled
> > > low at the start and then should only go high after the panel is ready
> > > for us to talk to it, right? So it's not like the DDIC has to boot up
> > > and actively init the state. I would assume that the initial state of
> > > the "HPD output" from the panel's IC would be one of the following:
> > > * A floating input.
> > > * A pulled down input.
> > > * An output driven low.
> > >
> > > In any of those cases just adding a pull down on the line would be
> > > enough to ensure that the HPD line is reliable until the panel comes
> > > around and actively drives the line high.
> > >
> > > Remember, this is eDP and it's not something that's hot-plugged, so
> > > there's no debouncing involved and in a properly designed system there
> > > should be no time needed for the signal to stabilize. I would also
> > > point out that on the oficial eDP docs the eDP timing diagram doesn't
> > > show the initial state of "HPD" as "unknown". It shows it as low.
> > >
> > > Now, that all being said, I have seen at least one panel that glitched
> > > itself at bootup. After you powered it on it would blip its HPD line
> > > high before it had actually finished booting. Then the HPD would go
> > > low again before finally going high after the panel finished booting.
> > > This is the reason for "hpd_reliable".
> > >
> > > If you've got a board with a well-designed panel but the hookup
> > > between the panel and the board is wrong (maybe the board is missing a
> > > pulldown on the HPD line?) then you can just set the "no-hpd" property
> > > for your board. That will tell the kernel to just always delay the
> > > "hpd-absent" delay.
> > >
>
> Thank you for the detailed explanation, this does clear all doubts from what 
> me
> and Angelo were discussing.
>
> >
> > We were concerned exactly about glitchy HPD during DDIC init, as I didn't
> > want to trust it because the only testing we could do was on just two 
> > units...
> >
> > ...but if you're sure that I was too much paranoid about that, that's good,
> > as it means I will be a bit more "relaxed" on this topic next time :-)
> >
> > > > I've set the T3 delay to hpd_absent in this series, following what's
> > > > instructed in the comments, but I'd like to discuss whether we shouldn't
> > > > be setting T3 on hpd_reliable instead, for all panels, to be on the
> > > > safer side.
> > >
> > > The way it's specified right now is more flexible, though, isn't it?
> > > This way if you're on a board where the HPD truly _isn't_ stable then
> > > you can just set the "no-hpd" and it will automatically use the
> > > "hpd_absent" delay, right?
> > >
>
> Yes, indeed. I just wasn't sure that flexibility brought us anything, but 
> after
> your explanation above it makes much more sense now, thanks!
>
> >
> > For Chromebooks, that's totally doable, thanks to the bootloader seeking for
> > proper machine compatibles, so yes I agree with that.
> >
> > >
> > > >   drivers/gpu/drm/panel/panel-edp.c | 8 
> > > >   1 file changed, 8 insertions(+)
> > > >
> > > > diff --git a/drivers/gpu/drm/panel/panel-edp.c 
> > > > b/drivers/gpu/drm/panel/panel-edp.c
> > > > index 3626469c4cc2..675d793d925e 100644
> > > > --- a/drivers/gpu/drm/panel/panel-edp.c
> > > > +++ b/drivers/gpu/drm/panel/panel-edp.c
> > > > @@ -1854,6 +1854,12 @@ static const struct panel_delay 
> > > > delay_100_500_e200 = {
> > > >  .enable = 200,
> > > >   };
> > > >
> > > > +static const struct panel_delay delay_200_500_e200 = {
> > > > +   .hpd_absent = 200,
> > > > +   .unprepare = 500,
> > > > +   .enable = 200,
> > > > +};
> > > > +
> > > >   #define EDP_PANEL_ENTRY(vend_chr_0, vend_chr_1, vend_chr_2, 
> > > > product_id, _delay, _name) \
> > > >   { \
> > > >  .name = _name, \
> > 

Re: [PATCH] drm/msm/dsi: Set panel orientation when directly connected

2022-07-20 Thread Doug Anderson
Hi,

On Wed, Jul 20, 2022 at 1:46 PM Rob Clark  wrote:
>
> On Fri, Jul 8, 2022 at 8:25 AM Doug Anderson  wrote:
> >
> > Hi,
> >
> > On Wed, Jul 6, 2022 at 12:14 PM Stephen Boyd  wrote:
> > >
> > > Set the panel orientation in drm when the panel is directly connected,
> > > i.e. we're not using an external bridge. The external bridge case is
> > > already handled by the panel bridge code, so we only update the path we
> > > take when the panel is directly connected/internal. This silences a
> > > warning splat coming from __drm_mode_object_add() on Wormdingler boards.
> > >
> > > Cc: Hsin-Yi Wang 
> > > Cc: Douglas Anderson 
> > > Signed-off-by: Stephen Boyd 
> > > ---
> > >
> > > This relies on commit 5e41b01a7808 ("drm/panel: Add an API to allow drm
> > > to set orientation from panel") which is in drm-misc
> > >
> > >  drivers/gpu/drm/msm/dsi/dsi_manager.c | 2 ++
> > >  1 file changed, 2 insertions(+)
> >
> > I don't personally have objections to this, but (to my understanding)
> > "the future" is that everyone should use panel_bridge. If we made the
> > move to panel_bridge today then we wouldn't need to do this. In
> > general I think panel_bridge would end up letting us delete a bunch of
> > code...
> >
> > See commit 4e5763f03e10 ("drm/bridge: ti-sn65dsi86: Wrap panel with
> > panel-bridge") for when this was done by ti-sn65dsi86.
> >
> > Then again, I spent a small amount of time looking into this and it's
> > definitely non-trivial. Still likely worthwhile, but not worth
> > blocking a tiny fix like this. It also should be fairly obvious that
> > we should delete this when we switch to panel_bridge.
> >
> > Thus:
> >
> > Reviewed-by: Douglas Anderson 
> >
> > I'll assume that we'll just snooze this commit until drm-misc-next
> > merges into a tree that msm-next is based on, which will probably be
> > the next -rc1. If desired and Acked I could land this in
> > drm-misc-next, but it's probably not worth it?
>
> if you want to land this patch via drm-misc, which might be the
> easier/faster route, then:
>
> Acked-by: Rob Clark 

As per discussion on IRC, I'm not going to apply this to drm-misc-next.

Given where we are in the cycle landing in drm-misc-next means it
won't be in mainline for a couple versions and I suspect that'll cause
merge conflicts with Dmitry's series [1]. ...and, of course, if
Dmitry's series lands then we don't even need ${SUBJECT} patch...

So I think the plan is:

1. Snooze waiting for the next -rc1 since
drm_connector_set_orientation_from_panel() won't be in mainline until
then.

2. If Dmitry's series looks like a long way off, we could land
${SUBJECT} patch in msm-next as a stopgap fix.


[1] 
https://lore.kernel.org/r/20220711094320.368062-5-dmitry.barysh...@linaro.org/

-Doug


Re: [PATCH 3/4] drm/amd/display: add doc entries for MPC blending configuration

2022-07-20 Thread Melissa Wen
On 07/17, Tales Lelo da Aparecida wrote:
> On 16/07/2022 19:25, Melissa Wen wrote:
> > Describe structs and enums used to set blend mode properties to MPC
> > blocks. Some pieces of information are already available as code
> > comments, and were just formatted. Others were collected and summarised
> > from discusssions on AMD issue tracker[1][2].
> 
> Typo in the commit message: discusssions -> discussions
> 
> > 
> > [1] https://gitlab.freedesktop.org/drm/amd/-/issues/1734
> > [2] https://gitlab.freedesktop.org/drm/amd/-/issues/1769
> > 
> > Signed-off-by: Melissa Wen 
> > ---
> >   drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h | 91 +
> >   1 file changed, 77 insertions(+), 14 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h 
> > b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
> > index 5097037e3962..cf28b841c42d 100644
> > --- a/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
> > +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h
> > @@ -22,6 +22,16 @@
> >*
> >*/
> > +/**
> > + * DOC: mpc-overview
> > + *
> > + * Multiple Pipe/Plane Combined (MPC) is a component in the hardware 
> > pipeline
> > + * that performs blending of multiple planes, using global and per-pixel 
> > alpha.
> > + * It also performs post-blending color correction operations according to 
> > the
> > + * hardware capabilities, such as color transformation matrix and gamma 1D 
> > and
> > + * 3D LUT.
> > + */
> > +
> >   #ifndef __DC_MPCC_H__
> >   #define __DC_MPCC_H__
> > @@ -48,14 +58,39 @@ enum mpcc_blend_mode {
> > MPCC_BLEND_MODE_TOP_BOT_BLENDING
> >   };
> > +/**
> > + * enum mpcc_alpha_blend_mode - define the alpha blend mode regarding pixel
> > + * alpha and plane alpha values
> > + */
> >   enum mpcc_alpha_blend_mode {
> > +   /**
> > +* @MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA: per pixel alpha using DPP
> > +* alpha value
> > +*/
> > MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA,
> > +   /**
> > +* @MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN: per
> > +* pixel alpha using DPP alpha value multiplied by a global gain (plane
> > +* alpha)
> > +*/
> > MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA_COMBINED_GLOBAL_GAIN,
> > +   /**
> > +* @MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA: global alpha value, ignores
> > +* pixel alpha and consider only plane alpha
> > +*/
> > MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA
> >   };
> > -/*
> > - * MPCC blending configuration
> > +/**
> > + * struct mpcc_blnd_cfg - MPCC blending configuration
> > + *
> > + * @black_color: background color
> > + * @alpha_mode: alpha blend mode (MPCC_ALPHA_BLND_MODE)
> > + * @pre_multiplied_alpha: whether pixel color values were pre-multiplied 
> > by the
> > + * alpha channel (MPCC_ALPHA_MULTIPLIED_MODE)
> > + * @global_gain: used when blend mode considers both pixel alpha and plane
> > + * alpha value and assumes the global alpha value.
> > + * @global_alpha: plane alpha value
> 
> There's quite a few members missing definition. After reading the 4th patch
> may I conclude that they weren't relevant for what's being described about
> alpha blending?

Hi Tales,

although they aren't changed for DRM blend modes programming, it would
be nice if someone can describe them and also avoid those warnings. I
wasn't able to identify how they behave for MPC programming (hope
someone from AMD can help on documenting them).

> 
> ./drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h:109: warning: Function
> parameter or member 'overlap_only' not described in 'mpcc_blnd_cfg'
> ./drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h:109: warning: Function
> parameter or member 'bottom_gain_mode' not described in 'mpcc_blnd_cfg'
> ./drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h:109: warning: Function
> parameter or member 'background_color_bpc' not described in 'mpcc_blnd_cfg'
> ./drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h:109: warning: Function
> parameter or member 'top_gain' not described in 'mpcc_blnd_cfg'
> ./drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h:109: warning: Function
> parameter or member 'bottom_inside_gain' not described in 'mpcc_blnd_cfg'
> ./drivers/gpu/drm/amd/display/dc/inc/hw/mpc.h:109: warning: Function
> parameter or member 'bottom_outside_gain' not described in 'mpcc_blnd_cfg'
> 
> >*/
> >   struct mpcc_blnd_cfg {
> > struct tg_color black_color;/* background color */
> > @@ -107,8 +142,15 @@ struct mpc_dwb_flow_control {
> > int flow_ctrl_cnt1;
> >   };
> > -/*
> > - * MPCC connection and blending configuration for a single MPCC instance.
> > +/**
> > + * struct mpcc - MPCC connection and blending configuration for a single 
> > MPCC instance.
> 
> Might be worth writing the definition of the abbreviation, if not here, in
> the glossary... I couldn't find what the last "C" stands for, my guess would
> be "context". hehehe
> 
> > + * @mpcc_id: MPCC physical instance
> > + * @dpp_id: DPP input to this MPCC
> > + * @mpcc_bot: pointer to bottom layer MPCC. NULL when not 

[pull] amdgpu drm-fixes-5.19

2022-07-20 Thread Alex Deucher
Hi Dave, Daniel,

A couple more fixes for 5.19 this week.  These are in addition to the
PR I sent late last week:
https://lists.freedesktop.org/archives/amd-gfx/2022-July/081597.html

The following changes since commit 2d4bd81fea1ad6ebba543bd6da3ef5179d130e6a:

  drm/amd/display: Fix new dmub notification enabling in DM (2022-07-15 
10:04:59 -0400)

are available in the Git repository at:

  https://gitlab.freedesktop.org/agd5f/linux.git 
tags/amd-drm-fixes-5.19-2022-07-20

for you to fetch changes up to 90af0ca047f3049c4b46e902f432ad6ef1e2ded6:

  drm/amdgpu: Protect the amdgpu_bo_list list with a mutex v2 (2022-07-20 
16:23:34 -0400)


amd-drm-fixes-5.19-2022-07-20:

amdgpu:
- Drop redundant buffer cleanup that can lead to a segfault
- Add a bo_list mutex to avoid possible list corruption in CS


Luben Tuikov (1):
  drm/amdgpu: Protect the amdgpu_bo_list list with a mutex v2

xinhui pan (1):
  drm/amdgpu: Remove one duplicated ef removal

 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c |  6 --
 drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c  |  3 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h  |  4 
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c   | 16 +---
 4 files changed, 19 insertions(+), 10 deletions(-)


Re: [Freedreno] [PATCH v2 3/7] drm/msm: Fix cx collapse issue during recovery

2022-07-20 Thread Akhil P Oommen

On 7/20/2022 11:36 PM, Rob Clark wrote:

On Tue, Jul 12, 2022 at 12:15 PM Akhil P Oommen
 wrote:

On 7/12/2022 10:14 PM, Rob Clark wrote:

On Mon, Jul 11, 2022 at 10:05 PM Akhil P Oommen
 wrote:

On 7/12/2022 4:52 AM, Doug Anderson wrote:

Hi,

On Fri, Jul 8, 2022 at 11:00 PM Akhil P Oommen  wrote:

There are some hardware logic under CX domain. For a successful
recovery, we should ensure cx headswitch collapses to ensure all the
stale states are cleard out. This is especially true to for a6xx family
where we can GMU co-processor.

Currently, cx doesn't collapse due to a devlink between gpu and its
smmu. So the *struct gpu device* needs to be runtime suspended to ensure
that the iommu driver removes its vote on cx gdsc.

Signed-off-by: Akhil P Oommen 
---

(no changes since v1)

drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 16 ++--
drivers/gpu/drm/msm/msm_gpu.c |  2 --
2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index 4d50110..7ed347c 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -1278,8 +1278,20 @@ static void a6xx_recover(struct msm_gpu *gpu)
*/
   gmu_write(_gpu->gmu, REG_A6XX_GMU_GMU_PWR_COL_KEEPALIVE, 0);

-   gpu->funcs->pm_suspend(gpu);
-   gpu->funcs->pm_resume(gpu);
+   /*
+* Now drop all the pm_runtime usage count to allow cx gdsc to collapse.
+* First drop the usage count from all active submits
+*/
+   for (i = gpu->active_submits; i > 0; i--)
+   pm_runtime_put(>pdev->dev);
+
+   /* And the final one from recover worker */
+   pm_runtime_put_sync(>pdev->dev);
+
+   for (i = gpu->active_submits; i > 0; i--)
+   pm_runtime_get(>pdev->dev);
+
+   pm_runtime_get_sync(>pdev->dev);

In response to v1, Rob suggested pm_runtime_force_suspend/resume().
Those seem like they would work to me, too. Why not use them?

Quoting my previous response which I seem to have sent only to Freedreno
list:

"I believe it is supposed to be used only during system sleep state
transitions. Btw, we don't want pm_runtime_get() calls from elsewhere to
fail by disabling RPM here."

The comment about not wanting other runpm calls to fail is valid.. but
that is also solveable, ie. by holding a lock around runpm calls.
Which I think we need to do anyways, otherwise looping over
gpu->active_submits is racey..

I think pm_runtime_force_suspend/resume() is the least-bad option.. or
at least I'm not seeing any obvious alternative that is better

BR,
-R

We are holding gpu->lock here which will block further submissions from
scheduler. Will active_submits still race?

It is possible that there is another thread which successfully completed
pm_runtime_get() and while it access the hardware, we pulled the plug on
regulator/clock here. That will result in obvious device crash. So I can
think of 2 solutions:

1. wrap *every* pm_runtime_get/put with a mutex. Something like:
  mutex_lock();
  pm_runtime_get();
  < ... access hardware here >>
  pm_runtime_put();
  mutex_unlock();

2. Drop runtime votes from every submit in recover worker and wait/poll
for regulator to collapse in case there are transient votes on
regulator  from other threads/subsystems.

Option (2) seems simpler to me.  What do you think?


But I think without #1 you could still be racing w/ some other path
that touches the hw, like devfreq, right.  They could be holding a
runpm ref, so even if you loop over active_submits decrementing the
runpm ref, it still doesn't drop to zero

BR,
-R
Yes, you are right. There could be some transient votes from other 
threads/drivers/subsystem. This is the reason we need to poll for cx 
gdsc collapse in the next patch.Even with #1, it is difficult to 
coordinate with smmu driver and close to impossible with tz/hyp.


-Akhil.


Re: [PATCH] drm/msm/dsi: Set panel orientation when directly connected

2022-07-20 Thread Rob Clark
On Fri, Jul 8, 2022 at 8:25 AM Doug Anderson  wrote:
>
> Hi,
>
> On Wed, Jul 6, 2022 at 12:14 PM Stephen Boyd  wrote:
> >
> > Set the panel orientation in drm when the panel is directly connected,
> > i.e. we're not using an external bridge. The external bridge case is
> > already handled by the panel bridge code, so we only update the path we
> > take when the panel is directly connected/internal. This silences a
> > warning splat coming from __drm_mode_object_add() on Wormdingler boards.
> >
> > Cc: Hsin-Yi Wang 
> > Cc: Douglas Anderson 
> > Signed-off-by: Stephen Boyd 
> > ---
> >
> > This relies on commit 5e41b01a7808 ("drm/panel: Add an API to allow drm
> > to set orientation from panel") which is in drm-misc
> >
> >  drivers/gpu/drm/msm/dsi/dsi_manager.c | 2 ++
> >  1 file changed, 2 insertions(+)
>
> I don't personally have objections to this, but (to my understanding)
> "the future" is that everyone should use panel_bridge. If we made the
> move to panel_bridge today then we wouldn't need to do this. In
> general I think panel_bridge would end up letting us delete a bunch of
> code...
>
> See commit 4e5763f03e10 ("drm/bridge: ti-sn65dsi86: Wrap panel with
> panel-bridge") for when this was done by ti-sn65dsi86.
>
> Then again, I spent a small amount of time looking into this and it's
> definitely non-trivial. Still likely worthwhile, but not worth
> blocking a tiny fix like this. It also should be fairly obvious that
> we should delete this when we switch to panel_bridge.
>
> Thus:
>
> Reviewed-by: Douglas Anderson 
>
> I'll assume that we'll just snooze this commit until drm-misc-next
> merges into a tree that msm-next is based on, which will probably be
> the next -rc1. If desired and Acked I could land this in
> drm-misc-next, but it's probably not worth it?

if you want to land this patch via drm-misc, which might be the
easier/faster route, then:

Acked-by: Rob Clark 

BR,
-R


Re: [v1 2/2] drm/msm/disp/dpu1: enable crtc color management based on encoder topology

2022-07-20 Thread Rob Clark
On Mon, Jun 27, 2022 at 4:56 AM Kalyan Thota  wrote:
>
> Thanks for the comments, Dmitry. I haven't noticed mode->hdisplay being used. 
> My idea was to run thru the topology and tie up the encoders with dspp to the 
> CRTCs.
> Since mode is available only in the commit, we cannot use the 
> dpu_encoder_get_topology during initialization sequence.
>
> The requirement here is that when we initialize the crtc, we need to enable 
> drm_crtc_enable_color_mgmt only for the crtcs that support it. As I 
> understand from Rob, chrome framework will check for the enablement in order 
> to exercise the feature.
>
> Do you have any ideas on how to handle this requirement ? Since we will 
> reserve the dspp's only when a commit is issued, I guess it will be too late 
> to enable color management by then.
>
> @robdcl...@gmail.com
> Is it okay, if we disable color management for all the crtcs during 
> initialization and enable it when we have dspps available during modeset. Can 
> we framework code query for the property before issuing a commit for the 
> frame after modeset ?
>

So, I suppose it would work out, because the splashscreen/frecon is
doing the first modeset before chrome even starts.  But that seems a
bit... delicate.

BR,
-R

> Thanks,
> Kalyan
>
> > -Original Message-
> > From: Dmitry Baryshkov 
> > Sent: Tuesday, June 21, 2022 4:43 PM
> > To: Kalyan Thota (QUIC) 
> > Cc: y...@qualcomm.com; dri-devel@lists.freedesktop.org; linux-arm-
> > m...@vger.kernel.org; freedr...@lists.freedesktop.org;
> > devicet...@vger.kernel.org; linux-ker...@vger.kernel.org;
> > robdcl...@gmail.com; diand...@chromium.org; swb...@chromium.org;
> > Vinod Polimera (QUIC) ; Abhinav Kumar (QUIC)
> > 
> > Subject: Re: [v1 2/2] drm/msm/disp/dpu1: enable crtc color management based
> > on encoder topology
> >
> > WARNING: This email originated from outside of Qualcomm. Please be wary of
> > any links or attachments, and do not enable macros.
> >
> > Generic comment: y...@qualcomm.com address bounces. Please remove it from
> > the cc list. If you need to send a patch for the internal reasons, please 
> > use Bcc.
> >
> > On Tue, 21 Jun 2022 at 12:06, Kalyan Thota  wrote:
> > >
> > > Crtc color management needs to be registered only for the crtc which
> > > has the capability to handle it. Since topology decides which encoder
> > > will get the dspp hw block, tie up the crtc and the encoder together
> > > (encoder->possible_crtcs)
> > >
> > > Change-Id: If5a0f33547b6f527ca4b8fbb78424b141dbbd711
> >
> > No change-id's please. This is not the gerrit.
> >
> > > Signed-off-by: Kalyan Thota 
> > > ---
> > >  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c|  8 ++--
> > >  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h|  2 +-
> > >  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 20 
> > > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h |  5 +
> > >  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 22 ++
> > >  5 files changed, 46 insertions(+), 11 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > > b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > > index 7763558..2913acb 100644
> > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > > @@ -1511,7 +1511,7 @@ static const struct drm_crtc_helper_funcs
> > > dpu_crtc_helper_funcs = {
> > >
> > >  /* initialize crtc */
> > >  struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane
> > *plane,
> > > -   struct drm_plane *cursor)
> > > +   struct drm_plane *cursor, unsigned int
> > > + enc_mask)
> > >  {
> > > struct drm_crtc *crtc = NULL;
> > > struct dpu_crtc *dpu_crtc = NULL; @@ -1544,7 +1544,11 @@
> > > struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct
> > > drm_plane *plane,
> > >
> > > drm_crtc_helper_add(crtc, _crtc_helper_funcs);
> > >
> > > -   drm_crtc_enable_color_mgmt(crtc, 0, true, 0);
> > > +   /* Register crtc color management if the encoder has dspp, use the
> > > +* crtc to mark it as possible_crtcs for that encoder.
> > > +*/
> > > +   if(BIT(crtc->index) & enc_mask)
> >
> > So, we are checking CRTC's index against the encoder's mask? This is
> > counterintuitive.
> >
> > > +   drm_crtc_enable_color_mgmt(crtc, 0, true, 0);
> > >
> > > /* save user friendly CRTC name for later */
> > > snprintf(dpu_crtc->name, DPU_CRTC_NAME_SIZE, "crtc%u",
> > > crtc->base.id); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> > > b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> > > index b8785c3..0a6458e 100644
> > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> > > @@ -269,7 +269,7 @@ void dpu_crtc_complete_commit(struct drm_crtc
> > *crtc);
> > >   * @Return: new crtc object or error
> > >   */
> > >  struct drm_crtc *dpu_crtc_init(struct drm_device 

Re: [PATCH v4 1/2] vfio: Replace the DMA unmapping notifier with a callback

2022-07-20 Thread Jason Gunthorpe
On Wed, Jul 20, 2022 at 01:41:13PM -0600, Alex Williamson wrote:
 
> ie. we don't need the gfn, we only need the iova.

Right, that makes sense
 
> However then I start to wonder why we're passing in 1 for the number of
> pages because this previously notifier, now callback is called for the
> entire vfio_dma range when we find any pinned pages.  

Well, it is doing this because it only ever pins one page.

The drivers are confused about what the contract is. vfio is calling
the notifier with the entire IOVA range that is being unmapped and the
drivers are expecting to receive notifications only for the IOVA they
have actually pinned.

> Should ap and ccw implementations of .dma_unmap just be replaced with a
> BUG_ON(1)?

The point of these callbacks is to halt concurrent DMA, and ccw does
that today. It looks like AP is missing a call to ap_aqic(), so it is
probably double wrong.

What I'd suggest is adding a WARN_ON that the dma->pfn_list is not
empty and leave these functions alone.

Most likely AP should be fixed to call vfio_ap_irq_disable() and to
check the q->saved_pfn against the IOVA.

But I'm inclined to leave this as-is for this series given we are at
rc7.

Jason


Re: [PATCH v4 1/2] vfio: Replace the DMA unmapping notifier with a callback

2022-07-20 Thread Alex Williamson
On Tue, 19 Jul 2022 21:02:48 -0300
Jason Gunthorpe  wrote:
> diff --git a/drivers/s390/crypto/vfio_ap_ops.c 
> b/drivers/s390/crypto/vfio_ap_ops.c
> index a7d2a95796d360..bb1a1677c5c230 100644
> --- a/drivers/s390/crypto/vfio_ap_ops.c
> +++ b/drivers/s390/crypto/vfio_ap_ops.c
> @@ -1226,34 +1226,14 @@ static int vfio_ap_mdev_set_kvm(struct ap_matrix_mdev 
> *matrix_mdev,
>   return 0;
>  }
>  
> -/**
> - * vfio_ap_mdev_iommu_notifier - IOMMU notifier callback
> - *
> - * @nb: The notifier block
> - * @action: Action to be taken
> - * @data: data associated with the request
> - *
> - * For an UNMAP request, unpin the guest IOVA (the NIB guest address we
> - * pinned before). Other requests are ignored.
> - *
> - * Return: for an UNMAP request, NOFITY_OK; otherwise NOTIFY_DONE.
> - */
> -static int vfio_ap_mdev_iommu_notifier(struct notifier_block *nb,
> -unsigned long action, void *data)
> +static void vfio_ap_mdev_dma_unmap(struct vfio_device *vdev, u64 iova,
> +u64 length)
>  {
> - struct ap_matrix_mdev *matrix_mdev;
> -
> - matrix_mdev = container_of(nb, struct ap_matrix_mdev, iommu_notifier);
> -
> - if (action == VFIO_IOMMU_NOTIFY_DMA_UNMAP) {
> - struct vfio_iommu_type1_dma_unmap *unmap = data;
> - unsigned long g_pfn = unmap->iova >> PAGE_SHIFT;
> -
> - vfio_unpin_pages(_mdev->vdev, _pfn, 1);
> - return NOTIFY_OK;
> - }
> + struct ap_matrix_mdev *matrix_mdev =
> + container_of(vdev, struct ap_matrix_mdev, vdev);
> + unsigned long g_pfn = iova >> PAGE_SHIFT;
>  
> - return NOTIFY_DONE;
> + vfio_unpin_pages(_mdev->vdev, _pfn, 1);
>  }
>  
>  /**


I tried to apply this on top of Nicolin's series which results in a
conflict that can be resolved as below:

diff --git a/drivers/s390/crypto/vfio_ap_ops.c 
b/drivers/s390/crypto/vfio_ap_ops.c
index e8856a7e151c..d7c38c82f694 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -1219,33 +1219,13 @@ static int vfio_ap_mdev_set_kvm(struct ap_matrix_mdev 
*matrix_mdev,
return 0;
 }
 
-/**
- * vfio_ap_mdev_iommu_notifier - IOMMU notifier callback
- *
- * @nb: The notifier block
- * @action: Action to be taken
- * @data: data associated with the request
- *
- * For an UNMAP request, unpin the guest IOVA (the NIB guest address we
- * pinned before). Other requests are ignored.
- *
- * Return: for an UNMAP request, NOFITY_OK; otherwise NOTIFY_DONE.
- */
-static int vfio_ap_mdev_iommu_notifier(struct notifier_block *nb,
-  unsigned long action, void *data)
+static void vfio_ap_mdev_dma_unmap(struct vfio_device *vdev, u64 iova,
+  u64 length)
 {
-   struct ap_matrix_mdev *matrix_mdev;
-
-   matrix_mdev = container_of(nb, struct ap_matrix_mdev, iommu_notifier);
-
-   if (action == VFIO_IOMMU_NOTIFY_DMA_UNMAP) {
-   struct vfio_iommu_type1_dma_unmap *unmap = data;
-
-   vfio_unpin_pages(_mdev->vdev, unmap->iova, 1);
-   return NOTIFY_OK;
-   }
+   struct ap_matrix_mdev *matrix_mdev =
+   container_of(vdev, struct ap_matrix_mdev, vdev);
 
-   return NOTIFY_DONE;
+   vfio_unpin_pages(_mdev->vdev, iova, 1);
 }
 
 /**

ie. we don't need the gfn, we only need the iova.

However then I start to wonder why we're passing in 1 for the number of
pages because this previously notifier, now callback is called for the
entire vfio_dma range when we find any pinned pages.  It makes no sense for
a driver to assume that the first iova is pinned and is the only pinned
page.

ccw has the same issue:

static void vfio_ccw_dma_unmap(struct vfio_device *vdev, u64 iova, u64 length)
{
struct vfio_ccw_private *private =
container_of(vdev, struct vfio_ccw_private, vdev);

/* Drivers MUST unpin pages in response to an invalidation. */
if (!cp_iova_pinned(>cp, iova))
return;

vfio_ccw_mdev_reset(private);
}

Entirely ignoring the length arg.

It seems only GVT-g has this correct to actually look through the
extent of the range being unmapped:

static void intel_vgpu_dma_unmap(struct vfio_device *vfio_dev, u64 iova,
 u64 length)
{
struct intel_vgpu *vgpu = vfio_dev_to_vgpu(vfio_dev);
struct gvt_dma *entry;
u64 iov_pfn = iova >> PAGE_SHIFT;
u64 end_iov_pfn = iov_pfn + length / PAGE_SIZE;

mutex_lock(>cache_lock);
for (; iov_pfn < end_iov_pfn; iov_pfn++) {
entry = __gvt_cache_find_gfn(vgpu, iov_pfn);
if (!entry)
continue;

gvt_dma_unmap_page(vgpu, entry->gfn, entry->dma_addr,
   entry->size);
__gvt_cache_remove_entry(vgpu, entry);
}
mutex_unlock(>cache_lock);
}

Should ap and 

[PATCH 5/5] drm/amd/display: move FPU code from dcn301 clk mgr to DML folder

2022-07-20 Thread Melissa Wen
The -mno-gnu-attribute option in dcn301 clk mgr makefile hides a soft vs
hard fp error for powerpc. After removing this flag, we can see some FPU
code remains there:

gcc-11.3.0-nolibc/powerpc64-linux/bin/powerpc64-linux-ld:
drivers/gpu/drm/amd/amdgpu/../display/dc/dml/display_mode_lib.o uses
hard float,
drivers/gpu/drm/amd/amdgpu/../display/dc/clk_mgr/dcn301/vg_clk_mgr.o
uses soft float

Therefore, remove the -mno-gnu-attribute flag for dcn301/powerpc and
move FPU-associated code to DML folder.

Signed-off-by: Melissa Wen 
---
 .../gpu/drm/amd/display/dc/clk_mgr/Makefile   |  6 --
 .../display/dc/clk_mgr/dcn301/vg_clk_mgr.c| 86 ++-
 .../display/dc/clk_mgr/dcn301/vg_clk_mgr.h|  3 +
 .../amd/display/dc/dml/dcn301/dcn301_fpu.c| 74 
 4 files changed, 84 insertions(+), 85 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile
index 15b660a951a5..271d8e573181 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile
@@ -123,12 +123,6 @@ AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN30)
 ###
 CLK_MGR_DCN301 = vg_clk_mgr.o dcn301_smu.o
 
-# prevent build errors regarding soft-float vs hard-float FP ABI tags
-# this code is currently unused on ppc64, as it applies to VanGogh APUs only
-ifdef CONFIG_PPC64
-CFLAGS_$(AMDDALPATH)/dc/clk_mgr/dcn301/vg_clk_mgr.o := $(call 
cc-option,-mno-gnu-attribute)
-endif
-
 AMD_DAL_CLK_MGR_DCN301 = $(addprefix 
$(AMDDALPATH)/dc/clk_mgr/dcn301/,$(CLK_MGR_DCN301))
 
 AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN301)
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c
index f310b0d25a07..65f224af03c0 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn301/vg_clk_mgr.c
@@ -32,6 +32,10 @@
 // For dcn20_update_clocks_update_dpp_dto
 #include "dcn20/dcn20_clk_mgr.h"
 
+// For DML FPU code
+#include "dml/dcn20/dcn20_fpu.h"
+#include "dml/dcn301/dcn301_fpu.h"
+
 #include "vg_clk_mgr.h"
 #include "dcn301_smu.h"
 #include "reg_helper.h"
@@ -526,81 +530,6 @@ static struct clk_bw_params vg_bw_params = {
 
 };
 
-static struct wm_table ddr4_wm_table = {
-   .entries = {
-   {
-   .wm_inst = WM_A,
-   .wm_type = WM_TYPE_PSTATE_CHG,
-   .pstate_latency_us = 11.72,
-   .sr_exit_time_us = 6.09,
-   .sr_enter_plus_exit_time_us = 7.14,
-   .valid = true,
-   },
-   {
-   .wm_inst = WM_B,
-   .wm_type = WM_TYPE_PSTATE_CHG,
-   .pstate_latency_us = 11.72,
-   .sr_exit_time_us = 10.12,
-   .sr_enter_plus_exit_time_us = 11.48,
-   .valid = true,
-   },
-   {
-   .wm_inst = WM_C,
-   .wm_type = WM_TYPE_PSTATE_CHG,
-   .pstate_latency_us = 11.72,
-   .sr_exit_time_us = 10.12,
-   .sr_enter_plus_exit_time_us = 11.48,
-   .valid = true,
-   },
-   {
-   .wm_inst = WM_D,
-   .wm_type = WM_TYPE_PSTATE_CHG,
-   .pstate_latency_us = 11.72,
-   .sr_exit_time_us = 10.12,
-   .sr_enter_plus_exit_time_us = 11.48,
-   .valid = true,
-   },
-   }
-};
-
-static struct wm_table lpddr5_wm_table = {
-   .entries = {
-   {
-   .wm_inst = WM_A,
-   .wm_type = WM_TYPE_PSTATE_CHG,
-   .pstate_latency_us = 11.65333,
-   .sr_exit_time_us = 13.5,
-   .sr_enter_plus_exit_time_us = 16.5,
-   .valid = true,
-   },
-   {
-   .wm_inst = WM_B,
-   .wm_type = WM_TYPE_PSTATE_CHG,
-   .pstate_latency_us = 11.65333,
-   .sr_exit_time_us = 13.5,
-   .sr_enter_plus_exit_time_us = 16.5,
-   .valid = true,
-   },
-   {
-   .wm_inst = WM_C,
-   .wm_type = WM_TYPE_PSTATE_CHG,
-   .pstate_latency_us = 11.65333,
-   .sr_exit_time_us = 13.5,
-   .sr_enter_plus_exit_time_us = 16.5,
-   .valid = true,
-   },
-   {
-   .wm_inst = WM_D,
-   .wm_type = WM_TYPE_PSTATE_CHG,
-   .pstate_latency_us = 

[PATCH 4/5] drm/amd/display: move FPU code from dcn30 clk mgr to DML folder

2022-07-20 Thread Melissa Wen
The -mno-gnu-attribute option in clk mgr makefile for dcn30 hides a soft
vs hard fp error for powerpc. After removing this flag, we can see some
FPU code remains there:

gcc-11.3.0-nolibc/powerpc64-linux/bin/powerpc64-linux-ld:
drivers/gpu/drm/amd/amdgpu/../display/dc/dml/display_mode_lib.o uses
hard float,
drivers/gpu/drm/amd/amdgpu/../display/dc/clk_mgr/dcn30/dcn30_clk_mgr.o
uses soft float

Therefore, remove the -mno-gnu-attribute flag for dcn30/powerpc and move
FPU-associated code to DML folder.

Signed-off-by: Melissa Wen 
---
 .../gpu/drm/amd/display/dc/clk_mgr/Makefile   |  6 --
 .../display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c  | 63 ++-
 .../drm/amd/display/dc/dml/dcn30/dcn30_fpu.c  | 63 ++-
 .../drm/amd/display/dc/dml/dcn30/dcn30_fpu.h  |  1 +
 4 files changed, 68 insertions(+), 65 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile
index 66dc02c426e9..15b660a951a5 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile
@@ -115,12 +115,6 @@ AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN21)
 ###
 CLK_MGR_DCN30 = dcn30_clk_mgr.o dcn30_clk_mgr_smu_msg.o
 
-# prevent build errors regarding soft-float vs hard-float FP ABI tags
-# this code is currently unused on ppc64, as it applies to VanGogh APUs only
-ifdef CONFIG_PPC64
-CFLAGS_$(AMDDALPATH)/dc/clk_mgr/dcn30/dcn30_clk_mgr.o := $(call 
cc-option,-mno-gnu-attribute)
-endif
-
 AMD_DAL_CLK_MGR_DCN30 = $(addprefix 
$(AMDDALPATH)/dc/clk_mgr/dcn30/,$(CLK_MGR_DCN30))
 
 AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN30)
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
index 914708cefc79..3ce0ee0d012f 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
@@ -29,6 +29,7 @@
 #include "dcn20/dcn20_clk_mgr.h"
 #include "dce100/dce_clk_mgr.h"
 #include "dcn30/dcn30_clk_mgr.h"
+#include "dml/dcn30/dcn30_fpu.h"
 #include "reg_helper.h"
 #include "core_types.h"
 #include "dm_helpers.h"
@@ -97,65 +98,11 @@ static void dcn3_init_single_clock(struct clk_mgr_internal 
*clk_mgr, uint32_t cl
}
 }
 
-static noinline void dcn3_build_wm_range_table(struct clk_mgr_internal 
*clk_mgr)
+static void dcn3_build_wm_range_table(struct clk_mgr_internal *clk_mgr)
 {
-   /* defaults */
-   double pstate_latency_us = 
clk_mgr->base.ctx->dc->dml.soc.dram_clock_change_latency_us;
-   double sr_exit_time_us = clk_mgr->base.ctx->dc->dml.soc.sr_exit_time_us;
-   double sr_enter_plus_exit_time_us = 
clk_mgr->base.ctx->dc->dml.soc.sr_enter_plus_exit_time_us;
-   uint16_t min_uclk_mhz = 
clk_mgr->base.bw_params->clk_table.entries[0].memclk_mhz;
-
-   /* Set A - Normal - default values*/
-   clk_mgr->base.bw_params->wm_table.nv_entries[WM_A].valid = true;
-   
clk_mgr->base.bw_params->wm_table.nv_entries[WM_A].dml_input.pstate_latency_us 
= pstate_latency_us;
-   
clk_mgr->base.bw_params->wm_table.nv_entries[WM_A].dml_input.sr_exit_time_us = 
sr_exit_time_us;
-   
clk_mgr->base.bw_params->wm_table.nv_entries[WM_A].dml_input.sr_enter_plus_exit_time_us
 = sr_enter_plus_exit_time_us;
-   
clk_mgr->base.bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.wm_type = 
WATERMARKS_CLOCK_RANGE;
-   
clk_mgr->base.bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.min_dcfclk = 
0;
-   
clk_mgr->base.bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.max_dcfclk = 
0x;
-   
clk_mgr->base.bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.min_uclk = 
min_uclk_mhz;
-   
clk_mgr->base.bw_params->wm_table.nv_entries[WM_A].pmfw_breakdown.max_uclk = 
0x;
-
-   /* Set B - Performance - higher minimum clocks */
-// clk_mgr->base.bw_params->wm_table.nv_entries[WM_B].valid = true;
-// 
clk_mgr->base.bw_params->wm_table.nv_entries[WM_B].dml_input.pstate_latency_us 
= pstate_latency_us;
-// 
clk_mgr->base.bw_params->wm_table.nv_entries[WM_B].dml_input.sr_exit_time_us = 
sr_exit_time_us;
-// 
clk_mgr->base.bw_params->wm_table.nv_entries[WM_B].dml_input.sr_enter_plus_exit_time_us
 = sr_enter_plus_exit_time_us;
-// 
clk_mgr->base.bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.wm_type = 
WATERMARKS_CLOCK_RANGE;
-// 
clk_mgr->base.bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.min_dcfclk = 
TUNED VALUE;
-// 
clk_mgr->base.bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.max_dcfclk = 
0x;
-// 
clk_mgr->base.bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.min_uclk = 
TUNED VALUE;
-// 
clk_mgr->base.bw_params->wm_table.nv_entries[WM_B].pmfw_breakdown.max_uclk = 
0x;
-
-   /* Set C - Dummy P-State - P-State latency set to "dummy p-state" value 
*/
-   

[PATCH 2/5] drm/amd/display: remove useless FPU protection wrapper from dcn31_resource file

2022-07-20 Thread Melissa Wen
Many lines of code in dcn31_resource_construct are wrapped by DC_FP
macro to protect FPU operations; however, there is no FPU in this
region. Therefore, just remove the wrapper for clarity.

Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c 
b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
index 929b712cbada..6d25fcf865bf 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
@@ -1863,8 +1863,6 @@ static bool dcn31_resource_construct(
struct dc_context *ctx = dc->ctx;
struct irq_service_init_data init_data;
 
-   DC_FP_START();
-
ctx->dc_bios->regs = _regs;
 
pool->base.res_cap = _cap_dcn31;
@@ -2175,13 +2173,9 @@ static bool dcn31_resource_construct(
 
dc->dcn_ip->max_num_dpp = dcn3_1_ip.max_num_dpp;
 
-   DC_FP_END();
-
return true;
 
 create_fail:
-
-   DC_FP_END();
dcn31_resource_destruct(pool);
 
return false;
-- 
2.35.1



[PATCH 3/5] drm/amd/display: move FPU code on dcn21 clk_mgr

2022-07-20 Thread Melissa Wen
The -mno-gnu-attribute option in dcn21 clk mgr makefile hides a soft vs
hard fp error for powerpc. After removing this flag, we can see some FPU
code remains there:

/gcc-11.3.0-nolibc/powerpc64-linux/bin/powerpc64-linux-ld:
drivers/gpu/drm/amd/amdgpu/../display/dc/dml/display_mode_lib.o uses
hard float,
drivers/gpu/drm/amd/amdgpu/../display/dc/clk_mgr/dcn21/rn_clk_mgr.o uses
soft float

Therefore, remove the -mno-gnu-attribute flag for dcn21/powerpc and move
FPU-associated code to DML folder.

Signed-off-by: Melissa Wen 
---
 .../gpu/drm/amd/display/dc/clk_mgr/Makefile   |   6 -
 .../amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c | 234 +
 .../amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.h |   7 +
 .../drm/amd/display/dc/dml/dcn20/dcn20_fpu.c  | 235 ++
 .../drm/amd/display/dc/dml/dcn20/dcn20_fpu.h  |   2 +
 5 files changed, 248 insertions(+), 236 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile
index a48453612d10..66dc02c426e9 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/Makefile
@@ -107,12 +107,6 @@ AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN201)
 ###
 CLK_MGR_DCN21 = rn_clk_mgr.o rn_clk_mgr_vbios_smu.o
 
-# prevent build errors regarding soft-float vs hard-float FP ABI tags
-# this code is currently unused on ppc64, as it applies to Renoir APUs only
-ifdef CONFIG_PPC64
-CFLAGS_$(AMDDALPATH)/dc/clk_mgr/dcn21/rn_clk_mgr.o := $(call 
cc-option,-mno-gnu-attribute)
-endif
-
 AMD_DAL_CLK_MGR_DCN21 = $(addprefix 
$(AMDDALPATH)/dc/clk_mgr/dcn21/,$(CLK_MGR_DCN21))
 
 AMD_DISPLAY_FILES += $(AMD_DAL_CLK_MGR_DCN21)
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c
index cf1b5f354ae9..0202dc682682 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c
@@ -26,10 +26,9 @@
 #include "dccg.h"
 #include "clk_mgr_internal.h"
 
-
 #include "dcn20/dcn20_clk_mgr.h"
 #include "rn_clk_mgr.h"
-
+#include "dml/dcn20/dcn20_fpu.h"
 
 #include "dce100/dce_clk_mgr.h"
 #include "rn_clk_mgr_vbios_smu.h"
@@ -45,7 +44,6 @@
 
 /* Constants */
 
-#define LPDDR_MEM_RETRAIN_LATENCY 4.977 /* Number obtained from LPDDR4 
Training Counter Requirement doc */
 #define SMU_VER_55_51_0 0x373300 /* SMU Version that is able to set DISPCLK 
below 100MHz */
 
 /* Macros */
@@ -613,228 +611,6 @@ static struct clk_bw_params rn_bw_params = {
 
 };
 
-static struct wm_table ddr4_wm_table_gs = {
-   .entries = {
-   {
-   .wm_inst = WM_A,
-   .wm_type = WM_TYPE_PSTATE_CHG,
-   .pstate_latency_us = 11.72,
-   .sr_exit_time_us = 7.09,
-   .sr_enter_plus_exit_time_us = 8.14,
-   .valid = true,
-   },
-   {
-   .wm_inst = WM_B,
-   .wm_type = WM_TYPE_PSTATE_CHG,
-   .pstate_latency_us = 11.72,
-   .sr_exit_time_us = 10.12,
-   .sr_enter_plus_exit_time_us = 11.48,
-   .valid = true,
-   },
-   {
-   .wm_inst = WM_C,
-   .wm_type = WM_TYPE_PSTATE_CHG,
-   .pstate_latency_us = 11.72,
-   .sr_exit_time_us = 10.12,
-   .sr_enter_plus_exit_time_us = 11.48,
-   .valid = true,
-   },
-   {
-   .wm_inst = WM_D,
-   .wm_type = WM_TYPE_PSTATE_CHG,
-   .pstate_latency_us = 11.72,
-   .sr_exit_time_us = 10.12,
-   .sr_enter_plus_exit_time_us = 11.48,
-   .valid = true,
-   },
-   }
-};
-
-static struct wm_table lpddr4_wm_table_gs = {
-   .entries = {
-   {
-   .wm_inst = WM_A,
-   .wm_type = WM_TYPE_PSTATE_CHG,
-   .pstate_latency_us = 11.65333,
-   .sr_exit_time_us = 5.32,
-   .sr_enter_plus_exit_time_us = 6.38,
-   .valid = true,
-   },
-   {
-   .wm_inst = WM_B,
-   .wm_type = WM_TYPE_PSTATE_CHG,
-   .pstate_latency_us = 11.65333,
-   .sr_exit_time_us = 9.82,
-   .sr_enter_plus_exit_time_us = 11.196,
-   .valid = true,
-   },
-   {
-   .wm_inst = WM_C,
-   .wm_type = WM_TYPE_PSTATE_CHG,
-   .pstate_latency_us = 11.65333,
-   

[PATCH 1/5] drm/amd/display: fix soft-fp vs hard-fp on DCN 3.1 family for powerpc

2022-07-20 Thread Melissa Wen
Move remaining FPU code to DML folder that caused compilation error for
powerpc. This patch depends on [1] to prevent the error below:

/gcc-11.3.0-nolibc/powerpc64-linux/bin/powerpc64-linux-ld: 
drivers/gpu/drm/amd/amdgpu/../display/dc/dml/display_mode_lib.o uses hard 
float, drivers/gpu/drm/amd/amdgpu/../display/dc/dcn31/dcn31_resource.o uses 
soft float
/gcc-11.3.0-nolibc/powerpc64-linux/bin/powerpc64-linux-ld: failed to merge 
target specific data of file 
drivers/gpu/drm/amd/amdgpu/../display/dc/dcn31/dcn31_resource.o
/gcc-11.3.0-nolibc/powerpc64-linux/bin/powerpc64-linux-ld: 
drivers/gpu/drm/amd/amdgpu/../display/dc/dml/display_mode_lib.o uses hard 
float, drivers/gpu/drm/amd/amdgpu/../display/dc/dcn315/dcn315_resource.o uses 
soft float
/gcc-11.3.0-nolibc/powerpc64-linux/bin/powerpc64-linux-ld: failed to merge 
target specific data of file 
drivers/gpu/drm/amd/amdgpu/../display/dc/dcn315/dcn315_resource.o
/gcc-11.3.0-nolibc/powerpc64-linux/bin/powerpc64-linux-ld: 
drivers/gpu/drm/amd/amdgpu/../display/dc/dml/display_mode_lib.o uses hard 
float, drivers/gpu/drm/amd/amdgpu/../display/dc/dcn316/dcn316_resource.o uses 
soft float
/gcc-11.3.0-nolibc/powerpc64-linux/bin/powerpc64-linux-ld: failed to merge 
target specific data of file 
drivers/gpu/drm/amd/amdgpu/../display/dc/dcn316/dcn316_resource.o

[1] https://lore.kernel.org/amd-gfx/20220716195144.342960-1-m...@igalia.com/

Reported-by: Guenter Roeck 
Signed-off-by: Melissa Wen 
---
 drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c |  5 +++--
 .../gpu/drm/amd/display/dc/dcn315/dcn315_resource.c   |  5 +++--
 .../gpu/drm/amd/display/dc/dcn316/dcn316_resource.c   |  5 +++--
 drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c  | 11 +++
 drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.h  |  3 +++
 5 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c 
b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
index 178d40c0d70a..929b712cbada 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
@@ -1663,11 +1663,12 @@ int dcn31_populate_dml_pipes_from_context(
pipes[pipe_cnt].pipe.src.immediate_flip = true;
pipes[pipe_cnt].pipe.src.unbounded_req_mode = false;
pipes[pipe_cnt].pipe.src.gpuvm = true;
-   pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_luma = 0;
-   pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_chroma = 0;
pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch;
pipes[pipe_cnt].pipe.src.dcc_rate = 3;
pipes[pipe_cnt].dout.dsc_input_bpc = 0;
+   DC_FP_START();
+   dcn31_zero_pipe_dcc_fraction(pipes, pipe_cnt);
+   DC_FP_END();
 
if (dc->debug.dml_hostvm_override == DML_HOSTVM_NO_OVERRIDE)
pipes[pipe_cnt].pipe.src.hostvm = 
dc->res_pool->hubbub->riommu_active;
diff --git a/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c 
b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c
index df2abd8fe2eb..1a5f5977f962 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c
@@ -1658,11 +1658,12 @@ static int dcn315_populate_dml_pipes_from_context(
 
pipes[pipe_cnt].pipe.src.unbounded_req_mode = false;
pipes[pipe_cnt].pipe.src.gpuvm = true;
-   pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_luma = 0;
-   pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_chroma = 0;
pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch;
pipes[pipe_cnt].pipe.src.dcc_rate = 3;
pipes[pipe_cnt].dout.dsc_input_bpc = 0;
+   DC_FP_START();
+   dcn31_zero_pipe_dcc_fraction(pipes, pipe_cnt);
+   DC_FP_END();
 
if (pipes[pipe_cnt].dout.dsc_enable) {
switch (timing->display_color_depth) {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c 
b/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c
index 070fe10a004e..53dea466348f 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c
@@ -1661,11 +1661,12 @@ static int dcn316_populate_dml_pipes_from_context(
 
pipes[pipe_cnt].pipe.src.unbounded_req_mode = false;
pipes[pipe_cnt].pipe.src.gpuvm = true;
-   pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_luma = 0;
-   pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_chroma = 0;
pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch;
pipes[pipe_cnt].pipe.src.dcc_rate = 3;
pipes[pipe_cnt].dout.dsc_input_bpc = 0;
+   DC_FP_START();
+   

[PATCH 0/5] drm/amd/display: FPU cleanup in clk_mgr files for powerpc

2022-07-20 Thread Melissa Wen
An initial report from Guenter[1] shows some soft-fp vs hard-fp error
from DCN31 clk mgr for powerpc. I was not able to reproduce it
cross-compiling with gcc-powerpc-linux-gnu and gcc-11.3, but thanks to
Maíra tips, I can reproduce the issue using make.cross, as follows:

- wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross 
-O ~/bin/make.cross
- chmod +x ~/bin/make.cross
- mkdir build_dir
- COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.3.0 ~/make.cross O=build_dir 
ARCH=powerpc SHELL=/bin/bash

with a config file generate by allmodconfig

So, the first patch fix the issue reported by Guenter. The second is
just a cleanup in dcn31_resource file to remove useless DC_FP_ wrapper.
Finally, the last three patches I'm removing the -mno-gnu-attribute
option, that was just hiding FPU-associated code in clk mgr files of
dcn21/30/301, and moving them to DML folder. This series doesn't cover
recent drivers dcn32/314.

Thanks Guenter, Maíra, Siqueira and Alex for all inputs on this
debugging process. Let me know your thoughts on this approach.

Melissa

[1] https://lore.kernel.org/amd-gfx/20220618232737.2036722-1-li...@roeck-us.net/

Melissa Wen (5):
  drm/amd/display: fix soft-fp vs hard-fp on DCN 3.1 family for powerpc
  drm/amd/display: remove useless FPU protection wrapper from
dcn31_resource file
  drm/amd/display: move FPU code on dcn21 clk_mgr
  drm/amd/display: move FPU code from dcn30 clk mgr to DML folder
  drm/amd/display: move FPU code from dcn301 clk mgr to DML folder

 .../gpu/drm/amd/display/dc/clk_mgr/Makefile   |  18 --
 .../amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c | 234 +
 .../amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.h |   7 +
 .../display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c  |  63 +
 .../display/dc/clk_mgr/dcn301/vg_clk_mgr.c|  86 +--
 .../display/dc/clk_mgr/dcn301/vg_clk_mgr.h|   3 +
 .../drm/amd/display/dc/dcn31/dcn31_resource.c |  11 +-
 .../amd/display/dc/dcn315/dcn315_resource.c   |   5 +-
 .../amd/display/dc/dcn316/dcn316_resource.c   |   5 +-
 .../drm/amd/display/dc/dml/dcn20/dcn20_fpu.c  | 235 ++
 .../drm/amd/display/dc/dml/dcn20/dcn20_fpu.h  |   2 +
 .../drm/amd/display/dc/dml/dcn30/dcn30_fpu.c  |  63 -
 .../drm/amd/display/dc/dml/dcn30/dcn30_fpu.h  |   1 +
 .../amd/display/dc/dml/dcn301/dcn301_fpu.c|  74 ++
 .../drm/amd/display/dc/dml/dcn31/dcn31_fpu.c  |  11 +
 .../drm/amd/display/dc/dml/dcn31/dcn31_fpu.h  |   3 +
 16 files changed, 423 insertions(+), 398 deletions(-)

-- 
2.35.1



[PATCH v2] drm/panel-edp: Add panel entry for B120XAN01.0

2022-07-20 Thread Nícolas F . R . A . Prado
Add panel identification entry for the AUO B120XAN01.0 (product ID:
0x1062) panel.

Signed-off-by: Nícolas F. R. A. Prado 

---
v1: https://lore.kernel.org/all/20220719203857.1488831-3-nfrapr...@collabora.com

Changes in v2:
- Move entry to the top so it respects the sorting

 drivers/gpu/drm/panel/panel-edp.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/panel/panel-edp.c 
b/drivers/gpu/drm/panel/panel-edp.c
index b3536d8600f4..e85d0c56f4a5 100644
--- a/drivers/gpu/drm/panel/panel-edp.c
+++ b/drivers/gpu/drm/panel/panel-edp.c
@@ -1876,6 +1876,7 @@ static const struct panel_delay delay_200_500_e200 = {
  * Sort first by vendor, then by product ID.
  */
 static const struct edp_panel_entry edp_panels[] = {
+   EDP_PANEL_ENTRY('A', 'U', 'O', 0x1062, _200_500_e50, 
"B120XAN01.0"),
EDP_PANEL_ENTRY('A', 'U', 'O', 0x405c, _b116xak01.delay, 
"B116XAK01"),
EDP_PANEL_ENTRY('A', 'U', 'O', 0x615c, _200_500_e50, 
"B116XAN06.1"),
EDP_PANEL_ENTRY('A', 'U', 'O', 0x8594, _200_500_e50, 
"B133UAN01.0"),
-- 
2.37.0



Re: [PATCH v4] drm/msm/dp: make eDP panel as the first connected connector

2022-07-20 Thread Abhinav Kumar




On 7/6/2022 12:32 PM, Kuogee Hsieh wrote:

Some userspace presumes that the first connected connector is the main
display, where it's supposed to display e.g. the login screen. For
laptops, this should be the main panel.

This patch call drm_helper_move_panel_connectors_to_head() after
drm_bridge_connector_init() to make sure eDP stay at head of
connected connector list. This fixes unexpected corruption happen
at eDP panel if eDP is not placed at head of connected connector
list.

Changes in v2:
-- move drm_helper_move_panel_connectors_to_head() to
dpu_kms_drm_obj_init()

Changes in v4:
-- move drm_helper_move_panel_connectors_to_head() to msm_drm_init()

Signed-off-by: Kuogee Hsieh 

Fixes: c8afe684c95c ("drm/msm: basic KMS driver for snapdragon")

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

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 4a3dda2..4d518c2 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -419,6 +419,8 @@ static int msm_drm_init(struct device *dev, const struct 
drm_driver *drv)
}
}
  
+	drm_helper_move_panel_connectors_to_head(ddev);

+
ddev->mode_config.funcs = _config_funcs;
ddev->mode_config.helper_private = _config_helper_funcs;
  


Re: [PATCH v4] drm/msm/dp: make eDP panel as the first connected connector

2022-07-20 Thread Abhinav Kumar




On 7/20/2022 11:47 AM, Abhinav Kumar wrote:



On 7/6/2022 12:32 PM, Kuogee Hsieh wrote:

Some userspace presumes that the first connected connector is the main
display, where it's supposed to display e.g. the login screen. For
laptops, this should be the main panel.

This patch call drm_helper_move_panel_connectors_to_head() after
drm_bridge_connector_init() to make sure eDP stay at head of
connected connector list. This fixes unexpected corruption happen
at eDP panel if eDP is not placed at head of connected connector
list.

Changes in v2:
-- move drm_helper_move_panel_connectors_to_head() to
    dpu_kms_drm_obj_init()

Changes in v4:
-- move drm_helper_move_panel_connectors_to_head() to msm_drm_init()

Signed-off-by: Kuogee Hsieh 

Fixes: c8afe684c95c ("drm/msm: basic KMS driver for snapdragon")


Lets drop the previous fixes tag and use this one as its more recent and 
appropriate as it added eDP support for sc7280.


Fixes: ef7837ff091c ("drm/msm/dp: Add DP controllers for sc7280")


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

diff --git a/drivers/gpu/drm/msm/msm_drv.c 
b/drivers/gpu/drm/msm/msm_drv.c

index 4a3dda2..4d518c2 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -419,6 +419,8 @@ static int msm_drm_init(struct device *dev, const 
struct drm_driver *drv)

  }
  }
+    drm_helper_move_panel_connectors_to_head(ddev);
+
  ddev->mode_config.funcs = _config_funcs;
  ddev->mode_config.helper_private = _config_helper_funcs;


Re: [PATCH 1/3] drm/panel-edp: Add panel entry for R140NWF5 RH

2022-07-20 Thread Nícolas F . R . A . Prado
On Wed, Jul 20, 2022 at 09:49:35AM +0200, AngeloGioacchino Del Regno wrote:
> Il 20/07/22 00:40, Doug Anderson ha scritto:
> > Hi,
> > 
> > On Tue, Jul 19, 2022 at 1:39 PM Nícolas F. R. A. Prado
> >  wrote:
> > > 
> > > Add panel identification entry for the IVO R140NWF5 RH (product ID:
> > > 0x057d) panel.
> > > 
> > > Signed-off-by: Nícolas F. R. A. Prado 
> > > 
> > > ---
> > > The comments on the driver indicate that the T3 timing should be set on
> > > hpd_absent, while hpd_reliable would have a shorter time just while the
> > > HPD line stabilizes on low after power is supplied.
> > 
> > Right. Ideally hpd_reliable is 0 unless you've got a badly-designed panel.
> > 
> > 
> > > But can we really assume that the HPD line will be reliable at all
> > > before the DDIC is done booting up, at which point the HPD line is
> > > brought up? IOW, shouldn't we always delay T3 (by setting hpd_reliable =
> > > T3), since only then we're really sure that the DDIC is done setting up
> > > and the HPD line is reliable?
> > 
> > If the panel is hooked up properly, then the HPD pin should be pulled
> > low at the start and then should only go high after the panel is ready
> > for us to talk to it, right? So it's not like the DDIC has to boot up
> > and actively init the state. I would assume that the initial state of
> > the "HPD output" from the panel's IC would be one of the following:
> > * A floating input.
> > * A pulled down input.
> > * An output driven low.
> > 
> > In any of those cases just adding a pull down on the line would be
> > enough to ensure that the HPD line is reliable until the panel comes
> > around and actively drives the line high.
> > 
> > Remember, this is eDP and it's not something that's hot-plugged, so
> > there's no debouncing involved and in a properly designed system there
> > should be no time needed for the signal to stabilize. I would also
> > point out that on the oficial eDP docs the eDP timing diagram doesn't
> > show the initial state of "HPD" as "unknown". It shows it as low.
> > 
> > Now, that all being said, I have seen at least one panel that glitched
> > itself at bootup. After you powered it on it would blip its HPD line
> > high before it had actually finished booting. Then the HPD would go
> > low again before finally going high after the panel finished booting.
> > This is the reason for "hpd_reliable".
> > 
> > If you've got a board with a well-designed panel but the hookup
> > between the panel and the board is wrong (maybe the board is missing a
> > pulldown on the HPD line?) then you can just set the "no-hpd" property
> > for your board. That will tell the kernel to just always delay the
> > "hpd-absent" delay.
> > 

Thank you for the detailed explanation, this does clear all doubts from what me
and Angelo were discussing.

> 
> We were concerned exactly about glitchy HPD during DDIC init, as I didn't
> want to trust it because the only testing we could do was on just two units...
> 
> ...but if you're sure that I was too much paranoid about that, that's good,
> as it means I will be a bit more "relaxed" on this topic next time :-)
> 
> > > I've set the T3 delay to hpd_absent in this series, following what's
> > > instructed in the comments, but I'd like to discuss whether we shouldn't
> > > be setting T3 on hpd_reliable instead, for all panels, to be on the
> > > safer side.
> > 
> > The way it's specified right now is more flexible, though, isn't it?
> > This way if you're on a board where the HPD truly _isn't_ stable then
> > you can just set the "no-hpd" and it will automatically use the
> > "hpd_absent" delay, right?
> > 

Yes, indeed. I just wasn't sure that flexibility brought us anything, but after
your explanation above it makes much more sense now, thanks!

> 
> For Chromebooks, that's totally doable, thanks to the bootloader seeking for
> proper machine compatibles, so yes I agree with that.
> 
> > 
> > >   drivers/gpu/drm/panel/panel-edp.c | 8 
> > >   1 file changed, 8 insertions(+)
> > > 
> > > diff --git a/drivers/gpu/drm/panel/panel-edp.c 
> > > b/drivers/gpu/drm/panel/panel-edp.c
> > > index 3626469c4cc2..675d793d925e 100644
> > > --- a/drivers/gpu/drm/panel/panel-edp.c
> > > +++ b/drivers/gpu/drm/panel/panel-edp.c
> > > @@ -1854,6 +1854,12 @@ static const struct panel_delay delay_100_500_e200 
> > > = {
> > >  .enable = 200,
> > >   };
> > > 
> > > +static const struct panel_delay delay_200_500_e200 = {
> > > +   .hpd_absent = 200,
> > > +   .unprepare = 500,
> > > +   .enable = 200,
> > > +};
> > > +
> > >   #define EDP_PANEL_ENTRY(vend_chr_0, vend_chr_1, vend_chr_2, product_id, 
> > > _delay, _name) \
> > >   { \
> > >  .name = _name, \
> > > @@ -1882,6 +1888,8 @@ static const struct edp_panel_entry edp_panels[] = {
> > > 
> > >  EDP_PANEL_ENTRY('C', 'M', 'N', 0x114c, 
> > > _n116bca_ea1.delay, "N116BCA-EA1"),
> > > 
> > > +   EDP_PANEL_ENTRY('I', 'V', 'O', 0x057d, _200_500_e200, 
> > > "R140NWF5 

Re: [PATCH 2/3] drm/panel-edp: Add panel entry for B120XAN01.0

2022-07-20 Thread Nícolas F . R . A . Prado
On Tue, Jul 19, 2022 at 03:41:43PM -0700, Doug Anderson wrote:
> Hi,
> 
> On Tue, Jul 19, 2022 at 1:39 PM Nícolas F. R. A. Prado
>  wrote:
> >
> > Add panel identification entry for the AUO B120XAN01.0 (product ID:
> > 0x1062) panel.
> >
> > Signed-off-by: Nícolas F. R. A. Prado 
> > ---
> >
> >  drivers/gpu/drm/panel/panel-edp.c | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/drivers/gpu/drm/panel/panel-edp.c 
> > b/drivers/gpu/drm/panel/panel-edp.c
> > index 675d793d925e..152e00eb846f 100644
> > --- a/drivers/gpu/drm/panel/panel-edp.c
> > +++ b/drivers/gpu/drm/panel/panel-edp.c
> > @@ -1879,6 +1879,7 @@ static const struct edp_panel_entry edp_panels[] = {
> > EDP_PANEL_ENTRY('A', 'U', 'O', 0x405c, _b116xak01.delay, 
> > "B116XAK01"),
> > EDP_PANEL_ENTRY('A', 'U', 'O', 0x615c, _200_500_e50, 
> > "B116XAN06.1"),
> > EDP_PANEL_ENTRY('A', 'U', 'O', 0x8594, _200_500_e50, 
> > "B133UAN01.0"),
> > +   EDP_PANEL_ENTRY('A', 'U', 'O', 0x1062, _200_500_e50, 
> > "B120XAN01.0"),
> 
>  * Sort first by vendor, then by product ID.
> 
> 0x1062 sorts at the top of the AUO panels, not at the bottom.

Right. Will fix on v2.

Thanks,
Nícolas


Re: [Freedreno] [PATCH v2 3/7] drm/msm: Fix cx collapse issue during recovery

2022-07-20 Thread Rob Clark
On Tue, Jul 12, 2022 at 12:15 PM Akhil P Oommen
 wrote:
>
> On 7/12/2022 10:14 PM, Rob Clark wrote:
> > On Mon, Jul 11, 2022 at 10:05 PM Akhil P Oommen
> >  wrote:
> >> On 7/12/2022 4:52 AM, Doug Anderson wrote:
> >>> Hi,
> >>>
> >>> On Fri, Jul 8, 2022 at 11:00 PM Akhil P Oommen  
> >>> wrote:
>  There are some hardware logic under CX domain. For a successful
>  recovery, we should ensure cx headswitch collapses to ensure all the
>  stale states are cleard out. This is especially true to for a6xx family
>  where we can GMU co-processor.
> 
>  Currently, cx doesn't collapse due to a devlink between gpu and its
>  smmu. So the *struct gpu device* needs to be runtime suspended to ensure
>  that the iommu driver removes its vote on cx gdsc.
> 
>  Signed-off-by: Akhil P Oommen 
>  ---
> 
>  (no changes since v1)
> 
> drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 16 ++--
> drivers/gpu/drm/msm/msm_gpu.c |  2 --
> 2 files changed, 14 insertions(+), 4 deletions(-)
> 
>  diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
>  b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>  index 4d50110..7ed347c 100644
>  --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>  +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
>  @@ -1278,8 +1278,20 @@ static void a6xx_recover(struct msm_gpu *gpu)
> */
>    gmu_write(_gpu->gmu, REG_A6XX_GMU_GMU_PWR_COL_KEEPALIVE, 
>  0);
> 
>  -   gpu->funcs->pm_suspend(gpu);
>  -   gpu->funcs->pm_resume(gpu);
>  +   /*
>  +* Now drop all the pm_runtime usage count to allow cx gdsc to 
>  collapse.
>  +* First drop the usage count from all active submits
>  +*/
>  +   for (i = gpu->active_submits; i > 0; i--)
>  +   pm_runtime_put(>pdev->dev);
>  +
>  +   /* And the final one from recover worker */
>  +   pm_runtime_put_sync(>pdev->dev);
>  +
>  +   for (i = gpu->active_submits; i > 0; i--)
>  +   pm_runtime_get(>pdev->dev);
>  +
>  +   pm_runtime_get_sync(>pdev->dev);
> >>> In response to v1, Rob suggested pm_runtime_force_suspend/resume().
> >>> Those seem like they would work to me, too. Why not use them?
> >> Quoting my previous response which I seem to have sent only to Freedreno
> >> list:
> >>
> >> "I believe it is supposed to be used only during system sleep state
> >> transitions. Btw, we don't want pm_runtime_get() calls from elsewhere to
> >> fail by disabling RPM here."
> > The comment about not wanting other runpm calls to fail is valid.. but
> > that is also solveable, ie. by holding a lock around runpm calls.
> > Which I think we need to do anyways, otherwise looping over
> > gpu->active_submits is racey..
> >
> > I think pm_runtime_force_suspend/resume() is the least-bad option.. or
> > at least I'm not seeing any obvious alternative that is better
> >
> > BR,
> > -R
> We are holding gpu->lock here which will block further submissions from
> scheduler. Will active_submits still race?
>
> It is possible that there is another thread which successfully completed
> pm_runtime_get() and while it access the hardware, we pulled the plug on
> regulator/clock here. That will result in obvious device crash. So I can
> think of 2 solutions:
>
> 1. wrap *every* pm_runtime_get/put with a mutex. Something like:
>  mutex_lock();
>  pm_runtime_get();
>  < ... access hardware here >>
>  pm_runtime_put();
>  mutex_unlock();
>
> 2. Drop runtime votes from every submit in recover worker and wait/poll
> for regulator to collapse in case there are transient votes on
> regulator  from other threads/subsystems.
>
> Option (2) seems simpler to me.  What do you think?
>

But I think without #1 you could still be racing w/ some other path
that touches the hw, like devfreq, right.  They could be holding a
runpm ref, so even if you loop over active_submits decrementing the
runpm ref, it still doesn't drop to zero

BR,
-R


Re: [PATCH v2 09/13] drm/gem: Add LRU/shrinker helper

2022-07-20 Thread Rob Clark
On Tue, Jul 19, 2022 at 11:56 AM Dmitry Osipenko
 wrote:
>
> On 7/19/22 20:18, Rob Clark wrote:
> > +void
> > +drm_gem_lru_move_tail_locked(struct drm_gem_lru *lru, struct 
> > drm_gem_object *obj)
> > +{
> > + WARN_ON(!mutex_is_locked(lru->lock));
>
> Nit: What about lockdep_assert_held_once(>lock->base)) ?

ahh, good point.. I've switched it locally

BR,
-R

> Otherwise, looks good! I'll use it for the DRM-SHMEM shrinker after
> completing the work on the dma-buf locks.
>
> Reviewed-by: Dmitry Osipenko 
>
> --
> Best regards,
> Dmitry


Re: [PATCH drm-misc-next v5 4/4] drm/todo: remove task to rename CMA helpers

2022-07-20 Thread Sam Ravnborg
On Wed, Jul 20, 2022 at 05:35:32PM +0200, Danilo Krummrich wrote:
> Both, GEM and FB, CMA helpers were renamed to "GEM DMA" and "FB DMA",
> hence the task can be removed.
> 
> Acked-by: Thomas Zimmermann 
> Reviewed-by: Laurent Pinchart 
> Signed-off-by: Danilo Krummrich 

It is good to see that someone picks up a task fro the todo list!
Thanks for doing this tedious job.

Acked-by: Sam Ravnborg 


Re: [PATCH drm-misc-next v5 3/4] drm/gem: rename struct drm_gem_dma_object.{paddr => dma_addr}

2022-07-20 Thread Sam Ravnborg
On Wed, Jul 20, 2022 at 05:35:31PM +0200, Danilo Krummrich wrote:
> The field paddr of struct drm_gem_dma_object holds a DMA address, which
> might actually be a physical address. However, depending on the platform,
> it can also be a bus address or a virtual address managed by an IOMMU.
> 
> Hence, rename the field to dma_addr, which is more applicable.
> 
> In order to do this renaming the following coccinelle script was used:
> 
> ```
>   @@
>   struct drm_gem_dma_object *gem;
>   @@
> 
>   - gem->paddr
>   + gem->dma_addr
> 
>   @@
>   struct drm_gem_dma_object gem;
>   @@
> 
>   - gem.paddr
>   + gem.dma_addr
> 
>   @exists@
>   typedef dma_addr_t;
>   symbol paddr;
>   @@
> 
>   dma_addr_t paddr;
>   <...
>   - paddr
>   + dma_addr
>   ...>
> 
>   @@
>   symbol paddr;
>   @@
>   dma_addr_t
>   - paddr
>   + dma_addr
>   ;
> 
> ```
> 
> This patch is compile-time tested with:
> 
> ```
>   make ARCH={x86_64,arm,arm64} allyesconfig
>   make ARCH={x86_64,arm,arm64} drivers/gpu/drm`
> ```
> 
> Reviewed-by: Laurent Pinchart 
> Signed-off-by: Danilo Krummrich 
Acked-by: Sam Ravnborg 


Re: [PATCH drm-misc-next v5 2/4] drm/gem: rename GEM CMA helpers to GEM DMA helpers

2022-07-20 Thread Sam Ravnborg
Hi Danilo,

On Wed, Jul 20, 2022 at 05:31:26PM +0200, Danilo Krummrich wrote:
> Rename "GEM CMA" helpers to "GEM DMA" helpers - considering the
> hierarchy of APIs (mm/cma -> dma -> gem dma) calling them "GEM
> DMA" seems to be more applicable.
> 
> Besides that, commit e57924d4ae80 ("drm/doc: Task to rename CMA helpers")
> requests to rename the CMA helpers and implies that people seem to be
> confused about the naming.
> 
> In order to do this renaming the following script was used:
> 
> ```
>   #!/bin/bash
> 
>   DIRS="drivers/gpu include/drm Documentation/gpu"
> 
>   REGEX_SYM_UPPER="[0-9A-Z_\-]"
>   REGEX_SYM_LOWER="[0-9a-z_\-]"
> 
>   REGEX_GREP_UPPER="(${REGEX_SYM_UPPER}*)(GEM)_CMA_(${REGEX_SYM_UPPER}*)"
>   REGEX_GREP_LOWER="(${REGEX_SYM_LOWER}*)(gem)_cma_(${REGEX_SYM_LOWER}*)"
> 
>   REGEX_SED_UPPER="s/${REGEX_GREP_UPPER}/\1\2_DMA_\3/g"
>   REGEX_SED_LOWER="s/${REGEX_GREP_LOWER}/\1\2_dma_\3/g"
> 
>   # Find all upper case 'CMA' symbols and replace them with 'DMA'.
>   for ff in $(grep -REHl "${REGEX_GREP_UPPER}" $DIRS)
>   do
>  sed -i -E "$REGEX_SED_UPPER" $ff
>   done
> 
>   # Find all lower case 'cma' symbols and replace them with 'dma'.
>   for ff in $(grep -REHl "${REGEX_GREP_LOWER}" $DIRS)
>   do
>  sed -i -E "$REGEX_SED_LOWER" $ff
>   done
> 
>   # Replace all occurrences of 'CMA' / 'cma' in comments and
>   # documentation files with 'DMA' / 'dma'.
>   for ff in $(grep -RiHl " cma " $DIRS)
>   do
>   sed -i -E "s/ cma / dma /g" $ff
>   sed -i -E "s/ CMA / DMA /g" $ff
>   done
> 
>   # Rename all 'cma_obj's to 'dma_obj'.
>   for ff in $(grep -RiHl "cma_obj" $DIRS)
>   do
>   sed -i -E "s/cma_obj/dma_obj/g" $ff
>   done
> ```
> 
> Only a few more manual modifications were needed, e.g. reverting the
> following modifications in some DRM Kconfig files
> 
> -   select CMA if HAVE_DMA_CONTIGUOUS
> +   select DMA if HAVE_DMA_CONTIGUOUS
> 
> as well as manually picking the occurrences of 'CMA'/'cma' in comments and
> documentation which relate to "GEM CMA", but not "FB CMA".
> 
> Also drivers/gpu/drm/Makefile was fixed up manually after renaming
> drm_gem_cma_helper.c to drm_gem_dma_helper.c.
> 
> This patch is compile-time tested building a x86_64 kernel with
> `make allyesconfig && make drivers/gpu/drm`.
> 
> Acked-by: Thomas Zimmermann 
> Reviewed-by: Laurent Pinchart 
> Signed-off-by: Danilo Krummrich 

I did not spot any cases where the include looked like it is not needed,
so patch looks good.
Acked-by: Sam Ravnborg 


Re: [PATCH drm-misc-next v5 1/4] drm/fb: rename FB CMA helpers to FB DMA helpers

2022-07-20 Thread Sam Ravnborg
Hi Danilo,

On Wed, Jul 20, 2022 at 05:31:25PM +0200, Danilo Krummrich wrote:
> Rename "FB CMA" helpers to "FB DMA" helpers - considering the hierarchy
> of APIs (mm/cma -> dma -> fb dma) calling them "FB DMA" seems to be
> more applicable.
> 
> Besides that, commit e57924d4ae80 ("drm/doc: Task to rename CMA helpers")
> requests to rename the CMA helpers and implies that people seem to be
> confused about the naming.
> 
> In order to do this renaming the following script was used:
> 
> ```
>   #!/bin/bash
> 
>   DIRS="drivers/gpu include/drm Documentation/gpu"
> 
>   REGEX_SYM_UPPER="[0-9A-Z_\-]"
>   REGEX_SYM_LOWER="[0-9a-z_\-]"
> 
>   REGEX_GREP_UPPER="(${REGEX_SYM_UPPER}*)(FB)_CMA_(${REGEX_SYM_UPPER}*)"
>   REGEX_GREP_LOWER="(${REGEX_SYM_LOWER}*)(fb)_cma_(${REGEX_SYM_LOWER}*)"
> 
>   REGEX_SED_UPPER="s/${REGEX_GREP_UPPER}/\1\2_DMA_\3/g"
>   REGEX_SED_LOWER="s/${REGEX_GREP_LOWER}/\1\2_dma_\3/g"
> 
>   # Find all upper case 'CMA' symbols and replace them with 'DMA'.
>   for ff in $(grep -REHl "${REGEX_GREP_UPPER}" $DIRS)
>   do
>  sed -i -E "$REGEX_SED_UPPER" $ff
>   done
> 
>   # Find all lower case 'cma' symbols and replace them with 'dma'.
>   for ff in $(grep -REHl "${REGEX_GREP_LOWER}" $DIRS)
>   do
>  sed -i -E "$REGEX_SED_LOWER" $ff
>   done
> 
>   # Replace all occurrences of 'CMA' / 'cma' in comments and
>   # documentation files with 'DMA' / 'dma'.
>   for ff in $(grep -RiHl " cma " $DIRS)
>   do
>   sed -i -E "s/ cma / dma /g" $ff
>   sed -i -E "s/ CMA / DMA /g" $ff
>   done
> ```
> 
> Only a few more manual modifications were needed, e.g. reverting the
> following modifications in some DRM Kconfig files
> 
> -   select CMA if HAVE_DMA_CONTIGUOUS
> +   select DMA if HAVE_DMA_CONTIGUOUS
> 
> as well as manually picking the occurrences of 'CMA'/'cma' in comments and
> documentation which relate to "FB CMA", but not "GEM CMA".
> 
> This patch is compile-time tested building a x86_64 kernel with
> `make allyesconfig && make drivers/gpu/drm`.
> 
> Acked-by: Thomas Zimmermann 
> Reviewed-by: Laurent Pinchart 
> Signed-off-by: Danilo Krummrich 

For the most part I like the patch.
But there is a few cases I would like to see fixed.


> diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
> index e89ae0ec60eb..fab18135f12b 100644
> --- a/drivers/gpu/drm/arm/hdlcd_drv.c
> +++ b/drivers/gpu/drm/arm/hdlcd_drv.c
> @@ -25,7 +25,7 @@
>  #include 
>  #include 
>  #include 
> -#include 
> +#include 
>  #include 
>  #include 
>  #include 


The only change in the file above is the rename of the include file.
This is a strong hint that the include is not needed and the correct fix
is to drop the include. There are more cases like the above.

This is a manual process on top of what you could automate, but then I
suggest to identify them and remove the includes before you change the
file name.

Or if anyone applies the patches then at least do it in a follow-up at
the places will never be easier to spot.

So with this cleanup done either before or after this patch.
Acked-by: Sam Ravnborg 

Sam


Re: [Intel-gfx] [PATCH] drm/i915/selftests: Fix comment typo

2022-07-20 Thread Andrzej Hajda

On 16.07.2022 06:05, Jason Wang wrote:

Fix the double `wait' typo in comment.

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

diff --git a/drivers/gpu/drm/i915/selftests/i915_request.c 
b/drivers/gpu/drm/i915/selftests/i915_request.c
index c56a0c2cd2f7..ec05f578a698 100644
--- a/drivers/gpu/drm/i915/selftests/i915_request.c
+++ b/drivers/gpu/drm/i915/selftests/i915_request.c
@@ -971,7 +971,7 @@ static struct i915_vma *empty_batch(struct drm_i915_private 
*i915)
if (err)
goto err;
  
-	/* Force the wait wait now to avoid including it in the benchmark */

+   /* Force the wait now to avoid including it in the benchmark */
err = i915_vma_sync(vma);
if (err)
goto err_pin;


Reviewed-by: Andrzej Hajda 

Regards
Andrzej


Re: [PATCH v2 14/29] drm/radeon: Register ACPI video backlight when skipping radeon backlight registration

2022-07-20 Thread Alex Deucher
On Tue, Jul 12, 2022 at 3:40 PM Hans de Goede  wrote:
>
> Typically the acpi_video driver will initialize before radeon, which
> used to cause /sys/class/backlight/acpi_video0 to get registered and then
> radeon would register its own radeon_bl# device later. After which
> the drivers/acpi/video_detect.c code unregistered the acpi_video0 device
> to avoid there being 2 backlight devices.
>
> This means that userspace used to briefly see 2 devices and the
> disappearing of acpi_video0 after a brief time confuses the systemd
> backlight level save/restore code, see e.g.:
> https://bbs.archlinux.org/viewtopic.php?id=269920
>
> To fix this the ACPI video code has been modified to make backlight class
> device registration a separate step, relying on the drm/kms driver to
> ask for the acpi_video backlight registration after it is done setting up
> its native backlight device.
>
> Add a call to the new acpi_video_register_backlight() when radeon skips
> registering its own backlight device because of e.g. the firmware_flags
> or the acpi_video_get_backlight_type() return value. This ensures that
> if the acpi_video backlight device should be used, it will be available
> before the radeon drm_device gets registered with userspace.
>
> Signed-off-by: Hans de Goede 

Acked-by: Alex Deucher 

> ---
>  drivers/gpu/drm/radeon/radeon_encoders.c | 11 ++-
>  1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c 
> b/drivers/gpu/drm/radeon/radeon_encoders.c
> index 46549d5179ee..c1cbebb51be1 100644
> --- a/drivers/gpu/drm/radeon/radeon_encoders.c
> +++ b/drivers/gpu/drm/radeon/radeon_encoders.c
> @@ -30,6 +30,8 @@
>  #include 
>  #include 
>
> +#include 
> +
>  #include "radeon.h"
>  #include "radeon_atombios.h"
>  #include "radeon_legacy_encoders.h"
> @@ -167,7 +169,7 @@ static void radeon_encoder_add_backlight(struct 
> radeon_encoder *radeon_encoder,
> return;
>
> if (radeon_backlight == 0) {
> -   return;
> +   use_bl = false;
> } else if (radeon_backlight == 1) {
> use_bl = true;
> } else if (radeon_backlight == -1) {
> @@ -193,6 +195,13 @@ static void radeon_encoder_add_backlight(struct 
> radeon_encoder *radeon_encoder,
> else
> radeon_legacy_backlight_init(radeon_encoder, 
> connector);
> }
> +
> +   /*
> +* If there is no native backlight device (which may happen even when
> +* use_bl==true) try registering an ACPI video backlight device 
> instead.
> +*/
> +   if (!rdev->mode_info.bl_encoder)
> +   acpi_video_register_backlight();
>  }
>
>  void
> --
> 2.36.0
>


Re: [PATCH v2 13/29] drm/amdgpu: Register ACPI video backlight when skipping amdgpu backlight registration

2022-07-20 Thread Alex Deucher
On Tue, Jul 12, 2022 at 3:40 PM Hans de Goede  wrote:
>
> Typically the acpi_video driver will initialize before amdgpu, which
> used to cause /sys/class/backlight/acpi_video0 to get registered and then
> amdgpu would register its own amdgpu_bl# device later. After which
> the drivers/acpi/video_detect.c code unregistered the acpi_video0 device
> to avoid there being 2 backlight devices.
>
> This means that userspace used to briefly see 2 devices and the
> disappearing of acpi_video0 after a brief time confuses the systemd
> backlight level save/restore code, see e.g.:
> https://bbs.archlinux.org/viewtopic.php?id=269920
>
> To fix this the ACPI video code has been modified to make backlight class
> device registration a separate step, relying on the drm/kms driver to
> ask for the acpi_video backlight registration after it is done setting up
> its native backlight device.
>
> Add a call to the new acpi_video_register_backlight() when amdgpu skips
> registering its own backlight device because of either the firmware_flags
> or the acpi_video_get_backlight_type() return value. This ensures that
> if the acpi_video backlight device should be used, it will be available
> before the amdgpu drm_device gets registered with userspace.
>
> Signed-off-by: Hans de Goede 
> ---
>  drivers/gpu/drm/amd/amdgpu/atombios_encoders.c| 9 +++--
>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 ++
>  2 files changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c 
> b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
> index abf209e36fca..45cd9268b426 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
> +++ b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
> @@ -184,11 +184,11 @@ void amdgpu_atombios_encoder_init_backlight(struct 
> amdgpu_encoder *amdgpu_encode
> return;
>
> if (!(adev->mode_info.firmware_flags & 
> ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU))
> -   return;
> +   goto register_acpi_backlight;
>
> if (!acpi_video_backlight_use_native()) {
> DRM_INFO("Skipping amdgpu atom DIG backlight registration\n");
> -   return;
> +   goto register_acpi_backlight;
> }
>
> pdata = kmalloc(sizeof(struct amdgpu_backlight_privdata), GFP_KERNEL);
> @@ -225,6 +225,11 @@ void amdgpu_atombios_encoder_init_backlight(struct 
> amdgpu_encoder *amdgpu_encode
>  error:
> kfree(pdata);
> return;
> +
> +register_acpi_backlight:
> +   /* Try registering an ACPI video backlight device instead. */
> +   acpi_video_register_backlight();
> +   return;

Can drop the return here.  Either way,
Acked-by: Alex Deucher 

>  }
>
>  void
> 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 3b03a95e59a8..a667e66a9842 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -4054,6 +4054,8 @@ amdgpu_dm_register_backlight_device(struct 
> amdgpu_display_manager *dm)
>
> if (!acpi_video_backlight_use_native()) {
> DRM_INFO("Skipping amdgpu DM backlight registration\n");
> +   /* Try registering an ACPI video backlight device instead. */
> +   acpi_video_register_backlight();
> return;
> }
>
> --
> 2.36.0
>


Re: [PATCH v2 09/29] ACPI: video: Make backlight class device registration a separate step

2022-07-20 Thread Alex Deucher
On Tue, Jul 12, 2022 at 3:40 PM Hans de Goede  wrote:
>
> On x86/ACPI boards the acpi_video driver will usually initializing before

initializing -> initialize

> the kms driver (except i915). This causes /sys/class/backlight/acpi_video0
> to show up and then the kms driver registers its own native backlight
> device after which the drivers/acpi/video_detect.c code unregisters
> the acpi_video0 device (when acpi_video_get_backlight_type()==native).
>
> This means that userspace briefly sees 2 devices and the disappearing of
> acpi_video0 after a brief time confuses the systemd backlight level
> save/restore code, see e.g.:
> https://bbs.archlinux.org/viewtopic.php?id=269920
>
> To fix this make backlight class device registration a separate step
> done by a new acpi_video_register_backlight() function. The intend is for
> this to be called by the drm/kms driver *after* it is done setting up its
> own native backlight device. So that acpi_video_get_backlight_type() knows
> if a native backlight will be available or not at acpi_video backlight
> registration time, avoiding the add + remove dance.
>
> Note the new acpi_video_register_backlight() function is also called from
> a delayed work to ensure that the acpi_video backlight devices does get
> registered if necessary even if there is no drm/kms driver or when it is
> disabled.
>
> Signed-off-by: Hans de Goede 
> ---
>  drivers/acpi/acpi_video.c | 45 ---
>  include/acpi/video.h  |  2 ++
>  2 files changed, 44 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c
> index 6944794797a5..c4c3a9e7ce69 100644
> --- a/drivers/acpi/acpi_video.c
> +++ b/drivers/acpi/acpi_video.c
> @@ -31,6 +31,12 @@
>  #define ACPI_VIDEO_BUS_NAME"Video Bus"
>  #define ACPI_VIDEO_DEVICE_NAME "Video Device"
>
> +/*
> + * Display probing is known to take up to 5 seconds, so delay the fallback
> + * backlight registration by 5 seconds + 3 seconds for some extra margin.
> + */
> +#define ACPI_VIDEO_REGISTER_BACKLIGHT_DELAY(8 * HZ)
> +
>  #define MAX_NAME_LEN   20
>
>  MODULE_AUTHOR("Bruno Ducrot");
> @@ -81,6 +87,9 @@ static LIST_HEAD(video_bus_head);
>  static int acpi_video_bus_add(struct acpi_device *device);
>  static int acpi_video_bus_remove(struct acpi_device *device);
>  static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
> +static void acpi_video_bus_register_backlight_work(struct work_struct 
> *ignored);
> +static DECLARE_DELAYED_WORK(video_bus_register_backlight_work,
> +   acpi_video_bus_register_backlight_work);
>  void acpi_video_detect_exit(void);
>
>  /*
> @@ -1865,8 +1874,6 @@ static int acpi_video_bus_register_backlight(struct 
> acpi_video_bus *video)
> if (video->backlight_registered)
> return 0;
>
> -   acpi_video_run_bcl_for_osi(video);
> -
> if (acpi_video_get_backlight_type() != acpi_backlight_video)
> return 0;
>
> @@ -2092,7 +2099,11 @@ static int acpi_video_bus_add(struct acpi_device 
> *device)
> list_add_tail(>entry, _bus_head);
> mutex_unlock(_list_lock);
>
> -   acpi_video_bus_register_backlight(video);
> +   /*
> +* The userspace visible backlight_device gets registered separately
> +* from acpi_video_register_backlight().
> +*/
> +   acpi_video_run_bcl_for_osi(video);
> acpi_video_bus_add_notify_handler(video);
>
> return 0;
> @@ -2131,6 +2142,11 @@ static int acpi_video_bus_remove(struct acpi_device 
> *device)
> return 0;
>  }
>
> +static void acpi_video_bus_register_backlight_work(struct work_struct 
> *ignored)
> +{
> +   acpi_video_register_backlight();
> +}
> +
>  static int __init is_i740(struct pci_dev *dev)
>  {
> if (dev->device == 0x00D1)
> @@ -2241,6 +2257,17 @@ int acpi_video_register(void)
>  */
> register_count = 1;
>
> +   /*
> +* acpi_video_bus_add() skips registering the userspace visible
> +* backlight_device. The intend is for this to be registered by the
> +* drm/kms driver calling acpi_video_register_backlight() *after* it 
> is
> +* done setting up its own native backlight device. The delayed work
> +* ensures that acpi_video_register_backlight() always gets called
> +* eventually, in case there is no drm/kms driver or it is disabled.
> +*/
> +   schedule_delayed_work(_bus_register_backlight_work,
> + ACPI_VIDEO_REGISTER_BACKLIGHT_DELAY);
> +
>  leave:
> mutex_unlock(_count_mutex);
> return ret;
> @@ -2251,6 +2278,7 @@ void acpi_video_unregister(void)
>  {
> mutex_lock(_count_mutex);
> if (register_count) {
> +   cancel_delayed_work_sync(_bus_register_backlight_work);
> acpi_bus_unregister_driver(_video_bus);
> register_count = 0;
> 

[PATCH v5 2/4] drm/i915/fbdev: suspend HPD before fbdev unregistration

2022-07-20 Thread Andrzej Hajda
HPD event after fbdev unregistration can cause registration of deferred
fbdev which will not be unregistered later, causing use-after-free.
To avoid it HPD handling should be suspended before fbdev unregistration.

It should fix following GPF:
[272.634530] general protection fault, probably for non-canonical address 
0x6b6b6b6b6b6b6b6b:  [#1] PREEMPT SMP NOPTI
[272.634536] CPU: 0 PID: 6030 Comm: i915_selftest Tainted: G U
5.18.0-rc5-CI_DRM_11603-g12dccf4f5eef+ #1
[272.634541] Hardware name: Intel Corporation Raptor Lake Client Platform/RPL-S 
ADP-S DDR5 UDIMM CRB, BIOS RPLSFWI1.R00.2397.A01.2109300731 09/30/2021
[272.634545] RIP: 0010:fb_do_apertures_overlap.part.14+0x26/0x60
...
[272.634582] Call Trace:
[272.634583]  
[272.634585]  do_remove_conflicting_framebuffers+0x59/0xa0
[272.634589]  remove_conflicting_framebuffers+0x2d/0xc0
[272.634592]  remove_conflicting_pci_framebuffers+0xc8/0x110
[272.634595]  drm_aperture_remove_conflicting_pci_framebuffers+0x52/0x70
[272.634604]  i915_driver_probe+0x63a/0xdd0 [i915]

Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/5329
Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/5510
Signed-off-by: Andrzej Hajda 
Reviewed-by: Arun R Murthy 
---
 drivers/gpu/drm/i915/display/intel_fbdev.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c 
b/drivers/gpu/drm/i915/display/intel_fbdev.c
index 221336178991f0..b682fd72d4bf25 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
@@ -573,7 +573,8 @@ void intel_fbdev_unregister(struct drm_i915_private 
*dev_priv)
if (!ifbdev)
return;
 
-   cancel_work_sync(_priv->fbdev_suspend_work);
+   intel_fbdev_set_suspend(_priv->drm, FBINFO_STATE_SUSPENDED, true);
+
if (!current_is_async())
intel_fbdev_sync(ifbdev);
 
-- 
2.25.1



[PATCH v5 4/4] drm/i915/fbdev: do not create fbdev if HPD is suspended

2022-07-20 Thread Andrzej Hajda
In case of deferred FB setup core can try to create new
framebuffer. Disallow it if hpd_suspended flag is set.

Signed-off-by: Andrzej Hajda 
---
 drivers/gpu/drm/i915/display/intel_fbdev.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c 
b/drivers/gpu/drm/i915/display/intel_fbdev.c
index b682fd72d4bf25..7cd3eb9b7729f9 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
@@ -210,6 +210,12 @@ static int intelfb_create(struct drm_fb_helper *helper,
struct drm_i915_gem_object *obj;
int ret;
 
+   mutex_lock(>hpd_lock);
+   ret = ifbdev->hpd_suspended ? -EAGAIN : 0;
+   mutex_unlock(>hpd_lock);
+   if (ret)
+   return ret;
+
if (intel_fb &&
(sizes->fb_width > intel_fb->base.width ||
 sizes->fb_height > intel_fb->base.height)) {
-- 
2.25.1



[PATCH v5 3/4] drm/i915/display: add hotplug.suspended flag

2022-07-20 Thread Andrzej Hajda
HPD events during driver removal can be generated by hardware and
software frameworks - drm_dp_mst, the former we can avoid by disabling
interrupts, the latter can be triggered by any drm_dp_mst transaction,
and this is too late. Introducing suspended flag allows to solve this
chicken-egg problem.

Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/5950
Signed-off-by: Andrzej Hajda 
Reviewed-by: Arun R Murthy 
---
 drivers/gpu/drm/i915/display/intel_display.c |  2 +-
 drivers/gpu/drm/i915/display/intel_hotplug.c | 11 ++-
 drivers/gpu/drm/i915/display/intel_hotplug.h |  2 +-
 drivers/gpu/drm/i915/i915_driver.c   |  4 ++--
 drivers/gpu/drm/i915/i915_drv.h  |  2 ++
 5 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index ec8e59b3adaea7..b969635b212ba9 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -9008,7 +9008,7 @@ void intel_modeset_driver_remove_noirq(struct 
drm_i915_private *i915)
intel_dp_mst_suspend(i915);
 
/* MST is the last user of HPD work */
-   intel_hpd_cancel_work(i915);
+   intel_hpd_suspend(i915);
 
/* poll work can call into fbdev, hence clean that up afterwards */
intel_fbdev_fini(i915);
diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.c 
b/drivers/gpu/drm/i915/display/intel_hotplug.c
index 5f8b4f481cff9a..e1d384cb99df6b 100644
--- a/drivers/gpu/drm/i915/display/intel_hotplug.c
+++ b/drivers/gpu/drm/i915/display/intel_hotplug.c
@@ -303,6 +303,8 @@ static void i915_digport_work_func(struct work_struct *work)
u32 old_bits = 0;
 
spin_lock_irq(_priv->irq_lock);
+   if (dev_priv->hotplug.suspended)
+   return spin_unlock_irq(_priv->irq_lock);
long_port_mask = dev_priv->hotplug.long_port_mask;
dev_priv->hotplug.long_port_mask = 0;
short_port_mask = dev_priv->hotplug.short_port_mask;
@@ -353,6 +355,8 @@ void intel_hpd_trigger_irq(struct intel_digital_port 
*dig_port)
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
 
spin_lock_irq(>irq_lock);
+   if (i915->hotplug.suspended)
+   return spin_unlock_irq(>irq_lock);
i915->hotplug.short_port_mask |= BIT(dig_port->base.port);
spin_unlock_irq(>irq_lock);
 
@@ -475,6 +479,9 @@ void intel_hpd_irq_handler(struct drm_i915_private 
*dev_priv,
 
spin_lock(_priv->irq_lock);
 
+   if (dev_priv->hotplug.suspended)
+   return spin_unlock(_priv->irq_lock);
+
/*
 * Determine whether ->hpd_pulse() exists for each pin, and
 * whether we have a short or a long pulse. This is needed
@@ -603,6 +610,7 @@ void intel_hpd_init(struct drm_i915_private *dev_priv)
 * just to make the assert_spin_locked checks happy.
 */
spin_lock_irq(_priv->irq_lock);
+   dev_priv->hotplug.suspended = false;
intel_hpd_irq_setup(dev_priv);
spin_unlock_irq(_priv->irq_lock);
 }
@@ -721,13 +729,14 @@ void intel_hpd_init_work(struct drm_i915_private 
*dev_priv)
  intel_hpd_irq_storm_reenable_work);
 }
 
-void intel_hpd_cancel_work(struct drm_i915_private *dev_priv)
+void intel_hpd_suspend(struct drm_i915_private *dev_priv)
 {
if (!HAS_DISPLAY(dev_priv))
return;
 
spin_lock_irq(_priv->irq_lock);
 
+   dev_priv->hotplug.suspended = true;
dev_priv->hotplug.long_port_mask = 0;
dev_priv->hotplug.short_port_mask = 0;
dev_priv->hotplug.event_bits = 0;
diff --git a/drivers/gpu/drm/i915/display/intel_hotplug.h 
b/drivers/gpu/drm/i915/display/intel_hotplug.h
index b87e95d606e668..54bddc4dd63421 100644
--- a/drivers/gpu/drm/i915/display/intel_hotplug.h
+++ b/drivers/gpu/drm/i915/display/intel_hotplug.h
@@ -23,7 +23,7 @@ void intel_hpd_irq_handler(struct drm_i915_private *dev_priv,
 void intel_hpd_trigger_irq(struct intel_digital_port *dig_port);
 void intel_hpd_init(struct drm_i915_private *dev_priv);
 void intel_hpd_init_work(struct drm_i915_private *dev_priv);
-void intel_hpd_cancel_work(struct drm_i915_private *dev_priv);
+void intel_hpd_suspend(struct drm_i915_private *dev_priv);
 enum hpd_pin intel_hpd_pin_default(struct drm_i915_private *dev_priv,
   enum port port);
 bool intel_hpd_disable(struct drm_i915_private *dev_priv, enum hpd_pin pin);
diff --git a/drivers/gpu/drm/i915/i915_driver.c 
b/drivers/gpu/drm/i915/i915_driver.c
index be932a6d9c7dfa..5f87719a74337c 100644
--- a/drivers/gpu/drm/i915/i915_driver.c
+++ b/drivers/gpu/drm/i915/i915_driver.c
@@ -1079,7 +1079,7 @@ void i915_driver_shutdown(struct drm_i915_private *i915)
intel_dp_mst_suspend(i915);
 
intel_runtime_pm_disable_interrupts(i915);
-   intel_hpd_cancel_work(i915);
+   intel_hpd_suspend(i915);
 
intel_suspend_encoders(i915);
  

[PATCH v5 1/4] drm/i915/hpd: postpone HPD cancel work after last user suspension

2022-07-20 Thread Andrzej Hajda
i915->hotplug.dig_port_work can be queued from intel_hpd_irq_handler
called by IRQ handler or by intel_hpd_trigger_irq called from dp_mst.
Since dp_mst is suspended after irq handler uninstall, a cleaner approach
is to cancel hpd work after intel_dp_mst_suspend, otherwise we risk
use-after-free.

It should fix following WARNINGS:
[283.405824] cpu_latency_qos_update_request called for unknown object
[283.405866] WARNING: CPU: 2 PID: 240 at kernel/power/qos.c:296 
cpu_latency_qos_update_request+0x2d/0x100
[283.405912] CPU: 2 PID: 240 Comm: kworker/u64:9 Not tainted 
5.18.0-rc6-Patchwork_103738v3-g1672d1c43e43+ #1
[283.405915] Hardware name: Intel Corporation Raptor Lake Client Platform/RPL-S 
ADP-S DDR5 UDIMM CRB, BIOS RPLSFWI1.R00.2397.A01.2109300731 09/30/2021
[283.405916] Workqueue: i915-dp i915_digport_work_func [i915]
[283.406020] RIP: 0010:cpu_latency_qos_update_request+0x2d/0x100
...
[283.406040] Call Trace:
[283.406041]  
[283.406044]  intel_dp_aux_xfer+0x60e/0x8e0 [i915]
[283.406131]  ? finish_swait+0x80/0x80
[283.406139]  intel_dp_aux_transfer+0xc5/0x2b0 [i915]
[283.406218]  drm_dp_dpcd_access+0x79/0x130 [drm_display_helper]
[283.406227]  drm_dp_dpcd_read+0xe2/0xf0 [drm_display_helper]
[283.406233]  intel_dp_hpd_pulse+0x134/0x570 [i915]
[283.406308]  ? __down_killable+0x70/0x140
[283.406313]  i915_digport_work_func+0xba/0x150 [i915]

Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/4586
Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/5558
Signed-off-by: Andrzej Hajda 
Reviewed-by: Arun R Murthy 
---
 drivers/gpu/drm/i915/display/intel_display.c | 3 +++
 drivers/gpu/drm/i915/i915_irq.c  | 1 -
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 903226e2a6260d..ec8e59b3adaea7 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -9007,6 +9007,9 @@ void intel_modeset_driver_remove_noirq(struct 
drm_i915_private *i915)
 */
intel_dp_mst_suspend(i915);
 
+   /* MST is the last user of HPD work */
+   intel_hpd_cancel_work(i915);
+
/* poll work can call into fbdev, hence clean that up afterwards */
intel_fbdev_fini(i915);
 
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 73cebc6aa65072..db14787aef95dd 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -4597,7 +4597,6 @@ void intel_irq_uninstall(struct drm_i915_private 
*dev_priv)
 
free_irq(irq, dev_priv);
 
-   intel_hpd_cancel_work(dev_priv);
dev_priv->runtime_pm.irqs_enabled = false;
 }
 
-- 
2.25.1



[PATCH v5 0/4] drm/i915/display: stop HPD workers before display driver unregister

2022-07-20 Thread Andrzej Hajda
Hi Jani, Ville, Arun,

This patchset is replacement of patch
"drm/i915/display: disable HPD workers before display driver unregister" [1].
Ive decided to split patch into two parts - fbdev and MST, there are different
issues.
Ive also dropped shutdown path, as it has slightly different requirements,
and more importantly I am not able to test properly.

v2 (thx Arun for review):
  - reword of commit message (Arun)
  - intel_fbdev_hpd_set_suspend replaced with intel_fbdev_set_suspend (Arun)
v3:
  - new patch adding suspended flag, to handle
https://gitlab.freedesktop.org/drm/intel/-/issues/5950
v4:
  - check suspend flag also in i915_digport_work_func
v5:
  - added patch blocking FB creation in case HPD is supended,
  - added R-B from Arun to patch 3, thx

[1]: https://patchwork.freedesktop.org/series/103811/

Regards
Andrzej


Andrzej Hajda (4):
  drm/i915/hpd: postpone HPD cancel work after last user suspension
  drm/i915/fbdev: suspend HPD before fbdev unregistration
  drm/i915/display: add hotplug.suspended flag
  drm/i915/fbdev: do not create fbdev if HPD is suspended

 drivers/gpu/drm/i915/display/intel_display.c |  3 +++
 drivers/gpu/drm/i915/display/intel_fbdev.c   |  9 -
 drivers/gpu/drm/i915/display/intel_hotplug.c | 11 ++-
 drivers/gpu/drm/i915/display/intel_hotplug.h |  2 +-
 drivers/gpu/drm/i915/i915_driver.c   |  4 ++--
 drivers/gpu/drm/i915/i915_drv.h  |  2 ++
 drivers/gpu/drm/i915/i915_irq.c  |  1 -
 7 files changed, 26 insertions(+), 6 deletions(-)

-- 
2.25.1



Re: [PATCH v2 03/29] drm/amdgpu: Don't register backlight when another backlight should be used

2022-07-20 Thread Alex Deucher
On Wed, Jul 20, 2022 at 12:44 PM Alex Deucher  wrote:
>
> On Tue, Jul 12, 2022 at 3:39 PM Hans de Goede  wrote:
> >
> > Before this commit when we want userspace to use the acpi_video backlight
> > device we register both the GPU's native backlight device and acpi_video's
> > firmware acpi_video# backlight device. This relies on userspace preferring
> > firmware type backlight devices over native ones.
> >
> > Registering 2 backlight devices for a single display really is
> > undesirable, don't register the GPU's native backlight device when
> > another backlight device should be used.
> >
> > Changes in v2:
> > - To avoid linker errors when amdgpu is builtin and video_detect.c is in
> >   a module, select ACPI_VIDEO and its deps if ACPI && X86 are enabled.
> >   When these are not set, ACPI_VIDEO is disabled, ensuring the stubs
> >   from acpi/video.h will be used.
> >
> > Signed-off-by: Hans de Goede 
>
> Acked-by: Alex Deucher 

Actually, can you use dev_info for the messages below rather than
DRM_INFO?  That makes it easier to tell which GPU is affected in a
multi-GPU system.  With that changed,
Acked-by: Alex Deucher 

>
> > ---
> >  drivers/gpu/drm/Kconfig   | 6 ++
> >  drivers/gpu/drm/amd/amdgpu/atombios_encoders.c| 7 +++
> >  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 +++
> >  3 files changed, 20 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> > index aaa7ad1f0614..d65119860760 100644
> > --- a/drivers/gpu/drm/Kconfig
> > +++ b/drivers/gpu/drm/Kconfig
> > @@ -258,6 +258,12 @@ config DRM_AMDGPU
> > select HWMON
> > select BACKLIGHT_CLASS_DEVICE
> > select INTERVAL_TREE
> > +   # amdgpu depends on ACPI_VIDEO when X86 and ACPI are both enabled
> > +   # for select to work, ACPI_VIDEO's dependencies must also be 
> > selected
> > +   select INPUT if ACPI && X86
> > +   select X86_PLATFORM_DEVICES if ACPI && X86
> > +   select ACPI_WMI if ACPI && X86
> > +   select ACPI_VIDEO if ACPI && X86
> > help
> >   Choose this option if you have a recent AMD Radeon graphics card.
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c 
> > b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
> > index fa7421afb9a6..abf209e36fca 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
> > @@ -26,6 +26,8 @@
> >
> >  #include 
> >
> > +#include 
> > +
> >  #include 
> >  #include 
> >  #include "amdgpu.h"
> > @@ -184,6 +186,11 @@ void amdgpu_atombios_encoder_init_backlight(struct 
> > amdgpu_encoder *amdgpu_encode
> > if (!(adev->mode_info.firmware_flags & 
> > ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU))
> > return;
> >
> > +   if (!acpi_video_backlight_use_native()) {
> > +   DRM_INFO("Skipping amdgpu atom DIG backlight 
> > registration\n");
> > +   return;
> > +   }
> > +
> > pdata = kmalloc(sizeof(struct amdgpu_backlight_privdata), 
> > GFP_KERNEL);
> > if (!pdata) {
> > DRM_ERROR("Memory allocation failed\n");
> > 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 5eb111d35793..3b03a95e59a8 100644
> > --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> > @@ -86,6 +86,8 @@
> >  #include 
> >  #include 
> >
> > +#include 
> > +
> >  #include "ivsrcid/dcn/irqsrcs_dcn_1_0.h"
> >
> >  #include "dcn/dcn_1_0_offset.h"
> > @@ -4050,6 +4052,11 @@ amdgpu_dm_register_backlight_device(struct 
> > amdgpu_display_manager *dm)
> > amdgpu_dm_update_backlight_caps(dm, dm->num_of_edps);
> > dm->brightness[dm->num_of_edps] = AMDGPU_MAX_BL_LEVEL;
> >
> > +   if (!acpi_video_backlight_use_native()) {
> > +   DRM_INFO("Skipping amdgpu DM backlight registration\n");
> > +   return;
> > +   }
> > +
> > props.max_brightness = AMDGPU_MAX_BL_LEVEL;
> > props.brightness = AMDGPU_MAX_BL_LEVEL;
> > props.type = BACKLIGHT_RAW;
> > --
> > 2.36.0
> >


Re: [PATCH v2 04/29] drm/radeon: Don't register backlight when another backlight should be used

2022-07-20 Thread Alex Deucher
On Tue, Jul 12, 2022 at 3:39 PM Hans de Goede  wrote:
>
> Before this commit when we want userspace to use the acpi_video backlight
> device we register both the GPU's native backlight device and acpi_video's
> firmware acpi_video# backlight device. This relies on userspace preferring
> firmware type backlight devices over native ones.
>
> Registering 2 backlight devices for a single display really is
> undesirable, don't register the GPU's native backlight device when
> another backlight device should be used.
>
> Changes in v2:
> - To avoid linker errors when radeon is builtin and video_detect.c is in
>   a module, select ACPI_VIDEO and its deps if ACPI && X86 are enabled.
>   When these are not set, ACPI_VIDEO is disabled, ensuring the stubs
>   from acpi/video.h will be used.
>
> Signed-off-by: Hans de Goede 

Acked-by: Alex Deucher 

> ---
>  drivers/gpu/drm/Kconfig | 6 ++
>  drivers/gpu/drm/radeon/atombios_encoders.c  | 7 +++
>  drivers/gpu/drm/radeon/radeon_legacy_encoders.c | 7 +++
>  3 files changed, 20 insertions(+)
>
> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> index d65119860760..a07b76e06f84 100644
> --- a/drivers/gpu/drm/Kconfig
> +++ b/drivers/gpu/drm/Kconfig
> @@ -234,6 +234,12 @@ config DRM_RADEON
> select HWMON
> select BACKLIGHT_CLASS_DEVICE
> select INTERVAL_TREE
> +   # radeon depends on ACPI_VIDEO when X86 and ACPI are both enabled
> +   # for select to work, ACPI_VIDEO's dependencies must also be selected
> +   select INPUT if ACPI && X86
> +   select X86_PLATFORM_DEVICES if ACPI && X86
> +   select ACPI_WMI if ACPI && X86
> +   select ACPI_VIDEO if ACPI && X86
> help
>   Choose this option if you have an ATI Radeon graphics card.  There
>   are both PCI and AGP versions.  You don't need to choose this to
> diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c 
> b/drivers/gpu/drm/radeon/atombios_encoders.c
> index c93040e60d04..958920230d6f 100644
> --- a/drivers/gpu/drm/radeon/atombios_encoders.c
> +++ b/drivers/gpu/drm/radeon/atombios_encoders.c
> @@ -32,6 +32,8 @@
>  #include 
>  #include 
>
> +#include 
> +
>  #include "atom.h"
>  #include "radeon_atombios.h"
>  #include "radeon.h"
> @@ -209,6 +211,11 @@ void radeon_atom_backlight_init(struct radeon_encoder 
> *radeon_encoder,
> if (!(rdev->mode_info.firmware_flags & 
> ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU))
> return;
>
> +   if (!acpi_video_backlight_use_native()) {
> +   DRM_INFO("Skipping radeon atom DIG backlight registration\n");
> +   return;
> +   }
> +
> pdata = kmalloc(sizeof(struct radeon_backlight_privdata), GFP_KERNEL);
> if (!pdata) {
> DRM_ERROR("Memory allocation failed\n");
> diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c 
> b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
> index 1a66fb969ee7..d24cedf20c47 100644
> --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
> +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
> @@ -33,6 +33,8 @@
>  #include 
>  #include 
>
> +#include 
> +
>  #include "radeon.h"
>  #include "radeon_asic.h"
>  #include "radeon_legacy_encoders.h"
> @@ -387,6 +389,11 @@ void radeon_legacy_backlight_init(struct radeon_encoder 
> *radeon_encoder,
> return;
>  #endif
>
> +   if (!acpi_video_backlight_use_native()) {
> +   DRM_INFO("Skipping radeon legacy LVDS backlight 
> registration\n");
> +   return;
> +   }
> +
> pdata = kmalloc(sizeof(struct radeon_backlight_privdata), GFP_KERNEL);
> if (!pdata) {
> DRM_ERROR("Memory allocation failed\n");
> --
> 2.36.0
>


Re: [PATCH v2 03/29] drm/amdgpu: Don't register backlight when another backlight should be used

2022-07-20 Thread Alex Deucher
On Tue, Jul 12, 2022 at 3:39 PM Hans de Goede  wrote:
>
> Before this commit when we want userspace to use the acpi_video backlight
> device we register both the GPU's native backlight device and acpi_video's
> firmware acpi_video# backlight device. This relies on userspace preferring
> firmware type backlight devices over native ones.
>
> Registering 2 backlight devices for a single display really is
> undesirable, don't register the GPU's native backlight device when
> another backlight device should be used.
>
> Changes in v2:
> - To avoid linker errors when amdgpu is builtin and video_detect.c is in
>   a module, select ACPI_VIDEO and its deps if ACPI && X86 are enabled.
>   When these are not set, ACPI_VIDEO is disabled, ensuring the stubs
>   from acpi/video.h will be used.
>
> Signed-off-by: Hans de Goede 

Acked-by: Alex Deucher 

> ---
>  drivers/gpu/drm/Kconfig   | 6 ++
>  drivers/gpu/drm/amd/amdgpu/atombios_encoders.c| 7 +++
>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 +++
>  3 files changed, 20 insertions(+)
>
> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> index aaa7ad1f0614..d65119860760 100644
> --- a/drivers/gpu/drm/Kconfig
> +++ b/drivers/gpu/drm/Kconfig
> @@ -258,6 +258,12 @@ config DRM_AMDGPU
> select HWMON
> select BACKLIGHT_CLASS_DEVICE
> select INTERVAL_TREE
> +   # amdgpu depends on ACPI_VIDEO when X86 and ACPI are both enabled
> +   # for select to work, ACPI_VIDEO's dependencies must also be selected
> +   select INPUT if ACPI && X86
> +   select X86_PLATFORM_DEVICES if ACPI && X86
> +   select ACPI_WMI if ACPI && X86
> +   select ACPI_VIDEO if ACPI && X86
> help
>   Choose this option if you have a recent AMD Radeon graphics card.
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c 
> b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
> index fa7421afb9a6..abf209e36fca 100644
> --- a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
> +++ b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
> @@ -26,6 +26,8 @@
>
>  #include 
>
> +#include 
> +
>  #include 
>  #include 
>  #include "amdgpu.h"
> @@ -184,6 +186,11 @@ void amdgpu_atombios_encoder_init_backlight(struct 
> amdgpu_encoder *amdgpu_encode
> if (!(adev->mode_info.firmware_flags & 
> ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU))
> return;
>
> +   if (!acpi_video_backlight_use_native()) {
> +   DRM_INFO("Skipping amdgpu atom DIG backlight registration\n");
> +   return;
> +   }
> +
> pdata = kmalloc(sizeof(struct amdgpu_backlight_privdata), GFP_KERNEL);
> if (!pdata) {
> DRM_ERROR("Memory allocation failed\n");
> 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 5eb111d35793..3b03a95e59a8 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -86,6 +86,8 @@
>  #include 
>  #include 
>
> +#include 
> +
>  #include "ivsrcid/dcn/irqsrcs_dcn_1_0.h"
>
>  #include "dcn/dcn_1_0_offset.h"
> @@ -4050,6 +4052,11 @@ amdgpu_dm_register_backlight_device(struct 
> amdgpu_display_manager *dm)
> amdgpu_dm_update_backlight_caps(dm, dm->num_of_edps);
> dm->brightness[dm->num_of_edps] = AMDGPU_MAX_BL_LEVEL;
>
> +   if (!acpi_video_backlight_use_native()) {
> +   DRM_INFO("Skipping amdgpu DM backlight registration\n");
> +   return;
> +   }
> +
> props.max_brightness = AMDGPU_MAX_BL_LEVEL;
> props.brightness = AMDGPU_MAX_BL_LEVEL;
> props.type = BACKLIGHT_RAW;
> --
> 2.36.0
>


[PATCH RESEND] dt-bindings: leds: qcom-wled: fix number of addresses

2022-07-20 Thread Krzysztof Kozlowski
On PM660L, PMI8994 and PMI8998, the WLED has two address spaces.  This
also fixes dtbs_check warnings like:

  arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dtb: leds@d800: reg: [[55296], 
[2]] is too long

Signed-off-by: Krzysztof Kozlowski 
Reviewed-by: Rob Herring 
---
 .../devicetree/bindings/leds/backlight/qcom-wled.yaml| 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml 
b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml
index 5d66c3e4def5..4c15693f7a01 100644
--- a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml
+++ b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml
@@ -26,7 +26,8 @@ properties:
   - qcom,pm8150l-wled
 
   reg:
-maxItems: 1
+minItems: 1
+maxItems: 2
 
   default-brightness:
 description: |
@@ -171,6 +172,9 @@ allOf:
 
 then:
   properties:
+reg:
+  maxItems: 1
+
 qcom,current-boost-limit:
   enum: [ 105, 385, 525, 805, 980, 1260, 1400, 1680 ]
   default: 805
@@ -189,6 +193,9 @@ allOf:
 
 else:
   properties:
+reg:
+  minItems: 2
+
 qcom,current-boost-limit:
   enum: [ 105, 280, 450, 620, 970, 1150, 1300, 1500 ]
   default: 970
-- 
2.34.1



Re: [PATCH] drm/msm/dpu: populate wb or intf before reset_intf_cfg

2022-07-20 Thread Jessica Zhang




On 7/15/2022 12:14 PM, Abhinav Kumar wrote:

dpu_encoder_helper_phys_cleanup() was not populating neither
wb or intf to the intf_cfg before calling the reset_intf_cfg().

This causes the reset of the active bits of wb/intf to be
skipped which is incorrect.

Fix this by populating the relevant wb or intf indices correctly.

Fixes: ae4d721ce100 ("drm/msm/dpu: add an API to reset the encoder related hw 
blocks")
Signed-off-by: Abhinav Kumar 


Reviewed-by: Jessica Zhang 

Tested-by: Jessica Zhang  # Trogdor (SC8170)


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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index c682d4e02d1b..52a626117f70 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -2061,6 +2061,12 @@ void dpu_encoder_helper_phys_cleanup(struct 
dpu_encoder_phys *phys_enc)
  
  	intf_cfg.stream_sel = 0; /* Don't care value for video mode */

intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
+
+   if (phys_enc->hw_intf)
+   intf_cfg.intf = phys_enc->hw_intf->idx;
+   if (phys_enc->hw_wb)
+   intf_cfg.wb = phys_enc->hw_wb->idx;
+
if (phys_enc->hw_pp->merge_3d)
intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx;
  
--

2.7.4



[PATCH v3 13/13] drm: bridge: samsung-dsim: Add i.MX8MM support

2022-07-20 Thread Jagan Teki
Samsung MIPI DSIM master can also be found in i.MX8MM SoC.

Add compatible and associated driver_data for it.

v3:
* enable DSIM_QUIRK_FIXUP_SYNC_POL quirk

v2:
* collect Laurent r-b

v1:
* none

Reviewed-by: Laurent Pinchart 
Signed-off-by: Jagan Teki 
---
 drivers/gpu/drm/bridge/samsung-dsim.c | 35 +++
 1 file changed, 35 insertions(+)

diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c 
b/drivers/gpu/drm/bridge/samsung-dsim.c
index ef439b49f2b8..3b859b61f493 100644
--- a/drivers/gpu/drm/bridge/samsung-dsim.c
+++ b/drivers/gpu/drm/bridge/samsung-dsim.c
@@ -360,6 +360,24 @@ static const unsigned int exynos5433_reg_values[] = {
[PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0c),
 };
 
+static const unsigned int imx8mm_dsim_reg_values[] = {
+   [RESET_TYPE] = DSIM_SWRST,
+   [PLL_TIMER] = 500,
+   [STOP_STATE_CNT] = 0xf,
+   [PHYCTRL_ULPS_EXIT] = 0,
+   [PHYCTRL_VREG_LP] = 0,
+   [PHYCTRL_SLEW_UP] = 0,
+   [PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x06),
+   [PHYTIMING_HS_EXIT] = DSIM_PHYTIMING_HS_EXIT(0x0b),
+   [PHYTIMING_CLK_PREPARE] = DSIM_PHYTIMING1_CLK_PREPARE(0x07),
+   [PHYTIMING_CLK_ZERO] = DSIM_PHYTIMING1_CLK_ZERO(0x26),
+   [PHYTIMING_CLK_POST] = DSIM_PHYTIMING1_CLK_POST(0x0d),
+   [PHYTIMING_CLK_TRAIL] = DSIM_PHYTIMING1_CLK_TRAIL(0x08),
+   [PHYTIMING_HS_PREPARE] = DSIM_PHYTIMING2_HS_PREPARE(0x08),
+   [PHYTIMING_HS_ZERO] = DSIM_PHYTIMING2_HS_ZERO(0x0d),
+   [PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0b),
+};
+
 static const struct samsung_dsim_driver_data exynos3_dsi_driver_data = {
.reg_ofs = exynos_reg_ofs,
.plltmr_reg = 0x50,
@@ -426,6 +444,19 @@ static const struct samsung_dsim_driver_data 
exynos5422_dsi_driver_data = {
.quirks = DSIM_QUIRK_PLAT_DATA,
 };
 
+static const struct samsung_dsim_driver_data imx8mm_dsi_driver_data = {
+   .reg_ofs = exynos5433_reg_ofs,
+   .plltmr_reg = 0xa0,
+   .has_clklane_stop = 1,
+   .num_clks = 2,
+   .max_freq = 2100,
+   .wait_for_reset = 0,
+   .num_bits_resol = 12,
+   .pll_p_offset = 14,
+   .reg_values = imx8mm_dsim_reg_values,
+   .quirks = DSIM_QUIRK_FIXUP_SYNC_POL,
+};
+
 static const struct of_device_id samsung_dsim_of_match[] = {
{
.compatible = "samsung,exynos3250-mipi-dsi",
@@ -447,6 +478,10 @@ static const struct of_device_id samsung_dsim_of_match[] = 
{
.compatible = "samsung,exynos5433-mipi-dsi",
.data = _dsi_driver_data
},
+   {
+   .compatible = "fsl,imx8mm-mipi-dsim",
+   .data = _dsi_driver_data
+   },
{ /* sentinel. */ }
 };
 
-- 
2.25.1



[PATCH v3 12/13] dt-bindings: display: exynos: dsim: Add NXP i.MX8MM support

2022-07-20 Thread Jagan Teki
Samsung MIPI DSIM bridge can also be found in i.MX8MM SoC.

Add dt-bingings for it.

v3:
* collect Rob Acked-by

v2:
* updated comments

v1:
* new patch

Acked-by: Rob Herring 
Signed-off-by: Jagan Teki 
---
 Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt 
b/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt
index be377786e8cd..8efcf4728e0b 100644
--- a/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt
+++ b/Documentation/devicetree/bindings/display/exynos/exynos_dsim.txt
@@ -7,6 +7,7 @@ Required properties:
"samsung,exynos5410-mipi-dsi" /* for Exynos5410/5420/5440 SoCs 
*/
"samsung,exynos5422-mipi-dsi" /* for Exynos5422/5800 SoCs */
"samsung,exynos5433-mipi-dsi" /* for Exynos5433 SoCs */
+   "fsl,imx8mm-mipi-dsim" /* for i.MX8M Mini SoCs */
   - reg: physical base address and length of the registers set for the device
   - interrupts: should contain DSI interrupt
   - clocks: list of clock specifiers, must contain an entry for each required
-- 
2.25.1



[PATCH v3 11/13] drm: bridge: samsung-dsim: Add input_bus_flags

2022-07-20 Thread Jagan Teki
eLCDIF is expecting to have input_bus_flags as DE_LOW in order to
set active low during valid data transfer on each horizontal line.

Add DE_LOW flag via drm bridge timings.

v3, v2:
* none

v1:
* none

Signed-off-by: Jagan Teki 
---
 drivers/gpu/drm/bridge/samsung-dsim.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c 
b/drivers/gpu/drm/bridge/samsung-dsim.c
index 2584343b767a..ef439b49f2b8 100644
--- a/drivers/gpu/drm/bridge/samsung-dsim.c
+++ b/drivers/gpu/drm/bridge/samsung-dsim.c
@@ -1591,6 +1591,10 @@ __weak void samsung_dsim_plat_remove(struct samsung_dsim 
*priv)
 {
 }
 
+static const struct drm_bridge_timings samsung_dsim_bridge_timings = {
+   .input_bus_flags = DRM_BUS_FLAG_DE_LOW,
+};
+
 static int samsung_dsim_probe(struct platform_device *pdev)
 {
struct device *dev = >dev;
@@ -1670,6 +1674,7 @@ static int samsung_dsim_probe(struct platform_device 
*pdev)
 
dsi->bridge.funcs = _dsim_bridge_funcs;
dsi->bridge.of_node = dev->of_node;
+   dsi->bridge.timings = _dsim_bridge_timings;
dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
 
if (dsi->driver_data->quirks & DSIM_QUIRK_PLAT_DATA)
-- 
2.25.1



[PATCH v3 10/13] drm: bridge: samsung-dsim: Add atomic_get_input_bus_fmts

2022-07-20 Thread Jagan Teki
Finding the right input bus format throughout the pipeline is hard
so add atomic_get_input_bus_fmts callback and initialize with the
default RGB888_1X24 bus format on DSI-end.

This format can be used in pipeline for negotiating bus format between
the DSI-end of this bridge and the other component closer to pipeline
components.

v3:
* include media-bus-format.h

v2:
* none

v1:
* new patch

Signed-off-by: Jagan Teki 
---
 drivers/gpu/drm/bridge/samsung-dsim.c | 28 +++
 1 file changed, 28 insertions(+)

diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c 
b/drivers/gpu/drm/bridge/samsung-dsim.c
index 376e9682e130..2584343b767a 100644
--- a/drivers/gpu/drm/bridge/samsung-dsim.c
+++ b/drivers/gpu/drm/bridge/samsung-dsim.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -1339,6 +1340,32 @@ static void samsung_dsim_atomic_post_disable(struct 
drm_bridge *bridge,
pm_runtime_put_sync(dsi->dev);
 }
 
+#define MAX_INPUT_SEL_FORMATS  1
+
+static u32 *
+samsung_dsim_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
+  struct drm_bridge_state *bridge_state,
+  struct drm_crtc_state *crtc_state,
+  struct drm_connector_state *conn_state,
+  u32 output_fmt,
+  unsigned int *num_input_fmts)
+{
+   u32 *input_fmts;
+
+   *num_input_fmts = 0;
+
+   input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, sizeof(*input_fmts),
+GFP_KERNEL);
+   if (!input_fmts)
+   return NULL;
+
+   /* This is the DSI-end bus format */
+   input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24;
+   *num_input_fmts = 1;
+
+   return input_fmts;
+}
+
 static int samsung_dsim_atomic_check(struct drm_bridge *bridge,
 struct drm_bridge_state *bridge_state,
 struct drm_crtc_state *crtc_state,
@@ -1378,6 +1405,7 @@ static const struct drm_bridge_funcs 
samsung_dsim_bridge_funcs = {
.atomic_duplicate_state = 
drm_atomic_helper_bridge_duplicate_state,
.atomic_destroy_state   = 
drm_atomic_helper_bridge_destroy_state,
.atomic_reset   = drm_atomic_helper_bridge_reset,
+   .atomic_get_input_bus_fmts  = 
samsung_dsim_atomic_get_input_bus_fmts,
.atomic_check   = samsung_dsim_atomic_check,
.atomic_pre_enable  = samsung_dsim_atomic_pre_enable,
.atomic_enable  = samsung_dsim_atomic_enable,
-- 
2.25.1



[PATCH v3 09/13] drm: bridge: samsung-dsim: Add atomic_check

2022-07-20 Thread Jagan Teki
Explicit fixing up of mode_flags is required for DSIM present
in i.MX8M SoC.

At least the LCDIF + DSIM needs active low sync polarities in
order to correlate the correct sync flags of the surrounding
components in the chain to make sure the whole pipeline can
work properly.

So, add DSIM_QUIRK_FIXUP_SYNC_POL to handle this fixup via bridge
atomic_check.

v3:
* add DSIM_QUIRK_FIXUP_SYNC_POL to handle mode_flasg fixup

v2:
* none

v1:
* fix mode flags in atomic_check instead of mode_fixup

Signed-off-by: Jagan Teki 
---
 drivers/gpu/drm/bridge/samsung-dsim.c | 18 ++
 include/drm/bridge/samsung-dsim.h |  1 +
 2 files changed, 19 insertions(+)

diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c 
b/drivers/gpu/drm/bridge/samsung-dsim.c
index 5a0fea30e9e8..376e9682e130 100644
--- a/drivers/gpu/drm/bridge/samsung-dsim.c
+++ b/drivers/gpu/drm/bridge/samsung-dsim.c
@@ -1339,6 +1339,23 @@ static void samsung_dsim_atomic_post_disable(struct 
drm_bridge *bridge,
pm_runtime_put_sync(dsi->dev);
 }
 
+static int samsung_dsim_atomic_check(struct drm_bridge *bridge,
+struct drm_bridge_state *bridge_state,
+struct drm_crtc_state *crtc_state,
+struct drm_connector_state *conn_state)
+{
+   struct samsung_dsim *dsi = bridge_to_dsi(bridge);
+   struct drm_display_mode *adjusted_mode = _state->adjusted_mode;
+
+   if (dsi->driver_data->quirks & DSIM_QUIRK_FIXUP_SYNC_POL) {
+   /* At least LCDIF + DSIM needs active low sync */
+   adjusted_mode->flags |= (DRM_MODE_FLAG_NHSYNC | 
DRM_MODE_FLAG_NVSYNC);
+   adjusted_mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | 
DRM_MODE_FLAG_PVSYNC);
+   }
+
+   return 0;
+}
+
 static void samsung_dsim_mode_set(struct drm_bridge *bridge,
  const struct drm_display_mode *mode,
  const struct drm_display_mode *adjusted_mode)
@@ -1361,6 +1378,7 @@ static const struct drm_bridge_funcs 
samsung_dsim_bridge_funcs = {
.atomic_duplicate_state = 
drm_atomic_helper_bridge_duplicate_state,
.atomic_destroy_state   = 
drm_atomic_helper_bridge_destroy_state,
.atomic_reset   = drm_atomic_helper_bridge_reset,
+   .atomic_check   = samsung_dsim_atomic_check,
.atomic_pre_enable  = samsung_dsim_atomic_pre_enable,
.atomic_enable  = samsung_dsim_atomic_enable,
.atomic_disable = samsung_dsim_atomic_disable,
diff --git a/include/drm/bridge/samsung-dsim.h 
b/include/drm/bridge/samsung-dsim.h
index c852d7b9981e..4eacaf18e00a 100644
--- a/include/drm/bridge/samsung-dsim.h
+++ b/include/drm/bridge/samsung-dsim.h
@@ -35,6 +35,7 @@ struct samsung_dsim_transfer {
 
 enum samsung_dsim_quirks {
DSIM_QUIRK_PLAT_DATA= BIT(0),
+   DSIM_QUIRK_FIXUP_SYNC_POL   = BIT(1),
 };
 
 struct samsung_dsim_driver_data {
-- 
2.25.1



[PATCH v3 08/13] drm: bridge: samsung-dsim: Add module init, exit

2022-07-20 Thread Jagan Teki
Add module init and exit functions for the bridge to register
and unregister dsi_driver.

Exynos drm driver stack will register the platform_driver separately
in the common of it's exynos_drm_drv.c including dsi_driver.

Register again would return -EBUSY, so return 0 for such cases as
dsi_driver is already registered.

v3, v2, v1:
* none

Signed-off-by: Jagan Teki 
---
 drivers/gpu/drm/bridge/samsung-dsim.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c 
b/drivers/gpu/drm/bridge/samsung-dsim.c
index 5eb594ea0bdf..5a0fea30e9e8 100644
--- a/drivers/gpu/drm/bridge/samsung-dsim.c
+++ b/drivers/gpu/drm/bridge/samsung-dsim.c
@@ -1737,6 +1737,28 @@ struct platform_driver dsi_driver = {
},
 };
 
+static int __init samsung_mipi_dsim_init(void)
+{
+   int ret;
+
+   ret = platform_driver_register(_driver);
+
+   /**
+* Exynos drm driver stack will register the platform_driver
+* separately in the common of it's exynos_drm_drv.c including
+* dsi_driver. Register again would return -EBUSY, so return 0
+* for such cases as dsi_driver is already registered.
+*/
+   return ret == -EBUSY ? 0 : ret;
+}
+module_init(samsung_mipi_dsim_init);
+
+static void __exit samsung_mipi_dsim_exit(void)
+{
+   platform_driver_unregister(_driver);
+}
+module_exit(samsung_mipi_dsim_exit);
+
 MODULE_AUTHOR("Jagan Teki ");
 MODULE_DESCRIPTION("Samsung MIPI DSIM controller bridge");
 MODULE_LICENSE("GPL");
-- 
2.25.1



[PATCH v3 07/13] drm: bridge: samsung-dsim: Fix PLL_P (PMS_P) offset

2022-07-20 Thread Jagan Teki
The i.MX 8M Mini Applications Processor Reference Manual, Rev. 3, 11/2020
with 13.7.10.1 Master PLL PMS Value setting Register mentioned PMS_P offset
range from BIT[18-13] and the upstream driver is using the same offset.

However, offset 13 is not working on i.MX8M Mini platforms but downstream
NXP driver is using 14 [1] and it is working with i.MX8M Mini SoC.

Not sure about whether it is reference manual documentation or something
else but this patch trusts the downstream code and fixes the PLL_P offset.

[1] 
https://source.codeaurora.org/external/imx/linux-imx/tree/drivers/gpu/drm/bridge/sec-dsim.c?h=imx_5.4.47_2.2.0#n211

v3, v2:
* none

v1:
* updated commit message
* add downstream driver link

Signed-off-by: Frieder Schrempf 
Signed-off-by: Jagan Teki 
---
 drivers/gpu/drm/bridge/samsung-dsim.c | 10 --
 include/drm/bridge/samsung-dsim.h |  1 +
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c 
b/drivers/gpu/drm/bridge/samsung-dsim.c
index b07909a52f2d..5eb594ea0bdf 100644
--- a/drivers/gpu/drm/bridge/samsung-dsim.c
+++ b/drivers/gpu/drm/bridge/samsung-dsim.c
@@ -168,7 +168,7 @@
 /* DSIM_PLLCTRL */
 #define DSIM_FREQ_BAND(x)  ((x) << 24)
 #define DSIM_PLL_EN(1 << 23)
-#define DSIM_PLL_P(x)  ((x) << 13)
+#define DSIM_PLL_P(x, offset)  ((x) << (offset))
 #define DSIM_PLL_M(x)  ((x) << 4)
 #define DSIM_PLL_S(x)  ((x) << 1)
 
@@ -368,6 +368,7 @@ static const struct samsung_dsim_driver_data 
exynos3_dsi_driver_data = {
.max_freq = 1000,
.wait_for_reset = 1,
.num_bits_resol = 11,
+   .pll_p_offset = 13,
.reg_values = reg_values,
.quirks = DSIM_QUIRK_PLAT_DATA,
 };
@@ -381,6 +382,7 @@ static const struct samsung_dsim_driver_data 
exynos4_dsi_driver_data = {
.max_freq = 1000,
.wait_for_reset = 1,
.num_bits_resol = 11,
+   .pll_p_offset = 13,
.reg_values = reg_values,
.quirks = DSIM_QUIRK_PLAT_DATA,
 };
@@ -392,6 +394,7 @@ static const struct samsung_dsim_driver_data 
exynos5_dsi_driver_data = {
.max_freq = 1000,
.wait_for_reset = 1,
.num_bits_resol = 11,
+   .pll_p_offset = 13,
.reg_values = reg_values,
.quirks = DSIM_QUIRK_PLAT_DATA,
 };
@@ -404,6 +407,7 @@ static const struct samsung_dsim_driver_data 
exynos5433_dsi_driver_data = {
.max_freq = 1500,
.wait_for_reset = 0,
.num_bits_resol = 12,
+   .pll_p_offset = 13,
.reg_values = exynos5433_reg_values,
.quirks = DSIM_QUIRK_PLAT_DATA,
 };
@@ -416,6 +420,7 @@ static const struct samsung_dsim_driver_data 
exynos5422_dsi_driver_data = {
.max_freq = 1500,
.wait_for_reset = 1,
.num_bits_resol = 12,
+   .pll_p_offset = 13,
.reg_values = exynos5422_reg_values,
.quirks = DSIM_QUIRK_PLAT_DATA,
 };
@@ -563,7 +568,8 @@ static unsigned long samsung_dsim_set_pll(struct 
samsung_dsim *dsi,
writel(driver_data->reg_values[PLL_TIMER],
dsi->reg_base + driver_data->plltmr_reg);
 
-   reg = DSIM_PLL_EN | DSIM_PLL_P(p) | DSIM_PLL_M(m) | DSIM_PLL_S(s);
+   reg = DSIM_PLL_EN | DSIM_PLL_P(p, driver_data->pll_p_offset) |
+ DSIM_PLL_M(m) | DSIM_PLL_S(s);
 
if (driver_data->has_freqband) {
static const unsigned long freq_bands[] = {
diff --git a/include/drm/bridge/samsung-dsim.h 
b/include/drm/bridge/samsung-dsim.h
index 97fdee5ef5df..c852d7b9981e 100644
--- a/include/drm/bridge/samsung-dsim.h
+++ b/include/drm/bridge/samsung-dsim.h
@@ -46,6 +46,7 @@ struct samsung_dsim_driver_data {
unsigned int max_freq;
unsigned int wait_for_reset;
unsigned int num_bits_resol;
+   unsigned int pll_p_offset;
const unsigned int *reg_values;
enum samsung_dsim_quirks quirks;
 };
-- 
2.25.1



[PATCH v3 06/13] drm: bridge: samsung-dsim: Add DSI init in bridge pre_enable()

2022-07-20 Thread Jagan Teki
Host transfer() in DSI master will invoke only when the DSI commands
are sent from DSI devices like DSI Panel or DSI bridges and this
host transfer wouldn't invoke for I2C-based-DSI bridge drivers.

Handling DSI host initialization in transfer calls misses the
controller setup for I2C configured DSI bridges.

This patch adds the DSI initialization from transfer to bridge
pre_enable as the bridge pre_enable API is invoked by core as
it is common across all classes of DSI device drivers.

v3:
* none

v2:
* check initialized state in samsung_dsim_init

v1:
* keep DSI init in host transfer

Signed-off-by: Jagan Teki 
---
 drivers/gpu/drm/bridge/samsung-dsim.c | 18 --
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c 
b/drivers/gpu/drm/bridge/samsung-dsim.c
index 9b74a3f98a17..b07909a52f2d 100644
--- a/drivers/gpu/drm/bridge/samsung-dsim.c
+++ b/drivers/gpu/drm/bridge/samsung-dsim.c
@@ -1258,6 +1258,9 @@ static int samsung_dsim_init(struct samsung_dsim *dsi)
 {
const struct samsung_dsim_driver_data *driver_data = dsi->driver_data;
 
+   if (dsi->state & DSIM_STATE_INITIALIZED)
+   return 0;
+
samsung_dsim_reset(dsi);
samsung_dsim_enable_irq(dsi);
 
@@ -1270,6 +1273,8 @@ static int samsung_dsim_init(struct samsung_dsim *dsi)
samsung_dsim_set_phy_ctrl(dsi);
samsung_dsim_init_link(dsi);
 
+   dsi->state |= DSIM_STATE_INITIALIZED;
+
return 0;
 }
 
@@ -1289,6 +1294,10 @@ static void samsung_dsim_atomic_pre_enable(struct 
drm_bridge *bridge,
}
 
dsi->state |= DSIM_STATE_ENABLED;
+
+   ret = samsung_dsim_init(dsi);
+   if (ret)
+   return;
 }
 
 static void samsung_dsim_atomic_enable(struct drm_bridge *bridge,
@@ -1464,12 +1473,9 @@ static ssize_t samsung_dsim_host_transfer(struct 
mipi_dsi_host *host,
if (!(dsi->state & DSIM_STATE_ENABLED))
return -EINVAL;
 
-   if (!(dsi->state & DSIM_STATE_INITIALIZED)) {
-   ret = samsung_dsim_init(dsi);
-   if (ret)
-   return ret;
-   dsi->state |= DSIM_STATE_INITIALIZED;
-   }
+   ret = samsung_dsim_init(dsi);
+   if (ret)
+   return ret;
 
ret = mipi_dsi_create_packet(, msg);
if (ret < 0)
-- 
2.25.1



[PATCH v3 05/13] drm: bridge: samsung-dsim: Mark PHY as optional

2022-07-20 Thread Jagan Teki
In i.MX8M Mini/Nano SoC the DSI Phy requires a MIPI DPHY bit
to reset in order to activate the PHY and that can be done via
upstream i.MX8M blk-ctrl driver.

So, mark the phy get as optional.

v3, v2:
* none

v1:
* new patch

Signed-off-by: Jagan Teki 
---
 drivers/gpu/drm/bridge/samsung-dsim.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c 
b/drivers/gpu/drm/bridge/samsung-dsim.c
index 4d5f72de2240..9b74a3f98a17 100644
--- a/drivers/gpu/drm/bridge/samsung-dsim.c
+++ b/drivers/gpu/drm/bridge/samsung-dsim.c
@@ -1583,7 +1583,7 @@ static int samsung_dsim_probe(struct platform_device 
*pdev)
if (IS_ERR(dsi->reg_base))
return PTR_ERR(dsi->reg_base);
 
-   dsi->phy = devm_phy_get(dev, "dsim");
+   dsi->phy = devm_phy_optional_get(dev, "dsim");
if (IS_ERR(dsi->phy)) {
dev_info(dev, "failed to get dsim phy\n");
return PTR_ERR(dsi->phy);
-- 
2.25.1



[PATCH v3 04/13] drm: bridge: samsung-dsim: Handle platform init via driver_data

2022-07-20 Thread Jagan Teki
In order to make a common Samsung DSIM bridge driver some platform
specific glue code needs to maintain separately as it is hard to
maintain platform specific glue and conventional component_ops on
the drm bridge drivers side.

This patch is trying to support that glue code initialization based
on the DSIM_QUIRK_PLAT_DATA set from respective driver_data.

So, the platforms which enable DSIM_QUIRK_PLAT_DATA flags will handle
all platform specific initialization via samsung_dsim_plat_probe.

The platform probe is responsible to
- initialize samsung_dsim_plat_data and install hooks
- initialize component_ops
- preserve samsung_dsim structure pointer

v3:
* update samsung_dsim_plat_probe return value
* add plat_data quirk to handle platform init

v2:
* fix samsung_dsim_plat_probe return pointer

v1:
* use platform_init instead of exynos_specific
* handle component_ops in glue code

Signed-off-by: Jagan Teki 
---
 drivers/gpu/drm/bridge/samsung-dsim.c | 16 ++--
 include/drm/bridge/samsung-dsim.h |  5 +
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c 
b/drivers/gpu/drm/bridge/samsung-dsim.c
index 20db345abf8b..4d5f72de2240 100644
--- a/drivers/gpu/drm/bridge/samsung-dsim.c
+++ b/drivers/gpu/drm/bridge/samsung-dsim.c
@@ -369,6 +369,7 @@ static const struct samsung_dsim_driver_data 
exynos3_dsi_driver_data = {
.wait_for_reset = 1,
.num_bits_resol = 11,
.reg_values = reg_values,
+   .quirks = DSIM_QUIRK_PLAT_DATA,
 };
 
 static const struct samsung_dsim_driver_data exynos4_dsi_driver_data = {
@@ -381,6 +382,7 @@ static const struct samsung_dsim_driver_data 
exynos4_dsi_driver_data = {
.wait_for_reset = 1,
.num_bits_resol = 11,
.reg_values = reg_values,
+   .quirks = DSIM_QUIRK_PLAT_DATA,
 };
 
 static const struct samsung_dsim_driver_data exynos5_dsi_driver_data = {
@@ -391,6 +393,7 @@ static const struct samsung_dsim_driver_data 
exynos5_dsi_driver_data = {
.wait_for_reset = 1,
.num_bits_resol = 11,
.reg_values = reg_values,
+   .quirks = DSIM_QUIRK_PLAT_DATA,
 };
 
 static const struct samsung_dsim_driver_data exynos5433_dsi_driver_data = {
@@ -402,6 +405,7 @@ static const struct samsung_dsim_driver_data 
exynos5433_dsi_driver_data = {
.wait_for_reset = 0,
.num_bits_resol = 12,
.reg_values = exynos5433_reg_values,
+   .quirks = DSIM_QUIRK_PLAT_DATA,
 };
 
 static const struct samsung_dsim_driver_data exynos5422_dsi_driver_data = {
@@ -413,6 +417,7 @@ static const struct samsung_dsim_driver_data 
exynos5422_dsi_driver_data = {
.wait_for_reset = 1,
.num_bits_resol = 12,
.reg_values = exynos5422_reg_values,
+   .quirks = DSIM_QUIRK_PLAT_DATA,
 };
 
 static const struct of_device_id samsung_dsim_of_match[] = {
@@ -1609,7 +1614,11 @@ static int samsung_dsim_probe(struct platform_device 
*pdev)
dsi->bridge.of_node = dev->of_node;
dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
 
-   ret = samsung_dsim_plat_probe(dsi);
+   if (dsi->driver_data->quirks & DSIM_QUIRK_PLAT_DATA)
+   ret = samsung_dsim_plat_probe(dsi);
+   else
+   ret = mipi_dsi_host_register(>dsi_host);
+
if (ret)
goto err_disable_runtime;
 
@@ -1627,7 +1636,10 @@ static int samsung_dsim_remove(struct platform_device 
*pdev)
 
pm_runtime_disable(>dev);
 
-   samsung_dsim_plat_remove(dsi);
+   if (dsi->driver_data->quirks & DSIM_QUIRK_PLAT_DATA)
+   samsung_dsim_plat_remove(dsi);
+   else
+   mipi_dsi_host_unregister(>dsi_host);
 
return 0;
 }
diff --git a/include/drm/bridge/samsung-dsim.h 
b/include/drm/bridge/samsung-dsim.h
index 2e245bffd1b6..97fdee5ef5df 100644
--- a/include/drm/bridge/samsung-dsim.h
+++ b/include/drm/bridge/samsung-dsim.h
@@ -33,6 +33,10 @@ struct samsung_dsim_transfer {
u16 rx_done;
 };
 
+enum samsung_dsim_quirks {
+   DSIM_QUIRK_PLAT_DATA= BIT(0),
+};
+
 struct samsung_dsim_driver_data {
const unsigned int *reg_ofs;
unsigned int plltmr_reg;
@@ -43,6 +47,7 @@ struct samsung_dsim_driver_data {
unsigned int wait_for_reset;
unsigned int num_bits_resol;
const unsigned int *reg_values;
+   enum samsung_dsim_quirks quirks;
 };
 
 struct samsung_dsim_host_ops {
-- 
2.25.1



[PATCH v3 03/13] drm: bridge: samsung-dsim: Lookup OF-graph or Child node devices

2022-07-20 Thread Jagan Teki
The child devices in MIPI DSI can be binding with OF-graph
and also via child nodes.

The OF-graph interface represents the child devices via
remote and associated endpoint numbers like

dsi {
   compatible = "fsl,imx8mm-mipi-dsim";

   ports {
port@0 {
 reg = <0>;

 dsi_in_lcdif: endpoint@0 {
  reg = <0>;
  remote-endpoint = <_out_dsi>;
 };
};

port@1 {
 reg = <1>;

 dsi_out_bridge: endpoint {
  remote-endpoint = <_in_dsi>;
 };
};
};

The child node interface represents the child devices via
conventional child nodes on given DSI parent like

dsi {
   compatible = "samsung,exynos5433-mipi-dsi";

   ports {
port@0 {
 reg = <0>;

 dsi_to_mic: endpoint {
  remote-endpoint = <_to_dsi>;
 };
};
   };

   panel@0 {
reg = <0>;
   };
};

As Samsung DSIM bridge is common DSI IP across all Exynos DSI
and NXP i.MX8M host controllers, this patch adds support to
lookup the child devices whether its bindings on the associated
host represent OF-graph or child node interfaces.

v3:
* none

v2:
* new patch

Signed-off-by: Jagan Teki 
---
 drivers/gpu/drm/bridge/samsung-dsim.c | 38 +--
 1 file changed, 36 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c 
b/drivers/gpu/drm/bridge/samsung-dsim.c
index 21975ed513bd..20db345abf8b 100644
--- a/drivers/gpu/drm/bridge/samsung-dsim.c
+++ b/drivers/gpu/drm/bridge/samsung-dsim.c
@@ -1357,18 +1357,52 @@ static int samsung_dsim_host_attach(struct 
mipi_dsi_host *host,
struct samsung_dsim *dsi = host_to_dsi(host);
const struct samsung_dsim_plat_data *pdata = dsi->plat_data;
struct device *dev = dsi->dev;
+   struct device_node *np = dev->of_node;
+   struct device_node *remote;
struct drm_panel *panel;
int ret;
 
-   panel = of_drm_find_panel(device->dev.of_node);
+   /**
+* Devices can also be child nodes when we also control that device
+* through the upstream device (ie, MIPI-DCS for a MIPI-DSI device).
+*
+* Lookup for a child node of the given parent that isn't either port
+* or ports.
+*/
+   for_each_available_child_of_node(np, remote) {
+   if (of_node_name_eq(remote, "port") ||
+   of_node_name_eq(remote, "ports"))
+   continue;
+
+   goto of_find_panel_or_bridge;
+   }
+
+   /*
+* of_graph_get_remote_node() produces a noisy error message if port
+* node isn't found and the absence of the port is a legit case here,
+* so at first we silently check whether graph presents in the
+* device-tree node.
+*/
+   if (!of_graph_is_present(np))
+   return -ENODEV;
+
+   remote = of_graph_get_remote_node(np, 1, 0);
+
+of_find_panel_or_bridge:
+   if (!remote)
+   return -ENODEV;
+
+   panel = of_drm_find_panel(remote);
if (!IS_ERR(panel)) {
dsi->out_bridge = devm_drm_panel_bridge_add(dev, panel);
} else {
-   dsi->out_bridge = of_drm_find_bridge(device->dev.of_node);
+   dsi->out_bridge = of_drm_find_bridge(remote);
if (!dsi->out_bridge)
dsi->out_bridge = ERR_PTR(-EINVAL);
}
 
+   of_node_put(remote);
+
if (IS_ERR(dsi->out_bridge)) {
ret = PTR_ERR(dsi->out_bridge);
DRM_DEV_ERROR(dev, "failed to find the bridge: %d\n", ret);
-- 
2.25.1



[PATCH v3 02/13] drm: bridge: Add Samsung DSIM bridge driver

2022-07-20 Thread Jagan Teki
Samsung MIPI DSIM controller is common DSI IP that can be used in various
SoCs like Exynos, i.MX8M Mini/Nano.

In order to access this DSI controller between various platform SoCs,
the ideal way to incorporate this in the drm stack is via the drm bridge
driver.

This patch is trying to differentiate platform-specific and bridge driver
code and keep maintaining the exynos_drm_dsi.c code as platform-specific
glue code and samsung-dsim.c as a common bridge driver code.

- Exynos specific glue code is exynos specific te_irq, host_attach, and
  detach code along with conventional component_ops.

- Samsung DSIM is a bridge driver which is common across all platforms and
  the respective platform-specific glue will initialize at the end of the
  probe. The platform-specific operations and other glue calls will invoke
  on associate code areas.

v3:
* restore gpio related fixes
* restore proper bridge chain
* rework initialization issue
* fix header includes in proper way

v2:
* fixed exynos dsi driver conversion (Marek Szyprowski)
* updated commit message
* updated MAINTAINERS file

v1:
* Don't maintain component_ops in bridge driver
* Don't maintain platform glue code in bridge driver
* Add platform-specific glue code and make a common bridge

Signed-off-by: Marek Szyprowski 
Signed-off-by: Jagan Teki 
---
 MAINTAINERS |8 +
 drivers/gpu/drm/bridge/Kconfig  |   12 +
 drivers/gpu/drm/bridge/Makefile |1 +
 drivers/gpu/drm/bridge/samsung-dsim.c   | 1684 ++
 drivers/gpu/drm/exynos/Kconfig  |1 +
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 1715 +--
 include/drm/bridge/samsung-dsim.h   |   99 ++
 7 files changed, 1865 insertions(+), 1655 deletions(-)
 create mode 100644 drivers/gpu/drm/bridge/samsung-dsim.c
 create mode 100644 include/drm/bridge/samsung-dsim.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 0f9366144d31..d796fa8c7be0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6546,6 +6546,14 @@ T:   git git://anongit.freedesktop.org/drm/drm-misc
 F: Documentation/devicetree/bindings/display/panel/samsung,lms397kf04.yaml
 F: drivers/gpu/drm/panel/panel-samsung-db7430.c
 
+DRM DRIVER FOR SAMSUNG MIPI DSIM BRIDGE
+M: Jagan Teki 
+M: Marek Szyprowski 
+S: Maintained
+T: git git://anongit.freedesktop.org/drm/drm-misc
+F: drivers/gpu/drm/bridge/samsung-dsim.c
+F: include/drm/bridge/samsung-dsim.h
+
 DRM DRIVER FOR SAMSUNG S6D27A1 PANELS
 M: Markuss Broks 
 S: Maintained
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 57946d80b02d..8e85dac9f53e 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -231,6 +231,18 @@ config DRM_PARADE_PS8640
  The PS8640 is a high-performance and low-power
  MIPI DSI to eDP converter
 
+config DRM_SAMSUNG_DSIM
+   tristate "Samsung MIPI DSIM bridge driver"
+   depends on COMMON_CLK
+   depends on OF && HAS_IOMEM
+   select DRM_KMS_HELPER
+   select DRM_MIPI_DSI
+   select DRM_PANEL_BRIDGE
+   help
+ The Samsung MIPI DSIM bridge controller driver.
+ This MIPI DSIM bridge can be found it on Exynos SoCs and
+ NXP's i.MX8M Mini/Nano.
+
 config DRM_SIL_SII8620
tristate "Silicon Image SII8620 HDMI/MHL bridge"
depends on OF
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index 1884803c6860..dae843723991 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_DRM_MEGACHIPS_STDP_GE_B850V3_FW) += 
megachips-stdp-ge-b850v
 obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
 obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o
 obj-$(CONFIG_DRM_PARADE_PS8640) += parade-ps8640.o
+obj-$(CONFIG_DRM_SAMSUNG_DSIM) += samsung-dsim.o
 obj-$(CONFIG_DRM_SIL_SII8620) += sil-sii8620.o
 obj-$(CONFIG_DRM_SII902X) += sii902x.o
 obj-$(CONFIG_DRM_SII9234) += sii9234.o
diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c 
b/drivers/gpu/drm/bridge/samsung-dsim.c
new file mode 100644
index ..21975ed513bd
--- /dev/null
+++ b/drivers/gpu/drm/bridge/samsung-dsim.c
@@ -0,0 +1,1684 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Samsung MIPI DSIM bridge driver.
+ *
+ * Copyright (C) 2021 Amarula Solutions(India)
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd
+ * Author: Jagan Teki 
+ *
+ * Based on exynos_drm_dsi from
+ * Tomasz Figa 
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+
+/* returns true iff both arguments logically differs */
+#define NEQV(a, b) (!(a) ^ !(b))
+
+/* DSIM_STATUS */
+#define DSIM_STOP_STATE_DAT(x) (((x) & 0xf) << 0)
+#define DSIM_STOP_STATE_CLK(1 << 8)
+#define DSIM_TX_READY_HS_CLK   (1 << 10)
+#define DSIM_PLL_STABLE(1 << 31)
+
+/* DSIM_SWRST */
+#define DSIM_FUNCRST  

[PATCH v3 01/13] drm: exynos: dsi: Restore proper bridge chain order

2022-07-20 Thread Jagan Teki
From: Marek Szyprowski 

Restore the proper bridge chain by finding the previous bridge
in the chain instead of passing NULL.

This establishes a proper bridge chain while attaching downstream
bridges.

v3:
* new patch

Signed-off-by: Marek Szyprowski 
Signed-off-by: Jagan Teki 
---
 drivers/gpu/drm/exynos/exynos_drm_dsi.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c 
b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
index ec673223d6b7..e5b1540c4ae4 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c
@@ -1428,7 +1428,8 @@ static int exynos_dsi_attach(struct drm_bridge *bridge,
 {
struct exynos_dsi *dsi = bridge_to_dsi(bridge);
 
-   return drm_bridge_attach(bridge->encoder, dsi->out_bridge, NULL, flags);
+   return drm_bridge_attach(bridge->encoder, dsi->out_bridge, bridge,
+flags);
 }
 
 static const struct drm_bridge_funcs exynos_dsi_bridge_funcs = {
@@ -1474,7 +1475,10 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host 
*host,
 
drm_bridge_add(>bridge);
 
-   drm_bridge_attach(encoder, >bridge, NULL, 0);
+   drm_bridge_attach(encoder, >bridge,
+ list_first_entry_or_null(>bridge_chain,
+  struct drm_bridge,
+  chain_node), 0);
 
/*
 * This is a temporary solution and should be made by more generic way.
-- 
2.25.1



[PATCH v3 00/13] drm: bridge: Add Samsung MIPI DSIM bridge

2022-07-20 Thread Jagan Teki
This series supports common bridge support for Samsung MIPI DSIM
which is used in Exynos and i.MX8MM SoC's.

Previous v2 can be available here [1].

The final bridge supports both the Exynos and i.MX8MM DSI devices.

On, summary this patch-set break the entire DSIM driver into
- platform specific glue code for platform ops, component_ops.
- common bridge driver which handle platform glue init and invoke.

Patch 0001: Restore proper bridge chain in exynos_dsi

Patch 0002: Samsung DSIM bridge

Patch 0003: Common lookup code for OF-graph or child

Patch 0004: plat_data quirk flag via driver_data

Patch 0005/11:  bridge fixes, atomic API's

Patch 0012: document fsl,imx8mm-mipi-dsim

Patch 0013: add i.MX8MM DSIM support

Tested in Engicam i.Core MX8M Mini SoM.

Anyone interested, please have a look on this repo [2]

[2] https://github.com/openedev/kernel/tree/imx8mm-dsi-v2 
[1] 
https://patchwork.kernel.org/project/dri-devel/cover/20220504114021.33265-1-ja...@amarulasolutions.com/

Any inputs?
Jagan.

Jagan Teki (12):
  drm: bridge: Add Samsung DSIM bridge driver
  drm: bridge: samsung-dsim: Lookup OF-graph or Child node devices
  drm: bridge: samsung-dsim: Handle platform init via driver_data
  drm: bridge: samsung-dsim: Mark PHY as optional
  drm: bridge: samsung-dsim: Add DSI init in bridge pre_enable()
  drm: bridge: samsung-dsim: Fix PLL_P (PMS_P) offset
  drm: bridge: samsung-dsim: Add module init, exit
  drm: bridge: samsung-dsim: Add atomic_check
  drm: bridge: samsung-dsim: Add atomic_get_input_bus_fmts
  drm: bridge: samsung-dsim: Add input_bus_flags
  dt-bindings: display: exynos: dsim: Add NXP i.MX8MM support
  drm: bridge: samsung-dsim: Add i.MX8MM support

Marek Szyprowski (1):
  drm: exynos: dsi: Restore proper bridge chain order

 .../bindings/display/exynos/exynos_dsim.txt   |1 +
 MAINTAINERS   |8 +
 drivers/gpu/drm/bridge/Kconfig|   12 +
 drivers/gpu/drm/bridge/Makefile   |1 +
 drivers/gpu/drm/bridge/samsung-dsim.c | 1850 +
 drivers/gpu/drm/exynos/Kconfig|1 +
 drivers/gpu/drm/exynos/exynos_drm_dsi.c   | 1717 +--
 include/drm/bridge/samsung-dsim.h |  106 +
 8 files changed, 2042 insertions(+), 1654 deletions(-)
 create mode 100644 drivers/gpu/drm/bridge/samsung-dsim.c
 create mode 100644 include/drm/bridge/samsung-dsim.h

-- 
2.25.1



[PATCH v4 31/41] dyndbg: add _DPRINTK_FLAGS_ENABLED

2022-07-20 Thread Jim Cromie
Distinguish the condition: _DPRINTK_FLAGS_ENABLED from the bit:
_DPRINTK_FLAGS_PRINT, and re-define former in terms of latter, in
preparation to add a 2nd bit: _DPRINTK_FLAGS_TRACE

Update JUMP_LABEL code block to check _DPRINTK_FLAGS_ENABLED symbol.
Also add a 'K' to get new symbol _DPRINTK_FLAGS_PRINTK, in order to
break any stale uses.

CC: vincent.whitchu...@axis.com
Signed-off-by: Jim Cromie 
---
 include/linux/dynamic_debug.h | 10 ++
 lib/dynamic_debug.c   |  8 
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index b50bdd5c8184..38cfdd5c0bdc 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -32,7 +32,7 @@ struct _ddebug {
 * writes commands to /dynamic_debug/control
 */
 #define _DPRINTK_FLAGS_NONE0
-#define _DPRINTK_FLAGS_PRINT   (1<<0) /* printk() a message using the format */
+#define _DPRINTK_FLAGS_PRINTK  (1 << 0) /* printk() a message using the format 
*/
 #define _DPRINTK_FLAGS_INCL_MODNAME(1<<1)
 #define _DPRINTK_FLAGS_INCL_FUNCNAME   (1<<2)
 #define _DPRINTK_FLAGS_INCL_LINENO (1<<3)
@@ -42,8 +42,10 @@ struct _ddebug {
(_DPRINTK_FLAGS_INCL_MODNAME | _DPRINTK_FLAGS_INCL_FUNCNAME |\
 _DPRINTK_FLAGS_INCL_LINENO  | _DPRINTK_FLAGS_INCL_TID)
 
+#define _DPRINTK_FLAGS_ENABLED _DPRINTK_FLAGS_PRINTK
+
 #if defined DEBUG
-#define _DPRINTK_FLAGS_DEFAULT _DPRINTK_FLAGS_PRINT
+#define _DPRINTK_FLAGS_DEFAULT _DPRINTK_FLAGS_PRINTK
 #else
 #define _DPRINTK_FLAGS_DEFAULT 0
 #endif
@@ -191,10 +193,10 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
 
 #ifdef DEBUG
 #define DYNAMIC_DEBUG_BRANCH(descriptor) \
-   likely(descriptor.flags & _DPRINTK_FLAGS_PRINT)
+   likely(descriptor.flags & _DPRINTK_FLAGS_ENABLED)
 #else
 #define DYNAMIC_DEBUG_BRANCH(descriptor) \
-   unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)
+   unlikely(descriptor.flags & _DPRINTK_FLAGS_ENABLED)
 #endif
 
 #endif /* CONFIG_JUMP_LABEL */
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index dd27dc514aa3..2a46c642373a 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -89,7 +89,7 @@ static inline const char *trim_prefix(const char *path)
 }
 
 static struct { unsigned flag:8; char opt_char; } opt_array[] = {
-   { _DPRINTK_FLAGS_PRINT, 'p' },
+   { _DPRINTK_FLAGS_PRINTK, 'p' },
{ _DPRINTK_FLAGS_INCL_MODNAME, 'm' },
{ _DPRINTK_FLAGS_INCL_FUNCNAME, 'f' },
{ _DPRINTK_FLAGS_INCL_LINENO, 'l' },
@@ -246,10 +246,10 @@ static int ddebug_change(const struct ddebug_query *query,
if (newflags == dp->flags)
continue;
 #ifdef CONFIG_JUMP_LABEL
-   if (dp->flags & _DPRINTK_FLAGS_PRINT) {
-   if (!(newflags & _DPRINTK_FLAGS_PRINT))
+   if (dp->flags & _DPRINTK_FLAGS_ENABLED) {
+   if (!(newflags & _DPRINTK_FLAGS_ENABLED))

static_branch_disable(>key.dd_key_true);
-   } else if (newflags & _DPRINTK_FLAGS_PRINT) {
+   } else if (newflags & _DPRINTK_FLAGS_ENABLED) {
static_branch_enable(>key.dd_key_true);
}
 #endif
-- 
2.36.1



[PATCH v4 34/41] dyndbg: add 2 trace-events: drm_{,dev}debug

2022-07-20 Thread Jim Cromie
Add include/trace/events/drm.h, with 2 new events: drm_debug() &
drm_devdbg(), and call them from drm_dbg() & drm_dev_dbg().  This is
easy, cuz the callers already build the vaf that the callee wants.

This allows the 3-5k drm.debug/on-dyndbg callsites to independently
(re-)direct messages to tracefs, not just syslog.  ISTM this is good;
debug traffic can be sent (just) to the tool where it can be best
used.  Over time, I'd expect to see less traffic to syslog.

NOTE: The message formats for the 2 events are both sub-optimal.
(both have event-name too)

drm_devdbg: TP_printk("cat:%d, %s %s", __entry->drm_debug_category,

  "cat:%d" should be "%s", but the classnames arent really in-scope
  here.  Maybe the events-decl-header should be under drm somewhere,
  so that class-names are available.

  It would also be nice to replace the event-name with the classname,
  as the names are highly client centric.

drm_dbg: TP_printk("%s", __get_str(msg))

  same as above.

NB:

The existing category param in this callchain is partially redundant;
when descriptor is available, it has the callsite's class_id.  If
later, CONFIG_DRM_USE_DYNAMIC_DEBUG:=y (hardwired), then category can
be dropped here, since the descriptor will always be available.

Also, if combined with header-move (or maybe its expanding inclusion
by lib/dynamic_debug), we could add the optional flags prefix, by
exposing dynamic_emit_prefix.  And perhaps this could be done only in
TP_printk, to save work while writing to the ring-buffer.

Signed-off-by: Jim Cromie 
---
 drivers/gpu/drm/drm_print.c | 25 -
 include/trace/events/drm.h  | 54 +
 2 files changed, 72 insertions(+), 7 deletions(-)
 create mode 100644 include/trace/events/drm.h

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 92f3f45e410c..9fb0b8e40dca 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -35,6 +35,9 @@
 #include 
 #include 
 
+#define CREATE_TRACE_POINTS
+#include 
+
 /*
  * __drm_debug: Enable debug output.
  * Bitmask of DRM_UT_x. See include/drm/drm_print.h for details.
@@ -293,13 +296,19 @@ void __drm_dev_dbg(struct _ddebug *desc, const struct 
device *dev,
vaf.fmt = format;
vaf.va = 
 
-   if (dev)
-   dev_printk(KERN_DEBUG, dev, "[" DRM_NAME ":%ps] %pV",
-  __builtin_return_address(0), );
-   else
-   printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV",
-  __builtin_return_address(0), );
-
+   if (dev) {
+   if (desc->flags & _DPRINTK_FLAGS_PRINTK)
+   dev_printk(KERN_DEBUG, dev, "[" DRM_NAME ":%ps] %pV",
+  __builtin_return_address(0), );
+   if (desc->flags & _DPRINTK_FLAGS_TRACE)
+   trace_drm_devdbg(dev, category, );
+   } else {
+   if (desc->flags & _DPRINTK_FLAGS_PRINTK)
+   printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV",
+  __builtin_return_address(0), );
+   if (desc->flags & _DPRINTK_FLAGS_TRACE)
+   trace_drm_debug(category, );
+   }
va_end(args);
 }
 EXPORT_SYMBOL(__drm_dev_dbg);
@@ -319,6 +328,8 @@ void ___drm_dbg(struct _ddebug *desc, enum 
drm_debug_category category, const ch
printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV",
   __builtin_return_address(0), );
 
+   trace_drm_debug(category, );
+
va_end(args);
 }
 EXPORT_SYMBOL(___drm_dbg);
diff --git a/include/trace/events/drm.h b/include/trace/events/drm.h
new file mode 100644
index ..589fa1e1f2c2
--- /dev/null
+++ b/include/trace/events/drm.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM drm
+
+#if !defined(_TRACE_DRM_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_DRM_H
+
+#include 
+
+/* drm_debug() was called, pass its args */
+TRACE_EVENT(drm_debug,
+   TP_PROTO(int drm_debug_category, struct va_format *vaf),
+
+   TP_ARGS(drm_debug_category, vaf),
+
+   TP_STRUCT__entry(
+   __field(int, drm_debug_category)
+   __vstring(msg, vaf->fmt, vaf->va)
+   ),
+
+   TP_fast_assign(
+   __entry->drm_debug_category = drm_debug_category;
+   __assign_vstr(msg, vaf->fmt, vaf->va);
+   ),
+
+   TP_printk("%s", __get_str(msg))
+);
+
+/* drm_devdbg() was called, pass its args, preserving order */
+TRACE_EVENT(drm_devdbg,
+   TP_PROTO(const struct device *dev, int drm_debug_category, struct 
va_format *vaf),
+
+   TP_ARGS(dev, drm_debug_category, vaf),
+
+   TP_STRUCT__entry(
+   __field(const struct device*, dev)
+   __field(int, drm_debug_category)
+   __vstring(msg, vaf->fmt, vaf->va)
+   ),
+
+   

[PATCH v4 28/41] drm_print: add _ddebug descriptor to drm_*dbg prototypes

2022-07-20 Thread Jim Cromie
upgrade the callchain to drm_dbg() and drm_dev_dbg(); add a struct
_ddebug ptr parameter to them, and supply that additional param by
replacing the '_no_desc' flavor of dyndbg Factory macro currently used
with the flavor that supplies the descriptor.

NOTES:

The descriptor gives these fns access to the decorator flags, but does
none of the dynamic-prefixing done by __dynamic_emit_prefix().

DRM already has conventions for logging/messaging; just tossing
optional decorations on top may not help.  Instead, existing flags (or
new ones) can be used to make current conventions optional.

For CONFIG_DRM_USE_DYNAMIC_DEBUG=N, just pass null.

Note: desc->class_id is redundant with category parameter, but its
availability is dependent on desc.

Signed-off-by: Jim Cromie 
---
 drivers/gpu/drm/drm_print.c |  8 +---
 include/drm/drm_print.h | 23 ---
 2 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index e0de79a22255..92f3f45e410c 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -278,8 +279,8 @@ void drm_dev_printk(const struct device *dev, const char 
*level,
 }
 EXPORT_SYMBOL(drm_dev_printk);
 
-void __drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
-  const char *format, ...)
+void __drm_dev_dbg(struct _ddebug *desc, const struct device *dev,
+  enum drm_debug_category category, const char *format, ...)
 {
struct va_format vaf;
va_list args;
@@ -287,6 +288,7 @@ void __drm_dev_dbg(const struct device *dev, enum 
drm_debug_category category,
if (!__drm_debug_enabled(category))
return;
 
+   /* we know we are printing for either syslog, tracefs, or both */
va_start(args, format);
vaf.fmt = format;
vaf.va = 
@@ -302,7 +304,7 @@ void __drm_dev_dbg(const struct device *dev, enum 
drm_debug_category category,
 }
 EXPORT_SYMBOL(__drm_dev_dbg);
 
-void ___drm_dbg(enum drm_debug_category category, const char *format, ...)
+void ___drm_dbg(struct _ddebug *desc, enum drm_debug_category category, const 
char *format, ...)
 {
struct va_format vaf;
va_list args;
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index 7631b5fb669e..46f14cfb401e 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -363,9 +363,10 @@ static inline bool drm_debug_enabled(enum 
drm_debug_category category)
 __printf(3, 4)
 void drm_dev_printk(const struct device *dev, const char *level,
const char *format, ...);
-__printf(3, 4)
-void __drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
-const char *format, ...);
+struct _ddebug;
+__printf(4, 5)
+void __drm_dev_dbg(struct _ddebug *desc, const struct device *dev,
+  enum drm_debug_category category, const char *format, ...);
 
 /**
  * DRM_DEV_ERROR() - Error output.
@@ -415,11 +416,11 @@ void __drm_dev_dbg(const struct device *dev, enum 
drm_debug_category category,
 
 #if !defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
 #define drm_dev_dbg(dev, cat, fmt, ...)\
-   __drm_dev_dbg(dev, cat, fmt, ##__VA_ARGS__)
+   __drm_dev_dbg(NULL, dev, cat, fmt, ##__VA_ARGS__)
 #else
 #define drm_dev_dbg(dev, cat, fmt, ...)\
-   _dynamic_func_call_no_desc(fmt, __drm_dev_dbg,  \
-  dev, cat, fmt, ##__VA_ARGS__)
+   _dynamic_func_call_cls(cat, fmt, __drm_dev_dbg, \
+  dev, cat, fmt, ##__VA_ARGS__)
 #endif
 
 /**
@@ -523,17 +524,17 @@ void __drm_dev_dbg(const struct device *dev, enum 
drm_debug_category category,
  * Prefer drm_device based logging over device or prink based logging.
  */
 
-__printf(2, 3)
-void ___drm_dbg(enum drm_debug_category category, const char *format, ...);
+__printf(3, 4)
+void ___drm_dbg(struct _ddebug *desc, enum drm_debug_category category, const 
char *format, ...);
 __printf(1, 2)
 void __drm_err(const char *format, ...);
 
 #if !defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
-#define __drm_dbg(fmt, ...)___drm_dbg(fmt, ##__VA_ARGS__)
+#define __drm_dbg(fmt, ...)___drm_dbg(NULL, fmt, ##__VA_ARGS__)
 #else
 #define __drm_dbg(cat, fmt, ...)   \
-   _dynamic_func_call_no_desc(fmt, ___drm_dbg, \
-  cat, fmt, ##__VA_ARGS__)
+   _dynamic_func_call_cls(cat, fmt, ___drm_dbg,\
+  cat, fmt, ##__VA_ARGS__)
 #endif
 
 /* Macros to make printk easier */
-- 
2.36.1



[PATCH v4 33/41] dyndbg: add write-events-to-tracefs code

2022-07-20 Thread Jim Cromie
1st, internals:

adds: ddebug_trace()
 uses trace_console() temporarily to issue printk:console event
 uses internal-ish __ftrace_trace_stack code:
  4-context buffer stack, barriers per Steve Rostedt

call it from new mid-layer funcs:
  ddebug_printk() - ddebug_trace or vprintk (to syslog)
  ddebug_dev_printk() - ddebug_trace or dev_printk_emit

These handle both _DPRINTK_FLAGS_PRINTK and _DPRINTK_FLAGS_TRACE
cases, allowing to vsnprintf the message once and use it for both,
skipping past the KERN_DEBUG prefix for tracing.

Finally, adjust the top-layer: __dynamic_{pr_debug,{,net,ib}dev_dbg),
replacing printk/dev_printk_emit with ddebug_printk/ddebug_dev_printk.

Interface additions:
  new 'T' flag decl in opt_array. existing code handles it like others.
  document the new flag.

To enable drm.debug ATOMIC messages to tracefs:

  :#> echo class DRM_UT_ATOMIC +T > /proc/dynamic_debug/control

NB:

This patch,~1,~2 are basically direct copies of:
  
https://lore.kernel.org/lkml/20200825153338.17061-1-vincent.whitchu...@axis.com/

with a few differences:

- s/dynamic_/ddebug_/ on Vincent's additions, tighter naming.
- __printf attrs on the _printk funcs.
- reuses trace_console() event, not adding a new "printk:dyndbg" event.
  later patches differentiate to new events.

- a flags arg remains unchanged, adapt later to *descriptor.

CC: vincent.whitchu...@axis.com
Signed-off-by: Jim Cromie 
---
 .../admin-guide/dynamic-debug-howto.rst   |   5 +-
 lib/dynamic_debug.c   | 156 +++---
 2 files changed, 133 insertions(+), 28 deletions(-)

diff --git a/Documentation/admin-guide/dynamic-debug-howto.rst 
b/Documentation/admin-guide/dynamic-debug-howto.rst
index faa22f77847a..45b6e5697c89 100644
--- a/Documentation/admin-guide/dynamic-debug-howto.rst
+++ b/Documentation/admin-guide/dynamic-debug-howto.rst
@@ -209,8 +209,9 @@ of the characters::
 
 The flags are::
 
-  penables the pr_debug() callsite.
-  _enables no flags.
+  pcallsite prints to syslog
+  Tcallsite issues a dyndbg:* trace-event
+  _enables no flags
 
   Decorator flags add to the message-prefix, in order:
   tInclude thread ID, or 
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 2a46c642373a..66f12b9127c7 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -90,6 +91,7 @@ static inline const char *trim_prefix(const char *path)
 
 static struct { unsigned flag:8; char opt_char; } opt_array[] = {
{ _DPRINTK_FLAGS_PRINTK, 'p' },
+   { _DPRINTK_FLAGS_TRACE, 'T' },
{ _DPRINTK_FLAGS_INCL_MODNAME, 'm' },
{ _DPRINTK_FLAGS_INCL_FUNCNAME, 'f' },
{ _DPRINTK_FLAGS_INCL_LINENO, 'l' },
@@ -835,6 +837,98 @@ static inline char *dynamic_emit_prefix(struct _ddebug 
*desc, char *buf)
return buf;
 }
 
+/*
+ * This code is heavily based on __ftrace_trace_stack().
+ *
+ * Allow 4 levels of nesting: normal, softirq, irq, NMI.
+ */
+#define DYNAMIC_TRACE_NESTING  4
+
+struct ddebug_trace_buf {
+   char buf[256];
+};
+
+struct ddebug_trace_bufs {
+   struct ddebug_trace_buf bufs[DYNAMIC_TRACE_NESTING];
+};
+
+static DEFINE_PER_CPU(struct ddebug_trace_bufs, ddebug_trace_bufs);
+static DEFINE_PER_CPU(int, ddebug_trace_reserve);
+
+static void ddebug_trace(const char *fmt, va_list args)
+{
+   struct ddebug_trace_buf *buf;
+   int bufidx;
+   int len;
+
+   preempt_disable_notrace();
+
+   bufidx = __this_cpu_inc_return(ddebug_trace_reserve) - 1;
+
+   if (WARN_ON_ONCE(bufidx > DYNAMIC_TRACE_NESTING))
+   goto out;
+
+   /* For the same reasons as in __ftrace_trace_stack(). */
+   barrier();
+
+   buf = this_cpu_ptr(ddebug_trace_bufs.bufs) + bufidx;
+
+   len = vscnprintf(buf->buf, sizeof(buf->buf), fmt, args);
+   trace_console(buf->buf, len);
+
+out:
+   /* As above. */
+   barrier();
+   __this_cpu_dec(ddebug_trace_reserve);
+   preempt_enable_notrace();
+}
+
+__printf(2, 3)
+static void ddebug_printk(unsigned int flags, const char *fmt, ...)
+{
+   if (flags & _DPRINTK_FLAGS_TRACE) {
+   va_list args;
+
+   va_start(args, fmt);
+   /*
+* All callers include the KERN_DEBUG prefix to keep the
+* vprintk case simple; strip it out for tracing.
+*/
+   ddebug_trace(fmt + strlen(KERN_DEBUG), args);
+   va_end(args);
+   }
+
+   if (flags & _DPRINTK_FLAGS_PRINTK) {
+   va_list args;
+
+   va_start(args, fmt);
+   vprintk(fmt, args);
+   va_end(args);
+   }
+}
+
+__printf(3, 4)
+static void ddebug_dev_printk(unsigned int flags, const struct device *dev,
+ const char *fmt, ...)
+{
+
+   if (flags & _DPRINTK_FLAGS_TRACE) {
+   va_list args;
+
+   va_start(args, fmt);
+

[PATCH drm-misc-next v5 3/4] drm/gem: rename struct drm_gem_dma_object.{paddr => dma_addr}

2022-07-20 Thread Danilo Krummrich
The field paddr of struct drm_gem_dma_object holds a DMA address, which
might actually be a physical address. However, depending on the platform,
it can also be a bus address or a virtual address managed by an IOMMU.

Hence, rename the field to dma_addr, which is more applicable.

In order to do this renaming the following coccinelle script was used:

```
@@
struct drm_gem_dma_object *gem;
@@

- gem->paddr
+ gem->dma_addr

@@
struct drm_gem_dma_object gem;
@@

- gem.paddr
+ gem.dma_addr

@exists@
typedef dma_addr_t;
symbol paddr;
@@

dma_addr_t paddr;
<...
- paddr
+ dma_addr
...>

@@
symbol paddr;
@@
dma_addr_t
- paddr
+ dma_addr
;

```

This patch is compile-time tested with:

```
make ARCH={x86_64,arm,arm64} allyesconfig
make ARCH={x86_64,arm,arm64} drivers/gpu/drm`
```

Reviewed-by: Laurent Pinchart 
Signed-off-by: Danilo Krummrich 
---
 .../arm/display/komeda/komeda_framebuffer.c   |  4 +--
 drivers/gpu/drm/arm/malidp_mw.c   |  2 +-
 drivers/gpu/drm/arm/malidp_planes.c   | 12 
 drivers/gpu/drm/aspeed/aspeed_gfx_crtc.c  |  2 +-
 .../gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c   |  2 +-
 drivers/gpu/drm/drm_fb_dma_helper.c   | 10 +++
 drivers/gpu/drm/drm_gem_dma_helper.c  | 23 +++---
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c   |  2 +-
 .../gpu/drm/hisilicon/kirin/kirin_drm_ade.c   |  4 +--
 drivers/gpu/drm/imx/dcss/dcss-plane.c |  6 ++--
 drivers/gpu/drm/imx/ipuv3-plane.c |  6 ++--
 drivers/gpu/drm/meson/meson_overlay.c |  6 ++--
 drivers/gpu/drm/meson/meson_plane.c   |  2 +-
 drivers/gpu/drm/mxsfb/mxsfb_kms.c | 30 +--
 drivers/gpu/drm/rcar-du/rcar_du_kms.c |  2 +-
 drivers/gpu/drm/rcar-du/rcar_du_plane.c   |  2 +-
 drivers/gpu/drm/rcar-du/rcar_du_vsp.c |  2 +-
 drivers/gpu/drm/shmobile/shmob_drm_crtc.c |  4 +--
 drivers/gpu/drm/shmobile/shmob_drm_plane.c|  4 +--
 drivers/gpu/drm/sprd/sprd_dpu.c   |  2 +-
 drivers/gpu/drm/sti/sti_gdp.c |  6 ++--
 drivers/gpu/drm/sti/sti_hqvdp.c   |  6 ++--
 drivers/gpu/drm/sun4i/sun4i_backend.c | 12 
 drivers/gpu/drm/sun4i/sun4i_frontend.c| 22 +++---
 drivers/gpu/drm/sun4i/sun8i_ui_layer.c| 14 -
 drivers/gpu/drm/sun4i/sun8i_vi_layer.c| 14 -
 drivers/gpu/drm/tidss/tidss_dispc.c   | 16 +-
 drivers/gpu/drm/tilcdc/tilcdc_crtc.c  |  2 +-
 drivers/gpu/drm/tiny/arcpgu.c |  2 +-
 drivers/gpu/drm/vc4/vc4_bo.c  |  2 +-
 drivers/gpu/drm/vc4/vc4_gem.c |  8 ++---
 drivers/gpu/drm/vc4/vc4_irq.c |  2 +-
 drivers/gpu/drm/vc4/vc4_plane.c   |  4 +--
 drivers/gpu/drm/vc4/vc4_render_cl.c   | 14 -
 drivers/gpu/drm/vc4/vc4_txp.c |  2 +-
 drivers/gpu/drm/vc4/vc4_v3d.c |  4 +--
 drivers/gpu/drm/vc4/vc4_validate.c| 12 
 drivers/gpu/drm/xlnx/zynqmp_disp.c|  6 ++--
 include/drm/drm_gem_dma_helper.h  |  4 +--
 39 files changed, 142 insertions(+), 137 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
index f1b27db5dad5..df5da5a44755 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
@@ -137,7 +137,7 @@ komeda_fb_none_afbc_size_check(struct komeda_dev *mdev, 
struct komeda_fb *kfb,
}
 
min_size = komeda_fb_get_pixel_addr(kfb, 0, fb->height, i)
-- to_drm_gem_dma_obj(obj)->paddr;
+- to_drm_gem_dma_obj(obj)->dma_addr;
if (obj->size < min_size) {
DRM_DEBUG_KMS("The fb->obj[%d] size: 0x%zx lower than 
the minimum requirement: 0x%llx.\n",
  i, obj->size, min_size);
@@ -260,7 +260,7 @@ komeda_fb_get_pixel_addr(struct komeda_fb *kfb, int x, int 
y, int plane)
+ plane_y * fb->pitches[plane];
}
 
-   return obj->paddr + offset;
+   return obj->dma_addr + offset;
 }
 
 /* if the fb can be supported by a specific layer */
diff --git a/drivers/gpu/drm/arm/malidp_mw.c b/drivers/gpu/drm/arm/malidp_mw.c
index cefae03f1bcc..ef76d0e6ee2f 100644
--- a/drivers/gpu/drm/arm/malidp_mw.c
+++ b/drivers/gpu/drm/arm/malidp_mw.c
@@ -170,7 +170,7 @@ malidp_mw_encoder_atomic_check(struct drm_encoder *encoder,
return -EINVAL;
}
mw_state->pitches[i] = fb->pitches[i];
-   mw_state->addrs[i] = obj->paddr + fb->offsets[i];
+   

[PATCH drm-misc-next v5 4/4] drm/todo: remove task to rename CMA helpers

2022-07-20 Thread Danilo Krummrich
Both, GEM and FB, CMA helpers were renamed to "GEM DMA" and "FB DMA",
hence the task can be removed.

Acked-by: Thomas Zimmermann 
Reviewed-by: Laurent Pinchart 
Signed-off-by: Danilo Krummrich 
---
 Documentation/gpu/todo.rst | 13 -
 1 file changed, 13 deletions(-)

diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index 10bfb50908d1..fd5b3f2fb19e 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -343,19 +343,6 @@ converted, except for struct drm_driver.gem_prime_mmap.
 
 Level: Intermediate
 
-Rename CMA helpers to DMA helpers
--
-
-CMA (standing for contiguous memory allocator) is really a bit an accident of
-what these were used for first, a much better name would be DMA helpers. In the
-text these should even be called coherent DMA memory helpers (so maybe CDM, but
-no one knows what that means) since underneath they just use 
dma_alloc_coherent.
-
-Contact: Laurent Pinchart, Daniel Vetter
-
-Level: Intermediate (mostly because it is a huge tasks without good partial
-milestones, not technically itself that challenging)
-
 connector register/unregister fixes
 ---
 
-- 
2.36.1



[PATCH v4 32/41] dyndbg: add _DPRINTK_FLAGS_TRACE

2022-07-20 Thread Jim Cromie
add new flag, and OR it into _DPRINTK_FLAGS_ENABLED definition

CC: vincent.whitchu...@axis.com
Signed-off-by: Jim Cromie 
---
 include/linux/dynamic_debug.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 38cfdd5c0bdc..0752e6c21c6e 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -42,7 +42,9 @@ struct _ddebug {
(_DPRINTK_FLAGS_INCL_MODNAME | _DPRINTK_FLAGS_INCL_FUNCNAME |\
 _DPRINTK_FLAGS_INCL_LINENO  | _DPRINTK_FLAGS_INCL_TID)
 
-#define _DPRINTK_FLAGS_ENABLED _DPRINTK_FLAGS_PRINTK
+#define _DPRINTK_FLAGS_TRACE   (1 << 5)
+#define _DPRINTK_FLAGS_ENABLED (_DPRINTK_FLAGS_PRINTK | \
+_DPRINTK_FLAGS_TRACE)
 
 #if defined DEBUG
 #define _DPRINTK_FLAGS_DEFAULT _DPRINTK_FLAGS_PRINTK
-- 
2.36.1



[PULL] drm-intel-fixes

2022-07-20 Thread Rodrigo Vivi
Hi Dave and Daniel,

This is basically only the guc regression fix.
The other patch is just a dependency to make the
important patch to apply cleanly without conflict.

drm-intel-fixes-2022-07-20-1:
- Fix the regression caused by the lack of GuC v70.
  Let's accept the fallback to v69.

Thanks,
Rodrigo.

The following changes since commit ff6992735ade75aae3e35d16b17da1008d753d28:

  Linux 5.19-rc7 (2022-07-17 13:30:22 -0700)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-intel tags/drm-intel-fixes-2022-07-20-1

for you to fetch changes up to 443148858f26ee0fea6ad1b292d49d884dce92d1:

  drm/i915/guc: support v69 in parallel to v70 (2022-07-19 21:25:03 -0400)


- Fix the regression caused by the lack of GuC v70.
  Let's accept the fallback to v69.


Daniele Ceraolo Spurio (1):
  drm/i915/guc: support v69 in parallel to v70

Matthew Brost (1):
  drm/i915/guc: Support programming the EU priority in the GuC descriptor

 drivers/gpu/drm/i915/gt/intel_context_types.h  |  11 +-
 .../gpu/drm/i915/gt/intel_execlists_submission.c   |  12 +-
 drivers/gpu/drm/i915/gt/intel_lrc.h|  10 -
 drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h   |   3 +
 drivers/gpu/drm/i915/gt/uc/intel_guc.h |   5 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h|  45 +++
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c  | 374 ++---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c   |  56 ++-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h   |   7 +
 9 files changed, 450 insertions(+), 73 deletions(-)


[PATCH v4 36/41] dyndbg/drm: POC add tracebits sysfs-knob

2022-07-20 Thread Jim Cromie
clone DRM.debug interface to DRM.tracebits: ie declare __drm_trace,
map its bits to drm-debug-categories, except this interface enables
messages to tracefs, not to syslog.

1- we reuse the drm_debug_classes class-map added previously.
   this reflects the single source of both syslog/trace events
   and is why structs classmap and bitmap-param are separate.

2- add a 2nd struct ddebug_classes_bitmap_param
   refs 1, reusing it.
   flags = "T", to enable trace-events on this callsite.

3- module_param_cb([2]) - does the sysfs part

Signed-off-by: Jim Cromie 
---
 drivers/gpu/drm/drm_print.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 9fb0b8e40dca..47a41d96beea 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -45,6 +45,9 @@
 unsigned long __drm_debug;
 EXPORT_SYMBOL(__drm_debug);
 
+unsigned long __drm_trace;
+EXPORT_SYMBOL(__drm_trace);
+
 MODULE_PARM_DESC(debug, "Enable debug output, where each bit enables a debug 
category.\n"
 "\t\tBit 0 (0x01)  will enable CORE messages (drm core code)\n"
 "\t\tBit 1 (0x02)  will enable DRIVER messages (drm controller code)\n"
@@ -77,6 +80,13 @@ static struct ddebug_classes_bitmap_param drm_debug_bitmap = 
{
.map = _debug_classes,
 };
 module_param_cb(debug, _ops_dyndbg_classes, _debug_bitmap, 0600);
+
+static struct ddebug_classes_bitmap_param drm_trace_bitmap = {
+   .bits = &__drm_trace,
+   .flags = "T",
+   .map = _debug_classes,
+};
+module_param_cb(tracecats, _ops_dyndbg_classes, _trace_bitmap, 0600);
 #endif
 
 void __drm_puts_coredump(struct drm_printer *p, const char *str)
-- 
2.36.1



[PATCH v4 26/41] drm_print: refine drm_debug_enabled for jump-label

2022-07-20 Thread Jim Cromie
In order to use dynamic-debug's jump-label optimization in drm-debug,
its clarifying to refine drm_debug_enabled into 3 uses:

1.   drm_debug_enabled - legacy, public
2. __drm_debug_enabled - optimized for dyndbg jump-label enablement.
3.  _drm_debug_enabled - pr_debug instrumented, observable

1. The legacy version always checks the bits.

2. is privileged, for use by __drm_dbg(), __drm_dev_dbg(), which do an
early return unless the category is enabled.  For dyndbg builds, debug
callsites are selectively "pre-enabled", so __drm_debug_enabled()
short-circuits to true there.  Remaining callers of 1 may be able to
use 2, case by case.

3. is 1st wrapped in a macro, with a pr_debug, which reports each
usage in /proc/dynamic_debug/control, making it observable in the
logs.  The macro lets the pr_debug see the real caller, not an inline
function.

When plugged into 1, 3 identified ~10 remaining callers of the
function, leading to the follow-on cleanup patch, and would allow
activating the pr_debugs, estimating the callrate, and the potential
savings by using the wrapper macro.  It is unused ATM, but it fills
out the picture.

Signed-off-by: Jim Cromie 
---
 drivers/gpu/drm/drm_print.c |  4 ++--
 include/drm/drm_print.h | 28 
 2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 21b416af0be2..effb95b3c2bf 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -285,7 +285,7 @@ void __drm_dev_dbg(const struct device *dev, enum 
drm_debug_category category,
struct va_format vaf;
va_list args;
 
-   if (!drm_debug_enabled(category))
+   if (!__drm_debug_enabled(category))
return;
 
va_start(args, format);
@@ -308,7 +308,7 @@ void ___drm_dbg(enum drm_debug_category category, const 
char *format, ...)
struct va_format vaf;
va_list args;
 
-   if (!drm_debug_enabled(category))
+   if (!__drm_debug_enabled(category))
return;
 
va_start(args, format);
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index dfdd81c3287c..7631b5fb669e 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -321,11 +321,39 @@ enum drm_debug_category {
DRM_UT_DRMRES
 };
 
+/*
+ * 3 name flavors of drm_debug_enabled:
+ *   drm_debug_enabled - public/legacy, always checks bits
+ *  _drm_debug_enabled - instrumented to observe call-rates, est overheads.
+ * __drm_debug_enabled - privileged - knows jump-label state, can short-circuit
+ */
 static inline bool drm_debug_enabled(enum drm_debug_category category)
 {
return unlikely(__drm_debug & BIT(category));
 }
 
+/*
+ * Wrap fn in macro, so that the pr_debug sees the actual caller, not
+ * the inline fn.  Using this name creates a callsite entry / control
+ * point in /proc/dynamic_debug/control.
+ */
+#define _drm_debug_enabled(category)   \
+   ({  \
+   pr_debug("todo: maybe avoid via dyndbg\n"); \
+   drm_debug_enabled(category);\
+   })
+
+#if defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
+/*
+ * dyndbg is wrapping the drm.debug API, so as to avoid the runtime
+ * bit-test overheads of drm_debug_enabled() in those api calls.
+ * In this case, executed callsites are known enabled, so true.
+ */
+#define __drm_debug_enabled(category)  true
+#else
+#define __drm_debug_enabled(category)  drm_debug_enabled(category)
+#endif
+
 /*
  * struct device based logging
  *
-- 
2.36.1



[PATCH v4 27/41] drm_print: prefer bare printk KERN_DEBUG on generic fn

2022-07-20 Thread Jim Cromie
drm_print.c calls pr_debug() just once, from __drm_printfn_debug(),
which is a generic/service fn.  The callsite is compile-time enabled
by DEBUG in both DYNAMIC_DEBUG=y/n builds.

For dyndbg builds, reverting this callsite back to bare printk is
correcting a few anti-features:

1- callsite is generic, serves multiple drm users.
   it is soft-wired on currently by #define DEBUG
   could accidentally: #> echo -p > /proc/dynamic_debug/control

2- optional "decorations" by dyndbg are unhelpful/misleading here,
   they describe only the generic site, not end users

IOW, 1,2 are unhelpful at best, and possibly confusing.

reverting yields a nominal data and text shrink:

   textdata bss dec hex filename
 462583   36604   54592 553779   87333 /kernel/drivers/gpu/drm/drm.ko
 462515   36532   54592 553639   872a7 -dirty/kernel/drivers/gpu/drm/drm.ko

Signed-off-by: Jim Cromie 
---
 drivers/gpu/drm/drm_print.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index effb95b3c2bf..e0de79a22255 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -23,8 +23,6 @@
  * Rob Clark 
  */
 
-#define DEBUG /* for pr_debug() */
-
 #include 
 
 #include 
@@ -185,7 +183,8 @@ EXPORT_SYMBOL(__drm_printfn_info);
 
 void __drm_printfn_debug(struct drm_printer *p, struct va_format *vaf)
 {
-   pr_debug("%s %pV", p->prefix, vaf);
+   /* pr_debug callsite decorations are unhelpful here */
+   printk(KERN_DEBUG "%s %pV", p->prefix, vaf);
 }
 EXPORT_SYMBOL(__drm_printfn_debug);
 
-- 
2.36.1



[PATCH v4 38/41] nouveau-dyndbg: alter DEBUG, TRACE, SPAM levels to use dyndbg

2022-07-20 Thread Jim Cromie
clone the nvkm_printk,_,__ macro ladder into nvkm_drmdbg,_,__.
And alter debug, trace, spam macros to use the renamed ladder.

This *sets-up* to remove the _subdev->debug >= (l) condition from the
__ macro, once the bitmap-param is wired up correctly (pointing at the
right state-bit-vector), and figured into dyndbg's jump-label
enablement.

Also, with DYNDBG=y, sites will be off, until enabled by >control, or
by #define DEBUG at compile time.

Starting with this as a model:

static struct ddebug_classes_bitmap_param drm_trace_bitmap = {
.bits = &__drm_trace,
.flags = "T",
.map = _trace_classes,
};
module_param_cb(tracecats, _ops_dyndbg_classes, _trace_bitmap,..

We basically need to clone that, but ref a different .bits:
.bits = &_subdev->debug,
while respecting the _subdev's lifecycle.
hints welcomed.

no functional changes. (other than dyndbg's default-off)

Signed-off-by: Jim Cromie 
---
 drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h | 14 +++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h 
b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h
index 065d07ccea87..b9c2afab321f 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h
@@ -59,9 +59,17 @@ void nvkm_subdev_intr(struct nvkm_subdev *);
 #define nvkm_error(s,f,a...) nvkm_printk((s), ERROR,err, f, ##a)
 #define nvkm_warn(s,f,a...)  nvkm_printk((s),  WARN, notice, f, ##a)
 #define nvkm_info(s,f,a...)  nvkm_printk((s),  INFO,   info, f, ##a)
-#define nvkm_debug(s,f,a...) nvkm_printk((s), DEBUG,dbg, f, ##a)
-#define nvkm_trace(s,f,a...) nvkm_printk((s), TRACE,dbg, f, ##a)
-#define nvkm_spam(s,f,a...)  nvkm_printk((s),  SPAM,dbg, f, ##a)
+
+#define nvkm_drmdbg__(s,l,p,f,a...) do {   \
+   const struct nvkm_subdev *_subdev = (s);\
+   if (CONFIG_NOUVEAU_DEBUG >= (l) && _subdev->debug >= (l))   \
+   dev_dbg(_subdev->device->dev, "%s: "f, _subdev->name, ##a); \
+} while(0)
+#define nvkm_drmdbg_(s,l,f,a...) nvkm_drmdbg__((s), NV_DBG_##l, dbg, f, ##a)
+#define nvkm_debug(s,f,a...) nvkm_drmdbg_((s), DEBUG, f, ##a)
+#define nvkm_trace(s,f,a...) nvkm_drmdbg_((s), TRACE, f, ##a)
+#define nvkm_spam(s,f,a...)  nvkm_drmdbg_((s),  SPAM, f, ##a)
 
 #define nvkm_error_ratelimited(s,f,a...) nvkm_printk((s), ERROR, 
err_ratelimited, f, ##a)
+
 #endif
-- 
2.36.1



[PATCH v4 39/41] nouveau-dbg: add 2 verbose-classmaps for CLI, SUBDEV

2022-07-20 Thread Jim Cromie
nouveau has additional debug variables to consider:

drivers/gpu/drm/nouveau/include/nvkm/core/device.h
131:if (_device->debug >= (l)) \

drivers/gpu/drm/nouveau/include/nvkm/core/client.h
39: if (_client->debug >= NV_DBG_##l)  \

drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h
54: if (CONFIG_NOUVEAU_DEBUG >= (l) && _subdev->debug >= (l))  \

This is another baby-step, that seems not to break, so lets get a
snapshot.

whats done here:

In nouveau_drm.c, declare class-names: NV_CLI_DBG_* NV_SUBDEV_DBG_* by
calling DECLARE_DYNDBG_CLASSMAP(verbose-type) 2x more, right after the
drm DECLARE, for cli and subdev.  Adjust base to 10,15, to avoid 0-10
allocated subsystem-wide for drm.debug.  This shares the 0..30
classid-space.

In nvkm/core/debug.h, add enums to match the names, with initial
values to match the bases.

In nvkm/core/subdev.h, alter (recently added) nvkm_drmdbg_() to use
NV_SUBDEV_DBG_* instead of NV_DBG_*.  Note: this is undone next,
because base != CONFIG_NOUVEAU_DEBUG.

NOTES:

class-name-space is flat and wide, so super-generic names like INFO
should be prefixed; who could predict what a generic "V1" does across
all modules.

A sub-system prefix, such as "DRM_UT_" could be considered a working
shorthand for module "foo,bar,buzz" (which wouldnt work), but it adds
a layer of authors-judgment in the classifications.

In both classmaps, Ive left FATAL..WARN out, they're not really
optional the way INFO..SPAM are; even if they were defaulted to on,
dyndbg shouldn't be able to turn them off.

bash-5.1# modprobe nouveau
[  966.107833] dyndbg:   3 debug prints in module wmi
[  966.342188] dyndbg: class[0]: module:nouveau base:15 len:5 ty:1
[  966.342873] dyndbg:  15: 0 NV_SUBDEV_DBG_OFF
[  966.343352] dyndbg:  16: 1 NV_SUBDEV_DBG_INFO
[  966.343912] dyndbg:  17: 2 NV_SUBDEV_DBG_DEBUG
[  966.33] dyndbg:  18: 3 NV_SUBDEV_DBG_TRACE
[  966.344938] dyndbg:  19: 4 NV_SUBDEV_DBG_SPAM
[  966.345402] dyndbg: class[1]: module:nouveau base:10 len:5 ty:1
[  966.346011] dyndbg:  10: 0 NV_CLI_DBG_OFF
[  966.346477] dyndbg:  11: 1 NV_CLI_DBG_INFO
[  966.346989] dyndbg:  12: 2 NV_CLI_DBG_DEBUG
[  966.347442] dyndbg:  13: 3 NV_CLI_DBG_TRACE
[  966.347875] dyndbg:  14: 4 NV_CLI_DBG_SPAM
[  966.348284] dyndbg: class[2]: module:nouveau base:0 len:10 ty:0
[  966.34] dyndbg:  0: 0 DRM_UT_CORE
[  966.349310] dyndbg:  1: 1 DRM_UT_DRIVER
[  966.349694] dyndbg:  2: 2 DRM_UT_KMS
[  966.350083] dyndbg:  3: 3 DRM_UT_PRIME
[  966.350482] dyndbg:  4: 4 DRM_UT_ATOMIC
[  966.351016] dyndbg:  5: 5 DRM_UT_VBL
[  966.351475] dyndbg:  6: 6 DRM_UT_STATE
[  966.351899] dyndbg:  7: 7 DRM_UT_LEASE
[  966.352309] dyndbg:  8: 8 DRM_UT_DP
[  966.352678] dyndbg:  9: 9 DRM_UT_DRMRES
[  966.353104] dyndbg: module:nouveau attached 3 classes
[  966.353759] dyndbg: 119 debug prints in module nouveau

NOTE: it was 632 with previous commit, switching NV_DEBUG to use
NV_SUBDEV_DBG_DEBUG instead of NV_DBG_DEBUG is the cause.

Signed-off-by: Jim Cromie 
---
 .../gpu/drm/nouveau/include/nvkm/core/debug.h| 16 
 .../gpu/drm/nouveau/include/nvkm/core/subdev.h   |  3 ++-
 drivers/gpu/drm/nouveau/nouveau_drm.c| 14 ++
 3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/debug.h 
b/drivers/gpu/drm/nouveau/include/nvkm/core/debug.h
index b4a9c7d991ca..6a155a23a3d1 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/debug.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/debug.h
@@ -9,4 +9,20 @@
 #define NV_DBG_TRACE5
 #define NV_DBG_PARANOIA 6
 #define NV_DBG_SPAM 7
+
+enum nv_cli_dbg_verbose {
+   NV_CLI_DBG_OFF = 10,
+   NV_CLI_DBG_INFO,
+   NV_CLI_DBG_DEBUG,
+   NV_CLI_DBG_TRACE,
+   NV_CLI_DBG_SPAM
+};
+enum nv_subdev_dbg_verbose {
+   NV_SUBDEV_DBG_OFF = 15,
+   NV_SUBDEV_DBG_INFO,
+   NV_SUBDEV_DBG_DEBUG,
+   NV_SUBDEV_DBG_TRACE,
+   NV_SUBDEV_DBG_SPAM
+};
+
 #endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h 
b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h
index b9c2afab321f..bf9c69f4fc3e 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h
@@ -2,6 +2,7 @@
 #ifndef __NVKM_SUBDEV_H__
 #define __NVKM_SUBDEV_H__
 #include 
+#include 
 
 enum nvkm_subdev_type {
 #define NVKM_LAYOUT_ONCE(t,s,p,...) t,
@@ -65,7 +66,7 @@ void nvkm_subdev_intr(struct nvkm_subdev *);
if (CONFIG_NOUVEAU_DEBUG >= (l) && _subdev->debug >= (l))   \
dev_dbg(_subdev->device->dev, "%s: "f, _subdev->name, ##a); \
 } while(0)
-#define nvkm_drmdbg_(s,l,f,a...) nvkm_drmdbg__((s), NV_DBG_##l, dbg, f, ##a)
+#define nvkm_drmdbg_(s,l,f,a...) nvkm_drmdbg__((s), NV_SUBDEV_DBG_##l, dbg, f, 
##a)
 #define nvkm_debug(s,f,a...) nvkm_drmdbg_((s), DEBUG, f, ##a)
 #define nvkm_trace(s,f,a...) nvkm_drmdbg_((s), TRACE, f, ##a)
 

[PATCH v4 22/41] drm_print: interpose drm_*dbg with forwarding macros

2022-07-20 Thread Jim Cromie
change drm_dev_dbg & drm_dbg to macros, which forward to the renamed
functions (with __ prefix added).

Those functions sit below the categorized layer of macros implementing
the DRM debug.category API, and implement most of it.  These are good
places to insert dynamic-debug jump-label mechanics, which will allow
DRM to avoid the runtime cost of drm_debug_enabled().

no functional changes.

memory cost baseline: (unchanged)
bash-5.1# drms_load
[9.220389] dyndbg:   1 debug prints in module drm
[9.224426] ACPI: bus type drm_connector registered
[9.302192] dyndbg:   2 debug prints in module ttm
[9.305033] dyndbg:   8 debug prints in module video
[9.627563] dyndbg: 127 debug prints in module i915
[9.721505] AMD-Vi: AMD IOMMUv2 functionality not available on this system - 
This is not a bug.
[   10.091345] dyndbg: 2196 debug prints in module amdgpu
[   10.106589] [drm] amdgpu kernel modesetting enabled.
[   10.107270] amdgpu: CRAT table not found
[   10.107926] amdgpu: Virtual CRAT table created for CPU
[   10.108398] amdgpu: Topology: Add CPU node
[   10.168507] dyndbg:   3 debug prints in module wmi
[   10.329587] dyndbg:   3 debug prints in module nouveau

Signed-off-by: Jim Cromie 
---
 drivers/gpu/drm/drm_print.c | 10 +-
 include/drm/drm_print.h |  9 +++--
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 44be95fac164..21b416af0be2 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -279,8 +279,8 @@ void drm_dev_printk(const struct device *dev, const char 
*level,
 }
 EXPORT_SYMBOL(drm_dev_printk);
 
-void drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
-const char *format, ...)
+void __drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
+  const char *format, ...)
 {
struct va_format vaf;
va_list args;
@@ -301,9 +301,9 @@ void drm_dev_dbg(const struct device *dev, enum 
drm_debug_category category,
 
va_end(args);
 }
-EXPORT_SYMBOL(drm_dev_dbg);
+EXPORT_SYMBOL(__drm_dev_dbg);
 
-void __drm_dbg(enum drm_debug_category category, const char *format, ...)
+void ___drm_dbg(enum drm_debug_category category, const char *format, ...)
 {
struct va_format vaf;
va_list args;
@@ -320,7 +320,7 @@ void __drm_dbg(enum drm_debug_category category, const char 
*format, ...)
 
va_end(args);
 }
-EXPORT_SYMBOL(__drm_dbg);
+EXPORT_SYMBOL(___drm_dbg);
 
 void __drm_err(const char *format, ...)
 {
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index 668273e36c2c..c429c258c957 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -335,7 +335,7 @@ __printf(3, 4)
 void drm_dev_printk(const struct device *dev, const char *level,
const char *format, ...);
 __printf(3, 4)
-void drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
+void __drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
 const char *format, ...);
 
 /**
@@ -384,6 +384,9 @@ void drm_dev_dbg(const struct device *dev, enum 
drm_debug_category category,
}   \
 })
 
+#define drm_dev_dbg(dev, cat, fmt, ...)\
+   __drm_dev_dbg(dev, cat, fmt, ##__VA_ARGS__)
+
 /**
  * DRM_DEV_DEBUG() - Debug output for generic drm code
  *
@@ -485,10 +488,12 @@ void drm_dev_dbg(const struct device *dev, enum 
drm_debug_category category,
  */
 
 __printf(2, 3)
-void __drm_dbg(enum drm_debug_category category, const char *format, ...);
+void ___drm_dbg(enum drm_debug_category category, const char *format, ...);
 __printf(1, 2)
 void __drm_err(const char *format, ...);
 
+#define __drm_dbg(fmt, ...)___drm_dbg(fmt, ##__VA_ARGS__)
+
 /* Macros to make printk easier */
 
 #define _DRM_PRINTK(once, level, fmt, ...) \
-- 
2.36.1



[PATCH v4 37/41] nouveau: adapt NV_DEBUG, NV_ATOMIC to use DRM.debug

2022-07-20 Thread Jim Cromie
These 2 macros used drm_debug_enabled() on DRM_UT_{DRIVER,ATOMIC}
respectively, replace those with drm_dbg_##cat invocations.

this results in new class'd prdbg callsites:

:#> grep nouveau /proc/dynamic_debug/control | grep class | wc
1161130   15584
:#> grep nouveau /proc/dynamic_debug/control | grep class | grep DRIVER | wc
 74 7049709
:#> grep nouveau /proc/dynamic_debug/control | grep class | grep ATOMIC | wc
 31 3074237
:#> grep nouveau /proc/dynamic_debug/control | grep class | grep KMS | wc
 11 1191638

the KMS entries are due to existing uses of drm_dbg_kms().

Signed-off-by: Jim Cromie 
---
 drivers/gpu/drm/nouveau/nouveau_drv.h | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h 
b/drivers/gpu/drm/nouveau/nouveau_drv.h
index b2a970aa9bf4..f266cd6b0405 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -39,6 +39,7 @@
  */
 
 #include 
+#include 
 
 #include 
 #include 
@@ -264,13 +265,16 @@ void nouveau_drm_device_remove(struct drm_device *dev);
 #define NV_WARN(drm,f,a...) NV_PRINTK(warn, &(drm)->client, f, ##a)
 #define NV_INFO(drm,f,a...) NV_PRINTK(info, &(drm)->client, f, ##a)
 
-#define NV_DEBUG(drm,f,a...) do {  
\
-   if (drm_debug_enabled(DRM_UT_DRIVER))  \
-   NV_PRINTK(info, &(drm)->client, f, ##a);   \
+#define NV_DRMDBG(cat,c,f,a...) do {   \
+   struct nouveau_cli *_cli = (c); \
+   drm_dbg_##cat(_cli->drm->dev, "%s: "f, _cli->name, ##a); \
 } while(0)
-#define NV_ATOMIC(drm,f,a...) do { 
\
-   if (drm_debug_enabled(DRM_UT_ATOMIC))  \
-   NV_PRINTK(info, &(drm)->client, f, ##a);   \
+
+#define NV_DEBUG(drm,f,a...) do {  \
+   NV_DRMDBG(driver, &(drm)->client, f, ##a);  \
+} while(0)
+#define NV_ATOMIC(drm,f,a...) do { \
+   NV_DRMDBG(atomic, &(drm)->client, f, ##a);  \
 } while(0)
 
 #define NV_PRINTK_ONCE(l,c,f,a...) NV_PRINTK(l##_once,c,f, ##a)
-- 
2.36.1



[PATCH v4 40/41] nouveau-dbg: fixup lost prdbgs

2022-07-20 Thread Jim Cromie
Undo the 1-line change that reduced count of prdbgs from 632 to 119.

ie: s/NV_SUBDEV_DBG_##l/NV_DBG_##l/

So heres what happened: new symbol is 15 (or 10), and fails this macro
test, so gets compiled out, and the dev_dbg is excluded.

if (CONFIG_NOUVEAU_DEBUG >= (l) && _subdev->debug >= (l))   \
dev_dbg(_subdev->device->dev, "%s: "f, _subdev->name, ##a); \

I could hack this, by hardcoding in (l + #base), but base is pretty
distant to just toss into the macro.  At least, the base-ref should be
a macro() properly exposing it.

OTOH, the whole CONFIG_NOUVEAU_DEBUG check could be reworked; given
that trace is minumum recommended, theres not that many callsites
elided (SPAM only iirc) at compile-time, and dyndbg means keeping them
has "zero" run=cost (and 56 bytes per).  So this config item doesnt do
much when DRM_USE_DYNAMIC_DEBUG=y.

So this is a useful place to stop and take another look around, try to
guess which trail to take..

Signed-off-by: Jim Cromie 
---
 drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h 
b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h
index bf9c69f4fc3e..d5f6ca05d5fa 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h
@@ -66,7 +66,7 @@ void nvkm_subdev_intr(struct nvkm_subdev *);
if (CONFIG_NOUVEAU_DEBUG >= (l) && _subdev->debug >= (l))   \
dev_dbg(_subdev->device->dev, "%s: "f, _subdev->name, ##a); \
 } while(0)
-#define nvkm_drmdbg_(s,l,f,a...) nvkm_drmdbg__((s), NV_SUBDEV_DBG_##l, dbg, f, 
##a)
+#define nvkm_drmdbg_(s,l,f,a...) nvkm_drmdbg__((s), NV_DBG_##l, dbg, f, ##a)
 #define nvkm_debug(s,f,a...) nvkm_drmdbg_((s), DEBUG, f, ##a)
 #define nvkm_trace(s,f,a...) nvkm_drmdbg_((s), TRACE, f, ##a)
 #define nvkm_spam(s,f,a...)  nvkm_drmdbg_((s),  SPAM, f, ##a)
-- 
2.36.1



[PATCH v4 41/41] nouveau-dyndbg: wip subdev refine, breaks on use

2022-07-20 Thread Jim Cromie
Change nvkm_subdev.debug to a ulong, so dyndbg can maybe use it.

Move macro decl from nv-drm.c to subdev.c, and add a struct
ddebug_classes_bitmap_param and a module_param_cb() that creates the
sysfs-knob.

Finally, in nvkm_subdev_ctor(), *attempt* to set dyndbg's pointer to
the debug address, so that dyndbg can observe the underlying debug
value, and make enable/disable decisions based upon it.

But Im not getting the ctor called, so the ptr is NULL when refd.

Signed-off-by: Jim Cromie 
---
 .../drm/nouveau/include/nvkm/core/subdev.h|  2 +-
 drivers/gpu/drm/nouveau/nouveau_drm.c |  7 --
 drivers/gpu/drm/nouveau/nvkm/core/subdev.c| 23 +++
 3 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h 
b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h
index d5f6ca05d5fa..05807403fdd6 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h
@@ -19,7 +19,7 @@ struct nvkm_subdev {
enum nvkm_subdev_type type;
int inst;
char name[16];
-   u32 debug;
+   unsigned long debug;
struct list_head head;
 
void **pself;
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c 
b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 85b63b527877..d45c71ffc09e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -90,13 +90,6 @@ DECLARE_DYNDBG_CLASSMAP(nv_cli_debug_verbose, 
DD_CLASS_TYPE_VERBOSE, 10,
"NV_CLI_DBG_TRACE",
"NV_CLI_DBG_SPAM");
 
-DECLARE_DYNDBG_CLASSMAP(nv_subdev_debug_verbose, DD_CLASS_TYPE_VERBOSE, 15,
-   "NV_SUBDEV_DBG_OFF",
-   "NV_SUBDEV_DBG_INFO",
-   "NV_SUBDEV_DBG_DEBUG",
-   "NV_SUBDEV_DBG_TRACE",
-   "NV_SUBDEV_DBG_SPAM");
-
 MODULE_PARM_DESC(config, "option string to pass to driver core");
 static char *nouveau_config;
 module_param_named(config, nouveau_config, charp, 0400);
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/subdev.c 
b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c
index a74b7acb6832..227871c3a749 100644
--- a/drivers/gpu/drm/nouveau/nvkm/core/subdev.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c
@@ -26,6 +26,27 @@
 #include 
 #include 
 
+#include 
+#include 
+
+#define DEBUG
+
+DECLARE_DYNDBG_CLASSMAP(nv_subdev_debug_verbose, DD_CLASS_TYPE_VERBOSE, 15,
+   "NV_SUBDEV_DBG_OFF",
+   "NV_SUBDEV_DBG_INFO",
+   "NV_SUBDEV_DBG_DEBUG",
+   "NV_SUBDEV_DBG_TRACE",
+   "NV_SUBDEV_DBG_SPAM");
+
+static struct ddebug_classes_bitmap_param nv_subdev_verbose = {
+   .bits = NULL, // wants &_subdev->debug
+   .flags = "p",
+   .map = _subdev_debug_verbose,
+};
+module_param_cb(debug_subdev, _ops_dyndbg_classes, _subdev_verbose, 
0600);
+
+
+
 const char *
 nvkm_subdev_type[NVKM_SUBDEV_NR] = {
 #define NVKM_LAYOUT_ONCE(type,data,ptr,...) [type] = #ptr,
@@ -180,6 +201,8 @@ nvkm_subdev_ctor(const struct nvkm_subdev_func *func, 
struct nvkm_device *device
else
strscpy(subdev->name, nvkm_subdev_type[type], 
sizeof(subdev->name));
subdev->debug = nvkm_dbgopt(device->dbgopt, subdev->name);
+   nv_subdev_verbose.bits = >debug;
+   pr_debug("updated bitmap: %px\n", _subdev_verbose.bits);
list_add_tail(>head, >subdev);
 }
 
-- 
2.36.1



[PATCH v4 25/41] drm-print: include dyndbg header indirectly

2022-07-20 Thread Jim Cromie
lkp robot told me:

  >> drivers/gpu/drm/drm_ioc32.c:989:2:
  error: call to undeclared function '_dynamic_func_call_cls';
  ISO C99 and later do not support implicit function declarations
  [-Wimplicit-function-declaration]

   DRM_DEBUG("comm=\"%s\", pid=%d, dev=0x%lx, auth=%d, %s\n",

Since that macro is defined in drm_print.h, include 
there too, so that any uses have the definitions of all the macros in
the callchain.

This is done as a separate patch mostly to see how lkp sorts it;
I'll probably squash it with HEAD~1

Signed-off-by: Jim Cromie 
---
 include/drm/drm_print.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index 3aa5e9ea26f4..dfdd81c3287c 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
-- 
2.36.1



[PATCH v4 05/41] dyndbg: reverse module.callsite walk in cat control

2022-07-20 Thread Jim Cromie
Walk the module's vector of callsites backwards; ie N..0.  This
"corrects" the backwards appearance of a module's prdbg vector when
walked 0..N.  I think this is due to linker mechanics, which I'm
inclined to treat as immutable, and the order is fixable in display.

No functional changes.

Combined with previous commit, which reversed tables-list, we get:

  :#> head -n7 /proc/dynamic_debug/control
  # filename:lineno [module]function flags format
  init/main.c:1179 [main]initcall_blacklist =_ "blacklisting initcall %s\012"
  init/main.c:1218 [main]initcall_blacklisted =_ "initcall %s blacklisted\012"
  init/main.c:1424 [main]run_init_process =_ "  with arguments:\012"
  init/main.c:1426 [main]run_init_process =_ "%s\012"
  init/main.c:1427 [main]run_init_process =_ "  with environment:\012"
  init/main.c:1429 [main]run_init_process =_ "%s\012"

Signed-off-by: Jim Cromie 
---
 lib/dynamic_debug.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 7fb99492c16f..8ff11977b8bd 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -59,7 +59,7 @@ struct ddebug_query {
 
 struct ddebug_iter {
struct ddebug_table *table;
-   unsigned int idx;
+   int idx;
 };
 
 struct flag_settings {
@@ -805,13 +805,12 @@ static struct _ddebug *ddebug_iter_first(struct 
ddebug_iter *iter)
 {
if (list_empty(_tables)) {
iter->table = NULL;
-   iter->idx = 0;
return NULL;
}
iter->table = list_entry(ddebug_tables.next,
 struct ddebug_table, link);
-   iter->idx = 0;
-   return >table->ddebugs[iter->idx];
+   iter->idx = iter->table->num_ddebugs;
+   return >table->ddebugs[--iter->idx];
 }
 
 /*
@@ -824,15 +823,16 @@ static struct _ddebug *ddebug_iter_next(struct 
ddebug_iter *iter)
 {
if (iter->table == NULL)
return NULL;
-   if (++iter->idx == iter->table->num_ddebugs) {
+   if (--iter->idx < 0) {
/* iterate to next table */
-   iter->idx = 0;
if (list_is_last(>table->link, _tables)) {
iter->table = NULL;
return NULL;
}
iter->table = list_entry(iter->table->link.next,
 struct ddebug_table, link);
+   iter->idx = iter->table->num_ddebugs;
+   --iter->idx;
}
return >table->ddebugs[iter->idx];
 }
-- 
2.36.1



[PATCH v4 30/41] tracing/events: Add __vstring() and __assign_vstr() helper macros

2022-07-20 Thread Jim Cromie
From: "Steven Rostedt (Google)" 

Steve's patch, carried til upstream.

There's several places that open code the following logic:

  TP_STRUCT__entry(__dynamic_array(char, msg, MSG_MAX)),
  TP_fast_assign(vsnprintf(__get_str(msg), MSG_MAX, vaf->fmt, *vaf->va);)

To load a string created by variable array va_list.

The main issue with this approach is that "MSG_MAX" usage in the
__dynamic_array() portion. That actually just reserves the MSG_MAX in the
event, and even wastes space because there's dynamic meta data also saved
in the event to denote the offset and size of the dynamic array. It would
have been better to just use a static __array() field.

Instead, create __vstring() and __assign_vstr() that work like __string
and __assign_str() but instead of taking a destination string to copy,
take a format string and a va_list pointer and fill in the values.

It uses the helper:

 #define __trace_event_vstr_len(fmt, va)\
 ({ \
va_list __ap;   \
int __ret;  \
\
va_copy(__ap, *(va));   \
__ret = vsnprintf(NULL, 0, fmt, __ap);  \
va_end(__ap);   \
\
min(__ret, TRACE_EVENT_STR_MAX);\
 })

To figure out the length to store the string. It may be slightly slower as
it needs to run the vsnprintf() twice, but it now saves space on the ring
buffer.

Link: https://lkml.kernel.org/r/20220705224749.053570...@goodmis.org

Cc: Dennis Dalessandro 
Cc: Ingo Molnar 
Cc: Andrew Morton 
Cc: Jason Gunthorpe 
Cc: Leon Romanovsky 
Cc: Kalle Valo 
Cc: "David S. Miller" 
Cc: Eric Dumazet 
Cc: Jakub Kicinski 
Cc: Paolo Abeni 
Cc: Arend van Spriel 
Cc: Franky Lin 
Cc: Hante Meuleman 
Cc: Gregory Greenman 
Cc: Peter Chen 
Cc: Greg Kroah-Hartman 
Cc: Mathias Nyman 
Cc: Chunfeng Yun 
Cc: Bin Liu 
Cc: Marek Lindner 
Cc: Simon Wunderlich 
Cc: Antonio Quartulli 
Cc: Sven Eckelmann 
Cc: Johannes Berg 
Cc: Jim Cromie 
Signed-off-by: Steven Rostedt (Google) 
---
 include/linux/trace_events.h | 18 ++
 include/trace/stages/stage1_struct_define.h  |  3 +++
 include/trace/stages/stage2_data_offsets.h   |  3 +++
 include/trace/stages/stage4_event_fields.h   |  3 +++
 include/trace/stages/stage5_get_offsets.h|  4 
 include/trace/stages/stage6_event_callback.h |  7 +++
 6 files changed, 38 insertions(+)

diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h
index e6e95a9f07a5..b18759a673c6 100644
--- a/include/linux/trace_events.h
+++ b/include/linux/trace_events.h
@@ -916,6 +916,24 @@ perf_trace_buf_submit(void *raw_data, int size, int rctx, 
u16 type,
 
 #endif
 
+#define TRACE_EVENT_STR_MAX512
+
+/*
+ * gcc warns that you can not use a va_list in an inlined
+ * function. But lets me make it into a macro :-/
+ */
+#define __trace_event_vstr_len(fmt, va)\
+({ \
+   va_list __ap;   \
+   int __ret;  \
+   \
+   va_copy(__ap, *(va));   \
+   __ret = vsnprintf(NULL, 0, fmt, __ap) + 1;  \
+   va_end(__ap);   \
+   \
+   min(__ret, TRACE_EVENT_STR_MAX);\
+})
+
 #endif /* _LINUX_TRACE_EVENT_H */
 
 /*
diff --git a/include/trace/stages/stage1_struct_define.h 
b/include/trace/stages/stage1_struct_define.h
index a16783419687..1b7bab60434c 100644
--- a/include/trace/stages/stage1_struct_define.h
+++ b/include/trace/stages/stage1_struct_define.h
@@ -26,6 +26,9 @@
 #undef __string_len
 #define __string_len(item, src, len) __dynamic_array(char, item, -1)
 
+#undef __vstring
+#define __vstring(item, fmt, ap) __dynamic_array(char, item, -1)
+
 #undef __bitmask
 #define __bitmask(item, nr_bits) __dynamic_array(char, item, -1)
 
diff --git a/include/trace/stages/stage2_data_offsets.h 
b/include/trace/stages/stage2_data_offsets.h
index 42fd1e8813ec..1b7a8f764fdd 100644
--- a/include/trace/stages/stage2_data_offsets.h
+++ b/include/trace/stages/stage2_data_offsets.h
@@ -32,6 +32,9 @@
 #undef __string_len
 #define __string_len(item, src, len) __dynamic_array(char, item, -1)
 
+#undef __vstring
+#define __vstring(item, fmt, ap) __dynamic_array(char, item, -1)
+
 #undef __bitmask
 #define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1)
 
diff --git a/include/trace/stages/stage4_event_fields.h 
b/include/trace/stages/stage4_event_fields.h
index e80cdc397a43..c3790ec7a453 100644
--- a/include/trace/stages/stage4_event_fields.h
+++ b/include/trace/stages/stage4_event_fields.h
@@ -38,6 +38,9 @@
 #undef __string_len
 #define __string_len(item, src, len) 

[PATCH v4 18/41] doc-dyndbg: describe "class CLASS_NAME" query support

2022-07-20 Thread Jim Cromie
Add an explanation of the new "class CLASS_NAME" syntax and meaning,
noting that the module determines if CLASS_NAME applies to it.

Signed-off-by: Jim Cromie 
---
 Documentation/admin-guide/dynamic-debug-howto.rst | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/Documentation/admin-guide/dynamic-debug-howto.rst 
b/Documentation/admin-guide/dynamic-debug-howto.rst
index a89cfa083155..d8954ab05c7b 100644
--- a/Documentation/admin-guide/dynamic-debug-howto.rst
+++ b/Documentation/admin-guide/dynamic-debug-howto.rst
@@ -35,6 +35,7 @@ Dynamic debug has even more useful features:
- line number (including ranges of line numbers)
- module name
- format string
+   - class name (as known/declared by each module)
 
  * Provides a debugfs control file: ``/dynamic_debug/control``
which can be read to display the complete list of known debug
@@ -142,6 +143,7 @@ against.  Possible keywords are:::
 'file' string |
 'module' string |
 'format' string |
+'class' string |
 'line' line-range
 
   line-range ::= lineno |
@@ -203,6 +205,15 @@ format
format "nfsd: SETATTR"  // a neater way to match a format with 
whitespace
format 'nfsd: SETATTR'  // yet another way to match a format with 
whitespace
 
+class
+The given class_name is validated against each module, which may
+have declared a list of known class_names.  If the class_name is
+found for a module, callsite & class matching and adjustment
+proceeds.  Examples::
+
+   class DRM_UT_KMS# a DRM.debug category
+   class JUNK  # silent non-match
+
 line
 The given line number or range of line numbers is compared
 against the line number of each ``pr_debug()`` callsite.  A single
-- 
2.36.1



[PATCH v4 16/41] dyndbg: add drm.debug style bitmap support

2022-07-20 Thread Jim Cromie
Add kernel_param_ops and callbacks to apply a class-map to a
sysfs-node, which then can control classes defined in that class-map.
This supports uses like:

  echo 0x3 > /sys/module/drm/parameters/debug

IE add these:

 - int param_set_dyndbg_classes()
 - int param_get_dyndbg_classes()
 - struct kernel_param_ops param_ops_dyndbg_classes

Following the model of kernel/params.c STANDARD_PARAM_DEFS, these are
non-static and exported.  This might be unnecessary here.

get/set use an augmented kernel_param; the arg refs a new struct
ddebug_classes_bitmap_param, initialized by DYNAMIC_DEBUG_CLASSBITS
macro, which contains:

BITS: a pointer to the user module's ulong holding the bits/state.  By
ref'g the client's bit-state _var, we coordinate with existing code
(such as drm_debug_enabled) which uses the _var, so it works
unchanged, even as the foundation is switched out underneath it..
Using a ulong allows use of BIT() etc.

FLAGS: dyndbg.flags toggled by changes to bitmap. Usually just "p".

MAP: a pointer to struct ddebug_classes_map, which maps those
class-names to .class_ids 0..N that the module is using.  This
class-map is declared & initialized by DEFINE_DYNDBG_CLASSMAP.

map-type: add support here for DD_CLASS_DISJOINT, DD_CLASS_VERBOSE.

These 2 class-types both expect an integer; _DISJOINT treats input
like a bit-vector (ala drm.debug), and sets each bit accordingly.

_VERBOSE treats input like a bit-pos:N, then sets bits(0..N)=1, and
bits(N+1..max)=0.  This applies (bit bitmap transform that set-param does
on VERBOSE inputs, this gives the read-what-was-written property.

_VERBOSE is overlay on _DISJOINT:

verbose-maps still need class-names, even though theyre not usable at
the sysfs interface (unlike with _SYMBOLIC/_LEVELS).

 - It must have a "V0" name,
   something below "V1" to turn "V1" off.
   __pr_debug_cls(V0,..) is printk, don't do that.

 - "class names" is required at the >control interface.
 - relative levels are not enforced at >control

IOW this is possible, and maybe confusing:

  echo class V3 +p > control
  echo class V1 -p > control

IMO thats ok, relative verbosity is an interface property.

Signed-off-by: Jim Cromie 
---
. drop kp->mod->name as unneeded (build-dependent) 
---
 include/linux/dynamic_debug.h |  18 
 lib/dynamic_debug.c   | 193 ++
 2 files changed, 211 insertions(+)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index f57076e02767..b50bdd5c8184 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -113,6 +113,12 @@ struct ddebug_class_map {
 #define NUM_TYPE_ARGS(eltype, ...) \
(sizeof((eltype[]) {__VA_ARGS__}) / sizeof(eltype))
 
+struct ddebug_classes_bitmap_param {
+   unsigned long *bits;
+   char flags[8];
+   const struct ddebug_class_map *map;
+};
+
 #if defined(CONFIG_DYNAMIC_DEBUG_CORE)
 
 int ddebug_add_module(struct _ddebug *tab, unsigned int num_debugs,
@@ -274,6 +280,10 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
   KERN_DEBUG, prefix_str, prefix_type, \
   rowsize, groupsize, buf, len, ascii)
 
+struct kernel_param;
+int param_set_dyndbg_classes(const char *instr, const struct kernel_param *kp);
+int param_get_dyndbg_classes(char *buffer, const struct kernel_param *kp);
+
 /* for test only, generally expect drm.debug style macro wrappers */
 #define __pr_debug_cls(cls, fmt, ...) do { \
BUILD_BUG_ON_MSG(!__builtin_constant_p(cls),\
@@ -322,6 +332,14 @@ static inline int ddebug_dyndbg_module_param_cb(char 
*param, char *val,
rowsize, groupsize, buf, len, ascii);   \
} while (0)
 
+struct kernel_param;
+static inline int param_set_dyndbg_classes(const char *instr, const struct 
kernel_param *kp)
+{ return 0; }
+static inline int param_get_dyndbg_classes(char *buffer, const struct 
kernel_param *kp)
+{ return 0; }
+
 #endif /* !CONFIG_DYNAMIC_DEBUG_CORE */
 
+extern const struct kernel_param_ops param_ops_dyndbg_classes;
+
 #endif
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 4c27bbe5187e..dd27dc514aa3 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -596,6 +596,199 @@ static int ddebug_exec_queries(char *query, const char 
*modname)
return nfound;
 }
 
+static int ddebug_apply_class_bitmap(const struct ddebug_classes_bitmap_param 
*dcp,
+unsigned long inbits)
+{
+#define QUERY_SIZE 128
+   char query[QUERY_SIZE];
+   const struct ddebug_class_map *map = dcp->map;
+   int matches = 0;
+   int bi, ct;
+
+   v2pr_info("in: 0x%lx on: 0x%lx\n", inbits, *dcp->bits);
+
+   for (bi = 0; bi < map->length; bi++) {
+   if (test_bit(bi, ) == test_bit(bi, dcp->bits))
+   continue;
+
+   snprintf(query, QUERY_SIZE, "class %s %c%s", 

[PATCH v4 29/41] nouveau: change nvkm_debug/trace to use dev_dbg POC

2022-07-20 Thread Jim Cromie
These 2 macros formerly used dev_info, and they still check
subdev->debug to gate the printing.  So dyndbg control is redundant
ATM (and possibly confusing, since its off by default).

prdbg count is up from 3, or from 65 (with VMM_DEBUG here)

[7.765379] dyndbg: 516 debug prints in module nouveau

Its possible to control error, warn, info callsites too, but they're
usually on, and the .data overheads on ~450 more callsites (56 bytes
each) would just be wasted.

$ for l in fatal error warn info debug trace spam; do
  echo $l; ack nvkm_$l drivers/gpu |wc; done
fatal
  3  19 335
error
2891956   30651
warn
 84 5138860
info
 14  881502
debug
3872339   40844
trace
 31 2193368
spam
  1   7 123

bash-5.1# echo $(( 516-65-387-31-1 ))
32

Thats approximate; not accounting #defines and doc/comment mentions.

NOTE: this patch changes the log-level of the macro-issued messages
from KERN_INFO to KERN_DEBUG.  Adding a .kern_lvl field to struct
_ddebug could fix that.

RFC: dyndbg & subdev->debug

Separate class-maps for each subdev are possible; except for the
coordinated use of _base, each is independent, including choice of
DISJOINT or LEVELS, as long as class-names don't conflict.
So theres some flexibility.

Signed-off-by: Jim Cromie 
---
 drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h 
b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h
index 96113c8bee8c..065d07ccea87 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/subdev.h
@@ -59,8 +59,8 @@ void nvkm_subdev_intr(struct nvkm_subdev *);
 #define nvkm_error(s,f,a...) nvkm_printk((s), ERROR,err, f, ##a)
 #define nvkm_warn(s,f,a...)  nvkm_printk((s),  WARN, notice, f, ##a)
 #define nvkm_info(s,f,a...)  nvkm_printk((s),  INFO,   info, f, ##a)
-#define nvkm_debug(s,f,a...) nvkm_printk((s), DEBUG,   info, f, ##a)
-#define nvkm_trace(s,f,a...) nvkm_printk((s), TRACE,   info, f, ##a)
+#define nvkm_debug(s,f,a...) nvkm_printk((s), DEBUG,dbg, f, ##a)
+#define nvkm_trace(s,f,a...) nvkm_printk((s), TRACE,dbg, f, ##a)
 #define nvkm_spam(s,f,a...)  nvkm_printk((s),  SPAM,dbg, f, ##a)
 
 #define nvkm_error_ratelimited(s,f,a...) nvkm_printk((s), ERROR, 
err_ratelimited, f, ##a)
-- 
2.36.1



[PATCH v4 24/41] drm-print: add drm_dbg_driver to improve namespace symmetry

2022-07-20 Thread Jim Cromie
drm_print defines all of these:
drm_dbg_{core,kms,prime,atomic,vbl,lease,_dp,_drmres}

but not drm_dbg_driver itself, since it was the original drm_dbg.

To improve namespace symmetry, change the drm_dbg defn to
drm_dbg_driver, and redef grandfathered name to symmetric one.

This will help with nouveau, which uses its own stack of macros to
construct calls to dev_info, dev_dbg, etc, for which adaptation means
drm_dbg_##driver constructs.

Signed-off-by: Jim Cromie 
---
 include/drm/drm_print.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index 2d2cef76b5c1..3aa5e9ea26f4 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -467,7 +467,7 @@ void __drm_dev_dbg(const struct device *dev, enum 
drm_debug_category category,
 
 #define drm_dbg_core(drm, fmt, ...)\
drm_dev_dbg((drm) ? (drm)->dev : NULL, DRM_UT_CORE, fmt, ##__VA_ARGS__)
-#define drm_dbg(drm, fmt, ...) \
+#define drm_dbg_driver(drm, fmt, ...)  
\
drm_dev_dbg((drm) ? (drm)->dev : NULL, DRM_UT_DRIVER, fmt, 
##__VA_ARGS__)
 #define drm_dbg_kms(drm, fmt, ...) \
drm_dev_dbg((drm) ? (drm)->dev : NULL, DRM_UT_KMS, fmt, ##__VA_ARGS__)
@@ -486,6 +486,7 @@ void __drm_dev_dbg(const struct device *dev, enum 
drm_debug_category category,
 #define drm_dbg_drmres(drm, fmt, ...)  \
drm_dev_dbg((drm) ? (drm)->dev : NULL, DRM_UT_DRMRES, fmt, 
##__VA_ARGS__)
 
+#define drm_dbg(drm, fmt, ...) drm_dbg_driver(drm, fmt, ##__VA_ARGS__)
 
 /*
  * printk based logging
-- 
2.36.1



[PATCH v4 35/41] dyndbg: add 2 more trace-events: pr_debug, dev_dbg

2022-07-20 Thread Jim Cromie
ddebug_trace() currently issues a single printk:console event.
Replace that, adding include/trace/events/dyndbg.h, which defines 2
new events:

- dyndbg:prdbg  - from trace_prdbg()  - if !dev
- dyndbg:devdbg - from trace_devdbg() - if !!dev

This links the legacy pr_debug API to tracefs, via dyndbg, allowing
pr_debug()s etc to add just a little more user-context to the
trace-logs, and then at users option, less syslog.

The 2 new trace_*() calls accept their caller's args respectively,
keeping the available info w/o alteration; we can't improve on
full disclosure.  The args:

 1- struct _ddebug *descriptor, giving tracefs all of dyndbg's info.
this replaces flags, which is in desc
 2- struct device *dev, used by trace_devdbg(), if !!dev

The trace_*() calls need the descriptor arg, the prototypes of the
callchain above them are extended to provide it.

dev_dbg(desc, dev...), if dev is true, issues a trace_devdbg(),
otherwise trace_prdbg().  This way we don't consume buffer space
storing nulls.  Otherwise the events are equivalent.

Signed-off-by: Jim Cromie 
---
 include/trace/events/dyndbg.h | 74 +++
 lib/dynamic_debug.c   | 73 +-
 2 files changed, 111 insertions(+), 36 deletions(-)
 create mode 100644 include/trace/events/dyndbg.h

diff --git a/include/trace/events/dyndbg.h b/include/trace/events/dyndbg.h
new file mode 100644
index ..e19fcb56566c
--- /dev/null
+++ b/include/trace/events/dyndbg.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM dyndbg
+
+#if !defined(_TRACE_DYNDBG_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_DYNDBG_H
+
+#include 
+
+/* capture pr_debug() callsite descriptor and message */
+TRACE_EVENT(prdbg,
+   TP_PROTO(const struct _ddebug *desc, const char *text, size_t len),
+
+   TP_ARGS(desc, text, len),
+
+   TP_STRUCT__entry(
+   __field(const struct _ddebug *, desc)
+   __dynamic_array(char, msg, len + 1)
+   ),
+
+   TP_fast_assign(
+   __entry->desc = desc;
+   /*
+* Each trace entry is printed in a new line.
+* If the msg finishes with '\n', cut it off
+* to avoid blank lines in the trace.
+*/
+   if (len > 0 && (text[len - 1] == '\n'))
+   len -= 1;
+
+   memcpy(__get_str(msg), text, len);
+   __get_str(msg)[len] = 0;
+   ),
+
+   TP_printk("%s.%s %s", __entry->desc->modname,
+ __entry->desc->function, __get_str(msg))
+);
+
+/* capture dev_dbg() callsite descriptor, device, and message */
+TRACE_EVENT(devdbg,
+   TP_PROTO(const struct _ddebug *desc, const struct device *dev,
+const char *text, size_t len),
+
+   TP_ARGS(desc, dev, text, len),
+
+   TP_STRUCT__entry(
+   __field(const struct _ddebug *, desc)
+   __field(const struct device *, dev)
+   __dynamic_array(char, msg, len + 1)
+   ),
+
+   TP_fast_assign(
+   __entry->desc = desc;
+   __entry->dev = (struct device *) dev;
+   /*
+* Each trace entry is printed in a new line.
+* If the msg finishes with '\n', cut it off
+* to avoid blank lines in the trace.
+*/
+   if (len > 0 && (text[len - 1] == '\n'))
+   len -= 1;
+
+   memcpy(__get_str(msg), text, len);
+   __get_str(msg)[len] = 0;
+   ),
+
+   TP_printk("%s.%s %s", __entry->desc->modname,
+ __entry->desc->function, __get_str(msg))
+);
+
+#endif /* _TRACE_DYNDBG_H */
+
+/* This part must be outside protection */
+#include 
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 66f12b9127c7..e000d037cb2e 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -36,7 +36,9 @@
 #include 
 #include 
 #include 
-#include 
+
+#define CREATE_TRACE_POINTS
+#include 
 
 #include 
 
@@ -855,7 +857,9 @@ struct ddebug_trace_bufs {
 static DEFINE_PER_CPU(struct ddebug_trace_bufs, ddebug_trace_bufs);
 static DEFINE_PER_CPU(int, ddebug_trace_reserve);
 
-static void ddebug_trace(const char *fmt, va_list args)
+__printf(3, 0)
+static void ddebug_trace(struct _ddebug *desc, const struct device *dev,
+const char *fmt, va_list args)
 {
struct ddebug_trace_buf *buf;
int bufidx;
@@ -874,7 +878,11 @@ static void ddebug_trace(const char *fmt, va_list args)
buf = this_cpu_ptr(ddebug_trace_bufs.bufs) + bufidx;
 
len = vscnprintf(buf->buf, sizeof(buf->buf), fmt, args);
-   trace_console(buf->buf, len);
+
+   if 

[PATCH v4 17/41] dyndbg: test DECLARE_DYNDBG_CLASSMAP, sysfs nodes

2022-07-20 Thread Jim Cromie
Demonstrate use of DECLARE_DYNDBG_CLASSMAP macro, and expose them as
sysfs-nodes for testing.

For each of the 4 class-map-types:

  - declare a class-map of that type,
  - declare the enum corresponding to those class-names
  - share _base across 0..30 range
  - add a __pr_debug_cls() call for each class-name
  - declare 2 sysnodes for each class-map
for 'p' flag, and future 'T' flag

These declarations create the following sysfs parameter interface:

  :> pwd
  /sys/module/test_dynamic_debug/parameters
  :> ls
  T_disjoint  T_levels  T_symbolic  T_verbosity  do_prints
  p_disjoint  p_levels  p_symbolic  p_verbosity

NOTES:

The local wrapper macro is an api candidate, but there are already too
many parameters.  OTOH, maybe related enum should be in there too,
since it has _base inter-dependencies.

The T_* params control the (future) T flag on the same class'd
pr_debug callsites as their p* counterparts.  Using them will fail,
until the dyndbg-trace patches are added in.

:#> echo 1 > T_disjoint
[   28.792489] dyndbg: disjoint: 0x1 > test_dynamic_debug.T_D2
[   28.793848] dyndbg: query 0: "class D2_CORE +T" mod:*
[   28.795086] dyndbg: split into words: "class" "D2_CORE" "+T"
[   28.796467] dyndbg: op='+'
[   28.797148] dyndbg: unknown flag 'T'
[   28.798021] dyndbg: flags parse failed
[   28.798947] dyndbg: processed 1 queries, with 0 matches, 1 errs
[   28.800378] dyndbg: bit_0: -22 matches on class: D2_CORE -> 0x1
[   28.801959] dyndbg: test_dynamic_debug.T_D2: updated 0x0 -> 0x1
[   28.803974] dyndbg: total matches: -22

Signed-off-by: Jim Cromie 
---
 lib/test_dynamic_debug.c | 125 ++-
 1 file changed, 110 insertions(+), 15 deletions(-)

diff --git a/lib/test_dynamic_debug.c b/lib/test_dynamic_debug.c
index ba3882ca3e48..eac85e4e996a 100644
--- a/lib/test_dynamic_debug.c
+++ b/lib/test_dynamic_debug.c
@@ -10,57 +10,152 @@
 
 #include 
 
-static void do_prints(void); /* device under test */
-
-/* run tests by reading or writing sysfs node */
+/* run tests by reading or writing sysfs node: do_prints */
 
+static void do_prints(void); /* device under test */
 static int param_set_do_prints(const char *instr, const struct kernel_param 
*kp)
 {
do_prints();
return 0;
 }
-
 static int param_get_do_prints(char *buffer, const struct kernel_param *kp)
 {
do_prints();
return scnprintf(buffer, PAGE_SIZE, "did do_prints\n");
 }
-
 static const struct kernel_param_ops param_ops_do_prints = {
.set = param_set_do_prints,
.get = param_get_do_prints,
 };
-
 module_param_cb(do_prints, _ops_do_prints, NULL, 0600);
 
-static void do_alpha(void)
+/*
+ * Using the CLASSMAP api:
+ * - classmaps must have corresponding enum
+ * - enum symbols must match/correlate with class-name strings in the map.
+ * - base must equal enum's 1st value
+ * - multiple maps must set their base to share the 0-30 class_id space !!
+ *   (build-bug-on tips welcome)
+ * Additionally, here:
+ * - tie together sysname, mapname, bitsname, flagsname
+ */
+#define DD_SYS_WRAP(_model, _flags)\
+   static unsigned long bits_##_model; \
+   static struct ddebug_classes_bitmap_param _flags##_model = {\
+   .bits = _##_model, \
+   .flags = #_flags,   \
+   .map = _##_model,   \
+   };  \
+   module_param_cb(_flags##_##_model, _ops_dyndbg_classes, 
&_flags##_model, 0600)
+
+/* numeric input, independent bits */
+enum cat_disjoint {
+   D2_CORE = 0,
+   D2_DRIVER,
+   D2_KMS,
+   D2_PRIME,
+   D2_ATOMIC,
+   D2_VBL,
+   D2_STATE,
+   D2_LEASE,
+   D2_DP,
+   D2_DRMRES };
+DECLARE_DYNDBG_CLASSMAP(map_disjoint, DD_CLASS_TYPE_DISJOINT, 0,
+   "D2_CORE",
+   "D2_DRIVER",
+   "D2_KMS",
+   "D2_PRIME",
+   "D2_ATOMIC",
+   "D2_VBL",
+   "D2_STATE",
+   "D2_LEASE",
+   "D2_DP",
+   "D2_DRMRES");
+DD_SYS_WRAP(disjoint, p);
+DD_SYS_WRAP(disjoint, T);
+
+/* symbolic input, independent bits */
+enum cat_symbolic { LOW = 11, MID, HI };
+DECLARE_DYNDBG_CLASSMAP(map_symbolic, DD_CLASS_TYPE_SYMBOLIC, 10,
+   "LOW", "MID", "HI");
+DD_SYS_WRAP(symbolic, p);
+DD_SYS_WRAP(symbolic, T);
+
+/* numeric verbosity, V2 > V1 related */
+enum cat_verbosity { V0 = 14, V1, V2, V3, V4, V5, V6, V7 };
+DECLARE_DYNDBG_CLASSMAP(map_verbosity, DD_CLASS_TYPE_VERBOSE, 14,
+  "V0", "V1", "V2", "V3", "V4", "V5", "V6", "V7");
+DD_SYS_WRAP(verbosity, p);
+DD_SYS_WRAP(verbosity, T);
+
+/* symbolic verbosity */
+enum cat_levels { L0 = 22, L1, L2, L3, L4, L5, 

[PATCH v4 11/41] dyndbg: add __pr_debug_cls for testing

2022-07-20 Thread Jim Cromie
For selftest purposes, add __pr_debug_cls(class, fmt, ...)

I didn't think we'd need to define this, since DRM effectively has it
already in drm_dbg, drm_devdbg.  But test_dynamic_debug needs it in
order to demonstrate all the moving parts.

Note the __ prefix; its not intended for general use, at least until a
need emerges.  ISTM the drm.debug model (macro wrappers inserting enum
const 1st arg) is the baseline approach.

NB: it does require a builtin-constant class, no __pr_debug_cls(i"",...)

Signed-off-by: Jim Cromie 
---
 include/linux/dynamic_debug.h | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index d1429812be2e..0f7ad6cecf05 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -217,6 +217,13 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
   KERN_DEBUG, prefix_str, prefix_type, \
   rowsize, groupsize, buf, len, ascii)
 
+/* for test only, generally expect drm.debug style macro wrappers */
+#define __pr_debug_cls(cls, fmt, ...) do { \
+   BUILD_BUG_ON_MSG(!__builtin_constant_p(cls),\
+"expecting constant class int/enum");  \
+   dynamic_pr_debug_cls(cls, fmt, ##__VA_ARGS__);  \
+   } while (0)
+
 #else /* !CONFIG_DYNAMIC_DEBUG_CORE */
 
 #include 
-- 
2.36.1



[PATCH v4 07/41] dyndbg: let query-modname override actual module name

2022-07-20 Thread Jim Cromie
dyndbg's control-parser: ddebug_parse_query(), requires that search
terms: module, func, file, lineno, are used only once in a query; a
thing cannot be named both foo and bar.

The cited commit added an overriding module modname, taken from the
module loader, which is authoritative.  So it set query.module 1st,
which disallowed its use in the query-string.

But now, its useful to allow a module-load to enable classes across a
whole (or part of) a subsystem at once.

  # enable (dynamic-debug in) drm only
  modprobe drm dyndbg="class DRM_UT_CORE +p"

  # get drm_helper too
  modprobe drm dyndbg="class DRM_UT_CORE module drm* +p"

  # get everything that knows DRM_UT_CORE
  modprobe drm dyndbg="class DRM_UT_CORE module * +p"

  # also for boot-args:
  drm.dyndbg="class DRM_UT_CORE module * +p"

So convert the override into a default, by filling it only when/after
the query-string omitted the module.

NB: the query class FOO handling is forthcoming.

Fixes: 8e59b5cfb9a6 dynamic_debug: add modname arg to exec_query callchain
Signed-off-by: Jim Cromie 
---
 lib/dynamic_debug.c | 11 +++
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index e5cbe603000c..5a849716220a 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -385,10 +385,6 @@ static int ddebug_parse_query(char *words[], int nwords,
return -EINVAL;
}
 
-   if (modname)
-   /* support $modname.dyndbg= */
-   query->module = modname;
-
for (i = 0; i < nwords; i += 2) {
char *keyword = words[i];
char *arg = words[i+1];
@@ -429,6 +425,13 @@ static int ddebug_parse_query(char *words[], int nwords,
if (rc)
return rc;
}
+   if (!query->module && modname)
+   /*
+* support $modname.dyndbg=, when
+* not given in the query itself
+*/
+   query->module = modname;
+
vpr_info_dq(query, "parsed");
return 0;
 }
-- 
2.36.1



[PATCH v4 14/41] dyndbg: add ddebug_attach_module_classes

2022-07-20 Thread Jim Cromie
Add ddebug_attach_module_classes(), call it from ddebug_add_module().
It scans the classes/section its given, finds records where the
module-name matches the module being added, and adds them to the
module's maps list.  No locking here, since the record
isn't yet linked into the ddebug_tables list.

It is called indirectly from 2 sources:

 - from load_module(), where it scans the module's __dyndbg_classes
   section, which contains DYNAMIC_DEBUG_CLASSES definitions from just
   the module.

 - from dynamic_debug_init(), where all DYNAMIC_DEBUG_CLASSES
   definitions of each builtin module have been packed together.
   This is why ddebug_attach_module_classes() checks module-name.

RFC:

Its (highly) likely that builtin classes will be ordered by module
name (just like prdbg descriptors are in the __dyndbg section).  So
the list can be replaced by a vector (ptr + length), which will work
for loaded modules too.  This would imitate whats currently done for
the _ddebug descriptors.

That said, converting to vector,len is close to pointless; a small
minority of modules will ever define a class-map, and almost all of
them will have only 1 or 2 class-maps, so theres only a couple dozen
pointers to save.

Signed-off-by: Jim Cromie 
---
 lib/dynamic_debug.c | 34 +-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index b6d80ba25bf5..e29730686cfb 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -45,7 +45,7 @@ extern struct ddebug_class_map __start___dyndbg_classes[];
 extern struct ddebug_class_map __stop___dyndbg_classes[];
 
 struct ddebug_table {
-   struct list_head link;
+   struct list_head link, maps;
const char *mod_name;
unsigned int num_ddebugs;
struct _ddebug *ddebugs;
@@ -921,6 +921,32 @@ static const struct proc_ops proc_fops = {
.proc_write = ddebug_proc_write
 };
 
+static void ddebug_attach_module_classes(struct ddebug_table *dt,
+struct ddebug_class_map *classes,
+int num_classes)
+{
+   struct ddebug_class_map *cm;
+   int i, j, ct = 0;
+
+   for (cm = classes, i = 0; i < num_classes; i++, cm++) {
+
+   if (!strcmp(cm->mod_name, dt->mod_name)) {
+
+   v2pr_info("class[%d]: module:%s base:%d len:%d 
ty:%d\n", i,
+ cm->mod_name, cm->base, cm->length, 
cm->map_type);
+
+   for (j = 0; j < cm->length; j++)
+   v3pr_info(" %d: %d %s\n", j + cm->base, j,
+ cm->class_names[j]);
+
+   list_add(>link, >maps);
+   ct++;
+   }
+   }
+   if (ct)
+   vpr_info("module:%s attached %d classes\n", dt->mod_name, ct);
+}
+
 /*
  * Allocate a new ddebug_table for the given module
  * and add it to the global list.
@@ -946,6 +972,12 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int 
num_debugs,
dt->num_ddebugs = num_debugs;
dt->ddebugs = tab;
 
+   INIT_LIST_HEAD(>link);
+   INIT_LIST_HEAD(>maps);
+
+   if (classes && num_classes)
+   ddebug_attach_module_classes(dt, classes, num_classes);
+
mutex_lock(_lock);
list_add_tail(>link, _tables);
mutex_unlock(_lock);
-- 
2.36.1



[PATCH v4 10/41] dyndbg: add class_id to pr_debug callsites

2022-07-20 Thread Jim Cromie
DRM issues ~10 exclusive categories of debug messages; to represent
this directly in dyndbg, add a new field: struct _ddebug.class_id:5.

This gives us 32 classes, which is a practical usability limit
with a bitmap interface:

  #> echo 0x012345678 > /sys/module/drm/parameters/debug

All existing callsites are initialized with _DPRINTK_CLASS_DFLT, which
is 2^5-1.  This reserves 0-30 for use in new categorized/class'd
pr_debugs, which fits perfectly with natural enums (ints: 0..N).

Then extend the init macro: DEFINE_DYNAMIC_DEBUG_METADATA() with
_CLS(cls, ...), and redef old name using extended name.

And extend the factory macro callchain with _cls() versions to provide
the callsite.class_id, with old-names passing _DPRINTK_CLASS_DFLT.

This sets us up to create class'd prdebug callsites (class'd callsites
are those with .class_id != _DPRINTK_CLASS_DFLT).

No behavior change.

Signed-off-by: Jim Cromie 
---
 include/linux/dynamic_debug.h | 71 +++
 1 file changed, 55 insertions(+), 16 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 8d9eec5f6d8b..d1429812be2e 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -6,6 +6,8 @@
 #include 
 #endif
 
+#include 
+
 /*
  * An instance of this structure is created in a special
  * ELF section at every dynamic debug callsite.  At runtime,
@@ -21,6 +23,9 @@ struct _ddebug {
const char *filename;
const char *format;
unsigned int lineno:18;
+#define CLS_BITS 5
+   unsigned int class_id:CLS_BITS;
+#define _DPRINTK_CLASS_DFLT((1 << CLS_BITS) - 1)
/*
 * The flags field controls the behaviour at the callsite.
 * The bits here are changed dynamically when the user
@@ -84,7 +89,7 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
 const struct ib_device *ibdev,
 const char *fmt, ...);
 
-#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt)   \
+#define DEFINE_DYNAMIC_DEBUG_METADATA_CLS(name, cls, fmt)  \
static struct _ddebug  __aligned(8) \
__section("__dyndbg") name = {  \
.modname = KBUILD_MODNAME,  \
@@ -93,8 +98,14 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
.format = (fmt),\
.lineno = __LINE__, \
.flags = _DPRINTK_FLAGS_DEFAULT,\
+   .class_id = cls,\
_DPRINTK_KEY_INIT   \
-   }
+   };  \
+   BUILD_BUG_ON_MSG(cls > _DPRINTK_CLASS_DFLT, \
+"classid value overflow")
+
+#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt)   \
+   DEFINE_DYNAMIC_DEBUG_METADATA_CLS(name, _DPRINTK_CLASS_DFLT, fmt)
 
 #ifdef CONFIG_JUMP_LABEL
 
@@ -125,17 +136,34 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
 
 #endif /* CONFIG_JUMP_LABEL */
 
-#define __dynamic_func_call(id, fmt, func, ...) do {   \
-   DEFINE_DYNAMIC_DEBUG_METADATA(id, fmt); \
-   if (DYNAMIC_DEBUG_BRANCH(id))   \
-   func(, ##__VA_ARGS__);   \
-} while (0)
-
-#define __dynamic_func_call_no_desc(id, fmt, func, ...) do {   \
-   DEFINE_DYNAMIC_DEBUG_METADATA(id, fmt); \
+/*
+ * Factory macros: ($prefix)dynamic_func_call($suffix)
+ *
+ * Lower layer (with __ prefix) gets the callsite metadata, and wraps
+ * the func inside a debug-branch/static-key construct.  Upper layer
+ * (with _ prefix) does the UNIQUE_ID once, so that lower can ref the
+ * name/label multiple times, and tie the elements together.
+ * Multiple flavors:
+ * (|_cls):adds in _DPRINT_CLASS_DFLT as needed
+ * (|_no_desc):former gets callsite descriptor as 1st arg (for prdbgs)
+ */
+#define __dynamic_func_call_cls(id, cls, fmt, func, ...) do {  \
+   DEFINE_DYNAMIC_DEBUG_METADATA_CLS(id, cls, fmt);\
if (DYNAMIC_DEBUG_BRANCH(id))   \
-   func(__VA_ARGS__);  \
+   func(, ##__VA_ARGS__);   \
 } while (0)
+#define __dynamic_func_call(id, fmt, func, ...)
\
+   __dynamic_func_call_cls(id, _DPRINTK_CLASS_DFLT, fmt,   \
+   func, ##__VA_ARGS__)
+
+#define __dynamic_func_call_cls_no_desc(id, cls, fmt, func, ...) do {  \
+   DEFINE_DYNAMIC_DEBUG_METADATA_CLS(id, cls, fmt);\
+   if (DYNAMIC_DEBUG_BRANCH(id))   \
+   func(__VA_ARGS__);  \
+} while (0)
+#define __dynamic_func_call_no_desc(id, fmt, func, ...)
\

[PATCH v4 23/41] drm_print: wrap drm_*_dbg in dyndbg descriptor factory macro

2022-07-20 Thread Jim Cromie
For CONFIG_DRM_USE_DYNAMIC_DEBUG=y, wrap __drm_dbg() & __drm_dev_dbg()
in one of dyndbg's Factory macros: _dynamic_func_call_no_desc().

This adds the callsite descriptor into the code, and an entry for each
into /proc/dynamic_debug/control.

  #> echo class DRM_UT_ATOMIC +p > /proc/dynamic_debug/control

CONFIG_DRM_USE_DYNAMIC_DEBUG=y/n is configurable because of the .data
footprint cost of per-callsite control; 56 bytes/site * ~2k for i915,
~4k callsites for amdgpu.  This is large enough that a kernel builder
might not want it.

Signed-off-by: Jim Cromie 
---
 drivers/gpu/drm/Kconfig  | 12 
 drivers/gpu/drm/Makefile |  2 ++
 include/drm/drm_print.h  | 12 
 3 files changed, 26 insertions(+)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index e88c497fa010..bb1fa20a8eb2 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -50,6 +50,18 @@ config DRM_DEBUG_MM
 
  If in doubt, say "N".
 
+config DRM_USE_DYNAMIC_DEBUG
+   bool "use dynamic debug to implement drm.debug"
+   default y
+   depends on DRM
+   depends on DYNAMIC_DEBUG || DYNAMIC_DEBUG_CORE
+   depends on JUMP_LABEL
+   help
+ Use dynamic-debug to avoid drm_debug_enabled() runtime overheads.
+ Due to callsite counts in DRM drivers (~4k in amdgpu) and 56
+ bytes per callsite, the .data costs can be substantial, and
+ are therefore configurable.
+
 config DRM_DEBUG_SELFTEST
tristate "kselftests for DRM"
depends on DRM
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 15fe3163f822..272de137d207 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -3,6 +3,8 @@
 # Makefile for the drm device driver.  This driver provides support for the
 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
 
+CFLAGS-$(CONFIG_DRM_USE_DYNAMIC_DEBUG) += -DDYNAMIC_DEBUG_MODULE
+
 drm-y   := drm_aperture.o drm_auth.o drm_cache.o \
drm_file.o drm_gem.o drm_ioctl.o \
drm_drv.o \
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index c429c258c957..2d2cef76b5c1 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -384,8 +384,14 @@ void __drm_dev_dbg(const struct device *dev, enum 
drm_debug_category category,
}   \
 })
 
+#if !defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
 #define drm_dev_dbg(dev, cat, fmt, ...)\
__drm_dev_dbg(dev, cat, fmt, ##__VA_ARGS__)
+#else
+#define drm_dev_dbg(dev, cat, fmt, ...)\
+   _dynamic_func_call_no_desc(fmt, __drm_dev_dbg,  \
+  dev, cat, fmt, ##__VA_ARGS__)
+#endif
 
 /**
  * DRM_DEV_DEBUG() - Debug output for generic drm code
@@ -492,7 +498,13 @@ void ___drm_dbg(enum drm_debug_category category, const 
char *format, ...);
 __printf(1, 2)
 void __drm_err(const char *format, ...);
 
+#if !defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
 #define __drm_dbg(fmt, ...)___drm_dbg(fmt, ##__VA_ARGS__)
+#else
+#define __drm_dbg(cat, fmt, ...)   \
+   _dynamic_func_call_no_desc(fmt, ___drm_dbg, \
+  cat, fmt, ##__VA_ARGS__)
+#endif
 
 /* Macros to make printk easier */
 
-- 
2.36.1



  1   2   >