Re: [PATCH] drm/lima: Mark simple_ondemand governor as softdep

2024-06-25 Thread Dragan Simic

Hello Qiang,

On 2024-06-26 03:11, Qiang Yu wrote:
On Wed, Jun 26, 2024 at 2:15 AM Dragan Simic  
wrote:


Hello everyone,

Just checking, any further thoughts about this patch?

I'm OK with this as a temp workaround because it's simple and do no 
harm
even it's not perfect. If no other better suggestion for short term, 
I'll submit

this at weekend.


Thanks.  Just as you described it, it's far from perfect, but it's still
fine until there's a better solution, such as harddeps.  I'll continue 
my
research about the possibility for adding harddeps, which would 
hopefully

replace quite a few instances of the softdep (ab)use.


On 2024-06-18 21:22, Dragan Simic wrote:
> On 2024-06-18 12:33, Dragan Simic wrote:
>> On 2024-06-18 10:13, Maxime Ripard wrote:
>>> On Tue, Jun 18, 2024 at 04:01:26PM GMT, Qiang Yu wrote:
 On Tue, Jun 18, 2024 at 12:33 PM Qiang Yu  wrote:
 >
 > I see the problem that initramfs need to build a module dependency chain,
 > but lima does not call any symbol from simpleondemand governor module.
 > softdep module seems to be optional while our dependency is hard one,
 > can we just add MODULE_INFO(depends, _depends), or create a new
 > macro called MODULE_DEPENDS()?
>>
>> I had the same thoughts, because softdeps are for optional module
>> dependencies, while in this case it's a hard dependency.  Though,
>> I went with adding a softdep, simply because I saw no better option
>> available.
>>
 This doesn't work on my side because depmod generates modules.dep
 by symbol lookup instead of modinfo section. So softdep may be our
 only
 choice to add module dependency manually. I can accept the softdep
 first, then make PM optional later.
>>
>> I also thought about making devfreq optional in the Lima driver,
>> which would make this additional softdep much more appropriate.
>> Though, I'm not really sure that's a good approach, because not
>> having working devfreq for Lima might actually cause issues on
>> some devices, such as increased power consumption.
>>
>> In other words, it might be better to have Lima probing fail if
>> devfreq can't be initialized, rather than having probing succeed
>> with no working devfreq.  Basically, failed probing is obvious,
>> while a warning in the kernel log about no devfreq might easily
>> be overlooked, causing regressions on some devices.
>>
>>> It's still super fragile, and depends on the user not changing the
>>> policy. It should be solved in some other, more robust way.
>>
>> I see, but I'm not really sure how to make it more robust?  In
>> the end, some user can blacklist the simple_ondemand governor
>> module, and we can't do much about it.
>>
>> Introducing harddeps alongside softdeps would make sense from
>> the design standpoint, but the amount of required changes wouldn't
>> be trivial at all, on various levels.
>
> After further investigation, it seems that the softdeps have
> already seen a fair amount of abuse for what they actually aren't
> intended, i.e. resolving hard dependencies.  For example, have
> a look at the commit d5178578bcd4 (btrfs: directly call into
> crypto framework for checksumming) [1] and the lines containing
> MODULE_SOFTDEP() at the very end of fs/btrfs/super.c. [2]
>
> If a filesystem driver can rely on the abuse of softdeps, which
> admittedly are a bit fragile, I think we can follow the same
> approach, at least for now.
>
> With all that in mind, I think that accepting this patch, as well
> as the related Panfrost patch, [3] should be warranted.  I'd keep
> investigating the possibility of introducing harddeps in form
> of MODULE_HARDDEP() and the related support in kmod project,
> similar to the already existing softdep support, [4] but that
> will inevitably take a lot of time, both for implementing it
> and for reaching various Linux distributions, which is another
> reason why accepting these patches seems reasonable.
>
> [1]
> 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d5178578bcd4
> [2]
> 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/btrfs/super.c#n2593
> [3]
> 
https://lore.kernel.org/dri-devel/4e1e00422a14db4e2a80870afb704405da16fd1b.1718655077.git.dsi...@manjaro.org/
> [4]
> 
https://git.kernel.org/pub/scm/utils/kernel/kmod/kmod.git/commit/?id=49d8e0b59052999de577ab732b719cfbeb89504d


RE: [PATCH] drm: renesas: Move RZ/G2L MIPI DSI driver to rz-du

2024-06-25 Thread Biju Das
Hi Laurent Pinchart,

> -Original Message-
> From: Laurent Pinchart 
> Sent: Wednesday, June 26, 2024 6:51 AM
> Subject: Re: [PATCH] drm: renesas: Move RZ/G2L MIPI DSI driver to rz-du
> 
> Hi Prabhakar,
> 
> Thank you for the patch.
> 
> On Tue, Jun 25, 2024 at 01:32:44PM +0100, Prabhakar wrote:
> > From: Lad Prabhakar 
> >
> > All the RZ/G2L DU specific components are located under the rz-du
> > folder, so it makes sense to move the RZ/G2L MIPI DSI driver there
> > instead of keeping it in the rcar-du folder. This change improves the
> > organization and modularity of the driver configuration by grouping related 
> > settings together.
> 
> I was thinking the same the other day. Thanks for beating me at sending a 
> patch :-)
> 
> Reviewed-by: Laurent Pinchart 
> 
> Do you or Biju has committer rights to drm-misc to push this patch ?

I guess, it will be taken by drm-misc folks like du driver, as this is now part 
of
rz-du folder which is part of the list [1] ??

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/MAINTAINERS?h=next-20240625#n7345

Cheers,
Biju

> 
> > Signed-off-by: Lad Prabhakar 
> > ---
> >  drivers/gpu/drm/renesas/rcar-du/Kconfig   | 8 
> >  drivers/gpu/drm/renesas/rcar-du/Makefile  | 2 --
> >  drivers/gpu/drm/renesas/rz-du/Kconfig | 8 
> >  drivers/gpu/drm/renesas/rz-du/Makefile| 2 ++
> >  .../gpu/drm/renesas/{rcar-du => rz-du}/rzg2l_mipi_dsi.c   | 0
> >  .../drm/renesas/{rcar-du => rz-du}/rzg2l_mipi_dsi_regs.h  | 0
> >  6 files changed, 10 insertions(+), 10 deletions(-)  rename
> > drivers/gpu/drm/renesas/{rcar-du => rz-du}/rzg2l_mipi_dsi.c (100%)
> > rename drivers/gpu/drm/renesas/{rcar-du =>
> > rz-du}/rzg2l_mipi_dsi_regs.h (100%)
> >
> > diff --git a/drivers/gpu/drm/renesas/rcar-du/Kconfig
> > b/drivers/gpu/drm/renesas/rcar-du/Kconfig
> > index 53c356aed5d5..39af73cf2092 100644
> > --- a/drivers/gpu/drm/renesas/rcar-du/Kconfig
> > +++ b/drivers/gpu/drm/renesas/rcar-du/Kconfig
> > @@ -60,14 +60,6 @@ config DRM_RCAR_MIPI_DSI
> > select DRM_MIPI_DSI
> > select RESET_CONTROLLER
> >
> > -config DRM_RZG2L_MIPI_DSI
> > -   tristate "RZ/G2L MIPI DSI Encoder Support"
> > -   depends on DRM && DRM_BRIDGE && OF
> > -   depends on ARCH_RENESAS || COMPILE_TEST
> > -   select DRM_MIPI_DSI
> > -   help
> > - Enable support for the RZ/G2L Display Unit embedded MIPI DSI encoders.
> > -
> >  config DRM_RCAR_VSP
> > bool "R-Car DU VSP Compositor Support" if ARM
> > default y if ARM64
> > diff --git a/drivers/gpu/drm/renesas/rcar-du/Makefile
> > b/drivers/gpu/drm/renesas/rcar-du/Makefile
> > index b8f2c82651d9..6f132325c8b7 100644
> > --- a/drivers/gpu/drm/renesas/rcar-du/Makefile
> > +++ b/drivers/gpu/drm/renesas/rcar-du/Makefile
> > @@ -14,5 +14,3 @@ obj-$(CONFIG_DRM_RCAR_DU) += rcar-du-drm.o
> >  obj-$(CONFIG_DRM_RCAR_DW_HDMI) += rcar_dw_hdmi.o
> >  obj-$(CONFIG_DRM_RCAR_LVDS)+= rcar_lvds.o
> >  obj-$(CONFIG_DRM_RCAR_MIPI_DSI)+= rcar_mipi_dsi.o
> > -
> > -obj-$(CONFIG_DRM_RZG2L_MIPI_DSI)   += rzg2l_mipi_dsi.o
> > diff --git a/drivers/gpu/drm/renesas/rz-du/Kconfig
> > b/drivers/gpu/drm/renesas/rz-du/Kconfig
> > index 5f0db2c5fee6..8ec14271ebba 100644
> > --- a/drivers/gpu/drm/renesas/rz-du/Kconfig
> > +++ b/drivers/gpu/drm/renesas/rz-du/Kconfig
> > @@ -10,3 +10,11 @@ config DRM_RZG2L_DU
> > help
> >   Choose this option if you have an RZ/G2L alike chipset.
> >   If M is selected the module will be called rzg2l-du-drm.
> > +
> > +config DRM_RZG2L_MIPI_DSI
> > +   tristate "RZ/G2L MIPI DSI Encoder Support"
> > +   depends on DRM && DRM_BRIDGE && OF
> > +   depends on ARCH_RENESAS || COMPILE_TEST
> > +   select DRM_MIPI_DSI
> > +   help
> > + Enable support for the RZ/G2L Display Unit embedded MIPI DSI encoders.
> > diff --git a/drivers/gpu/drm/renesas/rz-du/Makefile
> > b/drivers/gpu/drm/renesas/rz-du/Makefile
> > index 663b82a2577f..2987900ea6b6 100644
> > --- a/drivers/gpu/drm/renesas/rz-du/Makefile
> > +++ b/drivers/gpu/drm/renesas/rz-du/Makefile
> > @@ -6,3 +6,5 @@ rzg2l-du-drm-y := rzg2l_du_crtc.o \
> >
> >  rzg2l-du-drm-$(CONFIG_VIDEO_RENESAS_VSP1)  += rzg2l_du_vsp.o
> >  obj-$(CONFIG_DRM_RZG2L_DU) += rzg2l-du-drm.o
> > +
> > +obj-$(CONFIG_DRM_RZG2L_MIPI_DSI)   += rzg2l_mipi_dsi.o
> > diff --git a/drivers/gpu/drm/renesas/rcar-du/rzg2l_mipi_dsi.c
> > b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c
> > similarity index 100%
> > rename from drivers/gpu/drm/renesas/rcar-du/rzg2l_mipi_dsi.c
> > rename to drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c
> > diff --git a/drivers/gpu/drm/renesas/rcar-du/rzg2l_mipi_dsi_regs.h
> > b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h
> > similarity index 100%
> > rename from drivers/gpu/drm/renesas/rcar-du/rzg2l_mipi_dsi_regs.h
> > rename to drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h
> 
> --
> Regards,
> 
> Laurent Pinchart


[PATCH] drm/qxl: fix null pointer dereference in qxl_add_mode

2024-06-25 Thread Ma Ke
In qxl_add_mode(), the return value of drm_cvt_mode() is assigned to mode,
which will lead to a possible NULL pointer dereference on failure of
drm_cvt_mode(). Add a check to avoid npd.

Signed-off-by: Ma Ke 
---
 drivers/gpu/drm/qxl/qxl_display.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/qxl/qxl_display.c 
