Re: [PATCH 4/4] drm/atomic-helper: Add select_output_bus_format callback

Maxime Ripard
2024-02-28T15:29:59Z

[-- Attachment #1.1: Type: text/plain, Size: 3739 bytes --]

Hi,

On Mon, Feb 26, 2024 at 08:44:45PM -0800, Anatoliy Klymenko wrote:
> Add select_output_bus_format to CRTC atomic helpers callbacks. This
> callback Will allow CRTC to participate in media bus format negotiation
> over connected DRM bridge chain and impose CRTC-specific restrictions.
> A good example is CRTC implemented as FPGA soft IP. This kind of CRTC will
> most certainly support a single output media bus format, as supporting
> multiple runtime options consumes extra FPGA resources. A variety of
> options for FPGA are usually achieved by synthesizing IP with different
> parameters.
>
> Incorporate select_output_bus_format callback into the format negotiation
> stage to fix the input bus format of the first DRM bridge in the chain.
>
> Signed-off-by: Anatoliy Klymenko <anatoliy.klymenko@amd.com>
> ---
> drivers/gpu/drm/drm_bridge.c | 19 +++++++++++++++++--
> include/drm/drm_modeset_helper_vtables.h | 31 +++++++++++++++++++++++++++++++
> 2 files changed, 48 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
> index 521a71c61b16..453ae3d174b4 100644
> --- a/drivers/gpu/drm/drm_bridge.c
> +++ b/drivers/gpu/drm/drm_bridge.c
> @@ -32,6 +32,7 @@
> #include <drm/drm_edid.h>
> #include <drm/drm_encoder.h>
> #include <drm/drm_file.h>
> +#include <drm/drm_modeset_helper_vtables.h>
> #include <drm/drm_of.h>
> #include <drm/drm_print.h>
>
> @@ -879,7 +880,8 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge,
> unsigned int i, num_in_bus_fmts = 0;
> struct drm_bridge_state *cur_state;
> struct drm_bridge *prev_bridge;
> - u32 *in_bus_fmts;
> + struct drm_crtc *crtc = crtc_state->crtc;
> + u32 *in_bus_fmts, in_fmt;
> int ret;
>
> prev_bridge = drm_bridge_get_prev_bridge(cur_bridge);
> @@ -933,7 +935,20 @@ static int select_bus_fmt_recursive(struct drm_bridge *first_bridge,
> return -ENOMEM;
>
> if (first_bridge == cur_bridge) {
> - cur_state->input_bus_cfg.format = in_bus_fmts[0];
> + in_fmt = in_bus_fmts[0];
> + if (crtc->helper_private &&
> + crtc->helper_private->select_output_bus_format) {
> + in_fmt = crtc->helper_private->select_output_bus_format(
> + crtc,
> + crtc->state,
> + in_bus_fmts,
> + num_in_bus_fmts);
> + if (!in_fmt) {
> + kfree(in_bus_fmts);
> + return -ENOTSUPP;
> + }
> + }
> + cur_state->input_bus_cfg.format = in_fmt;

I don't think we should start poking at the CRTC internals, but we
should rather provide a helper here.

> cur_state->output_bus_cfg.format = out_bus_fmt;
> kfree(in_bus_fmts);
> return 0;
> diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
> index 881b03e4dc28..7c21ae1fe3ad 100644
> --- a/include/drm/drm_modeset_helper_vtables.h
> +++ b/include/drm/drm_modeset_helper_vtables.h
> @@ -489,6 +489,37 @@ struct drm_crtc_helper_funcs {
> bool in_vblank_irq, int *vpos, int *hpos,
> ktime_t *stime, ktime_t *etime,
> const struct drm_display_mode *mode);
> +
> + /**
> + * @select_output_bus_format
> + *
> + * Called by the first connected DRM bridge to negotiate input media
> + * bus format. CRTC is expected to pick preferable media formats from
> + * the list supported by the DRM bridge chain.

There's nothing restricting it to bridges here. Please rephrase this to
remove the bridge mention. The user is typically going to be the
encoder, and bridges are just an automagic implementation of an encoder.

And generally speaking, I'd really like to have an implementation
available before merging this.

Maxime

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]