help: Correct syntax of nandecc help output.
[oweals/u-boot.git] / cpu / mpc83xx / cpu.c
index b2c35d3007c6dfe360f950c48893a69afe6a9204..e38a3722ca25f6fc7c8f082cbb787f770b6d28e5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004-2006 Freescale Semiconductor, Inc.
+ * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
  *
  * See file CREDITS for list of people who contributed to this
  * project.
 #include <command.h>
 #include <mpc83xx.h>
 #include <asm/processor.h>
-#if defined(CONFIG_OF_FLAT_TREE)
-#include <ft_build.h>
-#elif defined(CONFIG_OF_LIBFDT)
 #include <libfdt.h>
+#include <tsec.h>
+#include <netdev.h>
+#include <fsl_esdhc.h>
+#ifdef CONFIG_BOOTCOUNT_LIMIT
+#include <asm/immap_qe.h>
+#include <asm/io.h>
 #endif
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -46,8 +49,31 @@ int checkcpu(void)
        u32 pvr = get_pvr();
        u32 spridr;
        char buf[32];
-
-       immr = (immap_t *)CFG_IMMR;
+       int i;
+
+       const struct cpu_type {
+               char name[15];
+               u32 partid;
+       } cpu_type_list [] = {
+               CPU_TYPE_ENTRY(8311),
+               CPU_TYPE_ENTRY(8313),
+               CPU_TYPE_ENTRY(8314),
+               CPU_TYPE_ENTRY(8315),
+               CPU_TYPE_ENTRY(8321),
+               CPU_TYPE_ENTRY(8323),
+               CPU_TYPE_ENTRY(8343),
+               CPU_TYPE_ENTRY(8347_TBGA_),
+               CPU_TYPE_ENTRY(8347_PBGA_),
+               CPU_TYPE_ENTRY(8349),
+               CPU_TYPE_ENTRY(8358_TBGA_),
+               CPU_TYPE_ENTRY(8358_PBGA_),
+               CPU_TYPE_ENTRY(8360),
+               CPU_TYPE_ENTRY(8377),
+               CPU_TYPE_ENTRY(8378),
+               CPU_TYPE_ENTRY(8379),
+       };
+
+       immr = (immap_t *)CONFIG_SYS_IMMR;
 
        puts("CPU:   ");
 
@@ -64,105 +90,35 @@ int checkcpu(void)
                        printf("e300c3, ");
                        break;
 
+               case PVR_E300C4:
+                       printf("e300c4, ");
+                       break;
+
                default:
                        printf("Unknown core, ");
        }
 
        spridr = immr->sysconf.spridr;
