diff options
author | Jamie Iles <jamie@jamieiles.com> | 2011-05-06 10:28:57 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2011-05-24 21:02:12 -0400 |
commit | c89eeda810f0ec4f0eee0206ebb79e476df9f83e (patch) | |
tree | e01415f166a82c05b1bc4e339dda8b47689716c5 | |
parent | 9589bf5bed2936a159fc96c96339f15a512fdfa9 (diff) |
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 5568640cb3ba..8c5dc89da2d2 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) | |||
178 | dev_dbg(denali->dev, "%s, Line %d, Function: %s\n", | 178 | dev_dbg(denali->dev, "%s, Line %d, Function: %s\n", |
179 | __FILE__, __LINE__, __func__); | 179 | __FILE__, __LINE__, __func__); |
180 | 180 | ||
181 | for (i = 0 ; i < LLD_MAX_FLASH_BANKS; i++) | 181 | for (i = 0 ; i < denali->max_banks; i++) |
182 | iowrite32(INTR_STATUS__RST_COMP | INTR_STATUS__TIME_OUT, | 182 | iowrite32(INTR_STATUS__RST_COMP | INTR_STATUS__TIME_OUT, |
183 | denali->flash_reg + INTR_STATUS(i)); | 183 | denali->flash_reg + INTR_STATUS(i)); |
184 | 184 | ||
185 | for (i = 0 ; i < LLD_MAX_FLASH_BANKS; i++) { | 185 | for (i = 0 ; i < denali->max_banks; i++) { |
186 | iowrite32(1 << i, denali->flash_reg + DEVICE_RESET); | 186 | iowrite32(1 << i, denali->flash_reg + DEVICE_RESET); |
187 | while (!(ioread32(denali->flash_reg + | 187 | while (!(ioread32(denali->flash_reg + |
188 | INTR_STATUS(i)) & | 188 | INTR_STATUS(i)) & |
@@ -194,7 +194,7 @@ static uint16_t denali_nand_reset(struct denali_nand_info *denali) | |||
194 | "NAND Reset operation timed out on bank %d\n", i); | 194 | "NAND Reset operation timed out on bank %d\n", i); |
195 | } | 195 | } |
196 | 196 | ||
197 | for (i = 0; i < LLD_MAX_FLASH_BANKS; i++) | 197 | for (i = 0; i < denali->max_banks; i++) |
198 | iowrite32(INTR_STATUS__RST_COMP | INTR_STATUS__TIME_OUT, | 198 | iowrite32(INTR_STATUS__RST_COMP | INTR_STATUS__TIME_OUT, |
199 | denali->flash_reg + INTR_STATUS(i)); | 199 | denali->flash_reg + INTR_STATUS(i)); |
200 | 200 | ||
@@ -405,11 +405,11 @@ static void get_hynix_nand_para(struct denali_nand_info *denali, | |||
405 | */ | 405 | */ |
406 | static void find_valid_banks(struct denali_nand_info *denali) | 406 | static void find_valid_banks(struct denali_nand_info *denali) |
407 | { | 407 | { |
408 | uint32_t id[LLD_MAX_FLASH_BANKS]; | 408 | uint32_t id[denali->max_banks]; |
409 | int i; | 409 | int i; |
410 | 410 | ||
411 | denali->total_used_banks = 1; | 411 | denali->total_used_banks = 1; |
412 | for (i = 0; i < LLD_MAX_FLASH_BANKS; i++) { | 412 | for (i = 0; i < denali->max_banks; i++) { |
413 | index_addr(denali, (uint32_t)(MODE_11 | (i << 24) | 0), 0x90); | 413 | index_addr(denali, (uint32_t)(MODE_11 | (i << 24) | 0), 0x90); |
414 | index_addr(denali, (uint32_t)(MODE_11 | (i << 24) | 1), 0); | 414 | index_addr(denali, (uint32_t)(MODE_11 | (i << 24) | 1), 0); |
415 | index_addr_read_data(denali, | 415 | index_addr_read_data(denali, |
@@ -445,6 +445,17 @@ static void find_valid_banks(struct denali_nand_info *denali) | |||
445 | "denali->total_used_banks: %d\n", denali->total_used_banks); | 445 | "denali->total_used_banks: %d\n", denali->total_used_banks); |
446 | } | 446 | } |
447 | 447 | ||
448 | /* | ||
449 | * Use the configuration feature register to determine the maximum number of | ||
450 | * banks that the hardware supports. | ||
451 | */ | ||
452 | static void detect_max_banks(struct denali_nand_info *denali) | ||
453 | { | ||
454 | uint32_t features = ioread32(denali->flash_reg + FEATURES); | ||
455 | |||
456 | denali->max_banks = 2 << (features & FEATURES__N_BANKS); | ||
457 | } | ||
458 | |||
448 | static void detect_partition_feature(struct denali_nand_info *denali) | 459 | static void detect_partition_feature(struct denali_nand_info *denali) |
449 | { | 460 | { |
450 | /* For MRST platform, denali->fwblks represent the | 461 | /* For MRST platform, denali->fwblks represent the |
@@ -562,7 +573,7 @@ static void denali_irq_init(struct denali_nand_info *denali) | |||
562 | int_mask = DENALI_IRQ_ALL; | 573 | int_mask = DENALI_IRQ_ALL; |
563 | 574 | ||
564 | /* Clear all status bits */ | 575 | /* Clear all status bits */ |
565 | for (i = 0; i < LLD_MAX_FLASH_BANKS; ++i) | 576 | for (i = 0; i < denali->max_banks; ++i) |
566 | iowrite32(0xFFFF, denali->flash_reg + INTR_STATUS(i)); | 577 | iowrite32(0xFFFF, denali->flash_reg + INTR_STATUS(i)); |
567 | 578 | ||
568 | denali_irq_enable(denali, int_mask); | 579 | denali_irq_enable(denali, int_mask); |
@@ -579,7 +590,7 @@ static void denali_irq_enable(struct denali_nand_info *denali, | |||
579 | { | 590 | { |
580 | int i; | 591 | int i; |
581 | 592 | ||
582 | for (i = 0; i < LLD_MAX_FLASH_BANKS; ++i) | 593 | for (i = 0; i < denali->max_banks; ++i) |
583 | iowrite32(int_mask, denali->flash_reg + INTR_EN(i)); | 594 | iowrite32(int_mask, denali->flash_reg + INTR_EN(i)); |
584 | } | 595 | } |
585 | 596 | ||
@@ -1345,6 +1356,7 @@ static void denali_hw_init(struct denali_nand_info *denali) | |||
1345 | /* Should set value for these registers when init */ | 1356 | /* Should set value for these registers when init */ |
1346 | iowrite32(0, denali->flash_reg + TWO_ROW_ADDR_CYCLES); | 1357 | iowrite32(0, denali->flash_reg + TWO_ROW_ADDR_CYCLES); |
1347 | iowrite32(1, denali->flash_reg + ECC_ENABLE); | 1358 | iowrite32(1, denali->flash_reg + ECC_ENABLE); |
1359 | detect_max_banks(denali); | ||
1348 | denali_nand_timing_set(denali); | 1360 | denali_nand_timing_set(denali); |
1349 | denali_irq_init(denali); | 1361 | denali_irq_init(denali); |
1350 | } | 1362 | } |
@@ -1522,7 +1534,7 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
1522 | /* scan for NAND devices attached to the controller | 1534 | /* scan for NAND devices attached to the controller |
1523 | * this is the first stage in a two step process to register | 1535 | * this is the first stage in a two step process to register |
1524 | * with the nand subsystem */ | 1536 | * with the nand subsystem */ |
1525 | if (nand_scan_ident(&denali->mtd, LLD_MAX_FLASH_BANKS, NULL)) { | 1537 | if (nand_scan_ident(&denali->mtd, denali->max_banks, NULL)) { |
1526 | ret = -ENXIO; | 1538 | ret = -ENXIO; |
1527 | goto failed_req_irq; | 1539 | goto failed_req_irq; |
1528 | } | 1540 | } |
diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/denali.h index 638668c4b41f..fabb9d56b39e 100644 --- a/drivers/mtd/nand/denali.h +++ b/drivers/mtd/nand/denali.h | |||
@@ -454,7 +454,6 @@ | |||
454 | #define READ_WRITE_ENABLE_HIGH_COUNT 22 | 454 | #define READ_WRITE_ENABLE_HIGH_COUNT 22 |
455 | 455 | ||
456 | #define ECC_SECTOR_SIZE 512 | 456 | #define ECC_SECTOR_SIZE 512 |
457 | #define LLD_MAX_FLASH_BANKS 4 | ||
458 | 457 | ||
459 | #define DENALI_BUF_SIZE (NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE) | 458 | #define DENALI_BUF_SIZE (NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE) |
460 | 459 | ||
@@ -494,6 +493,7 @@ struct denali_nand_info { | |||
494 | uint32_t totalblks; | 493 | uint32_t totalblks; |
495 | uint32_t blksperchip; | 494 | uint32_t blksperchip; |
496 | uint32_t bbtskipbytes; | 495 | uint32_t bbtskipbytes; |
496 | uint32_t max_banks; | ||
497 | }; | 497 | }; |
498 | 498 | ||
499 | #endif /*_LLD_NAND_*/ | 499 | #endif /*_LLD_NAND_*/ |