diff mbox series

[3/4] drm: xlnx: zynqmp_dpsub: Set input live format

Message ID 20240226-dp-live-fmt-v1-3-b78c3f69c9d8@amd.com (mailing list archive)
State New, archived
Headers show
Series Setting live video input format for ZynqMP DPSUB | expand

Commit Message

Klymenko, Anatoliy Feb. 27, 2024, 4:44 a.m. UTC
Program live video input format according to selected media bus format.

In the bridge mode of operation, DPSUB is connected to FPGA CRTC which
almost certainly supports a single media bus format as its output. Expect
this to be delivered via the new bridge atomic state. Program DPSUB
registers accordingly.

Signed-off-by: Anatoliy Klymenko <anatoliy.klymenko@amd.com>
---
 drivers/gpu/drm/xlnx/zynqmp_disp.c      | 52 +++++++++++++++++++++++++++++++++
 drivers/gpu/drm/xlnx/zynqmp_disp.h      |  2 ++
 drivers/gpu/drm/xlnx/zynqmp_disp_regs.h |  8 ++---
 drivers/gpu/drm/xlnx/zynqmp_dp.c        | 13 ++++++---
 4 files changed, 67 insertions(+), 8 deletions(-)

Comments

Laurent Pinchart Feb. 28, 2024, 4:07 p.m. UTC | #1
Hi Anatoliy,

Thank you for the patch.

On Mon, Feb 26, 2024 at 08:44:44PM -0800, Anatoliy Klymenko wrote:
> Program live video input format according to selected media bus format.
> 
> In the bridge mode of operation, DPSUB is connected to FPGA CRTC which
> almost certainly supports a single media bus format as its output. Expect
> this to be delivered via the new bridge atomic state. Program DPSUB
> registers accordingly.
> 
> Signed-off-by: Anatoliy Klymenko <anatoliy.klymenko@amd.com>
> ---
>  drivers/gpu/drm/xlnx/zynqmp_disp.c      | 52 +++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/xlnx/zynqmp_disp.h      |  2 ++
>  drivers/gpu/drm/xlnx/zynqmp_disp_regs.h |  8 ++---
>  drivers/gpu/drm/xlnx/zynqmp_dp.c        | 13 ++++++---
>  4 files changed, 67 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c b/drivers/gpu/drm/xlnx/zynqmp_disp.c
> index ee99aad915ba..1c3ffdee6b8e 100644
> --- a/drivers/gpu/drm/xlnx/zynqmp_disp.c
> +++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c
> @@ -416,6 +416,34 @@ static bool zynqmp_disp_layer_is_video(const struct zynqmp_disp_layer *layer)
>  	return layer->id == ZYNQMP_DPSUB_LAYER_VID;
>  }
>  
> +/**
> + * zynqmp_disp_avbuf_set_live_format - Set live input format for a layer
> + * @disp: Display controller
> + * @layer: The layer
> + * @fmt: The format information
> + *
> + * Set the live video input format for @layer to @fmt.
> + */
> +static void zynqmp_disp_avbuf_set_live_format(struct zynqmp_disp *disp,
> +					      struct zynqmp_disp_layer *layer,
> +					      const struct zynqmp_disp_format *fmt)
> +{
> +	u32 reg, i;
> +
> +	reg = zynqmp_disp_layer_is_video(layer)
> +	    ? ZYNQMP_DISP_AV_BUF_LIVE_VID_CONFIG
> +	    : ZYNQMP_DISP_AV_BUF_LIVE_GFX_CONFIG;
> +	zynqmp_disp_avbuf_write(disp, reg, fmt->buf_fmt);
> +
> +	for (i = 0; i < ZYNQMP_DISP_AV_BUF_NUM_SF; ++i) {
> +		reg = zynqmp_disp_layer_is_video(layer)
> +		    ? ZYNQMP_DISP_AV_BUF_LIVD_VID_COMP_SF(i)
> +		    : ZYNQMP_DISP_AV_BUF_LIVD_GFX_COMP_SF(i);
> +		zynqmp_disp_avbuf_write(disp, reg, fmt->sf[i]);
> +	}

This is identical to zynqmp_disp_avbuf_set_format(), you should avoid
duplicating code.

> +	layer->disp_fmt = fmt;
> +}
> +
>  /**
>   * zynqmp_disp_avbuf_set_format - Set the input format for a layer
>   * @disp: Display controller
> @@ -979,6 +1007,30 @@ void zynqmp_disp_layer_disable(struct zynqmp_disp_layer *layer)
>  	zynqmp_disp_blend_layer_disable(layer->disp, layer);
>  }
>  
> +/**
> + * zynqmp_disp_layer_set_live_format - Set live layer input format
> + * @layer: The layer
> + * @info: Input media bus format
> + *
> + * Set the live @layer input bus format. The layer must be disabled.
> + */
> +void zynqmp_disp_layer_set_live_format(struct zynqmp_disp_layer *layer,
> +				       u32 bus_format)

