Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Maxime Ripard <mripard@kernel.org>
To: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Cc: "Andrzej Hajda" <andrzej.hajda@intel.com>,
	"Neil Armstrong" <neil.armstrong@linaro.org>,
	"Robert Foss" <rfoss@kernel.org>,
	"Laurent Pinchart" <Laurent.pinchart@ideasonboard.com>,
	"Jonas Karlman" <jonas@kwiboo.se>,
	"Jernej Skrabec" <jernej.skrabec@gmail.com>,
	"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
	"Thomas Zimmermann" <tzimmermann@suse.de>,
	"David Airlie" <airlied@gmail.com>,
	"Simona Vetter" <simona@ffwll.ch>,
	"Jaroslav Kysela" <perex@perex.cz>,
	"Takashi Iwai" <tiwai@suse.com>,
	"Liam Girdwood" <lgirdwood@gmail.com>,
	"Mark Brown" <broonie@kernel.org>, "Phong LE" <ple@baylibre.com>,
	"Inki Dae" <inki.dae@samsung.com>,
	"Seung-Woo Kim" <sw0312.kim@samsung.com>,
	"Kyungmin Park" <kyungmin.park@samsung.com>,
	"Krzysztof Kozlowski" <krzk@kernel.org>,
	"Alim Akhtar" <alim.akhtar@samsung.com>,
	"Russell King" <linux@armlinux.org.uk>,
	"Chun-Kuang Hu" <chunkuang.hu@kernel.org>,
	"Philipp Zabel" <p.zabel@pengutronix.de>,
	"Matthias Brugger" <matthias.bgg@gmail.com>,
	"AngeloGioacchino Del Regno"
	<angelogioacchino.delregno@collabora.com>,
	"Sandy Huang" <hjc@rock-chips.com>,
	"Heiko Stübner" <heiko@sntech.de>,
	"Andy Yan" <andy.yan@rock-chips.com>,
	"Alain Volmat" <alain.volmat@foss.st.com>,
	"Raphael Gallais-Pou" <rgallaispou@gmail.com>,
	"Dave Stevenson" <dave.stevenson@raspberrypi.com>,
	"Maíra Canal" <mcanal@igalia.com>,
	"Raspberry Pi Kernel Maintenance" <kernel-list@raspberrypi.com>,
	"Jani Nikula" <jani.nikula@linux.intel.com>,
	dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
	linux-sound@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-samsung-soc@vger.kernel.org,
	linux-mediatek@lists.infradead.org,
	linux-rockchip@lists.infradead.org
Subject: Re: [PATCH v7 03/10] drm/connector: implement generic HDMI codec helpers
Date: Tue, 17 Dec 2024 18:22:37 +0100	[thread overview]
Message-ID: <20241217-thistle-rattlesnake-of-current-dfd247@houat> (raw)
In-Reply-To: <20241217-drm-bridge-hdmi-connector-v7-3-cb9df2b6a515@linaro.org>

