Loading drivers/platform/msm/ipa/ipa_api.c +12 −0 Original line number Diff line number Diff line Loading @@ -2758,6 +2758,18 @@ int ipa_tear_down_uc_offload_pipes(int ipa_ep_idx_ul, return ret; } /** * ipa_tz_unlock_reg() - Allow AP access to memory regions controlled by TZ */ int ipa_tz_unlock_reg(struct ipa_tz_unlock_reg_info *reg_info, u16 num_regs) { int ret; IPA_API_DISPATCH_RETURN(ipa_tz_unlock_reg, reg_info, num_regs); return ret; } static const struct dev_pm_ops ipa_pm_ops = { .suspend_noirq = ipa_ap_suspend, .resume_noirq = ipa_ap_resume, Loading drivers/platform/msm/ipa/ipa_api.h +3 −0 Original line number Diff line number Diff line Loading @@ -365,6 +365,9 @@ struct ipa_api_controller { int (*ipa_tear_down_uc_offload_pipes)(int ipa_ep_idx_ul, int ipa_ep_idx_dl); int (*ipa_tz_unlock_reg)(struct ipa_tz_unlock_reg_info *reg_info, u16 num_regs); }; #ifdef CONFIG_IPA Loading drivers/platform/msm/ipa/ipa_v3/ipa.c +52 −38 Original line number Diff line number Diff line Loading @@ -4210,30 +4210,41 @@ static ssize_t ipa3_write(struct file *file, const char __user *buf, return count; } static int ipa3_tz_unlock_reg(struct ipa3_context *ipa3_ctx) /** * ipa3_tz_unlock_reg - Unlocks memory regions so that they become accessible * from AP. * @reg_info - Pointer to array of memory regions to unlock * @num_regs - Number of elements in the array * * Converts the input array of regions to a struct that TZ understands and * issues an SCM call. * Also flushes the memory cache to DDR in order to make sure that TZ sees the * correct data structure. * * Returns: 0 on success, negative on failure */ int ipa3_tz_unlock_reg(struct ipa_tz_unlock_reg_info *reg_info, u16 num_regs) { int i, size, ret, resp; struct tz_smmu_ipa_protect_region_iovec_s *ipa_tz_unlock_vec; struct tz_smmu_ipa_protect_region_s cmd_buf; if (ipa3_ctx && ipa3_ctx->ipa_tz_unlock_reg_num > 0) { size = ipa3_ctx->ipa_tz_unlock_reg_num * sizeof(struct tz_smmu_ipa_protect_region_iovec_s); if (reg_info == NULL || num_regs == 0) { IPAERR("Bad parameters\n"); return -EFAULT; } size = num_regs * sizeof(struct tz_smmu_ipa_protect_region_iovec_s); ipa_tz_unlock_vec = kzalloc(PAGE_ALIGN(size), GFP_KERNEL); if (ipa_tz_unlock_vec == NULL) return -ENOMEM; for (i = 0; i < ipa3_ctx->ipa_tz_unlock_reg_num; i++) { ipa_tz_unlock_vec[i].input_addr = ipa3_ctx->ipa_tz_unlock_reg[i].reg_addr ^ (ipa3_ctx->ipa_tz_unlock_reg[i].reg_addr & 0xFFF); ipa_tz_unlock_vec[i].output_addr = ipa3_ctx->ipa_tz_unlock_reg[i].reg_addr ^ (ipa3_ctx->ipa_tz_unlock_reg[i].reg_addr & 0xFFF); ipa_tz_unlock_vec[i].size = ipa3_ctx->ipa_tz_unlock_reg[i].size; for (i = 0; i < num_regs; i++) { ipa_tz_unlock_vec[i].input_addr = reg_info[i].reg_addr ^ (reg_info[i].reg_addr & 0xFFF); ipa_tz_unlock_vec[i].output_addr = reg_info[i].reg_addr ^ (reg_info[i].reg_addr & 0xFFF); ipa_tz_unlock_vec[i].size = reg_info[i].size; ipa_tz_unlock_vec[i].attr = IPA_TZ_UNLOCK_ATTRIBUTE; } Loading @@ -4253,7 +4264,7 @@ static int ipa3_tz_unlock_reg(struct ipa3_context *ipa3_ctx) return -EFAULT; } kfree(ipa_tz_unlock_vec); } return 0; } Loading Loading @@ -4361,7 +4372,10 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, } /* unlock registers for uc */ ipa3_tz_unlock_reg(ipa3_ctx); result = ipa3_tz_unlock_reg(ipa3_ctx->ipa_tz_unlock_reg, ipa3_ctx->ipa_tz_unlock_reg_num); if (result) IPAERR("Failed to unlock memory region using TZ\n"); /* default aggregation parameters */ ipa3_ctx->aggregation_type = IPA_MBIM_16; Loading Loading @@ -5118,7 +5132,7 @@ static int get_ipa_dts_configuration(struct platform_device *pdev, ipa_tz_unlock_reg[pos++]; ipa_drv_res->ipa_tz_unlock_reg[i].size = ipa_tz_unlock_reg[pos++]; IPADBG("tz unlock reg %d: addr 0x%pa size %d\n", i, IPADBG("tz unlock reg %d: addr 0x%pa size %llu\n", i, &ipa_drv_res->ipa_tz_unlock_reg[i].reg_addr, ipa_drv_res->ipa_tz_unlock_reg[i].size); } Loading drivers/platform/msm/ipa/ipa_v3/ipa_i.h +1 −5 Original line number Diff line number Diff line Loading @@ -1066,11 +1066,6 @@ struct ipa3_ready_cb_info { void *user_data; }; struct ipa_tz_unlock_reg_info { u64 reg_addr; u32 size; }; /** * struct ipa3_context - IPA context * @class: pointer to the struct class Loading Loading @@ -2020,4 +2015,5 @@ int ipa3_smmu_map_peer_buff(u64 iova, phys_addr_t phys_addr, u32 size, bool map); struct dentry *ipa_debugfs_get_root(void); bool ipa3_is_msm_device(void); int ipa3_tz_unlock_reg(struct ipa_tz_unlock_reg_info *reg_info, u16 num_regs); #endif /* _IPA3_I_H_ */ drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +1 −0 Original line number Diff line number Diff line Loading @@ -4698,6 +4698,7 @@ int ipa3_bind_api_controller(enum ipa_hw_type ipa_hw_type, api_ctrl->ipa_setup_uc_ntn_pipes = ipa3_setup_uc_ntn_pipes; api_ctrl->ipa_tear_down_uc_offload_pipes = ipa3_tear_down_uc_offload_pipes; api_ctrl->ipa_tz_unlock_reg = ipa3_tz_unlock_reg; return 0; } Loading Loading
drivers/platform/msm/ipa/ipa_api.c +12 −0 Original line number Diff line number Diff line Loading @@ -2758,6 +2758,18 @@ int ipa_tear_down_uc_offload_pipes(int ipa_ep_idx_ul, return ret; } /** * ipa_tz_unlock_reg() - Allow AP access to memory regions controlled by TZ */ int ipa_tz_unlock_reg(struct ipa_tz_unlock_reg_info *reg_info, u16 num_regs) { int ret; IPA_API_DISPATCH_RETURN(ipa_tz_unlock_reg, reg_info, num_regs); return ret; } static const struct dev_pm_ops ipa_pm_ops = { .suspend_noirq = ipa_ap_suspend, .resume_noirq = ipa_ap_resume, Loading
drivers/platform/msm/ipa/ipa_api.h +3 −0 Original line number Diff line number Diff line Loading @@ -365,6 +365,9 @@ struct ipa_api_controller { int (*ipa_tear_down_uc_offload_pipes)(int ipa_ep_idx_ul, int ipa_ep_idx_dl); int (*ipa_tz_unlock_reg)(struct ipa_tz_unlock_reg_info *reg_info, u16 num_regs); }; #ifdef CONFIG_IPA Loading
drivers/platform/msm/ipa/ipa_v3/ipa.c +52 −38 Original line number Diff line number Diff line Loading @@ -4210,30 +4210,41 @@ static ssize_t ipa3_write(struct file *file, const char __user *buf, return count; } static int ipa3_tz_unlock_reg(struct ipa3_context *ipa3_ctx) /** * ipa3_tz_unlock_reg - Unlocks memory regions so that they become accessible * from AP. * @reg_info - Pointer to array of memory regions to unlock * @num_regs - Number of elements in the array * * Converts the input array of regions to a struct that TZ understands and * issues an SCM call. * Also flushes the memory cache to DDR in order to make sure that TZ sees the * correct data structure. * * Returns: 0 on success, negative on failure */ int ipa3_tz_unlock_reg(struct ipa_tz_unlock_reg_info *reg_info, u16 num_regs) { int i, size, ret, resp; struct tz_smmu_ipa_protect_region_iovec_s *ipa_tz_unlock_vec; struct tz_smmu_ipa_protect_region_s cmd_buf; if (ipa3_ctx && ipa3_ctx->ipa_tz_unlock_reg_num > 0) { size = ipa3_ctx->ipa_tz_unlock_reg_num * sizeof(struct tz_smmu_ipa_protect_region_iovec_s); if (reg_info == NULL || num_regs == 0) { IPAERR("Bad parameters\n"); return -EFAULT; } size = num_regs * sizeof(struct tz_smmu_ipa_protect_region_iovec_s); ipa_tz_unlock_vec = kzalloc(PAGE_ALIGN(size), GFP_KERNEL); if (ipa_tz_unlock_vec == NULL) return -ENOMEM; for (i = 0; i < ipa3_ctx->ipa_tz_unlock_reg_num; i++) { ipa_tz_unlock_vec[i].input_addr = ipa3_ctx->ipa_tz_unlock_reg[i].reg_addr ^ (ipa3_ctx->ipa_tz_unlock_reg[i].reg_addr & 0xFFF); ipa_tz_unlock_vec[i].output_addr = ipa3_ctx->ipa_tz_unlock_reg[i].reg_addr ^ (ipa3_ctx->ipa_tz_unlock_reg[i].reg_addr & 0xFFF); ipa_tz_unlock_vec[i].size = ipa3_ctx->ipa_tz_unlock_reg[i].size; for (i = 0; i < num_regs; i++) { ipa_tz_unlock_vec[i].input_addr = reg_info[i].reg_addr ^ (reg_info[i].reg_addr & 0xFFF); ipa_tz_unlock_vec[i].output_addr = reg_info[i].reg_addr ^ (reg_info[i].reg_addr & 0xFFF); ipa_tz_unlock_vec[i].size = reg_info[i].size; ipa_tz_unlock_vec[i].attr = IPA_TZ_UNLOCK_ATTRIBUTE; } Loading @@ -4253,7 +4264,7 @@ static int ipa3_tz_unlock_reg(struct ipa3_context *ipa3_ctx) return -EFAULT; } kfree(ipa_tz_unlock_vec); } return 0; } Loading Loading @@ -4361,7 +4372,10 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, } /* unlock registers for uc */ ipa3_tz_unlock_reg(ipa3_ctx); result = ipa3_tz_unlock_reg(ipa3_ctx->ipa_tz_unlock_reg, ipa3_ctx->ipa_tz_unlock_reg_num); if (result) IPAERR("Failed to unlock memory region using TZ\n"); /* default aggregation parameters */ ipa3_ctx->aggregation_type = IPA_MBIM_16; Loading Loading @@ -5118,7 +5132,7 @@ static int get_ipa_dts_configuration(struct platform_device *pdev, ipa_tz_unlock_reg[pos++]; ipa_drv_res->ipa_tz_unlock_reg[i].size = ipa_tz_unlock_reg[pos++]; IPADBG("tz unlock reg %d: addr 0x%pa size %d\n", i, IPADBG("tz unlock reg %d: addr 0x%pa size %llu\n", i, &ipa_drv_res->ipa_tz_unlock_reg[i].reg_addr, ipa_drv_res->ipa_tz_unlock_reg[i].size); } Loading
drivers/platform/msm/ipa/ipa_v3/ipa_i.h +1 −5 Original line number Diff line number Diff line Loading @@ -1066,11 +1066,6 @@ struct ipa3_ready_cb_info { void *user_data; }; struct ipa_tz_unlock_reg_info { u64 reg_addr; u32 size; }; /** * struct ipa3_context - IPA context * @class: pointer to the struct class Loading Loading @@ -2020,4 +2015,5 @@ int ipa3_smmu_map_peer_buff(u64 iova, phys_addr_t phys_addr, u32 size, bool map); struct dentry *ipa_debugfs_get_root(void); bool ipa3_is_msm_device(void); int ipa3_tz_unlock_reg(struct ipa_tz_unlock_reg_info *reg_info, u16 num_regs); #endif /* _IPA3_I_H_ */
drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +1 −0 Original line number Diff line number Diff line Loading @@ -4698,6 +4698,7 @@ int ipa3_bind_api_controller(enum ipa_hw_type ipa_hw_type, api_ctrl->ipa_setup_uc_ntn_pipes = ipa3_setup_uc_ntn_pipes; api_ctrl->ipa_tear_down_uc_offload_pipes = ipa3_tear_down_uc_offload_pipes; api_ctrl->ipa_tz_unlock_reg = ipa3_tz_unlock_reg; return 0; } Loading