Commit d5584335 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

added more mrmory regions from CMA

parent ebeecb50
Loading
Loading
Loading
Loading
+182 −61
Original line number Diff line number Diff line
@@ -59,7 +59,18 @@ static struct elphel_buf_t _elphel_buf = {
// Bidirectional stream DMA buffer
	.bidir_vaddr = NULL,
	.bidir_paddr = 0,
	.bidir_size = 1024
	.bidir_size = 1024,

    // Device to host stream DMA buffer for histograms
    .histograms_vaddr = NULL,
    .histograms_paddr = 0,
    .histograms_size = 1024,

    // Device to host stream DMA buffer for the logger
    .logger_vaddr = NULL,
    .logger_paddr = 0,
    .logger_size = 1024

};

struct elphel_buf_t *pElphel_buf; // static can not be extern
@@ -83,40 +94,6 @@ static int __init elphelmem_init(void)
	bufsize_be = (__be32 *)of_get_property(node, "memsize", NULL);
	_elphel_buf.size = be32_to_cpup(bufsize_be);

/*
	// Coherent DMA buffer
	void      *vaddr;
	dma_addr_t paddr;
	ssize_t    size;

	// Host to device stream DMA buffer
	void      *h2d_vaddr;
	dma_addr_t h2d_paddr;
	ssize_t    h2d_size;

	// Device to host stream DMA buffer
	void      *d2h_vaddr;
	dma_addr_t d2h_paddr;
	ssize_t    d2h_size;

	// Bidirectional stream DMA buffer
	void      *bidir_vaddr;
	dma_addr_t bidir_paddr;
	ssize_t    bidir_size;
	_elphel_buf.vaddr = dma_alloc_coherent(NULL,(_elphel_buf.size*PAGE_SIZE),&(_elphel_buf.paddr),GFP_KERNEL);

    if(_elphel_buf.paddr)
    {
    	printk("Allocated %u pages for DMA at address 0x%x\n", (u32)_elphel_buf.size, (u32)_elphel_buf.paddr);
    }
    else printk("ERROR allocating memory buffer");

    http://linuxkernelhacker.blogspot.com/2014/07/arm-dma-mapping-explained.html

*/
	// Alternative way to allocate memory for DMA
	// allocate continuous virtual memory range
//	_elphel_buf.vaddr = kmalloc((_elphel_buf.size*PAGE_SIZE) ,GFP_KERNEL);
	_elphel_buf.vaddr = dma_alloc_coherent(NULL,(_elphel_buf.size*PAGE_SIZE),&(_elphel_buf.paddr),GFP_KERNEL);
    if(_elphel_buf.vaddr) {
    	pr_info("Allocated %u pages for DMA at address 0x%x\n", (u32)_elphel_buf.size, (u32)_elphel_buf.paddr);
@@ -136,6 +113,18 @@ static int __init elphelmem_init(void)
    	pr_err("ERROR allocating D2H DMA memory buffer\n");
    }

    _elphel_buf.histograms_vaddr = kzalloc((_elphel_buf.histograms_size*PAGE_SIZE) ,GFP_KERNEL);
    if (!_elphel_buf.histograms_vaddr){
        _elphel_buf.histograms_size = 0;
        pr_err("ERROR allocating HISTOGRAMS memory buffer\n");
    }

    _elphel_buf.logger_vaddr = kzalloc((_elphel_buf.logger_size*PAGE_SIZE) ,GFP_KERNEL);
    if (!_elphel_buf.logger_vaddr){
        _elphel_buf.logger_size = 0;
        pr_err("ERROR allocating LOGGER memory buffer\n");
    }

    _elphel_buf.bidir_vaddr = kzalloc((_elphel_buf.bidir_size*PAGE_SIZE) ,GFP_KERNEL);
    if (!_elphel_buf.bidir_vaddr){
    	_elphel_buf.bidir_size = 0;
@@ -148,21 +137,13 @@ static int __init elphelmem_init(void)

    return 0;
}
/*
 dma_addr_t
dma_map_single(struct device *dev, void *cpu_addr, size_t size,
		      enum dma_data_direction direction)

 */
