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

Commit 34a9775e authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: Fix stall on pagefault sequence"

parents 0f2870d5 ffbd9932
Loading
Loading
Loading
Loading
+20 −15
Original line number Diff line number Diff line
@@ -1660,17 +1660,15 @@ static inline bool adreno_try_soft_reset(struct kgsl_device *device, int fault)
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);

	/*
	 * Try soft reset for non mmu fault case only and if VBIF
	 * pipe clears cleanly.
	 * Skip soft reset and use hard reset for A304 GPU, As
	 * A304 is not able to do SMMU programming after soft reset.
	 * 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
	 */
	if (!(fault & ADRENO_IOMMU_PAGE_FAULT) &&
			!adreno_is_a304(adreno_dev) &&
			!adreno_vbif_clear_pending_transactions(device))
		return true;

	if ((fault & ADRENO_IOMMU_PAGE_FAULT) || adreno_is_a304(adreno_dev))
		return false;

	return true;
}

/**
@@ -1690,9 +1688,15 @@ int adreno_reset(struct kgsl_device *device, int fault)

	/* Try soft reset first */
	if (adreno_try_soft_reset(device, fault)) {
		/* Make sure VBIF is cleared before resetting */
		ret = adreno_vbif_clear_pending_transactions(device);

		if (ret == 0) {
			ret = adreno_soft_reset(device);
			if (ret)
			KGSL_DEV_ERR_ONCE(device, "Device soft reset failed\n");
				KGSL_DEV_ERR_ONCE(device,
					"Device soft reset failed\n");
		}
	}
	if (ret) {
		/* If soft reset failed/skipped, then pull the power */
@@ -2217,13 +2221,14 @@ bool adreno_isidle(struct kgsl_device *device)
/**
 * adreno_spin_idle() - Spin wait for the GPU to idle
 * @device: Pointer to the KGSL device
 * @timeout: milliseconds to wait before returning error
 *
 * Spin the CPU waiting for the RBBM status to return idle
 */
int adreno_spin_idle(struct kgsl_device *device)
int adreno_spin_idle(struct kgsl_device *device, unsigned int timeout)
{
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	unsigned long wait = jiffies + msecs_to_jiffies(ADRENO_IDLE_TIMEOUT);
	unsigned long wait = jiffies + msecs_to_jiffies(timeout);

	kgsl_cffdump_regpoll(device,
		adreno_getreg(adreno_dev, ADRENO_REG_RBBM_STATUS) << 2,
@@ -2277,7 +2282,7 @@ int adreno_idle(struct kgsl_device *device)
	if (ret)
		return ret;

	return adreno_spin_idle(device);
	return adreno_spin_idle(device, ADRENO_IDLE_TIMEOUT);
}

/**
+1 −1
Original line number Diff line number Diff line
@@ -802,7 +802,7 @@ long adreno_ioctl_helper(struct kgsl_device_private *dev_priv,
		unsigned int cmd, unsigned long arg,
		const struct kgsl_ioctl *cmds, int len);

int adreno_spin_idle(struct kgsl_device *device);
int adreno_spin_idle(struct kgsl_device *device, unsigned int timeout);
int adreno_idle(struct kgsl_device *device);
bool adreno_isidle(struct kgsl_device *device);

+11 −3
Original line number Diff line number Diff line
@@ -635,6 +635,8 @@ static int a3xx_rb_init(struct adreno_device *adreno_dev,
			 struct adreno_ringbuffer *rb)
{
	unsigned int *cmds;
	int ret;

	cmds = adreno_ringbuffer_allocspace(rb, 18);
	if (IS_ERR(cmds))
		return PTR_ERR(cmds);
@@ -664,9 +666,15 @@ static int a3xx_rb_init(struct adreno_device *adreno_dev,
	*cmds++ = 0x00000000;
	*cmds++ = 0x00000000;

	adreno_ringbuffer_submit(rb, NULL);
	ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000);
	if (ret) {
		struct kgsl_device *device = &adreno_dev->dev;

	return 0;
		dev_err(device->dev, "CP initialization failed to idle\n");
		kgsl_device_snapshot(device, NULL);
	}

	return ret;
}

/*
@@ -1726,7 +1734,7 @@ static int _ringbuffer_bootstrap_ucode(struct adreno_ringbuffer *rb,
	}

	/* idle device to validate bootstrap */
	ret = adreno_spin_idle(device);
	ret = adreno_spin_idle(device, 2000);

	if (ret) {
		KGSL_DRV_ERR(rb->device,
+11 −2
Original line number Diff line number Diff line
@@ -1576,6 +1576,8 @@ static int a4xx_rb_init(struct adreno_device *adreno_dev,
			 struct adreno_ringbuffer *rb)
{
	unsigned int *cmds;
	int ret;

	cmds = adreno_ringbuffer_allocspace(rb, 20);
	if (IS_ERR(cmds))
		return PTR_ERR(cmds);
@@ -1614,8 +1616,15 @@ static int a4xx_rb_init(struct adreno_device *adreno_dev,
	*cmds++ = cp_type3_packet(CP_PREEMPT_ENABLE, 1);
	*cmds++ = 1;

	adreno_ringbuffer_submit(rb, NULL);
	return 0;
	ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000);
	if (ret) {
		struct kgsl_device *device = &adreno_dev->dev;

		dev_err(device->dev, "CP initialization failed to idle\n");
		kgsl_device_snapshot(device, NULL);
	}

	return ret;
}

static ADRENO_CORESIGHT_ATTR(cfg_debbus_ctrlt, &a4xx_coresight_registers[0]);
+47 −15
Original line number Diff line number Diff line
@@ -1001,9 +1001,7 @@ static int _gpmu_send_init_cmds(struct adreno_device *adreno_dev)

	/* Copy to the RB the predefined fw sequence cmds */
	memcpy(cmds, adreno_dev->gpmu_cmds, size << 2);
	adreno_ringbuffer_submit(rb, NULL);

	return adreno_spin_idle(&adreno_dev->dev);
	return adreno_ringbuffer_submit_spin(rb, NULL, 2000);
}

/*
@@ -1994,11 +1992,31 @@ static int _preemption_init(
	return cmds - cmds_orig;
}

/* Print some key registers if a spin-for-idle times out */
static void spin_idle_debug(struct kgsl_device *device)
{
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	unsigned int rptr, wptr;
	unsigned int status, status3, intstatus;
	unsigned int hwfault;

	adreno_readreg(adreno_dev, ADRENO_REG_CP_RB_RPTR, &rptr);
	adreno_readreg(adreno_dev, ADRENO_REG_CP_RB_WPTR, &wptr);

	kgsl_regread(device, A5XX_RBBM_STATUS, &status);
	kgsl_regread(device, A5XX_RBBM_STATUS3, &status3);
	kgsl_regread(device, A5XX_RBBM_INT_0_STATUS, &intstatus);
	kgsl_regread(device, A5XX_CP_HW_FAULT, &hwfault);

	dev_err(device->dev,
		" rb=%X/%X rbbm_status=%8.8X/%8.8X int_0_status=%8.8X\n",
		rptr, wptr, status, status3, intstatus);
	dev_err(device->dev, " hwfault=%8.8X\n", hwfault);
}

static void a5xx_post_start(struct adreno_device *adreno_dev)
{
	unsigned int *cmds, *start;
	int status = 0;
	struct kgsl_device *device = &(adreno_dev->dev);
	struct adreno_ringbuffer *rb = adreno_dev->cur_rb;

	cmds = adreno_ringbuffer_allocspace(rb, 42);
@@ -2024,13 +2042,10 @@ static void a5xx_post_start(struct adreno_device *adreno_dev)
	if (cmds == start)
		return;

	adreno_ringbuffer_submit(rb, NULL);
	if (adreno_ringbuffer_submit_spin(rb, NULL, 2000)) {
		struct kgsl_device *device = &adreno_dev->dev;

	/* idle device to validate hw INIT */
	status = adreno_spin_idle(device);
	if (status) {
		KGSL_DRV_ERR(rb->device,
		"hw initialization failed to idle\n");
		KGSL_DRV_ERR(device, "hw initialization failed to idle\n");
		kgsl_device_snapshot(device, NULL);
	}
}
@@ -2075,6 +2090,7 @@ static int a5xx_rb_init(struct adreno_device *adreno_dev,
			 struct adreno_ringbuffer *rb)
{
	unsigned int *cmds;
	int ret;

	cmds = adreno_ringbuffer_allocspace(rb, 8);
	if (IS_ERR(cmds))
@@ -2104,15 +2120,23 @@ static int a5xx_rb_init(struct adreno_device *adreno_dev,
	*cmds++ = 0x00000000;
	*cmds++ = 0x00000000;

	adreno_ringbuffer_submit(rb, NULL);
	ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000);
	if (ret != 0) {
		struct kgsl_device *device = &adreno_dev->dev;

	return 0;
		dev_err(device->dev, "CP initialization failed to idle\n");
		spin_idle_debug(device);
		kgsl_device_snapshot(device, NULL);
	}

	return ret;
}

int a5xx_switch_to_unsecure_mode(struct adreno_device *adreno_dev,
				struct adreno_ringbuffer *rb)
{
	unsigned int *cmds;
	int ret;

	cmds = adreno_ringbuffer_allocspace(rb, 2);
	if (IS_ERR(cmds))
@@ -2122,8 +2146,16 @@ int a5xx_switch_to_unsecure_mode(struct adreno_device *adreno_dev,

	cmds += cp_secure_mode(adreno_dev, cmds, 0);

	adreno_ringbuffer_submit(rb, NULL);
	return 0;
	ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000);
	if (ret != 0) {
		struct kgsl_device *device = &adreno_dev->dev;

		dev_err(device->dev, "Switch to unsecure failed to idle\n");
		spin_idle_debug(device);
		kgsl_device_snapshot(device, NULL);
	}

	return ret;
}

static int _load_firmware(struct adreno_device *adreno_dev, const char *fwfile,
Loading