diff options
-rw-r--r-- | arch/arm/plat-pxa/include/plat/pxa3xx_nand.h | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/pxa3xx_nand.c | 103 |
2 files changed, 36 insertions, 69 deletions
diff --git a/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h b/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h index 01a8448e471..442301fe48b 100644 --- a/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h +++ b/arch/arm/plat-pxa/include/plat/pxa3xx_nand.h | |||
@@ -30,6 +30,7 @@ struct pxa3xx_nand_cmdset { | |||
30 | }; | 30 | }; |
31 | 31 | ||
32 | struct pxa3xx_nand_flash { | 32 | struct pxa3xx_nand_flash { |
33 | char *name; | ||
33 | uint32_t chip_id; | 34 | uint32_t chip_id; |
34 | unsigned int page_per_block; /* Pages per block (PG_PER_BLK) */ | 35 | unsigned int page_per_block; /* Pages per block (PG_PER_BLK) */ |
35 | unsigned int page_size; /* Page size in bytes (PAGE_SZ) */ | 36 | unsigned int page_size; /* Page size in bytes (PAGE_SZ) */ |
@@ -37,7 +38,6 @@ struct pxa3xx_nand_flash { | |||
37 | unsigned int dfc_width; /* Width of flash controller(DWIDTH_C) */ | 38 | unsigned int dfc_width; /* Width of flash controller(DWIDTH_C) */ |
38 | unsigned int num_blocks; /* Number of physical blocks in Flash */ | 39 | unsigned int num_blocks; /* Number of physical blocks in Flash */ |
39 | 40 | ||
40 | struct pxa3xx_nand_cmdset *cmdset; /* NAND command set */ | ||
41 | struct pxa3xx_nand_timing *timing; /* NAND Flash timing */ | 41 | struct pxa3xx_nand_timing *timing; /* NAND Flash timing */ |
42 | }; | 42 | }; |
43 | 43 | ||
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index bb50cf2b11c..ab7f4c33ced 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c | |||
@@ -211,15 +211,15 @@ static struct pxa3xx_nand_timing timing[] = { | |||
211 | }; | 211 | }; |
212 | 212 | ||
213 | static struct pxa3xx_nand_flash builtin_flash_types[] = { | 213 | static struct pxa3xx_nand_flash builtin_flash_types[] = { |
214 | { 0, 0, 2048, 8, 8, 0, &default_cmdset, &timing[0] }, | 214 | { "DEFAULT FLASH", 0, 0, 2048, 8, 8, 0, &timing[0] }, |
215 | { 0x46ec, 32, 512, 16, 16, 4096, &default_cmdset, &timing[1] }, | 215 | { "64MiB 16-bit", 0x46ec, 32, 512, 16, 16, 4096, &timing[1] }, |
216 | { 0xdaec, 64, 2048, 8, 8, 2048, &default_cmdset, &timing[1] }, | 216 | { "256MiB 8-bit", 0xdaec, 64, 2048, 8, 8, 2048, &timing[1] }, |
217 | { 0xd7ec, 128, 4096, 8, 8, 8192, &default_cmdset, &timing[1] }, | 217 | { "4GiB 8-bit", 0xd7ec, 128, 4096, 8, 8, 8192, &timing[1] }, |
218 | { 0xa12c, 64, 2048, 8, 8, 1024, &default_cmdset, &timing[2] }, | 218 | { "128MiB 8-bit", 0xa12c, 64, 2048, 8, 8, 1024, &timing[2] }, |
219 | { 0xb12c, 64, 2048, 16, 16, 1024, &default_cmdset, &timing[2] }, | 219 | { "128MiB 16-bit", 0xb12c, 64, 2048, 16, 16, 1024, &timing[2] }, |
220 | { 0xdc2c, 64, 2048, 8, 8, 4096, &default_cmdset, &timing[2] }, | 220 | { "512MiB 8-bit", 0xdc2c, 64, 2048, 8, 8, 4096, &timing[2] }, |
221 | { 0xcc2c, 64, 2048, 16, 16, 4096, &default_cmdset, &timing[2] }, | 221 | { "512MiB 16-bit", 0xcc2c, 64, 2048, 16, 16, 4096, &timing[2] }, |
222 | { 0xba20, 64, 2048, 16, 16, 2048, &default_cmdset, &timing[3] }, | 222 | { "256MiB 16-bit", 0xba20, 64, 2048, 16, 16, 2048, &timing[3] }, |
223 | }; | 223 | }; |
224 | 224 | ||
225 | /* Define a default flash type setting serve as flash detecting only */ | 225 | /* Define a default flash type setting serve as flash detecting only */ |
@@ -779,9 +779,8 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info, | |||
779 | return -EINVAL; | 779 | return -EINVAL; |
780 | 780 | ||
781 | /* calculate flash information */ | 781 | /* calculate flash information */ |
782 | info->cmdset = f->cmdset; | 782 | info->cmdset = &default_cmdset; |
783 | info->page_size = f->page_size; | 783 | info->page_size = f->page_size; |
784 | info->oob_buff = info->data_buff + f->page_size; | ||
785 | info->read_id_bytes = (f->page_size == 2048) ? 4 : 2; | 784 | info->read_id_bytes = (f->page_size == 2048) ? 4 : 2; |
786 | 785 | ||
787 | /* calculate addressing information */ | 786 | /* calculate addressing information */ |
@@ -811,45 +810,12 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info, | |||
811 | static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info) | 810 | static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info) |
812 | { | 811 | { |
813 | uint32_t ndcr = nand_readl(info, NDCR); | 812 | uint32_t ndcr = nand_readl(info, NDCR); |
814 | struct nand_flash_dev *type = NULL; | ||
815 | uint32_t id = -1, page_per_block, num_blocks; | ||
816 | int i; | ||
817 | |||
818 | page_per_block = ndcr & NDCR_PG_PER_BLK ? 64 : 32; | ||
819 | info->page_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512; | 813 | info->page_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512; |
820 | /* set info fields needed to read id */ | 814 | /* set info fields needed to read id */ |
821 | info->read_id_bytes = (info->page_size == 2048) ? 4 : 2; | 815 | info->read_id_bytes = (info->page_size == 2048) ? 4 : 2; |
822 | info->reg_ndcr = ndcr; | 816 | info->reg_ndcr = ndcr; |
823 | info->cmdset = &default_cmdset; | 817 | info->cmdset = &default_cmdset; |
824 | 818 | ||
825 | pxa3xx_nand_cmdfunc(info->mtd, NAND_CMD_READID, 0, 0); | ||
826 | id = *((uint16_t *)(info->data_buff)); | ||
827 | if (id == 0) | ||
828 | return -ENODEV; | ||
829 | |||
830 | /* Lookup the flash id */ | ||
831 | for (i = 0; nand_flash_ids[i].name != NULL; i++) { | ||
832 | if (id == nand_flash_ids[i].id) { | ||
833 | type = &nand_flash_ids[i]; | ||
834 | break; | ||
835 | } | ||
836 | } | ||
837 | |||
838 | if (!type) | ||
839 | return -ENODEV; | ||
840 | |||
841 | /* fill the missing flash information */ | ||
842 | i = __ffs(page_per_block * info->page_size); | ||
843 | num_blocks = type->chipsize << (20 - i); | ||
844 | |||
845 | /* calculate addressing information */ | ||
846 | info->col_addr_cycles = (info->page_size == 2048) ? 2 : 1; | ||
847 | |||
848 | if (num_blocks * page_per_block > 65536) | ||
849 | info->row_addr_cycles = 3; | ||
850 | else | ||
851 | info->row_addr_cycles = 2; | ||
852 | |||
853 | info->ndtr0cs0 = nand_readl(info, NDTR0CS0); | 819 | info->ndtr0cs0 = nand_readl(info, NDTR0CS0); |
854 | info->ndtr1cs0 = nand_readl(info, NDTR1CS0); | 820 | info->ndtr1cs0 = nand_readl(info, NDTR1CS0); |
855 | 821 | ||
@@ -916,13 +882,15 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) | |||
916 | struct pxa3xx_nand_info *info = mtd->priv; | 882 | struct pxa3xx_nand_info *info = mtd->priv; |
917 | struct platform_device *pdev = info->pdev; | 883 | struct platform_device *pdev = info->pdev; |
918 | struct pxa3xx_nand_platform_data *pdata = pdev->dev.platform_data; | 884 | struct pxa3xx_nand_platform_data *pdata = pdev->dev.platform_data; |
885 | struct nand_flash_dev pxa3xx_flash_ids[2] = { {NULL,}, {NULL,} }; | ||
919 | const struct pxa3xx_nand_flash *f = NULL; | 886 | const struct pxa3xx_nand_flash *f = NULL; |
920 | struct nand_chip *chip = mtd->priv; | 887 | struct nand_chip *chip = mtd->priv; |
921 | uint32_t id = -1; | 888 | uint32_t id = -1; |
889 | uint64_t chipsize; | ||
922 | int i, ret, num; | 890 | int i, ret, num; |
923 | 891 | ||
924 | if (pdata->keep_config && !pxa3xx_nand_detect_config(info)) | 892 | if (pdata->keep_config && !pxa3xx_nand_detect_config(info)) |
925 | return 0; | 893 | goto KEEP_CONFIG; |
926 | 894 | ||
927 | ret = pxa3xx_nand_sensing(info); | 895 | ret = pxa3xx_nand_sensing(info); |
928 | if (!ret) { | 896 | if (!ret) { |
@@ -953,22 +921,11 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) | |||
953 | f = &builtin_flash_types[i - pdata->num_flash + 1]; | 921 | f = &builtin_flash_types[i - pdata->num_flash + 1]; |
954 | 922 | ||
955 | /* find the chip in default list */ | 923 | /* find the chip in default list */ |
956 | if (f->chip_id == id) { | 924 | if (f->chip_id == id) |
957 | pxa3xx_nand_config_flash(info, f); | ||
958 | mtd->writesize = f->page_size; | ||
959 | mtd->writesize_shift = ffs(mtd->writesize) - 1; | ||
960 | mtd->writesize_mask = (1 << mtd->writesize_shift) - 1; | ||
961 | mtd->oobsize = mtd->writesize / 32; | ||
962 | mtd->erasesize = f->page_size * f->page_per_block; | ||
963 | mtd->erasesize_shift = ffs(mtd->erasesize) - 1; | ||
964 | mtd->erasesize_mask = (1 << mtd->erasesize_shift) - 1; | ||
965 | |||
966 | mtd->name = mtd_names[0]; | ||
967 | break; | 925 | break; |
968 | } | ||
969 | } | 926 | } |
970 | 927 | ||
971 | if (i >= (ARRAY_SIZE(builtin_flash_types) + pdata->num_flash)) { | 928 | if (i >= (ARRAY_SIZE(builtin_flash_types) + pdata->num_flash - 1)) { |
972 | kfree(mtd); | 929 | kfree(mtd); |
973 | info->mtd = NULL; | 930 | info->mtd = NULL; |
974 | printk(KERN_ERR "ERROR!! flash not defined!!!\n"); | 931 | printk(KERN_ERR "ERROR!! flash not defined!!!\n"); |
@@ -976,18 +933,28 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) | |||
976 | return -EINVAL; | 933 | return -EINVAL; |
977 | } | 934 | } |
978 | 935 | ||
936 | pxa3xx_nand_config_flash(info, f); | ||
937 | pxa3xx_flash_ids[0].name = f->name; | ||
938 | pxa3xx_flash_ids[0].id = (f->chip_id >> 8) & 0xffff; | ||
939 | pxa3xx_flash_ids[0].pagesize = f->page_size; | ||
940 | chipsize = (uint64_t)f->num_blocks * f->page_per_block * f->page_size; | ||
941 | pxa3xx_flash_ids[0].chipsize = chipsize >> 20; | ||
942 | pxa3xx_flash_ids[0].erasesize = f->page_size * f->page_per_block; | ||
943 | if (f->flash_width == 16) | ||
944 | pxa3xx_flash_ids[0].options = NAND_BUSWIDTH_16; | ||
945 | KEEP_CONFIG: | ||
946 | if (nand_scan_ident(mtd, 1, pxa3xx_flash_ids)) | ||
947 | return -ENODEV; | ||
948 | /* calculate addressing information */ | ||
949 | info->col_addr_cycles = (mtd->writesize >= 2048) ? 2 : 1; | ||
950 | info->oob_buff = info->data_buff + mtd->writesize; | ||
951 | if ((mtd->size >> chip->page_shift) > 65536) | ||
952 | info->row_addr_cycles = 3; | ||
953 | else | ||
954 | info->row_addr_cycles = 2; | ||
955 | mtd->name = mtd_names[0]; | ||
979 | chip->ecc.mode = NAND_ECC_HW; | 956 | chip->ecc.mode = NAND_ECC_HW; |
980 | chip->ecc.size = f->page_size; | 957 | chip->ecc.size = f->page_size; |
981 | chip->chipsize = (uint64_t)f->num_blocks * f->page_per_block | ||
982 | * f->page_size; | ||
983 | mtd->size = chip->chipsize; | ||
984 | |||
985 | /* Calculate the address shift from the page size */ | ||
986 | chip->page_shift = ffs(mtd->writesize) - 1; | ||
987 | chip->pagemask = mtd_div_by_ws(chip->chipsize, mtd) - 1; | ||
988 | chip->numchips = 1; | ||
989 | chip->phys_erase_shift = ffs(mtd->erasesize) - 1; | ||
990 | chip->bbt_erase_shift = chip->phys_erase_shift; | ||
991 | 958 | ||
992 | chip->options = (f->flash_width == 16) ? NAND_BUSWIDTH_16 : 0; | 959 | chip->options = (f->flash_width == 16) ? NAND_BUSWIDTH_16 : 0; |
993 | chip->options |= NAND_NO_AUTOINCR; | 960 | chip->options |= NAND_NO_AUTOINCR; |