Home | History | Annotate | Download | only in libqdutils
      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