[PATCH v3 3/3] drm/i915: Convert REG_GENMASK* to fixed-width GENMASK_*

2024-02-07 Thread Lucas De Marchi
Now that include/linux/bits.h implements fixed-width GENMASK_*, use them
to implement the i915/xe specific macros. Converting each driver to use
the generic macros are left for later, when/if other driver-specific
macros are also generalized.

Signed-off-by: Lucas De Marchi 
Acked-by: Jani Nikula 
---
 drivers/gpu/drm/i915/i915_reg_defs.h | 108 +++
 1 file changed, 11 insertions(+), 97 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg_defs.h 
b/drivers/gpu/drm/i915/i915_reg_defs.h
index a685db1e815d..52f99eb96f86 100644
--- a/drivers/gpu/drm/i915/i915_reg_defs.h
+++ b/drivers/gpu/drm/i915/i915_reg_defs.h
@@ -9,76 +9,19 @@
 #include 
 #include 
 
-/**
- * REG_BIT() - Prepare a u32 bit value
- * @__n: 0-based bit number
- *
- * Local wrapper for BIT() to force u32, with compile time checks.
- *
- * @return: Value with bit @__n set.
- */
-#define REG_BIT(__n)   \
-   ((u32)(BIT(__n) +   \
-  BUILD_BUG_ON_ZERO(__is_constexpr(__n) && \
-((__n) < 0 || (__n) > 31
-
-/**
- * REG_BIT8() - Prepare a u8 bit value
- * @__n: 0-based bit number
- *
- * Local wrapper for BIT() to force u8, with compile time checks.
- *
- * @return: Value with bit @__n set.
- */
-#define REG_BIT8(__n)   \
-   ((u8)(BIT(__n) +\
-  BUILD_BUG_ON_ZERO(__is_constexpr(__n) && \
-((__n) < 0 || (__n) > 7
-
-/**
- * REG_GENMASK() - Prepare a continuous u32 bitmask
- * @__high: 0-based high bit
- * @__low: 0-based low bit
- *
- * Local wrapper for GENMASK() to force u32, with compile time checks.
- *
- * @return: Continuous bitmask from @__high to @__low, inclusive.
- */
-#define REG_GENMASK(__high, __low) \
-   ((u32)(GENMASK(__high, __low) + \
-  BUILD_BUG_ON_ZERO(__is_constexpr(__high) &&  \
-__is_constexpr(__low) &&   \
-((__low) < 0 || (__high) > 31 || (__low) > 
(__high)
-
-/**
- * REG_GENMASK64() - Prepare a continuous u64 bitmask
- * @__high: 0-based high bit
- * @__low: 0-based low bit
- *
- * Local wrapper for GENMASK_ULL() to force u64, with compile time checks.
- *
- * @return: Continuous bitmask from @__high to @__low, inclusive.
+/*
+ * Wrappers over the generic BIT_* and GENMASK_* implementations,
+ * for compatibility reasons with previous implementation
  */
-#define REG_GENMASK64(__high, __low)   \
-   ((u64)(GENMASK_ULL(__high, __low) + \
-  BUILD_BUG_ON_ZERO(__is_constexpr(__high) &&  \
-__is_constexpr(__low) &&   \
-((__low) < 0 || (__high) > 63 || (__low) > 
(__high)
+#define REG_GENMASK(__high, __low) GENMASK_U32(__high, __low)
+#define REG_GENMASK64(__high, __low)   GENMASK_U64(__high, __low)
+#define REG_GENMASK16(__high, __low)   GENMASK_U16(__high, __low)
+#define REG_GENMASK8(__high, __low)GENMASK_U8(__high, __low)
 
-/**
- * REG_GENMASK8() - Prepare a continuous u8 bitmask
- * @__high: 0-based high bit
- * @__low: 0-based low bit
- *
- * Local wrapper for GENMASK() to force u8, with compile time checks.
- *
- * @return: Continuous bitmask from @__high to @__low, inclusive.
- */
-#define REG_GENMASK8(__high, __low) \
-   ((u8)(GENMASK(__high, __low) +  \
-  BUILD_BUG_ON_ZERO(__is_constexpr(__high) &&  \
-__is_constexpr(__low) &&   \
-((__low) < 0 || (__high) > 7 || (__low) > 
(__high)
+#define REG_BIT(__n)   BIT_U32(__n)
+#define REG_BIT64(__n) BIT_U64(__n)
+#define REG_BIT16(__n) BIT_U16(__n)
+#define REG_BIT8(__n)  BIT_U8(__n)
 
 /*
  * Local integer constant expression version of is_power_of_2().
@@ -143,35 +86,6 @@
  */
 #define REG_FIELD_GET64(__mask, __val) ((u64)FIELD_GET(__mask, __val))
 
-/**
- * REG_BIT16() - Prepare a u16 bit value
- * @__n: 0-based bit number
- *
- * Local wrapper for BIT() to force u16, with compile time
- * checks.
- *
- * @return: Value with bit @__n set.
- */
-#define REG_BIT16(__n)   \
-   ((u16)(BIT(__n) +\
-  BUILD_BUG_ON_ZERO(__is_constexpr(__n) && \
-((__n) < 0 || (__n) > 15
-
-/**
- * REG_GENMASK16() - Prepare a continuous u8 bitmask
- * @__high: 0-based high bit
- * @__low: 0-based low bit
- *
- * Local wrapper for GENMASK() to 

[PATCH v3 1/3] bits: introduce fixed-type genmasks

2024-02-07 Thread Lucas De Marchi
From: Yury Norov 

Generalize __GENMASK() to support different types, and implement
fixed-types versions of GENMASK() based on it. The fixed-type version
allows more strict checks to the min/max values accepted, which is
useful for defining registers like implemented by i915 and xe drivers
with their REG_GENMASK*() macros.

The strict checks rely on shift-count-overflow compiler check to
fail the build if a number outside of the range allowed is passed.
Example:

#define FOO_MASK GENMASK_U32(33, 4)

will generate a warning like:

../include/linux/bits.h:41:31: error: left shift count >= width of type 
[-Werror=shift-count-overflow]
   41 |  (((t)~0ULL - ((t)(1) << (l)) + 1) & \
  |   ^~

Signed-off-by: Yury Norov 
Signed-off-by: Lucas De Marchi 
Acked-by: Jani Nikula 
---
 include/linux/bitops.h |  1 -
 include/linux/bits.h   | 32 ++--
 2 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index 2ba557e067fe..1db50c69cfdb 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -15,7 +15,6 @@
 #  define aligned_byte_mask(n) (~0xffUL << (BITS_PER_LONG - 8 - 8*(n)))
 #endif
 
-#define BITS_PER_TYPE(type)(sizeof(type) * BITS_PER_BYTE)
 #define BITS_TO_LONGS(nr)  __KERNEL_DIV_ROUND_UP(nr, BITS_PER_TYPE(long))
 #define BITS_TO_U64(nr)__KERNEL_DIV_ROUND_UP(nr, 
BITS_PER_TYPE(u64))
 #define BITS_TO_U32(nr)__KERNEL_DIV_ROUND_UP(nr, 
BITS_PER_TYPE(u32))
diff --git a/include/linux/bits.h b/include/linux/bits.h
index 7c0cf5031abe..bd56f32de44e 100644
--- a/include/linux/bits.h
+++ b/include/linux/bits.h
@@ -6,6 +6,8 @@
 #include 
 #include 
 
+#define BITS_PER_TYPE(type)(sizeof(type) * BITS_PER_BYTE)
+
 #define BIT_MASK(nr)   (UL(1) << ((nr) % BITS_PER_LONG))
 #define BIT_WORD(nr)   ((nr) / BITS_PER_LONG)
 #define BIT_ULL_MASK(nr)   (ULL(1) << ((nr) % BITS_PER_LONG_LONG))
@@ -30,16 +32,26 @@
 #define GENMASK_INPUT_CHECK(h, l) 0
 #endif
 
-#define __GENMASK(h, l) \
-   (((~UL(0)) - (UL(1) << (l)) + 1) & \
-(~UL(0) >> (BITS_PER_LONG - 1 - (h
-#define GENMASK(h, l) \
-   (GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
+/*
+ * Generate a mask for the specified type @t. Additional checks are made to
+ * guarantee the value returned fits in that type, relying on
+ * shift-count-overflow compiler check to detect incompatible arguments.
+ * For example, all these create build errors or warnings:
+ *
+ * - GENMASK(15, 20): wrong argument order
+ * - GENMASK(72, 15): doesn't fit unsigned long
+ * - GENMASK_U32(33, 15): doesn't fit in a u32
+ */
+#define __GENMASK(t, h, l) \
+   (GENMASK_INPUT_CHECK(h, l) + \
+(((t)~0ULL - ((t)(1) << (l)) + 1) & \
+((t)~0ULL >> (BITS_PER_TYPE(t) - 1 - (h)
 
-#define __GENMASK_ULL(h, l) \
-   (((~ULL(0)) - (ULL(1) << (l)) + 1) & \
-(~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h
-#define GENMASK_ULL(h, l) \
-   (GENMASK_INPUT_CHECK(h, l) + __GENMASK_ULL(h, l))
+#define GENMASK(h, l)  __GENMASK(unsigned long,  h, l)
+#define GENMASK_ULL(h, l)  __GENMASK(unsigned long long, h, l)
+#define GENMASK_U8(h, l)   __GENMASK(u8,  h, l)
+#define GENMASK_U16(h, l)  __GENMASK(u16, h, l)
+#define GENMASK_U32(h, l)  __GENMASK(u32, h, l)
+#define GENMASK_U64(h, l)  __GENMASK(u64, h, l)
 
 #endif /* __LINUX_BITS_H */
-- 
2.43.0



[PATCH v3 0/3] Fixed-type GENMASK/BIT

2024-02-07 Thread Lucas De Marchi
ove the implementation of REG_GENMASK/REG_BIT to a more appropriate
place to be shared by i915, xe and possibly other parts of the kernel.

For now this re-defines the old macros. In future we may start using the
new macros directly, but that's a more intrusive search-and-replace.

Changes from v2:

- Document both in commit message and code about the strict type
  checking and give examples how it´d break with invalid params.

v1: 
https://lore.kernel.org/intel-xe/20230509051403.2748545-1-lucas.demar...@intel.com/
v2: 
https://lore.kernel.org/intel-xe/20240124050205.3646390-1-lucas.demar...@intel.com

Lucas De Marchi (2):
  bits: Introduce fixed-type BIT
  drm/i915: Convert REG_GENMASK* to fixed-width GENMASK_*

Yury Norov (1):
  bits: introduce fixed-type genmasks

 drivers/gpu/drm/i915/i915_reg_defs.h | 108 +++
 include/linux/bitops.h   |   1 -
 include/linux/bits.h |  51 ++---
 3 files changed, 51 insertions(+), 109 deletions(-)

-- 
2.43.0



[PATCH v3 2/3] bits: Introduce fixed-type BIT

2024-02-07 Thread Lucas De Marchi
Implement fixed-type BIT() to help drivers add stricter checks, like was
done for GENMASK.

Signed-off-by: Lucas De Marchi 
Acked-by: Jani Nikula 
---
 include/linux/bits.h | 17 +
 1 file changed, 17 insertions(+)

diff --git a/include/linux/bits.h b/include/linux/bits.h
index bd56f32de44e..811846ce110e 100644
--- a/include/linux/bits.h
+++ b/include/linux/bits.h
@@ -24,12 +24,16 @@
 #define GENMASK_INPUT_CHECK(h, l) \
(BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
__is_constexpr((l) > (h)), (l) > (h), 0)))
+#define BIT_INPUT_CHECK(type, b) \
+   ((BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
+   __is_constexpr(b), (b) >= BITS_PER_TYPE(type), 0
 #else
 /*
  * BUILD_BUG_ON_ZERO is not available in h files included from asm files,
  * disable the input check if that is the case.
  */
 #define GENMASK_INPUT_CHECK(h, l) 0
+#define BIT_INPUT_CHECK(type, b) 0
 #endif
 
 /*
@@ -54,4 +58,17 @@
 #define GENMASK_U32(h, l)  __GENMASK(u32, h, l)
 #define GENMASK_U64(h, l)  __GENMASK(u64, h, l)
 
+/*
+ * Fixed-type variants of BIT(), with additional checks like __GENMASK().  The
+ * following examples generate compiler warnings due to shift-count-overflow:
+ *
+ * - BIT_U8(8)
+ * - BIT_U32(-1)
+ * - BIT_U32(40)
+ */
+#define BIT_U8(b)  ((u8)(BIT_INPUT_CHECK(u8, b) + BIT(b)))
+#define BIT_U16(b) ((u16)(BIT_INPUT_CHECK(u16, b) + BIT(b)))
+#define BIT_U32(b) ((u32)(BIT_INPUT_CHECK(u32, b) + BIT(b)))
+#define BIT_U64(b) ((u64)(BIT_INPUT_CHECK(u64, b) + BIT(b)))
+
 #endif /* __LINUX_BITS_H */
-- 
2.43.0



Re: [PATCH] drm/buddy: Fix alloc_range() error handling code

2024-02-07 Thread Christian König

Am 07.02.24 um 18:44 schrieb Arunpravin Paneer Selvam:

Few users have observed display corruption when they boot
the machine to KDE Plasma or playing games. We have root
caused the problem that whenever alloc_range() couldn't
find the required memory blocks the function was returning
SUCCESS in some of the corner cases.

The right approach would be if the total allocated size
is less than the required size, the function should
return -ENOSPC.

Gitlab ticket link - https://gitlab.freedesktop.org/drm/amd/-/issues/3097
Fixes: 0a1844bf0b53 ("drm/buddy: Improve contiguous memory allocation")
Signed-off-by: Arunpravin Paneer Selvam 
Tested-by: Mario Limonciello 


Acked-by: Christian König 

CC: stable.. ?


---
  drivers/gpu/drm/drm_buddy.c | 6 ++
  1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/drm_buddy.c b/drivers/gpu/drm/drm_buddy.c
index f57e6d74fb0e..c1a99bf4dffd 100644
--- a/drivers/gpu/drm/drm_buddy.c
+++ b/drivers/gpu/drm/drm_buddy.c
@@ -539,6 +539,12 @@ static int __alloc_range(struct drm_buddy *mm,
} while (1);
  
  	list_splice_tail(, blocks);

+
+   if (total_allocated < size) {
+   err = -ENOSPC;
+   goto err_free;
+   }
+
return 0;
  
  err_undo:




Re: xe vs amdgpu userptr handling

2024-02-07 Thread Christian König

Am 08.02.24 um 01:36 schrieb Dave Airlie:

Just cc'ing some folks. I've also added another question.

On Wed, 7 Feb 2024 at 21:08, Maíra Canal  wrote:

Adding another point to this discussion, would it make sense to somehow
create a generic structure that all drivers, including shmem drivers,
could use it?

Best Regards,
- Maíra

On 2/7/24 03:56, Dave Airlie wrote:

I'm just looking over the userptr handling in both drivers, and of
course they've chosen different ways to represent things. Again this
is a divergence that is just going to get more annoying over time and
eventually I'd like to make hmm/userptr driver independent as much as
possible, so we get consistent semantics in userspace.

AFAICS the main difference is that amdgpu builds the userptr handling
inside a GEM object in the kernel, whereas xe doesn't bother creating
a holding object and just handles things directly in the VM binding
code.

Is this just different thinking at different times here?
like since we have VM BIND in xe, it made sense not to bother creating
a gem object for userptrs?
or is there some other advantages to going one way or the other?


So the current AMD code uses hmm to do userptr work, but xe doesn't
again, why isn't xe using hmm here, I thought I remembered scenarios
where plain mmu_notifiers weren't sufficient.


Well amdgpu is using hmm_range_fault because that was made mandatory for 
the userptr handling.


And yes pure mmu_notifiers are not sufficient, you need the sequence 
number + retry mechanism hmm_range_fault provides.


Otherwise you open up security holes you can push an elephant through.

Regards,
Christian.



Dave.




Re: [PATCH] drm/etnaviv: fix DMA direction handling for cached read/write buffers

2024-02-07 Thread Sui Jingfeng

Hi,


On 2024/1/29 18:29, Daniel Stone wrote:

Hi Lucas,

On Fri, 26 Jan 2024 at 17:00, Lucas Stach  wrote:

The dma sync operation needs to be done with DMA_BIDIRECTIONAL when
the BO is prepared for both read and write operations. With the
current inverted if ladder it would only be synced for DMA_FROM_DEVICE.

[...]

  static inline enum dma_data_direction etnaviv_op_to_dma_dir(u32 op)
  {
-   if (op & ETNA_PREP_READ)
+   if (op & (ETNA_PREP_READ | ETNA_PREP_WRITE))
+   return DMA_BIDIRECTIONAL;

This test will always be true for _either_ read or write.



Haha, I think it should be"if ((op & ETNA_PREP_READ) && (op & ETNA_PREP_WRITE))"



Cheers,
Daniel


Re: [PATCH 2/2] xfs: disable large folio support in xfile_create

2024-02-07 Thread Andrew Morton
On Thu, 11 Jan 2024 18:22:50 -0800 "Darrick J. Wong"  wrote:

> On Thu, Jan 11, 2024 at 10:45:53PM +, Matthew Wilcox wrote:
> > On Thu, Jan 11, 2024 at 02:00:53PM -0800, Andrew Morton wrote:
> > > On Wed, 10 Jan 2024 12:04:51 -0800 "Darrick J. Wong"  
> > > wrote:
> > > 
> > > > > > Fixing this will require a bit of an API change, and prefeably 
> > > > > > sorting out
> > > > > > the hwpoison story for pages vs folio and where it is placed in the 
> > > > > > shmem
> > > > > > API.  For now use this one liner to disable large folios.
> > > > > > 
> > > > > > Reported-by: Darrick J. Wong 
> > > > > > Signed-off-by: Christoph Hellwig 
> > > > > 
> > > > > Can someone who knows more about shmem.c than I do please review
> > > > > https://lore.kernel.org/linux-xfs/20240103084126.513354-4-...@lst.de/
> > > > > so that I can feel slightly more confident as hch and I sort through 
> > > > > the
> > > > > xfile.c issues?
> > > > > 
> > > > > For this patch,
> > > > > Reviewed-by: Darrick J. Wong 
> > > > 
> > > > ...except that I'm still getting 2M THPs even with this enabled, so I
> > > > guess either we get to fix it now, or create our own private tmpfs mount
> > > > so that we can pass in huge=never, similar to what i915 does. :(
> > > 
> > > What is "this"?  Are you saying that $Subject doesn't work, or that the
> > > above-linked please-review patch doesn't work?
> > 
> > shmem pays no attention to the mapping_large_folio_support() flag,
> > so the proposed fix doesn't work.  It ought to, but it has its own way
> > of doing it that predates mapping_large_folio_support existing.
> 
> Yep.  It turned out to be easier to fix xfile.c to deal with large
> folios than I thought it would be.  Or so I think.  We'll see what
> happens on fstestscloud overnight.

Where do we stand with this?  Should I merge these two patches into
6.8-rcX, cc:stable?



Re: [PATCH v2 2/2] fbcon: Defer console takeover for splash screens to first switch

2024-02-07 Thread Daniel van Vugt
On 8/2/24 04:21, Mario Limonciello wrote:
> On 2/7/2024 03:51, Daniel Vetter wrote:
>> On Wed, Feb 07, 2024 at 10:03:10AM +0800, Daniel van Vugt wrote:
>>> On 6/2/24 23:41, Mario Limonciello wrote:
 On 2/6/2024 08:21, Daniel Vetter wrote:
> On Tue, Feb 06, 2024 at 06:10:51PM +0800, Daniel van Vugt wrote:
>> Until now, deferred console takeover only meant defer until there is
>> output. But that risks stepping on the toes of userspace splash screens,
>> as console messages may appear before the splash screen. So check the
>> command line for the expectation of userspace splash and if present then
>> extend the deferral until after the first switch.
>>
>> V2: Added Kconfig option instead of hard coding "splash".
>>
>> Closes: https://bugs.launchpad.net/bugs/1970069
>> Cc: Mario Limonciello 
>> Signed-off-by: Daniel van Vugt 
>> ---
>>    drivers/video/console/Kconfig    | 13 +++
>>    drivers/video/fbdev/core/fbcon.c | 38 ++--
>>    2 files changed, 49 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/video/console/Kconfig 
>> b/drivers/video/console/Kconfig
>> index bc31db6ef7..a6e371bfb4 100644
>> --- a/drivers/video/console/Kconfig
>> +++ b/drivers/video/console/Kconfig
>> @@ -138,6 +138,19 @@ config FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER
>>  by the firmware in place, rather then replacing the contents 
>> with a
>>  black screen as soon as fbcon loads.
>>    +config FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER_CONDITION
>> +    string "Framebuffer Console Deferred Takeover Condition"
>> +    depends on FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER
>> +    default "splash"
>> +    help
>> +  If enabled this defers further the framebuffer console taking over
>> +  until the first console switch has occurred. And even then only if
>> +  text has been output, and only if the specified parameter is found
>> +  on the command line. This ensures fbcon does not interrupt 
>> userspace
>> +  splash screens such as Plymouth which may be yet to start 
>> rendering
>> +  at the time of the first console output. "splash" is the simplest
>> +  distro-agnostic condition for this that Plymouth checks for.
>
> Hm this seems a bit strange since a lot of complexity that no one needs,
> also my impression is that it's rather distro specific how you want this
> to work. So why not just a Kconfig option that lets you choose how much
> you want to delay fbcon setup, with the following options:
>
> - no delay at all
> - dely until first output from the console (which then works for distros
>     which set a log-level to suppress unwanted stuff)
> - delay until first vt-switch. In that case I don't think we also need to
>     delay for first output, since vt switch usually means you'll get first
>     output right away (if it's a vt terminal) or you switch to a different
>     graphical console (which will keep fbcon fully suppressed on the drm
>     side).
>
>>>
>>> I had similar thoughts, and had prototyped some of this already. But in the 
>>> end
>>> it felt like extra complexity there was no demand for.
>>
>> For me this one is a bit too complex, since if you enable the vt switch
>> delay you also get the output delay on top. That seems one too much and I
>> can't come up with a use-case where you actually want that. So just a
>> choice of one or the other or none feels cleaner.

Remember the output "delay" goes to zero if any putc has occurred prior to
registration (see dummycon.c).

My current reason for using both is that in theory it prevents fbcon from
taking over *earlier* than it did before, in case there was never any output.
But I don't think there is "never any output" by the time you've tried to
manually VT switch so maybe that's unnecessary.

>>
>>> If you would like to specify the preferred Kconfig design then I can 
>>> implement
>>> it. Though I don't think there is an enumeration type. It could also be a
>>> runtime enumeration (deferred_takeover) controlled by fbcon=something.
>>
>> There's a choice in Kconfig, see e.g. kernel/Kconfig.hz for an example.

Thanks!

>>
 IIUC there is an "automatic" VT switch that happens with Ubuntu GRUB + 
 Ubuntu
 kernels.

 Why?

 Couldn't this also be suppressed by just not doing that?
>>>
>>> I have not seen any automatic VT switches in debugging but now that you 
>>> mention
>>> it I was probably only debugging on drm-misc-next and not an Ubuntu kernel.
>>
>> Hm but I don't see how the output delay would paper over a race (if there
>> is one) reliable for this case? If you do vt switch for boot splash or
>> login screen and don't yet have drm opened for display or something like
>> that, then fbcon can sneak in anyway ...

There is no VT switch 

Re: xe vs amdgpu userptr handling

2024-02-07 Thread Dave Airlie
Just cc'ing some folks. I've also added another question.

On Wed, 7 Feb 2024 at 21:08, Maíra Canal  wrote:
>
> Adding another point to this discussion, would it make sense to somehow
> create a generic structure that all drivers, including shmem drivers,
> could use it?
>
> Best Regards,
> - Maíra
>
> On 2/7/24 03:56, Dave Airlie wrote:
> > I'm just looking over the userptr handling in both drivers, and of
> > course they've chosen different ways to represent things. Again this
> > is a divergence that is just going to get more annoying over time and
> > eventually I'd like to make hmm/userptr driver independent as much as
> > possible, so we get consistent semantics in userspace.
> >
> > AFAICS the main difference is that amdgpu builds the userptr handling
> > inside a GEM object in the kernel, whereas xe doesn't bother creating
> > a holding object and just handles things directly in the VM binding
> > code.
> >
> > Is this just different thinking at different times here?
> > like since we have VM BIND in xe, it made sense not to bother creating
> > a gem object for userptrs?
> > or is there some other advantages to going one way or the other?
> >

So the current AMD code uses hmm to do userptr work, but xe doesn't
again, why isn't xe using hmm here, I thought I remembered scenarios
where plain mmu_notifiers weren't sufficient.

Dave.


[PATCH v4 3/3] drm: Drop unneeded selects in DRM drivers

2024-02-07 Thread Mario Limonciello
All of the selects on ACPI_VIDEO are unnecessary when DRM does the
select for ACPI_VIDEO as it provides a helper for acpi based EDID.

Reviewed-by: Pranjal Ramajor Asha Kanojiya 
Signed-off-by: Mario Limonciello 
---
 drivers/gpu/drm/amd/amdgpu/Kconfig | 7 ---
 drivers/gpu/drm/gma500/Kconfig | 6 --
 drivers/gpu/drm/i915/Kconfig   | 7 ---
 drivers/gpu/drm/nouveau/Kconfig| 4 
 drivers/gpu/drm/radeon/Kconfig | 7 ---
 drivers/gpu/drm/xe/Kconfig | 6 --
 6 files changed, 37 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/Kconfig 
b/drivers/gpu/drm/amd/amdgpu/Kconfig
index 22d88f8ef527..b2178a5a947c 100644
--- a/drivers/gpu/drm/amd/amdgpu/Kconfig
+++ b/drivers/gpu/drm/amd/amdgpu/Kconfig
@@ -22,13 +22,6 @@ config DRM_AMDGPU
select DRM_BUDDY
select DRM_SUBALLOC_HELPER
select DRM_EXEC
-   # amdgpu depends on ACPI_VIDEO when ACPI is enabled, for select to work
-   # ACPI_VIDEO's dependencies must also be selected.
-   select INPUT if ACPI
-   select ACPI_VIDEO if ACPI
-   # On x86 ACPI_VIDEO also needs ACPI_WMI
-   select X86_PLATFORM_DEVICES if ACPI && X86
-   select ACPI_WMI if ACPI && X86
help
  Choose this option if you have a recent AMD Radeon graphics card.
 
diff --git a/drivers/gpu/drm/gma500/Kconfig b/drivers/gpu/drm/gma500/Kconfig
index efb4a2dd2f80..6921ef67b256 100644
--- a/drivers/gpu/drm/gma500/Kconfig
+++ b/drivers/gpu/drm/gma500/Kconfig
@@ -6,12 +6,6 @@ config DRM_GMA500
select FB_IOMEM_HELPERS if DRM_FBDEV_EMULATION
select I2C
select I2C_ALGOBIT
-   # GMA500 depends on ACPI_VIDEO when ACPI is enabled, just like i915
-   select ACPI_VIDEO if ACPI
-   select BACKLIGHT_CLASS_DEVICE if ACPI
-   select INPUT if ACPI
-   select X86_PLATFORM_DEVICES if ACPI
-   select ACPI_WMI if ACPI
help
  Say yes for an experimental 2D KMS framebuffer driver for the
  Intel GMA500 (Poulsbo), Intel GMA600 (Moorestown/Oak Trail) and
diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index b5d6e3352071..476da09433bb 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -22,13 +22,6 @@ config DRM_I915
select I2C
select I2C_ALGOBIT
select IRQ_WORK
-   # i915 depends on ACPI_VIDEO when ACPI is enabled
-   # but for select to work, need to select ACPI_VIDEO's dependencies, ick
-   select BACKLIGHT_CLASS_DEVICE if ACPI
-   select INPUT if ACPI
-   select X86_PLATFORM_DEVICES if ACPI
-   select ACPI_WMI if ACPI
-   select ACPI_VIDEO if ACPI
select ACPI_BUTTON if ACPI
select SYNC_FILE
select IOSF_MBI if X86
diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig
index 1e6aaf95ff7c..61f531abd3e3 100644
--- a/drivers/gpu/drm/nouveau/Kconfig
+++ b/drivers/gpu/drm/nouveau/Kconfig
@@ -20,11 +20,7 @@ config DRM_NOUVEAU
select ACPI_WMI if ACPI && X86
select MXM_WMI if ACPI && X86
select POWER_SUPPLY
-   # Similar to i915, we need to select ACPI_VIDEO and it's dependencies
-   select BACKLIGHT_CLASS_DEVICE if ACPI && X86
-   select INPUT if ACPI && X86
select THERMAL if ACPI && X86
-   select ACPI_VIDEO if ACPI && X86
select SND_HDA_COMPONENT if SND_HDA_CORE
help
  Choose this option for open-source NVIDIA support.
diff --git a/drivers/gpu/drm/radeon/Kconfig b/drivers/gpu/drm/radeon/Kconfig
index f98356be0af2..12149d594100 100644
--- a/drivers/gpu/drm/radeon/Kconfig
+++ b/drivers/gpu/drm/radeon/Kconfig
@@ -19,13 +19,6 @@ config DRM_RADEON
select INTERVAL_TREE
select I2C
select I2C_ALGOBIT
-   # radeon depends on ACPI_VIDEO when ACPI is enabled, for select to work
-   # ACPI_VIDEO's dependencies must also be selected.
-   select INPUT if ACPI
-   select ACPI_VIDEO if ACPI
-   # On x86 ACPI_VIDEO also needs ACPI_WMI
-   select X86_PLATFORM_DEVICES if ACPI && X86
-   select ACPI_WMI if ACPI && X86
help
  Choose this option if you have an ATI Radeon graphics card.  There
  are both PCI and AGP versions.  You don't need to choose this to
diff --git a/drivers/gpu/drm/xe/Kconfig b/drivers/gpu/drm/xe/Kconfig
index e36ae1f0d885..cf60bdcafb0c 100644
--- a/drivers/gpu/drm/xe/Kconfig
+++ b/drivers/gpu/drm/xe/Kconfig
@@ -19,13 +19,7 @@ config DRM_XE
select DRM_MIPI_DSI
select RELAY
select IRQ_WORK
-   # xe depends on ACPI_VIDEO when ACPI is enabled
-   # but for select to work, need to select ACPI_VIDEO's dependencies, ick
-   select BACKLIGHT_CLASS_DEVICE if ACPI
-   select INPUT if ACPI
-   select ACPI_VIDEO if X86 && ACPI
select ACPI_BUTTON if ACPI
-   select ACPI_WMI if X86 && ACPI
select SYNC_FILE
select IOSF_MBI
select CRC32
-- 
2.34.1



[PATCH v4 1/3] drm: Add drm_get_acpi_edid() helper

2024-02-07 Thread Mario Limonciello
Some manufacturers have intentionally put an EDID that differs from
the EDID on the internal panel on laptops.  Drivers can call this
helper to attempt to fetch the EDID from the BIOS's ACPI _DDC method.

Signed-off-by: Mario Limonciello 
---
 drivers/gpu/drm/Kconfig|  5 +++
 drivers/gpu/drm/drm_edid.c | 77 ++
 include/drm/drm_edid.h |  1 +
 3 files changed, 83 insertions(+)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 6ec33d36f3a4..ec2bb71e8b36 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -21,6 +21,11 @@ menuconfig DRM
select KCMP
select VIDEO_CMDLINE
select VIDEO_NOMODESET
+   select ACPI_VIDEO if ACPI
+   select BACKLIGHT_CLASS_DEVICE if ACPI
+   select INPUT if ACPI
+   select X86_PLATFORM_DEVICES if ACPI && X86
+   select ACPI_WMI if ACPI && X86
help
  Kernel-level support for the Direct Rendering Infrastructure (DRI)
  introduced in XFree86 4.0. If you say Y here, you need to select
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 923c4423151c..c649b4f9fd8e 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -28,6 +28,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -2188,6 +2189,49 @@ drm_do_probe_ddc_edid(void *data, u8 *buf, unsigned int 
block, size_t len)
return ret == xfers ? 0 : -1;
 }
 
+/**
+ * drm_do_probe_acpi_edid() - get EDID information via ACPI _DDC
+ * @data: struct drm_device
+ * @buf: EDID data buffer to be filled
+ * @block: 128 byte EDID block to start fetching from
+ * @len: EDID data buffer length to fetch
+ *
+ * Try to fetch EDID information by calling acpi_video_get_edid() function.
+ *
+ * Return: 0 on success or error code on failure.
+ */
+static int
+drm_do_probe_acpi_edid(void *data, u8 *buf, unsigned int block, size_t len)
+{
+   struct drm_device *ddev = data;
+   struct acpi_device *acpidev = ACPI_COMPANION(ddev->dev);
+   unsigned char start = block * EDID_LENGTH;
+   void *edid;
+   int r;
+
+   if (!acpidev)
+   return -ENODEV;
+
+   /* fetch the entire edid from BIOS */
+   r = acpi_video_get_edid(acpidev, ACPI_VIDEO_DISPLAY_LCD, -1, );
+   if (r < 0) {
+   DRM_DEBUG_KMS("Failed to get EDID from ACPI: %d\n", r);
+   return -EINVAL;
+   }
+   if (len > r || start > r || start + len > r) {
+   r = -EINVAL;
+   goto cleanup;
+   }
+
+   memcpy(buf, edid + start, len);
+   r = 0;
+
+cleanup:
+   kfree(edid);
+
+   return r;
+}
+
 static void connector_bad_edid(struct drm_connector *connector,
   const struct edid *edid, int num_blocks)
 {
@@ -2643,6 +2687,39 @@ struct edid *drm_get_edid(struct drm_connector 
*connector,
 }
 EXPORT_SYMBOL(drm_get_edid);
 
+/**
+ * drm_get_acpi_edid - get EDID data, if available
+ * @connector: connector we're probing
+ *
+ * Use the BIOS to attempt to grab EDID data if possible.
+ *
+ * The returned pointer must be freed using drm_edid_free().
+ *
+ * Return: Pointer to valid EDID or NULL if we couldn't find any.
+ */
+const struct drm_edid *drm_get_acpi_edid(struct drm_connector *connector)
+{
+   const struct drm_edid *drm_edid;
+
+   switch (connector->connector_type) {
+   case DRM_MODE_CONNECTOR_LVDS:
+   case DRM_MODE_CONNECTOR_eDP:
+   break;
+   default:
+   return NULL;
+   }
+
+   if (connector->force == DRM_FORCE_OFF)
+   return NULL;
+
+   drm_edid = drm_edid_read_custom(connector, drm_do_probe_acpi_edid, 
connector->dev);
+
+   /* Note: Do *not* call connector updates here. */
+
+   return drm_edid;
+}
+EXPORT_SYMBOL(drm_get_acpi_edid);
+
 /**
  * drm_edid_read_custom - Read EDID data using given EDID block read function
  * @connector: Connector to use
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index 7923bc00dc7a..ca41be289fc6 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -410,6 +410,7 @@ struct edid *drm_do_get_edid(struct drm_connector 
*connector,
void *data);
 struct edid *drm_get_edid(struct drm_connector *connector,
  struct i2c_adapter *adapter);
+const struct drm_edid *drm_get_acpi_edid(struct drm_connector *connector);
 u32 drm_edid_get_panel_id(struct i2c_adapter *adapter);
 struct edid *drm_get_edid_switcheroo(struct drm_connector *connector,
 struct i2c_adapter *adapter);
-- 
2.34.1



[PATCH v4 2/3] drm/nouveau: Use drm_get_acpi_edid() helper

2024-02-07 Thread Mario Limonciello
Rather than inventing a wrapper to acpi_video_get_edid() use the
one provided by drm. This fixes two problems:
1. A memory leak that the memory provided by the ACPI call was
   never freed.
2. Validation of the BIOS provided blob.

Convert the usage in nouveau_connector_detect_lvds() to use
struct drm_edid at the same time.

Signed-off-by: Mario Limonciello 
---
 drivers/gpu/drm/nouveau/nouveau_acpi.c  | 27 -
 drivers/gpu/drm/nouveau/nouveau_acpi.h  |  2 --
 drivers/gpu/drm/nouveau/nouveau_connector.c | 20 +++
 3 files changed, 9 insertions(+), 40 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c 
b/drivers/gpu/drm/nouveau/nouveau_acpi.c
index 8f0c69aad248..de9daafb3fbb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
@@ -360,33 +360,6 @@ void nouveau_unregister_dsm_handler(void) {}
 void nouveau_switcheroo_optimus_dsm(void) {}
 #endif
 
-void *
-nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector)
-{
-   struct acpi_device *acpidev;
-   int type, ret;
-   void *edid;
-
-   switch (connector->connector_type) {
-   case DRM_MODE_CONNECTOR_LVDS:
-   case DRM_MODE_CONNECTOR_eDP:
-   type = ACPI_VIDEO_DISPLAY_LCD;
-   break;
-   default:
-   return NULL;
-   }
-
-   acpidev = ACPI_COMPANION(dev->dev);
-   if (!acpidev)
-   return NULL;
-
-   ret = acpi_video_get_edid(acpidev, type, -1, );
-   if (ret < 0)
-   return NULL;
-
-   return kmemdup(edid, EDID_LENGTH, GFP_KERNEL);
-}
-
 bool nouveau_acpi_video_backlight_use_native(void)
 {
return acpi_video_backlight_use_native();
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.h 
b/drivers/gpu/drm/nouveau/nouveau_acpi.h
index e39dd8b94b8b..6a3def8e6cca 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.h
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.h
@@ -10,7 +10,6 @@ bool nouveau_is_v1_dsm(void);
 void nouveau_register_dsm_handler(void);
 void nouveau_unregister_dsm_handler(void);
 void nouveau_switcheroo_optimus_dsm(void);
-void *nouveau_acpi_edid(struct drm_device *, struct drm_connector *);
 bool nouveau_acpi_video_backlight_use_native(void);
 void nouveau_acpi_video_register_backlight(void);
 #else
@@ -19,7 +18,6 @@ static inline bool nouveau_is_v1_dsm(void) { return false; };
 static inline void nouveau_register_dsm_handler(void) {}
 static inline void nouveau_unregister_dsm_handler(void) {}
 static inline void nouveau_switcheroo_optimus_dsm(void) {}
-static inline void *nouveau_acpi_edid(struct drm_device *dev, struct 
drm_connector *connector) { return NULL; }
 static inline bool nouveau_acpi_video_backlight_use_native(void) { return 
true; }
 static inline void nouveau_acpi_video_register_backlight(void) {}
 #endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c 
b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 856b3ef5edb8..4c47d231c65e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -687,7 +687,7 @@ nouveau_connector_detect_lvds(struct drm_connector 
*connector, bool force)
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_connector *nv_connector = nouveau_connector(connector);
struct nouveau_encoder *nv_encoder = NULL;
-   struct edid *edid = NULL;
+   const struct drm_edid *drm_edid = NULL;
enum drm_connector_status status = connector_status_disconnected;
 
nv_encoder = find_encoder(connector, DCB_OUTPUT_LVDS);
@@ -698,7 +698,7 @@ nouveau_connector_detect_lvds(struct drm_connector 
*connector, bool force)
if (!drm->vbios.fp_no_ddc) {
status = nouveau_connector_detect(connector, force);
if (status == connector_status_connected) {
-   edid = nv_connector->edid;
+   drm_edid = drm_edid_alloc(nv_connector->edid, 
EDID_LENGTH);
goto out;
}
}
@@ -713,8 +713,8 @@ nouveau_connector_detect_lvds(struct drm_connector 
*connector, bool force)
 * valid - it's not (rh#613284)
 */
if (nv_encoder->dcb->lvdsconf.use_acpi_for_edid) {
-   edid = nouveau_acpi_edid(dev, connector);
-   if (edid) {
+   drm_edid = drm_get_acpi_edid(connector);
+   if (drm_edid) {
status = connector_status_connected;
goto out;
}
@@ -734,12 +734,9 @@ nouveau_connector_detect_lvds(struct drm_connector 
*connector, bool force)
 * stored for the panel stored in them.
 */
if (!drm->vbios.fp_no_ddc) {
-   edid = (struct edid *)nouveau_bios_embedded_edid(dev);
-   if (edid) {
-   edid = kmemdup(edid, EDID_LENGTH, GFP_KERNEL);
-   if (edid)
-   status = 

[PATCH v4 0/3] Add drm_get_acpi_edid() helper

2024-02-07 Thread Mario Limonciello
The drm_get_acpi_edid() helper is for drivers that would prefer
to get the EDID from ACPI instead of from the panel.

Earlier versions of this series were aimed at using this in amdgpu
and nouveau.

This version does NOT update amdgpu as the change will require a
larger overhaul to use struct drm_edid. There will be a follow up
patch to amdgpu after Melissa Wen finishes that effort [2].

https://lore.kernel.org/dri-devel/20240201221119.42564-1-mario.limoncie...@amd.com/
 [1]
https://lore.kernel.org/amd-gfx/20240126163429.56714-1-m...@igalia.com/ [2]
Mario Limonciello (3):
  drm: Add drm_get_acpi_edid() helper
  drm/nouveau: Use drm_get_acpi_edid() helper
  drm: Drop unneeded selects in DRM drivers

 drivers/gpu/drm/Kconfig |  5 ++
 drivers/gpu/drm/amd/amdgpu/Kconfig  |  7 --
 drivers/gpu/drm/drm_edid.c  | 77 +
 drivers/gpu/drm/gma500/Kconfig  |  6 --
 drivers/gpu/drm/i915/Kconfig|  7 --
 drivers/gpu/drm/nouveau/Kconfig |  4 --
 drivers/gpu/drm/nouveau/nouveau_acpi.c  | 27 
 drivers/gpu/drm/nouveau/nouveau_acpi.h  |  2 -
 drivers/gpu/drm/nouveau/nouveau_connector.c | 20 +++---
 drivers/gpu/drm/radeon/Kconfig  |  7 --
 drivers/gpu/drm/xe/Kconfig  |  6 --
 include/drm/drm_edid.h  |  1 +
 12 files changed, 92 insertions(+), 77 deletions(-)

-- 
2.34.1



Re: [PATCH 02/19] drm/dp: Add support for DP tunneling

2024-02-07 Thread Imre Deak
On Wed, Feb 07, 2024 at 10:48:43PM +0200, Imre Deak wrote:
> On Wed, Feb 07, 2024 at 10:02:18PM +0200, Ville Syrjälä wrote:
> > On Tue, Jan 23, 2024 at 12:28:33PM +0200, Imre Deak wrote:
> > > + [...]
> > > +static int group_allocated_bw(struct drm_dp_tunnel_group *group)
> > > +{
> > > + struct drm_dp_tunnel *tunnel;
> > > + int group_allocated_bw = 0;
> > > +
> > > + for_each_tunnel_in_group(group, tunnel) {
> > > + if (check_tunnel(tunnel) == 0 &&
> > > + tunnel->bw_alloc_enabled)
> > > + group_allocated_bw += tunnel->allocated_bw;
> > > + }
> > > +
> > > + return group_allocated_bw;
> > > +}
> > > +
> > > +static int calc_group_available_bw(const struct drm_dp_tunnel *tunnel)
> > > +{
> > > + return group_allocated_bw(tunnel->group) -
> > > +tunnel->allocated_bw +
> > > +tunnel->estimated_bw;
> > 
> > Hmm. So the estimated_bw=actually_free_bw + tunnel->allocated_bw?
> 
> Yes.
> 
> > Ie. how much bw might be available for this tunnel right now?
> 
> Correct.
> 
> > And here we're trying to deduce the total bandwidth available by
> > adding in the allocated_bw of all the other tunnels in the group?
> 
> Yes.
> 
> > Rather weird that we can't just get that number directly...
> 
> It is. Imo this could be simply communicated via a DPCD register
> dedicated for this. Perhaps adding this should be requested from TBT
> architects.

One reason for this design can be that a host/driver may not see all the
tunnels in the group. In that case the tunnel's current usable BW will
be only its estimated_bw (that is it can't use the BW already allocated
by other tunnels in the group, until those are released by the other
host/driver).

> I assume this could also use a code comment.
> 
> > > +}
> > > +
> > > +static int update_group_available_bw(struct drm_dp_tunnel *tunnel,
> > > +  const struct drm_dp_tunnel_regs *regs)
> > > +{
> > > + struct drm_dp_tunnel *tunnel_iter;
> > > + int group_available_bw;
> > > + bool changed;
> > > +
> > > + tunnel->estimated_bw = tunnel_reg(regs, DP_ESTIMATED_BW) * 
> > > tunnel->bw_granularity;
> > > +
> > > + if (calc_group_available_bw(tunnel) == tunnel->group->available_bw)
> > > + return 0;
> > > +
> > > + for_each_tunnel_in_group(tunnel->group, tunnel_iter) {
> > > + int err;
> > > +
> > > + if (tunnel_iter == tunnel)
> > > + continue;
> > > +
> > > + if (check_tunnel(tunnel_iter) != 0 ||
> > > + !tunnel_iter->bw_alloc_enabled)
> > > + continue;
> > > +
> > > + err = drm_dp_dpcd_probe(tunnel_iter->aux, DP_DPCD_REV);
> > > + if (err) {
> > > + tun_dbg(tunnel_iter,
> > > + "Probe failed, assume disconnected (err %pe)\n",
> > > + ERR_PTR(err));
> > > + drm_dp_tunnel_set_io_error(tunnel_iter);
> > > + }
> > > + }
> > > +
> > > + group_available_bw = calc_group_available_bw(tunnel);
> > > +
> > > + tun_dbg(tunnel, "Updated group available BW: %d->%d\n",
> > > + DPTUN_BW_ARG(tunnel->group->available_bw),
> > > + DPTUN_BW_ARG(group_available_bw));
> > > +
> > > + changed = tunnel->group->available_bw != group_available_bw;
> > > +
> > > + tunnel->group->available_bw = group_available_bw;
> > > +
> > > + return changed ? 1 : 0;
> > > +}
> > > +
> > > +static int set_bw_alloc_mode(struct drm_dp_tunnel *tunnel, bool enable)
> > > +{
> > > + u8 mask = DP_DISPLAY_DRIVER_BW_ALLOCATION_MODE_ENABLE | 
> > > DP_UNMASK_BW_ALLOCATION_IRQ;
> > > + u8 val;
> > > +
> > > + if (drm_dp_dpcd_readb(tunnel->aux, DP_DPTX_BW_ALLOCATION_MODE_CONTROL, 
> > > ) < 0)
> > > + goto out_err;
> > > +
> > > + if (enable)
> > > + val |= mask;
> > > + else
> > > + val &= ~mask;
> > > +
> > > + if (drm_dp_dpcd_writeb(tunnel->aux, DP_DPTX_BW_ALLOCATION_MODE_CONTROL, 
> > > val) < 0)
> > > + goto out_err;
> > > +
> > > + tunnel->bw_alloc_enabled = enable;
> > > +
> > > + return 0;
> > > +
> > > +out_err:
> > > + drm_dp_tunnel_set_io_error(tunnel);
> > > +
> > > + return -EIO;
> > > +}
> > > +
> > > +/**
> > > + * drm_dp_tunnel_enable_bw_alloc: Enable DP tunnel BW allocation mode
> > > + * @tunnel: Tunnel object
> > > + *
> > > + * Enable the DP tunnel BW allocation mode on @tunnel if it supports it.
> > > + *
> > > + * Returns 0 in case of success, negative error code otherwise.
> > > + */
> > > +int drm_dp_tunnel_enable_bw_alloc(struct drm_dp_tunnel *tunnel)
> > > +{
> > > + struct drm_dp_tunnel_regs regs;
> > > + int err = check_tunnel(tunnel);
> > > +
> > > + if (err)
> > > + return err;
> > > +
> > > + if (!tunnel->bw_alloc_supported)
> > > + return -EOPNOTSUPP;
> > > +
> > > + if (!tunnel_group_id(tunnel->group->drv_group_id))
> > > + return -EINVAL;
> > > +
> > > + err = set_bw_alloc_mode(tunnel, true);
> > > + if (err)
> > > + goto out;
> > > +
> > > + err = 

[PATCH AUTOSEL 6.1 16/29] drm/amd/display: increased min_dcfclk_mhz and min_fclk_mhz

2024-02-07 Thread Sasha Levin
From: Sohaib Nadeem 

[ Upstream commit 2ff33c759a4247c84ec0b7815f1f223e155ba82a ]

[why]
Originally, PMFW said min FCLK is 300Mhz, but min DCFCLK can be increased
to 400Mhz because min FCLK is now 600Mhz so FCLK >= 1.5 * DCFCLK hardware
requirement will still be satisfied. Increasing min DCFCLK addresses
underflow issues (underflow occurs when phantom pipe is turned on for some
Sub-Viewport configs).

[how]
Increasing DCFCLK by raising the min_dcfclk_mhz

Reviewed-by: Chaitanya Dhere 
Reviewed-by: Alvin Lee 
Acked-by: Tom Chung 
Signed-off-by: Sohaib Nadeem 
Tested-by: Daniel Wheeler 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
index 85e0d1c2a908..baecc0ffe758 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
@@ -2123,7 +2123,7 @@ static int build_synthetic_soc_states(struct 
clk_bw_params *bw_params,
unsigned int max_dcfclk_mhz = 0, max_dispclk_mhz = 0, max_dppclk_mhz = 
0,
max_phyclk_mhz = 0, max_dtbclk_mhz = 0, max_fclk_mhz = 
0, max_uclk_mhz = 0;
 
-   unsigned int min_dcfclk_mhz = 199, min_fclk_mhz = 299;
+   unsigned int min_dcfclk_mhz = 399, min_fclk_mhz = 599;
 
static const unsigned int num_dcfclk_stas = 5;
unsigned int dcfclk_sta_targets[DC__VOLTAGE_STATES] = {199, 615, 906, 
1324, 1564};
-- 
2.43.0



[PATCH AUTOSEL 6.6 23/38] drm/amd/display: increased min_dcfclk_mhz and min_fclk_mhz

2024-02-07 Thread Sasha Levin
From: Sohaib Nadeem 

[ Upstream commit 2ff33c759a4247c84ec0b7815f1f223e155ba82a ]

[why]
Originally, PMFW said min FCLK is 300Mhz, but min DCFCLK can be increased
to 400Mhz because min FCLK is now 600Mhz so FCLK >= 1.5 * DCFCLK hardware
requirement will still be satisfied. Increasing min DCFCLK addresses
underflow issues (underflow occurs when phantom pipe is turned on for some
Sub-Viewport configs).

[how]
Increasing DCFCLK by raising the min_dcfclk_mhz

Reviewed-by: Chaitanya Dhere 
Reviewed-by: Alvin Lee 
Acked-by: Tom Chung 
Signed-off-by: Sohaib Nadeem 
Tested-by: Daniel Wheeler 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
index cf3b400c8619..ec09d5a8876b 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
@@ -2452,7 +2452,7 @@ static int build_synthetic_soc_states(bool 
disable_dc_mode_overwrite, struct clk
struct _vcs_dpi_voltage_scaling_st entry = {0};
struct clk_limit_table_entry max_clk_data = {0};
 
-   unsigned int min_dcfclk_mhz = 199, min_fclk_mhz = 299;
+   unsigned int min_dcfclk_mhz = 399, min_fclk_mhz = 599;
 
static const unsigned int num_dcfclk_stas = 5;
unsigned int dcfclk_sta_targets[DC__VOLTAGE_STATES] = {199, 615, 906, 
1324, 1564};
-- 
2.43.0



[PATCH AUTOSEL 6.6 22/38] drm/amdkfd: Use correct drm device for cgroup permission check

2024-02-07 Thread Sasha Levin
From: Mukul Joshi 

[ Upstream commit 4119734e06a7f30e7e8eb92a58b85dca0269 ]

On GFX 9.4.3, for a given KFD node, fetch the correct drm device from
XCP manager when checking for cgroup permissions.

Signed-off-by: Mukul Joshi 
Reviewed-by: Harish Kasiviswanathan 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h 
b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index 3287a3961395..12ee273e87e1 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -1482,10 +1482,15 @@ void kfd_dec_compute_active(struct kfd_node *dev);
 
 /* Cgroup Support */
 /* Check with device cgroup if @kfd device is accessible */
-static inline int kfd_devcgroup_check_permission(struct kfd_node *kfd)
+static inline int kfd_devcgroup_check_permission(struct kfd_node *node)
 {
 #if defined(CONFIG_CGROUP_DEVICE) || defined(CONFIG_CGROUP_BPF)
-   struct drm_device *ddev = adev_to_drm(kfd->adev);
+   struct drm_device *ddev;
+
+   if (node->xcp)
+   ddev = node->xcp->ddev;
+   else
+   ddev = adev_to_drm(node->adev);
 
return devcgroup_check_permission(DEVCG_DEV_CHAR, DRM_MAJOR,
  ddev->render->index,
-- 
2.43.0



Re: [RFC] drm/i915: Add GuC submission interface version query

2024-02-07 Thread John Harrison

On 2/7/2024 12:47, Souza, Jose wrote:

On Wed, 2024-02-07 at 11:52 -0800, John Harrison wrote:

On 2/7/2024 11:43, Souza, Jose wrote:

On Wed, 2024-02-07 at 11:34 -0800, John Harrison wrote:

On 2/7/2024 10:49, Tvrtko Ursulin wrote:

On 07/02/2024 18:12, John Harrison wrote:

On 2/7/2024 03:56, Tvrtko Ursulin wrote:

From: Tvrtko Ursulin 

Add a new query to the GuC submission interface version.

Mesa intends to use this information to check for old firmware versions
with a known bug where using the render and compute command streamers
simultaneously can cause GPU hangs due issues in firmware scheduling.

Based on patches from Vivaik and Joonas.

There is a little bit of an open around the width required for
versions.
While the GuC FW iface tells they are u8, i915 GuC code uses u32:

    #define CSS_SW_VERSION_UC_MAJOR   (0xFF << 16)
    #define CSS_SW_VERSION_UC_MINOR   (0xFF << 8)
    #define CSS_SW_VERSION_UC_PATCH   (0xFF << 0)
...
    struct intel_uc_fw_ver {
    u32 major;
    u32 minor;
    u32 patch;
    u32 build;
    };

This is copied from generic code which supports firmwares other than
GuC. Only GuC promises to use 8-bit version components. Other
firmwares very definitely do not. There is no open.

Ack.


So we could make the query u8, and refactor the struct intel_uc_fw_ver
to use u8, or not. To avoid any doubts on why are we assigning u32 to
u8 I simply opted to use u64. Which avoids the need to add any padding
too.

I don't follow how potential 8 vs 32 confusion means jump to 64?!

Suggestion was to use u8 in the uapi in order to align with GuC FW ABI
(or however it's called), in which case there would be:

     ver.major = guc->submission_version.major;

which would be:

     (u8) = (u32)

And I was anticipating someone not liking that either. Using too wide
u64 simply avoids the need to add a padding element to the uapi struct.

If you are positive we need to include a branch number, even though it
does not seem to be implemented in the code even(*) then I can make
uapi 4x u32 and achieve the same.

It's not implemented in the code because we've never had to, and it is
yet another train wreck waiting to happen. There are a bunch of issues
at different levels that need to be resolved. But that is all in the
kernel and/or firmware and so can be added by a later kernel update when
necessary. However, if the UMDs are not already taking it into account
or its not even in the UAPI, then we can't back fill in the kernel
later, we are just broken.

This sounds to me like a firmware version for internal testing or for 
pre-production HW, would any branched firmware be released to customers?

See comments below. Branching is about back porting critical fixes to
older releases. I.e. supporting LTS releases. There is absolutely
nothing internal only or testing related about branching.

Just because we haven't had to do so yet doesn't mean we won't need to
do so tomorrow.

John.


(*)
static void uc_unpack_css_version(struct intel_uc_fw_ver *ver, u32
css_value)
{
  /* Get version numbers from the CSS header */
  ver->major = FIELD_GET(CSS_SW_VERSION_UC_MAJOR, css_value);
  ver->minor = FIELD_GET(CSS_SW_VERSION_UC_MINOR, css_value);
  ver->patch = FIELD_GET(CSS_SW_VERSION_UC_PATCH, css_value);
}

No branch field in the CSS header?

I think there is, it's just not officially implemented yet.


And Why is UMD supposed to reject a non-zero branch? Like how would
1.1.3.0 be fine and 1.1.3.1 be bad? I don't get it. But anyway, I can
respin if you definitely confirm.

Because that is backwards. The branch number goes at the front.

So, for example (using made up numbers, I don't recall offhand what
versions we have where) say we currently have 0.1.3.0 in tip and 0.1.1.0
in the last LTS. We then need to ship a critical security fix and back
port it to the LTS. Tip becomes 0.1.3.1 but the LTS can't become 0.1.1.1
because that version already exists in the history of tip and does not
contain the fix. So the LTS gets branched to 1.1.0.0. We then have both
branches potentially moving forwards with completely independent versioning.

Exactly the same as 5.8.x, 5.9,y, 6.0.z, etc in the Linux kernel
versioning. You cannot make any assumptions about what might be in
1.4.5.6 compared to 0.1.2.3. 1.4.5.6 could actually 0.1.0.3 with a stack
of security fixes but none of the features, workarounds or bug fixes
that are in 0.1.2.3.

Hence, if the branch number changes then all bets are off. You have to
start over and reject anything you do not explicitly know about.

This is why we were saying that exposing version numbers to UMDs breaks
down horribly as soon as we have to start branching. There is no clean
or simple way to do this.

Odd versioning, would expect that fixes on LTS would increase patch version.
You can't. That would create multiple firmware entities with the same 
version number.


E.g. everything is on 0.1.2.3. Tip moves 

[PATCH AUTOSEL 6.7 27/44] drm/amd/display: Fix DPSTREAM CLK on and off sequence

2024-02-07 Thread Sasha Levin
From: Dmytro Laktyushkin 

[ Upstream commit 31c2bf25eaf51c2d45f092284a28e97f43b54c15 ]

[Why]
Secondary DP2 display fails to light up in some instances

[How]
Clock needs to be on when DPSTREAMCLK*_EN =1. This change
moves dtbclk_p enable/disable point to make sure this is
the case

Reviewed-by: Charlene Liu 
Reviewed-by: Dmytro Laktyushkin 
Acked-by: Tom Chung 
Signed-off-by: Daniel Miess 
Signed-off-by: Dmytro Laktyushkin 
Tested-by: Daniel Wheeler 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 .../gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c |  2 +-
 .../gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c   | 11 +--
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
index 9b8299d97e40..390d7ebfd8db 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
@@ -1182,9 +1182,9 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx)
dto_params.timing = _ctx->stream->timing;
dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst;
if (dccg) {
-   dccg->funcs->set_dtbclk_dto(dccg, _params);
dccg->funcs->disable_symclk32_se(dccg, dp_hpo_inst);
dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst, 
dp_hpo_inst);
+   dccg->funcs->set_dtbclk_dto(dccg, _params);
}
} else if (dccg && dccg->funcs->disable_symclk_se) {
dccg->funcs->disable_symclk_se(dccg, 
stream_enc->stream_enc_inst,
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c 
b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
index 608221b0dd5d..780b94592992 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
+++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
@@ -2755,18 +2755,17 @@ void dcn20_enable_stream(struct pipe_ctx *pipe_ctx)
}
 
if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {
-   dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst;
-   dccg->funcs->set_dpstreamclk(dccg, DTBCLK0, tg->inst, 
dp_hpo_inst);
-
-   phyd32clk = get_phyd32clk_src(link);
-   dccg->funcs->enable_symclk32_se(dccg, dp_hpo_inst, phyd32clk);
-
dto_params.otg_inst = tg->inst;
dto_params.pixclk_khz = pipe_ctx->stream->timing.pix_clk_100hz 
/ 10;
dto_params.num_odm_segments = get_odm_segment_count(pipe_ctx);
dto_params.timing = _ctx->stream->timing;
dto_params.ref_dtbclk_khz = 
dc->clk_mgr->funcs->get_dtb_ref_clk_frequency(dc->clk_mgr);
dccg->funcs->set_dtbclk_dto(dccg, _params);
+   dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst;
+   dccg->funcs->set_dpstreamclk(dccg, DTBCLK0, tg->inst, 
dp_hpo_inst);
+
+   phyd32clk = get_phyd32clk_src(link);
+   dccg->funcs->enable_symclk32_se(dccg, dp_hpo_inst, phyd32clk);
} else {
if (dccg->funcs->enable_symclk_se)
dccg->funcs->enable_symclk_se(dccg, 
stream_enc->stream_enc_inst,
-- 
2.43.0



[PATCH AUTOSEL 6.7 25/44] drm/amd/display: increased min_dcfclk_mhz and min_fclk_mhz

2024-02-07 Thread Sasha Levin
From: Sohaib Nadeem 

[ Upstream commit 2ff33c759a4247c84ec0b7815f1f223e155ba82a ]

[why]
Originally, PMFW said min FCLK is 300Mhz, but min DCFCLK can be increased
to 400Mhz because min FCLK is now 600Mhz so FCLK >= 1.5 * DCFCLK hardware
requirement will still be satisfied. Increasing min DCFCLK addresses
underflow issues (underflow occurs when phantom pipe is turned on for some
Sub-Viewport configs).

[how]
Increasing DCFCLK by raising the min_dcfclk_mhz

Reviewed-by: Chaitanya Dhere 
Reviewed-by: Alvin Lee 
Acked-by: Tom Chung 
Signed-off-by: Sohaib Nadeem 
Tested-by: Daniel Wheeler 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c 
b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
index 92e2ddc9ab7e..67497d7d66d2 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
@@ -2719,7 +2719,7 @@ static int build_synthetic_soc_states(bool 
disable_dc_mode_overwrite, struct clk
struct _vcs_dpi_voltage_scaling_st entry = {0};
struct clk_limit_table_entry max_clk_data = {0};
 
-   unsigned int min_dcfclk_mhz = 199, min_fclk_mhz = 299;
+   unsigned int min_dcfclk_mhz = 399, min_fclk_mhz = 599;
 
static const unsigned int num_dcfclk_stas = 5;
unsigned int dcfclk_sta_targets[DC__VOLTAGE_STATES] = {199, 615, 906, 
1324, 1564};
-- 
2.43.0



[PATCH AUTOSEL 6.7 24/44] drm/amdkfd: Use correct drm device for cgroup permission check

2024-02-07 Thread Sasha Levin
From: Mukul Joshi 

[ Upstream commit 4119734e06a7f30e7e8eb92a58b85dca0269 ]

On GFX 9.4.3, for a given KFD node, fetch the correct drm device from
XCP manager when checking for cgroup permissions.

Signed-off-by: Mukul Joshi 
Reviewed-by: Harish Kasiviswanathan 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h 
b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index 28162bfbe1b3..71445ab63b5e 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -1482,10 +1482,15 @@ void kfd_dec_compute_active(struct kfd_node *dev);
 
 /* Cgroup Support */
 /* Check with device cgroup if @kfd device is accessible */
-static inline int kfd_devcgroup_check_permission(struct kfd_node *kfd)
+static inline int kfd_devcgroup_check_permission(struct kfd_node *node)
 {
 #if defined(CONFIG_CGROUP_DEVICE) || defined(CONFIG_CGROUP_BPF)
-   struct drm_device *ddev = adev_to_drm(kfd->adev);
+   struct drm_device *ddev;
+
+   if (node->xcp)
+   ddev = node->xcp->ddev;
+   else
+   ddev = adev_to_drm(node->adev);
 
return devcgroup_check_permission(DEVCG_DEV_CHAR, DRM_MAJOR,
  ddev->render->index,
-- 
2.43.0



[PATCH AUTOSEL 6.7 26/44] drm/amd/display: fix USB-C flag update after enc10 feature init

2024-02-07 Thread Sasha Levin
From: Charlene Liu 

[ Upstream commit b5abd7f983e14054593dc91d6df2aa5f8cc67652 ]

[why]
BIOS's integration info table not following the original order
which is phy instance is ext_displaypath's array index.

[how]
Move them to follow the original order.

Reviewed-by: Muhammad Ahmed 
Acked-by: Tom Chung 
Signed-off-by: Charlene Liu 
Tested-by: Daniel Wheeler 
Signed-off-by: Alex Deucher 
Signed-off-by: Sasha Levin 
---
 drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.c | 4 ++--
 drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_link_encoder.c | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.c 
b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.c
index 501388014855..d761b0df2878 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.c
@@ -203,12 +203,12 @@ void dcn32_link_encoder_construct(
enc10->base.hpd_source = init_data->hpd_source;
enc10->base.connector = init_data->connector;
 
-   if (enc10->base.connector.id == CONNECTOR_ID_USBC)
-   enc10->base.features.flags.bits.DP_IS_USB_C = 1;
 
enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
 
enc10->base.features = *enc_features;
+   if (enc10->base.connector.id == CONNECTOR_ID_USBC)
+   enc10->base.features.flags.bits.DP_IS_USB_C = 1;
 
enc10->base.transmitter = init_data->transmitter;
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_link_encoder.c 
b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_link_encoder.c
index f91e08895275..3fca3dca61f0 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_link_encoder.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_link_encoder.c
@@ -184,8 +184,6 @@ void dcn35_link_encoder_construct(
enc10->base.hpd_source = init_data->hpd_source;
enc10->base.connector = init_data->connector;
 
-   if (enc10->base.connector.id == CONNECTOR_ID_USBC)
-   enc10->base.features.flags.bits.DP_IS_USB_C = 1;
 
enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
 
@@ -240,6 +238,8 @@ void dcn35_link_encoder_construct(
}
 
enc10->base.features.flags.bits.HDMI_6GB_EN = 1;
+   if (enc10->base.connector.id == CONNECTOR_ID_USBC)
+   enc10->base.features.flags.bits.DP_IS_USB_C = 1;
 
if (bp_funcs->get_connector_speed_cap_info)
result = 
bp_funcs->get_connector_speed_cap_info(enc10->base.ctx->dc_bios,
-- 
2.43.0



Re: [PATCH 02/19] drm/dp: Add support for DP tunneling

2024-02-07 Thread Imre Deak
On Wed, Feb 07, 2024 at 10:48:53PM +0200, Imre Deak wrote:
> On Wed, Feb 07, 2024 at 10:02:18PM +0200, Ville Syrjälä wrote:
> > > [...]
> > > +static int
> > > +drm_dp_tunnel_atomic_check_group_bw(struct drm_dp_tunnel_group_state 
> > > *new_group_state,
> > > + u32 *failed_stream_mask)
> > > +{
> > > + struct drm_dp_tunnel_group *group = to_group(new_group_state->base.obj);
> > > + struct drm_dp_tunnel_state *new_tunnel_state;
> > > + u32 group_stream_mask = 0;
> > > + int group_bw = 0;
> > > +
> > > + for_each_tunnel_state(new_group_state, new_tunnel_state) {
> > > + struct drm_dp_tunnel *tunnel = 
> > > new_tunnel_state->tunnel_ref.tunnel;
> > > + int max_dprx_bw = get_max_dprx_bw(tunnel);
> > > + int tunnel_bw = 
> > > drm_dp_tunnel_atomic_get_tunnel_bw(new_tunnel_state);
> > > +
> > > + tun_dbg(tunnel,
> > > + "%sRequired %d/%d Mb/s total for tunnel.\n",
> > > + tunnel_bw > max_dprx_bw ? "Not enough BW: " : "",
> > > + DPTUN_BW_ARG(tunnel_bw),
> > > + DPTUN_BW_ARG(max_dprx_bw));
> > > +
> > > + if (tunnel_bw > max_dprx_bw) {
> > 
> > I'm a bit confused why we're checking this here. Aren't we already
> > checking this somewhere else?
> 
> Ah, yes this should be checked already by the encoder compute config +
> the MST link BW check. It can be removed, thanks.

Though neither of that is guaranteed for drivers in general, so
shouldn't it be here still?

> > > + *failed_stream_mask = new_tunnel_state->stream_mask;
> > > + return -ENOSPC;
> > > + }
> > > +
> > > + group_bw += min(roundup(tunnel_bw, tunnel->bw_granularity),
> > > + max_dprx_bw);
> > > + group_stream_mask |= new_tunnel_state->stream_mask;
> > > + }
> > > +
> > > + tun_grp_dbg(group,
> > > + "%sRequired %d/%d Mb/s total for tunnel group.\n",
> > > + group_bw > group->available_bw ? "Not enough BW: " : "",
> > > + DPTUN_BW_ARG(group_bw),
> > > + DPTUN_BW_ARG(group->available_bw));
> > > +
> > > + if (group_bw > group->available_bw) {
> > > + *failed_stream_mask = group_stream_mask;
> > > + return -ENOSPC;
> > > + }
> > > +
> > > + return 0;
> > > +}
> > > +


Re: [PATCH] drm: panel-orientation-quirks: Add quirk for Aya Neo KUN

2024-02-07 Thread Tobias Jakobi

Hi Dmitry,

On 2/7/24 12:00, Dmitry Baryshkov wrote:

On Tue, 6 Feb 2024 at 01:57,  wrote:

From: Tobias Jakobi 

Similar to the other Aya Neo devices this one features
again a portrait screen, here with a native resolution
of 1600x2560.

Signed-off-by: Tobias Jakobi 

As you don't seem to be the author of the patch, this needs your sign-off too.


I'm not sure what you mean. Patch is by me, and signed off by me.

- Tobias



Re: [PATCH 02/19] drm/dp: Add support for DP tunneling

2024-02-07 Thread Imre Deak
On Wed, Feb 07, 2024 at 10:02:18PM +0200, Ville Syrjälä wrote:
> On Tue, Jan 23, 2024 at 12:28:33PM +0200, Imre Deak wrote:
> > +static char yes_no_chr(int val)
> > +{
> > +   return val ? 'Y' : 'N';
> > +}
> 
> We have str_yes_no() already.

Ok, will use this.

> v> +
> > +#define SKIP_DPRX_CAPS_CHECK   BIT(0)
> > +#define ALLOW_ALLOCATED_BW_CHANGE  BIT(1)
> > +
> > +static bool tunnel_regs_are_valid(struct drm_dp_tunnel_mgr *mgr,
> > + const struct drm_dp_tunnel_regs *regs,
> > + unsigned int flags)
> > +{
> > +   int drv_group_id = tunnel_reg_drv_group_id(regs);
> > +   bool check_dprx = !(flags & SKIP_DPRX_CAPS_CHECK);
> > +   bool ret = true;
> > +
> > +   if (!tunnel_reg_bw_alloc_supported(regs)) {
> > +   if (tunnel_group_id(drv_group_id)) {
> > +   drm_dbg_kms(mgr->dev,
> > +   "DPTUN: A non-zero group ID is only allowed 
> > with BWA support\n");
> > +   ret = false;
> > +   }
> > +
> > +   if (tunnel_reg(regs, DP_ALLOCATED_BW)) {
> > +   drm_dbg_kms(mgr->dev,
> > +   "DPTUN: BW is allocated without BWA 
> > support\n");
> > +   ret = false;
> > +   }
> > +
> > +   return ret;
> > +   }
> > +
> > +   if (!tunnel_group_id(drv_group_id)) {
> > +   drm_dbg_kms(mgr->dev,
> > +   "DPTUN: BWA support requires a non-zero group 
> > ID\n");
> > +   ret = false;
> > +   }
> > +
> > +   if (check_dprx && hweight8(tunnel_reg_max_dprx_lane_count(regs)) != 1) {
> > +   drm_dbg_kms(mgr->dev,
> > +   "DPTUN: Invalid DPRX lane count: %d\n",
> > +   tunnel_reg_max_dprx_lane_count(regs));
> > +
> > +   ret = false;
> > +   }
> > +
> > +   if (check_dprx && !tunnel_reg_max_dprx_rate(regs)) {
> > +   drm_dbg_kms(mgr->dev,
> > +   "DPTUN: DPRX rate is 0\n");
> > +
> > +   ret = false;
> > +   }
> > +
> > +   if (tunnel_reg(regs, DP_ALLOCATED_BW) > tunnel_reg(regs, 
> > DP_ESTIMATED_BW)) {
> > +   drm_dbg_kms(mgr->dev,
> > +   "DPTUN: Allocated BW %d > estimated BW %d Mb/s\n",
> > +   DPTUN_BW_ARG(tunnel_reg(regs, DP_ALLOCATED_BW) *
> > +tunnel_reg_bw_granularity(regs)),
> > +   DPTUN_BW_ARG(tunnel_reg(regs, DP_ESTIMATED_BW) *
> > +tunnel_reg_bw_granularity(regs)));
> > +
> > +   ret = false;
> > +   }
> > +
> > +   return ret;
> > +}
> > +
> > +static bool tunnel_info_changes_are_valid(struct drm_dp_tunnel *tunnel,
> > + const struct drm_dp_tunnel_regs *regs,
> > + unsigned int flags)
> > +{
> > +   int new_drv_group_id = tunnel_reg_drv_group_id(regs);
> > +   bool ret = true;
> > +
> > +   if (tunnel->bw_alloc_supported != tunnel_reg_bw_alloc_supported(regs)) {
> > +   tun_dbg(tunnel,
> > +   "BW alloc support has changed %c -> %c\n",
> > +   yes_no_chr(tunnel->bw_alloc_supported),
> > +   yes_no_chr(tunnel_reg_bw_alloc_supported(regs)));
> > +
> > +   ret = false;
> > +   }
> > +
> > +   if (tunnel->group->drv_group_id != new_drv_group_id) {
> > +   tun_dbg(tunnel,
> > +   "Driver/group ID has changed %d:%d:* -> %d:%d:*\n",
> > +   tunnel_group_drv_id(tunnel->group->drv_group_id),
> > +   tunnel_group_id(tunnel->group->drv_group_id),
> > +   tunnel_group_drv_id(new_drv_group_id),
> > +   tunnel_group_id(new_drv_group_id));
> > +
> > +   ret = false;
> > +   }
> > +
> > +   if (!tunnel->bw_alloc_supported)
> > +   return ret;
> > +
> > +   if (tunnel->bw_granularity != tunnel_reg_bw_granularity(regs)) {
> > +   tun_dbg(tunnel,
> > +   "BW granularity has changed: %d -> %d Mb/s\n",
> > +   DPTUN_BW_ARG(tunnel->bw_granularity),
> > +   DPTUN_BW_ARG(tunnel_reg_bw_granularity(regs)));
> > +
> > +   ret = false;
> > +   }
> > +
> > +   /*
> > +* On some devices at least the BW alloc mode enabled status is always
> > +* reported as 0, so skip checking that here.
> > +*/
> 
> So it's reported as supported and we enable it, but it's never
> reported back as being enabled?

Yes, at least using an engineering TBT (DP adapter) FW. I'll check if
this is fixed already on released platforms/FWs.

> > +
> > +   if (!(flags & ALLOW_ALLOCATED_BW_CHANGE) &&
> > +   tunnel->allocated_bw !=
> > +   tunnel_reg(regs, DP_ALLOCATED_BW) * tunnel->bw_granularity) {
> > +   tun_dbg(tunnel,
> > +   "Allocated BW has changed: %d -> %d Mb/s\n",
> > +   DPTUN_BW_ARG(tunnel->allocated_bw),
> > +  

Re: [RFC] drm/i915: Add GuC submission interface version query

2024-02-07 Thread Souza, Jose
On Wed, 2024-02-07 at 11:52 -0800, John Harrison wrote:
> On 2/7/2024 11:43, Souza, Jose wrote:
> > On Wed, 2024-02-07 at 11:34 -0800, John Harrison wrote:
> > > On 2/7/2024 10:49, Tvrtko Ursulin wrote:
> > > > On 07/02/2024 18:12, John Harrison wrote:
> > > > > On 2/7/2024 03:56, Tvrtko Ursulin wrote:
> > > > > > From: Tvrtko Ursulin 
> > > > > > 
> > > > > > Add a new query to the GuC submission interface version.
> > > > > > 
> > > > > > Mesa intends to use this information to check for old firmware 
> > > > > > versions
> > > > > > with a known bug where using the render and compute command 
> > > > > > streamers
> > > > > > simultaneously can cause GPU hangs due issues in firmware 
> > > > > > scheduling.
> > > > > > 
> > > > > > Based on patches from Vivaik and Joonas.
> > > > > > 
> > > > > > There is a little bit of an open around the width required for
> > > > > > versions.
> > > > > > While the GuC FW iface tells they are u8, i915 GuC code uses u32:
> > > > > > 
> > > > > >    #define CSS_SW_VERSION_UC_MAJOR   (0xFF << 16)
> > > > > >    #define CSS_SW_VERSION_UC_MINOR   (0xFF << 8)
> > > > > >    #define CSS_SW_VERSION_UC_PATCH   (0xFF << 0)
> > > > > > ...
> > > > > >    struct intel_uc_fw_ver {
> > > > > >    u32 major;
> > > > > >    u32 minor;
> > > > > >    u32 patch;
> > > > > >    u32 build;
> > > > > >    };
> > > > > This is copied from generic code which supports firmwares other than
> > > > > GuC. Only GuC promises to use 8-bit version components. Other
> > > > > firmwares very definitely do not. There is no open.
> > > > Ack.
> > > > 
> > > > > > So we could make the query u8, and refactor the struct 
> > > > > > intel_uc_fw_ver
> > > > > > to use u8, or not. To avoid any doubts on why are we assigning u32 
> > > > > > to
> > > > > > u8 I simply opted to use u64. Which avoids the need to add any 
> > > > > > padding
> > > > > > too.
> > > > > I don't follow how potential 8 vs 32 confusion means jump to 64?!
> > > > Suggestion was to use u8 in the uapi in order to align with GuC FW ABI
> > > > (or however it's called), in which case there would be:
> > > > 
> > > >     ver.major = guc->submission_version.major;
> > > > 
> > > > which would be:
> > > > 
> > > >     (u8) = (u32)
> > > > 
> > > > And I was anticipating someone not liking that either. Using too wide
> > > > u64 simply avoids the need to add a padding element to the uapi struct.
> > > > 
> > > > If you are positive we need to include a branch number, even though it
> > > > does not seem to be implemented in the code even(*) then I can make
> > > > uapi 4x u32 and achieve the same.
> > > It's not implemented in the code because we've never had to, and it is
> > > yet another train wreck waiting to happen. There are a bunch of issues
> > > at different levels that need to be resolved. But that is all in the
> > > kernel and/or firmware and so can be added by a later kernel update when
> > > necessary. However, if the UMDs are not already taking it into account
> > > or its not even in the UAPI, then we can't back fill in the kernel
> > > later, we are just broken.
> > This sounds to me like a firmware version for internal testing or for 
> > pre-production HW, would any branched firmware be released to customers?
> See comments below. Branching is about back porting critical fixes to 
> older releases. I.e. supporting LTS releases. There is absolutely 
> nothing internal only or testing related about branching.
> 
> Just because we haven't had to do so yet doesn't mean we won't need to 
> do so tomorrow.
> 
> John.
> 
> > 
> > > > (*)
> > > > static void uc_unpack_css_version(struct intel_uc_fw_ver *ver, u32
> > > > css_value)
> > > > {
> > > >  /* Get version numbers from the CSS header */
> > > >  ver->major = FIELD_GET(CSS_SW_VERSION_UC_MAJOR, css_value);
> > > >  ver->minor = FIELD_GET(CSS_SW_VERSION_UC_MINOR, css_value);
> > > >  ver->patch = FIELD_GET(CSS_SW_VERSION_UC_PATCH, css_value);
> > > > }
> > > > 
> > > > No branch field in the CSS header?
> > > I think there is, it's just not officially implemented yet.
> > > 
> > > > And Why is UMD supposed to reject a non-zero branch? Like how would
> > > > 1.1.3.0 be fine and 1.1.3.1 be bad? I don't get it. But anyway, I can
> > > > respin if you definitely confirm.
> > > Because that is backwards. The branch number goes at the front.
> > > 
> > > So, for example (using made up numbers, I don't recall offhand what
> > > versions we have where) say we currently have 0.1.3.0 in tip and 0.1.1.0
> > > in the last LTS. We then need to ship a critical security fix and back
> > > port it to the LTS. Tip becomes 0.1.3.1 but the LTS can't become 0.1.1.1
> > > because that version already exists in the history of tip and does not
> > > contain the fix. So the LTS gets branched to 1.1.0.0. We then have both
> > > branches potentially moving forwards with completely independent 
> > > versioning.
> > 

[pull] drm/msm: drm-msm-fixes-2024-02-07 for v6.8-rc4

2024-02-07 Thread Rob Clark
Hi Dave,

A few fixes for v6.8, description below

The following changes since commit d4ca26ac4be0d9aea7005c40df75e6775749671b:

  drm/msm/dp: call dp_display_get_next_bridge() during probe
(2023-12-14 09:27:46 +0200)

are available in the Git repository at:

  https://gitlab.freedesktop.org/drm/msm.git tags/drm-msm-fixes-2024-02-07

for you to fetch changes up to 8d35217149daa33358c284aca6a56d5ab92cfc6c:

  drm/msm/mdss: specify cfg bandwidth for SDM670 (2024-01-25 14:36:04 -0800)


Fixes for v6.8-rc4

DPU:
- fix for kernel doc warnings and smatch warnings in dpu_encoder
- fix for smatch warning in dpu_encoder
- fix the bus bandwidth value for SDM670

DP:
- fixes to handle unknown bpc case correctly for DP. The current code was
  spilling over into other bits of DP configuration register, had to be
  fixed to avoid the extra shifts which were causing the spill over
- fix for MISC0 programming in DP driver to program the correct
  colorimetry value

GPU:
- dmabuf vmap fix
- a610 UBWC corruption fix (incorrect hbb)
- revert a commit that was making GPU recovery unreliable


Abhinav Kumar (1):
  drm/msm/dpu: check for valid hw_pp in dpu_encoder_helper_phys_cleanup

Dmitry Baryshkov (1):
  drm/msm/mdss: specify cfg bandwidth for SDM670

Kuogee Hsieh (2):
  drm/msms/dp: fixed link clock divider bits be over written in
BPC unknown case
  drm/msm/dp: return correct Colorimetry for DP_TEST_DYNAMIC_RANGE_CEA case

Randy Dunlap (1):
  drm/msm/dpu: fix kernel-doc warnings

 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c |  8 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c  |  3 ++-
 drivers/gpu/drm/msm/dp/dp_ctrl.c|  5 -
 drivers/gpu/drm/msm/dp/dp_link.c| 22 ++
 drivers/gpu/drm/msm/dp/dp_reg.h |  3 +++
 drivers/gpu/drm/msm/msm_mdss.c  |  1 +
 6 files changed, 22 insertions(+), 20 deletions(-)


Re: [PATCH 2/2] drm/vkms: Use a simpler composition function

2024-02-07 Thread Arthur Grillo



On 07/02/24 13:03, Louis Chauvet wrote:
> Hello Pekka, Arthur,
> 
> [...]
> 
>>>> Would it be possible to have a standardised benchmark specifically
>>>> for performance rather than correctness, in IGT or where-ever it
>>>> would make sense? Then it would be simple to tell contributors to
>>>> run this and report the numbers before and after.
>>>>
>>>> I would propose this kind of KMS layout:
>>>>
>>>> - CRTC size 3841 x 2161
>>>> - primary plane, XRGB, 3639 x 2161 @ 101,0
>>>> - overlay A, XBGR2101010, 3033 x 1777 @ 201,199
>>>> - overlay B, ARGB, 1507 x 1400 @ 1800,250
>>>>
>>>> The sizes and positions are deliberately odd to try to avoid happy
>>>> alignment accidents. The planes are big, which should let the pixel
>>>> operations easily dominate performance measurement. There are
>>>> different pixel formats, both opaque and semi-transparent. There is
>>>> lots of plane overlap. The planes also do not cover the whole CRTC
>>>> leaving the background visible a bit.
>>>>
>>>> There should be two FBs per each plane, flipped alternatingly each
>>>> frame. Writeback should be active. Run this a number of frames, say,
>>>> 100, and measure the kernel CPU time taken. It's supposed to take at
>>>> least several seconds in total.
>>>>
>>>> I think something like this should be the base benchmark. One can
>>>> add more to it, like rotated planes, YUV planes, etc. or switch
>>>> settings on the existing planes. Maybe even FB_DAMAGE_CLIPS. Maybe
>>>> one more overlay that is very tall and thin.
>>>>
>>>> Just an idea, what do you all think?  
>>>
>>> Hi Pekka,
>>>
>>> I just finished writing this proposal using IGT.
>>>
>>> I got pretty interesting results:
>>>
>>> The mentioned commit 8356b97906503a02125c8d03c9b88a61ea46a05a took
>>> around 13 seconds. While drm-misc/drm-misc-next took 36 seconds.
>>>
>>> I'm currently bisecting to be certain that the change to the
>>> pixel-by-pixel is the culprit, but I don't see why it wouldn't be.
>>>
>>> I just need to do some final touches on the benchmark code and it
>>> will be ready for revision.
>>
>> Awesome, thank you very much for doing that!
>> pq
> 
> I also think it's a good benchmarks for classic configurations. The odd 
> size is a very nice idea to verify the corner cases of line-by-line 
> algorithms.
> 
> When this is ready, please share the test, so I can check if my patch is 
> as performant as before.
> 
> Thank you for this work.
> 
> Have a nice day,
> Louis Chauvet
> 

Just sent the benchmark for revision:
https://lore.kernel.org/r/20240207-bench-v1-1-7135ad426...@riseup.net


Re: [PATCH v2 2/2] fbcon: Defer console takeover for splash screens to first switch

2024-02-07 Thread Mario Limonciello

On 2/7/2024 03:51, Daniel Vetter wrote:

On Wed, Feb 07, 2024 at 10:03:10AM +0800, Daniel van Vugt wrote:

On 6/2/24 23:41, Mario Limonciello wrote:

On 2/6/2024 08:21, Daniel Vetter wrote:

On Tue, Feb 06, 2024 at 06:10:51PM +0800, Daniel van Vugt wrote:

Until now, deferred console takeover only meant defer until there is
output. But that risks stepping on the toes of userspace splash screens,
as console messages may appear before the splash screen. So check the
command line for the expectation of userspace splash and if present then
extend the deferral until after the first switch.

V2: Added Kconfig option instead of hard coding "splash".

Closes: https://bugs.launchpad.net/bugs/1970069
Cc: Mario Limonciello 
Signed-off-by: Daniel van Vugt 
---
   drivers/video/console/Kconfig    | 13 +++
   drivers/video/fbdev/core/fbcon.c | 38 ++--
   2 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index bc31db6ef7..a6e371bfb4 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -138,6 +138,19 @@ config FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER
     by the firmware in place, rather then replacing the contents with a
     black screen as soon as fbcon loads.
   +config FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER_CONDITION
+    string "Framebuffer Console Deferred Takeover Condition"
+    depends on FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER
+    default "splash"
+    help
+  If enabled this defers further the framebuffer console taking over
+  until the first console switch has occurred. And even then only if
+  text has been output, and only if the specified parameter is found
+  on the command line. This ensures fbcon does not interrupt userspace
+  splash screens such as Plymouth which may be yet to start rendering
+  at the time of the first console output. "splash" is the simplest
+  distro-agnostic condition for this that Plymouth checks for.


Hm this seems a bit strange since a lot of complexity that no one needs,
also my impression is that it's rather distro specific how you want this
to work. So why not just a Kconfig option that lets you choose how much
you want to delay fbcon setup, with the following options:

- no delay at all
- dely until first output from the console (which then works for distros
    which set a log-level to suppress unwanted stuff)
- delay until first vt-switch. In that case I don't think we also need to
    delay for first output, since vt switch usually means you'll get first
    output right away (if it's a vt terminal) or you switch to a different
    graphical console (which will keep fbcon fully suppressed on the drm
    side).



I had similar thoughts, and had prototyped some of this already. But in the end
it felt like extra complexity there was no demand for.


For me this one is a bit too complex, since if you enable the vt switch
delay you also get the output delay on top. That seems one too much and I
can't come up with a use-case where you actually want that. So just a
choice of one or the other or none feels cleaner.


If you would like to specify the preferred Kconfig design then I can implement
it. Though I don't think there is an enumeration type. It could also be a
runtime enumeration (deferred_takeover) controlled by fbcon=something.


There's a choice in Kconfig, see e.g. kernel/Kconfig.hz for an example.


IIUC there is an "automatic" VT switch that happens with Ubuntu GRUB + Ubuntu
kernels.

Why?

Couldn't this also be suppressed by just not doing that?


I have not seen any automatic VT switches in debugging but now that you mention
it I was probably only debugging on drm-misc-next and not an Ubuntu kernel.


Hm but I don't see how the output delay would paper over a race (if there
is one) reliable for this case? If you do vt switch for boot splash or
login screen and don't yet have drm opened for display or something like
that, then fbcon can sneak in anyway ...


Ubuntu has had in (at least some) kernels:

https://git.launchpad.net/~ubuntu-kernel/ubuntu/+source/linux/+git/unstable/commit/?id=320cfac8ef31

I'm unsure if it's still there today, but maybe it would be best if the 
author (Andy) could enlighten us?  Any idea why that didn't go upstream?


I had thought that tied with a automatic VT switch that was trying to 
hide fbcon as well.




Cheers, Sima


- Daniel




I think you could even reuse the existing
CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER for this, and then just
compile-time select which kind of notifier to register (well plus the
check for "splash" on the cmdline for the vt switch one I guess).

Thoughts?

Cheers, Sima



+
   config STI_CONSOLE
   bool "STI text console"
   depends on PARISC && HAS_IOMEM
diff --git a/drivers/video/fbdev/core/fbcon.c
b/drivers/video/fbdev/core/fbcon.c
index 63af6ab034..98155d2256 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ 

[PATCH i-g-t] benchmarks: Add VKMS benchmark

2024-02-07 Thread Arthur Grillo
;display.n_outputs; i++) {
+   igt_output_t *output = >display.outputs[i];
+
+   if (output->config.connector->connector_type != 
DRM_MODE_CONNECTOR_WRITEBACK)
+   continue;
+
+   return output;
+
+   }
+
+   return NULL;
+}
+
+static struct kms_t default_kms = {
+   .primary = {
+   .rect = {
+   .x = 101, .y = 0,
+   .width = 3639, .height = 2161,
+   },
+   .format = DRM_FORMAT_XRGB,
+   },
+   .overlay_a = {
+   .rect = {
+   .x = 201, .y = 199,
+   .width = 3033, .height = 1777,
+   },
+   .format = DRM_FORMAT_XRGB16161616,
+   },
+   .overlay_b = {
+   .rect = {
+   .x = 1800, .y = 250,
+   .width = 1507, .height = 1400,
+   },
+   .format = DRM_FORMAT_ARGB,
+   },
+   .writeback = {
+   .rect = {
+   .x = 0, .y = 0,
+   // Size is to be determined at runtime
+   },
+   .format = DRM_FORMAT_XRGB,
+   },
+};
+
+
+igt_simple_main
+{
+   struct data_t data;
+   enum pipe pipe = PIPE_NONE;
+
+   data.kms = default_kms;
+
+   data.fd = drm_open_driver_master(DRIVER_ANY);
+
+   igt_display_require(, data.fd);
+
+   kmstest_set_vt_graphics_mode();
+
+   igt_display_require(, data.fd);
+   igt_require(data.display.is_atomic);
+
+   igt_display_require_output();
+
+   igt_require(data.wb_output);
+   igt_display_reset();
+
+   data.wb_output = find_wb_output();
+
+   for_each_pipe(, pipe) {
+   igt_debug("Selecting pipe %s to %s\n",
+ kmstest_pipe_name(pipe),
+ igt_output_name(data.wb_output));
+   igt_output_set_pipe(data.wb_output, pipe);
+   }
+
+   igt_display_commit_atomic(, DRM_MODE_ATOMIC_ALLOW_MODESET, 
NULL);
+
+   gen_fbs();
+
+   data.kms.primary.base = igt_output_get_plane_type(data.wb_output, 
DRM_PLANE_TYPE_PRIMARY);
+   data.kms.overlay_a.base = 
igt_output_get_plane_type_index(data.wb_output,
+ 
DRM_PLANE_TYPE_OVERLAY, 0);
+   data.kms.overlay_b.base = 
igt_output_get_plane_type_index(data.wb_output,
+ 
DRM_PLANE_TYPE_OVERLAY, 1);
+
+   for (int i = 0; i < FRAME_COUNT; i++) {
+   int fb_index = i % 2;
+
+   plane_setup(, fb_index);
+
+   plane_setup(_a, fb_index);
+
+   plane_setup(_b, fb_index);
+
+   igt_output_set_writeback_fb(data.wb_output, 
[fb_index]);
+
+   igt_display_commit2(, COMMIT_ATOMIC);
+   }
+
+   igt_display_fini();
+   drm_close_driver(data.fd);
+}

---
base-commit: c58c5fb6aa1cb7d3627a15e364816a7a2add9edc
change-id: 20240207-bench-393789eaba47

Best regards,
-- 
Arthur Grillo 



Re: [PATCH v3 2/4] drm/msm/dpu: support binding to the mdp5 devices

2024-02-07 Thread Abhinav Kumar




On 2/7/2024 11:56 AM, Dmitry Baryshkov wrote:

On Wed, 7 Feb 2024 at 20:48, Abhinav Kumar  wrote:




On 1/5/2024 3:34 PM, Dmitry Baryshkov wrote:

Existing MDP5 devices have slightly different bindings. The main
register region is called `mdp_phys' instead of `mdp'. Also vbif
register regions are a part of the parent, MDSS device. Add support for
handling this binding differences.

Signed-off-by: Dmitry Baryshkov 
---
   drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 98 
++---
   drivers/gpu/drm/msm/msm_drv.h   |  3 +
   drivers/gpu/drm/msm/msm_io_utils.c  | 13 +
   3 files changed, 93 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 723cc1d82143..aa9e0ad33ebb 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -1197,6 +1197,78 @@ static int dpu_kms_init(struct drm_device *ddev)
   return 0;
   }

+static int dpu_kms_mmap_mdp5(struct dpu_kms *dpu_kms)
+{
+ struct platform_device *pdev = dpu_kms->pdev;
+ struct platform_device *mdss_dev;
+ int ret;
+
+ if (dpu_kms->pdev->dev.bus != _bus_type)
+ return -EINVAL;
+


!dev_is_platform() perhaps?


looks good



But I would like to understand this check a bit more. Can you pls
explain for which case this check was added?


It is necessary to be sure that we can perform to_platform_device() on
the next line.



Got it but on the next line we are using to_platform_device on dpu's 
parent device. So shouldnt the check also be dpu_kms->pdev->dev.parent.bus?





+ mdss_dev = to_platform_device(dpu_kms->pdev->dev.parent);
+
+ dpu_kms->mmio = msm_ioremap(pdev, "mdp_phys");
+ if (IS_ERR(dpu_kms->mmio)) {
+ ret = PTR_ERR(dpu_kms->mmio);
+ DPU_ERROR("mdp register memory map failed: %d\n", ret);
+ dpu_kms->mmio = NULL;
+ return ret;
+ }
+ DRM_DEBUG("mapped dpu address space @%pK\n", dpu_kms->mmio);
+
+ dpu_kms->vbif[VBIF_RT] = msm_ioremap_mdss(mdss_dev,
+   dpu_kms->pdev,
+   "vbif_phys");
+ if (IS_ERR(dpu_kms->vbif[VBIF_RT])) {
+ ret = PTR_ERR(dpu_kms->vbif[VBIF_RT]);
+ DPU_ERROR("vbif register memory map failed: %d\n", ret);
+ dpu_kms->vbif[VBIF_RT] = NULL;
+ return ret;
+ }
+
+ dpu_kms->vbif[VBIF_NRT] = msm_ioremap_mdss(mdss_dev,
+dpu_kms->pdev,
+"vbif_nrt_phys");


Do you think a "quiet" version would be better?


Yep, why not.





+ if (IS_ERR(dpu_kms->vbif[VBIF_NRT])) {
+ dpu_kms->vbif[VBIF_NRT] = NULL;
+ DPU_DEBUG("VBIF NRT is not defined");
+ }
+
+ return 0;
+}
+
+static int dpu_kms_mmap_dpu(struct dpu_kms *dpu_kms)
+{
+ struct platform_device *pdev = dpu_kms->pdev;
+ int ret;
+
+ dpu_kms->mmio = msm_ioremap(pdev, "mdp");
+ if (IS_ERR(dpu_kms->mmio)) {
+ ret = PTR_ERR(dpu_kms->mmio);
+ DPU_ERROR("mdp register memory map failed: %d\n", ret);
+ dpu_kms->mmio = NULL;
+ return ret;
+ }
+ DRM_DEBUG("mapped dpu address space @%pK\n", dpu_kms->mmio);
+
+ dpu_kms->vbif[VBIF_RT] = msm_ioremap(pdev, "vbif");
+ if (IS_ERR(dpu_kms->vbif[VBIF_RT])) {
+ ret = PTR_ERR(dpu_kms->vbif[VBIF_RT]);
+ DPU_ERROR("vbif register memory map failed: %d\n", ret);
+ dpu_kms->vbif[VBIF_RT] = NULL;
+ return ret;
+ }
+
+ dpu_kms->vbif[VBIF_NRT] = msm_ioremap_quiet(pdev, "vbif_nrt");
+ if (IS_ERR(dpu_kms->vbif[VBIF_NRT])) {
+ dpu_kms->vbif[VBIF_NRT] = NULL;
+ DPU_DEBUG("VBIF NRT is not defined");
+ }
+
+ return 0;
+}
+
   static int dpu_dev_probe(struct platform_device *pdev)
   {
   struct device *dev = >dev;
@@ -1230,28 +1302,12 @@ static int dpu_dev_probe(struct platform_device *pdev)

   dpu_kms->base.irq = irq;

- dpu_kms->mmio = msm_ioremap(pdev, "mdp");
- if (IS_ERR(dpu_kms->mmio)) {
- ret = PTR_ERR(dpu_kms->mmio);
- DPU_ERROR("mdp register memory map failed: %d\n", ret);
- dpu_kms->mmio = NULL;
- return ret;
- }
- DRM_DEBUG("mapped dpu address space @%pK\n", dpu_kms->mmio);
-
- dpu_kms->vbif[VBIF_RT] = msm_ioremap(pdev, "vbif");
- if (IS_ERR(dpu_kms->vbif[VBIF_RT])) {
- ret = PTR_ERR(dpu_kms->vbif[VBIF_RT]);
- DPU_ERROR("vbif register memory map failed: %d\n", ret);
- dpu_kms->vbif[VBIF_RT] = NULL;
+ if (of_device_is_compatible(dpu_kms->pdev->dev.of_node, "qcom,mdp5"))
+ ret = dpu_kms_mmap_mdp5(dpu_kms);
+ else
+ ret = dpu_kms_mmap_dpu(dpu_kms);
+ if (ret)
   return ret;
- }
-
- 

Re: [PATCH 02/19] drm/dp: Add support for DP tunneling

2024-02-07 Thread Ville Syrjälä
On Tue, Jan 23, 2024 at 12:28:33PM +0200, Imre Deak wrote:
> +static char yes_no_chr(int val)
> +{
> + return val ? 'Y' : 'N';
> +}

We have str_yes_no() already.

v> +
> +#define SKIP_DPRX_CAPS_CHECK BIT(0)
> +#define ALLOW_ALLOCATED_BW_CHANGEBIT(1)
> +
> +static bool tunnel_regs_are_valid(struct drm_dp_tunnel_mgr *mgr,
> +   const struct drm_dp_tunnel_regs *regs,
> +   unsigned int flags)
> +{
> + int drv_group_id = tunnel_reg_drv_group_id(regs);
> + bool check_dprx = !(flags & SKIP_DPRX_CAPS_CHECK);
> + bool ret = true;
> +
> + if (!tunnel_reg_bw_alloc_supported(regs)) {
> + if (tunnel_group_id(drv_group_id)) {
> + drm_dbg_kms(mgr->dev,
> + "DPTUN: A non-zero group ID is only allowed 
> with BWA support\n");
> + ret = false;
> + }
> +
> + if (tunnel_reg(regs, DP_ALLOCATED_BW)) {
> + drm_dbg_kms(mgr->dev,
> + "DPTUN: BW is allocated without BWA 
> support\n");
> + ret = false;
> + }
> +
> + return ret;
> + }
> +
> + if (!tunnel_group_id(drv_group_id)) {
> + drm_dbg_kms(mgr->dev,
> + "DPTUN: BWA support requires a non-zero group 
> ID\n");
> + ret = false;
> + }
> +
> + if (check_dprx && hweight8(tunnel_reg_max_dprx_lane_count(regs)) != 1) {
> + drm_dbg_kms(mgr->dev,
> + "DPTUN: Invalid DPRX lane count: %d\n",
> + tunnel_reg_max_dprx_lane_count(regs));
> +
> + ret = false;
> + }
> +
> + if (check_dprx && !tunnel_reg_max_dprx_rate(regs)) {
> + drm_dbg_kms(mgr->dev,
> + "DPTUN: DPRX rate is 0\n");
> +
> + ret = false;
> + }
> +
> + if (tunnel_reg(regs, DP_ALLOCATED_BW) > tunnel_reg(regs, 
> DP_ESTIMATED_BW)) {
> + drm_dbg_kms(mgr->dev,
> + "DPTUN: Allocated BW %d > estimated BW %d Mb/s\n",
> + DPTUN_BW_ARG(tunnel_reg(regs, DP_ALLOCATED_BW) *
> +  tunnel_reg_bw_granularity(regs)),
> + DPTUN_BW_ARG(tunnel_reg(regs, DP_ESTIMATED_BW) *
> +  tunnel_reg_bw_granularity(regs)));
> +
> + ret = false;
> + }
> +
> + return ret;
> +}
> +
> +static bool tunnel_info_changes_are_valid(struct drm_dp_tunnel *tunnel,
> +   const struct drm_dp_tunnel_regs *regs,
> +   unsigned int flags)
> +{
> + int new_drv_group_id = tunnel_reg_drv_group_id(regs);
> + bool ret = true;
> +
> + if (tunnel->bw_alloc_supported != tunnel_reg_bw_alloc_supported(regs)) {
> + tun_dbg(tunnel,
> + "BW alloc support has changed %c -> %c\n",
> + yes_no_chr(tunnel->bw_alloc_supported),
> + yes_no_chr(tunnel_reg_bw_alloc_supported(regs)));
> +
> + ret = false;
> + }
> +
> + if (tunnel->group->drv_group_id != new_drv_group_id) {
> + tun_dbg(tunnel,
> + "Driver/group ID has changed %d:%d:* -> %d:%d:*\n",
> + tunnel_group_drv_id(tunnel->group->drv_group_id),
> + tunnel_group_id(tunnel->group->drv_group_id),
> + tunnel_group_drv_id(new_drv_group_id),
> + tunnel_group_id(new_drv_group_id));
> +
> + ret = false;
> + }
> +
> + if (!tunnel->bw_alloc_supported)
> + return ret;
> +
> + if (tunnel->bw_granularity != tunnel_reg_bw_granularity(regs)) {
> + tun_dbg(tunnel,
> + "BW granularity has changed: %d -> %d Mb/s\n",
> + DPTUN_BW_ARG(tunnel->bw_granularity),
> + DPTUN_BW_ARG(tunnel_reg_bw_granularity(regs)));
> +
> + ret = false;
> + }
> +
> + /*
> +  * On some devices at least the BW alloc mode enabled status is always
> +  * reported as 0, so skip checking that here.
> +  */

So it's reported as supported and we enable it, but it's never
reported back as being enabled?

> +
> + if (!(flags & ALLOW_ALLOCATED_BW_CHANGE) &&
> + tunnel->allocated_bw !=
> + tunnel_reg(regs, DP_ALLOCATED_BW) * tunnel->bw_granularity) {
> + tun_dbg(tunnel,
> + "Allocated BW has changed: %d -> %d Mb/s\n",
> + DPTUN_BW_ARG(tunnel->allocated_bw),
> + DPTUN_BW_ARG(tunnel_reg(regs, DP_ALLOCATED_BW) * 
> tunnel->bw_granularity));
> +
> + ret = false;
> + }
> +
> + return ret;
> +}
> +
> +static int
> +read_and_verify_tunnel_regs(struct drm_dp_tunnel *tunnel,
> + struct 

Re: [PATCH v3 1/4] drm/msm/mdss: generate MDSS data for MDP5 platforms

2024-02-07 Thread Dmitry Baryshkov
On Wed, 7 Feb 2024 at 20:25, Abhinav Kumar  wrote:
>
>
>
> On 1/5/2024 3:34 PM, Dmitry Baryshkov wrote:
> > Older (mdp5) platforms do not use per-SoC compatible strings. Instead
> > they use a single compat entry 'qcom,mdss'. To facilitate migrating
> > these platforms to the DPU driver provide a way to generate the MDSS /
> > UBWC data at runtime, when the DPU driver asks for it.
> >
> > It is not possible to generate this data structure at the probe time,
> > since some platforms might not have MDP_CLK enabled, which makes reading
> > HW_REV register return 0.
> >
>
> I would have expected a crash if clock was not enabled and we tried to
> access the hw_rev register.

No, for all the platforms I tested it returns 0 instead.
However this doesn't make any difference, we don't read the register
in MDP5 case until all clocks are enabled.

>
> > Signed-off-by: Dmitry Baryshkov 
> > ---
> >   drivers/gpu/drm/msm/msm_mdss.c | 51 
> > ++
> >   1 file changed, 51 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c
> > index 455b2e3a0cdd..566a5dd5b8e8 100644
> > --- a/drivers/gpu/drm/msm/msm_mdss.c
> > +++ b/drivers/gpu/drm/msm/msm_mdss.c
> > @@ -3,6 +3,7 @@
> >* Copyright (c) 2018, The Linux Foundation
> >*/
> >
> > +#include 
> >   #include 
> >   #include 
> >   #include 
> > @@ -213,6 +214,49 @@ static void msm_mdss_setup_ubwc_dec_40(struct msm_mdss 
> > *msm_mdss)
> >   }
> >   }
> >
> > +#define MDSS_HW_MAJ_MIN  GENMASK(31, 16)
> > +
> > +#define MDSS_HW_MSM8996  0x1007
> > +#define MDSS_HW_MSM8937  0x100e
> > +#define MDSS_HW_MSM8956  0x1010
>
> This should be 0x100B in the docs I see.

Yes, I mixed MSM8956 and MSM8953 here. The code support the latter one.

>
> > +#define MDSS_HW_MSM8998  0x3000
> > +#define MDSS_HW_SDM660   0x3002
> > +#define MDSS_HW_SDM630   0x3003
> > +
> > +/*
> > + * MDP5 platforms use generic qcom,mdp5 compat string, so we have to 
> > generate this data
> > + */
> > +static const struct msm_mdss_data *msm_mdss_generate_mdp5_mdss_data(struct 
> > msm_mdss *mdss)
> > +{
> > + struct msm_mdss_data *data;
> > + u32 hw_rev;
> > +
> > + data = devm_kzalloc(mdss->dev, sizeof(*data), GFP_KERNEL);
> > + if (!data)
> > + return NULL;
> > +
> > + hw_rev = readl_relaxed(mdss->mmio + HW_REV);
> > + hw_rev = FIELD_GET(MDSS_HW_MAJ_MIN, hw_rev);
> > +
> > + if (hw_rev == MDSS_HW_MSM8996 ||
> > + hw_rev == MDSS_HW_MSM8937 ||
> > + hw_rev == MDSS_HW_MSM8956 ||
> > + hw_rev == MDSS_HW_MSM8998 ||
> > + hw_rev == MDSS_HW_SDM660 ||
> > + hw_rev == MDSS_HW_SDM630) {
> > + data->ubwc_dec_version = UBWC_1_0;
> > + data->ubwc_enc_version = UBWC_1_0;
> > + }
> > +
> > + if (hw_rev == MDSS_HW_MSM8996 ||
> > + hw_rev == MDSS_HW_MSM8998)
> > + data->highest_bank_bit = 2;
> > + else
> > + data->highest_bank_bit = 1;
> > +
> > + return data;
> > +}
> > +
> >   const struct msm_mdss_data *msm_mdss_get_mdss_data(struct device *dev)
> >   {
> >   struct msm_mdss *mdss;
> > @@ -222,6 +266,13 @@ const struct msm_mdss_data 
> > *msm_mdss_get_mdss_data(struct device *dev)
> >
> >   mdss = dev_get_drvdata(dev);
> >
> > + /*
> > +  * We could not do it at the probe time, since hw revision register 
> > was
> > +  * not readable. Fill data structure now for the MDP5 platforms.
> > +  */
> > + if (!mdss->mdss_data && mdss->is_mdp5)
> > + mdss->mdss_data = msm_mdss_generate_mdp5_mdss_data(mdss);
> > +
> >   return mdss->mdss_data;
> >   }
> >
> >



-- 
With best wishes
Dmitry


Re: [PATCH v3 2/4] drm/msm/dpu: support binding to the mdp5 devices

2024-02-07 Thread Dmitry Baryshkov
On Wed, 7 Feb 2024 at 20:48, Abhinav Kumar  wrote:
>
>
>
> On 1/5/2024 3:34 PM, Dmitry Baryshkov wrote:
> > Existing MDP5 devices have slightly different bindings. The main
> > register region is called `mdp_phys' instead of `mdp'. Also vbif
> > register regions are a part of the parent, MDSS device. Add support for
> > handling this binding differences.
> >
> > Signed-off-by: Dmitry Baryshkov 
> > ---
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 98 
> > ++---
> >   drivers/gpu/drm/msm/msm_drv.h   |  3 +
> >   drivers/gpu/drm/msm/msm_io_utils.c  | 13 +
> >   3 files changed, 93 insertions(+), 21 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> > index 723cc1d82143..aa9e0ad33ebb 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> > @@ -1197,6 +1197,78 @@ static int dpu_kms_init(struct drm_device *ddev)
> >   return 0;
> >   }
> >
> > +static int dpu_kms_mmap_mdp5(struct dpu_kms *dpu_kms)
> > +{
> > + struct platform_device *pdev = dpu_kms->pdev;
> > + struct platform_device *mdss_dev;
> > + int ret;
> > +
> > + if (dpu_kms->pdev->dev.bus != _bus_type)
> > + return -EINVAL;
> > +
>
> !dev_is_platform() perhaps?

looks good

>
> But I would like to understand this check a bit more. Can you pls
> explain for which case this check was added?

It is necessary to be sure that we can perform to_platform_device() on
the next line.

>
> > + mdss_dev = to_platform_device(dpu_kms->pdev->dev.parent);
> > +
> > + dpu_kms->mmio = msm_ioremap(pdev, "mdp_phys");
> > + if (IS_ERR(dpu_kms->mmio)) {
> > + ret = PTR_ERR(dpu_kms->mmio);
> > + DPU_ERROR("mdp register memory map failed: %d\n", ret);
> > + dpu_kms->mmio = NULL;
> > + return ret;
> > + }
> > + DRM_DEBUG("mapped dpu address space @%pK\n", dpu_kms->mmio);
> > +
> > + dpu_kms->vbif[VBIF_RT] = msm_ioremap_mdss(mdss_dev,
> > +   dpu_kms->pdev,
> > +   "vbif_phys");
> > + if (IS_ERR(dpu_kms->vbif[VBIF_RT])) {
> > + ret = PTR_ERR(dpu_kms->vbif[VBIF_RT]);
> > + DPU_ERROR("vbif register memory map failed: %d\n", ret);
> > + dpu_kms->vbif[VBIF_RT] = NULL;
> > + return ret;
> > + }
> > +
> > + dpu_kms->vbif[VBIF_NRT] = msm_ioremap_mdss(mdss_dev,
> > +dpu_kms->pdev,
> > +"vbif_nrt_phys");
>
> Do you think a "quiet" version would be better?

Yep, why not.

>
>
> > + if (IS_ERR(dpu_kms->vbif[VBIF_NRT])) {
> > + dpu_kms->vbif[VBIF_NRT] = NULL;
> > + DPU_DEBUG("VBIF NRT is not defined");
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int dpu_kms_mmap_dpu(struct dpu_kms *dpu_kms)
> > +{
> > + struct platform_device *pdev = dpu_kms->pdev;
> > + int ret;
> > +
> > + dpu_kms->mmio = msm_ioremap(pdev, "mdp");
> > + if (IS_ERR(dpu_kms->mmio)) {
> > + ret = PTR_ERR(dpu_kms->mmio);
> > + DPU_ERROR("mdp register memory map failed: %d\n", ret);
> > + dpu_kms->mmio = NULL;
> > + return ret;
> > + }
> > + DRM_DEBUG("mapped dpu address space @%pK\n", dpu_kms->mmio);
> > +
> > + dpu_kms->vbif[VBIF_RT] = msm_ioremap(pdev, "vbif");
> > + if (IS_ERR(dpu_kms->vbif[VBIF_RT])) {
> > + ret = PTR_ERR(dpu_kms->vbif[VBIF_RT]);
> > + DPU_ERROR("vbif register memory map failed: %d\n", ret);
> > + dpu_kms->vbif[VBIF_RT] = NULL;
> > + return ret;
> > + }
> > +
> > + dpu_kms->vbif[VBIF_NRT] = msm_ioremap_quiet(pdev, "vbif_nrt");
> > + if (IS_ERR(dpu_kms->vbif[VBIF_NRT])) {
> > + dpu_kms->vbif[VBIF_NRT] = NULL;
> > + DPU_DEBUG("VBIF NRT is not defined");
> > + }
> > +
> > + return 0;
> > +}
> > +
> >   static int dpu_dev_probe(struct platform_device *pdev)
> >   {
> >   struct device *dev = >dev;
> > @@ -1230,28 +1302,12 @@ static int dpu_dev_probe(struct platform_device 
> > *pdev)
> >
> >   dpu_kms->base.irq = irq;
> >
> > - dpu_kms->mmio = msm_ioremap(pdev, "mdp");
> > - if (IS_ERR(dpu_kms->mmio)) {
> > - ret = PTR_ERR(dpu_kms->mmio);
> > - DPU_ERROR("mdp register memory map failed: %d\n", ret);
> > - dpu_kms->mmio = NULL;
> > - return ret;
> > - }
> > - DRM_DEBUG("mapped dpu address space @%pK\n", dpu_kms->mmio);
> > -
> > - dpu_kms->vbif[VBIF_RT] = msm_ioremap(pdev, "vbif");
> > - if (IS_ERR(dpu_kms->vbif[VBIF_RT])) {
> > - ret = PTR_ERR(dpu_kms->vbif[VBIF_RT]);
> > - DPU_ERROR("vbif register memory map failed: %d\n", ret);
> > - dpu_kms->vbif[VBIF_RT] = NULL;
> 

[no subject]

2024-02-07 Thread Rob Clark
Hi Dave,

A few fixes for v6.8, description below

The following changes since commit d4ca26ac4be0d9aea7005c40df75e6775749671b:

  drm/msm/dp: call dp_display_get_next_bridge() during probe
(2023-12-14 09:27:46 +0200)

are available in the Git repository at:

  https://gitlab.freedesktop.org/drm/msm.git tags/drm-msm-fixes-2024-02-07

for you to fetch changes up to 8d35217149daa33358c284aca6a56d5ab92cfc6c:

  drm/msm/mdss: specify cfg bandwidth for SDM670 (2024-01-25 14:36:04 -0800)


Fixes for v6.8-rc4

DPU:
- fix for kernel doc warnings and smatch warnings in dpu_encoder
- fix for smatch warning in dpu_encoder
- fix the bus bandwidth value for SDM670

DP:
- fixes to handle unknown bpc case correctly for DP. The current code was
  spilling over into other bits of DP configuration register, had to be
  fixed to avoid the extra shifts which were causing the spill over
- fix for MISC0 programming in DP driver to program the correct
  colorimetry value

GPU:
- dmabuf vmap fix
- a610 UBWC corruption fix (incorrect hbb)
- revert a commit that was making GPU recovery unreliable


Abhinav Kumar (1):
  drm/msm/dpu: check for valid hw_pp in dpu_encoder_helper_phys_cleanup

Dmitry Baryshkov (1):
  drm/msm/mdss: specify cfg bandwidth for SDM670

Kuogee Hsieh (2):
  drm/msms/dp: fixed link clock divider bits be over written in
BPC unknown case
  drm/msm/dp: return correct Colorimetry for DP_TEST_DYNAMIC_RANGE_CEA case

Randy Dunlap (1):
  drm/msm/dpu: fix kernel-doc warnings

 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c |  8 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c  |  3 ++-
 drivers/gpu/drm/msm/dp/dp_ctrl.c|  5 -
 drivers/gpu/drm/msm/dp/dp_link.c| 22 ++
 drivers/gpu/drm/msm/dp/dp_reg.h |  3 +++
 drivers/gpu/drm/msm/msm_mdss.c  |  1 +
 6 files changed, 22 insertions(+), 20 deletions(-)


Re: [RFC] drm/i915: Add GuC submission interface version query

2024-02-07 Thread John Harrison

On 2/7/2024 11:43, Souza, Jose wrote:

On Wed, 2024-02-07 at 11:34 -0800, John Harrison wrote:

On 2/7/2024 10:49, Tvrtko Ursulin wrote:

On 07/02/2024 18:12, John Harrison wrote:

On 2/7/2024 03:56, Tvrtko Ursulin wrote:

From: Tvrtko Ursulin 

Add a new query to the GuC submission interface version.

Mesa intends to use this information to check for old firmware versions
with a known bug where using the render and compute command streamers
simultaneously can cause GPU hangs due issues in firmware scheduling.

Based on patches from Vivaik and Joonas.

There is a little bit of an open around the width required for
versions.
While the GuC FW iface tells they are u8, i915 GuC code uses u32:

   #define CSS_SW_VERSION_UC_MAJOR   (0xFF << 16)
   #define CSS_SW_VERSION_UC_MINOR   (0xFF << 8)
   #define CSS_SW_VERSION_UC_PATCH   (0xFF << 0)
...
   struct intel_uc_fw_ver {
   u32 major;
   u32 minor;
   u32 patch;
   u32 build;
   };

This is copied from generic code which supports firmwares other than
GuC. Only GuC promises to use 8-bit version components. Other
firmwares very definitely do not. There is no open.

Ack.


So we could make the query u8, and refactor the struct intel_uc_fw_ver
to use u8, or not. To avoid any doubts on why are we assigning u32 to
u8 I simply opted to use u64. Which avoids the need to add any padding
too.

I don't follow how potential 8 vs 32 confusion means jump to 64?!

Suggestion was to use u8 in the uapi in order to align with GuC FW ABI
(or however it's called), in which case there would be:

    ver.major = guc->submission_version.major;

which would be:

    (u8) = (u32)

And I was anticipating someone not liking that either. Using too wide
u64 simply avoids the need to add a padding element to the uapi struct.

If you are positive we need to include a branch number, even though it
does not seem to be implemented in the code even(*) then I can make
uapi 4x u32 and achieve the same.

It's not implemented in the code because we've never had to, and it is
yet another train wreck waiting to happen. There are a bunch of issues
at different levels that need to be resolved. But that is all in the
kernel and/or firmware and so can be added by a later kernel update when
necessary. However, if the UMDs are not already taking it into account
or its not even in the UAPI, then we can't back fill in the kernel
later, we are just broken.

This sounds to me like a firmware version for internal testing or for 
pre-production HW, would any branched firmware be released to customers?
See comments below. Branching is about back porting critical fixes to 
older releases. I.e. supporting LTS releases. There is absolutely 
nothing internal only or testing related about branching.


Just because we haven't had to do so yet doesn't mean we won't need to 
do so tomorrow.


John.




(*)
static void uc_unpack_css_version(struct intel_uc_fw_ver *ver, u32
css_value)
{
 /* Get version numbers from the CSS header */
 ver->major = FIELD_GET(CSS_SW_VERSION_UC_MAJOR, css_value);
 ver->minor = FIELD_GET(CSS_SW_VERSION_UC_MINOR, css_value);
 ver->patch = FIELD_GET(CSS_SW_VERSION_UC_PATCH, css_value);
}

No branch field in the CSS header?

I think there is, it's just not officially implemented yet.


And Why is UMD supposed to reject a non-zero branch? Like how would
1.1.3.0 be fine and 1.1.3.1 be bad? I don't get it. But anyway, I can
respin if you definitely confirm.

Because that is backwards. The branch number goes at the front.

So, for example (using made up numbers, I don't recall offhand what
versions we have where) say we currently have 0.1.3.0 in tip and 0.1.1.0
in the last LTS. We then need to ship a critical security fix and back
port it to the LTS. Tip becomes 0.1.3.1 but the LTS can't become 0.1.1.1
because that version already exists in the history of tip and does not
contain the fix. So the LTS gets branched to 1.1.0.0. We then have both
branches potentially moving forwards with completely independent versioning.

Exactly the same as 5.8.x, 5.9,y, 6.0.z, etc in the Linux kernel
versioning. You cannot make any assumptions about what might be in
1.4.5.6 compared to 0.1.2.3. 1.4.5.6 could actually 0.1.0.3 with a stack
of security fixes but none of the features, workarounds or bug fixes
that are in 0.1.2.3.

Hence, if the branch number changes then all bets are off. You have to
start over and reject anything you do not explicitly know about.

This is why we were saying that exposing version numbers to UMDs breaks
down horribly as soon as we have to start branching. There is no clean
or simple way to do this.

John.



Regards,

Tvrtko


Compile tested only.

Signed-off-by: Tvrtko Ursulin 
Cc: Kenneth Graunke 
Cc: Jose Souza 
Cc: Sagar Ghuge 
Cc: Paulo Zanoni 
Cc: John Harrison 
Cc: Rodrigo Vivi 
Cc: Jani Nikula 
Cc: Tvrtko Ursulin 
Cc: Vivaik Balasubrawmanian 
---
   drivers/gpu/drm/i915/i915_query.c | 32

Re: [PATCH v3 4/4] drm/msm/dpu: add support for SDM660 and SDM630 platforms

2024-02-07 Thread Abhinav Kumar




On 1/5/2024 3:34 PM, Dmitry Baryshkov wrote:

Bring in hardware support for the SDM660 and SDM630 platforms, which
belong to the same DPU generation as MSM8998.

Note, by default these platforms are still handled by the MDP5 driver
unless the `msm.prefer_mdp5=false' parameter is provided.

Co-developed-by: Konrad Dybcio 
Signed-off-by: Konrad Dybcio 
Signed-off-by: Dmitry Baryshkov 
---
  .../gpu/drm/msm/disp/dpu1/catalog/dpu_3_2_sdm660.h | 291 +
  .../gpu/drm/msm/disp/dpu1/catalog/dpu_3_3_sdm630.h | 225 
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c |   2 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |   2 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c|   2 +
  drivers/gpu/drm/msm/msm_drv.c  |   2 +
  6 files changed, 524 insertions(+)



I cross-checked a few entries with the downstream sources but certainly 
not all, but based on whatever I checked all the entries were correct in 
the catalog.


Reviewed-by: Abhinav Kumar 


Re: [RFC] drm/i915: Add GuC submission interface version query

2024-02-07 Thread Souza, Jose
On Wed, 2024-02-07 at 11:34 -0800, John Harrison wrote:
> On 2/7/2024 10:49, Tvrtko Ursulin wrote:
> > On 07/02/2024 18:12, John Harrison wrote:
> > > On 2/7/2024 03:56, Tvrtko Ursulin wrote:
> > > > From: Tvrtko Ursulin 
> > > > 
> > > > Add a new query to the GuC submission interface version.
> > > > 
> > > > Mesa intends to use this information to check for old firmware versions
> > > > with a known bug where using the render and compute command streamers
> > > > simultaneously can cause GPU hangs due issues in firmware scheduling.
> > > > 
> > > > Based on patches from Vivaik and Joonas.
> > > > 
> > > > There is a little bit of an open around the width required for 
> > > > versions.
> > > > While the GuC FW iface tells they are u8, i915 GuC code uses u32:
> > > > 
> > > >   #define CSS_SW_VERSION_UC_MAJOR   (0xFF << 16)
> > > >   #define CSS_SW_VERSION_UC_MINOR   (0xFF << 8)
> > > >   #define CSS_SW_VERSION_UC_PATCH   (0xFF << 0)
> > > > ...
> > > >   struct intel_uc_fw_ver {
> > > >   u32 major;
> > > >   u32 minor;
> > > >   u32 patch;
> > > >   u32 build;
> > > >   };
> > > This is copied from generic code which supports firmwares other than 
> > > GuC. Only GuC promises to use 8-bit version components. Other 
> > > firmwares very definitely do not. There is no open.
> > 
> > Ack.
> > 
> > > > 
> > > > So we could make the query u8, and refactor the struct intel_uc_fw_ver
> > > > to use u8, or not. To avoid any doubts on why are we assigning u32 to
> > > > u8 I simply opted to use u64. Which avoids the need to add any padding
> > > > too.
> > > I don't follow how potential 8 vs 32 confusion means jump to 64?!
> > 
> > Suggestion was to use u8 in the uapi in order to align with GuC FW ABI 
> > (or however it's called), in which case there would be:
> > 
> >    ver.major = guc->submission_version.major;
> > 
> > which would be:
> > 
> >    (u8) = (u32)
> > 
> > And I was anticipating someone not liking that either. Using too wide 
> > u64 simply avoids the need to add a padding element to the uapi struct.
> > 
> > If you are positive we need to include a branch number, even though it 
> > does not seem to be implemented in the code even(*) then I can make 
> > uapi 4x u32 and achieve the same.
> It's not implemented in the code because we've never had to, and it is 
> yet another train wreck waiting to happen. There are a bunch of issues 
> at different levels that need to be resolved. But that is all in the 
> kernel and/or firmware and so can be added by a later kernel update when 
> necessary. However, if the UMDs are not already taking it into account 
> or its not even in the UAPI, then we can't back fill in the kernel 
> later, we are just broken.

This sounds to me like a firmware version for internal testing or for 
pre-production HW, would any branched firmware be released to customers?

> 
> > 
> > (*)
> > static void uc_unpack_css_version(struct intel_uc_fw_ver *ver, u32 
> > css_value)
> > {
> > /* Get version numbers from the CSS header */
> > ver->major = FIELD_GET(CSS_SW_VERSION_UC_MAJOR, css_value);
> > ver->minor = FIELD_GET(CSS_SW_VERSION_UC_MINOR, css_value);
> > ver->patch = FIELD_GET(CSS_SW_VERSION_UC_PATCH, css_value);
> > }
> > 
> > No branch field in the CSS header?
> I think there is, it's just not officially implemented yet.
> 
> > 
> > And Why is UMD supposed to reject a non-zero branch? Like how would 
> > 1.1.3.0 be fine and 1.1.3.1 be bad? I don't get it. But anyway, I can 
> > respin if you definitely confirm.
> Because that is backwards. The branch number goes at the front.
> 
> So, for example (using made up numbers, I don't recall offhand what 
> versions we have where) say we currently have 0.1.3.0 in tip and 0.1.1.0 
> in the last LTS. We then need to ship a critical security fix and back 
> port it to the LTS. Tip becomes 0.1.3.1 but the LTS can't become 0.1.1.1 
> because that version already exists in the history of tip and does not 
> contain the fix. So the LTS gets branched to 1.1.0.0. We then have both 
> branches potentially moving forwards with completely independent versioning.
> 
> Exactly the same as 5.8.x, 5.9,y, 6.0.z, etc in the Linux kernel 
> versioning. You cannot make any assumptions about what might be in 
> 1.4.5.6 compared to 0.1.2.3. 1.4.5.6 could actually 0.1.0.3 with a stack 
> of security fixes but none of the features, workarounds or bug fixes 
> that are in 0.1.2.3.
> 
> Hence, if the branch number changes then all bets are off. You have to 
> start over and reject anything you do not explicitly know about.
> 
> This is why we were saying that exposing version numbers to UMDs breaks 
> down horribly as soon as we have to start branching. There is no clean 
> or simple way to do this.
> 
> John.
> 
> 
> > 
> > Regards,
> > 
> > Tvrtko
> > 
> > > > 
> > > > Compile tested only.
> > > > 
> > > > Signed-off-by: Tvrtko Ursulin 
> > > > Cc: Kenneth Graunke 
> 

Re: [PATCH v2] drm/msm/dpu: remove CRTC frame event callback registration

2024-02-07 Thread Dmitry Baryshkov
On Wed, 7 Feb 2024 at 19:52, Abhinav Kumar  wrote:
>
>
>
> On 10/5/2023 3:06 PM, Dmitry Baryshkov wrote:
> > The frame event callback is always set to dpu_crtc_frame_event_cb() (or
> > to NULL) and the data is always either the CRTC itself or NULL
> > (correpondingly). Thus drop the event callback registration, call the
> > dpu_crtc_frame_event_cb() directly and gate on the dpu_enc->crtc
> > assigned using dpu_encoder_assign_crtc().
> >
>
> The idea behind the registration was for CRTC to register for events if
> it wants to and perhaps have different callbacks for different events
> through a common registration mechanism and encoder need not know each
> dpu_crtc calls as most of the time we dont want encoder to go back to
> crtc to look up what its APIs are.
>
> But, we are always registering today and have only one callback, so it
> kind of makes it an additional redundant wrapper. So I guess, once again
> one of those things which , seems not necessary with the current code
> but nothing really wrong with it.
>
> Anyway, couple of comments below.
>
> > Signed-off-by: Dmitry Baryshkov 
> > ---
> >
> > This patch was previously posted as a part of the [1]
> >
> > Changes since v1:
> > - Rebased on top of linux-next
> >
> > [1] https://patchwork.freedesktop.org/series/112353/
> >
> > ---
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 17 +
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h| 14 +++
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 41 +++--
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 10 -
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h   |  4 --
> >   5 files changed, 21 insertions(+), 65 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > index 8ce7586e2ddf..dec5417b69d8 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > @@ -669,18 +669,8 @@ static void dpu_crtc_frame_event_work(struct 
> > kthread_work *work)
> >   DPU_ATRACE_END("crtc_frame_event");
> >   }
> >
> > -/*
> > - * dpu_crtc_frame_event_cb - crtc frame event callback API. CRTC module
> > - * registers this API to encoder for all frame event callbacks like
> > - * frame_error, frame_done, idle_timeout, etc. Encoder may call different 
> > events
> > - * from different context - IRQ, user thread, commit_thread, etc. Each 
> > event
> > - * should be carefully reviewed and should be processed in proper task 
> > context
> > - * to avoid schedulin delay or properly manage the irq context's bottom 
> > half
> > - * processing.
> > - */
> > -static void dpu_crtc_frame_event_cb(void *data, u32 event)
> > +void dpu_crtc_frame_event_cb(struct drm_crtc *crtc, u32 event)
> >   {
> > - struct drm_crtc *crtc = (struct drm_crtc *)data;
> >   struct dpu_crtc *dpu_crtc;
> >   struct msm_drm_private *priv;
> >   struct dpu_crtc_frame_event *fevent;
> > @@ -1102,9 +1092,6 @@ static void dpu_crtc_disable(struct drm_crtc *crtc,
> >
> >   dpu_core_perf_crtc_update(crtc, 0);
> >
> > - drm_for_each_encoder_mask(encoder, crtc->dev, 
> > crtc->state->encoder_mask)
> > - dpu_encoder_register_frame_event_callback(encoder, NULL, 
> > NULL);
> > -
> >   memset(cstate->mixers, 0, sizeof(cstate->mixers));
> >   cstate->num_mixers = 0;
> >
> > @@ -1143,8 +1130,6 @@ static void dpu_crtc_enable(struct drm_crtc *crtc,
> >*/
> >   if (dpu_encoder_get_intf_mode(encoder) == INTF_MODE_VIDEO)
> >   request_bandwidth = true;
> > - dpu_encoder_register_frame_event_callback(encoder,
> > - dpu_crtc_frame_event_cb, (void *)crtc);
> >   }
> >
> >   if (request_bandwidth)
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h 
> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> > index 539b68b1626a..3aa536d95721 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> > @@ -300,4 +300,18 @@ static inline enum dpu_crtc_client_type 
> > dpu_crtc_get_client_type(
> >   return crtc && crtc->state ? RT_CLIENT : NRT_CLIENT;
> >   }
> >
> > +/**
> > + * dpu_crtc_frame_event_cb - crtc frame event callback API
> > + * @crtc: Pointer to crtc
> > + * @event: Event to process
> > + *
> > + * CRTC module registers this API to encoder for all frame event callbacks 
> > like
> > + * frame_error, frame_done, idle_timeout, etc. Encoder may call different 
> > events
> > + * from different context - IRQ, user thread, commit_thread, etc. Each 
> > event
> > + * should be carefully reviewed and should be processed in proper task 
> > context
> > + * to avoid schedulin delay or properly manage the irq context's bottom 
> > half
> > + * processing.
> > + */
>
> This doc is no longer correct.
>
> CRTC module no longer registers anything.

Ack. I should have fixed this c

>
> > +void dpu_crtc_frame_event_cb(struct 

Re: [RFC] drm/i915: Add GuC submission interface version query

2024-02-07 Thread John Harrison

On 2/7/2024 10:49, Tvrtko Ursulin wrote:

On 07/02/2024 18:12, John Harrison wrote:

On 2/7/2024 03:56, Tvrtko Ursulin wrote:

From: Tvrtko Ursulin 

Add a new query to the GuC submission interface version.

Mesa intends to use this information to check for old firmware versions
with a known bug where using the render and compute command streamers
simultaneously can cause GPU hangs due issues in firmware scheduling.

Based on patches from Vivaik and Joonas.

There is a little bit of an open around the width required for 
versions.

While the GuC FW iface tells they are u8, i915 GuC code uses u32:

  #define CSS_SW_VERSION_UC_MAJOR   (0xFF << 16)
  #define CSS_SW_VERSION_UC_MINOR   (0xFF << 8)
  #define CSS_SW_VERSION_UC_PATCH   (0xFF << 0)
...
  struct intel_uc_fw_ver {
  u32 major;
  u32 minor;
  u32 patch;
  u32 build;
  };
This is copied from generic code which supports firmwares other than 
GuC. Only GuC promises to use 8-bit version components. Other 
firmwares very definitely do not. There is no open.


Ack.



So we could make the query u8, and refactor the struct intel_uc_fw_ver
to use u8, or not. To avoid any doubts on why are we assigning u32 to
u8 I simply opted to use u64. Which avoids the need to add any padding
too.

I don't follow how potential 8 vs 32 confusion means jump to 64?!


Suggestion was to use u8 in the uapi in order to align with GuC FW ABI 
(or however it's called), in which case there would be:


   ver.major = guc->submission_version.major;

which would be:

   (u8) = (u32)

And I was anticipating someone not liking that either. Using too wide 
u64 simply avoids the need to add a padding element to the uapi struct.


If you are positive we need to include a branch number, even though it 
does not seem to be implemented in the code even(*) then I can make 
uapi 4x u32 and achieve the same.
It's not implemented in the code because we've never had to, and it is 
yet another train wreck waiting to happen. There are a bunch of issues 
at different levels that need to be resolved. But that is all in the 
kernel and/or firmware and so can be added by a later kernel update when 
necessary. However, if the UMDs are not already taking it into account 
or its not even in the UAPI, then we can't back fill in the kernel 
later, we are just broken.




(*)
static void uc_unpack_css_version(struct intel_uc_fw_ver *ver, u32 
css_value)

{
/* Get version numbers from the CSS header */
ver->major = FIELD_GET(CSS_SW_VERSION_UC_MAJOR, css_value);
ver->minor = FIELD_GET(CSS_SW_VERSION_UC_MINOR, css_value);
ver->patch = FIELD_GET(CSS_SW_VERSION_UC_PATCH, css_value);
}

No branch field in the CSS header?

I think there is, it's just not officially implemented yet.



And Why is UMD supposed to reject a non-zero branch? Like how would 
1.1.3.0 be fine and 1.1.3.1 be bad? I don't get it. But anyway, I can 
respin if you definitely confirm.

Because that is backwards. The branch number goes at the front.

So, for example (using made up numbers, I don't recall offhand what 
versions we have where) say we currently have 0.1.3.0 in tip and 0.1.1.0 
in the last LTS. We then need to ship a critical security fix and back 
port it to the LTS. Tip becomes 0.1.3.1 but the LTS can't become 0.1.1.1 
because that version already exists in the history of tip and does not 
contain the fix. So the LTS gets branched to 1.1.0.0. We then have both 
branches potentially moving forwards with completely independent versioning.


Exactly the same as 5.8.x, 5.9,y, 6.0.z, etc in the Linux kernel 
versioning. You cannot make any assumptions about what might be in 
1.4.5.6 compared to 0.1.2.3. 1.4.5.6 could actually 0.1.0.3 with a stack 
of security fixes but none of the features, workarounds or bug fixes 
that are in 0.1.2.3.


Hence, if the branch number changes then all bets are off. You have to 
start over and reject anything you do not explicitly know about.


This is why we were saying that exposing version numbers to UMDs breaks 
down horribly as soon as we have to start branching. There is no clean 
or simple way to do this.


John.




Regards,

Tvrtko



Compile tested only.

Signed-off-by: Tvrtko Ursulin 
Cc: Kenneth Graunke 
Cc: Jose Souza 
Cc: Sagar Ghuge 
Cc: Paulo Zanoni 
Cc: John Harrison 
Cc: Rodrigo Vivi 
Cc: Jani Nikula 
Cc: Tvrtko Ursulin 
Cc: Vivaik Balasubrawmanian 
---
  drivers/gpu/drm/i915/i915_query.c | 32 
+++

  include/uapi/drm/i915_drm.h   | 11 +++
  2 files changed, 43 insertions(+)

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

index 00871ef99792..999687f6a3d4 100644
--- a/drivers/gpu/drm/i915/i915_query.c
+++ b/drivers/gpu/drm/i915/i915_query.c
@@ -551,6 +551,37 @@ static int query_hwconfig_blob(struct 
drm_i915_private *i915,

  return hwconfig->size;
  }
+static int
+query_guc_submission_version(struct drm_i915_private *i915,
+ 

Re: [PATCH v3 3/4] drm/msm: add a kernel param to select between MDP5 and DPU drivers

2024-02-07 Thread Abhinav Kumar




On 1/5/2024 3:34 PM, Dmitry Baryshkov wrote:

For some of the platforms (e.g. SDM660, SDM630, MSM8996, etc.) it is
possible to support this platform via the DPU driver (e.g. to provide
support for DP, multirect, etc). Add a modparam to be able to switch
between these two drivers.

All platforms supported by both drivers are by default handled by the
MDP5 driver. To let them be handled by the DPU driver pass the
`msm.prefer_mdp5=false` kernel param.

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


Reviewed-by: Abhinav Kumar 


Re: [RFC] drm/i915: Add GuC submission interface version query

2024-02-07 Thread Tvrtko Ursulin



On 07/02/2024 18:12, John Harrison wrote:

On 2/7/2024 03:56, Tvrtko Ursulin wrote:

From: Tvrtko Ursulin 

Add a new query to the GuC submission interface version.

Mesa intends to use this information to check for old firmware versions
with a known bug where using the render and compute command streamers
simultaneously can cause GPU hangs due issues in firmware scheduling.

Based on patches from Vivaik and Joonas.

There is a little bit of an open around the width required for versions.
While the GuC FW iface tells they are u8, i915 GuC code uses u32:

  #define CSS_SW_VERSION_UC_MAJOR   (0xFF << 16)
  #define CSS_SW_VERSION_UC_MINOR   (0xFF << 8)
  #define CSS_SW_VERSION_UC_PATCH   (0xFF << 0)
...
  struct intel_uc_fw_ver {
  u32 major;
  u32 minor;
  u32 patch;
  u32 build;
  };
This is copied from generic code which supports firmwares other than 
GuC. Only GuC promises to use 8-bit version components. Other firmwares 
very definitely do not. There is no open.


Ack.



So we could make the query u8, and refactor the struct intel_uc_fw_ver
to use u8, or not. To avoid any doubts on why are we assigning u32 to
u8 I simply opted to use u64. Which avoids the need to add any padding
too.

I don't follow how potential 8 vs 32 confusion means jump to 64?!


Suggestion was to use u8 in the uapi in order to align with GuC FW ABI (or 
however it's called), in which case there would be:

   ver.major = guc->submission_version.major;

which would be:

   (u8) = (u32)

And I was anticipating someone not liking that either. Using too wide u64 
simply avoids the need to add a padding element to the uapi struct.

If you are positive we need to include a branch number, even though it does not 
seem to be implemented in the code even(*) then I can make uapi 4x u32 and 
achieve the same.

(*)
static void uc_unpack_css_version(struct intel_uc_fw_ver *ver, u32 css_value)
{
/* Get version numbers from the CSS header */
ver->major = FIELD_GET(CSS_SW_VERSION_UC_MAJOR, css_value);
ver->minor = FIELD_GET(CSS_SW_VERSION_UC_MINOR, css_value);
ver->patch = FIELD_GET(CSS_SW_VERSION_UC_PATCH, css_value);
}

No branch field in the CSS header?

And Why is UMD supposed to reject a non-zero branch? Like how would 1.1.3.0 be 
fine and 1.1.3.1 be bad? I don't get it. But anyway, I can respin if you 
definitely confirm.

Regards,

Tvrtko



Compile tested only.

Signed-off-by: Tvrtko Ursulin 
Cc: Kenneth Graunke 
Cc: Jose Souza 
Cc: Sagar Ghuge 
Cc: Paulo Zanoni 
Cc: John Harrison 
Cc: Rodrigo Vivi 
Cc: Jani Nikula 
Cc: Tvrtko Ursulin 
Cc: Vivaik Balasubrawmanian 
---
  drivers/gpu/drm/i915/i915_query.c | 32 +++
  include/uapi/drm/i915_drm.h   | 11 +++
  2 files changed, 43 insertions(+)

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

index 00871ef99792..999687f6a3d4 100644
--- a/drivers/gpu/drm/i915/i915_query.c
+++ b/drivers/gpu/drm/i915/i915_query.c
@@ -551,6 +551,37 @@ static int query_hwconfig_blob(struct 
drm_i915_private *i915,

  return hwconfig->size;
  }
+static int
+query_guc_submission_version(struct drm_i915_private *i915,
+ struct drm_i915_query_item *query)
+{
+    struct drm_i915_query_guc_submission_version __user *query_ptr =
+    u64_to_user_ptr(query->data_ptr);
+    struct drm_i915_query_guc_submission_version ver;
+    struct intel_guc *guc = _gt(i915)->uc.guc;
+    const size_t size = sizeof(ver);
+    int ret;
+
+    if (!intel_uc_uses_guc_submission(_gt(i915)->uc))
+    return -ENODEV;
+
+    ret = copy_query_item(, size, size, query);
+    if (ret != 0)
+    return ret;
+
+    if (ver.major || ver.minor || ver.patch)
+    return -EINVAL;
+
+    ver.major = guc->submission_version.major;
+    ver.minor = guc->submission_version.minor;
+    ver.patch = guc->submission_version.patch;
This needs to include the branch version (currently set to zero) in the 
definition. And the UMD needs to barf if branch comes back as non-zero. 
I.e. there is no guarantee that a branched version will have the w/a + 
fix that they are wanting.


John.



+
+    if (copy_to_user(query_ptr, , size))
+    return -EFAULT;
+
+    return 0;
+}
+
  static int (* const i915_query_funcs[])(struct drm_i915_private 
*dev_priv,

  struct drm_i915_query_item *query_item) = {
  query_topology_info,
@@ -559,6 +590,7 @@ static int (* const i915_query_funcs[])(struct 
drm_i915_private *dev_priv,

  query_memregion_info,
  query_hwconfig_blob,
  query_geometry_subslices,
+    query_guc_submission_version,
  };
  int i915_query_ioctl(struct drm_device *dev, void *data, struct 
drm_file *file)

diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 550c496ce76d..d80d9b5e1eda 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -3038,6 

Re: [PATCH v3 2/4] drm/msm/dpu: support binding to the mdp5 devices

2024-02-07 Thread Abhinav Kumar




On 1/5/2024 3:34 PM, Dmitry Baryshkov wrote:

Existing MDP5 devices have slightly different bindings. The main
register region is called `mdp_phys' instead of `mdp'. Also vbif
register regions are a part of the parent, MDSS device. Add support for
handling this binding differences.

Signed-off-by: Dmitry Baryshkov 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 98 ++---
  drivers/gpu/drm/msm/msm_drv.h   |  3 +
  drivers/gpu/drm/msm/msm_io_utils.c  | 13 +
  3 files changed, 93 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 723cc1d82143..aa9e0ad33ebb 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -1197,6 +1197,78 @@ static int dpu_kms_init(struct drm_device *ddev)
return 0;
  }
  
+static int dpu_kms_mmap_mdp5(struct dpu_kms *dpu_kms)

+{
+   struct platform_device *pdev = dpu_kms->pdev;
+   struct platform_device *mdss_dev;
+   int ret;
+
+   if (dpu_kms->pdev->dev.bus != _bus_type)
+   return -EINVAL;
+


!dev_is_platform() perhaps?

But I would like to understand this check a bit more. Can you pls 
explain for which case this check was added?



+   mdss_dev = to_platform_device(dpu_kms->pdev->dev.parent);
+
+   dpu_kms->mmio = msm_ioremap(pdev, "mdp_phys");
+   if (IS_ERR(dpu_kms->mmio)) {
+   ret = PTR_ERR(dpu_kms->mmio);
+   DPU_ERROR("mdp register memory map failed: %d\n", ret);
+   dpu_kms->mmio = NULL;
+   return ret;
+   }
+   DRM_DEBUG("mapped dpu address space @%pK\n", dpu_kms->mmio);
+
+   dpu_kms->vbif[VBIF_RT] = msm_ioremap_mdss(mdss_dev,
+ dpu_kms->pdev,
+ "vbif_phys");
+   if (IS_ERR(dpu_kms->vbif[VBIF_RT])) {
+   ret = PTR_ERR(dpu_kms->vbif[VBIF_RT]);
+   DPU_ERROR("vbif register memory map failed: %d\n", ret);
+   dpu_kms->vbif[VBIF_RT] = NULL;
+   return ret;
+   }
+
+   dpu_kms->vbif[VBIF_NRT] = msm_ioremap_mdss(mdss_dev,
+  dpu_kms->pdev,
+  "vbif_nrt_phys");


Do you think a "quiet" version would be better?



+   if (IS_ERR(dpu_kms->vbif[VBIF_NRT])) {
+   dpu_kms->vbif[VBIF_NRT] = NULL;
+   DPU_DEBUG("VBIF NRT is not defined");
+   }
+
+   return 0;
+}
+
+static int dpu_kms_mmap_dpu(struct dpu_kms *dpu_kms)
+{
+   struct platform_device *pdev = dpu_kms->pdev;
+   int ret;
+
+   dpu_kms->mmio = msm_ioremap(pdev, "mdp");
+   if (IS_ERR(dpu_kms->mmio)) {
+   ret = PTR_ERR(dpu_kms->mmio);
+   DPU_ERROR("mdp register memory map failed: %d\n", ret);
+   dpu_kms->mmio = NULL;
+   return ret;
+   }
+   DRM_DEBUG("mapped dpu address space @%pK\n", dpu_kms->mmio);
+
+   dpu_kms->vbif[VBIF_RT] = msm_ioremap(pdev, "vbif");
+   if (IS_ERR(dpu_kms->vbif[VBIF_RT])) {
+   ret = PTR_ERR(dpu_kms->vbif[VBIF_RT]);
+   DPU_ERROR("vbif register memory map failed: %d\n", ret);
+   dpu_kms->vbif[VBIF_RT] = NULL;
+   return ret;
+   }
+
+   dpu_kms->vbif[VBIF_NRT] = msm_ioremap_quiet(pdev, "vbif_nrt");
+   if (IS_ERR(dpu_kms->vbif[VBIF_NRT])) {
+   dpu_kms->vbif[VBIF_NRT] = NULL;
+   DPU_DEBUG("VBIF NRT is not defined");
+   }
+
+   return 0;
+}
+
  static int dpu_dev_probe(struct platform_device *pdev)
  {
struct device *dev = >dev;
@@ -1230,28 +1302,12 @@ static int dpu_dev_probe(struct platform_device *pdev)
  
  	dpu_kms->base.irq = irq;
  
-	dpu_kms->mmio = msm_ioremap(pdev, "mdp");

-   if (IS_ERR(dpu_kms->mmio)) {
-   ret = PTR_ERR(dpu_kms->mmio);
-   DPU_ERROR("mdp register memory map failed: %d\n", ret);
-   dpu_kms->mmio = NULL;
-   return ret;
-   }
-   DRM_DEBUG("mapped dpu address space @%pK\n", dpu_kms->mmio);
-
-   dpu_kms->vbif[VBIF_RT] = msm_ioremap(pdev, "vbif");
-   if (IS_ERR(dpu_kms->vbif[VBIF_RT])) {
-   ret = PTR_ERR(dpu_kms->vbif[VBIF_RT]);
-   DPU_ERROR("vbif register memory map failed: %d\n", ret);
-   dpu_kms->vbif[VBIF_RT] = NULL;
+   if (of_device_is_compatible(dpu_kms->pdev->dev.of_node, "qcom,mdp5"))
+   ret = dpu_kms_mmap_mdp5(dpu_kms);
+   else
+   ret = dpu_kms_mmap_dpu(dpu_kms);
+   if (ret)
return ret;
-   }
-
-   dpu_kms->vbif[VBIF_NRT] = msm_ioremap_quiet(pdev, "vbif_nrt");
-   if (IS_ERR(dpu_kms->vbif[VBIF_NRT])) {
-   dpu_kms->vbif[VBIF_NRT] = NULL;
-   DPU_DEBUG("VBIF NRT is not defined");
-   }
  
  	ret = 

[PATCH v3 00/32] spi: get rid of some legacy macros

2024-02-07 Thread Uwe Kleine-König
Changes since v2
(https://lore.kernel.org/linux-spi/cover.1705944943.git.u.kleine-koe...@pengutronix.de):

 - Drop patch "mtd: rawnand: fsl_elbc: Let .probe retry if local bus is
   missing" which doesn't belong into this series.
 - Fix a build failure noticed by the kernel build bot in
   drivers/spi/spi-au1550.c. (I failed to catch this because this driver
   is mips only, but not enabled in a mips allmodconfig. That's a bit
   unfortunate, but not easily fixable.)
 - Add the Reviewed-by: and Acked-by: tags I received for v2.

Mark already announced for v2 that he is willing to apply the whole
series to his spi tree. Assuming no other show stoper are found in this
v3, I assume that's the plan still for this series now.

Thanks
Uwe

Uwe Kleine-König (32):
  fpga: ice40-spi: Follow renaming of SPI "master" to "controller"
  ieee802154: ca8210: Follow renaming of SPI "master" to "controller"
  iio: adc: ad_sigma_delta: Follow renaming of SPI "master" to "controller"
  Input: pxspad - follow renaming of SPI "master" to "controller"
  Input: synaptics-rmi4 - follow renaming of SPI "master" to "controller"
  media: mgb4: Follow renaming of SPI "master" to "controller"
  media: netup_unidvb: Follow renaming of SPI "master" to "controller"
  media: usb/msi2500: Follow renaming of SPI "master" to "controller"
  media: v4l2-subdev: Follow renaming of SPI "master" to "controller"
  misc: gehc-achc: Follow renaming of SPI "master" to "controller"
  mmc: mmc_spi: Follow renaming of SPI "master" to "controller"
  mtd: dataflash: Follow renaming of SPI "master" to "controller"
  net: ks8851: Follow renaming of SPI "master" to "controller"
  net: vertexcom: mse102x: Follow renaming of SPI "master" to "controller"
  platform/chrome: cros_ec_spi: Follow renaming of SPI "master" to "controller"
  spi: bitbang: Follow renaming of SPI "master" to "controller"
  spi: cadence-quadspi: Don't emit error message on allocation error
  spi: cadence-quadspi: Follow renaming of SPI "master" to "controller"
  spi: cavium: Follow renaming of SPI "master" to "controller"
  spi: geni-qcom: Follow renaming of SPI "master" to "controller"
  spi: loopback-test: Follow renaming of SPI "master" to "controller"
  spi: slave-mt27xx: Follow renaming of SPI "master" to "controller"
  spi: spidev: Follow renaming of SPI "master" to "controller"
  staging: fbtft: Follow renaming of SPI "master" to "controller"
  staging: greybus: spi: Follow renaming of SPI "master" to "controller"
  tpm_tis_spi: Follow renaming of SPI "master" to "controller"
  usb: gadget: max3420_udc: Follow renaming of SPI "master" to "controller"
  video: fbdev: mmp: Follow renaming of SPI "master" to "controller"
  wifi: libertas: Follow renaming of SPI "master" to "controller"
  spi: fsl-lib: Follow renaming of SPI "master" to "controller"
  spi: Drop compat layer from renaming "master" to "controller"
  Documentation: spi: Update documentation for renaming "master" to "controller"

 .../driver-api/driver-model/devres.rst|  2 +-
 Documentation/spi/spi-summary.rst | 74 +--
 drivers/char/tpm/tpm_tis_spi_main.c   |  4 +-
 drivers/fpga/ice40-spi.c  |  4 +-
 drivers/iio/adc/ad_sigma_delta.c  | 14 ++--
 drivers/input/joystick/psxpad-spi.c   |  4 +-
 drivers/input/rmi4/rmi_spi.c  |  2 +-
 drivers/media/pci/mgb4/mgb4_core.c| 14 ++--
 .../media/pci/netup_unidvb/netup_unidvb_spi.c | 48 ++--
 drivers/media/usb/msi2500/msi2500.c   | 38 +-
 drivers/media/v4l2-core/v4l2-spi.c|  4 +-
 drivers/misc/gehc-achc.c  |  8 +-
 drivers/mmc/host/mmc_spi.c|  6 +-
 drivers/mtd/devices/mtd_dataflash.c   |  2 +-
 drivers/net/ethernet/micrel/ks8851_spi.c  |  4 +-
 drivers/net/ethernet/vertexcom/mse102x.c  |  2 +-
 drivers/net/ieee802154/ca8210.c   |  2 +-
 .../net/wireless/marvell/libertas/if_spi.c|  2 +-
 drivers/platform/chrome/cros_ec_spi.c |  8 +-
 drivers/spi/spi-ath79.c   |  4 +-
 drivers/spi/spi-au1550.c  |  2 +-
 drivers/spi/spi-bitbang.c | 64 
 drivers/spi/spi-butterfly.c   |  6 +-
 drivers/spi/spi-cadence-quadspi.c |  7 +-
 drivers/spi/spi-cavium.c  |  6 +-
 drivers/spi/spi-cavium.h  |  2 +-
 drivers/spi/spi-davinci.c |  6 +-
 drivers/spi/spi-fsl-lib.c | 14 ++--
 drivers/spi/spi-geni-qcom.c   |  2 +-
 drivers/spi/spi-gpio.c|  2 +-
 drivers/spi/spi-lm70llp.c |  6 +-
 drivers/spi/spi-loopback-test.c   |  4 +-
 drivers/spi/spi-oc-tiny.c |  6 +-
 drivers/spi/spi-omap-uwire.c  |  4 +-
 drivers/spi/spi-sh-sci.c  | 10 +--
 drivers/spi/spi-slave-mt27xx.c|  

[PATCH v3 24/32] staging: fbtft: Follow renaming of SPI "master" to "controller"

2024-02-07 Thread Uwe Kleine-König
In commit 8caab75fd2c2 ("spi: Generalize SPI "master" to "controller"")
some functions and struct members were renamed. To not break all drivers
compatibility macros were provided.

To be able to remove these compatibility macros push the renaming into
this driver.

Acked-by: Greg Kroah-Hartman 
Acked-by: Jonathan Cameron 
Signed-off-by: Uwe Kleine-König 
---
 drivers/staging/fbtft/fbtft-core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/fbtft/fbtft-core.c 
b/drivers/staging/fbtft/fbtft-core.c
index 3626f429b002..68add4d598ae 100644
--- a/drivers/staging/fbtft/fbtft-core.c
+++ b/drivers/staging/fbtft/fbtft-core.c
@@ -794,7 +794,7 @@ int fbtft_register_framebuffer(struct fb_info *fb_info)
if (par->txbuf.buf && par->txbuf.len >= 1024)
sprintf(text1, ", %zu KiB buffer memory", par->txbuf.len >> 10);
if (spi)
-   sprintf(text2, ", spi%d.%d at %d MHz", spi->master->bus_num,
+   sprintf(text2, ", spi%d.%d at %d MHz", spi->controller->bus_num,
spi_get_chipselect(spi, 0), spi->max_speed_hz / 
100);
dev_info(fb_info->dev,
 "%s frame buffer, %dx%d, %d KiB video memory%s, fps=%lu%s\n",
@@ -1215,7 +1215,7 @@ int fbtft_probe_common(struct fbtft_display *display,
 
/* 9-bit SPI setup */
if (par->spi && display->buswidth == 9) {
-   if (par->spi->master->bits_per_word_mask & SPI_BPW_MASK(9)) {
+   if (par->spi->controller->bits_per_word_mask & SPI_BPW_MASK(9)) 
{
par->spi->bits_per_word = 9;
} else {
dev_warn(>spi->dev,
-- 
2.43.0



[PATCH v3 28/32] video: fbdev: mmp: Follow renaming of SPI "master" to "controller"

2024-02-07 Thread Uwe Kleine-König
In commit 8caab75fd2c2 ("spi: Generalize SPI "master" to "controller"")
some functions and struct members were renamed. To not break all drivers
compatibility macros were provided.

To be able to remove these compatibility macros push the renaming into
this driver.

Acked-by: Jonathan Cameron 
Signed-off-by: Uwe Kleine-König 
---
 drivers/video/fbdev/mmp/hw/mmp_spi.c | 26 +-
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/video/fbdev/mmp/hw/mmp_spi.c 
b/drivers/video/fbdev/mmp/hw/mmp_spi.c
index 0f8f0312a7c4..cf23650d7f0b 100644
--- a/drivers/video/fbdev/mmp/hw/mmp_spi.c
+++ b/drivers/video/fbdev/mmp/hw/mmp_spi.c
@@ -32,7 +32,7 @@ static inline int lcd_spi_write(struct spi_device *spi, u32 
data)
int timeout = 10, isr, ret = 0;
u32 tmp;
void __iomem *reg_base = (void __iomem *)
-   *(void **)spi_master_get_devdata(spi->master);
+   *(void **) spi_controller_get_devdata(spi->controller);
 
/* clear ISR */
writel_relaxed(~SPI_IRQ_MASK, reg_base + SPU_IRQ_ISR);
@@ -81,7 +81,7 @@ static inline int lcd_spi_write(struct spi_device *spi, u32 
data)
 static int lcd_spi_setup(struct spi_device *spi)
 {
void __iomem *reg_base = (void __iomem *)
-   *(void **)spi_master_get_devdata(spi->master);
+   *(void **) spi_controller_get_devdata(spi->controller);
u32 tmp;
 
tmp = CFG_SCLKCNT(16) |
@@ -136,32 +136,32 @@ static int lcd_spi_one_transfer(struct spi_device *spi, 
struct spi_message *m)
 
 int lcd_spi_register(struct mmphw_ctrl *ctrl)
 {
-   struct spi_master *master;
+   struct spi_controller *ctlr;
void **p_regbase;
int err;
 
-   master = spi_alloc_master(ctrl->dev, sizeof(void *));
-   if (!master) {
+   ctlr = spi_alloc_master(ctrl->dev, sizeof(void *));
+   if (!ctlr) {
dev_err(ctrl->dev, "unable to allocate SPI master\n");
return -ENOMEM;
}
-   p_regbase = spi_master_get_devdata(master);
+   p_regbase = spi_controller_get_devdata(ctlr);
*p_regbase = (void __force *)ctrl->reg_base;
 
/* set bus num to 5 to avoid conflict with other spi hosts */
-   master->bus_num = 5;
-   master->num_chipselect = 1;
-   master->setup = lcd_spi_setup;
-   master->transfer = lcd_spi_one_transfer;
+   ctlr->bus_num = 5;
+   ctlr->num_chipselect = 1;
+   ctlr->setup = lcd_spi_setup;
+   ctlr->transfer = lcd_spi_one_transfer;
 
-   err = spi_register_master(master);
+   err = spi_register_controller(ctlr);
if (err < 0) {
dev_err(ctrl->dev, "unable to register SPI master\n");
-   spi_master_put(master);
+   spi_controller_put(ctlr);
return err;
}
 
-   dev_info(>dev, "registered\n");
+   dev_info(>dev, "registered\n");
 
return 0;
 }
-- 
2.43.0



Re: [PATCH v3 1/4] drm/msm/mdss: generate MDSS data for MDP5 platforms

2024-02-07 Thread Abhinav Kumar




On 1/5/2024 3:34 PM, Dmitry Baryshkov wrote:

Older (mdp5) platforms do not use per-SoC compatible strings. Instead
they use a single compat entry 'qcom,mdss'. To facilitate migrating
these platforms to the DPU driver provide a way to generate the MDSS /
UBWC data at runtime, when the DPU driver asks for it.

It is not possible to generate this data structure at the probe time,
since some platforms might not have MDP_CLK enabled, which makes reading
HW_REV register return 0.



I would have expected a crash if clock was not enabled and we tried to 
access the hw_rev register.



Signed-off-by: Dmitry Baryshkov 
---
  drivers/gpu/drm/msm/msm_mdss.c | 51 ++
  1 file changed, 51 insertions(+)

diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c
index 455b2e3a0cdd..566a5dd5b8e8 100644
--- a/drivers/gpu/drm/msm/msm_mdss.c
+++ b/drivers/gpu/drm/msm/msm_mdss.c
@@ -3,6 +3,7 @@
   * Copyright (c) 2018, The Linux Foundation
   */
  
+#include 

  #include 
  #include 
  #include 
@@ -213,6 +214,49 @@ static void msm_mdss_setup_ubwc_dec_40(struct msm_mdss 
*msm_mdss)
}
  }
  
+#define MDSS_HW_MAJ_MIN		GENMASK(31, 16)

+
+#define MDSS_HW_MSM89960x1007
+#define MDSS_HW_MSM89370x100e
+#define MDSS_HW_MSM89560x1010


This should be 0x100B in the docs I see.


+#define MDSS_HW_MSM89980x3000
+#define MDSS_HW_SDM660 0x3002
+#define MDSS_HW_SDM630 0x3003
+
+/*
+ * MDP5 platforms use generic qcom,mdp5 compat string, so we have to generate 
this data
+ */
+static const struct msm_mdss_data *msm_mdss_generate_mdp5_mdss_data(struct 
msm_mdss *mdss)
+{
+   struct msm_mdss_data *data;
+   u32 hw_rev;
+
+   data = devm_kzalloc(mdss->dev, sizeof(*data), GFP_KERNEL);
+   if (!data)
+   return NULL;
+
+   hw_rev = readl_relaxed(mdss->mmio + HW_REV);
+   hw_rev = FIELD_GET(MDSS_HW_MAJ_MIN, hw_rev);
+
+   if (hw_rev == MDSS_HW_MSM8996 ||
+   hw_rev == MDSS_HW_MSM8937 ||
+   hw_rev == MDSS_HW_MSM8956 ||
+   hw_rev == MDSS_HW_MSM8998 ||
+   hw_rev == MDSS_HW_SDM660 ||
+   hw_rev == MDSS_HW_SDM630) {
+   data->ubwc_dec_version = UBWC_1_0;
+   data->ubwc_enc_version = UBWC_1_0;
+   }
+
+   if (hw_rev == MDSS_HW_MSM8996 ||
+   hw_rev == MDSS_HW_MSM8998)
+   data->highest_bank_bit = 2;
+   else
+   data->highest_bank_bit = 1;
+
+   return data;
+}
+
  const struct msm_mdss_data *msm_mdss_get_mdss_data(struct device *dev)
  {
struct msm_mdss *mdss;
@@ -222,6 +266,13 @@ const struct msm_mdss_data *msm_mdss_get_mdss_data(struct 
device *dev)
  
  	mdss = dev_get_drvdata(dev);
  
+	/*

+* We could not do it at the probe time, since hw revision register was
+* not readable. Fill data structure now for the MDP5 platforms.
+*/
+   if (!mdss->mdss_data && mdss->is_mdp5)
+   mdss->mdss_data = msm_mdss_generate_mdp5_mdss_data(mdss);
+
return mdss->mdss_data;
  }
  



Re: [syzbot] [dri?] WARNING in vkms_get_vblank_timestamp (2)

2024-02-07 Thread syzbot
syzbot has bisected this issue to:

commit ea40d7857d5250e5400f38c69ef9e17321e9c4a2
Author: Daniel Vetter 
Date:   Fri Oct 9 23:21:56 2020 +

drm/vkms: fbdev emulation support

bisection log:  https://syzkaller.appspot.com/x/bisect.txt?x=1282dbffe8
start commit:   6764c317b6bb Merge tag 'scsi-fixes' of git://git.kernel.or..
git tree:   upstream
final oops: https://syzkaller.appspot.com/x/report.txt?x=1182dbffe8
console output: https://syzkaller.appspot.com/x/log.txt?x=1682dbffe8
kernel config:  https://syzkaller.appspot.com/x/.config?x=2c0ac5dfae6ecc58
dashboard link: https://syzkaller.appspot.com/bug?extid=93bd128a383695391534
syz repro:  https://syzkaller.appspot.com/x/repro.syz?x=12067e6018
C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=102774b7e8

Reported-by: syzbot+93bd128a383695391...@syzkaller.appspotmail.com
Fixes: ea40d7857d52 ("drm/vkms: fbdev emulation support")

For information about bisection process see: https://goo.gl/tpsmEJ#bisection


Re: [RFC] drm/i915: Add GuC submission interface version query

2024-02-07 Thread John Harrison

On 2/7/2024 03:56, Tvrtko Ursulin wrote:

From: Tvrtko Ursulin 

Add a new query to the GuC submission interface version.

Mesa intends to use this information to check for old firmware versions
with a known bug where using the render and compute command streamers
simultaneously can cause GPU hangs due issues in firmware scheduling.

Based on patches from Vivaik and Joonas.

There is a little bit of an open around the width required for versions.
While the GuC FW iface tells they are u8, i915 GuC code uses u32:

  #define CSS_SW_VERSION_UC_MAJOR   (0xFF << 16)
  #define CSS_SW_VERSION_UC_MINOR   (0xFF << 8)
  #define CSS_SW_VERSION_UC_PATCH   (0xFF << 0)
...
  struct intel_uc_fw_ver {
  u32 major;
  u32 minor;
  u32 patch;
  u32 build;
  };
This is copied from generic code which supports firmwares other than 
GuC. Only GuC promises to use 8-bit version components. Other firmwares 
very definitely do not. There is no open.




So we could make the query u8, and refactor the struct intel_uc_fw_ver
to use u8, or not. To avoid any doubts on why are we assigning u32 to
u8 I simply opted to use u64. Which avoids the need to add any padding
too.

I don't follow how potential 8 vs 32 confusion means jump to 64?!



Compile tested only.

Signed-off-by: Tvrtko Ursulin 
Cc: Kenneth Graunke 
Cc: Jose Souza 
Cc: Sagar Ghuge 
Cc: Paulo Zanoni 
Cc: John Harrison 
Cc: Rodrigo Vivi 
Cc: Jani Nikula 
Cc: Tvrtko Ursulin 
Cc: Vivaik Balasubrawmanian 
---
  drivers/gpu/drm/i915/i915_query.c | 32 +++
  include/uapi/drm/i915_drm.h   | 11 +++
  2 files changed, 43 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_query.c 
b/drivers/gpu/drm/i915/i915_query.c
index 00871ef99792..999687f6a3d4 100644
--- a/drivers/gpu/drm/i915/i915_query.c
+++ b/drivers/gpu/drm/i915/i915_query.c
@@ -551,6 +551,37 @@ static int query_hwconfig_blob(struct drm_i915_private 
*i915,
return hwconfig->size;
  }
  
+static int

+query_guc_submission_version(struct drm_i915_private *i915,
+struct drm_i915_query_item *query)
+{
+   struct drm_i915_query_guc_submission_version __user *query_ptr =
+   u64_to_user_ptr(query->data_ptr);
+   struct drm_i915_query_guc_submission_version ver;
+   struct intel_guc *guc = _gt(i915)->uc.guc;
+   const size_t size = sizeof(ver);
+   int ret;
+
+   if (!intel_uc_uses_guc_submission(_gt(i915)->uc))
+   return -ENODEV;
+
+   ret = copy_query_item(, size, size, query);
+   if (ret != 0)
+   return ret;
+
+   if (ver.major || ver.minor || ver.patch)
+   return -EINVAL;
+
+   ver.major = guc->submission_version.major;
+   ver.minor = guc->submission_version.minor;
+   ver.patch = guc->submission_version.patch;
This needs to include the branch version (currently set to zero) in the 
definition. And the UMD needs to barf if branch comes back as non-zero. 
I.e. there is no guarantee that a branched version will have the w/a + 
fix that they are wanting.


John.



+
+   if (copy_to_user(query_ptr, , size))
+   return -EFAULT;
+
+   return 0;
+}
+
  static int (* const i915_query_funcs[])(struct drm_i915_private *dev_priv,
struct drm_i915_query_item *query_item) 
= {
query_topology_info,
@@ -559,6 +590,7 @@ static int (* const i915_query_funcs[])(struct 
drm_i915_private *dev_priv,
query_memregion_info,
query_hwconfig_blob,
query_geometry_subslices,
+   query_guc_submission_version,
  };
  
  int i915_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file)

diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 550c496ce76d..d80d9b5e1eda 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -3038,6 +3038,7 @@ struct drm_i915_query_item {
 *  - %DRM_I915_QUERY_MEMORY_REGIONS (see struct 
drm_i915_query_memory_regions)
 *  - %DRM_I915_QUERY_HWCONFIG_BLOB (see `GuC HWCONFIG blob uAPI`)
 *  - %DRM_I915_QUERY_GEOMETRY_SUBSLICES (see struct 
drm_i915_query_topology_info)
+*  - %DRM_I915_QUERY_GUC_SUBMISSION_VERSION (see struct 
drm_i915_query_guc_submission_version)
 */
__u64 query_id;
  #define DRM_I915_QUERY_TOPOLOGY_INFO  1
@@ -3046,6 +3047,7 @@ struct drm_i915_query_item {
  #define DRM_I915_QUERY_MEMORY_REGIONS 4
  #define DRM_I915_QUERY_HWCONFIG_BLOB  5
  #define DRM_I915_QUERY_GEOMETRY_SUBSLICES 6
+#define DRM_I915_QUERY_GUC_SUBMISSION_VERSION  7
  /* Must be kept compact -- no holes and well documented */
  
  	/**

@@ -3591,6 +3593,15 @@ struct drm_i915_query_memory_regions {
struct drm_i915_memory_region_info regions[];
  };
  
+/**

+* struct drm_i915_query_guc_submission_version - query GuC submission 
interface version

Re: [PATCH v2] drm/vmwgfx: Filter modes which exceed 3/4 of graphics memory.

2024-02-07 Thread Zack Rusin
On Tue, Feb 6, 2024 at 4:30 PM Ian Forbes  wrote:
>
> So the issue is that SVGA_3D_CMD_DX_PRED_COPY_REGION between 2
> surfaces that are the size of the mode fails. Technically for this to
> work the filter will have to be 1/2 of graphics mem. I was just lucky
> that the next mode in the list was already less than 1/2. 3/4 is not
> actually going to work. Also this only happens on X/Gnome and seems
> more like an issue with the compositor. Wayland/Gnome displays the
> desktop but it's unusable and glitches even with the 1/2 limit. I
> don't think wayland even abides by the mode limits as I see it trying
> to create surfaces larger than the mode. It might be using texture
> limits instead.

So the SVGA_3D_CMD_DX_PRED_COPY_REGION is only available with dx
contexts/3d enabled/gb surfaces. With 3d or gb objects disabled we
should fall back to legacy display and that command shouldn't have
been used. Is that the case? Does it work with 3d/gb objects disabled?

There's a few bugs there:
- SVGA_3D_CMD_DX_PRED_COPY_REGION should only come from userspace, the
userspace should validate that the max amount of resident memory
hasn't been exceeded before issuing those copies
- vmwgfx should be a lot better about determining whether the amount
of resident memory required by the current command buffers hasn't been
exceeded
- In case of high memory pressure vmwgfx should explicitly disable 3d
support. There's no way to run 3d workloads with anything less than
64mb of ram especially given that we do not adjust our texture limits
and they will remain either 4k, 8k or more depending on what we're
running on.

But those are secondary to making resolution switch work correctly on
basic system, i.e.:
1) Disable 3D and gb objects
2) Check if in the kernel log vmwgx says that it's using "legacy display"
3) Check if the resolution switching works correctly
4) If not lets fix that first (fix #1)
5) Disable 3D and keep gb objects active
6) Check that the kernel log select "screen target display unit" and
have 3d disabled (i.e. no SVGA_3D_CMD_DX_PRED_COPY_REGION is coming
through)
7) If that doesn't work lets fix that next (fix #2)
8) Enabled 3d and gb objects (your current default)
9) Check if max_mob_pages (i.e. max_resident_memory) is smaller than
what we'd need to hold even a single a texture limits * 4bpp, print a
warning and disable 3d (this should bring us in line with what we
fixed in point #7) (fix #3)

So basically we want to make sure that on vmwgfx all three
configurations work: 1) 3d and gb objects disabled, 2) 3d disabled, gb
objects enabled, 3) 3d and gb object enabled.

z


[PATCH] dma-buf: try to catch swiotlb bounce buffers

2024-02-07 Thread Daniel Vetter
They rather fundamentally break the entire concept of zero copy, so if
an exporter manages to hand these out things will break all over.

Luckily there's not too many case that use
swiotlb_sync_single_for_device/cpu():

- The generic iommu dma-api code in drivers/iommu/dma-iommu.c. We can
  catch that with sg_dma_is_swiotlb() reliably.

- The generic direct dma code in kernel/dma/direct.c. We can mostly
  catch that with looking for a NULL dma_ops, except for some powerpc
  special cases.

- Xen, which I don't bother to catch here.

Implement these checks in dma_buf_map_attachment when
CONFIG_DMA_API_DEBUG is enabled.

Signed-off-by: Daniel Vetter 
Cc: Sumit Semwal 
Cc: "Christian König" 
Cc: linux-me...@vger.kernel.org
Cc: linaro-mm-...@lists.linaro.org
Cc: Paul Cercueil 
---
Entirely untested, but since I sent the mail with the idea I figured I
might as well type it up after I realized there's a lot fewer cases to
check. That is, if I haven't completely misread the dma-api and swiotlb
code.
-Sima
---
 drivers/dma-buf/dma-buf.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index d1e7f823fbdb..d6f95523f995 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -28,6 +28,12 @@
 #include 
 #include 
 
+#ifdef CONFIG_DMA_API_DEBUG
+#include 
+#include 
+#include 
+#endif
+
 #include 
 #include 
 
@@ -1149,10 +1155,13 @@ struct sg_table *dma_buf_map_attachment(struct 
dma_buf_attachment *attach,
 #ifdef CONFIG_DMA_API_DEBUG
if (!IS_ERR(sg_table)) {
struct scatterlist *sg;
+   struct device *dev = attach->dev;
u64 addr;
int len;
int i;
 
+   bool is_direct_dma = !get_dma_ops(dev);
+
for_each_sgtable_dma_sg(sg_table, sg, i) {
addr = sg_dma_address(sg);
len = sg_dma_len(sg);
@@ -1160,7 +1169,15 @@ struct sg_table *dma_buf_map_attachment(struct 
dma_buf_attachment *attach,
pr_debug("%s: addr %llx or len %x is not page 
aligned!\n",
 __func__, addr, len);
}
+
+   if (is_direct_dma) {
+   phys_addr_t paddr = dma_to_phys(dev, addr);
+
+   WARN_ON_ONCE(is_swiotlb_buffer(dev, paddr));
+   }
}
+
+   WARN_ON_ONCE(sg_dma_is_swiotlb(sg));
}
 #endif /* CONFIG_DMA_API_DEBUG */
return sg_table;
-- 
2.43.0



Re: [PATCH v2] drm/msm/dpu: remove CRTC frame event callback registration

2024-02-07 Thread Abhinav Kumar




On 10/5/2023 3:06 PM, Dmitry Baryshkov wrote:

The frame event callback is always set to dpu_crtc_frame_event_cb() (or
to NULL) and the data is always either the CRTC itself or NULL
(correpondingly). Thus drop the event callback registration, call the
dpu_crtc_frame_event_cb() directly and gate on the dpu_enc->crtc
assigned using dpu_encoder_assign_crtc().



The idea behind the registration was for CRTC to register for events if 
it wants to and perhaps have different callbacks for different events 
through a common registration mechanism and encoder need not know each 
dpu_crtc calls as most of the time we dont want encoder to go back to 
crtc to look up what its APIs are.


But, we are always registering today and have only one callback, so it 
kind of makes it an additional redundant wrapper. So I guess, once again 
one of those things which , seems not necessary with the current code 
but nothing really wrong with it.


Anyway, couple of comments below.


Signed-off-by: Dmitry Baryshkov 
---

This patch was previously posted as a part of the [1]

Changes since v1:
- Rebased on top of linux-next

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

---
  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 17 +
  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h| 14 +++
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 41 +++--
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 10 -
  drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h   |  4 --
  5 files changed, 21 insertions(+), 65 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 8ce7586e2ddf..dec5417b69d8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -669,18 +669,8 @@ static void dpu_crtc_frame_event_work(struct kthread_work 
*work)
DPU_ATRACE_END("crtc_frame_event");
  }
  
-/*

- * dpu_crtc_frame_event_cb - crtc frame event callback API. CRTC module
- * registers this API to encoder for all frame event callbacks like
- * frame_error, frame_done, idle_timeout, etc. Encoder may call different 
events
- * from different context - IRQ, user thread, commit_thread, etc. Each event
- * should be carefully reviewed and should be processed in proper task context
- * to avoid schedulin delay or properly manage the irq context's bottom half
- * processing.
- */
-static void dpu_crtc_frame_event_cb(void *data, u32 event)
+void dpu_crtc_frame_event_cb(struct drm_crtc *crtc, u32 event)
  {
-   struct drm_crtc *crtc = (struct drm_crtc *)data;
struct dpu_crtc *dpu_crtc;
struct msm_drm_private *priv;
struct dpu_crtc_frame_event *fevent;
@@ -1102,9 +1092,6 @@ static void dpu_crtc_disable(struct drm_crtc *crtc,
  
  	dpu_core_perf_crtc_update(crtc, 0);
  
-	drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask)

-   dpu_encoder_register_frame_event_callback(encoder, NULL, NULL);
-
memset(cstate->mixers, 0, sizeof(cstate->mixers));
cstate->num_mixers = 0;
  
@@ -1143,8 +1130,6 @@ static void dpu_crtc_enable(struct drm_crtc *crtc,

 */
if (dpu_encoder_get_intf_mode(encoder) == INTF_MODE_VIDEO)
request_bandwidth = true;
-   dpu_encoder_register_frame_event_callback(encoder,
-   dpu_crtc_frame_event_cb, (void *)crtc);
}
  
  	if (request_bandwidth)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
index 539b68b1626a..3aa536d95721 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -300,4 +300,18 @@ static inline enum dpu_crtc_client_type 
dpu_crtc_get_client_type(
return crtc && crtc->state ? RT_CLIENT : NRT_CLIENT;
  }
  
+/**

+ * dpu_crtc_frame_event_cb - crtc frame event callback API
+ * @crtc: Pointer to crtc
+ * @event: Event to process
+ *
+ * CRTC module registers this API to encoder for all frame event callbacks like
+ * frame_error, frame_done, idle_timeout, etc. Encoder may call different 
events
+ * from different context - IRQ, user thread, commit_thread, etc. Each event
+ * should be carefully reviewed and should be processed in proper task context
+ * to avoid schedulin delay or properly manage the irq context's bottom half
+ * processing.
+ */


This doc is no longer correct.

CRTC module no longer registers anything.


+void dpu_crtc_frame_event_cb(struct drm_crtc *crtc, u32 event);
+
  #endif /* _DPU_CRTC_H_ */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index d34e684a4178..709fffa4dfa7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -148,8 +148,6 @@ enum dpu_enc_rc_states {
   * @frame_busy_mask:  Bitmask tracking which phys_enc we are still
   *busy processing current 

[PATCH] drm/buddy: Fix alloc_range() error handling code

2024-02-07 Thread Arunpravin Paneer Selvam
Few users have observed display corruption when they boot
the machine to KDE Plasma or playing games. We have root
caused the problem that whenever alloc_range() couldn't
find the required memory blocks the function was returning
SUCCESS in some of the corner cases.

The right approach would be if the total allocated size
is less than the required size, the function should
return -ENOSPC.

Gitlab ticket link - https://gitlab.freedesktop.org/drm/amd/-/issues/3097
Fixes: 0a1844bf0b53 ("drm/buddy: Improve contiguous memory allocation")
Signed-off-by: Arunpravin Paneer Selvam 
Tested-by: Mario Limonciello 
---
 drivers/gpu/drm/drm_buddy.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/drm_buddy.c b/drivers/gpu/drm/drm_buddy.c
index f57e6d74fb0e..c1a99bf4dffd 100644
--- a/drivers/gpu/drm/drm_buddy.c
+++ b/drivers/gpu/drm/drm_buddy.c
@@ -539,6 +539,12 @@ static int __alloc_range(struct drm_buddy *mm,
} while (1);
 
list_splice_tail(, blocks);
+
+   if (total_allocated < size) {
+   err = -ENOSPC;
+   goto err_free;
+   }
+
return 0;
 
 err_undo:
-- 
2.25.1



Re: [Linaro-mm-sig] [PATCH v5 2/6] dma-buf: udmabuf: Implement .{begin,end}_access

2024-02-07 Thread Daniel Vetter
On Fri, Jan 19, 2024 at 03:13:58PM +0100, Paul Cercueil wrote:
> Implement .begin_access() and .end_access() callbacks.
> 
> For now these functions will simply sync/flush the CPU cache when
> needed.
> 
> Signed-off-by: Paul Cercueil 
> 
> ---
> v5: New patch
> ---
>  drivers/dma-buf/udmabuf.c | 27 +++
>  1 file changed, 27 insertions(+)
> 
> diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
> index c40645999648..a87d89b58816 100644
> --- a/drivers/dma-buf/udmabuf.c
> +++ b/drivers/dma-buf/udmabuf.c
> @@ -179,6 +179,31 @@ static int end_cpu_udmabuf(struct dma_buf *buf,
>   return 0;
>  }
>  
> +static int begin_udmabuf(struct dma_buf_attachment *attach,
> +  struct sg_table *sgt,
> +  enum dma_data_direction dir)
> +{
> + struct dma_buf *buf = attach->dmabuf;
> + struct udmabuf *ubuf = buf->priv;
> + struct device *dev = ubuf->device->this_device;
> +
> + dma_sync_sg_for_device(dev, sgt->sgl, sg_nents(sgt->sgl), dir);

So one thing I've just wondered is whether we've made sure that this is
only doing cache coherency maintenance, and not swiotlb bounce buffer
copying. The latter would really not be suitable for dma-buf anymore I
think.

Not sure how to best check for that since it's all in the depths of the
dma-api code, but I guess the best way to really make sure is to disable
CONFIG_SWIOTLB. Otherwise I guess the way to absolutely make sure is to
trace swiotlb_sync_single_for_device/cpu.

It would be kinda neat if dma-buf.c code could make sure you never ever
get an swiotlb entry from a dma_buf_map_attachment call, but I don't think
we can enforce that. There's sg_dma_is_swiotlb, but that won't catch all
implementations, only the generic dma-iommu.c one.

Cheers, Sima

> + return 0;
> +}
> +
> +static int end_udmabuf(struct dma_buf_attachment *attach,
> +struct sg_table *sgt,
> +enum dma_data_direction dir)
> +{
> + struct dma_buf *buf = attach->dmabuf;
> + struct udmabuf *ubuf = buf->priv;
> + struct device *dev = ubuf->device->this_device;
> +
> + if (dir != DMA_TO_DEVICE)
> + dma_sync_sg_for_cpu(dev, sgt->sgl, sg_nents(sgt->sgl), dir);
> + return 0;
> +}
> +
>  static const struct dma_buf_ops udmabuf_ops = {
>   .cache_sgt_mapping = true,
>   .map_dma_buf   = map_udmabuf,
> @@ -189,6 +214,8 @@ static const struct dma_buf_ops udmabuf_ops = {
>   .vunmap= vunmap_udmabuf,
>   .begin_cpu_access  = begin_cpu_udmabuf,
>   .end_cpu_access= end_cpu_udmabuf,
> + .begin_access  = begin_udmabuf,
> + .end_access= end_udmabuf,
>  };
>  
>  #define SEALS_WANTED (F_SEAL_SHRINK)
> -- 
> 2.43.0
> 
> ___
> Linaro-mm-sig mailing list -- linaro-mm-...@lists.linaro.org
> To unsubscribe send an email to linaro-mm-sig-le...@lists.linaro.org

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


2024 X.Org Foundation Membership deadline for voting in the election

2024-02-07 Thread Christopher Michael
The 2024 X.Org Foundation elections are rapidly approaching. We will be 
forwarding the election schedule and nominating process to the 
membership shortly.



Please note that only current members can vote in the upcoming election, 
and that the deadline for new memberships or renewals to vote in the 
upcoming election is 26 February 2024 at 23:59 UTC.



If you are interested in joining the X.Org Foundation or in renewing 
your membership, please visit the membership system site at: 
https://members.x.org/




Christopher Michael, on behalf of the X.Org elections committee



Re: [PATCH v2] drivers/ps3: select VIDEO to provide cmdline functions

2024-02-07 Thread Thomas Zimmermann




Am 07.02.24 um 17:13 schrieb Randy Dunlap:

When VIDEO is not set, there is a build error. Fix that by selecting
VIDEO for PS3_PS3AV.

ERROR: modpost: ".video_get_options" [drivers/ps3/ps3av_mod.ko] undefined!

Fixes: dae7fbf43fd0 ("driver/ps3: Include  for mode parsing")
Fixes: a3b6792e990d ("video/cmdline: Introduce CONFIG_VIDEO for video= 
parameter")
Cc: Michael Ellerman 
Cc: Nicholas Piggin 
Cc: Christophe Leroy 
Cc: Aneesh Kumar K.V 
Cc: Naveen N. Rao 
Cc: linuxppc-...@lists.ozlabs.org
Cc: Thomas Zimmermann 
Cc: Geoff Levand 
Acked-by: Geoff Levand 
Cc: linux-fb...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Randy Dunlap 


Reviewed-by: Thomas Zimmermann 


---
v2: add Geoff's Ack;
 add second Fixes: tag and more Cc:s (Thomas)

  arch/powerpc/platforms/ps3/Kconfig |1 +
  1 file changed, 1 insertion(+)

diff -- a/arch/powerpc/platforms/ps3/Kconfig 
b/arch/powerpc/platforms/ps3/Kconfig
--- a/arch/powerpc/platforms/ps3/Kconfig
+++ b/arch/powerpc/platforms/ps3/Kconfig
@@ -67,6 +67,7 @@ config PS3_VUART
  config PS3_PS3AV
depends on PPC_PS3
tristate "PS3 AV settings driver" if PS3_ADVANCED
+   select VIDEO
select PS3_VUART
default y
help


--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)



[PATCH v2] drivers/ps3: select VIDEO to provide cmdline functions

2024-02-07 Thread Randy Dunlap
When VIDEO is not set, there is a build error. Fix that by selecting
VIDEO for PS3_PS3AV.

ERROR: modpost: ".video_get_options" [drivers/ps3/ps3av_mod.ko] undefined!

Fixes: dae7fbf43fd0 ("driver/ps3: Include  for mode parsing")
Fixes: a3b6792e990d ("video/cmdline: Introduce CONFIG_VIDEO for video= 
parameter")
Cc: Michael Ellerman 
Cc: Nicholas Piggin 
Cc: Christophe Leroy 
Cc: Aneesh Kumar K.V 
Cc: Naveen N. Rao 
Cc: linuxppc-...@lists.ozlabs.org
Cc: Thomas Zimmermann 
Cc: Geoff Levand 
Acked-by: Geoff Levand 
Cc: linux-fb...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Randy Dunlap 
---
v2: add Geoff's Ack;
add second Fixes: tag and more Cc:s (Thomas)

 arch/powerpc/platforms/ps3/Kconfig |1 +
 1 file changed, 1 insertion(+)

diff -- a/arch/powerpc/platforms/ps3/Kconfig 
b/arch/powerpc/platforms/ps3/Kconfig
--- a/arch/powerpc/platforms/ps3/Kconfig
+++ b/arch/powerpc/platforms/ps3/Kconfig
@@ -67,6 +67,7 @@ config PS3_VUART
 config PS3_PS3AV
depends on PPC_PS3
tristate "PS3 AV settings driver" if PS3_ADVANCED
+   select VIDEO
select PS3_VUART
default y
help


Re: [PATCH 2/2] drm/vkms: Use a simpler composition function

2024-02-07 Thread Louis Chauvet
Hello Pekka, Arthur,

[...]

> > > Would it be possible to have a standardised benchmark specifically
> > > for performance rather than correctness, in IGT or where-ever it
> > > would make sense? Then it would be simple to tell contributors to
> > > run this and report the numbers before and after.
> > > 
> > > I would propose this kind of KMS layout:
> > > 
> > > - CRTC size 3841 x 2161
> > > - primary plane, XRGB, 3639 x 2161 @ 101,0
> > > - overlay A, XBGR2101010, 3033 x 1777 @ 201,199
> > > - overlay B, ARGB, 1507 x 1400 @ 1800,250
> > > 
> > > The sizes and positions are deliberately odd to try to avoid happy
> > > alignment accidents. The planes are big, which should let the pixel
> > > operations easily dominate performance measurement. There are
> > > different pixel formats, both opaque and semi-transparent. There is
> > > lots of plane overlap. The planes also do not cover the whole CRTC
> > > leaving the background visible a bit.
> > > 
> > > There should be two FBs per each plane, flipped alternatingly each
> > > frame. Writeback should be active. Run this a number of frames, say,
> > > 100, and measure the kernel CPU time taken. It's supposed to take at
> > > least several seconds in total.
> > > 
> > > I think something like this should be the base benchmark. One can
> > > add more to it, like rotated planes, YUV planes, etc. or switch
> > > settings on the existing planes. Maybe even FB_DAMAGE_CLIPS. Maybe
> > > one more overlay that is very tall and thin.
> > > 
> > > Just an idea, what do you all think?  
> > 
> > Hi Pekka,
> > 
> > I just finished writing this proposal using IGT.
> > 
> > I got pretty interesting results:
> > 
> > The mentioned commit 8356b97906503a02125c8d03c9b88a61ea46a05a took
> > around 13 seconds. While drm-misc/drm-misc-next took 36 seconds.
> > 
> > I'm currently bisecting to be certain that the change to the
> > pixel-by-pixel is the culprit, but I don't see why it wouldn't be.
> > 
> > I just need to do some final touches on the benchmark code and it
> > will be ready for revision.
> 
> Awesome, thank you very much for doing that!
> pq

I also think it's a good benchmarks for classic configurations. The odd 
size is a very nice idea to verify the corner cases of line-by-line 
algorithms.

When this is ready, please share the test, so I can check if my patch is 
as performant as before.

Thank you for this work.

Have a nice day,
Louis Chauvet

-- 
Louis Chauvet, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


Re: [PATCH v3 1/4] dt-bindings: display: bridge: add sam9x75-lvds compatible

2024-02-07 Thread Conor Dooley
$subject: dt-bindings: display: bridge: add sam9x75-lvds compatible

If there's a respin for some reason, please update the subject to match
what the commit is actually doing (adding a whole binding).

Cheers,
Conor.


signature.asc
Description: PGP signature


Re: [PATCH 2/2] drm/vkms: Use a simpler composition function

2024-02-07 Thread Louis Chauvet
Hello Pekka, Arthur, Maxime,

> > > >> Change the composition algorithm to iterate over pixels instead of 
> > > >> lines.
> > > >> It allows a simpler management of rotation and pixel access for 
> > > >> complex formats.
> > > >>
> > > >> This new algorithm allows read_pixel function to have access to x/y
> > > >> coordinates and make it possible to read the correct thing in a 
> > > >> block
> > > >> when block_w and block_h are not 1.
> > > >> The iteration pixel-by-pixel in the same method also allows a 
> > > >> simpler
> > > >> management of rotation with drm_rect_* helpers. This way it's not 
> > > >> needed
> > > >> anymore to have misterious switch-case distributed in multiple 
> > > >> places.  
> > > >
> > > > Hi,
> > > >
> > > > there was a very good reason to write this code using lines:
> > > > performance. Before lines, it was indeed operating on individual 
> > > > pixels.
> > > >
> > > > Please, include performance measurements before and after this 
> > > > series
> > > > to quantify the impact on the previously already supported pixel
> > > > formats, particularly the 32-bit-per-pixel RGB variants.
> > > >
> > > > VKMS will be used more and more in CI for userspace projects, and
> > > > performance actually matters there.
> > > >
> > > > I'm worrying that this performance degradation here is significant. 
> > > > I
> > > > believe it is possible to keep blending with lines, if you add new 
> > > > line
> > > > getters for reading from rotated, sub-sampled etc. images. That way 
> > > > you
> > > > don't have to regress the most common formats' performance.

I tested, and yes, it's significant for most of the tests. None of them 
timed out on my machine, but I agree that I have to improve this. Do you 
know which tests are the more "heavy"?

> > >  While I understand performance is important and should be taken into
> > >  account seriously, I cannot understand how broken testing could be
> > >  considered better. Fast but inaccurate will always be significantly
> > >  less attractive to my eyes.
> > > >>>
> > > >>> AFAIK, neither the cover letter nor the commit log claimed it was 
> > > >>> fixing
> > > >>> something broken, just that it was "better" (according to what
> > > >>> criteria?).  

Sorry Maxime for this little missunderstanding, I will improve the commit 
message and cover letter for the v2.

> > > >> Today's RGB implementation is only optimized in the line-by-line case
> > > >> when there is no rotation. The logic is bit convoluted and may possibly
> > > >> be slightly clarified with a per-format read_line() implementation,
> > > >> at a very light performance cost. Such an improvement would definitely
> > > >> benefit to the clarity of the code, especially when transformations
> > > >> (especially the rotations) come into play because they would be clearly
> > > >> handled differently instead of being "hidden" in the optimized logic.
> > > >> Performances would not change much as this path is not optimized today
> > > >> anyway (the pixel-oriented logic is already used in the rotation case).

[...]

> > > > I think it would, if I understand what you mean. Ever since I proposed
> > > > a line-by-line algorithm to improve the performance, I was thinking of
> > > > per-format read_line() functions that would be selected outside of any
> > > > loops.

[...]

> > > > I haven't looked at VKMS in a long time, and I am disappointed to find
> > > > that vkms_compose_row() is calling plane->pixel_read() pixel-by-pixel.
> > > > The reading vfunc should be called with many pixels at a time when the
> > > > source FB layout allows it. The whole point of the line-based functions
> > > > was that they repeat the innermost loop in every function body to make
> > > > the per-pixel overhead as small as possible. The VKMS implementations
> > > > benchmarked before and after the original line-based algorithm showed
> > > > that calling a function pointer per-pixel is relatively very expensive.
> > > > Or maybe it was a switch-case.

[...]

> > > But, I agree with Miquel that the rotation logic is easier to implement
> > > in a pixel-based way. So going pixel-by-pixel only when rotation occurs
> > > would be great.  
> > 
> > Yes, and I think that can very well be done in the line-based framework
> > still that existed in the old days before any rotation support was
> > added. Essentially a plug-in line-getter function that then calls a
> > format-specific line-getter pixel-by-pixel while applying the rotation.
> > It would be simple, it would leave unrotated performance unharmed (use
> > format-specific line-getter directly with lines), but it might be
> > somewhat less performant for rotated KMS planes. I suspect that might
> > be a good compromise.
> > 
> > Format-specific line-getters could also 

Re: [v2,3/8] firmware/sysfb: Set firmware-framebuffer parent device

2024-02-07 Thread Sui Jingfeng

Hi,


On 2024/2/5 16:24, Thomas Zimmermann wrote:

Hi

Am 02.02.24 um 16:23 schrieb Sui Jingfeng:

Hi,


On 2024/2/2 19:58, Thomas Zimmermann wrote:

Set the firmware framebuffer's parent device, which usually is the
graphics hardware's physical device. Integrates the framebuffer in
the Linux device hierarchy and lets Linux handle dependencies among
devices. For example, the graphics hardware won't be suspended while
the firmware device is still active.


This is a very nice benefit, I can't agree more!

Because the backing memory of the firmware framebuffer occupied
belongs to the graphics hardware itself. For PCIe device, the
backing memory is typically the dedicated VRAM of the PCIe GPU.
But there are some exceptions, for example, the gma500. But I
think this can be fixed in the future, as majority(>99.9%) PCIe
GPU has the a dedicated VRAM.


For ARM and ARM64 platform device, the backing memory of the
firmware framebuffer may located at the system RAM. It's common
that the display controller is a platform device in the embedded
world. So I think the sysfb_parent_dev() function can be extended
to be able to works for platform device in the future.


The current approach has been taken from efifb. It would already not 
work reliably with gma500 or ARM SoCs. So there's no immediate loss of 
functionality AFAICT. But with the patchset now have a correct device 
hierarchy and PM for simpledrm, vesafb et al.


In the long term, I want to employ some of the logic in vgaarb that 
detects the firmware default device. That needs additional work, though.




Good ideas, try to be impressive.
I probably could help to test if I'm online.



Best regards
Thomas







Re: [RFC 1/8] cgroup: Add the DRM cgroup controller

2024-02-07 Thread Michal Koutný
Hello.

On Tue, Oct 24, 2023 at 05:07:20PM +0100, Tvrtko Ursulin 
 wrote:
> +struct drm_cgroup_state {
> + struct cgroup_subsys_state css;
> +};
> +
> +struct drm_root_cgroup_state {
> + struct drm_cgroup_state drmcs;
> +};
> +
> +static struct drm_root_cgroup_state root_drmcs;

Special struct type for root state is uncommon.
Have 
struct drm_cgroup_state root_drmcs;
and possible future members can be global state variables.


> +static void drmcs_free(struct cgroup_subsys_state *css)
> +{
> + struct drm_cgroup_state *drmcs = css_to_drmcs(css);
> +
> + if (drmcs != _drmcs.drmcs)
> + kfree(drmcs);
> +}

I think it can be relied on root cgroup not being ever free'd by cgroup
core.

Michal


signature.asc
Description: PGP signature


Re: [RFC 6/8] cgroup/drm: Introduce weight based drm cgroup control

2024-02-07 Thread Michal Koutný
Hello.

(I hope I'm replying to the latest iteration and it has some validitiy
still. Sorry for my late reply. Few points caught my attention.)

On Tue, Oct 24, 2023 at 05:07:25PM +0100, Tvrtko Ursulin 
 wrote:
> @@ -15,10 +17,28 @@ struct drm_cgroup_state {
>   struct cgroup_subsys_state css;
>  
>   struct list_head clients;
> +
> + unsigned int weight;
> +
> + unsigned int sum_children_weights;
> +
> + bool over;
> + bool over_budget;
> +
> + u64 per_s_budget_us;

Nit: sounds reversed (cf USEC_PER_SEC).

> +static int drmcg_period_ms = 2000;
> +module_param(drmcg_period_ms, int, 0644);
> +

cgroup subsystems as loadable modules were abandoded long time ago.
I'm not sure if this works as expected then.
The common way is __seutp(), see for instance __setup() in mm/memcontrol.c

> +static bool __start_scanning(unsigned int period_us)
...
> + css_for_each_descendant_post(node, >css) {
> + struct drm_cgroup_state *drmcs = css_to_drmcs(node);
> + struct drm_cgroup_state *parent;
> + u64 active;
> +
> + if (!css_tryget_online(node))
> + goto out;
> + if (!node->parent) {
> + css_put(node);
> + continue;
> + }

I think the parent check can go first witout put'ting (RCU is enough for
node).

> + if (!css_tryget_online(node->parent)) {
> + css_put(node);
> + goto out;
> + }

Online parent is implied onlined node. So this can be removed.

...
> +
> + css_put(node);
> + }

I wonder if the first passes could be implemented with rstat flushing
and then only invoke signalling based on the data. (As that's
best-effort).

> +
> + /*
> +  * 4th pass - send out over/under budget notifications.
> +  */
> + css_for_each_descendant_post(node, >css) {
> + struct drm_cgroup_state *drmcs = css_to_drmcs(node);
> +
> + if (!css_tryget_online(node))
> + goto out_retry;
> +
> + if (drmcs->over || drmcs->over_budget)
> + drmcs_signal_budget(drmcs,
> + drmcs->active_us,
> + drmcs->per_s_budget_us);
> + drmcs->over_budget = drmcs->over;
> +
> + css_put(node);
> + }

>  static struct cgroup_subsys_state *
> @@ -82,6 +365,7 @@ drmcs_alloc(struct cgroup_subsys_state *parent_css)
>  
>   if (!parent_css) {
>   drmcs = _drmcs.drmcs;
> + INIT_DELAYED_WORK(_drmcs.scan_work, scan_worker);

This reminds me discussion
https://lore.kernel.org/lkml/rlm36iypckvxol2edyr25jyo4imvlidtepbcjdaa2ouvwh3wjq@pqyuk3v2jesb/

I.e. worker needn't be initialized if controller is "invisible".

> +static void drmcs_attach(struct cgroup_taskset *tset)
> +{
> + struct drm_cgroup_state *old = old_drmcs;
> + struct cgroup_subsys_state *css;
> + struct drm_file *fpriv, *next;
> + struct drm_cgroup_state *new;
> + struct task_struct *task;
> + bool migrated = false;
> +
> + if (!old)
> + return;
> +
> + task = cgroup_taskset_first(tset, );
> + new = css_to_drmcs(task_css(task, drm_cgrp_id));
> + if (new == old)
> + return;
> +
> + mutex_lock(_mutex);
> +
> + list_for_each_entry_safe(fpriv, next, >clients, clink) {
> + cgroup_taskset_for_each(task, css, tset) {
> + struct cgroup_subsys_state *old_css;
> +
> + if (task->flags & PF_KTHREAD)
> + continue;

I'm curious, is this because of particular kthreads? Or would it fail
somehow below? (Like people should not migrate kthreads normally, so
their expectation cannot be high.)

Michal


signature.asc
Description: PGP signature


Re: [etnaviv-next v13 7/7] drm/etnaviv: Add support for vivante GPU cores attached via PCI(e)

2024-02-07 Thread Sui Jingfeng

Hi,


On 2024/2/7 17:35, Daniel Vetter wrote:

On Wed, Feb 07, 2024 at 01:27:59AM +0800, Sui Jingfeng wrote:

The component helper functions are the glue, which is used to bind multiple
GPU cores to a virtual master platform device. Which is fine and works well
for the SoCs who contains multiple GPU cores.

The problem is that usperspace programs (such as X server and Mesa) will
search the PCIe device to use if it is exist. In other words, usperspace
programs open the PCIe device with higher priority. Creating a virtual
master platform device for PCI(e) GPUs is unnecessary, as the PCI device
has been created by the time drm/etnaviv is loaded.

we create virtual platform devices as a representation for the vivante GPU
ip core. As all of subcomponent are attached via the PCIe master device,
we reflect this hardware layout by binding all of the virtual child to the
the real master.

Signed-off-by: Sui Jingfeng 

Uh so my understanding is that drivers really shouldn't create platform
devices of their own.



Yes,

At least for DT-based systems, this driver can be modified
to let the core to create the virtual master for us. We don't
have to create platform devices by our own(refer to the drm/etnaviv
driver).

I means that we could put the following example device node
into the .dts file.


gpu_2d: gpu@A {
compatible = "vivante,gc";
reg = <0xA 0x4000>;
};

gpu_3d: gpu@9 {
compatible = "vivante,gc";
reg = <0x9 0x4000>;
};

gpu@0 {
compatible = "etnaviv";
cores = <_2d _3d>;
dma-coherent;
dma-mask = <0x>
virtual_master;
};

But now, I'm afraid it's too late. Because the DTS/DTB may already have been
burned into board's BIOS for years. I guess, nowadays, modifying(changes)
this driver have to take the backward compatibility constraint into 
consideration.

Since we only have one chance to form the spec, that happens when this driver 
was
initially merged. Apparently, we miss it.




Re: [RFC] drm/i915: Add GuC submission interface version query

2024-02-07 Thread Joonas Lahtinen
Quoting Tvrtko Ursulin (2024-02-07 13:56:12)
> From: Tvrtko Ursulin 
> 
> Add a new query to the GuC submission interface version.
> 
> Mesa intends to use this information to check for old firmware versions
> with a known bug where using the render and compute command streamers
> simultaneously can cause GPU hangs due issues in firmware scheduling.
> 
> Based on patches from Vivaik and Joonas.
> 
> There is a little bit of an open around the width required for versions.
> While the GuC FW iface tells they are u8, i915 GuC code uses u32:
> 
>  #define CSS_SW_VERSION_UC_MAJOR   (0xFF << 16)
>  #define CSS_SW_VERSION_UC_MINOR   (0xFF << 8)
>  #define CSS_SW_VERSION_UC_PATCH   (0xFF << 0)
> ...
>  struct intel_uc_fw_ver {
>  u32 major;
>  u32 minor;
>  u32 patch;
>  u32 build;
>  };
> 
> So we could make the query u8, and refactor the struct intel_uc_fw_ver
> to use u8, or not. To avoid any doubts on why are we assigning u32 to
> u8 I simply opted to use u64. Which avoids the need to add any padding
> too.

This a single-shot init time query so I guess u64 is fine too, to keep
the code straightforward.

> Compile tested only.

If Mesa folks confirm this is working for them and after you add link to
the Mesa PR, then you can add my:

Reviewed-by: Joonas Lahtinen 

Regards, Joonas

> Signed-off-by: Tvrtko Ursulin 
> Cc: Kenneth Graunke 
> Cc: Jose Souza 
> Cc: Sagar Ghuge 
> Cc: Paulo Zanoni 
> Cc: John Harrison 
> Cc: Rodrigo Vivi 
> Cc: Jani Nikula 
> Cc: Tvrtko Ursulin 
> Cc: Vivaik Balasubrawmanian 
> ---
>  drivers/gpu/drm/i915/i915_query.c | 32 +++
>  include/uapi/drm/i915_drm.h   | 11 +++
>  2 files changed, 43 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_query.c 
> b/drivers/gpu/drm/i915/i915_query.c
> index 00871ef99792..999687f6a3d4 100644
> --- a/drivers/gpu/drm/i915/i915_query.c
> +++ b/drivers/gpu/drm/i915/i915_query.c
> @@ -551,6 +551,37 @@ static int query_hwconfig_blob(struct drm_i915_private 
> *i915,
> return hwconfig->size;
>  }
>  
> +static int
> +query_guc_submission_version(struct drm_i915_private *i915,
> +struct drm_i915_query_item *query)
> +{
> +   struct drm_i915_query_guc_submission_version __user *query_ptr =
> +   u64_to_user_ptr(query->data_ptr);
> +   struct drm_i915_query_guc_submission_version ver;
> +   struct intel_guc *guc = _gt(i915)->uc.guc;
> +   const size_t size = sizeof(ver);
> +   int ret;
> +
> +   if (!intel_uc_uses_guc_submission(_gt(i915)->uc))
> +   return -ENODEV;
> +
> +   ret = copy_query_item(, size, size, query);
> +   if (ret != 0)
> +   return ret;
> +
> +   if (ver.major || ver.minor || ver.patch)
> +   return -EINVAL;
> +
> +   ver.major = guc->submission_version.major;
> +   ver.minor = guc->submission_version.minor;
> +   ver.patch = guc->submission_version.patch;
> +
> +   if (copy_to_user(query_ptr, , size))
> +   return -EFAULT;
> +
> +   return 0;
> +}
> +
>  static int (* const i915_query_funcs[])(struct drm_i915_private *dev_priv,
> struct drm_i915_query_item 
> *query_item) = {
> query_topology_info,
> @@ -559,6 +590,7 @@ static int (* const i915_query_funcs[])(struct 
> drm_i915_private *dev_priv,
> query_memregion_info,
> query_hwconfig_blob,
> query_geometry_subslices,
> +   query_guc_submission_version,
>  };
>  
>  int i915_query_ioctl(struct drm_device *dev, void *data, struct drm_file 
> *file)
> diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
> index 550c496ce76d..d80d9b5e1eda 100644
> --- a/include/uapi/drm/i915_drm.h
> +++ b/include/uapi/drm/i915_drm.h
> @@ -3038,6 +3038,7 @@ struct drm_i915_query_item {
>  *  - %DRM_I915_QUERY_MEMORY_REGIONS (see struct 
> drm_i915_query_memory_regions)
>  *  - %DRM_I915_QUERY_HWCONFIG_BLOB (see `GuC HWCONFIG blob uAPI`)
>  *  - %DRM_I915_QUERY_GEOMETRY_SUBSLICES (see struct 
> drm_i915_query_topology_info)
> +*  - %DRM_I915_QUERY_GUC_SUBMISSION_VERSION (see struct 
> drm_i915_query_guc_submission_version)
>  */
> __u64 query_id;
>  #define DRM_I915_QUERY_TOPOLOGY_INFO   1
> @@ -3046,6 +3047,7 @@ struct drm_i915_query_item {
>  #define DRM_I915_QUERY_MEMORY_REGIONS  4
>  #define DRM_I915_QUERY_HWCONFIG_BLOB   5
>  #define DRM_I915_QUERY_GEOMETRY_SUBSLICES  6
> +#define DRM_I915_QUERY_GUC_SUBMISSION_VERSION  7
>  /* Must be kept compact -- no holes and well documented */
>  
> /**
> @@ -3591,6 +3593,15 @@ struct drm_i915_query_memory_regions {
> struct drm_i915_memory_region_info regions[];
>  };
>  
> +/**
> +* struct drm_i915_query_guc_submission_version - query GuC submission 
> interface version
> +*/
> +struct 

[PATCH v5 8/9] drm/mediatek: dsi: Compress of_device_id entries and add sentinel

2024-02-07 Thread AngeloGioacchino Del Regno
All entries fit in 82 columns, which is acceptable: compress all of
the mtk_dsi_of_match[] entries to a single line for each.

While at it, also add the usual sentinel comment to the last entry.

Reviewed-by: Alexandre Mergnat 
Signed-off-by: AngeloGioacchino Del Regno 

---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 17 ++---
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 195ff4dfc3a3..b644505de98a 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -1204,17 +1204,12 @@ static const struct mtk_dsi_driver_data 
mt8188_dsi_driver_data = {
 };
 
 static const struct of_device_id mtk_dsi_of_match[] = {
-   { .compatible = "mediatek,mt2701-dsi",
- .data = _dsi_driver_data },
-   { .compatible = "mediatek,mt8173-dsi",
- .data = _dsi_driver_data },
-   { .compatible = "mediatek,mt8183-dsi",
- .data = _dsi_driver_data },
-   { .compatible = "mediatek,mt8186-dsi",
- .data = _dsi_driver_data },
-   { .compatible = "mediatek,mt8188-dsi",
- .data = _dsi_driver_data },
-   { },
+   { .compatible = "mediatek,mt2701-dsi", .data = _dsi_driver_data 
},
+   { .compatible = "mediatek,mt8173-dsi", .data = _dsi_driver_data 
},
+   { .compatible = "mediatek,mt8183-dsi", .data = _dsi_driver_data 
},
+   { .compatible = "mediatek,mt8186-dsi", .data = _dsi_driver_data 
},
+   { .compatible = "mediatek,mt8188-dsi", .data = _dsi_driver_data 
},
+   { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, mtk_dsi_of_match);
 
-- 
2.43.0



[PATCH v5 6/9] drm/mediatek: dsi: Register DSI host after acquiring clocks and PHY

2024-02-07 Thread AngeloGioacchino Del Regno
Registering the dsi host with its ops before getting dsi->regs is
simply wrong: even though there's nothing (for now) asynchronously
calling those ops before the end of the probe function, installing
ops that are using iospace(s) and clocks before even initializing
those is too fragile.

Register the DSI host after getting clocks, iospace and PHY.
This wil also allow to simplify the error paths in a later commit.

Reviewed-by: Alexandre Mergnat 
Signed-off-by: AngeloGioacchino Del Regno 

---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 28 ++--
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 52758cab0abf..b3dd6251d611 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -1114,14 +1114,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
if (!dsi)
return -ENOMEM;
 
-   dsi->host.ops = _dsi_ops;
-   dsi->host.dev = dev;
-   ret = mipi_dsi_host_register(>host);
-   if (ret < 0) {
-   dev_err(dev, "failed to register DSI host: %d\n", ret);
-   return ret;
-   }
-
dsi->driver_data = of_device_get_match_data(dev);
 
dsi->engine_clk = devm_clk_get(dev, "engine");
@@ -1130,7 +1122,7 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 
if (ret != -EPROBE_DEFER)
dev_err(dev, "Failed to get engine clock: %d\n", ret);
-   goto err_unregister_host;
+   return ret;
}
 
dsi->digital_clk = devm_clk_get(dev, "digital");
@@ -1139,14 +1131,14 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 
if (ret != -EPROBE_DEFER)
dev_err(dev, "Failed to get digital clock: %d\n", ret);
-   goto err_unregister_host;
+   return ret;
}
 
dsi->hs_clk = devm_clk_get(dev, "hs");
if (IS_ERR(dsi->hs_clk)) {
ret = PTR_ERR(dsi->hs_clk);
dev_err(dev, "Failed to get hs clock: %d\n", ret);
-   goto err_unregister_host;
+   return ret;
}
 
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1154,20 +1146,28 @@ static int mtk_dsi_probe(struct platform_device *pdev)
if (IS_ERR(dsi->regs)) {
ret = PTR_ERR(dsi->regs);
dev_err(dev, "Failed to ioremap memory: %d\n", ret);
-   goto err_unregister_host;
+   return ret;
}
 
dsi->phy = devm_phy_get(dev, "dphy");
if (IS_ERR(dsi->phy)) {
ret = PTR_ERR(dsi->phy);
dev_err(dev, "Failed to get MIPI-DPHY: %d\n", ret);
-   goto err_unregister_host;
+   return ret;
}
 
irq_num = platform_get_irq(pdev, 0);
if (irq_num < 0) {
ret = irq_num;
-   goto err_unregister_host;
+   return ret;
+   }
+
+   dsi->host.ops = _dsi_ops;
+   dsi->host.dev = dev;
+   ret = mipi_dsi_host_register(>host);
+   if (ret < 0) {
+   dev_err(dev, "failed to register DSI host: %d\n", ret);
+   return ret;
}
 
ret = devm_request_irq(>dev, irq_num, mtk_dsi_irq,
-- 
2.43.0



[PATCH v5 5/9] drm/mediatek: dsi: Replace open-coded instance of HZ_PER_MHZ

2024-02-07 Thread AngeloGioacchino Del Regno
In mtk_dsi_phy_timconfig(), we're dividing the `data_rate` variable,
expressed in Hz to retrieve a value in MHz: instead of open-coding,
use the HZ_PER_MHZ definition, available in linux/units.h.

Reviewed-by: Alexandre Mergnat 
Signed-off-by: AngeloGioacchino Del Regno 

---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
b/drivers/gpu/drm/mediatek/mtk_dsi.c
index a330bb94c44a..52758cab0abf 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -13,6 +13,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -238,7 +239,7 @@ static void mtk_dsi_mask(struct mtk_dsi *dsi, u32 offset, 
u32 mask, u32 data)
 static void mtk_dsi_phy_timconfig(struct mtk_dsi *dsi)
 {
u32 timcon0, timcon1, timcon2, timcon3;
-   u32 data_rate_mhz = DIV_ROUND_UP(dsi->data_rate, 100);
+   u32 data_rate_mhz = DIV_ROUND_UP(dsi->data_rate, HZ_PER_MHZ);
struct mtk_phy_timing *timing = >phy_timing;
 
timing->lpx = (60 * data_rate_mhz / (8 * 1000)) + 1;
-- 
2.43.0



[PATCH v5 9/9] drm/mediatek: dsi: Use mipi_dsi_pixel_format_to_bpp() helper function

2024-02-07 Thread AngeloGioacchino Del Regno
Instead of open coding, use the mipi_dsi_pixel_format_to_bpp() helper
function from drm_mipi_dsi.h in mtk_dsi_poweron() and for validation
in mtk_dsi_bridge_mode_valid().

Note that this function changes the behavior of this driver: previously,
in case of unknown formats, it would (wrongly) assume that it should
account for a 24-bits format - now it will return an error and refuse
to set clocks and/or enable the DSI.

This is done because setting the wrong data rate will only produce a
garbage output that the display will misinterpret both because this
driver doesn't actually provide any extra-spec format support and/or
because the data rate (hence, the HS clock) will be wrong.

Reviewed-by: Alexandre Mergnat 
Signed-off-by: AngeloGioacchino Del Regno 

---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 26 +-
 1 file changed, 9 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
b/drivers/gpu/drm/mediatek/mtk_dsi.c
index b644505de98a..9501f4019199 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -598,19 +598,12 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
if (++dsi->refcount != 1)
return 0;
 
-   switch (dsi->format) {
-   case MIPI_DSI_FMT_RGB565:
-   bit_per_pixel = 16;
-   break;
-   case MIPI_DSI_FMT_RGB666_PACKED:
-   bit_per_pixel = 18;
-   break;
-   case MIPI_DSI_FMT_RGB666:
-   case MIPI_DSI_FMT_RGB888:
-   default:
-   bit_per_pixel = 24;
-   break;
+   ret = mipi_dsi_pixel_format_to_bpp(dsi->format);
+   if (ret < 0) {
+   dev_err(dev, "Unknown MIPI DSI format %d\n", dsi->format);
+   return ret;
}
+   bit_per_pixel = ret;
 
dsi->data_rate = DIV_ROUND_UP_ULL(dsi->vm.pixelclock * bit_per_pixel,
  dsi->lanes);
@@ -793,12 +786,11 @@ mtk_dsi_bridge_mode_valid(struct drm_bridge *bridge,
  const struct drm_display_mode *mode)
 {
struct mtk_dsi *dsi = bridge_to_dsi(bridge);
-   u32 bpp;
+   int bpp;
 
-   if (dsi->format == MIPI_DSI_FMT_RGB565)
-   bpp = 16;
-   else
-   bpp = 24;
+   bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
+   if (bpp < 0)
+   return MODE_ERROR;
 
if (mode->clock * bpp / dsi->lanes > 150)
return MODE_CLOCK_HIGH;
-- 
2.43.0



[PATCH v5 7/9] drm/mediatek: dsi: Simplify with dev_err_probe and remove gotos

2024-02-07 Thread AngeloGioacchino Del Regno
Most of the functions that are called in the probe callback are
devm managed, or all but mipi_dsi_host_register(): simplify the probe
function's error paths with dev_err_probe() and remove the lonely
instance of `goto err_unregister_host` by just directly calling the
mipi_dsi_host_unregister() function in the devm_request_irq() error
path, allowing to also remove the same label.

Reviewed-by: Alexandre Mergnat 
Signed-off-by: AngeloGioacchino Del Regno 

---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 60 +-
 1 file changed, 18 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
b/drivers/gpu/drm/mediatek/mtk_dsi.c
index b3dd6251d611..195ff4dfc3a3 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -1117,64 +1117,44 @@ static int mtk_dsi_probe(struct platform_device *pdev)
dsi->driver_data = of_device_get_match_data(dev);
 
dsi->engine_clk = devm_clk_get(dev, "engine");
-   if (IS_ERR(dsi->engine_clk)) {
-   ret = PTR_ERR(dsi->engine_clk);
+   if (IS_ERR(dsi->engine_clk))
+   return dev_err_probe(dev, PTR_ERR(dsi->engine_clk),
+"Failed to get engine clock\n");
 
-   if (ret != -EPROBE_DEFER)
-   dev_err(dev, "Failed to get engine clock: %d\n", ret);
-   return ret;
-   }
 
dsi->digital_clk = devm_clk_get(dev, "digital");
-   if (IS_ERR(dsi->digital_clk)) {
-   ret = PTR_ERR(dsi->digital_clk);
-
-   if (ret != -EPROBE_DEFER)
-   dev_err(dev, "Failed to get digital clock: %d\n", ret);
-   return ret;
-   }
+   if (IS_ERR(dsi->digital_clk))
+   return dev_err_probe(dev, PTR_ERR(dsi->digital_clk),
+"Failed to get digital clock\n");
 
dsi->hs_clk = devm_clk_get(dev, "hs");
-   if (IS_ERR(dsi->hs_clk)) {
-   ret = PTR_ERR(dsi->hs_clk);
-   dev_err(dev, "Failed to get hs clock: %d\n", ret);
-   return ret;
-   }
+   if (IS_ERR(dsi->hs_clk))
+   return dev_err_probe(dev, PTR_ERR(dsi->hs_clk), "Failed to get 
hs clock\n");
 
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
dsi->regs = devm_ioremap_resource(dev, regs);
-   if (IS_ERR(dsi->regs)) {
-   ret = PTR_ERR(dsi->regs);
-   dev_err(dev, "Failed to ioremap memory: %d\n", ret);
-   return ret;
-   }
+   if (IS_ERR(dsi->regs))
+   return dev_err_probe(dev, PTR_ERR(dsi->regs), "Failed to 
ioremap memory\n");
 
dsi->phy = devm_phy_get(dev, "dphy");
-   if (IS_ERR(dsi->phy)) {
-   ret = PTR_ERR(dsi->phy);
-   dev_err(dev, "Failed to get MIPI-DPHY: %d\n", ret);
-   return ret;
-   }
+   if (IS_ERR(dsi->phy))
+   return dev_err_probe(dev, PTR_ERR(dsi->phy), "Failed to get 
MIPI-DPHY\n");
 
irq_num = platform_get_irq(pdev, 0);
-   if (irq_num < 0) {
-   ret = irq_num;
-   return ret;
-   }
+   if (irq_num < 0)
+   return irq_num;
 
dsi->host.ops = _dsi_ops;
dsi->host.dev = dev;
ret = mipi_dsi_host_register(>host);
-   if (ret < 0) {
-   dev_err(dev, "failed to register DSI host: %d\n", ret);
-   return ret;
-   }
+   if (ret < 0)
+   return dev_err_probe(dev, ret, "Failed to register DSI host\n");
 
ret = devm_request_irq(>dev, irq_num, mtk_dsi_irq,
   IRQF_TRIGGER_NONE, dev_name(>dev), dsi);
if (ret) {
-   dev_err(>dev, "failed to request mediatek dsi irq\n");
-   goto err_unregister_host;
+   mipi_dsi_host_unregister(>host);
+   return dev_err_probe(>dev, ret, "Failed to request DSI 
irq\n");
}
 
init_waitqueue_head(>irq_wait_queue);
@@ -1186,10 +1166,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
 
return 0;
-
-err_unregister_host:
-   mipi_dsi_host_unregister(>host);
-   return ret;
 }
 
 static void mtk_dsi_remove(struct platform_device *pdev)
-- 
2.43.0



[PATCH v5 4/9] drm/mediatek: dsi: Use bitfield macros where useful

2024-02-07 Thread AngeloGioacchino Del Regno
Instead of open coding bitshifting for various register fields,
use the bitfield macro FIELD_PREP(): this allows to enhance the
human readability, decrease likeliness of mistakes (and register
field overflowing) and also to simplify the code.
The latter is especially seen in mtk_dsi_rxtx_control(), where
it was possible to change a switch to a short for loop and to
also remove the need to check for maximum DSI lanes == 4 thanks
to the FIELD_PREP macro masking the value.

While at it, also add the missing DA_HS_SYNC bitmask, used in
mtk_dsi_phy_timconfig().

Reviewed-by: Alexandre Mergnat 
Signed-off-by: AngeloGioacchino Del Regno 

---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 97 --
 1 file changed, 52 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 7d38e9500700..a330bb94c44a 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -3,6 +3,7 @@
  * Copyright (c) 2015 MediaTek Inc.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -70,16 +71,19 @@
 #define DSI_PSCTRL 0x1c
 #define DSI_PS_WC  GENMASK(13, 0)
 #define DSI_PS_SEL GENMASK(17, 16)
-#define PACKED_PS_16BIT_RGB565 (0 << 16)
-#define PACKED_PS_18BIT_RGB666 (1 << 16)
-#define LOOSELY_PS_24BIT_RGB666(2 << 16)
-#define PACKED_PS_24BIT_RGB888 (3 << 16)
+#define PACKED_PS_16BIT_RGB565 0
+#define PACKED_PS_18BIT_RGB666 1
+#define LOOSELY_PS_24BIT_RGB6662
+#define PACKED_PS_24BIT_RGB888 3
 
 #define DSI_VSA_NL 0x20
 #define DSI_VBP_NL 0x24
 #define DSI_VFP_NL 0x28
 #define DSI_VACT_NL0x2C
+#define VACT_NLGENMASK(14, 0)
 #define DSI_SIZE_CON   0x38
+#define DSI_HEIGHT GENMASK(30, 16)
+#define DSI_WIDTH  GENMASK(14, 0)
 #define DSI_HSA_WC 0x50
 #define DSI_HBP_WC 0x54
 #define DSI_HFP_WC 0x58
@@ -122,6 +126,7 @@
 
 #define DSI_PHY_TIMECON2   0x118
 #define CONT_DET   GENMASK(7, 0)
+#define DA_HS_SYNC GENMASK(15, 8)
 #define CLK_ZERO   GENMASK(23, 16)
 #define CLK_TRAIL  GENMASK(31, 24)
 
@@ -253,14 +258,23 @@ static void mtk_dsi_phy_timconfig(struct mtk_dsi *dsi)
timing->clk_hs_zero = timing->clk_hs_trail * 4;
timing->clk_hs_exit = 2 * timing->clk_hs_trail;
 
-   timcon0 = timing->lpx | timing->da_hs_prepare << 8 |
- timing->da_hs_zero << 16 | timing->da_hs_trail << 24;
-   timcon1 = timing->ta_go | timing->ta_sure << 8 |
- timing->ta_get << 16 | timing->da_hs_exit << 24;
-   timcon2 = 1 << 8 | timing->clk_hs_zero << 16 |
- timing->clk_hs_trail << 24;
-   timcon3 = timing->clk_hs_prepare | timing->clk_hs_post << 8 |
- timing->clk_hs_exit << 16;
+   timcon0 = FIELD_PREP(LPX, timing->lpx) |
+ FIELD_PREP(HS_PREP, timing->da_hs_prepare) |
+ FIELD_PREP(HS_ZERO, timing->da_hs_zero) |
+ FIELD_PREP(HS_TRAIL, timing->da_hs_trail);
+
+   timcon1 = FIELD_PREP(TA_GO, timing->ta_go) |
+ FIELD_PREP(TA_SURE, timing->ta_sure) |
+ FIELD_PREP(TA_GET, timing->ta_get) |
+ FIELD_PREP(DA_HS_EXIT, timing->da_hs_exit);
+
+   timcon2 = FIELD_PREP(DA_HS_SYNC, 1) |
+ FIELD_PREP(CLK_ZERO, timing->clk_hs_zero) |
+ FIELD_PREP(CLK_TRAIL, timing->clk_hs_trail);
+
+   timcon3 = FIELD_PREP(CLK_HS_PREP, timing->clk_hs_prepare) |
+ FIELD_PREP(CLK_HS_POST, timing->clk_hs_post) |
+ FIELD_PREP(CLK_HS_EXIT, timing->clk_hs_exit);
 
writel(timcon0, dsi->regs + DSI_PHY_TIMECON0);
writel(timcon1, dsi->regs + DSI_PHY_TIMECON1);
@@ -353,69 +367,61 @@ static void mtk_dsi_set_vm_cmd(struct mtk_dsi *dsi)
 
 static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
 {
-   u32 tmp_reg;
+   u32 regval, tmp_reg = 0;
+   u8 i;
 
-   switch (dsi->lanes) {
-   case 1:
-   tmp_reg = 1 << 2;
-   break;
-   case 2:
-   tmp_reg = 3 << 2;
-   break;
-   case 3:
-   tmp_reg = 7 << 2;
-   break;
-   case 4:
-   tmp_reg = 0xf << 2;
-   break;
-   default:
-   tmp_reg = 0xf << 2;
-   break;
-   }
+   /* Number of DSI lanes (max 4 lanes), each bit enables one DSI lane. */
+   for (i = 0; i < dsi->lanes; i++)
+   tmp_reg |= BIT(i);
+
+   regval = FIELD_PREP(LANE_NUM, tmp_reg);
 
if (dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)
-   tmp_reg |= HSTX_CKLP_EN;
+   regval |= HSTX_CKLP_EN;
 
if 

[PATCH v5 1/9] drm/mediatek: dsi: Use GENMASK() for register mask definitions

2024-02-07 Thread AngeloGioacchino Del Regno
Change magic numerical masks with usage of the GENMASK() macro
to improve readability.

This commit brings no functional changes.

Reviewed-by: Alexandre Mergnat 
Signed-off-by: AngeloGioacchino Del Regno 

---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 45 +++---
 1 file changed, 23 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
b/drivers/gpu/drm/mediatek/mtk_dsi.c
index a2fdfc8ddb15..c66e18006070 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -58,18 +58,18 @@
 
 #define DSI_TXRX_CTRL  0x18
 #define VC_NUM BIT(1)
-#define LANE_NUM   (0xf << 2)
+#define LANE_NUM   GENMASK(5, 2)
 #define DIS_EOTBIT(6)
 #define NULL_ENBIT(7)
 #define TE_FREERUN BIT(8)
 #define EXT_TE_EN  BIT(9)
 #define EXT_TE_EDGEBIT(10)
-#define MAX_RTN_SIZE   (0xf << 12)
+#define MAX_RTN_SIZE   GENMASK(15, 12)
 #define HSTX_CKLP_EN   BIT(16)
 
 #define DSI_PSCTRL 0x1c
-#define DSI_PS_WC  0x3fff
-#define DSI_PS_SEL (3 << 16)
+#define DSI_PS_WC  GENMASK(13, 0)
+#define DSI_PS_SEL GENMASK(17, 16)
 #define PACKED_PS_16BIT_RGB565 (0 << 16)
 #define LOOSELY_PS_18BIT_RGB666(1 << 16)
 #define PACKED_PS_18BIT_RGB666 (2 << 16)
@@ -109,26 +109,26 @@
 #define LD0_WAKEUP_EN  BIT(2)
 
 #define DSI_PHY_TIMECON0   0x110
-#define LPX(0xff << 0)
-#define HS_PREP(0xff << 8)
-#define HS_ZERO(0xff << 16)
-#define HS_TRAIL   (0xff << 24)
+#define LPXGENMASK(7, 0)
+#define HS_PREPGENMASK(15, 8)
+#define HS_ZEROGENMASK(23, 16)
+#define HS_TRAIL   GENMASK(31, 24)
 
 #define DSI_PHY_TIMECON1   0x114
-#define TA_GO  (0xff << 0)
-#define TA_SURE(0xff << 8)
-#define TA_GET (0xff << 16)
-#define DA_HS_EXIT (0xff << 24)
+#define TA_GO  GENMASK(7, 0)
+#define TA_SUREGENMASK(15, 8)
+#define TA_GET GENMASK(23, 16)
+#define DA_HS_EXIT GENMASK(31, 24)
 
 #define DSI_PHY_TIMECON2   0x118
-#define CONT_DET   (0xff << 0)
-#define CLK_ZERO   (0xff << 16)
-#define CLK_TRAIL  (0xff << 24)
+#define CONT_DET   GENMASK(7, 0)
+#define CLK_ZERO   GENMASK(23, 16)
+#define CLK_TRAIL  GENMASK(31, 24)
 
 #define DSI_PHY_TIMECON3   0x11c
-#define CLK_HS_PREP(0xff << 0)
-#define CLK_HS_POST(0xff << 8)
-#define CLK_HS_EXIT(0xff << 16)
+#define CLK_HS_PREPGENMASK(7, 0)
+#define CLK_HS_POSTGENMASK(15, 8)
+#define CLK_HS_EXITGENMASK(23, 16)
 
 #define DSI_VM_CMD_CON 0x130
 #define VM_CMD_EN  BIT(0)
@@ -138,13 +138,14 @@
 #define FORCE_COMMIT   BIT(0)
 #define BYPASS_SHADOW  BIT(1)
 
-#define CONFIG (0xff << 0)
+/* CMDQ related bits */
+#define CONFIG GENMASK(7, 0)
 #define SHORT_PACKET   0
 #define LONG_PACKET2
 #define BTABIT(2)
-#define DATA_ID(0xff << 8)
-#define DATA_0 (0xff << 16)
-#define DATA_1 (0xff << 24)
+#define DATA_IDGENMASK(15, 8)
+#define DATA_0 GENMASK(23, 16)
+#define DATA_1 GENMASK(31, 24)
 
 #define NS_TO_CYCLE(n, c)((n) / (c) + (((n) % (c)) ? 1 : 0))
 
-- 
2.43.0



[PATCH v5 3/9] drm/mediatek: dsi: Cleanup functions mtk_dsi_ps_control{_vact}()

2024-02-07 Thread AngeloGioacchino Del Regno
Function mtk_dsi_ps_control() is a subset of mtk_dsi_ps_control_vact():
merge the two in one mtk_dsi_ps_control() function by adding one
function parameter `config_vact` which, when true, writes the VACT
related registers.

Reviewed-by: Fei Shao 
Reviewed-by: Alexandre Mergnat 
Signed-off-by: AngeloGioacchino Del Regno 

---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 76 +-
 1 file changed, 23 insertions(+), 53 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 8af0afbe9e3d..7d38e9500700 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -351,40 +351,6 @@ static void mtk_dsi_set_vm_cmd(struct mtk_dsi *dsi)
mtk_dsi_mask(dsi, DSI_VM_CMD_CON, TS_VFP_EN, TS_VFP_EN);
 }
 
-static void mtk_dsi_ps_control_vact(struct mtk_dsi *dsi)
-{
-   struct videomode *vm = >vm;
-   u32 dsi_buf_bpp, ps_wc;
-   u32 ps_bpp_mode;
-
-   if (dsi->format == MIPI_DSI_FMT_RGB565)
-   dsi_buf_bpp = 2;
-   else
-   dsi_buf_bpp = 3;
-
-   ps_wc = vm->hactive * dsi_buf_bpp;
-   ps_bpp_mode = ps_wc;
-
-   switch (dsi->format) {
-   case MIPI_DSI_FMT_RGB888:
-   ps_bpp_mode |= PACKED_PS_24BIT_RGB888;
-   break;
-   case MIPI_DSI_FMT_RGB666:
-   ps_bpp_mode |= LOOSELY_PS_24BIT_RGB666;
-   break;
-   case MIPI_DSI_FMT_RGB666_PACKED:
-   ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
-   break;
-   case MIPI_DSI_FMT_RGB565:
-   ps_bpp_mode |= PACKED_PS_16BIT_RGB565;
-   break;
-   }
-
-   writel(vm->vactive, dsi->regs + DSI_VACT_NL);
-   writel(ps_bpp_mode, dsi->regs + DSI_PSCTRL);
-   writel(ps_wc, dsi->regs + DSI_HSTX_CKL_WC);
-}
-
 static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
 {
u32 tmp_reg;
@@ -416,36 +382,40 @@ static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
writel(tmp_reg, dsi->regs + DSI_TXRX_CTRL);
 }
 
-static void mtk_dsi_ps_control(struct mtk_dsi *dsi)
+static void mtk_dsi_ps_control(struct mtk_dsi *dsi, bool config_vact)
 {
-   u32 dsi_tmp_buf_bpp;
-   u32 tmp_reg;
+   struct videomode *vm = >vm;
+   u32 dsi_buf_bpp, ps_wc;
+   u32 ps_bpp_mode;
+
+   if (dsi->format == MIPI_DSI_FMT_RGB565)
+   dsi_buf_bpp = 2;
+   else
+   dsi_buf_bpp = 3;
+
+   ps_wc = vm->hactive * dsi_buf_bpp;
+   ps_bpp_mode = ps_wc;
 
switch (dsi->format) {
case MIPI_DSI_FMT_RGB888:
-   tmp_reg = PACKED_PS_24BIT_RGB888;
-   dsi_tmp_buf_bpp = 3;
+   ps_bpp_mode |= PACKED_PS_24BIT_RGB888;
break;
case MIPI_DSI_FMT_RGB666:
-   tmp_reg = LOOSELY_PS_24BIT_RGB666;
-   dsi_tmp_buf_bpp = 3;
+   ps_bpp_mode |= LOOSELY_PS_24BIT_RGB666;
break;
case MIPI_DSI_FMT_RGB666_PACKED:
-   tmp_reg = PACKED_PS_18BIT_RGB666;
-   dsi_tmp_buf_bpp = 3;
+   ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
break;
case MIPI_DSI_FMT_RGB565:
-   tmp_reg = PACKED_PS_16BIT_RGB565;
-   dsi_tmp_buf_bpp = 2;
-   break;
-   default:
-   tmp_reg = PACKED_PS_24BIT_RGB888;
-   dsi_tmp_buf_bpp = 3;
+   ps_bpp_mode |= PACKED_PS_16BIT_RGB565;
break;
}
 
-   tmp_reg += dsi->vm.hactive * dsi_tmp_buf_bpp & DSI_PS_WC;
-   writel(tmp_reg, dsi->regs + DSI_PSCTRL);
+   if (config_vact) {
+   writel(vm->vactive, dsi->regs + DSI_VACT_NL);
+   writel(ps_wc, dsi->regs + DSI_HSTX_CKL_WC);
+   }
+   writel(ps_bpp_mode, dsi->regs + DSI_PSCTRL);
 }
 
 static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
@@ -521,7 +491,7 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
writel(horizontal_backporch_byte, dsi->regs + DSI_HBP_WC);
writel(horizontal_frontporch_byte, dsi->regs + DSI_HFP_WC);
 
-   mtk_dsi_ps_control(dsi);
+   mtk_dsi_ps_control(dsi, false);
 }
 
 static void mtk_dsi_start(struct mtk_dsi *dsi)
@@ -666,7 +636,7 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
mtk_dsi_reset_engine(dsi);
mtk_dsi_phy_timconfig(dsi);
 
-   mtk_dsi_ps_control_vact(dsi);
+   mtk_dsi_ps_control(dsi, true);
mtk_dsi_set_vm_cmd(dsi);
mtk_dsi_config_vdo_timing(dsi);
mtk_dsi_set_interrupt_enable(dsi);
-- 
2.43.0



[PATCH v5 2/9] drm/mediatek: dsi: Fix DSI RGB666 formats and definitions

2024-02-07 Thread AngeloGioacchino Del Regno
The register bits definitions for RGB666 formats are wrong in multiple
ways: first, in the DSI_PS_SEL bits region, the Packed 18-bits RGB666
format is selected with bit 1, while the Loosely Packed one is bit 2,
and second - the definition name "LOOSELY_PS_18BIT_RGB666" is wrong
because the loosely packed format is 24 bits instead!

Either way, functions mtk_dsi_ps_control_vact() and mtk_dsi_ps_control()
do not even agree on the DSI_PS_SEL bit to set in DSI_PSCTRL: one sets
loosely packed (24) on RGB666, the other sets packed (18), and the other
way around for RGB666_PACKED.

Fixing this entire stack of issues is done in one go:
 - Use the correct bit for the Loosely Packed RGB666 definition
 - Rename LOOSELY_PS_18BIT_RGB666 to LOOSELY_PS_24BIT_RGB666
 - Change ps_bpp_mode in mtk_dsi_ps_control_vact() to set:
- Loosely Packed, 24-bits for MIPI_DSI_FMT_RGB666
- Packed, 18-bits for MIPI_DSI_FMT_RGB666_PACKED

Fixes: 2e54c14e310f ("drm/mediatek: Add DSI sub driver")
Reviewed-by: Alexandre Mergnat 
Signed-off-by: AngeloGioacchino Del Regno 

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

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
b/drivers/gpu/drm/mediatek/mtk_dsi.c
index c66e18006070..8af0afbe9e3d 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -71,8 +71,8 @@
 #define DSI_PS_WC  GENMASK(13, 0)
 #define DSI_PS_SEL GENMASK(17, 16)
 #define PACKED_PS_16BIT_RGB565 (0 << 16)
-#define LOOSELY_PS_18BIT_RGB666(1 << 16)
-#define PACKED_PS_18BIT_RGB666 (2 << 16)
+#define PACKED_PS_18BIT_RGB666 (1 << 16)
+#define LOOSELY_PS_24BIT_RGB666(2 << 16)
 #define PACKED_PS_24BIT_RGB888 (3 << 16)
 
 #define DSI_VSA_NL 0x20
@@ -370,10 +370,10 @@ static void mtk_dsi_ps_control_vact(struct mtk_dsi *dsi)
ps_bpp_mode |= PACKED_PS_24BIT_RGB888;
break;
case MIPI_DSI_FMT_RGB666:
-   ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
+   ps_bpp_mode |= LOOSELY_PS_24BIT_RGB666;
break;
case MIPI_DSI_FMT_RGB666_PACKED:
-   ps_bpp_mode |= LOOSELY_PS_18BIT_RGB666;
+   ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
break;
case MIPI_DSI_FMT_RGB565:
ps_bpp_mode |= PACKED_PS_16BIT_RGB565;
@@ -427,7 +427,7 @@ static void mtk_dsi_ps_control(struct mtk_dsi *dsi)
dsi_tmp_buf_bpp = 3;
break;
case MIPI_DSI_FMT_RGB666:
-   tmp_reg = LOOSELY_PS_18BIT_RGB666;
+   tmp_reg = LOOSELY_PS_24BIT_RGB666;
dsi_tmp_buf_bpp = 3;
break;
case MIPI_DSI_FMT_RGB666_PACKED:
-- 
2.43.0



[PATCH v5 0/9] MediaTek DRM - DSI driver cleanups

2024-02-07 Thread AngeloGioacchino Del Regno
Changes in v5:
 - Changed patch 1 to not fix the DSI_PS_SEL mask for newer SoCs

Changes in v4:
 - Added a fix for RGB666 formats setting and for wrong register
   definitions for packed vs loosely packed formats
 - Added a commit to make use of mipi_dsi_pixel_format_to_bpp() helper
   instead of open coding the same

Changes in v3:
 - Rebased over next-20240131
 - Added bitfield.h inclusion in patch 3
 - Added three more cleanup commits to the mix to simplify
   the probe function and remove gotos.

Changes in v2:
 - Rebased over next-20231213

This series performs some cleanups for mtk_dsi, enhancing human
readability, using kernel provided macros where possible and
also reducing code size.

Tested on MT8173 and MT8192 Chromebooks (using a DSI<->DP bridge)
and on MT6795 Sony Xperia M5 (DSI video mode panel).


AngeloGioacchino Del Regno (9):
  drm/mediatek: dsi: Use GENMASK() for register mask definitions
  drm/mediatek: dsi: Fix DSI RGB666 formats and definitions
  drm/mediatek: dsi: Cleanup functions mtk_dsi_ps_control{_vact}()
  drm/mediatek: dsi: Use bitfield macros where useful
  drm/mediatek: dsi: Replace open-coded instance of HZ_PER_MHZ
  drm/mediatek: dsi: Register DSI host after acquiring clocks and PHY
  drm/mediatek: dsi: Simplify with dev_err_probe and remove gotos
  drm/mediatek: dsi: Compress of_device_id entries and add sentinel
  drm/mediatek: dsi: Use mipi_dsi_pixel_format_to_bpp() helper function

 drivers/gpu/drm/mediatek/mtk_dsi.c | 310 -
 1 file changed, 126 insertions(+), 184 deletions(-)

-- 
2.43.0



Re: [PATCH v2 2/4] eventfd: simplify eventfd_signal()

2024-02-07 Thread Paolo Bonzini
On Wed, Nov 22, 2023 at 1:49 PM Christian Brauner  wrote:
>
> Ever since the evenfd type was introduced back in 2007 in commit
> e1ad7468c77d ("signal/timer/event: eventfd core") the eventfd_signal()
> function only ever passed 1 as a value for @n. There's no point in
> keeping that additional argument.
>
> Signed-off-by: Christian Brauner 
> ---
>  arch/x86/kvm/hyperv.c |  2 +-
>  arch/x86/kvm/xen.c|  2 +-
>  virt/kvm/eventfd.c|  4 ++--
>  30 files changed, 60 insertions(+), 63 deletions(-)

For KVM:

Acked-by: Paolo Bonzini 



Re: [PATCH v2 2/4] eventfd: simplify eventfd_signal()

2024-02-07 Thread Anthony Krowiak

For vfio_ap_ops.c

Reviewed-by: Anthony Krowiak 

On 2/6/24 2:44 PM, Stefan Hajnoczi wrote:

vhost and VIRTIO-related parts:

Reviewed-by: Stefan Hajnoczi 

On Wed, 22 Nov 2023 at 07:50, Christian Brauner  wrote:

Ever since the evenfd type was introduced back in 2007 in commit
e1ad7468c77d ("signal/timer/event: eventfd core") the eventfd_signal()
function only ever passed 1 as a value for @n. There's no point in
keeping that additional argument.

Signed-off-by: Christian Brauner 
---
  arch/x86/kvm/hyperv.c |  2 +-
  arch/x86/kvm/xen.c|  2 +-
  drivers/accel/habanalabs/common/device.c  |  2 +-
  drivers/fpga/dfl.c|  2 +-
  drivers/gpu/drm/drm_syncobj.c |  6 +++---
  drivers/gpu/drm/i915/gvt/interrupt.c  |  2 +-
  drivers/infiniband/hw/mlx5/devx.c |  2 +-
  drivers/misc/ocxl/file.c  |  2 +-
  drivers/s390/cio/vfio_ccw_chp.c   |  2 +-
  drivers/s390/cio/vfio_ccw_drv.c   |  4 ++--
  drivers/s390/cio/vfio_ccw_ops.c   |  6 +++---
  drivers/s390/crypto/vfio_ap_ops.c |  2 +-
  drivers/usb/gadget/function/f_fs.c|  4 ++--
  drivers/vdpa/vdpa_user/vduse_dev.c|  6 +++---
  drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c|  2 +-
  drivers/vfio/pci/vfio_pci_core.c  |  6 +++---
  drivers/vfio/pci/vfio_pci_intrs.c | 12 ++--
  drivers/vfio/platform/vfio_platform_irq.c |  4 ++--
  drivers/vhost/vdpa.c  |  4 ++--
  drivers/vhost/vhost.c | 10 +-
  drivers/vhost/vhost.h |  2 +-
  drivers/virt/acrn/ioeventfd.c |  2 +-
  drivers/xen/privcmd.c |  2 +-
  fs/aio.c  |  2 +-
  fs/eventfd.c  |  9 +++--
  include/linux/eventfd.h   |  4 ++--
  mm/memcontrol.c   | 10 +-
  mm/vmpressure.c   |  2 +-
  samples/vfio-mdev/mtty.c  |  4 ++--
  virt/kvm/eventfd.c|  4 ++--
  30 files changed, 60 insertions(+), 63 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index 238afd7335e4..4943f6b2bbee 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -2388,7 +2388,7 @@ static u16 kvm_hvcall_signal_event(struct kvm_vcpu *vcpu, 
struct kvm_hv_hcall *h
 if (!eventfd)
 return HV_STATUS_INVALID_PORT_ID;

-   eventfd_signal(eventfd, 1);
+   eventfd_signal(eventfd);
 return HV_STATUS_SUCCESS;
  }

diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c
index e53fad915a62..523bb6df5ac9 100644
--- a/arch/x86/kvm/xen.c
+++ b/arch/x86/kvm/xen.c
@@ -2088,7 +2088,7 @@ static bool kvm_xen_hcall_evtchn_send(struct kvm_vcpu 
*vcpu, u64 param, u64 *r)
 if (ret < 0 && ret != -ENOTCONN)
 return false;
 } else {
-   eventfd_signal(evtchnfd->deliver.eventfd.ctx, 1);
+   eventfd_signal(evtchnfd->deliver.eventfd.ctx);
 }

 *r = 0;
diff --git a/drivers/accel/habanalabs/common/device.c 
b/drivers/accel/habanalabs/common/device.c
index 9711e8fc979d..3a89644f087c 100644
--- a/drivers/accel/habanalabs/common/device.c
+++ b/drivers/accel/habanalabs/common/device.c
@@ -2044,7 +2044,7 @@ static void hl_notifier_event_send(struct 
hl_notifier_event *notifier_event, u64
 notifier_event->events_mask |= event_mask;

 if (notifier_event->eventfd)
-   eventfd_signal(notifier_event->eventfd, 1);
+   eventfd_signal(notifier_event->eventfd);

 mutex_unlock(_event->lock);
  }
diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c
index dd7a783d53b5..e73f88050f08 100644
--- a/drivers/fpga/dfl.c
+++ b/drivers/fpga/dfl.c
@@ -1872,7 +1872,7 @@ static irqreturn_t dfl_irq_handler(int irq, void *arg)
  {
 struct eventfd_ctx *trigger = arg;

-   eventfd_signal(trigger, 1);
+   eventfd_signal(trigger);
 return IRQ_HANDLED;
  }

diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 01da6789d044..b9cc62982196 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -1365,7 +1365,7 @@ static void syncobj_eventfd_entry_fence_func(struct 
dma_fence *fence,
 struct syncobj_eventfd_entry *entry =
 container_of(cb, struct syncobj_eventfd_entry, fence_cb);

-   eventfd_signal(entry->ev_fd_ctx, 1);
+   eventfd_signal(entry->ev_fd_ctx);
 syncobj_eventfd_entry_free(entry);
  }

@@ -1388,13 +1388,13 @@ syncobj_eventfd_entry_func(struct drm_syncobj *syncobj,
 entry->fence = fence;

 if (entry->flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE) {
-   eventfd_signal(entry->ev_fd_ctx, 1);
+   eventfd_signal(entry->ev_fd_ctx);
 syncobj_eventfd_entry_free(entry);
 } else {
 ret = 

Re: [PATCH 14/19] drm/i915/dp: Compute DP tunel BW during encoder state computation

2024-02-07 Thread Imre Deak
On Wed, Feb 07, 2024 at 01:25:19AM +0200, Ville Syrjälä wrote:
> On Tue, Jan 23, 2024 at 12:28:45PM +0200, Imre Deak wrote:
> > Compute the BW required through a DP tunnel on links with such tunnels
> > detected and add the corresponding atomic state during a modeset.
> > 
> > Signed-off-by: Imre Deak 
> > ---
> >  drivers/gpu/drm/i915/display/intel_dp.c | 16 +---
> >  drivers/gpu/drm/i915/display/intel_dp_mst.c | 13 +
> >  2 files changed, 26 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp.c 
> > b/drivers/gpu/drm/i915/display/intel_dp.c
> > index 78dfe8be6031d..6968fdb7ffcdf 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> > @@ -2880,6 +2880,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
> > struct drm_connector_state *conn_state)
> >  {
> > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> > +   struct intel_atomic_state *state = 
> > to_intel_atomic_state(conn_state->state);
> > struct drm_display_mode *adjusted_mode = _config->hw.adjusted_mode;
> > struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> > const struct drm_display_mode *fixed_mode;
> > @@ -2980,6 +2981,9 @@ intel_dp_compute_config(struct intel_encoder *encoder,
> > intel_dp_compute_vsc_sdp(intel_dp, pipe_config, conn_state);
> > intel_dp_compute_hdr_metadata_infoframe_sdp(intel_dp, pipe_config, 
> > conn_state);
> >  
> > +   intel_dp_tunnel_atomic_compute_stream_bw(state, intel_dp, connector,
> > +pipe_config);
> 
> Error handling seems awol?

Yes, along with checking the return from
drm_dp_tunnel_atomic_set_stream_bw(), thanks for spotting this.

> 
> > +
> > return 0;
> >  }
> >  
> > @@ -6087,6 +6091,15 @@ static int intel_dp_connector_atomic_check(struct 
> > drm_connector *conn,
> > return ret;
> > }
> >  
> > +   if (!intel_connector_needs_modeset(state, conn))
> > +   return 0;
> > +
> > +   ret = intel_dp_tunnel_atomic_check_state(state,
> > +intel_dp,
> > +intel_conn);
> > +   if (ret)
> > +   return ret;
> > +
> > /*
> >  * We don't enable port sync on BDW due to missing w/as and
> >  * due to not having adjusted the modeset sequence appropriately.
> > @@ -6094,9 +6107,6 @@ static int intel_dp_connector_atomic_check(struct 
> > drm_connector *conn,
> > if (DISPLAY_VER(dev_priv) < 9)
> > return 0;
> >  
> > -   if (!intel_connector_needs_modeset(state, conn))
> > -   return 0;
> > -
> > if (conn->has_tile) {
> > ret = intel_modeset_tile_group(state, conn->tile_group->id);
> > if (ret)
> > diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c 
> > b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > index 520393dc8b453..cbfab3173b9ef 100644
> > --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
> > @@ -42,6 +42,7 @@
> >  #include "intel_dp.h"
> >  #include "intel_dp_hdcp.h"
> >  #include "intel_dp_mst.h"
> > +#include "intel_dp_tunnel.h"
> >  #include "intel_dpio_phy.h"
> >  #include "intel_hdcp.h"
> >  #include "intel_hotplug.h"
> > @@ -523,6 +524,7 @@ static int intel_dp_mst_compute_config(struct 
> > intel_encoder *encoder,
> >struct drm_connector_state *conn_state)
> >  {
> > struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
> > +   struct intel_atomic_state *state = 
> > to_intel_atomic_state(conn_state->state);
> > struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
> > struct intel_dp *intel_dp = _mst->primary->dp;
> > const struct intel_connector *connector =
> > @@ -619,6 +621,9 @@ static int intel_dp_mst_compute_config(struct 
> > intel_encoder *encoder,
> >  
> > intel_psr_compute_config(intel_dp, pipe_config, conn_state);
> >  
> > +   intel_dp_tunnel_atomic_compute_stream_bw(state, intel_dp, connector,
> > +pipe_config);
> > +
> > return 0;
> >  }
> >  
> > @@ -876,6 +881,14 @@ intel_dp_mst_atomic_check(struct drm_connector 
> > *connector,
> > if (ret)
> > return ret;
> >  
> > +   if (intel_connector_needs_modeset(state, connector)) {
> > +   ret = intel_dp_tunnel_atomic_check_state(state,
> > +
> > intel_connector->mst_port,
> > +intel_connector);
> > +   if (ret)
> > +   return ret;
> > +   }
> > +
> > return drm_dp_atomic_release_time_slots(>base,
> > 
> > _connector->mst_port->mst_mgr,
> > intel_connector->port);
> > -- 
> > 2.39.2
> 
> -- 
> Ville Syrjälä

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

2024-02-07 Thread Rodrigo Vivi
On Wed, Feb 07, 2024 at 05:17:19PM +1100, Stephen Rothwell wrote:
> Hi all,
> 
> After merging the drm tree, today's linux-next build (htmldocs)
> produced this warning:
> 
> Documentation/gpu/rfc/index.rst:35: WARNING: toctree contains reference to 
> nonexisting document 'gpu/rfc/xe'
> 
> Introduced by commit
> 
>   d11dc7aa98e5 ("drm/doc/rfc: Remove Xe's pre-merge plan")

It should be fixed by commit 70a46e1fda3b ("drm/doc/rfc: Removing missing 
reference to xe.rst")
that is part of drm-misc/drm-misc-next and drm-misc/for-linux-next

> 
> -- 
> Cheers,
> Stephen Rothwell




Re: [PATCH v5 2/2] phy: mtk-mipi-csi: add driver for CSI phy

2024-02-07 Thread Vinod Koul


On Thu, 11 Jan 2024 11:17:30 +0100, Julien Stephan wrote:
> This is a new driver that supports the MIPI CSI CD-PHY version 0.5
> 
> The number of PHYs depend on the SoC.
> Each PHY can support D-PHY only or CD-PHY configuration.
> The driver supports only D-PHY mode, so CD-PHY
> compatible PHY are configured in D-PHY mode.
> 
> [...]

Applied, thanks!

[2/2] phy: mtk-mipi-csi: add driver for CSI phy
  commit: 673d70cb3c652ad6d97594e03225bbdf20226216

Best regards,
-- 
~Vinod




Re: [PATCH 3/4] media: platform: replace of_graph_get_next_endpoint()

2024-02-07 Thread Laurent Pinchart
On Tue, Feb 06, 2024 at 11:45:58PM +, Kuninori Morimoto wrote:
> 
> Hi Laurent
> 
> Thank you for your review
> 
> > > diff --git a/drivers/media/platform/samsung/exynos4-is/mipi-csis.c 
> > > b/drivers/media/platform/samsung/exynos4-is/mipi-csis.c
> > > index 686ca8753ba2..3f8bea2e3934 100644
> > > --- a/drivers/media/platform/samsung/exynos4-is/mipi-csis.c
> > > +++ b/drivers/media/platform/samsung/exynos4-is/mipi-csis.c
> > > @@ -728,7 +728,7 @@ static int s5pcsis_parse_dt(struct platform_device 
> > > *pdev,
> > >>max_num_lanes))
> > >   return -EINVAL;
> > >  
> > > - node = of_graph_get_next_endpoint(node, NULL);
> > > + node = of_graph_get_endpoint_by_regs(node, 0, -1);
> > 
> > This is not correct, see
> > Documentation/devicetree/bindings/media/samsung,exynos4210-csis.yaml.
> 
> Hmm... Then, It can be like this ?
> 
>   + node = of_graph_get_endpoint_by_regs(node, -1, -1);

I suppose that would work, even if we should really try not to pass -1
for the port. Rob, any opinion ?

-- 
Regards,

Laurent Pinchart


Re: [PATCH 2/4] media: i2c: replace of_graph_get_next_endpoint()

2024-02-07 Thread Laurent Pinchart
On Wed, Feb 07, 2024 at 02:13:05PM +0100, Krzysztof Hałasa wrote:
> Laurent,
> 
> Laurent Pinchart  writes:
> 
> >> +++ b/drivers/media/i2c/adv7604.c
> >> @@ -3205,7 +3205,7 @@ static int adv76xx_parse_dt(struct adv76xx_state 
> >> *state)
> >>   np = state->i2c_clients[ADV76XX_PAGE_IO]->dev.of_node;
> >>
> >>   /* Parse the endpoint. */
> >> - endpoint = of_graph_get_next_endpoint(np, NULL);
> >> + endpoint = of_graph_get_endpoint_by_regs(np, 0, -1);
> >
> > I think this should be port 1 for the adv7611 and port2 for the adv7612.
> > The adv7610 may need to use port 1 too, but the bindings likely need to
> > be updated.
> 
> To be honest I have no idea about ADV7611 and 7612.
> The 7610 I have on Tinyrex "mobo" seems to be single port.

One issue is that the commit that added the adv7610 compatible string to
the DT bindings (commit 901a52c43359, "media: Add ADV7610 support for
adv7604 driver - DT docs.") didn't extend the conditional rules further
down in the file that defines what ports are needed. That's why I don't
know what was intended. I believe the adv7610 should be treated like the
adv7611, given that the driver has

{ .compatible = "adi,adv7610", .data = _chip_info[ADV7611] },
{ .compatible = "adi,adv7611", .data = _chip_info[ADV7611] },

Could you send a patch to address that in the DT bindings ?

> ADV7611 seems to be mostly a 7610 in a different package (LQFP 64
> instead of some BGA 76). The driver simply treats ADV7610 as a 7611.
> 
> ADV7612 is apparently dual port (only one port can be used at a time)
> though:
> 
> [ADV7612] = {
> .type = ADV7612,
> .has_afe = false,
> .max_port = ADV76XX_PAD_HDMI_PORT_A,/* B not supported */
> .num_dv_ports = 1,  /* normally 2 */
> 
> 
> All related in-tree DTS entries (as of v6.8.0-rc1) seem to be ADV7612.
> 
> To me it seems all known devices use the first port only.

-- 
Regards,

Laurent Pinchart


Re: [PATCH 2/4] media: i2c: replace of_graph_get_next_endpoint()

2024-02-07 Thread Hans Verkuil
On 07/02/2024 14:51, Laurent Pinchart wrote:
> On Wed, Feb 07, 2024 at 02:14:33PM +0100, Krzysztof Hałasa wrote:
>> Hans,
>>
>> Hans Verkuil  writes:
>>
>>> Ideally someone would have to actually test this, perhaps with one of those
>>> Renesas boards. While I do have one, it got bricked after I attempted a
>>> u-boot update :-(
>>
>> May be reversible, though.
> 
> Maybe Morimoto-san could help ? :-) What board did you use Hans ?
> 

I have a Koelsch. I tried to update uboot at one time, but bricked it and was
unable to get a different uboot installed.

It would be nice if it can be revived.

Regards,

Hans


Re: [PATCH 2/4] media: i2c: replace of_graph_get_next_endpoint()

2024-02-07 Thread Laurent Pinchart
On Wed, Feb 07, 2024 at 02:14:33PM +0100, Krzysztof Hałasa wrote:
> Hans,
> 
> Hans Verkuil  writes:
> 
> > Ideally someone would have to actually test this, perhaps with one of those
> > Renesas boards. While I do have one, it got bricked after I attempted a
> > u-boot update :-(
> 
> May be reversible, though.

Maybe Morimoto-san could help ? :-) What board did you use Hans ?

-- 
Regards,

Laurent Pinchart


[PATCH v3 3/8] firmware/sysfb: Set firmware-framebuffer parent device

2024-02-07 Thread Thomas Zimmermann
Set the firmware framebuffer's parent device, which usually is the
graphics hardware's physical device. Integrates the framebuffer in
the Linux device hierarchy and lets Linux handle dependencies among
devices. For example, the graphics hardware won't be suspended while
the firmware device is still active.

v3:
* fix build for CONFIG_SYSFB_SIMPLEFB=n (Sui)
* test result of screen_info_pci_dev() for errors (Sui)
v2:
* detect parent device in sysfb_parent_dev()

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Javier Martinez Canillas 
---
 drivers/firmware/sysfb.c  | 21 -
 drivers/firmware/sysfb_simplefb.c |  5 -
 include/linux/sysfb.h |  6 --
 3 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/sysfb.c b/drivers/firmware/sysfb.c
index 3c197db42c9d9..4e104f3de4b95 100644
--- a/drivers/firmware/sysfb.c
+++ b/drivers/firmware/sysfb.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -69,9 +70,23 @@ void sysfb_disable(void)
 }
 EXPORT_SYMBOL_GPL(sysfb_disable);
 
+static __init struct device *sysfb_parent_dev(const struct screen_info *si)
+{
+   struct pci_dev *pdev;
+
+   pdev = screen_info_pci_dev(si);
+   if (IS_ERR(pdev))
+   return ERR_CAST(pdev);
+   else if (pdev)
+   return >dev;
+
+   return NULL;
+}
+
 static __init int sysfb_init(void)
 {
struct screen_info *si = _info;
+   struct device *parent;
struct simplefb_platform_data mode;
const char *name;
bool compatible;
@@ -83,10 +98,12 @@ static __init int sysfb_init(void)
 
sysfb_apply_efi_quirks();
 
+   parent = sysfb_parent_dev(si);
+
/* try to create a simple-framebuffer device */
compatible = sysfb_parse_mode(si, );
if (compatible) {
-   pd = sysfb_create_simplefb(si, );
+   pd = sysfb_create_simplefb(si, , parent);
if (!IS_ERR(pd))
goto unlock_mutex;
}
@@ -109,6 +126,8 @@ static __init int sysfb_init(void)
goto unlock_mutex;
}
 
+   pd->dev.parent = parent;
+
sysfb_set_efifb_fwnode(pd);
 
ret = platform_device_add_data(pd, si, sizeof(*si));
diff --git a/drivers/firmware/sysfb_simplefb.c 
b/drivers/firmware/sysfb_simplefb.c
index 74363ed7501f6..75a186bf8f8ec 100644
--- a/drivers/firmware/sysfb_simplefb.c
+++ b/drivers/firmware/sysfb_simplefb.c
@@ -91,7 +91,8 @@ __init bool sysfb_parse_mode(const struct screen_info *si,
 }
 
 __init struct platform_device *sysfb_create_simplefb(const struct screen_info 
*si,
-const struct 
simplefb_platform_data *mode)
+const struct 
simplefb_platform_data *mode,
+struct device *parent)
 {
struct platform_device *pd;
struct resource res;
@@ -143,6 +144,8 @@ __init struct platform_device *sysfb_create_simplefb(const 
struct screen_info *s
if (!pd)
return ERR_PTR(-ENOMEM);
 
+   pd->dev.parent = parent;
+
sysfb_set_efifb_fwnode(pd);
 
ret = platform_device_add_resources(pd, , 1);
diff --git a/include/linux/sysfb.h b/include/linux/sysfb.h
index 19cb803dd5ecd..9a007ea2d3635 100644
--- a/include/linux/sysfb.h
+++ b/include/linux/sysfb.h
@@ -91,7 +91,8 @@ static inline void sysfb_set_efifb_fwnode(struct 
platform_device *pd)
 bool sysfb_parse_mode(const struct screen_info *si,
  struct simplefb_platform_data *mode);
 struct platform_device *sysfb_create_simplefb(const struct screen_info *si,
- const struct 
simplefb_platform_data *mode);
+ const struct 
simplefb_platform_data *mode,
+ struct device *parent);
 
 #else /* CONFIG_SYSFB_SIMPLE */
 
@@ -102,7 +103,8 @@ static inline bool sysfb_parse_mode(const struct 
screen_info *si,
 }
 
 static inline struct platform_device *sysfb_create_simplefb(const struct 
screen_info *si,
-   const struct 
simplefb_platform_data *mode)
+   const struct 
simplefb_platform_data *mode,
+   struct device 
*parent);
 {
return ERR_PTR(-EINVAL);
 }
-- 
2.43.0



[PATCH v3 6/8] fbdev/efifb: Do not track parent device status

2024-02-07 Thread Thomas Zimmermann
There will be no EFI framebuffer device for disabled parent devices
and thus we never probe efifb in that case. Hence remove the tracking
code from efifb.

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Javier Martinez Canillas 
---
 drivers/video/fbdev/efifb.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c
index e66ef35fa6b62..f76b7ae007518 100644
--- a/drivers/video/fbdev/efifb.c
+++ b/drivers/video/fbdev/efifb.c
@@ -348,8 +348,6 @@ static struct attribute *efifb_attrs[] = {
 };
 ATTRIBUTE_GROUPS(efifb);
 
-static bool pci_dev_disabled;  /* FB base matches BAR of a disabled device */
-
 static struct resource *bar_resource;
 static u64 bar_offset;
 
@@ -377,7 +375,7 @@ static int efifb_probe(struct platform_device *dev)
if (!si)
return -ENOMEM;
 
-   if (si->orig_video_isVGA != VIDEO_TYPE_EFI || pci_dev_disabled)
+   if (si->orig_video_isVGA != VIDEO_TYPE_EFI)
return -ENODEV;
 
if (fb_get_options("efifb", ))
@@ -653,7 +651,6 @@ static void record_efifb_bar_resource(struct pci_dev *dev, 
int idx, u64 offset)
 
pci_read_config_word(dev, PCI_COMMAND, );
if (!(word & PCI_COMMAND_MEMORY)) {
-   pci_dev_disabled = true;
dev_err(>dev,
"BAR %d: assigned to efifb but device is disabled!\n",
idx);
-- 
2.43.0



[PATCH v3 0/8] firmware/sysfb: Track parent device for screen_info

2024-02-07 Thread Thomas Zimmermann
Detect the firmware framebuffer's parent device from the global
screen_info state and set up the framebuffer's device accordingly.
Remove the equivalent functionality from efifb. Other drivers for
firmware framebuffers, such as simpledrm or vesafb, now add these
new features.

Patches 1 and 2 provide a set of helper functions to avoid parsing
the screen_info values manually. Decoding screen_info is fragile and
many drivers get it wrong. We should later adopt these helpers in
existing drivers, such as efifb, vesafb, as well.

Patches 3 and 4 set the firmware framebuffer's parent device. There
is code in efifb to do something similar for power management. That
is now obsolete and being cleaned up. Setting the parent device makes
Linux track the power management correctly.

Patches 5 and 6 track the parent device's enable state. We don't
create framebuffer devices if the underlying hardware device has been
disabled. Remove the functionality from efifb.

Patches 7 and 8 track the parent device's PCI BAR location. It can
happen on aarch64 that the firmware framebuffer moves its location
during the kernel's boot. We now fix up the screen_info state to
point to the correct location. Again remove such functionality from
efifb.

v3:
* filter PCI device list with pci_get_base_class() (Sui)
* fix error handling for screen_info_pci_dev() (Sui)
* fix build for CONFIG_SYSFB_SIMPLEFB=n (Sui)
* small cleanups
v2:
* small refactorings throughout the patchset

Thomas Zimmermann (8):
  video: Add helpers for decoding screen_info
  video: Provide screen_info_get_pci_dev() to find screen_info's PCI
device
  firmware/sysfb: Set firmware-framebuffer parent device
  fbdev/efifb: Remove PM for parent device
  firmware/sysfb: Create firmware device only for enabled PCI devices
  fbdev/efifb: Do not track parent device status
  firmware/sysfb: Update screen_info for relocated EFI framebuffers
  fbdev/efifb: Remove framebuffer relocation tracking

 drivers/firmware/Kconfig|   1 +
 drivers/firmware/sysfb.c|  51 +-
 drivers/firmware/sysfb_simplefb.c   |   5 +-
 drivers/video/Kconfig   |   4 +
 drivers/video/Makefile  |   4 +
 drivers/video/fbdev/efifb.c |  97 +-
 drivers/video/screen_info_generic.c | 146 
 drivers/video/screen_info_pci.c | 136 ++
 include/linux/screen_info.h | 126 
 include/linux/sysfb.h   |   6 +-
 10 files changed, 480 insertions(+), 96 deletions(-)
 create mode 100644 drivers/video/screen_info_generic.c
 create mode 100644 drivers/video/screen_info_pci.c

-- 
2.43.0



[PATCH v3 8/8] fbdev/efifb: Remove framebuffer relocation tracking

2024-02-07 Thread Thomas Zimmermann
If the firmware framebuffer has been reloacted, the sysfb code
fixes the screen_info state before it creates the framebuffer's
platform device. Efifb will automatically receive a screen_info
with updated values. Hence remove the tracking from efifb.

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Javier Martinez Canillas 
Acked-by: Sui Jingfeng 
---
 drivers/video/fbdev/efifb.c | 76 +
 1 file changed, 1 insertion(+), 75 deletions(-)

diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c
index f76b7ae007518..8dd82afb3452b 100644
--- a/drivers/video/fbdev/efifb.c
+++ b/drivers/video/fbdev/efifb.c
@@ -13,7 +13,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -47,8 +46,6 @@ static bool use_bgrt = true;
 static bool request_mem_succeeded = false;
 static u64 mem_flags = EFI_MEMORY_WC | EFI_MEMORY_UC;
 
-static struct pci_dev *efifb_pci_dev;  /* dev with BAR covering the efifb */
-
 struct efifb_par {
u32 pseudo_palette[16];
resource_size_t base;
@@ -348,9 +345,6 @@ static struct attribute *efifb_attrs[] = {
 };
 ATTRIBUTE_GROUPS(efifb);
 
-static struct resource *bar_resource;
-static u64 bar_offset;
-
 static int efifb_probe(struct platform_device *dev)
 {
struct screen_info *si;
@@ -411,21 +405,7 @@ static int efifb_probe(struct platform_device *dev)
si->rsvd_pos = 24;
}
 
-   efifb_fix.smem_start = si->lfb_base;
-
-   if (si->capabilities & VIDEO_CAPABILITY_64BIT_BASE) {
-   u64 ext_lfb_base;
-
-   ext_lfb_base = (u64)(unsigned long)si->ext_lfb_base << 32;
-   efifb_fix.smem_start |= ext_lfb_base;
-   }
-
-   if (bar_resource &&
-   bar_resource->start + bar_offset != efifb_fix.smem_start) {
-   dev_info(_pci_dev->dev,
-"BAR has moved, updating efifb address\n");
-   efifb_fix.smem_start = bar_resource->start + bar_offset;
-   }
+   efifb_fix.smem_start = __screen_info_lfb_base(si);
 
efifb_defined.bits_per_pixel = si->lfb_depth;
efifb_defined.xres = si->lfb_width;
@@ -640,57 +620,3 @@ static struct platform_driver efifb_driver = {
 };
 
 builtin_platform_driver(efifb_driver);
-
-#if defined(CONFIG_PCI)
-
-static void record_efifb_bar_resource(struct pci_dev *dev, int idx, u64 offset)
-{
-   u16 word;
-
-   efifb_pci_dev = dev;
-
-   pci_read_config_word(dev, PCI_COMMAND, );
-   if (!(word & PCI_COMMAND_MEMORY)) {
-   dev_err(>dev,
-   "BAR %d: assigned to efifb but device is disabled!\n",
-   idx);
-   return;
-   }
-
-   bar_resource = >resource[idx];
-   bar_offset = offset;
-
-   dev_info(>dev, "BAR %d: assigned to efifb\n", idx);
-}
-
-static void efifb_fixup_resources(struct pci_dev *dev)
-{
-   u64 base = screen_info.lfb_base;
-   u64 size = screen_info.lfb_size;
-   int i;
-
-   if (efifb_pci_dev || screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
-   return;
-
-   if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE)
-   base |= (u64)screen_info.ext_lfb_base << 32;
-
-   if (!base)
-   return;
-
-   for (i = 0; i < PCI_STD_NUM_BARS; i++) {
-   struct resource *res = >resource[i];
-
-   if (!(res->flags & IORESOURCE_MEM))
-   continue;
-
-   if (res->start <= base && res->end >= base + size - 1) {
-   record_efifb_bar_resource(dev, i, base - res->start);
-   break;
-   }
-   }
-}
-DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY,
-  16, efifb_fixup_resources);
-
-#endif
-- 
2.43.0



[PATCH v3 5/8] firmware/sysfb: Create firmware device only for enabled PCI devices

2024-02-07 Thread Thomas Zimmermann
Test if the firmware framebuffer's parent PCI device, if any, has
been enabled. If not, the firmware framebuffer is most likely not
working. Hence, do not create a device for the firmware framebuffer
on disabled PCI devices.

So far, efifb tracked the status of the PCI parent device internally
and did not bind if it was disabled. This patch implements the
functionality for all PCI-based firmware framebuffers.

v3:
* make commit message more precise (Sui)
v2:
* rework sysfb_pci_dev_is_enabled() (Javier)

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Javier Martinez Canillas 
---
 drivers/firmware/sysfb.c | 32 ++--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/drivers/firmware/sysfb.c b/drivers/firmware/sysfb.c
index 4e104f3de4b95..170b7cd0cfcbf 100644
--- a/drivers/firmware/sysfb.c
+++ b/drivers/firmware/sysfb.c
@@ -70,15 +70,41 @@ void sysfb_disable(void)
 }
 EXPORT_SYMBOL_GPL(sysfb_disable);
 
+#if defined(CONFIG_PCI)
+static __init bool sysfb_pci_dev_is_enabled(struct pci_dev *pdev)
+{
+   /*
+* TODO: Try to integrate this code into the PCI subsystem
+*/
+   int ret;
+   u16 command;
+
+   ret = pci_read_config_word(pdev, PCI_COMMAND, );
+   if (ret != PCIBIOS_SUCCESSFUL)
+   return false;
+   if (!(command & PCI_COMMAND_MEMORY))
+   return false;
+   return true;
+}
+#else
+static __init bool sysfb_pci_dev_is_enabled(struct pci_dev *pdev)
+{
+   return false;
+}
+#endif
+
 static __init struct device *sysfb_parent_dev(const struct screen_info *si)
 {
struct pci_dev *pdev;
 
pdev = screen_info_pci_dev(si);
-   if (IS_ERR(pdev))
+   if (IS_ERR(pdev)) {
return ERR_CAST(pdev);
-   else if (pdev)
+   } else if (pdev) {
+   if (!sysfb_pci_dev_is_enabled(pdev))
+   return ERR_PTR(-ENODEV);
return >dev;
+   }
 
return NULL;
 }
@@ -99,6 +125,8 @@ static __init int sysfb_init(void)
sysfb_apply_efi_quirks();
 
parent = sysfb_parent_dev(si);
+   if (IS_ERR(parent))
+   goto unlock_mutex;
 
/* try to create a simple-framebuffer device */
compatible = sysfb_parse_mode(si, );
-- 
2.43.0



[PATCH v3 2/8] video: Provide screen_info_get_pci_dev() to find screen_info's PCI device

2024-02-07 Thread Thomas Zimmermann
Add screen_info_get_pci_dev() to find the PCI device of an instance
of screen_info. Does nothing on systems without PCI bus.

v3:
* search PCI device with pci_get_base_class() (Sui)
v2:
* remove ret from screen_info_pci_dev() (Javier)

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Javier Martinez Canillas 
---
 drivers/video/Makefile  |  1 +
 drivers/video/screen_info_pci.c | 48 +
 include/linux/screen_info.h | 10 +++
 3 files changed, 59 insertions(+)
 create mode 100644 drivers/video/screen_info_pci.c

diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 117cbdbb58c2c..ffbac4387c670 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_VIDEO)   += cmdline.o nomodeset.o
 obj-$(CONFIG_HDMI)+= hdmi.o
 
 screen_info-y:= screen_info_generic.o
+screen_info-$(CONFIG_PCI) += screen_info_pci.o
 
 obj-$(CONFIG_VT) += console/
 obj-$(CONFIG_FB_STI) += console/
diff --git a/drivers/video/screen_info_pci.c b/drivers/video/screen_info_pci.c
new file mode 100644
index 0..d8985a54ce717
--- /dev/null
+++ b/drivers/video/screen_info_pci.c
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include 
+#include 
+
+static struct pci_dev *__screen_info_pci_dev(struct resource *res)
+{
+   struct pci_dev *pdev = NULL;
+   const struct resource *r = NULL;
+
+   if (!(res->flags & IORESOURCE_MEM))
+   return NULL;
+
+   while (!r && (pdev = pci_get_base_class(PCI_BASE_CLASS_DISPLAY, pdev))) 
{
+   r = pci_find_resource(pdev, res);
+   }
+
+   return pdev;
+}
+
+/**
+ * screen_info_pci_dev() - Return PCI parent device that contains 
screen_info's framebuffer
+ * @si: the screen_info
+ *
+ * Returns:
+ * The screen_info's parent device or NULL on success, or a pointer-encoded
+ * errno value otherwise. The value NULL is not an error. It signals that no
+ * PCI device has been found.
+ */
+struct pci_dev *screen_info_pci_dev(const struct screen_info *si)
+{
+   struct resource res[SCREEN_INFO_MAX_RESOURCES];
+   ssize_t i, numres;
+
+   numres = screen_info_resources(si, res, ARRAY_SIZE(res));
+   if (numres < 0)
+   return ERR_PTR(numres);
+
+   for (i = 0; i < numres; ++i) {
+   struct pci_dev *pdev = __screen_info_pci_dev([i]);
+
+   if (pdev)
+   return pdev;
+   }
+
+   return NULL;
+}
+EXPORT_SYMBOL(screen_info_pci_dev);
diff --git a/include/linux/screen_info.h b/include/linux/screen_info.h
index e7a02c5609d12..0eae08e3c6f90 100644
--- a/include/linux/screen_info.h
+++ b/include/linux/screen_info.h
@@ -9,6 +9,7 @@
  */
 #define SCREEN_INFO_MAX_RESOURCES  3
 
+struct pci_dev;
 struct resource;
 
 static inline bool __screen_info_has_lfb(unsigned int type)
@@ -104,6 +105,15 @@ static inline unsigned int screen_info_video_type(const 
struct screen_info *si)
 
 ssize_t screen_info_resources(const struct screen_info *si, struct resource 
*r, size_t num);
 
+#if defined(CONFIG_PCI)
+struct pci_dev *screen_info_pci_dev(const struct screen_info *si);
+#else
+static inline struct pci_dev *screen_info_pci_dev(const struct screen_info *si)
+{
+   return NULL;
+}
+#endif
+
 extern struct screen_info screen_info;
 
 #endif /* _SCREEN_INFO_H */
-- 
2.43.0



[PATCH v3 7/8] firmware/sysfb: Update screen_info for relocated EFI framebuffers

2024-02-07 Thread Thomas Zimmermann
On ARM PCI systems, the PCI hierarchy might be reconfigured during
boot and the firmware framebuffer might move as a result of that.
The values in screen_info will then be invalid.

Work around this problem by tracking the framebuffer's initial
location before it get relocated; then fix the screen_info state
between reloaction and creating the firmware framebuffer's device.

This functionality has been lifted from efifb. See the commit message
of commit 55d728a40d36 ("efi/fb: Avoid reconfiguration of BAR that
covers the framebuffer") for more information.

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Javier Martinez Canillas 
---
 drivers/firmware/sysfb.c|  2 +
 drivers/video/screen_info_pci.c | 88 +
 include/linux/screen_info.h | 16 ++
 3 files changed, 106 insertions(+)

diff --git a/drivers/firmware/sysfb.c b/drivers/firmware/sysfb.c
index 170b7cd0cfcbf..a6b48703dc9e9 100644
--- a/drivers/firmware/sysfb.c
+++ b/drivers/firmware/sysfb.c
@@ -118,6 +118,8 @@ static __init int sysfb_init(void)
bool compatible;
int ret = 0;
 
+   screen_info_apply_fixups();
+
mutex_lock(_lock);
if (disabled)
goto unlock_mutex;
diff --git a/drivers/video/screen_info_pci.c b/drivers/video/screen_info_pci.c
index d8985a54ce717..6c58335171410 100644
--- a/drivers/video/screen_info_pci.c
+++ b/drivers/video/screen_info_pci.c
@@ -1,7 +1,95 @@
 // SPDX-License-Identifier: GPL-2.0
 
 #include 
+#include 
 #include 
+#include 
+
+static struct pci_dev *screen_info_lfb_pdev;
+static size_t screen_info_lfb_bar;
+static resource_size_t screen_info_lfb_offset;
+static struct resource screen_info_lfb_res = DEFINE_RES_MEM(0, 0);
+
+static bool __screen_info_relocation_is_valid(const struct screen_info *si, 
struct resource *pr)
+{
+   u64 size = __screen_info_lfb_size(si, screen_info_video_type(si));
+
+   if (screen_info_lfb_offset > resource_size(pr))
+   return false;
+   if (size > resource_size(pr))
+   return false;
+   if (resource_size(pr) - size < screen_info_lfb_offset)
+   return false;
+
+   return true;
+}
+
+void screen_info_apply_fixups(void)
+{
+   struct screen_info *si = _info;
+
+   if (screen_info_lfb_pdev) {
+   struct resource *pr = 
_info_lfb_pdev->resource[screen_info_lfb_bar];
+
+   if (pr->start != screen_info_lfb_res.start) {
+   if (__screen_info_relocation_is_valid(si, pr)) {
+   /*
+* Only update base if we have an actual
+* relocation to a valid I/O range.
+*/
+   __screen_info_set_lfb_base(si, pr->start + 
screen_info_lfb_offset);
+   pr_info("Relocating firmware framebuffer to 
offset %pa[d] within %pr\n",
+   _info_lfb_offset, pr);
+   } else {
+   pr_warn("Invalid relocating, disabling firmware 
framebuffer\n");
+   }
+   }
+   }
+}
+
+static void screen_info_fixup_lfb(struct pci_dev *pdev)
+{
+   unsigned int type;
+   struct resource res[SCREEN_INFO_MAX_RESOURCES];
+   size_t i, numres;
+   int ret;
+   const struct screen_info *si = _info;
+
+   if (screen_info_lfb_pdev)
+   return; // already found
+
+   type = screen_info_video_type(si);
+   if (type != VIDEO_TYPE_EFI)
+   return; // only applies to EFI
+
+   ret = screen_info_resources(si, res, ARRAY_SIZE(res));
+   if (ret < 0)
+   return;
+   numres = ret;
+
+   for (i = 0; i < numres; ++i) {
+   struct resource *r = [i];
+   const struct resource *pr;
+
+   if (!(r->flags & IORESOURCE_MEM))
+   continue;
+   pr = pci_find_resource(pdev, r);
+   if (!pr)
+   continue;
+
+   /*
+* We've found a PCI device with the framebuffer
+* resource. Store away the parameters to track
+* relocation of the framebuffer aperture.
+*/
+   screen_info_lfb_pdev = pdev;
+   screen_info_lfb_bar = pr - pdev->resource;
+   screen_info_lfb_offset = r->start - pr->start;
+   memcpy(_info_lfb_res, r, sizeof(screen_info_lfb_res));
+   }
+}
+DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY, 
16,
+  screen_info_fixup_lfb);
 
 static struct pci_dev *__screen_info_pci_dev(struct resource *res)
 {
diff --git a/include/linux/screen_info.h b/include/linux/screen_info.h
index 0eae08e3c6f90..75303c126285a 100644
--- a/include/linux/screen_info.h
+++ b/include/linux/screen_info.h
@@ -4,6 +4,8 @@
 
 #include 
 
+#include 

[PATCH v3 4/8] fbdev/efifb: Remove PM for parent device

2024-02-07 Thread Thomas Zimmermann
The EFI device has the correct parent device set. This allows Linux
to handle the power management internally. Hence, remove the manual
PM management for the parent device from efifb.

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Javier Martinez Canillas 
---
 drivers/video/fbdev/efifb.c | 16 +++-
 1 file changed, 3 insertions(+), 13 deletions(-)

diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c
index 10fc14ad5d127..e66ef35fa6b62 100644
--- a/drivers/video/fbdev/efifb.c
+++ b/drivers/video/fbdev/efifb.c
@@ -17,7 +17,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include  /* For drm_get_panel_orientation_quirk */
@@ -258,9 +257,6 @@ static void efifb_destroy(struct fb_info *info)
 {
struct efifb_par *par = info->par;
 
-   if (efifb_pci_dev)
-   pm_runtime_put(_pci_dev->dev);
-
if (info->screen_base) {
if (mem_flags & (EFI_MEMORY_UC | EFI_MEMORY_WC))
iounmap(info->screen_base);
@@ -598,26 +594,20 @@ static int efifb_probe(struct platform_device *dev)
goto err_groups;
}
 
-   if (efifb_pci_dev)
-   WARN_ON(pm_runtime_get_sync(_pci_dev->dev) < 0);
-
err = devm_aperture_acquire_for_platform_device(dev, par->base, 
par->size);
if (err) {
pr_err("efifb: cannot acquire aperture\n");
-   goto err_put_rpm_ref;
+   goto err_fb_dealloc_cmap;
}
err = register_framebuffer(info);
if (err < 0) {
pr_err("efifb: cannot register framebuffer\n");
-   goto err_put_rpm_ref;
+   goto err_fb_dealloc_cmap;
}
fb_info(info, "%s frame buffer device\n", info->fix.id);
return 0;
 
-err_put_rpm_ref:
-   if (efifb_pci_dev)
-   pm_runtime_put(_pci_dev->dev);
-
+err_fb_dealloc_cmap:
fb_dealloc_cmap(>cmap);
 err_groups:
sysfs_remove_groups(>dev.kobj, efifb_groups);
-- 
2.43.0



[PATCH v3 1/8] video: Add helpers for decoding screen_info

2024-02-07 Thread Thomas Zimmermann
The plain values as stored in struct screen_info need to be decoded
before being used. Add helpers that decode the type of video output
and the framebuffer I/O aperture.

Old or non-x86 systems may not set the type of video directly, but
only indicate the presence by storing 0x01 in orig_video_isVGA. The
decoding logic in screen_info_video_type() takes this into account.
It then follows similar code in vgacon's vgacon_startup() to detect
the video type from the given values.

A call to screen_info_resources() returns all known resources of the
given screen_info. The resources' values have been taken from existing
code in vgacon and vga16fb. These drivers can later be converted to
use the new interfaces.

v2:
* return ssize_t from screen_info_resources()
* don't call __screen_info_has_lfb() unnecessarily

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Javier Martinez Canillas 
---
 drivers/firmware/Kconfig|   1 +
 drivers/video/Kconfig   |   4 +
 drivers/video/Makefile  |   3 +
 drivers/video/screen_info_generic.c | 146 
 include/linux/screen_info.h | 100 +++
 5 files changed, 254 insertions(+)
 create mode 100644 drivers/video/screen_info_generic.c

diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index afd38539b92e5..71d8b26c4103b 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -182,6 +182,7 @@ config MTK_ADSP_IPC
 config SYSFB
bool
select BOOT_VESA_SUPPORT
+   select SCREEN_INFO
 
 config SYSFB_SIMPLEFB
bool "Mark VGA/VBE/EFI FB as generic system framebuffer"
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 130ebccb83380..44c9ef1435a2d 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -11,6 +11,10 @@ config APERTURE_HELPERS
  Support tracking and hand-over of aperture ownership. Required
  by graphics drivers for firmware-provided framebuffers.
 
+config SCREEN_INFO
+   bool
+   default n
+
 config STI_CORE
bool
depends on PARISC
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 9eb5557911de5..117cbdbb58c2c 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -1,11 +1,14 @@
 # SPDX-License-Identifier: GPL-2.0
 
 obj-$(CONFIG_APERTURE_HELPERS)+= aperture.o
+obj-$(CONFIG_SCREEN_INFO) += screen_info.o
 obj-$(CONFIG_STI_CORE)+= sticore.o
 obj-$(CONFIG_VGASTATE)+= vgastate.o
 obj-$(CONFIG_VIDEO)   += cmdline.o nomodeset.o
 obj-$(CONFIG_HDMI)+= hdmi.o
 
+screen_info-y:= screen_info_generic.o
+
 obj-$(CONFIG_VT) += console/
 obj-$(CONFIG_FB_STI) += console/
 obj-$(CONFIG_LOGO)   += logo/
diff --git a/drivers/video/screen_info_generic.c 
b/drivers/video/screen_info_generic.c
new file mode 100644
index 0..64117c6367abb
--- /dev/null
+++ b/drivers/video/screen_info_generic.c
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include 
+#include 
+#include 
+#include 
+
+static void resource_init_named(struct resource *r,
+   resource_size_t start, resource_size_t size,
+   const char *name, unsigned int flags)
+{
+   memset(r, 0, sizeof(*r));
+
+   r->start = start;
+   r->end = start + size - 1;
+   r->name = name;
+   r->flags = flags;
+}
+
+static void resource_init_io_named(struct resource *r,
+  resource_size_t start, resource_size_t size,
+  const char *name)
+{
+   resource_init_named(r, start, size, name, IORESOURCE_IO);
+}
+
+static void resource_init_mem_named(struct resource *r,
+  resource_size_t start, resource_size_t size,
+  const char *name)
+{
+   resource_init_named(r, start, size, name, IORESOURCE_MEM);
+}
+
+static inline bool __screen_info_has_ega_gfx(unsigned int mode)
+{
+   switch (mode) {
+   case 0x0d:  /* 320x200-4 */
+   case 0x0e:  /* 640x200-4 */
+   case 0x0f:  /* 640x350-1 */
+   case 0x10:  /* 640x350-4 */
+   return true;
+   default:
+   return false;
+   }
+}
+
+static inline bool __screen_info_has_vga_gfx(unsigned int mode)
+{
+   switch (mode) {
+   case 0x10:  /* 640x480-1 */
+   case 0x12:  /* 640x480-4 */
+   case 0x13:  /* 320-200-8 */
+   case 0x6a:  /* 800x600-4 (VESA) */
+   return true;
+   default:
+   return __screen_info_has_ega_gfx(mode);
+   }
+}
+
+/**
+ * screen_info_resources() - Get resources from screen_info structure
+ * @si: the screen_info
+ * @r: pointer to an array of resource structures
+ * @num: number of elements in @r:
+ *
+ * Returns:
+ * The number of resources stored in @r on success, or a 

Re: [PATCH v3 0/5] Fixing live video input in ZynqMP DPSUB

2024-02-07 Thread Tomi Valkeinen

On 24/01/2024 04:53, Anatoliy Klymenko wrote:

Add few missing pieces to support ZynqMP DPSUB live video in mode.

ZynqMP DPSUB supports 2 modes of operations in regard to video data
input.
 
In the first mode, DPSUB uses DMA engine to pull video data from memory

buffers. To support this the driver implements CRTC and DRM bridge
representing DP encoder.
 
In the second mode, DPSUB acquires video data pushed from FPGA and

passes it downstream to DP output. This mode of operation is modeled in
the driver as a DRM bridge that should be attached to some external
CRTC.

Patches 1/5,2/5,3/5,4/5 are minor fixes.

DPSUB requires input live video format to be configured.
Patch 5/5: The DP Subsystem requires the input live video format to be
configured. In this patch, we are assuming that the CRTC's bus format is
fixed (typical for FPGA CRTC) and comes from the device tree. This is a
proposed solution, as there is no API to query CRTC output bus format
or negotiate it in any other way.

Changes in v2:
- Address reviewers' comments:
   - More elaborate and consistent comments / commit messages
   - Fix includes' order
   - Replace of_property_read_u32_index() with of_property_read_u32()

Changes in v3:
- Split patch #3 into 3) moving status register clear immediately after
   read; 4) masking status against interrupts' mask

Link to v1: 
https://lore.kernel.org/all/20240112234222.913138-1-anatoliy.klyme...@amd.com/
Link to v2: 
https://lore.kernel.org/all/20240119055437.2549149-1-anatoliy.klyme...@amd.com/

Anatoliy Klymenko (5):
   drm: xlnx: zynqmp_dpsub: Make drm bridge discoverable
   drm: xlnx: zynqmp_dpsub: Fix timing for live mode
   drm: xlnx: zynqmp_dpsub: Clear status register ASAP
   drm: xlnx: zynqmp_dpsub: Filter interrupts against mask
   drm: xlnx: zynqmp_dpsub: Set live video in format

  drivers/gpu/drm/xlnx/zynqmp_disp.c  | 111 +---
  drivers/gpu/drm/xlnx/zynqmp_disp.h  |   3 +-
  drivers/gpu/drm/xlnx/zynqmp_disp_regs.h |   8 +-
  drivers/gpu/drm/xlnx/zynqmp_dp.c|  16 +++-
  drivers/gpu/drm/xlnx/zynqmp_kms.c   |   2 +-
  5 files changed, 119 insertions(+), 21 deletions(-)



Thanks! I have pushed patches 1 to 4 to drm-misc-next. As Laurent said, 
the fifth one needs some more work.


 Tomi



Re: [PATCH 2/4] media: i2c: replace of_graph_get_next_endpoint()

2024-02-07 Thread Krzysztof Hałasa
Laurent,

Laurent Pinchart  writes:

>> +++ b/drivers/media/i2c/adv7604.c
>> @@ -3205,7 +3205,7 @@ static int adv76xx_parse_dt(struct adv76xx_state 
>> *state)
>>   np = state->i2c_clients[ADV76XX_PAGE_IO]->dev.of_node;
>>
>>   /* Parse the endpoint. */
>> - endpoint = of_graph_get_next_endpoint(np, NULL);
>> + endpoint = of_graph_get_endpoint_by_regs(np, 0, -1);
>
> I think this should be port 1 for the adv7611 and port2 for the adv7612.
> The adv7610 may need to use port 1 too, but the bindings likely need to
> be updated.

To be honest I have no idea about ADV7611 and 7612.
The 7610 I have on Tinyrex "mobo" seems to be single port.

ADV7611 seems to be mostly a 7610 in a different package (LQFP 64
instead of some BGA 76). The driver simply treats ADV7610 as a 7611.

ADV7612 is apparently dual port (only one port can be used at a time)
though:

[ADV7612] = {
.type = ADV7612,
.has_afe = false,
.max_port = ADV76XX_PAD_HDMI_PORT_A,/* B not supported */
.num_dv_ports = 1,  /* normally 2 */


All related in-tree DTS entries (as of v6.8.0-rc1) seem to be ADV7612.

To me it seems all known devices use the first port only.
-- 
Krzysztof "Chris" Hałasa

Sieć Badawcza Łukasiewicz
Przemysłowy Instytut Automatyki i Pomiarów PIAP
Al. Jerozolimskie 202, 02-486 Warszawa


Re: [PATCH 2/4] media: i2c: replace of_graph_get_next_endpoint()

2024-02-07 Thread Krzysztof Hałasa
Hans,

Hans Verkuil  writes:

> Ideally someone would have to actually test this, perhaps with one of those
> Renesas boards. While I do have one, it got bricked after I attempted a
> u-boot update :-(

May be reversible, though.
-- 
Krzysztof "Chris" Hałasa

Sieć Badawcza Łukasiewicz
Przemysłowy Instytut Automatyki i Pomiarów PIAP
Al. Jerozolimskie 202, 02-486 Warszawa


Re: [PATCH] drm/tegra: Remove of_dma_configure() from host1x_device_add()

2024-02-07 Thread Jason Gunthorpe
On Fri, Feb 02, 2024 at 12:15:40PM -0400, Jason Gunthorpe wrote:

> > Yes looks like a race of some sort. Adding a bit of debug also makes the
> > issue go away so difficult to see what is happening.
> 
> I'm wondering if it is racing with iommu driver probing? I looked but
> didn't notice anything obviously wrong there that would cause this
> though.

Oh there is at least one racy thing here..

The of_xlate hackjob is out of order and is racy if you have multiple instances:

struct tegra_smmu *tegra_smmu_probe(struct device *dev,
const struct tegra_smmu_soc *soc,
struct tegra_mc *mc)
{
/*
 * This is a bit of a hack. Ideally we'd want to simply return this
 * value. However iommu_device_register() will attempt to add
 * all devices to the IOMMU before we get that far. In order
 * not to rely on global variables to track the IOMMU instance, we
 * set it here so that it can be looked up from the .probe_device()
 * callback via the IOMMU device's .drvdata field.
 */
mc->smmu = smmu;
 ^
   After this of_xlate and probe_device will succeed

[...]
err = iommu_device_sysfs_add(>iommu, dev, NULL, dev_name(dev));   

err = iommu_device_register(>iommu, _smmu_ops, dev);
^
But the iommu instance is not fully initialized yet.

So:

static int tegra_smmu_of_xlate(struct device *dev,
   struct of_phandle_args *args)
{
struct platform_device *iommu_pdev = of_find_device_by_node(args->np);
struct tegra_mc *mc = platform_get_drvdata(iommu_pdev);

dev_iommu_priv_set(dev, mc->smmu);

 Gets the partially initialized iommu
 instance


static struct iommu_device *tegra_smmu_probe_device(struct device *dev)
{
smmu = dev_iommu_priv_get(dev);
if (!smmu)
return ERR_PTR(-ENODEV);
   ^
  Allows the driver to bind to a partially setup instance

ie if you have multiple instances of tegra-smmu and you manage to do
concurrent probe where the iommu instance is probing concurrently with
the failing device_add flow then you can a situation like you have
described where the sysfs is not fully setup.

Is this making sense to you? Add a sleep after the mc->smmu store and
confirm with printing?

I think this is all an insane design. I fixed this race and removed
all this hackery in my fwspec removal series. There the iommu instance
only ever comes out of the locked list that iommu_device_register()
populates and drivers have a safe and simple flow.

Maybe just moving the store to mc->smmu later would improve it? I
didn't look closely..

Jason


Re: [PATCH 11/19] drm/i915/dp: Add support for DP tunnel BW allocation

2024-02-07 Thread Imre Deak
On Wed, Feb 07, 2024 at 01:08:43AM +0200, Ville Syrjälä wrote:
> On Tue, Jan 23, 2024 at 12:28:42PM +0200, Imre Deak wrote:
> > Add support to enable the DP tunnel BW allocation mode. Follow-up
> > patches will call the required helpers added here to prepare for a
> > modeset on a link with DP tunnels, the last change in the patchset
> > actually enabling BWA.
> > 
> > With BWA enabled, the driver will expose the full mode list a display
> > supports, regardless of any BW limitation on a shared (Thunderbolt)
> > link. Such BW limits will be checked against only during a modeset, when
> > the driver has the full knowledge of each display's BW requirement.
> > 
> > If the link BW changes in a way that a connector's modelist may also
> > change, userspace will get a hotplug notification for all the connectors
> > sharing the same link (so it can adjust the mode used for a display).
> > 
> > The BW limitation can change at any point, asynchronously to modesets
> > on a given connector, so a modeset can fail even though the atomic check
> > for it passed. In such scenarios userspace will get a bad link
> > notification and in response is supposed to retry the modeset.
> > 
> > Signed-off-by: Imre Deak 
> > ---
> >  drivers/gpu/drm/i915/Kconfig  |  13 +
> >  drivers/gpu/drm/i915/Kconfig.debug|   1 +
> >  drivers/gpu/drm/i915/Makefile |   3 +
> >  drivers/gpu/drm/i915/display/intel_atomic.c   |   2 +
> >  .../gpu/drm/i915/display/intel_display_core.h |   1 +
> >  .../drm/i915/display/intel_display_types.h|   9 +
> >  .../gpu/drm/i915/display/intel_dp_tunnel.c| 642 ++
> >  .../gpu/drm/i915/display/intel_dp_tunnel.h| 131 
> >  8 files changed, 802 insertions(+)
> >  create mode 100644 drivers/gpu/drm/i915/display/intel_dp_tunnel.c
> >  create mode 100644 drivers/gpu/drm/i915/display/intel_dp_tunnel.h
> > 
> > diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
> > index b5d6e3352071f..4636913c17868 100644
> > --- a/drivers/gpu/drm/i915/Kconfig
> > +++ b/drivers/gpu/drm/i915/Kconfig
> > @@ -155,6 +155,19 @@ config DRM_I915_PXP
> >   protected session and manage the status of the alive software session,
> >   as well as its life cycle.
> >  
> > +config DRM_I915_DP_TUNNEL
> > +   bool "Enable DP tunnel support"
> > +   depends on DRM_I915
> > +   select DRM_DISPLAY_DP_TUNNEL
> > +   default y
> > +   help
> > + Choose this option to detect DP tunnels and enable the Bandwidth
> > + Allocation mode for such tunnels. This allows using the maximum
> > + resolution allowed by the link BW on all displays sharing the
> > + link BW, for instance on a Thunderbolt link.
> > +
> > + If in doubt, say "Y".
> > +
> >  menu "drm/i915 Debugging"
> >  depends on DRM_I915
> >  depends on EXPERT
> > diff --git a/drivers/gpu/drm/i915/Kconfig.debug 
> > b/drivers/gpu/drm/i915/Kconfig.debug
> > index 5b7162076850c..bc18e2d9ea05d 100644
> > --- a/drivers/gpu/drm/i915/Kconfig.debug
> > +++ b/drivers/gpu/drm/i915/Kconfig.debug
> > @@ -28,6 +28,7 @@ config DRM_I915_DEBUG
> > select STACKDEPOT
> > select STACKTRACE
> > select DRM_DP_AUX_CHARDEV
> > +   select DRM_DISPLAY_DEBUG_DP_TUNNEL_STATE if DRM_I915_DP_TUNNEL
> > select X86_MSR # used by igt/pm_rpm
> > select DRM_VGEM # used by igt/prime_vgem (dmabuf interop checks)
> > select DRM_DEBUG_MM if DRM=y
> > diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> > index c13f14edb5088..3ef6ed41e62b4 100644
> > --- a/drivers/gpu/drm/i915/Makefile
> > +++ b/drivers/gpu/drm/i915/Makefile
> > @@ -369,6 +369,9 @@ i915-y += \
> > display/vlv_dsi.o \
> > display/vlv_dsi_pll.o
> >  
> > +i915-$(CONFIG_DRM_I915_DP_TUNNEL) += \
> > +   display/intel_dp_tunnel.o
> > +
> >  i915-y += \
> > i915_perf.o
> >  
> > diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c 
> > b/drivers/gpu/drm/i915/display/intel_atomic.c
> > index ec0d5168b5035..96ab37e158995 100644
> > --- a/drivers/gpu/drm/i915/display/intel_atomic.c
> > +++ b/drivers/gpu/drm/i915/display/intel_atomic.c
> > @@ -29,6 +29,7 @@
> >   * See intel_atomic_plane.c for the plane-specific atomic functionality.
> >   */
> >  
> > +#include 
> >  #include 
> >  #include 
> >  #include 
> > @@ -38,6 +39,7 @@
> >  #include "intel_atomic.h"
> >  #include "intel_cdclk.h"
> >  #include "intel_display_types.h"
> > +#include "intel_dp_tunnel.h"
> >  #include "intel_global_state.h"
> >  #include "intel_hdcp.h"
> >  #include "intel_psr.h"
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h 
> > b/drivers/gpu/drm/i915/display/intel_display_core.h
> > index a90f1aa201be8..0993d25a0a686 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_core.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display_core.h
> > @@ -522,6 +522,7 @@ struct intel_display {
> > } wq;
> >  
> > /* Grouping using named structs. Keep sorted. */
> > +   struct drm_dp_tunnel_mgr 

Re: [PATCH] drm/bridge: imx8mp-hdmi-pvi: Fix build warnings

2024-02-07 Thread Adam Ford
On Wed, Feb 7, 2024 at 3:24 AM Neil Armstrong  wrote:
>
> On 07/02/2024 10:22, Fabio Estevam wrote:
> > Hi Adam,
> >
> > On Tue, Feb 6, 2024 at 9:23 PM Adam Ford  wrote:
> >>
> >> Two separate build warnings were reported.  One from an
> >> uninitialized variable, and the other from returning 0
> >> instead of NULL from a pointer.
> >>
> >> Fixes: 059c53e877ca ("drm/bridge: imx: add driver for HDMI TX Parallel 
> >> Video Interface")
> >> Reported-by: nat...@kernel.org
> >
> > The Reported-by line format can be improved:
> >
Sorry about .that

> > Reported-by: Nathan Chancellor 
> >
> > Thanks
>
> Fixed while applying,

Thank you!

adam
>
> Thanks,
> Neil


  1   2   >