diff --git a/drivers/video/rockchip/mpp/mpp_common.h b/drivers/video/rockchip/mpp/mpp_common.h index d296e2b5fb988423e705e46b9e1c6a4100eab1ac..f3a7bed23ba80c1c150eeb12deea178311e073a7 100644 --- a/drivers/video/rockchip/mpp/mpp_common.h +++ b/drivers/video/rockchip/mpp/mpp_common.h @@ -29,7 +29,7 @@ #define MPP_WORK_TIMEOUT_DELAY (500) #define MPP_MAX_MSG_NUM (16) -#define MPP_MAX_REG_TRANS_NUM (60) +#define MPP_MAX_REG_TRANS_NUM (80) #define MPP_MAX_TASK_CAPACITY (16) /* define flags for mpp_request */ #define MPP_FLAGS_MULTI_MSG (0x00000001) @@ -249,6 +249,9 @@ struct mpp_hw_info { u32 reg_end; /* register of enable hardware */ int reg_en; + /* register of codec format */ + int reg_fmt; + u32 reg_ret_status; void *link_info; }; diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2.c b/drivers/video/rockchip/mpp/mpp_rkvdec2.c index 218499f7a6e9a5610a59bd03277bbbdb1e0fc26b..189e31cdf137895d372e88c520941cbfbf58c4a9 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2.c @@ -22,14 +22,49 @@ * hardware information */ static struct mpp_hw_info rkvdec_v2_hw_info = { - .reg_num = RKVDEC_REG_NUM, - .reg_id = RKVDEC_REG_HW_ID_INDEX, - .reg_start = RKVDEC_REG_START_INDEX, - .reg_end = RKVDEC_REG_END_INDEX, - .reg_en = RKVDEC_REG_START_EN_INDEX, + .reg_num = 279, + .reg_id = 0, + .reg_start = 0, + .reg_end = 278, + .reg_en = 10, + .reg_fmt = 9, + .reg_ret_status = 224, .link_info = &rkvdec_link_v2_hw_info, }; +static struct mpp_hw_info rkvdec_rk356x_hw_info = { + .reg_num = 279, + .reg_id = 0, + .reg_start = 0, + .reg_end = 278, + .reg_en = 10, + .reg_fmt = 9, + .reg_ret_status = 224, + .link_info = &rkvdec_link_rk356x_hw_info, +}; + +static struct mpp_hw_info rkvdec_vdpu382_hw_info = { + .reg_num = 279, + .reg_id = 0, + .reg_start = 0, + .reg_end = 278, + .reg_en = 10, + .reg_fmt = 9, + .reg_ret_status = 224, + .link_info = &rkvdec_link_vdpu382_hw_info, +}; + +static struct mpp_hw_info rkvdec_vdpu383_hw_info = { + .reg_num = 360, + .reg_id = 0, + .reg_start = 0, + .reg_end = 359, + .reg_en = 16, + .reg_fmt = 8, + .reg_ret_status = 15, + .link_info = &rkvdec_link_vdpu383_hw_info, +}; + /* * file handle translate information */ @@ -79,11 +114,77 @@ static struct mpp_trans_info rkvdec_v2_trans[] = { } }; +/* + * file handle translate information + */ +static const u16 trans_vdpu383_tbl_h265d[] = { + 128, 129, 130, 131, 132, 133, 134, 140, 142, 144, 146, 148, 150, 152, 154, + 156, 158, 160, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 192, 194, 195, 196, 197, 198, 199, 200, 201, + 202, 203, 204, 205, 206, 207, 208, 209, 210, 216, 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232 +}; + +static const u16 trans_vdpu383_tbl_h264d[] = { + 128, 129, 130, 131, 132, 133, 134, 140, 142, 144, 146, 148, 150, 152, 154, + 156, 158, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 182, 183, 184, 185, 192, 194, 195, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, 208, 209, 210, 216, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, 229, 230, 231, 232 +}; + +static const u16 trans_vdpu383_tbl_vp9d[] = { + 128, 129, 130, 131, 132, 133, 134, 140, 142, 144, 146, 148, 150, 152, 154, + 156, 158, 160, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 192, 194, 195, 196, 197, 198, 199, 200, 201, + 202, 203, 204, 205, 206, 207, 208, 209, 210, 216, 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232 +}; + +static const u16 trans_vdpu383_tbl_avs2d[] = { + 128, 129, 130, 131, 132, 133, 134, 140, 142, 144, 146, 148, 150, 152, 154, + 156, 158, 160, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 192, 194, 195, 196, 197, 198, 199, 200, 201, + 202, 203, 204, 205, 206, 207, 208, 209, 210, 216, 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232 +}; + +static const u16 trans_vdpu383_tbl_av1d[] = { + 128, 131, 133, 134, 140, 142, 144, 146, 148, 150, 152, 154, + 156, 158, 160, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 192, 194, 195, 196, 197, 198, 199, 200, 201, + 202, 203, 204, 205, 206, 207, 208, 209, 210, 216, 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232 +}; + +static struct mpp_trans_info rkvdec_vdpu383_trans[] = { + [RKVDEC_FMT_H265D] = { + .count = ARRAY_SIZE(trans_vdpu383_tbl_h265d), + .table = trans_vdpu383_tbl_h265d, + }, + [RKVDEC_FMT_H264D] = { + .count = ARRAY_SIZE(trans_vdpu383_tbl_h264d), + .table = trans_vdpu383_tbl_h264d, + }, + [RKVDEC_FMT_VP9D] = { + .count = ARRAY_SIZE(trans_vdpu383_tbl_vp9d), + .table = trans_vdpu383_tbl_vp9d, + }, + [RKVDEC_FMT_AVS2] = { + .count = ARRAY_SIZE(trans_vdpu383_tbl_avs2d), + .table = trans_vdpu383_tbl_avs2d, + }, + [RKVDEC_FMT_AV1D] = { + .count = ARRAY_SIZE(trans_vdpu383_tbl_av1d), + .table = trans_vdpu383_tbl_av1d, + } +}; + static int mpp_extract_rcb_info(struct rkvdec2_rcb_info *rcb_inf, struct mpp_request *req) { - int max_size = ARRAY_SIZE(rcb_inf->elem); - int cnt = req->size / sizeof(rcb_inf->elem[0]); + u32 max_size = ARRAY_SIZE(rcb_inf->elem); + u32 cnt = req->size / sizeof(rcb_inf->elem[0]); if (req->size > sizeof(rcb_inf->elem)) { mpp_err("count %d,max_size %d\n", cnt, max_size); @@ -129,8 +230,8 @@ static int rkvdec2_extract_task_msg(struct mpp_session *session, memcpy(&task->w_reqs[task->w_req_cnt++], req, sizeof(*req)); } break; case MPP_CMD_SET_REG_READ: { - int req_base; - int max_size; + u32 req_base; + u32 max_size; if (req->offset >= RKVDEC_PERF_SEL_OFFSET) { req_base = RKVDEC_PERF_SEL_OFFSET; @@ -174,7 +275,7 @@ int mpp_set_rcbbuf(struct mpp_dev *mpp, struct mpp_session *session, mpp_debug_enter(); if (priv && dec->rcb_iova) { - int i; + u32 i; u32 reg_idx, rcb_size, rcb_offset; struct rkvdec2_rcb_info *rcb_inf = &priv->rcb_inf; u32 width = priv->codec_info[DEC_INFO_WIDTH].val; @@ -221,7 +322,8 @@ int rkvdec2_task_init(struct mpp_dev *mpp, struct mpp_session *session, /* process fd in register */ if (!(msgs->flags & MPP_FLAGS_REG_FD_NO_TRANS)) { - u32 fmt = RKVDEC_GET_FORMAT(task->reg[RKVDEC_REG_FORMAT_INDEX]); + int reg_fmt = mpp_task->hw_info->reg_fmt; + u32 fmt = RKVDEC_GET_FORMAT(task->reg[reg_fmt]); ret = mpp_translate_reg_address(session, mpp_task, fmt, task->reg, &task->off_inf); @@ -279,6 +381,27 @@ void *rkvdec2_alloc_task(struct mpp_session *session, return &task->mpp_task; } +static void *rkvdec2_rk3568_alloc_task(struct mpp_session *session, + struct mpp_task_msgs *msgs) +{ + u32 fmt; + int reg_fmt; + struct mpp_task *mpp_task = NULL; + struct rkvdec2_task *task = NULL; + + mpp_task = rkvdec2_alloc_task(session, msgs); + if (!mpp_task) + return NULL; + + task = to_rkvdec2_task(mpp_task); + reg_fmt = mpp_task->hw_info->reg_fmt; + fmt = RKVDEC_GET_FORMAT(task->reg[reg_fmt]); + /* workaround for rk356x, fix the hw bug of cabac/cavlc switch only in h264d */ + task->need_hack = (fmt == RKVDEC_FMT_H264D); + + return mpp_task; +} + static int rkvdec2_run(struct mpp_dev *mpp, struct mpp_task *mpp_task) { struct rkvdec2_task *task = to_rkvdec2_task(mpp_task); @@ -287,7 +410,7 @@ static int rkvdec2_run(struct mpp_dev *mpp, struct mpp_task *mpp_task) /* set cache size */ u32 reg = RKVDEC_CACHE_PERMIT_CACHEABLE_ACCESS | RKVDEC_CACHE_PERMIT_READ_ALLOCATE; - int i; + u32 i; mpp_debug_enter(); @@ -304,7 +427,7 @@ static int rkvdec2_run(struct mpp_dev *mpp, struct mpp_task *mpp_task) /* set registers for hardware */ for (i = 0; i < task->w_req_cnt; i++) { - int s, e; + u32 s, e; struct mpp_request *req = &task->w_reqs[i]; s = req->offset / sizeof(u32); @@ -331,6 +454,81 @@ static int rkvdec2_run(struct mpp_dev *mpp, struct mpp_task *mpp_task) return 0; } +static int rkvdec2_rk3568_run(struct mpp_dev *mpp, struct mpp_task *mpp_task) +{ + struct rkvdec2_task *task = to_rkvdec2_task(mpp_task); + int ret = 0; + + mpp_debug_enter(); + + /* + * run fix before task processing + * workaround for rk356x, fix the hw bug of cabac/cavlc switch only in h264d + */ +// if (task->need_hack) +// rkvdec2_3568_hack_fix(mpp); + + ret = rkvdec2_run(mpp, mpp_task); + + mpp_debug_leave(); + + return ret; +} + +static int rkvdec_vdpu383_run(struct mpp_dev *mpp, struct mpp_task *mpp_task) +{ + struct rkvdec2_task *task = to_rkvdec2_task(mpp_task); + struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp); + u32 timing_en = mpp->srv->timing_en; + struct rkvdec_link_dev *link = dec->link_dec; + + /* set cache size */ + u32 reg = RKVDEC_CACHE_PERMIT_CACHEABLE_ACCESS | + RKVDEC_CACHE_PERMIT_READ_ALLOCATE; + u32 i; + + mpp_debug_enter(); + + if (!mpp_debug_unlikely(DEBUG_CACHE_32B)) + reg |= RKVDEC_CACHE_LINE_SIZE_64_BYTES; + + mpp_write_relaxed(mpp, RKVDEC_REG_CACHE0_SIZE_BASE, reg); + /* clear cache */ + mpp_write_relaxed(mpp, RKVDEC_REG_CLR_CACHE0_BASE, 1); + + /* set registers for hardware */ + for (i = 0; i < task->w_req_cnt; i++) { + u32 s, e; + struct mpp_request *req = &task->w_reqs[i]; + + s = req->offset / sizeof(u32); + e = s + req->size / sizeof(u32); + mpp_write_req(mpp, task->reg, s, e, -1); + } + + /* flush tlb before starting hardware */ + mpp_iommu_flush_tlb(mpp->iommu_info); + + /* init current task */ + mpp->cur_task = mpp_task; + + mpp_task_run_begin(mpp_task, timing_en, MPP_WORK_TIMEOUT_DELAY); + + /* set ip time out threshold, ip watch-dog */ + writel_relaxed(0x7fffff, link->reg_base + link->info->ip_time_base); + + /* Flush the register before the start the device */ + wmb(); + /* enable hardware */ + writel(RKVDEC_START_EN, link->reg_base + link->info->en_base); + + mpp_task_run_end(mpp_task, timing_en); + + mpp_debug_leave(); + + return 0; +} + static int rkvdec2_irq(struct mpp_dev *mpp) { mpp->irq_status = mpp_read(mpp, RKVDEC_REG_INT_EN); @@ -342,6 +540,30 @@ static int rkvdec2_irq(struct mpp_dev *mpp) return IRQ_WAKE_THREAD; } +static int rkvdec_vdpu383_irq(struct mpp_dev *mpp) +{ + struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp); + struct rkvdec_link_dev *link = dec->link_dec; + u32 irq_val; + u32 irq_bits = link->info->irq_mask >> 16; + u32 status_bits = link->info->status_mask >> 16; + + /* read and clear irq */ + irq_val = readl_relaxed(link->reg_base + link->info->irq_base); + if (!(irq_val & irq_bits)) + return IRQ_NONE; + writel(link->info->irq_mask, link->reg_base + link->info->irq_base); + + /* read and clear status */ + mpp->irq_status = readl_relaxed(link->reg_base + link->info->status_base); + writel(link->info->status_mask, link->reg_base + link->info->status_base); + /* wake isr to handle current task */ + if (mpp->irq_status & status_bits) + return IRQ_WAKE_THREAD; + + return IRQ_NONE; +} + static int rkvdec2_isr(struct mpp_dev *mpp) { u32 err_mask; @@ -377,6 +599,43 @@ static int rkvdec2_isr(struct mpp_dev *mpp) return IRQ_HANDLED; } +static int rkvdec_vdpu383_isr(struct mpp_dev *mpp) +{ + u32 err_mask; + struct rkvdec2_task *task = NULL; + struct mpp_task *mpp_task = mpp->cur_task; + struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp); + + /* FIXME use a spin lock here */ + if (!mpp_task) { + dev_err(mpp->dev, "no current task\n"); + return IRQ_HANDLED; + } + mpp_task->hw_cycles = mpp_read(mpp, RKVDEC_PERF_WORKING_CNT); + mpp_time_diff_with_hw_time(mpp_task, dec->cycle_clk->real_rate_hz); + mpp->cur_task = NULL; + task = to_rkvdec2_task(mpp_task); + task->irq_status = mpp->irq_status; + + mpp_debug(DEBUG_IRQ_STATUS, "irq_status: %08x\n", task->irq_status); + /* TODO */ + + /* handle error */ + err_mask = dec->link_dec->info->err_mask; + if (err_mask & task->irq_status) { + atomic_inc(&mpp->reset_request); + if (mpp_debug_unlikely(DEBUG_DUMP_ERR_REG)) { + mpp_debug(DEBUG_DUMP_ERR_REG, "irq_status: %08x\n", task->irq_status); + mpp_task_dump_hw_reg(mpp); + } + } + + mpp_task_finish(mpp_task->session, mpp_task); + + mpp_debug_leave(); + return IRQ_HANDLED; +} + static int rkvdec2_read_perf_sel(struct mpp_dev *mpp, u32 *regs, u32 s, u32 e) { u32 i; @@ -421,7 +680,7 @@ static int rkvdec2_finish(struct mpp_dev *mpp, struct mpp_task *mpp_task) req = &task->r_reqs[i]; /* read perf register */ if (req->offset >= RKVDEC_PERF_SEL_OFFSET) { - int off = req->offset - RKVDEC_PERF_SEL_OFFSET; + u32 off = req->offset - RKVDEC_PERF_SEL_OFFSET; s = off / sizeof(u32); e = s + req->size / sizeof(u32); @@ -434,6 +693,62 @@ static int rkvdec2_finish(struct mpp_dev *mpp, struct mpp_task *mpp_task) } /* revert hack for irq status */ task->reg[RKVDEC_REG_INT_EN_INDEX] = task->irq_status; + + /* revert hack for decoded length */ + dec_get = mpp_read_relaxed(mpp, RKVDEC_REG_RLC_BASE); + dec_length = dec_get - task->strm_addr; + task->reg[RKVDEC_REG_RLC_BASE_INDEX] = dec_length << 10; + mpp_debug(DEBUG_REGISTER, "dec_get %08x dec_length %d\n", dec_get, dec_length); + + if (mpp->srv->timing_en) { + s64 time_diff; + + mpp_task->on_finish = ktime_get(); + set_bit(TASK_TIMING_FINISH, &mpp_task->state); + + time_diff = ktime_us_delta(mpp_task->on_finish, mpp_task->on_create); + + if (mpp->timing_check && time_diff > (s64)mpp->timing_check) + mpp_task_dump_timing(mpp_task, time_diff); + } + + mpp_debug_leave(); + + return 0; +} + +static int rkvdec_vdpu383_finish(struct mpp_dev *mpp, struct mpp_task *mpp_task) +{ + u32 i; + u32 dec_get; + s32 dec_length; + u32 reg_ret_status; + struct rkvdec2_task *task = to_rkvdec2_task(mpp_task); + struct mpp_request *req; + u32 s, e; + + mpp_debug_enter(); + + /* read register after running */ + for (i = 0; i < task->r_req_cnt; i++) { + req = &task->r_reqs[i]; + /* read perf register */ + if (req->offset >= RKVDEC_PERF_SEL_OFFSET) { + u32 off = req->offset - RKVDEC_PERF_SEL_OFFSET; + + s = off / sizeof(u32); + e = s + req->size / sizeof(u32); + rkvdec2_read_perf_sel(mpp, task->reg_sel, s, e); + } else { + s = req->offset / sizeof(u32); + e = s + req->size / sizeof(u32); + mpp_read_req(mpp, task->reg, s, e); + } + } + /* revert hack for irq status */ + reg_ret_status = mpp->var->hw_info->reg_ret_status; + task->reg[reg_ret_status] = task->irq_status; + /* revert hack for decoded length */ dec_get = mpp_read_relaxed(mpp, RKVDEC_REG_RLC_BASE); dec_length = dec_get - task->strm_addr; @@ -468,7 +783,7 @@ int rkvdec2_result(struct mpp_dev *mpp, struct mpp_task *mpp_task, req = &task->r_reqs[i]; if (req->offset >= RKVDEC_PERF_SEL_OFFSET) { - int off = req->offset - RKVDEC_PERF_SEL_OFFSET; + u32 off = req->offset - RKVDEC_PERF_SEL_OFFSET; if (copy_to_user(req->data, (u8 *)task->reg_sel + off, @@ -503,8 +818,8 @@ static int rkvdec2_control(struct mpp_session *session, struct mpp_request *req) { switch (req->cmd) { case MPP_CMD_SEND_CODEC_INFO: { - int i; - int cnt; + u32 i; + u32 cnt; struct codec_info_elem elem; struct rkvdec2_session_priv *priv; @@ -863,6 +1178,24 @@ int rkvdec2_reset(struct mpp_dev *mpp) return 0; } +static int rkvdec_vdpu383_reset(struct mpp_dev *mpp) +{ + struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp); + struct rkvdec_link_dev *link = dec->link_dec; + + mpp_debug_enter(); + + /* use ip reset to reset core and mmu */ + writel(link->info->ip_reset_en, link->reg_base + link->info->ip_reset_base); + udelay(5); + /* clear reset ready status bit */ + writel(link->info->ip_reset_mask, link->reg_base + link->info->status_base); + + mpp_debug_leave(); + + return 0; +} + static struct mpp_hw_ops rkvdec_v2_hw_ops = { .init = rkvdec2_init, .clk_on = rkvdec2_clk_on, @@ -881,6 +1214,15 @@ static struct mpp_hw_ops rkvdec_rk3588_hw_ops = { .reset = rkvdec2_sip_reset, }; +static struct mpp_hw_ops rkvdec_vdpu383_hw_ops = { + .init = rkvdec2_init, + .clk_on = rkvdec2_clk_on, + .clk_off = rkvdec2_clk_off, + .get_freq = rkvdec2_get_freq, + .set_freq = rkvdec2_set_freq, + .reset = rkvdec_vdpu383_reset, +}; + static struct mpp_dev_ops rkvdec_v2_dev_ops = { .alloc_task = rkvdec2_alloc_task, .run = rkvdec2_run, @@ -894,6 +1236,33 @@ static struct mpp_dev_ops rkvdec_v2_dev_ops = { .free_session = rkvdec2_free_session, }; +static struct mpp_dev_ops rkvdec_rk3568_dev_ops = { + .alloc_task = rkvdec2_rk3568_alloc_task, + .run = rkvdec2_rk3568_run, + .irq = rkvdec2_irq, + .isr = rkvdec2_isr, + .finish = rkvdec2_finish, + .result = rkvdec2_result, + .free_task = rkvdec2_free_task, + .ioctl = rkvdec2_control, + .init_session = rkvdec2_init_session, + .free_session = rkvdec2_free_session, + .dump_dev = rkvdec_link_dump, +}; + +static struct mpp_dev_ops rkvdec_vdpu383_dev_ops = { + .alloc_task = rkvdec2_alloc_task, + .run = rkvdec_vdpu383_run, + .irq = rkvdec_vdpu383_irq, + .isr = rkvdec_vdpu383_isr, + .finish = rkvdec_vdpu383_finish, + .result = rkvdec2_result, + .free_task = rkvdec2_free_task, + .ioctl = rkvdec2_control, + .init_session = rkvdec2_init_session, + .free_session = rkvdec2_free_session, +}; + static const struct mpp_dev_var rkvdec_v2_data = { .device_type = MPP_DEVICE_RKVDEC, .hw_info = &rkvdec_v2_hw_info, @@ -910,6 +1279,14 @@ static const struct mpp_dev_var rkvdec_rk3588_data = { .dev_ops = &rkvdec_v2_dev_ops, }; +static const struct mpp_dev_var rkvdec_rk3576_data = { + .device_type = MPP_DEVICE_RKVDEC, + .hw_info = &rkvdec_vdpu383_hw_info, + .trans_info = rkvdec_vdpu383_trans, + .hw_ops = &rkvdec_vdpu383_hw_ops, + .dev_ops = &rkvdec_vdpu383_dev_ops, +}; + static const struct of_device_id mpp_rkvdec2_dt_match[] = { { .compatible = "rockchip,rkv-decoder-v2", @@ -919,6 +1296,10 @@ static const struct of_device_id mpp_rkvdec2_dt_match[] = { .compatible = "rockchip,rkv-decoder-v2-ccu", .data = &rkvdec_rk3588_data, }, + { + .compatible = "rockchip,rkv-decoder-rk3576", + .data = &rkvdec_rk3576_data, + }, {}, }; @@ -1084,7 +1465,7 @@ static int rkvdec2_alloc_rcbbuf(struct platform_device *pdev, struct rkvdec2_dev dec->rcb_info_count = device_property_count_u32(dev, "rockchip,rcb-info"); if (dec->rcb_info_count > 0 && dec->rcb_info_count <= (sizeof(dec->rcb_infos) / sizeof(u32))) { - int i; + u32 i; ret = device_property_read_u32_array(dev, "rockchip,rcb-info", dec->rcb_infos, dec->rcb_info_count); @@ -1220,7 +1601,7 @@ static int rkvdec2_probe_default(struct platform_device *pdev) rkvdec2_alloc_rcbbuf(pdev, dec); rkvdec2_link_init(pdev, dec); - if (dec->link_dec) { + if (dec->link_dec && (mpp->task_capacity > 1)) { ret = devm_request_threaded_irq(dev, mpp->irq, rkvdec2_link_irq_proc, NULL, IRQF_SHARED, dev_name(dev), mpp); @@ -1241,9 +1622,15 @@ static int rkvdec2_probe_default(struct platform_device *pdev) mpp->session_max_buffers = RKVDEC_SESSION_MAX_BUFFERS; rkvdec2_procfs_init(mpp); + + if (dec->link_dec && (mpp->task_capacity > 1)) + rkvdec2_link_procfs_init(mpp); + /* register current device to mpp service */ mpp_dev_register_srv(mpp, mpp->srv); + dev_info(dev, "probing finish\n"); + return ret; } diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2.h b/drivers/video/rockchip/mpp/mpp_rkvdec2.h index a0b0366f232c4bd823325362c11ccfa8d3193e79..ba1e63807653f2cfb07ed248de7769968dec681e 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2.h +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2.h @@ -39,19 +39,13 @@ #define RKVDEC_SESSION_MAX_BUFFERS 40 /* The maximum registers number of all the version */ -#define RKVDEC_REG_NUM 279 -#define RKVDEC_REG_HW_ID_INDEX 0 -#define RKVDEC_REG_START_INDEX 0 -#define RKVDEC_REG_END_INDEX 278 +#define RKVDEC_REG_NUM 360 #define REVDEC_GET_PROD_NUM(x) (((x) >> 16) & 0xffff) -#define RKVDEC_REG_FORMAT_INDEX 9 #define RKVDEC_GET_FORMAT(x) ((x) & 0x3ff) #define RKVDEC_REG_START_EN_BASE 0x28 -#define RKVDEC_REG_START_EN_INDEX 10 - #define RKVDEC_START_EN BIT(0) #define RKVDEC_REG_YSTRIDE_INDEX 20 @@ -110,6 +104,7 @@ enum RKVDEC_FMT { RKVDEC_FMT_H264D = 1, RKVDEC_FMT_VP9D = 2, RKVDEC_FMT_AVS2 = 3, + RKVDEC_FMT_AV1D = 4, }; #define RKVDEC_MAX_RCB_NUM (16) diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c index 97114a6cb97bfccd2a36aa1276015f9d43ab842a..a67f2c15d13eb3743b6e933ad1d49af3c3f3b3f6 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c @@ -134,6 +134,20 @@ struct rkvdec_link_info rkvdec_link_vdpu382_hw_info = { }, }; +/* vdpu382 link hw info */ +struct rkvdec_link_info rkvdec_link_vdpu383_hw_info = { + .ip_reset_base = 0x44, + .ip_reset_en = BIT(0), + .irq_base = 0x48, + .irq_mask = 0x30000, + .status_base = 0x4c, + .status_mask = 0x3ff0000, + .err_mask = 0x3fe, + .ip_reset_mask = 0x8000000, + .ip_time_base = 0x54, + .en_base = 0x40, +}; + static void rkvdec2_link_free_task(struct kref *ref); static void rkvdec2_link_timeout_proc(struct work_struct *work_s); static int rkvdec2_link_iommu_fault_handle(struct iommu_domain *iommu, @@ -562,13 +576,13 @@ int rkvdec2_link_procfs_init(struct mpp_dev *mpp) int rkvdec2_link_init(struct platform_device *pdev, struct rkvdec2_dev *dec) { - int ret; + int ret = 0; struct resource *res = NULL; struct rkvdec_link_dev *link_dec = NULL; struct device *dev = &pdev->dev; struct mpp_dev *mpp = &dec->mpp; struct mpp_dma_buffer *table; - int i; + u32 i; mpp_debug_enter(); @@ -595,6 +609,10 @@ int rkvdec2_link_init(struct platform_device *pdev, struct rkvdec2_dev *dec) } link_dec->task_capacity = mpp->task_capacity; + /* if capacity<2, then not to alloc table array */ + if (link_dec->task_capacity < 2) + goto out; + ret = rkvdec2_link_alloc_table(&dec->mpp, link_dec); if (ret) goto done; @@ -622,6 +640,7 @@ int rkvdec2_link_init(struct platform_device *pdev, struct rkvdec2_dev *dec) mpp->fault_handler = rkvdec2_link_iommu_fault_handle; +out: link_dec->mpp = mpp; link_dec->dev = dev; atomic_set(&link_dec->task_timeout, 0); @@ -1627,7 +1646,7 @@ static int rkvdec2_soft_ccu_enqueue(struct mpp_dev *mpp, struct mpp_task *mpp_ta /* set registers for hardware */ reg_en = mpp_task->hw_info->reg_en; for (i = 0; i < task->w_req_cnt; i++) { - int s, e; + u32 s, e; struct mpp_request *req = &task->w_reqs[i]; s = req->offset / sizeof(u32); @@ -1790,7 +1809,8 @@ void rkvdec2_soft_ccu_worker(struct kthread_work *work_s) int rkvdec2_ccu_alloc_table(struct rkvdec2_dev *dec, struct rkvdec_link_dev *link_dec) { - int ret, i; + int ret; + u32 i; struct mpp_dma_buffer *table; struct mpp_dev *mpp = &dec->mpp; @@ -1983,7 +2003,7 @@ static int rkvdec2_hard_ccu_dequeue(struct mpp_taskqueue *queue, static int rkvdec2_hard_ccu_reset(struct mpp_taskqueue *queue, struct rkvdec2_ccu *ccu) { - int i = 0; + u32 i = 0; mpp_debug_enter(); diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.h b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.h index 7a0c0a0a75e368d62b8ad6604db6fdb76c962097..9d20bc87da1ae60ba29e438b6f2a63c630edda60 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.h +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.h @@ -125,6 +125,18 @@ struct rkvdec_link_info { u32 tb_reg_cycle; bool hack_setup; struct rkvdec_link_status reg_status; + + /* register for vdpu383 later */ + u32 ip_reset_base; + u32 ip_reset_en; + u32 irq_base; + u32 irq_mask; + u32 status_base; + u32 status_mask; + u32 err_mask; + u32 ip_reset_mask; + u32 ip_time_base; + u32 en_base; }; struct rkvdec_link_dev { @@ -202,6 +214,7 @@ struct rkvdec2_ccu { extern struct rkvdec_link_info rkvdec_link_rk356x_hw_info; extern struct rkvdec_link_info rkvdec_link_v2_hw_info; extern struct rkvdec_link_info rkvdec_link_vdpu382_hw_info; +extern struct rkvdec_link_info rkvdec_link_vdpu383_hw_info; int rkvdec_link_dump(struct mpp_dev *mpp);