layerscape: add linux 4.9 support
[oweals/openwrt.git] / target / linux / layerscape / patches-4.9 / 402-mtd-support-layerscape.patch
1 From c0e4767d3b26f21e5043fe2d15a24a1958de766e Mon Sep 17 00:00:00 2001
2 From: Yangbo Lu <yangbo.lu@nxp.com>
3 Date: Mon, 25 Sep 2017 10:17:28 +0800
4 Subject: [PATCH] mtd: support layerscape
5
6 This is a integrated patch for layerscape ifc-nor-nand support.
7
8 Signed-off-by: Alison Wang <b18965@freescale.com>
9 Signed-off-by: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>
10 Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
11 ---
12  drivers/memory/Kconfig          |   2 +-
13  drivers/memory/fsl_ifc.c        | 263 ++++++++++++++++++++++++++++++++++++++++
14  drivers/mtd/maps/physmap_of.c   |   4 +
15  drivers/mtd/nand/Kconfig        |   2 +-
16  drivers/mtd/nand/fsl_ifc_nand.c |   5 +-
17  include/linux/fsl_ifc.h         |   7 ++
18  6 files changed, 280 insertions(+), 3 deletions(-)
19
20 diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
21 index 4b4c0c3c..820f5590 100644
22 --- a/drivers/memory/Kconfig
23 +++ b/drivers/memory/Kconfig
24 @@ -115,7 +115,7 @@ config FSL_CORENET_CF
25  
26  config FSL_IFC
27         bool
28 -       depends on FSL_SOC || ARCH_LAYERSCAPE
29 +       depends on FSL_SOC || ARCH_LAYERSCAPE || SOC_LS1021A
30  
31  config JZ4780_NEMC
32         bool "Ingenic JZ4780 SoC NEMC driver"
33 diff --git a/drivers/memory/fsl_ifc.c b/drivers/memory/fsl_ifc.c
34 index 1b182b11..10d2a5f8 100644
35 --- a/drivers/memory/fsl_ifc.c
36 +++ b/drivers/memory/fsl_ifc.c
37 @@ -24,6 +24,7 @@
38  #include <linux/compiler.h>
39  #include <linux/sched.h>
40  #include <linux/spinlock.h>
41 +#include <linux/delay.h>
42  #include <linux/types.h>
43  #include <linux/slab.h>
44  #include <linux/io.h>
45 @@ -37,6 +38,8 @@
46  
47  struct fsl_ifc_ctrl *fsl_ifc_ctrl_dev;
48  EXPORT_SYMBOL(fsl_ifc_ctrl_dev);
49 +#define FSL_IFC_V1_3_0 0x01030000
50 +#define IFC_TIMEOUT_MSECS      1000 /* 1000ms */
51  
52  /*
53   * convert_ifc_address - convert the base address
54 @@ -311,6 +314,261 @@ static int fsl_ifc_ctrl_probe(struct platform_device *dev)
55         return ret;
56  }
57  
58 +#ifdef CONFIG_PM_SLEEP
59 +/* save ifc registers */
60 +static int fsl_ifc_suspend(struct device *dev)
61 +{
62 +       struct fsl_ifc_ctrl *ctrl = dev_get_drvdata(dev);
63 +       struct fsl_ifc_global __iomem *fcm = ctrl->gregs;
64 +       struct fsl_ifc_runtime __iomem *runtime = ctrl->rregs;
65 +       __be32 nand_evter_intr_en, cm_evter_intr_en, nor_evter_intr_en,
66 +                                                        gpcm_evter_intr_en;
67 +       uint32_t ifc_bank, i;
68 +
69 +       ctrl->saved_gregs = kzalloc(sizeof(struct fsl_ifc_global), GFP_KERNEL);
70 +       if (!ctrl->saved_gregs)
71 +               return -ENOMEM;
72 +       ctrl->saved_rregs = kzalloc(sizeof(struct fsl_ifc_runtime), GFP_KERNEL);
73 +       if (!ctrl->saved_rregs)
74 +               return -ENOMEM;
75 +
76 +       cm_evter_intr_en = ifc_in32(&fcm->cm_evter_intr_en);
77 +       nand_evter_intr_en = ifc_in32(&runtime->ifc_nand.nand_evter_intr_en);
78 +       nor_evter_intr_en = ifc_in32(&runtime->ifc_nor.nor_evter_intr_en);
79 +       gpcm_evter_intr_en = ifc_in32(&runtime->ifc_gpcm.gpcm_evter_intr_en);
80 +
81 +/* IFC interrupts disabled */
82 +
83 +       ifc_out32(0x0, &fcm->cm_evter_intr_en);
84 +       ifc_out32(0x0, &runtime->ifc_nand.nand_evter_intr_en);
85 +       ifc_out32(0x0, &runtime->ifc_nor.nor_evter_intr_en);
86 +       ifc_out32(0x0, &runtime->ifc_gpcm.gpcm_evter_intr_en);
87 +
88 +       if (ctrl->saved_gregs) {
89 +               for (ifc_bank = 0; ifc_bank < FSL_IFC_BANK_COUNT; ifc_bank++) {
90 +                       ctrl->saved_gregs->cspr_cs[ifc_bank].cspr_ext =
91 +                               ifc_in32(&fcm->cspr_cs[ifc_bank].cspr_ext);
92 +                       ctrl->saved_gregs->cspr_cs[ifc_bank].cspr =
93 +                               ifc_in32(&fcm->cspr_cs[ifc_bank].cspr);
94 +                       ctrl->saved_gregs->amask_cs[ifc_bank].amask =
95 +                               ifc_in32(&fcm->amask_cs[ifc_bank].amask);
96 +                       ctrl->saved_gregs->csor_cs[ifc_bank].csor_ext =
97 +                               ifc_in32(&fcm->csor_cs[ifc_bank].csor_ext);
98 +                       ctrl->saved_gregs->csor_cs[ifc_bank].csor =
99 +                               ifc_in32(&fcm->csor_cs[ifc_bank].csor);
100 +                       for (i = 0; i < 4; i++) {
101 +                               ctrl->saved_gregs->ftim_cs[ifc_bank].ftim[i] =
102 +                                       ifc_in32(
103 +                                       &fcm->ftim_cs[ifc_bank].ftim[i]);
104 +                       }
105 +               }
106 +
107 +               ctrl->saved_gregs->rb_map = ifc_in32(&fcm->rb_map);
108 +               ctrl->saved_gregs->wb_map = ifc_in32(&fcm->wb_map);
109 +               ctrl->saved_gregs->ifc_gcr = ifc_in32(&fcm->ifc_gcr);
110 +               ctrl->saved_gregs->ddr_ccr_low = ifc_in32(&fcm->ddr_ccr_low);
111 +               ctrl->saved_gregs->cm_evter_en = ifc_in32(&fcm->cm_evter_en);
112 +       }
113 +
114 +       if (ctrl->saved_rregs) {
115 +               /* IFC controller NAND machine registers */
116 +               ctrl->saved_rregs->ifc_nand.ncfgr =
117 +                                       ifc_in32(&runtime->ifc_nand.ncfgr);
118 +               ctrl->saved_rregs->ifc_nand.nand_fcr0 =
119 +                                       ifc_in32(&runtime->ifc_nand.nand_fcr0);
120 +               ctrl->saved_rregs->ifc_nand.nand_fcr1 =
121 +                                       ifc_in32(&runtime->ifc_nand.nand_fcr1);
122 +               ctrl->saved_rregs->ifc_nand.row0 =
123 +                                       ifc_in32(&runtime->ifc_nand.row0);
124 +               ctrl->saved_rregs->ifc_nand.row1 =
125 +                                       ifc_in32(&runtime->ifc_nand.row1);
126 +               ctrl->saved_rregs->ifc_nand.col0 =
127 +                                       ifc_in32(&runtime->ifc_nand.col0);
128 +               ctrl->saved_rregs->ifc_nand.col1 =
129 +                                       ifc_in32(&runtime->ifc_nand.col1);
130 +               ctrl->saved_rregs->ifc_nand.row2 =
131 +                                       ifc_in32(&runtime->ifc_nand.row2);
132 +               ctrl->saved_rregs->ifc_nand.col2 =
133 +                                       ifc_in32(&runtime->ifc_nand.col2);
134 +               ctrl->saved_rregs->ifc_nand.row3 =
135 +                                       ifc_in32(&runtime->ifc_nand.row3);
136 +               ctrl->saved_rregs->ifc_nand.col3 =
137 +                                       ifc_in32(&runtime->ifc_nand.col3);
138 +
139 +               ctrl->saved_rregs->ifc_nand.nand_fbcr =
140 +                                       ifc_in32(&runtime->ifc_nand.nand_fbcr);
141 +               ctrl->saved_rregs->ifc_nand.nand_fir0 =
142 +                                       ifc_in32(&runtime->ifc_nand.nand_fir0);
143 +               ctrl->saved_rregs->ifc_nand.nand_fir1 =
144 +                                       ifc_in32(&runtime->ifc_nand.nand_fir1);
145 +               ctrl->saved_rregs->ifc_nand.nand_fir2 =
146 +                                       ifc_in32(&runtime->ifc_nand.nand_fir2);
147 +               ctrl->saved_rregs->ifc_nand.nand_csel =
148 +                                       ifc_in32(&runtime->ifc_nand.nand_csel);
149 +               ctrl->saved_rregs->ifc_nand.nandseq_strt =
150 +                                       ifc_in32(
151 +                                       &runtime->ifc_nand.nandseq_strt);
152 +               ctrl->saved_rregs->ifc_nand.nand_evter_en =
153 +                                       ifc_in32(
154 +                                       &runtime->ifc_nand.nand_evter_en);
155 +               ctrl->saved_rregs->ifc_nand.nanndcr =
156 +                                       ifc_in32(&runtime->ifc_nand.nanndcr);
157 +               ctrl->saved_rregs->ifc_nand.nand_dll_lowcfg0 =
158 +                                       ifc_in32(
159 +                                       &runtime->ifc_nand.nand_dll_lowcfg0);
160 +               ctrl->saved_rregs->ifc_nand.nand_dll_lowcfg1 =
161 +                                       ifc_in32(
162 +                                       &runtime->ifc_nand.nand_dll_lowcfg1);
163 +
164 +               /* IFC controller NOR machine registers */
165 +               ctrl->saved_rregs->ifc_nor.nor_evter_en =
166 +                                       ifc_in32(
167 +                                       &runtime->ifc_nor.nor_evter_en);
168 +               ctrl->saved_rregs->ifc_nor.norcr =
169 +                                       ifc_in32(&runtime->ifc_nor.norcr);
170 +
171 +               /* IFC controller GPCM Machine registers */
172 +               ctrl->saved_rregs->ifc_gpcm.gpcm_evter_en =
173 +                                       ifc_in32(
174 +                                       &runtime->ifc_gpcm.gpcm_evter_en);
175 +       }
176 +
177 +/* save the interrupt values */
178 +       ctrl->saved_gregs->cm_evter_intr_en = cm_evter_intr_en;
179 +       ctrl->saved_rregs->ifc_nand.nand_evter_intr_en = nand_evter_intr_en;
180 +       ctrl->saved_rregs->ifc_nor.nor_evter_intr_en = nor_evter_intr_en;
181 +       ctrl->saved_rregs->ifc_gpcm.gpcm_evter_intr_en = gpcm_evter_intr_en;
182 +
183 +       return 0;
184 +}
185 +
186 +/* restore ifc registers */
187 +static int fsl_ifc_resume(struct device *dev)
188 +{
189 +       struct fsl_ifc_ctrl *ctrl = dev_get_drvdata(dev);
190 +       struct fsl_ifc_global __iomem *fcm = ctrl->gregs;
191 +       struct fsl_ifc_runtime __iomem *runtime = ctrl->rregs;
192 +       struct fsl_ifc_global *savd_gregs = ctrl->saved_gregs;
193 +       struct fsl_ifc_runtime *savd_rregs = ctrl->saved_rregs;
194 +       uint32_t ver = 0, ncfgr, timeout, ifc_bank, i;
195 +
196 +/*
197 + * IFC interrupts disabled
198 + */
199 +       ifc_out32(0x0, &fcm->cm_evter_intr_en);
200 +       ifc_out32(0x0, &runtime->ifc_nand.nand_evter_intr_en);
201 +       ifc_out32(0x0, &runtime->ifc_nor.nor_evter_intr_en);
202 +       ifc_out32(0x0, &runtime->ifc_gpcm.gpcm_evter_intr_en);
203 +
204 +
205 +       if (ctrl->saved_gregs) {
206 +               for (ifc_bank = 0; ifc_bank < FSL_IFC_BANK_COUNT; ifc_bank++) {
207 +                       ifc_out32(savd_gregs->cspr_cs[ifc_bank].cspr_ext,
208 +                                       &fcm->cspr_cs[ifc_bank].cspr_ext);
209 +                       ifc_out32(savd_gregs->cspr_cs[ifc_bank].cspr,
210 +                                       &fcm->cspr_cs[ifc_bank].cspr);
211 +                       ifc_out32(savd_gregs->amask_cs[ifc_bank].amask,
212 +                                       &fcm->amask_cs[ifc_bank].amask);
213 +                       ifc_out32(savd_gregs->csor_cs[ifc_bank].csor_ext,
214 +                                       &fcm->csor_cs[ifc_bank].csor_ext);
215 +                       ifc_out32(savd_gregs->csor_cs[ifc_bank].csor,
216 +                                       &fcm->csor_cs[ifc_bank].csor);
217 +                       for (i = 0; i < 4; i++) {
218 +                               ifc_out32(savd_gregs->ftim_cs[ifc_bank].ftim[i],
219 +                                       &fcm->ftim_cs[ifc_bank].ftim[i]);
220 +                       }
221 +               }
222 +               ifc_out32(savd_gregs->rb_map, &fcm->rb_map);
223 +               ifc_out32(savd_gregs->wb_map, &fcm->wb_map);
224 +               ifc_out32(savd_gregs->ifc_gcr, &fcm->ifc_gcr);
225 +               ifc_out32(savd_gregs->ddr_ccr_low, &fcm->ddr_ccr_low);
226 +               ifc_out32(savd_gregs->cm_evter_en, &fcm->cm_evter_en);
227 +       }
228 +
229 +       if (ctrl->saved_rregs) {
230 +               /* IFC controller NAND machine registers */
231 +               ifc_out32(savd_rregs->ifc_nand.ncfgr,
232 +                                               &runtime->ifc_nand.ncfgr);
233 +               ifc_out32(savd_rregs->ifc_nand.nand_fcr0,
234 +                                               &runtime->ifc_nand.nand_fcr0);
235 +               ifc_out32(savd_rregs->ifc_nand.nand_fcr1,
236 +                                               &runtime->ifc_nand.nand_fcr1);
237 +               ifc_out32(savd_rregs->ifc_nand.row0, &runtime->ifc_nand.row0);
238 +               ifc_out32(savd_rregs->ifc_nand.row1, &runtime->ifc_nand.row1);
239 +               ifc_out32(savd_rregs->ifc_nand.col0, &runtime->ifc_nand.col0);
240 +               ifc_out32(savd_rregs->ifc_nand.col1, &runtime->ifc_nand.col1);
241 +               ifc_out32(savd_rregs->ifc_nand.row2, &runtime->ifc_nand.row2);
242 +               ifc_out32(savd_rregs->ifc_nand.col2, &runtime->ifc_nand.col2);
243 +               ifc_out32(savd_rregs->ifc_nand.row3, &runtime->ifc_nand.row3);
244 +               ifc_out32(savd_rregs->ifc_nand.col3, &runtime->ifc_nand.col3);
245 +               ifc_out32(savd_rregs->ifc_nand.nand_fbcr,
246 +                                               &runtime->ifc_nand.nand_fbcr);
247 +               ifc_out32(savd_rregs->ifc_nand.nand_fir0,
248 +                                               &runtime->ifc_nand.nand_fir0);
249 +               ifc_out32(savd_rregs->ifc_nand.nand_fir1,
250 +                                               &runtime->ifc_nand.nand_fir1);
251 +               ifc_out32(savd_rregs->ifc_nand.nand_fir2,
252 +                                               &runtime->ifc_nand.nand_fir2);
253 +               ifc_out32(savd_rregs->ifc_nand.nand_csel,
254 +                                               &runtime->ifc_nand.nand_csel);
255 +               ifc_out32(savd_rregs->ifc_nand.nandseq_strt,
256 +                                       &runtime->ifc_nand.nandseq_strt);
257 +               ifc_out32(savd_rregs->ifc_nand.nand_evter_en,
258 +                                       &runtime->ifc_nand.nand_evter_en);
259 +               ifc_out32(savd_rregs->ifc_nand.nanndcr,
260 +                                       &runtime->ifc_nand.nanndcr);
261 +               ifc_out32(savd_rregs->ifc_nand.nand_dll_lowcfg0,
262 +                                       &runtime->ifc_nand.nand_dll_lowcfg0);
263 +               ifc_out32(savd_rregs->ifc_nand.nand_dll_lowcfg1,
264 +                                       &runtime->ifc_nand.nand_dll_lowcfg1);
265 +
266 +               /* IFC controller NOR machine registers */
267 +               ifc_out32(savd_rregs->ifc_nor.nor_evter_en,
268 +                                       &runtime->ifc_nor.nor_evter_en);
269 +               ifc_out32(savd_rregs->ifc_nor.norcr, &runtime->ifc_nor.norcr);
270 +
271 +               /* IFC controller GPCM Machine registers */
272 +               ifc_out32(savd_rregs->ifc_gpcm.gpcm_evter_en,
273 +                                       &runtime->ifc_gpcm.gpcm_evter_en);
274 +
275 +               /* IFC interrupts enabled */
276 +               ifc_out32(ctrl->saved_gregs->cm_evter_intr_en,
277 +                                       &fcm->cm_evter_intr_en);
278 +               ifc_out32(ctrl->saved_rregs->ifc_nand.nand_evter_intr_en,
279 +                                       &runtime->ifc_nand.nand_evter_intr_en);
280 +               ifc_out32(ctrl->saved_rregs->ifc_nor.nor_evter_intr_en,
281 +                                       &runtime->ifc_nor.nor_evter_intr_en);
282 +               ifc_out32(ctrl->saved_rregs->ifc_gpcm.gpcm_evter_intr_en,
283 +                                       &runtime->ifc_gpcm.gpcm_evter_intr_en);
284 +
285 +               kfree(ctrl->saved_gregs);
286 +               kfree(ctrl->saved_rregs);
287 +               ctrl->saved_gregs = NULL;
288 +               ctrl->saved_rregs = NULL;
289 +       }
290 +
291 +       ver = ifc_in32(&fcm->ifc_rev);
292 +       ncfgr = ifc_in32(&runtime->ifc_nand.ncfgr);
293 +       if (ver >= FSL_IFC_V1_3_0) {
294 +
295 +               ifc_out32(ncfgr | IFC_NAND_SRAM_INIT_EN,
296 +                                       &runtime->ifc_nand.ncfgr);
297 +               /* wait for  SRAM_INIT bit to be clear or timeout */
298 +               timeout = 10;
299 +               while ((ifc_in32(&runtime->ifc_nand.ncfgr) &
300 +                       IFC_NAND_SRAM_INIT_EN) && timeout) {
301 +                       mdelay(IFC_TIMEOUT_MSECS);
302 +                       timeout--;
303 +               }
304 +
305 +               if (!timeout)
306 +                       dev_err(ctrl->dev, "Timeout waiting for IFC SRAM INIT");
307 +       }
308 +
309 +       return 0;
310 +}
311 +#endif /* CONFIG_PM_SLEEP */
312 +
313  static const struct of_device_id fsl_ifc_match[] = {
314         {
315                 .compatible = "fsl,ifc",
316 @@ -318,10 +576,15 @@ static const struct of_device_id fsl_ifc_match[] = {
317         {},
318  };
319  
320 +static const struct dev_pm_ops ifc_pm_ops = {
321 +       SET_SYSTEM_SLEEP_PM_OPS(fsl_ifc_suspend, fsl_ifc_resume)
322 +};
323 +
324  static struct platform_driver fsl_ifc_ctrl_driver = {
325         .driver = {
326                 .name   = "fsl-ifc",
327                 .of_match_table = fsl_ifc_match,
328 +               .pm = &ifc_pm_ops,
329         },
330         .probe       = fsl_ifc_ctrl_probe,
331         .remove      = fsl_ifc_ctrl_remove,
332 diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c
333 index 11d63046..38b90301 100644
334 --- a/drivers/mtd/maps/physmap_of.c
335 +++ b/drivers/mtd/maps/physmap_of.c
336 @@ -20,6 +20,7 @@
337  #include <linux/mtd/map.h>
338  #include <linux/mtd/partitions.h>
339  #include <linux/mtd/concat.h>
340 +#include <linux/mtd/cfi_endian.h>
341  #include <linux/of.h>
342  #include <linux/of_address.h>
343  #include <linux/of_platform.h>
344 @@ -209,6 +210,9 @@ static int of_flash_probe(struct platform_device *dev)
345                         return err;
346                 }
347  
348 +               if (of_property_read_bool(dp->parent, "big-endian"))
349 +                       info->list[i].map.swap = CFI_BIG_ENDIAN;
350 +
351                 err = -ENOMEM;
352                 info->list[i].map.virt = ioremap(info->list[i].map.phys,
353                                                  info->list[i].map.size);
354 diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
355 index b254090b..961f1aa1 100644
356 --- a/drivers/mtd/nand/Kconfig
357 +++ b/drivers/mtd/nand/Kconfig
358 @@ -438,7 +438,7 @@ config MTD_NAND_FSL_ELBC
359  
360  config MTD_NAND_FSL_IFC
361         tristate "NAND support for Freescale IFC controller"
362 -       depends on FSL_SOC || ARCH_LAYERSCAPE
363 +       depends on FSL_SOC || ARCH_LAYERSCAPE || SOC_LS1021A
364         select FSL_IFC
365         select MEMORY
366         help
367 diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
368 index d1570f51..785e9ee0 100644
369 --- a/drivers/mtd/nand/fsl_ifc_nand.c
370 +++ b/drivers/mtd/nand/fsl_ifc_nand.c
371 @@ -904,9 +904,12 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv)
372                 chip->ecc.algo = NAND_ECC_HAMMING;
373         }
374  
375 -       if (ctrl->version == FSL_IFC_VERSION_1_1_0)
376 +       if (ctrl->version >= FSL_IFC_VERSION_1_1_0)
377                 fsl_ifc_sram_init(priv);
378  
379 +       if (ctrl->version >= FSL_IFC_VERSION_2_0_0)
380 +               priv->bufnum_mask = (priv->bufnum_mask * 2) + 1;
381 +
382         return 0;
383  }
384  
385 diff --git a/include/linux/fsl_ifc.h b/include/linux/fsl_ifc.h
386 index c332f0a4..a41d21b6 100644
387 --- a/include/linux/fsl_ifc.h
388 +++ b/include/linux/fsl_ifc.h
389 @@ -274,6 +274,8 @@
390   */
391  /* Auto Boot Mode */
392  #define IFC_NAND_NCFGR_BOOT            0x80000000
393 +/* SRAM INIT EN */
394 +#define IFC_NAND_SRAM_INIT_EN          0x20000000
395  /* Addressing Mode-ROW0+n/COL0 */
396  #define IFC_NAND_NCFGR_ADDR_MODE_RC0   0x00000000
397  /* Addressing Mode-ROW0+n/COL0+n */
398 @@ -861,6 +863,11 @@ struct fsl_ifc_ctrl {
399         u32 nand_stat;
400         wait_queue_head_t nand_wait;
401         bool little_endian;
402 +#ifdef CONFIG_PM_SLEEP
403 +       /*save regs when system goes to deep sleep*/
404 +       struct fsl_ifc_global           *saved_gregs;
405 +       struct fsl_ifc_runtime          *saved_rregs;
406 +#endif
407  };
408  
409  extern struct fsl_ifc_ctrl *fsl_ifc_ctrl_dev;
410 -- 
411 2.14.1
412