Loading Documentation/devicetree/bindings/gpu/adreno.txt +3 −0 Original line number Original line Diff line number Diff line Loading @@ -80,6 +80,9 @@ DCVS Core info Optional Properties: Optional Properties: - qcom,initial-powerlevel: This value indicates which qcom,gpu-pwrlevel should be used at start time - qcom,initial-powerlevel: This value indicates which qcom,gpu-pwrlevel should be used at start time and when coming back out of resume and when coming back out of resume - qcom,restrict-powerlevel: This value to limit max GPU power level jump during the clock switch and while coming back out of slumber. Max GPU power level jump still allowed from the restricted-pwerlevel. - qcom,bus-control: Boolean. Enables an independent bus vote from the gpu frequency - qcom,bus-control: Boolean. Enables an independent bus vote from the gpu frequency - qcom,bus-width: Bus width in number of bytes. This enables dynamic AB bus voting based on - qcom,bus-width: Bus width in number of bytes. This enables dynamic AB bus voting based on bus width and actual bus transactions. bus width and actual bus transactions. Loading drivers/gpu/msm/kgsl_pwrctrl.c +32 −2 Original line number Original line Diff line number Diff line /* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -34,6 +34,7 @@ #define KGSL_PWRFLAGS_AXI_ON 2 #define KGSL_PWRFLAGS_AXI_ON 2 #define KGSL_PWRFLAGS_IRQ_ON 3 #define KGSL_PWRFLAGS_IRQ_ON 3 #define KGSL_PWRFLAGS_RETENTION_ON 4 #define KGSL_PWRFLAGS_RETENTION_ON 4 #define KGSL_PWRFLAGS_RESTRICT_MAX_LEVEL_JUMP 6 #define UPDATE_BUSY_VAL 1000000 #define UPDATE_BUSY_VAL 1000000 Loading Loading @@ -344,6 +345,16 @@ void kgsl_pwrctrl_pwrlevel_change(struct kgsl_device *device, */ */ kgsl_pwrctrl_set_thermal_cycle(pwr, new_level); kgsl_pwrctrl_set_thermal_cycle(pwr, new_level); /* Check any restriction over new level jump */ if (test_bit(KGSL_PWRFLAGS_RESTRICT_MAX_LEVEL_JUMP, &device->pwrctrl.ctrl_flags)) { if (new_level == 0 && old_level > device->pwrctrl.restrict_pwrlevel) new_level = device->pwrctrl.restrict_pwrlevel; else if (new_level == 0 && old_level == 0) new_level = device->pwrctrl.restrict_pwrlevel; } if (new_level == old_level) if (new_level == old_level) return; return; Loading Loading @@ -2049,6 +2060,11 @@ int kgsl_pwrctrl_init(struct kgsl_device *device) pwr->power_flags = BIT(KGSL_PWRFLAGS_RETENTION_ON); pwr->power_flags = BIT(KGSL_PWRFLAGS_RETENTION_ON); if (!of_property_read_u32(pdev->dev.of_node, "qcom,restrict-pwrlevel", &pwr->restrict_pwrlevel)) device->pwrctrl.ctrl_flags |= BIT(KGSL_PWRFLAGS_RESTRICT_MAX_LEVEL_JUMP); if (pwr->num_pwrlevels == 0) { if (pwr->num_pwrlevels == 0) { KGSL_PWR_ERR(device, "No power levels are defined\n"); KGSL_PWR_ERR(device, "No power levels are defined\n"); return -EINVAL; return -EINVAL; Loading Loading @@ -2394,6 +2410,7 @@ static int _wake(struct kgsl_device *device) { { struct kgsl_pwrctrl *pwr = &device->pwrctrl; struct kgsl_pwrctrl *pwr = &device->pwrctrl; int status = 0; int status = 0; bool limit_max_pwrlevel = false; switch (device->state) { switch (device->state) { case KGSL_STATE_SUSPEND: case KGSL_STATE_SUSPEND: Loading @@ -2416,6 +2433,16 @@ static int _wake(struct kgsl_device *device) kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_ON); kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_ON); kgsl_pwrscale_wake(device); kgsl_pwrscale_wake(device); kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON); kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON); /* * Check any restriction on max power level, clk_set_rate() * wil set based on the active_pwrlevel. */ if (test_bit(KGSL_PWRFLAGS_RESTRICT_MAX_LEVEL_JUMP, &pwr->ctrl_flags) && (pwr->active_pwrlevel == 0)) { pwr->active_pwrlevel = pwr->restrict_pwrlevel; limit_max_pwrlevel = true; } /* fall through */ /* fall through */ case KGSL_STATE_DEEP_NAP: case KGSL_STATE_DEEP_NAP: pm_qos_update_request(&device->pwrctrl.pm_qos_req_dma, pm_qos_update_request(&device->pwrctrl.pm_qos_req_dma, Loading @@ -2441,6 +2468,9 @@ static int _wake(struct kgsl_device *device) kgsl_pwrctrl_pwrlevel_change_settings(device, 0); kgsl_pwrctrl_pwrlevel_change_settings(device, 0); kgsl_pwrctrl_pwrlevel_change_settings(device, 1); kgsl_pwrctrl_pwrlevel_change_settings(device, 1); /* All settings for power level transitions are complete*/ /* All settings for power level transitions are complete*/ if (limit_max_pwrlevel) pwr->previous_pwrlevel = 0; else pwr->previous_pwrlevel = pwr->active_pwrlevel; pwr->previous_pwrlevel = pwr->active_pwrlevel; mod_timer(&device->idle_timer, jiffies + mod_timer(&device->idle_timer, jiffies + device->pwrctrl.interval_timeout); device->pwrctrl.interval_timeout); Loading drivers/gpu/msm/kgsl_pwrctrl.h +3 −1 Original line number Original line Diff line number Diff line /* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -116,6 +116,7 @@ struct kgsl_regulator { * @previous_pwrlevel - The power level before transition * @previous_pwrlevel - The power level before transition * @thermal_pwrlevel - maximum powerlevel constraint from thermal * @thermal_pwrlevel - maximum powerlevel constraint from thermal * @default_pwrlevel - device wake up power level * @default_pwrlevel - device wake up power level * @restrict_pwrlevel - maximum power level jump to restrict * @max_pwrlevel - maximum allowable powerlevel per the user * @max_pwrlevel - maximum allowable powerlevel per the user * @min_pwrlevel - minimum allowable powerlevel per the user * @min_pwrlevel - minimum allowable powerlevel per the user * @num_pwrlevels - number of available power levels * @num_pwrlevels - number of available power levels Loading Loading @@ -169,6 +170,7 @@ struct kgsl_pwrctrl { unsigned int previous_pwrlevel; unsigned int previous_pwrlevel; unsigned int thermal_pwrlevel; unsigned int thermal_pwrlevel; unsigned int default_pwrlevel; unsigned int default_pwrlevel; unsigned int restrict_pwrlevel; unsigned int wakeup_maxpwrlevel; unsigned int wakeup_maxpwrlevel; unsigned int max_pwrlevel; unsigned int max_pwrlevel; unsigned int min_pwrlevel; unsigned int min_pwrlevel; Loading Loading
Documentation/devicetree/bindings/gpu/adreno.txt +3 −0 Original line number Original line Diff line number Diff line Loading @@ -80,6 +80,9 @@ DCVS Core info Optional Properties: Optional Properties: - qcom,initial-powerlevel: This value indicates which qcom,gpu-pwrlevel should be used at start time - qcom,initial-powerlevel: This value indicates which qcom,gpu-pwrlevel should be used at start time and when coming back out of resume and when coming back out of resume - qcom,restrict-powerlevel: This value to limit max GPU power level jump during the clock switch and while coming back out of slumber. Max GPU power level jump still allowed from the restricted-pwerlevel. - qcom,bus-control: Boolean. Enables an independent bus vote from the gpu frequency - qcom,bus-control: Boolean. Enables an independent bus vote from the gpu frequency - qcom,bus-width: Bus width in number of bytes. This enables dynamic AB bus voting based on - qcom,bus-width: Bus width in number of bytes. This enables dynamic AB bus voting based on bus width and actual bus transactions. bus width and actual bus transactions. Loading
drivers/gpu/msm/kgsl_pwrctrl.c +32 −2 Original line number Original line Diff line number Diff line /* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -34,6 +34,7 @@ #define KGSL_PWRFLAGS_AXI_ON 2 #define KGSL_PWRFLAGS_AXI_ON 2 #define KGSL_PWRFLAGS_IRQ_ON 3 #define KGSL_PWRFLAGS_IRQ_ON 3 #define KGSL_PWRFLAGS_RETENTION_ON 4 #define KGSL_PWRFLAGS_RETENTION_ON 4 #define KGSL_PWRFLAGS_RESTRICT_MAX_LEVEL_JUMP 6 #define UPDATE_BUSY_VAL 1000000 #define UPDATE_BUSY_VAL 1000000 Loading Loading @@ -344,6 +345,16 @@ void kgsl_pwrctrl_pwrlevel_change(struct kgsl_device *device, */ */ kgsl_pwrctrl_set_thermal_cycle(pwr, new_level); kgsl_pwrctrl_set_thermal_cycle(pwr, new_level); /* Check any restriction over new level jump */ if (test_bit(KGSL_PWRFLAGS_RESTRICT_MAX_LEVEL_JUMP, &device->pwrctrl.ctrl_flags)) { if (new_level == 0 && old_level > device->pwrctrl.restrict_pwrlevel) new_level = device->pwrctrl.restrict_pwrlevel; else if (new_level == 0 && old_level == 0) new_level = device->pwrctrl.restrict_pwrlevel; } if (new_level == old_level) if (new_level == old_level) return; return; Loading Loading @@ -2049,6 +2060,11 @@ int kgsl_pwrctrl_init(struct kgsl_device *device) pwr->power_flags = BIT(KGSL_PWRFLAGS_RETENTION_ON); pwr->power_flags = BIT(KGSL_PWRFLAGS_RETENTION_ON); if (!of_property_read_u32(pdev->dev.of_node, "qcom,restrict-pwrlevel", &pwr->restrict_pwrlevel)) device->pwrctrl.ctrl_flags |= BIT(KGSL_PWRFLAGS_RESTRICT_MAX_LEVEL_JUMP); if (pwr->num_pwrlevels == 0) { if (pwr->num_pwrlevels == 0) { KGSL_PWR_ERR(device, "No power levels are defined\n"); KGSL_PWR_ERR(device, "No power levels are defined\n"); return -EINVAL; return -EINVAL; Loading Loading @@ -2394,6 +2410,7 @@ static int _wake(struct kgsl_device *device) { { struct kgsl_pwrctrl *pwr = &device->pwrctrl; struct kgsl_pwrctrl *pwr = &device->pwrctrl; int status = 0; int status = 0; bool limit_max_pwrlevel = false; switch (device->state) { switch (device->state) { case KGSL_STATE_SUSPEND: case KGSL_STATE_SUSPEND: Loading @@ -2416,6 +2433,16 @@ static int _wake(struct kgsl_device *device) kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_ON); kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_ON); kgsl_pwrscale_wake(device); kgsl_pwrscale_wake(device); kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON); kgsl_pwrctrl_irq(device, KGSL_PWRFLAGS_ON); /* * Check any restriction on max power level, clk_set_rate() * wil set based on the active_pwrlevel. */ if (test_bit(KGSL_PWRFLAGS_RESTRICT_MAX_LEVEL_JUMP, &pwr->ctrl_flags) && (pwr->active_pwrlevel == 0)) { pwr->active_pwrlevel = pwr->restrict_pwrlevel; limit_max_pwrlevel = true; } /* fall through */ /* fall through */ case KGSL_STATE_DEEP_NAP: case KGSL_STATE_DEEP_NAP: pm_qos_update_request(&device->pwrctrl.pm_qos_req_dma, pm_qos_update_request(&device->pwrctrl.pm_qos_req_dma, Loading @@ -2441,6 +2468,9 @@ static int _wake(struct kgsl_device *device) kgsl_pwrctrl_pwrlevel_change_settings(device, 0); kgsl_pwrctrl_pwrlevel_change_settings(device, 0); kgsl_pwrctrl_pwrlevel_change_settings(device, 1); kgsl_pwrctrl_pwrlevel_change_settings(device, 1); /* All settings for power level transitions are complete*/ /* All settings for power level transitions are complete*/ if (limit_max_pwrlevel) pwr->previous_pwrlevel = 0; else pwr->previous_pwrlevel = pwr->active_pwrlevel; pwr->previous_pwrlevel = pwr->active_pwrlevel; mod_timer(&device->idle_timer, jiffies + mod_timer(&device->idle_timer, jiffies + device->pwrctrl.interval_timeout); device->pwrctrl.interval_timeout); Loading
drivers/gpu/msm/kgsl_pwrctrl.h +3 −1 Original line number Original line Diff line number Diff line /* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2010-2017, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -116,6 +116,7 @@ struct kgsl_regulator { * @previous_pwrlevel - The power level before transition * @previous_pwrlevel - The power level before transition * @thermal_pwrlevel - maximum powerlevel constraint from thermal * @thermal_pwrlevel - maximum powerlevel constraint from thermal * @default_pwrlevel - device wake up power level * @default_pwrlevel - device wake up power level * @restrict_pwrlevel - maximum power level jump to restrict * @max_pwrlevel - maximum allowable powerlevel per the user * @max_pwrlevel - maximum allowable powerlevel per the user * @min_pwrlevel - minimum allowable powerlevel per the user * @min_pwrlevel - minimum allowable powerlevel per the user * @num_pwrlevels - number of available power levels * @num_pwrlevels - number of available power levels Loading Loading @@ -169,6 +170,7 @@ struct kgsl_pwrctrl { unsigned int previous_pwrlevel; unsigned int previous_pwrlevel; unsigned int thermal_pwrlevel; unsigned int thermal_pwrlevel; unsigned int default_pwrlevel; unsigned int default_pwrlevel; unsigned int restrict_pwrlevel; unsigned int wakeup_maxpwrlevel; unsigned int wakeup_maxpwrlevel; unsigned int max_pwrlevel; unsigned int max_pwrlevel; unsigned int min_pwrlevel; unsigned int min_pwrlevel; Loading