-       switch(spridr) {
-       case SPR_8349E_REV10:
-       case SPR_8349E_REV11:
-       case SPR_8349E_REV31:
-               puts("MPC8349E, ");
-               break;
-       case SPR_8349_REV10:
-       case SPR_8349_REV11:
-       case SPR_8349_REV31:
-               puts("MPC8349, ");
-               break;
-       case SPR_8347E_REV10_TBGA:
-       case SPR_8347E_REV11_TBGA:
-       case SPR_8347E_REV31_TBGA:
-       case SPR_8347E_REV10_PBGA:
-       case SPR_8347E_REV11_PBGA:
-       case SPR_8347E_REV31_PBGA:
-               puts("MPC8347E, ");
-               break;
-       case SPR_8347_REV10_TBGA:
-       case SPR_8347_REV11_TBGA:
-       case SPR_8347_REV31_TBGA:
-       case SPR_8347_REV10_PBGA:
-       case SPR_8347_REV11_PBGA:
-       case SPR_8347_REV31_PBGA:
-               puts("MPC8347, ");
-               break;
-       case SPR_8343E_REV10:
-       case SPR_8343E_REV11:
-       case SPR_8343E_REV31:
-               puts("MPC8343E, ");
-               break;
-       case SPR_8343_REV10:
-       case SPR_8343_REV11:
-       case SPR_8343_REV31:
-               puts("MPC8343, ");
-               break;
-       case SPR_8360E_REV10:
-       case SPR_8360E_REV11:
-       case SPR_8360E_REV12:
-       case SPR_8360E_REV20:
-       case SPR_8360E_REV21:
-               puts("MPC8360E, ");
-               break;
-       case SPR_8360_REV10:
-       case SPR_8360_REV11:
-       case SPR_8360_REV12:
-       case SPR_8360_REV20:
-       case SPR_8360_REV21:
-               puts("MPC8360, ");
-               break;
-       case SPR_8323E_REV10:
-       case SPR_8323E_REV11:
-               puts("MPC8323E, ");
-               break;
-       case SPR_8323_REV10:
-       case SPR_8323_REV11:
-               puts("MPC8323, ");
-               break;
-       case SPR_8321E_REV10:
-       case SPR_8321E_REV11:
-               puts("MPC8321E, ");
-               break;
-       case SPR_8321_REV10:
-       case SPR_8321_REV11:
-               puts("MPC8321, ");
-               break;
-       case SPR_8311_REV10:
-               puts("MPC8311, ");
-               break;
-       case SPR_8311E_REV10:
-               puts("MPC8311E, ");
-               break;
-       case SPR_8313_REV10:
-               puts("MPC8313, ");
-               break;
-       case SPR_8313E_REV10:
-               puts("MPC8313E, ");
-               break;
-       default:
-               printf("Rev: Unknown revision number:%08x\n"
-                       "Warning: Unsupported cpu revision!\n",spridr);
-               return 0;
-       }
 
-#if defined(CONFIG_MPC834X)
-       /* Multiple revisons of 834x processors may have the same SPRIDR value.
-        * So use PVR to identify the revision number.
-        */
-       printf("Rev: %02x at %s MHz", PVR_MAJ(pvr)<<4 | PVR_MIN(pvr), strmhz(buf, clock));
-#else
-       printf("Rev: %02x at %s MHz", spridr & 0x0000FFFF, strmhz(buf, clock));
-#endif
-       printf(", CSB: %4d MHz\n", gd->csb_clk / 1000000);
+       for (i = 0; i < ARRAY_SIZE(cpu_type_list); i++)
+               if (cpu_type_list[i].partid == PARTID_NO_E(spridr)) {
+                       puts("MPC");
+                       puts(cpu_type_list[i].name);
+                       if (IS_E_PROCESSOR(spridr))
+                               puts("E");
+                       if (REVID_MAJOR(spridr) >= 2)
+                               puts("A");
+                       printf(", Rev: %d.%d", REVID_MAJOR(spridr),
+                              REVID_MINOR(spridr));
+                       break;
+               }
+
+       if (i == ARRAY_SIZE(cpu_type_list))
+               printf("(SPRIDR %08x unknown), ", spridr);
+
+       printf(" at %s MHz, ", strmhz(buf, clock));
+
+       printf("CSB: %s MHz\n", strmhz(buf, gd->csb_clk));
 
        return 0;
 }
@@ -174,8 +130,8 @@ int checkcpu(void)
  * The 'dummy' variable is used to increment the MAD. 'dummy' is
  * supposed to be a pointer to the memory of the device being
  * programmed by the UPM.  The data in the MDR is written into
- * memory and the MAD is incremented every time there's a read
- * from 'dummy'. Unfortunately, the current prototype for this
+ * memory and the MAD is incremented every time there's a write
+ * to 'dummy'. Unfortunately, the current prototype for this
  * function doesn't allow for passing the address of this
  * device, and changing the prototype will break a number lots
  * of other code, so we need to use a round-about way of finding
