281 lines
7 KiB
C++
Executable file
281 lines
7 KiB
C++
Executable file
/*
|
|
* Copyright (C) Allwinner Tech All Rights Reserved
|
|
*
|
|
* 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 "../hwc.h"
|
|
|
|
|
|
/* this is for A64 P3 ,
|
|
* and ddr ram controler do not give us way to control it ,
|
|
* so we will use experience
|
|
*/
|
|
struct mem_speed_limit_t{
|
|
int ddrKHz;
|
|
int demem;
|
|
};
|
|
|
|
typedef struct memCtrlInfo{
|
|
int globlimit;// will varible for dvfs ddr
|
|
int globcurlimit;
|
|
int globcurrent;
|
|
int globReseveMem;
|
|
int dealReseveMem;
|
|
int cnt;
|
|
int numdisp;
|
|
Display_t **display;
|
|
int maxClientTarget;
|
|
}memCtrlInfo_t;
|
|
|
|
memCtrlInfo_t globCtrl;
|
|
|
|
static struct mem_speed_limit_t mem_speed_limit[3] =
|
|
{
|
|
#if (TARGET_BOARD_PLATFORM == tulip || TARGET_BOARD_PLATFORM == venus)
|
|
|
|
{672000, 37324800},
|
|
{552000, 29030400},
|
|
{432000, 20736000},
|
|
#elif (TARGET_BOARD_PLATFORM == uranus)
|
|
|
|
{672000, 49152000},
|
|
{552000, 49152000},
|
|
{432000, 30736000},
|
|
#elif (TARGET_BOARD_PLATFORM == t8)
|
|
{672000, 49152000},
|
|
{552000, 49152000},
|
|
{432000, 30736000},
|
|
#elif (TARGET_BOARD_PLATFORM == petrel)
|
|
{672000, 49152000},
|
|
{552000, 49152000},
|
|
{432000, 30736000},
|
|
#else
|
|
#error "please select a platform\n"
|
|
#endif
|
|
};
|
|
|
|
void memCtrlUpdateMaxFb(void)
|
|
{
|
|
int i;
|
|
DisplayConfig_t *config;
|
|
Display_t *display;
|
|
Layer_t *layer;
|
|
int max = 0;
|
|
|
|
for(i = 0; i < globCtrl.numdisp; i++) {
|
|
display = globCtrl.display[i];
|
|
if (!display->plugIn) {
|
|
max = 0;
|
|
continue;
|
|
}
|
|
config = display->displayConfigList[display->activeConfigId];
|
|
if( max < config->height * config->width * 4)
|
|
max = config->height * config->width * 4;
|
|
}
|
|
if (globCtrl.maxClientTarget != 0)
|
|
globCtrl.globReseveMem -= globCtrl.maxClientTarget;
|
|
globCtrl.maxClientTarget = max;
|
|
globCtrl.globReseveMem += max;
|
|
}
|
|
|
|
void memCtrlCheckResv(Layer_t *layer, bool add)
|
|
{
|
|
int memcurrntresv;
|
|
private_handle_t *handle;
|
|
handle = (private_handle_t *)layer->buffer;
|
|
|
|
if(handle == NULL)
|
|
return;
|
|
if (!layerIsVideo(layer)) {
|
|
layer->memresrve = 0;
|
|
return;
|
|
}
|
|
if(layer->memresrve == add)
|
|
return;
|
|
memcurrntresv = (int)ceilf((layer->crop.right - layer->crop.left)
|
|
* (layer->crop.bottom - layer->crop.top)
|
|
* getBitsPerPixel(layer) / 8);
|
|
if (layer->transform)
|
|
memcurrntresv *= 3;
|
|
if (add)
|
|
globCtrl.globReseveMem += memcurrntresv;
|
|
else
|
|
globCtrl.globReseveMem -= memcurrntresv;
|
|
ALOGV("memCtrlCheckResv layer:%d %s", memcurrntresv, add?"add":"sub");
|
|
|
|
layer->memresrve = add;
|
|
}
|
|
|
|
void memCtrlDealFBLayer(Layer_t *layer, bool add)
|
|
{
|
|
int mem = (int)ceilf((layer->crop.right - layer->crop.left)
|
|
* (layer->crop.bottom - layer->crop.top)
|
|
* getBitsPerPixel(layer) / 8);
|
|
if (add)
|
|
globCtrl.globReseveMem += mem;
|
|
else
|
|
globCtrl.globReseveMem -= mem;
|
|
ALOGV("deal fb:%d %s",mem, add?"add":"sub");
|
|
}
|
|
|
|
void memCtrlDealLayer(Layer_t *layer, bool add)
|
|
{
|
|
int mem = (int)ceilf((layer->crop.right - layer->crop.left)
|
|
* (layer->crop.bottom - layer->crop.top)
|
|
* getBitsPerPixel(layer) / 8);
|
|
if(!layer->memresrve)
|
|
return;
|
|
if (layer->transform)
|
|
mem *= 3;
|
|
if (add)
|
|
globCtrl.dealReseveMem += mem;
|
|
else
|
|
globCtrl.dealReseveMem -= mem;
|
|
|
|
}
|
|
|
|
void memCtrlDelCur(int mem)
|
|
{
|
|
globCtrl.globcurrent -= mem;
|
|
}
|
|
|
|
bool memCtrlAddLayer(Display_t *display, Layer_t *layer, int* pAddmem)
|
|
{
|
|
DisplayOpr_t *opt;
|
|
int addmem = 0, add = 0, srcmem = 0;
|
|
opt = display->displayOpration;
|
|
if (checkSoildLayer(layer)) {
|
|
*pAddmem = 0;
|
|
return true;
|
|
}
|
|
srcmem = (int)ceilf((layer->crop.right - layer->crop.left)
|
|
* (layer->crop.bottom - layer->crop.top)
|
|
* getBitsPerPixel(layer) / 8);
|
|
|
|
addmem = opt->memCtrlAddLayer(display, layer);
|
|
add = addmem;
|
|
if (layer->memresrve) {
|
|
add = addmem - srcmem;
|
|
if (add > 0)
|
|
ALOGE("Cal the mem err %d", add);
|
|
}
|
|
if(layer->compositionType == HWC2_COMPOSITION_CLIENT_TARGET)
|
|
memCtrlDealFBLayer(layer, false);
|
|
if (add + globCtrl.globReseveMem - globCtrl.dealReseveMem + globCtrl.globcurrent > globCtrl.globcurlimit){
|
|
ALOGV("memctrl layer:%p: %d %d %d %d %d %d",layer, add, globCtrl.globlimit,
|
|
globCtrl.globcurlimit, globCtrl.globcurrent, globCtrl.globReseveMem, globCtrl.dealReseveMem);
|
|
return false;
|
|
}
|
|
globCtrl.globcurrent += addmem;
|
|
|
|
*pAddmem = addmem;
|
|
return true;
|
|
}
|
|
|
|
void memContrlComplet(Display_t *display)
|
|
{
|
|
int max = 0;
|
|
unusedpara(display);
|
|
for (int i = 0; i < globCtrl.numdisp; i++){
|
|
max += globCtrl.display[i]->active;
|
|
}
|
|
if (globCtrl.cnt < max)
|
|
return;
|
|
globCtrl.cnt = 0;
|
|
}
|
|
|
|
void memResetPerframe(Display_t *display)
|
|
{
|
|
unusedpara(display);
|
|
|
|
if (globCtrl.cnt == 0) {
|
|
globCtrl.globcurrent = 0;
|
|
globCtrl.dealReseveMem = 0;
|
|
}
|
|
globCtrl.cnt++;
|
|
|
|
}
|
|
|
|
void memCtrlLimmitSet(Display_t *display, int screen)
|
|
{
|
|
DisplayConfig_t *config;
|
|
Display_t *displaytmp;
|
|
|
|
if (display->forceClient) {
|
|
for(int i = 0; i < globCtrl.numdisp; i++) {
|
|
displaytmp = globCtrl.display[i];
|
|
if (!displaytmp->plugIn)
|
|
continue;
|
|
config = displaytmp->displayConfigList[displaytmp->activeConfigId];
|
|
if (i == 0)
|
|
globCtrl.globcurlimit = config->height * config->width * 4;
|
|
else
|
|
globCtrl.globcurlimit += config->height * config->width * 4;
|
|
}
|
|
}else{
|
|
globCtrl.globcurlimit += screen;
|
|
if (globCtrl.globcurlimit > globCtrl.globlimit)
|
|
globCtrl.globcurlimit = globCtrl.globlimit;
|
|
}
|
|
}
|
|
|
|
int memCtrlDump(char* outBuffer)
|
|
{
|
|
return sprintf(outBuffer, "GL:%d GCL:%d GC:%d GR:%d DR:%d\n", globCtrl.globlimit,
|
|
globCtrl.globcurlimit, globCtrl.globcurrent, globCtrl.globReseveMem, globCtrl.dealReseveMem);
|
|
|
|
}
|
|
void memCtrlInit(Display_t **display, int num)
|
|
{
|
|
int ddrFreFd;
|
|
globCtrl.globcurrent = 0;
|
|
globCtrl.globReseveMem = 0;
|
|
globCtrl.numdisp = num;
|
|
globCtrl.display = display;
|
|
|
|
ddrFreFd = open("/sys/class/devfreq/dramfreq/max_freq", O_RDONLY);
|
|
if(ddrFreFd >= 0)
|
|
{
|
|
char val_ddr[10] = {0x0,};
|
|
int ret = -1, i = 0, speed = 0;
|
|
ret = read(ddrFreFd, &val_ddr, 6);
|
|
ALOGD("the ddr speed is %s",val_ddr);
|
|
close(ddrFreFd);
|
|
while(ret--) {
|
|
speed *= 10;
|
|
if ( val_ddr[i] >= '0' && val_ddr[i] <= '9') {
|
|
speed += val_ddr[i++] - 48;
|
|
} else {
|
|
speed = 552000;//defalt ddr max speed
|
|
break;
|
|
}
|
|
}
|
|
i = 0;
|
|
ret = sizeof(mem_speed_limit)/sizeof(mem_speed_limit_t);
|
|
for (i =0; i< ret; i++) {
|
|
if (mem_speed_limit[i].ddrKHz <= speed) {
|
|
break;
|
|
}
|
|
}
|
|
if (i == ret) {
|
|
i--;
|
|
}
|
|
globCtrl.globlimit = mem_speed_limit[i].demem;
|
|
} else {
|
|
ALOGD("open /sys/class/devfreq/dramfreq/max_freq err.");
|
|
globCtrl.globlimit = mem_speed_limit[1].demem;
|
|
}
|
|
globCtrl.globcurlimit = globCtrl.globlimit;
|
|
}
|
|
|