I'd prefer reusing zynqmp_disp_layer_set_format(), and handling the
differences between live and non-live input there. There's already a
dma_enabled check in that function.

> +{
> +	int i;
> +	const struct zynqmp_disp_format *fmt;
> +
> +	for (i = 0; i < ARRAY_SIZE(avbuf_live_fmts); ++i) {
> +		fmt = &avbuf_live_fmts[i];
> +		if (fmt->bus_fmt == bus_format) {
> +			layer->disp_fmt = fmt;
> +			layer->drm_fmt = drm_format_info(fmt->drm_fmt);
> +			zynqmp_disp_avbuf_set_live_format(layer->disp, layer, fmt);
> +			return;
> +		}
> +	}
> +}
> +
>  /**
>   * zynqmp_disp_layer_set_format - Set the layer format
>   * @layer: The layer
> diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.h b/drivers/gpu/drm/xlnx/zynqmp_disp.h
> index c2c8dd4896ba..f244b7d2346a 100644
> --- a/drivers/gpu/drm/xlnx/zynqmp_disp.h
> +++ b/drivers/gpu/drm/xlnx/zynqmp_disp.h
> @@ -66,6 +66,8 @@ void zynqmp_disp_layer_enable(struct zynqmp_disp_layer *layer);
>  void zynqmp_disp_layer_disable(struct zynqmp_disp_layer *layer);
>  void zynqmp_disp_layer_set_format(struct zynqmp_disp_layer *layer,
>  				  const struct drm_format_info *info);
> +void zynqmp_disp_layer_set_live_format(struct zynqmp_disp_layer *layer,
> +				       u32 bus_format);
>  int zynqmp_disp_layer_update(struct zynqmp_disp_layer *layer,
>  			     struct drm_plane_state *state);
>  
> diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp_regs.h b/drivers/gpu/drm/xlnx/zynqmp_disp_regs.h
> index f92a006d5070..fa3935384834 100644
> --- a/drivers/gpu/drm/xlnx/zynqmp_disp_regs.h
> +++ b/drivers/gpu/drm/xlnx/zynqmp_disp_regs.h
> @@ -165,10 +165,10 @@
>  #define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_BPC_10		0x2
>  #define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_BPC_12		0x3
>  #define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_BPC_MASK		GENMASK(2, 0)
> -#define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_RGB		0x0
> -#define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YUV444	0x1
> -#define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YUV422	0x2
> -#define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YONLY	0x3
> +#define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_RGB		(0x0 << 4)
> +#define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YUV444	(0x1 << 4)
> +#define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YUV422	(0x2 << 4)
> +#define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YONLY	(0x3 << 4)

This change isn't even mentioned in the commit message. It should be
split to a separate patch.

>  #define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_MASK		GENMASK(5, 4)
>  #define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_CB_FIRST		BIT(8)
>  #define ZYNQMP_DISP_AV_BUF_PALETTE_MEMORY		0x400
> diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> index 9cb7ac9f3097..0d5dffd20ad1 100644
> --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
> +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> @@ -1281,7 +1281,8 @@ static void zynqmp_dp_disp_enable(struct zynqmp_dp *dp,
>  {
>  	enum zynqmp_dpsub_layer_id layer_id;
>  	struct zynqmp_disp_layer *layer;
> -	const struct drm_format_info *info;
> +	struct drm_bridge_state *bridge_state;
> +	u32 bus_fmt;
>  
>  	if (dp->dpsub->connected_ports & BIT(ZYNQMP_DPSUB_PORT_LIVE_VIDEO))
>  		layer_id = ZYNQMP_DPSUB_LAYER_VID;
> @@ -1291,10 +1292,14 @@ static void zynqmp_dp_disp_enable(struct zynqmp_dp *dp,
>  		return;
>  
>  	layer = dp->dpsub->layers[layer_id];
> +	bridge_state = drm_atomic_get_new_bridge_state(old_bridge_state->base.state,
> +						       old_bridge_state->bridge);
> +	if (bridge_state) {
> +		bus_fmt = bridge_state->input_bus_cfg.format;
> +		zynqmp_disp_layer_set_live_format(layer, bus_fmt);
> +	} else
> +		return;

	if (!bridge_state)
		return;

	bus_fmt = bridge_state->input_bus_cfg.format;
	zynqmp_disp_layer_set_live_format(layer, bus_fmt);

But more importantly, why would this fail ? If it does something is
seriously wrong and the display won't be working. I'd expect at least a
warning, but you should instead ensure it never fails.

>  
> -	/* TODO: Make the format configurable. */
> -	info = drm_format_info(DRM_FORMAT_YUV422);
> -	zynqmp_disp_layer_set_format(layer, info);
>  	zynqmp_disp_layer_enable(layer);
>  
>  	if (layer_id == ZYNQMP_DPSUB_LAYER_GFX)
>
Klymenko, Anatoliy Feb. 28, 2024, 10:17 p.m. UTC | #2
Hi Laurent,

