Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-elphel
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
linux-elphel
Commits
24d7f26b
Commit
24d7f26b
authored
Jan 11, 2018
by
Oleg Dzhimiev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
+ run membridge via sysfs file
parent
1f97a843
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
129 additions
and
95 deletions
+129
-95
x393_videomem.c
src/drivers/elphel/x393_videomem.c
+129
-95
No files found.
src/drivers/elphel/x393_videomem.c
View file @
24d7f26b
...
...
@@ -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 */
};
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
hardware_initialized
=
0
;
...
...
@@ -105,6 +104,12 @@ int setup_membridge_system_memory(
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
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
,
...
...
@@ -113,12 +118,6 @@ int setup_membridge_system_memory(
len64
,
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
;
size
.
addr64
=
size64
;
start
.
addr64
=
start64
;
...
...
@@ -664,11 +663,9 @@ u16 get_memchannel_priority(int chn) ///< Memory channel (0..16). When usi
/** @brief Videomem buffer private data */
struct
raw_priv_t
{
int
minor
;
///< device file minor number
int
sensor_num
;
///< sensor number
int
sensor_port
;
///< sensor number
unsigned
long
*
buf_ptr
;
///< pointer to raw buffer memory region
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
};
...
...
@@ -677,16 +674,43 @@ static inline int membridge_is_busy(void){
return
status
.
busy
;
}
int
membridge_start
(
struct
file
*
file
){
struct
raw_priv_t
*
privData
=
(
struct
raw_priv_t
*
)
file
->
private_data
;
int
membridge_start
(
int
sensor_port
,
unsigned
long
target_frame
){
int
p_color
,
p_pf_height
;
int
width_marg
,
height_marg
,
width_bursts
;
int
frame_number
;
dma_addr_t
phys_addr
;
unsigned
long
buf_size
;
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
);
if
(
membridge_locked
==
0
){
membridge_locked
=
1
;
...
...
@@ -696,54 +720,44 @@ int membridge_start(struct file * file){
}
spin_unlock
(
&
membridge_lock
);
// no need
frame_number
=
GLOBALPARS
(
privData
->
sensor_num
,
G_THIS_FRAME
)
&
PARS_FRAMES_MASK
;
width_marg
=
get_imageParamsThis
(
sensor_port
,
P_ACTUAL_WIDTH
);
height_marg
=
get_imageParamsThis
(
sensor_port
,
P_ACTUAL_HEIGHT
)
;
//calculate things
//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
);
p_color
=
get_imageParamsThis
(
sensor_port
,
P_COLOR
);
p_pf_height
=
get_imageParamsThis
(
sensor_port
,
P_PF_HEIGHT
);
switch
(
p_color
){
case
COLORMODE_COLOR
:
case
COLORMODE_COLOR20
:
width_marg
+=
(
2
*
COLOR_MARGINS
);
if
((
p_pf_height
&
0xffff
)
==
0
)
{
// not a photofinish
height_marg
+=
(
2
*
COLOR_MARGINS
);
case
COLORMODE_COLOR
:
case
COLORMODE_COLOR20
:
width_marg
+=
(
2
*
COLOR_MARGINS
);
if
((
p_pf_height
&
0xffff
)
==
0
)
{
// not a photofinish
height_marg
+=
(
2
*
COLOR_MARGINS
);
}
break
;
}
break
;
}
width_bursts
=
(
width_marg
>>
4
)
+
((
width_marg
&
0xf
)
?
1
:
0
);
/** shorter version: */
//width_bursts = (width_marg+0xf)>>4;
setup_membridge_memory
(
privData
->
sensor_num
,
///< sensor port number (0..3)
0
,
///< 0 - from fpga mem to system mem, 1 - otherwise
width_bursts
,
///< 13-bit - in 8*16=128 bit bursts
height_marg
,
///< 16-bit window height (in scan lines)
0
,
///< 13-bit window left margin in 8-bursts (16 bytes)
0
,
///< 16-bit window top margin (in scan lines)
0
,
///< START X ...
0
,
///< START Y ...
DIRECT
,
///< how to apply commands - directly or through channel sequencer
frame_number
);
///< Frame number the command should be applied to (if not immediate mode)
// setup membridge system memory - everything is in QW
setup_membridge_system_memory
(
(
privData
->
phys_addr
)
>>
3
,
(
privData
->
buf_size
)
>>
3
,
0
,
// start offset?
(
width_bursts
<<
1
)
*
height_marg
,
(
width_bursts
<<
1
)
);
control_membridge_memory
(
membridge_sensor_port
,
1
,
DIRECT
,
frame_number
);
width_bursts
=
(
width_marg
>>
4
)
+
((
width_marg
&
0xf
)
?
1
:
0
);
setup_membridge_memory
(
sensor_port
,
///< sensor port number (0..3)
0
,
///< 0 - from fpga mem to system mem, 1 - otherwise
width_bursts
,
///< 13-bit - in 8*16=128 bit bursts
height_marg
,
///< 16-bit window height (in scan lines)
0
,
///< 13-bit window left margin in 8-bursts (16 bytes)
0
,
///< 16-bit window top margin (in scan lines)
0
,
///< START X ...
0
,
///< START Y ...
DIRECT
,
///< how to apply commands - directly or through channel sequencer
target_frame
);
///< Frame number the command should be applied to (if not immediate mode)
// setup membridge system memory - everything is in QW
setup_membridge_system_memory
(
phys_addr
>>
3
,
buf_size
>>
3
,
0
,
// start offset?
(
width_bursts
<<
1
)
*
height_marg
,
(
width_bursts
<<
1
)
);
control_membridge_memory
(
sensor_port
,
1
,
DIRECT
,
target_frame
);
status
=
x393_membridge_status
();
pr_debug
(
"membridge status is %d
\n
"
,
status
.
busy
);
...
...
@@ -774,7 +788,7 @@ int membridge_start(struct file * file){
//// get frame sizes
//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){
unsigned
long
target_frame
;
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;
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
);
...
...
@@ -861,15 +874,7 @@ loff_t videomem_lseek(struct file * file, loff_t offset, int orig){
}
else
{
target_frame
=
offset
;
waitFrame
(
sensor_port
,
target_frame
);
status
=
x393_membridge_status
();
if
(
status
.
busy
)
{
return
-
EBUSY
;
}
res
=
membridge_start
(
file
);
res
=
membridge_start
(
sensor_port
,
target_frame
);
if
(
res
<
0
)
return
res
;
}
...
...
@@ -893,6 +898,9 @@ int videomem_open(struct inode *inode, struct file *filp)
{
struct
raw_priv_t
*
privData
;
int
minor
;
int
sensor_port
;
// to enable interrupt
x393_membridge_ctrl_irq_t
membridge_irq_en
=
{.
d32
=
0
};
membridge_irq_en
.
interrupt_cmd
=
MEMBRIDGE_CMD_IRQ_EN
;
...
...
@@ -918,18 +926,18 @@ int videomem_open(struct inode *inode, struct file *filp)
}
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
if
(
membridge_
sensor_port
<
0
){
membridge_
sensor_port
=
0
;
if
(
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
):
privData
->
buf_ptr
=
pElphel_buf
->
raw_chn0_vaddr
;
privData
->
phys_addr
=
pElphel_buf
->
raw_chn0_paddr
;
...
...
@@ -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_size32
=
(
privData
->
buf_size
)
>>
2
;
// TODO: remove once lseek is tested
membridge_start
(
filp
);
//membridge_start(sensor_port,0
);
return
0
;
}
...
...
@@ -989,7 +995,6 @@ int videomem_mmap(struct file *file, struct vm_area_struct *vma)
{
int
ret
;
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_end = 0x%lx
\n
"
,
vma
->
vm_end
);
...
...
@@ -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
)]);
}
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
)
{
...
...
@@ -1116,12 +1117,6 @@ static ssize_t store_frames_in_buffer(struct device *dev, struct device_attribut
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
)
{
int
in
;
...
...
@@ -1135,6 +1130,41 @@ static ssize_t set_membridge_status_reg(struct device *dev, struct device_attrib
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_start1
,
SYSFS_PERMISSIONS
,
show_frame_start
,
store_frame_start
);
...
...
@@ -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_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
(
membridge_status
,
SYSFS_PERMISSIONS
,
get_membridge_status
,
set_membridge_status_reg
);
// selected sensor channel == port
// TODO: switch to multiple device files and remove this
static
DEVICE_ATTR
(
channel
,
SYSFS_PERMISSIONS
,
get_num_sensor
,
set_num_sensor
);
static
DEVICE_ATTR
(
membridge_status
,
SYSFS_PERMISSIONS
,
get_membridge_status
,
set_membridge_status_reg
);
static
DEVICE_ATTR
(
membridge_start0
,
SYSFS_PERMISSIONS
,
NULL
,
set_membridge0
);
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
[]
=
{
&
dev_attr_frame_start0
.
attr
,
...
...
@@ -1175,7 +1206,10 @@ static struct attribute *root_dev_attrs[] = {
&
dev_attr_frames_in_buffer1
.
attr
,
&
dev_attr_frames_in_buffer2
.
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
,
NULL
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment