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

Commit 49d0e9fb authored by Shrenuj Bansal's avatar Shrenuj Bansal Committed by George Shen
Browse files

msm: kgsl: Add soft reset for A6xx



A6xx architecture defines new soft reset procedure.

CRs-Fixed: 2017390
Change-Id: I87bc4aade9b0afab5ed63b893d82741e368cab40
Signed-off-by: default avatarShrenuj Bansal <shrenujb@codeaurora.org>
Signed-off-by: default avatarGeorge Shen <sqiao@codeaurora.org>
parent d56766f7
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -114,6 +114,7 @@
#define A6XX_RBBM_INT_0_STATUS                   0x201
#define A6XX_RBBM_STATUS                         0x210
#define A6XX_RBBM_STATUS3                        0x213
#define A6XX_RBBM_VBIF_GX_RESET_STATUS           0x215
#define A6XX_RBBM_PERFCTR_CP_0_LO                0x400
#define A6XX_RBBM_PERFCTR_CP_0_HI                0x401
#define A6XX_RBBM_PERFCTR_CP_1_LO                0x402
+23 −2
Original line number Diff line number Diff line
@@ -526,7 +526,7 @@ static int adreno_soft_reset(struct kgsl_device *device);
 * all the HW logic, restores GPU registers to default state and
 * flushes out pending VBIF transactions.
 */
static void _soft_reset(struct adreno_device *adreno_dev)
static int _soft_reset(struct adreno_device *adreno_dev)
{
	struct adreno_gpudev *gpudev  = ADRENO_GPU_DEVICE(adreno_dev);
	unsigned int reg;
@@ -555,6 +555,8 @@ static void _soft_reset(struct adreno_device *adreno_dev)

	if (gpudev->regulator_enable)
		gpudev->regulator_enable(adreno_dev);

	return 0;
}


@@ -2347,6 +2349,14 @@ static int adreno_soft_reset(struct kgsl_device *device)
	struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
	int ret;

	if (gpudev->oob_set) {
		ret = gpudev->oob_set(adreno_dev, OOB_CPINIT_SET_MASK,
				OOB_CPINIT_CHECK_MASK,
				OOB_CPINIT_CLEAR_MASK);
		if (ret)
			return ret;
	}

	kgsl_pwrctrl_change_state(device, KGSL_STATE_AWARE);
	adreno_set_active_ctxs_null(adreno_dev);

@@ -2360,7 +2370,15 @@ static int adreno_soft_reset(struct kgsl_device *device)
	adreno_perfcounter_save(adreno_dev);

	/* Reset the GPU */
	_soft_reset(adreno_dev);
	if (gpudev->soft_reset)
		ret = gpudev->soft_reset(adreno_dev);
	else
		ret = _soft_reset(adreno_dev);
	if (ret) {
		if (gpudev->oob_clear)
			gpudev->oob_clear(adreno_dev, OOB_CPINIT_CLEAR_MASK);
		return ret;
	}

	/* Set the page table back to the default page table */
	adreno_ringbuffer_set_global(adreno_dev, 0);
@@ -2402,6 +2420,9 @@ static int adreno_soft_reset(struct kgsl_device *device)
	/* Restore physical performance counter values after soft reset */
	adreno_perfcounter_restore(adreno_dev);

	if (gpudev->oob_clear)
		gpudev->oob_clear(adreno_dev, OOB_CPINIT_CLEAR_MASK);

	return ret;
}

+1 −0
Original line number Diff line number Diff line
@@ -864,6 +864,7 @@ struct adreno_gpudev {
	int (*wait_for_gmu_idle)(struct adreno_device *);
	const char *(*iommu_fault_block)(struct adreno_device *adreno_dev,
				unsigned int fsynr1);
	int (*soft_reset)(struct adreno_device *);
};

/**
+38 −0
Original line number Diff line number Diff line
@@ -1581,6 +1581,43 @@ static int a6xx_microcode_read(struct adreno_device *adreno_dev)
			ADRENO_FW(adreno_dev, ADRENO_FW_SQE));
}

#define VBIF_RESET_ACK_TIMEOUT	100
#define VBIF_RESET_ACK_MASK	0x00f0

static int a6xx_soft_reset(struct adreno_device *adreno_dev)
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
	unsigned int reg;

	/*
	 * For the soft reset case with GMU enabled this part is done
	 * by the GMU firmware
	 */
	if (kgsl_gmu_isenabled(device))
		return 0;


	adreno_writereg(adreno_dev, ADRENO_REG_RBBM_SW_RESET_CMD, 1);
	/*
	 * Do a dummy read to get a brief read cycle delay for the
	 * reset to take effect
	 */
	adreno_readreg(adreno_dev, ADRENO_REG_RBBM_SW_RESET_CMD, &reg);
	adreno_writereg(adreno_dev, ADRENO_REG_RBBM_SW_RESET_CMD, 0);

	/* Check VBIF status after reset */
	if (timed_poll_check(device,
			A6XX_RBBM_VBIF_GX_RESET_STATUS,
			VBIF_RESET_ACK_MASK,
			VBIF_RESET_ACK_TIMEOUT,
			VBIF_RESET_ACK_MASK))
		return -ETIMEDOUT;

	a6xx_sptprac_enable(adreno_dev);

	return 0;
}

static void a6xx_cp_hw_err_callback(struct adreno_device *adreno_dev, int bit)
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
@@ -2333,4 +2370,5 @@ struct adreno_gpudev adreno_a6xx_gpudev = {
	.hw_isidle = a6xx_hw_isidle, /* Replaced by NULL if GMU is disabled */
	.wait_for_gmu_idle = a6xx_wait_for_gmu_idle,
	.iommu_fault_block = a6xx_iommu_fault_block,
	.soft_reset = a6xx_soft_reset,
};