Add hda driver support for the Tegra234 chip. The hdacodec on this chip now supports DP MST feature, HDA block contains azalia controller and one hda-codec instance by supporting 4 independent output streams over DP MST mode. There is no input stream support.
Signed-off-by: Mohan Kumar mkumard@nvidia.com --- sound/pci/hda/hda_tegra.c | 21 +++++++++++++-- sound/pci/hda/patch_hdmi.c | 54 +++++++++++++++++++++++++++++++++----- 2 files changed, 67 insertions(+), 8 deletions(-)
diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c index 773f4903550a..95df52b0505b 100644 --- a/sound/pci/hda/hda_tegra.c +++ b/sound/pci/hda/hda_tegra.c @@ -70,6 +70,7 @@
struct hda_tegra_soc { bool has_hda2codec_2x_reset; + bool has_hda2hdmi; };
struct hda_tegra { @@ -435,15 +436,23 @@ static int hda_tegra_create(struct snd_card *card,
static const struct hda_tegra_soc tegra30_data = { .has_hda2codec_2x_reset = true, + .has_hda2hdmi = true, };
static const struct hda_tegra_soc tegra194_data = { .has_hda2codec_2x_reset = false, + .has_hda2hdmi = true, +}; + +static const struct hda_tegra_soc tegra234_data = { + .has_hda2codec_2x_reset = true, + .has_hda2hdmi = false, };
static const struct of_device_id hda_tegra_match[] = { { .compatible = "nvidia,tegra30-hda", .data = &tegra30_data }, { .compatible = "nvidia,tegra194-hda", .data = &tegra194_data }, + { .compatible = "nvidia,tegra234-hda", .data = &tegra234_data }, {}, }; MODULE_DEVICE_TABLE(of, hda_tegra_match); @@ -473,7 +482,14 @@ static int hda_tegra_probe(struct platform_device *pdev) }
hda->resets[hda->nresets++].id = "hda"; - hda->resets[hda->nresets++].id = "hda2hdmi"; + + /* + * "hda2hdmi" is not applicable for Tegra234. This is because the + * codec is separate IP and not under display SOR partition now. + */ + if (hda->soc->has_hda2hdmi) + hda->resets[hda->nresets++].id = "hda2hdmi"; + /* * "hda2codec_2x" reset is not present on Tegra194. Though DT would * be updated to reflect this, but to have backward compatibility @@ -488,7 +504,8 @@ static int hda_tegra_probe(struct platform_device *pdev) goto out_free;
hda->clocks[hda->nclocks++].id = "hda"; - hda->clocks[hda->nclocks++].id = "hda2hdmi"; + if (hda->soc->has_hda2hdmi) + hda->clocks[hda->nclocks++].id = "hda2hdmi"; hda->clocks[hda->nclocks++].id = "hda2codec_2x";
err = devm_clk_bulk_get(&pdev->dev, hda->nclocks, hda->clocks); diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 92df4f243ec6..879f886d2406 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -3851,17 +3851,29 @@ static int tegra_hdmi_build_pcms(struct hda_codec *codec) return 0; }
-static int patch_tegra_hdmi(struct hda_codec *codec) +static int tegra_hdmi_init(struct hda_codec *codec) { - struct hdmi_spec *spec; - int err; + struct hdmi_spec *spec = codec->spec; + int i, err;
- err = patch_generic_hdmi(codec); - if (err) + err = hdmi_parse_codec(codec); + if (err < 0) { + generic_spec_free(codec); return err; + } + + for (i = 0; i < spec->num_cvts; i++) + snd_hda_codec_write(codec, spec->cvt_nids[i], 0, + AC_VERB_SET_DIGI_CONVERT_1, + AC_DIG1_ENABLE); + + generic_hdmi_init_per_pins(codec);
codec->patch_ops.build_pcms = tegra_hdmi_build_pcms; - spec = codec->spec; + spec->chmap.ops.chmap_cea_alloc_validate_get_type = + nvhdmi_chmap_cea_alloc_validate_get_type; + spec->chmap.ops.chmap_validate = nvhdmi_chmap_validate; + spec->chmap.ops.chmap_cea_alloc_validate_get_type = nvhdmi_chmap_cea_alloc_validate_get_type; spec->chmap.ops.chmap_validate = nvhdmi_chmap_validate; @@ -3869,6 +3881,35 @@ static int patch_tegra_hdmi(struct hda_codec *codec) return 0; }
+static int patch_tegra_hdmi(struct hda_codec *codec) +{ + int err; + + err = alloc_generic_hdmi(codec); + if (err < 0) + return err; + + return tegra_hdmi_init(codec); +} + +static int patch_tegra234_hdmi(struct hda_codec *codec) +{ + struct hdmi_spec *spec; + int err; + + err = alloc_generic_hdmi(codec); + if (err < 0) + return err; + + codec->dp_mst = true; + codec->mst_no_extra_pcms = true; + spec = codec->spec; + spec->dyn_pin_out = true; + spec->dyn_pcm_assign = true; + + return tegra_hdmi_init(codec); +} + /* * ATI/AMD-specific implementations */ @@ -4322,6 +4363,7 @@ HDA_CODEC_ENTRY(0x10de002d, "Tegra186 HDMI/DP0", patch_tegra_hdmi), HDA_CODEC_ENTRY(0x10de002e, "Tegra186 HDMI/DP1", patch_tegra_hdmi), HDA_CODEC_ENTRY(0x10de002f, "Tegra194 HDMI/DP2", patch_tegra_hdmi), HDA_CODEC_ENTRY(0x10de0030, "Tegra194 HDMI/DP3", patch_tegra_hdmi), +HDA_CODEC_ENTRY(0x10de0031, "Tegra234 HDMI/DP", patch_tegra234_hdmi), HDA_CODEC_ENTRY(0x10de0040, "GPU 40 HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de0041, "GPU 41 HDMI/DP", patch_nvhdmi), HDA_CODEC_ENTRY(0x10de0042, "GPU 42 HDMI/DP", patch_nvhdmi),