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

2022-02-14 Thread Christian König

Am 15.02.22 um 00:56 schrieb Vivek Kasireddy:

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


Sounds like a good idea to me, but I somehow only see the cover letter 
and none of the patches.


Please double check your mail setup, looks like you CCed me only on the 
first mail and I don't see the rest on dri-devel for some reason.


Regards,
Christian.



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

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

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





Re: [RFC v2 6/6] android: binder: Add a buffer flag to relinquish ownership of fds

2022-02-14 Thread Greg Kroah-Hartman
On Mon, Feb 14, 2022 at 11:19:35PM -0800, Suren Baghdasaryan wrote:
> On Mon, Feb 14, 2022 at 11:01 PM Greg Kroah-Hartman
>  wrote:
> >
> > On Mon, Feb 14, 2022 at 02:25:47PM -0800, T.J. Mercier wrote:
> > > On Fri, Feb 11, 2022 at 11:19 PM Greg Kroah-Hartman
> > > > > --- a/include/uapi/linux/android/binder.h
> > > > > +++ b/include/uapi/linux/android/binder.h
> > > > > @@ -137,6 +137,7 @@ struct binder_buffer_object {
> > > > >
> > > > >  enum {
> > > > >   BINDER_BUFFER_FLAG_HAS_PARENT = 0x01,
> > > > > + BINDER_BUFFER_FLAG_SENDER_NO_NEED = 0x02,
> > > > >  };
> > > > >
> > > > >  /* struct binder_fd_array_object - object describing an array of fds 
> > > > > in a buffer
> > > > > --
> > > > > 2.35.1.265.g69c8d7142f-goog
> > > > >
> > > >
> > > > How does userspace know that binder supports this new flag?
> > >
> > > Sorry, I don't completely follow even after Todd's comment. Doesn't
> > > the presence of BINDER_BUFFER_FLAG_SENDER_NO_NEED in the header do
> > > this?
> >
> > There is no "header" when running a new kernel on an old userspace,
> > right?  How about the other way around, old kernel, new userspace?
> 
> 1. new kernel + old userspace = kernel supports the feature but
> userspace does not use it. The old userspace won't even mount the new
> cgroup controller, accounting is not performed, charge is not
> transferred.
> 2. old kernel + new userspace = the new cgroup controller is not
> supported by the kernel, accounting is not performed, charge is not
> transferred.
> 3. old kernel + old userspace = same as #2
> 4. new kernel + new userspace = cgroup is mounted, feature is
> supported and used.
> Does that work or do we need a separate indication of whether binder
> driver supports the charge transfer feature?

Ok, if that's all working, this is fine, it just seemed odd to add a new
type like this.  Perhaps this can go into the changelog text...

thanks,

greg k-h


Re: [PATCH v4 00/10] Overhaul `is_thunderbolt`

2022-02-14 Thread Lukas Wunner
On Mon, Feb 14, 2022 at 06:01:50PM -0600, Mario Limonciello wrote:
>  drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c |  2 +-
>  drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c  |  2 +-
>  drivers/gpu/drm/nouveau/nouveau_vga.c   |  4 +-
>  drivers/gpu/drm/radeon/radeon_device.c  |  4 +-
>  drivers/gpu/drm/radeon/radeon_kms.c |  2 +-
>  drivers/pci/hotplug/pciehp_hpc.c|  6 +-
>  drivers/pci/pci-acpi.c  | 15 -
>  drivers/pci/pci.c   | 17 +++--
>  drivers/pci/probe.c | 52 ++-
>  drivers/pci/quirks.c| 84 +
>  drivers/platform/x86/apple-gmux.c   |  2 +-
>  drivers/thunderbolt/nhi.h   |  2 -
>  include/linux/pci.h | 25 +---
>  include/linux/pci_ids.h |  3 +
>  14 files changed, 173 insertions(+), 47 deletions(-)

That's an awful lot of additional LoC for what is primarily
a refactoring job with the intent to simplify things.

Honestly this looks like an attempt to fix something that
isn't broken.  Specifically, the is_thunderbolt bit apparently
can't be removed without adding new bits to struct pci_dev.
Not sure if that can be called progress.

Thanks,

Lukas


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

2022-02-14 Thread Gabriel Krisman Bertazi
Hsin-Yi Wang  writes:

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

Yes.  But *after the property is successfully created*, the prop variable is 
still
NULL.  And then you call the following, using prop, which is still NULL:

>> > + drm_object_property_set_value(>base, prop,
>> > +   info->panel_orientation);

This will do property->dev right on the first line of code, and dereference the
null prop pointer.

You must do

  prop = dev->mode_config.panel_orientation_property;

again after drm_connector_init_panel_orientation_property successfully
returns, or call drm_object_property_set_value using
dev->mode_config.panel_orientation_property directly:

  drm_object_property_set_value(>base,
dev->mode_config.panel_orientation_property
info->panel_orientation);

-- 
Gabriel Krisman Bertazi


Re: [PATCH 09/27] mm: generalize the pgmap based page_free infrastructure

2022-02-14 Thread Logan Gunthorpe



On 2022-02-10 12:28 a.m., Christoph Hellwig wrote:
> Key off on the existence of ->page_free to prepare for adding support for
> more pgmap types that are device managed and thus need the free callback.
> 
> Signed-off-by: Christoph Hellwig 

Great! This makes my patch simpler.

Reviewed-by: Logan Gunthorpe 


> ---
>  mm/memremap.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/mm/memremap.c b/mm/memremap.c
> index fef5734d5e4933..e00ffcdba7b632 100644
> --- a/mm/memremap.c
> +++ b/mm/memremap.c
> @@ -452,7 +452,7 @@ EXPORT_SYMBOL_GPL(get_dev_pagemap);
>  
>  void free_zone_device_page(struct page *page)
>  {
> - if (WARN_ON_ONCE(!is_device_private_page(page)))
> + if (WARN_ON_ONCE(!page->pgmap->ops || !page->pgmap->ops->page_free))
>   return;
>  
>   __ClearPageWaiters(page);
> @@ -460,7 +460,7 @@ void free_zone_device_page(struct page *page)
>   mem_cgroup_uncharge(page_folio(page));
>  
>   /*
> -  * When a device_private page is freed, the page->mapping field
> +  * When a device managed page is freed, the page->mapping field
>* may still contain a (stale) mapping value. For example, the
>* lower bits of page->mapping may still identify the page as an
>* anonymous page. Ultimately, this entire field is just stale
> 


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

2022-02-14 Thread Gabriel Krisman Bertazi
Hsin-Yi Wang  writes:

> drm_dev_register() sets connector->registration_state to
> DRM_CONNECTOR_REGISTERED and dev->registered to true. If
> drm_connector_set_panel_orientation() is first called after
> drm_dev_register(), it will fail several checks and results in following
> warning.

Hi,

I stumbled upon this when investigating the same WARN_ON on amdgpu.
Thanks for the patch :)

> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index a50c82bc2b2fec..572ead7ac10690 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -1252,7 +1252,7 @@ static const struct drm_prop_enum_list dp_colorspaces[] 
> = {
>   *   INPUT_PROP_DIRECT) will still map 1:1 to the actual LCD panel
>   *   coordinates, so if userspace rotates the picture to adjust for
>   *   the orientation it must also apply the same transformation to the
> - *   touchscreen input coordinates. This property is initialized by calling
> + *   touchscreen input coordinates. This property value is set by calling
>   *   drm_connector_set_panel_orientation() or
>   *   drm_connector_set_panel_orientation_with_quirk()
>   *
> @@ -2341,8 +2341,8 @@ EXPORT_SYMBOL(drm_connector_set_vrr_capable_property);
>   * @connector: connector for which to set the panel-orientation property.
>   * @panel_orientation: drm_panel_orientation value to set
>   *
> - * This function sets the connector's panel_orientation and attaches
> - * a "panel orientation" property to the connector.
> + * This function sets the connector's panel_orientation value. If the 
> property
> + * doesn't exist, it will try to create one.
>   *
>   * Calling this function on a connector where the panel_orientation has
>   * already been set is a no-op (e.g. the orientation has been overridden with
> @@ -2373,19 +2373,12 @@ int drm_connector_set_panel_orientation(
>   info->panel_orientation = panel_orientation;
>  
>   prop = dev->mode_config.panel_orientation_property;
> - if (!prop) {
> - prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
> - "panel orientation",
> - drm_panel_orientation_enum_list,
> - ARRAY_SIZE(drm_panel_orientation_enum_list));
> - if (!prop)
> - return -ENOMEM;
> -
> - dev->mode_config.panel_orientation_property = prop;
> - }
> + if (!prop &&
> + drm_connector_init_panel_orientation_property(connector) < 0)
> + return -ENOMEM;
>

In the case where the property has not been created beforehand, you
forgot to reinitialize prop here, after calling
drm_connector_init_panel_orientation_property().  This means
drm_object_property_set_value() will be called with a NULL second argument
and Oops the kernel.


> - drm_object_attach_property(>base, prop,
> -info->panel_orientation);
> + drm_object_property_set_value(>base, prop,
> +   info->panel_orientation);


-- 
Gabriel Krisman Bertazi


Re: [RFC PATCH 1/6] dt-bindings: display: imx: Add EPDC

2022-02-14 Thread Andreas Kemnade
Hi Rob,

On Fri, 11 Feb 2022 09:46:27 -0600
Rob Herring  wrote:

> On Sun, Feb 06, 2022 at 09:00:11AM +0100, Andreas Kemnade wrote:
> > Add a binding for the Electrophoretic Display Controller found at least
> > in the i.MX6.  
> 
> The first version was in i.MX50 (I helped design the register 
> interface). Is that version compatible?
> 
it has some differences, but that could be detected by EPDC_VERSION
register. I do not own such a device, so I cannot fully check. I have
not seen any driver with devicetree for IMX5. For now I am rejecting
anything which has a EPDC version which I cannot check. 

> > The timing subnode is directly here to avoid having display parameters
> > spread all over the plate.
> > 
> > Supplies are organized the same way as in the fbdev driver in the
> > NXP/Freescale kernel forks. The regulators used for that purpose,
> > like the TPS65185, the SY7636A and MAX17135 have typically a single bit to
> > start a bunch of regulators of higher or negative voltage with a
> > well-defined timing. VCOM can be handled separately, but can also be
> > incorporated into that single bit.
> > 
> > Signed-off-by: Andreas Kemnade 
> > ---
> >  .../bindings/display/imx/fsl,mxc-epdc.yaml| 159 ++
> >  1 file changed, 159 insertions(+)
> >  create mode 100644 
> > Documentation/devicetree/bindings/display/imx/fsl,mxc-epdc.yaml
> > 
> > diff --git 
> > a/Documentation/devicetree/bindings/display/imx/fsl,mxc-epdc.yaml 
> > b/Documentation/devicetree/bindings/display/imx/fsl,mxc-epdc.yaml
> > new file mode 100644
> > index ..7e0795cc3f70
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/display/imx/fsl,mxc-epdc.yaml
> > @@ -0,0 +1,159 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/display/imx/fsl,mxc-epdc.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Freescale i.MX6 EPDC
> > +
> > +maintainers:
> > +  - Andreas Kemnade 
> > +
> > +description: |
> > +  The EPDC is a controller for handling electronic paper displays found in
> > +  i.MX6 SoCs.
> > +
> > +properties:
> > +  compatible:
> > +enum:
> > +  - fsl,imx6sl-epdc
> > +  - fsl,imx6sll-epdc  
> 
> Not compatible with each other?
> 
differences are detectable by EPDC_VERSION register, so probably so
problem. NXP/Freescale kernel uses
fsl,imx6dl-epdc
and 
fsl,imx7d-epdc (used also by imx6 devices with EPDC_VERSION = 3.0)
in their drivers.

fsl,imx6dl-epdc
fsl,imx6sl-epdc
fsl,imx6sll-epdc
fsl,imx7d-epdc
in their dtsis.

But the general rule is to use as less as possible compatible strings
if differences can be probed properly, so only one should be
sufficient? Which one?

Regards,
Andreas


Re: [RFC v2 6/6] android: binder: Add a buffer flag to relinquish ownership of fds

2022-02-14 Thread Greg Kroah-Hartman
On Mon, Feb 14, 2022 at 02:25:47PM -0800, T.J. Mercier wrote:
> On Fri, Feb 11, 2022 at 11:19 PM Greg Kroah-Hartman
> > > --- a/include/uapi/linux/android/binder.h
> > > +++ b/include/uapi/linux/android/binder.h
> > > @@ -137,6 +137,7 @@ struct binder_buffer_object {
> > >
> > >  enum {
> > >   BINDER_BUFFER_FLAG_HAS_PARENT = 0x01,
> > > + BINDER_BUFFER_FLAG_SENDER_NO_NEED = 0x02,
> > >  };
> > >
> > >  /* struct binder_fd_array_object - object describing an array of fds in 
> > > a buffer
> > > --
> > > 2.35.1.265.g69c8d7142f-goog
> > >
> >
> > How does userspace know that binder supports this new flag?
> 
> Sorry, I don't completely follow even after Todd's comment. Doesn't
> the presence of BINDER_BUFFER_FLAG_SENDER_NO_NEED in the header do
> this?

There is no "header" when running a new kernel on an old userspace,
right?  How about the other way around, old kernel, new userspace?

> So wouldn't userspace need to be compiled against the wrong
> kernel headers for there to be a problem? In that case the allocation
> would still succeed, but there would be no charge transfer and
> unfortunately no error code.

No error code is not good.  People upgrade their kernels all the time,
and do not do a "rebuild the world" when doing so.

> > And where is the userspace test for this new feature?
> 
> I tested this on a Pixel after modifying the gralloc implementation to
> mark allocated buffers as not used by the sender. This required
> setting the BINDER_BUFFER_FLAG_SENDER_NO_NEED in libhwbinder. That
> code can be found here:
> https://android-review.googlesource.com/c/platform/system/libhwbinder/+/1910752/1/Parcel.cpp
> https://android-review.googlesource.com/c/platform/system/libhidl/+/1910611/
> 
> Then by inspecting gpu.memory.current files in sysfs I was able to see
> the memory attributed to processes other than the graphics allocator
> service. Before this change, several megabytes of memory were
> attributed to the graphics allocator service but those buffers are
> actually used by other processes like surfaceflinger, the camera, etc.
> After the change, the gpu.memory.current amount for the graphics
> allocator service was 0 and the charges showed up in the
> gpu.memory.current files for those other processes like this:
> 
> PID: 764 Process Name: zygote64
> system 8192
> system-uncached 23191552
> 
> PID: 529 Process Name: /system/bin/surfaceflinger
> system-uncached 109535232
> system 92196864
> 
> PID: 530 Process Name:
> /vendor/bin/hw/android.hardware.graphics.allocator@4.0-service
> system-uncached 0
> system 0
> sensor_direct_heap 0
> 
> PID: 806 Process Name:
> /apex/com.google.pixel.camera.hal/bin/hw/android.hardware.camera.provider@2.7-service-google
> system 1196032
> 
> PID: 4608 Process Name: com.google.android.GoogleCamera
> system 2408448
> system-uncached 38887424
> sensor_direct_heap 0
> 
> PID: 32102 Process Name: com.google.android.googlequicksearchbox:search
> system-uncached 91279360
> system 20480
> 
> PID: 2758 Process Name: com.google.android.youtube
> system-uncached 1662976
> system 8192
> 
> PID: 2517 Process Name: com.google.android.apps.nexuslauncher
> system-uncached 115662848
> system 122880
> 
> PID: 2066 Process Name: com.android.systemui
> system 86016
> system-uncached 37957632
> 
> >  Isn't there a binder test framework somewhere?
> 
> Android has the Vendor Test Suite where automated tests could be added
> for this. Is that what you're thinking of?

tools/testing/selftests/ is a good start.  VTS is the worst-case as no
one can really run that on their own, but it is better than nothing.
Having no test at all for this is not ok.

thanks,

greg k-h


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

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

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

Fix this by handling PHY_E port seprately.

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

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



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

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

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

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

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

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

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

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

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

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

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



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

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

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

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

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

-- 
2.20.1



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

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

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

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



[PATCH] drm/msm/dpu: Disable boot loader configured data paths

2022-02-14 Thread Bjorn Andersson
It's typical for the bootloader to configure CTL_0 for the boot splash
or EFIFB, but for non-DSI use cases the DPU driver tend to pick another
CTL and the system might end up with two configured data paths producing
data on the same INTF. In particular as the IOMMU configuration isn't
retained from the bootloader one of the data paths will push underflow
color, resulting in screen flickering.

Naturally the end goal would be to inherit the bootloader's
configuration and provide the user with a glitch-free handover from the
boot configuration to a running DPU.

But such effort will affect clocks, regulators, power-domains etc, and
will take time to implement. So in the meantime this patch simply
disables all the data paths, on platforms that has CTL_FETCH_ACTIVE, to
avoid the graphical artifacts.

Signed-off-by: Bjorn Andersson 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 13 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h |  6 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c|  2 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 17 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h |  8 
 5 files changed, 46 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
index 02da9ecf71f1..69d4849484fa 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
@@ -357,6 +357,18 @@ static void dpu_hw_ctl_clear_all_blendstages(struct 
dpu_hw_ctl *ctx)
DPU_REG_WRITE(c, CTL_FETCH_PIPE_ACTIVE, 0);
 }
 
+static void dpu_hw_ctl_disable_boot_config(struct dpu_hw_ctl *ctx)
+{
+   if (ctx->caps->features & BIT(DPU_CTL_FETCH_ACTIVE)) {
+   /*
+* Disable the pipe fetch and trigger a start, to disable the
+* data path
+*/
+   DPU_REG_WRITE(>hw, CTL_FETCH_PIPE_ACTIVE, 0);
+   DPU_REG_WRITE(>hw, CTL_START, 0x1);
+   }
+}
+
 static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl *ctx,
enum dpu_lm lm, struct dpu_hw_stage_cfg *stage_cfg)
 {
@@ -590,6 +602,7 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops,
ops->trigger_pending = dpu_hw_ctl_trigger_pending;
ops->reset = dpu_hw_ctl_reset_control;
ops->wait_reset_status = dpu_hw_ctl_wait_reset_status;
+   ops->disable_boot_config = dpu_hw_ctl_disable_boot_config;
ops->clear_all_blendstages = dpu_hw_ctl_clear_all_blendstages;
ops->setup_blendstage = dpu_hw_ctl_setup_blendstage;
ops->get_bitmask_sspp = dpu_hw_ctl_get_bitmask_sspp;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
index 806c171e5df2..c2734f6ab760 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
@@ -159,6 +159,12 @@ struct dpu_hw_ctl_ops {
 */
void (*clear_all_blendstages)(struct dpu_hw_ctl *ctx);
 
+   /**
+* Disable the configuration setup by the bootloader
+* @ctx   : ctl path ctx pointer
+*/
+   void (*disable_boot_config)(struct dpu_hw_ctl *ctx);
+
/**
 * Configure layer mixer to pipe configuration
 * @ctx   : ctl path ctx pointer
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index cedc631f8498..eef2f017031a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -1107,6 +1107,8 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
 
dpu_kms->rm_init = true;
 
+   dpu_rm_clear_boot_config(_kms->rm, dpu_kms->catalog);
+
dpu_kms->hw_mdp = dpu_hw_mdptop_init(MDP_TOP, dpu_kms->mmio,
 dpu_kms->catalog);
if (IS_ERR(dpu_kms->hw_mdp)) {
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index f9c83d6e427a..3365c5e41e28 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -4,6 +4,7 @@
  */
 
 #define pr_fmt(fmt)"[drm:%s] " fmt, __func__
+#include 
 #include "dpu_kms.h"
 #include "dpu_hw_lm.h"
 #include "dpu_hw_ctl.h"
@@ -229,6 +230,22 @@ int dpu_rm_init(struct dpu_rm *rm,
return rc ? rc : -EFAULT;
 }
 
+void dpu_rm_clear_boot_config(struct dpu_rm *rm, struct dpu_mdss_cfg *cat)
+{
+   struct dpu_hw_ctl *ctl;
+   int i;
+
+   for (i = CTL_0; i < CTL_MAX; i++) {
+   if (!rm->ctl_blks[i - CTL_0])
+   continue;
+
+   DPU_DEBUG("disabling ctl%d boot configuration\n", i - CTL_0);
+
+   ctl = to_dpu_hw_ctl(rm->ctl_blks[i - CTL_0]);
+   ctl->ops.disable_boot_config(ctl);
+   }
+}
+
 static bool _dpu_rm_needs_split_display(const struct msm_display_topology *top)
 {
return top->num_intf > 1;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
index 

[PATCH v2 2/2] drm/msm/dpu: Add SC8180x to hw catalog

2022-02-14 Thread Bjorn Andersson
From: Rob Clark 

Add SC8180x to the hardware catalog, for initial support for the
platform. Due to limitations in the DP driver only one of the four DP
interfaces is left enabled.

The SC8180x platform supports the newly added DPU_INTF_WIDEBUS flag and
the Windows-on-Snapdragon bootloader leaves the widebus bit set, so this
is flagged appropriately to ensure widebus is disabled - for now.

Signed-off-by: Rob Clark 
[bjorn: Reworked intf and irq definitions]
Signed-off-by: Bjorn Andersson 
---

Changes since v1:
- Dropped widebus flag

 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 129 ++
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h|   1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   |   1 +
 drivers/gpu/drm/msm/msm_drv.c |   1 +
 4 files changed, 132 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index aa75991903a6..7ac0fe32df49 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -90,6 +90,17 @@
 BIT(MDP_INTF3_INTR) | \
 BIT(MDP_INTF4_INTR))
 
+#define IRQ_SC8180X_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
+ BIT(MDP_SSPP_TOP0_INTR2) | \
+ BIT(MDP_SSPP_TOP0_HIST_INTR) | \
+ BIT(MDP_INTF0_INTR) | \
+ BIT(MDP_INTF1_INTR) | \
+ BIT(MDP_INTF2_INTR) | \
+ BIT(MDP_INTF3_INTR) | \
+ BIT(MDP_INTF4_INTR) | \
+ BIT(MDP_INTF5_INTR) | \
+ BIT(MDP_AD4_0_INTR) | \
+ BIT(MDP_AD4_1_INTR))
 
 #define DEFAULT_PIXEL_RAM_SIZE (50 * 1024)
 #define DEFAULT_DPU_LINE_WIDTH 2048
@@ -225,6 +236,22 @@ static const struct dpu_caps sm8150_dpu_caps = {
.max_vdeci_exp = MAX_VERT_DECIMATION,
 };
 
+static const struct dpu_caps sc8180x_dpu_caps = {
+   .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+   .max_mixer_blendstages = 0xb,
+   .qseed_type = DPU_SSPP_SCALER_QSEED3,
+   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
+   .ubwc_version = DPU_HW_UBWC_VER_30,
+   .has_src_split = true,
+   .has_dim_layer = true,
+   .has_idle_pc = true,
+   .has_3d_merge = true,
+   .max_linewidth = 4096,
+   .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+   .max_hdeci_exp = MAX_HORZ_DECIMATION,
+   .max_vdeci_exp = MAX_VERT_DECIMATION,
+};
+
 static const struct dpu_caps sm8250_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
@@ -293,6 +320,31 @@ static const struct dpu_mdp_cfg sc7180_mdp[] = {
},
 };
 
+static const struct dpu_mdp_cfg sc8180x_mdp[] = {
+   {
+   .name = "top_0", .id = MDP_TOP,
+   .base = 0x0, .len = 0x45C,
+   .features = 0,
+   .highest_bank_bit = 0x3,
+   .clk_ctrls[DPU_CLK_CTRL_VIG0] = {
+   .reg_off = 0x2AC, .bit_off = 0},
+   .clk_ctrls[DPU_CLK_CTRL_VIG1] = {
+   .reg_off = 0x2B4, .bit_off = 0},
+   .clk_ctrls[DPU_CLK_CTRL_VIG2] = {
+   .reg_off = 0x2BC, .bit_off = 0},
+   .clk_ctrls[DPU_CLK_CTRL_VIG3] = {
+   .reg_off = 0x2C4, .bit_off = 0},
+   .clk_ctrls[DPU_CLK_CTRL_DMA0] = {
+   .reg_off = 0x2AC, .bit_off = 8},
+   .clk_ctrls[DPU_CLK_CTRL_DMA1] = {
+   .reg_off = 0x2B4, .bit_off = 8},
+   .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
+   .reg_off = 0x2BC, .bit_off = 8},
+   .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
+   .reg_off = 0x2C4, .bit_off = 8},
+   },
+};
+
 static const struct dpu_mdp_cfg sm8250_mdp[] = {
{
.name = "top_0", .id = MDP_TOP,
@@ -861,6 +913,16 @@ static const struct dpu_intf_cfg sc7280_intf[] = {
INTF_BLK("intf_5", INTF_5, 0x39000, INTF_DP, MSM_DP_CONTROLLER_1, 24, 
INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 22, 23),
 };
 
+static const struct dpu_intf_cfg sc8180x_intf[] = {
+   INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, MSM_DP_CONTROLLER_0, 24, 
INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
+   INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC7180_MASK, 
MDP_SSPP_TOP0_INTR, 26, 27),
+   INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 24, INTF_SC7180_MASK, 
MDP_SSPP_TOP0_INTR, 28, 29),
+   /* INTF_3 is for MST, wired to INTF_DP 0 and 1, use dummy index until 
this is supported */
+   INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 999, 24, INTF_SC7180_MASK, 
MDP_SSPP_TOP0_INTR, 30, 31),
+   INTF_BLK("intf_4", INTF_4, 0x6C000, INTF_DP, MSM_DP_CONTROLLER_1, 24, 
INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 20, 21),
+   INTF_BLK("intf_5", INTF_5, 0x6C800, INTF_DP, MSM_DP_CONTROLLER_2, 24, 
INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 22, 23),
+};
+
 

