uboot/drivers/dma/fsl_dma.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2004,2007,2008 Freescale Semiconductor, Inc.
   4 * (C) Copyright 2002, 2003 Motorola Inc.
   5 * Xianghua Xiao (X.Xiao@motorola.com)
   6 *
   7 * (C) Copyright 2000
   8 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   9 */
  10
  11#include <config.h>
  12#include <common.h>
  13#include <asm/io.h>
  14#include <asm/fsl_dma.h>
  15
  16/* Controller can only transfer 2^26 - 1 bytes at a time */
  17#define FSL_DMA_MAX_SIZE        (0x3ffffff)
  18
  19#if defined(CONFIG_MPC83xx)
  20#define FSL_DMA_MR_DEFAULT (FSL_DMA_MR_CTM_DIRECT | FSL_DMA_MR_DMSEN)
  21#else
  22#define FSL_DMA_MR_DEFAULT (FSL_DMA_MR_BWC_DIS | FSL_DMA_MR_CTM_DIRECT)
  23#endif
  24
  25
  26#if defined(CONFIG_MPC83xx)
  27dma83xx_t *dma_base = (void *)(CFG_SYS_MPC83xx_DMA_ADDR);
  28#elif defined(CONFIG_MPC85xx)
  29ccsr_dma_t *dma_base = (void *)(CFG_SYS_MPC85xx_DMA_ADDR);
  30#elif defined(CONFIG_MPC86xx)
  31ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC86xx_DMA_ADDR);
  32#else
  33#error "Freescale DMA engine not supported on your processor"
  34#endif
  35
  36static void dma_sync(void)
  37{
  38#if defined(CONFIG_MPC85xx)
  39        asm("sync; isync; msync");
  40#elif defined(CONFIG_MPC86xx)
  41        asm("sync; isync");
  42#endif
  43}
  44
  45static void out_dma32(volatile unsigned *addr, int val)
  46{
  47#if defined(CONFIG_MPC83xx)
  48        out_le32(addr, val);
  49#else
  50        out_be32(addr, val);
  51#endif
  52}
  53
  54static uint in_dma32(volatile unsigned *addr)
  55{
  56#if defined(CONFIG_MPC83xx)
  57        return in_le32(addr);
  58#else
  59        return in_be32(addr);
  60#endif
  61}
  62
  63static uint dma_check(void) {
  64        volatile fsl_dma_t *dma = &dma_base->dma[0];
  65        uint status;
  66
  67        /* While the channel is busy, spin */
  68        do {
  69                status = in_dma32(&dma->sr);
  70        } while (status & FSL_DMA_SR_CB);
  71
  72        /* clear MR[CS] channel start bit */
  73        out_dma32(&dma->mr, in_dma32(&dma->mr) & ~FSL_DMA_MR_CS);
  74        dma_sync();
  75
  76        if (status != 0)
  77                printf ("DMA Error: status = %x\n", status);
  78
  79        return status;
  80}
  81
  82#if !defined(CONFIG_MPC83xx)
  83void dma_init(void) {
  84        volatile fsl_dma_t *dma = &dma_base->dma[0];
  85
  86        out_dma32(&dma->satr, FSL_DMA_SATR_SREAD_SNOOP);
  87        out_dma32(&dma->datr, FSL_DMA_DATR_DWRITE_SNOOP);
  88        out_dma32(&dma->sr, 0xffffffff); /* clear any errors */
  89        dma_sync();
  90}
  91#endif
  92
  93int dmacpy(phys_addr_t dest, phys_addr_t src, phys_size_t count) {
  94        volatile fsl_dma_t *dma = &dma_base->dma[0];
  95        uint xfer_size;
  96
  97        while (count) {
  98                xfer_size = min(FSL_DMA_MAX_SIZE, count);
  99
 100                out_dma32(&dma->dar, (u32) (dest & 0xFFFFFFFF));
 101                out_dma32(&dma->sar, (u32) (src & 0xFFFFFFFF));
 102#if !defined(CONFIG_MPC83xx)
 103                out_dma32(&dma->satr,
 104                        in_dma32(&dma->satr) | (u32)((u64)src >> 32));
 105                out_dma32(&dma->datr,
 106                        in_dma32(&dma->datr) | (u32)((u64)dest >> 32));
 107#endif
 108                out_dma32(&dma->bcr, xfer_size);
 109                dma_sync();
 110
 111                /* Prepare mode register */
 112                out_dma32(&dma->mr, FSL_DMA_MR_DEFAULT);
 113                dma_sync();
 114
 115                /* Start the transfer */
 116                out_dma32(&dma->mr, FSL_DMA_MR_DEFAULT | FSL_DMA_MR_CS);
 117
 118                count -= xfer_size;
 119                src += xfer_size;
 120                dest += xfer_size;
 121
 122                dma_sync();
 123
 124                if (dma_check())
 125                        return -1;
 126        }
 127
 128        return 0;
 129}
 130
 131/*
 132 * 85xx/86xx use dma to initialize SDRAM when !CONFIG_ECC_INIT_VIA_DDRCONTROLLER
 133 */
 134#if ((!defined CONFIG_MPC83xx && defined(CONFIG_DDR_ECC) &&     \
 135        !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)))
 136void dma_meminit(uint size)
 137{
 138        uint *p = 0;
 139        uint i = 0;
 140
 141        for (*p = 0; p < (uint *)(8 * 1024); p++) {
 142                if (((uint)p & 0x1f) == 0)
 143                        ppcDcbz((ulong)p);
 144
 145                *p = (uint)0xDEADBEEF;
 146
 147                if (((uint)p & 0x1c) == 0x1c)
 148                        ppcDcbf((ulong)p);
 149        }
 150
 151        dmacpy(0x002000, 0, 0x002000); /* 8K */
 152        dmacpy(0x004000, 0, 0x004000); /* 16K */
 153        dmacpy(0x008000, 0, 0x008000); /* 32K */
 154        dmacpy(0x010000, 0, 0x010000); /* 64K */
 155        dmacpy(0x020000, 0, 0x020000); /* 128K */
 156        dmacpy(0x040000, 0, 0x040000); /* 256K */
 157        dmacpy(0x080000, 0, 0x080000); /* 512K */
 158        dmacpy(0x100000, 0, 0x100000); /* 1M */
 159        dmacpy(0x200000, 0, 0x200000); /* 2M */
 160        dmacpy(0x400000, 0, 0x400000); /* 4M */
 161
 162        for (i = 1; i < size / 0x800000; i++)
 163                dmacpy((0x800000 * i), 0, 0x800000);
 164}
 165#endif
 166