All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 00/16] Add QCOM QPIC NAND support
@ 2017-08-17 12:07 Abhishek Sahu
  2017-08-17 12:07 ` [PATCH v5 01/16] mtd: nand: qcom: DMA mapping support for register read buffer Abhishek Sahu
                   ` (16 more replies)
  0 siblings, 17 replies; 26+ messages in thread
From: Abhishek Sahu @ 2017-08-17 12:07 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: David Woodhouse, Brian Norris, Marek Vasut, Richard Weinberger,
	Cyrille Pitchen, linux-arm-msm, linux-kernel, linux-mtd,
	Andy Gross, Archit Taneja, Sricharan R, Abhishek Sahu

* v5:

1. Removed the patches already applied to linux-next and rebased the
   remaining patches on [3]
2. Addressed the review comments in v4 and Added Archit Reviewed
   by tag.

[3] http://git.infradead.org/l2-mtd.git/shortlog/refs/heads/nand/next

* v4:

1. Added Acked-by from Rob for DT documentation patches
2. Removed ipq8074 compatible string from ipq4019 DT example.
2. Used the BIT macro for NAND_CMD_VLD bits and consistent names
   as suggested by Boris in v3.

* v3:

1. Removed the patches already applied to linux-next and
   rebased the remaining patches on [1]
2. Reordered the patches and put the BAM DMA changes [2]
   dependent patches and compatible string patches in last
3. Removed the register offsets array and used the dev_cmd offsets
4. Changed some macro names to small letters for better code readability
5. Changed the compatible string to SoC specific
6. Did minor code changes for adding comment, error handling, structure names
7. Combined raw write (patch#18) and passing flag parameter (patch#22) patch
   into one
8. Made separate patch for compatible string and NAND properties
9. Made separate patch for BAM command descriptor and data descriptors handling
10. Changed commit message for some of the patches
11. Addressed review comments given in v2
12. Added Reviewed-by of Archit for some of the patches from v2
13. All the MTD tests are working fine for IPQ8064 AP148, IPQ4019 DK04 and
    IPQ8074 HK01 boards for v3 patches

[1] http://git.infradead.org/l2-mtd.git/shortlog/refs/heads/nand/next
[2] http://www.spinics.net/lists/dmaengine/msg13662.html

* v2:

1. Addressed the review comments given in v1
2. Removed the DMA coherent buffer for register read and used
   streaming DMA API’s
3. Reorganized the NAND read and write functions
4. Separated patch for driver and documentation changes
5. Changed the compatible string for EBI2

* v1:

http://www.spinics.net/lists/devicetree/msg183706.html


Abhishek Sahu (16):
  mtd: nand: qcom: DMA mapping support for register read buffer
  mtd: nand: qcom: allocate BAM transaction
  mtd: nand: qcom: add BAM DMA descriptor handling
  mtd: nand: qcom: support for passing flags in DMA helper functions
  mtd: nand: qcom: support for read location registers
  mtd: nand: qcom: erased codeword detection configuration
  mtd: nand: qcom: enable BAM or ADM mode
  mtd: nand: qcom: QPIC data descriptors handling
  mtd: nand: qcom: support for different DEV_CMD register offsets
  mtd: nand: qcom: add command elements in BAM transaction
  mtd: nand: qcom: support for command descriptor formation
  dt-bindings: qcom_nandc: fix the ipq806x device tree example
  dt-bindings: qcom_nandc: IPQ4019 QPIC NAND documentation
  dt-bindings: qcom_nandc: IPQ8074 QPIC NAND documentation
  mtd: nand: qcom: support for IPQ4019 QPIC NAND controller
  mtd: nand: qcom: Support for IPQ8074 QPIC NAND controller

 .../devicetree/bindings/mtd/qcom_nandc.txt         |  63 +-
 drivers/mtd/nand/qcom_nandc.c                      | 746 ++++++++++++++++++---
 2 files changed, 722 insertions(+), 87 deletions(-)

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v5 01/16] mtd: nand: qcom: DMA mapping support for register read buffer
  2017-08-17 12:07 [PATCH v5 00/16] Add QCOM QPIC NAND support Abhishek Sahu
@ 2017-08-17 12:07 ` Abhishek Sahu
  2017-08-17 12:07 ` [PATCH v5 02/16] mtd: nand: qcom: allocate BAM transaction Abhishek Sahu
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Abhishek Sahu @ 2017-08-17 12:07 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: David Woodhouse, Brian Norris, Marek Vasut, Richard Weinberger,
	Cyrille Pitchen, linux-arm-msm, linux-kernel, linux-mtd,
	Andy Gross, Archit Taneja, Sricharan R, Abhishek Sahu

The EBI2 NAND controller directly remaps register read buffer with
dma_map_sg and DMA address of this buffer will be passed to DMA
API’s. While, on QPIC NAND controller, which uses BAM DMA, we read
the controller registers by preparing a BAM command descriptor. This
command descriptor requires the

  - controller register address
  - the DMA address in which we want to store the value read
    back from the controller register.

This command descriptor will be remapped with dma_map_sg
and its DMA address will be passed to DMA API’s. Therefore,
it's required that we also map our register read buffer for
DMA (using dma_map_single). We use the returned DMA address
for preparing entries in our command descriptor.

This patch adds the DMA mapping support for register read
buffer. This buffer will be DMA mapped during allocation
time. Before starting of any operation, this buffer will
be synced for device operation and after operation
completion, it will be synced again for CPU.

Reviewed-by: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---

