xref: /rockchip-linux_mpp/osal/mpp_platform.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2*437bfbebSnyanmisaka /*
3*437bfbebSnyanmisaka  * Copyright (c) 2015 Rockchip Electronics Co., Ltd.
4*437bfbebSnyanmisaka  */
5*437bfbebSnyanmisaka 
6*437bfbebSnyanmisaka #define MODULE_TAG "mpp_platform"
7*437bfbebSnyanmisaka 
8*437bfbebSnyanmisaka #include <string.h>
9*437bfbebSnyanmisaka 
10*437bfbebSnyanmisaka #include "mpp_env.h"
11*437bfbebSnyanmisaka #include "mpp_mem.h"
12*437bfbebSnyanmisaka #include "mpp_debug.h"
13*437bfbebSnyanmisaka #include "mpp_common.h"
14*437bfbebSnyanmisaka #include "mpp_platform.h"
15*437bfbebSnyanmisaka #include "mpp_service.h"
16*437bfbebSnyanmisaka #include "mpp_singleton.h"
17*437bfbebSnyanmisaka 
18*437bfbebSnyanmisaka #define get_srv_platform() \
19*437bfbebSnyanmisaka     ({ \
20*437bfbebSnyanmisaka         MppPlatformService *__tmp; \
21*437bfbebSnyanmisaka         if (!srv_platform) { \
22*437bfbebSnyanmisaka             mpp_plat_srv_init(); \
23*437bfbebSnyanmisaka         } \
24*437bfbebSnyanmisaka         if (srv_platform) { \
25*437bfbebSnyanmisaka             __tmp = srv_platform; \
26*437bfbebSnyanmisaka         } else { \
27*437bfbebSnyanmisaka             mpp_err("mpp platform srv not init at %s\n", __FUNCTION__); \
28*437bfbebSnyanmisaka             __tmp = NULL; \
29*437bfbebSnyanmisaka         } \
30*437bfbebSnyanmisaka         __tmp; \
31*437bfbebSnyanmisaka     })
32*437bfbebSnyanmisaka 
33*437bfbebSnyanmisaka typedef struct MppPlatformService_t {
34*437bfbebSnyanmisaka     MppIoctlVersion     ioctl_version;
35*437bfbebSnyanmisaka     MppKernelVersion    kernel_version;
36*437bfbebSnyanmisaka     rk_u32              vcodec_type;
37*437bfbebSnyanmisaka     rk_u32              hw_ids[32];
38*437bfbebSnyanmisaka     MppServiceCmdCap    mpp_service_cmd_cap;
39*437bfbebSnyanmisaka     const MppSocInfo    *soc_info;
40*437bfbebSnyanmisaka     const char          *soc_name;
41*437bfbebSnyanmisaka } MppPlatformService;
42*437bfbebSnyanmisaka 
43*437bfbebSnyanmisaka static MppPlatformService *srv_platform = NULL;
44*437bfbebSnyanmisaka 
check_kernel_version(void)45*437bfbebSnyanmisaka static MppKernelVersion check_kernel_version(void)
46*437bfbebSnyanmisaka {
47*437bfbebSnyanmisaka     static const char *kernel_version_path = "/proc/version";
48*437bfbebSnyanmisaka     MppKernelVersion version = KERNEL_UNKNOWN;
49*437bfbebSnyanmisaka     FILE *fp = NULL;
50*437bfbebSnyanmisaka     char buf[32];
51*437bfbebSnyanmisaka 
52*437bfbebSnyanmisaka     if (access(kernel_version_path, F_OK | R_OK))
53*437bfbebSnyanmisaka         return version;
54*437bfbebSnyanmisaka 
55*437bfbebSnyanmisaka     fp = fopen(kernel_version_path, "rb");
56*437bfbebSnyanmisaka     if (fp) {
57*437bfbebSnyanmisaka         size_t len = fread(buf, 1, sizeof(buf) - 1, fp);
58*437bfbebSnyanmisaka         char *pos = NULL;
59*437bfbebSnyanmisaka 
60*437bfbebSnyanmisaka         buf[len] = '\0';
61*437bfbebSnyanmisaka         pos = strstr(buf, "Linux version ");
62*437bfbebSnyanmisaka         if (pos) {
63*437bfbebSnyanmisaka             rk_s32 major = 0;
64*437bfbebSnyanmisaka             rk_s32 minor = 0;
65*437bfbebSnyanmisaka             rk_s32 last = 0;
66*437bfbebSnyanmisaka             rk_s32 count = 0;
67*437bfbebSnyanmisaka 
68*437bfbebSnyanmisaka             pos += 14;
69*437bfbebSnyanmisaka             count = sscanf(pos, "%d.%d.%d ", &major, &minor, &last);
70*437bfbebSnyanmisaka             if (count >= 2 && major > 0 && minor > 0) {
71*437bfbebSnyanmisaka                 switch (major) {
72*437bfbebSnyanmisaka                 case 3: {
73*437bfbebSnyanmisaka                     version = KERNEL_3_10;
74*437bfbebSnyanmisaka                 } break;
75*437bfbebSnyanmisaka                 case 4: {
76*437bfbebSnyanmisaka                     version = KERNEL_4_4;
77*437bfbebSnyanmisaka                     if (minor >= 19)
78*437bfbebSnyanmisaka                         version = KERNEL_4_19;
79*437bfbebSnyanmisaka                 } break;
80*437bfbebSnyanmisaka                 case 5: {
81*437bfbebSnyanmisaka                     version = KERNEL_5_10;
82*437bfbebSnyanmisaka                 } break;
83*437bfbebSnyanmisaka                 case 6: {
84*437bfbebSnyanmisaka                     version = KERNEL_6_1;
85*437bfbebSnyanmisaka                 } break;
86*437bfbebSnyanmisaka                 default: break;
87*437bfbebSnyanmisaka                 }
88*437bfbebSnyanmisaka             }
89*437bfbebSnyanmisaka         }
90*437bfbebSnyanmisaka         fclose(fp);
91*437bfbebSnyanmisaka     }
92*437bfbebSnyanmisaka     return version;
93*437bfbebSnyanmisaka }
94*437bfbebSnyanmisaka 
mpp_plat_srv_init()95*437bfbebSnyanmisaka static void mpp_plat_srv_init()
96*437bfbebSnyanmisaka {
97*437bfbebSnyanmisaka     /* judge vdpu support version */
98*437bfbebSnyanmisaka     MppPlatformService *srv = srv_platform;
99*437bfbebSnyanmisaka     MppServiceCmdCap *cap;
100*437bfbebSnyanmisaka 
101*437bfbebSnyanmisaka     if (srv)
102*437bfbebSnyanmisaka         return;
103*437bfbebSnyanmisaka 
104*437bfbebSnyanmisaka     srv = mpp_calloc(MppPlatformService, 1);
105*437bfbebSnyanmisaka     if (!srv) {
106*437bfbebSnyanmisaka         mpp_err_f("failed to allocate platform service\n");
107*437bfbebSnyanmisaka         return;
108*437bfbebSnyanmisaka     }
109*437bfbebSnyanmisaka 
110*437bfbebSnyanmisaka     srv_platform = srv;
111*437bfbebSnyanmisaka 
112*437bfbebSnyanmisaka     /* default value */
113*437bfbebSnyanmisaka     cap = &srv->mpp_service_cmd_cap;
114*437bfbebSnyanmisaka     cap->support_cmd = 0;
115*437bfbebSnyanmisaka     cap->query_cmd = MPP_CMD_QUERY_BASE + 1;
116*437bfbebSnyanmisaka     cap->init_cmd = MPP_CMD_INIT_BASE + 1;
117*437bfbebSnyanmisaka     cap->send_cmd = MPP_CMD_SEND_BASE + 1;
118*437bfbebSnyanmisaka     cap->poll_cmd = MPP_CMD_POLL_BASE + 1;
119*437bfbebSnyanmisaka     cap->ctrl_cmd = MPP_CMD_CONTROL_BASE + 0;
120*437bfbebSnyanmisaka 
121*437bfbebSnyanmisaka     mpp_env_get_u32("mpp_debug", &mpp_debug, 0);
122*437bfbebSnyanmisaka 
123*437bfbebSnyanmisaka     /* read soc name */
124*437bfbebSnyanmisaka     srv->soc_name = mpp_get_soc_name();
125*437bfbebSnyanmisaka     srv->soc_info = mpp_get_soc_info();
126*437bfbebSnyanmisaka 
127*437bfbebSnyanmisaka     if (srv->soc_info->soc_type == ROCKCHIP_SOC_AUTO)
128*437bfbebSnyanmisaka         mpp_log("can not found match soc name: %s\n", srv->soc_name);
129*437bfbebSnyanmisaka 
130*437bfbebSnyanmisaka     srv->ioctl_version = IOCTL_VCODEC_SERVICE;
131*437bfbebSnyanmisaka     if (mpp_get_mpp_service_name()) {
132*437bfbebSnyanmisaka         srv->ioctl_version = IOCTL_MPP_SERVICE_V1;
133*437bfbebSnyanmisaka         check_mpp_service_cap(&srv->vcodec_type, srv->hw_ids, cap);
134*437bfbebSnyanmisaka         mpp_dbg_platform("vcodec_type from kernel 0x%08x, vs from soc info 0x%08x\n",
135*437bfbebSnyanmisaka                          srv->vcodec_type, srv->soc_info->vcodec_type);
136*437bfbebSnyanmisaka     }
137*437bfbebSnyanmisaka     srv->kernel_version = check_kernel_version();
138*437bfbebSnyanmisaka     if (!srv->vcodec_type) {
139*437bfbebSnyanmisaka         srv->vcodec_type = srv->soc_info->vcodec_type;
140*437bfbebSnyanmisaka     } else {
141*437bfbebSnyanmisaka         // Compare kernel result with soc infomation.
142*437bfbebSnyanmisaka         rk_u32 diff_type = srv->vcodec_type ^ srv->soc_info->vcodec_type;
143*437bfbebSnyanmisaka         rk_u32 i;
144*437bfbebSnyanmisaka 
145*437bfbebSnyanmisaka         for (i = 0; i <= VPU_CLIENT_VEPU22; i++) {
146*437bfbebSnyanmisaka             rk_u32 mask = 1 << i;
147*437bfbebSnyanmisaka 
148*437bfbebSnyanmisaka             if (diff_type & mask) {
149*437bfbebSnyanmisaka                 MppClientType client_type = (MppClientType) i;
150*437bfbebSnyanmisaka 
151*437bfbebSnyanmisaka                 mpp_dbg_platform("confliction found at client_type %d\n", client_type);
152*437bfbebSnyanmisaka 
153*437bfbebSnyanmisaka                 if (srv->soc_info->vcodec_type & mask) {
154*437bfbebSnyanmisaka                     mpp_err("client %d driver is not ready!\n", client_type);
155*437bfbebSnyanmisaka                 } else {
156*437bfbebSnyanmisaka                     mpp_dbg_platform("client %d driver is ready but not declared!\n", client_type);
157*437bfbebSnyanmisaka                     if (client_type == VPU_CLIENT_VDPU2_PP)
158*437bfbebSnyanmisaka                         srv->vcodec_type &= ~mask;
159*437bfbebSnyanmisaka                 }
160*437bfbebSnyanmisaka             }
161*437bfbebSnyanmisaka         }
162*437bfbebSnyanmisaka 
163*437bfbebSnyanmisaka         mpp_dbg_platform("vcode_type 0x%08x\n", srv->vcodec_type);
164*437bfbebSnyanmisaka     }
165*437bfbebSnyanmisaka 
166*437bfbebSnyanmisaka     return;
167*437bfbebSnyanmisaka }
168*437bfbebSnyanmisaka 
mpp_plat_srv_deinit()169*437bfbebSnyanmisaka static void mpp_plat_srv_deinit()
170*437bfbebSnyanmisaka {
171*437bfbebSnyanmisaka     MPP_FREE(srv_platform);
172*437bfbebSnyanmisaka }
173*437bfbebSnyanmisaka 
mpp_get_ioctl_version(void)174*437bfbebSnyanmisaka MppIoctlVersion mpp_get_ioctl_version(void)
175*437bfbebSnyanmisaka {
176*437bfbebSnyanmisaka     MppPlatformService *srv = get_srv_platform();
177*437bfbebSnyanmisaka     MppIoctlVersion ver = IOCTL_MPP_SERVICE_V1;
178*437bfbebSnyanmisaka 
179*437bfbebSnyanmisaka     if (srv)
180*437bfbebSnyanmisaka         ver = srv->ioctl_version;
181*437bfbebSnyanmisaka 
182*437bfbebSnyanmisaka     return ver;
183*437bfbebSnyanmisaka }
184*437bfbebSnyanmisaka 
mpp_get_kernel_version(void)185*437bfbebSnyanmisaka MppKernelVersion mpp_get_kernel_version(void)
186*437bfbebSnyanmisaka {
187*437bfbebSnyanmisaka     MppPlatformService *srv = get_srv_platform();
188*437bfbebSnyanmisaka     MppKernelVersion ver = KERNEL_UNKNOWN;
189*437bfbebSnyanmisaka 
190*437bfbebSnyanmisaka     if (srv)
191*437bfbebSnyanmisaka         ver = srv->kernel_version;
192*437bfbebSnyanmisaka 
193*437bfbebSnyanmisaka     return ver;
194*437bfbebSnyanmisaka }
195*437bfbebSnyanmisaka 
mpp_get_2d_hw_flag(void)196*437bfbebSnyanmisaka rk_u32 mpp_get_2d_hw_flag(void)
197*437bfbebSnyanmisaka {
198*437bfbebSnyanmisaka     rk_u32 flag = 0;
199*437bfbebSnyanmisaka 
200*437bfbebSnyanmisaka     if (!access("/dev/rga", F_OK))
201*437bfbebSnyanmisaka         flag |= HAVE_RGA;
202*437bfbebSnyanmisaka 
203*437bfbebSnyanmisaka     if (!access("/dev/iep", F_OK))
204*437bfbebSnyanmisaka         flag |= HAVE_IEP;
205*437bfbebSnyanmisaka 
206*437bfbebSnyanmisaka     return flag;
207*437bfbebSnyanmisaka }
208*437bfbebSnyanmisaka 
mpp_get_mpp_service_cmd_cap(void)209*437bfbebSnyanmisaka const MppServiceCmdCap *mpp_get_mpp_service_cmd_cap(void)
210*437bfbebSnyanmisaka {
211*437bfbebSnyanmisaka     MppPlatformService *srv = get_srv_platform();
212*437bfbebSnyanmisaka     const MppServiceCmdCap *cap = NULL;
213*437bfbebSnyanmisaka 
214*437bfbebSnyanmisaka     if (srv)
215*437bfbebSnyanmisaka         cap = &srv->mpp_service_cmd_cap;
216*437bfbebSnyanmisaka 
217*437bfbebSnyanmisaka     return cap;
218*437bfbebSnyanmisaka }
219*437bfbebSnyanmisaka 
mpp_get_client_hw_id(rk_s32 client_type)220*437bfbebSnyanmisaka rk_u32 mpp_get_client_hw_id(rk_s32 client_type)
221*437bfbebSnyanmisaka {
222*437bfbebSnyanmisaka     MppPlatformService *srv = get_srv_platform();
223*437bfbebSnyanmisaka     rk_u32 hw_id = 0;
224*437bfbebSnyanmisaka 
225*437bfbebSnyanmisaka     if (srv && srv->vcodec_type & (1 << client_type))
226*437bfbebSnyanmisaka         hw_id = srv->hw_ids[client_type];
227*437bfbebSnyanmisaka 
228*437bfbebSnyanmisaka     return hw_id;
229*437bfbebSnyanmisaka }
230*437bfbebSnyanmisaka 
mpp_get_vcodec_type(void)231*437bfbebSnyanmisaka rk_u32 mpp_get_vcodec_type(void)
232*437bfbebSnyanmisaka {
233*437bfbebSnyanmisaka     MppPlatformService *srv = get_srv_platform();
234*437bfbebSnyanmisaka     static rk_u32 vcodec_type = 0;
235*437bfbebSnyanmisaka 
236*437bfbebSnyanmisaka     if (vcodec_type)
237*437bfbebSnyanmisaka         return vcodec_type;
238*437bfbebSnyanmisaka 
239*437bfbebSnyanmisaka     if (srv)
240*437bfbebSnyanmisaka         vcodec_type = srv->vcodec_type;
241*437bfbebSnyanmisaka 
242*437bfbebSnyanmisaka     return vcodec_type;
243*437bfbebSnyanmisaka }
244*437bfbebSnyanmisaka 
245*437bfbebSnyanmisaka MPP_SINGLETON(MPP_SGLN_PLATFORM, mpp_platform, mpp_plat_srv_init, mpp_plat_srv_deinit);
246