[alsa-devel] [PATCH 1/5] ALSA: hda: add verbs for stripe control
Controllers can support multiple Serial Data Out(SDO) lines, for extended outbound bandwidth, to pump data to all codecs on the link. Codecs can sample data present on SDO.
Add verbs AC_VERB_GET_STRIPE_CONTROL and AC_VERB_SET_STRIPE_CONTROL These can be used to program usage of SDO lines for codec.
Signed-off-by: Sameer Pujar spujar@nvidia.com Reviewed-by: Mohan Kumar D mkumard@nvidia.com Reviewed-by: Ravindra Lokhande rlokhande@nvidia.com --- include/sound/hda_verbs.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/sound/hda_verbs.h b/include/sound/hda_verbs.h index 2a8573a..e36b775 100644 --- a/include/sound/hda_verbs.h +++ b/include/sound/hda_verbs.h @@ -66,6 +66,7 @@ enum { #define AC_VERB_GET_CONFIG_DEFAULT 0x0f1c /* f20: AFG/MFG */ #define AC_VERB_GET_SUBSYSTEM_ID 0x0f20 +#define AC_VERB_GET_STRIPE_CONTROL 0x0f24 #define AC_VERB_GET_CVT_CHAN_COUNT 0x0f2d #define AC_VERB_GET_HDMI_DIP_SIZE 0x0f2e #define AC_VERB_GET_HDMI_ELDD 0x0f2f @@ -110,6 +111,7 @@ enum { #define AC_VERB_SET_CONFIG_DEFAULT_BYTES_3 0x71f #define AC_VERB_SET_EAPD 0x788 #define AC_VERB_SET_CODEC_RESET 0x7ff +#define AC_VERB_SET_STRIPE_CONTROL 0x724 #define AC_VERB_SET_CVT_CHAN_COUNT 0x72d #define AC_VERB_SET_HDMI_DIP_INDEX 0x730 #define AC_VERB_SET_HDMI_DIP_DATA 0x731
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 spujar@nvidia.com Reviewed-by: Mohan Kumar D mkumard@nvidia.com Reviewed-by: Ravindra Lokhande rlokhande@nvidia.com --- include/sound/hdaudio.h | 3 +++ sound/hda/hdac_stream.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+)
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index b4fa1c7..45f944d 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 eee4223..b403b05 100644 --- a/sound/hda/hdac_stream.c +++ b/sound/hda/hdac_stream.c @@ -13,6 +13,40 @@ #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 * @azx_dev: HD-audio core stream object to initialize
bits 16:17 in SD_CTL register refer to stripe control. Added an offset register(AZX_REG_SD_CTL_3B) to have exclusive read/write of corresponding register byte. This helps to avoid unnecessary 32-bit read/write of SD_CTL whenever only stripe or other bits of corresponding byte need to be updated. Also HD audio spec defines SD_CTL as 3 byte register.
Signed-off-by: Sameer Pujar spujar@nvidia.com Reviewed-by: Mohan Kumar D mkumard@nvidia.com Reviewed-by: Ravindra Lokhande rlokhande@nvidia.com --- include/sound/hda_register.h | 1 + 1 file changed, 1 insertion(+)
diff --git a/include/sound/hda_register.h b/include/sound/hda_register.h index 2ab39fb..5b1f5d8 100644 --- a/include/sound/hda_register.h +++ b/include/sound/hda_register.h @@ -79,6 +79,7 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
/* stream register offsets from stream base */ #define AZX_REG_SD_CTL 0x00 +#define AZX_REG_SD_CTL_3B 0x02 /* 3rd byte of SD_CTL register */ #define AZX_REG_SD_STS 0x03 #define AZX_REG_SD_LPIB 0x04 #define AZX_REG_SD_CBL 0x08
Platforms having multiple 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 spujar@nvidia.com Reviewed-by: Mohan Kumar D mkumard@nvidia.com Reviewed-by: Ravindra Lokhande rlokhande@nvidia.com --- sound/hda/hdac_stream.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c index b403b05..7dbaecc 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);
@@ -91,6 +92,9 @@ void snd_hdac_stream_start(struct hdac_stream *azx_dev, bool fresh_start)
/* enable SIE */ snd_hdac_chip_updatel(bus, INTCTL, 0, 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, 0, stripe_ctl & 0x3); /* set DMA start and interrupt mask */ snd_hdac_stream_updateb(azx_dev, SD_CTL, 0, SD_CTL_DMA_START | SD_INT_MASK); @@ -107,6 +111,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, 0x3, 0); azx_dev->running = false; } EXPORT_SYMBOL_GPL(snd_hdac_stream_clear);
On Thu, 10 Jan 2019 18:03:24 +0100, Sameer Pujar wrote:
Platforms having multiple 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 spujar@nvidia.com Reviewed-by: Mohan Kumar D mkumard@nvidia.com Reviewed-by: Ravindra Lokhande rlokhande@nvidia.com
sound/hda/hdac_stream.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c index b403b05..7dbaecc 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);
@@ -91,6 +92,9 @@ void snd_hdac_stream_start(struct hdac_stream *azx_dev, bool fresh_start)
/* enable SIE */ snd_hdac_chip_updatel(bus, INTCTL, 0, 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, 0, stripe_ctl & 0x3);
Let's use 0x03 as the mask. Also it's safer to clear the mask bits, so something like:
snd_hdac_stream_updateb(azx_dev, SD_CTL_3B, AZX_REG_SD_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); @@ -107,6 +111,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, 0x3, 0);
Ditto.
thanks,
Takashi
Program codec stripe through AC_VERB_SET_STRIPE_CONTROL to use multiple sdo lines if supported. Audio needs to be striped across number of sdo lines for simultaneous playbacks of higher resolutions to work.
Signed-off-by: Sameer Pujar spujar@nvidia.com Reviewed-by: Mohan Kumar D mkumard@nvidia.com Reviewed-by: Ravindra Lokhande rlokhande@nvidia.com --- sound/pci/hda/patch_hdmi.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 46f88dc..855e526 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1865,7 +1865,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, hda_nid_t pin_nid; struct snd_pcm_runtime *runtime = substream->runtime; bool non_pcm; - int pinctl; + int pinctl, stripe; int err = 0;
mutex_lock(&spec->pcm_lock); @@ -1909,6 +1909,10 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, per_pin->channels = substream->runtime->channels; per_pin->setup = true;
+ stripe = snd_hdac_get_stream_stripe_ctl(&codec->bus->core, substream); + snd_hda_codec_write(codec, cvt_nid, 0, AC_VERB_SET_STRIPE_CONTROL, + stripe); + hdmi_setup_audio_infoframe(codec, per_pin, non_pcm); mutex_unlock(&per_pin->lock); if (spec->dyn_pin_out) {
On Thu, 10 Jan 2019 18:03:25 +0100, Sameer Pujar wrote:
Program codec stripe through AC_VERB_SET_STRIPE_CONTROL to use multiple sdo lines if supported. Audio needs to be striped across number of sdo lines for simultaneous playbacks of higher resolutions to work.
Signed-off-by: Sameer Pujar spujar@nvidia.com Reviewed-by: Mohan Kumar D mkumard@nvidia.com Reviewed-by: Ravindra Lokhande rlokhande@nvidia.com
sound/pci/hda/patch_hdmi.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 46f88dc..855e526 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1865,7 +1865,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, hda_nid_t pin_nid; struct snd_pcm_runtime *runtime = substream->runtime; bool non_pcm;
- int pinctl;
int pinctl, stripe; int err = 0;
mutex_lock(&spec->pcm_lock);
@@ -1909,6 +1909,10 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, per_pin->channels = substream->runtime->channels; per_pin->setup = true;
- stripe = snd_hdac_get_stream_stripe_ctl(&codec->bus->core, substream);
- snd_hda_codec_write(codec, cvt_nid, 0, AC_VERB_SET_STRIPE_CONTROL,
stripe);
This verb is supposed to be optional, hence it'd be safer to check the widget capability before issuing. I doubt whether all HDMI codecs including the very old one support this verb.
thanks,
Takashi
On Thu, 10 Jan 2019 18:03:21 +0100, Sameer Pujar wrote:
Controllers can support multiple Serial Data Out(SDO) lines, for extended outbound bandwidth, to pump data to all codecs on the link. Codecs can sample data present on SDO.
Add verbs AC_VERB_GET_STRIPE_CONTROL and AC_VERB_SET_STRIPE_CONTROL These can be used to program usage of SDO lines for codec.
Signed-off-by: Sameer Pujar spujar@nvidia.com Reviewed-by: Mohan Kumar D mkumard@nvidia.com Reviewed-by: Ravindra Lokhande rlokhande@nvidia.com
Could you put a cover letter at the next submission?
thanks,
Takashi
On 1/11/2019 4:52 PM, Takashi Iwai wrote:
On Thu, 10 Jan 2019 18:03:21 +0100, Sameer Pujar wrote:
Controllers can support multiple Serial Data Out(SDO) lines, for extended outbound bandwidth, to pump data to all codecs on the link. Codecs can sample data present on SDO.
Add verbs AC_VERB_GET_STRIPE_CONTROL and AC_VERB_SET_STRIPE_CONTROL These can be used to program usage of SDO lines for codec.
Signed-off-by: Sameer Pujar spujar@nvidia.com Reviewed-by: Mohan Kumar D mkumard@nvidia.com Reviewed-by: Ravindra Lokhande rlokhande@nvidia.com
Could you put a cover letter at the next submission?
Sorry for the naive question. Could you please point me to a reference how cover letter for a patch should look like?
Thanks, Sameer.
thanks,
Takashi
----------------------------------------------------------------------------------- This email message is for the sole use of the intended recipient(s) and may contain confidential information. Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message. -----------------------------------------------------------------------------------
On Fri, 11 Jan 2019 12:30:34 +0100, Sameer Pujar wrote:
On 1/11/2019 4:52 PM, Takashi Iwai wrote:
On Thu, 10 Jan 2019 18:03:21 +0100, Sameer Pujar wrote:
Controllers can support multiple Serial Data Out(SDO) lines, for extended outbound bandwidth, to pump data to all codecs on the link. Codecs can sample data present on SDO.
Add verbs AC_VERB_GET_STRIPE_CONTROL and AC_VERB_SET_STRIPE_CONTROL These can be used to program usage of SDO lines for codec.
Signed-off-by: Sameer Pujar spujar@nvidia.com Reviewed-by: Mohan Kumar D mkumard@nvidia.com Reviewed-by: Ravindra Lokhande rlokhande@nvidia.com
Could you put a cover letter at the next submission?
Sorry for the naive question. Could you please point me to a reference how cover letter for a patch should look like?
An easy way would be to create it via git format-patch --cover-letter option. Then describe what this patchset provides, and more importantly, why this is needed. More background that isn't included in each patch description, or some additional notes, as well as the information like what's different from the previous submission can be put there.
Look through ML archives. The post with "[PATCH 0/N]" is usually a cover letter.
Also, for the second submission, don't forget to put a version number to the subject prefix, e.g. [PATCH v2 0/5].
HTH,
Takashi
participants (2)
-
Sameer Pujar
-
Takashi Iwai