From patchwork Fri Jan 24 21:47:47 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 859654 Received: from mail-lf1-f41.google.com (mail-lf1-f41.google.com [209.85.167.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B4FF41F37DB for ; Fri, 24 Jan 2025 21:48:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737755283; cv=none; b=kJIywhiMmtyQGU/1iF2jvHPwfQGxthDRIGFdoRuNsNsGf1SbQE6TFqpSH4p7wHs1Tw1K4yI8y637zDJa6Z6dV+wyiyyLtLOZcjdd+RGjLuOLU94vkwyGjtK/NYzVVX1XPgxcjbJNnw3si0ZPz/iYY2clZ6f8jy2CMrtlsU4Ed9Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737755283; c=relaxed/simple; bh=6A5aCLP00sWata8KRfqPQ5CnVO9JUTbJd1uu3Qp6jAs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=a4p87oPEM96tww49yCa9NbJfjfrHMc5mxH7SAbGeZgZL0bXLII5/VAAWL2t2bVVLPVXx8yXIouAawkXy4GKrpovB86tzC1DtLBTtf2HHA+t/8M5cktyQVYCGvC1MJhUyivzuupJX31MGDfsf87ih/TKvjDBuaIK+w0m+BAH/Cls= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=E5NC60qj; arc=none smtp.client-ip=209.85.167.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="E5NC60qj" Received: by mail-lf1-f41.google.com with SMTP id 2adb3069b0e04-54020b0dcd2so4238867e87.1 for ; Fri, 24 Jan 2025 13:48:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1737755280; x=1738360080; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=jaIXZ620c8SPNqR/EOcjeZxHQVhRhL3PSxW+/q8xH8Y=; b=E5NC60qjHhmV6DiD+R0lu6LSVoHCHE3WSU+v/MC4V2C5iqiV9yG82iRodgzEwdaKif SCOAoQfjenBiO0w/zhShRSHs5EyhtTrKwwOm3cmwd1ZC5gAsxifnlkRghezjPH3xhfp+ I2KzOWLmqApRfJmKVcaOFR4NKjDCHn+5n6AmCjq1lCeen9V3XuWL2n34nQonLhKvF7gE pBB/h3yA/PYFtdQwbQNUA8KAwxOuCZzWRNTqsSTKcwdEYZdz3bct2xcGPkEi+t6t7nuC 8j67Zbq9FYZTn3fJWpWvsoL0TTZFNCjatLWMWmIuoI/OHBctpBkTsiujhB85amxfbHCs 30KQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737755280; x=1738360080; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=jaIXZ620c8SPNqR/EOcjeZxHQVhRhL3PSxW+/q8xH8Y=; b=uo9x9QZeVqdMULv9i77/dswlIC17riFkpvuCk3qHVGKpUO8WiQ+snaAUUPNnw5g56H JxyhP5AIVN6q9zvXGFnEYGpmBlnNuREfMQfClPy8bV2E6QrxtR7xGHBq4gWtJRg7JaHg IATdoeDG9TauEb3qsUdzwjfKkzoqYQ33t8RvGCrGciu3uDxe/vfZKUxdqNEUi+TzZn0x IDjwS7efMqzPyX/ivDyZM/OgDw9RLCMGOqhBqgI7Z4sAZL5pyYj3FkkYxVE1fG+xv+AY Twn8VVXwdKV6JtjUxo0UtU3nHSoxIQL6v+k9QPImTAPvbKec0L57jf0OmOr1EhcNOCNt +a7Q== X-Forwarded-Encrypted: i=1; AJvYcCUS7S1Q7p/4fm6pxEHEszDuOraoxu5ZxsKxONFRtIcc7lhi/DEKIh5Q3IbudkATTZIfJE/jGn0EtSEXU8yk@vger.kernel.org X-Gm-Message-State: AOJu0YxgWLMjZo9zkP/u8ENhprtTPBiY6nPrPOd9QZaYDK6OU63sHg6Q 16dk01ihbHg0tVvOZ5B8oym+3vNoJxuPMHBK9xZ+cRGxvzumSwrHFg/BO+rMpdM= X-Gm-Gg: ASbGncu4KTmlajTrtkM/UDKPs4ZEVw8HxL9/0y8cqFRS2ywZCFNqZRmtcmyfa1pJjH2 iGZ/kBisUsJ0YTlMGob0njf+IN4y1UhDeQz9IYoro9zkKByXK5aUfoYhnVTY7Niv9g8yV7CqTOU NsrzasDrQjs6m4L97i9zASlIGE+f8+u8G7Z/9AMDqsL0DxfDc9Z98gIqm6xNbxgBFn0w+Sz26u8 4D6tStWcPL7Eka9iuNFR/D5XKIU/iBjUAhL9FVCnw31Xn/xhke3KNO/Y5pf88LG2RQzC8mmSSyl dCxOd6Th38ai X-Google-Smtp-Source: AGHT+IEmwBFQTTopeGcaCwwyWTXN2DhizvSViHjXm/kfxIMxd8HWEBRaoukAypMxXebY6h/olO6r+g== X-Received: by 2002:a05:6512:3d0b:b0:542:21f8:d6bd with SMTP id 2adb3069b0e04-543c7dab41fmr1968649e87.22.1737755279688; Fri, 24 Jan 2025 13:47:59 -0800 (PST) Received: from umbar.lan ([192.130.178.90]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-543c8237491sm425014e87.104.2025.01.24.13.47.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Jan 2025 13:47:58 -0800 (PST) From: Dmitry Baryshkov Date: Fri, 24 Jan 2025 23:47:47 +0200 Subject: [PATCH v6 7/7] drm/msm/hdmi: use DRM HDMI Audio framework Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250124-bridge-hdmi-connector-v6-7-1592632327f7@linaro.org> References: <20250124-bridge-hdmi-connector-v6-0-1592632327f7@linaro.org> In-Reply-To: <20250124-bridge-hdmi-connector-v6-0-1592632327f7@linaro.org> To: Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Rob Clark , Abhinav Kumar , Sean Paul , Marijn Suijten , Simona Vetter , Simona Vetter Cc: dri-devel@lists.freedesktop.org, linux-arm-msm@vger.kernel.org, freedreno@lists.freedesktop.org, linux-kernel@vger.kernel.org X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=9947; i=dmitry.baryshkov@linaro.org; h=from:subject:message-id; bh=6A5aCLP00sWata8KRfqPQ5CnVO9JUTbJd1uu3Qp6jAs=; b=owEBbQGS/pANAwAKAYs8ij4CKSjVAcsmYgBnlAqAxeZ6YSaN8+dfdt7IoI//rQ2ZAxV9zfeRs UpqIcCteOyJATMEAAEKAB0WIQRMcISVXLJjVvC4lX+LPIo+Aiko1QUCZ5QKgAAKCRCLPIo+Aiko 1QwVB/9dMKxRddY8I5MDYek73fiBn9x3ZEFQd0JfxtaRF/VgkVHFrFKbjIrBV+z1Rg2KAwJNxy4 7QYFARie061bIx6cVjcWiIamSx3+K8lUJxIz4ceJO8tmTEx2Lj+HtskYjna5a3REaCPH7xAhKiY t3thqpF2kD1adjT8v1Cxl5Tn6ld9iX0f7P5Wk2WitB+G6z56ydKEGGddvPcyNMLK+/mKEppRwQ7 otiWSqZYHnN8FUB1ojTJ0Knm71zxHNShGEmpawiJX5sOuz8SBN56hYcDE2lA6l48Ly23yP3Qemv RuQ062QkO9/3LHRtlXxXyCjt4gvBBtbLOAVO/dPK2ozlU2oC X-Developer-Key: i=dmitry.baryshkov@linaro.org; a=openpgp; fpr=8F88381DD5C873E4AE487DA5199BF1243632046A In order to simplify the driver even further and to remove the boilerplate code, rewrite the audio interface to use the DRM HDMI Audio framework. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/hdmi/hdmi.c | 91 ---------------------------------- drivers/gpu/drm/msm/hdmi/hdmi.h | 20 ++++---- drivers/gpu/drm/msm/hdmi/hdmi_audio.c | 75 +++++++++++++++++++++++----- drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 5 ++ 4 files changed, 76 insertions(+), 115 deletions(-) diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index 6b77e0fb8d5ec218dfbf58215e2e12ad1dfb1b85..248541ff449204c72cd444458dadb9ae4a0a53d1 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -14,7 +14,6 @@ #include #include -#include #include "hdmi.h" void msm_hdmi_set_mode(struct hdmi *hdmi, bool power_on) @@ -245,87 +244,6 @@ static const struct hdmi_platform_config hdmi_tx_8974_config = { .hpd_freq = hpd_clk_freq_8x74, }; -/* - * HDMI audio codec callbacks - */ -static int msm_hdmi_audio_hw_params(struct device *dev, void *data, - struct hdmi_codec_daifmt *daifmt, - struct hdmi_codec_params *params) -{ - struct hdmi *hdmi = dev_get_drvdata(dev); - unsigned int rate; - int ret; - - DRM_DEV_DEBUG(dev, "%u Hz, %d bit, %d channels\n", params->sample_rate, - params->sample_width, params->cea.channels); - - switch (params->sample_rate) { - case 32000: - rate = HDMI_SAMPLE_RATE_32KHZ; - break; - case 44100: - rate = HDMI_SAMPLE_RATE_44_1KHZ; - break; - case 48000: - rate = HDMI_SAMPLE_RATE_48KHZ; - break; - case 88200: - rate = HDMI_SAMPLE_RATE_88_2KHZ; - break; - case 96000: - rate = HDMI_SAMPLE_RATE_96KHZ; - break; - case 176400: - rate = HDMI_SAMPLE_RATE_176_4KHZ; - break; - case 192000: - rate = HDMI_SAMPLE_RATE_192KHZ; - break; - default: - DRM_DEV_ERROR(dev, "rate[%d] not supported!\n", - params->sample_rate); - return -EINVAL; - } - - ret = drm_atomic_helper_connector_hdmi_update_audio_infoframe(hdmi->connector, - ¶ms->cea); - if (ret) - return ret; - - msm_hdmi_audio_info_setup(hdmi, rate, params->cea.channels); - - return 0; -} - -static void msm_hdmi_audio_shutdown(struct device *dev, void *data) -{ - struct hdmi *hdmi = dev_get_drvdata(dev); - - drm_atomic_helper_connector_hdmi_clear_audio_infoframe(hdmi->connector); - msm_hdmi_audio_disable(hdmi); -} - -static const struct hdmi_codec_ops msm_hdmi_audio_codec_ops = { - .hw_params = msm_hdmi_audio_hw_params, - .audio_shutdown = msm_hdmi_audio_shutdown, -}; - -static struct hdmi_codec_pdata codec_data = { - .ops = &msm_hdmi_audio_codec_ops, - .max_i2s_channels = 8, - .i2s = 1, -}; - -static int msm_hdmi_register_audio_driver(struct hdmi *hdmi, struct device *dev) -{ - hdmi->audio_pdev = platform_device_register_data(dev, - HDMI_CODEC_DRV_NAME, - PLATFORM_DEVID_AUTO, - &codec_data, - sizeof(codec_data)); - return PTR_ERR_OR_ZERO(hdmi->audio_pdev); -} - static int msm_hdmi_bind(struct device *dev, struct device *master, void *data) { struct msm_drm_private *priv = dev_get_drvdata(master); @@ -337,12 +255,6 @@ static int msm_hdmi_bind(struct device *dev, struct device *master, void *data) return err; priv->hdmi = hdmi; - err = msm_hdmi_register_audio_driver(hdmi, dev); - if (err) { - DRM_ERROR("Failed to attach an audio codec %d\n", err); - hdmi->audio_pdev = NULL; - } - return 0; } @@ -352,9 +264,6 @@ static void msm_hdmi_unbind(struct device *dev, struct device *master, struct msm_drm_private *priv = dev_get_drvdata(master); if (priv->hdmi) { - if (priv->hdmi->audio_pdev) - platform_device_unregister(priv->hdmi->audio_pdev); - if (priv->hdmi->bridge) msm_hdmi_hpd_disable(priv->hdmi); diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h index ab169b77377097dc22c0c718f65024cb8ad1d317..88a41be7c6fc2f878a1c372a0c75b3277f24f893 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.h +++ b/drivers/gpu/drm/msm/hdmi/hdmi.h @@ -33,7 +33,6 @@ struct hdmi_hdcp_ctrl; struct hdmi { struct drm_device *dev; struct platform_device *pdev; - struct platform_device *audio_pdev; const struct hdmi_platform_config *config; @@ -205,16 +204,15 @@ static inline int msm_hdmi_pll_8998_init(struct platform_device *pdev) /* * audio: */ -#define HDMI_SAMPLE_RATE_32KHZ 0 -#define HDMI_SAMPLE_RATE_44_1KHZ 1 -#define HDMI_SAMPLE_RATE_48KHZ 2 -#define HDMI_SAMPLE_RATE_88_2KHZ 3 -#define HDMI_SAMPLE_RATE_96KHZ 4 -#define HDMI_SAMPLE_RATE_176_4KHZ 5 -#define HDMI_SAMPLE_RATE_192KHZ 6 - -int msm_hdmi_audio_info_setup(struct hdmi *hdmi, int rate, int channels); -int msm_hdmi_audio_disable(struct hdmi *hdmi); +struct hdmi_codec_daifmt; +struct hdmi_codec_params; + +int msm_hdmi_bridge_audio_prepare(struct drm_connector *connector, + struct drm_bridge *bridge, + struct hdmi_codec_daifmt *daifmt, + struct hdmi_codec_params *params); +void msm_hdmi_bridge_audio_shutdown(struct drm_connector *connector, + struct drm_bridge *bridge); /* * hdmi bridge: diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_audio.c b/drivers/gpu/drm/msm/hdmi/hdmi_audio.c index 924654bfb48cf17feadea1c0661ee6ee4e1b4589..9c5b5310bfeb54902d7d0687909afc79e320f560 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_audio.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_audio.c @@ -4,7 +4,12 @@ * Author: Rob Clark */ +#include + #include + +#include + #include "hdmi.h" /* Supported HDMI Audio sample rates */ @@ -68,7 +73,8 @@ static const struct hdmi_msm_audio_arcs *get_arcs(unsigned long int pixclock) return NULL; } -static int msm_hdmi_audio_update(struct hdmi *hdmi) +static int msm_hdmi_audio_update(struct hdmi *hdmi, + struct drm_connector *connector) { struct hdmi_audio *audio = &hdmi->audio; const struct hdmi_msm_audio_arcs *arcs = NULL; @@ -76,7 +82,7 @@ static int msm_hdmi_audio_update(struct hdmi *hdmi) uint32_t acr_pkt_ctrl, vbi_pkt_ctrl, aud_pkt_ctrl; uint32_t audio_config; - if (!hdmi->connector->display_info.is_hdmi) + if (!connector->display_info.is_hdmi) return -EINVAL; DBG("audio: enabled=%d, channels=%d, rate=%d", @@ -192,29 +198,72 @@ static int msm_hdmi_audio_update(struct hdmi *hdmi) return 0; } -int msm_hdmi_audio_info_setup(struct hdmi *hdmi, int rate, int channels) +int msm_hdmi_bridge_audio_prepare(struct drm_connector *connector, + struct drm_bridge *bridge, + struct hdmi_codec_daifmt *daifmt, + struct hdmi_codec_params *params) { - if (!hdmi) - return -ENXIO; - - if ((rate < 0) || (rate >= MSM_HDMI_SAMPLE_RATE_MAX)) + struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); + struct hdmi *hdmi = hdmi_bridge->hdmi; + unsigned int rate; + int ret; + + drm_dbg_driver(bridge->dev, "%u Hz, %d bit, %d channels\n", + params->sample_rate, + params->sample_width, + params->cea.channels); + + switch (params->sample_rate) { + case 32000: + rate = MSM_HDMI_SAMPLE_RATE_32KHZ; + break; + case 44100: + rate = MSM_HDMI_SAMPLE_RATE_44_1KHZ; + break; + case 48000: + rate = MSM_HDMI_SAMPLE_RATE_48KHZ; + break; + case 88200: + rate = MSM_HDMI_SAMPLE_RATE_88_2KHZ; + break; + case 96000: + rate = MSM_HDMI_SAMPLE_RATE_96KHZ; + break; + case 176400: + rate = MSM_HDMI_SAMPLE_RATE_176_4KHZ; + break; + case 192000: + rate = MSM_HDMI_SAMPLE_RATE_192KHZ; + break; + default: + drm_err(bridge->dev, "rate[%d] not supported!\n", + params->sample_rate); return -EINVAL; + } + + ret = drm_atomic_helper_connector_hdmi_update_audio_infoframe(connector, + ¶ms->cea); + if (ret) + return ret; hdmi->audio.rate = rate; - hdmi->audio.channels = channels; + hdmi->audio.channels = params->cea.channels; hdmi->audio.enabled = true; - return msm_hdmi_audio_update(hdmi); + return msm_hdmi_audio_update(hdmi, connector); } -int msm_hdmi_audio_disable(struct hdmi *hdmi) +void msm_hdmi_bridge_audio_shutdown(struct drm_connector *connector, + struct drm_bridge *bridge) { - if (!hdmi) - return -ENXIO; + struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); + struct hdmi *hdmi = hdmi_bridge->hdmi; + + drm_atomic_helper_connector_hdmi_clear_audio_infoframe(connector); hdmi->audio.rate = 0; hdmi->audio.channels = 2; hdmi->audio.enabled = false; - return msm_hdmi_audio_update(hdmi); + msm_hdmi_audio_update(hdmi, connector); } diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c index c31e1d33593de6480c0c2b7cb322a85e645ff332..8a1bbcf578b0749480799d9e5b2baf3778322edc 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c @@ -470,6 +470,8 @@ static const struct drm_bridge_funcs msm_hdmi_bridge_funcs = { .hdmi_tmds_char_rate_valid = msm_hdmi_bridge_tmds_char_rate_valid, .hdmi_clear_infoframe = msm_hdmi_bridge_clear_infoframe, .hdmi_write_infoframe = msm_hdmi_bridge_write_infoframe, + .hdmi_audio_prepare = msm_hdmi_bridge_audio_prepare, + .hdmi_audio_shutdown = msm_hdmi_bridge_audio_shutdown, }; static void @@ -507,6 +509,9 @@ int msm_hdmi_bridge_init(struct hdmi *hdmi) DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_HDMI | DRM_BRIDGE_OP_EDID; + bridge->hdmi_audio_max_i2s_playback_channels = 8; + bridge->hdmi_audio_dev = &hdmi->pdev->dev; + bridge->hdmi_audio_dai_port = -1; ret = devm_drm_bridge_add(hdmi->dev->dev, bridge); if (ret)