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
d375e7d5
Commit
d375e7d5
authored
Apr 30, 2012
by
Ben Skeggs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
drm/nouveau/fence: minor api changes for an upcoming rework
Signed-off-by:
Ben Skeggs
<
bskeggs@redhat.com
>
parent
875ac34a
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
134 additions
and
158 deletions
+134
-158
drivers/gpu/drm/nouveau/nouveau_bo.c
drivers/gpu/drm/nouveau/nouveau_bo.c
+3
-2
drivers/gpu/drm/nouveau/nouveau_channel.c
drivers/gpu/drm/nouveau/nouveau_channel.c
+2
-1
drivers/gpu/drm/nouveau/nouveau_display.c
drivers/gpu/drm/nouveau/nouveau_display.c
+6
-3
drivers/gpu/drm/nouveau/nouveau_drv.h
drivers/gpu/drm/nouveau/nouveau_drv.h
+6
-20
drivers/gpu/drm/nouveau/nouveau_fence.c
drivers/gpu/drm/nouveau/nouveau_fence.c
+85
-130
drivers/gpu/drm/nouveau/nouveau_fence.h
drivers/gpu/drm/nouveau/nouveau_fence.h
+28
-0
drivers/gpu/drm/nouveau/nouveau_gem.c
drivers/gpu/drm/nouveau/nouveau_gem.c
+2
-1
drivers/gpu/drm/nouveau/nouveau_mem.c
drivers/gpu/drm/nouveau/nouveau_mem.c
+2
-1
No files found.
drivers/gpu/drm/nouveau/nouveau_bo.c
View file @
d375e7d5
...
...
@@ -35,6 +35,7 @@
#include "nouveau_dma.h"
#include "nouveau_mm.h"
#include "nouveau_vm.h"
#include "nouveau_fence.h"
#include <linux/log2.h>
#include <linux/slab.h>
...
...
@@ -478,7 +479,7 @@ nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan,
struct
nouveau_fence
*
fence
=
NULL
;
int
ret
;
ret
=
nouveau_fence_new
(
chan
,
&
fence
,
true
);
ret
=
nouveau_fence_new
(
chan
,
&
fence
);
if
(
ret
)
return
ret
;
...
...
@@ -1196,7 +1197,7 @@ nouveau_bo_fence_ref(void *sync_obj)
static
bool
nouveau_bo_fence_signalled
(
void
*
sync_obj
,
void
*
sync_arg
)
{
return
nouveau_fence_
signalled
(
sync_obj
);
return
nouveau_fence_
done
(
sync_obj
);
}
static
int
...
...
drivers/gpu/drm/nouveau/nouveau_channel.c
View file @
d375e7d5
...
...
@@ -28,6 +28,7 @@
#include "nouveau_drm.h"
#include "nouveau_dma.h"
#include "nouveau_ramht.h"
#include "nouveau_fence.h"
#include "nouveau_software.h"
static
int
...
...
@@ -369,7 +370,7 @@ nouveau_channel_idle(struct nouveau_channel *chan)
nouveau_fence_update
(
chan
);
if
(
chan
->
fence
.
sequence
!=
chan
->
fence
.
sequence_ack
)
{
ret
=
nouveau_fence_new
(
chan
,
&
fence
,
true
);
ret
=
nouveau_fence_new
(
chan
,
&
fence
);
if
(
!
ret
)
{
ret
=
nouveau_fence_wait
(
fence
,
false
,
false
);
nouveau_fence_unref
(
&
fence
);
...
...
drivers/gpu/drm/nouveau/nouveau_display.c
View file @
d375e7d5
...
...
@@ -35,6 +35,7 @@
#include "nouveau_connector.h"
#include "nouveau_software.h"
#include "nouveau_gpio.h"
#include "nouveau_fence.h"
#include "nv50_display.h"
static
void
...
...
@@ -465,7 +466,7 @@ nouveau_page_flip_emit(struct nouveau_channel *chan,
}
FIRE_RING
(
chan
);
ret
=
nouveau_fence_new
(
chan
,
pfence
,
true
);
ret
=
nouveau_fence_new
(
chan
,
pfence
);
if
(
ret
)
goto
fail
;
...
...
@@ -486,7 +487,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
struct
nouveau_bo
*
old_bo
=
nouveau_framebuffer
(
crtc
->
fb
)
->
nvbo
;
struct
nouveau_bo
*
new_bo
=
nouveau_framebuffer
(
fb
)
->
nvbo
;
struct
nouveau_page_flip_state
*
s
;
struct
nouveau_channel
*
chan
;
struct
nouveau_channel
*
chan
=
NULL
;
struct
nouveau_fence
*
fence
;
int
ret
;
...
...
@@ -509,7 +510,9 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
new_bo
->
bo
.
offset
};
/* Choose the channel the flip will be handled in */
chan
=
nouveau_fence_channel
(
new_bo
->
bo
.
sync_obj
);
fence
=
new_bo
->
bo
.
sync_obj
;
if
(
fence
)
chan
=
nouveau_channel_get_unlocked
(
fence
->
channel
);
if
(
!
chan
)
chan
=
nouveau_channel_get_unlocked
(
dev_priv
->
channel
);
mutex_lock
(
&
chan
->
mutex
);
...
...
drivers/gpu/drm/nouveau/nouveau_drv.h
View file @
d375e7d5
...
...
@@ -1444,26 +1444,12 @@ extern int nouveau_bo_vma_add(struct nouveau_bo *, struct nouveau_vm *,
extern
void
nouveau_bo_vma_del
(
struct
nouveau_bo
*
,
struct
nouveau_vma
*
);
/* nouveau_fence.c */
struct
nouveau_fence
;
extern
int
nouveau_fence_init
(
struct
drm_device
*
);
extern
void
nouveau_fence_fini
(
struct
drm_device
*
);
extern
int
nouveau_fence_channel_init
(
struct
nouveau_channel
*
);
extern
void
nouveau_fence_channel_fini
(
struct
nouveau_channel
*
);
extern
void
nouveau_fence_update
(
struct
nouveau_channel
*
);
extern
int
nouveau_fence_new
(
struct
nouveau_channel
*
,
struct
nouveau_fence
**
,
bool
emit
);
extern
int
nouveau_fence_emit
(
struct
nouveau_fence
*
);
extern
void
nouveau_fence_work
(
struct
nouveau_fence
*
fence
,
void
(
*
work
)(
void
*
priv
,
bool
signalled
),
void
*
priv
);
struct
nouveau_channel
*
nouveau_fence_channel
(
struct
nouveau_fence
*
);
extern
bool
nouveau_fence_signalled
(
struct
nouveau_fence
*
);
extern
int
nouveau_fence_wait
(
struct
nouveau_fence
*
,
bool
lazy
,
bool
intr
);
extern
void
nouveau_fence_unref
(
struct
nouveau_fence
**
);
extern
struct
nouveau_fence
*
nouveau_fence_ref
(
struct
nouveau_fence
*
);
extern
int
nouveau_fence_sync
(
struct
nouveau_fence
*
,
struct
nouveau_channel
*
);
int
nouveau_fence_init
(
struct
drm_device
*
);
void
nouveau_fence_fini
(
struct
drm_device
*
);
int
nouveau_fence_channel_init
(
struct
nouveau_channel
*
);
void
nouveau_fence_channel_fini
(
struct
nouveau_channel
*
);
void
nouveau_fence_work
(
struct
nouveau_fence
*
fence
,
void
(
*
work
)(
void
*
priv
,
bool
signalled
),
void
*
priv
);
/* nouveau_gem.c */
extern
int
nouveau_gem_new
(
struct
drm_device
*
,
int
size
,
int
align
,
uint32_t
domain
,
uint32_t
tile_mode
,
...
...
drivers/gpu/drm/nouveau/nouveau_fence.c
View file @
d375e7d5
...
...
@@ -32,47 +32,13 @@
#include "nouveau_drv.h"
#include "nouveau_ramht.h"
#include "nouveau_fence.h"
#include "nouveau_software.h"
#include "nouveau_dma.h"
#define USE_REFCNT(dev) (nouveau_private(dev)->chipset >= 0x10)
#define USE_SEMA(dev) (nouveau_private(dev)->chipset >= 0x17)
struct
nouveau_fence
{
struct
nouveau_channel
*
channel
;
struct
kref
refcount
;
struct
list_head
entry
;
uint32_t
sequence
;
bool
signalled
;
unsigned
long
timeout
;
void
(
*
work
)(
void
*
priv
,
bool
signalled
);
void
*
priv
;
};
struct
nouveau_semaphore
{
struct
kref
ref
;
struct
drm_device
*
dev
;
struct
drm_mm_node
*
mem
;
};
static
inline
struct
nouveau_fence
*
nouveau_fence
(
void
*
sync_obj
)
{
return
(
struct
nouveau_fence
*
)
sync_obj
;
}
static
void
nouveau_fence_del
(
struct
kref
*
ref
)
{
struct
nouveau_fence
*
fence
=
container_of
(
ref
,
struct
nouveau_fence
,
refcount
);
nouveau_channel_ref
(
NULL
,
&
fence
->
channel
);
kfree
(
fence
);
}
void
nouveau_fence_update
(
struct
nouveau_channel
*
chan
)
{
...
...
@@ -94,16 +60,16 @@ nouveau_fence_update(struct nouveau_channel *chan)
chan
->
fence
.
sequence_ack
=
sequence
;
}
list_for_each_entry_safe
(
fence
,
tmp
,
&
chan
->
fence
.
pending
,
entry
)
{
list_for_each_entry_safe
(
fence
,
tmp
,
&
chan
->
fence
.
pending
,
head
)
{
if
(
fence
->
sequence
>
chan
->
fence
.
sequence_ack
)
break
;
fence
->
signalled
=
true
;
list_del
(
&
fence
->
entry
);
fence
->
channel
=
NULL
;
list_del
(
&
fence
->
head
);
if
(
fence
->
work
)
fence
->
work
(
fence
->
priv
,
true
);
kref_put
(
&
fence
->
refcount
,
nouveau_fence_del
);
nouveau_fence_unref
(
&
fence
);
}
out:
...
...
@@ -111,37 +77,8 @@ nouveau_fence_update(struct nouveau_channel *chan)
}
int
nouveau_fence_new
(
struct
nouveau_channel
*
chan
,
struct
nouveau_fence
**
pfence
,
bool
emit
)
nouveau_fence_emit
(
struct
nouveau_fence
*
fence
,
struct
nouveau_channel
*
chan
)
{
struct
nouveau_fence
*
fence
;
int
ret
=
0
;
fence
=
kzalloc
(
sizeof
(
*
fence
),
GFP_KERNEL
);
if
(
!
fence
)
return
-
ENOMEM
;
kref_init
(
&
fence
->
refcount
);
nouveau_channel_ref
(
chan
,
&
fence
->
channel
);
if
(
emit
)
ret
=
nouveau_fence_emit
(
fence
);
if
(
ret
)
nouveau_fence_unref
(
&
fence
);
*
pfence
=
fence
;
return
ret
;
}
struct
nouveau_channel
*
nouveau_fence_channel
(
struct
nouveau_fence
*
fence
)
{
return
fence
?
nouveau_channel_get_unlocked
(
fence
->
channel
)
:
NULL
;
}
int
nouveau_fence_emit
(
struct
nouveau_fence
*
fence
)
{
struct
nouveau_channel
*
chan
=
fence
->
channel
;
struct
drm_device
*
dev
=
chan
->
dev
;
struct
drm_nouveau_private
*
dev_priv
=
dev
->
dev_private
;
int
ret
;
...
...
@@ -158,10 +95,11 @@ nouveau_fence_emit(struct nouveau_fence *fence)
}
fence
->
sequence
=
++
chan
->
fence
.
sequence
;
fence
->
channel
=
chan
;
kref_get
(
&
fence
->
refcount
);
kref_get
(
&
fence
->
kref
);
spin_lock
(
&
chan
->
fence
.
lock
);
list_add_tail
(
&
fence
->
entry
,
&
chan
->
fence
.
pending
);
list_add_tail
(
&
fence
->
head
,
&
chan
->
fence
.
pending
);
spin_unlock
(
&
chan
->
fence
.
lock
);
if
(
USE_REFCNT
(
dev
))
{
...
...
@@ -179,50 +117,12 @@ nouveau_fence_emit(struct nouveau_fence *fence)
return
0
;
}
void
nouveau_fence_work
(
struct
nouveau_fence
*
fence
,
void
(
*
work
)(
void
*
priv
,
bool
signalled
),
void
*
priv
)
{
BUG_ON
(
fence
->
work
);
spin_lock
(
&
fence
->
channel
->
fence
.
lock
);
if
(
fence
->
signalled
)
{
work
(
priv
,
true
);
}
else
{
fence
->
work
=
work
;
fence
->
priv
=
priv
;
}
spin_unlock
(
&
fence
->
channel
->
fence
.
lock
);
}
void
nouveau_fence_unref
(
struct
nouveau_fence
**
pfence
)
{
if
(
*
pfence
)
kref_put
(
&
(
*
pfence
)
->
refcount
,
nouveau_fence_del
);
*
pfence
=
NULL
;
}
struct
nouveau_fence
*
nouveau_fence_ref
(
struct
nouveau_fence
*
fence
)
{
kref_get
(
&
fence
->
refcount
);
return
fence
;
}
bool
nouveau_fence_
signalled
(
struct
nouveau_fence
*
fence
)
nouveau_fence_
done
(
struct
nouveau_fence
*
fence
)
{
struct
nouveau_channel
*
chan
=
fence
->
channel
;
if
(
fence
->
signalled
)
return
true
;
nouveau_fence_update
(
chan
);
return
fence
->
signalled
;
if
(
fence
->
channel
)
nouveau_fence_update
(
fence
->
channel
);
return
!
fence
->
channel
;
}
int
...
...
@@ -232,8 +132,8 @@ nouveau_fence_wait(struct nouveau_fence *fence, bool lazy, bool intr)
ktime_t
t
;
int
ret
=
0
;
while
(
!
nouveau_fence_
signalled
(
fence
))
{
if
(
time_after_eq
(
jiffies
,
fence
->
timeout
))
{
while
(
!
nouveau_fence_
done
(
fence
))
{
if
(
fence
->
timeout
&&
time_after_eq
(
jiffies
,
fence
->
timeout
))
{
ret
=
-
EBUSY
;
break
;
}
...
...
@@ -255,10 +155,71 @@ nouveau_fence_wait(struct nouveau_fence *fence, bool lazy, bool intr)
}
__set_current_state
(
TASK_RUNNING
);
return
ret
;
}
static
void
nouveau_fence_del
(
struct
kref
*
kref
)
{
struct
nouveau_fence
*
fence
=
container_of
(
kref
,
typeof
(
*
fence
),
kref
);
kfree
(
fence
);
}
void
nouveau_fence_unref
(
struct
nouveau_fence
**
pfence
)
{
if
(
*
pfence
)
kref_put
(
&
(
*
pfence
)
->
kref
,
nouveau_fence_del
);
*
pfence
=
NULL
;
}
struct
nouveau_fence
*
nouveau_fence_ref
(
struct
nouveau_fence
*
fence
)
{
kref_get
(
&
fence
->
kref
);
return
fence
;
}
int
nouveau_fence_new
(
struct
nouveau_channel
*
chan
,
struct
nouveau_fence
**
pfence
)
{
struct
nouveau_fence
*
fence
;
int
ret
=
0
;
fence
=
kzalloc
(
sizeof
(
*
fence
),
GFP_KERNEL
);
if
(
!
fence
)
return
-
ENOMEM
;
kref_init
(
&
fence
->
kref
);
if
(
chan
)
{
ret
=
nouveau_fence_emit
(
fence
,
chan
);
if
(
ret
)
nouveau_fence_unref
(
&
fence
);
}
*
pfence
=
fence
;
return
ret
;
}
struct
nouveau_semaphore
{
struct
kref
ref
;
struct
drm_device
*
dev
;
struct
drm_mm_node
*
mem
;
};
void
nouveau_fence_work
(
struct
nouveau_fence
*
fence
,
void
(
*
work
)(
void
*
priv
,
bool
signalled
),
void
*
priv
)
{
if
(
!
fence
->
channel
)
{
work
(
priv
,
true
);
}
else
{
fence
->
work
=
work
;
fence
->
priv
=
priv
;
}
}
static
struct
nouveau_semaphore
*
semaphore_alloc
(
struct
drm_device
*
dev
)
{
...
...
@@ -367,7 +328,7 @@ semaphore_acquire(struct nouveau_channel *chan, struct nouveau_semaphore *sema)
}
/* Delay semaphore destruction until its work is done */
ret
=
nouveau_fence_new
(
chan
,
&
fence
,
true
);
ret
=
nouveau_fence_new
(
chan
,
&
fence
);
if
(
ret
)
return
ret
;
...
...
@@ -421,7 +382,7 @@ semaphore_release(struct nouveau_channel *chan, struct nouveau_semaphore *sema)
}
/* Delay semaphore destruction until its work is done */
ret
=
nouveau_fence_new
(
chan
,
&
fence
,
true
);
ret
=
nouveau_fence_new
(
chan
,
&
fence
);
if
(
ret
)
return
ret
;
...
...
@@ -435,13 +396,13 @@ int
nouveau_fence_sync
(
struct
nouveau_fence
*
fence
,
struct
nouveau_channel
*
wchan
)
{
struct
nouveau_channel
*
chan
=
nouveau_fence_channel
(
fence
)
;
struct
nouveau_channel
*
chan
;
struct
drm_device
*
dev
=
wchan
->
dev
;
struct
nouveau_semaphore
*
sema
;
int
ret
=
0
;
if
(
likely
(
!
chan
||
chan
==
wchan
||
nouveau_fence_signalled
(
fence
)))
chan
=
fence
?
nouveau_channel_get_unlocked
(
fence
->
channel
)
:
NULL
;
if
(
likely
(
!
chan
||
chan
==
wchan
||
nouveau_fence_done
(
fence
)))
goto
out
;
sema
=
semaphore_alloc
(
dev
);
...
...
@@ -479,12 +440,6 @@ nouveau_fence_sync(struct nouveau_fence *fence,
return
ret
;
}
int
__nouveau_fence_flush
(
void
*
sync_obj
,
void
*
sync_arg
)
{
return
0
;
}
int
nouveau_fence_channel_init
(
struct
nouveau_channel
*
chan
)
{
...
...
@@ -538,14 +493,14 @@ nouveau_fence_channel_fini(struct nouveau_channel *chan)
struct
nouveau_fence
*
tmp
,
*
fence
;
spin_lock
(
&
chan
->
fence
.
lock
);
list_for_each_entry_safe
(
fence
,
tmp
,
&
chan
->
fence
.
pending
,
entry
)
{
fence
->
signalled
=
true
;
list_del
(
&
fence
->
entry
);
list_for_each_entry_safe
(
fence
,
tmp
,
&
chan
->
fence
.
pending
,
head
)
{
fence
->
channel
=
NULL
;
list_del
(
&
fence
->
head
);
if
(
unlikely
(
fence
->
work
))
fence
->
work
(
fence
->
priv
,
false
);
kref_put
(
&
fence
->
refcount
,
nouveau_fence_del
);
kref_put
(
&
fence
->
kref
,
nouveau_fence_del
);
}
spin_unlock
(
&
chan
->
fence
.
lock
);
...
...
drivers/gpu/drm/nouveau/nouveau_fence.h
0 → 100644
View file @
d375e7d5
#ifndef __NOUVEAU_FENCE_H__
#define __NOUVEAU_FENCE_H__
struct
nouveau_fence
{
struct
list_head
head
;
struct
kref
kref
;
struct
nouveau_channel
*
channel
;
unsigned
long
timeout
;
u32
sequence
;
void
(
*
work
)(
void
*
priv
,
bool
signalled
);
void
*
priv
;
};
int
nouveau_fence_new
(
struct
nouveau_channel
*
,
struct
nouveau_fence
**
);
struct
nouveau_fence
*
nouveau_fence_ref
(
struct
nouveau_fence
*
);
void
nouveau_fence_unref
(
struct
nouveau_fence
**
);
int
nouveau_fence_emit
(
struct
nouveau_fence
*
,
struct
nouveau_channel
*
);
bool
nouveau_fence_done
(
struct
nouveau_fence
*
);
int
nouveau_fence_wait
(
struct
nouveau_fence
*
,
bool
lazy
,
bool
intr
);
int
nouveau_fence_sync
(
struct
nouveau_fence
*
,
struct
nouveau_channel
*
);
void
nouveau_fence_idle
(
struct
nouveau_channel
*
);
void
nouveau_fence_update
(
struct
nouveau_channel
*
);
#endif
drivers/gpu/drm/nouveau/nouveau_gem.c
View file @
d375e7d5
...
...
@@ -30,6 +30,7 @@
#include "nouveau_drv.h"
#include "nouveau_drm.h"
#include "nouveau_dma.h"
#include "nouveau_fence.h"
#define nouveau_gem_pushbuf_sync(chan) 0
...
...
@@ -778,7 +779,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
}
}
ret
=
nouveau_fence_new
(
chan
,
&
fence
,
true
);
ret
=
nouveau_fence_new
(
chan
,
&
fence
);
if
(
ret
)
{
NV_ERROR
(
dev
,
"error fencing pushbuf: %d
\n
"
,
ret
);
WIND_RING
(
chan
);
...
...
drivers/gpu/drm/nouveau/nouveau_mem.c
View file @
d375e7d5
...
...
@@ -39,6 +39,7 @@
#include "nouveau_pm.h"
#include "nouveau_mm.h"
#include "nouveau_vm.h"
#include "nouveau_fence.h"
/*
* NV10-NV40 tiling helpers
...
...
@@ -89,7 +90,7 @@ nv10_mem_get_tile_region(struct drm_device *dev, int i)
spin_lock
(
&
dev_priv
->
tile
.
lock
);
if
(
!
tile
->
used
&&
(
!
tile
->
fence
||
nouveau_fence_
signalled
(
tile
->
fence
)))
(
!
tile
->
fence
||
nouveau_fence_
done
(
tile
->
fence
)))
tile
->
used
=
true
;
else
tile
=
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