In message: [linux-yocto][v5.15/standard/preempt-rt/sdkv5.15/xlnx-soc][PATCH] sound: xilinx: use hdmi-codec as dp audio codec on 13/03/2024 quanyang.w...@windriver.com wrote:
> 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 merged. Bruce > 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 (#13685): https://lists.yoctoproject.org/g/linux-yocto/message/13685 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] -=-=-=-=-=-=-=-=-=-=-=-