lkml.org 
[lkml]   [2023]   [May]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH v7 07/18] drm/msm/a6xx: Add a helper for software-resetting the GPU
    Introduce a6xx_gpu_sw_reset() in preparation for adding GMU wrapper
    GPUs and reuse it in a6xx_gmu_force_off().

    This helper, contrary to the original usage in GMU code paths, adds
    a write memory barrier which together with the necessary delay should
    ensure that the reset is never deasserted too quickly due to e.g. OoO
    execution going crazy.

    Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
    ---
    drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 3 +--
    drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 11 +++++++++++
    drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 1 +
    3 files changed, 13 insertions(+), 2 deletions(-)

    diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
    index b86be123ecd0..5ba8cba69383 100644
    --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
    +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
    @@ -899,8 +899,7 @@ static void a6xx_gmu_force_off(struct a6xx_gmu *gmu)
    a6xx_bus_clear_pending_transactions(adreno_gpu, true);

    /* Reset GPU core blocks */
    - gpu_write(gpu, REG_A6XX_RBBM_SW_RESET_CMD, 1);
    - udelay(100);
    + a6xx_gpu_sw_reset(gpu, true);
    }

    static void a6xx_gmu_set_initial_freq(struct msm_gpu *gpu, struct a6xx_gmu *gmu)
    diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
    index e3ac3f045665..083ccb5bcb4e 100644
    --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
    +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
    @@ -1634,6 +1634,17 @@ void a6xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu, bool gx_
    gpu_write(gpu, REG_A6XX_GBIF_HALT, 0x0);
    }

    +void a6xx_gpu_sw_reset(struct msm_gpu *gpu, bool assert)
    +{
    + gpu_write(gpu, REG_A6XX_RBBM_SW_RESET_CMD, assert);
    + /* Add a barrier to avoid bad surprises */
    + mb();
    +
    + /* The reset line needs to be asserted for at least 100 us */
    + if (assert)
    + udelay(100);
    +}
    +
    static int a6xx_pm_resume(struct msm_gpu *gpu)
    {
    struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
    diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
    index 9580def06d45..aa70390ee1c6 100644
    --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
    +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
    @@ -89,5 +89,6 @@ struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu);
    int a6xx_gpu_state_put(struct msm_gpu_state *state);

    void a6xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu, bool gx_off);
    +void a6xx_gpu_sw_reset(struct msm_gpu *gpu, bool assert);

    #endif /* __A6XX_GPU_H__ */
    --
    2.40.1

    \
     
     \ /
      Last update: 2023-05-20 14:23    [W:3.572 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site