summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilson Sung <wilsonsung@google.com>2020-05-14 01:32:16 +0800
committerWilson Sung <wilsonsung@google.com>2020-05-19 20:11:20 +0800
commitab11b12d131f189bbf0c737988149d8699eeb0bd (patch)
treea300d1b86912a91808d966a794b4badf5e669703
parent5763f0a1b2fa2ae2a2102e8bda94c985e90d9dc7 (diff)
parent5d2356acfe70bd212d56eace3e43b91e76b4ccaa (diff)
downloadmsm-extra-android-11.0.0_r0.74.tar.gz
Bug: 155859424 Change-Id: Ie0b4844432f2dfa3d8f310ca1eca8c8a5d3e2f7f Signed-off-by: Wilson Sung <wilsonsung@google.com>
-rw-r--r--4.0/asoc/codecs/bolero/bolero-cdc.c13
-rw-r--r--4.0/dsp/Kbuild2
-rw-r--r--4.0/dsp/hw-vote-rsc.c82
-rw-r--r--4.0/dsp/q6_init.c4
-rw-r--r--4.0/dsp/q6_init.h4
-rw-r--r--4.0/include/dsp/hw-vote-rsc.h15
-rw-r--r--4.0/soc/pinctrl-lpi.c8
-rw-r--r--4.0/soc/swr-mstr-ctrl.c11
8 files changed, 125 insertions, 14 deletions
diff --git a/4.0/asoc/codecs/bolero/bolero-cdc.c b/4.0/asoc/codecs/bolero/bolero-cdc.c
index 5ddc674e..59b1c58f 100644
--- a/4.0/asoc/codecs/bolero/bolero-cdc.c
+++ b/4.0/asoc/codecs/bolero/bolero-cdc.c
@@ -14,6 +14,7 @@
#include <soc/snd_event.h>
#include <linux/pm_runtime.h>
#include <soc/swr-common.h>
+#include <dsp/hw-vote-rsc.h>
#include "bolero-cdc.h"
#include "internal.h"
#include "bolero-clk-rsc.h"
@@ -835,6 +836,10 @@ static int bolero_ssr_enable(struct device *dev, void *data)
if (priv->rsc_clk_cb)
priv->rsc_clk_cb(priv->clk_dev, BOLERO_MACRO_EVT_SSR_GFMUX_UP);
+ /* Reset HW votes after SSR */
+ hw_vote_rsc_reset(priv->lpass_core_hw_vote);
+ hw_vote_rsc_reset(priv->lpass_audio_hw_vote);
+
trace_printk("%s: clk count reset\n", __func__);
regcache_cache_only(priv->regmap, false);
mutex_lock(&priv->clk_lock);
@@ -1379,7 +1384,7 @@ int bolero_runtime_resume(struct device *dev)
}
if (priv->core_hw_vote_count == 0) {
- ret = clk_prepare_enable(priv->lpass_core_hw_vote);
+ ret = hw_vote_rsc_enable(priv->lpass_core_hw_vote);
if (ret < 0) {
dev_err(dev, "%s:lpass core hw enable failed\n",
__func__);
@@ -1397,7 +1402,7 @@ audio_vote:
}
if (priv->core_audio_vote_count == 0) {
- ret = clk_prepare_enable(priv->lpass_audio_hw_vote);
+ ret = hw_vote_rsc_enable(priv->lpass_audio_hw_vote);
if (ret < 0) {
dev_err(dev, "%s:lpass audio hw enable failed\n",
__func__);
@@ -1422,7 +1427,7 @@ int bolero_runtime_suspend(struct device *dev)
mutex_lock(&priv->vote_lock);
if (priv->lpass_core_hw_vote != NULL) {
if (--priv->core_hw_vote_count == 0)
- clk_disable_unprepare(priv->lpass_core_hw_vote);
+ hw_vote_rsc_disable(priv->lpass_core_hw_vote);
if (priv->core_hw_vote_count < 0)
priv->core_hw_vote_count = 0;
} else {
@@ -1434,7 +1439,7 @@ int bolero_runtime_suspend(struct device *dev)
if (priv->lpass_audio_hw_vote != NULL) {
if (--priv->core_audio_vote_count == 0)
- clk_disable_unprepare(priv->lpass_audio_hw_vote);
+ hw_vote_rsc_disable(priv->lpass_audio_hw_vote);
if (priv->core_audio_vote_count < 0)
priv->core_audio_vote_count = 0;
} else {
diff --git a/4.0/dsp/Kbuild b/4.0/dsp/Kbuild
index 6f1a1801..53c510b9 100644
--- a/4.0/dsp/Kbuild
+++ b/4.0/dsp/Kbuild
@@ -112,6 +112,7 @@ ifdef CONFIG_SND_SOC_MSM_QDSP6V2_INTF
Q6_OBJS += adsp_err.o
Q6_OBJS += msm_audio_ion.o
Q6_OBJS += avtimer.o
+ Q6_OBJS += hw-vote-rsc.o
Q6_OBJS += q6_init.o
endif
@@ -131,6 +132,7 @@ ifdef CONFIG_SND_SOC_MSM_QDSP6V2_VM
Q6_OBJS += adsp_err.o
Q6_OBJS += msm_audio_ion_vm.o
Q6_OBJS += avtimer.o
+ Q6_OBJS += hw-vote-rsc.o
Q6_OBJS += q6_init.o
endif
diff --git a/4.0/dsp/hw-vote-rsc.c b/4.0/dsp/hw-vote-rsc.c
new file mode 100644
index 00000000..b90c56b7
--- /dev/null
+++ b/4.0/dsp/hw-vote-rsc.c
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/ratelimit.h>
+#include <dsp/hw-vote-rsc.h>
+
+struct mutex hw_vote_lock;
+static bool is_init_done;
+
+int hw_vote_rsc_enable(struct clk* vote_handle)
+{
+ int ret = 0;
+
+ if (!is_init_done || vote_handle == NULL) {
+ pr_err_ratelimited("%s: init failed or vote handle NULL\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ mutex_lock(&hw_vote_lock);
+ ret = clk_prepare_enable(vote_handle);
+ mutex_unlock(&hw_vote_lock);
+
+ trace_printk("%s\n", __func__);
+ return ret;
+}
+EXPORT_SYMBOL(hw_vote_rsc_enable);
+
+void hw_vote_rsc_disable(struct clk* vote_handle)
+{
+ if (!is_init_done || vote_handle == NULL) {
+ pr_err_ratelimited("%s: init failed or vote handle NULL\n",
+ __func__);
+ return;
+ }
+
+ mutex_lock(&hw_vote_lock);
+ clk_disable_unprepare(vote_handle);
+ mutex_unlock(&hw_vote_lock);
+ trace_printk("%s\n", __func__);
+}
+EXPORT_SYMBOL(hw_vote_rsc_disable);
+
+void hw_vote_rsc_reset(struct clk* vote_handle)
+{
+ int count = 0;
+
+ if (!is_init_done || vote_handle == NULL) {
+ pr_err_ratelimited("%s: init failed or vote handle NULL\n",
+ __func__);
+ return;
+ }
+
+ mutex_lock(&hw_vote_lock);
+ while (__clk_is_enabled(vote_handle)) {
+ clk_disable_unprepare(vote_handle);
+ count++;
+ }
+ pr_debug("%s: Vote count after SSR: %d\n", __func__, count);
+ trace_printk("%s: Vote count after SSR: %d\n", __func__, count);
+
+ while (count--)
+ clk_prepare_enable(vote_handle);
+ mutex_unlock(&hw_vote_lock);
+}
+EXPORT_SYMBOL(hw_vote_rsc_reset);
+
+void hw_vote_rsc_init()
+{
+ mutex_init(&hw_vote_lock);
+ is_init_done = true;
+}
+
+void hw_vote_rsc_exit()
+{
+ mutex_destroy(&hw_vote_lock);
+ is_init_done = false;
+}
diff --git a/4.0/dsp/q6_init.c b/4.0/dsp/q6_init.c
index fb18741d..f0f3d44b 100644
--- a/4.0/dsp/q6_init.c
+++ b/4.0/dsp/q6_init.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (c) 2017, 2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017, 2019-2020 The Linux Foundation. All rights reserved.
*/
#include <linux/kernel.h>
@@ -24,11 +24,13 @@ static int __init audio_q6_init(void)
avtimer_init();
msm_mdf_init();
voice_mhi_init();
+ hw_vote_rsc_init();
return 0;
}
static void __exit audio_q6_exit(void)
{
+ hw_vote_rsc_exit();
msm_mdf_exit();
avtimer_exit();
audio_slimslave_exit();
diff --git a/4.0/dsp/q6_init.h b/4.0/dsp/q6_init.h
index 4df2e032..028a9344 100644
--- a/4.0/dsp/q6_init.h
+++ b/4.0/dsp/q6_init.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*/
#ifndef __Q6_INIT_H__
@@ -16,6 +16,7 @@ int core_init(void);
int rtac_init(void);
int msm_audio_ion_init(void);
int avtimer_init(void);
+int hw_vote_rsc_init(void);
#ifdef CONFIG_MSM_MDF
int msm_mdf_init(void);
void msm_mdf_exit(void);
@@ -43,6 +44,7 @@ static inline void spk_params_exit(void)
}
#endif
+void hw_vote_rsc_exit(void);
void avtimer_exit(void);
void msm_audio_ion_exit(void);
void rtac_exit(void);
diff --git a/4.0/include/dsp/hw-vote-rsc.h b/4.0/include/dsp/hw-vote-rsc.h
new file mode 100644
index 00000000..35e8cd9c
--- /dev/null
+++ b/4.0/include/dsp/hw-vote-rsc.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef HW_VOTE_RSC_H
+#define HW_VOTE_RSC_H
+
+int hw_vote_rsc_enable(struct clk* vote_handle);
+void hw_vote_rsc_disable(struct clk* vote_handle);
+void hw_vote_rsc_reset(struct clk* vote_handle);
+void hw_vote_rsc_init(void);
+void hw_vote_rsc_exit(void);
+
+#endif /* HW_VOTE_RSC_H */
diff --git a/4.0/soc/pinctrl-lpi.c b/4.0/soc/pinctrl-lpi.c
index 4df9791c..2b8810d9 100644
--- a/4.0/soc/pinctrl-lpi.c
+++ b/4.0/soc/pinctrl-lpi.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/gpio.h>
@@ -16,6 +16,7 @@
#include <linux/clk.h>
#include <linux/bitops.h>
#include <soc/snd_event.h>
+#include <dsp/hw-vote-rsc.h>
#include <linux/pm_runtime.h>
#include <dsp/audio_notifier.h>
@@ -842,7 +843,6 @@ static int lpi_pinctrl_remove(struct platform_device *pdev)
gpiochip_remove(&state->chip);
mutex_destroy(&state->core_hw_vote_lock);
mutex_destroy(&state->slew_access_lock);
-
return 0;
}
@@ -869,7 +869,7 @@ int lpi_pinctrl_runtime_resume(struct device *dev)
}
mutex_lock(&state->core_hw_vote_lock);
- ret = clk_prepare_enable(hw_vote);
+ ret = hw_vote_rsc_enable(hw_vote);
if (ret < 0) {
pm_runtime_set_autosuspend_delay(dev,
LPI_AUTO_SUSPEND_DELAY_ERROR);
@@ -903,7 +903,7 @@ int lpi_pinctrl_runtime_suspend(struct device *dev)
mutex_lock(&state->core_hw_vote_lock);
if (state->core_hw_vote_status) {
- clk_disable_unprepare(hw_vote);
+ hw_vote_rsc_disable(hw_vote);
state->core_hw_vote_status = false;
}
mutex_unlock(&state->core_hw_vote_lock);
diff --git a/4.0/soc/swr-mstr-ctrl.c b/4.0/soc/swr-mstr-ctrl.c
index 23ccd234..771d245d 100644
--- a/4.0/soc/swr-mstr-ctrl.c
+++ b/4.0/soc/swr-mstr-ctrl.c
@@ -22,6 +22,7 @@
#include <soc/swr-common.h>
#include <linux/regmap.h>
#include <dsp/msm-audio-event-notify.h>
+#include <dsp/hw-vote-rsc.h>
#include "swrm_registers.h"
#include "swr-mstr-ctrl.h"
@@ -378,7 +379,7 @@ static int swrm_request_hw_vote(struct swr_mstr_ctrl *swrm,
}
if (++swrm->hw_core_clk_en == 1) {
ret =
- clk_prepare_enable(
+ hw_vote_rsc_enable(
swrm->lpass_core_hw_vote);
if (ret < 0) {
dev_err(swrm->dev,
@@ -392,7 +393,7 @@ static int swrm_request_hw_vote(struct swr_mstr_ctrl *swrm,
if (swrm->hw_core_clk_en < 0)
swrm->hw_core_clk_en = 0;
else if (swrm->hw_core_clk_en == 0)
- clk_disable_unprepare(
+ hw_vote_rsc_disable(
swrm->lpass_core_hw_vote);
}
}
@@ -410,7 +411,7 @@ static int swrm_request_hw_vote(struct swr_mstr_ctrl *swrm,
}
if (++swrm->aud_core_clk_en == 1) {
ret =
- clk_prepare_enable(
+ hw_vote_rsc_enable(
swrm->lpass_core_audio);
if (ret < 0) {
dev_err(swrm->dev,
@@ -424,7 +425,7 @@ static int swrm_request_hw_vote(struct swr_mstr_ctrl *swrm,
if (swrm->aud_core_clk_en < 0)
swrm->aud_core_clk_en = 0;
else if (swrm->aud_core_clk_en == 0)
- clk_disable_unprepare(
+ hw_vote_rsc_disable(
swrm->lpass_core_audio);
}
}
@@ -3319,6 +3320,8 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data)
swrm_device_down(&pdev->dev);
mutex_lock(&swrm->devlock);
swrm->dev_up = false;
+ swrm->hw_core_clk_en = 0;
+ swrm->aud_core_clk_en = 0;
mutex_unlock(&swrm->devlock);
mutex_lock(&swrm->reslock);
swrm->state = SWR_MSTR_SSR;