aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon
diff options
context:
space:
mode:
authorChristian König <deathsimple@vodafone.de>2011-09-15 13:02:22 -0400
committerDave Airlie <airlied@redhat.com>2011-12-20 14:49:36 -0500
commit15d3332f31afd571a6d23971dbc8d8db2856e661 (patch)
tree71610dd9dd6c455fe2f4ec3639691b10388d1dab /drivers/gpu/drm/radeon
parent7465280c076d6440e5908c158c83b542dc063a30 (diff)
drm/radeon/kms: add support for semaphores v3
They are used to sync between rings, while fences sync between a ring and the cpu. v2 Fix radeon_semaphore_driver_fini when no semaphore were allocated. v3 Initialize list early on to avoid issue in case or early error Signed-off-by: Christian König <deathsimple@vodafone.de> Signed-off-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon')
-rw-r--r--drivers/gpu/drm/radeon/Makefile5
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c3
-rw-r--r--drivers/gpu/drm/radeon/ni.c3
-rw-r--r--drivers/gpu/drm/radeon/r100.c8
-rw-r--r--drivers/gpu/drm/radeon/r600.c15
-rw-r--r--drivers/gpu/drm/radeon/r600_cp.c2
-rw-r--r--drivers/gpu/drm/radeon/r600d.h2
-rw-r--r--drivers/gpu/drm/radeon/radeon.h29
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.c17
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h6
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_semaphore.c161
-rw-r--r--drivers/gpu/drm/radeon/rv770.c1
13 files changed, 248 insertions, 6 deletions
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index cf8b4bc3e73d..94dcdc746041 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -70,7 +70,8 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
70 r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ 70 r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \
71 r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \ 71 r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \
72 evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o \ 72 evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o \
73 radeon_trace_points.o ni.o cayman_blit_shaders.o atombios_encoders.o 73 radeon_trace_points.o ni.o cayman_blit_shaders.o atombios_encoders.o \
74 radeon_semaphore.o
74 75
75radeon-$(CONFIG_COMPAT) += radeon_ioc32.o 76radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
76radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o 77radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
@@ -78,4 +79,4 @@ radeon-$(CONFIG_ACPI) += radeon_acpi.o
78 79
79obj-$(CONFIG_DRM_RADEON)+= radeon.o 80obj-$(CONFIG_DRM_RADEON)+= radeon.o
80 81
81CFLAGS_radeon_trace_points.o := -I$(src) \ No newline at end of file 82CFLAGS_radeon_trace_points.o := -I$(src)
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 1c7af5654336..233cbc0a2b59 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -1448,7 +1448,7 @@ int evergreen_cp_resume(struct radeon_device *rdev)
1448 tmp |= BUF_SWAP_32BIT; 1448 tmp |= BUF_SWAP_32BIT;
1449#endif 1449#endif
1450 WREG32(CP_RB_CNTL, tmp); 1450 WREG32(CP_RB_CNTL, tmp);
1451 WREG32(CP_SEM_WAIT_TIMER, 0x4); 1451 WREG32(CP_SEM_WAIT_TIMER, 0x0);
1452 1452
1453 /* Set the write pointer delay */ 1453 /* Set the write pointer delay */
1454 WREG32(CP_RB_WPTR_DELAY, 0); 1454 WREG32(CP_RB_WPTR_DELAY, 0);
@@ -3290,6 +3290,7 @@ void evergreen_fini(struct radeon_device *rdev)
3290 evergreen_pcie_gart_fini(rdev); 3290 evergreen_pcie_gart_fini(rdev);
3291 r600_vram_scratch_fini(rdev); 3291 r600_vram_scratch_fini(rdev);
3292 radeon_gem_fini(rdev); 3292 radeon_gem_fini(rdev);
3293 radeon_semaphore_driver_fini(rdev);
3293 radeon_fence_driver_fini(rdev); 3294 radeon_fence_driver_fini(rdev);
3294 radeon_agp_fini(rdev); 3295 radeon_agp_fini(rdev);
3295 radeon_bo_fini(rdev); 3296 radeon_bo_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 710ad8c82767..ef749950db08 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1136,7 +1136,7 @@ int cayman_cp_resume(struct radeon_device *rdev)
1136 WREG32(GRBM_SOFT_RESET, 0); 1136 WREG32(GRBM_SOFT_RESET, 0);
1137 RREG32(GRBM_SOFT_RESET); 1137 RREG32(GRBM_SOFT_RESET);
1138 1138
1139 WREG32(CP_SEM_WAIT_TIMER, 0x4); 1139 WREG32(CP_SEM_WAIT_TIMER, 0x0);
1140 1140
1141 /* Set the write pointer delay */ 1141 /* Set the write pointer delay */
1142 WREG32(CP_RB_WPTR_DELAY, 0); 1142 WREG32(CP_RB_WPTR_DELAY, 0);
@@ -1557,6 +1557,7 @@ void cayman_fini(struct radeon_device *rdev)
1557 cayman_pcie_gart_fini(rdev); 1557 cayman_pcie_gart_fini(rdev);
1558 r600_vram_scratch_fini(rdev); 1558 r600_vram_scratch_fini(rdev);
1559 radeon_gem_fini(rdev); 1559 radeon_gem_fini(rdev);
1560 radeon_semaphore_driver_fini(rdev);
1560 radeon_fence_driver_fini(rdev); 1561 radeon_fence_driver_fini(rdev);
1561 radeon_bo_fini(rdev); 1562 radeon_bo_fini(rdev);
1562 radeon_atombios_fini(rdev); 1563 radeon_atombios_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index d2dced5679b5..2f18163e5e32 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -832,6 +832,14 @@ void r100_fence_ring_emit(struct radeon_device *rdev,
832 radeon_ring_write(rdev, RADEON_SW_INT_FIRE); 832 radeon_ring_write(rdev, RADEON_SW_INT_FIRE);
833} 833}
834 834
835void r100_semaphore_ring_emit(struct radeon_device *rdev,
836 struct radeon_semaphore *semaphore,
837 unsigned ring, bool emit_wait)
838{
839 /* Unused on older asics, since we don't have semaphores or multiple rings */
840 BUG();
841}
842
835int r100_copy_blit(struct radeon_device *rdev, 843int r100_copy_blit(struct radeon_device *rdev,
836 uint64_t src_offset, 844 uint64_t src_offset,
837 uint64_t dst_offset, 845 uint64_t dst_offset,
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 2fff8cec723c..bd2b3d087b16 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2190,7 +2190,7 @@ int r600_cp_resume(struct radeon_device *rdev)
2190 tmp |= BUF_SWAP_32BIT; 2190 tmp |= BUF_SWAP_32BIT;
2191#endif 2191#endif
2192 WREG32(CP_RB_CNTL, tmp); 2192 WREG32(CP_RB_CNTL, tmp);
2193 WREG32(CP_SEM_WAIT_TIMER, 0x4); 2193 WREG32(CP_SEM_WAIT_TIMER, 0x0);
2194 2194
2195 /* Set the write pointer delay */ 2195 /* Set the write pointer delay */
2196 WREG32(CP_RB_WPTR_DELAY, 0); 2196 WREG32(CP_RB_WPTR_DELAY, 0);
@@ -2357,6 +2357,18 @@ void r600_fence_ring_emit(struct radeon_device *rdev,
2357 } 2357 }
2358} 2358}
2359 2359
2360void r600_semaphore_ring_emit(struct radeon_device *rdev,
2361 struct radeon_semaphore *semaphore,
2362 unsigned ring, bool emit_wait)
2363{
2364 uint64_t addr = semaphore->gpu_addr;
2365 unsigned sel = emit_wait ? PACKET3_SEM_SEL_WAIT : PACKET3_SEM_SEL_SIGNAL;
2366
2367 radeon_ring_write(rdev, PACKET3(PACKET3_MEM_SEMAPHORE, 1));
2368 radeon_ring_write(rdev, addr & 0xffffffff);
2369 radeon_ring_write(rdev, (upper_32_bits(addr) & 0xff) | sel);
2370}
2371
2360int r600_copy_blit(struct radeon_device *rdev, 2372int r600_copy_blit(struct radeon_device *rdev,
2361 uint64_t src_offset, 2373 uint64_t src_offset,
2362 uint64_t dst_offset, 2374 uint64_t dst_offset,
@@ -2649,6 +2661,7 @@ void r600_fini(struct radeon_device *rdev)
2649 r600_vram_scratch_fini(rdev); 2661 r600_vram_scratch_fini(rdev);
2650 radeon_agp_fini(rdev); 2662 radeon_agp_fini(rdev);
2651 radeon_gem_fini(rdev); 2663 radeon_gem_fini(rdev);
2664 radeon_semaphore_driver_fini(rdev);
2652 radeon_fence_driver_fini(rdev); 2665 radeon_fence_driver_fini(rdev);
2653 radeon_bo_fini(rdev); 2666 radeon_bo_fini(rdev);
2654 radeon_atombios_fini(rdev); 2667 radeon_atombios_fini(rdev);
diff --git a/drivers/gpu/drm/radeon/r600_cp.c b/drivers/gpu/drm/radeon/r600_cp.c
index c9db4931913f..84c546250955 100644
--- a/drivers/gpu/drm/radeon/r600_cp.c
+++ b/drivers/gpu/drm/radeon/r600_cp.c
@@ -1815,7 +1815,7 @@ static void r600_cp_init_ring_buffer(struct drm_device *dev,
1815 dev_priv->ring.size_l2qw); 1815 dev_priv->ring.size_l2qw);
1816#endif 1816#endif
1817 1817
1818 RADEON_WRITE(R600_CP_SEM_WAIT_TIMER, 0x4); 1818 RADEON_WRITE(R600_CP_SEM_WAIT_TIMER, 0x0);
1819 1819
1820 /* Set the write pointer delay */ 1820 /* Set the write pointer delay */
1821 RADEON_WRITE(R600_CP_RB_WPTR_DELAY, 0); 1821 RADEON_WRITE(R600_CP_RB_WPTR_DELAY, 0);
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
index bfe1b5d92afe..3ee1fd7ef394 100644
--- a/drivers/gpu/drm/radeon/r600d.h
+++ b/drivers/gpu/drm/radeon/r600d.h
@@ -831,6 +831,8 @@
831#define PACKET3_STRMOUT_BUFFER_UPDATE 0x34 831#define PACKET3_STRMOUT_BUFFER_UPDATE 0x34
832#define PACKET3_INDIRECT_BUFFER_MP 0x38 832#define PACKET3_INDIRECT_BUFFER_MP 0x38
833#define PACKET3_MEM_SEMAPHORE 0x39 833#define PACKET3_MEM_SEMAPHORE 0x39
834# define PACKET3_SEM_SEL_SIGNAL (0x6 << 29)
835# define PACKET3_SEM_SEL_WAIT (0x7 << 29)
834#define PACKET3_MPEG_INDEX 0x3A 836#define PACKET3_MPEG_INDEX 0x3A
835#define PACKET3_WAIT_REG_MEM 0x3C 837#define PACKET3_WAIT_REG_MEM 0x3C
836#define PACKET3_MEM_WRITE 0x3D 838#define PACKET3_MEM_WRITE 0x3D
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 8b93dec66ec6..6d84c64759e9 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -228,6 +228,30 @@ struct radeon_fence *radeon_fence_ref(struct radeon_fence *fence);
228void radeon_fence_unref(struct radeon_fence **fence); 228void radeon_fence_unref(struct radeon_fence **fence);
229 229
230/* 230/*
231 * Semaphores.
232 */
233struct radeon_semaphore_driver {
234 rwlock_t lock;
235 struct list_head free;
236};
237
238struct radeon_semaphore {
239 struct radeon_bo *robj;
240 struct list_head list;
241 uint64_t gpu_addr;
242};
243
244void radeon_semaphore_driver_fini(struct radeon_device *rdev);
245int radeon_semaphore_create(struct radeon_device *rdev,
246 struct radeon_semaphore **semaphore);
247void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring,
248 struct radeon_semaphore *semaphore);
249void radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring,
250 struct radeon_semaphore *semaphore);
251void radeon_semaphore_free(struct radeon_device *rdev,
252 struct radeon_semaphore *semaphore);
253
254/*
231 * Tiling registers 255 * Tiling registers
232 */ 256 */
233struct radeon_surface_reg { 257struct radeon_surface_reg {
@@ -921,6 +945,9 @@ struct radeon_asic {
921 int (*irq_process)(struct radeon_device *rdev); 945 int (*irq_process)(struct radeon_device *rdev);
922 u32 (*get_vblank_counter)(struct radeon_device *rdev, int crtc); 946 u32 (*get_vblank_counter)(struct radeon_device *rdev, int crtc);
923 void (*fence_ring_emit)(struct radeon_device *rdev, struct radeon_fence *fence); 947 void (*fence_ring_emit)(struct radeon_device *rdev, struct radeon_fence *fence);
948 void (*semaphore_ring_emit)(struct radeon_device *rdev,
949 struct radeon_semaphore *semaphore,
950 unsigned ring, bool emit_wait);
924 int (*cs_parse)(struct radeon_cs_parser *p); 951 int (*cs_parse)(struct radeon_cs_parser *p);
925 int (*copy_blit)(struct radeon_device *rdev, 952 int (*copy_blit)(struct radeon_device *rdev,
926 uint64_t src_offset, 953 uint64_t src_offset,
@@ -1250,6 +1277,7 @@ struct radeon_device {
1250 struct radeon_mman mman; 1277 struct radeon_mman mman;
1251 rwlock_t fence_lock; 1278 rwlock_t fence_lock;
1252 struct radeon_fence_driver fence_drv[RADEON_NUM_RINGS]; 1279 struct radeon_fence_driver fence_drv[RADEON_NUM_RINGS];
1280 struct radeon_semaphore_driver semaphore_drv;
1253 struct radeon_cp cp; 1281 struct radeon_cp cp;
1254 /* cayman compute rings */ 1282 /* cayman compute rings */
1255 struct radeon_cp cp1; 1283 struct radeon_cp cp1;
@@ -1470,6 +1498,7 @@ void radeon_ring_write(struct radeon_device *rdev, uint32_t v);
1470#define radeon_irq_process(rdev) (rdev)->asic->irq_process((rdev)) 1498#define radeon_irq_process(rdev) (rdev)->asic->irq_process((rdev))
1471#define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->get_vblank_counter((rdev), (crtc)) 1499#define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->get_vblank_counter((rdev), (crtc))
1472#define radeon_fence_ring_emit(rdev, fence) (rdev)->asic->fence_ring_emit((rdev), (fence)) 1500#define radeon_fence_ring_emit(rdev, fence) (rdev)->asic->fence_ring_emit((rdev), (fence))
1501#define radeon_semaphore_ring_emit(rdev, semaphore, ring, emit_wait) (rdev)->asic->semaphore_ring_emit((rdev), (semaphore), (ring), (emit_wait))
1473#define radeon_copy_blit(rdev, s, d, np, f) (rdev)->asic->copy_blit((rdev), (s), (d), (np), (f)) 1502#define radeon_copy_blit(rdev, s, d, np, f) (rdev)->asic->copy_blit((rdev), (s), (d), (np), (f))
1474#define radeon_copy_dma(rdev, s, d, np, f) (rdev)->asic->copy_dma((rdev), (s), (d), (np), (f)) 1503#define radeon_copy_dma(rdev, s, d, np, f) (rdev)->asic->copy_dma((rdev), (s), (d), (np), (f))
1475#define radeon_copy(rdev, s, d, np, f) (rdev)->asic->copy((rdev), (s), (d), (np), (f)) 1504#define radeon_copy(rdev, s, d, np, f) (rdev)->asic->copy((rdev), (s), (d), (np), (f))
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
index a2e1eae114ef..8cfbbc77d70b 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -146,6 +146,7 @@ static struct radeon_asic r100_asic = {
146 .irq_process = &r100_irq_process, 146 .irq_process = &r100_irq_process,
147 .get_vblank_counter = &r100_get_vblank_counter, 147 .get_vblank_counter = &r100_get_vblank_counter,
148 .fence_ring_emit = &r100_fence_ring_emit, 148 .fence_ring_emit = &r100_fence_ring_emit,
149 .semaphore_ring_emit = &r100_semaphore_ring_emit,
149 .cs_parse = &r100_cs_parse, 150 .cs_parse = &r100_cs_parse,
150 .copy_blit = &r100_copy_blit, 151 .copy_blit = &r100_copy_blit,
151 .copy_dma = NULL, 152 .copy_dma = NULL,
@@ -194,6 +195,7 @@ static struct radeon_asic r200_asic = {
194 .irq_process = &r100_irq_process, 195 .irq_process = &r100_irq_process,
195 .get_vblank_counter = &r100_get_vblank_counter, 196 .get_vblank_counter = &r100_get_vblank_counter,
196 .fence_ring_emit = &r100_fence_ring_emit, 197 .fence_ring_emit = &r100_fence_ring_emit,
198 .semaphore_ring_emit = &r100_semaphore_ring_emit,
197 .cs_parse = &r100_cs_parse, 199 .cs_parse = &r100_cs_parse,
198 .copy_blit = &r100_copy_blit, 200 .copy_blit = &r100_copy_blit,
199 .copy_dma = &r200_copy_dma, 201 .copy_dma = &r200_copy_dma,
@@ -241,6 +243,7 @@ static struct radeon_asic r300_asic = {
241 .irq_process = &r100_irq_process, 243 .irq_process = &r100_irq_process,
242 .get_vblank_counter = &r100_get_vblank_counter, 244 .get_vblank_counter = &r100_get_vblank_counter,
243 .fence_ring_emit = &r300_fence_ring_emit, 245 .fence_ring_emit = &r300_fence_ring_emit,
246 .semaphore_ring_emit = &r100_semaphore_ring_emit,
244 .cs_parse = &r300_cs_parse, 247 .cs_parse = &r300_cs_parse,
245 .copy_blit = &r100_copy_blit, 248 .copy_blit = &r100_copy_blit,
246 .copy_dma = &r200_copy_dma, 249 .copy_dma = &r200_copy_dma,
@@ -289,6 +292,7 @@ static struct radeon_asic r300_asic_pcie = {
289 .irq_process = &r100_irq_process, 292 .irq_process = &r100_irq_process,
290 .get_vblank_counter = &r100_get_vblank_counter, 293 .get_vblank_counter = &r100_get_vblank_counter,
291 .fence_ring_emit = &r300_fence_ring_emit, 294 .fence_ring_emit = &r300_fence_ring_emit,
295 .semaphore_ring_emit = &r100_semaphore_ring_emit,
292 .cs_parse = &r300_cs_parse, 296 .cs_parse = &r300_cs_parse,
293 .copy_blit = &r100_copy_blit, 297 .copy_blit = &r100_copy_blit,
294 .copy_dma = &r200_copy_dma, 298 .copy_dma = &r200_copy_dma,
@@ -336,6 +340,7 @@ static struct radeon_asic r420_asic = {
336 .irq_process = &r100_irq_process, 340 .irq_process = &r100_irq_process,
337 .get_vblank_counter = &r100_get_vblank_counter, 341 .get_vblank_counter = &r100_get_vblank_counter,
338 .fence_ring_emit = &r300_fence_ring_emit, 342 .fence_ring_emit = &r300_fence_ring_emit,
343 .semaphore_ring_emit = &r100_semaphore_ring_emit,
339 .cs_parse = &r300_cs_parse, 344 .cs_parse = &r300_cs_parse,
340 .copy_blit = &r100_copy_blit, 345 .copy_blit = &r100_copy_blit,
341 .copy_dma = &r200_copy_dma, 346 .copy_dma = &r200_copy_dma,
@@ -384,6 +389,7 @@ static struct radeon_asic rs400_asic = {
384 .irq_process = &r100_irq_process, 389 .irq_process = &r100_irq_process,
385 .get_vblank_counter = &r100_get_vblank_counter, 390 .get_vblank_counter = &r100_get_vblank_counter,
386 .fence_ring_emit = &r300_fence_ring_emit, 391 .fence_ring_emit = &r300_fence_ring_emit,
392 .semaphore_ring_emit = &r100_semaphore_ring_emit,
387 .cs_parse = &r300_cs_parse, 393 .cs_parse = &r300_cs_parse,
388 .copy_blit = &r100_copy_blit, 394 .copy_blit = &r100_copy_blit,
389 .copy_dma = &r200_copy_dma, 395 .copy_dma = &r200_copy_dma,
@@ -432,6 +438,7 @@ static struct radeon_asic rs600_asic = {
432 .irq_process = &rs600_irq_process, 438 .irq_process = &rs600_irq_process,
433 .get_vblank_counter = &rs600_get_vblank_counter, 439 .get_vblank_counter = &rs600_get_vblank_counter,
434 .fence_ring_emit = &r300_fence_ring_emit, 440 .fence_ring_emit = &r300_fence_ring_emit,
441 .semaphore_ring_emit = &r100_semaphore_ring_emit,
435 .cs_parse = &r300_cs_parse, 442 .cs_parse = &r300_cs_parse,
436 .copy_blit = &r100_copy_blit, 443 .copy_blit = &r100_copy_blit,
437 .copy_dma = &r200_copy_dma, 444 .copy_dma = &r200_copy_dma,
@@ -480,6 +487,7 @@ static struct radeon_asic rs690_asic = {
480 .irq_process = &rs600_irq_process, 487 .irq_process = &rs600_irq_process,
481 .get_vblank_counter = &rs600_get_vblank_counter, 488 .get_vblank_counter = &rs600_get_vblank_counter,
482 .fence_ring_emit = &r300_fence_ring_emit, 489 .fence_ring_emit = &r300_fence_ring_emit,
490 .semaphore_ring_emit = &r100_semaphore_ring_emit,
483 .cs_parse = &r300_cs_parse, 491 .cs_parse = &r300_cs_parse,
484 .copy_blit = &r100_copy_blit, 492 .copy_blit = &r100_copy_blit,
485 .copy_dma = &r200_copy_dma, 493 .copy_dma = &r200_copy_dma,
@@ -528,6 +536,7 @@ static struct radeon_asic rv515_asic = {
528 .irq_process = &rs600_irq_process, 536 .irq_process = &rs600_irq_process,
529 .get_vblank_counter = &rs600_get_vblank_counter, 537 .get_vblank_counter = &rs600_get_vblank_counter,
530 .fence_ring_emit = &r300_fence_ring_emit, 538 .fence_ring_emit = &r300_fence_ring_emit,
539 .semaphore_ring_emit = &r100_semaphore_ring_emit,
531 .cs_parse = &r300_cs_parse, 540 .cs_parse = &r300_cs_parse,
532 .copy_blit = &r100_copy_blit, 541 .copy_blit = &r100_copy_blit,
533 .copy_dma = &r200_copy_dma, 542 .copy_dma = &r200_copy_dma,
@@ -576,6 +585,7 @@ static struct radeon_asic r520_asic = {
576 .irq_process = &rs600_irq_process, 585 .irq_process = &rs600_irq_process,
577 .get_vblank_counter = &rs600_get_vblank_counter, 586 .get_vblank_counter = &rs600_get_vblank_counter,
578 .fence_ring_emit = &r300_fence_ring_emit, 587 .fence_ring_emit = &r300_fence_ring_emit,
588 .semaphore_ring_emit = &r100_semaphore_ring_emit,
579 .cs_parse = &r300_cs_parse, 589 .cs_parse = &r300_cs_parse,
580 .copy_blit = &r100_copy_blit, 590 .copy_blit = &r100_copy_blit,
581 .copy_dma = &r200_copy_dma, 591 .copy_dma = &r200_copy_dma,
@@ -623,6 +633,7 @@ static struct radeon_asic r600_asic = {
623 .irq_process = &r600_irq_process, 633 .irq_process = &r600_irq_process,
624 .get_vblank_counter = &rs600_get_vblank_counter, 634 .get_vblank_counter = &rs600_get_vblank_counter,
625 .fence_ring_emit = &r600_fence_ring_emit, 635 .fence_ring_emit = &r600_fence_ring_emit,
636 .semaphore_ring_emit = &r600_semaphore_ring_emit,
626 .cs_parse = &r600_cs_parse, 637 .cs_parse = &r600_cs_parse,
627 .copy_blit = &r600_copy_blit, 638 .copy_blit = &r600_copy_blit,
628 .copy_dma = NULL, 639 .copy_dma = NULL,
@@ -670,6 +681,7 @@ static struct radeon_asic rs780_asic = {
670 .irq_process = &r600_irq_process, 681 .irq_process = &r600_irq_process,
671 .get_vblank_counter = &rs600_get_vblank_counter, 682 .get_vblank_counter = &rs600_get_vblank_counter,
672 .fence_ring_emit = &r600_fence_ring_emit, 683 .fence_ring_emit = &r600_fence_ring_emit,
684 .semaphore_ring_emit = &r600_semaphore_ring_emit,
673 .cs_parse = &r600_cs_parse, 685 .cs_parse = &r600_cs_parse,
674 .copy_blit = &r600_copy_blit, 686 .copy_blit = &r600_copy_blit,
675 .copy_dma = NULL, 687 .copy_dma = NULL,
@@ -717,6 +729,7 @@ static struct radeon_asic rv770_asic = {
717 .irq_process = &r600_irq_process, 729 .irq_process = &r600_irq_process,
718 .get_vblank_counter = &rs600_get_vblank_counter, 730 .get_vblank_counter = &rs600_get_vblank_counter,
719 .fence_ring_emit = &r600_fence_ring_emit, 731 .fence_ring_emit = &r600_fence_ring_emit,
732 .semaphore_ring_emit = &r600_semaphore_ring_emit,
720 .cs_parse = &r600_cs_parse, 733 .cs_parse = &r600_cs_parse,
721 .copy_blit = &r600_copy_blit, 734 .copy_blit = &r600_copy_blit,
722 .copy_dma = NULL, 735 .copy_dma = NULL,
@@ -764,6 +777,7 @@ static struct radeon_asic evergreen_asic = {
764 .irq_process = &evergreen_irq_process, 777 .irq_process = &evergreen_irq_process,
765 .get_vblank_counter = &evergreen_get_vblank_counter, 778 .get_vblank_counter = &evergreen_get_vblank_counter,
766 .fence_ring_emit = &r600_fence_ring_emit, 779 .fence_ring_emit = &r600_fence_ring_emit,
780 .semaphore_ring_emit = &r600_semaphore_ring_emit,
767 .cs_parse = &evergreen_cs_parse, 781 .cs_parse = &evergreen_cs_parse,
768 .copy_blit = &r600_copy_blit, 782 .copy_blit = &r600_copy_blit,
769 .copy_dma = NULL, 783 .copy_dma = NULL,
@@ -811,6 +825,7 @@ static struct radeon_asic sumo_asic = {
811 .irq_process = &evergreen_irq_process, 825 .irq_process = &evergreen_irq_process,
812 .get_vblank_counter = &evergreen_get_vblank_counter, 826 .get_vblank_counter = &evergreen_get_vblank_counter,
813 .fence_ring_emit = &r600_fence_ring_emit, 827 .fence_ring_emit = &r600_fence_ring_emit,
828 .semaphore_ring_emit = &r600_semaphore_ring_emit,
814 .cs_parse = &evergreen_cs_parse, 829 .cs_parse = &evergreen_cs_parse,
815 .copy_blit = &r600_copy_blit, 830 .copy_blit = &r600_copy_blit,
816 .copy_dma = NULL, 831 .copy_dma = NULL,
@@ -858,6 +873,7 @@ static struct radeon_asic btc_asic = {
858 .irq_process = &evergreen_irq_process, 873 .irq_process = &evergreen_irq_process,
859 .get_vblank_counter = &evergreen_get_vblank_counter, 874 .get_vblank_counter = &evergreen_get_vblank_counter,
860 .fence_ring_emit = &r600_fence_ring_emit, 875 .fence_ring_emit = &r600_fence_ring_emit,
876 .semaphore_ring_emit = &r600_semaphore_ring_emit,
861 .cs_parse = &evergreen_cs_parse, 877 .cs_parse = &evergreen_cs_parse,
862 .copy_blit = &r600_copy_blit, 878 .copy_blit = &r600_copy_blit,
863 .copy_dma = NULL, 879 .copy_dma = NULL,
@@ -905,6 +921,7 @@ static struct radeon_asic cayman_asic = {
905 .irq_process = &evergreen_irq_process, 921 .irq_process = &evergreen_irq_process,
906 .get_vblank_counter = &evergreen_get_vblank_counter, 922 .get_vblank_counter = &evergreen_get_vblank_counter,
907 .fence_ring_emit = &r600_fence_ring_emit, 923 .fence_ring_emit = &r600_fence_ring_emit,
924 .semaphore_ring_emit = &r600_semaphore_ring_emit,
908 .cs_parse = &evergreen_cs_parse, 925 .cs_parse = &evergreen_cs_parse,
909 .copy_blit = &r600_copy_blit, 926 .copy_blit = &r600_copy_blit,
910 .copy_dma = NULL, 927 .copy_dma = NULL,
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index 59914842a729..6b589d5ae436 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -69,6 +69,9 @@ int r100_irq_set(struct radeon_device *rdev);
69int r100_irq_process(struct radeon_device *rdev); 69int r100_irq_process(struct radeon_device *rdev);
70void r100_fence_ring_emit(struct radeon_device *rdev, 70void r100_fence_ring_emit(struct radeon_device *rdev,
71 struct radeon_fence *fence); 71 struct radeon_fence *fence);
72void r100_semaphore_ring_emit(struct radeon_device *rdev,
73 struct radeon_semaphore *semaphore,
74 unsigned ring, bool emit_wait);
72int r100_cs_parse(struct radeon_cs_parser *p); 75int r100_cs_parse(struct radeon_cs_parser *p);
73void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); 76void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
74uint32_t r100_pll_rreg(struct radeon_device *rdev, uint32_t reg); 77uint32_t r100_pll_rreg(struct radeon_device *rdev, uint32_t reg);
@@ -300,6 +303,9 @@ void r600_pciep_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
300int r600_cs_parse(struct radeon_cs_parser *p); 303int r600_cs_parse(struct radeon_cs_parser *p);
301void r600_fence_ring_emit(struct radeon_device *rdev, 304void r600_fence_ring_emit(struct radeon_device *rdev,
302 struct radeon_fence *fence); 305 struct radeon_fence *fence);
306void r600_semaphore_ring_emit(struct radeon_device *rdev,
307 struct radeon_semaphore *semaphore,
308 unsigned ring, bool emit_wait);
303bool r600_gpu_is_lockup(struct radeon_device *rdev); 309bool r600_gpu_is_lockup(struct radeon_device *rdev);
304int r600_asic_reset(struct radeon_device *rdev); 310int r600_asic_reset(struct radeon_device *rdev);
305int r600_set_surface_reg(struct radeon_device *rdev, int reg, 311int r600_set_surface_reg(struct radeon_device *rdev, int reg,
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 4ed4eeb62cdf..36296ad397a1 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -726,9 +726,11 @@ int radeon_device_init(struct radeon_device *rdev,
726 mutex_init(&rdev->pm.mutex); 726 mutex_init(&rdev->pm.mutex);
727 mutex_init(&rdev->vram_mutex); 727 mutex_init(&rdev->vram_mutex);
728 rwlock_init(&rdev->fence_lock); 728 rwlock_init(&rdev->fence_lock);
729 rwlock_init(&rdev->semaphore_drv.lock);
729 INIT_LIST_HEAD(&rdev->gem.objects); 730 INIT_LIST_HEAD(&rdev->gem.objects);
730 init_waitqueue_head(&rdev->irq.vblank_queue); 731 init_waitqueue_head(&rdev->irq.vblank_queue);
731 init_waitqueue_head(&rdev->irq.idle_queue); 732 init_waitqueue_head(&rdev->irq.idle_queue);
733 INIT_LIST_HEAD(&rdev->semaphore_drv.free);
732 734
733 /* Set asic functions */ 735 /* Set asic functions */
734 r = radeon_asic_init(rdev); 736 r = radeon_asic_init(rdev);
diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c
new file mode 100644
index 000000000000..f7d3104de6d4
--- /dev/null
+++ b/drivers/gpu/drm/radeon/radeon_semaphore.c
@@ -0,0 +1,161 @@
1/*
2 * Copyright 2011 Christian König.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
16 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
17 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
18 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19 * USE OR OTHER DEALINGS IN THE SOFTWARE.
20 *
21 * The above copyright notice and this permission notice (including the
22 * next paragraph) shall be included in all copies or substantial portions
23 * of the Software.
24 *
25 */
26/*
27 * Authors:
28 * Christian König <deathsimple@vodafone.de>
29 */
30#include "drmP.h"
31#include "drm.h"
32#include "radeon.h"
33
34static int allocate_semaphores(struct radeon_device *rdev)
35{
36 const unsigned long bo_size = PAGE_SIZE * 4;
37
38 struct radeon_bo *bo;
39 struct list_head new_entrys;
40 unsigned long irq_flags;
41 uint64_t gpu_addr;
42 void *map;
43 int i, r;
44
45 r = radeon_bo_create(rdev, bo_size, RADEON_GPU_PAGE_SIZE, true,
46 RADEON_GEM_DOMAIN_GTT, &bo);
47 if (r) {
48 dev_err(rdev->dev, "(%d) failed to allocate semaphore bo\n", r);
49 return r;
50 }
51
52 r = radeon_bo_reserve(bo, false);
53 if (r) {
54 radeon_bo_unref(&bo);
55 dev_err(rdev->dev, "(%d) failed to reserve semaphore bo\n", r);
56 return r;
57 }
58
59 r = radeon_bo_kmap(bo, &map);
60 if (r) {
61 radeon_bo_unreserve(bo);
62 radeon_bo_unref(&bo);
63 dev_err(rdev->dev, "(%d) semaphore map failed\n", r);
64 return r;
65 }
66 memset(map, 0, bo_size);
67 radeon_bo_kunmap(bo);
68
69 r = radeon_bo_pin(bo, RADEON_GEM_DOMAIN_VRAM, &gpu_addr);
70 if (r) {
71 radeon_bo_unreserve(bo);
72 radeon_bo_unref(&bo);
73 dev_err(rdev->dev, "(%d) semaphore pin failed\n", r);
74 return r;
75 }
76
77 INIT_LIST_HEAD(&new_entrys);
78 for (i = 0; i < bo_size/8; ++i) {
79 struct radeon_semaphore *sem = kmalloc(sizeof(struct radeon_semaphore), GFP_KERNEL);
80 ttm_bo_reference(&bo->tbo);
81 sem->robj = bo;
82 sem->gpu_addr = gpu_addr;
83 gpu_addr += 8;
84 list_add_tail(&sem->list, &new_entrys);
85 }
86
87 radeon_bo_unreserve(bo);
88 radeon_bo_unref(&bo);
89
90 write_lock_irqsave(&rdev->semaphore_drv.lock, irq_flags);
91 list_splice_tail(&new_entrys, &rdev->semaphore_drv.free);
92 write_unlock_irqrestore(&rdev->semaphore_drv.lock, irq_flags);
93
94 DRM_INFO("%d new semaphores allocated\n", (int)(bo_size/8));
95
96 return 0;
97}
98
99int radeon_semaphore_create(struct radeon_device *rdev,
100 struct radeon_semaphore **semaphore)
101{
102 unsigned long irq_flags;
103
104 write_lock_irqsave(&rdev->semaphore_drv.lock, irq_flags);
105 if (list_empty(&rdev->semaphore_drv.free)) {
106 int r;
107 write_unlock_irqrestore(&rdev->semaphore_drv.lock, irq_flags);
108 r = allocate_semaphores(rdev);
109 if (r)
110 return r;
111 write_lock_irqsave(&rdev->semaphore_drv.lock, irq_flags);
112 }
113
114 *semaphore = list_first_entry(&rdev->semaphore_drv.free, struct radeon_semaphore, list);
115 list_del(&(*semaphore)->list);
116
117 write_unlock_irqrestore(&rdev->semaphore_drv.lock, irq_flags);
118 return 0;
119}
120
121void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring,
122 struct radeon_semaphore *semaphore)
123{
124 radeon_semaphore_ring_emit(rdev, semaphore, ring, false);
125}
126
127void radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring,
128 struct radeon_semaphore *semaphore)
129{
130 radeon_semaphore_ring_emit(rdev, semaphore, ring, true);
131}
132
133void radeon_semaphore_free(struct radeon_device *rdev,
134 struct radeon_semaphore *semaphore)
135{
136 unsigned long irq_flags;
137
138 write_lock_irqsave(&rdev->semaphore_drv.lock, irq_flags);
139 list_add_tail(&semaphore->list, &rdev->semaphore_drv.free);
140 write_unlock_irqrestore(&rdev->semaphore_drv.lock, irq_flags);
141}
142
143void radeon_semaphore_driver_fini(struct radeon_device *rdev)
144{
145 struct radeon_semaphore *i, *n;
146 struct list_head entrys;
147 unsigned long irq_flags;
148
149 INIT_LIST_HEAD(&entrys);
150 write_lock_irqsave(&rdev->semaphore_drv.lock, irq_flags);
151 if (!list_empty(&rdev->semaphore_drv.free)) {
152 list_splice(&rdev->semaphore_drv.free, &entrys);
153 }
154 INIT_LIST_HEAD(&rdev->semaphore_drv.free);
155 write_unlock_irqrestore(&rdev->semaphore_drv.lock, irq_flags);
156
157 list_for_each_entry_safe(i, n, &entrys, list) {
158 radeon_bo_unref(&i->robj);
159 kfree(i);
160 }
161}
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index 8637fd84e499..be02bee41213 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -1270,6 +1270,7 @@ void rv770_fini(struct radeon_device *rdev)
1270 rv770_pcie_gart_fini(rdev); 1270 rv770_pcie_gart_fini(rdev);
1271 r600_vram_scratch_fini(rdev); 1271 r600_vram_scratch_fini(rdev);
1272 radeon_gem_fini(rdev); 1272 radeon_gem_fini(rdev);
1273 radeon_semaphore_driver_fini(rdev);
1273 radeon_fence_driver_fini(rdev); 1274 radeon_fence_driver_fini(rdev);
1274 radeon_agp_fini(rdev); 1275 radeon_agp_fini(rdev);
1275 radeon_bo_fini(rdev); 1276 radeon_bo_fini(rdev);