Browse Source

asoc: codecs: bolero: vote for LPASS NPA resource

Updates for voting for LPASS island NPA resource while
access any LPASS registers.

Change-Id: Ibcebd2d6ef368f309594689335bc07a36eafeaf0
Signed-off-by: Mangesh Kunchamwar <[email protected]>
Mangesh Kunchamwar 6 years ago
parent
commit
920015ceb8

+ 59 - 0
asoc/codecs/bolero/bolero-cdc.c

@@ -18,7 +18,9 @@
 #include <linux/printk.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
+#include <linux/clk.h>
 #include <soc/snd_event.h>
+#include <linux/pm_runtime.h>
 #include "bolero-cdc.h"
 #include "internal.h"
 
@@ -30,6 +32,9 @@
 
 static struct snd_soc_codec_driver bolero;
 
+/* pm runtime auto suspend timer in msecs */
+#define BOLERO_AUTO_SUSPEND_DELAY          1500 /* delay in msec */
+
 /* MCLK_MUX table for all macros */
 static u16 bolero_mclk_mux_tbl[MAX_MACRO][MCLK_MUX_MAX] = {
 	{TX_MACRO, VA_MACRO},
@@ -67,6 +72,8 @@ static int __bolero_reg_read(struct bolero_priv *priv,
 			"%s: SSR in progress, exit\n", __func__);
 		goto err;
 	}
+
+	pm_runtime_get_sync(priv->macro_params[VA_MACRO].dev);
 	current_mclk_mux_macro =
 		priv->current_mclk_mux_macro[macro_id];
 	if (!priv->macro_params[current_mclk_mux_macro].mclk_fn) {
@@ -88,6 +95,8 @@ static int __bolero_reg_read(struct bolero_priv *priv,
 	priv->macro_params[current_mclk_mux_macro].mclk_fn(
 			priv->macro_params[current_mclk_mux_macro].dev, false);
 err:
+	pm_runtime_mark_last_busy(priv->macro_params[VA_MACRO].dev);
+	pm_runtime_put_autosuspend(priv->macro_params[VA_MACRO].dev);
 	mutex_unlock(&priv->clk_lock);
 	return ret;
 }
@@ -104,6 +113,7 @@ static int __bolero_reg_write(struct bolero_priv *priv,
 			"%s: SSR in progress, exit\n", __func__);
 		goto err;
 	}
+	ret = pm_runtime_get_sync(priv->macro_params[VA_MACRO].dev);
 	current_mclk_mux_macro =
 		priv->current_mclk_mux_macro[macro_id];
 	if (!priv->macro_params[current_mclk_mux_macro].mclk_fn) {
@@ -125,6 +135,8 @@ static int __bolero_reg_write(struct bolero_priv *priv,
 	priv->macro_params[current_mclk_mux_macro].mclk_fn(
 			priv->macro_params[current_mclk_mux_macro].dev, false);
 err:
+	pm_runtime_mark_last_busy(priv->macro_params[VA_MACRO].dev);
+	pm_runtime_put_autosuspend(priv->macro_params[VA_MACRO].dev);
 	mutex_unlock(&priv->clk_lock);
 	return ret;
 }
@@ -850,6 +862,7 @@ static int bolero_probe(struct platform_device *pdev)
 	struct bolero_priv *priv;
 	u32 num_macros = 0;
 	int ret;
+	struct clk *lpass_npa_rsc_island = NULL;
 
 	priv = devm_kzalloc(&pdev->dev, sizeof(struct bolero_priv),
 			    GFP_KERNEL);
@@ -898,6 +911,17 @@ static int bolero_probe(struct platform_device *pdev)
 		  bolero_add_child_devices);
 	schedule_work(&priv->bolero_add_child_devices_work);
 
+	/* Register LPASS NPA resource */
+	lpass_npa_rsc_island = devm_clk_get(&pdev->dev, "island_lpass_npa_rsc");
+	if (IS_ERR(lpass_npa_rsc_island)) {
+		ret = PTR_ERR(lpass_npa_rsc_island);
+		dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n",
+			__func__, "island_lpass_npa_rsc", ret);
+		lpass_npa_rsc_island = NULL;
+		ret = 0;
+	}
+	priv->lpass_npa_rsc_island = lpass_npa_rsc_island;
+
 	return 0;
 }
 
@@ -914,6 +938,41 @@ static int bolero_remove(struct platform_device *pdev)
 	return 0;
 }
 
