From c182a2ae13886463f7ae36e034449477306d182b Mon Sep 17 00:00:00 2001 From: Randolph Sapp Date: Mon, 13 Oct 2025 12:01:23 -0500 Subject: [PATCH] drm/etnaviv: force flush on power register ops Add gpu_write_power_sync to verify that power register modifications have reached the endpoint device in sequence specific sections that do not validate device state. These sequence specific areas have been detected experimentally with an am57xx-evm through numerous boot and module load+unload cycles. Signed-off-by: Randolph Sapp Reviewed-by: Lucas Stach Signed-off-by: Lucas Stach Link: https://patch.msgid.link/20251013170122.1145387-2-rs@ti.com --- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 10 +++++----- drivers/gpu/drm/etnaviv/etnaviv_gpu.h | 6 ++++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index 4dbc8a7ea6af..5c23182f4d33 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -545,13 +545,13 @@ static int etnaviv_hw_reset(struct etnaviv_gpu *gpu) u32 pulse_eater = 0x01590880; /* disable clock gating */ - gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, 0x0); + gpu_write_power_sync(gpu, VIVS_PM_POWER_CONTROLS, 0x0); /* disable pulse eater */ pulse_eater |= BIT(17); gpu_write_power(gpu, VIVS_PM_PULSE_EATER, pulse_eater); pulse_eater |= BIT(0); - gpu_write_power(gpu, VIVS_PM_PULSE_EATER, pulse_eater); + gpu_write_power_sync(gpu, VIVS_PM_PULSE_EATER, pulse_eater); /* enable clock */ control = VIVS_HI_CLOCK_CONTROL_FSCALE_VAL(fscale); @@ -662,7 +662,7 @@ static void etnaviv_gpu_enable_mlcg(struct etnaviv_gpu *gpu) gpu->identity.revision == 0x4302) ppc |= VIVS_PM_POWER_CONTROLS_DISABLE_STALL_MODULE_CLOCK_GATING; - gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, ppc); + gpu_write_power_sync(gpu, VIVS_PM_POWER_CONTROLS, ppc); pmc = gpu_read_power(gpu, VIVS_PM_MODULE_CONTROLS); @@ -706,7 +706,7 @@ static void etnaviv_gpu_enable_mlcg(struct etnaviv_gpu *gpu) pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_RA_HZ; pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_RA_EZ; - gpu_write_power(gpu, VIVS_PM_MODULE_CONTROLS, pmc); + gpu_write_power_sync(gpu, VIVS_PM_MODULE_CONTROLS, pmc); } void etnaviv_gpu_start_fe(struct etnaviv_gpu *gpu, u32 address, u16 prefetch) @@ -772,7 +772,7 @@ static void etnaviv_gpu_setup_pulse_eater(struct etnaviv_gpu *gpu) pulse_eater |= BIT(18); } - gpu_write_power(gpu, VIVS_PM_PULSE_EATER, pulse_eater); + gpu_write_power_sync(gpu, VIVS_PM_PULSE_EATER, pulse_eater); } static void etnaviv_gpu_hw_init(struct etnaviv_gpu *gpu) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h index 5cb46c84e03a..e89d591d7404 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h @@ -204,6 +204,12 @@ static inline u32 gpu_read_power(struct etnaviv_gpu *gpu, u32 reg) return readl(gpu->mmio + gpu_fix_power_address(gpu, reg)); } +static inline void gpu_write_power_sync(struct etnaviv_gpu *gpu, u32 reg, u32 data) +{ + gpu_write_power(gpu, reg, data); + gpu_read_power(gpu, reg); +} + int etnaviv_gpu_get_param(struct etnaviv_gpu *gpu, u32 param, u64 *value); int etnaviv_gpu_init(struct etnaviv_gpu *gpu);