717 lines
15 KiB
C
717 lines
15 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (c) 2019 MediaTek Inc.
|
|
*/
|
|
#include <linux/workqueue.h>
|
|
#include <linux/unistd.h>
|
|
#include <linux/module.h>
|
|
#include <linux/sched.h>
|
|
#include <linux/cpufreq.h>
|
|
#include <linux/topology.h>
|
|
|
|
#include "mt-plat/fpsgo_common.h"
|
|
#include "fpsgo_base.h"
|
|
#include "fpsgo_sysfs.h"
|
|
#include "fpsgo_usedext.h"
|
|
#include "fbt_cpu.h"
|
|
#include "fstb.h"
|
|
#include "fps_composer.h"
|
|
#include "xgf.h"
|
|
|
|
#ifdef CONFIG_DRM_MEDIATEK
|
|
#include "mtk_drm_arr.h"
|
|
#endif
|
|
|
|
#define CREATE_TRACE_POINTS
|
|
#include <trace/events/fpsgo.h>
|
|
|
|
#define API_READY 0
|
|
|
|
#define TARGET_UNLIMITED_FPS 240
|
|
|
|
enum FPSGO_NOTIFIER_PUSH_TYPE {
|
|
FPSGO_NOTIFIER_SWITCH_FPSGO = 0x00,
|
|
FPSGO_NOTIFIER_QUEUE_DEQUEUE = 0x01,
|
|
FPSGO_NOTIFIER_CONNECT = 0x02,
|
|
FPSGO_NOTIFIER_DFRC_FPS = 0x03,
|
|
FPSGO_NOTIFIER_BQID = 0x04,
|
|
FPSGO_NOTIFIER_NN_JOB_BEGIN = 0x05,
|
|
FPSGO_NOTIFIER_NN_JOB_END = 0x06,
|
|
FPSGO_NOTIFIER_GPU_BLOCK = 0x07,
|
|
FPSGO_NOTIFIER_VSYNC = 0x08,
|
|
};
|
|
|
|
/* TODO: use union*/
|
|
struct FPSGO_NOTIFIER_PUSH_TAG {
|
|
enum FPSGO_NOTIFIER_PUSH_TYPE ePushType;
|
|
|
|
int pid;
|
|
unsigned long long cur_ts;
|
|
|
|
int enable;
|
|
|
|
int qudeq_cmd;
|
|
unsigned int queue_arg;
|
|
|
|
unsigned long long bufID;
|
|
int connectedAPI;
|
|
int queue_SF;
|
|
unsigned long long identifier;
|
|
int create;
|
|
|
|
int dfrc_fps;
|
|
|
|
int num_step;
|
|
__s32 *device;
|
|
__s32 *boost;
|
|
__u64 *exec_time;
|
|
|
|
|
|
int tid;
|
|
int start;
|
|
|
|
struct work_struct sWork;
|
|
};
|
|
|
|
static struct mutex notify_lock;
|
|
struct workqueue_struct *g_psNotifyWorkQueue;
|
|
static int fpsgo_enable;
|
|
static int fpsgo_force_onoff;
|
|
static int gpu_boost_enable_perf;
|
|
static int gpu_boost_enable_camera;
|
|
|
|
void (*rsu_cpufreq_notifier_fp)(int cluster_id, unsigned long freq);
|
|
|
|
/* TODO: event register & dispatch */
|
|
int fpsgo_is_enable(void)
|
|
{
|
|
int enable;
|
|
|
|
mutex_lock(¬ify_lock);
|
|
enable = fpsgo_enable;
|
|
mutex_unlock(¬ify_lock);
|
|
|
|
FPSGO_LOGI("[FPSGO_CTRL] isenable %d\n", enable);
|
|
return enable;
|
|
}
|
|
|
|
static void fpsgo_notifier_wq_cb_vsync(unsigned long long ts)
|
|
{
|
|
FPSGO_LOGI("[FPSGO_CB] vsync: %llu\n", ts);
|
|
|
|
if (!fpsgo_is_enable())
|
|
return;
|
|
|
|
fpsgo_ctrl2fbt_vsync(ts);
|
|
}
|
|
|
|
static void fpsgo_notifier_wq_cb_dfrc_fps(int dfrc_fps)
|
|
{
|
|
FPSGO_LOGI("[FPSGO_CB] dfrc_fps %d\n", dfrc_fps);
|
|
|
|
fpsgo_ctrl2fstb_dfrc_fps(dfrc_fps);
|
|
fpsgo_ctrl2fbt_dfrc_fps(dfrc_fps);
|
|
}
|
|
|
|
static void fpsgo_notifier_wq_cb_connect(int pid,
|
|
int connectedAPI, unsigned long long id)
|
|
{
|
|
FPSGO_LOGI(
|
|
"[FPSGO_CB] connect: pid %d, API %d, id %llu\n",
|
|
pid, connectedAPI, id);
|
|
|
|
if (connectedAPI == WINDOW_DISCONNECT)
|
|
fpsgo_ctrl2comp_disconnect_api(pid, connectedAPI, id);
|
|
else
|
|
fpsgo_ctrl2comp_connect_api(pid, connectedAPI, id);
|
|
}
|
|
|
|
static void fpsgo_notifier_wq_cb_bqid(int pid, unsigned long long bufID,
|
|
int queue_SF, unsigned long long id, int create)
|
|
{
|
|
FPSGO_LOGI(
|
|
"[FPSGO_CB] bqid: pid %d, bufID %llu, queue_SF %d, id %llu, create %d\n",
|
|
pid, bufID, queue_SF, id, create);
|
|
|
|
fpsgo_ctrl2comp_bqid(pid, bufID, queue_SF, id, create);
|
|
}
|
|
|
|
static void fpsgo_notifier_wq_cb_gblock(int tid, int start)
|
|
{
|
|
FPSGO_LOGI(
|
|
"[FPSGO_CB] gblock: tid %d, start %d\n",
|
|
tid, start);
|
|
|
|
if (!fpsgo_is_enable())
|
|
return;
|
|
|
|
fpsgo_ctrl2fstb_gblock(tid, start);
|
|
}
|
|
|
|
static void fpsgo_notifier_wq_cb_qudeq(int qudeq,
|
|
unsigned int startend, int cur_pid,
|
|
unsigned long long curr_ts, unsigned long long id)
|
|
{
|
|
FPSGO_LOGI("[FPSGO_CB] qudeq: %d-%d, pid %d, ts %llu, id %llu\n",
|
|
qudeq, startend, cur_pid, curr_ts, id);
|
|
|
|
if (!fpsgo_is_enable())
|
|
return;
|
|
|
|
switch (qudeq) {
|
|
case 1:
|
|
if (startend) {
|
|
FPSGO_LOGI("[FPSGO_CB] QUEUE Start: pid %d\n",
|
|
cur_pid);
|
|
fpsgo_ctrl2comp_enqueue_start(cur_pid,
|
|
curr_ts, id);
|
|
} else {
|
|
FPSGO_LOGI("[FPSGO_CB] QUEUE End: pid %d\n",
|
|
cur_pid);
|
|
fpsgo_ctrl2comp_enqueue_end(cur_pid, curr_ts,
|
|
id);
|
|
}
|
|
break;
|
|
case 0:
|
|
if (startend) {
|
|
FPSGO_LOGI("[FPSGO_CB] DEQUEUE Start: pid %d\n",
|
|
cur_pid);
|
|
fpsgo_ctrl2comp_dequeue_start(cur_pid,
|
|
curr_ts, id);
|
|
} else {
|
|
FPSGO_LOGI("[FPSGO_CB] DEQUEUE End: pid %d\n",
|
|
cur_pid);
|
|
fpsgo_ctrl2comp_dequeue_end(cur_pid,
|
|
curr_ts, id);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void fpsgo_notifier_wq_cb_enable(int enable)
|
|
{
|
|
FPSGO_LOGI(
|
|
"[FPSGO_CB] enable %d, fpsgo_enable %d, force_onoff %d\n",
|
|
enable, fpsgo_enable, fpsgo_force_onoff);
|
|
|
|
mutex_lock(¬ify_lock);
|
|
if (enable == fpsgo_enable) {
|
|
mutex_unlock(¬ify_lock);
|
|
return;
|
|
}
|
|
|
|
if (fpsgo_force_onoff != FPSGO_FREE &&
|
|
enable != fpsgo_force_onoff) {
|
|
mutex_unlock(¬ify_lock);
|
|
return;
|
|
}
|
|
|
|
fpsgo_ctrl2fbt_switch_fbt(enable);
|
|
fpsgo_ctrl2fstb_switch_fstb(enable);
|
|
fpsgo_ctrl2xgf_switch_xgf(enable);
|
|
|
|
fpsgo_enable = enable;
|
|
|
|
if (!fpsgo_enable)
|
|
fpsgo_clear();
|
|
|
|
FPSGO_LOGI("[FPSGO_CB] fpsgo_enable %d\n",
|
|
fpsgo_enable);
|
|
mutex_unlock(¬ify_lock);
|
|
}
|
|
|
|
static void fpsgo_notifier_wq_cb(struct work_struct *psWork)
|
|
{
|
|
struct FPSGO_NOTIFIER_PUSH_TAG *vpPush =
|
|
FPSGO_CONTAINER_OF(psWork,
|
|
struct FPSGO_NOTIFIER_PUSH_TAG, sWork);
|
|
|
|
if (!vpPush) {
|
|
FPSGO_LOGE("[FPSGO_CTRL] ERROR\n");
|
|
return;
|
|
}
|
|
|
|
FPSGO_LOGI("[FPSGO_CTRL] push type = %d\n",
|
|
vpPush->ePushType);
|
|
|
|
switch (vpPush->ePushType) {
|
|
case FPSGO_NOTIFIER_SWITCH_FPSGO:
|
|
fpsgo_notifier_wq_cb_enable(vpPush->enable);
|
|
break;
|
|
case FPSGO_NOTIFIER_QUEUE_DEQUEUE:
|
|
fpsgo_notifier_wq_cb_qudeq(vpPush->qudeq_cmd,
|
|
vpPush->queue_arg, vpPush->pid,
|
|
vpPush->cur_ts, vpPush->identifier);
|
|
break;
|
|
case FPSGO_NOTIFIER_CONNECT:
|
|
fpsgo_notifier_wq_cb_connect(vpPush->pid,
|
|
vpPush->connectedAPI, vpPush->identifier);
|
|
break;
|
|
case FPSGO_NOTIFIER_DFRC_FPS:
|
|
fpsgo_notifier_wq_cb_dfrc_fps(vpPush->dfrc_fps);
|
|
break;
|
|
case FPSGO_NOTIFIER_BQID:
|
|
fpsgo_notifier_wq_cb_bqid(vpPush->pid, vpPush->bufID,
|
|
vpPush->queue_SF, vpPush->identifier, vpPush->create);
|
|
break;
|
|
case FPSGO_NOTIFIER_GPU_BLOCK:
|
|
fpsgo_notifier_wq_cb_gblock(vpPush->tid, vpPush->start);
|
|
break;
|
|
case FPSGO_NOTIFIER_VSYNC:
|
|
fpsgo_notifier_wq_cb_vsync(vpPush->cur_ts);
|
|
break;
|
|
default:
|
|
FPSGO_LOGE("[FPSGO_CTRL] unhandled push type = %d\n",
|
|
vpPush->ePushType);
|
|
break;
|
|
}
|
|
|
|
fpsgo_free(vpPush, sizeof(struct FPSGO_NOTIFIER_PUSH_TAG));
|
|
}
|
|
|
|
void fpsgo_notify_qudeq(int qudeq,
|
|
unsigned int startend,
|
|
int pid, unsigned long long id)
|
|
{
|
|
unsigned long long cur_ts;
|
|
struct FPSGO_NOTIFIER_PUSH_TAG *vpPush;
|
|
|
|
FPSGO_LOGI("[FPSGO_CTRL] qudeq %d-%d, id %llu pid %d\n",
|
|
qudeq, startend, id, pid);
|
|
|
|
if (!fpsgo_is_enable())
|
|
return;
|
|
|
|
vpPush =
|
|
(struct FPSGO_NOTIFIER_PUSH_TAG *)
|
|
fpsgo_alloc_atomic(sizeof(struct FPSGO_NOTIFIER_PUSH_TAG));
|
|
if (!vpPush) {
|
|
FPSGO_LOGE("[FPSGO_CTRL] OOM\n");
|
|
return;
|
|
}
|
|
|
|
if (!g_psNotifyWorkQueue) {
|
|
FPSGO_LOGE("[FPSGO_CTRL] NULL WorkQueue\n");
|
|
fpsgo_free(vpPush, sizeof(struct FPSGO_NOTIFIER_PUSH_TAG));
|
|
return;
|
|
}
|
|
|
|
cur_ts = fpsgo_get_time();
|
|
|
|
vpPush->ePushType = FPSGO_NOTIFIER_QUEUE_DEQUEUE;
|
|
vpPush->pid = pid;
|
|
vpPush->cur_ts = cur_ts;
|
|
vpPush->qudeq_cmd = qudeq;
|
|
vpPush->queue_arg = startend;
|
|
vpPush->identifier = id;
|
|
|
|
INIT_WORK(&vpPush->sWork, fpsgo_notifier_wq_cb);
|
|
queue_work(g_psNotifyWorkQueue, &vpPush->sWork);
|
|
}
|
|
void fpsgo_notify_connect(int pid,
|
|
int connectedAPI, unsigned long long id)
|
|
{
|
|
struct FPSGO_NOTIFIER_PUSH_TAG *vpPush;
|
|
|
|
FPSGO_LOGI(
|
|
"[FPSGO_CTRL] connect pid %d, id %llu, API %d\n",
|
|
pid, id, connectedAPI);
|
|
|
|
vpPush =
|
|
(struct FPSGO_NOTIFIER_PUSH_TAG *)
|
|
fpsgo_alloc_atomic(sizeof(struct FPSGO_NOTIFIER_PUSH_TAG));
|
|
|
|
if (!vpPush) {
|
|
FPSGO_LOGE("[FPSGO_CTRL] OOM\n");
|
|
return;
|
|
}
|
|
|
|
if (!g_psNotifyWorkQueue) {
|
|
FPSGO_LOGE("[FPSGO_CTRL] NULL WorkQueue\n");
|
|
fpsgo_free(vpPush, sizeof(struct FPSGO_NOTIFIER_PUSH_TAG));
|
|
return;
|
|
}
|
|
|
|
vpPush->ePushType = FPSGO_NOTIFIER_CONNECT;
|
|
vpPush->pid = pid;
|
|
vpPush->connectedAPI = connectedAPI;
|
|
vpPush->identifier = id;
|
|
|
|
INIT_WORK(&vpPush->sWork, fpsgo_notifier_wq_cb);
|
|
queue_work(g_psNotifyWorkQueue, &vpPush->sWork);
|
|
}
|
|
|
|
void fpsgo_notify_bqid(int pid, unsigned long long bufID,
|
|
int queue_SF, unsigned long long id, int create)
|
|
{
|
|
struct FPSGO_NOTIFIER_PUSH_TAG *vpPush;
|
|
|
|
FPSGO_LOGI("[FPSGO_CTRL] bqid pid %d, buf %llu, queue_SF %d, id %llu\n",
|
|
pid, bufID, queue_SF, id);
|
|
|
|
vpPush = (struct FPSGO_NOTIFIER_PUSH_TAG *)
|
|
fpsgo_alloc_atomic(sizeof(struct FPSGO_NOTIFIER_PUSH_TAG));
|
|
|
|
if (!vpPush) {
|
|
FPSGO_LOGE("[FPSGO_CTRL] OOM\n");
|
|
return;
|
|
}
|
|
|
|
if (!g_psNotifyWorkQueue) {
|
|
FPSGO_LOGE("[FPSGO_CTRL] NULL WorkQueue\n");
|
|
fpsgo_free(vpPush, sizeof(struct FPSGO_NOTIFIER_PUSH_TAG));
|
|
return;
|
|
}
|
|
|
|
vpPush->ePushType = FPSGO_NOTIFIER_BQID;
|
|
vpPush->pid = pid;
|
|
vpPush->bufID = bufID;
|
|
vpPush->queue_SF = queue_SF;
|
|
vpPush->identifier = id;
|
|
vpPush->create = create;
|
|
|
|
INIT_WORK(&vpPush->sWork, fpsgo_notifier_wq_cb);
|
|
queue_work(g_psNotifyWorkQueue, &vpPush->sWork);
|
|
}
|
|
|
|
int fpsgo_is_gpu_block_boost_enable(void)
|
|
{
|
|
int enable;
|
|
|
|
mutex_lock(¬ify_lock);
|
|
enable = max(gpu_boost_enable_camera,
|
|
gpu_boost_enable_perf);
|
|
mutex_unlock(¬ify_lock);
|
|
|
|
return enable;
|
|
}
|
|
|
|
int fpsgo_is_gpu_block_boost_perf_enable(void)
|
|
{
|
|
int enable;
|
|
|
|
mutex_lock(¬ify_lock);
|
|
enable = gpu_boost_enable_perf;
|
|
mutex_unlock(¬ify_lock);
|
|
|
|
return enable;
|
|
}
|
|
|
|
int fpsgo_is_gpu_block_boost_camera_enable(void)
|
|
{
|
|
int enable;
|
|
|
|
mutex_lock(¬ify_lock);
|
|
enable = gpu_boost_enable_camera;
|
|
mutex_unlock(¬ify_lock);
|
|
|
|
return enable;
|
|
}
|
|
|
|
void fpsgo_gpu_block_boost_enable_perf(int enable)
|
|
{
|
|
mutex_lock(¬ify_lock);
|
|
gpu_boost_enable_perf = enable;
|
|
mutex_unlock(¬ify_lock);
|
|
}
|
|
|
|
void fpsgo_gpu_block_boost_enable_camera(int enable)
|
|
{
|
|
mutex_lock(¬ify_lock);
|
|
gpu_boost_enable_camera = enable;
|
|
mutex_unlock(¬ify_lock);
|
|
}
|
|
|
|
|
|
int fpsgo_notify_gpu_block(int tid, unsigned long long mid, int start)
|
|
{
|
|
struct FPSGO_NOTIFIER_PUSH_TAG *vpPush;
|
|
int g_enable;
|
|
|
|
FPSGO_LOGI("[FPSGO_CTRL] gblock pid %d, start %d\n",
|
|
tid, start);
|
|
|
|
g_enable = fpsgo_is_gpu_block_boost_enable();
|
|
if (g_enable < 0 || g_enable > 100)
|
|
return -1;
|
|
|
|
vpPush = (struct FPSGO_NOTIFIER_PUSH_TAG *)
|
|
fpsgo_alloc_atomic(sizeof(struct FPSGO_NOTIFIER_PUSH_TAG));
|
|
|
|
if (!vpPush) {
|
|
FPSGO_LOGE("[FPSGO_CTRL] OOM\n");
|
|
return -1;
|
|
}
|
|
|
|
if (!g_psNotifyWorkQueue) {
|
|
FPSGO_LOGE("[FPSGO_CTRL] NULL WorkQueue\n");
|
|
fpsgo_free(vpPush, sizeof(struct FPSGO_NOTIFIER_PUSH_TAG));
|
|
return -1;
|
|
}
|
|
|
|
vpPush->ePushType = FPSGO_NOTIFIER_GPU_BLOCK;
|
|
vpPush->tid = tid;
|
|
vpPush->start = start;
|
|
|
|
INIT_WORK(&vpPush->sWork, fpsgo_notifier_wq_cb);
|
|
queue_work(g_psNotifyWorkQueue, &vpPush->sWork);
|
|
return g_enable;
|
|
}
|
|
|
|
void fpsgo_notify_vsync(void)
|
|
{
|
|
struct FPSGO_NOTIFIER_PUSH_TAG *vpPush;
|
|
|
|
FPSGO_LOGI("[FPSGO_CTRL] vsync\n");
|
|
|
|
if (!fpsgo_is_enable())
|
|
return;
|
|
|
|
vpPush = (struct FPSGO_NOTIFIER_PUSH_TAG *)
|
|
fpsgo_alloc_atomic(sizeof(struct FPSGO_NOTIFIER_PUSH_TAG));
|
|
|
|
if (!vpPush) {
|
|
FPSGO_LOGE("[FPSGO_CTRL] OOM\n");
|
|
return;
|
|
}
|
|
|
|
if (!g_psNotifyWorkQueue) {
|
|
FPSGO_LOGE("[FPSGO_CTRL] NULL WorkQueue\n");
|
|
fpsgo_free(vpPush, sizeof(struct FPSGO_NOTIFIER_PUSH_TAG));
|
|
return;
|
|
}
|
|
|
|
vpPush->ePushType = FPSGO_NOTIFIER_VSYNC;
|
|
vpPush->cur_ts = fpsgo_get_time();
|
|
|
|
INIT_WORK(&vpPush->sWork, fpsgo_notifier_wq_cb);
|
|
queue_work(g_psNotifyWorkQueue, &vpPush->sWork);
|
|
}
|
|
|
|
void fpsgo_get_fps(int *pid, int *fps)
|
|
{
|
|
//int pid = -1, fps = -1;
|
|
|
|
fpsgo_ctrl2fstb_get_fps(pid, fps);
|
|
|
|
FPSGO_LOGE("[FPSGO_CTRL] get_fps %d %d\n", *pid, *fps);
|
|
|
|
//return fps;
|
|
}
|
|
|
|
|
|
void fpsgo_notify_cpufreq(int cid, unsigned long freq)
|
|
{
|
|
FPSGO_LOGI("[FPSGO_CTRL] cid %d, cpufreq %lu\n", cid, freq);
|
|
|
|
if (rsu_cpufreq_notifier_fp)
|
|
rsu_cpufreq_notifier_fp(cid, freq);
|
|
|
|
if (!fpsgo_enable)
|
|
return;
|
|
|
|
fpsgo_ctrl2fbt_cpufreq_cb(cid, freq);
|
|
}
|
|
|
|
void dfrc_fps_limit_cb(unsigned int fps_limit)
|
|
{
|
|
unsigned int vTmp = TARGET_UNLIMITED_FPS;
|
|
struct FPSGO_NOTIFIER_PUSH_TAG *vpPush;
|
|
|
|
if (!fpsgo_is_enable())
|
|
return;
|
|
|
|
if (fps_limit > 0 && fps_limit <= TARGET_UNLIMITED_FPS)
|
|
vTmp = fps_limit;
|
|
|
|
FPSGO_LOGI("[FPSGO_CTRL] dfrc_fps %d\n", vTmp);
|
|
|
|
vpPush =
|
|
(struct FPSGO_NOTIFIER_PUSH_TAG *)
|
|
fpsgo_alloc_atomic(sizeof(struct FPSGO_NOTIFIER_PUSH_TAG));
|
|
|
|
if (!vpPush) {
|
|
FPSGO_LOGE("[FPSGO_CTRL] OOM\n");
|
|
return;
|
|
}
|
|
|
|
if (!g_psNotifyWorkQueue) {
|
|
FPSGO_LOGE("[FPSGO_CTRL] NULL WorkQueue\n");
|
|
fpsgo_free(vpPush, sizeof(struct FPSGO_NOTIFIER_PUSH_TAG));
|
|
return;
|
|
}
|
|
|
|
vpPush->ePushType = FPSGO_NOTIFIER_DFRC_FPS;
|
|
vpPush->dfrc_fps = vTmp;
|
|
|
|
INIT_WORK(&vpPush->sWork, fpsgo_notifier_wq_cb);
|
|
queue_work(g_psNotifyWorkQueue, &vpPush->sWork);
|
|
}
|
|
|
|
/* FPSGO control */
|
|
void fpsgo_switch_enable(int enable)
|
|
{
|
|
struct FPSGO_NOTIFIER_PUSH_TAG *vpPush = NULL;
|
|
|
|
if (!g_psNotifyWorkQueue) {
|
|
FPSGO_LOGE("[FPSGO_CTRL] NULL WorkQueue\n");
|
|
return;
|
|
}
|
|
|
|
FPSGO_LOGI("[FPSGO_CTRL] switch enable %d\n", enable);
|
|
|
|
if (fpsgo_is_force_enable() !=
|
|
FPSGO_FREE && enable !=
|
|
fpsgo_is_force_enable())
|
|
return;
|
|
|
|
vpPush =
|
|
(struct FPSGO_NOTIFIER_PUSH_TAG *)
|
|
fpsgo_alloc_atomic(sizeof(struct FPSGO_NOTIFIER_PUSH_TAG));
|
|
|
|
if (!vpPush) {
|
|
FPSGO_LOGE("[FPSGO_CTRL] OOM\n");
|
|
return;
|
|
}
|
|
|
|
vpPush->ePushType = FPSGO_NOTIFIER_SWITCH_FPSGO;
|
|
vpPush->enable = enable;
|
|
|
|
INIT_WORK(&vpPush->sWork, fpsgo_notifier_wq_cb);
|
|
queue_work(g_psNotifyWorkQueue, &vpPush->sWork);
|
|
}
|
|
|
|
int fpsgo_is_force_enable(void)
|
|
{
|
|
int temp_onoff;
|
|
|
|
mutex_lock(¬ify_lock);
|
|
temp_onoff = fpsgo_force_onoff;
|
|
mutex_unlock(¬ify_lock);
|
|
|
|
return temp_onoff;
|
|
}
|
|
|
|
void fpsgo_force_switch_enable(int enable)
|
|
{
|
|
mutex_lock(¬ify_lock);
|
|
fpsgo_force_onoff = enable;
|
|
mutex_unlock(¬ify_lock);
|
|
|
|
fpsgo_switch_enable(enable?1:0);
|
|
}
|
|
|
|
/* FSTB control */
|
|
int fpsgo_is_fstb_enable(void)
|
|
{
|
|
return is_fstb_enable();
|
|
}
|
|
|
|
int fpsgo_switch_fstb(int enable)
|
|
{
|
|
return fpsgo_ctrl2fstb_switch_fstb(enable);
|
|
}
|
|
|
|
int fpsgo_fstb_sample_window(long long time_usec)
|
|
{
|
|
return switch_sample_window(time_usec);
|
|
}
|
|
|
|
int fpsgo_fstb_fps_range(int nr_level,
|
|
struct fps_level *level)
|
|
{
|
|
return switch_fps_range(nr_level, level);
|
|
}
|
|
|
|
int fpsgo_fstb_process_fps_range(char *proc_name,
|
|
int nr_level, struct fps_level *level)
|
|
{
|
|
return switch_process_fps_range(proc_name, nr_level, level);
|
|
}
|
|
|
|
int fpsgo_fstb_thread_fps_range(pid_t pid,
|
|
int nr_level, struct fps_level *level)
|
|
{
|
|
return switch_thread_fps_range(pid, nr_level, level);
|
|
}
|
|
|
|
int fpsgo_fstb_fps_error_threhosld(int threshold)
|
|
{
|
|
return switch_fps_error_threhosld(threshold);
|
|
}
|
|
|
|
int fpsgo_fstb_percentile_frametime(int ratio)
|
|
{
|
|
return switch_percentile_frametime(ratio);
|
|
}
|
|
|
|
static void __exit fpsgo_exit(void)
|
|
{
|
|
fpsgo_notifier_wq_cb_enable(0);
|
|
|
|
if (g_psNotifyWorkQueue) {
|
|
flush_workqueue(g_psNotifyWorkQueue);
|
|
destroy_workqueue(g_psNotifyWorkQueue);
|
|
g_psNotifyWorkQueue = NULL;
|
|
}
|
|
#if API_READY
|
|
disp_unregister_fps_chg_callback(dfrc_fps_limit_cb);
|
|
#endif
|
|
fbt_cpu_exit();
|
|
mtk_fstb_exit();
|
|
fpsgo_composer_exit();
|
|
fpsgo_sysfs_exit();
|
|
}
|
|
|
|
static int __init fpsgo_init(void)
|
|
{
|
|
FPSGO_LOGI("[FPSGO_CTRL] init\n");
|
|
fpsgo_sysfs_init();
|
|
|
|
g_psNotifyWorkQueue =
|
|
create_singlethread_workqueue("fpsgo_notifier_wq");
|
|
|
|
if (g_psNotifyWorkQueue == NULL)
|
|
return -EFAULT;
|
|
|
|
mutex_init(¬ify_lock);
|
|
|
|
fpsgo_force_onoff = FPSGO_FREE;
|
|
gpu_boost_enable_perf = gpu_boost_enable_camera = -1;
|
|
|
|
init_fpsgo_common();
|
|
fbt_cpu_init();
|
|
mtk_fstb_init();
|
|
fpsgo_composer_init();
|
|
|
|
fpsgo_switch_enable(1);
|
|
|
|
cpufreq_notifier_fp = fpsgo_notify_cpufreq;
|
|
|
|
fpsgo_notify_vsync_fp = fpsgo_notify_vsync;
|
|
fpsgo_get_fps_fp = fpsgo_get_fps;
|
|
|
|
fpsgo_notify_qudeq_fp = fpsgo_notify_qudeq;
|
|
fpsgo_notify_connect_fp = fpsgo_notify_connect;
|
|
fpsgo_notify_bqid_fp = fpsgo_notify_bqid;
|
|
|
|
#ifdef CONFIG_DRM_MEDIATEK
|
|
drm_register_fps_chg_callback(dfrc_fps_limit_cb);
|
|
#else
|
|
#if API_READY
|
|
disp_register_fps_chg_callback(dfrc_fps_limit_cb);
|
|
#endif
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
module_init(fpsgo_init);
|
|
module_exit(fpsgo_exit);
|
|
|
|
MODULE_LICENSE("GPL");
|
|
MODULE_DESCRIPTION("MediaTek FPSGO");
|
|
MODULE_AUTHOR("MediaTek Inc.");
|