2 * S5PC100 OneNAND driver at U-Boot
4 * Copyright (C) 2008-2009 Samsung Electronics
5 * Kyungmin Park <kyungmin.park@samsung.com>
8 * Emulate the pseudo BufferRAM
10 * SPDX-License-Identifier: GPL-2.0+
15 #include <linux/compat.h>
16 #include <linux/mtd/mtd.h>
17 #include <linux/mtd/onenand.h>
18 #include <linux/mtd/samsung_onenand.h>
21 #include <asm/errno.h>
24 #define DPRINTK(format, args...) \
26 printf("%s[%d]: " format "\n", __func__, __LINE__, ##args); \
29 #define DPRINTK(...) do { } while (0)
32 #define ONENAND_ERASE_STATUS 0x00
33 #define ONENAND_MULTI_ERASE_SET 0x01
34 #define ONENAND_ERASE_START 0x03
35 #define ONENAND_UNLOCK_START 0x08
36 #define ONENAND_UNLOCK_END 0x09
37 #define ONENAND_LOCK_START 0x0A
38 #define ONENAND_LOCK_END 0x0B
39 #define ONENAND_LOCK_TIGHT_START 0x0C
40 #define ONENAND_LOCK_TIGHT_END 0x0D
41 #define ONENAND_UNLOCK_ALL 0x0E
42 #define ONENAND_OTP_ACCESS 0x12
43 #define ONENAND_SPARE_ACCESS_ONLY 0x13
44 #define ONENAND_MAIN_ACCESS_ONLY 0x14
45 #define ONENAND_ERASE_VERIFY 0x15
46 #define ONENAND_MAIN_SPARE_ACCESS 0x16
47 #define ONENAND_PIPELINE_READ 0x4000
49 #if defined(CONFIG_S5P)
50 #define MAP_00 (0x0 << 26)
51 #define MAP_01 (0x1 << 26)
52 #define MAP_10 (0x2 << 26)
53 #define MAP_11 (0x3 << 26)
56 /* read/write of XIP buffer */
57 #define CMD_MAP_00(mem_addr) (MAP_00 | ((mem_addr) << 1))
58 /* read/write to the memory device */
59 #define CMD_MAP_01(mem_addr) (MAP_01 | (mem_addr))
60 /* control special functions of the memory device */
61 #define CMD_MAP_10(mem_addr) (MAP_10 | (mem_addr))
62 /* direct interface(direct access) with the memory device */
63 #define CMD_MAP_11(mem_addr) (MAP_11 | ((mem_addr) << 2))
68 void __iomem
*ahb_addr
;
70 void __iomem
*page_buf
;
71 void __iomem
*oob_buf
;
72 unsigned int (*mem_addr
)(int fba
, int fpa
, int fsa
);
73 struct samsung_onenand
*reg
;
76 static struct s3c_onenand
*onenand
;
78 static int s3c_read_cmd(unsigned int cmd
)
80 return readl(onenand
->ahb_addr
+ cmd
);
83 static void s3c_write_cmd(int value
, unsigned int cmd
)
85 writel(value
, onenand
->ahb_addr
+ cmd
);
91 * fba: flash block address
92 * fpa: flash page address
93 * fsa: flash sector address
95 * return the buffer address on the memory device
96 * It will be combined with CMD_MAP_XX
98 #if defined(CONFIG_S5P)
99 static unsigned int s3c_mem_addr(int fba
, int fpa
, int fsa
)
101 return (fba
<< 13) | (fpa
<< 7) | (fsa
<< 5);
105 static void s3c_onenand_reset(void)
107 unsigned long timeout
= 0x10000;
110 writel(ONENAND_MEM_RESET_COLD
, &onenand
->reg
->mem_reset
);
112 stat
= readl(&onenand
->reg
->int_err_stat
);
116 stat
= readl(&onenand
->reg
->int_err_stat
);
117 writel(stat
, &onenand
->reg
->int_err_ack
);
119 /* Clear interrupt */
120 writel(0x0, &onenand
->reg
->int_err_ack
);
121 /* Clear the ECC status */
122 writel(0x0, &onenand
->reg
->ecc_err_stat
);
125 static unsigned short s3c_onenand_readw(void __iomem
*addr
)
127 struct onenand_chip
*this = onenand
->mtd
->priv
;
128 int reg
= addr
- this->base
;
129 int word_addr
= reg
>> 1;
132 /* It's used for probing time */
134 case ONENAND_REG_MANUFACTURER_ID
:
135 return readl(&onenand
->reg
->manufact_id
);
136 case ONENAND_REG_DEVICE_ID
:
137 return readl(&onenand
->reg
->device_id
);
138 case ONENAND_REG_VERSION_ID
:
139 return readl(&onenand
->reg
->flash_ver_id
);
140 case ONENAND_REG_DATA_BUFFER_SIZE
:
141 return readl(&onenand
->reg
->data_buf_size
);
142 case ONENAND_REG_TECHNOLOGY
:
143 return readl(&onenand
->reg
->tech
);
144 case ONENAND_REG_SYS_CFG1
:
145 return readl(&onenand
->reg
->mem_cfg
);
147 /* Used at unlock all status */
148 case ONENAND_REG_CTRL_STATUS
:
151 case ONENAND_REG_WP_STATUS
:
152 return ONENAND_WP_US
;
158 /* BootRAM access control */
159 if (reg
< ONENAND_DATARAM
&& onenand
->bootram_command
) {
161 return readl(&onenand
->reg
->manufact_id
);
163 return readl(&onenand
->reg
->device_id
);
165 return readl(&onenand
->reg
->flash_ver_id
);
168 value
= s3c_read_cmd(CMD_MAP_11(word_addr
)) & 0xffff;
169 printk(KERN_INFO
"s3c_onenand_readw: Illegal access"
170 " at reg 0x%x, value 0x%x\n", word_addr
, value
);
174 static void s3c_onenand_writew(unsigned short value
, void __iomem
*addr
)
176 struct onenand_chip
*this = onenand
->mtd
->priv
;
177 int reg
= addr
- this->base
;
178 int word_addr
= reg
>> 1;
180 /* It's used for probing time */
182 case ONENAND_REG_SYS_CFG1
:
183 writel(value
, &onenand
->reg
->mem_cfg
);
186 case ONENAND_REG_START_ADDRESS1
:
187 case ONENAND_REG_START_ADDRESS2
:
190 /* Lock/lock-tight/unlock/unlock_all */
191 case ONENAND_REG_START_BLOCK_ADDRESS
:
198 /* BootRAM access control */
199 if (reg
< ONENAND_DATARAM
) {
200 if (value
== ONENAND_CMD_READID
) {
201 onenand
->bootram_command
= 1;
204 if (value
== ONENAND_CMD_RESET
) {
205 writel(ONENAND_MEM_RESET_COLD
,
206 &onenand
->reg
->mem_reset
);
207 onenand
->bootram_command
= 0;
212 printk(KERN_INFO
"s3c_onenand_writew: Illegal access"
213 " at reg 0x%x, value 0x%x\n", word_addr
, value
);
215 s3c_write_cmd(value
, CMD_MAP_11(word_addr
));
218 static int s3c_onenand_wait(struct mtd_info
*mtd
, int state
)
220 unsigned int flags
= INT_ACT
;
221 unsigned int stat
, ecc
;
222 unsigned long timeout
= 0x100000;
226 flags
|= BLK_RW_CMP
| LOAD_CMP
;
229 flags
|= BLK_RW_CMP
| PGM_CMP
;
232 flags
|= BLK_RW_CMP
| ERS_CMP
;
242 stat
= readl(&onenand
->reg
->int_err_stat
);
247 /* To get correct interrupt status in timeout case */
248 stat
= readl(&onenand
->reg
->int_err_stat
);
249 writel(stat
, &onenand
->reg
->int_err_ack
);
252 * In the Spec. it checks the controller status first
253 * However if you get the correct information in case of
254 * power off recovery (POR) test, it should read ECC status first
256 if (stat
& LOAD_CMP
) {
257 ecc
= readl(&onenand
->reg
->ecc_err_stat
);
258 if (ecc
& ONENAND_ECC_4BIT_UNCORRECTABLE
) {
259 printk(KERN_INFO
"%s: ECC error = 0x%04x\n",
261 mtd
->ecc_stats
.failed
++;
266 if (stat
& (LOCKED_BLK
| ERS_FAIL
| PGM_FAIL
| LD_FAIL_ECC_ERR
)) {
267 printk(KERN_INFO
"%s: controller error = 0x%04x\n",
269 if (stat
& LOCKED_BLK
)
270 printk(KERN_INFO
"%s: it's locked error = 0x%04x\n",
279 static int s3c_onenand_command(struct mtd_info
*mtd
, int cmd
,
280 loff_t addr
, size_t len
)
282 struct onenand_chip
*this = mtd
->priv
;
284 int fba
, fpa
, fsa
= 0;
285 unsigned int mem_addr
;
286 int i
, mcount
, scount
;
289 fba
= (int) (addr
>> this->erase_shift
);
290 fpa
= (int) (addr
>> this->page_shift
);
291 fpa
&= this->page_mask
;
293 mem_addr
= onenand
->mem_addr(fba
, fpa
, fsa
);
296 case ONENAND_CMD_READ
:
297 case ONENAND_CMD_READOOB
:
298 case ONENAND_CMD_BUFFERRAM
:
299 ONENAND_SET_NEXT_BUFFERRAM(this);
304 index
= ONENAND_CURRENT_BUFFERRAM(this);
307 * Emulate Two BufferRAMs and access with 4 bytes pointer
309 m
= (unsigned int *) onenand
->page_buf
;
310 s
= (unsigned int *) onenand
->oob_buf
;
313 m
+= (this->writesize
>> 2);
314 s
+= (mtd
->oobsize
>> 2);
317 mcount
= mtd
->writesize
>> 2;
318 scount
= mtd
->oobsize
>> 2;
321 case ONENAND_CMD_READ
:
323 for (i
= 0; i
< mcount
; i
++)
324 *m
++ = s3c_read_cmd(CMD_MAP_01(mem_addr
));
327 case ONENAND_CMD_READOOB
:
328 writel(TSRF
, &onenand
->reg
->trans_spare
);
330 for (i
= 0; i
< mcount
; i
++)
331 *m
++ = s3c_read_cmd(CMD_MAP_01(mem_addr
));
334 for (i
= 0; i
< scount
; i
++)
335 *s
++ = s3c_read_cmd(CMD_MAP_01(mem_addr
));
337 writel(0, &onenand
->reg
->trans_spare
);
340 case ONENAND_CMD_PROG
:
342 for (i
= 0; i
< mcount
; i
++)
343 s3c_write_cmd(*m
++, CMD_MAP_01(mem_addr
));
346 case ONENAND_CMD_PROGOOB
:
347 writel(TSRF
, &onenand
->reg
->trans_spare
);
349 /* Main - dummy write */
350 for (i
= 0; i
< mcount
; i
++)
351 s3c_write_cmd(0xffffffff, CMD_MAP_01(mem_addr
));
354 for (i
= 0; i
< scount
; i
++)
355 s3c_write_cmd(*s
++, CMD_MAP_01(mem_addr
));
357 writel(0, &onenand
->reg
->trans_spare
);
360 case ONENAND_CMD_UNLOCK_ALL
:
361 s3c_write_cmd(ONENAND_UNLOCK_ALL
, CMD_MAP_10(mem_addr
));
364 case ONENAND_CMD_ERASE
:
365 s3c_write_cmd(ONENAND_ERASE_START
, CMD_MAP_10(mem_addr
));
368 case ONENAND_CMD_MULTIBLOCK_ERASE
:
369 s3c_write_cmd(ONENAND_MULTI_ERASE_SET
, CMD_MAP_10(mem_addr
));
372 case ONENAND_CMD_ERASE_VERIFY
:
373 s3c_write_cmd(ONENAND_ERASE_VERIFY
, CMD_MAP_10(mem_addr
));
383 static unsigned char *s3c_get_bufferram(struct mtd_info
*mtd
, int area
)
385 struct onenand_chip
*this = mtd
->priv
;
386 int index
= ONENAND_CURRENT_BUFFERRAM(this);
389 if (area
== ONENAND_DATARAM
) {
390 p
= (unsigned char *) onenand
->page_buf
;
392 p
+= this->writesize
;
394 p
= (unsigned char *) onenand
->oob_buf
;
402 static int onenand_read_bufferram(struct mtd_info
*mtd
, loff_t addr
, int area
,
403 unsigned char *buffer
, int offset
,
408 p
= s3c_get_bufferram(mtd
, area
);
409 memcpy(buffer
, p
+ offset
, count
);
413 static int onenand_write_bufferram(struct mtd_info
*mtd
, loff_t addr
, int area
,
414 const unsigned char *buffer
, int offset
,
419 p
= s3c_get_bufferram(mtd
, area
);
420 memcpy(p
+ offset
, buffer
, count
);
424 static int s3c_onenand_bbt_wait(struct mtd_info
*mtd
, int state
)
426 struct samsung_onenand
*reg
= (struct samsung_onenand
*)onenand
->base
;
427 unsigned int flags
= INT_ACT
| LOAD_CMP
;
429 unsigned long timeout
= 0x10000;
432 stat
= readl(®
->int_err_stat
);
436 /* To get correct interrupt status in timeout case */
437 stat
= readl(&onenand
->reg
->int_err_stat
);
438 writel(stat
, &onenand
->reg
->int_err_ack
);
440 if (stat
& LD_FAIL_ECC_ERR
) {
442 return ONENAND_BBT_READ_ERROR
;
445 if (stat
& LOAD_CMP
) {
446 int ecc
= readl(&onenand
->reg
->ecc_err_stat
);
447 if (ecc
& ONENAND_ECC_4BIT_UNCORRECTABLE
) {
449 return ONENAND_BBT_READ_ERROR
;
456 static void s3c_onenand_check_lock_status(struct mtd_info
*mtd
)
458 struct onenand_chip
*this = mtd
->priv
;
459 unsigned int block
, end
;
461 end
= this->chipsize
>> this->erase_shift
;
463 for (block
= 0; block
< end
; block
++) {
464 s3c_read_cmd(CMD_MAP_01(onenand
->mem_addr(block
, 0, 0)));
466 if (readl(&onenand
->reg
->int_err_stat
) & LOCKED_BLK
) {
467 printf("block %d is write-protected!\n", block
);
468 writel(LOCKED_BLK
, &onenand
->reg
->int_err_ack
);
473 static void s3c_onenand_do_lock_cmd(struct mtd_info
*mtd
, loff_t ofs
,
476 struct onenand_chip
*this = mtd
->priv
;
477 int start
, end
, start_mem_addr
, end_mem_addr
;
479 start
= ofs
>> this->erase_shift
;
480 start_mem_addr
= onenand
->mem_addr(start
, 0, 0);
481 end
= start
+ (len
>> this->erase_shift
) - 1;
482 end_mem_addr
= onenand
->mem_addr(end
, 0, 0);
484 if (cmd
== ONENAND_CMD_LOCK
) {
485 s3c_write_cmd(ONENAND_LOCK_START
, CMD_MAP_10(start_mem_addr
));
486 s3c_write_cmd(ONENAND_LOCK_END
, CMD_MAP_10(end_mem_addr
));
488 s3c_write_cmd(ONENAND_UNLOCK_START
, CMD_MAP_10(start_mem_addr
));
489 s3c_write_cmd(ONENAND_UNLOCK_END
, CMD_MAP_10(end_mem_addr
));
492 this->wait(mtd
, FL_LOCKING
);
495 static void s3c_onenand_unlock_all(struct mtd_info
*mtd
)
497 struct onenand_chip
*this = mtd
->priv
;
499 size_t len
= this->chipsize
;
501 /* FIXME workaround */
502 this->subpagesize
= mtd
->writesize
;
503 mtd
->subpage_sft
= 0;
505 if (this->options
& ONENAND_HAS_UNLOCK_ALL
) {
506 /* Write unlock command */
507 this->command(mtd
, ONENAND_CMD_UNLOCK_ALL
, 0, 0);
509 /* No need to check return value */
510 this->wait(mtd
, FL_LOCKING
);
512 /* Workaround for all block unlock in DDP */
513 if (!ONENAND_IS_DDP(this)) {
514 s3c_onenand_check_lock_status(mtd
);
518 /* All blocks on another chip */
519 ofs
= this->chipsize
>> 1;
520 len
= this->chipsize
>> 1;
523 s3c_onenand_do_lock_cmd(mtd
, ofs
, len
, ONENAND_CMD_UNLOCK
);
524 s3c_onenand_check_lock_status(mtd
);
527 int s5pc110_chip_probe(struct mtd_info
*mtd
)
532 int s5pc210_chip_probe(struct mtd_info
*mtd
)
537 void s3c_onenand_init(struct mtd_info
*mtd
)
539 struct onenand_chip
*this = mtd
->priv
;
540 u32 size
= (4 << 10); /* 4 KiB */
542 onenand
= malloc(sizeof(struct s3c_onenand
));
546 onenand
->page_buf
= malloc(size
* sizeof(char));
547 if (!onenand
->page_buf
)
549 memset(onenand
->page_buf
, 0xff, size
);
551 onenand
->oob_buf
= malloc(128 * sizeof(char));
552 if (!onenand
->oob_buf
)
554 memset(onenand
->oob_buf
, 0xff, 128);
558 #if defined(CONFIG_S5P)
559 onenand
->base
= (void *)0xE7100000;
560 onenand
->ahb_addr
= (void *)0xB0000000;
562 onenand
->mem_addr
= s3c_mem_addr
;
563 onenand
->reg
= (struct samsung_onenand
*)onenand
->base
;
565 this->read_word
= s3c_onenand_readw
;
566 this->write_word
= s3c_onenand_writew
;
568 this->wait
= s3c_onenand_wait
;
569 this->bbt_wait
= s3c_onenand_bbt_wait
;
570 this->unlock_all
= s3c_onenand_unlock_all
;
571 this->command
= s3c_onenand_command
;
573 this->read_bufferram
= onenand_read_bufferram
;
574 this->write_bufferram
= onenand_write_bufferram
;
576 this->options
|= ONENAND_RUNTIME_BADBLOCK_CHECK
;