diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2.c b/drivers/video/rockchip/mpp/mpp_rkvdec2.c index 354f277fb6a2..53fd57c6c519 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2.c @@ -47,6 +47,15 @@ static struct mpp_hw_info rkvdec_rk356x_hw_info = { .link_info = &rkvdec_link_rk356x_hw_info, }; +static struct mpp_hw_info rkvdec_vdpu382_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, + .link_info = &rkvdec_link_vdpu382_hw_info, +}; + /* * file handle translate information */ @@ -1224,6 +1233,14 @@ static const struct mpp_dev_var rkvdec_rk3568_data = { .dev_ops = &rkvdec_rk3568_dev_ops, }; +static const struct mpp_dev_var rkvdec_vdpu382_data = { + .device_type = MPP_DEVICE_RKVDEC, + .hw_info = &rkvdec_vdpu382_hw_info, + .trans_info = rkvdec_v2_trans, + .hw_ops = &rkvdec_v2_hw_ops, + .dev_ops = &rkvdec_v2_dev_ops, +}; + static const struct of_device_id mpp_rkvdec2_dt_match[] = { { .compatible = "rockchip,rkv-decoder-v2", @@ -1239,6 +1256,12 @@ static const struct of_device_id mpp_rkvdec2_dt_match[] = { { .compatible = "rockchip,rkv-decoder-v2-ccu", }, +#endif +#ifdef CONFIG_CPU_RK3528 + { + .compatible = "rockchip,rkv-decoder-rk3528", + .data = &rkvdec_vdpu382_data, + }, #endif {}, }; diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c index b722b2c794e0..8041b7ae7524 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.c @@ -73,6 +73,11 @@ struct rkvdec_link_info rkvdec_link_v2_hw_info = { .tb_reg_int = 180, .tb_reg_cycle = 195, .hack_setup = 0, + .reg_status = { + .dec_num_mask = 0x3fffffff, + .err_flag_base = 0x010, + .err_flag_bit = BIT(31), + }, }; /* vdpu34x link hw info for rk356x */ @@ -127,6 +132,69 @@ struct rkvdec_link_info rkvdec_link_rk356x_hw_info = { .tb_reg_int = 164, .tb_reg_cycle = 179, .hack_setup = 1, + .reg_status = { + .dec_num_mask = 0x3fffffff, + .err_flag_base = 0x010, + .err_flag_bit = BIT(31), + }, +}; + +/* vdpu382 link hw info */ +struct rkvdec_link_info rkvdec_link_vdpu382_hw_info = { + .tb_reg_num = 218, + .tb_reg_next = 0, + .tb_reg_r = 1, + .tb_reg_second_en = 8, + + .part_w_num = 6, + .part_r_num = 2, + .part_w[0] = { + .tb_reg_off = 4, + .reg_start = 8, + .reg_num = 28, + }, + .part_w[1] = { + .tb_reg_off = 32, + .reg_start = 64, + .reg_num = 52, + }, + .part_w[2] = { + .tb_reg_off = 84, + .reg_start = 128, + .reg_num = 16, + }, + .part_w[3] = { + .tb_reg_off = 100, + .reg_start = 160, + .reg_num = 48, + }, + .part_w[4] = { + .tb_reg_off = 148, + .reg_start = 224, + .reg_num = 16, + }, + .part_w[5] = { + .tb_reg_off = 164, + .reg_start = 256, + .reg_num = 16, + }, + .part_r[0] = { + .tb_reg_off = 180, + .reg_start = 224, + .reg_num = 10, + }, + .part_r[1] = { + .tb_reg_off = 190, + .reg_start = 258, + .reg_num = 28, + }, + .tb_reg_int = 180, + .hack_setup = 0, + .reg_status = { + .dec_num_mask = 0x000fffff, + .err_flag_base = 0x024, + .err_flag_bit = BIT(8), + }, }; static void rkvdec2_link_free_task(struct kref *ref); @@ -138,9 +206,12 @@ static void rkvdec_link_status_update(struct rkvdec_link_dev *dev) u32 enable_ff0, enable_ff1; u32 loop_count = 10; u32 val; + struct rkvdec_link_info *link_info = dev->info; + u32 dec_num_mask = link_info->reg_status.dec_num_mask; + u32 err_flag_base = link_info->reg_status.err_flag_base; + u32 err_flag_bit = link_info->reg_status.err_flag_bit; - error_ff1 = (readl(reg_base + RKVDEC_LINK_DEC_NUM_BASE) & - RKVDEC_LINK_BIT_DEC_ERROR) ? 1 : 0; + error_ff1 = (readl(reg_base + err_flag_base) & err_flag_bit) ? 1 : 0; enable_ff1 = readl(reg_base + RKVDEC_LINK_EN_BASE); dev->irq_status = readl(reg_base + RKVDEC_LINK_IRQ_BASE); @@ -151,7 +222,7 @@ static void rkvdec_link_status_update(struct rkvdec_link_dev *dev) do { val = readl(reg_base + RKVDEC_LINK_DEC_NUM_BASE); - error_ff0 = (val & RKVDEC_LINK_BIT_DEC_ERROR) ? 1 : 0; + error_ff0 = (readl(reg_base + err_flag_base) & err_flag_bit) ? 1 : 0; enable_ff0 = readl(reg_base + RKVDEC_LINK_EN_BASE); if (error_ff0 == error_ff1 && enable_ff0 == enable_ff1) @@ -163,7 +234,7 @@ static void rkvdec_link_status_update(struct rkvdec_link_dev *dev) dev->error = error_ff0; dev->decoded_status = val; - dev->decoded = RKVDEC_LINK_GET_DEC_NUM(val); + dev->decoded = val & dec_num_mask; dev->enabled = enable_ff0; if (!loop_count) @@ -755,6 +826,7 @@ static int rkvdec2_link_isr(struct mpp_dev *mpp) { struct rkvdec2_dev *dec = to_rkvdec2_dev(mpp); struct rkvdec_link_dev *link_dec = dec->link_dec; + struct rkvdec_link_info *link_info = link_dec->info; /* keep irq_status */ u32 irq_status = link_dec->irq_status; u32 prev_dec_num; @@ -777,7 +849,8 @@ static int rkvdec2_link_isr(struct mpp_dev *mpp) rkvdec_link_reg_dump("timeout", link_dec); val = mpp_read(mpp, 224 * 4); - if (link_dec->info->hack_setup && !(val & BIT(2))) { + if (link_info->hack_setup && !(val & BIT(2))) { + /* only for rk356x */ dev_info(mpp->dev, "frame not complete\n"); link_dec->decoded++; } diff --git a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.h b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.h index b2e20015a630..270cd46a71e7 100644 --- a/drivers/video/rockchip/mpp/mpp_rkvdec2_link.h +++ b/drivers/video/rockchip/mpp/mpp_rkvdec2_link.h @@ -41,8 +41,6 @@ #define RKVDEC_LINK_BIT_CFG_DONE BIT(0) #define RKVDEC_LINK_DEC_NUM_BASE 0x010 -#define RKVDEC_LINK_BIT_DEC_ERROR BIT(31) -#define RKVDEC_LINK_GET_DEC_NUM(x) ((x) & 0x3fffffff) #define RKVDEC_LINK_TOTAL_NUM_BASE 0x014 @@ -51,6 +49,8 @@ #define RKVDEC_LINK_NEXT_ADDR_BASE 0x01c +#define RKVDEC_LINK_STA_BASE 0x024 + #define RKVDEC_LINK_REG_CYCLE_CNT 179 /* define for ccu link hardware */ @@ -94,6 +94,12 @@ struct rkvdec_link_part { u32 reg_num; }; +struct rkvdec_link_status { + u32 dec_num_mask; + u32 err_flag_base; + u32 err_flag_bit; +}; + struct rkvdec_link_info { dma_addr_t iova; /* total register for link table buffer */ @@ -114,6 +120,7 @@ struct rkvdec_link_info { u32 tb_reg_int; u32 tb_reg_cycle; bool hack_setup; + struct rkvdec_link_status reg_status; }; struct rkvdec_link_dev { @@ -189,6 +196,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; int rkvdec_link_dump(struct mpp_dev *mpp);