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