Merge "msm: kgsl: Clear boot OOB in case GPU start fails"
This commit is contained in:
commit
be6924f0ee
2 changed files with 33 additions and 13 deletions
|
@ -1823,7 +1823,7 @@ static int _adreno_start(struct adreno_device *adreno_dev)
|
|||
|
||||
status = kgsl_mmu_start(device);
|
||||
if (status)
|
||||
goto error_pwr_off;
|
||||
goto error_boot_oob_clear;
|
||||
|
||||
status = adreno_ocmem_malloc(adreno_dev);
|
||||
if (status) {
|
||||
|
@ -2036,6 +2036,10 @@ static int _adreno_start(struct adreno_device *adreno_dev)
|
|||
error_mmu_off:
|
||||
kgsl_mmu_stop(&device->mmu);
|
||||
|
||||
error_boot_oob_clear:
|
||||
if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_HFI_USE_REG))
|
||||
gmu_core_dev_oob_clear(device, oob_boot_slumber);
|
||||
|
||||
error_pwr_off:
|
||||
/* set the state back to original state */
|
||||
kgsl_pwrctrl_change_state(device, state);
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#define GMU_CONTEXT_KERNEL 1
|
||||
#define GMU_KERNEL_ENTRIES 16
|
||||
|
||||
#define GMU_CM3_CFG_NONMASKINTR_SHIFT 9
|
||||
|
||||
struct gmu_iommu_context {
|
||||
const char *name;
|
||||
struct device *dev;
|
||||
|
@ -881,6 +883,24 @@ static int gmu_rpmh_init(struct kgsl_device *device,
|
|||
return rpmh_arc_votes_init(device, gmu, &cx_arc, &mx_arc, GMU_ARC_VOTE);
|
||||
}
|
||||
|
||||
static void send_nmi_to_gmu(struct adreno_device *adreno_dev)
|
||||
{
|
||||
/* Mask so there's no interrupt caused by NMI */
|
||||
adreno_write_gmureg(adreno_dev,
|
||||
ADRENO_REG_GMU_GMU2HOST_INTR_MASK, 0xFFFFFFFF);
|
||||
|
||||
/* Make sure the interrupt is masked before causing it */
|
||||
wmb();
|
||||
adreno_write_gmureg(adreno_dev,
|
||||
ADRENO_REG_GMU_NMI_CONTROL_STATUS, 0);
|
||||
adreno_write_gmureg(adreno_dev,
|
||||
ADRENO_REG_GMU_CM3_CFG,
|
||||
(1 << GMU_CM3_CFG_NONMASKINTR_SHIFT));
|
||||
|
||||
/* Make sure the NMI is invoked before we proceed*/
|
||||
wmb();
|
||||
}
|
||||
|
||||
static irqreturn_t gmu_irq_handler(int irq, void *data)
|
||||
{
|
||||
struct kgsl_device *device = data;
|
||||
|
@ -902,6 +922,13 @@ static irqreturn_t gmu_irq_handler(int irq, void *data)
|
|||
ADRENO_REG_GMU_AO_HOST_INTERRUPT_MASK,
|
||||
(mask | GMU_INT_WDOG_BITE));
|
||||
|
||||
send_nmi_to_gmu(adreno_dev);
|
||||
/*
|
||||
* There is sufficient delay for the GMU to have finished
|
||||
* handling the NMI before snapshot is taken, as the fault
|
||||
* worker is scheduled below.
|
||||
*/
|
||||
|
||||
dev_err_ratelimited(&gmu->pdev->dev,
|
||||
"GMU watchdog expired interrupt received\n");
|
||||
adreno_set_gpu_fault(adreno_dev, ADRENO_GMU_FAULT);
|
||||
|
@ -1472,19 +1499,8 @@ static void gmu_snapshot(struct kgsl_device *device)
|
|||
struct gmu_dev_ops *gmu_dev_ops = GMU_DEVICE_OPS(device);
|
||||
struct gmu_device *gmu = KGSL_GMU_DEVICE(device);
|
||||
|
||||
/* Mask so there's no interrupt caused by NMI */
|
||||
adreno_write_gmureg(adreno_dev,
|
||||
ADRENO_REG_GMU_GMU2HOST_INTR_MASK, 0xFFFFFFFF);
|
||||
|
||||
/* Make sure the interrupt is masked before causing it */
|
||||
wmb();
|
||||
adreno_write_gmureg(adreno_dev,
|
||||
ADRENO_REG_GMU_NMI_CONTROL_STATUS, 0);
|
||||
adreno_write_gmureg(adreno_dev,
|
||||
ADRENO_REG_GMU_CM3_CFG, (1 << 9));
|
||||
|
||||
send_nmi_to_gmu(adreno_dev);
|
||||
/* Wait for the NMI to be handled */
|
||||
wmb();
|
||||
udelay(100);
|
||||
kgsl_device_snapshot(device, NULL, true);
|
||||
|
||||
|
|
Loading…
Reference in a new issue