Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cf3b406a authored by Sudheer Papothi's avatar Sudheer Papothi Committed by Gerrit - the friendly Code Review server
Browse files

ASoC: bolero: Fix issue in clock sequence during VA concurrency



Fix issue in clock sequence when switching between VA clock to
TX clock and viceversa during VA usecase.

Change-Id: I4a7d423916b70b4b3c54d0d9a28b8ea874584525
Signed-off-by: default avatarSudheer Papothi <spapothi@codeaurora.org>
parent f53186de
Loading
Loading
Loading
Loading
+104 −87
Original line number Diff line number Diff line
@@ -159,7 +159,8 @@ struct tx_macro_priv {
	int child_count;
	int tx_swr_clk_cnt;
	int va_swr_clk_cnt;
	int swr_clk_type;
	int va_clk_status;
	int tx_clk_status;
};

static bool tx_macro_get_data(struct snd_soc_component *component,
@@ -1477,7 +1478,7 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv,
		(enable ? "enable" : "disable"), tx_priv->tx_mclk_users);

	if (enable) {
		if (tx_priv->swr_clk_users == 0) {
		if (tx_priv->swr_clk_users == 0)
			msm_cdc_pinctrl_select_active_state(
						tx_priv->tx_swr_gpio_p);

@@ -1488,6 +1489,7 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv,
		if (clk_type == TX_MCLK) {
			ret = tx_macro_mclk_enable(tx_priv, 1);
			if (ret < 0) {
				if (tx_priv->swr_clk_users == 0)
					msm_cdc_pinctrl_select_sleep_state(
							tx_priv->tx_swr_gpio_p);
				dev_err_ratelimited(tx_priv->dev,
@@ -1502,6 +1504,7 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv,
							   VA_CORE_CLK,
							   true);
			if (ret < 0) {
				if (tx_priv->swr_clk_users == 0)
					msm_cdc_pinctrl_select_sleep_state(
							tx_priv->tx_swr_gpio_p);
				dev_err_ratelimited(tx_priv->dev,
@@ -1521,6 +1524,7 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv,
					0x01, 0x01);
			}
		}
		if (tx_priv->swr_clk_users == 0) {
			dev_dbg(tx_priv->dev, "%s: reset_swr: %d\n",
				__func__, tx_priv->reset_swr);
			if (tx_priv->reset_swr)
@@ -1534,12 +1538,12 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv,
				regmap_update_bits(regmap,
					BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL,
					0x02, 0x00);
			tx_priv->reset_swr = false;
		}
		ret = bolero_clk_rsc_request_clock(tx_priv->dev,
						   TX_CORE_CLK,
						   TX_CORE_CLK,
						   false);
			tx_priv->reset_swr = false;
		}
		tx_priv->swr_clk_users++;
	} else {
		if (tx_priv->swr_clk_users <= 0) {
@@ -1548,12 +1552,12 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv,
			tx_priv->swr_clk_users = 0;
			return 0;
		}
		tx_priv->swr_clk_users--;
		if (tx_priv->swr_clk_users == 0) {
		ret = bolero_clk_rsc_request_clock(tx_priv->dev,
						   TX_CORE_CLK,
						   TX_CORE_CLK,
						   true);
		tx_priv->swr_clk_users--;
		if (tx_priv->swr_clk_users == 0)
			regmap_update_bits(regmap,
				BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL,
				0x01, 0x00);
@@ -1583,10 +1587,10 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv,
						   TX_CORE_CLK,
						   TX_CORE_CLK,
						   false);
		if (tx_priv->swr_clk_users == 0)
			msm_cdc_pinctrl_select_sleep_state(
						tx_priv->tx_swr_gpio_p);
	}
	}
	return 0;

done:
@@ -1609,53 +1613,66 @@ static int tx_macro_swrm_clock(void *handle, bool enable)
	}

	mutex_lock(&tx_priv->swr_clk_lock);
	dev_dbg(tx_priv->dev, "%s: swrm clock %s\n",
		__func__, (enable ? "enable" : "disable"));
	dev_dbg(tx_priv->dev,
		"%s: swrm clock %s tx_swr_clk_cnt: %d va_swr_clk_cnt: %d\n",
		__func__, (enable ? "enable" : "disable"),
		tx_priv->tx_swr_clk_cnt, tx_priv->va_swr_clk_cnt);

	if (enable) {
		pm_runtime_get_sync(tx_priv->dev);
		/*For standalone VA usecase, enable VA macro clock */
		if (tx_priv->va_swr_clk_cnt && !tx_priv->tx_swr_clk_cnt
			&& (tx_priv->swr_clk_type == TX_MCLK)) {
		if (tx_priv->va_swr_clk_cnt && !tx_priv->tx_swr_clk_cnt) {
			ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
							VA_MCLK, enable);
			if (ret)
				goto done;
			tx_priv->swr_clk_type = VA_MCLK;
			tx_priv->va_clk_status++;
		} else {
			/* Disable VA MCLK if its already enabled */
			if (tx_priv->swr_clk_type == VA_MCLK)
				tx_macro_tx_va_mclk_enable(tx_priv,
							regmap, VA_MCLK, false);
			ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
							TX_MCLK, enable);
			if (ret)
				goto done;
			tx_priv->swr_clk_type = TX_MCLK;
			tx_priv->tx_clk_status++;
		}
		pm_runtime_mark_last_busy(tx_priv->dev);
		pm_runtime_put_autosuspend(tx_priv->dev);
	} else {
		if (tx_priv->swr_clk_type == VA_MCLK) {
		if (tx_priv->va_clk_status && !tx_priv->tx_clk_status) {
			ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
							VA_MCLK, enable);
			if (ret)
				goto done;
			--tx_priv->va_clk_status;
		} else if (!tx_priv->va_clk_status && tx_priv->tx_clk_status) {
			ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
							TX_MCLK, enable);
			if (ret)
				goto done;
			--tx_priv->tx_clk_status;
		} else if (tx_priv->va_clk_status && tx_priv->tx_clk_status) {
			if (!tx_priv->va_swr_clk_cnt && tx_priv->tx_swr_clk_cnt) {
				ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
								VA_MCLK, enable);
				if (ret)
					goto done;
			tx_priv->swr_clk_type = TX_MCLK;
				--tx_priv->va_clk_status;
			} else {
				ret = tx_macro_tx_va_mclk_enable(tx_priv, regmap,
								TX_MCLK, enable);
			if (tx_priv->va_swr_clk_cnt) {
				ret = tx_macro_tx_va_mclk_enable(tx_priv,
						regmap, VA_MCLK, true);
				if (ret)
					goto done;
				tx_priv->swr_clk_type = VA_MCLK;
				--tx_priv->tx_clk_status;
			}

		} else {
			dev_dbg(tx_priv->dev,
				"%s: Both clocks are disabled\n", __func__);
		}
	}
	dev_dbg(tx_priv->dev, "%s: swrm clock users %d\n",
		__func__, tx_priv->swr_clk_users);

	dev_dbg(tx_priv->dev,
		"%s: swrm clock users %d tx_clk_sts_cnt: %d va_clk_sts_cnt: %d\n",
		__func__, tx_priv->swr_clk_users, tx_priv->tx_clk_status,
		tx_priv->va_clk_status);
done:
	mutex_unlock(&tx_priv->swr_clk_lock);
	return ret;