ASoC: add hw_core voting via PRM module
Change-Id: Ifa070caa6e5ff0263d0d471e5f0d7e7b09a41f0d Signed-off-by: Taha Azzaoui <tazzaoui@codeaurora.org>
This commit is contained in:

committed by
Phani Kumar Uppalapati

parent
12238a5ca3
commit
8fc7957756
@@ -160,16 +160,19 @@ static u8 audio_ext_clk_get_parent(struct clk_hw *hw)
|
|||||||
|
|
||||||
static int lpass_hw_vote_prepare(struct clk_hw *hw)
|
static int lpass_hw_vote_prepare(struct clk_hw *hw)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
struct audio_ext_clk_priv *clk_priv = to_audio_clk(hw);
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
|
struct audio_ext_clk_priv *clk_priv = to_audio_clk(hw);
|
||||||
|
int ret;
|
||||||
if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_CORE_HW_VOTE) {
|
if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_CORE_HW_VOTE) {
|
||||||
trace_printk("%s: vote for %d clock\n",
|
#ifdef CONFIG_AUDIO_PRM
|
||||||
__func__, clk_priv->clk_src);
|
pr_debug("%s: clk_id %d ",__func__, clk_priv->prm_clk_cfg.clk_id);
|
||||||
|
ret = audio_prm_set_lpass_hw_core_req(&clk_priv->prm_clk_cfg,
|
||||||
|
HW_CORE_ID_LPASS, 1);
|
||||||
|
#else
|
||||||
ret = afe_vote_lpass_core_hw(AFE_LPASS_CORE_HW_MACRO_BLOCK,
|
ret = afe_vote_lpass_core_hw(AFE_LPASS_CORE_HW_MACRO_BLOCK,
|
||||||
"LPASS_HW_MACRO",
|
"LPASS_HW_MACRO",
|
||||||
&clk_priv->lpass_core_hwvote_client_handle);
|
&clk_priv->lpass_core_hwvote_client_handle);
|
||||||
|
#endif
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
pr_err("%s lpass core hw vote failed %d\n",
|
pr_err("%s lpass core hw vote failed %d\n",
|
||||||
__func__, ret);
|
__func__, ret);
|
||||||
@@ -178,33 +181,40 @@ static int lpass_hw_vote_prepare(struct clk_hw *hw)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_AUDIO_HW_VOTE) {
|
if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_AUDIO_HW_VOTE) {
|
||||||
trace_printk("%s: vote for %d clock\n",
|
#ifdef CONFIG_AUDIO_PRM
|
||||||
__func__, clk_priv->clk_src);
|
pr_debug("%s: clk_id %d ",__func__, clk_priv->prm_clk_cfg.clk_id);
|
||||||
|
ret = audio_prm_set_lpass_hw_core_req(&clk_priv->prm_clk_cfg,
|
||||||
|
HW_CORE_ID_DCODEC, 1);
|
||||||
|
#else
|
||||||
ret = afe_vote_lpass_core_hw(AFE_LPASS_CORE_HW_DCODEC_BLOCK,
|
ret = afe_vote_lpass_core_hw(AFE_LPASS_CORE_HW_DCODEC_BLOCK,
|
||||||
"LPASS_HW_DCODEC",
|
"LPASS_HW_DCODEC",
|
||||||
&clk_priv->lpass_audio_hwvote_client_handle);
|
&clk_priv->lpass_audio_hwvote_client_handle);
|
||||||
|
#endif
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
pr_err("%s lpass audio hw vote failed %d\n",
|
pr_err("%s lpass audio hw vote failed %d\n",
|
||||||
__func__, ret);
|
__func__, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lpass_hw_vote_unprepare(struct clk_hw *hw)
|
static void lpass_hw_vote_unprepare(struct clk_hw *hw)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
struct audio_ext_clk_priv *clk_priv = to_audio_clk(hw);
|
struct audio_ext_clk_priv *clk_priv = to_audio_clk(hw);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_CORE_HW_VOTE) {
|
if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_CORE_HW_VOTE) {
|
||||||
trace_printk("%s: unvote for %d clock\n",
|
#ifdef CONFIG_AUDIO_PRM
|
||||||
__func__, clk_priv->clk_src);
|
pr_debug("%s: clk_id %d ",__func__, clk_priv->prm_clk_cfg.clk_id);
|
||||||
|
ret = audio_prm_set_lpass_hw_core_req(&clk_priv->prm_clk_cfg,
|
||||||
|
HW_CORE_ID_LPASS, 0);
|
||||||
|
#else
|
||||||
ret = afe_unvote_lpass_core_hw(
|
ret = afe_unvote_lpass_core_hw(
|
||||||
AFE_LPASS_CORE_HW_MACRO_BLOCK,
|
AFE_LPASS_CORE_HW_MACRO_BLOCK,
|
||||||
clk_priv->lpass_core_hwvote_client_handle);
|
clk_priv->lpass_core_hwvote_client_handle);
|
||||||
|
#endif
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
pr_err("%s lpass core hw vote failed %d\n",
|
pr_err("%s lpass core hw vote failed %d\n",
|
||||||
__func__, ret);
|
__func__, ret);
|
||||||
@@ -212,17 +222,21 @@ static void lpass_hw_vote_unprepare(struct clk_hw *hw)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_AUDIO_HW_VOTE) {
|
if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_AUDIO_HW_VOTE) {
|
||||||
trace_printk("%s: unvote for %d clock\n",
|
|
||||||
__func__, clk_priv->clk_src);
|
#ifdef CONFIG_AUDIO_PRM
|
||||||
|
pr_debug("%s: clk_id %d ",__func__, clk_priv->prm_clk_cfg.clk_id);
|
||||||
|
ret = audio_prm_set_lpass_hw_core_req(&clk_priv->prm_clk_cfg,
|
||||||
|
HW_CORE_ID_DCODEC, 0);
|
||||||
|
#else
|
||||||
ret = afe_unvote_lpass_core_hw(
|
ret = afe_unvote_lpass_core_hw(
|
||||||
AFE_LPASS_CORE_HW_DCODEC_BLOCK,
|
AFE_LPASS_CORE_HW_DCODEC_BLOCK,
|
||||||
clk_priv->lpass_audio_hwvote_client_handle);
|
clk_priv->lpass_audio_hwvote_client_handle);
|
||||||
|
#endif
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
pr_err("%s lpass audio hw unvote failed %d\n",
|
pr_err("%s lpass audio hw unvote failed %d\n",
|
||||||
__func__, ret);
|
__func__, ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct clk_ops audio_ext_clk_ops = {
|
static const struct clk_ops audio_ext_clk_ops = {
|
||||||
@@ -583,7 +597,7 @@ static int audio_ref_clk_probe(struct platform_device *pdev)
|
|||||||
clk_priv->clk_cfg.clk_id = clk_id;
|
clk_priv->clk_cfg.clk_id = clk_id;
|
||||||
#ifdef CONFIG_AUDIO_PRM
|
#ifdef CONFIG_AUDIO_PRM
|
||||||
clk_priv->prm_clk_cfg.clk_id = clk_id;
|
clk_priv->prm_clk_cfg.clk_id = clk_id;
|
||||||
dev_info(&pdev->dev, "%s: ext-clk freq: %d, lpass clk_id: %d, clk_src: %d\n",
|
dev_info(&pdev->dev, "%s: PRM ext-clk freq: %d, lpass clk_id: %d, clk_src: %d\n",
|
||||||
__func__, clk_priv->prm_clk_cfg.clk_freq_in_hz,
|
__func__, clk_priv->prm_clk_cfg.clk_freq_in_hz,
|
||||||
clk_priv->prm_clk_cfg.clk_id, clk_priv->clk_src);
|
clk_priv->prm_clk_cfg.clk_id, clk_priv->clk_src);
|
||||||
#endif
|
#endif
|
||||||
@@ -592,6 +606,11 @@ static int audio_ref_clk_probe(struct platform_device *pdev)
|
|||||||
dev_info(&pdev->dev, "%s: ext-clk freq: %d, lpass clk_id: %d, clk_src: %d\n",
|
dev_info(&pdev->dev, "%s: ext-clk freq: %d, lpass clk_id: %d, clk_src: %d\n",
|
||||||
__func__, clk_priv->clk_cfg.clk_freq_in_hz,
|
__func__, clk_priv->clk_cfg.clk_freq_in_hz,
|
||||||
clk_priv->clk_cfg.clk_id, clk_priv->clk_src);
|
clk_priv->clk_cfg.clk_id, clk_priv->clk_src);
|
||||||
|
|
||||||
|
dev_info(&pdev->dev, "%s: PRM2 ext-clk freq: %d, lpass clk_id: %d, clk_src: %d\n",
|
||||||
|
__func__, clk_priv->prm_clk_cfg.clk_freq_in_hz,
|
||||||
|
clk_priv->prm_clk_cfg.clk_id, clk_priv->clk_src);
|
||||||
|
|
||||||
platform_set_drvdata(pdev, clk_priv);
|
platform_set_drvdata(pdev, clk_priv);
|
||||||
|
|
||||||
ret = of_property_read_string(pdev->dev.of_node, "pmic-clock-names",
|
ret = of_property_read_string(pdev->dev.of_node, "pmic-clock-names",
|
||||||
|
@@ -41,7 +41,7 @@ static int audio_prm_callback(struct gpr_device *adev, void *data)
|
|||||||
struct gpr_hdr *hdr = (struct gpr_hdr *)data;
|
struct gpr_hdr *hdr = (struct gpr_hdr *)data;
|
||||||
uint32_t *payload = GPR_PKT_GET_PAYLOAD(uint32_t, data);
|
uint32_t *payload = GPR_PKT_GET_PAYLOAD(uint32_t, data);
|
||||||
|
|
||||||
dev_dbg(&adev->dev, "%s: Payload %x", __func__, hdr->opcode);
|
dev_err(&adev->dev, "%s: Payload %x", __func__, hdr->opcode);
|
||||||
switch (hdr->opcode) {
|
switch (hdr->opcode) {
|
||||||
case GPR_IBASIC_RSP_RESULT:
|
case GPR_IBASIC_RSP_RESULT:
|
||||||
pr_err("%s: Failed response received",__func__);
|
pr_err("%s: Failed response received",__func__);
|
||||||
@@ -61,6 +61,7 @@ static int audio_prm_callback(struct gpr_device *adev, void *data)
|
|||||||
switch (payload[0]) {
|
switch (payload[0]) {
|
||||||
case PARAM_ID_RSC_AUDIO_HW_CLK:
|
case PARAM_ID_RSC_AUDIO_HW_CLK:
|
||||||
case PARAM_ID_RSC_LPASS_CORE:
|
case PARAM_ID_RSC_LPASS_CORE:
|
||||||
|
case PARAM_ID_RSC_HW_CORE:
|
||||||
if (payload[1] != 0)
|
if (payload[1] != 0)
|
||||||
pr_err("%s: PRM command failed with error %d\n",
|
pr_err("%s: PRM command failed with error %d\n",
|
||||||
__func__, payload[1]);
|
__func__, payload[1]);
|
||||||
@@ -68,6 +69,7 @@ static int audio_prm_callback(struct gpr_device *adev, void *data)
|
|||||||
wake_up(&g_prm.wait);
|
wake_up(&g_prm.wait);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
pr_err("%s: hit default case",__func__);
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
default:
|
default:
|
||||||
@@ -129,6 +131,60 @@ static int prm_gpr_send_pkt(struct gpr_pkt *pkt, wait_queue_head_t *wait)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
int audio_prm_set_lpass_hw_core_req(struct clk_cfg *cfg, uint32_t hw_core_id, uint8_t enable)
|
||||||
|
{
|
||||||
|
struct gpr_pkt *pkt;
|
||||||
|
prm_cmd_request_hw_core_t prm_rsc_request;
|
||||||
|
int ret = 0;
|
||||||
|
uint32_t size;
|
||||||
|
|
||||||
|
size = GPR_HDR_SIZE + sizeof(prm_cmd_request_hw_core_t);
|
||||||
|
pkt = kzalloc(size, GFP_KERNEL);
|
||||||
|
if (!pkt)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
pkt->hdr.header = GPR_SET_FIELD(GPR_PKT_VERSION, GPR_PKT_VER) |
|
||||||
|
GPR_SET_FIELD(GPR_PKT_HEADER_SIZE, GPR_PKT_HEADER_WORD_SIZE_V) |
|
||||||
|
GPR_SET_FIELD(GPR_PKT_PACKET_SIZE, size);
|
||||||
|
|
||||||
|
pkt->hdr.src_port = GPR_SVC_ASM;
|
||||||
|
pkt->hdr.dst_port = PRM_MODULE_INSTANCE_ID;
|
||||||
|
pkt->hdr.dst_domain_id = GPR_IDS_DOMAIN_ID_ADSP_V;
|
||||||
|
pkt->hdr.src_domain_id = GPR_IDS_DOMAIN_ID_APPS_V;
|
||||||
|
pkt->hdr.token = 0; /* TBD */
|
||||||
|
if (enable)
|
||||||
|
pkt->hdr.opcode = PRM_CMD_REQUEST_HW_RSC;
|
||||||
|
else
|
||||||
|
pkt->hdr.opcode = PRM_CMD_RELEASE_HW_RSC;
|
||||||
|
|
||||||
|
pr_err("%s: clk_id %d size of cmd_req %ld \n",__func__, cfg->clk_id, sizeof(prm_cmd_request_hw_core_t));
|
||||||
|
|
||||||
|
prm_rsc_request.payload_header.payload_address_lsw = 0;
|
||||||
|
prm_rsc_request.payload_header.payload_address_msw = 0;
|
||||||
|
prm_rsc_request.payload_header.mem_map_handle = 0;
|
||||||
|
prm_rsc_request.payload_header.payload_size = sizeof(prm_cmd_request_hw_core_t) - sizeof(apm_cmd_header_t);
|
||||||
|
|
||||||
|
/** Populate the param payload */
|
||||||
|
prm_rsc_request.module_payload_0.module_instance_id = PRM_MODULE_INSTANCE_ID;
|
||||||
|
prm_rsc_request.module_payload_0.error_code = 0;
|
||||||
|
prm_rsc_request.module_payload_0.param_id = PARAM_ID_RSC_HW_CORE;
|
||||||
|
prm_rsc_request.module_payload_0.param_size =
|
||||||
|
sizeof(prm_cmd_request_hw_core_t) - sizeof(apm_cmd_header_t) - sizeof(apm_module_param_data_t);
|
||||||
|
|
||||||
|
|
||||||
|
prm_rsc_request.hw_core_id = hw_core_id; // HW_CORE_ID_LPASS;
|
||||||
|
|
||||||
|
memcpy(&pkt->payload, &prm_rsc_request, sizeof(prm_cmd_request_hw_core_t));
|
||||||
|
|
||||||
|
ret = prm_gpr_send_pkt(pkt, &g_prm.wait);
|
||||||
|
|
||||||
|
kfree(pkt);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(audio_prm_set_lpass_hw_core_req);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* prm_set_lpass_clk_cfg() - Set PRM clock
|
* prm_set_lpass_clk_cfg() - Set PRM clock
|
||||||
*
|
*
|
||||||
@@ -296,6 +352,7 @@ err:
|
|||||||
static int audio_prm_remove(struct gpr_device *adev)
|
static int audio_prm_remove(struct gpr_device *adev)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
mutex_lock(&g_prm.lock);
|
mutex_lock(&g_prm.lock);
|
||||||
ret = snd_event_client_deregister(&adev->dev);
|
ret = snd_event_client_deregister(&adev->dev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@@ -181,6 +181,13 @@ typedef struct prm_cmd_release_rsc_t
|
|||||||
audio_hw_clk_rel_cfg_t clock_ids_t[MAX_AUD_HW_CLK_NUM_REQ];
|
audio_hw_clk_rel_cfg_t clock_ids_t[MAX_AUD_HW_CLK_NUM_REQ];
|
||||||
}prm_cmd_release_rsc_t;
|
}prm_cmd_release_rsc_t;
|
||||||
|
|
||||||
|
typedef struct prm_cmd_request_hw_core_t
|
||||||
|
{
|
||||||
|
apm_cmd_header_t payload_header;
|
||||||
|
apm_module_param_data_t module_payload_0;
|
||||||
|
uint32_t hw_core_id;
|
||||||
|
}prm_cmd_request_hw_core_t;
|
||||||
|
|
||||||
|
|
||||||
#define PRM_CMD_REQUEST_HW_RSC 0x0100100F
|
#define PRM_CMD_REQUEST_HW_RSC 0x0100100F
|
||||||
|
|
||||||
@@ -197,6 +204,7 @@ typedef struct prm_cmd_release_rsc_t
|
|||||||
/* Param ID for lpass core clock */
|
/* Param ID for lpass core clock */
|
||||||
|
|
||||||
#define PARAM_ID_RSC_LPASS_CORE 0x0800102B
|
#define PARAM_ID_RSC_LPASS_CORE 0x0800102B
|
||||||
|
#define PARAM_ID_RSC_HW_CORE 0x08001032
|
||||||
|
|
||||||
#define HW_RSC_ID_AUDIO_HW_CLK 0x0800102C
|
#define HW_RSC_ID_AUDIO_HW_CLK 0x0800102C
|
||||||
|
|
||||||
@@ -494,6 +502,13 @@ typedef struct prm_cmd_release_rsc_t
|
|||||||
/** Default root clock source. */
|
/** Default root clock source. */
|
||||||
#define CLOCK_ROOT_DEFAULT 0x0
|
#define CLOCK_ROOT_DEFAULT 0x0
|
||||||
|
|
||||||
|
/** Hardware core identifier for LPASS. */
|
||||||
|
#define HW_CORE_ID_LPASS 0x1
|
||||||
|
|
||||||
|
/** Hardware core identifier for digital codec. */
|
||||||
|
#define HW_CORE_ID_DCODEC 0x2
|
||||||
|
|
||||||
int audio_prm_set_lpass_clk_cfg(struct clk_cfg *cfg, uint8_t enable);
|
int audio_prm_set_lpass_clk_cfg(struct clk_cfg *cfg, uint8_t enable);
|
||||||
|
int audio_prm_set_lpass_hw_core_req(struct clk_cfg *cfg, uint32_t hw_core_id, uint8_t enable);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user