@@ -197,9 +153,8 @@ int checkcpu(void)
  */
 void upmconfig (uint upm, uint *table, uint size)
 {
-#if defined(CONFIG_MPC834X)
-       volatile immap_t *immap = (immap_t *) CFG_IMMR;
-       volatile lbus83xx_t *lbus = &immap->lbus;
+       volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
+       volatile fsl_lbus_t *lbus = &immap->lbus;
        volatile uchar *dummy = NULL;
        const u32 msel = (upm + 4) << BR_MSEL_SHIFT;    /* What the MSEL field in BRn should be */
        volatile u32 *mxmr = &lbus->mamr + upm; /* Pointer to mamr, mbmr, or mcmr */
@@ -224,16 +179,13 @@ void upmconfig (uint upm, uint *table, uint size)
        for (i = 0; i < size; i++) {
                lbus->mdr = table[i];
                __asm__ __volatile__ ("sync");
-               *dummy; /* Write the value to memory and increment MAD */
+               *dummy = 0;     /* Write the value to memory and increment MAD */
                __asm__ __volatile__ ("sync");
+               while(((*mxmr & 0x3f) != ((i + 1) & 0x3f)));
        }
 
        /* Set the OP field in the MxMR to "normal" and the MAD field to 000000 */
        *mxmr &= 0xCFFFFFC0;
-#else
-       printf("Error: %s() not defined for this configuration.\n", __FUNCTION__);
-       hang();
-#endif
 }
 
 
@@ -245,7 +197,7 @@ do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
        ulong addr;
 #endif
 
-       volatile immap_t *immap = (immap_t *) CFG_IMMR;
+       volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
 
 #ifdef MPC83xx_RESET
        /* Interrupts and MMU off */
@@ -284,7 +236,7 @@ do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
         * Trying to execute the next instruction at a non-existing address
         * should cause a machine check, resulting in reset
         */
-       addr = CFG_RESET_ADDRESS;
+       addr = CONFIG_SYS_RESET_ADDRESS;
 
        printf("resetting the board.");
        printf("\n");
@@ -315,7 +267,7 @@ void watchdog_reset (void)
        int re_enable = disable_interrupts();
 
        /* Reset the 83xx watchdog */
-       volatile immap_t *immr = (immap_t *) CFG_IMMR;
+       volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
        immr->wdt.swsrr = 0x556c;
        immr->wdt.swsrr = 0xaa39;
 
@@ -324,409 +276,61 @@ void watchdog_reset (void)
 }
 #endif
 
-#if defined(CONFIG_OF_LIBFDT)
-
 /*
- * "Setter" functions used to add/modify FDT entries.
+ * Initializes on-chip ethernet controllers.
+ * to override, implement board_eth_init()
  */
-static int fdt_set_eth0(void *blob, int nodeoffset, const char *name, bd_t *bd)
-{
-       /* Fix it up if it exists, don't create it if it doesn't exist */
-       if (fdt_get_property(blob, nodeoffset, name, 0)) {
-               return fdt_setprop(blob, nodeoffset, name, bd->bi_enetaddr, 6);
-       }
-       return 0;
-}
-#ifdef CONFIG_HAS_ETH1
-/* second onboard ethernet port */
-static int fdt_set_eth1(void *blob, int nodeoffset, const char *name, bd_t *bd)
+int cpu_eth_init(bd_t *bis)
 {
-       /* Fix it up if it exists, don't create it if it doesn't exist */
-       if (fdt_get_property(blob, nodeoffset, name, 0)) {
-               return fdt_setprop(blob, nodeoffset, name, bd->bi_enet1addr, 6);
-       }
-       return 0;
-}
+#if defined(CONFIG_UEC_ETH)
+       uec_standard_init(bis);
 #endif
-#ifdef CONFIG_HAS_ETH2
-/* third onboard ethernet port */
-static int fdt_set_eth2(void *blob, int nodeoffset, const char *name, bd_t *bd)
-{
-       /* Fix it up if it exists, don't create it if it doesn't exist */
-       if (fdt_get_property(blob, nodeoffset, name, 0)) {
-               return fdt_setprop(blob, nodeoffset, name, bd->bi_enet2addr, 6);
-       }
-       return 0;
-}
+
+#if defined(CONFIG_TSEC_ENET)
+       tsec_standard_init(bis);
 #endif
