Commit 24d7f26b authored by Oleg Dzhimiev's avatar Oleg Dzhimiev

+ run membridge via sysfs file

parent 1f97a843
...@@ -92,7 +92,6 @@ static struct elphel_video_buf_t buffer_settings = { ///< some default settings, ...@@ -92,7 +92,6 @@ static struct elphel_video_buf_t buffer_settings = { ///< some default settings,
.frames_in_buffer = { 2, 2, 2, 2} /* Number of frames in channel 3 buffer */ .frames_in_buffer = { 2, 2, 2, 2} /* Number of frames in channel 3 buffer */
}; };
static int membridge_sensor_port = 0; // 0..3
static int membridge_direction = 0; // 0 - from pl to ps, 1 - from ps to pl static int membridge_direction = 0; // 0 - from pl to ps, 1 - from ps to pl
static int hardware_initialized = 0; static int hardware_initialized = 0;
...@@ -105,6 +104,12 @@ int setup_membridge_system_memory( ...@@ -105,6 +104,12 @@ int setup_membridge_system_memory(
int width64) ///< Frame width in QWORDs (last xfer in each line may be partial) int width64) ///< Frame width in QWORDs (last xfer in each line may be partial)
{ {
u29_t lo_addr = {.d32=0};
u29_t size = {.d32=0};
u29_t start = {.d32=0};
u29_t len = {.d32=0};
u29_t width = {.d32=0};
// no need to wait for anything // no need to wait for anything
pr_debug("setup_membridge_system_memory: lo_addr64=0x%08x size64=0x%08x start64=0x%08x len64=0x%08x width64=0x%08x\n", pr_debug("setup_membridge_system_memory: lo_addr64=0x%08x size64=0x%08x start64=0x%08x len64=0x%08x width64=0x%08x\n",
lo_addr64, lo_addr64,
...@@ -113,12 +118,6 @@ int setup_membridge_system_memory( ...@@ -113,12 +118,6 @@ int setup_membridge_system_memory(
len64, len64,
width64); width64);
u29_t lo_addr = {.d32=0};
u29_t size = {.d32=0};
u29_t start = {.d32=0};
u29_t len = {.d32=0};
u29_t width = {.d32=0};
lo_addr.addr64 = lo_addr64; lo_addr.addr64 = lo_addr64;
size.addr64 = size64; size.addr64 = size64;
start.addr64 = start64; start.addr64 = start64;
...@@ -664,11 +663,9 @@ u16 get_memchannel_priority(int chn) ///< Memory channel (0..16). When usi ...@@ -664,11 +663,9 @@ u16 get_memchannel_priority(int chn) ///< Memory channel (0..16). When usi
/** @brief Videomem buffer private data */ /** @brief Videomem buffer private data */
struct raw_priv_t { struct raw_priv_t {
int minor; ///< device file minor number int sensor_port; ///< sensor number
int sensor_num; ///< sensor number
unsigned long *buf_ptr; ///< pointer to raw buffer memory region unsigned long *buf_ptr; ///< pointer to raw buffer memory region
unsigned long buf_size; ///< circular region size in bytes unsigned long buf_size; ///< circular region size in bytes
unsigned long buf_size32; ///< circular region size in dwords
dma_addr_t phys_addr; ///< physical address of memory region reported by memory driver dma_addr_t phys_addr; ///< physical address of memory region reported by memory driver
}; };
...@@ -677,16 +674,43 @@ static inline int membridge_is_busy(void){ ...@@ -677,16 +674,43 @@ static inline int membridge_is_busy(void){
return status.busy; return status.busy;
} }
int membridge_start(struct file * file){ int membridge_start(int sensor_port, unsigned long target_frame){
struct raw_priv_t * privData = (struct raw_priv_t*) file -> private_data;
int p_color, p_pf_height; int p_color, p_pf_height;
int width_marg, height_marg, width_bursts; int width_marg, height_marg, width_bursts;
int frame_number;
dma_addr_t phys_addr;
unsigned long buf_size;
x393_status_membridge_t status; x393_status_membridge_t status;
// wait for target frame here
waitFrame(sensor_port,target_frame);
// update sizes (local vars)
switch(sensor_port){
case 0:
phys_addr = pElphel_buf->raw_chn0_paddr;
buf_size = pElphel_buf->raw_chn0_size*PAGE_SIZE;
break;
case 1:
phys_addr = pElphel_buf->raw_chn1_paddr;
buf_size = pElphel_buf->raw_chn1_size*PAGE_SIZE;
break;
case 2:
phys_addr = pElphel_buf->raw_chn2_paddr;
buf_size = pElphel_buf->raw_chn2_size*PAGE_SIZE;
break;
case 3:
phys_addr = pElphel_buf->raw_chn3_paddr;
buf_size = pElphel_buf->raw_chn3_size*PAGE_SIZE;
break;
default:
// temporary
phys_addr = pElphel_buf->raw_chn0_paddr;
buf_size = pElphel_buf->raw_chn0_size*PAGE_SIZE;
}
spin_lock(&membridge_lock); spin_lock(&membridge_lock);
if (membridge_locked==0){ if (membridge_locked==0){
membridge_locked=1; membridge_locked=1;
...@@ -696,54 +720,44 @@ int membridge_start(struct file * file){ ...@@ -696,54 +720,44 @@ int membridge_start(struct file * file){
} }
spin_unlock(&membridge_lock); spin_unlock(&membridge_lock);
// no need width_marg = get_imageParamsThis(sensor_port,P_ACTUAL_WIDTH);
frame_number = GLOBALPARS(privData->sensor_num,G_THIS_FRAME) & PARS_FRAMES_MASK; height_marg = get_imageParamsThis(sensor_port,P_ACTUAL_HEIGHT);
//calculate things p_color = get_imageParamsThis(sensor_port,P_COLOR);
p_pf_height = get_imageParamsThis(sensor_port,P_PF_HEIGHT);
//if (frame16 >= PARS_FRAMES) return -1; // wrong frame
width_marg = get_imageParamsThis(privData->sensor_num,P_ACTUAL_WIDTH);
height_marg = get_imageParamsThis(privData->sensor_num,P_ACTUAL_HEIGHT);
p_color = get_imageParamsThis(membridge_sensor_port,P_COLOR);
p_pf_height = get_imageParamsThis(privData->sensor_num,P_PF_HEIGHT);
switch(p_color){ switch(p_color){
case COLORMODE_COLOR: case COLORMODE_COLOR:
case COLORMODE_COLOR20: case COLORMODE_COLOR20:
width_marg += (2 * COLOR_MARGINS); width_marg += (2 * COLOR_MARGINS);
if ((p_pf_height & 0xffff)==0) { // not a photofinish if ((p_pf_height & 0xffff)==0) { // not a photofinish
height_marg += (2 * COLOR_MARGINS); height_marg += (2 * COLOR_MARGINS);
}
break;
} }
break; width_bursts = (width_marg >> 4) + ((width_marg & 0xf) ? 1 : 0);
}
width_bursts = (width_marg >> 4) + ((width_marg & 0xf) ? 1 : 0); setup_membridge_memory(sensor_port, ///< sensor port number (0..3)
/** shorter version: */ 0, ///< 0 - from fpga mem to system mem, 1 - otherwise
//width_bursts = (width_marg+0xf)>>4; width_bursts, ///< 13-bit - in 8*16=128 bit bursts
height_marg, ///< 16-bit window height (in scan lines)
setup_membridge_memory(privData->sensor_num, ///< sensor port number (0..3) 0, ///< 13-bit window left margin in 8-bursts (16 bytes)
0, ///< 0 - from fpga mem to system mem, 1 - otherwise 0, ///< 16-bit window top margin (in scan lines)
width_bursts, ///< 13-bit - in 8*16=128 bit bursts 0, ///< START X ...
height_marg, ///< 16-bit window height (in scan lines) 0, ///< START Y ...
0, ///< 13-bit window left margin in 8-bursts (16 bytes) DIRECT, ///< how to apply commands - directly or through channel sequencer
0, ///< 16-bit window top margin (in scan lines) target_frame); ///< Frame number the command should be applied to (if not immediate mode)
0, ///< START X ...
0, ///< START Y ... // setup membridge system memory - everything is in QW
DIRECT, ///< how to apply commands - directly or through channel sequencer setup_membridge_system_memory(
frame_number); ///< Frame number the command should be applied to (if not immediate mode) phys_addr>>3,
buf_size>>3,
// setup membridge system memory - everything is in QW 0, // start offset?
setup_membridge_system_memory( (width_bursts<<1)*height_marg,
(privData->phys_addr)>>3, (width_bursts<<1)
(privData->buf_size)>>3, );
0, // start offset?
(width_bursts<<1)*height_marg, control_membridge_memory(sensor_port,1,DIRECT,target_frame);
(width_bursts<<1)
);
control_membridge_memory(membridge_sensor_port,1,DIRECT,frame_number);
status = x393_membridge_status(); status = x393_membridge_status();
pr_debug("membridge status is %d\n",status.busy); pr_debug("membridge status is %d\n",status.busy);
...@@ -774,7 +788,7 @@ int membridge_start(struct file * file){ ...@@ -774,7 +788,7 @@ int membridge_start(struct file * file){
//// get frame sizes //// get frame sizes
//unsigned long get_imageParamsPast(int sensor_port, int n, int frame); //unsigned long get_imageParamsPast(int sensor_port, int n, int frame);
return 0; return 0;
} }
/** /**
...@@ -837,10 +851,9 @@ loff_t videomem_lseek(struct file * file, loff_t offset, int orig){ ...@@ -837,10 +851,9 @@ loff_t videomem_lseek(struct file * file, loff_t offset, int orig){
unsigned long target_frame; unsigned long target_frame;
struct raw_priv_t * privData = (struct raw_priv_t*) file -> private_data; struct raw_priv_t * privData = (struct raw_priv_t*) file -> private_data;
int sensor_port = privData->sensor_num; int sensor_port = privData->sensor_port;
//sec_usec_t sec_usec; //sec_usec_t sec_usec;
int res; int res;
x393_status_membridge_t status;
pr_debug("(videomem_lseek) offset=0x%x, orig=0x%x, sensor_port = %d\n", (int)offset, (int)orig, sensor_port); pr_debug("(videomem_lseek) offset=0x%x, orig=0x%x, sensor_port = %d\n", (int)offset, (int)orig, sensor_port);
...@@ -861,15 +874,7 @@ loff_t videomem_lseek(struct file * file, loff_t offset, int orig){ ...@@ -861,15 +874,7 @@ loff_t videomem_lseek(struct file * file, loff_t offset, int orig){
} else { } else {
target_frame = offset; target_frame = offset;
waitFrame(sensor_port,target_frame); res = membridge_start(sensor_port,target_frame);
status = x393_membridge_status();
if (status.busy) {
return -EBUSY;
}
res = membridge_start(file);
if (res<0) return res; if (res<0) return res;
} }
...@@ -893,6 +898,9 @@ int videomem_open(struct inode *inode, struct file *filp) ...@@ -893,6 +898,9 @@ int videomem_open(struct inode *inode, struct file *filp)
{ {
struct raw_priv_t *privData; struct raw_priv_t *privData;
int minor;
int sensor_port;
// to enable interrupt // to enable interrupt
x393_membridge_ctrl_irq_t membridge_irq_en = {.d32=0}; x393_membridge_ctrl_irq_t membridge_irq_en = {.d32=0};
membridge_irq_en.interrupt_cmd = MEMBRIDGE_CMD_IRQ_EN; membridge_irq_en.interrupt_cmd = MEMBRIDGE_CMD_IRQ_EN;
...@@ -918,18 +926,18 @@ int videomem_open(struct inode *inode, struct file *filp) ...@@ -918,18 +926,18 @@ int videomem_open(struct inode *inode, struct file *filp)
} }
filp->private_data = privData; filp->private_data = privData;
privData->minor = MINOR(inode->i_rdev); minor = MINOR(inode->i_rdev);
membridge_sensor_port = privData->minor - DEV393_MINOR(DEV393_IMAGE_RAW0); sensor_port = minor - DEV393_MINOR(DEV393_IMAGE_RAW0);
// temporary // temporary
if (membridge_sensor_port < 0){ if (sensor_port < 0){
membridge_sensor_port = 0; sensor_port = 0;
} }
privData->sensor_num = membridge_sensor_port; privData->sensor_port = sensor_port;
switch(privData->minor){ switch(minor){
case DEV393_MINOR(DEV393_IMAGE_RAW0): case DEV393_MINOR(DEV393_IMAGE_RAW0):
privData->buf_ptr = pElphel_buf->raw_chn0_vaddr; privData->buf_ptr = pElphel_buf->raw_chn0_vaddr;
privData->phys_addr = pElphel_buf->raw_chn0_paddr; privData->phys_addr = pElphel_buf->raw_chn0_paddr;
...@@ -957,10 +965,8 @@ int videomem_open(struct inode *inode, struct file *filp) ...@@ -957,10 +965,8 @@ int videomem_open(struct inode *inode, struct file *filp)
privData->buf_size = pElphel_buf->raw_chn0_size*PAGE_SIZE; privData->buf_size = pElphel_buf->raw_chn0_size*PAGE_SIZE;
} }
privData->buf_size32 = (privData->buf_size)>>2;
// TODO: remove once lseek is tested // TODO: remove once lseek is tested
membridge_start(filp); //membridge_start(sensor_port,0);
return 0; return 0;
} }
...@@ -989,7 +995,6 @@ int videomem_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -989,7 +995,6 @@ int videomem_mmap(struct file *file, struct vm_area_struct *vma)
{ {
int ret; int ret;
struct raw_priv_t * privData = (struct raw_priv_t*) file -> private_data; struct raw_priv_t * privData = (struct raw_priv_t*) file -> private_data;
unsigned int chn = privData->sensor_num;
dev_dbg(g_dev_ptr, "vm_start = 0x%lx\n", vma->vm_start); dev_dbg(g_dev_ptr, "vm_start = 0x%lx\n", vma->vm_start);
dev_dbg(g_dev_ptr, "vm_end = 0x%lx\n", vma->vm_end); dev_dbg(g_dev_ptr, "vm_end = 0x%lx\n", vma->vm_end);
...@@ -1084,10 +1089,6 @@ static ssize_t show_frames_in_buffer(struct device *dev, struct device_attribute ...@@ -1084,10 +1089,6 @@ static ssize_t show_frames_in_buffer(struct device *dev, struct device_attribute
{ {
return sprintf(buf,"0x%x\n", buffer_settings.frames_in_buffer[get_channel_from_name(attr)]); return sprintf(buf,"0x%x\n", buffer_settings.frames_in_buffer[get_channel_from_name(attr)]);
} }
static ssize_t get_num_sensor(struct device *dev, struct device_attribute *attr, char *buf)
{
return sprintf(buf,"%d\n", membridge_sensor_port);
}
static ssize_t get_membridge_status(struct device *dev, struct device_attribute *attr, char *buf) static ssize_t get_membridge_status(struct device *dev, struct device_attribute *attr, char *buf)
{ {
...@@ -1116,12 +1117,6 @@ static ssize_t store_frames_in_buffer(struct device *dev, struct device_attribut ...@@ -1116,12 +1117,6 @@ static ssize_t store_frames_in_buffer(struct device *dev, struct device_attribut
return count; return count;
} }
static ssize_t set_num_sensor(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
sscanf(buf, "%i", &membridge_sensor_port);
return count;
}
static ssize_t set_membridge_status_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) static ssize_t set_membridge_status_reg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{ {
int in; int in;
...@@ -1135,6 +1130,41 @@ static ssize_t set_membridge_status_reg(struct device *dev, struct device_attrib ...@@ -1135,6 +1130,41 @@ static ssize_t set_membridge_status_reg(struct device *dev, struct device_attrib
return count; return count;
} }
static ssize_t set_membridge0(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int sensor_port = 0;
unsigned long target_frame;
sscanf(buf, "%lu", &target_frame);
membridge_start(sensor_port,target_frame);
return count;
}
static ssize_t set_membridge1(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int sensor_port = 1;
unsigned long target_frame;
sscanf(buf, "%lu", &target_frame);
membridge_start(sensor_port,target_frame);
return count;
}
static ssize_t set_membridge2(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int sensor_port = 2;
unsigned long target_frame;
sscanf(buf, "%lu", &target_frame);
membridge_start(sensor_port,target_frame);
return count;
}
static ssize_t set_membridge3(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int sensor_port = 3;
unsigned long target_frame;
sscanf(buf, "%lu", &target_frame);
membridge_start(sensor_port,target_frame);
return count;
}
static DEVICE_ATTR(frame_start0, SYSFS_PERMISSIONS, show_frame_start, store_frame_start); static DEVICE_ATTR(frame_start0, SYSFS_PERMISSIONS, show_frame_start, store_frame_start);
static DEVICE_ATTR(frame_start1, SYSFS_PERMISSIONS, show_frame_start, store_frame_start); static DEVICE_ATTR(frame_start1, SYSFS_PERMISSIONS, show_frame_start, store_frame_start);
...@@ -1152,11 +1182,12 @@ static DEVICE_ATTR(frames_in_buffer0, SYSFS_PERMISSIONS, show_frame ...@@ -1152,11 +1182,12 @@ static DEVICE_ATTR(frames_in_buffer0, SYSFS_PERMISSIONS, show_frame
static DEVICE_ATTR(frames_in_buffer1, SYSFS_PERMISSIONS, show_frames_in_buffer, store_frames_in_buffer); static DEVICE_ATTR(frames_in_buffer1, SYSFS_PERMISSIONS, show_frames_in_buffer, store_frames_in_buffer);
static DEVICE_ATTR(frames_in_buffer2, SYSFS_PERMISSIONS, show_frames_in_buffer, store_frames_in_buffer); static DEVICE_ATTR(frames_in_buffer2, SYSFS_PERMISSIONS, show_frames_in_buffer, store_frames_in_buffer);
static DEVICE_ATTR(frames_in_buffer3, SYSFS_PERMISSIONS, show_frames_in_buffer, store_frames_in_buffer); static DEVICE_ATTR(frames_in_buffer3, SYSFS_PERMISSIONS, show_frames_in_buffer, store_frames_in_buffer);
static DEVICE_ATTR(membridge_status, SYSFS_PERMISSIONS, get_membridge_status, set_membridge_status_reg);
// selected sensor channel == port static DEVICE_ATTR(membridge_status, SYSFS_PERMISSIONS, get_membridge_status, set_membridge_status_reg);
// TODO: switch to multiple device files and remove this static DEVICE_ATTR(membridge_start0, SYSFS_PERMISSIONS, NULL, set_membridge0);
static DEVICE_ATTR(channel, SYSFS_PERMISSIONS, get_num_sensor, set_num_sensor); static DEVICE_ATTR(membridge_start1, SYSFS_PERMISSIONS, NULL, set_membridge1);
static DEVICE_ATTR(membridge_start2, SYSFS_PERMISSIONS, NULL, set_membridge2);
static DEVICE_ATTR(membridge_start3, SYSFS_PERMISSIONS, NULL, set_membridge3);
static struct attribute *root_dev_attrs[] = { static struct attribute *root_dev_attrs[] = {
&dev_attr_frame_start0.attr, &dev_attr_frame_start0.attr,
...@@ -1175,7 +1206,10 @@ static struct attribute *root_dev_attrs[] = { ...@@ -1175,7 +1206,10 @@ static struct attribute *root_dev_attrs[] = {
&dev_attr_frames_in_buffer1.attr, &dev_attr_frames_in_buffer1.attr,
&dev_attr_frames_in_buffer2.attr, &dev_attr_frames_in_buffer2.attr,
&dev_attr_frames_in_buffer3.attr, &dev_attr_frames_in_buffer3.attr,
&dev_attr_channel.attr, &dev_attr_membridge_start0.attr,
&dev_attr_membridge_start1.attr,
&dev_attr_membridge_start2.attr,
&dev_attr_membridge_start3.attr,
&dev_attr_membridge_status.attr, &dev_attr_membridge_status.attr,
NULL NULL
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment