All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alex Deucher <alexdeucher@gmail.com>
To: alsa-devel@alsa-project.org, broonie@kernel.org,
	vijendar.mukunda@amd.com, tiwai@suse.de
Cc: Alex Deucher <alexander.deucher@amd.com>,
	Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Subject: [PATCH v2 03/14] ASoC: amd: add acp init/de-init functions
Date: Mon, 11 May 2020 17:20:03 -0400	[thread overview]
Message-ID: <20200511212014.2359225-4-alexander.deucher@amd.com> (raw)
In-Reply-To: <20200511212014.2359225-1-alexander.deucher@amd.com>

From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>

Add Renoir ACP PCI driver init/deinit functions.

Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
 sound/soc/amd/renoir/rn-pci-acp3x.c | 143 ++++++++++++++++++++++++++++
 sound/soc/amd/renoir/rn_acp3x.h     |  16 ++++
 2 files changed, 159 insertions(+)

diff --git a/sound/soc/amd/renoir/rn-pci-acp3x.c b/sound/soc/amd/renoir/rn-pci-acp3x.c
index 56b76e355cd4..429813f6ba1c 100644
--- a/sound/soc/amd/renoir/rn-pci-acp3x.c
+++ b/sound/soc/amd/renoir/rn-pci-acp3x.c
@@ -7,13 +7,146 @@
 #include <linux/pci.h>
 #include <linux/module.h>
 #include <linux/io.h>
+#include <linux/delay.h>
 
 #include "rn_acp3x.h"
 
+static int acp_power_gating;
+module_param(acp_power_gating, int, 0644);
+MODULE_PARM_DESC(acp_power_gating, "Enable acp power gating");
+
 struct acp_dev_data {
 	void __iomem *acp_base;
 };
 
