mtd: mxc_nand: split some functions to get rid of more nfc_is_vX()
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Mon, 23 Apr 2012 09:23:36 +0000 (11:23 +0200)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Mon, 14 May 2012 04:01:50 +0000 (23:01 -0500)
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>
drivers/mtd/nand/mxc_nand.c

index b6e4618bb0432e6c09cb2a9a14d40aa3478b7320..fbd94f00e0ab382d85adc0ee86725627ad73154b 100644 (file)
@@ -151,6 +151,7 @@ struct mxc_nand_devtype_data {
        uint16_t (*get_dev_status)(struct mxc_nand_host *);
        int (*check_int)(struct mxc_nand_host *);
        void (*irq_control)(struct mxc_nand_host *, int);
+       u32 (*get_ecc_status)(struct mxc_nand_host *);
 };
 
 struct mxc_nand_host {
@@ -325,6 +326,21 @@ static void irq_control(struct mxc_nand_host *host, int activate)
        }
 }
 
+static u32 get_ecc_status_v1(struct mxc_nand_host *host)
+{
+       return readw(NFC_V1_V2_ECC_STATUS_RESULT);
+}
+
+static u32 get_ecc_status_v2(struct mxc_nand_host *host)
+{
+       return readl(NFC_V1_V2_ECC_STATUS_RESULT);
+}
+
+static u32 get_ecc_status_v3(struct mxc_nand_host *host)
+{
+       return readl(NFC_V3_ECC_STATUS_RESULT);
+}
+
 static irqreturn_t mxc_nfc_irq(int irq, void *dev_id)
 {
        struct mxc_nand_host *host = dev_id;
@@ -444,13 +460,27 @@ static void send_page_v3(struct mtd_info *mtd, unsigned int ops)
        wait_op_done(host, false);
 }
 
-static void send_page_v1_v2(struct mtd_info *mtd, unsigned int ops)
+static void send_page_v2(struct mtd_info *mtd, unsigned int ops)
+{
+       struct nand_chip *nand_chip = mtd->priv;
+       struct mxc_nand_host *host = nand_chip->priv;
+
+       /* NANDFC buffer 0 is used for page read/write */
+       writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR);
+
+       writew(ops, NFC_V1_V2_CONFIG2);
+
+       /* Wait for operation to complete */
+       wait_op_done(host, true);
+}
+
+static void send_page_v1(struct mtd_info *mtd, unsigned int ops)
 {
        struct nand_chip *nand_chip = mtd->priv;
        struct mxc_nand_host *host = nand_chip->priv;
        int bufs, i;
 
-       if (nfc_is_v1() && mtd->writesize > 512)
+       if (mtd->writesize > 512)
                bufs = 4;
        else
                bufs = 1;
@@ -566,7 +596,7 @@ static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat,
         * additional correction.  2-Bit errors cannot be corrected by
         * HW ECC, so we need to return failure
         */
-       uint16_t ecc_status = readw(NFC_V1_V2_ECC_STATUS_RESULT);
+       uint16_t ecc_status = get_ecc_status_v1(host);
 
        if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) {
                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,
 
        no_subpages = mtd->writesize >> 9;
 
-       if (nfc_is_v21())
-               ecc_stat = readl(NFC_V1_V2_ECC_STATUS_RESULT);
-       else
-               ecc_stat = readl(NFC_V3_ECC_STATUS_RESULT);
+       ecc_stat = host->devtype_data->get_ecc_status(host);
 
        do {
                err = ecc_stat & ecc_bit_mask;
@@ -821,7 +848,7 @@ static int get_eccsize(struct mtd_info *mtd)
                return 8;
 }
 
-static void preset_v1_v2(struct mtd_info *mtd)
+static void preset_v1(struct mtd_info *mtd)
 {
        struct nand_chip *nand_chip = mtd->priv;
        struct mxc_nand_host *host = nand_chip->priv;
@@ -830,13 +857,40 @@ static void preset_v1_v2(struct mtd_info *mtd)
        if (nand_chip->ecc.mode == NAND_ECC_HW)
                config1 |= NFC_V1_V2_CONFIG1_ECC_EN;
 
-       if (nfc_is_v21())
-               config1 |= NFC_V2_CONFIG1_FP_INT;
+       if (!host->irqpending_quirk)
+               config1 |= NFC_V1_V2_CONFIG1_INT_MSK;
+
+       host->eccsize = 1;
+
+       writew(config1, NFC_V1_V2_CONFIG1);
+       /* preset operation */
+
+       /* Unlock the internal RAM Buffer */
+       writew(0x2, NFC_V1_V2_CONFIG);
+
+       /* Blocks to be unlocked */
+       writew(0x0, NFC_V1_UNLOCKSTART_BLKADDR);
+       writew(0xffff, NFC_V1_UNLOCKEND_BLKADDR);
+
+       /* Unlock Block Command for given address range */
+       writew(0x4, NFC_V1_V2_WRPROT);
+}
+
+static void preset_v2(struct mtd_info *mtd)
+{
+       struct nand_chip *nand_chip = mtd->priv;
+       struct mxc_nand_host *host = nand_chip->priv;
+       uint16_t config1 = 0;
+
+       if (nand_chip->ecc.mode == NAND_ECC_HW)
+               config1 |= NFC_V1_V2_CONFIG1_ECC_EN;
+
+       config1 |= NFC_V2_CONFIG1_FP_INT;
 
        if (!host->irqpending_quirk)
                config1 |= NFC_V1_V2_CONFIG1_INT_MSK;
 
-       if (nfc_is_v21() && mtd->writesize) {
+       if (mtd->writesize) {
                uint16_t pages_per_block = mtd->erasesize / mtd->writesize;
 
                host->eccsize = get_eccsize(mtd);
@@ -855,20 +909,14 @@ static void preset_v1_v2(struct mtd_info *mtd)
        writew(0x2, NFC_V1_V2_CONFIG);
 
        /* Blocks to be unlocked */
-       if (nfc_is_v21()) {
-               writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR0);
-               writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR1);
-               writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR2);
-               writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR3);
-               writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR0);
-               writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR1);
-               writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR2);
-               writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR3);
-       } else if (nfc_is_v1()) {
-               writew(0x0, NFC_V1_UNLOCKSTART_BLKADDR);
-               writew(0xffff, NFC_V1_UNLOCKEND_BLKADDR);
-       } else
-               BUG();
+       writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR0);
+       writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR1);
+       writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR2);
+       writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR3);
+       writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR0);
+       writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR1);
+       writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR2);
+       writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR3);
 
        /* Unlock Block Command for given address range */
        writew(0x4, NFC_V1_V2_WRPROT);