[PATCH v2 1/2] drm/msm/dpu: Add INTF_5 interrupts

2022-02-14 Thread Bjorn Andersson
SC8180x has the eDP controller wired up to INTF_5, so add the interrupt
register block for this interface to the list.

Signed-off-by: Bjorn Andersson 
---

Changes since v1:
- None

 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 6 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h | 1 +
 2 files changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
index a77a5eaa78ad..dd2161e7bdb6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
@@ -23,6 +23,7 @@
 #define MDP_INTF_2_OFF 0x6B000
 #define MDP_INTF_3_OFF 0x6B800
 #define MDP_INTF_4_OFF 0x6C000
+#define MDP_INTF_5_OFF 0x6C800
 #define MDP_AD4_0_OFF  0x7C000
 #define MDP_AD4_1_OFF  0x7D000
 #define MDP_AD4_INTR_EN_OFF0x41c
@@ -93,6 +94,11 @@ static const struct dpu_intr_reg dpu_intr_set[] = {
MDP_INTF_4_OFF+INTF_INTR_EN,
MDP_INTF_4_OFF+INTF_INTR_STATUS
},
+   {
+   MDP_INTF_5_OFF+INTF_INTR_CLEAR,
+   MDP_INTF_5_OFF+INTF_INTR_EN,
+   MDP_INTF_5_OFF+INTF_INTR_STATUS
+   },
{
MDP_AD4_0_OFF + MDP_AD4_INTR_CLEAR_OFF,
MDP_AD4_0_OFF + MDP_AD4_INTR_EN_OFF,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
index 1ab75cccd145..37379966d8ec 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
@@ -22,6 +22,7 @@ enum dpu_hw_intr_reg {
MDP_INTF2_INTR,
MDP_INTF3_INTR,
MDP_INTF4_INTR,
+   MDP_INTF5_INTR,
MDP_AD4_0_INTR,
MDP_AD4_1_INTR,
MDP_INTF0_7xxx_INTR,
-- 
2.33.1



Re: [PATCH v4 2/2] drm/msm/dp: enable widebus feature for display port

2022-02-14 Thread Bjorn Andersson
On Mon 14 Feb 16:39 CST 2022, Kuogee Hsieh wrote:

> Widebus feature will transmit two pixel data per pixel clock to interface.
> This feature now is required to be enabled to easy migrant to higher
> resolution applications in future. However since some legacy chipsets
> does not support this feature, this feature is enabled base on chip's
> hardware revision.
> 
> changes in v2:
> -- remove compression related code from timing
> -- remove op_info from  struct msm_drm_private
> -- remove unnecessary wide_bus_en variables
> -- pass wide_bus_en into timing configuration by struct msm_dp
> 
> Changes in v3:
> -- split patch into 3 patches
> -- enable widebus feature base on chip hardware revision
> 
> Signed-off-by: Kuogee Hsieh 

Tested-by: Bjorn Andersson 

> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c |  4 +++-
>  drivers/gpu/drm/msm/dp/dp_catalog.c | 36 
> +++--
>  drivers/gpu/drm/msm/dp/dp_catalog.h |  3 ++-
>  drivers/gpu/drm/msm/dp/dp_ctrl.c| 13 +++
>  drivers/gpu/drm/msm/dp/dp_ctrl.h|  1 +
>  drivers/gpu/drm/msm/dp/dp_display.c | 30 
>  drivers/gpu/drm/msm/dp/dp_display.h |  2 ++
>  drivers/gpu/drm/msm/dp/dp_panel.c   |  4 ++--
>  drivers/gpu/drm/msm/dp/dp_panel.h   |  2 +-
>  drivers/gpu/drm/msm/msm_drv.h   |  6 +
>  10 files changed, 90 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> index 0c22839..b2d23c2 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> @@ -2167,8 +2167,10 @@ int dpu_encoder_setup(struct drm_device *dev, struct 
> drm_encoder *enc,
>   timer_setup(_enc->vsync_event_timer,
>   dpu_encoder_vsync_event_handler,
>   0);
> - else if (disp_info->intf_type == DRM_MODE_ENCODER_TMDS)
> + else if (disp_info->intf_type == DRM_MODE_ENCODER_TMDS) {
>   dpu_enc->dp = priv->dp[disp_info->h_tile_instance[0]];
> + dpu_enc->wide_bus_en = msm_dp_wide_bus_enable(dpu_enc->dp);
> + }
>  
>   INIT_DELAYED_WORK(_enc->delayed_off_work,
>   dpu_encoder_off_work);
> diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c 
> b/drivers/gpu/drm/msm/dp/dp_catalog.c
> index 64f0b26..99d087e 100644
> --- a/drivers/gpu/drm/msm/dp/dp_catalog.c
> +++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
> @@ -483,6 +483,27 @@ int dp_catalog_ctrl_set_pattern_state_bit(struct 
> dp_catalog *dp_catalog,
>  }
>  
>  /**
> + * dp_catalog_hw_revision() - retrieve DP hw revision
> + *
> + * @dp_catalog: DP catalog structure
> + *
> + * return: u32

Q: What's 2+2?
A: Integer

This should say:

Return: the controller hardware revision

> + *
> + * This function return the DP controller hw revision

That's what "Return:" in the kernel-doc is supposed to clarify...

https://docs.kernel.org/doc-guide/kernel-doc.html is good to read.

> + *
> + */
> +u32 dp_catalog_hw_revision(struct dp_catalog *dp_catalog)
> +{
> + u32 revision;
> + struct dp_catalog_private *catalog = container_of(dp_catalog,
> + struct dp_catalog_private, dp_catalog);
> +
> + revision = dp_read_ahb(catalog, REG_DP_HW_VERSION);

There's no need for a local variable here, just:

return dp_read_ahb();

> +
> + return revision;
> +}
> +
> +/**
>   * dp_catalog_ctrl_reset() - reset DP controller
>   *
>   * @dp_catalog: DP catalog structure
> @@ -739,10 +760,11 @@ u32 dp_catalog_ctrl_read_phy_pattern(struct dp_catalog 
> *dp_catalog)
>  }
>  
>  /* panel related catalog functions */
> -int dp_catalog_panel_timing_cfg(struct dp_catalog *dp_catalog)
> +int dp_catalog_panel_timing_cfg(struct dp_catalog *dp_catalog, bool 
> wide_bus_en)
>  {
>   struct dp_catalog_private *catalog = container_of(dp_catalog,
>   struct dp_catalog_private, dp_catalog);
> + u32 reg;
>  
>   dp_write_link(catalog, REG_DP_TOTAL_HOR_VER,
>   dp_catalog->total);
> @@ -751,7 +773,17 @@ int dp_catalog_panel_timing_cfg(struct dp_catalog 
> *dp_catalog)
>   dp_write_link(catalog, REG_DP_HSYNC_VSYNC_WIDTH_POLARITY,
>   dp_catalog->width_blanking);
>   dp_write_link(catalog, REG_DP_ACTIVE_HOR_VER, dp_catalog->dp_active);
> - dp_write_p0(catalog, MMSS_DP_INTF_CONFIG, 0);
> +
> + reg = dp_read_p0(catalog, MMSS_DP_INTF_CONFIG);
> +
> + if (wide_bus_en)
> + reg |= BIT(4);  /* DATABUS_WIDEN */

#define DATABUS_WIDEN BIT(4)

Would save you the need for writing that comment.

> + else
> + reg &= ~BIT(4);
> +
> + DRM_DEBUG_DP("wide_bus_en=%d reg=%x\n", wide_bus_en, reg);
> +
> + dp_write_p0(catalog, MMSS_DP_INTF_CONFIG, reg);
>   return 0;
>  }
>  
> diff --git 

Re: [PATCH v4 1/2] drm/msm/dp: revise timing engine programming to support widebus feature

2022-02-14 Thread Bjorn Andersson
On Mon 14 Feb 16:39 CST 2022, Kuogee Hsieh wrote:

> Widebus feature will transmit two pixel data per pixel clock to interface.
> Timing engine provides driving force for this purpose. This patch base
> on HPG (Hardware Programming Guide) to revise timing engine register
> setting to accommodate both widebus and non widebus application. Also
> horizontal width parameters need to be reduced by half since two pixel
> data are clocked out per pixel clock when widebus feature enabled.
> 
> Widebus can be enabled individually at DP. However at DSI, widebus have
> to be enabled along with DSC enabled to achieve pixel clock rate be
> scaled down with same ratio as compression ratio when 10 bits per source
> component. Therefore this patch have both widebus and compression covered
> together so tat less efforts will be required when DSC enabled later.
> 
> Changes in v2:
> -- remove compression related code from timing
> -- remove op_info from  struct msm_drm_private
> -- remove unnecessary wide_bus_en variables
> -- pass wide_bus_en into timing configuration by struct msm_dp
> 
> Changes in v3:
> -- split patch into 3 patches
> 
> Changes in v4:
> -- rework timing engine to not interfere with dsi/hdmi
> -- cover both widebus and compression
> 

Even though the change relates to DP, I think it would be appropriate to
change the $subject prefix to "drm/msm/dpu".

When booting sc8180x the bootloader leaves widebus enabled in the eDP
controller, and the two patches takes care of this problem for me. I
also checked the DP still works.

Tested-by: Bjorn Andersson 

Thanks,
Bjorn

> Signed-off-by: Kuogee Hsieh 
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c| 10 +++
>  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h|  2 +
>  .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c   | 14 +++
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c| 99 
> ++
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h|  6 ++
>  5 files changed, 115 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> index 0d315b4..0c22839 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> @@ -208,6 +208,8 @@ struct dpu_encoder_virt {
>  
>   u32 idle_timeout;
>  
> + bool wide_bus_en;
> +
>   struct msm_dp *dp;
>  };
>  
> @@ -217,6 +219,14 @@ static u32 dither_matrix[DITHER_MATRIX_SZ] = {
>   15, 7, 13, 5, 3, 11, 1, 9, 12, 4, 14, 6, 0, 8, 2, 10
>  };
>  
> +
> +bool dpu_encoder_is_widebus_enabled(struct drm_encoder *drm_enc)
> +{
> + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
> +
> + return dpu_enc->wide_bus_en;
> +}
> +
>  static void _dpu_encoder_setup_dither(struct dpu_hw_pingpong *hw_pp, 
> unsigned bpc)
>  {
>   struct dpu_hw_dither_cfg dither_cfg = { 0 };
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
> index 99a5d73..893d74d 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
> @@ -168,4 +168,6 @@ int dpu_encoder_get_linecount(struct drm_encoder 
> *drm_enc);
>   */
>  int dpu_encoder_get_frame_count(struct drm_encoder *drm_enc);
>  
> +bool dpu_encoder_is_widebus_enabled(struct drm_encoder *drm_enc);
> +
>  #endif /* __DPU_ENCODER_H__ */
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
> index 185379b..2af2bb7 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
> @@ -110,6 +110,20 @@ static void drm_mode_to_intf_timing_params(
>   timing->v_back_porch += timing->v_front_porch;
>   timing->v_front_porch = 0;
>   }
> +
> + timing->wide_bus_en = dpu_encoder_is_widebus_enabled(phys_enc->parent);
> +
> + /*
> +  * for DP, divide the horizonal parameters by 2 when
> +  * widebus is enabled
> +  */
> + if (phys_enc->hw_intf->cap->type == INTF_DP && timing->wide_bus_en) {
> + timing->width = timing->width >> 1;
> + timing->xres = timing->xres >> 1;
> + timing->h_back_porch = timing->h_back_porch >> 1;
> + timing->h_front_porch = timing->h_front_porch >> 1;
> + timing->hsync_pulse_width = timing->hsync_pulse_width >> 1;
> + }
>  }
>  
>  static u32 get_horizontal_total(const struct intf_timing_params *timing)
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c 
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
> index 116e2b5..3b9273e 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
> @@ -33,6 +33,7 @@
>  #define INTF_TP_COLOR1  0x05C
>  #define INTF_CONFIG20x060
>  #define INTF_DISPLAY_DATA_HCTL  0x064
> +#define 

Re: [PATCH v7 1/7] drm/lsdc: add drm driver for loongson display controller

2022-02-14 Thread Sui Jingfeng



On 2022/2/14 18:10, Maxime Ripard wrote:

On Sun, Feb 13, 2022 at 10:16:43PM +0800, Sui Jingfeng wrote:

From: suijingfeng 

There is a display controller in loongson's LS2K1000 SoC and LS7A1000
bridge chip, the DC is a PCI device in those chips. It has two display
pipes but with only one hardware cursor. Each way has a DVO interface
which provide RGB888 signals, vertical & horizontal synchronisations,
data enable and the pixel clock. Each CRTC is able to scanout from
1920x1080 resolution at 60Hz. The maxmium resolution is 2048x2048
according to the hardware spec.

Loongson display controllers are simple which require scanout buffers
to be physically contiguous. LS2K1000 is a SOC, Only system memory is
available. Therefore CMA helper based driver is intended to be use,
although it is possible to use VRAM helper based solution by carving
out part of system memory as VRAM.

On LS7A1000/LS7A2000 bridge chip, the DC is equipped with a dedicated
video memory which is typically 64MB or more. In this case, VRAM helper
based solution which scanout from local VRAM is reconmended to use.
It is reliable to use for massive production, but CMA based helper
solution is still usable on ls7a1000 and ls7a2000, at the price of
the CRTC must access the FB in RAM through the PCIe bus and HT3.0 bus.
This causes continuous traffic on the bus regardless of whether the FB
image is updating or not. Sadly, it suffer from screen flickering under
RAM pressure on LS7A1000. Luckily, It show extremely good condition on
LS7A2000 even under stressapptest, Maybe the hardware engineer resolve
this issue. Integrating two distict helpers based driver into one piece
allow code sharing.

We have also implemented demage update on top of CMA helper which copy
the demaged region from the shadow framebuffer in system RAM to the real
framebuffer in VRAM manually. This is intend to overcome the screen
flicking issue on LS7A1000, but the performance is not good.
Using "lsdc.dirty_update=1" in the kernel commmand line if you would like
to have a try.

For LS7A1000, there are 4 dedicated GPIOs whose control register is
located at the DC register space, They are used to emulate two way i2c.
One for DVO0, another for DVO1. This is the reason why this driver is
not switch to drm bridge framework yet. LS2K1000 and LS2K0500 SoC don't
have such GPIO hardwared, they grab i2c adapter from other module,
either general purpose GPIO emulated i2c or hardware i2c adapter.
Drm bridge and drm panel driver for the external encoder is suitable for
those SoC. We have already implemented this on our downstream 4.19.190
kernel. But due to the GPIO, PWM and I2C device driver support for
LS2K1000 is not upstreamed yet, this driver still can be use to bring
the graphic environment up by providing display timings or similar things
in the device tree.

The DC in LS7A1000 has only one hardware cursor, we simply let the two
CRTC share it. The DC in LS7A2000 have two cursor, two built-in hdmi
encoder and one transparent vga encoder and more, surport for LS7A2000
is on the way. In short, we have built-in gpio emulated i2c support,
we also have hardware cursor support. LS7A2000 The kind of tiny drivers
in drm/tiny is not suitable for us.

 +--++---+
 | DDR4 ||  +---+|
 +--+|  | PCIe Root complex |   LS7A1000 |
|| MC0   |  +--++-+++|
   +--+  HT 3.0  | || || |
   | LS3A4000 |<>| +---++---+  +--++--++-+   +--+
   |   CPU|<>| | GC1000 |  | LSDC |<-->| DDR3 MC |<->| VRAM |
   +--+  | ++  +-+--+-++-+   +--+
|| MC1   +---|--|+
 +--+|  |
 | DDR4 |  +---+   DVO0  |  |  DVO1   +--+
 +--+   VGA <--|ADV7125|<+  +>|TFP410|--> DVI/HDMI
   +---+  +--+

The above picture give a simple usage of LS7A1000, note that the encoder
is not necessary adv7125 or tfp410, it is a choice of the downstream board
manufacturer. Other candicate encoders can be ch7034b, sil9022 and ite66121
lt8618 etc. Besides, the DC in both ls2k1000 and ls7k1000 has the same of
PCI vendor id and pci device id. Both is 0x0014:0x7a06, the reverison id
is also same. This is the firmware engineer's mistake, but such firmware
and various boards ship with such firmware already released. We choose to
deduce the chip's identification from information provided by device tree.
For lsdc, there is only a 1:1 mapping of encoders and connectors.

v2: fixup warnings reported by kernel test robot

v3: fix more grammar mistakes in Kconfig reported by Randy Dunlap and give
 more details about lsdc.

v4:
1) Add dts required and explain why device tree is required.
2) Give more description about lsdc 

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

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

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

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


RE: Regression from 3c196f056666 ("drm/amdgpu: always reset the asic in suspend (v2)") on suspend?

2022-02-14 Thread Quan, Evan
[AMD Official Use Only]



> -Original Message-
> From: Salvatore Bonaccorso  On Behalf
> Of Salvatore Bonaccorso
> Sent: Sunday, February 13, 2022 2:24 AM
> To: Deucher, Alexander 
> Cc: Dominique Dumont ; 1005...@bugs.debian.org;
> Tuikov, Luben ; Quan, Evan
> ; Sasha Levin ; Koenig, Christian
> ; Pan, Xinhui ; David
> Airlie ; Daniel Vetter ; amd-
> g...@lists.freedesktop.org; dri-devel@lists.freedesktop.org; linux-
> ker...@vger.kernel.org
> Subject: Regression from 3c196f05 ("drm/amdgpu: always reset the asic
> in suspend (v2)") on suspend?
> 
> Hi Alex, hi all
> 
> In Debian we got a regression report from Dominique Dumont, CC'ed in
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugs
> .debian.org%2F1005005data=04%7C01%7Cevan.quan%40amd.com%7
> C735917b6e3f44fc8fda808d9ee54cbc0%7C3dd8961fe4884e608e11a82d994e1
> 83d%7C0%7C0%7C637802870862664095%7CUnknown%7CTWFpbGZsb3d8eyJ
> WIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%
> 7C3000sdata=6xECB3MmvNYuOn41ZOEDPyWUjklY%2Bfxumz7lf8fijwA
> %3Dreserved=0 that afer an update to 5.15.15 based kernel, his
> machine noe longer suspends correctly, after screen going black as usual it
> comes back. The Debian bug above contians a trace.
> 
> Dominique confirmed that this issue persisted after updating to 5.16.7
> furthermore he bisected the issue and found
> 
>   3c196f0510912645c7c5d9107706003f67c3 is the first bad commit
>   commit 3c196f0510912645c7c5d9107706003f67c3
>   Author: Alex Deucher 
>   Date:   Fri Nov 12 11:25:30 2021 -0500
> 
>   drm/amdgpu: always reset the asic in suspend (v2)
> 
>   [ Upstream commit daf8de0874ab5b74b38a38726fdd3d07ef98a7ee ]
> 
>   If the platform suspend happens to fail and the power rail
>   is not turned off, the GPU will be in an unknown state on
>   resume, so reset the asic so that it will be in a known
>   good state on resume even if the platform suspend failed.
> 
>   v2: handle s0ix
> 
>   Acked-by: Luben Tuikov 
>   Acked-by: Evan Quan 
>   Signed-off-by: Alex Deucher 
>   Signed-off-by: Sasha Levin 
> 
>drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 5 -
>1 file changed, 4 insertions(+), 1 deletion(-)
> 
> to be the first bad commit, see
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fbugs
> .debian.org%2F1005005%2334data=04%7C01%7Cevan.quan%40amd.c
> om%7C735917b6e3f44fc8fda808d9ee54cbc0%7C3dd8961fe4884e608e11a82d
> 994e183d%7C0%7C0%7C637802870862664095%7CUnknown%7CTWFpbGZsb3
> d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0
> %3D%7C3000sdata=CV%2FKmpYT8WOVJnrTiU91godaFDJMpjih%2FAV
> NAcw5qaI%3Dreserved=0 .
I checked the back trace posted there(below). It seems the error occurred 
during amdgpu_device_suspend(). 
That means Alex's patch should not be related(as it affected only those logic 
after amdgpu_device_suspend()). 
So we might got a wrong regression point here.
[  257.842851]  ? vi_common_set_clockgating_state+0x229/0x2f0 [amdgpu]
[  257.843356]  amdgpu_device_ip_suspend_phase1+0x5e/0xc0 [amdgpu]
[  257.843771]  amdgpu_device_suspend+0x62/0xc0 [amdgpu]
[  257.844184]  amdgpu_pmops_suspend+0x36/0x70 [amdgpu]
[  257.844631]  pci_pm_suspend+0x71/0x160
[  257.844643]  ? pci_pm_freeze+0xb0/0xb0

BR
Evan
> 
> Does this ring any bell? Any idea on the problem?
> 
> Regards,
> Salvatore


[PATCH] amdgpu: assign adev after null check

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

adev should be assigned after a null check

Signed-off-by: Wang Qing 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
index 2c929fa..da114f7
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
@@ -259,12 +259,13 @@ static void amdgpu_ctx_fini_entity(struct 
amdgpu_ctx_entity *entity)
 static int amdgpu_ctx_get_stable_pstate(struct amdgpu_ctx *ctx,
u32 *stable_pstate)
 {
-   struct amdgpu_device *adev = ctx->adev;
+   struct amdgpu_device *adev;
enum amd_dpm_forced_level current_level;
 
if (!ctx)
return -EINVAL;
 
+   adev = ctx->adev;
current_level = amdgpu_dpm_get_performance_level(adev);
 
switch (current_level) {
@@ -290,13 +291,14 @@ static int amdgpu_ctx_get_stable_pstate(struct amdgpu_ctx 
*ctx,
 static int amdgpu_ctx_set_stable_pstate(struct amdgpu_ctx *ctx,
u32 stable_pstate)
 {
-   struct amdgpu_device *adev = ctx->adev;
+   struct amdgpu_device *adev;
enum amd_dpm_forced_level level;
int r;
 
if (!ctx)
return -EINVAL;
 
+   adev = ctx->adev;
mutex_lock(>pm.stable_pstate_ctx_lock);
if (adev->pm.stable_pstate_ctx && adev->pm.stable_pstate_ctx != ctx) {
r = -EBUSY;
-- 
2.7.4



[PATCH V3 13/13] media: vivid: use time_is_after_jiffies() instead of open coding it

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

Use the helper function time_is_{before,after}_jiffies() to improve
code readability.

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

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



[PATCH V3 12/13] media: wl128x: use time_is_before_jiffies() instead of open coding it

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

Use the helper function time_is_{before,after}_jiffies() to improve
code readability.

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

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



[PATCH V3 11/13] media: tda8083: use time_is_after_jiffies() instead of open coding it

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

Use the helper function time_is_{before,after}_jiffies() to improve
code readability.

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

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



[PATCH V3 10/13] md: use time_is_before_eq_jiffies() instead of open coding it

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

Use the helper function time_is_{before,after}_jiffies() to improve
code readability.

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

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



[PATCH V3 10/13] media: stv0299: use time_is_before_jiffies() instead of open coding it

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

Use the helper function time_is_{before,after}_jiffies() to improve
code readability.

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

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



[PATCH V3 9/13] media: si21xx: use time_is_before_jiffies() instead of open coding it

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

Use the helper function time_is_{before,after}_jiffies() to improve
code readability.

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

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



[PATCH V3 7/13] md: use time_is_before_jiffies(() instead of open coding it

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

Use the helper function time_is_{before,after}_jiffies() to improve
code readability.

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

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



[PATCH V3 6/13] input: serio: use time_is_before_jiffies() instead of open coding it

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

Use the helper function time_is_{before,after}_jiffies() to improve
code readability.

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

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



[PATCH V3 5/13] hid: use time_is_after_jiffies() instead of open coding it

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

Use the helper function time_is_{before,after}_jiffies() to improve
code readability.

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

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



[PATCH V3 4/13] gpu: drm: radeon: use time_is_before_jiffies() instead of open coding it

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

Use the helper function time_is_{before,after}_jiffies() to improve
code readability.

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

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



[PATCH V3 3/13] gpu: drm: i915: use time_is_after_jiffies() instead of open coding it

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

Use the helper function time_is_{before,after}_jiffies() to improve
code readability.

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

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



[PATCH V3 2/13] clk: mvebu: use time_is_before_eq_jiffies() instead of open coding it

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

Use the helper function time_is_{before,after}_jiffies() to improve
code readability.

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

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



[PATCH V3 1/13] block: xen: use time_is_before_eq_jiffies() instead of open coding it

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

Use the helper function time_is_{before,after}_jiffies() to improve
code readability.

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

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



[PATCH V3 00/13] use time_is_{before, after}_jiffies() instead of open coding it

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

Use the helper function time_is_{before,after}_jiffies() to improve
code readability.

V2:
Batch them in a series suggested by Joe.
Use time_xxx_jiffies() instead of time_xxx() suggested by Kieran.

V3:
Fix subject and description suggested by Ted.

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

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

-- 
2.7.4



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

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

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

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



linux-next: build failure after merge of the drm-intel tree

2022-02-14 Thread Stephen Rothwell
Hi all,

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

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

Presumably caused by commit

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

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

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

-- 
Cheers,
Stephen Rothwell


pgpL5IiK2RgCC.pgp
Description: OpenPGP digital signature


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

-- 
2.34.1



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

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

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

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

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

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

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

[PATCH v4 07/10] drm/amd: drop the use of `pci_is_thunderbolt_attached`

2022-02-14 Thread Mario Limonciello
Currently `pci_is_thunderbolt_attached` is used to indicate a device
is connected externally.

The PCI core now marks such devices as removable and downstream drivers
can use this instead.

Reviewed-by: Macpaul Lin 
Signed-off-by: Mario Limonciello 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 2 +-
 drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 1ebb91db2274..6dbf5753b5be 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -161,7 +161,7 @@ int amdgpu_driver_load_kms(struct amdgpu_device *adev, 
unsigned long flags)
(amdgpu_is_atpx_hybrid() ||
 amdgpu_has_atpx_dgpu_power_cntl()) &&
((flags & AMD_IS_APU) == 0) &&
-   !pci_is_thunderbolt_attached(to_pci_dev(dev->dev)))
+   !dev_is_removable(>pdev->dev))
flags |= AMD_IS_PX;
 
parent = pci_upstream_bridge(adev->pdev);
diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c 
b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c
index ee7cab37dfd5..2c5d74d836f0 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c
+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c
@@ -382,7 +382,7 @@ static void nbio_v2_3_enable_aspm(struct amdgpu_device 
*adev,
 
data |= NAVI10_PCIE__LC_L0S_INACTIVITY_DEFAULT << 
PCIE_LC_CNTL__LC_L0S_INACTIVITY__SHIFT;
 
-   if (pci_is_thunderbolt_attached(adev->pdev))
+   if (dev_is_removable(>pdev->dev))
data |= NAVI10_PCIE__LC_L1_INACTIVITY_TBT_DEFAULT  << 
PCIE_LC_CNTL__LC_L1_INACTIVITY__SHIFT;
else
data |= NAVI10_PCIE__LC_L1_INACTIVITY_DEFAULT << 
PCIE_LC_CNTL__LC_L1_INACTIVITY__SHIFT;
-- 
2.34.1



[PATCH v4 06/10] PCI: Drop the `is_thunderbolt` attribute from PCI core

2022-02-14 Thread Mario Limonciello
The `is_thunderbolt` attribute originally had a well defined list of
quirks that it existed for, but it has been overloaded with more
meaning.

Instead use the driver core removable attribute to indicate the
detail a device is attached to a thunderbolt or USB4 chain.

Signed-off-by: Mario Limonciello 
---
 drivers/pci/probe.c   | 2 +-
 drivers/platform/x86/apple-gmux.c | 2 +-
 include/linux/pci.h   | 5 ++---
 3 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index a07859c8675f..fe49175770a1 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1586,7 +1586,7 @@ static void set_pcie_thunderbolt(struct pci_dev *dev)
/* Is the device part of a Thunderbolt controller? */
vsec = pci_find_vsec_capability(dev, PCI_VENDOR_ID_INTEL, 
PCI_VSEC_ID_INTEL_TBT);
if (vsec)
-   dev->is_thunderbolt = 1;
+   dev->external_facing = true;
 }
 
 static void set_pcie_untrusted(struct pci_dev *dev)
diff --git a/drivers/platform/x86/apple-gmux.c 
b/drivers/platform/x86/apple-gmux.c
index 57553f9b4d1d..da0c39b0 100644
--- a/drivers/platform/x86/apple-gmux.c
+++ b/drivers/platform/x86/apple-gmux.c
@@ -596,7 +596,7 @@ static int gmux_resume(struct device *dev)
 
 static int is_thunderbolt(struct device *dev, void *data)
 {
-   return to_pci_dev(dev)->is_thunderbolt;
+   return to_pci_dev(dev)->external_facing;
 }
 
 static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 1e5b769e42fc..d9719eb14654 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -442,7 +442,6 @@ struct pci_dev {
unsigned intis_virtfn:1;
unsigned intis_hotplug_bridge:1;
unsigned intshpc_managed:1; /* SHPC owned by shpchp */
-   unsigned intis_thunderbolt:1;   /* Thunderbolt controller */
unsigned intno_cmd_complete:1;  /* Lies about command completed 
events */
 
/*
@@ -2447,11 +2446,11 @@ static inline bool pci_is_thunderbolt_attached(struct 
pci_dev *pdev)
 {
struct pci_dev *parent = pdev;
 
-   if (pdev->is_thunderbolt)
+   if (dev_is_removable(>dev))
return true;
 
while ((parent = pci_upstream_bridge(parent)))
-   if (parent->is_thunderbolt)
+   if (dev_is_removable(>dev))
return true;
 
return false;
-- 
2.34.1



[PATCH v4 10/10] PCI: drop `pci_is_thunderbolt_attached`

2022-02-14 Thread Mario Limonciello
Currently `pci_is_thunderbolt_attached` is used to indicate a device
is connected externally.

As all drivers now look at the removable attribute, drop this function.

Signed-off-by: Mario Limonciello 
---
 include/linux/pci.h | 22 --
 1 file changed, 22 deletions(-)

diff --git a/include/linux/pci.h b/include/linux/pci.h
index d9719eb14654..089e7e36a0d9 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -2434,28 +2434,6 @@ static inline bool pci_ari_enabled(struct pci_bus *bus)
return bus->self && bus->self->ari_enabled;
 }
 
-/**
- * pci_is_thunderbolt_attached - whether device is on a Thunderbolt daisy chain
- * @pdev: PCI device to check
- *
- * Walk upwards from @pdev and check for each encountered bridge if it's part
- * of a Thunderbolt controller.  Reaching the host bridge means @pdev is not
- * Thunderbolt-attached.  (But rather soldered to the mainboard usually.)
- */
-static inline bool pci_is_thunderbolt_attached(struct pci_dev *pdev)
-{
-   struct pci_dev *parent = pdev;
-
-   if (dev_is_removable(>dev))
-   return true;
-
-   while ((parent = pci_upstream_bridge(parent)))
-   if (dev_is_removable(>dev))
-   return true;
-
-   return false;
-}
-
 #if defined(CONFIG_PCIEPORTBUS) || defined(CONFIG_EEH)
 void pci_uevent_ers(struct pci_dev *pdev, enum  pci_ers_result err_type);
 #endif
-- 
2.34.1



[PATCH v4 09/10] drm/radeon: drop the use of `pci_is_thunderbolt_attached`

2022-02-14 Thread Mario Limonciello
Currently `pci_is_thunderbolt_attached` is used to indicate a device
is connected externally.

The PCI core now marks such devices as removable and downstream drivers
can use this instead.

Signed-off-by: Mario Limonciello 
---
 drivers/gpu/drm/radeon/radeon_device.c | 4 ++--
 drivers/gpu/drm/radeon/radeon_kms.c| 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_device.c 
b/drivers/gpu/drm/radeon/radeon_device.c
index 4f0fbf667431..5117fce23b3f 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -1439,7 +1439,7 @@ int radeon_device_init(struct radeon_device *rdev,
 
if (rdev->flags & RADEON_IS_PX)
runtime = true;
-   if (!pci_is_thunderbolt_attached(rdev->pdev))
+   if (!dev_is_removable(>pdev->dev))
vga_switcheroo_register_client(rdev->pdev,
   _switcheroo_ops, runtime);
if (runtime)
@@ -1527,7 +1527,7 @@ void radeon_device_fini(struct radeon_device *rdev)
/* evict vram memory */
radeon_bo_evict_vram(rdev);
radeon_fini(rdev);
-   if (!pci_is_thunderbolt_attached(rdev->pdev))
+   if (!dev_is_removable(>pdev->dev))
vga_switcheroo_unregister_client(rdev->pdev);
if (rdev->flags & RADEON_IS_PX)
vga_switcheroo_fini_domain_pm_ops(rdev->dev);
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c 
b/drivers/gpu/drm/radeon/radeon_kms.c
index 11ad210919c8..e01ee7a5cf5d 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -139,7 +139,7 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned 
long flags)
if ((radeon_runtime_pm != 0) &&
radeon_has_atpx() &&
((flags & RADEON_IS_IGP) == 0) &&
-   !pci_is_thunderbolt_attached(pdev))
+   !dev_is_removable(>dev))
flags |= RADEON_IS_PX;
 
/* radeon_device_init should report only fatal error
-- 
2.34.1



[PATCH v4 08/10] drm/nouveau: drop the use of `pci_is_thunderbolt_attached`

2022-02-14 Thread Mario Limonciello
Currently `pci_is_thunderbolt_attached` is used to indicate a device
is connected externally.

The PCI core now marks such devices as removable and downstream drivers
can use this instead.

Signed-off-by: Mario Limonciello 
---
 drivers/gpu/drm/nouveau/nouveau_vga.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c 
b/drivers/gpu/drm/nouveau/nouveau_vga.c
index 60cd8c0463df..2c8008cb38e0 100644
--- a/drivers/gpu/drm/nouveau/nouveau_vga.c
+++ b/drivers/gpu/drm/nouveau/nouveau_vga.c
@@ -97,7 +97,7 @@ nouveau_vga_init(struct nouveau_drm *drm)
vga_client_register(pdev, nouveau_vga_set_decode);
 
/* don't register Thunderbolt eGPU with vga_switcheroo */
-   if (pci_is_thunderbolt_attached(pdev))
+   if (dev_is_removable(>dev))
return;
 
vga_switcheroo_register_client(pdev, _switcheroo_ops, runtime);
@@ -120,7 +120,7 @@ nouveau_vga_fini(struct nouveau_drm *drm)
 
vga_client_unregister(pdev);
 
-   if (pci_is_thunderbolt_attached(pdev))
+   if (dev_is_removable(>dev))
return;
 
vga_switcheroo_unregister_client(pdev);
-- 
2.34.1



[PATCH v4 02/10] PCI: Move `is_thunderbolt` check for lack of command completed to a quirk

2022-02-14 Thread Mario Limonciello
The `is_thunderbolt` check is currently used to indicate the lack of
command completed support for a number of older Thunderbolt devices.

This however is heavy handed and should have been done via a quirk.  Move
the affected devices outlined in commit 493fb50e958c ("PCI: pciehp: Assume
NoCompl+ for Thunderbolt ports") into pci quirks.

Suggested-by: Lukas Wunner 
Signed-off-by: Mario Limonciello 
---
 drivers/pci/hotplug/pciehp_hpc.c |  6 +-
 drivers/pci/quirks.c | 17 +
 include/linux/pci.h  |  2 ++
 3 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 1c1ebf3dad43..e4c42b24aba8 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -996,11 +996,7 @@ struct controller *pcie_init(struct pcie_device *dev)
if (pdev->hotplug_user_indicators)
slot_cap &= ~(PCI_EXP_SLTCAP_AIP | PCI_EXP_SLTCAP_PIP);
 
-   /*
-* We assume no Thunderbolt controllers support Command Complete events,
-* but some controllers falsely claim they do.
-*/
-   if (pdev->is_thunderbolt)
+   if (pdev->no_cmd_complete)
slot_cap |= PCI_EXP_SLTCAP_NCCS;
 
ctrl->slot_cap = slot_cap;
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index d2dd6a6cda60..6d3c88edde00 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3675,6 +3675,23 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 
PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PORT_RIDGE,
quirk_thunderbolt_hotplug_msi);
 
+static void quirk_thunderbolt_command_completed(struct pci_dev *pdev)
+{
+   pdev->no_cmd_complete = 1;
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LIGHT_RIDGE,
+   quirk_thunderbolt_command_completed);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EAGLE_RIDGE,
+   quirk_thunderbolt_command_completed);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LIGHT_PEAK,
+   quirk_thunderbolt_command_completed);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 
PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C,
+   quirk_thunderbolt_command_completed);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 
PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_2C,
+   quirk_thunderbolt_command_completed);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PORT_RIDGE,
+   quirk_thunderbolt_command_completed);
+
 #ifdef CONFIG_ACPI
 /*
  * Apple: Shutdown Cactus Ridge Thunderbolt controller.
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 8253a5413d7c..1e5b769e42fc 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -443,6 +443,8 @@ struct pci_dev {
unsigned intis_hotplug_bridge:1;
unsigned intshpc_managed:1; /* SHPC owned by shpchp */
unsigned intis_thunderbolt:1;   /* Thunderbolt controller */
+   unsigned intno_cmd_complete:1;  /* Lies about command completed 
events */
+
/*
 * Devices marked being untrusted are the ones that can potentially
 * execute DMA attacks and similar. They are typically connected
-- 
2.34.1



[PATCH v4 04/10] PCI: Detect PCIe root ports for discrete USB4 controllers

2022-02-14 Thread Mario Limonciello
Discrete USB4 controllers won't have ACPI nodes specifying which
root ports they are linked with when the software connection manager
creates tunnels.  These PCIe root ports should be marked as external
so that existing logic will mark tunneled devices as removable.

In order to set the external attribute, use the USB4 DVSEC extended
capabability set on these root ports to determine if they are located
on a discrete USB4 controller.

Suggested-by: Mika Westerberg 
Link: https://usb.org/sites/default/files/USB4%20Specification%202026.zip
Signed-off-by: Mario Limonciello 
---
 drivers/pci/probe.c | 50 +
 include/linux/pci_ids.h |  2 ++
 2 files changed, 52 insertions(+)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 17a969942d37..a07859c8675f 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -25,6 +25,8 @@
 #define CARDBUS_LATENCY_TIMER  176 /* secondary latency timer */
 #define CARDBUS_RESERVE_BUSNR  3
 