Thanks a lot for the review.

> -----Original Message-----
> From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> Sent: Wednesday, February 28, 2024 8:08 AM
> To: Klymenko, Anatoliy <Anatoliy.Klymenko@amd.com>
> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>; Maxime Ripard
> <mripard@kernel.org>; Thomas Zimmermann <tzimmermann@suse.de>; David
> Airlie <airlied@gmail.com>; Daniel Vetter <daniel@ffwll.ch>; Simek, Michal
> <michal.simek@amd.com>; Andrzej Hajda <andrzej.hajda@intel.com>; Neil
> Armstrong <neil.armstrong@linaro.org>; Robert Foss <rfoss@kernel.org>; Jonas
> Karlman <jonas@kwiboo.se>; Jernej Skrabec <jernej.skrabec@gmail.com>; dri-
> devel@lists.freedesktop.org; linux-arm-kernel@lists.infradead.org; linux-
> kernel@vger.kernel.org
> Subject: Re: [PATCH 3/4] drm: xlnx: zynqmp_dpsub: Set input live format
> 
> Caution: This message originated from an External Source. Use proper caution
> when opening attachments, clicking links, or responding.
> 
> 
> Hi Anatoliy,
> 
> Thank you for the patch.
> 
> On Mon, Feb 26, 2024 at 08:44:44PM -0800, Anatoliy Klymenko wrote:
> > Program live video input format according to selected media bus format.
> >
> > In the bridge mode of operation, DPSUB is connected to FPGA CRTC which
> > almost certainly supports a single media bus format as its output.
> > Expect this to be delivered via the new bridge atomic state. Program
> > DPSUB registers accordingly.
> >
> > Signed-off-by: Anatoliy Klymenko <anatoliy.klymenko@amd.com>
> > ---
> >  drivers/gpu/drm/xlnx/zynqmp_disp.c      | 52
> +++++++++++++++++++++++++++++++++
> >  drivers/gpu/drm/xlnx/zynqmp_disp.h      |  2 ++
> >  drivers/gpu/drm/xlnx/zynqmp_disp_regs.h |  8 ++---
> >  drivers/gpu/drm/xlnx/zynqmp_dp.c        | 13 ++++++---
> >  4 files changed, 67 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c
> > b/drivers/gpu/drm/xlnx/zynqmp_disp.c
> > index ee99aad915ba..1c3ffdee6b8e 100644
> > --- a/drivers/gpu/drm/xlnx/zynqmp_disp.c
> > +++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c
> > @@ -416,6 +416,34 @@ static bool zynqmp_disp_layer_is_video(const struct
> zynqmp_disp_layer *layer)
> >       return layer->id == ZYNQMP_DPSUB_LAYER_VID;  }
> >
> > +/**
> > + * zynqmp_disp_avbuf_set_live_format - Set live input format for a
> > +layer
> > + * @disp: Display controller
> > + * @layer: The layer
> > + * @fmt: The format information
> > + *
> > + * Set the live video input format for @layer to @fmt.
> > + */
> > +static void zynqmp_disp_avbuf_set_live_format(struct zynqmp_disp *disp,
> > +                                           struct zynqmp_disp_layer *layer,
> > +                                           const struct
> > +zynqmp_disp_format *fmt) {
> > +     u32 reg, i;
> > +
> > +     reg = zynqmp_disp_layer_is_video(layer)
> > +         ? ZYNQMP_DISP_AV_BUF_LIVE_VID_CONFIG
> > +         : ZYNQMP_DISP_AV_BUF_LIVE_GFX_CONFIG;
> > +     zynqmp_disp_avbuf_write(disp, reg, fmt->buf_fmt);
> > +
> > +     for (i = 0; i < ZYNQMP_DISP_AV_BUF_NUM_SF; ++i) {
> > +             reg = zynqmp_disp_layer_is_video(layer)
> > +                 ? ZYNQMP_DISP_AV_BUF_LIVD_VID_COMP_SF(i)
> > +                 : ZYNQMP_DISP_AV_BUF_LIVD_GFX_COMP_SF(i);
> > +             zynqmp_disp_avbuf_write(disp, reg, fmt->sf[i]);
> > +     }
> 
> This is identical to zynqmp_disp_avbuf_set_format(), you should avoid duplicating
> code.
> 

Yeah, there are similarities - let me think on how to refactor this properly.

> > +     layer->disp_fmt = fmt;
> > +}
> > +
> >  /**
> >   * zynqmp_disp_avbuf_set_format - Set the input format for a layer
> >   * @disp: Display controller
> > @@ -979,6 +1007,30 @@ void zynqmp_disp_layer_disable(struct
> zynqmp_disp_layer *layer)
> >       zynqmp_disp_blend_layer_disable(layer->disp, layer);  }
> >
> > +/**
> > + * zynqmp_disp_layer_set_live_format - Set live layer input format
> > + * @layer: The layer
> > + * @info: Input media bus format
> > + *
> > + * Set the live @layer input bus format. The layer must be disabled.
> > + */
> > +void zynqmp_disp_layer_set_live_format(struct zynqmp_disp_layer *layer,
> > +                                    u32 bus_format)
> 
> I'd prefer reusing zynqmp_disp_layer_set_format(), and handling the differences
> between live and non-live input there. There's already a dma_enabled check in
> that function.
> 

