msm: ipa: ipa 4.0 Immediate command upgrade
Add new imd commands ipa_imm_cmd_construct_register_write_v_4_0
and ipa_imm_cmd_construct_dma_shared_mem_v_4_0. Add an opcode
variable in the payload struct and use this opcode instead of
calling the imm_cmd_get_opcode function.
Change-Id: Ia7aaa7740f3295000b8e94f620bdad4c96076718
CRs-Fixed: 2044228
Signed-off-by: Michael Adisumarta <madisuma@codeaurora.org>
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c
index 8b2beea..31e530e 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c
@@ -1735,7 +1735,7 @@
IPAERR("failed to construct dma_shared_mem imm cmd\n");
return -ENOMEM;
}
- desc.opcode = ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_DMA_SHARED_MEM);
+ desc.opcode = cmd_pyld->opcode;
desc.pyld = cmd_pyld->data;
desc.len = cmd_pyld->len;
desc.type = IPA_IMM_CMD_DESC;
@@ -2000,8 +2000,7 @@
retval = -ENOMEM;
goto free_empty_img;
}
- desc[num_cmds].opcode = ipahal_imm_cmd_get_opcode(
- IPA_IMM_CMD_DMA_SHARED_MEM);
+ desc[num_cmds].opcode = cmd_pyld[num_cmds]->opcode;
desc[num_cmds].pyld = cmd_pyld[num_cmds]->data;
desc[num_cmds].len = cmd_pyld[num_cmds]->len;
desc[num_cmds].type = IPA_IMM_CMD_DESC;
@@ -2100,8 +2099,7 @@
retval = -ENOMEM;
goto free_desc;
}
- desc->opcode =
- ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_DMA_SHARED_MEM);
+ desc->opcode = cmd_pyld->opcode;
desc->pyld = cmd_pyld->data;
desc->len = cmd_pyld->len;
desc->type = IPA_IMM_CMD_DESC;
@@ -2191,8 +2189,7 @@
retval = -EFAULT;
goto bail_desc;
}
- desc->opcode =
- ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_REGISTER_WRITE);
+ desc->opcode = cmd_pyld->opcode;
desc->pyld = cmd_pyld->data;
desc->len = cmd_pyld->len;
desc->type = IPA_IMM_CMD_DESC;
@@ -2259,8 +2256,7 @@
BUG();
}
- desc[num_descs].opcode = ipahal_imm_cmd_get_opcode(
- IPA_IMM_CMD_REGISTER_WRITE);
+ desc[num_descs].opcode = cmd_pyld->opcode;
desc[num_descs].type = IPA_IMM_CMD_DESC;
desc[num_descs].callback = ipa3_destroy_imm;
desc[num_descs].user1 = cmd_pyld;
@@ -2289,8 +2285,7 @@
return -EFAULT;
}
- desc[num_descs].opcode = ipahal_imm_cmd_get_opcode(
- IPA_IMM_CMD_REGISTER_WRITE);
+ desc[num_descs].opcode = cmd_pyld->opcode;
desc[num_descs].type = IPA_IMM_CMD_DESC;
desc[num_descs].callback = ipa3_destroy_imm;
desc[num_descs].user1 = cmd_pyld;
@@ -2494,7 +2489,7 @@
mem.phys_base);
return -EFAULT;
}
- desc.opcode = ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_HDR_INIT_LOCAL);
+ desc.opcode = cmd_pyld->opcode;
desc.type = IPA_IMM_CMD_DESC;
desc.pyld = cmd_pyld->data;
desc.len = cmd_pyld->len;
@@ -2539,7 +2534,7 @@
mem.phys_base);
return -EFAULT;
}
- desc.opcode = ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_DMA_SHARED_MEM);
+ desc.opcode = cmd_pyld->opcode;
desc.pyld = cmd_pyld->data;
desc.len = cmd_pyld->len;
desc.type = IPA_IMM_CMD_DESC;
@@ -2611,8 +2606,7 @@
goto free_mem;
}
- desc.opcode =
- ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_IP_V4_ROUTING_INIT);
+ desc.opcode = cmd_pyld->opcode;
desc.type = IPA_IMM_CMD_DESC;
desc.pyld = cmd_pyld->data;
desc.len = cmd_pyld->len;
@@ -2678,8 +2672,7 @@
goto free_mem;
}
- desc.opcode =
- ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_IP_V6_ROUTING_INIT);
+ desc.opcode = cmd_pyld->opcode;
desc.type = IPA_IMM_CMD_DESC;
desc.pyld = cmd_pyld->data;
desc.len = cmd_pyld->len;
@@ -2739,7 +2732,7 @@
goto free_mem;
}
- desc.opcode = ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_IP_V4_FILTER_INIT);
+ desc.opcode = cmd_pyld->opcode;
desc.type = IPA_IMM_CMD_DESC;
desc.pyld = cmd_pyld->data;
desc.len = cmd_pyld->len;
@@ -2800,7 +2793,7 @@
goto free_mem;
}
- desc.opcode = ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_IP_V6_FILTER_INIT);
+ desc.opcode = cmd_pyld->opcode;
desc.type = IPA_IMM_CMD_DESC;
desc.pyld = cmd_pyld->data;
desc.len = cmd_pyld->len;
@@ -4322,6 +4315,7 @@
IPAERR("failed to construct IMM cmd\n");
return -ENOMEM;
}
+ ipa3_ctx->pkt_init_imm_opcode = cmd_pyld->opcode;
mem.size = cmd_pyld->len * ipa3_ctx->ipa_num_pipes;
mem.base = dma_alloc_coherent(ipa3_ctx->pdev, mem.size,
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
index faa47d8..bf13ac5 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
@@ -315,9 +315,7 @@
}
/* populate tag field */
- if (desc[i].opcode ==
- ipahal_imm_cmd_get_opcode(
- IPA_IMM_CMD_IP_PACKET_TAG_STATUS)) {
+ if (desc[i].is_tag_status) {
if (ipa_populate_tag_field(&desc[i], tx_pkt,
&tag_pyld_ret)) {
IPAERR("Failed to populate tag field\n");
@@ -1279,15 +1277,10 @@
* notification. IPA will generate a status packet with
* tag info as a result of the TAG STATUS command.
*/
- desc[data_idx].opcode =
- ipahal_imm_cmd_get_opcode(
- IPA_IMM_CMD_IP_PACKET_TAG_STATUS);
- desc[data_idx].type = IPA_IMM_CMD_DESC;
- desc[data_idx].callback = ipa3_tag_destroy_imm;
+ desc[data_idx].is_tag_status = true;
data_idx++;
}
- desc[data_idx].opcode =
- ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_IP_PACKET_INIT);
+ desc[data_idx].opcode = ipa3_ctx->pkt_init_imm_opcode;
desc[data_idx].dma_address_valid = true;
desc[data_idx].dma_address = ipa3_ctx->pkt_init_imm[dst_ep_idx];
desc[data_idx].type = IPA_IMM_CMD_DESC;
@@ -1338,11 +1331,7 @@
* notification. IPA will generate a status packet with
* tag info as a result of the TAG STATUS command.
*/
- desc[data_idx].opcode =
- ipahal_imm_cmd_get_opcode(
- IPA_IMM_CMD_IP_PACKET_TAG_STATUS);
- desc[data_idx].type = IPA_IMM_CMD_DESC;
- desc[data_idx].callback = ipa3_tag_destroy_imm;
+ desc[data_idx].is_tag_status = true;
data_idx++;
}
desc[data_idx].pyld = skb->data;
@@ -2979,11 +2968,7 @@
(u8)sys->ep->cfg.meta.qmap_id;
/* the tag field will be populated in ipa3_send() function */
- desc[0].opcode =
- ipahal_imm_cmd_get_opcode(
- IPA_IMM_CMD_IP_PACKET_TAG_STATUS);
- desc[0].type = IPA_IMM_CMD_DESC;
- desc[0].callback = ipa3_tag_destroy_imm;
+ desc[0].is_tag_status = true;
desc[1].pyld = entry->pyld_buffer;
desc[1].len = entry->pyld_len;
desc[1].type = IPA_DATA_DESC_SKB;
@@ -3615,8 +3600,11 @@
*/
IPADBG_LOW("tx_pkt sent in tag: 0x%p\n", tx_pkt);
desc->pyld = tag_pyld->data;
+ desc->opcode = tag_pyld->opcode;
desc->len = tag_pyld->len;
desc->user1 = tag_pyld;
+ desc->type = IPA_IMM_CMD_DESC;
+ desc->callback = ipa3_tag_destroy_imm;
*tag_pyld_ret = tag_pyld;
}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c b/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c
index ff763c4..d0ed782 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_flt.c
@@ -573,7 +573,7 @@
rc = -EFAULT;
goto fail_reg_write_construct;
}
- desc[0].opcode = ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_REGISTER_WRITE);
+ desc[0].opcode = cmd_pyld[0]->opcode;
desc[0].pyld = cmd_pyld[0]->data;
desc[0].len = cmd_pyld[0]->len;
desc[0].type = IPA_IMM_CMD_DESC;
@@ -609,8 +609,7 @@
ip);
goto fail_imm_cmd_construct;
}
- desc[num_cmd].opcode =
- ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_DMA_SHARED_MEM);
+ desc[num_cmd].opcode = cmd_pyld[num_cmd]->opcode;
desc[num_cmd].pyld = cmd_pyld[num_cmd]->data;
desc[num_cmd].len = cmd_pyld[num_cmd]->len;
desc[num_cmd++].type = IPA_IMM_CMD_DESC;
@@ -630,8 +629,7 @@
ip);
goto fail_imm_cmd_construct;
}
- desc[num_cmd].opcode =
- ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_DMA_SHARED_MEM);
+ desc[num_cmd].opcode = cmd_pyld[num_cmd]->opcode;
desc[num_cmd].pyld = cmd_pyld[num_cmd]->data;
desc[num_cmd].len = cmd_pyld[num_cmd]->len;
desc[num_cmd++].type = IPA_IMM_CMD_DESC;
@@ -653,8 +651,7 @@
ip);
goto fail_imm_cmd_construct;
}
- desc[num_cmd].opcode =
- ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_DMA_SHARED_MEM);
+ desc[num_cmd].opcode = cmd_pyld[num_cmd]->opcode;
desc[num_cmd].pyld = cmd_pyld[num_cmd]->data;
desc[num_cmd].len = cmd_pyld[num_cmd]->len;
desc[num_cmd++].type = IPA_IMM_CMD_DESC;
@@ -673,8 +670,7 @@
ip);
goto fail_imm_cmd_construct;
}
- desc[num_cmd].opcode =
- ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_DMA_SHARED_MEM);
+ desc[num_cmd].opcode = cmd_pyld[num_cmd]->opcode;
desc[num_cmd].pyld = cmd_pyld[num_cmd]->data;
desc[num_cmd].len = cmd_pyld[num_cmd]->len;
desc[num_cmd++].type = IPA_IMM_CMD_DESC;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c
index 69db99a..410b96a 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_hdr.c
@@ -181,8 +181,7 @@
IPAERR("fail construct dma_shared_mem cmd\n");
goto end;
}
- desc[0].opcode = ipahal_imm_cmd_get_opcode(
- IPA_IMM_CMD_DMA_SHARED_MEM);
+ desc[0].opcode = hdr_cmd_pyld->opcode;
desc[0].pyld = hdr_cmd_pyld->data;
desc[0].len = hdr_cmd_pyld->len;
}
@@ -200,8 +199,7 @@
IPAERR("fail construct hdr_init_system cmd\n");
goto end;
}
- desc[0].opcode = ipahal_imm_cmd_get_opcode(
- IPA_IMM_CMD_HDR_INIT_SYSTEM);
+ desc[0].opcode = hdr_cmd_pyld->opcode;
desc[0].pyld = hdr_cmd_pyld->data;
desc[0].len = hdr_cmd_pyld->len;
}
@@ -233,8 +231,7 @@
IPAERR("fail construct dma_shared_mem cmd\n");
goto end;
}
- desc[1].opcode = ipahal_imm_cmd_get_opcode(
- IPA_IMM_CMD_DMA_SHARED_MEM);
+ desc[1].opcode = ctx_cmd_pyld->opcode;
desc[1].pyld = ctx_cmd_pyld->data;
desc[1].len = ctx_cmd_pyld->len;
}
@@ -262,8 +259,7 @@
IPAERR("fail construct register_write cmd\n");
goto end;
}
- desc[1].opcode = ipahal_imm_cmd_get_opcode(
- IPA_IMM_CMD_REGISTER_WRITE);
+ desc[1].opcode = ctx_cmd_pyld->opcode;
desc[1].pyld = ctx_cmd_pyld->data;
desc[1].len = ctx_cmd_pyld->len;
}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
index 92ced4f..73a405f 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
@@ -701,6 +701,7 @@
* or kmalloc'ed immediate command parameters/plain old data
* @dma_address: dma mapped address of pyld
* @dma_address_valid: valid field for dma_address
+ * @is_tag_status: flag for IP_PACKET_TAG_STATUS imd cmd
* @len: length of the pyld
* @opcode: for immediate commands
* @callback: IPA client provided completion callback
@@ -715,6 +716,7 @@
skb_frag_t *frag;
dma_addr_t dma_address;
bool dma_address_valid;
+ bool is_tag_status;
u16 len;
u16 opcode;
void (*callback)(void *user1, int user2);
@@ -1069,6 +1071,7 @@
* @ipa_bus_hdl: msm driver handle for the data path bus
* @ctrl: holds the core specific operations based on
* core version (vtable like)
+ * @pkt_init_imm_opcode: opcode for IP_PACKET_INIT imm cmd
* @enable_clock_scaling: clock scaling is enabled ?
* @curr_ipa_clk_rate: IPA current clock rate
* @wcstats: wlan common buffer stats
@@ -1180,6 +1183,7 @@
bool q6_proxy_clk_vote_valid;
u32 ipa_num_pipes;
dma_addr_t pkt_init_imm[IPA3_MAX_NUM_PIPES];
+ u32 pkt_init_imm_opcode;
struct ipa3_wlan_comm_memb wc_memb;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c b/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c
index d98e6b4..e1177ca 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_nat.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -420,7 +420,7 @@
goto bail;
}
- desc[0].opcode = ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_REGISTER_WRITE);
+ desc[0].opcode = nop_cmd_pyld->opcode;
desc[0].type = IPA_IMM_CMD_DESC;
desc[0].callback = NULL;
desc[0].user1 = NULL;
@@ -505,7 +505,7 @@
goto free_nop;
}
- desc[1].opcode = ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_IP_V4_NAT_INIT);
+ desc[1].opcode = cmd_pyld->opcode;
desc[1].type = IPA_IMM_CMD_DESC;
desc[1].callback = NULL;
desc[1].user1 = NULL;
@@ -668,7 +668,7 @@
goto bail;
}
desc[0].type = IPA_IMM_CMD_DESC;
- desc[0].opcode = ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_REGISTER_WRITE);
+ desc[0].opcode = nop_cmd_pyld->opcode;
desc[0].callback = NULL;
desc[0].user1 = NULL;
desc[0].user2 = 0;
@@ -687,7 +687,7 @@
continue;
}
desc[1].type = IPA_IMM_CMD_DESC;
- desc[1].opcode = ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_NAT_DMA);
+ desc[1].opcode = cmd_pyld->opcode;
desc[1].callback = NULL;
desc[1].user1 = NULL;
desc[1].user2 = 0;
@@ -777,7 +777,7 @@
result = -ENOMEM;
goto bail;
}
- desc[0].opcode = ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_REGISTER_WRITE);
+ desc[0].opcode = nop_cmd_pyld->opcode;
desc[0].type = IPA_IMM_CMD_DESC;
desc[0].callback = NULL;
desc[0].user1 = NULL;
@@ -804,7 +804,7 @@
result = -EPERM;
goto destroy_regwrt_imm_cmd;
}
- desc[1].opcode = ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_IP_V4_NAT_INIT);
+ desc[1].opcode = cmd_pyld->opcode;
desc[1].type = IPA_IMM_CMD_DESC;
desc[1].callback = NULL;
desc[1].user1 = NULL;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
index 273877c..cf28986 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_rt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -550,8 +550,7 @@
IPAERR("fail construct register_write imm cmd. IP %d\n", ip);
goto fail_size_valid;
}
- desc[num_cmd].opcode =
- ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_REGISTER_WRITE);
+ desc[num_cmd].opcode = cmd_pyld[num_cmd]->opcode;
desc[num_cmd].pyld = cmd_pyld[num_cmd]->data;
desc[num_cmd].len = cmd_pyld[num_cmd]->len;
desc[num_cmd].type = IPA_IMM_CMD_DESC;
@@ -569,8 +568,7 @@
IPAERR("fail construct dma_shared_mem imm cmd. IP %d\n", ip);
goto fail_imm_cmd_construct;
}
- desc[num_cmd].opcode =
- ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_DMA_SHARED_MEM);
+ desc[num_cmd].opcode = cmd_pyld[num_cmd]->opcode;
desc[num_cmd].pyld = cmd_pyld[num_cmd]->data;
desc[num_cmd].len = cmd_pyld[num_cmd]->len;
desc[num_cmd].type = IPA_IMM_CMD_DESC;
@@ -588,8 +586,7 @@
IPAERR("fail construct dma_shared_mem imm cmd. IP %d\n", ip);
goto fail_imm_cmd_construct;
}
- desc[num_cmd].opcode =
- ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_DMA_SHARED_MEM);
+ desc[num_cmd].opcode = cmd_pyld[num_cmd]->opcode;
desc[num_cmd].pyld = cmd_pyld[num_cmd]->data;
desc[num_cmd].len = cmd_pyld[num_cmd]->len;
desc[num_cmd].type = IPA_IMM_CMD_DESC;
@@ -609,8 +606,7 @@
ip);
goto fail_imm_cmd_construct;
}
- desc[num_cmd].opcode =
- ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_DMA_SHARED_MEM);
+ desc[num_cmd].opcode = cmd_pyld[num_cmd]->opcode;
desc[num_cmd].pyld = cmd_pyld[num_cmd]->data;
desc[num_cmd].len = cmd_pyld[num_cmd]->len;
desc[num_cmd].type = IPA_IMM_CMD_DESC;
@@ -630,8 +626,7 @@
ip);
goto fail_imm_cmd_construct;
}
- desc[num_cmd].opcode =
- ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_DMA_SHARED_MEM);
+ desc[num_cmd].opcode = cmd_pyld[num_cmd]->opcode;
desc[num_cmd].pyld = cmd_pyld[num_cmd]->data;
desc[num_cmd].len = cmd_pyld[num_cmd]->len;
desc[num_cmd].type = IPA_IMM_CMD_DESC;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
index 68d520c..5203088 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
@@ -3369,8 +3369,7 @@
res = -ENOMEM;
goto fail_free_tag_desc;
}
- tag_desc[desc_idx].opcode =
- ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_REGISTER_WRITE);
+ tag_desc[desc_idx].opcode = cmd_pyld->opcode;
tag_desc[desc_idx].pyld = cmd_pyld->data;
tag_desc[desc_idx].len = cmd_pyld->len;
tag_desc[desc_idx].type = IPA_IMM_CMD_DESC;
@@ -3388,8 +3387,7 @@
res = -ENOMEM;
goto fail_free_desc;
}
- tag_desc[desc_idx].opcode =
- ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_IP_PACKET_INIT);
+ tag_desc[desc_idx].opcode = cmd_pyld->opcode;
tag_desc[desc_idx].pyld = cmd_pyld->data;
tag_desc[desc_idx].len = cmd_pyld->len;
tag_desc[desc_idx].type = IPA_IMM_CMD_DESC;
@@ -3406,8 +3404,7 @@
res = -ENOMEM;
goto fail_free_desc;
}
- tag_desc[desc_idx].opcode =
- ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_IP_PACKET_TAG_STATUS);
+ tag_desc[desc_idx].opcode = cmd_pyld->opcode;
tag_desc[desc_idx].pyld = cmd_pyld->data;
tag_desc[desc_idx].len = cmd_pyld->len;
tag_desc[desc_idx].type = IPA_IMM_CMD_DESC;
@@ -3546,8 +3543,7 @@
goto fail_alloc_reg_write_agg_close;
}
- desc[desc_idx].opcode =
- ipahal_imm_cmd_get_opcode(IPA_IMM_CMD_REGISTER_WRITE);
+ desc[desc_idx].opcode = cmd_pyld->opcode;
desc[desc_idx].pyld = cmd_pyld->data;
desc[desc_idx].len = cmd_pyld->len;
desc[desc_idx].type = IPA_IMM_CMD_DESC;
@@ -4335,8 +4331,7 @@
{
struct ipa3_desc desc = {0};
- desc.opcode = ipahal_imm_cmd_get_opcode_param(
- IPA_IMM_CMD_DMA_TASK_32B_ADDR, 1);
+ desc.opcode = ipa3_ctx->dma_task_info.cmd_pyld->opcode;
desc.pyld = ipa3_ctx->dma_task_info.cmd_pyld->data;
desc.len = ipa3_ctx->dma_task_info.cmd_pyld->len;
desc.type = IPA_IMM_CMD_DESC;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c
index fa9c6c8..d35b8a7 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.c
@@ -49,6 +49,8 @@
#define IPAHAL_MEM_ALLOC(__size, __is_atomic_ctx) \
(kzalloc((__size), ((__is_atomic_ctx)?GFP_ATOMIC:GFP_KERNEL)))
+static u16 ipahal_imm_cmd_get_opcode(enum ipahal_imm_cmd_name cmd);
+
static struct ipahal_imm_cmd_pyld *ipa_imm_cmd_construct_dma_task_32b_addr(
enum ipahal_imm_cmd_name cmd, const void *params, bool is_atomic_ctx)
@@ -63,6 +65,8 @@
IPAHAL_ERR("kzalloc err\n");
return pyld;
}
+ /* Currently supports only one packet */
+ pyld->opcode = ipahal_imm_cmd_get_opcode(cmd) + (1 << 8);
pyld->len = sizeof(*data);
data = (struct ipa_imm_cmd_hw_dma_task_32b_addr *)pyld->data;
@@ -101,6 +105,7 @@
IPAHAL_ERR("kzalloc err\n");
return pyld;
}
+ pyld->opcode = ipahal_imm_cmd_get_opcode(cmd);
pyld->len = sizeof(*data);
data = (struct ipa_imm_cmd_hw_ip_packet_tag_status *)pyld->data;
@@ -127,6 +132,7 @@
IPAHAL_ERR("kzalloc err\n");
return pyld;
}
+ pyld->opcode = ipahal_imm_cmd_get_opcode(cmd);
pyld->len = sizeof(*data);
data = (struct ipa_imm_cmd_hw_dma_shared_mem *)pyld->data;
@@ -164,6 +170,61 @@
return pyld;
}
+static struct ipahal_imm_cmd_pyld *ipa_imm_cmd_construct_dma_shared_mem_v_4_0(
+ enum ipahal_imm_cmd_name cmd, const void *params, bool is_atomic_ctx)
+{
+ struct ipahal_imm_cmd_pyld *pyld;
+ struct ipa_imm_cmd_hw_dma_shared_mem_v_4_0 *data;
+ struct ipahal_imm_cmd_dma_shared_mem *mem_params =
+ (struct ipahal_imm_cmd_dma_shared_mem *)params;
+
+ if (unlikely(mem_params->size & ~0xFFFF)) {
+ IPAHAL_ERR("Size is bigger than 16bit width 0x%x\n",
+ mem_params->size);
+ WARN_ON(1);
+ return NULL;
+ }
+ if (unlikely(mem_params->local_addr & ~0xFFFF)) {
+ IPAHAL_ERR("Local addr is bigger than 16bit width 0x%x\n",
+ mem_params->local_addr);
+ WARN_ON(1);
+ return NULL;
+ }
+
+ pyld = IPAHAL_MEM_ALLOC(sizeof(*pyld) + sizeof(*data), is_atomic_ctx);
+ if (unlikely(!pyld)) {
+ WARN_ON(1);
+ return pyld;
+ }
+
+ pyld->opcode = ipahal_imm_cmd_get_opcode(cmd);
+ pyld->len = sizeof(*data);
+ data = (struct ipa_imm_cmd_hw_dma_shared_mem_v_4_0 *)pyld->data;
+
+ data->direction = mem_params->is_read ? 1 : 0;
+ data->clear_after_read = mem_params->clear_after_read;
+ data->size = mem_params->size;
+ data->local_addr = mem_params->local_addr;
+ data->system_addr = mem_params->system_addr;
+ pyld->opcode |= (mem_params->skip_pipeline_clear ? 1 : 0) << 8;
+ switch (mem_params->pipeline_clear_options) {
+ case IPAHAL_HPS_CLEAR:
+ break;
+ case IPAHAL_SRC_GRP_CLEAR:
+ pyld->opcode |= (1 << 9);
+ break;
+ case IPAHAL_FULL_PIPELINE_CLEAR:
+ pyld->opcode |= (2 << 9);
+ break;
+ default:
+ IPAHAL_ERR("unsupported pipline clear option %d\n",
+ mem_params->pipeline_clear_options);
+ WARN_ON(1);
+ };
+
+ return pyld;
+}
+
static struct ipahal_imm_cmd_pyld *ipa_imm_cmd_construct_register_write(
enum ipahal_imm_cmd_name cmd, const void *params, bool is_atomic_ctx)
{
@@ -177,6 +238,7 @@
IPAHAL_ERR("kzalloc err\n");
return pyld;
}
+ pyld->opcode = ipahal_imm_cmd_get_opcode(cmd);
pyld->len = sizeof(*data);
data = (struct ipa_imm_cmd_hw_register_write *)pyld->data;
@@ -209,6 +271,54 @@
return pyld;
}
+static struct ipahal_imm_cmd_pyld *ipa_imm_cmd_construct_register_write_v_4_0(
+ enum ipahal_imm_cmd_name cmd, const void *params, bool is_atomic_ctx)
+{
+ struct ipahal_imm_cmd_pyld *pyld;
+ struct ipa_imm_cmd_hw_register_write_v_4_0 *data;
+ struct ipahal_imm_cmd_register_write *regwrt_params =
+ (struct ipahal_imm_cmd_register_write *)params;
+
+ if (unlikely(regwrt_params->offset & ~0xFFFF)) {
+ IPAHAL_ERR("Offset is bigger than 16bit width 0x%x\n",
+ regwrt_params->offset);
+ WARN_ON(1);
+ return NULL;
+ }
+
+ pyld = IPAHAL_MEM_ALLOC(sizeof(*pyld) + sizeof(*data), is_atomic_ctx);
+ if (unlikely(!pyld)) {
+ WARN_ON(1);
+ return pyld;
+ }
+ pyld->opcode = ipahal_imm_cmd_get_opcode(cmd);
+ pyld->len = sizeof(*data);
+ data = (struct ipa_imm_cmd_hw_register_write_v_4_0 *)pyld->data;
+
+ data->offset = regwrt_params->offset;
+ data->offset_high = regwrt_params->offset >> 16;
+ data->value = regwrt_params->value;
+ data->value_mask = regwrt_params->value_mask;
+
+ pyld->opcode |= (regwrt_params->skip_pipeline_clear ? 1 : 0) << 8;
+ switch (regwrt_params->pipeline_clear_options) {
+ case IPAHAL_HPS_CLEAR:
+ break;
+ case IPAHAL_SRC_GRP_CLEAR:
+ pyld->opcode |= (1 << 9);
+ break;
+ case IPAHAL_FULL_PIPELINE_CLEAR:
+ pyld->opcode |= (2 << 9);
+ break;
+ default:
+ IPAHAL_ERR("unsupported pipline clear option %d\n",
+ regwrt_params->pipeline_clear_options);
+ WARN_ON(1);
+ };
+
+ return pyld;
+}
+
static struct ipahal_imm_cmd_pyld *ipa_imm_cmd_construct_ip_packet_init(
enum ipahal_imm_cmd_name cmd, const void *params, bool is_atomic_ctx)
{
@@ -222,6 +332,7 @@
IPAHAL_ERR("kzalloc err\n");
return pyld;
}
+ pyld->opcode = ipahal_imm_cmd_get_opcode(cmd);
pyld->len = sizeof(*data);
data = (struct ipa_imm_cmd_hw_ip_packet_init *)pyld->data;
@@ -248,6 +359,7 @@
IPAHAL_ERR("kzalloc err\n");
return pyld;
}
+ pyld->opcode = ipahal_imm_cmd_get_opcode(cmd);
pyld->len = sizeof(*data);
data = (struct ipa_imm_cmd_hw_nat_dma *)pyld->data;
@@ -272,6 +384,7 @@
IPAHAL_ERR("kzalloc err\n");
return pyld;
}
+ pyld->opcode = ipahal_imm_cmd_get_opcode(cmd);
pyld->len = sizeof(*data);
data = (struct ipa_imm_cmd_hw_hdr_init_system *)pyld->data;
@@ -293,6 +406,7 @@
IPAHAL_ERR("kzalloc err\n");
return pyld;
}
+ pyld->opcode = ipahal_imm_cmd_get_opcode(cmd);
pyld->len = sizeof(*data);
data = (struct ipa_imm_cmd_hw_hdr_init_local *)pyld->data;
@@ -321,6 +435,7 @@
IPAHAL_ERR("kzalloc err\n");
return pyld;
}
+ pyld->opcode = ipahal_imm_cmd_get_opcode(cmd);
pyld->len = sizeof(*data);
data = (struct ipa_imm_cmd_hw_ip_v6_routing_init *)pyld->data;
@@ -347,6 +462,7 @@
IPAHAL_ERR("kzalloc err\n");
return pyld;
}
+ pyld->opcode = ipahal_imm_cmd_get_opcode(cmd);
pyld->len = sizeof(*data);
data = (struct ipa_imm_cmd_hw_ip_v4_routing_init *)pyld->data;
@@ -373,6 +489,7 @@
IPAHAL_ERR("kzalloc err\n");
return pyld;
}
+ pyld->opcode = ipahal_imm_cmd_get_opcode(cmd);
pyld->len = sizeof(*data);
data = (struct ipa_imm_cmd_hw_ip_v4_nat_init *)pyld->data;
@@ -411,6 +528,7 @@
IPAHAL_ERR("kzalloc err\n");
return pyld;
}
+ pyld->opcode = ipahal_imm_cmd_get_opcode(cmd);
pyld->len = sizeof(*data);
data = (struct ipa_imm_cmd_hw_ip_v6_filter_init *)pyld->data;
@@ -437,6 +555,7 @@
IPAHAL_ERR("kzalloc err\n");
return pyld;
}
+ pyld->opcode = ipahal_imm_cmd_get_opcode(cmd);
pyld->len = sizeof(*data);
data = (struct ipa_imm_cmd_hw_ip_v4_filter_init *)pyld->data;
@@ -455,16 +574,11 @@
* specific IPA version
* @construct - CB to construct imm command payload from abstracted structure
* @opcode - Immediate command OpCode
- * @dyn_op - Does this command supports Dynamic opcode?
- * Some commands opcode are dynamic where the part of the opcode is
- * supplied as param. This flag indicates if the specific command supports it
- * or not.
*/
struct ipahal_imm_cmd_obj {
struct ipahal_imm_cmd_pyld *(*construct)(enum ipahal_imm_cmd_name cmd,
const void *params, bool is_atomic_ctx);
u16 opcode;
- bool dyn_op;
};
/*
@@ -484,43 +598,51 @@
/* IPAv3 */
[IPA_HW_v3_0][IPA_IMM_CMD_IP_V4_FILTER_INIT] = {
ipa_imm_cmd_construct_ip_v4_filter_init,
- 3, false},
+ 3},
[IPA_HW_v3_0][IPA_IMM_CMD_IP_V6_FILTER_INIT] = {
ipa_imm_cmd_construct_ip_v6_filter_init,
- 4, false},
+ 4},
[IPA_HW_v3_0][IPA_IMM_CMD_IP_V4_NAT_INIT] = {
ipa_imm_cmd_construct_ip_v4_nat_init,
- 5, false},
+ 5},
[IPA_HW_v3_0][IPA_IMM_CMD_IP_V4_ROUTING_INIT] = {
ipa_imm_cmd_construct_ip_v4_routing_init,
- 7, false},
+ 7},
[IPA_HW_v3_0][IPA_IMM_CMD_IP_V6_ROUTING_INIT] = {
ipa_imm_cmd_construct_ip_v6_routing_init,
- 8, false},
+ 8},
[IPA_HW_v3_0][IPA_IMM_CMD_HDR_INIT_LOCAL] = {
ipa_imm_cmd_construct_hdr_init_local,
- 9, false},
+ 9},
[IPA_HW_v3_0][IPA_IMM_CMD_HDR_INIT_SYSTEM] = {
ipa_imm_cmd_construct_hdr_init_system,
- 10, false},
+ 10},
[IPA_HW_v3_0][IPA_IMM_CMD_REGISTER_WRITE] = {
ipa_imm_cmd_construct_register_write,
- 12, false},
+ 12},
[IPA_HW_v3_0][IPA_IMM_CMD_NAT_DMA] = {
ipa_imm_cmd_construct_nat_dma,
- 14, false},
+ 14},
[IPA_HW_v3_0][IPA_IMM_CMD_IP_PACKET_INIT] = {
ipa_imm_cmd_construct_ip_packet_init,
- 16, false},
+ 16},
[IPA_HW_v3_0][IPA_IMM_CMD_DMA_TASK_32B_ADDR] = {
ipa_imm_cmd_construct_dma_task_32b_addr,
- 17, true},
+ 17},
[IPA_HW_v3_0][IPA_IMM_CMD_DMA_SHARED_MEM] = {
ipa_imm_cmd_construct_dma_shared_mem,
- 19, false},
+ 19},
[IPA_HW_v3_0][IPA_IMM_CMD_IP_PACKET_TAG_STATUS] = {
ipa_imm_cmd_construct_ip_packet_tag_status,
- 20, false},
+ 20},
+
+ /* IPAv4 */
+ [IPA_HW_v4_0][IPA_IMM_CMD_REGISTER_WRITE] = {
+ ipa_imm_cmd_construct_register_write_v_4_0,
+ 12},
+ [IPA_HW_v4_0][IPA_IMM_CMD_DMA_SHARED_MEM] = {
+ ipa_imm_cmd_construct_dma_shared_mem_v_4_0,
+ 19},
};
/*
@@ -589,7 +711,7 @@
/*
* ipahal_imm_cmd_get_opcode() - Get the fixed opcode of the immediate command
*/
-u16 ipahal_imm_cmd_get_opcode(enum ipahal_imm_cmd_name cmd)
+static u16 ipahal_imm_cmd_get_opcode(enum ipahal_imm_cmd_name cmd)
{
u32 opcode;
@@ -613,63 +735,6 @@
}
/*
- * ipahal_imm_cmd_get_opcode_param() - Get the opcode of an immediate command
- * that supports dynamic opcode
- * Some commands opcode are not totaly fixed, but part of it is
- * a supplied parameter. E.g. Low-Byte is fixed and Hi-Byte
- * is a given parameter.
- * This API will return the composed opcode of the command given
- * the parameter
- * Note: Use this API only for immediate comamnds that support Dynamic Opcode
- */
-u16 ipahal_imm_cmd_get_opcode_param(enum ipahal_imm_cmd_name cmd, int param)
-{
- u32 opcode;
-
- if (cmd >= IPA_IMM_CMD_MAX) {
- IPAHAL_ERR("Invalid immediate command IMM_CMD=%u\n", cmd);
- ipa_assert();
- return -EFAULT;
- }
-
- IPAHAL_DBG_LOW("Get opcode of IMM_CMD=%s\n",
- ipahal_imm_cmd_name_str(cmd));
-
- if (!ipahal_imm_cmd_objs[ipahal_ctx->hw_type][cmd].dyn_op) {
- IPAHAL_ERR("IMM_CMD=%s does not support dynamic opcode\n",
- ipahal_imm_cmd_name_str(cmd));
- ipa_assert();
- return -EFAULT;
- }
-
- /* Currently, dynamic opcode commands uses params to be set
- * on the Opcode hi-byte (lo-byte is fixed).
- * If this to be changed in the future, make the opcode calculation
- * a CB per command
- */
- if (param & ~0xFFFF) {
- IPAHAL_ERR("IMM_CMD=%s opcode param is invalid\n",
- ipahal_imm_cmd_name_str(cmd));
- ipa_assert();
- return -EFAULT;
- }
- opcode = ipahal_imm_cmd_objs[ipahal_ctx->hw_type][cmd].opcode;
- if (opcode == -1) {
- IPAHAL_ERR("Try to get opcode of obsolete IMM_CMD=%s\n",
- ipahal_imm_cmd_name_str(cmd));
- ipa_assert();
- return -EFAULT;
- }
- if (opcode & ~0xFFFF) {
- IPAHAL_ERR("IMM_CMD=%s opcode will be overridden\n",
- ipahal_imm_cmd_name_str(cmd));
- ipa_assert();
- return -EFAULT;
- }
- return (opcode + (param<<8));
-}
-
-/*
* ipahal_construct_imm_cmd() - Construct immdiate command
* This function builds imm cmd bulk that can be be sent to IPA
* The command will be allocated dynamically.
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.h b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.h
index 8f85d4e..e71a48b 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal.h
@@ -259,6 +259,8 @@
* Perform mem copy into or out of the SW area of IPA local mem
* @size: Size in bytes of data to copy. Expected size is up to 2K bytes
* @local_addr: Address in IPA local memory
+ * @clear_after_read: Clear local memory at the end of a read operation allows
+ * atomic read and clear if HPS is clear. Ignore for writes.
* @is_read: Read operation from local memory? If not, then write.
* @skip_pipeline_clear: if to skip pipeline clear waiting (don't wait)
* @pipeline_clear_option: options for pipeline clear waiting
@@ -267,6 +269,7 @@
struct ipahal_imm_cmd_dma_shared_mem {
u32 size;
u32 local_addr;
+ bool clear_after_read;
bool is_read;
bool skip_pipeline_clear;
enum ipahal_pipeline_clear_option pipeline_clear_options;
@@ -322,13 +325,13 @@
/*
* struct ipahal_imm_cmd_pyld - Immediate cmd payload information
* @len: length of the buffer
- * @reserved: padding bytes to make data buffer aligned
+ * @opcode: opcode of the immediate command
* @data: buffer contains the immediate command payload. Buffer goes
* back to back with this structure
*/
struct ipahal_imm_cmd_pyld {
u16 len;
- u16 reserved;
+ u16 opcode;
u8 data[0];
};
@@ -342,23 +345,6 @@
const char *ipahal_imm_cmd_name_str(enum ipahal_imm_cmd_name cmd_name);
/*
- * ipahal_imm_cmd_get_opcode() - Get the fixed opcode of the immediate command
- */
-u16 ipahal_imm_cmd_get_opcode(enum ipahal_imm_cmd_name cmd);
-
-/*
- * ipahal_imm_cmd_get_opcode_param() - Get the opcode of an immediate command
- * that supports dynamic opcode
- * Some commands opcode are not totaly fixed, but part of it is
- * a supplied parameter. E.g. Low-Byte is fixed and Hi-Byte
- * is a given parameter.
- * This API will return the composed opcode of the command given
- * the parameter
- * Note: Use this API only for immediate comamnds that support Dynamic Opcode
- */
-u16 ipahal_imm_cmd_get_opcode_param(enum ipahal_imm_cmd_name cmd, int param);
-
-/*
* ipahal_construct_imm_cmd() - Construct immdiate command
* This function builds imm cmd bulk that can be be sent to IPA
* The command will be allocated dynamically.
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h
index d6a496e..804c554 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_i.h
@@ -278,7 +278,7 @@
* in H/W format.
* Write value to register. Allows reg changes to be synced with data packet
* and other immediate command. Can be used to access the sram
- * @sw_rsvd: Ignored by H/W. My be used by S/W
+ * @sw_rsvd: Ignored by H/W. May be used by S/W
* @skip_pipeline_clear: 0 to wait until IPA pipeline is clear. 1 don't wait
* @offset: offset from IPA base address - Lower 16bit of the IPA reg addr
* @value: value to write to register
@@ -301,6 +301,29 @@
};
/*
+ * struct ipa_imm_cmd_hw_register_write - REGISTER_WRITE command payload
+ * in H/W format.
+ * Write value to register. Allows reg changes to be synced with data packet
+ * and other immediate command. Can be used to access the sram
+ * @sw_rsvd: Ignored by H/W. May be used by S/W
+ * @offset_high: high bits of the Offset field - bits 17-20
+ * @rsvd: reserved - should be set to zero
+ * @offset: offset from IPA base address - Lower 16bit of the IPA reg addr
+ * @value: value to write to register
+ * @value_mask: mask specifying which value bits to write to the register
+ * @rsvd2: reserved - should be set to zero
+ */
+struct ipa_imm_cmd_hw_register_write_v_4_0 {
+ u64 sw_rsvd:11;
+ u64 offset_high:4;
+ u64 rsvd:1;
+ u64 offset:16;
+ u64 value:32;
+ u64 value_mask:32;
+ u64 rsvd2:32;
+};
+
+/*
* struct ipa_imm_cmd_hw_dma_shared_mem - DMA_SHARED_MEM command payload
* in H/W format.
* Perform mem copy into or out of the SW area of IPA local mem
@@ -331,6 +354,31 @@
};
/*
+ * struct ipa_imm_cmd_hw_dma_shared_mem - DMA_SHARED_MEM command payload
+ * in H/W format.
+ * Perform mem copy into or out of the SW area of IPA local mem
+ * @sw_rsvd: Ignored by H/W. My be used by S/W
+ * @size: Size in bytes of data to copy. Expected size is up to 2K bytes
+ * @clear_after_read: Clear local memory at the end of a read operation allows
+ * atomic read and clear if HPS is clear. Ignore for writes.
+ * @local_addr: Address in IPA local memory
+ * @direction: Read or write?
+ * 0: IPA write, Write to local address from system address
+ * 1: IPA read, Read from local address to system address
+ * @rsvd: reserved - should be set to zero
+ * @system_addr: Address in system memory
+ */
+struct ipa_imm_cmd_hw_dma_shared_mem_v_4_0 {
+ u64 sw_rsvd:15;
+ u64 clear_after_read:1;
+ u64 size:16;
+ u64 local_addr:16;
+ u64 direction:1;
+ u64 rsvd:15;
+ u64 system_addr:64;
+};
+
+/*
* struct ipa_imm_cmd_hw_ip_packet_tag_status -
* IP_PACKET_TAG_STATUS command payload in H/W format.
* This cmd is used for to allow SW to track HW processing by setting a TAG