|
|
|
@ -50,6 +50,7 @@ struct mxs_nand_info { |
|
|
|
|
int cur_chip; |
|
|
|
|
|
|
|
|
|
uint32_t cmd_queue_len; |
|
|
|
|
uint32_t data_buf_size; |
|
|
|
|
|
|
|
|
|
uint8_t *cmd_buf; |
|
|
|
|
uint8_t *data_buf; |
|
|
|
@ -73,6 +74,36 @@ struct mxs_nand_info { |
|
|
|
|
|
|
|
|
|
struct nand_ecclayout fake_ecc_layout; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Cache management functions |
|
|
|
|
*/ |
|
|
|
|
#ifndef CONFIG_SYS_DCACHE_OFF |
|
|
|
|
static void mxs_nand_flush_data_buf(struct mxs_nand_info *info) |
|
|
|
|
{ |
|
|
|
|
uint32_t addr = (uint32_t)info->data_buf; |
|
|
|
|
|
|
|
|
|
flush_dcache_range(addr, addr + info->data_buf_size); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void mxs_nand_inval_data_buf(struct mxs_nand_info *info) |
|
|
|
|
{ |
|
|
|
|
uint32_t addr = (uint32_t)info->data_buf; |
|
|
|
|
|
|
|
|
|
invalidate_dcache_range(addr, addr + info->data_buf_size); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void mxs_nand_flush_cmd_buf(struct mxs_nand_info *info) |
|
|
|
|
{ |
|
|
|
|
uint32_t addr = (uint32_t)info->cmd_buf; |
|
|
|
|
|
|
|
|
|
flush_dcache_range(addr, addr + MXS_NAND_COMMAND_BUFFER_SIZE); |
|
|
|
|
} |
|
|
|
|
#else |
|
|
|
|
static inline void mxs_nand_flush_data_buf(struct mxs_nand_info *info) {} |
|
|
|
|
static inline void mxs_nand_inval_data_buf(struct mxs_nand_info *info) {} |
|
|
|
|
static inline void mxs_nand_flush_cmd_buf(struct mxs_nand_info *info) {} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
static struct mxs_dma_desc *mxs_nand_get_dma_desc(struct mxs_nand_info *info) |
|
|
|
|
{ |
|
|
|
|
struct mxs_dma_desc *desc; |
|
|
|
@ -286,6 +317,9 @@ static void mxs_nand_cmd_ctrl(struct mtd_info *mtd, int data, unsigned int ctrl) |
|
|
|
|
|
|
|
|
|
mxs_dma_desc_append(channel, d); |
|
|
|
|
|
|
|
|
|
/* Flush caches */ |
|
|
|
|
mxs_nand_flush_cmd_buf(nand_info); |
|
|
|
|
|
|
|
|
|
/* Execute the DMA chain. */ |
|
|
|
|
ret = mxs_dma_go(channel); |
|
|
|
|
if (ret) |
|
|
|
@ -435,6 +469,9 @@ static void mxs_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int length) |
|
|
|
|
goto rtn; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Invalidate caches */ |
|
|
|
|
mxs_nand_inval_data_buf(nand_info); |
|
|
|
|
|
|
|
|
|
memcpy(buf, nand_info->data_buf, length); |
|
|
|
|
|
|
|
|
|
rtn: |
|
|
|
@ -484,6 +521,9 @@ static void mxs_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, |
|
|
|
|
|
|
|
|
|
mxs_dma_desc_append(channel, d); |
|
|
|
|
|
|
|
|
|
/* Flush caches */ |
|
|
|
|
mxs_nand_flush_data_buf(nand_info); |
|
|
|
|
|
|
|
|
|
/* Execute the DMA chain. */ |
|
|
|
|
ret = mxs_dma_go(channel); |
|
|
|
|
if (ret) |
|
|
|
@ -600,6 +640,9 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand, |
|
|
|
|
goto rtn; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Invalidate caches */ |
|
|
|
|
mxs_nand_inval_data_buf(nand_info); |
|
|
|
|
|
|
|
|
|
/* Read DMA completed, now do the mark swapping. */ |
|
|
|
|
mxs_nand_swap_block_mark(mtd, nand_info->data_buf, nand_info->oob_buf); |
|
|
|
|
|
|
|
|
@ -687,6 +730,9 @@ static void mxs_nand_ecc_write_page(struct mtd_info *mtd, |
|
|
|
|
|
|
|
|
|
mxs_dma_desc_append(channel, d); |
|
|
|
|
|
|
|
|
|
/* Flush caches */ |
|
|
|
|
mxs_nand_flush_data_buf(nand_info); |
|
|
|
|
|
|
|
|
|
/* Execute the DMA chain. */ |
|
|
|
|
ret = mxs_dma_go(channel); |
|
|
|
|
if (ret) { |
|
|
|
@ -978,18 +1024,19 @@ int mxs_nand_alloc_buffers(struct mxs_nand_info *nand_info) |
|
|
|
|
uint8_t *buf; |
|
|
|
|
const int size = NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE; |
|
|
|
|
|
|
|
|
|
nand_info->data_buf_size = roundup(size, MXS_DMA_ALIGNMENT); |
|
|
|
|
|
|
|
|
|
/* DMA buffers */ |
|
|
|
|
buf = memalign(MXS_DMA_ALIGNMENT, size); |
|
|
|
|
buf = memalign(MXS_DMA_ALIGNMENT, nand_info->data_buf_size); |
|
|
|
|
if (!buf) { |
|
|
|
|
printf("MXS NAND: Error allocating DMA buffers\n"); |
|
|
|
|
return -ENOMEM; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
memset(buf, 0, size); |
|
|
|
|
memset(buf, 0, nand_info->data_buf_size); |
|
|
|
|
|
|
|
|
|
nand_info->data_buf = buf; |
|
|
|
|
nand_info->oob_buf = buf + NAND_MAX_PAGESIZE; |
|
|
|
|
|
|
|
|
|
/* Command buffers */ |
|
|
|
|
nand_info->cmd_buf = memalign(MXS_DMA_ALIGNMENT, |
|
|
|
|
MXS_NAND_COMMAND_BUFFER_SIZE); |
|
|
|
|