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

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.com


Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent c55f5692
Loading
Loading
Loading
Loading
+33 −0
Original line number Original line Diff line number Diff line
@@ -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)


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)
	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,


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);