aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ipq806x/patches-4.9/861-qcom-mtd-nand-Added-bam-transaction-and-support-addi.patch
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2017-06-08 00:24:27 +0200
committerJo-Philipp Wich <jo@mein.io>2017-06-08 01:03:39 +0200
commit55623a9c83c8c21b25f55e63ba0b5672f074f486 (patch)
treecf85750861e8e0a123cb54af46f0568a4f249e91 /target/linux/ipq806x/patches-4.9/861-qcom-mtd-nand-Added-bam-transaction-and-support-addi.patch
parentb9600b8542dffd05ae9a85b98693dbf85e7f6c42 (diff)
downloadupstream-55623a9c83c8c21b25f55e63ba0b5672f074f486.tar.gz
upstream-55623a9c83c8c21b25f55e63ba0b5672f074f486.tar.bz2
upstream-55623a9c83c8c21b25f55e63ba0b5672f074f486.zip
kernel: update kernel 4.9 to 4.9.31
Fixes the following security vulnerabilities: CVE-2017-8890 The inet_csk_clone_lock function in net/ipv4/inet_connection_sock.c in the Linux kernel through 4.10.15 allows attackers to cause a denial of service (double free) or possibly have unspecified other impact by leveraging use of the accept system call. CVE-2017-9074 The IPv6 fragmentation implementation in the Linux kernel through 4.11.1 does not consider that the nexthdr field may be associated with an invalid option, which allows local users to cause a denial of service (out-of-bounds read and BUG) or possibly have unspecified other impact via crafted socket and send system calls. CVE-2017-9075 The sctp_v6_create_accept_sk function in net/sctp/ipv6.c in the Linux kernel through 4.11.1 mishandles inheritance, which allows local users to cause a denial of service or possibly have unspecified other impact via crafted system calls, a related issue to CVE-2017-8890. CVE-2017-9076 The dccp_v6_request_recv_sock function in net/dccp/ipv6.c in the Linux kernel through 4.11.1 mishandles inheritance, which allows local users to cause a denial of service or possibly have unspecified other impact via crafted system calls, a related issue to CVE-2017-8890. CVE-2017-9077 The tcp_v6_syn_recv_sock function in net/ipv6/tcp_ipv6.c in the Linux kernel through 4.11.1 mishandles inheritance, which allows local users to cause a denial of service or possibly have unspecified other impact via crafted system calls, a related issue to CVE-2017-8890. CVE-2017-9242 The __ip6_append_data function in net/ipv6/ip6_output.c in the Linux kernel through 4.11.3 is too late in checking whether an overwrite of an skb data structure may occur, which allows local users to cause a denial of service (system crash) via crafted system calls. Ref: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-8890 Ref: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9074 Ref: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9075 Ref: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9076 Ref: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9077 Ref: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-9242 Ref: https://www.kernel.org/pub/linux/kernel/v4.x/ChangeLog-4.9.31 Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'target/linux/ipq806x/patches-4.9/861-qcom-mtd-nand-Added-bam-transaction-and-support-addi.patch')
-rw-r--r--target/linux/ipq806x/patches-4.9/861-qcom-mtd-nand-Added-bam-transaction-and-support-addi.patch755
1 files changed, 374 insertions, 381 deletions
diff --git a/target/linux/ipq806x/patches-4.9/861-qcom-mtd-nand-Added-bam-transaction-and-support-addi.patch b/target/linux/ipq806x/patches-4.9/861-qcom-mtd-nand-Added-bam-transaction-and-support-addi.patch
index 674de77d96..84f90b48d6 100644
--- a/target/linux/ipq806x/patches-4.9/861-qcom-mtd-nand-Added-bam-transaction-and-support-addi.patch
+++ b/target/linux/ipq806x/patches-4.9/861-qcom-mtd-nand-Added-bam-transaction-and-support-addi.patch
@@ -26,8 +26,6 @@ Signed-off-by: Ram Chandra Jangir <rjangir@codeaurora.org>
2 files changed, 721 insertions(+), 59 deletions(-)
create mode 100644 include/linux/dma/qcom_bam_dma.h
-diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
-index 76a0ffc..9d941e3 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -22,6 +22,7 @@
@@ -35,7 +33,7 @@ index 76a0ffc..9d941e3 100644
#include <linux/of_device.h>
#include <linux/delay.h>
+#include <linux/dma/qcom_bam_dma.h>
-
+
/* NANDc reg offsets */
#define NAND_FLASH_CMD 0x00
@@ -53,6 +54,8 @@
@@ -44,13 +42,13 @@ index 76a0ffc..9d941e3 100644
#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
@@ -131,6 +134,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
@@ -62,7 +60,7 @@ index 76a0ffc..9d941e3 100644
@@ -148,6 +156,9 @@
#define FETCH_ID 0xb
#define RESET_DEVICE 0xd
-
+
+/* NAND_CTRL bits */
+#define BAM_MODE_EN BIT(0)
+
@@ -72,7 +70,7 @@ index 76a0ffc..9d941e3 100644
@@ -169,12 +180,77 @@
#define ECC_BCH_4BIT BIT(2)
#define ECC_BCH_8BIT BIT(3)
-
+
+/* Flags used for BAM DMA desc preparation*/
+/* Don't set the EOT in current tx sgl */
+#define DMA_DESC_FLAG_NO_EOT (0x0001)
@@ -138,19 +136,19 @@ index 76a0ffc..9d941e3 100644
+ * @bam_desc_data - used for bam desc mappings
+ */
struct desc_info {
- struct list_head node;
-
- enum dma_data_direction dir;
- struct scatterlist sgl;
- struct dma_async_tx_descriptor *dma_desc;
+ struct list_head node;
+
+ enum dma_data_direction dir;
+ struct scatterlist sgl;
+ struct dma_async_tx_descriptor *dma_desc;
+ struct qcom_bam_custom_data bam_desc_data;
};
-
+
/*
@@ -202,6 +278,13 @@ struct nandc_regs {
- __le32 orig_vld;
-
- __le32 ecc_buf_cfg;
+ __le32 orig_vld;
+
+ __le32 ecc_buf_cfg;
+ __le32 read_location0;
+ __le32 read_location1;
+ __le32 read_location2;
@@ -159,7 +157,7 @@ index 76a0ffc..9d941e3 100644
+ __le32 erased_cw_detect_cfg_clr;
+ __le32 erased_cw_detect_cfg_set;
};
-
+
/*
@@ -217,6 +300,7 @@ struct nandc_regs {
* @aon_clk: another controller clock
@@ -171,16 +169,16 @@ index 76a0ffc..9d941e3 100644
* @desc_list: DMA descriptor list (list of desc_infos)
@@ -242,6 +326,7 @@ struct nandc_regs {
struct qcom_nand_controller {
- struct nand_hw_control controller;
- struct list_head host_list;
+ struct nand_hw_control controller;
+ struct list_head host_list;
+ struct bam_transaction *bam_txn;
-
- struct device *dev;
-
+
+ struct device *dev;
+
@@ -342,6 +427,45 @@ struct qcom_nand_driver_data {
- bool dma_bam_enabled;
+ bool dma_bam_enabled;
};
-
+
+/* Allocates and Initializes the BAM transaction */
+struct bam_transaction *alloc_bam_transaction(
+ struct qcom_nand_controller *nandc)
@@ -222,11 +220,11 @@ index 76a0ffc..9d941e3 100644
+
static inline struct qcom_nand_host *to_qcom_nand_host(struct nand_chip *chip)
{
- return container_of(chip, struct qcom_nand_host, chip);
-@@ -398,6 +522,16 @@ 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;
+ return container_of(chip, struct qcom_nand_host, chip);
+@@ -398,6 +522,16 @@ static __le32 *offset_to_nandc_reg(struc
+ return &regs->orig_vld;
+ case NAND_EBI2_ECC_BUF_CFG:
+ return &regs->ecc_buf_cfg;
+ case NAND_BUFFER_STATUS:
+ return &regs->clrreadstatus;
+ case NAND_READ_LOCATION_0:
@@ -237,48 +235,48 @@ index 76a0ffc..9d941e3 100644
+ return &regs->read_location2;
+ case NAND_READ_LOCATION_3:
+ return &regs->read_location3;
- default:
- return NULL;
- }
-@@ -439,7 +573,7 @@ static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read)
+ default:
+ return NULL;
+ }
+@@ -439,7 +573,7 @@ static void update_rw_regs(struct qcom_n
{
- struct nand_chip *chip = &host->chip;
- struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
+ struct nand_chip *chip = &host->chip;
+ struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
- u32 cmd, cfg0, cfg1, ecc_bch_cfg;
+ u32 cmd, cfg0, cfg1, ecc_bch_cfg, read_location0;
-
- if (read) {
- if (host->use_ecc)
-@@ -456,12 +590,20 @@ static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read)
-
- cfg1 = host->cfg1;
- ecc_bch_cfg = host->ecc_bch_cfg;
+
+ if (read) {
+ if (host->use_ecc)
+@@ -456,12 +590,20 @@ static void update_rw_regs(struct qcom_n
+
+ cfg1 = host->cfg1;
+ ecc_bch_cfg = host->ecc_bch_cfg;
+ if (read)
+ read_location0 = (0 << READ_LOCATION_OFFSET) |
+ (host->cw_data << READ_LOCATION_SIZE) |
+ (1 << READ_LOCATION_LAST);
- } else {
- cfg0 = (host->cfg0_raw & ~(7U << CW_PER_PAGE)) |
- (num_cw - 1) << CW_PER_PAGE;
-
- cfg1 = host->cfg1_raw;
- ecc_bch_cfg = 1 << ECC_CFG_ECC_DISABLE;
+ } else {
+ cfg0 = (host->cfg0_raw & ~(7U << CW_PER_PAGE)) |
+ (num_cw - 1) << CW_PER_PAGE;
+
+ cfg1 = host->cfg1_raw;
+ ecc_bch_cfg = 1 << ECC_CFG_ECC_DISABLE;
+ if (read)
+ read_location0 = (0 << READ_LOCATION_OFFSET) |
+ (host->cw_size << READ_LOCATION_SIZE) |
+ (1 << READ_LOCATION_LAST);
- }
-
- nandc_set_reg(nandc, NAND_FLASH_CMD, cmd);
-@@ -472,8 +614,104 @@ 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);
+ }
+
+ nandc_set_reg(nandc, NAND_FLASH_CMD, cmd);
+@@ -472,8 +614,104 @@ static void update_rw_regs(struct qcom_n
+ 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_reg(nandc, NAND_READ_LOCATION_0, read_location0);
- }
-
++}
++
+/*
+ * Prepares the command descriptor for BAM DMA which will be used for NAND
+ * register read and write. The command descriptor requires the command
@@ -339,8 +337,8 @@ index 76a0ffc..9d941e3 100644
+ }
+
+ return 0;
-+}
-+
+ }
+
+/*
+ * Prepares the data descriptor for BAM DMA which will be used for NAND
+ * data read and write.
@@ -373,25 +371,25 @@ index 76a0ffc..9d941e3 100644
+
+/* Prepares the dma desciptor for adm dma engine */
static int prep_dma_desc(struct qcom_nand_controller *nandc, bool read,
- int reg_off, const void *vaddr, int size,
- bool flow_control)
-@@ -552,7 +790,7 @@ static int prep_dma_desc(struct qcom_nand_controller *nandc, bool read,
+ int reg_off, const void *vaddr, int size,
+ bool flow_control)
+@@ -552,7 +790,7 @@ err:
* @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;
-@@ -561,10 +799,18 @@ static int read_reg_dma(struct qcom_nand_controller *nandc, int first,
- if (first == NAND_READ_ID || first == NAND_FLASH_STATUS)
- flow_control = true;
-
+ bool flow_control = false;
+ void *vaddr;
+@@ -561,10 +799,18 @@ static int read_reg_dma(struct qcom_nand
+ if (first == NAND_READ_ID || first == NAND_FLASH_STATUS)
+ flow_control = true;
+
- size = num_regs * sizeof(u32);
- vaddr = nandc->reg_read_buf + nandc->reg_read_pos;
- nandc->reg_read_pos += num_regs;
-
+ vaddr = nandc->reg_read_buf + nandc->reg_read_pos;
+ nandc->reg_read_pos += num_regs;
+
+ if (nandc->dma_bam_enabled) {
+ size = num_regs;
+
@@ -401,22 +399,22 @@ index 76a0ffc..9d941e3 100644
+
+ size = num_regs * sizeof(u32);
+
- return prep_dma_desc(nandc, true, first, vaddr, size, flow_control);
+ return prep_dma_desc(nandc, true, first, vaddr, size, flow_control);
}
-
-@@ -576,7 +822,7 @@ static int read_reg_dma(struct qcom_nand_controller *nandc, int first,
+
+@@ -576,7 +822,7 @@ static int read_reg_dma(struct qcom_nand
* @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;
-@@ -588,12 +834,29 @@ static int write_reg_dma(struct qcom_nand_controller *nandc, int first,
- if (first == NAND_FLASH_CMD)
- flow_control = true;
-
+ bool flow_control = false;
+ struct nandc_regs *regs = nandc->regs;
+@@ -588,12 +834,29 @@ static int write_reg_dma(struct qcom_nan
+ if (first == NAND_FLASH_CMD)
+ flow_control = true;
+
+ if (first == NAND_ERASED_CW_DETECT_CFG) {
+ if (flags & DMA_DESC_ERASED_CW_SET)
+ vaddr = &regs->erased_cw_detect_cfg_set;
@@ -427,12 +425,12 @@ index 76a0ffc..9d941e3 100644
+ if (first == NAND_EXEC_CMD)
+ flags |= DMA_DESC_FLAG_BAM_NWD;
+
- if (first == NAND_DEV_CMD1_RESTORE)
- first = NAND_DEV_CMD1;
-
- if (first == NAND_DEV_CMD_VLD_RESTORE)
- first = NAND_DEV_CMD_VLD;
-
+ if (first == NAND_DEV_CMD1_RESTORE)
+ first = NAND_DEV_CMD1;
+
+ if (first == NAND_DEV_CMD_VLD_RESTORE)
+ first = NAND_DEV_CMD_VLD;
+
+ if (nandc->dma_bam_enabled) {
+ size = num_regs;
+
@@ -440,10 +438,10 @@ index 76a0ffc..9d941e3 100644
+ flags);
+ }
+
- size = num_regs * sizeof(u32);
-
- return prep_dma_desc(nandc, false, first, vaddr, size, flow_control);
-@@ -608,8 +871,12 @@ 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);
+@@ -608,8 +871,12 @@ static int write_reg_dma(struct qcom_nan
* @size: DMA transaction size in bytes
*/
static int read_data_dma(struct qcom_nand_controller *nandc, int reg_off,
@@ -454,10 +452,10 @@ index 76a0ffc..9d941e3 100644
+ return prep_dma_desc_data_bam(nandc, true, reg_off, vaddr, size,
+ flags);
+
- return prep_dma_desc(nandc, true, reg_off, vaddr, size, false);
+ return prep_dma_desc(nandc, true, reg_off, vaddr, size, false);
}
-
-@@ -622,8 +889,12 @@ static int read_data_dma(struct qcom_nand_controller *nandc, int reg_off,
+
+@@ -622,8 +889,12 @@ static int read_data_dma(struct qcom_nan
* @size: DMA transaction size in bytes
*/
static int write_data_dma(struct qcom_nand_controller *nandc, int reg_off,
@@ -468,17 +466,17 @@ index 76a0ffc..9d941e3 100644
+ return prep_dma_desc_data_bam(nandc, false, reg_off, vaddr,
+ size, flags);
+
- return prep_dma_desc(nandc, false, reg_off, vaddr, size, false);
+ return prep_dma_desc(nandc, false, reg_off, vaddr, size, false);
}
-
-@@ -633,14 +904,57 @@ static int write_data_dma(struct qcom_nand_controller *nandc, int reg_off,
+
+@@ -633,14 +904,57 @@ static int write_data_dma(struct qcom_na
*/
static void config_cw_read(struct qcom_nand_controller *nandc)
{
- write_reg_dma(nandc, NAND_FLASH_CMD, 3);
- write_reg_dma(nandc, NAND_DEV0_CFG0, 3);
- write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1);
-
+
- write_reg_dma(nandc, NAND_EXEC_CMD, 1);
+ write_reg_dma(nandc, NAND_FLASH_CMD, 3, 0);
+ write_reg_dma(nandc, NAND_DEV0_CFG0, 3, 0);
@@ -490,10 +488,10 @@ index 76a0ffc..9d941e3 100644
+ if (nandc->dma_bam_enabled)
+ write_reg_dma(nandc, NAND_READ_LOCATION_0, 1,
+ DMA_DESC_FLAG_BAM_NEXT_SGL);
-+
-
+
- read_reg_dma(nandc, NAND_FLASH_STATUS, 2);
- read_reg_dma(nandc, NAND_ERASED_CW_DETECT_STATUS, 1);
++
+ write_reg_dma(nandc, NAND_EXEC_CMD, 1, DMA_DESC_FLAG_BAM_NWD |
+ DMA_DESC_FLAG_BAM_NEXT_SGL);
+
@@ -533,9 +531,9 @@ index 76a0ffc..9d941e3 100644
+ read_reg_dma(nandc, NAND_ERASED_CW_DETECT_STATUS, 1,
+ DMA_DESC_FLAG_BAM_NEXT_SGL);
}
-
+
/*
-@@ -649,19 +963,20 @@ static void config_cw_read(struct qcom_nand_controller *nandc)
+@@ -649,19 +963,20 @@ static void config_cw_read(struct qcom_n
*/
static void config_cw_write_pre(struct qcom_nand_controller *nandc)
{
@@ -547,137 +545,138 @@ index 76a0ffc..9d941e3 100644
+ write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1,
+ DMA_DESC_FLAG_BAM_NEXT_SGL);
}
-
+
static void config_cw_write_post(struct qcom_nand_controller *nandc)
{
- write_reg_dma(nandc, NAND_EXEC_CMD, 1);
+ write_reg_dma(nandc, NAND_EXEC_CMD, 1, DMA_DESC_FLAG_BAM_NEXT_SGL);
-
+
- read_reg_dma(nandc, NAND_FLASH_STATUS, 1);
+ read_reg_dma(nandc, NAND_FLASH_STATUS, 1, DMA_DESC_FLAG_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, DMA_DESC_FLAG_BAM_NEXT_SGL);
}
-
+
/*
-@@ -675,6 +990,8 @@ static int nandc_param(struct qcom_nand_host *host)
- struct nand_chip *chip = &host->chip;
- struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
-
+@@ -675,6 +990,8 @@ static int nandc_param(struct qcom_nand_
+ struct nand_chip *chip = &host->chip;
+ struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
+
+ clear_bam_transaction(nandc);
+
- /*
- * NAND_CMD_PARAM is called before we know much about the FLASH chip
- * in use. we configure the controller to perform a raw read of 512
-@@ -708,9 +1025,13 @@ 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);
+ /*
+ * NAND_CMD_PARAM is called before we know much about the FLASH chip
+ * in use. we configure the controller to perform a raw read of 512
+@@ -708,9 +1025,13 @@ static int nandc_param(struct qcom_nand_
+
+ nandc_set_reg(nandc, NAND_DEV_CMD1_RESTORE, nandc->cmd1);
+ nandc_set_reg(nandc, NAND_DEV_CMD_VLD_RESTORE, nandc->vld);
+ nandc_set_reg(nandc, NAND_READ_LOCATION_0,
+ (0 << READ_LOCATION_OFFSET) |
+ (512 << READ_LOCATION_SIZE) |
+ (1 << READ_LOCATION_LAST));
-
+
- 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, DMA_DESC_FLAG_BAM_NEXT_SGL);
-
- nandc->buf_count = 512;
- memset(nandc->data_buffer, 0xff, nandc->buf_count);
-@@ -718,11 +1039,12 @@ static int nandc_param(struct qcom_nand_host *host)
- config_cw_read(nandc);
-
- read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer,
+
+ nandc->buf_count = 512;
+ memset(nandc->data_buffer, 0xff, nandc->buf_count);
+@@ -718,11 +1039,12 @@ static int nandc_param(struct qcom_nand_
+ config_cw_read(nandc);
+
+ read_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer,
- nandc->buf_count);
+ nandc->buf_count, 0);
-
- /* restore CMD1 and VLD regs */
+
+ /* 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,
+ DMA_DESC_FLAG_BAM_NEXT_SGL);
-
- return 0;
+
+ return 0;
}
-@@ -733,6 +1055,8 @@ static int erase_block(struct qcom_nand_host *host, int page_addr)
- struct nand_chip *chip = &host->chip;
- struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
-
+@@ -733,6 +1055,8 @@ static int erase_block(struct qcom_nand_
+ struct nand_chip *chip = &host->chip;
+ struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
+
+ clear_bam_transaction(nandc);
+
- nandc_set_reg(nandc, NAND_FLASH_CMD,
- BLOCK_ERASE | PAGE_ACC | LAST_PAGE);
- nandc_set_reg(nandc, NAND_ADDR0, page_addr);
-@@ -744,14 +1068,15 @@ 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);
-
+ nandc_set_reg(nandc, NAND_FLASH_CMD,
+ BLOCK_ERASE | PAGE_ACC | LAST_PAGE);
+ nandc_set_reg(nandc, NAND_ADDR0, page_addr);
+@@ -744,14 +1068,15 @@ static int erase_block(struct qcom_nand_
+ 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);
-
+
- read_reg_dma(nandc, NAND_FLASH_STATUS, 1);
+ write_reg_dma(nandc, NAND_FLASH_CMD, 3, DMA_DESC_FLAG_BAM_NEXT_SGL);
+ write_reg_dma(nandc, NAND_DEV0_CFG0, 2, DMA_DESC_FLAG_BAM_NEXT_SGL);
+ write_reg_dma(nandc, NAND_EXEC_CMD, 1, DMA_DESC_FLAG_BAM_NEXT_SGL);
-
++
++ read_reg_dma(nandc, NAND_FLASH_STATUS, 1, DMA_DESC_FLAG_BAM_NEXT_SGL);
+
- write_reg_dma(nandc, NAND_FLASH_STATUS, 1);
- write_reg_dma(nandc, NAND_READ_STATUS, 1);
-+ read_reg_dma(nandc, NAND_FLASH_STATUS, 1, DMA_DESC_FLAG_BAM_NEXT_SGL);
-+
+ write_reg_dma(nandc, NAND_FLASH_STATUS, 1, 0);
+ write_reg_dma(nandc, NAND_READ_STATUS, 1, DMA_DESC_FLAG_BAM_NEXT_SGL);
-
- return 0;
+
+ return 0;
}
-@@ -765,16 +1090,19 @@ static int read_id(struct qcom_nand_host *host, int column)
- if (column == -1)
- return 0;
-
+@@ -765,16 +1090,19 @@ static int read_id(struct qcom_nand_host
+ if (column == -1)
+ return 0;
+
+ clear_bam_transaction(nandc);
+
- 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_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->dma_bam_enabled ? 0 : DM_EN);
- nandc_set_reg(nandc, NAND_EXEC_CMD, 1);
-
+ 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, DMA_DESC_FLAG_BAM_NEXT_SGL);
+ write_reg_dma(nandc, NAND_EXEC_CMD, 1, DMA_DESC_FLAG_BAM_NEXT_SGL);
-
+
- read_reg_dma(nandc, NAND_READ_ID, 1);
+ read_reg_dma(nandc, NAND_READ_ID, 1, DMA_DESC_FLAG_BAM_NEXT_SGL);
-
- return 0;
+
+ return 0;
}
-@@ -785,15 +1113,61 @@ static int reset(struct qcom_nand_host *host)
- struct nand_chip *chip = &host->chip;
- struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
-
+@@ -785,28 +1113,108 @@ static int reset(struct qcom_nand_host *
+ struct nand_chip *chip = &host->chip;
+ struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
+
+ clear_bam_transaction(nandc);
+
- nandc_set_reg(nandc, NAND_FLASH_CMD, RESET_DEVICE);
- nandc_set_reg(nandc, NAND_EXEC_CMD, 1);
-
+ 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, DMA_DESC_FLAG_BAM_NEXT_SGL);
+ write_reg_dma(nandc, NAND_EXEC_CMD, 1, DMA_DESC_FLAG_BAM_NEXT_SGL);
-+
+
+- read_reg_dma(nandc, NAND_FLASH_STATUS, 1);
+ read_reg_dma(nandc, NAND_FLASH_STATUS, 1, DMA_DESC_FLAG_BAM_NEXT_SGL);
-+
-+ return 0;
-+}
-+
+
+ return 0;
+ }
+
+static int prepare_bam_async_desc(struct qcom_nand_controller *nandc,
+ struct dma_chan *chan,
+ struct qcom_bam_sgl *bam_sgl,
@@ -715,19 +714,18 @@ index 76a0ffc..9d941e3 100644
+ }
+
+ desc->dma_desc = dma_desc;
-
-- read_reg_dma(nandc, NAND_FLASH_STATUS, 1);
++
+ list_add_tail(&desc->node, &nandc->desc_list);
-
- return 0;
+
- }
-
++ return 0;
++
++}
++
/* helpers to submit/free our list of dma descriptors */
-@@ -801,12 +1175,46 @@ static int submit_descs(struct qcom_nand_controller *nandc)
+ static int submit_descs(struct qcom_nand_controller *nandc)
{
- struct desc_info *desc;
- dma_cookie_t cookie = 0;
+ struct desc_info *desc;
+ dma_cookie_t cookie = 0;
+ struct bam_transaction *bam_txn = nandc->bam_txn;
+ int r;
+
@@ -754,10 +752,10 @@ index 76a0ffc..9d941e3 100644
+ if (r)
+ return r;
+ }
-
- list_for_each_entry(desc, &nandc->desc_list, node)
- cookie = dmaengine_submit(desc->dma_desc);
-
+
+ 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->dma_bam_enabled) {
@@ -770,13 +768,13 @@ index 76a0ffc..9d941e3 100644
+ if (dma_sync_wait(nandc->chan, cookie) != DMA_COMPLETE)
+ return -ETIMEDOUT;
+ }
-
- return 0;
+
+ return 0;
}
-@@ -817,7 +1225,16 @@ static void free_descs(struct qcom_nand_controller *nandc)
-
- list_for_each_entry_safe(desc, n, &nandc->desc_list, node) {
- list_del(&desc->node);
+@@ -817,7 +1225,16 @@ static void free_descs(struct qcom_nand_
+
+ 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->dma_bam_enabled)
@@ -788,23 +786,23 @@ index 76a0ffc..9d941e3 100644
+ dma_unmap_sg(nandc->dev, &desc->sgl, 1,
+ desc->dir);
+
- kfree(desc);
- }
+ kfree(desc);
+ }
}
-@@ -1128,6 +1545,9 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf,
- struct nand_ecc_ctrl *ecc = &chip->ecc;
- int i, ret;
-
+@@ -1128,6 +1545,9 @@ static int read_page_ecc(struct qcom_nan
+ struct nand_ecc_ctrl *ecc = &chip->ecc;
+ int i, ret;
+
+ if (nandc->dma_bam_enabled)
+ config_bam_page_read(nandc);
+
- /* queue cmd descs for each codeword */
- for (i = 0; i < ecc->steps; i++) {
- int data_size, oob_size;
-@@ -1141,11 +1561,36 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf,
- oob_size = host->ecc_bytes_hw + host->spare_bytes;
- }
-
+ /* queue cmd descs for each codeword */
+ for (i = 0; i < ecc->steps; i++) {
+ int data_size, oob_size;
+@@ -1141,11 +1561,36 @@ static int read_page_ecc(struct qcom_nan
+ oob_size = host->ecc_bytes_hw + host->spare_bytes;
+ }
+
- config_cw_read(nandc);
+ if (nandc->dma_bam_enabled) {
+ if (data_buf && oob_buf) {
@@ -832,71 +830,71 @@ index 76a0ffc..9d941e3 100644
+ } else {
+ config_cw_read(nandc);
+ }
-
- if (data_buf)
- read_data_dma(nandc, FLASH_BUF_ACC, 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
-@@ -1161,7 +1606,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,
+
+ /*
+ * when ecc is enabled, the controller doesn't read the real
+@@ -1161,7 +1606,7 @@ static int read_page_ecc(struct qcom_nan
+ *oob_buf++ = 0xff;
+
+ read_data_dma(nandc, FLASH_BUF_ACC + data_size,
- oob_buf, oob_size);
+ oob_buf, oob_size, 0);
- }
-
- if (data_buf)
-@@ -1200,10 +1645,14 @@ 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);
+ }
+
+ if (data_buf)
+@@ -1200,10 +1645,14 @@ static int copy_last_cw(struct qcom_nand
+
+ set_address(host, host->cw_size * (ecc->steps - 1), page);
+ update_rw_regs(host, 1, true);
+ nandc_set_reg(nandc, NAND_READ_LOCATION_0,
+ (0 << READ_LOCATION_OFFSET) |
+ (size << READ_LOCATION_SIZE) |
+ (1 << READ_LOCATION_LAST));
-
- config_cw_read(nandc);
-
+
+ config_cw_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)
-@@ -1226,6 +1675,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;
-
+
+ ret = submit_descs(nandc);
+ if (ret)
+@@ -1226,6 +1675,7 @@ static int qcom_nandc_read_page(struct m
+ 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");
-@@ -1245,13 +1695,19 @@ 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;
+ ret = read_page_ecc(host, data_buf, oob_buf);
+ if (ret) {
+ dev_err(nandc->dev, "failure to read page\n");
+@@ -1245,13 +1695,19 @@ static int qcom_nandc_read_page_raw(stru
+ u8 *data_buf, *oob_buf;
+ struct nand_ecc_ctrl *ecc = &chip->ecc;
+ int i, ret;
+ int read_location;
-
- data_buf = buf;
- oob_buf = chip->oob_poi;
-
- host->use_ecc = false;
+
+ data_buf = buf;
+ oob_buf = chip->oob_poi;
+
+ host->use_ecc = false;
+
+ clear_bam_transaction(nandc);
- update_rw_regs(host, ecc->steps, true);
-
+ update_rw_regs(host, ecc->steps, true);
+
+ if (nandc->dma_bam_enabled)
+ config_bam_page_read(nandc);
+
- for (i = 0; i < ecc->steps; i++) {
- int data_size1, data_size2, oob_size1, oob_size2;
- int reg_off = FLASH_BUF_ACC;
-@@ -1269,21 +1725,49 @@ static int qcom_nandc_read_page_raw(struct mtd_info *mtd,
- oob_size2 = host->ecc_bytes_hw + host->spare_bytes;
- }
-
+ for (i = 0; i < ecc->steps; i++) {
+ int data_size1, data_size2, oob_size1, oob_size2;
+ int reg_off = FLASH_BUF_ACC;
+@@ -1269,21 +1725,49 @@ static int qcom_nandc_read_page_raw(stru
+ oob_size2 = host->ecc_bytes_hw + host->spare_bytes;
+ }
+
- config_cw_read(nandc);
+ if (nandc->dma_bam_enabled) {
+ read_location = 0;
@@ -927,181 +925,181 @@ index 76a0ffc..9d941e3 100644
+ } else {
+ config_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;
-
+ 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;
-
+ 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;
-
+ 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;
- }
-
-@@ -1306,6 +1790,7 @@ static int qcom_nandc_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
- int ret;
-
- clear_read_regs(nandc);
+ oob_buf += oob_size2;
+ }
+
+@@ -1306,6 +1790,7 @@ static int qcom_nandc_read_oob(struct mt
+ int ret;
+
+ clear_read_regs(nandc);
+ clear_bam_transaction(nandc);
-
- host->use_ecc = true;
- set_address(host, 0, page);
-@@ -1329,6 +1814,7 @@ static int qcom_nandc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
- int i, ret;
-
- clear_read_regs(nandc);
+
+ host->use_ecc = true;
+ set_address(host, 0, page);
+@@ -1329,6 +1814,7 @@ static int qcom_nandc_write_page(struct
+ int i, ret;
+
+ clear_read_regs(nandc);
+ clear_bam_transaction(nandc);
-
- data_buf = (u8 *)buf;
- oob_buf = chip->oob_poi;
-@@ -1350,7 +1836,8 @@ static int qcom_nandc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
-
- config_cw_write_pre(nandc);
-
+
+ data_buf = (u8 *)buf;
+ oob_buf = chip->oob_poi;
+@@ -1350,7 +1836,8 @@ static int qcom_nandc_write_page(struct
+
+ config_cw_write_pre(nandc);
+
- 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) ? DMA_DESC_FLAG_NO_EOT : 0);
-
- /*
- * when ECC is enabled, we don't really need to write anything
-@@ -1363,7 +1850,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,
+
+ /*
+ * when ECC is enabled, we don't really need to write anything
+@@ -1363,7 +1850,7 @@ static int qcom_nandc_write_page(struct
+ oob_buf += host->bbm_size;
+
+ write_data_dma(nandc, FLASH_BUF_ACC + data_size,
- oob_buf, oob_size);
+ oob_buf, oob_size, 0);
- }
-
- config_cw_write_post(nandc);
-@@ -1393,6 +1880,7 @@ static int qcom_nandc_write_page_raw(struct mtd_info *mtd,
- int i, ret;
-
- clear_read_regs(nandc);
+ }
+
+ config_cw_write_post(nandc);
+@@ -1393,6 +1880,7 @@ static int qcom_nandc_write_page_raw(str
+ int i, ret;
+
+ clear_read_regs(nandc);
+ clear_bam_transaction(nandc);
-
- data_buf = (u8 *)buf;
- oob_buf = chip->oob_poi;
-@@ -1419,19 +1907,22 @@ static int qcom_nandc_write_page_raw(struct mtd_info *mtd,
-
- config_cw_write_pre(nandc);
-
+
+ data_buf = (u8 *)buf;
+ oob_buf = chip->oob_poi;
+@@ -1419,19 +1907,22 @@ static int qcom_nandc_write_page_raw(str
+
+ config_cw_write_pre(nandc);
+
- write_data_dma(nandc, reg_off, data_buf, data_size1);
+ write_data_dma(nandc, reg_off, data_buf, data_size1,
+ DMA_DESC_FLAG_NO_EOT);
- reg_off += data_size1;
- data_buf += data_size1;
-
+ 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,
+ DMA_DESC_FLAG_NO_EOT);
- reg_off += oob_size1;
- oob_buf += oob_size1;
-
+ 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,
+ DMA_DESC_FLAG_NO_EOT);
- reg_off += data_size2;
- data_buf += data_size2;
-
+ 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_cw_write_post(nandc);
-@@ -1467,6 +1958,7 @@ static int qcom_nandc_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
-
- host->use_ecc = true;
-
+ oob_buf += oob_size2;
+
+ config_cw_write_post(nandc);
+@@ -1467,6 +1958,7 @@ static int qcom_nandc_write_oob(struct m
+
+ host->use_ecc = true;
+
+ clear_bam_transaction(nandc);
- ret = copy_last_cw(host, page);
- if (ret)
- return ret;
-@@ -1486,7 +1978,7 @@ static int qcom_nandc_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
-
- config_cw_write_pre(nandc);
- write_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer,
+ ret = copy_last_cw(host, page);
+ if (ret)
+ return ret;
+@@ -1486,7 +1978,7 @@ static int qcom_nandc_write_oob(struct m
+
+ config_cw_write_pre(nandc);
+ write_data_dma(nandc, FLASH_BUF_ACC, nandc->data_buffer,
- data_size + oob_size);
+ data_size + oob_size, 0);
- config_cw_write_post(nandc);
-
- ret = submit_descs(nandc);
-@@ -1524,6 +2016,7 @@ static int qcom_nandc_block_bad(struct mtd_info *mtd, loff_t ofs)
- */
- host->use_ecc = false;
-
+ config_cw_write_post(nandc);
+
+ ret = submit_descs(nandc);
+@@ -1524,6 +2016,7 @@ static int qcom_nandc_block_bad(struct m
+ */
+ host->use_ecc = false;
+
+ clear_bam_transaction(nandc);
- ret = copy_last_cw(host, page);
- if (ret)
- goto err;
-@@ -1554,6 +2047,7 @@ static int qcom_nandc_block_markbad(struct mtd_info *mtd, loff_t ofs)
- int page, ret, status = 0;
-
- clear_read_regs(nandc);
+ ret = copy_last_cw(host, page);
+ if (ret)
+ goto err;
+@@ -1554,6 +2047,7 @@ static int qcom_nandc_block_markbad(stru
+ 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.
-@@ -1570,7 +2064,8 @@ static int qcom_nandc_block_markbad(struct mtd_info *mtd, loff_t ofs)
- update_rw_regs(host, 1, false);
-
- config_cw_write_pre(nandc);
+
+ /*
+ * to mark the BBM as bad, we flash the entire last codeword with 0s.
+@@ -1570,7 +2064,8 @@ static int qcom_nandc_block_markbad(stru
+ update_rw_regs(host, 1, false);
+
+ config_cw_write_pre(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_cw_write_post(nandc);
-
- ret = submit_descs(nandc);
-@@ -1930,6 +2425,8 @@ static int qcom_nand_host_setup(struct qcom_nand_host *host)
-
- host->clrflashstatus = FS_READY_BSY_N;
- host->clrreadstatus = 0xc0;
+ config_cw_write_post(nandc);
+
+ ret = submit_descs(nandc);
+@@ -1930,6 +2425,8 @@ static int qcom_nand_host_setup(struct q
+
+ host->clrflashstatus = FS_READY_BSY_N;
+ host->clrreadstatus = 0xc0;
+ nandc->regs->erased_cw_detect_cfg_clr = CLR_ERASED_PAGE_DET;
+ nandc->regs->erased_cw_detect_cfg_set = 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",
-@@ -2008,6 +2505,12 @@ static int qcom_nandc_alloc(struct qcom_nand_controller *nandc)
- dev_err(nandc->dev, "failed to request cmd channel\n");
- return -ENODEV;
- }
+
+ 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",
+@@ -2008,6 +2505,12 @@ static int qcom_nandc_alloc(struct qcom_
+ dev_err(nandc->dev, "failed to request cmd channel\n");
+ return -ENODEV;
+ }
+
+ nandc->bam_txn = alloc_bam_transaction(nandc);
+ if (!nandc->bam_txn) {
+ dev_err(nandc->dev, "failed to allocate bam transaction\n");
+ return -ENOMEM;
+ }
- }
-
- INIT_LIST_HEAD(&nandc->desc_list);
-@@ -2043,6 +2546,9 @@ static void qcom_nandc_unalloc(struct qcom_nand_controller *nandc)
- devm_kfree(nandc->dev, nandc->reg_read_buf);
- }
-
+ }
+
+ INIT_LIST_HEAD(&nandc->desc_list);
+@@ -2043,6 +2546,9 @@ static void qcom_nandc_unalloc(struct qc
+ devm_kfree(nandc->dev, nandc->reg_read_buf);
+ }
+
+ if (nandc->bam_txn)
+ devm_kfree(nandc->dev, nandc->bam_txn);
+
- if (nandc->regs)
- devm_kfree(nandc->dev, nandc->regs);
-
-@@ -2053,11 +2559,18 @@ static void qcom_nandc_unalloc(struct qcom_nand_controller *nandc)
+ if (nandc->regs)
+ devm_kfree(nandc->dev, nandc->regs);
+
+@@ -2053,11 +2559,18 @@ static void qcom_nandc_unalloc(struct qc
/* 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);
-
+ /* kill onenand */
+ nandc_write(nandc, SFLASHC_BURST_CFG, 0);
+
- /* enable ADM DMA */
- nandc_write(nandc, NAND_FLASH_CHIP_SELECT, DM_EN);
+ /* enable ADM or BAM DMA */
@@ -1111,12 +1109,9 @@ index 76a0ffc..9d941e3 100644
+ nand_ctrl = nandc_read(nandc, NAND_CTRL);
+ nandc_write(nandc, NAND_CTRL, nand_ctrl | BAM_MODE_EN);
+ }
-
- /* save the original values of these registers */
- nandc->cmd1 = nandc_read(nandc, NAND_DEV_CMD1);
-diff --git a/include/linux/dma/qcom_bam_dma.h b/include/linux/dma/qcom_bam_dma.h
-new file mode 100644
-index 0000000..7e87a85
+
+ /* save the original values of these registers */
+ nandc->cmd1 = nandc_read(nandc, NAND_DEV_CMD1);
--- /dev/null
+++ b/include/linux/dma/qcom_bam_dma.h
@@ -0,0 +1,149 @@
@@ -1269,5 +1264,3 @@ index 0000000..7e87a85
+ bam_ce->mask = 0xFFFFFFFF;
+}
+#endif
---
-2.7.2