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

Commit c744ab5d authored by Jordan Crouse's avatar Jordan Crouse
Browse files

msm: kgsl: Clean up the reset and soft reset paths



a6xx added a new function hook and path for doing a GPU reset that fell
back to the default reset path for a610 but a610 purposely skipped
soft reset and the hard reset path is very similar to that used by
GMU/RGMU enabled devices except for one little bit.

Furthermore, if a610 skipped soft reset then there are no a6xx targets
that do soft reset so there is no reason to have an a6xx specific
soft reset path. And further to that, there isn't any reason to have
any a6xx specific functions (like oob) in the generic soft reset path.

Make the a6xx reset support all a6xx targets, remove unused infrastructure
from the rest of the generic code and cleanup the generic functions
to be a little bit easier to understand.

Change-Id: Ic0dedbadd3570fe148a464ff0dc647d91099ae09
Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
parent 108427ae
Loading
Loading
Loading
Loading
+36 −46
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include "adreno-gpulist.h"

static void adreno_input_work(struct work_struct *work);
static int adreno_soft_reset(struct kgsl_device *device);
static unsigned int counter_delta(struct kgsl_device *device,
	unsigned int reg, unsigned int *counter);

@@ -500,7 +501,7 @@ static struct input_handler adreno_input_handler = {
 * all the HW logic, restores GPU registers to default state and
 * flushes out pending VBIF transactions.
 */
static int _soft_reset(struct adreno_device *adreno_dev)
static void _soft_reset(struct adreno_device *adreno_dev)
{
	struct adreno_gpudev *gpudev  = ADRENO_GPU_DEVICE(adreno_dev);
	unsigned int reg;
@@ -517,8 +518,6 @@ static int _soft_reset(struct adreno_device *adreno_dev)

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

	return 0;
}

/**
@@ -2315,28 +2314,21 @@ static int adreno_stop(struct kgsl_device *device)
int adreno_reset(struct kgsl_device *device, int fault)
{
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
	int ret = -EINVAL;
	int i = 0;
	int i;

	if (gpudev->reset)
		return gpudev->reset(device, fault);

	/*
	 * Try soft reset first Do not do soft reset for a IOMMU fault (because
	 * the IOMMU hardware needs a reset too) or for the A304 because it
	 * can't do SMMU programming of any kind after a soft reset
	 * the IOMMU hardware needs a reset too)
	 */

	if (!(fault & ADRENO_IOMMU_PAGE_FAULT) && !adreno_is_a304(adreno_dev)
		&& !adreno_is_a612(adreno_dev) && !adreno_is_a610(adreno_dev)) {
		/* Make sure VBIF is cleared before resetting */
		ret = adreno_clear_pending_transactions(device);

		if (ret == 0) {
	if (!(fault & ADRENO_IOMMU_PAGE_FAULT))
		ret = adreno_soft_reset(device);
			if (ret)
				dev_err(device->dev,
					"Device soft reset failed: ret=%d\n",
					ret);
		}
	}

	if (ret) {
		/* If soft reset failed/skipped, then pull the power */
		kgsl_pwrctrl_change_state(device, KGSL_STATE_INIT);
@@ -2346,22 +2338,18 @@ int adreno_reset(struct kgsl_device *device, int fault)
		/* Try to reset the device */
		ret = adreno_start(device, 0);

		/* On some GPUS, keep trying until it works */
		if (ret && ADRENO_GPUREV(adreno_dev) < 600) {
			for (i = 0; i < NUM_TIMES_RESET_RETRY; i++) {
		for (i = 0; ret && i < NUM_TIMES_RESET_RETRY; i++) {
			msleep(20);
			ret = adreno_start(device, 0);
				if (!ret)
					break;
			}
		}
		}

		if (ret)
			return ret;

		if (i != 0)
			dev_warn(device->dev,
			      "Device hard reset tried %d tries\n", i);
	}

	/*
	 * If active_cnt is non-zero then the system was active before
@@ -2811,23 +2799,32 @@ bool adreno_hw_isidle(struct adreno_device *adreno_dev)
	return true;
}

/**
 * adreno_soft_reset() -  Do a soft reset of the GPU hardware
/*
 * adreno_soft_reset -  Do a soft reset of the GPU hardware
 * @device: KGSL device to soft reset
 *
 * "soft reset" the GPU hardware - this is a fast path GPU reset
 * The GPU hardware is reset but we never pull power so we can skip
 * a lot of the standard adreno_stop/adreno_start sequence
 */
int adreno_soft_reset(struct kgsl_device *device)
static int adreno_soft_reset(struct kgsl_device *device)
{
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
	int ret;

	ret = gmu_core_dev_oob_set(device, oob_gpu);
	if (ret)
	/*
	 * Don't allow a soft reset for a304 because the SMMU needs to be hard
	 * reset
	 */
	if (adreno_is_a304(adreno_dev))
		return -ENODEV;

	ret = adreno_clear_pending_transactions(device);
	if (ret) {
		dev_err(device->dev, "Timed out while clearing the VBIF\n");
		return ret;
	}

	kgsl_pwrctrl_change_state(device, KGSL_STATE_AWARE);
	adreno_set_active_ctxs_null(adreno_dev);
@@ -2841,15 +2838,7 @@ int adreno_soft_reset(struct kgsl_device *device)
	/* save physical performance counter values before GPU soft reset */
	adreno_perfcounter_save(adreno_dev);

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

	/* Clear the busy_data stats - we're starting over from scratch */
	adreno_dev->busy_data.gpu_busy = 0;
@@ -2889,7 +2878,8 @@ int adreno_soft_reset(struct kgsl_device *device)
	/* Restore physical performance counter values after soft reset */
	adreno_perfcounter_restore(adreno_dev);

	gmu_core_dev_oob_clear(device, oob_gpu);
	if (ret)
		dev_err(device->dev, "Device soft reset failed: %d\n", ret);

	return ret;
}
+0 −4
Original line number Diff line number Diff line
@@ -643,8 +643,6 @@ enum adreno_regs {
	ADRENO_REG_RBBM_INT_0_STATUS,
	ADRENO_REG_RBBM_PM_OVERRIDE2,
	ADRENO_REG_RBBM_SW_RESET_CMD,
	ADRENO_REG_RBBM_BLOCK_SW_RESET_CMD,
	ADRENO_REG_RBBM_BLOCK_SW_RESET_CMD2,
	ADRENO_REG_RBBM_CLOCK_CTL,
	ADRENO_REG_PA_SC_AA_CONFIG,
	ADRENO_REG_SQ_GPR_MANAGEMENT,
@@ -789,7 +787,6 @@ struct adreno_gpudev {
	const char *(*iommu_fault_block)(struct kgsl_device *device,
				unsigned int fsynr1);
	int (*reset)(struct kgsl_device *device, int fault);
	int (*soft_reset)(struct adreno_device *adreno_dev);
	bool (*sptprac_is_on)(struct adreno_device *adreno_dev);
	unsigned int (*ccu_invalidate)(struct adreno_device *adreno_dev,
				unsigned int *cmds);
@@ -871,7 +868,6 @@ extern int adreno_wake_nice;
extern unsigned int adreno_wake_timeout;

int adreno_start(struct kgsl_device *device, int priority);
int adreno_soft_reset(struct kgsl_device *device);
long adreno_ioctl(struct kgsl_device_private *dev_priv,
		unsigned int cmd, unsigned long arg);

+0 −4
Original line number Diff line number Diff line
@@ -2378,10 +2378,6 @@ static unsigned int a5xx_register_offsets[ADRENO_REG_REGISTER_MAX] = {
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_INT_0_STATUS, A5XX_RBBM_INT_0_STATUS),
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_CLOCK_CTL, A5XX_RBBM_CLOCK_CNTL),
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_SW_RESET_CMD, A5XX_RBBM_SW_RESET_CMD),
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_BLOCK_SW_RESET_CMD,
					  A5XX_RBBM_BLOCK_SW_RESET_CMD),
		ADRENO_REG_DEFINE(ADRENO_REG_RBBM_BLOCK_SW_RESET_CMD2,
					  A5XX_RBBM_BLOCK_SW_RESET_CMD2),
	ADRENO_REG_DEFINE(ADRENO_REG_UCHE_INVALIDATE0, A5XX_UCHE_INVALIDATE0),
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_RBBM_0_LO,
				A5XX_RBBM_PERFCTR_RBBM_0_LO),
