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

Commit 2c0e6b3f authored by Mayank Rana's avatar Mayank Rana
Browse files

usb_bam: Add functionality to update IPA of data and desc FIFO



This change adds functionality to update IPA (i.e. intermediate physical
address) of data and desc FIFO to SPS BAM driver. SPS BAM driver needs
this information to program USB BAM register so USB and USB BAM can access
both FIFOs.

Change-Id: I5986d03842cceb9dbae5e4471639ba89f2d55fe5
Signed-off-by: default avatarMayank Rana <mrana@codeaurora.org>
parent 5027ffca
Loading
Loading
Loading
Loading
+85 −22
Original line number Diff line number Diff line
@@ -292,10 +292,18 @@ static int usb_bam_alloc_buffer(struct usb_bam_pipe_connect *pipe_connect)
	struct usb_bam_ctx_type *ctx = &msm_usb_bam[pipe_connect->bam_type];
	struct sps_mem_buffer *data_buf = &(pipe_connect->data_mem_buf);
	struct sps_mem_buffer *desc_buf = &(pipe_connect->desc_mem_buf);
	struct device *dev = &ctx->usb_bam_pdev->dev;
	struct sg_table data_sgt, desc_sgt;
	dma_addr_t data_iova, desc_iova;
	u32 data_fifo_size;

	pr_debug("%s: data_fifo size:%x desc_fifo_size:%x\n",
				__func__, pipe_connect->data_fifo_size,
				pipe_connect->desc_fifo_size);

	if (dev->parent)
		dev = dev->parent;

	switch (pipe_connect->mem_type) {
	case SPS_PIPE_MEM:
		log_event_dbg("%s: USB BAM using SPS pipe memory\n", __func__);
@@ -337,7 +345,16 @@ static int usb_bam_alloc_buffer(struct usb_bam_pipe_connect *pipe_connect)
			ret = -ENOMEM;
			goto err_exit;
		}

		memset_io(data_buf->base, 0, data_buf->size);
		data_buf->iova = dma_map_resource(dev, data_buf->phys_base,
					data_buf->size, DMA_BIDIRECTIONAL, 0);
		if (dma_mapping_error(dev, data_buf->iova))
			log_event_err("%s(): oci_mem: err mapping data_buf\n",
								__func__);
		log_event_dbg("%s: data_buf:%s virt:%pK, phys:%lx, iova:%lx\n",
			__func__, dev_name(dev), data_buf->base,
			(unsigned long)data_buf->phys_base, data_buf->iova);

		desc_buf->phys_base = pipe_connect->desc_fifo_base_offset +
				ctx->usb_bam_data->usb_bam_fifo_baseaddr;
@@ -351,6 +368,16 @@ static int usb_bam_alloc_buffer(struct usb_bam_pipe_connect *pipe_connect)
			goto err_exit;
		}
		memset_io(desc_buf->base, 0, desc_buf->size);
		desc_buf->iova = dma_map_resource(dev, desc_buf->phys_base,
					desc_buf->size,
					DMA_BIDIRECTIONAL, 0);
		if (dma_mapping_error(dev, desc_buf->iova))
			log_event_err("%s(): oci_mem: err mapping desc_buf\n",
								__func__);

		log_event_dbg("%s: desc_buf:%s virt:%pK, phys:%lx, iova:%lx\n",
			__func__, dev_name(dev), desc_buf->base,
			(unsigned long)desc_buf->phys_base, desc_buf->iova);
		break;
	case SYSTEM_MEM:
		log_event_dbg("%s: USB BAM using system memory\n", __func__);
