diff options
author | Uwe Kleine-König <u.kleine-koenig@pengutronix.de> | 2012-04-23 05:23:36 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2012-05-14 00:01:50 -0400 |
commit | 6d38af255a106fe921762c5c5de32dac92647af9 (patch) | |
tree | 6752410ea32f35960ec4c01c6d1966118b70b0d4 /drivers/mtd | |
parent | e4303b25f4452dd6a0a49c318e5e93d0c5f8b1ba (diff) |
mtd: mxc_nand: split some functions to get rid of more nfc_is_vX()
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/nand/mxc_nand.c | 109 |
1 files changed, 80 insertions, 29 deletions
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index b6e4618bb043..fbd94f00e0ab 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c | |||
@@ -151,6 +151,7 @@ struct mxc_nand_devtype_data { | |||
151 | uint16_t (*get_dev_status)(struct mxc_nand_host *); | 151 | uint16_t (*get_dev_status)(struct mxc_nand_host *); |
152 | int (*check_int)(struct mxc_nand_host *); | 152 | int (*check_int)(struct mxc_nand_host *); |
153 | void (*irq_control)(struct mxc_nand_host *, int); | 153 | void (*irq_control)(struct mxc_nand_host *, int); |
154 | u32 (*get_ecc_status)(struct mxc_nand_host *); | ||
154 | }; | 155 | }; |
155 | 156 | ||
156 | struct mxc_nand_host { | 157 | struct mxc_nand_host { |
@@ -325,6 +326,21 @@ static void irq_control(struct mxc_nand_host *host, int activate) | |||
325 | } | 326 | } |
326 | } | 327 | } |
327 | 328 | ||
329 | static u32 get_ecc_status_v1(struct mxc_nand_host *host) | ||
330 | { | ||
331 | return readw(NFC_V1_V2_ECC_STATUS_RESULT); | ||
332 | } | ||
333 | |||
334 | static u32 get_ecc_status_v2(struct mxc_nand_host *host) | ||
335 | { | ||
336 | return readl(NFC_V1_V2_ECC_STATUS_RESULT); | ||
337 | } | ||
338 | |||
339 | static u32 get_ecc_status_v3(struct mxc_nand_host *host) | ||
340 | { | ||
341 | return readl(NFC_V3_ECC_STATUS_RESULT); | ||
342 | } | ||
343 | |||
328 | static irqreturn_t mxc_nfc_irq(int irq, void *dev_id) | 344 | static irqreturn_t mxc_nfc_irq(int irq, void *dev_id) |
329 | { | 345 | { |
330 | struct mxc_nand_host *host = dev_id; | 346 | struct mxc_nand_host *host = dev_id; |
@@ -444,13 +460,27 @@ static void send_page_v3(struct mtd_info *mtd, unsigned int ops) | |||
444 | wait_op_done(host, false); | 460 | wait_op_done(host, false); |
445 | } | 461 | } |
446 | 462 | ||
447 | static void send_page_v1_v2(struct mtd_info *mtd, unsigned int ops) | 463 | static void send_page_v2(struct mtd_info *mtd, unsigned int ops) |
464 | { | ||
465 | struct nand_chip *nand_chip = mtd->priv; | ||
466 | struct mxc_nand_host *host = nand_chip->priv; | ||
467 | |||
468 | /* NANDFC buffer 0 is used for page read/write */ | ||
469 | writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR); | ||
470 | |||
471 | writew(ops, NFC_V1_V2_CONFIG2); | ||
472 | |||
473 | /* Wait for operation to complete */ | ||
474 | wait_op_done(host, true); | ||
475 | } | ||
476 | |||
477 | static void send_page_v1(struct mtd_info *mtd, unsigned int ops) | ||
448 | { | 478 | { |
449 | struct nand_chip *nand_chip = mtd->priv; | 479 | struct nand_chip *nand_chip = mtd->priv; |
450 | struct mxc_nand_host *host = nand_chip->priv; | 480 | struct mxc_nand_host *host = nand_chip->priv; |
451 | int bufs, i; | 481 | int bufs, i; |
452 | 482 | ||
453 | if (nfc_is_v1() && mtd->writesize > 512) | 483 | if (mtd->writesize > 512) |
454 | bufs = 4; | 484 | bufs = 4; |
455 | else | 485 | else |
456 | bufs = 1; | 486 | bufs = 1; |
@@ -566,7 +596,7 @@ static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat, | |||
566 | * additional correction. 2-Bit errors cannot be corrected by | 596 | * additional correction. 2-Bit errors cannot be corrected by |
567 | * HW ECC, so we need to return failure | 597 | * HW ECC, so we need to return failure |
568 | */ | 598 | */ |
569 | uint16_t ecc_status = readw(NFC_V1_V2_ECC_STATUS_RESULT); | 599 | uint16_t ecc_status = get_ecc_status_v1(host); |
570 | 600 | ||
571 | if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) { | 601 | if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) { |
572 | pr_debug("MXC_NAND: HWECC uncorrectable 2-bit ECC error\n"); | 602 | pr_debug("MXC_NAND: HWECC uncorrectable 2-bit ECC error\n"); |
@@ -591,10 +621,7 @@ static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat, | |||
591 | 621 | ||
592 | no_subpages = mtd->writesize >> 9; | 622 | no_subpages = mtd->writesize >> 9; |
593 | 623 | ||
594 | if (nfc_is_v21()) | 624 | ecc_stat = host->devtype_data->get_ecc_status(host); |
595 | ecc_stat = readl(NFC_V1_V2_ECC_STATUS_RESULT); | ||
596 | else | ||
597 | ecc_stat = readl(NFC_V3_ECC_STATUS_RESULT); | ||
598 | 625 | ||
599 | do { | 626 | do { |
600 | err = ecc_stat & ecc_bit_mask; | 627 | err = ecc_stat & ecc_bit_mask; |
@@ -821,7 +848,7 @@ static int get_eccsize(struct mtd_info *mtd) | |||
821 | return 8; | 848 | return 8; |
822 | } | 849 | } |
823 | 850 | ||
824 | static void preset_v1_v2(struct mtd_info *mtd) | 851 | static void preset_v1(struct mtd_info *mtd) |
825 | { | 852 | { |
826 | struct nand_chip *nand_chip = mtd->priv; | 853 | struct nand_chip *nand_chip = mtd->priv; |
827 | struct mxc_nand_host *host = nand_chip->priv; | 854 | struct mxc_nand_host *host = nand_chip->priv; |
@@ -830,13 +857,40 @@ static void preset_v1_v2(struct mtd_info *mtd) | |||
830 | if (nand_chip->ecc.mode == NAND_ECC_HW) | 857 | if (nand_chip->ecc.mode == NAND_ECC_HW) |
831 | config1 |= NFC_V1_V2_CONFIG1_ECC_EN; | 858 | config1 |= NFC_V1_V2_CONFIG1_ECC_EN; |
832 | 859 | ||
833 | if (nfc_is_v21()) | 860 | if (!host->irqpending_quirk) |
834 | config1 |= NFC_V2_CONFIG1_FP_INT; | 861 | config1 |= NFC_V1_V2_CONFIG1_INT_MSK; |
862 | |||
863 | host->eccsize = 1; | ||
864 | |||
865 | writew(config1, NFC_V1_V2_CONFIG1); | ||
866 | /* preset operation */ | ||
867 | |||
868 | /* Unlock the internal RAM Buffer */ | ||
869 | writew(0x2, NFC_V1_V2_CONFIG); | ||
870 | |||
871 | /* Blocks to be unlocked */ | ||
872 | writew(0x0, NFC_V1_UNLOCKSTART_BLKADDR); | ||
873 | writew(0xffff, NFC_V1_UNLOCKEND_BLKADDR); | ||
874 | |||
875 | /* Unlock Block Command for given address range */ | ||
876 | writew(0x4, NFC_V1_V2_WRPROT); | ||
877 | } | ||
878 | |||
879 | static void preset_v2(struct mtd_info *mtd) | ||
880 | { | ||
881 | struct nand_chip *nand_chip = mtd->priv; | ||
882 | struct mxc_nand_host *host = nand_chip->priv; | ||
883 | uint16_t config1 = 0; | ||
884 | |||
885 | if (nand_chip->ecc.mode == NAND_ECC_HW) | ||
886 | config1 |= NFC_V1_V2_CONFIG1_ECC_EN; | ||
887 | |||
888 | config1 |= NFC_V2_CONFIG1_FP_INT; | ||
835 | 889 | ||
836 | if (!host->irqpending_quirk) | 890 | if (!host->irqpending_quirk) |
837 | config1 |= NFC_V1_V2_CONFIG1_INT_MSK; | 891 | config1 |= NFC_V1_V2_CONFIG1_INT_MSK; |
838 | 892 | ||
839 | if (nfc_is_v21() && mtd->writesize) { | 893 | if (mtd->writesize) { |
840 | uint16_t pages_per_block = mtd->erasesize / mtd->writesize; | 894 | uint16_t pages_per_block = mtd->erasesize / mtd->writesize; |
841 | 895 | ||
842 | host->eccsize = get_eccsize(mtd); | 896 | host->eccsize = get_eccsize(mtd); |
@@ -855,20 +909,14 @@ static void preset_v1_v2(struct mtd_info *mtd) | |||
855 | writew(0x2, NFC_V1_V2_CONFIG); | 909 | writew(0x2, NFC_V1_V2_CONFIG); |
856 | 910 | ||
857 | /* Blocks to be unlocked */ | 911 | /* Blocks to be unlocked */ |
858 | if (nfc_is_v21()) { | 912 | writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR0); |
859 | writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR0); | 913 | writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR1); |
860 | writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR1); | 914 | writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR2); |
861 | writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR2); | 915 | writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR3); |
862 | writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR3); | 916 | writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR0); |
863 | writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR0); | 917 | writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR1); |
864 | writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR1); | 918 | writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR2); |
865 | writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR2); | 919 | writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR3); |
866 | writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR3); | ||
867 | } else if (nfc_is_v1()) { | ||
868 | writew(0x0, NFC_V1_UNLOCKSTART_BLKADDR); | ||
869 | writew(0xffff, NFC_V1_UNLOCKEND_BLKADDR); | ||
870 | } else | ||
871 | BUG(); | ||
872 | 920 | ||
873 | /* Unlock Block Command for given address range */ | 921 | /* Unlock Block Command for given address range */ |
874 | writew(0x4, NFC_V1_V2_WRPROT); | 922 | writew(0x4, NFC_V1_V2_WRPROT); |
@@ -1056,26 +1104,28 @@ static struct nand_bbt_descr bbt_mirror_descr = { | |||
1056 | 1104 | ||
1057 | /* v1: i.MX21, i.MX27, i.MX31 */ | 1105 | /* v1: i.MX21, i.MX27, i.MX31 */ |
1058 | static const struct mxc_nand_devtype_data imx21_nand_devtype_data = { | 1106 | static const struct mxc_nand_devtype_data imx21_nand_devtype_data = { |
1059 | .preset = preset_v1_v2, | 1107 | .preset = preset_v1, |
1060 | .send_cmd = send_cmd_v1_v2, | 1108 | .send_cmd = send_cmd_v1_v2, |
1061 | .send_addr = send_addr_v1_v2, | 1109 | .send_addr = send_addr_v1_v2, |
1062 | .send_page = send_page_v1_v2, | 1110 | .send_page = send_page_v1, |
1063 | .send_read_id = send_read_id_v1_v2, | 1111 | .send_read_id = send_read_id_v1_v2, |
1064 | .get_dev_status = get_dev_status_v1_v2, | 1112 | .get_dev_status = get_dev_status_v1_v2, |
1065 | .check_int = check_int_v1_v2, | 1113 | .check_int = check_int_v1_v2, |
1066 | .irq_control = irq_control_v1_v2, | 1114 | .irq_control = irq_control_v1_v2, |
1115 | .get_ecc_status = get_ecc_status_v1, | ||
1067 | }; | 1116 | }; |
1068 | 1117 | ||
1069 | /* v21: i.MX25, i.MX35 */ | 1118 | /* v21: i.MX25, i.MX35 */ |
1070 | static const struct mxc_nand_devtype_data imx25_nand_devtype_data = { | 1119 | static const struct mxc_nand_devtype_data imx25_nand_devtype_data = { |
1071 | .preset = preset_v1_v2, | 1120 | .preset = preset_v2, |
1072 | .send_cmd = send_cmd_v1_v2, | 1121 | .send_cmd = send_cmd_v1_v2, |
1073 | .send_addr = send_addr_v1_v2, | 1122 | .send_addr = send_addr_v1_v2, |
1074 | .send_page = send_page_v1_v2, | 1123 | .send_page = send_page_v2, |
1075 | .send_read_id = send_read_id_v1_v2, | 1124 | .send_read_id = send_read_id_v1_v2, |
1076 | .get_dev_status = get_dev_status_v1_v2, | 1125 | .get_dev_status = get_dev_status_v1_v2, |
1077 | .check_int = check_int_v1_v2, | 1126 | .check_int = check_int_v1_v2, |
1078 | .irq_control = irq_control_v1_v2, | 1127 | .irq_control = irq_control_v1_v2, |
1128 | .get_ecc_status = get_ecc_status_v2, | ||
1079 | }; | 1129 | }; |
1080 | 1130 | ||
1081 | /* v3: i.MX51, i.MX53 */ | 1131 | /* v3: i.MX51, i.MX53 */ |
@@ -1088,6 +1138,7 @@ static const struct mxc_nand_devtype_data imx51_nand_devtype_data = { | |||
1088 | .get_dev_status = get_dev_status_v3, | 1138 | .get_dev_status = get_dev_status_v3, |
1089 | .check_int = check_int_v3, | 1139 | .check_int = check_int_v3, |
1090 | .irq_control = irq_control_v3, | 1140 | .irq_control = irq_control_v3, |
1141 | .get_ecc_status = get_ecc_status_v3, | ||
1091 | }; | 1142 | }; |
1092 | 1143 | ||
1093 | static int __init mxcnd_probe(struct platform_device *pdev) | 1144 | static int __init mxcnd_probe(struct platform_device *pdev) |