There is a difference between setting format for dma-backed layer vs live input layer. In the first case we have memory layout in fourcc format, but in the second case we have video signal described by media bus format. Anyways, let me check if I can unify both cases.

> > +{
> > +     int i;
> > +     const struct zynqmp_disp_format *fmt;
> > +
> > +     for (i = 0; i < ARRAY_SIZE(avbuf_live_fmts); ++i) {
> > +             fmt = &avbuf_live_fmts[i];
> > +             if (fmt->bus_fmt == bus_format) {
> > +                     layer->disp_fmt = fmt;
> > +                     layer->drm_fmt = drm_format_info(fmt->drm_fmt);
> > +                     zynqmp_disp_avbuf_set_live_format(layer->disp, layer, fmt);
> > +                     return;
> > +             }
> > +     }
> > +}
> > +
> >  /**
> >   * zynqmp_disp_layer_set_format - Set the layer format
> >   * @layer: The layer
> > diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.h
> > b/drivers/gpu/drm/xlnx/zynqmp_disp.h
> > index c2c8dd4896ba..f244b7d2346a 100644
> > --- a/drivers/gpu/drm/xlnx/zynqmp_disp.h
> > +++ b/drivers/gpu/drm/xlnx/zynqmp_disp.h
> > @@ -66,6 +66,8 @@ void zynqmp_disp_layer_enable(struct
> > zynqmp_disp_layer *layer);  void zynqmp_disp_layer_disable(struct
> > zynqmp_disp_layer *layer);  void zynqmp_disp_layer_set_format(struct
> zynqmp_disp_layer *layer,
> >                                 const struct drm_format_info *info);
> > +void zynqmp_disp_layer_set_live_format(struct zynqmp_disp_layer *layer,
> > +                                    u32 bus_format);
> >  int zynqmp_disp_layer_update(struct zynqmp_disp_layer *layer,
> >                            struct drm_plane_state *state);
> >
> > diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp_regs.h
> > b/drivers/gpu/drm/xlnx/zynqmp_disp_regs.h
> > index f92a006d5070..fa3935384834 100644
> > --- a/drivers/gpu/drm/xlnx/zynqmp_disp_regs.h
> > +++ b/drivers/gpu/drm/xlnx/zynqmp_disp_regs.h
> > @@ -165,10 +165,10 @@
> >  #define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_BPC_10                0x2
> >  #define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_BPC_12                0x3
> >  #define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_BPC_MASK
> GENMASK(2, 0)
> > -#define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_RGB               0x0
> > -#define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YUV444    0x1
> > -#define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YUV422    0x2
> > -#define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YONLY     0x3
> > +#define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_RGB               (0x0 << 4)
> > +#define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YUV444    (0x1 << 4)
> > +#define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YUV422    (0x2 << 4)
> > +#define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YONLY     (0x3 << 4)
> 
> This change isn't even mentioned in the commit message. It should be split to a
> separate patch.
> 

This patch is the first instance of these defines usage. Anyways, I'll split it. Thank you.

> >  #define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_MASK
> GENMASK(5, 4)
> >  #define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_CB_FIRST              BIT(8)
> >  #define ZYNQMP_DISP_AV_BUF_PALETTE_MEMORY            0x400
> > diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c
> > b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> > index 9cb7ac9f3097..0d5dffd20ad1 100644
> > --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
> > +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
> > @@ -1281,7 +1281,8 @@ static void zynqmp_dp_disp_enable(struct
> > zynqmp_dp *dp,  {
> >       enum zynqmp_dpsub_layer_id layer_id;
> >       struct zynqmp_disp_layer *layer;
> > -     const struct drm_format_info *info;
> > +     struct drm_bridge_state *bridge_state;
> > +     u32 bus_fmt;
> >
> >       if (dp->dpsub->connected_ports &
> BIT(ZYNQMP_DPSUB_PORT_LIVE_VIDEO))
> >               layer_id = ZYNQMP_DPSUB_LAYER_VID; @@ -1291,10 +1292,14
> > @@ static void zynqmp_dp_disp_enable(struct zynqmp_dp *dp,
> >               return;
> >
> >       layer = dp->dpsub->layers[layer_id];
> > +     bridge_state = drm_atomic_get_new_bridge_state(old_bridge_state-
> >base.state,
> > +                                                    old_bridge_state->bridge);
> > +     if (bridge_state) {
> > +             bus_fmt = bridge_state->input_bus_cfg.format;
> > +             zynqmp_disp_layer_set_live_format(layer, bus_fmt);
> > +     } else
> > +             return;
> 
>         if (!bridge_state)
>                 return;
> 
>         bus_fmt = bridge_state->input_bus_cfg.format;
>         zynqmp_disp_layer_set_live_format(layer, bus_fmt);
> 
> But more importantly, why would this fail ? If it does something is seriously wrong
> and the display won't be working. I'd expect at least a warning, but you should
> instead ensure it never fails.
> 

According to drm_atomic_get_new_bridge_state() doc, it is possible that bridge state is not a part of the global atomic state. But, most likely in this case bridge enable() callback will be omitted completely. I'll check this - thank you.

> >
> > -     /* TODO: Make the format configurable. */
> > -     info = drm_format_info(DRM_FORMAT_YUV422);
> > -     zynqmp_disp_layer_set_format(layer, info);
> >       zynqmp_disp_layer_enable(layer);
> >
> >       if (layer_id == ZYNQMP_DPSUB_LAYER_GFX)
> >
> 
> --
> Regards,
> 
> Laurent Pinchart

