diff options
author | andy.hu <andy.hu@starfivetech.com> | 2023-12-14 14:24:46 +0300 |
---|---|---|
committer | andy.hu <andy.hu@starfivetech.com> | 2023-12-14 14:24:46 +0300 |
commit | 087fc371bc05df960e63cb53ce307e1ae11c8c70 (patch) | |
tree | f0d888a2c285c372c3b51c24eb8011927a9fa268 | |
parent | 4fa467ccad855e895724cb05ca8b65f19798e5e9 (diff) | |
parent | b19c9481d505aea3a3b91d48f6379f38972b58d0 (diff) | |
download | linux-087fc371bc05df960e63cb53ce307e1ae11c8c70.tar.xz |
Merge branch 'CR_6988_wave5_v4l2_Som.Qin' into 'jh7110-5.15.y-devel'
CR 6988 Media:Wave5:Fix decoder dma buffer unconsistency
See merge request sdk/linux!993
3 files changed, 30 insertions, 6 deletions
diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c index e97b3b022055..c9eda6136e95 100644 --- a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c +++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c @@ -6,6 +6,7 @@ */ #include "wave5-helper.h" +#include <soc/sifive/sifive_l2_cache.h> #define VPU_DEC_DEV_NAME "C&M Wave5 VPU decoder" #define VPU_DEC_DRV_NAME "wave5-dec" @@ -1104,15 +1105,10 @@ static void wave5_vpu_dec_buf_queue_dst(struct vb2_buffer *vb) { struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); struct vpu_instance *inst = vb2_get_drv_priv(vb->vb2_queue); + struct frame_buffer *frame_buf; int ret; vbuf->sequence = inst->queued_dst_buf_num++; - ret = wave5_vpu_dec_clr_disp_flag(inst, vb->index); - if (ret) { - dev_dbg(inst->dev->dev, - "%s: Clearing the display flag of buffer index: %u, fail: %d\n", - __func__, vb->index, ret); - } if (inst->state == VPU_INST_STATE_INIT_SEQ) { dma_addr_t buf_addr_y = 0, buf_addr_cb = 0, buf_addr_cr = 0; @@ -1152,6 +1148,17 @@ static void wave5_vpu_dec_buf_queue_dst(struct vb2_buffer *vb) dev_dbg(inst->dev->dev, "linear framebuf y 0x%llx cb 0x%llx cr 0x%llx\n",buf_addr_y, buf_addr_cb, buf_addr_cr); } + frame_buf = &inst->frame_buf[vb->index + inst->dst_buf_count]; + if (frame_buf->size < inst->dev->l2_cache_size) + sifive_l2_flush64_range(frame_buf->buf_y, frame_buf->size); + + ret = wave5_vpu_dec_clr_disp_flag(inst, vb->index); + if (ret) { + dev_dbg(inst->dev->dev, + "%s: Clearing the display flag of buffer index: %u, fail: %d\n", + __func__, vb->index, ret); + } + if (!vb2_is_streaming(vb->vb2_queue)) return; diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu.c b/drivers/media/platform/chips-media/wave5/wave5-vpu.c index e378817f57a8..9aee7e90a9ac 100644 --- a/drivers/media/platform/chips-media/wave5/wave5-vpu.c +++ b/drivers/media/platform/chips-media/wave5/wave5-vpu.c @@ -169,11 +169,17 @@ err_without_release: return ret; } +static const struct of_device_id sifive_l2_ids[] = { + { .compatible = "sifive,fu740-c000-ccache" }, + { /* end of table */ }, +}; + static int wave5_vpu_probe(struct platform_device *pdev) { int ret; struct vpu_device *dev; const struct wave5_match_data *match_data; + struct device_node *np; match_data = device_get_match_data(&pdev->dev); if (!match_data) { @@ -283,6 +289,16 @@ static int wave5_vpu_probe(struct platform_device *pdev) goto err_enc_unreg; } + np = of_find_matching_node(NULL, sifive_l2_ids); + if (!np) { + dev_err(&pdev->dev, "find cache node, fail\n"); + goto err_enc_unreg; + } + + ret = of_property_read_u32(np, "cache-size", &dev->l2_cache_size); + if (ret) + dev->l2_cache_size = 0x200000; + dev_dbg(&pdev->dev, "Added wave5 driver with caps: %s %s and product code: 0x%x\n", (match_data->flags & WAVE5_IS_ENC) ? "'ENCODE'" : "", (match_data->flags & WAVE5_IS_DEC) ? "'DECODE'" : "", diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpuapi.h b/drivers/media/platform/chips-media/wave5/wave5-vpuapi.h index 892eff216aea..10f20a283592 100644 --- a/drivers/media/platform/chips-media/wave5/wave5-vpuapi.h +++ b/drivers/media/platform/chips-media/wave5/wave5-vpuapi.h @@ -1023,6 +1023,7 @@ struct vpu_device { struct dma_vpu_buf sram_buf; void __iomem *vdb_register; u32 product_code; + u32 l2_cache_size; struct ida inst_ida; struct clk_bulk_data *clks; struct reset_control *resets; |