Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 93e3423e authored by Rafal Redzimski's avatar Rafal Redzimski Committed by Takashi Iwai
Browse files

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



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>
parent 97bf6af1
Loading
Loading
Loading
Loading
+22 −2
Original line number Original line Diff line number Diff line
@@ -1922,10 +1922,18 @@ int azx_mixer_create(struct azx *chip)
EXPORT_SYMBOL_GPL(azx_mixer_create);
EXPORT_SYMBOL_GPL(azx_mixer_create);




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 */
int azx_init_stream(struct azx *chip)
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)
@@ -1938,8 +1946,20 @@ 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;

		/* 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;
			azx_dev->stream_tag = i + 1;
	}
	}


+1 −0
Original line number Original line Diff line number Diff line
@@ -171,6 +171,7 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
#define AZX_DCAPS_I915_POWERWELL (1 << 27)	/* HSW i915 powerwell support */
#define AZX_DCAPS_I915_POWERWELL (1 << 27)	/* HSW i915 powerwell support */
#define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28)	/* CORBRP clears itself after reset */
#define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28)	/* CORBRP clears itself after reset */
#define AZX_DCAPS_NO_MSI64      (1 << 29)	/* Stick to 32-bit MSIs */
#define AZX_DCAPS_NO_MSI64      (1 << 29)	/* Stick to 32-bit MSIs */
#define AZX_DCAPS_SEPARATE_STREAM_TAG	(1 << 30) /* capture and playback use separate stream tag */


enum {
enum {
	AZX_SNOOP_TYPE_NONE ,
	AZX_SNOOP_TYPE_NONE ,