[PATCH v2 09/17] drm/radeon: use common fence implementation for fences

2014-07-10 Thread Alex Deucher
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

2014-07-09 Thread Maarten Lankhorst
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)