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

Commit 4abe57b8 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 f6dc08e8 48afa058
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -3056,6 +3056,18 @@ int ipa_disable_wdi3_pipes(int ipa_ep_idx_tx, int ipa_ep_idx_rx)
	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
@@ -398,6 +398,9 @@ struct ipa_api_controller {

	int (*ipa_disable_wdi3_pipes)(int ipa_ep_idx_tx,
		int ipa_ep_idx_rx);

	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
@@ -4492,30 +4492,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;
	}

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

	return 0;
}

@@ -4687,7 +4698,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;
@@ -5465,7 +5479,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
@@ -1034,11 +1034,6 @@ struct ipa3_ready_cb_info {
	void *user_data;
};

struct ipa_tz_unlock_reg_info {
	u64 reg_addr;
	u32 size;
};

struct ipa_dma_task_info {
	struct ipa_mem_buffer mem;
	struct ipahal_imm_cmd_pyld *cmd_pyld;
@@ -2249,4 +2244,5 @@ int ipa3_allocate_dma_task_for_gsi(void);
void ipa3_free_dma_task_for_gsi(void);
int ipa3_set_clock_plan_from_pm(int idx);
void __ipa_gsi_irq_rx_scedule_poll(struct ipa3_sys_context *sys);
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
@@ -4501,6 +4501,7 @@ int ipa3_bind_api_controller(enum ipa_hw_type ipa_hw_type,
	api_ctrl->ipa_disconn_wdi3_pipes = ipa3_disconn_wdi3_pipes;
	api_ctrl->ipa_enable_wdi3_pipes = ipa3_enable_wdi3_pipes;
	api_ctrl->ipa_disable_wdi3_pipes = ipa3_disable_wdi3_pipes;
	api_ctrl->ipa_tz_unlock_reg = ipa3_tz_unlock_reg;

	return 0;
}
Loading