Execute shader on wakeup from power collapse

After wakeup from power-collapse, a shader execution is needed
to reset the GPU to a known and stable state on certain targets.
This change implements the required shader execution only
on initialization and on recovery from power-collapse on A3xx
GPU targets.

CRs-fixed: 526544

Change-Id: Ibd33578ecbb94df5ff276d1e460d94235a82dc43
Signed-off-by: Richard Ruigrok <rruigrok@codeaurora.org>
Signed-off-by: Ananta Kishore K <akollipa@codeaurora.org>
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index bc7a5c2..c4d12ec 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -584,6 +584,10 @@
 	if (flags & KGSL_CMD_FLAGS_EOF)
 		total_sizedwords += 2;
 
+	/* Add space for the power on shader fixup if we need it */
+	if (flags & KGSL_CMD_FLAGS_PWRON_FIXUP)
+		total_sizedwords += 5;
+
 	ringcmds = adreno_ringbuffer_allocspace(rb, context, total_sizedwords);
 	if (!ringcmds)
 		return -ENOSPC;
@@ -591,6 +595,18 @@
 	rcmd_gpu = rb->buffer_desc.gpuaddr
 		+ sizeof(uint)*(rb->wptr-total_sizedwords);
 
+	if (flags & KGSL_CMD_FLAGS_PWRON_FIXUP) {
+		GSL_RB_WRITE(ringcmds, rcmd_gpu, cp_nop_packet(1));
+		GSL_RB_WRITE(ringcmds, rcmd_gpu,
+				KGSL_PWRON_FIXUP_IDENTIFIER);
+		GSL_RB_WRITE(ringcmds, rcmd_gpu,
+			CP_HDR_INDIRECT_BUFFER_PFD);
+		GSL_RB_WRITE(ringcmds, rcmd_gpu,
+			adreno_dev->pwron_fixup.gpuaddr);
+		GSL_RB_WRITE(ringcmds, rcmd_gpu,
+			adreno_dev->pwron_fixup_dwords);
+	}
+
 	GSL_RB_WRITE(ringcmds, rcmd_gpu, cp_nop_packet(1));
 	GSL_RB_WRITE(ringcmds, rcmd_gpu, KGSL_CMD_IDENTIFIER);
 
@@ -1069,9 +1085,20 @@
 	} else
 		drawctxt->timestamp++;
 
+	/*
+	 * For some targets, we need to execute a dummy shader operation after a
+	 * power collapse
+	 */
+
+	if (test_and_clear_bit(ADRENO_DEVICE_PWRON, &adreno_dev->priv) &&
+	    test_bit(ADRENO_DEVICE_PWRON_FIXUP, &adreno_dev->priv))
+	{
+		flags |= KGSL_CMD_FLAGS_PWRON_FIXUP;
+	}
+
 	ret = adreno_ringbuffer_addcmds(&adreno_dev->ringbuffer,
 					drawctxt,
-					(flags & KGSL_CMD_FLAGS_EOF),
+					flags,
 					&link[0], (cmds - link));
 	if (ret)
 		goto done;