From 081e01f059ba03b25499cb4616ec58db0979406d Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Wed, 9 Jan 2019 16:20:50 +0800 Subject: ALSA: hda: Fix mismatches for register mask and value in hdac controller E.g. for azx_int_enable(), we should set both mask and value to be "AZX_INT_CTRL_EN | AZX_INT_GLOBAL_EN"(the mask was 0) to enable controller CIE and GIE. We have similar issues on setting AZX_GCTL_RESET and AZX_GCTL_UNSOL, here try to correct all of them. Signed-off-by: Keyon Jie Signed-off-by: Takashi Iwai --- sound/hda/hdac_controller.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'sound/hda') diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c index 74244d8e2909..b2e9454f5816 100644 --- a/sound/hda/hdac_controller.c +++ b/sound/hda/hdac_controller.c @@ -376,7 +376,7 @@ void snd_hdac_bus_exit_link_reset(struct hdac_bus *bus) { unsigned long timeout; - snd_hdac_chip_updateb(bus, GCTL, 0, AZX_GCTL_RESET); + snd_hdac_chip_updateb(bus, GCTL, AZX_GCTL_RESET, AZX_GCTL_RESET); timeout = jiffies + msecs_to_jiffies(100); while (!snd_hdac_chip_readb(bus, GCTL) && time_before(jiffies, timeout)) @@ -415,7 +415,7 @@ int snd_hdac_bus_reset_link(struct hdac_bus *bus, bool full_reset) } /* Accept unsolicited responses */ - snd_hdac_chip_updatel(bus, GCTL, 0, AZX_GCTL_UNSOL); + snd_hdac_chip_updatel(bus, GCTL, AZX_GCTL_UNSOL, AZX_GCTL_UNSOL); /* detect codecs */ if (!bus->codec_mask) { @@ -431,7 +431,9 @@ EXPORT_SYMBOL_GPL(snd_hdac_bus_reset_link); static void azx_int_enable(struct hdac_bus *bus) { /* enable controller CIE and GIE */ - snd_hdac_chip_updatel(bus, INTCTL, 0, AZX_INT_CTRL_EN | AZX_INT_GLOBAL_EN); + snd_hdac_chip_updatel(bus, INTCTL, + AZX_INT_CTRL_EN | AZX_INT_GLOBAL_EN, + AZX_INT_CTRL_EN | AZX_INT_GLOBAL_EN); } /* disable interrupts */ -- cgit v1.2.3 From fc2a6cf060d0c6feeb3719bf40088e48c5926e40 Mon Sep 17 00:00:00 2001 From: Keyon Jie Date: Wed, 9 Jan 2019 16:20:51 +0800 Subject: ALSA: hda: Fix a mask wrong issue in snd_hdac_stream_start() To enable SIE(Stream Interrupt Enable) in snd_hdac_stream_start(), we should set both mask and value to be "1 << azx_dev->index" for register update, the mask was 0, here fix it. Signed-off-by: Keyon Jie Signed-off-by: Takashi Iwai --- sound/hda/hdac_stream.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sound/hda') diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c index eee422390d8e..ba73a33480b6 100644 --- a/sound/hda/hdac_stream.c +++ b/sound/hda/hdac_stream.c @@ -56,7 +56,9 @@ void snd_hdac_stream_start(struct hdac_stream *azx_dev, bool fresh_start) azx_dev->start_wallclk -= azx_dev->period_wallclk; /* enable SIE */ - snd_hdac_chip_updatel(bus, INTCTL, 0, 1 << azx_dev->index); + snd_hdac_chip_updatel(bus, INTCTL, + 1 << azx_dev->index, + 1 << azx_dev->index); /* set DMA start and interrupt mask */ snd_hdac_stream_updateb(azx_dev, SD_CTL, 0, SD_CTL_DMA_START | SD_INT_MASK); -- cgit v1.2.3 From 5dd3d271320d888bb708ca6252b8a9e416a7fe64 Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Mon, 14 Jan 2019 23:51:09 +0530 Subject: ALSA: hda: Add api to program stripe control bits Controllers and codecs can support striping of audio out across multiple SDO lines. The number of supported SDO lines can be specific to chip. GCAP register can be read to know the maximum supported SDO lines. snd_hdac_get_stream_stripe_ctl() is exposed to program stripe bits on controller and codec side. stripe value: 0 for 1SDO, 1 for 2SDO, 2 for 4SDO lines, etc., Signed-off-by: Sameer Pujar Reviewed-by: Mohan Kumar D Reviewed-by: Ravindra Lokhande Reviewed-by: Pierre-Louis Bossart Signed-off-by: Takashi Iwai --- include/sound/hdaudio.h | 3 +++ sound/hda/hdac_stream.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) (limited to 'sound/hda') diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index b4fa1c775251..45f944d57982 100644 --- a/include/sound/hdaudio.h +++ b/include/sound/hdaudio.h @@ -539,6 +539,9 @@ void snd_hdac_stream_sync(struct hdac_stream *azx_dev, bool start, unsigned int streams); void snd_hdac_stream_timecounter_init(struct hdac_stream *azx_dev, unsigned int streams); +int snd_hdac_get_stream_stripe_ctl(struct hdac_bus *bus, + struct snd_pcm_substream *substream); + /* * macros for easy use */ diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c index ba73a33480b6..820694a2061e 100644 --- a/sound/hda/hdac_stream.c +++ b/sound/hda/hdac_stream.c @@ -12,6 +12,40 @@ #include #include "trace.h" +/** + * snd_hdac_get_stream_stripe_ctl - get stripe control value + * @bus: HD-audio core bus + * @substream: PCM substream + */ +int snd_hdac_get_stream_stripe_ctl(struct hdac_bus *bus, + struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + unsigned int channels = runtime->channels, + rate = runtime->rate, + bits_per_sample = runtime->sample_bits, + max_sdo_lines, value, sdo_line; + + /* T_AZA_GCAP_NSDO is 1:2 bitfields in GCAP */ + max_sdo_lines = snd_hdac_chip_readl(bus, GCAP) & AZX_GCAP_NSDO; + + /* following is from HD audio spec */ + for (sdo_line = max_sdo_lines; sdo_line > 0; sdo_line >>= 1) { + if (rate > 48000) + value = (channels * bits_per_sample * + (rate / 48000)) / sdo_line; + else + value = (channels * bits_per_sample) / sdo_line; + + if (value >= 8) + break; + } + + /* stripe value: 0 for 1SDO, 1 for 2SDO, 2 for 4SDO lines */ + return sdo_line >> 1; +} +EXPORT_SYMBOL_GPL(snd_hdac_get_stream_stripe_ctl); + /** * snd_hdac_stream_init - initialize each stream (aka device) * @bus: HD-audio core bus -- cgit v1.2.3 From 9b6f7e7a296e17990aae298c809b001e99ddd151 Mon Sep 17 00:00:00 2001 From: Sameer Pujar Date: Mon, 14 Jan 2019 23:51:11 +0530 Subject: ALSA: hda: program stripe bits for controller Platforms having multiple SORs and hdmi/dp sinks require higher bandwidth to support simultaneous playbacks of higher resolution. If hda controller supports multiple SDO lines, STRIPE can be used to indicate how many of the SDO lines the stream should be striped across. During stream start stripe control bits are programmed to use given number of sdo lines and the same is cleared during stream stop. Signed-off-by: Sameer Pujar Reviewed-by: Mohan Kumar D Reviewed-by: Ravindra Lokhande Reviewed-by: Pierre-Louis Bossart Signed-off-by: Takashi Iwai --- sound/hda/hdac_stream.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sound/hda') diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c index 820694a2061e..f5dd288d1a7a 100644 --- a/sound/hda/hdac_stream.c +++ b/sound/hda/hdac_stream.c @@ -82,6 +82,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_stream_init); void snd_hdac_stream_start(struct hdac_stream *azx_dev, bool fresh_start) { struct hdac_bus *bus = azx_dev->bus; + int stripe_ctl; trace_snd_hdac_stream_start(bus, azx_dev); @@ -93,6 +94,10 @@ void snd_hdac_stream_start(struct hdac_stream *azx_dev, bool fresh_start) snd_hdac_chip_updatel(bus, INTCTL, 1 << azx_dev->index, 1 << azx_dev->index); + /* set stripe control */ + stripe_ctl = snd_hdac_get_stream_stripe_ctl(bus, azx_dev->substream); + snd_hdac_stream_updateb(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK, + stripe_ctl); /* set DMA start and interrupt mask */ snd_hdac_stream_updateb(azx_dev, SD_CTL, 0, SD_CTL_DMA_START | SD_INT_MASK); @@ -109,6 +114,7 @@ void snd_hdac_stream_clear(struct hdac_stream *azx_dev) snd_hdac_stream_updateb(azx_dev, SD_CTL, SD_CTL_DMA_START | SD_INT_MASK, 0); snd_hdac_stream_writeb(azx_dev, SD_STS, SD_INT_MASK); /* to be sure */ + snd_hdac_stream_updateb(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK, 0); azx_dev->running = false; } EXPORT_SYMBOL_GPL(snd_hdac_stream_clear); -- cgit v1.2.3 From cfc35f9c128cea8fce6a5513b1de50d36f3b209f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 25 Feb 2019 16:49:27 +0100 Subject: ALSA: hda: Extend i915 component bind timeout I set 10 seconds for the timeout of the i915 audio component binding with a hope that recent machines are fast enough to handle all probe tasks in that period, but I was too optimistic. The binding may take longer than that, and this caused a problem on the machine with both audio and graphics driver modules loaded in parallel, as Paul Menzel experienced. This problem haven't hit so often just because the KMS driver is loaded in initrd on most machines. As a simple workaround, extend the timeout to 60 seconds. Fixes: f9b54e1961c7 ("ALSA: hda/i915: Allow delayed i915 audio component binding") Reported-by: Paul Menzel Cc: Signed-off-by: Takashi Iwai --- sound/hda/hdac_i915.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/hda') diff --git a/sound/hda/hdac_i915.c b/sound/hda/hdac_i915.c index 617ff1aa818f..27eb0270a711 100644 --- a/sound/hda/hdac_i915.c +++ b/sound/hda/hdac_i915.c @@ -144,9 +144,9 @@ int snd_hdac_i915_init(struct hdac_bus *bus) return -ENODEV; if (!acomp->ops) { request_module("i915"); - /* 10s timeout */ + /* 60s timeout */ wait_for_completion_timeout(&bind_complete, - msecs_to_jiffies(10 * 1000)); + msecs_to_jiffies(60 * 1000)); } if (!acomp->ops) { dev_info(bus->dev, "couldn't bind with audio component\n"); -- cgit v1.2.3