1 /*
2 * Copyright 2020 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 "hal_h265d_api"
18
19 #include <stdio.h>
20 #include <string.h>
21
22 #include "mpp_env.h"
23 #include "mpp_mem.h"
24 #include "mpp_debug.h"
25
26 #include "hal_h265d_ctx.h"
27 #include "hal_h265d_api.h"
28 #include "hal_h265d_rkv.h"
29 #include "hal_h265d_vdpu34x.h"
30 #include "hal_h265d_vdpu382.h"
31 #include "hal_h265d_vdpu383.h"
32 #include "hal_h265d_vdpu384a.h"
33
34 RK_U32 hal_h265d_debug = 0;
35
hal_h265d_init(void * ctx,MppHalCfg * cfg)36 MPP_RET hal_h265d_init(void *ctx, MppHalCfg *cfg)
37 {
38 MPP_RET ret = MPP_NOK;
39 HalH265dCtx *p = (HalH265dCtx *)ctx;
40 MppClientType client_type = VPU_CLIENT_BUTT;
41 RK_U32 vcodec_type = mpp_get_vcodec_type();
42 RockchipSocType soc = mpp_get_soc_type();
43 RK_U32 hw_id = 0;
44
45 if (!(vcodec_type & (HAVE_RKVDEC | HAVE_HEVC_DEC))) {
46 mpp_err_f("Can not found valid H.265 decoder hardware on platform %08x\n", vcodec_type);
47 return ret;
48 }
49
50 client_type = (vcodec_type & HAVE_HEVC_DEC) ?
51 VPU_CLIENT_HEVC_DEC : VPU_CLIENT_RKVDEC;
52
53 ret = mpp_dev_init(&cfg->dev, client_type);
54 if (ret) {
55 mpp_err("mpp_dev_init failed ret: %d\n", ret);
56 return ret;
57 }
58 cfg->hw_info = mpp_get_dec_hw_info_by_client_type(client_type);
59 p->hw_info = cfg->hw_info;
60
61 hw_id = mpp_get_client_hw_id(client_type);
62 p->dev = cfg->dev;
63 p->is_v341 = (soc == ROCKCHIP_SOC_RK3228H || (soc == ROCKCHIP_SOC_RK3328));
64 p->is_v345 = (hw_id == HWID_VDPU345);
65 p->is_v34x = (hw_id == HWID_VDPU34X || hw_id == HWID_VDPU38X);
66 p->is_v383 = (hw_id == HWID_VDPU383);
67 p->is_v384a = (hw_id == HWID_VDPU384A);
68 p->client_type = client_type;
69
70 if (hw_id == HWID_VDPU382_RK3528 || hw_id == HWID_VDPU382_RK3562)
71 p->api = &hal_h265d_vdpu382;
72 else if (p->is_v34x)
73 p->api = &hal_h265d_vdpu34x;
74 else if (p->is_v383)
75 p->api = &hal_h265d_vdpu383;
76 else if (p->is_v384a)
77 p->api = &hal_h265d_vdpu384a;
78 else
79 p->api = &hal_h265d_rkv;
80
81 cfg->support_fast_mode = 1;
82
83 p->cfg = cfg->cfg;
84 p->slots = cfg->frame_slots;
85 p->dec_cb = cfg->dec_cb;
86 p->fast_mode = cfg->cfg->base.fast_parse;
87 p->packet_slots = cfg->packet_slots;
88
89 mpp_env_get_u32("hal_h265d_debug", &hal_h265d_debug, 0);
90
91 ret = p->api->init(ctx, cfg);
92
93 return ret;
94 }
95
hal_h265d_deinit(void * ctx)96 MPP_RET hal_h265d_deinit(void *ctx)
97 {
98 MPP_RET ret = MPP_NOK;
99 HalH265dCtx *p = (HalH265dCtx *)ctx;
100
101 if (p && p->api && p->api->deinit)
102 ret = p->api->deinit(ctx);
103
104 if (p->dev) {
105 mpp_dev_deinit(p->dev);
106 p->dev = NULL;
107 }
108
109 return ret;
110 }
111
hal_h265d_gen_regs(void * ctx,HalTaskInfo * task)112 MPP_RET hal_h265d_gen_regs(void *ctx, HalTaskInfo *task)
113 {
114 MPP_RET ret = MPP_NOK;
115 HalH265dCtx *p = (HalH265dCtx *)ctx;
116
117 if (p && p->api && p->api->reg_gen)
118 ret = p->api->reg_gen(ctx, task);
119
120 return ret;
121 }
122
hal_h265d_start(void * ctx,HalTaskInfo * task)123 MPP_RET hal_h265d_start(void *ctx, HalTaskInfo *task)
124 {
125 MPP_RET ret = MPP_NOK;
126 HalH265dCtx *p = (HalH265dCtx *)ctx;
127
128 if (p && p->api && p->api->start)
129 ret = p->api->start(ctx, task);
130
131 return ret;
132 }
133
hal_h265d_wait(void * ctx,HalTaskInfo * task)134 MPP_RET hal_h265d_wait(void *ctx, HalTaskInfo *task)
135 {
136 MPP_RET ret = MPP_NOK;
137 HalH265dCtx *p = (HalH265dCtx *)ctx;
138
139 if (p && p->api && p->api->wait)
140 ret = p->api->wait(ctx, task);
141
142 return ret;
143 }
144
hal_h265d_reset(void * ctx)145 MPP_RET hal_h265d_reset(void *ctx)
146 {
147 MPP_RET ret = MPP_NOK;
148 HalH265dCtx *p = (HalH265dCtx *)ctx;
149
150 if (p && p->api && p->api->reset)
151 ret = p->api->reset(ctx);
152
153 return ret;
154 }
155
hal_h265d_flush(void * ctx)156 MPP_RET hal_h265d_flush(void *ctx)
157 {
158 MPP_RET ret = MPP_NOK;
159 HalH265dCtx *p = (HalH265dCtx *)ctx;
160
161 if (p && p->api && p->api->flush)
162 ret = p->api->flush(ctx);
163
164 return ret;
165 }
166
hal_h265d_control(void * ctx,MpiCmd cmd,void * param)167 MPP_RET hal_h265d_control(void *ctx, MpiCmd cmd, void *param)
168 {
169 MPP_RET ret = MPP_OK;
170 HalH265dCtx *p = (HalH265dCtx *)ctx;
171
172 if (p && p->api && p->api->control)
173 ret = p->api->control(ctx, cmd, param);
174
175 return ret;
176 }
177
178 const MppHalApi hal_api_h265d = {
179 .name = "h265d_rkdec",
180 .type = MPP_CTX_DEC,
181 .coding = MPP_VIDEO_CodingHEVC,
182 .ctx_size = sizeof(HalH265dCtx),
183 .flag = 0,
184 .init = hal_h265d_init,
185 .deinit = hal_h265d_deinit,
186 .reg_gen = hal_h265d_gen_regs,
187 .start = hal_h265d_start,
188 .wait = hal_h265d_wait,
189 .reset = hal_h265d_reset,
190 .flush = hal_h265d_flush,
191 .control = hal_h265d_control,
192 };
193