summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2011-02-24 16:42:40 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2011-03-03 16:15:57 +0100
commit5fb8333d34f17d85cd551854951476c22847a5c2 (patch)
tree8f6fbd4c9b9e40bb9470554b3a47a8a3213e8cb4 /drivers
parentfd5a99267f41d51821e67ff1b2743a80d0fd2653 (diff)
downloadbarebox-5fb8333d34f17d85cd551854951476c22847a5c2.tar.gz
barebox-5fb8333d34f17d85cd551854951476c22847a5c2.tar.xz
ARM i.MX: cleanup boot modes
The i.MX Processors support two different boot modes, the internal boot mode and the external boot mode. Traditionally the external NAND boot mode is handled in drivers/mtd/nand and the internal boot mode is handled in arch/arm/mach-imx. This patch consolidates the handling of both boot modes in arch/arm/mach-imx so that the user does not have to look in the mtd kconfig section for booting from NAND. Also, selecting between internal and external boot mode now is a clear choice. The external NAND boot mode has been independent of the mtd nand driver, but as the code was contained in the NAND driver it was not possible to support booting from NAND without a mtd nand driver. This is changed with this patch. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/nand/Kconfig21
-rw-r--r--drivers/mtd/nand/nand_imx.c307
2 files changed, 0 insertions, 328 deletions
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 034bb6fe49..12e1237e37 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -13,27 +13,6 @@ config NAND_IMX
prompt "i.MX NAND driver"
depends on ARCH_IMX21 || ARCH_IMX27 || ARCH_IMX31 || ARCH_IMX35 || ARCH_IMX25 || ARCH_IMX51
-config NAND_IMX_BOOT
- bool
- prompt "Support Starting barebox from NAND"
- depends on NAND_IMX && !ARCH_IMX51
-
-choice
- depends on NAND_IMX_BOOT
- default NAND_IMX_BOOT_512_2K
- prompt "select nand pagesize you want to support booting from"
-
-config NAND_IMX_BOOT_512
- bool "512 byte page size"
-
-config NAND_IMX_BOOT_2K
- bool "2048 byte page size"
-
-config NAND_IMX_BOOT_512_2K
- bool "512 byte and 2048 byte pagesize"
-
-endchoice
-
config NAND_OMAP_GPMC
tristate "NAND Flash Support for GPMC based OMAP platforms"
depends on ((ARCH_OMAP2 || ARCH_OMAP3) && GPMC)
diff --git a/drivers/mtd/nand/nand_imx.c b/drivers/mtd/nand/nand_imx.c
index 9a15ab2c98..ca6e55bd84 100644
--- a/drivers/mtd/nand/nand_imx.c
+++ b/drivers/mtd/nand/nand_imx.c
@@ -30,60 +30,6 @@
#include <asm/io.h>
#include <errno.h>
-#define nfc_is_v21() (cpu_is_mx25() || cpu_is_mx35())
-#define nfc_is_v1() (cpu_is_mx31() || cpu_is_mx27() || cpu_is_mx21())
-#define nfc_is_v3_2() cpu_is_mx51()
-#define nfc_is_v3() nfc_is_v3_2()
-
-#define NFC_V1_ECC_STATUS_RESULT 0x0c
-#define NFC_V1_RSLTMAIN_AREA 0x0e
-#define NFC_V1_RSLTSPARE_AREA 0x10
-
-#define NFC_V2_ECC_STATUS_RESULT1 0x0c
-#define NFC_V2_ECC_STATUS_RESULT2 0x0e
-#define NFC_V2_SPAS 0x10
-
-#define NFC_V1_V2_BUF_SIZE 0x00
-#define NFC_V1_V2_BUF_ADDR 0x04
-#define NFC_V1_V2_FLASH_ADDR 0x06
-#define NFC_V1_V2_FLASH_CMD 0x08
-#define NFC_V1_V2_CONFIG 0x0a
-
-#define NFC_V1_V2_WRPROT 0x12
-#define NFC_V1_UNLOCKSTART_BLKADDR 0x14
-#define NFC_V1_UNLOCKEND_BLKADDR 0x16
-#define NFC_V21_UNLOCKSTART_BLKADDR 0x20
-#define NFC_V21_UNLOCKEND_BLKADDR 0x22
-#define NFC_V1_V2_NF_WRPRST 0x18
-#define NFC_V1_V2_CONFIG1 0x1a
-#define NFC_V1_V2_CONFIG2 0x1c
-
-#define NFC_V2_CONFIG1_ECC_MODE_4 (1 << 0)
-#define NFC_V1_V2_CONFIG1_SP_EN (1 << 2)
-#define NFC_V1_V2_CONFIG1_ECC_EN (1 << 3)
-#define NFC_V1_V2_CONFIG1_INT_MSK (1 << 4)
-#define NFC_V1_V2_CONFIG1_BIG (1 << 5)
-#define NFC_V1_V2_CONFIG1_RST (1 << 6)
-#define NFC_V1_V2_CONFIG1_CE (1 << 7)
-#define NFC_V1_V2_CONFIG1_ONE_CYCLE (1 << 8)
-#define NFC_V2_CONFIG1_PPB(x) (((x) & 0x3) << 9)
-#define NFC_V2_CONFIG1_FP_INT (1 << 11)
-
-#define NFC_V1_V2_CONFIG2_INT (1 << 15)
-
-#define NFC_V2_SPAS_SPARESIZE(spas) ((spas) >> 1)
-
-/*
- * Operation modes for the NFC. Valid for v1, v2 and v3
- * type controllers.
- */
-#define NFC_CMD (1 << 0)
-#define NFC_ADDR (1 << 1)
-#define NFC_INPUT (1 << 2)
-#define NFC_OUTPUT (1 << 3)
-#define NFC_ID (1 << 4)
-#define NFC_STATUS (1 << 5)
-
#define NFC_V3_FLASH_CMD (host->regs_axi + 0x00)
#define NFC_V3_FLASH_ADDR0 (host->regs_axi + 0x04)
@@ -132,12 +78,6 @@
#define NFC_V3_DELAY_LINE (host->regs_ip + 0x34)
-#ifdef CONFIG_NAND_IMX_BOOT
-#define __nand_boot_init __bare_init
-#else
-#define __nand_boot_init
-#endif
-
struct imx_nand_host {
struct mtd_info mtd;
struct nand_chip nand;
@@ -1239,253 +1179,6 @@ static struct driver_d imx_nand_driver = {
.probe = imxnd_probe,
};
-#ifdef CONFIG_NAND_IMX_BOOT
-static void __nand_boot_init noinline imx_nandboot_wait_op_done(void *regs)
-{
- u32 r;
-
- while (1) {
- r = readw(regs + NFC_V1_V2_CONFIG2);
- if (r & NFC_V1_V2_CONFIG2_INT)
- break;
- };
-
- r &= ~NFC_V1_V2_CONFIG2_INT;
-
- writew(r, regs + NFC_V1_V2_CONFIG2);
-}
-
-/*
- * This function issues the specified command to the NAND device and
- * waits for completion.
- *
- * @param cmd command for NAND Flash
- */
-static void __nand_boot_init imx_nandboot_send_cmd(void *regs, u16 cmd)
-{
- writew(cmd, regs + NFC_V1_V2_FLASH_CMD);
- writew(NFC_CMD, regs + NFC_V1_V2_CONFIG2);
-
- imx_nandboot_wait_op_done(regs);
-}
-
-/*
- * This function sends an address (or partial address) to the
- * NAND device. The address is used to select the source/destination for
- * a NAND command.
- *
- * @param addr address to be written to NFC.
- * @param islast True if this is the last address cycle for command
- */
-static void __nand_boot_init noinline imx_nandboot_send_addr(void *regs, u16 addr)
-{
- writew(addr, regs + NFC_V1_V2_FLASH_ADDR);
- writew(NFC_ADDR, regs + NFC_V1_V2_CONFIG2);
-
- /* Wait for operation to complete */
- imx_nandboot_wait_op_done(regs);
-}
-
-static void __nand_boot_init imx_nandboot_nfc_addr(void *regs, u32 offs, int pagesize_2k)
-{
- imx_nandboot_send_addr(regs, offs & 0xff);
-
- if (pagesize_2k) {
- imx_nandboot_send_addr(regs, offs & 0xff);
- imx_nandboot_send_addr(regs, (offs >> 11) & 0xff);
- imx_nandboot_send_addr(regs, (offs >> 19) & 0xff);
- imx_nandboot_send_addr(regs, (offs >> 27) & 0xff);
- imx_nandboot_send_cmd(regs, NAND_CMD_READSTART);
- } else {
- imx_nandboot_send_addr(regs, (offs >> 9) & 0xff);
- imx_nandboot_send_addr(regs, (offs >> 17) & 0xff);
- imx_nandboot_send_addr(regs, (offs >> 25) & 0xff);
- }
-}
-
-static void __nand_boot_init imx_nandboot_send_page(void *regs,
- unsigned int ops, int pagesize_2k)
-{
- int bufs, i;
-
- if (nfc_is_v1() && pagesize_2k)
- bufs = 4;
- else
- bufs = 1;
-
- for (i = 0; i < bufs; i++) {
- /* NANDFC buffer 0 is used for page read/write */
- writew(i, regs + NFC_V1_V2_BUF_ADDR);
-
- writew(ops, regs + NFC_V1_V2_CONFIG2);
-
- /* Wait for operation to complete */
- imx_nandboot_wait_op_done(regs);
- }
-}
-
-static void __nand_boot_init __memcpy32(void *trg, const void *src, int size)
-{
- int i;
- unsigned int *t = trg;
- unsigned const int *s = src;
-
- for (i = 0; i < (size >> 2); i++)
- *t++ = *s++;
-}
-
-static int __maybe_unused is_pagesize_2k(void)
-{
-#ifdef CONFIG_ARCH_IMX21
- if (readl(IMX_SYSTEM_CTL_BASE + 0x14) & (1 << 5))
- return 1;
- else
- return 0;
-#endif
-#ifdef CONFIG_ARCH_IMX27
- if (readl(IMX_SYSTEM_CTL_BASE + 0x14) & (1 << 5))
- return 1;
- else
- return 0;
-#endif
-#ifdef CONFIG_ARCH_IMX31
- if (readl(IMX_CCM_BASE + CCM_RCSR) & RCSR_NFMS)
- return 1;
- else
- return 0;
-#endif
-#if defined(CONFIG_ARCH_IMX35) || defined(CONFIG_ARCH_IMX25)
- if (readl(IMX_CCM_BASE + CCM_RCSR) & (1 << 8))
- return 1;
- else
- return 0;
-#endif
-}
-
-void __nand_boot_init imx_nand_load_image(void *dest, int size)
-{
- u32 tmp, page, block, blocksize, pagesize;
- int pagesize_2k = 1;
- void *regs, *base, *spare0;
-
-#if defined(CONFIG_NAND_IMX_BOOT_512)
- pagesize_2k = 0;
-#elif defined(CONFIG_NAND_IMX_BOOT_2K)
- pagesize_2k = 1;
-#else
- pagesize_2k = is_pagesize_2k();
-#endif
-
- if (pagesize_2k) {
- pagesize = 2048;
- blocksize = 128 * 1024;
- } else {
- pagesize = 512;
- blocksize = 16 * 1024;
- }
-
- base = (void __iomem *)IMX_NFC_BASE;
- if (nfc_is_v21()) {
- regs = base + 0x1e00;
- spare0 = base + 0x1000;
- } else if (nfc_is_v1()) {
- regs = base + 0xe00;
- spare0 = base + 0x800;
- }
-
- imx_nandboot_send_cmd(regs, NAND_CMD_RESET);
-
- /* preset operation */
- /* Unlock the internal RAM Buffer */
- writew(0x2, regs + NFC_V1_V2_CONFIG);
-
- /* Unlock Block Command for given address range */
- writew(0x4, regs + NFC_V1_V2_WRPROT);
-
- tmp = readw(regs + NFC_V1_V2_CONFIG1);
- tmp |= NFC_V1_V2_CONFIG1_ECC_EN;
- if (nfc_is_v21())
- /* currently no support for 218 byte OOB with stronger ECC */
- tmp |= NFC_V2_CONFIG1_ECC_MODE_4;
- tmp &= ~(NFC_V1_V2_CONFIG1_SP_EN | NFC_V1_V2_CONFIG1_INT_MSK);
- writew(tmp, regs + NFC_V1_V2_CONFIG1);
-
- if (nfc_is_v21()) {
- if (pagesize_2k)
- writew(NFC_V2_SPAS_SPARESIZE(64), regs + NFC_V2_SPAS);
- else
- writew(NFC_V2_SPAS_SPARESIZE(16), regs + NFC_V2_SPAS);
- }
-
- block = page = 0;
-
- while (1) {
- page = 0;
- while (page * pagesize < blocksize) {
- debug("page: %d block: %d dest: %p src "
- "0x%08x\n",
- page, block, dest,
- block * blocksize +
- page * pagesize);
-
- imx_nandboot_send_cmd(regs, NAND_CMD_READ0);
- imx_nandboot_nfc_addr(regs, block * blocksize +
- page * pagesize, pagesize_2k);
- imx_nandboot_send_page(regs, NFC_OUTPUT, pagesize_2k);
- page++;
-
- if (pagesize_2k) {
- if ((readw(spare0) & 0xff) != 0xff)
- continue;
- } else {
- if ((readw(spare0 + 4) & 0xff00) != 0xff00)
- continue;
- }
-
- __memcpy32(dest, base, pagesize);
- dest += pagesize;
- size -= pagesize;
-
- if (size <= 0)
- return;
- }
- block++;
- }
-}
-#define CONFIG_NAND_IMX_BOOT_DEBUG
-#ifdef CONFIG_NAND_IMX_BOOT_DEBUG
-#include <command.h>
-
-static int do_nand_boot_test(struct command *cmdtp, int argc, char *argv[])
-{
- void *dest;
- int size;
-
- if (argc < 3)
- return COMMAND_ERROR_USAGE;
-
- dest = (void *)strtoul_suffix(argv[1], NULL, 0);
- size = strtoul_suffix(argv[2], NULL, 0);
-
- imx_nand_load_image(dest, size);
-
- return 0;
-}
-
-static const __maybe_unused char cmd_nand_boot_test_help[] =
-"Usage: nand_boot_test <dest> <size>\n"
-"This command loads the booloader from the NAND memory like the reset\n"
-"routine does. Its intended for development tests only";
-
-BAREBOX_CMD_START(nand_boot_test)
- .cmd = do_nand_boot_test,
- .usage = "load bootloader from NAND",
- BAREBOX_CMD_HELP(cmd_nand_boot_test_help)
-BAREBOX_CMD_END
-#endif
-
-#endif /* CONFIG_NAND_IMX_BOOT */
-
/*
* Main initialization routine
* @return 0 if successful; non-zero otherwise