diff --git a/drivers/media/platform/rockchip/rkvdec2/rkvdec2-vdpu383-h264.c b/drivers/media/platform/rockchip/rkvdec2/rkvdec2-vdpu383-h264.c index 8ce26f545c6c0b15d7eb6ceff5004ee49c7ac2df..b7e3c51ace961c53fd387e3efb771e830d13a63f 100644 --- a/drivers/media/platform/rockchip/rkvdec2/rkvdec2-vdpu383-h264.c +++ b/drivers/media/platform/rockchip/rkvdec2/rkvdec2-vdpu383-h264.c @@ -6,6 +6,7 @@ * Detlev Casanova <detlev.casanova@collabora.com> */ +#include "linux/dev_printk.h" #include <media/v4l2-h264.h> #include <media/v4l2-mem2mem.h> #include <media/v4l2-cabac/rkvdec-cabac.h> @@ -47,8 +48,6 @@ struct rkvdec2_sps { u16 num_views: 2; //0 1 u16 view_id0: 10; //0 u16 view_id1: 10; //0 - -// u16 reserved[11]; } __packed; // 96 bits struct rkvdec2_pps { @@ -75,20 +74,49 @@ struct rkvdec2_pps { // dpb u32 pic_field_flag: 1; // 88 (184) u32 pic_associated_flag: 1; // 89 (185) - u32 cur_top_field: 32; // 90 - 124 (186 - 218) // observed 192 - 224 - u32 cur_bot_field: 32; // 124 - 156 (218 - 250) - struct _field_order_count { - u32 top_field_order_cnt : 32; - u32 bot_field_order_cnt : 32; - } __packed field_order_count[16]; //1122 + u32 cur_top_field: 32; // 90 - 122 (186 - 218) + u32 cur_bot_field: 32; // 122 - 154 (218 - 250) + + u32 top_field_order_cnt0: 32; + u32 bot_field_order_cnt0: 32; + u32 top_field_order_cnt1: 32; + u32 bot_field_order_cnt1: 32; + u32 top_field_order_cnt2: 32; + u32 bot_field_order_cnt2: 32; + u32 top_field_order_cnt3: 32; + u32 bot_field_order_cnt3: 32; + u32 top_field_order_cnt4: 32; + u32 bot_field_order_cnt4: 32; + u32 top_field_order_cnt5: 32; + u32 bot_field_order_cnt5: 32; + u32 top_field_order_cnt6: 32; + u32 bot_field_order_cnt6: 32; + u32 top_field_order_cnt7: 32; + u32 bot_field_order_cnt7: 32; + u32 top_field_order_cnt8: 32; + u32 bot_field_order_cnt8: 32; + u32 top_field_order_cnt9: 32; + u32 bot_field_order_cnt9: 32; + u32 top_field_order_cnt10: 32; + u32 bot_field_order_cnt10: 32; + u32 top_field_order_cnt11: 32; + u32 bot_field_order_cnt11: 32; + u32 top_field_order_cnt12: 32; + u32 bot_field_order_cnt12: 32; + u32 top_field_order_cnt13: 32; + u32 bot_field_order_cnt13: 32; + u32 top_field_order_cnt14: 32; + u32 bot_field_order_cnt14: 32; + u32 top_field_order_cnt15: 32; + u32 bot_field_order_cnt15: 32; u32 ref_field_flags: 16; u32 ref_topfield_used: 16; u32 ref_botfield_used: 16; u32 ref_colmv_use_flag: 16; //1186 - u32 reserved: 30; - u32 reserved4: 32; + u32 : 30; + u32 reserved[3]; } __packed; struct rkvdec2_rps_entry { @@ -122,7 +150,7 @@ struct rkvdec2_rps { u16 frame_num[16]; u32 reserved0; struct rkvdec2_rps_entry entries[12]; - u32 reserved1[66]; + u32 reserved1[2]; } __packed; struct rkvdec2_sps_pps { @@ -158,9 +186,9 @@ struct rkvdec2_h264_ctx { struct rkvdec2_aux_buf priv_tbl; struct rkvdec2_h264_reflists reflists; struct vdpu383_regs_h264 regs; - //struct Vdpu383RegLlp llp; }; +/* static void dump_sps(struct rkvdec2_ctx *ctx, u32 *buf, size_t count) { for (int i = 0; i < count; i++) { @@ -174,7 +202,77 @@ static void dump_rps(struct rkvdec2_ctx *ctx, u32 *buf, size_t count) dev_warn(ctx->dev->dev, "RPS[%03d] %03x = 0x%08x\n", i, i*4, buf[i]); } } +*/ +static void set_field_order_cnt(struct rkvdec2_sps_pps *hw_ps, int id, u32 top, u32 bottom) +{ + switch (id) { + case 0: + hw_ps->pps.top_field_order_cnt0 = top; + hw_ps->pps.bot_field_order_cnt0 = bottom; + break; + case 1: + hw_ps->pps.top_field_order_cnt1 = top; + hw_ps->pps.bot_field_order_cnt1 = bottom; + break; + case 2: + hw_ps->pps.top_field_order_cnt2 = top; + hw_ps->pps.bot_field_order_cnt2 = bottom; + break; + case 3: + hw_ps->pps.top_field_order_cnt3 = top; + hw_ps->pps.bot_field_order_cnt3 = bottom; + break; + case 4: + hw_ps->pps.top_field_order_cnt4 = top; + hw_ps->pps.bot_field_order_cnt4 = bottom; + break; + case 5: + hw_ps->pps.top_field_order_cnt5 = top; + hw_ps->pps.bot_field_order_cnt5 = bottom; + break; + case 6: + hw_ps->pps.top_field_order_cnt6 = top; + hw_ps->pps.bot_field_order_cnt6 = bottom; + break; + case 7: + hw_ps->pps.top_field_order_cnt7 = top; + hw_ps->pps.bot_field_order_cnt7 = bottom; + break; + case 8: + hw_ps->pps.top_field_order_cnt8 = top; + hw_ps->pps.bot_field_order_cnt8 = bottom; + break; + case 9: + hw_ps->pps.top_field_order_cnt9 = top; + hw_ps->pps.bot_field_order_cnt9 = bottom; + break; + case 10: + hw_ps->pps.top_field_order_cnt10 = top; + hw_ps->pps.bot_field_order_cnt10 = bottom; + break; + case 11: + hw_ps->pps.top_field_order_cnt11 = top; + hw_ps->pps.bot_field_order_cnt11 = bottom; + break; + case 12: + hw_ps->pps.top_field_order_cnt12 = top; + hw_ps->pps.bot_field_order_cnt12 = bottom; + break; + case 13: + hw_ps->pps.top_field_order_cnt13 = top; + hw_ps->pps.bot_field_order_cnt13 = bottom; + break; + case 14: + hw_ps->pps.top_field_order_cnt14 = top; + hw_ps->pps.bot_field_order_cnt14 = bottom; + break; + case 15: + hw_ps->pps.top_field_order_cnt15 = top; + hw_ps->pps.bot_field_order_cnt15 = bottom; + break; + } +} static void assemble_hw_pps(struct rkvdec2_ctx *ctx, struct rkvdec2_h264_run *run) @@ -186,8 +284,6 @@ static void assemble_hw_pps(struct rkvdec2_ctx *ctx, const struct v4l2_h264_dpb_entry *dpb = dec_params->dpb; struct rkvdec2_h264_priv_tbl *priv_tbl = h264_ctx->priv_tbl.cpu; struct rkvdec2_sps_pps *hw_ps; - dma_addr_t scaling_list_address; - u32 scaling_distance; u32 i; /* @@ -274,9 +370,7 @@ static void assemble_hw_pps(struct rkvdec2_ctx *ctx, for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) { if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM) hw_ps->pps.is_longterm |= (1 << i); - //voidx = (pp->RefFrameList[i].bPicEntry != 0xff) ? pp->RefPicLayerIdList[i] : 0; - hw_ps->pps.field_order_count[i].top_field_order_cnt = dpb[i].top_field_order_cnt; - hw_ps->pps.field_order_count[i].bot_field_order_cnt = dpb[i].bottom_field_order_cnt; + set_field_order_cnt(hw_ps, i, dpb[i].top_field_order_cnt, dpb[i].bottom_field_order_cnt); hw_ps->pps.ref_field_flags |= (!!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_FIELD)) << i; hw_ps->pps.ref_colmv_use_flag |= @@ -286,11 +380,15 @@ static void assemble_hw_pps(struct rkvdec2_ctx *ctx, hw_ps->pps.ref_botfield_used |= (!!(dpb[i].fields & V4L2_H264_BOTTOM_FIELD_REF)) << i; } + hw_ps->pps.pic_field_flag = !!(dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC); hw_ps->pps.pic_associated_flag = !!(dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD); + // MPP only seems to set this when hw_ps->pps.pic_associated_flag is one. + // It doesn't seem to be needed, so I don't do it here and reg values are not identical + // with mpp. hw_ps->pps.cur_top_field = dec_params->top_field_order_cnt; hw_ps->pps.cur_bot_field = dec_params->bottom_field_order_cnt; @@ -450,9 +548,9 @@ static void assemble_hw_scaling_list(struct rkvdec2_ctx *ctx, static void dump_regs(struct rkvdec2_ctx *ctx, u32 *buf, size_t count, u32 offset) { - for (int i = 0; i < count; i++) { - dev_warn(ctx->dev->dev, "reg[%03d] %03x = 0x%08x\n", i + offset/4, offset + i*4, buf[i]); - } + //for (int i = 0; i < count; i++) { + // dev_warn(ctx->dev->dev, "reg[%03d] %03x = 0x%08x\n", i + offset/4, offset + i*4, buf[i]); + //} } @@ -473,19 +571,19 @@ static void rkvdec2_write_regs(struct rkvdec2_ctx *ctx) rkvdec2_memcpy_toio(rkvdec->regs + VDPU383_OFFSET_COMMON_REGS, &h264_ctx->regs.common, sizeof(h264_ctx->regs.common)); -// dump_regs(ctx, (u32*)&h264_ctx->regs.common, sizeof(h264_ctx->regs.common)/4, VDPU383_OFFSET_COMMON_REGS); + dump_regs(ctx, (u32*)&h264_ctx->regs.common, sizeof(h264_ctx->regs.common)/4, VDPU383_OFFSET_COMMON_REGS); rkvdec2_memcpy_toio(rkvdec->regs + VDPU383_OFFSET_COMMON_ADDR_REGS, &h264_ctx->regs.common_addr, sizeof(h264_ctx->regs.common_addr)); -// dump_regs(ctx, (u32*)&h264_ctx->regs.common_addr, sizeof(h264_ctx->regs.common_addr)/4, VDPU383_OFFSET_COMMON_ADDR_REGS); + dump_regs(ctx, (u32*)&h264_ctx->regs.common_addr, sizeof(h264_ctx->regs.common_addr)/4, VDPU383_OFFSET_COMMON_ADDR_REGS); rkvdec2_memcpy_toio(rkvdec->regs + VDPU383_OFFSET_CODEC_PARAMS_REGS, &h264_ctx->regs.h264_param, sizeof(h264_ctx->regs.h264_param)); -// dump_regs(ctx, (u32*)&h264_ctx->regs.h264_param, sizeof(h264_ctx->regs.h264_param)/4, VDPU383_OFFSET_CODEC_PARAMS_REGS); + dump_regs(ctx, (u32*)&h264_ctx->regs.h264_param, sizeof(h264_ctx->regs.h264_param)/4, VDPU383_OFFSET_CODEC_PARAMS_REGS); rkvdec2_memcpy_toio(rkvdec->regs + VDPU383_OFFSET_CODEC_ADDR_REGS, &h264_ctx->regs.h264_addr, sizeof(h264_ctx->regs.h264_addr)); -// dump_regs(ctx, (u32*)&h264_ctx->regs.h264_addr, sizeof(h264_ctx->regs.h264_addr)/4, VDPU383_OFFSET_CODEC_ADDR_REGS); + dump_regs(ctx, (u32*)&h264_ctx->regs.h264_addr, sizeof(h264_ctx->regs.h264_addr)/4, VDPU383_OFFSET_CODEC_ADDR_REGS); // rkvdec2_memcpy_toio(rkvdec->regs + VDPU383_OFFSET_POC_HIGHBIT_REGS, // &h264_ctx->regs.h264_highpoc, // sizeof(h264_ctx->regs.h264_highpoc)); @@ -556,10 +654,6 @@ static void config_registers(struct rkvdec2_ctx *ctx, regs->common.reg16.error_proc_disable = 1; - /* Set TOP and BOTTOM POCs */ - //regs->h264_param.cur_top_poc = dec_params->top_field_order_cnt; - //regs->h264_param.cur_bot_poc = dec_params->bottom_field_order_cnt; - /* Set ref pic address & poc */ for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) { struct vb2_buffer *vb_buf = run->ref_buf[i]; @@ -580,26 +674,6 @@ static void config_registers(struct rkvdec2_ctx *ctx, /* Set COLMV addresses */ regs->h264_addr.reg217_232_colmv_ref_base[i] = buf_dma + ctx->colmv_offset; - -/* - * TODO !!!!! - struct rkvdec2_h264_ref_info *ref_info = - ®s->h264_param.ref_info_regs[i / 4].ref_info[i % 4]; - - ref_info->ref_field = - !!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_FIELD); - ref_info->ref_colmv_use_flag = - !!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE); - ref_info->ref_topfield_used = - !!(dpb[i].fields & V4L2_H264_TOP_FIELD_REF); - ref_info->ref_botfield_used = - !!(dpb[i].fields & V4L2_H264_BOTTOM_FIELD_REF); - - regs->h264_param.ref_pocs[i * 2] = - dpb[i].top_field_order_cnt; - regs->h264_param.ref_pocs[i * 2 + 1] = - dpb[i].bottom_field_order_cnt; -*/ } /* Set rlc base address (input stream) */ @@ -624,7 +698,6 @@ static void config_registers(struct rkvdec2_ctx *ctx, /* Set hw pps address */ offset = offsetof(struct rkvdec2_h264_priv_tbl, param_set); regs->common_addr.reg131_gbl_base = priv_start_addr + offset; - //dev_warn(ctx->dev->dev, "sizeof(struct rkvdec2_sps_pps) = %lu (%lu)\n", sizeof(struct rkvdec2_sps_pps), sizeof(struct rkvdec2_sps_pps) / 16); regs->h264_param.reg67_global_len = sizeof(struct rkvdec2_sps_pps) / 16; /* Set hw rps address */ @@ -635,9 +708,6 @@ static void config_registers(struct rkvdec2_ctx *ctx, offset = offsetof(struct rkvdec2_h264_priv_tbl, cabac_table); regs->common_addr.reg130_cabactbl_base = priv_start_addr + offset; - //offset = offsetof(struct rkvdec2_h264_priv_tbl, scaling_list); - //regs->common_addr.reg132_scanlist_addr = priv_start_addr + offset; - rkvdec2_write_regs(ctx); } @@ -713,41 +783,6 @@ static int rkvdec2_h264_validate_sps(struct rkvdec2_ctx *ctx, return 0; } -static void vdpu383_reset(struct rkvdec2_dev *rkvdec) -{ - int ret; - u32 irq_status = 0; - - /* disable irq */ - dev_warn(rkvdec->dev, "HERE %s:%d\n", __func__, __LINE__); - writel(0, rkvdec->link + 0x58); - /* use ip reset to reset core and mmu */ - dev_warn(rkvdec->dev, "HERE %s:%d\n", __func__, __LINE__); - writel(1, rkvdec->link + 0x44); - dev_warn(rkvdec->dev, "HERE %s:%d\n", __func__, __LINE__); - ret = readl_relaxed_poll_timeout(rkvdec->link + 0x4c, - irq_status, - irq_status & 0x800, - 0, 200); - if (ret) - dev_err(rkvdec->dev, "reset timeout\n"); - - /* clear reset ready status bit */ - dev_warn(rkvdec->dev, "HERE %s:%d\n", __func__, __LINE__); - writel(0x08000000, rkvdec->link + 0x4c); - - /* clear irq and status */ - dev_warn(rkvdec->dev, "HERE %s:%d\n", __func__, __LINE__); - writel_relaxed(0xffff0000, rkvdec->link + 0x48); - dev_warn(rkvdec->dev, "HERE %s:%d\n", __func__, __LINE__); - writel_relaxed(0xffff0000, rkvdec->link + 0x4c); - - /* enable irq */ - dev_warn(rkvdec->dev, "HERE %s:%d\n", __func__, __LINE__); - writel(0x01000000, rkvdec->link + 0x58); - -} - static int rkvdec2_h264_start(struct rkvdec2_ctx *ctx) { struct rkvdec2_dev *rkvdec = ctx->dev; @@ -783,8 +818,6 @@ static int rkvdec2_h264_start(struct rkvdec2_ctx *ctx) ctx->priv = h264_ctx; - //vdpu383_reset(rkvdec); - return 0; err_free_ctx: @@ -861,13 +894,7 @@ static int rkvdec2_h264_run(struct rkvdec2_ctx *ctx) msecs_to_jiffies(watchdog_time)); - //__ioread32_copy(&h264_ctx->llp, rkvdec->link, sizeof(h264_ctx->llp)/4); - //dev_err(rkvdec->dev, "LINK REGS:\n"); - //dump_regs(ctx, (u32*)&h264_ctx->llp, sizeof(h264_ctx->llp)/4, 0); - - /* Start decoding! */ - //writel(VDPU383_DEC_E_BIT, rkvdec->regs + VDPU383_REG_DEC_E); writel(0x007fffff, rkvdec->link + 0x54); writel(0x00000000, rkvdec->link + 0x58); writel(0x00000001, rkvdec->link + 0x40);