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

Commit bc3f9153 authored by Harshdeep Dhatt's avatar Harshdeep Dhatt
Browse files

msm: kgsl: Skip DTCM and NMI if SMMU is stalled



Accessing DTCM when SMMU is stalled can lead to NoC timeouts.
Also, skip sending NMI to GMU because GMU will not be able
to save cm3 state to DDR if SMMU is stalled.

Change-Id: I56a5399ca4847c6463862141f362e01fb86d3669
Signed-off-by: default avatarHarshdeep Dhatt <hdhatt@codeaurora.org>
parent e00c3830
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -260,6 +260,21 @@ static inline int timed_poll_check(struct kgsl_device *device,
	return 0;
}

/**
 * a6xx_is_smmu_stalled() - Check whether smmu is stalled or not
 * @device: Pointer to KGSL device
 *
 * Return - True if smmu is stalled or false otherwise
 */
static inline bool a6xx_is_smmu_stalled(struct kgsl_device *device)
{
	u32 val;

	kgsl_regread(device, A6XX_RBBM_STATUS3, &val);

	return val & BIT(24);
}

/* Preemption functions */
void a6xx_preemption_trigger(struct adreno_device *adreno_dev);
void a6xx_preemption_schedule(struct adreno_device *adreno_dev);
+16 −0
Original line number Diff line number Diff line
@@ -1919,6 +1919,22 @@ static void a6xx_gmu_send_nmi(struct adreno_device *adreno_dev)
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	u32 val;

	if (!a6xx_gmu_gx_is_on(device))
		goto done;

	/*
	 * Do not send NMI if the SMMU is stalled because GMU will not be able
	 * to save cm3 state to DDR.
	 */
	if (a6xx_is_smmu_stalled(device)) {
		struct a6xx_gmu_device *gmu = to_a6xx_gmu(adreno_dev);

		dev_err(&gmu->pdev->dev,
			"Skipping NMI because SMMU is stalled\n");
		return;
	}

done:
	/* Mask so there's no interrupt caused by NMI */
	gmu_core_regwrite(device, A6XX_GMU_GMU2HOST_INTR_MASK, 0xFFFFFFFF);

+13 −6
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@

#include "a6xx_reg.h"
#include "adreno.h"
#include "adreno_a6xx.h"
#include "adreno_a6xx_gmu.h"
#include "adreno_snapshot.h"
#include "kgsl_device.h"
@@ -379,14 +380,10 @@ void a6xx_gmu_device_snapshot(struct kgsl_device *device,
{
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	struct a6xx_gmu_device *gmu = to_a6xx_gmu(adreno_dev);
	unsigned int val;

	kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_GMU_MEMORY,
		snapshot, a6xx_gmu_snapshot_itcm, gmu);

	kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_GMU_MEMORY,
		snapshot, a6xx_gmu_snapshot_dtcm, gmu);

	a6xx_gmu_snapshot_versions(device, gmu, snapshot);

	a6xx_gmu_snapshot_memories(device, gmu, snapshot);
@@ -409,15 +406,25 @@ void a6xx_gmu_device_snapshot(struct kgsl_device *device,
	snapshot_rscc_registers(adreno_dev, snapshot);

	if (!a6xx_gmu_gx_is_on(device))
		return;
		goto dtcm;

	/* Set fence to ALLOW mode so registers can be read */
	kgsl_regwrite(device, A6XX_GMU_AO_AHB_FENCE_CTRL, 0);
	/* Make sure the previous write posted before reading */
	wmb();
	kgsl_regread(device, A6XX_GMU_AO_AHB_FENCE_CTRL, &val);

	adreno_snapshot_registers(device, snapshot,
			a6xx_gmu_gx_registers,
			ARRAY_SIZE(a6xx_gmu_gx_registers) / 2);

	/* A stalled SMMU can lead to NoC timeouts when host accesses DTCM */
	if (a6xx_is_smmu_stalled(device)) {
		dev_err(&gmu->pdev->dev,
			"Not dumping dtcm because SMMU is stalled\n");
		return;
	}

dtcm:
	kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_GMU_MEMORY,
		snapshot, a6xx_gmu_snapshot_dtcm, gmu);
}
+1 −3
Original line number Diff line number Diff line
@@ -1566,7 +1566,6 @@ static void _a6xx_do_crashdump(struct kgsl_device *device)
{
	unsigned long wait_time;
	unsigned int reg = 0;
	unsigned int val;

	crash_dump_valid = false;

@@ -1578,8 +1577,7 @@ static void _a6xx_do_crashdump(struct kgsl_device *device)
		return;

	/* IF the SMMU is stalled we cannot do a crash dump */
	kgsl_regread(device, A6XX_RBBM_STATUS3, &val);
	if (val & BIT(24))
	if (a6xx_is_smmu_stalled(device))
		return;

	/* Turn on APRIV for legacy targets so we can access the buffers */