b/drivers/gpu/drm/qxl/qxl_display.c
index c6d35c33d5d6..7c11383cd3c4 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -236,6 +236,8 @@ static int qxl_add_mode(struct drm_connector *connector,
return 0;
 
mode = drm_cvt_mode(dev, width, height, 60, false, false, false);
+   if (!mode)
+   return -ENOMEM;
if (preferred)
mode->type |= DRM_MODE_TYPE_PREFERRED;
mode->hdisplay = width;
-- 
2.25.1




Re: [PATCH] drm/mediatek: select DRM_GEM_DMA_HELPER if DRM_FBDEV_EMULATION=y

2024-06-25 Thread Chen-Yu Tsai
Hi Thomas,

On Thu, Jun 20, 2024 at 10:20 PM Chun-Kuang Hu  wrote:
>
> Hi, Chen-Yu:
>
> Chen-Yu Tsai  於 2024年6月20日 週四 下午1:47寫道:
> >
> > With the recent switch from fbdev-generic to fbdev-dma, the driver now
> > requires the DRM GEM DMA helpers. This dependency is missing, and will
> > cause a link failure if fbdev emulation is enabled.
> >
> > Add the missing dependency.
>
> Acked-by: Chun-Kuang Hu 

Could you help merge this?

Thanks
ChenYu

> >
> > Fixes: 0992284b4fe4 ("drm/mediatek: Use fbdev-dma")
> > Signed-off-by: Chen-Yu Tsai 
> > ---
> > The commit this patch fixes is in drm-misc-next. Ideally this patch
> > should be applied on top of it directly.
> >
> > CK, could you give your ack for it?
> >
> >  drivers/gpu/drm/mediatek/Kconfig | 1 +
> >  1 file changed, 1 insertion(+)
> >
> > diff --git a/drivers/gpu/drm/mediatek/Kconfig 
> > b/drivers/gpu/drm/mediatek/Kconfig
> > index 96cbe020f493..d6449ebae838 100644
> > --- a/drivers/gpu/drm/mediatek/Kconfig
> > +++ b/drivers/gpu/drm/mediatek/Kconfig
> > @@ -7,6 +7,7 @@ config DRM_MEDIATEK
> > depends on HAVE_ARM_SMCCC
> > depends on OF
> > depends on MTK_MMSYS
> > +   select DRM_GEM_DMA_HELPER if DRM_FBDEV_EMULATION
> > select DRM_KMS_HELPER
> > select DRM_MIPI_DSI
> > select DRM_PANEL
> > --
> > 2.45.2.741.gdbec12cfda-goog
> >


Re: [PATCH] dt-bindings: display/msm/gmu: fix the schema being not applied

2024-06-25 Thread Krzysztof Kozlowski
On 26/06/2024 06:31, Dmitry Baryshkov wrote:
> On Tue, Jun 25, 2024 at 04:51:27PM GMT, Rob Herring wrote:
>> On Sun, Jun 23, 2024 at 02:59:30PM +0200, Krzysztof Kozlowski wrote:
>>> dtschema v2024.4, v2024.5 and maybe earlier do not select device nodes for
>>
>> That should be just since db9c05a08709 ("validator: Rework selecting 
>> schemas for validation") AKA the 6x speed up in v2024.04.
>>
>>> given binding validation if the schema contains compatible list with
>>> pattern and a const fallback.  This leads to binding being a no-op - not
>>> being applied at all.  Issue should be fixed in the dtschema but for now
>>> add a work-around do the binding can be used against DTS validation.
>>
>> The issue is we only look at the first compatible. I'm testing out a fix 
>> and will apply it tomorrow assuming no issues. With that, I don't think 
>> we should apply this patch.
> 
> I think we ended up picking up the next iteration of the patch, but we
> can probably land a revert later.

gpu patch was applied. This is gmu, so can be just ignored/skipped.
Anyway the code here should not have negative effect, so we can revert
it anytime later, e.g. when users upgrade to fixed dtschema.

Best regards,
Krzysztof



Re: [PATCH] drm: renesas: Move RZ/G2L MIPI DSI driver to rz-du

2024-06-25 Thread Laurent Pinchart
Hi Prabhakar,

Thank you for the patch.

On Tue, Jun 25, 2024 at 01:32:44PM +0100, Prabhakar wrote:
> From: Lad Prabhakar 
> 
> All the RZ/G2L DU specific components are located under the rz-du folder,
> so it makes sense to move the RZ/G2L MIPI DSI driver there instead of
> keeping it in the rcar-du folder. This change improves the organization
> and modularity of the driver configuration by grouping related settings 
> together.

I was thinking the same the other day. Thanks for beating me at sending
a patch :-)

Reviewed-by: Laurent Pinchart 

Do you or Biju has committer rights to drm-misc to push this patch ?

> Signed-off-by: Lad Prabhakar 
> ---
>  drivers/gpu/drm/renesas/rcar-du/Kconfig   | 8 
>  drivers/gpu/drm/renesas/rcar-du/Makefile  | 2 --
>  drivers/gpu/drm/renesas/rz-du/Kconfig | 8 
>  drivers/gpu/drm/renesas/rz-du/Makefile| 2 ++
>  .../gpu/drm/renesas/{rcar-du => rz-du}/rzg2l_mipi_dsi.c   | 0
>  .../drm/renesas/{rcar-du => rz-du}/rzg2l_mipi_dsi_regs.h  | 0
>  6 files changed, 10 insertions(+), 10 deletions(-)
>  rename drivers/gpu/drm/renesas/{rcar-du => rz-du}/rzg2l_mipi_dsi.c (100%)
>  rename drivers/gpu/drm/renesas/{rcar-du => rz-du}/rzg2l_mipi_dsi_regs.h 
> (100%)
> 
> diff --git a/drivers/gpu/drm/renesas/rcar-du/Kconfig 
> b/drivers/gpu/drm/renesas/rcar-du/Kconfig
> index 53c356aed5d5..39af73cf2092 100644
> --- a/drivers/gpu/drm/renesas/rcar-du/Kconfig
> +++ b/drivers/gpu/drm/renesas/rcar-du/Kconfig
> @@ -60,14 +60,6 @@ config DRM_RCAR_MIPI_DSI
>   select DRM_MIPI_DSI
>   select RESET_CONTROLLER
>  
> -config DRM_RZG2L_MIPI_DSI
> - tristate "RZ/G2L MIPI DSI Encoder Support"
> - depends on DRM && DRM_BRIDGE && OF
> - depends on ARCH_RENESAS || COMPILE_TEST
> - select DRM_MIPI_DSI
> - help
> -   Enable support for the RZ/G2L Display Unit embedded MIPI DSI encoders.
> -
>  config DRM_RCAR_VSP
>   bool "R-Car DU VSP Compositor Support" if ARM
>   default y if ARM64
> diff --git a/drivers/gpu/drm/renesas/rcar-du/Makefile 
> b/drivers/gpu/drm/renesas/rcar-du/Makefile
> index b8f2c82651d9..6f132325c8b7 100644
> --- a/drivers/gpu/drm/renesas/rcar-du/Makefile
> +++ b/drivers/gpu/drm/renesas/rcar-du/Makefile
> @@ -14,5 +14,3 @@ obj-$(CONFIG_DRM_RCAR_DU)   += rcar-du-drm.o
>  obj-$(CONFIG_DRM_RCAR_DW_HDMI)   += rcar_dw_hdmi.o
>  obj-$(CONFIG_DRM_RCAR_LVDS)  += rcar_lvds.o
>  obj-$(CONFIG_DRM_RCAR_MIPI_DSI)  += rcar_mipi_dsi.o
> -
> -obj-$(CONFIG_DRM_RZG2L_MIPI_DSI) += rzg2l_mipi_dsi.o
> diff --git a/drivers/gpu/drm/renesas/rz-du/Kconfig 
> b/drivers/gpu/drm/renesas/rz-du/Kconfig
> index 5f0db2c5fee6..8ec14271ebba 100644
> --- a/drivers/gpu/drm/renesas/rz-du/Kconfig
> +++ b/drivers/gpu/drm/renesas/rz-du/Kconfig
> @@ -10,3 +10,11 @@ config DRM_RZG2L_DU
>   help
> Choose this option if you have an RZ/G2L alike chipset.
> If M is selected the module will be called rzg2l-du-drm.
> +
> +config DRM_RZG2L_MIPI_DSI
> + tristate "RZ/G2L MIPI DSI Encoder Support"
> + depends on DRM && DRM_BRIDGE && OF
> + depends on ARCH_RENESAS || COMPILE_TEST
> + select DRM_MIPI_DSI
> + help
> +   Enable support for the RZ/G2L Display Unit embedded MIPI DSI encoders.
> diff --git a/drivers/gpu/drm/renesas/rz-du/Makefile 
> b/drivers/gpu/drm/renesas/rz-du/Makefile
> index 663b82a2577f..2987900ea6b6 100644
> --- a/drivers/gpu/drm/renesas/rz-du/Makefile
> +++ b/drivers/gpu/drm/renesas/rz-du/Makefile
> @@ -6,3 +6,5 @@ rzg2l-du-drm-y := rzg2l_du_crtc.o \
>  
>  rzg2l-du-drm-$(CONFIG_VIDEO_RENESAS_VSP1)+= rzg2l_du_vsp.o
>  obj-$(CONFIG_DRM_RZG2L_DU)   += rzg2l-du-drm.o
> +
> +obj-$(CONFIG_DRM_RZG2L_MIPI_DSI) += rzg2l_mipi_dsi.o
> diff --git a/drivers/gpu/drm/renesas/rcar-du/rzg2l_mipi_dsi.c 
> b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c
> similarity index 100%
> rename from drivers/gpu/drm/renesas/rcar-du/rzg2l_mipi_dsi.c
> rename to drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c
> diff --git a/drivers/gpu/drm/renesas/rcar-du/rzg2l_mipi_dsi_regs.h 
> b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h
> similarity index 100%
> rename from drivers/gpu/drm/renesas/rcar-du/rzg2l_mipi_dsi_regs.h
> rename to drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi_regs.h

-- 
Regards,

Laurent Pinchart


[PATCH] drm/panel: sitronix-st7703: transition to mipi_dsi wrapped functions

2024-06-25 Thread Tejas Vipin
Use functions introduced in commit 966e397e4f60 ("drm/mipi-dsi:
Introduce mipi_dsi_*_write_seq_multi()") and commit f79d6d28d8fe
("drm/mipi-dsi: wrap more functions for streamline handling") for 
sitronix-st7703 based panels.

Signed-off-by: Tejas Vipin 
---
 drivers/gpu/drm/panel/panel-sitronix-st7703.c | 836 +-
 1 file changed, 400 insertions(+), 436 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7703.c 
b/drivers/gpu/drm/panel/panel-sitronix-st7703.c
index 77b30e045a57..67e8e45498cb 100644
--- a/drivers/gpu/drm/panel/panel-sitronix-st7703.c
+++ b/drivers/gpu/drm/panel/panel-sitronix-st7703.c
@@ -69,7 +69,7 @@ struct st7703_panel_desc {
unsigned int lanes;
unsigned long mode_flags;
enum mipi_dsi_pixel_format format;
-   int (*init_sequence)(struct st7703 *ctx);
+   void (*init_sequence)(struct mipi_dsi_multi_context *dsi_ctx);
 };
 
 static inline struct st7703 *panel_to_st7703(struct drm_panel *panel)
@@ -77,62 +77,58 @@ static inline struct st7703 *panel_to_st7703(struct 
drm_panel *panel)
return container_of(panel, struct st7703, panel);
 }
 
-static int jh057n_init_sequence(struct st7703 *ctx)
+static void jh057n_init_sequence(struct mipi_dsi_multi_context *dsi_ctx)
 {
-   struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
-
/*
 * Init sequence was supplied by the panel vendor. Most of the commands
 * resemble the ST7703 but the number of parameters often don't match
 * so it's likely a clone.
 */
-   mipi_dsi_generic_write_seq(dsi, ST7703_CMD_SETEXTC,
-  0xF1, 0x12, 0x83);
-   mipi_dsi_generic_write_seq(dsi, ST7703_CMD_SETRGBIF,
-  0x10, 0x10, 0x05, 0x05, 0x03, 0xFF, 0x00, 
0x00,
-  0x00, 0x00);
-   mipi_dsi_generic_write_seq(dsi, ST7703_CMD_SETSCR,
-  0x73, 0x73, 0x50, 0x50, 0x00, 0x00, 0x08, 
0x70,
-  0x00);
-   mipi_dsi_generic_write_seq(dsi, ST7703_CMD_SETVDC, 0x4E);
-   mipi_dsi_generic_write_seq(dsi, ST7703_CMD_SETPANEL, 0x0B);
-   mipi_dsi_generic_write_seq(dsi, ST7703_CMD_SETCYC, 0x80);
-   mipi_dsi_generic_write_seq(dsi, ST7703_CMD_SETDISP, 0xF0, 0x12, 0x30);
-   mipi_dsi_generic_write_seq(dsi, ST7703_CMD_SETEQ,
-  0x07, 0x07, 0x0B, 0x0B, 0x03, 0x0B, 0x00, 
0x00,
-  0x00, 0x00, 0xFF, 0x00, 0xC0, 0x10);
-   mipi_dsi_generic_write_seq(dsi, ST7703_CMD_SETBGP, 0x08, 0x08);
-   msleep(20);
-
-   mipi_dsi_generic_write_seq(dsi, ST7703_CMD_SETVCOM, 0x3F, 0x3F);
-   mipi_dsi_generic_write_seq(dsi, ST7703_CMD_UNKNOWN_BF, 0x02, 0x11, 
0x00);
-   mipi_dsi_generic_write_seq(dsi, ST7703_CMD_SETGIP1,
-  0x82, 0x10, 0x06, 0x05, 0x9E, 0x0A, 0xA5, 
0x12,
-  0x31, 0x23, 0x37, 0x83, 0x04, 0xBC, 0x27, 
0x38,
-  0x0C, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 
0x00,
-  0x03, 0x00, 0x00, 0x00, 0x75, 0x75, 0x31, 
0x88,
-  0x88, 0x88, 0x88, 0x88, 0x88, 0x13, 0x88, 
0x64,
-  0x64, 0x20, 0x88, 0x88, 0x88, 0x88, 0x88, 
0x88,
-  0x02, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
-   mipi_dsi_generic_write_seq(dsi, ST7703_CMD_SETGIP2,
-  0x02, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00,
-  0x00, 0x00, 0x00, 0x00, 0x02, 0x46, 0x02, 
0x88,
-  0x88, 0x88, 0x88, 0x88, 0x88, 0x64, 0x88, 
0x13,
-  0x57, 0x13, 0x88, 0x88, 0x88, 0x88, 0x88, 
0x88,
-  0x75, 0x88, 0x23, 0x14, 0x00, 0x00, 0x02, 
0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 
0x0A,
-  0xA5, 0x00, 0x00, 0x00, 0x00);
-   mipi_dsi_generic_write_seq(dsi, ST7703_CMD_SETGAMMA,
-  0x00, 0x09, 0x0E, 0x29, 0x2D, 0x3C, 0x41, 
0x37,
-  0x07, 0x0B, 0x0D, 0x10, 0x11, 0x0F, 0x10, 
0x11,
-  0x18, 0x00, 0x09, 0x0E, 0x29, 0x2D, 0x3C, 
0x41,
-  0x37, 0x07, 0x0B, 0x0D, 0x10, 0x11, 0x0F, 
0x10,
-  0x11, 0x18);
-   msleep(20);
-
-   return 0;
+   mipi_dsi_generic_write_seq_multi(dsi_ctx, ST7703_CMD_SETEXTC,
+0xF1, 0x12, 0x83);
+   mipi_dsi_generic_write_seq_multi(dsi_ctx, ST7703_CMD_SETRGBIF,
+0x10, 0x10, 0x05, 0x05, 0x03, 0xFF, 
0x00,

Re: [PATCH v2 2/2] drm/bridge: add support for TI TDP158

2024-06-25 Thread Dmitry Baryshkov
On Tue, Jun 25, 2024 at 06:38:13PM GMT, Marc Gonzalez wrote:
> The TI TDP158 is an AC-Coupled HDMI signal to TMDS Redriver supporting
> DVI 1.0 and HDMI 1.4b and 2.0b output signals.
> 
> The default settings work fine for our use-case.
> 
> Signed-off-by: Marc Gonzalez 
> ---
>  drivers/gpu/drm/bridge/Kconfig |   6 +++
>  drivers/gpu/drm/bridge/Makefile|   1 +
>  drivers/gpu/drm/bridge/ti-tdp158.c | 103 
> +
>  3 files changed, 110 insertions(+)
> 
> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> index c621be1a99a89..0859f85cb4b69 100644
> --- a/drivers/gpu/drm/bridge/Kconfig
> +++ b/drivers/gpu/drm/bridge/Kconfig
> @@ -368,6 +368,12 @@ config DRM_TI_DLPC3433
> It supports up to 720p resolution with 60 and 120 Hz refresh
> rates.
>  
> +config DRM_TI_TDP158
> + tristate "TI TDP158 HDMI/TMDS bridge"
> + depends on OF
> + help
> +   Texas Instruments TDP158 HDMI/TMDS Bridge driver

Please run ./scripts/checkpatch.pl on your patch.

> +
>  config DRM_TI_TFP410
>   tristate "TI TFP410 DVI/HDMI bridge"
>   depends on OF
> diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
> index 7df87b582dca3..3daf803ce80b6 100644
> --- a/drivers/gpu/drm/bridge/Makefile
> +++ b/drivers/gpu/drm/bridge/Makefile
> @@ -32,6 +32,7 @@ obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/
>  obj-$(CONFIG_DRM_TI_DLPC3433) += ti-dlpc3433.o
>  obj-$(CONFIG_DRM_TI_SN65DSI83) += ti-sn65dsi83.o
>  obj-$(CONFIG_DRM_TI_SN65DSI86) += ti-sn65dsi86.o
> +obj-$(CONFIG_DRM_TI_TDP158) += ti-tdp158.o
>  obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o
>  obj-$(CONFIG_DRM_TI_TPD12S015) += ti-tpd12s015.o
>  obj-$(CONFIG_DRM_NWL_MIPI_DSI) += nwl-dsi.o
> diff --git a/drivers/gpu/drm/bridge/ti-tdp158.c 
> b/drivers/gpu/drm/bridge/ti-tdp158.c
> new file mode 100644
> index 0..b65132e3598fc
> --- /dev/null
> +++ b/drivers/gpu/drm/bridge/ti-tdp158.c
> @@ -0,0 +1,103 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright 2024 Freebox SAS
> + */
> +#include 
> +#include 
> +#include 
> +
> +struct tdp158 {
> + struct drm_bridge bridge;
> + struct drm_bridge *next;
> + struct gpio_desc *enable; // Operation Enable - pin 36
> + struct regulator *vcc; // 3.3V
> + struct regulator *vdd; // 1.1V
> +};
> +
> +static void tdp158_enable(struct drm_bridge *bridge, struct drm_bridge_state 
> *prev)
> +{
> + int err;
> + struct tdp158 *tdp158 = bridge->driver_private;
> +
> + if ((err = regulator_enable(tdp158->vcc)))
> + pr_err("%s: vcc: %d", __func__, err);

- dev_err
- please expand error messages
- ERROR: do not use assignment in if condition

> +
> + if ((err = regulator_enable(tdp158->vdd)))
> + pr_err("%s: vdd: %d", __func__, err);
> +
> + gpiod_set_value_cansleep(tdp158->enable, 1);
> +}
> +
> +static void tdp158_disable(struct drm_bridge *bridge, struct 
> drm_bridge_state *prev)
> +{
> + struct tdp158 *tdp158 = bridge->driver_private;
> +
> + gpiod_set_value_cansleep(tdp158->enable, 0);
> + regulator_disable(tdp158->vdd);
> + regulator_disable(tdp158->vcc);
> +}
> +
> +static int tdp158_attach(struct drm_bridge *bridge, enum 
> drm_bridge_attach_flags flags)
> +{
> + struct tdp158 *tdp158 = bridge->driver_private;

empty line

> + return drm_bridge_attach(bridge->encoder, tdp158->next, bridge, 
> DRM_BRIDGE_ATTACH_NO_CONNECTOR);

No. Pass flags directly.

> +}
> +
> +static const struct drm_bridge_funcs tdp158_bridge_funcs = {
> + .attach = tdp158_attach,
> + .atomic_enable = tdp158_enable,
> + .atomic_disable = tdp158_disable,
> + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
> + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
> + .atomic_reset = drm_atomic_helper_bridge_reset,
> +};
> +
> +static int tdp158_bridge_probe(struct i2c_client *client)
> +{
> + struct tdp158 *tdp158;
> + struct device *dev = &client->dev;
> +
> + tdp158 = devm_kzalloc(dev, sizeof(*tdp158), GFP_KERNEL);
> + if (!tdp158)
> + return -ENOMEM;
> +
> + tdp158->next = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);

Missing `select DRM_PANEL_BRIDGE`

> + if (IS_ERR(tdp158->next))
> + return dev_err_probe(dev, PTR_ERR(tdp158->next), "next");

This results in a cryptic message 'foo: ESOMETHING: next'. Please
expand.

> +
> + tdp158->vcc = devm_regulator_get(dev, "vcc");
> + if (IS_ERR(tdp158->vcc))
> + return dev_err_probe(dev, PTR_ERR(tdp158->vcc), "vcc");
> +
> + tdp158->vdd = devm_regulator_get(dev, "vdd");
> + if (IS_ERR(tdp158->vdd))
> + return dev_err_probe(dev, PTR_ERR(tdp158->vdd), "vdd");
> +
> + tdp158->enable = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
> + if (IS_ERR(tdp158->enable))
> + return dev_err_probe(dev, PTR_ERR(tdp158->enable), "enable");
> +
> + tdp158->br

Re: [PATCH v2 1/2] drm: bridge: samsung-dsim: Initialize bridge on attach

2024-06-25 Thread Marek Vasut

On 6/25/24 4:37 PM, Alexander Stein wrote:

Hi Marek,


Hi,


Am Dienstag, 25. Juni 2024, 14:26:10 CEST schrieb Marek Vasut:

Initialize the bridge on attach already, to force lanes into LP11
state, since attach does trigger attach of downstream bridges which
may trigger (e)DP AUX channel mode read.

This fixes a corner case where DSIM with TC9595 attached to it fails
to operate the DP AUX channel, because the TC9595 enters some debug
mode when it is released from reset without lanes in LP11 mode. By
ensuring the DSIM lanes are in LP11, the TC9595 (tc358767.c driver)
can be reset in its attach callback called from DSIM attach callback,
and recovered out of the debug mode just before TC9595 performs first
AUX channel access later in its attach callback.

Signed-off-by: Marek Vasut 
---
Cc: Adam Ford 
Cc: Alexander Stein 
Cc: Andrzej Hajda 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Frieder Schrempf 
Cc: Inki Dae 
Cc: Jagan Teki 
Cc: Jernej Skrabec 
Cc: Jonas Karlman 
Cc: Laurent Pinchart 
Cc: Lucas Stach 
Cc: Maarten Lankhorst 
Cc: Marek Szyprowski 
Cc: Maxime Ripard 
Cc: Michael Walle 
Cc: Neil Armstrong 
Cc: Robert Foss 
Cc: Thomas Zimmermann 
Cc: dri-devel@lists.freedesktop.org
Cc: ker...@dh-electronics.com
---
V2: Handle case where mode is not set yet
---
  drivers/gpu/drm/bridge/samsung-dsim.c | 32 ---
  1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c 
b/drivers/gpu/drm/bridge/samsung-dsim.c
index e7e53a9e42afb..22d3bbd866d97 100644
--- a/drivers/gpu/drm/bridge/samsung-dsim.c
+++ b/drivers/gpu/drm/bridge/samsung-dsim.c
@@ -699,20 +699,24 @@ static unsigned long samsung_dsim_set_pll(struct 
samsung_dsim *dsi,
  
  static int samsung_dsim_enable_clock(struct samsung_dsim *dsi)

  {
-   unsigned long hs_clk, byte_clk, esc_clk, pix_clk;
+   unsigned long hs_clk, byte_clk, esc_clk;
unsigned long esc_div;
u32 reg;
struct drm_display_mode *m = &dsi->mode;
int bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
  
-	/* m->clock is in KHz */

-   pix_clk = m->clock * 1000;
-
-   /* Use burst_clk_rate if available, otherwise use the pix_clk */
+   /*
+* Use burst_clk_rate if available, otherwise use the mode clock
+* if mode is already set and available, otherwise fall back to
+* PLL input clock and operate in 1:1 lowest frequency mode until
+* a mode is set.
+*/
if (dsi->burst_clk_rate)
hs_clk = samsung_dsim_set_pll(dsi, dsi->burst_clk_rate);
+   else if (m) /* m->clock is in KHz */
+   hs_clk = samsung_dsim_set_pll(dsi, DIV_ROUND_UP(m->clock * 1000 * 
bpp, dsi->lanes));
else
-   hs_clk = samsung_dsim_set_pll(dsi, DIV_ROUND_UP(pix_clk * bpp, 
dsi->lanes));
+   hs_clk = dsi->pll_clk_rate;
  


I can't reproduce that mentioned corner case and presumably this problem
does not exist otherwise. If samsung,burst-clock-frequency is unset I get
a sluggish image on the monitor.

It seems the calculation is using a adjusted clock frequency:
samsung-dsim 32e6.dsi: Using pixel clock for HS clock frequency
samsung-dsim 32e6.dsi: [drm:samsung_dsim_host_attach [samsung_dsim]] 
Attached tc358767 device (lanes:4 bpp:24 mode-flags:0xc03)
samsung-dsim 32e6.dsi: PLL ref clock freq 2400
samsung-dsim 32e6.dsi: failed to find PLL PMS for requested frequency
samsung-dsim 32e6.dsi: failed to configure DSI PLL
samsung-dsim 32e6.dsi: PLL ref clock freq 2400
samsung-dsim 32e6.dsi: PLL freq 883636363, (p 11, m 810, s 1)
samsung-dsim 32e6.dsi: hs_clk = 883636363, byte_clk = 110454545, esc_clk = 
9204545
samsung-dsim 32e6.dsi: calculated hfp: 60, hbp: 105, hsa: 27
samsung-dsim 32e6.dsi: LCD size = 1920x1080

891 MHz is the nominal one for 148.5 MHz pixelclock. But even setting
samsung,burst-clock-frequency to 891 MHz results in a sluggish image.
Maybe this usecase is nothing I need to consider while using DSI-DP
with EDID timings available.

As the burst clock needs to provide more bandwidth than actually needed,
I consider this a different usecase not providing
samsung,burst-clock-frequency for DSI->DP usage.

But the initialization upon attach is working intended, so:
Reviewed-by: Alexander Stein 


Thank you for testing and keeping up with this. I will wait for more 
feedback if there is any (Frieder? Lucas? Michael?). If there are no 
objections, then I can merge it in a week or two ?


Re: [PATCH 3/3] drm/panel: add lincoln lcd197 support

2024-06-25 Thread Dmitry Baryshkov
On Tue, Jun 25, 2024 at 04:25:50PM GMT, Jerome Brunet wrote:
> Add support for the Lincoln LCD197 1080x1920 DSI panel.
> 
> Signed-off-by: Jerome Brunet 
> ---
>  drivers/gpu/drm/panel/Kconfig|  11 +
>  drivers/gpu/drm/panel/Makefile   |   1 +
>  drivers/gpu/drm/panel/panel-lincoln-lcd197.c | 333 +++
>  3 files changed, 345 insertions(+)
>  create mode 100644 drivers/gpu/drm/panel/panel-lincoln-lcd197.c
> 

[...]

> +
> + mipi_dsi_dcs_write_seq(lcd->dsi, 0xB9, 0xFF, 0x83, 0x99);

- Please use lowercase hex instead
- Please consider switching to _multi() functions.


> + usleep_range(200, 300);

This will require new helper msm_dsi_usleep_range(ctx, 200, 300);

> + mipi_dsi_dcs_write_seq(lcd->dsi, 0xB6, 0x92, 0x92);
> + mipi_dsi_dcs_write_seq(lcd->dsi, 0xCC, 0x00);
> + mipi_dsi_dcs_write_seq(lcd->dsi, 0xBF, 0x40, 0x41, 0x50, 0x49);
> + mipi_dsi_dcs_write_seq(lcd->dsi, 0xC6, 0xFF, 0xF9);
> + mipi_dsi_dcs_write_seq(lcd->dsi, 0xC0, 0x25, 0x5A);
> + mipi_dsi_dcs_write_seq(lcd->dsi, MIPI_DCS_SET_ADDRESS_MODE, 0x02);
> +
> + err = mipi_dsi_dcs_exit_sleep_mode(lcd->dsi);
> + if (err < 0) {
> + dev_err(panel->dev, "failed to exit sleep mode: %d\n", err);
> + goto poweroff;
> + }
> + msleep(120);
> +
> + err = mipi_dsi_dcs_read(lcd->dsi, MIPI_DCS_GET_DISPLAY_ID, display_id, 
> 3);

This probably needs new _multi helper too.

> + if (err < 0) {
> + dev_err(panel->dev, "Failed to read display id: %d\n", err);
> + } else {
> + dev_dbg(panel->dev, "Display id: 0x%02x-0x%02x-0x%02x\n",
> + display_id[0], display_id[1], display_id[2]);
> + }
> +
> + lcd->prepared = true;

Should not be required anymore.

> +
> + return 0;
> +
> +poweroff:
> + gpiod_set_value_cansleep(lcd->enable_gpio, 0);
> + gpiod_set_value_cansleep(lcd->reset_gpio, 1);
> + regulator_disable(lcd->supply);
> +
> + return err;
> +}
> +

> +
> +static const struct drm_display_mode default_mode = {
> + .clock = 154002,
> + .hdisplay = 1080,
> + .hsync_start = 1080 + 20,
> + .hsync_end = 1080 + 20 + 6,
> + .htotal = 1080 + 204,
> + .vdisplay = 1920,
> + .vsync_start = 1920 + 4,
> + .vsync_end = 1920 + 4 + 4,
> + .vtotal = 1920 + 79,
> + .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
> +};
> +
> +static int lincoln_lcd197_panel_get_modes(struct drm_panel *panel,
> +   struct drm_connector *connector)
> +{
> + struct drm_display_mode *mode;
> +
> + mode = drm_mode_duplicate(connector->dev, &default_mode);
> + if (!mode) {
> + dev_err(panel->dev, "failed to add mode %ux%u@%u\n",
> + default_mode.hdisplay, default_mode.vdisplay,
> + drm_mode_vrefresh(&default_mode));
> + return -ENOMEM;
> + }
> +
> + drm_mode_set_name(mode);
> + drm_mode_probed_add(connector, mode);
> + connector->display_info.width_mm = 79;
> + connector->display_info.height_mm = 125;

drm_connector_helper_get_modes_fixed()

> +
> + return 1;
> +}
> +


> +
> +static void lincoln_lcd197_panel_shutdown(struct mipi_dsi_device *dsi)
> +{
> + struct lincoln_lcd197_panel *lcd = mipi_dsi_get_drvdata(dsi);
> +
> + drm_panel_disable(&lcd->panel);
> + drm_panel_unprepare(&lcd->panel);
> +}

I think the agreement was that there should be no need for the panel's
shutdown, the DRM driver should shutdown the panel.


-- 
With best wishes
Dmitry


Re: [PATCH] drm/ast: Inline drm_simple_encoder_init()

2024-06-25 Thread Dmitry Baryshkov
On Tue, Jun 25, 2024 at 03:18:09PM GMT, Thomas Zimmermann wrote:
> The function drm_simple_encoder_init() is a trivial helper and
> deprecated. Replace it with the regular call to drm_encoder_init().
> Resolves the dependency on drm_simple_kms_helper.h. No functional
> changes.
> 
> Signed-off-by: Thomas Zimmermann 
> ---
>  drivers/gpu/drm/ast/ast_mode.c | 45 ++
>  1 file changed, 40 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
> index 6695af70768f..2fd9c78eab73 100644
> --- a/drivers/gpu/drm/ast/ast_mode.c
> +++ b/drivers/gpu/drm/ast/ast_mode.c
> @@ -45,7 +45,6 @@
>  #include 
>  #include 
>  #include 
> -#include 
>  
>  #include "ast_ddc.h"
>  #include "ast_drv.h"
> @@ -1358,6 +1357,14 @@ static int ast_crtc_init(struct drm_device *dev)
>   return 0;
>  }
>  
> +/*
> + * VGA Encoder
> + */
> +
> +static const struct drm_encoder_funcs ast_vga_encoder_funcs = {
> + .destroy = drm_encoder_cleanup,
> +};
> +
>  /*
>   * VGA Connector
>   */
> @@ -1411,7 +1418,8 @@ static int ast_vga_output_init(struct ast_device *ast)
>   struct drm_connector *connector = &ast->output.vga.connector;
>   int ret;
>  
> - ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_DAC);
> + ret = drm_encoder_init(dev, encoder, &ast_vga_encoder_funcs,
> +DRM_MODE_ENCODER_DAC, NULL);

What about using drmm_encoder_init() instead? It will call
drm_encoder_cleanup automatically.

-- 
With best wishes
Dmitry


Re: [PATCH] dt-bindings: display/msm/gmu: fix the schema being not applied

2024-06-25 Thread Dmitry Baryshkov
On Tue, Jun 25, 2024 at 04:51:27PM GMT, Rob Herring wrote:
> On Sun, Jun 23, 2024 at 02:59:30PM +0200, Krzysztof Kozlowski wrote:
> > dtschema v2024.4, v2024.5 and maybe earlier do not select device nodes for
> 
> That should be just since db9c05a08709 ("validator: Rework selecting 
> schemas for validation") AKA the 6x speed up in v2024.04.
> 
> > given binding validation if the schema contains compatible list with
> > pattern and a const fallback.  This leads to binding being a no-op - not
> > being applied at all.  Issue should be fixed in the dtschema but for now
> > add a work-around do the binding can be used against DTS validation.
> 
> The issue is we only look at the first compatible. I'm testing out a fix 
> and will apply it tomorrow assuming no issues. With that, I don't think 
> we should apply this patch.

I think we ended up picking up the next iteration of the patch, but we
can probably land a revert later.

> 
> > 
> > Signed-off-by: Krzysztof Kozlowski 
> > 
> > ---
> > 
> > Cc: Akhil P Oommen 
> > ---
> >  .../devicetree/bindings/display/msm/gmu.yaml | 12 
> >  1 file changed, 12 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/display/msm/gmu.yaml 
> > b/Documentation/devicetree/bindings/display/msm/gmu.yaml
> > index b3837368a260..8d1b515f59ec 100644
> > --- a/Documentation/devicetree/bindings/display/msm/gmu.yaml
> > +++ b/Documentation/devicetree/bindings/display/msm/gmu.yaml
> > @@ -17,6 +17,18 @@ description: |
> >management and support to improve power efficiency and reduce the load on
> >the CPU.
> >  
> > +# dtschema does not select nodes based on pattern+const, so add custom 
> > select
> > +# as a work-around:
> > +select:
> > +  properties:
> > +compatible:
> > +  contains:
> > +enum:
> > +  - qcom,adreno-gmu
> > +  - qcom,adreno-gmu-wrapper
> > +  required:
> > +- compatible
> > +
> >  properties:
> >compatible:
> >  oneOf:
> > -- 
> > 2.43.0
> > 

-- 
With best wishes
Dmitry


Re: [PATCH 7/7] arm64: dts: qcom: add OnePlus 8T (kebab)

2024-06-25 Thread Bjorn Andersson
On Mon, Jun 24, 2024 at 03:30:31AM GMT, Caleb Connolly wrote:
> Initial support for USB, UFS, touchscreen, panel, wifi, and bluetooth.
> 

Nice.

> diff --git a/arch/arm64/boot/dts/qcom/sm8250-oneplus-common.dtsi 
> b/arch/arm64/boot/dts/qcom/sm8250-oneplus-common.dtsi
[..]
> + vph_pwr: vph-pwr-regulator {

Please keep nodes sorted by address, then node name, then label (as
applicable). Perhaps making the -regulator suffix a regulator- prefix
instead (to keep them grouped).

> + compatible = "regulator-fixed";
> + regulator-name = "vph_pwr";
> + regulator-min-microvolt = <370>;
> + regulator-max-microvolt = <370>;
> + regulator-always-on;
> + };
> +
> + vreg_s4a_1p8: vreg-s4a-1p8 {
> + compatible = "regulator-fixed";
> + regulator-name = "vreg_s4a_1p8";
> + regulator-min-microvolt = <180>;
> + regulator-max-microvolt = <180>;
> + regulator-always-on;
> + };
[..]
> +&adsp {
> + status = "okay";

Per Documentation/devicetree/bindings/dts-coding-style.rst please keep
"status" as last property in your nodes.

> + firmware-name = "qcom/sm8250/OnePlus/adsp.mbn";
> +};
> +
[..]
> +&mdss_dsi0 {
> + status = "okay";
> + vdda-supply = <&vreg_l9a_1p2>;
> +
> + display_panel: panel@0 {
> + reg = <0>;
> + vddio-supply = <&vreg_l14a_1p8>;
> + vdd-supply = <&vreg_l11c_3p3>;
> + avdd-supply = <&panel_avdd_5p5>;

How do you know that the panel will have these properties, when you
don't give it a compatible here? Not a strong objection, but perhaps
this should be pushed out?

> + /* FIXME: There is a bug somewhere in the display stack and it 
> isn't
> +  * possible to get the panel to a working state after toggling 
> reset.
> +  * At best it just shows one or more vertical red lines. So for 
> now
> +  * let's skip the reset GPIO.
> +  */
> + // reset-gpios = <&tlmm 75 GPIO_ACTIVE_LOW>;
> +
> + pinctrl-0 = <&panel_reset_pins &panel_vsync_pins 
> &panel_vout_pins>;
> + pinctrl-names = "default";
> +
> + status = "disabled";
> +
> + port {
> + panel_in_0: endpoint {
> + remote-endpoint = <&mdss_dsi0_out>;
> + };
> + };
> + };
> +
> +};
[..]
> +&pm8150_gpios {
> + gpio-reserved-ranges = <2 1>, <4 1>, <8 1>;

How come?

> +};
> +
[..]
> +&tlmm {
> + gpio-reserved-ranges = <28 4>, <40 4>;
> +
> + bt_en_state: bt-default-state {
> + pins = "gpio21";
> + function = "gpio";
> + drive-strength = <16>;
> + output-low;
> + bias-pull-up;
> + };
> +
> + wlan_en_state: wlan-default-state {
> + wlan-en-pins {

Perhaps flatten this?

> + pins = "gpio20";
> + function = "gpio";
> +
> + drive-strength = <16>;
> + output-low;
> + bias-pull-up;
> + };
> + };
> +
[..]
> diff --git a/arch/arm64/boot/dts/qcom/sm8250-oneplus-kebab.dts 
> b/arch/arm64/boot/dts/qcom/sm8250-oneplus-kebab.dts
[..]
> +&i2c13 {
[..]
> +};
> +
> +&display_panel {

'd' < 'i'

Regards,
Bjorn

> + compatible = "samsung,amb655x";
> + status = "okay";
> +};
> 
> -- 
> 2.45.0
> 


Re: [etnaviv-next v14 0/8] drm/etnaviv: Add driver wrapper for vivante GPUs attached on PCI(e) device

2024-06-25 Thread Icenowy Zheng
在 2024-06-25星期二的 14:01 +0200,Lucas Stach写道:
> Am Dienstag, dem 25.06.2024 um 11:18 +0800 schrieb Icenowy Zheng:
> > 在 2024-05-20星期一的 00:53 +0800,Sui Jingfeng写道:
> > > drm/etnaviv use the component framework to bind multiple GPU
> > > cores to
> > > a
> > > virtual master, the virtual master is manually create during
> > > driver
> > > load
> > > time. This works well for various SoCs, yet there are some PCIe
> > > card
> > > has
> > > the vivante GPU cores integrated. The driver lacks the support
> > > for
> > > PCIe
> > > devices currently.
> > > 
> > > Adds PCIe driver wrapper on the top of what drm/etnaviv already
> > > has,
> > > the
> > > component framework is still being used to bind subdevices, even
> > > though
> > > there is only one GPU core. But the process is going to be
> > > reversed,
> > > we
> > > create virtual platform device for each of the vivante GPU IP
> > > core
> > > shipped
> > > by the PCIe master. The PCIe master is real, bind all the virtual
> > > child
> > > to the master with component framework.
> > > 
> > > 
> > > v6:
> > > * Fix build issue on system without CONFIG_PCI enabled
> > > v7:
> > > * Add a separate patch for the platform driver
> > > rearrangement
> > > (Bjorn)
> > > * Switch to runtime check if the GPU is dma coherent or
> > > not
> > > (Lucas)
> > > * Add ETNAVIV_PARAM_GPU_COHERENT to allow userspace to
> > > query
> > > (Lucas)
> > > * Remove etnaviv_gpu.no_clk member (Lucas)
> > > * Fix Various typos and coding style fixed (Bjorn)
> > > v8:
> > > * Fix typos and remove unnecessary header included
> > > (Bjorn).
> > > * Add a dedicated function to create the virtual master
> > > platform
> > >   device.
> > > v9:
> > > * Use PCI_VDEVICE() macro (Bjorn)
> > > * Add trivial stubs for the PCI driver (Bjorn)
> > > * Remove a redundant dev_err() usage (Bjorn)
> > > * Clean up etnaviv_pdev_probe() with
> > > etnaviv_of_first_available_node()
> > > v10:
> > > * Add one more cleanup patch
> > > * Resolve the conflict with a patch from Rob
> > > * Make the dummy PCI stub inlined
> > > * Print only if the platform is dma-coherrent
> > > V11:
> > > * Drop unnecessary changes (Lucas)
> > > * Tweak according to other reviews of v10.
> > > 
> > > V12:
> > > * Create a virtual platform device for the subcomponent
> > > GPU
> > > cores
> > > * Bind all subordinate GPU cores to the real PCI master
> > > via
> > > component.
> > > 
> > > V13:
> > > * Drop the non-component code path, always use the
> > > component
> > > framework
> > >   to bind subcomponent GPU core. Even though there is
> > > only
> > > one core.
> > > * Defer the irq handler register.
> > > * Rebase and improve the commit message
> > > 
> > > V14:
> > > * Rebase onto etnaviv-next and improve commit message.
> > > 
> > > Tested with JD9230P GPU and LingJiu GP102 GPU.
> > 
> > BTW how should VRAM and displayed related parts be handled on these
> > dGPUs?
> > 
> The only way to handle VRAM properly would be to rewrite our GEM
> internals using TTM.

I suggest for these kind of dGPU to create a brand new driver instead.

BTW, Jingfeng, what's the situation of the Loongson 7A1000 GPU? Do it
share the same address space with the CPU?

(The display of 7A is another virtual PCI device that is already
handled in loongson-drm driver and don't need to be worried)

> 
> Regards,
> Lucas
> 
> > > 
> > > Sui Jingfeng (8):
> > >   drm/etnaviv: Add a dedicated helper function to get various
> > > clocks
> > >   drm/etnaviv: Add constructor and destructor for the
> > >     etnaviv_drm_private structure
> > >   drm/etnaviv: Embed struct drm_device into struct
> > > etnaviv_drm_private
> > >   drm/etnaviv: Fix wrong cache property being used for vmap()
> > >   drm/etnaviv: Add support for cached coherent caching mode
> > >   drm/etnaviv: Replace the '&pdev->dev' with 'dev'
> > >   drm/etnaviv: Allow creating subdevices and pass platform
> > > specific
> > > data
> > >   drm/etnaviv: Add support for vivante GPU cores attached via
> > > PCIe
> > >     device
> > > 
> > >  drivers/gpu/drm/etnaviv/Kconfig  |   8 +
> > >  drivers/gpu/drm/etnaviv/Makefile |   2 +
> > >  drivers/gpu/drm/etnaviv/etnaviv_drv.c    | 159 ++---
> > > ---
> > >  drivers/gpu/drm/etnaviv/etnaviv_drv.h    |  27 +++
> > >  drivers/gpu/drm/etnaviv/etnaviv_gem.c    |  22 ++-
> > >  drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c |   2 +-
> > >  drivers/gpu/drm/etnaviv/etnaviv_gpu.c    | 144 +
> > > -
> > >  drivers/gpu/drm/etnaviv/etnaviv_gpu.h    |   4 +
> > >  drivers/gpu/drm/etnaviv/etnaviv_mmu.c    |   4 +-
> > >  drivers/gpu/drm/etnaviv/etnaviv_pci_drv.c    | 187
> > > +++
> > >  drivers/gpu/drm/etnaviv/etnaviv_pci_drv.h    |  18 ++
> > >  include/uapi/drm/etnaviv_drm.h   

Re: [PATCH] drm/lima: Mark simple_ondemand governor as softdep

2024-06-25 Thread Qiang Yu
On Wed, Jun 26, 2024 at 2:15 AM Dragan Simic  wrote:
>
> Hello everyone,
>
> Just checking, any further thoughts about this patch?
>
I'm OK with this as a temp workaround because it's simple and do no harm
even it's not perfect. If no other better suggestion for short term, I'll submit
this at weekend.

> On 2024-06-18 21:22, Dragan Simic wrote:
> > On 2024-06-18 12:33, Dragan Simic wrote:
> >> On 2024-06-18 10:13, Maxime Ripard wrote:
> >>> On Tue, Jun 18, 2024 at 04:01:26PM GMT, Qiang Yu wrote:
>  On Tue, Jun 18, 2024 at 12:33 PM Qiang Yu  wrote:
>  >
>  > I see the problem that initramfs need to build a module dependency 
>  > chain,
>  > but lima does not call any symbol from simpleondemand governor module.
>  > softdep module seems to be optional while our dependency is hard one,
>  > can we just add MODULE_INFO(depends, _depends), or create a new
>  > macro called MODULE_DEPENDS()?
> >>
> >> I had the same thoughts, because softdeps are for optional module
> >> dependencies, while in this case it's a hard dependency.  Though,
> >> I went with adding a softdep, simply because I saw no better option
> >> available.
> >>
>  This doesn't work on my side because depmod generates modules.dep
>  by symbol lookup instead of modinfo section. So softdep may be our
>  only
>  choice to add module dependency manually. I can accept the softdep
>  first, then make PM optional later.
> >>
> >> I also thought about making devfreq optional in the Lima driver,
> >> which would make this additional softdep much more appropriate.
> >> Though, I'm not really sure that's a good approach, because not
> >> having working devfreq for Lima might actually cause issues on
> >> some devices, such as increased power consumption.
> >>
> >> In other words, it might be better to have Lima probing fail if
> >> devfreq can't be initialized, rather than having probing succeed
> >> with no working devfreq.  Basically, failed probing is obvious,
> >> while a warning in the kernel log about no devfreq might easily
> >> be overlooked, causing regressions on some devices.
> >>
> >>> It's still super fragile, and depends on the user not changing the
> >>> policy. It should be solved in some other, more robust way.
> >>
> >> I see, but I'm not really sure how to make it more robust?  In
> >> the end, some user can blacklist the simple_ondemand governor
> >> module, and we can't do much about it.
> >>
> >> Introducing harddeps alongside softdeps would make sense from
> >> the design standpoint, but the amount of required changes wouldn't
> >> be trivial at all, on various levels.
> >
> > After further investigation, it seems that the softdeps have
> > already seen a fair amount of abuse for what they actually aren't
> > intended, i.e. resolving hard dependencies.  For example, have
> > a look at the commit d5178578bcd4 (btrfs: directly call into
> > crypto framework for checksumming) [1] and the lines containing
> > MODULE_SOFTDEP() at the very end of fs/btrfs/super.c. [2]
> >
> > If a filesystem driver can rely on the abuse of softdeps, which
> > admittedly are a bit fragile, I think we can follow the same
> > approach, at least for now.
> >
> > With all that in mind, I think that accepting this patch, as well
> > as the related Panfrost patch, [3] should be warranted.  I'd keep
> > investigating the possibility of introducing harddeps in form
> > of MODULE_HARDDEP() and the related support in kmod project,
> > similar to the already existing softdep support, [4] but that
> > will inevitably take a lot of time, both for implementing it
> > and for reaching various Linux distributions, which is another
> > reason why accepting these patches seems reasonable.
> >
> > [1]
> > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d5178578bcd4
> > [2]
> > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/btrfs/super.c#n2593
> > [3]
> > https://lore.kernel.org/dri-devel/4e1e00422a14db4e2a80870afb704405da16fd1b.1718655077.git.dsi...@manjaro.org/
> > [4]
> > https://git.kernel.org/pub/scm/utils/kernel/kmod/kmod.git/commit/?id=49d8e0b59052999de577ab732b719cfbeb89504d


Re: [PATCH] dt-bindings: display/msm/gmu: fix the schema being not applied

2024-06-25 Thread Rob Herring
On Sun, Jun 23, 2024 at 02:59:30PM +0200, Krzysztof Kozlowski wrote:
> dtschema v2024.4, v2024.5 and maybe earlier do not select device nodes for

That should be just since db9c05a08709 ("validator: Rework selecting 
schemas for validation") AKA the 6x speed up in v2024.04.

> given binding validation if the schema contains compatible list with
> pattern and a const fallback.  This leads to binding being a no-op - not
> being applied at all.  Issue should be fixed in the dtschema but for now
> add a work-around do the binding can be used against DTS validation.

The issue is we only look at the first compatible. I'm testing out a fix 
and will apply it tomorrow assuming no issues. With that, I don't think 
we should apply this patch.

> 
> Signed-off-by: Krzysztof Kozlowski 
> 
> ---
> 
> Cc: Akhil P Oommen 
> ---
>  .../devicetree/bindings/display/msm/gmu.yaml | 12 
>  1 file changed, 12 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/display/msm/gmu.yaml 
> b/Documentation/devicetree/bindings/display/msm/gmu.yaml
> index b3837368a260..8d1b515f59ec 100644
> --- a/Documentation/devicetree/bindings/display/msm/gmu.yaml
> +++ b/Documentation/devicetree/bindings/display/msm/gmu.yaml
> @@ -17,6 +17,18 @@ description: |
>management and support to improve power efficiency and reduce the load on
>the CPU.
>  
> +# dtschema does not select nodes based on pattern+const, so add custom select
> +# as a work-around:
> +select:
> +  properties:
> +compatible:
> +  contains:
> +enum:
> +  - qcom,adreno-gmu
> +  - qcom,adreno-gmu-wrapper
> +  required:
> +- compatible
> +
>  properties:
>compatible:
>  oneOf:
> -- 
> 2.43.0
> 


Re: [PATCH v2 2/2] Revert "drm/msm/a6xx: Poll for GBIF unhalt status in hw_init"

2024-06-25 Thread Rob Clark
On Tue, Jun 25, 2024 at 1:18 PM Dmitry Baryshkov
 wrote:
>
> On Tue, 25 Jun 2024 at 21:54, Konrad Dybcio  wrote:
> >
> > Commit c9707bcbd0f3 ("drm/msm/adreno: De-spaghettify the use of memory
>
> ID is not present in next

it ofc wouldn't be, because it was the previous patch in this series ;-)

I've fixed that up (and below) while applying the patch

BR,
-R

> > barriers") made some fixups relating to write arrival, ensuring that
> > the GPU's memory interface has *really really really* been told to come
> > out of reset. That in turn rendered the hacky commit being reverted no
> > longer necessary.
> >
> > Get rid of it.
> >
> > This reverts commit b77532803d11f2b03efab2ebfd8c0061cd7f8b30.
>
> b77532803d11 ("drm/msm/a6xx: Poll for GBIF unhalt status in hw_init")
>
> >
> > Signed-off-by: Konrad Dybcio 
> > ---
> >  drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 4 
> >  1 file changed, 4 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
> > b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > index 4083d0cad782..03e23eef5126 100644
> > --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > @@ -867,10 +867,6 @@ static int hw_init(struct msm_gpu *gpu)
> > gpu_read(gpu, REG_A6XX_RBBM_GBIF_HALT);
> > }
> >
> > -   /* Some GPUs are stubborn and take their sweet time to unhalt GBIF! 
> > */
> > -   if (adreno_is_a7xx(adreno_gpu) && a6xx_has_gbif(adreno_gpu))
> > -   spin_until(!gpu_read(gpu, REG_A6XX_GBIF_HALT_ACK));
> > -
> > gpu_write(gpu, REG_A6XX_RBBM_SECVID_TSB_CNTL, 0);
> >
> > if (adreno_is_a619_holi(adreno_gpu))
> >
> > --
> > 2.45.2
> >
>
>
> --
> With best wishes
> Dmitry


Re: [PATCH] drm/msm/a6xx: request memory region

2024-06-25 Thread Rob Clark
On Tue, Jun 25, 2024 at 1:23 PM Akhil P Oommen  wrote:
>
> On Tue, Jun 25, 2024 at 11:03:42AM -0700, Rob Clark wrote: > On Tue, Jun 25, 
> 2024 at 10:59 AM Akhil P Oommen  wrote:
> > >
> > > On Fri, Jun 21, 2024 at 02:09:58PM -0700, Rob Clark wrote:
> > > > On Sat, Jun 8, 2024 at 8:44 AM Kiarash Hajian
> > > >  wrote:
> > > > >
> > > > > The driver's memory regions are currently just ioremap()ed, but not
> > > > > reserved through a request. That's not a bug, but having the request 
> > > > > is
> > > > > a little more robust.
> > > > >
> > > > > Implement the region-request through the corresponding managed
> > > > > devres-function.
> > > > >
> > > > > Signed-off-by: Kiarash Hajian 
> > > > > ---
> > > > > Changes in v6:
> > > > > -Fix compile error
> > > > > -Link to v5: 
> > > > > https://lore.kernel.org/all/20240607-memory-v1-1-8664f52fc...@gmail.com
> > > > >
> > > > > Changes in v5:
> > > > > - Fix error hanlding problems.
> > > > > - Link to v4: 
> > > > > https://lore.kernel.org/r/20240512-msm-adreno-memory-region-v4-1-3881a6408...@gmail.com
> > > > >
> > > > > Changes in v4:
> > > > > - Combine v3 commits into a singel commit
> > > > > - Link to v3: 
> > > > > https://lore.kernel.org/r/20240512-msm-adreno-memory-region-v3-0-0a728ad45...@gmail.com
> > > > >
> > > > > Changes in v3:
> > > > > - Remove redundant devm_iounmap calls, relying on devres for 
> > > > > automatic resource cleanup.
> > > > >
> > > > > Changes in v2:
> > > > > - update the subject prefix to "drm/msm/a6xx:", to match the 
> > > > > majority of other changes to this file.
> > > > > ---
> > > > >  drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 33 
> > > > > +++--
> > > > >  1 file changed, 11 insertions(+), 22 deletions(-)
> > > > >
> > > > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
> > > > > b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> > > > > index 8bea8ef26f77..d26cc6254ef9 100644
> > > > > --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> > > > > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> > > > > @@ -525,7 +525,7 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu 
> > > > > *gmu)
> > > > > bool pdc_in_aop = false;
> > > > >
> > > > > if (IS_ERR(pdcptr))
> > > > > -   goto err;
> > > > > +   return;
> > > > >
> > > > > if (adreno_is_a650(adreno_gpu) ||
> > > > > adreno_is_a660_family(adreno_gpu) ||
> > > > > @@ -541,7 +541,7 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu 
> > > > > *gmu)
> > > > > if (!pdc_in_aop) {
> > > > > seqptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc_seq");
> > > > > if (IS_ERR(seqptr))
> > > > > -   goto err;
> > > > > +   return;
> > > > > }
> > > > >
> > > > > /* Disable SDE clock gating */
> > > > > @@ -633,12 +633,6 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu 
> > > > > *gmu)
> > > > > wmb();
> > > > >
> > > > > a6xx_rpmh_stop(gmu);
> > > > > -
> > > > > -err:
> > > > > -   if (!IS_ERR_OR_NULL(pdcptr))
> > > > > -   iounmap(pdcptr);
> > > > > -   if (!IS_ERR_OR_NULL(seqptr))
> > > > > -   iounmap(seqptr);
> > > > >  }
> > > > >
> > > > >  /*
> > > > > @@ -1503,7 +1497,7 @@ static void __iomem *a6xx_gmu_get_mmio(struct 
> > > > > platform_device *pdev,
> > > > > return ERR_PTR(-EINVAL);
> > > > > }
> > > > >
> > > > > -   ret = ioremap(res->start, resource_size(res));
> > > > > +   ret = devm_ioremap_resource(&pdev->dev, res);
> > > >
> > > > So, this doesn't actually work, failing in __request_region_locked(),
> > > > because the gmu region partially overlaps with the gpucc region (which
> > > > is busy).  I think this is intentional, since gmu is controlling the
> > > > gpu clocks, etc.  In particular REG_A6XX_GPU_CC_GX_GDSCR is in this
> > > > overlapping region.  Maybe Akhil knows more about GMU.
> > >
> > > We don't really need to map gpucc region from driver on behalf of gmu.
> > > Since we don't access any gpucc register from drm-msm driver, we can
> > > update the range size to correct this. But due to backward compatibility
> > > requirement with older dt, can we still enable region locking? I prefer
> > > it if that is possible.
> >
> > Actually, when I reduced the region size to not overlap with gpucc,
> > the region is smaller than REG_A6XX_GPU_CC_GX_GDSCR * 4.
> >
> > So I guess that register is actually part of gpucc?
>
> Yes. It has *GPU_CC* in its name. :P
>
> I just saw that we program this register on legacy a6xx targets to
> ensure retention is really ON before collapsing gdsc. So we can't
> avoid mapping gpucc region in legacy a6xx GPUs. That is unfortunate!

I guess we could still use devm_ioremap().. idk if there is a better
way to solve this

BR,
-R

> -Akhil.
>
> >
> > BR,
> > -R
> >
> > > FYI, kgsl accesses gpucc registers to ensure gdsc has collapsed. So
> > > gpucc region has to

Re: [PATCH RFC v3] drm/msm/dpu: Configure DP INTF/PHY selector

2024-06-25 Thread Abhinav Kumar




On 6/25/2024 1:24 PM, Dmitry Baryshkov wrote:

From: Bjorn Andersson 

Some platforms provides a mechanism for configuring the mapping between
(one or two) DisplayPort intfs and their PHYs.

In particular SC8180X requires this to be configured, since on this
platform there are fewer controllers than PHYs.

The change implements the logic for optionally configuring which PHY
each of the DP INTFs should be connected to and marks the SC8180X DPU to
program 2 entries.

For now the request is simply to program the mapping 1:1, any support
for alternative mappings is left until the use case arrise.

Note that e.g. msm-4.14 unconditionally maps INTF 0 to PHY 0 on all
platforms, so perhaps this is needed in order to get DisplayPort working
on some other platforms as well.

Signed-off-by: Bjorn Andersson 
Co-developed-by: Bjorn Andersson 
Signed-off-by: Dmitry Baryshkov 
---
Changes in v3:
- Expanded the commit message and in-code comment based on feedback from
   Abhinav
- Fixed field masks for the affected register (Abhinav)
- Link to v2: 
https://lore.kernel.org/r/20240613-dp-phy-sel-v2-1-99af348c9...@linaro.org

Changes in v2:
- Removed entry from the catalog.
- Reworked the interface of dpu_hw_dp_phy_intf_sel(). Pass two entries
   for the PHYs instead of three entries.
- It seems the register isn't present on sdm845, enabled the callback
   only for DPU >= 5.x
- Added a comment regarding the data being platform-specific.
- Link to v1: 
https://lore.kernel.org/r/20230612221047.1886709-1-quic_bjora...@quicinc.com
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c | 39 +++---
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h | 18 --
  drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h   |  7 ++
  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c| 12 -
  4 files changed, 70 insertions(+), 6 deletions(-)



LGTM.

Reviewed-by: Abhinav Kumar 


Re: [PATCH v2 0/2] Clean up barriers

2024-06-25 Thread Akhil P Oommen
On Tue, Jun 25, 2024 at 08:54:40PM +0200, Konrad Dybcio wrote:
> Changes in v3:
> - Drop the wrapper functions
> - Drop the readback in GMU code
> - Split the commit in two
> 
> Link to v2: 
> https://lore.kernel.org/linux-arm-msm/20240509-topic-adreno-v2-1-b82a9f99b...@linaro.org/
> 
> Changes in v2:
> - Introduce gpu_write_flush() and use it
> - Don't accidentally break a630 by trying to write to non-existent GBIF
> 
> Link to v1: 
> https://lore.kernel.org/linux-arm-msm/20240508-topic-adreno-v1-1-1babd05c1...@linaro.org/
> 
> Signed-off-by: Konrad Dybcio 
> ---
> Konrad Dybcio (2):
>   drm/msm/adreno: De-spaghettify the use of memory barriers
>   Revert "drm/msm/a6xx: Poll for GBIF unhalt status in hw_init"
> 
>  drivers/gpu/drm/msm/adreno/a6xx_gmu.c |  4 +---
>  drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 14 ++
>  2 files changed, 7 insertions(+), 11 deletions(-)
> ---
> base-commit: 0fc4bfab2cd45f9acb86c4f04b5191e114e901ed
> change-id: 20240625-adreno_barriers-29f356742418

for the whole series:
Reviewed-by: Akhil P Oommen 

-Akhil

> 
> Best regards,
> -- 
> Konrad Dybcio 
> 


[PATCH RFC v3] drm/msm/dpu: Configure DP INTF/PHY selector

2024-06-25 Thread Dmitry Baryshkov
From: Bjorn Andersson 

Some platforms provides a mechanism for configuring the mapping between
(one or two) DisplayPort intfs and their PHYs.

In particular SC8180X requires this to be configured, since on this
platform there are fewer controllers than PHYs.

The change implements the logic for optionally configuring which PHY
each of the DP INTFs should be connected to and marks the SC8180X DPU to
program 2 entries.

For now the request is simply to program the mapping 1:1, any support
for alternative mappings is left until the use case arrise.

Note that e.g. msm-4.14 unconditionally maps INTF 0 to PHY 0 on all
platforms, so perhaps this is needed in order to get DisplayPort working
on some other platforms as well.

Signed-off-by: Bjorn Andersson 
Co-developed-by: Bjorn Andersson 
Signed-off-by: Dmitry Baryshkov 
---
Changes in v3:
- Expanded the commit message and in-code comment based on feedback from
  Abhinav
- Fixed field masks for the affected register (Abhinav)
- Link to v2: 
https://lore.kernel.org/r/20240613-dp-phy-sel-v2-1-99af348c9...@linaro.org

Changes in v2:
- Removed entry from the catalog.
- Reworked the interface of dpu_hw_dp_phy_intf_sel(). Pass two entries
  for the PHYs instead of three entries.
- It seems the register isn't present on sdm845, enabled the callback
  only for DPU >= 5.x
- Added a comment regarding the data being platform-specific.
- Link to v1: 
https://lore.kernel.org/r/20230612221047.1886709-1-quic_bjora...@quicinc.com
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c | 39 +++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h | 18 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h   |  7 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c| 12 -
 4 files changed, 70 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
index 05e48cf4ec1d..a11fdbefc8d2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
@@ -231,8 +231,38 @@ static void dpu_hw_intf_audio_select(struct dpu_hw_mdp 
*mdp)
DPU_REG_WRITE(c, HDMI_DP_CORE_SELECT, 0x1);
 }
 
+static void dpu_hw_dp_phy_intf_sel(struct dpu_hw_mdp *mdp,
+  enum dpu_dp_phy_sel phys[2])
+{
+   struct dpu_hw_blk_reg_map *c = &mdp->hw;
+   unsigned int intf;
+   u32 sel = 0;
+
+   sel |= FIELD_PREP(MDP_DP_PHY_INTF_SEL_INTF0, phys[0]);
+   sel |= FIELD_PREP(MDP_DP_PHY_INTF_SEL_INTF1, phys[1]);
+
+   for (intf = 0; intf < 2; intf++) {
+   switch (phys[intf]) {
+   case DPU_DP_PHY_0:
+   sel |= FIELD_PREP(MDP_DP_PHY_INTF_SEL_PHY0, intf + 1);
+   break;
+   case DPU_DP_PHY_1:
+   sel |= FIELD_PREP(MDP_DP_PHY_INTF_SEL_PHY1, intf + 1);
+   break;
+   case DPU_DP_PHY_2:
+   sel |= FIELD_PREP(MDP_DP_PHY_INTF_SEL_PHY2, intf + 1);
+   break;
+   default:
+   /* ignore */
+   break;
+   }
+   }
+
+   DPU_REG_WRITE(c, MDP_DP_PHY_INTF_SEL, sel);
+}
+
 static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops,
-   unsigned long cap)
+   unsigned long cap, const struct dpu_mdss_version *mdss_rev)
 {
ops->setup_split_pipe = dpu_hw_setup_split_pipe;
ops->setup_clk_force_ctrl = dpu_hw_setup_clk_force_ctrl;
@@ -245,6 +275,9 @@ static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops,
 
ops->get_safe_status = dpu_hw_get_safe_status;
 
+   if (mdss_rev->core_major_ver >= 5)
+   ops->dp_phy_intf_sel = dpu_hw_dp_phy_intf_sel;
+
if (cap & BIT(DPU_MDP_AUDIO_SELECT))
ops->intf_audio_select = dpu_hw_intf_audio_select;
 }
