Commit 31930d62 authored by Rafal Redzimski's avatar Rafal Redzimski Committed by Jiri Slaby

ALSA: hda_controller: Separate stream_tag for input and output streams.

commit 93e3423e upstream.

Implemented separate stream_tag assignment for input and output streams.
According to hda specification stream tag must be unique throughout the
input streams group, however an output stream might use a stream tag
which is already in use by an input stream. This change is necessary
to support HW which provides a total of more than 15 stream DMA engines
which with legacy implementation causes an overflow on SDxCTL.STRM
field (and the whole SDxCTL register) and as a result usage of
Reserved value 0 in the SDxCTL.STRM field which confuses HDA controller.
Signed-off-by: default avatarRafal Redzimski <rafal.f.redzimski@intel.com>
Signed-off-by: default avatarJayachandran B <jayachandran.b@intel.com>
Signed-off-by: default avatarLibin Yang <libin.yang@intel.com>
Reviewed-by: default avatarVinod Koul <vinod.koul@intel.com>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarJiri Slaby <jslaby@suse.cz>
parent ce3d400e
...@@ -607,6 +607,7 @@ enum { ...@@ -607,6 +607,7 @@ enum {
#define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */ #define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */
#define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */ #define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */
#define AZX_DCAPS_I915_POWERWELL (1 << 27) /* HSW i915 power well support */ #define AZX_DCAPS_I915_POWERWELL (1 << 27) /* HSW i915 power well support */
#define AZX_DCAPS_SEPARATE_STREAM_TAG (1 << 30) /* capture and playback use separate stream tag */
/* quirks for Intel PCH */ /* quirks for Intel PCH */
#define AZX_DCAPS_INTEL_PCH_NOPM \ #define AZX_DCAPS_INTEL_PCH_NOPM \
...@@ -2717,12 +2718,20 @@ static int azx_mixer_create(struct azx *chip) ...@@ -2717,12 +2718,20 @@ static int azx_mixer_create(struct azx *chip)
} }
static bool is_input_stream(struct azx *chip, unsigned char index)
{
return (index >= chip->capture_index_offset &&
index < chip->capture_index_offset + chip->capture_streams);
}
/* /*
* initialize SD streams * initialize SD streams
*/ */
static int azx_init_stream(struct azx *chip) static int azx_init_stream(struct azx *chip)
{ {
int i; int i;
int in_stream_tag = 0;
int out_stream_tag = 0;
/* initialize each stream (aka device) /* initialize each stream (aka device)
* assign the starting bdl address to each stream (device) * assign the starting bdl address to each stream (device)
...@@ -2735,9 +2744,21 @@ static int azx_init_stream(struct azx *chip) ...@@ -2735,9 +2744,21 @@ static int azx_init_stream(struct azx *chip)
azx_dev->sd_addr = chip->remap_addr + (0x20 * i + 0x80); azx_dev->sd_addr = chip->remap_addr + (0x20 * i + 0x80);
/* int mask: SDI0=0x01, SDI1=0x02, ... SDO3=0x80 */ /* int mask: SDI0=0x01, SDI1=0x02, ... SDO3=0x80 */
azx_dev->sd_int_sta_mask = 1 << i; azx_dev->sd_int_sta_mask = 1 << i;
/* stream tag: must be non-zero and unique */
azx_dev->index = i; azx_dev->index = i;
azx_dev->stream_tag = i + 1;
/* stream tag must be unique throughout
* the stream direction group,
* valid values 1...15
* use separate stream tag if the flag
* AZX_DCAPS_SEPARATE_STREAM_TAG is used
*/
if (chip->driver_caps & AZX_DCAPS_SEPARATE_STREAM_TAG)
azx_dev->stream_tag =
is_input_stream(chip, i) ?
++in_stream_tag :
++out_stream_tag;
else
azx_dev->stream_tag = i + 1;
} }
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment