aboutsummaryrefslogtreecommitdiff
path: root/drivers/mtd/devices/docg3.h
blob: 19fb93f96a3a4eca50f4f8b6bb01728b48bb064f (plain)
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
/*
 * Handles the M-Systems DiskOnChip G3 chip
 *
 * Copyright (C) 2011 Robert Jarzmik
 *
 * 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; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#ifndef _MTD_DOCG3_H
#define _MTD_DOCG3_H

#include <linux/mtd/mtd.h>

/*
 * Flash memory areas :
 *   - 0x0000 .. 0x07ff : IPL
 *   - 0x0800 .. 0x0fff : Data area
 *   - 0x1000 .. 0x17ff : Registers
 *   - 0x1800 .. 0x1fff : Unknown
 */
#define DOC_IOSPACE_IPL			0x0000
#define DOC_IOSPACE_DATA		0x0800
#define DOC_IOSPACE_SIZE		0x2000

/*
 * DOC G3 layout and adressing scheme
 *   A page address for the block "b", plane "P" and page "p":
 *   address = [bbbb bPpp pppp]
 */

#define DOC_ADDR_PAGE_MASK		0x3f
#define DOC_ADDR_BLOCK_SHIFT		6
#define DOC_LAYOUT_NBPLANES		2
#define DOC_LAYOUT_PAGES_PER_BLOCK	64
#define DOC_LAYOUT_PAGE_SIZE		512
#define DOC_LAYOUT_OOB_SIZE		16
#define DOC_LAYOUT_WEAR_SIZE		8
#define DOC_LAYOUT_PAGE_OOB_SIZE				\
	(DOC_LAYOUT_PAGE_SIZE + DOC_LAYOUT_OOB_SIZE)
#define DOC_LAYOUT_WEAR_OFFSET		(DOC_LAYOUT_PAGE_OOB_SIZE * 2)
#define DOC_LAYOUT_BLOCK_SIZE					\
	(DOC_LAYOUT_PAGES_PER_BLOCK * DOC_LAYOUT_PAGE_SIZE)

/*
 * ECC related constants
 */
#define DOC_ECC_BCH_M			14
#define DOC_ECC_BCH_T			4
#define DOC_ECC_BCH_PRIMPOLY		0x4443
#define DOC_ECC_BCH_SIZE		7
#define DOC_ECC_BCH_COVERED_BYTES				\
	(DOC_LAYOUT_PAGE_SIZE + DOC_LAYOUT_OOB_PAGEINFO_SZ +	\
	 DOC_LAYOUT_OOB_HAMMING_SZ)
#define DOC_ECC_BCH_TOTAL_BYTES					\
	(DOC_ECC_BCH_COVERED_BYTES + DOC_LAYOUT_OOB_BCH_SZ)

/*
 * Blocks distribution
 */
#define DOC_LAYOUT_BLOCK_BBT		0
#define DOC_LAYOUT_BLOCK_OTP		0
#define DOC_LAYOUT_BLOCK_FIRST_DATA	6

#define DOC_LAYOUT_PAGE_BBT		4

/*
 * Extra page OOB (16 bytes wide) layout
 */
#define DOC_LAYOUT_OOB_PAGEINFO_OFS	0
#define DOC_LAYOUT_OOB_HAMMING_OFS	7
#define DOC_LAYOUT_OOB_BCH_OFS		8
#define DOC_LAYOUT_OOB_UNUSED_OFS	15
#define DOC_LAYOUT_OOB_PAGEINFO_SZ	7
#define DOC_LAYOUT_OOB_HAMMING_SZ	1
#define DOC_LAYOUT_OOB_BCH_SZ		7
#define DOC_LAYOUT_OOB_UNUSED_SZ	1


#define DOC_CHIPID_G3			0x200
#define DOC_ERASE_MARK			0xaa
#define DOC_MAX_NBFLOORS		4
/*
 * Flash registers
 */
#define DOC_CHIPID			0x1000
#define DOC_TEST			0x1004
#define DOC_BUSLOCK			0x1006
#define DOC_ENDIANCONTROL		0x1008
#define DOC_DEVICESELECT		0x100a
#define DOC_ASICMODE			0x100c
#define DOC_CONFIGURATION		0x100e
#define DOC_INTERRUPTCONTROL		0x1010
#define DOC_READADDRESS			0x101a
#define DOC_DATAEND			0x101e
#define DOC_INTERRUPTSTATUS		0x1020

#define DOC_FLASHSEQUENCE		0x1032
#define DOC_FLASHCOMMAND		0x1034
#define DOC_FLASHADDRESS		0x1036
#define DOC_FLASHCONTROL		0x1038
#define DOC_NOP				0x103e

#define DOC_ECCCONF0			0x1040
#define DOC_ECCCONF1			0x1042
#define DOC_ECCPRESET			0x1044
#define DOC_HAMMINGPARITY		0x1046
#define DOC_BCH_HW_ECC(idx)		(0x1048 + idx)

