Loading Documentation/devicetree/bindings/gpu/adreno.txt +2 −0 Original line number Diff line number Diff line Loading @@ -91,6 +91,8 @@ Optional Properties: - qcom,gpubw-dev: a phandle to a device representing bus bandwidth requirements (see devdw.txt) - qcom,idle-timeout: This property represents the time in microseconds for idle timeout. - qcom,deep-nap-timeout: This property represents the time in microseconds for entering deeper power state. - qcom,chipid: If it exists this property is used to replace the chip identification read from the GPU hardware. This is used to override faulty hardware readings. Loading drivers/gpu/msm/kgsl_device.h +1 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ #define KGSL_STATE_SUSPEND 0x00000010 #define KGSL_STATE_AWARE 0x00000020 #define KGSL_STATE_SLUMBER 0x00000080 #define KGSL_STATE_DEEP_NAP 0x00000100 #define KGSL_GRAPHICS_MEMORY_LOW_WATERMARK 0x1000000 Loading drivers/gpu/msm/kgsl_pwrctrl.c +102 −11 Original line number Diff line number Diff line Loading @@ -747,9 +747,9 @@ static ssize_t kgsl_pwrctrl_gpuclk_show(struct device *dev, return snprintf(buf, PAGE_SIZE, "%ld\n", kgsl_pwrctrl_active_freq(pwr)); } static ssize_t kgsl_pwrctrl_idle_timer_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) static ssize_t __timer_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count, enum kgsl_pwrctrl_timer_type timer) { unsigned int val = 0; struct kgsl_device *device = kgsl_device_from_dev(dev); Loading @@ -772,15 +772,24 @@ static ssize_t kgsl_pwrctrl_idle_timer_store(struct device *dev, return -EINVAL; mutex_lock(&device->mutex); /* Let the timeout be requested in ms, but convert to jiffies. */ if (timer == KGSL_PWR_IDLE_TIMER) device->pwrctrl.interval_timeout = msecs_to_jiffies(val); else if (timer == KGSL_PWR_DEEP_NAP_TIMER) device->pwrctrl.deep_nap_timeout = msecs_to_jiffies(val); mutex_unlock(&device->mutex); return count; } static ssize_t kgsl_pwrctrl_idle_timer_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return __timer_store(dev, attr, buf, count, KGSL_PWR_IDLE_TIMER); } static ssize_t kgsl_pwrctrl_idle_timer_show(struct device *dev, struct device_attribute *attr, char *buf) Loading @@ -793,6 +802,27 @@ static ssize_t kgsl_pwrctrl_idle_timer_show(struct device *dev, jiffies_to_msecs(device->pwrctrl.interval_timeout)); } static ssize_t kgsl_pwrctrl_deep_nap_timer_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return __timer_store(dev, attr, buf, count, KGSL_PWR_DEEP_NAP_TIMER); } static ssize_t kgsl_pwrctrl_deep_nap_timer_show(struct device *dev, struct device_attribute *attr, char *buf) { struct kgsl_device *device = kgsl_device_from_dev(dev); if (device == NULL) return 0; /* Show the idle_timeout converted to msec */ return snprintf(buf, PAGE_SIZE, "%u\n", jiffies_to_msecs(device->pwrctrl.deep_nap_timeout)); } static ssize_t kgsl_pwrctrl_pmqos_active_latency_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) Loading Loading @@ -1092,6 +1122,8 @@ static DEVICE_ATTR(max_gpuclk, 0644, kgsl_pwrctrl_max_gpuclk_show, kgsl_pwrctrl_max_gpuclk_store); static DEVICE_ATTR(idle_timer, 0644, kgsl_pwrctrl_idle_timer_show, kgsl_pwrctrl_idle_timer_store); static DEVICE_ATTR(deep_nap_timer, 0644, kgsl_pwrctrl_deep_nap_timer_show, kgsl_pwrctrl_deep_nap_timer_store); static DEVICE_ATTR(gpubusy, 0444, kgsl_pwrctrl_gpubusy_show, NULL); static DEVICE_ATTR(gpu_available_frequencies, 0444, Loading Loading @@ -1136,6 +1168,7 @@ static const struct device_attribute *pwrctrl_attr_list[] = { &dev_attr_gpuclk, &dev_attr_max_gpuclk, &dev_attr_idle_timer, &dev_attr_deep_nap_timer, &dev_attr_gpubusy, &dev_attr_gpu_available_frequencies, &dev_attr_max_pwrlevel, Loading Loading @@ -1203,7 +1236,9 @@ static void kgsl_pwrctrl_clk(struct kgsl_device *device, int state, clk_disable(pwr->grp_clks[i]); /* High latency clock maintenance. */ if ((pwr->pwrlevels[0].gpu_freq > 0) && (requested_state != KGSL_STATE_NAP)) { (requested_state != KGSL_STATE_NAP) && (requested_state != KGSL_STATE_DEEP_NAP)) { for (i = KGSL_MAX_CLKS - 1; i > 0; i--) if (pwr->grp_clks[i]) clk_unprepare(pwr->grp_clks[i]); Loading @@ -1227,7 +1262,8 @@ static void kgsl_pwrctrl_clk(struct kgsl_device *device, int state, trace_kgsl_clk(device, state, kgsl_pwrctrl_active_freq(pwr)); /* High latency clock maintenance. */ if (device->state != KGSL_STATE_NAP) { if ((device->state != KGSL_STATE_NAP) && (device->state != KGSL_STATE_DEEP_NAP)) { if (pwr->pwrlevels[0].gpu_freq > 0) clk_set_rate(pwr->grp_clks[0], pwr->pwrlevels Loading Loading @@ -1391,6 +1427,16 @@ static void kgsl_thermal_timer(unsigned long data) queue_work(device->work_queue, &device->pwrctrl.thermal_cycle_ws); } void kgsl_deep_nap_timer(unsigned long data) { struct kgsl_device *device = (struct kgsl_device *) data; if (device->state == KGSL_STATE_NAP) { kgsl_pwrctrl_request_state(device, KGSL_STATE_DEEP_NAP); queue_work(device->work_queue, &device->idle_check_ws); } } int kgsl_pwrctrl_init(struct kgsl_device *device) { int i, k, m, n = 0, result = 0; Loading Loading @@ -1419,6 +1465,10 @@ int kgsl_pwrctrl_init(struct kgsl_device *device) if (pwr->grp_clks[0] == NULL) pwr->grp_clks[0] = pwr->grp_clks[1]; if (of_property_read_u32(pdev->dev.of_node, "qcom,deep-nap-timeout", &pwr->deep_nap_timeout)) pwr->deep_nap_timeout = HZ/50; if (pdata->num_levels > KGSL_MAX_PWRLEVELS || pdata->num_levels < 1) { KGSL_PWR_ERR(device, "invalid power level count: %d\n", Loading Loading @@ -1649,6 +1699,8 @@ int kgsl_pwrctrl_init(struct kgsl_device *device) spin_lock_init(&pwr->limits_lock); pwr->sysfs_pwr_limit = kgsl_pwr_limits_add(KGSL_DEVICE_3D0); setup_timer(&pwr->deep_nap_timer, kgsl_deep_nap_timer, (unsigned long) device); devfreq_vbif_register_callback(kgsl_get_bw); return result; Loading Loading @@ -1724,7 +1776,8 @@ void kgsl_idle_check(struct work_struct *work) mutex_lock(&device->mutex); if (device->state == KGSL_STATE_ACTIVE || device->state == KGSL_STATE_NAP) { || device->state == KGSL_STATE_NAP || device->state == KGSL_STATE_DEEP_NAP) { if (!atomic_read(&device->active_cnt)) kgsl_pwrctrl_change_state(device, Loading @@ -1736,7 +1789,7 @@ void kgsl_idle_check(struct work_struct *work) jiffies + device->pwrctrl.interval_timeout); } if (device->state != KGSL_STATE_DEEP_NAP) kgsl_pwrscale_update(device); mutex_unlock(&device->mutex); } Loading Loading @@ -1878,6 +1931,10 @@ static int _wake(struct kgsl_device *device) kgsl_pwrscale_wake(device); kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON); /* fall through */ case KGSL_STATE_DEEP_NAP: pm_qos_update_request(&device->pwrctrl.pm_qos_req_dma, device->pwrctrl.pm_qos_active_latency); /* fall through */ case KGSL_STATE_NAP: /* Turn on the core clocks */ kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_ON, KGSL_STATE_ACTIVE); Loading @@ -1894,6 +1951,8 @@ static int _wake(struct kgsl_device *device) pwr->previous_pwrlevel = pwr->active_pwrlevel; mod_timer(&device->idle_timer, jiffies + device->pwrctrl.interval_timeout); del_timer_sync(&device->pwrctrl.deep_nap_timer); break; case KGSL_STATE_AWARE: /* Enable state before turning on irq */ Loading @@ -1901,6 +1960,7 @@ static int _wake(struct kgsl_device *device) kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON); mod_timer(&device->idle_timer, jiffies + device->pwrctrl.interval_timeout); del_timer_sync(&device->pwrctrl.deep_nap_timer); break; default: KGSL_PWR_WARN(device, "unhandled state %s\n", Loading Loading @@ -1930,7 +1990,8 @@ _aware(struct kgsl_device *device) case KGSL_STATE_INIT: status = kgsl_pwrctrl_enable(device); break; /* The following 2 cases shouldn't occur, but don't panic. */ /* The following 3 cases shouldn't occur, but don't panic. */ case KGSL_STATE_DEEP_NAP: case KGSL_STATE_NAP: case KGSL_STATE_SLEEP: status = _wake(device); Loading Loading @@ -1970,6 +2031,9 @@ _nap(struct kgsl_device *device) */ kgsl_pwrscale_update_stats(device); mod_timer(&device->pwrctrl.deep_nap_timer, jiffies + device->pwrctrl.deep_nap_timeout); kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_OFF, KGSL_STATE_NAP); kgsl_pwrctrl_set_state(device, KGSL_STATE_NAP); case KGSL_STATE_SLEEP: Loading @@ -1985,6 +2049,26 @@ _nap(struct kgsl_device *device) return 0; } static int _deep_nap(struct kgsl_device *device) { switch (device->state) { /* * Device is expected to be clock gated to move to * a deeper low power state. No other transition is permitted */ case KGSL_STATE_NAP: pm_qos_update_request(&device->pwrctrl.pm_qos_req_dma, PM_QOS_DEFAULT_VALUE); kgsl_pwrctrl_set_state(device, KGSL_STATE_DEEP_NAP); break; default: BUG_ON(1); break; } return 0; } static int _sleep(struct kgsl_device *device) { Loading Loading @@ -2030,11 +2114,13 @@ _slumber(struct kgsl_device *device) /* fall through */ case KGSL_STATE_NAP: case KGSL_STATE_SLEEP: case KGSL_STATE_DEEP_NAP: del_timer_sync(&device->idle_timer); if (device->pwrctrl.thermal_cycle == CYCLE_ACTIVE) { device->pwrctrl.thermal_cycle = CYCLE_ENABLE; del_timer_sync(&device->pwrctrl.thermal_timer); } del_timer_sync(&device->pwrctrl.deep_nap_timer); kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF); /* make sure power is on to stop the device*/ status = kgsl_pwrctrl_enable(device); Loading Loading @@ -2145,6 +2231,9 @@ int kgsl_pwrctrl_change_state(struct kgsl_device *device, int state) case KGSL_STATE_SUSPEND: status = _suspend(device); break; case KGSL_STATE_DEEP_NAP: status = _deep_nap(device); break; default: KGSL_PWR_INFO(device, "bad state request 0x%x\n", state); kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE); Loading Loading @@ -2190,6 +2279,8 @@ const char *kgsl_pwrstate_to_str(unsigned int state) return "ACTIVE"; case KGSL_STATE_NAP: return "NAP"; case KGSL_STATE_DEEP_NAP: return "DEEP_NAP"; case KGSL_STATE_SLEEP: return "SLEEP"; case KGSL_STATE_SUSPEND: Loading drivers/gpu/msm/kgsl_pwrctrl.h +9 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,11 @@ #define KGSL_PWR_DEL_LIMIT 1 #define KGSL_PWR_SET_LIMIT 2 enum kgsl_pwrctrl_timer_type { KGSL_PWR_IDLE_TIMER, KGSL_PWR_DEEP_NAP_TIMER, }; /* * States for thermal cycling. _DISABLE means that no cycling has been * requested. _ENABLE means that cycling has been requested, but GPU Loading Loading @@ -123,6 +128,8 @@ struct kgsl_pwr_constraint { * @limits - list head for limits * @limits_lock - spin lock to protect limits list * @sysfs_pwr_limit - pointer to the sysfs limits node * @deep_nap_timer - Timer struct for entering deep nap * @deep_nap_timeout - Timeout for entering deep nap */ struct kgsl_pwrctrl { Loading Loading @@ -169,6 +176,8 @@ struct kgsl_pwrctrl { struct list_head limits; spinlock_t limits_lock; struct kgsl_pwr_limit *sysfs_pwr_limit; struct timer_list deep_nap_timer; uint32_t deep_nap_timeout; }; int kgsl_pwrctrl_init(struct kgsl_device *device); Loading Loading
Documentation/devicetree/bindings/gpu/adreno.txt +2 −0 Original line number Diff line number Diff line Loading @@ -91,6 +91,8 @@ Optional Properties: - qcom,gpubw-dev: a phandle to a device representing bus bandwidth requirements (see devdw.txt) - qcom,idle-timeout: This property represents the time in microseconds for idle timeout. - qcom,deep-nap-timeout: This property represents the time in microseconds for entering deeper power state. - qcom,chipid: If it exists this property is used to replace the chip identification read from the GPU hardware. This is used to override faulty hardware readings. Loading
drivers/gpu/msm/kgsl_device.h +1 −0 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ #define KGSL_STATE_SUSPEND 0x00000010 #define KGSL_STATE_AWARE 0x00000020 #define KGSL_STATE_SLUMBER 0x00000080 #define KGSL_STATE_DEEP_NAP 0x00000100 #define KGSL_GRAPHICS_MEMORY_LOW_WATERMARK 0x1000000 Loading
drivers/gpu/msm/kgsl_pwrctrl.c +102 −11 Original line number Diff line number Diff line Loading @@ -747,9 +747,9 @@ static ssize_t kgsl_pwrctrl_gpuclk_show(struct device *dev, return snprintf(buf, PAGE_SIZE, "%ld\n", kgsl_pwrctrl_active_freq(pwr)); } static ssize_t kgsl_pwrctrl_idle_timer_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) static ssize_t __timer_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count, enum kgsl_pwrctrl_timer_type timer) { unsigned int val = 0; struct kgsl_device *device = kgsl_device_from_dev(dev); Loading @@ -772,15 +772,24 @@ static ssize_t kgsl_pwrctrl_idle_timer_store(struct device *dev, return -EINVAL; mutex_lock(&device->mutex); /* Let the timeout be requested in ms, but convert to jiffies. */ if (timer == KGSL_PWR_IDLE_TIMER) device->pwrctrl.interval_timeout = msecs_to_jiffies(val); else if (timer == KGSL_PWR_DEEP_NAP_TIMER) device->pwrctrl.deep_nap_timeout = msecs_to_jiffies(val); mutex_unlock(&device->mutex); return count; } static ssize_t kgsl_pwrctrl_idle_timer_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return __timer_store(dev, attr, buf, count, KGSL_PWR_IDLE_TIMER); } static ssize_t kgsl_pwrctrl_idle_timer_show(struct device *dev, struct device_attribute *attr, char *buf) Loading @@ -793,6 +802,27 @@ static ssize_t kgsl_pwrctrl_idle_timer_show(struct device *dev, jiffies_to_msecs(device->pwrctrl.interval_timeout)); } static ssize_t kgsl_pwrctrl_deep_nap_timer_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { return __timer_store(dev, attr, buf, count, KGSL_PWR_DEEP_NAP_TIMER); } static ssize_t kgsl_pwrctrl_deep_nap_timer_show(struct device *dev, struct device_attribute *attr, char *buf) { struct kgsl_device *device = kgsl_device_from_dev(dev); if (device == NULL) return 0; /* Show the idle_timeout converted to msec */ return snprintf(buf, PAGE_SIZE, "%u\n", jiffies_to_msecs(device->pwrctrl.deep_nap_timeout)); } static ssize_t kgsl_pwrctrl_pmqos_active_latency_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) Loading Loading @@ -1092,6 +1122,8 @@ static DEVICE_ATTR(max_gpuclk, 0644, kgsl_pwrctrl_max_gpuclk_show, kgsl_pwrctrl_max_gpuclk_store); static DEVICE_ATTR(idle_timer, 0644, kgsl_pwrctrl_idle_timer_show, kgsl_pwrctrl_idle_timer_store); static DEVICE_ATTR(deep_nap_timer, 0644, kgsl_pwrctrl_deep_nap_timer_show, kgsl_pwrctrl_deep_nap_timer_store); static DEVICE_ATTR(gpubusy, 0444, kgsl_pwrctrl_gpubusy_show, NULL); static DEVICE_ATTR(gpu_available_frequencies, 0444, Loading Loading @@ -1136,6 +1168,7 @@ static const struct device_attribute *pwrctrl_attr_list[] = { &dev_attr_gpuclk, &dev_attr_max_gpuclk, &dev_attr_idle_timer, &dev_attr_deep_nap_timer, &dev_attr_gpubusy, &dev_attr_gpu_available_frequencies, &dev_attr_max_pwrlevel, Loading Loading @@ -1203,7 +1236,9 @@ static void kgsl_pwrctrl_clk(struct kgsl_device *device, int state, clk_disable(pwr->grp_clks[i]); /* High latency clock maintenance. */ if ((pwr->pwrlevels[0].gpu_freq > 0) && (requested_state != KGSL_STATE_NAP)) { (requested_state != KGSL_STATE_NAP) && (requested_state != KGSL_STATE_DEEP_NAP)) { for (i = KGSL_MAX_CLKS - 1; i > 0; i--) if (pwr->grp_clks[i]) clk_unprepare(pwr->grp_clks[i]); Loading @@ -1227,7 +1262,8 @@ static void kgsl_pwrctrl_clk(struct kgsl_device *device, int state, trace_kgsl_clk(device, state, kgsl_pwrctrl_active_freq(pwr)); /* High latency clock maintenance. */ if (device->state != KGSL_STATE_NAP) { if ((device->state != KGSL_STATE_NAP) && (device->state != KGSL_STATE_DEEP_NAP)) { if (pwr->pwrlevels[0].gpu_freq > 0) clk_set_rate(pwr->grp_clks[0], pwr->pwrlevels Loading Loading @@ -1391,6 +1427,16 @@ static void kgsl_thermal_timer(unsigned long data) queue_work(device->work_queue, &device->pwrctrl.thermal_cycle_ws); } void kgsl_deep_nap_timer(unsigned long data) { struct kgsl_device *device = (struct kgsl_device *) data; if (device->state == KGSL_STATE_NAP) { kgsl_pwrctrl_request_state(device, KGSL_STATE_DEEP_NAP); queue_work(device->work_queue, &device->idle_check_ws); } } int kgsl_pwrctrl_init(struct kgsl_device *device) { int i, k, m, n = 0, result = 0; Loading Loading @@ -1419,6 +1465,10 @@ int kgsl_pwrctrl_init(struct kgsl_device *device) if (pwr->grp_clks[0] == NULL) pwr->grp_clks[0] = pwr->grp_clks[1]; if (of_property_read_u32(pdev->dev.of_node, "qcom,deep-nap-timeout", &pwr->deep_nap_timeout)) pwr->deep_nap_timeout = HZ/50; if (pdata->num_levels > KGSL_MAX_PWRLEVELS || pdata->num_levels < 1) { KGSL_PWR_ERR(device, "invalid power level count: %d\n", Loading Loading @@ -1649,6 +1699,8 @@ int kgsl_pwrctrl_init(struct kgsl_device *device) spin_lock_init(&pwr->limits_lock); pwr->sysfs_pwr_limit = kgsl_pwr_limits_add(KGSL_DEVICE_3D0); setup_timer(&pwr->deep_nap_timer, kgsl_deep_nap_timer, (unsigned long) device); devfreq_vbif_register_callback(kgsl_get_bw); return result; Loading Loading @@ -1724,7 +1776,8 @@ void kgsl_idle_check(struct work_struct *work) mutex_lock(&device->mutex); if (device->state == KGSL_STATE_ACTIVE || device->state == KGSL_STATE_NAP) { || device->state == KGSL_STATE_NAP || device->state == KGSL_STATE_DEEP_NAP) { if (!atomic_read(&device->active_cnt)) kgsl_pwrctrl_change_state(device, Loading @@ -1736,7 +1789,7 @@ void kgsl_idle_check(struct work_struct *work) jiffies + device->pwrctrl.interval_timeout); } if (device->state != KGSL_STATE_DEEP_NAP) kgsl_pwrscale_update(device); mutex_unlock(&device->mutex); } Loading Loading @@ -1878,6 +1931,10 @@ static int _wake(struct kgsl_device *device) kgsl_pwrscale_wake(device); kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON); /* fall through */ case KGSL_STATE_DEEP_NAP: pm_qos_update_request(&device->pwrctrl.pm_qos_req_dma, device->pwrctrl.pm_qos_active_latency); /* fall through */ case KGSL_STATE_NAP: /* Turn on the core clocks */ kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_ON, KGSL_STATE_ACTIVE); Loading @@ -1894,6 +1951,8 @@ static int _wake(struct kgsl_device *device) pwr->previous_pwrlevel = pwr->active_pwrlevel; mod_timer(&device->idle_timer, jiffies + device->pwrctrl.interval_timeout); del_timer_sync(&device->pwrctrl.deep_nap_timer); break; case KGSL_STATE_AWARE: /* Enable state before turning on irq */ Loading @@ -1901,6 +1960,7 @@ static int _wake(struct kgsl_device *device) kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON); mod_timer(&device->idle_timer, jiffies + device->pwrctrl.interval_timeout); del_timer_sync(&device->pwrctrl.deep_nap_timer); break; default: KGSL_PWR_WARN(device, "unhandled state %s\n", Loading Loading @@ -1930,7 +1990,8 @@ _aware(struct kgsl_device *device) case KGSL_STATE_INIT: status = kgsl_pwrctrl_enable(device); break; /* The following 2 cases shouldn't occur, but don't panic. */ /* The following 3 cases shouldn't occur, but don't panic. */ case KGSL_STATE_DEEP_NAP: case KGSL_STATE_NAP: case KGSL_STATE_SLEEP: status = _wake(device); Loading Loading @@ -1970,6 +2031,9 @@ _nap(struct kgsl_device *device) */ kgsl_pwrscale_update_stats(device); mod_timer(&device->pwrctrl.deep_nap_timer, jiffies + device->pwrctrl.deep_nap_timeout); kgsl_pwrctrl_clk(device, KGSL_PWRFLAGS_OFF, KGSL_STATE_NAP); kgsl_pwrctrl_set_state(device, KGSL_STATE_NAP); case KGSL_STATE_SLEEP: Loading @@ -1985,6 +2049,26 @@ _nap(struct kgsl_device *device) return 0; } static int _deep_nap(struct kgsl_device *device) { switch (device->state) { /* * Device is expected to be clock gated to move to * a deeper low power state. No other transition is permitted */ case KGSL_STATE_NAP: pm_qos_update_request(&device->pwrctrl.pm_qos_req_dma, PM_QOS_DEFAULT_VALUE); kgsl_pwrctrl_set_state(device, KGSL_STATE_DEEP_NAP); break; default: BUG_ON(1); break; } return 0; } static int _sleep(struct kgsl_device *device) { Loading Loading @@ -2030,11 +2114,13 @@ _slumber(struct kgsl_device *device) /* fall through */ case KGSL_STATE_NAP: case KGSL_STATE_SLEEP: case KGSL_STATE_DEEP_NAP: del_timer_sync(&device->idle_timer); if (device->pwrctrl.thermal_cycle == CYCLE_ACTIVE) { device->pwrctrl.thermal_cycle = CYCLE_ENABLE; del_timer_sync(&device->pwrctrl.thermal_timer); } del_timer_sync(&device->pwrctrl.deep_nap_timer); kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_OFF); /* make sure power is on to stop the device*/ status = kgsl_pwrctrl_enable(device); Loading Loading @@ -2145,6 +2231,9 @@ int kgsl_pwrctrl_change_state(struct kgsl_device *device, int state) case KGSL_STATE_SUSPEND: status = _suspend(device); break; case KGSL_STATE_DEEP_NAP: status = _deep_nap(device); break; default: KGSL_PWR_INFO(device, "bad state request 0x%x\n", state); kgsl_pwrctrl_request_state(device, KGSL_STATE_NONE); Loading Loading @@ -2190,6 +2279,8 @@ const char *kgsl_pwrstate_to_str(unsigned int state) return "ACTIVE"; case KGSL_STATE_NAP: return "NAP"; case KGSL_STATE_DEEP_NAP: return "DEEP_NAP"; case KGSL_STATE_SLEEP: return "SLEEP"; case KGSL_STATE_SUSPEND: Loading
drivers/gpu/msm/kgsl_pwrctrl.h +9 −0 Original line number Diff line number Diff line Loading @@ -48,6 +48,11 @@ #define KGSL_PWR_DEL_LIMIT 1 #define KGSL_PWR_SET_LIMIT 2 enum kgsl_pwrctrl_timer_type { KGSL_PWR_IDLE_TIMER, KGSL_PWR_DEEP_NAP_TIMER, }; /* * States for thermal cycling. _DISABLE means that no cycling has been * requested. _ENABLE means that cycling has been requested, but GPU Loading Loading @@ -123,6 +128,8 @@ struct kgsl_pwr_constraint { * @limits - list head for limits * @limits_lock - spin lock to protect limits list * @sysfs_pwr_limit - pointer to the sysfs limits node * @deep_nap_timer - Timer struct for entering deep nap * @deep_nap_timeout - Timeout for entering deep nap */ struct kgsl_pwrctrl { Loading Loading @@ -169,6 +176,8 @@ struct kgsl_pwrctrl { struct list_head limits; spinlock_t limits_lock; struct kgsl_pwr_limit *sysfs_pwr_limit; struct timer_list deep_nap_timer; uint32_t deep_nap_timeout; }; int kgsl_pwrctrl_init(struct kgsl_device *device); Loading