Re: [PATCH] drm/ttm: provide default page protection for UML

2021-09-01 Thread Randy Dunlap

On 9/1/21 10:48 PM, Anton Ivanov wrote:

On 02/09/2021 03:01, Randy Dunlap wrote:

boot_cpu_data [struct cpuinfo_um (on UML)] does not have a struct
member named 'x86', so provide a default page protection mode
for CONFIG_UML.

Mends this build error:
../drivers/gpu/drm/ttm/ttm_module.c: In function ‘ttm_prot_from_caching’:
../drivers/gpu/drm/ttm/ttm_module.c:59:24: error: ‘struct cpuinfo_um’ has no 
member named ‘x86’
   else if (boot_cpu_data.x86 > 3)
 ^

Fixes: 3bf3710e3718 ("drm/ttm: Add a generic TTM memcpy move for page-based 
iomem")
Signed-off-by: Randy Dunlap 
Cc: Thomas Hellström 
Cc: Christian König 
Cc: Huang Rui 
Cc: dri-devel@lists.freedesktop.org
Cc: Jeff Dike 
Cc: Richard Weinberger 
Cc: Anton Ivanov 
Cc: linux...@lists.infradead.org
Cc: David Airlie 
Cc: Daniel Vetter 
---
  drivers/gpu/drm/ttm/ttm_module.c |    4 
  1 file changed, 4 insertions(+)

--- linux-next-20210901.orig/drivers/gpu/drm/ttm/ttm_module.c
+++ linux-next-20210901/drivers/gpu/drm/ttm/ttm_module.c
@@ -53,6 +53,9 @@ pgprot_t ttm_prot_from_caching(enum ttm_
  if (caching == ttm_cached)
  return tmp;
+#ifdef CONFIG_UML
+    tmp = pgprot_noncached(tmp);
+#else
  #if defined(__i386__) || defined(__x86_64__)
  if (caching == ttm_write_combined)
  tmp = pgprot_writecombine(tmp);
@@ -69,6 +72,7 @@ pgprot_t ttm_prot_from_caching(enum ttm_
  #if defined(__sparc__)
  tmp = pgprot_noncached(tmp);
  #endif
+#endif
  return tmp;
  }


Patch looks OK.

I have a question though - why all of DRM is not !UML in config. Not like we 
can use them.


I have no idea about that.
Hopefully one of the (other) UML maintainers can answer you.

thanks.
--
~Randy



RE: [diagnostic TDR mode patches] unify our solution opinions/suggestions in one thread

2021-09-01 Thread Liu, Monk
[AMD Official Use Only]

>>>
I'm not sure I can add much to help this along, I'm sure Alex has some internal 
training,
Once your driver is upstream, it belongs to upstream, you can maintain it, but 
you no longer control it 100%, it's a tradeoff, it's not one companies always 
understand.
Usually people are fine developing away internally, but once interaction with 
other parts of the kernel/subsystem is required they have the realisation that 
they needed to work upstream 6 months earlier.
The best time to interact with upstream was 6 months ago, the second best time 
is now.
<<<

Daniel/AlexD

I didn't mean your changes on AMD driver need my personal approval or review 
... and  I'm totally already get used that our driver is not 100% under control 
by AMDers, 
but supposedly any one from community (including you) who tend to change AMD's 
driver need at least to get approvement from someone in AMD, e.g.: AlexD or 
Christian, doesn't that reasonable?
just like we need your approve if we try to modify DRM-sched, or need 
panfrost's approval if we need to change panfrost code ...

by only CC AMD's engineers looks not quite properly, how do you know if your 
changes (on AMD code part) are conflicting with AMD's on-going internal 
features/refactoring or not ?

Thanks 

--
Monk Liu | Cloud-GPU Core team
--

-Original Message-
From: Dave Airlie  
Sent: Thursday, September 2, 2021 2:51 AM
To: Alex Deucher 
Cc: Liu, Monk ; Daniel Vetter ; Koenig, 
Christian ; Grodzovsky, Andrey 
; Chen, JingWen ; DRI 
Development ; amd-...@lists.freedesktop.org
Subject: Re: [diagnostic TDR mode patches] unify our solution 
opinions/suggestions in one thread

On Thu, 2 Sept 2021 at 01:20, Alex Deucher  wrote:
>
> On Wed, Sep 1, 2021 at 6:19 AM Liu, Monk  wrote:
> >
> > [AMD Official Use Only]
> >
> > Daniel
> >
> > From the link you share it looks you(or someone else) have quite a bunch 
> > patches that changes DRM_SCHED or even amdgpu, by that case before they are 
> > merged to kernel tree I'm wondering if any AMD develop reviewed them ?
> >
> > They looks to me somehow conflicting with what we changed in our repo
> >
> > It is really a chaos for AMDer if someone else out side of AMD changes our 
> > kernel driver (or/and scheduler) without reviewed by AMDer, just like we 
> > are requiring your review if we tend to change scheduler's logic here 
> >
> > This one changes AMD's code: 
> > https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flo
> > re.kernel.org%2Fdri-devel%2F20210625133327.2598825-2-boris.brezillon
> > %40collabora.com%2Fdata=04%7C01%7CMonk.Liu%40amd.com%7C6c507d18
> > d65341ef53bb08d96d7976e6%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%
> > 7C637661190727875969%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJ
> > QIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000sdata=BWJSkKN
> > y2%2BwjxbQrfxGPzuJ5PBpBwB4aV0ZH6QoJGEg%3Dreserved=0
> > And I didn't see any reviewed-by from AMDers ...
> >
> > This one also touches AMD's code: 
> > https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Flo
> > re.kernel.org%2Fdri-devel%2F20200604081224.863494-12-daniel.vetter%4
> > 0ffwll.ch%2Fdata=04%7C01%7CMonk.Liu%40amd.com%7C6c507d18d65341e
> > f53bb08d96d7976e6%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C63766
> > 1190727885929%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2
> > luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000sdata=%2F8vIVXCWjHkM
> > 56pcYI9EvuzhbsZhV9WczkKaBJE67KQ%3Dreserved=0
> > Which is conflicting with one patch we submitted (in our repo 
> > rightnow), and neither see AMDder gave a review-by on this one (let 
> > me know if I missed it)
> >
>
> Monk, this is not how upstream works.  You need to participate.
> That's how communities work.  There's a reason all these discussions 
> happen on public mailing lists.  The patch author can't be expected to 
> know every person on every vendor team to CC with a patch.  If you 
> have concerns, you need to raise them when the patches are being 
> discussed.
>

I'm not sure I can add much to help this along, I'm sure Alex has some internal 
training,

Once your driver is upstream, it belongs to upstream, you can maintain it, but 
you no longer control it 100%, it's a tradeoff, it's not one companies always 
understand.

Usually people are fine developing away internally, but once interaction with 
other parts of the kernel/subsystem is required they have the realisation that 
they needed to work upstream 6 months earlier.

The best time to interact with upstream was 6 months ago, the second best time 
is now.

Dave.


Re: [PATCH v2 2/2] clk: qcom: gcc-sdm660: Remove transient global "xo" clock

2021-09-01 Thread Stephen Boyd
Quoting Marijn Suijten (2021-09-01 01:57:15)
> On 2021-08-31 22:35:56, Stephen Boyd wrote:
> > Quoting Marijn Suijten (2021-08-30 11:24:45)
> > > The DSI PHY/PLL was relying on a global "xo" clock to be found, but the
> > > real clock is named "xo_board" in the DT.  The standard nowadays is to
> > > never use global clock names anymore but require the firmware (DT) to
> > > provide every clock binding explicitly with .fw_name.  The DSI PLLs have
> > > since been converted to this mechanism (specifically 14nm for SDM660)
> > > and this transient clock can now be removed.
> > > 
> > > This issue was originally discovered in:
> > > https://lore.kernel.org/linux-arm-msm/386db1a6-a1cd-3c7d-a88e-dc83f8a1b...@somainline.org/
> > > and prevented the removal of "xo" at that time.
> > > 
> > > Signed-off-by: Marijn Suijten 
> > > ---
> > 
> > Presumably this wants to go with the first one.
> 
> What are you referring to with "the first one"?  This patch can only go
> in after patch 1/2 of this series, unless you are suggesting to squash
> it with Bjorns cleanup and making sure that lands after the fix in the
> DSI?

The first patch in this series.


Re: [PATCH v2 1/2] drm/msm/dsi: Use "ref" fw clock instead of global name for VCO parent

2021-09-01 Thread Stephen Boyd
Quoting Marijn Suijten (2021-09-01 01:49:10)
> Hi Stephen,
> 
> On 2021-08-31 22:35:12, Stephen Boyd wrote:
> > Quoting Marijn Suijten (2021-08-30 16:10:26)
> > > 
> > > I'm 95% sure this shouldn't cause any problems given current DTs and
> > > their history, but that's probably not enough.  This might also impact
> > > DTs that have not yet been upstreamed, but afaik the general stance is
> > > to not care and actually serve as a fair hint/warning before new DTs
> > > make it to the list.
> > > 
> > > If there is a protocol in place to deprecate, warn, and eventually
> > > remove this reliance on global clock names I'm more than happy to add
> > > .name as a temporary fallback, even if likely unneeded.  Otherwise we
> > > might never get rid of it.
> > 
> > I'm not aware of any protocol to deprecate, warn, and remove the
> > fallback name. It's a fallback because it can't ever really be removed.
> 
> That is unfortunate, I was hoping for a breaking "kernel release" at
> some point where we could say "no more, update your DTs first".  But
> that may not be possible in every scenario?
> 
> > Anyway, if you're not willing to add the .name then that's fine.
> 
> I feel like .name has caused more problems for us than it solves, but in
> a fallback position it might be fine.  My main gripe is that I don't
> want DT to rely on the clock to also be discoverable through the clock
> tree, which we've seen on many occasions (not sure if the former was
> done upstream, but: "xo" being renamed to "xo_board", and DSI PLL clocks
> loosing +1 causing a naming mismatch with what mmcc expects, to name
> some examples).  Omitting .name is the only way to enforce that.

The simple approach to take is anything new should use fw_name. The name
member is only there for the backup mode when the DT isn't properly
setup to describe connections between clk controllers. If the code is
new then name can be omitted and everything is OK. Otherwise, if
parent_names was already being used, then most likely it will need to be
set as .name in the clk_parent_data struct to maintain compatibility. If
parent_names was wrong, then it was all broken to begin with and .name
can be omitted.

> 
> > We can
> > deal with the problem easily by adding a .name in the future if someone
> > complains that things aren't working. Sound like a plan? If so, it's
> > probably good to add some sort of note in the commit text so that when
> > the bisector lands on this patch they can realize that this
> > intentionally broke them.
> 
> I'm all for this but lack the industrial knowledge to sign off on the
> approach.  Bjorn and Dmitry should ack/agree before going ahead (you may
> wonder why I'm worrying about getting clock drivers and DT in sync on
> platforms I don't own...):
> 
> We have the following situations:
> - apq8064 used the wrong clock.  Bjorn acknowledged that landing the DT
>   fix in 5.15, and this patch in 5.16 should give enough time for DT to
>   be updated (this is nothing we can fix with .name anyway).
> - msm8974 doesn't have the clock at all.  Dmitry recommended to add
>   .name for this specific case, but I'm wondering if the 5.15 -> 5.16
>   window is enough to update DTs too?
> - msm8916 and sdm845 had the missing "ref" clock added three years ago.
>   Would a 5.16 kernel still work in any meaningful way with a DT that
>   old?
> 
> Should we decide on a case-by-case basis whether to add .name, ie. only
> for (some/all) of the aforementioned SoCs?
> 

I sort of glossed over this, sorry. Hopefully what I wrote above can
guide you and then we shouldn't really need to worry about anything?


Re: [PATCH 1/5] drm: Add drm_fixed_16_16 helper

2021-09-01 Thread Laurent Pinchart
On Wed, Sep 01, 2021 at 09:35:40PM -0400, Alyssa Rosenzweig wrote:
> > Missing documentation :-)
> 
> Ack.
> 
> > > +static inline int drm_fixed_16_16(s32 mult, s32 div)
> > 
> > You should return a s32.
> 
> Ack.
> 
> > The function name isn't very explicit, and departs from the naming
> > scheme of other functions in the same file. As fixed-point numbers are
> > stored in a s64 for the drm_fixp_* helpers, we shouldn't rese the
> > drm_fixp_ prefix, maybe drm_fixp_s16_16_ would be a good prefix. The
> > function should probably be named drm_fixp_s16_16 from_fraction() then,
> > but then the same logic should possibly be replicated to ensure optimal
> > precision. I wonder if it wouldn't be best to simply use
> > drm_fixp_from_fraction() and shift the result right by 16 bits.
> 
> Sure, I'm not attached to the naming ... will wait to hear what colours
> everyone else wants the bikehed painted.
> 
> As for the implementation, I just went with what was used across
> multiple drivers already (no chance of regressions that way) but could
> reuse other helpers if it's better..? If the behaviour changes this goes
> from a trivial cleanup to a much more invasive changeset. I don't own
> half of the hardware here.

But except for msm which may need testing, all other drivers use the
existing FRAC_16_16() macro with constant arguments, so it shouldn't be
difficult to ensure that the new function gives the same results.

-- 
Regards,

Laurent Pinchart


Re: [PATCH 1/5] drm: Add drm_fixed_16_16 helper

2021-09-01 Thread Alyssa Rosenzweig
> Missing documentation :-)

Ack.

> > +static inline int drm_fixed_16_16(s32 mult, s32 div)
> 
> You should return a s32.

Ack.

> The function name isn't very explicit, and departs from the naming
> scheme of other functions in the same file. As fixed-point numbers are
> stored in a s64 for the drm_fixp_* helpers, we shouldn't rese the
> drm_fixp_ prefix, maybe drm_fixp_s16_16_ would be a good prefix. The
> function should probably be named drm_fixp_s16_16 from_fraction() then,
> but then the same logic should possibly be replicated to ensure optimal
> precision. I wonder if it wouldn't be best to simply use
> drm_fixp_from_fraction() and shift the result right by 16 bits.

Sure, I'm not attached to the naming ... will wait to hear what colours
everyone else wants the bikehed painted.

As for the implementation, I just went with what was used across
multiple drivers already (no chance of regressions that way) but could
reuse other helpers if it's better..? If the behaviour changes this goes
from a trivial cleanup to a much more invasive changeset. I don't own
half of the hardware here.


[PATCH] drm/r128: fix build for UML

2021-09-01 Thread Randy Dunlap
Fix a build error on CONFIG_UML, which does not support (provide)
wbinvd(). UML can use the generic mb() instead.

../drivers/gpu/drm/r128/ati_pcigart.c: In function ‘drm_ati_pcigart_init’:
../drivers/gpu/drm/r128/ati_pcigart.c:218:2: error: implicit declaration of 
function ‘wbinvd’ [-Werror=implicit-function-declaration]
  wbinvd();
  ^~

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") # pre-git
Signed-off-by: Randy Dunlap 
Cc: David Airlie 
Cc: Daniel Vetter 
Cc: dri-devel@lists.freedesktop.org
Cc: Jeff Dike 
Cc: Richard Weinberger 
Cc: Anton Ivanov 
Cc: linux...@lists.infradead.org
---
 drivers/gpu/drm/r128/ati_pcigart.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- linux-next-20210901.orig/drivers/gpu/drm/r128/ati_pcigart.c
+++ linux-next-20210901/drivers/gpu/drm/r128/ati_pcigart.c
@@ -214,7 +214,7 @@ int drm_ati_pcigart_init(struct drm_devi
}
ret = 0;
 
-#if defined(__i386__) || defined(__x86_64__)
+#if (defined(__i386__) || defined(__x86_64__)) && !defined(CONFIG_UML)
wbinvd();
 #else
mb();


[PATCH] drm/ttm: provide default page protection for UML

2021-09-01 Thread Randy Dunlap
boot_cpu_data [struct cpuinfo_um (on UML)] does not have a struct
member named 'x86', so provide a default page protection mode
for CONFIG_UML.

Mends this build error:
../drivers/gpu/drm/ttm/ttm_module.c: In function ‘ttm_prot_from_caching’:
../drivers/gpu/drm/ttm/ttm_module.c:59:24: error: ‘struct cpuinfo_um’ has no 
member named ‘x86’
  else if (boot_cpu_data.x86 > 3)
^

