X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fopenwrt.git;a=blobdiff_plain;f=target%2Flinux%2Fipq806x%2Fpatches-4.9%2F860-qcom-mtd-nand-Add-bam_dma-support-in-qcom_nand-drive.patch;h=20940514eb4418df1c0b9677f4de2af13a003e01;hp=ad9d1bbf4c2e567212bbcd82119662f3bac44bc8;hb=55623a9c83c8c21b25f55e63ba0b5672f074f486;hpb=b9600b8542dffd05ae9a85b98693dbf85e7f6c42 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 index ad9d1bbf4c..20940514eb 100644 --- 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 @@ -17,13 +17,11 @@ Signed-off-by: Ram Chandra Jangir drivers/mtd/nand/qcom_nandc.c | 160 +++++++++++++++++---- 2 files changed, 190 insertions(+), 39 deletions(-) -diff --git a/Documentation/devicetree/bindings/mtd/qcom_nandc.txt b/Documentation/devicetree/bindings/mtd/qcom_nandc.txt -index 70dd511..9e5c9be 100644 --- 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 @@ -33,7 +31,7 @@ index 70dd511..9e5c9be 100644 - 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 + 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 @@ -57,36 +55,20 @@ index 70dd511..9e5c9be 100644 + 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>, -@@ -84,3 +89,45 @@ nand@1ac00000 { - }; - }; - }; -+ -+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>; + reg = <0x1ac00000 0x800>; + + clocks = <&gcc EBI2_CLK>, +@@ -58,6 +63,48 @@ nand@1ac00000 { + + #address-cells = <1>; + #size-cells = <0>; + + nandcs@0 { + compatible = "qcom,nandcs"; @@ -113,8 +95,25 @@ index 70dd511..9e5c9be 100644 + }; + }; +}; -diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c -index 57d483a..76a0ffc 100644 ++ ++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 @@ -226,6 +226,7 @@ struct nandc_regs { @@ -135,16 +134,16 @@ index 57d483a..76a0ffc 100644 + * bam dma +*/ struct qcom_nand_controller { - struct nand_hw_control controller; - struct list_head host_list; + struct nand_hw_control controller; + struct list_head host_list; @@ -247,17 +251,28 @@ struct qcom_nand_controller { - struct clk *core_clk; - struct clk *aon_clk; - + 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; + struct list_head desc_list; + union { + struct { + struct dma_chan *tx_chan; @@ -157,22 +156,22 @@ index 57d483a..76a0ffc 100644 + unsigned int data_crci; + }; + }; - - u8 *data_buffer; + + u8 *data_buffer; + bool dma_bam_enabled; - int buf_size; - int buf_count; - int buf_start; - - __le32 *reg_read_buf; + 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; + int reg_read_pos; + + struct nandc_regs *regs; @@ -316,6 +331,17 @@ struct qcom_nand_host { - u32 clrreadstatus; + u32 clrreadstatus; }; - + +/* + * This data type corresponds to the nand driver data which will be used at + * driver probe time @@ -186,20 +185,20 @@ index 57d483a..76a0ffc 100644 + static inline struct qcom_nand_host *to_qcom_nand_host(struct nand_chip *chip) { - return container_of(chip, struct qcom_nand_host, chip); -@@ -1893,7 +1919,7 @@ static int qcom_nand_host_setup(struct qcom_nand_host *host) - | wide_bus << WIDE_FLASH - | 1 << DEV0_CFG1_ECC_DISABLE; - + return container_of(chip, struct qcom_nand_host, chip); +@@ -1893,7 +1919,7 @@ static int qcom_nand_host_setup(struct q + | wide_bus << WIDE_FLASH + | 1 << DEV0_CFG1_ECC_DISABLE; + - host->ecc_bch_cfg = host->bch_enabled << ECC_CFG_ECC_DISABLE + host->ecc_bch_cfg = !host->bch_enabled << ECC_CFG_ECC_DISABLE - | 0 << ECC_SW_RESET - | host->cw_data << ECC_NUM_DATA_BYTES - | 1 << ECC_FORCE_CLK_OPEN -@@ -1942,16 +1968,46 @@ static int qcom_nandc_alloc(struct qcom_nand_controller *nandc) - if (!nandc->regs) - return -ENOMEM; - + | 0 << ECC_SW_RESET + | host->cw_data << ECC_NUM_DATA_BYTES + | 1 << ECC_FORCE_CLK_OPEN +@@ -1942,16 +1968,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); @@ -210,7 +209,7 @@ index 57d483a..76a0ffc 100644 + 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"); @@ -249,11 +248,11 @@ index 57d483a..76a0ffc 100644 + dev_err(nandc->dev, "failed to request cmd channel\n"); + return -ENODEV; + } - } - - INIT_LIST_HEAD(&nandc->desc_list); -@@ -1964,8 +2020,35 @@ static int qcom_nandc_alloc(struct qcom_nand_controller *nandc) - + } + + INIT_LIST_HEAD(&nandc->desc_list); +@@ -1964,8 +2020,35 @@ static int qcom_nandc_alloc(struct qcom_ + static void qcom_nandc_unalloc(struct qcom_nand_controller *nandc) { - dma_release_channel(nandc->chan); @@ -287,22 +286,22 @@ index 57d483a..76a0ffc 100644 + 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) -@@ -2002,6 +2085,8 @@ static int qcom_nand_host_init(struct qcom_nand_controller *nandc, - mtd->name = devm_kasprintf(dev, GFP_KERNEL, "qcom_nand.%d", host->cs); - mtd->owner = THIS_MODULE; - mtd->dev.parent = dev; +@@ -2002,6 +2085,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; -@@ -2049,16 +2134,20 @@ static int qcom_nandc_parse_dt(struct platform_device *pdev) - struct device_node *np = nandc->dev->of_node; - int ret; - + + chip->cmdfunc = qcom_nandc_command; + chip->select_chip = qcom_nandc_select_chip; +@@ -2049,16 +2134,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"); @@ -315,7 +314,7 @@ index 57d483a..76a0ffc 100644 + 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"); @@ -326,33 +325,33 @@ index 57d483a..76a0ffc 100644 + dev_err(nandc->dev, "data CRCI unspecified\n"); + return ret; + } - } - - return 0; -@@ -2073,6 +2162,7 @@ static int qcom_nandc_probe(struct platform_device *pdev) - struct device_node *dn = dev->of_node, *child; - struct resource *res; - int ret; + } + + return 0; +@@ -2073,6 +2162,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) -@@ -2087,7 +2177,10 @@ static int qcom_nandc_probe(struct platform_device *pdev) - return -ENODEV; - } - + + nandc = devm_kzalloc(&pdev->dev, sizeof(*nandc), GFP_KERNEL); + if (!nandc) +@@ -2087,7 +2177,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); -@@ -2179,7 +2272,15 @@ static int qcom_nandc_remove(struct platform_device *pdev) - return 0; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + nandc->base = devm_ioremap_resource(dev, res); +@@ -2179,7 +2272,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), @@ -363,20 +362,18 @@ index 57d483a..76a0ffc 100644 + .ecc_modes = (ECC_RS_4BIT | ECC_BCH_8BIT), + .dma_bam_enabled = false, +}; - + /* * data will hold a struct pointer containing more differences once we support -@@ -2187,7 +2288,10 @@ static int qcom_nandc_remove(struct platform_device *pdev) +@@ -2187,7 +2288,10 @@ static int qcom_nandc_remove(struct plat */ static const struct of_device_id qcom_nandc_of_match[] = { - { .compatible = "qcom,ipq806x-nand", + { .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, - }, - {} + }, + {} }; --- -2.7.2