Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 532f07ca authored by Mike Frysinger's avatar Mike Frysinger
Browse files

Blackfin: fix early_dma_memcpy() handling of busy channels



The early logic to locate a free DMA channel and then set it up was broken
in a few ways that only manifested itself when we needed to set up more
than 2 on chip SRAM regions (most board defaults setup 1 or 2).  First, we
checked the wrong status register (the destination gets updated, not the
source) and second, we did the ssync before rather than after resetting a
DMA config register.

Signed-off-by: default avatarMike Frysinger <vapier@gentoo.org>
parent fb4b5d3a
Loading
Loading
Loading
Loading
+14 −15
Original line number Diff line number Diff line
@@ -253,32 +253,31 @@ void __init early_dma_memcpy(void *pdst, const void *psrc, size_t size)
	BUG_ON(src % 4);
	BUG_ON(size % 4);

	/* Force a sync in case a previous config reset on this channel
	 * occurred.  This is needed so subsequent writes to DMA registers
	 * are not spuriously lost/corrupted.
	 */
	__builtin_bfin_ssync();

	src_ch = 0;
	/* Find an avalible memDMA channel */
	while (1) {
		if (!src_ch || src_ch == (struct dma_register *)MDMA_S1_NEXT_DESC_PTR) {
			dst_ch = (struct dma_register *)MDMA_D0_NEXT_DESC_PTR;
			src_ch = (struct dma_register *)MDMA_S0_NEXT_DESC_PTR;
		} else {
		if (src_ch == (struct dma_register *)MDMA_S0_NEXT_DESC_PTR) {
			dst_ch = (struct dma_register *)MDMA_D1_NEXT_DESC_PTR;
			src_ch = (struct dma_register *)MDMA_S1_NEXT_DESC_PTR;
		} else {
			dst_ch = (struct dma_register *)MDMA_D0_NEXT_DESC_PTR;
			src_ch = (struct dma_register *)MDMA_S0_NEXT_DESC_PTR;
		}

		if (!bfin_read16(&src_ch->cfg)) {
		if (!bfin_read16(&src_ch->cfg))
			break;
		} else {
			if (bfin_read16(&src_ch->irq_status) & DMA_DONE)
		else if (bfin_read16(&dst_ch->irq_status) & DMA_DONE) {
			bfin_write16(&src_ch->cfg, 0);
			break;
		}

	}

	/* Force a sync in case a previous config reset on this channel
	 * occurred.  This is needed so subsequent writes to DMA registers
	 * are not spuriously lost/corrupted.
	 */
	__builtin_bfin_ssync();

	/* Destination */
	bfin_write32(&dst_ch->start_addr, dst);
	bfin_write16(&dst_ch->x_count, size >> 2);