1 From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
2 Date: Wed, 10 Feb 2016 14:54:21 +0100
3 Subject: [PATCH] mtd: nand: pxa3xx_nand: add support for partial chunks
5 This commit is needed to properly support the 8-bits ECC configuration
8 When pages larger than 2 KB are used on platforms using the PXA3xx
9 NAND controller, the reading/programming operations need to be split
10 in chunks of 2 KBs or less because the controller FIFO is limited to
11 about 2 KB (i.e a bit more than 2 KB to accommodate OOB data). Due to
12 this requirement, the data layout on NAND is a bit strange, with ECC
13 interleaved with data, at the end of each chunk.
15 When a 4-bits ECC configuration is used with 4 KB pages, the physical
16 data layout on the NAND looks like this:
18 | 2048 data | 32 spare | 30 ECC | 2048 data | 32 spare | 30 ECC |
20 So the data chunks have an equal size, 2080 bytes for each chunk,
21 which the driver supports properly.
23 When a 8-bits ECC configuration is used with 4KB pages, the physical
24 data layout on the NAND looks like this:
26 | 1024 data | 30 ECC | 1024 data | 30 ECC | 1024 data | 30 ECC | 1024 data | 30 ECC | 64 spare | 30 ECC |
28 So, the spare area is stored in its own chunk, which has a different
29 size than the other chunks. Since OOB is not used by UBIFS, the initial
30 implementation of the driver has chosen to not support reading this
31 additional "spare" chunk of data.
33 Unfortunately, Marvell has chosen to store the BBT signature in the
34 OOB area. Therefore, if the driver doesn't read this spare area, Linux
35 has no way of finding the BBT. It thinks there is no BBT, and rewrites
36 one, which U-Boot does not recognize, causing compatibility problems
37 between the bootloader and the kernel in terms of NAND usage.
39 To fix this, this commit implements the support for reading a partial
40 last chunk. This support is currently only useful for the case of 8
41 bits ECC with 4 KB pages, but it will be useful in the future to
42 enable other configurations such as 12 bits and 16 bits ECC with 4 KB
43 pages, or 8 bits ECC with 8 KB pages, etc. All those configurations
44 have a "last" chunk that doesn't have the same size as the other
47 In order to implement reading of the last chunk, this commit:
49 - Adds a number of new fields to the pxa3xx_nand_info to describe how
50 many full chunks and how many chunks we have, the size of full
51 chunks and partial chunks, both in terms of data area and spare
54 - Fills in the step_chunk_size and step_spare_size variables to
55 describe how much data and spare should be read/written for the
56 current read/program step.
58 - Reworks the state machine to accommodate doing the additional read
59 or program step when a last partial chunk is used.
61 This commit has been tested on a Marvell Armada 398 DB board, with a
62 4KB page NAND, tested in both 4 bits ECC and 8 bits ECC
63 configurations. Robert Jarzmik has tested on some PXA platforms.
65 Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
66 Tested-by: Robert Jarzmik <robert.jarzmik@free.fr>
67 Acked-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
68 Signed-off-by: Brian Norris <computersforpeace@gmail.com>
71 --- a/drivers/mtd/nand/pxa3xx_nand.c
72 +++ b/drivers/mtd/nand/pxa3xx_nand.c
73 @@ -228,15 +228,44 @@ struct pxa3xx_nand_info {
74 int use_spare; /* use spare ? */
77 - unsigned int data_size; /* data to be read from FIFO */
78 - unsigned int chunk_size; /* split commands chunk size */
79 - unsigned int oob_size;
80 + /* Amount of real data per full chunk */
81 + unsigned int chunk_size;
83 + /* Amount of spare data per full chunk */
84 unsigned int spare_size;
86 + /* Number of full chunks (i.e chunk_size + spare_size) */
87 + unsigned int nfullchunks;
90 + * Total number of chunks. If equal to nfullchunks, then there
91 + * are only full chunks. Otherwise, there is one last chunk of
92 + * size (last_chunk_size + last_spare_size)
94 + unsigned int ntotalchunks;
96 + /* Amount of real data in the last chunk */
97 + unsigned int last_chunk_size;
99 + /* Amount of spare data in the last chunk */
100 + unsigned int last_spare_size;
102 unsigned int ecc_size;
103 unsigned int ecc_err_cnt;
104 unsigned int max_bitflips;
108 + * Variables only valid during command
109 + * execution. step_chunk_size and step_spare_size is the
110 + * amount of real data and spare data in the current
111 + * chunk. cur_chunk is the current chunk being
114 + unsigned int step_chunk_size;
115 + unsigned int step_spare_size;
116 + unsigned int cur_chunk;
118 /* cached register value */
121 @@ -531,25 +560,6 @@ static int pxa3xx_nand_init(struct pxa3x
126 - * Set the data and OOB size, depending on the selected
127 - * spare and ECC configuration.
128 - * Only applicable to READ0, READOOB and PAGEPROG commands.
130 -static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info,
131 - struct mtd_info *mtd)
133 - int oob_enable = info->reg_ndcr & NDCR_SPARE_EN;
135 - info->data_size = mtd->writesize;
139 - info->oob_size = info->spare_size;
140 - if (!info->use_ecc)
141 - info->oob_size += info->ecc_size;
145 * NOTE: it is a must to set ND_RUN firstly, then write
146 * command buffer, otherwise, it does not work.
147 @@ -665,28 +675,28 @@ static void drain_fifo(struct pxa3xx_nan
149 static void handle_data_pio(struct pxa3xx_nand_info *info)
151 - unsigned int do_bytes = min(info->data_size, info->chunk_size);
153 switch (info->state) {
154 case STATE_PIO_WRITING:
155 - writesl(info->mmio_base + NDDB,
156 - info->data_buff + info->data_buff_pos,
157 - DIV_ROUND_UP(do_bytes, 4));
158 + if (info->step_chunk_size)
159 + writesl(info->mmio_base + NDDB,
160 + info->data_buff + info->data_buff_pos,
161 + DIV_ROUND_UP(info->step_chunk_size, 4));
163 - if (info->oob_size > 0)
164 + if (info->step_spare_size)
165 writesl(info->mmio_base + NDDB,
166 info->oob_buff + info->oob_buff_pos,
167 - DIV_ROUND_UP(info->oob_size, 4));
168 + DIV_ROUND_UP(info->step_spare_size, 4));
170 case STATE_PIO_READING:
172 - info->data_buff + info->data_buff_pos,
173 - DIV_ROUND_UP(do_bytes, 4));
174 + if (info->step_chunk_size)
176 + info->data_buff + info->data_buff_pos,
177 + DIV_ROUND_UP(info->step_chunk_size, 4));
179 - if (info->oob_size > 0)
180 + if (info->step_spare_size)
182 info->oob_buff + info->oob_buff_pos,
183 - DIV_ROUND_UP(info->oob_size, 4));
184 + DIV_ROUND_UP(info->step_spare_size, 4));
187 dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__,
188 @@ -695,9 +705,8 @@ static void handle_data_pio(struct pxa3x
191 /* Update buffer pointers for multi-page read/write */
192 - info->data_buff_pos += do_bytes;
193 - info->oob_buff_pos += info->oob_size;
194 - info->data_size -= do_bytes;
195 + info->data_buff_pos += info->step_chunk_size;
196 + info->oob_buff_pos += info->step_spare_size;
199 static void pxa3xx_nand_data_dma_irq(void *data)
200 @@ -738,8 +747,9 @@ static void start_data_dma(struct pxa3xx
204 - info->sg.length = info->data_size +
205 - (info->oob_size ? info->spare_size + info->ecc_size : 0);
206 + info->sg.length = info->chunk_size;
207 + if (info->use_spare)
208 + info->sg.length += info->spare_size + info->ecc_size;
209 dma_map_sg(info->dma_chan->device->dev, &info->sg, 1, info->dma_dir);
211 tx = dmaengine_prep_slave_sg(info->dma_chan, &info->sg, 1, direction,
212 @@ -900,9 +910,11 @@ static void prepare_start_command(struct
213 /* reset data and oob column point to handle data */
216 - info->oob_size = 0;
217 info->data_buff_pos = 0;
218 info->oob_buff_pos = 0;
219 + info->step_chunk_size = 0;
220 + info->step_spare_size = 0;
221 + info->cur_chunk = 0;
224 info->retcode = ERR_NONE;
225 @@ -914,8 +926,6 @@ static void prepare_start_command(struct
227 case NAND_CMD_PAGEPROG:
229 - case NAND_CMD_READOOB:
230 - pxa3xx_set_datasize(info, mtd);
234 @@ -974,6 +984,14 @@ static int prepare_set_command(struct px
235 if (command == NAND_CMD_READOOB)
236 info->buf_start += mtd->writesize;
238 + if (info->cur_chunk < info->nfullchunks) {
239 + info->step_chunk_size = info->chunk_size;
240 + info->step_spare_size = info->spare_size;
242 + info->step_chunk_size = info->last_chunk_size;
243 + info->step_spare_size = info->last_spare_size;
247 * Multiple page read needs an 'extended command type' field,
248 * which is either naked-read or last-read according to the
249 @@ -985,8 +1003,8 @@ static int prepare_set_command(struct px
250 info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8)
252 | NDCB0_EXT_CMD_TYPE(ext_cmd_type);
253 - info->ndcb3 = info->chunk_size +
255 + info->ndcb3 = info->step_chunk_size +
256 + info->step_spare_size;
259 set_command_address(info, mtd->writesize, column, page_addr);
260 @@ -1006,8 +1024,6 @@ static int prepare_set_command(struct px
261 | NDCB0_EXT_CMD_TYPE(ext_cmd_type)
264 - /* No data transfer in this case */
265 - info->data_size = 0;
269 @@ -1019,6 +1035,14 @@ static int prepare_set_command(struct px
273 + if (info->cur_chunk < info->nfullchunks) {
274 + info->step_chunk_size = info->chunk_size;
275 + info->step_spare_size = info->spare_size;
277 + info->step_chunk_size = info->last_chunk_size;
278 + info->step_spare_size = info->last_spare_size;
281 /* Second command setting for large pages */
282 if (mtd->writesize > PAGE_CHUNK_SIZE) {
284 @@ -1029,14 +1053,14 @@ static int prepare_set_command(struct px
285 info->ndcb0 |= NDCB0_CMD_TYPE(0x1)
287 | NDCB0_EXT_CMD_TYPE(ext_cmd_type);
288 - info->ndcb3 = info->chunk_size +
290 + info->ndcb3 = info->step_chunk_size +
291 + info->step_spare_size;
294 * This is the command dispatch that completes a chunked
295 * page program operation.
297 - if (info->data_size == 0) {
298 + if (info->cur_chunk == info->ntotalchunks) {
299 info->ndcb0 = NDCB0_CMD_TYPE(0x1)
300 | NDCB0_EXT_CMD_TYPE(ext_cmd_type)
302 @@ -1063,7 +1087,7 @@ static int prepare_set_command(struct px
304 info->ndcb1 = (column & 0xFF);
305 info->ndcb3 = INIT_BUFFER_SIZE;
306 - info->data_size = INIT_BUFFER_SIZE;
307 + info->step_chunk_size = INIT_BUFFER_SIZE;
310 case NAND_CMD_READID:
311 @@ -1073,7 +1097,7 @@ static int prepare_set_command(struct px
313 info->ndcb1 = (column & 0xFF);
315 - info->data_size = 8;
316 + info->step_chunk_size = 8;
318 case NAND_CMD_STATUS:
320 @@ -1081,7 +1105,7 @@ static int prepare_set_command(struct px
324 - info->data_size = 8;
325 + info->step_chunk_size = 8;
328 case NAND_CMD_ERASE1:
329 @@ -1220,6 +1244,7 @@ static void nand_cmdfunc_extended(struct
330 init_completion(&info->dev_ready);
332 info->state = STATE_PREPARED;
334 exec_cmd = prepare_set_command(info, command, ext_cmd_type,
337 @@ -1239,22 +1264,30 @@ static void nand_cmdfunc_extended(struct
341 + /* Only a few commands need several steps */
342 + if (command != NAND_CMD_PAGEPROG &&
343 + command != NAND_CMD_READ0 &&
344 + command != NAND_CMD_READOOB)
349 /* Check if the sequence is complete */
350 - if (info->data_size == 0 && command != NAND_CMD_PAGEPROG)
351 + if (info->cur_chunk == info->ntotalchunks && command != NAND_CMD_PAGEPROG)
355 * After a splitted program command sequence has issued
356 * the command dispatch, the command sequence is complete.
358 - if (info->data_size == 0 &&
359 + if (info->cur_chunk == (info->ntotalchunks + 1) &&
360 command == NAND_CMD_PAGEPROG &&
361 ext_cmd_type == EXT_CMD_TYPE_DISPATCH)
364 if (command == NAND_CMD_READ0 || command == NAND_CMD_READOOB) {
365 /* Last read: issue a 'last naked read' */
366 - if (info->data_size == info->chunk_size)
367 + if (info->cur_chunk == info->ntotalchunks - 1)
368 ext_cmd_type = EXT_CMD_TYPE_LAST_RW;
370 ext_cmd_type = EXT_CMD_TYPE_NAKED_RW;
371 @@ -1264,7 +1297,7 @@ static void nand_cmdfunc_extended(struct
372 * the command dispatch must be issued to complete.
374 } else if (command == NAND_CMD_PAGEPROG &&
375 - info->data_size == 0) {
376 + info->cur_chunk == info->ntotalchunks) {
377 ext_cmd_type = EXT_CMD_TYPE_DISPATCH;
380 @@ -1514,6 +1547,8 @@ static int pxa_ecc_init(struct pxa3xx_na
381 int strength, int ecc_stepsize, int page_size)
383 if (strength == 1 && ecc_stepsize == 512 && page_size == 2048) {
384 + info->nfullchunks = 1;
385 + info->ntotalchunks = 1;
386 info->chunk_size = 2048;
387 info->spare_size = 40;
389 @@ -1522,6 +1557,8 @@ static int pxa_ecc_init(struct pxa3xx_na
392 } else if (strength == 1 && ecc_stepsize == 512 && page_size == 512) {
393 + info->nfullchunks = 1;
394 + info->ntotalchunks = 1;
395 info->chunk_size = 512;
396 info->spare_size = 8;
398 @@ -1535,6 +1572,8 @@ static int pxa_ecc_init(struct pxa3xx_na
400 } else if (strength == 4 && ecc_stepsize == 512 && page_size == 2048) {
402 + info->nfullchunks = 1;
403 + info->ntotalchunks = 1;
404 info->chunk_size = 2048;
405 info->spare_size = 32;
407 @@ -1545,6 +1584,8 @@ static int pxa_ecc_init(struct pxa3xx_na
409 } else if (strength == 4 && ecc_stepsize == 512 && page_size == 4096) {
411 + info->nfullchunks = 2;
412 + info->ntotalchunks = 2;
413 info->chunk_size = 2048;
414 info->spare_size = 32;
416 @@ -1559,8 +1600,12 @@ static int pxa_ecc_init(struct pxa3xx_na
418 } else if (strength == 8 && ecc_stepsize == 512 && page_size == 4096) {
420 + info->nfullchunks = 4;
421 + info->ntotalchunks = 5;
422 info->chunk_size = 1024;
423 info->spare_size = 0;
424 + info->last_chunk_size = 0;
425 + info->last_spare_size = 64;
427 ecc->mode = NAND_ECC_HW;
428 ecc->size = info->chunk_size;