diff options
35 files changed, 314 insertions, 128 deletions
diff --git a/Documentation/devicetree/bindings/media/qcom,sc7280-venus.yaml b/Documentation/devicetree/bindings/media/qcom,sc7280-venus.yaml index 8f9b6433aeb8..10c334e6b3dc 100644 --- a/Documentation/devicetree/bindings/media/qcom,sc7280-venus.yaml +++ b/Documentation/devicetree/bindings/media/qcom,sc7280-venus.yaml @@ -43,6 +43,7 @@ properties: - const: vcodec_bus iommus: + minItems: 1 maxItems: 2 interconnects: diff --git a/Documentation/devicetree/bindings/media/rockchip,rk3568-vepu.yaml b/Documentation/devicetree/bindings/media/rockchip,rk3568-vepu.yaml index 9d90d8d0565a..947ad699cc5e 100644 --- a/Documentation/devicetree/bindings/media/rockchip,rk3568-vepu.yaml +++ b/Documentation/devicetree/bindings/media/rockchip,rk3568-vepu.yaml @@ -17,6 +17,7 @@ properties: compatible: enum: - rockchip,rk3568-vepu + - rockchip,rk3588-vepu121 reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/media/rockchip-vpu.yaml b/Documentation/devicetree/bindings/media/rockchip-vpu.yaml index c57e1f488895..719aeb2dc593 100644 --- a/Documentation/devicetree/bindings/media/rockchip-vpu.yaml +++ b/Documentation/devicetree/bindings/media/rockchip-vpu.yaml @@ -26,11 +26,16 @@ properties: - rockchip,rk3568-vpu - rockchip,rk3588-av1-vpu - items: - - const: rockchip,rk3188-vpu + - enum: + - rockchip,rk3128-vpu + - rockchip,rk3188-vpu - const: rockchip,rk3066-vpu - items: - const: rockchip,rk3228-vpu - const: rockchip,rk3399-vpu + - items: + - const: rockchip,rk3588-vpu121 + - const: rockchip,rk3568-vpu reg: maxItems: 1 diff --git a/Documentation/driver-api/media/mc-core.rst b/Documentation/driver-api/media/mc-core.rst index 2456950ce8ff..1d010bd7ec49 100644 --- a/Documentation/driver-api/media/mc-core.rst +++ b/Documentation/driver-api/media/mc-core.rst @@ -144,7 +144,8 @@ valid values are described at :c:func:`media_create_pad_link()` and Graph traversal ^^^^^^^^^^^^^^^ -The media framework provides APIs to iterate over entities in a graph. +The media framework provides APIs to traverse media graphs, locating connected +entities and links. To iterate over all entities belonging to a media device, drivers can use the media_device_for_each_entity macro, defined in @@ -159,31 +160,6 @@ the media_device_for_each_entity macro, defined in ... } -Drivers might also need to iterate over all entities in a graph that can be -reached only through enabled links starting at a given entity. The media -framework provides a depth-first graph traversal API for that purpose. - -.. note:: - - Graphs with cycles (whether directed or undirected) are **NOT** - supported by the graph traversal API. To prevent infinite loops, the graph - traversal code limits the maximum depth to ``MEDIA_ENTITY_ENUM_MAX_DEPTH``, - currently defined as 16. - -Drivers initiate a graph traversal by calling -:c:func:`media_graph_walk_start()` - -The graph structure, provided by the caller, is initialized to start graph -traversal at the given entity. - -Drivers can then retrieve the next entity by calling -:c:func:`media_graph_walk_next()` - -When the graph traversal is complete the function will return ``NULL``. - -Graph traversal can be interrupted at any moment. No cleanup function call -is required and the graph structure can be freed normally. - Helper functions can be used to find a link between two given pads, or a pad connected to another pad through an enabled link (:c:func:`media_entity_find_link()`, :c:func:`media_pad_remote_pad_first()`, @@ -276,6 +252,45 @@ Subsystems should facilitate link validation by providing subsystem specific helper functions to provide easy access for commonly needed information, and in the end provide a way to use driver-specific callbacks. +Pipeline traversal +^^^^^^^^^^^^^^^^^^ + +Once a pipeline has been constructed with :c:func:`media_pipeline_start()`, +drivers can iterate over entities or pads in the pipeline with the +:c:macro:´media_pipeline_for_each_entity` and +:c:macro:´media_pipeline_for_each_pad` macros. Iterating over pads is +straightforward: + +.. code-block:: c + + media_pipeline_pad_iter iter; + struct media_pad *pad; + + media_pipeline_for_each_pad(pipe, &iter, pad) { + /* 'pad' will point to each pad in turn */ + ... + } + +To iterate over entities, the iterator needs to be initialized and cleaned up +as an additional steps: + +.. code-block:: c + + media_pipeline_entity_iter iter; + struct media_entity *entity; + int ret; + + ret = media_pipeline_entity_iter_init(pipe, &iter); + if (ret) + ...; + + media_pipeline_for_each_entity(pipe, &iter, entity) { + /* 'entity' will point to each entity in turn */ + ... + } + + media_pipeline_entity_iter_cleanup(&iter); + Media Controller Device Allocator API ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst index e8d2d56d794f..0da635691fdc 100644 --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst @@ -2993,7 +2993,11 @@ This structure contains all loop filter related parameters. See sections - Applications and drivers must set this to zero. * - __u16 - ``max_frame_width_minus_1`` - - specifies the maximum frame width minus 1 for the frames represented by + - Specifies the maximum frame width minus 1 for the frames represented by + this sequence header. + * - __u16 + - ``max_frame_height_minus_1`` + - Specifies the maximum frame height minus 1 for the frames represented by this sequence header. .. _av1_sequence_flags: @@ -3374,7 +3378,7 @@ semantics" of :ref:`av1`. - ``uv_pri_strength[V4L2_AV1_CDEF_MAX]`` - Specifies the strength of the primary filter. * - __u8 - - ``uv_secondary_strength[V4L2_AV1_CDEF_MAX]`` + - ``uv_sec_strength[V4L2_AV1_CDEF_MAX]`` - Specifies the strength of the secondary filter. .. c:type:: v4l2_av1_segment_feature @@ -3490,7 +3494,7 @@ AV1 Loop filter params as defined in section 6.8.10 "Loop filter semantics" of .. tabularcolumns:: |p{1.5cm}|p{5.8cm}|p{10.0cm}| -.. flat-table:: struct v4l2_av1_global_motion +.. flat-table:: struct v4l2_av1_loop_filter :header-rows: 0 :stub-columns: 0 :widths: 1 1 2 @@ -3806,12 +3810,12 @@ AV1 Tx mode as described in section 6.8.21 "TX mode semantics" of :ref:`av1`. * - struct :c:type:`v4l2_av1_quantization` - ``quantization`` - Quantization parameters. - * - struct :c:type:`v4l2_av1_segmentation` - - ``segmentation`` - - Segmentation parameters. * - __u8 - ``superres_denom`` - The denominator for the upscaling ratio. + * - struct :c:type:`v4l2_av1_segmentation` + - ``segmentation`` + - Segmentation parameters. * - struct :c:type:`v4l2_av1_loop_filter` - ``loop_filter`` - Loop filter params @@ -3829,7 +3833,7 @@ AV1 Tx mode as described in section 6.8.21 "TX mode semantics" of :ref:`av1`. * - struct :c:type:`v4l2_av1_loop_restoration` - ``loop_restoration`` - Loop restoration parameters. - * - struct :c:type:`v4l2_av1_loop_global_motion` + * - struct :c:type:`v4l2_av1_global_motion` - ``global_motion`` - Global motion parameters. * - __u32 diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c index f4b481212356..d8735c246e52 100644 --- a/drivers/media/i2c/mt9p031.c +++ b/drivers/media/i2c/mt9p031.c @@ -15,6 +15,7 @@ #include <linux/gpio/consumer.h> #include <linux/i2c.h> #include <linux/log2.h> +#include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/of.h> #include <linux/of_graph.h> @@ -112,11 +113,6 @@ #define MT9P031_TEST_PATTERN_RED 0xa2 #define MT9P031_TEST_PATTERN_BLUE 0xa3 -enum mt9p031_model { - MT9P031_MODEL_COLOR, - MT9P031_MODEL_MONOCHROME, -}; - struct mt9p031 { struct v4l2_subdev subdev; struct media_pad pad; @@ -129,7 +125,7 @@ struct mt9p031 { struct clk *clk; struct regulator_bulk_data regulators[3]; - enum mt9p031_model model; + u32 code; struct aptina_pll pll; unsigned int clk_div; bool use_pll; @@ -712,12 +708,7 @@ static int mt9p031_init_state(struct v4l2_subdev *subdev, crop->height = MT9P031_WINDOW_HEIGHT_DEF; format = __mt9p031_get_pad_format(mt9p031, sd_state, 0, which); - - if (mt9p031->model == MT9P031_MODEL_MONOCHROME) - format->code = MEDIA_BUS_FMT_Y12_1X12; - else - format->code = MEDIA_BUS_FMT_SGRBG12_1X12; - + format->code = mt9p031->code; format->width = MT9P031_WINDOW_WIDTH_DEF; format->height = MT9P031_WINDOW_HEIGHT_DEF; format->field = V4L2_FIELD_NONE; @@ -1102,7 +1093,6 @@ done: static int mt9p031_probe(struct i2c_client *client) { - const struct i2c_device_id *did = i2c_client_get_device_id(client); struct mt9p031_platform_data *pdata = mt9p031_get_pdata(client); struct i2c_adapter *adapter = client->adapter; struct mt9p031 *mt9p031; @@ -1127,7 +1117,7 @@ static int mt9p031_probe(struct i2c_client *client) mt9p031->pdata = pdata; mt9p031->output_control = MT9P031_OUTPUT_CONTROL_DEF; mt9p031->mode2 = MT9P031_READ_MODE_2_ROW_BLC; - mt9p031->model = did->driver_data; + mt9p031->code = (uintptr_t)i2c_get_match_data(client); mt9p031->regulators[0].supply = "vdd"; mt9p031->regulators[1].supply = "vdd_io"; @@ -1224,26 +1214,24 @@ static void mt9p031_remove(struct i2c_client *client) } static const struct i2c_device_id mt9p031_id[] = { - { "mt9p006", MT9P031_MODEL_COLOR }, - { "mt9p031", MT9P031_MODEL_COLOR }, - { "mt9p031m", MT9P031_MODEL_MONOCHROME }, - { } + { "mt9p006", MEDIA_BUS_FMT_SGRBG12_1X12 }, + { "mt9p031", MEDIA_BUS_FMT_SGRBG12_1X12 }, + { "mt9p031m", MEDIA_BUS_FMT_Y12_1X12 }, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(i2c, mt9p031_id); -#if IS_ENABLED(CONFIG_OF) static const struct of_device_id mt9p031_of_match[] = { - { .compatible = "aptina,mt9p006", }, - { .compatible = "aptina,mt9p031", }, - { .compatible = "aptina,mt9p031m", }, - { /* sentinel */ }, + { .compatible = "aptina,mt9p006", .data = (void *)MEDIA_BUS_FMT_SGRBG12_1X12 }, + { .compatible = "aptina,mt9p031", .data = (void *)MEDIA_BUS_FMT_SGRBG12_1X12 }, + { .compatible = "aptina,mt9p031m", .data = (void *)MEDIA_BUS_FMT_Y12_1X12 }, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, mt9p031_of_match); -#endif static struct i2c_driver mt9p031_i2c_driver = { .driver = { - .of_match_table = of_match_ptr(mt9p031_of_match), + .of_match_table = mt9p031_of_match, .name = "mt9p031", }, .probe = mt9p031_probe, diff --git a/drivers/media/platform/chips-media/coda/coda-bit.c b/drivers/media/platform/chips-media/coda/coda-bit.c index ed47d5bd8d61..84ded154adfe 100644 --- a/drivers/media/platform/chips-media/coda/coda-bit.c +++ b/drivers/media/platform/chips-media/coda/coda-bit.c @@ -585,7 +585,7 @@ static int coda_alloc_context_buffers(struct coda_ctx *ctx, if (!ctx->slicebuf.vaddr && q_data->fourcc == V4L2_PIX_FMT_H264) { /* worst case slice size */ - size = (DIV_ROUND_UP(q_data->rect.width, 16) * + size = (unsigned long)(DIV_ROUND_UP(q_data->rect.width, 16) * DIV_ROUND_UP(q_data->rect.height, 16)) * 3200 / 8 + 512; ret = coda_alloc_context_buf(ctx, &ctx->slicebuf, size, "slicebuf"); diff --git a/drivers/media/platform/imagination/Kconfig b/drivers/media/platform/imagination/Kconfig index 7139ae22219b..a302c955483d 100644 --- a/drivers/media/platform/imagination/Kconfig +++ b/drivers/media/platform/imagination/Kconfig @@ -2,6 +2,7 @@ config VIDEO_E5010_JPEG_ENC tristate "Imagination E5010 JPEG Encoder Driver" depends on VIDEO_DEV + depends on ARCH_K3 || COMPILE_TEST select VIDEOBUF2_DMA_CONTIG select VIDEOBUF2_VMALLOC select V4L2_MEM2MEM_DEV diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateful.c index 11ca2c2fbaad..e62c1c18758b 100644 --- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateful.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateful.c @@ -595,7 +595,7 @@ static void mtk_init_vdec_params(struct mtk_vcodec_dec_ctx *ctx) } } -static struct vb2_ops mtk_vdec_frame_vb2_ops = { +static const struct vb2_ops mtk_vdec_frame_vb2_ops = { .queue_setup = vb2ops_vdec_queue_setup, .buf_prepare = vb2ops_vdec_buf_prepare, .wait_prepare = vb2_ops_wait_prepare, diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c index b903e39fee89..3307dc15fc1d 100644 --- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c @@ -854,7 +854,7 @@ static int vb2ops_vdec_out_buf_validate(struct vb2_buffer *vb) return 0; } -static struct vb2_ops mtk_vdec_request_vb2_ops = { +static const struct vb2_ops mtk_vdec_request_vb2_ops = { .queue_setup = vb2ops_vdec_queue_setup, .wait_prepare = vb2_ops_wait_prepare, .wait_finish = vb2_ops_wait_finish, diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_if.c index 73d5cef33b2a..1e1b32faac77 100644 --- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_if.c @@ -347,11 +347,16 @@ static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs, return vpu_dec_reset(vpu); fb = inst->ctx->dev->vdec_pdata->get_cap_buffer(inst->ctx); + if (!fb) { + mtk_vdec_err(inst->ctx, "fb buffer is NULL"); + return -ENOMEM; + } + src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer); dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer); - y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0; - c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0; + y_fb_dma = fb->base_y.dma_addr; + c_fb_dma = fb->base_c.dma_addr; mtk_vdec_debug(inst->ctx, "+ [%d] FB y_dma=%llx c_dma=%llx va=%p", inst->num_nalu, y_fb_dma, c_fb_dma, fb); diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c index 2d4611e7fa0b..1ed0ccec5665 100644 --- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c @@ -724,11 +724,16 @@ static int vdec_h264_slice_single_decode(void *h_vdec, struct mtk_vcodec_mem *bs return vpu_dec_reset(vpu); fb = inst->ctx->dev->vdec_pdata->get_cap_buffer(inst->ctx); + if (!fb) { + mtk_vdec_err(inst->ctx, "fb buffer is NULL"); + return -ENOMEM; + } + src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer); dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer); - y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0; - c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0; + y_fb_dma = fb->base_y.dma_addr; + c_fb_dma = fb->base_c.dma_addr; mtk_vdec_debug(inst->ctx, "[h264-dec] [%d] y_dma=%llx c_dma=%llx", inst->ctx->decoded_frame_cnt, y_fb_dma, c_fb_dma); diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c index e27e728f392e..232ef3bd246a 100644 --- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c @@ -334,14 +334,18 @@ static int vdec_vp8_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs, src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer); fb = inst->ctx->dev->vdec_pdata->get_cap_buffer(inst->ctx); - dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer); + if (!fb) { + mtk_vdec_err(inst->ctx, "fb buffer is NULL"); + return -ENOMEM; + } - y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0; + dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer); + y_fb_dma = fb->base_y.dma_addr; if (inst->ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1) c_fb_dma = y_fb_dma + inst->ctx->picinfo.buf_w * inst->ctx->picinfo.buf_h; else - c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0; + c_fb_dma = fb->base_c.dma_addr; inst->vsi->dec.bs_dma = (u64)bs->dma_addr; inst->vsi->dec.bs_sz = bs->size; diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c index 165c947a6703..84e95a46dfc9 100644 --- a/drivers/media/platform/qcom/venus/core.c +++ b/drivers/media/platform/qcom/venus/core.c @@ -430,6 +430,7 @@ static void venus_remove(struct platform_device *pdev) struct device *dev = core->dev; int ret; + cancel_delayed_work_sync(&core->work); ret = pm_runtime_get_sync(dev); WARN_ON(ret < 0); diff --git a/drivers/media/platform/qcom/venus/firmware.c b/drivers/media/platform/qcom/venus/firmware.c index fe7da2b30482..66a18830e66d 100644 --- a/drivers/media/platform/qcom/venus/firmware.c +++ b/drivers/media/platform/qcom/venus/firmware.c @@ -316,10 +316,10 @@ int venus_firmware_init(struct venus_core *core) core->fw.dev = &pdev->dev; - iommu_dom = iommu_domain_alloc(&platform_bus_type); - if (!iommu_dom) { + iommu_dom = iommu_paging_domain_alloc(core->fw.dev); + if (IS_ERR(iommu_dom)) { dev_err(core->fw.dev, "Failed to allocate iommu domain\n"); - ret = -ENOMEM; + ret = PTR_ERR(iommu_dom); goto err_unregister; } diff --git a/drivers/media/platform/qcom/venus/hfi_cmds.c b/drivers/media/platform/qcom/venus/hfi_cmds.c index 3418d2dd9371..3ae063094e3e 100644 --- a/drivers/media/platform/qcom/venus/hfi_cmds.c +++ b/drivers/media/platform/qcom/venus/hfi_cmds.c @@ -156,7 +156,7 @@ void pkt_sys_image_version(struct hfi_sys_get_property_pkt *pkt) pkt->hdr.size = sizeof(*pkt); pkt->hdr.pkt_type = HFI_CMD_SYS_GET_PROPERTY; pkt->num_properties = 1; - pkt->data[0] = HFI_PROPERTY_SYS_IMAGE_VERSION; + pkt->data = HFI_PROPERTY_SYS_IMAGE_VERSION; } int pkt_session_init(struct hfi_session_init_pkt *pkt, void *cookie, @@ -331,7 +331,7 @@ int pkt_session_ftb(struct hfi_session_fill_buffer_pkt *pkt, void *cookie, pkt->alloc_len = out_frame->alloc_len; pkt->filled_len = out_frame->filled_len; pkt->offset = out_frame->offset; - pkt->data[0] = out_frame->extradata_size; + pkt->data = out_frame->extradata_size; return 0; } @@ -402,7 +402,7 @@ static int pkt_session_get_property_1x(struct hfi_session_get_property_pkt *pkt, pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_GET_PROPERTY; pkt->shdr.session_id = hash32_ptr(cookie); pkt->num_properties = 1; - pkt->data[0] = ptype; + pkt->data = ptype; return 0; } @@ -1110,7 +1110,7 @@ pkt_session_get_property_3xx(struct hfi_session_get_property_pkt *pkt, switch (ptype) { case HFI_PROPERTY_CONFIG_VDEC_ENTROPY: - pkt->data[0] = HFI_PROPERTY_CONFIG_VDEC_ENTROPY; + pkt->data = HFI_PROPERTY_CONFIG_VDEC_ENTROPY; break; default: ret = pkt_session_get_property_1x(pkt, cookie, ptype); diff --git a/drivers/media/platform/qcom/venus/hfi_cmds.h b/drivers/media/platform/qcom/venus/hfi_cmds.h index 20acd412ee7b..c4d165a2d325 100644 --- a/drivers/media/platform/qcom/venus/hfi_cmds.h +++ b/drivers/media/platform/qcom/venus/hfi_cmds.h @@ -74,7 +74,7 @@ struct hfi_sys_set_property_pkt { struct hfi_sys_get_property_pkt { struct hfi_pkt_hdr hdr; u32 num_properties; - u32 data[1]; + u32 data; }; struct hfi_sys_set_buffers_pkt { @@ -82,7 +82,7 @@ struct hfi_sys_set_buffers_pkt { u32 buffer_type; u32 buffer_size; u32 num_buffers; - u32 buffer_addr[1]; + u32 buffer_addr[]; }; struct hfi_sys_ping_pkt { @@ -151,7 +151,7 @@ struct hfi_session_empty_buffer_compressed_pkt { u32 input_tag; u32 packet_buffer; u32 extradata_buffer; - u32 data[1]; + u32 data; }; struct hfi_session_empty_buffer_uncompressed_plane0_pkt { @@ -168,7 +168,7 @@ struct hfi_session_empty_buffer_uncompressed_plane0_pkt { u32 input_tag; u32 packet_buffer; u32 extradata_buffer; - u32 data[1]; + u32 data; }; struct hfi_session_empty_buffer_uncompressed_plane1_pkt { @@ -177,7 +177,7 @@ struct hfi_session_empty_buffer_uncompressed_plane1_pkt { u32 filled_len; u32 offset; u32 packet_buffer2; - u32 data[1]; + u32 data; }; struct hfi_session_empty_buffer_uncompressed_plane2_pkt { @@ -186,7 +186,7 @@ struct hfi_session_empty_buffer_uncompressed_plane2_pkt { u32 filled_len; u32 offset; u32 packet_buffer3; - u32 data[1]; + u32 data; }; struct hfi_session_fill_buffer_pkt { @@ -198,7 +198,7 @@ struct hfi_session_fill_buffer_pkt { u32 output_tag; u32 packet_buffer; u32 extradata_buffer; - u32 data[1]; + u32 data; }; struct hfi_session_flush_pkt { @@ -217,7 +217,7 @@ struct hfi_session_resume_pkt { struct hfi_session_get_property_pkt { struct hfi_session_hdr_pkt shdr; u32 num_properties; - u32 data[1]; + u32 data; }; struct hfi_session_release_buffer_pkt { diff --git a/drivers/media/platform/qcom/venus/hfi_helper.h b/drivers/media/platform/qcom/venus/hfi_helper.h index e4c05d62cfc7..f44059f19505 100644 --- a/drivers/media/platform/qcom/venus/hfi_helper.h +++ b/drivers/media/platform/qcom/venus/hfi_helper.h @@ -761,7 +761,7 @@ struct hfi_multi_stream_3x { struct hfi_multi_view_format { u32 views; - u32 view_order[1]; + u32 view_order[]; }; #define HFI_MULTI_SLICE_OFF 0x1 @@ -1005,13 +1005,13 @@ struct hfi_uncompressed_plane_constraints { struct hfi_uncompressed_plane_info { u32 format; u32 num_planes; - struct hfi_uncompressed_plane_constraints plane_constraints[1]; + struct hfi_uncompressed_plane_constraints plane_constraints; }; struct hfi_uncompressed_format_supported { u32 buffer_type; u32 format_entries; - struct hfi_uncompressed_plane_info plane_info[1]; + struct hfi_uncompressed_plane_info plane_info; }; struct hfi_uncompressed_plane_actual { @@ -1038,7 +1038,7 @@ struct hfi_codec_supported { struct hfi_properties_supported { u32 num_properties; - u32 properties[1]; + u32 properties[]; }; struct hfi_max_sessions_supported { @@ -1085,12 +1085,12 @@ struct hfi_resource_ocmem_requirement { struct hfi_resource_ocmem_requirement_info { u32 num_entries; - struct hfi_resource_ocmem_requirement requirements[1]; + struct hfi_resource_ocmem_requirement requirements[]; }; struct hfi_property_sys_image_version_info_type { u32 string_size; - u8 str_image_version[1]; + u8 str_image_version[]; }; struct hfi_codec_mask_supported { @@ -1141,7 +1141,7 @@ struct hfi_extradata_header { u32 port_index; u32 type; u32 data_size; - u8 data[1]; + u8 data[]; }; struct hfi_batch_info { @@ -1236,7 +1236,7 @@ static inline void hfi_bufreq_set_count_min_host(struct hfi_buffer_requirements struct hfi_data_payload { u32 size; - u8 data[1]; + u8 data[]; }; struct hfi_enable_picture { @@ -1264,12 +1264,12 @@ struct hfi_interlace_format_supported { struct hfi_buffer_alloc_mode_supported { u32 buffer_type; u32 num_entries; - u32 data[1]; + u32 data[]; }; struct hfi_mb_error_map { u32 error_map_size; - u8 error_map[1]; + u8 error_map[]; }; struct hfi_metadata_pass_through { diff --git a/drivers/media/platform/qcom/venus/hfi_parser.c b/drivers/media/platform/qcom/venus/hfi_parser.c index c43839539d4d..3df241dc3a11 100644 --- a/drivers/media/platform/qcom/venus/hfi_parser.c +++ b/drivers/media/platform/qcom/venus/hfi_parser.c @@ -157,7 +157,7 @@ static void parse_raw_formats(struct venus_core *core, u32 codecs, u32 domain, void *data) { struct hfi_uncompressed_format_supported *fmt = data; - struct hfi_uncompressed_plane_info *pinfo = fmt->plane_info; + struct hfi_uncompressed_plane_info *pinfo = &fmt->plane_info; struct hfi_uncompressed_plane_constraints *constr; struct raw_formats rawfmts[MAX_FMT_ENTRIES] = {}; u32 entries = fmt->format_entries; diff --git a/drivers/media/platform/qcom/venus/hfi_plat_bufs_v6.c b/drivers/media/platform/qcom/venus/hfi_plat_bufs_v6.c index f5a655973c08..6289166786ec 100644 --- a/drivers/media/platform/qcom/venus/hfi_plat_bufs_v6.c +++ b/drivers/media/platform/qcom/venus/hfi_plat_bufs_v6.c @@ -1063,51 +1063,51 @@ struct enc_bufsize_ops { u32 (*persist)(void); }; -static struct dec_bufsize_ops dec_h264_ops = { +static const struct dec_bufsize_ops dec_h264_ops = { .scratch = h264d_scratch_size, .scratch1 = h264d_scratch1_size, .persist1 = h264d_persist1_size, }; -static struct dec_bufsize_ops dec_h265_ops = { +static const struct dec_bufsize_ops dec_h265_ops = { .scratch = h265d_scratch_size, .scratch1 = h265d_scratch1_size, .persist1 = h265d_persist1_size, }; -static struct dec_bufsize_ops dec_vp8_ops = { +static const struct dec_bufsize_ops dec_vp8_ops = { .scratch = vpxd_scratch_size, .scratch1 = vp8d_scratch1_size, .persist1 = vp8d_persist1_size, }; -static struct dec_bufsize_ops dec_vp9_ops = { +static const struct dec_bufsize_ops dec_vp9_ops = { .scratch = vpxd_scratch_size, .scratch1 = vp9d_scratch1_size, .persist1 = vp9d_persist1_size, }; -static struct dec_bufsize_ops dec_mpeg2_ops = { +static const struct dec_bufsize_ops dec_mpeg2_ops = { .scratch = mpeg2d_scratch_size, .scratch1 = mpeg2d_scratch1_size, .persist1 = mpeg2d_persist1_size, }; -static struct enc_bufsize_ops enc_h264_ops = { +static const struct enc_bufsize_ops enc_h264_ops = { .scratch = h264e_scratch_size, .scratch1 = h264e_scratch1_size, .scratch2 = enc_scratch2_size, .persist = enc_persist_size, }; -static struct enc_bufsize_ops enc_h265_ops = { +static const struct enc_bufsize_ops enc_h265_ops = { .scratch = h265e_scratch_size, .scratch1 = h265e_scratch1_size, .scratch2 = enc_scratch2_size, .persist = enc_persist_size, }; -static struct enc_bufsize_ops enc_vp8_ops = { +static const struct enc_bufsize_ops enc_vp8_ops = { .scratch = vp8e_scratch_size, .scratch1 = vp8e_scratch1_size, .scratch2 = enc_scratch2_size, @@ -1186,7 +1186,7 @@ static int bufreq_dec(struct hfi_plat_buffers_params *params, u32 buftype, u32 codec = params->codec; u32 width = params->width, height = params->height, out_min_count; u32 out_width = params->out_width, out_height = params->out_height; - struct dec_bufsize_ops *dec_ops; + const struct dec_bufsize_ops *dec_ops; bool is_secondary_output = params->dec.is_secondary_output; bool is_interlaced = params->dec.is_interlaced; u32 max_mbs_per_frame = params->dec.max_mbs_per_frame; @@ -1260,7 +1260,7 @@ static int bufreq_enc(struct hfi_plat_buffers_params *params, u32 buftype, struct hfi_buffer_requirements *bufreq) { enum hfi_version version = params->version; - struct enc_bufsize_ops *enc_ops; + const struct enc_bufsize_ops *enc_ops; u32 width = params->width; u32 height = params->height; bool is_tenbit = params->enc.is_tenbit; diff --git a/drivers/media/platform/verisilicon/Kconfig b/drivers/media/platform/verisilicon/Kconfig index 149d0b32c324..3272a24db71d 100644 --- a/drivers/media/platform/verisilicon/Kconfig +++ b/drivers/media/platform/verisilicon/Kconfig @@ -21,6 +21,14 @@ config VIDEO_HANTRO To compile this driver as a module, choose M here: the module will be called hantro-vpu. +config VIDEO_HANTRO_HEVC_RFC + bool "Use reference frame compression for HEVC" + depends on VIDEO_HANTRO + default n + help + Enable the reference frame compression feature for the HEVC codec. + It will use more memory but save bandwidth on memory bus. + config VIDEO_HANTRO_IMX8M bool "Hantro VPU i.MX8M support" depends on VIDEO_HANTRO diff --git a/drivers/media/platform/verisilicon/Makefile b/drivers/media/platform/verisilicon/Makefile index eb38a1833b02..f6f019d04ff0 100644 --- a/drivers/media/platform/verisilicon/Makefile +++ b/drivers/media/platform/verisilicon/Makefile @@ -14,13 +14,6 @@ hantro-vpu-y += \ hantro_g2.o \ hantro_g2_hevc_dec.o \ hantro_g2_vp9_dec.o \ - rockchip_vpu2_hw_jpeg_enc.o \ - rockchip_vpu2_hw_h264_dec.o \ - rockchip_vpu2_hw_mpeg2_dec.o \ - rockchip_vpu2_hw_vp8_dec.o \ - rockchip_vpu981_hw_av1_dec.o \ - rockchip_av1_filmgrain.o \ - rockchip_av1_entropymode.o \ hantro_jpeg.o \ hantro_h264.o \ hantro_hevc.o \ @@ -35,6 +28,13 @@ hantro-vpu-$(CONFIG_VIDEO_HANTRO_SAMA5D4) += \ sama5d4_vdec_hw.o hantro-vpu-$(CONFIG_VIDEO_HANTRO_ROCKCHIP) += \ + rockchip_vpu2_hw_jpeg_enc.o \ + rockchip_vpu2_hw_h264_dec.o \ + rockchip_vpu2_hw_mpeg2_dec.o \ + rockchip_vpu2_hw_vp8_dec.o \ + rockchip_vpu981_hw_av1_dec.o \ + rockchip_av1_filmgrain.o \ + rockchip_av1_entropymode.o \ rockchip_vpu_hw.o hantro-vpu-$(CONFIG_VIDEO_HANTRO_SUNXI) += \ diff --git a/drivers/media/platform/verisilicon/hantro_drv.c b/drivers/media/platform/verisilicon/hantro_drv.c index 34b123dafd89..05bbac853c4f 100644 --- a/drivers/media/platform/verisilicon/hantro_drv.c +++ b/drivers/media/platform/verisilicon/hantro_drv.c @@ -722,6 +722,7 @@ static const struct of_device_id of_hantro_match[] = { { .compatible = "rockchip,rk3399-vpu", .data = &rk3399_vpu_variant, }, { .compatible = "rockchip,rk3568-vepu", .data = &rk3568_vepu_variant, }, { .compatible = "rockchip,rk3568-vpu", .data = &rk3568_vpu_variant, }, + { .compatible = "rockchip,rk3588-vepu121", .data = &rk3568_vepu_variant, }, { .compatible = "rockchip,rk3588-av1-vpu", .data = &rk3588_vpu981_variant, }, #endif #ifdef CONFIG_VIDEO_HANTRO_IMX8M @@ -992,6 +993,49 @@ static const struct media_device_ops hantro_m2m_media_ops = { .req_queue = v4l2_m2m_request_queue, }; +/* + * Some SoCs, like RK3588 have multiple identical Hantro cores, but the + * kernel is currently missing support for multi-core handling. Exposing + * separate devices for each core to userspace is bad, since that does + * not allow scheduling tasks properly (and creates ABI). With this workaround + * the driver will only probe for the first core and early exit for the other + * cores. Once the driver gains multi-core support, the same technique + * for detecting the main core can be used to cluster all cores together. + */ +static int hantro_disable_multicore(struct hantro_dev *vpu) +{ + struct device_node *node = NULL; + const char *compatible; + bool is_main_core; + int ret; + + /* Intentionally ignores the fallback strings */ + ret = of_property_read_string(vpu->dev->of_node, "compatible", &compatible); + if (ret) + return ret; + + /* The first compatible and available node found is considered the main core */ + do { + node = of_find_compatible_node(node, NULL, compatible); + if (of_device_is_available(node)) + break; + } while (node); + + if (!node) + return -EINVAL; + + is_main_core = (vpu->dev->of_node == node); + + of_node_put(node); + + if (!is_main_core) { + dev_info(vpu->dev, "missing multi-core support, ignoring this instance\n"); + return -ENODEV; + } + + return 0; +} + static int hantro_probe(struct platform_device *pdev) { const struct of_device_id *match; @@ -1011,6 +1055,10 @@ static int hantro_probe(struct platform_device *pdev) match = of_match_node(of_hantro_match, pdev->dev.of_node); vpu->variant = match->data; + ret = hantro_disable_multicore(vpu); + if (ret) + return ret; + /* * Support for nxp,imx8mq-vpu is kept for backwards compatibility * but it's deprecated. Please update your DTS file to use diff --git a/drivers/media/platform/verisilicon/hantro_g2.c b/drivers/media/platform/verisilicon/hantro_g2.c index b880a6849d58..5c1d799d8618 100644 --- a/drivers/media/platform/verisilicon/hantro_g2.c +++ b/drivers/media/platform/verisilicon/hantro_g2.c @@ -56,3 +56,32 @@ size_t hantro_g2_motion_vectors_offset(struct hantro_ctx *ctx) return ALIGN((cr_offset * 3) / 2, G2_ALIGN); } + +static size_t hantro_g2_mv_size(struct hantro_ctx *ctx) +{ + const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls; + const struct v4l2_ctrl_hevc_sps *sps = ctrls->sps; + unsigned int pic_width_in_ctbs, pic_height_in_ctbs; + unsigned int max_log2_ctb_size; + + max_log2_ctb_size = sps->log2_min_luma_coding_block_size_minus3 + 3 + + sps->log2_diff_max_min_luma_coding_block_size; + pic_width_in_ctbs = (sps->pic_width_in_luma_samples + + (1 << max_log2_ctb_size) - 1) >> max_log2_ctb_size; + pic_height_in_ctbs = (sps->pic_height_in_luma_samples + (1 << max_log2_ctb_size) - 1) + >> max_log2_ctb_size; + + return pic_width_in_ctbs * pic_height_in_ctbs * (1 << (2 * (max_log2_ctb_size - 4))) * 16; +} + +size_t hantro_g2_luma_compress_offset(struct hantro_ctx *ctx) +{ + return hantro_g2_motion_vectors_offset(ctx) + + hantro_g2_mv_size(ctx); +} + +size_t hantro_g2_chroma_compress_offset(struct hantro_ctx *ctx) +{ + return hantro_g2_luma_compress_offset(ctx) + + hantro_hevc_luma_compressed_size(ctx->dst_fmt.width, ctx->dst_fmt.height); +} diff --git a/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c b/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c index d3f8c33eb16c..85a44143b378 100644 --- a/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c +++ b/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c @@ -367,11 +367,14 @@ static int set_ref(struct hantro_ctx *ctx) const struct v4l2_ctrl_hevc_decode_params *decode_params = ctrls->decode_params; const struct v4l2_hevc_dpb_entry *dpb = decode_params->dpb; dma_addr_t luma_addr, chroma_addr, mv_addr = 0; + dma_addr_t compress_luma_addr, compress_chroma_addr = 0; struct hantro_dev *vpu = ctx->dev; struct vb2_v4l2_buffer *vb2_dst; struct hantro_decoded_buffer *dst; size_t cr_offset = hantro_g2_chroma_offset(ctx); size_t mv_offset = hantro_g2_motion_vectors_offset(ctx); + size_t compress_luma_offset = hantro_g2_luma_compress_offset(ctx); + size_t compress_chroma_offset = hantro_g2_chroma_compress_offset(ctx); u32 max_ref_frames; u16 dpb_longterm_e; static const struct hantro_reg cur_poc[] = { @@ -445,6 +448,8 @@ static int set_ref(struct hantro_ctx *ctx) chroma_addr = luma_addr + cr_offset; mv_addr = luma_addr + mv_offset; + compress_luma_addr = luma_addr + compress_luma_offset; + compress_chroma_addr = luma_addr + compress_chroma_offset; if (dpb[i].flags & V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE) dpb_longterm_e |= BIT(V4L2_HEVC_DPB_ENTRIES_NUM_MAX - 1 - i); @@ -452,6 +457,8 @@ static int set_ref(struct hantro_ctx *ctx) hantro_write_addr(vpu, G2_REF_LUMA_ADDR(i), luma_addr); hantro_write_addr(vpu, G2_REF_CHROMA_ADDR(i), chroma_addr); hantro_write_addr(vpu, G2_REF_MV_ADDR(i), mv_addr); + hantro_write_addr(vpu, G2_REF_COMP_LUMA_ADDR(i), compress_luma_addr); + hantro_write_addr(vpu, G2_REF_COMP_CHROMA_ADDR(i), compress_chroma_addr); } vb2_dst = hantro_get_dst_buf(ctx); @@ -465,19 +472,27 @@ static int set_ref(struct hantro_ctx *ctx) chroma_addr = luma_addr + cr_offset; mv_addr = luma_addr + mv_offset; + compress_luma_addr = luma_addr + compress_luma_offset; + compress_chroma_addr = luma_addr + compress_chroma_offset; hantro_write_addr(vpu, G2_REF_LUMA_ADDR(i), luma_addr); hantro_write_addr(vpu, G2_REF_CHROMA_ADDR(i), chroma_addr); - hantro_write_addr(vpu, G2_REF_MV_ADDR(i++), mv_addr); + hantro_write_addr(vpu, G2_REF_MV_ADDR(i), mv_addr); + hantro_write_addr(vpu, G2_REF_COMP_LUMA_ADDR(i), compress_luma_addr); + hantro_write_addr(vpu, G2_REF_COMP_CHROMA_ADDR(i++), compress_chroma_addr); hantro_write_addr(vpu, G2_OUT_LUMA_ADDR, luma_addr); hantro_write_addr(vpu, G2_OUT_CHROMA_ADDR, chroma_addr); hantro_write_addr(vpu, G2_OUT_MV_ADDR, mv_addr); + hantro_write_addr(vpu, G2_OUT_COMP_LUMA_ADDR, compress_luma_addr); + hantro_write_addr(vpu, G2_OUT_COMP_CHROMA_ADDR, compress_chroma_addr); for (; i < V4L2_HEVC_DPB_ENTRIES_NUM_MAX; i++) { hantro_write_addr(vpu, G2_REF_LUMA_ADDR(i), 0); hantro_write_addr(vpu, G2_REF_CHROMA_ADDR(i), 0); hantro_write_addr(vpu, G2_REF_MV_ADDR(i), 0); + hantro_write_addr(vpu, G2_REF_COMP_LUMA_ADDR(i), 0); + hantro_write_addr(vpu, G2_REF_COMP_CHROMA_ADDR(i), 0); } hantro_reg_write(vpu, &g2_refer_lterm_e, dpb_longterm_e); @@ -594,8 +609,7 @@ int hantro_g2_hevc_dec_run(struct hantro_ctx *ctx) /* Don't disable output */ hantro_reg_write(vpu, &g2_out_dis, 0); - /* Don't compress buffers */ - hantro_reg_write(vpu, &g2_ref_compress_bypass, 1); + hantro_reg_write(vpu, &g2_ref_compress_bypass, !ctx->hevc_dec.use_compression); /* Bus width and max burst */ hantro_reg_write(vpu, &g2_buswidth, BUS_WIDTH_128); diff --git a/drivers/media/platform/verisilicon/hantro_g2_regs.h b/drivers/media/platform/verisilicon/hantro_g2_regs.h index 82606783591a..b943b1816db7 100644 --- a/drivers/media/platform/verisilicon/hantro_g2_regs.h +++ b/drivers/media/platform/verisilicon/hantro_g2_regs.h @@ -318,6 +318,10 @@ #define G2_TILE_BSD_ADDR (G2_SWREG(183)) #define G2_DS_DST (G2_SWREG(186)) #define G2_DS_DST_CHR (G2_SWREG(188)) +#define G2_OUT_COMP_LUMA_ADDR (G2_SWREG(190)) +#define G2_REF_COMP_LUMA_ADDR(i) (G2_SWREG(192) + ((i) * 0x8)) +#define G2_OUT_COMP_CHROMA_ADDR (G2_SWREG(224)) +#define G2_REF_COMP_CHROMA_ADDR(i) (G2_SWREG(226) + ((i) * 0x8)) #define g2_strm_buffer_len G2_DEC_REG(258, 0, 0xffffffff) #define g2_strm_start_offset G2_DEC_REG(259, 0, 0xffffffff) diff --git a/drivers/media/platform/verisilicon/hantro_hevc.c b/drivers/media/platform/verisilicon/hantro_hevc.c index 2c14330bc562..83cd12b0ddd6 100644 --- a/drivers/media/platform/verisilicon/hantro_hevc.c +++ b/drivers/media/platform/verisilicon/hantro_hevc.c @@ -25,6 +25,11 @@ #define MAX_TILE_COLS 20 #define MAX_TILE_ROWS 22 +static bool hevc_use_compression = IS_ENABLED(CONFIG_VIDEO_HANTRO_HEVC_RFC); +module_param_named(hevc_use_compression, hevc_use_compression, bool, 0644); +MODULE_PARM_DESC(hevc_use_compression, + "Use reference frame compression for HEVC"); + void hantro_hevc_ref_init(struct hantro_ctx *ctx) { struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec; @@ -275,5 +280,8 @@ int hantro_hevc_dec_init(struct hantro_ctx *ctx) hantro_hevc_ref_init(ctx); + hevc_dec->use_compression = + hevc_use_compression & hantro_needs_postproc(ctx, ctx->vpu_dst_fmt); + return 0; } diff --git a/drivers/media/platform/verisilicon/hantro_hw.h b/drivers/media/platform/verisilicon/hantro_hw.h index 7737320cc8cc..c9b6556f8b2b 100644 --- a/drivers/media/platform/verisilicon/hantro_hw.h +++ b/drivers/media/platform/verisilicon/hantro_hw.h @@ -42,6 +42,13 @@ #define MAX_POSTPROC_BUFFERS 64 +#define CBS_SIZE 16 /* compression table size in bytes */ +#define CBS_LUMA 8 /* luminance CBS is composed of 1 8x8 coded block */ +#define CBS_CHROMA_W (8 * 2) /* chrominance CBS is composed of two 8x4 coded + * blocks, with Cb CB first then Cr CB following + */ +#define CBS_CHROMA_H 4 + struct hantro_dev; struct hantro_ctx; struct hantro_buf; @@ -144,6 +151,7 @@ struct hantro_hevc_dec_ctrls { * @ref_bufs_used: Bitfield of used reference buffers * @ctrls: V4L2 controls attached to a run * @num_tile_cols_allocated: number of allocated tiles + * @use_compression: use reference buffer compression */ struct hantro_hevc_dec_hw_ctx { struct hantro_aux_buf tile_sizes; @@ -156,6 +164,7 @@ struct hantro_hevc_dec_hw_ctx { u32 ref_bufs_used; struct hantro_hevc_dec_ctrls ctrls; unsigned int num_tile_cols_allocated; + bool use_compression; }; /** @@ -510,6 +519,33 @@ hantro_hevc_mv_size(unsigned int width, unsigned int height) return width * height / 16; } +static inline size_t +hantro_hevc_luma_compressed_size(unsigned int width, unsigned int height) +{ + u32 pic_width_in_cbsy = + round_up((width + CBS_LUMA - 1) / CBS_LUMA, CBS_SIZE); + u32 pic_height_in_cbsy = (height + CBS_LUMA - 1) / CBS_LUMA; + + return round_up(pic_width_in_cbsy * pic_height_in_cbsy, CBS_SIZE); +} + +static inline size_t +hantro_hevc_chroma_compressed_size(unsigned int width, unsigned int height) +{ + u32 pic_width_in_cbsc = + round_up((width + CBS_CHROMA_W - 1) / CBS_CHROMA_W, CBS_SIZE); + u32 pic_height_in_cbsc = (height / 2 + CBS_CHROMA_H - 1) / CBS_CHROMA_H; + + return round_up(pic_width_in_cbsc * pic_height_in_cbsc, CBS_SIZE); +} + +static inline size_t +hantro_hevc_compressed_size(unsigned int width, unsigned int height) +{ + return hantro_hevc_luma_compressed_size(width, height) + + hantro_hevc_chroma_compressed_size(width, height); +} + static inline unsigned short hantro_av1_num_sbs(unsigned short dimension) { return DIV_ROUND_UP(dimension, 64); @@ -525,6 +561,8 @@ hantro_av1_mv_size(unsigned int width, unsigned int height) size_t hantro_g2_chroma_offset(struct hantro_ctx *ctx); size_t hantro_g2_motion_vectors_offset(struct hantro_ctx *ctx); +size_t hantro_g2_luma_compress_offset(struct hantro_ctx *ctx); +size_t hantro_g2_chroma_compress_offset(struct hantro_ctx *ctx); int hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx); int rockchip_vpu2_mpeg2_dec_run(struct hantro_ctx *ctx); diff --git a/drivers/media/platform/verisilicon/hantro_postproc.c b/drivers/media/platform/verisilicon/hantro_postproc.c index 41e93176300b..232c93eea7ee 100644 --- a/drivers/media/platform/verisilicon/hantro_postproc.c +++ b/drivers/media/platform/verisilicon/hantro_postproc.c @@ -213,9 +213,13 @@ static unsigned int hantro_postproc_buffer_size(struct hantro_ctx *ctx) else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_VP9_FRAME) buf_size += hantro_vp9_mv_size(pix_mp.width, pix_mp.height); - else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_HEVC_SLICE) + else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_HEVC_SLICE) { buf_size += hantro_hevc_mv_size(pix_mp.width, pix_mp.height); + if (ctx->hevc_dec.use_compression) + buf_size += hantro_hevc_compressed_size(pix_mp.width, + pix_mp.height); + } else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_AV1_FRAME) buf_size += hantro_av1_mv_size(pix_mp.width, pix_mp.height); diff --git a/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c b/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c index cc4483857489..65e8f2d07400 100644 --- a/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c +++ b/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c @@ -257,7 +257,8 @@ static int rockchip_vpu981_av1_dec_tiles_reallocate(struct hantro_ctx *ctx) struct hantro_dev *vpu = ctx->dev; struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec; struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls; - unsigned int num_tile_cols = 1 << ctrls->tile_group_entry->tile_col; + const struct v4l2_av1_tile_info *tile_info = &ctrls->frame->tile_info; + unsigned int num_tile_cols = tile_info->tile_cols; unsigned int height = ALIGN(ctrls->frame->frame_height_minus_1 + 1, 64); unsigned int height_in_sb = height / 64; unsigned int stripe_num = ((height + 8) + 63) / 64; diff --git a/drivers/media/platform/verisilicon/rockchip_vpu981_regs.h b/drivers/media/platform/verisilicon/rockchip_vpu981_regs.h index 850ff0f84424..e4008da64f19 100644 --- a/drivers/media/platform/verisilicon/rockchip_vpu981_regs.h +++ b/drivers/media/platform/verisilicon/rockchip_vpu981_regs.h @@ -327,7 +327,7 @@ #define av1_apf_threshold AV1_DEC_REG(55, 0, 0xffff) #define av1_apf_single_pu_mode AV1_DEC_REG(55, 30, 0x1) -#define av1_apf_disable AV1_DEC_REG(55, 30, 0x1) +#define av1_apf_disable AV1_DEC_REG(55, 31, 0x1) #define av1_dec_max_burst AV1_DEC_REG(58, 0, 0xff) #define av1_dec_buswidth AV1_DEC_REG(58, 8, 0x7) @@ -337,10 +337,10 @@ #define av1_dec_mc_polltime AV1_DEC_REG(58, 17, 0x3ff) #define av1_dec_mc_pollmode AV1_DEC_REG(58, 27, 0x3) -#define av1_filt_ref_adj_3 AV1_DEC_REG(59, 0, 0x3f) -#define av1_filt_ref_adj_2 AV1_DEC_REG(59, 7, 0x3f) -#define av1_filt_ref_adj_1 AV1_DEC_REG(59, 14, 0x3f) -#define av1_filt_ref_adj_0 AV1_DEC_REG(59, 21, 0x3f) +#define av1_filt_ref_adj_3 AV1_DEC_REG(59, 0, 0x7f) +#define av1_filt_ref_adj_2 AV1_DEC_REG(59, 7, 0x7f) +#define av1_filt_ref_adj_1 AV1_DEC_REG(59, 14, 0x7f) +#define av1_filt_ref_adj_0 AV1_DEC_REG(59, 21, 0x7f) #define av1_ref0_sign_bias AV1_DEC_REG(59, 28, 0x1) #define av1_ref1_sign_bias AV1_DEC_REG(59, 29, 0x1) #define av1_ref2_sign_bias AV1_DEC_REG(59, 30, 0x1) diff --git a/drivers/media/platform/verisilicon/rockchip_vpu_hw.c b/drivers/media/platform/verisilicon/rockchip_vpu_hw.c index f97527670783..964122e7c355 100644 --- a/drivers/media/platform/verisilicon/rockchip_vpu_hw.c +++ b/drivers/media/platform/verisilicon/rockchip_vpu_hw.c @@ -82,7 +82,6 @@ static const struct hantro_fmt rockchip_vpu981_postproc_fmts[] = { { .fourcc = V4L2_PIX_FMT_NV12, .codec_mode = HANTRO_MODE_NONE, - .match_depth = true, .postprocessed = true, .frmsize = { .min_width = ROCKCHIP_VPU981_MIN_SIZE, diff --git a/drivers/media/test-drivers/vicodec/vicodec-core.c b/drivers/media/test-drivers/vicodec/vicodec-core.c index 3e011fe62ae1..846e90c06291 100644 --- a/drivers/media/test-drivers/vicodec/vicodec-core.c +++ b/drivers/media/test-drivers/vicodec/vicodec-core.c @@ -1215,8 +1215,7 @@ static int vicodec_encoder_cmd(struct file *file, void *fh, if (ret < 0) return ret; - if (!vb2_is_streaming(&ctx->fh.m2m_ctx->cap_q_ctx.q) || - !vb2_is_streaming(&ctx->fh.m2m_ctx->out_q_ctx.q)) + if (!vb2_is_streaming(&ctx->fh.m2m_ctx->out_q_ctx.q)) return 0; ret = v4l2_m2m_ioctl_encoder_cmd(file, fh, ec); @@ -1250,8 +1249,7 @@ static int vicodec_decoder_cmd(struct file *file, void *fh, if (ret < 0) return ret; - if (!vb2_is_streaming(&ctx->fh.m2m_ctx->cap_q_ctx.q) || - !vb2_is_streaming(&ctx->fh.m2m_ctx->out_q_ctx.q)) + if (!vb2_is_streaming(&ctx->fh.m2m_ctx->out_q_ctx.q)) return 0; ret = v4l2_m2m_ioctl_decoder_cmd(file, fh, dc); diff --git a/drivers/staging/media/starfive/camss/stf-capture.c b/drivers/staging/media/starfive/camss/stf-capture.c index ec5169e7b391..e15d2e97eb0b 100644 --- a/drivers/staging/media/starfive/camss/stf-capture.c +++ b/drivers/staging/media/starfive/camss/stf-capture.c @@ -180,6 +180,8 @@ static void stf_channel_set(struct stfcamss_video *video) u32 val; if (cap->type == STF_CAPTURE_RAW) { + const struct v4l2_pix_format *pix = &video->active_fmt.fmt.pix; + val = stf_syscon_reg_read(stfcamss, VIN_CHANNEL_SEL_EN); val &= ~U0_VIN_CHANNEL_SEL_MASK; val |= CHANNEL(0); @@ -193,7 +195,7 @@ static void stf_channel_set(struct stfcamss_video *video) val |= PIXEL_HEIGH_BIT_SEL(0); val &= ~U0_VIN_PIX_CNT_END_MASK; - val |= PIX_CNT_END(IMAGE_MAX_WIDTH / 4 - 1); + val |= PIX_CNT_END(pix->width / 4 - 1); stf_syscon_reg_write(stfcamss, VIN_INRT_PIX_CFG, val); } else if (cap->type == STF_CAPTURE_YUV) { diff --git a/include/media/v4l2-mc.h b/include/media/v4l2-mc.h index ed0a44b6eada..1837c9fd78cf 100644 --- a/include/media/v4l2-mc.h +++ b/include/media/v4l2-mc.h @@ -178,6 +178,9 @@ void v4l2_pipeline_pm_put(struct media_entity *entity); * @flags: New link flags that will be applied * @notification: The link's state change notification type (MEDIA_DEV_NOTIFY_*) * + * THIS FUNCTION IS DEPRECATED. DO NOT USE IN NEW DRIVERS. USE RUNTIME PM + * ON SUB-DEVICE DRIVERS INSTEAD. + * * React to link management on powered pipelines by updating the use count of * all entities in the source and sink sides of the link. Entities are powered * on or off accordingly. The use of this function should be paired |