ALSA: hda/tegra: correct number of SDO lines for Tegra194

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>
This commit is contained in:
Sameer Pujar 2020-05-04 13:46:14 +05:30 committed by Takashi Iwai
parent c55f569274
commit bb9b02a458
1 changed files with 33 additions and 0 deletions

View File

@ -52,10 +52,21 @@
#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);