@@ -252,7 +285,7 @@ static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops,
 struct dpu_hw_mdp *dpu_hw_mdptop_init(struct drm_device *dev,
  const struct dpu_mdp_cfg *cfg,
  void __iomem *addr,
- const struct dpu_mdss_cfg *m)
+ const struct dpu_mdss_version *mdss_rev)
 {
struct dpu_hw_mdp *mdp;
 
@@ -270,7 +303,7 @@ struct dpu_hw_mdp *dpu_hw_mdptop_init(struct drm_device 
*dev,
 * Assign ops
 */
mdp->caps = cfg;
-   _setup_mdp_ops(&mdp->ops, mdp->caps->features);
+   _setup_mdp_ops(&mdp->ops, mdp->caps->features, mdss_rev);
 
return mdp;
 }
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h
index 6f3dc98087df..3a17e63b851c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h
@@ -67,6 +67,13 @@ struct dpu_vsync_source_cfg {
u32 vsync_source;
 };
 
+enum dpu_dp_phy_sel {
+   DPU_DP_PHY_NONE,
+   DPU_DP

Re: [PATCH] drm/msm/a6xx: request memory region

2024-06-25 Thread Akhil P Oommen
On Tue, Jun 25, 2024 at 11:03:42AM -0700, Rob Clark wrote: > On Tue, Jun 25, 
2024 at 10:59 AM Akhil P Oommen  wrote:
> >
> > On Fri, Jun 21, 2024 at 02:09:58PM -0700, Rob Clark wrote:
> > > On Sat, Jun 8, 2024 at 8:44 AM Kiarash Hajian
> > >  wrote:
> > > >
> > > > The driver's memory regions are currently just ioremap()ed, but not
> > > > reserved through a request. That's not a bug, but having the request is
> > > > a little more robust.
> > > >
> > > > Implement the region-request through the corresponding managed
> > > > devres-function.
> > > >
> > > > Signed-off-by: Kiarash Hajian 
> > > > ---
> > > > Changes in v6:
> > > > -Fix compile error
> > > > -Link to v5: 
> > > > https://lore.kernel.org/all/20240607-memory-v1-1-8664f52fc...@gmail.com
> > > >
> > > > Changes in v5:
> > > > - Fix error hanlding problems.
> > > > - Link to v4: 
> > > > https://lore.kernel.org/r/20240512-msm-adreno-memory-region-v4-1-3881a6408...@gmail.com
> > > >
> > > > Changes in v4:
> > > > - Combine v3 commits into a singel commit
> > > > - Link to v3: 
> > > > https://lore.kernel.org/r/20240512-msm-adreno-memory-region-v3-0-0a728ad45...@gmail.com
> > > >
> > > > Changes in v3:
> > > > - Remove redundant devm_iounmap calls, relying on devres for 
> > > > automatic resource cleanup.
> > > >
> > > > Changes in v2:
> > > > - update the subject prefix to "drm/msm/a6xx:", to match the 
> > > > majority of other changes to this file.
> > > > ---
> > > >  drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 33 
> > > > +++--
> > > >  1 file changed, 11 insertions(+), 22 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
> > > > b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> > > > index 8bea8ef26f77..d26cc6254ef9 100644
> > > > --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> > > > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> > > > @@ -525,7 +525,7 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
> > > > bool pdc_in_aop = false;
> > > >
> > > > if (IS_ERR(pdcptr))
> > > > -   goto err;
> > > > +   return;
> > > >
> > > > if (adreno_is_a650(adreno_gpu) ||
> > > > adreno_is_a660_family(adreno_gpu) ||
> > > > @@ -541,7 +541,7 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
> > > > if (!pdc_in_aop) {
> > > > seqptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc_seq");
> > > > if (IS_ERR(seqptr))
> > > > -   goto err;
> > > > +   return;
> > > > }
> > > >
> > > > /* Disable SDE clock gating */
> > > > @@ -633,12 +633,6 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu 
> > > > *gmu)
> > > > wmb();
> > > >
> > > > a6xx_rpmh_stop(gmu);
> > > > -
> > > > -err:
> > > > -   if (!IS_ERR_OR_NULL(pdcptr))
> > > > -   iounmap(pdcptr);
> > > > -   if (!IS_ERR_OR_NULL(seqptr))
> > > > -   iounmap(seqptr);
> > > >  }
> > > >
> > > >  /*
> > > > @@ -1503,7 +1497,7 @@ static void __iomem *a6xx_gmu_get_mmio(struct 
> > > > platform_device *pdev,
> > > > return ERR_PTR(-EINVAL);
> > > > }
> > > >
> > > > -   ret = ioremap(res->start, resource_size(res));
> > > > +   ret = devm_ioremap_resource(&pdev->dev, res);
> > >
> > > So, this doesn't actually work, failing in __request_region_locked(),
> > > because the gmu region partially overlaps with the gpucc region (which
> > > is busy).  I think this is intentional, since gmu is controlling the
> > > gpu clocks, etc.  In particular REG_A6XX_GPU_CC_GX_GDSCR is in this
> > > overlapping region.  Maybe Akhil knows more about GMU.
> >
> > We don't really need to map gpucc region from driver on behalf of gmu.
> > Since we don't access any gpucc register from drm-msm driver, we can
> > update the range size to correct this. But due to backward compatibility
> > requirement with older dt, can we still enable region locking? I prefer
> > it if that is possible.
> 
> Actually, when I reduced the region size to not overlap with gpucc,
> the region is smaller than REG_A6XX_GPU_CC_GX_GDSCR * 4.
> 
> So I guess that register is actually part of gpucc?

Yes. It has *GPU_CC* in its name. :P

I just saw that we program this register on legacy a6xx targets to
ensure retention is really ON before collapsing gdsc. So we can't
avoid mapping gpucc region in legacy a6xx GPUs. That is unfortunate! 

-Akhil.

> 
> BR,
> -R
> 
> > FYI, kgsl accesses gpucc registers to ensure gdsc has collapsed. So
> > gpucc region has to be mapped by kgsl and that is reflected in the kgsl
> > device tree.
> >
> > -Akhil
> >
> > >
> > > BR,
> > > -R
> > >
> > > > if (!ret) {
> > > > DRM_DEV_ERROR(&pdev->dev, "Unable to map the %s 
> > > > registers\n", name);
> > > > return ERR_PTR(-EINVAL);
> > > > @@ -1613,13 +1607,13 @@ int a6xx_gmu_wrapper_init(struct a6xx_gpu 
> > > > *a6xx_gpu, struct device_node *n

Re: [PATCH RFC v2] drm/msm/dpu: Configure DP INTF/PHY selector

2024-06-25 Thread Abhinav Kumar




On 6/25/2024 1:20 PM, Dmitry Baryshkov wrote:

On Tue, 25 Jun 2024 at 22:28, Abhinav Kumar  wrote:




On 6/25/2024 12:26 PM, Abhinav Kumar wrote:



On 6/24/2024 6:39 PM, Abhinav Kumar wrote:



On 6/13/2024 4:17 AM, Dmitry Baryshkov wrote:

From: Bjorn Andersson 

Some platforms provides a mechanism for configuring the mapping between
(one or two) DisplayPort intfs and their PHYs.

In particular SC8180X provides this functionality, without a default
configuration, resulting in no connection between its two external
DisplayPort controllers and any PHYs.



I have to cross-check internally about what makes it mandatory to
program this only for sc8180xp. We were not programming this so far
for any chipset and this register is present all the way from sm8150
till xe10100 and all the chipsets do not have a correct default value
which makes me think whether this is required to be programmed.

Will update this thread once I do.



Ok, I checked more. The reason this is mandatory for sc8180xp is the
number of controllers is greater than number of PHYs needing this to be
programmed. On all other chipsets its a 1:1 mapping.



Correction, number of controllers is < number of PHYs.


Thanks, I'll c&p your explanation to the commit message if you don't mind.



Yes you can, pls go ahead.




I am fine with the change once the genmap comment is addressed.




Re: [PATCH RFC v2] drm/msm/dpu: Configure DP INTF/PHY selector

2024-06-25 Thread Dmitry Baryshkov
On Tue, 25 Jun 2024 at 22:28, Abhinav Kumar  wrote:
>
>
>
> On 6/25/2024 12:26 PM, Abhinav Kumar wrote:
> >
> >
> > On 6/24/2024 6:39 PM, Abhinav Kumar wrote:
> >>
> >>
> >> On 6/13/2024 4:17 AM, Dmitry Baryshkov wrote:
> >>> From: Bjorn Andersson 
> >>>
> >>> Some platforms provides a mechanism for configuring the mapping between
> >>> (one or two) DisplayPort intfs and their PHYs.
> >>>
> >>> In particular SC8180X provides this functionality, without a default
> >>> configuration, resulting in no connection between its two external
> >>> DisplayPort controllers and any PHYs.
> >>>
> >>
> >> I have to cross-check internally about what makes it mandatory to
> >> program this only for sc8180xp. We were not programming this so far
> >> for any chipset and this register is present all the way from sm8150
> >> till xe10100 and all the chipsets do not have a correct default value
> >> which makes me think whether this is required to be programmed.
> >>
> >> Will update this thread once I do.
> >>
> >
> > Ok, I checked more. The reason this is mandatory for sc8180xp is the
> > number of controllers is greater than number of PHYs needing this to be
> > programmed. On all other chipsets its a 1:1 mapping.
> >
>
> Correction, number of controllers is < number of PHYs.

Thanks, I'll c&p your explanation to the commit message if you don't mind.

>
> > I am fine with the change once the genmap comment is addressed.

-- 
With best wishes
Dmitry


Re: [PATCH v2 2/2] Revert "drm/msm/a6xx: Poll for GBIF unhalt status in hw_init"

2024-06-25 Thread Dmitry Baryshkov
On Tue, 25 Jun 2024 at 21:54, Konrad Dybcio  wrote:
>
> Commit c9707bcbd0f3 ("drm/msm/adreno: De-spaghettify the use of memory

ID is not present in next

> barriers") made some fixups relating to write arrival, ensuring that
> the GPU's memory interface has *really really really* been told to come
> out of reset. That in turn rendered the hacky commit being reverted no
> longer necessary.
>
> Get rid of it.
>
> This reverts commit b77532803d11f2b03efab2ebfd8c0061cd7f8b30.

b77532803d11 ("drm/msm/a6xx: Poll for GBIF unhalt status in hw_init")

>
> Signed-off-by: Konrad Dybcio 
> ---
>  drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 4 
>  1 file changed, 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
> b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> index 4083d0cad782..03e23eef5126 100644
> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> @@ -867,10 +867,6 @@ static int hw_init(struct msm_gpu *gpu)
> gpu_read(gpu, REG_A6XX_RBBM_GBIF_HALT);
> }
>
> -   /* Some GPUs are stubborn and take their sweet time to unhalt GBIF! */
> -   if (adreno_is_a7xx(adreno_gpu) && a6xx_has_gbif(adreno_gpu))
> -   spin_until(!gpu_read(gpu, REG_A6XX_GBIF_HALT_ACK));
> -
> gpu_write(gpu, REG_A6XX_RBBM_SECVID_TSB_CNTL, 0);
>
> if (adreno_is_a619_holi(adreno_gpu))
>
> --
> 2.45.2
>


-- 
With best wishes
Dmitry


[PATCH net-next v14 03/13] netdev: support binding dma-buf to netdevice

2024-06-25 Thread Mina Almasry
Add a netdev_dmabuf_binding struct which represents the
dma-buf-to-netdevice binding. The netlink API will bind the dma-buf to
rx queues on the netdevice. On the binding, the dma_buf_attach
& dma_buf_map_attachment will occur. The entries in the sg_table from
mapping will be inserted into a genpool to make it ready
for allocation.

The chunks in the genpool are owned by a dmabuf_chunk_owner struct which
holds the dma-buf offset of the base of the chunk and the dma_addr of
the chunk. Both are needed to use allocations that come from this chunk.

We create a new type that represents an allocation from the genpool:
net_iov. We setup the net_iov allocation size in the
genpool to PAGE_SIZE for simplicity: to match the PAGE_SIZE normally
allocated by the page pool and given to the drivers.

The user can unbind the dmabuf from the netdevice by closing the netlink
socket that established the binding. We do this so that the binding is
automatically unbound even if the userspace process crashes.

The binding and unbinding leaves an indicator in struct netdev_rx_queue
that the given queue is bound, but the binding doesn't take effect until
the driver actually reconfigures its queues, and re-initializes its page
pool.

The netdev_dmabuf_binding struct is refcounted, and releases its
resources only when all the refs are released.

Signed-off-by: Willem de Bruijn 
Signed-off-by: Kaiyuan Zhang 
Signed-off-by: Mina Almasry 
Reviewed-by: Pavel Begunkov  # excluding netlink

---

v13:
- Fixed a couple of places that still listed DMA_BIDIRECTIONAL (Pavel).
- Added reviewed-by from Pavel.

v11:
- Fix build error with CONFIG_DMA_SHARED_BUFFER &&
  !CONFIG_GENERIC_ALLOCATOR
- Rebased on top of no memory provider ops.

v10:
- Moved net_iov_dma_addr() to devmem.h and made it devmem specific
  helper (David).

v9: https://lore.kernel.org/all/20240403002053.2376017-5-almasrym...@google.com/
- Removed net_devmem_restart_rx_queues and put it in its own patch
  (David).

v8:
- move dmabuf_devmem_ops usage to later patch to avoid patch-by-patch
  build error.

v7:
- Use IS_ERR() instead of IS_ERR_OR_NULL() for the dma_buf_get() return
  value.
- Changes netdev_* naming in devmem.c to net_devmem_* (Yunsheng).
- DMA_BIDIRECTIONAL -> DMA_FROM_DEVICE (Yunsheng).
- Added a comment around recovering of the old rx queue in
  net_devmem_restart_rx_queue(), and added freeing of old_mem if the
  restart of the old queue fails. (Yunsheng).
- Use kernel-family sock-priv (Jakub).
- Put pp_memory_provider_params in netdev_rx_queue instead of the
  dma-buf specific binding (Pavel & David).
- Move queue management ops to queue_mgmt_ops instead of netdev_ops
  (Jakub).
- Remove excess whitespaces (Jakub).
- Use genlmsg_iput (Jakub).

v6:
- Validate rx queue index
- Refactor new functions into devmem.c (Pavel)

v5:
- Renamed page_pool_iov to net_iov, and moved that support to devmem.h
  or netmem.h.

v1:
- Introduce devmem.h instead of bloating netdevice.h (Jakub)
- ENOTSUPP -> EOPNOTSUPP (checkpatch.pl I think)
- Remove unneeded rcu protection for binding->list (rtnl protected)
- Removed extraneous err_binding_put: label.
- Removed dma_addr += len (Paolo).
- Don't override err on netdev_bind_dmabuf_to_queue failure.
- Rename devmem -> dmabuf (David).
- Add id to dmabuf binding (David/Stan).
- Fix missing xa_destroy bound_rq_list.
- Use queue api to reset bound RX queues (Jakub).
- Update netlink API for rx-queue type (tx/re) (Jakub).

RFC v3:
- Support multi rx-queue binding

---
 Documentation/netlink/specs/netdev.yaml |   4 +
 include/net/devmem.h| 111 +++
 include/net/netdev_rx_queue.h   |   2 +
 include/net/netmem.h|  10 +
 include/net/page_pool/types.h   |   6 +
 net/core/Makefile   |   2 +-
 net/core/dev.c  |   3 +
 net/core/devmem.c   | 252 
 net/core/netdev-genl-gen.c  |   4 +
 net/core/netdev-genl-gen.h  |   4 +
 net/core/netdev-genl.c  | 101 +-
 11 files changed, 496 insertions(+), 3 deletions(-)
 create mode 100644 include/net/devmem.h
 create mode 100644 net/core/devmem.c

diff --git a/Documentation/netlink/specs/netdev.yaml 
b/Documentation/netlink/specs/netdev.yaml
index 899ac0882a098..d6d7cb01c145c 100644
--- a/Documentation/netlink/specs/netdev.yaml
+++ b/Documentation/netlink/specs/netdev.yaml
@@ -673,6 +673,10 @@ operations:
 - tx-packets
 - tx-bytes
 
+kernel-family:
+  headers: [ "linux/list.h"]
+  sock-priv: struct list_head
+
 mcast-groups:
   list:
 -
diff --git a/include/net/devmem.h b/include/net/devmem.h
new file mode 100644
index 0..eaf3fd965d7a8
--- /dev/null
+++ b/include/net/devmem.h
@@ -0,0 +1,111 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Device memory TCP support
+ *
+ * Authors:Mina Almasry 
+ * Willem de Bruijn 
+ * Kaiyuan Zhang 
+ *
+ *

[PATCH net-next v14 08/13] net: support non paged skb frags

2024-06-25 Thread Mina Almasry
Make skb_frag_page() fail in the case where the frag is not backed
by a page, and fix its relevant callers to handle this case.

Signed-off-by: Mina Almasry 


---

v10:
- Fixed newly generated kdoc warnings found by patchwork. While we're
  at it, fix the Return section of the functions I touched.

v6:
- Rebased on top of the merged netmem changes.

Changes in v1:
- Fix illegal_highdma() (Yunsheng).
- Rework napi_pp_put_page() slightly to reduce code churn (Willem).

---
 include/linux/skbuff.h | 42 +-
 include/linux/skbuff_ref.h |  9 
 net/core/dev.c |  3 ++-
 net/core/gro.c |  3 ++-
 net/core/skbuff.c  | 11 ++
 net/ipv4/esp4.c|  3 ++-
 net/ipv4/tcp.c |  3 +++
 net/ipv6/esp6.c|  3 ++-
 8 files changed, 67 insertions(+), 10 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index f4cda3fbdb75a..3cd06eb3a44da 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -3512,21 +3512,58 @@ static inline void skb_frag_off_copy(skb_frag_t *fragto,
fragto->offset = fragfrom->offset;
 }
 
+/* Return: true if the skb_frag contains a net_iov. */
+static inline bool skb_frag_is_net_iov(const skb_frag_t *frag)
+{
+   return netmem_is_net_iov(frag->netmem);
+}
+
+/**
+ * skb_frag_net_iov - retrieve the net_iov referred to by fragment
+ * @frag: the fragment
+ *
+ * Return: the &struct net_iov associated with @frag. Returns NULL if this
+ * frag has no associated net_iov.
+ */
+static inline struct net_iov *skb_frag_net_iov(const skb_frag_t *frag)
+{
+   if (!skb_frag_is_net_iov(frag))
+   return NULL;
+
+   return netmem_to_net_iov(frag->netmem);
+}
+
 /**
  * skb_frag_page - retrieve the page referred to by a paged fragment
  * @frag: the paged fragment
  *
- * Returns the &struct page associated with @frag.
+ * Return: the &struct page associated with @frag. Returns NULL if this frag
+ * has no associated page.
  */
 static inline struct page *skb_frag_page(const skb_frag_t *frag)
 {
+   if (skb_frag_is_net_iov(frag))
+   return NULL;
+
return netmem_to_page(frag->netmem);
 }
 
+/**
+ * skb_frag_netmem - retrieve the netmem referred to by a fragment
+ * @frag: the fragment
+ *
+ * Return: the &netmem_ref associated with @frag.
+ */
+static inline netmem_ref skb_frag_netmem(const skb_frag_t *frag)
+{
+   return frag->netmem;
+}
+
 int skb_pp_cow_data(struct page_pool *pool, struct sk_buff **pskb,
unsigned int headroom);
 int skb_cow_data_for_xdp(struct page_pool *pool, struct sk_buff **pskb,
 struct bpf_prog *prog);
+
 /**
  * skb_frag_address - gets the address of the data contained in a paged 
fragment
  * @frag: the paged fragment buffer
@@ -3536,6 +3573,9 @@ int skb_cow_data_for_xdp(struct page_pool *pool, struct 
sk_buff **pskb,
  */
 static inline void *skb_frag_address(const skb_frag_t *frag)
 {
+   if (!skb_frag_page(frag))
+   return NULL;
+
return page_address(skb_frag_page(frag)) + skb_frag_off(frag);
 }
 
diff --git a/include/linux/skbuff_ref.h b/include/linux/skbuff_ref.h
index 16c241a234728..0f3c58007488a 100644
--- a/include/linux/skbuff_ref.h
+++ b/include/linux/skbuff_ref.h
@@ -34,14 +34,13 @@ static inline void skb_frag_ref(struct sk_buff *skb, int f)
 
 bool napi_pp_put_page(netmem_ref netmem);
 
-static inline void
-skb_page_unref(struct page *page, bool recycle)
+static inline void skb_page_unref(netmem_ref netmem, bool recycle)
 {
 #ifdef CONFIG_PAGE_POOL
-   if (recycle && napi_pp_put_page(page_to_netmem(page)))
+   if (recycle && napi_pp_put_page(netmem))
return;
 #endif
-   put_page(page);
+   put_page(netmem_to_page(netmem));
 }
 
 /**
@@ -54,7 +53,7 @@ skb_page_unref(struct page *page, bool recycle)
  */
 static inline void __skb_frag_unref(skb_frag_t *frag, bool recycle)
 {
-   skb_page_unref(skb_frag_page(frag), recycle);
+   skb_page_unref(skb_frag_netmem(frag), recycle);
 }
 
 /**
diff --git a/net/core/dev.c b/net/core/dev.c
index 85255b8e34a45..65ea83e754c90 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3434,8 +3434,9 @@ static int illegal_highdma(struct net_device *dev, struct 
sk_buff *skb)
if (!(dev->features & NETIF_F_HIGHDMA)) {
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+   struct page *page = skb_frag_page(frag);
 
-   if (PageHighMem(skb_frag_page(frag)))
+   if (page && PageHighMem(page))
return 1;
}
}
diff --git a/net/core/gro.c b/net/core/gro.c
index b3b43de1a6502..26f09c3e830b7 100644
--- a/net/core/gro.c
+++ b/net/core/gro.c
@@ -408,7 +408,8 @@ static inline void skb_gro_reset_offset(struct sk_buff 
*skb, u32 nhoff)
pinfo = 

[PATCH net-next v14 13/13] selftests: add ncdevmem, netcat for devmem TCP

2024-06-25 Thread Mina Almasry
ncdevmem is a devmem TCP netcat. It works similarly to netcat, but it
sends and receives data using the devmem TCP APIs. It uses udmabuf as
the dmabuf provider. It is compatible with a regular netcat running on
a peer, or a ncdevmem running on a peer.

In addition to normal netcat support, ncdevmem has a validation mode,
where it sends a specific pattern and validates this pattern on the
receiver side to ensure data integrity.

Suggested-by: Stanislav Fomichev 
Signed-off-by: Mina Almasry 

---
v9: 
https://lore.kernel.org/netdev/20240403002053.2376017-15-almasrym...@google.com/
- Remove unused nic_pci_addr entry (Cong).

v6:
- Updated to bind 8 queues.
- Added RSS configuration.
- Added some more tests for the netlink API.

Changes in v1:
- Many more general cleanups (Willem).
- Removed driver reset (Jakub).
- Removed hardcoded if index (Paolo).

RFC v2:
- General cleanups (Willem).

---
 tools/testing/selftests/net/.gitignore |   1 +
 tools/testing/selftests/net/Makefile   |   5 +
 tools/testing/selftests/net/ncdevmem.c | 542 +
 3 files changed, 548 insertions(+)
 create mode 100644 tools/testing/selftests/net/ncdevmem.c

diff --git a/tools/testing/selftests/net/.gitignore 
b/tools/testing/selftests/net/.gitignore
index 49a56eb5d0368..9cd3c99c6e5d4 100644
--- a/tools/testing/selftests/net/.gitignore
+++ b/tools/testing/selftests/net/.gitignore
@@ -17,6 +17,7 @@ ipv6_flowlabel
 ipv6_flowlabel_mgr
 log.txt
 msg_zerocopy
+ncdevmem
 nettest
 psock_fanout
 psock_snd
diff --git a/tools/testing/selftests/net/Makefile 
b/tools/testing/selftests/net/Makefile
index bc3925200637c..e693a39df4b4f 100644
--- a/tools/testing/selftests/net/Makefile
+++ b/tools/testing/selftests/net/Makefile
@@ -5,6 +5,10 @@ CFLAGS =  -Wall -Wl,--no-as-needed -O2 -g
 CFLAGS += -I../../../../usr/include/ $(KHDR_INCLUDES)
 # Additional include paths needed by kselftest.h
 CFLAGS += -I../
+CFLAGS += -I../../../net/ynl/generated/
+CFLAGS += -I../../../net/ynl/lib/
+
+LDLIBS += ../../../net/ynl/lib/ynl.a ../../../net/ynl/generated/protos.a
 
 TEST_PROGS := run_netsocktests run_afpackettests test_bpf.sh netdevice.sh \
  rtnetlink.sh xfrm_policy.sh test_blackhole_dev.sh
@@ -94,6 +98,7 @@ TEST_PROGS += fdb_flush.sh
 TEST_PROGS += fq_band_pktlimit.sh
 TEST_PROGS += vlan_hw_filter.sh
 TEST_PROGS += bpf_offload.py
+TEST_GEN_FILES += ncdevmem
 
 TEST_FILES := settings
 TEST_FILES += in_netns.sh lib.sh net_helper.sh setup_loopback.sh setup_veth.sh
diff --git a/tools/testing/selftests/net/ncdevmem.c 
b/tools/testing/selftests/net/ncdevmem.c
new file mode 100644
index 0..e00255e54f77b
--- /dev/null
+++ b/tools/testing/selftests/net/ncdevmem.c
@@ -0,0 +1,542 @@
+// SPDX-License-Identifier: GPL-2.0
+#define _GNU_SOURCE
+#define __EXPORTED_HEADERS__
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#define __iovec_defined
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "netdev-user.h"
+#include 
+
+#define PAGE_SHIFT 12
+#define TEST_PREFIX "ncdevmem"
+#define NUM_PAGES 16000
+
+#ifndef MSG_SOCK_DEVMEM
+#define MSG_SOCK_DEVMEM 0x200
+#endif
+
+/*
+ * tcpdevmem netcat. Works similarly to netcat but does device memory TCP
+ * instead of regular TCP. Uses udmabuf to mock a dmabuf provider.
+ *
+ * Usage:
+ *
+ * On server:
+ * ncdevmem -s  -c  -f eth1 -d 3 -n :06:00.0 -l \
+ * -p 5201 -v 7
+ *
+ * On client:
+ * yes $(echo -e \\x01\\x02\\x03\\x04\\x05\\x06) | \
+ * tr \\n \\0 | \
+ * head -c 5G | \
+ * nc  5201 -p 5201
+ *
+ * Note this is compatible with regular netcat. i.e. the sender or receiver can
+ * be replaced with regular netcat to test the RX or TX path in isolation.
+ */
+
+static char *server_ip = "192.168.1.4";
+static char *client_ip = "192.168.1.2";
+static char *port = "5201";
+static size_t do_validation;
+static int start_queue = 8;
+static int num_queues = 8;
+static char *ifname = "eth1";
+static unsigned int ifindex = 3;
+static unsigned int iterations;
+static unsigned int dmabuf_id;
+
+void print_bytes(void *ptr, size_t size)
+{
+   unsigned char *p = ptr;
+   int i;
+
+   for (i = 0; i < size; i++)
+   printf("%02hhX ", p[i]);
+   printf("\n");
+}
+
+void print_nonzero_bytes(void *ptr, size_t size)
+{
+   unsigned char *p = ptr;
+   unsigned int i;
+
+   for (i = 0; i < size; i++)
+   putchar(p[i]);
+   printf("\n");
+}
+
+void validate_buffer(void *line, size_t size)
+{
+   static unsigned char seed = 1;
+   unsigned char *ptr = line;
+   int errors = 0;
+   size_t i;
+
+   for (i = 0; i < size; i++) {
+   if (ptr[i] != seed) {
+   fprintf(stderr,
+   "Failed validation: expected=%u, actual

[PATCH net-next v14 10/13] tcp: RX path for devmem TCP

2024-06-25 Thread Mina Almasry
In tcp_recvmsg_locked(), detect if the skb being received by the user
is a devmem skb. In this case - if the user provided the MSG_SOCK_DEVMEM
flag - pass it to tcp_recvmsg_devmem() for custom handling.

tcp_recvmsg_devmem() copies any data in the skb header to the linear
buffer, and returns a cmsg to the user indicating the number of bytes
returned in the linear buffer.

tcp_recvmsg_devmem() then loops over the unaccessible devmem skb frags,
and returns to the user a cmsg_devmem indicating the location of the
data in the dmabuf device memory. cmsg_devmem contains this information:

1. the offset into the dmabuf where the payload starts. 'frag_offset'.
2. the size of the frag. 'frag_size'.
3. an opaque token 'frag_token' to return to the kernel when the buffer
is to be released.

The pages awaiting freeing are stored in the newly added
sk->sk_user_frags, and each page passed to userspace is get_page()'d.
This reference is dropped once the userspace indicates that it is
done reading this page.  All pages are released when the socket is
destroyed.

Signed-off-by: Willem de Bruijn 
Signed-off-by: Kaiyuan Zhang 
Signed-off-by: Mina Almasry 

---

v13:
- Refactored user frags cleanup into a common function to avoid
  __maybe_unused. (Pavel)
- change to offset = 0 for some improved clarity.

v11:
- Refactor to common function te remove conditional lock sparse warning
  (Paolo)

v7:
- Updated the SO_DEVMEM_* uapi to use the next available entries (Arnd).
- Updated dmabuf_cmsg struct to be __u64 padded (Arnd).
- Squashed fix from Eric to initialize sk_user_frags for passive
  sockets (Eric).

v6
- skb->dmabuf -> skb->readable (Pavel)
- Fixed asm definitions of SO_DEVMEM_LINEAR/SO_DEVMEM_DMABUF not found
  on some archs.
- Squashed in locking optimizations from eduma...@google.com. With this
  change we lock the xarray once per per tcp_recvmsg_dmabuf() rather
  than once per frag in xa_alloc().

Changes in v1:
- Added dmabuf_id to dmabuf_cmsg (David/Stan).
- Devmem -> dmabuf (David).
- Change tcp_recvmsg_dmabuf() check to skb->dmabuf (Paolo).
- Use __skb_frag_ref() & napi_pp_put_page() for refcounting (Yunsheng).

RFC v3:
- Fixed issue with put_cmsg() failing silently.

---
 arch/alpha/include/uapi/asm/socket.h  |   5 +
 arch/mips/include/uapi/asm/socket.h   |   5 +
 arch/parisc/include/uapi/asm/socket.h |   5 +
 arch/sparc/include/uapi/asm/socket.h  |   5 +
 include/linux/socket.h|   1 +
 include/net/netmem.h  |  13 ++
 include/net/sock.h|   2 +
 include/uapi/asm-generic/socket.h |   5 +
 include/uapi/linux/uio.h  |  13 ++
 net/ipv4/tcp.c| 255 +-
 net/ipv4/tcp_ipv4.c   |  16 ++
 net/ipv4/tcp_minisocks.c  |   2 +
 12 files changed, 322 insertions(+), 5 deletions(-)

diff --git a/arch/alpha/include/uapi/asm/socket.h 
b/arch/alpha/include/uapi/asm/socket.h
index e94f621903fee..ef4656a41058a 100644
--- a/arch/alpha/include/uapi/asm/socket.h
+++ b/arch/alpha/include/uapi/asm/socket.h
@@ -140,6 +140,11 @@
 #define SO_PASSPIDFD   76
 #define SO_PEERPIDFD   77
 
+#define SO_DEVMEM_LINEAR   78
+#define SCM_DEVMEM_LINEAR  SO_DEVMEM_LINEAR
+#define SO_DEVMEM_DMABUF   79
+#define SCM_DEVMEM_DMABUF  SO_DEVMEM_DMABUF
+
 #if !defined(__KERNEL__)
 
 #if __BITS_PER_LONG == 64
diff --git a/arch/mips/include/uapi/asm/socket.h 
b/arch/mips/include/uapi/asm/socket.h
index 60ebaed28a4ca..414807d55e33f 100644
--- a/arch/mips/include/uapi/asm/socket.h
+++ b/arch/mips/include/uapi/asm/socket.h
@@ -151,6 +151,11 @@
 #define SO_PASSPIDFD   76
 #define SO_PEERPIDFD   77
 
+#define SO_DEVMEM_LINEAR   78
+#define SCM_DEVMEM_LINEAR  SO_DEVMEM_LINEAR
+#define SO_DEVMEM_DMABUF   79
+#define SCM_DEVMEM_DMABUF  SO_DEVMEM_DMABUF
+
 #if !defined(__KERNEL__)
 
 #if __BITS_PER_LONG == 64
diff --git a/arch/parisc/include/uapi/asm/socket.h 
b/arch/parisc/include/uapi/asm/socket.h
index be264c2b1a117..2b817efd45444 100644
--- a/arch/parisc/include/uapi/asm/socket.h
+++ b/arch/parisc/include/uapi/asm/socket.h
@@ -132,6 +132,11 @@
 #define SO_PASSPIDFD   0x404A
 #define SO_PEERPIDFD   0x404B
 
+#define SO_DEVMEM_LINEAR   78
+#define SCM_DEVMEM_LINEAR  SO_DEVMEM_LINEAR
+#define SO_DEVMEM_DMABUF   79
+#define SCM_DEVMEM_DMABUF  SO_DEVMEM_DMABUF
+
 #if !defined(__KERNEL__)
 
 #if __BITS_PER_LONG == 64
diff --git a/arch/sparc/include/uapi/asm/socket.h 
b/arch/sparc/include/uapi/asm/socket.h
index 682da3714686c..00248fc689773 100644
--- a/arch/sparc/include/uapi/asm/socket.h
+++ b/arch/sparc/include/uapi/asm/socket.h
@@ -133,6 +133,11 @@
 #define SO_PASSPIDFD 0x0055
 #define SO_PEERPIDFD 0x0056
 
+#define SO_DEVMEM_LINEAR 0x0057
+#define SCM_DEVMEM_LINEARSO_DEVMEM_LINEAR
+#define SO_DEVMEM_DMABUF 0x0058
+#define SCM_DEVMEM_DMABUFSO_DEVMEM_DMABUF
+
 #if !defined(__KERNEL__

[PATCH net-next v14 07/13] memory-provider: dmabuf devmem memory provider

2024-06-25 Thread Mina Almasry
Implement a memory provider that allocates dmabuf devmem in the form of
net_iov.

The provider receives a reference to the struct netdev_dmabuf_binding
via the pool->mp_priv pointer. The driver needs to set this pointer for
the provider in the net_iov.

The provider obtains a reference on the netdev_dmabuf_binding which
guarantees the binding and the underlying mapping remains alive until
the provider is destroyed.

Usage of PP_FLAG_DMA_MAP is required for this memory provide such that
the page_pool can provide the driver with the dma-addrs of the devmem.

Support for PP_FLAG_DMA_SYNC_DEV is omitted for simplicity & p.order !=
0.

Signed-off-by: Willem de Bruijn 
Signed-off-by: Kaiyuan Zhang 
Signed-off-by: Mina Almasry 
Reviewed-by: Pavel Begunkov 

---

v13:
- Return on warning (Pavel).
- Fixed pool->recycle_stats not being freed on error (Pavel).
- Applied reviewed-by from Pavel.

v11:
- Rebase to not use the ops. (Christoph)

v8:
- Use skb_frag_size instead of frag->bv_len to fix patch-by-patch build
  error

v6:
- refactor new memory provider functions into net/core/devmem.c (Pavel)

v2:
- Disable devmem for p.order != 0

v1:
- static_branch check in page_is_page_pool_iov() (Willem & Paolo).
- PP_DEVMEM -> PP_IOV (David).
- Require PP_FLAG_DMA_MAP (Jakub).

---
 include/net/mp_dmabuf_devmem.h  | 44 +++
 include/net/netmem.h| 15 +++
 include/net/page_pool/helpers.h | 22 ++
 include/net/page_pool/types.h   |  2 +
 net/core/devmem.c   | 77 +
 net/core/page_pool.c| 74 ---
 6 files changed, 208 insertions(+), 26 deletions(-)
 create mode 100644 include/net/mp_dmabuf_devmem.h

diff --git a/include/net/mp_dmabuf_devmem.h b/include/net/mp_dmabuf_devmem.h
new file mode 100644
index 0..300a2356eed00
--- /dev/null
+++ b/include/net/mp_dmabuf_devmem.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Dmabuf device memory provider.
+ *
+ * Authors:Mina Almasry 
+ *
+ */
+#ifndef _NET_MP_DMABUF_DEVMEM_H
+#define _NET_MP_DMABUF_DEVMEM_H
+
+#include 
+
+#if defined(CONFIG_DMA_SHARED_BUFFER) && defined(CONFIG_GENERIC_ALLOCATOR)
+int mp_dmabuf_devmem_init(struct page_pool *pool);
+
+netmem_ref mp_dmabuf_devmem_alloc_netmems(struct page_pool *pool, gfp_t gfp);
+
+void mp_dmabuf_devmem_destroy(struct page_pool *pool);
+
+bool mp_dmabuf_devmem_release_page(struct page_pool *pool, netmem_ref netmem);
+#else
+static inline int mp_dmabuf_devmem_init(struct page_pool *pool)
+{
+   return -EOPNOTSUPP;
+}
+
+static inline netmem_ref mp_dmabuf_devmem_alloc_netmems(struct page_pool *pool,
+   gfp_t gfp)
+{
+   return 0;
+}
+
+static inline void mp_dmabuf_devmem_destroy(struct page_pool *pool)
+{
+}
+
+static inline bool mp_dmabuf_devmem_release_page(struct page_pool *pool,
+netmem_ref netmem)
+{
+   return false;
+}
+#endif
+
+#endif /* _NET_MP_DMABUF_DEVMEM_H */
diff --git a/include/net/netmem.h b/include/net/netmem.h
index 35ad237fdf29e..7c28d6fac6242 100644
--- a/include/net/netmem.h
+++ b/include/net/netmem.h
@@ -100,6 +100,21 @@ static inline struct page *netmem_to_page(netmem_ref 
netmem)
return (__force struct page *)netmem;
 }
 
+static inline struct net_iov *netmem_to_net_iov(netmem_ref netmem)
+{
+   if (netmem_is_net_iov(netmem))
+   return (struct net_iov *)((__force unsigned long)netmem &
+ ~NET_IOV);
+
+   DEBUG_NET_WARN_ON_ONCE(true);
+   return NULL;
+}
+
+static inline netmem_ref net_iov_to_netmem(struct net_iov *niov)
+{
+   return (__force netmem_ref)((unsigned long)niov | NET_IOV);
+}
+
 static inline netmem_ref page_to_netmem(struct page *page)
 {
return (__force netmem_ref)page;
diff --git a/include/net/page_pool/helpers.h b/include/net/page_pool/helpers.h
index 0c95594ce8e1c..8058cb13e695c 100644
--- a/include/net/page_pool/helpers.h
+++ b/include/net/page_pool/helpers.h
@@ -476,4 +476,26 @@ static inline void page_pool_nid_changed(struct page_pool 
*pool, int new_nid)
page_pool_update_nid(pool, new_nid);
 }
 
+static inline void page_pool_set_pp_info(struct page_pool *pool,
+netmem_ref netmem)
+{
+   netmem_set_pp(netmem, pool);
+   netmem_or_pp_magic(netmem, PP_SIGNATURE);
+
+   /* Ensuring all pages have been split into one fragment initially:
+* page_pool_set_pp_info() is only called once for every page when it
+* is allocated from the page allocator and page_pool_fragment_page()
+* is dirtying the same cache line as the page->pp_magic above, so
+* the overhead is negligible.
+*/
+   page_pool_fragment_netmem(netmem, 1);
+   if (pool->has_init_callback)
+   pool->slow.init_callback(netmem, pool->slow.init_arg);
+}
+
+static 

[PATCH net-next v14 09/13] net: add support for skbs with unreadable frags

2024-06-25 Thread Mina Almasry
For device memory TCP, we expect the skb headers to be available in host
memory for access, and we expect the skb frags to be in device memory
and unaccessible to the host. We expect there to be no mixing and
matching of device memory frags (unaccessible) with host memory frags
(accessible) in the same skb.

Add a skb->devmem flag which indicates whether the frags in this skb
are device memory frags or not.

__skb_fill_netmem_desc() now checks frags added to skbs for net_iov,
and marks the skb as skb->devmem accordingly.

Add checks through the network stack to avoid accessing the frags of
devmem skbs and avoid coalescing devmem skbs with non devmem skbs.

Signed-off-by: Willem de Bruijn 
Signed-off-by: Kaiyuan Zhang 
Signed-off-by: Mina Almasry 


---

v11:
- drop excessive checks for frag 0 pull (Paolo)

v9: 
https://lore.kernel.org/netdev/20240403002053.2376017-11-almasrym...@google.com/
- change skb->readable to skb->unreadable (Pavel/David).

skb->readable was very complicated, because by default skbs are readable
so the flag needed to be set to true in all code paths where new skbs
were created or cloned. Forgetting to set skb->readable=true in some
paths caused crashes.

Flip it to skb->unreadable so that the default 0 value works well, and
we only need to set it to true when we add unreadable frags.

v6
- skb->dmabuf -> skb->readable (Pavel). Pavel's original suggestion was
  to remove the skb->dmabuf flag entirely, but when I looked into it
  closely, I found the issue that if we remove the flag we have to
  dereference the shinfo(skb) pointer to obtain the first frag, which
  can cause a performance regression if it dirties the cache line when
  the shinfo(skb) was not really needed. Instead, I converted the
  skb->dmabuf flag into a generic skb->readable flag which can be
  re-used by io_uring.

Changes in v1:
- Rename devmem -> dmabuf (David).
- Flip skb_frags_not_readable (Jakub).

---
 include/linux/skbuff.h | 19 +++--
 include/net/tcp.h  |  5 +++--
 net/core/datagram.c|  6 ++
 net/core/skbuff.c  | 48 --
 net/ipv4/tcp.c |  3 +++
 net/ipv4/tcp_input.c   | 13 +---
 net/ipv4/tcp_output.c  |  5 -
 net/packet/af_packet.c |  4 ++--
 8 files changed, 91 insertions(+), 12 deletions(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 3cd06eb3a44da..5438434b61300 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -827,6 +827,8 @@ enum skb_tstamp_type {
  * @csum_level: indicates the number of consecutive checksums found in
  * the packet minus one that have been verified as
  * CHECKSUM_UNNECESSARY (max 3)
+ * @unreadable: indicates that at least 1 of the fragments in this skb is
+ * unreadable.
  * @dst_pending_confirm: need to confirm neighbour
  * @decrypted: Decrypted SKB
  * @slow_gro: state present at GRO time, slower prepare step required
@@ -1008,7 +1010,7 @@ struct sk_buff {
 #if IS_ENABLED(CONFIG_IP_SCTP)
__u8csum_not_inet:1;
 #endif
-
+   __u8unreadable:1;
 #if defined(CONFIG_NET_SCHED) || defined(CONFIG_NET_XGRESS)
__u16   tc_index;   /* traffic control index */
 #endif
@@ -1820,6 +1822,12 @@ static inline void skb_zcopy_downgrade_managed(struct 
sk_buff *skb)
__skb_zcopy_downgrade_managed(skb);
 }
 
+/* Return true if frags in this skb are readable by the host. */
+static inline bool skb_frags_readable(const struct sk_buff *skb)
+{
+   return !skb->unreadable;
+}
+
 static inline void skb_mark_not_on_list(struct sk_buff *skb)
 {
skb->next = NULL;
@@ -2536,10 +2544,17 @@ static inline void skb_len_add(struct sk_buff *skb, int 
delta)
 static inline void __skb_fill_netmem_desc(struct sk_buff *skb, int i,
  netmem_ref netmem, int off, int size)
 {
-   struct page *page = netmem_to_page(netmem);
+   struct page *page;
 
__skb_fill_netmem_desc_noacc(skb_shinfo(skb), i, netmem, off, size);
 
+   if (netmem_is_net_iov(netmem)) {
+   skb->unreadable = true;
+   return;
+   }
+
+   page = netmem_to_page(netmem);
+
/* Propagate page pfmemalloc to the skb if we can. The problem is
 * that not all callers have unique ownership of the page but rely
 * on page_is_pfmemalloc doing the right thing(tm).
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 2aac11e7e1cc5..e8f6e602c2ad4 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1060,7 +1060,7 @@ static inline int tcp_skb_mss(const struct sk_buff *skb)
 
 static inline bool tcp_skb_can_collapse_to(const struct sk_buff *skb)
 {
-   return likely(!TCP_SKB_CB(skb)->eor);
+   return likely(!TCP_SKB_CB(skb)->eor && skb_frags_readable(skb));
 }
 
 static inline bool tcp_skb_can_collapse(const struct sk_buff *to,
@@ -1069,7 +1069,8 @@ static 

[PATCH net-next v14 12/13] net: add devmem TCP documentation

2024-06-25 Thread Mina Almasry
Add documentation outlining the usage and details of devmem TCP.

Signed-off-by: Mina Almasry 
Reviewed-by: Bagas Sanjaya 

---

v9: 
https://lore.kernel.org/netdev/20240403002053.2376017-14-almasrym...@google.com/
- Bagas doc suggestions.

v8:
- Applied docs suggestions (Randy). Thanks!

v7:
- Applied docs suggestions (Jakub).

v2:

- Missing spdx (simon)
- add to index.rst (simon)

---
 Documentation/networking/devmem.rst | 258 
 Documentation/networking/index.rst  |   1 +
 2 files changed, 259 insertions(+)
 create mode 100644 Documentation/networking/devmem.rst

diff --git a/Documentation/networking/devmem.rst 
b/Documentation/networking/devmem.rst
new file mode 100644
index 0..f32acfd62075d
--- /dev/null
+++ b/Documentation/networking/devmem.rst
@@ -0,0 +1,258 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=
+Device Memory TCP
+=
+
+
+Intro
+=
+
+Device memory TCP (devmem TCP) enables receiving data directly into device
+memory (dmabuf). The feature is currently implemented for TCP sockets.
+
+
+Opportunity
+---
+
+A large number of data transfers have device memory as the source and/or
+destination. Accelerators drastically increased the prevalence of such
+transfers.  Some examples include:
+
+- Distributed training, where ML accelerators, such as GPUs on different hosts,
+  exchange data.
+
+- Distributed raw block storage applications transfer large amounts of data 
with
+  remote SSDs. Much of this data does not require host processing.
+
+Typically the Device-to-Device data transfers in the network are implemented as
+the following low-level operations: Device-to-Host copy, Host-to-Host network
+transfer, and Host-to-Device copy.
+
+The flow involving host copies is suboptimal, especially for bulk data 
transfers,
+and can put significant strains on system resources such as host memory
+bandwidth and PCIe bandwidth.
+
+Devmem TCP optimizes this use case by implementing socket APIs that enable
+the user to receive incoming network packets directly into device memory.
+
+Packet payloads go directly from the NIC to device memory.
+
+Packet headers go to host memory and are processed by the TCP/IP stack
+normally. The NIC must support header split to achieve this.
+
+Advantages:
+
+- Alleviate host memory bandwidth pressure, compared to existing
+  network-transfer + device-copy semantics.
+
+- Alleviate PCIe bandwidth pressure, by limiting data transfer to the lowest
+  level of the PCIe tree, compared to the traditional path which sends data
+  through the root complex.
+
+
+More Info
+-
+
+  slides, video
+https://netdevconf.org/0x17/sessions/talk/device-memory-tcp.html
+
+  patchset
+[RFC PATCH v6 00/12] Device Memory TCP
+
https://lore.kernel.org/netdev/20240305020153.2787423-1-almasrym...@google.com/
+
+
+Interface
+=
+
+Example
+---
+
+tools/testing/selftests/net/ncdevmem.c:do_server shows an example of setting up
+the RX path of this API.
+
+NIC Setup
+-
+
+Header split, flow steering, & RSS are required features for devmem TCP.
+
+Header split is used to split incoming packets into a header buffer in host
+memory, and a payload buffer in device memory.
+
+Flow steering & RSS are used to ensure that only flows targeting devmem land on
+an RX queue bound to devmem.
+
+Enable header split & flow steering::
+
+   # enable header split
+   ethtool -G eth1 tcp-data-split on
+
+
+   # enable flow steering
+   ethtool -K eth1 ntuple on
+
+Configure RSS to steer all traffic away from the target RX queue (queue 15 in
+this example)::
+
+   ethtool --set-rxfh-indir eth1 equal 15
+
+
+The user must bind a dmabuf to any number of RX queues on a given NIC using
+the netlink API::
+
+   /* Bind dmabuf to NIC RX queue 15 */
+   struct netdev_queue *queues;
+   queues = malloc(sizeof(*queues) * 1);
+
+   queues[0]._present.type = 1;
+   queues[0]._present.idx = 1;
+   queues[0].type = NETDEV_RX_QUEUE_TYPE_RX;
+   queues[0].idx = 15;
+
+   *ys = ynl_sock_create(&ynl_netdev_family, &yerr);
+
+   req = netdev_bind_rx_req_alloc();
+   netdev_bind_rx_req_set_ifindex(req, 1 /* ifindex */);
+   netdev_bind_rx_req_set_dmabuf_fd(req, dmabuf_fd);
+   __netdev_bind_rx_req_set_queues(req, queues, n_queue_index);
+
+   rsp = netdev_bind_rx(*ys, req);
+
+   dmabuf_id = rsp->dmabuf_id;
+
+
+The netlink API returns a dmabuf_id: a unique ID that refers to this dmabuf
+that has been bound.
+
+Socket Setup
+
+
+The socket must be flow steered to the dmabuf bound RX queue::
+
+   ethtool -N eth1 flow-type tcp4 ... queue 15,
+
+
+Receiving data
+--
+
+The user application must signal to the kernel that it is capable of receiving
+devmem data by passing the MSG_SOCK_DEVMEM flag to recvmsg::
+
+   ret = recvmsg(fd, &msg, MSG_SOCK_DEVMEM);
+
+Applications that do not specify the MSG_SOCK_DEVMEM flag will re

[PATCH net-next v14 11/13] net: add SO_DEVMEM_DONTNEED setsockopt to release RX frags

2024-06-25 Thread Mina Almasry
Add an interface for the user to notify the kernel that it is done
reading the devmem dmabuf frags returned as cmsg. The kernel will
drop the reference on the frags to make them available for reuse.

Signed-off-by: Willem de Bruijn 
Signed-off-by: Kaiyuan Zhang 
Signed-off-by: Mina Almasry 

---

v10:
- Fix leak of tokens (Nikolay).

v7:
- Updated SO_DEVMEM_* uapi to use the next available entry (Arnd).

v6:
- Squash in locking optimizations from eduma...@google.com. With his
  changes we lock the xarray once per sock_devmem_dontneed operation
  rather than once per frag.

Changes in v1:
- devmemtoken -> dmabuf_token (David).
- Use napi_pp_put_page() for refcounting (Yunsheng).
- Fix build error with missing socket options on other asms.

---
 arch/alpha/include/uapi/asm/socket.h  |  1 +
 arch/mips/include/uapi/asm/socket.h   |  1 +
 arch/parisc/include/uapi/asm/socket.h |  1 +
 arch/sparc/include/uapi/asm/socket.h  |  1 +
 include/uapi/asm-generic/socket.h |  1 +
 include/uapi/linux/uio.h  |  4 ++
 net/core/sock.c   | 61 +++
 7 files changed, 70 insertions(+)

diff --git a/arch/alpha/include/uapi/asm/socket.h 
b/arch/alpha/include/uapi/asm/socket.h
index ef4656a41058a..251b73c5481ea 100644
--- a/arch/alpha/include/uapi/asm/socket.h
+++ b/arch/alpha/include/uapi/asm/socket.h
@@ -144,6 +144,7 @@
 #define SCM_DEVMEM_LINEAR  SO_DEVMEM_LINEAR
 #define SO_DEVMEM_DMABUF   79
 #define SCM_DEVMEM_DMABUF  SO_DEVMEM_DMABUF
+#define SO_DEVMEM_DONTNEED 80
 
 #if !defined(__KERNEL__)
 
diff --git a/arch/mips/include/uapi/asm/socket.h 
b/arch/mips/include/uapi/asm/socket.h
index 414807d55e33f..8ab7582291abf 100644
--- a/arch/mips/include/uapi/asm/socket.h
+++ b/arch/mips/include/uapi/asm/socket.h
@@ -155,6 +155,7 @@
 #define SCM_DEVMEM_LINEAR  SO_DEVMEM_LINEAR
 #define SO_DEVMEM_DMABUF   79
 #define SCM_DEVMEM_DMABUF  SO_DEVMEM_DMABUF
+#define SO_DEVMEM_DONTNEED 80
 
 #if !defined(__KERNEL__)
 
diff --git a/arch/parisc/include/uapi/asm/socket.h 
b/arch/parisc/include/uapi/asm/socket.h
index 2b817efd45444..38fc0b188e084 100644
--- a/arch/parisc/include/uapi/asm/socket.h
+++ b/arch/parisc/include/uapi/asm/socket.h
@@ -136,6 +136,7 @@
 #define SCM_DEVMEM_LINEAR  SO_DEVMEM_LINEAR
 #define SO_DEVMEM_DMABUF   79
 #define SCM_DEVMEM_DMABUF  SO_DEVMEM_DMABUF
+#define SO_DEVMEM_DONTNEED 80
 
 #if !defined(__KERNEL__)
 
diff --git a/arch/sparc/include/uapi/asm/socket.h 
b/arch/sparc/include/uapi/asm/socket.h
index 00248fc689773..57084ed2f3c4e 100644
--- a/arch/sparc/include/uapi/asm/socket.h
+++ b/arch/sparc/include/uapi/asm/socket.h
@@ -137,6 +137,7 @@
 #define SCM_DEVMEM_LINEARSO_DEVMEM_LINEAR
 #define SO_DEVMEM_DMABUF 0x0058
 #define SCM_DEVMEM_DMABUFSO_DEVMEM_DMABUF
+#define SO_DEVMEM_DONTNEED   0x0059
 
 #if !defined(__KERNEL__)
 
diff --git a/include/uapi/asm-generic/socket.h 
b/include/uapi/asm-generic/socket.h
index 25a2f5255f523..1acb77780f103 100644
--- a/include/uapi/asm-generic/socket.h
+++ b/include/uapi/asm-generic/socket.h
@@ -135,6 +135,7 @@
 #define SO_PASSPIDFD   76
 #define SO_PEERPIDFD   77
 
+#define SO_DEVMEM_DONTNEED 97
 #define SO_DEVMEM_LINEAR   98
 #define SCM_DEVMEM_LINEAR  SO_DEVMEM_LINEAR
 #define SO_DEVMEM_DMABUF   99
diff --git a/include/uapi/linux/uio.h b/include/uapi/linux/uio.h
index 3a22ddae376a2..d17f8fcd93ec9 100644
--- a/include/uapi/linux/uio.h
+++ b/include/uapi/linux/uio.h
@@ -33,6 +33,10 @@ struct dmabuf_cmsg {
 */
 };
 
+struct dmabuf_token {
+   __u32 token_start;
+   __u32 token_count;
+};
 /*
  * UIO_MAXIOV shall be at least 16 1003.1g (5.4.1.1)
  */
diff --git a/net/core/sock.c b/net/core/sock.c
index 9abc4fe259535..040c66ac26244 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -124,6 +124,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1049,6 +1050,62 @@ static int sock_reserve_memory(struct sock *sk, int 
bytes)
return 0;
 }
 
+#ifdef CONFIG_PAGE_POOL
+static noinline_for_stack int
+sock_devmem_dontneed(struct sock *sk, sockptr_t optval, unsigned int optlen)
+{
+   unsigned int num_tokens, i, j, k, netmem_num = 0;
+   struct dmabuf_token *tokens;
+   netmem_ref netmems[16];
+   int ret = 0;
+
+   if (sk->sk_type != SOCK_STREAM || sk->sk_protocol != IPPROTO_TCP)
+   return -EBADF;
+
+   if (optlen % sizeof(struct dmabuf_token) ||
+   optlen > sizeof(*tokens) * 128)
+   return -EINVAL;
+
+   tokens = kvmalloc_array(128, sizeof(*tokens), GFP_KERNEL);
+   if (!tokens)
+   return -ENOMEM;
+
+   num_tokens = optlen / sizeof(struct dmabuf_token);
+   if (copy_from_sockptr(tokens, optval, optlen)) {
+   kvfree(tokens);
+   return -EFAULT;
+   }
+
+   xa_lock_bh(&sk->sk_user_frags);
+   for (i = 0; i < num_tokens; 

[PATCH net-next v14 06/13] page_pool: devmem support

2024-06-25 Thread Mina Almasry
Convert netmem to be a union of struct page and struct netmem. Overload
the LSB of struct netmem* to indicate that it's a net_iov, otherwise
it's a page.

Currently these entries in struct page are rented by the page_pool and
used exclusively by the net stack:

struct {
unsigned long pp_magic;
struct page_pool *pp;
unsigned long _pp_mapping_pad;
unsigned long dma_addr;
atomic_long_t pp_ref_count;
};

Mirror these (and only these) entries into struct net_iov and implement
netmem helpers that can access these common fields regardless of
whether the underlying type is page or net_iov.

Implement checks for net_iov in netmem helpers which delegate to mm
APIs, to ensure net_iov are never passed to the mm stack.

Signed-off-by: Mina Almasry 
Reviewed-by: Pavel Begunkov 

---

v13:
- Move NET_IOV dependent changes to this patch.
- Fixed comment (Pavel)
- Applied Reviewed-by from Pavel.

v9: 
https://lore.kernel.org/netdev/20240403002053.2376017-8-almasrym...@google.com/
- Remove CONFIG checks in netmem_is_net_iov() (Pavel/David/Jens)

v7:
- Remove static_branch_unlikely from netmem_to_net_iov(). We're getting
  better results from the fast path in bench_page_pool_simple tests
  without the static_branch_unlikely, and the addition of
  static_branch_unlikely doesn't improve performance of devmem TCP.

  Additionally only check netmem_to_net_iov() if
  CONFIG_DMA_SHARED_BUFFER is enabled, otherwise dmabuf net_iovs cannot
  exist anyway.

  net-next base: 8 cycle fast path.
  with static_branch_unlikely: 10 cycle fast path.
  without static_branch_unlikely: 9 cycle fast path.
  CONFIG_DMA_SHARED_BUFFER disabled: 8 cycle fast path as baseline.

  Performance of devmem TCP is at 95% line rate is regardless of
  static_branch_unlikely or not.

v6:
- Rebased on top of the merged netmem_ref type.
- Rebased on top of the merged skb_pp_frag_ref() changes.

v5:
- Use netmem instead of page* with LSB set.
- Use pp_ref_count for refcounting net_iov.
- Removed many of the custom checks for netmem.

v1:
- Disable fragmentation support for iov properly.
- fix napi_pp_put_page() path (Yunsheng).
- Use pp_frag_count for devmem refcounting.

Cc: linux...@kvack.org
Cc: Matthew Wilcox 

---
 include/net/netmem.h | 137 +--
 include/net/page_pool/helpers.h  |  25 +++---
 include/trace/events/page_pool.h |   8 +-
 net/core/devmem.c|   3 +
 net/core/page_pool.c |  24 +++---
 net/core/skbuff.c|  22 +++--
 6 files changed, 171 insertions(+), 48 deletions(-)

diff --git a/include/net/netmem.h b/include/net/netmem.h
index 664df8325ece5..35ad237fdf29e 100644
--- a/include/net/netmem.h
+++ b/include/net/netmem.h
@@ -9,14 +9,51 @@
 #define _NET_NETMEM_H
 
 #include 
+#include 
 
 /* net_iov */
 
+DECLARE_STATIC_KEY_FALSE(page_pool_mem_providers);
+
+/*  We overload the LSB of the struct page pointer to indicate whether it's
+ *  a page or net_iov.
+ */
+#define NET_IOV 0x01UL
+
 struct net_iov {
+   unsigned long __unused_padding;
+   unsigned long pp_magic;
+   struct page_pool *pp;
struct dmabuf_genpool_chunk_owner *owner;
unsigned long dma_addr;
+   atomic_long_t pp_ref_count;
 };
 
+/* These fields in struct page are used by the page_pool and net stack:
+ *
+ * struct {
+ * unsigned long pp_magic;
+ * struct page_pool *pp;
+ * unsigned long _pp_mapping_pad;
+ * unsigned long dma_addr;
+ * atomic_long_t pp_ref_count;
+ * };
+ *
+ * We mirror the page_pool fields here so the page_pool can access these fields
+ * without worrying whether the underlying fields belong to a page or net_iov.
+ *
+ * The non-net stack fields of struct page are private to the mm stack and must
+ * never be mirrored to net_iov.
+ */
+#define NET_IOV_ASSERT_OFFSET(pg, iov) \
+   static_assert(offsetof(struct page, pg) == \
+ offsetof(struct net_iov, iov))
+NET_IOV_ASSERT_OFFSET(pp_magic, pp_magic);
+NET_IOV_ASSERT_OFFSET(pp, pp);
+NET_IOV_ASSERT_OFFSET(dma_addr, dma_addr);
+NET_IOV_ASSERT_OFFSET(pp_ref_count, pp_ref_count);
+#undef NET_IOV_ASSERT_OFFSET
+
 static inline struct dmabuf_genpool_chunk_owner *
 net_iov_owner(const struct net_iov *niov)
 {
@@ -47,20 +84,22 @@ net_iov_binding(const struct net_iov *niov)
  */
 typedef unsigned long __bitwise netmem_ref;
 
+static inline bool netmem_is_net_iov(const netmem_ref netmem)
+{
+   return (__force unsigned long)netmem & NET_IOV;
+}
+
 /* This conversion fails (returns NULL) if the netmem_ref is not struct page
  * backed.
- *
- * Currently struct page is the only possible netmem, and this helper never
- * fails.
  */
 static inline struct page *netmem_to_page(netmem_ref netmem)
 {
+   if (WARN_ON_ONCE(netmem_is_net_iov(netmem)))
+   return NULL;
+
return (__force struct page *)netmem;
 }
 
-/* Converting from page to netmem is always 

[PATCH net-next v14 04/13] netdev: netdevice devmem allocator

2024-06-25 Thread Mina Almasry
Implement netdev devmem allocator. The allocator takes a given struct
netdev_dmabuf_binding as input and allocates net_iov from that
binding.

The allocation simply delegates to the binding's genpool for the
allocation logic and wraps the returned memory region in a net_iov
struct.

Signed-off-by: Willem de Bruijn 
Signed-off-by: Kaiyuan Zhang 
Signed-off-by: Mina Almasry 
Reviewed-by: Pavel Begunkov 

---

v11:
- Fix extraneous inline directive (Paolo)

v8:
- Rename netdev_dmabuf_binding -> net_devmem_dmabuf_binding to avoid
  patch-by-patch build error.
- Move niov->pp_magic/pp/pp_ref_counter usage to later patch to avoid
  patch-by-patch build error.

v7:
- netdev_ -> net_devmem_* naming (Yunsheng).

v6:
- Add comment on net_iov_dma_addr to explain why we don't use
  niov->dma_addr (Pavel)
- Refactor new functions into net/core/devmem.c (Pavel)

v1:
- Rename devmem -> dmabuf (David).

---
 include/net/devmem.h | 13 +
 include/net/netmem.h | 18 ++
 net/core/devmem.c| 44 
 3 files changed, 75 insertions(+)

diff --git a/include/net/devmem.h b/include/net/devmem.h
index eaf3fd965d7a8..b65795a8f8f13 100644
--- a/include/net/devmem.h
+++ b/include/net/devmem.h
@@ -68,7 +68,20 @@ int net_devmem_bind_dmabuf(struct net_device *dev, unsigned 
int dmabuf_fd,
 void net_devmem_unbind_dmabuf(struct net_devmem_dmabuf_binding *binding);
 int net_devmem_bind_dmabuf_to_queue(struct net_device *dev, u32 rxq_idx,
struct net_devmem_dmabuf_binding *binding);
+struct net_iov *
+net_devmem_alloc_dmabuf(struct net_devmem_dmabuf_binding *binding);
+void net_devmem_free_dmabuf(struct net_iov *ppiov);
 #else
+static inline struct net_iov *
+net_devmem_alloc_dmabuf(struct net_devmem_dmabuf_binding *binding)
+{
+   return NULL;
+}
+
+static inline void net_devmem_free_dmabuf(struct net_iov *ppiov)
+{
+}
+
 static inline void
 __net_devmem_dmabuf_binding_free(struct net_devmem_dmabuf_binding *binding)
 {
diff --git a/include/net/netmem.h b/include/net/netmem.h
index 72e932a1a9489..01dbdd216fae7 100644
--- a/include/net/netmem.h
+++ b/include/net/netmem.h
@@ -14,8 +14,26 @@
 
 struct net_iov {
struct dmabuf_genpool_chunk_owner *owner;
+   unsigned long dma_addr;
 };
 
+static inline struct dmabuf_genpool_chunk_owner *
+net_iov_owner(const struct net_iov *niov)
+{
+   return niov->owner;
+}
+
+static inline unsigned int net_iov_idx(const struct net_iov *niov)
+{
+   return niov - net_iov_owner(niov)->niovs;
+}
+
+static inline struct net_devmem_dmabuf_binding *
+net_iov_binding(const struct net_iov *niov)
+{
+   return net_iov_owner(niov)->binding;
+}
+
 /* netmem */
 
 /**
diff --git a/net/core/devmem.c b/net/core/devmem.c
index cfb5a2f69dcd2..aeee25c91b844 100644
--- a/net/core/devmem.c
+++ b/net/core/devmem.c
@@ -32,6 +32,14 @@ static void net_devmem_dmabuf_free_chunk_owner(struct 
gen_pool *genpool,
kfree(owner);
 }
 
+static dma_addr_t net_devmem_get_dma_addr(const struct net_iov *niov)
+{
+   struct dmabuf_genpool_chunk_owner *owner = net_iov_owner(niov);
+
+   return owner->base_dma_addr +
+  ((dma_addr_t)net_iov_idx(niov) << PAGE_SHIFT);
+}
+
 void __net_devmem_dmabuf_binding_free(struct net_devmem_dmabuf_binding 
*binding)
 {
size_t size, avail;
@@ -54,6 +62,42 @@ void __net_devmem_dmabuf_binding_free(struct 
net_devmem_dmabuf_binding *binding)
kfree(binding);
 }
 
+struct net_iov *
+net_devmem_alloc_dmabuf(struct net_devmem_dmabuf_binding *binding)
+{
+   struct dmabuf_genpool_chunk_owner *owner;
+   unsigned long dma_addr;
+   struct net_iov *niov;
+   ssize_t offset;
+   ssize_t index;
+
+   dma_addr = gen_pool_alloc_owner(binding->chunk_pool, PAGE_SIZE,
+   (void **)&owner);
+   if (!dma_addr)
+   return NULL;
+
+   offset = dma_addr - owner->base_dma_addr;
+   index = offset / PAGE_SIZE;
+   niov = &owner->niovs[index];
+
+   niov->dma_addr = 0;
+
+   net_devmem_dmabuf_binding_get(binding);
+
+   return niov;
+}
+
+void net_devmem_free_dmabuf(struct net_iov *niov)
+{
+   struct net_devmem_dmabuf_binding *binding = net_iov_binding(niov);
+   unsigned long dma_addr = net_devmem_get_dma_addr(niov);
+
+   if (gen_pool_has_addr(binding->chunk_pool, dma_addr, PAGE_SIZE))
+   gen_pool_free(binding->chunk_pool, dma_addr, PAGE_SIZE);
+
+   net_devmem_dmabuf_binding_put(binding);
+}
+
 /* Protected by rtnl_lock() */
 static DEFINE_XARRAY_FLAGS(net_devmem_dmabuf_bindings, XA_FLAGS_ALLOC1);
 
-- 
2.45.2.741.gdbec12cfda-goog



[PATCH net-next v14 05/13] page_pool: convert to use netmem

2024-06-25 Thread Mina Almasry
Abstract the memory type from the page_pool so we can later add support
for new memory types. Convert the page_pool to use the new netmem type
abstraction, rather than use struct page directly.

As of this patch the netmem type is a no-op abstraction: it's always a
struct page underneath. All the page pool internals are converted to
use struct netmem instead of struct page, and the page pool now exports
2 APIs:

1. The existing struct page API.
2. The new struct netmem API.

Keeping the existing API is transitional; we do not want to refactor all
the current drivers using the page pool at once.

The netmem abstraction is currently a no-op. The page_pool uses
page_to_netmem() to convert allocated pages to netmem, and uses
netmem_to_page() to convert the netmem back to pages to pass to mm APIs,

Follow up patches to this series add non-paged netmem support to the
page_pool. This change is factored out on its own to limit the code
churn to this 1 patch, for ease of code review.

Signed-off-by: Mina Almasry 
Reviewed-by: Pavel Begunkov 

---

v13:
- Fix allmodconfig build error. NET_IOV was not defined as of this
  patch.
- Removed unnecessary update of page_pool_alloc() API. It now retains it
  struct page* interface.  (Paul).
- Fixed comments Pavel pointed to.
- Applied reviewed-by from Pavel.

v12:
- Fix allmodconfig build error. Very recently renesas/ravb_main.c added
  a dependency on page_pool that I missed in my rebase. The dependency
  calls page_pool_alloc() directly as it wants to set a custom gfp_mask,
  which is unique as all other drivers call a wrapper to that function.
  Fix it by adding netmem_to_page() in the driver.
- Fix printing netmem trace printing (Pavel).

v11:
- Fix typing to remove sparse warning. (Paolo/Steven)

v9:
- Fix sparse error (Simon).

v8:
- Fix napi_pp_put_page() taking netmem instead of page to fix
  patch-by-patch build error.
- Add net/netmem.h include in this patch to fix patch-by-patch build
  error.

v6:

- Rebased on top of the merged netmem_ref type.

Cc: linux...@kvack.org
Cc: Matthew Wilcox 

---
 include/linux/skbuff_ref.h   |   4 +-
 include/net/netmem.h |  15 ++
 include/net/page_pool/helpers.h  |  91 ++---
 include/net/page_pool/types.h|  14 +-
 include/trace/events/page_pool.h |  30 +--
 net/bpf/test_run.c   |   5 +-
 net/core/page_pool.c | 304 +--
 net/core/skbuff.c|   8 +-
 8 files changed, 287 insertions(+), 184 deletions(-)

diff --git a/include/linux/skbuff_ref.h b/include/linux/skbuff_ref.h
index 11f0a40634033..16c241a234728 100644
--- a/include/linux/skbuff_ref.h
+++ b/include/linux/skbuff_ref.h
@@ -32,13 +32,13 @@ static inline void skb_frag_ref(struct sk_buff *skb, int f)
__skb_frag_ref(&skb_shinfo(skb)->frags[f]);
 }
 
-bool napi_pp_put_page(struct page *page);
+bool napi_pp_put_page(netmem_ref netmem);
 
 static inline void
 skb_page_unref(struct page *page, bool recycle)
 {
 #ifdef CONFIG_PAGE_POOL
-   if (recycle && napi_pp_put_page(page))
+   if (recycle && napi_pp_put_page(page_to_netmem(page)))
return;
 #endif
put_page(page);
diff --git a/include/net/netmem.h b/include/net/netmem.h
index 01dbdd216fae7..664df8325ece5 100644
--- a/include/net/netmem.h
+++ b/include/net/netmem.h
@@ -66,4 +66,19 @@ static inline netmem_ref page_to_netmem(struct page *page)
return (__force netmem_ref)page;
 }
 
+static inline int netmem_ref_count(netmem_ref netmem)
+{
+   return page_ref_count(netmem_to_page(netmem));
+}
+
+static inline unsigned long netmem_to_pfn(netmem_ref netmem)
+{
+   return page_to_pfn(netmem_to_page(netmem));
+}
+
+static inline netmem_ref netmem_compound_head(netmem_ref netmem)
+{
+   return page_to_netmem(compound_head(netmem_to_page(netmem)));
+}
+
 #endif /* _NET_NETMEM_H */
diff --git a/include/net/page_pool/helpers.h b/include/net/page_pool/helpers.h
index 873631c79ab16..2b43a893c619d 100644
--- a/include/net/page_pool/helpers.h
+++ b/include/net/page_pool/helpers.h
@@ -55,6 +55,8 @@
 #include 
 
 #include 
+#include 
+#include 
 
 #ifdef CONFIG_PAGE_POOL_STATS
 /* Deprecated driver-facing API, use netlink instead */
@@ -212,6 +214,11 @@ page_pool_get_dma_dir(const struct page_pool *pool)
return pool->p.dma_dir;
 }
 
+static inline void page_pool_fragment_netmem(netmem_ref netmem, long nr)
+{
+   atomic_long_set(&netmem_to_page(netmem)->pp_ref_count, nr);
+}
+
 /**
  * page_pool_fragment_page() - split a fresh page into fragments
  * @page:  page to split
@@ -232,11 +239,12 @@ page_pool_get_dma_dir(const struct page_pool *pool)
  */
 static inline void page_pool_fragment_page(struct page *page, long nr)
 {
-   atomic_long_set(&page->pp_ref_count, nr);
+   page_pool_fragment_netmem(page_to_netmem(page), nr);
 }
 
-static inline long page_pool_unref_page(struct page *page, long nr)
+static inline long page_pool_unref_netmem(netmem_ref netmem, long nr)
 {
+   s

[PATCH net-next v14 02/13] net: netdev netlink api to bind dma-buf to a net device

2024-06-25 Thread Mina Almasry
API takes the dma-buf fd as input, and binds it to the netdevice. The
user can specify the rx queues to bind the dma-buf to.

Suggested-by: Stanislav Fomichev 
Signed-off-by: Mina Almasry 

---

v7:
- Use flags: [ admin-perm ] instead of a CAP_NET_ADMIN check.

Changes in v1:
- Add rx-queue-type to distingish rx from tx (Jakub)
- Return dma-buf ID from netlink API (David, Stan)

Changes in RFC-v3:
- Support binding multiple rx rx-queues

---
 Documentation/netlink/specs/netdev.yaml | 53 +
 include/uapi/linux/netdev.h | 19 +
 net/core/netdev-genl-gen.c  | 19 +
 net/core/netdev-genl-gen.h  |  2 +
 net/core/netdev-genl.c  |  6 +++
 tools/include/uapi/linux/netdev.h   | 19 +
 6 files changed, 118 insertions(+)

diff --git a/Documentation/netlink/specs/netdev.yaml 
b/Documentation/netlink/specs/netdev.yaml
index 959755be4d7f9..899ac0882a098 100644
--- a/Documentation/netlink/specs/netdev.yaml
+++ b/Documentation/netlink/specs/netdev.yaml
@@ -268,6 +268,45 @@ attribute-sets:
 name: napi-id
 doc: ID of the NAPI instance which services this queue.
 type: u32
+  -
+name: queue-dmabuf
+attributes:
+  -
+name: type
+doc: rx or tx queue
+type: u8
+enum: queue-type
+  -
+name: idx
+doc: queue index
+type: u32
+
+  -
+name: bind-dmabuf
+attributes:
+  -
+name: ifindex
+doc: netdev ifindex to bind the dma-buf to.
+type: u32
+checks:
+  min: 1
+  -
+name: queues
+doc: receive queues to bind the dma-buf to.
+type: nest
+nested-attributes: queue-dmabuf
+multi-attr: true
+  -
+name: dmabuf-fd
+doc: dmabuf file descriptor to bind.
+type: u32
+  -
+name: dmabuf-id
+doc: id of the dmabuf binding
+type: u32
+checks:
+  min: 1
+
 
   -
 name: qstats
@@ -579,6 +618,20 @@ operations:
   attributes:
 - ifindex
 reply: *queue-get-op
+-
+  name: bind-rx
+  doc: Bind dmabuf to netdev
+  attribute-set: bind-dmabuf
+  flags: [ admin-perm ]
+  do:
+request:
+  attributes:
+- ifindex
+- dmabuf-fd
+- queues
+reply:
+  attributes:
+- dmabuf-id
 -
   name: napi-get
   doc: Get information about NAPI instances configured on the system.
diff --git a/include/uapi/linux/netdev.h b/include/uapi/linux/netdev.h
index 43742ac5b00da..190a504a62358 100644
--- a/include/uapi/linux/netdev.h
+++ b/include/uapi/linux/netdev.h
@@ -136,6 +136,24 @@ enum {
NETDEV_A_QUEUE_MAX = (__NETDEV_A_QUEUE_MAX - 1)
 };
 
+enum {
+   NETDEV_A_QUEUE_DMABUF_TYPE = 1,
+   NETDEV_A_QUEUE_DMABUF_IDX,
+
+   __NETDEV_A_QUEUE_DMABUF_MAX,
+   NETDEV_A_QUEUE_DMABUF_MAX = (__NETDEV_A_QUEUE_DMABUF_MAX - 1)
+};
+
+enum {
+   NETDEV_A_BIND_DMABUF_IFINDEX = 1,
+   NETDEV_A_BIND_DMABUF_QUEUES,
+   NETDEV_A_BIND_DMABUF_DMABUF_FD,
+   NETDEV_A_BIND_DMABUF_DMABUF_ID,
+
+   __NETDEV_A_BIND_DMABUF_MAX,
+   NETDEV_A_BIND_DMABUF_MAX = (__NETDEV_A_BIND_DMABUF_MAX - 1)
+};
+
 enum {
NETDEV_A_QSTATS_IFINDEX = 1,
NETDEV_A_QSTATS_QUEUE_TYPE,
@@ -184,6 +202,7 @@ enum {
NETDEV_CMD_PAGE_POOL_CHANGE_NTF,
NETDEV_CMD_PAGE_POOL_STATS_GET,
NETDEV_CMD_QUEUE_GET,
+   NETDEV_CMD_BIND_RX,
NETDEV_CMD_NAPI_GET,
NETDEV_CMD_QSTATS_GET,
 
diff --git a/net/core/netdev-genl-gen.c b/net/core/netdev-genl-gen.c
index 8350a0afa9ec7..9acd0d893765a 100644
--- a/net/core/netdev-genl-gen.c
+++ b/net/core/netdev-genl-gen.c
@@ -27,6 +27,11 @@ const struct nla_policy 
netdev_page_pool_info_nl_policy[NETDEV_A_PAGE_POOL_IFIND
[NETDEV_A_PAGE_POOL_IFINDEX] = NLA_POLICY_FULL_RANGE(NLA_U32, 
&netdev_a_page_pool_ifindex_range),
 };
 
+const struct nla_policy 
netdev_queue_dmabuf_nl_policy[NETDEV_A_QUEUE_DMABUF_IDX + 1] = {
+   [NETDEV_A_QUEUE_DMABUF_TYPE] = NLA_POLICY_MAX(NLA_U8, 1),
+   [NETDEV_A_QUEUE_DMABUF_IDX] = { .type = NLA_U32, },
+};
+
 /* NETDEV_CMD_DEV_GET - do */
 static const struct nla_policy netdev_dev_get_nl_policy[NETDEV_A_DEV_IFINDEX + 
1] = {
[NETDEV_A_DEV_IFINDEX] = NLA_POLICY_MIN(NLA_U32, 1),
@@ -58,6 +63,13 @@ static const struct nla_policy 
netdev_queue_get_dump_nl_policy[NETDEV_A_QUEUE_IF
[NETDEV_A_QUEUE_IFINDEX] = NLA_POLICY_MIN(NLA_U32, 1),
 };
 
+/* NETDEV_CMD_BIND_RX - do */
+static const struct nla_policy 
netdev_bind_rx_nl_policy[NETDEV_A_BIND_DMABUF_DMABUF_FD + 1] = {
+   [NETDEV_A_BIND_DMABUF_IFINDEX] = NLA_POLICY_MIN(NLA_U32, 1),
+   [NETDEV_A_BIND_DMABUF_DMABUF_FD] = { .type = NLA_U32, },
+   [NETDEV_A_BIND_DMABUF_QUEUES] = 
NLA_POLICY_NESTED(netdev_queue_dmabuf_nl_policy),
+};
+
 /* NETDEV_CMD_NAPI_GET - do */
 static const struct nla_policy netd

[PATCH net-next v14 01/13] netdev: add netdev_rx_queue_restart()

2024-06-25 Thread Mina Almasry
Add netdev_rx_queue_restart() function to netdev_rx_queue.h

Signed-off-by: David Wei 
Signed-off-by: Mina Almasry 
Reviewed-by: Pavel Begunkov 

---

v13:
- Add reviewed-by from Pavel (thanks!)
- Fixed comment (Pavel)

v11:
- Fix not checking dev->queue_mgmt_ops (Pavel).
- Fix ndo_queue_mem_free call that passed the wrong pointer (David).

v9: https://lore.kernel.org/all/20240502045410.3524155-4...@davidwei.uk/
(submitted by David).
- fixed SPDX license identifier (Simon).
- Rebased on top of merged queue API definition, and changed
  implementation to match that.
- Replace rtnl_lock() with rtnl_is_locked() to make it useable from my
  netlink code where rtnl is already locked.

---
 include/net/netdev_rx_queue.h |  3 ++
 net/core/Makefile |  1 +
 net/core/netdev_rx_queue.c| 74 +++
 3 files changed, 78 insertions(+)
 create mode 100644 net/core/netdev_rx_queue.c

diff --git a/include/net/netdev_rx_queue.h b/include/net/netdev_rx_queue.h
index aa1716fb0e53c..e78ca52d67fbf 100644
--- a/include/net/netdev_rx_queue.h
+++ b/include/net/netdev_rx_queue.h
@@ -54,4 +54,7 @@ get_netdev_rx_queue_index(struct netdev_rx_queue *queue)
return index;
 }
 #endif
+
+int netdev_rx_queue_restart(struct net_device *dev, unsigned int rxq);
+
 #endif
diff --git a/net/core/Makefile b/net/core/Makefile
index 62be9aef25285..f82232b358a2c 100644
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_NETDEV_ADDR_LIST_TEST) += dev_addr_lists_test.o
 
 obj-y += net-sysfs.o
 obj-y += hotdata.o
+obj-y += netdev_rx_queue.o
 obj-$(CONFIG_PAGE_POOL) += page_pool.o page_pool_user.o
 obj-$(CONFIG_PROC_FS) += net-procfs.o
 obj-$(CONFIG_NET_PKTGEN) += pktgen.o
diff --git a/net/core/netdev_rx_queue.c b/net/core/netdev_rx_queue.c
new file mode 100644
index 0..cf15ffecfa368
--- /dev/null
+++ b/net/core/netdev_rx_queue.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include 
+#include 
+#include 
+
+int netdev_rx_queue_restart(struct net_device *dev, unsigned int rxq_idx)
+{
+   void *new_mem, *old_mem;
+   int err;
+
+   if (!dev->queue_mgmt_ops || !dev->queue_mgmt_ops->ndo_queue_stop ||
+   !dev->queue_mgmt_ops->ndo_queue_mem_free ||
+   !dev->queue_mgmt_ops->ndo_queue_mem_alloc ||
+   !dev->queue_mgmt_ops->ndo_queue_start)
+   return -EOPNOTSUPP;
+
+   DEBUG_NET_WARN_ON_ONCE(!rtnl_is_locked());
+
+   new_mem = kvzalloc(dev->queue_mgmt_ops->ndo_queue_mem_size, GFP_KERNEL);
+   if (!new_mem)
+   return -ENOMEM;
+
+   old_mem = kvzalloc(dev->queue_mgmt_ops->ndo_queue_mem_size, GFP_KERNEL);
+   if (!old_mem) {
+   err = -ENOMEM;
+   goto err_free_new_mem;
+   }
+
+   err = dev->queue_mgmt_ops->ndo_queue_mem_alloc(dev, new_mem, rxq_idx);
+   if (err)
+   goto err_free_old_mem;
+
+   err = dev->queue_mgmt_ops->ndo_queue_stop(dev, old_mem, rxq_idx);
+   if (err)
+   goto err_free_new_queue_mem;
+
+   err = dev->queue_mgmt_ops->ndo_queue_start(dev, new_mem, rxq_idx);
+   if (err)
+   goto err_start_queue;
+
+   dev->queue_mgmt_ops->ndo_queue_mem_free(dev, old_mem);
+
+   kvfree(old_mem);
+   kvfree(new_mem);
+
+   return 0;
+
+err_start_queue:
+   /* Restarting the queue with old_mem should be successful as we haven't
+* changed any of the queue configuration, and there is not much we can
+* do to recover from a failure here.
+*
+* WARN if we fail to recover the old rx queue, and at least free
+* old_mem so we don't also leak that.
+*/
+   if (dev->queue_mgmt_ops->ndo_queue_start(dev, old_mem, rxq_idx)) {
+   WARN(1,
+"Failed to restart old queue in error path. RX queue %d 
may be unhealthy.",
+rxq_idx);
+   dev->queue_mgmt_ops->ndo_queue_mem_free(dev, old_mem);
+   }
+
+err_free_new_queue_mem:
+   dev->queue_mgmt_ops->ndo_queue_mem_free(dev, new_mem);
+
+err_free_old_mem:
+   kvfree(old_mem);
+
+err_free_new_mem:
+   kvfree(new_mem);
+
+   return err;
+}
-- 
2.45.2.741.gdbec12cfda-goog



[PATCH net-next v14 00/13] Device Memory TCP

2024-06-25 Thread Mina Almasry
v14: 
https://patchwork.kernel.org/project/netdevbpf/list/?series=865135&archive=both&state=*


No material changes in this version. Only rebase and re-verification on
top of net-next. v13, I think, raced with commit ebad6d0334793
("net/ipv4: Use nested-BH locking for ipv4_tcp_sk.") being merged to
net-next that caused a patchwork failure to apply. This series should
apply cleanly on commit c4532232fa2a4 ("selftests: net: remove unneeded
IP_GRE config").

I did not wait the customary 24hr as Jakub said it's OK to repost as soon
as I build test the rebased version:

https://lore.kernel.org/netdev/20240625075926.146d7...@kernel.org/

v13: 
https://patchwork.kernel.org/project/netdevbpf/list/?series=861406&archive=both&state=*


Major changes:
--

This iteration addresses Pavel's review comments, applies his
reviewed-by's, and seeks to fix the patchwork build error (sorry!).

As usual, the full devmem TCP changes including the full GVE driver
implementation is here:

https://github.com/mina/linux/commits/tcpdevmem-v13/

v12: https://patchwork.kernel.org/project/netdevbpf/list/?series=859747&state=*


Major changes:
--

This iteration only addresses one minor comment from Pavel with regards
to the trace printing of netmem, and the patchwork build error
introduced in v11 because I missed doing an allmodconfig build, sorry.

Other than that v11, AFAICT, received no feedback. There is one
discussion about how the specifics of  plugging io uring memory through
the page pool, but not relevant to content in this particular patchset,
AFAICT.

As usual, the full devmem TCP changes including the full GVE driver
implementation is here:

https://github.com/mina/linux/commits/tcpdevmem-v12/

v11: https://patchwork.kernel.org/project/netdevbpf/list/?series=857457&state=*


Major Changes:
--

v11 addresses feedback received in v10. The major change is the removal
of the memory provider ops as requested by Christoph. We still
accomplish the same thing, but utilizing direct function calls with if
statements rather than generic ops.

Additionally address sparse warnings, bugs and review comments from
folks that reviewed.

As usual, the full devmem TCP changes including the full GVE driver
implementation is here:

https://github.com/mina/linux/commits/tcpdevmem-v11/

Detailed changelog:
---

- Fixes in netdev_rx_queue_restart() from Pavel & David.
- Remove commit e650e8c3a36f5 ("net: page_pool: create hooks for
custom page providers") from the series to address Christoph's
feedback and rebased other patches on the series on this change.
- Fixed build errors with CONFIG_DMA_SHARED_BUFFER &&
  !CONFIG_GENERIC_ALLOCATOR build.
- Fixed sparse warnings pointed out by Paolo.
- Drop unnecessary gro_pull_from_frag0 checks.
- Added Bagas reviewed-by to docs.

Cc: Bagas Sanjaya 
Cc: Steven Rostedt 
Cc: Christoph Hellwig 
Cc: Nikolay Aleksandrov 

v10: https://patchwork.kernel.org/project/netdevbpf/list/?series=852422&state=*


Major Changes:
--

v9 was sent right before the merge window closed (sorry!). v10 is almost
a re-send of the series now that the merge window re-opened. Only
rebased to latest net-next and addressed some minor iterative comments
received on v9.

As usual, the full devmem TCP changes including the full GVE driver
implementation is here:

https://github.com/mina/linux/commits/tcpdevmem-v10/

Detailed changelog:
---

- Fixed tokens leaking in DONTNEED setsockopt (Nikolay).
- Moved net_iov_dma_addr() to devmem.c and made it a devmem specific
  helpers (David).
- Rename hook alloc_pages to alloc_netmems as alloc_pages is now
  preprocessor macro defined and causes a build error.

v9:
===

Major Changes:
--

GVE queue API has been merged. Submitting this version as non-RFC after
rebasing on top of the merged API, and dropped the out of tree queue API
I was carrying on github. Addressed the little feedback v8 has received.

Detailed changelog:
--
- Added new patch from David Wei to this series for
  netdev_rx_queue_restart()
  - Fixed sparse error.
  - Removed CONFIG_ checks in netmem_is_net_iov()
  - Flipped skb->readable to skb->unreadable
  - Minor fixes to selftests & docs.

RFC v8:
===

Major Changes:
--

- Fixed build error generated by patch-by-patch build.
- Applied docs suggestions from Randy.

RFC v7:
===

Major Changes:
--

This revision largely rebases on top of net-next and addresses the feedback
RFCv6 received from folks, namely Jakub, Yunsheng, Arnd, David, & Pavel.

The series remains in RFC because the queue-API ndos defined in this
series are not yet implemented. I have a GVE implementation I carry out
of tree for my testing. A upstreamable GVE implementation is in the
works. Aside from that, in my estimation all the patches are ready for
review/merge. Please do take a look.

As usual the full devmem TCP changes including the full GVE driver
imple

Re: [PATCH RFC v2] drm/msm/dpu: Configure DP INTF/PHY selector

2024-06-25 Thread Abhinav Kumar




On 6/25/2024 12:26 PM, Abhinav Kumar wrote:



On 6/24/2024 6:39 PM, Abhinav Kumar wrote:



On 6/13/2024 4:17 AM, Dmitry Baryshkov wrote:

From: Bjorn Andersson 

Some platforms provides a mechanism for configuring the mapping between
(one or two) DisplayPort intfs and their PHYs.

In particular SC8180X provides this functionality, without a default
configuration, resulting in no connection between its two external
DisplayPort controllers and any PHYs.



I have to cross-check internally about what makes it mandatory to 
program this only for sc8180xp. We were not programming this so far 
for any chipset and this register is present all the way from sm8150 
till xe10100 and all the chipsets do not have a correct default value 
which makes me think whether this is required to be programmed.


Will update this thread once I do.



Ok, I checked more. The reason this is mandatory for sc8180xp is the 
number of controllers is greater than number of PHYs needing this to be 
programmed. On all other chipsets its a 1:1 mapping.




Correction, number of controllers is < number of PHYs.


I am fine with the change once the genmap comment is addressed.


The change implements the logic for optionally configuring which PHY
each of the DP INTFs should be connected to and marks the SC8180X DPU to
program 2 entries.

For now the request is simply to program the mapping 1:1, any support
for alternative mappings is left until the use case arrise.

Note that e.g. msm-4.14 unconditionally maps INTF 0 to PHY 0 on all
rlatforms, so perhaps this is needed in order to get DisplayPort working
on some other platforms as well.

Signed-off-by: Bjorn Andersson 
Co-developed-by: Bjorn Andersson 
Signed-off-by: Dmitry Baryshkov 
---
Changes in v2:
- Removed entry from the catalog.
- Reworked the interface of dpu_hw_dp_phy_intf_sel(). Pass two entries
   for the PHYs instead of three entries.
- It seems the register isn't present on sdm845, enabled the callback
   only for DPU >= 5.x
- Added a comment regarding the data being platform-specific.
- Link to v1: 
https://lore.kernel.org/r/20230612221047.1886709-1-quic_bjora...@quicinc.com

---
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c | 39 
+++---

  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h | 18 --
  drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h   |  7 ++
  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c    | 11 -
  4 files changed, 69 insertions(+), 6 deletions(-)

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

index 05e48cf4ec1d..a11fdbefc8d2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
@@ -231,8 +231,38 @@ static void dpu_hw_intf_audio_select(struct 
dpu_hw_mdp *mdp)

  DPU_REG_WRITE(c, HDMI_DP_CORE_SELECT, 0x1);
  }
+static void dpu_hw_dp_phy_intf_sel(struct dpu_hw_mdp *mdp,
+   enum dpu_dp_phy_sel phys[2])
+{
+    struct dpu_hw_blk_reg_map *c = &mdp->hw;
+    unsigned int intf;
+    u32 sel = 0;
+
+    sel |= FIELD_PREP(MDP_DP_PHY_INTF_SEL_INTF0, phys[0]);
+    sel |= FIELD_PREP(MDP_DP_PHY_INTF_SEL_INTF1, phys[1]);
+
+    for (intf = 0; intf < 2; intf++) {


I wonder if ARRAY_SIZE(phys) is better here.


+    switch (phys[intf]) {
+    case DPU_DP_PHY_0:
+    sel |= FIELD_PREP(MDP_DP_PHY_INTF_SEL_PHY0, intf + 1);
+    break;
+    case DPU_DP_PHY_1:
+    sel |= FIELD_PREP(MDP_DP_PHY_INTF_SEL_PHY1, intf + 1);
+    break;
+    case DPU_DP_PHY_2:
+    sel |= FIELD_PREP(MDP_DP_PHY_INTF_SEL_PHY2, intf + 1);
+    break;
+    default:
+    /* ignore */
+    break;
+    }
+    }
+
+    DPU_REG_WRITE(c, MDP_DP_PHY_INTF_SEL, sel);
+}
+
  static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops,
-    unsigned long cap)
+    unsigned long cap, const struct dpu_mdss_version *mdss_rev)
  {
  ops->setup_split_pipe = dpu_hw_setup_split_pipe;
  ops->setup_clk_force_ctrl = dpu_hw_setup_clk_force_ctrl;
@@ -245,6 +275,9 @@ static void _setup_mdp_ops(struct dpu_hw_mdp_ops 
*ops,

  ops->get_safe_status = dpu_hw_get_safe_status;
+    if (mdss_rev->core_major_ver >= 5)
+    ops->dp_phy_intf_sel = dpu_hw_dp_phy_intf_sel;
+
  if (cap & BIT(DPU_MDP_AUDIO_SELECT))
  ops->intf_audio_select = dpu_hw_intf_audio_select;
  }
@@ -252,7 +285,7 @@ static void _setup_mdp_ops(struct dpu_hw_mdp_ops 
*ops,

  struct dpu_hw_mdp *dpu_hw_mdptop_init(struct drm_device *dev,
    const struct dpu_mdp_cfg *cfg,
    void __iomem *addr,
-  const struct dpu_mdss_cfg *m)
+  const struct dpu_mdss_version *mdss_rev)
  {
  struct dpu_hw_mdp *mdp;
@@ -270,7 +303,7 @@ struct dpu_hw_mdp *dpu_hw_mdptop_init(struct 
drm_device *dev,

   * Assign ops
   */
  mdp->caps = cfg;
-    _setup_mdp_ops(&mdp->ops, mdp->caps->features);
+    _setup_mdp_ops(&mdp-

Re: [PATCH RFC v2] drm/msm/dpu: Configure DP INTF/PHY selector

2024-06-25 Thread Abhinav Kumar




On 6/24/2024 6:39 PM, Abhinav Kumar wrote:



On 6/13/2024 4:17 AM, Dmitry Baryshkov wrote:

From: Bjorn Andersson 

Some platforms provides a mechanism for configuring the mapping between
(one or two) DisplayPort intfs and their PHYs.

In particular SC8180X provides this functionality, without a default
configuration, resulting in no connection between its two external
DisplayPort controllers and any PHYs.



I have to cross-check internally about what makes it mandatory to 
program this only for sc8180xp. We were not programming this so far for 
any chipset and this register is present all the way from sm8150 till 
xe10100 and all the chipsets do not have a correct default value which 
makes me think whether this is required to be programmed.


Will update this thread once I do.



Ok, I checked more. The reason this is mandatory for sc8180xp is the 
number of controllers is greater than number of PHYs needing this to be 
programmed. On all other chipsets its a 1:1 mapping.


I am fine with the change once the genmap comment is addressed.


The change implements the logic for optionally configuring which PHY
each of the DP INTFs should be connected to and marks the SC8180X DPU to
program 2 entries.

For now the request is simply to program the mapping 1:1, any support
for alternative mappings is left until the use case arrise.

Note that e.g. msm-4.14 unconditionally maps INTF 0 to PHY 0 on all
rlatforms, so perhaps this is needed in order to get DisplayPort working
on some other platforms as well.

Signed-off-by: Bjorn Andersson 
Co-developed-by: Bjorn Andersson 
Signed-off-by: Dmitry Baryshkov 
---
Changes in v2:
- Removed entry from the catalog.
- Reworked the interface of dpu_hw_dp_phy_intf_sel(). Pass two entries
   for the PHYs instead of three entries.
- It seems the register isn't present on sdm845, enabled the callback
   only for DPU >= 5.x
- Added a comment regarding the data being platform-specific.
- Link to v1: 
https://lore.kernel.org/r/20230612221047.1886709-1-quic_bjora...@quicinc.com

---
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c | 39 
+++---

  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h | 18 --
  drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h   |  7 ++
  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c    | 11 -
  4 files changed, 69 insertions(+), 6 deletions(-)

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

index 05e48cf4ec1d..a11fdbefc8d2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
@@ -231,8 +231,38 @@ static void dpu_hw_intf_audio_select(struct 
dpu_hw_mdp *mdp)

  DPU_REG_WRITE(c, HDMI_DP_CORE_SELECT, 0x1);
  }
+static void dpu_hw_dp_phy_intf_sel(struct dpu_hw_mdp *mdp,
+   enum dpu_dp_phy_sel phys[2])
+{
+    struct dpu_hw_blk_reg_map *c = &mdp->hw;
+    unsigned int intf;
+    u32 sel = 0;
+
+    sel |= FIELD_PREP(MDP_DP_PHY_INTF_SEL_INTF0, phys[0]);
+    sel |= FIELD_PREP(MDP_DP_PHY_INTF_SEL_INTF1, phys[1]);
+
+    for (intf = 0; intf < 2; intf++) {


I wonder if ARRAY_SIZE(phys) is better here.


+    switch (phys[intf]) {
+    case DPU_DP_PHY_0:
+    sel |= FIELD_PREP(MDP_DP_PHY_INTF_SEL_PHY0, intf + 1);
+    break;
+    case DPU_DP_PHY_1:
+    sel |= FIELD_PREP(MDP_DP_PHY_INTF_SEL_PHY1, intf + 1);
+    break;
+    case DPU_DP_PHY_2:
+    sel |= FIELD_PREP(MDP_DP_PHY_INTF_SEL_PHY2, intf + 1);
+    break;
+    default:
+    /* ignore */
+    break;
+    }
+    }
+
+    DPU_REG_WRITE(c, MDP_DP_PHY_INTF_SEL, sel);
+}
+
  static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops,
-    unsigned long cap)
+    unsigned long cap, const struct dpu_mdss_version *mdss_rev)
  {
  ops->setup_split_pipe = dpu_hw_setup_split_pipe;
  ops->setup_clk_force_ctrl = dpu_hw_setup_clk_force_ctrl;
@@ -245,6 +275,9 @@ static void _setup_mdp_ops(struct dpu_hw_mdp_ops 
*ops,

  ops->get_safe_status = dpu_hw_get_safe_status;
+    if (mdss_rev->core_major_ver >= 5)
+    ops->dp_phy_intf_sel = dpu_hw_dp_phy_intf_sel;
+
  if (cap & BIT(DPU_MDP_AUDIO_SELECT))
  ops->intf_audio_select = dpu_hw_intf_audio_select;
  }
@@ -252,7 +285,7 @@ static void _setup_mdp_ops(struct dpu_hw_mdp_ops 
*ops,

  struct dpu_hw_mdp *dpu_hw_mdptop_init(struct drm_device *dev,
    const struct dpu_mdp_cfg *cfg,
    void __iomem *addr,
-  const struct dpu_mdss_cfg *m)
+  const struct dpu_mdss_version *mdss_rev)
  {
  struct dpu_hw_mdp *mdp;
@@ -270,7 +303,7 @@ struct dpu_hw_mdp *dpu_hw_mdptop_init(struct 
drm_device *dev,

   * Assign ops
   */
  mdp->caps = cfg;
-    _setup_mdp_ops(&mdp->ops, mdp->caps->features);
+    _setup_mdp_ops(&mdp->ops, mdp->caps->features, mdss_rev);
  return mdp;
  }
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu

Re: [PATCH] drm/nouveau/dispnv04: fix null pointer dereference in nv17_tv_get_hd_modes

2024-06-25 Thread Lyude Paul
Reviewed-by: Lyude Paul 

I will push this and the other patch that you sent upstream in just a
moment, thanks!

On Tue, 2024-06-25 at 16:10 +0800, Ma Ke wrote:
> In nv17_tv_get_hd_modes(), the return value of drm_mode_duplicate()
> is
> assigned to mode, which will lead to a possible NULL pointer
> dereference
> on failure of drm_mode_duplicate(). The same applies to
> drm_cvt_mode().
> Add a check to avoid null pointer dereference.
> 
> Cc: sta...@vger.kernel.org
> Signed-off-by: Ma Ke 
> ---
>  drivers/gpu/drm/nouveau/dispnv04/tvnv17.c | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c
> b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c
> index 670c9739e5e1..9c3dc9a5bb46 100644
> --- a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c
> +++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c
> @@ -258,6 +258,8 @@ static int nv17_tv_get_hd_modes(struct
> drm_encoder *encoder,
>   if (modes[i].hdisplay == output_mode->hdisplay &&
>       modes[i].vdisplay == output_mode->vdisplay) {
>   mode = drm_mode_duplicate(encoder->dev,
> output_mode);
> + if (!mode)
> + continue;
>   mode->type |= DRM_MODE_TYPE_PREFERRED;
>  
>   } else {
> @@ -265,6 +267,8 @@ static int nv17_tv_get_hd_modes(struct
> drm_encoder *encoder,
>       modes[i].vdisplay, 60,
> false,
>       (output_mode->flags &
>   
> DRM_MODE_FLAG_INTERLACE), false);
> + if (!mode)
> + continue;
>   }
>  
>   /* CVT modes are sometimes unsuitable... */

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat



Re: [PATCH] drm/nouveau/dispnv04: fix null pointer dereference in nv17_tv_get_ld_modes

2024-06-25 Thread Lyude Paul
Reviewed-by: Lyude Paul 

On Tue, 2024-06-25 at 16:18 +0800, Ma Ke wrote:
> In nv17_tv_get_ld_modes(), the return value of drm_mode_duplicate()
> is
> assigned to mode, which will lead to a possible NULL pointer
> dereference
> on failure of drm_mode_duplicate(). Add a check to avoid npd.
> 
> Cc: sta...@vger.kernel.org
> Signed-off-by: Ma Ke 
> ---
>  drivers/gpu/drm/nouveau/dispnv04/tvnv17.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c
> b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c
> index 670c9739e5e1..4a08e61f3336 100644
> --- a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c
> +++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c
> @@ -209,6 +209,8 @@ static int nv17_tv_get_ld_modes(struct
> drm_encoder *encoder,
>   struct drm_display_mode *mode;
>  
>   mode = drm_mode_duplicate(encoder->dev, tv_mode);
> + if (!mode)
> + continue;
>  
>   mode->clock = tv_norm->tv_enc_mode.vrefresh *
>   mode->htotal / 1000 *

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat



[PATCH v2 1/2] drm/msm/adreno: De-spaghettify the use of memory barriers

2024-06-25 Thread Konrad Dybcio
Memory barriers help ensure instruction ordering, NOT time and order
of actual write arrival at other observers (e.g. memory-mapped IP).
On architectures employing weak memory ordering, the latter can be a
giant pain point, and it has been as part of this driver.

Moreover, the gpu_/gmu_ accessors already use non-relaxed versions of
readl/writel, which include r/w (respectively) barriers.

Replace the barriers with a readback (or drop altogether where possible)
that ensures the previous writes have exited the write buffer (as the CPU
must flush the write to the register it's trying to read back).

Signed-off-by: Konrad Dybcio 
---
 drivers/gpu/drm/msm/adreno/a6xx_gmu.c |  4 +---
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 10 ++
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index 0e3dfd4c2bc8..09d640165b18 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -466,9 +466,7 @@ static int a6xx_rpmh_start(struct a6xx_gmu *gmu)
int ret;
u32 val;
 
-   gmu_write(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ, 1 << 1);
-   /* Wait for the register to finish posting */
-   wmb();
+   gmu_write(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ, BIT(1));
 
ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_RSCC_CONTROL_ACK, val,
val & (1 << 1), 100, 1);
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index c98cdb1e9326..4083d0cad782 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -855,14 +855,16 @@ static int hw_init(struct msm_gpu *gpu)
/* Clear GBIF halt in case GX domain was not collapsed */
if (adreno_is_a619_holi(adreno_gpu)) {
gpu_write(gpu, REG_A6XX_GBIF_HALT, 0);
+   gpu_read(gpu, REG_A6XX_GBIF_HALT);
+
gpu_write(gpu, REG_A6XX_RBBM_GPR0_CNTL, 0);
-   /* Let's make extra sure that the GPU can access the memory.. */
-   mb();
+   gpu_read(gpu, REG_A6XX_RBBM_GPR0_CNTL);
} else if (a6xx_has_gbif(adreno_gpu)) {
gpu_write(gpu, REG_A6XX_GBIF_HALT, 0);
+   gpu_read(gpu, REG_A6XX_GBIF_HALT);
+
gpu_write(gpu, REG_A6XX_RBBM_GBIF_HALT, 0);
-   /* Let's make extra sure that the GPU can access the memory.. */
-   mb();
+   gpu_read(gpu, REG_A6XX_RBBM_GBIF_HALT);
}
 
/* Some GPUs are stubborn and take their sweet time to unhalt GBIF! */

-- 
2.45.2



[PATCH v2 2/2] Revert "drm/msm/a6xx: Poll for GBIF unhalt status in hw_init"

2024-06-25 Thread Konrad Dybcio
Commit c9707bcbd0f3 ("drm/msm/adreno: De-spaghettify the use of memory
barriers") made some fixups relating to write arrival, ensuring that
the GPU's memory interface has *really really really* been told to come
out of reset. That in turn rendered the hacky commit being reverted no
longer necessary.

Get rid of it.

This reverts commit b77532803d11f2b03efab2ebfd8c0061cd7f8b30.

Signed-off-by: Konrad Dybcio 
---
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index 4083d0cad782..03e23eef5126 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -867,10 +867,6 @@ static int hw_init(struct msm_gpu *gpu)
gpu_read(gpu, REG_A6XX_RBBM_GBIF_HALT);
}
 
-   /* Some GPUs are stubborn and take their sweet time to unhalt GBIF! */
-   if (adreno_is_a7xx(adreno_gpu) && a6xx_has_gbif(adreno_gpu))
-   spin_until(!gpu_read(gpu, REG_A6XX_GBIF_HALT_ACK));
-
gpu_write(gpu, REG_A6XX_RBBM_SECVID_TSB_CNTL, 0);
 
if (adreno_is_a619_holi(adreno_gpu))

-- 
2.45.2



[PATCH v2 0/2] Clean up barriers

2024-06-25 Thread Konrad Dybcio
Changes in v3:
- Drop the wrapper functions
- Drop the readback in GMU code
- Split the commit in two

Link to v2: 
https://lore.kernel.org/linux-arm-msm/20240509-topic-adreno-v2-1-b82a9f99b...@linaro.org/

Changes in v2:
- Introduce gpu_write_flush() and use it
- Don't accidentally break a630 by trying to write to non-existent GBIF

Link to v1: 
https://lore.kernel.org/linux-arm-msm/20240508-topic-adreno-v1-1-1babd05c1...@linaro.org/

Signed-off-by: Konrad Dybcio 
---
Konrad Dybcio (2):
  drm/msm/adreno: De-spaghettify the use of memory barriers
  Revert "drm/msm/a6xx: Poll for GBIF unhalt status in hw_init"

 drivers/gpu/drm/msm/adreno/a6xx_gmu.c |  4 +---
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 14 ++
 2 files changed, 7 insertions(+), 11 deletions(-)
---
base-commit: 0fc4bfab2cd45f9acb86c4f04b5191e114e901ed
change-id: 20240625-adreno_barriers-29f356742418

Best regards,
-- 
Konrad Dybcio 



[PATCH v4 4/5] drm/msm/adreno: Redo the speedbin assignment

2024-06-25 Thread Konrad Dybcio
There is no need to reinvent the wheel for simple read-match-set logic.

Make speedbin discovery and assignment generation independent.

This implicitly removes the bogus 0x80 / BIT(7) speed bin on A5xx,
which has no representation in hardware whatshowever.

Signed-off-by: Konrad Dybcio 
---
 drivers/gpu/drm/msm/adreno/a5xx_gpu.c   | 34 
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c   | 56 -
 drivers/gpu/drm/msm/adreno/adreno_gpu.c | 51 ++
 drivers/gpu/drm/msm/adreno/adreno_gpu.h |  3 --
 4 files changed, 45 insertions(+), 99 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
index c003f970189b..eed6a2eb1731 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -1704,38 +1704,6 @@ static const struct adreno_gpu_funcs funcs = {
.get_timestamp = a5xx_get_timestamp,
 };
 
-static void check_speed_bin(struct device *dev)
-{
-   struct nvmem_cell *cell;
-   u32 val;
-
-   /*
-* If the OPP table specifies a opp-supported-hw property then we have
-* to set something with dev_pm_opp_set_supported_hw() or the table
-* doesn't get populated so pick an arbitrary value that should
-* ensure the default frequencies are selected but not conflict with any
-* actual bins
-*/
-   val = 0x80;
-
-   cell = nvmem_cell_get(dev, "speed_bin");
-
-   if (!IS_ERR(cell)) {
-   void *buf = nvmem_cell_read(cell, NULL);
-
-   if (!IS_ERR(buf)) {
-   u8 bin = *((u8 *) buf);
-
-   val = (1 << bin);
-   kfree(buf);
-   }
-
-   nvmem_cell_put(cell);
-   }
-
-   devm_pm_opp_set_supported_hw(dev, &val, 1);
-}
-
 struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
 {
struct msm_drm_private *priv = dev->dev_private;
@@ -1763,8 +1731,6 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
 
a5xx_gpu->lm_leakage = 0x4E001A;
 
-   check_speed_bin(&pdev->dev);
-
nr_rings = 4;
 
if (config->info->revn == 510)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index 8ace096bb68c..f038e5f1fe59 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -2112,55 +2112,6 @@ static bool a6xx_progress(struct msm_gpu *gpu, struct 
msm_ringbuffer *ring)
return progress;
 }
 
-static u32 fuse_to_supp_hw(const struct adreno_info *info, u32 fuse)
-{
-   if (!info->speedbins)
-   return UINT_MAX;
-
-   for (int i = 0; info->speedbins[i].fuse != SHRT_MAX; i++)
-   if (info->speedbins[i].fuse == fuse)
-   return BIT(info->speedbins[i].speedbin);
-
-   return UINT_MAX;
-}
-
-static int a6xx_set_supported_hw(struct adreno_gpu *adreno_gpu,
-struct device *dev,
-const struct adreno_info *info)
-{
-   u32 supp_hw;
-   u32 speedbin;
-   int ret;
-
-   ret = adreno_read_speedbin(adreno_gpu, dev, &speedbin);
-   /*
-* -ENOENT means that the platform doesn't support speedbin which is
-* fine
-*/
-   if (ret == -ENOENT) {
-   return 0;
-   } else if (ret) {
-   dev_err_probe(dev, ret,
- "failed to read speed-bin. Some OPPs may not be 
supported by hardware\n");
-   return ret;
-   }
-
-   supp_hw = fuse_to_supp_hw(info, speedbin);
-
-   if (supp_hw == UINT_MAX) {
-   DRM_DEV_ERROR(dev,
-   "missing support for speed-bin: %u. Some OPPs may not 
be supported by hardware\n",
-   speedbin);
-   supp_hw = BIT(0); /* Default */
-   }
-
-   ret = devm_pm_opp_set_supported_hw(dev, &supp_hw, 1);
-   if (ret)
-   return ret;
-
-   return 0;
-}
-
 static const struct adreno_gpu_funcs funcs = {
.base = {
.get_param = adreno_get_param,
@@ -2292,13 +2243,6 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
 
a6xx_llc_slices_init(pdev, a6xx_gpu, is_a7xx);
 
-   ret = a6xx_set_supported_hw(adreno_gpu, &pdev->dev, config->info);
-   if (ret) {
-   a6xx_llc_slices_destroy(a6xx_gpu);
-   kfree(a6xx_gpu);
-   return ERR_PTR(ret);
-   }
-
if (is_a7xx)
ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs_a7xx, 1);
else if (adreno_has_gmu_wrapper(adreno_gpu))
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c 
b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 6ffd02f38499..5b4205b76cdf 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -1064,8 +1064,8 @@ void adreno_gpu_ocmem_cleanup(struct adreno_ocmem 
*adr

[PATCH v4 5/5] arm64: dts: qcom: sm8550: Wire up GPU speed bin & more OPPs

2024-06-25 Thread Konrad Dybcio
Add the speedbin masks to ensure only the desired OPPs are available on
chips of a given bin.

Using this, add the binned 719 MHz OPP and the non-binned 124.8 MHz.

Reviewed-by: Dmitry Baryshkov 
Signed-off-by: Konrad Dybcio 
---
 arch/arm64/boot/dts/qcom/sm8550.dtsi | 21 -
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi 
b/arch/arm64/boot/dts/qcom/sm8550.dtsi
index 4c9820adcf52..c1e3cec1540a 100644
--- a/arch/arm64/boot/dts/qcom/sm8550.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi
@@ -2119,48 +2119,67 @@ zap-shader {
memory-region = <&gpu_micro_code_mem>;
};
 
-   /* Speedbin needs more work on A740+, keep only lower 
freqs */
gpu_opp_table: opp-table {
compatible = "operating-points-v2";
 
+   opp-71900 {
+   opp-hz = /bits/ 64 <71900>;
+   opp-level = 
;
+   opp-supported-hw = <0x1>;
+   };
+
opp-68000 {
opp-hz = /bits/ 64 <68000>;
opp-level = 
;
+   opp-supported-hw = <0x3>;
};
 
opp-61500 {
opp-hz = /bits/ 64 <61500>;
opp-level = 
;
+   opp-supported-hw = <0x3>;
};
 
opp-55000 {
opp-hz = /bits/ 64 <55000>;
opp-level = ;
+   opp-supported-hw = <0x3>;
};
 
opp-47500 {
opp-hz = /bits/ 64 <47500>;
opp-level = 
;
+   opp-supported-hw = <0x3>;
};
 
opp-40100 {
opp-hz = /bits/ 64 <40100>;
opp-level = 
;
+   opp-supported-hw = <0x3>;
};
 
opp-34800 {
opp-hz = /bits/ 64 <34800>;
opp-level = 
;
+   opp-supported-hw = <0x3>;
};
 
opp-29500 {
opp-hz = /bits/ 64 <29500>;
opp-level = 
;
+   opp-supported-hw = <0x3>;
};
 
opp-22000 {
opp-hz = /bits/ 64 <22000>;
opp-level = 
;
+   opp-supported-hw = <0x3>;
+   };
+
+   opp-12480 {
+   opp-hz = /bits/ 64 <12480>;
+   opp-level = 
;
+   opp-supported-hw = <0x3>;
};
};
};

-- 
2.45.2



[PATCH v4 3/5] drm/msm/adreno: Define A530 speed bins explicitly

2024-06-25 Thread Konrad Dybcio
In preparation for commonizing the speedbin handling code.

Reviewed-by: Dmitry Baryshkov 
Signed-off-by: Konrad Dybcio 
---
 drivers/gpu/drm/msm/adreno/a5xx_catalog.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/msm/adreno/a5xx_catalog.c 
b/drivers/gpu/drm/msm/adreno/a5xx_catalog.c
index 455a953dee67..c98ad4ea558c 100644
--- a/drivers/gpu/drm/msm/adreno/a5xx_catalog.c
+++ b/drivers/gpu/drm/msm/adreno/a5xx_catalog.c
@@ -116,6 +116,12 @@ static const struct adreno_info a5xx_gpus[] = {
ADRENO_QUIRK_FAULT_DETECT_MASK,
.init = a5xx_gpu_init,
.zapfw = "a530_zap.mdt",
+   .speedbins = ADRENO_SPEEDBINS(
+   { 0, 0 },
+   { 1, 1 },
+   { 2, 2 },
+   { 3, 3 },
+   ),
}, {
.chip_ids = ADRENO_CHIP_IDS(0x05040001),
.family = ADRENO_5XX,

-- 
2.45.2



[PATCH v4 2/5] drm/msm/adreno: Add speedbin data for SM8550 / A740

2024-06-25 Thread Konrad Dybcio
Add speebin data for A740, as found on SM8550 and derivative SoCs.

For non-development SoCs it seems that "everything except FC_AC, FC_AF
should be speedbin 1", but what the values are for said "everything" are
not known, so that's an exercise left to the user..

Reviewed-by: Dmitry Baryshkov 
Signed-off-by: Konrad Dybcio 
---
 drivers/gpu/drm/msm/adreno/a6xx_catalog.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_catalog.c 
b/drivers/gpu/drm/msm/adreno/a6xx_catalog.c
index 53e33ff78411..8f280d69ba71 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_catalog.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_catalog.c
@@ -11,6 +11,9 @@
 #include "a6xx.xml.h"
 #include "a6xx_gmu.xml.h"
 
+#include 
+#include 
+
 static const struct adreno_reglist a612_hwcg[] = {
{REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x},
{REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x0220},
@@ -1208,6 +1211,11 @@ static const struct adreno_info a7xx_gpus[] = {
.protect = &a730_protect,
},
.address_space_size = SZ_16G,
+   .speedbins = ADRENO_SPEEDBINS(
+   { ADRENO_SKU_ID(SOCINFO_FC_AC), 0 },
+   { ADRENO_SKU_ID(SOCINFO_FC_AF), 0 },
+   /* Other feature codes (on prod SoCs) should match to 
speedbin 1 */
+   ),
}, {
.chip_ids = ADRENO_CHIP_IDS(0x43051401), /* "C520v2" */
.family = ADRENO_7XX_GEN3,

-- 
2.45.2



[PATCH v4 1/5] drm/msm/adreno: Implement SMEM-based speed bin

2024-06-25 Thread Konrad Dybcio
On recent (SM8550+) Snapdragon platforms, the GPU speed bin data is
abstracted through SMEM, instead of being directly available in a fuse.

Add support for SMEM-based speed binning, which includes getting
"feature code" and "product code" from said source and parsing them
to form something that lets us match OPPs against.

Due to the product code being ignored in the context of Adreno on
production parts (as of SM8650), hardcode it to SOCINFO_PC_UNKNOWN.

Signed-off-by: Konrad Dybcio 
---
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c  |  8 +++---
 drivers/gpu/drm/msm/adreno/adreno_device.c |  2 ++
 drivers/gpu/drm/msm/adreno/adreno_gpu.c| 41 +++---
 drivers/gpu/drm/msm/adreno/adreno_gpu.h|  7 -
 4 files changed, 50 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index c98cdb1e9326..8ace096bb68c 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -2124,13 +2124,15 @@ static u32 fuse_to_supp_hw(const struct adreno_info 
*info, u32 fuse)
return UINT_MAX;
 }
 
-static int a6xx_set_supported_hw(struct device *dev, const struct adreno_info 
*info)
+static int a6xx_set_supported_hw(struct adreno_gpu *adreno_gpu,
+struct device *dev,
+const struct adreno_info *info)
 {
u32 supp_hw;
u32 speedbin;
int ret;
 
-   ret = adreno_read_speedbin(dev, &speedbin);
+   ret = adreno_read_speedbin(adreno_gpu, dev, &speedbin);
/*
 * -ENOENT means that the platform doesn't support speedbin which is
 * fine
@@ -2290,7 +2292,7 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
 
a6xx_llc_slices_init(pdev, a6xx_gpu, is_a7xx);
 
-   ret = a6xx_set_supported_hw(&pdev->dev, config->info);
+   ret = a6xx_set_supported_hw(adreno_gpu, &pdev->dev, config->info);
if (ret) {
a6xx_llc_slices_destroy(a6xx_gpu);
kfree(a6xx_gpu);
diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c 
b/drivers/gpu/drm/msm/adreno/adreno_device.c
index 1e789ff6945e..e514346088f9 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -6,6 +6,8 @@
  * Copyright (c) 2014,2017 The Linux Foundation. All rights reserved.
  */
 
+#include 
+
 #include "adreno_gpu.h"
 
 bool hang_debug = false;
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c 
b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 1c6626747b98..6ffd02f38499 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -21,6 +21,9 @@
 #include "msm_gem.h"
 #include "msm_mmu.h"
 
+#include 
+#include 
+
 static u64 address_space_size = 0;
 MODULE_PARM_DESC(address_space_size, "Override for size of processes private 
GPU address space");
 module_param(address_space_size, ullong, 0600);
@@ -1061,9 +1064,39 @@ void adreno_gpu_ocmem_cleanup(struct adreno_ocmem 
*adreno_ocmem)
   adreno_ocmem->hdl);
 }
 
-int adreno_read_speedbin(struct device *dev, u32 *speedbin)
+int adreno_read_speedbin(struct adreno_gpu *adreno_gpu,
+struct device *dev, u32 *fuse)
 {
-   return nvmem_cell_read_variable_le_u32(dev, "speed_bin", speedbin);
+   u32 fcode;
+   int ret;
+
+   /*
+* Try reading the speedbin via a nvmem cell first
+* -ENOENT means "no nvmem-cells" and essentially means "old DT" or
+* "nvmem fuse is irrelevant", simply assume it's fine.
+*/
+   ret = nvmem_cell_read_variable_le_u32(dev, "speed_bin", fuse);
+   if (!ret)
+   return 0;
+   else if (ret != -ENOENT)
+   return dev_err_probe(dev, ret, "Couldn't read the speed bin 
fuse value\n");
+
+#ifdef CONFIG_QCOM_SMEM
+   /*
+* Only check the feature code - the product code only matters for
+* proto SoCs unavailable outside Qualcomm labs, as far as GPU bin
+* matching is concerned.
+*
+* Ignore EOPNOTSUPP, as not all SoCs expose this info through SMEM.
+*/
+   ret = qcom_smem_get_feature_code(&fcode);
+   if (!ret)
+   *fuse = ADRENO_SKU_ID(fcode);
+   else if (ret != -EOPNOTSUPP)
+   return dev_err_probe(dev, ret, "Couldn't get feature code from 
SMEM\n");
+#endif
+
+   return 0;
 }
 
 int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
@@ -1102,9 +1135,9 @@ int adreno_gpu_init(struct drm_device *drm, struct 
platform_device *pdev,
devm_pm_opp_set_clkname(dev, "core");
}
 
-   if (adreno_read_speedbin(dev, &speedbin) || !speedbin)
+   if (adreno_read_speedbin(adreno_gpu, dev, &speedbin) || !speedbin)
speedbin = 0x;
-   adreno_gpu->speedbin = (uint16_t) (0x & speedbin);
+   adreno_gpu->speedbin = speedbin;
 
gpu_name 

[PATCH v4 0/5] Add SMEM-based speedbin matching

2024-06-25 Thread Konrad Dybcio
Newer (SM8550+) SoCs don't seem to have a nice speedbin fuse anymore,
but instead rely on a set of combinations of "feature code" (FC) and
"product code" (PC) identifiers to match the bins. This series adds
support for that.

I suppose a qcom/for-soc immutable branch would be in order if we want
to land this in the upcoming cycle.

FWIW I preferred the fuses myself..

Signed-off-by: Konrad Dybcio 
---
Changes in v4:
- Drop applied qcom patches
- Make the fuse/speedbin fields u16 again (as Pcode is unused)
- Add comments explaining why there's only speedbin0 for 8550
- Fix some checkpatch fluff (code style)
- Rebase on next-20240625

Changes in v3:
- Wrap the argument usage in new preprocessor macros in braces (Bjorn)
- Make the SOCINFO_FC_INT_MAX define inclusive, adjust .h and .c (Bjorn)
- Pick up rbs
- Rebase on next-20240605
- Drop the already-applied ("Avoid a nullptr dereference when speedbin
  setting fails")

Changes in v2:
- Separate moving existing and adding new defines
- Fix kerneldoc copypasta
- Remove some wrong comments and defines
- Remove assumed "max" values for PCs and external FCs
- Improve some commit messages
- Return -EOPNOTSUPP instead of -EINVAL when calling p/fcode getters
  on socinfo older than v16
- Drop pcode getters and evaluation (doesn't matter for Adreno on
  non-proto SoCs)
- Rework the speedbin logic to be hopefully saner
- Link to v1: 
https://lore.kernel.org/r/20240405-topic-smem_speedbin-v1-0-ce2b86425...@linaro.org

---
Konrad Dybcio (5):
  drm/msm/adreno: Implement SMEM-based speed bin
  drm/msm/adreno: Add speedbin data for SM8550 / A740
  drm/msm/adreno: Define A530 speed bins explicitly
  drm/msm/adreno: Redo the speedbin assignment
  arm64: dts: qcom: sm8550: Wire up GPU speed bin & more OPPs

 arch/arm64/boot/dts/qcom/sm8550.dtsi   | 21 +++-
 drivers/gpu/drm/msm/adreno/a5xx_catalog.c  |  6 +++
 drivers/gpu/drm/msm/adreno/a5xx_gpu.c  | 34 
 drivers/gpu/drm/msm/adreno/a6xx_catalog.c  |  8 +++
 drivers/gpu/drm/msm/adreno/a6xx_gpu.c  | 54 ---
 drivers/gpu/drm/msm/adreno/adreno_device.c |  2 +
 drivers/gpu/drm/msm/adreno/adreno_gpu.c| 84 +++---
 drivers/gpu/drm/msm/adreno/adreno_gpu.h|  6 ++-
 8 files changed, 118 insertions(+), 97 deletions(-)
---
base-commit: 0fc4bfab2cd45f9acb86c4f04b5191e114e901ed
change-id: 20240404-topic-smem_speedbin-8deecd0bef0e

Best regards,
-- 
Konrad Dybcio 



Re: [PATCH] drm/lima: Mark simple_ondemand governor as softdep

2024-06-25 Thread Dragan Simic

Hello everyone,

Just checking, any further thoughts about this patch?

On 2024-06-18 21:22, Dragan Simic wrote:

On 2024-06-18 12:33, Dragan Simic wrote:

On 2024-06-18 10:13, Maxime Ripard wrote:

On Tue, Jun 18, 2024 at 04:01:26PM GMT, Qiang Yu wrote:

On Tue, Jun 18, 2024 at 12:33 PM Qiang Yu  wrote:
>
> I see the problem that initramfs need to build a module dependency chain,
> but lima does not call any symbol from simpleondemand governor module.
> softdep module seems to be optional while our dependency is hard one,
> can we just add MODULE_INFO(depends, _depends), or create a new
> macro called MODULE_DEPENDS()?


I had the same thoughts, because softdeps are for optional module
dependencies, while in this case it's a hard dependency.  Though,
I went with adding a softdep, simply because I saw no better option
available.


This doesn't work on my side because depmod generates modules.dep
by symbol lookup instead of modinfo section. So softdep may be our 
only

choice to add module dependency manually. I can accept the softdep
first, then make PM optional later.


I also thought about making devfreq optional in the Lima driver,
which would make this additional softdep much more appropriate.
Though, I'm not really sure that's a good approach, because not
having working devfreq for Lima might actually cause issues on
some devices, such as increased power consumption.

In other words, it might be better to have Lima probing fail if
devfreq can't be initialized, rather than having probing succeed
with no working devfreq.  Basically, failed probing is obvious,
while a warning in the kernel log about no devfreq might easily
be overlooked, causing regressions on some devices.


It's still super fragile, and depends on the user not changing the
policy. It should be solved in some other, more robust way.


I see, but I'm not really sure how to make it more robust?  In
the end, some user can blacklist the simple_ondemand governor
module, and we can't do much about it.

Introducing harddeps alongside softdeps would make sense from
the design standpoint, but the amount of required changes wouldn't
be trivial at all, on various levels.


After further investigation, it seems that the softdeps have
already seen a fair amount of abuse for what they actually aren't
intended, i.e. resolving hard dependencies.  For example, have
a look at the commit d5178578bcd4 (btrfs: directly call into
crypto framework for checksumming) [1] and the lines containing
MODULE_SOFTDEP() at the very end of fs/btrfs/super.c. [2]

If a filesystem driver can rely on the abuse of softdeps, which
admittedly are a bit fragile, I think we can follow the same
approach, at least for now.

With all that in mind, I think that accepting this patch, as well
as the related Panfrost patch, [3] should be warranted.  I'd keep
investigating the possibility of introducing harddeps in form
of MODULE_HARDDEP() and the related support in kmod project,
similar to the already existing softdep support, [4] but that
will inevitably take a lot of time, both for implementing it
and for reaching various Linux distributions, which is another
reason why accepting these patches seems reasonable.

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d5178578bcd4
[2] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/btrfs/super.c#n2593
[3] 
https://lore.kernel.org/dri-devel/4e1e00422a14db4e2a80870afb704405da16fd1b.1718655077.git.dsi...@manjaro.org/
[4] 
https://git.kernel.org/pub/scm/utils/kernel/kmod/kmod.git/commit/?id=49d8e0b59052999de577ab732b719cfbeb89504d


Re: [PATCH] drm/msm/adreno: De-spaghettify the use of memory barriers

2024-06-25 Thread Akhil P Oommen
On Tue, Jun 18, 2024 at 10:08:23PM +0530, Akhil P Oommen wrote:
> On Tue, Jun 04, 2024 at 07:35:04PM +0200, Konrad Dybcio wrote:
> > 
> > 
> > On 5/14/24 20:38, Akhil P Oommen wrote:
> > > On Wed, May 08, 2024 at 07:46:31PM +0200, Konrad Dybcio wrote:
> > > > Memory barriers help ensure instruction ordering, NOT time and order
> > > > of actual write arrival at other observers (e.g. memory-mapped IP).
> > > > On architectures employing weak memory ordering, the latter can be a
> > > > giant pain point, and it has been as part of this driver.
> > > > 
> > > > Moreover, the gpu_/gmu_ accessors already use non-relaxed versions of
> > > > readl/writel, which include r/w (respectively) barriers.
> > > > 
> > > > Replace the barriers with a readback that ensures the previous writes
> > > > have exited the write buffer (as the CPU must flush the write to the
> > > > register it's trying to read back) and subsequently remove the hack
> > > > introduced in commit b77532803d11 ("drm/msm/a6xx: Poll for GBIF unhalt
> > > > status in hw_init").
> > > > 
> > > > Fixes: b77532803d11 ("drm/msm/a6xx: Poll for GBIF unhalt status in 
> > > > hw_init")
> > > > Signed-off-by: Konrad Dybcio 
> > > > ---
> > > >   drivers/gpu/drm/msm/adreno/a6xx_gmu.c |  5 ++---
> > > >   drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 14 --
> > > >   2 files changed, 6 insertions(+), 13 deletions(-)
> > > 
> > > I prefer this version compared to the v2. A helper routine is
> > > unnecessary here because:
> > > 1. there are very few scenarios where we have to read back the same
> > > register.
> > > 2. we may accidently readback a write only register.
> > 
> > Which would still trigger an address dependency on the CPU, no?
> 
> Yes, but it is not a good idea to read a write-only register. We can't be
> sure about its effect on the endpoint.
> 
> > 
> > > 
> > > > 
> > > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
> > > > b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> > > > index 0e3dfd4c2bc8..4135a53b55a7 100644
> > > > --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> > > > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> > > > @@ -466,9 +466,8 @@ static int a6xx_rpmh_start(struct a6xx_gmu *gmu)
> > > > int ret;
> > > > u32 val;
> > > > -   gmu_write(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ, 1 << 1);
> > > > -   /* Wait for the register to finish posting */
> > > > -   wmb();
> > > > +   gmu_write(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ, BIT(1));
> > > > +   gmu_read(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ);
> > > 
> > > This is unnecessary because we are polling on a register on the same port 
> > > below. But I think we
> > > can replace "wmb()" above with "mb()" to avoid reordering between read
> > > and write IO instructions.
> > 
> > Ok on the dropping readback part
> > 
> > + AFAIU from Will's response, we can drop the barrier as well

Yes, let drop the the barrier.

> 
> Lets wait a bit on Will's response on compiler reordering.
> 
> > 
> > > 
> > > > ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_RSCC_CONTROL_ACK, val,
> > > > val & (1 << 1), 100, 1);
> > > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
> > > > b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > > index 973872ad0474..0acbc38b8e70 100644
> > > > --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> > > > @@ -1713,22 +1713,16 @@ static int hw_init(struct msm_gpu *gpu)
> > > > }
> > > > /* Clear GBIF halt in case GX domain was not collapsed */
> > > > +   gpu_write(gpu, REG_A6XX_GBIF_HALT, 0);
> > > 
> > > We need a full barrier here to avoid reordering. Also, lets add a
> > > comment about why we are doing this odd looking sequence.

Please ignore this.

> > > 
> > > > +   gpu_read(gpu, REG_A6XX_GBIF_HALT);
> > > > if (adreno_is_a619_holi(adreno_gpu)) {
> > > > -   gpu_write(gpu, REG_A6XX_GBIF_HALT, 0);
> > > > gpu_write(gpu, REG_A6XX_RBBM_GPR0_CNTL, 0);
> > > > -   /* Let's make extra sure that the GPU can access the 
> > > > memory.. */
> > > > -   mb();
> > > 
> > > We need a full barrier here.

Please ignore this.

> > > 
> > > > +   gpu_read(gpu, REG_A6XX_RBBM_GPR0_CNTL);
> > > > } else if (a6xx_has_gbif(adreno_gpu)) {
> > > > -   gpu_write(gpu, REG_A6XX_GBIF_HALT, 0);
> > > > gpu_write(gpu, REG_A6XX_RBBM_GBIF_HALT, 0);
> > > > -   /* Let's make extra sure that the GPU can access the 
> > > > memory.. */
> > > > -   mb();
> > > 
> > > We need a full barrier here.
> > 
> > Not sure we do between REG_A6XX_GBIF_HALT & 
> > REG_A6XX_RBBM_(GBIF_HALT/GPR0_CNTL),
> > but I suppose keeping the one after REG_A6XX_RBBM_(GBIF_HALT/GPR0_CNTL) 
> > makes
> > sense to avoid the possibility of configuring the GPU before it can access 
> > DRAM..
> 
> Techinically, I think we don't need a barrier or the below read back.
> Because the above wr

Re: [PATCH] drm/msm/a6xx: request memory region

2024-06-25 Thread Rob Clark
On Tue, Jun 25, 2024 at 10:59 AM Akhil P Oommen
 wrote:
>
> On Fri, Jun 21, 2024 at 02:09:58PM -0700, Rob Clark wrote:
> > On Sat, Jun 8, 2024 at 8:44 AM Kiarash Hajian
> >  wrote:
> > >
> > > The driver's memory regions are currently just ioremap()ed, but not
> > > reserved through a request. That's not a bug, but having the request is
> > > a little more robust.
> > >
> > > Implement the region-request through the corresponding managed
> > > devres-function.
> > >
> > > Signed-off-by: Kiarash Hajian 
> > > ---
> > > Changes in v6:
> > > -Fix compile error
> > > -Link to v5: 
> > > https://lore.kernel.org/all/20240607-memory-v1-1-8664f52fc...@gmail.com
> > >
> > > Changes in v5:
> > > - Fix error hanlding problems.
> > > - Link to v4: 
> > > https://lore.kernel.org/r/20240512-msm-adreno-memory-region-v4-1-3881a6408...@gmail.com
> > >
> > > Changes in v4:
> > > - Combine v3 commits into a singel commit
> > > - Link to v3: 
> > > https://lore.kernel.org/r/20240512-msm-adreno-memory-region-v3-0-0a728ad45...@gmail.com
> > >
> > > Changes in v3:
> > > - Remove redundant devm_iounmap calls, relying on devres for 
> > > automatic resource cleanup.
> > >
> > > Changes in v2:
> > > - update the subject prefix to "drm/msm/a6xx:", to match the majority 
> > > of other changes to this file.
> > > ---
> > >  drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 33 
> > > +++--
> > >  1 file changed, 11 insertions(+), 22 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
> > > b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> > > index 8bea8ef26f77..d26cc6254ef9 100644
> > > --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> > > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> > > @@ -525,7 +525,7 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
> > > bool pdc_in_aop = false;
> > >
> > > if (IS_ERR(pdcptr))
> > > -   goto err;
> > > +   return;
> > >
> > > if (adreno_is_a650(adreno_gpu) ||
> > > adreno_is_a660_family(adreno_gpu) ||
> > > @@ -541,7 +541,7 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
> > > if (!pdc_in_aop) {
> > > seqptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc_seq");
> > > if (IS_ERR(seqptr))
> > > -   goto err;
> > > +   return;
> > > }
> > >
> > > /* Disable SDE clock gating */
> > > @@ -633,12 +633,6 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
> > > wmb();
> > >
> > > a6xx_rpmh_stop(gmu);
> > > -
> > > -err:
> > > -   if (!IS_ERR_OR_NULL(pdcptr))
> > > -   iounmap(pdcptr);
> > > -   if (!IS_ERR_OR_NULL(seqptr))
> > > -   iounmap(seqptr);
> > >  }
> > >
> > >  /*
> > > @@ -1503,7 +1497,7 @@ static void __iomem *a6xx_gmu_get_mmio(struct 
> > > platform_device *pdev,
> > > return ERR_PTR(-EINVAL);
> > > }
> > >
> > > -   ret = ioremap(res->start, resource_size(res));
> > > +   ret = devm_ioremap_resource(&pdev->dev, res);
> >
> > So, this doesn't actually work, failing in __request_region_locked(),
> > because the gmu region partially overlaps with the gpucc region (which
> > is busy).  I think this is intentional, since gmu is controlling the
> > gpu clocks, etc.  In particular REG_A6XX_GPU_CC_GX_GDSCR is in this
> > overlapping region.  Maybe Akhil knows more about GMU.
>
> We don't really need to map gpucc region from driver on behalf of gmu.
> Since we don't access any gpucc register from drm-msm driver, we can
> update the range size to correct this. But due to backward compatibility
> requirement with older dt, can we still enable region locking? I prefer
> it if that is possible.

Actually, when I reduced the region size to not overlap with gpucc,
the region is smaller than REG_A6XX_GPU_CC_GX_GDSCR * 4.

So I guess that register is actually part of gpucc?

BR,
-R

> FYI, kgsl accesses gpucc registers to ensure gdsc has collapsed. So
> gpucc region has to be mapped by kgsl and that is reflected in the kgsl
> device tree.
>
> -Akhil
>
> >
> > BR,
> > -R
> >
> > > if (!ret) {
> > > DRM_DEV_ERROR(&pdev->dev, "Unable to map the %s 
> > > registers\n", name);
> > > return ERR_PTR(-EINVAL);
> > > @@ -1613,13 +1607,13 @@ int a6xx_gmu_wrapper_init(struct a6xx_gpu 
> > > *a6xx_gpu, struct device_node *node)
> > > gmu->mmio = a6xx_gmu_get_mmio(pdev, "gmu");
> > > if (IS_ERR(gmu->mmio)) {
> > > ret = PTR_ERR(gmu->mmio);
> > > -   goto err_mmio;
> > > +   goto err_cleanup;
> > > }
> > >
> > > gmu->cxpd = dev_pm_domain_attach_by_name(gmu->dev, "cx");
> > > if (IS_ERR(gmu->cxpd)) {
> > > ret = PTR_ERR(gmu->cxpd);
> > > -   goto err_mmio;
> > > +   goto err_cleanup;
> > > }
> > >
> > > if (!device_link_add(gmu->dev, gmu->cxpd, DL

Re: [PATCH] drm/msm/adreno: De-spaghettify the use of memory barriers

2024-06-25 Thread Akhil P Oommen
On Thu, Jun 20, 2024 at 02:04:01PM +0100, Will Deacon wrote:
> On Tue, Jun 18, 2024 at 09:41:58PM +0530, Akhil P Oommen wrote:
> > On Tue, Jun 04, 2024 at 03:40:56PM +0100, Will Deacon wrote:
> > > On Thu, May 16, 2024 at 01:55:26PM -0500, Andrew Halaney wrote:
> > > > On Thu, May 16, 2024 at 08:20:05PM GMT, Akhil P Oommen wrote:
> > > > > On Thu, May 16, 2024 at 08:15:34AM -0500, Andrew Halaney wrote:
> > > > > > If I understand correctly, you don't need any memory barrier.
> > > > > > writel()/readl()'s are ordered to the same endpoint. That goes for 
> > > > > > all
> > > > > > the reordering/barrier comments mentioned below too.
> > > > > > 
> > > > > > device-io.rst:
> > > > > > 
> > > > > > The read and write functions are defined to be ordered. That is 
> > > > > > the
> > > > > > compiler is not permitted to reorder the I/O sequence. When the 
> > > > > > ordering
> > > > > > can be compiler optimised, you can use __readb() and friends to
> > > > > > indicate the relaxed ordering. Use this with care.
> > > > > > 
> > > > > > memory-barriers.txt:
> > > > > > 
> > > > > >  (*) readX(), writeX():
> > > > > > 
> > > > > > The readX() and writeX() MMIO accessors take a pointer to 
> > > > > > the
> > > > > > peripheral being accessed as an __iomem * parameter. For 
> > > > > > pointers
> > > > > > mapped with the default I/O attributes (e.g. those returned 
> > > > > > by
> > > > > > ioremap()), the ordering guarantees are as follows:
> > > > > > 
> > > > > > 1. All readX() and writeX() accesses to the same peripheral 
> > > > > > are ordered
> > > > > >with respect to each other. This ensures that MMIO 
> > > > > > register accesses
> > > > > >by the same CPU thread to a particular device will 
> > > > > > arrive in program
> > > > > >order.
> > > > > > 
> > > > > 
> > > > > In arm64, a writel followed by readl translates to roughly the 
> > > > > following
> > > > > sequence: dmb_wmb(), __raw_writel(), __raw_readl(), dmb_rmb(). I am 
> > > > > not
> > > > > sure what is stopping compiler from reordering  __raw_writel() and 
> > > > > __raw_readl()
> > > > > above? I am assuming iomem cookie is ignored during compilation.
> > > > 
> > > > It seems to me that is due to some usage of volatile there in
> > > > __raw_writel() etc, but to be honest after reading about volatile and
> > > > some threads from gcc mailing lists, I don't have a confident answer :)
> > > > 
> > > > > 
> > > > > Added Will to this thread if he can throw some light on this.
> > > > 
> > > > Hopefully Will can school us.
> > > 
> > > The ordering in this case is ensured by the memory attributes used for
> > > ioremap(). When an MMIO region is mapped using Device-nGnRE attributes
> > > (as it the case for ioremap()), the "nR" part means "no reordering", so
> > > readX() and writeX() to that region are ordered wrt each other.
> > 
> > But that avoids only HW reordering, doesn't it? What about *compiler 
> > reordering* in the
> > case of a writel following by a readl which translates to:
> > 1: dmb_wmb()
> > 2: __raw_writel() -> roughly "asm volatile('str')
> > 3: __raw_readl() -> roughly "asm volatile('ldr')
> > 4: dmb_rmb()
> > 
> > Is the 'volatile' keyword sufficient to avoid reordering between (2) and 
> > (3)? Or
> > do we need a "memory" clobber to inhibit reordering?
> > 
> > This is still not clear to me even after going through some compiler 
> > documentions.
> 
> I don't think the compiler should reorder volatile asm blocks wrt each
> other.
> 

Thanks Will for confirmation.

-Akhil.

> Will


Re: [PATCH] drm/msm/a6xx: request memory region

2024-06-25 Thread Akhil P Oommen
On Fri, Jun 21, 2024 at 02:09:58PM -0700, Rob Clark wrote:
> On Sat, Jun 8, 2024 at 8:44 AM Kiarash Hajian
>  wrote:
> >
> > The driver's memory regions are currently just ioremap()ed, but not
> > reserved through a request. That's not a bug, but having the request is
> > a little more robust.
> >
> > Implement the region-request through the corresponding managed
> > devres-function.
> >
> > Signed-off-by: Kiarash Hajian 
> > ---
> > Changes in v6:
> > -Fix compile error
> > -Link to v5: 
> > https://lore.kernel.org/all/20240607-memory-v1-1-8664f52fc...@gmail.com
> >
> > Changes in v5:
> > - Fix error hanlding problems.
> > - Link to v4: 
> > https://lore.kernel.org/r/20240512-msm-adreno-memory-region-v4-1-3881a6408...@gmail.com
> >
> > Changes in v4:
> > - Combine v3 commits into a singel commit
> > - Link to v3: 
> > https://lore.kernel.org/r/20240512-msm-adreno-memory-region-v3-0-0a728ad45...@gmail.com
> >
> > Changes in v3:
> > - Remove redundant devm_iounmap calls, relying on devres for automatic 
> > resource cleanup.
> >
> > Changes in v2:
> > - update the subject prefix to "drm/msm/a6xx:", to match the majority 
> > of other changes to this file.
> > ---
> >  drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 33 
> > +++--
> >  1 file changed, 11 insertions(+), 22 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c 
> > b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> > index 8bea8ef26f77..d26cc6254ef9 100644
> > --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> > @@ -525,7 +525,7 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
> > bool pdc_in_aop = false;
> >
> > if (IS_ERR(pdcptr))
> > -   goto err;
> > +   return;
> >
> > if (adreno_is_a650(adreno_gpu) ||
> > adreno_is_a660_family(adreno_gpu) ||
> > @@ -541,7 +541,7 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
> > if (!pdc_in_aop) {
> > seqptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc_seq");
> > if (IS_ERR(seqptr))
> > -   goto err;
> > +   return;
> > }
> >
> > /* Disable SDE clock gating */
> > @@ -633,12 +633,6 @@ static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
> > wmb();
> >
> > a6xx_rpmh_stop(gmu);
> > -
> > -err:
> > -   if (!IS_ERR_OR_NULL(pdcptr))
> > -   iounmap(pdcptr);
> > -   if (!IS_ERR_OR_NULL(seqptr))
> > -   iounmap(seqptr);
> >  }
> >
> >  /*
> > @@ -1503,7 +1497,7 @@ static void __iomem *a6xx_gmu_get_mmio(struct 
> > platform_device *pdev,
> > return ERR_PTR(-EINVAL);
> > }
> >
> > -   ret = ioremap(res->start, resource_size(res));
> > +   ret = devm_ioremap_resource(&pdev->dev, res);
> 
> So, this doesn't actually work, failing in __request_region_locked(),
> because the gmu region partially overlaps with the gpucc region (which
> is busy).  I think this is intentional, since gmu is controlling the
> gpu clocks, etc.  In particular REG_A6XX_GPU_CC_GX_GDSCR is in this
> overlapping region.  Maybe Akhil knows more about GMU.

We don't really need to map gpucc region from driver on behalf of gmu.
Since we don't access any gpucc register from drm-msm driver, we can
update the range size to correct this. But due to backward compatibility
requirement with older dt, can we still enable region locking? I prefer
it if that is possible.

FYI, kgsl accesses gpucc registers to ensure gdsc has collapsed. So
gpucc region has to be mapped by kgsl and that is reflected in the kgsl
device tree.

-Akhil

> 
> BR,
> -R
> 
> > if (!ret) {
> > DRM_DEV_ERROR(&pdev->dev, "Unable to map the %s 
> > registers\n", name);
> > return ERR_PTR(-EINVAL);
> > @@ -1613,13 +1607,13 @@ int a6xx_gmu_wrapper_init(struct a6xx_gpu 
> > *a6xx_gpu, struct device_node *node)
> > gmu->mmio = a6xx_gmu_get_mmio(pdev, "gmu");
> > if (IS_ERR(gmu->mmio)) {
> > ret = PTR_ERR(gmu->mmio);
> > -   goto err_mmio;
> > +   goto err_cleanup;
> > }
> >
> > gmu->cxpd = dev_pm_domain_attach_by_name(gmu->dev, "cx");
> > if (IS_ERR(gmu->cxpd)) {
> > ret = PTR_ERR(gmu->cxpd);
> > -   goto err_mmio;
> > +   goto err_cleanup;
> > }
> >
> > if (!device_link_add(gmu->dev, gmu->cxpd, DL_FLAG_PM_RUNTIME)) {
> > @@ -1635,7 +1629,7 @@ int a6xx_gmu_wrapper_init(struct a6xx_gpu *a6xx_gpu, 
> > struct device_node *node)
> > gmu->gxpd = dev_pm_domain_attach_by_name(gmu->dev, "gx");
> > if (IS_ERR(gmu->gxpd)) {
> > ret = PTR_ERR(gmu->gxpd);
> > -   goto err_mmio;
> > +   goto err_cleanup;
> > }
> >
> > gmu->initialized = true;
> > @@ -1645,9 +1639,7 @@ int a6xx_gmu_wrapper_init(struct a6xx_gpu *a6xx_gpu, 

[Bug 218900] amdgpu: Fatal error during GPU init

2024-06-25 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=218900

--- Comment #20 from Jean-Denis Girard (jd.gir...@sysnux.pf) ---
Yes, I confirm the patch "iommu/amd: Fix GT feature enablement again" applied
to 6.10-rc5 fixes resume on my machine.

Thanks for prompt reply!

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

Re: [PATCH v5 1/5] drm/panel: jd9365da: Modify the method of sending commands

2024-06-25 Thread Jessica Zhang




On 6/25/2024 5:13 AM, zhaoxiong lv wrote:

On Tue, Jun 25, 2024 at 7:41 AM Jessica Zhang  wrote:




On 6/24/2024 7:19 AM, Zhaoxiong Lv wrote:

Currently, the init_code of the jd9365da driver is placed
in the enable() function and sent, but this seems to take
a long time. It takes 17ms to send each instruction (an init
code consists of about 200 instructions), so it takes
about 3.5s to send the init_code. So we moved the sending
of the inti_code to the prepare() function, and each
instruction seemed to take only 25μs.

We checked the DSI host and found that the difference in
command sending time is caused by the different modes of
the DSI host in prepare() and enable() functions.
Our DSI Host only supports sending cmd in LP mode, The
prepare() function can directly send init_code (LP->cmd)
in LP mode, but the enable() function is in HS mode and
needs to switch to LP mode before sending init code
(HS->LP->cmd->HS). Therefore, it takes longer to send
the command.

Signed-off-by: Zhaoxiong Lv 


Hi Zhaoxiong,

Just curious, if the host expects that commands are sent in LP mode, why
isn't the MIPI_DSI_MODE_LPM flag set before sending the DCS commands?

Thanks,

Jessica Zhang


hi jessica

We have tried to set dsi->mode_flags to MIPI_DSI_MODE_LPM in the
probe() function,
but this seems to still happen. MTK colleagues believe that the host
dsi configuration is
still in LP mode during the prepare() function, and when in the
enable() function, the host
dsi is already in HS mode. However, since the command must be sent in
LP mode, it will
switch back and forth between HS->LP->HS.

Add Mediatek colleagues(shuijing...@mediatek.corp-partner.google.com)


Got it. Even drivers that call their init commands in prepare() set the 
LPM flag [1][2] when applicable so I was just wondering why this driver 
doesn't seem to set LPM at all even though it is going into LP mode.


[1] 
https://elixir.bootlin.com/linux/v6.10-rc5/source/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c#L46


[2] 
https://elixir.bootlin.com/linux/v6.10-rc5/source/drivers/gpu/drm/panel/panel-visionox-r66451.c#L46








---
Changes between V5 and V4:
- 1. No changes.

V4:https://lore.kernel.org/all/20240620080509.18504-2-lvzhaoxi...@huaqin.corp-partner.google.com/

Changes between V4 and V3:
- 1. Only move mipi_dsi_dcs_write_buffer from enable() function to prepare() 
function,
-and no longer use mipi_dsi_dcs_write_seq_multi.

V3:https://lore.kernel.org/all/20240614145510.22965-2-lvzhaoxi...@huaqin.corp-partner.google.com/

---
   .../gpu/drm/panel/panel-jadard-jd9365da-h3.c  | 24 +--
   1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c 
b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c
index 4879835fe101..a9c483a7b3fa 100644
--- a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c
+++ b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c
@@ -52,21 +52,9 @@ static int jadard_enable(struct drm_panel *panel)
   {
   struct device *dev = panel->dev;
   struct jadard *jadard = panel_to_jadard(panel);
- const struct jadard_panel_desc *desc = jadard->desc;
   struct mipi_dsi_device *dsi = jadard->dsi;
- unsigned int i;
   int err;

- msleep(10);
-
- for (i = 0; i < desc->num_init_cmds; i++) {
- const struct jadard_init_cmd *cmd = &desc->init_cmds[i];
-
- err = mipi_dsi_dcs_write_buffer(dsi, cmd->data, 
JD9365DA_INIT_CMD_LEN);
- if (err < 0)
- return err;
- }
-
   msleep(120);

   err = mipi_dsi_dcs_exit_sleep_mode(dsi);
@@ -100,6 +88,8 @@ static int jadard_disable(struct drm_panel *panel)
   static int jadard_prepare(struct drm_panel *panel)
   {
   struct jadard *jadard = panel_to_jadard(panel);
+ const struct jadard_panel_desc *desc = jadard->desc;
+ unsigned int i;
   int ret;

   ret = regulator_enable(jadard->vccio);
@@ -117,7 +107,15 @@ static int jadard_prepare(struct drm_panel *panel)
   msleep(10);

   gpiod_set_value(jadard->reset, 1);
- msleep(120);
+ msleep(130);
+
+ for (i = 0; i < desc->num_init_cmds; i++) {
+ const struct jadard_init_cmd *cmd = &desc->init_cmds[i];
+
+ ret = mipi_dsi_dcs_write_buffer(dsi, cmd->data, 
JD9365DA_INIT_CMD_LEN);
+ if (ret < 0)
+ return ret;
+ }

   return 0;
   }
--
2.17.1



Re: [PATCH v2 4/7] drm/msm/adreno: Add speedbin data for SM8550 / A740

2024-06-25 Thread Konrad Dybcio
On 25.06.2024 7:21 PM, Rob Clark wrote:
> On Wed, Jun 5, 2024 at 1:10 PM Konrad Dybcio  wrote:
>>
>> Add speebin data for A740, as found on SM8550 and derivative SoCs.
>>
>> Reviewed-by: Dmitry Baryshkov 
>> Signed-off-by: Konrad Dybcio 
>> ---
>>  drivers/gpu/drm/msm/adreno/adreno_device.c | 4 
>>  1 file changed, 4 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c 
>> b/drivers/gpu/drm/msm/adreno/adreno_device.c
>> index 901ef767e491..e00eef8099ae 100644
>> --- a/drivers/gpu/drm/msm/adreno/adreno_device.c
>> +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
>> @@ -570,6 +570,10 @@ static const struct adreno_info gpulist[] = {
>> .zapfw = "a740_zap.mdt",
>> .hwcg = a740_hwcg,
>> .address_space_size = SZ_16G,
>> +   .speedbins = ADRENO_SPEEDBINS(
>> +   { ADRENO_SKU_ID(SOCINFO_FC_AC), 0 },
>> +   { ADRENO_SKU_ID(SOCINFO_FC_AF), 0 },
> 
> Did you really mean for these both to map to the same speedbin?

Yes

There were more entries previously but the info was unclear and
different between BSPs..

For non-development SoCs it seems that "everything except FC_AC, FC_AF
should be speedbin 1", but what the values are for said "everything" are
not known, so that's an exercise left to the user..

Konrad


Re: [PATCH v2 3/7] drm/msm/adreno: Implement SMEM-based speed bin

2024-06-25 Thread Konrad Dybcio
On 25.06.2024 7:20 PM, Rob Clark wrote:
> On Wed, Jun 5, 2024 at 1:10 PM Konrad Dybcio  wrote:
>>

[...]

>>  struct adreno_speedbin {
>> -   uint16_t fuse;
>> +   /* <= 16-bit for NVMEM fuses, 32b for SOCID values */
>> +   uint32_t fuse;
>> +/* As of SM8650, PCODE on production SoCs is meaningless wrt the GPU bin */
>> +#define ADRENO_SKU_ID_FCODEGENMASK(15, 0)
>> +#define ADRENO_SKU_ID(fcode)   (SOCINFO_PC_UNKNOWN << 16 | fcode)
> 
> So, as I understand this, we are actually only using the feature-code,
> which is the low 16b.  So in reality the "fuse" is still only 16b?

Right, a leftover from when the pcode was used too.. None of them should
exceed 16b.

Konrad


Re: [PATCH v2 4/7] drm/msm/adreno: Add speedbin data for SM8550 / A740

2024-06-25 Thread Rob Clark
On Wed, Jun 5, 2024 at 1:10 PM Konrad Dybcio  wrote:
>
> Add speebin data for A740, as found on SM8550 and derivative SoCs.
>
> Reviewed-by: Dmitry Baryshkov 
> Signed-off-by: Konrad Dybcio 
> ---
>  drivers/gpu/drm/msm/adreno/adreno_device.c | 4 
>  1 file changed, 4 insertions(+)
>
> diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c 
> b/drivers/gpu/drm/msm/adreno/adreno_device.c
> index 901ef767e491..e00eef8099ae 100644
> --- a/drivers/gpu/drm/msm/adreno/adreno_device.c
> +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
> @@ -570,6 +570,10 @@ static const struct adreno_info gpulist[] = {
> .zapfw = "a740_zap.mdt",
> .hwcg = a740_hwcg,
> .address_space_size = SZ_16G,
> +   .speedbins = ADRENO_SPEEDBINS(
> +   { ADRENO_SKU_ID(SOCINFO_FC_AC), 0 },
> +   { ADRENO_SKU_ID(SOCINFO_FC_AF), 0 },

Did you really mean for these both to map to the same speedbin?

> +   ),
> }, {
> .chip_ids = ADRENO_CHIP_IDS(0x43051401), /* "C520v2" */
> .family = ADRENO_7XX_GEN3,
>
> --
> 2.43.0
>


Re: [PATCH v2 3/7] drm/msm/adreno: Implement SMEM-based speed bin

2024-06-25 Thread Rob Clark
On Wed, Jun 5, 2024 at 1:10 PM Konrad Dybcio  wrote:
>
> On recent (SM8550+) Snapdragon platforms, the GPU speed bin data is
> abstracted through SMEM, instead of being directly available in a fuse.
>
> Add support for SMEM-based speed binning, which includes getting
> "feature code" and "product code" from said source and parsing them
> to form something that lets us match OPPs against.
>
> Due to the product code being ignored in the context of Adreno on
> production parts (as of SM8650), hardcode it to SOCINFO_PC_UNKNOWN.
>
> Signed-off-by: Konrad Dybcio 
> ---
>  drivers/gpu/drm/msm/adreno/a6xx_gpu.c  |  8 +++---
>  drivers/gpu/drm/msm/adreno/adreno_device.c |  2 ++
>  drivers/gpu/drm/msm/adreno/adreno_gpu.c| 41 
> +++---
>  drivers/gpu/drm/msm/adreno/adreno_gpu.h| 12 ++---
>  4 files changed, 53 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
> b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> index 973872ad0474..3f84417ff027 100644
> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> @@ -2894,13 +2894,15 @@ static u32 fuse_to_supp_hw(const struct adreno_info 
> *info, u32 fuse)
> return UINT_MAX;
>  }
>
> -static int a6xx_set_supported_hw(struct device *dev, const struct 
> adreno_info *info)
> +static int a6xx_set_supported_hw(struct adreno_gpu *adreno_gpu,
> +struct device *dev,
> +const struct adreno_info *info)
>  {
> u32 supp_hw;
> u32 speedbin;
> int ret;
>
> -   ret = adreno_read_speedbin(dev, &speedbin);
> +   ret = adreno_read_speedbin(adreno_gpu, dev, &speedbin);
> /*
>  * -ENOENT means that the platform doesn't support speedbin which is
>  * fine
> @@ -3060,7 +3062,7 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
>
> a6xx_llc_slices_init(pdev, a6xx_gpu, is_a7xx);
>
> -   ret = a6xx_set_supported_hw(&pdev->dev, config->info);
> +   ret = a6xx_set_supported_hw(adreno_gpu, &pdev->dev, config->info);
> if (ret) {
> a6xx_llc_slices_destroy(a6xx_gpu);
> kfree(a6xx_gpu);
> diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c 
> b/drivers/gpu/drm/msm/adreno/adreno_device.c
> index c3703a51287b..901ef767e491 100644
> --- a/drivers/gpu/drm/msm/adreno/adreno_device.c
> +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c
> @@ -6,6 +6,8 @@
>   * Copyright (c) 2014,2017 The Linux Foundation. All rights reserved.
>   */
>
> +#include 
> +
>  #include "adreno_gpu.h"
>
>  bool hang_debug = false;
> diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c 
> b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> index 074fb498706f..055072260b3d 100644
> --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
> @@ -21,6 +21,9 @@
>  #include "msm_gem.h"
>  #include "msm_mmu.h"
>
> +#include 
> +#include 
> +
>  static u64 address_space_size = 0;
>  MODULE_PARM_DESC(address_space_size, "Override for size of processes private 
> GPU address space");
>  module_param(address_space_size, ullong, 0600);
> @@ -1057,9 +1060,39 @@ void adreno_gpu_ocmem_cleanup(struct adreno_ocmem 
> *adreno_ocmem)
>adreno_ocmem->hdl);
>  }
>
> -int adreno_read_speedbin(struct device *dev, u32 *speedbin)
> +int adreno_read_speedbin(struct adreno_gpu *adreno_gpu,
> +struct device *dev, u32 *fuse)
>  {
> -   return nvmem_cell_read_variable_le_u32(dev, "speed_bin", speedbin);
> +   u32 fcode;
> +   int ret;
> +
> +   /*
> +* Try reading the speedbin via a nvmem cell first
> +* -ENOENT means "no nvmem-cells" and essentially means "old DT" or
> +* "nvmem fuse is irrelevant", simply assume it's fine.
> +*/
> +   ret = nvmem_cell_read_variable_le_u32(dev, "speed_bin", fuse);
> +   if (!ret)
> +   return 0;
> +   else if (ret != -ENOENT)
> +   return dev_err_probe(dev, ret, "Couldn't read the speed bin 
> fuse value\n");
> +
> +#ifdef CONFIG_QCOM_SMEM
> +   /*
> +* Only check the feature code - the product code only matters for
> +* proto SoCs unavailable outside Qualcomm labs, as far as GPU bin
> +* matching is concerned.
> +*
> +* Ignore EOPNOTSUPP, as not all SoCs expose this info through SMEM.
> +*/
> +   ret = qcom_smem_get_feature_code(&fcode);
> +   if (!ret) {
> +   *fuse = ADRENO_SKU_ID(fcode);
> +   } else if (ret != -EOPNOTSUPP)
> +   return dev_err_probe(dev, ret, "Couldn't get feature code 
> from SMEM\n");
> +#endif
> +
> +   return 0;
>  }
>
>  int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
> @@ -1098,9 +1131,9 @@ int adreno_gpu_init(struct drm_device *drm, struct 
> platform_device *pdev,
> devm_pm_opp_set_clkname(dev, "core");
>  

[Bug 218900] amdgpu: Fatal error during GPU init

2024-06-25 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=218900

--- Comment #19 from Vasant Hegde (vasant.he...@amd.com) ---
Unfortunately there was another big in suspend/resume path. Can you please test
with below patch?

https://lore.kernel.org/linux-iommu/znqzxycu8bn32...@8bytes.org/T/#m1cd1520facb8b758efdf7a8c0261f9ee2ec217d7



-Vasant

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

[Bug 218900] amdgpu: Fatal error during GPU init

2024-06-25 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=218900

--- Comment #18 from Jean-Denis Girard (jd.gir...@sysnux.pf) ---
Created attachment 306495
  --> https://bugzilla.kernel.org/attachment.cgi?id=306495&action=edit
Complete dmesg

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

[Bug 218900] amdgpu: Fatal error during GPU init

2024-06-25 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=218900

Jean-Denis Girard (jd.gir...@sysnux.pf) changed:

   What|Removed |Added

 CC||jd.gir...@sysnux.pf

--- Comment #17 from Jean-Denis Girard (jd.gir...@sysnux.pf) ---
I seem to have a similar problem on 6.10-rc5 after suspend. I get a black
screen on resume.

[  269.157149] amdgpu :02:00.0: amdgpu: reserve 0x40 from 0xf41f80
for PSP TMR
[  269.159956] iommu ivhd0: AMD-Vi: Event logged [ILLEGAL_DEV_TABLE_ENTRY
device=:02:00.0 pasid=0x0 address=0x13140 flags=0x0180]
[  269.159960] AMD-Vi: DTE[0]: 6193
[  269.159962] AMD-Vi: DTE[1]: 1001049e000b
[  269.159963] AMD-Vi: DTE[2]: 20013c610013
[  269.159963] AMD-Vi: DTE[3]: 
[  269.160104] amdgpu :02:00.0: amdgpu: failed to load ucode SDMA0(0x1) 
[  269.160108] amdgpu :02:00.0: amdgpu: psp gfx command LOAD_IP_FW(0x6)
failed and response status is (0xF)

-- 
You may reply to this email to add a comment.

You are receiving this mail because:
You are watching the assignee of the bug.

Re: [PATCH v2 0/4] dt-bindings: display/msm/gpu: few cleanups

2024-06-25 Thread Dmitry Baryshkov


On Sun, 23 Jun 2024 22:02:59 +0200, Krzysztof Kozlowski wrote:
> Changes since v1:
> 1. Add tags
> 2. New patches #3 and #4
> 3. Drop previous patch "dt-bindings: display/msm/gpu: constrain
>reg/reg-names per variant", because I need to investigate more.
> 
> v1: dt-bindings: display/msm/gpu: constrain reg/reg-names per variant
> 
> [...]

Applied, thanks!

[1/4] dt-bindings: display/msm/gpu: constrain clocks in top-level
  https://gitlab.freedesktop.org/lumag/msm/-/commit/d6c7c411be78
[2/4] dt-bindings: display/msm/gpu: define reg-names in top-level
  https://gitlab.freedesktop.org/lumag/msm/-/commit/c808ece19640
[3/4] dt-bindings: display/msm/gpu: simplify compatible regex
  https://gitlab.freedesktop.org/lumag/msm/-/commit/6d69f8d37c85
[4/4] dt-bindings: display/msm/gpu: fix the schema being not applied
  https://gitlab.freedesktop.org/lumag/msm/-/commit/399af57ccca2

Best regards,
-- 
Dmitry Baryshkov 


[PATCH v2 0/2] Basic support for TI TDP158

2024-06-25 Thread Marc Gonzalez


---
Changes in v2:
- Don't overload simple-bridge, spin new minimal driver
- New driver, new binding
- Default device settings work fine for us, so we don't tweak registers
- Link to v1: 
https://lore.kernel.org/r/20240617-tdp158-v1-0-df98ef7de...@freebox.fr

Getting unusual message at run-time, need to check.

[2.389848] platform c9a.hdmi-tx: Fixed dependency cycle(s) with 
/soc@0/i2c@c1b5000/tdp158@5e
[2.391089] i2c 2-005e: Fixed dependency cycle(s) with 
/soc@0/display-subsystem@c90/hdmi-tx@c9a

---
Marc Gonzalez (2):
  dt-bindings: display: bridge: add TI TDP158
  drm/bridge: add support for TI TDP158

 .../bindings/display/bridge/ti,tdp158.yaml |  48 ++
 drivers/gpu/drm/bridge/Kconfig |   6 ++
 drivers/gpu/drm/bridge/Makefile|   1 +
 drivers/gpu/drm/bridge/ti-tdp158.c | 103 +
 4 files changed, 158 insertions(+)
---
base-commit: d47e2c964a51cbaa14a8c0ac641f85349584fae9
change-id: 20240617-tdp158-418200d6cc0b

Best regards,
-- 
Marc Gonzalez 



[PATCH v2 2/2] drm/bridge: add support for TI TDP158

2024-06-25 Thread Marc Gonzalez
The TI TDP158 is an AC-Coupled HDMI signal to TMDS Redriver supporting
DVI 1.0 and HDMI 1.4b and 2.0b output signals.

The default settings work fine for our use-case.

Signed-off-by: Marc Gonzalez 
---
 drivers/gpu/drm/bridge/Kconfig |   6 +++
 drivers/gpu/drm/bridge/Makefile|   1 +
 drivers/gpu/drm/bridge/ti-tdp158.c | 103 +
 3 files changed, 110 insertions(+)

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index c621be1a99a89..0859f85cb4b69 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -368,6 +368,12 @@ config DRM_TI_DLPC3433
  It supports up to 720p resolution with 60 and 120 Hz refresh
  rates.
 
+config DRM_TI_TDP158
+   tristate "TI TDP158 HDMI/TMDS bridge"
+   depends on OF
+   help
+ Texas Instruments TDP158 HDMI/TMDS Bridge driver
+
 config DRM_TI_TFP410
tristate "TI TFP410 DVI/HDMI bridge"
depends on OF
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index 7df87b582dca3..3daf803ce80b6 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/
 obj-$(CONFIG_DRM_TI_DLPC3433) += ti-dlpc3433.o
 obj-$(CONFIG_DRM_TI_SN65DSI83) += ti-sn65dsi83.o
 obj-$(CONFIG_DRM_TI_SN65DSI86) += ti-sn65dsi86.o
+obj-$(CONFIG_DRM_TI_TDP158) += ti-tdp158.o
 obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o
 obj-$(CONFIG_DRM_TI_TPD12S015) += ti-tpd12s015.o
 obj-$(CONFIG_DRM_NWL_MIPI_DSI) += nwl-dsi.o
diff --git a/drivers/gpu/drm/bridge/ti-tdp158.c 
b/drivers/gpu/drm/bridge/ti-tdp158.c
new file mode 100644
index 0..b65132e3598fc
--- /dev/null
+++ b/drivers/gpu/drm/bridge/ti-tdp158.c
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2024 Freebox SAS
+ */
+#include 
+#include 
+#include 
+
+struct tdp158 {
+   struct drm_bridge bridge;
+   struct drm_bridge *next;
+   struct gpio_desc *enable; // Operation Enable - pin 36
+   struct regulator *vcc; // 3.3V
+   struct regulator *vdd; // 1.1V
+};
+
+static void tdp158_enable(struct drm_bridge *bridge, struct drm_bridge_state 
*prev)
+{
+   int err;
+   struct tdp158 *tdp158 = bridge->driver_private;
+
+   if ((err = regulator_enable(tdp158->vcc)))
+   pr_err("%s: vcc: %d", __func__, err);
+
+   if ((err = regulator_enable(tdp158->vdd)))
+   pr_err("%s: vdd: %d", __func__, err);
+
+   gpiod_set_value_cansleep(tdp158->enable, 1);
+}
+
+static void tdp158_disable(struct drm_bridge *bridge, struct drm_bridge_state 
*prev)
+{
+   struct tdp158 *tdp158 = bridge->driver_private;
+
+   gpiod_set_value_cansleep(tdp158->enable, 0);
+   regulator_disable(tdp158->vdd);
+   regulator_disable(tdp158->vcc);
+}
+
+static int tdp158_attach(struct drm_bridge *bridge, enum 
drm_bridge_attach_flags flags)
+{
+   struct tdp158 *tdp158 = bridge->driver_private;
+   return drm_bridge_attach(bridge->encoder, tdp158->next, bridge, 
DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+}
+
+static const struct drm_bridge_funcs tdp158_bridge_funcs = {
+   .attach = tdp158_attach,
+   .atomic_enable = tdp158_enable,
+   .atomic_disable = tdp158_disable,
+   .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+   .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+   .atomic_reset = drm_atomic_helper_bridge_reset,
+};
+
+static int tdp158_bridge_probe(struct i2c_client *client)
+{
+   struct tdp158 *tdp158;
+   struct device *dev = &client->dev;
+
+   tdp158 = devm_kzalloc(dev, sizeof(*tdp158), GFP_KERNEL);
+   if (!tdp158)
+   return -ENOMEM;
+
+   tdp158->next = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
+   if (IS_ERR(tdp158->next))
+   return dev_err_probe(dev, PTR_ERR(tdp158->next), "next");
+
+   tdp158->vcc = devm_regulator_get(dev, "vcc");
+   if (IS_ERR(tdp158->vcc))
+   return dev_err_probe(dev, PTR_ERR(tdp158->vcc), "vcc");
+
+   tdp158->vdd = devm_regulator_get(dev, "vdd");
+   if (IS_ERR(tdp158->vdd))
+   return dev_err_probe(dev, PTR_ERR(tdp158->vdd), "vdd");
+
+   tdp158->enable = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
+   if (IS_ERR(tdp158->enable))
+   return dev_err_probe(dev, PTR_ERR(tdp158->enable), "enable");
+
+   tdp158->bridge.of_node = dev->of_node;
+   tdp158->bridge.funcs = &tdp158_bridge_funcs;
+   tdp158->bridge.driver_private = tdp158;
+
+   return devm_drm_bridge_add(dev, &tdp158->bridge);
+}
+
+static const struct of_device_id tdp158_bridge_match_table[] = {
+   { .compatible = "ti,tdp158" },
+   { }
+};
+MODULE_DEVICE_TABLE(of, tdp158_bridge_match_table);
+
+static struct i2c_driver tdp158_bridge_driver = {
+   .probe = tdp158_bridge_probe,
+   .driver = {
+   .name = "tdp158-bridge",
+

[PATCH v2 1/2] dt-bindings: display: bridge: add TI TDP158

2024-06-25 Thread Marc Gonzalez
The TI TDP158 is an HDMI to TMDS Redriver.

Signed-off-by: Marc Gonzalez 
---
 .../bindings/display/bridge/ti,tdp158.yaml | 48 ++
 1 file changed, 48 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/bridge/ti,tdp158.yaml 
b/Documentation/devicetree/bindings/display/bridge/ti,tdp158.yaml
new file mode 100644
index 0..b687699e2ba80
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/bridge/ti,tdp158.yaml
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/bridge/ti,tdp158.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TI TDP158 HDMI to TMDS Redriver
+
+maintainers:
+  - Arnaud Vrac 
+
+properties:
+  compatible:
+const: ti,tdp158
+
+  reg:
+description: I2C address of the device
+
+  enable-gpios:
+description: GPIO controlling bridge enable
+
+  vcc-supply:
+description: Power supply 3.3V
+
+  vdd-supply:
+description: Power supply 1.1V
+
+  ports:
+$ref: /schemas/graph.yaml#/properties/ports
+
+properties:
+  port@0:
+$ref: /schemas/graph.yaml#/properties/port
+description: Bridge input
+
+  port@1:
+$ref: /schemas/graph.yaml#/properties/port
+description: Bridge output
+
+required:
+  - port@0
+  - port@1
+
+required:
+  - compatible
+  - ports
+
+additionalProperties: false

-- 
2.34.1



Re: [PATCH v2 1/2] drm/bridge-connector: reset the HDMI connector state

2024-06-25 Thread Dmitry Baryshkov
On Tue, Jun 25, 2024 at 05:49:54PM GMT, Maxime Ripard wrote:
> On Tue, Jun 25, 2024 at 06:05:33PM GMT, Dmitry Baryshkov wrote:
> > On Tue, 25 Jun 2024 at 18:02, Maxime Ripard  wrote:
> > >
> > > Hi,
> > >
> > > On Sun, Jun 23, 2024 at 08:40:12AM GMT, Dmitry Baryshkov wrote:
> > > > On HDMI connectors which use drm_bridge_connector and DRM_BRIDGE_OP_HDMI
> > > > IGT chokes on the max_bpc property in several kms_properties tests due
> > > > to the the drm_bridge_connector failing to reset HDMI-related
> > > > properties.
> > > >
> > > > Call __drm_atomic_helper_connector_hdmi_reset() if there is a
> > > > the drm_bridge_connector has bridge_hdmi.
> > > >
> > > > Note, the __drm_atomic_helper_connector_hdmi_reset() is moved to
> > > > drm_atomic_state_helper.c because drm_bridge_connector.c can not depend
> > > > on DRM_DISPLAY_HDMI_STATE_HELPER. At the same time it is impossible to
> > > > call this function from HDMI bridges, there is is no function that
> > > > corresponds to the drm_connector_funcs::reset().
> > >
> > > Why can't it depend on DRM_DISPLAY_HDMI_STATE_HELPER?
> > 
> > Is it okay to have DRM_KMS_HELPER to depend unconditionally or select
> > DRM_DISPLAY_HDMI_STATE_HELPER?
> 
> No, but it's not clear to me why drm_bridge_connector is part of
> DRM_KMS_HELPER? It doesn't seem to be called from the core but only
> drivers, just like DRM_PANEL_BRIDGE which has a separate config option

But then DRM_PANEL_BRIDGE is also linked into drm_kms_helper.ko. I can't
really say that I understand the definition of various helper modules,
but my taste tells me that code from drm/*.c should not depend directly
on the code from drm/display/*.c.

-- 
With best wishes
Dmitry


Re: [PATCH 1/2] dt-bindings: display: panel: add Ilitek ili9806e panel controller

2024-06-25 Thread Conor Dooley
On Tue, Jun 25, 2024 at 03:33:16PM +0200, Michael Walle wrote:
> Add the device tree binding for the Ilitek ILI9806E controller which can
> be found on the Ortustech COME35H3P70ULC DSI display panel.
> 
> There are no peculiarities except for two different power signals.
> 
> Signed-off-by: Michael Walle 

Reviewed-by: Conor Dooley 


signature.asc
Description: PGP signature


Re: [PATCH 2/3] dt-bindings: panel-simple-dsi: add lincoln LCD197 panel bindings

2024-06-25 Thread Conor Dooley
On Tue, Jun 25, 2024 at 04:25:49PM +0200, Jerome Brunet wrote:
> This adds the bindings for the 1080x1920 Licoln LCD197 DSI panel to
> panel-simple-dsi.
> 
> Signed-off-by: Jerome Brunet 

Acked-by: Conor Dooley 


signature.asc
Description: PGP signature


Re: [PATCH 1/3] dt-bindings: vendor-prefixes: add prefix for lincoln

2024-06-25 Thread Conor Dooley
On Tue, Jun 25, 2024 at 04:25:48PM +0200, Jerome Brunet wrote:
> Lincoln Technology Solutions is a design services and LCD integration
> company
> 
> Link: https://lincolntechsolutions.com/
> Signed-off-by: Jerome Brunet 

Acked-by: Conor Dooley 


signature.asc
Description: PGP signature


Re: [PATCH 1/2] dt-bindings: display: meson-dw-hdmi: add missing power-domain

2024-06-25 Thread Conor Dooley
On Tue, Jun 25, 2024 at 04:50:14PM +0200, Jerome Brunet wrote:
> All Amlogic instances of the Synopsys HDMI controller need a power domain
> enabled. This is currently missing because the Amlogic HDMI driver directly
> pokes the power domain controller registers, which it should not do.
> 
> Instead The HDMI controller should use the power controller.
> Fix the bindings accordingly.
> 
> Signed-off-by: Jerome Brunet 

Acked-by: Conor Dooley 


signature.asc
Description: PGP signature


Re: [PATCH 01/18] dma-direct: take dma-ranges/offsets into account in resource mapping

2024-06-25 Thread Dave Stevenson
Hi Christoph

Sorry for the delay in coming back to you.

On Tue, 28 May 2024 at 07:33, Christoph Hellwig  wrote:
>
> On Fri, May 24, 2024 at 07:26:45PM +0100, Dave Stevenson wrote:
> > From: Serge Semin 
> >
> > A basic device-specific linear memory mapping was introduced back in
> > commit ("dma: Take into account dma_pfn_offset") as a single-valued offset
> > preserved in the device.dma_pfn_offset field, which was initialized for
> > instance by means of the "dma-ranges" DT property. Afterwards the
> > functionality was extended to support more than one device-specific region
> > defined in the device.dma_range_map list of maps. But all of these
> > improvements concerned a single pointer, page or sg DMA-mapping methods,
> > while the system resource mapping function turned to miss the
> > corresponding modification. Thus the dma_direct_map_resource() method now
> > just casts the CPU physical address to the device DMA address with no
> > dma-ranges-based mapping taking into account, which is obviously wrong.
> > Let's fix it by using the phys_to_dma_direct() method to get the
> > device-specific bus address from the passed memory resource for the case
> > of the directly mapped DMA.
>
> My memory is getting a little bad, but as dma_direct_map_resource is
> mostly used for (non-PCIe) peer to peer transfers, any kind of mapping
> from the host address should be excluded.

Could you elaborate on mapping from the host address being excluded?
On BCM283x DMA address != CPU physical address, so some mapping has to occur.

Robin Murphy directed us at dma_map_resource() in [1], and referenced
this patch as necessary because dma_map_resource() didn't currently
use dma-ranges mappings.
Mark Brown also hadn't corrected/objected to the statement that
dma_map_resource() was the correct call when I was querying how to
tackle this historic mismatch in [2].

I'll happily defer to the experts on DMA (I would never classify
myself as such), but I'm not clear on the direction you want here.

[1] https://lore.kernel.org/lkml/ee19a95d-fe1e-4f3f-bc81-bdef38475...@arm.com/
[2] 
https://lore.kernel.org/linux-arm-kernel/CAPY8ntBua=wpvuj+sm0wgcul0ft56ueho8yzutmb8z54x_a...@mail.gmail.com/T/

> (dma_direct_map_resource in general is a horrible interface and I'd
> prefer everyone to switch to the map_sg based P2P support, but we
> have plenty of users for it unfortunately)

Is that applicable for mapping device addresses with DMA_DEV_TO_MEM or
DMA_MEM_TO_DEV transfers?
Example use case on BCM283x is HDMI audio where the HDMI driver should
be passing in the CPU physical address of the audio FIFO, and that
needs to be mapped to the DMA address for the DMA controller. How do I
get a sglist for the peripheral address?

As noted in the cover letter for this series, if this isn't the
approved mechanism, then please let me know what is.

Many thanks
  Dave


Re: [PATCH 1/9] drm: Add helpers for x16 fixed point values

2024-06-25 Thread Imre Deak
On Wed, Jun 19, 2024 at 03:01:03PM +0300, Imre Deak wrote:
> On Wed, Jun 19, 2024 at 01:10:09PM +0300, Jani Nikula wrote:
> > On Fri, 14 Jun 2024, Imre Deak  wrote:
> > > Add helpers to convert between x16 fixed point and integer/fraction
> > > values. Also add the format/argument macros required to printk x16
> > > fixed point variables.
> > >
> > > These are needed by later patches dumping the Display Stream Compression
> > > configuration in DRM core and in the i915 driver to replace the
> > > corresponding bpp_x16 helpers defined locally in the driver.
> > >
> > > Signed-off-by: Imre Deak 
> > > ---
> > >  drivers/gpu/drm/display/drm_dp_helper.c |  5 +++--
> > >  include/drm/drm_fixed.h | 23 +++
> > >  2 files changed, 26 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/display/drm_dp_helper.c 
> > > b/drivers/gpu/drm/display/drm_dp_helper.c
> > > index 79a615667aab1..806f9c9764995 100644
> > > --- a/drivers/gpu/drm/display/drm_dp_helper.c
> > > +++ b/drivers/gpu/drm/display/drm_dp_helper.c
> > > @@ -35,6 +35,7 @@
> > >  #include 
> > >  #include 
> > >  #include 
> > > +#include 
> > >  #include 
> > >  #include 
> > >  #include 
> > > @@ -4151,9 +4152,9 @@ int drm_dp_bw_overhead(int lane_count, int hactive,
> > >   int symbol_cycles;
> > >  
> > >   if (lane_count == 0 || hactive == 0 || bpp_x16 == 0) {
> > > - DRM_DEBUG_KMS("Invalid BW overhead params: lane_count %d, 
> > > hactive %d, bpp_x16 %d.%04d\n",
> > > + DRM_DEBUG_KMS("Invalid BW overhead params: lane_count %d, 
> > > hactive %d, bpp_x16 " DRM_X16_FMT "\n",
> > > lane_count, hactive,
> > > -   bpp_x16 >> 4, (bpp_x16 & 0xf) * 625);
> > > +   DRM_X16_ARGS(bpp_x16));
> > >   return 0;
> > >   }
> > >  
> > > diff --git a/include/drm/drm_fixed.h b/include/drm/drm_fixed.h
> > > index 81572d32db0c2..0fe2a7f50d54e 100644
> > > --- a/include/drm/drm_fixed.h
> > > +++ b/include/drm/drm_fixed.h
> > > @@ -214,4 +214,27 @@ static inline s64 drm_fixp_exp(s64 x)
> > >   return sum;
> > >  }
> > >  
> > > +static inline int drm_x16_from_int(int val_int)
> > > +{
> > > + return val_int << 4;
> > > +}
> > > +
> > > +static inline int drm_x16_to_int(int val_x16)
> > > +{
> > > + return val_x16 >> 4;
> > > +}
> > > +
> > > +static inline int drm_x16_to_int_roundup(int val_x16)
> > > +{
> > > + return (val_x16 + 0xf) >> 4;
> > > +}
> > > +
> > > +static inline int drm_x16_to_frac(int val_x16)
> > > +{
> > > + return val_x16 & 0xf;
> > > +}
> > 
> > Sad trombone about the completely different naming scheme compared to
> > the rest of the file.
> > 
> > Not saying the existing naming is great, but neither is this. And
> > there's no way to unify except by renaming *both* afterwards.
> > 
> > We could devise a scheme now that could be used for the existing stuff
> > later, without renaming the new stuff.
> 
> Based on [1]'s short variant, we could have:
> 
> dfixed*(fixed20_12 v)  -> drm_uq12*(drm_uq20_12_t v)
> drm_fixp*(s64 v)   -> drm_q32*(s64 v)
> drm_x16*(int v)-> drm_q4*(int v)
> 
> Or instead of uq12/q32/q4 using ufp12/fp32/fp4.

Jani, any objection to using the drm_fp4_from_int() etc. names?

> [1] https://en.wikipedia.org/wiki/Q_(number_format)
> 
> > *shrug*
> > 
> > BR,
> > Jani.
> > 
> > 
> > 
> > > +
> > > +#define DRM_X16_FMT  "%d.%04d"
> > > +#define DRM_X16_ARGS(val_x16)drm_x16_to_int(val_x16), 
> > > (drm_x16_to_frac(val_x16) * 625)
> > > +
> > >  #endif
> > 
> > -- 
> > Jani Nikula, Intel


Re: [PATCH v2 1/2] drm/bridge-connector: reset the HDMI connector state

2024-06-25 Thread Maxime Ripard
On Tue, Jun 25, 2024 at 06:05:33PM GMT, Dmitry Baryshkov wrote:
> On Tue, 25 Jun 2024 at 18:02, Maxime Ripard  wrote:
> >
> > Hi,
> >
> > On Sun, Jun 23, 2024 at 08:40:12AM GMT, Dmitry Baryshkov wrote:
> > > On HDMI connectors which use drm_bridge_connector and DRM_BRIDGE_OP_HDMI
> > > IGT chokes on the max_bpc property in several kms_properties tests due
> > > to the the drm_bridge_connector failing to reset HDMI-related
> > > properties.
> > >
> > > Call __drm_atomic_helper_connector_hdmi_reset() if there is a
> > > the drm_bridge_connector has bridge_hdmi.
> > >
> > > Note, the __drm_atomic_helper_connector_hdmi_reset() is moved to
> > > drm_atomic_state_helper.c because drm_bridge_connector.c can not depend
> > > on DRM_DISPLAY_HDMI_STATE_HELPER. At the same time it is impossible to
> > > call this function from HDMI bridges, there is is no function that
> > > corresponds to the drm_connector_funcs::reset().
> >
> > Why can't it depend on DRM_DISPLAY_HDMI_STATE_HELPER?
> 
> Is it okay to have DRM_KMS_HELPER to depend unconditionally or select
> DRM_DISPLAY_HDMI_STATE_HELPER?

No, but it's not clear to me why drm_bridge_connector is part of
DRM_KMS_HELPER? It doesn't seem to be called from the core but only
drivers, just like DRM_PANEL_BRIDGE which has a separate config option

Maxime


signature.asc
Description: PGP signature


Re: [PATCH 1/4] dt-bindings: display: himax-hx8394: remove reset-gpio from required properties

2024-06-25 Thread Conor Dooley
On Tue, Jun 25, 2024 at 02:38:50PM +0530, Manikandan Muralidharan wrote:
> Remove "reset-gpio" property from required properties list and
> make it optional.When interfaced with some boards where reset line is not
> populated it leads to driver probe issues.
> 
> Signed-off-by: Manikandan Muralidharan 
> ---
>  .../devicetree/bindings/display/panel/himax,hx8394.yaml  | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git 
> a/Documentation/devicetree/bindings/display/panel/himax,hx8394.yaml 
> b/Documentation/devicetree/bindings/display/panel/himax,hx8394.yaml
> index 644387e4fb6f..017cb19ed64f 100644
> --- a/Documentation/devicetree/bindings/display/panel/himax,hx8394.yaml
> +++ b/Documentation/devicetree/bindings/display/panel/himax,hx8394.yaml
> @@ -46,7 +46,6 @@ properties:
>  required:
>- compatible
>- reg
> -  - reset-gpios

If this is just the case for the new microchip panel, please make the
removal of required be conditional for that panel only and squash both
binding patches.

Thanks,
Conor.


signature.asc
Description: PGP signature


Re: [PATCH 3/4] dt-bindings: display: himax-hx8394: Add Microchip AC40T08A MIPI Display panel

2024-06-25 Thread Conor Dooley
On Tue, Jun 25, 2024 at 02:38:52PM +0530, Manikandan Muralidharan wrote:
> Add compatible string for the Microchip's AC40T08A MIPI Display
> panel.This panel uses a Himax HX8394 display controller.
> 
> Signed-off-by: Manikandan Muralidharan 
> ---
>  .../devicetree/bindings/display/panel/himax,hx8394.yaml  | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git 
> a/Documentation/devicetree/bindings/display/panel/himax,hx8394.yaml 
> b/Documentation/devicetree/bindings/display/panel/himax,hx8394.yaml
> index 017cb19ed64f..d547df794b3b 100644
> --- a/Documentation/devicetree/bindings/display/panel/himax,hx8394.yaml
> +++ b/Documentation/devicetree/bindings/display/panel/himax,hx8394.yaml
> @@ -24,6 +24,7 @@ properties:
>- enum:
>- hannstar,hsd060bhw4
>- powkiddy,x55-panel
> +  - microchip,ac40t08a-mipi-panel

Please add this in alphabetical order.

>- const: himax,hx8394
>  
>reg:
> -- 
> 2.25.1
> 


signature.asc
Description: PGP signature


Re: [PATCH v4 1/2] iommu/io-pgtable-arm: Add way to debug pgtable walk

2024-06-25 Thread Rob Clark
On Tue, Jun 25, 2024 at 4:27 AM Will Deacon  wrote:
>
> On Mon, Jun 24, 2024 at 08:37:26AM -0700, Rob Clark wrote:
> > On Mon, Jun 24, 2024 at 8:14 AM Will Deacon  wrote:
> > >
> > > On Thu, May 23, 2024 at 10:52:21AM -0700, Rob Clark wrote:
> > > > From: Rob Clark 
> > > >
> > > > Add an io-pgtable method to walk the pgtable returning the raw PTEs that
> > > > would be traversed for a given iova access.
> > > >
> > > > Signed-off-by: Rob Clark 
> > > > ---
> > > >  drivers/iommu/io-pgtable-arm.c | 51 --
> > > >  include/linux/io-pgtable.h |  4 +++
> > > >  2 files changed, 46 insertions(+), 9 deletions(-)
> > > >
> > > > diff --git a/drivers/iommu/io-pgtable-arm.c 
> > > > b/drivers/iommu/io-pgtable-arm.c
> > > > index f7828a7aad41..f47a0e64bb35 100644
> > > > --- a/drivers/iommu/io-pgtable-arm.c
> > > > +++ b/drivers/iommu/io-pgtable-arm.c
> > > > @@ -693,17 +693,19 @@ static size_t arm_lpae_unmap_pages(struct 
> > > > io_pgtable_ops *ops, unsigned long iov
> > > >   data->start_level, ptep);
> > > >  }
> > > >
> > > > -static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
> > > > -  unsigned long iova)
> > > > +static int arm_lpae_pgtable_walk(struct io_pgtable_ops *ops, unsigned 
> > > > long iova,
> > > > + int (*cb)(void *cb_data, void *pte, int level),
> > > > + void *cb_data)
> > > >  {
> > > >   struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
> > > >   arm_lpae_iopte pte, *ptep = data->pgd;
> > > >   int lvl = data->start_level;
> > > > + int ret;
> > > >
> > > >   do {
> > > >   /* Valid IOPTE pointer? */
> > > >   if (!ptep)
> > > > - return 0;
> > > > + return -EFAULT;
> > >
> > > nit: -ENOENT might be a little better, as we're only checking against a
> > > NULL entry rather than strictly any faulting entry.
> > >
> > > >   /* Grab the IOPTE we're interested in */
> > > >   ptep += ARM_LPAE_LVL_IDX(iova, lvl, data);
> > > > @@ -711,22 +713,52 @@ static phys_addr_t arm_lpae_iova_to_phys(struct 
> > > > io_pgtable_ops *ops,
> > > >
> > > >   /* Valid entry? */
> > > >   if (!pte)
> > > > - return 0;
> > > > + return -EFAULT;
> > >
> > > Same here (and at the end of the function).
> > >
> > > > +
> > > > + ret = cb(cb_data, &pte, lvl);
> > >
> > > Since pte is on the stack, rather than pointing into the actual pgtable,
> > > I think it would be clearer to pass it by value to the callback.
> >
> > fwiw, I passed it as a void* to avoid the pte size.. although I guess
> > it could be a union of all the possible pte types
>
> Can you just get away with a u64?

yeah, that wfm if you're ok with it

BR,
-R


Re: [PATCH v2 1/2] drm/bridge-connector: reset the HDMI connector state

2024-06-25 Thread Dmitry Baryshkov
On Tue, 25 Jun 2024 at 18:02, Maxime Ripard  wrote:
>
> Hi,
>
> On Sun, Jun 23, 2024 at 08:40:12AM GMT, Dmitry Baryshkov wrote:
> > On HDMI connectors which use drm_bridge_connector and DRM_BRIDGE_OP_HDMI
> > IGT chokes on the max_bpc property in several kms_properties tests due
> > to the the drm_bridge_connector failing to reset HDMI-related
> > properties.
> >
> > Call __drm_atomic_helper_connector_hdmi_reset() if there is a
> > the drm_bridge_connector has bridge_hdmi.
> >
> > Note, the __drm_atomic_helper_connector_hdmi_reset() is moved to
> > drm_atomic_state_helper.c because drm_bridge_connector.c can not depend
> > on DRM_DISPLAY_HDMI_STATE_HELPER. At the same time it is impossible to
> > call this function from HDMI bridges, there is is no function that
> > corresponds to the drm_connector_funcs::reset().
>
> Why can't it depend on DRM_DISPLAY_HDMI_STATE_HELPER?

Is it okay to have DRM_KMS_HELPER to depend unconditionally or select
DRM_DISPLAY_HDMI_STATE_HELPER?

-- 
With best wishes
Dmitry


Re: [PATCH v2 1/2] drm/bridge-connector: reset the HDMI connector state

2024-06-25 Thread Maxime Ripard
Hi,

On Sun, Jun 23, 2024 at 08:40:12AM GMT, Dmitry Baryshkov wrote:
> On HDMI connectors which use drm_bridge_connector and DRM_BRIDGE_OP_HDMI
> IGT chokes on the max_bpc property in several kms_properties tests due
> to the the drm_bridge_connector failing to reset HDMI-related
> properties.
> 
> Call __drm_atomic_helper_connector_hdmi_reset() if there is a
> the drm_bridge_connector has bridge_hdmi.
> 
> Note, the __drm_atomic_helper_connector_hdmi_reset() is moved to
> drm_atomic_state_helper.c because drm_bridge_connector.c can not depend
> on DRM_DISPLAY_HDMI_STATE_HELPER. At the same time it is impossible to
> call this function from HDMI bridges, there is is no function that
> corresponds to the drm_connector_funcs::reset().

Why can't it depend on DRM_DISPLAY_HDMI_STATE_HELPER?

Maxime


signature.asc
Description: PGP signature


Re: [PATCH net-next v13 00/13] Device Memory TCP

2024-06-25 Thread Jakub Kicinski
On Tue, 25 Jun 2024 07:16:00 -0700 Mina Almasry wrote:
> What happened here is that I sync'd to net-next, ran all the tests
> including the allmodconfig build which took a few hours, then posted
> the series. In the meantime 34 patches got merged to net-next, and one
> of those patches seems to generate a git am failure when I try to use
> b4 to apply:

Got it, feel free to repost as soon as you can build test the rebased
version.


Re: [PATCH v2 0/4] MSM8937 MDP/DSI PHY enablement

2024-06-25 Thread Dmitry Baryshkov


On Sun, 23 Jun 2024 22:30:35 +0200, Barnabás Czémán wrote:
> This patch series adds support for the MDP and DSI PHY as found on the
> MSM8937 platform.
> 
> 

Applied, thanks!

[1/4] dt-bindings: display/msm: qcom, mdp5: Add msm8937 compatible
  https://gitlab.freedesktop.org/lumag/msm/-/commit/c94dc5feb494
[2/4] drm/msm/mdp5: Add MDP5 configuration for MSM8937
  https://gitlab.freedesktop.org/lumag/msm/-/commit/13099cb03f98
[3/4] dt-bindings: msm: dsi-phy-28nm: Document msm8937 compatible
  https://gitlab.freedesktop.org/lumag/msm/-/commit/60bdbaaf1220
[4/4] drm/msm/dsi: Add phy configuration for MSM8937
  https://gitlab.freedesktop.org/lumag/msm/-/commit/2df0161959d1

Best regards,
-- 
Dmitry Baryshkov 


Re: [PATCH] drm/msm/mdp5: Remove MDP_CAP_SRC_SPLIT from msm8x53_config

2024-06-25 Thread Dmitry Baryshkov


On Mon, 24 Jun 2024 00:26:01 +0200, Barnabás Czémán wrote:
> Remove MDP_CAP_SRC_SPLIT from msm8x53_config because
> it is not referenced in downstream.
> 
> 

Applied, thanks!

[1/1] drm/msm/mdp5: Remove MDP_CAP_SRC_SPLIT from msm8x53_config
  https://gitlab.freedesktop.org/lumag/msm/-/commit/a3a6b350eb6c

Best regards,
-- 
Dmitry Baryshkov 


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

2024-06-25 Thread Dmitry Baryshkov


On Tue, 25 Jun 2024 01:38:25 +0300, 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().
> 
> 
> [...]

Applied, thanks!

[1/1] drm/msm/dpu: remove CRTC frame event callback registration
  https://gitlab.freedesktop.org/lumag/msm/-/commit/5b90752f9619

Best regards,
-- 
Dmitry Baryshkov 


[PATCH 2/2] arm64: dts: amlogic: add power domain to hdmitx

2024-06-25 Thread Jerome Brunet
HDMI Tx needs HDMI Tx memory power domain turned on. This power domain is
handled under the VPU power domain.

The HDMI Tx currently works because it is enabling the PD by directly
poking the power controller register. It is should not do that but properly
use the power domain controller.

Fix this by adding the power domain to HDMI Tx.

Signed-off-by: Jerome Brunet 
---
 arch/arm64/boot/dts/amlogic/meson-g12.dtsi  | 4 
 arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 1 +
 arch/arm64/boot/dts/amlogic/meson-gxl.dtsi  | 1 +
 arch/arm64/boot/dts/amlogic/meson-sm1.dtsi  | 4 
 4 files changed, 10 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12.dtsi 
b/arch/arm64/boot/dts/amlogic/meson-g12.dtsi
index e732df3f3114..664912d1beaa 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12.dtsi
@@ -363,6 +363,10 @@ ðmac {
power-domains = <&pwrc PWRC_G12A_ETH_ID>;
 };
 
+&hdmi_tx {
+   power-domains = <&pwrc PWRC_G12A_VPU_ID>;
+};
+
 &vpu {
power-domains = <&pwrc PWRC_G12A_VPU_ID>;
 };
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi 
b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
index 12ef6e81c8bd..d8a386c31914 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
@@ -315,6 +315,7 @@ &hdmi_tx {
 <&clkc CLKID_CLK81>,
 <&clkc CLKID_GCLK_VENCI_INT0>;
clock-names = "isfr", "iahb", "venci";
+   power-domains = <&pwrc PWRC_GXBB_VPU_ID>;
 };
 
 &sysctrl {
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi 
b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
index 17bcfa4702e1..82386feb5177 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
@@ -327,6 +327,7 @@ &hdmi_tx {
 <&clkc CLKID_CLK81>,
 <&clkc CLKID_GCLK_VENCI_INT0>;
clock-names = "isfr", "iahb", "venci";
+   power-domains = <&pwrc PWRC_GXBB_VPU_ID>;
 };
 
 &sysctrl {
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi 
b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
index cd0046c0fe72..c76dcb0158a7 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
@@ -514,6 +514,10 @@ &gpio_intc {
 "amlogic,meson-gpio-intc";
 };
 
+&hdmi_tx {
+   power-domains = <&pwrc PWRC_SM1_VPU_ID>;
+};
+
 &pcie {
power-domains = <&pwrc PWRC_SM1_PCIE_ID>;
 };
-- 
2.43.0



[PATCH 1/2] dt-bindings: display: meson-dw-hdmi: add missing power-domain

2024-06-25 Thread Jerome Brunet
All Amlogic instances of the Synopsys HDMI controller need a power domain
enabled. This is currently missing because the Amlogic HDMI driver directly
pokes the power domain controller registers, which it should not do.

Instead The HDMI controller should use the power controller.
Fix the bindings accordingly.

Signed-off-by: Jerome Brunet 
---
 .../devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml   | 5 +
 1 file changed, 5 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml 
b/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml
index 0c85894648d8..84d68b8cfccc 100644
--- a/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml
+++ b/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml
@@ -71,6 +71,10 @@ properties:
   - const: iahb
   - const: venci
 
+  power-domains:
+maxItems: 1
+description: phandle to the associated power domain
+
   resets:
 minItems: 3
 
@@ -129,6 +133,7 @@ examples:
 reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy";
 clocks = <&clk_isfr>, <&clk_iahb>, <&clk_venci>;
 clock-names = "isfr", "iahb", "venci";
+power-domains = <&pd_vpu>;
 #address-cells = <1>;
 #size-cells = <0>;
 
-- 
2.43.0



[PATCH 0/2] arm64: dts: amlogic: add power domain to hdmitx

2024-06-25 Thread Jerome Brunet
This patchset add the bindings for the power domain of the HDMI Tx
on Amlogic SoC.

This is a 1st step in cleaning HDMI Tx and its direct usage of HHI
register space. Eventually, this will help remove component usage from
the Amlogic display drivers.

Jerome Brunet (2):
  dt-bindings: display: meson-dw-hdmi: add missing power-domain
  arm64: dts: amlogic: add power domain to hdmitx

 .../devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml   | 5 +
 arch/arm64/boot/dts/amlogic/meson-g12.dtsi   | 4 
 arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi  | 1 +
 arch/arm64/boot/dts/amlogic/meson-gxl.dtsi   | 1 +
 arch/arm64/boot/dts/amlogic/meson-sm1.dtsi   | 4 
 5 files changed, 15 insertions(+)

-- 
2.43.0



Re: [PATCH] MAINTAINERS: CC dri-devel list on Qualcomm FastRPC patches

2024-06-25 Thread Srinivas Kandagatla


On Mon, 24 Jun 2024 11:19:09 +0300, Dmitry Baryshkov wrote:
> FastRPC is a way to offload method invocation to the DSPs on Qualcomm
> platforms. As the driver uses dma-bufs, add dri-devel mailing list to
> the MAINTAINERS's entry, so that DRM maintainers are notified about the
> uAPI changes. This follows the usual practice established by the "DMA
> BUFFER SHARING FRAMEWORK" entry in the file.
> 
> 
> [...]

Applied, thanks!

[1/1] MAINTAINERS: CC dri-devel list on Qualcomm FastRPC patches
  commit: 47bf4198bf386018e99673c1ce5dbd8e5eda293e

Best regards,
-- 
Srinivas Kandagatla 



Re: [PATCH v2 1/2] drm: bridge: samsung-dsim: Initialize bridge on attach

2024-06-25 Thread Alexander Stein
Hi Marek,

Am Dienstag, 25. Juni 2024, 14:26:10 CEST schrieb Marek Vasut:
> Initialize the bridge on attach already, to force lanes into LP11
> state, since attach does trigger attach of downstream bridges which
> may trigger (e)DP AUX channel mode read.
> 
> This fixes a corner case where DSIM with TC9595 attached to it fails
> to operate the DP AUX channel, because the TC9595 enters some debug
> mode when it is released from reset without lanes in LP11 mode. By
> ensuring the DSIM lanes are in LP11, the TC9595 (tc358767.c driver)
> can be reset in its attach callback called from DSIM attach callback,
> and recovered out of the debug mode just before TC9595 performs first
> AUX channel access later in its attach callback.
> 
> Signed-off-by: Marek Vasut 
> ---
> Cc: Adam Ford 
> Cc: Alexander Stein 
> Cc: Andrzej Hajda 
> Cc: Daniel Vetter 
> Cc: David Airlie 
> Cc: Frieder Schrempf 
> Cc: Inki Dae 
> Cc: Jagan Teki 
> Cc: Jernej Skrabec 
> Cc: Jonas Karlman 
> Cc: Laurent Pinchart 
> Cc: Lucas Stach 
> Cc: Maarten Lankhorst 
> Cc: Marek Szyprowski 
> Cc: Maxime Ripard 
> Cc: Michael Walle 
> Cc: Neil Armstrong 
> Cc: Robert Foss 
> Cc: Thomas Zimmermann 
> Cc: dri-devel@lists.freedesktop.org
> Cc: ker...@dh-electronics.com
> ---
> V2: Handle case where mode is not set yet
> ---
>  drivers/gpu/drm/bridge/samsung-dsim.c | 32 ---
>  1 file changed, 24 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c 
> b/drivers/gpu/drm/bridge/samsung-dsim.c
> index e7e53a9e42afb..22d3bbd866d97 100644
> --- a/drivers/gpu/drm/bridge/samsung-dsim.c
> +++ b/drivers/gpu/drm/bridge/samsung-dsim.c
> @@ -699,20 +699,24 @@ static unsigned long samsung_dsim_set_pll(struct 
> samsung_dsim *dsi,
>  
>  static int samsung_dsim_enable_clock(struct samsung_dsim *dsi)
>  {
> - unsigned long hs_clk, byte_clk, esc_clk, pix_clk;
> + unsigned long hs_clk, byte_clk, esc_clk;
>   unsigned long esc_div;
>   u32 reg;
>   struct drm_display_mode *m = &dsi->mode;
>   int bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
>  
> - /* m->clock is in KHz */
> - pix_clk = m->clock * 1000;
> -
> - /* Use burst_clk_rate if available, otherwise use the pix_clk */
> + /*
> +  * Use burst_clk_rate if available, otherwise use the mode clock
> +  * if mode is already set and available, otherwise fall back to
> +  * PLL input clock and operate in 1:1 lowest frequency mode until
> +  * a mode is set.
> +  */
>   if (dsi->burst_clk_rate)
>   hs_clk = samsung_dsim_set_pll(dsi, dsi->burst_clk_rate);
> + else if (m) /* m->clock is in KHz */
> + hs_clk = samsung_dsim_set_pll(dsi, DIV_ROUND_UP(m->clock * 1000 
> * bpp, dsi->lanes));
>   else
> - hs_clk = samsung_dsim_set_pll(dsi, DIV_ROUND_UP(pix_clk * bpp, 
> dsi->lanes));
> + hs_clk = dsi->pll_clk_rate;
>  

I can't reproduce that mentioned corner case and presumably this problem
does not exist otherwise. If samsung,burst-clock-frequency is unset I get
a sluggish image on the monitor.

It seems the calculation is using a adjusted clock frequency:
samsung-dsim 32e6.dsi: Using pixel clock for HS clock frequency
samsung-dsim 32e6.dsi: [drm:samsung_dsim_host_attach [samsung_dsim]] 
Attached tc358767 device (lanes:4 bpp:24 mode-flags:0xc03)
samsung-dsim 32e6.dsi: PLL ref clock freq 2400
samsung-dsim 32e6.dsi: failed to find PLL PMS for requested frequency
samsung-dsim 32e6.dsi: failed to configure DSI PLL
samsung-dsim 32e6.dsi: PLL ref clock freq 2400
samsung-dsim 32e6.dsi: PLL freq 883636363, (p 11, m 810, s 1)
samsung-dsim 32e6.dsi: hs_clk = 883636363, byte_clk = 110454545, esc_clk = 
9204545
samsung-dsim 32e6.dsi: calculated hfp: 60, hbp: 105, hsa: 27
samsung-dsim 32e6.dsi: LCD size = 1920x1080

891 MHz is the nominal one for 148.5 MHz pixelclock. But even setting
samsung,burst-clock-frequency to 891 MHz results in a sluggish image.
Maybe this usecase is nothing I need to consider while using DSI-DP
with EDID timings available.

As the burst clock needs to provide more bandwidth than actually needed,
I consider this a different usecase not providing
samsung,burst-clock-frequency for DSI->DP usage.

But the initialization upon attach is working intended, so:
Reviewed-by: Alexander Stein 

>   if (!hs_clk) {
>   dev_err(dsi->dev, "failed to configure DSI PLL\n");
> @@ -1643,9 +1647,21 @@ static int samsung_dsim_attach(struct drm_bridge 
> *bridge,
>  enum drm_bridge_attach_flags flags)
>  {
>   struct samsung_dsim *dsi = bridge_to_dsi(bridge);
> + int ret;
>  
> - return drm_bridge_attach(bridge->encoder, dsi->out_bridge, bridge,
> -  flags);
> + ret = pm_runtime_resume_and_get(dsi->dev);
> + if (ret < 0)
> + return ret;
> +
> + ret = samsung_dsim_init(dsi);
> + if (ret < 0)
> + 

Re: [PATCH] drm/nouveau/dispnv04: fix null pointer dereference in nv17_tv_get_hd_modes

2024-06-25 Thread Markus Elfring
> In nv17_tv_get_hd_modes(), the return value of drm_mode_duplicate() is
> assigned to mode, which will lead to a possible NULL pointer dereference
> on failure of drm_mode_duplicate(). The same applies to drm_cvt_mode().
> Add a check to avoid null pointer dereference.

Can a wording approach (like the following) be a better change description?

  A null pointer is stored in the local variable “mode” after a call
  of the function “drm_cvt_mode” or “drm_mode_duplicate” failed.
  This pointer was used in subsequent statements where an undesirable
  dereference will be performed then.
  Thus add corresponding return value checks.


> Cc: sta...@vger.kernel.org

Would you like to add the tag “Fixes” accordingly?


How do you think about to use a summary phrase like
“Prevent null pointer dereferences in nv17_tv_get_hd_modes()”?

Regards,
Markus


Re: [PATCH v2 2/2] drm/connector: automatically set immutable flag for max_bpc property

2024-06-25 Thread Dmitry Baryshkov
On Tue, Jun 25, 2024 at 03:58:25PM GMT, Maxime Ripard wrote:
> On Tue, Jun 25, 2024 at 10:23:14AM GMT, Dmitry Baryshkov wrote:
> > On Tue, 25 Jun 2024 at 10:19, Maxime Ripard  wrote:
> > >
> > > Hi,
> > >
> > > On Tue, Jun 25, 2024 at 09:21:27AM GMT, Dmitry Baryshkov wrote:
> > > > On Tue, 25 Jun 2024 at 01:56, Abhinav Kumar  
> > > > wrote:
> > > > >
> > > > >
> > > > >
> > > > > On 6/24/2024 3:46 PM, Dmitry Baryshkov wrote:
> > > > > > On Tue, 25 Jun 2024 at 01:39, Abhinav Kumar 
> > > > > >  wrote:
> > > > > >>
> > > > > >> + IGT dev
> > > > > >>
> > > > > >> On 6/22/2024 10:40 PM, Dmitry Baryshkov wrote:
> > > > > >>> With the introduction of the HDMI Connector framework the driver 
> > > > > >>> might
> > > > > >>> end up creating the max_bpc property with min = max = 8. IGT 
> > > > > >>> insists
> > > > > >>> that such properties carry the 'immutable' flag. Automatically 
> > > > > >>> set the
> > > > > >>> flag if the driver asks for the max_bpc property with min == max.
> > > > > >>>
> > > > > >>
> > > > > >> This change does not look right to me.
> > > > > >>
> > > > > >> I wonder why we need this check because DRM_MODE_PROP_IMMUTABLE 
> > > > > >> means
> > > > > >> that as per the doc, userspace cannot change the property.
> > > > > >>
> > > > > >>* DRM_MODE_PROP_IMMUTABLE
> > > > > >>* Set for properties whose values cannot be changed 
> > > > > >> by
> > > > > >>* userspace. The kernel is allowed to update the 
> > > > > >> value of
> > > > > >> these
> > > > > >>* properties. This is generally used to expose 
> > > > > >> probe state to
> > > > > >>* userspace, e.g. the EDID, or the connector path 
> > > > > >> property
> > > > > >> on DP
> > > > > >>* MST sinks. Kernel can update the value of an 
> > > > > >> immutable
> > > > > >> property
> > > > > >>* by calling drm_object_property_set_value().
> > > > > >>*/
> > > > > >>
> > > > > >> Here we are allowing userspace to change max_bpc
> > > > > >>
> > > > > >>
> > > > > >> drm_atomic_connector_set_property()
> > > > > >> {
> > > > > >>  **
> > > > > >>
> > > > > >>   } else if (property == connector->max_bpc_property) {
> > > > > >>   state->max_requested_bpc = val;
> > > > > >>
> > > > > >>  **
> > > > > >> }
> > > > > >>
> > > > > >> I believe you are referring to this IGT check right?
> > > > > >>
> > > > > >> https://gitlab.freedesktop.org/drm/igt-gpu-tools/-/blob/master/tests/kms_properties.c#L428
> > > > > >
> > > > > > Yes
> > > > > >
> > > > > >>
> > > > > >> I think we should fix IGT in this case unless there is some reason 
> > > > > >> we
> > > > > >> are missing. Because just because it has the same min and max does 
> > > > > >> not
> > > > > >> mean its immutable by the doc of the IMMUTABLE flag.
> > > > > >
> > > > > > Well, having the same min and max means that it is impossible to
> > > > > > change the property. So the property is immutable, but doesn't have
> > > > > > the flag.
> > > > > >
> > > > >
> > > > > True, then does DRM_MODE_PROP_IMMUTABLE need a doc update too 
> > > > > indicating
> > > > > that even if the min and max is same, property will be interpreted as
> > > > > immutable.
> > > >
> > > > Granted that I'm only doing it for max_bpc property I don't think so.
> > >
> > > Yeah, I have to agree with Abhinav here, it does look fishy to me too,
> > > even more so that it's only ever "documented" through an igt routine
> > > that has never documented why we want that.
> > >
> > > I'm fine with the change if it's indeed what we expect, and it might
> > > very well be, but I'd like to clear that up and document it first.
> > 
> > Should I also move the setting of the IMMUTABLE flag to a more generic code?
> 
> Possibly, but I guess that will depend on the outcome of that discussion

Agreed, I'll post it later today. Could you please ack or comment the first 
patch?

-- 
With best wishes
Dmitry


Re: [PATCH] drm/nouveau/dispnv04: fix null pointer dereference in nv17_tv_get_ld_modes

2024-06-25 Thread Greg KH
On Tue, Jun 25, 2024 at 03:43:37PM +0200, Markus Elfring wrote:
> > In nv17_tv_get_ld_modes(), the return value of drm_mode_duplicate() is
> > assigned to mode, which will lead to a possible NULL pointer dereference
> > on failure of drm_mode_duplicate(). Add a check to avoid npd.
> 
> Can a wording approach (like the following) be a better change description?
> 
>   A null pointer is stored in the local variable “mode” after a call
>   of the function “drm_mode_duplicate” failed. This pointer was used
>   in a subsequent statement where an undesirable dereference will
>   be performed then.
>   Thus add a corresponding return value check.
> 
> 
> > Cc: sta...@vger.kernel.org
> 
> Would you like to add the tag “Fixes” accordingly?
> 
> 
> How do you think about to use a summary phrase like
> “Prevent null pointer dereference in nv17_tv_get_ld_modes()”?
> 
> 
> Regards,
> Markus
> 
Hi,

This is the semi-friendly patch-bot of Greg Kroah-Hartman.

Markus, you seem to have sent a nonsensical or otherwise pointless
review comment to a patch submission on a Linux kernel developer mailing
list.  I strongly suggest that you not do this anymore.  Please do not
bother developers who are actively working to produce patches and
features with comments that, in the end, are a waste of time.

Patch submitter, please ignore Markus's suggestion; you do not need to
follow it at all.  The person/bot/AI that sent it is being ignored by
almost all Linux kernel maintainers for having a persistent pattern of
behavior of producing distracting and pointless commentary, and
inability to adapt to feedback.  Please feel free to also ignore emails
from them.

thanks,

greg k-h's patch email bot


Re: [PATCH 2/2] drm/panel: add Ilitek ILI9806E panel driver

2024-06-25 Thread Dmitry Baryshkov
On Tue, Jun 25, 2024 at 03:33:17PM GMT, Michael Walle wrote:
> The Ortustech COM35H3P70ULC panel is based on the ILI9806E DSI display
> controller.
> 

[...]

> +static int ili9806e_get_modes(struct drm_panel *panel,
> +   struct drm_connector *connector)
> +{
> + struct ili9806e_panel *ctx = to_ili9806e_panel(panel);
> + struct drm_display_mode *mode;
> +
> + mode = drm_mode_duplicate(connector->dev, ctx->desc->display_mode);
> + if (!mode)
> + return -ENOMEM;
> +
> + drm_mode_set_name(mode);
> +
> + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
> + connector->display_info.width_mm = mode->width_mm;
> + connector->display_info.height_mm = mode->height_mm;
> + drm_mode_probed_add(connector, mode);

drm_connector_helper_get_modes_fixed(), please.

> +
> + return 1;
> +}
> +

-- 
With best wishes
Dmitry


[PATCH 2/3] dt-bindings: panel-simple-dsi: add lincoln LCD197 panel bindings

2024-06-25 Thread Jerome Brunet
This adds the bindings for the 1080x1920 Licoln LCD197 DSI panel to
panel-simple-dsi.

Signed-off-by: Jerome Brunet 
---
 .../devicetree/bindings/display/panel/panel-simple-dsi.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml 
b/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml
index db5acd2807ed..49e663dd267d 100644
--- a/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml
+++ b/Documentation/devicetree/bindings/display/panel/panel-simple-dsi.yaml
@@ -46,6 +46,8 @@ properties:
   - lg,ld070wx3-sl01
 # LG Corporation 5" HD TFT LCD panel
   - lg,lh500wx1-sd03
+# Lincoln LCD197 5" 1080x1920 LCD panel
+  - lincoln,lcd197
 # One Stop Displays OSD101T2587-53TS 10.1" 1920x1200 panel
   - osddisplays,osd101t2587-53ts
 # Panasonic 10" WUXGA TFT LCD panel
-- 
2.43.0



[PATCH 3/3] drm/panel: add lincoln lcd197 support

2024-06-25 Thread Jerome Brunet
Add support for the Lincoln LCD197 1080x1920 DSI panel.

Signed-off-by: Jerome Brunet 
---
 drivers/gpu/drm/panel/Kconfig|  11 +
 drivers/gpu/drm/panel/Makefile   |   1 +
 drivers/gpu/drm/panel/panel-lincoln-lcd197.c | 333 +++
 3 files changed, 345 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-lincoln-lcd197.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 2ae0eb0638f3..a4e68981e740 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -319,6 +319,17 @@ config DRM_PANEL_LEADTEK_LTK500HD1829
  24 bit RGB per pixel. It provides a MIPI DSI interface to
  the host and has a built-in LED backlight.
 
+config DRM_PANEL_LINCOLN_LCD197
+   tristate "Lincoln lcd197 panel"
+   depends on OF
+   depends on DRM_MIPI_DSI
+   depends on BACKLIGHT_CLASS_DEVICE
+   help
+ Say Y here if you want to enable support for lincoln lcd197
+ TFT-LCD modules. The panel has a 1080x1920 resolution and uses
+ 24 bit RGB per pixel. It provides a MIPI DSI interface to
+ the host.
+
 config DRM_PANEL_LG_LB035Q02
tristate "LG LB035Q024573 RGB panel"
depends on GPIOLIB && OF && SPI
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index f0203f6e02f4..06141ec2e065 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_DRM_PANEL_KHADAS_TS050) += panel-khadas-ts050.o
 obj-$(CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04) += panel-kingdisplay-kd097d04.o
 obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W) += panel-leadtek-ltk050h3146w.o
 obj-$(CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829) += panel-leadtek-ltk500hd1829.o
+obj-$(CONFIG_DRM_PANEL_LINCOLN_LCD197) += panel-lincoln-lcd197.o
 obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o
 obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
 obj-$(CONFIG_DRM_PANEL_LG_SW43408) += panel-lg-sw43408.o
diff --git a/drivers/gpu/drm/panel/panel-lincoln-lcd197.c 
b/drivers/gpu/drm/panel/panel-lincoln-lcd197.c
new file mode 100644
index ..977790797d70
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-lincoln-lcd197.c
@@ -0,0 +1,333 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2023 BayLibre, SAS
+ * Author: Jerome Brunet 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct lincoln_lcd197_panel {
+   struct drm_panel panel;
+   struct mipi_dsi_device *dsi;
+   struct regulator *supply;
+   struct gpio_desc *enable_gpio;
+   struct gpio_desc *reset_gpio;
+
+   bool prepared;
+   bool enabled;
+};
+
+static inline
+struct lincoln_lcd197_panel *to_lincoln_lcd197_panel(struct drm_panel *panel)
+{
+   return container_of(panel, struct lincoln_lcd197_panel, panel);
+}
+
+static int lincoln_lcd197_panel_prepare(struct drm_panel *panel)
+{
+   struct lincoln_lcd197_panel *lcd = to_lincoln_lcd197_panel(panel);
+   int err;
+   u8 display_id[3];
+
+   if (lcd->prepared)
+   return 0;
+
+   gpiod_set_value_cansleep(lcd->enable_gpio, 0);
+   err = regulator_enable(lcd->supply);
+   if (err < 0)
+   return err;
+
+   gpiod_set_value_cansleep(lcd->enable_gpio, 1);
+   usleep_range(1000, 2000);
+   gpiod_set_value_cansleep(lcd->reset_gpio, 1);
+   usleep_range(5000, 6000);
+   gpiod_set_value_cansleep(lcd->reset_gpio, 0);
+   msleep(50);
+
+   mipi_dsi_dcs_write_seq(lcd->dsi, 0xB9, 0xFF, 0x83, 0x99);
+   mipi_dsi_dcs_write_seq(lcd->dsi, 0xD2, 0x55);
+   mipi_dsi_dcs_write_seq(lcd->dsi, 0xB1, 0x02, 0x04, 0x70, 0x90, 0x01,
+  0x32, 0x33, 0x11, 0x11, 0x4D, 0x57, 0x56, 0x73,
+  0x02, 0x02);
+   mipi_dsi_dcs_write_seq(lcd->dsi, 0xB2, 0x00, 0x80, 0x80, 0xAE, 0x0A,
+  0x0E, 0x75, 0x11, 0x00, 0x00, 0x00);
+   mipi_dsi_dcs_write_seq(lcd->dsi, 0xB4, 0x00, 0xFF, 0x04, 0xA4, 0x02,
+  0xA0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x00,
+  0x24, 0x02, 0x04, 0x0A, 0x21, 0x03, 0x00, 0x00,
+  0x08, 0xA6, 0x88, 0x04, 0xA4, 0x02, 0xA0, 0x00,
+  0x00, 0x10, 0x00, 0x00, 0x02, 0x00, 0x24, 0x02,
+  0x04, 0x0A, 0x00, 0x00, 0x08, 0xA6, 0x00, 0x08,
+  0x11);
+   mipi_dsi_dcs_write_seq(lcd->dsi, 0xD3, 0x00, 0x00, 0x00, 0X00, 0x00,
+  0x00, 0x18, 0x18, 0x32, 0x10, 0x09, 0x00, 0x09,
+  0x32, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x11, 0x00, 0x02, 0x02, 0x03, 0x00,
+  0x00, 0x00, 0x0A, 0x40);
+   mipi_dsi_dcs_write_seq(lcd->dsi, 0xD5, 0x18, 0x18, 0x18, 0x18,

[PATCH 1/3] dt-bindings: vendor-prefixes: add prefix for lincoln

2024-06-25 Thread Jerome Brunet
Lincoln Technology Solutions is a design services and LCD integration
company

Link: https://lincolntechsolutions.com/
Signed-off-by: Jerome Brunet 
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml 
b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index fbf47f0bacf1..dc7edf8c33c1 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -820,6 +820,8 @@ patternProperties:
 description: Lichee Pi
   "^linaro,.*":
 description: Linaro Limited
+  "^lincoln,.*":
+description: Lincoln Technology Solutions
   "^lineartechnology,.*":
 description: Linear Technology
   "^linksprite,.*":
-- 
2.43.0



[PATCH 0/3] drm: panel: add support lincoln LCD197 panel

2024-06-25 Thread Jerome Brunet
This patchset adds support for the Lincoln LCD197 1080x1920 DSI panel.

Jerome Brunet (3):
  dt-bindings: vendor-prefixes: add prefix for lincoln
  dt-bindings: panel-simple-dsi: add lincoln LCD197 panel bindings
  drm/panel: add lincoln lcd197 support

 .../display/panel/panel-simple-dsi.yaml   |   2 +
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 drivers/gpu/drm/panel/Kconfig |  11 +
 drivers/gpu/drm/panel/Makefile|   1 +
 drivers/gpu/drm/panel/panel-lincoln-lcd197.c  | 333 ++
 5 files changed, 349 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-lincoln-lcd197.c

-- 
2.43.0



  1   2   >