* Changes from v4: None

 drivers/mtd/nand/qcom_nandc.c | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index 59b764a..590fc1d 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -234,6 +234,7 @@ struct nandc_regs {
  *				by upper layers directly
  * @buf_size/count/start:	markers for chip->read_buf/write_buf functions
  * @reg_read_buf:		local buffer for reading back registers via DMA
+ * @reg_read_dma:		contains dma address for register read buffer
  * @reg_read_pos:		marker for data read in reg_read_buf
  *
  * @regs:			a contiguous chunk of memory for DMA register
@@ -279,6 +280,7 @@ struct qcom_nand_controller {
 	int		buf_start;
 
 	__le32 *reg_read_buf;
+	dma_addr_t reg_read_dma;
 	int reg_read_pos;
 
 	struct nandc_regs *regs;
@@ -371,6 +373,24 @@ static inline void nandc_write(struct qcom_nand_controller *nandc, int offset,
 	iowrite32(val, nandc->base + offset);
 }
 
+static inline void nandc_read_buffer_sync(struct qcom_nand_controller *nandc,
+					  bool is_cpu)
+{
+	if (!nandc->props->is_bam)
+		return;
+
+	if (is_cpu)
+		dma_sync_single_for_cpu(nandc->dev, nandc->reg_read_dma,
+					MAX_REG_RD *
+					sizeof(*nandc->reg_read_buf),
+					DMA_FROM_DEVICE);
+	else
+		dma_sync_single_for_device(nandc->dev, nandc->reg_read_dma,
+					   MAX_REG_RD *
+					   sizeof(*nandc->reg_read_buf),
+					   DMA_FROM_DEVICE);
+}
+
 static __le32 *offset_to_nandc_reg(struct nandc_regs *regs, int offset)
 {
 	switch (offset) {
@@ -854,6 +874,7 @@ static void free_descs(struct qcom_nand_controller *nandc)
 static void clear_read_regs(struct qcom_nand_controller *nandc)
 {
 	nandc->reg_read_pos = 0;
+	nandc_read_buffer_sync(nandc, false);
 }
 
 static void pre_command(struct qcom_nand_host *host, int command)
@@ -883,6 +904,7 @@ static void parse_erase_write_errors(struct qcom_nand_host *host, int command)
 	int i;
 
 	num_cw = command == NAND_CMD_PAGEPROG ? ecc->steps : 1;
+	nandc_read_buffer_sync(nandc, true);
 
 	for (i = 0; i < num_cw; i++) {
 		u32 flash_status = le32_to_cpu(nandc->reg_read_buf[i]);
@@ -904,6 +926,7 @@ static void post_command(struct qcom_nand_host *host, int command)
 
 	switch (command) {
 	case NAND_CMD_READID:
+		nandc_read_buffer_sync(nandc, true);
 		memcpy(nandc->data_buffer, nandc->reg_read_buf,
 		       nandc->buf_count);
 		break;
@@ -1067,6 +1090,7 @@ static int parse_read_errors(struct qcom_nand_host *host, u8 *data_buf,
 	int i;
 
 	buf = (struct read_stats *)nandc->reg_read_buf;
+	nandc_read_buffer_sync(nandc, true);
 
 	for (i = 0; i < ecc->steps; i++, buf++) {
 		u32 flash, buffer, erased_cw;
@@ -2003,6 +2027,16 @@ static int qcom_nandc_alloc(struct qcom_nand_controller *nandc)
 		return -ENOMEM;
 
 	if (nandc->props->is_bam) {
+		nandc->reg_read_dma =
+			dma_map_single(nandc->dev, nandc->reg_read_buf,
+				       MAX_REG_RD *
+				       sizeof(*nandc->reg_read_buf),
+				       DMA_FROM_DEVICE);
+		if (dma_mapping_error(nandc->dev, nandc->reg_read_dma)) {
+			dev_err(nandc->dev, "failed to DMA MAP reg buffer\n");
+			return -EIO;
+		}
+
 		nandc->tx_chan = dma_request_slave_channel(nandc->dev, "tx");
 		if (!nandc->tx_chan) {
 			dev_err(nandc->dev, "failed to request tx channel\n");
@@ -2040,6 +2074,12 @@ 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 (!dma_mapping_error(nandc->dev, nandc->reg_read_dma))
+			dma_unmap_single(nandc->dev, nandc->reg_read_dma,
+					 MAX_REG_RD *
+					 sizeof(*nandc->reg_read_buf),
+					 DMA_FROM_DEVICE);
+
 		if (nandc->tx_chan)
 			dma_release_channel(nandc->tx_chan);
 
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v5 02/16] mtd: nand: qcom: allocate BAM transaction
  2017-08-17 12:07 [PATCH v5 00/16] Add QCOM QPIC NAND support Abhishek Sahu
  2017-08-17 12:07 ` [PATCH v5 01/16] mtd: nand: qcom: DMA mapping support for register read buffer Abhishek Sahu
@ 2017-08-17 12:07 ` Abhishek Sahu
  2017-08-17 12:07 ` [PATCH v5 03/16] mtd: nand: qcom: add BAM DMA descriptor handling Abhishek Sahu
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Abhishek Sahu @ 2017-08-17 12:07 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: David Woodhouse, Brian Norris, Marek Vasut, Richard Weinberger,
	Cyrille Pitchen, linux-arm-msm, linux-kernel, linux-mtd,
	Andy Gross, Archit Taneja, Sricharan R, Abhishek Sahu

- The BAM transaction is the core data structure which will be used
  for all the data transfers in QPIC NAND. Since the core framework
  in nand_base.c is serializing all the NAND requests so allocating
  BAM transaction before every transfer will be overhead. The memory
  for it be allocated during probe time and before every transfer,
  it will be cleared.

- The BAM transaction contains the array of
  command and data scatter gather list and indexes. For
  every transfer, all the resource will be taken from BAM
  transaction.

- The size of the buffer used for BAM transactions
  is calculated based on the NAND device with the maximum page size,
  among all the devices connected to the
  controller.

Reviewed-by: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---

* Changes from v4: None

 drivers/mtd/nand/qcom_nandc.c | 94 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 94 insertions(+)

diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index 590fc1d..4f8306e 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -177,6 +177,32 @@
 #define	ECC_BCH_4BIT	BIT(2)
 #define	ECC_BCH_8BIT	BIT(3)
 
+#define QPIC_PER_CW_CMD_SGL		32
+#define QPIC_PER_CW_DATA_SGL		8
+
+/*
+ * This data type corresponds to the BAM transaction which will be used for all
+ * NAND transfers.
+ * @cmd_sgl - sgl for NAND BAM command pipe
+ * @data_sgl - sgl for NAND BAM consumer/producer pipe
+ * @cmd_sgl_pos - current index in command sgl.
+ * @cmd_sgl_start - start index in command sgl.
+ * @tx_sgl_pos - current index in data sgl for tx.
+ * @tx_sgl_start - start index in data sgl for tx.
+ * @rx_sgl_pos - current index in data sgl for rx.
+ * @rx_sgl_start - start index in data sgl for rx.
+ */
+struct bam_transaction {
+	struct scatterlist *cmd_sgl;
+	struct scatterlist *data_sgl;
+	u32 cmd_sgl_pos;
+	u32 cmd_sgl_start;
+	u32 tx_sgl_pos;
+	u32 tx_sgl_start;
+	u32 rx_sgl_pos;
+	u32 rx_sgl_start;
+};
+
 struct desc_info {
 	struct list_head node;
 
@@ -243,6 +269,8 @@ struct nandc_regs {
  * @cmd1/vld:			some fixed controller register values
  * @props:			properties of current NAND controller,
  *				initialized via DT match data
+ * @max_cwperpage:		maximum QPIC codewords required. calculated
+ *				from all connected NAND devices pagesize
  */
 struct qcom_nand_controller {
 	struct nand_hw_control controller;
@@ -273,11 +301,13 @@ struct qcom_nand_controller {
 	};
 
 	struct list_head desc_list;
+	struct bam_transaction *bam_txn;
 
 	u8		*data_buffer;
 	int		buf_size;
 	int		buf_count;
 	int		buf_start;
+	unsigned int	max_cwperpage;
 
 	__le32 *reg_read_buf;
 	dma_addr_t reg_read_dma;
@@ -350,6 +380,44 @@ struct qcom_nandc_props {
 	bool is_bam;
 };
 
+/* Frees the BAM transaction memory */
+static void free_bam_transaction(struct qcom_nand_controller *nandc)
+{
+	struct bam_transaction *bam_txn = nandc->bam_txn;
+
+	devm_kfree(nandc->dev, bam_txn);
+}
+
+/* Allocates and Initializes the BAM transaction */
+static struct bam_transaction *
+alloc_bam_transaction(struct qcom_nand_controller *nandc)
+{
+	struct bam_transaction *bam_txn;
+	size_t bam_txn_size;
+	unsigned int num_cw = nandc->max_cwperpage;
+	void *bam_txn_buf;
+
+	bam_txn_size =
+		sizeof(*bam_txn) + num_cw *
+		((sizeof(*bam_txn->cmd_sgl) * QPIC_PER_CW_CMD_SGL) +
+		(sizeof(*bam_txn->data_sgl) * QPIC_PER_CW_DATA_SGL));
+
+	bam_txn_buf = devm_kzalloc(nandc->dev, bam_txn_size, GFP_KERNEL);
+	if (!bam_txn_buf)
+		return NULL;
+
+	bam_txn = bam_txn_buf;
+	bam_txn_buf += sizeof(*bam_txn);
+
+	bam_txn->cmd_sgl = bam_txn_buf;
+	bam_txn_buf +=
+		sizeof(*bam_txn->cmd_sgl) * QPIC_PER_CW_CMD_SGL * num_cw;
+
+	bam_txn->data_sgl = bam_txn_buf;
+
+	return bam_txn;
+}
+
 static inline struct qcom_nand_host *to_qcom_nand_host(struct nand_chip *chip)
 {
 	return container_of(chip, struct qcom_nand_host, chip);
@@ -1920,6 +1988,8 @@ static int qcom_nand_host_setup(struct qcom_nand_host *host)
 	mtd_set_ooblayout(mtd, &qcom_nand_ooblayout_ops);
 
 	cwperpage = mtd->writesize / ecc->size;
+	nandc->max_cwperpage = max_t(unsigned int, nandc->max_cwperpage,
+				     cwperpage);
 
 	/*
 	 * DATA_UD_BYTES varies based on whether the read/write command protects
@@ -2054,6 +2124,20 @@ static int qcom_nandc_alloc(struct qcom_nand_controller *nandc)
 			dev_err(nandc->dev, "failed to request cmd channel\n");
 			return -ENODEV;
 		}
+
+		/*
+		 * Initially allocate BAM transaction to read ONFI param page.
+		 * After detecting all the devices, this BAM transaction will
+		 * be freed and the next BAM tranasction will be allocated with
+		 * maximum codeword size
+		 */
+		nandc->max_cwperpage = 1;
+		nandc->bam_txn = alloc_bam_transaction(nandc);
+		if (!nandc->bam_txn) {
+			dev_err(nandc->dev,
+				"failed to allocate bam transaction\n");
+			return -ENOMEM;
+		}
 	} else {
 		nandc->chan = dma_request_slave_channel(nandc->dev, "rxtx");
 		if (!nandc->chan) {
@@ -2211,6 +2295,16 @@ static int qcom_probe_nand_devices(struct qcom_nand_controller *nandc)
 	if (list_empty(&nandc->host_list))
 		return -ENODEV;
 
+	if (nandc->props->is_bam) {
+		free_bam_transaction(nandc);
+		nandc->bam_txn = alloc_bam_transaction(nandc);
+		if (!nandc->bam_txn) {
+			dev_err(nandc->dev,
+				"failed to allocate bam transaction\n");
+			return -ENOMEM;
+		}
+	}
+
 	list_for_each_entry_safe(host, tmp, &nandc->host_list, node) {
 		ret = qcom_nand_mtd_register(nandc, host, child);
 		if (ret) {
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v5 03/16] mtd: nand: qcom: add BAM DMA descriptor handling
  2017-08-17 12:07 [PATCH v5 00/16] Add QCOM QPIC NAND support Abhishek Sahu
  2017-08-17 12:07 ` [PATCH v5 01/16] mtd: nand: qcom: DMA mapping support for register read buffer Abhishek Sahu
  2017-08-17 12:07 ` [PATCH v5 02/16] mtd: nand: qcom: allocate BAM transaction Abhishek Sahu
@ 2017-08-17 12:07 ` Abhishek Sahu
  2017-08-17 12:07   ` Abhishek Sahu
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Abhishek Sahu @ 2017-08-17 12:07 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: David Woodhouse, Brian Norris, Marek Vasut, Richard Weinberger,
	Cyrille Pitchen, linux-arm-msm, linux-kernel, linux-mtd,
	Andy Gross, Archit Taneja, Sricharan R, Abhishek Sahu

1. prepare_bam_async_desc is the function which will call
   all the DMA API’s. It will fetch the outstanding scatter gather
   list for passed channel and will do the DMA descriptor formation.
   The DMA flag is dependent upon the type of channel.

2. For ADM DMA, the descriptor is being formed for every DMA
   request so its sgl count will be always 1 while in BAM DMA, the
   clubbing of descriptor is being done to increase throughput.

3. ADM DMA uses only one channel while in BAM DMA, data descriptors
   will be submitted to tx channel (for write) or rx channel
   (for read) and all the registers read/write descriptors in
   command channel.

Reviewed-by: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---

* Changes from v4: None

 drivers/mtd/nand/qcom_nandc.c | 148 ++++++++++++++++++++++++++++++++++++++----
 1 file changed, 136 insertions(+), 12 deletions(-)

diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index 4f8306e..f52a692 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -203,11 +203,27 @@ struct bam_transaction {
 	u32 rx_sgl_start;
 };
 
+/*
+ * This data type corresponds to the nand dma descriptor
+ * @list - list for desc_info
+ * @dir - DMA transfer direction
+ * @adm_sgl - sgl which will be used for single sgl dma descriptor. Only used by
+ *	      ADM
+ * @bam_sgl - sgl which will be used for dma descriptor. Only used by BAM
+ * @sgl_cnt - number of SGL in bam_sgl. Only used by BAM
+ * @dma_desc - low level DMA engine descriptor
+ */
 struct desc_info {
 	struct list_head node;
 
 	enum dma_data_direction dir;
-	struct scatterlist sgl;
+	union {
+		struct scatterlist adm_sgl;
+		struct {
+			struct scatterlist *bam_sgl;
+			int sgl_cnt;
+		};
+	};
 	struct dma_async_tx_descriptor *dma_desc;
 };
 
@@ -568,9 +584,78 @@ static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read)
 	nandc_set_reg(nandc, NAND_EXEC_CMD, 1);
 }
 
-static int prep_dma_desc(struct qcom_nand_controller *nandc, bool read,
-			 int reg_off, const void *vaddr, int size,
-			 bool flow_control)
+/*
+ * Maps the scatter gather list for DMA transfer and forms the DMA descriptor
+ * for BAM. This descriptor will be added in the NAND DMA descriptor queue
+ * which will be submitted to DMA engine.
+ */
+static int prepare_bam_async_desc(struct qcom_nand_controller *nandc,
+				  struct dma_chan *chan,
+				  unsigned long flags)
+{
+	struct desc_info *desc;
+	struct scatterlist *sgl;
+	unsigned int sgl_cnt;
+	int ret;
+	struct bam_transaction *bam_txn = nandc->bam_txn;
+	enum dma_transfer_direction dir_eng;
+	struct dma_async_tx_descriptor *dma_desc;
+
+	desc = kzalloc(sizeof(*desc), GFP_KERNEL);
+	if (!desc)
+		return -ENOMEM;
+
+	if (chan == nandc->cmd_chan) {
+		sgl = &bam_txn->cmd_sgl[bam_txn->cmd_sgl_start];
+		sgl_cnt = bam_txn->cmd_sgl_pos - bam_txn->cmd_sgl_start;
+		bam_txn->cmd_sgl_start = bam_txn->cmd_sgl_pos;
+		dir_eng = DMA_MEM_TO_DEV;
+		desc->dir = DMA_TO_DEVICE;
+	} else if (chan == nandc->tx_chan) {
+		sgl = &bam_txn->data_sgl[bam_txn->tx_sgl_start];
+		sgl_cnt = bam_txn->tx_sgl_pos - bam_txn->tx_sgl_start;
+		bam_txn->tx_sgl_start = bam_txn->tx_sgl_pos;
+		dir_eng = DMA_MEM_TO_DEV;
+		desc->dir = DMA_TO_DEVICE;
+	} else {
+		sgl = &bam_txn->data_sgl[bam_txn->rx_sgl_start];
+		sgl_cnt = bam_txn->rx_sgl_pos - bam_txn->rx_sgl_start;
+		bam_txn->rx_sgl_start = bam_txn->rx_sgl_pos;
+		dir_eng = DMA_DEV_TO_MEM;
+		desc->dir = DMA_FROM_DEVICE;
+	}
+
+	sg_mark_end(sgl + sgl_cnt - 1);
+	ret = dma_map_sg(nandc->dev, sgl, sgl_cnt, desc->dir);
+	if (ret == 0) {
+		dev_err(nandc->dev, "failure in mapping desc\n");
+		kfree(desc);
+		return -ENOMEM;
+	}
+
+	desc->sgl_cnt = sgl_cnt;
+	desc->bam_sgl = sgl;
+
+	dma_desc = dmaengine_prep_slave_sg(chan, sgl, sgl_cnt, dir_eng,
+					   flags);
+
+	if (!dma_desc) {
+		dev_err(nandc->dev, "failure in prep desc\n");
+		dma_unmap_sg(nandc->dev, sgl, sgl_cnt, desc->dir);
+		kfree(desc);
+		return -EINVAL;
+	}
+
+	desc->dma_desc = dma_desc;
+
+	list_add_tail(&desc->node, &nandc->desc_list);
+
+	return 0;
+}
+
+static int prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read,
+			     int reg_off, const void *vaddr, int size,
+			     bool flow_control)
 {
 	struct desc_info *desc;
 	struct dma_async_tx_descriptor *dma_desc;
@@ -583,7 +668,7 @@ static int prep_dma_desc(struct qcom_nand_controller *nandc, bool read,
 	if (!desc)
 		return -ENOMEM;
 
-	sgl = &desc->sgl;
+	sgl = &desc->adm_sgl;
 
 	sg_init_one(sgl, vaddr, size);
 
@@ -659,7 +744,7 @@ static int read_reg_dma(struct qcom_nand_controller *nandc, int first,
 	vaddr = nandc->reg_read_buf + nandc->reg_read_pos;
 	nandc->reg_read_pos += num_regs;
 
-	return prep_dma_desc(nandc, true, first, vaddr, size, flow_control);
+	return prep_adm_dma_desc(nandc, true, first, vaddr, size, flow_control);
 }
 
 /*
@@ -690,7 +775,8 @@ static int write_reg_dma(struct qcom_nand_controller *nandc, int first,
 
 	size = num_regs * sizeof(u32);
 
-	return prep_dma_desc(nandc, false, first, vaddr, size, flow_control);
+	return prep_adm_dma_desc(nandc, false, first, vaddr, size,
+				 flow_control);
 }
 
 /*
@@ -704,7 +790,7 @@ static int write_reg_dma(struct qcom_nand_controller *nandc, int first,
 static int read_data_dma(struct qcom_nand_controller *nandc, int reg_off,
 			 const u8 *vaddr, int size)
 {
-	return prep_dma_desc(nandc, true, reg_off, vaddr, size, false);
+	return prep_adm_dma_desc(nandc, true, reg_off, vaddr, size, false);
 }
 
 /*
@@ -718,7 +804,7 @@ static int read_data_dma(struct qcom_nand_controller *nandc, int reg_off,
 static int write_data_dma(struct qcom_nand_controller *nandc, int reg_off,
 			  const u8 *vaddr, int size)
 {
-	return prep_dma_desc(nandc, false, reg_off, vaddr, size, false);
+	return prep_adm_dma_desc(nandc, false, reg_off, vaddr, size, false);
 }
 
 /*
@@ -917,12 +1003,43 @@ static int submit_descs(struct qcom_nand_controller *nandc)
 {
 	struct desc_info *desc;
 	dma_cookie_t cookie = 0;
+	struct bam_transaction *bam_txn = nandc->bam_txn;
+	int r;
+
+	if (nandc->props->is_bam) {
+		if (bam_txn->rx_sgl_pos > bam_txn->rx_sgl_start) {
+			r = prepare_bam_async_desc(nandc, nandc->rx_chan, 0);
+			if (r)
+				return r;
+		}
+
+		if (bam_txn->tx_sgl_pos > bam_txn->tx_sgl_start) {
+			r = prepare_bam_async_desc(nandc, nandc->tx_chan,
+						   DMA_PREP_INTERRUPT);
+			if (r)
+				return r;
+		}
+
+		if (bam_txn->cmd_sgl_pos > bam_txn->cmd_sgl_start) {
+			r = prepare_bam_async_desc(nandc, nandc->cmd_chan, 0);
+			if (r)
+				return r;
+		}
+	}
 
 	list_for_each_entry(desc, &nandc->desc_list, node)
 		cookie = dmaengine_submit(desc->dma_desc);
 
-	if (dma_sync_wait(nandc->chan, cookie) != DMA_COMPLETE)
-		return -ETIMEDOUT;
+	if (nandc->props->is_bam) {
+		dma_async_issue_pending(nandc->tx_chan);
+		dma_async_issue_pending(nandc->rx_chan);
+
+		if (dma_sync_wait(nandc->cmd_chan, cookie) != DMA_COMPLETE)
+			return -ETIMEDOUT;
+	} else {
+		if (dma_sync_wait(nandc->chan, cookie) != DMA_COMPLETE)
+			return -ETIMEDOUT;
+	}
 
 	return 0;
 }
@@ -933,7 +1050,14 @@ static void free_descs(struct qcom_nand_controller *nandc)
 
 	list_for_each_entry_safe(desc, n, &nandc->desc_list, node) {
 		list_del(&desc->node);
-		dma_unmap_sg(nandc->dev, &desc->sgl, 1, desc->dir);
+
+		if (nandc->props->is_bam)
+			dma_unmap_sg(nandc->dev, desc->bam_sgl,
+				     desc->sgl_cnt, desc->dir);
+		else
+			dma_unmap_sg(nandc->dev, &desc->adm_sgl, 1,
+				     desc->dir);
+
 		kfree(desc);
 	}
 }
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v5 04/16] mtd: nand: qcom: support for passing flags in DMA helper functions
  2017-08-17 12:07 [PATCH v5 00/16] Add QCOM QPIC NAND support Abhishek Sahu
@ 2017-08-17 12:07   ` Abhishek Sahu
  2017-08-17 12:07 ` [PATCH v5 02/16] mtd: nand: qcom: allocate BAM transaction Abhishek Sahu
                     ` (15 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Abhishek Sahu @ 2017-08-17 12:07 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Archit Taneja, Richard Weinberger, linux-arm-msm, linux-kernel,
	Marek Vasut, Abhishek Sahu, linux-mtd, Cyrille Pitchen,
	Andy Gross, Sricharan R, Brian Norris, David Woodhouse

The QPIC NAND BAM has multiple flags to control the transfer. This
patch adds flags parameter in register and data transfer DMA helper
functions and modifies all these functions call with appropriate
flags using following rule

1. Read and write can’t go in single command descriptor so
   separate SGL should be used.
2. For some of the requests, NWD flag should be set in BAM
   DMA descriptor.
3. For Data write, the BAM has internal buffer for each codeword.
   All write request will modify the data in internal buffer and
   this buffer will be flushed to NAND device once EOT flag is set.
   So for all the write requests in single codeword, the EOT should
   be cleared for all tx data descriptors except the last one.

Reviewed-by: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---

* Changes from v4:

1. Added flag argument description in function comment
2. Minor modification in the comment given before
       #define NAND_BAM_NO_EOT
3. Minor modification in commit message

 drivers/mtd/nand/qcom_nandc.c | 129 +++++++++++++++++++++++++-----------------
 1 file changed, 77 insertions(+), 52 deletions(-)

diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index f52a692..c922617 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -181,6 +181,17 @@
 #define QPIC_PER_CW_DATA_SGL		8
 
 /*
+ * Flags used in DMA descriptor preparation helper functions
+ * (i.e. read_reg_dma/write_reg_dma/read_data_dma/write_data_dma)
+ */
+/* Don't set the EOT in current tx BAM sgl */
+#define NAND_BAM_NO_EOT			BIT(0)
+/* Set the NWD flag in current BAM sgl */
+#define NAND_BAM_NWD			BIT(1)
+/* Finish writing in the current BAM sgl and start writing in another BAM sgl */
+#define NAND_BAM_NEXT_SGL		BIT(2)
+
+/*
  * This data type corresponds to the BAM transaction which will be used for all
  * NAND transfers.
  * @cmd_sgl - sgl for NAND BAM command pipe
@@ -729,9 +740,10 @@ static int prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read,
  *
  * @first:		offset of the first register in the contiguous block
  * @num_regs:		number of registers to read
+ * @flags:		flags to control DMA descriptor preparation
  */
 static int read_reg_dma(struct qcom_nand_controller *nandc, int first,
-			int num_regs)
+			int num_regs, unsigned int flags)
 {
 	bool flow_control = false;
 	void *vaddr;
@@ -753,9 +765,10 @@ static int read_reg_dma(struct qcom_nand_controller *nandc, int first,
  *
  * @first:		offset of the first register in the contiguous block
  * @num_regs:		number of registers to write
+ * @flags:		flags to control DMA descriptor preparation
  */
 static int write_reg_dma(struct qcom_nand_controller *nandc, int first,
-			 int num_regs)
+			 int num_regs, unsigned int flags)
 {
 	bool flow_control = false;
 	struct nandc_regs *regs = nandc->regs;
@@ -767,6 +780,9 @@ static int write_reg_dma(struct qcom_nand_controller *nandc, int first,
 	if (first == NAND_FLASH_CMD)
 		flow_control = true;
 
+	if (first == NAND_EXEC_CMD)
+		flags |= NAND_BAM_NWD;
+
 	if (first == NAND_DEV_CMD1_RESTORE)
 		first = NAND_DEV_CMD1;
 
@@ -786,9 +802,10 @@ static int write_reg_dma(struct qcom_nand_controller *nandc, int first,
  * @reg_off:		offset within the controller's data buffer
  * @vaddr:		virtual address of the buffer we want to write to
  * @size:		DMA transaction size in bytes
+ * @flags:		flags to control DMA descriptor preparation
  */
 static int read_data_dma(struct qcom_nand_controller *nandc, int reg_off,
-			 const u8 *vaddr, int size)
+			 const u8 *vaddr, int size, unsigned int flags)
 {
 	return prep_adm_dma_desc(nandc, true, reg_off, vaddr, size, false);
 }
@@ -800,9 +817,10 @@ static int read_data_dma(struct qcom_nand_controller *nandc, int reg_off,
  * @reg_off:		offset within the controller's data buffer
  * @vaddr:		virtual address of the buffer we want to read from
  * @size:		DMA transaction size in bytes
+ * @flags:		flags to control DMA descriptor preparation
  */
 static int write_data_dma(struct qcom_nand_controller *nandc, int reg_off,
-			  const u8 *vaddr, int size)
+			  const u8 *vaddr, int size, unsigned int flags)
 {
 	return prep_adm_dma_desc(nandc, false, reg_off, vaddr, size, false);
 }
@@ -813,9 +831,9 @@ static int write_data_dma(struct qcom_nand_controller *nandc, int reg_off,
  */
 static void config_nand_page_read(struct qcom_nand_controller *nandc)
 {
-	write_reg_dma(nandc, NAND_ADDR0, 2);
-	write_reg_dma(nandc, NAND_DEV0_CFG0, 3);
-	write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1);
+	write_reg_dma(nandc, NAND_ADDR0, 2, 0);
+	write_reg_dma(nandc, NAND_DEV0_CFG0, 3, 0);
+	write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1, 0);
 }
 
 /*
@@ -824,11 +842,12 @@ static void config_nand_page_read(struct qcom_nand_controller *nandc)
  */
 static void config_nand_cw_read(struct qcom_nand_controller *nandc)
 {
-	write_reg_dma(nandc, NAND_FLASH_CMD, 1);
-	write_reg_dma(nandc, NAND_EXEC_CMD, 1);
+	write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
+	write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
 
-	read_reg_dma(nandc, NAND_FLASH_STATUS, 2);
-	read_reg_dma(nandc, NAND_ERASED_CW_DETECT_STATUS, 1);
+	read_reg_dma(nandc, NAND_FLASH_STATUS, 2, 0);
+	read_reg_dma(nandc, NAND_ERASED_CW_DETECT_STATUS, 1,
+		     NAND_BAM_NEXT_SGL);
 }
 
 /*
@@ -847,9 +866,10 @@ static void config_nand_single_cw_page_read(struct qcom_nand_controller *nandc)
  */
 static void config_nand_page_write(struct qcom_nand_controller *nandc)
 {
-	write_reg_dma(nandc, NAND_ADDR0, 2);
-	write_reg_dma(nandc, NAND_DEV0_CFG0, 3);
-	write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1);
+	write_reg_dma(nandc, NAND_ADDR0, 2, 0);
+	write_reg_dma(nandc, NAND_DEV0_CFG0, 3, 0);
+	write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1,
+		      NAND_BAM_NEXT_SGL);
 }
 
 /*
@@ -858,13 +878,13 @@ static void config_nand_page_write(struct qcom_nand_controller *nandc)
  */
 static void config_nand_cw_write(struct qcom_nand_controller *nandc)
 {
-	write_reg_dma(nandc, NAND_FLASH_CMD, 1);
-	write_reg_dma(nandc, NAND_EXEC_CMD, 1);
+	write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
+	write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
 
-	read_reg_dma(nandc, NAND_FLASH_STATUS, 1);
+	read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
 
-	write_reg_dma(nandc, NAND_FLASH_STATUS, 1);
-	write_reg_dma(nandc, NAND_READ_STATUS, 1);
+	write_reg_dma(nandc, NAND_FLASH_STATUS, 1, 0);
+	write_reg_dma(nandc, NAND_READ_STATUS, 1, NAND_BAM_NEXT_SGL);
 }
 
 /*
@@ -911,8 +931,8 @@ static int nandc_param(struct qcom_nand_host *host)
 	nandc_set_reg(nandc, NAND_DEV_CMD1_RESTORE, nandc->cmd1);
 	nandc_set_reg(nandc, NAND_DEV_CMD_VLD_RESTORE, nandc->vld);
 
-	write_reg_dma(nandc, NAND_DEV_CMD_VLD, 1);
-	write_reg_dma(nandc, NAND_DEV_CMD1, 1);
+	write_reg_dma(nandc, NAND_DEV_CMD_VLD, 1, 0);
+	write_reg_dma(nandc, NAND_DEV_CMD1, 1, NAND_BAM_NEXT_SGL);
 
 	nandc->buf_count = 512;
 	memset(nandc->data_buffer, 0xff, nandc->buf_count);
@@ -920,11 +940,11 @@ static int nandc_param(struct qcom_nand_host *host)
 	config_nand_single_cw_page_read(nandc);
 
 	read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer,
-		      nandc->buf_count);
+		      nandc->buf_count, 0);
 
 	/* restore CMD1 and VLD regs */
-	write_reg_dma(nandc, NAND_DEV_CMD1_RESTORE, 1);
-	write_reg_dma(nandc, NAND_DEV_CMD_VLD_RESTORE, 1);
+	write_reg_dma(nandc, NAND_DEV_CMD1_RESTORE, 1, 0);
+	write_reg_dma(nandc, NAND_DEV_CMD_VLD_RESTORE, 1, NAND_BAM_NEXT_SGL);
 
 	return 0;
 }
@@ -946,14 +966,14 @@ static int erase_block(struct qcom_nand_host *host, int page_addr)
 	nandc_set_reg(nandc, NAND_FLASH_STATUS, host->clrflashstatus);
 	nandc_set_reg(nandc, NAND_READ_STATUS, host->clrreadstatus);
 
-	write_reg_dma(nandc, NAND_FLASH_CMD, 3);
-	write_reg_dma(nandc, NAND_DEV0_CFG0, 2);
-	write_reg_dma(nandc, NAND_EXEC_CMD, 1);
+	write_reg_dma(nandc, NAND_FLASH_CMD, 3, NAND_BAM_NEXT_SGL);
+	write_reg_dma(nandc, NAND_DEV0_CFG0, 2, NAND_BAM_NEXT_SGL);
+	write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
 
-	read_reg_dma(nandc, NAND_FLASH_STATUS, 1);
+	read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
 
-	write_reg_dma(nandc, NAND_FLASH_STATUS, 1);
-	write_reg_dma(nandc, NAND_READ_STATUS, 1);
+	write_reg_dma(nandc, NAND_FLASH_STATUS, 1, 0);
+	write_reg_dma(nandc, NAND_READ_STATUS, 1, NAND_BAM_NEXT_SGL);
 
 	return 0;
 }
@@ -973,10 +993,10 @@ static int read_id(struct qcom_nand_host *host, int column)
 	nandc_set_reg(nandc, NAND_FLASH_CHIP_SELECT, DM_EN);
 	nandc_set_reg(nandc, NAND_EXEC_CMD, 1);
 
-	write_reg_dma(nandc, NAND_FLASH_CMD, 4);
-	write_reg_dma(nandc, NAND_EXEC_CMD, 1);
+	write_reg_dma(nandc, NAND_FLASH_CMD, 4, NAND_BAM_NEXT_SGL);
+	write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
 
-	read_reg_dma(nandc, NAND_READ_ID, 1);
+	read_reg_dma(nandc, NAND_READ_ID, 1, NAND_BAM_NEXT_SGL);
 
 	return 0;
 }
@@ -990,10 +1010,10 @@ static int reset(struct qcom_nand_host *host)
 	nandc_set_reg(nandc, NAND_FLASH_CMD, RESET_DEVICE);
 	nandc_set_reg(nandc, NAND_EXEC_CMD, 1);
 
-	write_reg_dma(nandc, NAND_FLASH_CMD, 1);
-	write_reg_dma(nandc, NAND_EXEC_CMD, 1);
+	write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
+	write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
 
-	read_reg_dma(nandc, NAND_FLASH_STATUS, 1);
+	read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
 
 	return 0;
 }
@@ -1389,7 +1409,7 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf,
 
 		if (data_buf)
 			read_data_dma(nandc, FLASH_BUF_ACC, data_buf,
-				      data_size);
+				      data_size, 0);
 
 		/*
 		 * when ecc is enabled, the controller doesn't read the real
@@ -1405,7 +1425,7 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf,
 				*oob_buf++ = 0xff;
 
 			read_data_dma(nandc, FLASH_BUF_ACC + data_size,
-				      oob_buf, oob_size);
+				      oob_buf, oob_size, 0);
 		}
 
 		if (data_buf)
@@ -1447,7 +1467,7 @@ static int copy_last_cw(struct qcom_nand_host *host, int page)
 
 	config_nand_single_cw_page_read(nandc);
 
-	read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, size);
+	read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, size, 0);
 
 	ret = submit_descs(nandc);
 	if (ret)
@@ -1516,19 +1536,19 @@ static int qcom_nandc_read_page_raw(struct mtd_info *mtd,
 
 		config_nand_cw_read(nandc);
 
-		read_data_dma(nandc, reg_off, data_buf, data_size1);
+		read_data_dma(nandc, reg_off, data_buf, data_size1, 0);
 		reg_off += data_size1;
 		data_buf += data_size1;
 
-		read_data_dma(nandc, reg_off, oob_buf, oob_size1);
+		read_data_dma(nandc, reg_off, oob_buf, oob_size1, 0);
 		reg_off += oob_size1;
 		oob_buf += oob_size1;
 
-		read_data_dma(nandc, reg_off, data_buf, data_size2);
+		read_data_dma(nandc, reg_off, data_buf, data_size2, 0);
 		reg_off += data_size2;
 		data_buf += data_size2;
 
-		read_data_dma(nandc, reg_off, oob_buf, oob_size2);
+		read_data_dma(nandc, reg_off, oob_buf, oob_size2, 0);
 		oob_buf += oob_size2;
 	}
 
@@ -1595,7 +1615,8 @@ static int qcom_nandc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 		}
 
 
-		write_data_dma(nandc, FLASH_BUF_ACC, data_buf, data_size);
+		write_data_dma(nandc, FLASH_BUF_ACC, data_buf, data_size,
+			       i == (ecc->steps - 1) ? NAND_BAM_NO_EOT : 0);
 
 		/*
 		 * when ECC is enabled, we don't really need to write anything
@@ -1608,7 +1629,7 @@ static int qcom_nandc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 			oob_buf += host->bbm_size;
 
 			write_data_dma(nandc, FLASH_BUF_ACC + data_size,
-				       oob_buf, oob_size);
+				       oob_buf, oob_size, 0);
 		}
 
 		config_nand_cw_write(nandc);
@@ -1663,19 +1684,22 @@ static int qcom_nandc_write_page_raw(struct mtd_info *mtd,
 			oob_size2 = host->ecc_bytes_hw + host->spare_bytes;
 		}
 
-		write_data_dma(nandc, reg_off, data_buf, data_size1);
+		write_data_dma(nandc, reg_off, data_buf, data_size1,
+			       NAND_BAM_NO_EOT);
 		reg_off += data_size1;
 		data_buf += data_size1;
 
-		write_data_dma(nandc, reg_off, oob_buf, oob_size1);
+		write_data_dma(nandc, reg_off, oob_buf, oob_size1,
+			       NAND_BAM_NO_EOT);
 		reg_off += oob_size1;
 		oob_buf += oob_size1;
 
-		write_data_dma(nandc, reg_off, data_buf, data_size2);
+		write_data_dma(nandc, reg_off, data_buf, data_size2,
+			       NAND_BAM_NO_EOT);
 		reg_off += data_size2;
 		data_buf += data_size2;
 
-		write_data_dma(nandc, reg_off, oob_buf, oob_size2);
+		write_data_dma(nandc, reg_off, oob_buf, oob_size2, 0);
 		oob_buf += oob_size2;
 
 		config_nand_cw_write(nandc);
@@ -1729,8 +1753,8 @@ static int qcom_nandc_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
 	update_rw_regs(host, 1, false);
 
 	config_nand_page_write(nandc);
-	write_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer,
-		       data_size + oob_size);
+	write_data_dma(nandc, FLASH_BUF_ACC,
+		       nandc->data_buffer, data_size + oob_size, 0);
 	config_nand_cw_write(nandc);
 
 	ret = submit_descs(nandc);
@@ -1814,7 +1838,8 @@ static int qcom_nandc_block_markbad(struct mtd_info *mtd, loff_t ofs)
 	update_rw_regs(host, 1, false);
 
 	config_nand_page_write(nandc);
-	write_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, host->cw_size);
+	write_data_dma(nandc, FLASH_BUF_ACC,
+		       nandc->data_buffer, host->cw_size, 0);
 	config_nand_cw_write(nandc);
 
 	ret = submit_descs(nandc);
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v5 04/16] mtd: nand: qcom: support for passing flags in DMA helper functions
@ 2017-08-17 12:07   ` Abhishek Sahu
  0 siblings, 0 replies; 26+ messages in thread
From: Abhishek Sahu @ 2017-08-17 12:07 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: David Woodhouse, Brian Norris, Marek Vasut, Richard Weinberger,
	Cyrille Pitchen, linux-arm-msm, linux-kernel, linux-mtd,
	Andy Gross, Archit Taneja, Sricharan R, Abhishek Sahu

The QPIC NAND BAM has multiple flags to control the transfer. This
patch adds flags parameter in register and data transfer DMA helper
functions and modifies all these functions call with appropriate
flags using following rule

1. Read and write can’t go in single command descriptor so
   separate SGL should be used.
2. For some of the requests, NWD flag should be set in BAM
   DMA descriptor.
3. For Data write, the BAM has internal buffer for each codeword.
   All write request will modify the data in internal buffer and
   this buffer will be flushed to NAND device once EOT flag is set.
   So for all the write requests in single codeword, the EOT should
   be cleared for all tx data descriptors except the last one.

Reviewed-by: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---

* Changes from v4:

1. Added flag argument description in function comment
2. Minor modification in the comment given before
       #define NAND_BAM_NO_EOT
3. Minor modification in commit message

 drivers/mtd/nand/qcom_nandc.c | 129 +++++++++++++++++++++++++-----------------
 1 file changed, 77 insertions(+), 52 deletions(-)

diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index f52a692..c922617 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -181,6 +181,17 @@
 #define QPIC_PER_CW_DATA_SGL		8
 
 /*
+ * Flags used in DMA descriptor preparation helper functions
+ * (i.e. read_reg_dma/write_reg_dma/read_data_dma/write_data_dma)
+ */
+/* Don't set the EOT in current tx BAM sgl */
+#define NAND_BAM_NO_EOT			BIT(0)
+/* Set the NWD flag in current BAM sgl */
+#define NAND_BAM_NWD			BIT(1)
+/* Finish writing in the current BAM sgl and start writing in another BAM sgl */
+#define NAND_BAM_NEXT_SGL		BIT(2)
+
+/*
  * This data type corresponds to the BAM transaction which will be used for all
  * NAND transfers.
  * @cmd_sgl - sgl for NAND BAM command pipe
@@ -729,9 +740,10 @@ static int prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read,
  *
  * @first:		offset of the first register in the contiguous block
  * @num_regs:		number of registers to read
+ * @flags:		flags to control DMA descriptor preparation
  */
 static int read_reg_dma(struct qcom_nand_controller *nandc, int first,
-			int num_regs)
+			int num_regs, unsigned int flags)
 {
 	bool flow_control = false;
 	void *vaddr;
@@ -753,9 +765,10 @@ static int read_reg_dma(struct qcom_nand_controller *nandc, int first,
  *
  * @first:		offset of the first register in the contiguous block
  * @num_regs:		number of registers to write
+ * @flags:		flags to control DMA descriptor preparation
  */
 static int write_reg_dma(struct qcom_nand_controller *nandc, int first,
-			 int num_regs)
+			 int num_regs, unsigned int flags)
 {
 	bool flow_control = false;
 	struct nandc_regs *regs = nandc->regs;
@@ -767,6 +780,9 @@ static int write_reg_dma(struct qcom_nand_controller *nandc, int first,
 	if (first == NAND_FLASH_CMD)
 		flow_control = true;
 
+	if (first == NAND_EXEC_CMD)
+		flags |= NAND_BAM_NWD;
+
 	if (first == NAND_DEV_CMD1_RESTORE)
 		first = NAND_DEV_CMD1;
 
@@ -786,9 +802,10 @@ static int write_reg_dma(struct qcom_nand_controller *nandc, int first,
  * @reg_off:		offset within the controller's data buffer
  * @vaddr:		virtual address of the buffer we want to write to
  * @size:		DMA transaction size in bytes
+ * @flags:		flags to control DMA descriptor preparation
  */
 static int read_data_dma(struct qcom_nand_controller *nandc, int reg_off,
-			 const u8 *vaddr, int size)
+			 const u8 *vaddr, int size, unsigned int flags)
 {
 	return prep_adm_dma_desc(nandc, true, reg_off, vaddr, size, false);
 }
@@ -800,9 +817,10 @@ static int read_data_dma(struct qcom_nand_controller *nandc, int reg_off,
  * @reg_off:		offset within the controller's data buffer
  * @vaddr:		virtual address of the buffer we want to read from
  * @size:		DMA transaction size in bytes
+ * @flags:		flags to control DMA descriptor preparation
  */
 static int write_data_dma(struct qcom_nand_controller *nandc, int reg_off,
-			  const u8 *vaddr, int size)
+			  const u8 *vaddr, int size, unsigned int flags)
 {
 	return prep_adm_dma_desc(nandc, false, reg_off, vaddr, size, false);
 }
@@ -813,9 +831,9 @@ static int write_data_dma(struct qcom_nand_controller *nandc, int reg_off,
  */
 static void config_nand_page_read(struct qcom_nand_controller *nandc)
 {
-	write_reg_dma(nandc, NAND_ADDR0, 2);
-	write_reg_dma(nandc, NAND_DEV0_CFG0, 3);
-	write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1);
+	write_reg_dma(nandc, NAND_ADDR0, 2, 0);
+	write_reg_dma(nandc, NAND_DEV0_CFG0, 3, 0);
+	write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1, 0);
 }
 
 /*
@@ -824,11 +842,12 @@ static void config_nand_page_read(struct qcom_nand_controller *nandc)
  */
 static void config_nand_cw_read(struct qcom_nand_controller *nandc)
 {
-	write_reg_dma(nandc, NAND_FLASH_CMD, 1);
-	write_reg_dma(nandc, NAND_EXEC_CMD, 1);
+	write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
+	write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
 
-	read_reg_dma(nandc, NAND_FLASH_STATUS, 2);
-	read_reg_dma(nandc, NAND_ERASED_CW_DETECT_STATUS, 1);
+	read_reg_dma(nandc, NAND_FLASH_STATUS, 2, 0);
+	read_reg_dma(nandc, NAND_ERASED_CW_DETECT_STATUS, 1,
+		     NAND_BAM_NEXT_SGL);
 }
 
 /*
@@ -847,9 +866,10 @@ static void config_nand_single_cw_page_read(struct qcom_nand_controller *nandc)
  */
 static void config_nand_page_write(struct qcom_nand_controller *nandc)
 {
-	write_reg_dma(nandc, NAND_ADDR0, 2);
-	write_reg_dma(nandc, NAND_DEV0_CFG0, 3);
-	write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1);
+	write_reg_dma(nandc, NAND_ADDR0, 2, 0);
+	write_reg_dma(nandc, NAND_DEV0_CFG0, 3, 0);
+	write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1,
+		      NAND_BAM_NEXT_SGL);
 }
 
 /*
@@ -858,13 +878,13 @@ static void config_nand_page_write(struct qcom_nand_controller *nandc)
  */
 static void config_nand_cw_write(struct qcom_nand_controller *nandc)
 {
-	write_reg_dma(nandc, NAND_FLASH_CMD, 1);
-	write_reg_dma(nandc, NAND_EXEC_CMD, 1);
+	write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
+	write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
 
-	read_reg_dma(nandc, NAND_FLASH_STATUS, 1);
+	read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
 
-	write_reg_dma(nandc, NAND_FLASH_STATUS, 1);
-	write_reg_dma(nandc, NAND_READ_STATUS, 1);
+	write_reg_dma(nandc, NAND_FLASH_STATUS, 1, 0);
+	write_reg_dma(nandc, NAND_READ_STATUS, 1, NAND_BAM_NEXT_SGL);
 }
 
 /*
@@ -911,8 +931,8 @@ static int nandc_param(struct qcom_nand_host *host)
 	nandc_set_reg(nandc, NAND_DEV_CMD1_RESTORE, nandc->cmd1);
 	nandc_set_reg(nandc, NAND_DEV_CMD_VLD_RESTORE, nandc->vld);
 
-	write_reg_dma(nandc, NAND_DEV_CMD_VLD, 1);
-	write_reg_dma(nandc, NAND_DEV_CMD1, 1);
+	write_reg_dma(nandc, NAND_DEV_CMD_VLD, 1, 0);
+	write_reg_dma(nandc, NAND_DEV_CMD1, 1, NAND_BAM_NEXT_SGL);
 
 	nandc->buf_count = 512;
 	memset(nandc->data_buffer, 0xff, nandc->buf_count);
@@ -920,11 +940,11 @@ static int nandc_param(struct qcom_nand_host *host)
 	config_nand_single_cw_page_read(nandc);
 
 	read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer,
-		      nandc->buf_count);
+		      nandc->buf_count, 0);
 
 	/* restore CMD1 and VLD regs */
-	write_reg_dma(nandc, NAND_DEV_CMD1_RESTORE, 1);
-	write_reg_dma(nandc, NAND_DEV_CMD_VLD_RESTORE, 1);
+	write_reg_dma(nandc, NAND_DEV_CMD1_RESTORE, 1, 0);
+	write_reg_dma(nandc, NAND_DEV_CMD_VLD_RESTORE, 1, NAND_BAM_NEXT_SGL);
 
 	return 0;
 }
@@ -946,14 +966,14 @@ static int erase_block(struct qcom_nand_host *host, int page_addr)
 	nandc_set_reg(nandc, NAND_FLASH_STATUS, host->clrflashstatus);
 	nandc_set_reg(nandc, NAND_READ_STATUS, host->clrreadstatus);
 
-	write_reg_dma(nandc, NAND_FLASH_CMD, 3);
-	write_reg_dma(nandc, NAND_DEV0_CFG0, 2);
-	write_reg_dma(nandc, NAND_EXEC_CMD, 1);
+	write_reg_dma(nandc, NAND_FLASH_CMD, 3, NAND_BAM_NEXT_SGL);
+	write_reg_dma(nandc, NAND_DEV0_CFG0, 2, NAND_BAM_NEXT_SGL);
+	write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
 
-	read_reg_dma(nandc, NAND_FLASH_STATUS, 1);
+	read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
 
-	write_reg_dma(nandc, NAND_FLASH_STATUS, 1);
-	write_reg_dma(nandc, NAND_READ_STATUS, 1);
+	write_reg_dma(nandc, NAND_FLASH_STATUS, 1, 0);
+	write_reg_dma(nandc, NAND_READ_STATUS, 1, NAND_BAM_NEXT_SGL);
 
 	return 0;
 }
@@ -973,10 +993,10 @@ static int read_id(struct qcom_nand_host *host, int column)
 	nandc_set_reg(nandc, NAND_FLASH_CHIP_SELECT, DM_EN);
 	nandc_set_reg(nandc, NAND_EXEC_CMD, 1);
 
-	write_reg_dma(nandc, NAND_FLASH_CMD, 4);
-	write_reg_dma(nandc, NAND_EXEC_CMD, 1);
+	write_reg_dma(nandc, NAND_FLASH_CMD, 4, NAND_BAM_NEXT_SGL);
+	write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
 
-	read_reg_dma(nandc, NAND_READ_ID, 1);
+	read_reg_dma(nandc, NAND_READ_ID, 1, NAND_BAM_NEXT_SGL);
 
 	return 0;
 }
