Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 89ab8d65 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: ipa3: add an API to unlock PCIe memory regions"

parents dd34da35 73dbb11d
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -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,
+3 −0
Original line number Diff line number Diff line
@@ -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
+52 −38
Original line number Diff line number Diff line
@@ -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;
	}

@@ -4253,7 +4264,7 @@ static int ipa3_tz_unlock_reg(struct ipa3_context *ipa3_ctx)
		return -EFAULT;
	}
	kfree(ipa_tz_unlock_vec);
	}

	return 0;
}

@@ -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;
@@ -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);
		}
+1 −5
Original line number Diff line number Diff line
@@ -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
@@ -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_ */
+1 −0
Original line number Diff line number Diff line
@@ -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