+static int rn_acp_power_on(void __iomem *acp_base)
+{
+	u32 val;
+	int timeout;
+
+	val = rn_readl(acp_base + ACP_PGFSM_STATUS);
+
+	if (val == 0)
+		return val;
+
+	if ((val & ACP_PGFSM_STATUS_MASK) !=
+				ACP_POWER_ON_IN_PROGRESS)
+		rn_writel(ACP_PGFSM_CNTL_POWER_ON_MASK,
+			  acp_base + ACP_PGFSM_CONTROL);
+	timeout = 0;
+	while (++timeout < 500) {
+		val = rn_readl(acp_base + ACP_PGFSM_STATUS);
+		if (!val)
+			return 0;
+		udelay(1);
+	}
+	return -ETIMEDOUT;
+}
+
+static int rn_acp_power_off(void __iomem *acp_base)
+{
+	u32 val;
+	int timeout;
+
+	rn_writel(ACP_PGFSM_CNTL_POWER_OFF_MASK,
+		  acp_base + ACP_PGFSM_CONTROL);
+	timeout = 0;
+	while (++timeout < 500) {
+		val = rn_readl(acp_base + ACP_PGFSM_STATUS);
+		if ((val & ACP_PGFSM_STATUS_MASK) == ACP_POWERED_OFF)
+			return 0;
+		udelay(1);
+	}
+	return -ETIMEDOUT;
+}
+
+static int rn_acp_reset(void __iomem *acp_base)
+{
+	u32 val;
+	int timeout;
+
+	rn_writel(1, acp_base + ACP_SOFT_RESET);
+	timeout = 0;
+	while (++timeout < 500) {
+		val = rn_readl(acp_base + ACP_SOFT_RESET);
+		if (val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK)
+			break;
+		cpu_relax();
+	}
+	rn_writel(0, acp_base + ACP_SOFT_RESET);
+	timeout = 0;
+	while (++timeout < 500) {
+		val = rn_readl(acp_base + ACP_SOFT_RESET);
+		if (!val)
+			return 0;
+		cpu_relax();
+	}
+	return -ETIMEDOUT;
+}
+
+static void rn_acp_enable_interrupts(void __iomem *acp_base)
+{
+	u32 ext_intr_ctrl;
+
+	rn_writel(0x01, acp_base + ACP_EXTERNAL_INTR_ENB);
+	ext_intr_ctrl = rn_readl(acp_base + ACP_EXTERNAL_INTR_CNTL);
+	ext_intr_ctrl |= ACP_ERROR_MASK;
+	rn_writel(ext_intr_ctrl, acp_base + ACP_EXTERNAL_INTR_CNTL);
+}
+
+static void rn_acp_disable_interrupts(void __iomem *acp_base)
+{
+	rn_writel(ACP_EXT_INTR_STAT_CLEAR_MASK, acp_base +
+		  ACP_EXTERNAL_INTR_STAT);
+	rn_writel(0x00, acp_base + ACP_EXTERNAL_INTR_ENB);
+}
+
+static int rn_acp_init(void __iomem *acp_base)
+{
+	int ret;
+
+	/* power on */
+	ret = rn_acp_power_on(acp_base);
+	if (ret) {
+		pr_err("ACP power on failed\n");
+		return ret;
+	}
+	rn_writel(0x01, acp_base + ACP_CONTROL);
+	/* Reset */
+	ret = rn_acp_reset(acp_base);
+	if (ret) {
+		pr_err("ACP reset failed\n");
+		return ret;
+	}
+	rn_writel(0x03, acp_base + ACP_CLKMUX_SEL);
+	rn_acp_enable_interrupts(acp_base);
+	return 0;
+}
+
+static int rn_acp_deinit(void __iomem *acp_base)
+{
+	int ret;
+
+	rn_acp_disable_interrupts(acp_base);
+	/* Reset */
+	ret = rn_acp_reset(acp_base);
+	if (ret) {
+		pr_err("ACP reset failed\n");
+		return ret;
+	}
+	rn_writel(0x00, acp_base + ACP_CLKMUX_SEL);
+	rn_writel(0x00, acp_base + ACP_CONTROL);
+	/* power off */
+	if (acp_power_gating) {
+		ret = rn_acp_power_off(acp_base);
+		if (ret) {
+			pr_err("ACP power off failed\n");
+			return ret;
+		}
+	}
+	return 0;
+}
+
 static int snd_rn_acp_probe(struct pci_dev *pci,
 			    const struct pci_device_id *pci_id)
 {
@@ -48,6 +181,9 @@ static int snd_rn_acp_probe(struct pci_dev *pci,
 	}
 	pci_set_master(pci);
 	pci_set_drvdata(pci, adata);
+	ret = rn_acp_init(adata->acp_base);
+	if (ret)
+		goto release_regions;
 	return 0;
 
 release_regions:
@@ -60,6 +196,13 @@ static int snd_rn_acp_probe(struct pci_dev *pci,
 
 static void snd_rn_acp_remove(struct pci_dev *pci)
 {
+	struct acp_dev_data *adata;
+	int ret;
+
+	adata = pci_get_drvdata(pci);
+	ret = rn_acp_deinit(adata->acp_base);
+	if (ret)
+		dev_err(&pci->dev, "ACP de-init failed\n");
 	pci_disable_msi(pci);
 	pci_release_regions(pci);
 	pci_disable_device(pci);
diff --git a/sound/soc/amd/renoir/rn_acp3x.h b/sound/soc/amd/renoir/rn_acp3x.h
index da5715759646..ec2a85085163 100644
--- a/sound/soc/amd/renoir/rn_acp3x.h
+++ b/sound/soc/amd/renoir/rn_acp3x.h
@@ -9,6 +9,22 @@
 
 #define ACP_PHY_BASE_ADDRESS 0x1240000
 #define ACP_DEVICE_ID 0x15E2
+#define ACP_POWER_ON 0x00
+#define ACP_POWER_ON_IN_PROGRESS 0x01
+#define ACP_POWER_OFF 0x02
+#define ACP_POWER_OFF_IN_PROGRESS 0x03
+#define ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK	0x00010001
+
+#define ACP_PGFSM_CNTL_POWER_ON_MASK    0x01
+#define ACP_PGFSM_CNTL_POWER_OFF_MASK   0x00
+#define ACP_PGFSM_STATUS_MASK           0x03
+#define ACP_POWERED_ON                  0x00
+#define ACP_POWER_ON_IN_PROGRESS        0x01
+#define ACP_POWERED_OFF                 0x02
+#define ACP_POWER_OFF_IN_PROGRESS       0x03
+
+#define ACP_ERROR_MASK 0x20000000
+#define ACP_EXT_INTR_STAT_CLEAR_MASK 0xFFFFFFFF
 
 static inline u32 rn_readl(void __iomem *base_addr)
 {
-- 
2.25.4


  parent reply	other threads:[~2020-05-11 21:23 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-11 21:20 [PATCH v2 00/14] Add Renoir ACP driver Alex Deucher
2020-05-11 21:20 ` [PATCH v2 01/14] ASoC: amd: add Renoir ACP3x IP register header Alex Deucher
2020-05-11 21:20 ` [PATCH v2 02/14] ASoC: amd: add Renoir ACP PCI driver Alex Deucher
2020-05-11 21:20 ` Alex Deucher [this message]
2020-05-11 21:20 ` [PATCH v2 04/14] ASoC: amd: create acp3x pdm platform device Alex Deucher
2020-05-11 21:20 ` [PATCH v2 05/14] ASoC: amd: add ACP3x PDM platform driver Alex Deucher
2020-05-11 21:20 ` [PATCH v2 06/14] ASoC: amd: irq handler changes for ACP3x PDM dma driver Alex Deucher
2020-05-11 21:20 ` [PATCH v2 07/14] ASoC: amd: add acp3x pdm driver dma ops Alex Deucher
2020-05-11 21:20 ` [PATCH v2 08/14] ASoC: amd: add ACP PDM DMA driver dai ops Alex Deucher
2020-05-11 22:12   ` Pierre-Louis Bossart
2020-05-12 16:15     ` Mukunda, Vijendar
2020-05-11 21:20 ` [PATCH v2 09/14] ASoC: amd: add Renoir ACP PCI driver PM ops Alex Deucher
2020-05-11 22:28   ` Pierre-Louis Bossart
2020-05-12 13:46     ` Alex Deucher
2020-05-12 15:16       ` Pierre-Louis Bossart
2020-05-12 19:54         ` Mukunda, Vijendar
2020-05-12 20:36           ` Pierre-Louis Bossart
2020-05-13 17:44             ` Mukunda, Vijendar
2020-05-11 21:20 ` [PATCH v2 10/14] ASoC: amd: add ACP PDM DMA driver pm ops Alex Deucher
2020-05-11 21:20 ` [PATCH v2 11/14] ASoC: amd: enable Renoir acp3x drivers build Alex Deucher
2020-05-11 21:20 ` [PATCH v2 12/14] ASoC: amd: create platform devices for Renoir Alex Deucher
2020-05-11 21:20 ` [PATCH v2 13/14] ASoC: amd: RN machine driver using dmic Alex Deucher
2020-05-11 22:37   ` Pierre-Louis Bossart
2020-05-12 14:22     ` Mukunda, Vijendar
2020-05-11 21:20 ` [PATCH v2 14/14] ASoC: amd: enable build for RN machine driver Alex Deucher

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200511212014.2359225-4-alexander.deucher@amd.com \
    --to=alexdeucher@gmail.com \
    --cc=alexander.deucher@amd.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=broonie@kernel.org \
    --cc=tiwai@suse.de \
    --cc=vijendar.mukunda@amd.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.