aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-5.4/805-display-0007-drm-bridge-cadence-Add-mhdp-audio-driver.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/layerscape/patches-5.4/805-display-0007-drm-bridge-cadence-Add-mhdp-audio-driver.patch')
-rw-r--r--target/linux/layerscape/patches-5.4/805-display-0007-drm-bridge-cadence-Add-mhdp-audio-driver.patch715
1 files changed, 0 insertions, 715 deletions
diff --git a/target/linux/layerscape/patches-5.4/805-display-0007-drm-bridge-cadence-Add-mhdp-audio-driver.patch b/target/linux/layerscape/patches-5.4/805-display-0007-drm-bridge-cadence-Add-mhdp-audio-driver.patch
deleted file mode 100644
index f0a1414b03..0000000000
--- a/target/linux/layerscape/patches-5.4/805-display-0007-drm-bridge-cadence-Add-mhdp-audio-driver.patch
+++ /dev/null
@@ -1,715 +0,0 @@
-From 3cd4b3cfc651c4d54897c72fbbaa9cd583ee6208 Mon Sep 17 00:00:00 2001
-From: Sandor Yu <Sandor.yu@nxp.com>
-Date: Fri, 30 Aug 2019 17:51:43 +0800
-Subject: [PATCH] drm: bridge: cadence: Add mhdp audio driver
-
-Move mhdp audio driver to cadence folder.
-Add audio info-frame set function for hdmi tx audio.
-The driver suppoer both HDMI and DP audio.
-
-Signed-off-by: Sandor Yu <Sandor.yu@nxp.com>
----
- drivers/gpu/drm/bridge/cadence/Kconfig | 3 +
- drivers/gpu/drm/bridge/cadence/Makefile | 3 +-
- drivers/gpu/drm/bridge/cadence/cdns-dp-core.c | 4 +
- drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c | 5 +-
- drivers/gpu/drm/bridge/cadence/cdns-mhdp-audio.c | 395 ++++++++++++++++++++++
- drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c | 183 ----------
- drivers/gpu/drm/imx/Kconfig | 1 +
- include/drm/bridge/cdns-mhdp-common.h | 6 +
- 8 files changed, 414 insertions(+), 186 deletions(-)
- create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-mhdp-audio.c
-
---- a/drivers/gpu/drm/bridge/cadence/Kconfig
-+++ b/drivers/gpu/drm/bridge/cadence/Kconfig
-@@ -11,3 +11,6 @@ config DRM_CDNS_HDMI
-
- config DRM_CDNS_DP
- tristate "Cadence DP DRM driver"
-+
-+config DRM_CDNS_AUDIO
-+ tristate "Cadence MHDP Audio driver"
---- a/drivers/gpu/drm/bridge/cadence/Makefile
-+++ b/drivers/gpu/drm/bridge/cadence/Makefile
-@@ -1,5 +1,4 @@
--#ccflags-y := -Iinclude/drm
--
- obj-$(CONFIG_DRM_CDNS_MHDP) += cdns-mhdp-common.o cdns-mhdp-hdmi.o
- obj-$(CONFIG_DRM_CDNS_HDMI) += cdns-hdmi-core.o
- obj-$(CONFIG_DRM_CDNS_DP) += cdns-dp-core.o
-+obj-$(CONFIG_DRM_CDNS_AUDIO) += cdns-mhdp-audio.o
---- a/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c
-+++ b/drivers/gpu/drm/bridge/cadence/cdns-dp-core.c
-@@ -526,6 +526,9 @@ __cdns_dp_probe(struct platform_device *
-
- dev_set_drvdata(dev, &dp->mhdp);
-
-+ /* register audio driver */
-+ cdns_mhdp_register_audio_driver(dev);
-+
- dp_aux_init(&dp->mhdp, dev);
-
- return dp;
-@@ -537,6 +540,7 @@ err_out:
- static void __cdns_dp_remove(struct cdns_mhdp_device *mhdp)
- {
- dp_aux_destroy(mhdp);
-+ cdns_mhdp_unregister_audio_driver(mhdp->dev);
- }
-
- /* -----------------------------------------------------------------------------
---- a/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c
-+++ b/drivers/gpu/drm/bridge/cadence/cdns-hdmi-core.c
-@@ -9,7 +9,6 @@
- * (at your option) any later version.
- *
- */
--
- #include <drm/bridge/cdns-mhdp-imx.h>
- #include <drm/drm_atomic_helper.h>
- #include <drm/drm_crtc_helper.h>
-@@ -513,6 +512,9 @@ __cdns_hdmi_probe(struct platform_device
-
- dev_set_drvdata(dev, &hdmi->mhdp);
-
-+ /* register audio driver */
-+ cdns_mhdp_register_audio_driver(dev);
-+
- return hdmi;
-
- err_out:
-@@ -522,6 +524,7 @@ err_out:
-
- static void __cdns_hdmi_remove(struct cdns_mhdp_device *mhdp)
- {
-+ cdns_mhdp_unregister_audio_driver(mhdp->dev);
- }
-
- /* -----------------------------------------------------------------------------
---- /dev/null
-+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-audio.c
-@@ -0,0 +1,395 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
-+ * Author: Chris Zhong <zyw@rock-chips.com>
-+ *
-+ * This software is licensed under the terms of the GNU General Public
-+ * License version 2, as published by the Free Software Foundation, and
-+ * may be copied, distributed, and modified under those terms.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ */
-+#include <linux/clk.h>
-+#include <linux/reset.h>
-+#include <drm/bridge/cdns-mhdp-common.h>
-+#include <sound/hdmi-codec.h>
-+#include <drm/bridge/cdns-mhdp-imx.h>
-+#include <drm/drm_of.h>
-+#include <drm/drmP.h>
-+
-+#define CDNS_DP_SPDIF_CLK 200000000
-+
-+static u32 TMDS_rate_table[7] = {
-+ 25200, 27000, 54000, 74250, 148500, 297000, 594000,
-+};
-+
-+static u32 N_table_32k[7] = {
-+/* 25200/27000/54000/74250/148500/297000/594000 */
-+ 4096, 4096, 4096, 4096, 4096, 3072, 3072,
-+};
-+
-+static u32 N_table_44k[7] = {
-+ 6272, 6272, 6272, 6272, 6272, 4704, 9408,
-+};
-+
-+static u32 N_table_48k[7] = {
-+ 6144, 6144, 6144, 6144, 6144, 5120, 6144,
-+};
-+
-+static int select_N_index(u32 pclk)
-+{
-+ int num = sizeof(TMDS_rate_table)/sizeof(int);
-+ int i = 0;
-+
-+ for (i = 0; i < num ; i++)
-+ if (pclk == TMDS_rate_table[i])
-+ break;
-+
-+ if (i == num) {
-+ DRM_WARN("pclkc %d is not supported!\n", pclk);
-+ return num-1;
-+ }
-+
-+ return i;
-+}
-+
-+static void hdmi_audio_avi_set(struct cdns_mhdp_device *mhdp,
-+ u32 channels)
-+{
-+ struct hdmi_audio_infoframe frame;
-+ u8 buf[32];
-+ int ret;
-+
-+ hdmi_audio_infoframe_init(&frame);
-+
-+ frame.channels = channels;
-+ frame.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
-+
-+ if (channels == 2)
-+ frame.channel_allocation = 0;
-+ else if (channels == 4)
-+ frame.channel_allocation = 0x3;
-+ else if (channels == 8)
-+ frame.channel_allocation = 0x13;
-+
-+ ret = hdmi_audio_infoframe_pack(&frame, buf + 1, sizeof(buf) - 1);
-+ if (ret < 0) {
-+ DRM_ERROR("failed to pack audio infoframe: %d\n", ret);
-+ return;
-+ }
-+
-+ buf[0] = 0;
-+
-+ cdns_mhdp_infoframe_set(mhdp, 1, sizeof(buf), buf, HDMI_INFOFRAME_TYPE_AUDIO);
-+}
-+
-+int cdns_mhdp_audio_stop(struct cdns_mhdp_device *mhdp,
-+ struct audio_info *audio)
-+{
-+ int ret;
-+
-+ if (audio->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
-+ ret = cdns_mhdp_reg_write(mhdp, AUDIO_PACK_CONTROL, 0);
-+ if (ret) {
-+ DRM_DEV_ERROR(mhdp->dev, "audio stop failed: %d\n", ret);
-+ return ret;
-+ }
-+ }
-+
-+ cdns_mhdp_bus_write(0, mhdp, SPDIF_CTRL_ADDR);
-+
-+ /* clearn the audio config and reset */
-+ cdns_mhdp_bus_write(0, mhdp, AUDIO_SRC_CNTL);
-+ cdns_mhdp_bus_write(0, mhdp, AUDIO_SRC_CNFG);
-+ cdns_mhdp_bus_write(AUDIO_SW_RST, mhdp, AUDIO_SRC_CNTL);
-+ cdns_mhdp_bus_write(0, mhdp, AUDIO_SRC_CNTL);
-+
-+ /* reset smpl2pckt component */
-+ cdns_mhdp_bus_write(0, mhdp, SMPL2PKT_CNTL);
-+ cdns_mhdp_bus_write(AUDIO_SW_RST, mhdp, SMPL2PKT_CNTL);
-+ cdns_mhdp_bus_write(0, mhdp, SMPL2PKT_CNTL);
-+
-+ /* reset FIFO */
-+ cdns_mhdp_bus_write(AUDIO_SW_RST, mhdp, FIFO_CNTL);
-+ cdns_mhdp_bus_write(0, mhdp, FIFO_CNTL);
-+
-+ if (audio->format == AFMT_SPDIF_INT)
-+ clk_disable_unprepare(mhdp->spdif_clk);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL(cdns_mhdp_audio_stop);
-+
-+int cdns_mhdp_audio_mute(struct cdns_mhdp_device *mhdp, bool enable)
-+{
-+ struct audio_info *audio = &mhdp->audio_info;
-+ int ret = true;
-+
-+ if (audio->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
-+ ret = cdns_mhdp_reg_write_bit(mhdp, DP_VB_ID, 4, 1, enable);
-+ if (ret)
-+ DRM_DEV_ERROR(mhdp->dev, "audio mute failed: %d\n", ret);
-+ }
-+
-+ return ret;
-+}
-+EXPORT_SYMBOL(cdns_mhdp_audio_mute);
-+
-+static void cdns_mhdp_audio_config_i2s(struct cdns_mhdp_device *mhdp,
-+ struct audio_info *audio)
-+{
-+ int sub_pckt_num = 1, i2s_port_en_val = 0xf, i;
-+ int idx = select_N_index(mhdp->mode.clock);
-+ u32 val, ncts;
-+
-+ if (audio->channels == 2) {
-+ if (mhdp->dp.link.num_lanes == 1)
-+ sub_pckt_num = 2;
-+ else
-+ sub_pckt_num = 4;
-+
-+ i2s_port_en_val = 1;
-+ } else if (audio->channels == 4) {
-+ i2s_port_en_val = 3;
-+ }
-+
-+ cdns_mhdp_bus_write(0x0, mhdp, SPDIF_CTRL_ADDR);
-+
-+ cdns_mhdp_bus_write(SYNC_WR_TO_CH_ZERO, mhdp, FIFO_CNTL);
-+
-+ val = MAX_NUM_CH(audio->channels);
-+ val |= NUM_OF_I2S_PORTS(audio->channels);
-+ val |= AUDIO_TYPE_LPCM;
-+ val |= CFG_SUB_PCKT_NUM(sub_pckt_num);
-+ cdns_mhdp_bus_write(val, mhdp, SMPL2PKT_CNFG);
-+
-+ if (audio->sample_width == 16)
-+ val = 0;
-+ else if (audio->sample_width == 24)
-+ val = 1 << 9;
-+ else
-+ val = 2 << 9;
-+
-+ val |= AUDIO_CH_NUM(audio->channels);
-+ val |= I2S_DEC_PORT_EN(i2s_port_en_val);
-+ val |= TRANS_SMPL_WIDTH_32;
-+ cdns_mhdp_bus_write(val, mhdp, AUDIO_SRC_CNFG);
-+
-+ for (i = 0; i < (audio->channels + 1) / 2; i++) {
-+ if (audio->sample_width == 16)
-+ val = (0x02 << 8) | (0x02 << 20);
-+ else if (audio->sample_width == 24)
-+ val = (0x0b << 8) | (0x0b << 20);
-+
-+ val |= ((2 * i) << 4) | ((2 * i + 1) << 16);
-+ cdns_mhdp_bus_write(val, mhdp, STTS_BIT_CH(i));
-+ }
-+
-+ switch (audio->sample_rate) {
-+ case 32000:
-+ val = SAMPLING_FREQ(3) |
-+ ORIGINAL_SAMP_FREQ(0xc);
-+ ncts = N_table_32k[idx];
-+ break;
-+ case 44100:
-+ val = SAMPLING_FREQ(0) |
-+ ORIGINAL_SAMP_FREQ(0xf);
-+ ncts = N_table_44k[idx];
-+ break;
-+ case 48000:
-+ val = SAMPLING_FREQ(2) |
-+ ORIGINAL_SAMP_FREQ(0xd);
-+ ncts = N_table_48k[idx];
-+ break;
-+ case 88200:
-+ val = SAMPLING_FREQ(8) |
-+ ORIGINAL_SAMP_FREQ(0x7);
-+ ncts = N_table_44k[idx] * 2;
-+ break;
-+ case 96000:
-+ val = SAMPLING_FREQ(0xa) |
-+ ORIGINAL_SAMP_FREQ(5);
-+ ncts = N_table_48k[idx] * 2;
-+ break;
-+ case 176400:
-+ val = SAMPLING_FREQ(0xc) |
-+ ORIGINAL_SAMP_FREQ(3);
-+ ncts = N_table_44k[idx] * 4;
-+ break;
-+ case 192000:
-+ default:
-+ val = SAMPLING_FREQ(0xe) |
-+ ORIGINAL_SAMP_FREQ(1);
-+ ncts = N_table_48k[idx] * 4;
-+ break;
-+ }
-+ val |= 4;
-+ cdns_mhdp_bus_write(val, mhdp, COM_CH_STTS_BITS);
-+
-+ if (audio->connector_type == DRM_MODE_CONNECTOR_HDMIA)
-+ cdns_mhdp_reg_write(mhdp, CM_I2S_CTRL, ncts | 0x4000000);
-+
-+ cdns_mhdp_bus_write(SMPL2PKT_EN, mhdp, SMPL2PKT_CNTL);
-+ cdns_mhdp_bus_write(I2S_DEC_START, mhdp, AUDIO_SRC_CNTL);
-+}
-+
-+static void cdns_mhdp_audio_config_spdif(struct cdns_mhdp_device *mhdp)
-+{
-+ u32 val;
-+
-+ cdns_mhdp_bus_write(SYNC_WR_TO_CH_ZERO, mhdp, FIFO_CNTL);
-+
-+ val = MAX_NUM_CH(2) | AUDIO_TYPE_LPCM | CFG_SUB_PCKT_NUM(4);
-+ cdns_mhdp_bus_write(val, mhdp, SMPL2PKT_CNFG);
-+ cdns_mhdp_bus_write(SMPL2PKT_EN, mhdp, SMPL2PKT_CNTL);
-+
-+ val = SPDIF_ENABLE | SPDIF_AVG_SEL | SPDIF_JITTER_BYPASS;
-+ cdns_mhdp_bus_write(val, mhdp, SPDIF_CTRL_ADDR);
-+
-+ clk_prepare_enable(mhdp->spdif_clk);
-+ clk_set_rate(mhdp->spdif_clk, CDNS_DP_SPDIF_CLK);
-+}
-+
-+int cdns_mhdp_audio_config(struct cdns_mhdp_device *mhdp,
-+ struct audio_info *audio)
-+{
-+ int ret;
-+
-+ /* reset the spdif clk before config */
-+ if (audio->format == AFMT_SPDIF_INT) {
-+ reset_control_assert(mhdp->spdif_rst);
-+ reset_control_deassert(mhdp->spdif_rst);
-+ }
-+
-+ if (audio->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
-+ ret = cdns_mhdp_reg_write(mhdp, CM_LANE_CTRL, LANE_REF_CYC);
-+ if (ret)
-+ goto err_audio_config;
-+
-+ ret = cdns_mhdp_reg_write(mhdp, CM_CTRL, 0);
-+ if (ret)
-+ goto err_audio_config;
-+ } else {
-+ /* HDMI Mode */
-+ ret = cdns_mhdp_reg_write(mhdp, CM_CTRL, 8);
-+ if (ret)
-+ goto err_audio_config;
-+ }
-+
-+ if (audio->format == AFMT_I2S)
-+ cdns_mhdp_audio_config_i2s(mhdp, audio);
-+ else if (audio->format == AFMT_SPDIF_INT)
-+ cdns_mhdp_audio_config_spdif(mhdp);
-+
-+ if (audio->connector_type == DRM_MODE_CONNECTOR_DisplayPort)
-+ ret = cdns_mhdp_reg_write(mhdp, AUDIO_PACK_CONTROL, AUDIO_PACK_EN);
-+
-+ if (audio->connector_type == DRM_MODE_CONNECTOR_HDMIA)
-+ hdmi_audio_avi_set(mhdp, audio->channels);
-+
-+err_audio_config:
-+ if (ret)
-+ DRM_DEV_ERROR(mhdp->dev, "audio config failed: %d\n", ret);
-+ return ret;
-+}
-+EXPORT_SYMBOL(cdns_mhdp_audio_config);
-+
-+static int audio_hw_params(struct device *dev, void *data,
-+ struct hdmi_codec_daifmt *daifmt,
-+ struct hdmi_codec_params *params)
-+{
-+ struct cdns_mhdp_device *mhdp = dev_get_drvdata(dev);
-+ struct audio_info audio = {
-+ .sample_width = params->sample_width,
-+ .sample_rate = params->sample_rate,
-+ .channels = params->channels,
-+ .connector_type = mhdp->connector.base.connector_type,
-+ };
-+ int ret;
-+
-+ switch (daifmt->fmt) {
-+ case HDMI_I2S:
-+ audio.format = AFMT_I2S;
-+ break;
-+ case HDMI_SPDIF:
-+ audio.format = AFMT_SPDIF_EXT;
-+ break;
-+ default:
-+ DRM_DEV_ERROR(dev, "Invalid format %d\n", daifmt->fmt);
-+ ret = -EINVAL;
-+ goto out;
-+ }
-+
-+ ret = cdns_mhdp_audio_config(mhdp, &audio);
-+ if (!ret)
-+ mhdp->audio_info = audio;
-+
-+out:
-+ return ret;
-+}
-+
-+static void audio_shutdown(struct device *dev, void *data)
-+{
-+ struct cdns_mhdp_device *mhdp = dev_get_drvdata(dev);
-+ int ret;
-+
-+ ret = cdns_mhdp_audio_stop(mhdp, &mhdp->audio_info);
-+ if (!ret)
-+ mhdp->audio_info.format = AFMT_UNUSED;
-+}
-+
-+static int audio_digital_mute(struct device *dev, void *data,
-+ bool enable)
-+{
-+ struct cdns_mhdp_device *mhdp = dev_get_drvdata(dev);
-+ int ret;
-+
-+ ret = cdns_mhdp_audio_mute(mhdp, enable);
-+
-+ return ret;
-+}
-+
-+static int audio_get_eld(struct device *dev, void *data,
-+ u8 *buf, size_t len)
-+{
-+ struct cdns_mhdp_device *mhdp = dev_get_drvdata(dev);
-+
-+ memcpy(buf, mhdp->connector.base.eld,
-+ min(sizeof(mhdp->connector.base.eld), len));
-+
-+ return 0;
-+}
-+
-+static const struct hdmi_codec_ops audio_codec_ops = {
-+ .hw_params = audio_hw_params,
-+ .audio_shutdown = audio_shutdown,
-+ .digital_mute = audio_digital_mute,
-+ .get_eld = audio_get_eld,
-+};
-+
-+int cdns_mhdp_register_audio_driver(struct device *dev)
-+{
-+ struct cdns_mhdp_device *mhdp = dev_get_drvdata(dev);
-+ struct hdmi_codec_pdata codec_data = {
-+ .i2s = 1,
-+ .spdif = 1,
-+ .ops = &audio_codec_ops,
-+ .max_i2s_channels = 8,
-+ };
-+
-+ mhdp->audio_pdev = platform_device_register_data(
-+ dev, HDMI_CODEC_DRV_NAME, 1,
-+ &codec_data, sizeof(codec_data));
-+
-+ return PTR_ERR_OR_ZERO(mhdp->audio_pdev);
-+}
-+
-+void cdns_mhdp_unregister_audio_driver(struct device *dev)
-+{
-+ struct cdns_mhdp_device *mhdp = dev_get_drvdata(dev);
-+
-+ platform_device_unregister(mhdp->audio_pdev);
-+}
---- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c
-+++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp-common.c
-@@ -937,189 +937,6 @@ err_config_video:
- }
- EXPORT_SYMBOL(cdns_mhdp_config_video);
-
--int cdns_mhdp_audio_stop(struct cdns_mhdp_device *mhdp,
-- struct audio_info *audio)
--{
-- int ret;
--
-- ret = cdns_mhdp_reg_write(mhdp, AUDIO_PACK_CONTROL, 0);
-- if (ret) {
-- DRM_DEV_ERROR(mhdp->dev, "audio stop failed: %d\n", ret);
-- return ret;
-- }
--
-- cdns_mhdp_bus_write(0, mhdp, SPDIF_CTRL_ADDR);
--
-- /* clearn the audio config and reset */
-- cdns_mhdp_bus_write(0, mhdp, AUDIO_SRC_CNTL);
-- cdns_mhdp_bus_write(0, mhdp, AUDIO_SRC_CNFG);
-- cdns_mhdp_bus_write(AUDIO_SW_RST, mhdp, AUDIO_SRC_CNTL);
-- cdns_mhdp_bus_write(0, mhdp, AUDIO_SRC_CNTL);
--
-- /* reset smpl2pckt component */
-- cdns_mhdp_bus_write(0, mhdp, SMPL2PKT_CNTL);
-- cdns_mhdp_bus_write(AUDIO_SW_RST, mhdp, SMPL2PKT_CNTL);
-- cdns_mhdp_bus_write(0, mhdp, SMPL2PKT_CNTL);
--
-- /* reset FIFO */
-- cdns_mhdp_bus_write(AUDIO_SW_RST, mhdp, FIFO_CNTL);
-- cdns_mhdp_bus_write(0, mhdp, FIFO_CNTL);
--
-- if (audio->format == AFMT_SPDIF_INT)
-- clk_disable_unprepare(mhdp->spdif_clk);
--
-- return 0;
--}
--EXPORT_SYMBOL(cdns_mhdp_audio_stop);
--
--int cdns_mhdp_audio_mute(struct cdns_mhdp_device *mhdp, bool enable)
--{
-- int ret;
--
-- ret = cdns_mhdp_reg_write_bit(mhdp, DP_VB_ID, 4, 1, enable);
-- if (ret)
-- DRM_DEV_ERROR(mhdp->dev, "audio mute failed: %d\n", ret);
--
-- return ret;
--}
--EXPORT_SYMBOL(cdns_mhdp_audio_mute);
--
--static void cdns_mhdp_audio_config_i2s(struct cdns_mhdp_device *mhdp,
-- struct audio_info *audio)
--{
-- int sub_pckt_num = 1, i2s_port_en_val = 0xf, i;
-- u32 val;
--
-- if (audio->channels == 2) {
-- if (mhdp->dp.link.num_lanes == 1)
-- sub_pckt_num = 2;
-- else
-- sub_pckt_num = 4;
--
-- i2s_port_en_val = 1;
-- } else if (audio->channels == 4) {
-- i2s_port_en_val = 3;
-- }
--
-- cdns_mhdp_bus_write(0x0, mhdp, SPDIF_CTRL_ADDR);
--
-- cdns_mhdp_bus_write(SYNC_WR_TO_CH_ZERO, mhdp, FIFO_CNTL);
--
-- val = MAX_NUM_CH(audio->channels);
-- val |= NUM_OF_I2S_PORTS(audio->channels);
-- val |= AUDIO_TYPE_LPCM;
-- val |= CFG_SUB_PCKT_NUM(sub_pckt_num);
-- cdns_mhdp_bus_write(val, mhdp, SMPL2PKT_CNFG);
--
-- if (audio->sample_width == 16)
-- val = 0;
-- else if (audio->sample_width == 24)
-- val = 1 << 9;
-- else
-- val = 2 << 9;
--
-- val |= AUDIO_CH_NUM(audio->channels);
-- val |= I2S_DEC_PORT_EN(i2s_port_en_val);
-- val |= TRANS_SMPL_WIDTH_32;
-- cdns_mhdp_bus_write(val, mhdp, AUDIO_SRC_CNFG);
--
-- for (i = 0; i < (audio->channels + 1) / 2; i++) {
-- if (audio->sample_width == 16)
-- val = (0x02 << 8) | (0x02 << 20);
-- else if (audio->sample_width == 24)
-- val = (0x0b << 8) | (0x0b << 20);
--
-- val |= ((2 * i) << 4) | ((2 * i + 1) << 16);
-- cdns_mhdp_bus_write(val, mhdp, STTS_BIT_CH(i));
-- }
--
-- switch (audio->sample_rate) {
-- case 32000:
-- val = SAMPLING_FREQ(3) |
-- ORIGINAL_SAMP_FREQ(0xc);
-- break;
-- case 44100:
-- val = SAMPLING_FREQ(0) |
-- ORIGINAL_SAMP_FREQ(0xf);
-- break;
-- case 48000:
-- val = SAMPLING_FREQ(2) |
-- ORIGINAL_SAMP_FREQ(0xd);
-- break;
-- case 88200:
-- val = SAMPLING_FREQ(8) |
-- ORIGINAL_SAMP_FREQ(0x7);
-- break;
-- case 96000:
-- val = SAMPLING_FREQ(0xa) |
-- ORIGINAL_SAMP_FREQ(5);
-- break;
-- case 176400:
-- val = SAMPLING_FREQ(0xc) |
-- ORIGINAL_SAMP_FREQ(3);
-- break;
-- case 192000:
-- val = SAMPLING_FREQ(0xe) |
-- ORIGINAL_SAMP_FREQ(1);
-- break;
-- }
-- val |= 4;
-- cdns_mhdp_bus_write(val, mhdp, COM_CH_STTS_BITS);
--
-- cdns_mhdp_bus_write(SMPL2PKT_EN, mhdp, SMPL2PKT_CNTL);
-- cdns_mhdp_bus_write(I2S_DEC_START, mhdp, AUDIO_SRC_CNTL);
--}
--
--static void cdns_mhdp_audio_config_spdif(struct cdns_mhdp_device *mhdp)
--{
-- u32 val;
--
-- cdns_mhdp_bus_write(SYNC_WR_TO_CH_ZERO, mhdp, FIFO_CNTL);
--
-- val = MAX_NUM_CH(2) | AUDIO_TYPE_LPCM | CFG_SUB_PCKT_NUM(4);
-- cdns_mhdp_bus_write(val, mhdp, SMPL2PKT_CNFG);
-- cdns_mhdp_bus_write(SMPL2PKT_EN, mhdp, SMPL2PKT_CNTL);
--
-- val = SPDIF_ENABLE | SPDIF_AVG_SEL | SPDIF_JITTER_BYPASS;
-- cdns_mhdp_bus_write(val, mhdp, SPDIF_CTRL_ADDR);
--
-- clk_prepare_enable(mhdp->spdif_clk);
-- clk_set_rate(mhdp->spdif_clk, CDNS_DP_SPDIF_CLK);
--}
--
--int cdns_mhdp_audio_config(struct cdns_mhdp_device *mhdp,
-- struct audio_info *audio)
--{
-- int ret;
--
-- /* reset the spdif clk before config */
-- if (audio->format == AFMT_SPDIF_INT) {
-- reset_control_assert(mhdp->spdif_rst);
-- reset_control_deassert(mhdp->spdif_rst);
-- }
--
-- ret = cdns_mhdp_reg_write(mhdp, CM_LANE_CTRL, LANE_REF_CYC);
-- if (ret)
-- goto err_audio_config;
--
-- ret = cdns_mhdp_reg_write(mhdp, CM_CTRL, 0);
-- if (ret)
-- goto err_audio_config;
--
-- if (audio->format == AFMT_I2S)
-- cdns_mhdp_audio_config_i2s(mhdp, audio);
-- else if (audio->format == AFMT_SPDIF_INT)
-- cdns_mhdp_audio_config_spdif(mhdp);
--
-- ret = cdns_mhdp_reg_write(mhdp, AUDIO_PACK_CONTROL, AUDIO_PACK_EN);
--
--err_audio_config:
-- if (ret)
-- DRM_DEV_ERROR(mhdp->dev, "audio config failed: %d\n", ret);
-- return ret;
--}
--EXPORT_SYMBOL(cdns_mhdp_audio_config);
--
- int cdns_mhdp_adjust_lt(struct cdns_mhdp_device *mhdp,
- u8 nlanes, u16 udelay, u8 *lanes_data, u8 *dpcd)
- {
---- a/drivers/gpu/drm/imx/Kconfig
-+++ b/drivers/gpu/drm/imx/Kconfig
-@@ -45,6 +45,7 @@ config DRM_IMX_CDNS_MHDP
- select DRM_CDNS_MHDP
- select DRM_CDNS_DP
- select DRM_CDNS_HDMI
-+ select DRM_CDNS_AUDIO
- depends on DRM_IMX
- help
- Choose this if you want to use HDMI on i.MX8.
---- a/include/drm/bridge/cdns-mhdp-common.h
-+++ b/include/drm/bridge/cdns-mhdp-common.h
-@@ -548,6 +548,7 @@ struct audio_info {
- int sample_rate;
- int channels;
- int sample_width;
-+ int connector_type;
- };
-
- enum vic_pxl_encoding_format {
-@@ -670,11 +671,16 @@ int cdns_mhdp_get_edid_block(void *mhdp,
- int cdns_mhdp_train_link(struct cdns_mhdp_device *mhdp);
- int cdns_mhdp_set_video_status(struct cdns_mhdp_device *mhdp, int active);
- int cdns_mhdp_config_video(struct cdns_mhdp_device *mhdp);
-+
-+/* Audio */
- int cdns_mhdp_audio_stop(struct cdns_mhdp_device *mhdp,
- struct audio_info *audio);
- int cdns_mhdp_audio_mute(struct cdns_mhdp_device *mhdp, bool enable);
- int cdns_mhdp_audio_config(struct cdns_mhdp_device *mhdp,
- struct audio_info *audio);
-+int cdns_mhdp_register_audio_driver(struct device *dev);
-+void cdns_mhdp_unregister_audio_driver(struct device *dev);
-+
- int cdns_mhdp_reg_read(struct cdns_mhdp_device *mhdp, u32 addr);
- int cdns_mhdp_reg_write(struct cdns_mhdp_device *mhdp, u32 addr, u32 val);
- int cdns_mhdp_reg_write_bit(struct cdns_mhdp_device *mhdp, u16 addr,