+8 −36
Original line number Diff line number Diff line
@@ -1011,30 +1011,6 @@ static int a6xx_microcode_read(struct adreno_device *adreno_dev)
	return adreno_get_firmware(adreno_dev, a6xx_core->sqefw_name, sqe_fw);
}

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

	if (gmu_core_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);

	/* Clear GBIF client halt and CX arbiter halt */
	adreno_deassert_gbif_halt(adreno_dev);

	a6xx_sptprac_enable(adreno_dev);

	return 0;
}

static int64_t a6xx_read_throttling_counters(struct adreno_device *adreno_dev)
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
@@ -1098,12 +1074,14 @@ static int a6xx_reset(struct kgsl_device *device, int fault)
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	int ret;

	/* Use the regular reset sequence for No GMU */
	if (!gmu_core_isenabled(device))
		return adreno_reset(device, fault);

	/* Transition from ACTIVE to RESET state */
	/*
	 * GMU devices transition to KGSL_STATE_RESET, non GMU devices go
	 * directly to KGSL_STATE_INIT
	 */
	if (gmu_core_isenabled(device))
		kgsl_pwrctrl_change_state(device, KGSL_STATE_RESET);
	else
		kgsl_pwrctrl_change_state(device, KGSL_STATE_INIT);

	/* since device is officially off now clear start bit */
	clear_bit(ADRENO_DEVICE_STARTED, &adreno_dev->priv);
