summaryrefslogtreecommitdiffstats
path: root/include/linux/mtd/sh_flctl.h
blob: 9cf4c4c7955509a98590df62e13dcb4f679ac346 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
 * SuperH FLCTL nand controller
 *
 * Copyright © 2008 Renesas Solutions Corp.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef __SH_FLCTL_H__
#define __SH_FLCTL_H__

#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>

/* FLCTL registers */
#define FLCMNCR(f)		(f->reg + 0x0)
#define FLCMDCR(f)		(f->reg + 0x4)
#define FLCMCDR(f)		(f->reg + 0x8)
#define FLADR(f)		(f->reg + 0xC)
#define FLADR2(f)		(f->reg + 0x3C)
#define FLDATAR(f)		(f->reg + 0x10)
#define FLDTCNTR(f)		(f->reg + 0x14)
#define FLINTDMACR(f)		(f->reg + 0x18)
#define FLBSYTMR(f)		(f->reg + 0x1C)
#define FLBSYCNT(f)		(f->reg + 0x20)
#define FLDTFIFO(f)		(f->reg + 0x24)
#define FLECFIFO(f)		(f->reg + 0x28)
#define FLTRCR(f)		(f->reg + 0x2C)
#define	FL4ECCRESULT0(f)	(f->reg + 0x80)
#define	FL4ECCRESULT1(f)	(f->reg + 0x84)
#define	FL4ECCRESULT2(f)	(f->reg + 0x88)
#define	FL4ECCRESULT3(f)	(f->reg + 0x8C)
#define	FL4ECCCR(f)		(f->reg + 0x90)
#define	FL4ECCCNT(f)		(f->reg + 0x94)
#define	FLERRADR(f)		(f->reg + 0x98)

/* FLCMNCR control bits */
#define ECCPOS2		(0x1 << 25)
#define _4ECCCNTEN	(0x1 << 24)
#define _4ECCEN		(0x1 << 23)
#define _4ECCCORRECT	(0x1 << 22)
#define SHBUSSEL	(0x1 << 20)
#define SEL_16BIT	(0x1 << 19)
#define SNAND_E		(0x1 << 18)	/* SNAND (0=512 1=2048)*/
#define QTSEL_E		(0x1 << 17)
#define ENDIAN		(0x1 << 16)	/* 1 = little endian */
#define FCKSEL_E	(0x1 << 15)
#define ECCPOS_00	(0x00 << 12)
#define ECCPOS_01	(0x01 << 12)
#define ECCPOS_02	(0x02 << 12)
#define ACM_SACCES_MODE	(0x01 << 10)
#define NANWF_E		(0x1 << 9)
#define SE_D		(0x1 << 8)	/* Spare area disable */
#define	CE1_ENABLE	(0x1 << 4)	/* Chip Enable 1 */
#define	CE0_ENABLE	(0x1 << 3)	/* Chip Enable 0 */
#define	TYPESEL_SET	(0x1 << 0)

/* FLCMDCR control bits */
#define ADRCNT2_E	(0x1 << 31)	/* 5byte address enable */
#define ADRMD_E		(0x1 << 26)	/* Sector address access */
#define CDSRC_E		(0x1 << 25)	/* Data buffer selection */
#define DOSR_E		(0x1 << 24)	/* Status read check */
#define SELRW		(0x1 << 21)	/*  0:read 1:write */
#define DOADR_E		(0x1 << 20)	/* Address stage execute */
#define ADRCNT_1	(0x00 << 18)	/* Address data bytes: 1byte */
#define ADRCNT_2	(0x01 << 18)	/* Address data bytes: 2byte */
#define ADRCNT_3	(0x02 << 18)	/* Address data bytes: 3byte */
#define ADRCNT_4	(0x03 << 18)	/* Address data bytes: 4byte */
#define DOCMD2_E	(0x1 << 17)	/* 2nd cmd stage execute */
#define DOCMD1_E	(0x1 << 16)	/* 1st cmd stage execute */

/* FLTRCR control bits */
#define TRSTRT		(0x1 << 0)	/* translation start */
#define TREND		(0x1 << 1)	/* translation end */

/* FL4ECCCR control bits */
#define	_4ECCFA		(0x1 << 2)	/* 4 symbols correct fault */
#define	_4ECCEND	(0x1 << 1)	/* 4 symbols end */
#define	_4ECCEXST	(0x1 << 0)	/* 4 symbols exist */

#define INIT_FL4ECCRESULT_VAL	0x03FF03FF
#define LOOP_TIMEOUT_MAX	0x00010000

struct sh_flctl {
	struct mtd_info		mtd;
	struct nand_chip	chip;
	struct platform_device	*pdev;
	void __iomem		*reg;

	uint8_t	done_buff[2048 + 64];	/* max size 2048 + 64 */
	int	read_bytes;
	int	index;
	int	seqin_column;		/* column in SEQIN cmd */
	int	seqin_page_addr;	/* page_addr in SEQIN cmd */
	uint32_t seqin_read_cmd;		/* read cmd in SEQIN cmd */
	int	erase1_page_addr;	/* page_addr in ERASE1 cmd */
	uint32_t erase_ADRCNT;		/* bits of FLCMDCR in ERASE1 cmd */
	uint32_t rw_ADRCNT;	/* bits of FLCMDCR in READ WRITE cmd */

	int	hwecc_cant_correct[4];

	unsigned page_size:1;	/* NAND page size (0 = 512, 1 = 2048) */
	unsigned hwecc:1;	/* Hardware ECC (0 = disabled, 1 = enabled) */
};

struct sh_flctl_platform_data {
	struct mtd_partition	*parts;
	int			nr_parts;
	unsigned long		flcmncr_val;

	unsigned has_hwecc:1;
};

static inline struct sh_flctl *mtd_to_flctl(struct mtd_info *mtdinfo)
{
	return container_of(mtdinfo, struct sh_flctl, mtd);
}

#endif	/* __SH_FLCTL_H__ */