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

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

Merge "usb_bam: Add functionality to update IPA of data and desc FIFO" into msm-4.14

parents 14b10022 2c0e6b3f
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;