Browse Source

asoc: codecs: update audio clock driver for LPASS NPA resource

Add new clock node for LPASS NPA resource for clients
to enable or disable the resource.

Change-Id: I8aa587771618d301ace72d6df1045078cdf39c9c
Signed-off-by: Mangesh Kunchamwar <[email protected]>
Mangesh Kunchamwar 6 years ago
parent
commit
912a96accb
1 changed files with 81 additions and 0 deletions
  1. 81 0
      asoc/codecs/audio-ext-clk-up.c

+ 81 - 0
asoc/codecs/audio-ext-clk-up.c

@@ -21,6 +21,7 @@
 #include <linux/platform_device.h>
 #include <dt-bindings/clock/qcom,audio-ext-clk.h>
 #include <dsp/q6afe-v2.h>
+#include <dsp/q6core.h>
 #include "audio-ext-clk-up.h"
 
 enum {
@@ -33,6 +34,7 @@ enum {
 	AUDIO_EXT_CLK_LPASS5,
 	AUDIO_EXT_CLK_LPASS6,
 	AUDIO_EXT_CLK_LPASS7,
+	AUDIO_EXT_CLK_LPASS_NPA_RSC_ISLAND,
 	AUDIO_EXT_CLK_LPASS_MAX,
 	AUDIO_EXT_CLK_MAX = AUDIO_EXT_CLK_LPASS_MAX,
 };
@@ -55,6 +57,7 @@ struct audio_ext_clk_priv {
 	struct afe_clk_set clk_cfg;
 	struct audio_ext_clk audio_clk;
 	const char *clk_name;
+	uint32_t npa_rsc_client_handle;
 };
 
 static inline struct audio_ext_clk_priv *to_audio_clk(struct clk_hw *hw)
@@ -141,12 +144,58 @@ static u8 audio_ext_clk_get_parent(struct clk_hw *hw)
 		return 0;
 }
 
+static int lpass_npa_rsc_prepare(struct clk_hw *hw)
+{
+	struct audio_ext_clk_priv *clk_priv = to_audio_clk(hw);
+	int ret;
+
+	if ((clk_priv->clk_src >= AUDIO_EXT_CLK_LPASS_NPA_RSC_ISLAND) &&
+		(clk_priv->clk_src < AUDIO_EXT_CLK_LPASS_MAX))  {
+		if (q6core_get_avcs_api_version_per_service(
+		APRV2_IDS_SERVICE_ID_ADSP_CORE_V) >= AVCS_API_VERSION_V4) {
+			ret = q6core_request_island_transition(
+				clk_priv->npa_rsc_client_handle, false);
+			if (ret < 0) {
+				pr_err("%s q6core_request_island_transition failed %d\n",
+					__func__, ret);
+				return ret;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static void lpass_npa_rsc_unprepare(struct clk_hw *hw)
+{
+	struct audio_ext_clk_priv *clk_priv = to_audio_clk(hw);
+	int ret = 0;
+
+	if ((clk_priv->clk_src >= AUDIO_EXT_CLK_LPASS_NPA_RSC_ISLAND) &&
+		(clk_priv->clk_src < AUDIO_EXT_CLK_LPASS_MAX))  {
+		if (q6core_get_avcs_api_version_per_service(
+		APRV2_IDS_SERVICE_ID_ADSP_CORE_V) >= AVCS_API_VERSION_V4) {
+			ret = q6core_request_island_transition(
+					clk_priv->npa_rsc_client_handle, true);
+			if (ret < 0) {
+				pr_err("%s q6core_request_island_transition failed %d\n",
+					__func__, ret);
+			}
+		}
+	}
+}
+
 static const struct clk_ops audio_ext_clk_ops = {
 	.prepare = audio_ext_clk_prepare,
 	.unprepare = audio_ext_clk_unprepare,
 	.get_parent = audio_ext_clk_get_parent,
 };
 
+static const struct clk_ops lpass_npa_rsc_ops = {
+	.prepare = lpass_npa_rsc_prepare,
+	.unprepare = lpass_npa_rsc_unprepare,
+};
+
 static const char * const audio_ext_pmi_div_clk[] = {
 	"qpnp_clkdiv_1",
 	"pms405_div_clk1",
@@ -274,6 +323,15 @@ static struct audio_ext_clk audio_clk_array[] = {
 			},
 		},
 	},
+	{
+		.pnctrl_info = {NULL},
+		.fact = {
+			.hw.init = &(struct clk_init_data){
+				.name = "lpass_npa_rsc_island_clk",
+				.ops = &lpass_npa_rsc_ops,
+			},
+		},
+	},
 };
 
 static int audio_get_pinctrl(struct platform_device *pdev)
@@ -476,11 +534,34 @@ static int audio_ref_clk_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_NPA_RSC_ISLAND) {
+		if (q6core_get_avcs_api_version_per_service(
+		APRV2_IDS_SERVICE_ID_ADSP_CORE_V) >= AVCS_API_VERSION_V4) {
+			ret = q6core_create_lpass_npa_client(
+				AVCS_SLEEP_NODE_ISLAND_TRANSITION_RESOURCE_ID,
+				"lpass_npa_rsc_mgr",
+				&clk_priv->npa_rsc_client_handle);
+			if (ret) {
+				dev_err(&pdev->dev, "%s: q6core_create_lpass_npa_client is failed %d\n",
+					__func__, ret);
+				audio_put_pinctrl(pdev);
+				return ret;
+			}
+		}
+	}
 	return 0;
 }
 
 static int audio_ref_clk_remove(struct platform_device *pdev)
 {
+	struct audio_ext_clk_priv *clk_priv = platform_get_drvdata(pdev);
+
+	if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_NPA_RSC_ISLAND) {
+		if (q6core_get_avcs_api_version_per_service(
+		APRV2_IDS_SERVICE_ID_ADSP_CORE_V) >= AVCS_API_VERSION_V4)
+			q6core_destroy_lpass_npa_client(
+					clk_priv->npa_rsc_client_handle);
+	}
 	audio_put_pinctrl(pdev);
 
 	return 0;