SmartAudio/package/allwinner/nativepower/libscenemanager/np_scene_utils.c

392 lines
9.8 KiB
C
Executable File

/*
* Copyright (C) 2016 Allwinnertech
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include "np_uci_config.h"
#include "np_scene_utils.h"
#include "SceneConfig.h"
int np_get_property(const char *conf_section, const char *conf_name, char *property, size_t len)
{
NP_UCI *uci = np_uci_open(NATIVE_POWER_CONFIG_PATH);
if (uci == NULL)
return -1;
np_uci_read_config(uci, conf_section, conf_name, property, len);
np_uci_close(uci);
return 0;
}
int np_set_property(const char *conf_section, const char *conf_name, const char *property)
{
NP_UCI *uci = np_uci_open(NATIVE_POWER_CONFIG_PATH);
if (uci == NULL)
return -1;
np_uci_write_config(uci, conf_section, conf_name, property);
np_uci_close(uci);
return 0;
}
int np_get_scene_config(NP_SCENE * scene, const char *scene_name)
{
int ret = 0;
NP_UCI *uci = np_uci_open(NATIVE_POWER_CONFIG_PATH);
if (uci == NULL)
return -1;
ret += np_uci_read_config(uci, scene_name, "bootlock", scene->cpu.bootlock, sizeof(scene->cpu.bootlock));
ret += np_uci_read_config(uci, scene_name, "roomage", scene->cpu.roomage, sizeof(scene->cpu.roomage));
ret += np_uci_read_config(uci, scene_name, "cpu_freq", scene->cpu.cpu_freq, sizeof(scene->cpu.cpu_freq));
ret += np_uci_read_config(uci, scene_name, "cpu_freq_max", scene->cpu.cpu_freq_max, sizeof(scene->cpu.cpu_freq_max));
ret += np_uci_read_config(uci, scene_name, "cpu_freq_min", scene->cpu.cpu_freq_min, sizeof(scene->cpu.cpu_freq_min));
ret += np_uci_read_config(uci, scene_name, "cpu_gov", scene->cpu.cpu_gov, sizeof(scene->cpu.cpu_gov));
ret += np_uci_read_config(uci, scene_name, "cpu_hot", scene->cpu.cpu_hot, sizeof(scene->cpu.cpu_hot));
ret += np_uci_read_config(uci, scene_name, "cpu_online", scene->cpu.cpu_online, sizeof(scene->cpu.cpu_online));
ret += np_uci_read_config(uci, scene_name, "gpu_freq", scene->gpu.gpu_freq, sizeof(scene->gpu.gpu_freq));
ret += np_uci_read_config(uci, scene_name, "dram_adaptive", scene->dram.dram_adaptive, sizeof(scene->dram.dram_adaptive));
ret += np_uci_read_config(uci, scene_name, "dram_freq", scene->dram.dram_freq, sizeof(scene->dram.dram_freq));
ret += np_uci_read_config(uci, scene_name, "dram_freq_max", scene->dram.dram_freq_max, sizeof(scene->dram.dram_freq_max));
ret += np_uci_read_config(uci, scene_name, "dram_freq_min", scene->dram.dram_freq_min, sizeof(scene->dram.dram_freq_min));
TLOGI("get uci config:%s\n", scene_name);
TLOGI("bootlock:%s", scene->cpu.bootlock);
TLOGI("roomage:%s", scene->cpu.roomage);
TLOGI("cpu_freq:%s", scene->cpu.cpu_freq);
TLOGI("cpu_freq_max:%s", scene->cpu.cpu_freq_max);
TLOGI("cpu_freq_min:%s", scene->cpu.cpu_freq_min);
TLOGI("cpu_gov:%s", scene->cpu.cpu_gov);
TLOGI("cpu_hot:%s", scene->cpu.cpu_hot);
TLOGI("cpu_online:%s", scene->cpu.cpu_online);
TLOGI("gpu_freq:%s", scene->gpu.gpu_freq);
TLOGI("dram_adaptive:%s", scene->dram.dram_adaptive);
TLOGI("dram_freq:%s", scene->dram.dram_freq);
TLOGI("dram_freq_max:%s", scene->dram.dram_freq_max);
TLOGI("dram_freq_min:%s", scene->dram.dram_freq_min);
np_uci_close(uci);
return ret;
}
static int getConfig(const char *path, char *value, size_t size)
{
int fd = -1;
fd = open(path, O_RDONLY);
TLOGI("open %s return %d\n", path, fd);
if (fd < 0)
return -1;
read(fd, value, size);
close(fd);
return 0;
}
static int setConfig(const char *path, const char *value)
{
int fd = -1;
TLOGI("path:%s set value:%s", path, value);
fd = open(path, O_WRONLY);
if (fd < 0)
return -1;
write(fd, value, strlen(value));
close(fd);
return 0;
}
static int SetBootLock(const char *bootlock)
{
return setConfig(CPU0LOCK, bootlock);
}
static int SetRoomage(const char *roomage)
{
return setConfig(ROOMAGE, roomage);
}
static const char *GetActualFreq(char *freq, const char *avail_freq_path)
{
int ret = 0;
if (!strcmp(freq, "max"))
ret = 1;
else if (!strcmp(freq, "min"))
ret = 2;
if (ret != 0) {
char value[256];
char *token = NULL;
size_t len;
memset(value, 0, sizeof(value));
if (getConfig(avail_freq_path, value, sizeof(value)) != 0) {
fprintf(stderr, "avail_freq_path:%s unknown\n", avail_freq_path);
return NULL;
}
TLOGI("avail_freq: %s", value);
len = strlen(value);
token = strtok(value, " ");
if (token == NULL)
return NULL;
if (ret == 2)
strcpy(freq, token);
else {
char *token_pre;
do {
TLOGI("freq: %s", token);
token_pre = token;
token = strtok(NULL, " ");
} while (token != NULL && (len - (token - value) > 2));
strcpy(freq, token_pre);
}
}
return freq;
}
static int SetCpuFreq(const char *cpu_freq)
{
char actualfreq[32];
strcpy(actualfreq, cpu_freq);
if(!GetActualFreq(actualfreq, CPUFREQ_AVAIL))
return -1;
setConfig(CPUFREQ_MAX, actualfreq);
setConfig(CPUFREQ_MIN, actualfreq);
return 0;
}
static int SetCpuFreqMax(const char *cpu_freq_max)
{
return setConfig(CPUFREQ_MAX, cpu_freq_max);
}
static int SetCpuFreqMin(const char *cpu_freq_min)
{
return setConfig(CPUFREQ_MIN, cpu_freq_min);
}
static int GetCpuFreq(char *buf, size_t len)
{
return getConfig(CPUFREQ, buf, len);
}
static int GetCpuOnline(char *buf, size_t len)
{
return getConfig(CPUONLINE, buf, len);
}
static int GetCpuGov(char *buf, size_t len)
{
return getConfig(CPU0GOV, buf, len);
}
static int SetCpuGov(const char *cpu_gov)
{
return setConfig(CPU0GOV, cpu_gov);
}
static int SetCpuHot(const char *cpu_hot)
{
return setConfig(CPUHOT, cpu_hot);
}
static int SetCpuOnline(const char *cpu_online)
{
char online[CPU_NUM_MAX];
int num;
if (!strcmp(cpu_online, "all")) {
memset(online, 1, sizeof(online));
} else {
char cpu_online_tmp[sizeof(((CPU_SCENE *) 0)->cpu_online)];
char *token = NULL;
memset(online, 0, sizeof(online));
memcpy(cpu_online_tmp, cpu_online, sizeof(cpu_online_tmp));
token = strtok(cpu_online_tmp, "-,");
while (token != NULL) {
num = atoi(token);
if (num < 0 || num > (CPU_NUM_MAX - 1))
return -1;
online[num] = 1;
if (cpu_online[token - cpu_online_tmp + 1] == '-') {
int start = num;
int end, i;
if (token - cpu_online_tmp + 2 < sizeof(cpu_online_tmp))
end = cpu_online[token - cpu_online_tmp + 2] - '0';
else
return -1;
if (end < start)
return -1;
for (i = start; i <= end; i++)
online[i] = 1;
}
token = strtok(NULL, "-,");
}
}
/* ignore CPU0 */
for (num = 1; num < CPU_NUM_MAX; num++) {
char buf[128];
snprintf(buf, sizeof(buf), "/sys/devices/system/cpu/cpu%d/online", num);
setConfig(buf, online[num] != 0 ? "1" : "0");
}
return 0;
}
static int SetDramFreqAdaptive(const char *pause)
{
return setConfig(DRAMMODE, pause);
}
static int SetDramFreq(const char *dram_freq)
{
char actualfreq[32];
strcpy(actualfreq, dram_freq);
if(!GetActualFreq(actualfreq, DRAMFREQ_AVAIL))
return -1;
if (atoi(actualfreq)/1000000U > 0)
snprintf(actualfreq, sizeof(actualfreq), "%d", atoi(actualfreq) / 1000);
setConfig(DRAMFREQ_MAX, actualfreq);
setConfig(DRAMFREQ_MIN, actualfreq);
return 0;
}
static int SetDramFreqMax(const char *dram_freq_max)
{
return setConfig(DRAMFREQ_MAX, dram_freq_max);
}
static int SetDramFreqMin(const char *dram_freq_min)
{
return setConfig(DRAMFREQ_MIN, dram_freq_min);
}
static int GetDramFreq(char *buf, size_t len)
{
return getConfig(DRAMFREQ, buf, len);
}
static int SetGpuFreq(const char *gpu_freq)
{
return -1;
}
static int GetGpuFreq(char *buf, size_t len)
{
return -1;
}
static CPU_SCENE_OPS cpu_ops = {
.SetBootLock = SetBootLock,
.SetRoomAge = SetRoomage,
.SetCpuFreq = SetCpuFreq,
.SetCpuFreqMax = SetCpuFreqMax,
.SetCpuFreqMin = SetCpuFreqMin,
.SetCpuGov = SetCpuGov,
.SetCpuHot = SetCpuHot,
.SetCpuOnline = SetCpuOnline,
.GetCpuFreq = GetCpuFreq,
.GetCpuGov = GetCpuGov,
.GetCpuOnline = GetCpuOnline,
};
GPU_SCENE_OPS gpu_ops = {
.SetGpuFreq = SetGpuFreq,
.GetGpuFreq = GetGpuFreq,
};
DRAM_SCENE_OPS dram_ops = {
.SetDramFreqAdaptive = SetDramFreqAdaptive,
.SetDramFreq = SetDramFreq,
.SetDramFreqMax = SetDramFreqMax,
.SetDramFreqMin = SetDramFreqMin,
.GetDramFreq = GetDramFreq,
};
void *np_get_ops(int sel)
{
void *ops = NULL;
switch (sel) {
case 0:
ops = &cpu_ops;
break;
case 1:
ops = &dram_ops;
break;
case 2:
ops = &gpu_ops;
break;
}
return ops;
}
int np_set_scene(NP_SCENE * scene)
{
if (strlen(scene->cpu.bootlock) != 0)
cpu_ops.SetBootLock(scene->cpu.bootlock);
if (strlen(scene->cpu.roomage) != 0)
cpu_ops.SetRoomAge(scene->cpu.roomage);
if (strlen(scene->cpu.cpu_freq) != 0)
cpu_ops.SetCpuFreq(scene->cpu.cpu_freq);
if (strlen(scene->cpu.cpu_freq_max) != 0)
cpu_ops.SetCpuFreqMax(scene->cpu.cpu_freq_max);
if (strlen(scene->cpu.cpu_freq_min) != 0)
cpu_ops.SetCpuFreqMin(scene->cpu.cpu_freq_min);
if (strlen(scene->cpu.cpu_gov) != 0)
cpu_ops.SetCpuGov(scene->cpu.cpu_gov);
if (strlen(scene->cpu.cpu_hot) != 0)
cpu_ops.SetCpuHot(scene->cpu.cpu_hot);
if (strlen(scene->cpu.cpu_online) != 0)
cpu_ops.SetCpuOnline(scene->cpu.cpu_online);
if (strlen(scene->gpu.gpu_freq) != 0)
gpu_ops.SetGpuFreq(scene->gpu.gpu_freq);
if (strlen(scene->dram.dram_adaptive) != 0)
dram_ops.SetDramFreqAdaptive(scene->dram.dram_adaptive);
if (strlen(scene->dram.dram_freq) != 0)
dram_ops.SetDramFreq(scene->dram.dram_freq);
if (strlen(scene->dram.dram_freq_max) != 0)
dram_ops.SetDramFreqMax(scene->dram.dram_freq_max);
if (strlen(scene->dram.dram_freq_min) != 0)
dram_ops.SetDramFreqMin(scene->dram.dram_freq_min);
return 0;
}