| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304 |
- /*
- * Copyright (c) 2015 MediaTek Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/init.h>
- #include <linux/sched.h>
- #include <mt-plat/mt_hotplug_strategy_internal.h>
- #include <mt-plat/mt_hotplug_strategy.h>
- int hps_set_cpu_num_base(enum hps_base_type_e type, unsigned int little_cpu,
- unsigned int big_cpu)
- {
- unsigned int num_online;
- if (hps_ctxt.init_state != INIT_STATE_DONE)
- return -1;
- if ((type < 0) || (type >= BASE_COUNT))
- return -1;
- if ((little_cpu > num_possible_little_cpus()) || (little_cpu < 1))
- return -1;
- if (hps_ctxt.is_hmp && (big_cpu > num_possible_big_cpus()))
- return -1;
- /* check mutex lock or not? use hps_ctxt.lock! */
- mutex_lock(&hps_ctxt.lock);
- switch (type) {
- case BASE_PERF_SERV:
- hps_ctxt.little_num_base_perf_serv = little_cpu;
- if (hps_ctxt.is_hmp)
- hps_ctxt.big_num_base_perf_serv = big_cpu;
- break;
- case BASE_WIFI:
- hps_ctxt.little_num_base_wifi = little_cpu;
- if (hps_ctxt.is_hmp)
- hps_ctxt.big_num_base_wifi = big_cpu;
- break;
- default:
- break;
- }
- if (hps_ctxt.is_hmp) {
- num_online = num_online_big_cpus();
- if ((num_online < big_cpu) &&
- (num_online < min(hps_ctxt.big_num_limit_thermal,
- hps_ctxt.big_num_limit_low_battery)) &&
- (num_online <
- min(hps_ctxt.big_num_limit_ultra_power_saving,
- hps_ctxt.big_num_limit_power_serv))) {
- hps_task_wakeup_nolock();
- } else {
- num_online = num_online_little_cpus();
- if ((num_online < little_cpu) &&
- (num_online <
- min(hps_ctxt.little_num_limit_thermal,
- hps_ctxt.little_num_limit_low_battery)) &&
- (num_online <
- min(
- hps_ctxt.little_num_limit_ultra_power_saving,
- hps_ctxt.little_num_limit_power_serv)) &&
- (num_online_cpus() < (little_cpu + big_cpu)))
- hps_task_wakeup_nolock();
- }
- } else {
- num_online = num_online_little_cpus();
- if ((num_online < little_cpu) &&
- (num_online <
- min(hps_ctxt.little_num_limit_thermal,
- hps_ctxt.little_num_limit_low_battery)) &&
- (num_online <
- min(hps_ctxt.little_num_limit_ultra_power_saving,
- hps_ctxt.little_num_limit_power_serv)))
- hps_task_wakeup_nolock();
- }
- mutex_unlock(&hps_ctxt.lock);
- return 0;
- }
- int hps_get_cpu_num_base(enum hps_base_type_e type,
- unsigned int *little_cpu_ptr, unsigned int *big_cpu_ptr)
- {
- if (hps_ctxt.init_state != INIT_STATE_DONE)
- return -1;
- if ((little_cpu_ptr == NULL) || (big_cpu_ptr == NULL))
- return -1;
- if ((type < 0) || (type >= BASE_COUNT))
- return -1;
- switch (type) {
- case BASE_PERF_SERV:
- *little_cpu_ptr = hps_ctxt.little_num_base_perf_serv;
- *big_cpu_ptr = hps_ctxt.big_num_base_perf_serv;
- break;
- case BASE_WIFI:
- *little_cpu_ptr = hps_ctxt.little_num_base_wifi;
- *big_cpu_ptr = hps_ctxt.big_num_base_wifi;
- break;
- default:
- break;
- }
- return 0;
- }
- /*
- * hps cpu num limit
- */
- int hps_set_cpu_num_limit(enum hps_limit_type_e type,
- unsigned int little_cpu, unsigned int big_cpu)
- {
- if (hps_ctxt.init_state != INIT_STATE_DONE)
- return -1;
- if ((type < 0) || (type >= LIMIT_COUNT))
- return -1;
- if ((little_cpu > num_possible_little_cpus()) || (little_cpu < 1))
- return -1;
- if (hps_ctxt.is_hmp && (big_cpu > num_possible_big_cpus()))
- return -1;
- mutex_lock(&hps_ctxt.lock);
- switch (type) {
- case LIMIT_THERMAL:
- hps_ctxt.little_num_limit_thermal = little_cpu;
- if (hps_ctxt.is_hmp)
- hps_ctxt.big_num_limit_thermal = big_cpu;
- break;
- case LIMIT_LOW_BATTERY:
- hps_ctxt.little_num_limit_low_battery = little_cpu;
- if (hps_ctxt.is_hmp)
- hps_ctxt.big_num_limit_low_battery = big_cpu;
- break;
- case LIMIT_ULTRA_POWER_SAVING:
- hps_ctxt.little_num_limit_ultra_power_saving = little_cpu;
- if (hps_ctxt.is_hmp)
- hps_ctxt.big_num_limit_ultra_power_saving = big_cpu;
- break;
- case LIMIT_POWER_SERV:
- hps_ctxt.little_num_limit_power_serv = little_cpu;
- if (hps_ctxt.is_hmp)
- hps_ctxt.big_num_limit_power_serv = big_cpu;
- break;
- default:
- break;
- }
- if (hps_ctxt.is_hmp) {
- if (num_online_big_cpus() > big_cpu)
- hps_task_wakeup_nolock();
- else if (num_online_little_cpus() > little_cpu)
- hps_task_wakeup_nolock();
- } else {
- if (num_online_little_cpus() > little_cpu)
- hps_task_wakeup_nolock();
- }
- mutex_unlock(&hps_ctxt.lock);
- return 0;
- }
- int hps_get_cpu_num_limit(enum hps_limit_type_e type,
- unsigned int *little_cpu_ptr, unsigned int *big_cpu_ptr)
- {
- if (hps_ctxt.init_state != INIT_STATE_DONE)
- return -1;
- if ((little_cpu_ptr == NULL) || (big_cpu_ptr == NULL))
- return -1;
- if ((type < 0) || (type >= LIMIT_COUNT))
- return -1;
- switch (type) {
- case LIMIT_THERMAL:
- *little_cpu_ptr = hps_ctxt.little_num_limit_thermal;
- *big_cpu_ptr = hps_ctxt.big_num_limit_thermal;
- break;
- case LIMIT_LOW_BATTERY:
- *little_cpu_ptr = hps_ctxt.little_num_limit_low_battery;
- *big_cpu_ptr = hps_ctxt.big_num_limit_low_battery;
- break;
- case LIMIT_ULTRA_POWER_SAVING:
- *little_cpu_ptr = hps_ctxt.little_num_limit_ultra_power_saving;
- *big_cpu_ptr = hps_ctxt.big_num_limit_ultra_power_saving;
- break;
- case LIMIT_POWER_SERV:
- *little_cpu_ptr = hps_ctxt.little_num_limit_power_serv;
- *big_cpu_ptr = hps_ctxt.big_num_limit_power_serv;
- break;
- default:
- break;
- }
- return 0;
- }
- /*
- * hps tlp
- */
- int hps_get_tlp(unsigned int *tlp_ptr)
- {
- if (hps_ctxt.init_state != INIT_STATE_DONE)
- return -1;
- if (tlp_ptr == NULL)
- return -1;
- *tlp_ptr = hps_ctxt.tlp_avg;
- return 0;
- }
- /*
- * hps num_possible_cpus
- */
- int hps_get_num_possible_cpus(
- unsigned int *little_cpu_ptr, unsigned int *big_cpu_ptr)
- {
- if (hps_ctxt.init_state != INIT_STATE_DONE)
- return -1;
- if ((little_cpu_ptr == NULL) || (big_cpu_ptr == NULL))
- return -1;
- *little_cpu_ptr = num_possible_little_cpus();
- *big_cpu_ptr = num_possible_big_cpus();
- return 0;
- }
- /*
- * hps num_online_cpus
- */
- int hps_get_num_online_cpus(
- unsigned int *little_cpu_ptr, unsigned int *big_cpu_ptr)
- {
- if (hps_ctxt.init_state != INIT_STATE_DONE)
- return -1;
- if ((little_cpu_ptr == NULL) || (big_cpu_ptr == NULL))
- return -1;
- *little_cpu_ptr = num_online_little_cpus();
- *big_cpu_ptr = num_online_big_cpus();
- return 0;
- }
- /*
- * hps cpu num base
- */
- int hps_get_enabled(unsigned int *enabled_ptr)
- {
- if (hps_ctxt.init_state != INIT_STATE_DONE)
- return -1;
- if (enabled_ptr == NULL)
- return -1;
- *enabled_ptr = hps_ctxt.enabled;
- return 0;
- }
- int hps_set_enabled(unsigned int enabled)
- {
- if (hps_ctxt.init_state != INIT_STATE_DONE)
- return -1;
- if (enabled > 1)
- return -1;
- /* check mutex lock or not? use hps_ctxt.lock! */
- mutex_lock(&hps_ctxt.lock);
- if (!hps_ctxt.enabled && enabled)
- hps_ctxt_reset_stas_nolock();
- hps_ctxt.enabled = enabled;
- mutex_unlock(&hps_ctxt.lock);
- return 0;
- }
|