Thank you,
Anatoliy
kernel test robot March 3, 2024, 5:15 p.m. UTC | #3
Hi Anatoliy,

kernel test robot noticed the following build warnings:

[auto build test WARNING on bfa4437fd3938ae2e186e7664b2db65bb8775670]

url:    https://github.com/intel-lab-lkp/linux/commits/Anatoliy-Klymenko/drm-xlnx-zynqmp_dpsub-Set-layer-mode-during-creation/20240227-124631
base:   bfa4437fd3938ae2e186e7664b2db65bb8775670
patch link:    https://lore.kernel.org/r/20240226-dp-live-fmt-v1-3-b78c3f69c9d8%40amd.com
patch subject: [PATCH 3/4] drm: xlnx: zynqmp_dpsub: Set input live format
config: x86_64-allmodconfig (https://download.01.org/0day-ci/archive/20240304/202403040104.mwzqu5gs-lkp@intel.com/config)
compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240304/202403040104.mwzqu5gs-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202403040104.mwzqu5gs-lkp@intel.com/

All warnings (new ones prefixed by >>):

   drivers/gpu/drm/xlnx/zynqmp_disp.c:164: warning: Function parameter or struct member 'blend' not described in 'zynqmp_disp'
   drivers/gpu/drm/xlnx/zynqmp_disp.c:164: warning: Function parameter or struct member 'avbuf' not described in 'zynqmp_disp'
   drivers/gpu/drm/xlnx/zynqmp_disp.c:164: warning: Function parameter or struct member 'audio' not described in 'zynqmp_disp'
>> drivers/gpu/drm/xlnx/zynqmp_disp.c:1019: warning: Function parameter or struct member 'bus_format' not described in 'zynqmp_disp_layer_set_live_format'
>> drivers/gpu/drm/xlnx/zynqmp_disp.c:1019: warning: Excess function parameter 'info' description in 'zynqmp_disp_layer_set_live_format'


vim +1019 drivers/gpu/drm/xlnx/zynqmp_disp.c

  1009	
  1010	/**
  1011	 * zynqmp_disp_layer_set_live_format - Set live layer input format
  1012	 * @layer: The layer
  1013	 * @info: Input media bus format
  1014	 *
  1015	 * Set the live @layer input bus format. The layer must be disabled.
  1016	 */
  1017	void zynqmp_disp_layer_set_live_format(struct zynqmp_disp_layer *layer,
  1018					       u32 bus_format)
> 1019	{
  1020		int i;
  1021		const struct zynqmp_disp_format *fmt;
  1022	
  1023		for (i = 0; i < ARRAY_SIZE(avbuf_live_fmts); ++i) {
  1024			fmt = &avbuf_live_fmts[i];
  1025			if (fmt->bus_fmt == bus_format) {
  1026				layer->disp_fmt = fmt;
  1027				layer->drm_fmt = drm_format_info(fmt->drm_fmt);
  1028				zynqmp_disp_avbuf_set_live_format(layer->disp, layer, fmt);
  1029				return;
  1030			}
  1031		}
  1032	}
  1033
diff mbox series

Patch

diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c b/drivers/gpu/drm/xlnx/zynqmp_disp.c
index ee99aad915ba..1c3ffdee6b8e 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_disp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c
@@ -416,6 +416,34 @@  static bool zynqmp_disp_layer_is_video(const struct zynqmp_disp_layer *layer)
 	return layer->id == ZYNQMP_DPSUB_LAYER_VID;
 }
 
