Linux Audio

Check our new training course

Loading...
  1/*
  2 * SuperH FLCTL nand controller
  3 *
  4 * Copyright (c) 2008 Renesas Solutions Corp.
  5 * Copyright (c) 2008 Atom Create Engineering Co., Ltd.
  6 *
  7 * Based on fsl_elbc_nand.c, Copyright (c) 2006-2007 Freescale Semiconductor
  8 *
  9 * This program is free software; you can redistribute it and/or modify
 10 * it under the terms of the GNU General Public License as published by
 11 * the Free Software Foundation; version 2 of the License.
 12 *
 13 * This program is distributed in the hope that it will be useful,
 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 16 * GNU General Public License for more details.
 17 *
 18 * You should have received a copy of the GNU General Public License
 19 * along with this program; if not, write to the Free Software
 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 21 *
 22 */
 23
 24#include <linux/module.h>
 25#include <linux/kernel.h>
 26#include <linux/delay.h>
 27#include <linux/io.h>
 28#include <linux/platform_device.h>
 29#include <linux/pm_runtime.h>
 30#include <linux/slab.h>
 31
 32#include <linux/mtd/mtd.h>
 33#include <linux/mtd/nand.h>
 34#include <linux/mtd/partitions.h>
 35#include <linux/mtd/sh_flctl.h>
 36
 37static struct nand_ecclayout flctl_4secc_oob_16 = {
 38	.eccbytes = 10,
 39	.eccpos = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
 40	.oobfree = {
 41		{.offset = 12,
 42		. length = 4} },
 43};
 44
 45static struct nand_ecclayout flctl_4secc_oob_64 = {
 46	.eccbytes = 10,
 47	.eccpos = {48, 49, 50, 51, 52, 53, 54, 55, 56, 57},
 48	.oobfree = {
 49		{.offset = 60,
 50		. length = 4} },
 51};
 52
 53static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
 54
 55static struct nand_bbt_descr flctl_4secc_smallpage = {
 56	.options = NAND_BBT_SCAN2NDPAGE,
 57	.offs = 11,
 58	.len = 1,
 59	.pattern = scan_ff_pattern,
 60};
 61
 62static struct nand_bbt_descr flctl_4secc_largepage = {
 63	.options = NAND_BBT_SCAN2NDPAGE,
 64	.offs = 58,
 65	.len = 2,
 66	.pattern = scan_ff_pattern,
 67};
 68
 69static void empty_fifo(struct sh_flctl *flctl)
 70{
 71	writel(0x000c0000, FLINTDMACR(flctl));	/* FIFO Clear */
 72	writel(0x00000000, FLINTDMACR(flctl));	/* Clear Error flags */
 73}
 74
 75static void start_translation(struct sh_flctl *flctl)
 76{
 77	writeb(TRSTRT, FLTRCR(flctl));
 78}
 79
 80static void timeout_error(struct sh_flctl *flctl, const char *str)
 81{
 82	dev_err(&flctl->pdev->dev, "Timeout occurred in %s\n", str);
 83}
 84
 85static void wait_completion(struct sh_flctl *flctl)
 86{
 87	uint32_t timeout = LOOP_TIMEOUT_MAX;
 88
 89	while (timeout--) {
 90		if (readb(FLTRCR(flctl)) & TREND) {
 91			writeb(0x0, FLTRCR(flctl));
 92			return;
 93		}
 94		udelay(1);
 95	}
 96
 97	timeout_error(flctl, __func__);
 98	writeb(0x0, FLTRCR(flctl));
 99}