@@ -2407,11 +2385,6 @@ static unsigned int a6xx_register_offsets[ADRENO_REG_REGISTER_MAX] = {
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_INT_0_MASK, A6XX_RBBM_INT_0_MASK),
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_INT_0_STATUS, A6XX_RBBM_INT_0_STATUS),
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_CLOCK_CTL, A6XX_RBBM_CLOCK_CNTL),
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_SW_RESET_CMD, A6XX_RBBM_SW_RESET_CMD),
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_BLOCK_SW_RESET_CMD,
					  A6XX_RBBM_BLOCK_SW_RESET_CMD),
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_BLOCK_SW_RESET_CMD2,
					  A6XX_RBBM_BLOCK_SW_RESET_CMD2),
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_LOAD_VALUE_LO,
				A6XX_RBBM_PERFCTR_LOAD_VALUE_LO),
	ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_LOAD_VALUE_HI,
@@ -2615,7 +2588,6 @@ struct adreno_gpudev adreno_a6xx_gpudev = {
	.hw_isidle = a6xx_hw_isidle, /* Replaced by NULL if GMU is disabled */
	.iommu_fault_block = a6xx_iommu_fault_block,
	.reset = a6xx_reset,
	.soft_reset = a6xx_soft_reset,
	.preemption_pre_ibsubmit = a6xx_preemption_pre_ibsubmit,
	.preemption_post_ibsubmit = a6xx_preemption_post_ibsubmit,
	.preemption_init = a6xx_preemption_init,
+1 −4
Original line number Diff line number Diff line
@@ -2197,9 +2197,6 @@ static int dispatcher_do_fault(struct adreno_device *adreno_dev)
		kgsl_process_event_group(device, &hung_rb->events);
	}

	if (gpudev->reset)
		ret = gpudev->reset(device, fault);
	else
	ret = adreno_reset(device, fault);

	mutex_unlock(&device->mutex);