[-- Attachment #1: Type: text/plain, Size: 10284 bytes --]

On Tue, Dec 17, 2024 at 02:40:25AM +0200, Dmitry Baryshkov wrote:
> Several DRM drivers implement HDMI codec support (despite its name it
> applies to both HDMI and DisplayPort drivers). Implement generic
> framework to be used by these drivers. This removes a requirement to
> implement get_eld() callback and provides default implementation for
> codec's plug handling.
> 
> The framework is integrated with the DRM HDMI Connector framework, but
> can be used by DisplayPort drivers.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>  drivers/gpu/drm/Makefile                   |   1 +
>  drivers/gpu/drm/drm_connector.c            |   5 +
>  drivers/gpu/drm/drm_connector_hdmi_codec.c | 189 +++++++++++++++++++++++++++++
>  include/drm/drm_connector.h                | 125 +++++++++++++++++++
>  4 files changed, 320 insertions(+)
> 
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index 19fb370fbc56772077973c864df71e4b8e0bf99b..46e6dbc355afe4015ff2327ba04211cdc011a0b7 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -42,6 +42,7 @@ drm-y := \
>  	drm_cache.o \
>  	drm_color_mgmt.o \
>  	drm_connector.o \
> +	drm_connector_hdmi_codec.o \
>  	drm_crtc.o \
>  	drm_displayid.o \
>  	drm_drv.o \
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index bbdaaf7022b62d84594a29f1b60144920903a99a..4abfbded962bf45b793a2bd5b1b5c4d9f478a1f7 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -33,6 +33,7 @@
>  #include <drm/drm_sysfs.h>
>  #include <drm/drm_utils.h>
>  
> +#include <linux/platform_device.h>
>  #include <linux/property.h>
>  #include <linux/uaccess.h>
>  
> @@ -280,6 +281,7 @@ static int __drm_connector_init(struct drm_device *dev,
>  	mutex_init(&connector->eld_mutex);
>  	mutex_init(&connector->edid_override_mutex);
>  	mutex_init(&connector->hdmi.infoframes.lock);
> +	mutex_init(&connector->hdmi_codec.lock);
>  	connector->edid_blob_ptr = NULL;
>  	connector->epoch_counter = 0;
>  	connector->tile_blob_ptr = NULL;
> @@ -632,6 +634,8 @@ void drm_connector_cleanup(struct drm_connector *connector)
>  		    DRM_CONNECTOR_REGISTERED))
>  		drm_connector_unregister(connector);
>  
> +	platform_device_unregister(connector->hdmi_codec.codec_pdev);
> +
>  	if (connector->privacy_screen) {
>  		drm_privacy_screen_put(connector->privacy_screen);
>  		connector->privacy_screen = NULL;
> @@ -670,6 +674,7 @@ void drm_connector_cleanup(struct drm_connector *connector)
>  		connector->funcs->atomic_destroy_state(connector,
>  						       connector->state);
>  
> +	mutex_destroy(&connector->hdmi_codec.lock);
>  	mutex_destroy(&connector->hdmi.infoframes.lock);
>  	mutex_destroy(&connector->mutex);
>  
> diff --git a/drivers/gpu/drm/drm_connector_hdmi_codec.c b/drivers/gpu/drm/drm_connector_hdmi_codec.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..a6e2f27c3f7ff9d57cf19c055870001daff4c676
> --- /dev/null
> +++ b/drivers/gpu/drm/drm_connector_hdmi_codec.c
> @@ -0,0 +1,189 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright (c) 2024 Linaro Ltd
> + */
> +
> +#include <linux/mutex.h>
> +#include <linux/of_graph.h>
> +#include <linux/platform_device.h>
> +
> +#include <drm/drm_connector.h>
> +#include <drm/drm_device.h>
> +
> +#include <sound/hdmi-codec.h>
> +
> +static int drm_connector_hdmi_codec_audio_startup(struct device *dev, void *data)
> +{
> +	struct drm_connector *connector = data;
> +	const struct drm_connector_hdmi_codec_funcs *funcs =
> +		connector->hdmi_codec.funcs;
> +
> +	if (funcs->audio_startup)
> +		return funcs->audio_startup(connector);
> +
> +	return 0;
> +}
> +
> +static int drm_connector_hdmi_codec_prepare(struct device *dev, void *data,
> +					    struct hdmi_codec_daifmt *fmt,
> +					    struct hdmi_codec_params *hparms)
> +{
> +	struct drm_connector *connector = data;
> +	const struct drm_connector_hdmi_codec_funcs *funcs =
> +		connector->hdmi_codec.funcs;
> +
> +	return funcs->prepare(connector, fmt, hparms);
> +}
> +
> +static void drm_connector_hdmi_codec_audio_shutdown(struct device *dev, void *data)
> +{
> +	struct drm_connector *connector = data;
> +	const struct drm_connector_hdmi_codec_funcs *funcs =
> +		connector->hdmi_codec.funcs;
> +
> +	return funcs->audio_shutdown(connector);
> +}
> +
> +static int drm_connector_hdmi_codec_mute_stream(struct device *dev, void *data,
> +						bool enable, int direction)
> +{
> +	struct drm_connector *connector = data;
> +	const struct drm_connector_hdmi_codec_funcs *funcs =
> +		connector->hdmi_codec.funcs;
> +
> +	if (funcs->mute_stream)
> +		return funcs->mute_stream(connector, enable, direction);
> +
> +	return -ENOTSUPP;
> +}
> +
> +static int drm_connector_hdmi_codec_get_dai_id(struct snd_soc_component *comment,
> +		  struct device_node *endpoint,
> +		  void *data)
> +{
> +	struct drm_connector *connector = data;
> +	struct of_endpoint of_ep;
> +	int ret;
> +
> +	if (connector->hdmi_codec.dai_port < 0)
> +		return -ENOTSUPP;
> +
> +	ret = of_graph_parse_endpoint(endpoint, &of_ep);
> +	if (ret < 0)
> +		return ret;
> +
> +	if (of_ep.port == connector->hdmi_codec.dai_port)
> +		return 0;
> +
> +	return -EINVAL;
> +}
> +
> +static int drm_connector_hdmi_codec_get_eld(struct device *dev, void *data,
> +					    uint8_t *buf, size_t len)
> +{
> +	struct drm_connector *connector = data;
> +
> +	mutex_lock(&connector->eld_mutex);
> +	memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
> +	mutex_unlock(&connector->eld_mutex);
> +
> +	return 0;
> +}
> +
> +static int drm_connector_hdmi_codec_hook_plugged_cb(struct device *dev,
> +						    void *data,
> +						    hdmi_codec_plugged_cb fn,
> +						    struct device *codec_dev)
> +{
> +	struct drm_connector *connector = data;
> +
> +	mutex_lock(&connector->hdmi_codec.lock);
> +
> +	connector->hdmi_codec.plugged_cb = fn;
> +	connector->hdmi_codec.plugged_cb_dev = codec_dev;
> +
> +	fn(codec_dev, connector->hdmi_codec.last_state);
> +
> +	mutex_unlock(&connector->hdmi_codec.lock);
> +
> +	return 0;
> +}
> +
> +void drm_connector_hdmi_codec_plugged_notify(struct drm_connector *connector,
> +					     bool plugged)
> +{
> +	mutex_lock(&connector->hdmi_codec.lock);
> +
> +	connector->hdmi_codec.last_state = plugged;
> +
> +	if (connector->hdmi_codec.plugged_cb &&
> +	    connector->hdmi_codec.plugged_cb_dev)
> +		connector->hdmi_codec.plugged_cb(connector->hdmi_codec.plugged_cb_dev,
> +						 connector->hdmi_codec.last_state);
> +
> +	mutex_unlock(&connector->hdmi_codec.lock);
> +}
> +EXPORT_SYMBOL(drm_connector_hdmi_codec_plugged_notify);
> +
> +static const struct hdmi_codec_ops drm_connector_hdmi_codec_ops = {
> +	.audio_startup = drm_connector_hdmi_codec_audio_startup,
> +	.prepare = drm_connector_hdmi_codec_prepare,
> +	.audio_shutdown = drm_connector_hdmi_codec_audio_shutdown,
> +	.mute_stream = drm_connector_hdmi_codec_mute_stream,
> +	.get_eld = drm_connector_hdmi_codec_get_eld,
> +	.get_dai_id = drm_connector_hdmi_codec_get_dai_id,
> +	.hook_plugged_cb = drm_connector_hdmi_codec_hook_plugged_cb,
> +};
> +
> +/**
> + * drm_connector_hdmi_audio_init - Initialize HDMI Codec device for the DRM connector
> + * @connector: A pointer to the connector to allocate codec for
> + * @hdmi_codec_dev: device to be used as a parent for the HDMI Codec
> + * @funcs: callbacks for this HDMI Codec
> + * @max_i2s_playback_channels: maximum number of playback I2S channels
> + * @spdif_playback: set if HDMI codec has S/PDIF playback port
> + * @dai_port: sound DAI port, -1 if it is not enabled
> + *
> + * Create a HDMI codec device to be used with the specified connector.
> + *
> + * Returns:
> + * Zero on success, error code on failure.
> + */
> +int drm_connector_hdmi_audio_init(struct drm_connector *connector,
> +				  struct device *hdmi_codec_dev,
> +				  const struct drm_connector_hdmi_codec_funcs *funcs,
> +				  unsigned int max_i2s_playback_channels,
> +				  bool spdif_playback,
> +				  int dai_port)
> +{
> +	struct hdmi_codec_pdata codec_pdata = {
> +		.ops = &drm_connector_hdmi_codec_ops,
> +		.max_i2s_channels = max_i2s_playback_channels,
> +		.i2s = !!max_i2s_playback_channels,
> +		.spdif = spdif_playback,
> +		.no_i2s_capture = true,
> +		.no_spdif_capture = true,
> +		.data = connector,
> +	};
> +	struct platform_device *pdev;
> +
> +	if (!funcs ||
> +	    !funcs->prepare ||
> +	    !funcs->audio_shutdown)
> +		return -EINVAL;
> +
> +	connector->hdmi_codec.funcs = funcs;
> +	connector->hdmi_codec.dai_port = dai_port;
> +
> +	pdev = platform_device_register_data(hdmi_codec_dev,
> +					     HDMI_CODEC_DRV_NAME,
> +					     PLATFORM_DEVID_AUTO,
> +					     &codec_pdata, sizeof(codec_pdata));
> +	if (IS_ERR(pdev))
> +		return PTR_ERR(pdev);
> +
> +	connector->hdmi_codec.codec_pdev = pdev;
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(drm_connector_hdmi_audio_init);
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index 1e2b25e204cb523d61d30f5409faa059bf2b86eb..536d604b6fb27368c43805a2ecf57fac06b3d472 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -46,6 +46,8 @@ struct drm_property_blob;
>  struct drm_printer;
>  struct drm_privacy_screen;
>  struct edid;
> +struct hdmi_codec_daifmt;
> +struct hdmi_codec_params;
>  struct i2c_adapter;
>  
>  enum drm_connector_force {
> @@ -1141,6 +1143,53 @@ struct drm_connector_state {
>  	struct drm_connector_hdmi_state hdmi;
>  };
>  
> +struct drm_connector_hdmi_codec_funcs {
> +	/**
> +	 * @audio_startup:
> +	 *
> +	 * Called when ASoC starts an audio stream setup. The
> +	 * @hdmi_audio_startup is optional.
> +	 *
> +	 * Returns:
> +	 * 0 on success, a negative error code otherwise
> +	 */
> +	int (*audio_startup)(struct drm_connector *connector);

With the naming comment I made on the previous version addressed, and
assuming it's been tested on a pi3 and pi4,

Acked-by: Maxime Ripard <mripard@kernel.org>

Maxime

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

  reply	other threads:[~2024-12-17 17:24 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-12-17  0:40 [PATCH v7 00/10] drm: add DRM HDMI Codec framework Dmitry Baryshkov
2024-12-17  0:40 ` [PATCH v7 01/10] ASoC: hdmi-codec: pass data to get_dai_id too Dmitry Baryshkov
2024-12-17  0:40 ` [PATCH v7 02/10] ASoC: hdmi-codec: move no_capture_mute to struct hdmi_codec_pdata Dmitry Baryshkov
2024-12-17  0:40 ` [PATCH v7 03/10] drm/connector: implement generic HDMI codec helpers Dmitry Baryshkov
2024-12-17 17:22   ` Maxime Ripard [this message]
2024-12-17  0:40 ` [PATCH v7 04/10] drm/bridge: connector: add support for HDMI codec framework Dmitry Baryshkov
2024-12-17  0:40 ` [PATCH v7 05/10] drm/bridge: lt9611: switch to using the DRM " Dmitry Baryshkov
2024-12-17  0:40 ` [PATCH v7 06/10] drm/display/hdmi: implement hotplug functions Dmitry Baryshkov
2024-12-17 17:24   ` Maxime Ripard
2024-12-17  0:40 ` [PATCH v7 07/10] drm/bridge_connector: hook drm_atomic_helper_connector_hdmi_hotplug() Dmitry Baryshkov
2024-12-17 17:25   ` Maxime Ripard
2024-12-17  0:40 ` [PATCH v7 08/10] drm/vc4: hdmi: switch to using generic HDMI Codec infrastructure Dmitry Baryshkov
2024-12-17 17:26   ` Maxime Ripard
2024-12-17  0:40 ` [PATCH v7 09/10] drm/vc4: hdmi: stop rereading EDID in get_modes() Dmitry Baryshkov
2024-12-17 17:27   ` Maxime Ripard
2024-12-17  0:40 ` [PATCH v7 10/10] drm/vc4: hdmi: use drm_atomic_helper_connector_hdmi_hotplug_edid() Dmitry Baryshkov
2024-12-17 17:28   ` Maxime Ripard
2024-12-17 12:36 ` [PATCH v7 00/10] drm: add DRM HDMI Codec framework Diederik de Haas
2024-12-17 14:09   ` Dmitry Baryshkov
2024-12-17 17:21 ` Maxime Ripard
2024-12-18  5:24   ` Dmitry Baryshkov
2024-12-18  7:59     ` Maxime Ripard
2024-12-18 14:52       ` Dave Stevenson
2024-12-19 16:16         ` Dave Stevenson
2024-12-20  0:45           ` Dmitry Baryshkov
2024-12-20 15:00             ` Dave Stevenson
2024-12-20 19:15               ` Dmitry Baryshkov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20241217-thistle-rattlesnake-of-current-dfd247@houat \
    --to=mripard@kernel.org \
    --cc=Laurent.pinchart@ideasonboard.com \
    --cc=airlied@gmail.com \
    --cc=alain.volmat@foss.st.com \
    --cc=alim.akhtar@samsung.com \
    --cc=andrzej.hajda@intel.com \
    --cc=andy.yan@rock-chips.com \
    --cc=angelogioacchino.delregno@collabora.com \
    --cc=broonie@kernel.org \
    --cc=chunkuang.hu@kernel.org \
    --cc=dave.stevenson@raspberrypi.com \
    --cc=dmitry.baryshkov@linaro.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=heiko@sntech.de \
    --cc=hjc@rock-chips.com \
    --cc=inki.dae@samsung.com \
    --cc=jani.nikula@linux.intel.com \
    --cc=jernej.skrabec@gmail.com \
    --cc=jonas@kwiboo.se \
    --cc=kernel-list@raspberrypi.com \
    --cc=krzk@kernel.org \
    --cc=kyungmin.park@samsung.com \
    --cc=lgirdwood@gmail.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mediatek@lists.infradead.org \
    --cc=linux-rockchip@lists.infradead.org \
    --cc=linux-samsung-soc@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=matthias.bgg@gmail.com \
    --cc=mcanal@igalia.com \
    --cc=neil.armstrong@linaro.org \
    --cc=p.zabel@pengutronix.de \
    --cc=perex@perex.cz \
    --cc=ple@baylibre.com \
    --cc=rfoss@kernel.org \
    --cc=rgallaispou@gmail.com \
    --cc=simona@ffwll.ch \
    --cc=sw0312.kim@samsung.com \
    --cc=tiwai@suse.com \
    --cc=tzimmermann@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox