xref: /OK3568_Linux_fs/external/mpp/osal/mpp_platform.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright 2015 Rockchip Electronics Co. LTD
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define MODULE_TAG "mpp_platform"
18 
19 #include <string.h>
20 
21 #include "mpp_env.h"
22 #include "mpp_debug.h"
23 #include "mpp_common.h"
24 #include "mpp_platform.h"
25 #include "mpp_service.h"
26 
check_kernel_version(void)27 static MppKernelVersion check_kernel_version(void)
28 {
29     static const char *kernel_version_path = "/proc/version";
30     MppKernelVersion version = KERNEL_UNKNOWN;
31     FILE *fp = NULL;
32     char buf[32];
33 
34     if (access(kernel_version_path, F_OK | R_OK))
35         return version;
36 
37     fp = fopen(kernel_version_path, "rb");
38     if (fp) {
39         size_t len = fread(buf, 1, sizeof(buf) - 1, fp);
40         char *pos = NULL;
41 
42         buf[len] = '\0';
43         pos = strstr(buf, "Linux version ");
44         if (pos) {
45             RK_S32 major = 0;
46             RK_S32 minor = 0;
47             RK_S32 last = 0;
48             RK_S32 count = 0;
49 
50             pos += 14;
51             count = sscanf(pos, "%d.%d.%d ", &major, &minor, &last);
52             if (count >= 2 && major > 0 && minor > 0) {
53                 switch (major) {
54                 case 3: {
55                     version = KERNEL_3_10;
56                 } break;
57                 case 4: {
58                     version = KERNEL_4_4;
59                     if (minor >= 19)
60                         version = KERNEL_4_19;
61                 } break;
62                 case 5: {
63                     version = KERNEL_5_10;
64                 } break;
65                 default: break;
66                 }
67             }
68         }
69         fclose(fp);
70     }
71     return version;
72 }
73 
74 class MppPlatformService
75 {
76 private:
77     // avoid any unwanted function
78     MppPlatformService();
~MppPlatformService()79     ~MppPlatformService() {};
80     MppPlatformService(const MppPlatformService &);
81     MppPlatformService &operator=(const MppPlatformService &);
82 
83     MppIoctlVersion     ioctl_version;
84     MppKernelVersion    kernel_version;
85     RK_U32              vcodec_type;
86     RK_U32              hw_ids[32];
87     MppServiceCmdCap    mpp_service_cmd_cap;
88     const MppSocInfo    *soc_info;
89     const char          *soc_name;
90 
91 public:
get_instance()92     static MppPlatformService *get_instance() {
93         static MppPlatformService instance;
94         return &instance;
95     }
96 
get_ioctl_version(void)97     MppIoctlVersion     get_ioctl_version(void) { return ioctl_version; };
get_kernel_version(void)98     MppKernelVersion    get_kernel_version(void) { return kernel_version; };
get_soc_name()99     const char          *get_soc_name() { return soc_name; };
get_mpp_service_cmd_cap()100     MppServiceCmdCap    *get_mpp_service_cmd_cap() { return &mpp_service_cmd_cap; };
101     RK_U32              get_hw_id(RK_S32 client_type);
get_vcodec_type(void)102     RK_U32              get_vcodec_type(void) { return vcodec_type; };
103 };
104 
MppPlatformService()105 MppPlatformService::MppPlatformService()
106     : ioctl_version(IOCTL_MPP_SERVICE_V1),
107       kernel_version(KERNEL_UNKNOWN),
108       vcodec_type(0),
109       soc_info(NULL),
110       soc_name(NULL)
111 {
112     /* judge vdpu support version */
113     MppServiceCmdCap *cap = &mpp_service_cmd_cap;
114 
115     /* default value */
116     cap->support_cmd = 0;
117     cap->query_cmd = MPP_CMD_QUERY_BASE + 1;
118     cap->init_cmd = MPP_CMD_INIT_BASE + 1;
119     cap->send_cmd = MPP_CMD_SEND_BASE + 1;
120     cap->poll_cmd = MPP_CMD_POLL_BASE + 1;
121     cap->ctrl_cmd = MPP_CMD_CONTROL_BASE + 0;
122 
123     mpp_env_get_u32("mpp_debug", &mpp_debug, 0);
124 
125     /* read soc name */
126     soc_name = mpp_get_soc_name();
127     soc_info = mpp_get_soc_info();
128 
129     if (soc_info->soc_type == ROCKCHIP_SOC_AUTO)
130         mpp_log("can not found match soc name: %s\n", soc_name);
131 
132     ioctl_version = IOCTL_VCODEC_SERVICE;
133     if (mpp_get_mpp_service_name()) {
134         ioctl_version = IOCTL_MPP_SERVICE_V1;
135         check_mpp_service_cap(&vcodec_type, hw_ids, cap);
136     }
137     kernel_version = check_kernel_version();
138     if (!vcodec_type)
139         vcodec_type = soc_info->vcodec_type;
140 }
141 
get_hw_id(RK_S32 client_type)142 RK_U32 MppPlatformService::get_hw_id(RK_S32 client_type)
143 {
144     RK_U32 hw_id = 0;
145 
146     if (vcodec_type & (1 << client_type))
147         hw_id = hw_ids[client_type];
148 
149     return hw_id;
150 }
151 
mpp_get_ioctl_version(void)152 MppIoctlVersion mpp_get_ioctl_version(void)
153 {
154     return MppPlatformService::get_instance()->get_ioctl_version();
155 }
156 
mpp_get_kernel_version(void)157 MppKernelVersion mpp_get_kernel_version(void)
158 {
159     return MppPlatformService::get_instance()->get_kernel_version();
160 }
161 
mpp_get_2d_hw_flag(void)162 RK_U32 mpp_get_2d_hw_flag(void)
163 {
164     RK_U32 flag = 0;
165 
166     if (!access("/dev/rga", F_OK))
167         flag |= HAVE_RGA;
168 
169     if (!access("/dev/iep", F_OK))
170         flag |= HAVE_IEP;
171 
172     return flag;
173 }
174 
mpp_get_mpp_service_cmd_cap(void)175 const MppServiceCmdCap *mpp_get_mpp_service_cmd_cap(void)
176 {
177     return MppPlatformService::get_instance()->get_mpp_service_cmd_cap();
178 }
179 
mpp_get_client_hw_id(RK_S32 client_type)180 RK_U32 mpp_get_client_hw_id(RK_S32 client_type)
181 {
182     return MppPlatformService::get_instance()->get_hw_id(client_type);
183 }
184 
mpp_get_vcodec_type(void)185 RK_U32 mpp_get_vcodec_type(void)
186 {
187     static RK_U32 vcodec_type = 0;
188 
189     if (!vcodec_type)
190         vcodec_type = MppPlatformService::get_instance()->get_vcodec_type();
191 
192     return vcodec_type;
193 }
194