From 1e9eaef29e62a924a13edfaa6f81fd8e2db191e5 Mon Sep 17 00:00:00 2001 From: jc_gargma Date: Tue, 4 Feb 2020 14:47:21 -0800 Subject: Updated to 5.5.2 --- ...-hda-Fix-DP-MST-support-for-NVIDIA-codecs.patch | 182 +++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 0003-ALSA-hda-Fix-DP-MST-support-for-NVIDIA-codecs.patch (limited to '0003-ALSA-hda-Fix-DP-MST-support-for-NVIDIA-codecs.patch') diff --git a/0003-ALSA-hda-Fix-DP-MST-support-for-NVIDIA-codecs.patch b/0003-ALSA-hda-Fix-DP-MST-support-for-NVIDIA-codecs.patch new file mode 100644 index 0000000..1e74d55 --- /dev/null +++ b/0003-ALSA-hda-Fix-DP-MST-support-for-NVIDIA-codecs.patch @@ -0,0 +1,182 @@ +From 6b43b6519a752c51657b9afa4eb844cad29d2b8c Mon Sep 17 00:00:00 2001 +From: Nikhil Mahale +Date: Mon, 3 Feb 2020 15:36:17 +0530 +Subject: ALSA: hda - Fix DP-MST support for NVIDIA codecs + +If dyn_pcm_assign is set, different jack objects are being created +for pcm and pins. + +If dyn_pcm_assign is set, generic_hdmi_build_jack() calls into +add_hdmi_jack_kctl() to create and track separate jack object for +pcm. Like sync_eld_via_acomp(), hdmi_present_sense_via_verbs() also +need to report status change of the pcm jack. + +Rename pin_idx_to_jack() to pin_idx_to_pcm_jack(). The code to +report status change of pcm jack, move it to update_eld() which is +common for acomp and !acomp code paths. + +Fixes: 5398e94fb753 ALSA: hda - Add DP-MST support for NVIDIA codecs +Signed-off-by: Nikhil Mahale +--- + sound/pci/hda/patch_hdmi.c | 94 +++++++++++++++++++++++----------------------- + 1 file changed, 47 insertions(+), 47 deletions(-) + +diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c +index 630b1f5c276d..469b25065643 100644 +--- a/sound/pci/hda/patch_hdmi.c ++++ b/sound/pci/hda/patch_hdmi.c +@@ -1477,6 +1477,35 @@ static void hdmi_pcm_reset_pin(struct hdmi_spec *spec, + per_pin->channels = 0; + } + ++static struct snd_jack *pin_idx_to_pcm_jack(struct hda_codec *codec, ++ struct hdmi_spec_per_pin *per_pin) ++{ ++ struct hdmi_spec *spec = codec->spec; ++ struct snd_jack *jack = NULL; ++ struct hda_jack_tbl *jack_tbl; ++ ++ /* if !dyn_pcm_assign, get jack from hda_jack_tbl ++ * in !dyn_pcm_assign case, spec->pcm_rec[].jack is not ++ * NULL even after snd_hda_jack_tbl_clear() is called to ++ * free snd_jack. This may cause access invalid memory ++ * when calling snd_jack_report ++ */ ++ if (per_pin->pcm_idx >= 0 && spec->dyn_pcm_assign) { ++ jack = spec->pcm_rec[per_pin->pcm_idx].jack; ++ } else if (!spec->dyn_pcm_assign) { ++ /* ++ * jack tbl doesn't support DP MST ++ * DP MST will use dyn_pcm_assign, ++ * so DP MST will never come here ++ */ ++ jack_tbl = snd_hda_jack_tbl_get_mst(codec, per_pin->pin_nid, ++ per_pin->dev_id); ++ if (jack_tbl) ++ jack = jack_tbl->jack; ++ } ++ return jack; ++} ++ + /* update per_pin ELD from the given new ELD; + * setup info frame and notification accordingly + */ +@@ -1487,9 +1516,15 @@ static bool update_eld(struct hda_codec *codec, + struct hdmi_eld *pin_eld = &per_pin->sink_eld; + struct hdmi_spec *spec = codec->spec; + bool old_eld_valid = pin_eld->eld_valid; ++ struct snd_jack *pcm_jack; + bool eld_changed; + int pcm_idx; + ++ /* pcm_idx >=0 before update_eld() means it is in monitor ++ * disconnected event. Jack must be fetched before update_eld() ++ */ ++ pcm_jack = pin_idx_to_pcm_jack(codec, per_pin); ++ + /* for monitor disconnection, save pcm_idx firstly */ + pcm_idx = per_pin->pcm_idx; + if (spec->dyn_pcm_assign) { +@@ -1544,6 +1579,14 @@ static bool update_eld(struct hda_codec *codec, + SNDRV_CTL_EVENT_MASK_VALUE | + SNDRV_CTL_EVENT_MASK_INFO, + &get_hdmi_pcm(spec, pcm_idx)->eld_ctl->id); ++ ++ if (!pcm_jack) ++ pcm_jack = pin_idx_to_pcm_jack(codec, per_pin); ++ if (eld_changed && pcm_jack) ++ snd_jack_report(pcm_jack, ++ (eld->monitor_present && eld->eld_valid) ? ++ SND_JACK_AVOUT : 0); ++ + return eld_changed; + } + +@@ -1566,7 +1609,6 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin, + * the unsolicited response to avoid custom WARs. + */ + int present; +- bool ret; + bool do_repoll = false; + + present = snd_hda_jack_pin_sense(codec, pin_nid, dev_id); +@@ -1600,45 +1642,14 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin, + else + update_eld(codec, per_pin, eld); + +- ret = !repoll || !eld->monitor_present || eld->eld_valid; +- + jack = snd_hda_jack_tbl_get_mst(codec, pin_nid, per_pin->dev_id); + if (jack) { +- jack->block_report = !ret; ++ jack->block_report = do_repoll; + jack->pin_sense = (eld->monitor_present && eld->eld_valid) ? + AC_PINSENSE_PRESENCE : 0; + } + mutex_unlock(&per_pin->lock); +- return ret; +-} +- +-static struct snd_jack *pin_idx_to_jack(struct hda_codec *codec, +- struct hdmi_spec_per_pin *per_pin) +-{ +- struct hdmi_spec *spec = codec->spec; +- struct snd_jack *jack = NULL; +- struct hda_jack_tbl *jack_tbl; +- +- /* if !dyn_pcm_assign, get jack from hda_jack_tbl +- * in !dyn_pcm_assign case, spec->pcm_rec[].jack is not +- * NULL even after snd_hda_jack_tbl_clear() is called to +- * free snd_jack. This may cause access invalid memory +- * when calling snd_jack_report +- */ +- if (per_pin->pcm_idx >= 0 && spec->dyn_pcm_assign) +- jack = spec->pcm_rec[per_pin->pcm_idx].jack; +- else if (!spec->dyn_pcm_assign) { +- /* +- * jack tbl doesn't support DP MST +- * DP MST will use dyn_pcm_assign, +- * so DP MST will never come here +- */ +- jack_tbl = snd_hda_jack_tbl_get_mst(codec, per_pin->pin_nid, +- per_pin->dev_id); +- if (jack_tbl) +- jack = jack_tbl->jack; +- } +- return jack; ++ return !do_repoll; + } + + /* update ELD and jack state via audio component */ +@@ -1647,8 +1658,6 @@ static void sync_eld_via_acomp(struct hda_codec *codec, + { + struct hdmi_spec *spec = codec->spec; + struct hdmi_eld *eld = &spec->temp_eld; +- struct snd_jack *jack = NULL; +- bool changed; + int size; + + mutex_lock(&per_pin->lock); +@@ -1671,17 +1680,8 @@ static void sync_eld_via_acomp(struct hda_codec *codec, + eld->eld_size = 0; + } + +- /* pcm_idx >=0 before update_eld() means it is in monitor +- * disconnected event. Jack must be fetched before update_eld() +- */ +- jack = pin_idx_to_jack(codec, per_pin); +- changed = update_eld(codec, per_pin, eld); +- if (jack == NULL) +- jack = pin_idx_to_jack(codec, per_pin); +- if (changed && jack) +- snd_jack_report(jack, +- (eld->monitor_present && eld->eld_valid) ? +- SND_JACK_AVOUT : 0); ++ update_eld(codec, per_pin, eld); ++ + mutex_unlock(&per_pin->lock); + } + +-- +cgit v1.2.1-1-g437b + -- cgit v1.2.1