1145e9363SMing Qian // SPDX-License-Identifier: GPL-2.0 2145e9363SMing Qian /* 3145e9363SMing Qian * Copyright 2020-2021 NXP 4145e9363SMing Qian */ 5145e9363SMing Qian 6145e9363SMing Qian #include <linux/init.h> 7145e9363SMing Qian #include <linux/interconnect.h> 8145e9363SMing Qian #include <linux/ioctl.h> 9145e9363SMing Qian #include <linux/list.h> 10145e9363SMing Qian #include <linux/kernel.h> 11145e9363SMing Qian #include <linux/module.h> 12145e9363SMing Qian #include <linux/of_device.h> 13145e9363SMing Qian #include <linux/of_address.h> 14145e9363SMing Qian #include <linux/platform_device.h> 15145e9363SMing Qian #include <linux/delay.h> 16145e9363SMing Qian #include <linux/rational.h> 1705a03effSMing Qian #include <linux/time64.h> 18145e9363SMing Qian #include <media/videobuf2-v4l2.h> 19145e9363SMing Qian #include <media/videobuf2-dma-contig.h> 20145e9363SMing Qian #include <linux/videodev2.h> 21145e9363SMing Qian #include "vpu.h" 22145e9363SMing Qian #include "vpu_rpc.h" 23145e9363SMing Qian #include "vpu_defs.h" 24145e9363SMing Qian #include "vpu_helpers.h" 25145e9363SMing Qian #include "vpu_v4l2.h" 26145e9363SMing Qian #include "vpu_cmds.h" 27145e9363SMing Qian #include "vpu_imx8q.h" 28145e9363SMing Qian #include "vpu_malone.h" 29145e9363SMing Qian 30145e9363SMing Qian #define CMD_SIZE 25600 31145e9363SMing Qian #define MSG_SIZE 25600 32145e9363SMing Qian #define CODEC_SIZE 0x1000 33145e9363SMing Qian #define JPEG_SIZE 0x1000 34145e9363SMing Qian #define SEQ_SIZE 0x1000 35145e9363SMing Qian #define GOP_SIZE 0x1000 36145e9363SMing Qian #define PIC_SIZE 0x1000 37145e9363SMing Qian #define QMETER_SIZE 0x1000 38145e9363SMing Qian #define DBGLOG_SIZE 0x10000 39145e9363SMing Qian #define DEBUG_SIZE 0x80000 40145e9363SMing Qian #define ENG_SIZE 0x1000 41145e9363SMing Qian #define MALONE_SKIPPED_FRAME_ID 0x555 42145e9363SMing Qian 43145e9363SMing Qian #define MALONE_ALIGN_MBI 0x800 44145e9363SMing Qian #define MALONE_DCP_CHUNK_BIT 16 45145e9363SMing Qian #define MALONE_DCP_SIZE_MAX 0x3000000 46145e9363SMing Qian #define MALONE_DCP_SIZE_MIN 0x100000 47145e9363SMing Qian #define MALONE_DCP_FIXED_MB_ALLOC 250 48145e9363SMing Qian 49145e9363SMing Qian #define CONFIG_SET(val, cfg, pos, mask) \ 50145e9363SMing Qian (*(cfg) |= (((val) << (pos)) & (mask))) 51145e9363SMing Qian //x means source data , y means destination data 52145e9363SMing Qian #define STREAM_CONFIG_FORMAT_SET(x, y) CONFIG_SET(x, y, 0, 0x0000000F) 53145e9363SMing Qian #define STREAM_CONFIG_STRBUFIDX_SET(x, y) CONFIG_SET(x, y, 8, 0x00000300) 54145e9363SMing Qian #define STREAM_CONFIG_NOSEQ_SET(x, y) CONFIG_SET(x, y, 10, 0x00000400) 55145e9363SMing Qian #define STREAM_CONFIG_DEBLOCK_SET(x, y) CONFIG_SET(x, y, 11, 0x00000800) 56145e9363SMing Qian #define STREAM_CONFIG_DERING_SET(x, y) CONFIG_SET(x, y, 12, 0x00001000) 57145e9363SMing Qian #define STREAM_CONFIG_IBWAIT_SET(x, y) CONFIG_SET(x, y, 13, 0x00002000) 58145e9363SMing Qian #define STREAM_CONFIG_FBC_SET(x, y) CONFIG_SET(x, y, 14, 0x00004000) 59145e9363SMing Qian #define STREAM_CONFIG_PLAY_MODE_SET(x, y) CONFIG_SET(x, y, 16, 0x00030000) 60145e9363SMing Qian #define STREAM_CONFIG_ENABLE_DCP_SET(x, y) CONFIG_SET(x, y, 20, 0x00100000) 61145e9363SMing Qian #define STREAM_CONFIG_NUM_STR_BUF_SET(x, y) CONFIG_SET(x, y, 21, 0x00600000) 62145e9363SMing Qian #define STREAM_CONFIG_MALONE_USAGE_SET(x, y) CONFIG_SET(x, y, 23, 0x01800000) 63145e9363SMing Qian #define STREAM_CONFIG_MULTI_VID_SET(x, y) CONFIG_SET(x, y, 25, 0x02000000) 64145e9363SMing Qian #define STREAM_CONFIG_OBFUSC_EN_SET(x, y) CONFIG_SET(x, y, 26, 0x04000000) 65145e9363SMing Qian #define STREAM_CONFIG_RC4_EN_SET(x, y) CONFIG_SET(x, y, 27, 0x08000000) 66145e9363SMing Qian #define STREAM_CONFIG_MCX_SET(x, y) CONFIG_SET(x, y, 28, 0x10000000) 67145e9363SMing Qian #define STREAM_CONFIG_PES_SET(x, y) CONFIG_SET(x, y, 29, 0x20000000) 68145e9363SMing Qian #define STREAM_CONFIG_NUM_DBE_SET(x, y) CONFIG_SET(x, y, 30, 0x40000000) 69145e9363SMing Qian #define STREAM_CONFIG_FS_CTRL_MODE_SET(x, y) CONFIG_SET(x, y, 31, 0x80000000) 70145e9363SMing Qian 713b514e79SMing Qian #define MALONE_DEC_FMT_RV_MASK BIT(21) 723b514e79SMing Qian 73145e9363SMing Qian enum vpu_malone_stream_input_mode { 74145e9363SMing Qian INVALID_MODE = 0, 75145e9363SMing Qian FRAME_LVL, 76145e9363SMing Qian NON_FRAME_LVL 77145e9363SMing Qian }; 78145e9363SMing Qian 79145e9363SMing Qian enum vpu_malone_format { 80145e9363SMing Qian MALONE_FMT_NULL = 0x0, 81145e9363SMing Qian MALONE_FMT_AVC = 0x1, 82145e9363SMing Qian MALONE_FMT_MP2 = 0x2, 83145e9363SMing Qian MALONE_FMT_VC1 = 0x3, 84145e9363SMing Qian MALONE_FMT_AVS = 0x4, 85145e9363SMing Qian MALONE_FMT_ASP = 0x5, 86145e9363SMing Qian MALONE_FMT_JPG = 0x6, 87145e9363SMing Qian MALONE_FMT_RV = 0x7, 88145e9363SMing Qian MALONE_FMT_VP6 = 0x8, 89145e9363SMing Qian MALONE_FMT_SPK = 0x9, 90145e9363SMing Qian MALONE_FMT_VP8 = 0xA, 91145e9363SMing Qian MALONE_FMT_HEVC = 0xB, 92145e9363SMing Qian MALONE_FMT_LAST = MALONE_FMT_HEVC 93145e9363SMing Qian }; 94145e9363SMing Qian 95145e9363SMing Qian enum { 96145e9363SMing Qian VID_API_CMD_NULL = 0x00, 97145e9363SMing Qian VID_API_CMD_PARSE_NEXT_SEQ = 0x01, 98145e9363SMing Qian VID_API_CMD_PARSE_NEXT_I = 0x02, 99145e9363SMing Qian VID_API_CMD_PARSE_NEXT_IP = 0x03, 100145e9363SMing Qian VID_API_CMD_PARSE_NEXT_ANY = 0x04, 101145e9363SMing Qian VID_API_CMD_DEC_PIC = 0x05, 102145e9363SMing Qian VID_API_CMD_UPDATE_ES_WR_PTR = 0x06, 103145e9363SMing Qian VID_API_CMD_UPDATE_ES_RD_PTR = 0x07, 104145e9363SMing Qian VID_API_CMD_UPDATE_UDATA = 0x08, 105145e9363SMing Qian VID_API_CMD_GET_FSINFO = 0x09, 106145e9363SMing Qian VID_API_CMD_SKIP_PIC = 0x0a, 107145e9363SMing Qian VID_API_CMD_DEC_CHUNK = 0x0b, 108145e9363SMing Qian VID_API_CMD_START = 0x10, 109145e9363SMing Qian VID_API_CMD_STOP = 0x11, 110145e9363SMing Qian VID_API_CMD_ABORT = 0x12, 111145e9363SMing Qian VID_API_CMD_RST_BUF = 0x13, 112145e9363SMing Qian VID_API_CMD_FS_RELEASE = 0x15, 113145e9363SMing Qian VID_API_CMD_MEM_REGION_ATTACH = 0x16, 114145e9363SMing Qian VID_API_CMD_MEM_REGION_DETACH = 0x17, 115145e9363SMing Qian VID_API_CMD_MVC_VIEW_SELECT = 0x18, 116145e9363SMing Qian VID_API_CMD_FS_ALLOC = 0x19, 117145e9363SMing Qian VID_API_CMD_DBG_GET_STATUS = 0x1C, 118145e9363SMing Qian VID_API_CMD_DBG_START_LOG = 0x1D, 119145e9363SMing Qian VID_API_CMD_DBG_STOP_LOG = 0x1E, 120145e9363SMing Qian VID_API_CMD_DBG_DUMP_LOG = 0x1F, 121145e9363SMing Qian VID_API_CMD_YUV_READY = 0x20, 122145e9363SMing Qian VID_API_CMD_TS = 0x21, 123145e9363SMing Qian 124145e9363SMing Qian VID_API_CMD_FIRM_RESET = 0x40, 125145e9363SMing Qian 126145e9363SMing Qian VID_API_CMD_SNAPSHOT = 0xAA, 127145e9363SMing Qian VID_API_CMD_ROLL_SNAPSHOT = 0xAB, 128145e9363SMing Qian VID_API_CMD_LOCK_SCHEDULER = 0xAC, 129145e9363SMing Qian VID_API_CMD_UNLOCK_SCHEDULER = 0xAD, 130145e9363SMing Qian VID_API_CMD_CQ_FIFO_DUMP = 0xAE, 131145e9363SMing Qian VID_API_CMD_DBG_FIFO_DUMP = 0xAF, 132145e9363SMing Qian VID_API_CMD_SVC_ILP = 0xBB, 133145e9363SMing Qian VID_API_CMD_FW_STATUS = 0xF0, 134145e9363SMing Qian VID_API_CMD_INVALID = 0xFF 135145e9363SMing Qian }; 136145e9363SMing Qian 137145e9363SMing Qian enum { 138145e9363SMing Qian VID_API_EVENT_NULL = 0x00, 139145e9363SMing Qian VID_API_EVENT_RESET_DONE = 0x01, 140145e9363SMing Qian VID_API_EVENT_SEQ_HDR_FOUND = 0x02, 141145e9363SMing Qian VID_API_EVENT_PIC_HDR_FOUND = 0x03, 142145e9363SMing Qian VID_API_EVENT_PIC_DECODED = 0x04, 143145e9363SMing Qian VID_API_EVENT_FIFO_LOW = 0x05, 144145e9363SMing Qian VID_API_EVENT_FIFO_HIGH = 0x06, 145145e9363SMing Qian VID_API_EVENT_FIFO_EMPTY = 0x07, 146145e9363SMing Qian VID_API_EVENT_FIFO_FULL = 0x08, 147145e9363SMing Qian VID_API_EVENT_BS_ERROR = 0x09, 148145e9363SMing Qian VID_API_EVENT_UDATA_FIFO_UPTD = 0x0A, 149145e9363SMing Qian VID_API_EVENT_RES_CHANGE = 0x0B, 150145e9363SMing Qian VID_API_EVENT_FIFO_OVF = 0x0C, 151145e9363SMing Qian VID_API_EVENT_CHUNK_DECODED = 0x0D, 152145e9363SMing Qian VID_API_EVENT_REQ_FRAME_BUFF = 0x10, 153145e9363SMing Qian VID_API_EVENT_FRAME_BUFF_RDY = 0x11, 154145e9363SMing Qian VID_API_EVENT_REL_FRAME_BUFF = 0x12, 155145e9363SMing Qian VID_API_EVENT_STR_BUF_RST = 0x13, 156145e9363SMing Qian VID_API_EVENT_RET_PING = 0x14, 157145e9363SMing Qian VID_API_EVENT_QMETER = 0x15, 158145e9363SMing Qian VID_API_EVENT_STR_FMT_CHANGE = 0x16, 159145e9363SMing Qian VID_API_EVENT_FIRMWARE_XCPT = 0x17, 160145e9363SMing Qian VID_API_EVENT_START_DONE = 0x18, 161145e9363SMing Qian VID_API_EVENT_STOPPED = 0x19, 162145e9363SMing Qian VID_API_EVENT_ABORT_DONE = 0x1A, 163145e9363SMing Qian VID_API_EVENT_FINISHED = 0x1B, 164145e9363SMing Qian VID_API_EVENT_DBG_STAT_UPDATE = 0x1C, 165145e9363SMing Qian VID_API_EVENT_DBG_LOG_STARTED = 0x1D, 166145e9363SMing Qian VID_API_EVENT_DBG_LOG_STOPPED = 0x1E, 167145e9363SMing Qian VID_API_EVENT_DBG_LOG_UPDATED = 0x1F, 168145e9363SMing Qian VID_API_EVENT_DBG_MSG_DEC = 0x20, 169145e9363SMing Qian VID_API_EVENT_DEC_SC_ERR = 0x21, 170145e9363SMing Qian VID_API_EVENT_CQ_FIFO_DUMP = 0x22, 171145e9363SMing Qian VID_API_EVENT_DBG_FIFO_DUMP = 0x23, 172145e9363SMing Qian VID_API_EVENT_DEC_CHECK_RES = 0x24, 173145e9363SMing Qian VID_API_EVENT_DEC_CFG_INFO = 0x25, 174145e9363SMing Qian VID_API_EVENT_UNSUPPORTED_STREAM = 0x26, 175be9fd510SMing Qian VID_API_EVENT_PIC_SKIPPED = 0x27, 176145e9363SMing Qian VID_API_EVENT_STR_SUSPENDED = 0x30, 177145e9363SMing Qian VID_API_EVENT_SNAPSHOT_DONE = 0x40, 178145e9363SMing Qian VID_API_EVENT_FW_STATUS = 0xF0, 179145e9363SMing Qian VID_API_EVENT_INVALID = 0xFF 180145e9363SMing Qian }; 181145e9363SMing Qian 182145e9363SMing Qian struct vpu_malone_buffer_desc { 183145e9363SMing Qian struct vpu_rpc_buffer_desc buffer; 184145e9363SMing Qian u32 low; 185145e9363SMing Qian u32 high; 186145e9363SMing Qian }; 187145e9363SMing Qian 188145e9363SMing Qian struct vpu_malone_str_buffer { 189145e9363SMing Qian u32 wptr; 190145e9363SMing Qian u32 rptr; 191145e9363SMing Qian u32 start; 192145e9363SMing Qian u32 end; 193145e9363SMing Qian u32 lwm; 194145e9363SMing Qian }; 195145e9363SMing Qian 196145e9363SMing Qian struct vpu_malone_picth_info { 197145e9363SMing Qian u32 frame_pitch; 198145e9363SMing Qian }; 199145e9363SMing Qian 200145e9363SMing Qian struct vpu_malone_table_desc { 201145e9363SMing Qian u32 array_base; 202145e9363SMing Qian u32 size; 203145e9363SMing Qian }; 204145e9363SMing Qian 205145e9363SMing Qian struct vpu_malone_dbglog_desc { 206145e9363SMing Qian u32 addr; 207145e9363SMing Qian u32 size; 208145e9363SMing Qian u32 level; 209145e9363SMing Qian u32 reserved; 210145e9363SMing Qian }; 211145e9363SMing Qian 212145e9363SMing Qian struct vpu_malone_frame_buffer { 213145e9363SMing Qian u32 addr; 214145e9363SMing Qian u32 size; 215145e9363SMing Qian }; 216145e9363SMing Qian 217145e9363SMing Qian struct vpu_malone_udata { 218145e9363SMing Qian u32 base; 219145e9363SMing Qian u32 total_size; 220145e9363SMing Qian u32 slot_size; 221145e9363SMing Qian }; 222145e9363SMing Qian 223145e9363SMing Qian struct vpu_malone_buffer_info { 224145e9363SMing Qian u32 stream_input_mode; 225145e9363SMing Qian u32 stream_pic_input_count; 226145e9363SMing Qian u32 stream_pic_parsed_count; 227145e9363SMing Qian u32 stream_buffer_threshold; 228145e9363SMing Qian u32 stream_pic_end_flag; 229145e9363SMing Qian }; 230145e9363SMing Qian 231145e9363SMing Qian struct vpu_malone_encrypt_info { 232145e9363SMing Qian u32 rec4key[8]; 233145e9363SMing Qian u32 obfusc; 234145e9363SMing Qian }; 235145e9363SMing Qian 236145e9363SMing Qian struct malone_iface { 237145e9363SMing Qian u32 exec_base_addr; 238145e9363SMing Qian u32 exec_area_size; 239145e9363SMing Qian struct vpu_malone_buffer_desc cmd_buffer_desc; 240145e9363SMing Qian struct vpu_malone_buffer_desc msg_buffer_desc; 241145e9363SMing Qian u32 cmd_int_enable[VID_API_NUM_STREAMS]; 242145e9363SMing Qian struct vpu_malone_picth_info stream_pitch_info[VID_API_NUM_STREAMS]; 243145e9363SMing Qian u32 stream_config[VID_API_NUM_STREAMS]; 244145e9363SMing Qian struct vpu_malone_table_desc codec_param_tab_desc; 245145e9363SMing Qian struct vpu_malone_table_desc jpeg_param_tab_desc; 246145e9363SMing Qian u32 stream_buffer_desc[VID_API_NUM_STREAMS][VID_API_MAX_BUF_PER_STR]; 247145e9363SMing Qian struct vpu_malone_table_desc seq_info_tab_desc; 248145e9363SMing Qian struct vpu_malone_table_desc pic_info_tab_desc; 249145e9363SMing Qian struct vpu_malone_table_desc gop_info_tab_desc; 250145e9363SMing Qian struct vpu_malone_table_desc qmeter_info_tab_desc; 251145e9363SMing Qian u32 stream_error[VID_API_NUM_STREAMS]; 252145e9363SMing Qian u32 fw_version; 253145e9363SMing Qian u32 fw_offset; 254145e9363SMing Qian u32 max_streams; 255145e9363SMing Qian struct vpu_malone_dbglog_desc dbglog_desc; 256145e9363SMing Qian struct vpu_rpc_buffer_desc api_cmd_buffer_desc[VID_API_NUM_STREAMS]; 257145e9363SMing Qian struct vpu_malone_udata udata_buffer[VID_API_NUM_STREAMS]; 258145e9363SMing Qian struct vpu_malone_buffer_desc debug_buffer_desc; 259145e9363SMing Qian struct vpu_malone_buffer_desc eng_access_buff_desc[VID_API_NUM_STREAMS]; 260145e9363SMing Qian u32 encrypt_info[VID_API_NUM_STREAMS]; 261145e9363SMing Qian struct vpu_rpc_system_config system_cfg; 262145e9363SMing Qian u32 api_version; 263145e9363SMing Qian struct vpu_malone_buffer_info stream_buff_info[VID_API_NUM_STREAMS]; 264145e9363SMing Qian }; 265145e9363SMing Qian 266145e9363SMing Qian struct malone_jpg_params { 267145e9363SMing Qian u32 rotation_angle; 268145e9363SMing Qian u32 horiz_scale_factor; 269145e9363SMing Qian u32 vert_scale_factor; 270145e9363SMing Qian u32 rotation_mode; 271145e9363SMing Qian u32 rgb_mode; 272145e9363SMing Qian u32 chunk_mode; /* 0 ~ 1 */ 273145e9363SMing Qian u32 last_chunk; /* 0 ~ 1 */ 274145e9363SMing Qian u32 chunk_rows; /* 0 ~ 255 */ 275145e9363SMing Qian u32 num_bytes; 276145e9363SMing Qian u32 jpg_crop_x; 277145e9363SMing Qian u32 jpg_crop_y; 278145e9363SMing Qian u32 jpg_crop_width; 279145e9363SMing Qian u32 jpg_crop_height; 280145e9363SMing Qian u32 jpg_mjpeg_mode; 281145e9363SMing Qian u32 jpg_mjpeg_interlaced; 282145e9363SMing Qian }; 283145e9363SMing Qian 284145e9363SMing Qian struct malone_codec_params { 285145e9363SMing Qian u32 disp_imm; 286145e9363SMing Qian u32 fourcc; 287145e9363SMing Qian u32 codec_version; 288145e9363SMing Qian u32 frame_rate; 289145e9363SMing Qian u32 dbglog_enable; 290145e9363SMing Qian u32 bsdma_lwm; 291145e9363SMing Qian u32 bbd_coring; 292145e9363SMing Qian u32 bbd_s_thr_row; 293145e9363SMing Qian u32 bbd_p_thr_row; 294145e9363SMing Qian u32 bbd_s_thr_logo_row; 295145e9363SMing Qian u32 bbd_p_thr_logo_row; 296145e9363SMing Qian u32 bbd_s_thr_col; 297145e9363SMing Qian u32 bbd_p_thr_col; 298145e9363SMing Qian u32 bbd_chr_thr_row; 299145e9363SMing Qian u32 bbd_chr_thr_col; 300145e9363SMing Qian u32 bbd_uv_mid_level; 301145e9363SMing Qian u32 bbd_excl_win_mb_left; 302145e9363SMing Qian u32 bbd_excl_win_mb_right; 303145e9363SMing Qian }; 304145e9363SMing Qian 305145e9363SMing Qian struct malone_padding_scode { 306145e9363SMing Qian u32 scode_type; 307145e9363SMing Qian u32 pixelformat; 308145e9363SMing Qian u32 data[2]; 309145e9363SMing Qian }; 310145e9363SMing Qian 311145e9363SMing Qian struct malone_fmt_mapping { 312145e9363SMing Qian u32 pixelformat; 313145e9363SMing Qian enum vpu_malone_format malone_format; 314ded5c4faSMing Qian u32 is_disabled; 315145e9363SMing Qian }; 316145e9363SMing Qian 317145e9363SMing Qian struct malone_scode_t { 318145e9363SMing Qian struct vpu_inst *inst; 319145e9363SMing Qian struct vb2_buffer *vb; 320145e9363SMing Qian u32 wptr; 321145e9363SMing Qian u32 need_data; 322145e9363SMing Qian }; 323145e9363SMing Qian 324145e9363SMing Qian struct malone_scode_handler { 325145e9363SMing Qian u32 pixelformat; 326145e9363SMing Qian int (*insert_scode_seq)(struct malone_scode_t *scode); 327145e9363SMing Qian int (*insert_scode_pic)(struct malone_scode_t *scode); 328145e9363SMing Qian }; 329145e9363SMing Qian 330145e9363SMing Qian struct vpu_dec_ctrl { 331145e9363SMing Qian struct malone_codec_params *codec_param; 332145e9363SMing Qian struct malone_jpg_params *jpg; 333145e9363SMing Qian void *seq_mem; 334145e9363SMing Qian void *pic_mem; 335145e9363SMing Qian void *gop_mem; 336145e9363SMing Qian void *qmeter_mem; 337145e9363SMing Qian void *dbglog_mem; 338145e9363SMing Qian struct vpu_malone_str_buffer __iomem *str_buf[VID_API_NUM_STREAMS]; 339145e9363SMing Qian u32 buf_addr[VID_API_NUM_STREAMS]; 340145e9363SMing Qian }; 341145e9363SMing Qian 342145e9363SMing Qian u32 vpu_malone_get_data_size(void) 343145e9363SMing Qian { 344145e9363SMing Qian return sizeof(struct vpu_dec_ctrl); 345145e9363SMing Qian } 346145e9363SMing Qian 347145e9363SMing Qian void vpu_malone_init_rpc(struct vpu_shared_addr *shared, 348145e9363SMing Qian struct vpu_buffer *rpc, dma_addr_t boot_addr) 349145e9363SMing Qian { 350145e9363SMing Qian struct malone_iface *iface; 351145e9363SMing Qian struct vpu_dec_ctrl *hc; 352145e9363SMing Qian unsigned long base_phy_addr; 353145e9363SMing Qian unsigned long phy_addr; 354145e9363SMing Qian unsigned long offset; 355145e9363SMing Qian unsigned int i; 356145e9363SMing Qian 357145e9363SMing Qian if (rpc->phys < boot_addr) 358145e9363SMing Qian return; 359145e9363SMing Qian 360145e9363SMing Qian iface = rpc->virt; 361145e9363SMing Qian base_phy_addr = rpc->phys - boot_addr; 362145e9363SMing Qian hc = shared->priv; 363145e9363SMing Qian 364145e9363SMing Qian shared->iface = iface; 365145e9363SMing Qian shared->boot_addr = boot_addr; 366145e9363SMing Qian 367145e9363SMing Qian iface->exec_base_addr = base_phy_addr; 368145e9363SMing Qian iface->exec_area_size = rpc->length; 369145e9363SMing Qian 370145e9363SMing Qian offset = sizeof(struct malone_iface); 371145e9363SMing Qian phy_addr = base_phy_addr + offset; 372145e9363SMing Qian 373145e9363SMing Qian shared->cmd_desc = &iface->cmd_buffer_desc.buffer; 374145e9363SMing Qian shared->cmd_mem_vir = rpc->virt + offset; 375145e9363SMing Qian iface->cmd_buffer_desc.buffer.start = 376145e9363SMing Qian iface->cmd_buffer_desc.buffer.rptr = 377145e9363SMing Qian iface->cmd_buffer_desc.buffer.wptr = phy_addr; 378145e9363SMing Qian iface->cmd_buffer_desc.buffer.end = iface->cmd_buffer_desc.buffer.start + CMD_SIZE; 379145e9363SMing Qian offset += CMD_SIZE; 380145e9363SMing Qian phy_addr = base_phy_addr + offset; 381145e9363SMing Qian 382145e9363SMing Qian shared->msg_desc = &iface->msg_buffer_desc.buffer; 383145e9363SMing Qian shared->msg_mem_vir = rpc->virt + offset; 384145e9363SMing Qian iface->msg_buffer_desc.buffer.start = 385145e9363SMing Qian iface->msg_buffer_desc.buffer.wptr = 386145e9363SMing Qian iface->msg_buffer_desc.buffer.rptr = phy_addr; 387145e9363SMing Qian iface->msg_buffer_desc.buffer.end = iface->msg_buffer_desc.buffer.start + MSG_SIZE; 388145e9363SMing Qian offset += MSG_SIZE; 389145e9363SMing Qian phy_addr = base_phy_addr + offset; 390145e9363SMing Qian 391145e9363SMing Qian iface->codec_param_tab_desc.array_base = phy_addr; 392145e9363SMing Qian hc->codec_param = rpc->virt + offset; 393145e9363SMing Qian offset += CODEC_SIZE; 394145e9363SMing Qian phy_addr = base_phy_addr + offset; 395145e9363SMing Qian 396145e9363SMing Qian iface->jpeg_param_tab_desc.array_base = phy_addr; 397145e9363SMing Qian hc->jpg = rpc->virt + offset; 398145e9363SMing Qian offset += JPEG_SIZE; 399145e9363SMing Qian phy_addr = base_phy_addr + offset; 400145e9363SMing Qian 401145e9363SMing Qian iface->seq_info_tab_desc.array_base = phy_addr; 402145e9363SMing Qian hc->seq_mem = rpc->virt + offset; 403145e9363SMing Qian offset += SEQ_SIZE; 404145e9363SMing Qian phy_addr = base_phy_addr + offset; 405145e9363SMing Qian 406145e9363SMing Qian iface->pic_info_tab_desc.array_base = phy_addr; 407145e9363SMing Qian hc->pic_mem = rpc->virt + offset; 408145e9363SMing Qian offset += PIC_SIZE; 409145e9363SMing Qian phy_addr = base_phy_addr + offset; 410145e9363SMing Qian 411145e9363SMing Qian iface->gop_info_tab_desc.array_base = phy_addr; 412145e9363SMing Qian hc->gop_mem = rpc->virt + offset; 413145e9363SMing Qian offset += GOP_SIZE; 414145e9363SMing Qian phy_addr = base_phy_addr + offset; 415145e9363SMing Qian 416145e9363SMing Qian iface->qmeter_info_tab_desc.array_base = phy_addr; 417145e9363SMing Qian hc->qmeter_mem = rpc->virt + offset; 418145e9363SMing Qian offset += QMETER_SIZE; 419145e9363SMing Qian phy_addr = base_phy_addr + offset; 420145e9363SMing Qian 421145e9363SMing Qian iface->dbglog_desc.addr = phy_addr; 422145e9363SMing Qian iface->dbglog_desc.size = DBGLOG_SIZE; 423145e9363SMing Qian hc->dbglog_mem = rpc->virt + offset; 424145e9363SMing Qian offset += DBGLOG_SIZE; 425145e9363SMing Qian phy_addr = base_phy_addr + offset; 426145e9363SMing Qian 427145e9363SMing Qian for (i = 0; i < VID_API_NUM_STREAMS; i++) { 428145e9363SMing Qian iface->eng_access_buff_desc[i].buffer.start = 429145e9363SMing Qian iface->eng_access_buff_desc[i].buffer.wptr = 430145e9363SMing Qian iface->eng_access_buff_desc[i].buffer.rptr = phy_addr; 431145e9363SMing Qian iface->eng_access_buff_desc[i].buffer.end = 432145e9363SMing Qian iface->eng_access_buff_desc[i].buffer.start + ENG_SIZE; 433145e9363SMing Qian offset += ENG_SIZE; 434145e9363SMing Qian phy_addr = base_phy_addr + offset; 435145e9363SMing Qian } 436145e9363SMing Qian 437145e9363SMing Qian for (i = 0; i < VID_API_NUM_STREAMS; i++) { 438145e9363SMing Qian iface->encrypt_info[i] = phy_addr; 439145e9363SMing Qian offset += sizeof(struct vpu_malone_encrypt_info); 440145e9363SMing Qian phy_addr = base_phy_addr + offset; 441145e9363SMing Qian } 442145e9363SMing Qian 443145e9363SMing Qian rpc->bytesused = offset; 444145e9363SMing Qian } 445145e9363SMing Qian 446145e9363SMing Qian void vpu_malone_set_log_buf(struct vpu_shared_addr *shared, 447145e9363SMing Qian struct vpu_buffer *log) 448145e9363SMing Qian { 449145e9363SMing Qian struct malone_iface *iface = shared->iface; 450145e9363SMing Qian 451145e9363SMing Qian iface->debug_buffer_desc.buffer.start = 452145e9363SMing Qian iface->debug_buffer_desc.buffer.wptr = 453145e9363SMing Qian iface->debug_buffer_desc.buffer.rptr = log->phys - shared->boot_addr; 454145e9363SMing Qian iface->debug_buffer_desc.buffer.end = iface->debug_buffer_desc.buffer.start + log->length; 455145e9363SMing Qian } 456145e9363SMing Qian 457145e9363SMing Qian static u32 get_str_buffer_offset(u32 instance) 458145e9363SMing Qian { 459145e9363SMing Qian return DEC_MFD_XREG_SLV_BASE + MFD_MCX + MFD_MCX_OFF * instance; 460145e9363SMing Qian } 461145e9363SMing Qian 462145e9363SMing Qian void vpu_malone_set_system_cfg(struct vpu_shared_addr *shared, 463145e9363SMing Qian u32 regs_base, void __iomem *regs, u32 core_id) 464145e9363SMing Qian { 465145e9363SMing Qian struct malone_iface *iface = shared->iface; 466145e9363SMing Qian struct vpu_rpc_system_config *config = &iface->system_cfg; 467145e9363SMing Qian struct vpu_dec_ctrl *hc = shared->priv; 468145e9363SMing Qian int i; 469145e9363SMing Qian 470145e9363SMing Qian vpu_imx8q_set_system_cfg_common(config, regs_base, core_id); 471145e9363SMing Qian for (i = 0; i < VID_API_NUM_STREAMS; i++) { 472145e9363SMing Qian u32 offset = get_str_buffer_offset(i); 473145e9363SMing Qian 474145e9363SMing Qian hc->buf_addr[i] = regs_base + offset; 475145e9363SMing Qian hc->str_buf[i] = regs + offset; 476145e9363SMing Qian } 477145e9363SMing Qian } 478145e9363SMing Qian 479145e9363SMing Qian u32 vpu_malone_get_version(struct vpu_shared_addr *shared) 480145e9363SMing Qian { 481145e9363SMing Qian struct malone_iface *iface = shared->iface; 482145e9363SMing Qian 4833b514e79SMing Qian vpu_malone_enable_format(V4L2_PIX_FMT_RV30, iface->fw_version & MALONE_DEC_FMT_RV_MASK); 4843b514e79SMing Qian vpu_malone_enable_format(V4L2_PIX_FMT_RV40, iface->fw_version & MALONE_DEC_FMT_RV_MASK); 4853b514e79SMing Qian 486145e9363SMing Qian return iface->fw_version; 487145e9363SMing Qian } 488145e9363SMing Qian 489145e9363SMing Qian int vpu_malone_get_stream_buffer_size(struct vpu_shared_addr *shared) 490145e9363SMing Qian { 491145e9363SMing Qian return 0xc00000; 492145e9363SMing Qian } 493145e9363SMing Qian 494145e9363SMing Qian int vpu_malone_config_stream_buffer(struct vpu_shared_addr *shared, 495145e9363SMing Qian u32 instance, 496145e9363SMing Qian struct vpu_buffer *buf) 497145e9363SMing Qian { 498145e9363SMing Qian struct malone_iface *iface = shared->iface; 499145e9363SMing Qian struct vpu_dec_ctrl *hc = shared->priv; 500145e9363SMing Qian struct vpu_malone_str_buffer __iomem *str_buf = hc->str_buf[instance]; 501145e9363SMing Qian 502145e9363SMing Qian writel(buf->phys, &str_buf->start); 503145e9363SMing Qian writel(buf->phys, &str_buf->rptr); 504145e9363SMing Qian writel(buf->phys, &str_buf->wptr); 505145e9363SMing Qian writel(buf->phys + buf->length, &str_buf->end); 506145e9363SMing Qian writel(0x1, &str_buf->lwm); 507145e9363SMing Qian 508145e9363SMing Qian iface->stream_buffer_desc[instance][0] = hc->buf_addr[instance]; 509145e9363SMing Qian 510145e9363SMing Qian return 0; 511145e9363SMing Qian } 512145e9363SMing Qian 513145e9363SMing Qian int vpu_malone_get_stream_buffer_desc(struct vpu_shared_addr *shared, 514145e9363SMing Qian u32 instance, 515145e9363SMing Qian struct vpu_rpc_buffer_desc *desc) 516145e9363SMing Qian { 517145e9363SMing Qian struct vpu_dec_ctrl *hc = shared->priv; 518145e9363SMing Qian struct vpu_malone_str_buffer __iomem *str_buf = hc->str_buf[instance]; 519145e9363SMing Qian 520145e9363SMing Qian if (desc) { 521145e9363SMing Qian desc->wptr = readl(&str_buf->wptr); 522145e9363SMing Qian desc->rptr = readl(&str_buf->rptr); 523145e9363SMing Qian desc->start = readl(&str_buf->start); 524145e9363SMing Qian desc->end = readl(&str_buf->end); 525145e9363SMing Qian } 526145e9363SMing Qian 527145e9363SMing Qian return 0; 528145e9363SMing Qian } 529145e9363SMing Qian 530145e9363SMing Qian static void vpu_malone_update_wptr(struct vpu_malone_str_buffer __iomem *str_buf, u32 wptr) 531145e9363SMing Qian { 532145e9363SMing Qian /*update wptr after data is written*/ 533145e9363SMing Qian mb(); 534145e9363SMing Qian writel(wptr, &str_buf->wptr); 535145e9363SMing Qian } 536145e9363SMing Qian 537145e9363SMing Qian static void vpu_malone_update_rptr(struct vpu_malone_str_buffer __iomem *str_buf, u32 rptr) 538145e9363SMing Qian { 539145e9363SMing Qian /*update rptr after data is read*/ 540145e9363SMing Qian mb(); 541145e9363SMing Qian writel(rptr, &str_buf->rptr); 542145e9363SMing Qian } 543145e9363SMing Qian 544145e9363SMing Qian int vpu_malone_update_stream_buffer(struct vpu_shared_addr *shared, 545145e9363SMing Qian u32 instance, u32 ptr, bool write) 546145e9363SMing Qian { 547145e9363SMing Qian struct vpu_dec_ctrl *hc = shared->priv; 548145e9363SMing Qian struct vpu_malone_str_buffer __iomem *str_buf = hc->str_buf[instance]; 549145e9363SMing Qian 550145e9363SMing Qian if (write) 551145e9363SMing Qian vpu_malone_update_wptr(str_buf, ptr); 552145e9363SMing Qian else 553145e9363SMing Qian vpu_malone_update_rptr(str_buf, ptr); 554145e9363SMing Qian 555145e9363SMing Qian return 0; 556145e9363SMing Qian } 557145e9363SMing Qian 558145e9363SMing Qian static struct malone_fmt_mapping fmt_mappings[] = { 559145e9363SMing Qian {V4L2_PIX_FMT_H264, MALONE_FMT_AVC}, 560145e9363SMing Qian {V4L2_PIX_FMT_H264_MVC, MALONE_FMT_AVC}, 561145e9363SMing Qian {V4L2_PIX_FMT_HEVC, MALONE_FMT_HEVC}, 562145e9363SMing Qian {V4L2_PIX_FMT_VC1_ANNEX_G, MALONE_FMT_VC1}, 563145e9363SMing Qian {V4L2_PIX_FMT_VC1_ANNEX_L, MALONE_FMT_VC1}, 564145e9363SMing Qian {V4L2_PIX_FMT_MPEG2, MALONE_FMT_MP2}, 565145e9363SMing Qian {V4L2_PIX_FMT_MPEG4, MALONE_FMT_ASP}, 566145e9363SMing Qian {V4L2_PIX_FMT_XVID, MALONE_FMT_ASP}, 567145e9363SMing Qian {V4L2_PIX_FMT_H263, MALONE_FMT_ASP}, 568145e9363SMing Qian {V4L2_PIX_FMT_JPEG, MALONE_FMT_JPG}, 569145e9363SMing Qian {V4L2_PIX_FMT_VP8, MALONE_FMT_VP8}, 5709de92986SMing Qian {V4L2_PIX_FMT_SPK, MALONE_FMT_SPK}, 5713b514e79SMing Qian {V4L2_PIX_FMT_RV30, MALONE_FMT_RV}, 5723b514e79SMing Qian {V4L2_PIX_FMT_RV40, MALONE_FMT_RV}, 573145e9363SMing Qian }; 574145e9363SMing Qian 5753b514e79SMing Qian void vpu_malone_enable_format(u32 pixelformat, int enable) 5763b514e79SMing Qian { 5773b514e79SMing Qian u32 i; 5783b514e79SMing Qian 5793b514e79SMing Qian for (i = 0; i < ARRAY_SIZE(fmt_mappings); i++) { 5803b514e79SMing Qian if (pixelformat == fmt_mappings[i].pixelformat) { 5813b514e79SMing Qian fmt_mappings[i].is_disabled = enable ? 0 : 1; 5823b514e79SMing Qian return; 5833b514e79SMing Qian } 5843b514e79SMing Qian } 5853b514e79SMing Qian } 5863b514e79SMing Qian 587145e9363SMing Qian static enum vpu_malone_format vpu_malone_format_remap(u32 pixelformat) 588145e9363SMing Qian { 589145e9363SMing Qian u32 i; 590145e9363SMing Qian 591145e9363SMing Qian for (i = 0; i < ARRAY_SIZE(fmt_mappings); i++) { 592ded5c4faSMing Qian if (fmt_mappings[i].is_disabled) 593ded5c4faSMing Qian continue; 594145e9363SMing Qian if (pixelformat == fmt_mappings[i].pixelformat) 595145e9363SMing Qian return fmt_mappings[i].malone_format; 596145e9363SMing Qian } 597145e9363SMing Qian 598145e9363SMing Qian return MALONE_FMT_NULL; 599145e9363SMing Qian } 600145e9363SMing Qian 601ded5c4faSMing Qian bool vpu_malone_check_fmt(enum vpu_core_type type, u32 pixelfmt) 602ded5c4faSMing Qian { 603ded5c4faSMing Qian if (!vpu_imx8q_check_fmt(type, pixelfmt)) 604ded5c4faSMing Qian return false; 605ded5c4faSMing Qian 606d21ce554SMing Qian if (pixelfmt == V4L2_PIX_FMT_NV12_8L128 || pixelfmt == V4L2_PIX_FMT_NV12_10BE_8L128 || 607d21ce554SMing Qian pixelfmt == V4L2_PIX_FMT_NV12M_8L128 || pixelfmt == V4L2_PIX_FMT_NV12M_10BE_8L128) 608ded5c4faSMing Qian return true; 609ded5c4faSMing Qian if (vpu_malone_format_remap(pixelfmt) == MALONE_FMT_NULL) 610ded5c4faSMing Qian return false; 611ded5c4faSMing Qian 612ded5c4faSMing Qian return true; 613ded5c4faSMing Qian } 614ded5c4faSMing Qian 615145e9363SMing Qian static void vpu_malone_set_stream_cfg(struct vpu_shared_addr *shared, 616145e9363SMing Qian u32 instance, 617145e9363SMing Qian enum vpu_malone_format malone_format) 618145e9363SMing Qian { 619145e9363SMing Qian struct malone_iface *iface = shared->iface; 620145e9363SMing Qian u32 *curr_str_cfg = &iface->stream_config[instance]; 621145e9363SMing Qian 622145e9363SMing Qian *curr_str_cfg = 0; 623145e9363SMing Qian STREAM_CONFIG_FORMAT_SET(malone_format, curr_str_cfg); 624145e9363SMing Qian STREAM_CONFIG_STRBUFIDX_SET(0, curr_str_cfg); 625145e9363SMing Qian STREAM_CONFIG_NOSEQ_SET(0, curr_str_cfg); 626145e9363SMing Qian STREAM_CONFIG_DEBLOCK_SET(0, curr_str_cfg); 627145e9363SMing Qian STREAM_CONFIG_DERING_SET(0, curr_str_cfg); 628145e9363SMing Qian STREAM_CONFIG_PLAY_MODE_SET(0x3, curr_str_cfg); 629145e9363SMing Qian STREAM_CONFIG_FS_CTRL_MODE_SET(0x1, curr_str_cfg); 630145e9363SMing Qian STREAM_CONFIG_ENABLE_DCP_SET(1, curr_str_cfg); 631145e9363SMing Qian STREAM_CONFIG_NUM_STR_BUF_SET(1, curr_str_cfg); 632145e9363SMing Qian STREAM_CONFIG_MALONE_USAGE_SET(1, curr_str_cfg); 633145e9363SMing Qian STREAM_CONFIG_MULTI_VID_SET(0, curr_str_cfg); 634145e9363SMing Qian STREAM_CONFIG_OBFUSC_EN_SET(0, curr_str_cfg); 635145e9363SMing Qian STREAM_CONFIG_RC4_EN_SET(0, curr_str_cfg); 636145e9363SMing Qian STREAM_CONFIG_MCX_SET(1, curr_str_cfg); 637145e9363SMing Qian STREAM_CONFIG_PES_SET(0, curr_str_cfg); 638145e9363SMing Qian STREAM_CONFIG_NUM_DBE_SET(1, curr_str_cfg); 639145e9363SMing Qian } 640145e9363SMing Qian 641145e9363SMing Qian static int vpu_malone_set_params(struct vpu_shared_addr *shared, 642145e9363SMing Qian u32 instance, 643145e9363SMing Qian struct vpu_decode_params *params) 644145e9363SMing Qian { 645145e9363SMing Qian struct malone_iface *iface = shared->iface; 646145e9363SMing Qian struct vpu_dec_ctrl *hc = shared->priv; 647145e9363SMing Qian enum vpu_malone_format malone_format; 648145e9363SMing Qian 649145e9363SMing Qian malone_format = vpu_malone_format_remap(params->codec_format); 650a3a2efcaSMing Qian if (WARN_ON(malone_format == MALONE_FMT_NULL)) 651a3a2efcaSMing Qian return -EINVAL; 652145e9363SMing Qian iface->udata_buffer[instance].base = params->udata.base; 653145e9363SMing Qian iface->udata_buffer[instance].slot_size = params->udata.size; 654145e9363SMing Qian 655145e9363SMing Qian vpu_malone_set_stream_cfg(shared, instance, malone_format); 656145e9363SMing Qian 657145e9363SMing Qian if (malone_format == MALONE_FMT_JPG) { 658145e9363SMing Qian //1:JPGD_MJPEG_MODE_A; 2:JPGD_MJPEG_MODE_B 659145e9363SMing Qian hc->jpg[instance].jpg_mjpeg_mode = 1; 660145e9363SMing Qian //0: JPGD_MJPEG_PROGRESSIVE 661145e9363SMing Qian hc->jpg[instance].jpg_mjpeg_interlaced = 0; 662145e9363SMing Qian } 663145e9363SMing Qian 664ffa331d9SMing Qian hc->codec_param[instance].disp_imm = params->display_delay_enable ? 1 : 0; 665ffa331d9SMing Qian if (malone_format != MALONE_FMT_AVC) 666ffa331d9SMing Qian hc->codec_param[instance].disp_imm = 0; 667145e9363SMing Qian hc->codec_param[instance].dbglog_enable = 0; 668145e9363SMing Qian iface->dbglog_desc.level = 0; 669145e9363SMing Qian 670145e9363SMing Qian if (params->b_non_frame) 671145e9363SMing Qian iface->stream_buff_info[instance].stream_input_mode = NON_FRAME_LVL; 672145e9363SMing Qian else 673145e9363SMing Qian iface->stream_buff_info[instance].stream_input_mode = FRAME_LVL; 674145e9363SMing Qian iface->stream_buff_info[instance].stream_buffer_threshold = 0; 675145e9363SMing Qian iface->stream_buff_info[instance].stream_pic_input_count = 0; 676145e9363SMing Qian 677145e9363SMing Qian return 0; 678145e9363SMing Qian } 679145e9363SMing Qian 680145e9363SMing Qian static bool vpu_malone_is_non_frame_mode(struct vpu_shared_addr *shared, u32 instance) 681145e9363SMing Qian { 682145e9363SMing Qian struct malone_iface *iface = shared->iface; 683145e9363SMing Qian 684145e9363SMing Qian if (iface->stream_buff_info[instance].stream_input_mode == NON_FRAME_LVL) 685145e9363SMing Qian return true; 686145e9363SMing Qian 687145e9363SMing Qian return false; 688145e9363SMing Qian } 689145e9363SMing Qian 690145e9363SMing Qian static int vpu_malone_update_params(struct vpu_shared_addr *shared, 691145e9363SMing Qian u32 instance, 692145e9363SMing Qian struct vpu_decode_params *params) 693145e9363SMing Qian { 694145e9363SMing Qian struct malone_iface *iface = shared->iface; 695145e9363SMing Qian 696145e9363SMing Qian if (params->end_flag) 697145e9363SMing Qian iface->stream_buff_info[instance].stream_pic_end_flag = params->end_flag; 698145e9363SMing Qian params->end_flag = 0; 699145e9363SMing Qian 700145e9363SMing Qian return 0; 701145e9363SMing Qian } 702145e9363SMing Qian 703145e9363SMing Qian int vpu_malone_set_decode_params(struct vpu_shared_addr *shared, 704145e9363SMing Qian u32 instance, 705145e9363SMing Qian struct vpu_decode_params *params, 706145e9363SMing Qian u32 update) 707145e9363SMing Qian { 708145e9363SMing Qian if (!params) 709145e9363SMing Qian return -EINVAL; 710145e9363SMing Qian 711145e9363SMing Qian if (!update) 712145e9363SMing Qian return vpu_malone_set_params(shared, instance, params); 713145e9363SMing Qian else 714145e9363SMing Qian return vpu_malone_update_params(shared, instance, params); 715145e9363SMing Qian } 716145e9363SMing Qian 717145e9363SMing Qian static struct vpu_pair malone_cmds[] = { 71808274443SMing Qian {VPU_CMD_ID_NOOP, VID_API_CMD_NULL}, 719145e9363SMing Qian {VPU_CMD_ID_START, VID_API_CMD_START}, 720145e9363SMing Qian {VPU_CMD_ID_STOP, VID_API_CMD_STOP}, 721145e9363SMing Qian {VPU_CMD_ID_ABORT, VID_API_CMD_ABORT}, 722145e9363SMing Qian {VPU_CMD_ID_RST_BUF, VID_API_CMD_RST_BUF}, 723145e9363SMing Qian {VPU_CMD_ID_SNAPSHOT, VID_API_CMD_SNAPSHOT}, 724145e9363SMing Qian {VPU_CMD_ID_FIRM_RESET, VID_API_CMD_FIRM_RESET}, 725145e9363SMing Qian {VPU_CMD_ID_FS_ALLOC, VID_API_CMD_FS_ALLOC}, 726145e9363SMing Qian {VPU_CMD_ID_FS_RELEASE, VID_API_CMD_FS_RELEASE}, 727145e9363SMing Qian {VPU_CMD_ID_TIMESTAMP, VID_API_CMD_TS}, 728145e9363SMing Qian {VPU_CMD_ID_DEBUG, VID_API_CMD_FW_STATUS}, 729145e9363SMing Qian }; 730145e9363SMing Qian 731145e9363SMing Qian static struct vpu_pair malone_msgs[] = { 732145e9363SMing Qian {VPU_MSG_ID_RESET_DONE, VID_API_EVENT_RESET_DONE}, 733145e9363SMing Qian {VPU_MSG_ID_START_DONE, VID_API_EVENT_START_DONE}, 734145e9363SMing Qian {VPU_MSG_ID_STOP_DONE, VID_API_EVENT_STOPPED}, 735145e9363SMing Qian {VPU_MSG_ID_ABORT_DONE, VID_API_EVENT_ABORT_DONE}, 736145e9363SMing Qian {VPU_MSG_ID_BUF_RST, VID_API_EVENT_STR_BUF_RST}, 737145e9363SMing Qian {VPU_MSG_ID_PIC_EOS, VID_API_EVENT_FINISHED}, 738145e9363SMing Qian {VPU_MSG_ID_SEQ_HDR_FOUND, VID_API_EVENT_SEQ_HDR_FOUND}, 739145e9363SMing Qian {VPU_MSG_ID_RES_CHANGE, VID_API_EVENT_RES_CHANGE}, 740145e9363SMing Qian {VPU_MSG_ID_PIC_HDR_FOUND, VID_API_EVENT_PIC_HDR_FOUND}, 741145e9363SMing Qian {VPU_MSG_ID_PIC_DECODED, VID_API_EVENT_PIC_DECODED}, 742145e9363SMing Qian {VPU_MSG_ID_DEC_DONE, VID_API_EVENT_FRAME_BUFF_RDY}, 743145e9363SMing Qian {VPU_MSG_ID_FRAME_REQ, VID_API_EVENT_REQ_FRAME_BUFF}, 744145e9363SMing Qian {VPU_MSG_ID_FRAME_RELEASE, VID_API_EVENT_REL_FRAME_BUFF}, 745145e9363SMing Qian {VPU_MSG_ID_FIFO_LOW, VID_API_EVENT_FIFO_LOW}, 746145e9363SMing Qian {VPU_MSG_ID_BS_ERROR, VID_API_EVENT_BS_ERROR}, 747145e9363SMing Qian {VPU_MSG_ID_UNSUPPORTED, VID_API_EVENT_UNSUPPORTED_STREAM}, 748145e9363SMing Qian {VPU_MSG_ID_FIRMWARE_XCPT, VID_API_EVENT_FIRMWARE_XCPT}, 749be9fd510SMing Qian {VPU_MSG_ID_PIC_SKIPPED, VID_API_EVENT_PIC_SKIPPED}, 750145e9363SMing Qian }; 751145e9363SMing Qian 752145e9363SMing Qian static void vpu_malone_pack_fs_alloc(struct vpu_rpc_event *pkt, 753145e9363SMing Qian struct vpu_fs_info *fs) 754145e9363SMing Qian { 755145e9363SMing Qian const u32 fs_type[] = { 756145e9363SMing Qian [MEM_RES_FRAME] = 0, 757145e9363SMing Qian [MEM_RES_MBI] = 1, 758145e9363SMing Qian [MEM_RES_DCP] = 2, 759145e9363SMing Qian }; 760145e9363SMing Qian 761145e9363SMing Qian pkt->hdr.num = 7; 762145e9363SMing Qian pkt->data[0] = fs->id | (fs->tag << 24); 763145e9363SMing Qian pkt->data[1] = fs->luma_addr; 764145e9363SMing Qian if (fs->type == MEM_RES_FRAME) { 765145e9363SMing Qian /* 766145e9363SMing Qian * if luma_addr equal to chroma_addr, 767145e9363SMing Qian * means luma(plane[0]) and chromau(plane[1]) used the 768145e9363SMing Qian * same fd -- usage of NXP codec2. Need to manually 769145e9363SMing Qian * offset chroma addr. 770145e9363SMing Qian */ 771145e9363SMing Qian if (fs->luma_addr == fs->chroma_addr) 772145e9363SMing Qian fs->chroma_addr = fs->luma_addr + fs->luma_size; 773145e9363SMing Qian pkt->data[2] = fs->luma_addr + fs->luma_size / 2; 774145e9363SMing Qian pkt->data[3] = fs->chroma_addr; 775145e9363SMing Qian pkt->data[4] = fs->chroma_addr + fs->chromau_size / 2; 776145e9363SMing Qian pkt->data[5] = fs->bytesperline; 777145e9363SMing Qian } else { 778145e9363SMing Qian pkt->data[2] = fs->luma_size; 779145e9363SMing Qian pkt->data[3] = 0; 780145e9363SMing Qian pkt->data[4] = 0; 781145e9363SMing Qian pkt->data[5] = 0; 782145e9363SMing Qian } 783145e9363SMing Qian pkt->data[6] = fs_type[fs->type]; 784145e9363SMing Qian } 785145e9363SMing Qian 786145e9363SMing Qian static void vpu_malone_pack_fs_release(struct vpu_rpc_event *pkt, 787145e9363SMing Qian struct vpu_fs_info *fs) 788145e9363SMing Qian { 789145e9363SMing Qian pkt->hdr.num = 1; 790145e9363SMing Qian pkt->data[0] = fs->id | (fs->tag << 24); 791145e9363SMing Qian } 792145e9363SMing Qian 793145e9363SMing Qian static void vpu_malone_pack_timestamp(struct vpu_rpc_event *pkt, 794145e9363SMing Qian struct vpu_ts_info *info) 795145e9363SMing Qian { 79605a03effSMing Qian struct timespec64 ts = ns_to_timespec64(info->timestamp); 79705a03effSMing Qian 798145e9363SMing Qian pkt->hdr.num = 3; 79905a03effSMing Qian 80005a03effSMing Qian pkt->data[0] = ts.tv_sec; 80105a03effSMing Qian pkt->data[1] = ts.tv_nsec; 802145e9363SMing Qian pkt->data[2] = info->size; 803145e9363SMing Qian } 804145e9363SMing Qian 805145e9363SMing Qian int vpu_malone_pack_cmd(struct vpu_rpc_event *pkt, u32 index, u32 id, void *data) 806145e9363SMing Qian { 807145e9363SMing Qian int ret; 808145e9363SMing Qian 809145e9363SMing Qian ret = vpu_find_dst_by_src(malone_cmds, ARRAY_SIZE(malone_cmds), id); 810145e9363SMing Qian if (ret < 0) 811145e9363SMing Qian return ret; 812145e9363SMing Qian 813145e9363SMing Qian pkt->hdr.id = ret; 814145e9363SMing Qian pkt->hdr.num = 0; 815145e9363SMing Qian pkt->hdr.index = index; 816145e9363SMing Qian 817145e9363SMing Qian switch (id) { 818145e9363SMing Qian case VPU_CMD_ID_FS_ALLOC: 819145e9363SMing Qian vpu_malone_pack_fs_alloc(pkt, data); 820145e9363SMing Qian break; 821145e9363SMing Qian case VPU_CMD_ID_FS_RELEASE: 822145e9363SMing Qian vpu_malone_pack_fs_release(pkt, data); 823145e9363SMing Qian break; 824145e9363SMing Qian case VPU_CMD_ID_TIMESTAMP: 825145e9363SMing Qian vpu_malone_pack_timestamp(pkt, data); 826145e9363SMing Qian break; 827145e9363SMing Qian } 828145e9363SMing Qian 829145e9363SMing Qian pkt->hdr.index = index; 830145e9363SMing Qian return 0; 831145e9363SMing Qian } 832145e9363SMing Qian 833145e9363SMing Qian int vpu_malone_convert_msg_id(u32 id) 834145e9363SMing Qian { 835145e9363SMing Qian return vpu_find_src_by_dst(malone_msgs, ARRAY_SIZE(malone_msgs), id); 836145e9363SMing Qian } 837145e9363SMing Qian 838145e9363SMing Qian static void vpu_malone_fill_planes(struct vpu_dec_codec_info *info) 839145e9363SMing Qian { 840145e9363SMing Qian u32 interlaced = info->progressive ? 0 : 1; 841145e9363SMing Qian 842145e9363SMing Qian info->bytesperline[0] = 0; 843145e9363SMing Qian info->sizeimage[0] = vpu_helper_get_plane_size(info->pixfmt, 844145e9363SMing Qian info->decoded_width, 845145e9363SMing Qian info->decoded_height, 846145e9363SMing Qian 0, 847145e9363SMing Qian info->stride, 848145e9363SMing Qian interlaced, 849145e9363SMing Qian &info->bytesperline[0]); 850145e9363SMing Qian info->bytesperline[1] = 0; 851145e9363SMing Qian info->sizeimage[1] = vpu_helper_get_plane_size(info->pixfmt, 852145e9363SMing Qian info->decoded_width, 853145e9363SMing Qian info->decoded_height, 854145e9363SMing Qian 1, 855145e9363SMing Qian info->stride, 856145e9363SMing Qian interlaced, 857145e9363SMing Qian &info->bytesperline[1]); 858145e9363SMing Qian } 859145e9363SMing Qian 860145e9363SMing Qian static void vpu_malone_init_seq_hdr(struct vpu_dec_codec_info *info) 861145e9363SMing Qian { 862145e9363SMing Qian u32 chunks = info->num_dfe_area >> MALONE_DCP_CHUNK_BIT; 863145e9363SMing Qian 864145e9363SMing Qian vpu_malone_fill_planes(info); 865145e9363SMing Qian 866145e9363SMing Qian info->mbi_size = (info->sizeimage[0] + info->sizeimage[1]) >> 2; 867145e9363SMing Qian info->mbi_size = ALIGN(info->mbi_size, MALONE_ALIGN_MBI); 868145e9363SMing Qian 869145e9363SMing Qian info->dcp_size = MALONE_DCP_SIZE_MAX; 870145e9363SMing Qian if (chunks) { 871145e9363SMing Qian u32 mb_num; 872145e9363SMing Qian u32 mb_w; 873145e9363SMing Qian u32 mb_h; 874145e9363SMing Qian 875145e9363SMing Qian mb_w = DIV_ROUND_UP(info->decoded_width, 16); 876145e9363SMing Qian mb_h = DIV_ROUND_UP(info->decoded_height, 16); 877145e9363SMing Qian mb_num = mb_w * mb_h; 878145e9363SMing Qian info->dcp_size = mb_num * MALONE_DCP_FIXED_MB_ALLOC * chunks; 879145e9363SMing Qian info->dcp_size = clamp_t(u32, info->dcp_size, 880145e9363SMing Qian MALONE_DCP_SIZE_MIN, MALONE_DCP_SIZE_MAX); 881145e9363SMing Qian } 882145e9363SMing Qian } 883145e9363SMing Qian 884145e9363SMing Qian static void vpu_malone_unpack_seq_hdr(struct vpu_rpc_event *pkt, 885145e9363SMing Qian struct vpu_dec_codec_info *info) 886145e9363SMing Qian { 887145e9363SMing Qian info->num_ref_frms = pkt->data[0]; 888145e9363SMing Qian info->num_dpb_frms = pkt->data[1]; 889145e9363SMing Qian info->num_dfe_area = pkt->data[2]; 890145e9363SMing Qian info->progressive = pkt->data[3]; 891145e9363SMing Qian info->width = pkt->data[5]; 892145e9363SMing Qian info->height = pkt->data[4]; 893145e9363SMing Qian info->decoded_width = pkt->data[12]; 894145e9363SMing Qian info->decoded_height = pkt->data[11]; 895145e9363SMing Qian info->frame_rate.numerator = 1000; 896145e9363SMing Qian info->frame_rate.denominator = pkt->data[8]; 897145e9363SMing Qian info->dsp_asp_ratio = pkt->data[9]; 898145e9363SMing Qian info->level_idc = pkt->data[10]; 899145e9363SMing Qian info->bit_depth_luma = pkt->data[13]; 900145e9363SMing Qian info->bit_depth_chroma = pkt->data[14]; 901145e9363SMing Qian info->chroma_fmt = pkt->data[15]; 902145e9363SMing Qian info->color_primaries = vpu_color_cvrt_primaries_i2v(pkt->data[16]); 903145e9363SMing Qian info->transfer_chars = vpu_color_cvrt_transfers_i2v(pkt->data[17]); 904145e9363SMing Qian info->matrix_coeffs = vpu_color_cvrt_matrix_i2v(pkt->data[18]); 905145e9363SMing Qian info->full_range = vpu_color_cvrt_full_range_i2v(pkt->data[19]); 906145e9363SMing Qian info->vui_present = pkt->data[20]; 907145e9363SMing Qian info->mvc_num_views = pkt->data[21]; 908145e9363SMing Qian info->offset_x = pkt->data[23]; 909145e9363SMing Qian info->offset_y = pkt->data[25]; 910145e9363SMing Qian info->tag = pkt->data[27]; 911145e9363SMing Qian if (info->bit_depth_luma > 8) 912145e9363SMing Qian info->pixfmt = V4L2_PIX_FMT_NV12M_10BE_8L128; 913145e9363SMing Qian else 914145e9363SMing Qian info->pixfmt = V4L2_PIX_FMT_NV12M_8L128; 915145e9363SMing Qian if (info->frame_rate.numerator && info->frame_rate.denominator) { 916145e9363SMing Qian unsigned long n, d; 917145e9363SMing Qian 918145e9363SMing Qian rational_best_approximation(info->frame_rate.numerator, 919145e9363SMing Qian info->frame_rate.denominator, 920145e9363SMing Qian info->frame_rate.numerator, 921145e9363SMing Qian info->frame_rate.denominator, 922145e9363SMing Qian &n, &d); 923145e9363SMing Qian info->frame_rate.numerator = n; 924145e9363SMing Qian info->frame_rate.denominator = d; 925145e9363SMing Qian } 926145e9363SMing Qian vpu_malone_init_seq_hdr(info); 927145e9363SMing Qian } 928145e9363SMing Qian 929145e9363SMing Qian static void vpu_malone_unpack_pic_info(struct vpu_rpc_event *pkt, 930145e9363SMing Qian struct vpu_dec_pic_info *info) 931145e9363SMing Qian { 932145e9363SMing Qian info->id = pkt->data[7]; 933145e9363SMing Qian info->luma = pkt->data[0]; 934145e9363SMing Qian info->start = pkt->data[10]; 935145e9363SMing Qian info->end = pkt->data[12]; 936145e9363SMing Qian info->pic_size = pkt->data[11]; 937145e9363SMing Qian info->stride = pkt->data[5]; 938145e9363SMing Qian info->consumed_count = pkt->data[13]; 939145e9363SMing Qian if (info->id == MALONE_SKIPPED_FRAME_ID) 940145e9363SMing Qian info->skipped = 1; 941145e9363SMing Qian else 942145e9363SMing Qian info->skipped = 0; 943145e9363SMing Qian } 944145e9363SMing Qian 945145e9363SMing Qian static void vpu_malone_unpack_req_frame(struct vpu_rpc_event *pkt, 946145e9363SMing Qian struct vpu_fs_info *info) 947145e9363SMing Qian { 948145e9363SMing Qian info->type = pkt->data[1]; 949145e9363SMing Qian } 950145e9363SMing Qian 951145e9363SMing Qian static void vpu_malone_unpack_rel_frame(struct vpu_rpc_event *pkt, 952145e9363SMing Qian struct vpu_fs_info *info) 953145e9363SMing Qian { 954145e9363SMing Qian info->id = pkt->data[0]; 955145e9363SMing Qian info->type = pkt->data[1]; 956145e9363SMing Qian info->not_displayed = pkt->data[2]; 957145e9363SMing Qian } 958145e9363SMing Qian 959145e9363SMing Qian static void vpu_malone_unpack_buff_rdy(struct vpu_rpc_event *pkt, 960145e9363SMing Qian struct vpu_dec_pic_info *info) 961145e9363SMing Qian { 96205a03effSMing Qian struct timespec64 ts = { pkt->data[9], pkt->data[10] }; 96305a03effSMing Qian 964145e9363SMing Qian info->id = pkt->data[0]; 965145e9363SMing Qian info->luma = pkt->data[1]; 966145e9363SMing Qian info->stride = pkt->data[3]; 967145e9363SMing Qian if (info->id == MALONE_SKIPPED_FRAME_ID) 968145e9363SMing Qian info->skipped = 1; 969145e9363SMing Qian else 970145e9363SMing Qian info->skipped = 0; 97105a03effSMing Qian 97205a03effSMing Qian info->timestamp = timespec64_to_ns(&ts); 973145e9363SMing Qian } 974145e9363SMing Qian 975145e9363SMing Qian int vpu_malone_unpack_msg_data(struct vpu_rpc_event *pkt, void *data) 976145e9363SMing Qian { 977145e9363SMing Qian if (!pkt || !data) 978145e9363SMing Qian return -EINVAL; 979145e9363SMing Qian 980145e9363SMing Qian switch (pkt->hdr.id) { 981145e9363SMing Qian case VID_API_EVENT_SEQ_HDR_FOUND: 982145e9363SMing Qian vpu_malone_unpack_seq_hdr(pkt, data); 983145e9363SMing Qian break; 984145e9363SMing Qian case VID_API_EVENT_PIC_DECODED: 985145e9363SMing Qian vpu_malone_unpack_pic_info(pkt, data); 986145e9363SMing Qian break; 987145e9363SMing Qian case VID_API_EVENT_REQ_FRAME_BUFF: 988145e9363SMing Qian vpu_malone_unpack_req_frame(pkt, data); 989145e9363SMing Qian break; 990145e9363SMing Qian case VID_API_EVENT_REL_FRAME_BUFF: 991145e9363SMing Qian vpu_malone_unpack_rel_frame(pkt, data); 992145e9363SMing Qian break; 993145e9363SMing Qian case VID_API_EVENT_FRAME_BUFF_RDY: 994145e9363SMing Qian vpu_malone_unpack_buff_rdy(pkt, data); 995145e9363SMing Qian break; 996145e9363SMing Qian } 997145e9363SMing Qian 998145e9363SMing Qian return 0; 999145e9363SMing Qian } 1000145e9363SMing Qian 1001145e9363SMing Qian static const struct malone_padding_scode padding_scodes[] = { 1002145e9363SMing Qian {SCODE_PADDING_EOS, V4L2_PIX_FMT_H264, {0x0B010000, 0}}, 1003145e9363SMing Qian {SCODE_PADDING_EOS, V4L2_PIX_FMT_H264_MVC, {0x0B010000, 0}}, 1004145e9363SMing Qian {SCODE_PADDING_EOS, V4L2_PIX_FMT_HEVC, {0x4A010000, 0x20}}, 1005145e9363SMing Qian {SCODE_PADDING_EOS, V4L2_PIX_FMT_VC1_ANNEX_G, {0x0a010000, 0x0}}, 1006145e9363SMing Qian {SCODE_PADDING_EOS, V4L2_PIX_FMT_VC1_ANNEX_L, {0x0a010000, 0x0}}, 1007145e9363SMing Qian {SCODE_PADDING_EOS, V4L2_PIX_FMT_MPEG2, {0xCC010000, 0x0}}, 1008145e9363SMing Qian {SCODE_PADDING_EOS, V4L2_PIX_FMT_MPEG4, {0xb1010000, 0x0}}, 1009145e9363SMing Qian {SCODE_PADDING_EOS, V4L2_PIX_FMT_XVID, {0xb1010000, 0x0}}, 1010145e9363SMing Qian {SCODE_PADDING_EOS, V4L2_PIX_FMT_H263, {0xb1010000, 0x0}}, 1011145e9363SMing Qian {SCODE_PADDING_EOS, V4L2_PIX_FMT_VP8, {0x34010000, 0x0}}, 10129de92986SMing Qian {SCODE_PADDING_EOS, V4L2_PIX_FMT_SPK, {0x34010000, 0x0}}, 10133b514e79SMing Qian {SCODE_PADDING_EOS, V4L2_PIX_FMT_RV30, {0x34010000, 0x0}}, 10143b514e79SMing Qian {SCODE_PADDING_EOS, V4L2_PIX_FMT_RV40, {0x34010000, 0x0}}, 1015145e9363SMing Qian {SCODE_PADDING_EOS, V4L2_PIX_FMT_JPEG, {0xefff0000, 0x0}}, 1016145e9363SMing Qian {SCODE_PADDING_ABORT, V4L2_PIX_FMT_H264, {0x0B010000, 0}}, 1017145e9363SMing Qian {SCODE_PADDING_ABORT, V4L2_PIX_FMT_H264_MVC, {0x0B010000, 0}}, 1018145e9363SMing Qian {SCODE_PADDING_ABORT, V4L2_PIX_FMT_HEVC, {0x4A010000, 0x20}}, 1019145e9363SMing Qian {SCODE_PADDING_ABORT, V4L2_PIX_FMT_VC1_ANNEX_G, {0x0a010000, 0x0}}, 1020145e9363SMing Qian {SCODE_PADDING_ABORT, V4L2_PIX_FMT_VC1_ANNEX_L, {0x0a010000, 0x0}}, 1021145e9363SMing Qian {SCODE_PADDING_ABORT, V4L2_PIX_FMT_MPEG2, {0xb7010000, 0x0}}, 1022145e9363SMing Qian {SCODE_PADDING_ABORT, V4L2_PIX_FMT_MPEG4, {0xb1010000, 0x0}}, 1023145e9363SMing Qian {SCODE_PADDING_ABORT, V4L2_PIX_FMT_XVID, {0xb1010000, 0x0}}, 1024145e9363SMing Qian {SCODE_PADDING_ABORT, V4L2_PIX_FMT_H263, {0xb1010000, 0x0}}, 1025145e9363SMing Qian {SCODE_PADDING_ABORT, V4L2_PIX_FMT_VP8, {0x34010000, 0x0}}, 10269de92986SMing Qian {SCODE_PADDING_ABORT, V4L2_PIX_FMT_SPK, {0x34010000, 0x0}}, 10273b514e79SMing Qian {SCODE_PADDING_ABORT, V4L2_PIX_FMT_RV30, {0x34010000, 0x0}}, 10283b514e79SMing Qian {SCODE_PADDING_ABORT, V4L2_PIX_FMT_RV40, {0x34010000, 0x0}}, 1029145e9363SMing Qian {SCODE_PADDING_EOS, V4L2_PIX_FMT_JPEG, {0x0, 0x0}}, 1030145e9363SMing Qian {SCODE_PADDING_BUFFLUSH, V4L2_PIX_FMT_H264, {0x15010000, 0x0}}, 1031145e9363SMing Qian {SCODE_PADDING_BUFFLUSH, V4L2_PIX_FMT_H264_MVC, {0x15010000, 0x0}}, 1032145e9363SMing Qian }; 1033145e9363SMing Qian 1034145e9363SMing Qian static const struct malone_padding_scode padding_scode_dft = {0x0, 0x0}; 1035145e9363SMing Qian 1036145e9363SMing Qian static const struct malone_padding_scode *get_padding_scode(u32 type, u32 fmt) 1037145e9363SMing Qian { 1038145e9363SMing Qian const struct malone_padding_scode *s; 1039145e9363SMing Qian int i; 1040145e9363SMing Qian 1041145e9363SMing Qian for (i = 0; i < ARRAY_SIZE(padding_scodes); i++) { 1042145e9363SMing Qian s = &padding_scodes[i]; 1043145e9363SMing Qian 1044145e9363SMing Qian if (s->scode_type == type && s->pixelformat == fmt) 1045145e9363SMing Qian return s; 1046145e9363SMing Qian } 1047145e9363SMing Qian 1048145e9363SMing Qian if (type != SCODE_PADDING_BUFFLUSH) 1049145e9363SMing Qian return &padding_scode_dft; 1050145e9363SMing Qian 1051145e9363SMing Qian return NULL; 1052145e9363SMing Qian } 1053145e9363SMing Qian 1054145e9363SMing Qian static int vpu_malone_add_padding_scode(struct vpu_buffer *stream_buffer, 1055145e9363SMing Qian struct vpu_malone_str_buffer __iomem *str_buf, 1056145e9363SMing Qian u32 pixelformat, u32 scode_type) 1057145e9363SMing Qian { 1058145e9363SMing Qian u32 wptr; 1059a9f7224cSMing Qian int size; 1060a9f7224cSMing Qian int total_size = 0; 1061145e9363SMing Qian const struct malone_padding_scode *ps; 1062145e9363SMing Qian const u32 padding_size = 4096; 1063145e9363SMing Qian int ret; 1064145e9363SMing Qian 1065145e9363SMing Qian ps = get_padding_scode(scode_type, pixelformat); 1066145e9363SMing Qian if (!ps) 1067145e9363SMing Qian return -EINVAL; 1068145e9363SMing Qian 1069145e9363SMing Qian wptr = readl(&str_buf->wptr); 1070a9f7224cSMing Qian if (wptr < stream_buffer->phys || wptr > stream_buffer->phys + stream_buffer->length) 1071a9f7224cSMing Qian return -EINVAL; 1072a9f7224cSMing Qian if (wptr == stream_buffer->phys + stream_buffer->length) 1073a9f7224cSMing Qian wptr = stream_buffer->phys; 1074145e9363SMing Qian size = ALIGN(wptr, 4) - wptr; 1075145e9363SMing Qian if (size) 1076145e9363SMing Qian vpu_helper_memset_stream_buffer(stream_buffer, &wptr, 0, size); 1077145e9363SMing Qian total_size += size; 1078145e9363SMing Qian 1079145e9363SMing Qian size = sizeof(ps->data); 1080145e9363SMing Qian ret = vpu_helper_copy_to_stream_buffer(stream_buffer, &wptr, size, (void *)ps->data); 1081a9f7224cSMing Qian if (ret < 0) 1082145e9363SMing Qian return -EINVAL; 1083145e9363SMing Qian total_size += size; 1084145e9363SMing Qian 1085145e9363SMing Qian size = padding_size - sizeof(ps->data); 1086145e9363SMing Qian vpu_helper_memset_stream_buffer(stream_buffer, &wptr, 0, size); 1087145e9363SMing Qian total_size += size; 1088145e9363SMing Qian 1089145e9363SMing Qian vpu_malone_update_wptr(str_buf, wptr); 1090145e9363SMing Qian return total_size; 1091145e9363SMing Qian } 1092145e9363SMing Qian 1093145e9363SMing Qian int vpu_malone_add_scode(struct vpu_shared_addr *shared, 1094145e9363SMing Qian u32 instance, 1095145e9363SMing Qian struct vpu_buffer *stream_buffer, 1096145e9363SMing Qian u32 pixelformat, 1097145e9363SMing Qian u32 scode_type) 1098145e9363SMing Qian { 1099145e9363SMing Qian struct vpu_dec_ctrl *hc = shared->priv; 1100145e9363SMing Qian struct vpu_malone_str_buffer __iomem *str_buf = hc->str_buf[instance]; 1101145e9363SMing Qian int ret = -EINVAL; 1102145e9363SMing Qian 1103145e9363SMing Qian switch (scode_type) { 1104145e9363SMing Qian case SCODE_PADDING_EOS: 1105145e9363SMing Qian case SCODE_PADDING_ABORT: 1106145e9363SMing Qian case SCODE_PADDING_BUFFLUSH: 1107145e9363SMing Qian ret = vpu_malone_add_padding_scode(stream_buffer, str_buf, pixelformat, scode_type); 1108145e9363SMing Qian break; 1109145e9363SMing Qian default: 1110145e9363SMing Qian break; 1111145e9363SMing Qian } 1112145e9363SMing Qian 1113145e9363SMing Qian return ret; 1114145e9363SMing Qian } 1115145e9363SMing Qian 1116145e9363SMing Qian #define MALONE_PAYLOAD_HEADER_SIZE 16 1117145e9363SMing Qian #define MALONE_CODEC_VERSION_ID 0x1 1118145e9363SMing Qian #define MALONE_CODEC_ID_VC1_SIMPLE 0x10 1119145e9363SMing Qian #define MALONE_CODEC_ID_VC1_MAIN 0x11 1120145e9363SMing Qian #define MALONE_CODEC_ID_ARV8 0x28 1121145e9363SMing Qian #define MALONE_CODEC_ID_ARV9 0x29 1122145e9363SMing Qian #define MALONE_CODEC_ID_VP6 0x36 1123145e9363SMing Qian #define MALONE_CODEC_ID_VP8 0x36 1124145e9363SMing Qian #define MALONE_CODEC_ID_DIVX3 0x38 1125145e9363SMing Qian #define MALONE_CODEC_ID_SPK 0x39 1126145e9363SMing Qian 1127145e9363SMing Qian #define MALONE_VP8_IVF_SEQ_HEADER_LEN 32 1128145e9363SMing Qian #define MALONE_VP8_IVF_FRAME_HEADER_LEN 8 1129145e9363SMing Qian 1130145e9363SMing Qian #define MALONE_VC1_RCV_CODEC_V1_VERSION 0x85 1131145e9363SMing Qian #define MALONE_VC1_RCV_CODEC_V2_VERSION 0xC5 1132145e9363SMing Qian #define MALONE_VC1_RCV_NUM_FRAMES 0xFF 1133145e9363SMing Qian #define MALONE_VC1_RCV_SEQ_EXT_DATA_SIZE 4 1134145e9363SMing Qian #define MALONE_VC1_RCV_SEQ_HEADER_LEN 20 1135145e9363SMing Qian #define MALONE_VC1_RCV_PIC_HEADER_LEN 4 1136145e9363SMing Qian #define MALONE_VC1_NAL_HEADER_LEN 4 1137145e9363SMing Qian #define MALONE_VC1_CONTAIN_NAL(data) (((data) & 0x00FFFFFF) == 0x00010000) 1138145e9363SMing Qian 1139145e9363SMing Qian static void set_payload_hdr(u8 *dst, u32 scd_type, u32 codec_id, 1140145e9363SMing Qian u32 buffer_size, u32 width, u32 height) 1141145e9363SMing Qian { 1142145e9363SMing Qian unsigned int payload_size; 1143145e9363SMing Qian /* payload_size = buffer_size + itself_size(16) - start_code(4) */ 1144145e9363SMing Qian payload_size = buffer_size + 12; 1145145e9363SMing Qian 1146145e9363SMing Qian dst[0] = 0x00; 1147145e9363SMing Qian dst[1] = 0x00; 1148145e9363SMing Qian dst[2] = 0x01; 1149145e9363SMing Qian dst[3] = scd_type; 1150145e9363SMing Qian 1151145e9363SMing Qian /* length */ 1152145e9363SMing Qian dst[4] = ((payload_size >> 16) & 0xff); 1153145e9363SMing Qian dst[5] = ((payload_size >> 8) & 0xff); 1154145e9363SMing Qian dst[6] = 0x4e; 1155145e9363SMing Qian dst[7] = ((payload_size >> 0) & 0xff); 1156145e9363SMing Qian 1157145e9363SMing Qian /* Codec ID and Version */ 1158145e9363SMing Qian dst[8] = codec_id; 1159145e9363SMing Qian dst[9] = MALONE_CODEC_VERSION_ID; 1160145e9363SMing Qian 1161145e9363SMing Qian /* width */ 1162145e9363SMing Qian dst[10] = ((width >> 8) & 0xff); 1163145e9363SMing Qian dst[11] = ((width >> 0) & 0xff); 1164145e9363SMing Qian dst[12] = 0x58; 1165145e9363SMing Qian 1166145e9363SMing Qian /* height */ 1167145e9363SMing Qian dst[13] = ((height >> 8) & 0xff); 1168145e9363SMing Qian dst[14] = ((height >> 0) & 0xff); 1169145e9363SMing Qian dst[15] = 0x50; 1170145e9363SMing Qian } 1171145e9363SMing Qian 1172145e9363SMing Qian static void set_vp8_ivf_seqhdr(u8 *dst, u32 width, u32 height) 1173145e9363SMing Qian { 1174145e9363SMing Qian /* 0-3byte signature "DKIF" */ 1175145e9363SMing Qian dst[0] = 0x44; 1176145e9363SMing Qian dst[1] = 0x4b; 1177145e9363SMing Qian dst[2] = 0x49; 1178145e9363SMing Qian dst[3] = 0x46; 1179145e9363SMing Qian /* 4-5byte version: should be 0*/ 1180145e9363SMing Qian dst[4] = 0x00; 1181145e9363SMing Qian dst[5] = 0x00; 1182145e9363SMing Qian /* 6-7 length of Header */ 1183145e9363SMing Qian dst[6] = MALONE_VP8_IVF_SEQ_HEADER_LEN; 1184145e9363SMing Qian dst[7] = MALONE_VP8_IVF_SEQ_HEADER_LEN >> 8; 1185145e9363SMing Qian /* 8-11 VP8 fourcc */ 1186145e9363SMing Qian dst[8] = 0x56; 1187145e9363SMing Qian dst[9] = 0x50; 1188145e9363SMing Qian dst[10] = 0x38; 1189145e9363SMing Qian dst[11] = 0x30; 1190145e9363SMing Qian /* 12-13 width in pixels */ 1191145e9363SMing Qian dst[12] = width; 1192145e9363SMing Qian dst[13] = width >> 8; 1193145e9363SMing Qian /* 14-15 height in pixels */ 1194145e9363SMing Qian dst[14] = height; 1195145e9363SMing Qian dst[15] = height >> 8; 1196145e9363SMing Qian /* 16-19 frame rate */ 1197145e9363SMing Qian dst[16] = 0xe8; 1198145e9363SMing Qian dst[17] = 0x03; 1199145e9363SMing Qian dst[18] = 0x00; 1200145e9363SMing Qian dst[19] = 0x00; 1201145e9363SMing Qian /* 20-23 time scale */ 1202145e9363SMing Qian dst[20] = 0x01; 1203145e9363SMing Qian dst[21] = 0x00; 1204145e9363SMing Qian dst[22] = 0x00; 1205145e9363SMing Qian dst[23] = 0x00; 1206145e9363SMing Qian /* 24-27 number frames */ 1207145e9363SMing Qian dst[24] = 0xdf; 1208145e9363SMing Qian dst[25] = 0xf9; 1209145e9363SMing Qian dst[26] = 0x09; 1210145e9363SMing Qian dst[27] = 0x00; 1211145e9363SMing Qian /* 28-31 reserved */ 1212145e9363SMing Qian } 1213145e9363SMing Qian 1214145e9363SMing Qian static void set_vp8_ivf_pichdr(u8 *dst, u32 frame_size) 1215145e9363SMing Qian { 1216145e9363SMing Qian /* 1217145e9363SMing Qian * firmware just parse 64-bit timestamp(8 bytes). 1218145e9363SMing Qian * As not transfer timestamp to firmware, use default value(ZERO). 1219145e9363SMing Qian * No need to do anything here 1220145e9363SMing Qian */ 1221145e9363SMing Qian } 1222145e9363SMing Qian 1223145e9363SMing Qian static void set_vc1_rcv_seqhdr(u8 *dst, u8 *src, u32 width, u32 height) 1224145e9363SMing Qian { 1225145e9363SMing Qian u32 frames = MALONE_VC1_RCV_NUM_FRAMES; 1226145e9363SMing Qian u32 ext_data_size = MALONE_VC1_RCV_SEQ_EXT_DATA_SIZE; 1227145e9363SMing Qian 1228145e9363SMing Qian /* 0-2 Number of frames, used default value 0xFF */ 1229145e9363SMing Qian dst[0] = frames; 1230145e9363SMing Qian dst[1] = frames >> 8; 1231145e9363SMing Qian dst[2] = frames >> 16; 1232145e9363SMing Qian 1233145e9363SMing Qian /* 3 RCV version, used V1 */ 1234145e9363SMing Qian dst[3] = MALONE_VC1_RCV_CODEC_V1_VERSION; 1235145e9363SMing Qian 1236145e9363SMing Qian /* 4-7 extension data size */ 1237145e9363SMing Qian dst[4] = ext_data_size; 1238145e9363SMing Qian dst[5] = ext_data_size >> 8; 1239145e9363SMing Qian dst[6] = ext_data_size >> 16; 1240145e9363SMing Qian dst[7] = ext_data_size >> 24; 1241145e9363SMing Qian /* 8-11 extension data */ 1242145e9363SMing Qian dst[8] = src[0]; 1243145e9363SMing Qian dst[9] = src[1]; 1244145e9363SMing Qian dst[10] = src[2]; 1245145e9363SMing Qian dst[11] = src[3]; 1246145e9363SMing Qian 1247145e9363SMing Qian /* height */ 1248145e9363SMing Qian dst[12] = height; 1249145e9363SMing Qian dst[13] = (height >> 8) & 0xff; 1250145e9363SMing Qian dst[14] = (height >> 16) & 0xff; 1251145e9363SMing Qian dst[15] = (height >> 24) & 0xff; 1252145e9363SMing Qian /* width */ 1253145e9363SMing Qian dst[16] = width; 1254145e9363SMing Qian dst[17] = (width >> 8) & 0xff; 1255145e9363SMing Qian dst[18] = (width >> 16) & 0xff; 1256145e9363SMing Qian dst[19] = (width >> 24) & 0xff; 1257145e9363SMing Qian } 1258145e9363SMing Qian 1259145e9363SMing Qian static void set_vc1_rcv_pichdr(u8 *dst, u32 buffer_size) 1260145e9363SMing Qian { 1261145e9363SMing Qian dst[0] = buffer_size; 1262145e9363SMing Qian dst[1] = buffer_size >> 8; 1263145e9363SMing Qian dst[2] = buffer_size >> 16; 1264145e9363SMing Qian dst[3] = buffer_size >> 24; 1265145e9363SMing Qian } 1266145e9363SMing Qian 1267145e9363SMing Qian static void create_vc1_nal_pichdr(u8 *dst) 1268145e9363SMing Qian { 1269145e9363SMing Qian /* need insert nal header: special ID */ 1270145e9363SMing Qian dst[0] = 0x0; 1271145e9363SMing Qian dst[1] = 0x0; 1272145e9363SMing Qian dst[2] = 0x01; 1273145e9363SMing Qian dst[3] = 0x0D; 1274145e9363SMing Qian } 1275145e9363SMing Qian 1276145e9363SMing Qian static int vpu_malone_insert_scode_seq(struct malone_scode_t *scode, u32 codec_id, u32 ext_size) 1277145e9363SMing Qian { 1278145e9363SMing Qian u8 hdr[MALONE_PAYLOAD_HEADER_SIZE]; 1279145e9363SMing Qian int ret; 1280145e9363SMing Qian 1281145e9363SMing Qian set_payload_hdr(hdr, 1282145e9363SMing Qian SCODE_SEQUENCE, 1283145e9363SMing Qian codec_id, 1284145e9363SMing Qian ext_size, 1285145e9363SMing Qian scode->inst->out_format.width, 1286145e9363SMing Qian scode->inst->out_format.height); 1287145e9363SMing Qian ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer, 1288145e9363SMing Qian &scode->wptr, 1289145e9363SMing Qian sizeof(hdr), 1290145e9363SMing Qian hdr); 1291a9f7224cSMing Qian if (ret < 0) 1292145e9363SMing Qian return ret; 1293a9f7224cSMing Qian return sizeof(hdr); 1294145e9363SMing Qian } 1295145e9363SMing Qian 1296145e9363SMing Qian static int vpu_malone_insert_scode_pic(struct malone_scode_t *scode, u32 codec_id, u32 ext_size) 1297145e9363SMing Qian { 1298145e9363SMing Qian u8 hdr[MALONE_PAYLOAD_HEADER_SIZE]; 1299a9f7224cSMing Qian int ret; 1300145e9363SMing Qian 1301145e9363SMing Qian set_payload_hdr(hdr, 1302145e9363SMing Qian SCODE_PICTURE, 1303145e9363SMing Qian codec_id, 1304145e9363SMing Qian ext_size + vb2_get_plane_payload(scode->vb, 0), 1305145e9363SMing Qian scode->inst->out_format.width, 1306145e9363SMing Qian scode->inst->out_format.height); 1307a9f7224cSMing Qian ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer, 1308145e9363SMing Qian &scode->wptr, 1309145e9363SMing Qian sizeof(hdr), 1310145e9363SMing Qian hdr); 1311a9f7224cSMing Qian if (ret < 0) 1312a9f7224cSMing Qian return ret; 1313a9f7224cSMing Qian return sizeof(hdr); 1314145e9363SMing Qian } 1315145e9363SMing Qian 1316145e9363SMing Qian static int vpu_malone_insert_scode_vc1_g_pic(struct malone_scode_t *scode) 1317145e9363SMing Qian { 1318145e9363SMing Qian struct vb2_v4l2_buffer *vbuf; 1319145e9363SMing Qian u8 nal_hdr[MALONE_VC1_NAL_HEADER_LEN]; 1320145e9363SMing Qian u32 *data = NULL; 1321a9f7224cSMing Qian int ret; 1322145e9363SMing Qian 1323145e9363SMing Qian vbuf = to_vb2_v4l2_buffer(scode->vb); 1324145e9363SMing Qian data = vb2_plane_vaddr(scode->vb, 0); 1325145e9363SMing Qian 1326f7fd6c31SMing Qian if (scode->inst->total_input_count == 0 || vpu_vb_is_codecconfig(vbuf)) 1327145e9363SMing Qian return 0; 1328145e9363SMing Qian if (MALONE_VC1_CONTAIN_NAL(*data)) 1329145e9363SMing Qian return 0; 1330145e9363SMing Qian 1331145e9363SMing Qian create_vc1_nal_pichdr(nal_hdr); 1332a9f7224cSMing Qian ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer, 1333145e9363SMing Qian &scode->wptr, 1334145e9363SMing Qian sizeof(nal_hdr), 1335145e9363SMing Qian nal_hdr); 1336a9f7224cSMing Qian if (ret < 0) 1337a9f7224cSMing Qian return ret; 1338a9f7224cSMing Qian return sizeof(nal_hdr); 1339145e9363SMing Qian } 1340145e9363SMing Qian 1341145e9363SMing Qian static int vpu_malone_insert_scode_vc1_l_seq(struct malone_scode_t *scode) 1342145e9363SMing Qian { 1343145e9363SMing Qian int ret; 1344145e9363SMing Qian int size = 0; 1345145e9363SMing Qian u8 rcv_seqhdr[MALONE_VC1_RCV_SEQ_HEADER_LEN]; 1346145e9363SMing Qian 1347668ee1a3SMing Qian if (vpu_vb_is_codecconfig(to_vb2_v4l2_buffer(scode->vb))) 1348668ee1a3SMing Qian scode->need_data = 0; 1349e670f5d6SMing Qian if (scode->inst->total_input_count) 1350e670f5d6SMing Qian return 0; 1351145e9363SMing Qian scode->need_data = 0; 1352145e9363SMing Qian 1353a9f7224cSMing Qian ret = vpu_malone_insert_scode_seq(scode, MALONE_CODEC_ID_VC1_SIMPLE, sizeof(rcv_seqhdr)); 1354145e9363SMing Qian if (ret < 0) 1355145e9363SMing Qian return ret; 1356145e9363SMing Qian size = ret; 1357145e9363SMing Qian 1358145e9363SMing Qian set_vc1_rcv_seqhdr(rcv_seqhdr, 1359145e9363SMing Qian vb2_plane_vaddr(scode->vb, 0), 1360145e9363SMing Qian scode->inst->out_format.width, 1361145e9363SMing Qian scode->inst->out_format.height); 1362145e9363SMing Qian ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer, 1363145e9363SMing Qian &scode->wptr, 1364145e9363SMing Qian sizeof(rcv_seqhdr), 1365145e9363SMing Qian rcv_seqhdr); 1366145e9363SMing Qian 1367145e9363SMing Qian if (ret < 0) 1368145e9363SMing Qian return ret; 1369a9f7224cSMing Qian size += sizeof(rcv_seqhdr); 1370145e9363SMing Qian return size; 1371145e9363SMing Qian } 1372145e9363SMing Qian 1373145e9363SMing Qian static int vpu_malone_insert_scode_vc1_l_pic(struct malone_scode_t *scode) 1374145e9363SMing Qian { 1375145e9363SMing Qian int ret; 1376145e9363SMing Qian int size = 0; 1377145e9363SMing Qian u8 rcv_pichdr[MALONE_VC1_RCV_PIC_HEADER_LEN]; 1378145e9363SMing Qian 1379145e9363SMing Qian ret = vpu_malone_insert_scode_pic(scode, MALONE_CODEC_ID_VC1_SIMPLE, 1380145e9363SMing Qian sizeof(rcv_pichdr)); 1381145e9363SMing Qian if (ret < 0) 1382145e9363SMing Qian return ret; 1383145e9363SMing Qian size = ret; 1384145e9363SMing Qian 1385145e9363SMing Qian set_vc1_rcv_pichdr(rcv_pichdr, vb2_get_plane_payload(scode->vb, 0)); 1386145e9363SMing Qian ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer, 1387145e9363SMing Qian &scode->wptr, 1388145e9363SMing Qian sizeof(rcv_pichdr), 1389145e9363SMing Qian rcv_pichdr); 1390145e9363SMing Qian if (ret < 0) 1391145e9363SMing Qian return ret; 1392a9f7224cSMing Qian size += sizeof(rcv_pichdr); 1393145e9363SMing Qian return size; 1394145e9363SMing Qian } 1395145e9363SMing Qian 1396145e9363SMing Qian static int vpu_malone_insert_scode_vp8_seq(struct malone_scode_t *scode) 1397145e9363SMing Qian { 1398145e9363SMing Qian int ret; 1399145e9363SMing Qian int size = 0; 1400145e9363SMing Qian u8 ivf_hdr[MALONE_VP8_IVF_SEQ_HEADER_LEN]; 1401145e9363SMing Qian 1402145e9363SMing Qian ret = vpu_malone_insert_scode_seq(scode, MALONE_CODEC_ID_VP8, sizeof(ivf_hdr)); 1403145e9363SMing Qian if (ret < 0) 1404145e9363SMing Qian return ret; 1405145e9363SMing Qian size = ret; 1406145e9363SMing Qian 1407145e9363SMing Qian set_vp8_ivf_seqhdr(ivf_hdr, 1408145e9363SMing Qian scode->inst->out_format.width, 1409145e9363SMing Qian scode->inst->out_format.height); 1410145e9363SMing Qian ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer, 1411145e9363SMing Qian &scode->wptr, 1412145e9363SMing Qian sizeof(ivf_hdr), 1413145e9363SMing Qian ivf_hdr); 1414145e9363SMing Qian if (ret < 0) 1415145e9363SMing Qian return ret; 1416a9f7224cSMing Qian size += sizeof(ivf_hdr); 1417145e9363SMing Qian 1418145e9363SMing Qian return size; 1419145e9363SMing Qian } 1420145e9363SMing Qian 1421145e9363SMing Qian static int vpu_malone_insert_scode_vp8_pic(struct malone_scode_t *scode) 1422145e9363SMing Qian { 1423145e9363SMing Qian int ret; 1424145e9363SMing Qian int size = 0; 1425145e9363SMing Qian u8 ivf_hdr[MALONE_VP8_IVF_FRAME_HEADER_LEN] = {0}; 1426145e9363SMing Qian 1427145e9363SMing Qian ret = vpu_malone_insert_scode_pic(scode, MALONE_CODEC_ID_VP8, sizeof(ivf_hdr)); 1428145e9363SMing Qian if (ret < 0) 1429145e9363SMing Qian return ret; 1430145e9363SMing Qian size = ret; 1431145e9363SMing Qian 1432145e9363SMing Qian set_vp8_ivf_pichdr(ivf_hdr, vb2_get_plane_payload(scode->vb, 0)); 1433145e9363SMing Qian ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer, 1434145e9363SMing Qian &scode->wptr, 1435145e9363SMing Qian sizeof(ivf_hdr), 1436145e9363SMing Qian ivf_hdr); 1437145e9363SMing Qian if (ret < 0) 1438145e9363SMing Qian return ret; 1439a9f7224cSMing Qian size += sizeof(ivf_hdr); 1440145e9363SMing Qian 1441145e9363SMing Qian return size; 1442145e9363SMing Qian } 1443145e9363SMing Qian 14449de92986SMing Qian static int vpu_malone_insert_scode_spk_seq(struct malone_scode_t *scode) 14459de92986SMing Qian { 14469de92986SMing Qian return vpu_malone_insert_scode_seq(scode, MALONE_CODEC_ID_SPK, 0); 14479de92986SMing Qian } 14489de92986SMing Qian 14499de92986SMing Qian static int vpu_malone_insert_scode_spk_pic(struct malone_scode_t *scode) 14509de92986SMing Qian { 14519de92986SMing Qian return vpu_malone_insert_scode_pic(scode, MALONE_CODEC_ID_SPK, 0); 14529de92986SMing Qian } 14539de92986SMing Qian 1454145e9363SMing Qian static const struct malone_scode_handler scode_handlers[] = { 1455145e9363SMing Qian { 1456145e9363SMing Qian /* fix me, need to swap return operation after gstreamer swap */ 1457145e9363SMing Qian .pixelformat = V4L2_PIX_FMT_VC1_ANNEX_L, 1458145e9363SMing Qian .insert_scode_seq = vpu_malone_insert_scode_vc1_l_seq, 1459145e9363SMing Qian .insert_scode_pic = vpu_malone_insert_scode_vc1_l_pic, 1460145e9363SMing Qian }, 1461145e9363SMing Qian { 1462145e9363SMing Qian .pixelformat = V4L2_PIX_FMT_VC1_ANNEX_G, 1463145e9363SMing Qian .insert_scode_pic = vpu_malone_insert_scode_vc1_g_pic, 1464145e9363SMing Qian }, 1465145e9363SMing Qian { 1466145e9363SMing Qian .pixelformat = V4L2_PIX_FMT_VP8, 1467145e9363SMing Qian .insert_scode_seq = vpu_malone_insert_scode_vp8_seq, 1468145e9363SMing Qian .insert_scode_pic = vpu_malone_insert_scode_vp8_pic, 1469145e9363SMing Qian }, 14709de92986SMing Qian { 14719de92986SMing Qian .pixelformat = V4L2_PIX_FMT_SPK, 14729de92986SMing Qian .insert_scode_seq = vpu_malone_insert_scode_spk_seq, 14739de92986SMing Qian .insert_scode_pic = vpu_malone_insert_scode_spk_pic, 14749de92986SMing Qian }, 1475145e9363SMing Qian }; 1476145e9363SMing Qian 1477145e9363SMing Qian static const struct malone_scode_handler *get_scode_handler(u32 pixelformat) 1478145e9363SMing Qian { 1479145e9363SMing Qian int i; 1480145e9363SMing Qian 1481145e9363SMing Qian for (i = 0; i < ARRAY_SIZE(scode_handlers); i++) { 1482145e9363SMing Qian if (scode_handlers[i].pixelformat == pixelformat) 1483145e9363SMing Qian return &scode_handlers[i]; 1484145e9363SMing Qian } 1485145e9363SMing Qian 1486145e9363SMing Qian return NULL; 1487145e9363SMing Qian } 1488145e9363SMing Qian 1489145e9363SMing Qian static int vpu_malone_insert_scode(struct malone_scode_t *scode, u32 type) 1490145e9363SMing Qian { 1491145e9363SMing Qian const struct malone_scode_handler *handler; 1492145e9363SMing Qian int ret = 0; 1493145e9363SMing Qian 1494145e9363SMing Qian if (!scode || !scode->inst || !scode->vb) 1495145e9363SMing Qian return 0; 1496145e9363SMing Qian 1497145e9363SMing Qian scode->need_data = 1; 1498145e9363SMing Qian handler = get_scode_handler(scode->inst->out_format.pixfmt); 1499145e9363SMing Qian if (!handler) 1500145e9363SMing Qian return 0; 1501145e9363SMing Qian 1502145e9363SMing Qian switch (type) { 1503145e9363SMing Qian case SCODE_SEQUENCE: 1504145e9363SMing Qian if (handler->insert_scode_seq) 1505145e9363SMing Qian ret = handler->insert_scode_seq(scode); 1506145e9363SMing Qian break; 1507145e9363SMing Qian case SCODE_PICTURE: 1508145e9363SMing Qian if (handler->insert_scode_pic) 1509145e9363SMing Qian ret = handler->insert_scode_pic(scode); 1510145e9363SMing Qian break; 1511145e9363SMing Qian default: 1512145e9363SMing Qian break; 1513145e9363SMing Qian } 1514145e9363SMing Qian 1515145e9363SMing Qian return ret; 1516145e9363SMing Qian } 1517145e9363SMing Qian 1518145e9363SMing Qian static int vpu_malone_input_frame_data(struct vpu_malone_str_buffer __iomem *str_buf, 1519145e9363SMing Qian struct vpu_inst *inst, struct vb2_buffer *vb, 1520145e9363SMing Qian u32 disp_imm) 1521145e9363SMing Qian { 1522145e9363SMing Qian struct malone_scode_t scode; 1523145e9363SMing Qian struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); 1524145e9363SMing Qian u32 wptr = readl(&str_buf->wptr); 1525145e9363SMing Qian int size = 0; 1526145e9363SMing Qian int ret = 0; 1527145e9363SMing Qian 1528145e9363SMing Qian /*add scode: SCODE_SEQUENCE, SCODE_PICTURE, SCODE_SLICE*/ 1529145e9363SMing Qian scode.inst = inst; 1530145e9363SMing Qian scode.vb = vb; 1531145e9363SMing Qian scode.wptr = wptr; 1532145e9363SMing Qian scode.need_data = 1; 1533145e9363SMing Qian if (vbuf->sequence == 0 || vpu_vb_is_codecconfig(vbuf)) 1534145e9363SMing Qian ret = vpu_malone_insert_scode(&scode, SCODE_SEQUENCE); 1535145e9363SMing Qian 1536145e9363SMing Qian if (ret < 0) 1537145e9363SMing Qian return -ENOMEM; 1538145e9363SMing Qian size += ret; 1539145e9363SMing Qian wptr = scode.wptr; 1540145e9363SMing Qian if (!scode.need_data) { 1541145e9363SMing Qian vpu_malone_update_wptr(str_buf, wptr); 1542145e9363SMing Qian return size; 1543145e9363SMing Qian } 1544145e9363SMing Qian 1545145e9363SMing Qian ret = vpu_malone_insert_scode(&scode, SCODE_PICTURE); 1546145e9363SMing Qian if (ret < 0) 1547145e9363SMing Qian return -ENOMEM; 1548145e9363SMing Qian size += ret; 1549145e9363SMing Qian wptr = scode.wptr; 1550145e9363SMing Qian 1551145e9363SMing Qian ret = vpu_helper_copy_to_stream_buffer(&inst->stream_buffer, 1552145e9363SMing Qian &wptr, 1553145e9363SMing Qian vb2_get_plane_payload(vb, 0), 1554145e9363SMing Qian vb2_plane_vaddr(vb, 0)); 1555a9f7224cSMing Qian if (ret < 0) 1556145e9363SMing Qian return -ENOMEM; 1557a9f7224cSMing Qian size += vb2_get_plane_payload(vb, 0); 1558145e9363SMing Qian 1559145e9363SMing Qian vpu_malone_update_wptr(str_buf, wptr); 1560145e9363SMing Qian 1561145e9363SMing Qian if (disp_imm && !vpu_vb_is_codecconfig(vbuf)) { 1562145e9363SMing Qian ret = vpu_malone_add_scode(inst->core->iface, 1563145e9363SMing Qian inst->id, 1564145e9363SMing Qian &inst->stream_buffer, 1565145e9363SMing Qian inst->out_format.pixfmt, 1566145e9363SMing Qian SCODE_PADDING_BUFFLUSH); 1567145e9363SMing Qian if (ret < 0) 1568145e9363SMing Qian return ret; 1569145e9363SMing Qian size += ret; 1570145e9363SMing Qian } 1571145e9363SMing Qian 1572145e9363SMing Qian return size; 1573145e9363SMing Qian } 1574145e9363SMing Qian 1575145e9363SMing Qian static int vpu_malone_input_stream_data(struct vpu_malone_str_buffer __iomem *str_buf, 1576145e9363SMing Qian struct vpu_inst *inst, struct vb2_buffer *vb) 1577145e9363SMing Qian { 1578145e9363SMing Qian u32 wptr = readl(&str_buf->wptr); 1579145e9363SMing Qian int ret = 0; 1580145e9363SMing Qian 1581145e9363SMing Qian ret = vpu_helper_copy_to_stream_buffer(&inst->stream_buffer, 1582145e9363SMing Qian &wptr, 1583145e9363SMing Qian vb2_get_plane_payload(vb, 0), 1584145e9363SMing Qian vb2_plane_vaddr(vb, 0)); 1585a9f7224cSMing Qian if (ret < 0) 1586145e9363SMing Qian return -ENOMEM; 1587145e9363SMing Qian 1588145e9363SMing Qian vpu_malone_update_wptr(str_buf, wptr); 1589145e9363SMing Qian 1590145e9363SMing Qian return ret; 1591145e9363SMing Qian } 1592145e9363SMing Qian 1593145e9363SMing Qian static int vpu_malone_input_ts(struct vpu_inst *inst, s64 timestamp, u32 size) 1594145e9363SMing Qian { 1595145e9363SMing Qian struct vpu_ts_info info; 1596145e9363SMing Qian 1597145e9363SMing Qian memset(&info, 0, sizeof(info)); 1598145e9363SMing Qian info.timestamp = timestamp; 1599145e9363SMing Qian info.size = size; 1600145e9363SMing Qian 1601145e9363SMing Qian return vpu_session_fill_timestamp(inst, &info); 1602145e9363SMing Qian } 1603145e9363SMing Qian 1604145e9363SMing Qian int vpu_malone_input_frame(struct vpu_shared_addr *shared, 1605145e9363SMing Qian struct vpu_inst *inst, struct vb2_buffer *vb) 1606145e9363SMing Qian { 1607145e9363SMing Qian struct vpu_dec_ctrl *hc = shared->priv; 1608145e9363SMing Qian struct vb2_v4l2_buffer *vbuf; 1609145e9363SMing Qian struct vpu_malone_str_buffer __iomem *str_buf = hc->str_buf[inst->id]; 1610145e9363SMing Qian u32 disp_imm = hc->codec_param[inst->id].disp_imm; 1611145e9363SMing Qian u32 size; 1612145e9363SMing Qian int ret; 1613145e9363SMing Qian 1614145e9363SMing Qian if (vpu_malone_is_non_frame_mode(shared, inst->id)) 1615145e9363SMing Qian ret = vpu_malone_input_stream_data(str_buf, inst, vb); 1616145e9363SMing Qian else 1617145e9363SMing Qian ret = vpu_malone_input_frame_data(str_buf, inst, vb, disp_imm); 1618145e9363SMing Qian if (ret < 0) 1619145e9363SMing Qian return ret; 1620145e9363SMing Qian size = ret; 1621145e9363SMing Qian 1622145e9363SMing Qian /* 1623145e9363SMing Qian * if buffer only contain codec data, and the timestamp is invalid, 1624145e9363SMing Qian * don't put the invalid timestamp to resync 1625145e9363SMing Qian * merge the data to next frame 1626145e9363SMing Qian */ 1627145e9363SMing Qian vbuf = to_vb2_v4l2_buffer(vb); 1628a4dca209SMing Qian if (vpu_vb_is_codecconfig(vbuf)) { 1629145e9363SMing Qian inst->extra_size += size; 1630145e9363SMing Qian return 0; 1631145e9363SMing Qian } 1632145e9363SMing Qian if (inst->extra_size) { 1633145e9363SMing Qian size += inst->extra_size; 1634145e9363SMing Qian inst->extra_size = 0; 1635145e9363SMing Qian } 1636145e9363SMing Qian 1637145e9363SMing Qian ret = vpu_malone_input_ts(inst, vb->timestamp, size); 1638145e9363SMing Qian if (ret) 1639145e9363SMing Qian return ret; 1640145e9363SMing Qian 1641145e9363SMing Qian return 0; 1642145e9363SMing Qian } 1643145e9363SMing Qian 1644145e9363SMing Qian static bool vpu_malone_check_ready(struct vpu_shared_addr *shared, u32 instance) 1645145e9363SMing Qian { 1646145e9363SMing Qian struct malone_iface *iface = shared->iface; 1647145e9363SMing Qian struct vpu_rpc_buffer_desc *desc = &iface->api_cmd_buffer_desc[instance]; 1648145e9363SMing Qian u32 size = desc->end - desc->start; 1649145e9363SMing Qian u32 rptr = desc->rptr; 1650145e9363SMing Qian u32 wptr = desc->wptr; 1651a9f7224cSMing Qian u32 used; 1652145e9363SMing Qian 1653a9f7224cSMing Qian if (!size) 1654a9f7224cSMing Qian return true; 1655a9f7224cSMing Qian 1656a9f7224cSMing Qian used = (wptr + size - rptr) % size; 1657a9f7224cSMing Qian if (used < (size / 2)) 1658145e9363SMing Qian return true; 1659145e9363SMing Qian 1660145e9363SMing Qian return false; 1661145e9363SMing Qian } 1662145e9363SMing Qian 1663145e9363SMing Qian bool vpu_malone_is_ready(struct vpu_shared_addr *shared, u32 instance) 1664145e9363SMing Qian { 1665145e9363SMing Qian u32 cnt = 0; 1666145e9363SMing Qian 1667145e9363SMing Qian while (!vpu_malone_check_ready(shared, instance)) { 1668145e9363SMing Qian if (cnt > 30) 1669145e9363SMing Qian return false; 1670145e9363SMing Qian mdelay(1); 1671145e9363SMing Qian cnt++; 1672145e9363SMing Qian } 1673145e9363SMing Qian return true; 1674145e9363SMing Qian } 1675145e9363SMing Qian 1676145e9363SMing Qian int vpu_malone_pre_cmd(struct vpu_shared_addr *shared, u32 instance) 1677145e9363SMing Qian { 1678145e9363SMing Qian if (!vpu_malone_is_ready(shared, instance)) 1679145e9363SMing Qian return -EINVAL; 1680145e9363SMing Qian 1681145e9363SMing Qian return 0; 1682145e9363SMing Qian } 1683145e9363SMing Qian 1684145e9363SMing Qian int vpu_malone_post_cmd(struct vpu_shared_addr *shared, u32 instance) 1685145e9363SMing Qian { 1686145e9363SMing Qian struct malone_iface *iface = shared->iface; 1687145e9363SMing Qian struct vpu_rpc_buffer_desc *desc = &iface->api_cmd_buffer_desc[instance]; 1688145e9363SMing Qian 1689145e9363SMing Qian desc->wptr++; 1690145e9363SMing Qian if (desc->wptr == desc->end) 1691145e9363SMing Qian desc->wptr = desc->start; 1692145e9363SMing Qian 1693145e9363SMing Qian return 0; 1694145e9363SMing Qian } 1695145e9363SMing Qian 1696145e9363SMing Qian int vpu_malone_init_instance(struct vpu_shared_addr *shared, u32 instance) 1697145e9363SMing Qian { 1698145e9363SMing Qian struct malone_iface *iface = shared->iface; 1699145e9363SMing Qian struct vpu_rpc_buffer_desc *desc = &iface->api_cmd_buffer_desc[instance]; 1700145e9363SMing Qian 1701145e9363SMing Qian desc->wptr = desc->rptr; 1702145e9363SMing Qian if (desc->wptr == desc->end) 1703145e9363SMing Qian desc->wptr = desc->start; 1704145e9363SMing Qian 1705145e9363SMing Qian return 0; 1706145e9363SMing Qian } 1707145e9363SMing Qian 1708145e9363SMing Qian u32 vpu_malone_get_max_instance_count(struct vpu_shared_addr *shared) 1709145e9363SMing Qian { 1710145e9363SMing Qian struct malone_iface *iface = shared->iface; 1711145e9363SMing Qian 1712145e9363SMing Qian return iface->max_streams; 1713145e9363SMing Qian } 1714