aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2012-04-23 05:23:36 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2012-05-14 00:01:50 -0400
commit6d38af255a106fe921762c5c5de32dac92647af9 (patch)
tree6752410ea32f35960ec4c01c6d1966118b70b0d4 /drivers/mtd
parente4303b25f4452dd6a0a49c318e5e93d0c5f8b1ba (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.c109
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
156struct mxc_nand_host { 157struct mxc_nand_host {
@@ -325,6 +326,21 @@ static void irq_control(struct mxc_nand_host *host, int activate)
325 } 326 }
326} 327}
327 328
329static u32 get_ecc_status_v1(struct mxc_nand_host *host)
330{
331 return readw(NFC_V1_V2_ECC_STATUS_RESULT);
332}
333
334static u32 get_ecc_status_v2(struct mxc_nand_host *host)
335{
336 return readl(NFC_V1_V2_ECC_STATUS_RESULT);
337}
338
339static u32 get_ecc_status_v3(struct mxc_nand_host *host)
340{
341 return readl(NFC_V3_ECC_STATUS_RESULT);
342}
343
328static irqreturn_t mxc_nfc_irq(int irq, void *dev_id) 344static 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
447static void send_page_v1_v2(struct mtd_info *mtd, unsigned int ops) 463static 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
477static 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
824static void preset_v1_v2(struct mtd_info *mtd) 851static 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
879static 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 */
1058static const struct mxc_nand_devtype_data imx21_nand_devtype_data = { 1106static 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 */
1070static const struct mxc_nand_devtype_data imx25_nand_devtype_data = { 1119static 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
1093static int __init mxcnd_probe(struct platform_device *pdev) 1144static int __init mxcnd_probe(struct platform_device *pdev)