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

Commit 497d7d85 authored by Abhishek Sahu's avatar Abhishek Sahu Committed by Boris Brezillon
Browse files

mtd: nand: qcom: add and initialize QPIC DMA resources



1. QPIC NAND controller uses 3 BAM channels: command, data tx
   and data rx while EBI2 NAND controller uses only single ADM
   channel.
2. CRCI is only required for ADM DMA and it's not required for
   BAM DMA.

Reviewed-by: default avatarArchit Taneja <architt@codeaurora.org>
Signed-off-by: default avatarAbhishek Sahu <absahu@codeaurora.org>
Signed-off-by: default avatarBoris Brezillon <boris.brezillon@free-electrons.com>
parent 8c5d5d6a
Loading
Loading
Loading
Loading
+68 −18
Original line number Diff line number Diff line
@@ -255,9 +255,22 @@ struct qcom_nand_controller {
	struct clk *core_clk;
	struct clk *aon_clk;

	union {
		/* will be used only by QPIC for BAM DMA */
		struct {
			struct dma_chan *tx_chan;
			struct dma_chan *rx_chan;
			struct dma_chan *cmd_chan;
		};

		/* will be used only by EBI2 for ADM DMA */
		struct {
			struct dma_chan *chan;
			unsigned int cmd_crci;
			unsigned int data_crci;
		};
	};

	struct list_head desc_list;

	u8		*data_buffer;
@@ -1989,11 +2002,32 @@ static int qcom_nandc_alloc(struct qcom_nand_controller *nandc)
	if (!nandc->reg_read_buf)
		return -ENOMEM;

	if (nandc->props->is_bam) {
		nandc->tx_chan = dma_request_slave_channel(nandc->dev, "tx");
		if (!nandc->tx_chan) {
			dev_err(nandc->dev, "failed to request tx channel\n");
			return -ENODEV;
		}

		nandc->rx_chan = dma_request_slave_channel(nandc->dev, "rx");
		if (!nandc->rx_chan) {
			dev_err(nandc->dev, "failed to request rx channel\n");
			return -ENODEV;
		}

		nandc->cmd_chan = dma_request_slave_channel(nandc->dev, "cmd");
		if (!nandc->cmd_chan) {
			dev_err(nandc->dev, "failed to request cmd channel\n");
			return -ENODEV;
		}
	} else {
		nandc->chan = dma_request_slave_channel(nandc->dev, "rxtx");
		if (!nandc->chan) {
		dev_err(nandc->dev, "failed to request slave channel\n");
			dev_err(nandc->dev,
				"failed to request slave channel\n");
			return -ENODEV;
		}
	}

	INIT_LIST_HEAD(&nandc->desc_list);
	INIT_LIST_HEAD(&nandc->host_list);
@@ -2005,8 +2039,20 @@ static int qcom_nandc_alloc(struct qcom_nand_controller *nandc)

static void qcom_nandc_unalloc(struct qcom_nand_controller *nandc)
{
	if (nandc->props->is_bam) {
		if (nandc->tx_chan)
			dma_release_channel(nandc->tx_chan);

		if (nandc->rx_chan)
			dma_release_channel(nandc->rx_chan);

		if (nandc->cmd_chan)
			dma_release_channel(nandc->cmd_chan);
	} else {
		if (nandc->chan)
			dma_release_channel(nandc->chan);
	}
}

/* one time setup of a few nand controller registers */
static int qcom_nandc_setup(struct qcom_nand_controller *nandc)
@@ -2146,17 +2192,21 @@ static int qcom_nandc_parse_dt(struct platform_device *pdev)
	struct device_node *np = nandc->dev->of_node;
	int ret;

	ret = of_property_read_u32(np, "qcom,cmd-crci", &nandc->cmd_crci);
	if (!nandc->props->is_bam) {
		ret = of_property_read_u32(np, "qcom,cmd-crci",
					   &nandc->cmd_crci);
		if (ret) {
			dev_err(nandc->dev, "command CRCI unspecified\n");
			return ret;
		}

	ret = of_property_read_u32(np, "qcom,data-crci", &nandc->data_crci);
		ret = of_property_read_u32(np, "qcom,data-crci",
					   &nandc->data_crci);
		if (ret) {
			dev_err(nandc->dev, "data CRCI unspecified\n");
			return ret;
		}
	}

	return 0;
}
@@ -2205,7 +2255,7 @@ static int qcom_nandc_probe(struct platform_device *pdev)

	ret = qcom_nandc_alloc(nandc);
	if (ret)
		return ret;
		goto err_core_clk;

	ret = clk_prepare_enable(nandc->core_clk);
	if (ret)