diff options
author | Huang Shijie <b32955@freescale.com> | 2011-04-26 17:10:59 +0800 |
---|---|---|
committer | Jason Liu <r64343@freescale.com> | 2012-01-09 20:08:30 +0800 |
commit | 4af6959f2b8f317c24b26dea817751aa93231da9 (patch) | |
tree | 17619f94c03357d603ce70bfba05e2bf97dd881d /drivers/mtd | |
parent | bb3afd13acef49295cd7394151c8a7a73b58fc8d (diff) |
ENGR00141558-9 MTD : add gpmi support for MX50
add the gpmi support for mx50.
Signed-off-by: Huang Shijie <b32955@freescale.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/nand/Kconfig | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/gpmi-nfc/Makefile | 4 | ||||
-rw-r--r-- | drivers/mtd/nand/gpmi-nfc/bch-regs-mx50.h | 567 | ||||
-rw-r--r-- | drivers/mtd/nand/gpmi-nfc/gpmi-nfc.c | 10 | ||||
-rw-r--r-- | drivers/mtd/nand/gpmi-nfc/gpmi-nfc.h | 3 | ||||
-rw-r--r-- | drivers/mtd/nand/gpmi-nfc/gpmi-regs-mx50.h | 511 | ||||
-rw-r--r-- | drivers/mtd/nand/gpmi-nfc/hal-mx50.c | 875 |
7 files changed, 1969 insertions, 3 deletions
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index d0076f93dd22..88dec53eb65c 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -425,7 +425,7 @@ config MTD_NAND_NANDSIM config MTD_NAND_GPMI_NFC bool "GPMI NAND Flash Controller driver" - depends on MTD_NAND && (SOC_IMX23 || SOC_IMX28) + depends on MTD_NAND && (SOC_IMX23 || SOC_IMX28 || SOC_IMX50) select MTD_PARTITIONS select MTD_CMDLINE_PARTS help diff --git a/drivers/mtd/nand/gpmi-nfc/Makefile b/drivers/mtd/nand/gpmi-nfc/Makefile index 918fb52a18e4..2b32cf622a3c 100644 --- a/drivers/mtd/nand/gpmi-nfc/Makefile +++ b/drivers/mtd/nand/gpmi-nfc/Makefile @@ -1,3 +1,5 @@ obj-$(CONFIG_MTD_NAND_GPMI_NFC) += gpmi_nfc.o gpmi_nfc-objs += gpmi-nfc.o -gpmi_nfc-objs += hal-mxs.o +obj-$(CONFIG_SOC_IMX23) += hal-mxs.o +obj-$(CONFIG_SOC_IMX28) += hal-mxs.o +obj-$(CONFIG_SOC_IMX50) += hal-mx50.o diff --git a/drivers/mtd/nand/gpmi-nfc/bch-regs-mx50.h b/drivers/mtd/nand/gpmi-nfc/bch-regs-mx50.h new file mode 100644 index 000000000000..a8687bb128d2 --- /dev/null +++ b/drivers/mtd/nand/gpmi-nfc/bch-regs-mx50.h @@ -0,0 +1,567 @@ +/* + * Freescale BCH Register Definitions + * + * Copyright 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * This file is created by xml file. Don't Edit it. + * + * Xml Revision: 1.3 + * Template revision: 1.3 + */ + +#ifndef __ARCH_ARM___BCH_H +#define __ARCH_ARM___BCH_H + + +#define HW_BCH_CTRL (0x00000000) +#define HW_BCH_CTRL_SET (0x00000004) +#define HW_BCH_CTRL_CLR (0x00000008) +#define HW_BCH_CTRL_TOG (0x0000000c) + +#define BM_BCH_CTRL_SFTRST 0x80000000 +#define BV_BCH_CTRL_SFTRST__RUN 0x0 +#define BV_BCH_CTRL_SFTRST__RESET 0x1 +#define BM_BCH_CTRL_CLKGATE 0x40000000 +#define BV_BCH_CTRL_CLKGATE__RUN 0x0 +#define BV_BCH_CTRL_CLKGATE__NO_CLKS 0x1 +#define BP_BCH_CTRL_RSVD5 23 +#define BM_BCH_CTRL_RSVD5 0x3F800000 +#define BF_BCH_CTRL_RSVD5(v) \ + (((v) << 23) & BM_BCH_CTRL_RSVD5) +#define BM_BCH_CTRL_DEBUGSYNDROME 0x00400000 +#define BP_BCH_CTRL_RSVD4 20 +#define BM_BCH_CTRL_RSVD4 0x00300000 +#define BF_BCH_CTRL_RSVD4(v) \ + (((v) << 20) & BM_BCH_CTRL_RSVD4) +#define BP_BCH_CTRL_M2M_LAYOUT 18 +#define BM_BCH_CTRL_M2M_LAYOUT 0x000C0000 +#define BF_BCH_CTRL_M2M_LAYOUT(v) \ + (((v) << 18) & BM_BCH_CTRL_M2M_LAYOUT) +#define BM_BCH_CTRL_M2M_ENCODE 0x00020000 +#define BM_BCH_CTRL_M2M_ENABLE 0x00010000 +#define BP_BCH_CTRL_RSVD3 11 +#define BM_BCH_CTRL_RSVD3 0x0000F800 +#define BF_BCH_CTRL_RSVD3(v) \ + (((v) << 11) & BM_BCH_CTRL_RSVD3) +#define BM_BCH_CTRL_DEBUG_STALL_IRQ_EN 0x00000400 +#define BM_BCH_CTRL_RSVD2 0x00000200 +#define BM_BCH_CTRL_COMPLETE_IRQ_EN 0x00000100 +#define BP_BCH_CTRL_RSVD1 4 +#define BM_BCH_CTRL_RSVD1 0x000000F0 +#define BF_BCH_CTRL_RSVD1(v) \ + (((v) << 4) & BM_BCH_CTRL_RSVD1) +#define BM_BCH_CTRL_BM_ERROR_IRQ 0x00000008 +#define BM_BCH_CTRL_DEBUG_STALL_IRQ 0x00000004 +#define BM_BCH_CTRL_RSVD0 0x00000002 +#define BM_BCH_CTRL_COMPLETE_IRQ 0x00000001 + +#define HW_BCH_STATUS0 (0x00000010) + +#define BP_BCH_STATUS0_HANDLE 20 +#define BM_BCH_STATUS0_HANDLE 0xFFF00000 +#define BF_BCH_STATUS0_HANDLE(v) \ + (((v) << 20) & BM_BCH_STATUS0_HANDLE) +#define BP_BCH_STATUS0_COMPLETED_CE 16 +#define BM_BCH_STATUS0_COMPLETED_CE 0x000F0000 +#define BF_BCH_STATUS0_COMPLETED_CE(v) \ + (((v) << 16) & BM_BCH_STATUS0_COMPLETED_CE) +#define BP_BCH_STATUS0_STATUS_BLK0 8 +#define BM_BCH_STATUS0_STATUS_BLK0 0x0000FF00 +#define BF_BCH_STATUS0_STATUS_BLK0(v) \ + (((v) << 8) & BM_BCH_STATUS0_STATUS_BLK0) +#define BV_BCH_STATUS0_STATUS_BLK0__ZERO 0x00 +#define BV_BCH_STATUS0_STATUS_BLK0__ERROR1 0x01 +#define BV_BCH_STATUS0_STATUS_BLK0__ERROR2 0x02 +#define BV_BCH_STATUS0_STATUS_BLK0__ERROR3 0x03 +#define BV_BCH_STATUS0_STATUS_BLK0__ERROR4 0x04 +#define BV_BCH_STATUS0_STATUS_BLK0__UNCORRECTABLE 0xFE +#define BV_BCH_STATUS0_STATUS_BLK0__ERASED 0xFF +#define BP_BCH_STATUS0_RSVD1 5 +#define BM_BCH_STATUS0_RSVD1 0x000000E0 +#define BF_BCH_STATUS0_RSVD1(v) \ + (((v) << 5) & BM_BCH_STATUS0_RSVD1) +#define BM_BCH_STATUS0_ALLONES 0x00000010 +#define BM_BCH_STATUS0_CORRECTED 0x00000008 +#define BM_BCH_STATUS0_UNCORRECTABLE 0x00000004 +#define BP_BCH_STATUS0_RSVD0 0 +#define BM_BCH_STATUS0_RSVD0 0x00000003 +#define BF_BCH_STATUS0_RSVD0(v) \ + (((v) << 0) & BM_BCH_STATUS0_RSVD0) + +#define HW_BCH_MODE (0x00000020) + +#define BP_BCH_MODE_RSVD 8 +#define BM_BCH_MODE_RSVD 0xFFFFFF00 +#define BF_BCH_MODE_RSVD(v) \ + (((v) << 8) & BM_BCH_MODE_RSVD) +#define BP_BCH_MODE_ERASE_THRESHOLD 0 +#define BM_BCH_MODE_ERASE_THRESHOLD 0x000000FF +#define BF_BCH_MODE_ERASE_THRESHOLD(v) \ + (((v) << 0) & BM_BCH_MODE_ERASE_THRESHOLD) + +#define HW_BCH_ENCODEPTR (0x00000030) + +#define BP_BCH_ENCODEPTR_ADDR 0 +#define BM_BCH_ENCODEPTR_ADDR 0xFFFFFFFF +#define BF_BCH_ENCODEPTR_ADDR(v) (v) + +#define HW_BCH_DATAPTR (0x00000040) + +#define BP_BCH_DATAPTR_ADDR 0 +#define BM_BCH_DATAPTR_ADDR 0xFFFFFFFF +#define BF_BCH_DATAPTR_ADDR(v) (v) + +#define HW_BCH_METAPTR (0x00000050) + +#define BP_BCH_METAPTR_ADDR 0 +#define BM_BCH_METAPTR_ADDR 0xFFFFFFFF +#define BF_BCH_METAPTR_ADDR(v) (v) + +#define HW_BCH_LAYOUTSELECT (0x00000070) + +#define BP_BCH_LAYOUTSELECT_CS15_SELECT 30 +#define BM_BCH_LAYOUTSELECT_CS15_SELECT 0xC0000000 +#define BF_BCH_LAYOUTSELECT_CS15_SELECT(v) \ + (((v) << 30) & BM_BCH_LAYOUTSELECT_CS15_SELECT) +#define BP_BCH_LAYOUTSELECT_CS14_SELECT 28 +#define BM_BCH_LAYOUTSELECT_CS14_SELECT 0x30000000 +#define BF_BCH_LAYOUTSELECT_CS14_SELECT(v) \ + (((v) << 28) & BM_BCH_LAYOUTSELECT_CS14_SELECT) +#define BP_BCH_LAYOUTSELECT_CS13_SELECT 26 +#define BM_BCH_LAYOUTSELECT_CS13_SELECT 0x0C000000 +#define BF_BCH_LAYOUTSELECT_CS13_SELECT(v) \ + (((v) << 26) & BM_BCH_LAYOUTSELECT_CS13_SELECT) +#define BP_BCH_LAYOUTSELECT_CS12_SELECT 24 +#define BM_BCH_LAYOUTSELECT_CS12_SELECT 0x03000000 +#define BF_BCH_LAYOUTSELECT_CS12_SELECT(v) \ + (((v) << 24) & BM_BCH_LAYOUTSELECT_CS12_SELECT) +#define BP_BCH_LAYOUTSELECT_CS11_SELECT 22 +#define BM_BCH_LAYOUTSELECT_CS11_SELECT 0x00C00000 +#define BF_BCH_LAYOUTSELECT_CS11_SELECT(v) \ + (((v) << 22) & BM_BCH_LAYOUTSELECT_CS11_SELECT) +#define BP_BCH_LAYOUTSELECT_CS10_SELECT 20 +#define BM_BCH_LAYOUTSELECT_CS10_SELECT 0x00300000 +#define BF_BCH_LAYOUTSELECT_CS10_SELECT(v) \ + (((v) << 20) & BM_BCH_LAYOUTSELECT_CS10_SELECT) +#define BP_BCH_LAYOUTSELECT_CS9_SELECT 18 +#define BM_BCH_LAYOUTSELECT_CS9_SELECT 0x000C0000 +#define BF_BCH_LAYOUTSELECT_CS9_SELECT(v) \ + (((v) << 18) & BM_BCH_LAYOUTSELECT_CS9_SELECT) +#define BP_BCH_LAYOUTSELECT_CS8_SELECT 16 +#define BM_BCH_LAYOUTSELECT_CS8_SELECT 0x00030000 +#define BF_BCH_LAYOUTSELECT_CS8_SELECT(v) \ + (((v) << 16) & BM_BCH_LAYOUTSELECT_CS8_SELECT) +#define BP_BCH_LAYOUTSELECT_CS7_SELECT 14 +#define BM_BCH_LAYOUTSELECT_CS7_SELECT 0x0000C000 +#define BF_BCH_LAYOUTSELECT_CS7_SELECT(v) \ + (((v) << 14) & BM_BCH_LAYOUTSELECT_CS7_SELECT) +#define BP_BCH_LAYOUTSELECT_CS6_SELECT 12 +#define BM_BCH_LAYOUTSELECT_CS6_SELECT 0x00003000 +#define BF_BCH_LAYOUTSELECT_CS6_SELECT(v) \ + (((v) << 12) & BM_BCH_LAYOUTSELECT_CS6_SELECT) +#define BP_BCH_LAYOUTSELECT_CS5_SELECT 10 +#define BM_BCH_LAYOUTSELECT_CS5_SELECT 0x00000C00 +#define BF_BCH_LAYOUTSELECT_CS5_SELECT(v) \ + (((v) << 10) & BM_BCH_LAYOUTSELECT_CS5_SELECT) +#define BP_BCH_LAYOUTSELECT_CS4_SELECT 8 +#define BM_BCH_LAYOUTSELECT_CS4_SELECT 0x00000300 +#define BF_BCH_LAYOUTSELECT_CS4_SELECT(v) \ + (((v) << 8) & BM_BCH_LAYOUTSELECT_CS4_SELECT) +#define BP_BCH_LAYOUTSELECT_CS3_SELECT 6 +#define BM_BCH_LAYOUTSELECT_CS3_SELECT 0x000000C0 +#define BF_BCH_LAYOUTSELECT_CS3_SELECT(v) \ + (((v) << 6) & BM_BCH_LAYOUTSELECT_CS3_SELECT) +#define BP_BCH_LAYOUTSELECT_CS2_SELECT 4 +#define BM_BCH_LAYOUTSELECT_CS2_SELECT 0x00000030 +#define BF_BCH_LAYOUTSELECT_CS2_SELECT(v) \ + (((v) << 4) & BM_BCH_LAYOUTSELECT_CS2_SELECT) +#define BP_BCH_LAYOUTSELECT_CS1_SELECT 2 +#define BM_BCH_LAYOUTSELECT_CS1_SELECT 0x0000000C +#define BF_BCH_LAYOUTSELECT_CS1_SELECT(v) \ + (((v) << 2) & BM_BCH_LAYOUTSELECT_CS1_SELECT) +#define BP_BCH_LAYOUTSELECT_CS0_SELECT 0 +#define BM_BCH_LAYOUTSELECT_CS0_SELECT 0x00000003 +#define BF_BCH_LAYOUTSELECT_CS0_SELECT(v) \ + (((v) << 0) & BM_BCH_LAYOUTSELECT_CS0_SELECT) + +#define HW_BCH_FLASH0LAYOUT0 (0x00000080) + +#define BP_BCH_FLASH0LAYOUT0_NBLOCKS 24 +#define BM_BCH_FLASH0LAYOUT0_NBLOCKS 0xFF000000 +#define BF_BCH_FLASH0LAYOUT0_NBLOCKS(v) \ + (((v) << 24) & BM_BCH_FLASH0LAYOUT0_NBLOCKS) +#define BP_BCH_FLASH0LAYOUT0_META_SIZE 16 +#define BM_BCH_FLASH0LAYOUT0_META_SIZE 0x00FF0000 +#define BF_BCH_FLASH0LAYOUT0_META_SIZE(v) \ + (((v) << 16) & BM_BCH_FLASH0LAYOUT0_META_SIZE) +#define BP_BCH_FLASH0LAYOUT0_ECC0 11 +#define BM_BCH_FLASH0LAYOUT0_ECC0 0x0000F800 +#define BF_BCH_FLASH0LAYOUT0_ECC0(v) \ + (((v) << 11) & BM_BCH_FLASH0LAYOUT0_ECC0) +#define BV_BCH_FLASH0LAYOUT0_ECC0__NONE 0x0 +#define BV_BCH_FLASH0LAYOUT0_ECC0__ECC2 0x1 +#define BV_BCH_FLASH0LAYOUT0_ECC0__ECC4 0x2 +#define BV_BCH_FLASH0LAYOUT0_ECC0__ECC6 0x3 +#define BV_BCH_FLASH0LAYOUT0_ECC0__ECC8 0x4 +#define BV_BCH_FLASH0LAYOUT0_ECC0__ECC10 0x5 +#define BV_BCH_FLASH0LAYOUT0_ECC0__ECC12 0x6 +#define BV_BCH_FLASH0LAYOUT0_ECC0__ECC14 0x7 +#define BV_BCH_FLASH0LAYOUT0_ECC0__ECC16 0x8 +#define BV_BCH_FLASH0LAYOUT0_ECC0__ECC18 0x9 +#define BV_BCH_FLASH0LAYOUT0_ECC0__ECC20 0xA +#define BV_BCH_FLASH0LAYOUT0_ECC0__ECC22 0xB +#define BV_BCH_FLASH0LAYOUT0_ECC0__ECC24 0xC +#define BV_BCH_FLASH0LAYOUT0_ECC0__ECC26 0xD +#define BV_BCH_FLASH0LAYOUT0_ECC0__ECC28 0xE +#define BV_BCH_FLASH0LAYOUT0_ECC0__ECC30 0xF +#define BV_BCH_FLASH0LAYOUT0_ECC0__ECC32 0x10 +#define BM_BCH_FLASH0LAYOUT0_GF13_0_GF14_1 0x00000400 +#define BP_BCH_FLASH0LAYOUT0_DATA0_SIZE 0 +#define BM_BCH_FLASH0LAYOUT0_DATA0_SIZE 0x000003FF +#define BF_BCH_FLASH0LAYOUT0_DATA0_SIZE(v) \ + (((v) << 0) & BM_BCH_FLASH0LAYOUT0_DATA0_SIZE) + +#define HW_BCH_FLASH0LAYOUT1 (0x00000090) + +#define BP_BCH_FLASH0LAYOUT1_PAGE_SIZE 16 +#define BM_BCH_FLASH0LAYOUT1_PAGE_SIZE 0xFFFF0000 +#define BF_BCH_FLASH0LAYOUT1_PAGE_SIZE(v) \ + (((v) << 16) & BM_BCH_FLASH0LAYOUT1_PAGE_SIZE) +#define BP_BCH_FLASH0LAYOUT1_ECCN 11 +#define BM_BCH_FLASH0LAYOUT1_ECCN 0x0000F800 +#define BF_BCH_FLASH0LAYOUT1_ECCN(v) \ + (((v) << 11) & BM_BCH_FLASH0LAYOUT1_ECCN) +#define BV_BCH_FLASH0LAYOUT1_ECCN__NONE 0x0 +#define BV_BCH_FLASH0LAYOUT1_ECCN__ECC2 0x1 +#define BV_BCH_FLASH0LAYOUT1_ECCN__ECC4 0x2 +#define BV_BCH_FLASH0LAYOUT1_ECCN__ECC6 0x3 +#define BV_BCH_FLASH0LAYOUT1_ECCN__ECC8 0x4 +#define BV_BCH_FLASH0LAYOUT1_ECCN__ECC10 0x5 +#define BV_BCH_FLASH0LAYOUT1_ECCN__ECC12 0x6 +#define BV_BCH_FLASH0LAYOUT1_ECCN__ECC14 0x7 +#define BV_BCH_FLASH0LAYOUT1_ECCN__ECC16 0x8 +#define BV_BCH_FLASH0LAYOUT1_ECCN__ECC18 0x9 +#define BV_BCH_FLASH0LAYOUT1_ECCN__ECC20 0xA +#define BV_BCH_FLASH0LAYOUT1_ECCN__ECC22 0xB +#define BV_BCH_FLASH0LAYOUT1_ECCN__ECC24 0xC +#define BV_BCH_FLASH0LAYOUT1_ECCN__ECC26 0xD +#define BV_BCH_FLASH0LAYOUT1_ECCN__ECC28 0xE +#define BV_BCH_FLASH0LAYOUT1_ECCN__ECC30 0xF +#define BV_BCH_FLASH0LAYOUT1_ECCN__ECC32 0x10 +#define BM_BCH_FLASH0LAYOUT1_GF13_0_GF14_1 0x00000400 +#define BP_BCH_FLASH0LAYOUT1_DATAN_SIZE 0 +#define BM_BCH_FLASH0LAYOUT1_DATAN_SIZE 0x000003FF +#define BF_BCH_FLASH0LAYOUT1_DATAN_SIZE(v) \ + (((v) << 0) & BM_BCH_FLASH0LAYOUT1_DATAN_SIZE) + +#define HW_BCH_FLASH1LAYOUT0 (0x000000a0) + +#define BP_BCH_FLASH1LAYOUT0_NBLOCKS 24 +#define BM_BCH_FLASH1LAYOUT0_NBLOCKS 0xFF000000 +#define BF_BCH_FLASH1LAYOUT0_NBLOCKS(v) \ + (((v) << 24) & BM_BCH_FLASH1LAYOUT0_NBLOCKS) +#define BP_BCH_FLASH1LAYOUT0_META_SIZE 16 +#define BM_BCH_FLASH1LAYOUT0_META_SIZE 0x00FF0000 +#define BF_BCH_FLASH1LAYOUT0_META_SIZE(v) \ + (((v) << 16) & BM_BCH_FLASH1LAYOUT0_META_SIZE) +#define BP_BCH_FLASH1LAYOUT0_ECC0 11 +#define BM_BCH_FLASH1LAYOUT0_ECC0 0x0000F800 +#define BF_BCH_FLASH1LAYOUT0_ECC0(v) \ + (((v) << 11) & BM_BCH_FLASH1LAYOUT0_ECC0) +#define BV_BCH_FLASH1LAYOUT0_ECC0__NONE 0x0 +#define BV_BCH_FLASH1LAYOUT0_ECC0__ECC2 0x1 +#define BV_BCH_FLASH1LAYOUT0_ECC0__ECC4 0x2 +#define BV_BCH_FLASH1LAYOUT0_ECC0__ECC6 0x3 +#define BV_BCH_FLASH1LAYOUT0_ECC0__ECC8 0x4 +#define BV_BCH_FLASH1LAYOUT0_ECC0__ECC10 0x5 +#define BV_BCH_FLASH1LAYOUT0_ECC0__ECC12 0x6 +#define BV_BCH_FLASH1LAYOUT0_ECC0__ECC14 0x7 +#define BV_BCH_FLASH1LAYOUT0_ECC0__ECC16 0x8 +#define BV_BCH_FLASH1LAYOUT0_ECC0__ECC18 0x9 +#define BV_BCH_FLASH1LAYOUT0_ECC0__ECC20 0xA +#define BV_BCH_FLASH1LAYOUT0_ECC0__ECC22 0xB +#define BV_BCH_FLASH1LAYOUT0_ECC0__ECC24 0xC +#define BV_BCH_FLASH1LAYOUT0_ECC0__ECC26 0xD +#define BV_BCH_FLASH1LAYOUT0_ECC0__ECC28 0xE +#define BV_BCH_FLASH1LAYOUT0_ECC0__ECC30 0xF +#define BV_BCH_FLASH1LAYOUT0_ECC0__ECC32 0x10 +#define BM_BCH_FLASH1LAYOUT0_GF13_0_GF14_1 0x00000400 +#define BP_BCH_FLASH1LAYOUT0_DATA0_SIZE 0 +#define BM_BCH_FLASH1LAYOUT0_DATA0_SIZE 0x000003FF +#define BF_BCH_FLASH1LAYOUT0_DATA0_SIZE(v) \ + (((v) << 0) & BM_BCH_FLASH1LAYOUT0_DATA0_SIZE) + +#define HW_BCH_FLASH1LAYOUT1 (0x000000b0) + +#define BP_BCH_FLASH1LAYOUT1_PAGE_SIZE 16 +#define BM_BCH_FLASH1LAYOUT1_PAGE_SIZE 0xFFFF0000 +#define BF_BCH_FLASH1LAYOUT1_PAGE_SIZE(v) \ + (((v) << 16) & BM_BCH_FLASH1LAYOUT1_PAGE_SIZE) +#define BP_BCH_FLASH1LAYOUT1_ECCN 11 +#define BM_BCH_FLASH1LAYOUT1_ECCN 0x0000F800 +#define BF_BCH_FLASH1LAYOUT1_ECCN(v) \ + (((v) << 11) & BM_BCH_FLASH1LAYOUT1_ECCN) +#define BV_BCH_FLASH1LAYOUT1_ECCN__NONE 0x0 +#define BV_BCH_FLASH1LAYOUT1_ECCN__ECC2 0x1 +#define BV_BCH_FLASH1LAYOUT1_ECCN__ECC4 0x2 +#define BV_BCH_FLASH1LAYOUT1_ECCN__ECC6 0x3 +#define BV_BCH_FLASH1LAYOUT1_ECCN__ECC8 0x4 +#define BV_BCH_FLASH1LAYOUT1_ECCN__ECC10 0x5 +#define BV_BCH_FLASH1LAYOUT1_ECCN__ECC12 0x6 +#define BV_BCH_FLASH1LAYOUT1_ECCN__ECC14 0x7 +#define BV_BCH_FLASH1LAYOUT1_ECCN__ECC16 0x8 +#define BV_BCH_FLASH1LAYOUT1_ECCN__ECC18 0x9 +#define BV_BCH_FLASH1LAYOUT1_ECCN__ECC20 0xA +#define BV_BCH_FLASH1LAYOUT1_ECCN__ECC22 0xB +#define BV_BCH_FLASH1LAYOUT1_ECCN__ECC24 0xC +#define BV_BCH_FLASH1LAYOUT1_ECCN__ECC26 0xD +#define BV_BCH_FLASH1LAYOUT1_ECCN__ECC28 0xE +#define BV_BCH_FLASH1LAYOUT1_ECCN__ECC30 0xF +#define BV_BCH_FLASH1LAYOUT1_ECCN__ECC32 0x10 +#define BM_BCH_FLASH1LAYOUT1_GF13_0_GF14_1 0x00000400 +#define BP_BCH_FLASH1LAYOUT1_DATAN_SIZE 0 +#define BM_BCH_FLASH1LAYOUT1_DATAN_SIZE 0x000003FF +#define BF_BCH_FLASH1LAYOUT1_DATAN_SIZE(v) \ + (((v) << 0) & BM_BCH_FLASH1LAYOUT1_DATAN_SIZE) + +#define HW_BCH_FLASH2LAYOUT0 (0x000000c0) + +#define BP_BCH_FLASH2LAYOUT0_NBLOCKS 24 +#define BM_BCH_FLASH2LAYOUT0_NBLOCKS 0xFF000000 +#define BF_BCH_FLASH2LAYOUT0_NBLOCKS(v) \ + (((v) << 24) & BM_BCH_FLASH2LAYOUT0_NBLOCKS) +#define BP_BCH_FLASH2LAYOUT0_META_SIZE 16 +#define BM_BCH_FLASH2LAYOUT0_META_SIZE 0x00FF0000 +#define BF_BCH_FLASH2LAYOUT0_META_SIZE(v) \ + (((v) << 16) & BM_BCH_FLASH2LAYOUT0_META_SIZE) +#define BP_BCH_FLASH2LAYOUT0_ECC0 11 +#define BM_BCH_FLASH2LAYOUT0_ECC0 0x0000F800 +#define BF_BCH_FLASH2LAYOUT0_ECC0(v) \ + (((v) << 11) & BM_BCH_FLASH2LAYOUT0_ECC0) +#define BV_BCH_FLASH2LAYOUT0_ECC0__NONE 0x0 +#define BV_BCH_FLASH2LAYOUT0_ECC0__ECC2 0x1 +#define BV_BCH_FLASH2LAYOUT0_ECC0__ECC4 0x2 +#define BV_BCH_FLASH2LAYOUT0_ECC0__ECC6 0x3 +#define BV_BCH_FLASH2LAYOUT0_ECC0__ECC8 0x4 +#define BV_BCH_FLASH2LAYOUT0_ECC0__ECC10 0x5 +#define BV_BCH_FLASH2LAYOUT0_ECC0__ECC12 0x6 +#define BV_BCH_FLASH2LAYOUT0_ECC0__ECC14 0x7 +#define BV_BCH_FLASH2LAYOUT0_ECC0__ECC16 0x8 +#define BV_BCH_FLASH2LAYOUT0_ECC0__ECC18 0x9 +#define BV_BCH_FLASH2LAYOUT0_ECC0__ECC20 0xA +#define BV_BCH_FLASH2LAYOUT0_ECC0__ECC22 0xB +#define BV_BCH_FLASH2LAYOUT0_ECC0__ECC24 0xC +#define BV_BCH_FLASH2LAYOUT0_ECC0__ECC26 0xD +#define BV_BCH_FLASH2LAYOUT0_ECC0__ECC28 0xE +#define BV_BCH_FLASH2LAYOUT0_ECC0__ECC30 0xF +#define BV_BCH_FLASH2LAYOUT0_ECC0__ECC32 0x10 +#define BM_BCH_FLASH2LAYOUT0_GF13_0_GF14_1 0x00000400 +#define BP_BCH_FLASH2LAYOUT0_DATA0_SIZE 0 +#define BM_BCH_FLASH2LAYOUT0_DATA0_SIZE 0x000003FF +#define BF_BCH_FLASH2LAYOUT0_DATA0_SIZE(v) \ + (((v) << 0) & BM_BCH_FLASH2LAYOUT0_DATA0_SIZE) + +#define HW_BCH_FLASH2LAYOUT1 (0x000000d0) + +#define BP_BCH_FLASH2LAYOUT1_PAGE_SIZE 16 +#define BM_BCH_FLASH2LAYOUT1_PAGE_SIZE 0xFFFF0000 +#define BF_BCH_FLASH2LAYOUT1_PAGE_SIZE(v) \ + (((v) << 16) & BM_BCH_FLASH2LAYOUT1_PAGE_SIZE) +#define BP_BCH_FLASH2LAYOUT1_ECCN 11 +#define BM_BCH_FLASH2LAYOUT1_ECCN 0x0000F800 +#define BF_BCH_FLASH2LAYOUT1_ECCN(v) \ + (((v) << 11) & BM_BCH_FLASH2LAYOUT1_ECCN) +#define BV_BCH_FLASH2LAYOUT1_ECCN__NONE 0x0 +#define BV_BCH_FLASH2LAYOUT1_ECCN__ECC2 0x1 +#define BV_BCH_FLASH2LAYOUT1_ECCN__ECC4 0x2 +#define BV_BCH_FLASH2LAYOUT1_ECCN__ECC6 0x3 +#define BV_BCH_FLASH2LAYOUT1_ECCN__ECC8 0x4 +#define BV_BCH_FLASH2LAYOUT1_ECCN__ECC10 0x5 +#define BV_BCH_FLASH2LAYOUT1_ECCN__ECC12 0x6 +#define BV_BCH_FLASH2LAYOUT1_ECCN__ECC14 0x7 +#define BV_BCH_FLASH2LAYOUT1_ECCN__ECC16 0x8 +#define BV_BCH_FLASH2LAYOUT1_ECCN__ECC18 0x9 +#define BV_BCH_FLASH2LAYOUT1_ECCN__ECC20 0xA +#define BV_BCH_FLASH2LAYOUT1_ECCN__ECC22 0xB +#define BV_BCH_FLASH2LAYOUT1_ECCN__ECC24 0xC +#define BV_BCH_FLASH2LAYOUT1_ECCN__ECC26 0xD +#define BV_BCH_FLASH2LAYOUT1_ECCN__ECC28 0xE +#define BV_BCH_FLASH2LAYOUT1_ECCN__ECC30 0xF +#define BV_BCH_FLASH2LAYOUT1_ECCN__ECC32 0x10 +#define BM_BCH_FLASH2LAYOUT1_GF13_0_GF14_1 0x00000400 +#define BP_BCH_FLASH2LAYOUT1_DATAN_SIZE 0 +#define BM_BCH_FLASH2LAYOUT1_DATAN_SIZE 0x000003FF +#define BF_BCH_FLASH2LAYOUT1_DATAN_SIZE(v) \ + (((v) << 0) & BM_BCH_FLASH2LAYOUT1_DATAN_SIZE) + +#define HW_BCH_FLASH3LAYOUT0 (0x000000e0) + +#define BP_BCH_FLASH3LAYOUT0_NBLOCKS 24 +#define BM_BCH_FLASH3LAYOUT0_NBLOCKS 0xFF000000 +#define BF_BCH_FLASH3LAYOUT0_NBLOCKS(v) \ + (((v) << 24) & BM_BCH_FLASH3LAYOUT0_NBLOCKS) +#define BP_BCH_FLASH3LAYOUT0_META_SIZE 16 +#define BM_BCH_FLASH3LAYOUT0_META_SIZE 0x00FF0000 +#define BF_BCH_FLASH3LAYOUT0_META_SIZE(v) \ + (((v) << 16) & BM_BCH_FLASH3LAYOUT0_META_SIZE) +#define BP_BCH_FLASH3LAYOUT0_ECC0 11 +#define BM_BCH_FLASH3LAYOUT0_ECC0 0x0000F800 +#define BF_BCH_FLASH3LAYOUT0_ECC0(v) \ + (((v) << 11) & BM_BCH_FLASH3LAYOUT0_ECC0) +#define BV_BCH_FLASH3LAYOUT0_ECC0__NONE 0x0 +#define BV_BCH_FLASH3LAYOUT0_ECC0__ECC2 0x1 +#define BV_BCH_FLASH3LAYOUT0_ECC0__ECC4 0x2 +#define BV_BCH_FLASH3LAYOUT0_ECC0__ECC6 0x3 +#define BV_BCH_FLASH3LAYOUT0_ECC0__ECC8 0x4 +#define BV_BCH_FLASH3LAYOUT0_ECC0__ECC10 0x5 +#define BV_BCH_FLASH3LAYOUT0_ECC0__ECC12 0x6 +#define BV_BCH_FLASH3LAYOUT0_ECC0__ECC14 0x7 +#define BV_BCH_FLASH3LAYOUT0_ECC0__ECC16 0x8 +#define BV_BCH_FLASH3LAYOUT0_ECC0__ECC18 0x9 +#define BV_BCH_FLASH3LAYOUT0_ECC0__ECC20 0xA +#define BV_BCH_FLASH3LAYOUT0_ECC0__ECC22 0xB +#define BV_BCH_FLASH3LAYOUT0_ECC0__ECC24 0xC +#define BV_BCH_FLASH3LAYOUT0_ECC0__ECC26 0xD +#define BV_BCH_FLASH3LAYOUT0_ECC0__ECC28 0xE +#define BV_BCH_FLASH3LAYOUT0_ECC0__ECC30 0xF +#define BV_BCH_FLASH3LAYOUT0_ECC0__ECC32 0x10 +#define BM_BCH_FLASH3LAYOUT0_GF13_0_GF14_1 0x00000400 +#define BP_BCH_FLASH3LAYOUT0_DATA0_SIZE 0 +#define BM_BCH_FLASH3LAYOUT0_DATA0_SIZE 0x000003FF +#define BF_BCH_FLASH3LAYOUT0_DATA0_SIZE(v) \ + (((v) << 0) & BM_BCH_FLASH3LAYOUT0_DATA0_SIZE) + +#define HW_BCH_FLASH3LAYOUT1 (0x000000f0) + +#define BP_BCH_FLASH3LAYOUT1_PAGE_SIZE 16 +#define BM_BCH_FLASH3LAYOUT1_PAGE_SIZE 0xFFFF0000 +#define BF_BCH_FLASH3LAYOUT1_PAGE_SIZE(v) \ + (((v) << 16) & BM_BCH_FLASH3LAYOUT1_PAGE_SIZE) +#define BP_BCH_FLASH3LAYOUT1_ECCN 11 +#define BM_BCH_FLASH3LAYOUT1_ECCN 0x0000F800 +#define BF_BCH_FLASH3LAYOUT1_ECCN(v) \ + (((v) << 11) & BM_BCH_FLASH3LAYOUT1_ECCN) +#define BV_BCH_FLASH3LAYOUT1_ECCN__NONE 0x0 +#define BV_BCH_FLASH3LAYOUT1_ECCN__ECC2 0x1 +#define BV_BCH_FLASH3LAYOUT1_ECCN__ECC4 0x2 +#define BV_BCH_FLASH3LAYOUT1_ECCN__ECC6 0x3 +#define BV_BCH_FLASH3LAYOUT1_ECCN__ECC8 0x4 +#define BV_BCH_FLASH3LAYOUT1_ECCN__ECC10 0x5 +#define BV_BCH_FLASH3LAYOUT1_ECCN__ECC12 0x6 +#define BV_BCH_FLASH3LAYOUT1_ECCN__ECC14 0x7 +#define BV_BCH_FLASH3LAYOUT1_ECCN__ECC16 0x8 +#define BV_BCH_FLASH3LAYOUT1_ECCN__ECC18 0x9 +#define BV_BCH_FLASH3LAYOUT1_ECCN__ECC20 0xA +#define BV_BCH_FLASH3LAYOUT1_ECCN__ECC22 0xB +#define BV_BCH_FLASH3LAYOUT1_ECCN__ECC24 0xC +#define BV_BCH_FLASH3LAYOUT1_ECCN__ECC26 0xD +#define BV_BCH_FLASH3LAYOUT1_ECCN__ECC28 0xE +#define BV_BCH_FLASH3LAYOUT1_ECCN__ECC30 0xF +#define BV_BCH_FLASH3LAYOUT1_ECCN__ECC32 0x10 +#define BM_BCH_FLASH3LAYOUT1_GF13_0_GF14_1 0x00000400 +#define BP_BCH_FLASH3LAYOUT1_DATAN_SIZE 0 +#define BM_BCH_FLASH3LAYOUT1_DATAN_SIZE 0x000003FF +#define BF_BCH_FLASH3LAYOUT1_DATAN_SIZE(v) \ + (((v) << 0) & BM_BCH_FLASH3LAYOUT1_DATAN_SIZE) + +#define HW_BCH_DEBUG0 (0x00000100) +#define HW_BCH_DEBUG0_SET (0x00000104) +#define HW_BCH_DEBUG0_CLR (0x00000108) +#define HW_BCH_DEBUG0_TOG (0x0000010c) + +#define BP_BCH_DEBUG0_RSVD1 25 +#define BM_BCH_DEBUG0_RSVD1 0xFE000000 +#define BF_BCH_DEBUG0_RSVD1(v) \ + (((v) << 25) & BM_BCH_DEBUG0_RSVD1) +#define BP_BCH_DEBUG0_KES_DEBUG_SYNDROME_SYMBOL 16 +#define BM_BCH_DEBUG0_KES_DEBUG_SYNDROME_SYMBOL 0x01FF0000 +#define BF_BCH_DEBUG0_KES_DEBUG_SYNDROME_SYMBOL(v) \ + (((v) << 16) & BM_BCH_DEBUG0_KES_DEBUG_SYNDROME_SYMBOL) +#define BV_BCH_DEBUG0_KES_DEBUG_SYNDROME_SYMBOL__NORMAL 0x0 +#define BV_BCH_DEBUG0_KES_DEBUG_SYNDROME_SYMBOL__TEST_MODE 0x1 +#define BM_BCH_DEBUG0_KES_DEBUG_SHIFT_SYND 0x00008000 +#define BM_BCH_DEBUG0_KES_DEBUG_PAYLOAD_FLAG 0x00004000 +#define BV_BCH_DEBUG0_KES_DEBUG_PAYLOAD_FLAG__DATA 0x1 +#define BV_BCH_DEBUG0_KES_DEBUG_PAYLOAD_FLAG__AUX 0x1 +#define BM_BCH_DEBUG0_KES_DEBUG_MODE4K 0x00002000 +#define BV_BCH_DEBUG0_KES_DEBUG_MODE4K__4k 0x1 +#define BV_BCH_DEBUG0_KES_DEBUG_MODE4K__2k 0x1 +#define BM_BCH_DEBUG0_KES_DEBUG_KICK 0x00001000 +#define BM_BCH_DEBUG0_KES_STANDALONE 0x00000800 +#define BV_BCH_DEBUG0_KES_STANDALONE__NORMAL 0x0 +#define BV_BCH_DEBUG0_KES_STANDALONE__TEST_MODE 0x1 +#define BM_BCH_DEBUG0_KES_DEBUG_STEP 0x00000400 +#define BM_BCH_DEBUG0_KES_DEBUG_STALL 0x00000200 +#define BV_BCH_DEBUG0_KES_DEBUG_STALL__NORMAL 0x0 +#define BV_BCH_DEBUG0_KES_DEBUG_STALL__WAIT 0x1 +#define BM_BCH_DEBUG0_BM_KES_TEST_BYPASS 0x00000100 +#define BV_BCH_DEBUG0_BM_KES_TEST_BYPASS__NORMAL 0x0 +#define BV_BCH_DEBUG0_BM_KES_TEST_BYPASS__TEST_MODE 0x1 +#define BP_BCH_DEBUG0_RSVD0 6 +#define BM_BCH_DEBUG0_RSVD0 0x000000C0 +#define BF_BCH_DEBUG0_RSVD0(v) \ + (((v) << 6) & BM_BCH_DEBUG0_RSVD0) +#define BP_BCH_DEBUG0_DEBUG_REG_SELECT 0 +#define BM_BCH_DEBUG0_DEBUG_REG_SELECT 0x0000003F +#define BF_BCH_DEBUG0_DEBUG_REG_SELECT(v) \ + (((v) << 0) & BM_BCH_DEBUG0_DEBUG_REG_SELECT) + +#define HW_BCH_DBGKESREAD (0x00000110) + +#define BP_BCH_DBGKESREAD_VALUES 0 +#define BM_BCH_DBGKESREAD_VALUES 0xFFFFFFFF +#define BF_BCH_DBGKESREAD_VALUES(v) (v) + +#define HW_BCH_DBGCSFEREAD (0x00000120) + +#define BP_BCH_DBGCSFEREAD_VALUES 0 +#define BM_BCH_DBGCSFEREAD_VALUES 0xFFFFFFFF +#define BF_BCH_DBGCSFEREAD_VALUES(v) (v) + +#define HW_BCH_DBGSYNDGENREAD (0x00000130) + +#define BP_BCH_DBGSYNDGENREAD_VALUES 0 +#define BM_BCH_DBGSYNDGENREAD_VALUES 0xFFFFFFFF +#define BF_BCH_DBGSYNDGENREAD_VALUES(v) (v) + +#define HW_BCH_DBGAHBMREAD (0x00000140) + +#define BP_BCH_DBGAHBMREAD_VALUES 0 +#define BM_BCH_DBGAHBMREAD_VALUES 0xFFFFFFFF +#define BF_BCH_DBGAHBMREAD_VALUES(v) (v) + +#define HW_BCH_BLOCKNAME (0x00000150) + +#define BP_BCH_BLOCKNAME_NAME 0 +#define BM_BCH_BLOCKNAME_NAME 0xFFFFFFFF +#define BF_BCH_BLOCKNAME_NAME(v) (v) + +#define HW_BCH_VERSION (0x00000160) + +#define BP_BCH_VERSION_MAJOR 24 +#define BM_BCH_VERSION_MAJOR 0xFF000000 +#define BF_BCH_VERSION_MAJOR(v) \ + (((v) << 24) & BM_BCH_VERSION_MAJOR) +#define BP_BCH_VERSION_MINOR 16 +#define BM_BCH_VERSION_MINOR 0x00FF0000 +#define BF_BCH_VERSION_MINOR(v) \ + (((v) << 16) & BM_BCH_VERSION_MINOR) +#define BP_BCH_VERSION_STEP 0 +#define BM_BCH_VERSION_STEP 0x0000FFFF +#define BF_BCH_VERSION_STEP(v) \ + (((v) << 0) & BM_BCH_VERSION_STEP) +#endif /* __ARCH_ARM___BCH_H */ diff --git a/drivers/mtd/nand/gpmi-nfc/gpmi-nfc.c b/drivers/mtd/nand/gpmi-nfc/gpmi-nfc.c index a838e8c5c74d..95972af2ceff 100644 --- a/drivers/mtd/nand/gpmi-nfc/gpmi-nfc.c +++ b/drivers/mtd/nand/gpmi-nfc/gpmi-nfc.c @@ -1141,9 +1141,14 @@ static int __devinit set_up_nfc_hal(struct gpmi_nfc_data *this) .tRHOH_in_ns = -1, }; +#if defined(CONFIG_SOC_IMX23) || defined(CONFIG_SOC_IMX28) if (GPMI_IS_MX23(this) || GPMI_IS_MX28(this)) nfc = &gpmi_nfc_hal_imx23_imx28; - +#endif +#if defined(CONFIG_SOC_IMX50) + if (GPMI_IS_MX50(this)) + nfc = &gpmi_nfc_hal_mx50; +#endif BUG_ON(nfc == NULL); this->nfc = nfc; @@ -2428,6 +2433,9 @@ static const struct platform_device_id gpmi_ids[] = { }, { .name = "imx28-gpmi-nfc", .driver_data = IS_MX28, + }, { + .name = "imx50-gpmi-nfc", + .driver_data = IS_MX50, }, {}, }; diff --git a/drivers/mtd/nand/gpmi-nfc/gpmi-nfc.h b/drivers/mtd/nand/gpmi-nfc/gpmi-nfc.h index 50f7baf2ede4..dfa9cd160520 100644 --- a/drivers/mtd/nand/gpmi-nfc/gpmi-nfc.h +++ b/drivers/mtd/nand/gpmi-nfc/gpmi-nfc.h @@ -457,6 +457,7 @@ extern int start_dma_with_bch_irq(struct gpmi_nfc_data *this, struct dma_async_tx_descriptor *desc); /* NFC HAL Structures */ extern struct nfc_hal gpmi_nfc_hal_imx23_imx28; +extern struct nfc_hal gpmi_nfc_hal_mx50; /* ONFI or TOGGLE nand */ bool is_ddr_nand(struct gpmi_nfc_data *); @@ -489,6 +490,8 @@ extern int gpmi_debug; /* Use the platform_id to distinguish different Archs. */ #define IS_MX23 0x1 #define IS_MX28 0x2 +#define IS_MX50 0x4 #define GPMI_IS_MX23(x) ((x)->pdev->id_entry->driver_data == IS_MX23) #define GPMI_IS_MX28(x) ((x)->pdev->id_entry->driver_data == IS_MX28) +#define GPMI_IS_MX50(x) ((x)->pdev->id_entry->driver_data == IS_MX50) #endif diff --git a/drivers/mtd/nand/gpmi-nfc/gpmi-regs-mx50.h b/drivers/mtd/nand/gpmi-nfc/gpmi-regs-mx50.h new file mode 100644 index 000000000000..05986d8c1ac9 --- /dev/null +++ b/drivers/mtd/nand/gpmi-nfc/gpmi-regs-mx50.h @@ -0,0 +1,511 @@ +/* + * Freescale GPMI Register Definitions + * + * Copyright 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * This file is created by xml file. Don't Edit it. + * + * Xml Revision: 1.19 + * Template revision: 1.3 + */ + +#ifndef __ARCH_ARM___GPMI_H +#define __ARCH_ARM___GPMI_H + + +#define HW_GPMI_CTRL0 (0x00000000) +#define HW_GPMI_CTRL0_SET (0x00000004) +#define HW_GPMI_CTRL0_CLR (0x00000008) +#define HW_GPMI_CTRL0_TOG (0x0000000c) + +#define BM_GPMI_CTRL0_SFTRST 0x80000000 +#define BV_GPMI_CTRL0_SFTRST__RUN 0x0 +#define BV_GPMI_CTRL0_SFTRST__RESET 0x1 +#define BM_GPMI_CTRL0_CLKGATE 0x40000000 +#define BV_GPMI_CTRL0_CLKGATE__RUN 0x0 +#define BV_GPMI_CTRL0_CLKGATE__NO_CLKS 0x1 +#define BM_GPMI_CTRL0_RUN 0x20000000 +#define BV_GPMI_CTRL0_RUN__IDLE 0x0 +#define BV_GPMI_CTRL0_RUN__BUSY 0x1 +#define BM_GPMI_CTRL0_DEV_IRQ_EN 0x10000000 +#define BM_GPMI_CTRL0_LOCK_CS 0x08000000 +#define BV_GPMI_CTRL0_LOCK_CS__DISABLED 0x0 +#define BV_GPMI_CTRL0_LOCK_CS__ENABLED 0x1 +#define BM_GPMI_CTRL0_UDMA 0x04000000 +#define BV_GPMI_CTRL0_UDMA__DISABLED 0x0 +#define BV_GPMI_CTRL0_UDMA__ENABLED 0x1 +#define BP_GPMI_CTRL0_COMMAND_MODE 24 +#define BM_GPMI_CTRL0_COMMAND_MODE 0x03000000 +#define BF_GPMI_CTRL0_COMMAND_MODE(v) \ + (((v) << 24) & BM_GPMI_CTRL0_COMMAND_MODE) +#define BV_GPMI_CTRL0_COMMAND_MODE__WRITE 0x0 +#define BV_GPMI_CTRL0_COMMAND_MODE__READ 0x1 +#define BV_GPMI_CTRL0_COMMAND_MODE__READ_AND_COMPARE 0x2 +#define BV_GPMI_CTRL0_COMMAND_MODE__WAIT_FOR_READY 0x3 +#define BM_GPMI_CTRL0_WORD_LENGTH 0x00800000 +#define BV_GPMI_CTRL0_WORD_LENGTH__16_BIT 0x0 +#define BV_GPMI_CTRL0_WORD_LENGTH__8_BIT 0x1 +#define BP_GPMI_CTRL0_CS 20 +#define BM_GPMI_CTRL0_CS 0x00700000 +#define BF_GPMI_CTRL0_CS(v) \ + (((v) << 20) & BM_GPMI_CTRL0_CS) +#define BP_GPMI_CTRL0_ADDRESS 17 +#define BM_GPMI_CTRL0_ADDRESS 0x000E0000 +#define BF_GPMI_CTRL0_ADDRESS(v) \ + (((v) << 17) & BM_GPMI_CTRL0_ADDRESS) +#define BV_GPMI_CTRL0_ADDRESS__NAND_DATA 0x0 +#define BV_GPMI_CTRL0_ADDRESS__NAND_CLE 0x1 +#define BV_GPMI_CTRL0_ADDRESS__NAND_ALE 0x2 +#define BM_GPMI_CTRL0_ADDRESS_INCREMENT 0x00010000 +#define BV_GPMI_CTRL0_ADDRESS_INCREMENT__DISABLED 0x0 +#define BV_GPMI_CTRL0_ADDRESS_INCREMENT__ENABLED 0x1 +#define BP_GPMI_CTRL0_XFER_COUNT 0 +#define BM_GPMI_CTRL0_XFER_COUNT 0x0000FFFF +#define BF_GPMI_CTRL0_XFER_COUNT(v) \ + (((v) << 0) & BM_GPMI_CTRL0_XFER_COUNT) + +#define HW_GPMI_COMPARE (0x00000010) + +#define BP_GPMI_COMPARE_MASK 16 +#define BM_GPMI_COMPARE_MASK 0xFFFF0000 +#define BF_GPMI_COMPARE_MASK(v) \ + (((v) << 16) & BM_GPMI_COMPARE_MASK) +#define BP_GPMI_COMPARE_REFERENCE 0 +#define BM_GPMI_COMPARE_REFERENCE 0x0000FFFF +#define BF_GPMI_COMPARE_REFERENCE(v) \ + (((v) << 0) & BM_GPMI_COMPARE_REFERENCE) + +#define HW_GPMI_ECCCTRL (0x00000020) +#define HW_GPMI_ECCCTRL_SET (0x00000024) +#define HW_GPMI_ECCCTRL_CLR (0x00000028) +#define HW_GPMI_ECCCTRL_TOG (0x0000002c) + +#define BP_GPMI_ECCCTRL_HANDLE 16 +#define BM_GPMI_ECCCTRL_HANDLE 0xFFFF0000 +#define BF_GPMI_ECCCTRL_HANDLE(v) \ + (((v) << 16) & BM_GPMI_ECCCTRL_HANDLE) +#define BM_GPMI_ECCCTRL_RSVD2 0x00008000 +#define BP_GPMI_ECCCTRL_ECC_CMD 13 +#define BM_GPMI_ECCCTRL_ECC_CMD 0x00006000 +#define BF_GPMI_ECCCTRL_ECC_CMD(v) \ + (((v) << 13) & BM_GPMI_ECCCTRL_ECC_CMD) +#define BV_GPMI_ECCCTRL_ECC_CMD__BCH_DECODE 0x0 +#define BV_GPMI_ECCCTRL_ECC_CMD__BCH_ENCODE 0x1 +#define BV_GPMI_ECCCTRL_ECC_CMD__RESERVE2 0x2 +#define BV_GPMI_ECCCTRL_ECC_CMD__RESERVE3 0x3 +#define BM_GPMI_ECCCTRL_ENABLE_ECC 0x00001000 +#define BV_GPMI_ECCCTRL_ENABLE_ECC__ENABLE 0x1 +#define BV_GPMI_ECCCTRL_ENABLE_ECC__DISABLE 0x0 +#define BP_GPMI_ECCCTRL_RSVD1 9 +#define BM_GPMI_ECCCTRL_RSVD1 0x00000E00 +#define BF_GPMI_ECCCTRL_RSVD1(v) \ + (((v) << 9) & BM_GPMI_ECCCTRL_RSVD1) +#define BP_GPMI_ECCCTRL_BUFFER_MASK 0 +#define BM_GPMI_ECCCTRL_BUFFER_MASK 0x000001FF +#define BF_GPMI_ECCCTRL_BUFFER_MASK(v) \ + (((v) << 0) & BM_GPMI_ECCCTRL_BUFFER_MASK) +#define BV_GPMI_ECCCTRL_BUFFER_MASK__BCH_AUXONLY 0x100 +#define BV_GPMI_ECCCTRL_BUFFER_MASK__BCH_PAGE 0x1FF + +#define HW_GPMI_ECCCOUNT (0x00000030) + +#define BP_GPMI_ECCCOUNT_RSVD2 16 +#define BM_GPMI_ECCCOUNT_RSVD2 0xFFFF0000 +#define BF_GPMI_ECCCOUNT_RSVD2(v) \ + (((v) << 16) & BM_GPMI_ECCCOUNT_RSVD2) +#define BP_GPMI_ECCCOUNT_COUNT 0 +#define BM_GPMI_ECCCOUNT_COUNT 0x0000FFFF +#define BF_GPMI_ECCCOUNT_COUNT(v) \ + (((v) << 0) & BM_GPMI_ECCCOUNT_COUNT) + +#define HW_GPMI_PAYLOAD (0x00000040) + +#define BP_GPMI_PAYLOAD_ADDRESS 2 +#define BM_GPMI_PAYLOAD_ADDRESS 0xFFFFFFFC +#define BF_GPMI_PAYLOAD_ADDRESS(v) \ + (((v) << 2) & BM_GPMI_PAYLOAD_ADDRESS) +#define BP_GPMI_PAYLOAD_RSVD0 0 +#define BM_GPMI_PAYLOAD_RSVD0 0x00000003 +#define BF_GPMI_PAYLOAD_RSVD0(v) \ + (((v) << 0) & BM_GPMI_PAYLOAD_RSVD0) + +#define HW_GPMI_AUXILIARY (0x00000050) + +#define BP_GPMI_AUXILIARY_ADDRESS 2 +#define BM_GPMI_AUXILIARY_ADDRESS 0xFFFFFFFC +#define BF_GPMI_AUXILIARY_ADDRESS(v) \ + (((v) << 2) & BM_GPMI_AUXILIARY_ADDRESS) +#define BP_GPMI_AUXILIARY_RSVD0 0 +#define BM_GPMI_AUXILIARY_RSVD0 0x00000003 +#define BF_GPMI_AUXILIARY_RSVD0(v) \ + (((v) << 0) & BM_GPMI_AUXILIARY_RSVD0) + +#define HW_GPMI_CTRL1 (0x00000060) +#define HW_GPMI_CTRL1_SET (0x00000064) +#define HW_GPMI_CTRL1_CLR (0x00000068) +#define HW_GPMI_CTRL1_TOG (0x0000006c) + +#define BM_GPMI_CTRL1_DEV_CLK_STOP 0x80000000 +#define BM_GPMI_CTRL1_SSYNC_CLK_STOP 0x40000000 +#define BM_GPMI_CTRL1_WRITE_CLK_STOP 0x20000000 +#define BM_GPMI_CTRL1_TOGGLE_MODE 0x10000000 +#define BM_GPMI_CTRL1_GPMI_CLK_DIV2_EN 0x08000000 +#define BM_GPMI_CTRL1_UPDATE_CS 0x04000000 +#define BM_GPMI_CTRL1_SSYNCMODE 0x02000000 +#define BV_GPMI_CTRL1_SSYNCMODE__ASYNC 0x0 +#define BV_GPMI_CTRL1_SSYNCMODE__SSYNC 0x1 +#define BM_GPMI_CTRL1_DECOUPLE_CS 0x01000000 +#define BP_GPMI_CTRL1_WRN_DLY_SEL 22 +#define BM_GPMI_CTRL1_WRN_DLY_SEL 0x00C00000 +#define BF_GPMI_CTRL1_WRN_DLY_SEL(v) \ + (((v) << 22) & BM_GPMI_CTRL1_WRN_DLY_SEL) +#define BM_GPMI_CTRL1_RSVD1 0x00200000 +#define BM_GPMI_CTRL1_TIMEOUT_IRQ_EN 0x00100000 +#define BM_GPMI_CTRL1_GANGED_RDYBUSY 0x00080000 +#define BM_GPMI_CTRL1_BCH_MODE 0x00040000 +#define BM_GPMI_CTRL1_DLL_ENABLE 0x00020000 +#define BP_GPMI_CTRL1_HALF_PERIOD 16 +#define BM_GPMI_CTRL1_HALF_PERIOD 0x00010000 +#define BP_GPMI_CTRL1_RDN_DELAY 12 +#define BM_GPMI_CTRL1_RDN_DELAY 0x0000F000 +#define BF_GPMI_CTRL1_RDN_DELAY(v) \ + (((v) << 12) & BM_GPMI_CTRL1_RDN_DELAY) +#define BM_GPMI_CTRL1_DMA2ECC_MODE 0x00000800 +#define BM_GPMI_CTRL1_DEV_IRQ 0x00000400 +#define BM_GPMI_CTRL1_TIMEOUT_IRQ 0x00000200 +#define BM_GPMI_CTRL1_BURST_EN 0x00000100 +#define BM_GPMI_CTRL1_ABORT_WAIT_REQUEST 0x00000080 +#define BP_GPMI_CTRL1_ABORT_WAIT_FOR_READY_CHANNEL 4 +#define BM_GPMI_CTRL1_ABORT_WAIT_FOR_READY_CHANNEL 0x00000070 +#define BF_GPMI_CTRL1_ABORT_WAIT_FOR_READY_CHANNEL(v) \ + (((v) << 4) & BM_GPMI_CTRL1_ABORT_WAIT_FOR_READY_CHANNEL) +#define BM_GPMI_CTRL1_DEV_RESET 0x00000008 +#define BV_GPMI_CTRL1_DEV_RESET__ENABLED 0x0 +#define BV_GPMI_CTRL1_DEV_RESET__DISABLED 0x1 +#define BM_GPMI_CTRL1_ATA_IRQRDY_POLARITY 0x00000004 +#define BV_GPMI_CTRL1_ATA_IRQRDY_POLARITY__ACTIVELOW 0x0 +#define BV_GPMI_CTRL1_ATA_IRQRDY_POLARITY__ACTIVEHIGH 0x1 +#define BM_GPMI_CTRL1_CAMERA_MODE 0x00000002 +#define BM_GPMI_CTRL1_GPMI_MODE 0x00000001 +#define BV_GPMI_CTRL1_GPMI_MODE__NAND 0x0 +#define BV_GPMI_CTRL1_GPMI_MODE__ATA 0x1 + +#define HW_GPMI_TIMING0 (0x00000070) + +#define BP_GPMI_TIMING0_RSVD1 24 +#define BM_GPMI_TIMING0_RSVD1 0xFF000000 +#define BF_GPMI_TIMING0_RSVD1(v) \ + (((v) << 24) & BM_GPMI_TIMING0_RSVD1) +#define BP_GPMI_TIMING0_ADDRESS_SETUP 16 +#define BM_GPMI_TIMING0_ADDRESS_SETUP 0x00FF0000 +#define BF_GPMI_TIMING0_ADDRESS_SETUP(v) \ + (((v) << 16) & BM_GPMI_TIMING0_ADDRESS_SETUP) +#define BP_GPMI_TIMING0_DATA_HOLD 8 +#define BM_GPMI_TIMING0_DATA_HOLD 0x0000FF00 +#define BF_GPMI_TIMING0_DATA_HOLD(v) \ + (((v) << 8) & BM_GPMI_TIMING0_DATA_HOLD) +#define BP_GPMI_TIMING0_DATA_SETUP 0 +#define BM_GPMI_TIMING0_DATA_SETUP 0x000000FF +#define BF_GPMI_TIMING0_DATA_SETUP(v) \ + (((v) << 0) & BM_GPMI_TIMING0_DATA_SETUP) + +#define HW_GPMI_TIMING1 (0x00000080) + +#define BP_GPMI_TIMING1_DEVICE_BUSY_TIMEOUT 16 +#define BM_GPMI_TIMING1_DEVICE_BUSY_TIMEOUT 0xFFFF0000 +#define BF_GPMI_TIMING1_DEVICE_BUSY_TIMEOUT(v) \ + (((v) << 16) & BM_GPMI_TIMING1_DEVICE_BUSY_TIMEOUT) +#define BP_GPMI_TIMING1_RSVD1 0 +#define BM_GPMI_TIMING1_RSVD1 0x0000FFFF +#define BF_GPMI_TIMING1_RSVD1(v) \ + (((v) << 0) & BM_GPMI_TIMING1_RSVD1) + +#define HW_GPMI_TIMING2 (0x00000090) + +#define BP_GPMI_TIMING2_RSVD1 27 +#define BM_GPMI_TIMING2_RSVD1 0xF8000000 +#define BF_GPMI_TIMING2_RSVD1(v) \ + (((v) << 27) & BM_GPMI_TIMING2_RSVD1) +#define BP_GPMI_TIMING2_READ_LATENCY 24 +#define BM_GPMI_TIMING2_READ_LATENCY 0x07000000 +#define BF_GPMI_TIMING2_READ_LATENCY(v) \ + (((v) << 24) & BM_GPMI_TIMING2_READ_LATENCY) +#define BP_GPMI_TIMING2_RSVD0 21 +#define BM_GPMI_TIMING2_RSVD0 0x00E00000 +#define BF_GPMI_TIMING2_RSVD0(v) \ + (((v) << 21) & BM_GPMI_TIMING2_RSVD0) +#define BP_GPMI_TIMING2_CE_DELAY 16 +#define BM_GPMI_TIMING2_CE_DELAY 0x001F0000 +#define BF_GPMI_TIMING2_CE_DELAY(v) \ + (((v) << 16) & BM_GPMI_TIMING2_CE_DELAY) +#define BP_GPMI_TIMING2_PREAMBLE_DELAY 12 +#define BM_GPMI_TIMING2_PREAMBLE_DELAY 0x0000F000 +#define BF_GPMI_TIMING2_PREAMBLE_DELAY(v) \ + (((v) << 12) & BM_GPMI_TIMING2_PREAMBLE_DELAY) +#define BP_GPMI_TIMING2_POSTAMBLE_DELAY 8 +#define BM_GPMI_TIMING2_POSTAMBLE_DELAY 0x00000F00 +#define BF_GPMI_TIMING2_POSTAMBLE_DELAY(v) \ + (((v) << 8) & BM_GPMI_TIMING2_POSTAMBLE_DELAY) +#define BP_GPMI_TIMING2_CMDADD_PAUSE 4 +#define BM_GPMI_TIMING2_CMDADD_PAUSE 0x000000F0 +#define BF_GPMI_TIMING2_CMDADD_PAUSE(v) \ + (((v) << 4) & BM_GPMI_TIMING2_CMDADD_PAUSE) +#define BP_GPMI_TIMING2_DATA_PAUSE 0 +#define BM_GPMI_TIMING2_DATA_PAUSE 0x0000000F +#define BF_GPMI_TIMING2_DATA_PAUSE(v) \ + (((v) << 0) & BM_GPMI_TIMING2_DATA_PAUSE) + +#define HW_GPMI_DATA (0x000000a0) + +#define BP_GPMI_DATA_DATA 0 +#define BM_GPMI_DATA_DATA 0xFFFFFFFF +#define BF_GPMI_DATA_DATA(v) (v) + +#define HW_GPMI_STAT (0x000000b0) + +#define BP_GPMI_STAT_READY_BUSY 24 +#define BM_GPMI_STAT_READY_BUSY 0xFF000000 +#define BF_GPMI_STAT_READY_BUSY(v) \ + (((v) << 24) & BM_GPMI_STAT_READY_BUSY) +#define BP_GPMI_STAT_RDY_TIMEOUT 16 +#define BM_GPMI_STAT_RDY_TIMEOUT 0x00FF0000 +#define BF_GPMI_STAT_RDY_TIMEOUT(v) \ + (((v) << 16) & BM_GPMI_STAT_RDY_TIMEOUT) +#define BM_GPMI_STAT_DEV7_ERROR 0x00008000 +#define BM_GPMI_STAT_DEV6_ERROR 0x00004000 +#define BM_GPMI_STAT_DEV5_ERROR 0x00002000 +#define BM_GPMI_STAT_DEV4_ERROR 0x00001000 +#define BM_GPMI_STAT_DEV3_ERROR 0x00000800 +#define BM_GPMI_STAT_DEV2_ERROR 0x00000400 +#define BM_GPMI_STAT_DEV1_ERROR 0x00000200 +#define BM_GPMI_STAT_DEV0_ERROR 0x00000100 +#define BP_GPMI_STAT_RSVD1 5 +#define BM_GPMI_STAT_RSVD1 0x000000E0 +#define BF_GPMI_STAT_RSVD1(v) \ + (((v) << 5) & BM_GPMI_STAT_RSVD1) +#define BM_GPMI_STAT_ATA_IRQ 0x00000010 +#define BM_GPMI_STAT_INVALID_BUFFER_MASK 0x00000008 +#define BM_GPMI_STAT_FIFO_EMPTY 0x00000004 +#define BV_GPMI_STAT_FIFO_EMPTY__NOT_EMPTY 0x0 +#define BV_GPMI_STAT_FIFO_EMPTY__EMPTY 0x1 +#define BM_GPMI_STAT_FIFO_FULL 0x00000002 +#define BV_GPMI_STAT_FIFO_FULL__NOT_FULL 0x0 +#define BV_GPMI_STAT_FIFO_FULL__FULL 0x1 +#define BM_GPMI_STAT_PRESENT 0x00000001 +#define BV_GPMI_STAT_PRESENT__UNAVAILABLE 0x0 +#define BV_GPMI_STAT_PRESENT__AVAILABLE 0x1 + +#define HW_GPMI_DEBUG (0x000000c0) + +#define BP_GPMI_DEBUG_WAIT_FOR_READY_END 24 +#define BM_GPMI_DEBUG_WAIT_FOR_READY_END 0xFF000000 +#define BF_GPMI_DEBUG_WAIT_FOR_READY_END(v) \ + (((v) << 24) & BM_GPMI_DEBUG_WAIT_FOR_READY_END) +#define BP_GPMI_DEBUG_DMA_SENSE 16 +#define BM_GPMI_DEBUG_DMA_SENSE 0x00FF0000 +#define BF_GPMI_DEBUG_DMA_SENSE(v) \ + (((v) << 16) & BM_GPMI_DEBUG_DMA_SENSE) +#define BP_GPMI_DEBUG_DMAREQ 8 +#define BM_GPMI_DEBUG_DMAREQ 0x0000FF00 +#define BF_GPMI_DEBUG_DMAREQ(v) \ + (((v) << 8) & BM_GPMI_DEBUG_DMAREQ) +#define BP_GPMI_DEBUG_CMD_END 0 +#define BM_GPMI_DEBUG_CMD_END 0x000000FF +#define BF_GPMI_DEBUG_CMD_END(v) \ + (((v) << 0) & BM_GPMI_DEBUG_CMD_END) + +#define HW_GPMI_VERSION (0x000000d0) + +#define BP_GPMI_VERSION_MAJOR 24 +#define BM_GPMI_VERSION_MAJOR 0xFF000000 +#define BF_GPMI_VERSION_MAJOR(v) \ + (((v) << 24) & BM_GPMI_VERSION_MAJOR) +#define BP_GPMI_VERSION_MINOR 16 +#define BM_GPMI_VERSION_MINOR 0x00FF0000 +#define BF_GPMI_VERSION_MINOR(v) \ + (((v) << 16) & BM_GPMI_VERSION_MINOR) +#define BP_GPMI_VERSION_STEP 0 +#define BM_GPMI_VERSION_STEP 0x0000FFFF +#define BF_GPMI_VERSION_STEP(v) \ + (((v) << 0) & BM_GPMI_VERSION_STEP) + +#define HW_GPMI_DEBUG2 (0x000000e0) + +#define BP_GPMI_DEBUG2_RSVD1 28 +#define BM_GPMI_DEBUG2_RSVD1 0xF0000000 +#define BF_GPMI_DEBUG2_RSVD1(v) \ + (((v) << 28) & BM_GPMI_DEBUG2_RSVD1) +#define BP_GPMI_DEBUG2_UDMA_STATE 24 +#define BM_GPMI_DEBUG2_UDMA_STATE 0x0F000000 +#define BF_GPMI_DEBUG2_UDMA_STATE(v) \ + (((v) << 24) & BM_GPMI_DEBUG2_UDMA_STATE) +#define BM_GPMI_DEBUG2_BUSY 0x00800000 +#define BV_GPMI_DEBUG2_BUSY__DISABLED 0x0 +#define BV_GPMI_DEBUG2_BUSY__ENABLED 0x1 +#define BP_GPMI_DEBUG2_PIN_STATE 20 +#define BM_GPMI_DEBUG2_PIN_STATE 0x00700000 +#define BF_GPMI_DEBUG2_PIN_STATE(v) \ + (((v) << 20) & BM_GPMI_DEBUG2_PIN_STATE) +#define BV_GPMI_DEBUG2_PIN_STATE__PSM_IDLE 0x0 +#define BV_GPMI_DEBUG2_PIN_STATE__PSM_BYTCNT 0x1 +#define BV_GPMI_DEBUG2_PIN_STATE__PSM_ADDR 0x2 +#define BV_GPMI_DEBUG2_PIN_STATE__PSM_STALL 0x3 +#define BV_GPMI_DEBUG2_PIN_STATE__PSM_STROBE 0x4 +#define BV_GPMI_DEBUG2_PIN_STATE__PSM_ATARDY 0x5 +#define BV_GPMI_DEBUG2_PIN_STATE__PSM_DHOLD 0x6 +#define BV_GPMI_DEBUG2_PIN_STATE__PSM_DONE 0x7 +#define BP_GPMI_DEBUG2_MAIN_STATE 16 +#define BM_GPMI_DEBUG2_MAIN_STATE 0x000F0000 +#define BF_GPMI_DEBUG2_MAIN_STATE(v) \ + (((v) << 16) & BM_GPMI_DEBUG2_MAIN_STATE) +#define BV_GPMI_DEBUG2_MAIN_STATE__MSM_IDLE 0x0 +#define BV_GPMI_DEBUG2_MAIN_STATE__MSM_BYTCNT 0x1 +#define BV_GPMI_DEBUG2_MAIN_STATE__MSM_WAITFE 0x2 +#define BV_GPMI_DEBUG2_MAIN_STATE__MSM_WAITFR 0x3 +#define BV_GPMI_DEBUG2_MAIN_STATE__MSM_DMAREQ 0x4 +#define BV_GPMI_DEBUG2_MAIN_STATE__MSM_DMAACK 0x5 +#define BV_GPMI_DEBUG2_MAIN_STATE__MSM_WAITFF 0x6 +#define BV_GPMI_DEBUG2_MAIN_STATE__MSM_LDFIFO 0x7 +#define BV_GPMI_DEBUG2_MAIN_STATE__MSM_LDDMAR 0x8 +#define BV_GPMI_DEBUG2_MAIN_STATE__MSM_RDCMP 0x9 +#define BV_GPMI_DEBUG2_MAIN_STATE__MSM_DONE 0xA +#define BP_GPMI_DEBUG2_SYND2GPMI_BE 12 +#define BM_GPMI_DEBUG2_SYND2GPMI_BE 0x0000F000 +#define BF_GPMI_DEBUG2_SYND2GPMI_BE(v) \ + (((v) << 12) & BM_GPMI_DEBUG2_SYND2GPMI_BE) +#define BM_GPMI_DEBUG2_GPMI2SYND_VALID 0x00000800 +#define BM_GPMI_DEBUG2_GPMI2SYND_READY 0x00000400 +#define BM_GPMI_DEBUG2_SYND2GPMI_VALID 0x00000200 +#define BM_GPMI_DEBUG2_SYND2GPMI_READY 0x00000100 +#define BM_GPMI_DEBUG2_VIEW_DELAYED_RDN 0x00000080 +#define BM_GPMI_DEBUG2_UPDATE_WINDOW 0x00000040 +#define BP_GPMI_DEBUG2_RDN_TAP 0 +#define BM_GPMI_DEBUG2_RDN_TAP 0x0000003F +#define BF_GPMI_DEBUG2_RDN_TAP(v) \ + (((v) << 0) & BM_GPMI_DEBUG2_RDN_TAP) + +#define HW_GPMI_DEBUG3 (0x000000f0) + +#define BP_GPMI_DEBUG3_APB_WORD_CNTR 16 +#define BM_GPMI_DEBUG3_APB_WORD_CNTR 0xFFFF0000 +#define BF_GPMI_DEBUG3_APB_WORD_CNTR(v) \ + (((v) << 16) & BM_GPMI_DEBUG3_APB_WORD_CNTR) +#define BP_GPMI_DEBUG3_DEV_WORD_CNTR 0 +#define BM_GPMI_DEBUG3_DEV_WORD_CNTR 0x0000FFFF +#define BF_GPMI_DEBUG3_DEV_WORD_CNTR(v) \ + (((v) << 0) & BM_GPMI_DEBUG3_DEV_WORD_CNTR) + +#define HW_GPMI_READ_DDR_DLL_CTRL (0x00000100) + +#define BP_GPMI_READ_DDR_DLL_CTRL_REF_UPDATE_INT 28 +#define BM_GPMI_READ_DDR_DLL_CTRL_REF_UPDATE_INT 0xF0000000 +#define BF_GPMI_READ_DDR_DLL_CTRL_REF_UPDATE_INT(v) \ + (((v) << 28) & BM_GPMI_READ_DDR_DLL_CTRL_REF_UPDATE_INT) +#define BP_GPMI_READ_DDR_DLL_CTRL_SLV_UPDATE_INT 20 +#define BM_GPMI_READ_DDR_DLL_CTRL_SLV_UPDATE_INT 0x0FF00000 +#define BF_GPMI_READ_DDR_DLL_CTRL_SLV_UPDATE_INT(v) \ + (((v) << 20) & BM_GPMI_READ_DDR_DLL_CTRL_SLV_UPDATE_INT) +#define BP_GPMI_READ_DDR_DLL_CTRL_RSVD1 18 +#define BM_GPMI_READ_DDR_DLL_CTRL_RSVD1 0x000C0000 +#define BF_GPMI_READ_DDR_DLL_CTRL_RSVD1(v) \ + (((v) << 18) & BM_GPMI_READ_DDR_DLL_CTRL_RSVD1) +#define BP_GPMI_READ_DDR_DLL_CTRL_SLV_OVERRIDE_VAL 10 +#define BM_GPMI_READ_DDR_DLL_CTRL_SLV_OVERRIDE_VAL 0x0003FC00 +#define BF_GPMI_READ_DDR_DLL_CTRL_SLV_OVERRIDE_VAL(v) \ + (((v) << 10) & BM_GPMI_READ_DDR_DLL_CTRL_SLV_OVERRIDE_VAL) +#define BM_GPMI_READ_DDR_DLL_CTRL_SLV_OVERRIDE 0x00000200 +#define BM_GPMI_READ_DDR_DLL_CTRL_REFCLK_ON 0x00000100 +#define BM_GPMI_READ_DDR_DLL_CTRL_GATE_UPDATE 0x00000080 +#define BP_GPMI_READ_DDR_DLL_CTRL_SLV_DLY_TARGET 3 +#define BM_GPMI_READ_DDR_DLL_CTRL_SLV_DLY_TARGET 0x00000078 +#define BF_GPMI_READ_DDR_DLL_CTRL_SLV_DLY_TARGET(v) \ + (((v) << 3) & BM_GPMI_READ_DDR_DLL_CTRL_SLV_DLY_TARGET) +#define BM_GPMI_READ_DDR_DLL_CTRL_SLV_FORCE_UPD 0x00000004 +#define BM_GPMI_READ_DDR_DLL_CTRL_RESET 0x00000002 +#define BM_GPMI_READ_DDR_DLL_CTRL_ENABLE 0x00000001 + +#define HW_GPMI_WRITE_DDR_DLL_CTRL (0x00000110) + +#define BP_GPMI_WRITE_DDR_DLL_CTRL_REF_UPDATE_INT 28 +#define BM_GPMI_WRITE_DDR_DLL_CTRL_REF_UPDATE_INT 0xF0000000 +#define BF_GPMI_WRITE_DDR_DLL_CTRL_REF_UPDATE_INT(v) \ + (((v) << 28) & BM_GPMI_WRITE_DDR_DLL_CTRL_REF_UPDATE_INT) +#define BP_GPMI_WRITE_DDR_DLL_CTRL_SLV_UPDATE_INT 20 +#define BM_GPMI_WRITE_DDR_DLL_CTRL_SLV_UPDATE_INT 0x0FF00000 +#define BF_GPMI_WRITE_DDR_DLL_CTRL_SLV_UPDATE_INT(v) \ + (((v) << 20) & BM_GPMI_WRITE_DDR_DLL_CTRL_SLV_UPDATE_INT) +#define BP_GPMI_WRITE_DDR_DLL_CTRL_RSVD1 18 +#define BM_GPMI_WRITE_DDR_DLL_CTRL_RSVD1 0x000C0000 +#define BF_GPMI_WRITE_DDR_DLL_CTRL_RSVD1(v) \ + (((v) << 18) & BM_GPMI_WRITE_DDR_DLL_CTRL_RSVD1) +#define BP_GPMI_WRITE_DDR_DLL_CTRL_SLV_OVERRIDE_VAL 10 +#define BM_GPMI_WRITE_DDR_DLL_CTRL_SLV_OVERRIDE_VAL 0x0003FC00 +#define BF_GPMI_WRITE_DDR_DLL_CTRL_SLV_OVERRIDE_VAL(v) \ + (((v) << 10) & BM_GPMI_WRITE_DDR_DLL_CTRL_SLV_OVERRIDE_VAL) +#define BM_GPMI_WRITE_DDR_DLL_CTRL_SLV_OVERRIDE 0x00000200 +#define BM_GPMI_WRITE_DDR_DLL_CTRL_REFCLK_ON 0x00000100 +#define BM_GPMI_WRITE_DDR_DLL_CTRL_GATE_UPDATE 0x00000080 +#define BP_GPMI_WRITE_DDR_DLL_CTRL_SLV_DLY_TARGET 3 +#define BM_GPMI_WRITE_DDR_DLL_CTRL_SLV_DLY_TARGET 0x00000078 +#define BF_GPMI_WRITE_DDR_DLL_CTRL_SLV_DLY_TARGET(v) \ + (((v) << 3) & BM_GPMI_WRITE_DDR_DLL_CTRL_SLV_DLY_TARGET) +#define BM_GPMI_WRITE_DDR_DLL_CTRL_SLV_FORCE_UPD 0x00000004 +#define BM_GPMI_WRITE_DDR_DLL_CTRL_RESET 0x00000002 +#define BM_GPMI_WRITE_DDR_DLL_CTRL_ENABLE 0x00000001 + +#define HW_GPMI_READ_DDR_DLL_STS (0x00000120) + +#define BP_GPMI_READ_DDR_DLL_STS_RSVD1 25 +#define BM_GPMI_READ_DDR_DLL_STS_RSVD1 0xFE000000 +#define BF_GPMI_READ_DDR_DLL_STS_RSVD1(v) \ + (((v) << 25) & BM_GPMI_READ_DDR_DLL_STS_RSVD1) +#define BP_GPMI_READ_DDR_DLL_STS_REF_SEL 17 +#define BM_GPMI_READ_DDR_DLL_STS_REF_SEL 0x01FE0000 +#define BF_GPMI_READ_DDR_DLL_STS_REF_SEL(v) \ + (((v) << 17) & BM_GPMI_READ_DDR_DLL_STS_REF_SEL) +#define BM_GPMI_READ_DDR_DLL_STS_REF_LOCK 0x00010000 +#define BP_GPMI_READ_DDR_DLL_STS_RSVD0 9 +#define BM_GPMI_READ_DDR_DLL_STS_RSVD0 0x0000FE00 +#define BF_GPMI_READ_DDR_DLL_STS_RSVD0(v) \ + (((v) << 9) & BM_GPMI_READ_DDR_DLL_STS_RSVD0) +#define BP_GPMI_READ_DDR_DLL_STS_SLV_SEL 1 +#define BM_GPMI_READ_DDR_DLL_STS_SLV_SEL 0x000001FE +#define BF_GPMI_READ_DDR_DLL_STS_SLV_SEL(v) \ + (((v) << 1) & BM_GPMI_READ_DDR_DLL_STS_SLV_SEL) +#define BM_GPMI_READ_DDR_DLL_STS_SLV_LOCK 0x00000001 + +#define HW_GPMI_WRITE_DDR_DLL_STS (0x00000130) + +#define BP_GPMI_WRITE_DDR_DLL_STS_RSVD1 25 +#define BM_GPMI_WRITE_DDR_DLL_STS_RSVD1 0xFE000000 +#define BF_GPMI_WRITE_DDR_DLL_STS_RSVD1(v) \ + (((v) << 25) & BM_GPMI_WRITE_DDR_DLL_STS_RSVD1) +#define BP_GPMI_WRITE_DDR_DLL_STS_REF_SEL 17 +#define BM_GPMI_WRITE_DDR_DLL_STS_REF_SEL 0x01FE0000 +#define BF_GPMI_WRITE_DDR_DLL_STS_REF_SEL(v) \ + (((v) << 17) & BM_GPMI_WRITE_DDR_DLL_STS_REF_SEL) +#define BM_GPMI_WRITE_DDR_DLL_STS_REF_LOCK 0x00010000 +#define BP_GPMI_WRITE_DDR_DLL_STS_RSVD0 9 +#define BM_GPMI_WRITE_DDR_DLL_STS_RSVD0 0x0000FE00 +#define BF_GPMI_WRITE_DDR_DLL_STS_RSVD0(v) \ + (((v) << 9) & BM_GPMI_WRITE_DDR_DLL_STS_RSVD0) +#define BP_GPMI_WRITE_DDR_DLL_STS_SLV_SEL 1 +#define BM_GPMI_WRITE_DDR_DLL_STS_SLV_SEL 0x000001FE +#define BF_GPMI_WRITE_DDR_DLL_STS_SLV_SEL(v) \ + (((v) << 1) & BM_GPMI_WRITE_DDR_DLL_STS_SLV_SEL) +#define BM_GPMI_WRITE_DDR_DLL_STS_SLV_LOCK 0x00000001 +#endif /* __ARCH_ARM___GPMI_H */ diff --git a/drivers/mtd/nand/gpmi-nfc/hal-mx50.c b/drivers/mtd/nand/gpmi-nfc/hal-mx50.c new file mode 100644 index 000000000000..4230e8b59a2c --- /dev/null +++ b/drivers/mtd/nand/gpmi-nfc/hal-mx50.c @@ -0,0 +1,875 @@ +/* + * Freescale GPMI NFC NAND Flash Driver + * + * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. + * Copyright (C) 2008 Embedded Alley Solutions, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#include "gpmi-nfc.h" +#include "gpmi-regs-mx50.h" +#include "bch-regs-mx50.h" + +#define FEATURE_SIZE 4 /* p1, p2, p3, p4 */ +#define NAND_CMD_SET_FEATURE 0xef + +/* + * How many clocks do we need in low power mode? + * We try to list them : + * GMPI : gpmi_apb_clk, gpmi_io_clk + * BCH : bch_clk, bch_apb_clk + * DMA(RAM) : apbh_dma_clk, ddr_clk(RAM), ahb_max_clk(RAM) + * (APBHDMA fetches DMA descriptors from DDR + * through AHB-MAX/PL301) + * NAND : + * ONFI NAND : pll1_main_clk + */ +static struct clk *ddr_clk; +static struct clk *ahb_max_clk; + +static void setup_ddr_timing_onfi(struct gpmi_nfc_data *this) +{ + uint32_t value; + struct resources *resources = &this->resources; + + /* set timing 2 register */ + value = BF_GPMI_TIMING2_DATA_PAUSE(0x6) + | BF_GPMI_TIMING2_CMDADD_PAUSE(0x4) + | BF_GPMI_TIMING2_POSTAMBLE_DELAY(0x2) + | BF_GPMI_TIMING2_PREAMBLE_DELAY(0x4) + | BF_GPMI_TIMING2_CE_DELAY(0x2) + | BF_GPMI_TIMING2_READ_LATENCY(0x2); + + __raw_writel(value, resources->gpmi_regs + HW_GPMI_TIMING2); + + /* set timing 1 register */ + __raw_writel(BF_GPMI_TIMING1_DEVICE_BUSY_TIMEOUT(0x500), + resources->gpmi_regs + HW_GPMI_TIMING1); + + /* Put GPMI in NAND mode, disable device reset, and make certain + IRQRDY polarity is active high. */ + value = BV_GPMI_CTRL1_GPMI_MODE__NAND + | BM_GPMI_CTRL1_GANGED_RDYBUSY + | BF_GPMI_CTRL1_WRN_DLY_SEL(0x3) + | (BV_GPMI_CTRL1_DEV_RESET__DISABLED << 3) + | (BV_GPMI_CTRL1_ATA_IRQRDY_POLARITY__ACTIVEHIGH << 2); + + __raw_writel(value, resources->gpmi_regs + HW_GPMI_CTRL1_SET); +} + +/* This must be called in the context of enabling necessary clocks */ +static void common_ddr_init(struct resources *resources) +{ + uint32_t value; + + /* [6] enable both write & read DDR DLLs */ + value = BM_GPMI_READ_DDR_DLL_CTRL_REFCLK_ON | + BM_GPMI_READ_DDR_DLL_CTRL_ENABLE | + BF_GPMI_READ_DDR_DLL_CTRL_SLV_UPDATE_INT(0x2) | + BF_GPMI_READ_DDR_DLL_CTRL_SLV_DLY_TARGET(0x7); + + __raw_writel(value, resources->gpmi_regs + HW_GPMI_READ_DDR_DLL_CTRL); + + /* [7] reset read */ + __raw_writel(value | BM_GPMI_READ_DDR_DLL_CTRL_RESET, + resources->gpmi_regs + HW_GPMI_READ_DDR_DLL_CTRL); + value = value & ~BM_GPMI_READ_DDR_DLL_CTRL_RESET; + __raw_writel(value, resources->gpmi_regs + HW_GPMI_READ_DDR_DLL_CTRL); + + value = BM_GPMI_WRITE_DDR_DLL_CTRL_REFCLK_ON | + BM_GPMI_WRITE_DDR_DLL_CTRL_ENABLE | + BF_GPMI_WRITE_DDR_DLL_CTRL_SLV_UPDATE_INT(0x2) | + BF_GPMI_WRITE_DDR_DLL_CTRL_SLV_DLY_TARGET(0x7) , + + __raw_writel(value, resources->gpmi_regs + HW_GPMI_WRITE_DDR_DLL_CTRL); + + /* [8] reset write */ + __raw_writel(value | BM_GPMI_WRITE_DDR_DLL_CTRL_RESET, + resources->gpmi_regs + HW_GPMI_WRITE_DDR_DLL_CTRL); + __raw_writel(value, resources->gpmi_regs + HW_GPMI_WRITE_DDR_DLL_CTRL); + + /* [9] wait for locks for read and write */ + do { + uint32_t read_status, write_status; + uint32_t r_mask, w_mask; + + read_status = __raw_readl(resources->gpmi_regs + + HW_GPMI_READ_DDR_DLL_STS); + write_status = __raw_readl(resources->gpmi_regs + + HW_GPMI_WRITE_DDR_DLL_STS); + + r_mask = (BM_GPMI_READ_DDR_DLL_STS_REF_LOCK | + BM_GPMI_READ_DDR_DLL_STS_SLV_LOCK); + w_mask = (BM_GPMI_WRITE_DDR_DLL_STS_REF_LOCK | + BM_GPMI_WRITE_DDR_DLL_STS_SLV_LOCK); + + if (((read_status & r_mask) == r_mask) + && ((write_status & w_mask) == w_mask)) + break; + } while (1); + + /* [10] force update of read/write */ + value = __raw_readl(resources->gpmi_regs + HW_GPMI_READ_DDR_DLL_CTRL); + __raw_writel(value | BM_GPMI_READ_DDR_DLL_CTRL_SLV_FORCE_UPD, + resources->gpmi_regs + HW_GPMI_READ_DDR_DLL_CTRL); + __raw_writel(value, resources->gpmi_regs + HW_GPMI_READ_DDR_DLL_CTRL); + + value = __raw_readl(resources->gpmi_regs + HW_GPMI_WRITE_DDR_DLL_CTRL); + __raw_writel(value | BM_GPMI_WRITE_DDR_DLL_CTRL_SLV_FORCE_UPD, + resources->gpmi_regs + HW_GPMI_WRITE_DDR_DLL_CTRL); + __raw_writel(value, resources->gpmi_regs + HW_GPMI_WRITE_DDR_DLL_CTRL); + + /* [11] set gate update */ + value = __raw_readl(resources->gpmi_regs + HW_GPMI_READ_DDR_DLL_CTRL); + value |= BM_GPMI_READ_DDR_DLL_CTRL_GATE_UPDATE; + __raw_writel(value, resources->gpmi_regs + HW_GPMI_READ_DDR_DLL_CTRL); + + value = __raw_readl(resources->gpmi_regs + HW_GPMI_WRITE_DDR_DLL_CTRL); + value |= BM_GPMI_WRITE_DDR_DLL_CTRL_GATE_UPDATE; + __raw_writel(value, resources->gpmi_regs + HW_GPMI_WRITE_DDR_DLL_CTRL); +} + +static int enable_ddr_onfi(struct gpmi_nfc_data *this) +{ + struct resources *resources = &this->resources; + struct mil *mil = &this->mil; + struct nand_chip *nand = &this->mil.nand; + struct mtd_info *mtd = &mil->mtd; + int saved_chip_number = 0; + uint8_t device_feature[FEATURE_SIZE]; + int mode = 0;/* there is 5 mode available, default is 0 */ + + saved_chip_number = mil->current_chip; + nand->select_chip(mtd, 0); + + /* [0] set proper timing */ + __raw_writel(BF_GPMI_TIMING0_ADDRESS_SETUP(0x1) + | BF_GPMI_TIMING0_DATA_HOLD(0x3) + | BF_GPMI_TIMING0_DATA_SETUP(0x3), + resources->gpmi_regs + HW_GPMI_TIMING0); + + /* [1] send SET FEATURE commond to NAND */ + memset(device_feature, 0, sizeof(device_feature)); + device_feature[0] = (0x1 << 4) | (mode & 0x7); + + nand->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); + nand->cmdfunc(mtd, NAND_CMD_SET_FEATURE, 1, -1); + nand->write_buf(mtd, device_feature, FEATURE_SIZE); + + /* [2] set clk divider */ + __raw_writel(BM_GPMI_CTRL1_GPMI_CLK_DIV2_EN, + resources->gpmi_regs + HW_GPMI_CTRL1_SET); + + /* [3] about the clock, pay attention! */ + nand->select_chip(mtd, saved_chip_number); + { + struct clk *pll1; + pll1 = clk_get(NULL, "pll1_main_clk"); + if (IS_ERR(pll1)) { + printk(KERN_INFO "No PLL1 clock\n"); + return -EINVAL; + } + clk_set_parent(resources->clock, pll1); + clk_set_rate(resources->clock, 20000000); + } + nand->select_chip(mtd, 0); + + /* [4] setup timing */ + setup_ddr_timing_onfi(this); + + /* [5] set to SYNC mode */ + __raw_writel(BM_GPMI_CTRL1_TOGGLE_MODE, + resources->gpmi_regs + HW_GPMI_CTRL1_CLR); + __raw_writel(BM_GPMI_CTRL1_SSYNCMODE | BM_GPMI_CTRL1_GANGED_RDYBUSY, + resources->gpmi_regs + HW_GPMI_CTRL1_SET); + + /* common DDR initialization */ + common_ddr_init(resources); + + nand->select_chip(mtd, saved_chip_number); + + printk(KERN_INFO "Micron ONFI NAND enters synchronous mode %d\n", mode); + return 0; +} + +static void setup_ddr_timing_toggle(struct gpmi_nfc_data *this) +{ + uint32_t value; + struct resources *resources = &this->resources; + + /* set timing 2 register */ + value = BF_GPMI_TIMING2_DATA_PAUSE(0x6) + | BF_GPMI_TIMING2_CMDADD_PAUSE(0x4) + | BF_GPMI_TIMING2_POSTAMBLE_DELAY(0x3) + | BF_GPMI_TIMING2_PREAMBLE_DELAY(0x2) + | BF_GPMI_TIMING2_CE_DELAY(0x2) + | BF_GPMI_TIMING2_READ_LATENCY(0x2); + + __raw_writel(value, resources->gpmi_regs + HW_GPMI_TIMING2); + + /* set timing 1 register */ + __raw_writel(BF_GPMI_TIMING1_DEVICE_BUSY_TIMEOUT(0x500), + resources->gpmi_regs + HW_GPMI_TIMING1); + + /* Put GPMI in NAND mode, disable device reset, and make certain + IRQRDY polarity is active high. */ + value = BV_GPMI_CTRL1_GPMI_MODE__NAND + | BM_GPMI_CTRL1_GANGED_RDYBUSY + | (BV_GPMI_CTRL1_DEV_RESET__DISABLED << 3) + | (BV_GPMI_CTRL1_ATA_IRQRDY_POLARITY__ACTIVEHIGH << 2); + + __raw_writel(value, resources->gpmi_regs + HW_GPMI_CTRL1_SET); +} + +static int enable_ddr_toggle(struct gpmi_nfc_data *this) +{ + struct resources *resources = &this->resources; + struct mil *mil = &this->mil; + struct nand_chip *nand = &this->mil.nand; + struct mtd_info *mtd = &mil->mtd; + int saved_chip_number = mil->current_chip; + + nand->select_chip(mtd, 0); + + /* [0] set proper timing */ + __raw_writel(BF_GPMI_TIMING0_ADDRESS_SETUP(0x5) + | BF_GPMI_TIMING0_DATA_HOLD(0xa) + | BF_GPMI_TIMING0_DATA_SETUP(0xa), + resources->gpmi_regs + HW_GPMI_TIMING0); + + /* [2] set clk divider */ + __raw_writel(BM_GPMI_CTRL1_GPMI_CLK_DIV2_EN, + resources->gpmi_regs + HW_GPMI_CTRL1_SET); + + /* [3] about the clock, pay attention! */ + nand->select_chip(mtd, saved_chip_number); + { + struct clk *pll1; + unsigned long rate; + + pll1 = clk_get(NULL, "pll1_main_clk"); + if (IS_ERR(pll1)) { + printk(KERN_INFO "No PLL1 clock\n"); + return -EINVAL; + } + + /* toggle nand : 133/66 MHz */ + rate = 33000000; + clk_set_parent(resources->clock, pll1); + clk_set_rate(resources->clock, rate); + } + nand->select_chip(mtd, 0); + + /* [4] setup timing */ + setup_ddr_timing_toggle(this); + + /* [5] set to TOGGLE mode */ + __raw_writel(BM_GPMI_CTRL1_SSYNCMODE, + resources->gpmi_regs + HW_GPMI_CTRL1_CLR); + __raw_writel(BM_GPMI_CTRL1_TOGGLE_MODE | BM_GPMI_CTRL1_GANGED_RDYBUSY, + resources->gpmi_regs + HW_GPMI_CTRL1_SET); + + /* common DDR initialization */ + common_ddr_init(resources); + + nand->select_chip(mtd, saved_chip_number); + + printk(KERN_INFO "-- Sumsung TOGGLE NAND is enabled now. --\n"); + return 0; +} + +static inline bool is_board_support_ddr(struct gpmi_nfc_data *this) +{ + /* Only arm2 board supports the DDR, the rdp board does not. */ + return false; +} + +/* To check if we need to initialize something else*/ +static int extra_init(struct gpmi_nfc_data *this) +{ + ddr_clk = clk_get(NULL, "ddr_clk"); + if (IS_ERR(ddr_clk)) { + printk(KERN_ERR "The ddr clock is gone!"); + ddr_clk = NULL; + return -ENOENT; + } + + ahb_max_clk = clk_get(NULL, "ahb_max_clk"); + if (IS_ERR(ahb_max_clk)) { + printk(KERN_ERR "The APBH_DMA clock is gone!"); + ahb_max_clk = NULL; + return -ENOENT; + } + + if (is_board_support_ddr(this)) { + if (0) + return enable_ddr_onfi(this); + if (0) + return enable_ddr_toggle(this); + } + return 0; +} + +/** + * init() - Initializes the NFC hardware. + * + * @this: Per-device data. + */ +static int init(struct gpmi_nfc_data *this) +{ + struct resources *resources = &this->resources; + + /* Enable the clock. */ + clk_enable(resources->clock); + + /* Reset the GPMI block. */ + mxs_reset_block(resources->gpmi_regs + HW_GPMI_CTRL0, true); + + /* Choose NAND mode. */ + __raw_writel(BM_GPMI_CTRL1_GPMI_MODE, + resources->gpmi_regs + HW_GPMI_CTRL1_CLR); + + /* Set the IRQ polarity. */ + __raw_writel(BM_GPMI_CTRL1_ATA_IRQRDY_POLARITY, + resources->gpmi_regs + HW_GPMI_CTRL1_SET); + + /* Disable write protection. */ + __raw_writel(BM_GPMI_CTRL1_DEV_RESET, + resources->gpmi_regs + HW_GPMI_CTRL1_SET); + + /* Select BCH ECC. */ + __raw_writel(BM_GPMI_CTRL1_BCH_MODE, + resources->gpmi_regs + HW_GPMI_CTRL1_SET); + + /* Disable the clock. */ + clk_disable(resources->clock); + + return 0; +} + +/** + * set_geometry() - Configures the NFC geometry. + * + * @this: Per-device data. + */ +static int set_geometry(struct gpmi_nfc_data *this) +{ + struct resources *resources = &this->resources; + struct nfc_geometry *nfc = &this->nfc_geometry; + unsigned int block_count; + unsigned int block_size; + unsigned int metadata_size; + unsigned int ecc_strength; + unsigned int page_size; + uint32_t value; + + /* We make the abstract choices in a common function. */ + if (common_nfc_set_geometry(this)) + return !0; + + /* Translate the abstract choices into register fields. */ + block_count = nfc->ecc_chunk_count - 1; + block_size = nfc->ecc_chunk_size_in_bytes >> 2; + metadata_size = nfc->metadata_size_in_bytes; + ecc_strength = nfc->ecc_strength >> 1; + page_size = nfc->page_size_in_bytes; + + /* Enable the clock. */ + clk_enable(resources->clock); + + /* + * Reset the BCH block. Notice that we pass in true for the just_enable + * flag. This is because the soft reset for the version 0 BCH block + * doesn't work and the version 1 BCH block is similar enough that we + * suspect the same (though this has not been officially tested). If you + * try to soft reset a version 0 BCH block, it becomes unusable until + * the next hard reset. + */ + mxs_reset_block(resources->bch_regs, false); + + /* Configure layout 0. */ + value = BF_BCH_FLASH0LAYOUT0_NBLOCKS(block_count) | + BF_BCH_FLASH0LAYOUT0_META_SIZE(metadata_size) | + BF_BCH_FLASH0LAYOUT0_ECC0(ecc_strength) | + BF_BCH_FLASH0LAYOUT0_DATA0_SIZE(block_size); + if (is_ddr_nand(this)) + value |= BM_BCH_FLASH0LAYOUT0_GF13_0_GF14_1; + + __raw_writel(value, resources->bch_regs + HW_BCH_FLASH0LAYOUT0); + + value = BF_BCH_FLASH0LAYOUT1_PAGE_SIZE(page_size) | + BF_BCH_FLASH0LAYOUT1_ECCN(ecc_strength) | + BF_BCH_FLASH0LAYOUT1_DATAN_SIZE(block_size); + if (is_ddr_nand(this)) + value |= BM_BCH_FLASH0LAYOUT1_GF13_0_GF14_1; + + __raw_writel(value, resources->bch_regs + HW_BCH_FLASH0LAYOUT1); + + /* Set *all* chip selects to use layout 0. */ + __raw_writel(0, resources->bch_regs + HW_BCH_LAYOUTSELECT); + + /* Enable interrupts. */ + __raw_writel(BM_BCH_CTRL_COMPLETE_IRQ_EN, + resources->bch_regs + HW_BCH_CTRL_SET); + + /* Disable the clock. */ + clk_disable(resources->clock); + + return 0; +} + +/** + * set_timing() - Configures the NFC timing. + * + * @this: Per-device data. + * @timing: The timing of interest. + */ +static int set_timing(struct gpmi_nfc_data *this, + const struct nand_timing *timing) +{ + struct nfc_hal *nfc = this->nfc; + + /* Accept the new timing. */ + nfc->timing = *timing; + return 0; +} + +/** + * get_timing() - Retrieves the NFC hardware timing. + * + * @this: Per-device data. + * @clock_frequency_in_hz: The clock frequency, in Hz, during the current + * I/O transaction. If no I/O transaction is in + * progress, this is the clock frequency during the + * most recent I/O transaction. + * @hardware_timing: The hardware timing configuration in effect during + * the current I/O transaction. If no I/O transaction + * is in progress, this is the hardware timing + * configuration during the most recent I/O + * transaction. + */ +static void get_timing(struct gpmi_nfc_data *this, + unsigned long *clock_frequency_in_hz, + struct gpmi_nfc_hardware_timing *hardware_timing) +{ + struct resources *resources = &this->resources; + struct nfc_hal *nfc = this->nfc; + unsigned char *gpmi_regs = resources->gpmi_regs; + uint32_t register_image; + + /* Return the clock frequency. */ + *clock_frequency_in_hz = nfc->clock_frequency_in_hz; + + /* We'll be reading the hardware, so let's enable the clock. */ + clk_enable(resources->clock); + + /* Retrieve the hardware timing. */ + register_image = __raw_readl(gpmi_regs + HW_GPMI_TIMING0); + + hardware_timing->data_setup_in_cycles = + (register_image & BM_GPMI_TIMING0_DATA_SETUP) >> + BP_GPMI_TIMING0_DATA_SETUP; + + hardware_timing->data_hold_in_cycles = + (register_image & BM_GPMI_TIMING0_DATA_HOLD) >> + BP_GPMI_TIMING0_DATA_HOLD; + + hardware_timing->address_setup_in_cycles = + (register_image & BM_GPMI_TIMING0_ADDRESS_SETUP) >> + BP_GPMI_TIMING0_ADDRESS_SETUP; + + register_image = __raw_readl(gpmi_regs + HW_GPMI_CTRL1); + + hardware_timing->use_half_periods = + (register_image & BM_GPMI_CTRL1_HALF_PERIOD) >> + BP_GPMI_CTRL1_HALF_PERIOD; + + hardware_timing->sample_delay_factor = + (register_image & BM_GPMI_CTRL1_RDN_DELAY) >> + BP_GPMI_CTRL1_RDN_DELAY; + + /* We're done reading the hardware, so disable the clock. */ + clk_disable(resources->clock); +} + +static void exit(struct gpmi_nfc_data *this) +{ +} + +static void begin(struct gpmi_nfc_data *this) +{ + struct resources *resources = &this->resources; + struct nfc_hal *nfc = this->nfc; + struct gpmi_nfc_hardware_timing hw; + + /* Enable the clock. */ + if (ddr_clk) + clk_enable(ddr_clk); + if (ahb_max_clk) + clk_enable(ahb_max_clk); + clk_enable(resources->clock); + + /* Get the timing information we need. */ + nfc->clock_frequency_in_hz = clk_get_rate(resources->clock); + gpmi_nfc_compute_hardware_timing(this, &hw); + + /* Apply the hardware timing. */ + + /* Coming soon - the clock handling code isn't ready yet. */ + +} + +/** + * end() - End NFC I/O. + * + * @this: Per-device data. + */ +static void end(struct gpmi_nfc_data *this) +{ + struct resources *resources = &this->resources; + + clk_disable(resources->clock); + if (ahb_max_clk) + clk_disable(ahb_max_clk); + if (ddr_clk) + clk_disable(ddr_clk); +} + +/** + * clear_bch() - Clears a BCH interrupt. + * + * @this: Per-device data. + */ +static void clear_bch(struct gpmi_nfc_data *this) +{ + struct resources *resources = &this->resources; + __raw_writel(BM_BCH_CTRL_COMPLETE_IRQ, + resources->bch_regs + HW_BCH_CTRL_CLR); +} + +/** + * is_ready() - Returns the ready/busy status of the given chip. + * + * @this: Per-device data. + * @chip: The chip of interest. + */ +static int is_ready(struct gpmi_nfc_data *this, unsigned chip) +{ + struct resources *resources = &this->resources; + uint32_t mask; + uint32_t register_image; + + /* Extract and return the status. */ + mask = BF_GPMI_STAT_READY_BUSY(1 << 0); + register_image = __raw_readl(resources->gpmi_regs + HW_GPMI_STAT); + return !!(register_image & mask); +} + +/* The DMA may need the NAND-LOCK bit set to work properly. */ +static int send_command(struct gpmi_nfc_data *this) +{ + struct dma_chan *channel = get_dma_chan(this); + struct mil *mil = &this->mil; + struct dma_async_tx_descriptor *desc; + struct scatterlist *sgl; + u32 pio[3]; + + /* [1] send out the PIO words */ + pio[0] = BF_GPMI_CTRL0_COMMAND_MODE(BV_GPMI_CTRL0_COMMAND_MODE__WRITE) + | BM_GPMI_CTRL0_WORD_LENGTH + | BF_GPMI_CTRL0_CS(mil->current_chip) + | BF_GPMI_CTRL0_ADDRESS(BV_GPMI_CTRL0_ADDRESS__NAND_CLE) + | BM_GPMI_CTRL0_ADDRESS_INCREMENT + | BF_GPMI_CTRL0_XFER_COUNT(mil->command_length); + pio[1] = pio[2] = 0; + desc = channel->device->device_prep_slave_sg(channel, + (struct scatterlist *)pio, + ARRAY_SIZE(pio), DMA_NONE, 0); + if (!desc) { + pr_info("step 1 error"); + return -1; + } + + /* [2] send out the COMMAND + ADDRESS string stored in @buffer */ + sgl = &mil->cmd_sgl; + + sg_init_one(sgl, mil->cmd_buffer, mil->command_length); + dma_map_sg(this->dev, sgl, 1, DMA_TO_DEVICE); + desc = channel->device->device_prep_slave_sg(channel, + sgl, 1, DMA_TO_DEVICE, 1); + if (!desc) { + pr_info("error"); + return -1; + } + + /* [3] submit the DMA */ + this->dma_type = DMA_FOR_COMMAND; + start_dma_without_bch_irq(this, desc); + return 0; +} + +static int send_data(struct gpmi_nfc_data *this) +{ + struct dma_async_tx_descriptor *desc; + struct dma_chan *channel = get_dma_chan(this); + struct mil *mil = &this->mil; + uint32_t command_mode; + uint32_t address; + u32 pio[2]; + + /* [1] PIO */ + command_mode = BV_GPMI_CTRL0_COMMAND_MODE__WRITE; + address = BV_GPMI_CTRL0_ADDRESS__NAND_DATA; + + pio[0] = BF_GPMI_CTRL0_COMMAND_MODE(command_mode) + | BM_GPMI_CTRL0_WORD_LENGTH + | BF_GPMI_CTRL0_CS(mil->current_chip) + | BF_GPMI_CTRL0_ADDRESS(address) + | BF_GPMI_CTRL0_XFER_COUNT(mil->upper_len); + pio[1] = 0; + desc = channel->device->device_prep_slave_sg(channel, + (struct scatterlist *)pio, + ARRAY_SIZE(pio), DMA_NONE, 0); + if (!desc) { + pr_info("step 1 error"); + return -1; + } + + /* [2] send DMA request */ + prepare_data_dma(this, DMA_TO_DEVICE); + desc = channel->device->device_prep_slave_sg(channel, &mil->data_sgl, + 1, DMA_TO_DEVICE, 1); + if (!desc) { + pr_info("step 2 error"); + return -1; + } + /* [3] submit the DMA */ + this->dma_type = DMA_FOR_WRITE_DATA; + start_dma_without_bch_irq(this, desc); + return 0; +} + +static int read_data(struct gpmi_nfc_data *this) +{ + struct dma_async_tx_descriptor *desc; + struct dma_chan *channel = get_dma_chan(this); + struct mil *mil = &this->mil; + u32 pio[2]; + + /* [1] : send PIO */ + pio[0] = BF_GPMI_CTRL0_COMMAND_MODE(BV_GPMI_CTRL0_COMMAND_MODE__READ) + | BM_GPMI_CTRL0_WORD_LENGTH + | BF_GPMI_CTRL0_CS(mil->current_chip) + | BF_GPMI_CTRL0_ADDRESS(BV_GPMI_CTRL0_ADDRESS__NAND_DATA) + | BF_GPMI_CTRL0_XFER_COUNT(mil->upper_len); + pio[1] = 0; + desc = channel->device->device_prep_slave_sg(channel, + (struct scatterlist *)pio, + ARRAY_SIZE(pio), DMA_NONE, 0); + if (!desc) { + pr_info("step 1 error"); + return -1; + } + + /* [2] : send DMA request */ + prepare_data_dma(this, DMA_FROM_DEVICE); + desc = channel->device->device_prep_slave_sg(channel, &mil->data_sgl, + 1, DMA_FROM_DEVICE, 1); + if (!desc) { + pr_info("step 2 error"); + return -1; + } + + /* [3] : submit the DMA */ + this->dma_type = DMA_FOR_READ_DATA; + start_dma_without_bch_irq(this, desc); + return 0; +} + +static int send_page(struct gpmi_nfc_data *this, + dma_addr_t payload, dma_addr_t auxiliary) +{ + struct nfc_geometry *geo = &this->nfc_geometry; + uint32_t command_mode; + uint32_t address; + uint32_t ecc_command; + uint32_t buffer_mask; + uint32_t busw; + uint32_t page_size; + struct dma_async_tx_descriptor *desc; + struct dma_chan *channel = get_dma_chan(this); + struct mil *mil = &this->mil; + int chip = mil->current_chip; + u32 pio[6]; + + /* DDR use the 16-bit for DATA transmission! */ + if (is_board_support_ddr(this) && is_ddr_nand(this)) { + busw = BV_GPMI_CTRL0_WORD_LENGTH__16_BIT; + page_size = geo->page_size_in_bytes >> 1; + } else { + busw = BM_GPMI_CTRL0_WORD_LENGTH; + page_size = geo->page_size_in_bytes; + } + + /* A DMA descriptor that does an ECC page read. */ + command_mode = BV_GPMI_CTRL0_COMMAND_MODE__WRITE; + address = BV_GPMI_CTRL0_ADDRESS__NAND_DATA; + ecc_command = BV_GPMI_ECCCTRL_ECC_CMD__BCH_ENCODE; + buffer_mask = BV_GPMI_ECCCTRL_BUFFER_MASK__BCH_PAGE | + BV_GPMI_ECCCTRL_BUFFER_MASK__BCH_AUXONLY; + + pio[0] = BF_GPMI_CTRL0_COMMAND_MODE(command_mode) + | busw + | BF_GPMI_CTRL0_CS(chip) + | BF_GPMI_CTRL0_ADDRESS(address) + | BF_GPMI_CTRL0_XFER_COUNT(0); + pio[1] = 0; + pio[2] = BM_GPMI_ECCCTRL_ENABLE_ECC + | BF_GPMI_ECCCTRL_ECC_CMD(ecc_command) + | BF_GPMI_ECCCTRL_BUFFER_MASK(buffer_mask); + pio[3] = page_size; + pio[4] = payload; + pio[5] = auxiliary; + + desc = channel->device->device_prep_slave_sg(channel, + (struct scatterlist *)pio, + ARRAY_SIZE(pio), DMA_NONE, 0); + if (!desc) { + pr_info("step 2 error"); + return -1; + } + this->dma_type = DMA_FOR_WRITE_ECC_PAGE; + return start_dma_with_bch_irq(this, desc); +} + +static int read_page(struct gpmi_nfc_data *this, + dma_addr_t payload, dma_addr_t auxiliary) +{ + struct nfc_geometry *geo = &this->nfc_geometry; + uint32_t command_mode; + uint32_t address; + uint32_t ecc_command; + uint32_t buffer_mask; + uint32_t page_size; + uint32_t busw; + struct dma_async_tx_descriptor *desc; + struct dma_chan *channel = get_dma_chan(this); + struct mil *mil = &this->mil; + int chip = mil->current_chip; + u32 pio[6]; + + /* DDR use the 16-bit for DATA transmission! */ + if (is_board_support_ddr(this) && is_ddr_nand(this)) { + busw = BV_GPMI_CTRL0_WORD_LENGTH__16_BIT; + page_size = geo->page_size_in_bytes >> 1; + } else { + busw = BM_GPMI_CTRL0_WORD_LENGTH; + page_size = geo->page_size_in_bytes; + } + + /* [1] Wait for the chip to report ready. */ + command_mode = BV_GPMI_CTRL0_COMMAND_MODE__WAIT_FOR_READY; + address = BV_GPMI_CTRL0_ADDRESS__NAND_DATA; + + pio[0] = BF_GPMI_CTRL0_COMMAND_MODE(command_mode) + | busw + | BF_GPMI_CTRL0_CS(chip) + | BF_GPMI_CTRL0_ADDRESS(address) + | BF_GPMI_CTRL0_XFER_COUNT(0); + pio[1] = 0; + desc = channel->device->device_prep_slave_sg(channel, + (struct scatterlist *)pio, 2, DMA_NONE, 0); + if (!desc) { + pr_info("step 1 error"); + return -1; + } + + /* [2] Enable the BCH block and read. */ + command_mode = BV_GPMI_CTRL0_COMMAND_MODE__READ; + address = BV_GPMI_CTRL0_ADDRESS__NAND_DATA; + ecc_command = BV_GPMI_ECCCTRL_ECC_CMD__BCH_DECODE; + buffer_mask = BV_GPMI_ECCCTRL_BUFFER_MASK__BCH_PAGE + | BV_GPMI_ECCCTRL_BUFFER_MASK__BCH_AUXONLY; + + pio[0] = BF_GPMI_CTRL0_COMMAND_MODE(command_mode) + | busw + | BF_GPMI_CTRL0_CS(chip) + | BF_GPMI_CTRL0_ADDRESS(address) + | BF_GPMI_CTRL0_XFER_COUNT(page_size); + + pio[1] = 0; + pio[2] = BM_GPMI_ECCCTRL_ENABLE_ECC + | BF_GPMI_ECCCTRL_ECC_CMD(ecc_command) + | BF_GPMI_ECCCTRL_BUFFER_MASK(buffer_mask); + pio[3] = page_size; + pio[4] = payload; + pio[5] = auxiliary; + desc = channel->device->device_prep_slave_sg(channel, + (struct scatterlist *)pio, + ARRAY_SIZE(pio), DMA_NONE, 1); + if (!desc) { + pr_info("step 2 error"); + return -1; + } + + /* [3] Disable the BCH block */ + command_mode = BV_GPMI_CTRL0_COMMAND_MODE__WAIT_FOR_READY; + address = BV_GPMI_CTRL0_ADDRESS__NAND_DATA; + + pio[0] = BF_GPMI_CTRL0_COMMAND_MODE(command_mode) + | busw + | BF_GPMI_CTRL0_CS(chip) + | BF_GPMI_CTRL0_ADDRESS(address) + | BF_GPMI_CTRL0_XFER_COUNT(page_size); + pio[1] = 0; + desc = channel->device->device_prep_slave_sg(channel, + (struct scatterlist *)pio, 2, DMA_NONE, 1); + if (!desc) { + pr_info("step 3 error"); + return -1; + } + + /* [4] submit the DMA */ + this->dma_type = DMA_FOR_READ_ECC_PAGE; + return start_dma_with_bch_irq(this, desc); +} + +/* This structure represents the NFC HAL for this version of the hardware. */ +struct nfc_hal gpmi_nfc_hal_mx50 = { + .description = "8-chip GPMI and BCH", + .max_chip_count = 8, + .max_data_setup_cycles = (BM_GPMI_TIMING0_DATA_SETUP >> + BP_GPMI_TIMING0_DATA_SETUP), + .internal_data_setup_in_ns = 0, + .max_sample_delay_factor = (BM_GPMI_CTRL1_RDN_DELAY >> + BP_GPMI_CTRL1_RDN_DELAY), + .max_dll_clock_period_in_ns = 32, + .max_dll_delay_in_ns = 16, + .init = init, + .extra_init = extra_init, + .set_geometry = set_geometry, + .set_timing = set_timing, + .get_timing = get_timing, + .exit = exit, + .begin = begin, + .end = end, + .clear_bch = clear_bch, + .is_ready = is_ready, + .send_command = send_command, + .send_data = send_data, + .read_data = read_data, + .send_page = send_page, + .read_page = read_page, +}; |