diff options
| author | Rafal Redzimski <rafal.f.redzimski@intel.com> | 2014-12-18 19:44:30 -0500 |
|---|---|---|
| committer | Takashi Iwai <tiwai@suse.de> | 2014-12-26 06:21:21 -0500 |
| commit | 93e3423e6ba4b0ddaf056ecbdf5bc46f18f41deb (patch) | |
| tree | f1c490d8bdcc06665c914ebe77f5b7f10c6caf19 | |
| parent | 97bf6af1f928216fd6c5a66e8a57bfa95a659672 (diff) | |
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: Rafal Redzimski <rafal.f.redzimski@intel.com>
Signed-off-by: Jayachandran B <jayachandran.b@intel.com>
Signed-off-by: Libin Yang <libin.yang@intel.com>
Reviewed-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
| -rw-r--r-- | sound/pci/hda/hda_controller.c | 24 | ||||
| -rw-r--r-- | sound/pci/hda/hda_priv.h | 1 |
2 files changed, 23 insertions, 2 deletions
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c index 8276a743e22e..0cfc9c8c4b4e 100644 --- a/sound/pci/hda/hda_controller.c +++ b/sound/pci/hda/hda_controller.c | |||
| @@ -1922,10 +1922,18 @@ int azx_mixer_create(struct azx *chip) | |||
| 1922 | EXPORT_SYMBOL_GPL(azx_mixer_create); | 1922 | EXPORT_SYMBOL_GPL(azx_mixer_create); |
| 1923 | 1923 | ||
| 1924 | 1924 | ||
| 1925 | static bool is_input_stream(struct azx *chip, unsigned char index) | ||
| 1926 | { | ||
| 1927 | return (index >= chip->capture_index_offset && | ||
| 1928 | index < chip->capture_index_offset + chip->capture_streams); | ||
| 1929 | } | ||
| 1930 | |||
| 1925 | /* initialize SD streams */ | 1931 | /* initialize SD streams */ |
| 1926 | int azx_init_stream(struct azx *chip) | 1932 | int azx_init_stream(struct azx *chip) |
| 1927 | { | 1933 | { |
| 1928 | int i; | 1934 | int i; |
| 1935 | int in_stream_tag = 0; | ||
| 1936 | int out_stream_tag = 0; | ||
| 1929 | 1937 | ||
| 1930 | /* initialize each stream (aka device) | 1938 | /* initialize each stream (aka device) |
| 1931 | * assign the starting bdl address to each stream (device) | 1939 | * assign the starting bdl address to each stream (device) |
| @@ -1938,9 +1946,21 @@ int azx_init_stream(struct azx *chip) | |||
| 1938 | azx_dev->sd_addr = chip->remap_addr + (0x20 * i + 0x80); | 1946 | azx_dev->sd_addr = chip->remap_addr + (0x20 * i + 0x80); |
| 1939 | /* int mask: SDI0=0x01, SDI1=0x02, ... SDO3=0x80 */ | 1947 | /* int mask: SDI0=0x01, SDI1=0x02, ... SDO3=0x80 */ |
| 1940 | azx_dev->sd_int_sta_mask = 1 << i; | 1948 | azx_dev->sd_int_sta_mask = 1 << i; |
| 1941 | /* stream tag: must be non-zero and unique */ | ||
| 1942 | azx_dev->index = i; | 1949 | azx_dev->index = i; |
| 1943 | azx_dev->stream_tag = i + 1; | 1950 | |
| 1951 | /* stream tag must be unique throughout | ||
| 1952 | * the stream direction group, | ||
| 1953 | * valid values 1...15 | ||
| 1954 | * use separate stream tag if the flag | ||
| 1955 | * AZX_DCAPS_SEPARATE_STREAM_TAG is used | ||
| 1956 | */ | ||
| 1957 | if (chip->driver_caps & AZX_DCAPS_SEPARATE_STREAM_TAG) | ||
| 1958 | azx_dev->stream_tag = | ||
| 1959 | is_input_stream(chip, i) ? | ||
| 1960 | ++in_stream_tag : | ||
| 1961 | ++out_stream_tag; | ||
| 1962 | else | ||
| 1963 | azx_dev->stream_tag = i + 1; | ||
| 1944 | } | 1964 | } |
| 1945 | 1965 | ||
| 1946 | return 0; | 1966 | return 0; |
diff --git a/sound/pci/hda/hda_priv.h b/sound/pci/hda/hda_priv.h index aa484fdf4338..166e3e84b963 100644 --- a/sound/pci/hda/hda_priv.h +++ b/sound/pci/hda/hda_priv.h | |||
| @@ -171,6 +171,7 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; | |||
| 171 | #define AZX_DCAPS_I915_POWERWELL (1 << 27) /* HSW i915 powerwell support */ | 171 | #define AZX_DCAPS_I915_POWERWELL (1 << 27) /* HSW i915 powerwell support */ |
| 172 | #define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28) /* CORBRP clears itself after reset */ | 172 | #define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28) /* CORBRP clears itself after reset */ |
| 173 | #define AZX_DCAPS_NO_MSI64 (1 << 29) /* Stick to 32-bit MSIs */ | 173 | #define AZX_DCAPS_NO_MSI64 (1 << 29) /* Stick to 32-bit MSIs */ |
| 174 | #define AZX_DCAPS_SEPARATE_STREAM_TAG (1 << 30) /* capture and playback use separate stream tag */ | ||
| 174 | 175 | ||
| 175 | enum { | 176 | enum { |
| 176 | AZX_SNOOP_TYPE_NONE , | 177 | AZX_SNOOP_TYPE_NONE , |
