From: Quanyang Wang <quanyang.w...@windriver.com> According to the description in the section "Audio Management" of Chapter 33 in "Zynq UltraScale+ Device Technical Reference Manual", A set/clr operation to TX_AUDIO_CONTROL register is needed when we start/stop audio play. It means that when we stop playing audio, TX_AUDIO_CONTROL register should be cleared. Now the dp codec driver xilinx-dp-codec.c can't access DP Tx registers and it has no control of DP Tx Audio registers. This results that even if we close the audio device after playing audio, Tx Audio is still working and it triggers numerous underflow interrupts (bit 17 in DP_INT_STATUS).
zcu102-zynqmp:~$ cat /proc/interrupts | grep display 52: 1063792 0 0 0 GICv2 151 Level fd4a0000.display zcu102-zynqmp:~$ top Mem: 158168K used, 3864792K free, 9992K shrd, 0K buff, 36500K cached CPU: 0.0% usr 1.0% sys 0.0% nic 98.9% idle 0.0% io 0.0% irq 0.0% sirq Load average: 0.03 0.03 0.01 1/122 391 PID PPID USER STAT VSZ %VSZ CPU %CPU COMMAND 223 2 root SW 0 0.0 0 0.9 [irq/52-fd4a0000] 352 1 root S 94148 2.3 0 0.0 /usr/sbin/tcf-agent -d -L- -l0 So we register a HDMI codec device and use callbacks in hdmi_codec_ops to set/clr TX_AUDIO_CONTROL. Signed-off-by: Quanyang Wang <quanyang.w...@windriver.com> --- Hi Bruce, Would you please help merge this patch to the branches: v5.15/standard/preempt-rt/sdkv5.15/xlnx-soc v5.15/standard/sdkv5.15/xlnx-soc Thanks, Quanyang --- drivers/gpu/drm/xlnx/zynqmp_dp.c | 55 +++++++++++++++++++++++++++++++ sound/soc/xilinx/Kconfig | 1 + sound/soc/xilinx/xilinx-dp-card.c | 14 ++------ 3 files changed, 59 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c index 308404f122957..c9badbfe5b566 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c @@ -26,6 +26,7 @@ #include <linux/phy/phy.h> #include <linux/reset.h> #include <linux/uaccess.h> +#include <sound/hdmi-codec.h> #include "zynqmp_disp.h" #include "zynqmp_dp.h" @@ -329,6 +330,7 @@ struct zynqmp_dp { void __iomem *iomem; struct reset_control *reset; int irq; + struct platform_device *audio_pdev; struct zynqmp_dp_config config; struct drm_dp_aux aux; @@ -375,6 +377,53 @@ static void zynqmp_dp_set(void __iomem *base, int offset, u32 set) zynqmp_dp_write(base, offset, zynqmp_dp_read(base, offset) | set); } +static int zynqmp_dp_audio_hw_params(struct device *dev, void *data, + struct hdmi_codec_daifmt *daifmt, + struct hdmi_codec_params *params) +{ + return 0; +} + +static int zynqmp_dp_audio_startup(struct device *dev, void *data) +{ + struct zynqmp_dp *dp = data; + + if (zynqmp_disp_aud_enabled(dp->dpsub->disp)) + zynqmp_dp_write(dp->iomem, ZYNQMP_DP_TX_AUDIO_CONTROL, 1); + + return 0; +} + +static void zynqmp_dp_audio_shutdown(struct device *dev, void *data) +{ + struct zynqmp_dp *dp = data; + + if (zynqmp_disp_aud_enabled(dp->dpsub->disp)) + zynqmp_dp_write(dp->iomem, ZYNQMP_DP_TX_AUDIO_CONTROL, 0); +} + +static const struct hdmi_codec_ops audio_codec_ops = { + .hw_params = zynqmp_dp_audio_hw_params, + .audio_shutdown = zynqmp_dp_audio_shutdown, + .audio_startup = zynqmp_dp_audio_startup, +}; + +static int zynqmp_dp_audio_init(struct zynqmp_dp *dp, + struct device *dev) +{ + struct hdmi_codec_pdata codec_data = { + .ops = &audio_codec_ops, + .spdif = 1, + .data = dp, + }; + + dp->audio_pdev = platform_device_register_data( + dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_NONE, + &codec_data, sizeof(codec_data)); + + return PTR_ERR_OR_ZERO(dp->audio_pdev); +} + /* ----------------------------------------------------------------------------- * PHY Handling */ @@ -1950,6 +1999,12 @@ int zynqmp_dp_probe(struct platform_device *pdev) goto error; } + ret = zynqmp_dp_audio_init(dp, dp->dev); + if (ret < 0) { + dev_err(dp->dev, "failed to initialize DP audio codec\n"); + goto error; + } + irq = platform_get_irq(pdev, 0); if (irq < 0) { ret = irq; diff --git a/sound/soc/xilinx/Kconfig b/sound/soc/xilinx/Kconfig index ade55b32a8cc6..787b92a406a23 100644 --- a/sound/soc/xilinx/Kconfig +++ b/sound/soc/xilinx/Kconfig @@ -3,6 +3,7 @@ config SND_SOC_XILINX_DP tristate "Audio support for the the Xilinx DisplayPort" select SND_DMAENGINE_PCM select SND_SOC_GENERIC_DMAENGINE_PCM + select SND_SOC_HDMI_CODEC help Audio support the for Xilinx DisplayPort. diff --git a/sound/soc/xilinx/xilinx-dp-card.c b/sound/soc/xilinx/xilinx-dp-card.c index 396a87d56394f..ec0682f2a7a6c 100644 --- a/sound/soc/xilinx/xilinx-dp-card.c +++ b/sound/soc/xilinx/xilinx-dp-card.c @@ -36,12 +36,12 @@ static const struct snd_soc_ops xilinx_dp_ops = { SND_SOC_DAILINK_DEFS(xilinx_dp0, DAILINK_COMP_ARRAY(COMP_CPU("xilinx-dp-snd-codec-dai")), - DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "xilinx-dp-snd-codec-dai")), + DAILINK_COMP_ARRAY(COMP_CODEC("hdmi-audio-codec", "spdif-hifi")), DAILINK_COMP_ARRAY(COMP_PLATFORM(NULL))); SND_SOC_DAILINK_DEFS(xilinx_dp1, DAILINK_COMP_ARRAY(COMP_CPU("xilinx-dp-snd-codec-dai")), - DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "xilinx-dp-snd-codec-dai")), + DAILINK_COMP_ARRAY(COMP_CODEC("hdmi-audio-codec", "spdif-hifi")), DAILINK_COMP_ARRAY(COMP_PLATFORM(NULL))); static struct snd_soc_dai_link xilinx_dp_dai_links[] = { @@ -71,28 +71,20 @@ static int xilinx_dp_probe(struct platform_device *pdev) { struct snd_soc_card *card = &xilinx_dp_card; struct device_node *node = pdev->dev.of_node; - struct device_node *codec, *pcm; + struct device_node *pcm; int ret; card->dev = &pdev->dev; - codec = of_parse_phandle(node, "xlnx,dp-snd-codec", 0); - if (!codec) - return -ENODEV; - pcm = of_parse_phandle(node, "xlnx,dp-snd-pcm", 0); if (!pcm) return -ENODEV; xilinx_dp_dai_links[0].platforms->of_node = pcm; - xilinx_dp_dai_links[0].cpus->of_node = codec; - xilinx_dp_dai_links[0].codecs->of_node = codec; pcm = of_parse_phandle(node, "xlnx,dp-snd-pcm", 1); if (!pcm) return -ENODEV; xilinx_dp_dai_links[1].platforms->of_node = pcm; - xilinx_dp_dai_links[1].cpus->of_node = codec; - xilinx_dp_dai_links[1].codecs->of_node = codec; ret = devm_snd_soc_register_card(&pdev->dev, card); if (ret) -- 2.36.1
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#13680): https://lists.yoctoproject.org/g/linux-yocto/message/13680 Mute This Topic: https://lists.yoctoproject.org/mt/104902291/21656 Group Owner: linux-yocto+ow...@lists.yoctoproject.org Unsubscribe: https://lists.yoctoproject.org/g/linux-yocto/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-