// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright 2004,2007,2008 Freescale Semiconductor, Inc.
 * (C) Copyright 2002, 2003 Motorola Inc.
 * Xianghua Xiao (X.Xiao@motorola.com)
 *
 * (C) Copyright 2000
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 */

#include <config.h>
#include <asm/io.h>
#include <asm/fsl_dma.h>

/* Controller can only transfer 2^26 - 1 bytes at a time */
#define FSL_DMA_MAX_SIZE	(0x3ffffff)

#if defined(CONFIG_MPC83xx)
#define FSL_DMA_MR_DEFAULT (FSL_DMA_MR_CTM_DIRECT | FSL_DMA_MR_DMSEN)
#else
#define FSL_DMA_MR_DEFAULT (FSL_DMA_MR_BWC_DIS | FSL_DMA_MR_CTM_DIRECT)
#endif


#if defined(CONFIG_MPC83xx)
dma83xx_t *dma_base = (void *)(CFG_SYS_MPC83xx_DMA_ADDR);
#elif defined(CONFIG_MPC85xx)
ccsr_dma_t *dma_base = (void *)(CFG_SYS_MPC85xx_DMA_ADDR);
#elif defined(CONFIG_MPC86xx)
ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC86xx_DMA_ADDR);
#else
#error "Freescale DMA engine not supported on your processor"
#endif

static void dma_sync(void)
{
#if defined(CONFIG_MPC85xx)
	asm("sync; isync; msync");
#elif defined(CONFIG_MPC86xx)
	asm("sync; isync");
#endif
}

static void out_dma32(volatile unsigned *addr, int val)
{
#if defined(CONFIG_MPC83xx)
	out_le32(addr, val);
#else
	out_be32(addr, val);
#endif
}

static uint in_dma32(volatile unsigned *addr)
{
#if defined(CONFIG_MPC83xx)
	return in_le32(addr);
#else
	return in_be32(addr);
#endif
}

static uint dma_check(void) {
	volatile fsl_dma_t *dma = &dma_base->dma[0];
	uint status;

	/* While the channel is busy, spin */
	do {
		status = in_dma32(&dma->sr);
	} while (status & FSL_DMA_SR_CB);

	/* clear MR[CS] channel start bit */
	out_dma32(&dma->mr, in_dma32(&dma->mr) & ~FSL_DMA_MR_CS);
	dma_sync();

	if (status != 0)
		printf ("DMA Error: status = %x\n", status);

	return status;
}

#if !defined(CONFIG_MPC83xx)
void dma_init(void) {
	volatile fsl_dma_t *dma = &dma_base->dma[0];

	out_dma32(&dma->satr, FSL_DMA_SATR_SREAD_SNOOP);
	out_dma32(&dma->datr, FSL_DMA_DATR_DWRITE_SNOOP);
	out_dma32(&dma->sr, 0xffffffff); /* clear any errors */
	dma_sync();
}
#endif

int dmacpy(phys_addr_t dest, phys_addr_t src, phys_size_t count) {
	volatile fsl_dma_t *dma = &dma_base->dma[0];
	uint xfer_size;

	while (count) {
		xfer_size = min(FSL_DMA_MAX_SIZE, count);

		out_dma32(&dma->dar, (u32) (dest & 0xFFFFFFFF));
		out_dma32(&dma->sar, (u32) (src & 0xFFFFFFFF));
#if !defined(CONFIG_MPC83xx)
		out_dma32(&dma->satr,
			in_dma32(&dma->satr) | (u32)((u64)src >> 32));
		out_dma32(&dma->datr,
			in_dma32(&dma->datr) | (u32)((u64)dest >> 32));
#endif
		out_dma32(&dma->bcr, xfer_size);
		dma_sync();

		/* Prepare mode register */
		out_dma32(&dma->mr, FSL_DMA_MR_DEFAULT);
		dma_sync();

		/* Start the transfer */
		out_dma32(&dma->mr, FSL_DMA_MR_DEFAULT | FSL_DMA_MR_CS);

		count -= xfer_size;
		src += xfer_size;
		dest += xfer_size;

		dma_sync();

		if (dma_check())
			return -1;
	}

	return 0;
}

/*
 * 85xx/86xx use dma to initialize SDRAM when !CONFIG_ECC_INIT_VIA_DDRCONTROLLER
 */
#if ((!defined CONFIG_MPC83xx && defined(CONFIG_DDR_ECC) &&	\
	!defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)))
void dma_meminit(uint size)
{
	uint *p = 0;
	uint i = 0;

	for (*p = 0; p < (uint *)(8 * 1024); p++) {
		if (((uint)p & 0x1f) == 0)
			ppcDcbz((ulong)p);

		*p = (uint)0xDEADBEEF;

		if (((uint)p & 0x1c) == 0x1c)
			ppcDcbf((ulong)p);
	}

	dmacpy(0x002000, 0, 0x002000); /* 8K */
	dmacpy(0x004000, 0, 0x004000); /* 16K */
	dmacpy(0x008000, 0, 0x008000); /* 32K */
	dmacpy(0x010000, 0, 0x010000); /* 64K */
	dmacpy(0x020000, 0, 0x020000); /* 128K */
	dmacpy(0x040000, 0, 0x040000); /* 256K */
	dmacpy(0x080000, 0, 0x080000); /* 512K */
	dmacpy(0x100000, 0, 0x100000); /* 1M */
	dmacpy(0x200000, 0, 0x200000); /* 2M */
	dmacpy(0x400000, 0, 0x400000); /* 4M */

	for (i = 1; i < size / 0x800000; i++)
		dmacpy((0x800000 * i), 0, 0x800000);
}
#endif
