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
04b6f91f
Commit
04b6f91f
authored
Jan 10, 2018
by
Oleg Dzhimiev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
started implementing lseek
parent
b844e2fa
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
150 additions
and
99 deletions
+150
-99
x393_videomem.c
src/drivers/elphel/x393_videomem.c
+145
-99
x393_videomem.h
src/drivers/elphel/x393_videomem.h
+2
-0
c313a.h
src/include/uapi/elphel/c313a.h
+3
-0
No files found.
src/drivers/elphel/x393_videomem.c
View file @
04b6f91f
...
...
@@ -46,6 +46,21 @@
#define MEMBRIDGE_CMD_IRQ_EN 0x3
// like in framepars.c
// lock membridge run
#undef LOCK_BH_PROCESSPARS
#define LOCK_BH_FRAMEPARS
#ifdef LOCK_BH_FRAMEPARS
#define FLAGS_IBH
#define LOCK_IBH(x) spin_lock_bh(x)
#define UNLOCK_IBH(x) spin_unlock_bh(x)
#else
#define FLAGS_IBH unsigned long flags;
#define LOCK_IBH(x) spin_lock_irqsave(x,flags)
#define UNLOCK_IBH(x) spin_unlock_irqrestore(x,flags)
#endif
static
const
struct
of_device_id
elphel393_videomem_of_match
[];
static
struct
device
*
g_dev_ptr
;
///< Global pointer to basic device structure. This pointer is used in debugfs output functions
wait_queue_head_t
videomem_wait_queue
;
...
...
@@ -87,10 +102,6 @@ static struct elphel_video_buf_t buffer_settings = { ///< some default settings,
static
int
membridge_sensor_port
=
0
;
// 0..3
static
int
membridge_direction
=
0
;
// 0 - from pl to ps, 1 - from ps to pl
// Membridge can be only accessed by a single source - TODO: use this lock
static
bool
membridge_lock
=
false
;
static
int
hardware_initialized
=
0
;
/** Setup memory bridge system memory */
...
...
@@ -662,12 +673,85 @@ 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
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
};
int
membridge_start
(
struct
file
*
file
){
struct
raw_priv_t
*
privData
=
(
struct
raw_priv_t
*
)
file
->
private_data
;
int
p_color
,
p_pf_height
;
int
width_marg
,
height_marg
,
width_bursts
;
int
frame_number
;
// no need
frame_number
=
GLOBALPARS
(
privData
->
sensor_num
,
G_THIS_FRAME
)
&
PARS_FRAMES_MASK
;
//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
);
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
);
}
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
);
//NOTES:
//// get this frame number
//#define thisFrameNumber(p) GLOBALPARS(p,G_THIS_FRAME) // Current frame number (may lag from the hardware)
//#define thisCompressorFrameNumber(p) GLOBALPARS(p,G_COMPRESSOR_FRAME) // Current compressed frame number (lags from thisFrameNumber)
//// wait for certain frame number
// wait_event_interruptible(aframepars_wait_queue[sensor_port], getThisFrameNumber(sensor_port) >= target_frame);
//// get frame sizes
//unsigned long get_imageParamsPast(int sensor_port, int n, int frame);
return
0
;
}
/**
* @brief This function handles read operations for raw files.
* @param[in] file pointer to <em>struct file</em>
...
...
@@ -730,10 +814,62 @@ ssize_t vm_read(struct file *file, char *buf, size_t count, loff_t *off)
// TODO: Implement file operations using membridge for both raw memory access and per-channel image raw (including 16-bit)
//static int videomem_open (struct inode *inode, struct file *filp) {return 0;}
//static int videomem_release (struct inode *inode, struct file *filp) {return 0;}
static
loff_t
videomem_lseek
(
struct
file
*
file
,
loff_t
offset
,
int
orig
)
{
return
0
;}
//
static loff_t videomem_lseek (struct file * file, loff_t offset, int orig) {return 0;}
//static ssize_t videomem_read (struct file * file, char * buf, size_t count, loff_t *off) {return 0;}
static
ssize_t
videomem_write
(
struct
file
*
file
,
const
char
*
buf
,
size_t
count
,
loff_t
*
off
)
{
return
0
;}
/**
* @brief Driver LSEEK method (and execute commands)
* - lseek (SEEK_SET, value) - set absolute frame number
* - lseek (SEEK_CUR, value) - set frame number relative to the current frame number (thisFrameNumber),
* - lseek (SEEK_CUR, 0) - (used by ftell()) DOES NOT modify file pointer, returns thisFrameNumber,
* - lseek (SEEK_END, value <= 0) - do nothing?, do not modify file pointer
* - lseek (SEEK_END, value > 0) - execute commands, do not modify file pointer (and actually use it - frame number the command applies to)
* - no commands yet
* @param file
* @param offset
* @param orig SEEK_SET, SEEK_CUR or SEEK_SET END
* @return file position (absolute frame number)
*/
static
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
;
//sec_usec_t sec_usec;
int
res
;
pr_debug
(
"(videomem_lseek) offset=0x%x, orig=0x%x, sensor_port = %d
\n
"
,
(
int
)
offset
,
(
int
)
orig
,
sensor_port
);
switch
(
orig
)
{
case
SEEK_SET
:
file
->
f_pos
=
offset
;
break
;
case
SEEK_CUR
:
if
(
offset
==
0
)
return
getThisFrameNumber
(
sensor_port
);
// do not modify frame number
file
->
f_pos
=
getThisFrameNumber
(
sensor_port
)
+
offset
;
// modifies frame number, but it is better to use absolute SEEK SET
break
;
case
SEEK_END
:
if
(
offset
<=
0
)
{
file
->
f_pos
=
privData
->
buf_size
+
offset
;
}
else
{
switch
(
offset
)
{
case
LSEEK_VIDEOMEM_START
:
// Check lock here:
membridge_start
(
file
);
break
;
}
}
break
;
default
:
return
-
EINVAL
;
}
// roll-over position
//while (file->f_pos < 0) file->f_pos+= circbuf_priv_ptr[chn].buf_size;
//while (file->f_pos > circbuf_priv_ptr[chn].buf_size) file->f_pos-= circbuf_priv_ptr[chn].buf_size;
return
file
->
f_pos
;
}
/**
* @brief Process raw buffer file opening.
* @param[in] inode
...
...
@@ -744,10 +880,6 @@ static int videomem_open(struct inode *inode, struct file *filp)
{
struct
raw_priv_t
*
privData
;
int
p_color
,
p_pf_height
;
int
width_marg
,
height_marg
,
width_bursts
;
int
frame_number
;
// to enable interrupt
x393_membridge_ctrl_irq_t
membridge_irq_en
=
{.
d32
=
0
};
membridge_irq_en
.
interrupt_cmd
=
MEMBRIDGE_CMD_IRQ_EN
;
...
...
@@ -782,6 +914,8 @@ static int videomem_open(struct inode *inode, struct file *filp)
membridge_sensor_port
=
0
;
}
privData
->
sensor_num
=
membridge_sensor_port
;
switch
(
privData
->
minor
){
case
DEV393_MINOR
(
DEV393_IMAGE_RAW0
):
privData
->
buf_ptr
=
pElphel_buf
->
raw_chn0_vaddr
;
...
...
@@ -812,96 +946,8 @@ static int videomem_open(struct inode *inode, struct file *filp)
privData
->
buf_size32
=
(
privData
->
buf_size
)
>>
2
;
// no need
frame_number
=
GLOBALPARS
(
membridge_sensor_port
,
G_THIS_FRAME
)
&
PARS_FRAMES_MASK
;
//calculate things
//if (frame16 >= PARS_FRAMES) return -1; // wrong frame
width_marg
=
get_imageParamsThis
(
membridge_sensor_port
,
P_ACTUAL_WIDTH
);
height_marg
=
get_imageParamsThis
(
membridge_sensor_port
,
P_ACTUAL_HEIGHT
);
p_color
=
get_imageParamsThis
(
membridge_sensor_port
,
P_COLOR
);
p_pf_height
=
get_imageParamsThis
(
membridge_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
);
}
break
;
}
width_bursts
=
(
width_marg
>>
4
)
+
((
width_marg
&
0xf
)
?
1
:
0
);
/** shorter version: */
//width_bursts = (width_marg+0xf)>>4;
//int setup_sensor_memory (int num_sensor, ///< sensor port number (0..3)
// int window_width, ///< 13-bit - in 8*16=128 bit bursts
// int window_height, ///< 16-bit window height (in scan lines)
// int window_left, ///< 13-bit window left margin in 8-bursts (16 bytes)
// int window_top, ///< 16-bit window top margin (in scan lines)
// x393cmd_t x393cmd, ///< how to apply commands - directly or through channel sequencer
// int frame16) ///< Frame number the command should be applied to (if not immediate mode)
//setup_sensor_memory (sensor_port, // sensor port number (0..3)
// 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)
// (frame16<0)? ASAP: ABSOLUTE, // how to apply commands - directly or through channel sequencer
// frame16); // Frame number the command should be applied to (if not immediate mode)
// setup membridge fpga memory
//int setup_membridge_memory(
// int num_sensor, ///< sensor port number (0..3)
// int write_direction, ///< 0 - from fpga mem to system mem, 1 - otherwise
// int window_width, ///< 13-bit - in 8*16=128 bit bursts
// int window_height, ///< 16-bit window height (in scan lines)
// int window_left, ///< 13-bit window left margin in 8-bursts (16 bytes)
// int window_top, ///< 16-bit window top margin (in scan lines)
// int start_x, ///< START X ...
// int start_y, ///< START Y ...
// x393cmd_t x393cmd, ///< how to apply commands - directly or through channel sequencer
// int frame16) ///< Frame number the command should be applied to (if not immediate mode)
setup_membridge_memory
(
membridge_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
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
);
//NOTES:
//// get this frame number
//#define thisFrameNumber(p) GLOBALPARS(p,G_THIS_FRAME) // Current frame number (may lag from the hardware)
//#define thisCompressorFrameNumber(p) GLOBALPARS(p,G_COMPRESSOR_FRAME) // Current compressed frame number (lags from thisFrameNumber)
//// wait for certain frame number
// wait_event_interruptible(aframepars_wait_queue[sensor_port], getThisFrameNumber(sensor_port) >= target_frame);
//// get frame sizes
//unsigned long get_imageParamsPast(int sensor_port, int n, int frame);
// TODO: remove once lseek is tested
membridge_start
(
filp
);
return
0
;
}
...
...
src/drivers/elphel/x393_videomem.h
View file @
04b6f91f
...
...
@@ -38,3 +38,5 @@ int frames_in_buffer_minus_one (int num_sensor);
void
memchan_enable
(
int
chn
,
int
enable
);
void
set_memchannel_priority
(
int
chn
,
u16
priority
);
u16
get_memchannel_priority
(
int
chn
);
loff_t
videomem_lseek
(
struct
file
*
file
,
loff_t
offset
,
int
orig
);
src/include/uapi/elphel/c313a.h
View file @
04b6f91f
...
...
@@ -1552,6 +1552,9 @@ struct p_names_t {
#define LSEEK_FSDRAM_RESET 0x01 // re-program FSDRAM (to be programmed again when accessed)
// Videomem/raw image commands
#define LSEEK_VIDEOMEM_START 0x10 // setup and start membridge transfer
#define JPEG_CTRL_MONOCHROME 0x400
#define JPEG_CTRL_MONOCHROME_BLOCKED 0x1000
#define JPEG_CTRL_NOMOSAIC 0x1000
...
...
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