diff options
author | Jamie Iles <jamie@jamieiles.com> | 2011-05-06 14:28:57 (GMT) |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2011-05-25 01:02:12 (GMT) |
commit | c89eeda810f0ec4f0eee0206ebb79e476df9f83e (patch) | |
tree | e01415f166a82c05b1bc4e339dda8b47689716c5 | |
parent | 9589bf5bed2936a159fc96c96339f15a512fdfa9 (diff) | |
download | linux-c89eeda810f0ec4f0eee0206ebb79e476df9f83e.tar.xz |
mtd: denali: detect the number of banks
Not all configurations of the Denali controller support 4 banks. The
controller can support between 1 and 16 banks. Detect this from the
design features register.
Signed-off-by: Jamie Iles <jamie@jamieiles.com>
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
-rw-r--r-- | drivers/mtd/nand/denali.c | 28 | ||||
-rw-r--r-- | drivers/mtd/nand/denali.h | 2 |
2 files changed, 21 insertions, 9 deletions
diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index 5568640..8c5dc89 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c @@ -178,11 +178,11 @@ static uint16_t denali_nand_reset(struct denali_nand_info *denali) dev_dbg(denali->dev, "%s, Line %d, Function: %s\n", __FILE__, __LINE__, __func__); - for (i = 0 ; i < LLD_MAX_FLASH_BANKS; i++) + for (i = 0 ; i < denali->max_banks; i++) iowrite32(INTR_STATUS__RST_COMP | INTR_STATUS__TIME_OUT, denali->flash_reg + INTR_STATUS(i)); - for (i = 0 ; i < LLD_MAX_FLASH_BANKS; i++) { + for (i = 0 ; i < denali->max_banks; i++) { iowrite32(1 << i, denali->flash_reg + DEVICE_RESET); while (!(ioread32(denali->flash_reg + INTR_STATUS(i)) & @@ -194,7 +194,7 @@ static uint16_t denali_nand_reset(struct denali_nand_info *denali) "NAND Reset operation timed out on bank %d\n", i); } - for (i = 0; i < LLD_MAX_FLASH_BANKS; i++) + for (i = 0; i < denali->max_banks; i++) iowrite32(INTR_STATUS__RST_COMP | INTR_STATUS__TIME_OUT, denali->flash_reg + INTR_STATUS(i)); @@ -405,11 +405,11 @@ static void get_hynix_nand_para(struct denali_nand_info *denali, */ static void find_valid_banks(struct denali_nand_info *denali) { - uint32_t id[LLD_MAX_FLASH_BANKS]; + uint32_t id[denali->max_banks]; int i; denali->total_used_banks = 1; - for (i = 0; i < LLD_MAX_FLASH_BANKS; i++) { + for (i = 0; i < denali->max_banks; i++) { index_addr(denali, (uint32_t)(MODE_11 | (i << 24) | 0), 0x90); index_addr(denali, (uint32_t)(MODE_11 | (i << 24) | 1), 0); index_addr_read_data(denali, @@ -445,6 +445,17 @@ static void find_valid_banks(struct denali_nand_info *denali) "denali->total_used_banks: %d\n", denali->total_used_banks); } +/* + * Use the configuration feature register to determine the maximum number of + * banks that the hardware supports. + */ +static void detect_max_banks(struct denali_nand_info *denali) +{ + uint32_t features = ioread32(denali->flash_reg + FEATURES); + + denali->max_banks = 2 << (features & FEATURES__N_BANKS); +} + static void detect_partition_feature(struct denali_nand_info *denali) { /* For MRST platform, denali->fwblks represent the @@ -562,7 +573,7 @@ static void denali_irq_init(struct denali_nand_info *denali) int_mask = DENALI_IRQ_ALL; /* Clear all status bits */ - for (i = 0; i < LLD_MAX_FLASH_BANKS; ++i) + for (i = 0; i < denali->max_banks; ++i) iowrite32(0xFFFF, denali->flash_reg + INTR_STATUS(i)); denali_irq_enable(denali, int_mask); @@ -579,7 +590,7 @@ static void denali_irq_enable(struct denali_nand_info *denali, { int i; - for (i = 0; i < LLD_MAX_FLASH_BANKS; ++i) + for (i = 0; i < denali->max_banks; ++i) iowrite32(int_mask, denali->flash_reg + INTR_EN(i)); } @@ -1345,6 +1356,7 @@ static void denali_hw_init(struct denali_nand_info *denali) /* Should set value for these registers when init */ iowrite32(0, denali->flash_reg + TWO_ROW_ADDR_CYCLES); iowrite32(1, denali->flash_reg + ECC_ENABLE); + detect_max_banks(denali); denali_nand_timing_set(denali); denali_irq_init(denali); } @@ -1522,7 +1534,7 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) /* scan for NAND devices attached to the controller * this is the first stage in a two step process to register * with the nand subsystem */ - if (nand_scan_ident(&denali->mtd, LLD_MAX_FLASH_BANKS, NULL)) { + if (nand_scan_ident(&denali->mtd, denali->max_banks, NULL)) { ret = -ENXIO; goto failed_req_irq; } diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/denali.h index 638668c..fabb9d5 100644 --- a/drivers/mtd/nand/denali.h +++ b/drivers/mtd/nand/denali.h @@ -454,7 +454,6 @@ #define READ_WRITE_ENABLE_HIGH_COUNT 22 #define ECC_SECTOR_SIZE 512 -#define LLD_MAX_FLASH_BANKS 4 #define DENALI_BUF_SIZE (NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE) @@ -494,6 +493,7 @@ struct denali_nand_info { uint32_t totalblks; uint32_t blksperchip; uint32_t bbtskipbytes; + uint32_t max_banks; }; #endif /*_LLD_NAND_*/ |