+#define PCI_DVSEC_ID_USB4  0x23
+
 static struct resource busn_resource = {
.name   = "PCI busn",
.start  = 0,
@@ -1600,6 +1602,52 @@ static void set_pcie_untrusted(struct pci_dev *dev)
dev->untrusted = true;
 }
 
+/*
+ * Use the fields from the USB4 Designated Vendor Specific Extended Capability
+ * (DVSEC) for Power Management 1.0 to identify PCIe root ports that are for
+ * XHCI and PCIe tunneling
+ */
+static void pci_set_usb4_external(struct pci_dev *dev)
+{
+   int dvsec_val = 0, pos;
+   u32 hdr;
+
+   /*
+* Table 3-1 "USB4 DVSEC Header fields" says vendors can use
+* either the Intel or USB IF vendor ID but should look for
+* the appropriate DVSEC ID.
+*/
+   pos = pci_find_dvsec_capability(dev,
+   PCI_VENDOR_ID_INTEL,
+   PCI_DVSEC_ID_USB4);
+   if (pos) {
+   dvsec_val = 0x06;
+   } else {
+   pos = pci_find_dvsec_capability(dev,
+   PCI_VENDOR_ID_USB_IF,
+   PCI_DVSEC_ID_USB4);
+   if (pos)
+   dvsec_val = 0x01;
+   }
+   if (!dvsec_val)
+   return;
+
+   pci_read_config_dword(dev, pos + PCI_DVSEC_HEADER2, );
+   if ((hdr & GENMASK(15, 0)) != dvsec_val)
+   return;
+   /*
+* Look at the port type field for the expected bits for PCIe tunneling
+* and XHCI tunneling
+*
+* 0x0 - Native Host Interface
+* 0x1 - PCIe Tunneled Port
+* 0x2 - USB Tunneled Port
+* 0x3-0x7 - Reserved
+*/
+   if (hdr & GENMASK(17, 16))
+   dev->external_facing = true;
+}
+
 static void pci_set_removable(struct pci_dev *dev)
 {
struct pci_dev *parent = pci_upstream_bridge(dev);
@@ -1870,6 +1918,8 @@ int pci_setup_device(struct pci_dev *dev)
/* Early fixups, before probing the BARs */
pci_fixup_device(pci_fixup_early, dev);
 
+   pci_set_usb4_external(dev);
+
pci_set_removable(dev);
 
pci_info(dev, "[%04x:%04x] type %02x class %#08x\n",
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 61b161d914f0..3faee1af9ace 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2567,6 +2567,8 @@
 #define PCI_VENDOR_ID_TEKRAM   0x1de1
 #define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29
 
+#define PCI_VENDOR_ID_USB_IF   0x1ec0
+
 #define PCI_VENDOR_ID_TEHUTI   0x1fc9
 #define PCI_DEVICE_ID_TEHUTI_3009  0x3009
 #define PCI_DEVICE_ID_TEHUTI_3010  0x3010
-- 
2.34.1



[PATCH v4 05/10] PCI: Move check for old Apple Thunderbolt controllers into a quirk

2022-02-14 Thread Mario Limonciello
`pci_bridge_d3_possible` currently checks explicitly for a Thunderbolt
controller to indicate that D3 is possible.

This is used solely for older Apple systems, due to a variety of factors:
* Apple used SW connection manager from the beginning, other manufacturers
  used a FW connection manager (ICM)
* Apple supported D3 initially, other manfuacturers didn't introduced this
  until the `HotplugSupportInD3` _DSD was introduced in ~2015.

Apple has stopped creating new machines with Intel Thunderbolt controllers,
and all other manufacturers now support D3 via `HotPlugSupportInD3` so
this should be a fixed list.

Suggested-by: Mika Westerberg 
Signed-off-by: Mario Limonciello 
---
 drivers/pci/pci.c| 17 +++
 drivers/pci/quirks.c | 67 
 2 files changed, 79 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 9ecce435fb3f..01557c950c9f 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1064,7 +1064,18 @@ static inline bool platform_pci_bridge_d3(struct pci_dev 
*dev)
if (pci_use_mid_pm())
return false;
 
-   return acpi_pci_bridge_d3(dev);
+   if (acpi_pci_bridge_d3(dev))
+   return true;
+
+   /*
+* This is for Apple machines via a quirk
+* Non-Apple machines will use the ACPI property with the same name
+* from `acpi_pci_bridge_d3` to indciate support.
+*/
+   if (device_property_read_bool(>dev, "HotPlugSupportInD3"))
+   return true;
+
+   return false;
 }
 
 /**
@@ -2954,10 +2965,6 @@ bool pci_bridge_d3_possible(struct pci_dev *bridge)
if (pci_bridge_d3_force)
return true;
 
-   /* Even the oldest 2010 Thunderbolt controller supports D3. */
-   if (bridge->is_thunderbolt)
-   return true;
-
/* Platform might know better if the bridge supports D3 */
if (platform_pci_bridge_d3(bridge))
return true;
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 6d3c88edde00..97793cfcd8ff 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3756,6 +3756,73 @@ DECLARE_PCI_FIXUP_SUSPEND_LATE(PCI_VENDOR_ID_INTEL,
   quirk_apple_poweroff_thunderbolt);
 #endif
 
+/*
+ * The first machines supporting Intel Thunderbolt were released by Apple, and
+ * supported a software based connection manager including D3 support, as far
+ * back as 2010. These machines don't have ACPI companions to declare D3
+ * support.
+ *
+ * Other manufacturers introduced Thunderbolt shortly after but notably did not
+ * support:
+ * - Software based connection manager
+ * - Runtime power management
+ * Power management was handled via the BIOS when nothing was plugged in.
+ * Runtime D3 was later introduced in ~2015 and Microsoft declared when the
+ * `HotPlugSupportInD3` _DSD was present that they would support D3.
+ *
+ * This list is expected to be complete and not grow in the future as Apple
+ * has stopped producing new x86 models with Intel Thunderbolt controllers.
+ */
+static void quirk_apple_d3_thunderbolt(struct pci_dev *dev)
+{
+   struct property_entry properties[] = {
+   PROPERTY_ENTRY_BOOL("HotPlugSupportInD3"),
+   {},
+   };
+
+   if (!x86_apple_machine)
+   return;
+
+   if (device_create_managed_software_node(>dev, properties, NULL))
+   pci_warn(dev, "could not add HotPlugSupportInD3 property");
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LIGHT_RIDGE,
+   quirk_apple_d3_thunderbolt);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EAGLE_RIDGE,
+   quirk_apple_d3_thunderbolt);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LIGHT_PEAK,
+   quirk_apple_d3_thunderbolt);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 
PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C,
+   quirk_apple_d3_thunderbolt);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 
PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_2C,
+   quirk_apple_d3_thunderbolt);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PORT_RIDGE,
+   quirk_apple_d3_thunderbolt);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 
PCI_DEVICE_ID_INTEL_REDWOOD_RIDGE_2C_NHI,
+   quirk_apple_d3_thunderbolt);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 
PCI_DEVICE_ID_INTEL_REDWOOD_RIDGE_2C_BRIDGE,
+   quirk_apple_d3_thunderbolt);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 
PCI_DEVICE_ID_INTEL_REDWOOD_RIDGE_4C_NHI,
+   quirk_apple_d3_thunderbolt);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 
PCI_DEVICE_ID_INTEL_REDWOOD_RIDGE_4C_BRIDGE,
+   quirk_apple_d3_thunderbolt);

[PATCH v4 03/10] PCI: Detect root port of internal USB4 controllers

2022-02-14 Thread Mario Limonciello
The root port used for PCIe tunneling is the root of the hierarchy used
for all PCIe devices that are connected downstream.  Tunnels are created
and destroyed by the USB4 SW CM.  So this port should be marked as external
meaning all devices connected to it are appropriately marked as removable
for downstream drivers to detect.

This can be done by looking for the device property specified in
the ACPI tables `usb4-host-interface`.

