6db4831e98
Android 14
129 lines
3.1 KiB
C
129 lines
3.1 KiB
C
/*
|
|
* Copyright (C) 2012-2019 Samsung Electronics, Inc.
|
|
*
|
|
* This software is licensed under the terms of the GNU General Public
|
|
* License version 2, as published by the Free Software Foundation, and
|
|
* may be copied, distributed, and modified under those terms.
|
|
*
|
|
* 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/atomic.h>
|
|
#include <linux/fs.h>
|
|
#include <linux/module.h>
|
|
#include <linux/mutex.h>
|
|
#include <linux/pm_qos.h>
|
|
|
|
#include "tzdev_internal.h"
|
|
#include "core/cdev.h"
|
|
#include "core/log.h"
|
|
#include "core/notifier.h"
|
|
#include "core/subsystem.h"
|
|
#include "extensions/hotplug.h"
|
|
|
|
#if CONFIG_TZDEV_BOOST_CLUSTER == 1
|
|
|
|
/* cluster 1 is a high performance cluster */
|
|
#ifndef PM_QOS_CLUSTER1_FREQ_MAX_DEFAULT_VALUE
|
|
#define TZ_BOOST_CPU_FREQ_MAX_DEFAULT_VALUE INT_MAX
|
|
#else
|
|
#define TZ_BOOST_CPU_FREQ_MAX_DEFAULT_VALUE PM_QOS_CLUSTER1_FREQ_MAX_DEFAULT_VALUE
|
|
#endif
|
|
|
|
#define TZ_BOOST_CPU_FREQ_MIN PM_QOS_CLUSTER1_FREQ_MIN
|
|
|
|
#elif CONFIG_TZDEV_BOOST_CLUSTER == 2
|
|
|
|
/* cluster 2 is a high performance cluster */
|
|
#ifndef PM_QOS_CLUSTER2_FREQ_MAX_DEFAULT_VALUE
|
|
#define TZ_BOOST_CPU_FREQ_MAX_DEFAULT_VALUE INT_MAX
|
|
#else
|
|
#define TZ_BOOST_CPU_FREQ_MAX_DEFAULT_VALUE PM_QOS_CLUSTER2_FREQ_MAX_DEFAULT_VALUE
|
|
#endif
|
|
|
|
#define TZ_BOOST_CPU_FREQ_MIN PM_QOS_CLUSTER2_FREQ_MIN
|
|
|
|
#endif /* TZDEV_BOOST_CLUSTER */
|
|
|
|
static int tz_boost_users = 0;
|
|
static struct pm_qos_request tz_boost_qos;
|
|
static unsigned int cpu_boost_mask;
|
|
static DEFINE_MUTEX(tz_boost_lock);
|
|
|
|
static int tz_boost_init_call(struct notifier_block *cb, unsigned long code, void *unused)
|
|
{
|
|
struct tzio_swd_sysconf *swd_sysconf;
|
|
int i;
|
|
|
|
(void)cb;
|
|
(void)code;
|
|
(void)unused;
|
|
|
|
swd_sysconf = &tzdev_sysconf()->swd_sysconf;
|
|
|
|
for (i = 0; i < CPU_CLUSTER_MAX; ++i) {
|
|
if (swd_sysconf->cluster_info[i].type == CPU_CLUSTER_BIG) {
|
|
cpu_boost_mask = swd_sysconf->cluster_info[i].mask;
|
|
log_info(tzdev_boost, "Booster initialization done.\n");
|
|
return NOTIFY_DONE;
|
|
}
|
|
}
|
|
|
|
log_error(tzdev_boost, "Failed to get CPU boost mask\n");
|
|
|
|
return NOTIFY_BAD;
|
|
}
|
|
|
|
static struct notifier_block tz_boost_init_notifier = {
|
|
.notifier_call = tz_boost_init_call,
|
|
};
|
|
|
|
int tz_boost_init(void)
|
|
{
|
|
int rc;
|
|
|
|
rc = tzdev_blocking_notifier_register(TZDEV_INIT_NOTIFIER, &tz_boost_init_notifier);
|
|
if (rc) {
|
|
log_error(tzdev_boost, "Failed to register init notifier, error=%d\n", rc);
|
|
return rc;
|
|
}
|
|
log_info(tzdev_boost, "Boost callbacks registration done\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
tzdev_early_initcall(tz_boost_init);
|
|
|
|
void tz_boost_enable(void)
|
|
{
|
|
mutex_lock(&tz_boost_lock);
|
|
|
|
if (!tz_boost_users) {
|
|
tz_hotplug_update_nwd_cpu_mask(cpu_boost_mask);
|
|
pm_qos_add_request(&tz_boost_qos, TZ_BOOST_CPU_FREQ_MIN,
|
|
TZ_BOOST_CPU_FREQ_MAX_DEFAULT_VALUE);
|
|
}
|
|
|
|
tz_boost_users++;
|
|
|
|
mutex_unlock(&tz_boost_lock);
|
|
}
|
|
|
|
void tz_boost_disable(void)
|
|
{
|
|
mutex_lock(&tz_boost_lock);
|
|
|
|
tz_boost_users--;
|
|
BUG_ON(tz_boost_users < 0);
|
|
|
|
if (!tz_boost_users) {
|
|
pm_qos_remove_request(&tz_boost_qos);
|
|
tz_hotplug_update_nwd_cpu_mask(0x0);
|
|
}
|
|
|
|
mutex_unlock(&tz_boost_lock);
|
|
}
|