mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-14 00:24:41 -04:00
msm: kgsl: Add target specific touch wakeup function
This is needed because gmu and rgmu targets have their own different power up sequences. Change-Id: I98f6d24938bfd5968e041c5b680b42750f87dd2e Signed-off-by: Harshdeep Dhatt <hdhatt@codeaurora.org>
This commit is contained in:
parent
51f932b1e3
commit
f7954ed2e5
4 changed files with 112 additions and 13 deletions
|
|
@ -321,23 +321,10 @@ void adreno_fault_detect_stop(struct adreno_device *adreno_dev)
|
|||
adreno_dev->fast_hang_detect = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* A workqueue callback responsible for actually turning on the GPU after a
|
||||
* touch event. kgsl_pwrctrl_change_state(ACTIVE) is used without any
|
||||
* active_count protection to avoid the need to maintain state. Either
|
||||
* somebody will start using the GPU or the idle timer will fire and put the
|
||||
* GPU back into slumber.
|
||||
*/
|
||||
static void adreno_input_work(struct work_struct *work)
|
||||
static void adreno_touch_wakeup(struct adreno_device *adreno_dev)
|
||||
{
|
||||
struct adreno_device *adreno_dev = container_of(work,
|
||||
struct adreno_device, input_work);
|
||||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
|
||||
mutex_lock(&device->mutex);
|
||||
|
||||
device->flags |= KGSL_FLAG_WAKE_ON_TOUCH;
|
||||
|
||||
/*
|
||||
* Don't schedule adreno_start in a high priority workqueue, we are
|
||||
* already in a workqueue which should be sufficient
|
||||
|
|
@ -352,6 +339,29 @@ static void adreno_input_work(struct work_struct *work)
|
|||
*/
|
||||
mod_timer(&device->idle_timer,
|
||||
jiffies + msecs_to_jiffies(adreno_wake_timeout));
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* A workqueue callback responsible for actually turning on the GPU after a
|
||||
* touch event. kgsl_pwrctrl_change_state(ACTIVE) is used without any
|
||||
* active_count protection to avoid the need to maintain state. Either
|
||||
* somebody will start using the GPU or the idle timer will fire and put the
|
||||
* GPU back into slumber.
|
||||
*/
|
||||
static void adreno_input_work(struct work_struct *work)
|
||||
{
|
||||
struct adreno_device *adreno_dev = container_of(work,
|
||||
struct adreno_device, input_work);
|
||||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
const struct adreno_power_ops *ops = ADRENO_POWER_OPS(adreno_dev);
|
||||
|
||||
mutex_lock(&device->mutex);
|
||||
|
||||
device->flags |= KGSL_FLAG_WAKE_ON_TOUCH;
|
||||
|
||||
ops->touch_wakeup(adreno_dev);
|
||||
|
||||
mutex_unlock(&device->mutex);
|
||||
}
|
||||
|
||||
|
|
@ -377,6 +387,11 @@ static void adreno_input_event(struct input_handle *handle, unsigned int type,
|
|||
if (device->flags & KGSL_FLAG_WAKE_ON_TOUCH)
|
||||
return;
|
||||
|
||||
if (gmu_core_isenabled(device)) {
|
||||
schedule_work(&adreno_dev->input_work);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the device is in nap, kick the idle timer to make sure that we
|
||||
* don't go into slumber before the first render. If the device is
|
||||
|
|
@ -3841,6 +3856,7 @@ const struct adreno_power_ops adreno_power_operations = {
|
|||
.active_count_put = adreno_pwrctrl_active_count_put,
|
||||
.pm_suspend = adreno_suspend,
|
||||
.pm_resume = adreno_resume,
|
||||
.touch_wakeup = adreno_touch_wakeup,
|
||||
};
|
||||
|
||||
static const struct of_device_id adreno_gmu_match[] = {
|
||||
|
|
|
|||
|
|
@ -357,6 +357,10 @@ struct adreno_power_ops {
|
|||
int (*pm_suspend)(struct adreno_device *adreno_dev);
|
||||
/** @pm_resume: Target specific function to resume the driver */
|
||||
void (*pm_resume)(struct adreno_device *adreno_dev);
|
||||
/**
|
||||
* @touch_wakeup: Target specific function to start gpu on touch event
|
||||
*/
|
||||
void (*touch_wakeup)(struct adreno_device *adreno_dev);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3113,6 +3113,44 @@ static void a6xx_gmu_pm_resume(struct adreno_device *adreno_dev)
|
|||
clear_bit(GMU_PRIV_PM_SUSPEND, &gmu->flags);
|
||||
}
|
||||
|
||||
static void a6xx_gmu_touch_wakeup(struct adreno_device *adreno_dev)
|
||||
{
|
||||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
struct a6xx_gmu_device *gmu = to_a6xx_gmu(adreno_dev);
|
||||
int ret;
|
||||
|
||||
/* Do not wake up a suspended device through touch event */
|
||||
if (test_bit(GMU_PRIV_PM_SUSPEND, &gmu->flags))
|
||||
return;
|
||||
|
||||
if (test_bit(GMU_PRIV_GPU_STARTED, &gmu->flags))
|
||||
goto done;
|
||||
|
||||
ret = a6xx_gmu_boot(adreno_dev);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
ret = a6xx_gpu_boot(adreno_dev);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
kgsl_pwrscale_wake(device);
|
||||
|
||||
set_bit(GMU_PRIV_GPU_STARTED, &gmu->flags);
|
||||
device->state = KGSL_STATE_ACTIVE;
|
||||
|
||||
done:
|
||||
/*
|
||||
* When waking up from a touch event we want to stay active long enough
|
||||
* for the user to send a draw command. The default idle timer timeout
|
||||
* is shorter than we want so go ahead and push the idle timer out
|
||||
* further for this special case
|
||||
*/
|
||||
mod_timer(&device->idle_timer, jiffies +
|
||||
msecs_to_jiffies(adreno_wake_timeout));
|
||||
|
||||
}
|
||||
|
||||
const struct adreno_power_ops a6xx_gmu_power_ops = {
|
||||
.first_open = a6xx_gmu_first_open,
|
||||
.last_close = a6xx_gmu_last_close,
|
||||
|
|
@ -3120,6 +3158,7 @@ const struct adreno_power_ops a6xx_gmu_power_ops = {
|
|||
.active_count_put = a6xx_gmu_active_count_put,
|
||||
.pm_suspend = a6xx_gmu_pm_suspend,
|
||||
.pm_resume = a6xx_gmu_pm_resume,
|
||||
.touch_wakeup = a6xx_gmu_touch_wakeup,
|
||||
};
|
||||
|
||||
int a6xx_gmu_device_probe(struct platform_device *pdev,
|
||||
|
|
|
|||
|
|
@ -881,6 +881,45 @@ static int a6xx_boot(struct adreno_device *adreno_dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void a6xx_rgmu_touch_wakeup(struct adreno_device *adreno_dev)
|
||||
{
|
||||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
struct a6xx_rgmu_device *rgmu = to_a6xx_rgmu(adreno_dev);
|
||||
int ret;
|
||||
|
||||
/* Do not wake up a suspended device through touch event */
|
||||
if (test_bit(RGMU_PRIV_PM_SUSPEND, &rgmu->flags))
|
||||
return;
|
||||
|
||||
if (test_bit(RGMU_PRIV_GPU_STARTED, &rgmu->flags))
|
||||
goto done;
|
||||
|
||||
ret = a6xx_rgmu_boot(adreno_dev);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
ret = a6xx_gpu_boot(adreno_dev);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
kgsl_pwrscale_wake(device);
|
||||
|
||||
set_bit(RGMU_PRIV_GPU_STARTED, &rgmu->flags);
|
||||
|
||||
device->state = KGSL_STATE_ACTIVE;
|
||||
|
||||
done:
|
||||
/*
|
||||
* When waking up from a touch event we want to stay active long enough
|
||||
* for the user to send a draw command. The default idle timer timeout
|
||||
* is shorter than we want so go ahead and push the idle timer out
|
||||
* further for this special case
|
||||
*/
|
||||
mod_timer(&device->idle_timer, jiffies +
|
||||
msecs_to_jiffies(adreno_wake_timeout));
|
||||
|
||||
}
|
||||
|
||||
static int a6xx_first_boot(struct adreno_device *adreno_dev)
|
||||
{
|
||||
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
|
||||
|
|
@ -1204,6 +1243,7 @@ const struct adreno_power_ops a6xx_rgmu_power_ops = {
|
|||
.active_count_put = a6xx_rgmu_active_count_put,
|
||||
.pm_suspend = a6xx_rgmu_pm_suspend,
|
||||
.pm_resume = a6xx_rgmu_pm_resume,
|
||||
.touch_wakeup = a6xx_rgmu_touch_wakeup,
|
||||
};
|
||||
|
||||
int a6xx_rgmu_device_probe(struct platform_device *pdev,
|
||||
|
|
|
|||
Loading…
Reference in a new issue