Suggested-by: Mika Westerberg 
Link: 
https://docs.microsoft.com/en-us/windows-hardware/drivers/pci/dsd-for-pcie-root-ports#mapping-native-protocols-pcie-displayport-tunneled-through-usb4-to-usb4-host-routers
Signed-off-by: Mario Limonciello 
---
 drivers/pci/pci-acpi.c | 15 ---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index a42dbf448860..695dbd88b8b7 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -1335,12 +1335,21 @@ static void pci_acpi_optimize_delay(struct pci_dev 
*pdev,
 
 static void pci_acpi_set_external_facing(struct pci_dev *dev)
 {
-   u8 val;
+   u8 val = 0;
 
if (pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT)
return;
-   if (device_property_read_u8(>dev, "ExternalFacingPort", ))
-   return;
+   device_property_read_u8(>dev, "ExternalFacingPort", );
+
+   /* check for root port for PCIe tunnels on integrated controllers */
+   if (!val) {
+   struct acpi_device *adev = ACPI_COMPANION(>dev);
+
+   if (!adev)
+   return;
+   val = fwnode_property_present(acpi_fwnode_handle(adev),
+ "usb4-host-interface");
+   }
 
/*
 * These root ports expose PCIe (including DMA) outside of the
-- 
2.34.1



[PATCH v4 01/10] PCI: Add USB4 class definition

2022-02-14 Thread Mario Limonciello
This PCI class definition of the USB4 device is currently located only in
the thunderbolt driver.

It will be needed by a few other drivers for upcoming changes. Move it into
the common include file.

Acked-by: Bjorn Helgaas 
Acked-by: Alex Deucher 
Acked-by: Mika Westerberg 
Signed-off-by: Mario Limonciello 
---
 drivers/thunderbolt/nhi.h | 2 --
 include/linux/pci_ids.h   | 1 +
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/thunderbolt/nhi.h b/drivers/thunderbolt/nhi.h
index 69083aab2736..79e980b51f94 100644
--- a/drivers/thunderbolt/nhi.h
+++ b/drivers/thunderbolt/nhi.h
@@ -81,6 +81,4 @@ extern const struct tb_nhi_ops icl_nhi_ops;
 #define PCI_DEVICE_ID_INTEL_TGL_H_NHI0 0x9a1f
 #define PCI_DEVICE_ID_INTEL_TGL_H_NHI1 0x9a21
 
-#define PCI_CLASS_SERIAL_USB_USB4  0x0c0340
-
 #endif
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index aad54c666407..61b161d914f0 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -116,6 +116,7 @@
 #define PCI_CLASS_SERIAL_USB_OHCI  0x0c0310
 #define PCI_CLASS_SERIAL_USB_EHCI  0x0c0320
 #define PCI_CLASS_SERIAL_USB_XHCI  0x0c0330
+#define PCI_CLASS_SERIAL_USB_USB4  0x0c0340
 #define PCI_CLASS_SERIAL_USB_DEVICE0x0c03fe
 #define PCI_CLASS_SERIAL_FIBER 0x0c04
 #define PCI_CLASS_SERIAL_SMBUS 0x0c05
-- 
2.34.1



[PATCH v4 00/10] Overhaul `is_thunderbolt`

2022-02-14 Thread Mario Limonciello
Various drivers in the kernel use `is_thunderbolt` or
`pci_is_thunderbolt_attached` to designate behaving differently
from a device that is internally in the machine. This relies upon checks
for a specific capability only set on Intel controllers.

Non-Intel USB4 designs should also match this designation so that they
can be treated the same regardless of the host they're connected to.

As part of adding the generic USB4 controller code, it was realized that
`is_thunderbolt` and `pcie_is_thunderbolt_attached` have been overloaded.

Instead migrate to using removable attribute from device core.

Changes from v3->v4:
- Add tags from last review where applicable
- Update titles of different patches
- Add more comments and commit messages to various patches to address
  comments raised in review
- Re-order the patch series, moving more contentious patches later
- Drop patch marking NHI removable
- Drop patch changing gmux on it's own, roll into patch to drop
  `is_thunderbolt`
- Modify patch to mark integrated USB4 tunnel PCIe root ports as
  "external" instead of removable.
- Modify patch to mark discrete USB4 tunnel root ports as "external"
  instead of removable.
- Fix bit mask error in discrete USB4 tunnel patch
- Fix USB IF vendor designation location in pci_ids.h

Changes from v2->v3:
- Add various tags for patches that haven't changed from v2->v3
- Add new patches for Mika's suggestions:
  * Moving Apple Thunderbolt D3 declaration into quirks
  * Detect PCIe root port used for PCIe tunneling on integrated
controllers using `usb4-host-interface`
  * Detect PCIe root port used for PCIe tunneling on discrete
controllers using the USB4 DVSEC specification

Changes from v1->v2:
- Add Alex's tag to first patch
- Move lack of command completion into a quirk (Lukas)
- Drop `is_thunderbolt` attribute and `pci_is_thunderbolt_attached` and
  use device core removable attribute instead
- Adjust all consumers of old attribute to use removable

Note: this spans USB/DRM/platform-x86/PCI trees.
As a majority of the changes are in PCI, it should probably come through
that tree if possible.

Mario Limonciello (10):
  PCI: Add USB4 class definition
  PCI: Move `is_thunderbolt` check for lack of command completed to a
quirk
  PCI: Detect root port of internal USB4 controllers
  PCI: Detect PCIe root ports for discrete USB4 controllers
  PCI: Move check for old Apple Thunderbolt controllers into a quirk
  PCI: Drop the `is_thunderbolt` attribute from PCI core
  drm/amd: drop the use of `pci_is_thunderbolt_attached`
  drm/nouveau: drop the use of `pci_is_thunderbolt_attached`
  drm/radeon: drop the use of `pci_is_thunderbolt_attached`
  PCI: drop `pci_is_thunderbolt_attached`

 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c |  2 +-
 drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c  |  2 +-
 drivers/gpu/drm/nouveau/nouveau_vga.c   |  4 +-
 drivers/gpu/drm/radeon/radeon_device.c  |  4 +-
 drivers/gpu/drm/radeon/radeon_kms.c |  2 +-
 drivers/pci/hotplug/pciehp_hpc.c|  6 +-
 drivers/pci/pci-acpi.c  | 15 -
 drivers/pci/pci.c   | 17 +++--
 drivers/pci/probe.c | 52 ++-
 drivers/pci/quirks.c| 84 +
 drivers/platform/x86/apple-gmux.c   |  2 +-
 drivers/thunderbolt/nhi.h   |  2 -
 include/linux/pci.h | 25 +---
 include/linux/pci_ids.h |  3 +
 14 files changed, 173 insertions(+), 47 deletions(-)

-- 
2.34.1



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

2022-02-14 Thread Bjorn Andersson
On Mon 14 Feb 09:59 PST 2022, Imre Deak wrote:

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

That makes sense, thanks for point it out!

Regards,
Bjorn


Re: [Freedreno] [PATCH v5 6/6] drm/msm/dpu: move VBIF blocks handling to dpu_rm

2022-02-14 Thread Abhinav Kumar




On 2/14/2022 2:39 PM, Dmitry Baryshkov wrote:

On 15/02/2022 01:04, Abhinav Kumar wrote:



On 2/14/2022 12:56 PM, Dmitry Baryshkov wrote:

On 14/02/2022 22:53, Abhinav Kumar wrote:



On 1/21/2022 1:06 PM, Dmitry Baryshkov wrote:

Move handling of VBIF blocks into dpu_rm. This serves the purpose of
unification of handling of all hardware blocks inside the DPU driver.
This removes hand-coded loops in dpu_vbif (which look for necessary 
VBIF

instance by looping through the dpu_kms->hw_vbif and comparing
vbif_idx).

Signed-off-by: Dmitry Baryshkov 


I have a slightly different idea about this. Let me know what you 
think.


VBIF is a bus interface for the dpu to fetch from. I am not sure if 
pulling it in the RM is right because its not a dedicated HW block like

the others in the RM.


It's not a hardware block, but a it's still a hardware resource 
(hardware instance). It is described in the hw catalog. Thus I 
suggested moving it to dpu_rm.


As you have seen, from my previous iterations of this patchset, I 
tried   to move things out of dpu_rm. After some hacking, I saw that 
having alloc/free loops in several places seems like a worse idea. So 
I moved dpu_hw_intf back to dpu_rm and then moved dpu_hw_vbif to 
dpu_rm too.



Actually for some reason, I only see two revs here:

https://patchwork.freedesktop.org/series/99175/#rev1


Yeah, I'm not sure why patchwork created new series rather than new 
revision.




Hence, I didnt check the previous patchsets from patchwork to see the 
evolution.




https://patchwork.freedesktop.org/patch/464353/




But, I agree with your problem statement of hand-coded loops.

So instead, why dont you just have a helper in the dpu_vbif.c to get
you the vbif hw for the passed index like, maybe something like this?

--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
@@ -11,6 +11,19 @@
  #include "dpu_hw_vbif.h"
  #include "dpu_trace.h"

+static dpu_hw_vbif *dpu_vbif_get_hw(struct dpu_kms *dpu_kms, u32 
vbif_idx)

+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
+   if (dpu_kms->hw_vbif[i] &&
+   dpu_kms->hw_vbif[i]->idx == vbif_idx)
+   vbif = dpu_kms->hw_vbif[i];
+   }
+
+   return vbif;
+}
+


You see, this code still bears an idea of looping through hw_vbif 
entries looking for the correct one (we can directly access 
hw_vbif[idx - VBIF_0] instead).


And also the alloc/destroy loops are very similar to rm ones, but are 
working against the array in dpu_kms.


One of the previous iterations had neearly the same idea as yours 
patch proposes, but I later abandoned this idea.


I'm trying to place common code nearby, so that there is a less 
chance of an error.


This loop is being used to find the vbif matching the index only in 
two places today dpu_vbif_set_ot_limit and dpu_vbif_set_qos_remap.


Here I was talking about the loops to allocate and destroy VBIFs.



Today and from whatever I see even in downstream (which has support 
for more newer chipsets), there is only one VBIF

instance in the catalog and always with the index 0.


When should we use VBIF_NRT? Judging from the _NRT suffix I thought that 
it's used for WB2, but it doesn't seem to be true.


So to be honest, even that loop is an overkill today because the index 
seems to be always 0 and there is only one instance so the loop seems 
to break out at the first occurrence.


It's always better to remove a loop rather than to break from it.



Thats why I was wondering whether moving VBIF to RM is an overkill for 
this and just the simple cleanup i was suggesting was enough as that 
loop itself is an overkill today for one instance of vbif.


Then we might as well drop an array and just leave a single vbif_0.

Just checked downstream device trees. 8996 declares two VBIFs. It looks 
like it's the only user of VBIF_1. Any comments? What would we loose for 
(possible) 8996 support in DPU if we drop VBIF_1 / VBIF_NRT support?


Yes it seems like 8996 writeback is the only client to use VBIF_NRT. I 
am unable to locate the old codebase to check its usage.


Here since we are talking about eventually using DPU for 8996, even if 
we consider VBIF_NRT into the mix, its only 2.


So I feel we can get rid of the loop and instead just come up with a 
simple if else?


So something like:

if (VBIF_RT)
vbif = dpu_kms[VBIF_RT].vbif;
else
vbif = dpu_kms[VBIF_NRT].vbif

I am not foreseeing more vbif clients so far.

We can revisit this in the future if it goes beyond 2.








  /**
   * _dpu_vbif_wait_for_xin_halt - wait for the xin to halt
   * @vbif:  Pointer to hardware vbif driver
@@ -156,11 +169,7 @@ void dpu_vbif_set_ot_limit(struct dpu_kms 
*dpu_kms,


 mdp = dpu_kms->hw_mdp;

-   for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
-   if (dpu_kms->hw_vbif[i] &&
-   dpu_kms->hw_vbif[i]->idx == 

Re: [Freedreno] [PATCH v5 6/6] drm/msm/dpu: move VBIF blocks handling to dpu_rm

2022-02-14 Thread Dmitry Baryshkov

On 15/02/2022 01:04, Abhinav Kumar wrote:



On 2/14/2022 12:56 PM, Dmitry Baryshkov wrote:

On 14/02/2022 22:53, Abhinav Kumar wrote:



On 1/21/2022 1:06 PM, Dmitry Baryshkov wrote:

Move handling of VBIF blocks into dpu_rm. This serves the purpose of
unification of handling of all hardware blocks inside the DPU driver.
This removes hand-coded loops in dpu_vbif (which look for necessary 
VBIF

instance by looping through the dpu_kms->hw_vbif and comparing
vbif_idx).

Signed-off-by: Dmitry Baryshkov 


I have a slightly different idea about this. Let me know what you think.

VBIF is a bus interface for the dpu to fetch from. I am not sure if 
pulling it in the RM is right because its not a dedicated HW block like

the others in the RM.


It's not a hardware block, but a it's still a hardware resource 
(hardware instance). It is described in the hw catalog. Thus I 
suggested moving it to dpu_rm.


As you have seen, from my previous iterations of this patchset, I 
tried   to move things out of dpu_rm. After some hacking, I saw that 
having alloc/free loops in several places seems like a worse idea. So 
I moved dpu_hw_intf back to dpu_rm and then moved dpu_hw_vbif to 
dpu_rm too.



Actually for some reason, I only see two revs here:

https://patchwork.freedesktop.org/series/99175/#rev1


Yeah, I'm not sure why patchwork created new series rather than new 
revision.




Hence, I didnt check the previous patchsets from patchwork to see the 
evolution.




https://patchwork.freedesktop.org/patch/464353/




But, I agree with your problem statement of hand-coded loops.

So instead, why dont you just have a helper in the dpu_vbif.c to get
you the vbif hw for the passed index like, maybe something like this?

--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
@@ -11,6 +11,19 @@
  #include "dpu_hw_vbif.h"
  #include "dpu_trace.h"

+static dpu_hw_vbif *dpu_vbif_get_hw(struct dpu_kms *dpu_kms, u32 
vbif_idx)

+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
+   if (dpu_kms->hw_vbif[i] &&
+   dpu_kms->hw_vbif[i]->idx == vbif_idx)
+   vbif = dpu_kms->hw_vbif[i];
+   }
+
+   return vbif;
+}
+


You see, this code still bears an idea of looping through hw_vbif 
entries looking for the correct one (we can directly access 
hw_vbif[idx - VBIF_0] instead).


And also the alloc/destroy loops are very similar to rm ones, but are 
working against the array in dpu_kms.


One of the previous iterations had neearly the same idea as yours 
patch proposes, but I later abandoned this idea.


I'm trying to place common code nearby, so that there is a less chance 
of an error.


This loop is being used to find the vbif matching the index only in two 
places today dpu_vbif_set_ot_limit and dpu_vbif_set_qos_remap.


Here I was talking about the loops to allocate and destroy VBIFs.



Today and from whatever I see even in downstream (which has support for 
more newer chipsets), there is only one VBIF

instance in the catalog and always with the index 0.


When should we use VBIF_NRT? Judging from the _NRT suffix I thought that 
it's used for WB2, but it doesn't seem to be true.


So to be honest, even that loop is an overkill today because the index 
seems to be always 0 and there is only one instance so the loop seems to 
break out at the first occurrence.


It's always better to remove a loop rather than to break from it.



Thats why I was wondering whether moving VBIF to RM is an overkill for 
this and just the simple cleanup i was suggesting was enough as that 
loop itself is an overkill today for one instance of vbif.


Then we might as well drop an array and just leave a single vbif_0.

Just checked downstream device trees. 8996 declares two VBIFs. It looks 
like it's the only user of VBIF_1. Any comments? What would we loose for 
(possible) 8996 support in DPU if we drop VBIF_1 / VBIF_NRT support?







  /**
   * _dpu_vbif_wait_for_xin_halt - wait for the xin to halt
   * @vbif:  Pointer to hardware vbif driver
@@ -156,11 +169,7 @@ void dpu_vbif_set_ot_limit(struct dpu_kms *dpu_kms,

 mdp = dpu_kms->hw_mdp;

-   for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
-   if (dpu_kms->hw_vbif[i] &&
-   dpu_kms->hw_vbif[i]->idx == 
params->vbif_idx)

-   vbif = dpu_kms->hw_vbif[i];
-   }
+   vbif = dpu_vbif_get_hw(dpu_kms, params->vbif_idx);

 if (!vbif || !mdp) {
 DRM_DEBUG_ATOMIC("invalid arguments vbif %d mdp %d\n",
@@ -216,13 +225,7 @@ void dpu_vbif_set_qos_remap(struct dpu_kms 
*dpu_kms,

 }
 mdp = dpu_kms->hw_mdp;

-   for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
-   if (dpu_kms->hw_vbif[i] &&
-   dpu_kms->hw_vbif[i]->idx == 
params->vbif_idx) {

-   vbif = dpu_kms->hw_vbif[i];
-  

[PATCH v4 2/2] drm/msm/dp: enable widebus feature for display port

2022-02-14 Thread Kuogee Hsieh
Widebus feature will transmit two pixel data per pixel clock to interface.
This feature now is required to be enabled to easy migrant to higher
resolution applications in future. However since some legacy chipsets
does not support this feature, this feature is enabled base on chip's
hardware revision.

changes in v2:
-- remove compression related code from timing
-- remove op_info from  struct msm_drm_private
-- remove unnecessary wide_bus_en variables
-- pass wide_bus_en into timing configuration by struct msm_dp

Changes in v3:
-- split patch into 3 patches
-- enable widebus feature base on chip hardware revision

Signed-off-by: Kuogee Hsieh 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c |  4 +++-
 drivers/gpu/drm/msm/dp/dp_catalog.c | 36 +++--
 drivers/gpu/drm/msm/dp/dp_catalog.h |  3 ++-
 drivers/gpu/drm/msm/dp/dp_ctrl.c| 13 +++
 drivers/gpu/drm/msm/dp/dp_ctrl.h|  1 +
 drivers/gpu/drm/msm/dp/dp_display.c | 30 
 drivers/gpu/drm/msm/dp/dp_display.h |  2 ++
 drivers/gpu/drm/msm/dp/dp_panel.c   |  4 ++--
 drivers/gpu/drm/msm/dp/dp_panel.h   |  2 +-
 drivers/gpu/drm/msm/msm_drv.h   |  6 +
 10 files changed, 90 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 0c22839..b2d23c2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -2167,8 +2167,10 @@ int dpu_encoder_setup(struct drm_device *dev, struct 
drm_encoder *enc,
timer_setup(_enc->vsync_event_timer,
dpu_encoder_vsync_event_handler,
0);
-   else if (disp_info->intf_type == DRM_MODE_ENCODER_TMDS)
+   else if (disp_info->intf_type == DRM_MODE_ENCODER_TMDS) {
dpu_enc->dp = priv->dp[disp_info->h_tile_instance[0]];
+   dpu_enc->wide_bus_en = msm_dp_wide_bus_enable(dpu_enc->dp);
+   }
 
INIT_DELAYED_WORK(_enc->delayed_off_work,
dpu_encoder_off_work);
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c 
b/drivers/gpu/drm/msm/dp/dp_catalog.c
index 64f0b26..99d087e 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
@@ -483,6 +483,27 @@ int dp_catalog_ctrl_set_pattern_state_bit(struct 
dp_catalog *dp_catalog,
 }
 
 /**
+ * dp_catalog_hw_revision() - retrieve DP hw revision
+ *
+ * @dp_catalog: DP catalog structure
+ *
+ * return: u32
+ *
+ * This function return the DP controller hw revision
+ *
+ */
+u32 dp_catalog_hw_revision(struct dp_catalog *dp_catalog)
+{
+   u32 revision;
+   struct dp_catalog_private *catalog = container_of(dp_catalog,
+   struct dp_catalog_private, dp_catalog);
+
+   revision = dp_read_ahb(catalog, REG_DP_HW_VERSION);
+
+   return revision;
+}
+
+/**
  * dp_catalog_ctrl_reset() - reset DP controller
  *
  * @dp_catalog: DP catalog structure
@@ -739,10 +760,11 @@ u32 dp_catalog_ctrl_read_phy_pattern(struct dp_catalog 
*dp_catalog)
 }
 
 /* panel related catalog functions */
-int dp_catalog_panel_timing_cfg(struct dp_catalog *dp_catalog)
+int dp_catalog_panel_timing_cfg(struct dp_catalog *dp_catalog, bool 
wide_bus_en)
 {
struct dp_catalog_private *catalog = container_of(dp_catalog,
struct dp_catalog_private, dp_catalog);
+   u32 reg;
 
dp_write_link(catalog, REG_DP_TOTAL_HOR_VER,
dp_catalog->total);
@@ -751,7 +773,17 @@ int dp_catalog_panel_timing_cfg(struct dp_catalog 
*dp_catalog)
dp_write_link(catalog, REG_DP_HSYNC_VSYNC_WIDTH_POLARITY,
dp_catalog->width_blanking);
dp_write_link(catalog, REG_DP_ACTIVE_HOR_VER, dp_catalog->dp_active);
-   dp_write_p0(catalog, MMSS_DP_INTF_CONFIG, 0);
+
+   reg = dp_read_p0(catalog, MMSS_DP_INTF_CONFIG);
+
+   if (wide_bus_en)
+   reg |= BIT(4);  /* DATABUS_WIDEN */
+   else
+   reg &= ~BIT(4);
+
+   DRM_DEBUG_DP("wide_bus_en=%d reg=%x\n", wide_bus_en, reg);
+
+   dp_write_p0(catalog, MMSS_DP_INTF_CONFIG, reg);
return 0;
 }
 
diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h 
b/drivers/gpu/drm/msm/dp/dp_catalog.h
index 7dea101..a3a0129 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.h
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.h
@@ -95,6 +95,7 @@ void dp_catalog_ctrl_config_misc(struct dp_catalog 
*dp_catalog, u32 cc, u32 tb);
 void dp_catalog_ctrl_config_msa(struct dp_catalog *dp_catalog, u32 rate,
u32 stream_rate_khz, bool fixed_nvid);
 int dp_catalog_ctrl_set_pattern_state_bit(struct dp_catalog *dp_catalog, u32 
pattern);
+u32 dp_catalog_hw_revision(struct dp_catalog *dp_catalog);
 void dp_catalog_ctrl_reset(struct dp_catalog *dp_catalog);
 bool 

[PATCH v4 1/2] drm/msm/dp: revise timing engine programming to support widebus feature

2022-02-14 Thread Kuogee Hsieh
Widebus feature will transmit two pixel data per pixel clock to interface.
Timing engine provides driving force for this purpose. This patch base
on HPG (Hardware Programming Guide) to revise timing engine register
setting to accommodate both widebus and non widebus application. Also
horizontal width parameters need to be reduced by half since two pixel
data are clocked out per pixel clock when widebus feature enabled.

Widebus can be enabled individually at DP. However at DSI, widebus have
to be enabled along with DSC enabled to achieve pixel clock rate be
scaled down with same ratio as compression ratio when 10 bits per source
component. Therefore this patch have both widebus and compression covered
together so tat less efforts will be required when DSC enabled later.

Changes in v2:
-- remove compression related code from timing
-- remove op_info from  struct msm_drm_private
-- remove unnecessary wide_bus_en variables
-- pass wide_bus_en into timing configuration by struct msm_dp

Changes in v3:
-- split patch into 3 patches

Changes in v4:
-- rework timing engine to not interfere with dsi/hdmi
-- cover both widebus and compression

Signed-off-by: Kuogee Hsieh 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c| 10 +++
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h|  2 +
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c   | 14 +++
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c| 99 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h|  6 ++
 5 files changed, 115 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 0d315b4..0c22839 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -208,6 +208,8 @@ struct dpu_encoder_virt {
 
u32 idle_timeout;
 
+   bool wide_bus_en;
+
struct msm_dp *dp;
 };
 
@@ -217,6 +219,14 @@ static u32 dither_matrix[DITHER_MATRIX_SZ] = {
15, 7, 13, 5, 3, 11, 1, 9, 12, 4, 14, 6, 0, 8, 2, 10
 };
 
+
+bool dpu_encoder_is_widebus_enabled(struct drm_encoder *drm_enc)
+{
+   struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
+
+   return dpu_enc->wide_bus_en;
+}
+
 static void _dpu_encoder_setup_dither(struct dpu_hw_pingpong *hw_pp, unsigned 
bpc)
 {
struct dpu_hw_dither_cfg dither_cfg = { 0 };
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
index 99a5d73..893d74d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
@@ -168,4 +168,6 @@ int dpu_encoder_get_linecount(struct drm_encoder *drm_enc);
  */
 int dpu_encoder_get_frame_count(struct drm_encoder *drm_enc);
 
+bool dpu_encoder_is_widebus_enabled(struct drm_encoder *drm_enc);
+
 #endif /* __DPU_ENCODER_H__ */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
index 185379b..2af2bb7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
@@ -110,6 +110,20 @@ static void drm_mode_to_intf_timing_params(
timing->v_back_porch += timing->v_front_porch;
timing->v_front_porch = 0;
}
+
+   timing->wide_bus_en = dpu_encoder_is_widebus_enabled(phys_enc->parent);
+
+   /*
+* for DP, divide the horizonal parameters by 2 when
+* widebus is enabled
+*/
+   if (phys_enc->hw_intf->cap->type == INTF_DP && timing->wide_bus_en) {
+   timing->width = timing->width >> 1;
+   timing->xres = timing->xres >> 1;
+   timing->h_back_porch = timing->h_back_porch >> 1;
+   timing->h_front_porch = timing->h_front_porch >> 1;
+   timing->hsync_pulse_width = timing->hsync_pulse_width >> 1;
+   }
 }
 
 static u32 get_horizontal_total(const struct intf_timing_params *timing)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
index 116e2b5..3b9273e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
@@ -33,6 +33,7 @@
 #define INTF_TP_COLOR1  0x05C
 #define INTF_CONFIG20x060
 #define INTF_DISPLAY_DATA_HCTL  0x064
+#define INTF_ACTIVE_DATA_HCTL   0x068
 #define INTF_FRAME_LINE_COUNT_EN0x0A8
 #define INTF_FRAME_COUNT0x0AC
 #define   INTF_LINE_COUNT   0x0B0
@@ -60,6 +61,14 @@
 
 #define   INTF_MUX  0x25C
 
+#define BIT_INTF_CFG_ACTIVE_H_EN   BIT(29)
+#define BIT_INTF_CFG_ACTIVE_V_EN   BIT(30)
+
+#define BIT_INTF_CFG2_DATABUS_WIDENBIT(0)
+#define BIT_INTF_CFG2_DATA_HCTL_EN BIT(4)
+#define BIT_INTF_CFG2_DCE_DATA_COMPRESSBIT(12)
+
+
 static const struct dpu_intf_cfg *_intf_offset(enum dpu_intf intf,

[PATCH v4 0/2] enable widebus feature base on chip hardware revision

2022-02-14 Thread Kuogee Hsieh
split into 2 patches
1) widebus timing engine programming
2) enable widebus feature base on chip hardware revision

Kuogee Hsieh (2):
  drm/msm/dp:  revise timing engine programming to support widebus
feature
  drm/msm/dp: enable widebus feature for display port

 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c| 14 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h|  2 +
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c   | 14 +++
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c| 99 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h|  6 ++
 drivers/gpu/drm/msm/dp/dp_catalog.c| 36 +++-
 drivers/gpu/drm/msm/dp/dp_catalog.h|  3 +-
 drivers/gpu/drm/msm/dp/dp_ctrl.c   | 13 ++-
 drivers/gpu/drm/msm/dp/dp_ctrl.h   |  1 +
 drivers/gpu/drm/msm/dp/dp_display.c| 30 +++
 drivers/gpu/drm/msm/dp/dp_display.h|  2 +
 drivers/gpu/drm/msm/dp/dp_panel.c  |  4 +-
 drivers/gpu/drm/msm/dp/dp_panel.h  |  2 +-
 drivers/gpu/drm/msm/msm_drv.h  |  6 ++
 14 files changed, 205 insertions(+), 27 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [Freedreno] [PATCH v5 6/6] drm/msm/dpu: move VBIF blocks handling to dpu_rm

2022-02-14 Thread Abhinav Kumar




On 2/14/2022 12:56 PM, Dmitry Baryshkov wrote:

On 14/02/2022 22:53, Abhinav Kumar wrote:



On 1/21/2022 1:06 PM, Dmitry Baryshkov wrote:

Move handling of VBIF blocks into dpu_rm. This serves the purpose of
unification of handling of all hardware blocks inside the DPU driver.
This removes hand-coded loops in dpu_vbif (which look for necessary VBIF
instance by looping through the dpu_kms->hw_vbif and comparing
vbif_idx).

Signed-off-by: Dmitry Baryshkov 


I have a slightly different idea about this. Let me know what you think.

VBIF is a bus interface for the dpu to fetch from. I am not sure if 
pulling it in the RM is right because its not a dedicated HW block like

the others in the RM.


It's not a hardware block, but a it's still a hardware resource 
(hardware instance). It is described in the hw catalog. Thus I suggested 
moving it to dpu_rm.


As you have seen, from my previous iterations of this patchset, I tried 
  to move things out of dpu_rm. After some hacking, I saw that having 
alloc/free loops in several places seems like a worse idea. So I moved 
dpu_hw_intf back to dpu_rm and then moved dpu_hw_vbif to dpu_rm too.



Actually for some reason, I only see two revs here:

https://patchwork.freedesktop.org/series/99175/#rev1

Hence, I didnt check the previous patchsets from patchwork to see the 
evolution.




But, I agree with your problem statement of hand-coded loops.

So instead, why dont you just have a helper in the dpu_vbif.c to get
you the vbif hw for the passed index like, maybe something like this?

--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
@@ -11,6 +11,19 @@
  #include "dpu_hw_vbif.h"
  #include "dpu_trace.h"

+static dpu_hw_vbif *dpu_vbif_get_hw(struct dpu_kms *dpu_kms, u32 
vbif_idx)

+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
+   if (dpu_kms->hw_vbif[i] &&
+   dpu_kms->hw_vbif[i]->idx == vbif_idx)
+   vbif = dpu_kms->hw_vbif[i];
+   }
+
+   return vbif;
+}
+


