mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 22:40:54 -04:00
dsp: update q6core driver to vote for LPASS island NPA resource
Add interface functions to vote for LPASS island NPA resource from clients. Change-Id: I532dd697f986aca48c3125b1bab3435b890d4039 Signed-off-by: Mangesh Kunchamwar <mangeshk@codeaurora.org>
This commit is contained in:
parent
3e19f3c007
commit
70c29ec0dc
2 changed files with 320 additions and 2 deletions
219
dsp/q6core.c
219
dsp/q6core.c
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
#define TIMEOUT_MS 1000
|
||||
/*
|
||||
* AVS bring up in the modem is optimitized for the new
|
||||
* AVS bring up in the modem is optimized for the new
|
||||
* Sub System Restart design and 100 milliseconds timeout
|
||||
* is sufficient to make sure the Q6 will be ready.
|
||||
*/
|
||||
|
|
@ -67,6 +67,8 @@ struct q6core_str {
|
|||
wait_queue_head_t mdf_map_resp_wait;
|
||||
wait_queue_head_t cmd_req_wait;
|
||||
wait_queue_head_t avcs_fwk_ver_req_wait;
|
||||
wait_queue_head_t lpass_npa_rsc_wait;
|
||||
u32 lpass_npa_rsc_rsp_rcvd;
|
||||
u32 bus_bw_resp_received;
|
||||
u32 mdf_map_resp_received;
|
||||
enum cmd_flags {
|
||||
|
|
@ -84,6 +86,7 @@ struct q6core_str {
|
|||
struct cal_type_data *cal_data[CORE_MAX_CAL];
|
||||
uint32_t mem_map_cal_handle;
|
||||
uint32_t mdf_mem_map_cal_handle;
|
||||
uint32_t npa_client_handle;
|
||||
int32_t adsp_status;
|
||||
int32_t avs_state;
|
||||
struct q6core_avcs_ver_info q6core_avcs_ver_info;
|
||||
|
|
@ -321,6 +324,15 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv)
|
|||
"AVCS_CMD_UNLOAD_TOPO_MODULES",
|
||||
adsp_err_get_err_str(payload1[1]));
|
||||
break;
|
||||
case AVCS_CMD_DESTROY_LPASS_NPA_CLIENT:
|
||||
case AVCS_CMD_REQUEST_LPASS_NPA_RESOURCES:
|
||||
pr_debug("%s: Cmd = AVCS_CMD_CREATE_LPASS_NPA_CLIENT/AVCS_CMD_DESTROY_LPASS_NPA_CLIENT status[%s]\n",
|
||||
__func__, adsp_err_get_err_str(payload1[1]));
|
||||
/* ADSP status to match Linux error standard */
|
||||
q6core_lcl.adsp_status = -payload1[1];
|
||||
q6core_lcl.lpass_npa_rsc_rsp_rcvd = 1;
|
||||
wake_up(&q6core_lcl.lpass_npa_rsc_wait);
|
||||
break;
|
||||
default:
|
||||
pr_err("%s: Invalid cmd rsp[0x%x][0x%x] opcode %d\n",
|
||||
__func__,
|
||||
|
|
@ -355,6 +367,15 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv)
|
|||
wake_up(&q6core_lcl.bus_bw_req_wait);
|
||||
}
|
||||
break;
|
||||
case AVCS_CMDRSP_CREATE_LPASS_NPA_CLIENT:
|
||||
payload1 = data->payload;
|
||||
pr_debug("%s: AVCS_CMDRSP_CREATE_LPASS_NPA_CLIENT handle %d\n",
|
||||
__func__, payload1[1]);
|
||||
q6core_lcl.adsp_status = payload1[0];
|
||||
q6core_lcl.npa_client_handle = payload1[1];
|
||||
q6core_lcl.lpass_npa_rsc_rsp_rcvd = 1;
|
||||
wake_up(&q6core_lcl.lpass_npa_rsc_wait);
|
||||
break;
|
||||
case AVCS_CMDRSP_ADSP_EVENT_GET_STATE:
|
||||
payload1 = data->payload;
|
||||
q6core_lcl.param = payload1[0];
|
||||
|
|
@ -933,6 +954,201 @@ bail:
|
|||
}
|
||||
EXPORT_SYMBOL(q6core_is_adsp_ready);
|
||||
|
||||
int q6core_create_lpass_npa_client(uint32_t node_id, char *client_name,
|
||||
uint32_t *client_handle)
|
||||
{
|
||||
struct avcs_cmd_create_lpass_npa_client_t create_lpass_npa_client;
|
||||
struct avcs_cmd_create_lpass_npa_client_t *cmd_ptr =
|
||||
&create_lpass_npa_client;
|
||||
int ret = 0;
|
||||
|
||||
if (!client_name) {
|
||||
pr_err("%s: Invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&(q6core_lcl.cmd_lock));
|
||||
|
||||
memset(cmd_ptr, 0, sizeof(create_lpass_npa_client));
|
||||
|
||||
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(create_lpass_npa_client);
|
||||
cmd_ptr->hdr.src_port = 0;
|
||||
cmd_ptr->hdr.dest_port = 0;
|
||||
cmd_ptr->hdr.token = 0;
|
||||
cmd_ptr->hdr.opcode = AVCS_CMD_CREATE_LPASS_NPA_CLIENT;
|
||||
cmd_ptr->node_id = AVCS_SLEEP_ISLAND_CORE_DRIVER_NODE_ID;
|
||||
strlcpy(cmd_ptr->client_name, client_name,
|
||||
sizeof(cmd_ptr->client_name));
|
||||
|
||||
pr_debug("%s: create lpass npa client opcode[0x%x] node id[0x%x]\n",
|
||||
__func__, cmd_ptr->hdr.opcode, cmd_ptr->node_id);
|
||||
|
||||
*client_handle = 0;
|
||||
q6core_lcl.adsp_status = 0;
|
||||
q6core_lcl.lpass_npa_rsc_rsp_rcvd = 0;
|
||||
ret = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *) cmd_ptr);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: create lpass npa client failed %d\n",
|
||||
__func__, ret);
|
||||
ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = wait_event_timeout(q6core_lcl.lpass_npa_rsc_wait,
|
||||
(q6core_lcl.lpass_npa_rsc_rsp_rcvd == 1),
|
||||
msecs_to_jiffies(TIMEOUT_MS));
|
||||
if (!ret) {
|
||||
pr_err("%s: timeout. waited for create lpass npa rsc client\n",
|
||||
__func__);
|
||||
ret = -ETIMEDOUT;
|
||||
goto done;
|
||||
} else {
|
||||
/* set ret to 0 as no timeout happened */
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (q6core_lcl.adsp_status < 0) {
|
||||
pr_err("%s: DSP returned error %d\n",
|
||||
__func__, q6core_lcl.adsp_status);
|
||||
ret = q6core_lcl.adsp_status;
|
||||
goto done;
|
||||
}
|
||||
|
||||
*client_handle = q6core_lcl.npa_client_handle;
|
||||
pr_debug("%s: q6core_lcl.npa_client_handle %d\n", __func__,
|
||||
q6core_lcl.npa_client_handle);
|
||||
done:
|
||||
mutex_unlock(&q6core_lcl.cmd_lock);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(q6core_create_lpass_npa_client);
|
||||
|
||||
int q6core_destroy_lpass_npa_client(uint32_t client_handle)
|
||||
{
|
||||
struct avcs_cmd_destroy_lpass_npa_client_t destroy_lpass_npa_client;
|
||||
struct avcs_cmd_destroy_lpass_npa_client_t *cmd_ptr =
|
||||
&destroy_lpass_npa_client;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&(q6core_lcl.cmd_lock));
|
||||
|
||||
memset(cmd_ptr, 0, sizeof(destroy_lpass_npa_client));
|
||||
|
||||
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(destroy_lpass_npa_client);
|
||||
cmd_ptr->hdr.src_port = 0;
|
||||
cmd_ptr->hdr.dest_port = 0;
|
||||
cmd_ptr->hdr.token = 0;
|
||||
cmd_ptr->hdr.opcode = AVCS_CMD_DESTROY_LPASS_NPA_CLIENT;
|
||||
cmd_ptr->client_handle = client_handle;
|
||||
|
||||
pr_debug("%s: dstry lpass npa client opcode[0x%x] client hdl[0x%x]\n",
|
||||
__func__, cmd_ptr->hdr.opcode, cmd_ptr->client_handle);
|
||||
|
||||
q6core_lcl.adsp_status = 0;
|
||||
q6core_lcl.lpass_npa_rsc_rsp_rcvd = 0;
|
||||
ret = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *) cmd_ptr);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: destroy lpass npa client failed %d\n",
|
||||
__func__, ret);
|
||||
ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = wait_event_timeout(q6core_lcl.lpass_npa_rsc_wait,
|
||||
(q6core_lcl.lpass_npa_rsc_rsp_rcvd == 1),
|
||||
msecs_to_jiffies(TIMEOUT_MS));
|
||||
if (!ret) {
|
||||
pr_err("%s: timeout. waited for destroy lpass npa rsc client\n",
|
||||
__func__);
|
||||
ret = -ETIMEDOUT;
|
||||
goto done;
|
||||
} else {
|
||||
/* set ret to 0 as no timeout happened */
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (q6core_lcl.adsp_status < 0) {
|
||||
pr_err("%s: DSP returned error %d\n",
|
||||
__func__, q6core_lcl.adsp_status);
|
||||
ret = q6core_lcl.adsp_status;
|
||||
}
|
||||
done:
|
||||
mutex_unlock(&q6core_lcl.cmd_lock);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(q6core_destroy_lpass_npa_client);
|
||||
|
||||
int q6core_request_island_transition(uint32_t client_handle,
|
||||
uint32_t island_allow_mode)
|
||||
{
|
||||
struct avcs_sleep_node_island_transition_config_t island_tsn_cfg;
|
||||
struct avcs_sleep_node_island_transition_config_t *cmd_ptr =
|
||||
&island_tsn_cfg;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&(q6core_lcl.cmd_lock));
|
||||
|
||||
memset(cmd_ptr, 0, sizeof(island_tsn_cfg));
|
||||
|
||||
cmd_ptr->req_lpass_npa_rsc.hdr.hdr_field =
|
||||
APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
|
||||
APR_HDR_LEN(APR_HDR_SIZE),
|
||||
APR_PKT_VER);
|
||||
cmd_ptr->req_lpass_npa_rsc.hdr.pkt_size = sizeof(island_tsn_cfg);
|
||||
cmd_ptr->req_lpass_npa_rsc.hdr.src_port = 0;
|
||||
cmd_ptr->req_lpass_npa_rsc.hdr.dest_port = 0;
|
||||
cmd_ptr->req_lpass_npa_rsc.hdr.token = 0;
|
||||
cmd_ptr->req_lpass_npa_rsc.hdr.opcode =
|
||||
AVCS_CMD_REQUEST_LPASS_NPA_RESOURCES;
|
||||
cmd_ptr->req_lpass_npa_rsc.client_handle = client_handle;
|
||||
cmd_ptr->req_lpass_npa_rsc.resource_id =
|
||||
AVCS_SLEEP_NODE_ISLAND_TRANSITION_RESOURCE_ID;
|
||||
cmd_ptr->island_allow_mode = island_allow_mode;
|
||||
|
||||
pr_debug("%s: req islnd tnsn opcode[0x%x] island_allow_mode[0x%x]\n",
|
||||
__func__, cmd_ptr->req_lpass_npa_rsc.hdr.opcode,
|
||||
cmd_ptr->island_allow_mode);
|
||||
|
||||
q6core_lcl.adsp_status = 0;
|
||||
q6core_lcl.lpass_npa_rsc_rsp_rcvd = 0;
|
||||
ret = apr_send_pkt(q6core_lcl.core_handle_q, (uint32_t *) cmd_ptr);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: island tnsn cmd send failed %d\n",
|
||||
__func__, ret);
|
||||
ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = wait_event_timeout(q6core_lcl.lpass_npa_rsc_wait,
|
||||
(q6core_lcl.lpass_npa_rsc_rsp_rcvd == 1),
|
||||
msecs_to_jiffies(TIMEOUT_MS));
|
||||
if (!ret) {
|
||||
pr_err("%s: timeout. waited for island lpass npa rsc req\n",
|
||||
__func__);
|
||||
ret = -ETIMEDOUT;
|
||||
goto done;
|
||||
} else {
|
||||
/* set ret to 0 as no timeout happened */
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (q6core_lcl.adsp_status < 0) {
|
||||
pr_err("%s: DSP returned error %d\n",
|
||||
__func__, q6core_lcl.adsp_status);
|
||||
ret = q6core_lcl.adsp_status;
|
||||
}
|
||||
done:
|
||||
mutex_unlock(&q6core_lcl.cmd_lock);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(q6core_request_island_transition);
|
||||
|
||||
int q6core_map_memory_regions(phys_addr_t *buf_add, uint32_t mempool_id,
|
||||
uint32_t *bufsz, uint32_t bufcnt, uint32_t *map_handle)
|
||||
{
|
||||
|
|
@ -1671,6 +1887,7 @@ int __init core_init(void)
|
|||
init_waitqueue_head(&q6core_lcl.cmd_req_wait);
|
||||
init_waitqueue_head(&q6core_lcl.avcs_fwk_ver_req_wait);
|
||||
init_waitqueue_head(&q6core_lcl.mdf_map_resp_wait);
|
||||
init_waitqueue_head(&q6core_lcl.lpass_npa_rsc_wait);
|
||||
q6core_lcl.cmd_resp_received_flag = FLAG_NONE;
|
||||
mutex_init(&q6core_lcl.cmd_lock);
|
||||
mutex_init(&q6core_lcl.ver_lock);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
#define AVCS_CMD_ADSP_EVENT_GET_STATE 0x0001290C
|
||||
#define AVCS_CMDRSP_ADSP_EVENT_GET_STATE 0x0001290D
|
||||
#define AVCS_API_VERSION_V4 4
|
||||
#define APRV2_IDS_SERVICE_ID_ADSP_CORE_V (0x3)
|
||||
|
||||
bool q6core_is_adsp_ready(void);
|
||||
|
||||
|
|
@ -150,7 +152,7 @@ struct avcs_cmd_register_topologies {
|
|||
} __packed;
|
||||
|
||||
|
||||
#define AVCS_CMD_DEREGISTER_TOPOLOGIES 0x0001292a
|
||||
#define AVCS_CMD_DEREGISTER_TOPOLOGIES 0x0001292a
|
||||
|
||||
/* The payload for the AVCS_CMD_DEREGISTER_TOPOLOGIES command */
|
||||
struct avcs_cmd_deregister_topologies {
|
||||
|
|
@ -195,6 +197,99 @@ struct avcs_cmd_load_unload_topo_modules {
|
|||
uint32_t topology_id;
|
||||
} __packed;
|
||||
|
||||
/* This command allows a remote client(HLOS) creates a client to LPASS NPA
|
||||
* resource node. Currently, this command supports only the NPA Sleep resource
|
||||
* "/island/core/drivers" node ID.
|
||||
*/
|
||||
#define AVCS_CMD_CREATE_LPASS_NPA_CLIENT 0x00012985
|
||||
|
||||
#define AVCS_SLEEP_ISLAND_CORE_DRIVER_NODE_ID 0x00000001
|
||||
|
||||
struct avcs_cmd_create_lpass_npa_client_t {
|
||||
struct apr_hdr hdr;
|
||||
uint32_t node_id;
|
||||
/* Unique ID of the NPA node.
|
||||
* @values
|
||||
* - #AVCS_SLEEP_ISLAND_CORE_DRIVER_NODE_ID
|
||||
*/
|
||||
|
||||
char client_name[16];
|
||||
/* Client name, up to a maximum of sixteen characters.*/
|
||||
};
|
||||
|
||||
/* In response to the #AVCS_CMD_CREATE_LPASS_NPA_CLIENT command, the AVCS
|
||||
* returns the handle to remote HLOS client.
|
||||
*/
|
||||
#define AVCS_CMDRSP_CREATE_LPASS_NPA_CLIENT 0x00012986
|
||||
|
||||
struct avcs_cmdrsp_create_lpass_npa_client_t {
|
||||
uint32_t status;
|
||||
/* Status message (error code).
|
||||
* @values
|
||||
* - ADSP_EOK -- Create was successful
|
||||
* - ADSP_EFAILED -- Create failed
|
||||
*/
|
||||
|
||||
uint32_t client_handle;
|
||||
/* Handle of the client.*/
|
||||
};
|
||||
|
||||
/* The remote HLOS client use this command to issue the request to the npa
|
||||
* resource. Remote client(HLOS) must send the valid npa client handle and
|
||||
* resource id info.
|
||||
*/
|
||||
#define AVCS_CMD_REQUEST_LPASS_NPA_RESOURCES 0x00012987
|
||||
|
||||
#define AVCS_SLEEP_NODE_ISLAND_TRANSITION_RESOURCE_ID 0x00000001
|
||||
|
||||
#define SLEEP_RESTRICT_ISLAND 0x0
|
||||
#define SLEEP_ALLOW_ISLAND 0x1
|
||||
|
||||
/* Immediately following this structure is the resource request configuration
|
||||
* data payload. Payload varies depend on the resource_id requested.
|
||||
* Currently supported only island transition payload.
|
||||
*/
|
||||
struct avcs_cmd_request_lpass_npa_resources_t {
|
||||
struct apr_hdr hdr;
|
||||
uint32_t client_handle;
|
||||
/* Handle of the client.
|
||||
* @values
|
||||
* - Valid uint32 number
|
||||
*/
|
||||
|
||||
uint32_t resource_id;
|
||||
/* Unique ID of the NPA resource ID.
|
||||
* @values
|
||||
* - #AVCS_SLEEP_NODE_ISLAND_TRANSITION_RESOURCE_ID
|
||||
*/
|
||||
};
|
||||
|
||||
/* This structure contains the sleep node resource payload data.
|
||||
*/
|
||||
struct avcs_sleep_node_island_transition_config_t {
|
||||
struct avcs_cmd_request_lpass_npa_resources_t req_lpass_npa_rsc;
|
||||
uint32_t island_allow_mode;
|
||||
/* Specifies the island state.
|
||||
* @values
|
||||
* - #SLEEP_RESTRICT_ISLAND
|
||||
* - #SLEEP_ALLOW_ISLAND
|
||||
*/
|
||||
};
|
||||
|
||||
/* This command allows remote client(HLOS) to destroy the npa node client
|
||||
* handle, which is created using the #AVCS_CMD_CREATE_LPASS_NPA_CLIENT command.
|
||||
* Remote client(HLOS) must send the valid npa client handle.
|
||||
*/
|
||||
#define AVCS_CMD_DESTROY_LPASS_NPA_CLIENT 0x00012988
|
||||
|
||||
struct avcs_cmd_destroy_lpass_npa_client_t {
|
||||
struct apr_hdr hdr;
|
||||
uint32_t client_handle;
|
||||
/* Handle of the client.
|
||||
* @values
|
||||
* - Valid uint32 number
|
||||
*/
|
||||
};
|
||||
|
||||
int q6core_map_memory_regions(phys_addr_t *buf_add, uint32_t mempool_id,
|
||||
uint32_t *bufsz, uint32_t bufcnt, uint32_t *map_handle);
|
||||
|
|
@ -212,6 +307,12 @@ int32_t core_get_license_status(uint32_t module_id);
|
|||
int32_t q6core_load_unload_topo_modules(uint32_t topology_id,
|
||||
bool preload_type);
|
||||
|
||||
int q6core_create_lpass_npa_client(uint32_t node_id, char *client_name,
|
||||
uint32_t *client_handle);
|
||||
int q6core_destroy_lpass_npa_client(uint32_t client_handle);
|
||||
int q6core_request_island_transition(uint32_t client_handle,
|
||||
uint32_t island_allow_mode);
|
||||
|
||||
#if IS_ENABLED(CONFIG_USE_Q6_32CH_SUPPORT)
|
||||
static inline bool q6core_use_Q6_32ch_support(void)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue