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

Commit 7eb6f74c authored by Mayank Rana's avatar Mayank Rana
Browse files

USB: Add functionality to map QDSS BAM address space with USB



This change adds functionality to map QDSS BAM address space within
USB context bank, and pass that information to SPS driver.

Change-Id: Idbd13e6faed52be79d36c4bd95674636821ba3ed
Signed-off-by: default avatarMayank Rana <mrana@codeaurora.org>
parent 2f4e4b6d
Loading
Loading
Loading
Loading
+33 −3
Original line number Diff line number Diff line
@@ -535,7 +535,8 @@ int usb_bam_free_fifos(enum usb_ctrl cur_bam, u8 idx)
	return 0;
}

static int connect_pipe(enum usb_ctrl cur_bam, u8 idx, u32 *usb_pipe_idx)
static int connect_pipe(enum usb_ctrl cur_bam, u8 idx, u32 *usb_pipe_idx,
							unsigned long iova)
{
	int ret;
	struct usb_bam_ctx_type *ctx = &msm_usb_bam[cur_bam];
@@ -580,9 +581,11 @@ static int connect_pipe(enum usb_ctrl cur_bam, u8 idx, u32 *usb_pipe_idx)
	if (dir == USB_TO_PEER_PERIPHERAL) {
		sps_connection->mode = SPS_MODE_SRC;
		*usb_pipe_idx = pipe_connect->src_pipe_index;
		sps_connection->dest_iova = iova;
	} else {
		sps_connection->mode = SPS_MODE_DEST;
		*usb_pipe_idx = pipe_connect->dst_pipe_index;
		sps_connection->source_iova = iova;
	}

	sps_connection->data = *data_buf;
@@ -620,7 +623,34 @@ static int disconnect_pipe(enum usb_ctrl cur_bam, u8 idx)
	return 0;
}

int usb_bam_connect(enum usb_ctrl cur_bam, int idx, u32 *bam_pipe_idx)
int get_qdss_bam_info(enum usb_ctrl cur_bam, u8 idx,
			phys_addr_t *p_addr, u32 *bam_size)
{
	int ret = 0;
	struct usb_bam_ctx_type *ctx = &msm_usb_bam[cur_bam];
	struct usb_bam_pipe_connect *pipe_connect =
				&ctx->usb_bam_connections[idx];
	unsigned long peer_bam_handle;

	ret = sps_phy2h(pipe_connect->dst_phy_addr, &peer_bam_handle);
	if (ret) {
		log_event_err("%s: sps_phy2h failed (src BAM) %d\n",
						__func__, ret);
		return ret;
	}

	ret = sps_get_bam_addr(peer_bam_handle, p_addr, bam_size);
	if (ret) {
		log_event_err("%s: sps_get_bam_addr failed%d\n",
						__func__, ret);
		return ret;
	}

	return 0;
}

