Loading drivers/platform/msm/ipa/ipa_v3/ipa.c +10 −0 Original line number Diff line number Diff line Loading @@ -4036,6 +4036,7 @@ fail_register_device: unregister_chrdev_region(ipa3_ctx->dev_num, 1); if (ipa3_ctx->pipe_mem_pool) gen_pool_destroy(ipa3_ctx->pipe_mem_pool); ipa3_free_dma_task_for_gsi(); ipa3_destroy_flt_tbl_idrs(); idr_destroy(&ipa3_ctx->ipa_idr); kmem_cache_destroy(ipa3_ctx->rx_pkt_wrapper_cache); Loading Loading @@ -4551,6 +4552,13 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, goto fail_dma_pool; } /* allocate memory for DMA_TASK workaround */ result = ipa3_allocate_dma_task_for_gsi(); if (result) { IPAERR("failed to allocate dma task\n"); goto fail_dma_task; } /* init the various list heads */ INIT_LIST_HEAD(&ipa3_ctx->hdr_tbl.head_hdr_entry_list); for (i = 0; i < IPA_HDR_BIN_MAX; i++) { Loading Loading @@ -4723,6 +4731,8 @@ fail_cdev_add: fail_device_create: unregister_chrdev_region(ipa3_ctx->dev_num, 1); fail_alloc_chrdev_region: ipa3_free_dma_task_for_gsi(); fail_dma_task: if (ipa3_ctx->pipe_mem_pool) gen_pool_destroy(ipa3_ctx->pipe_mem_pool); ipa3_destroy_flt_tbl_idrs(); Loading drivers/platform/msm/ipa/ipa_v3/ipa_i.h +8 −0 Original line number Diff line number Diff line Loading @@ -1027,6 +1027,11 @@ struct ipa_tz_unlock_reg_info { u32 size; }; struct ipa_dma_task_info { struct ipa_mem_buffer mem; struct ipahal_imm_cmd_pyld *cmd_pyld; }; /** * struct ipa3_context - IPA context * @class: pointer to the struct class Loading Loading @@ -1246,6 +1251,7 @@ struct ipa3_context { struct ipa3_smp2p_info smp2p_info; u32 ipa_tz_unlock_reg_num; struct ipa_tz_unlock_reg_info *ipa_tz_unlock_reg; struct ipa_dma_task_info dma_task_info; }; /** Loading Loading @@ -2053,4 +2059,6 @@ int ipa3_get_ntn_stats(struct Ipa3HwStatsNTNInfoData_t *stats); struct dentry *ipa_debugfs_get_root(void); bool ipa3_is_msm_device(void); struct device *ipa3_get_pdev(void); int ipa3_allocate_dma_task_for_gsi(void); void ipa3_free_dma_task_for_gsi(void); #endif /* _IPA3_I_H_ */ drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +47 −31 Original line number Diff line number Diff line Loading @@ -3483,49 +3483,65 @@ void ipa3_suspend_apps_pipes(bool suspend) } } /** * ipa3_inject_dma_task_for_gsi()- Send DMA_TASK to IPA for GSI stop channel * * Send a DMA_TASK of 1B to IPA to unblock GSI channel in STOP_IN_PROG. * Return value: 0 on success, negative otherwise */ int ipa3_inject_dma_task_for_gsi(void) int ipa3_allocate_dma_task_for_gsi(void) { static struct ipa_mem_buffer mem = {0}; struct ipahal_imm_cmd_dma_task_32b_addr cmd = { 0 }; static struct ipahal_imm_cmd_pyld *cmd_pyld; struct ipa3_desc desc = {0}; /* allocate the memory only for the very first time */ if (!mem.base) { IPADBG("Allocate mem\n"); mem.size = IPA_GSI_CHANNEL_STOP_PKT_SIZE; mem.base = dma_alloc_coherent(ipa3_ctx->pdev, mem.size, &mem.phys_base, ipa3_ctx->dma_task_info.mem.size = IPA_GSI_CHANNEL_STOP_PKT_SIZE; ipa3_ctx->dma_task_info.mem.base = dma_alloc_coherent(ipa3_ctx->pdev, ipa3_ctx->dma_task_info.mem.size, &ipa3_ctx->dma_task_info.mem.phys_base, GFP_KERNEL); if (!mem.base) { if (!ipa3_ctx->dma_task_info.mem.base) { IPAERR("no mem\n"); return -EFAULT; } } if (!cmd_pyld) { cmd.flsh = 1; cmd.size1 = mem.size; cmd.addr1 = mem.phys_base; cmd.packet_size = mem.size; cmd_pyld = ipahal_construct_imm_cmd( cmd.size1 = ipa3_ctx->dma_task_info.mem.size; cmd.addr1 = ipa3_ctx->dma_task_info.mem.phys_base; cmd.packet_size = ipa3_ctx->dma_task_info.mem.size; ipa3_ctx->dma_task_info.cmd_pyld = ipahal_construct_imm_cmd( IPA_IMM_CMD_DMA_TASK_32B_ADDR, &cmd, false); if (!cmd_pyld) { if (!ipa3_ctx->dma_task_info.cmd_pyld) { IPAERR("failed to construct dma_task_32b_addr cmd\n"); dma_free_coherent(ipa3_ctx->pdev, ipa3_ctx->dma_task_info.mem.size, ipa3_ctx->dma_task_info.mem.base, ipa3_ctx->dma_task_info.mem.phys_base); memset(&ipa3_ctx->dma_task_info, 0, sizeof(ipa3_ctx->dma_task_info)); return -EFAULT; } return 0; } void ipa3_free_dma_task_for_gsi(void) { dma_free_coherent(ipa3_ctx->pdev, ipa3_ctx->dma_task_info.mem.size, ipa3_ctx->dma_task_info.mem.base, ipa3_ctx->dma_task_info.mem.phys_base); ipahal_destroy_imm_cmd(ipa3_ctx->dma_task_info.cmd_pyld); memset(&ipa3_ctx->dma_task_info, 0, sizeof(ipa3_ctx->dma_task_info)); } /** * ipa3_inject_dma_task_for_gsi()- Send DMA_TASK to IPA for GSI stop channel * * Send a DMA_TASK of 1B to IPA to unblock GSI channel in STOP_IN_PROG. * Return value: 0 on success, negative otherwise */ int ipa3_inject_dma_task_for_gsi(void) { struct ipa3_desc desc = {0}; desc.opcode = ipahal_imm_cmd_get_opcode_param( IPA_IMM_CMD_DMA_TASK_32B_ADDR, 1); desc.pyld = cmd_pyld->data; desc.len = cmd_pyld->len; 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; IPADBG("sending 1B packet to IPA\n"); Loading Loading
drivers/platform/msm/ipa/ipa_v3/ipa.c +10 −0 Original line number Diff line number Diff line Loading @@ -4036,6 +4036,7 @@ fail_register_device: unregister_chrdev_region(ipa3_ctx->dev_num, 1); if (ipa3_ctx->pipe_mem_pool) gen_pool_destroy(ipa3_ctx->pipe_mem_pool); ipa3_free_dma_task_for_gsi(); ipa3_destroy_flt_tbl_idrs(); idr_destroy(&ipa3_ctx->ipa_idr); kmem_cache_destroy(ipa3_ctx->rx_pkt_wrapper_cache); Loading Loading @@ -4551,6 +4552,13 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, goto fail_dma_pool; } /* allocate memory for DMA_TASK workaround */ result = ipa3_allocate_dma_task_for_gsi(); if (result) { IPAERR("failed to allocate dma task\n"); goto fail_dma_task; } /* init the various list heads */ INIT_LIST_HEAD(&ipa3_ctx->hdr_tbl.head_hdr_entry_list); for (i = 0; i < IPA_HDR_BIN_MAX; i++) { Loading Loading @@ -4723,6 +4731,8 @@ fail_cdev_add: fail_device_create: unregister_chrdev_region(ipa3_ctx->dev_num, 1); fail_alloc_chrdev_region: ipa3_free_dma_task_for_gsi(); fail_dma_task: if (ipa3_ctx->pipe_mem_pool) gen_pool_destroy(ipa3_ctx->pipe_mem_pool); ipa3_destroy_flt_tbl_idrs(); Loading
drivers/platform/msm/ipa/ipa_v3/ipa_i.h +8 −0 Original line number Diff line number Diff line Loading @@ -1027,6 +1027,11 @@ struct ipa_tz_unlock_reg_info { u32 size; }; struct ipa_dma_task_info { struct ipa_mem_buffer mem; struct ipahal_imm_cmd_pyld *cmd_pyld; }; /** * struct ipa3_context - IPA context * @class: pointer to the struct class Loading Loading @@ -1246,6 +1251,7 @@ struct ipa3_context { struct ipa3_smp2p_info smp2p_info; u32 ipa_tz_unlock_reg_num; struct ipa_tz_unlock_reg_info *ipa_tz_unlock_reg; struct ipa_dma_task_info dma_task_info; }; /** Loading Loading @@ -2053,4 +2059,6 @@ int ipa3_get_ntn_stats(struct Ipa3HwStatsNTNInfoData_t *stats); struct dentry *ipa_debugfs_get_root(void); bool ipa3_is_msm_device(void); struct device *ipa3_get_pdev(void); int ipa3_allocate_dma_task_for_gsi(void); void ipa3_free_dma_task_for_gsi(void); #endif /* _IPA3_I_H_ */
drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +47 −31 Original line number Diff line number Diff line Loading @@ -3483,49 +3483,65 @@ void ipa3_suspend_apps_pipes(bool suspend) } } /** * ipa3_inject_dma_task_for_gsi()- Send DMA_TASK to IPA for GSI stop channel * * Send a DMA_TASK of 1B to IPA to unblock GSI channel in STOP_IN_PROG. * Return value: 0 on success, negative otherwise */ int ipa3_inject_dma_task_for_gsi(void) int ipa3_allocate_dma_task_for_gsi(void) { static struct ipa_mem_buffer mem = {0}; struct ipahal_imm_cmd_dma_task_32b_addr cmd = { 0 }; static struct ipahal_imm_cmd_pyld *cmd_pyld; struct ipa3_desc desc = {0}; /* allocate the memory only for the very first time */ if (!mem.base) { IPADBG("Allocate mem\n"); mem.size = IPA_GSI_CHANNEL_STOP_PKT_SIZE; mem.base = dma_alloc_coherent(ipa3_ctx->pdev, mem.size, &mem.phys_base, ipa3_ctx->dma_task_info.mem.size = IPA_GSI_CHANNEL_STOP_PKT_SIZE; ipa3_ctx->dma_task_info.mem.base = dma_alloc_coherent(ipa3_ctx->pdev, ipa3_ctx->dma_task_info.mem.size, &ipa3_ctx->dma_task_info.mem.phys_base, GFP_KERNEL); if (!mem.base) { if (!ipa3_ctx->dma_task_info.mem.base) { IPAERR("no mem\n"); return -EFAULT; } } if (!cmd_pyld) { cmd.flsh = 1; cmd.size1 = mem.size; cmd.addr1 = mem.phys_base; cmd.packet_size = mem.size; cmd_pyld = ipahal_construct_imm_cmd( cmd.size1 = ipa3_ctx->dma_task_info.mem.size; cmd.addr1 = ipa3_ctx->dma_task_info.mem.phys_base; cmd.packet_size = ipa3_ctx->dma_task_info.mem.size; ipa3_ctx->dma_task_info.cmd_pyld = ipahal_construct_imm_cmd( IPA_IMM_CMD_DMA_TASK_32B_ADDR, &cmd, false); if (!cmd_pyld) { if (!ipa3_ctx->dma_task_info.cmd_pyld) { IPAERR("failed to construct dma_task_32b_addr cmd\n"); dma_free_coherent(ipa3_ctx->pdev, ipa3_ctx->dma_task_info.mem.size, ipa3_ctx->dma_task_info.mem.base, ipa3_ctx->dma_task_info.mem.phys_base); memset(&ipa3_ctx->dma_task_info, 0, sizeof(ipa3_ctx->dma_task_info)); return -EFAULT; } return 0; } void ipa3_free_dma_task_for_gsi(void) { dma_free_coherent(ipa3_ctx->pdev, ipa3_ctx->dma_task_info.mem.size, ipa3_ctx->dma_task_info.mem.base, ipa3_ctx->dma_task_info.mem.phys_base); ipahal_destroy_imm_cmd(ipa3_ctx->dma_task_info.cmd_pyld); memset(&ipa3_ctx->dma_task_info, 0, sizeof(ipa3_ctx->dma_task_info)); } /** * ipa3_inject_dma_task_for_gsi()- Send DMA_TASK to IPA for GSI stop channel * * Send a DMA_TASK of 1B to IPA to unblock GSI channel in STOP_IN_PROG. * Return value: 0 on success, negative otherwise */ int ipa3_inject_dma_task_for_gsi(void) { struct ipa3_desc desc = {0}; desc.opcode = ipahal_imm_cmd_get_opcode_param( IPA_IMM_CMD_DMA_TASK_32B_ADDR, 1); desc.pyld = cmd_pyld->data; desc.len = cmd_pyld->len; 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; IPADBG("sending 1B packet to IPA\n"); Loading