diff --git a/mpp/codec/dec/jpeg/jpegd_parser.c b/mpp/codec/dec/jpeg/jpegd_parser.c index 58bee7d9..a6dd5808 100644 --- a/mpp/codec/dec/jpeg/jpegd_parser.c +++ b/mpp/codec/dec/jpeg/jpegd_parser.c @@ -19,12 +19,12 @@ #include "mpp_env.h" #include "mpp_mem.h" +#include "mpp_soc.h" #include "mpp_bitread.h" #include "mpp_packet_impl.h" #include "jpegd_api.h" #include "jpegd_parser.h" -#include "mpp_platform.h" RK_U32 jpegd_debug = 0x0; diff --git a/mpp/codec/enc/h265/h265e_ps.c b/mpp/codec/enc/h265/h265e_ps.c index 31ae6fd3..4986cefa 100644 --- a/mpp/codec/enc/h265/h265e_ps.c +++ b/mpp/codec/enc/h265/h265e_ps.c @@ -19,9 +19,11 @@ #include #include "mpp_mem.h" +#include "mpp_soc.h" #include "mpp_common.h" #include "h265e_ps.h" + #define MAX_UINT 0xFFFFFFFFU typedef struct H265levelspec_t { diff --git a/mpp/codec/inc/enc_impl_api.h b/mpp/codec/inc/enc_impl_api.h index ec7dd5ea..32986314 100644 --- a/mpp/codec/inc/enc_impl_api.h +++ b/mpp/codec/inc/enc_impl_api.h @@ -19,7 +19,6 @@ #include "rk_mpi_cmd.h" -#include "mpp_platform.h" #include "hal_task.h" #include "mpp_enc_cfg.h" #include "mpp_enc_refs.h" diff --git a/mpp/hal/rkdec/h264d/hal_h264d_vdpu2.c b/mpp/hal/rkdec/h264d/hal_h264d_vdpu2.c index 715b39e7..c1284370 100644 --- a/mpp/hal/rkdec/h264d/hal_h264d_vdpu2.c +++ b/mpp/hal/rkdec/h264d/hal_h264d_vdpu2.c @@ -24,6 +24,7 @@ #include "rk_type.h" #include "mpp_err.h" #include "mpp_mem.h" +#include "mpp_soc.h" #include "mpp_common.h" #include "hal_h264d_global.h" diff --git a/mpp/hal/rkenc/h264e/hal_h264e_vepu541.c b/mpp/hal/rkenc/h264e/hal_h264e_vepu541.c index b13ad906..56d5fd96 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_vepu541.c +++ b/mpp/hal/rkenc/h264e/hal_h264e_vepu541.c @@ -20,6 +20,7 @@ #include "mpp_env.h" #include "mpp_mem.h" +#include "mpp_soc.h" #include "mpp_frame.h" #include "mpp_common.h" #include "mpp_device.h" diff --git a/mpp/hal/rkenc/h265e/hal_h265e_vepu541.c b/mpp/hal/rkenc/h265e/hal_h265e_vepu541.c index 1ab1a633..360fc2d2 100644 --- a/mpp/hal/rkenc/h265e/hal_h265e_vepu541.c +++ b/mpp/hal/rkenc/h265e/hal_h265e_vepu541.c @@ -22,6 +22,7 @@ #include "mpp_env.h" #include "mpp_mem.h" +#include "mpp_soc.h" #include "mpp_common.h" #include "mpp_device.h" #include "mpp_frame_impl.h" diff --git a/mpp/legacy/vpu_api.cpp b/mpp/legacy/vpu_api.cpp index f773958b..0dd5e23f 100644 --- a/mpp/legacy/vpu_api.cpp +++ b/mpp/legacy/vpu_api.cpp @@ -24,7 +24,7 @@ #include "mpp_mem.h" #include "mpp_env.h" #include "mpp_common.h" -#include "mpp_platform.h" +#include "mpp_soc.h" #include "vpu_api.h" #include "vpu_api_legacy.h" diff --git a/osal/CMakeLists.txt b/osal/CMakeLists.txt index b5d8bc3c..55ef8be7 100644 --- a/osal/CMakeLists.txt +++ b/osal/CMakeLists.txt @@ -32,6 +32,7 @@ set(MPP_DRIVER ) add_library(osal STATIC + mpp_soc.cpp mpp_platform.cpp mpp_runtime.cpp mpp_allocator.cpp diff --git a/osal/driver/mpp_device.c b/osal/driver/mpp_device.c index 32fd064d..536a42b1 100644 --- a/osal/driver/mpp_device.c +++ b/osal/driver/mpp_device.c @@ -23,6 +23,7 @@ #include "mpp_mem.h" #include "mpp_common.h" +#include "mpp_platform.h" #include "mpp_device_debug.h" #include "mpp_service_api.h" #include "vcodec_service_api.h" diff --git a/osal/driver/vcodec_service.c b/osal/driver/vcodec_service.c index afb7eb4f..8db09d89 100644 --- a/osal/driver/vcodec_service.c +++ b/osal/driver/vcodec_service.c @@ -31,12 +31,18 @@ #include "vpu.h" #include "mpp_soc.h" +#include "mpp_platform.h" #include "vcodec_service.h" #include "vcodec_service_api.h" #define MAX_REGS_COUNT 3 #define MPX_EXTRA_INFO_NUM 16 +typedef struct MppReq_t { + RK_U32 *req; + RK_U32 size; +} MppReq; + typedef struct VcodecExtraSlot_t { RK_U32 reg_idx; RK_U32 offset; @@ -151,10 +157,6 @@ const char *mpp_get_platform_dev_name(MppCtxType type, MppCodingType coding, RK_ } else if ((platform & HAVE_VEPU22) && (type == MPP_CTX_ENC) && (coding == MPP_VIDEO_CodingHEVC)) { dev = mpp_find_device(mpp_h265e_dev); - } else if ((platform & (HAVE_VEPU2_LITE)) && (type == MPP_CTX_ENC) && - ((coding == MPP_VIDEO_CodingAVC || - coding == MPP_VIDEO_CodingMJPEG))) { - dev = mpp_find_device(mpp_vepu_dev); } else { if (type == MPP_CTX_ENC) dev = mpp_find_device(mpp_vepu_dev); @@ -444,13 +446,6 @@ MPP_RET vcodec_service_init(void *ctx, MppClientType type) client_type = VPU_ENC; reg_size = VEPU2_REGISTERS; } break; - case VPU_CLIENT_VEPU2_LITE : { - name = mpp_find_device(mpp_vepu_dev); - if (name == NULL) - name = mpp_find_device(mpp_vpu_dev); - client_type = VPU_ENC; - reg_size = VEPU2_REGISTERS; - } break; default : { mpp_err_f("unsupported client type %d\n", type); return ret; diff --git a/osal/inc/mpp_dev_defs.h b/osal/inc/mpp_dev_defs.h new file mode 100644 index 00000000..abd19ab2 --- /dev/null +++ b/osal/inc/mpp_dev_defs.h @@ -0,0 +1,71 @@ +/* + * Copyright 2020 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_DEV_DEFS_H__ +#define __MPP_DEV_DEFS_H__ + +#include "rk_type.h" + +/* + * Platform video codec hardware feature + */ +typedef enum MppClientType_e { + VPU_CLIENT_VDPU1 = 0, /* 0x00000001 */ + VPU_CLIENT_VDPU2 = 1, /* 0x00000002 */ + VPU_CLIENT_VDPU1_PP = 2, /* 0x00000004 */ + VPU_CLIENT_VDPU2_PP = 3, /* 0x00000008 */ + + VPU_CLIENT_HEVC_DEC = 8, /* 0x00000100 */ + VPU_CLIENT_RKVDEC = 9, /* 0x00000200 */ + VPU_CLIENT_AVSPLUS_DEC = 12, /* 0x00001000 */ + VPU_CLIENT_JPEG_DEC = 13, /* 0x00002000 */ + + VPU_CLIENT_RKVENC = 16, /* 0x00010000 */ + VPU_CLIENT_VEPU1 = 17, /* 0x00020000 */ + VPU_CLIENT_VEPU2 = 18, /* 0x00040000 */ + VPU_CLIENT_VEPU2_LITE = 19, /* 0x00080000 */ + VPU_CLIENT_VEPU22 = 24, /* 0x01000000 */ + + IEP_CLIENT_TYPE = 28, /* 0x10000000 */ + + VPU_CLIENT_BUTT, +} MppClientType; + +/* RK combined codec */ +#define HAVE_VDPU1 (1 << VPU_CLIENT_VDPU1) /* 0x00000001 */ +#define HAVE_VDPU2 (1 << VPU_CLIENT_VDPU2) /* 0x00000002 */ +#define HAVE_VDPU1_PP (1 << VPU_CLIENT_VDPU1_PP) /* 0x00000004 */ +#define HAVE_VDPU2_PP (1 << VPU_CLIENT_VDPU2_PP) /* 0x00000008 */ +/* RK standalone decoder */ +#define HAVE_HEVC_DEC (1 << VPU_CLIENT_HEVC_DEC) /* 0x00000100 */ +#define HAVE_RKVDEC (1 << VPU_CLIENT_RKVDEC) /* 0x00000200 */ +#define HAVE_AVSDEC (1 << VPU_CLIENT_AVSPLUS_DEC) /* 0x00001000 */ +#define HAVE_JPEG_DEC (1 << VPU_CLIENT_JPEG_DEC) /* 0x00002000 */ +/* RK standalone encoder */ +#define HAVE_RKVENC (1 << VPU_CLIENT_RKVENC) /* 0x00010000 */ +#define HAVE_VEPU1 (1 << VPU_CLIENT_VEPU1) /* 0x00020000 */ +#define HAVE_VEPU2 (1 << VPU_CLIENT_VEPU2) /* 0x00040000 */ +/* External encoder */ +#define HAVE_VEPU22 (1 << VPU_CLIENT_VEPU22) /* 0x01000000 */ +/* RK Image Enhance Processor for deinterlacing */ +#define HAVE_IEP (1 << IEP_CLIENT_TYPE) /* 0x10000000 */ + +/* Platform image process hardware feature */ +#define HAVE_IPP (0x00000001) +#define HAVE_RGA (0x00000002) +#define HAVE_RGA2 (0x00000004) + +#endif /*__MPP_DEV_DEFS_H__*/ diff --git a/osal/inc/mpp_device.h b/osal/inc/mpp_device.h index 41c24dc3..4ceb3be8 100644 --- a/osal/inc/mpp_device.h +++ b/osal/inc/mpp_device.h @@ -17,9 +17,8 @@ #ifndef __MPP_DEVICE_H__ #define __MPP_DEVICE_H__ -#include "rk_type.h" #include "mpp_err.h" -#include "mpp_platform.h" +#include "mpp_dev_defs.h" typedef enum MppDevIoctlCmd_e { /* hardware operation setup config */ diff --git a/osal/inc/mpp_platform.h b/osal/inc/mpp_platform.h index ae1c7edf..91fcb512 100644 --- a/osal/inc/mpp_platform.h +++ b/osal/inc/mpp_platform.h @@ -18,7 +18,7 @@ #define __MPP_PLATFORM__ #include "rk_type.h" -#include "mpp_service.h" +#include "mpp_soc.h" /* * Platform flag detection is for rockchip hardware platform detection @@ -29,56 +29,6 @@ typedef enum MppIoctlVersion_e { IOCTL_VERSION_BUTT, } MppIoctlVersion; -/* - * Platform video codec hardware feature - */ -typedef enum MppClientType_e { - VPU_CLIENT_VDPU1 = 0, /* 0x00000001 */ - VPU_CLIENT_VDPU2 = 1, /* 0x00000002 */ - VPU_CLIENT_VDPU1_PP = 2, /* 0x00000004 */ - VPU_CLIENT_VDPU2_PP = 3, /* 0x00000008 */ - - VPU_CLIENT_HEVC_DEC = 8, /* 0x00000100 */ - VPU_CLIENT_RKVDEC = 9, /* 0x00000200 */ - VPU_CLIENT_AVSPLUS_DEC = 12, /* 0x00001000 */ - VPU_CLIENT_JPEG_DEC = 13, /* 0x00002000 */ - - VPU_CLIENT_RKVENC = 16, /* 0x00010000 */ - VPU_CLIENT_VEPU1 = 17, /* 0x00020000 */ - VPU_CLIENT_VEPU2 = 18, /* 0x00040000 */ - VPU_CLIENT_VEPU2_LITE = 19, /* 0x00080000 */ - VPU_CLIENT_VEPU22 = 24, /* 0x01000000 */ - - IEP_CLIENT_TYPE = 28, /* 0x10000000 */ - - VPU_CLIENT_BUTT, -} MppClientType; - -/* RK combined codec */ -#define HAVE_VDPU1 (1 << VPU_CLIENT_VDPU1) /* 0x00000001 */ -#define HAVE_VDPU2 (1 << VPU_CLIENT_VDPU2) /* 0x00000002 */ -#define HAVE_VDPU1_PP (1 << VPU_CLIENT_VDPU1_PP) /* 0x00000004 */ -#define HAVE_VDPU2_PP (1 << VPU_CLIENT_VDPU2_PP) /* 0x00000008 */ -/* RK standalone decoder */ -#define HAVE_HEVC_DEC (1 << VPU_CLIENT_HEVC_DEC) /* 0x00000100 */ -#define HAVE_RKVDEC (1 << VPU_CLIENT_RKVDEC) /* 0x00000200 */ -#define HAVE_AVSDEC (1 << VPU_CLIENT_AVSPLUS_DEC) /* 0x00001000 */ -#define HAVE_JPEG_DEC (1 << VPU_CLIENT_JPEG_DEC) /* 0x00002000 */ -/* RK standalone encoder */ -#define HAVE_RKVENC (1 << VPU_CLIENT_RKVENC) /* 0x00010000 */ -#define HAVE_VEPU1 (1 << VPU_CLIENT_VEPU1) /* 0x00020000 */ -#define HAVE_VEPU2 (1 << VPU_CLIENT_VEPU2) /* 0x00040000 */ -#define HAVE_VEPU2_LITE (1 << VPU_CLIENT_VEPU2_LITE) /* 0x00080000 */ -/* External encoder */ -#define HAVE_VEPU22 (1 << VPU_CLIENT_VEPU22) /* 0x01000000 */ -/* RK Image Enhance Processor for deinterlacing */ -#define HAVE_IEP (1 << IEP_CLIENT_TYPE) /* 0x10000000 */ - -/* Platform image process hardware feature */ -#define HAVE_IPP (0x00000001) -#define HAVE_RGA (0x00000002) -#define HAVE_RGA2 (0x00000004) - /* Hal device id */ typedef enum MppDeviceId_e { DEV_VDPU, //!< vpu combined decoder @@ -93,10 +43,7 @@ extern "C" { #endif MppIoctlVersion mpp_get_ioctl_version(void); -const char *mpp_get_soc_name(void); -RK_U32 mpp_get_vcodec_type(void); RK_U32 mpp_get_2d_hw_flag(void); -const MppServiceCmdCap *mpp_get_mpp_service_cmd_cap(void); RK_U32 mpp_get_client_hw_id(RK_S32 client_type); #ifdef __cplusplus diff --git a/osal/inc/mpp_service.h b/osal/inc/mpp_service.h index eec528c9..2c9d9ed8 100644 --- a/osal/inc/mpp_service.h +++ b/osal/inc/mpp_service.h @@ -89,11 +89,6 @@ typedef enum MppServiceCmdType_e { MPP_CMD_BUTT, } MppServiceCmdType; -typedef struct MppReq_t { - RK_U32 *req; - RK_U32 size; -} MppReq; - typedef struct mppReqV1_t { RK_U32 cmd; RK_U32 flag; diff --git a/osal/inc/mpp_soc.h b/osal/inc/mpp_soc.h index 63316a24..2f573913 100644 --- a/osal/inc/mpp_soc.h +++ b/osal/inc/mpp_soc.h @@ -14,10 +14,10 @@ * limitations under the License. */ -#ifndef __MPP_SOC__ -#define __MPP_SOC__ +#ifndef __MPP_SOC_H__ +#define __MPP_SOC_H__ -#include "rk_type.h" +#include "mpp_dev_defs.h" /* Do NOT use this outside MPP it may be changed in new version */ typedef enum RockchipSocType_e { @@ -45,14 +45,59 @@ typedef enum RockchipSocType_e { ROCKCHIP_SOC_BUTT, } RockchipSocType; +typedef struct MppDecHwCap_t { + RK_U32 cap_coding; + + MppClientType type : 8; + + RK_U32 cap_fbc : 4; + RK_U32 cap_4k : 1; + RK_U32 cap_8k : 1; + RK_U32 cap_colmv_buf : 1; + RK_U32 cap_hw_h265_rps : 1; + RK_U32 cap_hw_vp9_prob : 1; + RK_U32 cap_jpg_pp_out : 1; + RK_U32 cap_10bit : 1; + RK_U32 reserved : 13; +} MppDecHwCap; + +typedef struct MppEncHwCap_t { + RK_U32 cap_coding; + + MppClientType type : 8; + + RK_U32 cap_fbc : 4; + RK_U32 cap_4k : 1; + RK_U32 cap_8k : 1; + RK_U32 cap_hw_osd : 1; + RK_U32 cap_hw_roi : 1; + RK_U32 reserved : 16; +} MppEncHwCap; + +typedef struct { + const char *compatible; + const RockchipSocType soc_type; + const RK_U32 vcodec_type; + + /* Max 4 decoder cap */ + const MppDecHwCap *dec_caps[4]; + /* Max 4 encoder cap */ + const MppEncHwCap *enc_caps[4]; +} MppSocInfo; + #ifdef __cplusplus extern "C" { #endif +const char *mpp_get_soc_name(void); RockchipSocType mpp_get_soc_type(void); +RK_U32 mpp_get_vcodec_type(void); + +const MppSocInfo *mpp_get_soc_info(void); +RK_U32 mpp_check_soc_cap(MppCtxType type, MppCodingType coding); #ifdef __cplusplus } #endif -#endif /*__MPP_SOC__*/ +#endif /*__MPP_SOC_H__*/ diff --git a/osal/mpp_platform.cpp b/osal/mpp_platform.cpp index b45aa2f4..84e005a8 100644 --- a/osal/mpp_platform.cpp +++ b/osal/mpp_platform.cpp @@ -14,90 +14,13 @@ * limitations under the License. */ -#include -#include -#include -#include +#define MODULE_TAG "mpp_platform" #include "mpp_env.h" #include "mpp_log.h" -#include "mpp_mem.h" #include "mpp_common.h" #include "mpp_platform.h" #include "mpp_service.h" -#include "mpp_soc.h" - -#define MAX_SOC_NAME_LENGTH 128 - -typedef struct { - const char *compatible; - RockchipSocType soc_type; - RK_U32 vcodec_type; -} MppVpuType; - -static const MppVpuType mpp_vpu_version[] = { - { "rk3036", ROCKCHIP_SOC_RK3036, HAVE_VDPU1 | HAVE_VEPU1 | HAVE_HEVC_DEC, }, - { "rk3066", ROCKCHIP_SOC_RK3066, HAVE_VDPU1 | HAVE_VEPU1, }, - { "rk3188", ROCKCHIP_SOC_RK3188, HAVE_VDPU1 | HAVE_VEPU1, }, - { "rk3288", ROCKCHIP_SOC_RK3288, HAVE_VDPU1 | HAVE_VEPU1 | HAVE_HEVC_DEC, }, - { "rk3126", ROCKCHIP_SOC_RK312X, HAVE_VDPU1 | HAVE_VEPU1 | HAVE_HEVC_DEC, }, - { "rk3128h", ROCKCHIP_SOC_RK3128H, HAVE_VDPU2 | HAVE_VEPU2 | HAVE_RKVDEC, }, - { "rk3128", ROCKCHIP_SOC_RK312X, HAVE_VDPU1 | HAVE_VEPU1 | HAVE_HEVC_DEC, }, - { "rk3368", ROCKCHIP_SOC_RK3368, HAVE_VDPU1 | HAVE_VEPU1 | HAVE_HEVC_DEC, }, - { "rk3399", ROCKCHIP_SOC_RK3399, HAVE_VDPU2 | HAVE_VEPU2 | HAVE_RKVDEC, }, - /* 3228h first for string matching */ - { "rk3228h", ROCKCHIP_SOC_RK3228H, HAVE_VDPU2 | HAVE_VEPU2 | HAVE_RKVDEC | HAVE_AVSDEC | HAVE_VEPU22, }, - { "rk3328", ROCKCHIP_SOC_RK3328, HAVE_VDPU2 | HAVE_VEPU2 | HAVE_RKVDEC | HAVE_VEPU22, }, - { "rk3228", ROCKCHIP_SOC_RK3228, HAVE_VDPU2 | HAVE_VEPU2 | HAVE_RKVDEC, }, - { "rk3229", ROCKCHIP_SOC_RK3229, HAVE_VDPU2 | HAVE_VEPU2 | HAVE_RKVDEC, }, - { "rv1108", ROCKCHIP_SOC_RV1108, HAVE_VDPU2 | HAVE_VEPU2 | HAVE_RKVDEC | HAVE_RKVENC, }, - { "rv1109", ROCKCHIP_SOC_RV1109, HAVE_VDPU2 | HAVE_VEPU2 | HAVE_RKVDEC | HAVE_RKVENC, }, - { "rv1126", ROCKCHIP_SOC_RV1126, HAVE_VDPU2 | HAVE_VEPU2 | HAVE_RKVDEC | HAVE_RKVENC, }, - { "rk3326", ROCKCHIP_SOC_RK3326, HAVE_VDPU2 | HAVE_VEPU2 | HAVE_HEVC_DEC, }, - { "px30", ROCKCHIP_SOC_RK3326, HAVE_VDPU2 | HAVE_VEPU2 | HAVE_HEVC_DEC, }, - { "rk1808", ROCKCHIP_SOC_RK1808, HAVE_VDPU2 | HAVE_VEPU2, }, - { "rk3566", ROCKCHIP_SOC_RK3566, HAVE_VDPU2 | HAVE_VEPU2 | HAVE_RKVDEC | HAVE_RKVENC | HAVE_JPEG_DEC, }, - { "rk3568", ROCKCHIP_SOC_RK3568, HAVE_VDPU2 | HAVE_VEPU2 | HAVE_RKVDEC | HAVE_RKVENC | HAVE_JPEG_DEC, }, -}; - -static void read_soc_name(char *name, RK_S32 size) -{ - static const char *mpp_soc_name_path = "/proc/device-tree/compatible"; - RK_S32 fd = open(mpp_soc_name_path, O_RDONLY); - if (fd < 0) { - mpp_err("open %s error\n", mpp_soc_name_path); - } else { - ssize_t soc_name_len = 0; - - snprintf(name, size, "unknown"); - soc_name_len = read(fd, name, size - 1); - if (soc_name_len > 0) { - name[soc_name_len] = '\0'; - /* replacing the termination character to space */ - for (char *ptr = name;; ptr = name) { - ptr += strnlen(name, size); - if (ptr >= name + soc_name_len - 1) - break; - *ptr = ' '; - } - - mpp_dbg(MPP_DBG_PLATFORM, "chip name: %s\n", name); - } - - close(fd); - } -} - -static const MppVpuType *check_vpu_type_by_soc_name(const char *soc_name) -{ - RK_U32 i; - - for (i = 0; i < MPP_ARRAY_ELEMS(mpp_vpu_version); i++) - if (strstr(soc_name, mpp_vpu_version[i].compatible)) - return &mpp_vpu_version[i]; - - return NULL; -} class MppPlatformService { @@ -112,8 +35,8 @@ private: RK_U32 vcodec_type; RK_U32 hw_ids[32]; MppServiceCmdCap mpp_service_cmd_cap; - char soc_name[MAX_SOC_NAME_LENGTH]; - RockchipSocType soc_type; + const MppSocInfo *soc_info; + const char *soc_name; public: static MppPlatformService *get_instance() { @@ -123,15 +46,15 @@ public: MppIoctlVersion get_ioctl_version(void) { return ioctl_version; }; const char *get_soc_name() { return soc_name; }; - RockchipSocType get_soc_type() { return soc_type; }; - RK_U32 get_vcodec_type() { return vcodec_type; }; MppServiceCmdCap *get_mpp_service_cmd_cap() { return &mpp_service_cmd_cap; }; RK_U32 get_hw_id(RK_S32 client_type); }; MppPlatformService::MppPlatformService() : ioctl_version(IOCTL_VCODEC_SERVICE), - vcodec_type(0) + vcodec_type(0), + soc_info(NULL), + soc_name(NULL) { /* judge vdpu support version */ MppServiceCmdCap *cap = &mpp_service_cmd_cap; @@ -147,27 +70,18 @@ MppPlatformService::MppPlatformService() mpp_env_get_u32("mpp_debug", &mpp_debug, 0); /* read soc name */ - read_soc_name(soc_name, sizeof(soc_name)); + soc_name = mpp_get_soc_name(); + soc_info = mpp_get_soc_info(); - /* set vpu1 defalut for old chip without dts */ - vcodec_type = HAVE_VDPU1 | HAVE_VEPU1; - { - const MppVpuType *hw_info = check_vpu_type_by_soc_name(soc_name); - if (hw_info) { - vcodec_type = hw_info->vcodec_type; - soc_type = hw_info->soc_type; - mpp_dbg(MPP_DBG_PLATFORM, "match soc name: %s\n", soc_name); - } else - mpp_log("can not found match soc name: %s\n", soc_name); - } + if (soc_info->soc_type == ROCKCHIP_SOC_AUTO) + mpp_log("can not found match soc name: %s\n", soc_name); - /* if /dev/mpp_service not double check */ + ioctl_version = IOCTL_VCODEC_SERVICE; if (mpp_get_mpp_service_name()) { ioctl_version = IOCTL_MPP_SERVICE_V1; check_mpp_service_cap(&vcodec_type, hw_ids, cap); } - - mpp_dbg(MPP_DBG_PLATFORM, "vcodec type %08x\n", vcodec_type); + vcodec_type = soc_info->vcodec_type; } RK_U32 MppPlatformService::get_hw_id(RK_S32 client_type) @@ -185,38 +99,6 @@ MppIoctlVersion mpp_get_ioctl_version(void) return MppPlatformService::get_instance()->get_ioctl_version(); } -const char *mpp_get_soc_name(void) -{ - static const char *soc_name = NULL; - - if (soc_name) - return soc_name; - - soc_name = MppPlatformService::get_instance()->get_soc_name(); - return soc_name; -} - -RockchipSocType mpp_get_soc_type(void) -{ - static RockchipSocType soc_type = ROCKCHIP_SOC_AUTO; - - if (soc_type) - return soc_type; - - soc_type = MppPlatformService::get_instance()->get_soc_type(); - return soc_type; -} - -RK_U32 mpp_get_vcodec_type(void) -{ - static RK_U32 vcodec_type = 0; - - if (!vcodec_type) - vcodec_type = MppPlatformService::get_instance()->get_vcodec_type(); - - return vcodec_type; -} - RK_U32 mpp_get_2d_hw_flag(void) { RK_U32 flag = 0; diff --git a/osal/mpp_soc.cpp b/osal/mpp_soc.cpp new file mode 100644 index 00000000..3120162c --- /dev/null +++ b/osal/mpp_soc.cpp @@ -0,0 +1,793 @@ +/* + * Copyright 2020 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "mpp_soc" + +#include +#include +#include +#include + +#include "mpp_log.h" +#include "mpp_common.h" + +#include "mpp_soc.h" +#include "mpp_platform.h" + +#define MAX_SOC_NAME_LENGTH 128 + +#define CODING_TO_IDX(type) \ + ((RK_U32)(type) >= (RK_U32)MPP_VIDEO_CodingKhronosExtensions) ? \ + ((RK_U32)(-1)) : \ + ((RK_U32)(type) >= (RK_U32)MPP_VIDEO_CodingVC1) ? \ + ((RK_U32)(type) - (RK_U32)MPP_VIDEO_CodingVC1 + 16) : \ + ((RK_U32)(type) - (RK_U32)MPP_VIDEO_CodingUnused) + +#define HAVE_MPEG2 ((RK_U32)(1 << (CODING_TO_IDX(MPP_VIDEO_CodingMPEG2)))) +#define HAVE_H263 ((RK_U32)(1 << (CODING_TO_IDX(MPP_VIDEO_CodingH263)))) +#define HAVE_MPEG4 ((RK_U32)(1 << (CODING_TO_IDX(MPP_VIDEO_CodingMPEG4)))) +#define HAVE_AVC ((RK_U32)(1 << (CODING_TO_IDX(MPP_VIDEO_CodingAVC)))) +#define HAVE_MJPEG ((RK_U32)(1 << (CODING_TO_IDX(MPP_VIDEO_CodingMJPEG)))) +#define HAVE_VP8 ((RK_U32)(1 << (CODING_TO_IDX(MPP_VIDEO_CodingVP8)))) +#define HAVE_VP9 ((RK_U32)(1 << (CODING_TO_IDX(MPP_VIDEO_CodingVP9)))) +#define HAVE_HEVC ((RK_U32)(1 << (CODING_TO_IDX(MPP_VIDEO_CodingHEVC)))) +#define HAVE_AVSP ((RK_U32)(1 << (CODING_TO_IDX(MPP_VIDEO_CodingAVSPLUS)))) +#define HAVE_AVS ((RK_U32)(1 << (CODING_TO_IDX(MPP_VIDEO_CodingAVS)))) + +#define CAP_CODING_VDPU (HAVE_MPEG2|HAVE_H263|HAVE_MPEG4|HAVE_AVC|HAVE_MJPEG|HAVE_VP8) +#define CAP_CODING_JPEGD_PP (HAVE_MJPEG) +#define CAP_CODING_AVSD (HAVE_AVS) +#define CAP_CODING_HEVC (HAVE_HEVC) +#define CAP_CODING_VDPU341 (HAVE_AVC|HAVE_HEVC|HAVE_VP9) +#define CAP_CODING_VDPU341_LITE (HAVE_AVC|HAVE_HEVC) + +#define CAP_CODING_VEPU1 (HAVE_AVC|HAVE_MJPEG|HAVE_VP8) +#define CAP_CODING_VEPU_LITE (HAVE_AVC|HAVE_MJPEG) +#define CAP_CODING_VEPU22 (HAVE_HEVC) +#define CAP_CODING_VEPU54X (HAVE_AVC|HAVE_HEVC) + +static const MppDecHwCap vdpu1 = { + .cap_coding = CAP_CODING_VDPU, + .type = VPU_CLIENT_VDPU1, + .cap_fbc = 0, + .cap_4k = 0, + .cap_8k = 0, + .cap_colmv_buf = 0, + .cap_hw_h265_rps = 0, + .cap_hw_vp9_prob = 0, + .cap_jpg_pp_out = 0, + .cap_10bit = 0, + .reserved = 0, +}; + +static const MppDecHwCap vdpu1_2160p = { + .cap_coding = CAP_CODING_VDPU, + .type = VPU_CLIENT_VDPU1, + .cap_fbc = 0, + .cap_4k = 1, + .cap_8k = 0, + .cap_colmv_buf = 0, + .cap_hw_h265_rps = 0, + .cap_hw_vp9_prob = 0, + .cap_jpg_pp_out = 0, + .cap_10bit = 0, + .reserved = 0, +}; + +static const MppDecHwCap vdpu1_jpeg_pp = { + .cap_coding = CAP_CODING_JPEGD_PP, + .type = VPU_CLIENT_VDPU1_PP, + .cap_fbc = 0, + .cap_4k = 1, + .cap_8k = 1, + .cap_colmv_buf = 0, + .cap_hw_h265_rps = 0, + .cap_hw_vp9_prob = 0, + .cap_jpg_pp_out = 1, + .cap_10bit = 0, + .reserved = 0, +}; + +static const MppDecHwCap vdpu2 = { + .cap_coding = CAP_CODING_VDPU, + .type = VPU_CLIENT_VDPU2, + .cap_fbc = 0, + .cap_4k = 0, + .cap_8k = 0, + .cap_colmv_buf = 0, + .cap_hw_h265_rps = 0, + .cap_hw_vp9_prob = 0, + .cap_jpg_pp_out = 0, + .cap_10bit = 0, + .reserved = 0, +}; + +static const MppDecHwCap vdpu2_jpeg = { + .cap_coding = HAVE_MJPEG, + .type = VPU_CLIENT_VDPU2, + .cap_fbc = 0, + .cap_4k = 0, + .cap_8k = 0, + .cap_colmv_buf = 0, + .cap_hw_h265_rps = 0, + .cap_hw_vp9_prob = 0, + .cap_jpg_pp_out = 0, + .cap_10bit = 0, + .reserved = 0, +}; + +static const MppDecHwCap vdpu2_jpeg_pp = { + .cap_coding = CAP_CODING_JPEGD_PP, + .type = VPU_CLIENT_VDPU2_PP, + .cap_fbc = 0, + .cap_4k = 0, + .cap_8k = 0, + .cap_colmv_buf = 0, + .cap_hw_h265_rps = 0, + .cap_hw_vp9_prob = 0, + .cap_jpg_pp_out = 1, + .cap_10bit = 0, + .reserved = 0, +}; + +static const MppDecHwCap rk_hevc = { + .cap_coding = CAP_CODING_HEVC, + .type = VPU_CLIENT_HEVC_DEC, + .cap_fbc = 0, + .cap_4k = 1, + .cap_8k = 0, + .cap_colmv_buf = 0, + .cap_hw_h265_rps = 0, + .cap_hw_vp9_prob = 0, + .cap_jpg_pp_out = 0, + .cap_10bit = 1, + .reserved = 0, +}; + +static const MppDecHwCap rk_hevc_1080p = { + .cap_coding = CAP_CODING_HEVC, + .type = VPU_CLIENT_HEVC_DEC, + .cap_fbc = 0, + .cap_4k = 0, + .cap_8k = 0, + .cap_colmv_buf = 0, + .cap_hw_h265_rps = 0, + .cap_hw_vp9_prob = 0, + .cap_jpg_pp_out = 0, + .cap_10bit = 0, + .reserved = 0, +}; + +static const MppDecHwCap vdpu341 = { + .cap_coding = CAP_CODING_VDPU341, + .type = VPU_CLIENT_RKVDEC, + .cap_fbc = 0, + .cap_4k = 1, + .cap_8k = 0, + .cap_colmv_buf = 0, + .cap_hw_h265_rps = 0, + .cap_hw_vp9_prob = 0, + .cap_jpg_pp_out = 0, + .cap_10bit = 1, + .reserved = 0, +}; + +static const MppDecHwCap vdpu341_lite = { + .cap_coding = CAP_CODING_VDPU341_LITE, + .type = VPU_CLIENT_RKVDEC, + .cap_fbc = 0, + .cap_4k = 1, + .cap_8k = 0, + .cap_colmv_buf = 0, + .cap_hw_h265_rps = 0, + .cap_hw_vp9_prob = 0, + .cap_jpg_pp_out = 0, + .cap_10bit = 1, + .reserved = 0, +}; + +static const MppDecHwCap vdpu341_lite_1080p = { + .cap_coding = CAP_CODING_VDPU341_LITE, + .type = VPU_CLIENT_RKVDEC, + .cap_fbc = 0, + .cap_4k = 0, + .cap_8k = 0, + .cap_colmv_buf = 0, + .cap_hw_h265_rps = 0, + .cap_hw_vp9_prob = 0, + .cap_jpg_pp_out = 0, + .cap_10bit = 0, + .reserved = 0, +}; + +static const MppDecHwCap vdpu341_h264 = { + .cap_coding = HAVE_AVC, + .type = VPU_CLIENT_RKVDEC, + .cap_fbc = 0, + .cap_4k = 1, + .cap_8k = 0, + .cap_colmv_buf = 0, + .cap_hw_h265_rps = 0, + .cap_hw_vp9_prob = 0, + .cap_jpg_pp_out = 0, + .cap_10bit = 0, + .reserved = 0, +}; + +/* vdpu34x support AFBC_V2 output */ +static const MppDecHwCap vdpu34x = { + .cap_coding = CAP_CODING_VDPU341, + .type = VPU_CLIENT_RKVDEC, + .cap_fbc = 2, + .cap_4k = 1, + .cap_8k = 0, + .cap_colmv_buf = 1, + .cap_hw_h265_rps = 1, + .cap_hw_vp9_prob = 1, + .cap_jpg_pp_out = 0, + .cap_10bit = 1, + .reserved = 0, +}; + +static const MppDecHwCap avsd = { + .cap_coding = CAP_CODING_AVSD, + .type = VPU_CLIENT_AVSPLUS_DEC, + .cap_fbc = 0, + .cap_4k = 0, + .cap_8k = 0, + .cap_colmv_buf = 0, + .cap_hw_h265_rps = 0, + .cap_hw_vp9_prob = 0, + .cap_jpg_pp_out = 0, + .cap_10bit = 0, + .reserved = 0, +}; + +static const MppDecHwCap rkjpegd = { + .cap_coding = HAVE_MJPEG, + .type = VPU_CLIENT_JPEG_DEC, + .cap_fbc = 0, + .cap_4k = 1, + .cap_8k = 0, + .cap_colmv_buf = 0, + .cap_hw_h265_rps = 0, + .cap_hw_vp9_prob = 0, + .cap_jpg_pp_out = 0, + .cap_10bit = 0, + .reserved = 0, +}; + +static const MppEncHwCap vepu1 = { + .cap_coding = CAP_CODING_VEPU1, + .type = VPU_CLIENT_VEPU1, + .cap_fbc = 0, + .cap_4k = 0, + .cap_8k = 0, + .cap_hw_osd = 0, + .cap_hw_roi = 0, + .reserved = 0, +}; + +static const MppEncHwCap vepu2 = { + .cap_coding = CAP_CODING_VEPU1, + .type = VPU_CLIENT_VEPU2, + .cap_fbc = 0, + .cap_4k = 0, + .cap_8k = 0, + .cap_hw_osd = 0, + .cap_hw_roi = 0, + .reserved = 0, +}; + +static const MppEncHwCap vepu2_no_jpeg = { + .cap_coding = HAVE_AVC | HAVE_VP8, + .type = VPU_CLIENT_VEPU2, + .cap_fbc = 0, + .cap_4k = 0, + .cap_8k = 0, + .cap_hw_osd = 0, + .cap_hw_roi = 0, + .reserved = 0, +}; + +static const MppEncHwCap vepu2_jpeg = { + .cap_coding = HAVE_MJPEG, + .type = VPU_CLIENT_VEPU2, + .cap_fbc = 0, + .cap_4k = 0, + .cap_8k = 0, + .cap_hw_osd = 0, + .cap_hw_roi = 0, + .reserved = 0, +}; + +static const MppEncHwCap vepu22 = { + .cap_coding = CAP_CODING_HEVC, + .type = VPU_CLIENT_VEPU22, + .cap_fbc = 0, + .cap_4k = 0, + .cap_8k = 0, + .cap_hw_osd = 0, + .cap_hw_roi = 0, + .reserved = 0, +}; + +static const MppEncHwCap vepu540p = { + .cap_coding = HAVE_AVC, + .type = VPU_CLIENT_RKVENC, + .cap_fbc = 0, + .cap_4k = 0, + .cap_8k = 0, + .cap_hw_osd = 1, + .cap_hw_roi = 1, + .reserved = 0, +}; + +static const MppEncHwCap vepu541 = { + .cap_coding = CAP_CODING_VEPU54X, + .type = VPU_CLIENT_RKVENC, + .cap_fbc = 1, + .cap_4k = 1, + .cap_8k = 0, + .cap_hw_osd = 1, + .cap_hw_roi = 1, + .reserved = 0, +}; + +/* vepu540 support both AFBC_V1 and AFBC_V2 input */ +static const MppEncHwCap vepu540 = { + .cap_coding = CAP_CODING_VEPU54X, + .type = VPU_CLIENT_RKVENC, + .cap_fbc = 0x1 | 0x2, + .cap_4k = 0, + .cap_8k = 0, + .cap_hw_osd = 1, + .cap_hw_roi = 1, + .reserved = 0, +}; + +/* + * NOTE: + * vpu1 = vdpu1 + vepu1 + * vpu2 = vdpu2 + vepu2 + */ +static const MppSocInfo mpp_soc_infos[] = { + { /* + * rk3036 has + * 1 - vdpu1 + * 2 - RK hevc decoder + * rk3036 do NOT have encoder + */ + "rk3036", + ROCKCHIP_SOC_RK3036, + HAVE_VDPU1 | HAVE_VDPU1_PP | HAVE_HEVC_DEC, + { &rk_hevc_1080p, &vdpu1, &vdpu1_jpeg_pp, NULL, }, + { NULL, NULL, NULL, NULL, }, + }, + { /* rk3066 has vpu1 only */ + "rk3066", + ROCKCHIP_SOC_RK3066, + HAVE_VDPU1 | HAVE_VDPU1_PP | HAVE_VEPU1, + { &vdpu1, &vdpu1_jpeg_pp, NULL, NULL, }, + { &vepu1, NULL, NULL, NULL, }, + }, + { /* rk3188 has vpu1 only */ + "rk3188", + ROCKCHIP_SOC_RK3188, + HAVE_VDPU1 | HAVE_VDPU1_PP | HAVE_VEPU1, + { &vdpu1, &vdpu1_jpeg_pp, NULL, NULL, }, + { &vepu1, NULL, NULL, NULL, }, + }, + { /* + * rk3288 has + * 1 - vpu1 with 2160p AVC decoder + * 2 - RK hevc 4K decoder + */ + "rk3288", + ROCKCHIP_SOC_RK3288, + HAVE_VDPU1 | HAVE_VDPU1_PP | HAVE_VEPU1 | HAVE_HEVC_DEC, + { &rk_hevc, &vdpu1_2160p, &vdpu1_jpeg_pp, NULL, }, + { &vepu1, NULL, NULL, NULL, }, + }, + { /* + * rk3126 has + * 1 - vpu1 + * 2 - RK hevc 1080p decoder + */ + "rk3126", + ROCKCHIP_SOC_RK312X, + HAVE_VDPU1 | HAVE_VDPU1_PP | HAVE_VEPU1 | HAVE_HEVC_DEC, + { &rk_hevc_1080p, &vdpu1, &vdpu1_jpeg_pp, NULL, }, + { &vepu1, NULL, NULL, NULL, }, + }, + { /* + * rk3128h has + * 1 - vpu2 + * 2 - RK H.264/H.265 1080p@60fps decoder + * NOTE: rk3128H do NOT have jpeg encoder + */ + "rk3128h", + ROCKCHIP_SOC_RK3128H, + HAVE_VDPU2 | HAVE_VDPU2_PP | HAVE_VEPU2 | HAVE_RKVDEC, + { &vdpu341_lite_1080p, &vdpu2, &vdpu2_jpeg_pp, NULL, }, + { &vepu2_no_jpeg, NULL, NULL, NULL, }, + }, + { /* + * rk3128 has + * 1 - vpu1 + * 2 - RK hevc 1080p decoder + */ + "rk3128", + ROCKCHIP_SOC_RK312X, + HAVE_VDPU1 | HAVE_VDPU1_PP | HAVE_VEPU1 | HAVE_HEVC_DEC, + { &rk_hevc_1080p, &vdpu1, &vdpu1_jpeg_pp, NULL, }, + { &vepu1, NULL, NULL, NULL, }, + }, + { /* + * rk3368 has + * 1 - vpu1 + * 2 - RK hevc 4K decoder + */ + "rk3368", + ROCKCHIP_SOC_RK3368, + HAVE_VDPU1 | HAVE_VDPU1_PP | HAVE_VEPU1 | HAVE_HEVC_DEC, + { &rk_hevc, &vdpu1, &vdpu1_jpeg_pp, NULL, }, + { &vepu1, NULL, NULL, NULL, }, + }, + { /* + * rk3399 has + * 1 - vpu2 + * 2 - H.264/H.265/VP9 4K decoder + */ + "rk3399", + ROCKCHIP_SOC_RK3399, + HAVE_VDPU2 | HAVE_VDPU2_PP | HAVE_VEPU2 | HAVE_RKVDEC, + { &vdpu341, &vdpu2, &vdpu2_jpeg_pp, NULL, }, + { &vepu2, NULL, NULL, NULL, }, + }, + { /* + * rk3228h has + * 1 - vpu2 + * 2 - RK H.264/H.265 4K decoder + * 3 - avs+ decoder + * 4 - H.265 1080p encoder + * rk3228h first for string matching + */ + "rk3228h", + ROCKCHIP_SOC_RK3228H, + HAVE_VDPU2 | HAVE_VDPU2_PP | HAVE_VEPU2 | HAVE_RKVDEC | HAVE_AVSDEC | HAVE_VEPU22, + { &vdpu341_lite, &vdpu2, &vdpu2_jpeg_pp, &avsd, }, + { &vepu2_no_jpeg, &vepu22, NULL, NULL, }, + }, + { /* + * rk3228 has codec: + * 1 - vpu2 + * 2 - RK H.264/H.265/VP9 4K decoder + * 4 - H.265 encoder + */ + "rk3328", + ROCKCHIP_SOC_RK3328, + HAVE_VDPU2 | HAVE_VDPU2_PP | HAVE_VEPU2 | HAVE_RKVDEC | HAVE_VEPU22, + { &vdpu341, &vdpu2, &vdpu2_jpeg_pp, NULL, }, + { &vepu2, &vepu22, NULL, NULL, }, + }, + { /* + * rk3228 have codec: + * 1 - vpu2 + * 2 - RK H.264/H.265 4K decoder + * NOTE: rk3228 do NOT have jpeg encoder + */ + "rk3228", + ROCKCHIP_SOC_RK3228, + HAVE_VDPU2 | HAVE_VDPU2_PP | HAVE_VEPU2 | HAVE_RKVDEC, + { &vdpu341_lite, &vdpu2, &vdpu2_jpeg_pp, NULL, }, + { &vepu2_no_jpeg, NULL, NULL, NULL, }, + }, + { /* + * rk3229 has + * 1 - vpu2 + * 2 - H.264/H.265/VP9 4K decoder + */ + "rk3229", + ROCKCHIP_SOC_RK3229, + HAVE_VDPU2 | HAVE_VDPU2_PP | HAVE_VEPU2 | HAVE_RKVDEC, + { &vdpu341, &vdpu2, &vdpu2_jpeg_pp, NULL, }, + { &vepu2, NULL, NULL, NULL, }, + }, + { /* + * rv1108 has codec: + * 1 - vpu2 for jpeg encoder and decoder + * 2 - RK H.264 4K decoder + * 3 - RK H.264 4K encoder + */ + "rv1108", + ROCKCHIP_SOC_RV1108, + HAVE_VDPU2 | HAVE_VEPU2 | HAVE_RKVDEC | HAVE_RKVENC, + { &vdpu2_jpeg, &vdpu341_h264, NULL, NULL, }, + { &vepu2_jpeg, &vepu540p, NULL, NULL, }, + }, + { /* + * rv1109 has codec: + * 1 - vpu2 for jpeg encoder and decoder + * 2 - RK H.264/H.265 4K decoder + * 3 - RK H.264/H.265 4K encoder + */ + "rv1109", + ROCKCHIP_SOC_RV1109, + HAVE_VDPU2 | HAVE_VEPU2 | HAVE_RKVDEC | HAVE_RKVENC, + { &vdpu2_jpeg, &vdpu341_lite, NULL, NULL, }, + { &vepu2_jpeg, &vepu541, NULL, NULL, }, + }, + { /* + * rv1126 has codec: + * 1 - vpu2 for jpeg encoder and decoder + * 2 - RK H.264/H.265 4K decoder + * 3 - RK H.264/H.265 4K encoder + */ + "rv1126", + ROCKCHIP_SOC_RV1126, + HAVE_VDPU2 | HAVE_VEPU2 | HAVE_RKVDEC | HAVE_RKVENC, + { &vdpu2_jpeg, &vdpu341_lite, NULL, NULL, }, + { &vepu2_jpeg, &vepu541, NULL, NULL, }, + }, + { /* + * rk3326 has + * 1 - vpu2 + * 2 - RK hevc 1080p decoder + */ + "rk3326", + ROCKCHIP_SOC_RK3326, + HAVE_VDPU2 | HAVE_VDPU2_PP | HAVE_VEPU2 | HAVE_HEVC_DEC, + { &rk_hevc_1080p, &vdpu2, &vdpu2_jpeg_pp, NULL, }, + { &vepu2, NULL, NULL, NULL, }, + }, + { /* + * px30 has + * 1 - vpu2 + * 2 - RK hevc 1080p decoder + */ + "px30", + ROCKCHIP_SOC_RK3326, + HAVE_VDPU2 | HAVE_VDPU2_PP | HAVE_VEPU2 | HAVE_HEVC_DEC, + { &rk_hevc_1080p, &vdpu2, &vdpu2_jpeg_pp, NULL, }, + { &vepu2, NULL, NULL, NULL, }, + }, + { /* + * px30 has vpu2 only + */ + "rk1808", + ROCKCHIP_SOC_RK1808, + HAVE_VDPU2 | HAVE_VDPU2_PP | HAVE_VEPU2, + { &vdpu2, &vdpu2_jpeg_pp, NULL, NULL, }, + { &vepu2, NULL, NULL, NULL, }, + }, + { /* + * rk3566/rk3568 has codec: + * 1 - vpu2 for jpeg/vp8 encoder and decoder + * 2 - RK H.264/H.265/VP9 4K decoder + * 3 - RK H.264/H.265 4K encoder + * 3 - RK jpeg decoder + */ + "rk3566", + ROCKCHIP_SOC_RK3566, + HAVE_VDPU2 | HAVE_VEPU2 | HAVE_RKVDEC | HAVE_RKVENC | HAVE_JPEG_DEC, + { &vdpu34x, &rkjpegd, &vdpu2, NULL, }, + { &vepu540, &vepu2, NULL, NULL, }, + }, + { /* + * rk3566/rk3568 has codec: + * 1 - vpu2 for jpeg/vp8 encoder and decoder + * 2 - RK H.264/H.265/VP9 4K decoder + * 3 - RK H.264/H.265 4K encoder + * 3 - RK jpeg decoder + */ + "rk3568", + ROCKCHIP_SOC_RK3568, + HAVE_VDPU2 | HAVE_VEPU2 | HAVE_RKVDEC | HAVE_RKVENC | HAVE_JPEG_DEC, + { &vdpu34x, &rkjpegd, &vdpu2, NULL, }, + { &vepu540, &vepu2, NULL, NULL, }, + }, +}; + +static const MppSocInfo mpp_soc_default = { + "unknown", + ROCKCHIP_SOC_AUTO, + HAVE_VDPU2 | HAVE_VEPU2 | HAVE_VDPU1 | HAVE_VEPU1, + { &vdpu2, &vdpu1, NULL, NULL, }, + { &vepu2, &vepu1, NULL, NULL, }, +}; + +static void read_soc_name(char *name, RK_S32 size) +{ + const char *path = "/proc/device-tree/compatible"; + RK_S32 fd = open(path, O_RDONLY); + + if (fd < 0) { + mpp_err("open %s error\n", path); + } else { + ssize_t soc_name_len = 0; + + snprintf(name, size - 1, "unknown"); + soc_name_len = read(fd, name, size - 1); + if (soc_name_len > 0) { + name[soc_name_len] = '\0'; + /* replacing the termination character to space */ + for (char *ptr = name;; ptr = name) { + ptr += strnlen(name, size); + if (ptr >= name + soc_name_len - 1) + break; + *ptr = ' '; + } + + mpp_dbg(MPP_DBG_PLATFORM, "chip name: %s\n", name); + } + + close(fd); + } +} + + +static const MppSocInfo *check_soc_info(const char *soc_name) +{ + RK_U32 i; + + for (i = 0; i < MPP_ARRAY_ELEMS(mpp_soc_infos); i++) { + const char *compatible = mpp_soc_infos[i].compatible; + + if (strstr(soc_name, compatible)) { + mpp_dbg(MPP_DBG_PLATFORM, "match chip name: %s\n", compatible); + return &mpp_soc_infos[i]; + } + } + + return NULL; +} + +class MppSocService +{ +private: + // avoid any unwanted function + MppSocService(); + ~MppSocService() {}; + MppSocService(const MppSocService &); + MppSocService &operator=(const MppSocService &); + + char soc_name[MAX_SOC_NAME_LENGTH]; + const MppSocInfo *soc_info; + RK_U32 dec_coding_cap; + RK_U32 enc_coding_cap; + +public: + static MppSocService *get() { + static MppSocService instance; + return &instance; + } + + const char *get_soc_name() { return soc_name; }; + const MppSocInfo *get_soc_info() { return soc_info; }; + RK_U32 get_dec_cap() { return dec_coding_cap; }; + RK_U32 get_enc_cap() { return enc_coding_cap; }; +}; + +MppSocService::MppSocService() + : soc_info(NULL), + dec_coding_cap(0), + enc_coding_cap(0) +{ + RK_U32 i; + RK_U32 vcodec_type = 0; + + read_soc_name(soc_name, sizeof(soc_name)); + soc_info = check_soc_info(soc_name); + if (NULL == soc_info) { + mpp_dbg(MPP_DBG_PLATFORM, "use default chip info\n"); + soc_info = &mpp_soc_default; + } + + for (i = 0; i < MPP_ARRAY_ELEMS(soc_info->dec_caps); i++) { + const MppDecHwCap *cap = soc_info->dec_caps[i]; + + if (cap && cap->cap_coding) { + dec_coding_cap |= cap->cap_coding; + vcodec_type |= (1 << cap->type); + } + } + + for (i = 0; i < MPP_ARRAY_ELEMS(soc_info->enc_caps); i++) { + const MppEncHwCap *cap = soc_info->enc_caps[i]; + + if (cap && cap->cap_coding) { + enc_coding_cap |= cap->cap_coding; + vcodec_type |= (1 << cap->type); + } + } + + mpp_dbg(MPP_DBG_PLATFORM, "coding caps: dec %08x enc %08x\n", + dec_coding_cap, enc_coding_cap); + mpp_dbg(MPP_DBG_PLATFORM, "vcodec type: %08x\n", soc_info->vcodec_type); + mpp_assert(soc_info->vcodec_type == vcodec_type); +} + +const char *mpp_get_soc_name(void) +{ + static const char *soc_name = NULL; + + if (soc_name) + return soc_name; + + soc_name = MppSocService::get()->get_soc_name(); + return soc_name; +} + +const MppSocInfo *mpp_get_soc_info(void) +{ + static const MppSocInfo *soc_info = NULL; + + if (soc_info) + return soc_info; + + soc_info = MppSocService::get()->get_soc_info(); + return soc_info; +} + +RockchipSocType mpp_get_soc_type(void) +{ + static RockchipSocType soc_type = ROCKCHIP_SOC_AUTO; + + if (soc_type) + return soc_type; + + soc_type = MppSocService::get()->get_soc_info()->soc_type; + return soc_type; +} + +RK_U32 mpp_get_vcodec_type(void) +{ + static RK_U32 vcodec_type = 0; + + if (!vcodec_type) + vcodec_type = MppSocService::get()->get_soc_info()->vcodec_type; + + return vcodec_type; +} + +static RK_U32 is_valid_cap_coding(RK_U32 cap, MppCodingType coding) +{ + RK_S32 index = CODING_TO_IDX(coding); + if (index > 0 && index < 32 && (cap & (RK_U32)(1 << index))) + return true; + + return false; +} + +RK_U32 mpp_check_soc_cap(MppCtxType type, MppCodingType coding) +{ + RK_U32 cap = 0; + + if (type == MPP_CTX_DEC) + cap = MppSocService::get()->get_dec_cap(); + else if (type == MPP_CTX_ENC) + cap = MppSocService::get()->get_enc_cap(); + else { + mpp_err_f("invalid ctx type %d\n", type); + return 0; + } + + if (!cap) + return 0; + + return is_valid_cap_coding(cap, coding); +}