[PATCH RFC 009/111] staging: etnaviv: fix etnaviv_hw_reset()
Lucas Stach
l.stach at pengutronix.de
Thu Apr 2 08:29:11 PDT 2015
From: Russell King <rmk+kernel at arm.linux.org.uk>
Ensure that we reset the GPU with the clocks on, and restore the clock
state after GPU reset has completed. Without this, register accesses
can fail:
Unhandled fault: external abort on non-linefetch (0x1828) at 0xfe640418
Internal error: : 1828 [#1] PREEMPT ARM
Modules linked in: etnaviv(C+) ...
CPU: 0 PID: 1617 Comm: modprobe Tainted: G C 3.16.0+ #1010
task: d6210140 ti: d4102000 task.ti: d4102000
PC is at etnaviv_writel+0x2c/0x38 [etnaviv]
LR is at etnaviv_gpu_init+0x304/0x5cc [etnaviv]
pc : [<bf104960>] lr : [<bf107228>] psr: 600f0013
sp : d4103ba8 ip : d4103bc0 fp : d4103bbc
r10: 00000000 r9 : 00000000 r8 : cd45b034
r7 : d43ee480 r6 : d5ab1c10 r5 : 00000000 r4 : fe640418
r3 : 00000000 r2 : 00000000 r1 : fe640418 r0 : 00000000
Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
Control: 10c5387d Table: 143d4019 DAC: 00000015
Process modprobe (pid: 1617, stack limit = 0xd4102250)
Backtrace:
[<bf104934>] (etnaviv_writel [etnaviv]) from [<bf107228>] (etnaviv_gpu_init+0x304/0x5cc [etnaviv])
[<bf106f24>] (etnaviv_gpu_init [etnaviv]) from [<bf10481c>] (etnaviv_load+0xbc/0x128 [etnaviv])
[<bf104760>] (etnaviv_load [etnaviv]) from [<c0270a8c>] (drm_dev_register+0xa8/0x108)
[<c02709e4>] (drm_dev_register) from [<c027238c>] (drm_platform_init+0x50/0xe8)
...
Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
---
drivers/staging/etnaviv/etnaviv_gpu.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/drivers/staging/etnaviv/etnaviv_gpu.c b/drivers/staging/etnaviv/etnaviv_gpu.c
index 40ee6ac2ccd7..56afba7625ed 100644
--- a/drivers/staging/etnaviv/etnaviv_gpu.c
+++ b/drivers/staging/etnaviv/etnaviv_gpu.c
@@ -260,7 +260,16 @@ static void etnaviv_hw_reset(struct etnaviv_gpu *gpu)
*/
while (true) {
- control = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL);
+ control = VIVS_HI_CLOCK_CONTROL_DISABLE_DEBUG_REGISTERS |
+ VIVS_HI_CLOCK_CONTROL_FSCALE_VAL(0x40);
+
+ /* enable clock */
+ gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, control |
+ VIVS_HI_CLOCK_CONTROL_FSCALE_CMD_LOAD);
+ gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, control);
+
+ /* Wait for stable clock. Vivante's code waited for 1ms */
+ usleep_range(1000, 10000);
/* isolate the GPU. */
control |= VIVS_HI_CLOCK_CONTROL_ISOLATE_GPU;
@@ -302,6 +311,15 @@ static void etnaviv_hw_reset(struct etnaviv_gpu *gpu)
break;
}
+
+ /* We rely on the GPU running, so program the clock */
+ control = VIVS_HI_CLOCK_CONTROL_DISABLE_DEBUG_REGISTERS |
+ VIVS_HI_CLOCK_CONTROL_FSCALE_VAL(0x40);
+
+ /* enable clock */
+ gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, control |
+ VIVS_HI_CLOCK_CONTROL_FSCALE_CMD_LOAD);
+ gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, control);
}
int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
--
2.1.4
More information about the dri-devel
mailing list