aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ipq806x/patches-4.9/860-qcom-mtd-nand-Add-bam_dma-support-in-qcom_nand-drive.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/ipq806x/patches-4.9/860-qcom-mtd-nand-Add-bam_dma-support-in-qcom_nand-drive.patch')
-rw-r--r--target/linux/ipq806x/patches-4.9/860-qcom-mtd-nand-Add-bam_dma-support-in-qcom_nand-drive.patch370
1 files changed, 0 insertions, 370 deletions
diff --git a/target/linux/ipq806x/patches-4.9/860-qcom-mtd-nand-Add-bam_dma-support-in-qcom_nand-drive.patch b/target/linux/ipq806x/patches-4.9/860-qcom-mtd-nand-Add-bam_dma-support-in-qcom_nand-drive.patch
deleted file mode 100644
index 5a3c02c700..0000000000
--- a/target/linux/ipq806x/patches-4.9/860-qcom-mtd-nand-Add-bam_dma-support-in-qcom_nand-drive.patch
+++ /dev/null
@@ -1,370 +0,0 @@
-From 074036f9de6b8c5fc642e8e2540950f6a35aa804 Mon Sep 17 00:00:00 2001
-From: Ram Chandra Jangir <rjangir@codeaurora.org>
-Date: Thu, 20 Apr 2017 10:31:10 +0530
-Subject: [PATCH] qcom: mtd: nand: Add bam_dma support in qcom_nand driver
-
-The current driver only support ADM DMA so this patch adds the
-BAM DMA support in current NAND driver with compatible string
-qcom,ebi2-nandc-bam.
-Added bam channels and data buffers, NAND BAM uses 3 channels:
-command, data tx and data rx, while ADM uses only single channel.
-So this patch adds the BAM channel in device tree and using the
-same in NAND driver allocation function.
-
-Signed-off-by: Ram Chandra Jangir <rjangir@codeaurora.org>
----
- .../devicetree/bindings/mtd/qcom_nandc.txt | 69 +++++++--
- drivers/mtd/nand/qcom_nandc.c | 160 +++++++++++++++++----
- 2 files changed, 190 insertions(+), 39 deletions(-)
-
---- a/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
-+++ b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt
-@@ -1,21 +1,26 @@
- * Qualcomm NAND controller
-
- Required properties:
--- compatible: should be "qcom,ipq806x-nand"
-+- compatible: "qcom,ipq806x-nand" for IPQ8064 which uses
-+ ADM DMA.
-+ "qcom,ebi2-nand-bam" - nand drivers using BAM DMA
-+ like IPQ4019.
- - reg: MMIO address range
- - clocks: must contain core clock and always on clock
- - clock-names: must contain "core" for the core clock and "aon" for the
- always on clock
- - dmas: DMA specifier, consisting of a phandle to the ADM DMA
-- controller node and the channel number to be used for
-- NAND. Refer to dma.txt and qcom_adm.txt for more details
--- dma-names: must be "rxtx"
--- qcom,cmd-crci: must contain the ADM command type CRCI block instance
-- number specified for the NAND controller on the given
-- platform
--- qcom,data-crci: must contain the ADM data type CRCI block instance
-- number specified for the NAND controller on the given
-- platform
-+ or BAM DMA controller node and the channel number to
-+ be used for NAND. Refer to dma.txt, qcom_adm.txt(ADM)
-+ and qcom_bam_dma.txt(BAM) for more details
-+- dma-names: "rxtx" - ADM
-+ "tx", "rx", "cmd" - BAM
-+- qcom,cmd-crci: Only required for ADM DMA. must contain the ADM command
-+ type CRCI block instance number specified for the NAND
-+ controller on the given platform.
-+- qcom,data-crci: Only required for ADM DMA. must contain the ADM data
-+ type CRCI block instance number specified for the NAND
-+ controller on the given platform.
- - #address-cells: <1> - subnodes give the chip-select number
- - #size-cells: <0>
-
-@@ -44,7 +49,7 @@ partition.txt for more detail.
- Example:
-
- nand@1ac00000 {
-- compatible = "qcom,ebi2-nandc";
-+ compatible = "qcom,ipq806x-nand","qcom.qcom_nand";
- reg = <0x1ac00000 0x800>;
-
- clocks = <&gcc EBI2_CLK>,
-@@ -58,6 +63,48 @@ nand@1ac00000 {
-
- #address-cells = <1>;
- #size-cells = <0>;
-+
-+ nandcs@0 {
-+ compatible = "qcom,nandcs";
-+ reg = <0>;
-+
-+ nand-ecc-strength = <4>;
-+ nand-ecc-step-size = <512>;
-+ nand-bus-width = <8>;
-+
-+ partitions {
-+ compatible = "fixed-partitions";
-+ #address-cells = <1>;
-+ #size-cells = <1>;
-+
-+ partition@0 {
-+ label = "boot-nand";
-+ reg = <0 0x58a0000>;
-+ };
-+
-+ partition@58a0000 {
-+ label = "fs-nand";
-+ reg = <0x58a0000 0x4000000>;
-+ };
-+ };
-+ };
-+};
-+
-+nand@79B0000 {
-+ compatible = "qcom,ebi2-nandc-bam";
-+ reg = <0x79B0000 0x1000>;
-+
-+ clocks = <&gcc EBI2_CLK>,
-+ <&gcc EBI2_AON_CLK>;
-+ clock-names = "core", "aon";
-+
-+ dmas = <&qpicbam 0>,
-+ <&qpicbam 1>,
-+ <&qpicbam 2>;
-+ dma-names = "tx", "rx", "cmd";
-+
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-
- nandcs@0 {
- compatible = "qcom,nandcs";
---- a/drivers/mtd/nand/qcom_nandc.c
-+++ b/drivers/mtd/nand/qcom_nandc.c
-@@ -234,6 +234,7 @@ struct nandc_regs {
- * by upper layers directly
- * @buf_size/count/start: markers for chip->read_buf/write_buf functions
- * @reg_read_buf: local buffer for reading back registers via DMA
-+ * @reg_read_buf_phys: 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
-@@ -242,7 +243,10 @@ struct nandc_regs {
- * @cmd1/vld: some fixed controller register values
- * @ecc_modes: supported ECC modes by the current controller,
- * initialized via DT match data
-- */
-+ * @bch_enabled: flag to tell whether BCH or RS ECC mode is used
-+ * @dma_bam_enabled: flag to tell whether nand controller is using
-+ * bam dma
-+*/
- struct qcom_nand_controller {
- struct nand_hw_control controller;
- struct list_head host_list;
-@@ -255,17 +259,28 @@ struct qcom_nand_controller {
- struct clk *core_clk;
- struct clk *aon_clk;
-
-- struct dma_chan *chan;
-- unsigned int cmd_crci;
-- unsigned int data_crci;
- struct list_head desc_list;
-+ union {
-+ struct {
-+ struct dma_chan *tx_chan;
-+ struct dma_chan *rx_chan;
-+ struct dma_chan *cmd_chan;
-+ };
-+ struct {
-+ struct dma_chan *chan;
-+ unsigned int cmd_crci;
-+ unsigned int data_crci;
-+ };
-+ };
-
- u8 *data_buffer;
-+ bool dma_bam_enabled;
- int buf_size;
- int buf_count;
- int buf_start;
-
- __le32 *reg_read_buf;
-+ dma_addr_t reg_read_buf_phys;
- int reg_read_pos;
-
- struct nandc_regs *regs;
-@@ -324,6 +339,17 @@ struct qcom_nand_host {
- u32 clrreadstatus;
- };
-
-+/*
-+ * This data type corresponds to the nand driver data which will be used at
-+ * driver probe time
-+ * @ecc_modes - ecc mode for nand
-+ * @dma_bam_enabled - whether this driver is using bam
-+ */
-+struct qcom_nand_driver_data {
-+ u32 ecc_modes;
-+ bool dma_bam_enabled;
-+};
-+
- static inline struct qcom_nand_host *to_qcom_nand_host(struct nand_chip *chip)
- {
- return container_of(chip, struct qcom_nand_host, chip);
-@@ -1949,16 +1975,46 @@ static int qcom_nandc_alloc(struct qcom_
- if (!nandc->regs)
- return -ENOMEM;
-
-- nandc->reg_read_buf = devm_kzalloc(nandc->dev,
-- MAX_REG_RD * sizeof(*nandc->reg_read_buf),
-- GFP_KERNEL);
-- if (!nandc->reg_read_buf)
-- return -ENOMEM;
-+ if (!nandc->dma_bam_enabled) {
-+ nandc->reg_read_buf = devm_kzalloc(nandc->dev,
-+ MAX_REG_RD *
-+ sizeof(*nandc->reg_read_buf),
-+ GFP_KERNEL);
-
-- 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->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;
-+ }
-+ } else {
-+ nandc->reg_read_buf = dmam_alloc_coherent(nandc->dev,
-+ MAX_REG_RD *
-+ sizeof(*nandc->reg_read_buf),
-+ &nandc->reg_read_buf_phys, GFP_KERNEL);
-+
-+ if (!nandc->reg_read_buf)
-+ return -ENOMEM;
-+
-+ 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;
-+ }
- }
-
- INIT_LIST_HEAD(&nandc->desc_list);
-@@ -1971,8 +2027,35 @@ static int qcom_nandc_alloc(struct qcom_
-
- static void qcom_nandc_unalloc(struct qcom_nand_controller *nandc)
- {
-- dma_release_channel(nandc->chan);
--}
-+ if (nandc->dma_bam_enabled) {
-+ 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->tx_chan);
-+
-+ if (nandc->reg_read_buf)
-+ dmam_free_coherent(nandc->dev, MAX_REG_RD *
-+ sizeof(*nandc->reg_read_buf),
-+ nandc->reg_read_buf,
-+ nandc->reg_read_buf_phys);
-+ } else {
-+ if (nandc->chan)
-+ dma_release_channel(nandc->chan);
-+
-+ if (nandc->reg_read_buf)
-+ devm_kfree(nandc->dev, nandc->reg_read_buf);
-+ }
-+
-+ if (nandc->regs)
-+ devm_kfree(nandc->dev, nandc->regs);
-+
-+ if (nandc->data_buffer)
-+ devm_kfree(nandc->dev, nandc->data_buffer);
-+ }
-
- /* one time setup of a few nand controller registers */
- static int qcom_nandc_setup(struct qcom_nand_controller *nandc)
-@@ -2010,6 +2093,8 @@ static int qcom_nand_host_init(struct qc
- mtd->name = devm_kasprintf(dev, GFP_KERNEL, "qcom_nand.%d", host->cs);
- mtd->owner = THIS_MODULE;
- mtd->dev.parent = dev;
-+ mtd->priv = chip;
-+ chip->priv = nandc;
-
- chip->cmdfunc = qcom_nandc_command;
- chip->select_chip = qcom_nandc_select_chip;
-@@ -2057,16 +2142,20 @@ static int qcom_nandc_parse_dt(struct pl
- 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->dma_bam_enabled) {
-+ 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;
-@@ -2081,6 +2170,7 @@ static int qcom_nandc_probe(struct platf
- struct device_node *dn = dev->of_node, *child;
- struct resource *res;
- int ret;
-+ struct qcom_nand_driver_data *driver_data;
-
- nandc = devm_kzalloc(&pdev->dev, sizeof(*nandc), GFP_KERNEL);
- if (!nandc)
-@@ -2095,7 +2185,10 @@ static int qcom_nandc_probe(struct platf
- return -ENODEV;
- }
-
-- nandc->ecc_modes = (unsigned long)dev_data;
-+ driver_data = (struct qcom_nand_driver_data *)dev_data;
-+
-+ nandc->ecc_modes = driver_data->ecc_modes;
-+ nandc->dma_bam_enabled = driver_data->dma_bam_enabled;
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- nandc->base = devm_ioremap_resource(dev, res);
-@@ -2187,7 +2280,15 @@ static int qcom_nandc_remove(struct plat
- return 0;
- }
-
--#define EBI2_NANDC_ECC_MODES (ECC_RS_4BIT | ECC_BCH_8BIT)
-+struct qcom_nand_driver_data ebi2_nandc_bam_data = {
-+ .ecc_modes = (ECC_BCH_4BIT | ECC_BCH_8BIT),
-+ .dma_bam_enabled = true,
-+};
-+
-+struct qcom_nand_driver_data ebi2_nandc_data = {
-+ .ecc_modes = (ECC_RS_4BIT | ECC_BCH_8BIT),
-+ .dma_bam_enabled = false,
-+};
-
- /*
- * data will hold a struct pointer containing more differences once we support
-@@ -2195,7 +2296,10 @@ static int qcom_nandc_remove(struct plat
- */
- static const struct of_device_id qcom_nandc_of_match[] = {
- { .compatible = "qcom,ipq806x-nand",
-- .data = (void *)EBI2_NANDC_ECC_MODES,
-+ .data = (void *) &ebi2_nandc_data,
-+ },
-+ { .compatible = "qcom,ebi2-nandc-bam",
-+ .data = (void *) &ebi2_nandc_bam_data,
- },
- {}
- };