diff --git a/drivers/video/rockchip/mpp/mpp_common.c b/drivers/video/rockchip/mpp/mpp_common.c index ec25e33a56e1..1d1e01754d7f 100644 --- a/drivers/video/rockchip/mpp/mpp_common.c +++ b/drivers/video/rockchip/mpp/mpp_common.c @@ -1075,7 +1075,7 @@ static int mpp_process_request(struct mpp_session *session, if (mpp->dev_ops->ioctl) return mpp->dev_ops->ioctl(session, req); - mpp_err("unknown mpp ioctl cmd %x\n", req->cmd); + mpp_debug(DEBUG_IOCTL, "unknown mpp ioctl cmd %x\n", req->cmd); return -ENOIOCTLCMD; } break; } diff --git a/drivers/video/rockchip/mpp/mpp_common.h b/drivers/video/rockchip/mpp/mpp_common.h index 677208ebcc21..7df07dfd0b90 100644 --- a/drivers/video/rockchip/mpp/mpp_common.h +++ b/drivers/video/rockchip/mpp/mpp_common.h @@ -150,12 +150,23 @@ enum ENC_INFO_TYPE { ENC_INFO_BUTT, }; -enum ENC_INFO_FLAGS { - ENC_INFO_FLAG_NULL = 0, - ENC_INFO_FLAG_NUMBER, - ENC_INFO_FLAG_STRING, +enum DEC_INFO_TYPE { + DEC_INFO_BASE = 0, + DEC_INFO_WIDTH, + DEC_INFO_HEIGHT, + DEC_INFO_FORMAT, + DEC_INFO_BITDEPTH, + DEC_INFO_FPS, - ENC_INFO_FLAG_BUTT, + DEC_INFO_BUTT, +}; + +enum CODEC_INFO_FLAGS { + CODEC_INFO_FLAG_NULL = 0, + CODEC_INFO_FLAG_NUMBER, + CODEC_INFO_FLAG_STRING, + + CODEC_INFO_FLAG_BUTT, }; /* data common struct for parse out */ diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2.c b/drivers/video/rockchip/mpp/mpp_rkvdec2.c index dc4b6d922410..b401609d07d3 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -144,6 +145,16 @@ struct rkvdec_task { struct mpp_request r_reqs[MPP_MAX_MSG_NUM]; }; +struct rkvdec_session_priv { + /* codec info from user */ + struct { + /* show mode */ + u32 flag; + /* item data */ + u64 val; + } codec_info[DEC_INFO_BUTT]; +}; + struct rkvdec_dev { struct mpp_dev mpp; /* sip smc reset lock */ @@ -610,6 +621,75 @@ static int rkvdec_free_task(struct mpp_session *session, return 0; } +static int rkvdec_control(struct mpp_session *session, struct mpp_request *req) +{ + switch (req->cmd) { + case MPP_CMD_SEND_CODEC_INFO: { + int i; + int cnt; + struct codec_info_elem elem; + struct rkvdec_session_priv *priv; + + if (!session || !session->priv) { + mpp_err("session info null\n"); + return -EINVAL; + } + priv = session->priv; + + cnt = req->size / sizeof(elem); + cnt = (cnt > DEC_INFO_BUTT) ? DEC_INFO_BUTT : cnt; + mpp_debug(DEBUG_IOCTL, "codec info count %d\n", cnt); + for (i = 0; i < cnt; i++) { + if (copy_from_user(&elem, req->data + i * sizeof(elem), sizeof(elem))) { + mpp_err("copy_from_user failed\n"); + continue; + } + if (elem.type > DEC_INFO_BASE && elem.type < DEC_INFO_BUTT && + elem.flag > CODEC_INFO_FLAG_NULL && elem.flag < CODEC_INFO_FLAG_BUTT) { + elem.type = array_index_nospec(elem.type, DEC_INFO_BUTT); + priv->codec_info[elem.type].flag = elem.flag; + priv->codec_info[elem.type].val = elem.data; + } else { + mpp_err("codec info invalid, type %d, flag %d\n", + elem.type, elem.flag); + } + } + } break; + default: { + mpp_err("unknown mpp ioctl cmd %x\n", req->cmd); + } break; + } + + return 0; +} + +static int rkvdec_free_session(struct mpp_session *session) +{ + if (session && session->priv) { + kfree(session->priv); + session->priv = NULL; + } + + return 0; +} + +static int rkvdec_init_session(struct mpp_session *session) +{ + struct rkvdec_session_priv *priv; + + if (!session) { + mpp_err("session is null\n"); + return -EINVAL; + } + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + session->priv = priv; + + return 0; +} + #ifdef CONFIG_PROC_FS static int rkvdec_procfs_remove(struct mpp_dev *mpp) { @@ -821,6 +901,9 @@ static struct mpp_dev_ops rkvdec_v2_dev_ops = { .finish = rkvdec_finish, .result = rkvdec_result, .free_task = rkvdec_free_task, + .ioctl = rkvdec_control, + .init_session = rkvdec_init_session, + .free_session = rkvdec_free_session, }; static const struct mpp_dev_var rkvdec_v2_data = { diff --git a/drivers/video/rockchip/mpp/mpp_rkvenc.c b/drivers/video/rockchip/mpp/mpp_rkvenc.c index 3cd4de229873..1fc3c244e7f0 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvenc.c +++ b/drivers/video/rockchip/mpp/mpp_rkvenc.c @@ -667,7 +667,7 @@ static int rkvenc_control(struct mpp_session *session, struct mpp_request *req) continue; } if (elem.type > ENC_INFO_BASE && elem.type < ENC_INFO_BUTT && - elem.flag > ENC_INFO_FLAG_NULL && elem.flag < ENC_INFO_FLAG_BUTT) { + elem.flag > CODEC_INFO_FLAG_NULL && elem.flag < CODEC_INFO_FLAG_BUTT) { elem.type = array_index_nospec(elem.type, ENC_INFO_BUTT); priv->codec_info[elem.type].flag = elem.flag; priv->codec_info[elem.type].val = elem.data; @@ -753,11 +753,11 @@ static int rkvenc_dump_session(struct mpp_session *session, struct seq_file *seq if (!flag) continue; - if (flag == ENC_INFO_FLAG_NUMBER) { + if (flag == CODEC_INFO_FLAG_NUMBER) { u32 data = priv->codec_info[i].val; seq_printf(seq, "%8d|", data); - } else if (flag == ENC_INFO_FLAG_STRING) { + } else if (flag == CODEC_INFO_FLAG_STRING) { const char *name = (const char *)&priv->codec_info[i].val; seq_printf(seq, "%8s|", name); diff --git a/drivers/video/rockchip/mpp/mpp_vepu1.c b/drivers/video/rockchip/mpp/mpp_vepu1.c index 58619e917b8e..f140a0f828b9 100644 --- a/drivers/video/rockchip/mpp/mpp_vepu1.c +++ b/drivers/video/rockchip/mpp/mpp_vepu1.c @@ -419,7 +419,7 @@ static int vepu_control(struct mpp_session *session, struct mpp_request *req) continue; } if (elem.type > ENC_INFO_BASE && elem.type < ENC_INFO_BUTT && - elem.flag > ENC_INFO_FLAG_NULL && elem.flag < ENC_INFO_FLAG_BUTT) { + elem.flag > CODEC_INFO_FLAG_NULL && elem.flag < CODEC_INFO_FLAG_BUTT) { elem.type = array_index_nospec(elem.type, ENC_INFO_BUTT); priv->codec_info[elem.type].flag = elem.flag; priv->codec_info[elem.type].val = elem.data; @@ -506,11 +506,11 @@ static int vepu_dump_session(struct mpp_session *session, struct seq_file *seq) if (!flag) continue; - if (flag == ENC_INFO_FLAG_NUMBER) { + if (flag == CODEC_INFO_FLAG_NUMBER) { u32 data = priv->codec_info[i].val; seq_printf(seq, "%8d|", data); - } else if (flag == ENC_INFO_FLAG_STRING) { + } else if (flag == CODEC_INFO_FLAG_STRING) { const char *name = (const char *)&priv->codec_info[i].val; seq_printf(seq, "%8s|", name); diff --git a/drivers/video/rockchip/mpp/mpp_vepu2.c b/drivers/video/rockchip/mpp/mpp_vepu2.c index f89b0ce05b2f..8593fe6a8ab4 100644 --- a/drivers/video/rockchip/mpp/mpp_vepu2.c +++ b/drivers/video/rockchip/mpp/mpp_vepu2.c @@ -442,7 +442,7 @@ static int vepu_control(struct mpp_session *session, struct mpp_request *req) continue; } if (elem.type > ENC_INFO_BASE && elem.type < ENC_INFO_BUTT && - elem.flag > ENC_INFO_FLAG_NULL && elem.flag < ENC_INFO_FLAG_BUTT) { + elem.flag > CODEC_INFO_FLAG_NULL && elem.flag < CODEC_INFO_FLAG_BUTT) { elem.type = array_index_nospec(elem.type, ENC_INFO_BUTT); priv->codec_info[elem.type].flag = elem.flag; priv->codec_info[elem.type].val = elem.data; @@ -528,11 +528,11 @@ static int vepu_dump_session(struct mpp_session *session, struct seq_file *seq) if (!flag) continue; - if (flag == ENC_INFO_FLAG_NUMBER) { + if (flag == CODEC_INFO_FLAG_NUMBER) { u32 data = priv->codec_info[i].val; seq_printf(seq, "%8d|", data); - } else if (flag == ENC_INFO_FLAG_STRING) { + } else if (flag == CODEC_INFO_FLAG_STRING) { const char *name = (const char *)&priv->codec_info[i].val; seq_printf(seq, "%8s|", name);