xref: /rockchip-linux_mpp/mpp/hal/rkenc/common/vepu540c_common.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka  * Copyright 2021 Rockchip Electronics Co. LTD
3*437bfbebSnyanmisaka  *
4*437bfbebSnyanmisaka  * Licensed under the Apache License, Version 2.0 (the "License");
5*437bfbebSnyanmisaka  * you may not use this file except in compliance with the License.
6*437bfbebSnyanmisaka  * You may obtain a copy of the License at
7*437bfbebSnyanmisaka  *
8*437bfbebSnyanmisaka  *      http://www.apache.org/licenses/LICENSE-2.0
9*437bfbebSnyanmisaka  *
10*437bfbebSnyanmisaka  * Unless required by applicable law or agreed to in writing, software
11*437bfbebSnyanmisaka  * distributed under the License is distributed on an "AS IS" BASIS,
12*437bfbebSnyanmisaka  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*437bfbebSnyanmisaka  * See the License for the specific language governing permissions and
14*437bfbebSnyanmisaka  * limitations under the License.
15*437bfbebSnyanmisaka  */
16*437bfbebSnyanmisaka 
17*437bfbebSnyanmisaka #define MODULE_TAG  "vepu540c_common"
18*437bfbebSnyanmisaka 
19*437bfbebSnyanmisaka #include <linux/string.h>
20*437bfbebSnyanmisaka 
21*437bfbebSnyanmisaka #include "mpp_log.h"
22*437bfbebSnyanmisaka #include "mpp_debug.h"
23*437bfbebSnyanmisaka #include "mpp_mem.h"
24*437bfbebSnyanmisaka #include "mpp_common.h"
25*437bfbebSnyanmisaka #include "jpege_syntax.h"
26*437bfbebSnyanmisaka #include "vepu5xx_common.h"
27*437bfbebSnyanmisaka #include "vepu540c_common.h"
28*437bfbebSnyanmisaka #include "hal_enc_task.h"
29*437bfbebSnyanmisaka #include "mpp_frame_impl.h"
30*437bfbebSnyanmisaka #include "mpp_packet.h"
31*437bfbebSnyanmisaka 
vepu540c_set_roi(void * roi_reg_base,MppEncROICfg * roi,RK_S32 w,RK_S32 h)32*437bfbebSnyanmisaka MPP_RET vepu540c_set_roi(void *roi_reg_base, MppEncROICfg * roi,
33*437bfbebSnyanmisaka                          RK_S32 w, RK_S32 h)
34*437bfbebSnyanmisaka {
35*437bfbebSnyanmisaka     MppEncROIRegion *region = roi->regions;
36*437bfbebSnyanmisaka     Vepu540cRoiCfg  *roi_cfg = (Vepu540cRoiCfg *)roi_reg_base;
37*437bfbebSnyanmisaka     Vepu540cRoiRegion *reg_regions = &roi_cfg->regions[0];
38*437bfbebSnyanmisaka     MPP_RET ret = MPP_NOK;
39*437bfbebSnyanmisaka     RK_S32 i = 0;
40*437bfbebSnyanmisaka     memset(reg_regions, 0, sizeof(Vepu540cRoiRegion) * 8);
41*437bfbebSnyanmisaka     if (NULL == roi_cfg || NULL == roi) {
42*437bfbebSnyanmisaka         mpp_err_f("invalid buf %p roi %p\n", roi_cfg, roi);
43*437bfbebSnyanmisaka         goto DONE;
44*437bfbebSnyanmisaka     }
45*437bfbebSnyanmisaka 
46*437bfbebSnyanmisaka     if (roi->number > VEPU540C_MAX_ROI_NUM) {
47*437bfbebSnyanmisaka         mpp_err_f("invalid region number %d\n", roi->number);
48*437bfbebSnyanmisaka         goto DONE;
49*437bfbebSnyanmisaka     }
50*437bfbebSnyanmisaka 
51*437bfbebSnyanmisaka     /* check region config */
52*437bfbebSnyanmisaka     ret = MPP_OK;
53*437bfbebSnyanmisaka     for (i = 0; i < (RK_S32) roi->number; i++, region++) {
54*437bfbebSnyanmisaka         if (region->x + region->w > w || region->y + region->h > h)
55*437bfbebSnyanmisaka             ret = MPP_NOK;
56*437bfbebSnyanmisaka 
57*437bfbebSnyanmisaka         if (region->intra > 1
58*437bfbebSnyanmisaka             || region->qp_area_idx >= VEPU540C_MAX_ROI_NUM
59*437bfbebSnyanmisaka             || region->area_map_en > 1 || region->abs_qp_en > 1)
60*437bfbebSnyanmisaka             ret = MPP_NOK;
61*437bfbebSnyanmisaka 
62*437bfbebSnyanmisaka         if ((region->abs_qp_en && region->quality > 51) ||
63*437bfbebSnyanmisaka             (!region->abs_qp_en
64*437bfbebSnyanmisaka              && (region->quality > 51 || region->quality < -51)))
65*437bfbebSnyanmisaka             ret = MPP_NOK;
66*437bfbebSnyanmisaka 
67*437bfbebSnyanmisaka         if (ret) {
68*437bfbebSnyanmisaka             mpp_err_f("region %d invalid param:\n", i);
69*437bfbebSnyanmisaka             mpp_err_f("position [%d:%d:%d:%d] vs [%d:%d]\n",
70*437bfbebSnyanmisaka                       region->x, region->y, region->w, region->h, w,
71*437bfbebSnyanmisaka                       h);
72*437bfbebSnyanmisaka             mpp_err_f("force intra %d qp area index %d\n",
73*437bfbebSnyanmisaka                       region->intra, region->qp_area_idx);
74*437bfbebSnyanmisaka             mpp_err_f("abs qp mode %d value %d\n",
75*437bfbebSnyanmisaka                       region->abs_qp_en, region->quality);
76*437bfbebSnyanmisaka             goto DONE;
77*437bfbebSnyanmisaka         }
78*437bfbebSnyanmisaka         reg_regions->roi_pos_lt.roi_lt_x = MPP_ALIGN(region->x, 16) >> 4;
79*437bfbebSnyanmisaka         reg_regions->roi_pos_lt.roi_lt_y = MPP_ALIGN(region->y, 16) >> 4;
80*437bfbebSnyanmisaka         reg_regions->roi_pos_rb.roi_rb_x = MPP_ALIGN(region->x + region->w, 16) >> 4;
81*437bfbebSnyanmisaka         reg_regions->roi_pos_rb.roi_rb_y = MPP_ALIGN(region->y + region->h, 16) >> 4;
82*437bfbebSnyanmisaka         reg_regions->roi_base.roi_qp_value = region->quality;
83*437bfbebSnyanmisaka         reg_regions->roi_base.roi_qp_adj_mode = region->abs_qp_en;
84*437bfbebSnyanmisaka         reg_regions->roi_base.roi_en = 1;
85*437bfbebSnyanmisaka         reg_regions->roi_base.roi_pri = 0x1f;
86*437bfbebSnyanmisaka         if (region->intra) {
87*437bfbebSnyanmisaka             reg_regions->roi_mdc.roi_mdc_intra16 = 1;
88*437bfbebSnyanmisaka             reg_regions->roi_mdc.roi0_mdc_intra32_hevc = 1;
89*437bfbebSnyanmisaka         }
90*437bfbebSnyanmisaka         reg_regions++;
91*437bfbebSnyanmisaka     }
92*437bfbebSnyanmisaka 
93*437bfbebSnyanmisaka DONE:
94*437bfbebSnyanmisaka     return ret;
95*437bfbebSnyanmisaka }
96*437bfbebSnyanmisaka 
vepu540c_jpeg_set_patch_info(MppDev dev,JpegeSyntax * syn,VepuFmt input_fmt,HalEncTask * task)97*437bfbebSnyanmisaka static MPP_RET vepu540c_jpeg_set_patch_info(MppDev dev, JpegeSyntax *syn,
98*437bfbebSnyanmisaka                                             VepuFmt input_fmt,
99*437bfbebSnyanmisaka                                             HalEncTask *task)
100*437bfbebSnyanmisaka {
101*437bfbebSnyanmisaka     RK_U32 hor_stride = syn->hor_stride;
102*437bfbebSnyanmisaka     RK_U32 ver_stride = syn->ver_stride ? syn->ver_stride : syn->height;
103*437bfbebSnyanmisaka     RK_U32 frame_size = hor_stride * ver_stride;
104*437bfbebSnyanmisaka     RK_U32 u_offset = 0, v_offset = 0;
105*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
106*437bfbebSnyanmisaka 
107*437bfbebSnyanmisaka     if (MPP_FRAME_FMT_IS_FBC(mpp_frame_get_fmt(task->frame))) {
108*437bfbebSnyanmisaka         u_offset = mpp_frame_get_fbc_offset(task->frame);
109*437bfbebSnyanmisaka         v_offset = 0;
110*437bfbebSnyanmisaka         mpp_log("fbc case u_offset = %d", u_offset);
111*437bfbebSnyanmisaka     } else {
112*437bfbebSnyanmisaka         switch (input_fmt) {
113*437bfbebSnyanmisaka         case VEPU5xx_FMT_YUV420P: {
114*437bfbebSnyanmisaka             u_offset = frame_size;
115*437bfbebSnyanmisaka             v_offset = frame_size * 5 / 4;
116*437bfbebSnyanmisaka         } break;
117*437bfbebSnyanmisaka         case VEPU5xx_FMT_YUV420SP:
118*437bfbebSnyanmisaka         case VEPU5xx_FMT_YUV422SP: {
119*437bfbebSnyanmisaka             u_offset = frame_size;
120*437bfbebSnyanmisaka             v_offset = frame_size;
121*437bfbebSnyanmisaka         } break;
122*437bfbebSnyanmisaka         case VEPU5xx_FMT_YUV422P: {
123*437bfbebSnyanmisaka             u_offset = frame_size;
124*437bfbebSnyanmisaka             v_offset = frame_size * 3 / 2;
125*437bfbebSnyanmisaka         } break;
126*437bfbebSnyanmisaka         case VEPU5xx_FMT_YUYV422:
127*437bfbebSnyanmisaka         case VEPU5xx_FMT_UYVY422: {
128*437bfbebSnyanmisaka             u_offset = 0;
129*437bfbebSnyanmisaka             v_offset = 0;
130*437bfbebSnyanmisaka         } break;
131*437bfbebSnyanmisaka         case VEPU5xx_FMT_BGR565:
132*437bfbebSnyanmisaka         case VEPU5xx_FMT_BGR888:
133*437bfbebSnyanmisaka         case VEPU5xx_FMT_BGRA8888: {
134*437bfbebSnyanmisaka             u_offset = 0;
135*437bfbebSnyanmisaka             v_offset = 0;
136*437bfbebSnyanmisaka         } break;
137*437bfbebSnyanmisaka         default: {
138*437bfbebSnyanmisaka             mpp_err("unknown color space: %d\n", input_fmt);
139*437bfbebSnyanmisaka             u_offset = frame_size;
140*437bfbebSnyanmisaka             v_offset = frame_size * 5 / 4;
141*437bfbebSnyanmisaka         }
142*437bfbebSnyanmisaka         }
143*437bfbebSnyanmisaka     }
144*437bfbebSnyanmisaka 
145*437bfbebSnyanmisaka     /* input cb addr */
146*437bfbebSnyanmisaka     if (u_offset)
147*437bfbebSnyanmisaka         mpp_dev_set_reg_offset(dev, 265, u_offset);
148*437bfbebSnyanmisaka 
149*437bfbebSnyanmisaka     /* input cr addr */
150*437bfbebSnyanmisaka     if (v_offset)
151*437bfbebSnyanmisaka         mpp_dev_set_reg_offset(dev, 266, v_offset);
152*437bfbebSnyanmisaka 
153*437bfbebSnyanmisaka     return ret;
154*437bfbebSnyanmisaka }
155*437bfbebSnyanmisaka 
156*437bfbebSnyanmisaka 
vepu540c_set_jpeg_reg(Vepu540cJpegCfg * cfg)157*437bfbebSnyanmisaka MPP_RET vepu540c_set_jpeg_reg(Vepu540cJpegCfg *cfg)
158*437bfbebSnyanmisaka {
159*437bfbebSnyanmisaka     HalEncTask *task = ( HalEncTask *)cfg->enc_task;
160*437bfbebSnyanmisaka     JpegeSyntax *syn = (JpegeSyntax *)task->syntax.data;
161*437bfbebSnyanmisaka     Vepu540cJpegReg *regs = (Vepu540cJpegReg *)cfg->jpeg_reg_base;
162*437bfbebSnyanmisaka     VepuFmtCfg *fmt = (VepuFmtCfg *)cfg->input_fmt;
163*437bfbebSnyanmisaka     RK_U32 pic_width_align8, pic_height_align8;
164*437bfbebSnyanmisaka     RK_S32 stridey = 0;
165*437bfbebSnyanmisaka     RK_S32 stridec = 0;
166*437bfbebSnyanmisaka 
167*437bfbebSnyanmisaka     pic_width_align8 = (syn->width + 7) & (~7);
168*437bfbebSnyanmisaka     pic_height_align8 = (syn->height + 7) & (~7);
169*437bfbebSnyanmisaka 
170*437bfbebSnyanmisaka     regs->reg0264_adr_src0 =  mpp_buffer_get_fd(task->input);
171*437bfbebSnyanmisaka     regs->reg0265_adr_src1 = regs->reg0264_adr_src0;
172*437bfbebSnyanmisaka     regs->reg0266_adr_src2 = regs->reg0264_adr_src0;
173*437bfbebSnyanmisaka 
174*437bfbebSnyanmisaka     vepu540c_jpeg_set_patch_info(cfg->dev, syn, (VepuFmt)fmt->format, task);
175*437bfbebSnyanmisaka 
176*437bfbebSnyanmisaka     regs->reg0256_adr_bsbt = mpp_buffer_get_fd(task->output);
177*437bfbebSnyanmisaka     regs->reg0257_adr_bsbb = regs->reg0256_adr_bsbt;
178*437bfbebSnyanmisaka     regs->reg0258_adr_bsbs = regs->reg0256_adr_bsbt;
179*437bfbebSnyanmisaka     regs->reg0259_adr_bsbr = regs->reg0256_adr_bsbt;
180*437bfbebSnyanmisaka 
181*437bfbebSnyanmisaka     mpp_dev_set_reg_offset(cfg->dev, 258, mpp_packet_get_length(task->packet));
182*437bfbebSnyanmisaka     mpp_dev_set_reg_offset(cfg->dev, 256, mpp_buffer_get_size(task->output));
183*437bfbebSnyanmisaka 
184*437bfbebSnyanmisaka     regs->reg0272_enc_rsl.pic_wd8_m1    = pic_width_align8 / 8 - 1;
185*437bfbebSnyanmisaka     regs->reg0273_src_fill.pic_wfill    = (syn->width & 0x7)
186*437bfbebSnyanmisaka                                           ? (8 - (syn->width & 0x7)) : 0;
187*437bfbebSnyanmisaka     regs->reg0272_enc_rsl.pic_hd8_m1    = pic_height_align8 / 8 - 1;
188*437bfbebSnyanmisaka     regs->reg0273_src_fill.pic_hfill    = (syn->height & 0x7)
189*437bfbebSnyanmisaka                                           ? (8 - (syn->height & 0x7)) : 0;
190*437bfbebSnyanmisaka 
191*437bfbebSnyanmisaka     regs->reg0274_src_fmt.src_cfmt = fmt->format;
192*437bfbebSnyanmisaka     regs->reg0274_src_fmt.alpha_swap = fmt->alpha_swap;
193*437bfbebSnyanmisaka     regs->reg0274_src_fmt.rbuv_swap  = fmt->rbuv_swap;
194*437bfbebSnyanmisaka     regs->reg0274_src_fmt.src_range_trns_en  = 0;
195*437bfbebSnyanmisaka     regs->reg0274_src_fmt.src_range_trns_sel = 0;
196*437bfbebSnyanmisaka     regs->reg0274_src_fmt.chroma_ds_mode     = 0;
197*437bfbebSnyanmisaka     regs->reg0274_src_fmt.out_fmt = 1;
198*437bfbebSnyanmisaka 
199*437bfbebSnyanmisaka     regs->reg0279_src_proc.src_mirr = 0 ;//prep_cfg->mirroring > 0;
200*437bfbebSnyanmisaka     regs->reg0279_src_proc.src_rot = syn->rotation;
201*437bfbebSnyanmisaka 
202*437bfbebSnyanmisaka     if (syn->hor_stride) {
203*437bfbebSnyanmisaka         stridey = syn->hor_stride;
204*437bfbebSnyanmisaka     } else {
205*437bfbebSnyanmisaka         if (regs->reg0274_src_fmt.src_cfmt == VEPU5xx_FMT_BGRA8888)
206*437bfbebSnyanmisaka             stridey = syn->width * 4;
207*437bfbebSnyanmisaka         else if (regs->reg0274_src_fmt.src_cfmt == VEPU5xx_FMT_BGR888)
208*437bfbebSnyanmisaka             stridey = syn->width * 3;
209*437bfbebSnyanmisaka         else if (regs->reg0274_src_fmt.src_cfmt == VEPU5xx_FMT_BGR565 ||
210*437bfbebSnyanmisaka                  regs->reg0274_src_fmt.src_cfmt == VEPU5xx_FMT_YUYV422 ||
211*437bfbebSnyanmisaka                  regs->reg0274_src_fmt.src_cfmt == VEPU5xx_FMT_UYVY422)
212*437bfbebSnyanmisaka             stridey = syn->width * 2;
213*437bfbebSnyanmisaka     }
214*437bfbebSnyanmisaka 
215*437bfbebSnyanmisaka     stridec = (regs->reg0274_src_fmt.src_cfmt == VEPU5xx_FMT_YUV422SP ||
216*437bfbebSnyanmisaka                regs->reg0274_src_fmt.src_cfmt == VEPU5xx_FMT_YUV420SP) ?
217*437bfbebSnyanmisaka               stridey : stridey / 2;
218*437bfbebSnyanmisaka 
219*437bfbebSnyanmisaka     if (regs->reg0274_src_fmt.src_cfmt < VEPU5xx_FMT_ARGB1555) {
220*437bfbebSnyanmisaka         regs->reg0275_src_udfy.csc_wgt_r2y = 66;
221*437bfbebSnyanmisaka         regs->reg0275_src_udfy.csc_wgt_g2y = 129;
222*437bfbebSnyanmisaka         regs->reg0275_src_udfy.csc_wgt_b2y = 25;
223*437bfbebSnyanmisaka 
224*437bfbebSnyanmisaka         regs->reg0276_src_udfu.csc_wgt_r2u = -38;
225*437bfbebSnyanmisaka         regs->reg0276_src_udfu.csc_wgt_g2u = -74;
226*437bfbebSnyanmisaka         regs->reg0276_src_udfu.csc_wgt_b2u = 112;
227*437bfbebSnyanmisaka 
228*437bfbebSnyanmisaka         regs->reg0277_src_udfv.csc_wgt_r2v = 112;
229*437bfbebSnyanmisaka         regs->reg0277_src_udfv.csc_wgt_g2v = -94;
230*437bfbebSnyanmisaka         regs->reg0277_src_udfv.csc_wgt_b2v = -18;
231*437bfbebSnyanmisaka 
232*437bfbebSnyanmisaka         regs->reg0278_src_udfo.csc_ofst_y = 16;
233*437bfbebSnyanmisaka         regs->reg0278_src_udfo.csc_ofst_u = 128;
234*437bfbebSnyanmisaka         regs->reg0278_src_udfo.csc_ofst_v = 128;
235*437bfbebSnyanmisaka     }
236*437bfbebSnyanmisaka     regs->reg0281_src_strd0.src_strd0  = stridey;
237*437bfbebSnyanmisaka     regs->reg0282_src_strd1.src_strd1  = stridec;
238*437bfbebSnyanmisaka     regs->reg0280_pic_ofst.pic_ofst_y = mpp_frame_get_offset_y(task->frame);
239*437bfbebSnyanmisaka     regs->reg0280_pic_ofst.pic_ofst_x = mpp_frame_get_offset_x(task->frame);
240*437bfbebSnyanmisaka     //to be done
241*437bfbebSnyanmisaka 
242*437bfbebSnyanmisaka     // no 0283 ?
243*437bfbebSnyanmisaka     // regs->reg0283_src_flt.pp_corner_filter_strength = 0;
244*437bfbebSnyanmisaka     // regs->reg0283_src_flt.pp_edge_filter_strength = 0;
245*437bfbebSnyanmisaka     // regs->reg0283_src_flt.pp_internal_filter_strength = 0;
246*437bfbebSnyanmisaka 
247*437bfbebSnyanmisaka     regs->reg0284_y_cfg.bias_y = 0;
248*437bfbebSnyanmisaka     regs->reg0285_u_cfg.bias_u = 0;
249*437bfbebSnyanmisaka     regs->reg0286_v_cfg.bias_v = 0;
250*437bfbebSnyanmisaka 
251*437bfbebSnyanmisaka     regs->reg0287_base_cfg.jpeg_ri  = 0;
252*437bfbebSnyanmisaka     regs->reg0287_base_cfg.jpeg_out_mode = 0;
253*437bfbebSnyanmisaka     regs->reg0287_base_cfg.jpeg_start_rst_m = 0;
254*437bfbebSnyanmisaka     regs->reg0287_base_cfg.jpeg_pic_last_ecs = 1;
255*437bfbebSnyanmisaka     regs->reg0287_base_cfg.jpeg_slen_fifo = 0;
256*437bfbebSnyanmisaka     regs->reg0287_base_cfg.jpeg_stnd = 1; //enable
257*437bfbebSnyanmisaka 
258*437bfbebSnyanmisaka     regs->reg0288_uvc_cfg.uvc_partition0_len = 0;
259*437bfbebSnyanmisaka     regs->reg0288_uvc_cfg.uvc_partition_len = 0;
260*437bfbebSnyanmisaka     regs->reg0288_uvc_cfg.uvc_skip_len = 0;
261*437bfbebSnyanmisaka     return MPP_OK;
262*437bfbebSnyanmisaka }
263