ALSA: hda/tegra: correct number of SDO lines for Tegra194
authorSameer Pujar <spujar@nvidia.com>
Mon, 4 May 2020 08:16:14 +0000 (13:46 +0530)
committerTakashi Iwai <tiwai@suse.de>
Mon, 4 May 2020 09:51:05 +0000 (11:51 +0200)
Tegra194 supports 4 SDO lines but GCAP register indicates 2 lines. Thus it
does not reflect the true capability of the HW. This patch presents a
workaround by updating NSDO value accordingly in T_AZA_DBG_CFG_2 register.

Signed-off-by: Sameer Pujar <spujar@nvidia.com>
Link: https://lore.kernel.org/r/1588580176-2801-2-git-send-email-spujar@nvidia.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/hda/hda_tegra.c

index 773992a..45dc544 100644 (file)
 #define HDA_IPFS_INTR_MASK        0x188
 #define HDA_IPFS_EN_INTR          (1 << 16)
 
+/* FPCI */
+#define FPCI_DBG_CFG_2           0x10F4
+#define FPCI_GCAP_NSDO_SHIFT     18
+#define FPCI_GCAP_NSDO_MASK      (0x3 << FPCI_GCAP_NSDO_SHIFT)
+
 /* max number of SDs */
 #define NUM_CAPTURE_SD 1
 #define NUM_PLAYBACK_SD 1
 
+/*
+ * Tegra194 does not reflect correct number of SDO lines. Below macro
+ * is used to update the GCAP register to workaround the issue.
+ */
+#define TEGRA194_NUM_SDO_LINES   4
+
 struct hda_tegra {
        struct azx chip;
        struct device *dev;
@@ -275,6 +286,7 @@ static int hda_tegra_init_clk(struct hda_tegra *hda)
 
 static int hda_tegra_first_init(struct azx *chip, struct platform_device *pdev)
 {
+       struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip);
        struct hdac_bus *bus = azx_bus(chip);
        struct snd_card *card = chip->card;
        int err;
@@ -298,6 +310,26 @@ static int hda_tegra_first_init(struct azx *chip, struct platform_device *pdev)
        bus->irq = irq_id;
        card->sync_irq = bus->irq;
 
+       /*
+        * Tegra194 has 4 SDO lines and the STRIPE can be used to
+        * indicate how many of the SDO lines the stream should be
+        * striped. But GCAP register does not reflect the true
+        * capability of HW. Below workaround helps to fix this.
+        *
+        * GCAP_NSDO is bits 19:18 in T_AZA_DBG_CFG_2,
+        * 0 for 1 SDO, 1 for 2 SDO, 2 for 4 SDO lines.
+        */
+       if (of_device_is_compatible(np, "nvidia,tegra194-hda")) {
+               u32 val;
+
+               dev_info(card->dev, "Override SDO lines to %u\n",
+                        TEGRA194_NUM_SDO_LINES);
+
+               val = readl(hda->regs + FPCI_DBG_CFG_2) & ~FPCI_GCAP_NSDO_MASK;
+               val |= (TEGRA194_NUM_SDO_LINES >> 1) << FPCI_GCAP_NSDO_SHIFT;
+               writel(val, hda->regs + FPCI_DBG_CFG_2);
+       }
+
        gcap = azx_readw(chip, GCAP);
        dev_dbg(card->dev, "chipset global capabilities = 0x%x\n", gcap);
 
@@ -408,6 +440,7 @@ static int hda_tegra_create(struct snd_card *card,
 
 static const struct of_device_id hda_tegra_match[] = {
        { .compatible = "nvidia,tegra30-hda" },
+       { .compatible = "nvidia,tegra194-hda" },
        {},
 };
 MODULE_DEVICE_TABLE(of, hda_tegra_match);