-#ifdef CONFIG_HAS_ETH3
-/* fourth onboard ethernet port */
-static int fdt_set_eth3(void *blob, int nodeoffset, const char *name, bd_t *bd)
-{
-       /* Fix it up if it exists, don't create it if it doesn't exist */
-       if (fdt_get_property(blob, nodeoffset, name, 0)) {
-               return fdt_setprop(blob, nodeoffset, name, bd->bi_enet3addr, 6);
-       }
        return 0;
 }
-#endif
-
-static int fdt_set_busfreq(void *blob, int nodeoffset, const char *name, bd_t *bd)
-{
-       u32  tmp;
-       /* Create or update the property */
-       tmp = cpu_to_be32(bd->bi_busfreq);
-       return fdt_setprop(blob, nodeoffset, name, &tmp, sizeof(tmp));
-}
-
-static int fdt_set_tbfreq(void *blob, int nodeoffset, const char *name, bd_t *bd)
-{
-       u32  tmp;
-       /* Create or update the property */
-       tmp = cpu_to_be32(OF_TBCLK);
-       return fdt_setprop(blob, nodeoffset, name, &tmp, sizeof(tmp));
-}
-
-
-static int fdt_set_clockfreq(void *blob, int nodeoffset, const char *name, bd_t *bd)
-{
-       u32  tmp;
-       /* Create or update the property */
-       tmp = cpu_to_be32(gd->core_clk);
-       return fdt_setprop(blob, nodeoffset, name, &tmp, sizeof(tmp));
-}
-
-#ifdef CONFIG_QE
-static int fdt_set_qe_busfreq(void *blob, int nodeoffset, const char *name, bd_t *bd)
-{
-       u32  tmp;
-       /* Create or update the property */
-       tmp = cpu_to_be32(gd->qe_clk);
-       return fdt_setprop(blob, nodeoffset, name, &tmp, sizeof(tmp));
-}
-
-static int fdt_set_qe_brgfreq(void *blob, int nodeoffset, const char *name, bd_t *bd)
-{
-       u32  tmp;
-       /* Create or update the property */
-       tmp = cpu_to_be32(gd->brg_clk);
-       return fdt_setprop(blob, nodeoffset, name, &tmp, sizeof(tmp));
-}
-#endif
 
 /*
- * Fixups to the fdt.
+ * Initializes on-chip MMC controllers.
+ * to override, implement board_mmc_init()
  */