You see, this code still bears an idea of looping through hw_vbif 
entries looking for the correct one (we can directly access hw_vbif[idx 
- VBIF_0] instead).


And also the alloc/destroy loops are very similar to rm ones, but are 
working against the array in dpu_kms.


One of the previous iterations had neearly the same idea as yours patch 
proposes, but I later abandoned this idea.


I'm trying to place common code nearby, so that there is a less chance 
of an error.


This loop is being used to find the vbif matching the index only in two 
places today dpu_vbif_set_ot_limit and dpu_vbif_set_qos_remap.


Today and from whatever I see even in downstream (which has support for 
more newer chipsets), there is only one VBIF

instance in the catalog and always with the index 0.

So to be honest, even that loop is an overkill today because the index 
seems to be always 0 and there is only one instance so the loop seems to 
break out at the first occurrence.


Thats why I was wondering whether moving VBIF to RM is an overkill for 
this and just the simple cleanup i was suggesting was enough as that 
loop itself is an overkill today for one instance of vbif.





  /**
   * _dpu_vbif_wait_for_xin_halt - wait for the xin to halt
   * @vbif:  Pointer to hardware vbif driver
@@ -156,11 +169,7 @@ void dpu_vbif_set_ot_limit(struct dpu_kms *dpu_kms,

 mdp = dpu_kms->hw_mdp;

-   for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
-   if (dpu_kms->hw_vbif[i] &&
-   dpu_kms->hw_vbif[i]->idx == 
params->vbif_idx)

-   vbif = dpu_kms->hw_vbif[i];
-   }
+   vbif = dpu_vbif_get_hw(dpu_kms, params->vbif_idx);

 if (!vbif || !mdp) {
 DRM_DEBUG_ATOMIC("invalid arguments vbif %d mdp %d\n",
@@ -216,13 +225,7 @@ void dpu_vbif_set_qos_remap(struct dpu_kms *dpu_kms,
 }
 mdp = dpu_kms->hw_mdp;

-   for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
-   if (dpu_kms->hw_vbif[i] &&
-   dpu_kms->hw_vbif[i]->idx == 
params->vbif_idx) {

-   vbif = dpu_kms->hw_vbif[i];
-   break;
-   }
-   }
+   vbif = dpu_vbif_get_hw(params->vbif_idx);




---
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h |  1 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 28 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h |  1 -
  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c  | 19 ++
  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h  | 12 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c    | 26 ++-
  6 files changed, 40 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h

index 6417aa28d32c..895e86dabcb6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h
+++ 

Re: [PATCH v2] drm/msm: populate intf_audio_select() base on hardware capability

2022-02-14 Thread Dmitry Baryshkov

On 15/02/2022 00:46, Kuogee Hsieh wrote:

intf_audio_select() callback function use to configure
HDMI_DP_CORE_SELECT to decide audio output routes to HDMI or DP
interface. HDMI is obsoleted at newer chipset. To keep supporting
legacy hdmi application, intf_audio_select call back function have
to be populated base on hardware chip capability where legacy
chipsets have has_audio_select flag set to true.

Changes in V2:
-- remove has_audio_select flag
-- add BIT(DPU_MDP_AUDIO_SELECT) into dpu_mdp_cfg

Signed-off-by: Kuogee Hsieh 



Reviewed-by: Dmitry Baryshkov 


---
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 2 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 1 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c | 4 +++-
  3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index 272b14b..9c2df26 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -265,7 +265,7 @@ static const struct dpu_mdp_cfg sdm845_mdp[] = {
{
.name = "top_0", .id = MDP_TOP,
.base = 0x0, .len = 0x45C,
-   .features = 0,
+   .features = BIT(DPU_MDP_AUDIO_SELECT),
.highest_bank_bit = 0x2,
.clk_ctrls[DPU_CLK_CTRL_VIG0] = {
.reg_off = 0x2AC, .bit_off = 0},
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
index e5a96d6..fb7b5b5 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -87,6 +87,7 @@ enum {
DPU_MDP_BWC,
DPU_MDP_UBWC_1_0,
DPU_MDP_UBWC_1_5,
+   DPU_MDP_AUDIO_SELECT,
DPU_MDP_MAX
  };
  
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c

index 282e3c6..ab3ef16 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
@@ -268,7 +268,9 @@ static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops,
ops->get_danger_status = dpu_hw_get_danger_status;
ops->setup_vsync_source = dpu_hw_setup_vsync_source;
ops->get_safe_status = dpu_hw_get_safe_status;
-   ops->intf_audio_select = dpu_hw_intf_audio_select;
+
+   if (cap & BIT(DPU_MDP_AUDIO_SELECT))
+   ops->intf_audio_select = dpu_hw_intf_audio_select;
  }
  
  static const struct dpu_mdp_cfg *_top_offset(enum dpu_mdp mdp,



--
With best wishes
Dmitry


Re: Regression from 3c196f056666 ("drm/amdgpu: always reset the asic in suspend (v2)") on suspend?

2022-02-14 Thread Alex Deucher
On Sat, Feb 12, 2022 at 1:23 PM Salvatore Bonaccorso  wrote:
>
> Hi Alex, hi all
>
> In Debian we got a regression report from Dominique Dumont, CC'ed in
> https://bugs.debian.org/1005005 that afer an update to 5.15.15 based
> kernel, his machine noe longer suspends correctly, after screen going
> black as usual it comes back. The Debian bug above contians a trace.
>
> Dominique confirmed that this issue persisted after updating to 5.16.7
> furthermore he bisected the issue and found
>
> 3c196f0510912645c7c5d9107706003f67c3 is the first bad commit
> commit 3c196f0510912645c7c5d9107706003f67c3
> Author: Alex Deucher 
> Date:   Fri Nov 12 11:25:30 2021 -0500
>
> drm/amdgpu: always reset the asic in suspend (v2)
>
> [ Upstream commit daf8de0874ab5b74b38a38726fdd3d07ef98a7ee ]
>
> If the platform suspend happens to fail and the power rail
> is not turned off, the GPU will be in an unknown state on
> resume, so reset the asic so that it will be in a known
> good state on resume even if the platform suspend failed.
>
> v2: handle s0ix
>
> Acked-by: Luben Tuikov 
> Acked-by: Evan Quan 
> Signed-off-by: Alex Deucher 
> Signed-off-by: Sasha Levin 
>
>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 5 -
>  1 file changed, 4 insertions(+), 1 deletion(-)
>
> to be the first bad commit, see https://bugs.debian.org/1005005#34 .
>
> Does this ring any bell? Any idea on the problem?

Does the system actually suspend?  Putting the GPU into reset on
suspend shouldn't cause any problems since the power rail will
presumably be cut by the platform.  Is this system S0i3 or regular S3?
 Does this patch help by any chance?
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e55a3aea418269266d84f426b3bd70794d3389c8

Alex


>
> Regards,
> Salvatore


[PATCH v2] drm/msm: populate intf_audio_select() base on hardware capability

2022-02-14 Thread Kuogee Hsieh
intf_audio_select() callback function use to configure
HDMI_DP_CORE_SELECT to decide audio output routes to HDMI or DP
interface. HDMI is obsoleted at newer chipset. To keep supporting
legacy hdmi application, intf_audio_select call back function have
to be populated base on hardware chip capability where legacy
chipsets have has_audio_select flag set to true.

Changes in V2:
-- remove has_audio_select flag
-- add BIT(DPU_MDP_AUDIO_SELECT) into dpu_mdp_cfg

Signed-off-by: Kuogee Hsieh 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c | 4 +++-
 3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index 272b14b..9c2df26 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -265,7 +265,7 @@ static const struct dpu_mdp_cfg sdm845_mdp[] = {
{
.name = "top_0", .id = MDP_TOP,
.base = 0x0, .len = 0x45C,
-   .features = 0,
+   .features = BIT(DPU_MDP_AUDIO_SELECT),
.highest_bank_bit = 0x2,
.clk_ctrls[DPU_CLK_CTRL_VIG0] = {
.reg_off = 0x2AC, .bit_off = 0},
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
index e5a96d6..fb7b5b5 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -87,6 +87,7 @@ enum {
DPU_MDP_BWC,
DPU_MDP_UBWC_1_0,
DPU_MDP_UBWC_1_5,
+   DPU_MDP_AUDIO_SELECT,
DPU_MDP_MAX
 };
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
index 282e3c6..ab3ef16 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
@@ -268,7 +268,9 @@ static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops,
ops->get_danger_status = dpu_hw_get_danger_status;
ops->setup_vsync_source = dpu_hw_setup_vsync_source;
ops->get_safe_status = dpu_hw_get_safe_status;
-   ops->intf_audio_select = dpu_hw_intf_audio_select;
+
+   if (cap & BIT(DPU_MDP_AUDIO_SELECT))
+   ops->intf_audio_select = dpu_hw_intf_audio_select;
 }
 
 static const struct dpu_mdp_cfg *_top_offset(enum dpu_mdp mdp,
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project



Re: [PATCH v5 5/6] drm/msm/dpu: fix error handling in dpu_rm_init

2022-02-14 Thread Abhinav Kumar




On 2/14/2022 12:43 PM, Dmitry Baryshkov wrote:

On 14/02/2022 22:15, Abhinav Kumar wrote:



On 1/21/2022 1:06 PM, Dmitry Baryshkov wrote:

Using IS_ERR_OR_NULL() together with PTR_ERR() is a typical mistake. If
the value is NULL, then the function will return 0 instead of a proper
return code. Moreover none of dpu_hw_*_init() functions can return NULL.
So, replace all dpu_rm_init()'s IS_ERR_OR_NULL() calls with IS_ERR().

Can you please give an example of a case where dpu_hw_*_init() can 
return NULL?


All dpu_hw_*_init() functions are only called if the corresponding
hw*_counts are valid. So I would like to understand this.

Now, if NULL is treated as a non-error case, should we atleast print
a message indicating so?


- No dpu_hw_*init() can return NULL

- If at some point any of these functions returns NULL, it will cause a 
premature dpu_rm_init() termination with the success (=0) status, 
leaving parts of RM uninitialized.


Thus I'm replacing IS_ERR_OR_NULL with IS_ERR()


Ah okay, got it.

Reviewed-by: Abhinav Kumar 





Signed-off-by: Dmitry Baryshkov 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 12 ++--
  1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c

index 96554e962e38..7497538adae1 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -109,7 +109,7 @@ int dpu_rm_init(struct dpu_rm *rm,
  continue;
  }
  hw = dpu_hw_lm_init(lm->id, mmio, cat);
-    if (IS_ERR_OR_NULL(hw)) {
+    if (IS_ERR(hw)) {
  rc = PTR_ERR(hw);
  DPU_ERROR("failed lm object creation: err %d\n", rc);
  goto fail;
@@ -126,7 +126,7 @@ int dpu_rm_init(struct dpu_rm *rm,
  continue;
  }
  hw = dpu_hw_merge_3d_init(merge_3d->id, mmio, cat);
-    if (IS_ERR_OR_NULL(hw)) {
+    if (IS_ERR(hw)) {
  rc = PTR_ERR(hw);
  DPU_ERROR("failed merge_3d object creation: err %d\n",
  rc);
@@ -144,7 +144,7 @@ int dpu_rm_init(struct dpu_rm *rm,
  continue;
  }
  hw = dpu_hw_pingpong_init(pp->id, mmio, cat);
-    if (IS_ERR_OR_NULL(hw)) {
+    if (IS_ERR(hw)) {
  rc = PTR_ERR(hw);
  DPU_ERROR("failed pingpong object creation: err %d\n",
  rc);
@@ -168,7 +168,7 @@ int dpu_rm_init(struct dpu_rm *rm,
  continue;
  }
  hw = dpu_hw_intf_init(intf->id, mmio, cat);
-    if (IS_ERR_OR_NULL(hw)) {
+    if (IS_ERR(hw)) {
  rc = PTR_ERR(hw);
  DPU_ERROR("failed intf object creation: err %d\n", rc);
  goto fail;
@@ -185,7 +185,7 @@ int dpu_rm_init(struct dpu_rm *rm,
  continue;
  }
  hw = dpu_hw_ctl_init(ctl->id, mmio, cat);
-    if (IS_ERR_OR_NULL(hw)) {
+    if (IS_ERR(hw)) {
  rc = PTR_ERR(hw);
  DPU_ERROR("failed ctl object creation: err %d\n", rc);
  goto fail;
@@ -202,7 +202,7 @@ int dpu_rm_init(struct dpu_rm *rm,
  continue;
  }
  hw = dpu_hw_dspp_init(dspp->id, mmio, cat);
-    if (IS_ERR_OR_NULL(hw)) {
+    if (IS_ERR(hw)) {
  rc = PTR_ERR(hw);
  DPU_ERROR("failed dspp object creation: err %d\n", rc);
  goto fail;





Re: [PATCH] drm/msm: populate intf_audio_select() base on hardware capability

2022-02-14 Thread Dmitry Baryshkov

On 14/02/2022 20:55, Kuogee Hsieh wrote:


On 2/11/2022 3:36 PM, Dmitry Baryshkov wrote:

On Sat, 12 Feb 2022 at 02:23, Kuogee Hsieh  wrote:

intf_audio_select() callback function use to configure
HDMI_DP_CORE_SELECT to decide audio output routes to HDMI or DP
interface. HDMI is obsoleted at newer chipset. To keep supporting
legacy hdmi application, intf_audio_select call back function have
to be populated base on hardware chip capability where legacy
chipsets have has_audio_select flag set to true.

Signed-off-by: Kuogee Hsieh
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 2 ++
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 1 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c | 9 ++---
  3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index 272b14b..23680e7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -201,6 +201,7 @@ static const struct dpu_caps sdm845_dpu_caps = {
 .has_dim_layer = true,
 .has_idle_pc = true,
 .has_3d_merge = true,
+   .has_audio_select = true,
 .max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
 .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
 .max_hdeci_exp = MAX_HORZ_DECIMATION,
@@ -229,6 +230,7 @@ static const struct dpu_caps sm8150_dpu_caps = {
 .has_dim_layer = true,
 .has_idle_pc = true,
 .has_3d_merge = true,
+   .has_audio_select = true,
 .max_linewidth = 4096,
 .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
 .max_hdeci_exp = MAX_HORZ_DECIMATION,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
index e5a96d6..b33f91b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -357,6 +357,7 @@ struct dpu_caps {
 bool has_dim_layer;
 bool has_idle_pc;
 bool has_3d_merge;
+   bool has_audio_select;

I'd suggest adding a bit to dpu_mdp_cfg's features instead, following
the example of other hardware blocks.


it may cause mis leading if we put this in hardware level since 
MDP_HDMI_DP_SELECT  bit has not be connected


to logic for a while even it still present at ipcat. Also this bit but 
will be  removed at next release.


I'm sorry, I can't quite catch you. Why would you like to remove this 
bit at the next release?




Is dpu_caps level more proper than in hardware feature level?


A priciple of the least surprise. In other hardware-dependent virtual 
functions selection we use block's caps->features rather than boolean flags.






 /* SSPP limits */
 u32 max_linewidth;
 u32 pixel_ram_size;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
index 282e3c6..e608f4d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
@@ -261,14 +261,17 @@ static void dpu_hw_intf_audio_select(struct dpu_hw_mdp 
*mdp)
  }

  static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops,
-   unsigned long cap)
+   unsigned long cap,
+   const struct dpu_mdss_cfg *m)
  {
 ops->setup_split_pipe = dpu_hw_setup_split_pipe;
 ops->setup_clk_force_ctrl = dpu_hw_setup_clk_force_ctrl;
 ops->get_danger_status = dpu_hw_get_danger_status;
 ops->setup_vsync_source = dpu_hw_setup_vsync_source;
 ops->get_safe_status = dpu_hw_get_safe_status;
-   ops->intf_audio_select = dpu_hw_intf_audio_select;
+
+   if (m->caps->has_audio_select)
+   ops->intf_audio_select = dpu_hw_intf_audio_select;
  }

  static const struct dpu_mdp_cfg *_top_offset(enum dpu_mdp mdp,
@@ -320,7 +323,7 @@ struct dpu_hw_mdp *dpu_hw_mdptop_init(enum dpu_mdp idx,
  */
 mdp->idx = idx;
 mdp->caps = cfg;
-   _setup_mdp_ops(>ops, mdp->caps->features);
+   _setup_mdp_ops(>ops, mdp->caps->features, m);

 return mdp;
  }



--
With best wishes
Dmitry


Re: [PATCH v5 6/6] drm/msm/dpu: move VBIF blocks handling to dpu_rm

2022-02-14 Thread Dmitry Baryshkov

On 14/02/2022 22:53, Abhinav Kumar wrote:



On 1/21/2022 1:06 PM, Dmitry Baryshkov wrote:

Move handling of VBIF blocks into dpu_rm. This serves the purpose of
unification of handling of all hardware blocks inside the DPU driver.
This removes hand-coded loops in dpu_vbif (which look for necessary VBIF
instance by looping through the dpu_kms->hw_vbif and comparing
vbif_idx).

Signed-off-by: Dmitry Baryshkov 


I have a slightly different idea about this. Let me know what you think.
 
VBIF is a bus interface for the dpu to fetch from. I am not sure if 
pulling it in the RM is right because its not a dedicated HW block like

the others in the RM.


It's not a hardware block, but a it's still a hardware resource 
(hardware instance). It is described in the hw catalog. Thus I suggested 
moving it to dpu_rm.


As you have seen, from my previous iterations of this patchset, I tried 
 to move things out of dpu_rm. After some hacking, I saw that having 
alloc/free loops in several places seems like a worse idea. So I moved 
dpu_hw_intf back to dpu_rm and then moved dpu_hw_vbif to dpu_rm too.




But, I agree with your problem statement of hand-coded loops.

So instead, why dont you just have a helper in the dpu_vbif.c to get
you the vbif hw for the passed index like, maybe something like this?

--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
@@ -11,6 +11,19 @@
  #include "dpu_hw_vbif.h"
  #include "dpu_trace.h"

+static dpu_hw_vbif *dpu_vbif_get_hw(struct dpu_kms *dpu_kms, u32 vbif_idx)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
+   if (dpu_kms->hw_vbif[i] &&
+   dpu_kms->hw_vbif[i]->idx == vbif_idx)
+   vbif = dpu_kms->hw_vbif[i];
+   }
+
+   return vbif;
+}
+


You see, this code still bears an idea of looping through hw_vbif 
entries looking for the correct one (we can directly access hw_vbif[idx 
- VBIF_0] instead).


And also the alloc/destroy loops are very similar to rm ones, but are 
working against the array in dpu_kms.


One of the previous iterations had neearly the same idea as yours patch 
proposes, but I later abandoned this idea.


I'm trying to place common code nearby, so that there is a less chance 
of an error.



  /**
   * _dpu_vbif_wait_for_xin_halt - wait for the xin to halt
   * @vbif:  Pointer to hardware vbif driver
@@ -156,11 +169,7 @@ void dpu_vbif_set_ot_limit(struct dpu_kms *dpu_kms,

     mdp = dpu_kms->hw_mdp;

-   for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
-   if (dpu_kms->hw_vbif[i] &&
-   dpu_kms->hw_vbif[i]->idx == 
params->vbif_idx)

-   vbif = dpu_kms->hw_vbif[i];
-   }
+   vbif = dpu_vbif_get_hw(dpu_kms, params->vbif_idx);

     if (!vbif || !mdp) {
     DRM_DEBUG_ATOMIC("invalid arguments vbif %d mdp %d\n",
@@ -216,13 +225,7 @@ void dpu_vbif_set_qos_remap(struct dpu_kms *dpu_kms,
     }
     mdp = dpu_kms->hw_mdp;

-   for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
-   if (dpu_kms->hw_vbif[i] &&
-   dpu_kms->hw_vbif[i]->idx == 
params->vbif_idx) {

-   vbif = dpu_kms->hw_vbif[i];
-   break;
-   }
-   }
+   vbif = dpu_vbif_get_hw(params->vbif_idx);




---
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h |  1 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 28 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h |  1 -
  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c  | 19 ++
  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h  | 12 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c    | 26 ++-
  6 files changed, 40 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h

index 6417aa28d32c..895e86dabcb6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h
@@ -8,6 +8,7 @@
  #include "dpu_hw_catalog.h"
  #include "dpu_hw_mdss.h"
  #include "dpu_hw_util.h"
+#include "dpu_hw_blk.h"
  struct dpu_hw_vbif;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c

index 47fe11a84a77..4a1983d8561b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -782,8 +782,6 @@ static long dpu_kms_round_pixclk(struct msm_kms 
*kms, unsigned long rate,

  static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms)
  {
-    int i;
-
  if (dpu_kms->hw_intr)
  dpu_hw_intr_destroy(dpu_kms->hw_intr);
  dpu_kms->hw_intr = NULL;
@@ -791,15 +789,6 @@ static void _dpu_kms_hw_destroy(struct dpu_kms 
*dpu_kms)

  /* safe to call these more than once during shutdown */
  _dpu_kms_mmu_destroy(dpu_kms);
