summaryrefslogtreecommitdiff
path: root/cpu/mpc83xx/cpu.c
diff options
context:
space:
mode:
authorWolfgang Denk <wd@pollux.denx.de>2006-03-17 17:41:56 +0100
committerWolfgang Denk <wd@pollux.denx.de>2006-03-17 17:41:56 +0100
commit0a112d8696dcffdf87a7066e2dade1eacbdd80d9 (patch)
tree86f83dc1ad77177294d23499aadbe8db69bfdb54 /cpu/mpc83xx/cpu.c
parent09e4b0c5d3881412519f33d498560a5bbcc82cd9 (diff)
parentdc9e499c620a590e0f906e807e24c85807af3338 (diff)
downloadu-boot-imx-0a112d8696dcffdf87a7066e2dade1eacbdd80d9.zip
u-boot-imx-0a112d8696dcffdf87a7066e2dade1eacbdd80d9.tar.gz
u-boot-imx-0a112d8696dcffdf87a7066e2dade1eacbdd80d9.tar.bz2
Merge with port of MPC8349EMDS board
Diffstat (limited to 'cpu/mpc83xx/cpu.c')
-rw-r--r--cpu/mpc83xx/cpu.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c
index e49e4fe..f24d3a4 100644
--- a/cpu/mpc83xx/cpu.c
+++ b/cpu/mpc83xx/cpu.c
@@ -93,6 +93,8 @@ do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
/* enable Reset Control Reg */
immap->reset.rpr = 0x52535445;
+ __asm__ __volatile__ ("sync");
+ __asm__ __volatile__ ("isync");
/* confirm Reset Control Reg is enabled */
while(!((immap->reset.rcer) & RCER_CRE));
@@ -189,3 +191,88 @@ ft_cpu_setup(void *blob, bd_t *bd)
#endif
}
#endif
+
+#if defined(CONFIG_DDR_ECC)
+void dma_init(void)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMRBAR;
+ volatile dma8349_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_IMMRBAR;
+ volatile dma8349_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;
+}
+
+int dma_xfer(void *dest, u32 count, void *src)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMRBAR;
+ volatile dma8349_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);
+
+ __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());
+}
+#endif /*CONFIG_DDR_ECC*/