-static const struct {
-       char *node;
-       char *prop;
-       int (*set_fn)(void *blob, int nodeoffset, const char *name, bd_t *bd);
-} fixup_props[] = {
-       {       "/cpus/" OF_CPU,
-               "timebase-frequency",
-               fdt_set_tbfreq
-       },
-       {       "/cpus/" OF_CPU,
-               "bus-frequency",
-               fdt_set_busfreq
-       },
-       {       "/cpus/" OF_CPU,
-               "clock-frequency",
-               fdt_set_clockfreq
-       },
-       {       "/" OF_SOC,
-               "bus-frequency",
-               fdt_set_busfreq
-       },
-       {       "/" OF_SOC "/serial@4500",
-               "clock-frequency",
-               fdt_set_busfreq
-       },
-       {       "/" OF_SOC "/serial@4600",
-               "clock-frequency",
-               fdt_set_busfreq
-       },
-#ifdef CONFIG_TSEC1
-       {       "/" OF_SOC "/ethernet@24000",
-               "mac-address",
-               fdt_set_eth0
-       },
-       {       "/" OF_SOC "/ethernet@24000",
-               "local-mac-address",
-               fdt_set_eth0
-       },
-#endif
-#ifdef CONFIG_TSEC2
-       {       "/" OF_SOC "/ethernet@25000",
-               "mac-address",
-               fdt_set_eth1
-       },
-       {       "/" OF_SOC "/ethernet@25000",
-               "local-mac-address",
-               fdt_set_eth1
-       },
-#endif
-#ifdef CONFIG_QE
-       {       "/" OF_QE,
-               "brg-frequency",
-               fdt_set_qe_brgfreq
-       },
-       {       "/" OF_QE,
-               "bus-frequency",
-               fdt_set_qe_busfreq
-       },
-#ifdef CONFIG_UEC_ETH1
-#if CFG_UEC1_UCC_NUM == 0  /* UCC1 */
-       {       "/" OF_QE "/ucc@2000",
-               "mac-address",
-               fdt_set_eth0
-       },
-       {       "/" OF_QE "/ucc@2000",
-               "local-mac-address",
-               fdt_set_eth0
-       },
-#elif CFG_UEC1_UCC_NUM == 2  /* UCC3 */
-       {       "/" OF_QE "/ucc@2200",
-               "mac-address",
-               fdt_set_eth0
-       },
-       {       "/" OF_QE "/ucc@2200",
-               "local-mac-address",
-               fdt_set_eth0
-       },
-#endif
-#endif /* CONFIG_UEC_ETH1 */
-#ifdef CONFIG_UEC_ETH2
-#if CFG_UEC2_UCC_NUM == 1  /* UCC2 */
-       {       "/" OF_QE "/ucc@3000",
-               "mac-address",
-               fdt_set_eth1
-       },
-       {       "/" OF_QE "/ucc@3000",
-               "local-mac-address",
-               fdt_set_eth1
-       },
-#elif CFG_UEC2_UCC_NUM == 3  /* UCC4 */
-       {       "/" OF_QE "/ucc@3200",
-               "mac-address",
-               fdt_set_eth1
-       },
-       {       "/" OF_QE "/ucc@3200",
-               "local-mac-address",
-               fdt_set_eth1
-       },
-#endif
-#endif /* CONFIG_UEC_ETH2 */
-#endif /* CONFIG_QE */
-};
-
-void
-ft_cpu_setup(void *blob, bd_t *bd)
+int cpu_mmc_init(bd_t *bis)
 {
-       int nodeoffset;
-       int err;
-       int j;
-       int tmp[2];
-
-       for (j = 0; j < (sizeof(fixup_props) / sizeof(fixup_props[0])); j++) {
-               nodeoffset = fdt_path_offset(blob, fixup_props[j].node);
-               if (nodeoffset >= 0) {
-                       err = fixup_props[j].set_fn(blob, nodeoffset,
-                                                   fixup_props[j].prop, bd);
-                       if (err < 0)
-                               debug("Problem setting %s = %s: %s\n",
-                                     fixup_props[j].node, fixup_props[j].prop,
-                                     fdt_strerror(err));
-               } else {
-                       debug("Couldn't find %s: %s\n",
-                             fixup_props[j].node, fdt_strerror(nodeoffset));
-               }
-       }
-
-       /* update, or add and update /memory node */
-       nodeoffset = fdt_path_offset(blob, "/memory");
-       if (nodeoffset < 0) {
-               nodeoffset = fdt_add_subnode(blob, 0, "memory");
-               if (nodeoffset < 0)
-                       debug("failed to add /memory node: %s\n",
-                             fdt_strerror(nodeoffset));
-       }
-       if (nodeoffset >= 0) {
-               fdt_setprop(blob, nodeoffset, "device_type",
-                           "memory", sizeof("memory"));
-               tmp[0] = cpu_to_be32(bd->bi_memstart);
-               tmp[1] = cpu_to_be32(bd->bi_memsize);
-               fdt_setprop(blob, nodeoffset, "reg", tmp, sizeof(tmp));
-       }
-}
-#elif defined(CONFIG_OF_FLAT_TREE)
-void
-ft_cpu_setup(void *blob, bd_t *bd)
-{
-       u32 *p;
-       int len;
-       ulong clock;
-
-       clock = bd->bi_busfreq;
-       p = ft_get_prop(blob, "/cpus/" OF_CPU "/bus-frequency", &len);
-       if (p != NULL)
-               *p = cpu_to_be32(clock);
-
-       p = ft_get_prop(blob, "/" OF_SOC "/bus-frequency", &len);
-       if (p != NULL)
-               *p = cpu_to_be32(clock);
-
-       p = ft_get_prop(blob, "/" OF_SOC "/serial@4500/clock-frequency", &len);
-       if (p != NULL)
-               *p = cpu_to_be32(clock);
-
-       p = ft_get_prop(blob, "/" OF_SOC "/serial@4600/clock-frequency", &len);
-       if (p != NULL)
-               *p = cpu_to_be32(clock);
-
-#ifdef CONFIG_TSEC1
-       p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/mac-address", &len);
-       if (p != NULL)
-               memcpy(p, bd->bi_enetaddr, 6);
-
-       p = ft_get_prop(blob, "/" OF_SOC "/ethernet@24000/local-mac-address", &len);
-       if (p != NULL)
-               memcpy(p, bd->bi_enetaddr, 6);
+#ifdef CONFIG_FSL_ESDHC
+       return fsl_esdhc_mmc_init(bis);
+#else
+       return 0;
 #endif
+}
 
