Commit bb9b02a4 authored by Sameer Pujar's avatar Sameer Pujar Committed by Takashi Iwai

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: default avatarSameer Pujar <spujar@nvidia.com>
Link: https://lore.kernel.org/r/1588580176-2801-2-git-send-email-spujar@nvidia.comSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent c55f5692
...@@ -52,10 +52,21 @@ ...@@ -52,10 +52,21 @@
#define HDA_IPFS_INTR_MASK 0x188 #define HDA_IPFS_INTR_MASK 0x188
#define HDA_IPFS_EN_INTR (1 << 16) #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 */ /* max number of SDs */
#define NUM_CAPTURE_SD 1 #define NUM_CAPTURE_SD 1
#define NUM_PLAYBACK_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 hda_tegra {
struct azx chip; struct azx chip;
struct device *dev; struct device *dev;
...@@ -275,6 +286,7 @@ static int hda_tegra_init_clk(struct hda_tegra *hda) ...@@ -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) 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 hdac_bus *bus = azx_bus(chip);
struct snd_card *card = chip->card; struct snd_card *card = chip->card;
int err; int err;
...@@ -298,6 +310,26 @@ static int hda_tegra_first_init(struct azx *chip, struct platform_device *pdev) ...@@ -298,6 +310,26 @@ static int hda_tegra_first_init(struct azx *chip, struct platform_device *pdev)
bus->irq = irq_id; bus->irq = irq_id;
card->sync_irq = bus->irq; 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); gcap = azx_readw(chip, GCAP);
dev_dbg(card->dev, "chipset global capabilities = 0x%x\n", 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, ...@@ -408,6 +440,7 @@ static int hda_tegra_create(struct snd_card *card,
static const struct of_device_id hda_tegra_match[] = { static const struct of_device_id hda_tegra_match[] = {
{ .compatible = "nvidia,tegra30-hda" }, { .compatible = "nvidia,tegra30-hda" },
{ .compatible = "nvidia,tegra194-hda" },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, hda_tegra_match); MODULE_DEVICE_TABLE(of, hda_tegra_match);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment