xref: /openbmc/u-boot/drivers/mtd/onenand/samsung.c (revision e7e90901)
1 /*
2  * S5PC100 OneNAND driver at U-Boot
3  *
4  * Copyright (C) 2008-2009 Samsung Electronics
5  * Kyungmin Park <kyungmin.park@samsung.com>
6  *
7  * Implementation:
8  *	Emulate the pseudo BufferRAM
9  *
10  * SPDX-License-Identifier:	GPL-2.0+
11  */
12 
13 #include <common.h>
14 #include <malloc.h>
15 #include <linux/compat.h>
16 #include <linux/mtd/mtd.h>
17 #include <linux/mtd/onenand.h>
18 #include <linux/mtd/samsung_onenand.h>
19 
20 #include <asm/io.h>
21 #include <asm/errno.h>
22 
23 #ifdef ONENAND_DEBUG
24 #define DPRINTK(format, args...)					\
25 do {									\
26 	printf("%s[%d]: " format "\n", __func__, __LINE__, ##args);	\
27 } while (0)
28 #else
29 #define DPRINTK(...)			do { } while (0)
30 #endif
31 
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
48 
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)
54 #endif
55 
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))
64 
65 struct s3c_onenand {
66 	struct mtd_info	*mtd;
67 	void __iomem	*base;
68 	void __iomem	*ahb_addr;
69 	int		bootram_command;
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;
74 };
75 
76 static struct s3c_onenand *onenand;
77 
78 static int s3c_read_cmd(unsigned int cmd)
79 {
80 	return readl(onenand->ahb_addr + cmd);
81 }
82 
83 static void s3c_write_cmd(int value, unsigned int cmd)
84 {
85 	writel(value, onenand->ahb_addr + cmd);
86 }
87 
88 /*
89  * MEM_ADDR
90  *
91  * fba: flash block address
92  * fpa: flash page address
93  * fsa: flash sector address
94  *
95  * return the buffer address on the memory device
96  * It will be combined with CMD_MAP_XX
97  */
98 #if defined(CONFIG_S5P)
99 static unsigned int s3c_mem_addr(int fba, int fpa, int fsa)
100 {
101 	return (fba << 13) | (fpa << 7) | (fsa << 5);
102 }
103 #endif
104 
105 static void s3c_onenand_reset(void)
106 {
107 	unsigned long timeout = 0x10000;
108 	int stat;
109 
110 	writel(ONENAND_MEM_RESET_COLD, &onenand->reg->mem_reset);
111 	while (timeout--) {
112 		stat = readl(&onenand->reg->int_err_stat);
113 		if (stat & RST_CMP)
114 			break;
115 	}
116 	stat = readl(&onenand->reg->int_err_stat);
117 	writel(stat, &onenand->reg->int_err_ack);
118 
119 	/* Clear interrupt */
120 	writel(0x0, &onenand->reg->int_err_ack);
121 	/* Clear the ECC status */
122 	writel(0x0, &onenand->reg->ecc_err_stat);
123 }
124 
125 static unsigned short s3c_onenand_readw(void __iomem *addr)
126 {
127 	struct onenand_chip *this = onenand->mtd->priv;
128 	int reg = addr - this->base;
129 	int word_addr = reg >> 1;
130 	int value;
131 
132 	/* It's used for probing time */
133 	switch (reg) {
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);
146 
147 	/* Used at unlock all status */
148 	case ONENAND_REG_CTRL_STATUS:
149 		return 0;
150 
151 	case ONENAND_REG_WP_STATUS:
152 		return ONENAND_WP_US;
153 
154 	default:
155 		break;
156 	}
157 
158 	/* BootRAM access control */
159 	if (reg < ONENAND_DATARAM && onenand->bootram_command) {
160 		if (word_addr == 0)
161 			return readl(&onenand->reg->manufact_id);
162 		if (word_addr == 1)
163 			return readl(&onenand->reg->device_id);
164 		if (word_addr == 2)
165 			return readl(&onenand->reg->flash_ver_id);
166 	}
167 
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);
171 	return value;
172 }
173 
174 static void s3c_onenand_writew(unsigned short value, void __iomem *addr)
175 {
176 	struct onenand_chip *this = onenand->mtd->priv;
177 	int reg = addr - this->base;
178 	int word_addr = reg >> 1;
179 
180 	/* It's used for probing time */
181 	switch (reg) {
182 	case ONENAND_REG_SYS_CFG1:
183 		writel(value, &onenand->reg->mem_cfg);
184 		return;
185 
186 	case ONENAND_REG_START_ADDRESS1:
187 	case ONENAND_REG_START_ADDRESS2:
188 		return;
189 
190 	/* Lock/lock-tight/unlock/unlock_all */
191 	case ONENAND_REG_START_BLOCK_ADDRESS:
192 		return;
193 
194 	default:
195 		break;
196 	}
197 
198 	/* BootRAM access control */
199 	if (reg < ONENAND_DATARAM) {
200 		if (value == ONENAND_CMD_READID) {
201 			onenand->bootram_command = 1;
202 			return;
203 		}
204 		if (value == ONENAND_CMD_RESET) {
205 			writel(ONENAND_MEM_RESET_COLD,
206 					&onenand->reg->mem_reset);
207 			onenand->bootram_command = 0;
208 			return;
209 		}
210 	}
211 
212 	printk(KERN_INFO "s3c_onenand_writew: Illegal access"
213 		" at reg 0x%x, value 0x%x\n", word_addr, value);
214 
215 	s3c_write_cmd(value, CMD_MAP_11(word_addr));
216 }
217 
218 static int s3c_onenand_wait(struct mtd_info *mtd, int state)
219 {
220 	unsigned int flags = INT_ACT;
221 	unsigned int stat, ecc;
222 	unsigned long timeout = 0x100000;
223 
224 	switch (state) {
225 	case FL_READING:
226 		flags |= BLK_RW_CMP | LOAD_CMP;
227 		break;
228 	case FL_WRITING:
229 		flags |= BLK_RW_CMP | PGM_CMP;
230 		break;
231 	case FL_ERASING:
232 		flags |= BLK_RW_CMP | ERS_CMP;
233 		break;
234 	case FL_LOCKING:
235 		flags |= BLK_RW_CMP;
236 		break;
237 	default:
238 		break;
239 	}
240 
241 	while (timeout--) {
242 		stat = readl(&onenand->reg->int_err_stat);
243 		if (stat & flags)
244 			break;
245 	}
246 
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);
250 
251 	/*
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
255 	 */
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",
260 					__func__, ecc);
261 			mtd->ecc_stats.failed++;
262 			return -EBADMSG;
263 		}
264 	}
265 
266 	if (stat & (LOCKED_BLK | ERS_FAIL | PGM_FAIL | LD_FAIL_ECC_ERR)) {
267 		printk(KERN_INFO "%s: controller error = 0x%04x\n",
268 				__func__, stat);
269 		if (stat & LOCKED_BLK)
270 			printk(KERN_INFO "%s: it's locked error = 0x%04x\n",
271 					__func__, stat);
272 
273 		return -EIO;
274 	}
275 
276 	return 0;
277 }
278 
279 static int s3c_onenand_command(struct mtd_info *mtd, int cmd,
280 		loff_t addr, size_t len)
281 {
282 	struct onenand_chip *this = mtd->priv;
283 	unsigned int *m, *s;
284 	int fba, fpa, fsa = 0;
285 	unsigned int mem_addr;
286 	int i, mcount, scount;
287 	int index;
288 
289 	fba = (int) (addr >> this->erase_shift);
290 	fpa = (int) (addr >> this->page_shift);
291 	fpa &= this->page_mask;
292 
293 	mem_addr = onenand->mem_addr(fba, fpa, fsa);
294 
295 	switch (cmd) {
296 	case ONENAND_CMD_READ:
297 	case ONENAND_CMD_READOOB:
298 	case ONENAND_CMD_BUFFERRAM:
299 		ONENAND_SET_NEXT_BUFFERRAM(this);
300 	default:
301 		break;
302 	}
303 
304 	index = ONENAND_CURRENT_BUFFERRAM(this);
305 
306 	/*
307 	 * Emulate Two BufferRAMs and access with 4 bytes pointer
308 	 */
309 	m = (unsigned int *) onenand->page_buf;
310 	s = (unsigned int *) onenand->oob_buf;
311 
312 	if (index) {
313 		m += (this->writesize >> 2);
314 		s += (mtd->oobsize >> 2);
315 	}
316 
317 	mcount = mtd->writesize >> 2;
318 	scount = mtd->oobsize >> 2;
319 
320 	switch (cmd) {
321 	case ONENAND_CMD_READ:
322 		/* Main */
323 		for (i = 0; i < mcount; i++)
324 			*m++ = s3c_read_cmd(CMD_MAP_01(mem_addr));
325 		return 0;
326 
327 	case ONENAND_CMD_READOOB:
328 		writel(TSRF, &onenand->reg->trans_spare);
329 		/* Main */
330 		for (i = 0; i < mcount; i++)
331 			*m++ = s3c_read_cmd(CMD_MAP_01(mem_addr));
332 
333 		/* Spare */
334 		for (i = 0; i < scount; i++)
335 			*s++ = s3c_read_cmd(CMD_MAP_01(mem_addr));
336 
337 		writel(0, &onenand->reg->trans_spare);
338 		return 0;
339 
340 	case ONENAND_CMD_PROG:
341 		/* Main */
342 		for (i = 0; i < mcount; i++)
343 			s3c_write_cmd(*m++, CMD_MAP_01(mem_addr));
344 		return 0;
345 
346 	case ONENAND_CMD_PROGOOB:
347 		writel(TSRF, &onenand->reg->trans_spare);
348 
349 		/* Main - dummy write */
350 		for (i = 0; i < mcount; i++)
351 			s3c_write_cmd(0xffffffff, CMD_MAP_01(mem_addr));
352 
353 		/* Spare */
354 		for (i = 0; i < scount; i++)
355 			s3c_write_cmd(*s++, CMD_MAP_01(mem_addr));
356 
357 		writel(0, &onenand->reg->trans_spare);
358 		return 0;
359 
360 	case ONENAND_CMD_UNLOCK_ALL:
361 		s3c_write_cmd(ONENAND_UNLOCK_ALL, CMD_MAP_10(mem_addr));
362 		return 0;
363 
364 	case ONENAND_CMD_ERASE:
365 		s3c_write_cmd(ONENAND_ERASE_START, CMD_MAP_10(mem_addr));
366 		return 0;
367 
368 	case ONENAND_CMD_MULTIBLOCK_ERASE:
369 		s3c_write_cmd(ONENAND_MULTI_ERASE_SET, CMD_MAP_10(mem_addr));
370 		return 0;
371 
372 	case ONENAND_CMD_ERASE_VERIFY:
373 		s3c_write_cmd(ONENAND_ERASE_VERIFY, CMD_MAP_10(mem_addr));
374 		return 0;
375 
376 	default:
377 		break;
378 	}
379 
380 	return 0;
381 }
382 
383 static unsigned char *s3c_get_bufferram(struct mtd_info *mtd, int area)
384 {
385 	struct onenand_chip *this = mtd->priv;
386 	int index = ONENAND_CURRENT_BUFFERRAM(this);
387 	unsigned char *p;
388 
389 	if (area == ONENAND_DATARAM) {
390 		p = (unsigned char *) onenand->page_buf;
391 		if (index == 1)
392 			p += this->writesize;
393 	} else {
394 		p = (unsigned char *) onenand->oob_buf;
395 		if (index == 1)
396 			p += mtd->oobsize;
397 	}
398 
399 	return p;
400 }
401 
402 static int onenand_read_bufferram(struct mtd_info *mtd, loff_t addr, int area,
403 				  unsigned char *buffer, int offset,
404 				  size_t count)
405 {
406 	unsigned char *p;
407 
408 	p = s3c_get_bufferram(mtd, area);
409 	memcpy(buffer, p + offset, count);
410 	return 0;
411 }
412 
413 static int onenand_write_bufferram(struct mtd_info *mtd, loff_t addr, int area,
414 				   const unsigned char *buffer, int offset,
415 				   size_t count)
416 {
417 	unsigned char *p;
418 
419 	p = s3c_get_bufferram(mtd, area);
420 	memcpy(p + offset, buffer, count);
421 	return 0;
422 }
423 
424 static int s3c_onenand_bbt_wait(struct mtd_info *mtd, int state)
425 {
426 	struct samsung_onenand *reg = (struct samsung_onenand *)onenand->base;
427 	unsigned int flags = INT_ACT | LOAD_CMP;
428 	unsigned int stat;
429 	unsigned long timeout = 0x10000;
430 
431 	while (timeout--) {
432 		stat = readl(&reg->int_err_stat);
433 		if (stat & flags)
434 			break;
435 	}
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);
439 
440 	if (stat & LD_FAIL_ECC_ERR) {
441 		s3c_onenand_reset();
442 		return ONENAND_BBT_READ_ERROR;
443 	}
444 
445 	if (stat & LOAD_CMP) {
446 		int ecc = readl(&onenand->reg->ecc_err_stat);
447 		if (ecc & ONENAND_ECC_4BIT_UNCORRECTABLE) {
448 			s3c_onenand_reset();
449 			return ONENAND_BBT_READ_ERROR;
450 		}
451 	}
452 
453 	return 0;
454 }
455 
456 static void s3c_onenand_check_lock_status(struct mtd_info *mtd)
457 {
458 	struct onenand_chip *this = mtd->priv;
459 	unsigned int block, end;
460 
461 	end = this->chipsize >> this->erase_shift;
462 
463 	for (block = 0; block < end; block++) {
464 		s3c_read_cmd(CMD_MAP_01(onenand->mem_addr(block, 0, 0)));
465 
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);
469 		}
470 	}
471 }
472 
473 static void s3c_onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs,
474 		size_t len, int cmd)
475 {
476 	struct onenand_chip *this = mtd->priv;
477 	int start, end, start_mem_addr, end_mem_addr;
478 
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);
483 
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));
487 	} else {
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));
490 	}
491 
492 	this->wait(mtd, FL_LOCKING);
493 }
494 
495 static void s3c_onenand_unlock_all(struct mtd_info *mtd)
496 {
497 	struct onenand_chip *this = mtd->priv;
498 	loff_t ofs = 0;
499 	size_t len = this->chipsize;
500 
501 	/* FIXME workaround */
502 	this->subpagesize = mtd->writesize;
503 	mtd->subpage_sft = 0;
504 
505 	if (this->options & ONENAND_HAS_UNLOCK_ALL) {
506 		/* Write unlock command */
507 		this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0);
508 
509 		/* No need to check return value */
510 		this->wait(mtd, FL_LOCKING);
511 
512 		/* Workaround for all block unlock in DDP */
513 		if (!ONENAND_IS_DDP(this)) {
514 			s3c_onenand_check_lock_status(mtd);
515 			return;
516 		}
517 
518 		/* All blocks on another chip */
519 		ofs = this->chipsize >> 1;
520 		len = this->chipsize >> 1;
521 	}
522 
523 	s3c_onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
524 	s3c_onenand_check_lock_status(mtd);
525 }
526 
527 int s5pc110_chip_probe(struct mtd_info *mtd)
528 {
529 	return 0;
530 }
531 
532 int s5pc210_chip_probe(struct mtd_info *mtd)
533 {
534 	return 0;
535 }
536 
537 void s3c_onenand_init(struct mtd_info *mtd)
538 {
539 	struct onenand_chip *this = mtd->priv;
540 	u32 size = (4 << 10);	/* 4 KiB */
541 
542 	onenand = malloc(sizeof(struct s3c_onenand));
543 	if (!onenand)
544 		return;
545 
546 	onenand->page_buf = malloc(size * sizeof(char));
547 	if (!onenand->page_buf)
548 		return;
549 	memset(onenand->page_buf, 0xff, size);
550 
551 	onenand->oob_buf = malloc(128 * sizeof(char));
552 	if (!onenand->oob_buf)
553 		return;
554 	memset(onenand->oob_buf, 0xff, 128);
555 
556 	onenand->mtd = mtd;
557 
558 #if defined(CONFIG_S5P)
559 	onenand->base = (void *)0xE7100000;
560 	onenand->ahb_addr = (void *)0xB0000000;
561 #endif
562 	onenand->mem_addr = s3c_mem_addr;
563 	onenand->reg = (struct samsung_onenand *)onenand->base;
564 
565 	this->read_word = s3c_onenand_readw;
566 	this->write_word = s3c_onenand_writew;
567 
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;
572 
573 	this->read_bufferram = onenand_read_bufferram;
574 	this->write_bufferram = onenand_write_bufferram;
575 
576 	this->options |= ONENAND_RUNTIME_BADBLOCK_CHECK;
577 }
578