#define DOC_PROTECTION			0x1056
#define DOC_DPS0_KEY			0x105c
#define DOC_DPS1_KEY			0x105e
#define DOC_DPS0_ADDRLOW		0x1060
#define DOC_DPS0_ADDRHIGH		0x1062
#define DOC_DPS1_ADDRLOW		0x1064
#define DOC_DPS1_ADDRHIGH		0x1066
#define DOC_DPS0_STATUS			0x106c
#define DOC_DPS1_STATUS			0x106e

#define DOC_ASICMODECONFIRM		0x1072
#define DOC_CHIPID_INV			0x1074
#define DOC_POWERMODE			0x107c

/*
 * Flash sequences
 * A sequence is preset before one or more commands are input to the chip.
 */
#define DOC_SEQ_RESET			0x00
#define DOC_SEQ_PAGE_SIZE_532		0x03
#define DOC_SEQ_SET_FASTMODE		0x05
#define DOC_SEQ_SET_RELIABLEMODE	0x09
#define DOC_SEQ_READ			0x12
#define DOC_SEQ_SET_PLANE1		0x0e
#define DOC_SEQ_SET_PLANE2		0x10
#define DOC_SEQ_PAGE_SETUP		0x1d
#define DOC_SEQ_ERASE			0x27
#define DOC_SEQ_PLANES_STATUS		0x31

/*
 * Flash commands
 */
#define DOC_CMD_READ_PLANE1		0x00
#define DOC_CMD_SET_ADDR_READ		0x05
#define DOC_CMD_READ_ALL_PLANES		0x30
#define DOC_CMD_READ_PLANE2		0x50
#define DOC_CMD_READ_FLASH		0xe0
#define DOC_CMD_PAGE_SIZE_532		0x3c

#define DOC_CMD_PROG_BLOCK_ADDR		0x60
#define DOC_CMD_PROG_CYCLE1		0x80
#define DOC_CMD_PROG_CYCLE2		0x10
#define DOC_CMD_PROG_CYCLE3		0x11
#define DOC_CMD_ERASECYCLE2		0xd0
#define DOC_CMD_READ_STATUS		0x70
#define DOC_CMD_PLANES_STATUS		0x71

#define DOC_CMD_RELIABLE_MODE		0x22
#define DOC_CMD_FAST_MODE		0xa2

#define DOC_CMD_RESET			0xff

/*
 * Flash register : DOC_FLASHCONTROL
 */
#define DOC_CTRL_VIOLATION		0x20
#define DOC_CTRL_CE			0x10
#define DOC_CTRL_UNKNOWN_BITS		0x08
#define DOC_CTRL_PROTECTION_ERROR	0x04
#define DOC_CTRL_SEQUENCE_ERROR		0x02
#define DOC_CTRL_FLASHREADY		0x01

/*
 * Flash register : DOC_ASICMODE
 */
#define DOC_ASICMODE_RESET		0x00
#define DOC_ASICMODE_NORMAL		0x01
#define DOC_ASICMODE_POWERDOWN		0x02
#define DOC_ASICMODE_MDWREN		0x04
#define DOC_ASICMODE_BDETCT_RESET	0x08
#define DOC_ASICMODE_RSTIN_RESET	0x10
#define DOC_ASICMODE_RAM_WE		0x20

/*
 * Flash register : DOC_ECCCONF0
 */
#define DOC_ECCCONF0_WRITE_MODE		0x0000
#define DOC_ECCCONF0_READ_MODE		0x8000
#define DOC_ECCCONF0_AUTO_ECC_ENABLE	0x4000
#define DOC_ECCCONF0_HAMMING_ENABLE	0x1000
#define DOC_ECCCONF0_BCH_ENABLE		0x0800
#define DOC_ECCCONF0_DATA_BYTES_MASK	0x07ff

/*
 * Flash register : DOC_ECCCONF1
 */
#define DOC_ECCCONF1_BCH_SYNDROM_ERR	0x80
#define DOC_ECCCONF1_UNKOWN1		0x40
#define DOC_ECCCONF1_PAGE_IS_WRITTEN	0x20
#define DOC_ECCCONF1_UNKOWN3		0x10
#define DOC_ECCCONF1_HAMMING_BITS_MASK	0x0f

/*
 * Flash register : DOC_PROTECTION
 */
#define DOC_PROTECT_FOUNDRY_OTP_LOCK	0x01
#define DOC_PROTECT_CUSTOMER_OTP_LOCK	0x02
#define DOC_PROTECT_LOCK_INPUT		0x04
#define DOC_PROTECT_STICKY_LOCK		0x08
#define DOC_PROTECT_PROTECTION_ENABLED	0x10
#define DOC_PROTECT_IPL_DOWNLOAD_LOCK	0x20
#define DOC_PROTECT_PROTECTION_ERROR	0x80

/*
 * Flash register : DOC_DPS0_STATUS and DOC_DPS1_STATUS
 */
#define DOC_DPS_OTP_PROTECTED		0x01
#define DOC_DPS_READ_PROTECTED		0x02
#define DOC_DPS_WRITE_PROTECTED		0x04
#define DOC_DPS_HW_LOCK_ENABLED		0x08
#define DOC_DPS_KEY_OK			0x80

