From: Sidraya <sidraya.bj@xxxxxxxxxxxxxxxxxxx> This patch prepares the picture commands for the firmware it includes reconstructed and alternate picture commands. Signed-off-by: Amit Makani <amit.makani@xxxxxx> Signed-off-by: Sidraya <sidraya.bj@xxxxxxxxxxxxxxxxxxx> --- MAINTAINERS | 2 + drivers/staging/media/vxd/decoder/vxd_int.c | 1137 +++++++++++++++++++ drivers/staging/media/vxd/decoder/vxd_int.h | 128 +++ 3 files changed, 1267 insertions(+) create mode 100644 drivers/staging/media/vxd/decoder/vxd_int.c create mode 100644 drivers/staging/media/vxd/decoder/vxd_int.h diff --git a/MAINTAINERS b/MAINTAINERS index 2327ea12caa6..7b21ebfc61d4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -19548,6 +19548,8 @@ F: drivers/staging/media/vxd/decoder/img_dec_common.h F: drivers/staging/media/vxd/decoder/vxd_core.c F: drivers/staging/media/vxd/decoder/vxd_dec.c F: drivers/staging/media/vxd/decoder/vxd_dec.h +F: drivers/staging/media/vxd/decoder/vxd_int.c +F: drivers/staging/media/vxd/decoder/vxd_int.h F: drivers/staging/media/vxd/decoder/vxd_pvdec.c F: drivers/staging/media/vxd/decoder/vxd_pvdec_priv.h F: drivers/staging/media/vxd/decoder/vxd_pvdec_regs.h diff --git a/drivers/staging/media/vxd/decoder/vxd_int.c b/drivers/staging/media/vxd/decoder/vxd_int.c new file mode 100644 index 000000000000..c75aef6deed1 --- /dev/null +++ b/drivers/staging/media/vxd/decoder/vxd_int.c @@ -0,0 +1,1137 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * VXD DEC Common low level core interface component + * + * Copyright (c) Imagination Technologies Ltd. + * Copyright (c) 2021 Texas Instruments Incorporated - http://www.ti.com/ + * + * Authors: + * Amit Makani <amit.makani@xxxxxx> + * + * Re-written for upstreamimg + * Sidraya Jayagond <sidraya.bj@xxxxxxxxxxxxxxxxxxx> + * Prashanth Kumar Amai <prashanth.ka@xxxxxxxxxxxxxxxxxxx> + */ + +#include <linux/types.h> +#include <linux/dma-mapping.h> +#include <media/v4l2-ctrls.h> +#include <media/v4l2-device.h> +#include <media/v4l2-mem2mem.h> + +#include "bspp.h" +#include "fw_interface.h" +#include "h264fw_data.h" +#include "img_errors.h" +#include "img_dec_common.h" +#include "img_pvdec_core_regs.h" +#include "img_pvdec_pixel_regs.h" +#include "img_pvdec_test_regs.h" +#include "img_vdec_fw_msg.h" +#include "img_video_bus4_mmu_regs.h" +#include "img_msvdx_core_regs.h" +#include "img_msvdx_cmds.h" +#include "reg_io2.h" +#include "scaler_setup.h" +#include "vdecdd_defs.h" +#include "vdecdd_utils.h" +#include "vdecfw_shared.h" +#include "vdec_defs.h" +#include "vxd_ext.h" +#include "vxd_int.h" +#include "vxd_props.h" + +#define MSVDX_CACHE_REF_OFFSET_V100 (72L) +#define MSVDX_CACHE_ROW_OFFSET_V100 (4L) + +#define MSVDX_CACHE_REF_OFFSET_V550 (144L) +#define MSVDX_CACHE_ROW_OFFSET_V550 (8L) + +#define GET_BITS(v, lb, n) (((v) >> (lb)) & ((1 << (n)) - 1)) +#define IS_PVDEC_PIPELINE(std) ((std) == VDEC_STD_HEVC ? 1 : 0) + +static int amsvdx_codecmode[VDEC_STD_MAX] = { + /* Invalid */ + -1, + /* MPEG2 */ + 3, + /* MPEG4 */ + 4, + /* H263 */ + 4, + /* H264 */ + 1, + /* VC1 */ + 2, + /* AVS */ + 5, + /* RealVideo (8) */ + 8, + /* JPEG */ + 0, + /* On2 VP6 */ + 10, + /* On2 VP8 */ + 11, + /* Invalid */ +#ifdef HAS_VP9 + /* On2 VP9 */ + 13, +#endif + /* Sorenson */ + 4, + /* HEVC */ + 12, +}; + +struct msvdx_scaler_coeff_cmds { + unsigned int acmd_horizluma_coeff[VDECFW_NUM_SCALE_COEFFS]; + unsigned int acmd_vertluma_coeff[VDECFW_NUM_SCALE_COEFFS]; + unsigned int acmd_horizchroma_coeff[VDECFW_NUM_SCALE_COEFFS]; + unsigned int acmd_vertchroma_coeff[VDECFW_NUM_SCALE_COEFFS]; +}; + +static struct vxd_vidstd_props astd_props[] = { + { VDEC_STD_MPEG2, CORE_REVISION(7, 0, 0), 64, 16, 4096, 4096, 0, 8, 8, + PIXEL_FORMAT_420 }, + { VDEC_STD_MPEG4, CORE_REVISION(7, 0, 0), 64, 16, 4096, 4096, 0, 8, 8, + PIXEL_FORMAT_420 }, + { VDEC_STD_H263, CORE_REVISION(7, 0, 0), 64, 16, 4096, 4096, 0, 8, 8, + PIXEL_FORMAT_420 }, + { VDEC_STD_H264, CORE_REVISION(7, 0, 0), 64, 16, 4096, 4096, 0x10000, 8, + 8, PIXEL_FORMAT_420 }, + { VDEC_STD_VC1, CORE_REVISION(7, 0, 0), 80, 16, 4096, 4096, 0, 8, 8, + PIXEL_FORMAT_420 }, + { VDEC_STD_AVS, CORE_REVISION(7, 0, 0), 64, 16, 4096, 4096, 0, 8, 8, + PIXEL_FORMAT_420 }, + { VDEC_STD_REAL, CORE_REVISION(7, 0, 0), 64, 16, 4096, 4096, 0, 8, 8, + PIXEL_FORMAT_420 }, + { VDEC_STD_JPEG, CORE_REVISION(7, 0, 0), 64, 16, 32768, 32768, 0, 8, 8, + PIXEL_FORMAT_444 }, + { VDEC_STD_VP6, CORE_REVISION(7, 0, 0), 64, 16, 4096, 4096, 0, 8, 8, + PIXEL_FORMAT_420 }, + { VDEC_STD_VP8, CORE_REVISION(7, 0, 0), 64, 16, 4096, 4096, 0, 8, 8, + PIXEL_FORMAT_420 }, + { VDEC_STD_SORENSON, CORE_REVISION(7, 0, 0), 64, 16, 4096, 4096, 0, 8, + 8, PIXEL_FORMAT_420 }, + { VDEC_STD_HEVC, CORE_REVISION(7, 0, 0), 64, 16, 8192, 8192, 0, 8, 8, + PIXEL_FORMAT_420 }, +}; + +enum vdec_msvdx_async_mode { + VDEC_MSVDX_ASYNC_NORMAL, + VDEC_MSVDX_ASYNC_VDMC, + VDEC_MSVDX_ASYNC_VDEB, + VDEC_MSVDX_ASYNC_FORCE32BITS = 0x7FFFFFFFU +}; + +/* MSVDX row strides for video buffers. */ +static const unsigned int amsvdx_64byte_row_stride[] = { + 384, 768, 1280, 1920, 512, 1024, 2048, 4096 +}; + +/* MSVDX row strides for jpeg buffers. */ +static const unsigned int amsvdx_jpeg_row_stride[] = { + 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576, 32768 +}; + +/* VXD Core major revision. */ +static unsigned int maj_rev; +/* VXD Core minor revision. */ +static unsigned int min_rev; +/* VXD Core maintenance revision. */ +static unsigned int maint_rev; + +static int get_stride_code(enum vdec_vid_std vidstd, unsigned int row_stride) +{ + unsigned int i; + + if (vidstd == VDEC_STD_JPEG) { + for (i = 0; i < (sizeof(amsvdx_jpeg_row_stride) / + sizeof(amsvdx_jpeg_row_stride[0])); i++) { + if (amsvdx_jpeg_row_stride[i] == row_stride) + return i; + } + } else { + for (i = 0; i < (sizeof(amsvdx_64byte_row_stride) / + sizeof(amsvdx_64byte_row_stride[0])); i++) { + if (amsvdx_64byte_row_stride[i] == row_stride) + return i; + } + } + + return -1; +} + +/* Obtains the hardware defined video profile. */ +static unsigned int vxd_getprofile(enum vdec_vid_std vidstd, unsigned int std_profile) +{ + unsigned int profile = 0; + + switch (vidstd) { + case VDEC_STD_H264: + switch (std_profile) { + case H264_PROFILE_BASELINE: + profile = 0; + break; + + /* + * Extended may be attempted as Baseline or + * Main depending on the constraint_set_flags + */ + case H264_PROFILE_EXTENDED: + case H264_PROFILE_MAIN: + profile = 1; + break; + + case H264_PROFILE_HIGH: + case H264_PROFILE_HIGH444: + case H264_PROFILE_HIGH422: + case H264_PROFILE_HIGH10: + case H264_PROFILE_CAVLC444: + case H264_PROFILE_MVC_HIGH: + case H264_PROFILE_MVC_STEREO: + profile = 2; + break; + default: + profile = 2; + break; + } + break; + + default: + profile = 0; + break; + } + + return profile; +} + +static int vxd_getcoreproperties(struct vxd_coreprops *coreprops, + unsigned int corerev, + unsigned int pvdec_coreid, unsigned int mmu_config0, + unsigned int mmu_config1, unsigned int *pixel_pipecfg, + unsigned int *pixel_misccfg, unsigned int max_framecfg) +{ + unsigned int group_id; + unsigned int core_id; + unsigned int core_config; + unsigned int extended_address_range; + unsigned char group_size = 0; + unsigned char pipe_minus1 = 0; + unsigned int max_h264_hw_chromaformat = 0; + unsigned int max_hevc_hw_chromaformat = 0; + unsigned int max_bitdepth_luma = 0; + unsigned int i; + + struct pvdec_core_rev core_rev; + + if (!coreprops || !pixel_pipecfg || !pixel_misccfg) + return IMG_ERROR_INVALID_PARAMETERS; + + /* PVDEC Core Revision Information */ + core_rev.maj_rev = REGIO_READ_FIELD(corerev, PVDEC_CORE, CR_PVDEC_CORE_REV, + CR_PVDEC_MAJOR_REV); + core_rev.min_rev = REGIO_READ_FIELD(corerev, PVDEC_CORE, CR_PVDEC_CORE_REV, + CR_PVDEC_MINOR_REV); + core_rev.maint_rev = REGIO_READ_FIELD(corerev, PVDEC_CORE, CR_PVDEC_CORE_REV, + CR_PVDEC_MAINT_REV); + + /* core id */ + group_id = REGIO_READ_FIELD(pvdec_coreid, PVDEC_CORE, CR_PVDEC_CORE_ID, CR_GROUP_ID); + core_id = REGIO_READ_FIELD(pvdec_coreid, PVDEC_CORE, CR_PVDEC_CORE_ID, CR_CORE_ID); + + /* Ensure that the core is IMG Video Decoder (PVDEC). */ + if (group_id != 3 || core_id != 3) + return IMG_ERROR_DEVICE_NOT_FOUND; + + core_config = REGIO_READ_FIELD(pvdec_coreid, PVDEC_CORE, + CR_PVDEC_CORE_ID, CR_PVDEC_CORE_CONFIG); + + memset(coreprops, 0, sizeof(*(coreprops))); + + /* Construct core version name. */ + snprintf(coreprops->aversion, VER_STR_LEN, "%d.%d.%d", + core_rev.maj_rev, core_rev.min_rev, core_rev.maint_rev); + + coreprops->mmu_support_stride_per_context = + REGIO_READ_FIELD(mmu_config1, IMG_VIDEO_BUS4_MMU, + MMU_CONFIG1, + SUPPORT_STRIDE_PER_CONTEXT) == 1 ? 1 : 0; + + coreprops->mmu_support_secure = REGIO_READ_FIELD(mmu_config1, IMG_VIDEO_BUS4_MMU, + MMU_CONFIG1, SUPPORT_SECURE) == 1 ? 1 : 0; + + extended_address_range = REGIO_READ_FIELD(mmu_config0, IMG_VIDEO_BUS4_MMU, + MMU_CONFIG0, EXTENDED_ADDR_RANGE); + + switch (extended_address_range) { + case 0: + coreprops->mmu_type = MMU_TYPE_32BIT; + break; + case 4: + coreprops->mmu_type = MMU_TYPE_36BIT; + break; + case 8: + coreprops->mmu_type = MMU_TYPE_40BIT; + break; + default: + return IMG_ERROR_NOT_SUPPORTED; + } + + group_size += REGIO_READ_FIELD(mmu_config0, IMG_VIDEO_BUS4_MMU, + MMU_CONFIG0, GROUP_OVERRIDE_SIZE); + + coreprops->num_entropy_pipes = core_config & 0xF; + coreprops->num_pixel_pipes = core_config >> 4 & 0xF; +#ifdef DEBUG_DECODER_DRIVER + pr_info("PVDEC revision %08x detected, id %08x.\n", corerev, core_id); + pr_info("Found %d entropy pipe(s), %d pixel pipe(s), %d group size", + coreprops->num_entropy_pipes, coreprops->num_pixel_pipes, + group_size); +#endif + + /* Set global rev info variables used by macros */ + maj_rev = core_rev.maj_rev; + min_rev = core_rev.min_rev; + maint_rev = core_rev.maint_rev; + + /* Default settings */ + for (i = 0; i < ARRAY_SIZE(astd_props); i++) { + struct vxd_vidstd_props *pvidstd_props = + &coreprops->vidstd_props[astd_props[i].vidstd]; + /* + * Update video standard properties if the core is beyond + * specified version and the properties are for newer cores + * than the previous. + */ + if (FROM_REV(MAJOR_REVISION((int)astd_props[i].core_rev), + MINOR_REVISION((int)astd_props[i].core_rev), + MAINT_REVISION((int)astd_props[i].core_rev), int) && + astd_props[i].core_rev >= pvidstd_props->core_rev) { + *pvidstd_props = astd_props[i]; + + if (pvidstd_props->vidstd != VDEC_STD_JPEG && + (FROM_REV(8, 0, 0, int)) && (pvidstd_props->vidstd == + VDEC_STD_HEVC ? 1 : 0)) { + /* + * override default values with values + * specified in HW (register does not + * exist in previous cores) + */ + pvidstd_props->max_width = + 2 << REGIO_READ_FIELD(max_framecfg, + PVDEC_PIXEL, + CR_MAX_FRAME_CONFIG, + CR_PVDEC_HOR_MSB); + + pvidstd_props->max_height = + 2 << REGIO_READ_FIELD(max_framecfg, + PVDEC_PIXEL, + CR_MAX_FRAME_CONFIG, + CR_PVDEC_VER_MSB); + } else if (pvidstd_props->vidstd != VDEC_STD_JPEG && + (FROM_REV(8, 0, 0, int))) { + pvidstd_props->max_width = + 2 << REGIO_READ_FIELD(max_framecfg, + PVDEC_PIXEL, + CR_MAX_FRAME_CONFIG, + CR_MSVDX_HOR_MSB); + + pvidstd_props->max_height = + 2 << REGIO_READ_FIELD(max_framecfg, + PVDEC_PIXEL, + CR_MAX_FRAME_CONFIG, + CR_MSVDX_VER_MSB); + } + } + } + + /* Populate the core properties. */ + if (GET_BITS(core_config, 11, 1)) + coreprops->hd_support = 1; + + for (pipe_minus1 = 0; pipe_minus1 < coreprops->num_pixel_pipes; + pipe_minus1++) { + unsigned int current_bitdepth = + GET_BITS(pixel_misccfg[pipe_minus1], 4, 3) + 8; + unsigned int current_h264_hw_chromaformat = + GET_BITS(pixel_misccfg[pipe_minus1], 0, 2); + unsigned int current_hevc_hw_chromaformat = + GET_BITS(pixel_misccfg[pipe_minus1], 2, 2); +#ifdef DEBUG_DECODER_DRIVER + pr_info("cur_bitdepth: %d cur_h264_hw_chromaformat: %d", + current_bitdepth, current_h264_hw_chromaformat); + pr_info("cur_hevc_hw_chromaformat: %d pipe_minus1: %d\n", + current_hevc_hw_chromaformat, pipe_minus1); +#endif + + if (GET_BITS(pixel_misccfg[pipe_minus1], 8, 1)) + coreprops->rotation_support[pipe_minus1] = 1; + + if (GET_BITS(pixel_misccfg[pipe_minus1], 9, 1)) + coreprops->scaling_support[pipe_minus1] = 1; + + coreprops->num_streams[pipe_minus1] = + GET_BITS(pixel_misccfg[pipe_minus1], 12, 2) + 1; + + /* Video standards. */ + coreprops->mpeg2[pipe_minus1] = + GET_BITS(pixel_pipecfg[pipe_minus1], 0, 1) ? 1 : 0; + coreprops->mpeg4[pipe_minus1] = + GET_BITS(pixel_pipecfg[pipe_minus1], 1, 1) ? 1 : 0; + coreprops->h264[pipe_minus1] = + GET_BITS(pixel_pipecfg[pipe_minus1], 2, 1) ? 1 : 0; + coreprops->vc1[pipe_minus1] = + GET_BITS(pixel_pipecfg[pipe_minus1], 3, 1) ? 1 : 0; + coreprops->jpeg[pipe_minus1] = + GET_BITS(pixel_pipecfg[pipe_minus1], 5, 1) ? 1 : 0; + coreprops->avs[pipe_minus1] = + GET_BITS(pixel_pipecfg[pipe_minus1], 7, 1) ? 1 : 0; + coreprops->real[pipe_minus1] = + GET_BITS(pixel_pipecfg[pipe_minus1], 8, 1) ? 1 : 0; + coreprops->vp6[pipe_minus1] = + GET_BITS(pixel_pipecfg[pipe_minus1], 9, 1) ? 1 : 0; + coreprops->vp8[pipe_minus1] = + GET_BITS(pixel_pipecfg[pipe_minus1], 10, 1) ? 1 : 0; + coreprops->hevc[pipe_minus1] = + GET_BITS(pixel_pipecfg[pipe_minus1], 22, 1) ? 1 : 0; + + max_bitdepth_luma = (max_bitdepth_luma > current_bitdepth ? + max_bitdepth_luma : current_bitdepth); + max_h264_hw_chromaformat = (max_h264_hw_chromaformat > + current_h264_hw_chromaformat ? max_h264_hw_chromaformat + : current_h264_hw_chromaformat); + max_hevc_hw_chromaformat = (max_hevc_hw_chromaformat > + current_hevc_hw_chromaformat ? max_hevc_hw_chromaformat + : current_hevc_hw_chromaformat); + } + + /* Override default bit-depth with value signalled explicitly by core. */ + coreprops->vidstd_props[0].max_luma_bitdepth = max_bitdepth_luma; + coreprops->vidstd_props[0].max_chroma_bitdepth = + coreprops->vidstd_props[0].max_luma_bitdepth; + + for (i = 1; i < VDEC_STD_MAX; i++) { + coreprops->vidstd_props[i].max_luma_bitdepth = + coreprops->vidstd_props[0].max_luma_bitdepth; + coreprops->vidstd_props[i].max_chroma_bitdepth = + coreprops->vidstd_props[0].max_chroma_bitdepth; + } + + switch (max_h264_hw_chromaformat) { + case 1: + coreprops->vidstd_props[VDEC_STD_H264].max_chroma_format = + PIXEL_FORMAT_420; + break; + + case 2: + coreprops->vidstd_props[VDEC_STD_H264].max_chroma_format = + PIXEL_FORMAT_422; + break; + + case 3: + coreprops->vidstd_props[VDEC_STD_H264].max_chroma_format = + PIXEL_FORMAT_444; + break; + + default: + break; + } + + switch (max_hevc_hw_chromaformat) { + case 1: + coreprops->vidstd_props[VDEC_STD_HEVC].max_chroma_format = + PIXEL_FORMAT_420; + break; + + case 2: + coreprops->vidstd_props[VDEC_STD_HEVC].max_chroma_format = + PIXEL_FORMAT_422; + break; + + case 3: + coreprops->vidstd_props[VDEC_STD_HEVC].max_chroma_format = + PIXEL_FORMAT_444; + break; + + default: + break; + } + + return 0; +} + +static unsigned char vxd_is_supported_byatleast_onepipe(const unsigned char *features, + unsigned int num_pipes) +{ + unsigned int i; + + VDEC_ASSERT(features); + VDEC_ASSERT(num_pipes <= VDEC_MAX_PIXEL_PIPES); + + for (i = 0; i < num_pipes; i++) { + if (features[i]) + return 1; + } + + return 0; +} + +void vxd_set_reconpictcmds(const struct vdecdd_str_unit *str_unit, + const struct vdec_str_configdata *str_configdata, + const struct vdec_str_opconfig *output_config, + const struct vxd_coreprops *coreprops, + const struct vxd_buffers *buffers, + unsigned int *pict_cmds) +{ + struct pixel_pixinfo *pixel_info; + unsigned int row_stride_code; + unsigned char benable_auxline_buf = 1; + + unsigned int coded_height; + unsigned int coded_width; + unsigned int disp_height; + unsigned int disp_width; + unsigned int profile; + unsigned char plane; + unsigned int y_stride; + unsigned int uv_stride; + unsigned int v_stride; + unsigned int cache_ref_offset; + unsigned int cache_row_offset; + + if (str_configdata->vid_std == VDEC_STD_JPEG) { + disp_height = 0; + disp_width = 0; + coded_height = 0; + coded_width = 0; + } else { + coded_height = ALIGN(str_unit->pict_hdr_info->coded_frame_size.height, + (str_unit->pict_hdr_info->field) ? + 2 * VDEC_MB_DIMENSION : VDEC_MB_DIMENSION); + /* Hardware field is coded size - 1 */ + coded_height -= 1; + + coded_width = ALIGN(str_unit->pict_hdr_info->coded_frame_size.width, + VDEC_MB_DIMENSION); + /* Hardware field is coded size - 1 */ + coded_width -= 1; + + disp_height = str_unit->pict_hdr_info->disp_info.enc_disp_region.height + + str_unit->pict_hdr_info->disp_info.enc_disp_region.left_offset - 1; + disp_width = str_unit->pict_hdr_info->disp_info.enc_disp_region.width + + str_unit->pict_hdr_info->disp_info.enc_disp_region.top_offset - 1; + } + /* + * Display picture size (DISPLAY_PICTURE) + * The display to be written is not the actual video size to be + * displayed but a number that has to differ from the coded pixel size + * by less than 1MB (coded_size-display_size <= 0x0F). Because H264 can + * have a different display size, we need to check and write + * the coded_size again in the display_size register if this condition + * is not fulfilled. + */ + if (str_configdata->vid_std != VDEC_STD_VC1 && ((coded_height - disp_height) > 0x0F)) { + REGIO_WRITE_FIELD_LITE(pict_cmds[VDECFW_CMD_DISPLAY_PICTURE], + MSVDX_CMDS, DISPLAY_PICTURE_SIZE, + DISPLAY_PICTURE_HEIGHT, + coded_height, unsigned int); + } else { + REGIO_WRITE_FIELD_LITE(pict_cmds[VDECFW_CMD_DISPLAY_PICTURE], + MSVDX_CMDS, DISPLAY_PICTURE_SIZE, + DISPLAY_PICTURE_HEIGHT, + disp_height, unsigned int); + } + + if (((coded_width - disp_width) > 0x0F)) { + REGIO_WRITE_FIELD_LITE(pict_cmds[VDECFW_CMD_DISPLAY_PICTURE], + MSVDX_CMDS, DISPLAY_PICTURE_SIZE, + DISPLAY_PICTURE_WIDTH, + coded_width, unsigned int); + } else { + REGIO_WRITE_FIELD_LITE(pict_cmds[VDECFW_CMD_DISPLAY_PICTURE], + MSVDX_CMDS, DISPLAY_PICTURE_SIZE, + DISPLAY_PICTURE_WIDTH, + disp_width, unsigned int); + } + + REGIO_WRITE_FIELD_LITE(pict_cmds[VDECFW_CMD_CODED_PICTURE], + MSVDX_CMDS, CODED_PICTURE_SIZE, + CODED_PICTURE_HEIGHT, + coded_height, unsigned int); + REGIO_WRITE_FIELD_LITE(pict_cmds[VDECFW_CMD_CODED_PICTURE], + MSVDX_CMDS, CODED_PICTURE_SIZE, + CODED_PICTURE_WIDTH, + coded_width, unsigned int); + + /* + * For standards where dpb_diff != 1 and chroma format != 420 + * cache_ref_offset has to be calculated in the F/W. + */ + if (str_configdata->vid_std != VDEC_STD_HEVC && str_configdata->vid_std != VDEC_STD_H264) { + unsigned int log2_size, cache_size, luma_size; + unsigned char is_hevc_supported, is_hevc444_supported = 0; + + is_hevc_supported = + vxd_is_supported_byatleast_onepipe(coreprops->hevc, + coreprops->num_pixel_pipes); + + if (is_hevc_supported) { + is_hevc444_supported = + coreprops->vidstd_props[VDEC_STD_HEVC].max_chroma_format == + PIXEL_FORMAT_444 ? 1 : 0; + } + + log2_size = 9 + (is_hevc_supported ? 1 : 0) + (is_hevc444_supported ? 1 : 0); + cache_size = 3 << log2_size; + luma_size = (cache_size * 2) / 3; + cache_ref_offset = (luma_size * 15) / 32; + cache_ref_offset = (cache_ref_offset + 7) & (~7); + cache_row_offset = 0x0C; + + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_MC_CACHE_CONFIGURATION], + MSVDX_CMDS, MC_CACHE_CONFIGURATION, + CONFIG_REF_CHROMA_ADJUST, 1, + unsigned int, unsigned int); + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_MC_CACHE_CONFIGURATION], + MSVDX_CMDS, MC_CACHE_CONFIGURATION, + CONFIG_REF_OFFSET, cache_ref_offset, + unsigned int, unsigned int); + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_MC_CACHE_CONFIGURATION], + MSVDX_CMDS, MC_CACHE_CONFIGURATION, + CONFIG_ROW_OFFSET, cache_row_offset, + unsigned int, unsigned int); + } + + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_OPERATING_MODE], + MSVDX_CMDS, OPERATING_MODE, CODEC_MODE, + amsvdx_codecmode[str_configdata->vid_std], + unsigned int, unsigned int); + + profile = str_unit->seq_hdr_info->com_sequ_hdr_info.codec_profile; + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_OPERATING_MODE], + MSVDX_CMDS, OPERATING_MODE, CODEC_PROFILE, + vxd_getprofile(str_configdata->vid_std, profile), + unsigned int, unsigned int); + + plane = str_unit->seq_hdr_info->com_sequ_hdr_info.separate_chroma_planes; + pixel_info = &str_unit->seq_hdr_info->com_sequ_hdr_info.pixel_info; + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_OPERATING_MODE], + MSVDX_CMDS, OPERATING_MODE, CHROMA_FORMAT, plane ? + 0 : pixel_info->chroma_fmt, unsigned int, int); + + if (str_configdata->vid_std != VDEC_STD_JPEG) { + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_EXT_OP_MODE], + MSVDX_CMDS, EXT_OP_MODE, CHROMA_FORMAT_IDC, plane ? + 0 : pixel_get_hw_chroma_format_idc + (pixel_info->chroma_fmt_idc), + unsigned int, int); + + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_EXT_OP_MODE], + MSVDX_CMDS, EXT_OP_MODE, MEMORY_PACKING, + output_config->pixel_info.mem_pkg == + PIXEL_BIT10_MP ? 1 : 0, unsigned int, int); + + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_EXT_OP_MODE], + MSVDX_CMDS, EXT_OP_MODE, BIT_DEPTH_LUMA_MINUS8, + pixel_info->bitdepth_y - 8, + unsigned int, unsigned int); + + if (pixel_info->chroma_fmt_idc == PIXEL_FORMAT_MONO) { + /* + * For monochrome streams use the same bit depth for + * chroma and luma. + */ + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_EXT_OP_MODE], + MSVDX_CMDS, EXT_OP_MODE, + BIT_DEPTH_CHROMA_MINUS8, + pixel_info->bitdepth_y - 8, + unsigned int, unsigned int); + } else { + /* + * For normal streams use the appropriate bit depth for chroma. + */ + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_EXT_OP_MODE], MSVDX_CMDS, + EXT_OP_MODE, BIT_DEPTH_CHROMA_MINUS8, + pixel_info->bitdepth_c - 8, + unsigned int, unsigned int); + } + } else { + pict_cmds[VDECFW_CMD_EXT_OP_MODE] = 0; + } + + if (str_configdata->vid_std != VDEC_STD_JPEG) { + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_OPERATING_MODE], MSVDX_CMDS, + OPERATING_MODE, CHROMA_INTERLEAVED, + PIXEL_GET_HW_CHROMA_INTERLEAVED + (output_config->pixel_info.chroma_interleave), + unsigned int, int); + } + + if (str_configdata->vid_std == VDEC_STD_JPEG) { + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_OPERATING_MODE], + MSVDX_CMDS, OPERATING_MODE, ASYNC_MODE, + VDEC_MSVDX_ASYNC_VDMC, + unsigned int, unsigned int); + } + + if (str_configdata->vid_std == VDEC_STD_H264) { + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_OPERATING_MODE], MSVDX_CMDS, + OPERATING_MODE, ASYNC_MODE, + str_unit->pict_hdr_info->discontinuous_mbs ? + VDEC_MSVDX_ASYNC_VDMC : VDEC_MSVDX_ASYNC_NORMAL, + unsigned int, int); + } + + y_stride = buffers->recon_pict->rend_info.plane_info[VDEC_PLANE_VIDEO_Y].stride; + uv_stride = buffers->recon_pict->rend_info.plane_info[VDEC_PLANE_VIDEO_UV].stride; + v_stride = buffers->recon_pict->rend_info.plane_info[VDEC_PLANE_VIDEO_V].stride; + + if (((y_stride % (VDEC_VXD_EXT_STRIDE_ALIGNMENT_DEFAULT)) == 0) && + ((uv_stride % (VDEC_VXD_EXT_STRIDE_ALIGNMENT_DEFAULT)) == 0) && + ((v_stride % (VDEC_VXD_EXT_STRIDE_ALIGNMENT_DEFAULT)) == 0)) { + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_OPERATING_MODE], + MSVDX_CMDS, OPERATING_MODE, + USE_EXT_ROW_STRIDE, 1, unsigned int, int); + + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_EXTENDED_ROW_STRIDE], + MSVDX_CMDS, EXTENDED_ROW_STRIDE, + EXT_ROW_STRIDE, y_stride >> 6, unsigned int, unsigned int); + + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_CHROMA_ROW_STRIDE], + MSVDX_CMDS, CHROMA_ROW_STRIDE, + CHROMA_ROW_STRIDE, uv_stride >> 6, unsigned int, unsigned int); + } else { + row_stride_code = get_stride_code(str_configdata->vid_std, y_stride); + + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_OPERATING_MODE], + MSVDX_CMDS, OPERATING_MODE, ROW_STRIDE, + row_stride_code & 0x7, unsigned int, unsigned int); + + if (str_configdata->vid_std == VDEC_STD_JPEG) { + /* + * Use the unused chroma interleaved flag + * to hold MSB of row stride code + */ + IMG_ASSERT(row_stride_code < 16); + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_OPERATING_MODE], + MSVDX_CMDS, OPERATING_MODE, + CHROMA_INTERLEAVED, + row_stride_code >> 3, unsigned int, unsigned int); + } else { + IMG_ASSERT(row_stride_code < 8); + } + } + pict_cmds[VDECFW_CMD_LUMA_RECONSTRUCTED_PICTURE_BASE_ADDRESS] = + (unsigned int)GET_HOST_ADDR(&buffers->recon_pict->pict_buf->ddbuf_info) + + buffers->recon_pict->rend_info.plane_info[0].offset; + + pict_cmds[VDECFW_CMD_CHROMA_RECONSTRUCTED_PICTURE_BASE_ADDRESS] = + (unsigned int)GET_HOST_ADDR(&buffers->recon_pict->pict_buf->ddbuf_info) + + buffers->recon_pict->rend_info.plane_info[1].offset; + + pict_cmds[VDECFW_CMD_CHROMA2_RECONSTRUCTED_PICTURE_BASE_ADDRESS] = + (unsigned int)GET_HOST_ADDR(&buffers->recon_pict->pict_buf->ddbuf_info) + + buffers->recon_pict->rend_info.plane_info[2].offset; + + pict_cmds[VDECFW_CMD_LUMA_ERROR_PICTURE_BASE_ADDRESS] = 0; + pict_cmds[VDECFW_CMD_CHROMA_ERROR_PICTURE_BASE_ADDRESS] = 0; + +#ifdef ERROR_CONCEALMENT + /* update error concealment frame info if available */ + if (buffers->err_pict_bufinfo) { + pict_cmds[VDECFW_CMD_LUMA_ERROR_PICTURE_BASE_ADDRESS] = + (unsigned int)GET_HOST_ADDR(buffers->err_pict_bufinfo) + + buffers->recon_pict->rend_info.plane_info[0].offset; + + pict_cmds[VDECFW_CMD_CHROMA_ERROR_PICTURE_BASE_ADDRESS] = + (unsigned int)GET_HOST_ADDR(buffers->err_pict_bufinfo) + + buffers->recon_pict->rend_info.plane_info[1].offset; + } +#endif + + pict_cmds[VDECFW_CMD_INTRA_BUFFER_BASE_ADDRESS] = + (unsigned int)GET_HOST_ADDR(buffers->intra_bufinfo); + pict_cmds[VDECFW_CMD_INTRA_BUFFER_PLANE_SIZE] = + buffers->intra_bufsize_per_pipe / 3; + pict_cmds[VDECFW_CMD_INTRA_BUFFER_SIZE_PER_PIPE] = + buffers->intra_bufsize_per_pipe; + pict_cmds[VDECFW_CMD_AUX_LINE_BUFFER_BASE_ADDRESS] = + (unsigned int)GET_HOST_ADDR(buffers->auxline_bufinfo); + pict_cmds[VDECFW_CMD_AUX_LINE_BUFFER_SIZE_PER_PIPE] = + buffers->auxline_bufsize_per_pipe; + + /* + * for pvdec we need to set this registers even if we don't + * use alternative output + */ + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_ALTERNATIVE_OUTPUT_CONTROL], + MSVDX_CMDS, ALTERNATIVE_OUTPUT_CONTROL, + ALT_BIT_DEPTH_CHROMA_MINUS8, + output_config->pixel_info.bitdepth_c - 8, unsigned int, unsigned int); + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_ALTERNATIVE_OUTPUT_CONTROL], + MSVDX_CMDS, ALTERNATIVE_OUTPUT_CONTROL, + ALT_BIT_DEPTH_LUMA_MINUS8, + output_config->pixel_info.bitdepth_y - 8, unsigned int, unsigned int); + + /* + * this is causing corruption in RV40 and VC1 streams with + * scaling/rotation enabled on Coral, so setting to 0 + */ + benable_auxline_buf = benable_auxline_buf && + (str_configdata->vid_std != VDEC_STD_REAL) && + (str_configdata->vid_std != VDEC_STD_VC1); + + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_ALTERNATIVE_OUTPUT_PICTURE_ROTATION], + MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION, + USE_AUX_LINE_BUF, benable_auxline_buf ? 1 : 0, unsigned int, int); +} + +void vxd_set_altpictcmds(const struct vdecdd_str_unit *str_unit, + const struct vdec_str_configdata *str_configdata, + const struct vdec_str_opconfig *output_config, + const struct vxd_coreprops *coreprops, + const struct vxd_buffers *buffers, + unsigned int *pict_cmds) +{ + unsigned int row_stride_code; + unsigned int y_stride; + unsigned int uv_stride; + unsigned int v_stride; + + y_stride = buffers->alt_pict->rend_info.plane_info[VDEC_PLANE_VIDEO_Y].stride; + uv_stride = buffers->alt_pict->rend_info.plane_info[VDEC_PLANE_VIDEO_UV].stride; + v_stride = buffers->alt_pict->rend_info.plane_info[VDEC_PLANE_VIDEO_V].stride; + + if (((y_stride % (VDEC_VXD_EXT_STRIDE_ALIGNMENT_DEFAULT)) == 0) && + ((uv_stride % (VDEC_VXD_EXT_STRIDE_ALIGNMENT_DEFAULT)) == 0) && + ((v_stride % (VDEC_VXD_EXT_STRIDE_ALIGNMENT_DEFAULT)) == 0)) { + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_ALTERNATIVE_OUTPUT_PICTURE_ROTATION], + MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION, + USE_EXT_ROT_ROW_STRIDE, 1, unsigned int, int); + + /* 64-byte (min) aligned luma stride value. */ + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_ALTERNATIVE_OUTPUT_PICTURE_ROTATION], + MSVDX_CMDS, + ALTERNATIVE_OUTPUT_PICTURE_ROTATION, + EXT_ROT_ROW_STRIDE, y_stride >> 6, + unsigned int, unsigned int); + + /* 64-byte (min) aligned chroma stride value. */ + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_CHROMA_ROW_STRIDE], + MSVDX_CMDS, CHROMA_ROW_STRIDE, + ALT_CHROMA_ROW_STRIDE, uv_stride >> 6, + unsigned int, unsigned int); + } else { + /* + * Obtain the code for buffer stride + * (must be less than 8, i.e. not JPEG strides) + */ + row_stride_code = + get_stride_code(str_configdata->vid_std, y_stride); + + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_ALTERNATIVE_OUTPUT_PICTURE_ROTATION], + MSVDX_CMDS, + ALTERNATIVE_OUTPUT_PICTURE_ROTATION, + ROTATION_ROW_STRIDE, row_stride_code & 0x7, + unsigned int, unsigned int); + } + + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_ALTERNATIVE_OUTPUT_PICTURE_ROTATION], + MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION, + SCALE_INPUT_SIZE_SEL, + ((output_config->pixel_info.chroma_fmt_idc != + str_unit->seq_hdr_info->com_sequ_hdr_info.pixel_info.chroma_fmt_idc)) ? + 1 : 0, unsigned int, int); + + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_ALTERNATIVE_OUTPUT_PICTURE_ROTATION], + MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION, + PACKED_422_OUTPUT, + (output_config->pixel_info.chroma_fmt_idc == + PIXEL_FORMAT_422 && + output_config->pixel_info.num_planes == 1) ? 1 : 0, + unsigned int, int); + + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_ALTERNATIVE_OUTPUT_CONTROL], + MSVDX_CMDS, ALTERNATIVE_OUTPUT_CONTROL, + ALT_OUTPUT_FORMAT, + str_unit->seq_hdr_info->com_sequ_hdr_info.separate_chroma_planes ? + 0 : pixel_get_hw_chroma_format_idc + (output_config->pixel_info.chroma_fmt_idc), + unsigned int, int); + + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_ALTERNATIVE_OUTPUT_CONTROL], + MSVDX_CMDS, ALTERNATIVE_OUTPUT_CONTROL, + ALT_BIT_DEPTH_CHROMA_MINUS8, + output_config->pixel_info.bitdepth_c - 8, + unsigned int, unsigned int); + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_ALTERNATIVE_OUTPUT_CONTROL], + MSVDX_CMDS, ALTERNATIVE_OUTPUT_CONTROL, + ALT_BIT_DEPTH_LUMA_MINUS8, + output_config->pixel_info.bitdepth_y - 8, + unsigned int, unsigned int); + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_ALTERNATIVE_OUTPUT_CONTROL], + MSVDX_CMDS, ALTERNATIVE_OUTPUT_CONTROL, + ALT_MEMORY_PACKING, + (output_config->pixel_info.mem_pkg == + PIXEL_BIT10_MP) ? 1 : 0, unsigned int, int); + + pict_cmds[VDECFW_CMD_LUMA_ALTERNATIVE_PICTURE_BASE_ADDRESS] = + (unsigned int)GET_HOST_ADDR(&buffers->alt_pict->pict_buf->ddbuf_info) + + buffers->alt_pict->rend_info.plane_info[0].offset; + + pict_cmds[VDECFW_CMD_CHROMA_ALTERNATIVE_PICTURE_BASE_ADDRESS] = + (unsigned int)GET_HOST_ADDR(&buffers->alt_pict->pict_buf->ddbuf_info) + + buffers->alt_pict->rend_info.plane_info[1].offset; + + pict_cmds[VDECFW_CMD_CHROMA2_ALTERNATIVE_PICTURE_BASE_ADDRESS] = + (unsigned int)GET_HOST_ADDR(&buffers->alt_pict->pict_buf->ddbuf_info) + + buffers->alt_pict->rend_info.plane_info[2].offset; +} + +int vxd_getscalercmds(const struct scaler_config *scaler_config, + const struct scaler_pitch *pitch, + const struct scaler_filter *filter, + const struct pixel_pixinfo *out_loop_pixel_info, + struct scaler_params *params, + unsigned int *pict_cmds) +{ + const struct vxd_coreprops *coreprops = scaler_config->coreprops; + /* + * Indirectly detect decoder core type (if HEVC is supported, it has + * to be PVDEC core) and decide if to force luma re-sampling. + */ + unsigned char bforce_luma_resampling = coreprops->hevc[0]; + + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_ALTERNATIVE_OUTPUT_CONTROL], + MSVDX_CMDS, ALTERNATIVE_OUTPUT_CONTROL, + ALT_OUTPUT_FORMAT, + scaler_config->bseparate_chroma_planes ? 0 : + pixel_get_hw_chroma_format_idc(out_loop_pixel_info->chroma_fmt_idc), + unsigned int, int); + + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_ALTERNATIVE_OUTPUT_CONTROL], + MSVDX_CMDS, ALTERNATIVE_OUTPUT_CONTROL, + SCALE_CHROMA_RESAMP_ONLY, bforce_luma_resampling ? 0 : + (pitch->horiz_luma == FIXED(1, HIGHP)) && + (pitch->vert_luma == FIXED(1, HIGHP)), unsigned int, int); + + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_ALTERNATIVE_OUTPUT_CONTROL], + MSVDX_CMDS, ALTERNATIVE_OUTPUT_CONTROL, ALT_MEMORY_PACKING, + pixel_get_hw_memory_packing(out_loop_pixel_info->mem_pkg), + unsigned int, int); + + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_ALTERNATIVE_OUTPUT_CONTROL], + MSVDX_CMDS, ALTERNATIVE_OUTPUT_CONTROL, + ALT_BIT_DEPTH_LUMA_MINUS8, + out_loop_pixel_info->bitdepth_y - 8, + unsigned int, unsigned int); + + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_ALTERNATIVE_OUTPUT_CONTROL], + MSVDX_CMDS, ALTERNATIVE_OUTPUT_CONTROL, + ALT_BIT_DEPTH_CHROMA_MINUS8, + out_loop_pixel_info->bitdepth_c - 8, + unsigned int, unsigned int); + + /* Scale luma bifilter is always 0 for now */ + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_ALTERNATIVE_OUTPUT_CONTROL], + MSVDX_CMDS, ALTERNATIVE_OUTPUT_CONTROL, + SCALE_LUMA_BIFILTER_HORIZ, + 0, unsigned int, int); + + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_ALTERNATIVE_OUTPUT_CONTROL], + MSVDX_CMDS, ALTERNATIVE_OUTPUT_CONTROL, + SCALE_LUMA_BIFILTER_VERT, + 0, unsigned int, int); + + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_ALTERNATIVE_OUTPUT_CONTROL], + MSVDX_CMDS, ALTERNATIVE_OUTPUT_CONTROL, + SCALE_CHROMA_BIFILTER_HORIZ, + filter->bhoriz_bilinear ? 1 : 0, + unsigned int, int); + + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_ALTERNATIVE_OUTPUT_CONTROL], + MSVDX_CMDS, ALTERNATIVE_OUTPUT_CONTROL, + SCALE_CHROMA_BIFILTER_VERT, + filter->bvert_bilinear ? 1 : 0, unsigned int, int); + + /* for cores 7.x.x and more, precision 3.13 */ + params->fixed_point_shift = 13; + + /* Calculate the fixed-point versions for use by the hardware. */ + params->vert_pitch = (int)((pitch->vert_luma + + (1 << (HIGHP - params->fixed_point_shift - 1))) >> + (HIGHP - params->fixed_point_shift)); + params->vert_startpos = params->vert_pitch >> 1; + params->vert_pitch_chroma = (int)((pitch->vert_chroma + + (1 << (HIGHP - params->fixed_point_shift - 1))) >> + (HIGHP - params->fixed_point_shift)); + params->vert_startpos_chroma = params->vert_pitch_chroma >> 1; + params->horz_pitch = (int)(pitch->horiz_luma >> + (HIGHP - params->fixed_point_shift)); + params->horz_startpos = params->horz_pitch >> 1; + params->horz_pitch_chroma = (int)(pitch->horiz_chroma >> + (HIGHP - params->fixed_point_shift)); + params->horz_startpos_chroma = params->horz_pitch_chroma >> 1; + +#ifdef HAS_HEVC + if (scaler_config->vidstd == VDEC_STD_HEVC) { + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_SCALED_DISPLAY_SIZE], + MSVDX_CMDS, PVDEC_SCALED_DISPLAY_SIZE, + PVDEC_SCALE_DISPLAY_WIDTH, + scaler_config->recon_width - 1, + unsigned int, unsigned int); + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_SCALED_DISPLAY_SIZE], + MSVDX_CMDS, PVDEC_SCALED_DISPLAY_SIZE, + PVDEC_SCALE_DISPLAY_HEIGHT, + scaler_config->recon_height - 1, + unsigned int, unsigned int); + } else { + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_SCALED_DISPLAY_SIZE], + MSVDX_CMDS, SCALED_DISPLAY_SIZE, + SCALE_DISPLAY_WIDTH, + scaler_config->recon_width - 1, + unsigned int, unsigned int); + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_SCALED_DISPLAY_SIZE], + MSVDX_CMDS, SCALED_DISPLAY_SIZE, + SCALE_DISPLAY_HEIGHT, + scaler_config->recon_height - 1, + unsigned int, unsigned int); + } +#else + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_SCALED_DISPLAY_SIZE], + MSVDX_CMDS, SCALED_DISPLAY_SIZE, + SCALE_DISPLAY_WIDTH, + scaler_config->recon_width - 1, + unsigned int, unsigned int); + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_SCALED_DISPLAY_SIZE], + MSVDX_CMDS, SCALED_DISPLAY_SIZE, SCALE_DISPLAY_HEIGHT, + scaler_config->recon_height - 1, + unsigned int, unsigned int); +#endif + + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_SCALE_OUTPUT_SIZE], + MSVDX_CMDS, SCALE_OUTPUT_SIZE, + SCALE_OUTPUT_WIDTH_MIN1, + scaler_config->scale_width - 1, + unsigned int, unsigned int); + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_SCALE_OUTPUT_SIZE], + MSVDX_CMDS, SCALE_OUTPUT_SIZE, + SCALE_OUTPUT_HEIGHT_MIN1, + scaler_config->scale_height - 1, + unsigned int, unsigned int); + + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_HORIZONTAL_SCALE_CONTROL], + MSVDX_CMDS, HORIZONTAL_SCALE_CONTROL, + HORIZONTAL_SCALE_PITCH, params->horz_pitch, + unsigned int, unsigned int); + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_HORIZONTAL_SCALE_CONTROL], + MSVDX_CMDS, HORIZONTAL_SCALE_CONTROL, + HORIZONTAL_INITIAL_POS, params->horz_startpos, + unsigned int, unsigned int); + + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_SCALE_HORIZONTAL_CHROMA], + MSVDX_CMDS, SCALE_HORIZONTAL_CHROMA, + CHROMA_HORIZONTAL_PITCH, params->horz_pitch_chroma, + unsigned int, unsigned int); + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_SCALE_HORIZONTAL_CHROMA], + MSVDX_CMDS, SCALE_HORIZONTAL_CHROMA, + CHROMA_HORIZONTAL_INITIAL, + params->horz_startpos_chroma, + unsigned int, unsigned int); + + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_VERTICAL_SCALE_CONTROL], + MSVDX_CMDS, VERTICAL_SCALE_CONTROL, + VERTICAL_SCALE_PITCH, params->vert_pitch, + unsigned int, unsigned int); + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_VERTICAL_SCALE_CONTROL], + MSVDX_CMDS, VERTICAL_SCALE_CONTROL, + VERTICAL_INITIAL_POS, params->vert_startpos, + unsigned int, unsigned int); + + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_SCALE_VERTICAL_CHROMA], + MSVDX_CMDS, SCALE_VERTICAL_CHROMA, + CHROMA_VERTICAL_PITCH, params->vert_pitch_chroma, + unsigned int, unsigned int); + REGIO_WRITE_FIELD(pict_cmds[VDECFW_CMD_SCALE_VERTICAL_CHROMA], + MSVDX_CMDS, SCALE_VERTICAL_CHROMA, + CHROMA_VERTICAL_INITIAL, + params->vert_startpos_chroma, + unsigned int, unsigned int); + return 0; +} + +unsigned int vxd_get_codedpicsize(unsigned short width_min1, unsigned short height_min1) +{ + unsigned int reg = 0; + + REGIO_WRITE_FIELD_LITE(reg, MSVDX_CMDS, CODED_PICTURE_SIZE, + CODED_PICTURE_WIDTH, width_min1, + unsigned short); + REGIO_WRITE_FIELD_LITE(reg, MSVDX_CMDS, CODED_PICTURE_SIZE, + CODED_PICTURE_HEIGHT, height_min1, + unsigned short); + + return reg; +} + +unsigned char vxd_get_codedmode(enum vdec_vid_std vidstd) +{ + return (unsigned char)amsvdx_codecmode[vidstd]; +} + +void vxd_get_coreproperties(void *hndl_coreproperties, + struct vxd_coreprops *vxd_coreprops) +{ + struct vxd_core_props *props = + (struct vxd_core_props *)hndl_coreproperties; + + vxd_getcoreproperties(vxd_coreprops, props->core_rev, + props->pvdec_core_id, + props->mmu_config0, + props->mmu_config1, + props->pixel_pipe_cfg, + props->pixel_misc_cfg, + props->pixel_max_frame_cfg); +} + +int vxd_get_pictattrs(unsigned int flags, struct vxd_pict_attrs *pict_attrs) +{ + if (flags & (VXD_FW_MSG_FLAG_DWR | VXD_FW_MSG_FLAG_FATAL)) + pict_attrs->dwrfired = 1; + if (flags & VXD_FW_MSG_FLAG_MMU_FAULT) + pict_attrs->mmufault = 1; + if (flags & VXD_FW_MSG_FLAG_DEV_ERR) + pict_attrs->deverror = 1; + + return 0; +} + +int vxd_get_msgerrattr(unsigned int flags, enum vxd_msg_attr *msg_attr) +{ + if ((flags & ~VXD_FW_MSG_FLAG_CANCELED)) + *msg_attr = VXD_MSG_ATTR_FATAL; + else if ((flags & VXD_FW_MSG_FLAG_CANCELED)) + *msg_attr = VXD_MSG_ATTR_CANCELED; + else + *msg_attr = VXD_MSG_ATTR_NONE; + + return 0; +} + +int vxd_set_msgflag(enum vxd_msg_flag input_flag, unsigned int *flags) +{ + switch (input_flag) { + case VXD_MSG_FLAG_DROP: + *flags |= VXD_FW_MSG_FLAG_DROP; + break; + case VXD_MSG_FLAG_EXCL: + *flags |= VXD_FW_MSG_FLAG_EXCL; + break; + default: + return IMG_ERROR_FATAL; + } + + return 0; +} diff --git a/drivers/staging/media/vxd/decoder/vxd_int.h b/drivers/staging/media/vxd/decoder/vxd_int.h new file mode 100644 index 000000000000..a294e0d6044f --- /dev/null +++ b/drivers/staging/media/vxd/decoder/vxd_int.h @@ -0,0 +1,128 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * VXD DEC Common low level core interface component + * + * Copyright (c) Imagination Technologies Ltd. + * Copyright (c) 2021 Texas Instruments Incorporated - http://www.ti.com/ + * + * Authors: + * Amit Makani <amit.makani@xxxxxx> + * + * Re-written for upstreamimg + * Sidraya Jayagond <sidraya.bj@xxxxxxxxxxxxxxxxxxx> + * Prashanth Kumar Amai <prashanth.ka@xxxxxxxxxxxxxxxxxxx> + */ +#ifndef _VXD_INT_H +#define _VXD_INT_H + +#include "fw_interface.h" +#include "scaler_setup.h" +#include "vdecdd_defs.h" +#include "vdecfw_shared.h" +#include "vdec_defs.h" +#include "vxd_ext.h" +#include "vxd_props.h" + +/* + * Size of buffer used for batching messages + */ +#define BATCH_MSG_BUFFER_SIZE (8 * 4096) + +#define INTRA_BUF_SIZE (1024 * 32) +#define AUX_LINE_BUFFER_SIZE (512 * 1024) + +#define MAX_PICTURE_WIDTH (4096) +#define MAX_PICTURE_HEIGHT (4096) + +/* + * this macro returns the host address of device buffer. + */ +#define GET_HOST_ADDR(buf) ((buf)->dev_virt) + +#define GET_HOST_ADDR_OFFSET(buf, offset) (((buf)->dev_virt) + (offset)) + +/* + * The extended stride alignment for VXD. + */ +#define VDEC_VXD_EXT_STRIDE_ALIGNMENT_DEFAULT (64) + +struct vxd_buffers { + struct vdecdd_ddpict_buf *recon_pict; + struct vdecdd_ddpict_buf *alt_pict; + struct vidio_ddbufinfo *intra_bufinfo; + struct vidio_ddbufinfo *auxline_bufinfo; + struct vidio_ddbufinfo *err_pict_bufinfo; + unsigned int intra_bufsize_per_pipe; + unsigned int auxline_bufsize_per_pipe; + struct vidio_ddbufinfo *msb_bufinfo; + unsigned char btwopass; +}; + +struct pvdec_core_rev { + unsigned int maj_rev; + unsigned int min_rev; + unsigned int maint_rev; + unsigned int int_rev; +}; + +/* + * this has all that it needs to translate a Stream Unit for a picture + * into a transaction. + */ +void vxd_set_altpictcmds(const struct vdecdd_str_unit *str_unit, + const struct vdec_str_configdata *str_configdata, + const struct vdec_str_opconfig *output_config, + const struct vxd_coreprops *coreprops, + const struct vxd_buffers *buffers, + unsigned int *pict_cmds); + +/* + * this has all that it needs to translate a Stream Unit for + * a picture into a transaction. + */ +void vxd_set_reconpictcmds(const struct vdecdd_str_unit *str_unit, + const struct vdec_str_configdata *str_configdata, + const struct vdec_str_opconfig *output_config, + const struct vxd_coreprops *coreprops, + const struct vxd_buffers *buffers, + unsigned int *pict_cmds); + +int vxd_getscalercmds(const struct scaler_config *scaler_config, + const struct scaler_pitch *pitch, + const struct scaler_filter *filter, + const struct pixel_pixinfo *out_loop_pixel_info, + struct scaler_params *params, + unsigned int *pict_cmds); + +/* + * this creates value of MSVDX_CMDS_CODED_PICTURE_SIZE register. + */ +unsigned int vxd_get_codedpicsize(unsigned short width_min1, unsigned short height_min1); + +/* + * return HW codec mode based on video standard. + */ +unsigned char vxd_get_codedmode(enum vdec_vid_std vidstd); + +/* + * translates core properties to the form of the struct vxd_coreprops struct. + */ +void vxd_get_coreproperties(void *hndl_coreproperties, + struct vxd_coreprops *vxd_coreprops); + +/* + * translates picture attributes to the form of the VXD_sPictAttrs struct. + */ +int vxd_get_pictattrs(unsigned int flags, struct vxd_pict_attrs *pict_attrs); + +/* + * translates message attributes to the form of the VXD_eMsgAttr struct. + */ +int vxd_get_msgerrattr(unsigned int flags, enum vxd_msg_attr *msg_attr); + +/* + * sets a message flag. + */ +int vxd_set_msgflag(enum vxd_msg_flag input_flag, unsigned int *flags); + +#endif /* _VXD_INT_H */ -- 2.17.1 -- This message contains confidential information and is intended only for the individual(s) named. If you are not the intended recipient, you are notified that disclosing, copying, distributing or taking any action in reliance on the contents of this mail and attached file/s is strictly prohibited. Please notify the sender immediately and delete this e-mail from your system. E-mail transmission cannot be guaranteed to be secured or error-free as information could be intercepted, corrupted, lost, destroyed, arrive late or incomplete, or contain viruses. The sender therefore does not accept liability for any errors or omissions in the contents of this message, which arise as a result of e-mail transmission.