1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * JZ4780 NAND/external memory controller (NEMC) |
4 | * |
5 | * Copyright (c) 2015 Imagination Technologies |
6 | * Author: Alex Smith <alex@alex-smith.me.uk> |
7 | */ |
8 | |
9 | #include <linux/clk.h> |
10 | #include <linux/init.h> |
11 | #include <linux/io.h> |
12 | #include <linux/math64.h> |
13 | #include <linux/of.h> |
14 | #include <linux/of_address.h> |
15 | #include <linux/of_platform.h> |
16 | #include <linux/platform_device.h> |
17 | #include <linux/slab.h> |
18 | #include <linux/spinlock.h> |
19 | |
20 | #include <linux/jz4780-nemc.h> |
21 | |
22 | #define NEMC_SMCRn(n) (0x14 + (((n) - 1) * 4)) |
23 | #define NEMC_NFCSR 0x50 |
24 | |
25 | #define NEMC_REG_LEN 0x54 |
26 | |
27 | #define NEMC_SMCR_SMT BIT(0) |
28 | #define NEMC_SMCR_BW_SHIFT 6 |
29 | #define NEMC_SMCR_BW_MASK (0x3 << NEMC_SMCR_BW_SHIFT) |
30 | #define NEMC_SMCR_BW_8 (0 << 6) |
31 | #define NEMC_SMCR_TAS_SHIFT 8 |
32 | #define NEMC_SMCR_TAS_MASK (0xf << NEMC_SMCR_TAS_SHIFT) |
33 | #define NEMC_SMCR_TAH_SHIFT 12 |
34 | #define NEMC_SMCR_TAH_MASK (0xf << NEMC_SMCR_TAH_SHIFT) |
35 | #define NEMC_SMCR_TBP_SHIFT 16 |
36 | #define NEMC_SMCR_TBP_MASK (0xf << NEMC_SMCR_TBP_SHIFT) |
37 | #define NEMC_SMCR_TAW_SHIFT 20 |
38 | #define NEMC_SMCR_TAW_MASK (0xf << NEMC_SMCR_TAW_SHIFT) |
39 | #define NEMC_SMCR_TSTRV_SHIFT 24 |
40 | #define NEMC_SMCR_TSTRV_MASK (0x3f << NEMC_SMCR_TSTRV_SHIFT) |
41 | |
42 | #define NEMC_NFCSR_NFEn(n) BIT(((n) - 1) << 1) |
43 | #define NEMC_NFCSR_NFCEn(n) BIT((((n) - 1) << 1) + 1) |
44 | #define NEMC_NFCSR_TNFEn(n) BIT(16 + (n) - 1) |
45 | |
46 | struct jz_soc_info { |
47 | u8 tas_tah_cycles_max; |
48 | }; |
49 | |
50 | struct jz4780_nemc { |
51 | spinlock_t lock; |
52 | struct device *dev; |
53 | const struct jz_soc_info *soc_info; |
54 | void __iomem *base; |
55 | struct clk *clk; |
56 | uint32_t clk_period; |
57 | unsigned long banks_present; |
58 | }; |
59 | |
60 | /** |
61 | * jz4780_nemc_num_banks() - count the number of banks referenced by a device |
62 | * @dev: device to count banks for, must be a child of the NEMC. |
63 | * |
64 | * Return: The number of unique NEMC banks referred to by the specified NEMC |
65 | * child device. Unique here means that a device that references the same bank |
66 | * multiple times in its "reg" property will only count once. |
67 | */ |
68 | unsigned int jz4780_nemc_num_banks(struct device *dev) |
69 | { |
70 | const __be32 *prop; |
71 | unsigned int bank, count = 0; |
72 | unsigned long referenced = 0; |
73 | int i = 0; |
74 | |
75 | while ((prop = of_get_address(dev: dev->of_node, index: i++, NULL, NULL))) { |
76 | bank = of_read_number(cell: prop, size: 1); |
77 | if (!(referenced & BIT(bank))) { |
78 | referenced |= BIT(bank); |
79 | count++; |
80 | } |
81 | } |
82 | |
83 | return count; |
84 | } |
85 | EXPORT_SYMBOL(jz4780_nemc_num_banks); |
86 | |
87 | /** |
88 | * jz4780_nemc_set_type() - set the type of device connected to a bank |
89 | * @dev: child device of the NEMC. |
90 | * @bank: bank number to configure. |
91 | * @type: type of device connected to the bank. |
92 | */ |
93 | void jz4780_nemc_set_type(struct device *dev, unsigned int bank, |
94 | enum jz4780_nemc_bank_type type) |
95 | { |
96 | struct jz4780_nemc *nemc = dev_get_drvdata(dev: dev->parent); |
97 | uint32_t nfcsr; |
98 | |
99 | nfcsr = readl(addr: nemc->base + NEMC_NFCSR); |
100 | |
101 | /* TODO: Support toggle NAND devices. */ |
102 | switch (type) { |
103 | case JZ4780_NEMC_BANK_SRAM: |
104 | nfcsr &= ~(NEMC_NFCSR_TNFEn(bank) | NEMC_NFCSR_NFEn(bank)); |
105 | break; |
106 | case JZ4780_NEMC_BANK_NAND: |
107 | nfcsr &= ~NEMC_NFCSR_TNFEn(bank); |
108 | nfcsr |= NEMC_NFCSR_NFEn(bank); |
109 | break; |
110 | } |
111 | |
112 | writel(val: nfcsr, addr: nemc->base + NEMC_NFCSR); |
113 | } |
114 | EXPORT_SYMBOL(jz4780_nemc_set_type); |
115 | |
116 | /** |
117 | * jz4780_nemc_assert() - (de-)assert a NAND device's chip enable pin |
118 | * @dev: child device of the NEMC. |
119 | * @bank: bank number of device. |
120 | * @assert: whether the chip enable pin should be asserted. |
121 | * |
122 | * (De-)asserts the chip enable pin for the NAND device connected to the |
123 | * specified bank. |
124 | */ |
125 | void jz4780_nemc_assert(struct device *dev, unsigned int bank, bool assert) |
126 | { |
127 | struct jz4780_nemc *nemc = dev_get_drvdata(dev: dev->parent); |
128 | uint32_t nfcsr; |
129 | |
130 | nfcsr = readl(addr: nemc->base + NEMC_NFCSR); |
131 | |
132 | if (assert) |
133 | nfcsr |= NEMC_NFCSR_NFCEn(bank); |
134 | else |
135 | nfcsr &= ~NEMC_NFCSR_NFCEn(bank); |
136 | |
137 | writel(val: nfcsr, addr: nemc->base + NEMC_NFCSR); |
138 | } |
139 | EXPORT_SYMBOL(jz4780_nemc_assert); |
140 | |
141 | static uint32_t jz4780_nemc_clk_period(struct jz4780_nemc *nemc) |
142 | { |
143 | unsigned long rate; |
144 | |
145 | rate = clk_get_rate(clk: nemc->clk); |
146 | if (!rate) |
147 | return 0; |
148 | |
149 | /* Return in picoseconds. */ |
150 | return div64_ul(1000000000000ull, rate); |
151 | } |
152 | |
153 | static uint32_t jz4780_nemc_ns_to_cycles(struct jz4780_nemc *nemc, uint32_t ns) |
154 | { |
155 | return ((ns * 1000) + nemc->clk_period - 1) / nemc->clk_period; |
156 | } |
157 | |
158 | static bool jz4780_nemc_configure_bank(struct jz4780_nemc *nemc, |
159 | unsigned int bank, |
160 | struct device_node *node) |
161 | { |
162 | uint32_t smcr, val, cycles; |
163 | |
164 | /* |
165 | * Conversion of tBP and tAW cycle counts to values supported by the |
166 | * hardware (round up to the next supported value). |
167 | */ |
168 | static const u8 convert_tBP_tAW[] = { |
169 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, |
170 | |
171 | /* 11 - 12 -> 12 cycles */ |
172 | 11, 11, |
173 | |
174 | /* 13 - 15 -> 15 cycles */ |
175 | 12, 12, 12, |
176 | |
177 | /* 16 - 20 -> 20 cycles */ |
178 | 13, 13, 13, 13, 13, |
179 | |
180 | /* 21 - 25 -> 25 cycles */ |
181 | 14, 14, 14, 14, 14, |
182 | |
183 | /* 26 - 31 -> 31 cycles */ |
184 | 15, 15, 15, 15, 15, 15 |
185 | }; |
186 | |
187 | smcr = readl(addr: nemc->base + NEMC_SMCRn(bank)); |
188 | smcr &= ~NEMC_SMCR_SMT; |
189 | |
190 | if (!of_property_read_u32(np: node, propname: "ingenic,nemc-bus-width" , out_value: &val)) { |
191 | smcr &= ~NEMC_SMCR_BW_MASK; |
192 | switch (val) { |
193 | case 8: |
194 | smcr |= NEMC_SMCR_BW_8; |
195 | break; |
196 | default: |
197 | /* |
198 | * Earlier SoCs support a 16 bit bus width (the 4780 |
199 | * does not), until those are properly supported, error. |
200 | */ |
201 | dev_err(nemc->dev, "unsupported bus width: %u\n" , val); |
202 | return false; |
203 | } |
204 | } |
205 | |
206 | if (of_property_read_u32(np: node, propname: "ingenic,nemc-tAS" , out_value: &val) == 0) { |
207 | smcr &= ~NEMC_SMCR_TAS_MASK; |
208 | cycles = jz4780_nemc_ns_to_cycles(nemc, ns: val); |
209 | if (cycles > nemc->soc_info->tas_tah_cycles_max) { |
210 | dev_err(nemc->dev, "tAS %u is too high (%u cycles)\n" , |
211 | val, cycles); |
212 | return false; |
213 | } |
214 | |
215 | smcr |= cycles << NEMC_SMCR_TAS_SHIFT; |
216 | } |
217 | |
218 | if (of_property_read_u32(np: node, propname: "ingenic,nemc-tAH" , out_value: &val) == 0) { |
219 | smcr &= ~NEMC_SMCR_TAH_MASK; |
220 | cycles = jz4780_nemc_ns_to_cycles(nemc, ns: val); |
221 | if (cycles > nemc->soc_info->tas_tah_cycles_max) { |
222 | dev_err(nemc->dev, "tAH %u is too high (%u cycles)\n" , |
223 | val, cycles); |
224 | return false; |
225 | } |
226 | |
227 | smcr |= cycles << NEMC_SMCR_TAH_SHIFT; |
228 | } |
229 | |
230 | if (of_property_read_u32(np: node, propname: "ingenic,nemc-tBP" , out_value: &val) == 0) { |
231 | smcr &= ~NEMC_SMCR_TBP_MASK; |
232 | cycles = jz4780_nemc_ns_to_cycles(nemc, ns: val); |
233 | if (cycles > 31) { |
234 | dev_err(nemc->dev, "tBP %u is too high (%u cycles)\n" , |
235 | val, cycles); |
236 | return false; |
237 | } |
238 | |
239 | smcr |= convert_tBP_tAW[cycles] << NEMC_SMCR_TBP_SHIFT; |
240 | } |
241 | |
242 | if (of_property_read_u32(np: node, propname: "ingenic,nemc-tAW" , out_value: &val) == 0) { |
243 | smcr &= ~NEMC_SMCR_TAW_MASK; |
244 | cycles = jz4780_nemc_ns_to_cycles(nemc, ns: val); |
245 | if (cycles > 31) { |
246 | dev_err(nemc->dev, "tAW %u is too high (%u cycles)\n" , |
247 | val, cycles); |
248 | return false; |
249 | } |
250 | |
251 | smcr |= convert_tBP_tAW[cycles] << NEMC_SMCR_TAW_SHIFT; |
252 | } |
253 | |
254 | if (of_property_read_u32(np: node, propname: "ingenic,nemc-tSTRV" , out_value: &val) == 0) { |
255 | smcr &= ~NEMC_SMCR_TSTRV_MASK; |
256 | cycles = jz4780_nemc_ns_to_cycles(nemc, ns: val); |
257 | if (cycles > 63) { |
258 | dev_err(nemc->dev, "tSTRV %u is too high (%u cycles)\n" , |
259 | val, cycles); |
260 | return false; |
261 | } |
262 | |
263 | smcr |= cycles << NEMC_SMCR_TSTRV_SHIFT; |
264 | } |
265 | |
266 | writel(val: smcr, addr: nemc->base + NEMC_SMCRn(bank)); |
267 | return true; |
268 | } |
269 | |
270 | static int jz4780_nemc_probe(struct platform_device *pdev) |
271 | { |
272 | struct device *dev = &pdev->dev; |
273 | struct jz4780_nemc *nemc; |
274 | struct resource *res; |
275 | struct device_node *child; |
276 | const __be32 *prop; |
277 | unsigned int bank; |
278 | unsigned long referenced; |
279 | int i, ret; |
280 | |
281 | nemc = devm_kzalloc(dev, size: sizeof(*nemc), GFP_KERNEL); |
282 | if (!nemc) |
283 | return -ENOMEM; |
284 | |
285 | nemc->soc_info = device_get_match_data(dev); |
286 | if (!nemc->soc_info) |
287 | return -EINVAL; |
288 | |
289 | spin_lock_init(&nemc->lock); |
290 | nemc->dev = dev; |
291 | |
292 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
293 | if (!res) |
294 | return -EINVAL; |
295 | |
296 | /* |
297 | * The driver currently only uses the registers up to offset |
298 | * NEMC_REG_LEN. Since the EFUSE registers are in the middle of the |
299 | * NEMC registers, we only request the registers we will use for now; |
300 | * that way the EFUSE driver can probe too. |
301 | */ |
302 | if (!devm_request_mem_region(dev, res->start, NEMC_REG_LEN, dev_name(dev))) { |
303 | dev_err(dev, "unable to request I/O memory region\n" ); |
304 | return -EBUSY; |
305 | } |
306 | |
307 | nemc->base = devm_ioremap(dev, offset: res->start, NEMC_REG_LEN); |
308 | if (!nemc->base) { |
309 | dev_err(dev, "failed to get I/O memory\n" ); |
310 | return -ENOMEM; |
311 | } |
312 | |
313 | writel(val: 0, addr: nemc->base + NEMC_NFCSR); |
314 | |
315 | nemc->clk = devm_clk_get(dev, NULL); |
316 | if (IS_ERR(ptr: nemc->clk)) { |
317 | dev_err(dev, "failed to get clock\n" ); |
318 | return PTR_ERR(ptr: nemc->clk); |
319 | } |
320 | |
321 | ret = clk_prepare_enable(clk: nemc->clk); |
322 | if (ret) { |
323 | dev_err(dev, "failed to enable clock: %d\n" , ret); |
324 | return ret; |
325 | } |
326 | |
327 | nemc->clk_period = jz4780_nemc_clk_period(nemc); |
328 | if (!nemc->clk_period) { |
329 | dev_err(dev, "failed to calculate clock period\n" ); |
330 | clk_disable_unprepare(clk: nemc->clk); |
331 | return -EINVAL; |
332 | } |
333 | |
334 | /* |
335 | * Iterate over child devices, check that they do not conflict with |
336 | * each other, and register child devices for them. If a child device |
337 | * has invalid properties, it is ignored and no platform device is |
338 | * registered for it. |
339 | */ |
340 | for_each_child_of_node(nemc->dev->of_node, child) { |
341 | referenced = 0; |
342 | i = 0; |
343 | while ((prop = of_get_address(dev: child, index: i++, NULL, NULL))) { |
344 | bank = of_read_number(cell: prop, size: 1); |
345 | if (bank < 1 || bank >= JZ4780_NEMC_NUM_BANKS) { |
346 | dev_err(nemc->dev, |
347 | "%pOF requests invalid bank %u\n" , |
348 | child, bank); |
349 | |
350 | /* Will continue the outer loop below. */ |
351 | referenced = 0; |
352 | break; |
353 | } |
354 | |
355 | referenced |= BIT(bank); |
356 | } |
357 | |
358 | if (!referenced) { |
359 | dev_err(nemc->dev, "%pOF has no addresses\n" , |
360 | child); |
361 | continue; |
362 | } else if (nemc->banks_present & referenced) { |
363 | dev_err(nemc->dev, "%pOF conflicts with another node\n" , |
364 | child); |
365 | continue; |
366 | } |
367 | |
368 | /* Configure bank parameters. */ |
369 | for_each_set_bit(bank, &referenced, JZ4780_NEMC_NUM_BANKS) { |
370 | if (!jz4780_nemc_configure_bank(nemc, bank, node: child)) { |
371 | referenced = 0; |
372 | break; |
373 | } |
374 | } |
375 | |
376 | if (referenced) { |
377 | if (of_platform_device_create(np: child, NULL, parent: nemc->dev)) |
378 | nemc->banks_present |= referenced; |
379 | } |
380 | } |
381 | |
382 | platform_set_drvdata(pdev, data: nemc); |
383 | dev_info(dev, "JZ4780 NEMC initialised\n" ); |
384 | return 0; |
385 | } |
386 | |
387 | static int jz4780_nemc_remove(struct platform_device *pdev) |
388 | { |
389 | struct jz4780_nemc *nemc = platform_get_drvdata(pdev); |
390 | |
391 | clk_disable_unprepare(clk: nemc->clk); |
392 | return 0; |
393 | } |
394 | |
395 | static const struct jz_soc_info jz4740_soc_info = { |
396 | .tas_tah_cycles_max = 7, |
397 | }; |
398 | |
399 | static const struct jz_soc_info jz4780_soc_info = { |
400 | .tas_tah_cycles_max = 15, |
401 | }; |
402 | |
403 | static const struct of_device_id jz4780_nemc_dt_match[] = { |
404 | { .compatible = "ingenic,jz4740-nemc" , .data = &jz4740_soc_info, }, |
405 | { .compatible = "ingenic,jz4780-nemc" , .data = &jz4780_soc_info, }, |
406 | {}, |
407 | }; |
408 | |
409 | static struct platform_driver jz4780_nemc_driver = { |
410 | .probe = jz4780_nemc_probe, |
411 | .remove = jz4780_nemc_remove, |
412 | .driver = { |
413 | .name = "jz4780-nemc" , |
414 | .of_match_table = of_match_ptr(jz4780_nemc_dt_match), |
415 | }, |
416 | }; |
417 | |
418 | static int __init jz4780_nemc_init(void) |
419 | { |
420 | return platform_driver_register(&jz4780_nemc_driver); |
421 | } |
422 | subsys_initcall(jz4780_nemc_init); |
423 | |