@@ -990,10 +1010,10 @@ static int reset(struct qcom_nand_host *host)
 	nandc_set_reg(nandc, NAND_FLASH_CMD, RESET_DEVICE);
 	nandc_set_reg(nandc, NAND_EXEC_CMD, 1);
 
-	write_reg_dma(nandc, NAND_FLASH_CMD, 1);
-	write_reg_dma(nandc, NAND_EXEC_CMD, 1);
+	write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
+	write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
 
-	read_reg_dma(nandc, NAND_FLASH_STATUS, 1);
+	read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
 
 	return 0;
 }
@@ -1389,7 +1409,7 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf,
 
 		if (data_buf)
 			read_data_dma(nandc, FLASH_BUF_ACC, data_buf,
-				      data_size);
+				      data_size, 0);
 
 		/*
 		 * when ecc is enabled, the controller doesn't read the real
@@ -1405,7 +1425,7 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf,
 				*oob_buf++ = 0xff;
 
 			read_data_dma(nandc, FLASH_BUF_ACC + data_size,
-				      oob_buf, oob_size);
+				      oob_buf, oob_size, 0);
 		}
 
 		if (data_buf)
@@ -1447,7 +1467,7 @@ static int copy_last_cw(struct qcom_nand_host *host, int page)
 
 	config_nand_single_cw_page_read(nandc);
 
-	read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, size);
+	read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, size, 0);
 
 	ret = submit_descs(nandc);
 	if (ret)
@@ -1516,19 +1536,19 @@ static int qcom_nandc_read_page_raw(struct mtd_info *mtd,
 
 		config_nand_cw_read(nandc);
 
-		read_data_dma(nandc, reg_off, data_buf, data_size1);
+		read_data_dma(nandc, reg_off, data_buf, data_size1, 0);
 		reg_off += data_size1;
 		data_buf += data_size1;
 
-		read_data_dma(nandc, reg_off, oob_buf, oob_size1);
+		read_data_dma(nandc, reg_off, oob_buf, oob_size1, 0);
 		reg_off += oob_size1;
 		oob_buf += oob_size1;
 
-		read_data_dma(nandc, reg_off, data_buf, data_size2);
+		read_data_dma(nandc, reg_off, data_buf, data_size2, 0);
 		reg_off += data_size2;
 		data_buf += data_size2;
 
-		read_data_dma(nandc, reg_off, oob_buf, oob_size2);
+		read_data_dma(nandc, reg_off, oob_buf, oob_size2, 0);
 		oob_buf += oob_size2;
 	}
 
@@ -1595,7 +1615,8 @@ static int qcom_nandc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 		}
 
 
-		write_data_dma(nandc, FLASH_BUF_ACC, data_buf, data_size);
+		write_data_dma(nandc, FLASH_BUF_ACC, data_buf, data_size,
+			       i == (ecc->steps - 1) ? NAND_BAM_NO_EOT : 0);
 
 		/*
 		 * when ECC is enabled, we don't really need to write anything
@@ -1608,7 +1629,7 @@ static int qcom_nandc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 			oob_buf += host->bbm_size;
 
 			write_data_dma(nandc, FLASH_BUF_ACC + data_size,
-				       oob_buf, oob_size);
+				       oob_buf, oob_size, 0);
 		}
 
 		config_nand_cw_write(nandc);
@@ -1663,19 +1684,22 @@ static int qcom_nandc_write_page_raw(struct mtd_info *mtd,
 			oob_size2 = host->ecc_bytes_hw + host->spare_bytes;
 		}
 
-		write_data_dma(nandc, reg_off, data_buf, data_size1);
+		write_data_dma(nandc, reg_off, data_buf, data_size1,
+			       NAND_BAM_NO_EOT);
 		reg_off += data_size1;
 		data_buf += data_size1;
 
-		write_data_dma(nandc, reg_off, oob_buf, oob_size1);
+		write_data_dma(nandc, reg_off, oob_buf, oob_size1,
+			       NAND_BAM_NO_EOT);
 		reg_off += oob_size1;
 		oob_buf += oob_size1;
 
-		write_data_dma(nandc, reg_off, data_buf, data_size2);
+		write_data_dma(nandc, reg_off, data_buf, data_size2,
+			       NAND_BAM_NO_EOT);
 		reg_off += data_size2;
 		data_buf += data_size2;
 
-		write_data_dma(nandc, reg_off, oob_buf, oob_size2);
+		write_data_dma(nandc, reg_off, oob_buf, oob_size2, 0);
 		oob_buf += oob_size2;
 
 		config_nand_cw_write(nandc);
@@ -1729,8 +1753,8 @@ static int qcom_nandc_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
 	update_rw_regs(host, 1, false);
 
 	config_nand_page_write(nandc);
-	write_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer,
-		       data_size + oob_size);
+	write_data_dma(nandc, FLASH_BUF_ACC,
+		       nandc->data_buffer, data_size + oob_size, 0);
 	config_nand_cw_write(nandc);
 
 	ret = submit_descs(nandc);
@@ -1814,7 +1838,8 @@ static int qcom_nandc_block_markbad(struct mtd_info *mtd, loff_t ofs)
 	update_rw_regs(host, 1, false);
 
 	config_nand_page_write(nandc);
-	write_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer, host->cw_size);
+	write_data_dma(nandc, FLASH_BUF_ACC,
+		       nandc->data_buffer, host->cw_size, 0);
 	config_nand_cw_write(nandc);
 
 	ret = submit_descs(nandc);
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v5 05/16] mtd: nand: qcom: support for read location registers
  2017-08-17 12:07 [PATCH v5 00/16] Add QCOM QPIC NAND support Abhishek Sahu
                   ` (3 preceding siblings ...)
  2017-08-17 12:07   ` Abhishek Sahu
@ 2017-08-17 12:07 ` Abhishek Sahu
  2017-08-17 12:07 ` [PATCH v5 06/16] mtd: nand: qcom: erased codeword detection configuration Abhishek Sahu
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Abhishek Sahu @ 2017-08-17 12:07 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: David Woodhouse, Brian Norris, Marek Vasut, Richard Weinberger,
	Cyrille Pitchen, linux-arm-msm, linux-kernel, linux-mtd,
	Andy Gross, Archit Taneja, Sricharan R, Abhishek Sahu

In EBI2, all codeword data will be read in FLASH_BUF_ACC buffer
and ADM will copy the data from source (FLASH_BUF_ACC) to
destination (memory for data read).

In QPIC, there is no FLASH_BUF_ACC and all the codeword data will
held in QPIC BAM FIFO buffers. It provides multiple READ_LOCATION
registers which will be used for copying the data from FIFO to
memory. The READ_LOCATION register will be used to read a
specific amount of data from a specific offset within the flash
buffer. It supports sequential offset requests. Each request is
composed of the following fields:

a. Offset within the flash buffer from which data should be
   read
b. Amount of data to be read
c. Flag bit specifying the last read request from the flash
   buffer. Following the last read request the NANDc refers to the
   buffer as empty.

Reviewed-by: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---

* Changes from v4:

1. Changed macro name from nanc_set_readl to nandc_set_read_loc
2. Removed redundant nanc_set_readl in copy_lasy_cw

 drivers/mtd/nand/qcom_nandc.c | 63 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index c922617..9d55e8e 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -53,6 +53,8 @@
 #define	NAND_VERSION			0xf08
 #define	NAND_READ_LOCATION_0		0xf20
 #define	NAND_READ_LOCATION_1		0xf24
+#define	NAND_READ_LOCATION_2		0xf28
+#define	NAND_READ_LOCATION_3		0xf2c
 
 /* dummy register offsets, used by write_reg_dma */
 #define	NAND_DEV_CMD1_RESTORE		0xdead
