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 
87 
isDPConnected()88 bool isDPConnected() {
89     char connectPath[MAX_FRAME_BUFFER_NAME_SIZE];
90     FILE *connectFile = NULL;
91     size_t len = MAX_STRING_LENGTH;
92     char stringBuffer[MAX_STRING_LENGTH];
93     char *line = stringBuffer;
94 
95     int nodeId = getExternalNode("dp panel");
96     if (nodeId < 0) {
97         ALOGE("%s no DP node found", __func__);
98         return false;
99     }
100 
101     snprintf(connectPath, sizeof(connectPath),
102              "/sys/devices/virtual/graphics/fb%d/connected", nodeId);
103 
104     connectFile = fopen(connectPath, "rb");
105     if (!connectFile) {
106         ALOGW("Failed to open connect node for device node %s", connectPath);
107         return false;
108     }
109 
110     if (getline(&line, &len, connectFile) < 0) {
111         fclose(connectFile);
112         return false;
113     }
114 
115     fclose(connectFile);
116 
117     return atoi(line);
118 }
119 
getDPTestConfig(uint32_t * panelBpp,uint32_t * patternType)120 int getDPTestConfig(uint32_t *panelBpp, uint32_t *patternType) {
121     if (!panelBpp || !patternType) {
122         return -1;
123     }
124 
125     char configPath[MAX_FRAME_BUFFER_NAME_SIZE];
126     FILE *configFile = NULL;
127     uint32_t tokenCount = 0;
128     const uint32_t maxCount = 10;
129     char *tokens[maxCount] = { NULL };
130     size_t len = MAX_STRING_LENGTH;
131     char stringBuffer[MAX_STRING_LENGTH];
132     char *line = stringBuffer;
133 
134     int nodeId = getExternalNode("dp panel");
135     if (nodeId < 0) {
136         ALOGE("%s no DP node found", __func__);
137         return -EINVAL;
138     }
139 
140     snprintf(configPath, sizeof(configPath),
141              "/sys/devices/virtual/graphics/fb%d/config", nodeId);
142 
143     configFile = fopen(configPath, "rb");
144     if (!configFile) {
145         ALOGW("Failed to open config node for device node %s", configPath);
146         return -EINVAL;
147     }
148 
149     while (getline(&line, &len, configFile) != -1) {
150         if (!parseLine(line, tokens, maxCount, &tokenCount)) {
151             if (tokens[0] != NULL) {
152               if (!strncmp(tokens[0], "bpp", strlen("bpp"))) {
153                 *panelBpp = static_cast<uint32_t>(atoi(tokens[1]));
154               } else  if (!strncmp(tokens[0], "pattern", strlen("pattern"))) {
155                 *patternType = static_cast<uint32_t>(atoi(tokens[1]));
156               }
157             }
158         }
159     }
160 
161     fclose(configFile);
162 
163     return 0;
164 }
165 
getDriverType()166 DriverType getDriverType() {
167     const char *fb_caps = "/sys/devices/virtual/graphics/fb0/mdp/caps";
168     // 0 - File exists
169     return access(fb_caps, F_OK) ? DriverType::DRM : DriverType::FB;
170 }
171 
GetHALPixelFormatString(int format)172 const char *GetHALPixelFormatString(int format) {
173   switch (format) {
174   case HAL_PIXEL_FORMAT_RGBA_8888:
175     return "RGBA_8888";
176   case HAL_PIXEL_FORMAT_RGBX_8888:
177     return "RGBX_8888";
178   case HAL_PIXEL_FORMAT_RGB_888:
179     return "RGB_888";
180   case HAL_PIXEL_FORMAT_RGB_565:
181     return "RGB_565";
182   case HAL_PIXEL_FORMAT_BGR_565:
183     return "BGR_565";
184   case HAL_PIXEL_FORMAT_BGRA_8888:
185     return "BGRA_8888";
186   case HAL_PIXEL_FORMAT_RGBA_5551:
187     return "RGBA_5551";
188   case HAL_PIXEL_FORMAT_RGBA_4444:
189     return "RGBA_4444";
190   case HAL_PIXEL_FORMAT_YV12:
191     return "YV12";
192   case HAL_PIXEL_FORMAT_YCbCr_422_SP:
193     return "YCbCr_422_SP_NV16";
194   case HAL_PIXEL_FORMAT_YCrCb_420_SP:
195     return "YCrCb_420_SP_NV21";
196   case HAL_PIXEL_FORMAT_YCbCr_422_I:
197     return "YCbCr_422_I_YUY2";
198   case HAL_PIXEL_FORMAT_YCrCb_422_I:
199     return "YCrCb_422_I_YVYU";
200   case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
201     return "NV12_ENCODEABLE";
202   case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
203     return "YCbCr_420_SP_TILED_TILE_4x2";
204   case HAL_PIXEL_FORMAT_YCbCr_420_SP:
205     return "YCbCr_420_SP";
206   case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
207     return "YCrCb_420_SP_ADRENO";
208   case HAL_PIXEL_FORMAT_YCrCb_422_SP:
209     return "YCrCb_422_SP";
210   case HAL_PIXEL_FORMAT_R_8:
211     return "R_8";
212   case HAL_PIXEL_FORMAT_RG_88:
213     return "RG_88";
214   case HAL_PIXEL_FORMAT_INTERLACE:
215     return "INTERLACE";
216   case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
217     return "YCbCr_420_SP_VENUS";
218   case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
219     return "YCrCb_420_SP_VENUS";
220   case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
221     return "YCbCr_420_SP_VENUS_UBWC";
222   case HAL_PIXEL_FORMAT_RGBA_1010102:
223     return "RGBA_1010102";
224   case HAL_PIXEL_FORMAT_ARGB_2101010:
225     return "ARGB_2101010";
226   case HAL_PIXEL_FORMAT_RGBX_1010102:
227     return "RGBX_1010102";
228   case HAL_PIXEL_FORMAT_XRGB_2101010:
229     return "XRGB_2101010";
230   case HAL_PIXEL_FORMAT_BGRA_1010102:
231     return "BGRA_1010102";
232   case HAL_PIXEL_FORMAT_ABGR_2101010:
233     return "ABGR_2101010";
234   case HAL_PIXEL_FORMAT_BGRX_1010102:
235     return "BGRX_1010102";
236   case HAL_PIXEL_FORMAT_XBGR_2101010:
237     return "XBGR_2101010";
238   case HAL_PIXEL_FORMAT_YCbCr_420_P010:
239     return "YCbCr_420_P010";
240   case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
241     return "YCbCr_420_TP10_UBWC";
242   case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
243     return "YCbCr_420_P010_VENUS";
244   default:
245     return "Unknown_format";
246   }
247 }
248 
249 }; //namespace qdutils
250