mtd: onenand/omap2.c: use mtd_device_parse_register
[deliverable/linux.git] / drivers / mtd / onenand / samsung.c
CommitLineData
46f3e88b
KP
1/*
2 * Samsung S3C64XX/S5PC1XX OneNAND driver
3 *
4 * Copyright © 2008-2010 Samsung Electronics
5 * Kyungmin Park <kyungmin.park@samsung.com>
6 * Marek Szyprowski <m.szyprowski@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * Implementation:
13 * S3C64XX and S5PC100: emulate the pseudo BufferRAM
14 * S5PC110: use DMA
15 */
16
17#include <linux/module.h>
18#include <linux/platform_device.h>
19#include <linux/sched.h>
20#include <linux/slab.h>
21#include <linux/mtd/mtd.h>
22#include <linux/mtd/onenand.h>
23#include <linux/mtd/partitions.h>
24#include <linux/dma-mapping.h>
e23abf4b 25#include <linux/interrupt.h>
46f3e88b
KP
26
27#include <asm/mach/flash.h>
28#include <plat/regs-onenand.h>
29
30#include <linux/io.h>
31
32enum soc_type {
33 TYPE_S3C6400,
34 TYPE_S3C6410,
35 TYPE_S5PC100,
36 TYPE_S5PC110,
37};
38
39#define ONENAND_ERASE_STATUS 0x00
40#define ONENAND_MULTI_ERASE_SET 0x01
41#define ONENAND_ERASE_START 0x03
42#define ONENAND_UNLOCK_START 0x08
43#define ONENAND_UNLOCK_END 0x09
44#define ONENAND_LOCK_START 0x0A
45#define ONENAND_LOCK_END 0x0B
46#define ONENAND_LOCK_TIGHT_START 0x0C
47#define ONENAND_LOCK_TIGHT_END 0x0D
48#define ONENAND_UNLOCK_ALL 0x0E
49#define ONENAND_OTP_ACCESS 0x12
50#define ONENAND_SPARE_ACCESS_ONLY 0x13
51#define ONENAND_MAIN_ACCESS_ONLY 0x14
52#define ONENAND_ERASE_VERIFY 0x15
53#define ONENAND_MAIN_SPARE_ACCESS 0x16
54#define ONENAND_PIPELINE_READ 0x4000
55
56#define MAP_00 (0x0)
57#define MAP_01 (0x1)
58#define MAP_10 (0x2)
59#define MAP_11 (0x3)
60
61#define S3C64XX_CMD_MAP_SHIFT 24
aa6d1c0e 62#define S5PC100_CMD_MAP_SHIFT 26
46f3e88b
KP
63
64#define S3C6400_FBA_SHIFT 10
65#define S3C6400_FPA_SHIFT 4
66#define S3C6400_FSA_SHIFT 2
67
68#define S3C6410_FBA_SHIFT 12
69#define S3C6410_FPA_SHIFT 6
70#define S3C6410_FSA_SHIFT 4
71
72#define S5PC100_FBA_SHIFT 13
73#define S5PC100_FPA_SHIFT 7
74#define S5PC100_FSA_SHIFT 5
75
76/* S5PC110 specific definitions */
77#define S5PC110_DMA_SRC_ADDR 0x400
78#define S5PC110_DMA_SRC_CFG 0x404
79#define S5PC110_DMA_DST_ADDR 0x408
80#define S5PC110_DMA_DST_CFG 0x40C
81#define S5PC110_DMA_TRANS_SIZE 0x414
82#define S5PC110_DMA_TRANS_CMD 0x418
83#define S5PC110_DMA_TRANS_STATUS 0x41C
84#define S5PC110_DMA_TRANS_DIR 0x420
e23abf4b
KP
85#define S5PC110_INTC_DMA_CLR 0x1004
86#define S5PC110_INTC_ONENAND_CLR 0x1008
87#define S5PC110_INTC_DMA_MASK 0x1024
88#define S5PC110_INTC_ONENAND_MASK 0x1028
89#define S5PC110_INTC_DMA_PEND 0x1044
90#define S5PC110_INTC_ONENAND_PEND 0x1048
91#define S5PC110_INTC_DMA_STATUS 0x1064
92#define S5PC110_INTC_ONENAND_STATUS 0x1068
93
94#define S5PC110_INTC_DMA_TD (1 << 24)
95#define S5PC110_INTC_DMA_TE (1 << 16)
46f3e88b
KP
96
97#define S5PC110_DMA_CFG_SINGLE (0x0 << 16)
98#define S5PC110_DMA_CFG_4BURST (0x2 << 16)
99#define S5PC110_DMA_CFG_8BURST (0x3 << 16)
100#define S5PC110_DMA_CFG_16BURST (0x4 << 16)
101
102#define S5PC110_DMA_CFG_INC (0x0 << 8)
103#define S5PC110_DMA_CFG_CNT (0x1 << 8)
104
105#define S5PC110_DMA_CFG_8BIT (0x0 << 0)
106#define S5PC110_DMA_CFG_16BIT (0x1 << 0)
107#define S5PC110_DMA_CFG_32BIT (0x2 << 0)
108
109#define S5PC110_DMA_SRC_CFG_READ (S5PC110_DMA_CFG_16BURST | \
110 S5PC110_DMA_CFG_INC | \
111 S5PC110_DMA_CFG_16BIT)
112#define S5PC110_DMA_DST_CFG_READ (S5PC110_DMA_CFG_16BURST | \
113 S5PC110_DMA_CFG_INC | \
114 S5PC110_DMA_CFG_32BIT)
115#define S5PC110_DMA_SRC_CFG_WRITE (S5PC110_DMA_CFG_16BURST | \
116 S5PC110_DMA_CFG_INC | \
117 S5PC110_DMA_CFG_32BIT)
118#define S5PC110_DMA_DST_CFG_WRITE (S5PC110_DMA_CFG_16BURST | \
119 S5PC110_DMA_CFG_INC | \
120 S5PC110_DMA_CFG_16BIT)
121
122#define S5PC110_DMA_TRANS_CMD_TDC (0x1 << 18)
123#define S5PC110_DMA_TRANS_CMD_TEC (0x1 << 16)
124#define S5PC110_DMA_TRANS_CMD_TR (0x1 << 0)
125
126#define S5PC110_DMA_TRANS_STATUS_TD (0x1 << 18)
127#define S5PC110_DMA_TRANS_STATUS_TB (0x1 << 17)
128#define S5PC110_DMA_TRANS_STATUS_TE (0x1 << 16)
129
130#define S5PC110_DMA_DIR_READ 0x0
131#define S5PC110_DMA_DIR_WRITE 0x1
132
133struct s3c_onenand {
134 struct mtd_info *mtd;
135 struct platform_device *pdev;
136 enum soc_type type;
137 void __iomem *base;
138 struct resource *base_res;
139 void __iomem *ahb_addr;
140 struct resource *ahb_res;
141 int bootram_command;
142 void __iomem *page_buf;
143 void __iomem *oob_buf;
144 unsigned int (*mem_addr)(int fba, int fpa, int fsa);
145 unsigned int (*cmd_map)(unsigned int type, unsigned int val);
146 void __iomem *dma_addr;
147 struct resource *dma_res;
148 unsigned long phys_base;
e23abf4b 149 struct completion complete;
46f3e88b 150 struct mtd_partition *parts;
46f3e88b
KP
151};
152
153#define CMD_MAP_00(dev, addr) (dev->cmd_map(MAP_00, ((addr) << 1)))
154#define CMD_MAP_01(dev, mem_addr) (dev->cmd_map(MAP_01, (mem_addr)))
155#define CMD_MAP_10(dev, mem_addr) (dev->cmd_map(MAP_10, (mem_addr)))
156#define CMD_MAP_11(dev, addr) (dev->cmd_map(MAP_11, ((addr) << 2)))
157
158static struct s3c_onenand *onenand;
159
46f3e88b
KP
160static inline int s3c_read_reg(int offset)
161{
162 return readl(onenand->base + offset);
163}
164
165static inline void s3c_write_reg(int value, int offset)
166{
167 writel(value, onenand->base + offset);
168}
169
170static inline int s3c_read_cmd(unsigned int cmd)
171{
172 return readl(onenand->ahb_addr + cmd);
173}
174
175static inline void s3c_write_cmd(int value, unsigned int cmd)
176{
177 writel(value, onenand->ahb_addr + cmd);
178}
179
180#ifdef SAMSUNG_DEBUG
181static void s3c_dump_reg(void)
182{
183 int i;
184
185 for (i = 0; i < 0x400; i += 0x40) {
186 printk(KERN_INFO "0x%08X: 0x%08x 0x%08x 0x%08x 0x%08x\n",
187 (unsigned int) onenand->base + i,
188 s3c_read_reg(i), s3c_read_reg(i + 0x10),
189 s3c_read_reg(i + 0x20), s3c_read_reg(i + 0x30));
190 }
191}
192#endif
193
194static unsigned int s3c64xx_cmd_map(unsigned type, unsigned val)
195{
196 return (type << S3C64XX_CMD_MAP_SHIFT) | val;
197}
198
199static unsigned int s5pc1xx_cmd_map(unsigned type, unsigned val)
200{
aa6d1c0e 201 return (type << S5PC100_CMD_MAP_SHIFT) | val;
46f3e88b
KP
202}
203
204static unsigned int s3c6400_mem_addr(int fba, int fpa, int fsa)
205{
206 return (fba << S3C6400_FBA_SHIFT) | (fpa << S3C6400_FPA_SHIFT) |
207 (fsa << S3C6400_FSA_SHIFT);
208}
209
210static unsigned int s3c6410_mem_addr(int fba, int fpa, int fsa)
211{
212 return (fba << S3C6410_FBA_SHIFT) | (fpa << S3C6410_FPA_SHIFT) |
213 (fsa << S3C6410_FSA_SHIFT);
214}
215
216static unsigned int s5pc100_mem_addr(int fba, int fpa, int fsa)
217{
218 return (fba << S5PC100_FBA_SHIFT) | (fpa << S5PC100_FPA_SHIFT) |
219 (fsa << S5PC100_FSA_SHIFT);
220}
221
222static void s3c_onenand_reset(void)
223{
224 unsigned long timeout = 0x10000;
225 int stat;
226
227 s3c_write_reg(ONENAND_MEM_RESET_COLD, MEM_RESET_OFFSET);
228 while (1 && timeout--) {
229 stat = s3c_read_reg(INT_ERR_STAT_OFFSET);
230 if (stat & RST_CMP)
231 break;
232 }
233 stat = s3c_read_reg(INT_ERR_STAT_OFFSET);
234 s3c_write_reg(stat, INT_ERR_ACK_OFFSET);
235
236 /* Clear interrupt */
237 s3c_write_reg(0x0, INT_ERR_ACK_OFFSET);
238 /* Clear the ECC status */
239 s3c_write_reg(0x0, ECC_ERR_STAT_OFFSET);
240}
241
242static unsigned short s3c_onenand_readw(void __iomem *addr)
243{
244 struct onenand_chip *this = onenand->mtd->priv;
245 struct device *dev = &onenand->pdev->dev;
246 int reg = addr - this->base;
247 int word_addr = reg >> 1;
248 int value;
249
250 /* It's used for probing time */
251 switch (reg) {
252 case ONENAND_REG_MANUFACTURER_ID:
253 return s3c_read_reg(MANUFACT_ID_OFFSET);
254 case ONENAND_REG_DEVICE_ID:
255 return s3c_read_reg(DEVICE_ID_OFFSET);
256 case ONENAND_REG_VERSION_ID:
257 return s3c_read_reg(FLASH_VER_ID_OFFSET);
258 case ONENAND_REG_DATA_BUFFER_SIZE:
259 return s3c_read_reg(DATA_BUF_SIZE_OFFSET);
260 case ONENAND_REG_TECHNOLOGY:
261 return s3c_read_reg(TECH_OFFSET);
262 case ONENAND_REG_SYS_CFG1:
263 return s3c_read_reg(MEM_CFG_OFFSET);
264
265 /* Used at unlock all status */
266 case ONENAND_REG_CTRL_STATUS:
267 return 0;
268
269 case ONENAND_REG_WP_STATUS:
270 return ONENAND_WP_US;
271
272 default:
273 break;
274 }
275
276 /* BootRAM access control */
277 if ((unsigned int) addr < ONENAND_DATARAM && onenand->bootram_command) {
278 if (word_addr == 0)
279 return s3c_read_reg(MANUFACT_ID_OFFSET);
280 if (word_addr == 1)
281 return s3c_read_reg(DEVICE_ID_OFFSET);
282 if (word_addr == 2)
283 return s3c_read_reg(FLASH_VER_ID_OFFSET);
284 }
285
286 value = s3c_read_cmd(CMD_MAP_11(onenand, word_addr)) & 0xffff;
287 dev_info(dev, "%s: Illegal access at reg 0x%x, value 0x%x\n", __func__,
288 word_addr, value);
289 return value;
290}
291
292static void s3c_onenand_writew(unsigned short value, void __iomem *addr)
293{
294 struct onenand_chip *this = onenand->mtd->priv;
295 struct device *dev = &onenand->pdev->dev;
296 unsigned int reg = addr - this->base;
297 unsigned int word_addr = reg >> 1;
298
299 /* It's used for probing time */
300 switch (reg) {
301 case ONENAND_REG_SYS_CFG1:
302 s3c_write_reg(value, MEM_CFG_OFFSET);
303 return;
304
305 case ONENAND_REG_START_ADDRESS1:
306 case ONENAND_REG_START_ADDRESS2:
307 return;
308
309 /* Lock/lock-tight/unlock/unlock_all */
310 case ONENAND_REG_START_BLOCK_ADDRESS:
311 return;
312
313 default:
314 break;
315 }
316
317 /* BootRAM access control */
318 if ((unsigned int)addr < ONENAND_DATARAM) {
319 if (value == ONENAND_CMD_READID) {
320 onenand->bootram_command = 1;
321 return;
322 }
323 if (value == ONENAND_CMD_RESET) {
324 s3c_write_reg(ONENAND_MEM_RESET_COLD, MEM_RESET_OFFSET);
325 onenand->bootram_command = 0;
326 return;
327 }
328 }
329
330 dev_info(dev, "%s: Illegal access at reg 0x%x, value 0x%x\n", __func__,
331 word_addr, value);
332
333 s3c_write_cmd(value, CMD_MAP_11(onenand, word_addr));
334}
335
336static int s3c_onenand_wait(struct mtd_info *mtd, int state)
337{
338 struct device *dev = &onenand->pdev->dev;
339 unsigned int flags = INT_ACT;
340 unsigned int stat, ecc;
341 unsigned long timeout;
342
343 switch (state) {
344 case FL_READING:
345 flags |= BLK_RW_CMP | LOAD_CMP;
346 break;
347 case FL_WRITING:
348 flags |= BLK_RW_CMP | PGM_CMP;
349 break;
350 case FL_ERASING:
351 flags |= BLK_RW_CMP | ERS_CMP;
352 break;
353 case FL_LOCKING:
354 flags |= BLK_RW_CMP;
355 break;
356 default:
357 break;
358 }
359
360 /* The 20 msec is enough */
361 timeout = jiffies + msecs_to_jiffies(20);
362 while (time_before(jiffies, timeout)) {
363 stat = s3c_read_reg(INT_ERR_STAT_OFFSET);
364 if (stat & flags)
365 break;
366
367 if (state != FL_READING)
368 cond_resched();
369 }
370 /* To get correct interrupt status in timeout case */
371 stat = s3c_read_reg(INT_ERR_STAT_OFFSET);
372 s3c_write_reg(stat, INT_ERR_ACK_OFFSET);
373
374 /*
375 * In the Spec. it checks the controller status first
376 * However if you get the correct information in case of
377 * power off recovery (POR) test, it should read ECC status first
378 */
379 if (stat & LOAD_CMP) {
380 ecc = s3c_read_reg(ECC_ERR_STAT_OFFSET);
381 if (ecc & ONENAND_ECC_4BIT_UNCORRECTABLE) {
382 dev_info(dev, "%s: ECC error = 0x%04x\n", __func__,
383 ecc);
384 mtd->ecc_stats.failed++;
385 return -EBADMSG;
386 }
387 }
388
389 if (stat & (LOCKED_BLK | ERS_FAIL | PGM_FAIL | LD_FAIL_ECC_ERR)) {
390 dev_info(dev, "%s: controller error = 0x%04x\n", __func__,
391 stat);
392 if (stat & LOCKED_BLK)
393 dev_info(dev, "%s: it's locked error = 0x%04x\n",
394 __func__, stat);
395
396 return -EIO;
397 }
398
399 return 0;
400}
401
402static int s3c_onenand_command(struct mtd_info *mtd, int cmd, loff_t addr,
403 size_t len)
404{
405 struct onenand_chip *this = mtd->priv;
406 unsigned int *m, *s;
407 int fba, fpa, fsa = 0;
408 unsigned int mem_addr, cmd_map_01, cmd_map_10;
409 int i, mcount, scount;
410 int index;
411
412 fba = (int) (addr >> this->erase_shift);
413 fpa = (int) (addr >> this->page_shift);
414 fpa &= this->page_mask;
415
416 mem_addr = onenand->mem_addr(fba, fpa, fsa);
417 cmd_map_01 = CMD_MAP_01(onenand, mem_addr);
418 cmd_map_10 = CMD_MAP_10(onenand, mem_addr);
419
420 switch (cmd) {
421 case ONENAND_CMD_READ:
422 case ONENAND_CMD_READOOB:
423 case ONENAND_CMD_BUFFERRAM:
424 ONENAND_SET_NEXT_BUFFERRAM(this);
425 default:
426 break;
427 }
428
429 index = ONENAND_CURRENT_BUFFERRAM(this);
430
431 /*
432 * Emulate Two BufferRAMs and access with 4 bytes pointer
433 */
434 m = (unsigned int *) onenand->page_buf;
435 s = (unsigned int *) onenand->oob_buf;
436
437 if (index) {
438 m += (this->writesize >> 2);
439 s += (mtd->oobsize >> 2);
440 }
441
442 mcount = mtd->writesize >> 2;
443 scount = mtd->oobsize >> 2;
444
445 switch (cmd) {
446 case ONENAND_CMD_READ:
447 /* Main */
448 for (i = 0; i < mcount; i++)
449 *m++ = s3c_read_cmd(cmd_map_01);
450 return 0;
451
452 case ONENAND_CMD_READOOB:
453 s3c_write_reg(TSRF, TRANS_SPARE_OFFSET);
454 /* Main */
455 for (i = 0; i < mcount; i++)
456 *m++ = s3c_read_cmd(cmd_map_01);
457
458 /* Spare */
459 for (i = 0; i < scount; i++)
460 *s++ = s3c_read_cmd(cmd_map_01);
461
462 s3c_write_reg(0, TRANS_SPARE_OFFSET);
463 return 0;
464
465 case ONENAND_CMD_PROG:
466 /* Main */
467 for (i = 0; i < mcount; i++)
468 s3c_write_cmd(*m++, cmd_map_01);
469 return 0;
470
471 case ONENAND_CMD_PROGOOB:
472 s3c_write_reg(TSRF, TRANS_SPARE_OFFSET);
473
474 /* Main - dummy write */
475 for (i = 0; i < mcount; i++)
476 s3c_write_cmd(0xffffffff, cmd_map_01);
477
478 /* Spare */
479 for (i = 0; i < scount; i++)
480 s3c_write_cmd(*s++, cmd_map_01);
481
482 s3c_write_reg(0, TRANS_SPARE_OFFSET);
483 return 0;
484
485 case ONENAND_CMD_UNLOCK_ALL:
486 s3c_write_cmd(ONENAND_UNLOCK_ALL, cmd_map_10);
487 return 0;
488
489 case ONENAND_CMD_ERASE:
490 s3c_write_cmd(ONENAND_ERASE_START, cmd_map_10);
491 return 0;
492
493 default:
494 break;
495 }
496
497 return 0;
498}
499
500static unsigned char *s3c_get_bufferram(struct mtd_info *mtd, int area)
501{
502 struct onenand_chip *this = mtd->priv;
503 int index = ONENAND_CURRENT_BUFFERRAM(this);
504 unsigned char *p;
505
506 if (area == ONENAND_DATARAM) {
507 p = (unsigned char *) onenand->page_buf;
508 if (index == 1)
509 p += this->writesize;
510 } else {
511 p = (unsigned char *) onenand->oob_buf;
512 if (index == 1)
513 p += mtd->oobsize;
514 }
515
516 return p;
517}
518
519static int onenand_read_bufferram(struct mtd_info *mtd, int area,
520 unsigned char *buffer, int offset,
521 size_t count)
522{
523 unsigned char *p;
524
525 p = s3c_get_bufferram(mtd, area);
526 memcpy(buffer, p + offset, count);
527 return 0;
528}
529
530static int onenand_write_bufferram(struct mtd_info *mtd, int area,
531 const unsigned char *buffer, int offset,
532 size_t count)
533{
534 unsigned char *p;
535
536 p = s3c_get_bufferram(mtd, area);
537 memcpy(p + offset, buffer, count);
538 return 0;
539}
540
e23abf4b
KP
541static int (*s5pc110_dma_ops)(void *dst, void *src, size_t count, int direction);
542
543static int s5pc110_dma_poll(void *dst, void *src, size_t count, int direction)
46f3e88b
KP
544{
545 void __iomem *base = onenand->dma_addr;
546 int status;
ebe8a642 547 unsigned long timeout;
46f3e88b
KP
548
549 writel(src, base + S5PC110_DMA_SRC_ADDR);
550 writel(dst, base + S5PC110_DMA_DST_ADDR);
551
552 if (direction == S5PC110_DMA_DIR_READ) {
553 writel(S5PC110_DMA_SRC_CFG_READ, base + S5PC110_DMA_SRC_CFG);
554 writel(S5PC110_DMA_DST_CFG_READ, base + S5PC110_DMA_DST_CFG);
555 } else {
556 writel(S5PC110_DMA_SRC_CFG_WRITE, base + S5PC110_DMA_SRC_CFG);
557 writel(S5PC110_DMA_DST_CFG_WRITE, base + S5PC110_DMA_DST_CFG);
558 }
559
560 writel(count, base + S5PC110_DMA_TRANS_SIZE);
561 writel(direction, base + S5PC110_DMA_TRANS_DIR);
562
563 writel(S5PC110_DMA_TRANS_CMD_TR, base + S5PC110_DMA_TRANS_CMD);
564
ebe8a642
KP
565 /*
566 * There's no exact timeout values at Spec.
567 * In real case it takes under 1 msec.
568 * So 20 msecs are enough.
569 */
570 timeout = jiffies + msecs_to_jiffies(20);
571
46f3e88b
KP
572 do {
573 status = readl(base + S5PC110_DMA_TRANS_STATUS);
53d1e137
KP
574 if (status & S5PC110_DMA_TRANS_STATUS_TE) {
575 writel(S5PC110_DMA_TRANS_CMD_TEC,
576 base + S5PC110_DMA_TRANS_CMD);
577 return -EIO;
578 }
ebe8a642
KP
579 } while (!(status & S5PC110_DMA_TRANS_STATUS_TD) &&
580 time_before(jiffies, timeout));
46f3e88b 581
46f3e88b
KP
582 writel(S5PC110_DMA_TRANS_CMD_TDC, base + S5PC110_DMA_TRANS_CMD);
583
584 return 0;
585}
586
e23abf4b
KP
587static irqreturn_t s5pc110_onenand_irq(int irq, void *data)
588{
589 void __iomem *base = onenand->dma_addr;
590 int status, cmd = 0;
591
592 status = readl(base + S5PC110_INTC_DMA_STATUS);
593
594 if (likely(status & S5PC110_INTC_DMA_TD))
595 cmd = S5PC110_DMA_TRANS_CMD_TDC;
596
597 if (unlikely(status & S5PC110_INTC_DMA_TE))
598 cmd = S5PC110_DMA_TRANS_CMD_TEC;
599
600 writel(cmd, base + S5PC110_DMA_TRANS_CMD);
601 writel(status, base + S5PC110_INTC_DMA_CLR);
602
603 if (!onenand->complete.done)
604 complete(&onenand->complete);
605
606 return IRQ_HANDLED;
607}
608
609static int s5pc110_dma_irq(void *dst, void *src, size_t count, int direction)
610{
611 void __iomem *base = onenand->dma_addr;
612 int status;
613
614 status = readl(base + S5PC110_INTC_DMA_MASK);
615 if (status) {
616 status &= ~(S5PC110_INTC_DMA_TD | S5PC110_INTC_DMA_TE);
617 writel(status, base + S5PC110_INTC_DMA_MASK);
618 }
619
620 writel(src, base + S5PC110_DMA_SRC_ADDR);
621 writel(dst, base + S5PC110_DMA_DST_ADDR);
622
623 if (direction == S5PC110_DMA_DIR_READ) {
624 writel(S5PC110_DMA_SRC_CFG_READ, base + S5PC110_DMA_SRC_CFG);
625 writel(S5PC110_DMA_DST_CFG_READ, base + S5PC110_DMA_DST_CFG);
626 } else {
627 writel(S5PC110_DMA_SRC_CFG_WRITE, base + S5PC110_DMA_SRC_CFG);
628 writel(S5PC110_DMA_DST_CFG_WRITE, base + S5PC110_DMA_DST_CFG);
629 }
630
631 writel(count, base + S5PC110_DMA_TRANS_SIZE);
632 writel(direction, base + S5PC110_DMA_TRANS_DIR);
633
634 writel(S5PC110_DMA_TRANS_CMD_TR, base + S5PC110_DMA_TRANS_CMD);
635
636 wait_for_completion_timeout(&onenand->complete, msecs_to_jiffies(20));
637
638 return 0;
639}
640
46f3e88b
KP
641static int s5pc110_read_bufferram(struct mtd_info *mtd, int area,
642 unsigned char *buffer, int offset, size_t count)
643{
644 struct onenand_chip *this = mtd->priv;
46f3e88b
KP
645 void __iomem *p;
646 void *buf = (void *) buffer;
647 dma_addr_t dma_src, dma_dst;
08b3af30 648 int err, ofs, page_dma = 0;
dcf08227 649 struct device *dev = &onenand->pdev->dev;
46f3e88b 650
9aba97ad 651 p = this->base + area;
46f3e88b
KP
652 if (ONENAND_CURRENT_BUFFERRAM(this)) {
653 if (area == ONENAND_DATARAM)
654 p += this->writesize;
655 else
656 p += mtd->oobsize;
657 }
658
659 if (offset & 3 || (size_t) buf & 3 ||
660 !onenand->dma_addr || count != mtd->writesize)
661 goto normal;
662
663 /* Handle vmalloc address */
664 if (buf >= high_memory) {
665 struct page *page;
666
667 if (((size_t) buf & PAGE_MASK) !=
668 ((size_t) (buf + count - 1) & PAGE_MASK))
669 goto normal;
670 page = vmalloc_to_page(buf);
671 if (!page)
672 goto normal;
46f3e88b 673
08b3af30
KP
674 /* Page offset */
675 ofs = ((size_t) buf & ~PAGE_MASK);
dcf08227 676 page_dma = 1;
08b3af30 677
dcf08227
KP
678 /* DMA routine */
679 dma_src = onenand->phys_base + (p - this->base);
08b3af30 680 dma_dst = dma_map_page(dev, page, ofs, count, DMA_FROM_DEVICE);
dcf08227
KP
681 } else {
682 /* DMA routine */
683 dma_src = onenand->phys_base + (p - this->base);
684 dma_dst = dma_map_single(dev, buf, count, DMA_FROM_DEVICE);
685 }
686 if (dma_mapping_error(dev, dma_dst)) {
687 dev_err(dev, "Couldn't map a %d byte buffer for DMA\n", count);
46f3e88b
KP
688 goto normal;
689 }
690 err = s5pc110_dma_ops((void *) dma_dst, (void *) dma_src,
691 count, S5PC110_DMA_DIR_READ);
dcf08227
KP
692
693 if (page_dma)
694 dma_unmap_page(dev, dma_dst, count, DMA_FROM_DEVICE);
695 else
696 dma_unmap_single(dev, dma_dst, count, DMA_FROM_DEVICE);
46f3e88b
KP
697
698 if (!err)
699 return 0;
700
701normal:
702 if (count != mtd->writesize) {
703 /* Copy the bufferram to memory to prevent unaligned access */
9aba97ad 704 memcpy(this->page_buf, p, mtd->writesize);
46f3e88b
KP
705 p = this->page_buf + offset;
706 }
707
708 memcpy(buffer, p, count);
709
710 return 0;
711}
712
7b0507eb
KP
713static int s5pc110_chip_probe(struct mtd_info *mtd)
714{
715 /* Now just return 0 */
716 return 0;
717}
718
46f3e88b
KP
719static int s3c_onenand_bbt_wait(struct mtd_info *mtd, int state)
720{
721 unsigned int flags = INT_ACT | LOAD_CMP;
722 unsigned int stat;
723 unsigned long timeout;
724
725 /* The 20 msec is enough */
726 timeout = jiffies + msecs_to_jiffies(20);
727 while (time_before(jiffies, timeout)) {
728 stat = s3c_read_reg(INT_ERR_STAT_OFFSET);
729 if (stat & flags)
730 break;
731 }
732 /* To get correct interrupt status in timeout case */
733 stat = s3c_read_reg(INT_ERR_STAT_OFFSET);
734 s3c_write_reg(stat, INT_ERR_ACK_OFFSET);
735
736 if (stat & LD_FAIL_ECC_ERR) {
737 s3c_onenand_reset();
738 return ONENAND_BBT_READ_ERROR;
739 }
740
741 if (stat & LOAD_CMP) {
742 int ecc = s3c_read_reg(ECC_ERR_STAT_OFFSET);
743 if (ecc & ONENAND_ECC_4BIT_UNCORRECTABLE) {
744 s3c_onenand_reset();
745 return ONENAND_BBT_READ_ERROR;
746 }
747 }
748
749 return 0;
750}
751
752static void s3c_onenand_check_lock_status(struct mtd_info *mtd)
753{
754 struct onenand_chip *this = mtd->priv;
755 struct device *dev = &onenand->pdev->dev;
756 unsigned int block, end;
757 int tmp;
758
759 end = this->chipsize >> this->erase_shift;
760
761 for (block = 0; block < end; block++) {
762 unsigned int mem_addr = onenand->mem_addr(block, 0, 0);
763 tmp = s3c_read_cmd(CMD_MAP_01(onenand, mem_addr));
764
765 if (s3c_read_reg(INT_ERR_STAT_OFFSET) & LOCKED_BLK) {
766 dev_err(dev, "block %d is write-protected!\n", block);
767 s3c_write_reg(LOCKED_BLK, INT_ERR_ACK_OFFSET);
768 }
769 }
770}
771
772static void s3c_onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs,
773 size_t len, int cmd)
774{
775 struct onenand_chip *this = mtd->priv;
776 int start, end, start_mem_addr, end_mem_addr;
777
778 start = ofs >> this->erase_shift;
779 start_mem_addr = onenand->mem_addr(start, 0, 0);
780 end = start + (len >> this->erase_shift) - 1;
781 end_mem_addr = onenand->mem_addr(end, 0, 0);
782
783 if (cmd == ONENAND_CMD_LOCK) {
784 s3c_write_cmd(ONENAND_LOCK_START, CMD_MAP_10(onenand,
785 start_mem_addr));
786 s3c_write_cmd(ONENAND_LOCK_END, CMD_MAP_10(onenand,
787 end_mem_addr));
788 } else {
789 s3c_write_cmd(ONENAND_UNLOCK_START, CMD_MAP_10(onenand,
790 start_mem_addr));
791 s3c_write_cmd(ONENAND_UNLOCK_END, CMD_MAP_10(onenand,
792 end_mem_addr));
793 }
794
795 this->wait(mtd, FL_LOCKING);
796}
797
798static void s3c_unlock_all(struct mtd_info *mtd)
799{
800 struct onenand_chip *this = mtd->priv;
801 loff_t ofs = 0;
802 size_t len = this->chipsize;
803
804 if (this->options & ONENAND_HAS_UNLOCK_ALL) {
805 /* Write unlock command */
806 this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0);
807
808 /* No need to check return value */
809 this->wait(mtd, FL_LOCKING);
810
811 /* Workaround for all block unlock in DDP */
812 if (!ONENAND_IS_DDP(this)) {
813 s3c_onenand_check_lock_status(mtd);
814 return;
815 }
816
817 /* All blocks on another chip */
818 ofs = this->chipsize >> 1;
819 len = this->chipsize >> 1;
820 }
821
822 s3c_onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
823
824 s3c_onenand_check_lock_status(mtd);
825}
826
827static void s3c_onenand_setup(struct mtd_info *mtd)
828{
829 struct onenand_chip *this = mtd->priv;
830
831 onenand->mtd = mtd;
832
833 if (onenand->type == TYPE_S3C6400) {
834 onenand->mem_addr = s3c6400_mem_addr;
835 onenand->cmd_map = s3c64xx_cmd_map;
836 } else if (onenand->type == TYPE_S3C6410) {
837 onenand->mem_addr = s3c6410_mem_addr;
838 onenand->cmd_map = s3c64xx_cmd_map;
839 } else if (onenand->type == TYPE_S5PC100) {
840 onenand->mem_addr = s5pc100_mem_addr;
841 onenand->cmd_map = s5pc1xx_cmd_map;
842 } else if (onenand->type == TYPE_S5PC110) {
843 /* Use generic onenand functions */
46f3e88b 844 this->read_bufferram = s5pc110_read_bufferram;
7b0507eb 845 this->chip_probe = s5pc110_chip_probe;
46f3e88b
KP
846 return;
847 } else {
848 BUG();
849 }
850
851 this->read_word = s3c_onenand_readw;
852 this->write_word = s3c_onenand_writew;
853
854 this->wait = s3c_onenand_wait;
855 this->bbt_wait = s3c_onenand_bbt_wait;
856 this->unlock_all = s3c_unlock_all;
857 this->command = s3c_onenand_command;
858
859 this->read_bufferram = onenand_read_bufferram;
860 this->write_bufferram = onenand_write_bufferram;
861}
862
863static int s3c_onenand_probe(struct platform_device *pdev)
864{
865 struct onenand_platform_data *pdata;
866 struct onenand_chip *this;
867 struct mtd_info *mtd;
868 struct resource *r;
869 int size, err;
46f3e88b
KP
870
871 pdata = pdev->dev.platform_data;
872 /* No need to check pdata. the platform data is optional */
873
874 size = sizeof(struct mtd_info) + sizeof(struct onenand_chip);
875 mtd = kzalloc(size, GFP_KERNEL);
876 if (!mtd) {
877 dev_err(&pdev->dev, "failed to allocate memory\n");
878 return -ENOMEM;
879 }
880
881 onenand = kzalloc(sizeof(struct s3c_onenand), GFP_KERNEL);
882 if (!onenand) {
883 err = -ENOMEM;
884 goto onenand_fail;
885 }
886
887 this = (struct onenand_chip *) &mtd[1];
888 mtd->priv = this;
889 mtd->dev.parent = &pdev->dev;
890 mtd->owner = THIS_MODULE;
891 onenand->pdev = pdev;
892 onenand->type = platform_get_device_id(pdev)->driver_data;
893
894 s3c_onenand_setup(mtd);
895
896 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
897 if (!r) {
898 dev_err(&pdev->dev, "no memory resource defined\n");
899 return -ENOENT;
900 goto ahb_resource_failed;
901 }
902
903 onenand->base_res = request_mem_region(r->start, resource_size(r),
904 pdev->name);
905 if (!onenand->base_res) {
906 dev_err(&pdev->dev, "failed to request memory resource\n");
907 err = -EBUSY;
908 goto resource_failed;
909 }
910
911 onenand->base = ioremap(r->start, resource_size(r));
912 if (!onenand->base) {
913 dev_err(&pdev->dev, "failed to map memory resource\n");
914 err = -EFAULT;
915 goto ioremap_failed;
916 }
917 /* Set onenand_chip also */
918 this->base = onenand->base;
919
920 /* Use runtime badblock check */
921 this->options |= ONENAND_SKIP_UNLOCK_CHECK;
922
923 if (onenand->type != TYPE_S5PC110) {
924 r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
925 if (!r) {
926 dev_err(&pdev->dev, "no buffer memory resource defined\n");
927 return -ENOENT;
928 goto ahb_resource_failed;
929 }
930
931 onenand->ahb_res = request_mem_region(r->start, resource_size(r),
932 pdev->name);
933 if (!onenand->ahb_res) {
934 dev_err(&pdev->dev, "failed to request buffer memory resource\n");
935 err = -EBUSY;
936 goto ahb_resource_failed;
937 }
938
939 onenand->ahb_addr = ioremap(r->start, resource_size(r));
940 if (!onenand->ahb_addr) {
941 dev_err(&pdev->dev, "failed to map buffer memory resource\n");
942 err = -EINVAL;
943 goto ahb_ioremap_failed;
944 }
945
946 /* Allocate 4KiB BufferRAM */
947 onenand->page_buf = kzalloc(SZ_4K, GFP_KERNEL);
948 if (!onenand->page_buf) {
949 err = -ENOMEM;
950 goto page_buf_fail;
951 }
952
953 /* Allocate 128 SpareRAM */
954 onenand->oob_buf = kzalloc(128, GFP_KERNEL);
955 if (!onenand->oob_buf) {
956 err = -ENOMEM;
957 goto oob_buf_fail;
958 }
959
960 /* S3C doesn't handle subpage write */
961 mtd->subpage_sft = 0;
962 this->subpagesize = mtd->writesize;
963
964 } else { /* S5PC110 */
965 r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
966 if (!r) {
967 dev_err(&pdev->dev, "no dma memory resource defined\n");
968 return -ENOENT;
969 goto dma_resource_failed;
970 }
971
972 onenand->dma_res = request_mem_region(r->start, resource_size(r),
973 pdev->name);
974 if (!onenand->dma_res) {
975 dev_err(&pdev->dev, "failed to request dma memory resource\n");
976 err = -EBUSY;
977 goto dma_resource_failed;
978 }
979
980 onenand->dma_addr = ioremap(r->start, resource_size(r));
981 if (!onenand->dma_addr) {
982 dev_err(&pdev->dev, "failed to map dma memory resource\n");
983 err = -EINVAL;
984 goto dma_ioremap_failed;
985 }
986
987 onenand->phys_base = onenand->base_res->start;
e23abf4b
KP
988
989 s5pc110_dma_ops = s5pc110_dma_poll;
990 /* Interrupt support */
991 r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
992 if (r) {
993 init_completion(&onenand->complete);
994 s5pc110_dma_ops = s5pc110_dma_irq;
995 err = request_irq(r->start, s5pc110_onenand_irq,
996 IRQF_SHARED, "onenand", &onenand);
997 if (err) {
998 dev_err(&pdev->dev, "failed to get irq\n");
999 goto scan_failed;
1000 }
1001 }
46f3e88b
KP
1002 }
1003
1004 if (onenand_scan(mtd, 1)) {
1005 err = -EFAULT;
1006 goto scan_failed;
1007 }
1008
7b0507eb 1009 if (onenand->type != TYPE_S5PC110) {
46f3e88b
KP
1010 /* S3C doesn't handle subpage write */
1011 mtd->subpage_sft = 0;
1012 this->subpagesize = mtd->writesize;
1013 }
1014
1015 if (s3c_read_reg(MEM_CFG_OFFSET) & ONENAND_SYS_CFG1_SYNC_READ)
1016 dev_info(&onenand->pdev->dev, "OneNAND Sync. Burst Read enabled\n");
1017
18f8eb1b 1018 err = parse_mtd_partitions(mtd, NULL, &onenand->parts, 0);
46f3e88b 1019 if (err > 0)
6b57c116 1020 mtd_device_register(mtd, onenand->parts, err);
46f3e88b 1021 else if (err <= 0 && pdata && pdata->parts)
6b57c116 1022 mtd_device_register(mtd, pdata->parts, pdata->nr_parts);
46f3e88b 1023 else
6b57c116 1024 err = mtd_device_register(mtd, NULL, 0);
46f3e88b
KP
1025
1026 platform_set_drvdata(pdev, mtd);
1027
1028 return 0;
1029
1030scan_failed:
1031 if (onenand->dma_addr)
1032 iounmap(onenand->dma_addr);
1033dma_ioremap_failed:
1034 if (onenand->dma_res)
1035 release_mem_region(onenand->dma_res->start,
1036 resource_size(onenand->dma_res));
1037 kfree(onenand->oob_buf);
1038oob_buf_fail:
1039 kfree(onenand->page_buf);
1040page_buf_fail:
1041 if (onenand->ahb_addr)
1042 iounmap(onenand->ahb_addr);
1043ahb_ioremap_failed:
1044 if (onenand->ahb_res)
1045 release_mem_region(onenand->ahb_res->start,
1046 resource_size(onenand->ahb_res));
1047dma_resource_failed:
1048ahb_resource_failed:
1049 iounmap(onenand->base);
1050ioremap_failed:
1051 if (onenand->base_res)
1052 release_mem_region(onenand->base_res->start,
1053 resource_size(onenand->base_res));
1054resource_failed:
1055 kfree(onenand);
1056onenand_fail:
1057 kfree(mtd);
1058 return err;
1059}
1060
1061static int __devexit s3c_onenand_remove(struct platform_device *pdev)
1062{
1063 struct mtd_info *mtd = platform_get_drvdata(pdev);
1064
1065 onenand_release(mtd);
1066 if (onenand->ahb_addr)
1067 iounmap(onenand->ahb_addr);
1068 if (onenand->ahb_res)
1069 release_mem_region(onenand->ahb_res->start,
1070 resource_size(onenand->ahb_res));
1071 if (onenand->dma_addr)
1072 iounmap(onenand->dma_addr);
1073 if (onenand->dma_res)
1074 release_mem_region(onenand->dma_res->start,
1075 resource_size(onenand->dma_res));
1076
1077 iounmap(onenand->base);
1078 release_mem_region(onenand->base_res->start,
1079 resource_size(onenand->base_res));
1080
1081 platform_set_drvdata(pdev, NULL);
1082 kfree(onenand->oob_buf);
1083 kfree(onenand->page_buf);
1084 kfree(onenand);
1085 kfree(mtd);
1086 return 0;
1087}
1088
1089static int s3c_pm_ops_suspend(struct device *dev)
1090{
1091 struct platform_device *pdev = to_platform_device(dev);
1092 struct mtd_info *mtd = platform_get_drvdata(pdev);
1093 struct onenand_chip *this = mtd->priv;
1094
1095 this->wait(mtd, FL_PM_SUSPENDED);
2316d3bc 1096 return 0;
46f3e88b
KP
1097}
1098
1099static int s3c_pm_ops_resume(struct device *dev)
1100{
1101 struct platform_device *pdev = to_platform_device(dev);
1102 struct mtd_info *mtd = platform_get_drvdata(pdev);
1103 struct onenand_chip *this = mtd->priv;
1104
46f3e88b
KP
1105 this->unlock_all(mtd);
1106 return 0;
1107}
1108
1109static const struct dev_pm_ops s3c_pm_ops = {
1110 .suspend = s3c_pm_ops_suspend,
1111 .resume = s3c_pm_ops_resume,
1112};
1113
1114static struct platform_device_id s3c_onenand_driver_ids[] = {
1115 {
1116 .name = "s3c6400-onenand",
1117 .driver_data = TYPE_S3C6400,
1118 }, {
1119 .name = "s3c6410-onenand",
1120 .driver_data = TYPE_S3C6410,
1121 }, {
1122 .name = "s5pc100-onenand",
1123 .driver_data = TYPE_S5PC100,
1124 }, {
1125 .name = "s5pc110-onenand",
1126 .driver_data = TYPE_S5PC110,
1127 }, { },
1128};
1129MODULE_DEVICE_TABLE(platform, s3c_onenand_driver_ids);
1130
1131static struct platform_driver s3c_onenand_driver = {
1132 .driver = {
1133 .name = "samsung-onenand",
1134 .pm = &s3c_pm_ops,
1135 },
1136 .id_table = s3c_onenand_driver_ids,
1137 .probe = s3c_onenand_probe,
1138 .remove = __devexit_p(s3c_onenand_remove),
1139};
1140
1141static int __init s3c_onenand_init(void)
1142{
1143 return platform_driver_register(&s3c_onenand_driver);
1144}
1145
1146static void __exit s3c_onenand_exit(void)
1147{
1148 platform_driver_unregister(&s3c_onenand_driver);
1149}
1150
1151module_init(s3c_onenand_init);
1152module_exit(s3c_onenand_exit);
1153
1154MODULE_LICENSE("GPL");
1155MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
1156MODULE_DESCRIPTION("Samsung OneNAND controller support");
This page took 0.131284 seconds and 5 git commands to generate.