+/**
+ * zynqmp_disp_avbuf_set_live_format - Set live input format for a layer
+ * @disp: Display controller
+ * @layer: The layer
+ * @fmt: The format information
+ *
+ * Set the live video input format for @layer to @fmt.
+ */
+static void zynqmp_disp_avbuf_set_live_format(struct zynqmp_disp *disp,
+					      struct zynqmp_disp_layer *layer,
+					      const struct zynqmp_disp_format *fmt)
+{
+	u32 reg, i;
+
+	reg = zynqmp_disp_layer_is_video(layer)
+	    ? ZYNQMP_DISP_AV_BUF_LIVE_VID_CONFIG
+	    : ZYNQMP_DISP_AV_BUF_LIVE_GFX_CONFIG;
+	zynqmp_disp_avbuf_write(disp, reg, fmt->buf_fmt);
+
+	for (i = 0; i < ZYNQMP_DISP_AV_BUF_NUM_SF; ++i) {
+		reg = zynqmp_disp_layer_is_video(layer)
+		    ? ZYNQMP_DISP_AV_BUF_LIVD_VID_COMP_SF(i)
+		    : ZYNQMP_DISP_AV_BUF_LIVD_GFX_COMP_SF(i);
+		zynqmp_disp_avbuf_write(disp, reg, fmt->sf[i]);
+	}
+	layer->disp_fmt = fmt;
+}
+
 /**
  * zynqmp_disp_avbuf_set_format - Set the input format for a layer
  * @disp: Display controller
@@ -979,6 +1007,30 @@  void zynqmp_disp_layer_disable(struct zynqmp_disp_layer *layer)
 	zynqmp_disp_blend_layer_disable(layer->disp, layer);
 }
 
+/**
+ * zynqmp_disp_layer_set_live_format - Set live layer input format
+ * @layer: The layer
+ * @info: Input media bus format
+ *
+ * Set the live @layer input bus format. The layer must be disabled.
+ */
+void zynqmp_disp_layer_set_live_format(struct zynqmp_disp_layer *layer,
+				       u32 bus_format)
+{
+	int i;
+	const struct zynqmp_disp_format *fmt;
+
+	for (i = 0; i < ARRAY_SIZE(avbuf_live_fmts); ++i) {
+		fmt = &avbuf_live_fmts[i];
+		if (fmt->bus_fmt == bus_format) {
+			layer->disp_fmt = fmt;
+			layer->drm_fmt = drm_format_info(fmt->drm_fmt);
+			zynqmp_disp_avbuf_set_live_format(layer->disp, layer, fmt);
+			return;
+		}
+	}
+}
+
 /**
  * zynqmp_disp_layer_set_format - Set the layer format
  * @layer: The layer
diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.h b/drivers/gpu/drm/xlnx/zynqmp_disp.h
index c2c8dd4896ba..f244b7d2346a 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_disp.h
+++ b/drivers/gpu/drm/xlnx/zynqmp_disp.h
@@ -66,6 +66,8 @@  void zynqmp_disp_layer_enable(struct zynqmp_disp_layer *layer);
 void zynqmp_disp_layer_disable(struct zynqmp_disp_layer *layer);
 void zynqmp_disp_layer_set_format(struct zynqmp_disp_layer *layer,
 				  const struct drm_format_info *info);
+void zynqmp_disp_layer_set_live_format(struct zynqmp_disp_layer *layer,
+				       u32 bus_format);
 int zynqmp_disp_layer_update(struct zynqmp_disp_layer *layer,
 			     struct drm_plane_state *state);
 
diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp_regs.h b/drivers/gpu/drm/xlnx/zynqmp_disp_regs.h
index f92a006d5070..fa3935384834 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_disp_regs.h
+++ b/drivers/gpu/drm/xlnx/zynqmp_disp_regs.h
@@ -165,10 +165,10 @@ 
 #define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_BPC_10		0x2
 #define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_BPC_12		0x3
 #define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_BPC_MASK		GENMASK(2, 0)
-#define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_RGB		0x0
-#define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YUV444	0x1
-#define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YUV422	0x2
-#define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YONLY	0x3
+#define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_RGB		(0x0 << 4)
+#define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YUV444	(0x1 << 4)
+#define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YUV422	(0x2 << 4)
+#define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_YONLY	(0x3 << 4)
 #define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_FMT_MASK		GENMASK(5, 4)
 #define ZYNQMP_DISP_AV_BUF_LIVE_CONFIG_CB_FIRST		BIT(8)
 #define ZYNQMP_DISP_AV_BUF_PALETTE_MEMORY		0x400
diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c
index 9cb7ac9f3097..0d5dffd20ad1 100644
--- a/drivers/gpu/drm/xlnx/zynqmp_dp.c
+++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c
@@ -1281,7 +1281,8 @@  static void zynqmp_dp_disp_enable(struct zynqmp_dp *dp,
 {
 	enum zynqmp_dpsub_layer_id layer_id;
 	struct zynqmp_disp_layer *layer;
-	const struct drm_format_info *info;
+	struct drm_bridge_state *bridge_state;
+	u32 bus_fmt;
 
 	if (dp->dpsub->connected_ports & BIT(ZYNQMP_DPSUB_PORT_LIVE_VIDEO))
 		layer_id = ZYNQMP_DPSUB_LAYER_VID;
@@ -1291,10 +1292,14 @@  static void zynqmp_dp_disp_enable(struct zynqmp_dp *dp,
 		return;
 
 	layer = dp->dpsub->layers[layer_id];
+	bridge_state = drm_atomic_get_new_bridge_state(old_bridge_state->base.state,
+						       old_bridge_state->bridge);
+	if (bridge_state) {
+		bus_fmt = bridge_state->input_bus_cfg.format;
+		zynqmp_disp_layer_set_live_format(layer, bus_fmt);
+	} else
+		return;
 
-	/* TODO: Make the format configurable. */
-	info = drm_format_info(DRM_FORMAT_YUV422);
-	zynqmp_disp_layer_set_format(layer, info);
 	zynqmp_disp_layer_enable(layer);
 
 	if (layer_id == ZYNQMP_DPSUB_LAYER_GFX)