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

This commit is contained in:
qctecmdr 2020-09-20 02:12:29 -07:00 • committed by Gerrit - the friendly Code Review server
commit bba4d8f645
4 changed files with 45 additions and 9 deletions

View file

@ -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);

View file

@ -1903,6 +1903,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);

View file

@ -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);
}

View file

@ -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 */