@@ -135,6 +137,11 @@
 #define	ERASED_PAGE			(PAGE_ALL_ERASED | PAGE_ERASED)
 #define	ERASED_CW			(CODEWORD_ALL_ERASED | CODEWORD_ERASED)
 
+/* NAND_READ_LOCATION_n bits */
+#define READ_LOCATION_OFFSET		0
+#define READ_LOCATION_SIZE		16
+#define READ_LOCATION_LAST		31
+
 /* Version Mask */
 #define	NAND_VERSION_MAJOR_MASK		0xf0000000
 #define	NAND_VERSION_MAJOR_SHIFT	28
@@ -177,6 +184,12 @@
 #define	ECC_BCH_4BIT	BIT(2)
 #define	ECC_BCH_8BIT	BIT(3)
 
+#define nandc_set_read_loc(nandc, reg, offset, size, is_last)	\
+nandc_set_reg(nandc, NAND_READ_LOCATION_##reg,			\
+	      ((offset) << READ_LOCATION_OFFSET) |		\
+	      ((size) << READ_LOCATION_SIZE) |			\
+	      ((is_last) << READ_LOCATION_LAST))
+
 #define QPIC_PER_CW_CMD_SGL		32
 #define QPIC_PER_CW_DATA_SGL		8
 
@@ -263,6 +276,11 @@ struct nandc_regs {
 	__le32 orig_vld;
 
 	__le32 ecc_buf_cfg;
+	__le32 read_location0;
+	__le32 read_location1;
+	__le32 read_location2;
+	__le32 read_location3;
+
 };
 
 /*
@@ -519,6 +537,14 @@ static __le32 *offset_to_nandc_reg(struct nandc_regs *regs, int offset)
 		return &regs->orig_vld;
 	case NAND_EBI2_ECC_BUF_CFG:
 		return &regs->ecc_buf_cfg;
+	case NAND_READ_LOCATION_0:
+		return &regs->read_location0;
+	case NAND_READ_LOCATION_1:
+		return &regs->read_location1;
+	case NAND_READ_LOCATION_2:
+		return &regs->read_location2;
+	case NAND_READ_LOCATION_3:
+		return &regs->read_location3;
 	default:
 		return NULL;
 	}
@@ -593,6 +619,10 @@ static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read)
 	nandc_set_reg(nandc, NAND_FLASH_STATUS, host->clrflashstatus);
 	nandc_set_reg(nandc, NAND_READ_STATUS, host->clrreadstatus);
 	nandc_set_reg(nandc, NAND_EXEC_CMD, 1);
+
+	if (read)
+		nandc_set_read_loc(nandc, 0, 0, host->use_ecc ?
+				   host->cw_data : host->cw_size, 1);
 }
 
 /*
@@ -842,6 +872,10 @@ static void config_nand_page_read(struct qcom_nand_controller *nandc)
  */
 static void config_nand_cw_read(struct qcom_nand_controller *nandc)
 {
+	if (nandc->props->is_bam)
+		write_reg_dma(nandc, NAND_READ_LOCATION_0, 4,
+			      NAND_BAM_NEXT_SGL);
+
 	write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
 	write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
 
@@ -930,6 +964,7 @@ static int nandc_param(struct qcom_nand_host *host)
 
 	nandc_set_reg(nandc, NAND_DEV_CMD1_RESTORE, nandc->cmd1);
 	nandc_set_reg(nandc, NAND_DEV_CMD_VLD_RESTORE, nandc->vld);
+	nandc_set_read_loc(nandc, 0, 0, 512, 1);
 
 	write_reg_dma(nandc, NAND_DEV_CMD_VLD, 1, 0);
 	write_reg_dma(nandc, NAND_DEV_CMD1, 1, NAND_BAM_NEXT_SGL);
@@ -1405,6 +1440,19 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf,
 			oob_size = host->ecc_bytes_hw + host->spare_bytes;
 		}
 
+		if (nandc->props->is_bam) {
+			if (data_buf && oob_buf) {
+				nandc_set_read_loc(nandc, 0, 0, data_size, 0);
+				nandc_set_read_loc(nandc, 1, data_size,
+						   oob_size, 1);
+			} else if (data_buf) {
+				nandc_set_read_loc(nandc, 0, 0, data_size, 1);
+			} else {
+				nandc_set_read_loc(nandc, 0, data_size,
+						   oob_size, 1);
+			}
+		}
+
 		config_nand_cw_read(nandc);
 
 		if (data_buf)
@@ -1509,6 +1557,7 @@ static int qcom_nandc_read_page_raw(struct mtd_info *mtd,
 	u8 *data_buf, *oob_buf;
 	struct nand_ecc_ctrl *ecc = &chip->ecc;
 	int i, ret;
+	int read_loc;
 
 	data_buf = buf;
 	oob_buf = chip->oob_poi;
@@ -1534,6 +1583,20 @@ static int qcom_nandc_read_page_raw(struct mtd_info *mtd,
 			oob_size2 = host->ecc_bytes_hw + host->spare_bytes;
 		}
 
+		if (nandc->props->is_bam) {
+			read_loc = 0;
+			nandc_set_read_loc(nandc, 0, read_loc, data_size1, 0);
+			read_loc += data_size1;
+
+			nandc_set_read_loc(nandc, 1, read_loc, oob_size1, 0);
+			read_loc += oob_size1;
+
+			nandc_set_read_loc(nandc, 2, read_loc, data_size2, 0);
+			read_loc += data_size2;
+
+			nandc_set_read_loc(nandc, 3, read_loc, oob_size2, 1);
+		}
+
 		config_nand_cw_read(nandc);
 
 		read_data_dma(nandc, reg_off, data_buf, data_size1, 0);
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v5 06/16] mtd: nand: qcom: erased codeword detection configuration
  2017-08-17 12:07 [PATCH v5 00/16] Add QCOM QPIC NAND support Abhishek Sahu
                   ` (4 preceding siblings ...)
  2017-08-17 12:07 ` [PATCH v5 05/16] mtd: nand: qcom: support for read location registers Abhishek Sahu
@ 2017-08-17 12:07 ` Abhishek Sahu
  2017-08-17 12:07 ` [PATCH v5 07/16] mtd: nand: qcom: enable BAM or ADM mode Abhishek Sahu
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Abhishek Sahu @ 2017-08-17 12:07 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: David Woodhouse, Brian Norris, Marek Vasut, Richard Weinberger,
	Cyrille Pitchen, linux-arm-msm, linux-kernel, linux-mtd,
	Andy Gross, Archit Taneja, Sricharan R, Abhishek Sahu

The NAND controller returns ECC failure during read of completely
erased codeword. The NAND controller has hardware functionality
to detect erased codeword in case of BCH ECC algorithm. The
NAND_ERASED_CW_DETECT_CFG register controls the erased
codeword/page detection controller. This register should be reset
before every page read by setting and clearing bit 0 of
NAND_ERASED_CW_DETECT_CFG.

Reviewed-by: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---

* Changes from v4: None

 drivers/mtd/nand/qcom_nandc.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index 9d55e8e..81cfce7 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -203,6 +203,11 @@
 #define NAND_BAM_NWD			BIT(1)
 /* Finish writing in the current BAM sgl and start writing in another BAM sgl */
 #define NAND_BAM_NEXT_SGL		BIT(2)
+/*
+ * Erased codeword status is being used two times in single transfer so this
+ * flag will determine the current value of erased codeword status register
+ */
+#define NAND_ERASED_CW_SET		BIT(4)
 
 /*
  * This data type corresponds to the BAM transaction which will be used for all
@@ -281,6 +286,8 @@ struct nandc_regs {
 	__le32 read_location2;
 	__le32 read_location3;
 
+	__le32 erased_cw_detect_cfg_clr;
+	__le32 erased_cw_detect_cfg_set;
 };
 
 /*
@@ -810,6 +817,13 @@ static int write_reg_dma(struct qcom_nand_controller *nandc, int first,
 	if (first == NAND_FLASH_CMD)
 		flow_control = true;
 
+	if (first == NAND_ERASED_CW_DETECT_CFG) {
+		if (flags & NAND_ERASED_CW_SET)
+			vaddr = &regs->erased_cw_detect_cfg_set;
+		else
+			vaddr = &regs->erased_cw_detect_cfg_clr;
+	}
+
 	if (first == NAND_EXEC_CMD)
 		flags |= NAND_BAM_NWD;
 
@@ -864,6 +878,9 @@ static void config_nand_page_read(struct qcom_nand_controller *nandc)
 	write_reg_dma(nandc, NAND_ADDR0, 2, 0);
 	write_reg_dma(nandc, NAND_DEV0_CFG0, 3, 0);
 	write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1, 0);
+	write_reg_dma(nandc, NAND_ERASED_CW_DETECT_CFG, 1, 0);
+	write_reg_dma(nandc, NAND_ERASED_CW_DETECT_CFG, 1,
+		      NAND_ERASED_CW_SET | NAND_BAM_NEXT_SGL);
 }
 
 /*
@@ -2264,6 +2281,10 @@ static int qcom_nand_host_setup(struct qcom_nand_host *host)
 
 	host->clrflashstatus = FS_READY_BSY_N;
 	host->clrreadstatus = 0xc0;
+	nandc->regs->erased_cw_detect_cfg_clr =
+		cpu_to_le32(CLR_ERASED_PAGE_DET);
+	nandc->regs->erased_cw_detect_cfg_set =
+		cpu_to_le32(SET_ERASED_PAGE_DET);
 
 	dev_dbg(nandc->dev,
 		"cfg0 %x cfg1 %x ecc_buf_cfg %x ecc_bch cfg %x cw_size %d cw_data %d strength %d parity_bytes %d steps %d\n",
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v5 07/16] mtd: nand: qcom: enable BAM or ADM mode
  2017-08-17 12:07 [PATCH v5 00/16] Add QCOM QPIC NAND support Abhishek Sahu
                   ` (5 preceding siblings ...)
  2017-08-17 12:07 ` [PATCH v5 06/16] mtd: nand: qcom: erased codeword detection configuration Abhishek Sahu
@ 2017-08-17 12:07 ` Abhishek Sahu
  2017-08-17 12:07 ` [PATCH v5 08/16] mtd: nand: qcom: QPIC data descriptors handling Abhishek Sahu
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Abhishek Sahu @ 2017-08-17 12:07 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: David Woodhouse, Brian Norris, Marek Vasut, Richard Weinberger,
	Cyrille Pitchen, linux-arm-msm, linux-kernel, linux-mtd,
	Andy Gross, Archit Taneja, Sricharan R, Abhishek Sahu

1. DM_EN is only required for EBI2 NAND controller which uses ADM
2. BAM mode will be disabled after power on reset which needs to
   be enabled before starting any BAM transfers.

Reviewed-by: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---

* Changes from v4: None

 drivers/mtd/nand/qcom_nandc.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index 81cfce7..fd77d59 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -163,6 +163,9 @@
 #define NAND_DEV_CMD_VLD_VAL		(READ_START_VLD | WRITE_START_VLD | \
 					 ERASE_START_VLD | SEQ_READ_START_VLD)
 
+/* NAND_CTRL bits */
+#define	BAM_MODE_EN			BIT(0)
+
 /*
  * the NAND controller performs reads/writes with ECC in 516 byte chunks.
  * the driver calls the chunks 'step' or 'codeword' interchangeably
@@ -1042,7 +1045,8 @@ static int read_id(struct qcom_nand_host *host, int column)
 	nandc_set_reg(nandc, NAND_FLASH_CMD, FETCH_ID);
 	nandc_set_reg(nandc, NAND_ADDR0, column);
 	nandc_set_reg(nandc, NAND_ADDR1, 0);
-	nandc_set_reg(nandc, NAND_FLASH_CHIP_SELECT, DM_EN);
+	nandc_set_reg(nandc, NAND_FLASH_CHIP_SELECT,
+		      nandc->props->is_bam ? 0 : DM_EN);
 	nandc_set_reg(nandc, NAND_EXEC_CMD, 1);
 
 	write_reg_dma(nandc, NAND_FLASH_CMD, 4, NAND_BAM_NEXT_SGL);
@@ -2414,12 +2418,19 @@ static void qcom_nandc_unalloc(struct qcom_nand_controller *nandc)
 /* one time setup of a few nand controller registers */
 static int qcom_nandc_setup(struct qcom_nand_controller *nandc)
 {
+	u32 nand_ctrl;
+
 	/* kill onenand */
 	nandc_write(nandc, SFLASHC_BURST_CFG, 0);
 	nandc_write(nandc, NAND_DEV_CMD_VLD, NAND_DEV_CMD_VLD_VAL);
 
-	/* enable ADM DMA */
-	nandc_write(nandc, NAND_FLASH_CHIP_SELECT, DM_EN);
+	/* enable ADM or BAM DMA */
+	if (nandc->props->is_bam) {
+		nand_ctrl = nandc_read(nandc, NAND_CTRL);
+		nandc_write(nandc, NAND_CTRL, nand_ctrl | BAM_MODE_EN);
+	} else {
+		nandc_write(nandc, NAND_FLASH_CHIP_SELECT, DM_EN);
+	}
 
 	/* save the original values of these registers */
 	nandc->cmd1 = nandc_read(nandc, NAND_DEV_CMD1);
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v5 08/16] mtd: nand: qcom: QPIC data descriptors handling
  2017-08-17 12:07 [PATCH v5 00/16] Add QCOM QPIC NAND support Abhishek Sahu
                   ` (6 preceding siblings ...)
  2017-08-17 12:07 ` [PATCH v5 07/16] mtd: nand: qcom: enable BAM or ADM mode Abhishek Sahu