@@ -1056,26 +1104,28 @@ static struct nand_bbt_descr bbt_mirror_descr = {
 
 /* v1: i.MX21, i.MX27, i.MX31 */
 static const struct mxc_nand_devtype_data imx21_nand_devtype_data = {
-       .preset = preset_v1_v2,
+       .preset = preset_v1,
        .send_cmd = send_cmd_v1_v2,
        .send_addr = send_addr_v1_v2,
-       .send_page = send_page_v1_v2,
+       .send_page = send_page_v1,
        .send_read_id = send_read_id_v1_v2,
        .get_dev_status = get_dev_status_v1_v2,
        .check_int = check_int_v1_v2,
        .irq_control = irq_control_v1_v2,
+       .get_ecc_status = get_ecc_status_v1,
 };
 
 /* v21: i.MX25, i.MX35 */
 static const struct mxc_nand_devtype_data imx25_nand_devtype_data = {
-       .preset = preset_v1_v2,
+       .preset = preset_v2,
        .send_cmd = send_cmd_v1_v2,
        .send_addr = send_addr_v1_v2,
-       .send_page = send_page_v1_v2,
+       .send_page = send_page_v2,
        .send_read_id = send_read_id_v1_v2,
        .get_dev_status = get_dev_status_v1_v2,
        .check_int = check_int_v1_v2,
        .irq_control = irq_control_v1_v2,
+       .get_ecc_status = get_ecc_status_v2,
 };
 
 /* v3: i.MX51, i.MX53 */
@@ -1088,6 +1138,7 @@ static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
        .get_dev_status = get_dev_status_v3,
        .check_int = check_int_v3,
        .irq_control = irq_control_v3,
+       .get_ecc_status = get_ecc_status_v3,
 };
 
 static int __init mxcnd_probe(struct platform_device *pdev)