Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * NAND Flash Controller Device Driver for DT
0004  *
0005  * Copyright © 2011, Picochip.
0006  */
0007 
0008 #include <linux/clk.h>
0009 #include <linux/delay.h>
0010 #include <linux/err.h>
0011 #include <linux/io.h>
0012 #include <linux/ioport.h>
0013 #include <linux/kernel.h>
0014 #include <linux/module.h>
0015 #include <linux/of.h>
0016 #include <linux/of_device.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/reset.h>
0019 
0020 #include "denali.h"
0021 
0022 struct denali_dt {
0023     struct denali_controller controller;
0024     struct clk *clk;    /* core clock */
0025     struct clk *clk_x;  /* bus interface clock */
0026     struct clk *clk_ecc;    /* ECC circuit clock */
0027     struct reset_control *rst;  /* core reset */
0028     struct reset_control *rst_reg;  /* register reset */
0029 };
0030 
0031 struct denali_dt_data {
0032     unsigned int revision;
0033     unsigned int caps;
0034     unsigned int oob_skip_bytes;
0035     const struct nand_ecc_caps *ecc_caps;
0036 };
0037 
0038 NAND_ECC_CAPS_SINGLE(denali_socfpga_ecc_caps, denali_calc_ecc_bytes,
0039              512, 8, 15);
0040 static const struct denali_dt_data denali_socfpga_data = {
0041     .caps = DENALI_CAP_HW_ECC_FIXUP,
0042     .oob_skip_bytes = 2,
0043     .ecc_caps = &denali_socfpga_ecc_caps,
0044 };
0045 
0046 NAND_ECC_CAPS_SINGLE(denali_uniphier_v5a_ecc_caps, denali_calc_ecc_bytes,
0047              1024, 8, 16, 24);
0048 static const struct denali_dt_data denali_uniphier_v5a_data = {
0049     .caps = DENALI_CAP_HW_ECC_FIXUP |
0050         DENALI_CAP_DMA_64BIT,
0051     .oob_skip_bytes = 8,
0052     .ecc_caps = &denali_uniphier_v5a_ecc_caps,
0053 };
0054 
0055 NAND_ECC_CAPS_SINGLE(denali_uniphier_v5b_ecc_caps, denali_calc_ecc_bytes,
0056              1024, 8, 16);
0057 static const struct denali_dt_data denali_uniphier_v5b_data = {
0058     .revision = 0x0501,
0059     .caps = DENALI_CAP_HW_ECC_FIXUP |
0060         DENALI_CAP_DMA_64BIT,
0061     .oob_skip_bytes = 8,
0062     .ecc_caps = &denali_uniphier_v5b_ecc_caps,
0063 };
0064 
0065 static const struct of_device_id denali_nand_dt_ids[] = {
0066     {
0067         .compatible = "altr,socfpga-denali-nand",
0068         .data = &denali_socfpga_data,
0069     },
0070     {
0071         .compatible = "socionext,uniphier-denali-nand-v5a",
0072         .data = &denali_uniphier_v5a_data,
0073     },
0074     {
0075         .compatible = "socionext,uniphier-denali-nand-v5b",
0076         .data = &denali_uniphier_v5b_data,
0077     },
0078     { /* sentinel */ }
0079 };
0080 MODULE_DEVICE_TABLE(of, denali_nand_dt_ids);
0081 
0082 static int denali_dt_chip_init(struct denali_controller *denali,
0083                    struct device_node *chip_np)
0084 {
0085     struct denali_chip *dchip;
0086     u32 bank;
0087     int nsels, i, ret;
0088 
0089     nsels = of_property_count_u32_elems(chip_np, "reg");
0090     if (nsels < 0)
0091         return nsels;
0092 
0093     dchip = devm_kzalloc(denali->dev, struct_size(dchip, sels, nsels),
0094                  GFP_KERNEL);
0095     if (!dchip)
0096         return -ENOMEM;
0097 
0098     dchip->nsels = nsels;
0099 
0100     for (i = 0; i < nsels; i++) {
0101         ret = of_property_read_u32_index(chip_np, "reg", i, &bank);
0102         if (ret)
0103             return ret;
0104 
0105         dchip->sels[i].bank = bank;
0106 
0107         nand_set_flash_node(&dchip->chip, chip_np);
0108     }
0109 
0110     return denali_chip_init(denali, dchip);
0111 }
0112 
0113 static int denali_dt_probe(struct platform_device *pdev)
0114 {
0115     struct device *dev = &pdev->dev;
0116     struct denali_dt *dt;
0117     const struct denali_dt_data *data;
0118     struct denali_controller *denali;
0119     struct device_node *np;
0120     int ret;
0121 
0122     dt = devm_kzalloc(dev, sizeof(*dt), GFP_KERNEL);
0123     if (!dt)
0124         return -ENOMEM;
0125     denali = &dt->controller;
0126 
0127     data = of_device_get_match_data(dev);
0128     if (WARN_ON(!data))
0129         return -EINVAL;
0130 
0131     denali->revision = data->revision;
0132     denali->caps = data->caps;
0133     denali->oob_skip_bytes = data->oob_skip_bytes;
0134     denali->ecc_caps = data->ecc_caps;
0135 
0136     denali->dev = dev;
0137     denali->irq = platform_get_irq(pdev, 0);
0138     if (denali->irq < 0)
0139         return denali->irq;
0140 
0141     denali->reg = devm_platform_ioremap_resource_byname(pdev, "denali_reg");
0142     if (IS_ERR(denali->reg))
0143         return PTR_ERR(denali->reg);
0144 
0145     denali->host = devm_platform_ioremap_resource_byname(pdev, "nand_data");
0146     if (IS_ERR(denali->host))
0147         return PTR_ERR(denali->host);
0148 
0149     dt->clk = devm_clk_get(dev, "nand");
0150     if (IS_ERR(dt->clk))
0151         return PTR_ERR(dt->clk);
0152 
0153     dt->clk_x = devm_clk_get(dev, "nand_x");
0154     if (IS_ERR(dt->clk_x))
0155         return PTR_ERR(dt->clk_x);
0156 
0157     dt->clk_ecc = devm_clk_get(dev, "ecc");
0158     if (IS_ERR(dt->clk_ecc))
0159         return PTR_ERR(dt->clk_ecc);
0160 
0161     dt->rst = devm_reset_control_get_optional_shared(dev, "nand");
0162     if (IS_ERR(dt->rst))
0163         return PTR_ERR(dt->rst);
0164 
0165     dt->rst_reg = devm_reset_control_get_optional_shared(dev, "reg");
0166     if (IS_ERR(dt->rst_reg))
0167         return PTR_ERR(dt->rst_reg);
0168 
0169     ret = clk_prepare_enable(dt->clk);
0170     if (ret)
0171         return ret;
0172 
0173     ret = clk_prepare_enable(dt->clk_x);
0174     if (ret)
0175         goto out_disable_clk;
0176 
0177     ret = clk_prepare_enable(dt->clk_ecc);
0178     if (ret)
0179         goto out_disable_clk_x;
0180 
0181     denali->clk_rate = clk_get_rate(dt->clk);
0182     denali->clk_x_rate = clk_get_rate(dt->clk_x);
0183 
0184     /*
0185      * Deassert the register reset, and the core reset in this order.
0186      * Deasserting the core reset while the register reset is asserted
0187      * will cause unpredictable behavior in the controller.
0188      */
0189     ret = reset_control_deassert(dt->rst_reg);
0190     if (ret)
0191         goto out_disable_clk_ecc;
0192 
0193     ret = reset_control_deassert(dt->rst);
0194     if (ret)
0195         goto out_assert_rst_reg;
0196 
0197     /*
0198      * When the reset is deasserted, the initialization sequence is kicked
0199      * (bootstrap process). The driver must wait until it finished.
0200      * Otherwise, it will result in unpredictable behavior.
0201      */
0202     usleep_range(200, 1000);
0203 
0204     ret = denali_init(denali);
0205     if (ret)
0206         goto out_assert_rst;
0207 
0208     for_each_child_of_node(dev->of_node, np) {
0209         ret = denali_dt_chip_init(denali, np);
0210         if (ret) {
0211             of_node_put(np);
0212             goto out_remove_denali;
0213         }
0214     }
0215 
0216     platform_set_drvdata(pdev, dt);
0217 
0218     return 0;
0219 
0220 out_remove_denali:
0221     denali_remove(denali);
0222 out_assert_rst:
0223     reset_control_assert(dt->rst);
0224 out_assert_rst_reg:
0225     reset_control_assert(dt->rst_reg);
0226 out_disable_clk_ecc:
0227     clk_disable_unprepare(dt->clk_ecc);
0228 out_disable_clk_x:
0229     clk_disable_unprepare(dt->clk_x);
0230 out_disable_clk:
0231     clk_disable_unprepare(dt->clk);
0232 
0233     return ret;
0234 }
0235 
0236 static int denali_dt_remove(struct platform_device *pdev)
0237 {
0238     struct denali_dt *dt = platform_get_drvdata(pdev);
0239 
0240     denali_remove(&dt->controller);
0241     reset_control_assert(dt->rst);
0242     reset_control_assert(dt->rst_reg);
0243     clk_disable_unprepare(dt->clk_ecc);
0244     clk_disable_unprepare(dt->clk_x);
0245     clk_disable_unprepare(dt->clk);
0246 
0247     return 0;
0248 }
0249 
0250 static struct platform_driver denali_dt_driver = {
0251     .probe      = denali_dt_probe,
0252     .remove     = denali_dt_remove,
0253     .driver     = {
0254         .name   = "denali-nand-dt",
0255         .of_match_table = denali_nand_dt_ids,
0256     },
0257 };
0258 module_platform_driver(denali_dt_driver);
0259 
0260 MODULE_LICENSE("GPL v2");
0261 MODULE_AUTHOR("Jamie Iles");
0262 MODULE_DESCRIPTION("DT driver for Denali NAND controller");