+int bolero_runtime_resume(struct device *dev)
+{
+	struct bolero_priv *priv = dev_get_drvdata(dev->parent);
+	int ret = 0;
+
+	if (priv->lpass_npa_rsc_island == NULL) {
+		dev_dbg(dev, "%s: Invalid lpass npa rsc node\n", __func__);
+		return 0;
+	}
+
+	ret = clk_prepare_enable(priv->lpass_npa_rsc_island);
+	if (ret < 0)
+		dev_err(dev, "%s:lpass npa rsc island enable failed\n",
+			__func__);
+
+	pm_runtime_set_autosuspend_delay(priv->dev, BOLERO_AUTO_SUSPEND_DELAY);
+	return 0;
+}
+EXPORT_SYMBOL(bolero_runtime_resume);
+
+int bolero_runtime_suspend(struct device *dev)
+{
+	struct bolero_priv *priv = dev_get_drvdata(dev->parent);
+
+	mutex_lock(&priv->clk_lock);
+	if (priv->lpass_npa_rsc_island != NULL)
+		clk_disable_unprepare(priv->lpass_npa_rsc_island);
+	else
+		dev_dbg(dev, "%s: Invalid lpass npa rsc node\n",
+			__func__);
+	mutex_unlock(&priv->clk_lock);
+	return 0;
+}
+EXPORT_SYMBOL(bolero_runtime_suspend);
+
 static const struct of_device_id bolero_dt_match[] = {
 	{.compatible = "qcom,bolero-codec"},
 	{}

+ 7 - 0
asoc/codecs/bolero/bolero-cdc.h

@@ -75,6 +75,8 @@ int bolero_info_create_codec_entry(
 		struct snd_soc_codec *codec);
 int bolero_register_wake_irq(struct snd_soc_codec *codec, u32 data);
 void bolero_clear_amic_tx_hold(struct device *dev, u16 adc_n);
+int bolero_runtime_resume(struct device *dev);
+int bolero_runtime_suspend(struct device *dev);
 #else
 static inline int bolero_register_macro(struct device *dev,
 					u16 macro_id,
@@ -113,6 +115,11 @@ static inline void bolero_clear_amic_tx_hold(struct device *dev, u16 adc_n)
 
 static inline int bolero_register_wake_irq(struct snd_soc_codec *codec,
 					   u32 data)
+static inline int bolero_runtime_resume(struct device *dev)
+{
+	return 0;
+}
+static int bolero_runtime_suspend(struct device *dev)
 {
 	return 0;
 }

+ 1 - 0
asoc/codecs/bolero/internal.h

@@ -64,6 +64,7 @@ struct bolero_priv {
 	u16 current_mclk_mux_macro[MAX_MACRO];
 	struct work_struct bolero_add_child_devices_work;
 	u32 version;
+	struct clk *lpass_npa_rsc_island;
 
 	/* Entry for version info */
 	struct snd_info_entry *entry;

+ 18 - 1
asoc/codecs/bolero/va-macro.c

@@ -20,9 +20,12 @@
 #include <sound/soc.h>
 #include <sound/soc-dapm.h>
 #include <sound/tlv.h>
+#include <linux/pm_runtime.h>
 #include "bolero-cdc.h"
 #include "bolero-cdc-registers.h"
 
+/* pm runtime auto suspend timer in msecs */
+#define VA_AUTO_SUSPEND_DELAY          1500 /* delay in msec */
 #define VA_MACRO_MAX_OFFSET 0x1000
 
 #define VA_MACRO_NUM_DECIMATORS 8
@@ -1617,6 +1620,10 @@ static int va_macro_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "%s: register macro failed\n", __func__);
 		goto reg_macro_fail;
 	}
+	pm_runtime_set_autosuspend_delay(&pdev->dev, VA_AUTO_SUSPEND_DELAY);
+	pm_runtime_use_autosuspend(&pdev->dev);
+	pm_runtime_set_suspended(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
 	return ret;
 
 reg_macro_fail:
@@ -1632,7 +1639,8 @@ static int va_macro_remove(struct platform_device *pdev)
 
 	if (!va_priv)
 		return -EINVAL;
-
+	pm_runtime_disable(&pdev->dev);
+	pm_runtime_set_suspended(&pdev->dev);
 	bolero_unregister_macro(&pdev->dev, VA_MACRO);
 	mutex_destroy(&va_priv->mclk_lock);
 	return 0;
@@ -1644,10 +1652,19 @@ static const struct of_device_id va_macro_dt_match[] = {
 	{}
 };
 
+static const struct dev_pm_ops bolero_dev_pm_ops = {
+	SET_RUNTIME_PM_OPS(
+		bolero_runtime_suspend,
+		bolero_runtime_resume,
+		NULL
+	)
+};
+
 static struct platform_driver va_macro_driver = {
 	.driver = {
 		.name = "va_macro",
 		.owner = THIS_MODULE,
+		.pm = &bolero_dev_pm_ops,
 		.of_match_table = va_macro_dt_match,
 	},
 	.probe = va_macro_probe,