예제 #1
0
int test(void)
{
	dma_set_pc(DMA_PHYS, 0, dma_program1);
	dma_set_source_address(DMA_PHYS, 0, (uint64_t)source1);
	dma_set_dest_address(DMA_PHYS, 0, (uint64_t)dest1);

	dma_start_transfer(DMA_PHYS, 0);

	//We can set up the new transfer whilst the old transfer is happening.

	dma_set_pc(DMA_PHYS, 0, dma_program2);
	dma_set_source_address(DMA_PHYS, 0, (uint64_t)source2);
	dma_set_dest_address(DMA_PHYS, 0, (uint64_t)dest2);

	while (!dma_thread_ready(DMA_PHYS, 0)) {
		DEBUG_NOP();
		DEBUG_NOP();
		DEBUG_NOP();
		DEBUG_NOP();
	}

	dma_start_transfer(DMA_PHYS, 0);

	while (!dma_thread_ready(DMA_PHYS, 0)) {
		DEBUG_NOP();
		DEBUG_NOP();
		DEBUG_NOP();
		DEBUG_NOP();
	}

	assert(dest1[0] == 0xBE);
	assert(dest2[0] == 0xDEADBEEF);

	return 0;
}
예제 #2
0
int test(void)
{
	dma_set_pc(DMA_PHYS, 0, dma_program);
	dma_set_source_address(DMA_PHYS, 0, (uint64_t)(source + 2));
	dma_set_dest_address(DMA_PHYS, 0, (uint64_t)(dest + 2));

	dma_start_transfer(DMA_PHYS, 0);

	while (!dma_thread_ready(DMA_PHYS, 0)) {
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
	}

	assert(dest[0] == -1);
	assert(dest[1] == -1);
	assert(dest[2] == -2);

	return 0;
}
예제 #3
0
int test(void)
{
	dma_set_pc(DMA_PHYS, 0, dma_program);
	dma_set_source_address(DMA_PHYS, 0, (uint64_t)source);
	dma_set_dest_address(DMA_PHYS, 0, (uint64_t)dest);

	dma_start_transfer(DMA_PHYS, 0);

	while(!dma_thread_ready(DMA_PHYS, 0)) {
		asm("nop");
		asm("nop");
		asm("nop");
		asm("nop");
	}

	assert(dest[0] == 1);
	assert(dest[3] == 2);
	assert(dest[7] == 3);
	assert(dest[8] == 0xBEEF);

	return 0;
}
예제 #4
0
/*
 * Kernel thread that processes the update requests
 */
