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

Commit 91f426d8 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: State based power code interaction"

parents 1ce96927 579c53a1
Loading
Loading
Loading
Loading
+23 −58
Original line number Diff line number Diff line
@@ -395,7 +395,7 @@ void adreno_hang_int_callback(struct adreno_device *adreno_dev, int bit)
	struct kgsl_device *device = &adreno_dev->dev;

	KGSL_DRV_CRIT(device, "MISC: GPU hang detected\n");
	kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
	adreno_irqctrl(adreno_dev, 0);

	/* Trigger a fault in the dispatcher - this will effect a restart */
	adreno_dispatcher_irq_fault(device);
@@ -974,8 +974,8 @@ static int adreno_init(struct kgsl_device *device)
	if (test_bit(ADRENO_DEVICE_INITIALIZED, &adreno_dev->priv))
		return 0;

	/* Power up the device */
	ret = kgsl_pwrctrl_enable(device);
	/* Put the GPU in a responsive state */
	ret = kgsl_pwrctrl_change_state(device, KGSL_STATE_AWARE);
	if (ret)
		return ret;

@@ -985,7 +985,6 @@ static int adreno_init(struct kgsl_device *device)
	adreno_ringbuffer_read_pm4_ucode(device);
	adreno_ringbuffer_read_pfp_ucode(device);

	kgsl_pwrctrl_change_state(device, KGSL_STATE_INIT);
	/*
	 * Check if firmware supports the sync lock PM4 packets needed
	 * for IOMMUv1
@@ -1016,10 +1015,10 @@ static int adreno_init(struct kgsl_device *device)
	ret = adreno_perfcounter_init(adreno_dev);

	/* Power down the device */
	kgsl_pwrctrl_disable(device);
	kgsl_pwrctrl_change_state(device, KGSL_STATE_INIT);

	if (ret)
		goto done;
		return ret;

	/*
	 * Enable the power on shader corruption fix
@@ -1075,7 +1074,6 @@ static int adreno_init(struct kgsl_device *device)
				&adreno_dev->priv);
	}

done:
	return ret;
}

@@ -1091,7 +1089,6 @@ static int _adreno_start(struct adreno_device *adreno_dev)
	struct kgsl_device *device = &adreno_dev->dev;
	struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
	int status = -EINVAL;
	unsigned int state = device->state;
	unsigned int regulator_left_on = 0;
	unsigned int pmqos_wakeup_vote = device->pwrctrl.pm_qos_wakeup_latency;
	unsigned int pmqos_active_vote = device->pwrctrl.pm_qos_active_latency;
@@ -1104,8 +1101,6 @@ static int _adreno_start(struct adreno_device *adreno_dev)

	kgsl_cffdump_open(device);

	kgsl_pwrctrl_change_state(device, KGSL_STATE_INIT);

	regulator_left_on = (regulator_is_enabled(device->pwrctrl.gpu_reg) ||
				(device->pwrctrl.gpu_cx &&
				regulator_is_enabled(device->pwrctrl.gpu_cx)));
@@ -1113,17 +1108,17 @@ static int _adreno_start(struct adreno_device *adreno_dev)
	/* Clear any GPU faults that might have been left over */
	adreno_clear_gpu_fault(adreno_dev);

	/* Power up the device */
	status = kgsl_pwrctrl_enable(device);
	/* Put the GPU in a responsive state */
	status = kgsl_pwrctrl_change_state(device, KGSL_STATE_AWARE);
	if (status)
		goto error_rail_off;
		goto error_pwr_off;

	/* Set the bit to indicate that we've just powered on */
	set_bit(ADRENO_DEVICE_PWRON, &adreno_dev->priv);

	status = kgsl_mmu_start(device);
	if (status)
		goto error_clk_off;
		goto error_pwr_off;

	status = adreno_ocmem_malloc(adreno_dev);
	if (status) {
@@ -1168,18 +1163,17 @@ static int _adreno_start(struct adreno_device *adreno_dev)
	/* Re-initialize the coresight registers if applicable */
	adreno_coresight_start(adreno_dev);

	kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON);
	adreno_irqctrl(adreno_dev, 1);

	status = adreno_perfcounter_start(adreno_dev);

	if (status)
		goto error_irq_off;
		goto error_mmu_off;

	status = adreno_ringbuffer_cold_start(adreno_dev);

	if (status)
		goto error_irq_off;
		goto error_mmu_off;

	/* Enable h/w power collapse feature */
	if (gpudev->enable_pc)