-#ifdef CONFIG_TSEC2
-       p = ft_get_prop(blob, "/" OF_SOC "/ethernet@25000/mac-address", &len);
-       if (p != NULL)
-               memcpy(p, bd->bi_enet1addr, 6);
+#ifdef CONFIG_BOOTCOUNT_LIMIT
 
-       p = ft_get_prop(blob, "/" OF_SOC "/ethernet@25000/local-mac-address", &len);
-       if (p != NULL)
-               memcpy(p, bd->bi_enet1addr, 6);
+#if !defined(CONFIG_MPC8360)
+#error "CONFIG_BOOTCOUNT_LIMIT only for MPC8360 implemented"
 #endif
 
-#ifdef CONFIG_UEC_ETH1
-#if CFG_UEC1_UCC_NUM == 0  /* UCC1 */
-       p = ft_get_prop(blob, "/" OF_QE "/ucc@2000/mac-address", &len);
-       if (p != NULL)
-               memcpy(p, bd->bi_enetaddr, 6);
-
-       p = ft_get_prop(blob, "/" OF_QE "/ucc@2000/local-mac-address", &len);
-       if (p != NULL)
-               memcpy(p, bd->bi_enetaddr, 6);
-#elif CFG_UEC1_UCC_NUM == 2  /* UCC3 */
-       p = ft_get_prop(blob, "/" OF_QE "/ucc@2200/mac-address", &len);
-       if (p != NULL)
-               memcpy(p, bd->bi_enetaddr, 6);
-
-       p = ft_get_prop(blob, "/" OF_QE "/ucc@2200/local-mac-address", &len);
-       if (p != NULL)
-               memcpy(p, bd->bi_enetaddr, 6);
-#endif
+#if !defined(CONFIG_BOOTCOUNT_ADDR)
+#define CONFIG_BOOTCOUNT_ADDR  (0x110000 + QE_MURAM_SIZE - 2 * sizeof(unsigned long))
 #endif
 
-#ifdef CONFIG_UEC_ETH2
-#if CFG_UEC2_UCC_NUM == 1  /* UCC2 */
-       p = ft_get_prop(blob, "/" OF_QE "/ucc@3000/mac-address", &len);
-       if (p != NULL)
-               memcpy(p, bd->bi_enet1addr, 6);
-
-       p = ft_get_prop(blob, "/" OF_QE "/ucc@3000/local-mac-address", &len);
-       if (p != NULL)
-               memcpy(p, bd->bi_enet1addr, 6);
-#elif CFG_UEC2_UCC_NUM == 3  /* UCC4 */
-       p = ft_get_prop(blob, "/" OF_QE "/ucc@3200/mac-address", &len);
-       if (p != NULL)
-               memcpy(p, bd->bi_enet1addr, 6);
-
-       p = ft_get_prop(blob, "/" OF_QE "/ucc@3200/local-mac-address", &len);
-       if (p != NULL)
-               memcpy(p, bd->bi_enet1addr, 6);
-#endif
-#endif
-}
-#endif
+#include <asm/io.h>
 
