Commit 6b9408edd3f6af6e91bcc0eebd4aedc0aca28934

Authored by Marek Vasut
Committed by Albert ARIBAUD
1 parent c3dfe70776

i.MX28: Add cache support to MXS NAND driver

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Stefano Babic <sbabic@denx.de>

Showing 1 changed file with 50 additions and 3 deletions Side-by-side Diff

drivers/mtd/nand/mxs_nand.c
... ... @@ -50,6 +50,7 @@
50 50 int cur_chip;
51 51  
52 52 uint32_t cmd_queue_len;
  53 + uint32_t data_buf_size;
53 54  
54 55 uint8_t *cmd_buf;
55 56 uint8_t *data_buf;
... ... @@ -73,6 +74,36 @@
73 74  
74 75 struct nand_ecclayout fake_ecc_layout;
75 76  
  77 +/*
  78 + * Cache management functions
  79 + */
  80 +#ifndef CONFIG_SYS_DCACHE_OFF
  81 +static void mxs_nand_flush_data_buf(struct mxs_nand_info *info)
  82 +{
  83 + uint32_t addr = (uint32_t)info->data_buf;
  84 +
  85 + flush_dcache_range(addr, addr + info->data_buf_size);
  86 +}
  87 +
  88 +static void mxs_nand_inval_data_buf(struct mxs_nand_info *info)
  89 +{
  90 + uint32_t addr = (uint32_t)info->data_buf;
  91 +
  92 + invalidate_dcache_range(addr, addr + info->data_buf_size);
  93 +}
  94 +
  95 +static void mxs_nand_flush_cmd_buf(struct mxs_nand_info *info)
  96 +{
  97 + uint32_t addr = (uint32_t)info->cmd_buf;
  98 +
  99 + flush_dcache_range(addr, addr + MXS_NAND_COMMAND_BUFFER_SIZE);
  100 +}
  101 +#else
  102 +static inline void mxs_nand_flush_data_buf(struct mxs_nand_info *info) {}
  103 +static inline void mxs_nand_inval_data_buf(struct mxs_nand_info *info) {}
  104 +static inline void mxs_nand_flush_cmd_buf(struct mxs_nand_info *info) {}
  105 +#endif
  106 +
76 107 static struct mxs_dma_desc *mxs_nand_get_dma_desc(struct mxs_nand_info *info)
77 108 {
78 109 struct mxs_dma_desc *desc;
... ... @@ -286,6 +317,9 @@
286 317  
287 318 mxs_dma_desc_append(channel, d);
288 319  
  320 + /* Flush caches */
  321 + mxs_nand_flush_cmd_buf(nand_info);
  322 +
289 323 /* Execute the DMA chain. */
290 324 ret = mxs_dma_go(channel);
291 325 if (ret)
... ... @@ -435,6 +469,9 @@
435 469 goto rtn;
436 470 }
437 471  
  472 + /* Invalidate caches */
  473 + mxs_nand_inval_data_buf(nand_info);
  474 +
438 475 memcpy(buf, nand_info->data_buf, length);
439 476  
440 477 rtn:
... ... @@ -484,6 +521,9 @@
484 521  
485 522 mxs_dma_desc_append(channel, d);
486 523  
  524 + /* Flush caches */
  525 + mxs_nand_flush_data_buf(nand_info);
  526 +
487 527 /* Execute the DMA chain. */
488 528 ret = mxs_dma_go(channel);
489 529 if (ret)
... ... @@ -600,6 +640,9 @@
600 640 goto rtn;
601 641 }
602 642  
  643 + /* Invalidate caches */
  644 + mxs_nand_inval_data_buf(nand_info);
  645 +
603 646 /* Read DMA completed, now do the mark swapping. */
604 647 mxs_nand_swap_block_mark(mtd, nand_info->data_buf, nand_info->oob_buf);
605 648  
... ... @@ -687,6 +730,9 @@
687 730  
688 731 mxs_dma_desc_append(channel, d);
689 732  
  733 + /* Flush caches */
  734 + mxs_nand_flush_data_buf(nand_info);
  735 +
690 736 /* Execute the DMA chain. */
691 737 ret = mxs_dma_go(channel);
692 738 if (ret) {
693 739  
694 740  
695 741  
... ... @@ -978,18 +1024,19 @@
978 1024 uint8_t *buf;
979 1025 const int size = NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE;
980 1026  
  1027 + nand_info->data_buf_size = roundup(size, MXS_DMA_ALIGNMENT);
  1028 +
981 1029 /* DMA buffers */
982   - buf = memalign(MXS_DMA_ALIGNMENT, size);
  1030 + buf = memalign(MXS_DMA_ALIGNMENT, nand_info->data_buf_size);
983 1031 if (!buf) {
984 1032 printf("MXS NAND: Error allocating DMA buffers\n");
985 1033 return -ENOMEM;
986 1034 }
987 1035  
988   - memset(buf, 0, size);
  1036 + memset(buf, 0, nand_info->data_buf_size);
989 1037  
990 1038 nand_info->data_buf = buf;
991 1039 nand_info->oob_buf = buf + NAND_MAX_PAGESIZE;
992   -
993 1040 /* Command buffers */
994 1041 nand_info->cmd_buf = memalign(MXS_DMA_ALIGNMENT,
995 1042 MXS_NAND_COMMAND_BUFFER_SIZE);