diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c index 9167088f0922..9934a86525db 100644 --- a/asoc/codecs/bolero/rx-macro.c +++ b/asoc/codecs/bolero/rx-macro.c @@ -1236,6 +1236,7 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv, rx_priv->default_clk_id, rx_priv->clk_id, true); + rx_macro_core_vote(rx_priv, false); if (ret < 0) { dev_err(rx_priv->dev, "%s: rx request clock enable failed\n", @@ -1290,6 +1291,7 @@ static int rx_macro_mclk_enable(struct rx_macro_priv *rx_priv, rx_priv->default_clk_id, rx_priv->clk_id, false); + rx_macro_core_vote(rx_priv, false); rx_priv->clk_id = rx_priv->default_clk_id; } } @@ -1409,11 +1411,11 @@ static int rx_macro_event_handler(struct snd_soc_component *component, "%s, failed to enable clk, ret:%d\n", __func__, ret); } else { - rx_macro_core_vote(rx_priv, true); bolero_clk_rsc_request_clock(rx_priv->dev, rx_priv->default_clk_id, RX_CORE_CLK, false); } + rx_macro_core_vote(rx_priv, false); break; case BOLERO_MACRO_EVT_SSR_UP: trace_printk("%s, enter SSR up\n", __func__); @@ -3678,22 +3680,25 @@ static const struct snd_soc_dapm_route rx_audio_map[] = { static int rx_macro_core_vote(void *handle, bool enable) { + int rc = 0; struct rx_macro_priv *rx_priv = (struct rx_macro_priv *) handle; if (rx_priv == NULL) { pr_err("%s: rx priv data is NULL\n", __func__); return -EINVAL; } + if (enable) { pm_runtime_get_sync(rx_priv->dev); + if (bolero_check_core_votes(rx_priv->dev)) + rc = 0; + else + rc = -ENOTSYNC; + } else { pm_runtime_put_autosuspend(rx_priv->dev); pm_runtime_mark_last_busy(rx_priv->dev); } - - if (bolero_check_core_votes(rx_priv->dev)) - return 0; - else - return -EINVAL; + return rc; } static int rx_swrm_clock(void *handle, bool enable) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index e28656707dc8..bd04e85b507f 100644 --- a/asoc/codecs/bolero/tx-macro.c +++ b/asoc/codecs/bolero/tx-macro.c @@ -2678,22 +2678,25 @@ static int tx_macro_clk_switch(struct snd_soc_component *component, int clk_src) static int tx_macro_core_vote(void *handle, bool enable) { + int rc = 0; struct tx_macro_priv *tx_priv = (struct tx_macro_priv *) handle; if (tx_priv == NULL) { pr_err("%s: tx priv data is NULL\n", __func__); return -EINVAL; } + if (enable) { pm_runtime_get_sync(tx_priv->dev); + if (bolero_check_core_votes(tx_priv->dev)) + rc = 0; + else + rc = -ENOTSYNC; + } else { pm_runtime_put_autosuspend(tx_priv->dev); pm_runtime_mark_last_busy(tx_priv->dev); } - - if (bolero_check_core_votes(tx_priv->dev)) - return 0; - else - return -EINVAL; + return rc; } static int tx_macro_swrm_clock(void *handle, bool enable) diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 421d48e83a78..2b989b1f2792 100644 --- a/asoc/codecs/bolero/va-macro.c +++ b/asoc/codecs/bolero/va-macro.c @@ -672,22 +672,25 @@ done: static int va_macro_core_vote(void *handle, bool enable) { + int rc = 0; struct va_macro_priv *va_priv = (struct va_macro_priv *) handle; if (va_priv == NULL) { pr_err("%s: va priv data is NULL\n", __func__); return -EINVAL; } + if (enable) { pm_runtime_get_sync(va_priv->dev); + if (bolero_check_core_votes(va_priv->dev)) + rc = 0; + else + rc = -ENOTSYNC; + } else { pm_runtime_put_autosuspend(va_priv->dev); pm_runtime_mark_last_busy(va_priv->dev); } - - if (bolero_check_core_votes(va_priv->dev)) - return 0; - else - return -EINVAL; + return rc; } static int va_macro_swrm_clock(void *handle, bool enable) diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c index 73fa8f7d8c6e..b70599b4861d 100644 --- a/asoc/codecs/bolero/wsa-macro.c +++ b/asoc/codecs/bolero/wsa-macro.c @@ -2830,22 +2830,25 @@ static void wsa_macro_init_reg(struct snd_soc_component *component) static int wsa_macro_core_vote(void *handle, bool enable) { + int rc = 0; struct wsa_macro_priv *wsa_priv = (struct wsa_macro_priv *) handle; if (wsa_priv == NULL) { pr_err("%s: wsa priv data is NULL\n", __func__); return -EINVAL; } + if (enable) { pm_runtime_get_sync(wsa_priv->dev); + if (bolero_check_core_votes(wsa_priv->dev)) + rc = 0; + else + rc = -ENOTSYNC; + } else { pm_runtime_put_autosuspend(wsa_priv->dev); pm_runtime_mark_last_busy(wsa_priv->dev); } - - if (bolero_check_core_votes(wsa_priv->dev)) - return 0; - else - return -EINVAL; + return rc; } static int wsa_swrm_clock(void *handle, bool enable) diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c index 12c23bb455b2..fdaf4acfdc56 100644 --- a/soc/swr-mstr-ctrl.c +++ b/soc/swr-mstr-ctrl.c @@ -457,7 +457,7 @@ static int swrm_get_ssp_period(struct swr_mstr_ctrl *swrm, return ((swrm->bus_clk * 2) / ((row * col) * frame_sync)); } -static int swrm_core_vote_request(struct swr_mstr_ctrl *swrm) +static int swrm_core_vote_request(struct swr_mstr_ctrl *swrm, bool enable) { int ret = 0; @@ -470,7 +470,7 @@ static int swrm_core_vote_request(struct swr_mstr_ctrl *swrm) goto exit; } if (swrm->core_vote) { - ret = swrm->core_vote(swrm->handle, true); + ret = swrm->core_vote(swrm->handle, enable); if (ret) dev_err_ratelimited(swrm->dev, "%s: core vote request failed\n", __func__); @@ -501,8 +501,10 @@ static int swrm_clk_request(struct swr_mstr_ctrl *swrm, bool enable) dev_err_ratelimited(swrm->dev, "%s: core vote request failed\n", __func__); + swrm->core_vote(swrm->handle, false); goto exit; } + ret = swrm->core_vote(swrm->handle, false); } } swrm->clk_ref_count++; @@ -538,6 +540,7 @@ static int swrm_ahb_write(struct swr_mstr_ctrl *swrm, { u32 temp = (u32)(*value); int ret = 0; + int vote_ret = 0; mutex_lock(&swrm->devlock); if (!swrm->dev_up) @@ -551,13 +554,20 @@ static int swrm_ahb_write(struct swr_mstr_ctrl *swrm, __func__); goto err; } - } else if (swrm_core_vote_request(swrm)) { - goto err; + } else { + vote_ret = swrm_core_vote_request(swrm, true); + if (vote_ret == -ENOTSYNC) + goto err_vote; + else if (vote_ret) + goto err; } iowrite32(temp, swrm->swrm_dig_base + reg); if (is_swr_clk_needed(swrm)) swrm_clk_request(swrm, FALSE); +err_vote: + if (!is_swr_clk_needed(swrm)) + swrm_core_vote_request(swrm, false); err: mutex_unlock(&swrm->devlock); return ret; @@ -568,6 +578,7 @@ static int swrm_ahb_read(struct swr_mstr_ctrl *swrm, { u32 temp = 0; int ret = 0; + int vote_ret = 0; mutex_lock(&swrm->devlock); if (!swrm->dev_up) @@ -580,14 +591,21 @@ static int swrm_ahb_read(struct swr_mstr_ctrl *swrm, __func__); goto err; } - } else if (swrm_core_vote_request(swrm)) { - goto err; + } else { + vote_ret = swrm_core_vote_request(swrm, true); + if (vote_ret == -ENOTSYNC) + goto err_vote; + else if (vote_ret) + goto err; } temp = ioread32(swrm->swrm_dig_base + reg); *value = temp; if (is_swr_clk_needed(swrm)) swrm_clk_request(swrm, FALSE); +err_vote: + if (!is_swr_clk_needed(swrm)) + swrm_core_vote_request(swrm, false); err: mutex_unlock(&swrm->devlock); return ret; @@ -2583,6 +2601,7 @@ static int swrm_probe(struct platform_device *pdev) int ret = 0; struct clk *lpass_core_hw_vote = NULL; struct clk *lpass_core_audio = NULL; + u32 swrm_hw_ver = 0; /* Allocate soundwire master driver structure */ swrm = devm_kzalloc(&pdev->dev, sizeof(struct swr_mstr_ctrl), @@ -2609,6 +2628,14 @@ static int swrm_probe(struct platform_device *pdev) ret = -EINVAL; goto err_pdata_fail; } + ret = of_property_read_u32(pdev->dev.of_node, + "qcom,swr-master-version", + &swrm->version); + if (ret) { + dev_dbg(&pdev->dev, "%s: swrm version not defined, use default\n", + __func__); + swrm->version = SWRM_VERSION_1_6; + } ret = of_property_read_u32(pdev->dev.of_node, "qcom,swr_master_id", &swrm->master_id); if (ret) { @@ -2854,7 +2881,11 @@ static int swrm_probe(struct platform_device *pdev) swr_master_add_boarddevices(&swrm->master); mutex_lock(&swrm->mlock); swrm_clk_request(swrm, true); - swrm->version = swr_master_read(swrm, SWRM_COMP_HW_VERSION); + swrm_hw_ver = swr_master_read(swrm, SWRM_COMP_HW_VERSION); + if (swrm->version != swrm_hw_ver) + dev_info(&pdev->dev, + "%s: version specified in dtsi: 0x%x not match with HW read version 0x%x\n", + __func__, swrm->version, swrm_hw_ver); swrm->rd_fifo_depth = ((swr_master_read(swrm, SWRM_COMP_PARAMS) & SWRM_COMP_PARAMS_RD_FIFO_DEPTH) >> 15); swrm->wr_fifo_depth = ((swr_master_read(swrm, SWRM_COMP_PARAMS)