static void test_thread(void)
{
	struct test_cfg *cfg = &gCfg;
	unsigned int i;
	int rc;
	void *virt_addr;
	enum dma_data_direction dir;
	dma_addr_t devPhysAddr;
	unsigned long time_left;
	unsigned long trials = 0;

	if (!cfg->setup_is_done) {
		printk(KERN_ERR
		       "Need to set up parameters before running the test\n");
		return;
	}

	cfg->kill_thread = 0;
	cfg->in_use = 1;

	/* allocate memory for dstination and source */
	cfg->src_ptr = alloc_mem(&cfg->src_addr, cfg->len, cfg->src_type);
	if (cfg->src_ptr == NULL) {
		printk(KERN_ERR "alloc_mem for src failed\n");
		goto exit_free_mem;
	}

	cfg->dst_ptr = alloc_mem(&cfg->dst_addr, cfg->len, cfg->dst_type);
	if (cfg->dst_ptr == NULL) {
		printk(KERN_ERR "alloc_mem for dst failed\n");
		goto exit_free_mem;
	}

	/* init mmap */
	rc = dma_mmap_init_map(&cfg->mmap_cfg);
	if (rc < 0) {
		printk(KERN_ERR "dma_mmap_init_map failed\n");
		goto exit_free_mem;
	}

	if (cfg->dir) {		/* mem-to-dev, map src memory */
		virt_addr = cfg->src_ptr;
		dir = DMA_TO_DEVICE;
		devPhysAddr = cfg->dst_addr;
	} else {		/* dev-to-mem, map dst memory */

		virt_addr = cfg->dst_ptr;
		dir = DMA_FROM_DEVICE;
		devPhysAddr = cfg->src_addr;
	}

	daemonize(MODULE_NAME);
	allow_signal(SIGKILL);

	for (;;) {
		/* driver shutting down... let's quit the kthread */
		if (cfg->kill_thread)
			goto exit_term_mmap;

		if (signal_pending(current))
			goto exit_term_mmap;

		/* write some values into the source buffer */
		for (i = 0; i < cfg->len; i++) {
			((unsigned char *)cfg->src_ptr)[i] = cnt++;
		}

		/* clear the destination buffer */
		memset(cfg->dst_ptr, 0, cfg->len);

		/* map memories */
		rc = dma_mmap_map(&cfg->mmap_cfg, virt_addr, cfg->len, dir);
		if (rc < 0) {
			printk(KERN_ERR "dma_mmap_map failed\n");
			goto exit_term_mmap;
		}

		/* reserve the DMA channel and set up descriptors */
		if (cfg->dma_type == DMA_TYPE_SDMA) {
			cfg->sdma_hdl = sdma_request_channel(cfg->device);
			if (cfg->sdma_hdl < 0) {
				printk(KERN_ERR
				       "sdma_request_channel failed\n");
				goto exit_unmap;
			}

			rc = sdma_map_create_descriptor_ring(cfg->sdma_hdl,
							     &cfg->mmap_cfg,
							     devPhysAddr,
							     DMA_UPDATE_MODE_INC);
			if (rc < 0) {
				printk(KERN_ERR "create desc ring failed\n");
				goto exit_free_dma_channel;
			}
		} else {
			printk(KERN_ERR "only support SDMA for now\n");
			rc = -EINVAL;
			goto exit_unmap;
#if 0
			cfg->dma_hdl = dma_request_channel(cfg->device);
			if (cfg->dma_hdl < 0) {
				printk(KERN_ERR "dma_request_channel failed\n");
				goto exit_unmap;
			}

			rc = dma_map_create_descriptor_ring(cfg->device,
							    &cfg->mmap_cfg,
							    devPhysAddr,
							    DMA_UPDATE_MODE_INC);
			if (rc < 0) {
				printk(KERN_ERR "create desc ring failed\n");
				goto exit_free_dma_channel;
			}
#endif
		}

		/* set DMA interrupt handler */
		rc = set_dev_handler(cfg);
		if (rc < 0) {
			printk(KERN_ERR "set_dev_handler failed\n");
			goto exit_free_dma_channel;
		}

		INIT_COMPLETION(cfg->dma_done);

		if (cfg->dma_type == DMA_TYPE_SDMA) {
			rc = sdma_start_transfer(cfg->sdma_hdl);
			if (rc < 0) {
				printk(KERN_ERR "sdma_transfer failed\n");
				goto exit_free_dma_channel;
			}
		}
#if 0
		else {		/* synopsys DMA */

			rc = dma_start_transfer(cfg->dma_hdl, cfg->len);
			if (rc < 0) {
				printk(KERN_ERR "dma_start_transfer failed\n");
				goto exit_free_dma_channel;
			}
		}
#endif

		time_left =
		    wait_for_completion_timeout(&cfg->dma_done, TIMEOUT_TIME);
		if (time_left == 0) {
			printk(KERN_ERR
			       "DMA MMAP test timeout after %lu trials\n",
			       trials);
			goto exit_free_dma_channel;
		}

		/* free DMA channel and unmap memory */
		if (cfg->dma_type == DMA_TYPE_SDMA)
			sdma_free_channel(cfg->sdma_hdl);
#if 0
		else
			dma_free_channel(cfg->dma_hdl);
#endif

		dma_mmap_unmap(&cfg->mmap_cfg, 0);

		/* verify the result */
		for (i = 0; i < cfg->len; i++) {
			if (((unsigned char *)cfg->src_ptr)[i] !=
			    ((unsigned char *)cfg->dst_ptr)[i]) {
				printk(KERN_ERR
				       "src[%u]=%u != dst[%u]=%u trials=%lu\n",
				       i, ((unsigned char *)cfg->src_ptr)[i], i,
				       ((unsigned char *)cfg->dst_ptr)[i],
				       trials);
				goto exit_term_mmap;
			}
		}

		trials++;
	}

exit_free_dma_channel:
	if (cfg->dma_type == DMA_TYPE_SDMA)
		sdma_free_channel(cfg->sdma_hdl);
#if 0
	else
		dma_free_channel(cfg->dma_hdl);
#endif

exit_unmap:
	dma_mmap_unmap(&cfg->mmap_cfg, 0);

exit_term_mmap:
	dma_mmap_term_map(&cfg->mmap_cfg);

exit_free_mem:
	if (cfg->src_ptr) {
		free_mem(cfg->src_ptr, cfg->src_addr, cfg->len, cfg->src_type);
		cfg->src_ptr = NULL;
	}

	if (cfg->dst_ptr) {
		free_mem(cfg->dst_ptr, cfg->dst_addr, cfg->len, cfg->dst_type);
		cfg->dst_ptr = NULL;
	}

	cfg->thread = NULL;
	cfg->in_use = 0;
	cfg->kill_thread = 0;

	printk(KERN_INFO "Quitted test thread\n");
}