aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/maps/tegra_nor.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/maps/tegra_nor.c')
-rw-r--r--drivers/mtd/maps/tegra_nor.c483
1 files changed, 483 insertions, 0 deletions
diff --git a/drivers/mtd/maps/tegra_nor.c b/drivers/mtd/maps/tegra_nor.c
new file mode 100644
index 00000000000..b455fd5e1c0
--- /dev/null
+++ b/drivers/mtd/maps/tegra_nor.c
@@ -0,0 +1,483 @@
1/*
2 * drivers/mtd/maps/tegra_nor.c
3 *
4 * MTD mapping driver for the internal SNOR controller in Tegra SoCs
5 *
6 * Copyright (C) 2009 - 2012 NVIDIA Corporation
7 *
8 * Author:
9 * Raghavendra VK <rvk@nvidia.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but WITHOUT
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 * more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 */
25
26#include <linux/platform_device.h>
27#include <linux/module.h>
28#include <linux/types.h>
29#include <linux/kernel.h>
30#include <linux/init.h>
31#include <linux/ioport.h>
32#include <linux/slab.h>
33#include <linux/interrupt.h>
34#include <linux/irq.h>
35#include <linux/mutex.h>
36#include <linux/mtd/mtd.h>
37#include <linux/mtd/map.h>
38#include <linux/mtd/partitions.h>
39#include <linux/dma-mapping.h>
40#include <linux/proc_fs.h>
41#include <linux/io.h>
42#include <linux/uaccess.h>
43#include <linux/clk.h>
44#include <linux/platform_data/tegra_nor.h>
45#include <asm/cacheflush.h>
46
47#define __BITMASK0(len) (BIT(len) - 1)
48#define REG_FIELD(val, start, len) (((val) & __BITMASK0(len)) << (start))
49#define REG_GET_FIELD(val, start, len) (((val) >> (start)) & __BITMASK0(len))
50
51/* tegra gmi registers... */
52#define TEGRA_SNOR_CONFIG_REG 0x00
53#define TEGRA_SNOR_NOR_ADDR_PTR_REG 0x08
54#define TEGRA_SNOR_AHB_ADDR_PTR_REG 0x0C
55#define TEGRA_SNOR_TIMING0_REG 0x10
56#define TEGRA_SNOR_TIMING1_REG 0x14
57#define TEGRA_SNOR_DMA_CFG_REG 0x20
58
59/* config register */
60#define TEGRA_SNOR_CONFIG_GO BIT(31)
61#define TEGRA_SNOR_CONFIG_WORDWIDE BIT(30)
62#define TEGRA_SNOR_CONFIG_DEVICE_TYPE BIT(29)
63#define TEGRA_SNOR_CONFIG_MUX_MODE BIT(28)
64#define TEGRA_SNOR_CONFIG_BURST_LEN(val) REG_FIELD((val), 26, 2)
65#define TEGRA_SNOR_CONFIG_RDY_ACTIVE BIT(24)
66#define TEGRA_SNOR_CONFIG_RDY_POLARITY BIT(23)
67#define TEGRA_SNOR_CONFIG_ADV_POLARITY BIT(22)
68#define TEGRA_SNOR_CONFIG_OE_WE_POLARITY BIT(21)
69#define TEGRA_SNOR_CONFIG_CS_POLARITY BIT(20)
70#define TEGRA_SNOR_CONFIG_NOR_DPD BIT(19)
71#define TEGRA_SNOR_CONFIG_WP BIT(15)
72#define TEGRA_SNOR_CONFIG_PAGE_SZ(val) REG_FIELD((val), 8, 2)
73#define TEGRA_SNOR_CONFIG_MST_ENB BIT(7)
74#define TEGRA_SNOR_CONFIG_SNOR_CS(val) REG_FIELD((val), 4, 2)
75#define TEGRA_SNOR_CONFIG_CE_LAST REG_FIELD(3)
76#define TEGRA_SNOR_CONFIG_CE_FIRST REG_FIELD(2)
77#define TEGRA_SNOR_CONFIG_DEVICE_MODE(val) REG_FIELD((val), 0, 2)
78
79/* dma config register */
80#define TEGRA_SNOR_DMA_CFG_GO BIT(31)
81#define TEGRA_SNOR_DMA_CFG_BSY BIT(30)
82#define TEGRA_SNOR_DMA_CFG_DIR BIT(29)
83#define TEGRA_SNOR_DMA_CFG_INT_ENB BIT(28)
84#define TEGRA_SNOR_DMA_CFG_INT_STA BIT(27)
85#define TEGRA_SNOR_DMA_CFG_BRST_SZ(val) REG_FIELD((val), 24, 3)
86#define TEGRA_SNOR_DMA_CFG_WRD_CNT(val) REG_FIELD((val), 2, 14)
87
88/* timing 0 register */
89#define TEGRA_SNOR_TIMING0_PG_RDY(val) REG_FIELD((val), 28, 4)
90#define TEGRA_SNOR_TIMING0_PG_SEQ(val) REG_FIELD((val), 20, 4)
91#define TEGRA_SNOR_TIMING0_MUX(val) REG_FIELD((val), 12, 4)
92#define TEGRA_SNOR_TIMING0_HOLD(val) REG_FIELD((val), 8, 4)
93#define TEGRA_SNOR_TIMING0_ADV(val) REG_FIELD((val), 4, 4)
94#define TEGRA_SNOR_TIMING0_CE(val) REG_FIELD((val), 0, 4)
95
96/* timing 1 register */
97#define TEGRA_SNOR_TIMING1_WE(val) REG_FIELD((val), 16, 8)
98#define TEGRA_SNOR_TIMING1_OE(val) REG_FIELD((val), 8, 8)
99#define TEGRA_SNOR_TIMING1_WAIT(val) REG_FIELD((val), 0, 8)
100
101/* SNOR DMA supports 2^14 AHB (32-bit words)
102 * Maximum data in one transfer = 2^16 bytes
103 */
104#define TEGRA_SNOR_DMA_LIMIT 0x10000
105#define TEGRA_SNOR_DMA_LIMIT_WORDS (TEGRA_SNOR_DMA_LIMIT >> 2)
106
107/* Even if BW is 1 MB/s, maximum time to
108 * transfer SNOR_DMA_LIMIT bytes is 66 ms
109 */
110#define TEGRA_SNOR_DMA_TIMEOUT_MS 67
111
112struct tegra_nor_info {
113 struct tegra_nor_platform_data *plat;
114 struct device *dev;
115 struct clk *clk;
116 struct mtd_partition *parts;
117 struct mtd_info *mtd;
118 struct map_info map;
119 struct completion dma_complete;
120 void __iomem *base;
121 void *dma_virt_buffer;
122 dma_addr_t dma_phys_buffer;
123 u32 init_config;
124 u32 timing0_default, timing1_default;
125 u32 timing0_read, timing1_read;
126};
127
128static inline unsigned long snor_tegra_readl(struct tegra_nor_info *tnor,
129 unsigned long reg)
130{
131 return readl(tnor->base + reg);
132}
133
134static inline void snor_tegra_writel(struct tegra_nor_info *tnor,
135 unsigned long val, unsigned long reg)
136{
137 writel(val, tnor->base + reg);
138}
139
140#define DRV_NAME "tegra-nor"
141
142static const char * const part_probes[] = { "cmdlinepart", NULL };
143
144static int wait_for_dma_completion(struct tegra_nor_info *info)
145{
146 unsigned long dma_timeout;
147 int ret;
148
149 dma_timeout = msecs_to_jiffies(TEGRA_SNOR_DMA_TIMEOUT_MS);
150 ret = wait_for_completion_timeout(&info->dma_complete, dma_timeout);
151 return ret ? 0 : -ETIMEDOUT;
152}
153
154static void tegra_flash_dma(struct map_info *map,
155 void *to, unsigned long from, ssize_t len)
156{
157 u32 snor_config, dma_config = 0;
158 int dma_transfer_count = 0, word32_count = 0;
159 u32 nor_address, current_transfer = 0;
160 u32 copy_to = (u32)to;
161 struct tegra_nor_info *c =
162 container_of(map, struct tegra_nor_info, map);
163 unsigned int bytes_remaining = len;
164
165 snor_config = c->init_config;
166 snor_tegra_writel(c, c->timing0_read, TEGRA_SNOR_TIMING0_REG);
167 snor_tegra_writel(c, c->timing1_read, TEGRA_SNOR_TIMING1_REG);
168
169 if (len > 32) {
170 word32_count = len >> 2;
171 bytes_remaining = len & 0x00000003;
172 /*
173 * The parameters can be setup in any order since we write to
174 * controller register only after all parameters are set.
175 */
176 /* SNOR CONFIGURATION SETUP */
177 snor_config |= TEGRA_SNOR_CONFIG_DEVICE_MODE(1);
178 /* 8 word page */
179 snor_config |= TEGRA_SNOR_CONFIG_PAGE_SZ(2);
180 snor_config |= TEGRA_SNOR_CONFIG_MST_ENB;
181 /* SNOR DMA CONFIGURATION SETUP */
182 /* NOR -> AHB */
183 dma_config &= ~TEGRA_SNOR_DMA_CFG_DIR;
184 /* One word burst */
185 dma_config |= TEGRA_SNOR_DMA_CFG_BRST_SZ(4);
186
187 for (nor_address = (unsigned int)(map->phys + from);
188 word32_count > 0;
189 word32_count -= current_transfer,
190 dma_transfer_count += current_transfer,
191 nor_address += (current_transfer * 4),
192 copy_to += (current_transfer * 4)) {
193
194 current_transfer =
195 (word32_count > TEGRA_SNOR_DMA_LIMIT_WORDS)
196 ? (TEGRA_SNOR_DMA_LIMIT_WORDS) : word32_count;
197 /* Start NOR operation */
198 snor_config |= TEGRA_SNOR_CONFIG_GO;
199 dma_config |= TEGRA_SNOR_DMA_CFG_GO;
200 /* Enable interrupt before every transaction since the
201 * interrupt handler disables it */
202 dma_config |= TEGRA_SNOR_DMA_CFG_INT_ENB;
203 /* Num of AHB (32-bit) words to transferred minus 1 */
204 dma_config |=
205 TEGRA_SNOR_DMA_CFG_WRD_CNT(current_transfer - 1);
206 snor_tegra_writel(c, c->dma_phys_buffer,
207 TEGRA_SNOR_AHB_ADDR_PTR_REG);
208 snor_tegra_writel(c, nor_address,
209 TEGRA_SNOR_NOR_ADDR_PTR_REG);
210 snor_tegra_writel(c, snor_config,
211 TEGRA_SNOR_CONFIG_REG);
212 snor_tegra_writel(c, dma_config,
213 TEGRA_SNOR_DMA_CFG_REG);
214 if (wait_for_dma_completion(c)) {
215 dev_err(c->dev, "timout waiting for DMA\n");
216 /* Transfer the remaining words by memcpy */
217 bytes_remaining += (word32_count << 2);
218 break;
219 }
220 memcpy((char *)(copy_to), (char *)(c->dma_virt_buffer),
221 (current_transfer << 2));
222
223 }
224 }
225 /* Put the controller back into slave mode. */
226 snor_config = snor_tegra_readl(c, TEGRA_SNOR_CONFIG_REG);
227 snor_config &= ~TEGRA_SNOR_CONFIG_MST_ENB;
228 snor_config |= TEGRA_SNOR_CONFIG_DEVICE_MODE(0);
229 snor_tegra_writel(c, snor_config, TEGRA_SNOR_CONFIG_REG);
230
231 memcpy_fromio(((char *)to + (dma_transfer_count << 2)),
232 ((char *)(map->virt + from) + (dma_transfer_count << 2)),
233 bytes_remaining);
234
235 snor_tegra_writel(c, c->timing0_default, TEGRA_SNOR_TIMING0_REG);
236 snor_tegra_writel(c, c->timing1_default, TEGRA_SNOR_TIMING1_REG);
237}
238
239static irqreturn_t tegra_nor_isr(int flag, void *dev_id)
240{
241 struct tegra_nor_info *info = (struct tegra_nor_info *)dev_id;
242 u32 dma_config = snor_tegra_readl(info, TEGRA_SNOR_DMA_CFG_REG);
243 if (dma_config & TEGRA_SNOR_DMA_CFG_INT_STA) {
244 /* Disable interrupts. WAR for BUG:821560 */
245 dma_config &= ~TEGRA_SNOR_DMA_CFG_INT_ENB;
246 snor_tegra_writel(info, dma_config, TEGRA_SNOR_DMA_CFG_REG);
247 complete(&info->dma_complete);
248 } else {
249 pr_err("%s: Spurious interrupt\n", __func__);
250 }
251 return IRQ_HANDLED;
252}
253
254static int tegra_snor_controller_init(struct tegra_nor_info *info)
255{
256 struct tegra_nor_chip_parms *chip_parm = &info->plat->chip_parms;
257 u32 width = info->plat->flash.width;
258 u32 config = 0;
259
260 config |= TEGRA_SNOR_CONFIG_DEVICE_MODE(0);
261 config |= TEGRA_SNOR_CONFIG_SNOR_CS(0);
262 config &= ~TEGRA_SNOR_CONFIG_DEVICE_TYPE; /* Select NOR */
263 config |= TEGRA_SNOR_CONFIG_WP; /* Enable writes */
264 switch (width) {
265 case 2:
266 config &= ~TEGRA_SNOR_CONFIG_WORDWIDE; /* 16 bit */
267 break;
268 case 4:
269 config |= TEGRA_SNOR_CONFIG_WORDWIDE; /* 32 bit */
270 break;
271 default:
272 return -EINVAL;
273 }
274 config |= TEGRA_SNOR_CONFIG_BURST_LEN(0);
275 config &= ~TEGRA_SNOR_CONFIG_MUX_MODE;
276 snor_tegra_writel(info, config, TEGRA_SNOR_CONFIG_REG);
277 info->init_config = config;
278
279 info->timing0_default = chip_parm->timing_default.timing0;
280 info->timing0_read = chip_parm->timing_read.timing0;
281 info->timing1_default = chip_parm->timing_default.timing1;
282 info->timing1_read = chip_parm->timing_read.timing0;
283
284 snor_tegra_writel(info, info->timing1_default, TEGRA_SNOR_TIMING1_REG);
285 snor_tegra_writel(info, info->timing0_default, TEGRA_SNOR_TIMING0_REG);
286 return 0;
287}
288
289static int tegra_nor_probe(struct platform_device *pdev)
290{
291 int err = 0;
292 struct tegra_nor_platform_data *plat = pdev->dev.platform_data;
293 struct tegra_nor_info *info = NULL;
294 struct device *dev = &pdev->dev;
295 struct resource *res;
296 int irq;
297
298 if (!plat) {
299 pr_err("%s: no platform device info\n", __func__);
300 err = -EINVAL;
301 goto fail;
302 }
303
304 info = devm_kzalloc(dev, sizeof(struct tegra_nor_info),
305 GFP_KERNEL);
306 if (!info) {
307 err = -ENOMEM;
308 goto fail;
309 }
310
311 /* Get NOR controller & map the same */
312 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
313 if (!res) {
314 dev_err(dev, "no mem resource?\n");
315 err = -ENODEV;
316 goto fail;
317 }
318
319 if (!devm_request_mem_region(dev, res->start, resource_size(res),
320 dev_name(&pdev->dev))) {
321 dev_err(dev, "NOR region already claimed\n");
322 err = -EBUSY;
323 goto fail;
324 }
325
326 info->base = devm_ioremap(dev, res->start, resource_size(res));
327 if (!info->base) {
328 dev_err(dev, "Can't ioremap NOR region\n");
329 err = -ENOMEM;
330 goto fail;
331 }
332
333 /* Get NOR flash aperture & map the same */
334 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
335 if (!res) {
336 dev_err(dev, "no mem resource?\n");
337 err = -ENODEV;
338 goto fail;
339 }
340
341 if (!devm_request_mem_region(dev, res->start, resource_size(res),
342 dev_name(dev))) {
343 dev_err(dev, "NOR region already claimed\n");
344 err = -EBUSY;
345 goto fail;
346 }
347
348 info->map.virt = devm_ioremap(dev, res->start,
349 resource_size(res));
350 if (!info->map.virt) {
351 dev_err(dev, "Can't ioremap NOR region\n");
352 err = -ENOMEM;
353 goto fail;
354 }
355
356 info->plat = plat;
357 info->dev = dev;
358 info->map.bankwidth = plat->flash.width;
359 info->map.name = dev_name(dev);
360 info->map.phys = res->start;
361 info->map.size = resource_size(res);
362
363 info->clk = clk_get(dev, NULL);
364 if (IS_ERR(info->clk)) {
365 err = PTR_ERR(info->clk);
366 goto fail;
367 }
368
369 err = clk_enable(info->clk);
370 if (err != 0)
371 goto out_clk_put;
372
373 simple_map_init(&info->map);
374 info->map.copy_from = tegra_flash_dma;
375
376 /* Intialise the SNOR controller before probe */
377 err = tegra_snor_controller_init(info);
378 if (err) {
379 dev_err(dev, "Error initializing controller\n");
380 goto out_clk_disable;
381 }
382
383 init_completion(&info->dma_complete);
384
385 irq = platform_get_irq(pdev, 0);
386 if (!irq) {
387 dev_err(dev, "no irq resource?\n");
388 err = -ENODEV;
389 goto out_clk_disable;
390 }
391
392 /* Register SNOR DMA completion interrupt */
393 err = devm_request_irq(dev, irq, tegra_nor_isr, IRQF_DISABLED,
394 dev_name(dev), info);
395 if (err) {
396 dev_err(dev, "Failed to request irq %i\n", irq);
397 goto out_clk_disable;
398 }
399 info->dma_virt_buffer = dma_alloc_coherent(dev,
400 TEGRA_SNOR_DMA_LIMIT,
401 &info->dma_phys_buffer,
402 GFP_KERNEL);
403 if (info->dma_virt_buffer == NULL) {
404 dev_err(&pdev->dev, "Could not allocate buffer for DMA");
405 err = -ENOMEM;
406 goto out_clk_disable;
407 }
408
409 info->mtd = do_map_probe(plat->flash.map_name, &info->map);
410 if (!info->mtd) {
411 err = -EIO;
412 goto out_dma_free_coherent;
413 }
414 info->mtd->owner = THIS_MODULE;
415 info->parts = NULL;
416
417 platform_set_drvdata(pdev, info);
418 err = parse_mtd_partitions(info->mtd, part_probes, &info->parts, 0);
419 if (err > 0)
420 err = mtd_device_register(info->mtd, info->parts, err);
421 else if (err <= 0 && plat->flash.parts)
422 err =
423 mtd_device_register(info->mtd, plat->flash.parts,
424 plat->flash.nr_parts);
425 else
426 mtd_device_register(info->mtd, NULL, 0);
427
428 return 0;
429
430out_dma_free_coherent:
431 dma_free_coherent(dev, TEGRA_SNOR_DMA_LIMIT,
432 info->dma_virt_buffer, info->dma_phys_buffer);
433out_clk_disable:
434 clk_disable(info->clk);
435out_clk_put:
436 clk_put(info->clk);
437fail:
438 pr_err("Tegra NOR probe failed\n");
439 return err;
440}
441
442static int tegra_nor_remove(struct platform_device *pdev)
443{
444 struct tegra_nor_info *info = platform_get_drvdata(pdev);
445
446 mtd_device_unregister(info->mtd);
447 if (info->parts)
448 kfree(info->parts);
449 dma_free_coherent(&pdev->dev, TEGRA_SNOR_DMA_LIMIT,
450 info->dma_virt_buffer, info->dma_phys_buffer);
451 map_destroy(info->mtd);
452 clk_disable(info->clk);
453 clk_put(info->clk);
454
455 return 0;
456}
457
458static struct platform_driver __refdata tegra_nor_driver = {
459 .probe = tegra_nor_probe,
460 .remove = __devexit_p(tegra_nor_remove),
461 .driver = {
462 .name = DRV_NAME,
463 .owner = THIS_MODULE,
464 },
465};
466
467static int __init tegra_nor_init(void)
468{
469 return platform_driver_register(&tegra_nor_driver);
470}
471
472static void __exit tegra_nor_exit(void)
473{
474 platform_driver_unregister(&tegra_nor_driver);
475}
476
477module_init(tegra_nor_init);
478module_exit(tegra_nor_exit);
479
480MODULE_AUTHOR("Raghavendra VK <rvk@nvidia.com>");
481MODULE_DESCRIPTION("NOR Flash mapping driver for NVIDIA Tegra based boards");
482MODULE_LICENSE("GPL");
483MODULE_ALIAS("platform:" DRV_NAME);