mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-07 01:52:46 +08:00
[mpp_device]: Add new mpp_device for kernel driver
1. Change mpp_device into a new layer for kernel drvier. 2. Separate mpp_service driver and vcodec_service driver. 3. Add mpp_service.c for /dev/mpp_service driver support. 4. Add global mpp_service info query interface. 5. Remove unused function in mpp_device.c Change-Id: I3f53bba3aef525ad3b1f450bb55830d1eeaf29a6 Signed-off-by: Herman Chen <herman.chen@rock-chips.com>
This commit is contained in:
@@ -104,52 +104,6 @@ static MPP_RET mpp_check_cmd_valid(RK_U32 cmd, MppDevCtxImpl *p)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RK_U32 mpp_probe_hw_support(RK_S32 dev)
|
||||
{
|
||||
RK_S32 ret;
|
||||
RK_U32 flag = 0;
|
||||
MppReqV1 mpp_req;
|
||||
|
||||
mpp_req.cmd = MPP_CMD_PROBE_HW_SUPPORT;
|
||||
mpp_req.flag = 0;
|
||||
mpp_req.size = 0;
|
||||
mpp_req.offset = 0;
|
||||
mpp_req.data_ptr = REQ_DATA_PTR(&flag);
|
||||
|
||||
ret = (RK_S32)ioctl(dev, MPP_IOC_CFG_V1, &mpp_req);
|
||||
if (ret) {
|
||||
mpp_err_f("probe hw support error %s.\n", strerror(errno));
|
||||
flag = 0;
|
||||
} else {
|
||||
mpp_refresh_vcodec_type(flag);
|
||||
mpp_dev_dbg_hw_cap("vcodec_support %08x\n", flag);
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
static RK_U32 mpp_get_hw_id(RK_S32 dev)
|
||||
{
|
||||
RK_S32 ret;
|
||||
RK_U32 flag = 0;
|
||||
MppReqV1 mpp_req;
|
||||
|
||||
mpp_req.cmd = MPP_CMD_QUERY_HW_ID;
|
||||
mpp_req.flag = 0;
|
||||
mpp_req.size = 0;
|
||||
mpp_req.offset = 0;
|
||||
mpp_req.data_ptr = REQ_DATA_PTR(&flag);
|
||||
|
||||
ret = (RK_S32)ioctl(dev, MPP_IOC_CFG_V1, &mpp_req);
|
||||
if (ret) {
|
||||
mpp_err_f("get hw id error %s.\n", strerror(errno));
|
||||
flag = 0;
|
||||
}
|
||||
|
||||
mpp_dev_dbg_hw_cap("hardware version 0x%8x", flag);
|
||||
return flag;
|
||||
}
|
||||
|
||||
static RK_S32 mpp_device_set_client_type(MppDevCtx ctx, int dev, RK_S32 client_type)
|
||||
{
|
||||
RK_S32 ret;
|
||||
@@ -266,10 +220,8 @@ MPP_RET mpp_device_init(MppDevCtx *ctx, MppDevCfg *cfg)
|
||||
RK_S32 ret;
|
||||
|
||||
/* if ioctl_version is 1, query hw supprot*/
|
||||
if (p->ioctl_version > 0) {
|
||||
if (p->ioctl_version > 0)
|
||||
p->cap = mpp_get_mpp_service_cmd_cap();
|
||||
mpp_probe_hw_support(dev);
|
||||
}
|
||||
|
||||
client_type = mpp_device_get_client_type(p, p->type, p->coding);
|
||||
ret = mpp_device_set_client_type(p, dev, client_type);
|
||||
@@ -287,7 +239,7 @@ MPP_RET mpp_device_init(MppDevCtx *ctx, MppDevCfg *cfg)
|
||||
*ctx = p;
|
||||
p->vpu_fd = dev;
|
||||
if (p->ioctl_version > 0)
|
||||
cfg->hw_id = mpp_get_hw_id(dev);
|
||||
cfg->hw_id = mpp_get_client_hw_id(p->client_type);
|
||||
else
|
||||
cfg->hw_id = 0;
|
||||
|
||||
|
@@ -25,6 +25,12 @@ set(MPP_ALLOCATOR
|
||||
${DRM_FILES}
|
||||
)
|
||||
|
||||
set(MPP_DRIVER
|
||||
driver/mpp_device_v2.c
|
||||
driver/mpp_service.c
|
||||
driver/vcodec_service.c
|
||||
)
|
||||
|
||||
add_library(osal STATIC
|
||||
mpp_platform.cpp
|
||||
mpp_runtime.cpp
|
||||
@@ -53,6 +59,7 @@ add_library(osal STATIC
|
||||
windows/os_env.c
|
||||
windows/os_log.c
|
||||
${MPP_ALLOCATOR}
|
||||
${MPP_DRIVER}
|
||||
)
|
||||
|
||||
target_link_libraries(osal ${CMAKE_THREAD_LIBS_INIT})
|
||||
|
150
osal/driver/mpp_device_v2.c
Normal file
150
osal/driver/mpp_device_v2.c
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* 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_device"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mpp_log.h"
|
||||
#include "mpp_mem.h"
|
||||
#include "mpp_platform.h"
|
||||
|
||||
#include "mpp_device_api.h"
|
||||
#include "mpp_service_api.h"
|
||||
#include "vcodec_service_api.h"
|
||||
|
||||
typedef struct MppDevImpl_t {
|
||||
MppClientType type;
|
||||
|
||||
void *ctx;
|
||||
const MppDevApi *api;
|
||||
} MppDevImpl;
|
||||
|
||||
MPP_RET mpp_dev_init(MppDev *ctx, MppClientType type)
|
||||
{
|
||||
if (NULL == ctx) {
|
||||
mpp_err_f("found NULL input ctx\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
*ctx = NULL;
|
||||
|
||||
RK_U32 codec_type = mpp_get_vcodec_type();
|
||||
if (!(codec_type & (1 << type))) {
|
||||
mpp_err_f("found unsupported client type %d in platform %x\n",
|
||||
type, codec_type);
|
||||
return MPP_ERR_VALUE;
|
||||
}
|
||||
|
||||
MppIoctlVersion ioctl_version = mpp_get_ioctl_version();
|
||||
const MppDevApi *api = NULL;
|
||||
|
||||
switch (ioctl_version) {
|
||||
case IOCTL_VCODEC_SERVICE : {
|
||||
api = &vcodec_service_api;
|
||||
} break;
|
||||
case IOCTL_MPP_SERVICE_V1 : {
|
||||
api = &mpp_service_api;
|
||||
} break;
|
||||
default : {
|
||||
mpp_err_f("invalid ioctl verstion %d\n", ioctl_version);
|
||||
return MPP_NOK;
|
||||
} break;
|
||||
}
|
||||
|
||||
MppDevImpl *impl = mpp_calloc(MppDevImpl, 1);
|
||||
void *impl_ctx = mpp_calloc_size(void, api->ctx_size);
|
||||
if (NULL == impl || NULL == impl_ctx) {
|
||||
mpp_err_f("malloc failed impl %p impl_ctx %p\n", impl, impl_ctx);
|
||||
MPP_FREE(impl);
|
||||
MPP_FREE(impl_ctx);
|
||||
return MPP_ERR_MALLOC;
|
||||
}
|
||||
|
||||
impl->ctx = impl_ctx;
|
||||
impl->api = api;
|
||||
impl->type = type;
|
||||
*ctx = impl;
|
||||
|
||||
return api->init(impl_ctx, type);
|
||||
}
|
||||
|
||||
MPP_RET mpp_dev_deinit(MppDev ctx)
|
||||
{
|
||||
if (NULL == ctx) {
|
||||
mpp_err_f("found NULL input ctx\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
MppDevImpl *p = (MppDevImpl *)ctx;
|
||||
MPP_RET ret = MPP_OK;
|
||||
|
||||
if (p->api && p->api->deinit && p->ctx)
|
||||
ret = p->api->deinit(p->ctx);
|
||||
|
||||
MPP_FREE(p->ctx);
|
||||
MPP_FREE(p);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
MPP_RET mpp_dev_ioctl(MppDev ctx, RK_S32 cmd, void *param)
|
||||
{
|
||||
if (NULL == ctx) {
|
||||
mpp_err_f("found NULL input ctx\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
MppDevImpl *p = (MppDevImpl *)ctx;
|
||||
const MppDevApi *api = p->api;
|
||||
void *impl_ctx = p->ctx;
|
||||
MPP_RET ret = MPP_OK;
|
||||
|
||||
if (NULL == ctx || NULL == api)
|
||||
return ret;
|
||||
|
||||
switch (cmd) {
|
||||
case MPP_DEV_REG_WR : {
|
||||
if (api->reg_wr)
|
||||
ret = api->reg_wr(impl_ctx, param);
|
||||
} break;
|
||||
case MPP_DEV_REG_RD : {
|
||||
if (api->reg_rd)
|
||||
ret = api->reg_rd(impl_ctx, param);
|
||||
} break;
|
||||
case MPP_DEV_FD_TRANS : {
|
||||
if (api->fd_trans)
|
||||
ret = api->fd_trans(impl_ctx, param);
|
||||
} break;
|
||||
case MPP_DEV_SET_INFO : {
|
||||
if (api->set_info)
|
||||
ret = api->set_info(impl_ctx, param);
|
||||
} break;
|
||||
case MPP_DEV_CMD_SEND : {
|
||||
if (api->cmd_send)
|
||||
ret = api->cmd_send(impl_ctx);
|
||||
} break;
|
||||
case MPP_DEV_CMD_POLL : {
|
||||
if (api->cmd_poll)
|
||||
ret = api->cmd_poll(impl_ctx);
|
||||
} break;
|
||||
default : {
|
||||
mpp_err_f("invalid cmd %d\n", cmd);
|
||||
} break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
412
osal/driver/mpp_service.c
Normal file
412
osal/driver/mpp_service.c
Normal file
@@ -0,0 +1,412 @@
|
||||
/*
|
||||
* 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_serivce"
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mpp_env.h"
|
||||
#include "mpp_log.h"
|
||||
#include "mpp_common.h"
|
||||
|
||||
#include "mpp_service.h"
|
||||
#include "mpp_service_api.h"
|
||||
|
||||
#define MPP_SERVICE_DBG_FUNC (0x00000001)
|
||||
#define MPP_SERVICE_DBG_PROBE (0x00000002)
|
||||
|
||||
#define mpp_srv_dbg(flag, fmt, ...) _mpp_dbg(mpp_service_debug, flag, fmt, ## __VA_ARGS__)
|
||||
#define mpp_srv_dbg_f(flag, fmt, ...) _mpp_dbg_f(mpp_service_debug, flag, fmt, ## __VA_ARGS__)
|
||||
|
||||
#define mpp_src_dbg_func(fmt, ...) mpp_srv_dbg_f(MPP_SERVICE_DBG_FUNC, fmt, ## __VA_ARGS__)
|
||||
#define mpp_src_dbg_probe(fmt, ...) mpp_srv_dbg(MPP_SERVICE_DBG_PROBE, fmt, ## __VA_ARGS__)
|
||||
|
||||
static RK_U32 mpp_service_debug = 0;
|
||||
|
||||
typedef struct MppServiceQueryCfg_t {
|
||||
RK_U32 cmd_butt;
|
||||
const char *name;
|
||||
} MppServiceQueryCfg;
|
||||
|
||||
static const MppServiceQueryCfg query_cfg[] = {
|
||||
{ MPP_CMD_QUERY_BASE, "query_cmd", },
|
||||
{ MPP_CMD_INIT_BASE, "init_cmd", },
|
||||
{ MPP_CMD_SEND_BASE, "query_cmd", },
|
||||
{ MPP_CMD_POLL_BASE, "init_cmd", },
|
||||
{ MPP_CMD_CONTROL_BASE, "control_cmd", },
|
||||
};
|
||||
|
||||
static const RK_U32 query_count = MPP_ARRAY_ELEMS(query_cfg);
|
||||
|
||||
static const char *mpp_service_hw_name[] = {
|
||||
/* 0 ~ 3 */
|
||||
/* VPU_CLIENT_VDPU1 */ "vdpu1",
|
||||
/* VPU_CLIENT_VDPU2 */ "vdpu2",
|
||||
/* VPU_CLIENT_VDPU1_PP */ "vdpu1_pp",
|
||||
/* VPU_CLIENT_VDPU2_PP */ "vdpu2_pp",
|
||||
/* 4 ~ 7 */
|
||||
/* VPU_CLIENT_BUTT */ NULL,
|
||||
/* VPU_CLIENT_BUTT */ NULL,
|
||||
/* VPU_CLIENT_BUTT */ NULL,
|
||||
/* VPU_CLIENT_BUTT */ NULL,
|
||||
/* 8 ~ 11 */
|
||||
/* VPU_CLIENT_HEVC_DEC */ "rkhevc",
|
||||
/* VPU_CLIENT_RKVDEC */ "rkvdec",
|
||||
/* VPU_CLIENT_BUTT */ NULL,
|
||||
/* VPU_CLIENT_BUTT */ NULL,
|
||||
/* 12 ~ 15 */
|
||||
/* VPU_CLIENT_AVSPLUS_DEC */ "avsd",
|
||||
/* VPU_CLIENT_BUTT */ NULL,
|
||||
/* VPU_CLIENT_BUTT */ NULL,
|
||||
/* VPU_CLIENT_BUTT */ NULL,
|
||||
/* 16 ~ 19 */
|
||||
/* VPU_CLIENT_RKVENC */ "rkvenc",
|
||||
/* VPU_CLIENT_VEPU1 */ "vepu1",
|
||||
/* VPU_CLIENT_VEPU2 */ "vepu2",
|
||||
/* VPU_CLIENT_VEPU2_LITE */ "vepu2_lite",
|
||||
/* 20 ~ 23 */
|
||||
/* VPU_CLIENT_BUTT */ NULL,
|
||||
/* VPU_CLIENT_BUTT */ NULL,
|
||||
/* VPU_CLIENT_BUTT */ NULL,
|
||||
/* VPU_CLIENT_BUTT */ NULL,
|
||||
/* 24 ~ 27 */
|
||||
/* VPU_CLIENT_VEPU22 */ "vepu22",
|
||||
/* VPU_CLIENT_BUTT */ NULL,
|
||||
/* VPU_CLIENT_BUTT */ NULL,
|
||||
/* VPU_CLIENT_BUTT */ NULL,
|
||||
/* 28 ~ 31 */
|
||||
/* IEP_CLIENT_TYPE */ "iep",
|
||||
/* VPU_CLIENT_BUTT */ NULL,
|
||||
/* VPU_CLIENT_BUTT */ NULL,
|
||||
/* VPU_CLIENT_BUTT */ NULL,
|
||||
};
|
||||
|
||||
static const char *mpp_service_name = "/dev/mpp_service";
|
||||
|
||||
static RK_S32 mpp_service_ioctl(RK_S32 fd, RK_U32 cmd, RK_U32 size, void *param)
|
||||
{
|
||||
MppReqV1 mpp_req;
|
||||
|
||||
memset(&mpp_req, 0, sizeof(mpp_req));
|
||||
|
||||
mpp_req.cmd = cmd;
|
||||
mpp_req.flag = 0;
|
||||
mpp_req.size = size;
|
||||
mpp_req.offset = 0;
|
||||
mpp_req.data_ptr = REQ_DATA_PTR(param);
|
||||
|
||||
return (RK_S32)ioctl(fd, MPP_IOC_CFG_V1, &mpp_req);
|
||||
}
|
||||
|
||||
static RK_S32 mpp_service_ioctl_request(RK_S32 fd, MppReqV1 *req)
|
||||
{
|
||||
return (RK_S32)ioctl(fd, MPP_IOC_CFG_V1, req);
|
||||
}
|
||||
|
||||
void check_mpp_service_cap(RK_U32 *codec_type, RK_U32 *hw_ids, MppServiceCmdCap *cap)
|
||||
{
|
||||
MppReqV1 mpp_req;
|
||||
RK_S32 fd = -1;
|
||||
RK_S32 ret = 0;
|
||||
RK_U32 *cmd_butt = &cap->query_cmd;;
|
||||
RK_U32 val;
|
||||
RK_U32 i;
|
||||
|
||||
mpp_env_get_u32("mpp_service_debug", &mpp_service_debug, 0);
|
||||
|
||||
*codec_type = 0;
|
||||
memset(hw_ids, 0, sizeof(RK_U32) * 32);
|
||||
|
||||
fd = open(mpp_service_name, O_RDWR);
|
||||
if (fd < 0) {
|
||||
mpp_err("open mpp_service to check cmd capability failed\n");
|
||||
memset(cap, 0, sizeof(*cap));
|
||||
return ;
|
||||
}
|
||||
|
||||
/* check hw_support flag for valid client type */
|
||||
ret = mpp_service_ioctl(fd, MPP_CMD_PROBE_HW_SUPPORT, 0, &val);
|
||||
if (!ret) {
|
||||
mpp_src_dbg_probe("vcodec_support %08x\n", val);
|
||||
*codec_type = val;
|
||||
}
|
||||
|
||||
/* check each valid client type for hw_id */
|
||||
{
|
||||
RK_U32 hw_support = val;
|
||||
|
||||
/* find first valid client type */
|
||||
for (i = 0; i < 32; i++)
|
||||
if (hw_support & (1 << i)) {
|
||||
val = i;
|
||||
break;
|
||||
}
|
||||
|
||||
/* for compatible check hw_id read mode first */
|
||||
ret = mpp_service_ioctl(fd, MPP_CMD_QUERY_HW_ID, sizeof(val), &val);
|
||||
if (!ret) {
|
||||
/* kernel support hw_id check by input client type */
|
||||
for (i = 0; i < 32; i++) {
|
||||
if (hw_support & (1 << i)) {
|
||||
val = i;
|
||||
|
||||
/* send client type and get hw_id */
|
||||
ret = mpp_service_ioctl(fd, MPP_CMD_QUERY_HW_ID, sizeof(val), &val);
|
||||
if (!ret) {
|
||||
mpp_src_dbg_probe("client %-10s hw_id %08x\n", mpp_service_hw_name[i], val);
|
||||
hw_ids[i] = val;
|
||||
} else
|
||||
mpp_err("check valid client %-10s for hw_id failed\n",
|
||||
mpp_service_hw_name[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* kernel need to set client type then get hw_id */
|
||||
for (i = 0; i < 32; i++) {
|
||||
if (hw_support & (1 << i)) {
|
||||
val = i;
|
||||
|
||||
/* set client type first */
|
||||
ret = mpp_service_ioctl(fd, MPP_CMD_INIT_CLIENT_TYPE, sizeof(val), &val);
|
||||
if (ret) {
|
||||
mpp_err("check valid client type %d failed\n", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* then get hw_id */
|
||||
ret = mpp_service_ioctl(fd, MPP_CMD_QUERY_HW_ID, sizeof(val), &val);
|
||||
if (!ret) {
|
||||
mpp_src_dbg_probe("client %-10s hw_id %08x\n", mpp_service_hw_name[i], val);
|
||||
hw_ids[i] = val;
|
||||
} else
|
||||
mpp_err("check valid client %-10s for hw_id failed\n",
|
||||
mpp_service_hw_name[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cap->support_cmd = access("/proc/mpp_service/support_cmd", F_OK) ? 0 : 1;
|
||||
if (!cap->support_cmd)
|
||||
return ;
|
||||
|
||||
for (i = 0; i < query_count; i++, cmd_butt++) {
|
||||
const MppServiceQueryCfg *cfg = &query_cfg[i];
|
||||
|
||||
memset(&mpp_req, 0, sizeof(mpp_req));
|
||||
|
||||
val = cfg->cmd_butt;
|
||||
mpp_req.cmd = MPP_CMD_QUERY_CMD_SUPPORT;
|
||||
mpp_req.data_ptr = REQ_DATA_PTR(&val);
|
||||
|
||||
ret = (RK_S32)ioctl(fd, MPP_IOC_CFG_V1, &mpp_req);
|
||||
if (ret)
|
||||
mpp_err_f("query %-11s support error %s.\n", cfg->name, strerror(errno));
|
||||
else {
|
||||
*cmd_butt = val;
|
||||
mpp_src_dbg_probe("query %-11s support %04x\n", cfg->name, val);
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
#define MAX_FD_TRANS 16
|
||||
|
||||
typedef struct FdTransInfo_t {
|
||||
RK_U32 reg_idx;
|
||||
RK_U32 offset;
|
||||
} FdTransInfo;
|
||||
|
||||
typedef struct MppDevMppService_t {
|
||||
RK_S32 client_type;
|
||||
RK_S32 fd;
|
||||
|
||||
RK_S32 req_cnt;
|
||||
MppReqV1 reqs[MAX_REQ_NUM];
|
||||
RK_S32 fd_trans_count;
|
||||
FdTransInfo fd_trans_info[MAX_FD_TRANS];
|
||||
|
||||
/* support max cmd buttom */
|
||||
const MppServiceCmdCap *cap;
|
||||
} MppDevMppService;
|
||||
|
||||
MPP_RET mpp_service_init(void *ctx, MppClientType type)
|
||||
{
|
||||
MppDevMppService *p = (MppDevMppService *)ctx;
|
||||
MPP_RET ret = MPP_NOK;
|
||||
|
||||
p->cap = mpp_get_mpp_service_cmd_cap();
|
||||
p->fd = open(mpp_service_name, O_RDWR);
|
||||
if (p->fd < 0) {
|
||||
mpp_err("open mpp_service failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* set client type first */
|
||||
ret = mpp_service_ioctl(p->fd, MPP_CMD_INIT_CLIENT_TYPE, sizeof(type), &type);
|
||||
if (ret)
|
||||
mpp_err("set client type %d failed\n", type);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
MPP_RET mpp_service_deinit(void *ctx)
|
||||
{
|
||||
MppDevMppService *p = (MppDevMppService *)ctx;
|
||||
if (p->fd)
|
||||
close(p->fd);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_service_reg_wr(void *ctx, MppDevRegWrCfg *cfg)
|
||||
{
|
||||
MppDevMppService *p = (MppDevMppService *)ctx;
|
||||
|
||||
if (!p->req_cnt)
|
||||
memset(p->reqs, 0, sizeof(p->reqs));
|
||||
|
||||
MppReqV1 *mpp_req = &p->reqs[p->req_cnt];
|
||||
|
||||
mpp_req->cmd = MPP_CMD_SET_REG_WRITE;
|
||||
mpp_req->flag = 0;
|
||||
mpp_req->size = cfg->size;
|
||||
mpp_req->offset = cfg->offset;
|
||||
mpp_req->data_ptr = REQ_DATA_PTR(cfg->reg);
|
||||
p->req_cnt++;
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_service_reg_rd(void *ctx, MppDevRegRdCfg *cfg)
|
||||
{
|
||||
MppDevMppService *p = (MppDevMppService *)ctx;
|
||||
|
||||
if (!p->req_cnt)
|
||||
memset(p->reqs, 0, sizeof(p->reqs));
|
||||
|
||||
MppReqV1 *mpp_req = &p->reqs[p->req_cnt];
|
||||
|
||||
mpp_req->cmd = MPP_CMD_SET_REG_READ;
|
||||
mpp_req->flag = 0;
|
||||
mpp_req->size = cfg->size;
|
||||
mpp_req->offset = cfg->offset;
|
||||
mpp_req->data_ptr = REQ_DATA_PTR(cfg->reg);
|
||||
p->req_cnt++;
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_service_fd_trans(void *ctx, MppDevFdTransCfg *cfg)
|
||||
{
|
||||
MppDevMppService *p = (MppDevMppService *)ctx;
|
||||
|
||||
if (!cfg->offset)
|
||||
return MPP_OK;
|
||||
|
||||
FdTransInfo *info = &p->fd_trans_info[p->fd_trans_count++];
|
||||
|
||||
info->reg_idx = cfg->reg_idx;
|
||||
info->offset = cfg->offset;
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_service_set_info(void *ctx, MppDevSetInfoCfg *cfg)
|
||||
{
|
||||
(void)ctx;
|
||||
(void)cfg;
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET mpp_service_cmd_send(void *ctx)
|
||||
{
|
||||
MppDevMppService *p = (MppDevMppService *)ctx;
|
||||
|
||||
if (p->req_cnt <= 0 || p->req_cnt > MAX_REQ_NUM) {
|
||||
mpp_err_f("ctx %p invalid request count %d\n", ctx, p->req_cnt);
|
||||
return MPP_ERR_VALUE;
|
||||
}
|
||||
|
||||
/* set fd trans info if needed */
|
||||
if (p->fd_trans_count) {
|
||||
MppReqV1 *mpp_req = &p->reqs[p->req_cnt];
|
||||
|
||||
mpp_req->cmd = MPP_CMD_SET_REG_ADDR_OFFSET;
|
||||
mpp_req->flag = 0;
|
||||
mpp_req->size = p->fd_trans_count * sizeof(p->fd_trans_info[0]);
|
||||
mpp_req->offset = 0;
|
||||
mpp_req->data_ptr = REQ_DATA_PTR(&p->fd_trans_info[0]);
|
||||
p->req_cnt++;
|
||||
}
|
||||
|
||||
/* setup flag for multi message request */
|
||||
if (p->req_cnt > 1) {
|
||||
RK_S32 i;
|
||||
|
||||
for (i = 0; i < p->req_cnt; i++)
|
||||
p->reqs[i].flag |= MPP_FLAGS_MULTI_MSG;
|
||||
}
|
||||
p->reqs[p->req_cnt - 1].flag |= MPP_FLAGS_LAST_MSG;
|
||||
|
||||
MPP_RET ret = mpp_service_ioctl_request(p->fd, &p->reqs[0]);
|
||||
if (ret) {
|
||||
mpp_err_f("ioctl MPP_IOC_CFG_V1 failed ret %d errno %d %s\n",
|
||||
ret, errno, strerror(errno));
|
||||
ret = errno;
|
||||
}
|
||||
|
||||
p->req_cnt = 0;
|
||||
p->fd_trans_count = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
MPP_RET mpp_service_cmd_poll(void *ctx)
|
||||
{
|
||||
MppDevMppService *p = (MppDevMppService *)ctx;
|
||||
MppReqV1 dev_req;
|
||||
|
||||
memset(&dev_req, 0, sizeof(dev_req));
|
||||
dev_req.cmd = MPP_CMD_POLL_HW_FINISH;
|
||||
dev_req.flag |= MPP_FLAGS_LAST_MSG;
|
||||
|
||||
MPP_RET ret = mpp_service_ioctl_request(p->fd, &dev_req);
|
||||
if (ret) {
|
||||
mpp_err_f("ioctl MPP_IOC_CFG_V1 failed ret %d errno %d %s\n",
|
||||
ret, errno, strerror(errno));
|
||||
ret = errno;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const MppDevApi mpp_service_api = {
|
||||
"mpp_service",
|
||||
sizeof(MppDevMppService),
|
||||
mpp_service_init,
|
||||
mpp_service_deinit,
|
||||
mpp_service_reg_wr,
|
||||
mpp_service_reg_rd,
|
||||
mpp_service_fd_trans,
|
||||
mpp_service_set_info,
|
||||
mpp_service_cmd_send,
|
||||
mpp_service_cmd_poll,
|
||||
};
|
369
osal/driver/vcodec_service.c
Normal file
369
osal/driver/vcodec_service.c
Normal file
@@ -0,0 +1,369 @@
|
||||
/*
|
||||
* 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 "vcodec_service"
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mpp_env.h"
|
||||
#include "mpp_log.h"
|
||||
#include "mpp_mem.h"
|
||||
#include "mpp_time.h"
|
||||
#include "mpp_list.h"
|
||||
#include "mpp_common.h"
|
||||
|
||||
#include "vpu.h"
|
||||
#include "vcodec_service.h"
|
||||
#include "vcodec_service_api.h"
|
||||
|
||||
#define MAX_REGS_COUNT 3
|
||||
#define MPX_EXTRA_INFO_NUM 16
|
||||
|
||||
typedef struct VcodecExtraSlot_t {
|
||||
RK_U32 reg_idx;
|
||||
RK_U32 offset;
|
||||
} VcodecExtraSlot;
|
||||
|
||||
typedef struct VcodecExtraInfo_t {
|
||||
RK_U32 magic; // Fix magic value 0x4C4A46
|
||||
RK_U32 count; // valid patch info count
|
||||
VcodecExtraSlot slots[MPX_EXTRA_INFO_NUM];
|
||||
} VcodecExtraInfo;
|
||||
|
||||
typedef struct VcodecRegCfg_t {
|
||||
RK_U32 reg_size;
|
||||
VcodecExtraInfo extra_info;
|
||||
|
||||
void *reg_set;
|
||||
void *reg_get;
|
||||
} VcodecRegCfg;
|
||||
|
||||
typedef struct MppDevVcodecService_t {
|
||||
RK_S32 client_type;
|
||||
RK_S32 fd;
|
||||
RK_S32 max_regs;
|
||||
RK_U32 reg_size;
|
||||
|
||||
RK_S32 reg_send_idx;
|
||||
RK_S32 reg_poll_idx;
|
||||
|
||||
VcodecRegCfg regs[MAX_REGS_COUNT];
|
||||
} MppDevVcodecService;
|
||||
|
||||
/* For vpu1 / vpu2 */
|
||||
static const char *mpp_vpu_dev[] = {
|
||||
"/dev/vpu_service",
|
||||
"/dev/vpu-service",
|
||||
};
|
||||
|
||||
/* For hevc 4K decoder */
|
||||
static const char *mpp_hevc_dev[] = {
|
||||
"/dev/hevc_service",
|
||||
"/dev/hevc-service",
|
||||
};
|
||||
|
||||
/* For H.264/H.265/VP9 4K decoder */
|
||||
static const char *mpp_rkvdec_dev[] = {
|
||||
"/dev/rkvdec",
|
||||
};
|
||||
|
||||
/* For H.264 4K encoder */
|
||||
static const char *mpp_rkvenc_dev[] = {
|
||||
"/dev/rkvenc",
|
||||
};
|
||||
|
||||
/* For avs+ decoder */
|
||||
static const char *mpp_avsd_dev[] = {
|
||||
"/dev/avsd",
|
||||
};
|
||||
|
||||
/* For H.264 / jpeg encoder */
|
||||
static const char *mpp_vepu_dev[] = {
|
||||
"/dev/vepu",
|
||||
};
|
||||
|
||||
#define mpp_find_device(dev) _mpp_find_device(dev, MPP_ARRAY_ELEMS(dev))
|
||||
|
||||
static const char *_mpp_find_device(const char **dev, RK_U32 size)
|
||||
{
|
||||
RK_U32 i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
if (!access(dev[i], F_OK))
|
||||
return dev[i];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static RK_S32 vcodec_service_ioctl(RK_S32 fd, RK_S32 cmd, void *regs, RK_S32 size)
|
||||
{
|
||||
MppReq req;
|
||||
|
||||
req.req = regs;
|
||||
req.size = size;
|
||||
|
||||
return (RK_S32)ioctl(fd, cmd, &req);
|
||||
}
|
||||
|
||||
static void extra_info_init(VcodecExtraInfo *info)
|
||||
{
|
||||
info->magic = EXTRA_INFO_MAGIC;
|
||||
info->count = 0;
|
||||
}
|
||||
|
||||
MPP_RET vcodec_service_init(void *ctx, MppClientType type)
|
||||
{
|
||||
MppDevVcodecService *p = (MppDevVcodecService *)ctx;
|
||||
static RK_S32 vcodec_ioctl_version = -1;
|
||||
VPU_CLIENT_TYPE client_type;
|
||||
const char *name = NULL;
|
||||
RK_U32 reg_size = 0;
|
||||
RK_S32 max_regs = 2;
|
||||
MPP_RET ret = MPP_NOK;
|
||||
|
||||
switch (type) {
|
||||
case VPU_CLIENT_VDPU1 : {
|
||||
name = mpp_find_device(mpp_vpu_dev);
|
||||
client_type = VPU_DEC;
|
||||
reg_size = VDPU1_REGISTERS;
|
||||
} break;
|
||||
case VPU_CLIENT_VDPU2 : {
|
||||
name = mpp_find_device(mpp_vpu_dev);
|
||||
client_type = VPU_DEC;
|
||||
reg_size = VDPU2_REGISTERS;
|
||||
} break;
|
||||
case VPU_CLIENT_VDPU1_PP : {
|
||||
name = mpp_find_device(mpp_vpu_dev);
|
||||
client_type = VPU_DEC_PP;
|
||||
reg_size = VDPU1_PP_REGISTERS;
|
||||
} break;
|
||||
case VPU_CLIENT_VDPU2_PP : {
|
||||
name = mpp_find_device(mpp_vpu_dev);
|
||||
client_type = VPU_DEC_PP;
|
||||
reg_size = VDPU2_PP_REGISTERS;
|
||||
} break;
|
||||
case VPU_CLIENT_HEVC_DEC : {
|
||||
name = mpp_find_device(mpp_hevc_dev);
|
||||
client_type = VPU_DEC;
|
||||
reg_size = RKHEVC_REGISTERS;
|
||||
max_regs = 3;
|
||||
} break;
|
||||
case VPU_CLIENT_RKVDEC : {
|
||||
name = mpp_find_device(mpp_rkvdec_dev);
|
||||
client_type = VPU_DEC;
|
||||
reg_size = RKVDEC_REGISTERS;
|
||||
max_regs = 3;
|
||||
} break;
|
||||
case VPU_CLIENT_AVSPLUS_DEC : {
|
||||
name = mpp_find_device(mpp_avsd_dev);
|
||||
client_type = VPU_DEC;
|
||||
reg_size = AVSD_REGISTERS;
|
||||
} break;
|
||||
case VPU_CLIENT_RKVENC : {
|
||||
name = mpp_find_device(mpp_rkvenc_dev);
|
||||
client_type = VPU_ENC;
|
||||
reg_size = AVSD_REGISTERS;
|
||||
} break;
|
||||
case VPU_CLIENT_VEPU1 : {
|
||||
name = mpp_find_device(mpp_vpu_dev);
|
||||
client_type = VPU_ENC;
|
||||
reg_size = VEPU1_REGISTERS;
|
||||
} break;
|
||||
case VPU_CLIENT_VEPU2 : {
|
||||
name = mpp_find_device(mpp_vpu_dev);
|
||||
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;
|
||||
} break;
|
||||
}
|
||||
|
||||
p->fd = open(name, O_RDWR);
|
||||
if (p->fd < 0) {
|
||||
mpp_err("open vcodec_service %s failed\n", name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (vcodec_ioctl_version < 0) {
|
||||
ret = (RK_S32)ioctl(p->fd, VPU_IOC_SET_CLIENT_TYPE, (unsigned long)client_type);
|
||||
if (!ret) {
|
||||
vcodec_ioctl_version = 0;
|
||||
} else {
|
||||
ret = (RK_S32)ioctl(p->fd, VPU_IOC_SET_CLIENT_TYPE_U32, (RK_U32)client_type);
|
||||
if (!ret)
|
||||
vcodec_ioctl_version = 1;
|
||||
}
|
||||
mpp_assert(ret == MPP_OK);
|
||||
} else {
|
||||
RK_U32 cmd = (vcodec_ioctl_version == 0) ?
|
||||
(VPU_IOC_SET_CLIENT_TYPE) :
|
||||
(VPU_IOC_SET_CLIENT_TYPE_U32);
|
||||
|
||||
ret = (RK_S32)ioctl(p->fd, cmd, client_type);
|
||||
}
|
||||
|
||||
p->max_regs = max_regs;
|
||||
p->reg_size = reg_size * sizeof(RK_U32);
|
||||
{
|
||||
RK_S32 i;
|
||||
|
||||
for (i = 0; i < max_regs; i++) {
|
||||
VcodecRegCfg *reg = &p->regs[i];
|
||||
|
||||
reg->reg_size = p->reg_size;
|
||||
extra_info_init(®->extra_info);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
MPP_RET vcodec_service_deinit(void *ctx)
|
||||
{
|
||||
MppDevVcodecService *p = (MppDevVcodecService *)ctx;
|
||||
|
||||
if (p->fd)
|
||||
close(p->fd);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET vcodec_service_reg_wr(void *ctx, MppDevRegWrCfg *cfg)
|
||||
{
|
||||
MppDevVcodecService *p = (MppDevVcodecService *)ctx;
|
||||
VcodecRegCfg *send_cfg = &p->regs[p->reg_send_idx];
|
||||
|
||||
mpp_assert(cfg->offset == 0);
|
||||
send_cfg->reg_set = cfg->reg;
|
||||
send_cfg->reg_size = cfg->size;
|
||||
|
||||
if (p->reg_size != cfg->size)
|
||||
mpp_err_f("reg size mismatch wr %d rd %d\n",
|
||||
p->reg_size, cfg->size);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET vcodec_service_reg_rd(void *ctx, MppDevRegRdCfg *cfg)
|
||||
{
|
||||
MppDevVcodecService *p = (MppDevVcodecService *)ctx;
|
||||
VcodecRegCfg *send_cfg = &p->regs[p->reg_send_idx];
|
||||
|
||||
mpp_assert(cfg->offset == 0);
|
||||
send_cfg->reg_get = cfg->reg;
|
||||
if (send_cfg->reg_size != cfg->size)
|
||||
mpp_err_f("reg size mismatch rd %d rd %d\n",
|
||||
send_cfg->reg_size, cfg->size);
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET vcodec_service_fd_trans(void *ctx, MppDevFdTransCfg *cfg)
|
||||
{
|
||||
if (cfg->offset) {
|
||||
MppDevVcodecService *p = (MppDevVcodecService *)ctx;
|
||||
VcodecRegCfg *send_cfg = &p->regs[p->reg_send_idx];
|
||||
VcodecExtraInfo *extra = &send_cfg->extra_info;
|
||||
VcodecExtraSlot *slot = &extra->slots[extra->count];
|
||||
|
||||
slot->reg_idx = cfg->reg_idx;
|
||||
slot->offset = cfg->offset;
|
||||
extra->count++;
|
||||
}
|
||||
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
MPP_RET vcodec_service_cmd_send(void *ctx)
|
||||
{
|
||||
MppDevVcodecService *p = (MppDevVcodecService *)ctx;
|
||||
VcodecRegCfg *send_cfg = &p->regs[p->reg_send_idx];
|
||||
VcodecExtraInfo *extra = &send_cfg->extra_info;
|
||||
void *reg_set = send_cfg->reg_set;
|
||||
RK_U32 reg_size = send_cfg->reg_size;
|
||||
|
||||
if (extra->count) {
|
||||
void *extra_data = reg_set + reg_size;
|
||||
RK_S32 extra_size = sizeof(send_cfg->extra_info);
|
||||
|
||||
memcpy(extra_data, extra, extra_size);
|
||||
reg_size += extra_size;
|
||||
|
||||
extra_info_init(extra);
|
||||
}
|
||||
|
||||
MPP_RET ret = vcodec_service_ioctl(p->fd, VPU_IOC_SET_REG,
|
||||
reg_set, reg_size);
|
||||
if (ret) {
|
||||
mpp_err_f("ioctl VPU_IOC_SET_REG failed ret %d errno %d %s\n",
|
||||
ret, errno, strerror(errno));
|
||||
ret = errno;
|
||||
}
|
||||
|
||||
p->reg_send_idx++;
|
||||
if (p->reg_send_idx >= p->max_regs)
|
||||
p->reg_send_idx = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
MPP_RET vcodec_service_cmd_poll(void *ctx)
|
||||
{
|
||||
MppDevVcodecService *p = (MppDevVcodecService *)ctx;
|
||||
VcodecRegCfg *poll_cfg = &p->regs[p->reg_poll_idx];
|
||||
void *reg_get = poll_cfg->reg_get;
|
||||
RK_S32 reg_size = poll_cfg->reg_size;
|
||||
MPP_RET ret = vcodec_service_ioctl(p->fd, VPU_IOC_GET_REG,
|
||||
reg_get, reg_size);
|
||||
if (ret) {
|
||||
mpp_err_f("ioctl VPU_IOC_GET_REG failed ret %d errno %d %s\n",
|
||||
ret, errno, strerror(errno));
|
||||
ret = errno;
|
||||
}
|
||||
|
||||
p->reg_poll_idx++;
|
||||
if (p->reg_poll_idx >= p->max_regs)
|
||||
p->reg_poll_idx = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const MppDevApi vcodec_service_api = {
|
||||
"vcodec_service",
|
||||
sizeof(MppDevVcodecService),
|
||||
vcodec_service_init,
|
||||
vcodec_service_deinit,
|
||||
vcodec_service_reg_wr,
|
||||
vcodec_service_reg_rd,
|
||||
vcodec_service_fd_trans,
|
||||
NULL,
|
||||
vcodec_service_cmd_send,
|
||||
vcodec_service_cmd_poll,
|
||||
};
|
98
osal/inc/mpp_device_api.h
Normal file
98
osal/inc/mpp_device_api.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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_DEVICE_API_H__
|
||||
#define __MPP_DEVICE_API_H__
|
||||
|
||||
#include "rk_type.h"
|
||||
#include "mpp_err.h"
|
||||
#include "mpp_platform.h"
|
||||
|
||||
typedef enum MppDevIoctlCmd_e {
|
||||
/* hardware operation setup config */
|
||||
MPP_DEV_REG_WR,
|
||||
MPP_DEV_REG_RD,
|
||||
MPP_DEV_FD_TRANS,
|
||||
MPP_DEV_SET_INFO,
|
||||
|
||||
MPP_DEV_CMD_SEND,
|
||||
MPP_DEV_CMD_POLL,
|
||||
|
||||
MPP_DEV_IOCTL_CMD_BUTT,
|
||||
} MppDevIoctlCmd;
|
||||
|
||||
/* for MPP_DEV_REG_WR */
|
||||
typedef struct MppDevRegWrCfg_t {
|
||||
void *reg;
|
||||
RK_U32 size;
|
||||
RK_U32 offset;
|
||||
} MppDevRegWrCfg;
|
||||
|
||||
/* for MPP_DEV_REG_RD */
|
||||
typedef struct MppDevRegRdCfg_t {
|
||||
void *reg;
|
||||
RK_U32 size;
|
||||
RK_U32 offset;
|
||||
} MppDevRegRdCfg;
|
||||
|
||||
/* for MPP_DEV_FD_TRANS */
|
||||
typedef struct MppDevFdTransCfg_t {
|
||||
RK_U32 reg_idx;
|
||||
RK_U32 offset;
|
||||
} MppDevFdTransCfg;
|
||||
|
||||
/* for MPP_DEV_SET_INFO */
|
||||
typedef struct MppDevSetInfoCfg_t {
|
||||
RK_U32 type;
|
||||
RK_U32 flag;
|
||||
RK_U64 data;
|
||||
} MppDevSetInfoCfg;
|
||||
|
||||
typedef struct MppDevApi_t {
|
||||
const char *name;
|
||||
RK_U32 ctx_size;
|
||||
MPP_RET (*init)(void *ctx, MppClientType type);
|
||||
MPP_RET (*deinit)(void *ctx);
|
||||
|
||||
/* config the cmd on preparing */
|
||||
MPP_RET (*reg_wr)(void *ctx, MppDevRegWrCfg *cfg);
|
||||
MPP_RET (*reg_rd)(void *ctx, MppDevRegRdCfg *cfg);
|
||||
MPP_RET (*fd_trans)(void *ctx, MppDevFdTransCfg *cfg);
|
||||
MPP_RET (*set_info)(void *ctx, MppDevSetInfoCfg *cfg);
|
||||
|
||||
/* send cmd to hardware */
|
||||
MPP_RET (*cmd_send)(void *ctx);
|
||||
|
||||
/* poll cmd from hardware */
|
||||
MPP_RET (*cmd_poll)(void *ctx);
|
||||
} MppDevApi;
|
||||
|
||||
typedef void* MppDev;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
MPP_RET mpp_dev_init(MppDev *ctx, MppClientType type);
|
||||
MPP_RET mpp_dev_deinit(MppDev ctx);
|
||||
|
||||
MPP_RET mpp_dev_ioctl(MppDev ctx, RK_S32 cmd, void *param);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MPP_DEVICE_API_H__ */
|
@@ -32,7 +32,7 @@ typedef enum MppIoctlVersion_e {
|
||||
/*
|
||||
* Platform video codec hardware feature
|
||||
*/
|
||||
typedef enum {
|
||||
typedef enum MppClientType_e {
|
||||
VPU_CLIENT_VDPU1 = 0, /* 0x00000001 */
|
||||
VPU_CLIENT_VDPU2 = 1, /* 0x00000002 */
|
||||
VPU_CLIENT_VDPU1_PP = 2, /* 0x00000004 */
|
||||
@@ -51,7 +51,7 @@ typedef enum {
|
||||
IEP_CLIENT_TYPE = 28, /* 0x10000000 */
|
||||
|
||||
VPU_CLIENT_BUTT,
|
||||
} VPU_CLIENT2_TYPE;
|
||||
} MppClientType;
|
||||
|
||||
/* RK combined codec */
|
||||
#define HAVE_VDPU1 (1 << VPU_CLIENT_VDPU1) /* 0x00000001 */
|
||||
@@ -94,14 +94,13 @@ 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);
|
||||
RK_U32 mpp_refresh_vcodec_type(RK_U32 vcodec_type);
|
||||
const char *mpp_get_platform_dev_name(MppCtxType type, MppCodingType coding, RK_U32 platform);
|
||||
const char *mpp_get_vcodec_dev_name(MppCtxType type, MppCodingType coding);
|
||||
const MppServiceCmdCap *mpp_get_mpp_service_cmd_cap(void);
|
||||
RK_U32 mpp_get_client_hw_id(RK_S32 client_type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__MPP_PLATFORM__*/
|
||||
|
||||
|
@@ -56,7 +56,7 @@ typedef enum MppDevCmd_e {
|
||||
MPP_DEV_PROP_BUTT,
|
||||
} MppDevCmd;
|
||||
|
||||
typedef enum MppDevCmdType_e {
|
||||
typedef enum MppServiceCmdType_e {
|
||||
MPP_CMD_QUERY_BASE = 0,
|
||||
MPP_CMD_PROBE_HW_SUPPORT = MPP_CMD_QUERY_BASE + 0,
|
||||
MPP_CMD_QUERY_HW_ID = MPP_CMD_QUERY_BASE + 1,
|
||||
@@ -87,7 +87,7 @@ typedef enum MppDevCmdType_e {
|
||||
MPP_CMD_CONTROL_BUTT,
|
||||
|
||||
MPP_CMD_BUTT,
|
||||
} MppDevCmdType;
|
||||
} MppServiceCmdType;
|
||||
|
||||
typedef struct MppReq_t {
|
||||
RK_U32 *req;
|
||||
@@ -111,4 +111,14 @@ typedef struct MppServiceCmdCap_t {
|
||||
RK_U32 ctrl_cmd;
|
||||
} MppServiceCmdCap;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void check_mpp_service_cap(RK_U32 *codec_type, RK_U32 *hw_ids, MppServiceCmdCap *cap);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MPP_SERVICE_H__ */
|
||||
|
32
osal/inc/mpp_service_api.h
Normal file
32
osal/inc/mpp_service_api.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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_SERVICE_API_H__
|
||||
#define __MPP_SERVICE_API_H__
|
||||
|
||||
#include "mpp_device_api.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const MppDevApi mpp_service_api;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MPP_SERVICE_API_H__ */
|
@@ -32,6 +32,18 @@
|
||||
|
||||
#define VPU_IOC_WRITE(nr, size) _IOC(_IOC_WRITE, VPU_IOC_MAGIC, (nr), (size))
|
||||
|
||||
#define VDPU1_REGISTERS (101)
|
||||
#define VDPU2_REGISTERS (159)
|
||||
#define VDPU1_PP_REGISTERS (164)
|
||||
#define VDPU2_PP_REGISTERS (184)
|
||||
#define RKHEVC_REGISTERS (68)
|
||||
#define RKVDEC_REGISTERS (78)
|
||||
#define AVSD_REGISTERS (60)
|
||||
|
||||
#define VEPU1_REGISTERS (164)
|
||||
#define VEPU2_REGISTERS (184)
|
||||
#define RKVENC_REGISTERS (140)
|
||||
|
||||
typedef struct VPUReq {
|
||||
RK_U32 *req;
|
||||
RK_U32 size;
|
||||
|
32
osal/inc/vcodec_service_api.h
Normal file
32
osal/inc/vcodec_service_api.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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 __VCODEC_SERVICE_API_H__
|
||||
#define __VCODEC_SERVICE_API_H__
|
||||
|
||||
#include "mpp_device_api.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const MppDevApi vcodec_service_api;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __VCODEC_SERVICE_API_H__ */
|
@@ -194,7 +194,7 @@ private:
|
||||
|
||||
MppIoctlVersion ioctl_version;
|
||||
RK_U32 vcodec_type;
|
||||
RK_U32 vcodec_capability;
|
||||
RK_U32 hw_ids[32];
|
||||
MppServiceCmdCap mpp_service_cmd_cap;
|
||||
char soc_name[MAX_SOC_NAME_LENGTH];
|
||||
RockchipSocType soc_type;
|
||||
@@ -209,9 +209,8 @@ public:
|
||||
const char *get_soc_name() { return soc_name; };
|
||||
RockchipSocType get_soc_type() { return soc_type; };
|
||||
RK_U32 get_vcodec_type() { return vcodec_type; };
|
||||
void set_vcodec_type(RK_U32 val) { vcodec_type = val; };
|
||||
RK_U32 get_vcodec_capability() { return vcodec_capability; };
|
||||
MppServiceCmdCap *get_mpp_service_cmd_cap() { return &mpp_service_cmd_cap; };
|
||||
RK_U32 get_hw_id(RK_S32 client_type);
|
||||
};
|
||||
|
||||
MppPlatformService::MppPlatformService()
|
||||
@@ -248,6 +247,7 @@ MppPlatformService::MppPlatformService()
|
||||
/* if /dev/mpp_service not double check */
|
||||
if (mpp_find_device(mpp_service_dev)) {
|
||||
ioctl_version = IOCTL_MPP_SERVICE_V1;
|
||||
check_mpp_service_cap(&vcodec_type, hw_ids, cap);
|
||||
mpp_dbg(MPP_DBG_PLATFORM, "/dev/mpp_service not double check device\n");
|
||||
goto __return;
|
||||
}
|
||||
@@ -301,6 +301,16 @@ __return:
|
||||
mpp_dbg(MPP_DBG_PLATFORM, "vcodec type %08x\n", vcodec_type);
|
||||
}
|
||||
|
||||
RK_U32 MppPlatformService::get_hw_id(RK_S32 client_type)
|
||||
{
|
||||
RK_U32 hw_id = 0;
|
||||
|
||||
if (vcodec_type & (1 << client_type))
|
||||
hw_id = hw_ids[client_type];
|
||||
|
||||
return hw_id;
|
||||
}
|
||||
|
||||
MppIoctlVersion mpp_get_ioctl_version(void)
|
||||
{
|
||||
return MppPlatformService::get_instance()->get_ioctl_version();
|
||||
@@ -340,13 +350,6 @@ RK_U32 mpp_get_2d_hw_flag(void)
|
||||
return flag;
|
||||
}
|
||||
|
||||
RK_U32 mpp_refresh_vcodec_type(RK_U32 vcodec_type)
|
||||
{
|
||||
MppPlatformService::get_instance()->set_vcodec_type(vcodec_type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *mpp_get_platform_dev_name(MppCtxType type, MppCodingType coding, RK_U32 platform)
|
||||
{
|
||||
const char *dev = mpp_find_device(mpp_service_dev);
|
||||
@@ -558,3 +561,8 @@ const MppServiceCmdCap *mpp_get_mpp_service_cmd_cap(void)
|
||||
{
|
||||
return MppPlatformService::get_instance()->get_mpp_service_cmd_cap();
|
||||
}
|
||||
|
||||
RK_U32 mpp_get_client_hw_id(RK_S32 client_type)
|
||||
{
|
||||
return MppPlatformService::get_instance()->get_hw_id(client_type);
|
||||
}
|
||||
|
Reference in New Issue
Block a user