Fixes: 3bf3710e3718 ("drm/ttm: Add a generic TTM memcpy move for page-based 
iomem")
Signed-off-by: Randy Dunlap 
Cc: Thomas Hellström 
Cc: Christian König 
Cc: Huang Rui 
Cc: dri-devel@lists.freedesktop.org
Cc: Jeff Dike 
Cc: Richard Weinberger 
Cc: Anton Ivanov 
Cc: linux...@lists.infradead.org
Cc: David Airlie 
Cc: Daniel Vetter 
---
 drivers/gpu/drm/ttm/ttm_module.c |4 
 1 file changed, 4 insertions(+)

--- linux-next-20210901.orig/drivers/gpu/drm/ttm/ttm_module.c
+++ linux-next-20210901/drivers/gpu/drm/ttm/ttm_module.c
@@ -53,6 +53,9 @@ pgprot_t ttm_prot_from_caching(enum ttm_
if (caching == ttm_cached)
return tmp;
 
+#ifdef CONFIG_UML
+   tmp = pgprot_noncached(tmp);
+#else
 #if defined(__i386__) || defined(__x86_64__)
if (caching == ttm_write_combined)
tmp = pgprot_writecombine(tmp);
@@ -69,6 +72,7 @@ pgprot_t ttm_prot_from_caching(enum ttm_
 #if defined(__sparc__)
tmp = pgprot_noncached(tmp);
 #endif
+#endif
return tmp;
 }
 


Re: linux-next: manual merge of the drm tree with the qcom/for-next tree

2021-09-01 Thread Stephen Rothwell
Hi all,

On Mon, 26 Jul 2021 17:38:14 +0100 Mark Brown  wrote:
> 
> Today's linux-next merge of the drm tree got a conflict in:
> 
>   drivers/firmware/Makefile
> 
> between commit:
> 
>   b42000e4b874 ("firmware: qcom_scm: Allow qcom_scm driver to be loadable as 
> a permenent module")
> 
> from the qcom/for-next tree and commits:
> 
>   8633ef82f101 ("drivers/firmware: consolidate EFI framebuffer setup for all 
> arches")
>   d391c5827107 ("drivers/firmware: move x86 Generic System Framebuffers 
> support")
> 
> from the drm tree.
> 
> I fixed it up (see below) and can carry the fix as necessary. This
> is now fixed as far as linux-next is concerned, but any non trivial
> conflicts should be mentioned to your upstream maintainer when your tree
> is submitted for merging.  You may also want to consider cooperating
> with the maintainer of the conflicting tree to minimise any particularly
> complex conflicts.
> 
> diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
> index 3c2af2e98def..5ced0673d94b 100644
> --- a/drivers/firmware/Makefile
> +++ b/drivers/firmware/Makefile
> @@ -19,6 +19,8 @@ obj-$(CONFIG_RASPBERRYPI_FIRMWARE) += raspberrypi.o
>  obj-$(CONFIG_FW_CFG_SYSFS)   += qemu_fw_cfg.o
>  obj-$(CONFIG_QCOM_SCM)   += qcom-scm.o
>  qcom-scm-objs += qcom_scm.o qcom_scm-smc.o qcom_scm-legacy.o
> +obj-$(CONFIG_SYSFB)  += sysfb.o
> +obj-$(CONFIG_SYSFB_SIMPLEFB) += sysfb_simplefb.o
>  obj-$(CONFIG_TI_SCI_PROTOCOL)+= ti_sci.o
>  obj-$(CONFIG_TRUSTED_FOUNDATIONS) += trusted_foundations.o
>  obj-$(CONFIG_TURRIS_MOX_RWTM)+= turris-mox-rwtm.o

This is now a conflict between the arm-soc tree and Linus' tree.

-- 
Cheers,
Stephen Rothwell


pgphs912fm6tO.pgp
Description: OpenPGP digital signature


Re: [PATCH v1 03/14] mm: add iomem vma selection for memory migration

2021-09-01 Thread Dave Chinner
On Wed, Sep 01, 2021 at 07:07:34PM -0400, Felix Kuehling wrote:
> On 2021-09-01 6:03 p.m., Dave Chinner wrote:
> > On Wed, Sep 01, 2021 at 11:40:43AM -0400, Felix Kuehling wrote:
> > > Am 2021-09-01 um 4:29 a.m. schrieb Christoph Hellwig:
> > > > On Mon, Aug 30, 2021 at 01:04:43PM -0400, Felix Kuehling wrote:
> > > > > > > driver code is not really involved in updating the CPU mappings. 
> > > > > > > Maybe
> > > > > > > it's something we need to do in the migration helpers.
> > > > > > It looks like I'm totally misunderstanding what you are adding here
> > > > > > then.  Why do we need any special treatment at all for memory that
> > > > > > has normal struct pages and is part of the direct kernel map?
> > > > > The pages are like normal memory for purposes of mapping them in CPU
> > > > > page tables and for coherent access from the CPU.
> > > > That's the user page tables.  What about the kernel direct map?
> > > > If there is a normal kernel struct page backing there really should
> > > > be no need for the pgmap.
> > > I'm not sure. The physical address ranges are in the UEFI system address
> > > map as special-purpose memory. Does Linux create the struct pages and
> > > kernel direct map for that without a pgmap call? I didn't see that last
> > > time I went digging through that code.
> > > 
> > > 
> > > > >  From an application
> > > > > perspective, we want file-backed and anonymous mappings to be able to
> > > > > use DEVICE_PUBLIC pages with coherent CPU access. The goal is to
> > > > > optimize performance for GPU heavy workloads while minimizing the need
> > > > > to migrate data back-and-forth between system memory and device 
> > > > > memory.
> > > > I don't really understand that part.  file backed pages are always
> > > > allocated by the file system using the pagecache helpers, that is
> > > > using the page allocator.  Anonymouns memory also always comes from
> > > > the page allocator.
> > > I'm coming at this from my experience with DEVICE_PRIVATE. Both
> > > anonymous and file-backed pages should be migrateable to DEVICE_PRIVATE
> > > memory by the migrate_vma_* helpers for more efficient access by our
> > > GPU. (*) It's part of the basic premise of HMM as I understand it. I
> > > would expect the same thing to work for DEVICE_PUBLIC memory.
> > > 
> > > (*) I believe migrating file-backed pages to DEVICE_PRIVATE doesn't
> > > currently work, but that's something I'm hoping to fix at some point.
> > FWIW, I'd love to see the architecture documents that define how
> > filesystems are supposed to interact with this device private
> > memory. This whole "hand filesystem controlled memory to other
> > devices" is a minefield that is trivial to get wrong iand very
> > difficult to fix - just look at the historical mess that RDMA
> > to/from file backed and/or DAX pages has been.
> > 
> > So, really, from my perspective as a filesystem engineer, I want to
> > see an actual specification for how this new memory type is going to
> > interact with filesystem and the page cache so everyone has some
> > idea of how this is going to work and can point out how it doesn't
> > work before code that simply doesn't work is pushed out into
> > production systems and then merged
> 
> OK. To be clear, that's not part of this patch series. And I have no
> authority to push anything in this part of the kernel, so you have nothing
> to fear. ;)

I know this isn't part of the series. but this patchset is laying
the foundation for future work that will impact subsystems that
currently have zero visibility and/or knowledge of these changes.
There must be an overall architectural plan for this functionality,
regardless of the current state of implementation. It's that overall
architectural plan I'm asking about here, because I need to
understand that before I can sanely comment on the page
cache/filesystem aspect of the proposed functionality...

> FWIW, we already have the ability to map file-backed system memory pages
> into device page tables with HMM and interval notifiers. But we cannot
> currently migrate them to ZONE_DEVICE pages.

Sure, but sharing page cache pages allocated and managed by the
filesystem is not what you are talking about. You're talking about
migrating page cache data to completely different memory allocated
by a different memory manager that the filesystems currently have no
knowledge of or have any way of interfacing with.

So I'm asking basic, fundamental questions about how these special
device based pages are going to work.  How are these pages different
to normal pages - does page_lock() still guarantee exclusive access
to the page state across all hardware that can access it? If not,
what provides access serialisation for pages that are allocated in
device memory rather than CPU memory (e.g. for truncate
serialisation)?  Does the hardware that own these pages raise page
faults on the CPU when those pages are accessed/dirtied? How does
demand paging in and out of device 

[PATCH v5 22/25] drm/i915/guc: Move GuC priority fields in context under guc_active

2021-09-01 Thread Daniele Ceraolo Spurio
From: Matthew Brost 

Move GuC management fields in context under guc_active struct as this is
where the lock that protects theses fields lives. Also only set guc_prio
field once during context init.

v2:
 (Daniele)
  - set CONTEXT_SET_INIT

Signed-off-by: Matthew Brost 
Reviewed-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/intel_context_types.h | 12 ++--
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 69 +++
 drivers/gpu/drm/i915/i915_trace.h |  2 +-
 3 files changed, 46 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h 
b/drivers/gpu/drm/i915/gt/intel_context_types.h
index 3a5d98e908f4..b56960a781da 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -112,6 +112,7 @@ struct intel_context {
 #define CONTEXT_FORCE_SINGLE_SUBMISSION7
 #define CONTEXT_NOPREEMPT  8
 #define CONTEXT_LRCA_DIRTY 9
+#define CONTEXT_GUC_INIT   10
 
struct {
u64 timeout_us;
@@ -178,6 +179,11 @@ struct intel_context {
spinlock_t lock;
/** requests: active requests on this context */
struct list_head requests;
+   /*
+* GuC priority management
+*/
+   u8 prio;
+   u32 prio_count[GUC_CLIENT_PRIORITY_NUM];
} guc_active;
 
/* GuC LRC descriptor ID */
@@ -191,12 +197,6 @@ struct intel_context {
 */
struct list_head guc_id_link;
 
-   /*
-* GuC priority management
-*/
-   u8 guc_prio;
-   u32 guc_prio_count[GUC_CLIENT_PRIORITY_NUM];
-
 #ifdef CONFIG_DRM_I915_SELFTEST
/**
 * @drop_schedule_enable: Force drop of schedule enable G2H for selftest
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 440ddcaae627..7f8472ae3f19 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1368,8 +1368,6 @@ static void guc_context_policy_init(struct 
intel_engine_cs *engine,
desc->preemption_timeout = engine->props.preempt_timeout_ms * 1000;
 }
 
-static inline u8 map_i915_prio_to_guc_prio(int prio);
-
 static int guc_lrc_desc_pin(struct intel_context *ce, bool loop)
 {
struct intel_engine_cs *engine = ce->engine;
@@ -1377,8 +1375,6 @@ static int guc_lrc_desc_pin(struct intel_context *ce, 
bool loop)
struct intel_guc *guc = >gt->uc.guc;
u32 desc_idx = ce->guc_id;
struct guc_lrc_desc *desc;
-   const struct i915_gem_context *ctx;
-   int prio = I915_CONTEXT_DEFAULT_PRIORITY;
bool context_registered;
intel_wakeref_t wakeref;
int ret = 0;
@@ -1395,12 +1391,6 @@ static int guc_lrc_desc_pin(struct intel_context *ce, 
bool loop)
 
context_registered = lrc_desc_registered(guc, desc_idx);
 
-   rcu_read_lock();
-   ctx = rcu_dereference(ce->gem_context);
-   if (ctx)
-   prio = ctx->sched.priority;
-   rcu_read_unlock();
-
reset_lrc_desc(guc, desc_idx);
set_lrc_desc_registered(guc, desc_idx, ce);
 
@@ -1409,8 +1399,7 @@ static int guc_lrc_desc_pin(struct intel_context *ce, 
bool loop)
desc->engine_submit_mask = adjust_engine_mask(engine->class,
  engine->mask);
desc->hw_context_desc = ce->lrc.lrca;
-   ce->guc_prio = map_i915_prio_to_guc_prio(prio);
-   desc->priority = ce->guc_prio;
+   desc->priority = ce->guc_active.prio;
desc->context_flags = CONTEXT_REGISTRATION_FLAG_KMD;
guc_context_policy_init(engine, desc);
 
@@ -1805,10 +1794,10 @@ static inline void guc_lrc_desc_unpin(struct 
intel_context *ce)
 
 static void __guc_context_destroy(struct intel_context *ce)
 {
-   GEM_BUG_ON(ce->guc_prio_count[GUC_CLIENT_PRIORITY_KMD_HIGH] ||
-  ce->guc_prio_count[GUC_CLIENT_PRIORITY_HIGH] ||
-  ce->guc_prio_count[GUC_CLIENT_PRIORITY_KMD_NORMAL] ||
-  ce->guc_prio_count[GUC_CLIENT_PRIORITY_NORMAL]);
+   GEM_BUG_ON(ce->guc_active.prio_count[GUC_CLIENT_PRIORITY_KMD_HIGH] ||
+  ce->guc_active.prio_count[GUC_CLIENT_PRIORITY_HIGH] ||
+  ce->guc_active.prio_count[GUC_CLIENT_PRIORITY_KMD_NORMAL] ||
+  ce->guc_active.prio_count[GUC_CLIENT_PRIORITY_NORMAL]);
GEM_BUG_ON(ce->guc_state.number_committed_requests);
 
lrc_fini(ce);
@@ -1918,14 +1907,17 @@ static void guc_context_set_prio(struct intel_guc *guc,
 
GEM_BUG_ON(prio < GUC_CLIENT_PRIORITY_KMD_HIGH ||
   prio > GUC_CLIENT_PRIORITY_NORMAL);
+   lockdep_assert_held(>guc_active.lock);
 
-   if (ce->guc_prio == prio || submission_disabled(guc) ||
-   !context_registered(ce))
+   if (ce->guc_active.prio == prio || 

[PATCH v5 25/25] drm/i915/guc: Add GuC kernel doc

2021-09-01 Thread Daniele Ceraolo Spurio
From: Matthew Brost 

Add GuC kernel doc for all structures added thus far for GuC submission
and update the main GuC submission section with the new interface
details.

v2:
 - Drop guc_active.lock DOC
v3:
 - Fixup a few kernel doc comments (Daniele)
v4 (Daniele):
 - Implement doc suggestions from John
 - Add kerneldoc for all members of the GuC structure and pull the file
   in i915.rst

Signed-off-by: Matthew Brost 
Signed-off-by: Daniele Ceraolo Spurio 
Cc: John Harrison 
---
 Documentation/gpu/i915.rst|   2 +
 drivers/gpu/drm/i915/gt/intel_context_types.h |  43 +---
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|  68 +---
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 100 ++
 drivers/gpu/drm/i915/i915_request.h   |  21 ++--
 5 files changed, 174 insertions(+), 60 deletions(-)

diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst
index 101dde3eb1ea..311e10400708 100644
--- a/Documentation/gpu/i915.rst
+++ b/Documentation/gpu/i915.rst
@@ -495,6 +495,8 @@ GuC
 .. kernel-doc:: drivers/gpu/drm/i915/gt/uc/intel_guc.c
:doc: GuC
 
+.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/intel_guc.h
+
 GuC Firmware Layout
 ~~~
 
diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h 
b/drivers/gpu/drm/i915/gt/intel_context_types.h
index 5285d660eacf..930569a1a01f 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -156,40 +156,51 @@ struct intel_context {
u8 wa_bb_page; /* if set, page num reserved for context workarounds */
 
struct {
-   /** lock: protects everything in guc_state */
+   /** @lock: protects everything in guc_state */
spinlock_t lock;
/**
-* sched_state: scheduling state of this context using GuC
+* @sched_state: scheduling state of this context using GuC
 * submission
 */
u32 sched_state;
/*
-* fences: maintains of list of requests that have a submit
-* fence related to GuC submission
+* @fences: maintains a list of requests that are currently
+* being fenced until a GuC operation completes
 */
struct list_head fences;
-   /* GuC context blocked fence */
+   /**
+* @blocked: fence used to signal when the blocking of a
+* context's submissions is complete.
+*/
struct i915_sw_fence blocked;
-   /* GuC committed requests */
+   /** @number_committed_requests: number of committed requests */
int number_committed_requests;
-   /** requests: active requests on this context */
+   /** @requests: list of active requests on this context */
struct list_head requests;
-   /*
-* GuC priority management
-*/
+   /** @prio: the context's current guc priority */
u8 prio;
+   /**
+* @prio_count: a counter of the number requests in flight in
+* each priority bucket
+*/
u32 prio_count[GUC_CLIENT_PRIORITY_NUM];
} guc_state;
 
struct {
-   /* GuC LRC descriptor ID */
+   /**
+* @id: handle which is used to uniquely identify this context
+* with the GuC, protected by guc->contexts_lock
+*/
u16 id;
-
-   /* GuC LRC descriptor reference count */
+   /**
+* @ref: the number of references to the guc_id, when
+* transitioning in and out of zero protected by
+* guc->contexts_lock
+*/
atomic_t ref;
-
-   /*
-* GuC ID link - in list when unpinned but guc_id still valid 
in GuC
+   /**
+* @link: in guc->guc_id_list when the guc_id has no refs but is
+* still valid, protected by guc->contexts_lock
 */
struct list_head link;
} guc_id;
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 2e27fe59786b..8427cd590087 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -22,74 +22,114 @@
 
 struct __guc_ads_blob;
 
-/*
- * Top level structure of GuC. It handles firmware loading and manages client
- * pool. intel_guc owns a intel_guc_client to replace the legacy ExecList
- * submission.
+/**
+ * struct intel_guc - Top level structure of GuC.
+ *
+ * It handles firmware loading and manages client pool. intel_guc owns an
+ * i915_sched_engine to replace the legacy ExecList submission.
  */
 struct intel_guc {
+   

[PATCH v5 23/25] drm/i915/guc: Move fields protected by guc->contexts_lock into sub structure

2021-09-01 Thread Daniele Ceraolo Spurio
From: Matthew Brost 

To make ownership of locking clear move fields (guc_id, guc_id_ref,
guc_id_link) to sub structure guc_id in intel_context.

Reviewed-by: Daniele Ceraolo Spurio 
Signed-off-by: Matthew Brost 
---
 drivers/gpu/drm/i915/gt/intel_context.c   |   4 +-
 drivers/gpu/drm/i915/gt/intel_context_types.h |  18 +--
 drivers/gpu/drm/i915/gt/selftest_hangcheck.c  |   6 +-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 104 +-
 drivers/gpu/drm/i915/i915_trace.h |   4 +-
 5 files changed, 69 insertions(+), 67 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index 3048267ddc7e..485460a11331 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -398,8 +398,8 @@ intel_context_init(struct intel_context *ce, struct 
intel_engine_cs *engine)
spin_lock_init(>guc_active.lock);
INIT_LIST_HEAD(>guc_active.requests);
 
-   ce->guc_id = GUC_INVALID_LRC_ID;
-   INIT_LIST_HEAD(>guc_id_link);
+   ce->guc_id.id = GUC_INVALID_LRC_ID;
+   INIT_LIST_HEAD(>guc_id.link);
 
/*
 * Initialize fence to be complete as this is expected to be complete
diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h 
b/drivers/gpu/drm/i915/gt/intel_context_types.h
index b56960a781da..0b00d249c884 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -186,16 +186,18 @@ struct intel_context {
u32 prio_count[GUC_CLIENT_PRIORITY_NUM];
} guc_active;
 
-   /* GuC LRC descriptor ID */
-   u16 guc_id;
+   struct {
+   /* GuC LRC descriptor ID */
+   u16 id;
 
-   /* GuC LRC descriptor reference count */
-   atomic_t guc_id_ref;
+   /* GuC LRC descriptor reference count */
+   atomic_t ref;
 
-   /*
-* GuC ID link - in list when unpinned but guc_id still valid in GuC
-*/
-   struct list_head guc_id_link;
+   /*
+* GuC ID link - in list when unpinned but guc_id still valid 
in GuC
+*/
+   struct list_head link;
+   } guc_id;
 
 #ifdef CONFIG_DRM_I915_SELFTEST
/**
diff --git a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c 
b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
index 2c1ed32ca5ac..e9130fa39616 100644
--- a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
+++ b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c
@@ -789,7 +789,7 @@ static int __igt_reset_engine(struct intel_gt *gt, bool 
active)
if (err)
pr_err("[%s] Wait for request %lld:%lld 
[0x%04X] failed: %d!\n",
   engine->name, rq->fence.context,
-  rq->fence.seqno, 
rq->context->guc_id, err);
+  rq->fence.seqno, 
rq->context->guc_id.id, err);
}
 
 skip:
@@ -1098,7 +1098,7 @@ static int __igt_reset_engines(struct intel_gt *gt,
if (err)
pr_err("[%s] Wait for request %lld:%lld 
[0x%04X] failed: %d!\n",
   engine->name, rq->fence.context,
-  rq->fence.seqno, 
rq->context->guc_id, err);
+  rq->fence.seqno, 
rq->context->guc_id.id, err);
}
 
count++;
@@ -1108,7 +1108,7 @@ static int __igt_reset_engines(struct intel_gt *gt,
pr_err("i915_reset_engine(%s:%s): 
failed to reset request %lld:%lld [0x%04X]\n",
   engine->name, test_name,
   rq->fence.context,
-  rq->fence.seqno, 
rq->context->guc_id);
+  rq->fence.seqno, 
rq->context->guc_id.id);
i915_request_put(rq);
 
GEM_TRACE_DUMP();
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 7f8472ae3f19..5a3435c041d1 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -270,12 +270,12 @@ static inline void decr_context_committed_requests(struct 
intel_context *ce)
 
 static inline bool context_guc_id_invalid(struct intel_context *ce)
 {
-   return ce->guc_id == GUC_INVALID_LRC_ID;
+   return ce->guc_id.id == GUC_INVALID_LRC_ID;
 }
 
 static inline void set_context_guc_id_invalid(struct intel_context *ce)
 {
-   ce->guc_id = GUC_INVALID_LRC_ID;
+   ce->guc_id.id = GUC_INVALID_LRC_ID;
 }
 
 static inline struct 

[PATCH v5 24/25] drm/i915/guc: Drop guc_active move everything into guc_state

2021-09-01 Thread Daniele Ceraolo Spurio
From: Matthew Brost 

Now that we have locking hierarchy of sched_engine->lock ->
ce->guc_state everything from guc_active can be moved into guc_state and
protected the guc_state.lock.

Signed-off-by: Matthew Brost 
Reviewed-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/intel_context.c   | 10 +--
 drivers/gpu/drm/i915/gt/intel_context_types.h |  7 +-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 88 +--
 drivers/gpu/drm/i915/i915_trace.h |  2 +-
 4 files changed, 49 insertions(+), 58 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index 485460a11331..ff637147b1a9 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -394,9 +394,7 @@ intel_context_init(struct intel_context *ce, struct 
intel_engine_cs *engine)
 
spin_lock_init(>guc_state.lock);
INIT_LIST_HEAD(>guc_state.fences);
-
-   spin_lock_init(>guc_active.lock);
-   INIT_LIST_HEAD(>guc_active.requests);
+   INIT_LIST_HEAD(>guc_state.requests);
 
ce->guc_id.id = GUC_INVALID_LRC_ID;
INIT_LIST_HEAD(>guc_id.link);
@@ -521,15 +519,15 @@ struct i915_request 
*intel_context_find_active_request(struct intel_context *ce)
 
GEM_BUG_ON(!intel_engine_uses_guc(ce->engine));
 
-   spin_lock_irqsave(>guc_active.lock, flags);
-   list_for_each_entry_reverse(rq, >guc_active.requests,
+   spin_lock_irqsave(>guc_state.lock, flags);
+   list_for_each_entry_reverse(rq, >guc_state.requests,
sched.link) {
if (i915_request_completed(rq))
break;
 
active = rq;
}
-   spin_unlock_irqrestore(>guc_active.lock, flags);
+   spin_unlock_irqrestore(>guc_state.lock, flags);
 
return active;
 }
diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h 
b/drivers/gpu/drm/i915/gt/intel_context_types.h
index 0b00d249c884..5285d660eacf 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -172,11 +172,6 @@ struct intel_context {
struct i915_sw_fence blocked;
/* GuC committed requests */
int number_committed_requests;
-   } guc_state;
-
-   struct {
-   /** lock: protects everything in guc_active */
-   spinlock_t lock;
/** requests: active requests on this context */
struct list_head requests;
/*
@@ -184,7 +179,7 @@ struct intel_context {
 */
u8 prio;
u32 prio_count[GUC_CLIENT_PRIORITY_NUM];
-   } guc_active;
+   } guc_state;
 
struct {
/* GuC LRC descriptor ID */
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 5a3435c041d1..6a894c3b7925 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -829,9 +829,9 @@ __unwind_incomplete_requests(struct intel_context *ce)
unsigned long flags;
 
spin_lock_irqsave(_engine->lock, flags);
-   spin_lock(>guc_active.lock);
+   spin_lock(>guc_state.lock);
list_for_each_entry_safe_reverse(rq, rn,
->guc_active.requests,
+>guc_state.requests,
 sched.link) {
if (i915_request_completed(rq))
continue;
@@ -850,7 +850,7 @@ __unwind_incomplete_requests(struct intel_context *ce)
list_add(>sched.link, pl);
set_bit(I915_FENCE_FLAG_PQUEUE, >fence.flags);
}
-   spin_unlock(>guc_active.lock);
+   spin_unlock(>guc_state.lock);
spin_unlock_irqrestore(_engine->lock, flags);
 }
 
@@ -945,10 +945,10 @@ static void guc_cancel_context_requests(struct 
intel_context *ce)
 
/* Mark all executing requests as skipped. */
spin_lock_irqsave(_engine->lock, flags);
-   spin_lock(>guc_active.lock);
-   list_for_each_entry(rq, >guc_active.requests, sched.link)
+   spin_lock(>guc_state.lock);
+   list_for_each_entry(rq, >guc_state.requests, sched.link)
i915_request_put(i915_request_mark_eio(rq));
-   spin_unlock(>guc_active.lock);
+   spin_unlock(>guc_state.lock);
spin_unlock_irqrestore(_engine->lock, flags);
 }
 
@@ -1399,7 +1399,7 @@ static int guc_lrc_desc_pin(struct intel_context *ce, 
bool loop)
desc->engine_submit_mask = adjust_engine_mask(engine->class,
  engine->mask);
desc->hw_context_desc = ce->lrc.lrca;
-   desc->priority = ce->guc_active.prio;
+   desc->priority = ce->guc_state.prio;
desc->context_flags = CONTEXT_REGISTRATION_FLAG_KMD;

[PATCH v5 16/25] drm/i915/guc: Flush G2H work queue during reset

2021-09-01 Thread Daniele Ceraolo Spurio
From: Matthew Brost 

It isn't safe to scrub for missing G2H or continue with the reset until
all G2H processing is complete. Flush the G2H work queue during reset to
ensure it is done running. No need to call the IRQ handler directly
either as the scrubbing code can deal with any missing G2H.

Fixes: eb5e7da736f3 ("drm/i915/guc: Reset implementation for new GuC interface")
Signed-off-by: Matthew Brost 
Reviewed-by: Daniele Ceraolo Spurio 
---
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c  | 18 ++
 1 file changed, 2 insertions(+), 16 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 dcd7a09f8559..8509e827a8d0 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -716,8 +716,6 @@ static void guc_flush_submissions(struct intel_guc *guc)
 
 void intel_guc_submission_reset_prepare(struct intel_guc *guc)
 {
-   int i;
-
if (unlikely(!guc_submission_initialized(guc))) {
/* Reset called during driver load? GuC not yet initialised! */
return;
@@ -733,20 +731,8 @@ void intel_guc_submission_reset_prepare(struct intel_guc 
*guc)
 
guc_flush_submissions(guc);
 
-   /*
-* Handle any outstanding G2Hs before reset. Call IRQ handler directly
-* each pass as interrupt have been disabled. We always scrub for
-* outstanding G2H as it is possible for outstanding_submission_g2h to
-* be incremented after the context state update.
-*/
-   for (i = 0; i < 4 && atomic_read(>outstanding_submission_g2h); 
++i) {
-   intel_guc_to_host_event_handler(guc);
-#define wait_for_reset(guc, wait_var) \
-   intel_guc_wait_for_pending_msg(guc, wait_var, false, (HZ / 20))
-   do {
-   wait_for_reset(guc, >outstanding_submission_g2h);
-   } while (!list_empty(>ct.requests.incoming));
-   }
+   flush_work(>ct.requests.worker);
+
scrub_guc_desc_for_outstanding_g2h(guc);
 }
 
-- 
2.25.1



[PATCH v5 15/25] drm/i915: Allocate error capture in nowait context

2021-09-01 Thread Daniele Ceraolo Spurio
From: Matthew Brost 

Error captures can now be done in a work queue processing G2H messages.
These messages need to be completely done being processed in the reset
path, to avoid races in the missing G2H cleanup, which create a
dependency on memory allocations and dma fences (i915_requests).
Requests depend on resets, thus now we have a circular dependency. To
work around this, allocate the error capture in a nowait context.

v2:
 (Daniel Vetter)
  - Use GFP_NOWAIT instead GFP_ATOMIC

Fixes: dc0dad365c5e ("Fix for error capture after full GPU reset with GuC")
Fixes: 573ba126aef3 ("Capture error state on context reset")
Signed-off-by: Matthew Brost 
---
 drivers/gpu/drm/i915/i915_gpu_error.c | 39 +--
 1 file changed, 19 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c 
b/drivers/gpu/drm/i915/i915_gpu_error.c
index b9f66dbd46bb..8696ead02118 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -49,8 +49,7 @@
 #include "i915_memcpy.h"
 #include "i915_scatterlist.h"
 
-#define ALLOW_FAIL (GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN)
-#define ATOMIC_MAYFAIL (GFP_ATOMIC | __GFP_NOWARN)
+#define ATOMIC_MAYFAIL (GFP_NOWAIT | __GFP_NOWARN)
 
 static void __sg_set_buf(struct scatterlist *sg,
 void *addr, unsigned int len, loff_t it)
@@ -79,7 +78,7 @@ static bool __i915_error_grow(struct drm_i915_error_state_buf 
*e, size_t len)
if (e->cur == e->end) {
struct scatterlist *sgl;
 
-   sgl = (typeof(sgl))__get_free_page(ALLOW_FAIL);
+   sgl = (typeof(sgl))__get_free_page(ATOMIC_MAYFAIL);
if (!sgl) {
e->err = -ENOMEM;
return false;
@@ -99,10 +98,10 @@ static bool __i915_error_grow(struct 
drm_i915_error_state_buf *e, size_t len)
}
 
e->size = ALIGN(len + 1, SZ_64K);
-   e->buf = kmalloc(e->size, ALLOW_FAIL);
+   e->buf = kmalloc(e->size, ATOMIC_MAYFAIL);
if (!e->buf) {
e->size = PAGE_ALIGN(len + 1);
-   e->buf = kmalloc(e->size, GFP_KERNEL);
+   e->buf = kmalloc(e->size, ATOMIC_MAYFAIL);
}
if (!e->buf) {
e->err = -ENOMEM;
@@ -243,12 +242,12 @@ static bool compress_init(struct i915_vma_compress *c)
 {
struct z_stream_s *zstream = >zstream;
 
-   if (pool_init(>pool, ALLOW_FAIL))
+   if (pool_init(>pool, ATOMIC_MAYFAIL))
return false;
 
zstream->workspace =
kmalloc(zlib_deflate_workspacesize(MAX_WBITS, MAX_MEM_LEVEL),
-   ALLOW_FAIL);
+   ATOMIC_MAYFAIL);
if (!zstream->workspace) {
pool_fini(>pool);
return false;
@@ -256,7 +255,7 @@ static bool compress_init(struct i915_vma_compress *c)
 
c->tmp = NULL;
if (i915_has_memcpy_from_wc())
-   c->tmp = pool_alloc(>pool, ALLOW_FAIL);
+   c->tmp = pool_alloc(>pool, ATOMIC_MAYFAIL);
 
return true;
 }
@@ -280,7 +279,7 @@ static void *compress_next_page(struct i915_vma_compress *c,
if (dst->page_count >= dst->num_pages)
return ERR_PTR(-ENOSPC);
 
-   page = pool_alloc(>pool, ALLOW_FAIL);
+   page = pool_alloc(>pool, ATOMIC_MAYFAIL);
if (!page)
return ERR_PTR(-ENOMEM);
 
@@ -376,7 +375,7 @@ struct i915_vma_compress {
 
 static bool compress_init(struct i915_vma_compress *c)
 {
-   return pool_init(>pool, ALLOW_FAIL) == 0;
+   return pool_init(>pool, ATOMIC_MAYFAIL) == 0;
 }
 
 static bool compress_start(struct i915_vma_compress *c)
@@ -391,7 +390,7 @@ static int compress_page(struct i915_vma_compress *c,
 {
void *ptr;
 
-   ptr = pool_alloc(>pool, ALLOW_FAIL);
+   ptr = pool_alloc(>pool, ATOMIC_MAYFAIL);
if (!ptr)
return -ENOMEM;
 
@@ -1026,7 +1025,7 @@ i915_vma_coredump_create(const struct intel_gt *gt,
 
num_pages = min_t(u64, vma->size, vma->obj->base.size) >> PAGE_SHIFT;
num_pages = DIV_ROUND_UP(10 * num_pages, 8); /* worstcase zlib growth */
-   dst = kmalloc(sizeof(*dst) + num_pages * sizeof(u32 *), ALLOW_FAIL);
+   dst = kmalloc(sizeof(*dst) + num_pages * sizeof(u32 *), ATOMIC_MAYFAIL);
if (!dst)
return NULL;
 
@@ -1462,7 +1461,7 @@ capture_engine(struct intel_engine_cs *engine,
struct i915_request *rq = NULL;
unsigned long flags;
 
-   ee = intel_engine_coredump_alloc(engine, GFP_KERNEL);
+   ee = intel_engine_coredump_alloc(engine, ATOMIC_MAYFAIL);
if (!ee)
return NULL;
 
@@ -1510,7 +1509,7 @@ gt_record_engines(struct intel_gt_coredump *gt,
struct intel_engine_coredump *ee;
 
/* Refill our page pool before entering atomic section */
-   pool_refill(>pool, ALLOW_FAIL);
+   pool_refill(>pool, 

[PATCH v5 18/25] drm/i915/guc: Move guc_blocked fence to struct guc_state

2021-09-01 Thread Daniele Ceraolo Spurio
From: Matthew Brost 

Move guc_blocked fence to struct guc_state as the lock which protects
the fence lives there.

s/ce->guc_blocked/ce->guc_state.blocked/g

v2:
 (Daniele)
  - s/blocked_fence/blocked/g

Reviewed-by: Daniele Ceraolo Spurio 
Signed-off-by: Matthew Brost 
---
 drivers/gpu/drm/i915/gt/intel_context.c|  5 +++--
 drivers/gpu/drm/i915/gt/intel_context_types.h  |  5 ++---
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c  | 18 +-
 3 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context.c 
b/drivers/gpu/drm/i915/gt/intel_context.c
index 745e84c72c90..3048267ddc7e 100644
--- a/drivers/gpu/drm/i915/gt/intel_context.c
+++ b/drivers/gpu/drm/i915/gt/intel_context.c
@@ -405,8 +405,9 @@ intel_context_init(struct intel_context *ce, struct 
intel_engine_cs *engine)
 * Initialize fence to be complete as this is expected to be complete
 * unless there is a pending schedule disable outstanding.
 */
-   i915_sw_fence_init(>guc_blocked, sw_fence_dummy_notify);
-   i915_sw_fence_commit(>guc_blocked);
+   i915_sw_fence_init(>guc_state.blocked,
+  sw_fence_dummy_notify);
+   i915_sw_fence_commit(>guc_state.blocked);
 
i915_active_init(>active,
 __intel_context_active, __intel_context_retire, 0);
diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h 
b/drivers/gpu/drm/i915/gt/intel_context_types.h
index 3a73f3117873..5aecb9038b5b 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -167,6 +167,8 @@ struct intel_context {
 * fence related to GuC submission
 */
struct list_head fences;
+   /* GuC context blocked fence */
+   struct i915_sw_fence blocked;
} guc_state;
 
struct {
@@ -190,9 +192,6 @@ struct intel_context {
 */
struct list_head guc_id_link;
 
-   /* GuC context blocked fence */
-   struct i915_sw_fence guc_blocked;
-
/*
 * GuC priority management
 */
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 7c7cbd57d568..38068d5851e2 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1488,24 +1488,24 @@ static void guc_blocked_fence_complete(struct 
intel_context *ce)
 {
lockdep_assert_held(>guc_state.lock);
 
-   if (!i915_sw_fence_done(>guc_blocked))
-   i915_sw_fence_complete(>guc_blocked);
+   if (!i915_sw_fence_done(>guc_state.blocked))
+   i915_sw_fence_complete(>guc_state.blocked);
 }
 
 static void guc_blocked_fence_reinit(struct intel_context *ce)
 {
lockdep_assert_held(>guc_state.lock);
-   GEM_BUG_ON(!i915_sw_fence_done(>guc_blocked));
+   GEM_BUG_ON(!i915_sw_fence_done(>guc_state.blocked));
 
/*
 * This fence is always complete unless a pending schedule disable is
 * outstanding. We arm the fence here and complete it when we receive
 * the pending schedule disable complete message.
 */
-   i915_sw_fence_fini(>guc_blocked);
-   i915_sw_fence_reinit(>guc_blocked);
-   i915_sw_fence_await(>guc_blocked);
-   i915_sw_fence_commit(>guc_blocked);
+   i915_sw_fence_fini(>guc_state.blocked);
+   i915_sw_fence_reinit(>guc_state.blocked);
+   i915_sw_fence_await(>guc_state.blocked);
+   i915_sw_fence_commit(>guc_state.blocked);
 }
 
 static u16 prep_context_pending_disable(struct intel_context *ce)
@@ -1545,7 +1545,7 @@ static struct i915_sw_fence *guc_context_block(struct 
intel_context *ce)
if (enabled)
clr_context_enabled(ce);
spin_unlock_irqrestore(>guc_state.lock, flags);
-   return >guc_blocked;
+   return >guc_state.blocked;
}
 
/*
@@ -1561,7 +1561,7 @@ static struct i915_sw_fence *guc_context_block(struct 
intel_context *ce)
with_intel_runtime_pm(runtime_pm, wakeref)
__guc_context_sched_disable(guc, ce, guc_id);
 
-   return >guc_blocked;
+   return >guc_state.blocked;
 }
 
 #define SCHED_STATE_MULTI_BLOCKED_MASK \
-- 
2.25.1



[PATCH v5 20/25] drm/i915/guc: Proper xarray usage for contexts_lookup

2021-09-01 Thread Daniele Ceraolo Spurio
From: Matthew Brost 

Lock the xarray and take ref to the context if needed.

v2:
 (Checkpatch)
  - Add new line after declaration
 (Daniel Vetter)
  - Correct put / get accounting in xa_for_loops
v3:
 (Checkpatch)
  - Extra new line

Reviewed-by: Daniele Ceraolo Spurio 
Signed-off-by: Matthew Brost 
---
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 102 +++---
 1 file changed, 87 insertions(+), 15 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 3062406503d8..987aec197658 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -608,8 +608,18 @@ static void scrub_guc_desc_for_outstanding_g2h(struct 
intel_guc *guc)
unsigned long index, flags;
bool pending_disable, pending_enable, deregister, destroyed, banned;
 
+   xa_lock_irqsave(>context_lookup, flags);
xa_for_each(>context_lookup, index, ce) {
-   spin_lock_irqsave(>guc_state.lock, flags);
+   /*
+* Corner case where the ref count on the object is zero but and
+* deregister G2H was lost. In this case we don't touch the ref
+* count and finish the destroy of the context.
+*/
+   bool do_put = kref_get_unless_zero(>ref);
+
+   xa_unlock(>context_lookup);
+
+   spin_lock(>guc_state.lock);
 
/*
 * Once we are at this point submission_disabled() is guaranteed
@@ -625,7 +635,9 @@ static void scrub_guc_desc_for_outstanding_g2h(struct 
intel_guc *guc)
banned = context_banned(ce);
init_sched_state(ce);
 
-   spin_unlock_irqrestore(>guc_state.lock, flags);
+   spin_unlock(>guc_state.lock);
+
+   GEM_BUG_ON(!do_put && !destroyed);
 
if (pending_enable || destroyed || deregister) {
decr_outstanding_submission_g2h(guc);
@@ -648,13 +660,19 @@ static void scrub_guc_desc_for_outstanding_g2h(struct 
intel_guc *guc)
}
intel_context_sched_disable_unpin(ce);
decr_outstanding_submission_g2h(guc);
-   spin_lock_irqsave(>guc_state.lock, flags);
+
+   spin_lock(>guc_state.lock);
guc_blocked_fence_complete(ce);
-   spin_unlock_irqrestore(>guc_state.lock, flags);
+   spin_unlock(>guc_state.lock);
 
intel_context_put(ce);
}
+
+   if (do_put)
+   intel_context_put(ce);
+   xa_lock(>context_lookup);
}
+   xa_unlock_irqrestore(>context_lookup, flags);
 }
 
 static inline bool
@@ -873,16 +891,29 @@ void intel_guc_submission_reset(struct intel_guc *guc, 
bool stalled)
 {
struct intel_context *ce;
unsigned long index;
+   unsigned long flags;
 
if (unlikely(!guc_submission_initialized(guc))) {
/* Reset called during driver load? GuC not yet initialised! */
return;
}
 
-   xa_for_each(>context_lookup, index, ce)
+   xa_lock_irqsave(>context_lookup, flags);
+   xa_for_each(>context_lookup, index, ce) {
+   if (!kref_get_unless_zero(>ref))
+   continue;
+
+   xa_unlock(>context_lookup);
+
if (intel_context_is_pinned(ce))
__guc_reset_context(ce, stalled);
 
+   intel_context_put(ce);
+
+   xa_lock(>context_lookup);
+   }
+   xa_unlock_irqrestore(>context_lookup, flags);
+
/* GuC is blown away, drop all references to contexts */
xa_destroy(>context_lookup);
 }
@@ -957,11 +988,24 @@ void intel_guc_submission_cancel_requests(struct 
intel_guc *guc)
 {
struct intel_context *ce;
unsigned long index;
+   unsigned long flags;
+
+   xa_lock_irqsave(>context_lookup, flags);
+   xa_for_each(>context_lookup, index, ce) {
+   if (!kref_get_unless_zero(>ref))
+   continue;
+
+   xa_unlock(>context_lookup);
 
-   xa_for_each(>context_lookup, index, ce)
if (intel_context_is_pinned(ce))
guc_cancel_context_requests(ce);
 
+   intel_context_put(ce);
+
+   xa_lock(>context_lookup);
+   }
+   xa_unlock_irqrestore(>context_lookup, flags);
+
guc_cancel_sched_engine_requests(guc->sched_engine);
 
/* GuC is blown away, drop all references to contexts */
@@ -2849,21 +2893,28 @@ void intel_guc_find_hung_context(struct intel_engine_cs 
*engine)
struct intel_context *ce;
struct i915_request *rq;
unsigned long index;
+   unsigned long flags;
 
/* Reset called during driver load? GuC not yet 

[PATCH v5 17/25] drm/i915/guc: Release submit fence from an irq_work

2021-09-01 Thread Daniele Ceraolo Spurio
From: Matthew Brost 

A subsequent patch will flip the locking hierarchy from
ce->guc_state.lock -> sched_engine->lock to sched_engine->lock ->
ce->guc_state.lock. As such we need to release the submit fence for a
request from an IRQ to break a lock inversion - i.e. the fence must be
release went holding ce->guc_state.lock and the releasing of the can
acquire sched_engine->lock.

v2:
 (Daniele)
  - Delete request from list before calling irq_work_queue

Reviewed-by: Daniele Ceraolo Spurio 
Signed-off-by: Matthew Brost 
---
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 22 ---
 drivers/gpu/drm/i915/i915_request.h   |  5 +
 2 files changed, 24 insertions(+), 3 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 8509e827a8d0..7c7cbd57d568 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -2035,17 +2035,32 @@ static const struct intel_context_ops guc_context_ops = 
{
.create_virtual = guc_create_virtual,
 };
 
+static void submit_work_cb(struct irq_work *wrk)
+{
+   struct i915_request *rq = container_of(wrk, typeof(*rq), submit_work);
+
+   might_lock(>engine->sched_engine->lock);
+   i915_sw_fence_complete(>submit);
+}
+
 static void __guc_signal_context_fence(struct intel_context *ce)
 {
-   struct i915_request *rq;
+   struct i915_request *rq, *rn;
 
lockdep_assert_held(>guc_state.lock);
 
if (!list_empty(>guc_state.fences))
trace_intel_context_fence_release(ce);
 
-   list_for_each_entry(rq, >guc_state.fences, guc_fence_link)
-   i915_sw_fence_complete(>submit);
+   /*
+* Use an IRQ to ensure locking order of sched_engine->lock ->
+* ce->guc_state.lock is preserved.
+*/
+   list_for_each_entry_safe(rq, rn, >guc_state.fences,
+guc_fence_link) {
+   list_del(>guc_fence_link);
+   irq_work_queue(>submit_work);
+   }
 
INIT_LIST_HEAD(>guc_state.fences);
 }
@@ -2155,6 +2170,7 @@ static int guc_request_alloc(struct i915_request *rq)
spin_lock_irqsave(>guc_state.lock, flags);
if (context_wait_for_deregister_to_register(ce) ||
context_pending_disable(ce)) {
+   init_irq_work(>submit_work, submit_work_cb);
i915_sw_fence_await(>submit);
 
list_add_tail(>guc_fence_link, >guc_state.fences);
diff --git a/drivers/gpu/drm/i915/i915_request.h 
b/drivers/gpu/drm/i915/i915_request.h
index 1bc1349ba3c2..d818cfbfc41d 100644
--- a/drivers/gpu/drm/i915/i915_request.h
+++ b/drivers/gpu/drm/i915/i915_request.h
@@ -218,6 +218,11 @@ struct i915_request {
};
struct llist_head execute_cb;
struct i915_sw_fence semaphore;
+   /**
+* @submit_work: complete submit fence from an IRQ if needed for
+* locking hierarchy reasons.
+*/
+   struct irq_work submit_work;
 
/*
 * A list of everyone we wait upon, and everyone who waits upon us.
-- 
2.25.1



[PATCH v5 19/25] drm/i915/guc: Rework and simplify locking

2021-09-01 Thread Daniele Ceraolo Spurio
From: Matthew Brost 

Rework and simplify the locking with GuC subission. Drop
sched_state_no_lock and move all fields under the guc_state.sched_state
and protect all these fields with guc_state.lock . This requires
changing the locking hierarchy from guc_state.lock -> sched_engine.lock
to sched_engine.lock -> guc_state.lock.

v2:
 (Daniele)
  - Don't check fields outside of lock during sched disable, check less
fields within lock as some of the outside are no longer needed

Reviewed-by: Daniele Ceraolo Spurio 
Signed-off-by: Matthew Brost 
---
 drivers/gpu/drm/i915/gt/intel_context_types.h |   5 +-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 200 --
 drivers/gpu/drm/i915/i915_trace.h |   6 +-
 3 files changed, 89 insertions(+), 122 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h 
b/drivers/gpu/drm/i915/gt/intel_context_types.h
index 5aecb9038b5b..d2f798ef678c 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -161,7 +161,7 @@ struct intel_context {
 * sched_state: scheduling state of this context using GuC
 * submission
 */
-   u16 sched_state;
+   u32 sched_state;
/*
 * fences: maintains of list of requests that have a submit
 * fence related to GuC submission
@@ -178,9 +178,6 @@ struct intel_context {
struct list_head requests;
} guc_active;
 
-   /* GuC scheduling state flags that do not require a lock. */
-   atomic_t guc_sched_state_no_lock;
-
/* GuC LRC descriptor ID */
u16 guc_id;
 
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 38068d5851e2..3062406503d8 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -72,87 +72,24 @@ guc_create_virtual(struct intel_engine_cs **siblings, 
unsigned int count);
 
 #define GUC_REQUEST_SIZE 64 /* bytes */
 
-/*
- * Below is a set of functions which control the GuC scheduling state which do
- * not require a lock as all state transitions are mutually exclusive. i.e. It
- * is not possible for the context pinning code and submission, for the same
- * context, to be executing simultaneously. We still need an atomic as it is
- * possible for some of the bits to changing at the same time though.
- */
-#define SCHED_STATE_NO_LOCK_ENABLEDBIT(0)
-#define SCHED_STATE_NO_LOCK_PENDING_ENABLE BIT(1)
-#define SCHED_STATE_NO_LOCK_REGISTERED BIT(2)
-static inline bool context_enabled(struct intel_context *ce)
-{
-   return (atomic_read(>guc_sched_state_no_lock) &
-   SCHED_STATE_NO_LOCK_ENABLED);
-}
-
-static inline void set_context_enabled(struct intel_context *ce)
-{
-   atomic_or(SCHED_STATE_NO_LOCK_ENABLED, >guc_sched_state_no_lock);
-}
-
-static inline void clr_context_enabled(struct intel_context *ce)
-{
-   atomic_and((u32)~SCHED_STATE_NO_LOCK_ENABLED,
-  >guc_sched_state_no_lock);
-}
-
-static inline bool context_pending_enable(struct intel_context *ce)
-{
-   return (atomic_read(>guc_sched_state_no_lock) &
-   SCHED_STATE_NO_LOCK_PENDING_ENABLE);
-}
-
-static inline void set_context_pending_enable(struct intel_context *ce)
-{
-   atomic_or(SCHED_STATE_NO_LOCK_PENDING_ENABLE,
- >guc_sched_state_no_lock);
-}
-
-static inline void clr_context_pending_enable(struct intel_context *ce)
-{
-   atomic_and((u32)~SCHED_STATE_NO_LOCK_PENDING_ENABLE,
-  >guc_sched_state_no_lock);
-}
-
-static inline bool context_registered(struct intel_context *ce)
-{
-   return (atomic_read(>guc_sched_state_no_lock) &
-   SCHED_STATE_NO_LOCK_REGISTERED);
-}
-
-static inline void set_context_registered(struct intel_context *ce)
-{
-   atomic_or(SCHED_STATE_NO_LOCK_REGISTERED,
- >guc_sched_state_no_lock);
-}
-
-static inline void clr_context_registered(struct intel_context *ce)
-{
-   atomic_and((u32)~SCHED_STATE_NO_LOCK_REGISTERED,
-  >guc_sched_state_no_lock);
-}
-
 /*
  * Below is a set of functions which control the GuC scheduling state which
- * require a lock, aside from the special case where the functions are called
- * from guc_lrc_desc_pin(). In that case it isn't possible for any other code
- * path to be executing on the context.
+ * require a lock.
  */
 #define SCHED_STATE_WAIT_FOR_DEREGISTER_TO_REGISTERBIT(0)
 #define SCHED_STATE_DESTROYED  BIT(1)
 #define SCHED_STATE_PENDING_DISABLEBIT(2)
 #define SCHED_STATE_BANNED BIT(3)
-#define SCHED_STATE_BLOCKED_SHIFT  4
+#define SCHED_STATE_ENABLEDBIT(4)
+#define SCHED_STATE_PENDING_ENABLE

[PATCH v5 21/25] drm/i915/guc: Drop pin count check trick between sched_disable and re-pin

2021-09-01 Thread Daniele Ceraolo Spurio
From: Matthew Brost 

Drop pin count check trick between a sched_disable and re-pin, now rely
on the lock and counter of the number of committed requests to determine
if scheduling should be disabled on the context.

Reviewed-by: Daniele Ceraolo Spurio 
Signed-off-by: Matthew Brost 
---
 drivers/gpu/drm/i915/gt/intel_context_types.h |  2 +
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 53 +++
 2 files changed, 34 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h 
b/drivers/gpu/drm/i915/gt/intel_context_types.h
index d2f798ef678c..3a5d98e908f4 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -169,6 +169,8 @@ struct intel_context {
struct list_head fences;
/* GuC context blocked fence */
struct i915_sw_fence blocked;
+   /* GuC committed requests */
+   int number_committed_requests;
} guc_state;
 
struct {
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 987aec197658..440ddcaae627 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -249,6 +249,25 @@ static inline void decr_context_blocked(struct 
intel_context *ce)
ce->guc_state.sched_state -= SCHED_STATE_BLOCKED;
 }
 
+static inline bool context_has_committed_requests(struct intel_context *ce)
+{
+   return !!ce->guc_state.number_committed_requests;
+}
+
+static inline void incr_context_committed_requests(struct intel_context *ce)
+{
+   lockdep_assert_held(>guc_state.lock);
+   ++ce->guc_state.number_committed_requests;
+   GEM_BUG_ON(ce->guc_state.number_committed_requests < 0);
+}
+
+static inline void decr_context_committed_requests(struct intel_context *ce)
+{
+   lockdep_assert_held(>guc_state.lock);
+   --ce->guc_state.number_committed_requests;
+   GEM_BUG_ON(ce->guc_state.number_committed_requests < 0);
+}
+
 static inline bool context_guc_id_invalid(struct intel_context *ce)
 {
return ce->guc_id == GUC_INVALID_LRC_ID;
@@ -1749,24 +1768,18 @@ static void guc_context_sched_disable(struct 
intel_context *ce)
spin_lock_irqsave(>guc_state.lock, flags);
 
/*
-* We have to check if the context has been disabled by another thread.
-* We also have to check if the context has been pinned again as another
-* pin operation is allowed to pass this function. Checking the pin
-* count, within ce->guc_state.lock, synchronizes this function with
-* guc_request_alloc ensuring a request doesn't slip through the
-* 'context_pending_disable' fence. Checking within the spin lock (can't
-* sleep) ensures another process doesn't pin this context and generate
-* a request before we set the 'context_pending_disable' flag here.
+* We have to check if the context has been disabled by another thread,
+* check if submssion has been disabled to seal a race with reset and
+* finally check if any more requests have been committed to the
+* context ensursing that a request doesn't slip through the
+* 'context_pending_disable' fence.
 */
-   if (unlikely(!context_enabled(ce) || submission_disabled(guc))) {
+   if (unlikely(!context_enabled(ce) || submission_disabled(guc) ||
+context_has_committed_requests(ce))) {
clr_context_enabled(ce);
spin_unlock_irqrestore(>guc_state.lock, flags);
goto unpin;
}
-   if (unlikely(atomic_add_unless(>pin_count, -2, 2))) {
-   spin_unlock_irqrestore(>guc_state.lock, flags);
-   return;
-   }
guc_id = prep_context_pending_disable(ce);
 
spin_unlock_irqrestore(>guc_state.lock, flags);
@@ -1796,6 +1809,7 @@ static void __guc_context_destroy(struct intel_context 
*ce)
   ce->guc_prio_count[GUC_CLIENT_PRIORITY_HIGH] ||
   ce->guc_prio_count[GUC_CLIENT_PRIORITY_KMD_NORMAL] ||
   ce->guc_prio_count[GUC_CLIENT_PRIORITY_NORMAL]);
+   GEM_BUG_ON(ce->guc_state.number_committed_requests);
 
lrc_fini(ce);
intel_context_fini(ce);
@@ -2026,6 +2040,10 @@ static void remove_from_context(struct i915_request *rq)
 
spin_unlock_irq(>guc_active.lock);
 
+   spin_lock_irq(>guc_state.lock);
+   decr_context_committed_requests(ce);
+   spin_unlock_irq(>guc_state.lock);
+
atomic_dec(>guc_id_ref);
i915_request_notify_execute_cb_imm(rq);
 }
@@ -2176,15 +2194,7 @@ static int guc_request_alloc(struct i915_request *rq)
 * schedule enable or context registration if either G2H is pending
 * respectfully. Once a G2H returns, the fence is released that is
 * blocking these requests (see 

[PATCH v5 12/25] drm/i915/guc: Take context ref when cancelling request

2021-09-01 Thread Daniele Ceraolo Spurio
From: Matthew Brost 

A context can get destroyed after cancelling a request, if a context or
GT reset occurs, so take a reference to context when cancelling a
request.

Fixes: 62eaf0ae217d ("drm/i915/guc: Support request cancellation")
Signed-off-by: Matthew Brost 
Reviewed-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

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 5970c54a2e72..e036a171ff17 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1624,8 +1624,10 @@ static void guc_context_cancel_request(struct 
intel_context *ce,
   struct i915_request *rq)
 {
if (i915_sw_fence_signaled(>submit)) {
-   struct i915_sw_fence *fence = guc_context_block(ce);
+   struct i915_sw_fence *fence;
 
+   intel_context_get(ce);
+   fence = guc_context_block(ce);
i915_sw_fence_wait(fence);
if (!i915_request_completed(rq)) {
__i915_request_skip(rq);
@@ -1640,6 +1642,7 @@ static void guc_context_cancel_request(struct 
intel_context *ce,
flush_work(_to_guc(ce)->ct.requests.worker);
 
guc_context_unblock(ce);
+   intel_context_put(ce);
}
 }
 
-- 
2.25.1



[PATCH v5 13/25] drm/i915/guc: Don't touch guc_state.sched_state without a lock

2021-09-01 Thread Daniele Ceraolo Spurio
From: Matthew Brost 

Before we did some clever tricks to not use the a lock when touching
guc_state.sched_state in certain cases. Don't do that, enforce the use
of the lock.

v2:
 (kernel test robo )
  - Add __maybe_unused to sched_state_is_init()

v3: rebase after the unused code path removal has been moved to an
earlier patch.

Signed-off-by: Matthew Brost 
Reported-by: kernel test robot 
Reviewed-by: Daniele Ceraolo Spurio 
---
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 22 ++-
 1 file changed, 17 insertions(+), 5 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 e036a171ff17..ca73128d7b4d 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -151,11 +151,23 @@ static inline void clr_context_registered(struct 
intel_context *ce)
 
 static inline void init_sched_state(struct intel_context *ce)
 {
-   /* Only should be called from guc_lrc_desc_pin() */
+   lockdep_assert_held(>guc_state.lock);
atomic_set(>guc_sched_state_no_lock, 0);
ce->guc_state.sched_state &= SCHED_STATE_BLOCKED_MASK;
 }
 
+__maybe_unused
+static bool sched_state_is_init(struct intel_context *ce)
+{
+   /*
+* XXX: Kernel contexts can have SCHED_STATE_NO_LOCK_REGISTERED after
+* suspend.
+*/
+   return !(atomic_read(>guc_sched_state_no_lock) &
+~SCHED_STATE_NO_LOCK_REGISTERED) &&
+   !(ce->guc_state.sched_state &= ~SCHED_STATE_BLOCKED_MASK);
+}
+
 static inline bool
 context_wait_for_deregister_to_register(struct intel_context *ce)
 {
@@ -166,7 +178,7 @@ context_wait_for_deregister_to_register(struct 
intel_context *ce)
 static inline void
 set_context_wait_for_deregister_to_register(struct intel_context *ce)
 {
-   /* Only should be called from guc_lrc_desc_pin() without lock */
+   lockdep_assert_held(>guc_state.lock);
ce->guc_state.sched_state |=
SCHED_STATE_WAIT_FOR_DEREGISTER_TO_REGISTER;
 }
@@ -607,9 +619,7 @@ static void scrub_guc_desc_for_outstanding_g2h(struct 
intel_guc *guc)
bool pending_disable, pending_enable, deregister, destroyed, banned;
 
xa_for_each(>context_lookup, index, ce) {
-   /* Flush context */
spin_lock_irqsave(>guc_state.lock, flags);
-   spin_unlock_irqrestore(>guc_state.lock, flags);
 
/*
 * Once we are at this point submission_disabled() is guaranteed
@@ -625,6 +635,8 @@ static void scrub_guc_desc_for_outstanding_g2h(struct 
intel_guc *guc)
banned = context_banned(ce);
init_sched_state(ce);
 
+   spin_unlock_irqrestore(>guc_state.lock, flags);
+
if (pending_enable || destroyed || deregister) {
decr_outstanding_submission_g2h(guc);
if (deregister)
@@ -1324,6 +1336,7 @@ static int guc_lrc_desc_pin(struct intel_context *ce, 
bool loop)
int ret = 0;
 
GEM_BUG_ON(!engine->mask);
+   GEM_BUG_ON(!sched_state_is_init(ce));
 
/*
 * Ensure LRC + CT vmas are is same region as write barrier is done
@@ -1352,7 +1365,6 @@ static int guc_lrc_desc_pin(struct intel_context *ce, 
bool loop)
desc->priority = ce->guc_prio;
desc->context_flags = CONTEXT_REGISTRATION_FLAG_KMD;
guc_context_policy_init(engine, desc);
-   init_sched_state(ce);
 
/*
 * The context_lookup xarray is used to determine if the hardware
-- 
2.25.1



[PATCH v5 11/25] drm/i915/selftests: Add initial GuC selftest for scrubbing lost G2H

2021-09-01 Thread Daniele Ceraolo Spurio
From: Matthew Brost 

While debugging an issue with full GT resets I went down a rabbit hole
thinking the scrubbing of lost G2H wasn't working correctly. This proved
to be incorrect as this was working just fine but this chase inspired me
to write a selftest to prove that this works. This simple selftest
injects errors dropping various G2H and then issues a full GT reset
proving that the scrubbing of these G2H doesn't blow up.

v2:
 (Daniel Vetter)
  - Use ifdef instead of macros for selftests
v3:
 (Checkpatch)
  - A space after 'switch' statement
v4:
 (Daniele)
  - A comment saying GT won't idle if G2H are lost

Reviewed-by: Daniele Ceraolo Spurio 
Signed-off-by: Matthew Brost 
---
 drivers/gpu/drm/i915/gt/intel_context_types.h |  18 +++
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  25 
 drivers/gpu/drm/i915/gt/uc/selftest_guc.c | 127 ++
 .../drm/i915/selftests/i915_live_selftests.h  |   1 +
 .../i915/selftests/intel_scheduler_helpers.c  |  12 ++
 .../i915/selftests/intel_scheduler_helpers.h  |   2 +
 6 files changed, 185 insertions(+)
 create mode 100644 drivers/gpu/drm/i915/gt/uc/selftest_guc.c

diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h 
b/drivers/gpu/drm/i915/gt/intel_context_types.h
index e54351a170e2..3a73f3117873 100644
--- a/drivers/gpu/drm/i915/gt/intel_context_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_context_types.h
@@ -198,6 +198,24 @@ struct intel_context {
 */
u8 guc_prio;
u32 guc_prio_count[GUC_CLIENT_PRIORITY_NUM];
+
+#ifdef CONFIG_DRM_I915_SELFTEST
+   /**
+* @drop_schedule_enable: Force drop of schedule enable G2H for selftest
+*/
+   bool drop_schedule_enable;
+
+   /**
+* @drop_schedule_disable: Force drop of schedule disable G2H for
+* selftest
+*/
+   bool drop_schedule_disable;
+
+   /**
+* @drop_deregister: Force drop of deregister G2H for selftest
+*/
+   bool drop_deregister;
+#endif
 };
 
 #endif /* __INTEL_CONTEXT_TYPES__ */
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 f5bee833ee7d..5970c54a2e72 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -2639,6 +2639,13 @@ int intel_guc_deregister_done_process_msg(struct 
intel_guc *guc,
 
trace_intel_context_deregister_done(ce);
 
+#ifdef CONFIG_DRM_I915_SELFTEST
+   if (unlikely(ce->drop_deregister)) {
+   ce->drop_deregister = false;
+   return 0;
+   }
+#endif
+
if (context_wait_for_deregister_to_register(ce)) {
struct intel_runtime_pm *runtime_pm =
>engine->gt->i915->runtime_pm;
@@ -2693,10 +2700,24 @@ int intel_guc_sched_done_process_msg(struct intel_guc 
*guc,
trace_intel_context_sched_done(ce);
 
if (context_pending_enable(ce)) {
+#ifdef CONFIG_DRM_I915_SELFTEST
+   if (unlikely(ce->drop_schedule_enable)) {
+   ce->drop_schedule_enable = false;
+   return 0;
+   }
+#endif
+
clr_context_pending_enable(ce);
} else if (context_pending_disable(ce)) {
bool banned;
 
+#ifdef CONFIG_DRM_I915_SELFTEST
+   if (unlikely(ce->drop_schedule_disable)) {
+   ce->drop_schedule_disable = false;
+   return 0;
+   }
+#endif
+
/*
 * Unpin must be done before __guc_signal_context_fence,
 * otherwise a race exists between the requests getting
@@ -3073,3 +3094,7 @@ bool intel_guc_virtual_engine_has_heartbeat(const struct 
intel_engine_cs *ve)
 
return false;
 }
+
+#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+#include "selftest_guc.c"
+#endif
diff --git a/drivers/gpu/drm/i915/gt/uc/selftest_guc.c 
b/drivers/gpu/drm/i915/gt/uc/selftest_guc.c
new file mode 100644
index ..fb0e4a7bd8ca
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/selftest_guc.c
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright �� 2021 Intel Corporation
+ */
+
+#include "selftests/intel_scheduler_helpers.h"
+
+static struct i915_request *nop_user_request(struct intel_context *ce,
+struct i915_request *from)
+{
+   struct i915_request *rq;
+   int ret;
+
+   rq = intel_context_create_request(ce);
+   if (IS_ERR(rq))
+   return rq;
+
+   if (from) {
+   ret = i915_sw_fence_await_dma_fence(>submit,
+   >fence, 0,
+   I915_FENCE_GFP);
+   if (ret < 0) {
+   i915_request_put(rq);
+   return ERR_PTR(ret);
+   }
+   }
+
+   i915_request_get(rq);
+   i915_request_add(rq);
+
+   return rq;
+}
+

[PATCH v5 09/25] drm/i915/guc: Don't enable scheduling on a banned context, guc_id invalid, not registered

2021-09-01 Thread Daniele Ceraolo Spurio
From: Matthew Brost 

When unblocking a context, do not enable scheduling if the context is
banned, guc_id invalid, or not registered.

v2:
 (Daniele)
  - Add helper for unblock

Fixes: 62eaf0ae217d ("drm/i915/guc: Support request cancellation")
Signed-off-by: Matthew Brost 
Reviewed-by: Daniele Ceraolo Spurio 
Cc: 
---
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 22 ---
 1 file changed, 19 insertions(+), 3 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 bd401a5be87c..f5bee833ee7d 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -148,6 +148,7 @@ static inline void clr_context_registered(struct 
intel_context *ce)
 #define SCHED_STATE_BLOCKED_SHIFT  4
 #define SCHED_STATE_BLOCKEDBIT(SCHED_STATE_BLOCKED_SHIFT)
 #define SCHED_STATE_BLOCKED_MASK   (0xfff << SCHED_STATE_BLOCKED_SHIFT)
+
 static inline void init_sched_state(struct intel_context *ce)
 {
/* Only should be called from guc_lrc_desc_pin() */
@@ -1563,6 +1564,23 @@ static struct i915_sw_fence *guc_context_block(struct 
intel_context *ce)
return >guc_blocked;
 }
 
+#define SCHED_STATE_MULTI_BLOCKED_MASK \
+   (SCHED_STATE_BLOCKED_MASK & ~SCHED_STATE_BLOCKED)
+#define SCHED_STATE_NO_UNBLOCK \
+   (SCHED_STATE_MULTI_BLOCKED_MASK | \
+SCHED_STATE_PENDING_DISABLE | \
+SCHED_STATE_BANNED)
+
+static bool context_cant_unblock(struct intel_context *ce)
+{
+   lockdep_assert_held(>guc_state.lock);
+
+   return (ce->guc_state.sched_state & SCHED_STATE_NO_UNBLOCK) ||
+   context_guc_id_invalid(ce) ||
+   !lrc_desc_registered(ce_to_guc(ce), ce->guc_id) ||
+   !intel_context_is_pinned(ce);
+}
+
 static void guc_context_unblock(struct intel_context *ce)
 {
struct intel_guc *guc = ce_to_guc(ce);
@@ -1577,9 +1595,7 @@ static void guc_context_unblock(struct intel_context *ce)
spin_lock_irqsave(>guc_state.lock, flags);
 
if (unlikely(submission_disabled(guc) ||
-!intel_context_is_pinned(ce) ||
-context_pending_disable(ce) ||
-context_blocked(ce) > 1)) {
+context_cant_unblock(ce))) {
enable = false;
} else {
enable = true;
-- 
2.25.1



[PATCH v5 14/25] drm/i915/guc: Reset LRC descriptor if register returns -ENODEV

2021-09-01 Thread Daniele Ceraolo Spurio
From: Matthew Brost 

Reset LRC descriptor if a context register returns -ENODEV as this means
we are mid-reset.

Fixes: eb5e7da736f3 ("drm/i915/guc: Reset implementation for new GuC interface")
Signed-off-by: Matthew Brost 
Reviewed-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 6 --
 1 file changed, 4 insertions(+), 2 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 ca73128d7b4d..dcd7a09f8559 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1405,10 +1405,12 @@ static int guc_lrc_desc_pin(struct intel_context *ce, 
bool loop)
} else {
with_intel_runtime_pm(runtime_pm, wakeref)
ret = register_context(ce, loop);
-   if (unlikely(ret == -EBUSY))
+   if (unlikely(ret == -EBUSY)) {
+   reset_lrc_desc(guc, desc_idx);
+   } else if (unlikely(ret == -ENODEV)) {
reset_lrc_desc(guc, desc_idx);
-   else if (unlikely(ret == -ENODEV))
ret = 0;/* Will get registered later */
+   }
}
 
return ret;
-- 
2.25.1



[PATCH v5 10/25] drm/i915/guc: Copy whole golden context, set engine state size of subset

2021-09-01 Thread Daniele Ceraolo Spurio
From: Matthew Brost 

When the GuC does a media reset, it copies a golden context state back
into the corrupted context's state. The address of the golden context
and the size of the engine state restore are passed in via the GuC ADS.
The i915 had a bug where it passed in the whole size of the golden
context, not the size of the engine state to restore resulting in a
memory corruption.

Also copy the entire golden context on init rather than just the engine
state that is restored.

v2 (Daniele): use defines to avoid duplicated const variables (John).

Fixes: 481d458caede ("drm/i915/guc: Add golden context to GuC ADS")
Signed-off-by: Matthew Brost 
Signed-off-by: Daniele Ceraolo Spurio 
Cc: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c | 26 ++
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index 6926919bcac6..2c6ea64af7ec 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -349,6 +349,8 @@ static void fill_engine_enable_masks(struct intel_gt *gt,
info->engine_enabled_masks[GUC_VIDEOENHANCE_CLASS] = VEBOX_MASK(gt);
 }
 
+#define LR_HW_CONTEXT_SIZE (80 * sizeof(u32))
+#define LRC_SKIP_SIZE (LRC_PPHWSP_SZ * PAGE_SIZE + LR_HW_CONTEXT_SIZE)
 static int guc_prep_golden_context(struct intel_guc *guc,
   struct __guc_ads_blob *blob)
 {
@@ -396,7 +398,18 @@ static int guc_prep_golden_context(struct intel_guc *guc,
if (!blob)
continue;
 
-   blob->ads.eng_state_size[guc_class] = real_size;
+   /*
+* This interface is slightly confusing. We need to pass the
+* base address of the full golden context and the size of just
+* the engine state, which is the section of the context image
+* that starts after the execlists context. This is required to
+* allow the GuC to restore just the engine state when a
+* watchdog reset occurs.
+* We calculate the engine state size by removing the size of
+* what comes before it in the context image (which is identical
+* on all engines).
+*/
+   blob->ads.eng_state_size[guc_class] = real_size - LRC_SKIP_SIZE;
blob->ads.golden_context_lrca[guc_class] = addr_ggtt;
addr_ggtt += alloc_size;
}
@@ -436,11 +449,6 @@ static void guc_init_golden_context(struct intel_guc *guc)
u8 engine_class, guc_class;
u8 *ptr;
 
-   /* Skip execlist and PPGTT registers + HWSP */
-   const u32 lr_hw_context_size = 80 * sizeof(u32);
-   const u32 skip_size = LRC_PPHWSP_SZ * PAGE_SIZE +
-   lr_hw_context_size;
-
if (!intel_uc_uses_guc_submission(>uc))
return;
 
@@ -476,12 +484,12 @@ static void guc_init_golden_context(struct intel_guc *guc)
continue;
}
 
-   GEM_BUG_ON(blob->ads.eng_state_size[guc_class] != real_size);
+   GEM_BUG_ON(blob->ads.eng_state_size[guc_class] !=
+  real_size - LRC_SKIP_SIZE);
GEM_BUG_ON(blob->ads.golden_context_lrca[guc_class] != 
addr_ggtt);
addr_ggtt += alloc_size;
 
-   shmem_read(engine->default_state, skip_size, ptr + skip_size,
-  real_size - skip_size);
+   shmem_read(engine->default_state, 0, ptr, real_size);
ptr += alloc_size;
}
 
-- 
2.25.1



[PATCH v5 08/25] drm/i915/guc: Kick tasklet after queuing a request

2021-09-01 Thread Daniele Ceraolo Spurio
From: Matthew Brost 

Kick tasklet after queuing a request so it submitted in a timely manner.

Fixes: 3a4cdf1982f0 ("drm/i915/guc: Implement GuC context operations for new 
inteface")
Signed-off-by: Matthew Brost 
Reviewed-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 1 +
 1 file changed, 1 insertion(+)

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 f9e3725b94c1..bd401a5be87c 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1049,6 +1049,7 @@ static inline void queue_request(struct i915_sched_engine 
*sched_engine,
list_add_tail(>sched.link,
  i915_sched_lookup_priolist(sched_engine, prio));
set_bit(I915_FENCE_FLAG_PQUEUE, >fence.flags);
+   tasklet_hi_schedule(_engine->tasklet);
 }
 
 static int guc_bypass_tasklet_submit(struct intel_guc *guc,
-- 
2.25.1



[PATCH v5 07/25] Revert "drm/i915/gt: Propagate change in error status to children on unhold"

2021-09-01 Thread Daniele Ceraolo Spurio
From: Matthew Brost 

Propagating errors to dependent fences is broken and can lead to
errors from one client ending up in another.  In 3761baae908a (Revert
"drm/i915: Propagate errors on awaiting already signaled fences"), we
attempted to get rid of fence error propagation but missed the case
added in 8e9f84cf5cac ("drm/i915/gt: Propagate change in error status
to children on unhold").  Revert that one too.  This error was found
by an up-and-coming selftest which triggers a reset during request
cancellation and verifies that subsequent requests complete
successfully.

v2:
 (Daniel Vetter)
  - Use revert
v3:
 (Jason)
  - Update commit message

References: '3761baae908a ("Revert "drm/i915: Propagate errors on awaiting 
already signaled fences"")'
Signed-off-by: Matthew Brost 
Reviewed-by: Daniel Vetter 
---
 drivers/gpu/drm/i915/gt/intel_execlists_submission.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c 
b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
index de5f9c86b9a4..cafb0608ffb4 100644
--- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
+++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
@@ -2140,10 +2140,6 @@ static void __execlists_unhold(struct i915_request *rq)
if (p->flags & I915_DEPENDENCY_WEAK)
continue;
 
-   /* Propagate any change in error status */
-   if (rq->fence.error)
-   i915_request_set_error_once(w, rq->fence.error);
-
if (w->engine != rq->engine)
continue;
 
-- 
2.25.1



[PATCH v5 04/25] drm/i915/guc: Don't drop ce->guc_active.lock when unwinding context

2021-09-01 Thread Daniele Ceraolo Spurio
From: Matthew Brost 

Don't drop ce->guc_active.lock when unwinding a context after reset.
At one point we had to drop this because of a lock inversion but that is
no longer the case. It is much safer to hold the lock so let's do that.

Fixes: eb5e7da736f3 ("drm/i915/guc: Reset implementation for new GuC interface")
Reviewed-by: Daniele Ceraolo Spurio 
Signed-off-by: Matthew Brost 
Cc: 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 4 
 1 file changed, 4 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 0c1e6b465fba..31bbfe5479ae 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -813,8 +813,6 @@ __unwind_incomplete_requests(struct intel_context *ce)
continue;
 
list_del_init(>sched.link);
-   spin_unlock(>guc_active.lock);
-
__i915_request_unsubmit(rq);
 
/* Push the request back into the queue for later resubmission. 
*/
@@ -827,8 +825,6 @@ __unwind_incomplete_requests(struct intel_context *ce)
 
list_add(>sched.link, pl);
set_bit(I915_FENCE_FLAG_PQUEUE, >fence.flags);
-
-   spin_lock(>guc_active.lock);
}
spin_unlock(>guc_active.lock);
spin_unlock_irqrestore(_engine->lock, flags);
-- 
2.25.1



[PATCH v5 06/25] drm/i915/guc: Workaround reset G2H is received after schedule done G2H

2021-09-01 Thread Daniele Ceraolo Spurio
From: Matthew Brost 

If the context is reset as a result of the request cancellation the
context reset G2H is received after schedule disable done G2H which is
the wrong order. The schedule disable done G2H release the waiting
request cancellation code which resubmits the context. This races
with the context reset G2H which also wants to resubmit the context but
in this case it really should be a NOP as request cancellation code owns
the resubmit. Use some clever tricks of checking the context state to
seal this race until the GuC firmware is fixed.

v2:
 (Checkpatch)
  - Fix typos
v3:
 (Daniele)
  - State that is a bug in the GuC firmware

Fixes: 62eaf0ae217d ("drm/i915/guc: Support request cancellation")
Signed-off-by: Matthew Brost 
Cc: 
Reviewed-by: Daniele Ceraolo Spurio 
---
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 41 ---
 1 file changed, 35 insertions(+), 6 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 31bbfe5479ae..f9e3725b94c1 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -833,17 +833,33 @@ __unwind_incomplete_requests(struct intel_context *ce)
 static void __guc_reset_context(struct intel_context *ce, bool stalled)
 {
struct i915_request *rq;
+   unsigned long flags;
u32 head;
+   bool skip = false;
 
intel_context_get(ce);
 
/*
-* GuC will implicitly mark the context as non-schedulable
-* when it sends the reset notification. Make sure our state
-* reflects this change. The context will be marked enabled
-* on resubmission.
+* GuC will implicitly mark the context as non-schedulable when it sends
+* the reset notification. Make sure our state reflects this change. The
+* context will be marked enabled on resubmission.
+*
+* XXX: If the context is reset as a result of the request cancellation
+* this G2H is received after the schedule disable complete G2H which is
+* wrong as this creates a race between the request cancellation code
+* re-submitting the context and this G2H handler. This is a bug in the
+* GuC but can be worked around in the meantime but converting this to a
+* NOP if a pending enable is in flight as this indicates that a request
+* cancellation has occurred.
 */
-   clr_context_enabled(ce);
+   spin_lock_irqsave(>guc_state.lock, flags);
+   if (likely(!context_pending_enable(ce)))
+   clr_context_enabled(ce);
+   else
+   skip = true;
+   spin_unlock_irqrestore(>guc_state.lock, flags);
+   if (unlikely(skip))
+   goto out_put;
 
rq = intel_context_find_active_request(ce);
if (!rq) {
@@ -862,6 +878,7 @@ static void __guc_reset_context(struct intel_context *ce, 
bool stalled)
 out_replay:
guc_reset_state(ce, head, stalled);
__unwind_incomplete_requests(ce);
+out_put:
intel_context_put(ce);
 }
 
@@ -1598,6 +1615,13 @@ static void guc_context_cancel_request(struct 
intel_context *ce,
guc_reset_state(ce, intel_ring_wrap(ce->ring, rq->head),
true);
}
+
+   /*
+* XXX: Racey if context is reset, see comment in
+* __guc_reset_context().
+*/
+   flush_work(_to_guc(ce)->ct.requests.worker);
+
guc_context_unblock(ce);
}
 }
@@ -2712,7 +2736,12 @@ static void guc_handle_context_reset(struct intel_guc 
*guc,
 {
trace_intel_context_reset(ce);
 
-   if (likely(!intel_context_is_banned(ce))) {
+   /*
+* XXX: Racey if request cancellation has occurred, see comment in
+* __guc_reset_context().
+*/
+   if (likely(!intel_context_is_banned(ce) &&
+  !context_blocked(ce))) {
capture_error_state(guc, ce);
guc_context_replay(ce);
}
-- 
2.25.1



[PATCH v5 02/25] drm/i915/guc: Fix outstanding G2H accounting

2021-09-01 Thread Daniele Ceraolo Spurio
From: Matthew Brost 

A small race that could result in incorrect accounting of the number
of outstanding G2H. Basically prior to this patch we did not increment
the number of outstanding G2H if we encoutered a GT reset while sending
a H2G. This was incorrect as the context state had already been updated
to anticipate a G2H response thus the counter should be incremented.

As part of this change we remove a legacy (now unused) path that was the
last caller requiring a G2H response that was not guaranteed to loop.
This allows us to simplify the accounting as we don't need to handle the
case where the send fails due to the channel being busy.

Also always use helper when decrementing this value.

v2 (Daniele): update GEM_BUG_ON check, pull in dead code removal from
later patch, remove loop param from context_deregister.

Fixes: f4eb1f3fe946 ("drm/i915/guc: Ensure G2H response has space in buffer")
Signed-off-by: Matthew Brost 
Signed-off-by: Daniele Ceraolo Spurio 
Cc: 
---
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 79 +--
 1 file changed, 37 insertions(+), 42 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 69faa39da178..aff5dd247a88 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -352,20 +352,29 @@ static inline void set_lrc_desc_registered(struct 
intel_guc *guc, u32 id,
xa_unlock_irqrestore(>context_lookup, flags);
 }
 
+static void decr_outstanding_submission_g2h(struct intel_guc *guc)
+{
+   if (atomic_dec_and_test(>outstanding_submission_g2h))
+   wake_up_all(>ct.wq);
+}
+
 static int guc_submission_send_busy_loop(struct intel_guc *guc,
 const u32 *action,
 u32 len,
 u32 g2h_len_dw,
 bool loop)
 {
-   int err;
-
-   err = intel_guc_send_busy_loop(guc, action, len, g2h_len_dw, loop);
+   /*
+* We always loop when a send requires a reply (i.e. g2h_len_dw > 0),
+* so we don't handle the case where we don't get a reply because we
+* aborted the send due to the channel being busy.
+*/
+   GEM_BUG_ON(g2h_len_dw && !loop);
 
-   if (!err && g2h_len_dw)
+   if (g2h_len_dw)
atomic_inc(>outstanding_submission_g2h);
 
-   return err;
+   return intel_guc_send_busy_loop(guc, action, len, g2h_len_dw, loop);
 }
 
 int intel_guc_wait_for_pending_msg(struct intel_guc *guc,
@@ -616,7 +625,7 @@ static void scrub_guc_desc_for_outstanding_g2h(struct 
intel_guc *guc)
init_sched_state(ce);
 
if (pending_enable || destroyed || deregister) {
-   atomic_dec(>outstanding_submission_g2h);
+   decr_outstanding_submission_g2h(guc);
if (deregister)
guc_signal_context_fence(ce);
if (destroyed) {
@@ -635,7 +644,7 @@ static void scrub_guc_desc_for_outstanding_g2h(struct 
intel_guc *guc)
intel_engine_signal_breadcrumbs(ce->engine);
}
intel_context_sched_disable_unpin(ce);
-   atomic_dec(>outstanding_submission_g2h);
+   decr_outstanding_submission_g2h(guc);
spin_lock_irqsave(>guc_state.lock, flags);
guc_blocked_fence_complete(ce);
spin_unlock_irqrestore(>guc_state.lock, flags);
@@ -1233,8 +1242,7 @@ static int register_context(struct intel_context *ce, 
bool loop)
 }
 
 static int __guc_action_deregister_context(struct intel_guc *guc,
-  u32 guc_id,
-  bool loop)
+  u32 guc_id)
 {
u32 action[] = {
INTEL_GUC_ACTION_DEREGISTER_CONTEXT,
@@ -1243,16 +1251,16 @@ static int __guc_action_deregister_context(struct 
intel_guc *guc,
 
return guc_submission_send_busy_loop(guc, action, ARRAY_SIZE(action),
 G2H_LEN_DW_DEREGISTER_CONTEXT,
-loop);
+true);
 }
 
-static int deregister_context(struct intel_context *ce, u32 guc_id, bool loop)
+static int deregister_context(struct intel_context *ce, u32 guc_id)
 {
struct intel_guc *guc = ce_to_guc(ce);
 
trace_intel_context_deregister(ce);
 
-   return __guc_action_deregister_context(guc, guc_id, loop);
+   return __guc_action_deregister_context(guc, guc_id);
 }
 
 static intel_engine_mask_t adjust_engine_mask(u8 class, intel_engine_mask_t 
mask)
@@ -1340,26 +1348,23 @@ static int guc_lrc_desc_pin(struct intel_context *ce, 

[PATCH v5 05/25] drm/i915/guc: Process all G2H message at once in work queue

2021-09-01 Thread Daniele Ceraolo Spurio
From: Matthew Brost 

Rather than processing 1 G2H at a time and re-queuing the work queue if
more messages exist, process all the G2H in a single pass of the work
queue.

Signed-off-by: Matthew Brost 
Reviewed-by: Daniele Ceraolo Spurio 
Cc: Daniel Vetter 
Cc: Michal Wajdeczko 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
index 22b4733b55e2..20c710a74498 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
@@ -1042,9 +1042,9 @@ static void ct_incoming_request_worker_func(struct 
work_struct *w)
container_of(w, struct intel_guc_ct, requests.worker);
bool done;
 
-   done = ct_process_incoming_requests(ct);
-   if (!done)
-   queue_work(system_unbound_wq, >requests.worker);
+   do {
+   done = ct_process_incoming_requests(ct);
+   } while (!done);
 }
 
 static int ct_handle_event(struct intel_guc_ct *ct, struct ct_incoming_msg 
*request)
-- 
2.25.1



[PATCH v5 03/25] drm/i915/guc: Unwind context requests in reverse order

2021-09-01 Thread Daniele Ceraolo Spurio
From: Matthew Brost 

When unwinding requests on a reset context, if other requests in the
context are in the priority list the requests could be resubmitted out
of seqno order. Traverse the list of active requests in reverse and
append to the head of the priority list to fix this.

Fixes: eb5e7da736f3 ("drm/i915/guc: Reset implementation for new GuC interface")
Signed-off-by: Matthew Brost 
Reviewed-by: Daniele Ceraolo Spurio 
Cc: 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 8 
 1 file changed, 4 insertions(+), 4 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 aff5dd247a88..0c1e6b465fba 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -806,9 +806,9 @@ __unwind_incomplete_requests(struct intel_context *ce)
 
spin_lock_irqsave(_engine->lock, flags);
spin_lock(>guc_active.lock);
-   list_for_each_entry_safe(rq, rn,
->guc_active.requests,
-sched.link) {
+   list_for_each_entry_safe_reverse(rq, rn,
+>guc_active.requests,
+sched.link) {
if (i915_request_completed(rq))
continue;
 
@@ -825,7 +825,7 @@ __unwind_incomplete_requests(struct intel_context *ce)
}
GEM_BUG_ON(i915_sched_engine_is_empty(sched_engine));
 
-   list_add_tail(>sched.link, pl);
+   list_add(>sched.link, pl);
set_bit(I915_FENCE_FLAG_PQUEUE, >fence.flags);
 
spin_lock(>guc_active.lock);
-- 
2.25.1



[PATCH v5 01/25] drm/i915/guc: Fix blocked context accounting

2021-09-01 Thread Daniele Ceraolo Spurio
From: Matthew Brost 

Prior to this patch the blocked context counter was cleared on
init_sched_state (used during registering a context & resets) which is
incorrect. This state needs to be persistent or the counter can read the
incorrect value resulting in scheduling never getting enabled again.

Fixes: 62eaf0ae217d ("drm/i915/guc: Support request cancellation")
Signed-off-by: Matthew Brost 
Reviewed-by: Daniel Vetter 
Cc: 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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 87d8dc8f51b9..69faa39da178 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -152,7 +152,7 @@ static inline void init_sched_state(struct intel_context 
*ce)
 {
/* Only should be called from guc_lrc_desc_pin() */
atomic_set(>guc_sched_state_no_lock, 0);
-   ce->guc_state.sched_state = 0;
+   ce->guc_state.sched_state &= SCHED_STATE_BLOCKED_MASK;
 }
 
 static inline bool
-- 
2.25.1



[PATCH v5 00/25] Clean up GuC CI failures, simplify locking, and kernel DOC

2021-09-01 Thread Daniele Ceraolo Spurio
Daniel Vetter pointed out that locking in the GuC submission code was
overly complicated, let's clean this up a bit before introducing more
features in the GuC submission backend.

Also fix some CI failures, port fixes from our internal tree, and add a
few more selftests for coverage.

Lastly, add some kernel DOC explaining how the GuC submission backend
works.

v2: Fix logic error in 'Workaround reset G2H is received after schedule
done G2H', don't propagate errors to dependent fences in execlists
submissiom, resolve checkpatch issues, resend to correct lists
v3: Fix issue kicking tasklet, drop guc_active, fix ref counting in
xarray, add guc_id sub structure, drop inline fuctions, and various
other cleanup suggested by Daniel
v4: Address Daniele's feedback, rebase to tip, resend for CI
v5 [Daniele taking over while Matt is out]: drop patches 8 and 27 for
now (not critical, Matt will update and resend when he's back), address
review comments, improve kerneldoc. Also move all code related to busy
loop to patch 2 so we have a standalone fix.

Signed-off-by: Matthew Brost 
Signed-off-by: Daniele Ceraolo Spurio  #v5

Matthew Brost (25):
  drm/i915/guc: Fix blocked context accounting
  drm/i915/guc: Fix outstanding G2H accounting
  drm/i915/guc: Unwind context requests in reverse order
  drm/i915/guc: Don't drop ce->guc_active.lock when unwinding context
  drm/i915/guc: Process all G2H message at once in work queue
  drm/i915/guc: Workaround reset G2H is received after schedule done G2H
  Revert "drm/i915/gt: Propagate change in error status to children on
unhold"
  drm/i915/guc: Kick tasklet after queuing a request
  drm/i915/guc: Don't enable scheduling on a banned context, guc_id
invalid, not registered
  drm/i915/guc: Copy whole golden context, set engine state size of
subset
  drm/i915/selftests: Add initial GuC selftest for scrubbing lost G2H
  drm/i915/guc: Take context ref when cancelling request
  drm/i915/guc: Don't touch guc_state.sched_state without a lock
  drm/i915/guc: Reset LRC descriptor if register returns -ENODEV
  drm/i915: Allocate error capture in nowait context
  drm/i915/guc: Flush G2H work queue during reset
  drm/i915/guc: Release submit fence from an irq_work
  drm/i915/guc: Move guc_blocked fence to struct guc_state
  drm/i915/guc: Rework and simplify locking
  drm/i915/guc: Proper xarray usage for contexts_lookup
  drm/i915/guc: Drop pin count check trick between sched_disable and
re-pin
  drm/i915/guc: Move GuC priority fields in context under guc_active
  drm/i915/guc: Move fields protected by guc->contexts_lock into sub
structure
  drm/i915/guc: Drop guc_active move everything into guc_state
  drm/i915/guc: Add GuC kernel doc

 Documentation/gpu/i915.rst|   2 +
 drivers/gpu/drm/i915/gt/intel_context.c   |  19 +-
 drivers/gpu/drm/i915/gt/intel_context_types.h |  80 +-
 .../drm/i915/gt/intel_execlists_submission.c  |   4 -
 drivers/gpu/drm/i915/gt/selftest_hangcheck.c  |   6 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|  68 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c|  26 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c |   6 +-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 921 +++---
 drivers/gpu/drm/i915/gt/uc/selftest_guc.c | 127 +++
 drivers/gpu/drm/i915/i915_gpu_error.c |  39 +-
 drivers/gpu/drm/i915/i915_request.h   |  26 +-
 drivers/gpu/drm/i915/i915_trace.h |  12 +-
 .../drm/i915/selftests/i915_live_selftests.h  |   1 +
 .../i915/selftests/intel_scheduler_helpers.c  |  12 +
 .../i915/selftests/intel_scheduler_helpers.h  |   2 +
 16 files changed, 884 insertions(+), 467 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/uc/selftest_guc.c

-- 
2.25.1



[PATCH v2 3/5] drm: rcar-du: Fix DIDSR field name

2021-09-01 Thread Kieran Bingham
The DIDSR fields named LDCS were incorrectly defined as LCDS.
Both the Gen2 and Gen3 documentation refer to the fields as the "LVDS
Dot Clock Select".

Correct the definitions.

Signed-off-by: Kieran Bingham 

---
v2:
 - New patch

 drivers/gpu/drm/rcar-du/rcar_du_group.c | 4 ++--
 drivers/gpu/drm/rcar-du/rcar_du_regs.h  | 8 
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c 
b/drivers/gpu/drm/rcar-du/rcar_du_group.c
index 88a783ceb3e9..a984eef265d2 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
@@ -122,10 +122,10 @@ static void rcar_du_group_setup_didsr(struct 
rcar_du_group *rgrp)
didsr = DIDSR_CODE;
for (i = 0; i < num_crtcs; ++i, ++rcrtc) {
if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index))
-   didsr |= DIDSR_LCDS_LVDS0(i)
+   didsr |= DIDSR_LDCS_LVDS0(i)
  |  DIDSR_PDCS_CLK(i, 0);
else
-   didsr |= DIDSR_LCDS_DCLKIN(i)
+   didsr |= DIDSR_LDCS_DCLKIN(i)
  |  DIDSR_PDCS_CLK(i, 0);
}
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_regs.h 
b/drivers/gpu/drm/rcar-du/rcar_du_regs.h
index fb9964949368..fb7c467aa484 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_regs.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_regs.h
@@ -257,10 +257,10 @@
 
 #define DIDSR  0x20028
 #define DIDSR_CODE (0x7790 << 16)
-#define DIDSR_LCDS_DCLKIN(n)   (0 << (8 + (n) * 2))
-#define DIDSR_LCDS_LVDS0(n)(2 << (8 + (n) * 2))
-#define DIDSR_LCDS_LVDS1(n)(3 << (8 + (n) * 2))
-#define DIDSR_LCDS_MASK(n) (3 << (8 + (n) * 2))
+#define DIDSR_LDCS_DCLKIN(n)   (0 << (8 + (n) * 2))
+#define DIDSR_LDCS_LVDS0(n)(2 << (8 + (n) * 2))
+#define DIDSR_LDCS_LVDS1(n)(3 << (8 + (n) * 2))
+#define DIDSR_LDCS_MASK(n) (3 << (8 + (n) * 2))
 #define DIDSR_PDCS_CLK(n, clk) (clk << ((n) * 2))
 #define DIDSR_PDCS_MASK(n) (3 << ((n) * 2))
 
-- 
2.30.2



[PATCH v2 4/5] drm: rcar-du: Split CRTC IRQ and Clock features

2021-09-01 Thread Kieran Bingham
Not all platforms require both per-crtc IRQ and per-crtc clock
management. In preparation for suppporting such platforms, split the
feature macro to be able to specify both features independently.

The other features are incremented accordingly, to keep the two crtc
features adjacent.

Signed-off-by: Kieran Bingham 
---
v2:
 - New patch

 drivers/gpu/drm/rcar-du/rcar_du_crtc.c |  4 +--
 drivers/gpu/drm/rcar-du/rcar_du_drv.c  | 48 +-
 drivers/gpu/drm/rcar-du/rcar_du_drv.h  |  9 ++---
 3 files changed, 39 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c 
b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index a0f837e8243a..5672830ca184 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -1206,7 +1206,7 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, 
unsigned int swindex,
int ret;
 
/* Get the CRTC clock and the optional external clock. */
-   if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_IRQ_CLOCK)) {
+   if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_CLOCK)) {
sprintf(clk_name, "du.%u", hwindex);
name = clk_name;
} else {
@@ -1272,7 +1272,7 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, 
unsigned int swindex,
drm_crtc_helper_add(crtc, _helper_funcs);
 
/* Register the interrupt handler. */
-   if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_IRQ_CLOCK)) {
+   if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_IRQ)) {
/* The IRQ's are associated with the CRTC (sw)index. */
irq = platform_get_irq(pdev, swindex);
irqflags = 0;
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c 
b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index 4ac26d08ebb4..8a094d5b9c77 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -36,7 +36,8 @@
 
 static const struct rcar_du_device_info rzg1_du_r8a7743_info = {
.gen = 2,
-   .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
+   .features = RCAR_DU_FEATURE_CRTC_IRQ
+ | RCAR_DU_FEATURE_CRTC_CLOCK
  | RCAR_DU_FEATURE_INTERLACED
  | RCAR_DU_FEATURE_TVM_SYNC,
.channels_mask = BIT(1) | BIT(0),
@@ -58,7 +59,8 @@ static const struct rcar_du_device_info rzg1_du_r8a7743_info 
= {
 
 static const struct rcar_du_device_info rzg1_du_r8a7745_info = {
.gen = 2,
-   .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
+   .features = RCAR_DU_FEATURE_CRTC_IRQ
+ | RCAR_DU_FEATURE_CRTC_CLOCK
  | RCAR_DU_FEATURE_INTERLACED
  | RCAR_DU_FEATURE_TVM_SYNC,
.channels_mask = BIT(1) | BIT(0),
@@ -79,7 +81,8 @@ static const struct rcar_du_device_info rzg1_du_r8a7745_info 
= {
 
 static const struct rcar_du_device_info rzg1_du_r8a77470_info = {
.gen = 2,
-   .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
+   .features = RCAR_DU_FEATURE_CRTC_IRQ
+ | RCAR_DU_FEATURE_CRTC_CLOCK
  | RCAR_DU_FEATURE_INTERLACED
  | RCAR_DU_FEATURE_TVM_SYNC,
.channels_mask = BIT(1) | BIT(0),
@@ -105,7 +108,8 @@ static const struct rcar_du_device_info 
rzg1_du_r8a77470_info = {
 
 static const struct rcar_du_device_info rcar_du_r8a774a1_info = {
.gen = 3,
-   .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
+   .features = RCAR_DU_FEATURE_CRTC_IRQ
+ | RCAR_DU_FEATURE_CRTC_CLOCK
  | RCAR_DU_FEATURE_VSP1_SOURCE
  | RCAR_DU_FEATURE_INTERLACED
  | RCAR_DU_FEATURE_TVM_SYNC,
@@ -134,7 +138,8 @@ static const struct rcar_du_device_info 
rcar_du_r8a774a1_info = {
 
 static const struct rcar_du_device_info rcar_du_r8a774b1_info = {
.gen = 3,
-   .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
+   .features = RCAR_DU_FEATURE_CRTC_IRQ
+ | RCAR_DU_FEATURE_CRTC_CLOCK
  | RCAR_DU_FEATURE_VSP1_SOURCE
  | RCAR_DU_FEATURE_INTERLACED
  | RCAR_DU_FEATURE_TVM_SYNC,
@@ -163,7 +168,8 @@ static const struct rcar_du_device_info 
rcar_du_r8a774b1_info = {
 
 static const struct rcar_du_device_info rcar_du_r8a774c0_info = {
.gen = 3,
-   .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
+   .features = RCAR_DU_FEATURE_CRTC_IRQ
+ | RCAR_DU_FEATURE_CRTC_CLOCK
  | RCAR_DU_FEATURE_VSP1_SOURCE,
.channels_mask = BIT(1) | BIT(0),
.routes = {
@@ -189,7 +195,8 @@ static const struct rcar_du_device_info 
rcar_du_r8a774c0_info = {
 
 static const struct rcar_du_device_info rcar_du_r8a774e1_info = {
.gen = 3,
-   .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK
+   .features = RCAR_DU_FEATURE_CRTC_IRQ
+ | RCAR_DU_FEATURE_CRTC_CLOCK
  | RCAR_DU_FEATURE_VSP1_SOURCE
  | RCAR_DU_FEATURE_INTERLACED
  | RCAR_DU_FEATURE_TVM_SYNC,
@@ -239,7 +246,8 @@ 

[PATCH v2 5/5] drm: rcar-du: Add r8a779a0 device support

2021-09-01 Thread Kieran Bingham
From: Kieran Bingham 

Extend the rcar_du_device_info structure and rcar_du_output enum to
support DSI outputs and utilise these additions to provide support for
the R8A779A0 V3U platform.

While the DIDSR register field is now named "DSI/CSI-2-TX-IF0 Dot Clock
Select" the existing define LVDS0 is used, and is directly compatible
from other DU variants.

Signed-off-by: Kieran Bingham 

---

I can add a macro named DIDSR_LDCS_DSI0 duplicating DIDSR_LDCS_LVDS0 if
it's deemed better.

v2:
 - No longer requires a direct interface with the DSI encoder
 - Use correct field naming (LDCS)
 - Remove per-crtc clock feature.

 drivers/gpu/drm/rcar-du/rcar_du_crtc.h  |  2 ++
 drivers/gpu/drm/rcar-du/rcar_du_drv.c   | 20 
 drivers/gpu/drm/rcar-du/rcar_du_drv.h   |  2 ++
 drivers/gpu/drm/rcar-du/rcar_du_group.c |  2 ++
 4 files changed, 26 insertions(+)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h 
b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
index 440e6b4fbb58..26e79b74898c 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
@@ -96,6 +96,8 @@ struct rcar_du_crtc_state {
 enum rcar_du_output {
RCAR_DU_OUTPUT_DPAD0,
RCAR_DU_OUTPUT_DPAD1,
+   RCAR_DU_OUTPUT_DSI0,
+   RCAR_DU_OUTPUT_DSI1,
RCAR_DU_OUTPUT_HDMI0,
RCAR_DU_OUTPUT_HDMI1,
RCAR_DU_OUTPUT_LVDS0,
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c 
b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index 8a094d5b9c77..8b4c8851b6bc 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -489,6 +489,25 @@ static const struct rcar_du_device_info 
rcar_du_r8a7799x_info = {
.lvds_clk_mask =  BIT(1) | BIT(0),
 };
 
+static const struct rcar_du_device_info rcar_du_r8a779a0_info = {
+   .gen = 3,
+   .features = RCAR_DU_FEATURE_CRTC_IRQ
+ | RCAR_DU_FEATURE_VSP1_SOURCE,
+   .channels_mask = BIT(1) | BIT(0),
+   .routes = {
+   /* R8A779A0 has two MIPI DSI outputs. */
+   [RCAR_DU_OUTPUT_DSI0] = {
+   .possible_crtcs = BIT(0),
+   .port = 0,
+   },
+   [RCAR_DU_OUTPUT_DSI1] = {
+   .possible_crtcs = BIT(1),
+   .port = 1,
+   },
+   },
+   .dsi_clk_mask =  BIT(1) | BIT(0),
+};
+
 static const struct of_device_id rcar_du_of_table[] = {
{ .compatible = "renesas,du-r8a7742", .data = _du_r8a7790_info },
{ .compatible = "renesas,du-r8a7743", .data = _du_r8a7743_info },
@@ -513,6 +532,7 @@ static const struct of_device_id rcar_du_of_table[] = {
{ .compatible = "renesas,du-r8a77980", .data = _du_r8a77970_info },
{ .compatible = "renesas,du-r8a77990", .data = _du_r8a7799x_info },
{ .compatible = "renesas,du-r8a77995", .data = _du_r8a7799x_info },
+   { .compatible = "renesas,du-r8a779a0", .data = _du_r8a779a0_info },
{ }
 };
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h 
b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
index 5fe9152454ff..cf98d43d72d0 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
@@ -57,6 +57,7 @@ struct rcar_du_output_routing {
  * @routes: array of CRTC to output routes, indexed by output 
(RCAR_DU_OUTPUT_*)
  * @num_lvds: number of internal LVDS encoders
  * @dpll_mask: bit mask of DU channels equipped with a DPLL
+ * @dsi_clk_mask: bitmask of channels that can use the DSI clock as dot clock
  * @lvds_clk_mask: bitmask of channels that can use the LVDS clock as dot clock
  */
 struct rcar_du_device_info {
@@ -67,6 +68,7 @@ struct rcar_du_device_info {
struct rcar_du_output_routing routes[RCAR_DU_OUTPUT_MAX];
unsigned int num_lvds;
unsigned int dpll_mask;
+   unsigned int dsi_clk_mask;
unsigned int lvds_clk_mask;
 };
 
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c 
b/drivers/gpu/drm/rcar-du/rcar_du_group.c
index a984eef265d2..27c912bab76e 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c
@@ -124,6 +124,8 @@ static void rcar_du_group_setup_didsr(struct rcar_du_group 
*rgrp)
if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index))
didsr |= DIDSR_LDCS_LVDS0(i)
  |  DIDSR_PDCS_CLK(i, 0);
+   else if (rcdu->info->dsi_clk_mask & BIT(rcrtc->index))
+   didsr |= DIDSR_LDCS_LVDS0(i);
else
didsr |= DIDSR_LDCS_DCLKIN(i)
  |  DIDSR_PDCS_CLK(i, 0);
-- 
2.30.2



[PATCH v2 2/5] drm: rcar-du: Only initialise TVM_TVSYNC mode when supported

2021-09-01 Thread Kieran Bingham
The R-Car DU as found on the D3, E3, and V3U do not have support
for an external synchronisation method.

In these cases, the dsysr cached register should not be initialised
in DSYSR_TVM_TVSYNC, but instead should be left clear to configure as
DSYSR_TVM_MASTER by default.

Reviewed-by: Laurent Pinchart 
Signed-off-by: Kieran Bingham 

---
v2:
 - Remove parenthesis

 drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c 
b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
index ea7e39d03545..a0f837e8243a 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c
@@ -1243,7 +1243,10 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, 
unsigned int swindex,
rcrtc->group = rgrp;
rcrtc->mmio_offset = mmio_offsets[hwindex];
rcrtc->index = hwindex;
-   rcrtc->dsysr = (rcrtc->index % 2 ? 0 : DSYSR_DRES) | DSYSR_TVM_TVSYNC;
+   rcrtc->dsysr = rcrtc->index % 2 ? 0 : DSYSR_DRES;
+
+   if (rcar_du_has(rcdu, RCAR_DU_FEATURE_TVM_SYNC))
+   rcrtc->dsysr |= DSYSR_TVM_TVSYNC;
 
if (rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE))
primary = >vsp->planes[rcrtc->vsp_pipe].plane;
-- 
2.30.2



[PATCH v2 1/5] drm: rcar-du: Sort the DU outputs

2021-09-01 Thread Kieran Bingham
From: Kieran Bingham 

Sort the DU outputs alphabetically, with the exception of the final
entry which is there as a sentinal.

Reviewed-by: Laurent Pinchart 
Signed-off-by: Kieran Bingham 

---
v2:
 - Collect tag

 drivers/gpu/drm/rcar-du/rcar_du_crtc.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h 
b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
index 5f2940c42225..440e6b4fbb58 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
@@ -96,10 +96,10 @@ struct rcar_du_crtc_state {
 enum rcar_du_output {
RCAR_DU_OUTPUT_DPAD0,
RCAR_DU_OUTPUT_DPAD1,
-   RCAR_DU_OUTPUT_LVDS0,
-   RCAR_DU_OUTPUT_LVDS1,
RCAR_DU_OUTPUT_HDMI0,
RCAR_DU_OUTPUT_HDMI1,
+   RCAR_DU_OUTPUT_LVDS0,
+   RCAR_DU_OUTPUT_LVDS1,
RCAR_DU_OUTPUT_TCON,
RCAR_DU_OUTPUT_MAX,
 };
-- 
2.30.2



[PATCH v2] dt-bindings: display: renesas, du: Provide bindings for r8a779a0

2021-09-01 Thread Kieran Bingham
From: Kieran Bingham 

Extend the Renesas DU display bindings to support the r8a779a0 V3U.

Reviewed-by: Laurent Pinchart 
Signed-off-by: Kieran Bingham 
---
v2:
 - Collected Laurent's tag
 - Remove clock-names requirement
 - Specify only a single clock

 .../bindings/display/renesas,du.yaml  | 50 +++
 1 file changed, 50 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/renesas,du.yaml 
b/Documentation/devicetree/bindings/display/renesas,du.yaml
index e3ca5389c17d..a6f7ef30fbb4 100644
--- a/Documentation/devicetree/bindings/display/renesas,du.yaml
+++ b/Documentation/devicetree/bindings/display/renesas,du.yaml
@@ -39,6 +39,7 @@ properties:
   - renesas,du-r8a77980 # for R-Car V3H compatible DU
   - renesas,du-r8a77990 # for R-Car E3 compatible DU
   - renesas,du-r8a77995 # for R-Car D3 compatible DU
+  - renesas,du-r8a779a0 # for R-Car V3U compatible DU
 
   reg:
 maxItems: 1
@@ -773,6 +774,55 @@ allOf:
 - reset-names
 - renesas,vsps
 
+  - if:
+  properties:
+compatible:
+  contains:
+enum:
+  - renesas,du-r8a779a0
+then:
+  properties:
+clocks:
+  items:
+- description: Functional clock
+
+clock-names:
+  maxItems: 1
+  items:
+- const: du
+
+interrupts:
+  maxItems: 2
+
+resets:
+  maxItems: 1
+
+reset-names:
+  items:
+- const: du.0
+
+ports:
+  properties:
+port@0:
+  description: DSI 0
+port@1:
+  description: DSI 1
+port@2: false
+port@3: false
+
+  required:
+- port@0
+- port@1
+
+renesas,vsps:
+  minItems: 2
+
+  required:
+- interrupts
+- resets
+- reset-names
+- renesas,vsps
+
 additionalProperties: false
 
 examples:
-- 
2.30.2



Re: [PATCH] dt-bindings: display: renesas,du: Provide bindings for r8a779a0

2021-09-01 Thread Kieran Bingham
Hi Laurent,

On 01/09/2021 23:13, Laurent Pinchart wrote:
> Hi Kieran,
> 
> On Wed, Sep 01, 2021 at 11:01:11PM +0100, Kieran Bingham wrote:
>> On 23/06/2021 13:53, Geert Uytterhoeven wrote:
>>> On Wed, Jun 23, 2021 at 1:11 AM Kieran Bingham wrote:
 From: Kieran Bingham 

 Extend the Renesas DU display bindings to support the r8a779a0 V3U.

 Signed-off-by: Kieran Bingham 
>>>
>>> Thanks for your patch!
>>>
 --- a/Documentation/devicetree/bindings/display/renesas,du.yaml
 +++ b/Documentation/devicetree/bindings/display/renesas,du.yaml
 @@ -39,6 +39,7 @@ properties:
- renesas,du-r8a77980 # for R-Car V3H compatible DU
- renesas,du-r8a77990 # for R-Car E3 compatible DU
- renesas,du-r8a77995 # for R-Car D3 compatible DU
 +  - renesas,du-r8a779a0 # for R-Car V3U compatible DU

reg:
  maxItems: 1
 @@ -774,6 +775,57 @@ allOf:
  - reset-names
  - renesas,vsps

 +  - if:
 +  properties:
 +compatible:
 +  contains:
 +enum:
 +  - renesas,du-r8a779a0
 +then:
 +  properties:
 +clocks:
 +  items:
 +- description: Functional clock for DU0
 +- description: Functional clock for DU1
 +
 +clock-names:
 +  items:
 +- const: du.0
 +- const: du.1
>>>
>>> The hardware block has only a single function clock for both channels,
>>> like on R-Car H1.
>>
>> Indeed, but I believe both channels still need to set them, if they can
>> be operated independently, the driver looks up the clock based on the
>> du.%d, and so for DU1, it is simply expressed as the same clock in DT.
>>
>> Is this acceptable? or is there further issues there?
> 
> Could we handle that on the driver side, like we do for H1 by not
> setting RCAR_DU_FEATURE_CRTC_IRQ_CLOCK ? We would probably need to split
> that flag in two, as there are two interrupts.

Ok, that's not so bad to split, Done.


> It's a bit annoying not knowing what the MSTP bits do exactly, we've
> modelled them as gates for the functional clock, but maybe in cases like
> this one the mapping isn't fully correct, I'm not sure.
> 
>>> And what about DU_DOTCLKIN?
>>
>> This thread has already discussed this with Laurent, and I concur -
>> There doesn't appear to be any relevant reference to DU_DOTCLKIN on the
>> DU side.
> 


Re: [PATCH v3 06/16] ARM: configs: Everyone who had PANEL_SIMPLE now gets PANEL_SIMPLE_EDP

2021-09-01 Thread Doug Anderson
Hi,

On Wed, Sep 1, 2021 at 2:12 PM Olof Johansson  wrote:
>
> On Wed, Sep 1, 2021 at 1:20 PM Douglas Anderson  wrote:
> >
> > In the patch ("drm/panel-simple-edp: Split eDP panels out of
> > panel-simple") we split the PANEL_SIMPLE driver in 2. By default let's
> > give everyone who had the old driver enabled the new driver too. If
> > folks want to opt-out of one or the other they always can later.
> >
> > Signed-off-by: Douglas Anderson 
>
> Isn't this a case where the new option should just have had the old
> option as the default value to avoid this kind of churn and possibly
> broken platforms?

I'm happy to go either way. I guess I didn't do that originally
because logically there's not any reason to link the two drivers going
forward. Said another way, someone enabling the "simple panel" driver
for non-eDP panels wouldn't expect that the "simple panel" driver for
DP panels would also get enabled by default. They really have nothing
to do with one another. Enabling by default for something like this
also seems like it would lead to bloat. I could have sworn that
periodically people get yelled at for marking drivers on by default
when it doesn't make sense.

...that being said, I'm happy to change the default as you suggest.
Just let me know.

-Doug


Re: [PATCH v1 03/14] mm: add iomem vma selection for memory migration

2021-09-01 Thread Felix Kuehling

On 2021-09-01 6:03 p.m., Dave Chinner wrote:

On Wed, Sep 01, 2021 at 11:40:43AM -0400, Felix Kuehling wrote:

Am 2021-09-01 um 4:29 a.m. schrieb Christoph Hellwig:

On Mon, Aug 30, 2021 at 01:04:43PM -0400, Felix Kuehling wrote:

driver code is not really involved in updating the CPU mappings. Maybe
it's something we need to do in the migration helpers.

It looks like I'm totally misunderstanding what you are adding here
then.  Why do we need any special treatment at all for memory that
has normal struct pages and is part of the direct kernel map?

The pages are like normal memory for purposes of mapping them in CPU
page tables and for coherent access from the CPU.

That's the user page tables.  What about the kernel direct map?
If there is a normal kernel struct page backing there really should
be no need for the pgmap.

I'm not sure. The physical address ranges are in the UEFI system address
map as special-purpose memory. Does Linux create the struct pages and
kernel direct map for that without a pgmap call? I didn't see that last
time I went digging through that code.



 From an application
perspective, we want file-backed and anonymous mappings to be able to
use DEVICE_PUBLIC pages with coherent CPU access. The goal is to
optimize performance for GPU heavy workloads while minimizing the need
to migrate data back-and-forth between system memory and device memory.

I don't really understand that part.  file backed pages are always
allocated by the file system using the pagecache helpers, that is
using the page allocator.  Anonymouns memory also always comes from
the page allocator.

I'm coming at this from my experience with DEVICE_PRIVATE. Both
anonymous and file-backed pages should be migrateable to DEVICE_PRIVATE
memory by the migrate_vma_* helpers for more efficient access by our
GPU. (*) It's part of the basic premise of HMM as I understand it. I
would expect the same thing to work for DEVICE_PUBLIC memory.

(*) I believe migrating file-backed pages to DEVICE_PRIVATE doesn't
currently work, but that's something I'm hoping to fix at some point.

FWIW, I'd love to see the architecture documents that define how
filesystems are supposed to interact with this device private
memory. This whole "hand filesystem controlled memory to other
devices" is a minefield that is trivial to get wrong iand very
difficult to fix - just look at the historical mess that RDMA
to/from file backed and/or DAX pages has been.

So, really, from my perspective as a filesystem engineer, I want to
see an actual specification for how this new memory type is going to
interact with filesystem and the page cache so everyone has some
idea of how this is going to work and can point out how it doesn't
work before code that simply doesn't work is pushed out into
production systems and then merged


OK. To be clear, that's not part of this patch series. And I have no 
authority to push anything in this part of the kernel, so you have 
nothing to fear. ;)


FWIW, we already have the ability to map file-backed system memory pages 
into device page tables with HMM and interval notifiers. But we cannot 
currently migrate them to ZONE_DEVICE pages. Beyond that, my 
understanding of how filesystems and page cache work is rather 
superficial at this point. I'll keep your name in mind for when I am 
ready to discuss this in more detail.


Cheers,
  Felix




Cheers,

Dave.


Re: [PATCH v1 03/14] mm: add iomem vma selection for memory migration

2021-09-01 Thread Dave Chinner
On Wed, Sep 01, 2021 at 11:40:43AM -0400, Felix Kuehling wrote:
> 
> Am 2021-09-01 um 4:29 a.m. schrieb Christoph Hellwig:
> > On Mon, Aug 30, 2021 at 01:04:43PM -0400, Felix Kuehling wrote:
>  driver code is not really involved in updating the CPU mappings. Maybe
>  it's something we need to do in the migration helpers.
> >>> It looks like I'm totally misunderstanding what you are adding here
> >>> then.  Why do we need any special treatment at all for memory that
> >>> has normal struct pages and is part of the direct kernel map?
> >> The pages are like normal memory for purposes of mapping them in CPU
> >> page tables and for coherent access from the CPU.
> > That's the user page tables.  What about the kernel direct map?
> > If there is a normal kernel struct page backing there really should
> > be no need for the pgmap.
> 
> I'm not sure. The physical address ranges are in the UEFI system address
> map as special-purpose memory. Does Linux create the struct pages and
> kernel direct map for that without a pgmap call? I didn't see that last
> time I went digging through that code.
> 
> 
> >
> >> From an application
> >> perspective, we want file-backed and anonymous mappings to be able to
> >> use DEVICE_PUBLIC pages with coherent CPU access. The goal is to
> >> optimize performance for GPU heavy workloads while minimizing the need
> >> to migrate data back-and-forth between system memory and device memory.
> > I don't really understand that part.  file backed pages are always
> > allocated by the file system using the pagecache helpers, that is
> > using the page allocator.  Anonymouns memory also always comes from
> > the page allocator.
> 
> I'm coming at this from my experience with DEVICE_PRIVATE. Both
> anonymous and file-backed pages should be migrateable to DEVICE_PRIVATE
> memory by the migrate_vma_* helpers for more efficient access by our
> GPU. (*) It's part of the basic premise of HMM as I understand it. I
> would expect the same thing to work for DEVICE_PUBLIC memory.
> 
> (*) I believe migrating file-backed pages to DEVICE_PRIVATE doesn't
> currently work, but that's something I'm hoping to fix at some point.

FWIW, I'd love to see the architecture documents that define how
filesystems are supposed to interact with this device private
memory. This whole "hand filesystem controlled memory to other
devices" is a minefield that is trivial to get wrong iand very
difficult to fix - just look at the historical mess that RDMA
to/from file backed and/or DAX pages has been.

So, really, from my perspective as a filesystem engineer, I want to
see an actual specification for how this new memory type is going to
interact with filesystem and the page cache so everyone has some
idea of how this is going to work and can point out how it doesn't
work before code that simply doesn't work is pushed out into
production systems and then merged

Cheers,

Dave.
-- 
Dave Chinner
da...@fromorbit.com


Re: [PATCH] dt-bindings: display: renesas,du: Provide bindings for r8a779a0

2021-09-01 Thread Laurent Pinchart
Hi Kieran,

On Wed, Sep 01, 2021 at 11:01:11PM +0100, Kieran Bingham wrote:
> On 23/06/2021 13:53, Geert Uytterhoeven wrote:
> > On Wed, Jun 23, 2021 at 1:11 AM Kieran Bingham wrote:
> >> From: Kieran Bingham 
> >>
> >> Extend the Renesas DU display bindings to support the r8a779a0 V3U.
> >>
> >> Signed-off-by: Kieran Bingham 
> > 
> > Thanks for your patch!
> > 
> >> --- a/Documentation/devicetree/bindings/display/renesas,du.yaml
> >> +++ b/Documentation/devicetree/bindings/display/renesas,du.yaml
> >> @@ -39,6 +39,7 @@ properties:
> >>- renesas,du-r8a77980 # for R-Car V3H compatible DU
> >>- renesas,du-r8a77990 # for R-Car E3 compatible DU
> >>- renesas,du-r8a77995 # for R-Car D3 compatible DU
> >> +  - renesas,du-r8a779a0 # for R-Car V3U compatible DU
> >>
> >>reg:
> >>  maxItems: 1
> >> @@ -774,6 +775,57 @@ allOf:
> >>  - reset-names
> >>  - renesas,vsps
> >>
> >> +  - if:
> >> +  properties:
> >> +compatible:
> >> +  contains:
> >> +enum:
> >> +  - renesas,du-r8a779a0
> >> +then:
> >> +  properties:
> >> +clocks:
> >> +  items:
> >> +- description: Functional clock for DU0
> >> +- description: Functional clock for DU1
> >> +
> >> +clock-names:
> >> +  items:
> >> +- const: du.0
> >> +- const: du.1
> > 
> > The hardware block has only a single function clock for both channels,
> > like on R-Car H1.
> 
> Indeed, but I believe both channels still need to set them, if they can
> be operated independently, the driver looks up the clock based on the
> du.%d, and so for DU1, it is simply expressed as the same clock in DT.
> 
> Is this acceptable? or is there further issues there?

Could we handle that on the driver side, like we do for H1 by not
setting RCAR_DU_FEATURE_CRTC_IRQ_CLOCK ? We would probably need to split
that flag in two, as there are two interrupts.

It's a bit annoying not knowing what the MSTP bits do exactly, we've
modelled them as gates for the functional clock, but maybe in cases like
this one the mapping isn't fully correct, I'm not sure.

> > And what about DU_DOTCLKIN?
> 
> This thread has already discussed this with Laurent, and I concur -
> There doesn't appear to be any relevant reference to DU_DOTCLKIN on the
> DU side.

-- 
Regards,

Laurent Pinchart


Re: linux-next: build failure after merge of the hmm tree

2021-09-01 Thread Stephen Rothwell
Hi ,

On Mon, 23 Aug 2021 17:50:27 +1000 Stephen Rothwell  
wrote:
>
> Hi all,
> 
> After merging the hmm tree, today's linux-next build (x86_64 allmodconfig)
> failed like this:
> 
> drivers/gpu/drm/i915/gem/i915_gem_ttm.c: In function 'i915_ttm_tt_get_st':
> drivers/gpu/drm/i915/gem/i915_gem_ttm.c:396:7: error: implicit declaration of 
> function '__sg_alloc_table_from_pages'; did you mean 
> 'sg_alloc_table_from_pages'? [-Werror=implicit-function-declaration]
>   396 |  sg = __sg_alloc_table_from_pages
>   |   ^~~
>   |   sg_alloc_table_from_pages
> drivers/gpu/drm/i915/gem/i915_gem_ttm.c:396:5: warning: assignment to 'struct 
> scatterlist *' from 'int' makes pointer from integer without a cast 
> [-Wint-conversion]
>   396 |  sg = __sg_alloc_table_from_pages
>   | ^
> 
> Caused by commit
> 
>   fcbfe956561b ("lib/scatterlist: Provide a dedicated function to support 
> table append")
> 
> interacting with commit
> 
>   213d50927763 ("drm/i915/ttm: Introduce a TTM i915 gem object backend")
> 
> from the drm tree.
> 
> I have applied the following merge resolution patch.
> 
> From: Stephen Rothwell 
> Date: Mon, 23 Aug 2021 17:46:27 +1000
> Subject: [PATCH] drm/i915/ttm: fix up for "lib/scatterlist: Provide a
>  dedicated function to support tableappend"
> 
> Signed-off-by: Stephen Rothwell 
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 9 -
>  1 file changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c 
> b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> index 771eb2963123..d3d95934a047 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
> @@ -382,7 +382,6 @@ i915_ttm_region(struct ttm_device *bdev, int ttm_mem_type)
>  static struct sg_table *i915_ttm_tt_get_st(struct ttm_tt *ttm)
>  {
>   struct i915_ttm_tt *i915_tt = container_of(ttm, typeof(*i915_tt), ttm);
> - struct scatterlist *sg;
>   struct sg_table *st;
>   int ret;
>  
> @@ -393,13 +392,13 @@ static struct sg_table *i915_ttm_tt_get_st(struct 
> ttm_tt *ttm)
>   if (!st)
>   return ERR_PTR(-ENOMEM);
>  
> - sg = __sg_alloc_table_from_pages
> + ret = sg_alloc_table_from_pages_segment
>   (st, ttm->pages, ttm->num_pages, 0,
>(unsigned long)ttm->num_pages << PAGE_SHIFT,
> -  i915_sg_segment_size(), NULL, 0, GFP_KERNEL);
> - if (IS_ERR(sg)) {
> +  i915_sg_segment_size(), GFP_KERNEL);
> + if (ret) {
>   kfree(st);
> - return ERR_CAST(sg);
> + return ERR_PTR(ret);
>   }
>  
>   ret = dma_map_sgtable(i915_tt->dev, st, DMA_BIDIRECTIONAL, 0);

I am now applying this merge fix patch to the merge of the rdma tree
(since that has merged the hmm tree and the drm tree has been merged
upstream).

-- 
Cheers,
Stephen Rothwell


pgpQKICT9iDL_.pgp
Description: OpenPGP digital signature


Re: [PATCH] dt-bindings: display: renesas,du: Provide bindings for r8a779a0

2021-09-01 Thread Kieran Bingham
Hi Geert,

On 23/06/2021 13:53, Geert Uytterhoeven wrote:
> Hi Kieran,
> 
> On Wed, Jun 23, 2021 at 1:11 AM Kieran Bingham
>  wrote:
>> From: Kieran Bingham 
>>
>> Extend the Renesas DU display bindings to support the r8a779a0 V3U.
>>
>> Signed-off-by: Kieran Bingham 
> 
> Thanks for your patch!
> 
>> --- a/Documentation/devicetree/bindings/display/renesas,du.yaml
>> +++ b/Documentation/devicetree/bindings/display/renesas,du.yaml
>> @@ -39,6 +39,7 @@ properties:
>>- renesas,du-r8a77980 # for R-Car V3H compatible DU
>>- renesas,du-r8a77990 # for R-Car E3 compatible DU
>>- renesas,du-r8a77995 # for R-Car D3 compatible DU
>> +  - renesas,du-r8a779a0 # for R-Car V3U compatible DU
>>
>>reg:
>>  maxItems: 1
>> @@ -774,6 +775,57 @@ allOf:
>>  - reset-names
>>  - renesas,vsps
>>
>> +  - if:
>> +  properties:
>> +compatible:
>> +  contains:
>> +enum:
>> +  - renesas,du-r8a779a0
>> +then:
>> +  properties:
>> +clocks:
>> +  items:
>> +- description: Functional clock for DU0
>> +- description: Functional clock for DU1
>> +
>> +clock-names:
>> +  items:
>> +- const: du.0
>> +- const: du.1
> 
> The hardware block has only a single function clock for both channels,
> like on R-Car H1.

Indeed, but I believe both channels still need to set them, if they can
be operated independently, the driver looks up the clock based on the
du.%d, and so for DU1, it is simply expressed as the same clock in DT.

Is this acceptable? or is there further issues there?

> 
> And what about DU_DOTCLKIN?

This thread has already discussed this with Laurent, and I concur -
There doesn't appear to be any relevant reference to DU_DOTCLKIN on the
DU side.


> 
> Gr{oetje,eeting}s,
> 
> Geert
> 


Re: [PATCH 2/4] drm/dp_mst: Only create connector for connected end device

2021-09-01 Thread Lyude Paul
Actually - did some more thinking, and I think we shouldn't try to make
changes like this until we actually know what the problem is here. I could try
to figure out what the actual race conditions I was facing before with trying
to add/destroy connectors based on PDT, but we still don't even actually have
a clear idea of what's broken here. I'd much rather us figure out exactly how
this leak is happening before considering making changes like this, because we
have no way of knowing if we've properly fixed it or not if we don't know what
the problem is in the first place.

I'm still happy to write up the topology debugging stuff I mentioned to you if
you think that would help you debug this issue - since that would make it a
lot easier for you to track down what references are keeping a connector alive
(and additkionally, where those references were taken in code. thanks
stack_depot!)

On Tue, 2021-08-31 at 18:47 -0400, Lyude Paul wrote:
> (I am going to try responding to this tomorrow btw. I haven't been super
> busy
> this week, but this has been a surprisingly difficult email to respond to
> because I need to actually need to do a deep dive some of the MST helpers
> tomorrow to figure out more of the specifics on why I realized we couldn't
> just hot add/remove port->connector here).
> 
> On Wed, 2021-08-25 at 03:35 +, Lin, Wayne wrote:
> > [Public]
> > 
> > > -Original Message-
> > > From: Lyude Paul 
> > > Sent: Tuesday, August 24, 2021 5:18 AM
> > > To: Lin, Wayne ; dri-devel@lists.freedesktop.org
> > > Cc: Kazlauskas, Nicholas ; Wentland, Harry
> > > ; Zuo, Jerry
> > > ; Wu, Hersen ; Juston Li
> > > ; Imre Deak ;
> > > Ville Syrjälä ; Daniel Vetter
> > > ; Sean Paul ; Maarten Lankhorst
> > > ; Maxime Ripard ;
> > > Thomas Zimmermann ;
> > > David Airlie ; Daniel Vetter ;
> > > Deucher,
> > > Alexander ; Siqueira,
> > > Rodrigo ; Pillai, Aurabindo
> > > ; Bas Nieuwenhuizen
> > > ; Cornij, Nikola ; Jani
> > > Nikula ; Manasi Navare
> > > ; Ankit Nautiyal
> > > ;
> > > José Roberto de Souza ; Sean
> > > Paul ; Ben Skeggs ;
> > > sta...@vger.kernel.org
> > > Subject: Re: [PATCH 2/4] drm/dp_mst: Only create connector for connected
> > > end device
> > > 
> > > [snip]
> > > 
> > > I think I might still be misunderstanding something, some comments below
> > > 
> > > On Mon, 2021-08-23 at 06:33 +, Lin, Wayne wrote:
> > > > > > Hi Lyude,
> > > > > > 
> > > > > > Really thankful for willing to explain in such details. Really
> > > > > > appreciate.
> > > > > > 
> > > > > > I'm trying to fix some problems that observed after these 2
> > > > > > patches
> > > > > > * 09b974e8983 drm/amd/amdgpu_dm/mst: Remove ->destroy_connector()
> > > > > > callback
> > > > > > * 72dc0f51591 drm/dp_mst: Remove
> > > > > > drm_dp_mst_topology_cbs.destroy_connector
> > > > > > 
> > > > > > With above patches, we now change to remove dc_sink when connector
> > > > > > is about to be destroyed. However, we found out that connectors
> > > > > > won't get destroyed after hotplugs. Thus, after few times
> > > > > > hotplugs, we won't create any new dc_sink since number of sink is
> > > > > > exceeding our limitation. As the result of that, I'm trying to
> > > > > > figure out why the refcount of connectors won't get zero.
> > > > > > 
> > > > > > Based on my analysis, I found out that if we connect a sst monitor
> > > > > > to a mst hub then connect the hub to the system, and then unplug
> > > > > > the sst monitor from the hub. E.g.
> > > > > > src - mst hub - sst monitor => src - mst hub  (unplug) sst monitor
> > > > > > 
> > > > > > Within this case, we won't try to put refcount of the sst monitor.
> > > > > > Which is what I tried to resolve by [PATCH 3/4].
> > > > > > But here comes a problem which is confusing me that if I can
> > > > > > destroy connector in this case. By comparing to another case, if
> > > > > > now mst hub is connected with a mst monitor like this:
> > > > > > src - mst hub - mst monitor => src - mst hub  (unplug) mst monitor
> > > > > > 
> > > > > > We will put the topology refcount of mst monitor's branching unit
> > > > > > in and
> > > > > > drm_dp_port_set_pdt() and eventually call
> > > > > > drm_dp_delayed_destroy_port() to unregister the connector of the
> > > > > > logical port. So following the same rule, I think to dynamically
> > > > > > unregister a mst connector is what we want and should be
> > > > > > reasonable to also destroy sst connectors in my case. But this
> > > > > > conflicts the idea what we have here. We want to create connectors
> > > > > > for all output ports.
> > > > > > So if dynamically creating/destroying connectors is what we want,
> > > > > > when is the appropriate time for us to create one is what I'm
> > > > > > considering.
> > > > > > 
> > > > > > Take the StartTech hub DP 1to4 DP output ports for instance. This
> > > > > > hub, internally, is constructed by  3 1-to-2 mst branch chips. 2
> > > > > > output ports of 1st chip are hardwired to another 2 

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

2021-09-01 Thread Stephen Rothwell
Hi Masahiro,

On Fri, 20 Aug 2021 15:23:34 +0900 Masahiro Yamada  wrote:
>
> On Fri, Aug 20, 2021 at 11:33 AM Stephen Rothwell  
> wrote:
> >
> > Hi all,
> >
> > After merging the drm tree, today's linux-next build (x86_64 allmodconfig)
> > failed like this:
> >
> > In file included from drivers/gpu/drm/i915/i915_debugfs.c:39:
> > drivers/gpu/drm/i915/gt/intel_gt_requests.h:9:10: fatal error: stddef.h: No 
> > such file or directory
> > 9 | #include 
> >   |  ^~
> >
> > Caused by commit
> >
> >   564f963eabd1 ("isystem: delete global -isystem compile option")
> >
> > from the kbuild tree interacting with commit
> >
> >   b97060a99b01 ("drm/i915/guc: Update intel_gt_wait_for_idle to work with 
> > GuC")
> >
> > I have applied the following patch for today.  
> 
> 
> Thanks.
> 
> This fix-up does not depend on my kbuild tree in any way.
> 
> So, the drm maintainer can apply it to his tree.
> 
> Perhaps with
> 
> Fixes: b97060a99b01 ("drm/i915/guc: Update intel_gt_wait_for_idle to
> work with GuC")

OK, so that didn't happen so I will now apply the merge fix up to the
merge of the kbuild tree.

> > From: Stephen Rothwell 
> > Date: Fri, 20 Aug 2021 12:24:19 +1000
> > Subject: [PATCH] drm/i915: use linux/stddef.h due to "isystem: trim/fixup 
> > stdarg.h and other headers"
> >
> > Signed-off-by: Stephen Rothwell 
> > ---
> >  drivers/gpu/drm/i915/gt/intel_gt_requests.h | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/i915/gt/intel_gt_requests.h 
> > b/drivers/gpu/drm/i915/gt/intel_gt_requests.h
> > index 51dbe0e3294e..d2969f68dd64 100644
> > --- a/drivers/gpu/drm/i915/gt/intel_gt_requests.h
> > +++ b/drivers/gpu/drm/i915/gt/intel_gt_requests.h
> > @@ -6,7 +6,7 @@
> >  #ifndef INTEL_GT_REQUESTS_H
> >  #define INTEL_GT_REQUESTS_H
> >
> > -#include 
> > +#include 
> >
> >  struct intel_engine_cs;
> >  struct intel_gt;
> > --
> > 2.32.0

-- 
Cheers,
Stephen Rothwell


pgp8_qLvx_7Ey.pgp
Description: OpenPGP digital signature


[pull] amdgpu, amdkfd drm-next-5.15

2021-09-01 Thread Alex Deucher
Hi Dave, Daniel,

Fixes for 5.15.

The following changes since commit 8f0284f190e6a0aa09015090568c03f18288231a:

  Merge tag 'amd-drm-next-5.15-2021-08-27' of 
https://gitlab.freedesktop.org/agd5f/linux into drm-next (2021-08-30 09:06:03 
+1000)

are available in the Git repository at:

  https://gitlab.freedesktop.org/agd5f/linux.git 
tags/amd-drm-next-5.15-2021-09-01

for you to fetch changes up to d6043581e1d9d0507a8413a302db0e35c8506e0e:

  drm/amdkfd: drop process ref count when xnack disable (2021-09-01 16:55:09 
-0400)


amd-drm-next-5.15-2021-09-01:

amdgpu:
- Misc cleanups, typo fixes
- EEPROM fix
- Add some new PCI IDs
- Scatter/Gather display support for Yellow Carp
- PCIe DPM fix for RKL platforms
- RAS fix

amdkfd:
- SVM fix


Aaron Liu (1):
  drm/amd/display: setup system context for APUs

Alex Deucher (1):
  drm/amdgpu: add some additional RDNA2 PCI IDs

Alex Sierra (1):
  drm/amdkfd: drop process ref count when xnack disable

Angus Wang (1):
  drm/amd/display: cleanup idents after a revert

Anson Jacob (1):
  drm/amd/display: Fix memory leak reported by coverity

Colin Ian King (1):
  drm/amdgpu/swsmu: fix spelling mistake "minimun" -> "minimum"

Evan Quan (1):
  drm/amdgpu: reenable BACO support for 699F:C7 polaris12 SKU

Guchun Chen (1):
  drm/amdgpu: stop scheduler when calling hw_fini (v2)

Jiawei Gu (1):
  drm/amdgpu: enable more pm sysfs under SRIOV 1-VF mode

Jing Yangyang (1):
  drm:dcn31: fix boolreturn.cocci warnings

John Clements (1):
  drm/amdgpu: Clear RAS interrupt status on aldebaran

Kees Cook (1):
  drm/amd/pm: And destination bounds checking to struct copy

Koba Ko (1):
  drm/amdgpu: Disable PCIE_DPM on Intel RKL Platform

Lang Yu (1):
  drm/amdgpu: show both cmd id and name when psp cmd failed

Luben Tuikov (2):
  drm/amdgpu: Fixes to returning VBIOS RAS EEPROM address
  drm/amdgpu: Process any VBIOS RAS EEPROM address

Michael Strauss (1):
  drm/amd/display: Initialize lt_settings on instantiation

Nicholas Kazlauskas (1):
  drm/amdgpu: Enable S/G for Yellow Carp

Philip Yang (1):
  drm/amdgpu: fix fdinfo race with process exit

Yifan Zhang (1):
  drm/amdgpu: correct comments in memory type managers

YuBiao Wang (1):
  drm/amd/amdgpu: Add ready_to_reset resp for vega10

xinhui pan (1):
  drm/amdgpu: Fix a deadlock if previous GEM object allocation fails

 drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c   | 50 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c|  1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c| 17 
 drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c | 11 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c  |  8 
 drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c| 23 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c|  4 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c|  8 ++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c | 25 +--
 drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c   |  6 +--
 drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c  |  2 +
 drivers/gpu/drm/amd/amdgpu/mxgpu_ai.h  |  1 +
 drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c | 30 ++---
 drivers/gpu/drm/amd/amdgpu/vi.c|  9 +---
 drivers/gpu/drm/amd/amdkfd/kfd_svm.c   |  3 +-
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  |  2 +-
 drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c   |  6 +--
 .../drm/amd/display/dc/dcn303/dcn303_resource.c|  6 ++-
 .../drm/amd/display/dc/dcn31/dcn31_panel_cntl.c|  4 +-
 .../display/dc/dml/dcn20/display_mode_vba_20v2.c   |  2 +-
 drivers/gpu/drm/amd/pm/amdgpu_pm.c |  8 ++--
 drivers/gpu/drm/amd/pm/inc/amdgpu_smu.h| 24 +++
 .../gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c| 17 +++-
 drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c  |  6 +--
 drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c|  8 ++--
 drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c   |  2 +-
 drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c|  2 +-
 drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c |  5 +--
 .../gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c   |  2 +-
 29 files changed, 198 insertions(+), 94 deletions(-)


Re: [PATCH v3 06/16] ARM: configs: Everyone who had PANEL_SIMPLE now gets PANEL_SIMPLE_EDP

2021-09-01 Thread Olof Johansson
On Wed, Sep 1, 2021 at 1:20 PM Douglas Anderson  wrote:
>
> In the patch ("drm/panel-simple-edp: Split eDP panels out of
> panel-simple") we split the PANEL_SIMPLE driver in 2. By default let's
> give everyone who had the old driver enabled the new driver too. If
> folks want to opt-out of one or the other they always can later.
>
> Signed-off-by: Douglas Anderson 

Isn't this a case where the new option should just have had the old
option as the default value to avoid this kind of churn and possibly
broken platforms?


-Olof


Re: [PATCH 1/2] drm/sched: fix the bug of time out calculation(v4)

2021-09-01 Thread Alex Deucher
On Wed, Sep 1, 2021 at 2:50 AM Christian König
 wrote:
>
> Am 01.09.21 um 02:46 schrieb Monk Liu:
> > issue:
> > in cleanup_job the cancle_delayed_work will cancel a TO timer
> > even the its corresponding job is still running.
> >
> > fix:
> > do not cancel the timer in cleanup_job, instead do the cancelling
> > only when the heading job is signaled, and if there is a "next" job
> > we start_timeout again.
> >
> > v2:
> > further cleanup the logic, and do the TDR timer cancelling if the signaled 
> > job
> > is the last one in its scheduler.
> >
> > v3:
> > change the issue description
> > remove the cancel_delayed_work in the begining of the cleanup_job
> > recover the implement of drm_sched_job_begin.
> >
> > v4:
> > remove the kthread_should_park() checking in cleanup_job routine,
> > we should cleanup the signaled job asap
> >
> > TODO:
> > 1)introduce pause/resume scheduler in job_timeout to serial the handling
> > of scheduler and job_timeout.
> > 2)drop the bad job's del and insert in scheduler due to above serialization
> > (no race issue anymore with the serialization)
> >
> > tested-by: jingwen 
> > Signed-off-by: Monk Liu 
>
> Reviewed-by: Christian König 
>

Are you planning to push this to drm-misc?

Alex


> > ---
> >   drivers/gpu/drm/scheduler/sched_main.c | 26 +-
> >   1 file changed, 9 insertions(+), 17 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/scheduler/sched_main.c 
> > b/drivers/gpu/drm/scheduler/sched_main.c
> > index a2a9536..3e0bbc7 100644
> > --- a/drivers/gpu/drm/scheduler/sched_main.c
> > +++ b/drivers/gpu/drm/scheduler/sched_main.c
> > @@ -676,15 +676,6 @@ drm_sched_get_cleanup_job(struct drm_gpu_scheduler 
> > *sched)
> >   {
> >   struct drm_sched_job *job, *next;
> >
> > - /*
> > -  * Don't destroy jobs while the timeout worker is running  OR thread
> > -  * is being parked and hence assumed to not touch pending_list
> > -  */
> > - if ((sched->timeout != MAX_SCHEDULE_TIMEOUT &&
> > - !cancel_delayed_work(>work_tdr)) ||
> > - kthread_should_park())
> > - return NULL;
> > -
> >   spin_lock(>job_list_lock);
> >
> >   job = list_first_entry_or_null(>pending_list,
> > @@ -693,17 +684,21 @@ drm_sched_get_cleanup_job(struct drm_gpu_scheduler 
> > *sched)
> >   if (job && dma_fence_is_signaled(>s_fence->finished)) {
> >   /* remove job from pending_list */
> >   list_del_init(>list);
> > +
> > + /* cancel this job's TO timer */
> > + cancel_delayed_work(>work_tdr);
> >   /* make the scheduled timestamp more accurate */
> >   next = list_first_entry_or_null(>pending_list,
> >   typeof(*next), list);
> > - if (next)
> > +
> > + if (next) {
> >   next->s_fence->scheduled.timestamp =
> >   job->s_fence->finished.timestamp;
> > -
> > + /* start TO timer for next job */
> > + drm_sched_start_timeout(sched);
> > + }
> >   } else {
> >   job = NULL;
> > - /* queue timeout for next job */
> > - drm_sched_start_timeout(sched);
> >   }
> >
> >   spin_unlock(>job_list_lock);
> > @@ -791,11 +786,8 @@ static int drm_sched_main(void *param)
> > (entity = 
> > drm_sched_select_entity(sched))) ||
> >kthread_should_stop());
> >
> > - if (cleanup_job) {
> > + if (cleanup_job)
> >   sched->ops->free_job(cleanup_job);
> > - /* queue timeout for next job */
> > - drm_sched_start_timeout(sched);
> > - }
> >
> >   if (!entity)
> >   continue;
>


Re: [PATCH v3 08/16] MIPS: configs: Everyone who had PANEL_SIMPLE now gets PANEL_SIMPLE_EDP

2021-09-01 Thread Paul Cercueil

Hi Douglas,

Le mer., sept. 1 2021 at 13:19:26 -0700, Douglas Anderson 
 a écrit :

In the patch ("drm/panel-simple-edp: Split eDP panels out of
panel-simple") we split the PANEL_SIMPLE driver in 2. By default let's
give everyone who had the old driver enabled the new driver too. If
folks want to opt-out of one or the other they always can later.

Signed-off-by: Douglas Anderson 
---

(no changes since v1)

 arch/mips/configs/qi_lb60_defconfig | 1 +
 arch/mips/configs/rs90_defconfig| 1 +


The SoCs on these two boards don't support eDP, you can drop this patch.

Cheers,
-Paul


 2 files changed, 2 insertions(+)

diff --git a/arch/mips/configs/qi_lb60_defconfig 
b/arch/mips/configs/qi_lb60_defconfig

index b4448d0876d5..3e99e223ea02 100644
--- a/arch/mips/configs/qi_lb60_defconfig
+++ b/arch/mips/configs/qi_lb60_defconfig
@@ -72,6 +72,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_DRM=y
 CONFIG_DRM_FBDEV_OVERALLOC=200
 CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_PANEL_SIMPLE_EDP=y
 CONFIG_DRM_INGENIC=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 # CONFIG_VGA_CONSOLE is not set
diff --git a/arch/mips/configs/rs90_defconfig 
b/arch/mips/configs/rs90_defconfig

index 7ce3b814fdc8..42b4f621cbfa 100644
--- a/arch/mips/configs/rs90_defconfig
+++ b/arch/mips/configs/rs90_defconfig
@@ -94,6 +94,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_DRM=y
 CONFIG_DRM_FBDEV_OVERALLOC=300
 CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_PANEL_SIMPLE_EDP=y
 CONFIG_DRM_INGENIC=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 CONFIG_BACKLIGHT_PWM=y
--
2.33.0.259.gc128427fd7-goog






Re: VKMS: New plane formats

2021-09-01 Thread Simon Ser
Ideally the final composition format would have enough precision for
all of the planes. I think it'd make sense to use ARGB16161616 if the
primary plane uses ARGB and an overlay plane uses ARGB16161616.

To simplify the code, maybe it's fine to always use ARGB16161616 for
the output, and add getters which fetch an ARGB16161616 row for each
supported plane format.


[PATCH v3 16/16] drm/panel-simple-edp: Implement generic "edp-panel"s probed by EDID

2021-09-01 Thread Douglas Anderson
As discussed in the patch ("dt-bindings: drm/panel-simple: Introduce
generic eDP panels") we can actually support probing eDP panels at
runtime instead of hardcoding what panel is connected. Add support to
the panel-simple-edp driver for this.

We'll implement a solution like this:
* We'll read in two delays from the device tree that are used for
  powering up the panel the initial time (to read the EDID).
* In the EDID we can find a 32-bit ID that identifies what panel we've
  found. From this ID we can look up the full set of delays.

After this change we'll still need to add per-panel delays into the
panel-simple driver but we will no longer need to specify exactly
which panel is connected to which board in the device tree. Nicely,
any panels that are only supported this way also don't need to
hardcode mode data since it's guaranteed that we can get that through
the EDID.

This patch will seed the ID-to-delay table with a few panels that I
have access to, many of which are on sc7180-trogdor devices.

Signed-off-by: Douglas Anderson 
---

Changes in v3:
- Generic "edp-panel" handled by the eDP panel driver now.
- Change init order to we power at the end.
- Adjust endianness of product ID.
- Fallback to conservative delays if panel not recognized.
- Add Sharp LQ116M1JW10 to table.
- Add AUO B116XAN06.1 to table.
- Rename delays more generically so they can be reused.

Changes in v2:
- Don't support a "fallback" panel. Probed panels must be probed.
- Not based on patch to copy "desc"--just allocate for probed panels.
- Add "-ms" suffix to delays.

 drivers/gpu/drm/panel/panel-simple-edp.c | 215 +--
 1 file changed, 201 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-simple-edp.c 
b/drivers/gpu/drm/panel/panel-simple-edp.c
index 90ba146426e4..1762a10d43b1 100644
--- a/drivers/gpu/drm/panel/panel-simple-edp.c
+++ b/drivers/gpu/drm/panel/panel-simple-edp.c
@@ -189,6 +189,20 @@ struct panel_desc {
struct panel_delay delay;
 };
 
+/**
+ * struct edp_panel_entry - Maps panel ID to delay / panel name.
+ */
+struct edp_panel_entry {
+   /** @panel_id: 32-bit ID for panel, encoded with encode_edid_id(). */
+   u32 panel_id;
+
+   /* @delay: The power sequencing delays needed for this panel. */
+   const struct panel_delay *delay;
+
+   /* @name: Name of this panel (for printing to logs). */
+   const char *name;
+};
+
 struct panel_edp {
struct drm_panel base;
bool enabled;
@@ -559,8 +573,15 @@ static int panel_edp_get_modes(struct drm_panel *panel,
pm_runtime_put_autosuspend(panel->dev);
}
 
-   /* add hard-coded panel modes */
-   num += panel_edp_get_non_edid_modes(p, connector);
+   /*
+* Add hard-coded panel modes. Don't call this if there are no timings
+* and no modes (the generic edp-panel case) because it will clobber
+* the display_info that was already set by drm_add_edid_modes().
+*/
+   if (p->desc->num_timings || p->desc->num_modes)
+   num += panel_edp_get_non_edid_modes(p, connector);
+   else if (!num)
+   dev_warn(p->base.dev, "No display modes\n");
 
/* set up connector's "panel orientation" property */
drm_connector_set_panel_orientation(connector, p->orientation);
@@ -641,6 +662,94 @@ static void panel_edp_parse_panel_timing_node(struct 
device *dev,
dev_err(dev, "Reject override mode: No display_timing found\n");
 }
 
+static const struct edp_panel_entry *find_edp_panel(u32 panel_id);
+
+static int generic_edp_panel_probe(struct device *dev, struct panel_edp *panel)
+{
+   const struct edp_panel_entry *edp_panel;
+   struct panel_desc *desc;
+   u32 panel_id;
+   char vend[4];
+   u16 product_id;
+   u32 reliable_ms = 0;
+   u32 absent_ms = 0;
+   int ret;
+
+   desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
+   if (!desc)
+   return -ENOMEM;
+   panel->desc = desc;
+
+   /*
+* Read the dts properties for the initial probe. These are used by
+* the runtime resume code which will get called by the
+* pm_runtime_get_sync() call below.
+*/
+   of_property_read_u32(dev->of_node, "hpd-reliable-delay-ms", 
_ms);
+   desc->delay.hpd_reliable = reliable_ms;
+   of_property_read_u32(dev->of_node, "hpd-absent-delay-ms", _ms);
+   desc->delay.hpd_reliable = absent_ms;
+
+   /* Power the panel on so we can read the EDID */
+   ret = pm_runtime_get_sync(dev);
+   if (ret < 0) {
+   dev_err(dev, "Couldn't power on panel to read EDID: %d\n", ret);
+   goto exit;
+   }
+
+   panel_id = drm_get_panel_id(panel->ddc);
+   if (!panel_id) {
+   dev_err(dev, "Couldn't identify panel via EDID\n");
+   ret = -EIO;
+   goto exit;
+   }
+   decode_edid_id(panel_id, vend, _id);
+
+   

[PATCH v3 15/16] drm/panel-simple-edp: Don't re-read the EDID every time we power off the panel

2021-09-01 Thread Douglas Anderson
The simple-panel driver is for panels that are not hot-pluggable at
runtime. Let's keep our cached EDID around until driver unload.

Signed-off-by: Douglas Anderson 
---

Changes in v3:
- ("Don't re-read the EDID every time") moved to eDP only patch.

 drivers/gpu/drm/panel/panel-simple-edp.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-simple-edp.c 
b/drivers/gpu/drm/panel/panel-simple-edp.c
index 5d58dc25ddf5..90ba146426e4 100644
--- a/drivers/gpu/drm/panel/panel-simple-edp.c
+++ b/drivers/gpu/drm/panel/panel-simple-edp.c
@@ -362,9 +362,6 @@ static int panel_edp_suspend(struct device *dev)
regulator_disable(p->supply);
p->unprepared_time = ktime_get();
 
-   kfree(p->edid);
-   p->edid = NULL;
-
return 0;
 }
 
@@ -758,6 +755,9 @@ static int panel_edp_remove(struct device *dev)
if (panel->ddc && (!panel->aux || panel->ddc != >aux->ddc))
put_device(>ddc->dev);
 
+   kfree(panel->edid);
+   panel->edid = NULL;
+
return 0;
 }
 
-- 
2.33.0.259.gc128427fd7-goog



[PATCH v3 14/16] drm/panel-simple-edp: Fix "prepare_to_enable" if panel doesn't handle HPD

2021-09-01 Thread Douglas Anderson
While cleaning up the descriptions of the delay for eDP panels I
realized that we'd have a bug if any panels need the
"prepare_to_enable" but HPD handling isn't happening in the panel
driver. Let's put in a stopgap to at least make us not violate
timings. This is not perfectly optimal but trying to do better is
hard. At the moment only 2 panels specify this delay and only 30 ms is
at stake. These panels are also currently hooked up with "hpd-gpios"
so effectively this "fix" is just a theoretical fix and won't actually
do anything for any devices currently supported in mainline.

Signed-off-by: Douglas Anderson 
---

Changes in v3:
- Fix "prepare_to_enable" patch new for v3.

 drivers/gpu/drm/panel/panel-simple-edp.c | 24 ++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-simple-edp.c 
b/drivers/gpu/drm/panel/panel-simple-edp.c
index 762589ef66c3..5d58dc25ddf5 100644
--- a/drivers/gpu/drm/panel/panel-simple-edp.c
+++ b/drivers/gpu/drm/panel/panel-simple-edp.c
@@ -508,12 +508,32 @@ static int panel_edp_prepare(struct drm_panel *panel)
 static int panel_edp_enable(struct drm_panel *panel)
 {
struct panel_edp *p = to_panel_edp(panel);
+   unsigned int delay;
 
if (p->enabled)
return 0;
 
-   if (p->desc->delay.enable)
-   msleep(p->desc->delay.enable);
+   delay = p->desc->delay.enable;
+
+   /*
+* If there is a "prepare_to_enable" delay then that's supposed to be
+* the delay from HPD going high until we can turn the backlight on.
+* However, we can only count this if HPD is handled by the panel
+* driver, not if it goes to a dedicated pin on the controller.
+* If we aren't handling the HPD pin ourselves then the best we
+* can do is assume that HPD went high immediately before we were
+* called (and link training took zero time).
+*
+* NOTE: if we ever end up in this "if" statement then we're
+* guaranteed that the panel_edp_wait() call below will do no delay.
+* It already handles that case, though, so we don't need any special
+* code for it.
+*/
+   if (p->desc->delay.prepare_to_enable && !p->hpd_gpio && !p->no_hpd)
+   delay = max(delay, p->desc->delay.prepare_to_enable);
+
+   if (delay)
+   msleep(delay);
 
panel_edp_wait(p->prepared_time, p->desc->delay.prepare_to_enable);
 
-- 
2.33.0.259.gc128427fd7-goog



[PATCH v3 13/16] drm/panel-simple-edp: hpd_reliable shouldn't be subtraced from hpd_absent

2021-09-01 Thread Douglas Anderson
Now that the delays are named / described with eDP-centric names, it
becomes clear that we should really specify the "hpd_reliable" and
"hpd_absent" separately without taking the other into account. Let's
fix it.

This should be a no-op change and just adjust how we specify
things. The actual delays should be the same before and after for the
one panel that currently species both "hpd_reliable" and "hpd_absent".

Signed-off-by: Douglas Anderson 
---

(no changes since v1)

 drivers/gpu/drm/panel/panel-simple-edp.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-simple-edp.c 
b/drivers/gpu/drm/panel/panel-simple-edp.c
index ede5e3e4920b..762589ef66c3 100644
--- a/drivers/gpu/drm/panel/panel-simple-edp.c
+++ b/drivers/gpu/drm/panel/panel-simple-edp.c
@@ -423,7 +423,7 @@ static int panel_edp_prepare_once(struct panel_edp *p)
 
delay = p->desc->delay.hpd_reliable;
if (p->no_hpd)
-   delay += p->desc->delay.hpd_absent;
+   delay = max(delay, p->desc->delay.hpd_absent);
if (delay)
msleep(delay);
 
@@ -1039,15 +1039,13 @@ static const struct panel_desc boe_nv133fhm_n61 = {
 * spike on the HPD line.  It was explained that this spike
 * was until the TCON data download was complete.  On
 * one system this was measured at 8 ms.  We'll put 15 ms
-* in the prepare delay just to be safe and take it away
-* from the hpd_absent (which would otherwise be 200 ms)
-* to handle this.  That means:
+* in the prepare delay just to be safe.  That means:
 * - If HPD isn't hooked up you still have 200 ms delay.
 * - If HPD is hooked up we won't try to look at it for the
 *   first 15 ms.
 */
.hpd_reliable = 15,
-   .hpd_absent = 185,
+   .hpd_absent = 200,
 
.unprepare = 500,
},
-- 
2.33.0.259.gc128427fd7-goog



[PATCH v3 12/16] drm/panel-simple-edp: Better describe eDP panel delays

2021-09-01 Thread Douglas Anderson
Now that the eDP panel driver only handles eDP panels we can make
better sense of the delays here. Let's describe them in terms of the
standard eDP timing diagram from the eDP spec.

As part of this, it becomes pretty clear that some eDP panels have too
long of a "hpd_reliable_delay". This used to be the "prepare"
delay. It's the fixed delay that we do in the panel driver after
powering on our panel before we look at the HPD signal. To understand
this better, first realize that there could be 3 paths we follow
depending on how HPD is hooked up. Let's walk through them:
1. HPD is handled by the eDP controller driver. Until "recently"
   (commit 48834e6084f1 ("drm/panel-simple: Support hpd-gpios for
   delaying prepare()") in May 2020) this was the only supported
   way. This is supposed to be when the controller driver gets HPD
   straight to a dedicated pin. In this case the controller driver
   should be waiting for HPD in its pre_enable() routine which should
   be called right after the panel's prepare() function is
   called. That means that the old "prepare" delay was only needed as
   a delay after powering the panel but before looking at HPD.
2. HPD is handled via hpd-gpios in the panel. This is much like #1 but
   much easier to follow since all the handling is in the panel
   driver.
3. The no-hpd case. This is also easy to follow.

In any case, even though it seems like some old panel data was using
this incorrectly, let's not touch the old data structures but we'll
add a note indicating that something seems off.

Signed-off-by: Douglas Anderson 
---

Changes in v3:
- ("Better describe eDP panel delays") new for v3.

 drivers/gpu/drm/panel/panel-simple-edp.c | 82 +++-
 1 file changed, 53 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-simple-edp.c 
b/drivers/gpu/drm/panel/panel-simple-edp.c
index d227adba92ec..ede5e3e4920b 100644
--- a/drivers/gpu/drm/panel/panel-simple-edp.c
+++ b/drivers/gpu/drm/panel/panel-simple-edp.c
@@ -45,20 +45,28 @@
  */
 struct panel_delay {
/**
-* @prepare: Time for the panel to become ready.
+* @hpd_reliable: Time for HPD to be reliable
 *
-* The time (in milliseconds) that it takes for the panel to
-* become ready and start receiving video data
+* The time (in milliseconds) that it takes after powering the panel
+* before the HPD signal is reliable. Ideally this is 0 but some panels,
+* board designs, or bad pulldown configs can cause a glitch here.
+*
+* NOTE: on some old panel data this number appers to be much too big.
+* Presumably some old panels simply didn't have HPD hooked up and put
+* the hpd_absent here because this field predates the
+* hpd_absent. While that works, it's non-ideal.
 */
-   unsigned int prepare;
+   unsigned int hpd_reliable;
 
/**
-* @hpd_absent_delay: Time to wait if HPD isn't hooked up.
+* @hpd_absent: Time to wait if HPD isn't hooked up.
 *
-* Add this to the prepare delay if we know Hot Plug Detect
-* isn't used.
+* Add this to the prepare delay if we know Hot Plug Detect isn't used.
+*
+* This is T3-max on eDP timing diagrams or the delay from power on
+* until HPD is guaranteed to be asserted.
 */
-   unsigned int hpd_absent_delay;
+   unsigned int hpd_absent;
 
/**
 * @prepare_to_enable: Time between prepare and enable.
@@ -87,6 +95,10 @@ struct panel_delay {
 *   enable()
 * // do fixed enable delay
 * // enforce prepare_to_enable min time
+*
+* This is not specified in a standard way on eDP timing diagrams.
+* It is effectively the time from HPD going high till you can
+* turn on the backlight.
 */
unsigned int prepare_to_enable;
 
@@ -96,6 +108,10 @@ struct panel_delay {
 * The time (in milliseconds) that it takes for the panel to
 * display the first valid frame after starting to receive
 * video data.
+*
+* This is (T6-min + max(T7-max, T8-min)) on eDP timing diagrams or
+* the delay after link training finishes until we can turn the
+* backlight on and see valid data.
 */
unsigned int enable;
 
@@ -104,6 +120,9 @@ struct panel_delay {
 *
 * The time (in milliseconds) that it takes for the panel to
 * turn the display off (no content is visible).
+*
+* This is T9-min (delay from backlight off to end of valid video
+* data) on eDP timing diagrams. It is not common to set.
 */
unsigned int disable;
 
@@ -117,6 +136,8 @@ struct panel_delay {
 * starting until at least this many milliseconds has passed.
 * If at prepare time less time has passed since unprepare
 * finished, the driver waits for the remaining time.

[PATCH v3 11/16] drm/panel-simple-edp: Split the delay structure out

2021-09-01 Thread Douglas Anderson
In the case where we can read an EDID for a panel the only part of the
panel description that can't be found directly from the EDID is the
description of the delays. Let's break the delay structure out so that
we can specify just the delays for panels that are detected by EDID.

This is simple code motion. No functional change is intended.

Signed-off-by: Douglas Anderson 
---

Changes in v3:
- Split the delay structure out patch just on eDP now.

 drivers/gpu/drm/panel/panel-simple-edp.c | 159 ---
 1 file changed, 82 insertions(+), 77 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-simple-edp.c 
b/drivers/gpu/drm/panel/panel-simple-edp.c
index 8acac5bb792e..d227adba92ec 100644
--- a/drivers/gpu/drm/panel/panel-simple-edp.c
+++ b/drivers/gpu/drm/panel/panel-simple-edp.c
@@ -40,6 +40,87 @@
 #include 
 #include 
 
+/**
+ * struct panel_delay - Describes delays for a simple panel.
+ */
+struct panel_delay {
+   /**
+* @prepare: Time for the panel to become ready.
+*
+* The time (in milliseconds) that it takes for the panel to
+* become ready and start receiving video data
+*/
+   unsigned int prepare;
+
+   /**
+* @hpd_absent_delay: Time to wait if HPD isn't hooked up.
+*
+* Add this to the prepare delay if we know Hot Plug Detect
+* isn't used.
+*/
+   unsigned int hpd_absent_delay;
+
+   /**
+* @prepare_to_enable: Time between prepare and enable.
+*
+* The minimum time, in milliseconds, that needs to have passed
+* between when prepare finished and enable may begin. If at
+* enable time less time has passed since prepare finished,
+* the driver waits for the remaining time.
+*
+* If a fixed enable delay is also specified, we'll start
+* counting before delaying for the fixed delay.
+*
+* If a fixed prepare delay is also specified, we won't start
+* counting until after the fixed delay. We can't overlap this
+* fixed delay with the min time because the fixed delay
+* doesn't happen at the end of the function if a HPD GPIO was
+* specified.
+*
+* In other words:
+*   prepare()
+* ...
+* // do fixed prepare delay
+* // wait for HPD GPIO if applicable
+* // start counting for prepare_to_enable
+*
+*   enable()
+* // do fixed enable delay
+* // enforce prepare_to_enable min time
+*/
+   unsigned int prepare_to_enable;
+
+   /**
+* @enable: Time for the panel to display a valid frame.
+*
+* The time (in milliseconds) that it takes for the panel to
+* display the first valid frame after starting to receive
+* video data.
+*/
+   unsigned int enable;
+
+   /**
+* @disable: Time for the panel to turn the display off.
+*
+* The time (in milliseconds) that it takes for the panel to
+* turn the display off (no content is visible).
+*/
+   unsigned int disable;
+
+   /**
+* @unprepare: Time to power down completely.
+*
+* The time (in milliseconds) that it takes for the panel
+* to power itself down completely.
+*
+* This time is used to prevent a future "prepare" from
+* starting until at least this many milliseconds has passed.
+* If at prepare time less time has passed since unprepare
+* finished, the driver waits for the remaining time.
+*/
+   unsigned int unprepare;
+};
+
 /**
  * struct panel_desc - Describes a simple panel.
  */
@@ -84,83 +165,7 @@ struct panel_desc {
} size;
 
/** @delay: Structure containing various delay values for this panel. */
-   struct {
-   /**
-* @delay.prepare: Time for the panel to become ready.
-*
-* The time (in milliseconds) that it takes for the panel to
-* become ready and start receiving video data
-*/
-   unsigned int prepare;
-
-   /**
-* @delay.hpd_absent_delay: Time to wait if HPD isn't hooked up.
-*
-* Add this to the prepare delay if we know Hot Plug Detect
-* isn't used.
-*/
-   unsigned int hpd_absent_delay;
-
-   /**
-* @delay.prepare_to_enable: Time between prepare and enable.
-*
-* The minimum time, in milliseconds, that needs to have passed
-* between when prepare finished and enable may begin. If at
-* enable time less time has passed since prepare finished,
-* the driver waits for the remaining time.
-*
-* If a fixed enable delay is also specified, 

[PATCH v3 10/16] drm/panel-simple: Non-eDP panels don't need "HPD" handling

2021-09-01 Thread Douglas Anderson
All of the "HPD" handling added to panel-simple recently was for eDP
panels. Remove it from panel-simple now that panel-simple-edp handles
eDP panels. The "prepare_to_enable" delay only makes sense in the
context of HPD, so remove it too. No non-eDP panels used it anyway.

Signed-off-by: Douglas Anderson 
---

Changes in v3:
- ("Non-eDP panels don't need "HPD" handling") new for v3.

 drivers/gpu/drm/panel/panel-simple.c | 134 +--
 1 file changed, 4 insertions(+), 130 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-simple.c 
b/drivers/gpu/drm/panel/panel-simple.c
index dcfec124d69d..abec01d9798e 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -23,7 +23,6 @@
 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -92,44 +91,6 @@ struct panel_desc {
 */
unsigned int prepare;
 
-   /**
-* @delay.hpd_absent_delay: Time to wait if HPD isn't hooked up.
-*
-* Add this to the prepare delay if we know Hot Plug Detect
-* isn't used.
-*/
-   unsigned int hpd_absent_delay;
-
-   /**
-* @delay.prepare_to_enable: Time between prepare and enable.
-*
-* The minimum time, in milliseconds, that needs to have passed
-* between when prepare finished and enable may begin. If at
-* enable time less time has passed since prepare finished,
-* the driver waits for the remaining time.
-*
-* If a fixed enable delay is also specified, we'll start
-* counting before delaying for the fixed delay.
-*
-* If a fixed prepare delay is also specified, we won't start
-* counting until after the fixed delay. We can't overlap this
-* fixed delay with the min time because the fixed delay
-* doesn't happen at the end of the function if a HPD GPIO was
-* specified.
-*
-* In other words:
-*   prepare()
-* ...
-* // do fixed prepare delay
-* // wait for HPD GPIO if applicable
-* // start counting for prepare_to_enable
-*
-*   enable()
-* // do fixed enable delay
-* // enforce prepare_to_enable min time
-*/
-   unsigned int prepare_to_enable;
-
/**
 * @delay.enable: Time for the panel to display a valid frame.
 *
@@ -174,7 +135,6 @@ struct panel_desc {
 struct panel_simple {
struct drm_panel base;
bool enabled;
-   bool no_hpd;
 
bool prepared;
 
@@ -187,7 +147,6 @@ struct panel_simple {
struct i2c_adapter *ddc;
 
struct gpio_desc *enable_gpio;
-   struct gpio_desc *hpd_gpio;
 
struct edid *edid;
 
@@ -371,30 +330,10 @@ static int panel_simple_unprepare(struct drm_panel *panel)
return 0;
 }
 
-static int panel_simple_get_hpd_gpio(struct device *dev, struct panel_simple 
*p)
-{
-   int err;
-
-   p->hpd_gpio = devm_gpiod_get_optional(dev, "hpd", GPIOD_IN);
-   if (IS_ERR(p->hpd_gpio)) {
-   err = PTR_ERR(p->hpd_gpio);
-
-   if (err != -EPROBE_DEFER)
-   dev_err(dev, "failed to get 'hpd' GPIO: %d\n", err);
-
-   return err;
-   }
-
-   return 0;
-}
-
-static int panel_simple_prepare_once(struct panel_simple *p)
+static int panel_simple_resume(struct device *dev)
 {
-   struct device *dev = p->base.dev;
-   unsigned int delay;
+   struct panel_simple *p = dev_get_drvdata(dev);
int err;
-   int hpd_asserted;
-   unsigned long hpd_wait_us;
 
panel_simple_wait(p->unprepared_time, p->desc->delay.unprepare);
 
@@ -406,68 +345,12 @@ static int panel_simple_prepare_once(struct panel_simple 
*p)
 
gpiod_set_value_cansleep(p->enable_gpio, 1);
 
-   delay = p->desc->delay.prepare;
-   if (p->no_hpd)
-   delay += p->desc->delay.hpd_absent_delay;
-   if (delay)
-   msleep(delay);
-
-   if (p->hpd_gpio) {
-   if (p->desc->delay.hpd_absent_delay)
-   hpd_wait_us = p->desc->delay.hpd_absent_delay * 1000UL;
-   else
-   hpd_wait_us = 200;
-
-   err = readx_poll_timeout(gpiod_get_value_cansleep, p->hpd_gpio,
-hpd_asserted, hpd_asserted,
-1000, hpd_wait_us);
-   if (hpd_asserted < 0)
-   err = hpd_asserted;
-
-   if (err) {
-   if (err != -ETIMEDOUT)
-   

[PATCH v3 09/16] drm/panel-simple-edp: Move some wayward panels to the eDP driver

2021-09-01 Thread Douglas Anderson
Not all panels in panel-simple were marked what type of panel they
were. I searched through ARM/ARM64 Chromebooks or Chromebook-related
reference boards that I was aware of and found some panels that needed
to be moved. I also skimmed for panels that had no mode and were "big"
since it's quite rare to see a small eDP panel. Here's what I found:
* auo,b101ean01 - rk3288-veyron-minnie
* auo,b133htn01 - exynos5800-peach-pi
* auo,b133xtn01 - tegra124-nyan-big
* boe,nv101wxmn51 - rk3399-gru-bob
* innolux,p120zdg-bf1 - sdm845-cheza
* lg,lp079qx1-sp0v - rk3399-evb and similar
* lg,lp097qx1-spa1 - According to commit 0355dde26e52 ("drm/panel:
  simple: Add support for LG LP097QX1-SPA1 panel") this is an eDP
  panel.
* lg,lp129qe - tegra124-venice2
* samsung,lsn122dl01-c01 - According to commit 0330eaf39082
  ("drm/panel: simple: Add support for Samsung LSN122DL01-C01 panel")
  this is an eDP panel.
* samsung,ltn140at29-301 - tegra124-nyan-blaze
* sharp,ld-d5116z01b - According to commit cd5e1cbe1f0a ("drm/panel:
  simple: Add support for Sharp LD-D5116Z01B panel") this is an eDP
  panel.
* sharp,lq123p1jx31 - rk3399-gru-kevin
* starry,kr122ea0sra - rk3399-gru-gru (reference board, not upstream)

I won't promise that I didn't miss a single panel, but that's fairly
complete I think.

I'm not sure the full impact of the fact that they didn't have the
connector type specified, but at least as of commit 9f069c6fbc72
("drm/panel: panel-simple: add default connector_type") we may have
been accidentally thinking of them as DPI panels. We also would
certainly have had a warning. In any case since we don't want to
support anything eDP in the old simple-panel driver, we should move
these.

Cc: Yakir Yang 
Cc: Jeffrey Hugo 
Cc: Thierry Reding 
Signed-off-by: Douglas Anderson 
---

Changes in v3:
- Move wayward panels patch new for v3.

 drivers/gpu/drm/panel/panel-simple-edp.c | 363 ++
 drivers/gpu/drm/panel/panel-simple.c | 365 ---
 2 files changed, 363 insertions(+), 365 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-simple-edp.c 
b/drivers/gpu/drm/panel/panel-simple-edp.c
index 5b47ee4bc338..8acac5bb792e 100644
--- a/drivers/gpu/drm/panel/panel-simple-edp.c
+++ b/drivers/gpu/drm/panel/panel-simple-edp.c
@@ -723,6 +723,28 @@ static void panel_edp_shutdown(struct device *dev)
drm_panel_unprepare(>base);
 }
 
+static const struct display_timing auo_b101ean01_timing = {
+   .pixelclock = { 6530, 7250, 7500 },
+   .hactive = { 1280, 1280, 1280 },
+   .hfront_porch = { 18, 119, 119 },
+   .hback_porch = { 21, 21, 21 },
+   .hsync_len = { 32, 32, 32 },
+   .vactive = { 800, 800, 800 },
+   .vfront_porch = { 4, 4, 4 },
+   .vback_porch = { 8, 8, 8 },
+   .vsync_len = { 18, 20, 20 },
+};
+
+static const struct panel_desc auo_b101ean01 = {
+   .timings = _b101ean01_timing,
+   .num_timings = 1,
+   .bpc = 6,
+   .size = {
+   .width = 217,
+   .height = 136,
+   },
+};
+
 static const struct drm_display_mode auo_b116xak01_mode = {
.clock = 69300,
.hdisplay = 1366,
@@ -802,6 +824,55 @@ static const struct panel_desc auo_b133han05 = {
},
 };
 
+static const struct drm_display_mode auo_b133htn01_mode = {
+   .clock = 150660,
+   .hdisplay = 1920,
+   .hsync_start = 1920 + 172,
+   .hsync_end = 1920 + 172 + 80,
+   .htotal = 1920 + 172 + 80 + 60,
+   .vdisplay = 1080,
+   .vsync_start = 1080 + 25,
+   .vsync_end = 1080 + 25 + 10,
+   .vtotal = 1080 + 25 + 10 + 10,
+};
+
+static const struct panel_desc auo_b133htn01 = {
+   .modes = _b133htn01_mode,
+   .num_modes = 1,
+   .bpc = 6,
+   .size = {
+   .width = 293,
+   .height = 165,
+   },
+   .delay = {
+   .prepare = 105,
+   .enable = 20,
+   .unprepare = 50,
+   },
+};
+
+static const struct drm_display_mode auo_b133xtn01_mode = {
+   .clock = 69500,
+   .hdisplay = 1366,
+   .hsync_start = 1366 + 48,
+   .hsync_end = 1366 + 48 + 32,
+   .htotal = 1366 + 48 + 32 + 20,
+   .vdisplay = 768,
+   .vsync_start = 768 + 3,
+   .vsync_end = 768 + 3 + 6,
+   .vtotal = 768 + 3 + 6 + 13,
+};
+
+static const struct panel_desc auo_b133xtn01 = {
+   .modes = _b133xtn01_mode,
+   .num_modes = 1,
+   .bpc = 6,
+   .size = {
+   .width = 293,
+   .height = 165,
+   },
+};
+
 static const struct drm_display_mode auo_b140han06_mode = {
.clock = 141000,
.hdisplay = 1920,
@@ -829,6 +900,46 @@ static const struct panel_desc auo_b140han06 = {
},
 };
 
+static const struct drm_display_mode boe_nv101wxmn51_modes[] = {
+   {
+   .clock = 71900,
+   .hdisplay = 1280,
+   .hsync_start = 1280 + 48,
+   .hsync_end = 1280 + 48 + 32,
+   .htotal = 1280 + 

[PATCH v3 08/16] MIPS: configs: Everyone who had PANEL_SIMPLE now gets PANEL_SIMPLE_EDP

2021-09-01 Thread Douglas Anderson
In the patch ("drm/panel-simple-edp: Split eDP panels out of
panel-simple") we split the PANEL_SIMPLE driver in 2. By default let's
give everyone who had the old driver enabled the new driver too. If
folks want to opt-out of one or the other they always can later.

Signed-off-by: Douglas Anderson 
---

(no changes since v1)

 arch/mips/configs/qi_lb60_defconfig | 1 +
 arch/mips/configs/rs90_defconfig| 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/mips/configs/qi_lb60_defconfig 
b/arch/mips/configs/qi_lb60_defconfig
index b4448d0876d5..3e99e223ea02 100644
--- a/arch/mips/configs/qi_lb60_defconfig
+++ b/arch/mips/configs/qi_lb60_defconfig
@@ -72,6 +72,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_DRM=y
 CONFIG_DRM_FBDEV_OVERALLOC=200
 CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_PANEL_SIMPLE_EDP=y
 CONFIG_DRM_INGENIC=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 # CONFIG_VGA_CONSOLE is not set
diff --git a/arch/mips/configs/rs90_defconfig b/arch/mips/configs/rs90_defconfig
index 7ce3b814fdc8..42b4f621cbfa 100644
--- a/arch/mips/configs/rs90_defconfig
+++ b/arch/mips/configs/rs90_defconfig
@@ -94,6 +94,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_DRM=y
 CONFIG_DRM_FBDEV_OVERALLOC=300
 CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_PANEL_SIMPLE_EDP=y
 CONFIG_DRM_INGENIC=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 CONFIG_BACKLIGHT_PWM=y
-- 
2.33.0.259.gc128427fd7-goog



[PATCH v3 06/16] ARM: configs: Everyone who had PANEL_SIMPLE now gets PANEL_SIMPLE_EDP

2021-09-01 Thread Douglas Anderson
In the patch ("drm/panel-simple-edp: Split eDP panels out of
panel-simple") we split the PANEL_SIMPLE driver in 2. By default let's
give everyone who had the old driver enabled the new driver too. If
folks want to opt-out of one or the other they always can later.

Signed-off-by: Douglas Anderson 
---

(no changes since v1)

 arch/arm/configs/at91_dt_defconfig   | 1 +
 arch/arm/configs/exynos_defconfig| 1 +
 arch/arm/configs/imx_v6_v7_defconfig | 1 +
 arch/arm/configs/lpc32xx_defconfig   | 1 +
 arch/arm/configs/multi_v5_defconfig  | 1 +
 arch/arm/configs/multi_v7_defconfig  | 1 +
 arch/arm/configs/omap2plus_defconfig | 1 +
 arch/arm/configs/qcom_defconfig  | 1 +
 arch/arm/configs/realview_defconfig  | 1 +
 arch/arm/configs/sama5_defconfig | 1 +
 arch/arm/configs/shmobile_defconfig  | 1 +
 arch/arm/configs/sunxi_defconfig | 1 +
 arch/arm/configs/tegra_defconfig | 1 +
 arch/arm/configs/versatile_defconfig | 1 +
 arch/arm/configs/vexpress_defconfig  | 1 +
 15 files changed, 15 insertions(+)

diff --git a/arch/arm/configs/at91_dt_defconfig 
b/arch/arm/configs/at91_dt_defconfig
index b1564e0aa000..3c92ba8c850d 100644
--- a/arch/arm/configs/at91_dt_defconfig
+++ b/arch/arm/configs/at91_dt_defconfig
@@ -144,6 +144,7 @@ CONFIG_VIDEO_MT9V032=m
 CONFIG_DRM=y
 CONFIG_DRM_ATMEL_HLCDC=y
 CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_PANEL_SIMPLE_EDP=y
 CONFIG_FB_ATMEL=y
 CONFIG_BACKLIGHT_ATMEL_LCDC=y
 CONFIG_BACKLIGHT_PWM=y
diff --git a/arch/arm/configs/exynos_defconfig 
b/arch/arm/configs/exynos_defconfig
index f4e1873912a3..3fc348d5765d 100644
--- a/arch/arm/configs/exynos_defconfig
+++ b/arch/arm/configs/exynos_defconfig
@@ -227,6 +227,7 @@ CONFIG_DRM_EXYNOS_DPI=y
 CONFIG_DRM_EXYNOS_DSI=y
 CONFIG_DRM_EXYNOS_HDMI=y
 CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_PANEL_SIMPLE_EDP=y
 CONFIG_DRM_PANEL_SAMSUNG_LD9040=y
 CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03=y
 CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=y
diff --git a/arch/arm/configs/imx_v6_v7_defconfig 
b/arch/arm/configs/imx_v6_v7_defconfig
index 079fcd8d1d11..ece13c0dc153 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -280,6 +280,7 @@ CONFIG_DRM=y
 CONFIG_DRM_MSM=y
 CONFIG_DRM_PANEL_LVDS=y
 CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_PANEL_SIMPLE_EDP=y
 CONFIG_DRM_PANEL_SEIKO_43WVF1G=y
 CONFIG_DRM_TI_TFP410=y
 CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
diff --git a/arch/arm/configs/lpc32xx_defconfig 
b/arch/arm/configs/lpc32xx_defconfig
index 989bcc84e7fb..86db9cdced97 100644
--- a/arch/arm/configs/lpc32xx_defconfig
+++ b/arch/arm/configs/lpc32xx_defconfig
@@ -108,6 +108,7 @@ CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_DRM=y
 CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_PANEL_SIMPLE_EDP=y
 CONFIG_DRM_PL111=y
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
diff --git a/arch/arm/configs/multi_v5_defconfig 
b/arch/arm/configs/multi_v5_defconfig
index 80a3ae02d759..fab163305918 100644
--- a/arch/arm/configs/multi_v5_defconfig
+++ b/arch/arm/configs/multi_v5_defconfig
@@ -194,6 +194,7 @@ CONFIG_VIDEO_ATMEL_ISI=m
 CONFIG_DRM=y
 CONFIG_DRM_ATMEL_HLCDC=m
 CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_PANEL_SIMPLE_EDP=y
 CONFIG_DRM_ASPEED_GFX=m
 CONFIG_FB_IMX=y
 CONFIG_FB_ATMEL=y
diff --git a/arch/arm/configs/multi_v7_defconfig 
b/arch/arm/configs/multi_v7_defconfig
index d9abaae118dd..d299d0045823 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -699,6 +699,7 @@ CONFIG_DRM_TEGRA=y
 CONFIG_DRM_STM=m
 CONFIG_DRM_STM_DSI=m
 CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_PANEL_SIMPLE_EDP=y
 CONFIG_DRM_PANEL_SAMSUNG_LD9040=m
 CONFIG_DRM_PANEL_ORISETECH_OTM8009A=m
 CONFIG_DRM_PANEL_RAYDIUM_RM68200=m
diff --git a/arch/arm/configs/omap2plus_defconfig 
b/arch/arm/configs/omap2plus_defconfig
index 2ac2418084ab..dcc55aa62d69 100644
--- a/arch/arm/configs/omap2plus_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -511,6 +511,7 @@ CONFIG_OMAP2_DSS_DSI=y
 CONFIG_DRM_TILCDC=m
 CONFIG_DRM_PANEL_DSI_CM=m
 CONFIG_DRM_PANEL_SIMPLE=m
+CONFIG_DRM_PANEL_SIMPLE_EDP=m
 CONFIG_DRM_PANEL_LG_LB035Q02=m
 CONFIG_DRM_PANEL_NEC_NL8048HL11=m
 CONFIG_DRM_PANEL_SHARP_LS037V7DW01=m
diff --git a/arch/arm/configs/qcom_defconfig b/arch/arm/configs/qcom_defconfig
index 26353cbfa968..37116db013f8 100644
--- a/arch/arm/configs/qcom_defconfig
+++ b/arch/arm/configs/qcom_defconfig
@@ -158,6 +158,7 @@ CONFIG_MEDIA_SUPPORT=y
 CONFIG_DRM=y
 CONFIG_DRM_MSM=m
 CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_PANEL_SIMPLE_EDP=y
 CONFIG_DRM_ANALOGIX_ANX78XX=m
 CONFIG_FB=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
diff --git a/arch/arm/configs/realview_defconfig 
b/arch/arm/configs/realview_defconfig
index 4c01e313099f..c433890fc4e9 100644
--- a/arch/arm/configs/realview_defconfig
+++ b/arch/arm/configs/realview_defconfig
@@ -61,6 +61,7 @@ CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_DRM=y
 CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_PANEL_SIMPLE_EDP=y
 CONFIG_DRM_DISPLAY_CONNECTOR=y
 CONFIG_DRM_SIMPLE_BRIDGE=y
 CONFIG_DRM_PL111=y
diff --git 

[PATCH v3 07/16] arm64: defconfig: Everyone who had PANEL_SIMPLE now gets PANEL_SIMPLE_EDP

2021-09-01 Thread Douglas Anderson
In the patch ("drm/panel-simple-edp: Split eDP panels out of
panel-simple") we split the PANEL_SIMPLE driver in 2. Let's enable the
new config.

Signed-off-by: Douglas Anderson 
---

(no changes since v1)

 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index f423d08b9a71..914057efa160 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -697,6 +697,7 @@ CONFIG_DRM_MSM=m
 CONFIG_DRM_TEGRA=m
 CONFIG_DRM_PANEL_LVDS=m
 CONFIG_DRM_PANEL_SIMPLE=m
+CONFIG_DRM_PANEL_SIMPLE_EDP=m
 CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
 CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m
 CONFIG_DRM_PANEL_RAYDIUM_RM67191=m
-- 
2.33.0.259.gc128427fd7-goog



[PATCH v3 05/16] drm/panel-simple-edp: Split eDP panels out of panel-simple

2021-09-01 Thread Douglas Anderson
The panel-simple driver handles way too much. Let's start trying to
get a handle on it by splitting out the eDP panels. This patch does
this:

1. Start by copying simple-panel verbatim over to a new driver,
   simple-panel-edp.
2. Rename "panel_simple" to "panel_edp" in the new driver.
3. Keep only panels marked with `DRM_MODE_CONNECTOR_eDP` in the new
   driver. Remove those panels from the old driver.
4. Remove all recent "DP AUX bus" stuff from the old driver. The DP
   AUX bus is only possible on DP panels.
5. Remove all DSI / MIPI related functions from the new driver.
6. Remove bus_format / bus_flags from eDP driver. These things don't
   seem to make any sense for eDP panels so let's stop filling in made
   up stuff.

In the end we end up with a bunch of duplicated code for now. Future
patches will try to address _some_ of this duplicated code though some
of it will be unavoidable.

NOTE: This may not actually move all eDP panels over to the new driver
since not all panels were properly marked with
`DRM_MODE_CONNECTOR_eDP`. A future patch will attempt to move wayward
panels I could identify but even so there may be some missed.

Suggested-by: Sam Ravnborg 
Signed-off-by: Douglas Anderson 
---
I believe this is what Sam was looking for when he requested that the
eDP panels split out [1]. Please yell if not.

[1] https://lore.kernel.org/dri-devel/yrtsfntn%2ft8fl...@ravnborg.org/

Changes in v3:
- Split eDP panels patch new for v3.

 drivers/gpu/drm/panel/Kconfig|   16 +-
 drivers/gpu/drm/panel/Makefile   |1 +
 drivers/gpu/drm/panel/panel-simple-edp.c | 1298 ++
 drivers/gpu/drm/panel/panel-simple.c |  575 +-
 4 files changed, 1323 insertions(+), 567 deletions(-)
 create mode 100644 drivers/gpu/drm/panel/panel-simple-edp.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 0b3784941312..4b7ff4ebdc34 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -77,14 +77,26 @@ config DRM_PANEL_LVDS
  backlight handling if the panel is attached to a backlight controller.
 
 config DRM_PANEL_SIMPLE
-   tristate "support for simple panels"
+   tristate "support for simple panels (other than eDP ones)"
+   depends on OF
+   depends on BACKLIGHT_CLASS_DEVICE
+   depends on PM
+   select VIDEOMODE_HELPERS
+   help
+ DRM panel driver for dumb non-eDP panels that need at most a regulator
+ and a GPIO to be powered up. Optionally a backlight can be attached so
+ that it can be automatically turned off when the panel goes into a
+ low power state.
+
+config DRM_PANEL_SIMPLE_EDP
+   tristate "support for simple Embedded DisplayPort panels"
depends on OF
depends on BACKLIGHT_CLASS_DEVICE
depends on PM
select VIDEOMODE_HELPERS
select DRM_DP_AUX_BUS
help
- DRM panel driver for dumb panels that need at most a regulator and
+ DRM panel driver for dumb eDP panels that need at most a regulator and
  a GPIO to be powered up. Optionally a backlight can be attached so
  that it can be automatically turned off when the panel goes into a
  low power state.
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 60c0149fc54a..640234d4d693 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_DRM_PANEL_BOE_TV101WUM_NL6) += 
panel-boe-tv101wum-nl6.o
 obj-$(CONFIG_DRM_PANEL_DSI_CM) += panel-dsi-cm.o
 obj-$(CONFIG_DRM_PANEL_LVDS) += panel-lvds.o
 obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o
+obj-$(CONFIG_DRM_PANEL_SIMPLE_EDP) += panel-simple-edp.o
 obj-$(CONFIG_DRM_PANEL_ELIDA_KD35T133) += panel-elida-kd35t133.o
 obj-$(CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02) += panel-feixin-k101-im2ba02.o
 obj-$(CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D) += 
panel-feiyang-fy07024di26a30d.o
diff --git a/drivers/gpu/drm/panel/panel-simple-edp.c 
b/drivers/gpu/drm/panel/panel-simple-edp.c
new file mode 100644
index ..5b47ee4bc338
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-simple-edp.c
@@ -0,0 +1,1298 @@
+/*
+ * Copyright (C) 2013, NVIDIA Corporation.  All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * 

[PATCH v3 04/16] drm/panel-simple: Reorder logicpd_type_28 / mitsubishi_aa070mc01

2021-09-01 Thread Douglas Anderson
The "logicpd_type_28" panel data was splitting up the
mitsubishi_aa070mc01 panel data. Reorganize it so that the panel descs
and modes are kept together.

This is a no-op code-cleanup change, found by code inspection.

Signed-off-by: Douglas Anderson 
---

Changes in v3:
- ("Reorder logicpd_type_28...") patch new for v3.

 drivers/gpu/drm/panel/panel-simple.c | 26 +-
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-simple.c 
b/drivers/gpu/drm/panel/panel-simple.c
index 0e4f3cac0fef..4ec310a650cd 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -3158,19 +3158,6 @@ static const struct panel_desc 
logictechno_lttd800480070_l6wh_rt = {
.connector_type = DRM_MODE_CONNECTOR_DPI,
 };
 
-static const struct drm_display_mode mitsubishi_aa070mc01_mode = {
-   .clock = 30400,
-   .hdisplay = 800,
-   .hsync_start = 800 + 0,
-   .hsync_end = 800 + 1,
-   .htotal = 800 + 0 + 1 + 160,
-   .vdisplay = 480,
-   .vsync_start = 480 + 0,
-   .vsync_end = 480 + 48 + 1,
-   .vtotal = 480 + 48 + 1 + 0,
-   .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
-};
-
 static const struct drm_display_mode logicpd_type_28_mode = {
.clock = 9107,
.hdisplay = 480,
@@ -3205,6 +3192,19 @@ static const struct panel_desc logicpd_type_28 = {
.connector_type = DRM_MODE_CONNECTOR_DPI,
 };
 
+static const struct drm_display_mode mitsubishi_aa070mc01_mode = {
+   .clock = 30400,
+   .hdisplay = 800,
+   .hsync_start = 800 + 0,
+   .hsync_end = 800 + 1,
+   .htotal = 800 + 0 + 1 + 160,
+   .vdisplay = 480,
+   .vsync_start = 480 + 0,
+   .vsync_end = 480 + 48 + 1,
+   .vtotal = 480 + 48 + 1 + 0,
+   .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
+};
+
 static const struct panel_desc mitsubishi_aa070mc01 = {
.modes = _aa070mc01_mode,
.num_modes = 1,
-- 
2.33.0.259.gc128427fd7-goog



[PATCH v3 03/16] drm/edid: Allow the querying/working with the panel ID from the EDID

2021-09-01 Thread Douglas Anderson
EDIDs have 32-bits worth of data which is intended to be used to
uniquely identify the make/model of a panel. This has historically
been used only internally in the EDID processing code to identify
quirks with panels.

We'd like to use this panel ID in panel-simple to identify which panel
is hooked up and from that information figure out power sequence
timings. Let's expose this information from the EDID code and also
allow it to be accessed early, before a connector has been created.

To make matching in the panel-simple code easier, we'll return the
panel ID as a 32-bit value. We'll provide some functions for
converting this value back and forth to something more human readable.

Signed-off-by: Douglas Anderson 
---

Changes in v3:
- Decode hex product ID w/ same endianness as everyone else.

 drivers/gpu/drm/drm_edid.c | 59 ++
 include/drm/drm_edid.h | 47 ++
 2 files changed, 106 insertions(+)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index a22c38482a90..ac128bc3478a 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2086,6 +2086,65 @@ struct edid *drm_get_edid(struct drm_connector 
*connector,
 }
 EXPORT_SYMBOL(drm_get_edid);
 
+/**
+ * drm_get_panel_id - Get a panel's ID through DDC
+ * @adapter: I2C adapter to use for DDC
+ *
+ * This function reads the first block of the EDID of a panel and (assuming
+ * that the EDID is valid) extracts the ID out of it. The ID is a 32-bit value
+ * (16 bits of manufacturer ID and 16 bits of per-manufacturer ID) that's
+ * supposed to be different for each different modem of panel.
+ *
+ * This function is intended to be used during early probing on devices where
+ * more than one panel might be present. Because of its intended use it must
+ * assume that the EDID of the panel is correct, at least as far as the ID
+ * is concerned (in other words, we don't process any overrides here).
+ *
+ * NOTE: it's expected that this function and drm_do_get_edid() will both
+ * be read the EDID, but there is no caching between them. Since we're only
+ * reading the first block, hopefully this extra overhead won't be too big.
+ *
+ * Return: A 32-bit ID that should be different for each make/model of panel.
+ * See the functions encode_edid_id() and decode_edid_id() for some
+ * details on the structure of this ID.
+ */
+u32 drm_get_panel_id(struct i2c_adapter *adapter)
+{
+   struct edid *edid;
+   u32 val;
+
+   edid = drm_do_get_edid_blk0(drm_do_probe_ddc_edid, adapter, NULL, NULL);
+
+   /*
+* There are no manufacturer IDs of 0, so if there is a problem reading
+* the EDID then we'll just return 0.
+*/
+   if (IS_ERR_OR_NULL(edid))
+   return 0;
+
+   /*
+* In theory we could try to de-obfuscate this like edid_get_quirks()
+* does, but it's easier to just deal with a 32-bit number.
+*
+* NOTE that we deal with endianness differently for the top half
+* of this ID than for the bottom half. The bottom half (the product
+* id) gets decoded as little endian by the EDID_PRODUCT_ID because
+* that's how everyone seems to interpret it. The top half (the mfg_id)
+* gets stored as big endian because that makes encode_edid_id() and
+* decode_edid_id() easier to write (it's easier to extract the ASCII).
+* It doesn't really matter, though, as long as the number here is
+* unique.
+*/
+   val = (u32)edid->mfg_id[0] << 24   |
+ (u32)edid->mfg_id[1] << 16   |
+ (u32)EDID_PRODUCT_ID(edid);
+
+   kfree(edid);
+
+   return val;
+}
+EXPORT_SYMBOL(drm_get_panel_id);
+
 /**
  * drm_get_edid_switcheroo - get EDID data for a vga_switcheroo output
  * @connector: connector we're probing
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index deccfd39e6db..73da40d0b5d1 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -508,6 +508,52 @@ static inline u8 drm_eld_get_conn_type(const uint8_t *eld)
return eld[DRM_ELD_SAD_COUNT_CONN_TYPE] & DRM_ELD_CONN_TYPE_MASK;
 }
 
+/**
+ * encode_edid_id - Encode an ID for matching against drm_get_panel_id()
+ * @vend_chr_0: First character of the vendor string.
+ * @vend_chr_2: Second character of the vendor string.
+ * @vend_chr_3: Third character of the vendor string.
+ * @product_id: The 16-bit product ID.
+ *
+ * This is a macro so that it can be calculated at compile time and used
+ * as an initializer.
+ *
+ * For instance:
+ *   encode_edid_id('B', 'O', 'E', 0x2d08) => 0x09e52d08
+ *
+ * Return: a 32-bit ID per panel.
+ */
+#define encode_edid_id(vend_chr_0, vend_chr_1, vend_chr_2, product_id) \
+   u32)(vend_chr_0) - '@') & 0x1f) << 26 | \
+(((u32)(vend_chr_1) - '@') & 0x1f) << 21 | \
+(((u32)(vend_chr_2) - '@') & 0x1f) << 16 | \
+((product_id) & 0x))
+
+/**
+ 

[PATCH v3 02/16] drm/edid: Break out reading block 0 of the EDID

2021-09-01 Thread Douglas Anderson
A future change wants to be able to read just block 0 of the EDID, so
break it out of drm_do_get_edid() into a sub-function.

This is intended to be a no-op change--just code movement.

Signed-off-by: Douglas Anderson 
---

(no changes since v1)

 drivers/gpu/drm/drm_edid.c | 62 +++---
 1 file changed, 44 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 6325877c5fd6..a22c38482a90 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1905,6 +1905,43 @@ int drm_add_override_edid_modes(struct drm_connector 
*connector)
 }
 EXPORT_SYMBOL(drm_add_override_edid_modes);
 
+static struct edid *drm_do_get_edid_blk0(
+   int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
+ size_t len),
+   void *data, bool *edid_corrupt, int *null_edid_counter)
+{
+   int i;
+   u8 *edid;
+
+   if ((edid = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL)
+   return NULL;
+
+   /* base block fetch */
+   for (i = 0; i < 4; i++) {
+   if (get_edid_block(data, edid, 0, EDID_LENGTH))
+   goto out;
+   if (drm_edid_block_valid(edid, 0, false, edid_corrupt))
+   break;
+   if (i == 0 && drm_edid_is_zero(edid, EDID_LENGTH)) {
+   if (null_edid_counter)
+   (*null_edid_counter)++;
+   goto carp;
+   }
+   }
+   if (i == 4)
+   goto carp;
+
+   return (struct edid *)edid;
+
+carp:
+   kfree(edid);
+   return ERR_PTR(-EINVAL);
+
+out:
+   kfree(edid);
+   return NULL;
+}
+
 /**
  * drm_do_get_edid - get EDID data using a custom EDID block read function
  * @connector: connector we're probing
@@ -1938,25 +1975,16 @@ struct edid *drm_do_get_edid(struct drm_connector 
*connector,
if (override)
return override;
 
-   if ((edid = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL)
+   edid = (u8 *)drm_do_get_edid_blk0(get_edid_block, data,
+ >edid_corrupt,
+ >null_edid_counter);
+   if (IS_ERR_OR_NULL(edid)) {
+   if (IS_ERR(edid))
+   connector_bad_edid(connector, edid, 1);
return NULL;
-
-   /* base block fetch */
-   for (i = 0; i < 4; i++) {
-   if (get_edid_block(data, edid, 0, EDID_LENGTH))
-   goto out;
-   if (drm_edid_block_valid(edid, 0, false,
->edid_corrupt))
-   break;
-   if (i == 0 && drm_edid_is_zero(edid, EDID_LENGTH)) {
-   connector->null_edid_counter++;
-   goto carp;
-   }
}
-   if (i == 4)
-   goto carp;
 
-   /* if there's no extensions, we're done */
+   /* if there's no extensions or no connector, we're done */
valid_extensions = edid[0x7e];
if (valid_extensions == 0)
return (struct edid *)edid;
@@ -2010,8 +2038,6 @@ struct edid *drm_do_get_edid(struct drm_connector 
*connector,
 
return (struct edid *)edid;
 
-carp:
-   connector_bad_edid(connector, edid, 1);
 out:
kfree(edid);
return NULL;
-- 
2.33.0.259.gc128427fd7-goog



[PATCH v3 01/16] dt-bindings: drm/panel-simple-edp: Introduce generic eDP panels

2021-09-01 Thread Douglas Anderson
eDP panels generally contain almost everything needed to control them
in their EDID. This comes from their DP heritage were a computer needs
to be able to properly control pretty much any DP display that's
plugged into it.

The one big issue with eDP panels and the reason that we need a panel
driver for them is that the power sequencing can be different per
panel.

While it is true that eDP panel sequencing can be arbitrarily complex,
in practice it turns out that many eDP panels are compatible with just
some slightly different delays. See the contents of the bindings file
introduced in this patch for some details.

The fact that eDP panels are 99% probable and that the power
sequencing (especially power up) can be compatible between many panels
means that there's a constant desire to plug multiple different panels
into the same board. This could be for second sourcing purposes or to
support multiple SKUs (maybe a 11" and a 13", for instance).

As discussed [1], it should be OK to support this by adding two
properties to the device tree to specify the delays needed for
powering up the panel the first time. We'll create a new "edp-panel"
bindings file and define the two delays that might need to be
specified. NOTE: in the vast majority of the cases (HPD is hooked up
and isn't glitchy or is debounced) even these delays aren't needed.

[1] 
https://lore.kernel.org/r/CAD=FV=vzyompwqzzwdhjgh5cjjww_ecm-wqveivz-bdgxjp...@mail.gmail.com

Signed-off-by: Douglas Anderson 
Reviewed-by: Rob Herring 
---

(no changes since v2)

Changes in v2:
- No longer allow fallback to panel-simple.
- Add "-ms" suffix to delays.

 .../bindings/display/panel/panel-edp.yaml | 188 ++
 1 file changed, 188 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/panel/panel-edp.yaml

diff --git a/Documentation/devicetree/bindings/display/panel/panel-edp.yaml 
b/Documentation/devicetree/bindings/display/panel/panel-edp.yaml
new file mode 100644
index ..6a621376ff86
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/panel-edp.yaml
@@ -0,0 +1,188 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/panel-edp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Probable (via DP AUX / EDID) eDP Panels with simple poweron sequences
+
+maintainers:
+  - Douglas Anderson 
+
+description: |
+  This binding file can be used to indicate that an eDP panel is connected
+  to a Embedded DisplayPort AUX bus (see display/dp-aux-bus.yaml) without
+  actually specifying exactly what panel is connected. This is useful for
+  the case that more than one different panel could be connected to the
+  board, either for second-sourcing purposes or to support multiple SKUs
+  with different LCDs that hook up to a common board.
+
+  As per above, a requirement for using this binding is that the panel is
+  represented under the DP AUX bus. This means that we can use any
+  information provided by the DP AUX bus (including the EDID) to identify
+  the panel. We can use this to identify display size, resolution, and
+  timings among other things.
+
+  One piece of information about eDP panels that is typically _not_
+  provided anywhere on the DP AUX bus is the power sequencing timings.
+  This is the reason why, historically, we've always had to explicitly
+  list eDP panels. We solve that here with two tricks. The "worst case"
+  power on timings for any panels expected to be connected to a board are
+  specified in these bindings. Once we've powered on, it's expected that
+  the operating system will lookup the panel in a table (based on EDID
+  information) to figure out other power sequencing timings.
+
+  eDP panels in general can have somewhat arbitrary power sequencing
+  requirements. However, even though it's arbitrary in general, the
+  vast majority of panel datasheets have a power sequence diagram that
+  looks the exactly the same as every other panel. Each panel datasheet
+  cares about different timings in this diagram but the fact that the
+  diagram is so similar means we can come up with a single driver to
+  handle it.
+
+  These diagrams all look roughly like this, sometimes labeled with
+  slightly different numbers / lines but all pretty much the same
+  sequence. This is because much of this diagram comes straight from
+  the eDP Standard.
+
+__
+  Vdd   ___/::\   /
+  _/:: \_/
+   ::: :<--T10-->:::
+:+---+-+-+
+  eDP ---+ Black video   | Src vid | Blk vid +
+  Display   :+---+-+-+
+: 

[PATCH v3 00/16] eDP: Support probing eDP panels dynamically instead of hardcoding

2021-09-01 Thread Douglas Anderson
The goal of this patch series is to move away from hardcoding exact
eDP panels in device tree files. As discussed in the various patches
in this series (I'm not repeating everything here), most eDP panels
are 99% probable and we can get that last 1% by allowing two "power
up" delays to be specified in the device tree file and then using the
panel ID (found in the EDID) to look up additional power sequencing
delays for the panel.

This patch series is the logical contiunation of a previous patch
series where I proposed solving this problem by adding a
board-specific compatible string [1]. In the discussion that followed
it sounded like people were open to something like the solution
proposed in this new series.

In version 2 I got rid of the idea that we could have a "fallback"
compatible string that we'd use if we didn't recognize the ID in the
EDID. This simplifies the bindings a lot and the implementation
somewhat. As a result of not having a "fallback", though, I'm not
confident in transitioning any existing boards over to this since
we'll have to fallback to very conservative timings if we don't
recognize the ID from the EDID and I can't guarantee that I've seen
every panel that might have shipped on an existing product. The plan
is to use "edp-panel" only on new boards or new revisions of old
boards where we can guarantee that every EDID that ships out of the
factory has an ID in the table.

Version 3 of this series now splits out all eDP panels to their own
driver and adds the generic eDP panel support to this new driver. I
believe this is what Sam was looking for [2].

[1] https://lore.kernel.org/r/yfkqaxomowyye...@google.com/
[2] https://lore.kernel.org/r/yrtsfntn%2ft8fl...@ravnborg.org/

Changes in v3:
- Decode hex product ID w/ same endianness as everyone else.
- ("Reorder logicpd_type_28...") patch new for v3.
- Split eDP panels patch new for v3.
- Move wayward panels patch new for v3.
- ("Non-eDP panels don't need "HPD" handling") new for v3.
- Split the delay structure out patch just on eDP now.
- ("Better describe eDP panel delays") new for v3.
- Fix "prepare_to_enable" patch new for v3.
- ("Don't re-read the EDID every time") moved to eDP only patch.
- Generic "edp-panel" handled by the eDP panel driver now.
- Change init order to we power at the end.
- Adjust endianness of product ID.
- Fallback to conservative delays if panel not recognized.
- Add Sharp LQ116M1JW10 to table.
- Add AUO B116XAN06.1 to table.
- Rename delays more generically so they can be reused.

Changes in v2:
- No longer allow fallback to panel-simple.
- Add "-ms" suffix to delays.
- Don't support a "fallback" panel. Probed panels must be probed.
- Not based on patch to copy "desc"--just allocate for probed panels.
- Add "-ms" suffix to delays.

Douglas Anderson (16):
  dt-bindings: drm/panel-simple-edp: Introduce generic eDP panels
  drm/edid: Break out reading block 0 of the EDID
  drm/edid: Allow the querying/working with the panel ID from the EDID
  drm/panel-simple: Reorder logicpd_type_28 / mitsubishi_aa070mc01
  drm/panel-simple-edp: Split eDP panels out of panel-simple
  ARM: configs: Everyone who had PANEL_SIMPLE now gets PANEL_SIMPLE_EDP
  arm64: defconfig: Everyone who had PANEL_SIMPLE now gets
PANEL_SIMPLE_EDP
  MIPS: configs: Everyone who had PANEL_SIMPLE now gets PANEL_SIMPLE_EDP
  drm/panel-simple-edp: Move some wayward panels to the eDP driver
  drm/panel-simple: Non-eDP panels don't need "HPD" handling
  drm/panel-simple-edp: Split the delay structure out
  drm/panel-simple-edp: Better describe eDP panel delays
  drm/panel-simple-edp: hpd_reliable shouldn't be subtraced from
hpd_absent
  drm/panel-simple-edp: Fix "prepare_to_enable" if panel doesn't handle
HPD
  drm/panel-simple-edp: Don't re-read the EDID every time we power off
the panel
  drm/panel-simple-edp: Implement generic "edp-panel"s probed by EDID

 .../bindings/display/panel/panel-edp.yaml |  188 ++
 arch/arm/configs/at91_dt_defconfig|1 +
 arch/arm/configs/exynos_defconfig |1 +
 arch/arm/configs/imx_v6_v7_defconfig  |1 +
 arch/arm/configs/lpc32xx_defconfig|1 +
 arch/arm/configs/multi_v5_defconfig   |1 +
 arch/arm/configs/multi_v7_defconfig   |1 +
 arch/arm/configs/omap2plus_defconfig  |1 +
 arch/arm/configs/qcom_defconfig   |1 +
 arch/arm/configs/realview_defconfig   |1 +
 arch/arm/configs/sama5_defconfig  |1 +
 arch/arm/configs/shmobile_defconfig   |1 +
 arch/arm/configs/sunxi_defconfig  |1 +
 arch/arm/configs/tegra_defconfig  |1 +
 arch/arm/configs/versatile_defconfig  |1 +
 arch/arm/configs/vexpress_defconfig   |1 +
 arch/arm64/configs/defconfig  |1 +
 arch/mips/configs/qi_lb60_defconfig   |1 +
 arch/mips/configs/rs90_defconfig  |1 +
 drivers/gpu/drm/drm_edid.c 

VKMS: New plane formats

2021-09-01 Thread Igor Matheus Andrade Torrente

Hi,

I'm working to add new plane formats to vkms. But I don't know what 
should be the behavior in the situation that we received multiple planes 
with different formats from the users-space.


For example, if the user chooses:
- DRM_FORMAT_ARGB16161616 to the primary plane
- DRM_FORMAT_ARGB to the cursor
- DRM_FORMAT_YUV42 to the overlay

What should be the output format that will be used to calculate the crc? 
DRM_FORMAT_ARGB16161616?


My idea was to convert all the planes to the primary, but I'm not sure 
if it is the right approach.


Best regards,
---
Igor M. A. Torrente


Re: [PATCH] dt-bindings: display: add missing simple-framebuffer formats

2021-09-01 Thread Luca Weiss
Hi Rob,

On Dienstag, 31. August 2021 23:30:15 CEST Rob Herring wrote:
> On Sat, Aug 28, 2021 at 01:02:05PM +0200, Luca Weiss wrote:
> > Document all formats currently present in include/linux/platform_data/
> > simplefb.h
> > 
> > Signed-off-by: Luca Weiss 
> > ---
> > 
> >  .../bindings/display/simple-framebuffer.yaml | 12 
> >  1 file changed, 12 insertions(+)
> > 
> > diff --git
> > a/Documentation/devicetree/bindings/display/simple-framebuffer.yaml
> > b/Documentation/devicetree/bindings/display/simple-framebuffer.yaml index
> > c2499a7906f5..c1acd2859ae8 100644
> > --- a/Documentation/devicetree/bindings/display/simple-framebuffer.yaml
> > +++ b/Documentation/devicetree/bindings/display/simple-framebuffer.yaml
> > 
> > @@ -83,13 +83,25 @@ properties:
> >format:
> >  description: >
> >  
> >Format of the framebuffer:
> > +* `a1r5g5b5` - 16-bit pixels, d[15]=a, d[14:10]=r, d[9:5]=g,
> > d[4:0]=b +* `a2r10g10b10` - 32-bit pixels, d[31:30]=a,
> > d[29:20]=r, d[19:10]=g, d[9:0]=b
> Not a new problem, but are these 32-bit big or little endian words? That
> should be figured out before we add more.

As I'm neither involved in the driver nor really have any knowledge on pixel 
formats, maybe the maintainers of the binding can help out here?
(Bartlomiej Zolnierkiewicz & Hans de Goede, both are CC'ed)

I can probably dig through the sources and guess but documentation should be 
written without guessing :)

Regards
Luca






Re: [git pull] drm for 5.15-rc1

2021-09-01 Thread Alex Deucher
On Wed, Sep 1, 2021 at 2:33 PM Linus Torvalds
 wrote:
>
> On Wed, Sep 1, 2021 at 10:57 AM Linus Torvalds
>  wrote:
> >
> > No worries. I enjoyed seeing the AMD code-names in the conflicts, they
> > are using positively kernel-level naming.
>
> Oh, I spoke too soon.
>
> The conflict in amdgpu_ras_eeprom.c is trivial to fix up, but the
> *code* is garbage.
>
> It does this (from commit 14fb496a84f1: "drm/amdgpu: set RAS EEPROM
> address from VBIOS"):
>
> ...
> control->i2c_address = 0;
>
> if (amdgpu_atomfirmware_ras_rom_addr(adev,
> (uint8_t*)>i2c_address))
> {
> if (control->i2c_address == 0xA0)
> control->i2c_address = 0;
> ...
>
> and honestly, that just hurts to look at. It's completely wrong, even
> if it happens to work on a little-endian machine.
>
> Yes, yes, BE is irrelevant, and doubly so for an AMD GPU driver, but still.
>
> It's assigning a 8-bit value to a 32-bit entity by doing a pointer
> cast on the address, and then mixing things up by using/assigning to
> that same field.
>
> That's just *wrong* and nasty.
>
> Oh, the resolution would be easy - just take that broken code as-is -
> but I can't actually make myself do that.
>
> So I fixed it up to not be that incredibly ugly garbage.
>
> Please holler if I did something wrong.

Fix looks good.  Thanks,

Alex


Re: [diagnostic TDR mode patches] unify our solution opinions/suggestions in one thread

2021-09-01 Thread Dave Airlie
On Thu, 2 Sept 2021 at 01:20, Alex Deucher  wrote:
>
> On Wed, Sep 1, 2021 at 6:19 AM Liu, Monk  wrote:
> >
> > [AMD Official Use Only]
> >
> > Daniel
> >
> > From the link you share it looks you(or someone else) have quite a bunch 
> > patches that changes DRM_SCHED or even amdgpu, by that case before they are 
> > merged to kernel tree I'm wondering if any AMD develop reviewed them ?
> >
> > They looks to me somehow conflicting with what we changed in our repo
> >
> > It is really a chaos for AMDer if someone else out side of AMD changes our 
> > kernel driver (or/and scheduler) without reviewed by AMDer, just like we 
> > are requiring your review if we tend to change scheduler's logic here 
> >
> > This one changes AMD's code: 
> > https://lore.kernel.org/dri-devel/20210625133327.2598825-2-boris.brezil...@collabora.com/
> > And I didn't see any reviewed-by from AMDers ...
> >
> > This one also touches AMD's code: 
> > https://lore.kernel.org/dri-devel/20200604081224.863494-12-daniel.vet...@ffwll.ch/
> > Which is conflicting with one patch we submitted (in our repo rightnow), 
> > and neither see AMDder gave a review-by on this one (let me know if I 
> > missed it)
> >
>
> Monk, this is not how upstream works.  You need to participate.
> That's how communities work.  There's a reason all these discussions
> happen on public mailing lists.  The patch author can't be expected to
> know every person on every vendor team to CC with a patch.  If you
> have concerns, you need to raise them when the patches are being
> discussed.
>

I'm not sure I can add much to help this along, I'm sure Alex has some
internal training,

Once your driver is upstream, it belongs to upstream, you can maintain
it, but you no longer control it 100%, it's a tradeoff, it's not one
companies always understand.

Usually people are fine developing away internally, but once
interaction with other parts of the kernel/subsystem is required they
have the realisation that they needed to work upstream 6 months
earlier.

The best time to interact with upstream was 6 months ago, the second
best time is now.

Dave.


Re: [git pull] drm for 5.15-rc1

2021-09-01 Thread pr-tracker-bot
The pull request you sent on Tue, 31 Aug 2021 15:53:10 +1000:

> git://anongit.freedesktop.org/drm/drm tags/drm-next-2021-08-31-1

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/477f70cd2a67904e04c2c2b9bd0fa2e95222f2f6

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


Re: [git pull] drm for 5.15-rc1

2021-09-01 Thread Linus Torvalds
On Wed, Sep 1, 2021 at 10:57 AM Linus Torvalds
 wrote:
>
> No worries. I enjoyed seeing the AMD code-names in the conflicts, they
> are using positively kernel-level naming.

Oh, I spoke too soon.

The conflict in amdgpu_ras_eeprom.c is trivial to fix up, but the
*code* is garbage.

It does this (from commit 14fb496a84f1: "drm/amdgpu: set RAS EEPROM
address from VBIOS"):

...
control->i2c_address = 0;

if (amdgpu_atomfirmware_ras_rom_addr(adev,
(uint8_t*)>i2c_address))
{
if (control->i2c_address == 0xA0)
control->i2c_address = 0;
...

and honestly, that just hurts to look at. It's completely wrong, even
if it happens to work on a little-endian machine.

Yes, yes, BE is irrelevant, and doubly so for an AMD GPU driver, but still.

It's assigning a 8-bit value to a 32-bit entity by doing a pointer
cast on the address, and then mixing things up by using/assigning to
that same field.

That's just *wrong* and nasty.

Oh, the resolution would be easy - just take that broken code as-is -
but I can't actually make myself do that.

So I fixed it up to not be that incredibly ugly garbage.

Please holler if I did something wrong.

 Linus


Re: [PATCH 1/5] drm: Add drm_fixed_16_16 helper

2021-09-01 Thread Laurent Pinchart
Hi Alyssa,

Thank you for the patch.

On Wed, Sep 01, 2021 at 01:54:27PM -0400, Alyssa Rosenzweig wrote:
> This constructs a fixed 16.16 rational, useful to specify the minimum
> and maximum scaling in drm_atomic_helper_check_plane_state. It is
> open-coded as a macro in multiple drivers, so let's share the helper.
> 
> Signed-off-by: Alyssa Rosenzweig 
> ---
>  include/drm/drm_fixed.h | 5 +
>  1 file changed, 5 insertions(+)
> 
> diff --git a/include/drm/drm_fixed.h b/include/drm/drm_fixed.h
> index 553210c02ee0..df1f369b4918 100644
> --- a/include/drm/drm_fixed.h
> +++ b/include/drm/drm_fixed.h
> @@ -208,4 +208,9 @@ static inline s64 drm_fixp_exp(s64 x)
>   return sum;
>  }
>  

Missing documentation :-)

> +static inline int drm_fixed_16_16(s32 mult, s32 div)

You should return a s32.

The function name isn't very explicit, and departs from the naming
scheme of other functions in the same file. As fixed-point numbers are
stored in a s64 for the drm_fixp_* helpers, we shouldn't rese the
drm_fixp_ prefix, maybe drm_fixp_s16_16_ would be a good prefix. The
function should probably be named drm_fixp_s16_16 from_fraction() then,
but then the same logic should possibly be replicated to ensure optimal
precision. I wonder if it wouldn't be best to simply use
drm_fixp_from_fraction() and shift the result right by 16 bits.

> +{
> + return (mult << 16) / div;
> +}
> +
>  #endif

-- 
Regards,

Laurent Pinchart


[PATCH 3/3] dt-bindings: display: msm: Add binding for msm8998 dpu

2021-09-01 Thread AngeloGioacchino Del Regno
Add yaml binding for msm8998 dpu1 support.

Signed-off-by: AngeloGioacchino Del Regno 

---
 .../bindings/display/msm/dpu-msm8998.yaml | 220 ++
 1 file changed, 220 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/msm/dpu-msm8998.yaml

diff --git a/Documentation/devicetree/bindings/display/msm/dpu-msm8998.yaml 
b/Documentation/devicetree/bindings/display/msm/dpu-msm8998.yaml
new file mode 100644
index ..db435342ecbf
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/msm/dpu-msm8998.yaml
@@ -0,0 +1,220 @@
+# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/msm/dpu-msm8998.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Display DPU dt properties for MSM8998 target
+
+maintainers:
+  - AngeloGioacchino Del Regno 
+
+description: |
+  Device tree bindings for MSM Mobile Display Subsystem(MDSS) that encapsulates
+  sub-blocks like DPU display controller, DSI and DP interfaces etc. Device 
tree
+  bindings of MDSS and DPU are mentioned for MSM8998 target.
+
+properties:
+  compatible:
+items:
+  - const: qcom,msm8998-mdss
+
+  reg:
+maxItems: 1
+
+  reg-names:
+const: mdss
+
+  power-domains:
+maxItems: 1
+
+  clocks:
+items:
+  - description: Display AHB clock
+  - description: Display AXI clock
+  - description: Display core clock
+
+  clock-names:
+items:
+  - const: iface
+  - const: bus
+  - const: core
+
+  interrupts:
+maxItems: 1
+
+  interrupt-controller: true
+
+  "#address-cells": true
+
+  "#size-cells": true
+
+  "#interrupt-cells":
+const: 1
+
+  iommus:
+items:
+  - description: Phandle to apps_smmu node with SID mask for Hard-Fail 
port0
+
+  ranges: true
+
+patternProperties:
+  "^display-controller@[0-9a-f]+$":
+type: object
+description: Node containing the properties of DPU.
+
+properties:
+  compatible:
+items:
+  - const: qcom,msm8998-dpu
+
+  reg:
+items:
+  - description: Address offset and size for mdp register set
+  - description: Address offset and size for regdma register set
+  - description: Address offset and size for vbif register set
+  - description: Address offset and size for non-realtime vbif 
register set
+
+  reg-names:
+items:
+  - const: mdp
+  - const: regdma
+  - const: vbif
+  - const: vbif_nrt
+
+  clocks:
+items:
+  - description: Display ahb clock
+  - description: Display axi clock
+  - description: Display mem-noc clock
+  - description: Display core clock
+  - description: Display vsync clock
+
+  clock-names:
+items:
+  - const: iface
+  - const: bus
+  - const: mnoc
+  - const: core
+  - const: vsync
+
+  interrupts:
+maxItems: 1
+
+  power-domains:
+maxItems: 1
+
+  operating-points-v2: true
+  ports:
+$ref: /schemas/graph.yaml#/properties/ports
+description: |
+  Contains the list of output ports from DPU device. These ports
+  connect to interfaces that are external to the DPU hardware,
+  such as DSI, DP etc. Each output port contains an endpoint that
+  describes how it is connected to an external interface.
+
+properties:
+  port@0:
+$ref: /schemas/graph.yaml#/properties/port
+description: DPU_INTF1 (DSI1)
+
+  port@1:
+$ref: /schemas/graph.yaml#/properties/port
+description: DPU_INTF2 (DSI2)
+
+required:
+  - port@0
+  - port@1
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - clocks
+  - interrupts
+  - power-domains
+  - operating-points-v2
+  - ports
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - power-domains
+  - clocks
+  - interrupts
+  - interrupt-controller
+  - iommus
+  - ranges
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+#include 
+
+display-subsystem@c90 {
+compatible = "qcom,msm8998-mdss";
+reg = <0x0c90 0x1000>;
+reg-names = "mdss";
+
+clocks = < MDSS_AHB_CLK>,
+ < MDSS_AXI_CLK>,
+ < MDSS_MDP_CLK>;
+clock-names = "iface", "bus", "core";
+
+#address-cells = <1>;
+#interrupt-cells = <1>;
+#size-cells = <1>;
+
+interrupts = ;
+interrupt-controller;
+iommus = <_smmu 0>;
+
+power-domains = < MDSS_GDSC>;
+ranges;
+status = "disabled";
+
+display-controller@c901000 {
+compatible = "qcom,msm8998-dpu";
+reg = <0x0c901000 0x8f000>,
+  <0x0c9a8e00 0xf0>,
+  <0x0c9b 0x2008>,
+  <0x0c9b8000 

[PATCH 2/3] drm/msm/dpu1: Add MSM8998 to hw catalog

2021-09-01 Thread AngeloGioacchino Del Regno
Bringup functionality for MSM8998 in the DPU, driver which is mostly
the same as SDM845 (just a few variations).

Signed-off-by: AngeloGioacchino Del Regno 

---
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 335 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   |   1 +
 drivers/gpu/drm/msm/msm_drv.c |   1 +
 3 files changed, 326 insertions(+), 11 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 b131fd376192..f2cc715af782 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -16,6 +16,9 @@
BIT(DPU_SSPP_CSC_10BIT) | BIT(DPU_SSPP_CDP) |\
BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_EXCL_RECT))
 
+#define VIG_MSM8998_MASK \
+   (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
+
 #define VIG_SDM845_MASK \
(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3))
 
@@ -25,6 +28,11 @@
 #define VIG_SM8250_MASK \
(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3LITE))
 
+#define DMA_MSM8998_MASK \
+   (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) |\
+   BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\
+   BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT))
+
 #define DMA_SDM845_MASK \
(BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_QOS_8LVL) |\
BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\
@@ -33,6 +41,9 @@
 #define DMA_CURSOR_SDM845_MASK \
(DMA_SDM845_MASK | BIT(DPU_SSPP_CURSOR))
 
+#define DMA_CURSOR_MSM8998_MASK \
+   (DMA_MSM8998_MASK | BIT(DPU_SSPP_CURSOR))
+
 #define MIXER_SDM845_MASK \
(BIT(DPU_MIXER_SOURCESPLIT) | BIT(DPU_DIM_LAYER))
 
@@ -49,6 +60,8 @@
 
 #define MERGE_3D_SM8150_MASK (0)
 
+#define DSPP_MSM8998_MASK (BIT(DPU_DSPP_PCC) | BIT(DPU_DSPP_GC))
+
 #define DSPP_SC7180_MASK BIT(DPU_DSPP_PCC)
 
 #define INTF_SDM845_MASK (0)
@@ -181,6 +194,22 @@ static const uint32_t plane_formats_yuv[] = {
  * DPU sub blocks config
  */
 /* DPU top level caps */
+static const struct dpu_caps msm8998_dpu_caps = {
+   .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+   .max_mixer_blendstages = 0x7,
+   .qseed_type = DPU_SSPP_SCALER_QSEED3,
+   .smart_dma_rev = DPU_SSPP_SMART_DMA_V1,
+   .ubwc_version = DPU_HW_UBWC_VER_10,
+   .has_src_split = true,
+   .has_dim_layer = true,
+   .has_idle_pc = true,
+   .has_3d_merge = true,
+   .max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+   .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+   .max_hdeci_exp = MAX_HORZ_DECIMATION,
+   .max_vdeci_exp = MAX_VERT_DECIMATION,
+};
+
 static const struct dpu_caps sdm845_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
@@ -251,6 +280,35 @@ static const struct dpu_caps sc7280_dpu_caps = {
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
 };
 
+static const struct dpu_mdp_cfg msm8998_mdp[] = {
+   {
+   .name = "top_0", .id = MDP_TOP,
+   .base = 0x0, .len = 0x458,
+   .features = 0,
+   .highest_bank_bit = 0x2,
+   .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_DMA2] = {
+   .reg_off = 0x2C4, .bit_off = 8},
+   .clk_ctrls[DPU_CLK_CTRL_DMA3] = {
+   .reg_off = 0x2C4, .bit_off = 12},
+   .clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
+   .reg_off = 0x3A8, .bit_off = 15},
+   .clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
+   .reg_off = 0x3B0, .bit_off = 15},
+   },
+};
+
 static const struct dpu_mdp_cfg sdm845_mdp[] = {
{
.name = "top_0", .id = MDP_TOP,
@@ -339,6 +397,39 @@ static const struct dpu_mdp_cfg sc7280_mdp[] = {
 /*
  * CTL sub blocks config
  */
+static const struct dpu_ctl_cfg msm8998_ctl[] = {
+   {
+   .name = "ctl_0", .id = CTL_0,
+   .base = 0x1000, .len = 0x94,
+   .features = BIT(DPU_CTL_SPLIT_DISPLAY),
+   .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+   },
+   {
+   .name = "ctl_1", .id = CTL_1,
+   .base = 0x1200, .len = 0x94,
+   .features = 0,
+   .intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
+   },
+   {
+   

[PATCH 1/3] drm/msm/dpu1: Add DMA2, DMA3 clock control to enum

2021-09-01 Thread AngeloGioacchino Del Regno
The enum dpu_clk_ctrl_type misses DPU_CLK_CTRL_DMA{2,3} even though
this driver does actually handle both, if present: add the two in
preparation for adding support for SoCs having them.

Signed-off-by: AngeloGioacchino Del Regno 

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

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 d2a945a27cfa..059e1402b7d0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -432,6 +432,8 @@ enum dpu_clk_ctrl_type {
DPU_CLK_CTRL_RGB3,
DPU_CLK_CTRL_DMA0,
DPU_CLK_CTRL_DMA1,
+   DPU_CLK_CTRL_DMA2,
+   DPU_CLK_CTRL_DMA3,
DPU_CLK_CTRL_CURSOR0,
DPU_CLK_CTRL_CURSOR1,
DPU_CLK_CTRL_INLINE_ROT0_SSPP,
-- 
2.32.0



Re: [git pull] drm for 5.15-rc1

2021-09-01 Thread Linus Torvalds
On Mon, Aug 30, 2021 at 10:53 PM Dave Airlie  wrote:
>
> There are a bunch of conflicts with your tree, but none of them seem
> too serious, but I might have missed something.

No worries. I enjoyed seeing the AMD code-names in the conflicts, they
are using positively kernel-level naming.

That said, I wonder why AMD people can't use consistent formatting,
mixing ALL-CAPS with underscores, spaces, whatever:

/* Sienna_Cichlid */
/* Yellow Carp */
/* Navy_Flounder */
/* DIMGREY_CAVEFISH */
/* Aldebaran */
/* CYAN_SKILLFISH */
/* BEIGE_GOBY */

which shows a distinct lack of professionalism and caring in the silly naming.

 Linus


[PATCH 5/5] drm/zte: Use common drm_fixed_16_16 helper

2021-09-01 Thread Alyssa Rosenzweig
Replace our open-coded FRAC_16_16 with the common drm_fixed_16_16
helper to reduce code duplication between drivers.

Signed-off-by: Alyssa Rosenzweig 
---
 drivers/gpu/drm/zte/zx_plane.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/zte/zx_plane.c b/drivers/gpu/drm/zte/zx_plane.c
index 93bcca428e35..80f61d79be83 100644
--- a/drivers/gpu/drm/zte/zx_plane.c
+++ b/drivers/gpu/drm/zte/zx_plane.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "zx_common_regs.h"
 #include "zx_drm_drv.h"
@@ -43,8 +44,6 @@ static const uint32_t vl_formats[] = {
 */
 };
 
-#define FRAC_16_16(mult, div)(((mult) << 16) / (div))
-
 static int zx_vl_plane_atomic_check(struct drm_plane *plane,
struct drm_atomic_state *state)
 {
@@ -53,8 +52,8 @@ static int zx_vl_plane_atomic_check(struct drm_plane *plane,
struct drm_framebuffer *fb = plane_state->fb;
struct drm_crtc *crtc = plane_state->crtc;
struct drm_crtc_state *crtc_state;
-   int min_scale = FRAC_16_16(1, 8);
-   int max_scale = FRAC_16_16(8, 1);
+   int min_scale = drm_fixed_16_16(1, 8);
+   int max_scale = drm_fixed_16_16(8, 1);
 
if (!crtc || WARN_ON(!fb))
return 0;
-- 
2.30.2



[PATCH 4/5] drm/rockchip: Use common drm_fixed_16_16 helper

2021-09-01 Thread Alyssa Rosenzweig
Replace our open-coded FRAC_16_16 with the common drm_fixed_16_16
helper to reduce code duplication between drivers.

Signed-off-by: Alyssa Rosenzweig 
Cc: linux-rockc...@lists.infradead.org
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 9 +
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 1 -
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index ba9e14da41b4..9428fcba400f 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #ifdef CONFIG_DRM_ANALOGIX_DP
 #include 
@@ -789,9 +790,9 @@ static int vop_plane_atomic_check(struct drm_plane *plane,
struct vop_win *vop_win = to_vop_win(plane);
const struct vop_win_data *win = vop_win->data;
int ret;
-   int min_scale = win->phy->scl ? FRAC_16_16(1, 8) :
+   int min_scale = win->phy->scl ? drm_fixed_16_16(1, 8) :
DRM_PLANE_HELPER_NO_SCALING;
-   int max_scale = win->phy->scl ? FRAC_16_16(8, 1) :
+   int max_scale = win->phy->scl ? drm_fixed_16_16(8, 1) :
DRM_PLANE_HELPER_NO_SCALING;
 
if (!crtc || WARN_ON(!fb))
@@ -1037,9 +1038,9 @@ static int vop_plane_atomic_async_check(struct drm_plane 
*plane,

 plane);
struct vop_win *vop_win = to_vop_win(plane);
const struct vop_win_data *win = vop_win->data;
-   int min_scale = win->phy->scl ? FRAC_16_16(1, 8) :
+   int min_scale = win->phy->scl ? drm_fixed_16_16(1, 8) :
DRM_PLANE_HELPER_NO_SCALING;
-   int max_scale = win->phy->scl ? FRAC_16_16(8, 1) :
+   int max_scale = win->phy->scl ? drm_fixed_16_16(8, 1) :
DRM_PLANE_HELPER_NO_SCALING;
struct drm_crtc_state *crtc_state;
 
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index 857d97cdc67c..cada12e653cc 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -335,7 +335,6 @@ enum vop_pol {
DEN_NEGATIVE   = 2
 };
 
-#define FRAC_16_16(mult, div)(((mult) << 16) / (div))
 #define SCL_FT_DEFAULT_FIXPOINT_SHIFT  12
 #define SCL_MAX_VSKIPLINES 4
 #define MIN_SCL_FT_AFTER_VSKIP 1
-- 
2.30.2



[PATCH 3/5] drm/msm: Use common drm_fixed_16_16 helper

2021-09-01 Thread Alyssa Rosenzweig
Replace our open-coded FRAC_16_16 with the common drm_fixed_16_16
helper to reduce code duplication between drivers.

Signed-off-by: Alyssa Rosenzweig 
Cc: linux-arm-...@vger.kernel.org
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c  | 2 +-
 drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 8 
 drivers/gpu/drm/msm/msm_drv.h  | 3 +--
 3 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index c989621209aa..fc9a9f544110 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -964,7 +964,7 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
crtc_state = drm_atomic_get_new_crtc_state(state,
   
new_plane_state->crtc);
 
-   min_scale = FRAC_16_16(1, pdpu->pipe_sblk->maxupscale);
+   min_scale = drm_fixed_16_16(1, pdpu->pipe_sblk->maxupscale);
ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
  min_scale,
  pdpu->pipe_sblk->maxdwnscale 
<< 16,
diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c 
b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
index c6b69afcbac8..079b0662ee3c 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c
@@ -199,8 +199,8 @@ static int mdp5_plane_atomic_check_with_state(struct 
drm_crtc_state *crtc_state,
return -ERANGE;
}
 
-   min_scale = FRAC_16_16(1, 8);
-   max_scale = FRAC_16_16(8, 1);
+   min_scale = drm_fixed_16_16(1, 8);
+   max_scale = drm_fixed_16_16(8, 1);
 
ret = drm_atomic_helper_check_plane_state(state, crtc_state,
  min_scale, max_scale,
@@ -381,8 +381,8 @@ static int mdp5_plane_atomic_async_check(struct drm_plane 
*plane,
plane->state->fb != new_plane_state->fb)
return -EINVAL;
 
-   min_scale = FRAC_16_16(1, 8);
-   max_scale = FRAC_16_16(8, 1);
+   min_scale = drm_fixed_16_16(1, 8);
+   max_scale = drm_fixed_16_16(8, 1);
 
ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
  min_scale, max_scale,
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 8b005d1ac899..b5aa94024a42 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -32,6 +32,7 @@
 #include 
 #include 
 #include 
+#include 
 
 struct msm_kms;
 struct msm_gpu;
@@ -51,8 +52,6 @@ struct msm_disp_state;
 #define MAX_BRIDGES8
 #define MAX_CONNECTORS 8
 
-#define FRAC_16_16(mult, div)(((mult) << 16) / (div))
-
 struct msm_file_private {
rwlock_t queuelock;
struct list_head submitqueues;
-- 
2.30.2



[PATCH 2/5] drm/meson: Use common drm_fixed_16_16 helper

2021-09-01 Thread Alyssa Rosenzweig
Replace our open-coded FRAC_16_16 with the common drm_fixed_16_16
helper to reduce code duplication between drivers.

Signed-off-by: Alyssa Rosenzweig 
Cc: linux-amlo...@lists.infradead.org
---
 drivers/gpu/drm/meson/meson_overlay.c | 7 +++
 drivers/gpu/drm/meson/meson_plane.c   | 5 ++---
 2 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/meson/meson_overlay.c 
b/drivers/gpu/drm/meson/meson_overlay.c
index dfef8afcc245..d8fc6bbb332f 100644
--- a/drivers/gpu/drm/meson/meson_overlay.c
+++ b/drivers/gpu/drm/meson/meson_overlay.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "meson_overlay.h"
 #include "meson_registers.h"
@@ -162,8 +163,6 @@ struct meson_overlay {
 };
 #define to_meson_overlay(x) container_of(x, struct meson_overlay, base)
 
-#define FRAC_16_16(mult, div)(((mult) << 16) / (div))
-
 static int meson_overlay_atomic_check(struct drm_plane *plane,
  struct drm_atomic_state *state)
 {
@@ -181,8 +180,8 @@ static int meson_overlay_atomic_check(struct drm_plane 
*plane,
 
return drm_atomic_helper_check_plane_state(new_plane_state,
   crtc_state,
-  FRAC_16_16(1, 5),
-  FRAC_16_16(5, 1),
+  drm_fixed_16_16(1, 5),
+  drm_fixed_16_16(5, 1),
   true, true);
 }
 
diff --git a/drivers/gpu/drm/meson/meson_plane.c 
b/drivers/gpu/drm/meson/meson_plane.c
index 8640a8a8a469..4fae9ebbf178 100644
--- a/drivers/gpu/drm/meson/meson_plane.c
+++ b/drivers/gpu/drm/meson/meson_plane.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "meson_plane.h"
 #include "meson_registers.h"
@@ -68,8 +69,6 @@ struct meson_plane {
 };
 #define to_meson_plane(x) container_of(x, struct meson_plane, base)
 
-#define FRAC_16_16(mult, div)(((mult) << 16) / (div))
-
 static int meson_plane_atomic_check(struct drm_plane *plane,
struct drm_atomic_state *state)
 {
@@ -92,7 +91,7 @@ static int meson_plane_atomic_check(struct drm_plane *plane,
 */
return drm_atomic_helper_check_plane_state(new_plane_state,
   crtc_state,
-  FRAC_16_16(1, 5),
+  drm_fixed_16_16(1, 5),
   DRM_PLANE_HELPER_NO_SCALING,
   false, true);
 }
-- 
2.30.2



[PATCH 1/5] drm: Add drm_fixed_16_16 helper

2021-09-01 Thread Alyssa Rosenzweig
This constructs a fixed 16.16 rational, useful to specify the minimum
and maximum scaling in drm_atomic_helper_check_plane_state. It is
open-coded as a macro in multiple drivers, so let's share the helper.

Signed-off-by: Alyssa Rosenzweig 
---
 include/drm/drm_fixed.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/include/drm/drm_fixed.h b/include/drm/drm_fixed.h
index 553210c02ee0..df1f369b4918 100644
--- a/include/drm/drm_fixed.h
+++ b/include/drm/drm_fixed.h
@@ -208,4 +208,9 @@ static inline s64 drm_fixp_exp(s64 x)
return sum;
 }
 
+static inline int drm_fixed_16_16(s32 mult, s32 div)
+{
+   return (mult << 16) / div;
+}
+
 #endif
-- 
2.30.2



[PATCH 2/2] drm/msm/dpu: Fix timeout issues on command mode panels

2021-09-01 Thread AngeloGioacchino Del Regno
In function dpu_encoder_phys_cmd_wait_for_commit_done we are always
checking if the relative CTL is started by waiting for an interrupt
to fire: it is fine to do that, but then sometimes we call this
function while the CTL is up and has never been put down, but that
interrupt gets raised only when the CTL gets a state change from
0 to 1 (disabled to enabled), so we're going to wait for something
that will never happen on its own.

Solving this while avoiding to restart the CTL is actually possible
and can be done by just checking if it is already up and running
when the wait_for_commit_done function is called: in this case, so,
if the CTL was already running, we can say that the commit is done
if the command transmission is complete (in other terms, if the
interface has been flushed).

Signed-off-by: AngeloGioacchino Del Regno 

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
index aa01698d6b25..b5b1b555ac4e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
@@ -682,6 +682,9 @@ static int dpu_encoder_phys_cmd_wait_for_commit_done(
if (!dpu_encoder_phys_cmd_is_master(phys_enc))
return 0;
 
+   if (phys_enc->hw_ctl->ops.is_started)
+   return dpu_encoder_phys_cmd_wait_for_tx_complete(phys_enc);
+
return _dpu_encoder_phys_cmd_wait_for_ctl_start(phys_enc);
 }
 
-- 
2.32.0



[PATCH 1/2] drm/msm/dpu: Add a function to retrieve the current CTL status

2021-09-01 Thread AngeloGioacchino Del Regno
Add a function that returns whether the requested CTL is active or not:
this will be used in a later commit to fix command mode panel issues.

Signed-off-by: AngeloGioacchino Del Regno 

---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 6 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 7 +++
 2 files changed, 13 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 64740ddb983e..3b6fd73eb3a8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
@@ -91,6 +91,11 @@ static inline void dpu_hw_ctl_trigger_start(struct 
dpu_hw_ctl *ctx)
DPU_REG_WRITE(>hw, CTL_START, 0x1);
 }
 
+static inline bool dpu_hw_ctl_is_started(struct dpu_hw_ctl *ctx)
+{
+   return !!(DPU_REG_READ(>hw, CTL_START) & BIT(0));
+}
+
 static inline void dpu_hw_ctl_trigger_pending(struct dpu_hw_ctl *ctx)
 {
trace_dpu_hw_ctl_trigger_prepare(ctx->pending_flush_mask,
@@ -579,6 +584,7 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops,
ops->get_pending_flush = dpu_hw_ctl_get_pending_flush;
ops->get_flush_register = dpu_hw_ctl_get_flush_register;
ops->trigger_start = dpu_hw_ctl_trigger_start;
+   ops->is_started = dpu_hw_ctl_is_started;
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;
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..ac1544474022 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
@@ -61,6 +61,13 @@ struct dpu_hw_ctl_ops {
 */
void (*trigger_start)(struct dpu_hw_ctl *ctx);
 
+   /**
+* check if the ctl is started
+* @ctx   : ctl path ctx pointer
+* @Return: true if started, false if stopped
+*/
+   bool (*is_started)(struct dpu_hw_ctl *ctx);
+
/**
 * kickoff prepare is in progress hw operation for sw
 * controlled interfaces: DSI cmd mode and WB interface
-- 
2.32.0



[PATCH 1/2] drm/panel: Add BOE BF060Y8M-AJ0 5.99" AMOLED panel driver

2021-09-01 Thread AngeloGioacchino Del Regno
This adds support for the BOE BF060Y8M-AJ0 5.99" AMOLED module
that can be found in some F(x)Tec Pro1 and Elephone U1 devices.

Signed-off-by: AngeloGioacchino Del Regno 

---
 drivers/gpu/drm/panel/Kconfig |  11 +
 drivers/gpu/drm/panel/Makefile|   1 +
 .../gpu/drm/panel/panel-boe-bf060y8m-aj0.c| 445 ++
 3 files changed, 457 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-boe-bf060y8m-aj0.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index beb581b96ecd..ab5a52c71ec5 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -37,6 +37,17 @@ config DRM_PANEL_ASUS_Z00T_TM5P5_NT35596
  NT35596 1080x1920 video mode panel as found in some Asus
  Zenfone 2 Laser Z00T devices.
 
+config DRM_PANEL_BOE_BF060Y8M_AJ0
+   tristate "Boe BF060Y8M-AJ0 panel"
+   depends on OF
+   depends on DRM_MIPI_DSI
+   depends on BACKLIGHT_CLASS_DEVICE
+   help
+ Say Y here if you want to enable support for Boe BF060Y8M-AJ0
+ 5.99" AMOLED modules. The panel has a 1080x2160 resolution and
+ uses 24 bit RGB per pixel. It provides a MIPI DSI interface to
+ the host and backlight is controlled through DSI commands.
+
 config DRM_PANEL_BOE_HIMAX8279D
tristate "Boe Himax8279d panel"
depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index c8132050bcec..1b494d479ffd 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_DRM_PANEL_ABT_Y030XX067A) += panel-abt-y030xx067a.o
 obj-$(CONFIG_DRM_PANEL_ARM_VERSATILE) += panel-arm-versatile.o
 obj-$(CONFIG_DRM_PANEL_ASUS_Z00T_TM5P5_NT35596) += 
panel-asus-z00t-tm5p5-n35596.o
+obj-$(CONFIG_DRM_PANEL_BOE_BF060Y8M_AJ0) += panel-boe-bf060y8m-aj0.o
 obj-$(CONFIG_DRM_PANEL_BOE_HIMAX8279D) += panel-boe-himax8279d.o
 obj-$(CONFIG_DRM_PANEL_BOE_TV101WUM_NL6) += panel-boe-tv101wum-nl6.o
 obj-$(CONFIG_DRM_PANEL_DSI_CM) += panel-dsi-cm.o
diff --git a/drivers/gpu/drm/panel/panel-boe-bf060y8m-aj0.c 
b/drivers/gpu/drm/panel/panel-boe-bf060y8m-aj0.c
new file mode 100644
index ..8d080004b86c
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-boe-bf060y8m-aj0.c
@@ -0,0 +1,445 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * BOE BF060Y8M-AJ0 5.99" MIPI-DSI OLED Panel on SW43404 DriverIC
+ *
+ * Copyright (c) 2020 AngeloGioacchino Del Regno
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define DCS_ALLOW_HBM_RANGE0x0c
+#define DCS_DISALLOW_HBM_RANGE 0x08
+
+enum boe_bf060y8m_aj0_supplies {
+   BF060Y8M_VREG_VCC,
+   BF060Y8M_VREG_VDDIO,
+   BF060Y8M_VREG_VCI,
+   BF060Y8M_VREG_EL_VDD,
+   BF060Y8M_VREG_EL_VSS,
+   BF060Y8M_VREG_MAX
+};
+
+struct boe_bf060y8m_aj0 {
+   struct drm_panel panel;
+   struct mipi_dsi_device *dsi;
+   struct regulator_bulk_data vregs[BF060Y8M_VREG_MAX];
+   struct gpio_desc *reset_gpio;
+   bool prepared;
+};
+
+static inline
+struct boe_bf060y8m_aj0 *to_boe_bf060y8m_aj0(struct drm_panel *panel)
+{
+   return container_of(panel, struct boe_bf060y8m_aj0, panel);
+}
+
+#define dsi_dcs_write_seq(dsi, seq...) do {\
+   static const u8 d[] = { seq };  \
+   int ret;\
+   ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d)); \
+   if (ret < 0)\
+   return ret; \
+   } while (0)
+
+static void boe_bf060y8m_aj0_reset(struct boe_bf060y8m_aj0 *boe)
+{
+   gpiod_set_value_cansleep(boe->reset_gpio, 0);
+   usleep_range(2000, 3000);
+   gpiod_set_value_cansleep(boe->reset_gpio, 1);
+   usleep_range(15000, 16000);
+   gpiod_set_value_cansleep(boe->reset_gpio, 0);
+   usleep_range(5000, 6000);
+}
+
+static int boe_bf060y8m_aj0_on(struct boe_bf060y8m_aj0 *boe)
+{
+   struct mipi_dsi_device *dsi = boe->dsi;
+   struct device *dev = >dev;
+   int ret;
+
+   dsi_dcs_write_seq(dsi, 0xb0, 0xa5, 0x00);
+   dsi_dcs_write_seq(dsi, 0xb2, 0x00, 0x4c);
+   dsi_dcs_write_seq(dsi, MIPI_DCS_SET_3D_CONTROL, 0x10);
+   dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_POWER_SAVE, DCS_ALLOW_HBM_RANGE);
+   dsi_dcs_write_seq(dsi, 0xf8,
+ 0x00, 0x08, 0x10, 0x00, 0x22, 0x00, 0x00, 0x2d);
+
+   ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
+   if (ret < 0) {
+   dev_err(dev, "Failed to exit sleep mode: %d\n", ret);
+   return ret;
+   }
+   msleep(30);
+
+   dsi_dcs_write_seq(dsi, 0xb0, 0xa5, 0x00);
+   dsi_dcs_write_seq(dsi, 0xc0,
+ 0x08, 0x48, 0x65, 0x33, 0x33, 0x33,
+  

[PATCH 2/2] dt-bindings: display: Document BOE BF060Y8M-AJ0 panel compatible

2021-09-01 Thread AngeloGioacchino Del Regno
Document the boe,bf060y8m-aj0 panel.

Signed-off-by: AngeloGioacchino Del Regno 

---
 .../display/panel/boe,bf060y8m-aj0.yaml   | 81 +++
 1 file changed, 81 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/panel/boe,bf060y8m-aj0.yaml

diff --git 
a/Documentation/devicetree/bindings/display/panel/boe,bf060y8m-aj0.yaml 
b/Documentation/devicetree/bindings/display/panel/boe,bf060y8m-aj0.yaml
new file mode 100644
index ..a8f3afa922c8
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/boe,bf060y8m-aj0.yaml
@@ -0,0 +1,81 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/boe,bf060y8m-aj0.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: BOE BF060Y8M-AJ0 5.99" 1080x2160 AMOLED Panel
+
+maintainers:
+  - AngeloGioacchino Del Regno 
+
+description: |
+  This is a 5.99" 1080x2160 16.7M Color active matrix AMOLED
+  video mode panel module on MIPI-DSI 4-Lane interface, GGRB
+  pixel arrangement, 63 micrometers pitch, with an active
+  area of 68.04 x 136.08 millimeters.
+  Each pixel is divided into red and green dots, or blue and
+  green dots, and two pixels share red or blue dots which are
+  arranged in vertical stripe.
+  The DriverIC for this panel module is SW43404.
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+const: boe,bf060y8m-aj0
+
+  elvdd-supply:
+description: EL Driving positive (VDD) supply (4.40-4.80V)
+  elvss-supply:
+description: EL Driving negative (VSS) supply (-5.00V to -1.40V)
+  vcc-supply:
+description: Core (TSP) voltage supply (2.70-3.60V)
+  vci-supply:
+description: DriverIC Operation supply (2.60-3.60V)
+  vddio-supply:
+description: I/O voltage supply (1.62-1.98V)
+
+  port: true
+  reg: true
+  reset-gpios: true
+
+required:
+  - compatible
+  - elvdd-supply
+  - elvss-supply
+  - vcc-supply
+  - vci-supply
+  - vddio-supply
+  - reg
+  - reset-gpios
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+
+dsi {
+#address-cells = <1>;
+#size-cells = <0>;
+panel@0 {
+compatible = "boe,bf060y8m-aj0";
+reg = <0>;
+
+reset-gpios = < 94 GPIO_ACTIVE_HIGH>;
+
+vcc-supply = <_vcc_vreg>;
+vddio-supply = <_vddio_vreg>;
+vci-supply = <_vci_vreg>;
+elvdd-supply = <_elvdd_vreg>;
+elvss-supply = <_elvss_vreg>;
+
+port {
+panel_in: endpoint {
+remote-endpoint = <_out>;
+};
+};
+};
+};
-- 
2.32.0



[PATCH 1/2] drm/panel: Add driver for Novatek NT35950 DSI DriverIC panels

2021-09-01 Thread AngeloGioacchino Del Regno
Add a driver for panels using the Novatek NT35950 Display Driver IC,
including support for the Sharp LS055D1SX04, found in some Sony Xperia
Z5 Premium and XZ Premium smartphones.

Signed-off-by: AngeloGioacchino Del Regno 

---
 drivers/gpu/drm/panel/Kconfig |  11 +
 drivers/gpu/drm/panel/Makefile|   1 +
 drivers/gpu/drm/panel/panel-novatek-nt35950.c | 702 ++
 3 files changed, 714 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-novatek-nt35950.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index ab5a52c71ec5..1cf064d597a2 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -271,6 +271,17 @@ config DRM_PANEL_NOVATEK_NT35510
  around the Novatek NT35510 display controller, such as some
  Hydis panels.
 
+config DRM_PANEL_NOVATEK_NT35950
+   tristate "Novatek NT35950 DSI panel"
+   depends on OF
+   depends on DRM_MIPI_DSI
+   depends on BACKLIGHT_CLASS_DEVICE
+   help
+ Say Y here if you want to enable support for the panels built
+ around the Novatek NT35950 display controller, such as some
+ Sharp panels used in Sony Xperia Z5 Premium and XZ Premium
+ mobile phones.
+
 config DRM_PANEL_NOVATEK_NT36672A
tristate "Novatek NT36672A DSI panel"
depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 1b494d479ffd..190b5f90af4d 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o
 obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
 obj-$(CONFIG_DRM_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o
 obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35510) += panel-novatek-nt35510.o
+obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35950) += panel-novatek-nt35950.o
 obj-$(CONFIG_DRM_PANEL_NOVATEK_NT36672A) += panel-novatek-nt36672a.o
 obj-$(CONFIG_DRM_PANEL_NOVATEK_NT39016) += panel-novatek-nt39016.o
 obj-$(CONFIG_DRM_PANEL_MANTIX_MLAF057WE51) += panel-mantix-mlaf057we51.o
diff --git a/drivers/gpu/drm/panel/panel-novatek-nt35950.c 
b/drivers/gpu/drm/panel/panel-novatek-nt35950.c
new file mode 100644
index ..d42c7af0d75c
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-novatek-nt35950.c
@@ -0,0 +1,702 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Novatek NT35950 DriverIC panels driver
+ *
+ * Copyright (c) 2021 AngeloGioacchino Del Regno
+ *
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MCS_CMD_MAUCCTR0xf0 /* Manufacturer command 
enable */
+#define MCS_PARAM_SCALER_FUNCTION  0x58 /* Scale-up function */
+#define MCS_PARAM_SCALEUP_MODE 0xc9
+ #define MCS_SCALEUP_SIMPLE0x0
+ #define MCS_SCALEUP_BILINEAR  BIT(0)
+ #define MCS_SCALEUP_DUPLICATE (BIT(0) | BIT(4))
+
+/* VESA Display Stream Compression param */
+#define MCS_PARAM_VESA_DSC_ON  0x03
+
+/* Data Compression mode */
+#define MCS_PARAM_DATA_COMPRESSION 0x90
+ #define MCS_DATA_COMPRESSION_NONE 0x00
+ #define MCS_DATA_COMPRESSION_FBC  0x02
+ #define MCS_DATA_COMPRESSION_DSC  0x03
+
+/* Display Output control */
+#define MCS_PARAM_DISP_OUTPUT_CTRL 0xb4
+ #define MCS_DISP_OUT_SRAM_EN  BIT(0)
+ #define MCS_DISP_OUT_VIDEO_MODE   BIT(4)
+
+/* VESA Display Stream Compression setting */
+#define MCS_PARAM_VESA_DSC_SETTING 0xc0
+
+/* SubPixel Rendering (SPR) */
+#define MCS_PARAM_SPR_EN   0xe3
+#define MCS_PARAM_SPR_MODE 0xef
+ #define MCS_SPR_MODE_YYG_RAINBOW_RGB  0x01
+
+#define NT35950_VREG_MAX   4
+
+struct nt35950 {
+   struct drm_panel panel;
+   struct drm_connector *connector;
+   struct mipi_dsi_device *dsi[2];
+   struct regulator_bulk_data vregs[NT35950_VREG_MAX];
+   struct gpio_desc *reset_gpio;
+   const struct nt35950_panel_desc *desc;
+
+   int cur_mode;
+   u8 last_page;
+   bool prepared;
+};
+
+struct nt35950_panel_mode {
+   const struct drm_display_mode mode;
+
+   bool enable_sram;
+   bool is_video_mode;
+   u8 scaler_on;
+   u8 scaler_mode;
+   u8 compression;
+   u8 spr_en;
+   u8 spr_mode;
+};
+
+struct nt35950_panel_desc {
+   const char *model_name;
+   const struct mipi_dsi_device_info dsi_info;
+   const struct nt35950_panel_mode *mode_data;
+
+   bool is_dual_dsi;
+   u8 num_lanes;
+   u8 num_modes;
+};
+
+static inline struct nt35950 *to_nt35950(struct drm_panel *panel)
+{
+   return container_of(panel, struct nt35950, panel);
+}
+
+#define dsi_dcs_write_seq(dsi, seq...) do {\
+   static const u8 d[] = { seq };  \
+   int ret;\
+ 

[PATCH 2/2] dt-bindings: display: Add bindings for Novatek NT35950

2021-09-01 Thread AngeloGioacchino Del Regno
The nt35950 IC from Novatek is a Driver IC used to drive MIPI-DSI panels,
with Static RAM for content retention in command mode and also supports
video mode with VESA Frame Buffer Compression or Display Stream Compression
on single, or dual dsi port(s).
This DDIC is also capable of upscaling an input image to the panel's native
resolution, for example it can upscale a 1920x1080 input to 3840x2160 with
either bilinear interpolation or pixel duplication.

Signed-off-by: AngeloGioacchino Del Regno 

---
 .../display/panel/novatek,nt35950.yaml| 106 ++
 1 file changed, 106 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/panel/novatek,nt35950.yaml

diff --git 
a/Documentation/devicetree/bindings/display/panel/novatek,nt35950.yaml 
b/Documentation/devicetree/bindings/display/panel/novatek,nt35950.yaml
new file mode 100644
index ..377a05d48a02
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/novatek,nt35950.yaml
@@ -0,0 +1,106 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/novatek,nt35950.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Novatek NT35950-based display panels
+
+maintainers:
+  - AngeloGioacchino Del Regno 
+
+description: |
+  The nt35950 IC from Novatek is a Driver IC used to drive MIPI-DSI panels,
+  with Static RAM for content retention in command mode and also supports
+  video mode with VESA Frame Buffer Compression or Display Stream Compression
+  on single, or dual dsi port(s).
+  This DDIC is also capable of upscaling an input image to the panel's native
+  resolution, for example it can upscale a 1920x1080 input to 3840x2160 with
+  either bilinear interpolation or pixel duplication.
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+items:
+  - enum:
+  - sharp,ls055d1sx04
+  - const: novatek,nt35950
+description: This indicates the panel manufacturer of the panel
+  that is in turn using the NT35950 panel driver. The compatible
+  string determines how the NT35950 panel driver shall be configured
+  to work with the indicated panel. The novatek,nt35950 compatible shall
+  always be provided as a fallback.
+
+  reset-gpios:
+maxItems: 1
+description: phandle of gpio for reset line - This should be 8mA, gpio
+  can be configured using mux, pinctrl, pinctrl-names (active high)
+
+  avdd-supply:
+description: positive boost supply regulator
+  avee-supply:
+description: negative boost supply regulator
+  dvdd-supply:
+description: regulator that supplies the digital voltage
+  vddio-supply:
+description: regulator that supplies the I/O voltage
+
+  backlight: true
+  ports: true
+  reg: true
+
+required:
+  - compatible
+  - reg
+  - reset-gpios
+  - avdd-supply
+  - avee-supply
+  - dvdd-supply
+  - vddio-supply
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+
+dsi0 {
+#address-cells = <1>;
+#size-cells = <0>;
+
+panel@0 {
+compatible = "sharp,ls055d1sx04", "novatek,nt35950";
+reg = <0>;
+
+backlight = <_wled>;
+reset-gpios = < 94 GPIO_ACTIVE_HIGH>;
+
+avdd-supply = <>;
+avee-supply = <>;
+dvdd-supply = <_dvdd_vreg>;
+vddio-supply = <_l14a_1p85>;
+
+ports {
+#address-cells = <1>;
+#size-cells = <0>;
+
+port@0 {
+reg = <0>;
+panel_in0: endpoint {
+remote-endpoint = <_out>;
+};
+};
+
+port@1 {
+reg = <1>;
+panel_in1: endpoint {
+remote-endpoint = <_out>;
+};
+};
+};
+};
+};
+
+...
-- 
2.32.0



[PATCH V6 2/2] drm/vkms: Add support for virtual hardware mode

2021-09-01 Thread Sumera Priyadarsini
Add a virtual hardware or vblank-less mode as a module
to enable VKMS to emulate virtual hardware drivers. This means
no vertical blanking events occur and pageflips are completed
arbitrarily and when required for updating the frame.

Add a new drm_crtc_funcs struct, vkms_vblankless_crtc_funcs and a
drm_crtc_helper_funcs struct, vkms_vblankless_crtc_helper_funcs()
which hold the atomic helpers for virtual hardware mode.
The existing vkms_crtc_funcs struct and vkms_crtc_helper_funcs
struct hold atomic helpers for the default vblank mode.
This makes the code flow clearer and testing
virtual hardware mode easier.

Add a function vkms_crtc_composer() which calls the helper function,
vkms_composer_common() for plane composition in vblank-less mode.
vkms_crtc_composer() is directly called in the atomic hook in
vkms_crtc_atomic_begin().

However, some crc captures still use vblanks which causes the crc-based
igt tests to crash. So, no CRC functions are called in vblankless mode
for now and will be implemented in a later patch.

This patchset has been tested with the igt tests- kms_writeback, kms_atomic
, kms_lease, kms_flip, kms_pipe_get_crc and preserves results except for
subtests related to crc reads and vertical blanking, in which case,
tests are skipped.

The patch is based on Rodrigo Siqueira's
patch(https://patchwork.freedesktop.org/patch/316851/?series=48469=3)
and the ensuing review.

Signed-off-by: Sumera Priyadarsini 
---
Changes in V6:
- Skip CRC functions in vblankless mode
- Refactor helper function names(Melissa)
Changes in V5:
- Move vkms_crtc_composer() to this patch(Melissa)
- Add more clarification for "vblank-less" mode(Pekka)
- Replace kzalloc() with kvmalloc() in compose_active_planes()
to fix memory allocation error for output frame
- Fix checkpatch warnings (Melissa)
Changes in V3:
- Refactor patchset(Melissa)
Changes in V2:
- Add atomic helper functions in a separate struct for virtual hardware
mode (Daniel)
- Remove spinlock across 'vkms_output->lock' in vkms_crtc.c(Daniel)
- Add vkms_composer_common() (Daniel)
---
 drivers/gpu/drm/vkms/vkms_composer.c  | 21 +++--
 drivers/gpu/drm/vkms/vkms_crtc.c  | 43 +--
 drivers/gpu/drm/vkms/vkms_drv.c   | 16 +++---
 drivers/gpu/drm/vkms/vkms_drv.h   |  2 ++
 drivers/gpu/drm/vkms/vkms_writeback.c |  3 +-
 5 files changed, 74 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_composer.c 
b/drivers/gpu/drm/vkms/vkms_composer.c
index bca746fb5b53..a009589b2c3a 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -176,11 +176,12 @@ static int compose_active_planes(void **vaddr_out,
 {
struct drm_framebuffer *fb = _composer->fb;
struct drm_gem_object *gem_obj = drm_gem_fb_get_obj(fb, 0);
+
const void *vaddr;
int i;
 
if (!*vaddr_out) {
-   *vaddr_out = kzalloc(gem_obj->size, GFP_KERNEL);
+   *vaddr_out = kvmalloc(gem_obj->size, GFP_KERNEL);
if (!*vaddr_out) {
DRM_ERROR("Cannot allocate memory for output frame.");
return -ENOMEM;
@@ -229,7 +230,7 @@ int vkms_composer_common(struct vkms_crtc_state *crtc_state,
 
if (ret) {
if ((ret == -EINVAL || ret == -ENOMEM) && !wb_pending)
-   kfree(vaddr_out);
+   kvfree(vaddr_out);
return ret;
}
 
@@ -241,7 +242,7 @@ int vkms_composer_common(struct vkms_crtc_state *crtc_state,
crtc_state->wb_pending = false;
spin_unlock_irq(>composer_lock);
} else {
-   kfree(vaddr_out);
+   kvfree(vaddr_out);
}
 
return 0;
@@ -296,6 +297,20 @@ void vkms_composer_worker(struct work_struct *work)
drm_crtc_add_crc_entry(crtc, true, frame_start++, );
 }
 
+void vkms_crtc_composer(struct vkms_crtc_state *crtc_state)
+{
+   struct drm_crtc *crtc = crtc_state->base.crtc;
+   struct vkms_output *out = drm_crtc_to_vkms_output(crtc);
+   u32 crc32 = 0;
+   int ret;
+
+   ret = vkms_composer_common(crtc_state, out, crtc_state->wb_pending, 
);
+   if (ret == -EINVAL)
+   return;
+
+   drm_crtc_add_crc_entry(crtc, true, 0, );
+}
+
 static const char * const pipe_crc_sources[] = {"auto"};
 
 const char *const *vkms_get_crc_sources(struct drm_crtc *crtc,
diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
index 57bbd32e9beb..4a933553e0e4 100644
--- a/drivers/gpu/drm/vkms/vkms_crtc.c
+++ b/drivers/gpu/drm/vkms/vkms_crtc.c
@@ -174,6 +174,15 @@ static const struct drm_crtc_funcs vkms_crtc_funcs = {
.verify_crc_source  = vkms_verify_crc_source,
 };
 
+static const struct drm_crtc_funcs vkms_vblankless_crtc_funcs = {
+   .set_config = drm_atomic_helper_set_config,
+   .destroy= drm_crtc_cleanup,
+   .page_flip  

[PATCH V6 1/2] drm/vkms: Refactor vkms_composer_worker() to prep for virtual_hw mode

2021-09-01 Thread Sumera Priyadarsini
Add a new function vkms_composer_common(). The actual plane
composition work has been moved to the helper function,
vkms_composer_common() which is called by vkms_composer_worker()
and will be called in the implementation of virtual_hw mode
as well.

Signed-off-by: Sumera Priyadarsini 
---
Changes in V5:
- Move vkms_crtc_composer() to the patch that introduces
virtual_hw mode (Melissa)
- Fix checkpatch errors(Melissa)
Changes in V4:
- Fix warning
Changes in V3:
- Refactor patchset (Melissa)
Change in V2:
- Add vkms_composer_common() (Daniel)
---
 drivers/gpu/drm/vkms/vkms_composer.c | 75 
 drivers/gpu/drm/vkms/vkms_drv.h  |  2 +
 2 files changed, 45 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_composer.c 
b/drivers/gpu/drm/vkms/vkms_composer.c
index 9e8204be9a14..bca746fb5b53 100644
--- a/drivers/gpu/drm/vkms/vkms_composer.c
+++ b/drivers/gpu/drm/vkms/vkms_composer.c
@@ -206,6 +206,47 @@ static int compose_active_planes(void **vaddr_out,
return 0;
 }
 
+int vkms_composer_common(struct vkms_crtc_state *crtc_state,
+struct vkms_output *out, bool wb_pending, uint32_t 
*crc32)
+{
+   struct vkms_composer *primary_composer = NULL;
+   struct vkms_plane_state *act_plane = NULL;
+   void *vaddr_out = NULL;
+   int ret;
+
+   if (crtc_state->num_active_planes >= 1) {
+   act_plane = crtc_state->active_planes[0];
+   if (act_plane->base.base.plane->type == DRM_PLANE_TYPE_PRIMARY)
+   primary_composer = act_plane->composer;
+   }
+
+   if (!primary_composer)
+   return -EINVAL;
+   if (wb_pending)
+   vaddr_out = crtc_state->active_writeback->data[0].vaddr;
+
+   ret = compose_active_planes(_out, primary_composer, crtc_state);
+
+   if (ret) {
+   if ((ret == -EINVAL || ret == -ENOMEM) && !wb_pending)
+   kfree(vaddr_out);
+   return ret;
+   }
+
+   *crc32 = compute_crc(vaddr_out, primary_composer);
+
+   if (wb_pending) {
+   drm_writeback_signal_completion(>wb_connector, 0);
+   spin_lock_irq(>composer_lock);
+   crtc_state->wb_pending = false;
+   spin_unlock_irq(>composer_lock);
+   } else {
+   kfree(vaddr_out);
+   }
+
+   return 0;
+}
+
 /**
  * vkms_composer_worker - ordered work_struct to compute CRC
  *
@@ -222,10 +263,7 @@ void vkms_composer_worker(struct work_struct *work)
composer_work);
struct drm_crtc *crtc = crtc_state->base.crtc;
struct vkms_output *out = drm_crtc_to_vkms_output(crtc);
-   struct vkms_composer *primary_composer = NULL;
-   struct vkms_plane_state *act_plane = NULL;
bool crc_pending, wb_pending;
-   void *vaddr_out = NULL;
u32 crc32 = 0;
u64 frame_start, frame_end;
int ret;
@@ -247,37 +285,10 @@ void vkms_composer_worker(struct work_struct *work)
if (!crc_pending)
return;
 
-   if (crtc_state->num_active_planes >= 1) {
-   act_plane = crtc_state->active_planes[0];
-   if (act_plane->base.base.plane->type == DRM_PLANE_TYPE_PRIMARY)
-   primary_composer = act_plane->composer;
-   }
-
-   if (!primary_composer)
+   ret = vkms_composer_common(crtc_state, out, wb_pending, );
+   if (ret == -EINVAL)
return;
 
-   if (wb_pending)
-   vaddr_out = crtc_state->active_writeback->data[0].vaddr;
-
-   ret = compose_active_planes(_out, primary_composer,
-   crtc_state);
-   if (ret) {
-   if (ret == -EINVAL && !wb_pending)
-   kfree(vaddr_out);
-   return;
-   }
-
-   crc32 = compute_crc(vaddr_out, primary_composer);
-
-   if (wb_pending) {
-   drm_writeback_signal_completion(>wb_connector, 0);
-   spin_lock_irq(>composer_lock);
-   crtc_state->wb_pending = false;
-   spin_unlock_irq(>composer_lock);
-   } else {
-   kfree(vaddr_out);
-   }
-
/*
 * The worker can fall behind the vblank hrtimer, make sure we catch up.
 */
diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
index d48c23d40ce5..6f5f63591c20 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.h
+++ b/drivers/gpu/drm/vkms/vkms_drv.h
@@ -137,6 +137,8 @@ int vkms_verify_crc_source(struct drm_crtc *crtc, const 
char *source_name,
   size_t *values_cnt);
 
 /* Composer Support */
+int vkms_composer_common(struct vkms_crtc_state *crtc_state, struct 
vkms_output *out,
+bool wb_pending, uint32_t *crcs);
 void vkms_composer_worker(struct work_struct *work);
 void vkms_set_composer(struct vkms_output *out, bool enabled);
 
-- 
2.31.1



[PATCH V6 0/2] drm/vkms: Add virtual hardware module

2021-09-01 Thread Sumera Priyadarsini
This patchset adds support for emulating virtual hardware with VKMS.
The virtual hardware mode can be enabled by using the following command
while loading the module:
sudo modprobe vkms enable_virtual_hw=1

The first patch is prep work for adding virtual_hw mode and refactors
the plane composition in vkms by adding a helper function
vkms_composer_common() which can be used for both vblank mode
and virtual mode.

The second patch adds virtual hardware support as a module option.
It adds new atomic helper functions for the virtual mode
and uses the existing atomic helpers for vblank mode
This gives us two sets of drm_crtc_funcs and drm_crtc_helper_funcs
structs for both modes, making the code flow cleaner and
easier to debug.

This patchset has been tested with the igt tests- kms_writeback, kms_atomic,
kms_lease, kms_flip, kms_pipe_get_crc and preserves results except for
subtests related to crc reads and vertical blanking, in which case,
tests are skipped.

Sumera Priyadarsini (2):
  drm/vkms: Refactor vkms_composer_worker() to prep for virtual_hw mode
  drm/vkms: Add support for virtual hardware mode

 drivers/gpu/drm/vkms/vkms_composer.c  | 92 +--
 drivers/gpu/drm/vkms/vkms_crtc.c  | 43 -
 drivers/gpu/drm/vkms/vkms_drv.c   | 16 +++--
 drivers/gpu/drm/vkms/vkms_drv.h   |  4 ++
 drivers/gpu/drm/vkms/vkms_writeback.c |  3 +-
 5 files changed, 117 insertions(+), 41 deletions(-)

-- 
2.31.1



Re: [PATCH] drm: rcar-du: Improve kernel log messages when initializing encoders

2021-09-01 Thread Kieran Bingham
On 22/08/2021 01:39, Laurent Pinchart wrote:
> Improve the debugging and error messages printing when initializing
> encoders by replacing the output number by the output name, printing the
> bridge OF node name, and the error code of failed operations.
> 
> While at it, move the related rcar_du_output enumeration from
> rcar_du_crtc.h to rcar_du_drv.h as it's not specific to the CRTC.
> 

It would be nice if you applied "drm: rcar-du: Sort the DU outputs" [0]
before this patch.

[0]
https://patchwork.kernel.org/project/linux-renesas-soc/patch/20210622232024.3215248-2-kieran.bing...@ideasonboard.com/

But I can always rebase that later otherwise.

Reviewed-by: Kieran Bingham 


> Signed-off-by: Laurent Pinchart 
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_crtc.h| 11 ---
>  drivers/gpu/drm/rcar-du/rcar_du_drv.c | 18 ++
>  drivers/gpu/drm/rcar-du/rcar_du_drv.h | 13 +
>  drivers/gpu/drm/rcar-du/rcar_du_encoder.c | 12 +++-
>  drivers/gpu/drm/rcar-du/rcar_du_kms.c |  4 ++--
>  5 files changed, 40 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h 
> b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> index 5f2940c42225..66e8839db708 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h
> @@ -93,17 +93,6 @@ struct rcar_du_crtc_state {
>  
>  #define to_rcar_crtc_state(s) container_of(s, struct rcar_du_crtc_state, 
> state)
>  
> -enum rcar_du_output {
> - RCAR_DU_OUTPUT_DPAD0,
> - RCAR_DU_OUTPUT_DPAD1,
> - RCAR_DU_OUTPUT_LVDS0,
> - RCAR_DU_OUTPUT_LVDS1,
> - RCAR_DU_OUTPUT_HDMI0,
> - RCAR_DU_OUTPUT_HDMI1,
> - RCAR_DU_OUTPUT_TCON,
> - RCAR_DU_OUTPUT_MAX,
> -};
> -
>  int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int swindex,
>   unsigned int hwindex);
>  
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c 
> b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> index 4ac26d08ebb4..d4dc101dc1d7 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> @@ -502,6 +502,24 @@ static const struct of_device_id rcar_du_of_table[] = {
>  
>  MODULE_DEVICE_TABLE(of, rcar_du_of_table);
>  
> +const char *rcar_du_output_name(enum rcar_du_output output)
> +{
> + static const char * const names[] = {
> + [RCAR_DU_OUTPUT_DPAD0] = "DPAD0",
> + [RCAR_DU_OUTPUT_DPAD1] = "DPAD1",
> + [RCAR_DU_OUTPUT_LVDS0] = "LVDS0",
> + [RCAR_DU_OUTPUT_LVDS1] = "LVDS1",
> + [RCAR_DU_OUTPUT_HDMI0] = "HDMI0",
> + [RCAR_DU_OUTPUT_HDMI1] = "HDMI1",
> + [RCAR_DU_OUTPUT_TCON] = "TCON",
> + };
> +
> + if (output >= ARRAY_SIZE(names) || !names[output])
> + return "UNKNOWN";
> +
> + return names[output];
> +}
> +
>  /* 
> -
>   * DRM operations
>   */
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h 
> b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> index 02ca2d0e1b55..859fd5992601 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h
> @@ -33,6 +33,17 @@ struct rcar_du_device;
>  
>  #define RCAR_DU_QUIRK_ALIGN_128B BIT(0)  /* Align pitches to 128 bytes */
>  
> +enum rcar_du_output {
> + RCAR_DU_OUTPUT_DPAD0,
> + RCAR_DU_OUTPUT_DPAD1,
> + RCAR_DU_OUTPUT_LVDS0,
> + RCAR_DU_OUTPUT_LVDS1,
> + RCAR_DU_OUTPUT_HDMI0,
> + RCAR_DU_OUTPUT_HDMI1,
> + RCAR_DU_OUTPUT_TCON,
> + RCAR_DU_OUTPUT_MAX,
> +};
> +
>  /*
>   * struct rcar_du_output_routing - Output routing specification
>   * @possible_crtcs: bitmask of possible CRTCs for the output
> @@ -126,4 +137,6 @@ static inline void rcar_du_write(struct rcar_du_device 
> *rcdu, u32 reg, u32 data)
>   iowrite32(data, rcdu->mmio + reg);
>  }
>  
> +const char *rcar_du_output_name(enum rcar_du_output output);
> +
>  #endif /* __RCAR_DU_DRV_H__ */
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c 
> b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
> index 4bf4e25d7f01..3977aaa1ab5a 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c
> @@ -103,8 +103,8 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
>   return -ENOLINK;
>   }
>  
> - dev_dbg(rcdu->dev, "initializing encoder %pOF for output %u\n",
> - enc_node, output);
> + dev_dbg(rcdu->dev, "initializing encoder %pOF for output %s\n",
> + enc_node, rcar_du_output_name(output));
>  
>   renc = drmm_encoder_alloc(>ddev, struct rcar_du_encoder, base,
> _du_encoder_funcs, DRM_MODE_ENCODER_NONE,
> @@ -118,8 +118,9 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu,
>   ret = drm_bridge_attach(>base, bridge, NULL,
>   DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>   if (ret) {
> - 

Re: [Intel-gfx] [PATCH 2/7] drm/i915/guc: put all guc objects in lmem when available

2021-09-01 Thread Matthew Auld
On Wed, 1 Sept 2021 at 03:21,  wrote:
>
> From: Daniele Ceraolo Spurio 
>
> The firmware binary has to be loaded from lmem and the recommendation is
> to put all other objects in there as well. Note that we don't fall back
> to system memory if the allocation in lmem fails because all objects are
> allocated during driver load and if we have issues with lmem at that point
> something is seriously wrong with the system, so no point in trying to
> handle it.
>
> Cc: Matthew Auld 
> Cc: Abdiel Janulgue 
> Cc: Michal Wajdeczko 
> Cc: Vinay Belgaumkar 
> Cc: Radoslaw Szwichtenberg 
> Signed-off-by: Daniele Ceraolo Spurio 
> Signed-off-by: Matthew Brost 
> ---
>  drivers/gpu/drm/i915/gem/i915_gem_lmem.c  | 26 
>  drivers/gpu/drm/i915/gem/i915_gem_lmem.h  |  4 ++
>  drivers/gpu/drm/i915/gt/uc/intel_guc.c|  9 ++-
>  drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c | 13 ++--
>  drivers/gpu/drm/i915/gt/uc/intel_huc.c| 14 -
>  drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  | 75 +--
>  6 files changed, 128 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c 
> b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
> index eb345305dc52..034226c5d4d0 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_lmem.c
> @@ -103,6 +103,32 @@ __i915_gem_object_create_lmem_with_ps(struct 
> drm_i915_private *i915,
>  size, page_size, flags);
>  }
>
> +struct drm_i915_gem_object *
> +i915_gem_object_create_lmem_from_data(struct drm_i915_private *i915,
> + const void *data, size_t size)
> +{
> +   struct drm_i915_gem_object *obj;
> +   void *map;
> +
> +   obj = i915_gem_object_create_lmem(i915,
> + round_up(size, PAGE_SIZE),
> + I915_BO_ALLOC_CONTIGUOUS);

Maybe push the ALLOC_CONTIG into the caller and expose the flags
instead, assuming it's still needed for something GuC related?
pin_map() at least no longer has that constraint.


  1   2   >