[PATCH 6/7] ASoC: mediatek: mt8188: add bus protection

From: Trevor Wu
Date: Thu Apr 13 2023 - 06:47:47 EST


Add bus protection for reset controller.

Signed-off-by: Trevor Wu <trevor.wu@xxxxxxxxxxxx>
---
sound/soc/mediatek/mt8188/mt8188-afe-pcm.c | 76 ++++++++++++++++++++++
1 file changed, 76 insertions(+)

diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
index fecc891f892d..c3fd32764da0 100644
--- a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
+++ b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
@@ -17,6 +17,7 @@
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/pm_runtime.h>
+#include <linux/soc/mediatek/infracfg.h>
#include <linux/reset.h>
#include <sound/pcm_params.h>
#include "mt8188-afe-common.h"
@@ -3133,12 +3134,68 @@ static int mt8188_afe_parse_of(struct mtk_base_afe *afe,
return 0;
}

+#define MT8188_DELAY_US 10
+#define MT8188_TIMEOUT_US USEC_PER_SEC
+
+static int bus_protect_enable(struct regmap *regmap)
+{
+ int ret;
+ u32 val;
+ u32 mask;
+
+ val = 0;
+ mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP1;
+ regmap_write(regmap, MT8188_TOP_AXI_PROT_EN_2_SET, mask);
+
+ ret = regmap_read_poll_timeout(regmap, MT8188_TOP_AXI_PROT_EN_2_STA,
+ val, (val & mask) == mask,
+ MT8188_DELAY_US, MT8188_TIMEOUT_US);
+ if (ret)
+ return ret;
+
+ val = 0;
+ mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP2;
+ regmap_write(regmap, MT8188_TOP_AXI_PROT_EN_2_SET, mask);
+
+ ret = regmap_read_poll_timeout(regmap, MT8188_TOP_AXI_PROT_EN_2_STA,
+ val, (val & mask) == mask,
+ MT8188_DELAY_US, MT8188_TIMEOUT_US);
+ return ret;
+}
+
+static int bus_protect_disable(struct regmap *regmap)
+{
+ int ret;
+ u32 val;
+ u32 mask;
+
+ val = 0;
+ mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP2;
+ regmap_write(regmap, MT8188_TOP_AXI_PROT_EN_2_CLR, mask);
+
+ ret = regmap_read_poll_timeout(regmap, MT8188_TOP_AXI_PROT_EN_2_STA,
+ val, !(val & mask),
+ MT8188_DELAY_US, MT8188_TIMEOUT_US);
+ if (ret)
+ return ret;
+
+ val = 0;
+ mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP1;
+ regmap_write(regmap, MT8188_TOP_AXI_PROT_EN_2_CLR, mask);
+
+ ret = regmap_read_poll_timeout(regmap, MT8188_TOP_AXI_PROT_EN_2_STA,
+ val, !(val & mask),
+ MT8188_DELAY_US, MT8188_TIMEOUT_US);
+ return ret;
+}
+
static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev)
{
struct mtk_base_afe *afe;
struct mt8188_afe_private *afe_priv;
struct device *dev;
struct reset_control *rstc;
+ struct regmap *infra_ao;
int i, irq_id, ret;

ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(33));
@@ -3163,18 +3220,37 @@ static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(afe->base_addr),
"AFE base_addr not found\n");

+ infra_ao = syscon_regmap_lookup_by_phandle(dev->of_node,
+ "mediatek,infracfg");
+ if (IS_ERR(infra_ao))
+ return dev_err_probe(dev, PTR_ERR(infra_ao),
+ "%s() Cannot find infra_ao controller\n",
+ __func__);
+
/* reset controller to reset audio regs before regmap cache */
rstc = devm_reset_control_get_exclusive(dev, "audiosys");
if (IS_ERR(rstc))
return dev_err_probe(dev, PTR_ERR(rstc),
"could not get audiosys reset\n");

+ ret = bus_protect_enable(infra_ao);
+ if (ret) {
+ dev_err(dev, "bus_protect_enable failed\n");
+ return ret;
+ }
+
ret = reset_control_reset(rstc);
if (ret) {
dev_err(dev, "failed to trigger audio reset:%d\n", ret);
return ret;
}

+ ret = bus_protect_disable(infra_ao);
+ if (ret) {
+ dev_err(dev, "bus_protect_disable failed\n");
+ return ret;
+ }
+
/* initial audio related clock */
ret = mt8188_afe_init_clock(afe);
if (ret)
--
2.18.0