To make sure that we don't unintentionally perform any unclocked and/or unpowered R/W operation on GPU registers, before turning off clocks and regulators we must make sure that no GPU, JOB or MMU ISR execution is pending: doing that requires to add a mechanism to synchronize the interrupts on suspend. Add functions panfrost_{gpu,job,mmu}_suspend_irq() which will perform interrupts masking and ISR execution synchronization, and then call those in the panfrost_device_runtime_suspend() handler in the exact sequence of job (may require mmu!) -> mmu -> gpu. As a side note, JOB and MMU suspend_irq functions needed some special treatment: as their interrupt handlers will unmask interrupts, it was necessary to add an `is_suspended` bitmap which is used to address the possible corner case of unintentional IRQ unmasking because of ISR execution after a call to synchronize_irq(). At resume, clear each is_suspended bit in the reset path of JOB/MMU to allow unmasking the interrupts. Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> Reviewed-by: Steven Price <steven.price@arm.com> Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Link: https://patchwork.freedesktop.org/patch/msgid/20231204114215.54575-4-angelogioacchino.delregno@collabora.com
27 lines
962 B
C
27 lines
962 B
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/* Copyright 2019 Linaro, Ltd, Rob Herring <robh@kernel.org> */
|
|
|
|
#ifndef __PANFROST_MMU_H__
|
|
#define __PANFROST_MMU_H__
|
|
|
|
struct panfrost_gem_mapping;
|
|
struct panfrost_file_priv;
|
|
struct panfrost_mmu;
|
|
|
|
int panfrost_mmu_map(struct panfrost_gem_mapping *mapping);
|
|
void panfrost_mmu_unmap(struct panfrost_gem_mapping *mapping);
|
|
|
|
int panfrost_mmu_init(struct panfrost_device *pfdev);
|
|
void panfrost_mmu_fini(struct panfrost_device *pfdev);
|
|
void panfrost_mmu_reset(struct panfrost_device *pfdev);
|
|
void panfrost_mmu_suspend_irq(struct panfrost_device *pfdev);
|
|
|
|
u32 panfrost_mmu_as_get(struct panfrost_device *pfdev, struct panfrost_mmu *mmu);
|
|
void panfrost_mmu_as_put(struct panfrost_device *pfdev, struct panfrost_mmu *mmu);
|
|
|
|
struct panfrost_mmu *panfrost_mmu_ctx_get(struct panfrost_mmu *mmu);
|
|
void panfrost_mmu_ctx_put(struct panfrost_mmu *mmu);
|
|
struct panfrost_mmu *panfrost_mmu_ctx_create(struct panfrost_device *pfdev);
|
|
|
|
#endif
|