diff options
author | Lei Wen <leiwen@marvell.com> | 2010-08-17 02:09:30 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2010-10-24 18:39:41 -0400 |
commit | 9d8b10437441e7f31ce86202ccadad922a9e914f (patch) | |
tree | a1f3b9953e27ee7bf8675fae5a0e037095f55101 /drivers/mtd/nand/pxa3xx_nand.c | |
parent | 18c81b1828f8c4bdd01dd24f4015604a17ca0bb8 (diff) |
mtd: pxa3xx_nand: set oob length in the runtime
For different command need different oob requirement, set the proper
oob length by different cmd.
Signed-off-by: Lei Wen <leiwen@marvell.com>
Acked-by: Eric Miao <eric.y.miao@gmail.com>
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd/nand/pxa3xx_nand.c')
-rw-r--r-- | drivers/mtd/nand/pxa3xx_nand.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index cafd8e4946bc..17f8518cc5eb 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c | |||
@@ -273,13 +273,20 @@ static int wait_for_event(struct pxa3xx_nand_info *info, uint32_t event) | |||
273 | 273 | ||
274 | static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info) | 274 | static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info) |
275 | { | 275 | { |
276 | /* calculate data size */ | 276 | int oob_enable = info->reg_ndcr & NDCR_SPARE_EN; |
277 | |||
278 | info->data_size = info->page_size; | ||
279 | if (!oob_enable) { | ||
280 | info->oob_size = 0; | ||
281 | return; | ||
282 | } | ||
283 | |||
277 | switch (info->page_size) { | 284 | switch (info->page_size) { |
278 | case 2048: | 285 | case 2048: |
279 | info->data_size = (info->use_ecc) ? 2088 : 2112; | 286 | info->oob_size = (info->use_ecc) ? 40 : 64; |
280 | break; | 287 | break; |
281 | case 512: | 288 | case 512: |
282 | info->data_size = (info->use_ecc) ? 520 : 528; | 289 | info->oob_size = (info->use_ecc) ? 8 : 16; |
283 | break; | 290 | break; |
284 | } | 291 | } |
285 | } | 292 | } |
@@ -333,6 +340,7 @@ static int prepare_other_cmd(struct pxa3xx_nand_info *info, uint16_t cmd) | |||
333 | info->ndcb1 = 0; | 340 | info->ndcb1 = 0; |
334 | info->ndcb2 = 0; | 341 | info->ndcb2 = 0; |
335 | 342 | ||
343 | info->oob_size = 0; | ||
336 | if (cmd == cmdset->read_id) { | 344 | if (cmd == cmdset->read_id) { |
337 | info->ndcb0 |= NDCB0_CMD_TYPE(3); | 345 | info->ndcb0 |= NDCB0_CMD_TYPE(3); |
338 | info->data_size = 8; | 346 | info->data_size = 8; |
@@ -401,6 +409,9 @@ static int handle_data_pio(struct pxa3xx_nand_info *info) | |||
401 | case STATE_PIO_WRITING: | 409 | case STATE_PIO_WRITING: |
402 | __raw_writesl(info->mmio_base + NDDB, info->data_buff, | 410 | __raw_writesl(info->mmio_base + NDDB, info->data_buff, |
403 | DIV_ROUND_UP(info->data_size, 4)); | 411 | DIV_ROUND_UP(info->data_size, 4)); |
412 | if (info->oob_size > 0) | ||
413 | __raw_writesl(info->mmio_base + NDDB, info->oob_buff, | ||
414 | DIV_ROUND_UP(info->oob_size, 4)); | ||
404 | 415 | ||
405 | enable_int(info, NDSR_CS0_BBD | NDSR_CS0_CMDD); | 416 | enable_int(info, NDSR_CS0_BBD | NDSR_CS0_CMDD); |
406 | 417 | ||
@@ -413,6 +424,9 @@ static int handle_data_pio(struct pxa3xx_nand_info *info) | |||
413 | case STATE_PIO_READING: | 424 | case STATE_PIO_READING: |
414 | __raw_readsl(info->mmio_base + NDDB, info->data_buff, | 425 | __raw_readsl(info->mmio_base + NDDB, info->data_buff, |
415 | DIV_ROUND_UP(info->data_size, 4)); | 426 | DIV_ROUND_UP(info->data_size, 4)); |
427 | if (info->oob_size > 0) | ||
428 | __raw_readsl(info->mmio_base + NDDB, info->oob_buff, | ||
429 | DIV_ROUND_UP(info->oob_size, 4)); | ||
416 | break; | 430 | break; |
417 | default: | 431 | default: |
418 | printk(KERN_ERR "%s: invalid state %d\n", __func__, | 432 | printk(KERN_ERR "%s: invalid state %d\n", __func__, |
@@ -427,7 +441,7 @@ static int handle_data_pio(struct pxa3xx_nand_info *info) | |||
427 | static void start_data_dma(struct pxa3xx_nand_info *info, int dir_out) | 441 | static void start_data_dma(struct pxa3xx_nand_info *info, int dir_out) |
428 | { | 442 | { |
429 | struct pxa_dma_desc *desc = info->data_desc; | 443 | struct pxa_dma_desc *desc = info->data_desc; |
430 | int dma_len = ALIGN(info->data_size, 32); | 444 | int dma_len = ALIGN(info->data_size + info->oob_size, 32); |
431 | 445 | ||
432 | desc->ddadr = DDADR_STOP; | 446 | desc->ddadr = DDADR_STOP; |
433 | desc->dcmd = DCMD_ENDIRQEN | DCMD_WIDTH4 | DCMD_BURST32 | dma_len; | 447 | desc->dcmd = DCMD_ENDIRQEN | DCMD_WIDTH4 | DCMD_BURST32 | dma_len; |
@@ -833,7 +847,6 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info, | |||
833 | info->cmdset = f->cmdset; | 847 | info->cmdset = f->cmdset; |
834 | info->page_size = f->page_size; | 848 | info->page_size = f->page_size; |
835 | info->oob_buff = info->data_buff + f->page_size; | 849 | info->oob_buff = info->data_buff + f->page_size; |
836 | info->oob_size = (f->page_size == 2048) ? 64 : 16; | ||
837 | info->read_id_bytes = (f->page_size == 2048) ? 4 : 2; | 850 | info->read_id_bytes = (f->page_size == 2048) ? 4 : 2; |
838 | 851 | ||
839 | /* calculate addressing information */ | 852 | /* calculate addressing information */ |
@@ -892,8 +905,6 @@ static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info) | |||
892 | i = __ffs(page_per_block * info->page_size); | 905 | i = __ffs(page_per_block * info->page_size); |
893 | num_blocks = type->chipsize << (20 - i); | 906 | num_blocks = type->chipsize << (20 - i); |
894 | 907 | ||
895 | info->oob_size = (info->page_size == 2048) ? 64 : 16; | ||
896 | |||
897 | /* calculate addressing information */ | 908 | /* calculate addressing information */ |
898 | info->col_addr_cycles = (info->page_size == 2048) ? 2 : 1; | 909 | info->col_addr_cycles = (info->page_size == 2048) ? 2 : 1; |
899 | 910 | ||