/*
 * Flash register : DOC_CONFIGURATION
 */
#define DOC_CONF_IF_CFG			0x80
#define DOC_CONF_MAX_ID_MASK		0x30
#define DOC_CONF_VCCQ_3V		0x01

/*
 * Flash register : DOC_READADDRESS
 */
#define DOC_READADDR_INC		0x8000
#define DOC_READADDR_ONE_BYTE		0x4000
#define DOC_READADDR_ADDR_MASK		0x1fff

/*
 * Flash register : DOC_POWERMODE
 */
#define DOC_POWERDOWN_READY		0x80

/*
 * Status of erase and write operation
 */
#define DOC_PLANES_STATUS_FAIL		0x01
#define DOC_PLANES_STATUS_PLANE0_KO	0x02
#define DOC_PLANES_STATUS_PLANE1_KO	0x04

/*
 * DPS key management
 *
 * Each floor of docg3 has 2 protection areas: DPS0 and DPS1. These areas span
 * across block boundaries, and define whether these blocks can be read or
 * written.
 * The definition is dynamically stored in page 0 of blocks (2,3) for DPS0, and
 * page 0 of blocks (4,5) for DPS1.
 */
#define DOC_LAYOUT_DPS_KEY_LENGTH	8

/**
 * struct docg3_cascade - Cascade of 1 to 4 docg3 chips
 * @floors: floors (ie. one physical docg3 chip is one floor)
 * @base: IO space to access all chips in the cascade
 * @bch: the BCH correcting control structure
 * @lock: lock to protect docg3 IO space from concurrent accesses
 */
struct docg3_cascade {
	struct mtd_info *floors[DOC_MAX_NBFLOORS];
	void __iomem *base;
	struct bch_control *bch;
	struct mutex lock;
};

/**
 * struct docg3 - DiskOnChip driver private data
 * @dev: the device currently under control
 * @cascade: the cascade this device belongs to
 * @device_id: number of the cascaded DoCG3 device (0, 1, 2 or 3)
 * @if_cfg: if true, reads are on 16bits, else reads are on 8bits

 * @reliable: if 0, docg3 in normal mode, if 1 docg3 in fast mode, if 2 in
 *            reliable mode
 *            Fast mode implies more errors than normal mode.
 *            Reliable mode implies that page 2*n and 2*n+1 are clones.
 * @bbt: bad block table cache
 * @oob_write_ofs: offset of the MTD where this OOB should belong (ie. in next
 *                 page_write)
 * @oob_autoecc: if 1, use only bytes 0-7, 15, and fill the others with HW ECC
 *               if 0, use all the 16 bytes.
 * @oob_write_buf: prepared OOB for next page_write
 * @debugfs_root: debugfs root node
 */
struct docg3 {
	struct device *dev;
	struct docg3_cascade *cascade;
	unsigned int device_id:4;
	unsigned int if_cfg:1;
	unsigned int reliable:2;
	int max_block;
	u8 *bbt;
	loff_t oob_write_ofs;
	int oob_autoecc;
	u8 oob_write_buf[DOC_LAYOUT_OOB_SIZE];
	struct dentry *debugfs_root;
};

#define doc_err(fmt, arg...) dev_err(docg3->dev, (fmt), ## arg)
#define doc_info(fmt, arg...) dev_info(docg3->dev, (fmt), ## arg)
#define doc_dbg(fmt, arg...) dev_dbg(docg3->dev, (fmt), ## arg)
#define doc_vdbg(fmt, arg...) dev_vdbg(docg3->dev, (fmt), ## arg)

#define DEBUGFS_RO_ATTR(name, show_fct) \
	static int name##_open(struct inode *inode, struct file *file) \
	{ return single_open(file, show_fct, inode->i_private); }      \
	static const struct file_operations name##_fops = { \
		.owner = THIS_MODULE, \
		.open = name##_open, \
		.llseek = seq_lseek, \
		.read = seq_read, \
		.release = single_release \
	};
#endif

/*
 * Trace events part
 */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM docg3

#if !defined(_MTD_DOCG3_TRACE) || defined(TRACE_HEADER_MULTI_READ)
#define _MTD_DOCG3_TRACE

#include <linux/tracepoint.h>

TRACE_EVENT(docg3_io,
	    TP_PROTO(int op, int width, u16 reg, int val),
	    TP_ARGS(op, width, reg, val),
	    TP_STRUCT__entry(
		    __field(int, op)
		    __field(unsigned char, width)
		    __field(u16, reg)
		    __field(int, val)),
	    TP_fast_assign(
		    __entry->op = op;
		    __entry->width = width;
		    __entry->reg = reg;
		    __entry->val = val;),
	    TP_printk("docg3: %s%02d reg=%04x, val=%04x",
		      __entry->op ? "write" : "read", __entry->width,
		      __entry->reg, __entry->val)
	);
#endif

/* This part must be outside protection */
#undef TRACE_INCLUDE_PATH
#undef TRACE_INCLUDE_FILE
#define TRACE_INCLUDE_PATH .
#define TRACE_INCLUDE_FILE docg3
#include <trace/define_trace.h>