OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | From 780865643e5dbf41fe950924a68f7ee4fea8af3e Mon Sep 17 00:00:00 2001 |
2 | From: Biwen Li <biwen.li@nxp.com> |
||
3 | Date: Tue, 30 Oct 2018 18:26:39 +0800 |
||
4 | Subject: [PATCH 30/40] ifc-nor-nand: support layerscape |
||
5 | This is an integrated patch of ifc-nor-nand for |
||
6 | layerscape |
||
7 | |||
8 | Signed-off-by: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com> |
||
9 | Signed-off-by: Raghav Dogra <raghav.dogra@nxp.com> |
||
10 | Signed-off-by: Biwen Li <biwen.li@nxp.com> |
||
11 | --- |
||
12 | drivers/memory/fsl_ifc.c | 263 +++++++++++++++++++++++++++++ |
||
13 | drivers/mtd/maps/physmap_of_core.c | 4 + |
||
14 | include/linux/fsl_ifc.h | 7 + |
||
15 | 3 files changed, 274 insertions(+) |
||
16 | |||
17 | --- a/drivers/memory/fsl_ifc.c |
||
18 | +++ b/drivers/memory/fsl_ifc.c |
||
19 | @@ -24,6 +24,7 @@ |
||
20 | #include <linux/compiler.h> |
||
21 | #include <linux/sched.h> |
||
22 | #include <linux/spinlock.h> |
||
23 | +#include <linux/delay.h> |
||
24 | #include <linux/types.h> |
||
25 | #include <linux/slab.h> |
||
26 | #include <linux/io.h> |
||
27 | @@ -37,6 +38,8 @@ |
||
28 | |||
29 | struct fsl_ifc_ctrl *fsl_ifc_ctrl_dev; |
||
30 | EXPORT_SYMBOL(fsl_ifc_ctrl_dev); |
||
31 | +#define FSL_IFC_V1_3_0 0x01030000 |
||
32 | +#define IFC_TIMEOUT_MSECS 1000 /* 1000ms */ |
||
33 | |||
34 | /* |
||
35 | * convert_ifc_address - convert the base address |
||
36 | @@ -311,6 +314,261 @@ err: |
||
37 | return ret; |
||
38 | } |
||
39 | |||
40 | +#ifdef CONFIG_PM_SLEEP |
||
41 | +/* save ifc registers */ |
||
42 | +static int fsl_ifc_suspend(struct device *dev) |
||
43 | +{ |
||
44 | + struct fsl_ifc_ctrl *ctrl = dev_get_drvdata(dev); |
||
45 | + struct fsl_ifc_global __iomem *fcm = ctrl->gregs; |
||
46 | + struct fsl_ifc_runtime __iomem *runtime = ctrl->rregs; |
||
47 | + __be32 nand_evter_intr_en, cm_evter_intr_en, nor_evter_intr_en, |
||
48 | + gpcm_evter_intr_en; |
||
49 | + uint32_t ifc_bank, i; |
||
50 | + |
||
51 | + ctrl->saved_gregs = kzalloc(sizeof(struct fsl_ifc_global), GFP_KERNEL); |
||
52 | + if (!ctrl->saved_gregs) |
||
53 | + return -ENOMEM; |
||
54 | + ctrl->saved_rregs = kzalloc(sizeof(struct fsl_ifc_runtime), GFP_KERNEL); |
||
55 | + if (!ctrl->saved_rregs) |
||
56 | + return -ENOMEM; |
||
57 | + |
||
58 | + cm_evter_intr_en = ifc_in32(&fcm->cm_evter_intr_en); |
||
59 | + nand_evter_intr_en = ifc_in32(&runtime->ifc_nand.nand_evter_intr_en); |
||
60 | + nor_evter_intr_en = ifc_in32(&runtime->ifc_nor.nor_evter_intr_en); |
||
61 | + gpcm_evter_intr_en = ifc_in32(&runtime->ifc_gpcm.gpcm_evter_intr_en); |
||
62 | + |
||
63 | +/* IFC interrupts disabled */ |
||
64 | + |
||
65 | + ifc_out32(0x0, &fcm->cm_evter_intr_en); |
||
66 | + ifc_out32(0x0, &runtime->ifc_nand.nand_evter_intr_en); |
||
67 | + ifc_out32(0x0, &runtime->ifc_nor.nor_evter_intr_en); |
||
68 | + ifc_out32(0x0, &runtime->ifc_gpcm.gpcm_evter_intr_en); |
||
69 | + |
||
70 | + if (ctrl->saved_gregs) { |
||
71 | + for (ifc_bank = 0; ifc_bank < FSL_IFC_BANK_COUNT; ifc_bank++) { |
||
72 | + ctrl->saved_gregs->cspr_cs[ifc_bank].cspr_ext = |
||
73 | + ifc_in32(&fcm->cspr_cs[ifc_bank].cspr_ext); |
||
74 | + ctrl->saved_gregs->cspr_cs[ifc_bank].cspr = |
||
75 | + ifc_in32(&fcm->cspr_cs[ifc_bank].cspr); |
||
76 | + ctrl->saved_gregs->amask_cs[ifc_bank].amask = |
||
77 | + ifc_in32(&fcm->amask_cs[ifc_bank].amask); |
||
78 | + ctrl->saved_gregs->csor_cs[ifc_bank].csor_ext = |
||
79 | + ifc_in32(&fcm->csor_cs[ifc_bank].csor_ext); |
||
80 | + ctrl->saved_gregs->csor_cs[ifc_bank].csor = |
||
81 | + ifc_in32(&fcm->csor_cs[ifc_bank].csor); |
||
82 | + for (i = 0; i < 4; i++) { |
||
83 | + ctrl->saved_gregs->ftim_cs[ifc_bank].ftim[i] = |
||
84 | + ifc_in32( |
||
85 | + &fcm->ftim_cs[ifc_bank].ftim[i]); |
||
86 | + } |
||
87 | + } |
||
88 | + |
||
89 | + ctrl->saved_gregs->rb_map = ifc_in32(&fcm->rb_map); |
||
90 | + ctrl->saved_gregs->wb_map = ifc_in32(&fcm->wb_map); |
||
91 | + ctrl->saved_gregs->ifc_gcr = ifc_in32(&fcm->ifc_gcr); |
||
92 | + ctrl->saved_gregs->ddr_ccr_low = ifc_in32(&fcm->ddr_ccr_low); |
||
93 | + ctrl->saved_gregs->cm_evter_en = ifc_in32(&fcm->cm_evter_en); |
||
94 | + } |
||
95 | + |
||
96 | + if (ctrl->saved_rregs) { |
||
97 | + /* IFC controller NAND machine registers */ |
||
98 | + ctrl->saved_rregs->ifc_nand.ncfgr = |
||
99 | + ifc_in32(&runtime->ifc_nand.ncfgr); |
||
100 | + ctrl->saved_rregs->ifc_nand.nand_fcr0 = |
||
101 | + ifc_in32(&runtime->ifc_nand.nand_fcr0); |
||
102 | + ctrl->saved_rregs->ifc_nand.nand_fcr1 = |
||
103 | + ifc_in32(&runtime->ifc_nand.nand_fcr1); |
||
104 | + ctrl->saved_rregs->ifc_nand.row0 = |
||
105 | + ifc_in32(&runtime->ifc_nand.row0); |
||
106 | + ctrl->saved_rregs->ifc_nand.row1 = |
||
107 | + ifc_in32(&runtime->ifc_nand.row1); |
||
108 | + ctrl->saved_rregs->ifc_nand.col0 = |
||
109 | + ifc_in32(&runtime->ifc_nand.col0); |
||
110 | + ctrl->saved_rregs->ifc_nand.col1 = |
||
111 | + ifc_in32(&runtime->ifc_nand.col1); |
||
112 | + ctrl->saved_rregs->ifc_nand.row2 = |
||
113 | + ifc_in32(&runtime->ifc_nand.row2); |
||
114 | + ctrl->saved_rregs->ifc_nand.col2 = |
||
115 | + ifc_in32(&runtime->ifc_nand.col2); |
||
116 | + ctrl->saved_rregs->ifc_nand.row3 = |
||
117 | + ifc_in32(&runtime->ifc_nand.row3); |
||
118 | + ctrl->saved_rregs->ifc_nand.col3 = |
||
119 | + ifc_in32(&runtime->ifc_nand.col3); |
||
120 | + |
||
121 | + ctrl->saved_rregs->ifc_nand.nand_fbcr = |
||
122 | + ifc_in32(&runtime->ifc_nand.nand_fbcr); |
||
123 | + ctrl->saved_rregs->ifc_nand.nand_fir0 = |
||
124 | + ifc_in32(&runtime->ifc_nand.nand_fir0); |
||
125 | + ctrl->saved_rregs->ifc_nand.nand_fir1 = |
||
126 | + ifc_in32(&runtime->ifc_nand.nand_fir1); |
||
127 | + ctrl->saved_rregs->ifc_nand.nand_fir2 = |
||
128 | + ifc_in32(&runtime->ifc_nand.nand_fir2); |
||
129 | + ctrl->saved_rregs->ifc_nand.nand_csel = |
||
130 | + ifc_in32(&runtime->ifc_nand.nand_csel); |
||
131 | + ctrl->saved_rregs->ifc_nand.nandseq_strt = |
||
132 | + ifc_in32( |
||
133 | + &runtime->ifc_nand.nandseq_strt); |
||
134 | + ctrl->saved_rregs->ifc_nand.nand_evter_en = |
||
135 | + ifc_in32( |
||
136 | + &runtime->ifc_nand.nand_evter_en); |
||
137 | + ctrl->saved_rregs->ifc_nand.nanndcr = |
||
138 | + ifc_in32(&runtime->ifc_nand.nanndcr); |
||
139 | + ctrl->saved_rregs->ifc_nand.nand_dll_lowcfg0 = |
||
140 | + ifc_in32( |
||
141 | + &runtime->ifc_nand.nand_dll_lowcfg0); |
||
142 | + ctrl->saved_rregs->ifc_nand.nand_dll_lowcfg1 = |
||
143 | + ifc_in32( |
||
144 | + &runtime->ifc_nand.nand_dll_lowcfg1); |
||
145 | + |
||
146 | + /* IFC controller NOR machine registers */ |
||
147 | + ctrl->saved_rregs->ifc_nor.nor_evter_en = |
||
148 | + ifc_in32( |
||
149 | + &runtime->ifc_nor.nor_evter_en); |
||
150 | + ctrl->saved_rregs->ifc_nor.norcr = |
||
151 | + ifc_in32(&runtime->ifc_nor.norcr); |
||
152 | + |
||
153 | + /* IFC controller GPCM Machine registers */ |
||
154 | + ctrl->saved_rregs->ifc_gpcm.gpcm_evter_en = |
||
155 | + ifc_in32( |
||
156 | + &runtime->ifc_gpcm.gpcm_evter_en); |
||
157 | + } |
||
158 | + |
||
159 | +/* save the interrupt values */ |
||
160 | + ctrl->saved_gregs->cm_evter_intr_en = cm_evter_intr_en; |
||
161 | + ctrl->saved_rregs->ifc_nand.nand_evter_intr_en = nand_evter_intr_en; |
||
162 | + ctrl->saved_rregs->ifc_nor.nor_evter_intr_en = nor_evter_intr_en; |
||
163 | + ctrl->saved_rregs->ifc_gpcm.gpcm_evter_intr_en = gpcm_evter_intr_en; |
||
164 | + |
||
165 | + return 0; |
||
166 | +} |
||
167 | + |
||
168 | +/* restore ifc registers */ |
||
169 | +static int fsl_ifc_resume(struct device *dev) |
||
170 | +{ |
||
171 | + struct fsl_ifc_ctrl *ctrl = dev_get_drvdata(dev); |
||
172 | + struct fsl_ifc_global __iomem *fcm = ctrl->gregs; |
||
173 | + struct fsl_ifc_runtime __iomem *runtime = ctrl->rregs; |
||
174 | + struct fsl_ifc_global *savd_gregs = ctrl->saved_gregs; |
||
175 | + struct fsl_ifc_runtime *savd_rregs = ctrl->saved_rregs; |
||
176 | + uint32_t ver = 0, ncfgr, timeout, ifc_bank, i; |
||
177 | + |
||
178 | +/* |
||
179 | + * IFC interrupts disabled |
||
180 | + */ |
||
181 | + ifc_out32(0x0, &fcm->cm_evter_intr_en); |
||
182 | + ifc_out32(0x0, &runtime->ifc_nand.nand_evter_intr_en); |
||
183 | + ifc_out32(0x0, &runtime->ifc_nor.nor_evter_intr_en); |
||
184 | + ifc_out32(0x0, &runtime->ifc_gpcm.gpcm_evter_intr_en); |
||
185 | + |
||
186 | + |
||
187 | + if (ctrl->saved_gregs) { |
||
188 | + for (ifc_bank = 0; ifc_bank < FSL_IFC_BANK_COUNT; ifc_bank++) { |
||
189 | + ifc_out32(savd_gregs->cspr_cs[ifc_bank].cspr_ext, |
||
190 | + &fcm->cspr_cs[ifc_bank].cspr_ext); |
||
191 | + ifc_out32(savd_gregs->cspr_cs[ifc_bank].cspr, |
||
192 | + &fcm->cspr_cs[ifc_bank].cspr); |
||
193 | + ifc_out32(savd_gregs->amask_cs[ifc_bank].amask, |
||
194 | + &fcm->amask_cs[ifc_bank].amask); |
||
195 | + ifc_out32(savd_gregs->csor_cs[ifc_bank].csor_ext, |
||
196 | + &fcm->csor_cs[ifc_bank].csor_ext); |
||
197 | + ifc_out32(savd_gregs->csor_cs[ifc_bank].csor, |
||
198 | + &fcm->csor_cs[ifc_bank].csor); |
||
199 | + for (i = 0; i < 4; i++) { |
||
200 | + ifc_out32(savd_gregs->ftim_cs[ifc_bank].ftim[i], |
||
201 | + &fcm->ftim_cs[ifc_bank].ftim[i]); |
||
202 | + } |
||
203 | + } |
||
204 | + ifc_out32(savd_gregs->rb_map, &fcm->rb_map); |
||
205 | + ifc_out32(savd_gregs->wb_map, &fcm->wb_map); |
||
206 | + ifc_out32(savd_gregs->ifc_gcr, &fcm->ifc_gcr); |
||
207 | + ifc_out32(savd_gregs->ddr_ccr_low, &fcm->ddr_ccr_low); |
||
208 | + ifc_out32(savd_gregs->cm_evter_en, &fcm->cm_evter_en); |
||
209 | + } |
||
210 | + |
||
211 | + if (ctrl->saved_rregs) { |
||
212 | + /* IFC controller NAND machine registers */ |
||
213 | + ifc_out32(savd_rregs->ifc_nand.ncfgr, |
||
214 | + &runtime->ifc_nand.ncfgr); |
||
215 | + ifc_out32(savd_rregs->ifc_nand.nand_fcr0, |
||
216 | + &runtime->ifc_nand.nand_fcr0); |
||
217 | + ifc_out32(savd_rregs->ifc_nand.nand_fcr1, |
||
218 | + &runtime->ifc_nand.nand_fcr1); |
||
219 | + ifc_out32(savd_rregs->ifc_nand.row0, &runtime->ifc_nand.row0); |
||
220 | + ifc_out32(savd_rregs->ifc_nand.row1, &runtime->ifc_nand.row1); |
||
221 | + ifc_out32(savd_rregs->ifc_nand.col0, &runtime->ifc_nand.col0); |
||
222 | + ifc_out32(savd_rregs->ifc_nand.col1, &runtime->ifc_nand.col1); |
||
223 | + ifc_out32(savd_rregs->ifc_nand.row2, &runtime->ifc_nand.row2); |
||
224 | + ifc_out32(savd_rregs->ifc_nand.col2, &runtime->ifc_nand.col2); |
||
225 | + ifc_out32(savd_rregs->ifc_nand.row3, &runtime->ifc_nand.row3); |
||
226 | + ifc_out32(savd_rregs->ifc_nand.col3, &runtime->ifc_nand.col3); |
||
227 | + ifc_out32(savd_rregs->ifc_nand.nand_fbcr, |
||
228 | + &runtime->ifc_nand.nand_fbcr); |
||
229 | + ifc_out32(savd_rregs->ifc_nand.nand_fir0, |
||
230 | + &runtime->ifc_nand.nand_fir0); |
||
231 | + ifc_out32(savd_rregs->ifc_nand.nand_fir1, |
||
232 | + &runtime->ifc_nand.nand_fir1); |
||
233 | + ifc_out32(savd_rregs->ifc_nand.nand_fir2, |
||
234 | + &runtime->ifc_nand.nand_fir2); |
||
235 | + ifc_out32(savd_rregs->ifc_nand.nand_csel, |
||
236 | + &runtime->ifc_nand.nand_csel); |
||
237 | + ifc_out32(savd_rregs->ifc_nand.nandseq_strt, |
||
238 | + &runtime->ifc_nand.nandseq_strt); |
||
239 | + ifc_out32(savd_rregs->ifc_nand.nand_evter_en, |
||
240 | + &runtime->ifc_nand.nand_evter_en); |
||
241 | + ifc_out32(savd_rregs->ifc_nand.nanndcr, |
||
242 | + &runtime->ifc_nand.nanndcr); |
||
243 | + ifc_out32(savd_rregs->ifc_nand.nand_dll_lowcfg0, |
||
244 | + &runtime->ifc_nand.nand_dll_lowcfg0); |
||
245 | + ifc_out32(savd_rregs->ifc_nand.nand_dll_lowcfg1, |
||
246 | + &runtime->ifc_nand.nand_dll_lowcfg1); |
||
247 | + |
||
248 | + /* IFC controller NOR machine registers */ |
||
249 | + ifc_out32(savd_rregs->ifc_nor.nor_evter_en, |
||
250 | + &runtime->ifc_nor.nor_evter_en); |
||
251 | + ifc_out32(savd_rregs->ifc_nor.norcr, &runtime->ifc_nor.norcr); |
||
252 | + |
||
253 | + /* IFC controller GPCM Machine registers */ |
||
254 | + ifc_out32(savd_rregs->ifc_gpcm.gpcm_evter_en, |
||
255 | + &runtime->ifc_gpcm.gpcm_evter_en); |
||
256 | + |
||
257 | + /* IFC interrupts enabled */ |
||
258 | + ifc_out32(ctrl->saved_gregs->cm_evter_intr_en, |
||
259 | + &fcm->cm_evter_intr_en); |
||
260 | + ifc_out32(ctrl->saved_rregs->ifc_nand.nand_evter_intr_en, |
||
261 | + &runtime->ifc_nand.nand_evter_intr_en); |
||
262 | + ifc_out32(ctrl->saved_rregs->ifc_nor.nor_evter_intr_en, |
||
263 | + &runtime->ifc_nor.nor_evter_intr_en); |
||
264 | + ifc_out32(ctrl->saved_rregs->ifc_gpcm.gpcm_evter_intr_en, |
||
265 | + &runtime->ifc_gpcm.gpcm_evter_intr_en); |
||
266 | + |
||
267 | + kfree(ctrl->saved_gregs); |
||
268 | + kfree(ctrl->saved_rregs); |
||
269 | + ctrl->saved_gregs = NULL; |
||
270 | + ctrl->saved_rregs = NULL; |
||
271 | + } |
||
272 | + |
||
273 | + ver = ifc_in32(&fcm->ifc_rev); |
||
274 | + ncfgr = ifc_in32(&runtime->ifc_nand.ncfgr); |
||
275 | + if (ver >= FSL_IFC_V1_3_0) { |
||
276 | + |
||
277 | + ifc_out32(ncfgr | IFC_NAND_SRAM_INIT_EN, |
||
278 | + &runtime->ifc_nand.ncfgr); |
||
279 | + /* wait for SRAM_INIT bit to be clear or timeout */ |
||
280 | + timeout = 10; |
||
281 | + while ((ifc_in32(&runtime->ifc_nand.ncfgr) & |
||
282 | + IFC_NAND_SRAM_INIT_EN) && timeout) { |
||
283 | + mdelay(IFC_TIMEOUT_MSECS); |
||
284 | + timeout--; |
||
285 | + } |
||
286 | + |
||
287 | + if (!timeout) |
||
288 | + dev_err(ctrl->dev, "Timeout waiting for IFC SRAM INIT"); |
||
289 | + } |
||
290 | + |
||
291 | + return 0; |
||
292 | +} |
||
293 | +#endif /* CONFIG_PM_SLEEP */ |
||
294 | + |
||
295 | static const struct of_device_id fsl_ifc_match[] = { |
||
296 | { |
||
297 | .compatible = "fsl,ifc", |
||
298 | @@ -318,10 +576,15 @@ static const struct of_device_id fsl_ifc |
||
299 | {}, |
||
300 | }; |
||
301 | |||
302 | +static const struct dev_pm_ops ifc_pm_ops = { |
||
303 | + SET_SYSTEM_SLEEP_PM_OPS(fsl_ifc_suspend, fsl_ifc_resume) |
||
304 | +}; |
||
305 | + |
||
306 | static struct platform_driver fsl_ifc_ctrl_driver = { |
||
307 | .driver = { |
||
308 | .name = "fsl-ifc", |
||
309 | .of_match_table = fsl_ifc_match, |
||
310 | + .pm = &ifc_pm_ops, |
||
311 | }, |
||
312 | .probe = fsl_ifc_ctrl_probe, |
||
313 | .remove = fsl_ifc_ctrl_remove, |
||
314 | --- a/drivers/mtd/maps/physmap_of_core.c |
||
315 | +++ b/drivers/mtd/maps/physmap_of_core.c |
||
316 | @@ -20,6 +20,7 @@ |
||
317 | #include <linux/mtd/map.h> |
||
318 | #include <linux/mtd/partitions.h> |
||
319 | #include <linux/mtd/concat.h> |
||
320 | +#include <linux/mtd/cfi_endian.h> |
||
321 | #include <linux/of.h> |
||
322 | #include <linux/of_address.h> |
||
323 | #include <linux/of_platform.h> |
||
324 | @@ -205,6 +206,9 @@ static int of_flash_probe(struct platfor |
||
325 | info->list[i].map.bankwidth = be32_to_cpup(width); |
||
326 | info->list[i].map.device_node = dp; |
||
327 | |||
328 | + if (of_property_read_bool(dp->parent, "big-endian")) |
||
329 | + info->list[i].map.swap = CFI_BIG_ENDIAN; |
||
330 | + |
||
331 | err = of_flash_probe_gemini(dev, dp, &info->list[i].map); |
||
332 | if (err) |
||
333 | goto err_out; |
||
334 | --- a/include/linux/fsl_ifc.h |
||
335 | +++ b/include/linux/fsl_ifc.h |
||
336 | @@ -274,6 +274,8 @@ |
||
337 | */ |
||
338 | /* Auto Boot Mode */ |
||
339 | #define IFC_NAND_NCFGR_BOOT 0x80000000 |
||
340 | +/* SRAM INIT EN */ |
||
341 | +#define IFC_NAND_SRAM_INIT_EN 0x20000000 |
||
342 | /* Addressing Mode-ROW0+n/COL0 */ |
||
343 | #define IFC_NAND_NCFGR_ADDR_MODE_RC0 0x00000000 |
||
344 | /* Addressing Mode-ROW0+n/COL0+n */ |
||
345 | @@ -857,6 +859,11 @@ struct fsl_ifc_ctrl { |
||
346 | u32 nand_stat; |
||
347 | wait_queue_head_t nand_wait; |
||
348 | bool little_endian; |
||
349 | +#ifdef CONFIG_PM_SLEEP |
||
350 | + /*save regs when system goes to deep sleep*/ |
||
351 | + struct fsl_ifc_global *saved_gregs; |
||
352 | + struct fsl_ifc_runtime *saved_rregs; |
||
353 | +#endif |
||
354 | }; |
||
355 | |||
356 | extern struct fsl_ifc_ctrl *fsl_ifc_ctrl_dev; |