hwc: Replace metadata ioctl reading with sysfs node
Metadata ioctl approach has limitations with respect
to adding new capabilities in MDSS driver.
Use sysfs node mechanism to obtain MDSS capabilities.
(sysfs node: /sys/class/graphics/fb0/mdp/caps)
Change-Id: Id7fe683c85b3acf182920d28abf62e9826ff1161
diff --git a/libqdutils/mdp_version.cpp b/libqdutils/mdp_version.cpp
index a444920..259d078 100644
--- a/libqdutils/mdp_version.cpp
+++ b/libqdutils/mdp_version.cpp
@@ -33,66 +33,55 @@
#include <linux/msm_mdp.h>
#include "mdp_version.h"
+#define DEBUG 0
+
ANDROID_SINGLETON_STATIC_INSTANCE(qdutils::MDPVersion);
namespace qdutils {
+#define TOKEN_PARAMS_DELIM "="
+
MDPVersion::MDPVersion()
{
int fb_fd = open("/dev/graphics/fb0", O_RDWR);
- int mdp_version = MDP_V_UNKNOWN;
char panel_type = 0;
struct fb_fix_screeninfo fb_finfo;
+ mMDPVersion = MDP_V_UNKNOWN;
mMdpRev = 0;
mRGBPipes = 0;
mVGPipes = 0;
mDMAPipes = 0;
mFeatures = 0;
+ mMDPUpscale = 0;
//TODO get this from driver, default for A-fam to 8
mMDPDownscale = 8;
mFd = fb_fd;
if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &fb_finfo) < 0) {
ALOGE("FBIOGET_FSCREENINFO failed");
- mdp_version = MDP_V_UNKNOWN;
} else {
if(!strncmp(fb_finfo.id, "msmfb", 5)) {
char str_ver[4] = { 0 };
memcpy(str_ver, &fb_finfo.id[5], 3);
str_ver[3] = '\0';
- mdp_version = atoi(str_ver);
-
+ mMDPVersion = atoi(str_ver);
//Normalize MDP version to ease comparison.
//This is needed only because
//MDP 3.0.3 reports value as 303 which
//is more than all the others
- if (mdp_version < 100)
- mdp_version *= 10;
+ if (mMDPVersion < 100)
+ mMDPVersion *= 10;
mRGBPipes = mVGPipes = 2;
} else if (!strncmp(fb_finfo.id, "mdssfb", 6)) {
- mdp_version = MDSS_V5;
-#ifdef MDSS_TARGET
- struct msmfb_metadata metadata;
- memset(&metadata, 0 , sizeof(metadata));
- metadata.op = metadata_op_get_caps;
- if (ioctl(fb_fd, MSMFB_METADATA_GET, &metadata) == -1) {
- ALOGE("Error retrieving MDP revision and pipes info");
- mdp_version = MDP_V_UNKNOWN;
- } else {
- mMdpRev = metadata.data.caps.mdp_rev;
- mRGBPipes = metadata.data.caps.rgb_pipes;
- mVGPipes = metadata.data.caps.vig_pipes;
- mDMAPipes = metadata.data.caps.dma_pipes;
- mFeatures = metadata.data.caps.features;
- if (metadata.data.caps.mdp_rev == MDP_V3_0_4){
- mdp_version = MDP_V3_0_4;
- }
+ mMDPVersion = MDSS_V5;
+ if(!updateSysFsInfo()) {
+ ALOGE("Unable to read updateSysFsInfo");
}
-#endif
- } else {
- mdp_version = MDP_V_UNKNOWN;
+ if (mMdpRev == MDP_V3_0_4){
+ mMDPVersion = MDP_V3_0_4;
+ }
}
/* Assumes panel type is 2nd element in '_' delimited id string */
@@ -104,16 +93,12 @@
panel_type = *ptype;
}
mPanelType = panel_type;
- mMDPVersion = mdp_version;
mHasOverlay = false;
if((mMDPVersion >= MDP_V4_0) ||
(mMDPVersion == MDP_V_UNKNOWN) ||
(mMDPVersion == MDP_V3_0_4))
mHasOverlay = true;
if(mMDPVersion >= MDSS_V5) {
- //TODO get this from driver
- mMDPDownscale = 4;
-
char split[64] = {0};
FILE* fp = fopen("/sys/class/graphics/fb0/msm_fb_split", "r");
if(fp){
@@ -139,6 +124,95 @@
close(mFd);
}
+int MDPVersion::tokenizeParams(char *inputParams, const char *delim,
+ char* tokenStr[], int *idx) {
+ char *tmp_token = NULL;
+ char *temp_ptr;
+ int ret = 0, index = 0;
+ if (!inputParams) {
+ return -1;
+ }
+ tmp_token = strtok_r(inputParams, delim, &temp_ptr);
+ while (tmp_token != NULL) {
+ tokenStr[index++] = tmp_token;
+ tmp_token = strtok_r(NULL, " ", &temp_ptr);
+ }
+ *idx = index;
+ return 0;
+}
+
+
+// This function reads the sysfs node to read MDP capabilities
+// and parses and updates information accordingly.
+bool MDPVersion::updateSysFsInfo() {
+ FILE *sysfsFd;
+ size_t len = 0;
+ ssize_t read;
+ char *line = NULL;
+ char sysfsPath[255];
+ memset(sysfsPath, 0, sizeof(sysfsPath));
+ snprintf(sysfsPath , sizeof(sysfsPath),
+ "/sys/class/graphics/fb0/mdp/caps");
+
+ sysfsFd = fopen(sysfsPath, "rb");
+
+ if (sysfsFd == NULL) {
+ ALOGE("%s: sysFsFile file '%s' not found",
+ __FUNCTION__, sysfsPath);
+ return false;
+ } else {
+ while((read = getline(&line, &len, sysfsFd)) != -1) {
+ int index=0;
+ char *tokens[10];
+ memset(tokens, 0, sizeof(tokens));
+
+ // parse the line and update information accordingly
+ if(!tokenizeParams(line, TOKEN_PARAMS_DELIM, tokens, &index)) {
+ if(!strncmp(tokens[0], "hw_rev", strlen("hw_rev"))) {
+ mMdpRev = atoi(tokens[1]);
+ }
+ else if(!strncmp(tokens[0], "rgb_pipes", strlen("rgb_pipes"))) {
+ mRGBPipes = atoi(tokens[1]);
+ }
+ else if(!strncmp(tokens[0], "vig_pipes", strlen("vig_pipes"))) {
+ mVGPipes = atoi(tokens[1]);
+ }
+ else if(!strncmp(tokens[0], "dma_pipes", strlen("dma_pipes"))) {
+ mDMAPipes = atoi(tokens[1]);
+ }
+ else if(!strncmp(tokens[0], "max_downscale_ratio",
+ strlen("max_downscale_ratio"))) {
+ mMDPDownscale = atoi(tokens[1]);
+ }
+ else if(!strncmp(tokens[0], "max_upscale_ratio",
+ strlen("max_upscale_ratio"))) {
+ mMDPUpscale = atoi(tokens[1]);
+ }
+ else if(!strncmp(tokens[0], "features", strlen("features"))) {
+ for(int i=1; i<index;i++) {
+ if(!strncmp(tokens[i], "bwc", strlen("bwc"))) {
+ mFeatures |= MDP_BWC_EN;
+ }
+ else if(!strncmp(tokens[i], "decimation",
+ strlen("decimation"))) {
+ mFeatures |= MDP_DECIMATION_EN;
+ }
+ }
+ }
+ }
+ free(line);
+ line = NULL;
+ }
+ fclose(sysfsFd);
+ }
+ ALOGD_IF(DEBUG, "%s: mMDPVersion: %d mMdpRev: %x mRGBPipes:%d,"
+ "mVGPipes:%d", __FUNCTION__, mMDPVersion, mMdpRev,
+ mRGBPipes, mVGPipes);
+ ALOGD_IF(DEBUG, "%s:mDMAPipes:%d \t mMDPDownscale:%d, mFeatures:%d",
+ __FUNCTION__, mDMAPipes, mMDPDownscale, mFeatures);
+ return true;
+}
+
bool MDPVersion::supportsDecimation() {
return mFeatures & MDP_DECIMATION_EN;
}
diff --git a/libqdutils/mdp_version.h b/libqdutils/mdp_version.h
index 8d23b2d..a14592b 100644
--- a/libqdutils/mdp_version.h
+++ b/libqdutils/mdp_version.h
@@ -106,6 +106,9 @@
int getLeftSplit() { return mSplit.left(); }
int getRightSplit() { return mSplit.right(); }
private:
+ bool updateSysFsInfo();
+ int tokenizeParams(char *inputParams, const char *delim,
+ char* tokenStr[], int *idx);
int mFd;
int mMDPVersion;
char mPanelType;
@@ -116,6 +119,7 @@
uint8_t mDMAPipes;
uint32_t mFeatures;
uint32_t mMDPDownscale;
+ uint32_t mMDPUpscale;
Split mSplit;
};
}; //namespace qdutils