Merge "msm: vote for LPASS core while access LPASS registers"
このコミットが含まれているのは:

committed by
Gerrit - the friendly Code Review server

コミット
8fd4a210ab
@@ -1,5 +1,5 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
@@ -14,7 +14,6 @@
|
||||
#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 {
|
||||
@@ -27,7 +26,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_CORE_HW_VOTE,
|
||||
AUDIO_EXT_CLK_LPASS_MAX,
|
||||
AUDIO_EXT_CLK_EXTERNAL_PLL = AUDIO_EXT_CLK_LPASS_MAX,
|
||||
AUDIO_EXT_CLK_MAX,
|
||||
@@ -51,7 +50,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;
|
||||
uint32_t lpass_core_hwvote_client_handle;
|
||||
};
|
||||
|
||||
static inline struct audio_ext_clk_priv *to_audio_clk(struct clk_hw *hw)
|
||||
@@ -138,43 +137,37 @@ static u8 audio_ext_clk_get_parent(struct clk_hw *hw)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lpass_npa_rsc_prepare(struct clk_hw *hw)
|
||||
static int lpass_hw_vote_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;
|
||||
}
|
||||
if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_CORE_HW_VOTE) {
|
||||
ret = afe_vote_lpass_core_hw(AFE_LPASS_CORE_HW_MACRO_BLOCK,
|
||||
"LPASS_HW_MACRO",
|
||||
&clk_priv->lpass_core_hwvote_client_handle);
|
||||
if (ret < 0) {
|
||||
pr_err("%s lpass core hw vote failed %d\n",
|
||||
__func__, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lpass_npa_rsc_unprepare(struct clk_hw *hw)
|
||||
static void lpass_hw_vote_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);
|
||||
}
|
||||
if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_CORE_HW_VOTE) {
|
||||
ret = afe_unvote_lpass_core_hw(
|
||||
AFE_LPASS_CORE_HW_MACRO_BLOCK,
|
||||
clk_priv->lpass_core_hwvote_client_handle);
|
||||
if (ret < 0) {
|
||||
pr_err("%s lpass core hw vote failed %d\n",
|
||||
__func__, ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -185,9 +178,9 @@ static const struct clk_ops audio_ext_clk_ops = {
|
||||
.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 struct clk_ops lpass_hw_vote_ops = {
|
||||
.prepare = lpass_hw_vote_prepare,
|
||||
.unprepare = lpass_hw_vote_unprepare,
|
||||
};
|
||||
|
||||
static const char * const audio_ext_pmi_div_clk[] = {
|
||||
@@ -322,8 +315,8 @@ 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,
|
||||
.name = "lpass_hw_vote_clk",
|
||||
.ops = &lpass_hw_vote_ops,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -539,35 +532,11 @@ static int audio_ref_clk_probe(struct platform_device *pdev)
|
||||
audio_put_pinctrl(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;
|
||||
|
@@ -949,7 +949,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;
|
||||
struct clk *lpass_core_hw_vote = NULL;
|
||||
|
||||
priv = devm_kzalloc(&pdev->dev, sizeof(struct bolero_priv),
|
||||
GFP_KERNEL);
|
||||
@@ -998,16 +998,16 @@ 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);
|
||||
/* Register LPASS core hw vote */
|
||||
lpass_core_hw_vote = devm_clk_get(&pdev->dev, "lpass_core_hw_vote");
|
||||
if (IS_ERR(lpass_core_hw_vote)) {
|
||||
ret = PTR_ERR(lpass_core_hw_vote);
|
||||
dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n",
|
||||
__func__, "island_lpass_npa_rsc", ret);
|
||||
lpass_npa_rsc_island = NULL;
|
||||
__func__, "lpass_core_hw_vote", ret);
|
||||
lpass_core_hw_vote = NULL;
|
||||
ret = 0;
|
||||
}
|
||||
priv->lpass_npa_rsc_island = lpass_npa_rsc_island;
|
||||
priv->lpass_core_hw_vote = lpass_core_hw_vote;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1030,14 +1030,14 @@ 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__);
|
||||
if (priv->lpass_core_hw_vote == NULL) {
|
||||
dev_dbg(dev, "%s: Invalid lpass core hw node\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(priv->lpass_npa_rsc_island);
|
||||
ret = clk_prepare_enable(priv->lpass_core_hw_vote);
|
||||
if (ret < 0)
|
||||
dev_err(dev, "%s:lpass npa rsc island enable failed\n",
|
||||
dev_err(dev, "%s:lpass core hw enable failed\n",
|
||||
__func__);
|
||||
|
||||
pm_runtime_set_autosuspend_delay(priv->dev, BOLERO_AUTO_SUSPEND_DELAY);
|
||||
@@ -1050,10 +1050,10 @@ 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);
|
||||
if (priv->lpass_core_hw_vote != NULL)
|
||||
clk_disable_unprepare(priv->lpass_core_hw_vote);
|
||||
else
|
||||
dev_dbg(dev, "%s: Invalid lpass npa rsc node\n",
|
||||
dev_dbg(dev, "%s: Invalid lpass core hw node\n",
|
||||
__func__);
|
||||
mutex_unlock(&priv->clk_lock);
|
||||
return 0;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _BOLERO_INTERNAL_H
|
||||
@@ -57,7 +57,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;
|
||||
struct clk *lpass_core_hw_vote;
|
||||
|
||||
/* Entry for version info */
|
||||
struct snd_info_entry *entry;
|
||||
|
177
dsp/q6afe.c
177
dsp/q6afe.c
@@ -92,6 +92,9 @@ struct afe_ctl {
|
||||
atomic_t status;
|
||||
wait_queue_head_t wait[AFE_MAX_PORTS];
|
||||
wait_queue_head_t wait_wakeup;
|
||||
struct task_struct *task;
|
||||
wait_queue_head_t lpass_core_hw_wait;
|
||||
uint32_t lpass_hw_core_client_hdl;
|
||||
void (*tx_cb)(uint32_t opcode,
|
||||
uint32_t token, uint32_t *payload, void *priv);
|
||||
void (*rx_cb)(uint32_t opcode,
|
||||
@@ -555,6 +558,16 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
|
||||
return -EINVAL;
|
||||
} else if (data->opcode == AFE_EVENT_MBHC_DETECTION_SW_WA) {
|
||||
msm_aud_evt_notifier_call_chain(SWR_WAKE_IRQ_EVENT, NULL);
|
||||
} else if (data->opcode ==
|
||||
AFE_CMD_RSP_REMOTE_LPASS_CORE_HW_VOTE_REQUEST) {
|
||||
uint32_t *payload = data->payload;
|
||||
|
||||
pr_debug("%s: AFE_CMD_RSP_REMOTE_LPASS_CORE_HW_VOTE_REQUEST handle %d\n",
|
||||
__func__, payload[0]);
|
||||
this_afe.lpass_hw_core_client_hdl = payload[0];
|
||||
atomic_set(&this_afe.state, 0);
|
||||
atomic_set(&this_afe.status, 0);
|
||||
wake_up(&this_afe.lpass_core_hw_wait);
|
||||
} else if (data->payload_size) {
|
||||
uint32_t *payload;
|
||||
uint16_t port_id = 0;
|
||||
@@ -635,6 +648,11 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
|
||||
else
|
||||
return -EINVAL;
|
||||
break;
|
||||
case AFE_CMD_REMOTE_LPASS_CORE_HW_VOTE_REQUEST:
|
||||
case AFE_CMD_REMOTE_LPASS_CORE_HW_DEVOTE_REQUEST:
|
||||
atomic_set(&this_afe.state, 0);
|
||||
wake_up(&this_afe.lpass_core_hw_wait);
|
||||
break;
|
||||
case AFE_SVC_CMD_EVENT_CFG:
|
||||
atomic_set(&this_afe.state, payload[1]);
|
||||
wake_up(&this_afe.wait_wakeup);
|
||||
@@ -8427,6 +8445,7 @@ int __init afe_init(void)
|
||||
init_waitqueue_head(&this_afe.wait[i]);
|
||||
}
|
||||
init_waitqueue_head(&this_afe.wait_wakeup);
|
||||
init_waitqueue_head(&this_afe.lpass_core_hw_wait);
|
||||
wakeup_source_init(&wl.ws, "spkr-prot");
|
||||
ret = afe_init_cal_data();
|
||||
if (ret)
|
||||
@@ -8498,3 +8517,161 @@ int afe_cal_init_hwdep(void *card)
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(afe_cal_init_hwdep);
|
||||
|
||||
/*
|
||||
* afe_vote_lpass_core_hw -
|
||||
* Voting for lpass core hardware
|
||||
*
|
||||
* @hw_block_id: id of the hardware block
|
||||
* @client_name: client name
|
||||
* @client_handle: client handle
|
||||
*
|
||||
*/
|
||||
int afe_vote_lpass_core_hw(uint32_t hw_block_id, char *client_name,
|
||||
uint32_t *client_handle)
|
||||
{
|
||||
struct afe_cmd_remote_lpass_core_hw_vote_request hw_vote_cfg;
|
||||
struct afe_cmd_remote_lpass_core_hw_vote_request *cmd_ptr =
|
||||
&hw_vote_cfg;
|
||||
int ret = 0;
|
||||
|
||||
if (!client_handle) {
|
||||
pr_err("%s: Invalid client_handle\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!client_name) {
|
||||
pr_err("%s: Invalid client_name\n", __func__);
|
||||
*client_handle = 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&this_afe.afe_cmd_lock);
|
||||
|
||||
memset(cmd_ptr, 0, sizeof(hw_vote_cfg));
|
||||
|
||||
cmd_ptr->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
|
||||
APR_HDR_LEN(APR_HDR_SIZE),
|
||||
APR_PKT_VER);
|
||||
cmd_ptr->hdr.pkt_size = sizeof(hw_vote_cfg);
|
||||
cmd_ptr->hdr.src_port = 0;
|
||||
cmd_ptr->hdr.dest_port = 0;
|
||||
cmd_ptr->hdr.token = 0;
|
||||
cmd_ptr->hdr.opcode = AFE_CMD_REMOTE_LPASS_CORE_HW_VOTE_REQUEST;
|
||||
cmd_ptr->hw_block_id = hw_block_id;
|
||||
strlcpy(cmd_ptr->client_name, client_name,
|
||||
sizeof(cmd_ptr->client_name));
|
||||
|
||||
pr_debug("%s: lpass core hw vote opcode[0x%x] hw id[0x%x]\n",
|
||||
__func__, cmd_ptr->hdr.opcode, cmd_ptr->hw_block_id);
|
||||
|
||||
*client_handle = 0;
|
||||
atomic_set(&this_afe.status, 0);
|
||||
atomic_set(&this_afe.state, 1);
|
||||
ret = apr_send_pkt(this_afe.apr, (uint32_t *) cmd_ptr);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: lpass core hw vote failed %d\n",
|
||||
__func__, ret);
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = wait_event_timeout(this_afe.lpass_core_hw_wait,
|
||||
(atomic_read(&this_afe.state) == 0),
|
||||
msecs_to_jiffies(TIMEOUT_MS));
|
||||
if (!ret) {
|
||||
pr_err("%s: timeout. waited for lpass core hw vote\n",
|
||||
__func__);
|
||||
ret = -ETIMEDOUT;
|
||||
goto done;
|
||||
} else {
|
||||
/* set ret to 0 as no timeout happened */
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (atomic_read(&this_afe.status) > 0) {
|
||||
pr_err("%s: lpass core hw vote cmd failed [%s]\n",
|
||||
__func__, adsp_err_get_err_str(
|
||||
atomic_read(&this_afe.status)));
|
||||
ret = adsp_err_get_lnx_err_code(
|
||||
atomic_read(&this_afe.status));
|
||||
goto done;
|
||||
}
|
||||
|
||||
*client_handle = this_afe.lpass_hw_core_client_hdl;
|
||||
pr_debug("%s: lpass_hw_core_client_hdl %d\n", __func__,
|
||||
this_afe.lpass_hw_core_client_hdl);
|
||||
done:
|
||||
mutex_unlock(&this_afe.afe_cmd_lock);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(afe_vote_lpass_core_hw);
|
||||
|
||||
/*
|
||||
* afe_unvote_lpass_core_hw -
|
||||
* unvoting for lpass core hardware
|
||||
*
|
||||
* @hw_block_id: id of the hardware block
|
||||
* @client_handle: client handle
|
||||
*
|
||||
*/
|
||||
int afe_unvote_lpass_core_hw(uint32_t hw_block_id, uint32_t client_handle)
|
||||
{
|
||||
struct afe_cmd_remote_lpass_core_hw_devote_request hw_vote_cfg;
|
||||
struct afe_cmd_remote_lpass_core_hw_devote_request *cmd_ptr =
|
||||
&hw_vote_cfg;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&this_afe.afe_cmd_lock);
|
||||
|
||||
memset(cmd_ptr, 0, sizeof(hw_vote_cfg));
|
||||
|
||||
cmd_ptr->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
|
||||
APR_HDR_LEN(APR_HDR_SIZE),
|
||||
APR_PKT_VER);
|
||||
cmd_ptr->hdr.pkt_size = sizeof(hw_vote_cfg);
|
||||
cmd_ptr->hdr.src_port = 0;
|
||||
cmd_ptr->hdr.dest_port = 0;
|
||||
cmd_ptr->hdr.token = 0;
|
||||
cmd_ptr->hdr.opcode = AFE_CMD_REMOTE_LPASS_CORE_HW_DEVOTE_REQUEST;
|
||||
cmd_ptr->hw_block_id = hw_block_id;
|
||||
cmd_ptr->client_handle = client_handle;
|
||||
|
||||
pr_debug("%s: lpass core hw unvote opcode[0x%x] hw id[0x%x]\n",
|
||||
__func__, cmd_ptr->hdr.opcode, cmd_ptr->hw_block_id);
|
||||
|
||||
atomic_set(&this_afe.status, 0);
|
||||
atomic_set(&this_afe.state, 1);
|
||||
ret = apr_send_pkt(this_afe.apr, (uint32_t *) cmd_ptr);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: lpass core hw devote failed %d\n",
|
||||
__func__, ret);
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = wait_event_timeout(this_afe.lpass_core_hw_wait,
|
||||
(atomic_read(&this_afe.state) == 0),
|
||||
msecs_to_jiffies(TIMEOUT_MS));
|
||||
if (!ret) {
|
||||
pr_err("%s: timeout. waited for lpass core hw devote\n",
|
||||
__func__);
|
||||
ret = -ETIMEDOUT;
|
||||
goto done;
|
||||
} else {
|
||||
/* set ret to 0 as no timeout happened */
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (atomic_read(&this_afe.status) > 0) {
|
||||
pr_err("%s: lpass core hw devote cmd failed [%s]\n",
|
||||
__func__, adsp_err_get_err_str(
|
||||
atomic_read(&this_afe.status)));
|
||||
ret = adsp_err_get_lnx_err_code(
|
||||
atomic_read(&this_afe.status));
|
||||
}
|
||||
|
||||
done:
|
||||
mutex_unlock(&this_afe.afe_cmd_lock);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(afe_unvote_lpass_core_hw);
|
||||
|
||||
|
@@ -453,4 +453,42 @@ void afe_register_wakeup_irq_callback(
|
||||
void (*afe_cb_wakeup_irq)(void *handle));
|
||||
int afe_get_doa_tracking_mon(u16 port_id,
|
||||
struct doa_tracking_mon_param *doa_tracking_data);
|
||||
|
||||
#define AFE_LPASS_CORE_HW_BLOCK_ID_NONE 0
|
||||
#define AFE_LPASS_CORE_HW_BLOCK_ID_AVTIMER 2
|
||||
#define AFE_LPASS_CORE_HW_MACRO_BLOCK 3
|
||||
|
||||
/* Handles audio-video timer (avtimer) and BTSC vote requests from clients.
|
||||
*/
|
||||
#define AFE_CMD_REMOTE_LPASS_CORE_HW_VOTE_REQUEST 0x000100f4
|
||||
|
||||
struct afe_cmd_remote_lpass_core_hw_vote_request {
|
||||
struct apr_hdr hdr;
|
||||
uint32_t hw_block_id;
|
||||
/* ID of the hardware block. */
|
||||
char client_name[8];
|
||||
/* Name of the client. */
|
||||
} __packed;
|
||||
|
||||
#define AFE_CMD_RSP_REMOTE_LPASS_CORE_HW_VOTE_REQUEST 0x000100f5
|
||||
|
||||
struct afe_cmd_rsp_remote_lpass_core_hw_vote_request {
|
||||
uint32_t client_handle;
|
||||
/**< Handle of the client. */
|
||||
} __packed;
|
||||
|
||||
#define AFE_CMD_REMOTE_LPASS_CORE_HW_DEVOTE_REQUEST 0x000100f6
|
||||
|
||||
struct afe_cmd_remote_lpass_core_hw_devote_request {
|
||||
struct apr_hdr hdr;
|
||||
uint32_t hw_block_id;
|
||||
/**< ID of the hardware block.*/
|
||||
|
||||
uint32_t client_handle;
|
||||
/**< Handle of the client.*/
|
||||
} __packed;
|
||||
|
||||
int afe_vote_lpass_core_hw(uint32_t hw_block_id, char *client_name,
|
||||
uint32_t *client_handle);
|
||||
int afe_unvote_lpass_core_hw(uint32_t hw_block_id, uint32_t client_handle);
|
||||
#endif /* __Q6AFE_V2_H__ */
|
||||
|
@@ -108,7 +108,7 @@ struct lpi_gpio_state {
|
||||
struct pinctrl_dev *ctrl;
|
||||
struct gpio_chip chip;
|
||||
char __iomem *base;
|
||||
struct clk *lpass_npa_rsc_island;
|
||||
struct clk *lpass_core_hw_vote;
|
||||
struct mutex slew_access_lock;
|
||||
};
|
||||
|
||||
@@ -555,7 +555,7 @@ static int lpi_pinctrl_probe(struct platform_device *pdev)
|
||||
char __iomem *lpi_base;
|
||||
char __iomem *slew_base;
|
||||
u32 reg, slew_reg;
|
||||
struct clk *lpass_npa_rsc_island = NULL;
|
||||
struct clk *lpass_core_hw_vote = NULL;
|
||||
|
||||
ret = of_property_read_u32(dev->of_node, "reg", ®);
|
||||
if (ret < 0) {
|
||||
@@ -699,16 +699,16 @@ static int lpi_pinctrl_probe(struct platform_device *pdev)
|
||||
goto err_snd_evt;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
/* Register LPASS core hw vote */
|
||||
lpass_core_hw_vote = devm_clk_get(&pdev->dev, "lpass_core_hw_vote");
|
||||
if (IS_ERR(lpass_core_hw_vote)) {
|
||||
ret = PTR_ERR(lpass_core_hw_vote);
|
||||
dev_dbg(&pdev->dev, "%s: clk get %s failed %d\n",
|
||||
__func__, "island_lpass_npa_rsc", ret);
|
||||
lpass_npa_rsc_island = NULL;
|
||||
__func__, "lpass_core_hw_vote", ret);
|
||||
lpass_core_hw_vote = NULL;
|
||||
ret = 0;
|
||||
}
|
||||
state->lpass_npa_rsc_island = lpass_npa_rsc_island;
|
||||
state->lpass_core_hw_vote = lpass_core_hw_vote;
|
||||
|
||||
pm_runtime_set_autosuspend_delay(&pdev->dev, LPI_AUTO_SUSPEND_DELAY);
|
||||
pm_runtime_use_autosuspend(&pdev->dev);
|
||||
@@ -754,14 +754,14 @@ int lpi_pinctrl_runtime_resume(struct device *dev)
|
||||
struct lpi_gpio_state *state = dev_get_drvdata(dev);
|
||||
int ret = 0;
|
||||
|
||||
if (state->lpass_npa_rsc_island == NULL) {
|
||||
dev_dbg(dev, "%s: Invalid lpass npa rsc node\n", __func__);
|
||||
if (state->lpass_core_hw_vote == NULL) {
|
||||
dev_dbg(dev, "%s: Invalid core hw node\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(state->lpass_npa_rsc_island);
|
||||
ret = clk_prepare_enable(state->lpass_core_hw_vote);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "%s:lpass npa rsc island enable failed\n",
|
||||
dev_err(dev, "%s:lpass core hw island enable failed\n",
|
||||
__func__);
|
||||
}
|
||||
pm_runtime_set_autosuspend_delay(dev, LPI_AUTO_SUSPEND_DELAY);
|
||||
@@ -772,11 +772,11 @@ int lpi_pinctrl_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct lpi_gpio_state *state = dev_get_drvdata(dev);
|
||||
|
||||
if (state->lpass_npa_rsc_island == NULL) {
|
||||
dev_dbg(dev, "%s: Invalid lpass npa rsc node\n", __func__);
|
||||
if (state->lpass_core_hw_vote == NULL) {
|
||||
dev_dbg(dev, "%s: Invalid core hw node\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
clk_disable_unprepare(state->lpass_npa_rsc_island);
|
||||
clk_disable_unprepare(state->lpass_core_hw_vote);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
新しいイシューから参照
ユーザーをブロックする