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