From 676db2fa2a465d759e3568d39f7f1190390606d7 Mon Sep 17 00:00:00 2001 From: Hyunwoong Kim Date: Wed, 20 Nov 2019 14:57:22 +0900 Subject: [PATCH] asoc: abox: check abox power domain status before resuming ITMON error detected when abox driver accessed SFR of abox in the step of resuming abox The state of abox power domain was not off state at that time. This patch check if abox power domain is off before abox driver starts resuming abox H/W. Change-Id: I6afd0d27540705cf6d140ffda94f6f24a567f27d Signed-off-by: Hyunwoong Kim --- arch/arm64/boot/dts/exynos/exynos9610.dtsi | 1 + sound/soc/samsung/abox/abox.c | 28 ++++++++++++++++++++++ sound/soc/samsung/abox/abox.h | 2 ++ 3 files changed, 31 insertions(+) diff --git a/arch/arm64/boot/dts/exynos/exynos9610.dtsi b/arch/arm64/boot/dts/exynos/exynos9610.dtsi index 672ee462360a..000a2b074f44 100644 --- a/arch/arm64/boot/dts/exynos/exynos9610.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos9610.dtsi @@ -2689,6 +2689,7 @@ iommus = <&sysmmu_abox>; pm_qos_int = <0 0 0 0 0>; pm_qos_aud = <1180000 800000 590000 394000 0>; + pd_name = "pd-dispaud"; abox_rdma_0: abox_rdma@0x14A51000 { compatible = "samsung,abox-rdma"; diff --git a/sound/soc/samsung/abox/abox.c b/sound/soc/samsung/abox/abox.c index bde066184814..460bbf31e311 100644 --- a/sound/soc/samsung/abox/abox.c +++ b/sound/soc/samsung/abox/abox.c @@ -5591,6 +5591,7 @@ static int abox_pm_notifier(struct notifier_block *nb, { struct abox_data *data = container_of(nb, struct abox_data, pm_nb); struct device *dev = &data->pdev->dev; + int pd_status, retry = 0; int ret; dev_dbg(dev, "%s(%lu)\n", __func__, action); @@ -5650,6 +5651,24 @@ static int abox_pm_notifier(struct notifier_block *nb, dev_info(dev, "(%d)r suspend_state: %d\n", __LINE__, atomic_read(&data->suspend_state)); if (atomic_read(&data->suspend_state) == 1) { + if (data->abox_pm_domain) { + do { + pd_status = exynos_pd_status(data->abox_pm_domain); + if (pd_status == 0) { + dev_info(dev, "%s is off, go to ABOX initial sequence\n", + data->abox_pm_domain->name); + break; + } else if (pd_status > 0) { + dev_info(dev, "%s is still on, wait for 10ms\n", + data->abox_pm_domain->name); + mdelay(10); + } else if (pd_status < 0) { + dev_info(dev, "%s is in abnormal state\n", + data->abox_pm_domain->name); + break; + } + } while (retry++ < 10); + } pm_runtime_get_sync(&data->pdev->dev); atomic_set(&data->suspend_state, 0); } @@ -5788,6 +5807,7 @@ static int samsung_abox_probe(struct platform_device *pdev) struct platform_device *pdev_tmp; struct abox_data *data; phys_addr_t paddr; + const char *pd_name; int ret, i; dev_info(dev, "%s\n", __func__); @@ -5975,6 +5995,14 @@ static int samsung_abox_probe(struct platform_device *pdev) } } + if (of_property_read_string(np, "pd_name", &pd_name)) { + dev_warn(dev, "no power domain\n"); + data->abox_pm_domain = NULL; + } else { + dev_info(dev, "power domain: %s\n", pd_name); + data->abox_pm_domain = exynos_pd_lookup_name(pd_name); + + } np_tmp = of_parse_phandle(np, "abox_gic", 0); if (!np_tmp) { dev_err(dev, "Failed to get abox_gic device node\n"); diff --git a/sound/soc/samsung/abox/abox.h b/sound/soc/samsung/abox/abox.h index e6461a98326b..a61b229cdb1b 100644 --- a/sound/soc/samsung/abox/abox.h +++ b/sound/soc/samsung/abox/abox.h @@ -14,6 +14,7 @@ #include #include +#include #define ABOX_MASK(name) (GENMASK(ABOX_##name##_H, ABOX_##name##_L)) #define ABOX_MASK_ARG(name, x) (GENMASK(ABOX_##name##_H(x), ABOX_##name##_L(x))) @@ -576,6 +577,7 @@ struct abox_data { void *dump_base; phys_addr_t dump_base_phys; struct iommu_domain *iommu_domain; + struct exynos_pm_domain *abox_pm_domain; unsigned int ipc_tx_offset; unsigned int ipc_rx_offset; unsigned int ipc_tx_ack_offset; -- 2.20.1