@@ -1202,17 +1196,11 @@ static int _adreno_start(struct adreno_device *adreno_dev)

	return 0;

error_irq_off:
	kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);

error_mmu_off:
	kgsl_mmu_stop(&device->mmu);

error_clk_off:
	kgsl_pwrctrl_disable(device);
error_rail_off:
	/* set the state back to original state */
	kgsl_pwrctrl_change_state(device, state);
error_pwr_off:
	kgsl_pwrctrl_change_state(device, KGSL_STATE_INIT);

	if (pmqos_active_vote != pmqos_wakeup_vote)
		pm_qos_update_request(&device->pwrctrl.pm_qos_req_dma,
@@ -1283,8 +1271,6 @@ static int adreno_stop(struct kgsl_device *device)
	if (!test_bit(ADRENO_DEVICE_STARTED, &adreno_dev->priv))
		return 0;

	kgsl_pwrctrl_enable(device);

	adreno_set_active_ctx_null(adreno_dev);

	adreno_dispatcher_stop(adreno_dev);
@@ -1292,8 +1278,6 @@ static int adreno_stop(struct kgsl_device *device)
	adreno_ringbuffer_stop(adreno_dev);

	adreno_irqctrl(adreno_dev, 0);
	kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
	del_timer_sync(&device->idle_timer);

	adreno_ocmem_free(adreno_dev);

@@ -1304,9 +1288,6 @@ static int adreno_stop(struct kgsl_device *device)
	adreno_perfcounter_save(adreno_dev);

	kgsl_mmu_stop(&device->mmu);
	/* Power down the device */
	kgsl_pwrctrl_disable(device);

	kgsl_cffdump_close(device);

	clear_bit(ADRENO_DEVICE_STARTED, &adreno_dev->priv);
@@ -1344,7 +1325,7 @@ int adreno_reset(struct kgsl_device *device)
	}
	if (ret) {
		/* If soft reset failed/skipped, then pull the power */
		adreno_stop(device);
		kgsl_pwrctrl_change_state(device, KGSL_STATE_INIT);

		/* Keep trying to start the device until it works */
		for (i = 0; i < NUM_TIMES_RESET_RETRY; i++) {
@@ -1368,6 +1349,8 @@ int adreno_reset(struct kgsl_device *device)

	if (atomic_read(&device->active_cnt))
		kgsl_pwrctrl_change_state(device, KGSL_STATE_ACTIVE);
	else
		kgsl_pwrctrl_change_state(device, KGSL_STATE_NAP);

	/* Set the page table back to the default page table */
	kgsl_mmu_set_pt(&device->mmu, device->mmu.defaultpagetable);
@@ -1639,6 +1622,8 @@ static ssize_t _ft_hang_intr_status_store(struct device *dev,
	if (device == NULL)
		return 0;
	adreno_dev = ADRENO_DEVICE(device);
	if (adreno_dev == NULL)
		return 0;

	mutex_lock(&device->mutex);
	ret = kgsl_sysfs_store(buf, &new_setting);
@@ -1654,21 +1639,10 @@ static ssize_t _ft_hang_intr_status_store(struct device *dev,
		else
			clear_bit(ADRENO_DEVICE_HANG_INTR, &adreno_dev->priv);
		/* Set the new setting based on device state */
		switch (device->state) {
		case KGSL_STATE_NAP:
		case KGSL_STATE_SLEEP:
		if (test_bit(ADRENO_DEVICE_STARTED, &adreno_dev->priv)) {
			kgsl_pwrctrl_change_state(device, KGSL_STATE_ACTIVE);
		case KGSL_STATE_ACTIVE:
			adreno_irqctrl(adreno_dev, 1);
		/*
		 * For following states setting will be picked up on device
		 * start. Still need them in switch statement to differentiate
		 * from default
		 */
		case KGSL_STATE_SLUMBER:
		case KGSL_STATE_SUSPEND:
			break;
		default:
		} else if (device->state == KGSL_STATE_INIT) {
			ret = -EACCES;
			/* reset back to old setting on error */
			if (new_setting)
@@ -2250,23 +2224,15 @@ static int adreno_soft_reset(struct kgsl_device *device)
	struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
	int ret;

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

	if (kgsl_pwrctrl_isenabled(device))
	adreno_irqctrl(adreno_dev, 0);

	kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);

	adreno_clear_gpu_fault(adreno_dev);
	/* since device is oficially off now clear start bit */
	clear_bit(ADRENO_DEVICE_STARTED, &adreno_dev->priv);

	/* Delete the idle timer */
	del_timer_sync(&device->idle_timer);

	/* Make sure we are totally awake */
	kgsl_pwrctrl_enable(device);

	/* save physical performance counter values before GPU soft reset */
	adreno_perfcounter_save(adreno_dev);

@@ -2287,7 +2253,6 @@ static int adreno_soft_reset(struct kgsl_device *device)
	adreno_coresight_start(adreno_dev);

	/* Enable IRQ */
	kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON);
	adreno_irqctrl(adreno_dev, 1);

	/* stop all ringbuffers to cancel RB events */
@@ -2324,7 +2289,7 @@ bool adreno_isidle(struct kgsl_device *device)
	struct adreno_ringbuffer *rb;
	int i;

	if (!kgsl_pwrctrl_isenabled(device))
	if (!kgsl_state_is_awake(device))
		return true;

	adreno_get_rptr(ADRENO_CURRENT_RINGBUFFER(adreno_dev));
+9 −4
Original line number Diff line number Diff line
@@ -172,7 +172,7 @@ static inline bool _isidle(struct kgsl_device *device)
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	unsigned int ts, i;

	if (!kgsl_pwrctrl_isenabled(device))
	if (!kgsl_state_is_awake(device))
		goto ret;

	/* If GPU HW status is not idle then return false */
@@ -1617,9 +1617,14 @@ static int dispatcher_do_fault(struct kgsl_device *device)
		 * For certain faults like h/w fault the interrupts are
		 * turned off, re-enable here
		 */
		if (kgsl_pwrctrl_isenabled(device))
			kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON);
		return 0;
		mutex_lock(&device->mutex);
		if (device->state == KGSL_STATE_AWARE)
			ret = kgsl_pwrctrl_change_state(device,
				KGSL_STATE_ACTIVE);
		else
			ret = 0;
		mutex_unlock(&device->mutex);
		return ret;
	}

	/* Turn off all the timers */
+4 −3
Original line number Diff line number Diff line
@@ -1063,8 +1063,7 @@ static int kgsl_close_device(struct kgsl_device *device)
		/* Fail if the wait times out */
		BUG_ON(atomic_read(&device->active_cnt) > 0);

		result = device->ftbl->stop(device);
		kgsl_pwrctrl_change_state(device, KGSL_STATE_INIT);
		result = kgsl_pwrctrl_change_state(device, KGSL_STATE_INIT);
	}
	mutex_unlock(&device->mutex);
	return result;
@@ -1155,8 +1154,10 @@ static int kgsl_open_device(struct kgsl_device *device)
	}
	device->open_count++;
