Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
776c9443
Commit
776c9443
authored
Oct 24, 2006
by
=?utf-8?q?Michel_D=C3=A4nzer?=
Committed by
airlied
Dec 07, 2006
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
drm: add support for secondary vertical blank interrupt to DRM core
Signed-off-by:
Dave Airlie
<
airlied@linux.ie
>
parent
620034c8
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
60 additions
and
28 deletions
+60
-28
drivers/char/drm/drm.h
drivers/char/drm/drm.h
+3
-1
drivers/char/drm/drmP.h
drivers/char/drm/drmP.h
+4
-0
drivers/char/drm/drm_core.h
drivers/char/drm/drm_core.h
+4
-4
drivers/char/drm/drm_irq.c
drivers/char/drm/drm_irq.c
+49
-23
No files found.
drivers/char/drm/drm.h
View file @
776c9443
...
...
@@ -465,10 +465,12 @@ typedef struct drm_irq_busid {
typedef
enum
{
_DRM_VBLANK_ABSOLUTE
=
0x0
,
/**< Wait for specific vblank sequence number */
_DRM_VBLANK_RELATIVE
=
0x1
,
/**< Wait for given number of vblanks */
_DRM_VBLANK_SECONDARY
=
0x20000000
,
/**< Secondary display controller */
_DRM_VBLANK_SIGNAL
=
0x40000000
/**< Send signal instead of blocking */
}
drm_vblank_seq_type_t
;
#define _DRM_VBLANK_FLAGS_MASK _DRM_VBLANK_SIGNAL
#define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE)
#define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_SIGNAL | _DRM_VBLANK_SECONDARY)
struct
drm_wait_vblank_request
{
drm_vblank_seq_type_t
type
;
...
...
drivers/char/drm/drmP.h
View file @
776c9443
...
...
@@ -97,6 +97,7 @@
#define DRIVER_IRQ_VBL 0x100
#define DRIVER_DMA_QUEUE 0x200
#define DRIVER_FB_DMA 0x400
#define DRIVER_IRQ_VBL2 0x800
/***********************************************************************/
/** \name Begin the DRM... */
...
...
@@ -562,6 +563,7 @@ struct drm_driver {
void
(
*
kernel_context_switch_unlock
)
(
struct
drm_device
*
dev
,
drm_lock_t
*
lock
);
int
(
*
vblank_wait
)
(
struct
drm_device
*
dev
,
unsigned
int
*
sequence
);
int
(
*
vblank_wait2
)
(
struct
drm_device
*
dev
,
unsigned
int
*
sequence
);
int
(
*
dri_library_name
)
(
struct
drm_device
*
dev
,
char
*
buf
);
/**
...
...
@@ -708,8 +710,10 @@ typedef struct drm_device {
wait_queue_head_t
vbl_queue
;
/**< VBLANK wait queue */
atomic_t
vbl_received
;
atomic_t
vbl_received2
;
/**< number of secondary VBLANK interrupts */
spinlock_t
vbl_lock
;
drm_vbl_sig_t
vbl_sigs
;
/**< signal list to send on VBLANK */
drm_vbl_sig_t
vbl_sigs2
;
/**< signals to send on secondary VBLANK */
unsigned
int
vbl_pending
;
/*@} */
...
...
drivers/char/drm/drm_core.h
View file @
776c9443
...
...
@@ -24,11 +24,11 @@
#define CORE_NAME "drm"
#define CORE_DESC "DRM shared core routines"
#define CORE_DATE "200
51102
"
#define CORE_DATE "200
60810
"
#define DRM_IF_MAJOR 1
#define DRM_IF_MINOR
2
#define DRM_IF_MINOR
3
#define CORE_MAJOR 1
#define CORE_MINOR
0
#define CORE_PATCHLEVEL
1
#define CORE_MINOR
1
#define CORE_PATCHLEVEL
0
drivers/char/drm/drm_irq.c
View file @
776c9443
...
...
@@ -121,6 +121,7 @@ static int drm_irq_install(drm_device_t * dev)
spin_lock_init
(
&
dev
->
vbl_lock
);
INIT_LIST_HEAD
(
&
dev
->
vbl_sigs
.
head
);
INIT_LIST_HEAD
(
&
dev
->
vbl_sigs2
.
head
);
dev
->
vbl_pending
=
0
;
}
...
...
@@ -248,9 +249,7 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
struct
timeval
now
;
int
ret
=
0
;
unsigned
int
flags
;
if
(
!
drm_core_check_feature
(
dev
,
DRIVER_IRQ_VBL
))
return
-
EINVAL
;
atomic_t
*
seq
;
if
(
!
dev
->
irq
)
return
-
EINVAL
;
...
...
@@ -258,9 +257,26 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
if
(
copy_from_user
(
&
vblwait
,
argp
,
sizeof
(
vblwait
)))
return
-
EFAULT
;
switch
(
vblwait
.
request
.
type
&
~
_DRM_VBLANK_FLAGS_MASK
)
{
if
(
vblwait
.
request
.
type
&
~
(
_DRM_VBLANK_TYPES_MASK
|
_DRM_VBLANK_FLAGS_MASK
))
{
DRM_ERROR
(
"Unsupported type value 0x%x, supported mask 0x%x
\n
"
,
vblwait
.
request
.
type
,
(
_DRM_VBLANK_TYPES_MASK
|
_DRM_VBLANK_FLAGS_MASK
));
return
-
EINVAL
;
}
flags
=
vblwait
.
request
.
type
&
_DRM_VBLANK_FLAGS_MASK
;
if
(
!
drm_core_check_feature
(
dev
,
(
flags
&
_DRM_VBLANK_SECONDARY
)
?
DRIVER_IRQ_VBL2
:
DRIVER_IRQ_VBL
))
return
-
EINVAL
;
seq
=
(
flags
&
_DRM_VBLANK_SECONDARY
)
?
&
dev
->
vbl_received2
:
&
dev
->
vbl_received
;
switch
(
vblwait
.
request
.
type
&
_DRM_VBLANK_TYPES_MASK
)
{
case
_DRM_VBLANK_RELATIVE
:
vblwait
.
request
.
sequence
+=
atomic_read
(
&
dev
->
vbl_received
);
vblwait
.
request
.
sequence
+=
atomic_read
(
seq
);
vblwait
.
request
.
type
&=
~
_DRM_VBLANK_RELATIVE
;
case
_DRM_VBLANK_ABSOLUTE
:
break
;
...
...
@@ -268,13 +284,13 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
return
-
EINVAL
;
}
flags
=
vblwait
.
request
.
type
&
_DRM_VBLANK_FLAGS_MASK
;
if
(
flags
&
_DRM_VBLANK_SIGNAL
)
{
unsigned
long
irqflags
;
drm_vbl_sig_t
*
vbl_sigs
=
(
flags
&
_DRM_VBLANK_SECONDARY
)
?
&
dev
->
vbl_sigs2
:
&
dev
->
vbl_sigs
;
drm_vbl_sig_t
*
vbl_sig
;
vblwait
.
reply
.
sequence
=
atomic_read
(
&
dev
->
vbl_received
);
vblwait
.
reply
.
sequence
=
atomic_read
(
seq
);
spin_lock_irqsave
(
&
dev
->
vbl_lock
,
irqflags
);
...
...
@@ -282,7 +298,7 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
* for the same vblank sequence number; nothing to be done in
* that case
*/
list_for_each_entry
(
vbl_sig
,
&
dev
->
vbl_sigs
.
head
,
head
)
{
list_for_each_entry
(
vbl_sig
,
&
vbl_sigs
->
head
,
head
)
{
if
(
vbl_sig
->
sequence
==
vblwait
.
request
.
sequence
&&
vbl_sig
->
info
.
si_signo
==
vblwait
.
request
.
signal
&&
vbl_sig
->
task
==
current
)
{
...
...
@@ -315,11 +331,14 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
spin_lock_irqsave
(
&
dev
->
vbl_lock
,
irqflags
);
list_add_tail
((
struct
list_head
*
)
vbl_sig
,
&
dev
->
vbl_sigs
.
head
);
list_add_tail
((
struct
list_head
*
)
vbl_sig
,
&
vbl_sigs
->
head
);
spin_unlock_irqrestore
(
&
dev
->
vbl_lock
,
irqflags
);
}
else
{
if
(
dev
->
driver
->
vblank_wait
)
if
(
flags
&
_DRM_VBLANK_SECONDARY
)
{
if
(
dev
->
driver
->
vblank_wait2
)
ret
=
dev
->
driver
->
vblank_wait2
(
dev
,
&
vblwait
.
request
.
sequence
);
}
else
if
(
dev
->
driver
->
vblank_wait
)
ret
=
dev
->
driver
->
vblank_wait
(
dev
,
&
vblwait
.
request
.
sequence
);
...
...
@@ -347,27 +366,34 @@ int drm_wait_vblank(DRM_IOCTL_ARGS)
*/
void
drm_vbl_send_signals
(
drm_device_t
*
dev
)
{
struct
list_head
*
list
,
*
tmp
;
drm_vbl_sig_t
*
vbl_sig
;
unsigned
int
vbl_seq
=
atomic_read
(
&
dev
->
vbl_received
);
unsigned
long
flags
;
int
i
;
spin_lock_irqsave
(
&
dev
->
vbl_lock
,
flags
);
list_for_each_safe
(
list
,
tmp
,
&
dev
->
vbl_sigs
.
head
)
{
for
(
i
=
0
;
i
<
2
;
i
++
)
{
struct
list_head
*
list
,
*
tmp
;
drm_vbl_sig_t
*
vbl_sig
;
drm_vbl_sig_t
*
vbl_sigs
=
i
?
&
dev
->
vbl_sigs2
:
&
dev
->
vbl_sigs
;
unsigned
int
vbl_seq
=
atomic_read
(
i
?
&
dev
->
vbl_received2
:
&
dev
->
vbl_received
);
list_for_each_safe
(
list
,
tmp
,
&
vbl_sigs
->
head
)
{
vbl_sig
=
list_entry
(
list
,
drm_vbl_sig_t
,
head
);
if
((
vbl_seq
-
vbl_sig
->
sequence
)
<=
(
1
<<
23
))
{
vbl_sig
->
info
.
si_code
=
vbl_seq
;
send_sig_info
(
vbl_sig
->
info
.
si_signo
,
&
vbl_sig
->
inf
o
,
vbl_sig
->
task
);
send_sig_info
(
vbl_sig
->
info
.
si_sign
o
,
&
vbl_sig
->
info
,
vbl_sig
->
task
);
list_del
(
list
);
drm_free
(
vbl_sig
,
sizeof
(
*
vbl_sig
),
DRM_MEM_DRIVER
);
drm_free
(
vbl_sig
,
sizeof
(
*
vbl_sig
),
DRM_MEM_DRIVER
);
dev
->
vbl_pending
--
;
}
}
}
spin_unlock_irqrestore
(
&
dev
->
vbl_lock
,
flags
);
}
...
...
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