diff options
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/nand/denali.c | 39 | ||||
-rw-r--r-- | drivers/mtd/nand/denali.h | 1 |
2 files changed, 36 insertions, 4 deletions
diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index b95e33a84201..417a8950cf49 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c @@ -979,8 +979,30 @@ static void denali_enable_dma(struct denali_nand_info *denali, bool en) ioread32(denali->flash_reg + DMA_ENABLE); } -/* setups the HW to perform the data DMA */ -static void denali_setup_dma(struct denali_nand_info *denali, int op) +static void denali_setup_dma64(struct denali_nand_info *denali, int op) +{ + uint32_t mode; + const int page_count = 1; + uint64_t addr = denali->buf.dma_buf; + + mode = MODE_10 | BANK(denali->flash_bank) | denali->page; + + /* DMA is a three step process */ + + /* + * 1. setup transfer type, interrupt when complete, + * burst len = 64 bytes, the number of pages + */ + index_addr(denali, mode, 0x01002000 | (64 << 16) | op | page_count); + + /* 2. set memory low address */ + index_addr(denali, mode, addr); + + /* 3. set memory high address */ + index_addr(denali, mode, addr >> 32); +} + +static void denali_setup_dma32(struct denali_nand_info *denali, int op) { uint32_t mode; const int page_count = 1; @@ -1003,6 +1025,14 @@ static void denali_setup_dma(struct denali_nand_info *denali, int op) index_addr(denali, mode | 0x14000, 0x2400); } +static void denali_setup_dma(struct denali_nand_info *denali, int op) +{ + if (denali->caps & DENALI_CAP_DMA_64BIT) + denali_setup_dma64(denali, op); + else + denali_setup_dma32(denali, op); +} + /* * writes a page. user specifies type, and this function handles the * configuration details. @@ -1518,8 +1548,9 @@ int denali_init(struct denali_nand_info *denali) goto failed_req_irq; } - /* Is 32-bit DMA supported? */ - ret = dma_set_mask(denali->dev, DMA_BIT_MASK(32)); + ret = dma_set_mask(denali->dev, + DMA_BIT_MASK(denali->caps & DENALI_CAP_DMA_64BIT ? + 64 : 32)); if (ret) { dev_err(denali->dev, "No usable DMA configuration\n"); goto failed_req_irq; diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/denali.h index e532956b7177..1f413d05a010 100644 --- a/drivers/mtd/nand/denali.h +++ b/drivers/mtd/nand/denali.h @@ -347,6 +347,7 @@ struct denali_nand_info { }; #define DENALI_CAP_HW_ECC_FIXUP BIT(0) +#define DENALI_CAP_DMA_64BIT BIT(1) extern int denali_init(struct denali_nand_info *denali); extern void denali_remove(struct denali_nand_info *denali); |