-    if (dpu_kms->catalog) {
-    for (i = 0; i < 

Re: [PATCH] drm/panfrost: Dynamically allocate pm_domains

2022-02-14 Thread Alyssa Rosenzweig
mali_kbase hardcodes MAX_PM_DOMAINS (=5 for the mt8192 kernel). I have
no real objection to it but Angelo did. Maybe should've marked this RFC.

On Mon, Feb 14, 2022 at 03:31:32PM -0500, Alyssa Rosenzweig wrote:
> MT8192 requires 5 power domains. Rather than bump MAX_PM_DOMAINS and
> waste memory on every supported Panfrost chip, instead dynamically
> allocate pm_domain_devs and pm_domain_links. This adds some flexibility;
> it seems inevitable a new MediaTek device will require more than 5
> domains.
> 
> On non-MediaTek devices, this saves a small amount of memory.
> 
> Suggested-by: AngeloGioacchino Del Regno 
> 
> Signed-off-by: Alyssa Rosenzweig 
> ---
>  drivers/gpu/drm/panfrost/panfrost_device.c | 14 ++
>  drivers/gpu/drm/panfrost/panfrost_device.h |  5 ++---
>  2 files changed, 12 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c 
> b/drivers/gpu/drm/panfrost/panfrost_device.c
> index ee612303f076..661cdec320af 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_device.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_device.c
> @@ -127,7 +127,10 @@ static void panfrost_pm_domain_fini(struct 
> panfrost_device *pfdev)
>  {
>   int i;
>  
> - for (i = 0; i < ARRAY_SIZE(pfdev->pm_domain_devs); i++) {
> + if (!pfdev->pm_domain_devs || !pfdev->pm_domain_links)
> + return;
> +
> + for (i = 0; i < pfdev->comp->num_pm_domains; i++) {
>   if (!pfdev->pm_domain_devs[i])
>   break;
>  
> @@ -161,9 +164,12 @@ static int panfrost_pm_domain_init(struct 
> panfrost_device *pfdev)
>   return -EINVAL;
>   }
>  
> - if (WARN(num_domains > ARRAY_SIZE(pfdev->pm_domain_devs),
> - "Too many supplies in compatible structure.\n"))
> - return -EINVAL;
> + pfdev->pm_domain_devs = devm_kcalloc(pfdev->dev, num_domains,
> +  sizeof(*pfdev->pm_domain_devs),
> +  GFP_KERNEL);
> + pfdev->pm_domain_links = devm_kcalloc(pfdev->dev, num_domains,
> +   sizeof(*pfdev->pm_domain_links),
> +   GFP_KERNEL);
>  
>   for (i = 0; i < num_domains; i++) {
>   pfdev->pm_domain_devs[i] =
> diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h 
> b/drivers/gpu/drm/panfrost/panfrost_device.h
> index 8b25278f34c8..98e3039696f9 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_device.h
> +++ b/drivers/gpu/drm/panfrost/panfrost_device.h
> @@ -22,7 +22,6 @@ struct panfrost_job;
>  struct panfrost_perfcnt;
>  
>  #define NUM_JOB_SLOTS 3
> -#define MAX_PM_DOMAINS 3
>  
>  struct panfrost_features {
>   u16 id;
> @@ -87,8 +86,8 @@ struct panfrost_device {
>   struct regulator_bulk_data *regulators;
>   struct reset_control *rstc;
>   /* pm_domains for devices with more than one. */
> - struct device *pm_domain_devs[MAX_PM_DOMAINS];
> - struct device_link *pm_domain_links[MAX_PM_DOMAINS];
> + struct device **pm_domain_devs;
> + struct device_link **pm_domain_links;
>   bool coherent;
>  
>   struct panfrost_features features;
> -- 
> 2.34.1
> 


Re: [PATCH v5 5/6] drm/msm/dpu: fix error handling in dpu_rm_init

2022-02-14 Thread Dmitry Baryshkov

On 14/02/2022 22:15, Abhinav Kumar wrote:



On 1/21/2022 1:06 PM, Dmitry Baryshkov wrote:

Using IS_ERR_OR_NULL() together with PTR_ERR() is a typical mistake. If
the value is NULL, then the function will return 0 instead of a proper
return code. Moreover none of dpu_hw_*_init() functions can return NULL.
So, replace all dpu_rm_init()'s IS_ERR_OR_NULL() calls with IS_ERR().

Can you please give an example of a case where dpu_hw_*_init() can 
return NULL?


All dpu_hw_*_init() functions are only called if the corresponding
hw*_counts are valid. So I would like to understand this.

Now, if NULL is treated as a non-error case, should we atleast print
a message indicating so?


- No dpu_hw_*init() can return NULL

- If at some point any of these functions returns NULL, it will cause a 
premature dpu_rm_init() termination with the success (=0) status, 
leaving parts of RM uninitialized.


Thus I'm replacing IS_ERR_OR_NULL with IS_ERR()




Signed-off-by: Dmitry Baryshkov 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 12 ++--
  1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c

index 96554e962e38..7497538adae1 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -109,7 +109,7 @@ int dpu_rm_init(struct dpu_rm *rm,
  continue;
  }
  hw = dpu_hw_lm_init(lm->id, mmio, cat);
-    if (IS_ERR_OR_NULL(hw)) {
+    if (IS_ERR(hw)) {
  rc = PTR_ERR(hw);
  DPU_ERROR("failed lm object creation: err %d\n", rc);
  goto fail;
@@ -126,7 +126,7 @@ int dpu_rm_init(struct dpu_rm *rm,
  continue;
  }
  hw = dpu_hw_merge_3d_init(merge_3d->id, mmio, cat);
-    if (IS_ERR_OR_NULL(hw)) {
+    if (IS_ERR(hw)) {
  rc = PTR_ERR(hw);
  DPU_ERROR("failed merge_3d object creation: err %d\n",
  rc);
@@ -144,7 +144,7 @@ int dpu_rm_init(struct dpu_rm *rm,
  continue;
  }
  hw = dpu_hw_pingpong_init(pp->id, mmio, cat);
-    if (IS_ERR_OR_NULL(hw)) {
+    if (IS_ERR(hw)) {
  rc = PTR_ERR(hw);
  DPU_ERROR("failed pingpong object creation: err %d\n",
  rc);
@@ -168,7 +168,7 @@ int dpu_rm_init(struct dpu_rm *rm,
  continue;
  }
  hw = dpu_hw_intf_init(intf->id, mmio, cat);
-    if (IS_ERR_OR_NULL(hw)) {
+    if (IS_ERR(hw)) {
  rc = PTR_ERR(hw);
  DPU_ERROR("failed intf object creation: err %d\n", rc);
  goto fail;
@@ -185,7 +185,7 @@ int dpu_rm_init(struct dpu_rm *rm,
  continue;
  }
  hw = dpu_hw_ctl_init(ctl->id, mmio, cat);
-    if (IS_ERR_OR_NULL(hw)) {
+    if (IS_ERR(hw)) {
  rc = PTR_ERR(hw);
  DPU_ERROR("failed ctl object creation: err %d\n", rc);
  goto fail;
@@ -202,7 +202,7 @@ int dpu_rm_init(struct dpu_rm *rm,
  continue;
  }
  hw = dpu_hw_dspp_init(dspp->id, mmio, cat);
-    if (IS_ERR_OR_NULL(hw)) {
+    if (IS_ERR(hw)) {
  rc = PTR_ERR(hw);
  DPU_ERROR("failed dspp object creation: err %d\n", rc);
  goto fail;



--
With best wishes
Dmitry


Re: [RFC v2 6/6] android: binder: Add a buffer flag to relinquish ownership of fds

2022-02-14 Thread John Stultz
On Mon, Feb 14, 2022 at 12:19 PM Todd Kjos  wrote:
> On Mon, Feb 14, 2022 at 11:29 AM Suren Baghdasaryan  wrote:
> > On Mon, Feb 14, 2022 at 10:33 AM Todd Kjos  wrote:
> > >
> > > Since we are creating a new gpu cgroup abstraction, couldn't this
> > > "transfer" be done in userspace by the target instead of in the kernel
> > > driver? Then this patch would reduce to just a flag on the buffer
> > > object.
> >
> > Are you suggesting to have a userspace accessible cgroup interface for
> > transferring buffer charges and the target process to use that
> > interface for requesting the buffer to be charged to its cgroup?
>
> Well, I'm asking why we need to do these cgroup-ish actions in the
> kernel when it seems more natural to do it in userspace.
>

In case its useful, some additional context from some of the Linux
Plumber's discussions last fall:

Daniel Stone outlines some concerns with the cgroup userland handling
for accounting:
  https://youtu.be/3OqllZONTiQ?t=3430

And the binder ownership transfer bit was suggested here by Daniel Vetter:
  https://youtu.be/3OqllZONTiQ?t=3730

thanks
-john


[PATCH] drm/panfrost: Dynamically allocate pm_domains

2022-02-14 Thread Alyssa Rosenzweig
MT8192 requires 5 power domains. Rather than bump MAX_PM_DOMAINS and
waste memory on every supported Panfrost chip, instead dynamically
allocate pm_domain_devs and pm_domain_links. This adds some flexibility;
it seems inevitable a new MediaTek device will require more than 5
domains.

On non-MediaTek devices, this saves a small amount of memory.

Suggested-by: AngeloGioacchino Del Regno 

Signed-off-by: Alyssa Rosenzweig 
---
 drivers/gpu/drm/panfrost/panfrost_device.c | 14 ++
 drivers/gpu/drm/panfrost/panfrost_device.h |  5 ++---
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c 
b/drivers/gpu/drm/panfrost/panfrost_device.c
index ee612303f076..661cdec320af 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.c
+++ b/drivers/gpu/drm/panfrost/panfrost_device.c
@@ -127,7 +127,10 @@ static void panfrost_pm_domain_fini(struct panfrost_device 
*pfdev)
 {
int i;
 
-   for (i = 0; i < ARRAY_SIZE(pfdev->pm_domain_devs); i++) {
+   if (!pfdev->pm_domain_devs || !pfdev->pm_domain_links)
+   return;
+
+   for (i = 0; i < pfdev->comp->num_pm_domains; i++) {
if (!pfdev->pm_domain_devs[i])
break;
 
@@ -161,9 +164,12 @@ static int panfrost_pm_domain_init(struct panfrost_device 
*pfdev)
return -EINVAL;
}
 
-   if (WARN(num_domains > ARRAY_SIZE(pfdev->pm_domain_devs),
-   "Too many supplies in compatible structure.\n"))
-   return -EINVAL;
+   pfdev->pm_domain_devs = devm_kcalloc(pfdev->dev, num_domains,
+sizeof(*pfdev->pm_domain_devs),
+GFP_KERNEL);
+   pfdev->pm_domain_links = devm_kcalloc(pfdev->dev, num_domains,
+ sizeof(*pfdev->pm_domain_links),
+ GFP_KERNEL);
 
for (i = 0; i < num_domains; i++) {
pfdev->pm_domain_devs[i] =
diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h 
b/drivers/gpu/drm/panfrost/panfrost_device.h
index 8b25278f34c8..98e3039696f9 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.h
+++ b/drivers/gpu/drm/panfrost/panfrost_device.h
@@ -22,7 +22,6 @@ struct panfrost_job;
 struct panfrost_perfcnt;
 
 #define NUM_JOB_SLOTS 3
-#define MAX_PM_DOMAINS 3
 
 struct panfrost_features {
u16 id;
@@ -87,8 +86,8 @@ struct panfrost_device {
struct regulator_bulk_data *regulators;
struct reset_control *rstc;
/* pm_domains for devices with more than one. */
-   struct device *pm_domain_devs[MAX_PM_DOMAINS];
-   struct device_link *pm_domain_links[MAX_PM_DOMAINS];
+   struct device **pm_domain_devs;
+   struct device_link **pm_domain_links;
bool coherent;
 
struct panfrost_features features;
-- 
2.34.1



[PATCH v2] drm/i915: fix build issue when using clang

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

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

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

Signed-off-by: Tong Zhang 
---

v2: revise commit message

 drivers/gpu/drm/i915/Makefile | 1 +
 1 file changed, 1 insertion(+)

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



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

2022-02-14 Thread Tong Zhang
On Sun, Feb 13, 2022 at 10:39 AM Nathan Chancellor  wrote:
>
> On Sat, Feb 12, 2022 at 10:51:06PM -0800, Tong Zhang wrote:
> > drm/i915 target adds some extra cflags, especially it does re-apply -Wall.
> > In clang this will override -Wno-format-security and cause the build to
> > fail when CONFIG_DRM_I915_WERROR=y. While with GCC this does not happen.
> > We reapply -Wno-format-security here to get around this issue.
>
> For what it's worth, GCC would warn in the exact same way if
> -Wformat-security was included within -Wall like it is for clang:
>
> drivers/gpu/drm/i915/gt/intel_gt.c: In function ‘intel_gt_invalidate_tlbs’:
> drivers/gpu/drm/i915/gt/intel_gt.c:988:9: error: format not a string literal 
> and no format arguments [-Werror=format-security]
>   988 | GEM_TRACE("\n");
>   | ^
> cc1: all warnings being treated as errors
>
> drivers/gpu/drm/i915/gt/selftest_execlists.c: In function ‘live_sanitycheck’:
> drivers/gpu/drm/i915/gt/selftest_execlists.c:142:25: error: format not a 
> string literal and no format arguments [-Werror=format-security]
>   142 | GEM_TRACE("spinner failed to start\n");
>   | ^
> drivers/gpu/drm/i915/gt/selftest_execlists.c: In function ‘live_preempt’:
> drivers/gpu/drm/i915/gt/selftest_execlists.c:1775:25: error: format not a 
> string literal and no format arguments [-Werror=format-security]
>  1775 | GEM_TRACE("lo spinner failed to start\n");
>   | ^
> drivers/gpu/drm/i915/gt/selftest_execlists.c:1792:25: error: format not a 
> string literal and no format arguments [-Werror=format-security]
>  1792 | GEM_TRACE("hi spinner failed to start\n");
>   | ^
> cc1: all warnings being treated as errors
>
> If fixing these warnings instead of just disabling the warning is
> undesirable (since I feel like the entire point of the i195 cflags
> situation is to enable more warnings than the main Makefile), I think
> the commit message should be rewritten to something along the lines of:
>
> "drm/i915 adds some extra cflags, namely -Wall, which causes
> instances of -Wformat-security to appear when building with clang, even
> though this warning is turned off kernel-wide in the main Makefile:"
>
> > drivers/gpu/drm/i915/gt/intel_gt.c:983:2: error: format string is not a 
> > string literal (potentially insecure) [-Werror,-Wformat-security]
> > GEM_TRACE("ERROR\n");
> > ^~~~
> > ./drivers/gpu/drm/i915/i915_gem.h:76:24: note: expanded from macro 
> > 'GEM_TRACE'
> >  #define GEM_TRACE(...) trace_printk(__VA_ARGS__)
> >^
> > ./include/linux/kernel.h:369:3: note: expanded from macro 'trace_printk'
> > do_trace_printk(fmt, ##__VA_ARGS__);\
> > ^~~
> > ./include/linux/kernel.h:383:30: note: expanded from macro 'do_trace_printk'
> > __trace_bprintk(_THIS_IP_, trace_printk_fmt, ##args);   \
> >^~~~
> > drivers/gpu/drm/i915/gt/intel_gt.c:983:2: note: treat the string as an 
> > argument to avoid this
>
> "This does not happen with GCC because it does not enable
> -Wformat-security with -Wall. Disable -Wformat-security within the i915
> Makefile so that these warnings do not show up with clang."
>
> The actual diff itself looks fine to me.
>
> Cheers,
> Nathan
>
> > Signed-off-by: Tong Zhang 
> > ---
> >  drivers/gpu/drm/i915/Makefile | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> > index 1b62b9f65196..c04e05a3d39f 100644
> > --- a/drivers/gpu/drm/i915/Makefile
> > +++ b/drivers/gpu/drm/i915/Makefile
> > @@ -13,6 +13,7 @@
> >  # will most likely get a sudden build breakage... Hopefully we will fix
> >  # new warnings before CI updates!
> >  subdir-ccflags-y := -Wall -Wextra
> > +subdir-ccflags-y += -Wno-format-security
> >  subdir-ccflags-y += -Wno-unused-parameter
> >  subdir-ccflags-y += -Wno-type-limits
> >  subdir-ccflags-y += -Wno-missing-field-initializers
> > --
> > 2.25.1
> >

Thank you Nathan!
I will send a v2 with a revised commit message.
Thanks,
- Tong


Re: [PATCH v5 6/6] drm/msm/dpu: move VBIF blocks handling to dpu_rm

2022-02-14 Thread Abhinav Kumar




On 1/21/2022 1:06 PM, Dmitry Baryshkov wrote:

Move handling of VBIF blocks into dpu_rm. This serves the purpose of
unification of handling of all hardware blocks inside the DPU driver.
This removes hand-coded loops in dpu_vbif (which look for necessary VBIF
instance by looping through the dpu_kms->hw_vbif and comparing
vbif_idx).

Signed-off-by: Dmitry Baryshkov 


I have a slightly different idea about this. Let me know what you think.

VBIF is a bus interface for the dpu to fetch from. I am not sure if 
pulling it in the RM is right because its not a dedicated HW block like

the others in the RM.

But, I agree with your problem statement of hand-coded loops.

So instead, why dont you just have a helper in the dpu_vbif.c to get
you the vbif hw for the passed index like, maybe something like this?

--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
@@ -11,6 +11,19 @@
 #include "dpu_hw_vbif.h"
 #include "dpu_trace.h"

+static dpu_hw_vbif *dpu_vbif_get_hw(struct dpu_kms *dpu_kms, u32 vbif_idx)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
+   if (dpu_kms->hw_vbif[i] &&
+   dpu_kms->hw_vbif[i]->idx == vbif_idx)
+   vbif = dpu_kms->hw_vbif[i];
+   }
+
+   return vbif;
+}
+
 /**
  * _dpu_vbif_wait_for_xin_halt - wait for the xin to halt
  * @vbif:  Pointer to hardware vbif driver
@@ -156,11 +169,7 @@ void dpu_vbif_set_ot_limit(struct dpu_kms *dpu_kms,

mdp = dpu_kms->hw_mdp;

-   for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
-   if (dpu_kms->hw_vbif[i] &&
-   dpu_kms->hw_vbif[i]->idx == 
params->vbif_idx)

-   vbif = dpu_kms->hw_vbif[i];
-   }
+   vbif = dpu_vbif_get_hw(dpu_kms, params->vbif_idx);

if (!vbif || !mdp) {
DRM_DEBUG_ATOMIC("invalid arguments vbif %d mdp %d\n",
@@ -216,13 +225,7 @@ void dpu_vbif_set_qos_remap(struct dpu_kms *dpu_kms,
}
mdp = dpu_kms->hw_mdp;

-   for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
-   if (dpu_kms->hw_vbif[i] &&
-   dpu_kms->hw_vbif[i]->idx == 
params->vbif_idx) {

-   vbif = dpu_kms->hw_vbif[i];
-   break;
-   }
-   }
+   vbif = dpu_vbif_get_hw(params->vbif_idx);




---
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h |  1 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 28 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h |  1 -
  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c  | 19 ++
  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h  | 12 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c| 26 ++-
  6 files changed, 40 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h
index 6417aa28d32c..895e86dabcb6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_vbif.h
@@ -8,6 +8,7 @@
  #include "dpu_hw_catalog.h"
  #include "dpu_hw_mdss.h"
  #include "dpu_hw_util.h"
+#include "dpu_hw_blk.h"
  
  struct dpu_hw_vbif;
  
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c

index 47fe11a84a77..4a1983d8561b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -782,8 +782,6 @@ static long dpu_kms_round_pixclk(struct msm_kms *kms, 
unsigned long rate,
  
  static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms)

  {
-   int i;
-
if (dpu_kms->hw_intr)
dpu_hw_intr_destroy(dpu_kms->hw_intr);
dpu_kms->hw_intr = NULL;
@@ -791,15 +789,6 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms)
/* safe to call these more than once during shutdown */
_dpu_kms_mmu_destroy(dpu_kms);
  
-	if (dpu_kms->catalog) {

-   for (i = 0; i < dpu_kms->catalog->vbif_count; i++) {
-   u32 vbif_idx = dpu_kms->catalog->vbif[i].id;
-
-   if ((vbif_idx < VBIF_MAX) && dpu_kms->hw_vbif[vbif_idx])
-   dpu_hw_vbif_destroy(dpu_kms->hw_vbif[vbif_idx]);
-   }
-   }
-
if (dpu_kms->rm_init)
dpu_rm_destroy(_kms->rm);
dpu_kms->rm_init = false;
@@ -1027,7 +1016,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
  {
struct dpu_kms *dpu_kms;
struct drm_device *dev;
-   int i, rc = -EINVAL;
+   int rc = -EINVAL;
  
  	if (!kms) {

DPU_ERROR("invalid kms\n");
@@ -1116,21 +1105,6 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
goto power_error;
}
  
-	for (i = 0; i < dpu_kms->catalog->vbif_count; i++) {

-   u32 vbif_idx = dpu_kms->catalog->vbif[i].id;
-
-   dpu_kms->hw_vbif[i] = dpu_hw_vbif_init(vbif_idx,
-   

Re: [RFC v2 0/6] Proposal for a GPU cgroup controller

2022-02-14 Thread Tejun Heo
Hello,

On Fri, Feb 11, 2022 at 04:18:23PM +, T.J. Mercier wrote:
> The GPU/DRM cgroup controller came into being when a consensus[1]
> was reached that the resources it tracked were unsuitable to be integrated
> into memcg. Originally, the proposed controller was specific to the DRM
> subsystem and was intended to track GEM buffers and GPU-specific
> resources[2]. In order to help establish a unified memory accounting model
> for all GPU and all related subsystems, Daniel Vetter put forth a
> suggestion to move it out of the DRM subsystem so that it can be used by
> other DMA-BUF exporters as well[3]. This RFC proposes an interface that
> does the same.
> 
> [1]: 
> https://patchwork.kernel.org/project/dri-devel/cover/20190501140438.9506-1-brian.we...@intel.com/#22624705
> [2]: 
> https://lore.kernel.org/amd-gfx/20210126214626.16260-1-brian.we...@intel.com/
> [3]: https://lore.kernel.org/amd-gfx/YCVOl8%2F87bqRSQei@phenom.ffwll.local/

IIRC, the only consensus was that it needs to be a separate controller and
folks had trouble agreeing on resource types, control mechanism and
interface. Imma keep an eye on how the discussion develops among GPU folks.
Please feel free to ping if there's an area my input may be useful.

Thanks.

-- 
tejun


Re: [PATCH v5 5/6] drm/msm/dpu: fix error handling in dpu_rm_init

2022-02-14 Thread Abhinav Kumar




On 1/21/2022 1:06 PM, Dmitry Baryshkov wrote:

Using IS_ERR_OR_NULL() together with PTR_ERR() is a typical mistake. If
the value is NULL, then the function will return 0 instead of a proper
return code. Moreover none of dpu_hw_*_init() functions can return NULL.
So, replace all dpu_rm_init()'s IS_ERR_OR_NULL() calls with IS_ERR().

Can you please give an example of a case where dpu_hw_*_init() can 
return NULL?


All dpu_hw_*_init() functions are only called if the corresponding
hw*_counts are valid. So I would like to understand this.

Now, if NULL is treated as a non-error case, should we atleast print
a message indicating so?


Signed-off-by: Dmitry Baryshkov 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 12 ++--
  1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 96554e962e38..7497538adae1 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -109,7 +109,7 @@ int dpu_rm_init(struct dpu_rm *rm,
continue;
}
hw = dpu_hw_lm_init(lm->id, mmio, cat);
-   if (IS_ERR_OR_NULL(hw)) {
+   if (IS_ERR(hw)) {
rc = PTR_ERR(hw);
DPU_ERROR("failed lm object creation: err %d\n", rc);
goto fail;
@@ -126,7 +126,7 @@ int dpu_rm_init(struct dpu_rm *rm,
continue;
}
hw = dpu_hw_merge_3d_init(merge_3d->id, mmio, cat);
-   if (IS_ERR_OR_NULL(hw)) {
+   if (IS_ERR(hw)) {
rc = PTR_ERR(hw);
DPU_ERROR("failed merge_3d object creation: err %d\n",
rc);
@@ -144,7 +144,7 @@ int dpu_rm_init(struct dpu_rm *rm,
continue;
}
hw = dpu_hw_pingpong_init(pp->id, mmio, cat);
-   if (IS_ERR_OR_NULL(hw)) {
+   if (IS_ERR(hw)) {
rc = PTR_ERR(hw);
DPU_ERROR("failed pingpong object creation: err %d\n",
rc);
@@ -168,7 +168,7 @@ int dpu_rm_init(struct dpu_rm *rm,
continue;
}
hw = dpu_hw_intf_init(intf->id, mmio, cat);
-   if (IS_ERR_OR_NULL(hw)) {
+   if (IS_ERR(hw)) {
rc = PTR_ERR(hw);
DPU_ERROR("failed intf object creation: err %d\n", rc);
goto fail;
@@ -185,7 +185,7 @@ int dpu_rm_init(struct dpu_rm *rm,
continue;
}
hw = dpu_hw_ctl_init(ctl->id, mmio, cat);
-   if (IS_ERR_OR_NULL(hw)) {
+   if (IS_ERR(hw)) {
rc = PTR_ERR(hw);
DPU_ERROR("failed ctl object creation: err %d\n", rc);
goto fail;
@@ -202,7 +202,7 @@ int dpu_rm_init(struct dpu_rm *rm,
continue;
}
hw = dpu_hw_dspp_init(dspp->id, mmio, cat);
-   if (IS_ERR_OR_NULL(hw)) {
+   if (IS_ERR(hw)) {
rc = PTR_ERR(hw);
DPU_ERROR("failed dspp object creation: err %d\n", rc);
goto fail;


Re: [PATCH v5 4/6] drm/msm/dpu: stop embedding dpu_hw_blk into dpu_hw_intf

2022-02-14 Thread Abhinav Kumar




On 1/21/2022 1:06 PM, Dmitry Baryshkov wrote:

Now as dpu_hw_intf is not hanled by dpu_rm_get_assigned_resources, there
is no point in embedding the (empty) struct dpu_hw_blk into dpu_hw_intf
(and using typecasts between dpu_hw_blk and dpu_hw_intf). Drop it and
use dpu_hw_intf directly.

Signed-off-by: Dmitry Baryshkov 
Reviewed-by: Stephen Boyd 

Reviewed-by: Abhinav Kumar 

---
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h | 11 ---
  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c  | 17 +++--
  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h  |  9 ++---
  3 files changed, 9 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h
index 3568be80dab5..230d122fa43b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h
@@ -78,7 +78,6 @@ struct dpu_hw_intf_ops {
  };
  
  struct dpu_hw_intf {

-   struct dpu_hw_blk base;
struct dpu_hw_blk_reg_map hw;
  
  	/* intf */

@@ -90,16 +89,6 @@ struct dpu_hw_intf {
struct dpu_hw_intf_ops ops;
  };
  
-/**

- * to_dpu_hw_intf - convert base object dpu_hw_base to container
- * @hw: Pointer to base hardware block
- * return: Pointer to hardware block container
- */
-static inline struct dpu_hw_intf *to_dpu_hw_intf(struct dpu_hw_blk *hw)
-{
-   return container_of(hw, struct dpu_hw_intf, base);
-}
-
  /**
   * dpu_hw_intf_init(): Initializes the intf driver for the passed
   * interface idx.
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 8df21a46308e..96554e962e38 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -74,14 +74,8 @@ int dpu_rm_destroy(struct dpu_rm *rm)
dpu_hw_ctl_destroy(hw);
}
}
-   for (i = 0; i < ARRAY_SIZE(rm->intf_blks); i++) {
-   struct dpu_hw_intf *hw;
-
-   if (rm->intf_blks[i]) {
-   hw = to_dpu_hw_intf(rm->intf_blks[i]);
-   dpu_hw_intf_destroy(hw);
-   }
-   }
+   for (i = 0; i < ARRAY_SIZE(rm->hw_intf); i++)
+   dpu_hw_intf_destroy(rm->hw_intf[i]);
  
  	return 0;

  }
@@ -179,7 +173,7 @@ int dpu_rm_init(struct dpu_rm *rm,
DPU_ERROR("failed intf object creation: err %d\n", rc);
goto fail;
}
-   rm->intf_blks[intf->id - INTF_0] = >base;
+   rm->hw_intf[intf->id - INTF_0] = hw;
}
  
  	for (i = 0; i < cat->ctl_count; i++) {

@@ -593,8 +587,3 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
  
  	return num_blks;

  }
-
-struct dpu_hw_intf *dpu_rm_get_intf(struct dpu_rm *rm, enum dpu_intf intf_idx)
-{
-   return to_dpu_hw_intf(rm->intf_blks[intf_idx - INTF_0]);
-}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
index ee50f6651b6e..9b13200a050a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
@@ -18,14 +18,14 @@ struct dpu_global_state;
   * @pingpong_blks: array of pingpong hardware resources
   * @mixer_blks: array of layer mixer hardware resources
   * @ctl_blks: array of ctl hardware resources
- * @intf_blks: array of intf hardware resources
+ * @hw_intf: array of intf hardware resources
   * @dspp_blks: array of dspp hardware resources
   */
  struct dpu_rm {
struct dpu_hw_blk *pingpong_blks[PINGPONG_MAX - PINGPONG_0];
struct dpu_hw_blk *mixer_blks[LM_MAX - LM_0];
struct dpu_hw_blk *ctl_blks[CTL_MAX - CTL_0];
-   struct dpu_hw_blk *intf_blks[INTF_MAX - INTF_0];
+   struct dpu_hw_intf *hw_intf[INTF_MAX - INTF_0];
struct dpu_hw_blk *dspp_blks[DSPP_MAX - DSPP_0];
struct dpu_hw_blk *merge_3d_blks[MERGE_3D_MAX - MERGE_3D_0];
  };
@@ -90,7 +90,10 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
   * @rm: DPU Resource Manager handle
   * @intf_idx: INTF's index
   */
-struct dpu_hw_intf *dpu_rm_get_intf(struct dpu_rm *rm, enum dpu_intf intf_idx);
+static inline struct dpu_hw_intf *dpu_rm_get_intf(struct dpu_rm *rm, enum 
dpu_intf intf_idx)
+{
+   return rm->hw_intf[intf_idx - INTF_0];
+}
  
  #endif /* __DPU_RM_H__ */
  


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

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

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

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

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



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

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

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

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

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

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

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

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

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

Re: [PATCH] drm/amdgpu: check return status before using stable_pstate

2022-02-14 Thread Alex Deucher
Applied.  Thanks!

Alex

On Mon, Feb 14, 2022 at 1:22 PM  wrote:
>
> From: Tom Rix 
>
> Clang static analysis reports this problem
> amdgpu_ctx.c:616:26: warning: Assigned value is garbage
>   or undefined
>   args->out.pstate.flags = stable_pstate;
>  ^ ~
> amdgpu_ctx_stable_pstate can fail without setting
> stable_pstate.  So check.
>
> Fixes: 8cda7a4f96e4 ("drm/amdgpu/UAPI: add new CTX OP to get/set stable 
> pstates")
> Signed-off-by: Tom Rix 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
> index 1c72f6095f08..f522b52725e4 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
> @@ -613,7 +613,8 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
> if (args->in.flags)
> return -EINVAL;
> r = amdgpu_ctx_stable_pstate(adev, fpriv, id, false, 
> _pstate);
> -   args->out.pstate.flags = stable_pstate;
> +   if (!r)
> +   args->out.pstate.flags = stable_pstate;
> break;
> case AMDGPU_CTX_OP_SET_STABLE_PSTATE:
> if (args->in.flags & ~AMDGPU_CTX_STABLE_PSTATE_FLAGS_MASK)
> --
> 2.26.3
>


[PATCH] drm/amdgpu: check return status before using stable_pstate

2022-02-14 Thread trix
From: Tom Rix 

Clang static analysis reports this problem
amdgpu_ctx.c:616:26: warning: Assigned value is garbage
  or undefined
  args->out.pstate.flags = stable_pstate;
 ^ ~
amdgpu_ctx_stable_pstate can fail without setting
stable_pstate.  So check.

Fixes: 8cda7a4f96e4 ("drm/amdgpu/UAPI: add new CTX OP to get/set stable 
pstates")
Signed-off-by: Tom Rix 
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
index 1c72f6095f08..f522b52725e4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
@@ -613,7 +613,8 @@ int amdgpu_ctx_ioctl(struct drm_device *dev, void *data,
if (args->in.flags)
return -EINVAL;
r = amdgpu_ctx_stable_pstate(adev, fpriv, id, false, 
_pstate);
-   args->out.pstate.flags = stable_pstate;
+   if (!r)
+   args->out.pstate.flags = stable_pstate;
break;
case AMDGPU_CTX_OP_SET_STABLE_PSTATE:
if (args->in.flags & ~AMDGPU_CTX_STABLE_PSTATE_FLAGS_MASK)
-- 
2.26.3



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

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

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

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

Re: [PATCH] drm/msm: populate intf_audio_select() base on hardware capability

2022-02-14 Thread Kuogee Hsieh


On 2/11/2022 3:36 PM, Dmitry Baryshkov wrote:

On Sat, 12 Feb 2022 at 02:23, Kuogee Hsieh  wrote:

intf_audio_select() callback function use to configure
HDMI_DP_CORE_SELECT to decide audio output routes to HDMI or DP
interface. HDMI is obsoleted at newer chipset. To keep supporting
legacy hdmi application, intf_audio_select call back function have
to be populated base on hardware chip capability where legacy
chipsets have has_audio_select flag set to true.

Signed-off-by: Kuogee Hsieh
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 2 ++
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 1 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c | 9 ++---
  3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index 272b14b..23680e7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -201,6 +201,7 @@ static const struct dpu_caps sdm845_dpu_caps = {
 .has_dim_layer = true,
 .has_idle_pc = true,
 .has_3d_merge = true,
+   .has_audio_select = true,
 .max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
 .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
 .max_hdeci_exp = MAX_HORZ_DECIMATION,
@@ -229,6 +230,7 @@ static const struct dpu_caps sm8150_dpu_caps = {
 .has_dim_layer = true,
 .has_idle_pc = true,
 .has_3d_merge = true,
+   .has_audio_select = true,
 .max_linewidth = 4096,
 .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
 .max_hdeci_exp = MAX_HORZ_DECIMATION,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
index e5a96d6..b33f91b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -357,6 +357,7 @@ struct dpu_caps {
 bool has_dim_layer;
 bool has_idle_pc;
 bool has_3d_merge;
+   bool has_audio_select;

I'd suggest adding a bit to dpu_mdp_cfg's features instead, following
the example of other hardware blocks.


it may cause mis leading if we put this in hardware level since 
MDP_HDMI_DP_SELECT  bit has not be connected


to logic for a while even it still present at ipcat. Also this bit but 
will be  removed at next release.


Is dpu_caps level more proper than in hardware feature level?





 /* SSPP limits */
 u32 max_linewidth;
 u32 pixel_ram_size;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
index 282e3c6..e608f4d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
@@ -261,14 +261,17 @@ static void dpu_hw_intf_audio_select(struct dpu_hw_mdp 
*mdp)
  }

  static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops,
-   unsigned long cap)
+   unsigned long cap,
+   const struct dpu_mdss_cfg *m)
  {
 ops->setup_split_pipe = dpu_hw_setup_split_pipe;
 ops->setup_clk_force_ctrl = dpu_hw_setup_clk_force_ctrl;
 ops->get_danger_status = dpu_hw_get_danger_status;
 ops->setup_vsync_source = dpu_hw_setup_vsync_source;
 ops->get_safe_status = dpu_hw_get_safe_status;
-   ops->intf_audio_select = dpu_hw_intf_audio_select;
+
+   if (m->caps->has_audio_select)
+   ops->intf_audio_select = dpu_hw_intf_audio_select;
  }

  static const struct dpu_mdp_cfg *_top_offset(enum dpu_mdp mdp,
@@ -320,7 +323,7 @@ struct dpu_hw_mdp *dpu_hw_mdptop_init(enum dpu_mdp idx,
  */
 mdp->idx = idx;
 mdp->caps = cfg;
-   _setup_mdp_ops(>ops, mdp->caps->features);
+   _setup_mdp_ops(>ops, mdp->caps->features, m);

 return mdp;
  }

Re: [PATCH 1/9] dt-bindings: Add arm,mali-valhall compatible

2022-02-14 Thread Daniel Stone
On Mon, 14 Feb 2022 at 16:23, Steven Price  wrote:
> On 11/02/2022 20:27, alyssa.rosenzw...@collabora.com wrote:
> > From the kernel's perspective, pre-CSF Valhall is more or less
> > compatible with Bifrost, although they differ to userspace. Add a
> > compatible for Valhall to the existing Bifrost bindings documentation.
> >
> > diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml 
> > b/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml
> > index 63a08f3f321d..48aeabd2ed68 100644
> > --- a/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml
> > +++ b/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml
> > @@ -23,6 +23,7 @@ properties:
> >- rockchip,px30-mali
> >- rockchip,rk3568-mali
> >- const: arm,mali-bifrost # Mali Bifrost GPU model/revision is fully 
> > discoverable
> > +  - const: arm,mali-valhall # Mali Valhall GPU model/revision is fully 
> > discoverable
>
> It might be worth spelling out here that this is *pre-CSF* Valhall. I'm
> pretty sure we're going to need different bindings for CSF GPUs.

Good point - maybe either make it arm,mali-valhall-jm then?

Cheers,
Daniel


Re: [PATCH] gpu: ipu-v3: Fix dev_dbg frequency output

2022-02-14 Thread Lucas Stach
Am Montag, dem 14.02.2022 um 16:44 + schrieb Jonas Mark (BT-FIR/ENG1-Grb):
> Hi,
> 
> > From: Leo Ruan 
> > 
> > This commit corrects the printing of the IPU clock error percentage if it is
> > between -0.1% to -0.9%. For example, if the pixel clock requested is 27.2
> > MHz but only 27.0 MHz can be achieved the deviation is -0.8%.
> > But the fixed point math had a flaw and calculated error of 0.2%.
> > 
> > Before:
> >   Clocks: IPU 27000Hz DI 24716667Hz Needed 2720Hz
> >   IPU clock can give 2700 with divider 10, error 0.2%
> >   Want 2720Hz IPU 27000Hz DI 24716667Hz using IPU,
> > 2700Hz
> > 
> > After:
> >   Clocks: IPU 27000Hz DI 24716667Hz Needed 2720Hz
> >   IPU clock can give 2700 with divider 10, error -0.8%
> >   Want 2720Hz IPU 27000Hz DI 24716667Hz using IPU,
> > 2700Hz
> > 
> > Signed-off-by: Leo Ruan 
> > Signed-off-by: Mark Jonas 
> > ---
> >  drivers/gpu/ipu-v3/ipu-di.c | 5 +++--
> >  1 file changed, 3 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/gpu/ipu-v3/ipu-di.c b/drivers/gpu/ipu-v3/ipu-di.c index
> > b4a31d506fcc..74eca68891ad 100644
> > --- a/drivers/gpu/ipu-v3/ipu-di.c
> > +++ b/drivers/gpu/ipu-v3/ipu-di.c
> > @@ -451,8 +451,9 @@ static void ipu_di_config_clock(struct ipu_di *di,
> > 
> > error = rate / (sig->mode.pixelclock / 1000);
> > 
> > -   dev_dbg(di->ipu->dev, "  IPU clock can give %lu with divider
> > %u, error %d.%u%%\n",
> > -   rate, div, (signed)(error - 1000) / 10, error % 10);
> > +   dev_dbg(di->ipu->dev, "  IPU clock can give %lu with divider
> > %u, error %c%d.%d%%\n",
> > +   rate, div, error < 1000 ? '-' : '+',
> > +   abs(error - 1000) / 10, abs(error - 1000) % 10);
> > 
> > /* Allow a 1% error */
> > if (error < 1010 && error >= 990) {
> 
> Is there anything I can do to help getting this patch mainline?

Philipp is still on vacation, but will be back in a few days. I guess
he will take a look at those patches then.

Regards,
Lucas



Re: [PATCH 5/9] drm/panfrost: Add HW_ISSUE_TTRX_3485 quirk

2022-02-14 Thread Alyssa Rosenzweig
> > TTRX_3485 requires the infamous "dummy job" workaround. I have this
> > workaround implemented in a local branch, but I have not yet hit a case
> > that requires it so I cannot test whether the implementation is correct.
> > In the mean time, add the quirk bit so we can document which platforms
> > may need it in the future.
> 
> This one is hideous ;) Although to me this isn't the 'infamous' one as
> it's not the earliest example of a dummy job.

Terrifying. I guess we narrowly avoided the 'replay' workaround which
was far worse than this one...

> However... I believe as Panfrost currently stands this is probably not
> very possible to hit. It requires a job to be stopped (soft or hard) at
> a critical point during submission - which at the moment Panfrost
> basically never does (the exception is if you close the fd immediately
> while a job is in progress). And of course the timing has to be 'just
> right' to hit the bug.

OK, that's good to know. Still "should" be fixed but that definitely
lowers the priority of it. Frankly the multithreading bugs we have on
the CPU side would hang the machine sooner...


Re: [PATCH 4/9] drm/panfrost: Handle HW_ISSUE_TTRX_3076

2022-02-14 Thread Alyssa Rosenzweig
On Mon, Feb 14, 2022 at 04:23:18PM +, Steven Price wrote:
> On 11/02/2022 20:27, alyssa.rosenzw...@collabora.com wrote:
> > From: Alyssa Rosenzweig 
> > 
> > Some Valhall GPUs require resets when encountering bus faults due to
> > occlusion query writes. Add the issue bit for this and handle it.
> > 
> > Signed-off-by: Alyssa Rosenzweig 
> 
> Reviewed-by: Steven Price 
> (although one nit below)
> 
> Just in case any one is wondering - these bus faults occur when
> switching the GPU's MMU to unmapped - it's not a normal "bus fault" from
> the external bus. This is triggered by an attempt to read unmapped
> memory which is completed by the driver by switching the entire MMU to
> unmapped.

Ouch, that's subtle.

> > diff --git a/drivers/gpu/drm/panfrost/panfrost_issues.h 
> > b/drivers/gpu/drm/panfrost/panfrost_issues.h
> > index a66692663833..058f6a4c8435 100644
> > --- a/drivers/gpu/drm/panfrost/panfrost_issues.h
> > +++ b/drivers/gpu/drm/panfrost/panfrost_issues.h
> > @@ -128,6 +128,10 @@ enum panfrost_hw_issue {
> > /* Must set SC_VAR_ALGORITHM */
> > HW_ISSUE_TTRX_2968_TTRX_3162,
> >  
> > +   /* Bus fault from occlusion query write may cause future fragment jobs
> > +* to hang */
> 
> NIT: Kernel comment style has the "/*" and "*/" on lines by themselves
> for multi-line comments. checkpatch will complain!

Yes, I am aware (and checkpatch did complain). The existing multi-line
comments in that file do not have the extra lines. Consistency within
the file seemed like the lesser evil. If you think it's better to
appease checkpatch, I can reformat for v2.

(I can also throw in a patch fixing the rest of that file's multiline
comments but that seems a bit extra.)


Re: [PATCH 8/9] drm/panfrost: Add Mali-G57 "Natt" support

2022-02-14 Thread Alyssa Rosenzweig
> > index b8865fc9efce..1a0dc7f7f857 100644
> > --- a/drivers/gpu/drm/panfrost/panfrost_issues.h
> > +++ b/drivers/gpu/drm/panfrost/panfrost_issues.h
> > @@ -258,6 +258,11 @@ enum panfrost_hw_issue {
> >  
> >  #define hw_issues_g76 0
> >  
> > +#define hw_issues_g57 (\
> > +   BIT_ULL(HW_ISSUE_TTRX_2968_TTRX_3162) | \
> > +   BIT_ULL(HW_ISSUE_TTRX_3076) | \
> > +   BIT_ULL(HW_ISSUE_TTRX_3485))
> 
> Do you know whether you have an r0p0 or an r0p1 Natt? Only the r0p0 has
> the 3485 issue, and we might be lucky and it's the r0p1 that's "in the
> wild".

Sadly, I believe I have an r0p0. I don't know if future spins of the
same SoC would be bumped up, but I'm skeptical.

> It would be good to annotate these lists with the hardware revisions
> when there is a difference.

Sure.


Re: [PATCH 6/9] drm/panfrost: Add "clean only safe" feature bit

2022-02-14 Thread Alyssa Rosenzweig
> > Add the HW_FEATURE_CLEAN_ONLY_SAFE bit based on kbase. When I actually
> > tried to port the logic from kbase, trivial jobs raised Data Invalid
> > Faults, so this may depend on other coherency details. It's still useful
> > to have the bit to record the feature bit when adding new models.
> > 
> > Signed-off-by: Alyssa Rosenzweig 
> 
> Reviewed-by: Steven Price 
> 
> Sadly I don't have the hardware to try this out on, but it should be a
> simple case of the below (untested):
> 
> 8<
> diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c 
> b/drivers/gpu/drm/panfrost/panfrost_job.c
> index 908d79520853..602e51c4966e 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_job.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_job.c
> @@ -212,9 +212,13 @@ static void panfrost_job_hw_submit(struct panfrost_job 
> *job, int js)
>  * start */
> cfg |= JS_CONFIG_THREAD_PRI(8) |
> JS_CONFIG_START_FLUSH_CLEAN_INVALIDATE |
> -   JS_CONFIG_END_FLUSH_CLEAN_INVALIDATE |
> panfrost_get_job_chain_flag(job);
>  
> +   if (panfrost_has_hw_feature(pfdev, HW_FEATURE_CLEAN_ONLY_SAFE))
> +   cfg |= JS_CONFIG_END_FLUSH_CLEAN;
> +   else
> +   cfg |= JS_CONFIG_END_FLUSH_CLEAN_INVALIDATE;
> +
> if (panfrost_has_hw_feature(pfdev, HW_FEATURE_FLUSH_REDUCTION))
> cfg |= JS_CONFIG_ENABLE_FLUSH_REDUCTION;

Yes, this is the patch I typed out... causes DATA_INVALID_FAULTs for me
with Mesa. Which makes me wonder if userspace needs to respect some
extra rules for this to be safe.


Re: [PATCH 1/9] dt-bindings: Add arm,mali-valhall compatible

2022-02-14 Thread Alyssa Rosenzweig
> > diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml 
> > b/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml
> > index 63a08f3f321d..48aeabd2ed68 100644
> > --- a/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml
> > +++ b/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml
> > @@ -23,6 +23,7 @@ properties:
> >- rockchip,px30-mali
> >- rockchip,rk3568-mali
> >- const: arm,mali-bifrost # Mali Bifrost GPU model/revision is fully 
> > discoverable
> > +  - const: arm,mali-valhall # Mali Valhall GPU model/revision is fully 
> > discoverable
> 
> It might be worth spelling out here that this is *pre-CSF* Valhall. I'm
> pretty sure we're going to need different bindings for CSF GPUs.

Yes, agreed, will make a note for v2.


Re: [PATCH v3 0/3] Add connector_type to debug info to differentiate between eDP and DP

2022-02-14 Thread Kuogee Hsieh

Hi Stephen,

Can you please review this serial patches.

On 2/2/2022 10:56 AM, Kuogee Hsieh wrote:

1) Add connector_type to debug info to differentiate between eDP and DP
2) add more debug info to cover dp Phy
3) repalce DRM_DEBUG_DP with drm_debug_dp

Kuogee Hsieh (3):
   drm/msm/dp: add connector type to enhance debug messages
   drm/msm/dp: enhance debug info related to dp phy
   drm/msm/dp:  replace DRM_DEBUG_DP marco with drm_dbg_dp

  drivers/gpu/drm/msm/dp/dp_audio.c   |  49 +--
  drivers/gpu/drm/msm/dp/dp_catalog.c |  34 ++-
  drivers/gpu/drm/msm/dp/dp_ctrl.c| 116 +++-
  drivers/gpu/drm/msm/dp/dp_display.c | 103 ++--
  drivers/gpu/drm/msm/dp/dp_drm.c |   4 +-
  drivers/gpu/drm/msm/dp/dp_link.c|  99 +-
  drivers/gpu/drm/msm/dp/dp_panel.c   |  43 +++--
  drivers/gpu/drm/msm/dp/dp_parser.c  |   2 +-
  drivers/gpu/drm/msm/dp/dp_power.c   |  20 ---
  9 files changed, 283 insertions(+), 187 deletions(-)



AW: [PATCH] gpu: ipu-v3: Fix dev_dbg frequency output

2022-02-14 Thread Jonas Mark (BT-FIR/ENG1-Grb)
Hi,

> From: Leo Ruan 
> 
> This commit corrects the printing of the IPU clock error percentage if it is
> between -0.1% to -0.9%. For example, if the pixel clock requested is 27.2
> MHz but only 27.0 MHz can be achieved the deviation is -0.8%.
> But the fixed point math had a flaw and calculated error of 0.2%.
> 
> Before:
>   Clocks: IPU 27000Hz DI 24716667Hz Needed 2720Hz
>   IPU clock can give 2700 with divider 10, error 0.2%
>   Want 2720Hz IPU 27000Hz DI 24716667Hz using IPU,
> 2700Hz
> 
> After:
>   Clocks: IPU 27000Hz DI 24716667Hz Needed 2720Hz
>   IPU clock can give 2700 with divider 10, error -0.8%
>   Want 2720Hz IPU 27000Hz DI 24716667Hz using IPU,
> 2700Hz
> 
> Signed-off-by: Leo Ruan 
> Signed-off-by: Mark Jonas 
> ---
>  drivers/gpu/ipu-v3/ipu-di.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/ipu-v3/ipu-di.c b/drivers/gpu/ipu-v3/ipu-di.c index
> b4a31d506fcc..74eca68891ad 100644
> --- a/drivers/gpu/ipu-v3/ipu-di.c
> +++ b/drivers/gpu/ipu-v3/ipu-di.c
> @@ -451,8 +451,9 @@ static void ipu_di_config_clock(struct ipu_di *di,
> 
>   error = rate / (sig->mode.pixelclock / 1000);
> 
> - dev_dbg(di->ipu->dev, "  IPU clock can give %lu with divider
> %u, error %d.%u%%\n",
> - rate, div, (signed)(error - 1000) / 10, error % 10);
> + dev_dbg(di->ipu->dev, "  IPU clock can give %lu with divider
> %u, error %c%d.%d%%\n",
> + rate, div, error < 1000 ? '-' : '+',
> + abs(error - 1000) / 10, abs(error - 1000) % 10);
> 
>   /* Allow a 1% error */
>   if (error < 1010 && error >= 990) {

Is there anything I can do to help getting this patch mainline?

Cheers,
Mark

Mark Jonas 

Building Technologies, Panel Software Fire (BT-FIR/ENG1-Grb)
Bosch Sicherheitssysteme GmbH | Postfach 11 11 | 85626 Grasbrunn | GERMANY | 
www.boschsecurity.com

Sitz: Stuttgart, Registergericht: Amtsgericht Stuttgart HRB 23118
Aufsichtsratsvorsitzender: Christian Fischer; Geschäftsführung: Thomas Quante, 
Peter Löffler, Henrik Siegle


Re: [PATCH v2] drm/msm/dp: always add fail-safe mode into connector mode list

2022-02-14 Thread Kuogee Hsieh

Hi Stephen,

Are you have more comments?


On 1/24/2022 3:17 PM, Kuogee Hsieh wrote:

Some of DP link compliant test expects to return fail-safe mode
if prefer detailed timing mode can not be supported by mainlink's
lane and rate after link training. Therefore add fail-safe mode
into connector mode list as backup mode. This patch fixes test
case 4.2.2.1.

Changes in v2:
-- add Fixes text string

Fixes: 4b85d405cfe9 ( "drm/msm/dp: reduce link rate if failed at link training 
1")
Signed-off-by: Kuogee Hsieh 
---
  drivers/gpu/drm/msm/dp/dp_panel.c | 5 +
  1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/msm/dp/dp_panel.c 
b/drivers/gpu/drm/msm/dp/dp_panel.c
index 71db10c..f141872 100644
--- a/drivers/gpu/drm/msm/dp/dp_panel.c
+++ b/drivers/gpu/drm/msm/dp/dp_panel.c
@@ -212,6 +212,11 @@ int dp_panel_read_sink_caps(struct dp_panel *dp_panel,
if (drm_add_modes_noedid(connector, 640, 480))
drm_set_preferred_mode(connector, 640, 480);
mutex_unlock(>dev->mode_config.mutex);
+   } else {
+   /* always add fail-safe mode as backup mode */
+   mutex_lock(>dev->mode_config.mutex);
+   drm_add_modes_noedid(connector, 640, 480);
+   mutex_unlock(>dev->mode_config.mutex);
}
  
  	if (panel->aux_cfg_update_done) {


Re: [PATCH] drm/nouveau/bios: Use HWSQ entry 1 for PowerBook6,1

2022-02-14 Thread Icenowy Zheng
在 2022-02-14星期一的 11:07 -0500,Ilia Mirkin写道:
> I'm not saying this is wrong, but could you file a bug at
> gitlab.freedesktop.org/drm/nouveau/-/issues and include the VBIOS
> (/sys/kernel/debug/dri/0/vbios.rom)? That would make it easier to
> review the full situation.

Created at https://gitlab.freedesktop.org/drm/nouveau/-/issues/158 .

> 
> On Mon, Feb 14, 2022 at 11:03 AM Icenowy Zheng  wrote:
> > 
> > On PowerBook6,1 (PowerBook G4 867 12") HWSQ entry 0 (which is
> > currently
> > always used by nouveau) fails, but the BIOS declares 2 HWSQ entries
> > and
> > entry 1 works.
> > 
> > Add a quirk to use HWSQ entry 1.
> > 
> > Signed-off-by: Icenowy Zheng 
> > ---
> >  drivers/gpu/drm/nouveau/nouveau_bios.c | 7 +++
> >  1 file changed, 7 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c
> > b/drivers/gpu/drm/nouveau/nouveau_bios.c
> > index e8c445eb11004..2691d0e0cf9f1 100644
> > --- a/drivers/gpu/drm/nouveau/nouveau_bios.c
> > +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
> > @@ -1977,6 +1977,13 @@ static int load_nv17_hw_sequencer_ucode(struct
> > drm_device *dev,
> >     if (!hwsq_offset)
> >     return 0;
> > 
> > +#ifdef __powerpc__
> > +   /* HWSQ entry 0 fails on PowerBook G4 867 12" (Al) */
> > +   if (of_machine_is_compatible("PowerBook6,1"))
> > +   return load_nv17_hwsq_ucode_entry(dev, bios,
> > + hwsq_offset + sz,
> > 1);
> > +#endif
> > +
> >     /* always use entry 0? */
> >     return load_nv17_hwsq_ucode_entry(dev, bios, hwsq_offset +
> > sz, 0);
> >  }
> > --
> > 2.30.2
> > 




Re: [PATCH 9/9] drm/panfrost: Handle arm,mali-valhall compatible

2022-02-14 Thread Steven Price
On 11/02/2022 20:27, alyssa.rosenzw...@collabora.com wrote:
> From: Alyssa Rosenzweig 
> 
> The most important Valhall-specific quirks have been handled, so add the
> Valhall compatible and probe.
> 
> Signed-off-by: Alyssa Rosenzweig 

Reviewed-by: Steven Price 

> ---
>  drivers/gpu/drm/panfrost/panfrost_drv.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c 
> b/drivers/gpu/drm/panfrost/panfrost_drv.c
> index 96bb5a465627..12977454af75 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_drv.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
> @@ -663,6 +663,7 @@ static const struct of_device_id dt_match[] = {
>   { .compatible = "arm,mali-t860", .data = _data, },
>   { .compatible = "arm,mali-t880", .data = _data, },
>   { .compatible = "arm,mali-bifrost", .data = _data, },
> + { .compatible = "arm,mali-valhall", .data = _data, },
>   { .compatible = "mediatek,mt8183-mali", .data = _mt8183_data },
>   {}
>  };



Re: [PATCH 8/9] drm/panfrost: Add Mali-G57 "Natt" support

2022-02-14 Thread Steven Price
On 11/02/2022 20:27, alyssa.rosenzw...@collabora.com wrote:
> From: Alyssa Rosenzweig 
> 
> Add the features, issues, and GPU ID for Mali-G57, a first-generation
> Valhall GPU. Other first- and second-generation Valhall GPUs should be
> similar.
> 
> Signed-off-by: Alyssa Rosenzweig 
> ---
>  drivers/gpu/drm/panfrost/panfrost_features.h | 12 
>  drivers/gpu/drm/panfrost/panfrost_gpu.c  |  2 ++
>  drivers/gpu/drm/panfrost/panfrost_issues.h   |  5 +
>  3 files changed, 19 insertions(+)
> 
> diff --git a/drivers/gpu/drm/panfrost/panfrost_features.h 
> b/drivers/gpu/drm/panfrost/panfrost_features.h
> index 1a8bdebc86a3..7ed0cd3ea2d4 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_features.h
> +++ b/drivers/gpu/drm/panfrost/panfrost_features.h
> @@ -106,6 +106,18 @@ enum panfrost_hw_feature {
>   BIT_ULL(HW_FEATURE_TLS_HASHING) | \
>   BIT_ULL(HW_FEATURE_3BIT_EXT_RW_L2_MMU_CONFIG))
>  
> +#define hw_features_g57 (\
> + BIT_ULL(HW_FEATURE_JOBCHAIN_DISAMBIGUATION) | \
> + BIT_ULL(HW_FEATURE_PWRON_DURING_PWROFF_TRANS) | \
> + BIT_ULL(HW_FEATURE_XAFFINITY) | \
> + BIT_ULL(HW_FEATURE_FLUSH_REDUCTION) | \
> + BIT_ULL(HW_FEATURE_PROTECTED_MODE) | \
> + BIT_ULL(HW_FEATURE_PROTECTED_DEBUG_MODE) | \
> + BIT_ULL(HW_FEATURE_COHERENCY_REG) | \
> + BIT_ULL(HW_FEATURE_AARCH64_MMU) | \
> + BIT_ULL(HW_FEATURE_IDVS_GROUP_SIZE) | \
> + BIT_ULL(HW_FEATURE_CLEAN_ONLY_SAFE))
> +
>  static inline bool panfrost_has_hw_feature(struct panfrost_device *pfdev,
>  enum panfrost_hw_feature feat)
>  {
> diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.c 
> b/drivers/gpu/drm/panfrost/panfrost_gpu.c
> index 73e5774f01c1..08d657527099 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_gpu.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_gpu.c
> @@ -201,6 +201,8 @@ static const struct panfrost_model gpu_models[] = {
>   GPU_MODEL(g52, 0x7002),
>   GPU_MODEL(g31, 0x7003,
>   GPU_REV(g31, 1, 0)),
> +
> + GPU_MODEL(g57, 0x9001),
>  };
>  
>  static void panfrost_gpu_init_features(struct panfrost_device *pfdev)
> diff --git a/drivers/gpu/drm/panfrost/panfrost_issues.h 
> b/drivers/gpu/drm/panfrost/panfrost_issues.h
> index b8865fc9efce..1a0dc7f7f857 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_issues.h
> +++ b/drivers/gpu/drm/panfrost/panfrost_issues.h
> @@ -258,6 +258,11 @@ enum panfrost_hw_issue {
>  
>  #define hw_issues_g76 0
>  
> +#define hw_issues_g57 (\
> + BIT_ULL(HW_ISSUE_TTRX_2968_TTRX_3162) | \
> + BIT_ULL(HW_ISSUE_TTRX_3076) | \
> + BIT_ULL(HW_ISSUE_TTRX_3485))

Do you know whether you have an r0p0 or an r0p1 Natt? Only the r0p0 has
the 3485 issue, and we might be lucky and it's the r0p1 that's "in the
wild".

It would be good to annotate these lists with the hardware revisions
when there is a difference.

Steve

> +
>  static inline bool panfrost_has_hw_issue(const struct panfrost_device *pfdev,
>enum panfrost_hw_issue issue)
>  {



Re: [PATCH 7/9] drm/panfrost: Don't set L2_MMU_CONFIG quirks

2022-02-14 Thread Steven Price
On 11/02/2022 20:27, alyssa.rosenzw...@collabora.com wrote:
> From: Alyssa Rosenzweig 
> 
> L2_MMU_CONFIG is an implementation-defined register. Different Mali GPUs
> define slightly different MAX_READS and MAX_WRITES fields, which
> throttle outstanding reads and writes when set to non-zero values. When
> left as zero, reads and writes are not throttled.
> 
> Both kbase and panfrost always zero these registers. Per discussion with
> Steven Price, there are two reasons these quirks may be used:
> 
> 1. Simulating slower memory subsystems. This use case is only of
>interest to system-on-chip designers; it is not relevant to mainline.
> 
> 2. Working around broken memory subsystems. Hopefully we never see this
>case in mainline. If we do, we'll need to set this register based on
>an SoC-compatible, rather than generally matching on the GPU model.
> 
> To the best of our knowledge, these fields are zero at reset, so the
> write is not necessary. Let's remove the write to aid porting to new
> Mali GPUs, which have different layouts for the L2_MMU_CONFIG register.
> 
> Signed-off-by: Alyssa Rosenzweig 
> Suggested-by: Steven Price 

Reviewed-by: Steven Price 

> ---
>  drivers/gpu/drm/panfrost/panfrost_gpu.c | 12 
>  1 file changed, 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.c 
> b/drivers/gpu/drm/panfrost/panfrost_gpu.c
> index 1c1e2017aa80..73e5774f01c1 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_gpu.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_gpu.c
> @@ -127,18 +127,6 @@ static void panfrost_gpu_init_quirks(struct 
> panfrost_device *pfdev)
>   gpu_write(pfdev, GPU_TILER_CONFIG, quirks);
>  
>  
> - quirks = gpu_read(pfdev, GPU_L2_MMU_CONFIG);
> -
> - /* Limit read & write ID width for AXI */
> - if (panfrost_has_hw_feature(pfdev, 
> HW_FEATURE_3BIT_EXT_RW_L2_MMU_CONFIG))
> - quirks &= ~(L2_MMU_CONFIG_3BIT_LIMIT_EXTERNAL_READS |
> - L2_MMU_CONFIG_3BIT_LIMIT_EXTERNAL_WRITES);
> - else
> - quirks &= ~(L2_MMU_CONFIG_LIMIT_EXTERNAL_READS |
> - L2_MMU_CONFIG_LIMIT_EXTERNAL_WRITES);
> -
> - gpu_write(pfdev, GPU_L2_MMU_CONFIG, quirks);
> -
>   quirks = 0;
>   if ((panfrost_model_eq(pfdev, 0x860) || panfrost_model_eq(pfdev, 
> 0x880)) &&
>   pfdev->features.revision >= 0x2000)



Re: [PATCH 6/9] drm/panfrost: Add "clean only safe" feature bit

2022-02-14 Thread Steven Price
On 11/02/2022 20:27, alyssa.rosenzw...@collabora.com wrote:
> From: Alyssa Rosenzweig 
> 
> Add the HW_FEATURE_CLEAN_ONLY_SAFE bit based on kbase. When I actually
> tried to port the logic from kbase, trivial jobs raised Data Invalid
> Faults, so this may depend on other coherency details. It's still useful
> to have the bit to record the feature bit when adding new models.
> 
> Signed-off-by: Alyssa Rosenzweig 

Reviewed-by: Steven Price 

Sadly I don't have the hardware to try this out on, but it should be a
simple case of the below (untested):

8<
diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c 
b/drivers/gpu/drm/panfrost/panfrost_job.c
index 908d79520853..602e51c4966e 100644
--- a/drivers/gpu/drm/panfrost/panfrost_job.c
+++ b/drivers/gpu/drm/panfrost/panfrost_job.c
@@ -212,9 +212,13 @@ static void panfrost_job_hw_submit(struct panfrost_job 
*job, int js)
 * start */
cfg |= JS_CONFIG_THREAD_PRI(8) |
JS_CONFIG_START_FLUSH_CLEAN_INVALIDATE |
-   JS_CONFIG_END_FLUSH_CLEAN_INVALIDATE |
panfrost_get_job_chain_flag(job);
 
+   if (panfrost_has_hw_feature(pfdev, HW_FEATURE_CLEAN_ONLY_SAFE))
+   cfg |= JS_CONFIG_END_FLUSH_CLEAN;
+   else
+   cfg |= JS_CONFIG_END_FLUSH_CLEAN_INVALIDATE;
+
if (panfrost_has_hw_feature(pfdev, HW_FEATURE_FLUSH_REDUCTION))
cfg |= JS_CONFIG_ENABLE_FLUSH_REDUCTION;
 
8<

Steve

> ---
>  drivers/gpu/drm/panfrost/panfrost_features.h | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpu/drm/panfrost/panfrost_features.h 
> b/drivers/gpu/drm/panfrost/panfrost_features.h
> index 36fadcf9634e..1a8bdebc86a3 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_features.h
> +++ b/drivers/gpu/drm/panfrost/panfrost_features.h
> @@ -21,6 +21,7 @@ enum panfrost_hw_feature {
>   HW_FEATURE_TLS_HASHING,
>   HW_FEATURE_THREAD_GROUP_SPLIT,
>   HW_FEATURE_IDVS_GROUP_SIZE,
> + HW_FEATURE_CLEAN_ONLY_SAFE,
>   HW_FEATURE_3BIT_EXT_RW_L2_MMU_CONFIG,
>  };
>  



Re: [PATCH 5/9] drm/panfrost: Add HW_ISSUE_TTRX_3485 quirk

2022-02-14 Thread Steven Price
On 11/02/2022 20:27, alyssa.rosenzw...@collabora.com wrote:
> From: Alyssa Rosenzweig 
> 
> TTRX_3485 requires the infamous "dummy job" workaround. I have this
> workaround implemented in a local branch, but I have not yet hit a case
> that requires it so I cannot test whether the implementation is correct.
> In the mean time, add the quirk bit so we can document which platforms
> may need it in the future.

This one is hideous ;) Although to me this isn't the 'infamous' one as
it's not the earliest example of a dummy job.

However... I believe as Panfrost currently stands this is probably not
very possible to hit. It requires a job to be stopped (soft or hard) at
a critical point during submission - which at the moment Panfrost
basically never does (the exception is if you close the fd immediately
while a job is in progress). And of course the timing has to be 'just
right' to hit the bug.

That said I think we should probably add pre-emption support sometime at
which point this could become an issue.

> Signed-off-by: Alyssa Rosenzweig 

Reviewed-by: Steven Price 

> ---
>  drivers/gpu/drm/panfrost/panfrost_issues.h | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/gpu/drm/panfrost/panfrost_issues.h 
> b/drivers/gpu/drm/panfrost/panfrost_issues.h
> index 058f6a4c8435..b8865fc9efce 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_issues.h
> +++ b/drivers/gpu/drm/panfrost/panfrost_issues.h
> @@ -132,6 +132,9 @@ enum panfrost_hw_issue {
>* to hang */
>   HW_ISSUE_TTRX_3076,
>  
> + /* Must issue a dummy job before starting real work to prevent hangs */
> + HW_ISSUE_TTRX_3485,
> +
>   HW_ISSUE_END
>  };
>  



Re: [PATCH 4/9] drm/panfrost: Handle HW_ISSUE_TTRX_3076

2022-02-14 Thread Steven Price
On 11/02/2022 20:27, alyssa.rosenzw...@collabora.com wrote:
> From: Alyssa Rosenzweig 
> 
> Some Valhall GPUs require resets when encountering bus faults due to
> occlusion query writes. Add the issue bit for this and handle it.
> 
> Signed-off-by: Alyssa Rosenzweig 

Reviewed-by: Steven Price 
(although one nit below)

Just in case any one is wondering - these bus faults occur when
switching the GPU's MMU to unmapped - it's not a normal "bus fault" from
the external bus. This is triggered by an attempt to read unmapped
memory which is completed by the driver by switching the entire MMU to
unmapped.

> ---
>  drivers/gpu/drm/panfrost/panfrost_device.c | 9 +++--
>  drivers/gpu/drm/panfrost/panfrost_issues.h | 4 
>  2 files changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c 
> b/drivers/gpu/drm/panfrost/panfrost_device.c
> index 7f51a4682ccb..ee612303f076 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_device.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_device.c
> @@ -11,6 +11,7 @@
>  #include "panfrost_device.h"
>  #include "panfrost_devfreq.h"
>  #include "panfrost_features.h"
> +#include "panfrost_issues.h"
>  #include "panfrost_gpu.h"
>  #include "panfrost_job.h"
>  #include "panfrost_mmu.h"
> @@ -380,9 +381,13 @@ const char *panfrost_exception_name(u32 exception_code)
>  bool panfrost_exception_needs_reset(const struct panfrost_device *pfdev,
>   u32 exception_code)
>  {
> - /* Right now, none of the GPU we support need a reset, but this
> -  * might change.
> + /* If an occlusion query write causes a bus fault on affected GPUs,
> +  * future fragment jobs may hang. Reset to workaround.
>*/
> + if (exception_code == DRM_PANFROST_EXCEPTION_JOB_BUS_FAULT)
> + return panfrost_has_hw_issue(pfdev, HW_ISSUE_TTRX_3076);
> +
> + /* No other GPUs we support need a reset */
>   return false;
>  }
>  
> diff --git a/drivers/gpu/drm/panfrost/panfrost_issues.h 
> b/drivers/gpu/drm/panfrost/panfrost_issues.h
> index a66692663833..058f6a4c8435 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_issues.h
> +++ b/drivers/gpu/drm/panfrost/panfrost_issues.h
> @@ -128,6 +128,10 @@ enum panfrost_hw_issue {
>   /* Must set SC_VAR_ALGORITHM */
>   HW_ISSUE_TTRX_2968_TTRX_3162,
>  
> + /* Bus fault from occlusion query write may cause future fragment jobs
> +  * to hang */

NIT: Kernel comment style has the "/*" and "*/" on lines by themselves
for multi-line comments. checkpatch will complain!

> + HW_ISSUE_TTRX_3076,
> +
>   HW_ISSUE_END
>  };
>  



Re: [PATCH 3/9] drm/panfrost: Constify argument to has_hw_issue

2022-02-14 Thread Steven Price
On 11/02/2022 20:27, alyssa.rosenzw...@collabora.com wrote:
> From: Alyssa Rosenzweig 
> 
> Logically, this function is free of side effects, so any pointers it
> takes should be const. Needed to avoid a warning in the next patch.
> 
> Signed-off-by: Alyssa Rosenzweig 

Reviewed-by: Steven Price 

> ---
>  drivers/gpu/drm/panfrost/panfrost_issues.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/panfrost/panfrost_issues.h 
> b/drivers/gpu/drm/panfrost/panfrost_issues.h
> index 3af7d723377e..a66692663833 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_issues.h
> +++ b/drivers/gpu/drm/panfrost/panfrost_issues.h
> @@ -251,7 +251,7 @@ enum panfrost_hw_issue {
>  
>  #define hw_issues_g76 0
>  
> -static inline bool panfrost_has_hw_issue(struct panfrost_device *pfdev,
> +static inline bool panfrost_has_hw_issue(const struct panfrost_device *pfdev,
>enum panfrost_hw_issue issue)
>  {
>   return test_bit(issue, pfdev->features.hw_issues);



Re: [PATCH 2/9] drm/panfrost: Handle HW_ISSUE_TTRX_2968_TTRX_3162

2022-02-14 Thread Steven Price
On 11/02/2022 20:27, alyssa.rosenzw...@collabora.com wrote:
> From: Alyssa Rosenzweig 
> 
> Add handling for the HW_ISSUE_TTRX_2968_TTRX_3162 quirk. Logic ported
> from kbase. kbase lists this workaround as used on Mali-G57.
> 
> Signed-off-by: Alyssa Rosenzweig 

Reviewed-by: Steven Price 

> ---
>  drivers/gpu/drm/panfrost/panfrost_gpu.c| 3 +++
>  drivers/gpu/drm/panfrost/panfrost_issues.h | 3 +++
>  drivers/gpu/drm/panfrost/panfrost_regs.h   | 1 +
>  3 files changed, 7 insertions(+)
> 
> diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.c 
> b/drivers/gpu/drm/panfrost/panfrost_gpu.c
> index 50c8922694d7..1c1e2017aa80 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_gpu.c
> +++ b/drivers/gpu/drm/panfrost/panfrost_gpu.c
> @@ -108,6 +108,9 @@ static void panfrost_gpu_init_quirks(struct 
> panfrost_device *pfdev)
>   quirks |= SC_LS_ALLOW_ATTR_TYPES;
>   }
>  
> + if (panfrost_has_hw_issue(pfdev, HW_ISSUE_TTRX_2968_TTRX_3162))
> + quirks |= SC_VAR_ALGORITHM;
> +
>   if (panfrost_has_hw_feature(pfdev, HW_FEATURE_TLS_HASHING))
>   quirks |= SC_TLS_HASH_ENABLE;
>  
> diff --git a/drivers/gpu/drm/panfrost/panfrost_issues.h 
> b/drivers/gpu/drm/panfrost/panfrost_issues.h
> index 8e59d765bf19..3af7d723377e 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_issues.h
> +++ b/drivers/gpu/drm/panfrost/panfrost_issues.h
> @@ -125,6 +125,9 @@ enum panfrost_hw_issue {
>* kernel must fiddle with L2 caches to prevent data leakage */
>   HW_ISSUE_TGOX_R1_1234,
>  
> + /* Must set SC_VAR_ALGORITHM */
> + HW_ISSUE_TTRX_2968_TTRX_3162,
> +
>   HW_ISSUE_END
>  };
>  
> diff --git a/drivers/gpu/drm/panfrost/panfrost_regs.h 
> b/drivers/gpu/drm/panfrost/panfrost_regs.h
> index 16e776cc82ea..fa1e1af56e17 100644
> --- a/drivers/gpu/drm/panfrost/panfrost_regs.h
> +++ b/drivers/gpu/drm/panfrost/panfrost_regs.h
> @@ -195,6 +195,7 @@
>  #define SC_TLS_HASH_ENABLE   BIT(17)
>  #define SC_LS_ATTR_CHECK_DISABLE BIT(18)
>  #define SC_ENABLE_TEXGRD_FLAGS   BIT(25)
> +#define SC_VAR_ALGORITHM BIT(29)
>  /* End SHADER_CONFIG register */
>  
>  /* TILER_CONFIG register */



  1   2   >