err:
	if (result)
	if (result) {
		kgsl_pwrctrl_change_state(device, KGSL_STATE_INIT);
		atomic_dec(&device->active_cnt);
	}

	mutex_unlock(&device->mutex);
	return result;
+10 −1
Original line number Diff line number Diff line
@@ -52,7 +52,7 @@
#define KGSL_STATE_NAP		0x00000004
#define KGSL_STATE_SLEEP	0x00000008
#define KGSL_STATE_SUSPEND	0x00000010
#define KGSL_STATE_HUNG		0x00000020
#define KGSL_STATE_AWARE	0x00000020
#define KGSL_STATE_SLUMBER	0x00000080

#define KGSL_GRAPHICS_MEMORY_LOW_WATERMARK  0x1000000
@@ -663,6 +663,15 @@ static inline int kgsl_create_device_workqueue(struct kgsl_device *device)
	return 0;
}

static inline int kgsl_state_is_awake(struct kgsl_device *device)
{
	if (device->state == KGSL_STATE_ACTIVE ||
		device->state == KGSL_STATE_AWARE)
		return true;
	else
		return false;
}

int kgsl_readtimestamp(struct kgsl_device *device, void *priv,
		enum kgsl_timestamp_type type, unsigned int *timestamp);

+1 −1
Original line number Diff line number Diff line
@@ -375,7 +375,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
	if (adreno_dev->ft_pf_policy & KGSL_FT_PAGEFAULT_GPUHALT_ENABLE) {
		adreno_set_gpu_fault(adreno_dev, ADRENO_IOMMU_PAGE_FAULT);
		/* turn off GPU IRQ so we don't get faults from it too */
		kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF);
		kgsl_pwrctrl_change_state(device, KGSL_STATE_AWARE);
		adreno_dispatcher_schedule(device);
	}

Loading