diff options
Diffstat (limited to 'drivers/gpu/drm/v3d/v3d_irq.c')
| -rw-r--r-- | drivers/gpu/drm/v3d/v3d_irq.c | 93 | 
1 files changed, 74 insertions, 19 deletions
| diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c index e714d5318f30..afc76390a197 100644 --- a/drivers/gpu/drm/v3d/v3d_irq.c +++ b/drivers/gpu/drm/v3d/v3d_irq.c @@ -14,21 +14,23 @@   */  #include <linux/platform_device.h> +#include <linux/sched/clock.h>  #include "v3d_drv.h"  #include "v3d_regs.h"  #include "v3d_trace.h" -#define V3D_CORE_IRQS ((u32)(V3D_INT_OUTOMEM |	\ -			     V3D_INT_FLDONE |	\ -			     V3D_INT_FRDONE |	\ -			     V3D_INT_CSDDONE |	\ -			     V3D_INT_GMPV)) +#define V3D_CORE_IRQS(ver) ((u32)(V3D_INT_OUTOMEM |	\ +				  V3D_INT_FLDONE |	\ +				  V3D_INT_FRDONE |	\ +				  V3D_INT_CSDDONE(ver) |	\ +				  (ver < 71 ? V3D_INT_GMPV : 0))) -#define V3D_HUB_IRQS ((u32)(V3D_HUB_INT_MMU_WRV |	\ -			    V3D_HUB_INT_MMU_PTI |	\ -			    V3D_HUB_INT_MMU_CAP |	\ -			    V3D_HUB_INT_TFUC)) +#define V3D_HUB_IRQS(ver) ((u32)(V3D_HUB_INT_MMU_WRV |	\ +				 V3D_HUB_INT_MMU_PTI |	\ +				 V3D_HUB_INT_MMU_CAP |	\ +				 V3D_HUB_INT_TFUC |		\ +				 (ver >= 71 ? V3D_V7_HUB_INT_GMPV : 0)))  static irqreturn_t  v3d_hub_irq(int irq, void *arg); @@ -100,6 +102,18 @@ v3d_irq(int irq, void *arg)  	if (intsts & V3D_INT_FLDONE) {  		struct v3d_fence *fence =  			to_v3d_fence(v3d->bin_job->base.irq_fence); +		struct v3d_file_priv *file = v3d->bin_job->base.file->driver_priv; +		u64 runtime = local_clock() - file->start_ns[V3D_BIN]; + +		file->enabled_ns[V3D_BIN] += local_clock() - file->start_ns[V3D_BIN]; +		file->jobs_sent[V3D_BIN]++; +		v3d->queue[V3D_BIN].jobs_sent++; + +		file->start_ns[V3D_BIN] = 0; +		v3d->queue[V3D_BIN].start_ns = 0; + +		file->enabled_ns[V3D_BIN] += runtime; +		v3d->queue[V3D_BIN].enabled_ns += runtime;  		trace_v3d_bcl_irq(&v3d->drm, fence->seqno);  		dma_fence_signal(&fence->base); @@ -109,15 +123,39 @@ v3d_irq(int irq, void *arg)  	if (intsts & V3D_INT_FRDONE) {  		struct v3d_fence *fence =  			to_v3d_fence(v3d->render_job->base.irq_fence); +		struct v3d_file_priv *file = v3d->render_job->base.file->driver_priv; +		u64 runtime = local_clock() - file->start_ns[V3D_RENDER]; + +		file->enabled_ns[V3D_RENDER] += local_clock() - file->start_ns[V3D_RENDER]; +		file->jobs_sent[V3D_RENDER]++; +		v3d->queue[V3D_RENDER].jobs_sent++; + +		file->start_ns[V3D_RENDER] = 0; +		v3d->queue[V3D_RENDER].start_ns = 0; + +		file->enabled_ns[V3D_RENDER] += runtime; +		v3d->queue[V3D_RENDER].enabled_ns += runtime;  		trace_v3d_rcl_irq(&v3d->drm, fence->seqno);  		dma_fence_signal(&fence->base);  		status = IRQ_HANDLED;  	} -	if (intsts & V3D_INT_CSDDONE) { +	if (intsts & V3D_INT_CSDDONE(v3d->ver)) {  		struct v3d_fence *fence =  			to_v3d_fence(v3d->csd_job->base.irq_fence); +		struct v3d_file_priv *file = v3d->csd_job->base.file->driver_priv; +		u64 runtime = local_clock() - file->start_ns[V3D_CSD]; + +		file->enabled_ns[V3D_CSD] += local_clock() - file->start_ns[V3D_CSD]; +		file->jobs_sent[V3D_CSD]++; +		v3d->queue[V3D_CSD].jobs_sent++; + +		file->start_ns[V3D_CSD] = 0; +		v3d->queue[V3D_CSD].start_ns = 0; + +		file->enabled_ns[V3D_CSD] += runtime; +		v3d->queue[V3D_CSD].enabled_ns += runtime;  		trace_v3d_csd_irq(&v3d->drm, fence->seqno);  		dma_fence_signal(&fence->base); @@ -127,7 +165,7 @@ v3d_irq(int irq, void *arg)  	/* We shouldn't be triggering these if we have GMP in  	 * always-allowed mode.  	 */ -	if (intsts & V3D_INT_GMPV) +	if (v3d->ver < 71 && (intsts & V3D_INT_GMPV))  		dev_err(v3d->drm.dev, "GMP violation\n");  	/* V3D 4.2 wires the hub and core IRQs together, so if we & @@ -154,6 +192,18 @@ v3d_hub_irq(int irq, void *arg)  	if (intsts & V3D_HUB_INT_TFUC) {  		struct v3d_fence *fence =  			to_v3d_fence(v3d->tfu_job->base.irq_fence); +		struct v3d_file_priv *file = v3d->tfu_job->base.file->driver_priv; +		u64 runtime = local_clock() - file->start_ns[V3D_TFU]; + +		file->enabled_ns[V3D_TFU] += local_clock() - file->start_ns[V3D_TFU]; +		file->jobs_sent[V3D_TFU]++; +		v3d->queue[V3D_TFU].jobs_sent++; + +		file->start_ns[V3D_TFU] = 0; +		v3d->queue[V3D_TFU].start_ns = 0; + +		file->enabled_ns[V3D_TFU] += runtime; +		v3d->queue[V3D_TFU].enabled_ns += runtime;  		trace_v3d_tfu_irq(&v3d->drm, fence->seqno);  		dma_fence_signal(&fence->base); @@ -197,6 +247,11 @@ v3d_hub_irq(int irq, void *arg)  		status = IRQ_HANDLED;  	} +	if (v3d->ver >= 71 && (intsts & V3D_V7_HUB_INT_GMPV)) { +		dev_err(v3d->drm.dev, "GMP Violation\n"); +		status = IRQ_HANDLED; +	} +  	return status;  } @@ -211,8 +266,8 @@ v3d_irq_init(struct v3d_dev *v3d)  	 * for us.  	 */  	for (core = 0; core < v3d->cores; core++) -		V3D_CORE_WRITE(core, V3D_CTL_INT_CLR, V3D_CORE_IRQS); -	V3D_WRITE(V3D_HUB_INT_CLR, V3D_HUB_IRQS); +		V3D_CORE_WRITE(core, V3D_CTL_INT_CLR, V3D_CORE_IRQS(v3d->ver)); +	V3D_WRITE(V3D_HUB_INT_CLR, V3D_HUB_IRQS(v3d->ver));  	irq1 = platform_get_irq_optional(v3d_to_pdev(v3d), 1);  	if (irq1 == -EPROBE_DEFER) @@ -256,12 +311,12 @@ v3d_irq_enable(struct v3d_dev *v3d)  	/* Enable our set of interrupts, masking out any others. */  	for (core = 0; core < v3d->cores; core++) { -		V3D_CORE_WRITE(core, V3D_CTL_INT_MSK_SET, ~V3D_CORE_IRQS); -		V3D_CORE_WRITE(core, V3D_CTL_INT_MSK_CLR, V3D_CORE_IRQS); +		V3D_CORE_WRITE(core, V3D_CTL_INT_MSK_SET, ~V3D_CORE_IRQS(v3d->ver)); +		V3D_CORE_WRITE(core, V3D_CTL_INT_MSK_CLR, V3D_CORE_IRQS(v3d->ver));  	} -	V3D_WRITE(V3D_HUB_INT_MSK_SET, ~V3D_HUB_IRQS); -	V3D_WRITE(V3D_HUB_INT_MSK_CLR, V3D_HUB_IRQS); +	V3D_WRITE(V3D_HUB_INT_MSK_SET, ~V3D_HUB_IRQS(v3d->ver)); +	V3D_WRITE(V3D_HUB_INT_MSK_CLR, V3D_HUB_IRQS(v3d->ver));  }  void @@ -276,8 +331,8 @@ v3d_irq_disable(struct v3d_dev *v3d)  	/* Clear any pending interrupts we might have left. */  	for (core = 0; core < v3d->cores; core++) -		V3D_CORE_WRITE(core, V3D_CTL_INT_CLR, V3D_CORE_IRQS); -	V3D_WRITE(V3D_HUB_INT_CLR, V3D_HUB_IRQS); +		V3D_CORE_WRITE(core, V3D_CTL_INT_CLR, V3D_CORE_IRQS(v3d->ver)); +	V3D_WRITE(V3D_HUB_INT_CLR, V3D_HUB_IRQS(v3d->ver));  	cancel_work_sync(&v3d->overflow_mem_work);  } | 
