From: Russell King <rmk+kernel@xxxxxxxxxxxxxxxx> 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@xxxxxxxxxxxxxxxx> --- 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 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel