summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-imx
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2020-02-25 09:17:30 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2020-02-25 09:17:30 +0100
commit9044ad7c2cf78a2963c9ddc3c4b9bf2054f46e95 (patch)
tree2ec929318b89e1e1f31e32a8adf7a417a6165117 /arch/arm/mach-imx
parent1b3ee1f1a292f88e5f18aae152082fac97aa1ba6 (diff)
parent104f5a22d61480fb275d05298ea185c95fbcb5b7 (diff)
downloadbarebox-9044ad7c2cf78a2963c9ddc3c4b9bf2054f46e95.tar.gz
barebox-9044ad7c2cf78a2963c9ddc3c4b9bf2054f46e95.tar.xz
Merge branch 'for-master/imx-external-nand'
Diffstat (limited to 'arch/arm/mach-imx')
-rw-r--r--arch/arm/mach-imx/external-nand-boot.c274
-rw-r--r--arch/arm/mach-imx/include/mach/imx-nand.h19
2 files changed, 174 insertions, 119 deletions
diff --git a/arch/arm/mach-imx/external-nand-boot.c b/arch/arm/mach-imx/external-nand-boot.c
index c4d61aa786..123589c071 100644
--- a/arch/arm/mach-imx/external-nand-boot.c
+++ b/arch/arm/mach-imx/external-nand-boot.c
@@ -134,12 +134,13 @@ static noinline void __bare_init imx_nandboot_get_page(void *regs, int v1,
imx_nandboot_send_page(regs, v1, NFC_OUTPUT, pagesize_2k);
}
-static void __bare_init imx_nand_load_image(void *dest, int v1, int size,
+static void __bare_init imx_nand_load_image(void *dest, int v1,
void __iomem *base, int pagesize_2k)
{
u32 tmp, page, block, blocksize, pagesize, badblocks;
int bbt = 0;
void *regs, *spare0;
+ int size = *(uint32_t *)(dest + 0x2c);
if (pagesize_2k) {
pagesize = 2048;
@@ -239,143 +240,188 @@ static void __bare_init imx_nand_load_image(void *dest, int v1, int size,
}
}
-static void BARE_INIT_FUNCTION(imx25_nand_load_image)(void *dest, int size,
- void __iomem *base, int pagesize_2k)
+void BARE_INIT_FUNCTION(imx25_nand_load_image)(void)
{
- imx_nand_load_image(dest, 0, size, base, pagesize_2k);
+ void *sdram = (void *)MX25_CSD0_BASE_ADDR;
+ void __iomem *nfc_base = IOMEM(MX25_NFC_BASE_ADDR);
+ bool pagesize_2k;
+
+ if (readl(MX25_CCM_BASE_ADDR + MX25_CCM_RCSR) & (1 << 8))
+ pagesize_2k = true;
+ else
+ pagesize_2k = false;
+
+ imx_nand_load_image(sdram, 0, nfc_base, pagesize_2k);
}
-static void BARE_INIT_FUNCTION(imx27_nand_load_image)(void *dest, int size,
- void __iomem *base, int pagesize_2k)
+void BARE_INIT_FUNCTION(imx27_nand_load_image)(void)
{
- imx_nand_load_image(dest, 1, size, base, pagesize_2k);
+ void *sdram = (void *)MX27_CSD0_BASE_ADDR;
+ void __iomem *nfc_base = IOMEM(MX27_NFC_BASE_ADDR);
+ bool pagesize_2k;
+
+ if (readl(MX27_SYSCTRL_BASE_ADDR + 0x14) & (1 << 5))
+ pagesize_2k = true;
+ else
+ pagesize_2k = false;
+
+ imx_nand_load_image(sdram, 1, nfc_base, pagesize_2k);
}
-static void BARE_INIT_FUNCTION(imx31_nand_load_image)(void *dest, int size,
- void __iomem *base, int pagesize_2k)
+void BARE_INIT_FUNCTION(imx31_nand_load_image)(void)
{
- imx_nand_load_image(dest, 1, size, base, pagesize_2k);
+ void *sdram = (void *)MX31_CSD0_BASE_ADDR;
+ void __iomem *nfc_base = IOMEM(MX31_NFC_BASE_ADDR);
+ bool pagesize_2k;
+
+ if (readl(MX31_CCM_BASE_ADDR + MX31_CCM_RCSR) & MX31_RCSR_NFMS)
+ pagesize_2k = true;
+ else
+ pagesize_2k = false;
+
+ imx_nand_load_image(sdram, 1, nfc_base, pagesize_2k);
}
-static void BARE_INIT_FUNCTION(imx35_nand_load_image)(void *dest, int size,
- void __iomem *base, int pagesize_2k)
+void BARE_INIT_FUNCTION(imx35_nand_load_image)(void)
{
- imx_nand_load_image(dest, 0, size, base, pagesize_2k);
+ void *sdram = (void *)MX35_CSD0_BASE_ADDR;
+ void __iomem *nfc_base = IOMEM(MX35_NFC_BASE_ADDR);
+ bool pagesize_2k;
+
+ if (readl(MX35_CCM_BASE_ADDR + MX35_CCM_RCSR) & (1 << 8))
+ pagesize_2k = true;
+ else
+ pagesize_2k = false;
+
+ imx_nand_load_image(sdram, 0, nfc_base, pagesize_2k);
}
-static inline int imx25_pagesize_2k(void)
+/*
+ * relocate_to_sdram - move ourselves out of NFC SRAM
+ *
+ * @nfc_base: base address of the NFC controller
+ * @sdram: SDRAM base address where we move ourselves to
+ * @fn: Function we continue with when running in SDRAM
+ *
+ * This function moves ourselves out of NFC SRAM to SDRAM. In case we a currently
+ * not running in NFC SRAM this function returns. If running in NFC SRAM, this
+ * function will not return, but call @fn instead.
+ */
+static void BARE_INIT_FUNCTION(relocate_to_sdram)(unsigned long nfc_base,
+ unsigned long sdram,
+ void __noreturn (*fn)(void))
{
- if (readl(MX25_CCM_BASE_ADDR + MX25_CCM_RCSR) & (1 << 8))
- return 1;
- else
- return 0;
+ unsigned long __fn;
+ u32 r;
+ u32 *src, *trg;
+ int i;
+
+ /* skip NAND boot if not running from NFC space */
+ r = get_pc();
+ if (r < nfc_base || r > nfc_base + 0x800)
+ return;
+
+ src = (unsigned int *)nfc_base;
+ trg = (unsigned int *)sdram;
+
+ /*
+ * Copy initial binary portion from NFC SRAM to beginning of
+ * SDRAM
+ */
+ for (i = 0; i < 0x800 / sizeof(int); i++)
+ *trg++ = *src++;
+
+ /* The next function we jump to */
+ __fn = (unsigned long)fn;
+ /* mask out TEXT_BASE */
+ __fn &= 0x7ff;
+ /*
+ * and add sdram base instead where we copied the initial
+ * binary above
+ */
+ __fn += sdram;
+
+ fn = (void *)__fn;
+
+ fn();
}
-static inline int imx27_pagesize_2k(void)
+void BARE_INIT_FUNCTION(imx25_nand_relocate_to_sdram)(void __noreturn (*fn)(void))
{
- if (readl(MX27_SYSCTRL_BASE_ADDR + 0x14) & (1 << 5))
- return 1;
- else
- return 0;
+ unsigned long nfc_base = MX25_NFC_BASE_ADDR;
+ unsigned long sdram = MX25_CSD0_BASE_ADDR;
+
+ relocate_to_sdram(nfc_base, sdram, fn);
}
-static inline int imx31_pagesize_2k(void)
+static void __noreturn BARE_INIT_FUNCTION(imx25_boot_nand_external_cont)(void)
{
- if (readl(MX31_CCM_BASE_ADDR + MX31_CCM_RCSR) & MX31_RCSR_NFMS)
- return 1;
- else
- return 0;
+ imx25_nand_load_image();
+ imx25_barebox_entry(NULL);
}
-static inline int imx35_pagesize_2k(void)
+void __noreturn BARE_INIT_FUNCTION(imx25_barebox_boot_nand_external)(void)
{
- if (readl(MX35_CCM_BASE_ADDR + MX35_CCM_RCSR) & (1 << 8))
- return 1;
- else
- return 0;
+ imx25_nand_relocate_to_sdram(imx25_boot_nand_external_cont);
+ imx25_barebox_entry(NULL);
}
-/*
- * SoC specific entries for booting in external NAND mode. To be called from
- * the board specific entry code. This is safe to call even if not booting from
- * NAND. In this case the booting is continued without loading an image from
- * NAND. This function needs a stack to be set up.
- */
+void BARE_INIT_FUNCTION(imx27_nand_relocate_to_sdram)(void __noreturn (*fn)(void))
+{
+ unsigned long nfc_base = MX27_NFC_BASE_ADDR;
+ unsigned long sdram = MX27_CSD0_BASE_ADDR;
+
+ relocate_to_sdram(nfc_base, sdram, fn);
+}
+
+static void __noreturn BARE_INIT_FUNCTION(imx27_boot_nand_external_cont)(void)
+{
+ imx27_nand_load_image();
+ imx27_barebox_entry(NULL);
+}
+
+void __noreturn BARE_INIT_FUNCTION(imx27_barebox_boot_nand_external)(void)
+{
+ imx27_nand_relocate_to_sdram(imx27_boot_nand_external_cont);
+ imx27_barebox_entry(NULL);
+}
-#define DEFINE_EXTERNAL_NAND_ENTRY(soc) \
- \
-static void __noreturn BARE_INIT_FUNCTION(imx##soc##_boot_nand_external_cont) \
- (void *boarddata) \
-{ \
- unsigned long nfc_base = MX##soc##_NFC_BASE_ADDR; \
- void *sdram = (void *)MX##soc##_CSD0_BASE_ADDR; \
- uint32_t image_size, r; \
- \
- image_size = *(uint32_t *)(sdram + 0x2c); \
- \
- r = get_cr(); \
- r |= CR_I; \
- set_cr(r); \
- \
- imx##soc##_nand_load_image(sdram, \
- image_size, \
- (void *)nfc_base, \
- imx##soc##_pagesize_2k()); \
- \
- imx##soc##_barebox_entry(boarddata); \
-} \
- \
-void __noreturn BARE_INIT_FUNCTION(imx##soc##_barebox_boot_nand_external) \
- (void *bd) \
-{ \
- unsigned long nfc_base = MX##soc##_NFC_BASE_ADDR; \
- unsigned long sdram = MX##soc##_CSD0_BASE_ADDR; \
- unsigned long boarddata = (unsigned long)bd; \
- unsigned long __fn; \
- u32 r; \
- u32 *src, *trg; \
- int i; \
- void __noreturn (*fn)(void *); \
- \
- r = get_cr(); \
- r &= ~CR_I; \
- set_cr(r); \
- /* skip NAND boot if not running from NFC space */ \
- r = get_pc(); \
- if (r < nfc_base || r > nfc_base + 0x800) \
- imx##soc##_barebox_entry(bd); \
- \
- src = (unsigned int *)nfc_base; \
- trg = (unsigned int *)sdram; \
- \
- /* \
- * Copy initial binary portion from NFC SRAM to beginning of \
- * SDRAM \
- */ \
- for (i = 0; i < 0x800 / sizeof(int); i++) \
- *trg++ = *src++; \
- \
- /* The next function we jump to */ \
- __fn = (unsigned long)imx##soc##_boot_nand_external_cont; \
- /* mask out TEXT_BASE */ \
- __fn &= 0x7ff; \
- /* \
- * and add sdram base instead where we copied the initial \
- * binary above \
- */ \
- __fn += sdram; \
- \
- fn = (void *)__fn; \
- \
- if (boarddata > nfc_base && boarddata < nfc_base + SZ_512K) { \
- boarddata &= SZ_512K - 1; \
- boarddata += sdram; \
- } \
- \
- fn((void *)boarddata); \
+void BARE_INIT_FUNCTION(imx31_nand_relocate_to_sdram)(void __noreturn (*fn)(void))
+{
+ unsigned long nfc_base = MX31_NFC_BASE_ADDR;
+ unsigned long sdram = MX31_CSD0_BASE_ADDR;
+
+ relocate_to_sdram(nfc_base, sdram, fn);
+}
+
+static void __noreturn BARE_INIT_FUNCTION(imx31_boot_nand_external_cont)(void)
+{
+ imx31_nand_load_image();
+ imx31_barebox_entry(NULL);
}
-DEFINE_EXTERNAL_NAND_ENTRY(25)
-DEFINE_EXTERNAL_NAND_ENTRY(27)
-DEFINE_EXTERNAL_NAND_ENTRY(31)
-DEFINE_EXTERNAL_NAND_ENTRY(35)
+void __noreturn BARE_INIT_FUNCTION(imx31_barebox_boot_nand_external)(void)
+{
+ imx31_nand_relocate_to_sdram(imx31_boot_nand_external_cont);
+ imx31_barebox_entry(NULL);
+}
+
+void BARE_INIT_FUNCTION(imx35_nand_relocate_to_sdram)(void __noreturn (*fn)(void))
+{
+ unsigned long nfc_base = MX35_NFC_BASE_ADDR;
+ unsigned long sdram = MX35_CSD0_BASE_ADDR;
+
+ relocate_to_sdram(nfc_base, sdram, fn);
+}
+
+static void __noreturn BARE_INIT_FUNCTION(imx35_boot_nand_external_cont)(void)
+{
+ imx35_nand_load_image();
+ imx35_barebox_entry(NULL);
+}
+
+void __noreturn BARE_INIT_FUNCTION(imx35_barebox_boot_nand_external)(void)
+{
+ imx35_nand_relocate_to_sdram(imx35_boot_nand_external_cont);
+ imx35_barebox_entry(NULL);
+}
diff --git a/arch/arm/mach-imx/include/mach/imx-nand.h b/arch/arm/mach-imx/include/mach/imx-nand.h
index 0adba0989a..f34799a011 100644
--- a/arch/arm/mach-imx/include/mach/imx-nand.h
+++ b/arch/arm/mach-imx/include/mach/imx-nand.h
@@ -3,11 +3,20 @@
#include <linux/mtd/mtd.h>
-void imx21_barebox_boot_nand_external(void *boarddata);
-void imx25_barebox_boot_nand_external(void *boarddata);
-void imx27_barebox_boot_nand_external(void *boarddata);
-void imx31_barebox_boot_nand_external(void *boarddata);
-void imx35_barebox_boot_nand_external(void *boarddata);
+void imx25_nand_load_image(void);
+void imx27_nand_load_image(void);
+void imx31_nand_load_image(void);
+void imx35_nand_load_image(void);
+
+void imx25_nand_relocate_to_sdram(void __noreturn (*fn)(void));
+void imx27_nand_relocate_to_sdram(void __noreturn (*fn)(void));
+void imx31_nand_relocate_to_sdram(void __noreturn (*fn)(void));
+void imx35_nand_relocate_to_sdram(void __noreturn (*fn)(void));
+
+void imx25_barebox_boot_nand_external(void);
+void imx27_barebox_boot_nand_external(void);
+void imx31_barebox_boot_nand_external(void);
+void imx35_barebox_boot_nand_external(void);
void imx_nand_set_layout(int writesize, int datawidth);
struct imx_nand_platform_data {