1 /*
2  * Copyright (c) 2013, 2018, 2020, 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 
30 #include <unistd.h>
31 #include <gralloc_priv.h>
32 #include "qd_utils.h"
33 
34 static const int kFBNodeMax = 4;
35 namespace qdutils {
36 
parseLine(char * input,char * tokens[],const uint32_t maxToken,uint32_t * count)37 static int parseLine(char *input, char *tokens[], const uint32_t maxToken, uint32_t *count) {
38     char *tmpToken = NULL;
39     char *tmpPtr;
40     uint32_t index = 0;
41     const char *delim = ", =\n";
42     if (!input) {
43       return -1;
44     }
45     tmpToken = strtok_r(input, delim, &tmpPtr);
46     while (tmpToken && index < maxToken) {
47       tokens[index++] = tmpToken;
48       tmpToken = strtok_r(NULL, delim, &tmpPtr);
49     }
50     *count = index;
51 
52     return 0;
53 }
54 
getExternalNode(const char * type)55 static int getExternalNode(const char *type) {
56     FILE *displayDeviceFP = NULL;
57     char fbType[MAX_FRAME_BUFFER_NAME_SIZE];
58     char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE];
59     int j = 0;
60 
61     for(j = 0; j < kFBNodeMax; j++) {
62         snprintf (msmFbTypePath, sizeof(msmFbTypePath),
63                   "/sys/devices/virtual/graphics/fb%d/msm_fb_type", j);
64         displayDeviceFP = fopen(msmFbTypePath, "r");
65         if(displayDeviceFP) {
66             fread(fbType, sizeof(char), MAX_FRAME_BUFFER_NAME_SIZE,
67                     displayDeviceFP);
68             if(strncmp(fbType, type, strlen(type)) == 0) {
69                 ALOGD("%s: %s is at fb%d", __func__, type, j);
70                 fclose(displayDeviceFP);
71                 break;
72             }
73             fclose(displayDeviceFP);
74         } else {
75             ALOGE("%s: Failed to open fb node %s", __func__, msmFbTypePath);
76         }
77     }
78 
79     if (j < kFBNodeMax)
80         return j;
81     else
82         ALOGE("%s: Failed to find %s node", __func__, type);
83 
84     return -1;
85 }
86 
isDPConnected()87 bool isDPConnected() {
88     char connectPath[MAX_FRAME_BUFFER_NAME_SIZE];
89     FILE *connectFile = NULL;
90     size_t len = MAX_STRING_LENGTH;
91     char stringBuffer[MAX_STRING_LENGTH];
92     char *line = stringBuffer;
93 
94     int nodeId = getExternalNode("dp panel");
95     if (nodeId < 0) {
96         ALOGE("%s no DP node found", __func__);
97         return false;
98     }
99 
100     snprintf(connectPath, sizeof(connectPath),
101              "/sys/devices/virtual/graphics/fb%d/connected", nodeId);
102 
103     connectFile = fopen(connectPath, "rb");
104     if (!connectFile) {
105         ALOGW("Failed to open connect node for device node %s", connectPath);
106         return false;
107     }
108 
109     if (getline(&line, &len, connectFile) < 0) {
110         fclose(connectFile);
111         return false;
112     }
113 
114     fclose(connectFile);
115 
116     return atoi(line);
117 }
118 
getDPTestConfig(uint32_t * panelBpp,uint32_t * patternType)119 int getDPTestConfig(uint32_t *panelBpp, uint32_t *patternType) {
120     if (!panelBpp || !patternType) {
121         return -1;
122     }
123 
124     char configPath[MAX_FRAME_BUFFER_NAME_SIZE];
125     FILE *configFile = NULL;
126     uint32_t tokenCount = 0;
127     const uint32_t maxCount = 10;
128     char *tokens[maxCount] = { NULL };
129     size_t len = MAX_STRING_LENGTH;
130     char stringBuffer[MAX_STRING_LENGTH];
131     char *line = stringBuffer;
132 
133     int nodeId = getExternalNode("dp panel");
134     if (nodeId < 0) {
135         ALOGE("%s no DP node found", __func__);
136         return -EINVAL;
137     }
138 
139     snprintf(configPath, sizeof(configPath),
140              "/sys/devices/virtual/graphics/fb%d/config", nodeId);
141 
142     configFile = fopen(configPath, "rb");
143     if (!configFile) {
144         ALOGW("Failed to open config node for device node %s", configPath);
145         return -EINVAL;
146     }
147 
148     while (getline(&line, &len, configFile) != -1) {
149         if (!parseLine(line, tokens, maxCount, &tokenCount)) {
150             if (tokens[0] != NULL) {
151               if (!strncmp(tokens[0], "bpp", strlen("bpp"))) {
152                 *panelBpp = static_cast<uint32_t>(atoi(tokens[1]));
153               } else  if (!strncmp(tokens[0], "pattern", strlen("pattern"))) {
154                 *patternType = static_cast<uint32_t>(atoi(tokens[1]));
155               }
156             }
157         }
158     }
159 
160     fclose(configFile);
161 
162     return 0;
163 }
164 
GetHALPixelFormatString(int format)165 const char *GetHALPixelFormatString(int format) {
166   switch (format) {
167   case HAL_PIXEL_FORMAT_RGBA_8888:
168     return "RGBA_8888";
169   case HAL_PIXEL_FORMAT_RGBX_8888:
170     return "RGBX_8888";
171   case HAL_PIXEL_FORMAT_RGB_888:
172     return "RGB_888";
173   case HAL_PIXEL_FORMAT_RGB_565:
174     return "RGB_565";
175   case HAL_PIXEL_FORMAT_BGR_565:
176     return "BGR_565";
177   case HAL_PIXEL_FORMAT_BGRA_8888:
178     return "BGRA_8888";
179   case HAL_PIXEL_FORMAT_RGBA_5551:
180     return "RGBA_5551";
181   case HAL_PIXEL_FORMAT_RGBA_4444:
182     return "RGBA_4444";
183   case HAL_PIXEL_FORMAT_YV12:
184     return "YV12";
185   case HAL_PIXEL_FORMAT_YCbCr_422_SP:
186     return "YCbCr_422_SP_NV16";
187   case HAL_PIXEL_FORMAT_YCrCb_420_SP:
188     return "YCrCb_420_SP_NV21";
189   case HAL_PIXEL_FORMAT_YCbCr_422_I:
190     return "YCbCr_422_I_YUY2";
191   case HAL_PIXEL_FORMAT_YCrCb_422_I:
192     return "YCrCb_422_I_YVYU";
193   case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
194     return "NV12_ENCODEABLE";
195   case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
196     return "YCbCr_420_SP_TILED_TILE_4x2";
197   case HAL_PIXEL_FORMAT_YCbCr_420_SP:
198     return "YCbCr_420_SP";
199   case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
200     return "YCrCb_420_SP_ADRENO";
201   case HAL_PIXEL_FORMAT_YCrCb_422_SP:
202     return "YCrCb_422_SP";
203   case HAL_PIXEL_FORMAT_R_8:
204     return "R_8";
205   case HAL_PIXEL_FORMAT_RG_88:
206     return "RG_88";
207   case HAL_PIXEL_FORMAT_INTERLACE:
208     return "INTERLACE";
209   case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
210     return "YCbCr_420_SP_VENUS";
211   case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
212     return "YCrCb_420_SP_VENUS";
213   case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
214     return "YCbCr_420_SP_VENUS_UBWC";
215   case HAL_PIXEL_FORMAT_RGBA_1010102:
216     return "RGBA_1010102";
217   case HAL_PIXEL_FORMAT_ARGB_2101010:
218     return "ARGB_2101010";
219   case HAL_PIXEL_FORMAT_RGBX_1010102:
220     return "RGBX_1010102";
221   case HAL_PIXEL_FORMAT_XRGB_2101010:
222     return "XRGB_2101010";
223   case HAL_PIXEL_FORMAT_BGRA_1010102:
224     return "BGRA_1010102";
225   case HAL_PIXEL_FORMAT_ABGR_2101010:
226     return "ABGR_2101010";
227   case HAL_PIXEL_FORMAT_BGRX_1010102:
228     return "BGRX_1010102";
229   case HAL_PIXEL_FORMAT_XBGR_2101010:
230     return "XBGR_2101010";
231   case HAL_PIXEL_FORMAT_YCbCr_420_P010:
232     return "YCbCr_420_P010";
233   case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
234     return "YCbCr_420_TP10_UBWC";
235   case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
236     return "YCbCr_420_P010_VENUS";
237   case HAL_PIXEL_FORMAT_RGBA_FP16:
238     return "PIXEL_FORMAT_RGBA_FP16";
239   default:
240     return "Unknown_format";
241   }
242 }
243 
244 }; //namespace qdutils
245