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

Commit 1fa07c8b 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: allocate memory for DMA task on init" into msm-4.9

parents d6c16d9c 6c4bec9a
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -4064,6 +4064,7 @@ static int ipa3_post_init(const struct ipa3_plat_drv_res *resource_p,
	cdev_del(&ipa3_ctx->cdev);
	device_destroy(ipa3_ctx->class, ipa3_ctx->dev_num);
	unregister_chrdev_region(ipa3_ctx->dev_num, 1);
	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);
@@ -4604,6 +4605,13 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p,
		goto fail_rx_pkt_wrapper_cache;
	}

	/* 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++) {
@@ -4744,6 +4752,8 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p,
fail_device_create:
	unregister_chrdev_region(ipa3_ctx->dev_num, 1);
fail_alloc_chrdev_region:
	ipa3_free_dma_task_for_gsi();
fail_dma_task:
	idr_destroy(&ipa3_ctx->ipa_idr);
	kmem_cache_destroy(ipa3_ctx->rx_pkt_wrapper_cache);
fail_rx_pkt_wrapper_cache:
+8 −0
Original line number Diff line number Diff line
@@ -997,6 +997,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
@@ -1206,6 +1211,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;
};

struct ipa3_plat_drv_res {
@@ -1982,4 +1988,6 @@ struct device *ipa3_get_pdev(void);
void ipa3_enable_dcd(void);
void ipa3_disable_prefetch(enum ipa_client_type client);
int ipa3_alloc_common_event_ring(void);
int ipa3_allocate_dma_task_for_gsi(void);
void ipa3_free_dma_task_for_gsi(void);
#endif /* _IPA3_I_H_ */
+47 −31
Original line number Diff line number Diff line
@@ -4216,49 +4216,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");