[PATCH 1/3] drm/msm: Fix race of GPU init vs timestamp power management.

Jordan Crouse jcrouse at codeaurora.org
Thu Jan 28 18:47:03 UTC 2021


On Wed, Jan 27, 2021 at 03:39:44PM -0800, Eric Anholt wrote:
> We were using the same force-poweron bit in the two codepaths, so they
> could race to have one of them lose GPU power early.
> 
> Signed-off-by: Eric Anholt <eric at anholt.net>
> Cc: stable at vger.kernel.org # v5.9

You can add:
Fixes: 4b565ca5a2cb ("drm/msm: Add A6XX device support")

Because that was my ugly.

Reviewed-by: Jordan Crouse <jcrouse at codeaurora.org>

> ---
>  drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 25 ++++++++++++++++++++++---
>  drivers/gpu/drm/msm/adreno/a6xx_gmu.h |  8 ++++++++
>  drivers/gpu/drm/msm/adreno/a6xx_gpu.c |  4 ++--
>  3 files changed, 32 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> index 78836b4fb98e..378dc7f190c3 100644
> --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
> @@ -264,6 +264,16 @@ int _a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state, char
>  		}
>  		name = "GPU_SET";
>  		break;
> +	case GMU_OOB_PERFCOUNTER_SET:
> +		if (gmu->legacy) {
> +			request = GMU_OOB_PERFCOUNTER_REQUEST;
> +			ack = GMU_OOB_PERFCOUNTER_ACK;
> +		} else {
> +			request = GMU_OOB_PERFCOUNTER_REQUEST_NEW;
> +			ack = GMU_OOB_PERFCOUNTER_ACK_NEW;
> +		}
> +		name = "PERFCOUNTER";
> +		break;
>  	case GMU_OOB_BOOT_SLUMBER:
>  		request = GMU_OOB_BOOT_SLUMBER_REQUEST;
>  		ack = GMU_OOB_BOOT_SLUMBER_ACK;
> @@ -302,9 +312,14 @@ int _a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state, char
>  void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state)
>  {
>  	if (!gmu->legacy) {
> -		WARN_ON(state != GMU_OOB_GPU_SET);
> -		gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET,
> -			1 << GMU_OOB_GPU_SET_CLEAR_NEW);
> +		if (state == GMU_OOB_GPU_SET) {
> +			gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET,
> +				1 << GMU_OOB_GPU_SET_CLEAR_NEW);
> +		} else {
> +			WARN_ON(state != GMU_OOB_PERFCOUNTER_SET);
> +			gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET,
> +				1 << GMU_OOB_PERFCOUNTER_CLEAR_NEW);
> +		}
>  		return;
>  	}
>  
> @@ -313,6 +328,10 @@ void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state)
>  		gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET,
>  			1 << GMU_OOB_GPU_SET_CLEAR);
>  		break;
> +	case GMU_OOB_PERFCOUNTER_SET:
> +		gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET,
> +			1 << GMU_OOB_PERFCOUNTER_CLEAR);
> +		break;
>  	case GMU_OOB_BOOT_SLUMBER:
>  		gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET,
>  			1 << GMU_OOB_BOOT_SLUMBER_CLEAR);
> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
> index c6d2bced8e5d..9fa278de2106 100644
> --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.h
> @@ -156,6 +156,7 @@ enum a6xx_gmu_oob_state {
>  	GMU_OOB_BOOT_SLUMBER = 0,
>  	GMU_OOB_GPU_SET,
>  	GMU_OOB_DCVS_SET,
> +	GMU_OOB_PERFCOUNTER_SET,
>  };
>  
>  /* These are the interrupt / ack bits for each OOB request that are set
> @@ -190,6 +191,13 @@ enum a6xx_gmu_oob_state {
>  #define GMU_OOB_GPU_SET_ACK_NEW		31
>  #define GMU_OOB_GPU_SET_CLEAR_NEW	31
>  
> +#define GMU_OOB_PERFCOUNTER_REQUEST	17
> +#define GMU_OOB_PERFCOUNTER_ACK		25
> +#define GMU_OOB_PERFCOUNTER_CLEAR	25
> +
> +#define GMU_OOB_PERFCOUNTER_REQUEST_NEW	28
> +#define GMU_OOB_PERFCOUNTER_ACK_NEW	30
> +#define GMU_OOB_PERFCOUNTER_CLEAR_NEW	30
>  
>  void a6xx_hfi_init(struct a6xx_gmu *gmu);
>  int a6xx_hfi_start(struct a6xx_gmu *gmu, int boot_state);
> diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> index c8a9010c1a1d..7424a70b9d35 100644
> --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
> @@ -1177,12 +1177,12 @@ static int a6xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value)
>  	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
>  
>  	/* Force the GPU power on so we can read this register */
> -	a6xx_gmu_set_oob(&a6xx_gpu->gmu, GMU_OOB_GPU_SET);
> +	a6xx_gmu_set_oob(&a6xx_gpu->gmu, GMU_OOB_PERFCOUNTER_SET);
>  
>  	*value = gpu_read64(gpu, REG_A6XX_RBBM_PERFCTR_CP_0_LO,
>  		REG_A6XX_RBBM_PERFCTR_CP_0_HI);
>  
> -	a6xx_gmu_clear_oob(&a6xx_gpu->gmu, GMU_OOB_GPU_SET);
> +	a6xx_gmu_clear_oob(&a6xx_gpu->gmu, GMU_OOB_PERFCOUNTER_SET);
>  	return 0;
>  }
>  
> -- 
> 2.30.0
> 

-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project


More information about the dri-devel mailing list