[PATCH v2 09/17] drm/radeon: use common fence implementation for fences
On Wed, Jul 9, 2014 at 9:23 AM, Maarten Lankhorst wrote: > op 09-07-14 14:57, Deucher, Alexander schreef: >>> >>> +static const char *radeon_fence_get_timeline_name(struct fence *f) >>> +{ >>> +struct radeon_fence *fence = to_radeon_fence(f); >>> +switch (fence->ring) { >>> +case RADEON_RING_TYPE_GFX_INDEX: return "radeon.gfx"; >>> +case CAYMAN_RING_TYPE_CP1_INDEX: return "radeon.cp1"; >>> +case CAYMAN_RING_TYPE_CP2_INDEX: return "radeon.cp2"; >>> +case R600_RING_TYPE_DMA_INDEX: return "radeon.dma"; >>> +case CAYMAN_RING_TYPE_DMA1_INDEX: return "radeon.dma1"; >>> +case R600_RING_TYPE_UVD_INDEX: return "radeon.uvd"; >> Radeon supports vce rings on newer ascis. Probably want to add the case for >> those here too. >> >> Alex >> > Indeed, how about this? Looks good. I'll let Christian comment on the rest of the changes. Alex > --8<--- > Signed-off-by: Maarten Lankhorst > --- > drivers/gpu/drm/radeon/radeon.h| 15 +-- > drivers/gpu/drm/radeon/radeon_device.c | 60 - > drivers/gpu/drm/radeon/radeon_fence.c | 225 > +++-- > 3 files changed, 250 insertions(+), 50 deletions(-) > > diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h > index 29d9cc04c04e..03a5567f2c2f 100644 > --- a/drivers/gpu/drm/radeon/radeon.h > +++ b/drivers/gpu/drm/radeon/radeon.h > @@ -64,6 +64,7 @@ > #include > #include > #include > +#include > > #include > #include > @@ -116,9 +117,6 @@ extern int radeon_deep_color; > #define RADEONFB_CONN_LIMIT4 > #define RADEON_BIOS_NUM_SCRATCH8 > > -/* fence seq are set to this number when signaled */ > -#define RADEON_FENCE_SIGNALED_SEQ 0LL > - > /* internal ring indices */ > /* r1xx+ has gfx CP ring */ > #define RADEON_RING_TYPE_GFX_INDEX 0 > @@ -350,12 +348,15 @@ struct radeon_fence_driver { > }; > > struct radeon_fence { > + struct fence base; > + > struct radeon_device*rdev; > - struct kref kref; > /* protected by radeon_fence.lock */ > uint64_tseq; > /* RB, DMA, etc. */ > unsignedring; > + > + wait_queue_t fence_wake; > }; > > int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring); > @@ -2268,6 +2269,7 @@ struct radeon_device { > struct radeon_mman mman; > struct radeon_fence_driver fence_drv[RADEON_NUM_RINGS]; > wait_queue_head_t fence_queue; > + unsignedfence_context; > struct mutexring_lock; > struct radeon_ring ring[RADEON_NUM_RINGS]; > boolib_pool_ready; > @@ -2358,11 +2360,6 @@ u32 cik_mm_rdoorbell(struct radeon_device *rdev, u32 > index); > void cik_mm_wdoorbell(struct radeon_device *rdev, u32 index, u32 v); > > /* > - * Cast helper > - */ > -#define to_radeon_fence(p) ((struct radeon_fence *)(p)) > - > -/* > * Registers read & write functions. > */ > #define RREG8(reg) readb((rdev->rmmio) + (reg)) > diff --git a/drivers/gpu/drm/radeon/radeon_device.c > b/drivers/gpu/drm/radeon/radeon_device.c > index 03686fab842d..86699df7c8f3 100644 > --- a/drivers/gpu/drm/radeon/radeon_device.c > +++ b/drivers/gpu/drm/radeon/radeon_device.c > @@ -1213,6 +1213,7 @@ int radeon_device_init(struct radeon_device *rdev, > for (i = 0; i < RADEON_NUM_RINGS; i++) { > rdev->ring[i].idx = i; > } > + rdev->fence_context = fence_context_alloc(RADEON_NUM_RINGS); > > DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X > 0x%04X:0x%04X).\n", > radeon_family_name[rdev->family], pdev->vendor, pdev->device, > @@ -1607,6 +1608,54 @@ int radeon_resume_kms(struct drm_device *dev, bool > resume, bool fbcon) > return 0; > } > > +static uint32_t radeon_gpu_mask_sw_irq(struct radeon_device *rdev) > +{ > + uint32_t mask = 0; > + int i; > + > + if (!rdev->ddev->irq_enabled) > + return mask; > + > + /* > +* increase refcount on sw interrupts for all rings to stop > +* enabling interrupts in radeon_fence_enable_signaling during > +* gpu reset. > +*/ > + > + for (i = 0; i < RADEON_NUM_RINGS; ++i) { > + if (!rdev->ring[i].ready) > + continue; > + > + atomic_inc(>irq.ring_int[i]); > + mask |= 1 << i; > + } > + return mask; > +} > + > +static void radeon_gpu_unmask_sw_irq(struct radeon_device *rdev, uint32_t > mask) > +{ > + unsigned long irqflags; > + int i; > + > + if (!mask) > + return; > + > + /* > +* undo refcount increase, and reset irqs to correct value. > +*/ > + > + for (i = 0; i < RADEON_NUM_RINGS;
[PATCH v2 09/17] drm/radeon: use common fence implementation for fences
op 09-07-14 14:57, Deucher, Alexander schreef: >> >> +static const char *radeon_fence_get_timeline_name(struct fence *f) >> +{ >> +struct radeon_fence *fence = to_radeon_fence(f); >> +switch (fence->ring) { >> +case RADEON_RING_TYPE_GFX_INDEX: return "radeon.gfx"; >> +case CAYMAN_RING_TYPE_CP1_INDEX: return "radeon.cp1"; >> +case CAYMAN_RING_TYPE_CP2_INDEX: return "radeon.cp2"; >> +case R600_RING_TYPE_DMA_INDEX: return "radeon.dma"; >> +case CAYMAN_RING_TYPE_DMA1_INDEX: return "radeon.dma1"; >> +case R600_RING_TYPE_UVD_INDEX: return "radeon.uvd"; > Radeon supports vce rings on newer ascis. Probably want to add the case for > those here too. > > Alex > Indeed, how about this? --8<--- Signed-off-by: Maarten Lankhorst --- drivers/gpu/drm/radeon/radeon.h| 15 +-- drivers/gpu/drm/radeon/radeon_device.c | 60 - drivers/gpu/drm/radeon/radeon_fence.c | 225 +++-- 3 files changed, 250 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 29d9cc04c04e..03a5567f2c2f 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -64,6 +64,7 @@ #include #include #include +#include #include #include @@ -116,9 +117,6 @@ extern int radeon_deep_color; #define RADEONFB_CONN_LIMIT4 #define RADEON_BIOS_NUM_SCRATCH8 -/* fence seq are set to this number when signaled */ -#define RADEON_FENCE_SIGNALED_SEQ 0LL - /* internal ring indices */ /* r1xx+ has gfx CP ring */ #define RADEON_RING_TYPE_GFX_INDEX 0 @@ -350,12 +348,15 @@ struct radeon_fence_driver { }; struct radeon_fence { + struct fence base; + struct radeon_device*rdev; - struct kref kref; /* protected by radeon_fence.lock */ uint64_tseq; /* RB, DMA, etc. */ unsignedring; + + wait_queue_t fence_wake; }; int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring); @@ -2268,6 +2269,7 @@ struct radeon_device { struct radeon_mman mman; struct radeon_fence_driver fence_drv[RADEON_NUM_RINGS]; wait_queue_head_t fence_queue; + unsignedfence_context; struct mutexring_lock; struct radeon_ring ring[RADEON_NUM_RINGS]; boolib_pool_ready; @@ -2358,11 +2360,6 @@ u32 cik_mm_rdoorbell(struct radeon_device *rdev, u32 index); void cik_mm_wdoorbell(struct radeon_device *rdev, u32 index, u32 v); /* - * Cast helper - */ -#define to_radeon_fence(p) ((struct radeon_fence *)(p)) - -/* * Registers read & write functions. */ #define RREG8(reg) readb((rdev->rmmio) + (reg)) diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 03686fab842d..86699df7c8f3 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -1213,6 +1213,7 @@ int radeon_device_init(struct radeon_device *rdev, for (i = 0; i < RADEON_NUM_RINGS; i++) { rdev->ring[i].idx = i; } + rdev->fence_context = fence_context_alloc(RADEON_NUM_RINGS); DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X).\n", radeon_family_name[rdev->family], pdev->vendor, pdev->device, @@ -1607,6 +1608,54 @@ int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon) return 0; } +static uint32_t radeon_gpu_mask_sw_irq(struct radeon_device *rdev) +{ + uint32_t mask = 0; + int i; + + if (!rdev->ddev->irq_enabled) + return mask; + + /* +* increase refcount on sw interrupts for all rings to stop +* enabling interrupts in radeon_fence_enable_signaling during +* gpu reset. +*/ + + for (i = 0; i < RADEON_NUM_RINGS; ++i) { + if (!rdev->ring[i].ready) + continue; + + atomic_inc(>irq.ring_int[i]); + mask |= 1 << i; + } + return mask; +} + +static void radeon_gpu_unmask_sw_irq(struct radeon_device *rdev, uint32_t mask) +{ + unsigned long irqflags; + int i; + + if (!mask) + return; + + /* +* undo refcount increase, and reset irqs to correct value. +*/ + + for (i = 0; i < RADEON_NUM_RINGS; ++i) { + if (!(mask & (1 << i))) + continue; + + atomic_dec(>irq.ring_int[i]); + } + + spin_lock_irqsave(>irq.lock, irqflags); + radeon_irq_set(rdev); + spin_unlock_irqrestore(>irq.lock, irqflags); +} + /** * radeon_gpu_reset - reset the asic * @@ -1624,6 +1673,7 @@ int radeon_gpu_reset(struct radeon_device *rdev)