1 /* 2 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. 3 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above 10 * copyright notice, this list of conditions and the following 11 * disclaimer in the documentation and/or other materials provided 12 * with the distribution. 13 * * Neither the name of The Linux Foundation nor the names of its 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 #include <cutils/log.h> 30 #include <fcntl.h> 31 #include <sys/ioctl.h> 32 #include <linux/fb.h> 33 #include <linux/msm_mdp.h> 34 #include "mdp_version.h" 35 36 ANDROID_SINGLETON_STATIC_INSTANCE(qdutils::MDPVersion); 37 namespace qdutils { 38 39 MDPVersion::MDPVersion() 40 { 41 int fb_fd = open("/dev/graphics/fb0", O_RDWR); 42 int mdp_version = MDP_V_UNKNOWN; 43 char panel_type = 0; 44 struct fb_fix_screeninfo fb_finfo; 45 46 mMdpRev = 0; 47 mRGBPipes = 0; 48 mVGPipes = 0; 49 mDMAPipes = 0; 50 mFeatures = 0; 51 //TODO get this from driver, default for A-fam to 8 52 mMDPDownscale = 8; 53 mFd = fb_fd; 54 55 if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &fb_finfo) < 0) { 56 ALOGE("FBIOGET_FSCREENINFO failed"); 57 mdp_version = MDP_V_UNKNOWN; 58 } else { 59 if(!strncmp(fb_finfo.id, "msmfb", 5)) { 60 char str_ver[4] = { 0 }; 61 memcpy(str_ver, &fb_finfo.id[5], 3); 62 str_ver[3] = '\0'; 63 mdp_version = atoi(str_ver); 64 65 //Normalize MDP version to ease comparison. 66 //This is needed only because 67 //MDP 3.0.3 reports value as 303 which 68 //is more than all the others 69 if (mdp_version < 100) 70 mdp_version *= 10; 71 72 mRGBPipes = mVGPipes = 2; 73 74 } else if (!strncmp(fb_finfo.id, "mdssfb", 6)) { 75 mdp_version = MDSS_V5; 76 #ifdef MDSS_TARGET 77 struct msmfb_metadata metadata; 78 memset(&metadata, 0 , sizeof(metadata)); 79 metadata.op = metadata_op_get_caps; 80 if (ioctl(fb_fd, MSMFB_METADATA_GET, &metadata) == -1) { 81 ALOGE("Error retrieving MDP revision and pipes info"); 82 mdp_version = MDP_V_UNKNOWN; 83 } else { 84 mMdpRev = metadata.data.caps.mdp_rev; 85 mRGBPipes = metadata.data.caps.rgb_pipes; 86 mVGPipes = metadata.data.caps.vig_pipes; 87 mDMAPipes = metadata.data.caps.dma_pipes; 88 mFeatures = metadata.data.caps.features; 89 if (metadata.data.caps.mdp_rev == MDP_V3_0_4){ 90 mdp_version = MDP_V3_0_4; 91 } 92 } 93 #endif 94 } else { 95 mdp_version = MDP_V_UNKNOWN; 96 } 97 98 /* Assumes panel type is 2nd element in '_' delimited id string */ 99 char * ptype = strstr(fb_finfo.id, "_"); 100 if (!ptype || (*(++ptype) == '\0')) { 101 ALOGE("Invalid framebuffer info string: %s", fb_finfo.id); 102 ptype = fb_finfo.id; 103 } 104 panel_type = *ptype; 105 } 106 mPanelType = panel_type; 107 mMDPVersion = mdp_version; 108 mHasOverlay = false; 109 if((mMDPVersion >= MDP_V4_0) || 110 (mMDPVersion == MDP_V_UNKNOWN) || 111 (mMDPVersion == MDP_V3_0_4)) 112 mHasOverlay = true; 113 if(mMDPVersion >= MDSS_V5) { 114 //TODO get this from driver 115 mMDPDownscale = 4; 116 117 char split[64]; 118 FILE* fp = fopen("/sys/class/graphics/fb0/msm_fb_split", "r"); 119 if(fp){ 120 //Format "left right" space as delimiter 121 if(fread(split, sizeof(char), 64, fp)) { 122 mSplit.mLeft = atoi(split); 123 ALOGI_IF(mSplit.mLeft, "Left Split=%d", mSplit.mLeft); 124 char *rght = strpbrk(split, " "); 125 if(rght) 126 mSplit.mRight = atoi(rght + 1); 127 ALOGI_IF(rght, "Right Split=%d", mSplit.mRight); 128 } 129 } else { 130 ALOGE("Failed to open mdss_fb_split node"); 131 } 132 133 if(fp) 134 fclose(fp); 135 } 136 } 137 138 MDPVersion::~MDPVersion() { 139 close(mFd); 140 } 141 142 bool MDPVersion::supportsDecimation() { 143 return mFeatures & MDP_DECIMATION_EN; 144 } 145 146 uint32_t MDPVersion::getMaxMDPDownscale() { 147 return mMDPDownscale; 148 } 149 150 bool MDPVersion::supportsBWC() { 151 // BWC - Bandwidth Compression 152 return (mFeatures & MDP_BWC_EN); 153 } 154 155 bool MDPVersion::is8x26() { 156 // check for 8x26 variants 157 // chip variants have same major number and minor numbers usually vary 158 // for e.g., MDSS_MDP_HW_REV_101 is 0x10010000 159 // 1001 - major number 160 // 0000 - minor number 161 // 8x26 v1 minor number is 0000 162 // v2 minor number is 0001 etc.. 163 if( mMdpRev >= MDSS_MDP_HW_REV_101 && mMdpRev < MDSS_MDP_HW_REV_102) { 164 return true; 165 } 166 return false; 167 } 168 169 }; //namespace qdutils 170 171