@@ -362,33 +389,48 @@ static int usb_bam_alloc_buffer(struct usb_bam_pipe_connect *pipe_connect)
		}

		/* BAM would use system memory, allocate FIFOs */
		data_buf->size = pipe_connect->data_fifo_size;
		data_buf->base = dma_alloc_coherent(&ctx->usb_bam_pdev->dev,
				pipe_connect->data_fifo_size,
				&(data_buf->phys_base), GFP_KERNEL);
		data_buf->base = dma_alloc_attrs(dev, data_fifo_size,
						&data_iova, GFP_KERNEL,
						DMA_ATTR_FORCE_CONTIGUOUS);
		if (!data_buf->base) {
			log_event_err("%s: dma_alloc_coherent failed for data fifo\n",
			log_event_err("%s: data_fifo: dma_alloc_attr failed\n",
								__func__);
			ret = -ENOMEM;
			goto err_exit;
		}
		memset(data_buf->base, 0, pipe_connect->data_fifo_size);

		data_buf->iova = data_iova;
		dma_get_sgtable(dev, &data_sgt, data_buf->base, data_buf->iova,
								data_fifo_size);
		data_buf->phys_base = page_to_phys(sg_page(data_sgt.sgl));
		sg_free_table(&data_sgt);
		log_event_dbg("%s: data_buf:%s virt:%pK, phys:%lx, iova:%lx\n",
			__func__, dev_name(dev), data_buf->base,
			(unsigned long)data_buf->phys_base, data_buf->iova);

		desc_buf->size = pipe_connect->desc_fifo_size;
		desc_buf->base = dma_alloc_coherent(&ctx->usb_bam_pdev->dev,
		desc_buf->base = dma_alloc_attrs(dev,
				pipe_connect->desc_fifo_size,
			&(desc_buf->phys_base),
			GFP_KERNEL);
				&desc_iova, GFP_KERNEL,
				DMA_ATTR_FORCE_CONTIGUOUS);
		if (!desc_buf->base) {
			log_event_err("%s: dma_alloc_coherent failed for desc fifo\n",
			log_event_err("%s: desc_fifo: dma_alloc_attr failed\n",
								__func__);
			dma_free_coherent(&ctx->usb_bam_pdev->dev,
					pipe_connect->data_fifo_size,
					data_buf->base, data_buf->phys_base);
			dma_free_attrs(dev, data_fifo_size, data_buf->base,
				data_buf->iova, DMA_ATTR_FORCE_CONTIGUOUS);
			ret = -ENOMEM;
			goto err_exit;
		}
		memset(desc_buf->base, 0, pipe_connect->desc_fifo_size);
		desc_buf->iova = desc_iova;
		dma_get_sgtable(dev, &desc_sgt, desc_buf->base, desc_buf->iova,
								desc_buf->size);
		desc_buf->phys_base = page_to_phys(sg_page(desc_sgt.sgl));
		sg_free_table(&desc_sgt);
		log_event_dbg("%s: desc_buf:%s virt:%pK, phys:%lx, iova:%lx\n",
			__func__, dev_name(dev), desc_buf->base,
			(unsigned long)desc_buf->phys_base, desc_buf->iova);
		break;
	default:
		log_event_err("%s: invalid mem type\n", __func__);
@@ -424,28 +466,36 @@ int usb_bam_free_fifos(enum usb_ctrl cur_bam, u8 idx)
				&ctx->usb_bam_connections[idx];
	struct sps_connect *sps_connection =
				&ctx->usb_bam_sps.sps_connections[idx];
	struct device *dev = &ctx->usb_bam_pdev->dev;
	u32 data_fifo_size;

	pr_debug("%s(): data size:%x desc size:%x\n",
			__func__, sps_connection->data.size,
			sps_connection->desc.size);

	if (dev->parent)
		dev = dev->parent;

	switch (pipe_connect->mem_type) {
	case SYSTEM_MEM:
		log_event_dbg("%s: Freeing system memory used by PIPE\n",
				__func__);
		if (sps_connection->data.phys_base) {
			dma_free_coherent(&ctx->usb_bam_pdev->dev,
					sps_connection->data.size,
		if (sps_connection->data.iova) {
			data_fifo_size = sps_connection->data.size;
			dma_free_attrs(dev, data_fifo_size,
					sps_connection->data.base,
					sps_connection->data.phys_base);
					sps_connection->data.iova,
					DMA_ATTR_FORCE_CONTIGUOUS);
			sps_connection->data.iova = 0;
			sps_connection->data.phys_base = 0;
			pipe_connect->data_mem_buf.base = NULL;
		}
		if (sps_connection->desc.phys_base) {
			dma_free_coherent(&ctx->usb_bam_pdev->dev,
					sps_connection->desc.size,
		if (sps_connection->desc.iova) {
			dma_free_attrs(dev, sps_connection->desc.size,
					sps_connection->desc.base,
					sps_connection->desc.phys_base);
					sps_connection->desc.iova,
					DMA_ATTR_FORCE_CONTIGUOUS);
			sps_connection->desc.iova = 0;
			sps_connection->desc.phys_base = 0;
			pipe_connect->desc_mem_buf.base = NULL;
		}
@@ -453,11 +503,25 @@ int usb_bam_free_fifos(enum usb_ctrl cur_bam, u8 idx)
	case OCI_MEM:
		log_event_dbg("Freeing oci memory used by BAM PIPE\n");
		if (sps_connection->data.base) {
			if (sps_connection->data.iova) {
				dma_unmap_resource(dev,
					sps_connection->data.iova,
					sps_connection->data.size,
					DMA_BIDIRECTIONAL, 0);
				sps_connection->data.iova = 0;
			}
			iounmap(sps_connection->data.base);
			sps_connection->data.base = NULL;
			pipe_connect->data_mem_buf.base = NULL;
		}
		if (sps_connection->desc.base) {
			if (sps_connection->desc.iova) {
				dma_unmap_resource(dev,
					sps_connection->desc.iova,
					sps_connection->desc.size,
					DMA_BIDIRECTIONAL, 0);
				sps_connection->desc.iova = 0;
			}
			iounmap(sps_connection->desc.base);
			sps_connection->desc.base = NULL;
			pipe_connect->desc_mem_buf.base = NULL;
@@ -1118,7 +1182,6 @@ static int usb_bam_init(struct platform_device *pdev)
		props.options |= SPS_BAM_NO_LOCAL_CLK_GATING;

	ret = sps_register_bam_device(&props, &ctx->h_bam);

	if (ret < 0) {
		log_event_err("%s: register bam error %d\n", __func__, ret);
		return -EFAULT;