diff options
| author | Nikhil Mahale <nmahale@nvidia.com> | 2019-11-19 14:17:10 +0530 | 
|---|---|---|
| committer | Takashi Iwai <tiwai@suse.de> | 2019-11-19 11:51:12 +0100 | 
| commit | 5398e94fb753d022301825ebfa5f7cf8a660d8eb (patch) | |
| tree | 729eac41f13aa8eed93cca1b1bfdc633e66eb543 /sound | |
| parent | 9c32fea836928d7a25a83b337f268e533cfc5c3d (diff) | |
| download | linux-5398e94fb753d022301825ebfa5f7cf8a660d8eb.tar.bz2 | |
ALSA: hda - Add DP-MST support for NVIDIA codecs
This patch adds DP-MST support for GK104+ NVIDIA codecs.
GK104+ NVIDIA codecs support DP-MST audio. These codecs have 4
output converters and 4 pin widgets, with 4 device entries per pin
widget for a total of 16 device entries.
This patch moves the existing patch_nvhdmi() definition to
patch_nvhdmi_legacy(), used by pre-GK104 NVIDIA codecs. Redefine
patch_nvhdmi() to enable DP-MST support by setting codec->dp_mst and
spec->dyn_pcm_assign.
Introduce fresh logic for dynamic pcm assignment, making
sure that new pcm assignments are compatible with the legacy static
per_pin-pmc assignment that existed in the days before DP-MST.
Signed-off-by: Nikhil Mahale <nmahale@nvidia.com>
Reviewed-by: Aaron Plattner <aplattner@nvidia.com>
Link: https://lore.kernel.org/r/20191119084710.29267-5-nmahale@nvidia.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
| -rw-r--r-- | sound/pci/hda/patch_hdmi.c | 95 | 
1 files changed, 73 insertions, 22 deletions
| diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 0a3045d49297..55d20e40a195 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1321,15 +1321,32 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx)  }  static int hdmi_find_pcm_slot(struct hdmi_spec *spec, -				struct hdmi_spec_per_pin *per_pin) +			      struct hdmi_spec_per_pin *per_pin)  {  	int i; -	/* try the prefer PCM */ -	if (!test_bit(per_pin->pin_nid_idx, &spec->pcm_bitmap)) +	/* +	 * generic_hdmi_build_pcms() allocates (num_nids + dev_num - 1) +	 * number of pcms. +	 * +	 * The per_pin of pin_nid_idx=n and dev_id=m prefers to get pcm-n +	 * if m==0. This guarantees that dynamic pcm assignments are compatible +	 * with the legacy static per_pin-pmc assignment that existed in the +	 * days before DP-MST. +	 * +	 * per_pin of m!=0 prefers to get pcm=(num_nids + (m - 1)). +	 */ +	if (per_pin->dev_id == 0 && +	    !test_bit(per_pin->pin_nid_idx, &spec->pcm_bitmap))  		return per_pin->pin_nid_idx; -	/* have a second try; check the "reserved area" over num_pins */ +	if (per_pin->dev_id != 0 && +	    !(test_bit(spec->num_nids + (per_pin->dev_id - 1), +		&spec->pcm_bitmap))) { +		return spec->num_nids + (per_pin->dev_id - 1); +	} + +	/* have a second try; check the area over num_nids */  	for (i = spec->num_nids; i < spec->pcm_used; i++) {  		if (!test_bit(i, &spec->pcm_bitmap))  			return i; @@ -3510,6 +3527,40 @@ static int patch_nvhdmi(struct hda_codec *codec)  	struct hdmi_spec *spec;  	int err; +	err = alloc_generic_hdmi(codec); +	if (err < 0) +		return err; +	codec->dp_mst = true; + +	spec = codec->spec; +	spec->dyn_pcm_assign = true; + +	err = hdmi_parse_codec(codec); +	if (err < 0) { +		generic_spec_free(codec); +		return err; +	} + +	generic_hdmi_init_per_pins(codec); + +	spec->dyn_pin_out = true; + +	spec->chmap.ops.chmap_cea_alloc_validate_get_type = +		nvhdmi_chmap_cea_alloc_validate_get_type; +	spec->chmap.ops.chmap_validate = nvhdmi_chmap_validate; + +	codec->link_down_at_suspend = 1; + +	generic_acomp_init(codec, &nvhdmi_audio_ops, nvhdmi_port2pin); + +	return 0; +} + +static int patch_nvhdmi_legacy(struct hda_codec *codec) +{ +	struct hdmi_spec *spec; +	int err; +  	err = patch_generic_hdmi(codec);  	if (err)  		return err; @@ -4118,25 +4169,25 @@ HDA_CODEC_ENTRY(0x10de0004, "GPU 04 HDMI",	patch_nvhdmi_8ch_7x),  HDA_CODEC_ENTRY(0x10de0005, "MCP77/78 HDMI",	patch_nvhdmi_8ch_7x),  HDA_CODEC_ENTRY(0x10de0006, "MCP77/78 HDMI",	patch_nvhdmi_8ch_7x),  HDA_CODEC_ENTRY(0x10de0007, "MCP79/7A HDMI",	patch_nvhdmi_8ch_7x), -HDA_CODEC_ENTRY(0x10de0008, "GPU 08 HDMI/DP",	patch_nvhdmi), -HDA_CODEC_ENTRY(0x10de0009, "GPU 09 HDMI/DP",	patch_nvhdmi), -HDA_CODEC_ENTRY(0x10de000a, "GPU 0a HDMI/DP",	patch_nvhdmi), -HDA_CODEC_ENTRY(0x10de000b, "GPU 0b HDMI/DP",	patch_nvhdmi), -HDA_CODEC_ENTRY(0x10de000c, "MCP89 HDMI",	patch_nvhdmi), -HDA_CODEC_ENTRY(0x10de000d, "GPU 0d HDMI/DP",	patch_nvhdmi), -HDA_CODEC_ENTRY(0x10de0010, "GPU 10 HDMI/DP",	patch_nvhdmi), -HDA_CODEC_ENTRY(0x10de0011, "GPU 11 HDMI/DP",	patch_nvhdmi), -HDA_CODEC_ENTRY(0x10de0012, "GPU 12 HDMI/DP",	patch_nvhdmi), -HDA_CODEC_ENTRY(0x10de0013, "GPU 13 HDMI/DP",	patch_nvhdmi), -HDA_CODEC_ENTRY(0x10de0014, "GPU 14 HDMI/DP",	patch_nvhdmi), -HDA_CODEC_ENTRY(0x10de0015, "GPU 15 HDMI/DP",	patch_nvhdmi), -HDA_CODEC_ENTRY(0x10de0016, "GPU 16 HDMI/DP",	patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de0008, "GPU 08 HDMI/DP",	patch_nvhdmi_legacy), +HDA_CODEC_ENTRY(0x10de0009, "GPU 09 HDMI/DP",	patch_nvhdmi_legacy), +HDA_CODEC_ENTRY(0x10de000a, "GPU 0a HDMI/DP",	patch_nvhdmi_legacy), +HDA_CODEC_ENTRY(0x10de000b, "GPU 0b HDMI/DP",	patch_nvhdmi_legacy), +HDA_CODEC_ENTRY(0x10de000c, "MCP89 HDMI",	patch_nvhdmi_legacy), +HDA_CODEC_ENTRY(0x10de000d, "GPU 0d HDMI/DP",	patch_nvhdmi_legacy), +HDA_CODEC_ENTRY(0x10de0010, "GPU 10 HDMI/DP",	patch_nvhdmi_legacy), +HDA_CODEC_ENTRY(0x10de0011, "GPU 11 HDMI/DP",	patch_nvhdmi_legacy), +HDA_CODEC_ENTRY(0x10de0012, "GPU 12 HDMI/DP",	patch_nvhdmi_legacy), +HDA_CODEC_ENTRY(0x10de0013, "GPU 13 HDMI/DP",	patch_nvhdmi_legacy), +HDA_CODEC_ENTRY(0x10de0014, "GPU 14 HDMI/DP",	patch_nvhdmi_legacy), +HDA_CODEC_ENTRY(0x10de0015, "GPU 15 HDMI/DP",	patch_nvhdmi_legacy), +HDA_CODEC_ENTRY(0x10de0016, "GPU 16 HDMI/DP",	patch_nvhdmi_legacy),  /* 17 is known to be absent */ -HDA_CODEC_ENTRY(0x10de0018, "GPU 18 HDMI/DP",	patch_nvhdmi), -HDA_CODEC_ENTRY(0x10de0019, "GPU 19 HDMI/DP",	patch_nvhdmi), -HDA_CODEC_ENTRY(0x10de001a, "GPU 1a HDMI/DP",	patch_nvhdmi), -HDA_CODEC_ENTRY(0x10de001b, "GPU 1b HDMI/DP",	patch_nvhdmi), -HDA_CODEC_ENTRY(0x10de001c, "GPU 1c HDMI/DP",	patch_nvhdmi), +HDA_CODEC_ENTRY(0x10de0018, "GPU 18 HDMI/DP",	patch_nvhdmi_legacy), +HDA_CODEC_ENTRY(0x10de0019, "GPU 19 HDMI/DP",	patch_nvhdmi_legacy), +HDA_CODEC_ENTRY(0x10de001a, "GPU 1a HDMI/DP",	patch_nvhdmi_legacy), +HDA_CODEC_ENTRY(0x10de001b, "GPU 1b HDMI/DP",	patch_nvhdmi_legacy), +HDA_CODEC_ENTRY(0x10de001c, "GPU 1c HDMI/DP",	patch_nvhdmi_legacy),  HDA_CODEC_ENTRY(0x10de0020, "Tegra30 HDMI",	patch_tegra_hdmi),  HDA_CODEC_ENTRY(0x10de0022, "Tegra114 HDMI",	patch_tegra_hdmi),  HDA_CODEC_ENTRY(0x10de0028, "Tegra124 HDMI",	patch_tegra_hdmi), |