Because the device must be in a position to accept jobs between the time drm_dev_register() is called and autosuspend first kicks in, there's a very narrow window inbetween during which jobs targeting the tiler buffer object would time out, since the device's PM status is 'Active', but no MMU interrupts were enabled at device initialisation time.
Signed-off-by: Adrián Larumbe <[email protected]> Fixes: 73e467f60acd ("drm/panfrost: Consolidate reset handling") --- drivers/gpu/drm/panfrost/panfrost_job.c | 3 ++- drivers/gpu/drm/panfrost/panfrost_mmu.c | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c index 35ff5b0f0013..bda1494eb430 100644 --- a/drivers/gpu/drm/panfrost/panfrost_job.c +++ b/drivers/gpu/drm/panfrost/panfrost_job.c @@ -871,7 +871,6 @@ int panfrost_jm_init(struct panfrost_device *pfdev) js = devm_kzalloc(pfdev->base.dev, sizeof(*js), GFP_KERNEL); if (!js) return -ENOMEM; - pfdev->js = js; INIT_WORK(&pfdev->reset.work, panfrost_reset_work); spin_lock_init(&js->job_lock); @@ -906,6 +905,8 @@ int panfrost_jm_init(struct panfrost_device *pfdev) } } + pfdev->js = js; + panfrost_jm_reset_interrupts(pfdev); panfrost_jm_enable_interrupts(pfdev); diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c index 4a3162c3b659..aad0cd31516d 100644 --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c @@ -336,6 +336,12 @@ void panfrost_mmu_as_put(struct panfrost_device *pfdev, struct panfrost_mmu *mmu WARN_ON(atomic_read(&mmu->as_count) < 0); } +static void panfrost_mmu_enable_interrupts(struct panfrost_device *pfdev) +{ + mmu_write(pfdev, MMU_INT_CLEAR, ~0); + mmu_write(pfdev, MMU_INT_MASK, ~0); +} + void panfrost_mmu_reset(struct panfrost_device *pfdev) { struct panfrost_mmu *mmu, *mmu_tmp; @@ -355,8 +361,7 @@ void panfrost_mmu_reset(struct panfrost_device *pfdev) spin_unlock(&pfdev->as_lock); - mmu_write(pfdev, MMU_INT_CLEAR, ~0); - mmu_write(pfdev, MMU_INT_MASK, ~0); + panfrost_mmu_enable_interrupts(pfdev); } static size_t get_pgsize(u64 addr, size_t size, size_t *count) @@ -880,6 +885,9 @@ static irqreturn_t panfrost_mmu_irq_handler_thread(int irq, void *data) u32 status = mmu_read(pfdev, MMU_INT_RAWSTAT); int ret; + if (!pfdev->js) + return IRQ_NONE; + while (status) { u32 as = ffs(status | (status >> 16)) - 1; u32 mask = BIT(as) | BIT(as + 16); @@ -970,6 +978,8 @@ int panfrost_mmu_init(struct panfrost_device *pfdev) return err; } + panfrost_mmu_enable_interrupts(pfdev); + return 0; } -- 2.55.0
