GNU Linux-libre 5.19-rc6-gnu
[releases.git] / drivers / mtd / nand / raw / denali_dt.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * NAND Flash Controller Device Driver for DT
4  *
5  * Copyright © 2011, Picochip.
6  */
7
8 #include <linux/clk.h>
9 #include <linux/delay.h>
10 #include <linux/err.h>
11 #include <linux/io.h>
12 #include <linux/ioport.h>
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/of.h>
16 #include <linux/of_device.h>
17 #include <linux/platform_device.h>
18 #include <linux/reset.h>
19
20 #include "denali.h"
21
22 struct denali_dt {
23         struct denali_controller controller;
24         struct clk *clk;        /* core clock */
25         struct clk *clk_x;      /* bus interface clock */
26         struct clk *clk_ecc;    /* ECC circuit clock */
27         struct reset_control *rst;      /* core reset */
28         struct reset_control *rst_reg;  /* register reset */
29 };
30
31 struct denali_dt_data {
32         unsigned int revision;
33         unsigned int caps;
34         unsigned int oob_skip_bytes;
35         const struct nand_ecc_caps *ecc_caps;
36 };
37
38 NAND_ECC_CAPS_SINGLE(denali_socfpga_ecc_caps, denali_calc_ecc_bytes,
39                      512, 8, 15);
40 static const struct denali_dt_data denali_socfpga_data = {
41         .caps = DENALI_CAP_HW_ECC_FIXUP,
42         .oob_skip_bytes = 2,
43         .ecc_caps = &denali_socfpga_ecc_caps,
44 };
45
46 NAND_ECC_CAPS_SINGLE(denali_uniphier_v5a_ecc_caps, denali_calc_ecc_bytes,
47                      1024, 8, 16, 24);
48 static const struct denali_dt_data denali_uniphier_v5a_data = {
49         .caps = DENALI_CAP_HW_ECC_FIXUP |
50                 DENALI_CAP_DMA_64BIT,
51         .oob_skip_bytes = 8,
52         .ecc_caps = &denali_uniphier_v5a_ecc_caps,
53 };
54
55 NAND_ECC_CAPS_SINGLE(denali_uniphier_v5b_ecc_caps, denali_calc_ecc_bytes,
56                      1024, 8, 16);
57 static const struct denali_dt_data denali_uniphier_v5b_data = {
58         .revision = 0x0501,
59         .caps = DENALI_CAP_HW_ECC_FIXUP |
60                 DENALI_CAP_DMA_64BIT,
61         .oob_skip_bytes = 8,
62         .ecc_caps = &denali_uniphier_v5b_ecc_caps,
63 };
64
65 static const struct of_device_id denali_nand_dt_ids[] = {
66         {
67                 .compatible = "altr,socfpga-denali-nand",
68                 .data = &denali_socfpga_data,
69         },
70         {
71                 .compatible = "socionext,uniphier-denali-nand-v5a",
72                 .data = &denali_uniphier_v5a_data,
73         },
74         {
75                 .compatible = "socionext,uniphier-denali-nand-v5b",
76                 .data = &denali_uniphier_v5b_data,
77         },
78         { /* sentinel */ }
79 };
80 MODULE_DEVICE_TABLE(of, denali_nand_dt_ids);
81
82 static int denali_dt_chip_init(struct denali_controller *denali,
83                                struct device_node *chip_np)
84 {
85         struct denali_chip *dchip;
86         u32 bank;
87         int nsels, i, ret;
88
89         nsels = of_property_count_u32_elems(chip_np, "reg");
90         if (nsels < 0)
91                 return nsels;
92
93         dchip = devm_kzalloc(denali->dev, struct_size(dchip, sels, nsels),
94                              GFP_KERNEL);
95         if (!dchip)
96                 return -ENOMEM;
97
98         dchip->nsels = nsels;
99
100         for (i = 0; i < nsels; i++) {
101                 ret = of_property_read_u32_index(chip_np, "reg", i, &bank);
102                 if (ret)
103                         return ret;
104
105                 dchip->sels[i].bank = bank;
106
107                 nand_set_flash_node(&dchip->chip, chip_np);
108         }
109
110         return denali_chip_init(denali, dchip);
111 }
112
113 static int denali_dt_probe(struct platform_device *pdev)
114 {
115         struct device *dev = &pdev->dev;
116         struct denali_dt *dt;
117         const struct denali_dt_data *data;
118         struct denali_controller *denali;
119         struct device_node *np;
120         int ret;
121
122         dt = devm_kzalloc(dev, sizeof(*dt), GFP_KERNEL);
123         if (!dt)
124                 return -ENOMEM;
125         denali = &dt->controller;
126
127         data = of_device_get_match_data(dev);
128         if (WARN_ON(!data))
129                 return -EINVAL;
130
131         denali->revision = data->revision;
132         denali->caps = data->caps;
133         denali->oob_skip_bytes = data->oob_skip_bytes;
134         denali->ecc_caps = data->ecc_caps;
135
136         denali->dev = dev;
137         denali->irq = platform_get_irq(pdev, 0);
138         if (denali->irq < 0)
139                 return denali->irq;
140
141         denali->reg = devm_platform_ioremap_resource_byname(pdev, "denali_reg");
142         if (IS_ERR(denali->reg))
143                 return PTR_ERR(denali->reg);
144
145         denali->host = devm_platform_ioremap_resource_byname(pdev, "nand_data");
146         if (IS_ERR(denali->host))
147                 return PTR_ERR(denali->host);
148
149         dt->clk = devm_clk_get(dev, "nand");
150         if (IS_ERR(dt->clk))
151                 return PTR_ERR(dt->clk);
152
153         dt->clk_x = devm_clk_get(dev, "nand_x");
154         if (IS_ERR(dt->clk_x))
155                 return PTR_ERR(dt->clk_x);
156
157         dt->clk_ecc = devm_clk_get(dev, "ecc");
158         if (IS_ERR(dt->clk_ecc))
159                 return PTR_ERR(dt->clk_ecc);
160
161         dt->rst = devm_reset_control_get_optional_shared(dev, "nand");
162         if (IS_ERR(dt->rst))
163                 return PTR_ERR(dt->rst);
164
165         dt->rst_reg = devm_reset_control_get_optional_shared(dev, "reg");
166         if (IS_ERR(dt->rst_reg))
167                 return PTR_ERR(dt->rst_reg);
168
169         ret = clk_prepare_enable(dt->clk);
170         if (ret)
171                 return ret;
172
173         ret = clk_prepare_enable(dt->clk_x);
174         if (ret)
175                 goto out_disable_clk;
176
177         ret = clk_prepare_enable(dt->clk_ecc);
178         if (ret)
179                 goto out_disable_clk_x;
180
181         denali->clk_rate = clk_get_rate(dt->clk);
182         denali->clk_x_rate = clk_get_rate(dt->clk_x);
183
184         /*
185          * Deassert the register reset, and the core reset in this order.
186          * Deasserting the core reset while the register reset is asserted
187          * will cause unpredictable behavior in the controller.
188          */
189         ret = reset_control_deassert(dt->rst_reg);
190         if (ret)
191                 goto out_disable_clk_ecc;
192
193         ret = reset_control_deassert(dt->rst);
194         if (ret)
195                 goto out_assert_rst_reg;
196
197         /*
198          * When the reset is deasserted, the initialization sequence is kicked
199          * (bootstrap process). The driver must wait until it finished.
200          * Otherwise, it will result in unpredictable behavior.
201          */
202         usleep_range(200, 1000);
203
204         ret = denali_init(denali);
205         if (ret)
206                 goto out_assert_rst;
207
208         for_each_child_of_node(dev->of_node, np) {
209                 ret = denali_dt_chip_init(denali, np);
210                 if (ret) {
211                         of_node_put(np);
212                         goto out_remove_denali;
213                 }
214         }
215
216         platform_set_drvdata(pdev, dt);
217
218         return 0;
219
220 out_remove_denali:
221         denali_remove(denali);
222 out_assert_rst:
223         reset_control_assert(dt->rst);
224 out_assert_rst_reg:
225         reset_control_assert(dt->rst_reg);
226 out_disable_clk_ecc:
227         clk_disable_unprepare(dt->clk_ecc);
228 out_disable_clk_x:
229         clk_disable_unprepare(dt->clk_x);
230 out_disable_clk:
231         clk_disable_unprepare(dt->clk);
232
233         return ret;
234 }
235
236 static int denali_dt_remove(struct platform_device *pdev)
237 {
238         struct denali_dt *dt = platform_get_drvdata(pdev);
239
240         denali_remove(&dt->controller);
241         reset_control_assert(dt->rst);
242         reset_control_assert(dt->rst_reg);
243         clk_disable_unprepare(dt->clk_ecc);
244         clk_disable_unprepare(dt->clk_x);
245         clk_disable_unprepare(dt->clk);
246
247         return 0;
248 }
249
250 static struct platform_driver denali_dt_driver = {
251         .probe          = denali_dt_probe,
252         .remove         = denali_dt_remove,
253         .driver         = {
254                 .name   = "denali-nand-dt",
255                 .of_match_table = denali_nand_dt_ids,
256         },
257 };
258 module_platform_driver(denali_dt_driver);
259
260 MODULE_LICENSE("GPL v2");
261 MODULE_AUTHOR("Jamie Iles");
262 MODULE_DESCRIPTION("DT driver for Denali NAND controller");