@ 2017-08-17 12:07 ` Abhishek Sahu
  2017-08-17 12:07 ` [PATCH v5 09/16] mtd: nand: qcom: support for different DEV_CMD register offsets Abhishek Sahu
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Abhishek Sahu @ 2017-08-17 12:07 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: David Woodhouse, Brian Norris, Marek Vasut, Richard Weinberger,
	Cyrille Pitchen, linux-arm-msm, linux-kernel, linux-mtd,
	Andy Gross, Archit Taneja, Sricharan R, Abhishek Sahu

1. Add the data descriptor preparation function which will be used
   only by BAM DMA for forming the data SGL’s
2. Add clear BAM transaction and call it before every new request
3. Check DMA mode for ADM or BAM and call the appropriate
   descriptor formation function.

Reviewed-by: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---

* Changes from v4: None

 drivers/mtd/nand/qcom_nandc.c | 76 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index fd77d59..1ff5daf 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -473,6 +473,27 @@ static void free_bam_transaction(struct qcom_nand_controller *nandc)
 	return bam_txn;
 }
 
+/* Clears the BAM transaction indexes */
+static void clear_bam_transaction(struct qcom_nand_controller *nandc)
+{
+	struct bam_transaction *bam_txn = nandc->bam_txn;
+
+	if (!nandc->props->is_bam)
+		return;
+
+	bam_txn->cmd_sgl_pos = 0;
+	bam_txn->cmd_sgl_start = 0;
+	bam_txn->tx_sgl_pos = 0;
+	bam_txn->tx_sgl_start = 0;
+	bam_txn->rx_sgl_pos = 0;
+	bam_txn->rx_sgl_start = 0;
+
+	sg_init_table(bam_txn->cmd_sgl, nandc->max_cwperpage *
+		      QPIC_PER_CW_CMD_SGL);
+	sg_init_table(bam_txn->data_sgl, nandc->max_cwperpage *
+		      QPIC_PER_CW_DATA_SGL);
+}
+
 static inline struct qcom_nand_host *to_qcom_nand_host(struct nand_chip *chip)
 {
 	return container_of(chip, struct qcom_nand_host, chip);
@@ -704,6 +725,41 @@ static int prepare_bam_async_desc(struct qcom_nand_controller *nandc,
 	return 0;
 }
 
+/*
+ * Prepares the data descriptor for BAM DMA which will be used for NAND
+ * data reads and writes.
+ */
+static int prep_bam_dma_desc_data(struct qcom_nand_controller *nandc, bool read,
+				  const void *vaddr,
+				  int size, unsigned int flags)
+{
+	int ret;
+	struct bam_transaction *bam_txn = nandc->bam_txn;
+
+	if (read) {
+		sg_set_buf(&bam_txn->data_sgl[bam_txn->rx_sgl_pos],
+			   vaddr, size);
+		bam_txn->rx_sgl_pos++;
+	} else {
+		sg_set_buf(&bam_txn->data_sgl[bam_txn->tx_sgl_pos],
+			   vaddr, size);
+		bam_txn->tx_sgl_pos++;
+
+		/*
+		 * BAM will only set EOT for DMA_PREP_INTERRUPT so if this flag
+		 * is not set, form the DMA descriptor
+		 */
+		if (!(flags & NAND_BAM_NO_EOT)) {
+			ret = prepare_bam_async_desc(nandc, nandc->tx_chan,
+						     DMA_PREP_INTERRUPT);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
 static int prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read,
 			     int reg_off, const void *vaddr, int size,
 			     bool flow_control)
@@ -854,6 +910,9 @@ static int write_reg_dma(struct qcom_nand_controller *nandc, int first,
 static int read_data_dma(struct qcom_nand_controller *nandc, int reg_off,
 			 const u8 *vaddr, int size, unsigned int flags)
 {
+	if (nandc->props->is_bam)
+		return prep_bam_dma_desc_data(nandc, true, vaddr, size, flags);
+
 	return prep_adm_dma_desc(nandc, true, reg_off, vaddr, size, false);
 }
 
@@ -869,6 +928,9 @@ static int read_data_dma(struct qcom_nand_controller *nandc, int reg_off,
 static int write_data_dma(struct qcom_nand_controller *nandc, int reg_off,
 			  const u8 *vaddr, int size, unsigned int flags)
 {
+	if (nandc->props->is_bam)
+		return prep_bam_dma_desc_data(nandc, false, vaddr, size, flags);
+
 	return prep_adm_dma_desc(nandc, false, reg_off, vaddr, size, false);
 }
 
@@ -1156,6 +1218,10 @@ static void pre_command(struct qcom_nand_host *host, int command)
 	host->last_command = command;
 
 	clear_read_regs(nandc);
+
+	if (command == NAND_CMD_RESET || command == NAND_CMD_READID ||
+	    command == NAND_CMD_PARAM || command == NAND_CMD_ERASE1)
+		clear_bam_transaction(nandc);
 }
 
 /*
@@ -1559,6 +1625,7 @@ static int qcom_nandc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
 	data_buf = buf;
 	oob_buf = oob_required ? chip->oob_poi : NULL;
 
+	clear_bam_transaction(nandc);
 	ret = read_page_ecc(host, data_buf, oob_buf);
 	if (ret) {
 		dev_err(nandc->dev, "failure to read page\n");
@@ -1584,6 +1651,8 @@ static int qcom_nandc_read_page_raw(struct mtd_info *mtd,
 	oob_buf = chip->oob_poi;
 
 	host->use_ecc = false;
+
+	clear_bam_transaction(nandc);
 	update_rw_regs(host, ecc->steps, true);
 	config_nand_page_read(nandc);
 
@@ -1655,6 +1724,7 @@ static int qcom_nandc_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
 	int ret;
 
 	clear_read_regs(nandc);
+	clear_bam_transaction(nandc);
 
 	host->use_ecc = true;
 	set_address(host, 0, page);
@@ -1678,6 +1748,7 @@ static int qcom_nandc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 	int i, ret;
 
 	clear_read_regs(nandc);
+	clear_bam_transaction(nandc);
 
 	data_buf = (u8 *)buf;
 	oob_buf = chip->oob_poi;
@@ -1743,6 +1814,7 @@ static int qcom_nandc_write_page_raw(struct mtd_info *mtd,
 	int i, ret;
 
 	clear_read_regs(nandc);
+	clear_bam_transaction(nandc);
 
 	data_buf = (u8 *)buf;
 	oob_buf = chip->oob_poi;
@@ -1819,11 +1891,13 @@ static int qcom_nandc_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
 
 	host->use_ecc = true;
 
+	clear_bam_transaction(nandc);
 	ret = copy_last_cw(host, page);
 	if (ret)
 		return ret;
 
 	clear_read_regs(nandc);
+	clear_bam_transaction(nandc);
 
 	/* calculate the data and oob size for the last codeword/step */
 	data_size = ecc->size - ((ecc->steps - 1) << 2);
@@ -1876,6 +1950,7 @@ static int qcom_nandc_block_bad(struct mtd_info *mtd, loff_t ofs)
 	 */
 	host->use_ecc = false;
 
+	clear_bam_transaction(nandc);
 	ret = copy_last_cw(host, page);
 	if (ret)
 		goto err;
@@ -1906,6 +1981,7 @@ static int qcom_nandc_block_markbad(struct mtd_info *mtd, loff_t ofs)
 	int page, ret, status = 0;
 
 	clear_read_regs(nandc);
+	clear_bam_transaction(nandc);
 
 	/*
 	 * to mark the BBM as bad, we flash the entire last codeword with 0s.
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v5 09/16] mtd: nand: qcom: support for different DEV_CMD register offsets
  2017-08-17 12:07 [PATCH v5 00/16] Add QCOM QPIC NAND support Abhishek Sahu
                   ` (7 preceding siblings ...)
  2017-08-17 12:07 ` [PATCH v5 08/16] mtd: nand: qcom: QPIC data descriptors handling Abhishek Sahu
@ 2017-08-17 12:07 ` Abhishek Sahu
  2017-08-17 12:07 ` [PATCH v5 10/16] mtd: nand: qcom: add command elements in BAM transaction Abhishek Sahu
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Abhishek Sahu @ 2017-08-17 12:07 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: David Woodhouse, Brian Norris, Marek Vasut, Richard Weinberger,
	Cyrille Pitchen, linux-arm-msm, linux-kernel, linux-mtd,
	Andy Gross, Archit Taneja, Sricharan R, Abhishek Sahu

The FLASH_DEV_CMD registers starting offset is not same in
different QPIC NAND controller versions. This patch adds
the starting offset in NAND controller properties and uses
the same for calculating the actual offset of these registers.

Reviewed-by: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---

* Changes from v4:

1. Changed macro name from nandc_dev_addr to dev_cmd_reg_addr
2. Modified comment for nandc_dev_addr
3. Changed new property variable name from flash_dev_offset to
   dev_cmd_reg_start

 drivers/mtd/nand/qcom_nandc.c | 25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index 1ff5daf..7977a70 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -193,6 +193,12 @@
 	      ((size) << READ_LOCATION_SIZE) |			\
 	      ((is_last) << READ_LOCATION_LAST))
 
+/*
+ * Returns the actual register address for all NAND_DEV_ registers
+ * (i.e. NAND_DEV_CMD0, NAND_DEV_CMD1, NAND_DEV_CMD2 and NAND_DEV_CMD_VLD)
+ */
+#define dev_cmd_reg_addr(nandc, reg) ((nandc)->props->dev_cmd_reg_start + (reg))
+
 #define QPIC_PER_CW_CMD_SGL		32
 #define QPIC_PER_CW_DATA_SGL		8
 
@@ -429,10 +435,12 @@ struct qcom_nand_host {
  * among different NAND controllers.
  * @ecc_modes - ecc mode for NAND
  * @is_bam - whether NAND controller is using BAM
+ * @dev_cmd_reg_start - NAND_DEV_CMD_* registers starting offset
  */
 struct qcom_nandc_props {
 	u32 ecc_modes;
 	bool is_bam;
+	u32 dev_cmd_reg_start;
 };
 
 /* Frees the BAM transaction memory */
@@ -848,6 +856,9 @@ static int read_reg_dma(struct qcom_nand_controller *nandc, int first,
 	if (first == NAND_READ_ID || first == NAND_FLASH_STATUS)
 		flow_control = true;
 
+	if (first == NAND_DEV_CMD_VLD || first == NAND_DEV_CMD1)
+		first = dev_cmd_reg_addr(nandc, first);
+
 	size = num_regs * sizeof(u32);
 	vaddr = nandc->reg_read_buf + nandc->reg_read_pos;
 	nandc->reg_read_pos += num_regs;
@@ -886,11 +897,11 @@ static int write_reg_dma(struct qcom_nand_controller *nandc, int first,
 	if (first == NAND_EXEC_CMD)
 		flags |= NAND_BAM_NWD;
 
-	if (first == NAND_DEV_CMD1_RESTORE)
-		first = NAND_DEV_CMD1;
+	if (first == NAND_DEV_CMD1_RESTORE || first == NAND_DEV_CMD1)
+		first = dev_cmd_reg_addr(nandc, NAND_DEV_CMD1);
 
-	if (first == NAND_DEV_CMD_VLD_RESTORE)
-		first = NAND_DEV_CMD_VLD;
+	if (first == NAND_DEV_CMD_VLD_RESTORE || first == NAND_DEV_CMD_VLD)
+		first = dev_cmd_reg_addr(nandc, NAND_DEV_CMD_VLD);
 
 	size = num_regs * sizeof(u32);
 
@@ -2498,7 +2509,8 @@ static int qcom_nandc_setup(struct qcom_nand_controller *nandc)
 
 	/* kill onenand */
 	nandc_write(nandc, SFLASHC_BURST_CFG, 0);
-	nandc_write(nandc, NAND_DEV_CMD_VLD, NAND_DEV_CMD_VLD_VAL);
+	nandc_write(nandc, dev_cmd_reg_addr(nandc, NAND_DEV_CMD_VLD),
+		    NAND_DEV_CMD_VLD_VAL);
 
 	/* enable ADM or BAM DMA */
 	if (nandc->props->is_bam) {
@@ -2509,7 +2521,7 @@ static int qcom_nandc_setup(struct qcom_nand_controller *nandc)
 	}
 
 	/* save the original values of these registers */
-	nandc->cmd1 = nandc_read(nandc, NAND_DEV_CMD1);
+	nandc->cmd1 = nandc_read(nandc, dev_cmd_reg_addr(nandc, NAND_DEV_CMD1));
 	nandc->vld = NAND_DEV_CMD_VLD_VAL;
 
 	return 0;
@@ -2758,6 +2770,7 @@ static int qcom_nandc_remove(struct platform_device *pdev)
 static const struct qcom_nandc_props ipq806x_nandc_props = {
 	.ecc_modes = (ECC_RS_4BIT | ECC_BCH_8BIT),
 	.is_bam = false,
+	.dev_cmd_reg_start = 0x0,
 };
 
 /*
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v5 10/16] mtd: nand: qcom: add command elements in BAM transaction
  2017-08-17 12:07 [PATCH v5 00/16] Add QCOM QPIC NAND support Abhishek Sahu
                   ` (8 preceding siblings ...)
  2017-08-17 12:07 ` [PATCH v5 09/16] mtd: nand: qcom: support for different DEV_CMD register offsets Abhishek Sahu
@ 2017-08-17 12:07 ` Abhishek Sahu
  2017-08-19  9:32   ` Abhishek Sahu
  2017-08-17 12:07 ` [PATCH v5 11/16] mtd: nand: qcom: support for command descriptor formation Abhishek Sahu
                   ` (6 subsequent siblings)
  16 siblings, 1 reply; 26+ messages in thread
From: Abhishek Sahu @ 2017-08-17 12:07 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: David Woodhouse, Brian Norris, Marek Vasut, Richard Weinberger,
	Cyrille Pitchen, linux-arm-msm, linux-kernel, linux-mtd,
	Andy Gross, Archit Taneja, Sricharan R, Abhishek Sahu,
	Vinod Koul, dmaengine

All the QPIC register read/write through BAM DMA requires
command descriptor which contains the array of command elements.

Reviewed-by: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---

* Changes from v4: None

* BUILD DEPENDENCY:

  This PATCH has build dependency over following BAM command descriptor
  patch posted in DMA engine mailing list

  http://www.spinics.net/lists/dmaengine/msg13665.html

 drivers/mtd/nand/qcom_nandc.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index 7977a70..b0a4734 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -22,6 +22,7 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/delay.h>
+#include <linux/dma/qcom_bam_dma.h>
 
 /* NANDc reg offsets */
 #define	NAND_FLASH_CMD			0x00
@@ -199,6 +200,7 @@
  */
 #define dev_cmd_reg_addr(nandc, reg) ((nandc)->props->dev_cmd_reg_start + (reg))
 
+#define QPIC_PER_CW_CMD_ELEMENTS	32
 #define QPIC_PER_CW_CMD_SGL		32
 #define QPIC_PER_CW_DATA_SGL		8
 
@@ -221,8 +223,13 @@
 /*
  * This data type corresponds to the BAM transaction which will be used for all
  * NAND transfers.
+ * @bam_ce - the array of BAM command elements
  * @cmd_sgl - sgl for NAND BAM command pipe
  * @data_sgl - sgl for NAND BAM consumer/producer pipe
+ * @bam_ce_pos - the index in bam_ce which is available for next sgl
+ * @bam_ce_start - the index in bam_ce which marks the start position ce
+ *		   for current sgl. It will be used for size calculation
+ *		   for current sgl
  * @cmd_sgl_pos - current index in command sgl.
  * @cmd_sgl_start - start index in command sgl.
  * @tx_sgl_pos - current index in data sgl for tx.
@@ -231,8 +238,11 @@
  * @rx_sgl_start - start index in data sgl for rx.
  */
 struct bam_transaction {
+	struct bam_cmd_element *bam_ce;
 	struct scatterlist *cmd_sgl;
 	struct scatterlist *data_sgl;
+	u32 bam_ce_pos;
+	u32 bam_ce_start;
 	u32 cmd_sgl_pos;
 	u32 cmd_sgl_start;
 	u32 tx_sgl_pos;
@@ -462,7 +472,8 @@ static void free_bam_transaction(struct qcom_nand_controller *nandc)
 
 	bam_txn_size =
 		sizeof(*bam_txn) + num_cw *
-		((sizeof(*bam_txn->cmd_sgl) * QPIC_PER_CW_CMD_SGL) +
+		((sizeof(*bam_txn->bam_ce) * QPIC_PER_CW_CMD_ELEMENTS) +
+		(sizeof(*bam_txn->cmd_sgl) * QPIC_PER_CW_CMD_SGL) +
 		(sizeof(*bam_txn->data_sgl) * QPIC_PER_CW_DATA_SGL));
 
 	bam_txn_buf = devm_kzalloc(nandc->dev, bam_txn_size, GFP_KERNEL);
@@ -472,6 +483,10 @@ static void free_bam_transaction(struct qcom_nand_controller *nandc)
 	bam_txn = bam_txn_buf;
 	bam_txn_buf += sizeof(*bam_txn);
 
+	bam_txn->bam_ce = bam_txn_buf;
+	bam_txn_buf +=
+		sizeof(*bam_txn->bam_ce) * QPIC_PER_CW_CMD_ELEMENTS * num_cw;
+
 	bam_txn->cmd_sgl = bam_txn_buf;
 	bam_txn_buf +=
 		sizeof(*bam_txn->cmd_sgl) * QPIC_PER_CW_CMD_SGL * num_cw;
@@ -489,6 +504,8 @@ static void clear_bam_transaction(struct qcom_nand_controller *nandc)
 	if (!nandc->props->is_bam)
 		return;
 
+	bam_txn->bam_ce_pos = 0;
+	bam_txn->bam_ce_start = 0;
 	bam_txn->cmd_sgl_pos = 0;
 	bam_txn->cmd_sgl_start = 0;
 	bam_txn->tx_sgl_pos = 0;
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v5 11/16] mtd: nand: qcom: support for command descriptor formation
  2017-08-17 12:07 [PATCH v5 00/16] Add QCOM QPIC NAND support Abhishek Sahu
                   ` (9 preceding siblings ...)
  2017-08-17 12:07 ` [PATCH v5 10/16] mtd: nand: qcom: add command elements in BAM transaction Abhishek Sahu
@ 2017-08-17 12:07 ` Abhishek Sahu
  2017-08-19  9:47   ` Abhishek Sahu
  2017-08-17 12:07 ` [PATCH v5 12/16] dt-bindings: qcom_nandc: fix the ipq806x device tree example Abhishek Sahu
                   ` (5 subsequent siblings)
  16 siblings, 1 reply; 26+ messages in thread
From: Abhishek Sahu @ 2017-08-17 12:07 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: David Woodhouse, Brian Norris, Marek Vasut, Richard Weinberger,
	Cyrille Pitchen, linux-arm-msm, linux-kernel, linux-mtd,
	Andy Gross, Archit Taneja, Sricharan R, Abhishek Sahu,
	vinod.koul, dmaengine

1. Add the function for command descriptor preparation which will
   be used only by BAM DMA and it will form the DMA descriptors
   containing command elements
2. DMA_PREP_CMD flag should be used for forming command DMA
   descriptors

Reviewed-by: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---

* Changes from v4: None

* BUILD DEPENDENCY:

 This PATCH has build dependency over following BAM command descriptor
 patch posted in DMA engine mailing list

 http://www.spinics.net/lists/dmaengine/msg13665.html

 drivers/mtd/nand/qcom_nandc.c | 108 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 92 insertions(+), 16 deletions(-)

diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index b0a4734..52d9fae 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -200,6 +200,14 @@
  */
 #define dev_cmd_reg_addr(nandc, reg) ((nandc)->props->dev_cmd_reg_start + (reg))
 
+/* Returns the NAND register physical address */
+#define nandc_reg_phys(chip, offset) ((chip)->base_phys + (offset))
+
+/* Returns the dma address for reg read buffer */
+#define reg_buf_dma_addr(chip, vaddr) \
+	((chip)->reg_read_dma + \
+	((uint8_t *)(vaddr) - (uint8_t *)(chip)->reg_read_buf))
+
 #define QPIC_PER_CW_CMD_ELEMENTS	32
 #define QPIC_PER_CW_CMD_SGL		32
 #define QPIC_PER_CW_DATA_SGL		8
@@ -317,7 +325,8 @@ struct nandc_regs {
  *				controller
  * @dev:			parent device
  * @base:			MMIO base
- * @base_dma:			physical base address of controller registers
+ * @base_phys:			physical base address of controller registers
+ * @base_dma:			dma base address of controller registers
  * @core_clk:			controller clock
  * @aon_clk:			another controller clock
  *
@@ -350,6 +359,7 @@ struct qcom_nand_controller {
 	struct device *dev;
 
 	void __iomem *base;
+	phys_addr_t base_phys;
 	dma_addr_t base_dma;
 
 	struct clk *core_clk;
@@ -751,6 +761,66 @@ static int prepare_bam_async_desc(struct qcom_nand_controller *nandc,
 }
 
 /*
+ * Prepares the command descriptor for BAM DMA which will be used for NAND
+ * register reads and writes. The command descriptor requires the command
+ * to be formed in command element type so this function uses the command
+ * element from bam transaction ce array and fills the same with required
+ * data. A single SGL can contain multiple command elements so
+ * NAND_BAM_NEXT_SGL will be used for starting the separate SGL
+ * after the current command element.
+ */
+static int prep_bam_dma_desc_cmd(struct qcom_nand_controller *nandc, bool read,
+				 int reg_off, const void *vaddr,
+				 int size, unsigned int flags)
+{
+	int bam_ce_size;
+	int i, ret;
+	struct bam_cmd_element *bam_ce_buffer;
+	struct bam_transaction *bam_txn = nandc->bam_txn;
+
+	bam_ce_buffer = &bam_txn->bam_ce[bam_txn->bam_ce_pos];
+
+	/* fill the command desc */
+	for (i = 0; i < size; i++) {
+		if (read)
+			bam_prep_ce(&bam_ce_buffer[i],
+				    nandc_reg_phys(nandc, reg_off + 4 * i),
+				    BAM_READ_COMMAND,
+				    reg_buf_dma_addr(nandc,
+						     (__le32 *)vaddr + i));
+		else
+			bam_prep_ce_le32(&bam_ce_buffer[i],
+					 nandc_reg_phys(nandc, reg_off + 4 * i),
+					 BAM_WRITE_COMMAND,
+					 *((__le32 *)vaddr + i));
+	}
+
+	bam_txn->bam_ce_pos += size;
+
+	/* use the separate sgl after this command */
+	if (flags & NAND_BAM_NEXT_SGL) {
+		bam_ce_buffer = &bam_txn->bam_ce[bam_txn->bam_ce_start];
+		bam_ce_size = (bam_txn->bam_ce_pos -
+				bam_txn->bam_ce_start) *
+				sizeof(struct bam_cmd_element);
+		sg_set_buf(&bam_txn->cmd_sgl[bam_txn->cmd_sgl_pos],
+			   bam_ce_buffer, bam_ce_size);
+		bam_txn->cmd_sgl_pos++;
+		bam_txn->bam_ce_start = bam_txn->bam_ce_pos;
+
+		if (flags & NAND_BAM_NWD) {
+			ret = prepare_bam_async_desc(nandc, nandc->cmd_chan,
+						     DMA_PREP_FENCE |
+						     DMA_PREP_CMD);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
+/*
  * Prepares the data descriptor for BAM DMA which will be used for NAND
  * data reads and writes.
  */
@@ -868,19 +938,22 @@ static int read_reg_dma(struct qcom_nand_controller *nandc, int first,
 {
 	bool flow_control = false;
 	void *vaddr;
-	int size;
 
-	if (first == NAND_READ_ID || first == NAND_FLASH_STATUS)
-		flow_control = true;
+	vaddr = nandc->reg_read_buf + nandc->reg_read_pos;
+	nandc->reg_read_pos += num_regs;
 
 	if (first == NAND_DEV_CMD_VLD || first == NAND_DEV_CMD1)
 		first = dev_cmd_reg_addr(nandc, first);
 
-	size = num_regs * sizeof(u32);
-	vaddr = nandc->reg_read_buf + nandc->reg_read_pos;
-	nandc->reg_read_pos += num_regs;
+	if (nandc->props->is_bam)
+		return prep_bam_dma_desc_cmd(nandc, true, first, vaddr,
+					     num_regs, flags);
 
-	return prep_adm_dma_desc(nandc, true, first, vaddr, size, flow_control);
+	if (first == NAND_READ_ID || first == NAND_FLASH_STATUS)
+		flow_control = true;
+
+	return prep_adm_dma_desc(nandc, true, first, vaddr,
+				 num_regs * sizeof(u32), flow_control);
 }
 
 /*
@@ -897,13 +970,9 @@ static int write_reg_dma(struct qcom_nand_controller *nandc, int first,
 	bool flow_control = false;
 	struct nandc_regs *regs = nandc->regs;
 	void *vaddr;
-	int size;
 
 	vaddr = offset_to_nandc_reg(regs, first);
 
-	if (first == NAND_FLASH_CMD)
-		flow_control = true;
-
 	if (first == NAND_ERASED_CW_DETECT_CFG) {
 		if (flags & NAND_ERASED_CW_SET)
 			vaddr = &regs->erased_cw_detect_cfg_set;
@@ -920,10 +989,15 @@ static int write_reg_dma(struct qcom_nand_controller *nandc, int first,
 	if (first == NAND_DEV_CMD_VLD_RESTORE || first == NAND_DEV_CMD_VLD)
 		first = dev_cmd_reg_addr(nandc, NAND_DEV_CMD_VLD);
 
-	size = num_regs * sizeof(u32);
+	if (nandc->props->is_bam)
+		return prep_bam_dma_desc_cmd(nandc, false, first, vaddr,
+					     num_regs, flags);
+
+	if (first == NAND_FLASH_CMD)
+		flow_control = true;
 
-	return prep_adm_dma_desc(nandc, false, first, vaddr, size,
-				 flow_control);
+	return prep_adm_dma_desc(nandc, false, first, vaddr,
+				 num_regs * sizeof(u32), flow_control);
 }
 
 /*
@@ -1187,7 +1261,8 @@ static int submit_descs(struct qcom_nand_controller *nandc)
 		}
 
 		if (bam_txn->cmd_sgl_pos > bam_txn->cmd_sgl_start) {
-			r = prepare_bam_async_desc(nandc, nandc->cmd_chan, 0);
+			r = prepare_bam_async_desc(nandc, nandc->cmd_chan,
+						   DMA_PREP_CMD);
 			if (r)
 				return r;
 		}
@@ -2722,6 +2797,7 @@ static int qcom_nandc_probe(struct platform_device *pdev)
 	if (IS_ERR(nandc->base))
 		return PTR_ERR(nandc->base);
 
+	nandc->base_phys = res->start;
 	nandc->base_dma = phys_to_dma(dev, (phys_addr_t)res->start);
 
 	nandc->core_clk = devm_clk_get(dev, "core");
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v5 12/16] dt-bindings: qcom_nandc: fix the ipq806x device tree example
  2017-08-17 12:07 [PATCH v5 00/16] Add QCOM QPIC NAND support Abhishek Sahu
                   ` (10 preceding siblings ...)
  2017-08-17 12:07 ` [PATCH v5 11/16] mtd: nand: qcom: support for command descriptor formation Abhishek Sahu
@ 2017-08-17 12:07 ` Abhishek Sahu
  2017-08-17 12:07 ` [PATCH v5 13/16] dt-bindings: qcom_nandc: IPQ4019 QPIC NAND documentation Abhishek Sahu
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Abhishek Sahu @ 2017-08-17 12:07 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: David Woodhouse, Brian Norris, Marek Vasut, Richard Weinberger,
	Cyrille Pitchen, linux-arm-msm, linux-kernel, linux-mtd,
	Andy Gross, Archit Taneja, Sricharan R, Abhishek Sahu

1. Correct the compatible string for IPQ806x
2. Change the NAND controller and NAND chip nodes name
   for more clarity.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---

* Changes from v4: None

 Documentation/devicetree/bindings/mtd/qcom_nandc.txt | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/qcom_nandc.txt b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
index 26360fe..f475b65 100644
--- a/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
+++ b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
@@ -42,8 +42,8 @@ partition.txt for more detail.
 
 Example:
 
-nand@1ac00000 {
-	compatible = "qcom,ebi2-nandc";
+nand-controller@1ac00000 {
+	compatible = "qcom,ipq806x-nand";
 	reg = <0x1ac00000 0x800>;
 
 	clocks = <&gcc EBI2_CLK>,
@@ -58,7 +58,7 @@ nand@1ac00000 {
 	#address-cells = <1>;
 	#size-cells = <0>;
 
-	nandcs@0 {
+	nand@0 {
 		reg = <0>;
 
 		nand-ecc-strength = <4>;
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v5 13/16] dt-bindings: qcom_nandc: IPQ4019 QPIC NAND documentation
  2017-08-17 12:07 [PATCH v5 00/16] Add QCOM QPIC NAND support Abhishek Sahu
                   ` (11 preceding siblings ...)
  2017-08-17 12:07 ` [PATCH v5 12/16] dt-bindings: qcom_nandc: fix the ipq806x device tree example Abhishek Sahu
@ 2017-08-17 12:07 ` Abhishek Sahu
  2017-08-17 12:07 ` [PATCH v5 14/16] dt-bindings: qcom_nandc: IPQ8074 " Abhishek Sahu
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 26+ messages in thread
From: Abhishek Sahu @ 2017-08-17 12:07 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: David Woodhouse, Brian Norris, Marek Vasut, Richard Weinberger,
	Cyrille Pitchen, linux-arm-msm, linux-kernel, linux-mtd,
	Andy Gross, Archit Taneja, Sricharan R, Abhishek Sahu

1. Qualcom IPQ4019 SoC uses QPIC NAND controller version 1.4.0
   which uses BAM DMA Engine while IPQ806x uses EBI2 NAND
   which uses ADM DMA Engine.
2. QPIC NAND will 3 BAM channels: command, data tx and data rx
   while EBI2 NAND uses only single ADM channel.
3. CRCI is only required for ADM DMA and its not required for
   BAM DMA.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---

* Changes from v4: None

 .../devicetree/bindings/mtd/qcom_nandc.txt         | 55 +++++++++++++++++++++-
 1 file changed, 54 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mtd/qcom_nandc.txt b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
index f475b65..d93b952 100644
--- a/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
+++ b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
@@ -1,11 +1,18 @@
 * Qualcomm NAND controller
 
 Required properties:
-- compatible:		should be "qcom,ipq806x-nand"
+- compatible:		must be one of the following:
+    * "qcom,ipq806x-nand" - for EBI2 NAND controller being used in IPQ806x
+			    SoC and it uses ADM DMA
+    * "qcom,ipq4019-nand" - for QPIC NAND controller v1.4.0 being used in
+                            IPQ4019 SoC and it uses BAM DMA
+
 - reg:			MMIO address range
 - clocks:		must contain core clock and always on clock
 - clock-names:		must contain "core" for the core clock and "aon" for the
 			always on clock
+
+EBI2 specific properties:
 - dmas:			DMA specifier, consisting of a phandle to the ADM DMA
 			controller node and the channel number to be used for
 			NAND. Refer to dma.txt and qcom_adm.txt for more details
@@ -16,6 +23,12 @@ Required properties:
 - qcom,data-crci:	must contain the ADM data type CRCI block instance
 			number specified for the NAND controller on the given
 			platform
+
+QPIC specific properties:
+- dmas:			DMA specifier, consisting of a phandle to the BAM DMA
+			and the channel number to be used for NAND. Refer to
+			dma.txt, qcom_bam_dma.txt for more details
+- dma-names:		must contain all 3 channel names : "tx", "rx", "cmd"
 - #address-cells:	<1> - subnodes give the chip-select number
 - #size-cells:		<0>
 
@@ -82,3 +95,43 @@ nand-controller@1ac00000 {
 		};
 	};
 };
+
+nand-controller@79b0000 {
+	compatible = "qcom,ipq4019-nand";
+	reg = <0x79b0000 0x1000>;
+
+	clocks = <&gcc GCC_QPIC_CLK>,
+		<&gcc GCC_QPIC_AHB_CLK>;
+	clock-names = "core", "aon";
+
+	dmas = <&qpicbam 0>,
+		<&qpicbam 1>,
+		<&qpicbam 2>;
+	dma-names = "tx", "rx", "cmd";
+
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	nand@0 {
+		reg = <0>;
+		nand-ecc-strength = <4>;
+		nand-ecc-step-size = <512>;
+		nand-bus-width = <8>;
+
+		partitions {
+			compatible = "fixed-partitions";
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			partition@0 {
+				label = "boot-nand";
+				reg = <0 0x58a0000>;
+			};
+
+			partition@58a0000 {
+				label = "fs-nand";
+				reg = <0x58a0000 0x4000000>;
+			};
+		};
+	};
+};
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v5 14/16] dt-bindings: qcom_nandc: IPQ8074 QPIC NAND documentation
  2017-08-17 12:07 [PATCH v5 00/16] Add QCOM QPIC NAND support Abhishek Sahu
                   ` (12 preceding siblings ...)
  2017-08-17 12:07 ` [PATCH v5 13/16] dt-bindings: qcom_nandc: IPQ4019 QPIC NAND documentation Abhishek Sahu
@ 2017-08-17 12:07 ` Abhishek Sahu
       [not found]   ` <1502971674-13810-15-git-send-email-absahu-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
  2017-08-17 12:07 ` [PATCH v5 15/16] mtd: nand: qcom: support for IPQ4019 QPIC NAND controller Abhishek Sahu
                   ` (2 subsequent siblings)
  16 siblings, 1 reply; 26+ messages in thread
From: Abhishek Sahu @ 2017-08-17 12:07 UTC (permalink / raw)
  To: Boris Brezillon, Rob Herring
  Cc: David Woodhouse, Brian Norris, Marek Vasut, Richard Weinberger,
	Cyrille Pitchen, linux-arm-msm, linux-kernel, linux-mtd,
	Andy Gross, Archit Taneja, Sricharan R, Abhishek Sahu,
	Mark Rutland, devicetree

Qualcom IPQ8074 SoC uses QPIC NAND controller version 1.5.0
which uses BAM DMA Engine.

Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---

* Changes from v4: None

 Documentation/devicetree/bindings/mtd/qcom_nandc.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/mtd/qcom_nandc.txt b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
index d93b952..73d336be 100644
--- a/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
+++ b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
@@ -6,6 +6,8 @@ Required properties:
 			    SoC and it uses ADM DMA
     * "qcom,ipq4019-nand" - for QPIC NAND controller v1.4.0 being used in
                             IPQ4019 SoC and it uses BAM DMA
+    * "qcom,ipq8074-nand" - for QPIC NAND controller v1.5.0 being used in
+                            IPQ8074 SoC and it uses BAM DMA
 
 - reg:			MMIO address range
 - clocks:		must contain core clock and always on clock
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v5 15/16] mtd: nand: qcom: support for IPQ4019 QPIC NAND controller
  2017-08-17 12:07 [PATCH v5 00/16] Add QCOM QPIC NAND support Abhishek Sahu
                   ` (13 preceding siblings ...)
  2017-08-17 12:07 ` [PATCH v5 14/16] dt-bindings: qcom_nandc: IPQ8074 " Abhishek Sahu
@ 2017-08-17 12:07 ` Abhishek Sahu
  2017-08-17 12:07 ` [PATCH v5 16/16] mtd: nand: qcom: Support for IPQ8074 " Abhishek Sahu
  2017-08-21 20:15 ` [PATCH v5 00/16] Add QCOM QPIC NAND support Boris Brezillon
  16 siblings, 0 replies; 26+ messages in thread
From: Abhishek Sahu @ 2017-08-17 12:07 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: David Woodhouse, Brian Norris, Marek Vasut, Richard Weinberger,
	Cyrille Pitchen, linux-arm-msm, linux-kernel, linux-mtd,
	Andy Gross, Archit Taneja, Sricharan R, Abhishek Sahu

Add the compatible string for IPQ4019 QPIC NAND controller
version 1.4.0 which uses BAM DMA.

Reviewed-by: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---

* Changes from v4: None

 drivers/mtd/nand/qcom_nandc.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index 52d9fae..84fcdb3 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -2866,6 +2866,12 @@ static int qcom_nandc_remove(struct platform_device *pdev)
 	.dev_cmd_reg_start = 0x0,
 };
 
+static const struct qcom_nandc_props ipq4019_nandc_props = {
+	.ecc_modes = (ECC_BCH_4BIT | ECC_BCH_8BIT),
+	.is_bam = true,
+	.dev_cmd_reg_start = 0x0,
+};
+
 /*
  * data will hold a struct pointer containing more differences once we support
  * more controller variants
@@ -2875,6 +2881,10 @@ static int qcom_nandc_remove(struct platform_device *pdev)
 		.compatible = "qcom,ipq806x-nand",
 		.data = &ipq806x_nandc_props,
 	},
+	{
+		.compatible = "qcom,ipq4019-nand",
+		.data = &ipq4019_nandc_props,
+	},
 	{}
 };
 MODULE_DEVICE_TABLE(of, qcom_nandc_of_match);
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v5 16/16] mtd: nand: qcom: Support for IPQ8074 QPIC NAND controller
  2017-08-17 12:07 [PATCH v5 00/16] Add QCOM QPIC NAND support Abhishek Sahu
                   ` (14 preceding siblings ...)
  2017-08-17 12:07 ` [PATCH v5 15/16] mtd: nand: qcom: support for IPQ4019 QPIC NAND controller Abhishek Sahu
@ 2017-08-17 12:07 ` Abhishek Sahu
  2017-08-21 20:15 ` [PATCH v5 00/16] Add QCOM QPIC NAND support Boris Brezillon
  16 siblings, 0 replies; 26+ messages in thread
From: Abhishek Sahu @ 2017-08-17 12:07 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: David Woodhouse, Brian Norris, Marek Vasut, Richard Weinberger,
	Cyrille Pitchen, linux-arm-msm, linux-kernel, linux-mtd,
	Andy Gross, Archit Taneja, Sricharan R, Abhishek Sahu

Add the compatible string for IPQ8074 QPIC NAND controller
version 1.5.0 which uses BAM DMA and its FLASH_DEV_CMD registers
starting offset is 0x7000.

Reviewed-by: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---

* Changes from v4: None

 drivers/mtd/nand/qcom_nandc.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index 84fcdb3..97ce16a 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -2872,6 +2872,12 @@ static int qcom_nandc_remove(struct platform_device *pdev)
 	.dev_cmd_reg_start = 0x0,
 };
 
+static const struct qcom_nandc_props ipq8074_nandc_props = {
+	.ecc_modes = (ECC_BCH_4BIT | ECC_BCH_8BIT),
+	.is_bam = true,
+	.dev_cmd_reg_start = 0x7000,
+};
+
 /*
  * data will hold a struct pointer containing more differences once we support
  * more controller variants
@@ -2885,6 +2891,10 @@ static int qcom_nandc_remove(struct platform_device *pdev)
 		.compatible = "qcom,ipq4019-nand",
 		.data = &ipq4019_nandc_props,
 	},
+	{
+		.compatible = "qcom,ipq8074-nand",
+		.data = &ipq8074_nandc_props,
+	},
 	{}
 };
 MODULE_DEVICE_TABLE(of, qcom_nandc_of_match);
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH v5 10/16] mtd: nand: qcom: add command elements in BAM transaction
  2017-08-17 12:07 ` [PATCH v5 10/16] mtd: nand: qcom: add command elements in BAM transaction Abhishek Sahu
@ 2017-08-19  9:32   ` Abhishek Sahu
  0 siblings, 0 replies; 26+ messages in thread
From: Abhishek Sahu @ 2017-08-19  9:32 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: David Woodhouse, Brian Norris, Marek Vasut, Richard Weinberger,
	Cyrille Pitchen, linux-arm-msm, linux-kernel, linux-mtd,
	Andy Gross, Archit Taneja, Sricharan R, Vinod Koul, dmaengine

On 2017-08-17 17:37, Abhishek Sahu wrote:
> All the QPIC register read/write through BAM DMA requires
> command descriptor which contains the array of command elements.
> 
> Reviewed-by: Archit Taneja <architt@codeaurora.org>
> Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
> ---
> 
> * Changes from v4: None
> 
> * BUILD DEPENDENCY:
> 
>   This PATCH has build dependency over following BAM command descriptor
>   patch posted in DMA engine mailing list
> 
>   http://www.spinics.net/lists/dmaengine/msg13665.html

  Hi Boris,

  These patch has build dependency over DMA engine patch
  http://www.spinics.net/lists/dmaengine/msg13665.html

  but this patch has been applied in your github
  https://github.com/bbrezillon/linux-0day/commits/nand/next

  The DMA change has not merged yet so could we drop this and
  next patch alone till the the DMA change is merged to prevent
  build error.

  Rest of the patch can go without any build or functionality
  failure.

  Thanks,
  Abhishek

> 
>  drivers/mtd/nand/qcom_nandc.c | 19 ++++++++++++++++++-
>  1 file changed, 18 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/nand/qcom_nandc.c 
> b/drivers/mtd/nand/qcom_nandc.c
> index 7977a70..b0a4734 100644
> --- a/drivers/mtd/nand/qcom_nandc.c
> +++ b/drivers/mtd/nand/qcom_nandc.c
> @@ -22,6 +22,7 @@
>  #include <linux/of.h>
>  #include <linux/of_device.h>
>  #include <linux/delay.h>
> +#include <linux/dma/qcom_bam_dma.h>
> 
>  /* NANDc reg offsets */
>  #define	NAND_FLASH_CMD			0x00
> @@ -199,6 +200,7 @@
>   */
>  #define dev_cmd_reg_addr(nandc, reg)
> ((nandc)->props->dev_cmd_reg_start + (reg))
> 
> +#define QPIC_PER_CW_CMD_ELEMENTS	32
>  #define QPIC_PER_CW_CMD_SGL		32
>  #define QPIC_PER_CW_DATA_SGL		8
> 
> @@ -221,8 +223,13 @@
>  /*
>   * This data type corresponds to the BAM transaction which will be 
> used for all
>   * NAND transfers.
> + * @bam_ce - the array of BAM command elements
>   * @cmd_sgl - sgl for NAND BAM command pipe
>   * @data_sgl - sgl for NAND BAM consumer/producer pipe
> + * @bam_ce_pos - the index in bam_ce which is available for next sgl
> + * @bam_ce_start - the index in bam_ce which marks the start position 
> ce
> + *		   for current sgl. It will be used for size calculation
> + *		   for current sgl
>   * @cmd_sgl_pos - current index in command sgl.
>   * @cmd_sgl_start - start index in command sgl.
>   * @tx_sgl_pos - current index in data sgl for tx.
> @@ -231,8 +238,11 @@
>   * @rx_sgl_start - start index in data sgl for rx.
>   */
>  struct bam_transaction {
> +	struct bam_cmd_element *bam_ce;
>  	struct scatterlist *cmd_sgl;
>  	struct scatterlist *data_sgl;
> +	u32 bam_ce_pos;
> +	u32 bam_ce_start;
>  	u32 cmd_sgl_pos;
>  	u32 cmd_sgl_start;
>  	u32 tx_sgl_pos;
> @@ -462,7 +472,8 @@ static void free_bam_transaction(struct
> qcom_nand_controller *nandc)
> 
>  	bam_txn_size =
>  		sizeof(*bam_txn) + num_cw *
> -		((sizeof(*bam_txn->cmd_sgl) * QPIC_PER_CW_CMD_SGL) +
> +		((sizeof(*bam_txn->bam_ce) * QPIC_PER_CW_CMD_ELEMENTS) +
> +		(sizeof(*bam_txn->cmd_sgl) * QPIC_PER_CW_CMD_SGL) +
>  		(sizeof(*bam_txn->data_sgl) * QPIC_PER_CW_DATA_SGL));
> 
>  	bam_txn_buf = devm_kzalloc(nandc->dev, bam_txn_size, GFP_KERNEL);
> @@ -472,6 +483,10 @@ static void free_bam_transaction(struct
> qcom_nand_controller *nandc)
>  	bam_txn = bam_txn_buf;
>  	bam_txn_buf += sizeof(*bam_txn);
> 
> +	bam_txn->bam_ce = bam_txn_buf;
> +	bam_txn_buf +=
> +		sizeof(*bam_txn->bam_ce) * QPIC_PER_CW_CMD_ELEMENTS * num_cw;
> +
>  	bam_txn->cmd_sgl = bam_txn_buf;
>  	bam_txn_buf +=
>  		sizeof(*bam_txn->cmd_sgl) * QPIC_PER_CW_CMD_SGL * num_cw;
> @@ -489,6 +504,8 @@ static void clear_bam_transaction(struct
> qcom_nand_controller *nandc)
>  	if (!nandc->props->is_bam)
>  		return;
> 
> +	bam_txn->bam_ce_pos = 0;
> +	bam_txn->bam_ce_start = 0;
>  	bam_txn->cmd_sgl_pos = 0;
>  	bam_txn->cmd_sgl_start = 0;
>  	bam_txn->tx_sgl_pos = 0;

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v5 11/16] mtd: nand: qcom: support for command descriptor formation
  2017-08-17 12:07 ` [PATCH v5 11/16] mtd: nand: qcom: support for command descriptor formation Abhishek Sahu
@ 2017-08-19  9:47   ` Abhishek Sahu
  2017-08-19 20:38     ` Boris Brezillon
  0 siblings, 1 reply; 26+ messages in thread
From: Abhishek Sahu @ 2017-08-19  9:47 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: David Woodhouse, Brian Norris, Marek Vasut, Richard Weinberger,
	Cyrille Pitchen, linux-arm-msm, linux-kernel, linux-mtd,
	Andy Gross, Archit Taneja, Sricharan R, vinod.koul, dmaengine

On 2017-08-17 17:37, Abhishek Sahu wrote:
> 1. Add the function for command descriptor preparation which will
>    be used only by BAM DMA and it will form the DMA descriptors
>    containing command elements
> 2. DMA_PREP_CMD flag should be used for forming command DMA
>    descriptors
> 
> Reviewed-by: Archit Taneja <architt@codeaurora.org>
> Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
> ---
> 
> * Changes from v4: None
> 
> * BUILD DEPENDENCY:
> 
>  This PATCH has build dependency over following BAM command descriptor
>  patch posted in DMA engine mailing list
> 
>  http://www.spinics.net/lists/dmaengine/msg13665.html
> 

  Hi Boris,

  These patch has build dependency over DMA engine patch
  http://www.spinics.net/lists/dmaengine/msg13665.html

  but this patch has been applied in your github
  https://github.com/bbrezillon/linux-0day/commits/nand/next

  The DMA change has not merged yet so could we drop this and
  previous patch alone till the the DMA change is merged to prevent
  build error.

  Rest of the patch can go without any build or functionality
  failure.

>  drivers/mtd/nand/qcom_nandc.c | 108 
> +++++++++++++++++++++++++++++++++++-------
>  1 file changed, 92 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/mtd/nand/qcom_nandc.c 
> b/drivers/mtd/nand/qcom_nandc.c
> index b0a4734..52d9fae 100644
> --- a/drivers/mtd/nand/qcom_nandc.c
> +++ b/drivers/mtd/nand/qcom_nandc.c
> @@ -200,6 +200,14 @@
>   */
>  #define dev_cmd_reg_addr(nandc, reg)
> ((nandc)->props->dev_cmd_reg_start + (reg))
> 
> +/* Returns the NAND register physical address */
> +#define nandc_reg_phys(chip, offset) ((chip)->base_phys + (offset))
> +
> +/* Returns the dma address for reg read buffer */
> +#define reg_buf_dma_addr(chip, vaddr) \
> +	((chip)->reg_read_dma + \
> +	((uint8_t *)(vaddr) - (uint8_t *)(chip)->reg_read_buf))
> +
>  #define QPIC_PER_CW_CMD_ELEMENTS	32
>  #define QPIC_PER_CW_CMD_SGL		32
>  #define QPIC_PER_CW_DATA_SGL		8
> @@ -317,7 +325,8 @@ struct nandc_regs {
>   *				controller
>   * @dev:			parent device
>   * @base:			MMIO base
> - * @base_dma:			physical base address of controller registers
> + * @base_phys:			physical base address of controller registers
> + * @base_dma:			dma base address of controller registers
>   * @core_clk:			controller clock
>   * @aon_clk:			another controller clock
>   *
> @@ -350,6 +359,7 @@ struct qcom_nand_controller {
>  	struct device *dev;
> 
>  	void __iomem *base;
> +	phys_addr_t base_phys;
>  	dma_addr_t base_dma;
> 
>  	struct clk *core_clk;
> @@ -751,6 +761,66 @@ static int prepare_bam_async_desc(struct
> qcom_nand_controller *nandc,
>  }
> 
>  /*
> + * Prepares the command descriptor for BAM DMA which will be used for 
> NAND
> + * register reads and writes. The command descriptor requires the 
> command
> + * to be formed in command element type so this function uses the 
> command
> + * element from bam transaction ce array and fills the same with 
> required
> + * data. A single SGL can contain multiple command elements so
> + * NAND_BAM_NEXT_SGL will be used for starting the separate SGL
> + * after the current command element.
> + */
> +static int prep_bam_dma_desc_cmd(struct qcom_nand_controller *nandc, 
> bool read,
> +				 int reg_off, const void *vaddr,
> +				 int size, unsigned int flags)
> +{
> +	int bam_ce_size;
> +	int i, ret;
> +	struct bam_cmd_element *bam_ce_buffer;
> +	struct bam_transaction *bam_txn = nandc->bam_txn;
> +
> +	bam_ce_buffer = &bam_txn->bam_ce[bam_txn->bam_ce_pos];
> +
> +	/* fill the command desc */
> +	for (i = 0; i < size; i++) {
> +		if (read)
> +			bam_prep_ce(&bam_ce_buffer[i],
> +				    nandc_reg_phys(nandc, reg_off + 4 * i),
> +				    BAM_READ_COMMAND,
> +				    reg_buf_dma_addr(nandc,
> +						     (__le32 *)vaddr + i));
> +		else
> +			bam_prep_ce_le32(&bam_ce_buffer[i],
> +					 nandc_reg_phys(nandc, reg_off + 4 * i),
> +					 BAM_WRITE_COMMAND,
> +					 *((__le32 *)vaddr + i));
> +	}
> +
> +	bam_txn->bam_ce_pos += size;
> +
> +	/* use the separate sgl after this command */
> +	if (flags & NAND_BAM_NEXT_SGL) {
> +		bam_ce_buffer = &bam_txn->bam_ce[bam_txn->bam_ce_start];
> +		bam_ce_size = (bam_txn->bam_ce_pos -
> +				bam_txn->bam_ce_start) *
> +				sizeof(struct bam_cmd_element);
> +		sg_set_buf(&bam_txn->cmd_sgl[bam_txn->cmd_sgl_pos],
> +			   bam_ce_buffer, bam_ce_size);
> +		bam_txn->cmd_sgl_pos++;
> +		bam_txn->bam_ce_start = bam_txn->bam_ce_pos;
> +
> +		if (flags & NAND_BAM_NWD) {
> +			ret = prepare_bam_async_desc(nandc, nandc->cmd_chan,
> +						     DMA_PREP_FENCE |
> +						     DMA_PREP_CMD);
> +			if (ret)
> +				return ret;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +/*
>   * Prepares the data descriptor for BAM DMA which will be used for 
> NAND
>   * data reads and writes.
>   */
> @@ -868,19 +938,22 @@ static int read_reg_dma(struct
> qcom_nand_controller *nandc, int first,
>  {
>  	bool flow_control = false;
>  	void *vaddr;
> -	int size;
> 
> -	if (first == NAND_READ_ID || first == NAND_FLASH_STATUS)
> -		flow_control = true;
> +	vaddr = nandc->reg_read_buf + nandc->reg_read_pos;
> +	nandc->reg_read_pos += num_regs;
> 
>  	if (first == NAND_DEV_CMD_VLD || first == NAND_DEV_CMD1)
>  		first = dev_cmd_reg_addr(nandc, first);
> 
> -	size = num_regs * sizeof(u32);
> -	vaddr = nandc->reg_read_buf + nandc->reg_read_pos;
> -	nandc->reg_read_pos += num_regs;
> +	if (nandc->props->is_bam)
> +		return prep_bam_dma_desc_cmd(nandc, true, first, vaddr,
> +					     num_regs, flags);
> 
> -	return prep_adm_dma_desc(nandc, true, first, vaddr, size, 
> flow_control);
> +	if (first == NAND_READ_ID || first == NAND_FLASH_STATUS)
> +		flow_control = true;
> +
> +	return prep_adm_dma_desc(nandc, true, first, vaddr,
> +				 num_regs * sizeof(u32), flow_control);
>  }
> 
>  /*
> @@ -897,13 +970,9 @@ static int write_reg_dma(struct
> qcom_nand_controller *nandc, int first,
>  	bool flow_control = false;
>  	struct nandc_regs *regs = nandc->regs;
>  	void *vaddr;
> -	int size;
> 
>  	vaddr = offset_to_nandc_reg(regs, first);
> 
> -	if (first == NAND_FLASH_CMD)
> -		flow_control = true;
> -
>  	if (first == NAND_ERASED_CW_DETECT_CFG) {
>  		if (flags & NAND_ERASED_CW_SET)
>  			vaddr = &regs->erased_cw_detect_cfg_set;
> @@ -920,10 +989,15 @@ static int write_reg_dma(struct
> qcom_nand_controller *nandc, int first,
>  	if (first == NAND_DEV_CMD_VLD_RESTORE || first == NAND_DEV_CMD_VLD)
>  		first = dev_cmd_reg_addr(nandc, NAND_DEV_CMD_VLD);
> 
> -	size = num_regs * sizeof(u32);
> +	if (nandc->props->is_bam)
> +		return prep_bam_dma_desc_cmd(nandc, false, first, vaddr,
> +					     num_regs, flags);
> +
> +	if (first == NAND_FLASH_CMD)
> +		flow_control = true;
> 
> -	return prep_adm_dma_desc(nandc, false, first, vaddr, size,
> -				 flow_control);
> +	return prep_adm_dma_desc(nandc, false, first, vaddr,
> +				 num_regs * sizeof(u32), flow_control);
>  }
> 
>  /*
> @@ -1187,7 +1261,8 @@ static int submit_descs(struct
> qcom_nand_controller *nandc)
>  		}
> 
>  		if (bam_txn->cmd_sgl_pos > bam_txn->cmd_sgl_start) {
> -			r = prepare_bam_async_desc(nandc, nandc->cmd_chan, 0);
> +			r = prepare_bam_async_desc(nandc, nandc->cmd_chan,
> +						   DMA_PREP_CMD);
>  			if (r)
>  				return r;
>  		}
> @@ -2722,6 +2797,7 @@ static int qcom_nandc_probe(struct 
> platform_device *pdev)
>  	if (IS_ERR(nandc->base))
>  		return PTR_ERR(nandc->base);
> 
> +	nandc->base_phys = res->start;
>  	nandc->base_dma = phys_to_dma(dev, (phys_addr_t)res->start);
> 
>  	nandc->core_clk = devm_clk_get(dev, "core");

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v5 11/16] mtd: nand: qcom: support for command descriptor formation
  2017-08-19  9:47   ` Abhishek Sahu
@ 2017-08-19 20:38     ` Boris Brezillon
  0 siblings, 0 replies; 26+ messages in thread
From: Boris Brezillon @ 2017-08-19 20:38 UTC (permalink / raw)
  To: Abhishek Sahu
  Cc: David Woodhouse, Brian Norris, Marek Vasut, Richard Weinberger,
	Cyrille Pitchen, linux-arm-msm, linux-kernel, linux-mtd,
	Andy Gross, Archit Taneja, Sricharan R, Vinod Koul, dmaengine

Le Sat, 19 Aug 2017 15:17:13 +0530,
Abhishek Sahu <absahu@codeaurora.org> a écrit :

> On 2017-08-17 17:37, Abhishek Sahu wrote:
> > 1. Add the function for command descriptor preparation which will
> >    be used only by BAM DMA and it will form the DMA descriptors
> >    containing command elements
> > 2. DMA_PREP_CMD flag should be used for forming command DMA
> >    descriptors
> > 
> > Reviewed-by: Archit Taneja <architt@codeaurora.org>
> > Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
> > ---
> > 
> > * Changes from v4: None
> > 
> > * BUILD DEPENDENCY:
> > 
> >  This PATCH has build dependency over following BAM command descriptor
> >  patch posted in DMA engine mailing list
> > 
> >  http://www.spinics.net/lists/dmaengine/msg13665.html
> >   
> 
>   Hi Boris,
> 
>   These patch has build dependency over DMA engine patch
>   http://www.spinics.net/lists/dmaengine/msg13665.html
> 
>   but this patch has been applied in your github
>   https://github.com/bbrezillon/linux-0day/commits/nand/next
> 
>   The DMA change has not merged yet so could we drop this and
>   previous patch alone till the the DMA change is merged to prevent
>   build error.

Oops. I saw this note when reviewing previous version of this and
completely forgot when applying v5. I dropped it from my nand/next
branch.
;
Note that the linux-0day repo is just a personal repo I use to let
Fenguang's robots test things before I push then to l2-mtd/nand/next.

Anyway, thanks for the heads up.

Boris

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v5 00/16] Add QCOM QPIC NAND support
  2017-08-17 12:07 [PATCH v5 00/16] Add QCOM QPIC NAND support Abhishek Sahu
                   ` (15 preceding siblings ...)
  2017-08-17 12:07 ` [PATCH v5 16/16] mtd: nand: qcom: Support for IPQ8074 " Abhishek Sahu
@ 2017-08-21 20:15 ` Boris Brezillon
  2017-08-22  6:32   ` Abhishek Sahu
  16 siblings, 1 reply; 26+ messages in thread
From: Boris Brezillon @ 2017-08-21 20:15 UTC (permalink / raw)
  To: Abhishek Sahu
  Cc: Archit Taneja, Richard Weinberger, linux-arm-msm, linux-kernel,
	Marek Vasut, linux-mtd, Cyrille Pitchen, Andy Gross, Sricharan R,
	Brian Norris, David Woodhouse

Le Thu, 17 Aug 2017 17:37:38 +0530,
Abhishek Sahu <absahu@codeaurora.org> a écrit :

> * v5:
> 
> 1. Removed the patches already applied to linux-next and rebased the
>    remaining patches on [3]
> 2. Addressed the review comments in v4 and Added Archit Reviewed
>    by tag.
> 
> [3] http://git.infradead.org/l2-mtd.git/shortlog/refs/heads/nand/next
> 
> * v4:
> 
> 1. Added Acked-by from Rob for DT documentation patches
> 2. Removed ipq8074 compatible string from ipq4019 DT example.
> 2. Used the BIT macro for NAND_CMD_VLD bits and consistent names
>    as suggested by Boris in v3.
> 
> * v3:
> 
> 1. Removed the patches already applied to linux-next and
>    rebased the remaining patches on [1]
> 2. Reordered the patches and put the BAM DMA changes [2]
>    dependent patches and compatible string patches in last
> 3. Removed the register offsets array and used the dev_cmd offsets
> 4. Changed some macro names to small letters for better code readability
> 5. Changed the compatible string to SoC specific
> 6. Did minor code changes for adding comment, error handling, structure names
> 7. Combined raw write (patch#18) and passing flag parameter (patch#22) patch
>    into one
> 8. Made separate patch for compatible string and NAND properties
> 9. Made separate patch for BAM command descriptor and data descriptors handling
> 10. Changed commit message for some of the patches
> 11. Addressed review comments given in v2
> 12. Added Reviewed-by of Archit for some of the patches from v2
> 13. All the MTD tests are working fine for IPQ8064 AP148, IPQ4019 DK04 and
>     IPQ8074 HK01 boards for v3 patches
> 
> [1] http://git.infradead.org/l2-mtd.git/shortlog/refs/heads/nand/next
> [2] http://www.spinics.net/lists/dmaengine/msg13662.html
> 
> * v2:
> 
> 1. Addressed the review comments given in v1
> 2. Removed the DMA coherent buffer for register read and used
>    streaming DMA API’s
> 3. Reorganized the NAND read and write functions
> 4. Separated patch for driver and documentation changes
> 5. Changed the compatible string for EBI2
> 
> * v1:
> 
> http://www.spinics.net/lists/devicetree/msg183706.html
> 
> 
> Abhishek Sahu (16):
>   mtd: nand: qcom: DMA mapping support for register read buffer
>   mtd: nand: qcom: allocate BAM transaction
>   mtd: nand: qcom: add BAM DMA descriptor handling
>   mtd: nand: qcom: support for passing flags in DMA helper functions
>   mtd: nand: qcom: support for read location registers
>   mtd: nand: qcom: erased codeword detection configuration
>   mtd: nand: qcom: enable BAM or ADM mode
>   mtd: nand: qcom: QPIC data descriptors handling
>   mtd: nand: qcom: support for different DEV_CMD register offsets
>   mtd: nand: qcom: add command elements in BAM transaction
>   mtd: nand: qcom: support for command descriptor formation
>   dt-bindings: qcom_nandc: fix the ipq806x device tree example
>   dt-bindings: qcom_nandc: IPQ4019 QPIC NAND documentation
>   dt-bindings: qcom_nandc: IPQ8074 QPIC NAND documentation
>   mtd: nand: qcom: support for IPQ4019 QPIC NAND controller
>   mtd: nand: qcom: Support for IPQ8074 QPIC NAND controller

Applied everything to nand/next except patch 10 and 11. Let me know
when the dmaengine dependency is merged and I'll take the remaining
patches.

Thanks,

Boris

> 
>  .../devicetree/bindings/mtd/qcom_nandc.txt         |  63 +-
>  drivers/mtd/nand/qcom_nandc.c                      | 746 ++++++++++++++++++---
>  2 files changed, 722 insertions(+), 87 deletions(-)
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v5 14/16] dt-bindings: qcom_nandc: IPQ8074 QPIC NAND documentation
  2017-08-17 12:07 ` [PATCH v5 14/16] dt-bindings: qcom_nandc: IPQ8074 " Abhishek Sahu
@ 2017-08-22  2:21       ` Rob Herring
  0 siblings, 0 replies; 26+ messages in thread
From: Rob Herring @ 2017-08-22  2:21 UTC (permalink / raw)
  To: Abhishek Sahu
  Cc: Boris Brezillon, David Woodhouse, Brian Norris, Marek Vasut,
	Richard Weinberger, Cyrille Pitchen,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Andy Gross,
	Archit Taneja, Sricharan R, Mark Rutland,
	devicetree-u79uwXL29TY76Z2rM5mHXA

On Thu, Aug 17, 2017 at 05:37:52PM +0530, Abhishek Sahu wrote:
> Qualcom IPQ8074 SoC uses QPIC NAND controller version 1.5.0
> which uses BAM DMA Engine.
> 
> Signed-off-by: Abhishek Sahu <absahu-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
> ---
> 
> * Changes from v4: None
> 
>  Documentation/devicetree/bindings/mtd/qcom_nandc.txt | 2 ++
>  1 file changed, 2 insertions(+)

Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v5 14/16] dt-bindings: qcom_nandc: IPQ8074 QPIC NAND documentation
@ 2017-08-22  2:21       ` Rob Herring
  0 siblings, 0 replies; 26+ messages in thread
From: Rob Herring @ 2017-08-22  2:21 UTC (permalink / raw)
  To: Abhishek Sahu
  Cc: Boris Brezillon, David Woodhouse, Brian Norris, Marek Vasut,
	Richard Weinberger, Cyrille Pitchen, linux-arm-msm, linux-kernel,
	linux-mtd, Andy Gross, Archit Taneja, Sricharan R, Mark Rutland,
	devicetree

On Thu, Aug 17, 2017 at 05:37:52PM +0530, Abhishek Sahu wrote:
> Qualcom IPQ8074 SoC uses QPIC NAND controller version 1.5.0
> which uses BAM DMA Engine.
> 
> Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
> ---
> 
> * Changes from v4: None
> 
>  Documentation/devicetree/bindings/mtd/qcom_nandc.txt | 2 ++
>  1 file changed, 2 insertions(+)

Acked-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v5 00/16] Add QCOM QPIC NAND support
  2017-08-21 20:15 ` [PATCH v5 00/16] Add QCOM QPIC NAND support Boris Brezillon
@ 2017-08-22  6:32   ` Abhishek Sahu
  2017-09-25  8:09     ` Abhishek Sahu
  0 siblings, 1 reply; 26+ messages in thread
From: Abhishek Sahu @ 2017-08-22  6:32 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Archit Taneja, Richard Weinberger, linux-arm-msm, linux-kernel,
	Marek Vasut, linux-mtd, Cyrille Pitchen, Andy Gross, Sricharan R,
	Brian Norris, David Woodhouse

On 2017-08-22 01:45, Boris Brezillon wrote:
> Le Thu, 17 Aug 2017 17:37:38 +0530,
> Abhishek Sahu <absahu@codeaurora.org> a écrit :
> 
>> * v5:
>> 
>> 1. Removed the patches already applied to linux-next and rebased the
>>    remaining patches on [3]
>> 2. Addressed the review comments in v4 and Added Archit Reviewed
>>    by tag.
>> 
>> [3] http://git.infradead.org/l2-mtd.git/shortlog/refs/heads/nand/next
>> 

  <snip>

>> 
>> Abhishek Sahu (16):
>>   mtd: nand: qcom: DMA mapping support for register read buffer
>>   mtd: nand: qcom: allocate BAM transaction
>>   mtd: nand: qcom: add BAM DMA descriptor handling
>>   mtd: nand: qcom: support for passing flags in DMA helper functions
>>   mtd: nand: qcom: support for read location registers
>>   mtd: nand: qcom: erased codeword detection configuration
>>   mtd: nand: qcom: enable BAM or ADM mode
>>   mtd: nand: qcom: QPIC data descriptors handling
>>   mtd: nand: qcom: support for different DEV_CMD register offsets
>>   mtd: nand: qcom: add command elements in BAM transaction
>>   mtd: nand: qcom: support for command descriptor formation
>>   dt-bindings: qcom_nandc: fix the ipq806x device tree example
>>   dt-bindings: qcom_nandc: IPQ4019 QPIC NAND documentation
>>   dt-bindings: qcom_nandc: IPQ8074 QPIC NAND documentation
>>   mtd: nand: qcom: support for IPQ4019 QPIC NAND controller
>>   mtd: nand: qcom: Support for IPQ8074 QPIC NAND controller
> 
> Applied everything to nand/next except patch 10 and 11. Let me know
> when the dmaengine dependency is merged and I'll take the remaining
> patches.
> 

  Thanks Boris for your great help and reviewing this long patch series 
:-)

  I will update you when DMA dependency is merged.

  Thanks,
  Abhishek

> 
>> 
>>  .../devicetree/bindings/mtd/qcom_nandc.txt         |  63 +-
>>  drivers/mtd/nand/qcom_nandc.c                      | 746 
>> ++++++++++++++++++---
>>  2 files changed, 722 insertions(+), 87 deletions(-)
>> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v5 00/16] Add QCOM QPIC NAND support
  2017-08-22  6:32   ` Abhishek Sahu
@ 2017-09-25  8:09     ` Abhishek Sahu
  0 siblings, 0 replies; 26+ messages in thread
From: Abhishek Sahu @ 2017-09-25  8:09 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Archit Taneja, Richard Weinberger, linux-arm-msm, linux-kernel,
	Marek Vasut, linux-mtd, Cyrille Pitchen, Andy Gross, Sricharan R,
	Brian Norris, David Woodhouse

On 2017-08-22 12:02, Abhishek Sahu wrote:
> On 2017-08-22 01:45, Boris Brezillon wrote:
>> Le Thu, 17 Aug 2017 17:37:38 +0530,
>> Abhishek Sahu <absahu@codeaurora.org> a écrit :
>> 
>>> * v5:
>>> 
>>> 1. Removed the patches already applied to linux-next and rebased the
>>>    remaining patches on [3]
>>> 2. Addressed the review comments in v4 and Added Archit Reviewed
>>>    by tag.
>>> 
>>> [3] http://git.infradead.org/l2-mtd.git/shortlog/refs/heads/nand/next
>>> 
> 
>  <snip>
> 
>>> 
>>> Abhishek Sahu (16):
>>>   mtd: nand: qcom: DMA mapping support for register read buffer
>>>   mtd: nand: qcom: allocate BAM transaction
>>>   mtd: nand: qcom: add BAM DMA descriptor handling
>>>   mtd: nand: qcom: support for passing flags in DMA helper functions
>>>   mtd: nand: qcom: support for read location registers
>>>   mtd: nand: qcom: erased codeword detection configuration
>>>   mtd: nand: qcom: enable BAM or ADM mode
>>>   mtd: nand: qcom: QPIC data descriptors handling
>>>   mtd: nand: qcom: support for different DEV_CMD register offsets
>>>   mtd: nand: qcom: add command elements in BAM transaction
>>>   mtd: nand: qcom: support for command descriptor formation
>>>   dt-bindings: qcom_nandc: fix the ipq806x device tree example
>>>   dt-bindings: qcom_nandc: IPQ4019 QPIC NAND documentation
>>>   dt-bindings: qcom_nandc: IPQ8074 QPIC NAND documentation
>>>   mtd: nand: qcom: support for IPQ4019 QPIC NAND controller
>>>   mtd: nand: qcom: Support for IPQ8074 QPIC NAND controller
>> 
>> Applied everything to nand/next except patch 10 and 11. Let me know
>> when the dmaengine dependency is merged and I'll take the remaining
>> patches.
>> 

  Hi Boris,

  The dmaengine dependencies are merged in 4.14-rc1 so you can take 
remaining 2
  patches. I have resent those 2 patches again and it can be cleanly
  applied over 4.14-rc1.

  Thanks,
  Abhishek

> 
>> 
>>> 
>>>  .../devicetree/bindings/mtd/qcom_nandc.txt         |  63 +-
>>>  drivers/mtd/nand/qcom_nandc.c                      | 746 
>>> ++++++++++++++++++---
>>>  2 files changed, 722 insertions(+), 87 deletions(-)
>>> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2017-09-25  8:09 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-17 12:07 [PATCH v5 00/16] Add QCOM QPIC NAND support Abhishek Sahu
2017-08-17 12:07 ` [PATCH v5 01/16] mtd: nand: qcom: DMA mapping support for register read buffer Abhishek Sahu
2017-08-17 12:07 ` [PATCH v5 02/16] mtd: nand: qcom: allocate BAM transaction Abhishek Sahu
2017-08-17 12:07 ` [PATCH v5 03/16] mtd: nand: qcom: add BAM DMA descriptor handling Abhishek Sahu
2017-08-17 12:07 ` [PATCH v5 04/16] mtd: nand: qcom: support for passing flags in DMA helper functions Abhishek Sahu
2017-08-17 12:07   ` Abhishek Sahu
2017-08-17 12:07 ` [PATCH v5 05/16] mtd: nand: qcom: support for read location registers Abhishek Sahu
2017-08-17 12:07 ` [PATCH v5 06/16] mtd: nand: qcom: erased codeword detection configuration Abhishek Sahu
2017-08-17 12:07 ` [PATCH v5 07/16] mtd: nand: qcom: enable BAM or ADM mode Abhishek Sahu
2017-08-17 12:07 ` [PATCH v5 08/16] mtd: nand: qcom: QPIC data descriptors handling Abhishek Sahu
2017-08-17 12:07 ` [PATCH v5 09/16] mtd: nand: qcom: support for different DEV_CMD register offsets Abhishek Sahu
2017-08-17 12:07 ` [PATCH v5 10/16] mtd: nand: qcom: add command elements in BAM transaction Abhishek Sahu
2017-08-19  9:32   ` Abhishek Sahu
2017-08-17 12:07 ` [PATCH v5 11/16] mtd: nand: qcom: support for command descriptor formation Abhishek Sahu
2017-08-19  9:47   ` Abhishek Sahu
2017-08-19 20:38     ` Boris Brezillon
2017-08-17 12:07 ` [PATCH v5 12/16] dt-bindings: qcom_nandc: fix the ipq806x device tree example Abhishek Sahu
2017-08-17 12:07 ` [PATCH v5 13/16] dt-bindings: qcom_nandc: IPQ4019 QPIC NAND documentation Abhishek Sahu
2017-08-17 12:07 ` [PATCH v5 14/16] dt-bindings: qcom_nandc: IPQ8074 " Abhishek Sahu
     [not found]   ` <1502971674-13810-15-git-send-email-absahu-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2017-08-22  2:21     ` Rob Herring
2017-08-22  2:21       ` Rob Herring
2017-08-17 12:07 ` [PATCH v5 15/16] mtd: nand: qcom: support for IPQ4019 QPIC NAND controller Abhishek Sahu
2017-08-17 12:07 ` [PATCH v5 16/16] mtd: nand: qcom: Support for IPQ8074 " Abhishek Sahu
2017-08-21 20:15 ` [PATCH v5 00/16] Add QCOM QPIC NAND support Boris Brezillon
2017-08-22  6:32   ` Abhishek Sahu
2017-09-25  8:09     ` Abhishek Sahu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.