Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1704676 > unrolled thread
| Started by | Abhishek Sahu <absahu@codeaurora.org> |
|---|---|
| First post | 2017-08-05 18:30 +0200 |
| Last post | 2017-08-11 11:10 +0200 |
| Articles | 19 — 3 participants |
Back to article view | Back to linux.kernel
[PATCH v3 00/20] Add QCOM QPIC NAND support Abhishek Sahu <absahu@codeaurora.org> - 2017-08-05 18:30 +0200
[PATCH v3 20/20] mtd: nand: qcom: Support for IPQ8074 QPIC NAND controller Abhishek Sahu <absahu@codeaurora.org> - 2017-08-05 18:30 +0200
[PATCH v3 19/20] mtd: nand: qcom: Support for IPQ4019 QPIC NAND controller Abhishek Sahu <absahu@codeaurora.org> - 2017-08-05 18:30 +0200
[PATCH v3 08/20] mtd: nand: qcom: support for passing flags in transfer functions Abhishek Sahu <absahu@codeaurora.org> - 2017-08-05 18:30 +0200
[PATCH v3 14/20] mtd: nand: qcom: add command elements in BAM transaction Abhishek Sahu <absahu@codeaurora.org> - 2017-08-05 18:30 +0200
Re: [PATCH v3 14/20] mtd: nand: qcom: add command elements in BAM transaction Abhishek Sahu <absahu@codeaurora.org> - 2017-08-09 10:30 +0200
[PATCH v3 15/20] mtd: nand: qcom: support for command descriptor formation Abhishek Sahu <absahu@codeaurora.org> - 2017-08-05 18:30 +0200
Re: [PATCH v3 15/20] mtd: nand: qcom: support for command descriptor formation Abhishek Sahu <absahu@codeaurora.org> - 2017-08-09 10:40 +0200
[PATCH v3 01/20] mtd: nand: qcom: program NAND_DEV_CMD_VLD register Abhishek Sahu <absahu@codeaurora.org> - 2017-08-05 18:30 +0200
Re: [PATCH v3 01/20] mtd: nand: qcom: program NAND_DEV_CMD_VLD register Boris Brezillon <boris.brezillon@free-electrons.com> - 2017-08-10 11:50 +0200
Re: [PATCH v3 01/20] mtd: nand: qcom: program NAND_DEV_CMD_VLD register Abhishek Sahu <absahu@codeaurora.org> - 2017-08-10 12:40 +0200
[PATCH v3 12/20] mtd: nand: qcom: QPIC data descriptors handling Abhishek Sahu <absahu@codeaurora.org> - 2017-08-05 18:30 +0200
[PATCH v3 09/20] mtd: nand: qcom: support for read location registers Abhishek Sahu <absahu@codeaurora.org> - 2017-08-05 18:30 +0200
[PATCH v3 04/20] mtd: nand: qcom: add and initialize QPIC DMA resources Abhishek Sahu <absahu@codeaurora.org> - 2017-08-05 18:30 +0200
[PATCH v3 11/20] mtd: nand: qcom: enable BAM or ADM mode Abhishek Sahu <absahu@codeaurora.org> - 2017-08-05 18:30 +0200
[PATCH v3 05/20] mtd: nand: qcom: DMA mapping support for register read buffer Abhishek Sahu <absahu@codeaurora.org> - 2017-08-05 18:30 +0200
[PATCH v3 18/20] dt-bindings: qcom_nandc: IPQ8074 QPIC NAND documentation Abhishek Sahu <absahu@codeaurora.org> - 2017-08-05 18:30 +0200
Re: [PATCH v3 18/20] dt-bindings: qcom_nandc: IPQ8074 QPIC NAND documentation Rob Herring <robh@kernel.org> - 2017-08-10 22:40 +0200
Re: [PATCH v3 18/20] dt-bindings: qcom_nandc: IPQ8074 QPIC NAND documentation Abhishek Sahu <absahu@codeaurora.org> - 2017-08-11 11:10 +0200
| From | Abhishek Sahu <absahu@codeaurora.org> |
|---|---|
| Date | 2017-08-05 18:30 +0200 |
| Subject | [PATCH v3 00/20] Add QCOM QPIC NAND support |
| Message-ID | <uba7D-7k7-3@gated-at.bofh.it> |
* 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 (20):
mtd: nand: qcom: program NAND_DEV_CMD_VLD register
mtd: nand: qcom: support for NAND controller properties
mtd: nand: qcom: add bam property for QPIC NAND controller
mtd: nand: qcom: add and initialize QPIC DMA resources
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 transfer 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 | 863 ++++++++++++++++++---
2 files changed, 814 insertions(+), 112 deletions(-)
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[toc] | [next] | [standalone]
| From | Abhishek Sahu <absahu@codeaurora.org> |
|---|---|
| Date | 2017-08-05 18:30 +0200 |
| Subject | [PATCH v3 20/20] mtd: nand: qcom: Support for IPQ8074 QPIC NAND controller |
| Message-ID | <uba7G-7k7-43@gated-at.bofh.it> |
| In reply to | #1704676 |
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.
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---
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 cc58e8f..d606262 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)
.flash_dev_offset = 0x0,
};
+static const struct qcom_nandc_props ipq8074_nandc_props = {
+ .ecc_modes = (ECC_BCH_4BIT | ECC_BCH_8BIT),
+ .is_bam = true,
+ .flash_dev_offset = 0x7000,
+};
+
/*
* data will hold a struct pointer containing more differences once we support
* more controller variants
@@ -2879,6 +2885,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
[toc] | [prev] | [next] | [standalone]
| From | Abhishek Sahu <absahu@codeaurora.org> |
|---|---|
| Date | 2017-08-05 18:30 +0200 |
| Subject | [PATCH v3 19/20] mtd: nand: qcom: Support for IPQ4019 QPIC NAND controller |
| Message-ID | <uba7G-7k7-45@gated-at.bofh.it> |
| In reply to | #1704676 |
Add the compatible string for IPQ4019 QPIC NAND controller
version 1.4.0 which uses BAM DMA.
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---
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 16463ac..cc58e8f 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -2860,6 +2860,12 @@ static int qcom_nandc_remove(struct platform_device *pdev)
.flash_dev_offset = 0x0,
};
+static const struct qcom_nandc_props ipq4019_nandc_props = {
+ .ecc_modes = (ECC_BCH_4BIT | ECC_BCH_8BIT),
+ .is_bam = true,
+ .flash_dev_offset = 0x0,
+};
+
/*
* data will hold a struct pointer containing more differences once we support
* more controller variants
@@ -2869,6 +2875,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
[toc] | [prev] | [next] | [standalone]
| From | Abhishek Sahu <absahu@codeaurora.org> |
|---|---|
| Date | 2017-08-05 18:30 +0200 |
| Subject | [PATCH v3 08/20] mtd: nand: qcom: support for passing flags in transfer functions |
| Message-ID | <uba7G-7k7-51@gated-at.bofh.it> |
| In reply to | #1704676 |
The BAM has multiple flags to control the transfer. This patch
adds flags parameter in register and data transfer 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.
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---
drivers/mtd/nand/qcom_nandc.c | 122 ++++++++++++++++++++++++------------------
1 file changed, 70 insertions(+), 52 deletions(-)
diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index 825ad4a..fb1f5de 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -182,6 +182,14 @@
#define QPIC_PER_CW_CMD_SGL 32
#define QPIC_PER_CW_DATA_SGL 8
+/* Flags used for BAM DMA desc preparation*/
+/* Don't set the EOT in current tx sgl */
+#define NAND_BAM_NO_EOT BIT(0)
+/* Set the NWD flag in current sgl */
+#define NAND_BAM_NWD BIT(1)
+/* Finish writing in the current sgl and start writing in another sgl */
+#define NAND_BAM_NEXT_SGL BIT(2)
+
/*
* This data type corresponds to the BAM transaction which will be used for all
* NAND transfers.
@@ -733,7 +741,7 @@ static int prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read,
* @num_regs: number of registers to read
*/
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;
@@ -757,7 +765,7 @@ static int read_reg_dma(struct qcom_nand_controller *nandc, int first,
* @num_regs: number of registers to write
*/
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;
@@ -769,6 +777,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;
@@ -790,7 +801,7 @@ static int write_reg_dma(struct qcom_nand_controller *nandc, int first,
* @size: DMA transaction size in bytes
*/
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);
}
@@ -804,7 +815,7 @@ static int read_data_dma(struct qcom_nand_controller *nandc, int reg_off,
* @size: DMA transaction size in bytes
*/
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);
}
@@ -815,9 +826,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);
}
/*
@@ -826,11 +837,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);
}
/*
@@ -849,9 +861,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);
}
/*
@@ -860,13 +873,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);
}
/*
@@ -914,8 +927,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);
@@ -923,11 +936,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;
}
@@ -949,14 +962,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;
}
@@ -976,10 +989,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;
}
@@ -993,10 +1006,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;
}
@@ -1392,7 +1405,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
@@ -1408,7 +1421,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)
@@ -1450,7 +1463,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)
@@ -1519,19 +1532,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;
}
@@ -1598,7 +1611,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
@@ -1611,7 +1625,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);
@@ -1666,19 +1680,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);
@@ -1732,8 +1749,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);
@@ -1817,7 +1834,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
[toc] | [prev] | [next] | [standalone]
| From | Abhishek Sahu <absahu@codeaurora.org> |
|---|---|
| Date | 2017-08-05 18:30 +0200 |
| Subject | [PATCH v3 14/20] mtd: nand: qcom: add command elements in BAM transaction |
| Message-ID | <uba7G-7k7-55@gated-at.bofh.it> |
| In reply to | #1704676 |
All the QPIC register read/write through BAM DMA requires
command descriptor which contains the array of command elements.
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---
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 c940a20..9c12404 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
@@ -198,6 +199,7 @@
/* Returns the actual register address for NAND_FLASH_DEV_* */
#define nandc_dev_addr(nandc, reg) ((nandc)->props->flash_dev_offset + (reg))
+#define QPIC_PER_CW_CMD_ELEMENTS 32
#define QPIC_PER_CW_CMD_SGL 32
#define QPIC_PER_CW_DATA_SGL 8
@@ -217,8 +219,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.
@@ -227,8 +234,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;
@@ -458,7 +468,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);
@@ -468,6 +479,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;
@@ -485,6 +500,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
[toc] | [prev] | [next] | [standalone]
| From | Abhishek Sahu <absahu@codeaurora.org> |
|---|---|
| Date | 2017-08-09 10:30 +0200 |
| Subject | Re: [PATCH v3 14/20] mtd: nand: qcom: add command elements in BAM transaction |
| Message-ID | <ucuxj-4uZ-19@gated-at.bofh.it> |
| In reply to | #1704680 |
On 2017-08-05 21:49, Abhishek Sahu wrote:
> All the QPIC register read/write through BAM DMA requires
> command descriptor which contains the array of command elements.
>
> Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
This patch has build dependency on
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 c940a20..9c12404 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
> @@ -198,6 +199,7 @@
> /* Returns the actual register address for NAND_FLASH_DEV_* */
> #define nandc_dev_addr(nandc, reg) ((nandc)->props->flash_dev_offset +
> (reg))
>
> +#define QPIC_PER_CW_CMD_ELEMENTS 32
> #define QPIC_PER_CW_CMD_SGL 32
> #define QPIC_PER_CW_DATA_SGL 8
>
> @@ -217,8 +219,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.
> @@ -227,8 +234,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;
> @@ -458,7 +468,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);
> @@ -468,6 +479,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;
> @@ -485,6 +500,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;
[toc] | [prev] | [next] | [standalone]
| From | Abhishek Sahu <absahu@codeaurora.org> |
|---|---|
| Date | 2017-08-05 18:30 +0200 |
| Subject | [PATCH v3 15/20] mtd: nand: qcom: support for command descriptor formation |
| Message-ID | <uba7G-7k7-53@gated-at.bofh.it> |
| In reply to | #1704676 |
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
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---
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 9c12404..16463ac 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -196,6 +196,14 @@
((size) << READ_LOCATION_SIZE) | \
((is_last) << READ_LOCATION_LAST))
+/* 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))
+
/* Returns the actual register address for NAND_FLASH_DEV_* */
#define nandc_dev_addr(nandc, reg) ((nandc)->props->flash_dev_offset + (reg))
@@ -313,7 +321,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
*
@@ -346,6 +355,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;
@@ -747,6 +757,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.
*/
@@ -863,19 +933,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 = nandc_dev_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);
}
/*
@@ -891,13 +964,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 = ®s->erased_cw_detect_cfg_set;
@@ -914,10 +983,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 = nandc_dev_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);
}
/*
@@ -1180,7 +1254,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;
}
@@ -2716,6 +2791,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
[toc] | [prev] | [next] | [standalone]
| From | Abhishek Sahu <absahu@codeaurora.org> |
|---|---|
| Date | 2017-08-09 10:40 +0200 |
| Subject | Re: [PATCH v3 15/20] mtd: nand: qcom: support for command descriptor formation |
| Message-ID | <ucuH0-4y9-23@gated-at.bofh.it> |
| In reply to | #1704681 |
On 2017-08-05 21:49, 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
>
> Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
This patch has build dependency on
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 9c12404..16463ac 100644
> --- a/drivers/mtd/nand/qcom_nandc.c
> +++ b/drivers/mtd/nand/qcom_nandc.c
> @@ -196,6 +196,14 @@
> ((size) << READ_LOCATION_SIZE) | \
> ((is_last) << READ_LOCATION_LAST))
>
> +/* 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))
> +
> /* Returns the actual register address for NAND_FLASH_DEV_* */
> #define nandc_dev_addr(nandc, reg) ((nandc)->props->flash_dev_offset +
> (reg))
>
> @@ -313,7 +321,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
> *
> @@ -346,6 +355,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;
> @@ -747,6 +757,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.
> */
> @@ -863,19 +933,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 = nandc_dev_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);
> }
>
> /*
> @@ -891,13 +964,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 = ®s->erased_cw_detect_cfg_set;
> @@ -914,10 +983,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 = nandc_dev_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);
> }
>
> /*
> @@ -1180,7 +1254,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;
> }
> @@ -2716,6 +2791,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");
[toc] | [prev] | [next] | [standalone]
| From | Abhishek Sahu <absahu@codeaurora.org> |
|---|---|
| Date | 2017-08-05 18:30 +0200 |
| Subject | [PATCH v3 01/20] mtd: nand: qcom: program NAND_DEV_CMD_VLD register |
| Message-ID | <uba7G-7k7-57@gated-at.bofh.it> |
| In reply to | #1704676 |
The NAND page read fails without complete boot chain since
NAND_DEV_CMD_VLD value is not proper. The default power on reset
value for this register is
0xe - ERASE_START_VALID | WRITE_START_VALID | READ_STOP_VALID
The READ_START_VALID should be enabled for sending PAGE_READ
command. READ_STOP_VALID should be cleared since normal NAND
page read does not require READ_STOP command.
Fixes: c76b78d8ec05a ("mtd: nand: Qualcomm NAND controller driver")
Cc: stable@vger.kernel.org
Reviewed-by: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---
drivers/mtd/nand/qcom_nandc.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index 0289f09..7406019 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -110,6 +110,10 @@
/* NAND_DEV_CMD_VLD bits */
#define READ_START_VLD 0
+#define READ_STOP_VALID 1
+#define WRITE_START_VALID 2
+#define ERASE_START_VALID 3
+#define SEQ_READ_START_VLD 4
/* NAND_EBI2_ECC_BUF_CFG bits */
#define NUM_STEPS 0
@@ -148,6 +152,12 @@
#define FETCH_ID 0xb
#define RESET_DEVICE 0xd
+/* Default Value for NAND_DEV_CMD_VLD */
+#define NAND_DEV_CMD_VLD_VAL (BIT(READ_START_VLD) | \
+ BIT(WRITE_START_VALID) | \
+ BIT(ERASE_START_VALID) | \
+ BIT(SEQ_READ_START_VLD))
+
/*
* the NAND controller performs reads/writes with ECC in 516 byte chunks.
* the driver calls the chunks 'step' or 'codeword' interchangeably
@@ -1995,13 +2005,14 @@ 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);
/* enable ADM DMA */
nandc_write(nandc, NAND_FLASH_CHIP_SELECT, DM_EN);
/* save the original values of these registers */
nandc->cmd1 = nandc_read(nandc, NAND_DEV_CMD1);
- nandc->vld = nandc_read(nandc, NAND_DEV_CMD_VLD);
+ nandc->vld = NAND_DEV_CMD_VLD_VAL;
return 0;
}
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[toc] | [prev] | [next] | [standalone]
| From | Boris Brezillon <boris.brezillon@free-electrons.com> |
|---|---|
| Date | 2017-08-10 11:50 +0200 |
| Subject | Re: [PATCH v3 01/20] mtd: nand: qcom: program NAND_DEV_CMD_VLD register |
| Message-ID | <ucSgh-3P5-3@gated-at.bofh.it> |
| In reply to | #1704682 |
Le Sat, 5 Aug 2017 21:49:39 +0530,
Abhishek Sahu <absahu@codeaurora.org> a écrit :
> The NAND page read fails without complete boot chain since
> NAND_DEV_CMD_VLD value is not proper. The default power on reset
> value for this register is
>
> 0xe - ERASE_START_VALID | WRITE_START_VALID | READ_STOP_VALID
>
> The READ_START_VALID should be enabled for sending PAGE_READ
> command. READ_STOP_VALID should be cleared since normal NAND
> page read does not require READ_STOP command.
>
> Fixes: c76b78d8ec05a ("mtd: nand: Qualcomm NAND controller driver")
> Cc: stable@vger.kernel.org
> Reviewed-by: Archit Taneja <architt@codeaurora.org>
> Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
> ---
> drivers/mtd/nand/qcom_nandc.c | 13 ++++++++++++-
> 1 file changed, 12 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
> index 0289f09..7406019 100644
> --- a/drivers/mtd/nand/qcom_nandc.c
> +++ b/drivers/mtd/nand/qcom_nandc.c
> @@ -110,6 +110,10 @@
>
> /* NAND_DEV_CMD_VLD bits */
> #define READ_START_VLD 0
> +#define READ_STOP_VALID 1
> +#define WRITE_START_VALID 2
> +#define ERASE_START_VALID 3
> +#define SEQ_READ_START_VLD 4
Why not
#define READ_START_VLD BIT(0)
#define READ_STOP_VALID BIT(1)
#define WRITE_START_VALID BIT(2)
#define ERASE_START_VALID BIT(3)
#define SEQ_READ_START_VLD BIT(4)
>
> /* NAND_EBI2_ECC_BUF_CFG bits */
> #define NUM_STEPS 0
> @@ -148,6 +152,12 @@
> #define FETCH_ID 0xb
> #define RESET_DEVICE 0xd
>
> +/* Default Value for NAND_DEV_CMD_VLD */
> +#define NAND_DEV_CMD_VLD_VAL (BIT(READ_START_VLD) | \
> + BIT(WRITE_START_VALID) | \
> + BIT(ERASE_START_VALID) | \
> + BIT(SEQ_READ_START_VLD))
> +
and then:
#define NAND_DEV_CMD_VLD_VAL (READ_START_VLD | \
WRITE_START_VALID | \
ERASE_START_VALID | \
SEQ_READ_START_VLD)
BTW, can you use consistent suffixes? Sometime definitions are suffixed
with _VLD and others are suffixed with _VALID.
> /*
> * the NAND controller performs reads/writes with ECC in 516 byte chunks.
> * the driver calls the chunks 'step' or 'codeword' interchangeably
> @@ -1995,13 +2005,14 @@ 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);
>
> /* enable ADM DMA */
> nandc_write(nandc, NAND_FLASH_CHIP_SELECT, DM_EN);
>
> /* save the original values of these registers */
> nandc->cmd1 = nandc_read(nandc, NAND_DEV_CMD1);
> - nandc->vld = nandc_read(nandc, NAND_DEV_CMD_VLD);
> + nandc->vld = NAND_DEV_CMD_VLD_VAL;
>
> return 0;
> }
[toc] | [prev] | [next] | [standalone]
| From | Abhishek Sahu <absahu@codeaurora.org> |
|---|---|
| Date | 2017-08-10 12:40 +0200 |
| Subject | Re: [PATCH v3 01/20] mtd: nand: qcom: program NAND_DEV_CMD_VLD register |
| Message-ID | <ucT2H-4pl-51@gated-at.bofh.it> |
| In reply to | #1708378 |
On 2017-08-10 15:12, Boris Brezillon wrote:
> Le Sat, 5 Aug 2017 21:49:39 +0530,
> Abhishek Sahu <absahu@codeaurora.org> a écrit :
>
>> The NAND page read fails without complete boot chain since
>> NAND_DEV_CMD_VLD value is not proper. The default power on reset
>> value for this register is
>>
>> 0xe - ERASE_START_VALID | WRITE_START_VALID | READ_STOP_VALID
>>
>> The READ_START_VALID should be enabled for sending PAGE_READ
>> command. READ_STOP_VALID should be cleared since normal NAND
>> page read does not require READ_STOP command.
>>
>> Fixes: c76b78d8ec05a ("mtd: nand: Qualcomm NAND controller driver")
>> Cc: stable@vger.kernel.org
>> Reviewed-by: Archit Taneja <architt@codeaurora.org>
>> Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
>> ---
>> drivers/mtd/nand/qcom_nandc.c | 13 ++++++++++++-
>> 1 file changed, 12 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/mtd/nand/qcom_nandc.c
>> b/drivers/mtd/nand/qcom_nandc.c
>> index 0289f09..7406019 100644
>> --- a/drivers/mtd/nand/qcom_nandc.c
>> +++ b/drivers/mtd/nand/qcom_nandc.c
>> @@ -110,6 +110,10 @@
>>
>> /* NAND_DEV_CMD_VLD bits */
>> #define READ_START_VLD 0
>> +#define READ_STOP_VALID 1
>> +#define WRITE_START_VALID 2
>> +#define ERASE_START_VALID 3
>> +#define SEQ_READ_START_VLD 4
>
> Why not
>
> #define READ_START_VLD BIT(0)
> #define READ_STOP_VALID BIT(1)
> #define WRITE_START_VALID BIT(2)
> #define ERASE_START_VALID BIT(3)
> #define SEQ_READ_START_VLD BIT(4)
>
Sure. we can change to use BIT macro.
We are using READ_START_VLD only at one place so will replace in
current code from
/* configure CMD1 and VLD for ONFI param probing */
nandc_set_reg(nandc, NAND_DEV_CMD_VLD,
(nandc->vld & ~(1 << READ_START_VLD))
| 0 << READ_START_VLD);
to
nandc_set_reg(nandc, NAND_DEV_CMD_VLD, nandc->vld & ~READ_START_VLD)
>>
>> /* NAND_EBI2_ECC_BUF_CFG bits */
>> #define NUM_STEPS 0
>> @@ -148,6 +152,12 @@
>> #define FETCH_ID 0xb
>> #define RESET_DEVICE 0xd
>>
>> +/* Default Value for NAND_DEV_CMD_VLD */
>> +#define NAND_DEV_CMD_VLD_VAL (BIT(READ_START_VLD) | \
>> + BIT(WRITE_START_VALID) | \
>> + BIT(ERASE_START_VALID) | \
>> + BIT(SEQ_READ_START_VLD))
>> +
>
> and then:
>
> #define NAND_DEV_CMD_VLD_VAL (READ_START_VLD | \
> WRITE_START_VALID | \
> ERASE_START_VALID | \
> SEQ_READ_START_VLD)
>
> BTW, can you use consistent suffixes? Sometime definitions are suffixed
> with _VLD and others are suffixed with _VALID.
>
Sure. I will change all the names to _VLD.
>> /*
>> * the NAND controller performs reads/writes with ECC in 516 byte
>> chunks.
>> * the driver calls the chunks 'step' or 'codeword' interchangeably
>> @@ -1995,13 +2005,14 @@ 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);
>>
>> /* enable ADM DMA */
>> nandc_write(nandc, NAND_FLASH_CHIP_SELECT, DM_EN);
>>
>> /* save the original values of these registers */
>> nandc->cmd1 = nandc_read(nandc, NAND_DEV_CMD1);
>> - nandc->vld = nandc_read(nandc, NAND_DEV_CMD_VLD);
>> + nandc->vld = NAND_DEV_CMD_VLD_VAL;
>>
>> return 0;
>> }
[toc] | [prev] | [next] | [standalone]
| From | Abhishek Sahu <absahu@codeaurora.org> |
|---|---|
| Date | 2017-08-05 18:30 +0200 |
| Subject | [PATCH v3 12/20] mtd: nand: qcom: QPIC data descriptors handling |
| Message-ID | <uba7G-7k7-59@gated-at.bofh.it> |
| In reply to | #1704676 |
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.
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---
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 af69a89..d7a2ca4 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -472,6 +472,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);
@@ -703,6 +724,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)
@@ -850,6 +906,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);
}
@@ -864,6 +923,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);
}
@@ -1152,6 +1214,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);
}
/*
@@ -1556,6 +1622,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");
@@ -1581,6 +1648,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);
@@ -1652,6 +1721,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);
@@ -1675,6 +1745,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;
@@ -1740,6 +1811,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;
@@ -1816,11 +1888,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);
@@ -1873,6 +1947,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;
@@ -1903,6 +1978,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
[toc] | [prev] | [next] | [standalone]
| From | Abhishek Sahu <absahu@codeaurora.org> |
|---|---|
| Date | 2017-08-05 18:30 +0200 |
| Subject | [PATCH v3 09/20] mtd: nand: qcom: support for read location registers |
| Message-ID | <uba7H-7k7-69@gated-at.bofh.it> |
| In reply to | #1704676 |
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.
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---
drivers/mtd/nand/qcom_nandc.c | 64 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 64 insertions(+)
diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index fb1f5de..28543c1 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
@@ -179,6 +186,12 @@
#define ECC_BCH_4BIT BIT(2)
#define ECC_BCH_8BIT BIT(3)
+#define nandc_set_readl(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
@@ -262,6 +275,11 @@ struct nandc_regs {
__le32 orig_vld;
__le32 ecc_buf_cfg;
+ __le32 read_location0;
+ __le32 read_location1;
+ __le32 read_location2;
+ __le32 read_location3;
+
};
/*
@@ -518,6 +536,14 @@ static __le32 *offset_to_nandc_reg(struct nandc_regs *regs, int offset)
return ®s->orig_vld;
case NAND_EBI2_ECC_BUF_CFG:
return ®s->ecc_buf_cfg;
+ case NAND_READ_LOCATION_0:
+ return ®s->read_location0;
+ case NAND_READ_LOCATION_1:
+ return ®s->read_location1;
+ case NAND_READ_LOCATION_2:
+ return ®s->read_location2;
+ case NAND_READ_LOCATION_3:
+ return ®s->read_location3;
default:
return NULL;
}
@@ -592,6 +618,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_readl(nandc, 0, 0, host->use_ecc ?
+ host->cw_data : host->cw_size, 1);
}
/*
@@ -837,6 +867,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);
@@ -926,6 +960,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_readl(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);
@@ -1401,6 +1436,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_readl(nandc, 0, 0, data_size, 0);
+ nandc_set_readl(nandc, 1, data_size,
+ oob_size, 1);
+ } else if (data_buf) {
+ nandc_set_readl(nandc, 0, 0, data_size, 1);
+ } else {
+ nandc_set_readl(nandc, 0, data_size,
+ oob_size, 1);
+ }
+ }
+
config_nand_cw_read(nandc);
if (data_buf)
@@ -1460,6 +1508,7 @@ static int copy_last_cw(struct qcom_nand_host *host, int page)
set_address(host, host->cw_size * (ecc->steps - 1), page);
update_rw_regs(host, 1, true);
+ nandc_set_readl(nandc, 0, 0, size, 1);
config_nand_single_cw_page_read(nandc);
@@ -1505,6 +1554,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;
@@ -1530,6 +1580,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_readl(nandc, 0, read_loc, data_size1, 0);
+ read_loc += data_size1;
+
+ nandc_set_readl(nandc, 1, read_loc, oob_size1, 0);
+ read_loc += oob_size1;
+
+ nandc_set_readl(nandc, 2, read_loc, data_size2, 0);
+ read_loc += data_size2;
+
+ nandc_set_readl(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
[toc] | [prev] | [next] | [standalone]
| From | Abhishek Sahu <absahu@codeaurora.org> |
|---|---|
| Date | 2017-08-05 18:30 +0200 |
| Subject | [PATCH v3 04/20] mtd: nand: qcom: add and initialize QPIC DMA resources |
| Message-ID | <uba7H-7k7-65@gated-at.bofh.it> |
| In reply to | #1704676 |
1. QPIC NAND controller uses 3 BAM channels: command, data tx
and data rx while EBI2 NAND controller uses only single ADM
channel.
2. CRCI is only required for ADM DMA and it's not required for
BAM DMA.
Reviewed-by: Archit Taneja <architt@codeaurora.org>
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---
drivers/mtd/nand/qcom_nandc.c | 86 ++++++++++++++++++++++++++++++++++---------
1 file changed, 68 insertions(+), 18 deletions(-)
diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index 08cda7d..0b2c8a1 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -257,9 +257,22 @@ struct qcom_nand_controller {
struct clk *core_clk;
struct clk *aon_clk;
- struct dma_chan *chan;
- unsigned int cmd_crci;
- unsigned int data_crci;
+ union {
+ /* will be used only by QPIC for BAM DMA */
+ struct {
+ struct dma_chan *tx_chan;
+ struct dma_chan *rx_chan;
+ struct dma_chan *cmd_chan;
+ };
+
+ /* will be used only by EBI2 for ADM DMA */
+ struct {
+ struct dma_chan *chan;
+ unsigned int cmd_crci;
+ unsigned int data_crci;
+ };
+ };
+
struct list_head desc_list;
u8 *data_buffer;
@@ -1992,10 +2005,31 @@ static int qcom_nandc_alloc(struct qcom_nand_controller *nandc)
if (!nandc->reg_read_buf)
return -ENOMEM;
- nandc->chan = dma_request_slave_channel(nandc->dev, "rxtx");
- if (!nandc->chan) {
- dev_err(nandc->dev, "failed to request slave channel\n");
- return -ENODEV;
+ if (nandc->props->is_bam) {
+ nandc->tx_chan = dma_request_slave_channel(nandc->dev, "tx");
+ if (!nandc->tx_chan) {
+ dev_err(nandc->dev, "failed to request tx channel\n");
+ return -ENODEV;
+ }
+
+ nandc->rx_chan = dma_request_slave_channel(nandc->dev, "rx");
+ if (!nandc->rx_chan) {
+ dev_err(nandc->dev, "failed to request rx channel\n");
+ return -ENODEV;
+ }
+
+ nandc->cmd_chan = dma_request_slave_channel(nandc->dev, "cmd");
+ if (!nandc->cmd_chan) {
+ dev_err(nandc->dev, "failed to request cmd channel\n");
+ return -ENODEV;
+ }
+ } else {
+ nandc->chan = dma_request_slave_channel(nandc->dev, "rxtx");
+ if (!nandc->chan) {
+ dev_err(nandc->dev,
+ "failed to request slave channel\n");
+ return -ENODEV;
+ }
}
INIT_LIST_HEAD(&nandc->desc_list);
@@ -2008,7 +2042,19 @@ static int qcom_nandc_alloc(struct qcom_nand_controller *nandc)
static void qcom_nandc_unalloc(struct qcom_nand_controller *nandc)
{
- dma_release_channel(nandc->chan);
+ if (nandc->props->is_bam) {
+ if (nandc->tx_chan)
+ dma_release_channel(nandc->tx_chan);
+
+ if (nandc->rx_chan)
+ dma_release_channel(nandc->rx_chan);
+
+ if (nandc->cmd_chan)
+ dma_release_channel(nandc->cmd_chan);
+ } else {
+ if (nandc->chan)
+ dma_release_channel(nandc->chan);
+ }
}
/* one time setup of a few nand controller registers */
@@ -2149,16 +2195,20 @@ static int qcom_nandc_parse_dt(struct platform_device *pdev)
struct device_node *np = nandc->dev->of_node;
int ret;
- ret = of_property_read_u32(np, "qcom,cmd-crci", &nandc->cmd_crci);
- if (ret) {
- dev_err(nandc->dev, "command CRCI unspecified\n");
- return ret;
- }
+ if (!nandc->props->is_bam) {
+ ret = of_property_read_u32(np, "qcom,cmd-crci",
+ &nandc->cmd_crci);
+ if (ret) {
+ dev_err(nandc->dev, "command CRCI unspecified\n");
+ return ret;
+ }
- ret = of_property_read_u32(np, "qcom,data-crci", &nandc->data_crci);
- if (ret) {
- dev_err(nandc->dev, "data CRCI unspecified\n");
- return ret;
+ ret = of_property_read_u32(np, "qcom,data-crci",
+ &nandc->data_crci);
+ if (ret) {
+ dev_err(nandc->dev, "data CRCI unspecified\n");
+ return ret;
+ }
}
return 0;
@@ -2208,7 +2258,7 @@ static int qcom_nandc_probe(struct platform_device *pdev)
ret = qcom_nandc_alloc(nandc);
if (ret)
- return ret;
+ goto err_core_clk;
ret = clk_prepare_enable(nandc->core_clk);
if (ret)
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[toc] | [prev] | [next] | [standalone]
| From | Abhishek Sahu <absahu@codeaurora.org> |
|---|---|
| Date | 2017-08-05 18:30 +0200 |
| Subject | [PATCH v3 11/20] mtd: nand: qcom: enable BAM or ADM mode |
| Message-ID | <uba7H-7k7-67@gated-at.bofh.it> |
| In reply to | #1704676 |
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.
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---
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 67c7e62..af69a89 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -165,6 +165,9 @@
BIT(ERASE_START_VALID) | \
BIT(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
@@ -1038,7 +1041,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);
@@ -2411,12 +2415,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
[toc] | [prev] | [next] | [standalone]
| From | Abhishek Sahu <absahu@codeaurora.org> |
|---|---|
| Date | 2017-08-05 18:30 +0200 |
| Subject | [PATCH v3 05/20] mtd: nand: qcom: DMA mapping support for register read buffer |
| Message-ID | <uba7H-7k7-71@gated-at.bofh.it> |
| In reply to | #1704676 |
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.
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---
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 0b2c8a1..064d06b 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -236,6 +236,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
@@ -281,6 +282,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;
@@ -373,6 +375,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) {
@@ -857,6 +877,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)
@@ -886,6 +907,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]);
@@ -907,6 +929,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;
@@ -1070,6 +1093,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;
@@ -2006,6 +2030,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");
@@ -2043,6 +2077,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
[toc] | [prev] | [next] | [standalone]
| From | Abhishek Sahu <absahu@codeaurora.org> |
|---|---|
| Date | 2017-08-05 18:30 +0200 |
| Subject | [PATCH v3 18/20] dt-bindings: qcom_nandc: IPQ8074 QPIC NAND documentation |
| Message-ID | <uba7H-7k7-77@gated-at.bofh.it> |
| In reply to | #1704676 |
Qualcom IPQ8074 SoC uses QPIC NAND controller version 1.5.0
which uses BAM DMA Engine.
Signed-off-by: Abhishek Sahu <absahu@codeaurora.org>
---
Documentation/devicetree/bindings/mtd/qcom_nandc.txt | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/mtd/qcom_nandc.txt b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
index d93b952..8dfa543 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
@@ -97,7 +99,7 @@ nand-controller@1ac00000 {
};
nand-controller@79b0000 {
- compatible = "qcom,ipq4019-nand";
+ compatible = "qcom,ipq4019-nand", "qcom,ipq8074-nand";
reg = <0x79b0000 0x1000>;
clocks = <&gcc GCC_QPIC_CLK>,
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[toc] | [prev] | [next] | [standalone]
| From | Rob Herring <robh@kernel.org> |
|---|---|
| Date | 2017-08-10 22:40 +0200 |
| Subject | Re: [PATCH v3 18/20] dt-bindings: qcom_nandc: IPQ8074 QPIC NAND documentation |
| Message-ID | <ud2pk-2qz-3@gated-at.bofh.it> |
| In reply to | #1704688 |
On Sat, Aug 05, 2017 at 09:49:56PM +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>
> ---
> Documentation/devicetree/bindings/mtd/qcom_nandc.txt | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/mtd/qcom_nandc.txt b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
> index d93b952..8dfa543 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
> @@ -97,7 +99,7 @@ nand-controller@1ac00000 {
> };
>
> nand-controller@79b0000 {
> - compatible = "qcom,ipq4019-nand";
> + compatible = "qcom,ipq4019-nand", "qcom,ipq8074-nand";
The order here should be reversed as 8074 is the newer one. And if 4019
is the fallback compatible, that needs to be documented above.
Rob
[toc] | [prev] | [next] | [standalone]
| From | Abhishek Sahu <absahu@codeaurora.org> |
|---|---|
| Date | 2017-08-11 11:10 +0200 |
| Subject | Re: [PATCH v3 18/20] dt-bindings: qcom_nandc: IPQ8074 QPIC NAND documentation |
| Message-ID | <ude77-1CC-1@gated-at.bofh.it> |
| In reply to | #1709007 |
On 2017-08-11 02:00, Rob Herring wrote:
> On Sat, Aug 05, 2017 at 09:49:56PM +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>
>> ---
>> Documentation/devicetree/bindings/mtd/qcom_nandc.txt | 4 +++-
>> 1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
>> b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
>> index d93b952..8dfa543 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
>> @@ -97,7 +99,7 @@ nand-controller@1ac00000 {
>> };
>>
>> nand-controller@79b0000 {
>> - compatible = "qcom,ipq4019-nand";
>> + compatible = "qcom,ipq4019-nand", "qcom,ipq8074-nand";
>
> The order here should be reversed as 8074 is the newer one. And if 4019
> is the fallback compatible, that needs to be documented above.
>
Thanks Rob for review.
This is not fallback compatible. I checked the other device tree
binding examples and it seems, we don't have to add every
similar compatible string in example. I will remove the
qcom,ipq8074-nand from example which is causing confusion.
> Rob
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web