100
101static void set_addr(struct mtd_info *mtd, int column, int page_addr)
102{
103	struct sh_flctl *flctl = mtd_to_flctl(mtd);
104	uint32_t addr = 0;
105
106	if (column == -1) {
107		addr = page_addr;	/* ERASE1 */
108	} else if (page_addr != -1) {
109		/* SEQIN, READ0, etc.. */
110		if (flctl->chip.options & NAND_BUSWIDTH_16)
111			column >>= 1;
112		if (flctl->page_size) {
113			addr = column & 0x0FFF;
114			addr |= (page_addr & 0xff) << 16;
115			addr |= ((page_addr >> 8) & 0xff) << 24;
116			/* big than 128MB */
117			if (flctl->rw_ADRCNT == ADRCNT2_E) {
118				uint32_t 	addr2;
119				addr2 = (page_addr >> 16) & 0xff;
120				writel(addr2, FLADR2(flctl));
121			}
122		} else {
123			addr = column;
124			addr |= (page_addr & 0xff) << 8;
125			addr |= ((page_addr >> 8) & 0xff) << 16;
126			addr |= ((page_addr >> 16) & 0xff) << 24;
127		}
128	}
129	writel(addr, FLADR(flctl));
130}
131
132static void wait_rfifo_ready(struct sh_flctl *flctl)
133{
134	uint32_t timeout = LOOP_TIMEOUT_MAX;
135
136	while (timeout--) {
137		uint32_t val;
138		/* check FIFO */
139		val = readl(FLDTCNTR(flctl)) >> 16;
140		if (val & 0xFF)
141			return;
142		udelay(1);
143	}
144	timeout_error(flctl, __func__);
145}
146
147static void wait_wfifo_ready(struct sh_flctl *flctl)
148{
149	uint32_t len, timeout = LOOP_TIMEOUT_MAX;
150
151	while (timeout--) {
152		/* check FIFO */
153		len = (readl(FLDTCNTR(flctl)) >> 16) & 0xFF;
154		if (len >= 4)
155			return;
156		udelay(1);
157	}
158	timeout_error(flctl, __func__);
159}
160
161static int wait_recfifo_ready(struct sh_flctl *flctl, int sector_number)
162{
163	uint32_t timeout = LOOP_TIMEOUT_MAX;
164	int checked[4];
165	void __iomem *ecc_reg[4];
166	int i;
167	uint32_t data, size;
168
169	memset(checked, 0, sizeof(checked));
170
171	while (timeout--) {
172		size = readl(FLDTCNTR(flctl)) >> 24;
173		if (size & 0xFF)
174			return 0;	/* success */
175
176		if (readl(FL4ECCCR(flctl)) & _4ECCFA)
177			return 1;	/* can't correct */
178
179		udelay(1);
180		if (!(readl(FL4ECCCR(flctl)) & _4ECCEND))
181			continue;
182
183		/* start error correction */
184		ecc_reg[0] = FL4ECCRESULT0(flctl);
185		ecc_reg[1] = FL4ECCRESULT1(flctl);
186		ecc_reg[2] = FL4ECCRESULT2(flctl);
187		ecc_reg[3] = FL4ECCRESULT3(flctl);
188
189		for (i = 0; i < 3; i++) {
190			data = readl(ecc_reg[i]);
191			if (data != INIT_FL4ECCRESULT_VAL && !checked[i]) {
192				uint8_t org;
193				int index;
194
195				if (flctl->page_size)
196					index = (512 * sector_number) +
197						(data >> 16);
198				else
199					index = data >> 16;
200
201				org = flctl->done_buff[index];
202				flctl->done_buff[index] = org ^ (data & 0xFF);
203				checked[i] = 1;
204			}
205		}
206
207		writel(0, FL4ECCCR(flctl));
208	}
209
210	timeout_error(flctl, __func__);
211	return 1;	/* timeout */
212}
213
214static void wait_wecfifo_ready(struct sh_flctl *flctl)
215{
216	uint32_t timeout = LOOP_TIMEOUT_MAX;
217	uint32_t len;
218
219	while (timeout--) {
220		/* check FLECFIFO */
221		len = (readl(FLDTCNTR(flctl)) >> 24) & 0xFF;
222		if (len >= 4)
223			return;
224		udelay(1);
225	}
226	timeout_error(flctl, __func__);
227}
228
229static void read_datareg(struct sh_flctl *flctl, int offset)
230{
231	unsigned long data;
232	unsigned long *buf = (unsigned long *)&flctl->done_buff[offset];
233
234	wait_completion(flctl);
235
236	data = readl(FLDATAR(flctl));
237	*buf = le32_to_cpu(data);
238}
239
240static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
241{
242	int i, len_4align;
243	unsigned long *buf = (unsigned long *)&flctl->done_buff[offset];
244	void *fifo_addr = (void *)FLDTFIFO(flctl);
245
246	len_4align = (rlen + 3) / 4;
247
248	for (i = 0; i < len_4align; i++) {
249		wait_rfifo_ready(flctl);
250		buf[i] = readl(fifo_addr);
251		buf[i] = be32_to_cpu(buf[i]);
252	}
253}
254
255static int read_ecfiforeg(struct sh_flctl *flctl, uint8_t *buff, int sector)
256{
257	int i;
258	unsigned long *ecc_buf = (unsigned long *)buff;
259	void *fifo_addr = (void *)FLECFIFO(flctl);
260
261	for (i = 0; i < 4; i++) {
262		if (wait_recfifo_ready(flctl , sector))
263			return 1;
264		ecc_buf[i] = readl(fifo_addr);
265		ecc_buf[i] = be32_to_cpu(ecc_buf[i]);
266	}
267
268	return 0;
269}
270
271static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
272{
273	int i, len_4align;
274	unsigned long *data = (unsigned long *)&flctl->done_buff[offset];
275	void *fifo_addr = (void *)FLDTFIFO(flctl);
276
277	len_4align = (rlen + 3) / 4;
278	for (i = 0; i < len_4align; i++) {
279		wait_wfifo_ready(flctl);
280		writel(cpu_to_be32(data[i]), fifo_addr);
281	}
282}
283
284static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_val)
285{
286	struct sh_flctl *flctl = mtd_to_flctl(mtd);
287	uint32_t flcmncr_val = flctl->flcmncr_base & ~SEL_16BIT;
288	uint32_t flcmdcr_val, addr_len_bytes = 0;
289
290	/* Set SNAND bit if page size is 2048byte */
291	if (flctl->page_size)
292		flcmncr_val |= SNAND_E;
293	else
294		flcmncr_val &= ~SNAND_E;
295
296	/* default FLCMDCR val */
297	flcmdcr_val = DOCMD1_E | DOADR_E;
298
299	/* Set for FLCMDCR */
300	switch (cmd) {
301	case NAND_CMD_ERASE1:
302		addr_len_bytes = flctl->erase_ADRCNT;
303		flcmdcr_val |= DOCMD2_E;
304		break;
305	case NAND_CMD_READ0:
306	case NAND_CMD_READOOB:
307	case NAND_CMD_RNDOUT:
308		addr_len_bytes = flctl->rw_ADRCNT;
309		flcmdcr_val |= CDSRC_E;
310		if (flctl->chip.options & NAND_BUSWIDTH_16)
311			flcmncr_val |= SEL_16BIT;
312		break;
313	case NAND_CMD_SEQIN:
314		/* This case is that cmd is READ0 or READ1 or READ00 */
315		flcmdcr_val &= ~DOADR_E;	/* ONLY execute 1st cmd */
316		break;
317	case NAND_CMD_PAGEPROG:
318		addr_len_bytes = flctl->rw_ADRCNT;
319		flcmdcr_val |= DOCMD2_E | CDSRC_E | SELRW;
320		if (flctl->chip.options & NAND_BUSWIDTH_16)
321			flcmncr_val |= SEL_16BIT;
322		break;
323	case NAND_CMD_READID:
324		flcmncr_val &= ~SNAND_E;
325		flcmdcr_val |= CDSRC_E;
326		addr_len_bytes = ADRCNT_1;
327		break;
328	case NAND_CMD_STATUS:
329	case NAND_CMD_RESET:
330		flcmncr_val &= ~SNAND_E;
331		flcmdcr_val &= ~(DOADR_E | DOSR_E);
332		break;
333	default:
334		break;
335	}
336
337	/* Set address bytes parameter */
338	flcmdcr_val |= addr_len_bytes;
339
340	/* Now actually write */
341	writel(flcmncr_val, FLCMNCR(flctl));
342	writel(flcmdcr_val, FLCMDCR(flctl));
343	writel(flcmcdr_val, FLCMCDR(flctl));
344}
345
346static int flctl_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
347				uint8_t *buf, int oob_required, int page)
348{
349	int i, eccsize = chip->ecc.size;
350	int eccbytes = chip->ecc.bytes;
351	int eccsteps = chip->ecc.steps;
352	uint8_t *p = buf;
353	struct sh_flctl *flctl = mtd_to_flctl(mtd);
354
355	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
356		chip->read_buf(mtd, p, eccsize);
357
358	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
359		if (flctl->hwecc_cant_correct[i])
360			mtd->ecc_stats.failed++;
361		else
362			mtd->ecc_stats.corrected += 0; /* FIXME */
363	}
364
365	return 0;
366}
367
368static void flctl_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
369				   const uint8_t *buf, int oob_required)
370{
371	int i, eccsize = chip->ecc.size;
372	int eccbytes = chip->ecc.bytes;
373	int eccsteps = chip->ecc.steps;
374	const uint8_t *p = buf;
375
376	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
377		chip->write_buf(mtd, p, eccsize);
378}
379
380static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr)
381{
382	struct sh_flctl *flctl = mtd_to_flctl(mtd);
383	int sector, page_sectors;
384
385	if (flctl->page_size)
386		page_sectors = 4;
387	else
388		page_sectors = 1;
389
390	writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE | _4ECCCORRECT,
391		 FLCMNCR(flctl));
392
393	set_cmd_regs(mtd, NAND_CMD_READ0,
394		(NAND_CMD_READSTART << 8) | NAND_CMD_READ0);
395
396	for (sector = 0; sector < page_sectors; sector++) {
397		int ret;
398
399		empty_fifo(flctl);
400		writel(readl(FLCMDCR(flctl)) | 1, FLCMDCR(flctl));
401		writel(page_addr << 2 | sector, FLADR(flctl));
402
403		start_translation(flctl);
404		read_fiforeg(flctl, 512, 512 * sector);
405
406		ret = read_ecfiforeg(flctl,
407			&flctl->done_buff[mtd->writesize + 16 * sector],
408			sector);
409
410		if (ret)
411			flctl->hwecc_cant_correct[sector] = 1;
412
413		writel(0x0, FL4ECCCR(flctl));
414		wait_completion(flctl);
415	}
416	writel(readl(FLCMNCR(flctl)) & ~(ACM_SACCES_MODE | _4ECCCORRECT),
417			FLCMNCR(flctl));
418}
419
420static void execmd_read_oob(struct mtd_info *mtd, int page_addr)
421{
422	struct sh_flctl *flctl = mtd_to_flctl(mtd);
423
424	set_cmd_regs(mtd, NAND_CMD_READ0,
425		(NAND_CMD_READSTART << 8) | NAND_CMD_READ0);
426
427	empty_fifo(flctl);
428	if (flctl->page_size) {
429		int i;
430		/* In case that the page size is 2k */
431		for (i = 0; i < 16 * 3; i++)
432			flctl->done_buff[i] = 0xFF;
433
434		set_addr(mtd, 3 * 528 + 512, page_addr);
435		writel(16, FLDTCNTR(flctl));
436
437		start_translation(flctl);
438		read_fiforeg(flctl, 16, 16 * 3);
439		wait_completion(flctl);
440	} else {
441		/* In case that the page size is 512b */
442		set_addr(mtd, 512, page_addr);
443		writel(16, FLDTCNTR(flctl));
444
445		start_translation(flctl);
446		read_fiforeg(flctl, 16, 0);
447		wait_completion(flctl);
448	}
449}
450
451static void execmd_write_page_sector(struct mtd_info *mtd)
452{
453	struct sh_flctl *flctl = mtd_to_flctl(mtd);
454	int i, page_addr = flctl->seqin_page_addr;
455	int sector, page_sectors;
456
457	if (flctl->page_size)
458		page_sectors = 4;
459	else
460		page_sectors = 1;
461
462	writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE, FLCMNCR(flctl));
463
464	set_cmd_regs(mtd, NAND_CMD_PAGEPROG,
465			(NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN);
466
467	for (sector = 0; sector < page_sectors; sector++) {
468		empty_fifo(flctl);
469		writel(readl(FLCMDCR(flctl)) | 1, FLCMDCR(flctl));
470		writel(page_addr << 2 | sector, FLADR(flctl));
471
472		start_translation(flctl);
473		write_fiforeg(flctl, 512, 512 * sector);
474
475		for (i = 0; i < 4; i++) {
476			wait_wecfifo_ready(flctl); /* wait for write ready */
477			writel(0xFFFFFFFF, FLECFIFO(flctl));
478		}
479		wait_completion(flctl);
480	}
481
482	writel(readl(FLCMNCR(flctl)) & ~ACM_SACCES_MODE, FLCMNCR(flctl));
483}
484
485static void execmd_write_oob(struct mtd_info *mtd)
486{
487	struct sh_flctl *flctl = mtd_to_flctl(mtd);
488	int page_addr = flctl->seqin_page_addr;
489	int sector, page_sectors;
490
491	if (flctl->page_size) {
492		sector = 3;
493		page_sectors = 4;
494	} else {
495		sector = 0;
496		page_sectors = 1;
497	}
498
499	set_cmd_regs(mtd, NAND_CMD_PAGEPROG,
500			(NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN);
501
502	for (; sector < page_sectors; sector++) {
503		empty_fifo(flctl);
504		set_addr(mtd, sector * 528 + 512, page_addr);
505		writel(16, FLDTCNTR(flctl));	/* set read size */
506
507		start_translation(flctl);
508		write_fiforeg(flctl, 16, 16 * sector);
509		wait_completion(flctl);
510	}
511}
512
513static void flctl_cmdfunc(struct mtd_info *mtd, unsigned int command,
514			int column, int page_addr)
515{
516	struct sh_flctl *flctl = mtd_to_flctl(mtd);
517	uint32_t read_cmd = 0;
518
519	pm_runtime_get_sync(&flctl->pdev->dev);
520
521	flctl->read_bytes = 0;
522	if (command != NAND_CMD_PAGEPROG)
523		flctl->index = 0;
524
525	switch (command) {
526	case NAND_CMD_READ1:
527	case NAND_CMD_READ0:
528		if (flctl->hwecc) {
529			/* read page with hwecc */
530			execmd_read_page_sector(mtd, page_addr);
531			break;
532		}
533		if (flctl->page_size)
534			set_cmd_regs(mtd, command, (NAND_CMD_READSTART << 8)
535				| command);
536		else
537			set_cmd_regs(mtd, command, command);
538
539		set_addr(mtd, 0, page_addr);
540
541		flctl->read_bytes = mtd->writesize + mtd->oobsize;
542		if (flctl->chip.options & NAND_BUSWIDTH_16)
543			column >>= 1;
544		flctl->index += column;
545		goto read_normal_exit;
546
547	case NAND_CMD_READOOB:
548		if (flctl->hwecc) {
549			/* read page with hwecc */
550			execmd_read_oob(mtd, page_addr);
551			break;
552		}
553
554		if (flctl->page_size) {
555			set_cmd_regs(mtd, command, (NAND_CMD_READSTART << 8)
556				| NAND_CMD_READ0);
557			set_addr(mtd, mtd->writesize, page_addr);
558		} else {
559			set_cmd_regs(mtd, command, command);
560			set_addr(mtd, 0, page_addr);
561		}
562		flctl->read_bytes = mtd->oobsize;
563		goto read_normal_exit;
564
565	case NAND_CMD_RNDOUT:
566		if (flctl->hwecc)
567			break;
568
569		if (flctl->page_size)
570			set_cmd_regs(mtd, command, (NAND_CMD_RNDOUTSTART << 8)
571				| command);
572		else
573			set_cmd_regs(mtd, command, command);
574
575		set_addr(mtd, column, 0);
576
577		flctl->read_bytes = mtd->writesize + mtd->oobsize - column;
578		goto read_normal_exit;
579
580	case NAND_CMD_READID:
581		set_cmd_regs(mtd, command, command);
582
583		/* READID is always performed using an 8-bit bus */
584		if (flctl->chip.options & NAND_BUSWIDTH_16)
585			column <<= 1;
586		set_addr(mtd, column, 0);
587
588		flctl->read_bytes = 8;
589		writel(flctl->read_bytes, FLDTCNTR(flctl)); /* set read size */
590		empty_fifo(flctl);
591		start_translation(flctl);
592		read_fiforeg(flctl, flctl->read_bytes, 0);
593		wait_completion(flctl);
594		break;
595
596	case NAND_CMD_ERASE1:
597		flctl->erase1_page_addr = page_addr;
598		break;
599
600	case NAND_CMD_ERASE2:
601		set_cmd_regs(mtd, NAND_CMD_ERASE1,
602			(command << 8) | NAND_CMD_ERASE1);
603		set_addr(mtd, -1, flctl->erase1_page_addr);
604		start_translation(flctl);
605		wait_completion(flctl);
606		break;
607
608	case NAND_CMD_SEQIN:
609		if (!flctl->page_size) {
610			/* output read command */
611			if (column >= mtd->writesize) {
612				column -= mtd->writesize;
613				read_cmd = NAND_CMD_READOOB;
614			} else if (column < 256) {
615				read_cmd = NAND_CMD_READ0;
616			} else {
617				column -= 256;
618				read_cmd = NAND_CMD_READ1;
619			}
620		}
621		flctl->seqin_column = column;
622		flctl->seqin_page_addr = page_addr;
623		flctl->seqin_read_cmd = read_cmd;
624		break;
625
626	case NAND_CMD_PAGEPROG:
627		empty_fifo(flctl);
628		if (!flctl->page_size) {
629			set_cmd_regs(mtd, NAND_CMD_SEQIN,
630					flctl->seqin_read_cmd);
631			set_addr(mtd, -1, -1);
632			writel(0, FLDTCNTR(flctl));	/* set 0 size */
633			start_translation(flctl);
634			wait_completion(flctl);
635		}
636		if (flctl->hwecc) {
637			/* write page with hwecc */
638			if (flctl->seqin_column == mtd->writesize)
639				execmd_write_oob(mtd);
640			else if (!flctl->seqin_column)
641				execmd_write_page_sector(mtd);
642			else
643				printk(KERN_ERR "Invalid address !?\n");
644			break;
645		}
646		set_cmd_regs(mtd, command, (command << 8) | NAND_CMD_SEQIN);
647		set_addr(mtd, flctl->seqin_column, flctl->seqin_page_addr);
648		writel(flctl->index, FLDTCNTR(flctl));	/* set write size */
649		start_translation(flctl);
650		write_fiforeg(flctl, flctl->index, 0);
651		wait_completion(flctl);
652		break;
653
654	case NAND_CMD_STATUS:
655		set_cmd_regs(mtd, command, command);
656		set_addr(mtd, -1, -1);
657
658		flctl->read_bytes = 1;
659		writel(flctl->read_bytes, FLDTCNTR(flctl)); /* set read size */
660		start_translation(flctl);
661		read_datareg(flctl, 0); /* read and end */
662		break;
663
664	case NAND_CMD_RESET:
665		set_cmd_regs(mtd, command, command);
666		set_addr(mtd, -1, -1);
667
668		writel(0, FLDTCNTR(flctl));	/* set 0 size */
669		start_translation(flctl);
670		wait_completion(flctl);
671		break;
672
673	default:
674		break;
675	}
676	goto runtime_exit;
677
678read_normal_exit:
679	writel(flctl->read_bytes, FLDTCNTR(flctl));	/* set read size */
680	empty_fifo(flctl);
681	start_translation(flctl);
682	read_fiforeg(flctl, flctl->read_bytes, 0);
683	wait_completion(flctl);
684runtime_exit:
685	pm_runtime_put_sync(&flctl->pdev->dev);
686	return;
687}
688
689static void flctl_select_chip(struct mtd_info *mtd, int chipnr)
690{
691	struct sh_flctl *flctl = mtd_to_flctl(mtd);
692	int ret;
693
694	switch (chipnr) {
695	case -1:
696		flctl->flcmncr_base &= ~CE0_ENABLE;
697
698		pm_runtime_get_sync(&flctl->pdev->dev);
699		writel(flctl->flcmncr_base, FLCMNCR(flctl));
700
701		if (flctl->qos_request) {
702			dev_pm_qos_remove_request(&flctl->pm_qos);
703			flctl->qos_request = 0;
704		}
705
706		pm_runtime_put_sync(&flctl->pdev->dev);
707		break;
708	case 0:
709		flctl->flcmncr_base |= CE0_ENABLE;
710
711		if (!flctl->qos_request) {
712			ret = dev_pm_qos_add_request(&flctl->pdev->dev,
713							&flctl->pm_qos, 100);
714			if (ret < 0)
715				dev_err(&flctl->pdev->dev,
716					"PM QoS request failed: %d\n", ret);
717			flctl->qos_request = 1;
718		}
719
720		if (flctl->holden) {
721			pm_runtime_get_sync(&flctl->pdev->dev);
722			writel(HOLDEN, FLHOLDCR(flctl));
723			pm_runtime_put_sync(&flctl->pdev->dev);
724		}
725		break;
726	default:
727		BUG();
728	}
729}
730
731static void flctl_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
732{
733	struct sh_flctl *flctl = mtd_to_flctl(mtd);
734	int i, index = flctl->index;
735
736	for (i = 0; i < len; i++)
737		flctl->done_buff[index + i] = buf[i];
738	flctl->index += len;
739}
740
741static uint8_t flctl_read_byte(struct mtd_info *mtd)
742{
743	struct sh_flctl *flctl = mtd_to_flctl(mtd);
744	int index = flctl->index;
745	uint8_t data;
746
747	data = flctl->done_buff[index];
748	flctl->index++;
749	return data;
750}
751
752static uint16_t flctl_read_word(struct mtd_info *mtd)
753{
754       struct sh_flctl *flctl = mtd_to_flctl(mtd);
755       int index = flctl->index;
756       uint16_t data;
757       uint16_t *buf = (uint16_t *)&flctl->done_buff[index];
758
759       data = *buf;
760       flctl->index += 2;
761       return data;
762}
763
764static void flctl_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
765{
766	int i;
767
768	for (i = 0; i < len; i++)
769		buf[i] = flctl_read_byte(mtd);
770}
771
772static int flctl_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
773{
774	int i;
775
776	for (i = 0; i < len; i++)
777		if (buf[i] != flctl_read_byte(mtd))
778			return -EFAULT;
779	return 0;
780}
781
782static int flctl_chip_init_tail(struct mtd_info *mtd)
783{
784	struct sh_flctl *flctl = mtd_to_flctl(mtd);
785	struct nand_chip *chip = &flctl->chip;
786
787	if (mtd->writesize == 512) {
788		flctl->page_size = 0;
789		if (chip->chipsize > (32 << 20)) {
790			/* big than 32MB */
791			flctl->rw_ADRCNT = ADRCNT_4;
792			flctl->erase_ADRCNT = ADRCNT_3;
793		} else if (chip->chipsize > (2 << 16)) {
794			/* big than 128KB */
795			flctl->rw_ADRCNT = ADRCNT_3;
796			flctl->erase_ADRCNT = ADRCNT_2;
797		} else {
798			flctl->rw_ADRCNT = ADRCNT_2;
799			flctl->erase_ADRCNT = ADRCNT_1;
800		}
801	} else {
802		flctl->page_size = 1;
803		if (chip->chipsize > (128 << 20)) {
804			/* big than 128MB */
805			flctl->rw_ADRCNT = ADRCNT2_E;
806			flctl->erase_ADRCNT = ADRCNT_3;
807		} else if (chip->chipsize > (8 << 16)) {
808			/* big than 512KB */
809			flctl->rw_ADRCNT = ADRCNT_4;
810			flctl->erase_ADRCNT = ADRCNT_2;
811		} else {
812			flctl->rw_ADRCNT = ADRCNT_3;
813			flctl->erase_ADRCNT = ADRCNT_1;
814		}
815	}
816
817	if (flctl->hwecc) {
818		if (mtd->writesize == 512) {
819			chip->ecc.layout = &flctl_4secc_oob_16;
820			chip->badblock_pattern = &flctl_4secc_smallpage;
821		} else {
822			chip->ecc.layout = &flctl_4secc_oob_64;
823			chip->badblock_pattern = &flctl_4secc_largepage;
824		}
825
826		chip->ecc.size = 512;
827		chip->ecc.bytes = 10;
828		chip->ecc.strength = 4;
829		chip->ecc.read_page = flctl_read_page_hwecc;
830		chip->ecc.write_page = flctl_write_page_hwecc;
831		chip->ecc.mode = NAND_ECC_HW;
832
833		/* 4 symbols ECC enabled */
834		flctl->flcmncr_base |= _4ECCEN | ECCPOS2 | ECCPOS_02;
835	} else {
836		chip->ecc.mode = NAND_ECC_SOFT;
837	}
838
839	return 0;
840}
841
842static int __devinit flctl_probe(struct platform_device *pdev)
843{
844	struct resource *res;
845	struct sh_flctl *flctl;
846	struct mtd_info *flctl_mtd;
847	struct nand_chip *nand;
848	struct sh_flctl_platform_data *pdata;
849	int ret = -ENXIO;
850
851	pdata = pdev->dev.platform_data;
852	if (pdata == NULL) {
853		dev_err(&pdev->dev, "no platform data defined\n");
854		return -EINVAL;
855	}
856
857	flctl = kzalloc(sizeof(struct sh_flctl), GFP_KERNEL);
858	if (!flctl) {
859		dev_err(&pdev->dev, "failed to allocate driver data\n");
860		return -ENOMEM;
861	}
862
863	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
864	if (!res) {
865		dev_err(&pdev->dev, "failed to get I/O memory\n");
866		goto err_iomap;
867	}
868
869	flctl->reg = ioremap(res->start, resource_size(res));
870	if (flctl->reg == NULL) {
871		dev_err(&pdev->dev, "failed to remap I/O memory\n");
872		goto err_iomap;
873	}
874
875	platform_set_drvdata(pdev, flctl);
876	flctl_mtd = &flctl->mtd;
877	nand = &flctl->chip;
878	flctl_mtd->priv = nand;
879	flctl->pdev = pdev;
880	flctl->flcmncr_base = pdata->flcmncr_val;
881	flctl->hwecc = pdata->has_hwecc;
882	flctl->holden = pdata->use_holden;
883
884	/* Set address of hardware control function */
885	/* 20 us command delay time */
886	nand->chip_delay = 20;
887
888	nand->read_byte = flctl_read_byte;
889	nand->write_buf = flctl_write_buf;
890	nand->read_buf = flctl_read_buf;
891	nand->verify_buf = flctl_verify_buf;
892	nand->select_chip = flctl_select_chip;
893	nand->cmdfunc = flctl_cmdfunc;
894
895	if (pdata->flcmncr_val & SEL_16BIT) {
896		nand->options |= NAND_BUSWIDTH_16;
897		nand->read_word = flctl_read_word;
898	}
899
900	pm_runtime_enable(&pdev->dev);
901	pm_runtime_resume(&pdev->dev);
902
903	ret = nand_scan_ident(flctl_mtd, 1, NULL);
904	if (ret)
905		goto err_chip;
906
907	ret = flctl_chip_init_tail(flctl_mtd);
908	if (ret)
909		goto err_chip;
910
911	ret = nand_scan_tail(flctl_mtd);
912	if (ret)
913		goto err_chip;
914
915	mtd_device_register(flctl_mtd, pdata->parts, pdata->nr_parts);
916
917	return 0;
918
919err_chip:
920	pm_runtime_disable(&pdev->dev);
921err_iomap:
922	kfree(flctl);
923	return ret;
924}
925
926static int __devexit flctl_remove(struct platform_device *pdev)
927{
928	struct sh_flctl *flctl = platform_get_drvdata(pdev);
929
930	nand_release(&flctl->mtd);
931	pm_runtime_disable(&pdev->dev);
932	kfree(flctl);
933
934	return 0;
935}
936
937static struct platform_driver flctl_driver = {
938	.remove		= flctl_remove,
939	.driver = {
940		.name	= "sh_flctl",
941		.owner	= THIS_MODULE,
942	},
943};
944
945static int __init flctl_nand_init(void)
946{
947	return platform_driver_probe(&flctl_driver, flctl_probe);
948}
949
950static void __exit flctl_nand_cleanup(void)
951{
952	platform_driver_unregister(&flctl_driver);
953}
954
955module_init(flctl_nand_init);
956module_exit(flctl_nand_cleanup);
957
958MODULE_LICENSE("GPL");
959MODULE_AUTHOR("Yoshihiro Shimoda");
960MODULE_DESCRIPTION("SuperH FLCTL driver");
961MODULE_ALIAS("platform:sh_flctl");