xref: /rockchip-linux_mpp/mpp/hal/rkenc/common/vepu580_common.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /* SPDX-License-Identifier: Apache-2.0 */
2*437bfbebSnyanmisaka /*
3*437bfbebSnyanmisaka  * Copyright (c) 2025 Rockchip Electronics Co., Ltd.
4*437bfbebSnyanmisaka  */
5*437bfbebSnyanmisaka 
6*437bfbebSnyanmisaka #define MODULE_TAG  "vepu580_common"
7*437bfbebSnyanmisaka 
8*437bfbebSnyanmisaka #include "mpp_debug.h"
9*437bfbebSnyanmisaka #include "vepu580_common.h"
10*437bfbebSnyanmisaka 
vepu580_set_osd(Vepu5xxOsdCfg * cfg)11*437bfbebSnyanmisaka MPP_RET vepu580_set_osd(Vepu5xxOsdCfg *cfg)
12*437bfbebSnyanmisaka {
13*437bfbebSnyanmisaka     Vepu580OsdReg *regs = (Vepu580OsdReg *)cfg->reg_base;
14*437bfbebSnyanmisaka     MppDev dev = cfg->dev;
15*437bfbebSnyanmisaka     MppDevRegOffCfgs *reg_cfg = cfg->reg_cfg;
16*437bfbebSnyanmisaka     MppEncOSDPltCfg *plt_cfg = cfg->plt_cfg;
17*437bfbebSnyanmisaka     MppEncOSDData2 osd;
18*437bfbebSnyanmisaka 
19*437bfbebSnyanmisaka     if (copy2osd2(&osd, cfg->osd_data, cfg->osd_data2))
20*437bfbebSnyanmisaka         return MPP_NOK;
21*437bfbebSnyanmisaka 
22*437bfbebSnyanmisaka     if (osd.num_region == 0)
23*437bfbebSnyanmisaka         return MPP_OK;
24*437bfbebSnyanmisaka 
25*437bfbebSnyanmisaka     if (osd.num_region > 8) {
26*437bfbebSnyanmisaka         mpp_err_f("do NOT support more than 8 regions invalid num %d\n",
27*437bfbebSnyanmisaka                   osd.num_region);
28*437bfbebSnyanmisaka         mpp_assert(osd.num_region <= 8);
29*437bfbebSnyanmisaka         return MPP_NOK;
30*437bfbebSnyanmisaka     }
31*437bfbebSnyanmisaka 
32*437bfbebSnyanmisaka     if (plt_cfg->type == MPP_ENC_OSD_PLT_TYPE_USERDEF) {
33*437bfbebSnyanmisaka         memcpy(regs->plt_data, plt_cfg->plt, sizeof(MppEncOSDPlt));
34*437bfbebSnyanmisaka         regs->reg3074.osd_plt_cks = 1;
35*437bfbebSnyanmisaka         regs->reg3074.osd_plt_typ = VEPU5xx_OSD_PLT_TYPE_USERDEF;
36*437bfbebSnyanmisaka     } else {
37*437bfbebSnyanmisaka         regs->reg3074.osd_plt_cks = 0;
38*437bfbebSnyanmisaka         regs->reg3074.osd_plt_typ = VEPU5xx_OSD_PLT_TYPE_DEFAULT;
39*437bfbebSnyanmisaka     }
40*437bfbebSnyanmisaka 
41*437bfbebSnyanmisaka     regs->reg3074.osd_e = 0;
42*437bfbebSnyanmisaka     regs->reg3072.osd_lu_inv_en = 0;
43*437bfbebSnyanmisaka     regs->reg3072.osd_ch_inv_en = 0;
44*437bfbebSnyanmisaka     regs->reg3072.osd_lu_inv_msk = 0;
45*437bfbebSnyanmisaka     regs->reg3072.osd_ch_inv_msk = 0;
46*437bfbebSnyanmisaka 
47*437bfbebSnyanmisaka     RK_U32 num = osd.num_region;
48*437bfbebSnyanmisaka     RK_U32 k = 0;
49*437bfbebSnyanmisaka     MppEncOSDRegion2 *region = osd.region;
50*437bfbebSnyanmisaka     MppEncOSDRegion2 *tmp = region;
51*437bfbebSnyanmisaka 
52*437bfbebSnyanmisaka     for (k = 0; k < num; k++, tmp++) {
53*437bfbebSnyanmisaka         regs->reg3074.osd_e          |= tmp->enable << k;
54*437bfbebSnyanmisaka         regs->reg3072.osd_lu_inv_en  |= (tmp->inverse) ? (1 << k) : 0;
55*437bfbebSnyanmisaka         regs->reg3072.osd_ch_inv_en  |= (tmp->inverse) ? (1 << k) : 0;
56*437bfbebSnyanmisaka 
57*437bfbebSnyanmisaka         if (tmp->enable && tmp->num_mb_x && tmp->num_mb_y) {
58*437bfbebSnyanmisaka             Vepu580OsdPos *pos = &regs->osd_pos[k];
59*437bfbebSnyanmisaka             size_t blk_len = tmp->num_mb_x * tmp->num_mb_y * 256;
60*437bfbebSnyanmisaka             RK_S32 fd = -1;
61*437bfbebSnyanmisaka             size_t buf_size = 0;
62*437bfbebSnyanmisaka 
63*437bfbebSnyanmisaka             pos->osd_lt_x = tmp->start_mb_x;
64*437bfbebSnyanmisaka             pos->osd_lt_y = tmp->start_mb_y;
65*437bfbebSnyanmisaka             pos->osd_rb_x = tmp->start_mb_x + tmp->num_mb_x - 1;
66*437bfbebSnyanmisaka             pos->osd_rb_y = tmp->start_mb_y + tmp->num_mb_y - 1;
67*437bfbebSnyanmisaka 
68*437bfbebSnyanmisaka             buf_size = mpp_buffer_get_size(tmp->buf);
69*437bfbebSnyanmisaka             fd = mpp_buffer_get_fd(tmp->buf);
70*437bfbebSnyanmisaka             if (fd < 0) {
71*437bfbebSnyanmisaka                 mpp_err_f("invalid osd buffer fd %d\n", fd);
72*437bfbebSnyanmisaka                 return MPP_NOK;
73*437bfbebSnyanmisaka             }
74*437bfbebSnyanmisaka             regs->osd_addr[k] = fd;
75*437bfbebSnyanmisaka 
76*437bfbebSnyanmisaka             if (tmp->buf_offset) {
77*437bfbebSnyanmisaka                 if (reg_cfg)
78*437bfbebSnyanmisaka                     mpp_dev_multi_offset_update(reg_cfg, VEPU580_OSD_ADDR_IDX_BASE + k, tmp->buf_offset);
79*437bfbebSnyanmisaka                 else
80*437bfbebSnyanmisaka                     mpp_dev_set_reg_offset(dev, VEPU580_OSD_ADDR_IDX_BASE + k, tmp->buf_offset);
81*437bfbebSnyanmisaka             }
82*437bfbebSnyanmisaka 
83*437bfbebSnyanmisaka             /* There should be enough buffer and offset should be 16B aligned */
84*437bfbebSnyanmisaka             if (buf_size < tmp->buf_offset + blk_len ||
85*437bfbebSnyanmisaka                 (tmp->buf_offset & 0xf)) {
86*437bfbebSnyanmisaka                 mpp_err_f("invalid osd cfg: %d x:y:w:h:off %d:%d:%d:%d:%x size %x\n",
87*437bfbebSnyanmisaka                           k, tmp->start_mb_x, tmp->start_mb_y,
88*437bfbebSnyanmisaka                           tmp->num_mb_x, tmp->num_mb_y, tmp->buf_offset, buf_size);
89*437bfbebSnyanmisaka             }
90*437bfbebSnyanmisaka         }
91*437bfbebSnyanmisaka     }
92*437bfbebSnyanmisaka 
93*437bfbebSnyanmisaka     SET_OSD_INV_THR(0, regs->reg3073, region);
94*437bfbebSnyanmisaka     SET_OSD_INV_THR(1, regs->reg3073, region);
95*437bfbebSnyanmisaka     SET_OSD_INV_THR(2, regs->reg3073, region);
96*437bfbebSnyanmisaka     SET_OSD_INV_THR(3, regs->reg3073, region);
97*437bfbebSnyanmisaka     SET_OSD_INV_THR(4, regs->reg3073, region);
98*437bfbebSnyanmisaka     SET_OSD_INV_THR(5, regs->reg3073, region);
99*437bfbebSnyanmisaka     SET_OSD_INV_THR(6, regs->reg3073, region);
100*437bfbebSnyanmisaka     SET_OSD_INV_THR(7, regs->reg3073, region);
101*437bfbebSnyanmisaka 
102*437bfbebSnyanmisaka     return MPP_OK;
103*437bfbebSnyanmisaka }
104