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