Am Donnerstag, den 30.04.2020, 12:46 +0000 schrieb Schrempf Frieder:
From: Frieder Schrempf frieder.schrempf@kontron.de
On some i.MX8MM devices the boot hangs when enabling the GPU clocks. Changing the order of clock initalization to
core -> shader -> bus -> reg
fixes the issue. This is the same order used in the imx platform code of the downstream GPU driver in the NXP kernel [1]. For the sake of consistency we also adjust the order of disabling the clocks to the reverse.
[1] https://source.codeaurora.org/external/imx/linux-imx/tree/drivers/mxc/gpu-vi...
I don't see why the order of the clocks is important. Is this really a GPU issue? As in: does a GPU access hang when enabling the clocks in the wrong order? Or is this a clock driver issue with a clock access hanging due to an upstream clock still being disabled?
Regards, Lucas
Signed-off-by: Frieder Schrempf frieder.schrempf@kontron.de
drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 42 +++++++++++++-------------- 1 file changed, 21 insertions(+), 21 deletions(-)
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index 7b138d4dd068..424b2e5951f0 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -1487,55 +1487,55 @@ static int etnaviv_gpu_clk_enable(struct etnaviv_gpu *gpu) { int ret;
- if (gpu->clk_reg) {
ret = clk_prepare_enable(gpu->clk_reg);
- if (gpu->clk_core) {
if (ret) return ret; }ret = clk_prepare_enable(gpu->clk_core);
- if (gpu->clk_bus) {
ret = clk_prepare_enable(gpu->clk_bus);
- if (gpu->clk_shader) {
if (ret)ret = clk_prepare_enable(gpu->clk_shader);
goto disable_clk_reg;
}goto disable_clk_core;
- if (gpu->clk_core) {
ret = clk_prepare_enable(gpu->clk_core);
- if (gpu->clk_bus) {
if (ret)ret = clk_prepare_enable(gpu->clk_bus);
goto disable_clk_bus;
}goto disable_clk_shader;
- if (gpu->clk_shader) {
ret = clk_prepare_enable(gpu->clk_shader);
- if (gpu->clk_reg) {
if (ret)ret = clk_prepare_enable(gpu->clk_reg);
goto disable_clk_core;
goto disable_clk_bus;
}
return 0;
-disable_clk_core:
- if (gpu->clk_core)
clk_disable_unprepare(gpu->clk_core);
disable_clk_bus: if (gpu->clk_bus) clk_disable_unprepare(gpu->clk_bus); -disable_clk_reg:
- if (gpu->clk_reg)
clk_disable_unprepare(gpu->clk_reg);
+disable_clk_shader:
- if (gpu->clk_shader)
clk_disable_unprepare(gpu->clk_shader);
+disable_clk_core:
if (gpu->clk_core)
clk_disable_unprepare(gpu->clk_core);
return ret;
}
static int etnaviv_gpu_clk_disable(struct etnaviv_gpu *gpu) {
- if (gpu->clk_reg)
clk_disable_unprepare(gpu->clk_reg);
- if (gpu->clk_bus)
if (gpu->clk_shader) clk_disable_unprepare(gpu->clk_shader); if (gpu->clk_core) clk_disable_unprepare(gpu->clk_core);clk_disable_unprepare(gpu->clk_bus);
if (gpu->clk_bus)
clk_disable_unprepare(gpu->clk_bus);
if (gpu->clk_reg)
clk_disable_unprepare(gpu->clk_reg);
return 0;
}