您尚未登录。

楼主 #1 2018-08-14 12:33:04

达克罗德
会员
注册时间: 2018-04-10
已发帖子: 1,135
积分: 1087.5

谁有V3S或者F1C100s的DMA例程?

当前xboot似乎没有DMA的驱动,我想看看能否把SPI的读写以及memcpy用DMA来加速

离线

楼主 #3 2018-08-14 13:48:32

达克罗德
会员
注册时间: 2018-04-10
已发帖子: 1,135
积分: 1087.5

Re: 谁有V3S或者F1C100s的DMA例程?

非常感谢,你找资源可真快呀!

离线

楼主 #6 2018-08-19 22:23:59

达克罗德
会员
注册时间: 2018-04-10
已发帖子: 1,135
积分: 1087.5

Re: 谁有V3S或者F1C100s的DMA例程?

mianhua 说:

请问显示的时候是不是已经用了DMA?
void fb_present(struct framebuffer_t * fb, struct render_t * render)
{
    struct fb_f1c100s_pdata_t * pdat = (struct fb_f1c100s_pdata_t *)fb->priv;

    if(render && render->pixels)
    {
        pdat->index = (pdat->index + 1) & 0x1;
        memcpy(pdat->vram[pdat->index], render->pixels, render->pixlen);
        dma_cache_sync(pdat->vram[pdat->index], render->pixlen, DMA_TO_DEVICE);
        f1c100s_debe_set_address(pdat, pdat->vram[pdat->index]);
    }
}

这里dma_cache_sync我没有看到dma具体实现,感觉还是靠memcpy软拷贝的

离线

楼主 #7 2018-08-26 23:21:17

达克罗德
会员
注册时间: 2018-04-10
已发帖子: 1,135
积分: 1087.5

Re: 谁有V3S或者F1C100s的DMA例程?

void sys_dma_init()
{
	/* Enable gate for DMA clock, and perform softreset */
	write32(F1C100S_CCU_BASE + CCU_BUS_CLK_GATE0, read32(F1C100S_CCU_BASE + CCU_BUS_CLK_GATE0) | (0x1 << 6));
	write32(F1C100S_CCU_BASE + CCU_BUS_SOFT_RST0, read32(F1C100S_CCU_BASE + CCU_BUS_SOFT_RST0) & ~(0x1 << 6));
	for(int i = 0; i < 10; i++)
		continue;
	write32(F1C100S_CCU_BASE + CCU_BUS_SOFT_RST0, read32(F1C100S_CCU_BASE + CCU_BUS_SOFT_RST0) | (0x1 << 6));
}

void sys_dma_wait_end(int ch)
{
	u32_t cfg_reg = 0x80000000;
	/* when the dma end, it clear this bit automatically */
	while ((cfg_reg & 0x80000000) ) {
		cfg_reg = read32(NDMA_CHANNEL_REG_BASE(ch) +
						NDMA_CFG_REG);
	}
}

void sys_dma_dram_copy(int dma_ch, void * dest, void *src, size_t len)
{
	virtual_addr_t addr = NDMA_CHANNEL_REG_BASE(dma_ch);
	u32_t val = 0;
	u32_t bytes_cnt;

	while(len)
	{
		if(len >= SZ_128K)
		{
			bytes_cnt = SZ_128K;
		}
		else
		{
			bytes_cnt = len;
		}
		len -= bytes_cnt;

		/* Set source address */
		write32(addr + NDMA_SRC_ADR_REG, (u32_t)src);

		/* Set dst address */
		write32(addr + NDMA_DST_ADR_REG, (u32_t)dest);

		/* Set byte number */
		write32(addr + NDMA_BYTE_CNT_REG, bytes_cnt);

		/* Set config and start */
		val = (1 << 31) | (2 << 24) | (1 << 23) | (0x11 << 16) | (2 << 8) | (1 << 7) | (0x11 << 0);
		// val = NDMA_SDRAM2SDRAM_CFG;
		write32(addr + NDMA_CFG_REG, val);

		/* Wait end */
		sys_dma_wait_end(dma_ch);
		src += bytes_cnt;
		dest += bytes_cnt;
	}
}

今天写了个最简单的SDRAM to SDRAM的DMA copy函数,已经调试通过。
注意src需要是用dma_alloc_coherent函数得到的空间才行,估计是cache同步的问题,否则数据有异常。

把这个函数用在framebuffer的拷贝上,替代memcpy,结果发现速度还不如memcpy。估计F1C100S的DMA时钟很慢?另外一个主要原因是DMA一次传输竟然只支持128KB字节,所以不得不CPU polling在这里然后等结束后继续下一个128KB传输,DMA的并行处理机制完全没被充分利用起来。等我有时间了,做个用中断中管理DMA的,才能充分发挥DMA的优势。

下面是带头文件的源程序:
f1c100s-dma.zip

离线

楼主 #9 2018-09-03 11:34:24

达克罗德
会员
注册时间: 2018-04-10
已发帖子: 1,135
积分: 1087.5

Re: 谁有V3S或者F1C100s的DMA例程?

dedicated DMA支持16M字节传输,所以可以简化代码

static void sys_ddma_wait_end(int ch)
{
	u32_t cfg_reg = 0x80000000;
	/* when the dma end, it clear this bit automatically */
	while ((cfg_reg & 0x80000000) ) {
		cfg_reg = read32(DDMA_CHANNEL_REG_BASE(ch) +
						DDMA_CFG_REG);
	}
}

void sys_ddma_dram_copy(int dma_ch, void * dest, void *src, size_t bytes_cnt)
{
	virtual_addr_t base = DDMA_CHANNEL_REG_BASE(dma_ch);
	u32_t val = 0;

	if (bytes_cnt > SZ_16M)
	{
		bytes_cnt = SZ_16M;
	}

	/* Set source address */
	write32(base + DDMA_SRC_ADR_REG, (u32_t)src);

	/* Set dst address */
	write32(base + DDMA_DST_ADR_REG, (u32_t)dest);

	/* Set byte number */
	write32(base + DDMA_BYTE_CNT_REG, bytes_cnt);

	/* Set config and start */
	val = (1 << 31) | (2 << 24) | (1 << 23) | (0x1 << 16) | (2 << 8) | (1 << 7) | (0x1 << 0);
	// val = NDMA_SDRAM2SDRAM_CFG;
	write32(base + DDMA_CFG_REG, val);

	/* Wait end */
	sys_ddma_wait_end(dma_ch);
}

离线

楼主 #17 2020-04-30 15:46:21

达克罗德
会员
注册时间: 2018-04-10
已发帖子: 1,135
积分: 1087.5

Re: 谁有V3S或者F1C100s的DMA例程?

Quotation 说:

@达克罗德 楼主,有没有调通SPI的DMA?(顺便问晕哥,回复帖子能不能强提醒某人?)

没有继续研究了

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn