Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 73b6615d authored by Jordan Crouse's avatar Jordan Crouse
Browse files

msm: kgsl: Force the ME off before reading the microcode



On A3XX reading the microcode while the CP is running is dangerous
beyond words.  By setting the offset address for the read, we are
essentially changing the instruction pointer for the ME while it
is running causing opcode errors, gpu faults and/or system errors.

We do not want to stop the CP at the beginning of the snapshot
process beacuse doing so changes the RBBM status and the state of
the CP registers which may damage the debug effort.  But by the
time we get to the microcode read we no longer care about the state
of the registers so we can freely halt the ME just before starting
the read.

CRs-fixed: 585449
Change-Id: Ic0dedbad85d7ec26915f054dd597e226e8101a29
Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
parent 63a67de8
Loading
Loading
Loading
Loading
+17 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -528,6 +528,22 @@ void *a3xx_snapshot(struct adreno_device *adreno_dev, void *snapshot,
	/* Reading these will hang the GPU if it isn't already hung */

	if (hang) {
		unsigned int reg;

		/*
		 * Reading the microcode while the CP will is running will
		 * basically basically move the CP instruction pointer to
		 * whatever address we read. Big badaboom ensues. Stop the CP
		 * (if it isn't already stopped) to ensure that we are safe.
		 * We do this here and not earlier to avoid corrupting the RBBM
		 * status and CP registers - by the time we get here we don't
		 * care about the contents of the CP anymore.
		 */

		adreno_readreg(adreno_dev, ADRENO_REG_CP_ME_CNTL, &reg);
		reg |= (1 << 27) | (1 << 28);
		adreno_writereg(adreno_dev, ADRENO_REG_CP_ME_CNTL, reg);

		snapshot = kgsl_snapshot_add_section(device,
			KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain,
			a3xx_snapshot_cp_pfp_ram, NULL);