static void __exit elphelmem_exit(void)
{
	pr_info("DMA buffer disabled\n");
}



// SYSFS

static ssize_t get_paddr(struct device *dev, struct device_attribute *attr, char *buf)
{
	return sprintf(buf,"0x%x\n", (u32)_elphel_buf.paddr);
@@ -203,6 +184,26 @@ static ssize_t get_size_bidir(struct device *dev, struct device_attribute *attr,
	return sprintf(buf,"%u\n", _elphel_buf.bidir_size);
}

static ssize_t get_paddr_histograms(struct device *dev, struct device_attribute *attr, char *buf)
{
    return sprintf(buf,"0x%x\n", (u32)_elphel_buf.histograms_paddr);
}

static ssize_t get_size_histograms(struct device *dev, struct device_attribute *attr, char *buf)
{
    return sprintf(buf,"%u\n", _elphel_buf.histograms_size);
}
static ssize_t get_paddr_logger(struct device *dev, struct device_attribute *attr, char *buf)
{
    return sprintf(buf,"0x%x\n", (u32)_elphel_buf.logger_paddr);
}

static ssize_t get_size_logger(struct device *dev, struct device_attribute *attr, char *buf)
{
    return sprintf(buf,"%u\n", _elphel_buf.logger_size);
}


static ssize_t sync_for_cpu_h2d(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
	dma_addr_t paddr;
@@ -265,6 +266,7 @@ static ssize_t sync_for_device_d2h(struct device *dev, struct device_attribute *

    return count;
}

static ssize_t sync_for_cpu_bidir(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
	dma_addr_t paddr;
@@ -297,6 +299,72 @@ static ssize_t sync_for_device_bidir(struct device *dev, struct device_attribute
    return count;
}



static ssize_t sync_for_cpu_histograms(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
    dma_addr_t paddr;
    size_t len;
    int num_items;
    num_items=sscanf(buf, "%u %u", &paddr, &len);
    if (num_items<2) {
        paddr =  _elphel_buf.histograms_paddr;
        len = _elphel_buf.histograms_size * PAGE_SIZE;
    }
    pr_info("\naddr=0x%08x, size = 0x%08x\n", paddr, len);
    dma_sync_single_for_cpu(dev, paddr, len, DMA_FROM_DEVICE);

    return count;

}
static ssize_t sync_for_device_histograms(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
    dma_addr_t paddr;
    size_t len;
    int num_items;
    num_items=sscanf(buf, "%u %u", &paddr, &len);
    if (num_items<2) {
        paddr =  _elphel_buf.histograms_paddr;
        len = _elphel_buf.histograms_size * PAGE_SIZE;
    }
    pr_info("\naddr=0x%08x, size = 0x%08x\n", paddr, len);
    dma_sync_single_for_device(dev, paddr, len, DMA_FROM_DEVICE);

    return count;
}
static ssize_t sync_for_cpu_logger(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
    dma_addr_t paddr;
    size_t len;
    int num_items;
    num_items=sscanf(buf, "%u %u", &paddr, &len);
    if (num_items<2) {
        paddr =  _elphel_buf.logger_paddr;
        len = _elphel_buf.logger_size * PAGE_SIZE;
    }
    pr_info("\naddr=0x%08x, size = 0x%08x\n", paddr, len);
    dma_sync_single_for_cpu(dev, paddr, len, DMA_FROM_DEVICE);

    return count;

}
static ssize_t sync_for_device_logger(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
    dma_addr_t paddr;
    size_t len;
    int num_items;
    num_items=sscanf(buf, "%u %u", &paddr, &len);
    if (num_items<2) {
        paddr =  _elphel_buf.logger_paddr;
        len = _elphel_buf.logger_size * PAGE_SIZE;
    }
    pr_info("\naddr=0x%08x, size = 0x%08x\n", paddr, len);
    dma_sync_single_for_device(dev, paddr, len, DMA_FROM_DEVICE);

    return count;
}


static ssize_t get_sync_for_device_h2d(struct device *dev, struct device_attribute *attr, char *buf)
{
	return sprintf(buf,"Write address/length pair into this file to hand this region of the host to device DMA buffer to device (after CPU writes).\n");
@@ -322,6 +390,25 @@ static ssize_t get_sync_for_cpu_bidir(struct device *dev, struct device_attribut
	return sprintf(buf,"Write address/length pair into this file to hand this region of the bidirectional DMA buffer to CPU (before CPU reads).\n");
}


static ssize_t get_sync_for_device_histograms(struct device *dev, struct device_attribute *attr, char *buf)
{
    return sprintf(buf,"Write address/length pair into this file to hand this region of the histograms buffer to device (after CPU writes).\n");
}
static ssize_t get_sync_for_cpu_histograms(struct device *dev, struct device_attribute *attr, char *buf)
{
    return sprintf(buf,"Write address/length pair into this file to hand this region of the histograms buffer to CPU (before CPU reads).\n");
}
static ssize_t get_sync_for_device_logger(struct device *dev, struct device_attribute *attr, char *buf)
{
    return sprintf(buf,"Write address/length pair into this file to hand this region of the logger buffer to device (after CPU writes).\n");
}
static ssize_t get_sync_for_cpu_logger(struct device *dev, struct device_attribute *attr, char *buf)
{
    return sprintf(buf,"Write address/length pair into this file to hand this region of the logger buffer to CPU (before CPU reads).\n");
}


static DEVICE_ATTR(buffer_address,            SYSFS_PERMISSIONS & SYSFS_READONLY, get_paddr,                      NULL);
static DEVICE_ATTR(buffer_pages,              SYSFS_PERMISSIONS & SYSFS_READONLY, get_size,                       NULL);
static DEVICE_ATTR(buffer_address_h2d,        SYSFS_PERMISSIONS & SYSFS_READONLY, get_paddr_h2d,                  NULL);
@@ -330,12 +417,20 @@ static DEVICE_ATTR(buffer_address_d2h, SYSFS_PERMISSIONS & SYSFS_READONLY,
static DEVICE_ATTR(buffer_pages_d2h,          SYSFS_PERMISSIONS & SYSFS_READONLY, get_size_d2h,                   NULL);
static DEVICE_ATTR(buffer_address_bidir,      SYSFS_PERMISSIONS & SYSFS_READONLY, get_paddr_bidir,                NULL);
static DEVICE_ATTR(buffer_pages_bidir,        SYSFS_PERMISSIONS & SYSFS_READONLY, get_size_bidir,                 NULL);
static DEVICE_ATTR(buffer_address_histograms, SYSFS_PERMISSIONS & SYSFS_READONLY, get_paddr_histograms,           NULL);
static DEVICE_ATTR(buffer_pages_histograms,   SYSFS_PERMISSIONS & SYSFS_READONLY, get_size_histograms,            NULL);
static DEVICE_ATTR(buffer_address_logger,     SYSFS_PERMISSIONS & SYSFS_READONLY, get_paddr_logger,               NULL);
static DEVICE_ATTR(buffer_pages_logger,       SYSFS_PERMISSIONS & SYSFS_READONLY, get_size_logger,                NULL);
static DEVICE_ATTR(sync_for_cpu_h2d,          SYSFS_PERMISSIONS,                  get_sync_for_cpu_h2d,           sync_for_cpu_h2d);
static DEVICE_ATTR(sync_for_device_h2d,       SYSFS_PERMISSIONS,                  get_sync_for_device_h2d,        sync_for_device_h2d);
static DEVICE_ATTR(sync_for_cpu_d2h,          SYSFS_PERMISSIONS,                  get_sync_for_cpu_d2h,           sync_for_cpu_d2h);
static DEVICE_ATTR(sync_for_device_d2h,       SYSFS_PERMISSIONS,                  get_sync_for_device_d2h,        sync_for_device_d2h);
static DEVICE_ATTR(sync_for_cpu_bidir,        SYSFS_PERMISSIONS,                  get_sync_for_cpu_bidir,         sync_for_cpu_bidir);
static DEVICE_ATTR(sync_for_device_bidir,     SYSFS_PERMISSIONS,                  get_sync_for_device_bidir,      sync_for_device_bidir);
static DEVICE_ATTR(sync_for_cpu_histograms,   SYSFS_PERMISSIONS,                  get_sync_for_cpu_histograms,    sync_for_cpu_histograms);
static DEVICE_ATTR(sync_for_device_histograms,SYSFS_PERMISSIONS,                  get_sync_for_device_histograms, sync_for_device_histograms);
static DEVICE_ATTR(sync_for_cpu_logger,       SYSFS_PERMISSIONS,                  get_sync_for_cpu_logger,        sync_for_cpu_logger);
static DEVICE_ATTR(sync_for_device_logger,    SYSFS_PERMISSIONS,                  get_sync_for_device_logger,     sync_for_device_logger);

static struct attribute *root_dev_attrs[] = {
		&dev_attr_buffer_address.attr,
@@ -346,12 +441,20 @@ static struct attribute *root_dev_attrs[] = {
		&dev_attr_buffer_pages_d2h.attr,
		&dev_attr_buffer_address_bidir.attr,
		&dev_attr_buffer_pages_bidir.attr,
        &dev_attr_buffer_address_histograms.attr,
        &dev_attr_buffer_pages_histograms.attr,
        &dev_attr_buffer_address_logger.attr,
        &dev_attr_buffer_pages_logger.attr,
		&dev_attr_sync_for_cpu_h2d.attr,
		&dev_attr_sync_for_device_h2d.attr,
		&dev_attr_sync_for_cpu_d2h.attr,
		&dev_attr_sync_for_device_d2h.attr,
		&dev_attr_sync_for_cpu_bidir.attr,
		&dev_attr_sync_for_device_bidir.attr,
        &dev_attr_sync_for_cpu_histograms.attr,
        &dev_attr_sync_for_device_histograms.attr,
        &dev_attr_sync_for_cpu_logger.attr,
        &dev_attr_sync_for_device_logger.attr,
		NULL
};

@@ -379,7 +482,7 @@ static int elphel393_mem_probe(struct platform_device *pdev)
		// mapped as DMA_BIDIRECTIONAL, each time will be synchronized when passing control from soft to hard and back
		pElphel_buf->h2d_paddr = dma_map_single(&pdev->dev, _elphel_buf.h2d_vaddr, (_elphel_buf.h2d_size*PAGE_SIZE), DMA_TO_DEVICE);
		if (!pElphel_buf->h2d_paddr){
			pr_err("ERROR in dma_map_single() for bidirectional buffer\n");
			pr_err("ERROR in dma_map_single() for h2d buffer\n");
			return 0;
		}
//	    printk("H2D DMA buffer location:\t\t0x%08X\n", pElphel_buf->h2d_paddr);
@@ -389,15 +492,27 @@ static int elphel393_mem_probe(struct platform_device *pdev)
		// mapped as DMA_BIDIRECTIONAL, each time will be synchronized when passing control from soft to hard and back
		pElphel_buf->d2h_paddr = dma_map_single(&pdev->dev, _elphel_buf.d2h_vaddr, (_elphel_buf.d2h_size*PAGE_SIZE), DMA_FROM_DEVICE);
		if (!pElphel_buf->d2h_paddr){
			pr_err("ERROR in dma_map_single() for bidirectional buffer\n");
			pr_err("ERROR in dma_map_single() for d2h buffer\n");
			return 0;
		}
//	    printk("D2H DMA buffer location:\t\t0x%08X\n", pElphel_buf->d2h_paddr);
	}

    if (_elphel_buf.histograms_vaddr){
        pElphel_buf->histograms_paddr = dma_map_single(&pdev->dev, _elphel_buf.histograms_vaddr, (_elphel_buf.histograms_size*PAGE_SIZE), DMA_FROM_DEVICE);
        if (!pElphel_buf->histograms_paddr){
            pr_err("ERROR in dma_map_single() for histograms buffer\n");
            return 0;
        }
    }
    if (_elphel_buf.logger_vaddr){
        pElphel_buf->logger_paddr = dma_map_single(&pdev->dev, _elphel_buf.logger_vaddr, (_elphel_buf.logger_size*PAGE_SIZE), DMA_FROM_DEVICE);
        if (!pElphel_buf->logger_paddr){
            pr_err("ERROR in dma_map_single() for the logger buffer\n");
            return 0;
        }
    }

	if (_elphel_buf.bidir_vaddr){
		// mapped as DMA_BIDIRECTIONAL, each time will be synchronized when passing control from soft to hard and back
		pElphel_buf->bidir_paddr = dma_map_single(&pdev->dev, _elphel_buf.bidir_vaddr, (_elphel_buf.bidir_size*PAGE_SIZE), DMA_BIDIRECTIONAL);
		if (!pElphel_buf->bidir_paddr){
			pr_err("ERROR in dma_map_single() for bidirectional buffer\n");
@@ -418,7 +533,13 @@ static int elphel393_mem_probe(struct platform_device *pdev)
    printk("Bidirectional stream buffer paddr:  0x%08X\n",(u32) pElphel_buf -> bidir_paddr);
    printk("Bidirectional stream buffer length: 0x%08X\n",(u32) pElphel_buf -> bidir_size * PAGE_SIZE);

    printk("HISTOGRAMS stream buffer vaddr:     0x%08X\n",(u32) pElphel_buf -> histograms_vaddr);
    printk("HISTOGRAMS stream buffer paddr:     0x%08X\n",(u32) pElphel_buf -> histograms_paddr);
    printk("HISTOGRAMS stream buffer length:    0x%08X\n",(u32) pElphel_buf -> histograms_size * PAGE_SIZE);

    printk("LOGGER stream buffer vaddr:         0x%08X\n",(u32) pElphel_buf -> logger_vaddr);
    printk("LOGGER stream buffer paddr:         0x%08X\n",(u32) pElphel_buf -> logger_paddr);
    printk("LOGGER stream buffer length:        0x%08X\n",(u32) pElphel_buf -> logger_size * PAGE_SIZE);

	return 0;
}
+2 −2
Original line number Diff line number Diff line
@@ -199,8 +199,8 @@ int histograms_init_hardware(void)
    int port, chn;
    x393_hist_saxi_addr_t saxi_addr;
//    fpga_hist_data = (u32 [SENSOR_PORTS][MAX_SENSORS][PARS_FRAMES][4][256]) pElphel_buf->d2h_vaddr; // must be page-aligned!
    fpga_hist_data = (u32 *) pElphel_buf->d2h_vaddr; // must be page-aligned!
    fpga_hist_phys = pElphel_buf->d2h_paddr;
    fpga_hist_data = (u32 *) pElphel_buf->histograms_vaddr; // d2h_vaddr; // must be page-aligned!
    fpga_hist_phys = pElphel_buf->histograms_paddr; //d2h_paddr;
    for (port=0; port<SENSOR_PORTS; port++) for (chn=0; chn < MAX_SENSORS; chn++) {
        saxi_addr.page=(fpga_hist_phys >> PAGE_SHIFT)+ PARS_FRAMES * (chn + MAX_SENSORS *port);// table for 4 colors is exactly 1 page;
        set_x393_hist_saxi_addr (saxi_addr, chn);       // Histogram DMA addresses (in 4096 byte pages)