int usb_bam_connect(enum usb_ctrl cur_bam, int idx, u32 *bam_pipe_idx,
						unsigned long iova)
{
	int ret;
	struct usb_bam_ctx_type *ctx = &msm_usb_bam[cur_bam];
@@ -657,7 +687,7 @@ int usb_bam_connect(enum usb_ctrl cur_bam, int idx, u32 *bam_pipe_idx)
	}
	spin_unlock(&ctx->usb_bam_lock);

	ret = connect_pipe(cur_bam, idx, bam_pipe_idx);
	ret = connect_pipe(cur_bam, idx, bam_pipe_idx, iova);
	if (ret) {
		log_event_err("%s: pipe connection[%d] failure\n",
				__func__, idx);
+3 −0
Original line number Diff line number Diff line
@@ -31,6 +31,9 @@ struct usb_qdss_bam_connect_info {
	u32 peer_pipe_idx;
	unsigned long usb_bam_handle;
	struct sps_mem_buffer *data_fifo;
	unsigned long qdss_bam_iova;
	phys_addr_t qdss_bam_phys;
	u32 qdss_bam_size;
};

struct gqdss {
+32 −2
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/usb_bam.h>
#include <linux/dma-mapping.h>

#include "f_qdss.h"
static int alloc_sps_req(struct usb_ep *data_ep)
@@ -47,6 +48,8 @@ int set_qdss_data_connection(struct f_qdss *qdss, int enable)
	int			idx;
	struct usb_qdss_bam_connect_info bam_info;
	struct usb_gadget *gadget;
	struct device *dev;
	int ret;

	pr_debug("%s\n", __func__);

@@ -57,6 +60,7 @@ int set_qdss_data_connection(struct f_qdss *qdss, int enable)

	gadget = qdss->gadget;
	usb_bam_type = usb_bam_get_bam_type(gadget->name);
	dev = gadget->dev.parent;

	bam_info = qdss->bam_info;
	/* There is only one qdss pipe, so the pipe number can be set to 0 */
@@ -68,6 +72,23 @@ int set_qdss_data_connection(struct f_qdss *qdss, int enable)
	}

	if (enable) {
		ret = get_qdss_bam_info(usb_bam_type, idx,
				&bam_info.qdss_bam_phys,
				&bam_info.qdss_bam_size);
		if (ret) {
			pr_err("%s(): failed to get qdss bam info err(%d)\n",
								__func__, ret);
			return ret;
		}

		bam_info.qdss_bam_iova = dma_map_resource(dev->parent,
				bam_info.qdss_bam_phys, bam_info.qdss_bam_size,
				DMA_BIDIRECTIONAL, 0);
		if (!bam_info.qdss_bam_iova) {
			pr_err("dma_map_resource failed\n");
			return -ENOMEM;
		}

		usb_bam_alloc_fifos(usb_bam_type, idx);
		bam_info.data_fifo =
			kzalloc(sizeof(struct sps_mem_buffer), GFP_KERNEL);
@@ -75,6 +96,12 @@ int set_qdss_data_connection(struct f_qdss *qdss, int enable)
			usb_bam_free_fifos(usb_bam_type, idx);
			return -ENOMEM;
		}

		pr_debug("%s(): qdss_bam: iova:%lx p_addr:%lx size:%x\n",
				__func__, bam_info.qdss_bam_iova,
				(unsigned long)bam_info.qdss_bam_phys,
				bam_info.qdss_bam_size);

		get_bam2bam_connection_info(usb_bam_type, idx,
				&bam_info.usb_bam_pipe_idx,
				NULL, bam_info.data_fifo, NULL);
@@ -87,13 +114,16 @@ int set_qdss_data_connection(struct f_qdss *qdss, int enable)
		init_data(qdss->port.data);

		res = usb_bam_connect(usb_bam_type, idx,
					&(bam_info.usb_bam_pipe_idx));
					&(bam_info.usb_bam_pipe_idx),
					bam_info.qdss_bam_iova);
	} else {
		kfree(bam_info.data_fifo);
		res = usb_bam_disconnect_pipe(usb_bam_type, idx);
		if (res)
			pr_err("usb_bam_disconnection error\n");
		dma_unmap_resource(dev->parent, bam_info.qdss_bam_iova,
				bam_info.qdss_bam_size, DMA_BIDIRECTIONAL, 0);
		usb_bam_free_fifos(usb_bam_type, idx);
		kfree(bam_info.data_fifo);
	}

	return res;
+14 −3
Original line number Diff line number Diff line
@@ -62,10 +62,13 @@ enum usb_bam_pipe_type {
 *
 * @bam_pipe_idx - allocated pipe index.
 *
 * @iova - IPA address of USB peer BAM (i.e. QDSS BAM)
 *
 * @return 0 on success, negative value on error
 *
 */
int usb_bam_connect(enum usb_ctrl bam_type, int idx, u32 *bam_pipe_idx);
int usb_bam_connect(enum usb_ctrl bam_type, int idx, u32 *bam_pipe_idx,
						unsigned long iova);

/**
 * Register a wakeup callback from peer BAM.
@@ -192,9 +195,11 @@ int usb_bam_alloc_fifos(enum usb_ctrl cur_bam, u8 idx);

/* Frees memory for data fifo and descriptor fifos. */
int usb_bam_free_fifos(enum usb_ctrl cur_bam, u8 idx);

int get_qdss_bam_info(enum usb_ctrl cur_bam, u8 idx,
			phys_addr_t *p_addr, u32 *bam_size);
#else
static inline int usb_bam_connect(enum usb_ctrl bam, u8 idx, u32 *bam_pipe_idx)
static inline int usb_bam_connect(enum usb_ctrl bam, u8 idx, u32 *bam_pipe_idx,
							unsigned long iova)
{
	return -ENODEV;
}
@@ -259,6 +264,12 @@ static inline int usb_bam_free_fifos(enum usb_ctrl cur_bam, u8 idx)
{
	return false;
}

static inline int get_qdss_bam_info(enum usb_ctrl cur_bam, u8 idx,
				phys_addr_t *p_addr, u32 *bam_size)
{
	return false;
}
#endif

/* CONFIG_PM */