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

Commit 0a56af85 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: Improve GPU soft fault detection"

parents 55fd6ae9 329932ad
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -2862,6 +2862,7 @@ static const struct kgsl_functable adreno_functable = {
	.pwrlevel_change_settings = adreno_pwrlevel_change_settings,
	.regulator_disable_poll = adreno_regulator_disable_poll,
	.gpu_model = adreno_gpu_model,
	.stop_fault_timer = adreno_dispatcher_stop_fault_timer,
};

static struct platform_driver adreno_platform_driver = {
+31 −1
Original line number Diff line number Diff line
@@ -206,6 +206,10 @@ static inline bool _isidle(struct adreno_device *adreno_dev)
	if (!kgsl_state_is_awake(KGSL_DEVICE(adreno_dev)))
		goto ret;

	if (test_bit(ADRENO_DEVICE_HANG_INTR, &adreno_dev->priv)
			&& adreno_rb_empty(adreno_dev->cur_rb))
		goto ret;

	/* only check rbbm status to determine if GPU is idle */
	adreno_readreg(adreno_dev, ADRENO_REG_RBBM_STATUS, &reg_rbbm_status);

@@ -1751,6 +1755,18 @@ static int dispatcher_do_fault(struct adreno_device *adreno_dev)
	if (fault == 0)
		return 0;

	/*
	 * In the very unlikely case that the power is off, do nothing - the
	 * state will be reset on power up and everybody will be happy
	 */

	if (!kgsl_state_is_awake(device) && (fault & ADRENO_SOFT_FAULT)) {
		/* Clear the existing register values */
		memset(adreno_ft_regs_val, 0,
				adreno_ft_regs_num * sizeof(unsigned int));
		return 0;
	}

	/*
	 * On A5xx, read RBBM_STATUS3:SMMU_STALLED_ON_FAULT (BIT 24) to
	 * tell if this function was entered after a pagefault. If so, only
@@ -2202,7 +2218,7 @@ static void adreno_dispatcher_fault_timer(unsigned long data)
	if (!fault_detect_read_compare(adreno_dev)) {
		adreno_set_gpu_fault(adreno_dev, ADRENO_SOFT_FAULT);
		adreno_dispatcher_schedule(KGSL_DEVICE(adreno_dev));
	} else {
	} else if (dispatcher->inflight > 0) {
		mod_timer(&dispatcher->fault_timer,
			jiffies + msecs_to_jiffies(_fault_timer_interval));
	}
@@ -2246,6 +2262,20 @@ void adreno_dispatcher_stop(struct adreno_device *adreno_dev)
	del_timer_sync(&dispatcher->fault_timer);
}

/**
 * adreno_dispatcher_stop() - stop the dispatcher fault timer
 * @adreno_dev: pointer to the adreno device structure
 *
 * Stop the dispatcher fault timer
 */
void adreno_dispatcher_stop_fault_timer(struct kgsl_device *device)
{
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	struct adreno_dispatcher *dispatcher = &adreno_dev->dispatcher;

	del_timer_sync(&dispatcher->fault_timer);
}

/**
 * adreno_dispatcher_close() - close the dispatcher
 * @adreno_dev: pointer to the adreno device structure
+2 −1
Original line number Diff line number Diff line
/* Copyright (c) 2008-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2008-2017, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -108,6 +108,7 @@ void adreno_dispatcher_close(struct adreno_device *adreno_dev);
int adreno_dispatcher_idle(struct adreno_device *adreno_dev);
void adreno_dispatcher_irq_fault(struct adreno_device *adreno_dev);
void adreno_dispatcher_stop(struct adreno_device *adreno_dev);
void adreno_dispatcher_stop_fault_timer(struct kgsl_device *device);

int adreno_dispatcher_queue_cmd(struct adreno_device *adreno_dev,
		struct adreno_context *drawctxt, struct kgsl_cmdbatch *cmdbatch,
+1 −0
Original line number Diff line number Diff line
@@ -171,6 +171,7 @@ struct kgsl_functable {
	void (*regulator_disable_poll)(struct kgsl_device *device);
	void (*gpu_model)(struct kgsl_device *device, char *str,
		size_t bufsz);
	void (*stop_fault_timer)(struct kgsl_device *device);
};

struct kgsl_ioctl {
+2 −0
Original line number Diff line number Diff line
@@ -2545,6 +2545,8 @@ _nap(struct kgsl_device *device)
			return -EBUSY;
		}

		device->ftbl->stop_fault_timer(device);

		/*
		 * Read HW busy counters before going to NAP state.
		 * The data might be used by power scale governors