-#if defined(CONFIG_DDR_ECC)
-void dma_init(void)
+void bootcount_store (ulong a)
 {
-       volatile immap_t *immap = (immap_t *)CFG_IMMR;
-       volatile dma83xx_t *dma = &immap->dma;
-       volatile u32 status = swab32(dma->dmasr0);
-       volatile u32 dmamr0 = swab32(dma->dmamr0);
-
-       debug("DMA-init\n");
-
-       /* initialize DMASARn, DMADAR and DMAABCRn */
-       dma->dmadar0 = (u32)0;
-       dma->dmasar0 = (u32)0;
-       dma->dmabcr0 = 0;
-
-       __asm__ __volatile__ ("sync");
-       __asm__ __volatile__ ("isync");
-
-       /* clear CS bit */
-       dmamr0 &= ~DMA_CHANNEL_START;
-       dma->dmamr0 = swab32(dmamr0);
-       __asm__ __volatile__ ("sync");
-       __asm__ __volatile__ ("isync");
-
-       /* while the channel is busy, spin */
-       while(status & DMA_CHANNEL_BUSY) {
-               status = swab32(dma->dmasr0);
-       }
-
-       debug("DMA-init end\n");
-}
-
-uint dma_check(void)
-{
-       volatile immap_t *immap = (immap_t *)CFG_IMMR;
-       volatile dma83xx_t *dma = &immap->dma;
-       volatile u32 status = swab32(dma->dmasr0);
-       volatile u32 byte_count = swab32(dma->dmabcr0);
-
-       /* while the channel is busy, spin */
-       while (status & DMA_CHANNEL_BUSY) {
-               status = swab32(dma->dmasr0);
-       }
-
-       if (status & DMA_CHANNEL_TRANSFER_ERROR) {
-               printf ("DMA Error: status = %x @ %d\n", status, byte_count);
-       }
-
-       return status;
+       void *reg = (void *)(CONFIG_SYS_IMMR + CONFIG_BOOTCOUNT_ADDR);
+       out_be32 (reg, a);
+       out_be32 (reg + 4, BOOTCOUNT_MAGIC);
 }
 
-int dma_xfer(void *dest, u32 count, void *src)
+ulong bootcount_load (void)
 {
-       volatile immap_t *immap = (immap_t *)CFG_IMMR;
-       volatile dma83xx_t *dma = &immap->dma;
-       volatile u32 dmamr0;
-
-       /* initialize DMASARn, DMADAR and DMAABCRn */
-       dma->dmadar0 = swab32((u32)dest);
-       dma->dmasar0 = swab32((u32)src);
-       dma->dmabcr0 = swab32(count);
+       void *reg = (void *)(CONFIG_SYS_IMMR + CONFIG_BOOTCOUNT_ADDR);
 
-       __asm__ __volatile__ ("sync");
-       __asm__ __volatile__ ("isync");
-
-       /* init direct transfer, clear CS bit */
-       dmamr0 = (DMA_CHANNEL_TRANSFER_MODE_DIRECT |
-                       DMA_CHANNEL_SOURCE_ADDRESS_HOLD_8B |
-                       DMA_CHANNEL_SOURCE_ADRESSS_HOLD_EN);
-
-       dma->dmamr0 = swab32(dmamr0);
-
-       __asm__ __volatile__ ("sync");
-       __asm__ __volatile__ ("isync");
-
-       /* set CS to start DMA transfer */
-       dmamr0 |= DMA_CHANNEL_START;
-       dma->dmamr0 = swab32(dmamr0);
-       __asm__ __volatile__ ("sync");
-       __asm__ __volatile__ ("isync");
-
-       return ((int)dma_check());
+       if (in_be32 (reg + 4) != BOOTCOUNT_MAGIC)
+               return 0;
+       else
+               return in_be32 (reg);
 }
-#endif /*CONFIG_DDR_ECC*/
+#endif /* CONFIG_BOOTCOUNT_LIMIT */