Re: [PATCH] media: venus: Add support for H265 controls required by gstreamer V4L2 H265 module

2018-12-07 Thread Stanimir Varbanov
Hi Kelvin,

Thanks for the patch!

On 11/30/18 7:31 PM, Kelvin Lawson wrote:
> Add support for V4L2_CID_MPEG_VIDEO_HEVC_PROFILE and
> V4L2_CID_MPEG_VIDEO_HEVC_LEVEL controls required by gstreamer V4L2 H265
> encoder module.
> 
> Signed-off-by: Kelvin Lawson 
> ---
>  drivers/media/platform/qcom/venus/venc_ctrls.c | 19 +++
>  1 file changed, 19 insertions(+)
> 
> diff --git a/drivers/media/platform/qcom/venus/venc_ctrls.c 
> b/drivers/media/platform/qcom/venus/venc_ctrls.c
> index 45910172..ad1a4d8 100644
> --- a/drivers/media/platform/qcom/venus/venc_ctrls.c
> +++ b/drivers/media/platform/qcom/venus/venc_ctrls.c
> @@ -101,6 +101,9 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
>   case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
>   ctr->profile.h264 = ctrl->val;
>   break;
> + case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE:
> + ctr->profile.hevc = ctrl->val;
> + break;
>   case V4L2_CID_MPEG_VIDEO_VP8_PROFILE:
>   ctr->profile.vpx = ctrl->val;
>   break;
> @@ -110,6 +113,9 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
>   case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
>   ctr->level.h264 = ctrl->val;
>   break;
> + case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL:
> + ctr->level.hevc = ctrl->val;
> + break;
>   case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
>   ctr->h264_i_qp = ctrl->val;
>   break;
> @@ -217,6 +223,19 @@ int venc_ctrl_init(struct venus_inst *inst)
>   0, V4L2_MPEG_VIDEO_MPEG4_LEVEL_0);
>  
>   v4l2_ctrl_new_std_menu(>ctrl_handler, _ctrl_ops,
> + V4L2_CID_MPEG_VIDEO_HEVC_PROFILE,
> + V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10,
> + ~((1 << V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN) |
> +   (1 << V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE) |
> +   (1 << V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10)),
> + V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN);
> +
> + v4l2_ctrl_new_std_menu(>ctrl_handler, _ctrl_ops,
> + V4L2_CID_MPEG_VIDEO_HEVC_LEVEL,
> + V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2,
> + 0, V4L2_MPEG_VIDEO_HEVC_LEVEL_1);
> +
> + v4l2_ctrl_new_std_menu(>ctrl_handler, _ctrl_ops,

you are adding two new menu controls but forgot to increment the count
of controls in v4l2_ctrl_handler_init(). Can you resend with that fixed?

>   V4L2_CID_MPEG_VIDEO_H264_PROFILE,
>   V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH,
>   ~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
> 

-- 
regards,
Stan


Re: [PATCH v2] media: venus: Support V4L2 QP parameters in Venus encoder

2018-12-07 Thread Stanimir Varbanov
Hi Kelvin,

Thanks for the patch!

On 11/30/18 2:07 AM, Kelvin Lawson wrote:
> Support V4L2 QP parameters in Venus encoder:
>  * V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP
>  * V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP
>  * V4L2_CID_MPEG_VIDEO_H264_MIN_QP
>  * V4L2_CID_MPEG_VIDEO_H264_MAX_QP
> 
> Signed-off-by: Kelvin Lawson 
> ---
>  drivers/media/platform/qcom/venus/venc.c | 19 +++
>  1 file changed, 19 insertions(+)

Acked-by: Stanimir Varbanov 

-- 
regards,
Stan


Re: [PATCH] media: venus: Support V4L2 QP parameters in Venus encoder

2018-11-29 Thread Stanimir Varbanov
Hi Kelvin,

Thanks for the patch!

On 11/12/18 12:59 PM, Kelvin Lawson wrote:
> Support V4L2 QP parameters in Venus encoder:
>  * V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP
>  * V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP
>  * V4L2_CID_MPEG_VIDEO_H264_MIN_QP
>  * V4L2_CID_MPEG_VIDEO_H264_MAX_QP
> 
> Signed-off-by: Kelvin Lawson 
> ---
>  drivers/media/platform/qcom/venus/venc.c | 19 +++
>  1 file changed, 19 insertions(+)

As functional changes the patch is fine, but it has many coding style
issues. Did you read [1]?

> 
> diff --git a/drivers/media/platform/qcom/venus/venc.c
> b/drivers/media/platform/qcom/venus/venc.c
> index ce85962..321d612 100644
> --- a/drivers/media/platform/qcom/venus/venc.c
> +++ b/drivers/media/platform/qcom/venus/venc.c
> @@ -651,6 +651,8 @@ static int venc_set_properties(struct venus_inst *inst)
>   struct hfi_framerate frate;
>   struct hfi_bitrate brate;
>   struct hfi_idr_period idrp;
> + struct hfi_quantization quant;
> + struct hfi_quantization_range quant_range;
>   u32 ptype, rate_control, bitrate, profile = 0, level = 0;
>   int ret;
> 
> @@ -770,6 +772,23 @@ static int venc_set_properties(struct venus_inst *inst)
>   if (ret)
>   return ret;
> 
> + ptype = HFI_PROPERTY_PARAM_VENC_SESSION_QP;
> + quant.qp_i = ctr->h264_i_qp;
> + quant.qp_p = ctr->h264_p_qp;
> + quant.qp_b = ctr->h264_b_qp;
> + quant.layer_id = 0;
> + ret = hfi_session_set_property(inst, ptype, );
> + if (ret)
> + return ret;

please fix the indentation according to coding style
> +
> + ptype = HFI_PROPERTY_PARAM_VENC_SESSION_QP_RANGE;
> + quant_range.min_qp = ctr->h264_min_qp;
> + quant_range.max_qp = ctr->h264_max_qp;
> + quant_range.layer_id = 0;
> + ret = hfi_session_set_property(inst, ptype, _range);
> + if (ret)
> + return ret;

ditto

> +
>   if (inst->fmt_cap->pixfmt == V4L2_PIX_FMT_H264) {
>   profile = venc_v4l2_to_hfi(V4L2_CID_MPEG_VIDEO_H264_PROFILE,
>  ctr->profile.h264);
> 

Maybe your mail server is mangling the patches, but also please run
checkpatch before sending patches.

-- 
regards,
Stan

[1] https://www.kernel.org/doc/html/v4.19/process/submitting-patches.html


Re: [PATCH 0/2] Clarify H.264 loop filter offset controls and fix them for coda

2018-11-28 Thread Stanimir Varbanov
Hi Philipp,

On 11/28/18 3:01 PM, Philipp Zabel wrote:
> Hi,
> 
> the coda driver handles the H.264 loop filter alpha/beta offset controls
> incorrectly. When trying to fix them, I noticed that the documentation
> is not clear about what these values actually are.
> 
> From the value range of -6 to +6 used in the existing drivers (s5p-mfc,
> venus), it looks like they currently correspond directly to the values
> stored into the slice headers: slice_alpha_c0_offset_div2 and
> slice_beta_offset_div2. These are only half of the actual alpha/beta
> filter offsets.
> 
> The ITU-T Rec. H.264 (02/2016) states:
> 
>   slice_alpha_c0_offset_div2 specifies the offset used in accessing the
>   α [...] deblocking filter tables for filtering operations controlled
>   by the macroblocks within the slice. From this value, the offset that
>   shall be applied when addressing these tables shall be computed as
> 
>   FilterOffsetA = slice_alpha_c0_offset_div2 << 1 (7-32)
> 
>   The value of slice_alpha_c0_offset_div2 shall be in the range of −6 to
>   +6, inclusive. When slice_alpha_c0_offset_div2 is not present in the
>   slice header, the value of slice_alpha_c0_offset_div2 shall be inferred
>   to be equal to 0.
> 
> And the same for slice_beta_offset_div2 / FilterOffsetB.
> 
> Do the s5p-mfc and venus drivers use the controls
> V4L2_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA and _BETA directly as slice
> header fields, and thus their values are to be interpreted as half of
> FilterOffsetA/B defined in the H.264 spec, respectively?

That is correct for Venus encoder, it uses slice header fields directly
[-6, 6].

-- 
regards,
Stan


Re: [PATCH] media: venus: support VB2_USERPTR IO mode

2018-10-11 Thread Stanimir Varbanov
Hi Alex,

On 10/11/2018 09:50 AM, Alexandre Courbot wrote:
> Please ignore this patch - I did not notice that a similar one has
> been sent before. 

The difference is that you made it for decoder as well. Do you need
userptr for decoder?


-- 
regards,
Stan


Re: [PATCH v3] vb2: check for sane values from queue_setup

2018-09-12 Thread Stanimir Varbanov
Hi,

On 09/11/2018 03:46 PM, Johan Fjeldtvedt wrote:
> Warn and return error from the reqbufs ioctl when driver sets 0 number
> of planes or 0 as plane sizes, as these values don't make any sense.

typo: planes -> buffers

> Checking this here stops obviously wrong values from propagating
> further and causing various problems that are hard to trace back to
> either of these values being 0.
> 
> Signed-off-by: Johan Fjeldtvedt 
> ---
>  drivers/media/common/videobuf2/videobuf2-core.c | 9 +
>  1 file changed, 9 insertions(+)
> 
> diff --git a/drivers/media/common/videobuf2/videobuf2-core.c 
> b/drivers/media/common/videobuf2/videobuf2-core.c
> index f32ec7342ef0..5741e95e6af1 100644
> --- a/drivers/media/common/videobuf2/videobuf2-core.c
> +++ b/drivers/media/common/videobuf2/videobuf2-core.c
> @@ -662,6 +662,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory 
> memory,
>   unsigned int num_buffers, allocated_buffers, num_planes = 0;
>   unsigned plane_sizes[VB2_MAX_PLANES] = { };
>   int ret;
> + int i;
>  
>   if (q->streaming) {
>   dprintk(1, "streaming active\n");
> @@ -718,6 +719,14 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum 
> vb2_memory memory,
>   if (ret)
>   return ret;
>  
> + /* Check that driver has set sane values */
> + if (WARN_ON(!num_buffers))
> + return -EINVAL;
> +
> + for (i = 0; i < num_buffers; i++)
> + if (WARN_ON(!plane_sizes[i]))
> + return -EINVAL;
> +
>   /* Finally, allocate buffers and video memory */
>   allocated_buffers =
>   __vb2_queue_alloc(q, memory, num_buffers, num_planes, 
> plane_sizes);
> 

-- 
regards,
Stan


Re: [PATCH 4/4] venus: firmware: register separate platform_device for firmware loader

2018-08-22 Thread Stanimir Varbanov
Hi Vikash,

Could you give a try below patch on your environment? You should keep
your 1/4 to 3/4 patches and replace your 4/4 with the below one.

You have to drop the compatible string in firmware DT subnode (keep only
iommus).

On 08/22/2018 03:34 PM, Stanimir Varbanov wrote:
> This registers a firmware platform_device and associate it with
> video-firmware DT subnode. Then calls dma configure to initialize
> dma and iommu.
> 
> Signed-off-by: Stanimir Varbanov 
> ---
>  .../devicetree/bindings/media/qcom,venus.txt   | 13 +-
>  drivers/media/platform/qcom/venus/core.c   | 14 +--
>  drivers/media/platform/qcom/venus/firmware.c   | 49 
> ++
>  drivers/media/platform/qcom/venus/firmware.h   |  2 +
>  4 files changed, 73 insertions(+), 5 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/media/qcom,venus.txt 
> b/Documentation/devicetree/bindings/media/qcom,venus.txt
> index 00d0d1bf7647..7e045862c3fe 100644
> --- a/Documentation/devicetree/bindings/media/qcom,venus.txt
> +++ b/Documentation/devicetree/bindings/media/qcom,venus.txt
> @@ -53,7 +53,7 @@
>  
>  * Subnodes
>  The Venus video-codec node must contain two subnodes representing
> -video-decoder and video-encoder.
> +video-decoder and video-encoder, and one optional firmware subnode.
>  
>  Every of video-encoder or video-decoder subnode should have:
>  
> @@ -79,6 +79,13 @@ Every of video-encoder or video-decoder subnode should 
> have:
>   power domain which is responsible for collapsing
>   and restoring power to the subcore.
>  
> +The firmware subnode must have:
> +
> +- iommus:
> + Usage: required
> + Value type: 
> + Definition: A list of phandle and IOMMU specifier pairs.
> +
>  * An Example
>   video-codec@1d0 {
>   compatible = "qcom,msm8916-venus";
> @@ -105,4 +112,8 @@ Every of video-encoder or video-decoder subnode should 
> have:
>   clock-names = "core";
>   power-domains = < VENUS_CORE1_GDSC>;
>   };
> +
> + video-firmware {
> + iommus = <_iommu 0x10b2 0x0>;
> + };
>   };
> diff --git a/drivers/media/platform/qcom/venus/core.c 
> b/drivers/media/platform/qcom/venus/core.c
> index 393994ecab26..3bd3b8ab1f82 100644
> --- a/drivers/media/platform/qcom/venus/core.c
> +++ b/drivers/media/platform/qcom/venus/core.c
> @@ -284,6 +284,14 @@ static int venus_probe(struct platform_device *pdev)
>   if (ret < 0)
>   goto err_runtime_disable;
>  
> + ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
> + if (ret)
> + goto err_runtime_disable;
> +
> + ret = venus_firmware_init(core);
> + if (ret)
> + goto err_runtime_disable;
> +
>   ret = venus_boot(core);
>   if (ret)
>   goto err_runtime_disable;
> @@ -308,10 +316,6 @@ static int venus_probe(struct platform_device *pdev)
>   if (ret)
>   goto err_core_deinit;
>  
> - ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
> - if (ret)
> - goto err_dev_unregister;
> -
>   ret = pm_runtime_put_sync(dev);
>   if (ret)
>   goto err_dev_unregister;
> @@ -347,6 +351,8 @@ static int venus_remove(struct platform_device *pdev)
>   venus_shutdown(core);
>   of_platform_depopulate(dev);
>  
> + venus_firmware_deinit(core);
> +
>   pm_runtime_put_sync(dev);
>   pm_runtime_disable(dev);
>  
> diff --git a/drivers/media/platform/qcom/venus/firmware.c 
> b/drivers/media/platform/qcom/venus/firmware.c
> index 80c3d1362c04..2a9fcbb71216 100644
> --- a/drivers/media/platform/qcom/venus/firmware.c
> +++ b/drivers/media/platform/qcom/venus/firmware.c
> @@ -20,6 +20,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -228,3 +229,51 @@ int venus_shutdown(struct venus_core *core)
>  
>   return ret;
>  }
> +
> +int venus_firmware_init(struct venus_core *core)
> +{
> + struct platform_device_info info;
> + struct platform_device *pdev;
> + struct device_node *np;
> + int ret;
> +
> + np = of_get_child_by_name(core->dev->of_node, "video-firmware");
> + if (!np)
> + return 0;
> +
> + memset(, 0, sizeof(info));
> + info.fwnode = >fwnode;
> + info.parent = core->dev;
> + info.name = np->name;
> + info.dma_mask = DMA_BIT_MASK(32);
> +
> + pdev = platform_device_register_ful

[PATCH 4/4] venus: firmware: register separate platform_device for firmware loader

2018-08-22 Thread Stanimir Varbanov
This registers a firmware platform_device and associate it with
video-firmware DT subnode. Then calls dma configure to initialize
dma and iommu.

Signed-off-by: Stanimir Varbanov 
---
 .../devicetree/bindings/media/qcom,venus.txt   | 13 +-
 drivers/media/platform/qcom/venus/core.c   | 14 +--
 drivers/media/platform/qcom/venus/firmware.c   | 49 ++
 drivers/media/platform/qcom/venus/firmware.h   |  2 +
 4 files changed, 73 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/qcom,venus.txt 
b/Documentation/devicetree/bindings/media/qcom,venus.txt
index 00d0d1bf7647..7e045862c3fe 100644
--- a/Documentation/devicetree/bindings/media/qcom,venus.txt
+++ b/Documentation/devicetree/bindings/media/qcom,venus.txt
@@ -53,7 +53,7 @@
 
 * Subnodes
 The Venus video-codec node must contain two subnodes representing
-video-decoder and video-encoder.
+video-decoder and video-encoder, and one optional firmware subnode.
 
 Every of video-encoder or video-decoder subnode should have:
 
@@ -79,6 +79,13 @@ Every of video-encoder or video-decoder subnode should have:
power domain which is responsible for collapsing
and restoring power to the subcore.
 
+The firmware subnode must have:
+
+- iommus:
+   Usage: required
+   Value type: 
+   Definition: A list of phandle and IOMMU specifier pairs.
+
 * An Example
video-codec@1d0 {
compatible = "qcom,msm8916-venus";
@@ -105,4 +112,8 @@ Every of video-encoder or video-decoder subnode should have:
clock-names = "core";
power-domains = < VENUS_CORE1_GDSC>;
};
+
+   video-firmware {
+   iommus = <_iommu 0x10b2 0x0>;
+   };
};
diff --git a/drivers/media/platform/qcom/venus/core.c 
b/drivers/media/platform/qcom/venus/core.c
index 393994ecab26..3bd3b8ab1f82 100644
--- a/drivers/media/platform/qcom/venus/core.c
+++ b/drivers/media/platform/qcom/venus/core.c
@@ -284,6 +284,14 @@ static int venus_probe(struct platform_device *pdev)
if (ret < 0)
goto err_runtime_disable;
 
+   ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
+   if (ret)
+   goto err_runtime_disable;
+
+   ret = venus_firmware_init(core);
+   if (ret)
+   goto err_runtime_disable;
+
ret = venus_boot(core);
if (ret)
goto err_runtime_disable;
@@ -308,10 +316,6 @@ static int venus_probe(struct platform_device *pdev)
if (ret)
goto err_core_deinit;
 
-   ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
-   if (ret)
-   goto err_dev_unregister;
-
ret = pm_runtime_put_sync(dev);
if (ret)
goto err_dev_unregister;
@@ -347,6 +351,8 @@ static int venus_remove(struct platform_device *pdev)
venus_shutdown(core);
of_platform_depopulate(dev);
 
+   venus_firmware_deinit(core);
+
pm_runtime_put_sync(dev);
pm_runtime_disable(dev);
 
diff --git a/drivers/media/platform/qcom/venus/firmware.c 
b/drivers/media/platform/qcom/venus/firmware.c
index 80c3d1362c04..2a9fcbb71216 100644
--- a/drivers/media/platform/qcom/venus/firmware.c
+++ b/drivers/media/platform/qcom/venus/firmware.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -228,3 +229,51 @@ int venus_shutdown(struct venus_core *core)
 
return ret;
 }
+
+int venus_firmware_init(struct venus_core *core)
+{
+   struct platform_device_info info;
+   struct platform_device *pdev;
+   struct device_node *np;
+   int ret;
+
+   np = of_get_child_by_name(core->dev->of_node, "video-firmware");
+   if (!np)
+   return 0;
+
+   memset(, 0, sizeof(info));
+   info.fwnode = >fwnode;
+   info.parent = core->dev;
+   info.name = np->name;
+   info.dma_mask = DMA_BIT_MASK(32);
+
+   pdev = platform_device_register_full();
+   if (IS_ERR(pdev)) {
+   of_node_put(np);
+   return PTR_ERR(pdev);
+   }
+
+   pdev->dev.of_node = np;
+
+   ret = of_dma_configure(>dev, np);
+   if (ret)
+   dev_err(core->dev, "dma configure fail\n");
+
+   of_node_put(np);
+
+   if (ret)
+   return ret;
+
+   core->no_tz = true;
+   core->fw.dev = >dev;
+
+   return 0;
+}
+
+void venus_firmware_deinit(struct venus_core *core)
+{
+   if (!core->fw.dev)
+   return;
+
+   platform_device_unregister(to_platform_device(core->fw.dev));
+}
diff --git a/drivers/media/platform/qcom/venus/firmware.h 
b/drivers/media/platform/qcom/venus/firmware.h
index f41b615b96f1..119a9a4fc1a2 100644
--- a/drivers/media/platform/qcom/venus/firm

Re: [PATCH v3 1/4] venus: firmware: add routine to reset ARM9

2018-07-25 Thread Stanimir Varbanov
Hi,

On 07/04/2018 10:06 PM, Vikash Garodia wrote:
> Add routine to reset the ARM9 and brings it out of reset. Also
> abstract the Venus CPU state handling with a new function. This
> is in preparation to add PIL functionality in venus driver.
> 
> Signed-off-by: Vikash Garodia 
> ---
>  drivers/media/platform/qcom/venus/core.h |  1 +
>  drivers/media/platform/qcom/venus/firmware.c | 36 
> 
>  drivers/media/platform/qcom/venus/firmware.h |  1 +
>  drivers/media/platform/qcom/venus/hfi_venus.c| 13 +++--
>  drivers/media/platform/qcom/venus/hfi_venus_io.h |  5 
>  5 files changed, 47 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/media/platform/qcom/venus/core.h 
> b/drivers/media/platform/qcom/venus/core.h
> index 2f02365..eb5ee66 100644
> --- a/drivers/media/platform/qcom/venus/core.h
> +++ b/drivers/media/platform/qcom/venus/core.h
> @@ -129,6 +129,7 @@ struct venus_core {
>   struct device *dev;
>   struct device *dev_dec;
>   struct device *dev_enc;
> + bool no_tz;
>   struct mutex lock;
>   struct list_head instances;
>   atomic_t insts_count;
> diff --git a/drivers/media/platform/qcom/venus/firmware.c 
> b/drivers/media/platform/qcom/venus/firmware.c
> index 521d4b3..3968553d 100644
> --- a/drivers/media/platform/qcom/venus/firmware.c
> +++ b/drivers/media/platform/qcom/venus/firmware.c
> @@ -22,11 +22,47 @@
>  #include 
>  #include 
>  
> +#include "core.h"
>  #include "firmware.h"
> +#include "hfi_venus_io.h"
>  
>  #define VENUS_PAS_ID 9
>  #define VENUS_FW_MEM_SIZE(6 * SZ_1M)
>  
> +static void venus_reset_cpu(struct venus_core *core)
> +{
> + void __iomem *base = core->base;
> +
> + writel(0, base + WRAPPER_FW_START_ADDR);
> + writel(VENUS_FW_MEM_SIZE, base + WRAPPER_FW_END_ADDR);
> + writel(0, base + WRAPPER_CPA_START_ADDR);
> + writel(VENUS_FW_MEM_SIZE, base + WRAPPER_CPA_END_ADDR);
> + writel(0x0, base + WRAPPER_CPU_CGC_DIS);
> + writel(0x0, base + WRAPPER_CPU_CLOCK_CONFIG);
> +
> + /* Make sure all register writes are committed. */
> + mb();
> +
> + /* Bring ARM9 out of reset */
> + writel_relaxed(0, base + WRAPPER_A9SS_SW_RESET);
> +}
> +
> +int venus_set_hw_state(struct venus_core *core, bool resume)
> +{
> + void __iomem *base = core->base;
> +
> + if (!core->no_tz)
> + return qcom_scm_set_remote_state(resume, 0);
> +
> + if (resume)
> + venus_reset_cpu(core);
> + else
> + writel(1, base + WRAPPER_A9SS_SW_RESET);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(venus_set_hw_state);

This export_symbol shouldn't be needed

-- 
regards,
Stan


Re: [PATCH v3 3/4] venus: firmware: add no TZ boot and shutdown routine

2018-07-25 Thread Stanimir Varbanov
Hi Vikash,

On 07/04/2018 10:06 PM, Vikash Garodia wrote:
> Video hardware is mainly comprised of vcodec subsystem and video
> control subsystem. Video control has ARM9 which executes the video
> firmware instructions whereas vcodec does the video frame processing.
> This change adds support to load the video firmware and bring ARM9
> out of reset for platforms which does not have trustzone.
> 
> Signed-off-by: Vikash Garodia 
> ---
>  drivers/media/platform/qcom/venus/core.c |  6 +-
>  drivers/media/platform/qcom/venus/core.h |  5 ++
>  drivers/media/platform/qcom/venus/firmware.c | 93 
> ++--
>  drivers/media/platform/qcom/venus/firmware.h |  2 +-
>  4 files changed, 98 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/media/platform/qcom/venus/core.c 
> b/drivers/media/platform/qcom/venus/core.c
> index 75b9785..393994e 100644
> --- a/drivers/media/platform/qcom/venus/core.c
> +++ b/drivers/media/platform/qcom/venus/core.c
> @@ -76,7 +76,7 @@ static void venus_sys_error_handler(struct work_struct 
> *work)
>   hfi_core_deinit(core, true);
>   hfi_destroy(core);
>   mutex_lock(>lock);
> - venus_shutdown(core->dev);
> + venus_shutdown(core);
>  
>   pm_runtime_put_sync(core->dev);
>  
> @@ -323,7 +323,7 @@ static int venus_probe(struct platform_device *pdev)
>  err_core_deinit:
>   hfi_core_deinit(core, false);
>  err_venus_shutdown:
> - venus_shutdown(dev);
> + venus_shutdown(core);
>  err_runtime_disable:
>   pm_runtime_set_suspended(dev);
>   pm_runtime_disable(dev);
> @@ -344,7 +344,7 @@ static int venus_remove(struct platform_device *pdev)
>   WARN_ON(ret);
>  
>   hfi_destroy(core);
> - venus_shutdown(dev);
> + venus_shutdown(core);
>   of_platform_depopulate(dev);
>  
>   pm_runtime_put_sync(dev);
> diff --git a/drivers/media/platform/qcom/venus/core.h 
> b/drivers/media/platform/qcom/venus/core.h
> index eb5ee66..abe4ddf 100644
> --- a/drivers/media/platform/qcom/venus/core.h
> +++ b/drivers/media/platform/qcom/venus/core.h
> @@ -81,6 +81,10 @@ struct venus_caps {
>   bool valid; /* used only for Venus v1xx */
>  };
>  
> +struct video_firmware {
> + struct device *dev;
> + struct iommu_domain *iommu_domain;
> +};

add an empty line here

>  /**
>   * struct venus_core - holds core parameters valid for all instances
>   *
> @@ -129,6 +133,7 @@ struct venus_core {
>   struct device *dev;
>   struct device *dev_dec;
>   struct device *dev_enc;
> + struct video_firmware fw;
>   bool no_tz;
>   struct mutex lock;
>   struct list_head instances;
> diff --git a/drivers/media/platform/qcom/venus/firmware.c 
> b/drivers/media/platform/qcom/venus/firmware.c
> index 6d6cca4..2a98d9e 100644
> --- a/drivers/media/platform/qcom/venus/firmware.c
> +++ b/drivers/media/platform/qcom/venus/firmware.c
> @@ -12,8 +12,10 @@
>   *
>   */
>  
> +#include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -27,7 +29,8 @@
>  #include "hfi_venus_io.h"
>  
>  #define VENUS_PAS_ID 9
> -#define VENUS_FW_MEM_SIZE(6 * SZ_1M)
> +#define VENUS_FW_MEM_SIZE(5 * SZ_1M)

This change should be subject to a separate patch.

> +#define VENUS_FW_START_ADDR  0x0
>  
>  static void venus_reset_cpu(struct venus_core *core)
>  {
> @@ -121,6 +124,76 @@ static int venus_load_fw(struct venus_core *core, const 
> char *fwname,
>   return ret;
>  }
>  
> +int venus_boot_noTZ(struct venus_core *core, phys_addr_t mem_phys,
> + size_t mem_size)

please use lowercase for function names and correct the size_t mem_size
indentation.

> +{
> + struct iommu_domain *iommu;

s/iommu/iommu_dom ?

> + struct device *dev;
> + int ret;
> +
> + if (!core->fw.dev)
> + return -EPROBE_DEFER;
> +
> + dev = core->fw.dev;

you could make this initialization in declaration and check for !dev
above in the if statement.

> +
> + iommu = iommu_domain_alloc(_bus_type);
> + if (!iommu) {
> + dev_err(dev, "Failed to allocate iommu domain\n");
> + return -ENOMEM;
> + }
> +
> + ret = iommu_attach_device(iommu, dev);
> + if (ret) {
> + dev_err(dev, "could not attach device\n");
> + goto err_attach;
> + }
> +
> + ret = iommu_map(iommu, VENUS_FW_START_ADDR, mem_phys, mem_size,
> + IOMMU_READ|IOMMU_WRITE|IOMMU_PRIV);

spaces between IOMMU_xxx

> + if (ret) {
> + dev_err(dev, "could not map video firmware region\n");
> + goto err_map;
> + }

add blank line here

> + core->fw.iommu_domain = iommu;
> + venus_reset_cpu(core);
> +
> + return 0;
> +
> +err_map:
> + iommu_detach_device(iommu, dev);
> +err_attach:
> + iommu_domain_free(iommu);
> + return ret;
> +}
> +
> +int venus_shutdown_noTZ(struct venus_core *core)


Re: [PATCH v3 2/4] venus: firmware: move load firmware in a separate function

2018-07-25 Thread Stanimir Varbanov
Hi Vikash,

On 07/04/2018 10:06 PM, Vikash Garodia wrote:
> Separate firmware loading part into a new function.

I cannot apply this patch in order to test the series.

> 
> Signed-off-by: Vikash Garodia 
> ---
>  drivers/media/platform/qcom/venus/core.c |  4 +-
>  drivers/media/platform/qcom/venus/firmware.c | 58 
> +---
>  drivers/media/platform/qcom/venus/firmware.h |  2 +-
>  3 files changed, 39 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/media/platform/qcom/venus/core.c 
> b/drivers/media/platform/qcom/venus/core.c
> index bb6add9..75b9785 100644
> --- a/drivers/media/platform/qcom/venus/core.c
> +++ b/drivers/media/platform/qcom/venus/core.c
> @@ -84,7 +84,7 @@ static void venus_sys_error_handler(struct work_struct 
> *work)
>  
>   pm_runtime_get_sync(core->dev);
>  
> - ret |= venus_boot(core->dev, core->res->fwname);
> + ret |= venus_boot(core);
>  
>   ret |= hfi_core_resume(core, true);
>  
> @@ -284,7 +284,7 @@ static int venus_probe(struct platform_device *pdev)
>   if (ret < 0)
>   goto err_runtime_disable;
>  
> - ret = venus_boot(dev, core->res->fwname);
> + ret = venus_boot(core);
>   if (ret)
>   goto err_runtime_disable;
>  
> diff --git a/drivers/media/platform/qcom/venus/firmware.c 
> b/drivers/media/platform/qcom/venus/firmware.c
> index 3968553d..6d6cca4 100644
> --- a/drivers/media/platform/qcom/venus/firmware.c
> +++ b/drivers/media/platform/qcom/venus/firmware.c
> @@ -63,40 +63,37 @@ int venus_set_hw_state(struct venus_core *core, bool 
> resume)
>  }
>  EXPORT_SYMBOL_GPL(venus_set_hw_state);
>  
> -int venus_boot(struct device *dev, const char *fwname)
> +static int venus_load_fw(struct venus_core *core, const char *fwname,
> + phys_addr_t *mem_phys, size_t *mem_size)

the next function argument on new line should be just below open brace

>  {
>   const struct firmware *mdt;
>   struct device_node *node;
> - phys_addr_t mem_phys;
> + struct device *dev;
>   struct resource r;
>   ssize_t fw_size;
> - size_t mem_size;
>   void *mem_va;
>   int ret;
>  
> - if (!IS_ENABLED(CONFIG_QCOM_MDT_LOADER) || !qcom_scm_is_available())
> - return -EPROBE_DEFER;
> -
> + dev = core->dev;
>   node = of_parse_phandle(dev->of_node, "memory-region", 0);
>   if (!node) {
>   dev_err(dev, "no memory-region specified\n");
>   return -EINVAL;
>   }
> -

please don't delete above blank line

>   ret = of_address_to_resource(node, 0, );
>   if (ret)
>   return ret;
>  
> - mem_phys = r.start;
> - mem_size = resource_size();
> + *mem_phys = r.start;
> + *mem_size = resource_size();
>  
> - if (mem_size < VENUS_FW_MEM_SIZE)
> + if (*mem_size < VENUS_FW_MEM_SIZE)
>   return -EINVAL;
>  
> - mem_va = memremap(r.start, mem_size, MEMREMAP_WC);
> + mem_va = memremap(r.start, *mem_size, MEMREMAP_WC);
>   if (!mem_va) {
>   dev_err(dev, "unable to map memory region: %pa+%zx\n",
> - , mem_size);
> + , *mem_size);
>   return -ENOMEM;
>   }
>  
> @@ -110,24 +107,41 @@ int venus_boot(struct device *dev, const char *fwname)
>   release_firmware(mdt);
>   goto err_unmap;
>   }
> -
> - ret = qcom_mdt_load(dev, mdt, fwname, VENUS_PAS_ID, mem_va, mem_phys,
> - mem_size);
> + if (core->no_tz)
> + ret = qcom_mdt_load_no_init(dev, mdt, fwname, VENUS_PAS_ID,
> + mem_va, *mem_phys, *mem_size, NULL);

indentation is wrong see the original code

> + else
> + ret = qcom_mdt_load(dev, mdt, fwname, VENUS_PAS_ID, mem_va,
> + *mem_phys, *mem_size);

indentation again

>  
>   release_firmware(mdt);
>  
> - if (ret)
> - goto err_unmap;
> -
> - ret = qcom_scm_pas_auth_and_reset(VENUS_PAS_ID);
> - if (ret)
> - goto err_unmap;
> -
>  err_unmap:
>   memunmap(mem_va);
>   return ret;
>  }
>  
> +int venus_boot(struct venus_core *core)
> +{
> + phys_addr_t mem_phys;
> + size_t mem_size;
> + int ret;
> + struct device *dev;

please order declarations from longer to shorter.

> +
> + if (!IS_ENABLED(CONFIG_QCOM_MDT_LOADER))
> + return -EPROBE_DEFER;

the original venus_boot was checking for || !qcom_scm_is_available() why
is that removed? It was done on purpose.

> +
> + dev = core->dev;

this could be done when dev is declared.

> +
> + ret = venus_load_fw(core, core->res->fwname, _phys, _size);
> + if (ret) {
> + dev_err(dev, "fail to load video firmware\n");
> + return -EINVAL;
> + }
> +
> + return qcom_scm_pas_auth_and_reset(VENUS_PAS_ID);
> +}
> +
>  int venus_shutdown(struct device *dev)
>  {
>   return 

Re: [PATCH v3 1/4] venus: firmware: add routine to reset ARM9

2018-07-25 Thread Stanimir Varbanov
Hi Vikash,

On 07/04/2018 10:06 PM, Vikash Garodia wrote:
> Add routine to reset the ARM9 and brings it out of reset. Also
> abstract the Venus CPU state handling with a new function. This
> is in preparation to add PIL functionality in venus driver.
> 
> Signed-off-by: Vikash Garodia 
> ---
>  drivers/media/platform/qcom/venus/core.h |  1 +
>  drivers/media/platform/qcom/venus/firmware.c | 36 
> 
>  drivers/media/platform/qcom/venus/firmware.h |  1 +
>  drivers/media/platform/qcom/venus/hfi_venus.c| 13 +++--
>  drivers/media/platform/qcom/venus/hfi_venus_io.h |  5 
>  5 files changed, 47 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/media/platform/qcom/venus/core.h 
> b/drivers/media/platform/qcom/venus/core.h
> index 2f02365..eb5ee66 100644
> --- a/drivers/media/platform/qcom/venus/core.h
> +++ b/drivers/media/platform/qcom/venus/core.h
> @@ -129,6 +129,7 @@ struct venus_core {
>   struct device *dev;
>   struct device *dev_dec;
>   struct device *dev_enc;
> + bool no_tz;
>   struct mutex lock;
>   struct list_head instances;
>   atomic_t insts_count;
> diff --git a/drivers/media/platform/qcom/venus/firmware.c 
> b/drivers/media/platform/qcom/venus/firmware.c
> index 521d4b3..3968553d 100644
> --- a/drivers/media/platform/qcom/venus/firmware.c
> +++ b/drivers/media/platform/qcom/venus/firmware.c
> @@ -22,11 +22,47 @@
>  #include 
>  #include 
>  
> +#include "core.h"
>  #include "firmware.h"
> +#include "hfi_venus_io.h"
>  
>  #define VENUS_PAS_ID 9
>  #define VENUS_FW_MEM_SIZE(6 * SZ_1M)
>  
> +static void venus_reset_cpu(struct venus_core *core)
> +{
> + void __iomem *base = core->base;
> +
> + writel(0, base + WRAPPER_FW_START_ADDR);
> + writel(VENUS_FW_MEM_SIZE, base + WRAPPER_FW_END_ADDR);
> + writel(0, base + WRAPPER_CPA_START_ADDR);
> + writel(VENUS_FW_MEM_SIZE, base + WRAPPER_CPA_END_ADDR);
> + writel(0x0, base + WRAPPER_CPU_CGC_DIS);
> + writel(0x0, base + WRAPPER_CPU_CLOCK_CONFIG);
> +
> + /* Make sure all register writes are committed. */
> + mb();
> +
> + /* Bring ARM9 out of reset */
> + writel_relaxed(0, base + WRAPPER_A9SS_SW_RESET);

replace writel_relaxed with writel and drop above mb. The writel has wmb
just before writing so I think using writel here is better choice.

> +}
> +
> +int venus_set_hw_state(struct venus_core *core, bool resume)

s/resume/suspend as it is done in the function prototype in firmware.h.

> +{
> + void __iomem *base = core->base;
> +
> + if (!core->no_tz)
> + return qcom_scm_set_remote_state(resume, 0);
> +
> + if (resume)
> + venus_reset_cpu(core);
> + else
> + writel(1, base + WRAPPER_A9SS_SW_RESET);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(venus_set_hw_state);
> +
>  int venus_boot(struct device *dev, const char *fwname)
>  {
>   const struct firmware *mdt;
> diff --git a/drivers/media/platform/qcom/venus/firmware.h 
> b/drivers/media/platform/qcom/venus/firmware.h
> index 428efb5..ff2e70e 100644
> --- a/drivers/media/platform/qcom/venus/firmware.h
> +++ b/drivers/media/platform/qcom/venus/firmware.h
> @@ -18,5 +18,6 @@
>  
>  int venus_boot(struct device *dev, const char *fwname);
>  int venus_shutdown(struct device *dev);
> +int venus_set_hw_state(struct venus_core *core, bool suspend);

could you make two inline functions here, call them
venus_set_hw_state_suspend() and venus_set_hw_state_resume() which just
call venus_set_hw_state with the right state.

>  
>  #endif
> diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c 
> b/drivers/media/platform/qcom/venus/hfi_venus.c
> index 9366dae..5b56925 100644
> --- a/drivers/media/platform/qcom/venus/hfi_venus.c
> +++ b/drivers/media/platform/qcom/venus/hfi_venus.c
> @@ -19,7 +19,6 @@
>  #include 
>  #include 
>  #include 
> -#include 
>  #include 
>  
>  #include "core.h"
> @@ -27,6 +26,7 @@
>  #include "hfi_msgs.h"
>  #include "hfi_venus.h"
>  #include "hfi_venus_io.h"
> +#include "firmware.h"
>  
>  #define HFI_MASK_QHDR_TX_TYPE0xff00
>  #define HFI_MASK_QHDR_RX_TYPE0x00ff
> @@ -55,11 +55,6 @@
>  #define IFACEQ_VAR_LARGE_PKT_SIZE512
>  #define IFACEQ_VAR_HUGE_PKT_SIZE (1024 * 12)
>  
> -enum tzbsp_video_state {
> - TZBSP_VIDEO_STATE_SUSPEND = 0,
> - TZBSP_VIDEO_STATE_RESUME
> -};
> -
>  struct hfi_queue_table_header {
>   u32 version;
>   u32 size;
> @@ -575,7 +570,7 @@ static int venus_power_off(struct venus_hfi_device *hdev)
>   if (!hdev->power_enabled)
>   return 0;
>  
> - ret = qcom_scm_set_remote_state(TZBSP_VIDEO_STATE_SUSPEND, 0);
> + ret = venus_set_hw_state(hdev->core, false);

... and use venus_set_hw_state_suspend()

>   if (ret)
>   return ret;
>  
> @@ -595,7 +590,7 @@ static int venus_power_on(struct venus_hfi_device *hdev)
>   if (hdev->power_enabled)
>  

[PATCH v5 10/27] venus: hfi_venus: add suspend functionality for Venus 4xx

2018-07-05 Thread Stanimir Varbanov
This adds suspend (power collapse) functionality by reusing
the suspend function for Venus 3xx and also enables idle indicator
property for Venus 4xx (where it is disabled by default).

Signed-off-by: Stanimir Varbanov 
Reviewed-by: Tomasz Figa 
---
 drivers/media/platform/qcom/venus/hfi_venus.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c 
b/drivers/media/platform/qcom/venus/hfi_venus.c
index 7a83e967a8ea..124085556b94 100644
--- a/drivers/media/platform/qcom/venus/hfi_venus.c
+++ b/drivers/media/platform/qcom/venus/hfi_venus.c
@@ -879,6 +879,14 @@ static int venus_sys_set_default_properties(struct 
venus_hfi_device *hdev)
if (ret)
dev_warn(dev, "setting fw debug msg ON failed (%d)\n", ret);
 
+   /*
+* Idle indicator is disabled by default on some 4xx firmware versions,
+* enable it explicitly in order to make suspend functional by checking
+* WFI (wait-for-interrupt) bit.
+*/
+   if (IS_V4(hdev->core))
+   venus_sys_idle_indicator = true;
+
ret = venus_sys_set_idle_message(hdev, venus_sys_idle_indicator);
if (ret)
dev_warn(dev, "setting idle response ON failed (%d)\n", ret);
@@ -1533,7 +1541,7 @@ static int venus_suspend_3xx(struct venus_core *core)
 
 static int venus_suspend(struct venus_core *core)
 {
-   if (core->res->hfi_version == HFI_VERSION_3XX)
+   if (IS_V3(core) || IS_V4(core))
return venus_suspend_3xx(core);
 
return venus_suspend_1xx(core);
-- 
2.14.1



Re: [PATCH v2 11/29] venus: venc,vdec: adds clocks needed for venus 4xx

2018-05-28 Thread Stanimir Varbanov
Hi Tomasz,

On 05/24/2018 09:11 AM, Tomasz Figa wrote:
> Hi Stanimir,
> 
> On Tue, May 15, 2018 at 5:10 PM Stanimir Varbanov <
> stanimir.varba...@linaro.org> wrote:
> 
>> This extends the clocks number to support suspend and resume
>> on Venus version 4xx.
> 
>> Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
>> ---
>>   drivers/media/platform/qcom/venus/core.h |  4 +--
>>   drivers/media/platform/qcom/venus/vdec.c | 42
> ++--
>>   drivers/media/platform/qcom/venus/venc.c | 42
> ++--
>>   3 files changed, 72 insertions(+), 16 deletions(-)
> 
>> diff --git a/drivers/media/platform/qcom/venus/core.h
> b/drivers/media/platform/qcom/venus/core.h
>> index 8d3e150800c9..b5b9a84e9155 100644
>> --- a/drivers/media/platform/qcom/venus/core.h
>> +++ b/drivers/media/platform/qcom/venus/core.h
>> @@ -92,8 +92,8 @@ struct venus_core {
>>  void __iomem *base;
>>  int irq;
>>  struct clk *clks[VIDC_CLKS_NUM_MAX];
>> -   struct clk *core0_clk;
>> -   struct clk *core1_clk;
>> +   struct clk *core0_clk, *core0_bus_clk;
>> +   struct clk *core1_clk, *core1_bus_clk;
>>  struct video_device *vdev_dec;
>>  struct video_device *vdev_enc;
>>  struct v4l2_device v4l2_dev;
>> diff --git a/drivers/media/platform/qcom/venus/vdec.c
> b/drivers/media/platform/qcom/venus/vdec.c
>> index 261a51adeef2..c45452634e7e 100644
>> --- a/drivers/media/platform/qcom/venus/vdec.c
>> +++ b/drivers/media/platform/qcom/venus/vdec.c
>> @@ -1081,12 +1081,18 @@ static int vdec_probe(struct platform_device
> *pdev)
>>  if (!core)
>>  return -EPROBE_DEFER;
> 
>> -   if (core->res->hfi_version == HFI_VERSION_3XX) {
>> +   if (IS_V3(core) || IS_V4(core)) {
>>  core->core0_clk = devm_clk_get(dev, "core");
>>  if (IS_ERR(core->core0_clk))
>>  return PTR_ERR(core->core0_clk);
>>  }
> 
>> +   if (IS_V4(core)) {
>> +   core->core0_bus_clk = devm_clk_get(dev, "bus");
>> +   if (IS_ERR(core->core0_bus_clk))
>> +   return PTR_ERR(core->core0_bus_clk);
>> +   }
>> +
> 
> Rather than doing this conditional dance, wouldn't it make more sense to
> just list all the clocks in variant data struct and use clk_bulk_get()?

Do you mean the same as it is done for venus/core.c ?

> 
>>  platform_set_drvdata(pdev, core);
> 
>>  vdev = video_device_alloc();
>> @@ -1132,12 +1138,23 @@ static __maybe_unused int
> vdec_runtime_suspend(struct device *dev)
>>   {
>>  struct venus_core *core = dev_get_drvdata(dev);
> 
>> -   if (core->res->hfi_version == HFI_VERSION_1XX)
>> +   if (IS_V1(core))
>>  return 0;
> 
>> -   writel(0, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
>> +   if (IS_V3(core))
>> +   writel(0, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
>> +   else if (IS_V4(core))
>> +   writel(0, core->base +
> WRAPPER_VCODEC0_MMCC_POWER_CONTROL);
>> +
>> +   if (IS_V4(core))
>> +   clk_disable_unprepare(core->core0_bus_clk);
>> +
>>  clk_disable_unprepare(core->core0_clk);
>> -   writel(1, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
>> +
>> +   if (IS_V3(core))
>> +   writel(1, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
>> +   else if (IS_V4(core))
>> +   writel(1, core->base +
> WRAPPER_VCODEC0_MMCC_POWER_CONTROL);
> 
> Almost every step here differs between version. I'd suggest splitting this
> into separate functions for both versions.

I think it will be better to squash this patch with 13/29.


-- 
regards,
Stan


Re: [PATCH 3/4] venus: add check to make scm calls

2018-05-22 Thread Stanimir Varbanov

Hi Jordan,

On 22.05.2018 22:50, Jordan Crouse wrote:

On Tue, May 22, 2018 at 04:04:51PM +0300, Stanimir Varbanov wrote:

Hi Vikash,

On 05/17/2018 02:32 PM, Vikash Garodia wrote:

In order to invoke scm calls, ensure that the platform
has the required support to invoke the scm calls in
secure world. This code is in preparation to add PIL
functionality in venus driver.

Signed-off-by: Vikash Garodia <vgaro...@codeaurora.org>
---
  drivers/media/platform/qcom/venus/hfi_venus.c | 26 +++---
  1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c 
b/drivers/media/platform/qcom/venus/hfi_venus.c
index f61d34b..9bcce94 100644
--- a/drivers/media/platform/qcom/venus/hfi_venus.c
+++ b/drivers/media/platform/qcom/venus/hfi_venus.c
@@ -27,6 +27,7 @@
  #include "hfi_msgs.h"
  #include "hfi_venus.h"
  #include "hfi_venus_io.h"
+#include "firmware.h"
  
  #define HFI_MASK_QHDR_TX_TYPE		0xff00

  #define HFI_MASK_QHDR_RX_TYPE 0x00ff
@@ -570,13 +571,19 @@ static int venus_halt_axi(struct venus_hfi_device *hdev)
  static int venus_power_off(struct venus_hfi_device *hdev)
  {
int ret;
+   void __iomem *reg_base;
  
  	if (!hdev->power_enabled)

return 0;
  
-	ret = qcom_scm_set_remote_state(TZBSP_VIDEO_STATE_SUSPEND, 0);

-   if (ret)
-   return ret;
+   if (qcom_scm_is_available()) {
+   ret = qcom_scm_set_remote_state(TZBSP_VIDEO_STATE_SUSPEND, 0);


I think it will be clearer if we abstract qcom_scm_set_remote_state to
something like venus_set_state(SUSPEND|RESUME) in firmware.c and export
the functions to be used here.


This specific function is a little odd because the SCM function got overloaded
and used as a hardware workaround for the adreno a5xx zap shader.

When we added it for the GPU we knew the day would come that we would need it
for Venus so we kept the name purposely generic. You can wrap if if you want
but just know that there are other non video entities out there using it.


Sorry I wasn't clear, by abstract it I meant to introduce a new 
venus_set_state function in venus/firmware.c where we'll select 
tz/non-tz functions for suspend / resume depending on the configuration.


regards,
Stan


Re: [PATCH 4/4] media: venus: add PIL support

2018-05-22 Thread Stanimir Varbanov
Hi,

On 05/22/2018 04:02 PM, Stanimir Varbanov wrote:
> Hi Vikash,
> 
> On 05/17/2018 02:32 PM, Vikash Garodia wrote:
>> This adds support to load the video firmware
>> and bring ARM9 out of reset. This is useful
>> for platforms which does not have trustzone
>> to reset the ARM9.
>>
>> Signed-off-by: Vikash Garodia <vgaro...@codeaurora.org>
>> ---
>>  .../devicetree/bindings/media/qcom,venus.txt   |   8 +-
>>  drivers/media/platform/qcom/venus/core.c   |  67 +++--
>>  drivers/media/platform/qcom/venus/core.h   |   6 +
>>  drivers/media/platform/qcom/venus/firmware.c   | 163 
>> +
>>  drivers/media/platform/qcom/venus/firmware.h   |  10 +-
>>  5 files changed, 217 insertions(+), 37 deletions(-)
>>



>>  
>> -int venus_shutdown(struct device *dev)
>> +int venus_boot_noTZ(struct venus_core *core, phys_addr_t mem_phys,
>> +size_t mem_size)
>>  {
>> -return qcom_scm_pas_shutdown(VENUS_PAS_ID);
>> +struct iommu_domain *iommu;
>> +struct device *dev;
>> +int ret;
>> +
>> +if (!core->fw.dev)
>> +return -EPROBE_DEFER;
>> +
>> +dev = core->fw.dev;
>> +
>> +iommu = iommu_domain_alloc(_bus_type);
>> +if (!iommu) {
>> +dev_err(dev, "Failed to allocate iommu domain\n");
>> +return -ENOMEM;
>> +}
>> +
>> +iommu->geometry.aperture_start = 0x0;
>> +iommu->geometry.aperture_end = VENUS_FW_MEM_SIZE;
> 
> The same comment for geometry params as for venus_probe is valid here.

Infact aperture_end will be overwritten by arm-smmu driver in the next
call to iommu_attach_device(), and by chance geometry.force_aperture
will become true.

I wonder is that geometry params are supposed to be used by drivers or
by iommu drivers?

> 
>> +
>> +ret = iommu_attach_device(iommu, dev);
>> +if (ret) {
>> +dev_err(dev, "could not attach device\n");
>> +goto err_attach;
>> +}
>> +
>> +ret = iommu_map(iommu, core->fw.iova, mem_phys, mem_size,
>> +IOMMU_READ|IOMMU_WRITE|IOMMU_PRIV);
> 
> iova is not initialized and is zero, maybe we don't need that variable
> in the venus_firmware structure?
> 
>> +if (ret) {
>> +dev_err(dev, "could not map video firmware region\n");
>> +goto err_map;
>> +}
>> +core->fw.iommu_domain = iommu;
>> +venus_reset_hw(core);
>> +
>> +return 0;
>> +
>> +err_map:
>> +iommu_detach_device(iommu, dev);
>> +err_attach:
>> +iommu_domain_free(iommu);
>> +return ret;
>>  }
>> +



-- 
regards,
Stan


Re: [PATCH 3/4] venus: add check to make scm calls

2018-05-22 Thread Stanimir Varbanov
Hi Vikash,

On 05/17/2018 02:32 PM, Vikash Garodia wrote:
> In order to invoke scm calls, ensure that the platform
> has the required support to invoke the scm calls in
> secure world. This code is in preparation to add PIL
> functionality in venus driver.
> 
> Signed-off-by: Vikash Garodia 
> ---
>  drivers/media/platform/qcom/venus/hfi_venus.c | 26 +++---
>  1 file changed, 19 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c 
> b/drivers/media/platform/qcom/venus/hfi_venus.c
> index f61d34b..9bcce94 100644
> --- a/drivers/media/platform/qcom/venus/hfi_venus.c
> +++ b/drivers/media/platform/qcom/venus/hfi_venus.c
> @@ -27,6 +27,7 @@
>  #include "hfi_msgs.h"
>  #include "hfi_venus.h"
>  #include "hfi_venus_io.h"
> +#include "firmware.h"
>  
>  #define HFI_MASK_QHDR_TX_TYPE0xff00
>  #define HFI_MASK_QHDR_RX_TYPE0x00ff
> @@ -570,13 +571,19 @@ static int venus_halt_axi(struct venus_hfi_device *hdev)
>  static int venus_power_off(struct venus_hfi_device *hdev)
>  {
>   int ret;
> + void __iomem *reg_base;
>  
>   if (!hdev->power_enabled)
>   return 0;
>  
> - ret = qcom_scm_set_remote_state(TZBSP_VIDEO_STATE_SUSPEND, 0);
> - if (ret)
> - return ret;
> + if (qcom_scm_is_available()) {
> + ret = qcom_scm_set_remote_state(TZBSP_VIDEO_STATE_SUSPEND, 0);

I think it will be clearer if we abstract qcom_scm_set_remote_state to
something like venus_set_state(SUSPEND|RESUME) in firmware.c and export
the functions to be used here.

-- 
regards,
Stan


Re: [PATCH 4/4] media: venus: add PIL support

2018-05-22 Thread Stanimir Varbanov
Hi Vikash,

On 05/17/2018 02:32 PM, Vikash Garodia wrote:
> This adds support to load the video firmware
> and bring ARM9 out of reset. This is useful
> for platforms which does not have trustzone
> to reset the ARM9.
> 
> Signed-off-by: Vikash Garodia 
> ---
>  .../devicetree/bindings/media/qcom,venus.txt   |   8 +-
>  drivers/media/platform/qcom/venus/core.c   |  67 +++--
>  drivers/media/platform/qcom/venus/core.h   |   6 +
>  drivers/media/platform/qcom/venus/firmware.c   | 163 
> +
>  drivers/media/platform/qcom/venus/firmware.h   |  10 +-
>  5 files changed, 217 insertions(+), 37 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/media/qcom,venus.txt 
> b/Documentation/devicetree/bindings/media/qcom,venus.txt
> index 00d0d1b..0ff0f2d 100644
> --- a/Documentation/devicetree/bindings/media/qcom,venus.txt
> +++ b/Documentation/devicetree/bindings/media/qcom,venus.txt

for this change in DT binding you have to cc devicetree ML. And probably
it could be separate patch.

> @@ -53,7 +53,7 @@
>  
>  * Subnodes
>  The Venus video-codec node must contain two subnodes representing
> -video-decoder and video-encoder.
> +video-decoder and video-encoder, one optional firmware subnode.
>  
>  Every of video-encoder or video-decoder subnode should have:
>  
> @@ -79,6 +79,8 @@ Every of video-encoder or video-decoder subnode should have:
>   power domain which is responsible for collapsing
>   and restoring power to the subcore.
>  
> +The firmware sub node must contain the iommus specifiers for ARM9.
> +
>  * An Example
>   video-codec@1d0 {
>   compatible = "qcom,msm8916-venus";
> @@ -105,4 +107,8 @@ Every of video-encoder or video-decoder subnode should 
> have:
>   clock-names = "core";
>   power-domains = < VENUS_CORE1_GDSC>;
>   };
> + firmware {

venus-firmware

> + compatible = "qcom,venus-pil-no-tz";

this should be following the other subnodes compatible names:

compatible = "venus-firmware";

> + iommus = <_smmu 0x10b2 0x0>;
> + }
>   };
> diff --git a/drivers/media/platform/qcom/venus/core.c 
> b/drivers/media/platform/qcom/venus/core.c
> index 1308488..16910558 100644
> --- a/drivers/media/platform/qcom/venus/core.c
> +++ b/drivers/media/platform/qcom/venus/core.c
> @@ -22,6 +22,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -30,6 +31,7 @@
>  #include "vdec.h"
>  #include "venc.h"
>  #include "firmware.h"
> +#include "hfi_venus.h"
>  
>  static void venus_event_notify(struct venus_core *core, u32 event)
>  {
> @@ -76,7 +78,7 @@ static void venus_sys_error_handler(struct work_struct 
> *work)
>   hfi_core_deinit(core, true);
>   hfi_destroy(core);
>   mutex_lock(>lock);
> - venus_shutdown(core->dev);
> + venus_shutdown(core);
>  
>   pm_runtime_put_sync(core->dev);
>  
> @@ -84,7 +86,7 @@ static void venus_sys_error_handler(struct work_struct 
> *work)
>  
>   pm_runtime_get_sync(core->dev);
>  
> - ret |= venus_boot(core->dev, core->res->fwname);
> + ret |= venus_boot(core);
>  
>   ret |= hfi_core_resume(core, true);
>  
> @@ -179,6 +181,20 @@ static u32 to_v4l2_codec_type(u32 codec)
>   }
>  }
>  
> +static int store_firmware_dev(struct device *dev, void *data)
> +{
> + struct venus_core *core;
> +
> + core = (struct venus_core *)data;
> + if (!core)
> + return -EINVAL;
> +
> + if (of_device_is_compatible(dev->of_node, "qcom,venus-pil-no-tz"))
> + core->fw.dev = dev;
> +
> + return 0;
> +}
> +
>  static int venus_enumerate_codecs(struct venus_core *core, u32 type)
>  {
>   const struct hfi_inst_ops dummy_ops = {};
> @@ -229,6 +245,7 @@ static int venus_probe(struct platform_device *pdev)
>   struct device *dev = >dev;
>   struct venus_core *core;
>   struct resource *r;
> + struct iommu_domain *iommu_domain;
>   int ret;
>  
>   core = devm_kzalloc(dev, sizeof(*core), GFP_KERNEL);
> @@ -279,7 +296,14 @@ static int venus_probe(struct platform_device *pdev)
>   if (ret < 0)
>   goto err_runtime_disable;
>  
> - ret = venus_boot(dev, core->res->fwname);
> + ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
> + if (ret)
> + goto err_runtime_disable;
> +
> + /* Attempt to register child devices */

This comment is wrong, the child devices are created by
of_platform_populate above.

> + ret = device_for_each_child(dev, core, store_firmware_dev);

Why we need these complex gymnastics to get struct device pointer when
that could be done in venus_firmware .probe method?

I think the answer is because you want to avoid having venus-firmware.ko
(because you have to have separate struct device for iommu SID). In that
case it would 

Re: [PATCH v2 04/29] venus: hfi_cmds: add set_properties for 4xx version

2018-05-21 Thread Stanimir Varbanov
Hi Tomasz,

On 05/18/2018 05:16 PM, Tomasz Figa wrote:
> On Tue, May 15, 2018 at 5:13 PM Stanimir Varbanov <
> stanimir.varba...@linaro.org> wrote:
> 
>> Adds set_properties method to handle newer 4xx properties and
>> fall-back to 3xx for the rest.
> 
>> Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
>> ---
>>   drivers/media/platform/qcom/venus/hfi_cmds.c | 64
> +++-
>>   1 file changed, 63 insertions(+), 1 deletion(-)
> 
>> diff --git a/drivers/media/platform/qcom/venus/hfi_cmds.c
> b/drivers/media/platform/qcom/venus/hfi_cmds.c
>> index 1cfeb7743041..6bd287154796 100644
>> --- a/drivers/media/platform/qcom/venus/hfi_cmds.c
>> +++ b/drivers/media/platform/qcom/venus/hfi_cmds.c
> 
> [snip]
> 
>> +   case HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE:
>> +   /* not implemented on Venus 4xx */
> 
> Shouldn't return -EINVAL here, similar to what
> pkt_session_set_property_1x() does for unknown property?

Probably the right error code should be ENOTSUPP, but I kind of
following the rule to silently not return the error to simplify the
callers of set_property (otherwise I have to have a version conditional
code in the callers).

> 
>> +   break;
>> +   default:
>> +   ret = pkt_session_set_property_3xx(pkt, cookie, ptype,
> pdata);
>> +   break;
> 
> nit: How about simply return pkt_session_set_property_3xx(pkt, cookie,
> ptype, pdata); and removing the |ret| variable completely, since the return
> below the switch can just return 0 all the time?

OK, I will do that way.

> 
>> +   }
>> +
>> +   return ret;
>> +}
>> +
>>   int pkt_session_get_property(struct hfi_session_get_property_pkt *pkt,
>>   void *cookie, u32 ptype)
>>   {
>> @@ -1181,7 +1240,10 @@ int pkt_session_set_property(struct
> hfi_session_set_property_pkt *pkt,
>>  if (hfi_ver == HFI_VERSION_1XX)
>>  return pkt_session_set_property_1x(pkt, cookie, ptype,
> pdata);
> 
>> -   return pkt_session_set_property_3xx(pkt, cookie, ptype, pdata);
>> +   if (hfi_ver == HFI_VERSION_3XX)
>> +   return pkt_session_set_property_3xx(pkt, cookie, ptype,
> pdata);
>> +
>> +   return pkt_session_set_property_4xx(pkt, cookie, ptype, pdata);
> 
> nit: Since we're adding third variant, I'd consider using function pointers
> here, but no strong opinion.

Let's keep that for future improvements.

-- 
regards,
Stan


Re: [PATCH v2 03/29] venus: hfi: update sequence event to handle more properties

2018-05-21 Thread Stanimir Varbanov
Hi Tomasz,

On 05/18/2018 04:53 PM, Tomasz Figa wrote:
> On Tue, May 15, 2018 at 5:14 PM Stanimir Varbanov <
> stanimir.varba...@linaro.org> wrote:
> 
>> HFI version 4xx can pass more properties in the sequence change
>> event, extend the event structure with them.
> 
>> Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
>> ---
>>   drivers/media/platform/qcom/venus/hfi.h  |  9 ++
>>   drivers/media/platform/qcom/venus/hfi_msgs.c | 46
> 
>>   2 files changed, 55 insertions(+)
> 
>> diff --git a/drivers/media/platform/qcom/venus/hfi.h
> b/drivers/media/platform/qcom/venus/hfi.h
>> index 5466b7d60dd0..21376d93170f 100644
>> --- a/drivers/media/platform/qcom/venus/hfi.h
>> +++ b/drivers/media/platform/qcom/venus/hfi.h
>> @@ -74,6 +74,15 @@ struct hfi_event_data {
>>  u32 tag;
>>  u32 profile;
>>  u32 level;
> 
> nit; Could we add a comment saying that it showed in 4xx?

Sure, I can add a comment.

> 
> [snip]
> 
>> +   case HFI_PROPERTY_CONFIG_VDEC_ENTROPY:
>> +   data_ptr += sizeof(u32);
>> +   entropy_mode = *(u32 *)data_ptr;
>> +   event.entropy_mode = entropy_mode;
> 
> Is the |entropy_mode| local variable necessary?

Isn't GCC smart enough ;) Sure, I can drop entropy_mode local variable.

-- 
regards,
Stan


Re: [PATCH v2 02/29] venus: hfi: preparation to support venus 4xx

2018-05-21 Thread Stanimir Varbanov
Hi Tomasz,

Thanks for the comments!

On 05/18/2018 12:44 PM, Tomasz Figa wrote:
> Hi Stanimir,
> 
> On Tue, May 15, 2018 at 5:14 PM Stanimir Varbanov <
> stanimir.varba...@linaro.org> wrote:
> 
>> This covers the differences between 1xx,3xx and 4xx.
> 
>> Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
>> ---
>>drivers/media/platform/qcom/venus/core.h |  4 ++
>>drivers/media/platform/qcom/venus/helpers.c  | 37 +++
>>drivers/media/platform/qcom/venus/hfi_helper.h   | 84
> ++--
>>drivers/media/platform/qcom/venus/hfi_venus_io.h | 24 +++
>>drivers/media/platform/qcom/venus/vdec.c |  5 +-
>>drivers/media/platform/qcom/venus/venc.c |  5 +-
>>6 files changed, 137 insertions(+), 22 deletions(-)
> 
> Please see my comments inline.
> 
> [snip]
> 
>> @@ -257,12 +273,11 @@ static int load_scale_clocks(struct venus_core
> *core)
> 
>>set_freq:
> 
>> -   if (core->res->hfi_version == HFI_VERSION_3XX) {
>> -   ret = clk_set_rate(clk, freq);
>> +   ret = clk_set_rate(clk, freq);
>> +
>> +   if (IS_V3(core) || IS_V4(core)) {
>>   ret |= clk_set_rate(core->core0_clk, freq);
>>   ret |= clk_set_rate(core->core1_clk, freq);
>> -   } else {
>> -   ret = clk_set_rate(clk, freq);
>>   }
> 
> nit: The clock API defines NULL clock as a special no-op value and so
> clk_set_rate(NULL, ...) would return 0 instantly. Maybe it would just make
> sense to have core0_clk and core1_clk set to NULL for V1 and remove the
> condition here?

OK, we could avoid the condition but I'll add a comment that those
clocks exist from v3 onwards.

> 
>>   if (ret) {
>> diff --git a/drivers/media/platform/qcom/venus/hfi_helper.h
> b/drivers/media/platform/qcom/venus/hfi_helper.h
>> index 55d8eb21403a..1bc5aab1ce6b 100644
>> --- a/drivers/media/platform/qcom/venus/hfi_helper.h
>> +++ b/drivers/media/platform/qcom/venus/hfi_helper.h
>> @@ -121,6 +121,7 @@
>>#define HFI_EXTRADATA_METADATA_FILLER  0x7fe2
> 
>>#define HFI_INDEX_EXTRADATA_INPUT_CROP 0x070e
>> +#define HFI_INDEX_EXTRADATA_OUTPUT_CROP0x070f
> 
> nit: Would it make sense to suffix this _4XX, so that reader could know
> that it was introduced in this version? Similarly for other newly added
> definitions.

I personally don't like the version suffix on defines. Also seems this
is not used in the code, so I'll drop it for now.

> 
>>#define HFI_INDEX_EXTRADATA_DIGITAL_ZOOM   0x0710
>>#define HFI_INDEX_EXTRADATA_ASPECT_RATIO   0x7f13
> 
>> @@ -376,13 +377,18 @@
>>#define HFI_BUFFER_OUTPUT2 0x3
>>#define HFI_BUFFER_INTERNAL_PERSIST0x4
>>#define HFI_BUFFER_INTERNAL_PERSIST_1  0x5
>> -#define HFI_BUFFER_INTERNAL_SCRATCH0x101
>> -#define HFI_BUFFER_EXTRADATA_INPUT 0x102
>> -#define HFI_BUFFER_EXTRADATA_OUTPUT0x103
>> -#define HFI_BUFFER_EXTRADATA_OUTPUT2   0x104
>> -#define HFI_BUFFER_INTERNAL_SCRATCH_1  0x105
>> -#define HFI_BUFFER_INTERNAL_SCRATCH_2  0x106
>> -
>> +#define HFI_BUFFER_INTERNAL_SCRATCH(ver)   \
>> +   (((ver) == HFI_VERSION_4XX) ? 0x6 : 0x101)
>> +#define HFI_BUFFER_INTERNAL_SCRATCH_1(ver) \
>> +   (((ver) == HFI_VERSION_4XX) ? 0x7 : 0x105)
>> +#define HFI_BUFFER_INTERNAL_SCRATCH_2(ver) \
>> +   (((ver) == HFI_VERSION_4XX) ? 0x8 : 0x106)
>> +#define HFI_BUFFER_EXTRADATA_INPUT(ver)\
>> +   (((ver) == HFI_VERSION_4XX) ? 0xc : 0x102)
>> +#define HFI_BUFFER_EXTRADATA_OUTPUT(ver)   \
>> +   (((ver) == HFI_VERSION_4XX) ? 0xa : 0x103)
>> +#define HFI_BUFFER_EXTRADATA_OUTPUT2(ver)  \
>> +   (((ver) == HFI_VERSION_4XX) ? 0xb : 0x104)
> 
> nit: Does it make sense to add an argument, rather than simply defining
> separate HFI_BUFFER_INTERNAL_SCRATCH_1XX and
> HFI_BUFFER_INTERNAL_SCRATCH_4XX? In my subjective opinion, the argument

I'd like to keep the name of the define version agnostic.

> just makes it harder to read, as it's not clear how it is used inside the
> macro from reading just the call to it. Also it would get messy when adding
> further variants in future.
> 
> [snip]
> 
>> +/* HFI 4XX reorder the fields, use these macros */
>> +#define HFI_BUFREQ_HOLD_COUNT(bufreq, ver)   

Re: [PATCH v2 08/29] venus: hfi_venus: fix suspend function for venus 3xx versions

2018-05-21 Thread Stanimir Varbanov
Hi Tomasz,

On 05/18/2018 06:14 PM, Tomasz Figa wrote:
> On Tue, May 15, 2018 at 5:11 PM Stanimir Varbanov <
> stanimir.varba...@linaro.org> wrote:
> 
>> This fixes the suspend function for Venus 3xx versions by
>> add a check for WFI (wait for interrupt) bit. This bit
>> is on when the ARM9 is idle and entered in low power mode.
> 
>> Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
>> ---
>>   drivers/media/platform/qcom/venus/hfi_venus.c| 59
> 
>>   drivers/media/platform/qcom/venus/hfi_venus_io.h |  1 +
>>   2 files changed, 41 insertions(+), 19 deletions(-)
> 
>> diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c
> b/drivers/media/platform/qcom/venus/hfi_venus.c
>> index 53546174aab8..aac351f699a0 100644
>> --- a/drivers/media/platform/qcom/venus/hfi_venus.c
>> +++ b/drivers/media/platform/qcom/venus/hfi_venus.c
>> @@ -1447,7 +1447,7 @@ static int venus_suspend_3xx(struct venus_core
> *core)
>>   {
>>  struct venus_hfi_device *hdev = to_hfi_priv(core);
>>  struct device *dev = core->dev;
>> -   u32 ctrl_status, wfi_status;
>> +   u32 ctrl_status, cpu_status;
>>  int ret;
>>  int cnt = 100;
> 
>> @@ -1463,29 +1463,50 @@ static int venus_suspend_3xx(struct venus_core
> *core)
>>  return -EINVAL;
>>  }
> 
>> -   ctrl_status = venus_readl(hdev, CPU_CS_SCIACMDARG0);
>> -   if (!(ctrl_status & CPU_CS_SCIACMDARG0_PC_READY)) {
>> -   wfi_status = venus_readl(hdev, WRAPPER_CPU_STATUS);
>> +   /*
>> +* Power collapse sequence for Venus 3xx and 4xx versions:
>> +* 1. Check for ARM9 and video core to be idle by checking WFI bit
>> +*(bit 0) in CPU status register and by checking Idle (bit
> 30) in
>> +*Control status register for video core.
>> +* 2. Send a command to prepare for power collapse.
>> +* 3. Check for WFI and PC_READY bits.
>> +*/
>> +
>> +   while (--cnt) {
>> +   cpu_status = venus_readl(hdev, WRAPPER_CPU_STATUS);
>>  ctrl_status = venus_readl(hdev, CPU_CS_SCIACMDARG0);
> 
>> -   ret = venus_prepare_power_collapse(hdev, false);
>> -   if (ret) {
>> -   dev_err(dev, "prepare for power collapse fail
> (%d)\n",
>> -   ret);
>> -   return ret;
>> -   }
>> +   if (cpu_status & WRAPPER_CPU_STATUS_WFI &&
>> +   ctrl_status & CPU_CS_SCIACMDARG0_INIT_IDLE_MSG_MASK)
>> +   break;
> 
>> -   cnt = 100;
>> -   while (cnt--) {
>> -   wfi_status = venus_readl(hdev,
> WRAPPER_CPU_STATUS);
>> -   ctrl_status = venus_readl(hdev,
> CPU_CS_SCIACMDARG0);
>> -   if (ctrl_status & CPU_CS_SCIACMDARG0_PC_READY &&
>> -   wfi_status & BIT(0))
>> -   break;
>> -   usleep_range(1000, 1500);
>> -   }
>> +   usleep_range(1000, 1500);
>>  }
> 
> To avoid opencoding the polling, I'd suggest doing a readx_poll_timeout()
> trick:

I like the idea, will try to rework that and use readx_poll_timeout.



-- 
regards,
Stan


Re: [PATCH v2 07/29] venus: hfi_venus: add halt AXI support for Venus 4xx

2018-05-21 Thread Stanimir Varbanov
Hi Tomasz,

On 05/18/2018 05:23 PM, Tomasz Figa wrote:
> On Tue, May 15, 2018 at 5:12 PM Stanimir Varbanov <
> stanimir.varba...@linaro.org> wrote:
> 
>> Add AXI halt support for version 4xx by using venus wrapper
>> registers.
> 
>> Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
>> ---
>>   drivers/media/platform/qcom/venus/hfi_venus.c | 17 +
>>   1 file changed, 17 insertions(+)
> 
>> diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c
> b/drivers/media/platform/qcom/venus/hfi_venus.c
>> index 734ce11b0ed0..53546174aab8 100644
>> --- a/drivers/media/platform/qcom/venus/hfi_venus.c
>> +++ b/drivers/media/platform/qcom/venus/hfi_venus.c
>> @@ -532,6 +532,23 @@ static int venus_halt_axi(struct venus_hfi_device
> *hdev)
>>  u32 val;
>>  int ret;
> 
>> +   if (hdev->core->res->hfi_version == HFI_VERSION_4XX) {
>> +   val = venus_readl(hdev, WRAPPER_CPU_AXI_HALT);
>> +   val |= BIT(16);
> 
> Can we have the bit defined?
> 
>> +   venus_writel(hdev, WRAPPER_CPU_AXI_HALT, val);
>> +
>> +   ret = readl_poll_timeout(base +
> WRAPPER_CPU_AXI_HALT_STATUS,
>> +val, val & BIT(24),
> 
> Ditto.

Sure will add defines.

-- 
regards,
Stan


[PATCH v3 27/29] venus: implementing multi-stream support

2018-05-18 Thread Stanimir Varbanov
This is implementing multi-stream decoder support. The multi-stream
will be used to enable/disable the primary/secondary decoder
outputs. Depending on formats on both decoder outputs we could
implement downscale, dithering and supporting UBWC (universal
bandwidth compression) formats. The UBWC compressed raw format is
used to optimize interconnect bandwidth for bigger resolutions
like 4K and hence we will get some power-saving benefits as well.

Both decoder outputs are distinguished by buffer_type field in
the HFI packets. For example HFI_BUFFER_OUTPUT is the buffer type
for primary decoder output and HFI_BUFFER_OUTPUT2 is for secondary
decoder output.

Starting from Venus 4xx the DPB buffers format must be UBWC, so
the multi-stream becomes mandatory for this Venus version. That
means that we need to allocate internally in the driver a set of
DPB buffers (with UBWC NV12 format) and give them to the firmware.
The other decoder output (we called it OPB) format will be NV12
linear format and with the same resolution (or smaller in case
the user wants to downscale).

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---

Hi Hans, I have updated patch description a bit. Is it now clearer?

If you have some particular questions I could try to answer and
extend the description.

Also, as Tomasz Figa started to review the patchset I'll postpone
patchset v3 a bit.

 drivers/media/platform/qcom/venus/core.h|   2 +
 drivers/media/platform/qcom/venus/helpers.c | 204 +++-
 drivers/media/platform/qcom/venus/helpers.h |   6 +
 drivers/media/platform/qcom/venus/vdec.c|  93 -
 drivers/media/platform/qcom/venus/venc.c|   1 +
 5 files changed, 302 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/core.h 
b/drivers/media/platform/qcom/venus/core.h
index 1cac8dc79cd1..afa4e49e0e06 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -210,6 +210,7 @@ struct venus_buffer {
  * @list:  used for attach an instance to the core
  * @lock:  instance lock
  * @core:  a reference to the core struct
+ * @dpbbufs:   a list of decoded picture buffers
  * @internalbufs:  a list of internal bufferes
  * @registeredbufs:a list of registered capture bufferes
  * @delayed_processa list of delayed buffers
@@ -259,6 +260,7 @@ struct venus_inst {
struct list_head list;
struct mutex lock;
struct venus_core *core;
+   struct list_head dpbbufs;
struct list_head internalbufs;
struct list_head registeredbufs;
struct list_head delayed_process;
diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index ed569705ecac..87dcf9973e6f 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -85,6 +85,112 @@ bool venus_helper_check_codec(struct venus_inst *inst, u32 
v4l2_pixfmt)
 }
 EXPORT_SYMBOL_GPL(venus_helper_check_codec);
 
+static int venus_helper_queue_dpb_bufs(struct venus_inst *inst)
+{
+   struct intbuf *buf;
+   int ret = 0;
+
+   if (list_empty(>dpbbufs))
+   return 0;
+
+   list_for_each_entry(buf, >dpbbufs, list) {
+   struct hfi_frame_data fdata;
+
+   memset(, 0, sizeof(fdata));
+   fdata.alloc_len = buf->size;
+   fdata.device_addr = buf->da;
+   fdata.buffer_type = buf->type;
+
+   ret = hfi_session_process_buf(inst, );
+   if (ret)
+   goto fail;
+   }
+
+fail:
+   return ret;
+}
+
+int venus_helper_free_dpb_bufs(struct venus_inst *inst)
+{
+   struct intbuf *buf, *n;
+
+   if (list_empty(>dpbbufs))
+   return 0;
+
+   list_for_each_entry_safe(buf, n, >dpbbufs, list) {
+   list_del_init(>list);
+   dma_free_attrs(inst->core->dev, buf->size, buf->va, buf->da,
+  buf->attrs);
+   kfree(buf);
+   }
+
+   INIT_LIST_HEAD(>dpbbufs);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(venus_helper_free_dpb_bufs);
+
+int venus_helper_alloc_dpb_bufs(struct venus_inst *inst)
+{
+   struct venus_core *core = inst->core;
+   struct device *dev = core->dev;
+   enum hfi_version ver = core->res->hfi_version;
+   struct hfi_buffer_requirements bufreq;
+   u32 buftype = inst->dpb_buftype;
+   unsigned int dpb_size = 0;
+   struct intbuf *buf;
+   unsigned int i;
+   u32 count;
+   int ret;
+
+   /* no need to allocate dpb buffers */
+   if (!inst->dpb_fmt)
+   return 0;
+
+   if (inst->dpb_buftype == HFI_BUFFER_OUTPUT)
+   dpb_size = inst->output_buf_size;
+   else if (inst->dpb_buftype == HFI_BUFFER_OUTPUT2)
+   dpb_size = inst->o

Re: [PATCH 01/28] venus: hfi_msgs: correct pointer increment

2018-05-18 Thread Stanimir Varbanov
Hi Tomasz,

Thanks for the review!

On 05/18/2018 11:33 AM, Tomasz Figa wrote:
> Hi Stanimir,
> 
> Thanks for the series. I'll be gradually reviewing subsequent patches. Stay
> tuned. :)
> 

Please consider that there is a v2 of this patchset. :)

> 
> Reviewed-by: Tomasz Figa 
> 

Thanks!

-- 
regards,
Stan


Re: [PATCH v2 27/29] venus: implementing multi-stream support

2018-05-15 Thread Stanimir Varbanov
Hi Hans,

On 05/15/2018 11:17 AM, Hans Verkuil wrote:
> Hi Stanimir,
> 
> On 05/15/18 09:58, Stanimir Varbanov wrote:
>> This is implementing a multi-stream decoder support. The multi
>> stream gives an option to use the secondary decoder output
>> with different raw format (or the same in case of crop).
> 
> You told me that multi-stream support is currently internal only.
> 
> It would be good if you could elaborate a bit about that in this
> commit log and (I think) also add some comments in the code that
> reflect this.
> 
> It's also not clear to me how and why this is used in the driver
> if this is just internal. Does it enable a feature you would
> otherwise not be able to use?
> 
> I have no complaints about the code, I would just like to see a
> bit more background information in the source and commit log.

Thanks for the fast comments! Sure I will try to document multi-stream
support in the patch description and in the code if it makes sense.

-- 
regards,
Stan


[PATCH v2 00/29] Venus updates

2018-05-15 Thread Stanimir Varbanov
Hello,

Here is v2 with following comments addressed:

* reworked venus suspend 3xx and reuse it for 4xx.
* drop 10/28 patch from v1, i.e. call of session_continue when
  buffer requirements are not sufficient.
* fixed kbuild test robot warning in 11/28 by allocating instance
  variable from heap.
* spelling typo in 15/28.
* added Reviewed-by for DT changes.
* extended 28/28 HEVC support for encoder, now the profile and
  level are selected properly.

Comments are welcome!

regards,
Stan

Stanimir Varbanov (29):
  venus: hfi_msgs: correct pointer increment
  venus: hfi: preparation to support venus 4xx
  venus: hfi: update sequence event to handle more properties
  venus: hfi_cmds: add set_properties for 4xx version
  venus: hfi: support session continue for 4xx version
  venus: hfi: handle buffer output2 type as well
  venus: hfi_venus: add halt AXI support for Venus 4xx
  venus: hfi_venus: fix suspend function for venus 3xx versions
  venus: hfi_venus: move set of default properties to core init
  venus: hfi_venus: add suspend functionality for Venus 4xx
  venus: venc,vdec: adds clocks needed for venus 4xx
  venus: add common capability parser
  venus: helpers: make a commmon function for power_enable
  venus: core: delete not used flag for buffer mode
  venus: helpers: rename a helper function and use buffer mode from caps
  venus: add a helper function to set dynamic buffer mode
  venus: add helper function to set actual buffer size
  venus: delete no longer used bufmode flag from instance
  venus: helpers: add buffer type argument to a helper
  venus: helpers: add a new helper to set raw format
  venus: helpers,vdec,venc: add helpers to set work mode and core usage
  venus: helpers: extend set_num_bufs helper with one more argument
  venus: helpers: add a helper to return opb buffer sizes
  venus: vdec: get required input buffers as well
  venus: vdec: new function for output configuration
  venus: move frame size calculations in common place
  venus: implementing multi-stream support
  venus: add sdm845 compatible and resource data
  venus: add HEVC codec support

 .../devicetree/bindings/media/qcom,venus.txt   |   1 +
 drivers/media/platform/qcom/venus/Makefile |   3 +-
 drivers/media/platform/qcom/venus/core.c   | 107 
 drivers/media/platform/qcom/venus/core.h   |  93 ++--
 drivers/media/platform/qcom/venus/helpers.c| 558 +++--
 drivers/media/platform/qcom/venus/helpers.h|  23 +-
 drivers/media/platform/qcom/venus/hfi.c|  12 +-
 drivers/media/platform/qcom/venus/hfi.h|   9 +
 drivers/media/platform/qcom/venus/hfi_cmds.c   |  64 ++-
 drivers/media/platform/qcom/venus/hfi_helper.h | 112 -
 drivers/media/platform/qcom/venus/hfi_msgs.c   | 401 +++
 drivers/media/platform/qcom/venus/hfi_parser.c | 291 +++
 drivers/media/platform/qcom/venus/hfi_parser.h |  45 ++
 drivers/media/platform/qcom/venus/hfi_venus.c  |  95 +++-
 drivers/media/platform/qcom/venus/hfi_venus_io.h   |  25 +
 drivers/media/platform/qcom/venus/vdec.c   | 316 +++-
 drivers/media/platform/qcom/venus/venc.c   | 211 
 17 files changed, 1689 insertions(+), 677 deletions(-)
 create mode 100644 drivers/media/platform/qcom/venus/hfi_parser.c
 create mode 100644 drivers/media/platform/qcom/venus/hfi_parser.h

-- 
2.14.1



[PATCH v2 03/29] venus: hfi: update sequence event to handle more properties

2018-05-15 Thread Stanimir Varbanov
HFI version 4xx can pass more properties in the sequence change
event, extend the event structure with them.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/hfi.h  |  9 ++
 drivers/media/platform/qcom/venus/hfi_msgs.c | 46 
 2 files changed, 55 insertions(+)

diff --git a/drivers/media/platform/qcom/venus/hfi.h 
b/drivers/media/platform/qcom/venus/hfi.h
index 5466b7d60dd0..21376d93170f 100644
--- a/drivers/media/platform/qcom/venus/hfi.h
+++ b/drivers/media/platform/qcom/venus/hfi.h
@@ -74,6 +74,15 @@ struct hfi_event_data {
u32 tag;
u32 profile;
u32 level;
+   u32 bit_depth;
+   u32 pic_struct;
+   u32 colour_space;
+   u32 entropy_mode;
+   u32 buf_count;
+   struct {
+   u32 left, top;
+   u32 width, height;
+   } input_crop;
 };
 
 /* define core states */
diff --git a/drivers/media/platform/qcom/venus/hfi_msgs.c 
b/drivers/media/platform/qcom/venus/hfi_msgs.c
index 589e1a6b36a9..5970e9b1716b 100644
--- a/drivers/media/platform/qcom/venus/hfi_msgs.c
+++ b/drivers/media/platform/qcom/venus/hfi_msgs.c
@@ -25,10 +25,17 @@
 static void event_seq_changed(struct venus_core *core, struct venus_inst *inst,
  struct hfi_msg_event_notify_pkt *pkt)
 {
+   enum hfi_version ver = core->res->hfi_version;
struct hfi_event_data event = {0};
int num_properties_changed;
struct hfi_framesize *frame_sz;
struct hfi_profile_level *profile_level;
+   struct hfi_bit_depth *pixel_depth;
+   struct hfi_pic_struct *pic_struct;
+   struct hfi_colour_space *colour_info;
+   struct hfi_buffer_requirements *bufreq;
+   struct hfi_extradata_input_crop *crop;
+   u32 entropy_mode = 0;
u8 *data_ptr;
u32 ptype;
 
@@ -69,6 +76,45 @@ static void event_seq_changed(struct venus_core *core, 
struct venus_inst *inst,
event.level = profile_level->level;
data_ptr += sizeof(*profile_level);
break;
+   case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH:
+   data_ptr += sizeof(u32);
+   pixel_depth = (struct hfi_bit_depth *)data_ptr;
+   event.bit_depth = pixel_depth->bit_depth;
+   data_ptr += sizeof(*pixel_depth);
+   break;
+   case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT:
+   data_ptr += sizeof(u32);
+   pic_struct = (struct hfi_pic_struct *)data_ptr;
+   event.pic_struct = pic_struct->progressive_only;
+   data_ptr += sizeof(*pic_struct);
+   break;
+   case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE:
+   data_ptr += sizeof(u32);
+   colour_info = (struct hfi_colour_space *)data_ptr;
+   event.colour_space = colour_info->colour_space;
+   data_ptr += sizeof(*colour_info);
+   break;
+   case HFI_PROPERTY_CONFIG_VDEC_ENTROPY:
+   data_ptr += sizeof(u32);
+   entropy_mode = *(u32 *)data_ptr;
+   event.entropy_mode = entropy_mode;
+   data_ptr += sizeof(u32);
+   break;
+   case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:
+   data_ptr += sizeof(u32);
+   bufreq = (struct hfi_buffer_requirements *)data_ptr;
+   event.buf_count = HFI_BUFREQ_COUNT_MIN(bufreq, ver);
+   data_ptr += sizeof(*bufreq);
+   break;
+   case HFI_INDEX_EXTRADATA_INPUT_CROP:
+   data_ptr += sizeof(u32);
+   crop = (struct hfi_extradata_input_crop *)data_ptr;
+   event.input_crop.left = crop->left;
+   event.input_crop.top = crop->top;
+   event.input_crop.width = crop->width;
+   event.input_crop.height = crop->height;
+   data_ptr += sizeof(*crop);
+   break;
default:
break;
}
-- 
2.14.1



[PATCH v2 02/29] venus: hfi: preparation to support venus 4xx

2018-05-15 Thread Stanimir Varbanov
This covers the differences between 1xx,3xx and 4xx.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/core.h |  4 ++
 drivers/media/platform/qcom/venus/helpers.c  | 37 +++
 drivers/media/platform/qcom/venus/hfi_helper.h   | 84 ++--
 drivers/media/platform/qcom/venus/hfi_venus_io.h | 24 +++
 drivers/media/platform/qcom/venus/vdec.c |  5 +-
 drivers/media/platform/qcom/venus/venc.c |  5 +-
 6 files changed, 137 insertions(+), 22 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/core.h 
b/drivers/media/platform/qcom/venus/core.h
index 0360d295f4c8..8d3e150800c9 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -305,6 +305,10 @@ struct venus_inst {
struct hfi_buffer_requirements bufreq[HFI_BUFFER_TYPE_MAX];
 };
 
+#define IS_V1(core)((core)->res->hfi_version == HFI_VERSION_1XX)
+#define IS_V3(core)((core)->res->hfi_version == HFI_VERSION_3XX)
+#define IS_V4(core)((core)->res->hfi_version == HFI_VERSION_4XX)
+
 #define ctrl_to_inst(ctrl) \
container_of((ctrl)->handler, struct venus_inst, ctrl_handler)
 
diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index 0ce9559a2924..d9065cc8a7d3 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -166,21 +166,37 @@ static int intbufs_unset_buffers(struct venus_inst *inst)
return ret;
 }
 
-static const unsigned int intbuf_types[] = {
-   HFI_BUFFER_INTERNAL_SCRATCH,
-   HFI_BUFFER_INTERNAL_SCRATCH_1,
-   HFI_BUFFER_INTERNAL_SCRATCH_2,
+static const unsigned int intbuf_types_1xx[] = {
+   HFI_BUFFER_INTERNAL_SCRATCH(HFI_VERSION_1XX),
+   HFI_BUFFER_INTERNAL_SCRATCH_1(HFI_VERSION_1XX),
+   HFI_BUFFER_INTERNAL_SCRATCH_2(HFI_VERSION_1XX),
+   HFI_BUFFER_INTERNAL_PERSIST,
+   HFI_BUFFER_INTERNAL_PERSIST_1,
+};
+
+static const unsigned int intbuf_types_4xx[] = {
+   HFI_BUFFER_INTERNAL_SCRATCH(HFI_VERSION_4XX),
+   HFI_BUFFER_INTERNAL_SCRATCH_1(HFI_VERSION_4XX),
+   HFI_BUFFER_INTERNAL_SCRATCH_2(HFI_VERSION_4XX),
HFI_BUFFER_INTERNAL_PERSIST,
HFI_BUFFER_INTERNAL_PERSIST_1,
 };
 
 static int intbufs_alloc(struct venus_inst *inst)
 {
-   unsigned int i;
+   size_t arr_sz;
+   size_t i;
int ret;
 
-   for (i = 0; i < ARRAY_SIZE(intbuf_types); i++) {
-   ret = intbufs_set_buffer(inst, intbuf_types[i]);
+   if (IS_V4(inst->core))
+   arr_sz = ARRAY_SIZE(intbuf_types_4xx);
+   else
+   arr_sz = ARRAY_SIZE(intbuf_types_1xx);
+
+   for (i = 0; i < arr_sz; i++) {
+   ret = intbufs_set_buffer(inst,
+   IS_V4(inst->core) ? intbuf_types_4xx[i] :
+   intbuf_types_1xx[i]);
if (ret)
goto error;
}
@@ -257,12 +273,11 @@ static int load_scale_clocks(struct venus_core *core)
 
 set_freq:
 
-   if (core->res->hfi_version == HFI_VERSION_3XX) {
-   ret = clk_set_rate(clk, freq);
+   ret = clk_set_rate(clk, freq);
+
+   if (IS_V3(core) || IS_V4(core)) {
ret |= clk_set_rate(core->core0_clk, freq);
ret |= clk_set_rate(core->core1_clk, freq);
-   } else {
-   ret = clk_set_rate(clk, freq);
}
 
if (ret) {
diff --git a/drivers/media/platform/qcom/venus/hfi_helper.h 
b/drivers/media/platform/qcom/venus/hfi_helper.h
index 55d8eb21403a..1bc5aab1ce6b 100644
--- a/drivers/media/platform/qcom/venus/hfi_helper.h
+++ b/drivers/media/platform/qcom/venus/hfi_helper.h
@@ -121,6 +121,7 @@
 #define HFI_EXTRADATA_METADATA_FILLER  0x7fe2
 
 #define HFI_INDEX_EXTRADATA_INPUT_CROP 0x070e
+#define HFI_INDEX_EXTRADATA_OUTPUT_CROP0x070f
 #define HFI_INDEX_EXTRADATA_DIGITAL_ZOOM   0x0710
 #define HFI_INDEX_EXTRADATA_ASPECT_RATIO   0x7f13
 
@@ -376,13 +377,18 @@
 #define HFI_BUFFER_OUTPUT2 0x3
 #define HFI_BUFFER_INTERNAL_PERSIST0x4
 #define HFI_BUFFER_INTERNAL_PERSIST_1  0x5
-#define HFI_BUFFER_INTERNAL_SCRATCH0x101
-#define HFI_BUFFER_EXTRADATA_INPUT 0x102
-#define HFI_BUFFER_EXTRADATA_OUTPUT0x103
-#define HFI_BUFFER_EXTRADATA_OUTPUT2   0x104
-#define HFI_BUFFER_INTERNAL_SCRATCH_1  0x105
-#define HFI_BUFFER_INTERNAL_SCRATCH_2  0x106
-
+#define HFI_BUFFER_INTERNAL_SCRATCH(ver)   \
+   (((ver) == HFI_VERSION_4XX) ? 0x6 : 0x101)
+#define HFI_BUFFER_INTERNAL_SCRATCH_1(ver) \
+   (((ver) == HFI_VERSION_4XX) ? 0x7 : 0x105)
+#define HFI_BUFFER_INTERNAL_SCRATCH_2(v

[PATCH v2 01/29] venus: hfi_msgs: correct pointer increment

2018-05-15 Thread Stanimir Varbanov
Data pointer should be incremented by size of the structure not
the size of a pointer, correct the mistake.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/hfi_msgs.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/hfi_msgs.c 
b/drivers/media/platform/qcom/venus/hfi_msgs.c
index 90c93d9603dc..589e1a6b36a9 100644
--- a/drivers/media/platform/qcom/venus/hfi_msgs.c
+++ b/drivers/media/platform/qcom/venus/hfi_msgs.c
@@ -60,14 +60,14 @@ static void event_seq_changed(struct venus_core *core, 
struct venus_inst *inst,
frame_sz = (struct hfi_framesize *)data_ptr;
event.width = frame_sz->width;
event.height = frame_sz->height;
-   data_ptr += sizeof(frame_sz);
+   data_ptr += sizeof(*frame_sz);
break;
case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT:
data_ptr += sizeof(u32);
profile_level = (struct hfi_profile_level *)data_ptr;
event.profile = profile_level->profile;
event.level = profile_level->level;
-   data_ptr += sizeof(profile_level);
+   data_ptr += sizeof(*profile_level);
break;
default:
break;
-- 
2.14.1



[PATCH v2 04/29] venus: hfi_cmds: add set_properties for 4xx version

2018-05-15 Thread Stanimir Varbanov
Adds set_properties method to handle newer 4xx properties and
fall-back to 3xx for the rest.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/hfi_cmds.c | 64 +++-
 1 file changed, 63 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/qcom/venus/hfi_cmds.c 
b/drivers/media/platform/qcom/venus/hfi_cmds.c
index 1cfeb7743041..6bd287154796 100644
--- a/drivers/media/platform/qcom/venus/hfi_cmds.c
+++ b/drivers/media/platform/qcom/venus/hfi_cmds.c
@@ -1166,6 +1166,65 @@ pkt_session_set_property_3xx(struct 
hfi_session_set_property_pkt *pkt,
return ret;
 }
 
+static int
+pkt_session_set_property_4xx(struct hfi_session_set_property_pkt *pkt,
+void *cookie, u32 ptype, void *pdata)
+{
+   void *prop_data;
+   int ret = 0;
+
+   if (!pkt || !cookie || !pdata)
+   return -EINVAL;
+
+   prop_data = >data[1];
+
+   pkt->shdr.hdr.size = sizeof(*pkt);
+   pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_SET_PROPERTY;
+   pkt->shdr.session_id = hash32_ptr(cookie);
+   pkt->num_properties = 1;
+   pkt->data[0] = ptype;
+
+   /*
+* Any session set property which is different in 3XX packetization
+* should be added as a new case below. All unchanged session set
+* properties will be handled in the default case.
+*/
+   switch (ptype) {
+   case HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL: {
+   struct hfi_buffer_count_actual *in = pdata;
+   struct hfi_buffer_count_actual_4xx *count = prop_data;
+
+   count->count_actual = in->count_actual;
+   count->type = in->type;
+   count->count_min_host = in->count_actual;
+   pkt->shdr.hdr.size += sizeof(u32) + sizeof(*count);
+   break;
+   }
+   case HFI_PROPERTY_PARAM_WORK_MODE: {
+   struct hfi_video_work_mode *in = pdata, *wm = prop_data;
+
+   wm->video_work_mode = in->video_work_mode;
+   pkt->shdr.hdr.size += sizeof(u32) + sizeof(*wm);
+   break;
+   }
+   case HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE: {
+   struct hfi_videocores_usage_type *in = pdata, *cu = prop_data;
+
+   cu->video_core_enable_mask = in->video_core_enable_mask;
+   pkt->shdr.hdr.size += sizeof(u32) + sizeof(*cu);
+   break;
+   }
+   case HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE:
+   /* not implemented on Venus 4xx */
+   break;
+   default:
+   ret = pkt_session_set_property_3xx(pkt, cookie, ptype, pdata);
+   break;
+   }
+
+   return ret;
+}
+
 int pkt_session_get_property(struct hfi_session_get_property_pkt *pkt,
 void *cookie, u32 ptype)
 {
@@ -1181,7 +1240,10 @@ int pkt_session_set_property(struct 
hfi_session_set_property_pkt *pkt,
if (hfi_ver == HFI_VERSION_1XX)
return pkt_session_set_property_1x(pkt, cookie, ptype, pdata);
 
-   return pkt_session_set_property_3xx(pkt, cookie, ptype, pdata);
+   if (hfi_ver == HFI_VERSION_3XX)
+   return pkt_session_set_property_3xx(pkt, cookie, ptype, pdata);
+
+   return pkt_session_set_property_4xx(pkt, cookie, ptype, pdata);
 }
 
 void pkt_set_version(enum hfi_version version)
-- 
2.14.1



[PATCH v2 06/29] venus: hfi: handle buffer output2 type as well

2018-05-15 Thread Stanimir Varbanov
This adds handling of buffers of type OUTPUT2 which is needed to
support Venus 4xx version.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/hfi.c  | 3 ++-
 drivers/media/platform/qcom/venus/hfi_msgs.c | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/hfi.c 
b/drivers/media/platform/qcom/venus/hfi.c
index cbc6fad05e47..a570fdad0de0 100644
--- a/drivers/media/platform/qcom/venus/hfi.c
+++ b/drivers/media/platform/qcom/venus/hfi.c
@@ -473,7 +473,8 @@ int hfi_session_process_buf(struct venus_inst *inst, struct 
hfi_frame_data *fd)
 
if (fd->buffer_type == HFI_BUFFER_INPUT)
return ops->session_etb(inst, fd);
-   else if (fd->buffer_type == HFI_BUFFER_OUTPUT)
+   else if (fd->buffer_type == HFI_BUFFER_OUTPUT ||
+fd->buffer_type == HFI_BUFFER_OUTPUT2)
return ops->session_ftb(inst, fd);
 
return -EINVAL;
diff --git a/drivers/media/platform/qcom/venus/hfi_msgs.c 
b/drivers/media/platform/qcom/venus/hfi_msgs.c
index 5970e9b1716b..023802e62833 100644
--- a/drivers/media/platform/qcom/venus/hfi_msgs.c
+++ b/drivers/media/platform/qcom/venus/hfi_msgs.c
@@ -825,7 +825,8 @@ static void hfi_session_ftb_done(struct venus_core *core,
error = HFI_ERR_SESSION_INVALID_PARAMETER;
}
 
-   if (buffer_type != HFI_BUFFER_OUTPUT)
+   if (buffer_type != HFI_BUFFER_OUTPUT &&
+   buffer_type != HFI_BUFFER_OUTPUT2)
goto done;
 
if (hfi_flags & HFI_BUFFERFLAG_EOS)
-- 
2.14.1



[PATCH v2 07/29] venus: hfi_venus: add halt AXI support for Venus 4xx

2018-05-15 Thread Stanimir Varbanov
Add AXI halt support for version 4xx by using venus wrapper
registers.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/hfi_venus.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c 
b/drivers/media/platform/qcom/venus/hfi_venus.c
index 734ce11b0ed0..53546174aab8 100644
--- a/drivers/media/platform/qcom/venus/hfi_venus.c
+++ b/drivers/media/platform/qcom/venus/hfi_venus.c
@@ -532,6 +532,23 @@ static int venus_halt_axi(struct venus_hfi_device *hdev)
u32 val;
int ret;
 
+   if (hdev->core->res->hfi_version == HFI_VERSION_4XX) {
+   val = venus_readl(hdev, WRAPPER_CPU_AXI_HALT);
+   val |= BIT(16);
+   venus_writel(hdev, WRAPPER_CPU_AXI_HALT, val);
+
+   ret = readl_poll_timeout(base + WRAPPER_CPU_AXI_HALT_STATUS,
+val, val & BIT(24),
+POLL_INTERVAL_US,
+VBIF_AXI_HALT_ACK_TIMEOUT_US);
+   if (ret) {
+   dev_err(dev, "AXI bus port halt timeout\n");
+   return ret;
+   }
+
+   return 0;
+   }
+
/* Halt AXI and AXI IMEM VBIF Access */
val = venus_readl(hdev, VBIF_AXI_HALT_CTRL0);
val |= VBIF_AXI_HALT_CTRL0_HALT_REQ;
-- 
2.14.1



[PATCH v2 05/29] venus: hfi: support session continue for 4xx version

2018-05-15 Thread Stanimir Varbanov
This makes possible to handle session_continue for 4xx as well.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/hfi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/qcom/venus/hfi.c 
b/drivers/media/platform/qcom/venus/hfi.c
index bca894a00c07..cbc6fad05e47 100644
--- a/drivers/media/platform/qcom/venus/hfi.c
+++ b/drivers/media/platform/qcom/venus/hfi.c
@@ -312,7 +312,7 @@ int hfi_session_continue(struct venus_inst *inst)
 {
struct venus_core *core = inst->core;
 
-   if (core->res->hfi_version != HFI_VERSION_3XX)
+   if (core->res->hfi_version == HFI_VERSION_1XX)
return 0;
 
return core->ops->session_continue(inst);
-- 
2.14.1



[PATCH v2 09/29] venus: hfi_venus: move set of default properties to core init

2018-05-15 Thread Stanimir Varbanov
This moves setting of default properties (firmware debug, idle
indicator and low power mode) from session init to core init.
All of those properties are need to be enabled/disabled early
so that they could be used before the clients are even initialized.

The other reason is to set idle indicator property early before
we enter into venus_suspend function where we need to check for
ARM9 WFI.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/hfi_venus.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c 
b/drivers/media/platform/qcom/venus/hfi_venus.c
index aac351f699a0..284da69eb81b 100644
--- a/drivers/media/platform/qcom/venus/hfi_venus.c
+++ b/drivers/media/platform/qcom/venus/hfi_venus.c
@@ -1090,6 +1090,10 @@ static int venus_core_init(struct venus_core *core)
if (ret)
dev_warn(dev, "failed to send image version pkt to fw\n");
 
+   ret = venus_sys_set_default_properties(hdev);
+   if (ret)
+   return ret;
+
return 0;
 }
 
@@ -1134,10 +1138,6 @@ static int venus_session_init(struct venus_inst *inst, 
u32 session_type,
struct hfi_session_init_pkt pkt;
int ret;
 
-   ret = venus_sys_set_default_properties(hdev);
-   if (ret)
-   return ret;
-
ret = pkt_session_init(, inst, session_type, codec);
if (ret)
goto err;
-- 
2.14.1



[PATCH v2 08/29] venus: hfi_venus: fix suspend function for venus 3xx versions

2018-05-15 Thread Stanimir Varbanov
This fixes the suspend function for Venus 3xx versions by
add a check for WFI (wait for interrupt) bit. This bit
is on when the ARM9 is idle and entered in low power mode.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/hfi_venus.c| 59 
 drivers/media/platform/qcom/venus/hfi_venus_io.h |  1 +
 2 files changed, 41 insertions(+), 19 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c 
b/drivers/media/platform/qcom/venus/hfi_venus.c
index 53546174aab8..aac351f699a0 100644
--- a/drivers/media/platform/qcom/venus/hfi_venus.c
+++ b/drivers/media/platform/qcom/venus/hfi_venus.c
@@ -1447,7 +1447,7 @@ static int venus_suspend_3xx(struct venus_core *core)
 {
struct venus_hfi_device *hdev = to_hfi_priv(core);
struct device *dev = core->dev;
-   u32 ctrl_status, wfi_status;
+   u32 ctrl_status, cpu_status;
int ret;
int cnt = 100;
 
@@ -1463,29 +1463,50 @@ static int venus_suspend_3xx(struct venus_core *core)
return -EINVAL;
}
 
-   ctrl_status = venus_readl(hdev, CPU_CS_SCIACMDARG0);
-   if (!(ctrl_status & CPU_CS_SCIACMDARG0_PC_READY)) {
-   wfi_status = venus_readl(hdev, WRAPPER_CPU_STATUS);
+   /*
+* Power collapse sequence for Venus 3xx and 4xx versions:
+* 1. Check for ARM9 and video core to be idle by checking WFI bit
+*(bit 0) in CPU status register and by checking Idle (bit 30) in
+*Control status register for video core.
+* 2. Send a command to prepare for power collapse.
+* 3. Check for WFI and PC_READY bits.
+*/
+
+   while (--cnt) {
+   cpu_status = venus_readl(hdev, WRAPPER_CPU_STATUS);
ctrl_status = venus_readl(hdev, CPU_CS_SCIACMDARG0);
 
-   ret = venus_prepare_power_collapse(hdev, false);
-   if (ret) {
-   dev_err(dev, "prepare for power collapse fail (%d)\n",
-   ret);
-   return ret;
-   }
+   if (cpu_status & WRAPPER_CPU_STATUS_WFI &&
+   ctrl_status & CPU_CS_SCIACMDARG0_INIT_IDLE_MSG_MASK)
+   break;
 
-   cnt = 100;
-   while (cnt--) {
-   wfi_status = venus_readl(hdev, WRAPPER_CPU_STATUS);
-   ctrl_status = venus_readl(hdev, CPU_CS_SCIACMDARG0);
-   if (ctrl_status & CPU_CS_SCIACMDARG0_PC_READY &&
-   wfi_status & BIT(0))
-   break;
-   usleep_range(1000, 1500);
-   }
+   usleep_range(1000, 1500);
}
 
+   if (!cnt)
+   return -ETIMEDOUT;
+
+   ret = venus_prepare_power_collapse(hdev, false);
+   if (ret) {
+   dev_err(dev, "prepare for power collapse fail (%d)\n", ret);
+   return ret;
+   }
+
+   cnt = 100;
+   while (--cnt) {
+   cpu_status = venus_readl(hdev, WRAPPER_CPU_STATUS);
+   ctrl_status = venus_readl(hdev, CPU_CS_SCIACMDARG0);
+
+   if (cpu_status & WRAPPER_CPU_STATUS_WFI &&
+   ctrl_status & CPU_CS_SCIACMDARG0_PC_READY)
+   break;
+
+   usleep_range(1000, 1500);
+   }
+
+   if (!cnt)
+   return -ETIMEDOUT;
+
mutex_lock(>lock);
 
ret = venus_power_off(hdev);
diff --git a/drivers/media/platform/qcom/venus/hfi_venus_io.h 
b/drivers/media/platform/qcom/venus/hfi_venus_io.h
index 76f47936d0fa..12e3d33a3d82 100644
--- a/drivers/media/platform/qcom/venus/hfi_venus_io.h
+++ b/drivers/media/platform/qcom/venus/hfi_venus_io.h
@@ -108,6 +108,7 @@
 
 #define WRAPPER_CPU_CGC_DIS(WRAPPER_BASE + 0x2010)
 #define WRAPPER_CPU_STATUS (WRAPPER_BASE + 0x2014)
+#define WRAPPER_CPU_STATUS_WFI BIT(0)
 #define WRAPPER_SW_RESET   (WRAPPER_BASE + 0x3000)
 
 /* Venus 4xx */
-- 
2.14.1



[PATCH v2 11/29] venus: venc,vdec: adds clocks needed for venus 4xx

2018-05-15 Thread Stanimir Varbanov
This extends the clocks number to support suspend and resume
on Venus version 4xx.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/core.h |  4 +--
 drivers/media/platform/qcom/venus/vdec.c | 42 ++--
 drivers/media/platform/qcom/venus/venc.c | 42 ++--
 3 files changed, 72 insertions(+), 16 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/core.h 
b/drivers/media/platform/qcom/venus/core.h
index 8d3e150800c9..b5b9a84e9155 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -92,8 +92,8 @@ struct venus_core {
void __iomem *base;
int irq;
struct clk *clks[VIDC_CLKS_NUM_MAX];
-   struct clk *core0_clk;
-   struct clk *core1_clk;
+   struct clk *core0_clk, *core0_bus_clk;
+   struct clk *core1_clk, *core1_bus_clk;
struct video_device *vdev_dec;
struct video_device *vdev_enc;
struct v4l2_device v4l2_dev;
diff --git a/drivers/media/platform/qcom/venus/vdec.c 
b/drivers/media/platform/qcom/venus/vdec.c
index 261a51adeef2..c45452634e7e 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -1081,12 +1081,18 @@ static int vdec_probe(struct platform_device *pdev)
if (!core)
return -EPROBE_DEFER;
 
-   if (core->res->hfi_version == HFI_VERSION_3XX) {
+   if (IS_V3(core) || IS_V4(core)) {
core->core0_clk = devm_clk_get(dev, "core");
if (IS_ERR(core->core0_clk))
return PTR_ERR(core->core0_clk);
}
 
+   if (IS_V4(core)) {
+   core->core0_bus_clk = devm_clk_get(dev, "bus");
+   if (IS_ERR(core->core0_bus_clk))
+   return PTR_ERR(core->core0_bus_clk);
+   }
+
platform_set_drvdata(pdev, core);
 
vdev = video_device_alloc();
@@ -1132,12 +1138,23 @@ static __maybe_unused int vdec_runtime_suspend(struct 
device *dev)
 {
struct venus_core *core = dev_get_drvdata(dev);
 
-   if (core->res->hfi_version == HFI_VERSION_1XX)
+   if (IS_V1(core))
return 0;
 
-   writel(0, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
+   if (IS_V3(core))
+   writel(0, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
+   else if (IS_V4(core))
+   writel(0, core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL);
+
+   if (IS_V4(core))
+   clk_disable_unprepare(core->core0_bus_clk);
+
clk_disable_unprepare(core->core0_clk);
-   writel(1, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
+
+   if (IS_V3(core))
+   writel(1, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
+   else if (IS_V4(core))
+   writel(1, core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL);
 
return 0;
 }
@@ -1147,12 +1164,23 @@ static __maybe_unused int vdec_runtime_resume(struct 
device *dev)
struct venus_core *core = dev_get_drvdata(dev);
int ret;
 
-   if (core->res->hfi_version == HFI_VERSION_1XX)
+   if (IS_V1(core))
return 0;
 
-   writel(0, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
+   if (IS_V3(core))
+   writel(0, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
+   else if (IS_V4(core))
+   writel(0, core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL);
+
ret = clk_prepare_enable(core->core0_clk);
-   writel(1, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
+
+   if (IS_V4(core))
+   ret |= clk_prepare_enable(core->core0_bus_clk);
+
+   if (IS_V3(core))
+   writel(1, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
+   else if (IS_V4(core))
+   writel(1, core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL);
 
return ret;
 }
diff --git a/drivers/media/platform/qcom/venus/venc.c 
b/drivers/media/platform/qcom/venus/venc.c
index 947001170a77..bc8c2e7a8d2c 100644
--- a/drivers/media/platform/qcom/venus/venc.c
+++ b/drivers/media/platform/qcom/venus/venc.c
@@ -1225,12 +1225,18 @@ static int venc_probe(struct platform_device *pdev)
if (!core)
return -EPROBE_DEFER;
 
-   if (core->res->hfi_version == HFI_VERSION_3XX) {
+   if (IS_V3(core) || IS_V4(core)) {
core->core1_clk = devm_clk_get(dev, "core");
if (IS_ERR(core->core1_clk))
return PTR_ERR(core->core1_clk);
}
 
+   if (IS_V4(core)) {
+   core->core1_bus_clk = devm_clk_get(dev, "bus");
+   if (IS_ERR(core->core1_bus_clk))
+   return PTR_ERR(core->core1_bus_clk);
+   }
+
platform_set_drvdata(pdev, core);
 
   

[PATCH v2 19/29] venus: helpers: add buffer type argument to a helper

2018-05-15 Thread Stanimir Varbanov
This adds one more function argument to pass buffer type to
set_output_resolution() helper function. That is a preparation
to support secondary decoder output.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/helpers.c | 5 +++--
 drivers/media/platform/qcom/venus/helpers.h | 3 ++-
 drivers/media/platform/qcom/venus/venc.c| 3 ++-
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index 94664a3ce3e2..5512fbfdebb9 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -456,12 +456,13 @@ int venus_helper_set_input_resolution(struct venus_inst 
*inst,
 EXPORT_SYMBOL_GPL(venus_helper_set_input_resolution);
 
 int venus_helper_set_output_resolution(struct venus_inst *inst,
-  unsigned int width, unsigned int height)
+  unsigned int width, unsigned int height,
+  u32 buftype)
 {
u32 ptype = HFI_PROPERTY_PARAM_FRAME_SIZE;
struct hfi_framesize fs;
 
-   fs.buffer_type = HFI_BUFFER_OUTPUT;
+   fs.buffer_type = buftype;
fs.width = width;
fs.height = height;
 
diff --git a/drivers/media/platform/qcom/venus/helpers.h 
b/drivers/media/platform/qcom/venus/helpers.h
index cd306bd8978f..0de9989adcdb 100644
--- a/drivers/media/platform/qcom/venus/helpers.h
+++ b/drivers/media/platform/qcom/venus/helpers.h
@@ -36,7 +36,8 @@ int venus_helper_get_bufreq(struct venus_inst *inst, u32 type,
 int venus_helper_set_input_resolution(struct venus_inst *inst,
  unsigned int width, unsigned int height);
 int venus_helper_set_output_resolution(struct venus_inst *inst,
-  unsigned int width, unsigned int height);
+  unsigned int width, unsigned int height,
+  u32 buftype);
 int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs,
  unsigned int output_bufs);
 int venus_helper_set_color_format(struct venus_inst *inst, u32 fmt);
diff --git a/drivers/media/platform/qcom/venus/venc.c 
b/drivers/media/platform/qcom/venus/venc.c
index f87d891325ea..8970f14b3a82 100644
--- a/drivers/media/platform/qcom/venus/venc.c
+++ b/drivers/media/platform/qcom/venus/venc.c
@@ -795,7 +795,8 @@ static int venc_init_session(struct venus_inst *inst)
goto deinit;
 
ret = venus_helper_set_output_resolution(inst, inst->width,
-inst->height);
+inst->height,
+HFI_BUFFER_OUTPUT);
if (ret)
goto deinit;
 
-- 
2.14.1



[PATCH v2 18/29] venus: delete no longer used bufmode flag from instance

2018-05-15 Thread Stanimir Varbanov
Delete no longer used flag cap_bufs_mode_dynamic from instance
structure.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/core.h   | 2 --
 drivers/media/platform/qcom/venus/hfi_parser.c | 6 +-
 2 files changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/core.h 
b/drivers/media/platform/qcom/venus/core.h
index c46334454cd9..255292899204 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -249,7 +249,6 @@ struct venus_buffer {
  * @priv:  a private for HFI operations callbacks
  * @session_type:  the type of the session (decoder or encoder)
  * @hprop: a union used as a holder by get property
- * @cap_bufs_mode_dynamic: buffers allocation mode capability
  */
 struct venus_inst {
struct list_head list;
@@ -298,7 +297,6 @@ struct venus_inst {
const struct hfi_inst_ops *ops;
u32 session_type;
union hfi_get_property hprop;
-   bool cap_bufs_mode_dynamic;
 };
 
 #define IS_V1(core)((core)->res->hfi_version == HFI_VERSION_1XX)
diff --git a/drivers/media/platform/qcom/venus/hfi_parser.c 
b/drivers/media/platform/qcom/venus/hfi_parser.c
index f9181d999b23..ad039a3444b8 100644
--- a/drivers/media/platform/qcom/venus/hfi_parser.c
+++ b/drivers/media/platform/qcom/venus/hfi_parser.c
@@ -75,13 +75,9 @@ static void parse_alloc_mode(struct venus_core *core, struct 
venus_inst *inst,
 
while (num_entries--) {
if (mode->buffer_type == HFI_BUFFER_OUTPUT ||
-   mode->buffer_type == HFI_BUFFER_OUTPUT2) {
-   if (*type == HFI_BUFFER_MODE_DYNAMIC && inst)
-   inst->cap_bufs_mode_dynamic = true;
-
+   mode->buffer_type == HFI_BUFFER_OUTPUT2)
for_each_codec(core->caps, ARRAY_SIZE(core->caps),
   codecs, domain, fill_buf_mode, type, 1);
-   }
 
type++;
}
-- 
2.14.1



[PATCH v2 12/29] venus: add common capability parser

2018-05-15 Thread Stanimir Varbanov
This adds common capability parser for all supported Venus
versions. Having it will help to enumerate better the supported
raw formars and codecs and also the capabilities for every
codec like max/min width/height, framerate, bitrate and so on.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/Makefile |   3 +-
 drivers/media/platform/qcom/venus/core.c   |  85 ++
 drivers/media/platform/qcom/venus/core.h   |  68 +++--
 drivers/media/platform/qcom/venus/hfi.c|   5 +-
 drivers/media/platform/qcom/venus/hfi_helper.h |  28 +-
 drivers/media/platform/qcom/venus/hfi_msgs.c   | 348 ++---
 drivers/media/platform/qcom/venus/hfi_parser.c | 295 +
 drivers/media/platform/qcom/venus/hfi_parser.h |  45 
 drivers/media/platform/qcom/venus/vdec.c   |  38 +--
 drivers/media/platform/qcom/venus/venc.c   |  52 ++--
 10 files changed, 530 insertions(+), 437 deletions(-)
 create mode 100644 drivers/media/platform/qcom/venus/hfi_parser.c
 create mode 100644 drivers/media/platform/qcom/venus/hfi_parser.h

diff --git a/drivers/media/platform/qcom/venus/Makefile 
b/drivers/media/platform/qcom/venus/Makefile
index bfd4edf7c83f..b44b11b03e12 100644
--- a/drivers/media/platform/qcom/venus/Makefile
+++ b/drivers/media/platform/qcom/venus/Makefile
@@ -2,7 +2,8 @@
 # Makefile for Qualcomm Venus driver
 
 venus-core-objs += core.o helpers.o firmware.o \
-  hfi_venus.o hfi_msgs.o hfi_cmds.o hfi.o
+  hfi_venus.o hfi_msgs.o hfi_cmds.o hfi.o \
+  hfi_parser.o
 
 venus-dec-objs += vdec.o vdec_ctrls.o
 venus-enc-objs += venc.o venc_ctrls.o
diff --git a/drivers/media/platform/qcom/venus/core.c 
b/drivers/media/platform/qcom/venus/core.c
index 41eef376eb2d..381bfdd688db 100644
--- a/drivers/media/platform/qcom/venus/core.c
+++ b/drivers/media/platform/qcom/venus/core.c
@@ -152,6 +152,83 @@ static void venus_clks_disable(struct venus_core *core)
clk_disable_unprepare(core->clks[i]);
 }
 
+static u32 to_v4l2_codec_type(u32 codec)
+{
+   switch (codec) {
+   case HFI_VIDEO_CODEC_H264:
+   return V4L2_PIX_FMT_H264;
+   case HFI_VIDEO_CODEC_H263:
+   return V4L2_PIX_FMT_H263;
+   case HFI_VIDEO_CODEC_MPEG1:
+   return V4L2_PIX_FMT_MPEG1;
+   case HFI_VIDEO_CODEC_MPEG2:
+   return V4L2_PIX_FMT_MPEG2;
+   case HFI_VIDEO_CODEC_MPEG4:
+   return V4L2_PIX_FMT_MPEG4;
+   case HFI_VIDEO_CODEC_VC1:
+   return V4L2_PIX_FMT_VC1_ANNEX_G;
+   case HFI_VIDEO_CODEC_VP8:
+   return V4L2_PIX_FMT_VP8;
+   case HFI_VIDEO_CODEC_VP9:
+   return V4L2_PIX_FMT_VP9;
+   case HFI_VIDEO_CODEC_DIVX:
+   case HFI_VIDEO_CODEC_DIVX_311:
+   return V4L2_PIX_FMT_XVID;
+   default:
+   return 0;
+   }
+}
+
+static int venus_enumerate_codecs(struct venus_core *core, u32 type)
+{
+   const struct hfi_inst_ops dummy_ops = {};
+   struct venus_inst *inst;
+   u32 codec, codecs;
+   unsigned int i;
+   int ret;
+
+   if (core->res->hfi_version != HFI_VERSION_1XX)
+   return 0;
+
+   inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+   if (!inst)
+   return -ENOMEM;
+
+   mutex_init(>lock);
+   inst->core = core;
+   inst->session_type = type;
+   if (type == VIDC_SESSION_TYPE_DEC)
+   codecs = core->dec_codecs;
+   else
+   codecs = core->enc_codecs;
+
+   ret = hfi_session_create(inst, _ops);
+   if (ret)
+   goto err;
+
+   for (i = 0; i < MAX_CODEC_NUM; i++) {
+   codec = (1 << i) & codecs;
+   if (!codec)
+   continue;
+
+   ret = hfi_session_init(inst, to_v4l2_codec_type(codec));
+   if (ret)
+   goto done;
+
+   ret = hfi_session_deinit(inst);
+   if (ret)
+   goto done;
+   }
+
+done:
+   hfi_session_destroy(inst);
+err:
+   mutex_destroy(>lock);
+   kfree(inst);
+
+   return ret;
+}
+
 static int venus_probe(struct platform_device *pdev)
 {
struct device *dev = >dev;
@@ -219,6 +296,14 @@ static int venus_probe(struct platform_device *pdev)
if (ret)
goto err_venus_shutdown;
 
+   ret = venus_enumerate_codecs(core, VIDC_SESSION_TYPE_DEC);
+   if (ret)
+   goto err_venus_shutdown;
+
+   ret = venus_enumerate_codecs(core, VIDC_SESSION_TYPE_ENC);
+   if (ret)
+   goto err_venus_shutdown;
+
ret = v4l2_device_register(dev, >v4l2_dev);
if (ret)
goto err_core_deinit;
diff --git a/drivers/media/platform/qcom/venus/core.h 
b/drivers/media/platform/qcom/venus/core.h
index b5b9a84e9155..fe2d2b9e8af8 100644
--- a/dr

[PATCH v2 13/29] venus: helpers: make a commmon function for power_enable

2018-05-15 Thread Stanimir Varbanov
Make common function which will enable power when enabling/disabling
clocks and also covers Venus 3xx/4xx versions.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/helpers.c | 51 +
 drivers/media/platform/qcom/venus/helpers.h |  2 ++
 drivers/media/platform/qcom/venus/vdec.c| 25 --
 drivers/media/platform/qcom/venus/venc.c| 25 --
 4 files changed, 67 insertions(+), 36 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index d9065cc8a7d3..2b21f6ed7502 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -13,6 +13,7 @@
  *
  */
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -24,6 +25,7 @@
 #include "core.h"
 #include "helpers.h"
 #include "hfi_helper.h"
+#include "hfi_venus_io.h"
 
 struct intbuf {
struct list_head list;
@@ -781,3 +783,52 @@ void venus_helper_init_instance(struct venus_inst *inst)
}
 }
 EXPORT_SYMBOL_GPL(venus_helper_init_instance);
+
+int venus_helper_power_enable(struct venus_core *core, u32 session_type,
+ bool enable)
+{
+   void __iomem *ctrl, *stat;
+   u32 val;
+   int ret;
+
+   if (!IS_V3(core) && !IS_V4(core))
+   return -EINVAL;
+
+   if (IS_V3(core)) {
+   if (session_type == VIDC_SESSION_TYPE_DEC)
+   ctrl = core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL;
+   else
+   ctrl = core->base + WRAPPER_VENC_VCODEC_POWER_CONTROL;
+   if (enable)
+   writel(0, ctrl);
+   else
+   writel(1, ctrl);
+
+   return 0;
+   }
+
+   if (session_type == VIDC_SESSION_TYPE_DEC) {
+   ctrl = core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL;
+   stat = core->base + WRAPPER_VCODEC0_MMCC_POWER_STATUS;
+   } else {
+   ctrl = core->base + WRAPPER_VCODEC1_MMCC_POWER_CONTROL;
+   stat = core->base + WRAPPER_VCODEC1_MMCC_POWER_STATUS;
+   }
+
+   if (enable) {
+   writel(0, ctrl);
+
+   ret = readl_poll_timeout(stat, val, val & BIT(1), 1, 100);
+   if (ret)
+   return ret;
+   } else {
+   writel(1, ctrl);
+
+   ret = readl_poll_timeout(stat, val, !(val & BIT(1)), 1, 100);
+   if (ret)
+   return ret;
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(venus_helper_power_enable);
diff --git a/drivers/media/platform/qcom/venus/helpers.h 
b/drivers/media/platform/qcom/venus/helpers.h
index 971392be5df5..0e64aa95624a 100644
--- a/drivers/media/platform/qcom/venus/helpers.h
+++ b/drivers/media/platform/qcom/venus/helpers.h
@@ -43,4 +43,6 @@ int venus_helper_set_color_format(struct venus_inst *inst, 
u32 fmt);
 void venus_helper_acquire_buf_ref(struct vb2_v4l2_buffer *vbuf);
 void venus_helper_release_buf_ref(struct venus_inst *inst, unsigned int idx);
 void venus_helper_init_instance(struct venus_inst *inst);
+int venus_helper_power_enable(struct venus_core *core, u32 session_type,
+ bool enable);
 #endif
diff --git a/drivers/media/platform/qcom/venus/vdec.c 
b/drivers/media/platform/qcom/venus/vdec.c
index 3b38bd1241b0..2bd81de6328a 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -1123,26 +1123,21 @@ static int vdec_remove(struct platform_device *pdev)
 static __maybe_unused int vdec_runtime_suspend(struct device *dev)
 {
struct venus_core *core = dev_get_drvdata(dev);
+   int ret;
 
if (IS_V1(core))
return 0;
 
-   if (IS_V3(core))
-   writel(0, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
-   else if (IS_V4(core))
-   writel(0, core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL);
+   ret = venus_helper_power_enable(core, VIDC_SESSION_TYPE_DEC, true);
 
if (IS_V4(core))
clk_disable_unprepare(core->core0_bus_clk);
 
clk_disable_unprepare(core->core0_clk);
 
-   if (IS_V3(core))
-   writel(1, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
-   else if (IS_V4(core))
-   writel(1, core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL);
+   ret |= venus_helper_power_enable(core, VIDC_SESSION_TYPE_DEC, false);
 
-   return 0;
+   return ret;
 }
 
 static __maybe_unused int vdec_runtime_resume(struct device *dev)
@@ -1153,20 +1148,14 @@ static __maybe_unused int vdec_runtime_resume(struct 
device *dev)
if (IS_V1(core))
return 0;
 
-   if (IS_V3(core))
-   writel(0, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
- 

[PATCH v2 15/29] venus: helpers: rename a helper function and use buffer mode from caps

2018-05-15 Thread Stanimir Varbanov
Rename is_reg_unreg_needed() to better name is_dynamic_bufmode() and
use buffer mode from enumerated per codec capabilities.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/helpers.c | 21 +++--
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index 2b21f6ed7502..1eda19adbf28 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -354,18 +354,19 @@ session_process_buf(struct venus_inst *inst, struct 
vb2_v4l2_buffer *vbuf)
return 0;
 }
 
-static inline int is_reg_unreg_needed(struct venus_inst *inst)
+static inline int is_dynamic_bufmode(struct venus_inst *inst)
 {
-   if (inst->session_type == VIDC_SESSION_TYPE_DEC &&
-   inst->core->res->hfi_version == HFI_VERSION_3XX)
-   return 0;
+   struct venus_core *core = inst->core;
+   struct venus_caps *caps;
 
-   if (inst->session_type == VIDC_SESSION_TYPE_DEC &&
-   inst->cap_bufs_mode_dynamic &&
-   inst->core->res->hfi_version == HFI_VERSION_1XX)
+   caps = venus_caps_by_codec(core, inst->hfi_codec, inst->session_type);
+   if (!caps)
return 0;
 
-   return 1;
+   if (caps->cap_bufs_mode_dynamic)
+   return 1;
+
+   return 0;
 }
 
 static int session_unregister_bufs(struct venus_inst *inst)
@@ -374,7 +375,7 @@ static int session_unregister_bufs(struct venus_inst *inst)
struct hfi_buffer_desc bd;
int ret = 0;
 
-   if (!is_reg_unreg_needed(inst))
+   if (is_dynamic_bufmode(inst))
return 0;
 
list_for_each_entry_safe(buf, n, >registeredbufs, reg_list) {
@@ -394,7 +395,7 @@ static int session_register_bufs(struct venus_inst *inst)
struct venus_buffer *buf;
int ret = 0;
 
-   if (!is_reg_unreg_needed(inst))
+   if (is_dynamic_bufmode(inst))
return 0;
 
list_for_each_entry(buf, >registeredbufs, reg_list) {
-- 
2.14.1



[PATCH v2 20/29] venus: helpers: add a new helper to set raw format

2018-05-15 Thread Stanimir Varbanov
The new helper will has one more argument for buffer type, that
way the decoder can configure the format on it's secondary
output.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/helpers.c | 52 ++---
 drivers/media/platform/qcom/venus/helpers.h |  2 ++
 2 files changed, 35 insertions(+), 19 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index 5512fbfdebb9..0d55604f7484 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -410,6 +410,20 @@ static int session_register_bufs(struct venus_inst *inst)
return ret;
 }
 
+static u32 to_hfi_raw_fmt(u32 v4l2_fmt)
+{
+   switch (v4l2_fmt) {
+   case V4L2_PIX_FMT_NV12:
+   return HFI_COLOR_FORMAT_NV12;
+   case V4L2_PIX_FMT_NV21:
+   return HFI_COLOR_FORMAT_NV21;
+   default:
+   break;
+   }
+
+   return 0;
+}
+
 int venus_helper_get_bufreq(struct venus_inst *inst, u32 type,
struct hfi_buffer_requirements *req)
 {
@@ -491,35 +505,35 @@ int venus_helper_set_num_bufs(struct venus_inst *inst, 
unsigned int input_bufs,
 }
 EXPORT_SYMBOL_GPL(venus_helper_set_num_bufs);
 
-int venus_helper_set_color_format(struct venus_inst *inst, u32 pixfmt)
+int venus_helper_set_raw_format(struct venus_inst *inst, u32 hfi_format,
+   u32 buftype)
 {
-   struct hfi_uncompressed_format_select fmt;
u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT;
-   int ret;
+   struct hfi_uncompressed_format_select fmt;
+
+   fmt.buffer_type = buftype;
+   fmt.format = hfi_format;
+
+   return hfi_session_set_property(inst, ptype, );
+}
+EXPORT_SYMBOL_GPL(venus_helper_set_raw_format);
+
+int venus_helper_set_color_format(struct venus_inst *inst, u32 pixfmt)
+{
+   u32 hfi_format, buftype;
 
if (inst->session_type == VIDC_SESSION_TYPE_DEC)
-   fmt.buffer_type = HFI_BUFFER_OUTPUT;
+   buftype = HFI_BUFFER_OUTPUT;
else if (inst->session_type == VIDC_SESSION_TYPE_ENC)
-   fmt.buffer_type = HFI_BUFFER_INPUT;
+   buftype = HFI_BUFFER_INPUT;
else
return -EINVAL;
 
-   switch (pixfmt) {
-   case V4L2_PIX_FMT_NV12:
-   fmt.format = HFI_COLOR_FORMAT_NV12;
-   break;
-   case V4L2_PIX_FMT_NV21:
-   fmt.format = HFI_COLOR_FORMAT_NV21;
-   break;
-   default:
+   hfi_format = to_hfi_raw_fmt(pixfmt);
+   if (!hfi_format)
return -EINVAL;
-   }
 
-   ret = hfi_session_set_property(inst, ptype, );
-   if (ret)
-   return ret;
-
-   return 0;
+   return venus_helper_set_raw_format(inst, hfi_format, buftype);
 }
 EXPORT_SYMBOL_GPL(venus_helper_set_color_format);
 
diff --git a/drivers/media/platform/qcom/venus/helpers.h 
b/drivers/media/platform/qcom/venus/helpers.h
index 0de9989adcdb..79af7845efbd 100644
--- a/drivers/media/platform/qcom/venus/helpers.h
+++ b/drivers/media/platform/qcom/venus/helpers.h
@@ -40,6 +40,8 @@ int venus_helper_set_output_resolution(struct venus_inst 
*inst,
   u32 buftype);
 int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs,
  unsigned int output_bufs);
+int venus_helper_set_raw_format(struct venus_inst *inst, u32 hfi_format,
+   u32 buftype);
 int venus_helper_set_color_format(struct venus_inst *inst, u32 fmt);
 int venus_helper_set_dyn_bufmode(struct venus_inst *inst);
 int venus_helper_set_bufsize(struct venus_inst *inst, u32 bufsize, u32 
buftype);
-- 
2.14.1



[PATCH v2 16/29] venus: add a helper function to set dynamic buffer mode

2018-05-15 Thread Stanimir Varbanov
Adds a new helper function to set dynamic buffer mode if it is
supported by current HFI version.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/helpers.c | 22 ++
 drivers/media/platform/qcom/venus/helpers.h |  1 +
 drivers/media/platform/qcom/venus/vdec.c| 15 +++
 3 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index 1eda19adbf28..824ad4d2d064 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -522,6 +522,28 @@ int venus_helper_set_color_format(struct venus_inst *inst, 
u32 pixfmt)
 }
 EXPORT_SYMBOL_GPL(venus_helper_set_color_format);
 
+int venus_helper_set_dyn_bufmode(struct venus_inst *inst)
+{
+   u32 ptype = HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE;
+   struct hfi_buffer_alloc_mode mode;
+   int ret;
+
+   if (!is_dynamic_bufmode(inst))
+   return 0;
+
+   mode.type = HFI_BUFFER_OUTPUT;
+   mode.mode = HFI_BUFFER_MODE_DYNAMIC;
+
+   ret = hfi_session_set_property(inst, ptype, );
+   if (ret)
+   return ret;
+
+   mode.type = HFI_BUFFER_OUTPUT2;
+
+   return hfi_session_set_property(inst, ptype, );
+}
+EXPORT_SYMBOL_GPL(venus_helper_set_dyn_bufmode);
+
 static void delayed_process_buf_func(struct work_struct *work)
 {
struct venus_buffer *buf, *n;
diff --git a/drivers/media/platform/qcom/venus/helpers.h 
b/drivers/media/platform/qcom/venus/helpers.h
index 0e64aa95624a..52b961ed491e 100644
--- a/drivers/media/platform/qcom/venus/helpers.h
+++ b/drivers/media/platform/qcom/venus/helpers.h
@@ -40,6 +40,7 @@ int venus_helper_set_output_resolution(struct venus_inst 
*inst,
 int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs,
  unsigned int output_bufs);
 int venus_helper_set_color_format(struct venus_inst *inst, u32 fmt);
+int venus_helper_set_dyn_bufmode(struct venus_inst *inst);
 void venus_helper_acquire_buf_ref(struct vb2_v4l2_buffer *vbuf);
 void venus_helper_release_buf_ref(struct venus_inst *inst, unsigned int idx);
 void venus_helper_init_instance(struct venus_inst *inst);
diff --git a/drivers/media/platform/qcom/venus/vdec.c 
b/drivers/media/platform/qcom/venus/vdec.c
index 2bd81de6328a..271192273953 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -557,18 +557,9 @@ static int vdec_set_properties(struct venus_inst *inst)
return ret;
}
 
-   if (core->res->hfi_version == HFI_VERSION_3XX ||
-   inst->cap_bufs_mode_dynamic) {
-   struct hfi_buffer_alloc_mode mode;
-
-   ptype = HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE;
-   mode.type = HFI_BUFFER_OUTPUT;
-   mode.mode = HFI_BUFFER_MODE_DYNAMIC;
-
-   ret = hfi_session_set_property(inst, ptype, );
-   if (ret)
-   return ret;
-   }
+   ret = venus_helper_set_dyn_bufmode(inst);
+   if (ret)
+   return ret;
 
if (ctr->post_loop_deb_mode) {
ptype = HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER;
-- 
2.14.1



[PATCH v2 22/29] venus: helpers: extend set_num_bufs helper with one more argument

2018-05-15 Thread Stanimir Varbanov
Extend venus_helper_set_num_bufs() helper function with one more
argument to set number of output buffers for the secondary decoder
output.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/helpers.c | 16 ++--
 drivers/media/platform/qcom/venus/helpers.h |  3 ++-
 drivers/media/platform/qcom/venus/vdec.c|  2 +-
 drivers/media/platform/qcom/venus/venc.c|  2 +-
 4 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index adf8701a64bb..f04d16953b3a 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -513,7 +513,8 @@ int venus_helper_set_core_usage(struct venus_inst *inst, 
u32 usage)
 EXPORT_SYMBOL_GPL(venus_helper_set_core_usage);
 
 int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs,
- unsigned int output_bufs)
+ unsigned int output_bufs,
+ unsigned int output2_bufs)
 {
u32 ptype = HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL;
struct hfi_buffer_count_actual buf_count;
@@ -529,7 +530,18 @@ int venus_helper_set_num_bufs(struct venus_inst *inst, 
unsigned int input_bufs,
buf_count.type = HFI_BUFFER_OUTPUT;
buf_count.count_actual = output_bufs;
 
-   return hfi_session_set_property(inst, ptype, _count);
+   ret = hfi_session_set_property(inst, ptype, _count);
+   if (ret)
+   return ret;
+
+   if (output2_bufs) {
+   buf_count.type = HFI_BUFFER_OUTPUT2;
+   buf_count.count_actual = output2_bufs;
+
+   ret = hfi_session_set_property(inst, ptype, _count);
+   }
+
+   return ret;
 }
 EXPORT_SYMBOL_GPL(venus_helper_set_num_bufs);
 
diff --git a/drivers/media/platform/qcom/venus/helpers.h 
b/drivers/media/platform/qcom/venus/helpers.h
index d5e727e1ecab..8ff4bd3ef958 100644
--- a/drivers/media/platform/qcom/venus/helpers.h
+++ b/drivers/media/platform/qcom/venus/helpers.h
@@ -41,7 +41,8 @@ int venus_helper_set_output_resolution(struct venus_inst 
*inst,
 int venus_helper_set_work_mode(struct venus_inst *inst, u32 mode);
 int venus_helper_set_core_usage(struct venus_inst *inst, u32 usage);
 int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs,
- unsigned int output_bufs);
+ unsigned int output_bufs,
+ unsigned int output2_bufs);
 int venus_helper_set_raw_format(struct venus_inst *inst, u32 hfi_format,
u32 buftype);
 int venus_helper_set_color_format(struct venus_inst *inst, u32 fmt);
diff --git a/drivers/media/platform/qcom/venus/vdec.c 
b/drivers/media/platform/qcom/venus/vdec.c
index 3c7ffebe4bad..898c5edb91f5 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -758,7 +758,7 @@ static int vdec_start_streaming(struct vb2_queue *q, 
unsigned int count)
goto deinit_sess;
 
ret = venus_helper_set_num_bufs(inst, inst->num_input_bufs,
-   VB2_MAX_FRAME);
+   VB2_MAX_FRAME, VB2_MAX_FRAME);
if (ret)
goto deinit_sess;
 
diff --git a/drivers/media/platform/qcom/venus/venc.c 
b/drivers/media/platform/qcom/venus/venc.c
index 3b3299bff1cd..c9c40d1ce7c6 100644
--- a/drivers/media/platform/qcom/venus/venc.c
+++ b/drivers/media/platform/qcom/venus/venc.c
@@ -963,7 +963,7 @@ static int venc_start_streaming(struct vb2_queue *q, 
unsigned int count)
goto deinit_sess;
 
ret = venus_helper_set_num_bufs(inst, inst->num_input_bufs,
-   inst->num_output_bufs);
+   inst->num_output_bufs, 0);
if (ret)
goto deinit_sess;
 
-- 
2.14.1



[PATCH v2 21/29] venus: helpers,vdec,venc: add helpers to set work mode and core usage

2018-05-15 Thread Stanimir Varbanov
These are new properties applicable to Venus version 4xx. Add the
helpers and call them from decoder and encoder drivers.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/helpers.c | 28 
 drivers/media/platform/qcom/venus/helpers.h |  2 ++
 drivers/media/platform/qcom/venus/vdec.c|  8 
 drivers/media/platform/qcom/venus/venc.c|  8 
 4 files changed, 46 insertions(+)

diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index 0d55604f7484..adf8701a64bb 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -484,6 +484,34 @@ int venus_helper_set_output_resolution(struct venus_inst 
*inst,
 }
 EXPORT_SYMBOL_GPL(venus_helper_set_output_resolution);
 
+int venus_helper_set_work_mode(struct venus_inst *inst, u32 mode)
+{
+   u32 ptype = HFI_PROPERTY_PARAM_WORK_MODE;
+   struct hfi_video_work_mode wm;
+
+   if (!IS_V4(inst->core))
+   return 0;
+
+   wm.video_work_mode = mode;
+
+   return hfi_session_set_property(inst, ptype, );
+}
+EXPORT_SYMBOL_GPL(venus_helper_set_work_mode);
+
+int venus_helper_set_core_usage(struct venus_inst *inst, u32 usage)
+{
+   u32 ptype = HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE;
+   struct hfi_videocores_usage_type cu;
+
+   if (!IS_V4(inst->core))
+   return 0;
+
+   cu.video_core_enable_mask = usage;
+
+   return hfi_session_set_property(inst, ptype, );
+}
+EXPORT_SYMBOL_GPL(venus_helper_set_core_usage);
+
 int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs,
  unsigned int output_bufs)
 {
diff --git a/drivers/media/platform/qcom/venus/helpers.h 
b/drivers/media/platform/qcom/venus/helpers.h
index 79af7845efbd..d5e727e1ecab 100644
--- a/drivers/media/platform/qcom/venus/helpers.h
+++ b/drivers/media/platform/qcom/venus/helpers.h
@@ -38,6 +38,8 @@ int venus_helper_set_input_resolution(struct venus_inst *inst,
 int venus_helper_set_output_resolution(struct venus_inst *inst,
   unsigned int width, unsigned int height,
   u32 buftype);
+int venus_helper_set_work_mode(struct venus_inst *inst, u32 mode);
+int venus_helper_set_core_usage(struct venus_inst *inst, u32 usage);
 int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs,
  unsigned int output_bufs);
 int venus_helper_set_raw_format(struct venus_inst *inst, u32 hfi_format,
diff --git a/drivers/media/platform/qcom/venus/vdec.c 
b/drivers/media/platform/qcom/venus/vdec.c
index e8e00d0650e9..3c7ffebe4bad 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -550,6 +550,14 @@ static int vdec_set_properties(struct venus_inst *inst)
u32 ptype;
int ret;
 
+   ret = venus_helper_set_work_mode(inst, VIDC_WORK_MODE_2);
+   if (ret)
+   return ret;
+
+   ret = venus_helper_set_core_usage(inst, VIDC_CORE_ID_1);
+   if (ret)
+   return ret;
+
if (core->res->hfi_version == HFI_VERSION_1XX) {
ptype = HFI_PROPERTY_PARAM_VDEC_CONTINUE_DATA_TRANSFER;
ret = hfi_session_set_property(inst, ptype, );
diff --git a/drivers/media/platform/qcom/venus/venc.c 
b/drivers/media/platform/qcom/venus/venc.c
index 8970f14b3a82..3b3299bff1cd 100644
--- a/drivers/media/platform/qcom/venus/venc.c
+++ b/drivers/media/platform/qcom/venus/venc.c
@@ -643,6 +643,14 @@ static int venc_set_properties(struct venus_inst *inst)
u32 ptype, rate_control, bitrate, profile = 0, level = 0;
int ret;
 
+   ret = venus_helper_set_work_mode(inst, VIDC_WORK_MODE_2);
+   if (ret)
+   return ret;
+
+   ret = venus_helper_set_core_usage(inst, VIDC_CORE_ID_2);
+   if (ret)
+   return ret;
+
ptype = HFI_PROPERTY_CONFIG_FRAME_RATE;
frate.buffer_type = HFI_BUFFER_OUTPUT;
frate.framerate = inst->fps * (1 << 16);
-- 
2.14.1



[PATCH v2 14/29] venus: core: delete not used flag for buffer mode

2018-05-15 Thread Stanimir Varbanov
Delete not used flag for capture buffer allocation mode.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/core.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/core.h 
b/drivers/media/platform/qcom/venus/core.h
index fe2d2b9e8af8..c46334454cd9 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -249,7 +249,6 @@ struct venus_buffer {
  * @priv:  a private for HFI operations callbacks
  * @session_type:  the type of the session (decoder or encoder)
  * @hprop: a union used as a holder by get property
- * @cap_bufs_mode_static:  buffers allocation mode capability
  * @cap_bufs_mode_dynamic: buffers allocation mode capability
  */
 struct venus_inst {
@@ -299,7 +298,6 @@ struct venus_inst {
const struct hfi_inst_ops *ops;
u32 session_type;
union hfi_get_property hprop;
-   bool cap_bufs_mode_static;
bool cap_bufs_mode_dynamic;
 };
 
-- 
2.14.1



[PATCH v2 23/29] venus: helpers: add a helper to return opb buffer sizes

2018-05-15 Thread Stanimir Varbanov
Add a helper function to return current output picture buffer size.
OPB sizes can vary depending on the selected decoder output(s).

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/core.h| 10 ++
 drivers/media/platform/qcom/venus/helpers.c | 15 +++
 drivers/media/platform/qcom/venus/helpers.h |  1 +
 3 files changed, 26 insertions(+)

diff --git a/drivers/media/platform/qcom/venus/core.h 
b/drivers/media/platform/qcom/venus/core.h
index 255292899204..4d6c05f156c4 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -234,6 +234,11 @@ struct venus_buffer {
  * @num_output_bufs:   holds number of output buffers
  * @input_buf_size holds input buffer size
  * @output_buf_size:   holds output buffer size
+ * @output2_buf_size:  holds secondary decoder output buffer size
+ * @dpb_buftype:   decoded picture buffer type
+ * @dpb_fmt:   decodec picture buffre raw format
+ * @opb_buftype:   output picture buffer type
+ * @opb_fmt:   output picture buffer raw format
  * @reconfig:  a flag raised by decoder when the stream resolution changed
  * @reconfig_width:holds the new width
  * @reconfig_height:   holds the new height
@@ -282,6 +287,11 @@ struct venus_inst {
unsigned int num_output_bufs;
unsigned int input_buf_size;
unsigned int output_buf_size;
+   unsigned int output2_buf_size;
+   u32 dpb_buftype;
+   u32 dpb_fmt;
+   u32 opb_buftype;
+   u32 opb_fmt;
bool reconfig;
u32 reconfig_width;
u32 reconfig_height;
diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index f04d16953b3a..f0a0fca60c76 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -611,6 +611,21 @@ int venus_helper_set_bufsize(struct venus_inst *inst, u32 
bufsize, u32 buftype)
 }
 EXPORT_SYMBOL_GPL(venus_helper_set_bufsize);
 
+unsigned int venus_helper_get_opb_size(struct venus_inst *inst)
+{
+   /* the encoder has only one output */
+   if (inst->session_type == VIDC_SESSION_TYPE_ENC)
+   return inst->output_buf_size;
+
+   if (inst->opb_buftype == HFI_BUFFER_OUTPUT)
+   return inst->output_buf_size;
+   else if (inst->opb_buftype == HFI_BUFFER_OUTPUT2)
+   return inst->output2_buf_size;
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(venus_helper_get_opb_size);
+
 static void delayed_process_buf_func(struct work_struct *work)
 {
struct venus_buffer *buf, *n;
diff --git a/drivers/media/platform/qcom/venus/helpers.h 
b/drivers/media/platform/qcom/venus/helpers.h
index 8ff4bd3ef958..92be45894a69 100644
--- a/drivers/media/platform/qcom/venus/helpers.h
+++ b/drivers/media/platform/qcom/venus/helpers.h
@@ -48,6 +48,7 @@ int venus_helper_set_raw_format(struct venus_inst *inst, u32 
hfi_format,
 int venus_helper_set_color_format(struct venus_inst *inst, u32 fmt);
 int venus_helper_set_dyn_bufmode(struct venus_inst *inst);
 int venus_helper_set_bufsize(struct venus_inst *inst, u32 bufsize, u32 
buftype);
+unsigned int venus_helper_get_opb_size(struct venus_inst *inst);
 void venus_helper_acquire_buf_ref(struct vb2_v4l2_buffer *vbuf);
 void venus_helper_release_buf_ref(struct venus_inst *inst, unsigned int idx);
 void venus_helper_init_instance(struct venus_inst *inst);
-- 
2.14.1



[PATCH v2 24/29] venus: vdec: get required input buffers as well

2018-05-15 Thread Stanimir Varbanov
Rework and rename vdec_cap_num_buffers() to get the number of
input buffers too.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/vdec.c | 41 +++-
 1 file changed, 24 insertions(+), 17 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/vdec.c 
b/drivers/media/platform/qcom/venus/vdec.c
index 898c5edb91f5..5a5e3e2fece4 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -603,19 +603,32 @@ static int vdec_init_session(struct venus_inst *inst)
return ret;
 }
 
-static int vdec_cap_num_buffers(struct venus_inst *inst, unsigned int *num)
+static int vdec_num_buffers(struct venus_inst *inst, unsigned int *in_num,
+   unsigned int *out_num)
 {
+   enum hfi_version ver = inst->core->res->hfi_version;
struct hfi_buffer_requirements bufreq;
int ret;
 
+   *in_num = *out_num = 0;
+
ret = vdec_init_session(inst);
if (ret)
return ret;
 
+   ret = venus_helper_get_bufreq(inst, HFI_BUFFER_INPUT, );
+   if (ret)
+   goto deinit;
+
+   *in_num = HFI_BUFREQ_COUNT_MIN(, ver);
+
ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, );
+   if (ret)
+   goto deinit;
 
-   *num = bufreq.count_actual;
+   *out_num = HFI_BUFREQ_COUNT_MIN(, ver);
 
+deinit:
hfi_session_deinit(inst);
 
return ret;
@@ -626,7 +639,7 @@ static int vdec_queue_setup(struct vb2_queue *q,
unsigned int sizes[], struct device *alloc_devs[])
 {
struct venus_inst *inst = vb2_get_drv_priv(q);
-   unsigned int p, num;
+   unsigned int p, in_num, out_num;
int ret = 0;
 
if (*num_planes) {
@@ -649,35 +662,29 @@ static int vdec_queue_setup(struct vb2_queue *q,
return 0;
}
 
+   ret = vdec_num_buffers(inst, _num, _num);
+   if (ret)
+   return ret;
+
switch (q->type) {
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
*num_planes = inst->fmt_out->num_planes;
sizes[0] = get_framesize_compressed(inst->out_width,
inst->out_height);
inst->input_buf_size = sizes[0];
+   *num_buffers = max(*num_buffers, in_num);
inst->num_input_bufs = *num_buffers;
-
-   ret = vdec_cap_num_buffers(inst, );
-   if (ret)
-   break;
-
-   inst->num_output_bufs = num;
+   inst->num_output_bufs = out_num;
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
*num_planes = inst->fmt_cap->num_planes;
 
-   ret = vdec_cap_num_buffers(inst, );
-   if (ret)
-   break;
-
-   *num_buffers = max(*num_buffers, num);
-
for (p = 0; p < *num_planes; p++)
sizes[p] = get_framesize_uncompressed(p, inst->width,
  inst->height);
-
-   inst->num_output_bufs = *num_buffers;
inst->output_buf_size = sizes[0];
+   *num_buffers = max(*num_buffers, out_num);
+   inst->num_output_bufs = *num_buffers;
break;
default:
ret = -EINVAL;
-- 
2.14.1



[PATCH v2 17/29] venus: add helper function to set actual buffer size

2018-05-15 Thread Stanimir Varbanov
Add and use a helper function to set actual buffer size for
particular buffer type. This is also preparation to use
the second decoder output.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/helpers.c | 12 
 drivers/media/platform/qcom/venus/helpers.h |  1 +
 drivers/media/platform/qcom/venus/vdec.c| 10 ++
 3 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index 824ad4d2d064..94664a3ce3e2 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -544,6 +544,18 @@ int venus_helper_set_dyn_bufmode(struct venus_inst *inst)
 }
 EXPORT_SYMBOL_GPL(venus_helper_set_dyn_bufmode);
 
+int venus_helper_set_bufsize(struct venus_inst *inst, u32 bufsize, u32 buftype)
+{
+   u32 ptype = HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL;
+   struct hfi_buffer_size_actual bufsz;
+
+   bufsz.type = buftype;
+   bufsz.size = bufsize;
+
+   return hfi_session_set_property(inst, ptype, );
+}
+EXPORT_SYMBOL_GPL(venus_helper_set_bufsize);
+
 static void delayed_process_buf_func(struct work_struct *work)
 {
struct venus_buffer *buf, *n;
diff --git a/drivers/media/platform/qcom/venus/helpers.h 
b/drivers/media/platform/qcom/venus/helpers.h
index 52b961ed491e..cd306bd8978f 100644
--- a/drivers/media/platform/qcom/venus/helpers.h
+++ b/drivers/media/platform/qcom/venus/helpers.h
@@ -41,6 +41,7 @@ int venus_helper_set_num_bufs(struct venus_inst *inst, 
unsigned int input_bufs,
  unsigned int output_bufs);
 int venus_helper_set_color_format(struct venus_inst *inst, u32 fmt);
 int venus_helper_set_dyn_bufmode(struct venus_inst *inst);
+int venus_helper_set_bufsize(struct venus_inst *inst, u32 bufsize, u32 
buftype);
 void venus_helper_acquire_buf_ref(struct vb2_v4l2_buffer *vbuf);
 void venus_helper_release_buf_ref(struct venus_inst *inst, unsigned int idx);
 void venus_helper_init_instance(struct venus_inst *inst);
diff --git a/drivers/media/platform/qcom/venus/vdec.c 
b/drivers/media/platform/qcom/venus/vdec.c
index 271192273953..e8e00d0650e9 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -710,7 +710,6 @@ static int vdec_start_streaming(struct vb2_queue *q, 
unsigned int count)
 {
struct venus_inst *inst = vb2_get_drv_priv(q);
struct venus_core *core = inst->core;
-   u32 ptype;
int ret;
 
mutex_lock(>lock);
@@ -740,13 +739,8 @@ static int vdec_start_streaming(struct vb2_queue *q, 
unsigned int count)
goto deinit_sess;
 
if (core->res->hfi_version == HFI_VERSION_3XX) {
-   struct hfi_buffer_size_actual buf_sz;
-
-   ptype = HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL;
-   buf_sz.type = HFI_BUFFER_OUTPUT;
-   buf_sz.size = inst->output_buf_size;
-
-   ret = hfi_session_set_property(inst, ptype, _sz);
+   ret = venus_helper_set_bufsize(inst, inst->output_buf_size,
+  HFI_BUFFER_OUTPUT);
if (ret)
goto deinit_sess;
}
-- 
2.14.1



[PATCH v2 26/29] venus: move frame size calculations in common place

2018-05-15 Thread Stanimir Varbanov
move calculations of raw and compressed in a common helper
and make it identical for encoder and decoder.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/helpers.c | 98 +
 drivers/media/platform/qcom/venus/helpers.h |  2 +
 drivers/media/platform/qcom/venus/vdec.c| 54 
 drivers/media/platform/qcom/venus/venc.c| 56 -
 4 files changed, 126 insertions(+), 84 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index f0a0fca60c76..ed569705ecac 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -455,6 +455,104 @@ int venus_helper_get_bufreq(struct venus_inst *inst, u32 
type,
 }
 EXPORT_SYMBOL_GPL(venus_helper_get_bufreq);
 
+static u32 get_framesize_raw_nv12(u32 width, u32 height)
+{
+   u32 y_stride, uv_stride, y_plane;
+   u32 y_sclines, uv_sclines, uv_plane;
+   u32 size;
+
+   y_stride = ALIGN(width, 128);
+   uv_stride = ALIGN(width, 128);
+   y_sclines = ALIGN(height, 32);
+   uv_sclines = ALIGN(((height + 1) >> 1), 16);
+
+   y_plane = y_stride * y_sclines;
+   uv_plane = uv_stride * uv_sclines + SZ_4K;
+   size = y_plane + uv_plane + SZ_8K;
+
+   return ALIGN(size, SZ_4K);
+}
+
+static u32 get_framesize_raw_nv12_ubwc(u32 width, u32 height)
+{
+   u32 y_meta_stride, y_meta_plane;
+   u32 y_stride, y_plane;
+   u32 uv_meta_stride, uv_meta_plane;
+   u32 uv_stride, uv_plane;
+   u32 extradata = SZ_16K;
+
+   y_meta_stride = ALIGN(DIV_ROUND_UP(width, 32), 64);
+   y_meta_plane = y_meta_stride * ALIGN(DIV_ROUND_UP(height, 8), 16);
+   y_meta_plane = ALIGN(y_meta_plane, SZ_4K);
+
+   y_stride = ALIGN(width, 128);
+   y_plane = ALIGN(y_stride * ALIGN(height, 32), SZ_4K);
+
+   uv_meta_stride = ALIGN(DIV_ROUND_UP(width / 2, 16), 64);
+   uv_meta_plane = uv_meta_stride * ALIGN(DIV_ROUND_UP(height / 2, 8), 16);
+   uv_meta_plane = ALIGN(uv_meta_plane, SZ_4K);
+
+   uv_stride = ALIGN(width, 128);
+   uv_plane = ALIGN(uv_stride * ALIGN(height / 2, 32), SZ_4K);
+
+   return ALIGN(y_meta_plane + y_plane + uv_meta_plane + uv_plane +
+max(extradata, y_stride * 48), SZ_4K);
+}
+
+u32 venus_helper_get_framesz_raw(u32 hfi_fmt, u32 width, u32 height)
+{
+   switch (hfi_fmt) {
+   case HFI_COLOR_FORMAT_NV12:
+   case HFI_COLOR_FORMAT_NV21:
+   return get_framesize_raw_nv12(width, height);
+   case HFI_COLOR_FORMAT_NV12_UBWC:
+   return get_framesize_raw_nv12_ubwc(width, height);
+   default:
+   return 0;
+   }
+}
+EXPORT_SYMBOL_GPL(venus_helper_get_framesz_raw);
+
+u32 venus_helper_get_framesz(u32 v4l2_fmt, u32 width, u32 height)
+{
+   u32 hfi_fmt, sz;
+   bool compressed;
+
+   switch (v4l2_fmt) {
+   case V4L2_PIX_FMT_MPEG:
+   case V4L2_PIX_FMT_H264:
+   case V4L2_PIX_FMT_H264_NO_SC:
+   case V4L2_PIX_FMT_H264_MVC:
+   case V4L2_PIX_FMT_H263:
+   case V4L2_PIX_FMT_MPEG1:
+   case V4L2_PIX_FMT_MPEG2:
+   case V4L2_PIX_FMT_MPEG4:
+   case V4L2_PIX_FMT_XVID:
+   case V4L2_PIX_FMT_VC1_ANNEX_G:
+   case V4L2_PIX_FMT_VC1_ANNEX_L:
+   case V4L2_PIX_FMT_VP8:
+   case V4L2_PIX_FMT_VP9:
+   case V4L2_PIX_FMT_HEVC:
+   compressed = true;
+   break;
+   default:
+   compressed = false;
+   break;
+   }
+
+   if (compressed) {
+   sz = ALIGN(height, 32) * ALIGN(width, 32) * 3 / 2 / 2;
+   return ALIGN(sz, SZ_4K);
+   }
+
+   hfi_fmt = to_hfi_raw_fmt(v4l2_fmt);
+   if (!hfi_fmt)
+   return 0;
+
+   return venus_helper_get_framesz_raw(hfi_fmt, width, height);
+}
+EXPORT_SYMBOL_GPL(venus_helper_get_framesz);
+
 int venus_helper_set_input_resolution(struct venus_inst *inst,
  unsigned int width, unsigned int height)
 {
diff --git a/drivers/media/platform/qcom/venus/helpers.h 
b/drivers/media/platform/qcom/venus/helpers.h
index 92be45894a69..92b167a47166 100644
--- a/drivers/media/platform/qcom/venus/helpers.h
+++ b/drivers/media/platform/qcom/venus/helpers.h
@@ -33,6 +33,8 @@ void venus_helper_m2m_device_run(void *priv);
 void venus_helper_m2m_job_abort(void *priv);
 int venus_helper_get_bufreq(struct venus_inst *inst, u32 type,
struct hfi_buffer_requirements *req);
+u32 venus_helper_get_framesz_raw(u32 hfi_fmt, u32 width, u32 height);
+u32 venus_helper_get_framesz(u32 v4l2_fmt, u32 width, u32 height);
 int venus_helper_set_input_resolution(struct venus_inst *inst,
  unsigned int width, unsigned int height);
 int venus_helper_set_output_resolution(struct venus_inst *inst,
diff --git a/drivers/media/platform/qcom/ven

[PATCH v2 25/29] venus: vdec: new function for output configuration

2018-05-15 Thread Stanimir Varbanov
Make a new function vdec_output_conf() for decoder output
configuration. vdec_output_conf() will set properties via
HFI interface related to the output configuration, and
keep vdec_set_properties() which will set properties
related to decoding parameters.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/vdec.c | 35 ++--
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/vdec.c 
b/drivers/media/platform/qcom/venus/vdec.c
index 5a5e3e2fece4..3a699af0ab58 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -545,6 +545,23 @@ static const struct v4l2_ioctl_ops vdec_ioctl_ops = {
 static int vdec_set_properties(struct venus_inst *inst)
 {
struct vdec_controls *ctr = >controls.dec;
+   struct hfi_enable en = { .enable = 1 };
+   u32 ptype;
+   int ret;
+
+   if (ctr->post_loop_deb_mode) {
+   ptype = HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER;
+   en.enable = 1;
+   ret = hfi_session_set_property(inst, ptype, );
+   if (ret)
+   return ret;
+   }
+
+   return 0;
+}
+
+static int vdec_output_conf(struct venus_inst *inst)
+{
struct venus_core *core = inst->core;
struct hfi_enable en = { .enable = 1 };
u32 ptype;
@@ -569,14 +586,6 @@ static int vdec_set_properties(struct venus_inst *inst)
if (ret)
return ret;
 
-   if (ctr->post_loop_deb_mode) {
-   ptype = HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER;
-   en.enable = 1;
-   ret = hfi_session_set_property(inst, ptype, );
-   if (ret)
-   return ret;
-   }
-
return 0;
 }
 
@@ -724,7 +733,6 @@ static int vdec_verify_conf(struct venus_inst *inst)
 static int vdec_start_streaming(struct vb2_queue *q, unsigned int count)
 {
struct venus_inst *inst = vb2_get_drv_priv(q);
-   struct venus_core *core = inst->core;
int ret;
 
mutex_lock(>lock);
@@ -753,12 +761,9 @@ static int vdec_start_streaming(struct vb2_queue *q, 
unsigned int count)
if (ret)
goto deinit_sess;
 
-   if (core->res->hfi_version == HFI_VERSION_3XX) {
-   ret = venus_helper_set_bufsize(inst, inst->output_buf_size,
-  HFI_BUFFER_OUTPUT);
-   if (ret)
-   goto deinit_sess;
-   }
+   ret = vdec_output_conf(inst);
+   if (ret)
+   goto deinit_sess;
 
ret = vdec_verify_conf(inst);
if (ret)
-- 
2.14.1



[PATCH v2 28/29] venus: add sdm845 compatible and resource data

2018-05-15 Thread Stanimir Varbanov
This adds sdm845 DT compatible string with it's resource
data table.

Reviewed-by: Rob Herring <r...@kernel.org>
Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 .../devicetree/bindings/media/qcom,venus.txt   |  1 +
 drivers/media/platform/qcom/venus/core.c   | 22 ++
 2 files changed, 23 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/qcom,venus.txt 
b/Documentation/devicetree/bindings/media/qcom,venus.txt
index 2693449daf73..00d0d1bf7647 100644
--- a/Documentation/devicetree/bindings/media/qcom,venus.txt
+++ b/Documentation/devicetree/bindings/media/qcom,venus.txt
@@ -6,6 +6,7 @@
Definition: Value should contain one of:
- "qcom,msm8916-venus"
- "qcom,msm8996-venus"
+   - "qcom,sdm845-venus"
 - reg:
Usage: required
Value type: 
diff --git a/drivers/media/platform/qcom/venus/core.c 
b/drivers/media/platform/qcom/venus/core.c
index 381bfdd688db..bb6add9d340e 100644
--- a/drivers/media/platform/qcom/venus/core.c
+++ b/drivers/media/platform/qcom/venus/core.c
@@ -450,9 +450,31 @@ static const struct venus_resources msm8996_res = {
.fwname = "qcom/venus-4.2/venus.mdt",
 };
 
+static const struct freq_tbl sdm845_freq_table[] = {
+   { 1944000, 38000 }, /* 4k UHD @ 60 */
+   {  972000, 32000 }, /* 4k UHD @ 30 */
+   {  489600, 2 }, /* 1080p @ 60 */
+   {  244800, 1 }, /* 1080p @ 30 */
+};
+
+static const struct venus_resources sdm845_res = {
+   .freq_tbl = sdm845_freq_table,
+   .freq_tbl_size = ARRAY_SIZE(sdm845_freq_table),
+   .clks = {"core", "iface", "bus" },
+   .clks_num = 3,
+   .max_load = 2563200,
+   .hfi_version = HFI_VERSION_4XX,
+   .vmem_id = VIDC_RESOURCE_NONE,
+   .vmem_size = 0,
+   .vmem_addr = 0,
+   .dma_mask = 0xe000 - 1,
+   .fwname = "qcom/venus-5.2/venus.mdt",
+};
+
 static const struct of_device_id venus_dt_match[] = {
{ .compatible = "qcom,msm8916-venus", .data = _res, },
{ .compatible = "qcom,msm8996-venus", .data = _res, },
+   { .compatible = "qcom,sdm845-venus", .data = _res, },
{ }
 };
 MODULE_DEVICE_TABLE(of, venus_dt_match);
-- 
2.14.1



[PATCH v2 29/29] venus: add HEVC codec support

2018-05-15 Thread Stanimir Varbanov
This add HEVC codec support for venus versions 3xx and 4xx.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/core.h|  2 ++
 drivers/media/platform/qcom/venus/helpers.c |  3 ++
 drivers/media/platform/qcom/venus/hfi.c |  2 ++
 drivers/media/platform/qcom/venus/vdec.c|  4 +++
 drivers/media/platform/qcom/venus/venc.c| 49 +
 5 files changed, 60 insertions(+)

diff --git a/drivers/media/platform/qcom/venus/core.h 
b/drivers/media/platform/qcom/venus/core.h
index 85e66e2dd672..2a956d1b9bd1 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -185,10 +185,12 @@ struct venc_controls {
u32 mpeg4;
u32 h264;
u32 vpx;
+   u32 hevc;
} profile;
struct {
u32 mpeg4;
u32 h264;
+   u32 hevc;
} level;
 };
 
diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index 87dcf9973e6f..fecadba039cf 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -71,6 +71,9 @@ bool venus_helper_check_codec(struct venus_inst *inst, u32 
v4l2_pixfmt)
case V4L2_PIX_FMT_XVID:
codec = HFI_VIDEO_CODEC_DIVX;
break;
+   case V4L2_PIX_FMT_HEVC:
+   codec = HFI_VIDEO_CODEC_HEVC;
+   break;
default:
return false;
}
diff --git a/drivers/media/platform/qcom/venus/hfi.c 
b/drivers/media/platform/qcom/venus/hfi.c
index 94ca27b0bb99..24207829982f 100644
--- a/drivers/media/platform/qcom/venus/hfi.c
+++ b/drivers/media/platform/qcom/venus/hfi.c
@@ -49,6 +49,8 @@ static u32 to_codec_type(u32 pixfmt)
return HFI_VIDEO_CODEC_VP9;
case V4L2_PIX_FMT_XVID:
return HFI_VIDEO_CODEC_DIVX;
+   case V4L2_PIX_FMT_HEVC:
+   return HFI_VIDEO_CODEC_HEVC;
default:
return 0;
}
diff --git a/drivers/media/platform/qcom/venus/vdec.c 
b/drivers/media/platform/qcom/venus/vdec.c
index d2d082009686..d2ffd9bd44de 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -77,6 +77,10 @@ static const struct venus_format vdec_formats[] = {
.pixfmt = V4L2_PIX_FMT_XVID,
.num_planes = 1,
.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+   }, {
+   .pixfmt = V4L2_PIX_FMT_HEVC,
+   .num_planes = 1,
+   .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
},
 };
 
diff --git a/drivers/media/platform/qcom/venus/venc.c 
b/drivers/media/platform/qcom/venus/venc.c
index a703bce78abc..50a04cb1cc22 100644
--- a/drivers/media/platform/qcom/venus/venc.c
+++ b/drivers/media/platform/qcom/venus/venc.c
@@ -59,6 +59,10 @@ static const struct venus_format venc_formats[] = {
.pixfmt = V4L2_PIX_FMT_VP8,
.num_planes = 1,
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+   }, {
+   .pixfmt = V4L2_PIX_FMT_HEVC,
+   .num_planes = 1,
+   .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
},
 };
 
@@ -220,6 +224,46 @@ static int venc_v4l2_to_hfi(int id, int value)
case 
V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY:
return HFI_H264_DB_MODE_SKIP_SLICE_BOUNDARY;
}
+   case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE:
+   switch (value) {
+   case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN:
+   default:
+   return HFI_HEVC_PROFILE_MAIN;
+   case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE:
+   return HFI_HEVC_PROFILE_MAIN_STILL_PIC;
+   case V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10:
+   return HFI_HEVC_PROFILE_MAIN10;
+   }
+   case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL:
+   switch (value) {
+   case V4L2_MPEG_VIDEO_HEVC_LEVEL_1:
+   default:
+   return HFI_HEVC_LEVEL_1;
+   case V4L2_MPEG_VIDEO_HEVC_LEVEL_2:
+   return HFI_HEVC_LEVEL_2;
+   case V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1:
+   return HFI_HEVC_LEVEL_21;
+   case V4L2_MPEG_VIDEO_HEVC_LEVEL_3:
+   return HFI_HEVC_LEVEL_3;
+   case V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1:
+   return HFI_HEVC_LEVEL_31;
+   case V4L2_MPEG_VIDEO_HEVC_LEVEL_4:
+   return HFI_HEVC_LEVEL_4;
+   case V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1:
+   return HFI_HEVC_LEVEL_41;
+   case V4L2_MPEG_VIDEO_HEVC_LEVEL_5:
+   return HFI_HEVC_LEVEL_5;
+ 

[PATCH v2 27/29] venus: implementing multi-stream support

2018-05-15 Thread Stanimir Varbanov
This is implementing a multi-stream decoder support. The multi
stream gives an option to use the secondary decoder output
with different raw format (or the same in case of crop).

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/core.h|   1 +
 drivers/media/platform/qcom/venus/helpers.c | 204 +++-
 drivers/media/platform/qcom/venus/helpers.h |   6 +
 drivers/media/platform/qcom/venus/vdec.c|  91 -
 drivers/media/platform/qcom/venus/venc.c|   1 +
 5 files changed, 299 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/core.h 
b/drivers/media/platform/qcom/venus/core.h
index 4d6c05f156c4..85e66e2dd672 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -259,6 +259,7 @@ struct venus_inst {
struct list_head list;
struct mutex lock;
struct venus_core *core;
+   struct list_head dpbbufs;
struct list_head internalbufs;
struct list_head registeredbufs;
struct list_head delayed_process;
diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index ed569705ecac..87dcf9973e6f 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -85,6 +85,112 @@ bool venus_helper_check_codec(struct venus_inst *inst, u32 
v4l2_pixfmt)
 }
 EXPORT_SYMBOL_GPL(venus_helper_check_codec);
 
+static int venus_helper_queue_dpb_bufs(struct venus_inst *inst)
+{
+   struct intbuf *buf;
+   int ret = 0;
+
+   if (list_empty(>dpbbufs))
+   return 0;
+
+   list_for_each_entry(buf, >dpbbufs, list) {
+   struct hfi_frame_data fdata;
+
+   memset(, 0, sizeof(fdata));
+   fdata.alloc_len = buf->size;
+   fdata.device_addr = buf->da;
+   fdata.buffer_type = buf->type;
+
+   ret = hfi_session_process_buf(inst, );
+   if (ret)
+   goto fail;
+   }
+
+fail:
+   return ret;
+}
+
+int venus_helper_free_dpb_bufs(struct venus_inst *inst)
+{
+   struct intbuf *buf, *n;
+
+   if (list_empty(>dpbbufs))
+   return 0;
+
+   list_for_each_entry_safe(buf, n, >dpbbufs, list) {
+   list_del_init(>list);
+   dma_free_attrs(inst->core->dev, buf->size, buf->va, buf->da,
+  buf->attrs);
+   kfree(buf);
+   }
+
+   INIT_LIST_HEAD(>dpbbufs);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(venus_helper_free_dpb_bufs);
+
+int venus_helper_alloc_dpb_bufs(struct venus_inst *inst)
+{
+   struct venus_core *core = inst->core;
+   struct device *dev = core->dev;
+   enum hfi_version ver = core->res->hfi_version;
+   struct hfi_buffer_requirements bufreq;
+   u32 buftype = inst->dpb_buftype;
+   unsigned int dpb_size = 0;
+   struct intbuf *buf;
+   unsigned int i;
+   u32 count;
+   int ret;
+
+   /* no need to allocate dpb buffers */
+   if (!inst->dpb_fmt)
+   return 0;
+
+   if (inst->dpb_buftype == HFI_BUFFER_OUTPUT)
+   dpb_size = inst->output_buf_size;
+   else if (inst->dpb_buftype == HFI_BUFFER_OUTPUT2)
+   dpb_size = inst->output2_buf_size;
+
+   if (!dpb_size)
+   return 0;
+
+   ret = venus_helper_get_bufreq(inst, buftype, );
+   if (ret)
+   return ret;
+
+   count = HFI_BUFREQ_COUNT_MIN(, ver);
+
+   for (i = 0; i < count; i++) {
+   buf = kzalloc(sizeof(*buf), GFP_KERNEL);
+   if (!buf) {
+   ret = -ENOMEM;
+   goto fail;
+   }
+
+   buf->type = buftype;
+   buf->size = dpb_size;
+   buf->attrs = DMA_ATTR_WRITE_COMBINE |
+DMA_ATTR_NO_KERNEL_MAPPING;
+   buf->va = dma_alloc_attrs(dev, buf->size, >da, GFP_KERNEL,
+ buf->attrs);
+   if (!buf->va) {
+   kfree(buf);
+   ret = -ENOMEM;
+   goto fail;
+   }
+
+   list_add_tail(>list, >dpbbufs);
+   }
+
+   return 0;
+
+fail:
+   venus_helper_free_dpb_bufs(inst);
+   return ret;
+}
+EXPORT_SYMBOL_GPL(venus_helper_alloc_dpb_bufs);
+
 static int intbufs_set_buffer(struct venus_inst *inst, u32 type)
 {
struct venus_core *core = inst->core;
@@ -342,7 +448,10 @@ session_process_buf(struct venus_inst *inst, struct 
vb2_v4l2_buffer *vbuf)
if (vbuf->flags & V4L2_BUF_FLAG_LAST || !fdata.filled_len)
fdata.flags |= HFI_BUFFERFLAG_EOS;
} else if (type == V4L2_BU

[PATCH v2 10/29] venus: hfi_venus: add suspend functionality for Venus 4xx

2018-05-15 Thread Stanimir Varbanov
This adds suspend (power collapse) functionality by reusing
the suspend function for Venus 3xx and also enables idle indicator
property for Venus 4xx (where it is disabled by default).

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/hfi_venus.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c 
b/drivers/media/platform/qcom/venus/hfi_venus.c
index 284da69eb81b..109116e1545d 100644
--- a/drivers/media/platform/qcom/venus/hfi_venus.c
+++ b/drivers/media/platform/qcom/venus/hfi_venus.c
@@ -878,6 +878,14 @@ static int venus_sys_set_default_properties(struct 
venus_hfi_device *hdev)
if (ret)
dev_warn(dev, "setting fw debug msg ON failed (%d)\n", ret);
 
+   /*
+* Idle indicator is disabled by default on some 4xx firmware versions,
+* enable it explicitly in order to make suspend functional by checking
+* WFI (wait-for-interrupt) bit.
+*/
+   if (IS_V4(hdev->core))
+   venus_sys_idle_indicator = true;
+
ret = venus_sys_set_idle_message(hdev, venus_sys_idle_indicator);
if (ret)
dev_warn(dev, "setting idle response ON failed (%d)\n", ret);
@@ -1525,7 +1533,8 @@ static int venus_suspend_3xx(struct venus_core *core)
 
 static int venus_suspend(struct venus_core *core)
 {
-   if (core->res->hfi_version == HFI_VERSION_3XX)
+   if (core->res->hfi_version == HFI_VERSION_3XX ||
+   core->res->hfi_version == HFI_VERSION_4XX)
return venus_suspend_3xx(core);
 
return venus_suspend_1xx(core);
-- 
2.14.1



Re: [PATCH 08/28] venus: hfi_venus: add suspend function for 4xx version

2018-05-09 Thread Stanimir Varbanov
Hi,

On 05/09/2018 05:14 PM, Vikash Garodia wrote:
> Hi Stanimir,
> 
> On 2018-05-09 16:45, Stanimir Varbanov wrote:
>> Hi Vikash,
>>
>> On 05/02/2018 09:07 AM, vgaro...@codeaurora.org wrote:
>>> Hello Stanimir,
>>>
>>> On 2018-04-24 18:14, Stanimir Varbanov wrote:
>>>> This adds suspend (power collapse) function with slightly
>>>> different order of calls comparing with Venus 3xx.
>>>>
>>>> Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
>>>> ---
>>>>  drivers/media/platform/qcom/venus/hfi_venus.c | 52
>>>> +++
>>>>  1 file changed, 52 insertions(+)
>>>>
>>>> diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c
>>>> b/drivers/media/platform/qcom/venus/hfi_venus.c
>>>> index 53546174aab8..f61d34bf61b4 100644
>>>> --- a/drivers/media/platform/qcom/venus/hfi_venus.c
>>>> +++ b/drivers/media/platform/qcom/venus/hfi_venus.c
>>>> @@ -1443,6 +1443,55 @@ static int venus_suspend_1xx(struct venus_core
>>>> *core)
>>>>  return 0;
>>>>  }
>>>>
>>>> +static int venus_suspend_4xx(struct venus_core *core)
>>>> +{
>>>> +    struct venus_hfi_device *hdev = to_hfi_priv(core);
>>>> +    struct device *dev = core->dev;
>>>> +    u32 val;
>>>> +    int ret;
>>>> +
>>>> +    if (!hdev->power_enabled || hdev->suspended)
>>>> +    return 0;
>>>> +
>>>> +    mutex_lock(>lock);
>>>> +    ret = venus_is_valid_state(hdev);
>>>> +    mutex_unlock(>lock);
>>>> +
>>>> +    if (!ret) {
>>>> +    dev_err(dev, "bad state, cannot suspend\n");
>>>> +    return -EINVAL;
>>>> +    }
>>>> +
>>>> +    ret = venus_prepare_power_collapse(hdev, false);
>>>> +    if (ret) {
>>>> +    dev_err(dev, "prepare for power collapse fail (%d)\n", ret);
>>>> +    return ret;
>>>> +    }
>>>> +
>>>> +    ret = readl_poll_timeout(core->base + CPU_CS_SCIACMDARG0, val,
>>>> + val & CPU_CS_SCIACMDARG0_PC_READY,
>>>> + POLL_INTERVAL_US, 10);
>>>> +    if (ret) {
>>>> +    dev_err(dev, "Polling power collapse ready timed out\n");
>>>> +    return ret;
>>>> +    }
>>>> +
>>>> +    mutex_lock(>lock);
>>>> +
>>>> +    ret = venus_power_off(hdev);
>>>> +    if (ret) {
>>>> +    dev_err(dev, "venus_power_off (%d)\n", ret);
>>>> +    mutex_unlock(>lock);
>>>> +    return ret;
>>>> +    }
>>>> +
>>>> +    hdev->suspended = true;
>>>> +
>>>> +    mutex_unlock(>lock);
>>>> +
>>>> +    return 0;
>>>> +}
>>>> +
>>>>  static int venus_suspend_3xx(struct venus_core *core)
>>>>  {
>>>>  struct venus_hfi_device *hdev = to_hfi_priv(core);
>>>> @@ -1507,6 +1556,9 @@ static int venus_suspend(struct venus_core *core)
>>>>  if (core->res->hfi_version == HFI_VERSION_3XX)
>>>>  return venus_suspend_3xx(core);
>>>>
>>>> +    if (core->res->hfi_version == HFI_VERSION_4XX)
>>>> +    return venus_suspend_4xx(core);
>>>> +
>>>>  return venus_suspend_1xx(core);
>>>>  }
>>>
>>> Let me brief on the power collapse sequence for Venus_4xx
>>> 1. Host checks for ARM9 and Video core to be idle.
>>>    This can be done by checking for WFI bit (bit 0) in CPU status
>>> register for ARM9 and by checking bit 30 in Control status reg for video
>>> core/s.
>>> 2. Host then sends command to ARM9 to prepare for power collapse.
>>> 3. Host then checks for WFI bit and PC_READY bit before withdrawing
>>> going for power off.
>>>
>>> As per this patch, host is preparing for power collapse without checking
>>> for #1.
>>> Update the code to handle #3.
>>
>> This looks similar to suspend for Venus 3xx. Can you confirm that the
>> sequence of checks for 4xx is the same as 3xx?
> 
> Do you mean the driver implementation for Suspend Venus 3xx or the hardware
> expectation for Venus 3xx ? If hardware expectation wise, the sequence is
> same for 3xx and 4xx.
> In the suspend implementation for 3xx, i see that the host just reads
> the WFI
> and idle status bits, but does not validate those bit value before
> preparing
> Venus for power collapse. Sequence #2 and #3 is followed for Venus 3xx
> implementation.

OK, than we can reuse venus_suspend_3xx function for 4xx, just need to
fix WFI and idle bit for #1.

-- 
regards,
Stan


Re: [PATCH 08/28] venus: hfi_venus: add suspend function for 4xx version

2018-05-09 Thread Stanimir Varbanov
Hi Vikash,

On 05/02/2018 09:07 AM, vgaro...@codeaurora.org wrote:
> Hello Stanimir,
> 
> On 2018-04-24 18:14, Stanimir Varbanov wrote:
>> This adds suspend (power collapse) function with slightly
>> different order of calls comparing with Venus 3xx.
>>
>> Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
>> ---
>>  drivers/media/platform/qcom/venus/hfi_venus.c | 52
>> +++
>>  1 file changed, 52 insertions(+)
>>
>> diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c
>> b/drivers/media/platform/qcom/venus/hfi_venus.c
>> index 53546174aab8..f61d34bf61b4 100644
>> --- a/drivers/media/platform/qcom/venus/hfi_venus.c
>> +++ b/drivers/media/platform/qcom/venus/hfi_venus.c
>> @@ -1443,6 +1443,55 @@ static int venus_suspend_1xx(struct venus_core
>> *core)
>>  return 0;
>>  }
>>
>> +static int venus_suspend_4xx(struct venus_core *core)
>> +{
>> +    struct venus_hfi_device *hdev = to_hfi_priv(core);
>> +    struct device *dev = core->dev;
>> +    u32 val;
>> +    int ret;
>> +
>> +    if (!hdev->power_enabled || hdev->suspended)
>> +    return 0;
>> +
>> +    mutex_lock(>lock);
>> +    ret = venus_is_valid_state(hdev);
>> +    mutex_unlock(>lock);
>> +
>> +    if (!ret) {
>> +    dev_err(dev, "bad state, cannot suspend\n");
>> +    return -EINVAL;
>> +    }
>> +
>> +    ret = venus_prepare_power_collapse(hdev, false);
>> +    if (ret) {
>> +    dev_err(dev, "prepare for power collapse fail (%d)\n", ret);
>> +    return ret;
>> +    }
>> +
>> +    ret = readl_poll_timeout(core->base + CPU_CS_SCIACMDARG0, val,
>> + val & CPU_CS_SCIACMDARG0_PC_READY,
>> + POLL_INTERVAL_US, 10);
>> +    if (ret) {
>> +    dev_err(dev, "Polling power collapse ready timed out\n");
>> +    return ret;
>> +    }
>> +
>> +    mutex_lock(>lock);
>> +
>> +    ret = venus_power_off(hdev);
>> +    if (ret) {
>> +    dev_err(dev, "venus_power_off (%d)\n", ret);
>> +    mutex_unlock(>lock);
>> +    return ret;
>> +    }
>> +
>> +    hdev->suspended = true;
>> +
>> +    mutex_unlock(>lock);
>> +
>> +    return 0;
>> +}
>> +
>>  static int venus_suspend_3xx(struct venus_core *core)
>>  {
>>  struct venus_hfi_device *hdev = to_hfi_priv(core);
>> @@ -1507,6 +1556,9 @@ static int venus_suspend(struct venus_core *core)
>>  if (core->res->hfi_version == HFI_VERSION_3XX)
>>  return venus_suspend_3xx(core);
>>
>> +    if (core->res->hfi_version == HFI_VERSION_4XX)
>> +    return venus_suspend_4xx(core);
>> +
>>  return venus_suspend_1xx(core);
>>  }
> 
> Let me brief on the power collapse sequence for Venus_4xx
> 1. Host checks for ARM9 and Video core to be idle.
>    This can be done by checking for WFI bit (bit 0) in CPU status
> register for ARM9 and by checking bit 30 in Control status reg for video
> core/s.
> 2. Host then sends command to ARM9 to prepare for power collapse.
> 3. Host then checks for WFI bit and PC_READY bit before withdrawing
> going for power off.
> 
> As per this patch, host is preparing for power collapse without checking
> for #1.
> Update the code to handle #3.

This looks similar to suspend for Venus 3xx. Can you confirm that the
sequence of checks for 4xx is the same as 3xx?

-- 
regards,
Stan


Re: [PATCH 10/28] venus: vdec: call session_continue in insufficient event

2018-05-09 Thread Stanimir Varbanov
Hi Vikash,

On 05/04/2018 02:09 PM, Vikash Garodia wrote:
> Hi Stanimir,
> 
> On 2018-05-03 17:06, Stanimir Varbanov wrote:
>> Hi Vikash,
>>
>> Thanks for the comments!
>>
>> On  2.05.2018 09:26, Vikash Garodia wrote:
>>> Hello Stanimir,
>>>
>>> On 2018-04-24 18:14, Stanimir Varbanov wrote:
>>>> Call session_continue for Venus 4xx version even when the event
>>>> says that the buffer resources are not sufficient. Leaving a
>>>> comment with more information about the workaround.
>>>>
>>>> Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
>>>> ---
>>>>  drivers/media/platform/qcom/venus/vdec.c | 8 
>>>>  1 file changed, 8 insertions(+)
>>>>
>>>> diff --git a/drivers/media/platform/qcom/venus/vdec.c
>>>> b/drivers/media/platform/qcom/venus/vdec.c
>>>> index c45452634e7e..91c7384ff9c8 100644
>>>> --- a/drivers/media/platform/qcom/venus/vdec.c
>>>> +++ b/drivers/media/platform/qcom/venus/vdec.c
>>>> @@ -873,6 +873,14 @@ static void vdec_event_notify(struct venus_inst
>>>> *inst, u32 event,
>>>>
>>>>  dev_dbg(dev, "event not sufficient resources (%ux%u)\n",
>>>>  data->width, data->height);
>>>> +    /*
>>>> + * Workaround: Even that the firmware send and event for
>>>> + * insufficient buffer resources it is safe to call
>>>> + * session_continue because actually the event says that
>>>> + * the number of capture buffers is lower.
>>>> + */
>>>> +    if (IS_V4(core))
>>>> +    hfi_session_continue(inst);
>>>>  break;
>>>>  case HFI_EVENT_RELEASE_BUFFER_REFERENCE:
>>>>  venus_helper_release_buf_ref(inst, data->tag);
>>>
>>> Insufficient event from video firmware could be sent either,
>>> 1. due to insufficient buffer resources
>>> 2. due to lower capture buffers
>>>
>>> It cannot be assumed that the event received by the host is due to
>>> lower capture
>>> buffers. Incase the buffer resource is insufficient, let say there is
>>> a bitstream
>>> resolution switch from 720p to 1080p, capture buffers needs to be
>>> reallocated.
>>
>> I agree with you. I will rework this part and call session_continue
>> only for case #2.
> 
> Even if the capture buffers are lower, driver should consider
> reallocation of capture
> buffers with required higher count. Without this, it may happen that for
> a given video
> frame, the decoded output will not be generated.

Thanks for the comments, I realized that this workaround is not needed
anymore, so I will drop the patch.

-- 
regards,
Stan


Re: [PATCH 00/28] Venus updates

2018-05-07 Thread Stanimir Varbanov

Hi Hans,

On  7.05.2018 13:41, Hans Verkuil wrote:

On 24/04/18 14:44, Stanimir Varbanov wrote:

Hello,

This patch set aims to:

* add initial support for Venus version 4xx (found on sdm845).

* introduce a common capability parser to enumerate better
   supported uncompressed formats, capabilities by codec,
   supported codecs and so on.

* also contains various cleanups, readability improvements
   and fixes.

* adds HEVC codec support for the Venus versions which has
   support for it.

* add multi-stream support (secondary decoder output), which
   will give as an opportunity to use UBWC compressed formats
   to optimize internal interconnect bandwidth on higher
   resolutions.


I'm a bit confused about this: is this a purely driver-internal thing,
or is this exposed somehow to userspace as well? It seems to be purely
internal.


For now it'll be internal for the driver. In downstream driver it is 
exposed to userspace via custom v4l_control but that is not generic and 
I decided to not expose it.


regards,
Stan


Re: [PATCH 28/28] venus: add HEVC codec support

2018-05-07 Thread Stanimir Varbanov

Hi Hans,

On  7.05.2018 13:39, Hans Verkuil wrote:

On 24/04/18 14:44, Stanimir Varbanov wrote:

This add HEVC codec support for venus versions 3xx and 4xx.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
  drivers/media/platform/qcom/venus/helpers.c | 3 +++
  drivers/media/platform/qcom/venus/hfi.c | 2 ++
  drivers/media/platform/qcom/venus/vdec.c| 4 
  drivers/media/platform/qcom/venus/venc.c| 4 
  4 files changed, 13 insertions(+)

diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index 87dcf9973e6f..fecadba039cf 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -71,6 +71,9 @@ bool venus_helper_check_codec(struct venus_inst *inst, u32 
v4l2_pixfmt)
case V4L2_PIX_FMT_XVID:
codec = HFI_VIDEO_CODEC_DIVX;
break;
+   case V4L2_PIX_FMT_HEVC:
+   codec = HFI_VIDEO_CODEC_HEVC;
+   break;
default:
return false;
}
diff --git a/drivers/media/platform/qcom/venus/hfi.c 
b/drivers/media/platform/qcom/venus/hfi.c
index 94ca27b0bb99..24207829982f 100644
--- a/drivers/media/platform/qcom/venus/hfi.c
+++ b/drivers/media/platform/qcom/venus/hfi.c
@@ -49,6 +49,8 @@ static u32 to_codec_type(u32 pixfmt)
return HFI_VIDEO_CODEC_VP9;
case V4L2_PIX_FMT_XVID:
return HFI_VIDEO_CODEC_DIVX;
+   case V4L2_PIX_FMT_HEVC:
+   return HFI_VIDEO_CODEC_HEVC;
default:
return 0;
}
diff --git a/drivers/media/platform/qcom/venus/vdec.c 
b/drivers/media/platform/qcom/venus/vdec.c
index 7deee104ac56..a114f421edad 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -77,6 +77,10 @@ static const struct venus_format vdec_formats[] = {
.pixfmt = V4L2_PIX_FMT_XVID,
.num_planes = 1,
.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+   }, {
+   .pixfmt = V4L2_PIX_FMT_HEVC,
+   .num_planes = 1,
+   .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
},
  };
  
diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c

index a703bce78abc..fdb76b69786f 100644
--- a/drivers/media/platform/qcom/venus/venc.c
+++ b/drivers/media/platform/qcom/venus/venc.c
@@ -59,6 +59,10 @@ static const struct venus_format venc_formats[] = {
.pixfmt = V4L2_PIX_FMT_VP8,
.num_planes = 1,
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+   }, {
+   .pixfmt = V4L2_PIX_FMT_HEVC,
+   .num_planes = 1,
+   .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
},
  };
  



No changes are necessary to venc_set_properties() for HEVC support?

Just checking, I kind of expected that.


yes, I think so, but will leave that for future updates.

regards,
Stan


Re: [PATCH 10/28] venus: vdec: call session_continue in insufficient event

2018-05-03 Thread Stanimir Varbanov

Hi Vikash,

Thanks for the comments!

On  2.05.2018 09:26, Vikash Garodia wrote:

Hello Stanimir,

On 2018-04-24 18:14, Stanimir Varbanov wrote:

Call session_continue for Venus 4xx version even when the event
says that the buffer resources are not sufficient. Leaving a
comment with more information about the workaround.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/vdec.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/media/platform/qcom/venus/vdec.c
b/drivers/media/platform/qcom/venus/vdec.c
index c45452634e7e..91c7384ff9c8 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -873,6 +873,14 @@ static void vdec_event_notify(struct venus_inst
*inst, u32 event,

 dev_dbg(dev, "event not sufficient resources (%ux%u)\n",
 data->width, data->height);
+    /*
+ * Workaround: Even that the firmware send and event for
+ * insufficient buffer resources it is safe to call
+ * session_continue because actually the event says that
+ * the number of capture buffers is lower.
+ */
+    if (IS_V4(core))
+    hfi_session_continue(inst);
 break;
 case HFI_EVENT_RELEASE_BUFFER_REFERENCE:
 venus_helper_release_buf_ref(inst, data->tag);


Insufficient event from video firmware could be sent either,
1. due to insufficient buffer resources
2. due to lower capture buffers

It cannot be assumed that the event received by the host is due to lower 
capture
buffers. Incase the buffer resource is insufficient, let say there is a 
bitstream
resolution switch from 720p to 1080p, capture buffers needs to be 
reallocated.


I agree with you. I will rework this part and call session_continue only 
for case #2.




The driver should be sending the V4L2_EVENT_SOURCE_CHANGE to client 
instead of ignoring

the event from firmware.


The v4l2 event is sent always to v4l clients.

regards,
Stan


Re: [PATCH 26/28] venus: implementing multi-stream support

2018-05-03 Thread Stanimir Varbanov

Hi Vikash,

Please write the comments for the chunk of code for which they are refer to.

On  2.05.2018 10:40, Vikash Garodia wrote:

Hello Stanimir,

On 2018-04-24 18:14, Stanimir Varbanov wrote:

This is implementing a multi-stream decoder support. The multi
stream gives an option to use the secondary decoder output
with different raw format (or the same in case of crop).

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/core.h    |   1 +
 drivers/media/platform/qcom/venus/helpers.c | 204 
+++-

 drivers/media/platform/qcom/venus/helpers.h |   6 +
 drivers/media/platform/qcom/venus/vdec.c    |  91 -
 drivers/media/platform/qcom/venus/venc.c    |   1 +
 5 files changed, 299 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/core.h
b/drivers/media/platform/qcom/venus/core.h
index 4d6c05f156c4..85e66e2dd672 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -259,6 +259,7 @@ struct venus_inst {
 struct list_head list;
 struct mutex lock;
 struct venus_core *core;
+    struct list_head dpbbufs;
 struct list_head internalbufs;
 struct list_head registeredbufs;
 struct list_head delayed_process;






The dpb buffers queued to hardware will be returned back to host either 
during flush
or when the session is stopped. Host should not send these buffers to 
client.


That's correct.

vdec_buf_done should be handling in a way to drop dpb buffers from 
sending to client.


That is also correct, vdec_buf_done is trying to find the buffer by 
index from a list of queued buffers from v4l2 clients. See 
venus_helper_vb2_buf_queue where it is calling v4l2_m2m_buf_queue.


So for the dpb buffers venus_helper_find_buf() will return NULL.

regards,
Stan


[PATCH 01/28] venus: hfi_msgs: correct pointer increment

2018-04-24 Thread Stanimir Varbanov
Data pointer should be incremented by size of the structure not
the size of a pointer, correct the mistake.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/hfi_msgs.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/hfi_msgs.c 
b/drivers/media/platform/qcom/venus/hfi_msgs.c
index 90c93d9603dc..589e1a6b36a9 100644
--- a/drivers/media/platform/qcom/venus/hfi_msgs.c
+++ b/drivers/media/platform/qcom/venus/hfi_msgs.c
@@ -60,14 +60,14 @@ static void event_seq_changed(struct venus_core *core, 
struct venus_inst *inst,
frame_sz = (struct hfi_framesize *)data_ptr;
event.width = frame_sz->width;
event.height = frame_sz->height;
-   data_ptr += sizeof(frame_sz);
+   data_ptr += sizeof(*frame_sz);
break;
case HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT:
data_ptr += sizeof(u32);
profile_level = (struct hfi_profile_level *)data_ptr;
event.profile = profile_level->profile;
event.level = profile_level->level;
-   data_ptr += sizeof(profile_level);
+   data_ptr += sizeof(*profile_level);
break;
default:
break;
-- 
2.14.1



[PATCH 03/28] venus: hfi: update sequence event to handle more properties

2018-04-24 Thread Stanimir Varbanov
HFI version 4xx can pass more properties in the sequence change
event, extend the event structure with them.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/hfi.h  |  9 ++
 drivers/media/platform/qcom/venus/hfi_msgs.c | 46 
 2 files changed, 55 insertions(+)

diff --git a/drivers/media/platform/qcom/venus/hfi.h 
b/drivers/media/platform/qcom/venus/hfi.h
index 5466b7d60dd0..21376d93170f 100644
--- a/drivers/media/platform/qcom/venus/hfi.h
+++ b/drivers/media/platform/qcom/venus/hfi.h
@@ -74,6 +74,15 @@ struct hfi_event_data {
u32 tag;
u32 profile;
u32 level;
+   u32 bit_depth;
+   u32 pic_struct;
+   u32 colour_space;
+   u32 entropy_mode;
+   u32 buf_count;
+   struct {
+   u32 left, top;
+   u32 width, height;
+   } input_crop;
 };
 
 /* define core states */
diff --git a/drivers/media/platform/qcom/venus/hfi_msgs.c 
b/drivers/media/platform/qcom/venus/hfi_msgs.c
index 589e1a6b36a9..5970e9b1716b 100644
--- a/drivers/media/platform/qcom/venus/hfi_msgs.c
+++ b/drivers/media/platform/qcom/venus/hfi_msgs.c
@@ -25,10 +25,17 @@
 static void event_seq_changed(struct venus_core *core, struct venus_inst *inst,
  struct hfi_msg_event_notify_pkt *pkt)
 {
+   enum hfi_version ver = core->res->hfi_version;
struct hfi_event_data event = {0};
int num_properties_changed;
struct hfi_framesize *frame_sz;
struct hfi_profile_level *profile_level;
+   struct hfi_bit_depth *pixel_depth;
+   struct hfi_pic_struct *pic_struct;
+   struct hfi_colour_space *colour_info;
+   struct hfi_buffer_requirements *bufreq;
+   struct hfi_extradata_input_crop *crop;
+   u32 entropy_mode = 0;
u8 *data_ptr;
u32 ptype;
 
@@ -69,6 +76,45 @@ static void event_seq_changed(struct venus_core *core, 
struct venus_inst *inst,
event.level = profile_level->level;
data_ptr += sizeof(*profile_level);
break;
+   case HFI_PROPERTY_PARAM_VDEC_PIXEL_BITDEPTH:
+   data_ptr += sizeof(u32);
+   pixel_depth = (struct hfi_bit_depth *)data_ptr;
+   event.bit_depth = pixel_depth->bit_depth;
+   data_ptr += sizeof(*pixel_depth);
+   break;
+   case HFI_PROPERTY_PARAM_VDEC_PIC_STRUCT:
+   data_ptr += sizeof(u32);
+   pic_struct = (struct hfi_pic_struct *)data_ptr;
+   event.pic_struct = pic_struct->progressive_only;
+   data_ptr += sizeof(*pic_struct);
+   break;
+   case HFI_PROPERTY_PARAM_VDEC_COLOUR_SPACE:
+   data_ptr += sizeof(u32);
+   colour_info = (struct hfi_colour_space *)data_ptr;
+   event.colour_space = colour_info->colour_space;
+   data_ptr += sizeof(*colour_info);
+   break;
+   case HFI_PROPERTY_CONFIG_VDEC_ENTROPY:
+   data_ptr += sizeof(u32);
+   entropy_mode = *(u32 *)data_ptr;
+   event.entropy_mode = entropy_mode;
+   data_ptr += sizeof(u32);
+   break;
+   case HFI_PROPERTY_CONFIG_BUFFER_REQUIREMENTS:
+   data_ptr += sizeof(u32);
+   bufreq = (struct hfi_buffer_requirements *)data_ptr;
+   event.buf_count = HFI_BUFREQ_COUNT_MIN(bufreq, ver);
+   data_ptr += sizeof(*bufreq);
+   break;
+   case HFI_INDEX_EXTRADATA_INPUT_CROP:
+   data_ptr += sizeof(u32);
+   crop = (struct hfi_extradata_input_crop *)data_ptr;
+   event.input_crop.left = crop->left;
+   event.input_crop.top = crop->top;
+   event.input_crop.width = crop->width;
+   event.input_crop.height = crop->height;
+   data_ptr += sizeof(*crop);
+   break;
default:
break;
}
-- 
2.14.1



[PATCH 02/28] venus: hfi: preparation to support venus 4xx

2018-04-24 Thread Stanimir Varbanov
This covers the differences between 1xx,3xx and 4xx.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/core.h |  4 ++
 drivers/media/platform/qcom/venus/helpers.c  | 37 +++
 drivers/media/platform/qcom/venus/hfi_helper.h   | 84 ++--
 drivers/media/platform/qcom/venus/hfi_venus_io.h | 24 +++
 drivers/media/platform/qcom/venus/vdec.c |  5 +-
 drivers/media/platform/qcom/venus/venc.c |  5 +-
 6 files changed, 137 insertions(+), 22 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/core.h 
b/drivers/media/platform/qcom/venus/core.h
index 0360d295f4c8..8d3e150800c9 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -305,6 +305,10 @@ struct venus_inst {
struct hfi_buffer_requirements bufreq[HFI_BUFFER_TYPE_MAX];
 };
 
+#define IS_V1(core)((core)->res->hfi_version == HFI_VERSION_1XX)
+#define IS_V3(core)((core)->res->hfi_version == HFI_VERSION_3XX)
+#define IS_V4(core)((core)->res->hfi_version == HFI_VERSION_4XX)
+
 #define ctrl_to_inst(ctrl) \
container_of((ctrl)->handler, struct venus_inst, ctrl_handler)
 
diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index 0ce9559a2924..d9065cc8a7d3 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -166,21 +166,37 @@ static int intbufs_unset_buffers(struct venus_inst *inst)
return ret;
 }
 
-static const unsigned int intbuf_types[] = {
-   HFI_BUFFER_INTERNAL_SCRATCH,
-   HFI_BUFFER_INTERNAL_SCRATCH_1,
-   HFI_BUFFER_INTERNAL_SCRATCH_2,
+static const unsigned int intbuf_types_1xx[] = {
+   HFI_BUFFER_INTERNAL_SCRATCH(HFI_VERSION_1XX),
+   HFI_BUFFER_INTERNAL_SCRATCH_1(HFI_VERSION_1XX),
+   HFI_BUFFER_INTERNAL_SCRATCH_2(HFI_VERSION_1XX),
+   HFI_BUFFER_INTERNAL_PERSIST,
+   HFI_BUFFER_INTERNAL_PERSIST_1,
+};
+
+static const unsigned int intbuf_types_4xx[] = {
+   HFI_BUFFER_INTERNAL_SCRATCH(HFI_VERSION_4XX),
+   HFI_BUFFER_INTERNAL_SCRATCH_1(HFI_VERSION_4XX),
+   HFI_BUFFER_INTERNAL_SCRATCH_2(HFI_VERSION_4XX),
HFI_BUFFER_INTERNAL_PERSIST,
HFI_BUFFER_INTERNAL_PERSIST_1,
 };
 
 static int intbufs_alloc(struct venus_inst *inst)
 {
-   unsigned int i;
+   size_t arr_sz;
+   size_t i;
int ret;
 
-   for (i = 0; i < ARRAY_SIZE(intbuf_types); i++) {
-   ret = intbufs_set_buffer(inst, intbuf_types[i]);
+   if (IS_V4(inst->core))
+   arr_sz = ARRAY_SIZE(intbuf_types_4xx);
+   else
+   arr_sz = ARRAY_SIZE(intbuf_types_1xx);
+
+   for (i = 0; i < arr_sz; i++) {
+   ret = intbufs_set_buffer(inst,
+   IS_V4(inst->core) ? intbuf_types_4xx[i] :
+   intbuf_types_1xx[i]);
if (ret)
goto error;
}
@@ -257,12 +273,11 @@ static int load_scale_clocks(struct venus_core *core)
 
 set_freq:
 
-   if (core->res->hfi_version == HFI_VERSION_3XX) {
-   ret = clk_set_rate(clk, freq);
+   ret = clk_set_rate(clk, freq);
+
+   if (IS_V3(core) || IS_V4(core)) {
ret |= clk_set_rate(core->core0_clk, freq);
ret |= clk_set_rate(core->core1_clk, freq);
-   } else {
-   ret = clk_set_rate(clk, freq);
}
 
if (ret) {
diff --git a/drivers/media/platform/qcom/venus/hfi_helper.h 
b/drivers/media/platform/qcom/venus/hfi_helper.h
index 55d8eb21403a..1bc5aab1ce6b 100644
--- a/drivers/media/platform/qcom/venus/hfi_helper.h
+++ b/drivers/media/platform/qcom/venus/hfi_helper.h
@@ -121,6 +121,7 @@
 #define HFI_EXTRADATA_METADATA_FILLER  0x7fe2
 
 #define HFI_INDEX_EXTRADATA_INPUT_CROP 0x070e
+#define HFI_INDEX_EXTRADATA_OUTPUT_CROP0x070f
 #define HFI_INDEX_EXTRADATA_DIGITAL_ZOOM   0x0710
 #define HFI_INDEX_EXTRADATA_ASPECT_RATIO   0x7f13
 
@@ -376,13 +377,18 @@
 #define HFI_BUFFER_OUTPUT2 0x3
 #define HFI_BUFFER_INTERNAL_PERSIST0x4
 #define HFI_BUFFER_INTERNAL_PERSIST_1  0x5
-#define HFI_BUFFER_INTERNAL_SCRATCH0x101
-#define HFI_BUFFER_EXTRADATA_INPUT 0x102
-#define HFI_BUFFER_EXTRADATA_OUTPUT0x103
-#define HFI_BUFFER_EXTRADATA_OUTPUT2   0x104
-#define HFI_BUFFER_INTERNAL_SCRATCH_1  0x105
-#define HFI_BUFFER_INTERNAL_SCRATCH_2  0x106
-
+#define HFI_BUFFER_INTERNAL_SCRATCH(ver)   \
+   (((ver) == HFI_VERSION_4XX) ? 0x6 : 0x101)
+#define HFI_BUFFER_INTERNAL_SCRATCH_1(ver) \
+   (((ver) == HFI_VERSION_4XX) ? 0x7 : 0x105)
+#define HFI_BUFFER_INTERNAL_SCRATCH_2(v

[PATCH 05/28] venus: hfi: support session continue for 4xx version

2018-04-24 Thread Stanimir Varbanov
This makes possible to handle session_continue for 4xx as well.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/hfi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/qcom/venus/hfi.c 
b/drivers/media/platform/qcom/venus/hfi.c
index bca894a00c07..cbc6fad05e47 100644
--- a/drivers/media/platform/qcom/venus/hfi.c
+++ b/drivers/media/platform/qcom/venus/hfi.c
@@ -312,7 +312,7 @@ int hfi_session_continue(struct venus_inst *inst)
 {
struct venus_core *core = inst->core;
 
-   if (core->res->hfi_version != HFI_VERSION_3XX)
+   if (core->res->hfi_version == HFI_VERSION_1XX)
return 0;
 
return core->ops->session_continue(inst);
-- 
2.14.1



[PATCH 06/28] venus: hfi: handle buffer output2 type as well

2018-04-24 Thread Stanimir Varbanov
This adds handling of buffers of type OUTPUT2 which is needed to
support Venus 4xx version.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/hfi.c  | 3 ++-
 drivers/media/platform/qcom/venus/hfi_msgs.c | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/hfi.c 
b/drivers/media/platform/qcom/venus/hfi.c
index cbc6fad05e47..a570fdad0de0 100644
--- a/drivers/media/platform/qcom/venus/hfi.c
+++ b/drivers/media/platform/qcom/venus/hfi.c
@@ -473,7 +473,8 @@ int hfi_session_process_buf(struct venus_inst *inst, struct 
hfi_frame_data *fd)
 
if (fd->buffer_type == HFI_BUFFER_INPUT)
return ops->session_etb(inst, fd);
-   else if (fd->buffer_type == HFI_BUFFER_OUTPUT)
+   else if (fd->buffer_type == HFI_BUFFER_OUTPUT ||
+fd->buffer_type == HFI_BUFFER_OUTPUT2)
return ops->session_ftb(inst, fd);
 
return -EINVAL;
diff --git a/drivers/media/platform/qcom/venus/hfi_msgs.c 
b/drivers/media/platform/qcom/venus/hfi_msgs.c
index 5970e9b1716b..023802e62833 100644
--- a/drivers/media/platform/qcom/venus/hfi_msgs.c
+++ b/drivers/media/platform/qcom/venus/hfi_msgs.c
@@ -825,7 +825,8 @@ static void hfi_session_ftb_done(struct venus_core *core,
error = HFI_ERR_SESSION_INVALID_PARAMETER;
}
 
-   if (buffer_type != HFI_BUFFER_OUTPUT)
+   if (buffer_type != HFI_BUFFER_OUTPUT &&
+   buffer_type != HFI_BUFFER_OUTPUT2)
goto done;
 
if (hfi_flags & HFI_BUFFERFLAG_EOS)
-- 
2.14.1



[PATCH 08/28] venus: hfi_venus: add suspend function for 4xx version

2018-04-24 Thread Stanimir Varbanov
This adds suspend (power collapse) function with slightly
different order of calls comparing with Venus 3xx.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/hfi_venus.c | 52 +++
 1 file changed, 52 insertions(+)

diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c 
b/drivers/media/platform/qcom/venus/hfi_venus.c
index 53546174aab8..f61d34bf61b4 100644
--- a/drivers/media/platform/qcom/venus/hfi_venus.c
+++ b/drivers/media/platform/qcom/venus/hfi_venus.c
@@ -1443,6 +1443,55 @@ static int venus_suspend_1xx(struct venus_core *core)
return 0;
 }
 
+static int venus_suspend_4xx(struct venus_core *core)
+{
+   struct venus_hfi_device *hdev = to_hfi_priv(core);
+   struct device *dev = core->dev;
+   u32 val;
+   int ret;
+
+   if (!hdev->power_enabled || hdev->suspended)
+   return 0;
+
+   mutex_lock(>lock);
+   ret = venus_is_valid_state(hdev);
+   mutex_unlock(>lock);
+
+   if (!ret) {
+   dev_err(dev, "bad state, cannot suspend\n");
+   return -EINVAL;
+   }
+
+   ret = venus_prepare_power_collapse(hdev, false);
+   if (ret) {
+   dev_err(dev, "prepare for power collapse fail (%d)\n", ret);
+   return ret;
+   }
+
+   ret = readl_poll_timeout(core->base + CPU_CS_SCIACMDARG0, val,
+val & CPU_CS_SCIACMDARG0_PC_READY,
+POLL_INTERVAL_US, 10);
+   if (ret) {
+   dev_err(dev, "Polling power collapse ready timed out\n");
+   return ret;
+   }
+
+   mutex_lock(>lock);
+
+   ret = venus_power_off(hdev);
+   if (ret) {
+   dev_err(dev, "venus_power_off (%d)\n", ret);
+   mutex_unlock(>lock);
+   return ret;
+   }
+
+   hdev->suspended = true;
+
+   mutex_unlock(>lock);
+
+   return 0;
+}
+
 static int venus_suspend_3xx(struct venus_core *core)
 {
struct venus_hfi_device *hdev = to_hfi_priv(core);
@@ -1507,6 +1556,9 @@ static int venus_suspend(struct venus_core *core)
if (core->res->hfi_version == HFI_VERSION_3XX)
return venus_suspend_3xx(core);
 
+   if (core->res->hfi_version == HFI_VERSION_4XX)
+   return venus_suspend_4xx(core);
+
return venus_suspend_1xx(core);
 }
 
-- 
2.14.1



[PATCH 07/28] venus: hfi_venus: add halt AXI support for Venus 4xx

2018-04-24 Thread Stanimir Varbanov
Add AXI halt support for version 4xx by using venus wrapper
registers.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/hfi_venus.c | 17 +
 1 file changed, 17 insertions(+)

diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c 
b/drivers/media/platform/qcom/venus/hfi_venus.c
index 734ce11b0ed0..53546174aab8 100644
--- a/drivers/media/platform/qcom/venus/hfi_venus.c
+++ b/drivers/media/platform/qcom/venus/hfi_venus.c
@@ -532,6 +532,23 @@ static int venus_halt_axi(struct venus_hfi_device *hdev)
u32 val;
int ret;
 
+   if (hdev->core->res->hfi_version == HFI_VERSION_4XX) {
+   val = venus_readl(hdev, WRAPPER_CPU_AXI_HALT);
+   val |= BIT(16);
+   venus_writel(hdev, WRAPPER_CPU_AXI_HALT, val);
+
+   ret = readl_poll_timeout(base + WRAPPER_CPU_AXI_HALT_STATUS,
+val, val & BIT(24),
+POLL_INTERVAL_US,
+VBIF_AXI_HALT_ACK_TIMEOUT_US);
+   if (ret) {
+   dev_err(dev, "AXI bus port halt timeout\n");
+   return ret;
+   }
+
+   return 0;
+   }
+
/* Halt AXI and AXI IMEM VBIF Access */
val = venus_readl(hdev, VBIF_AXI_HALT_CTRL0);
val |= VBIF_AXI_HALT_CTRL0_HALT_REQ;
-- 
2.14.1



[PATCH 09/28] venus: venc,vdec: adds clocks needed for venus 4xx

2018-04-24 Thread Stanimir Varbanov
This extends the clocks number to support suspend and resume
on Venus version 4xx.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/core.h |  4 +--
 drivers/media/platform/qcom/venus/vdec.c | 42 ++--
 drivers/media/platform/qcom/venus/venc.c | 42 ++--
 3 files changed, 72 insertions(+), 16 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/core.h 
b/drivers/media/platform/qcom/venus/core.h
index 8d3e150800c9..b5b9a84e9155 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -92,8 +92,8 @@ struct venus_core {
void __iomem *base;
int irq;
struct clk *clks[VIDC_CLKS_NUM_MAX];
-   struct clk *core0_clk;
-   struct clk *core1_clk;
+   struct clk *core0_clk, *core0_bus_clk;
+   struct clk *core1_clk, *core1_bus_clk;
struct video_device *vdev_dec;
struct video_device *vdev_enc;
struct v4l2_device v4l2_dev;
diff --git a/drivers/media/platform/qcom/venus/vdec.c 
b/drivers/media/platform/qcom/venus/vdec.c
index 261a51adeef2..c45452634e7e 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -1081,12 +1081,18 @@ static int vdec_probe(struct platform_device *pdev)
if (!core)
return -EPROBE_DEFER;
 
-   if (core->res->hfi_version == HFI_VERSION_3XX) {
+   if (IS_V3(core) || IS_V4(core)) {
core->core0_clk = devm_clk_get(dev, "core");
if (IS_ERR(core->core0_clk))
return PTR_ERR(core->core0_clk);
}
 
+   if (IS_V4(core)) {
+   core->core0_bus_clk = devm_clk_get(dev, "bus");
+   if (IS_ERR(core->core0_bus_clk))
+   return PTR_ERR(core->core0_bus_clk);
+   }
+
platform_set_drvdata(pdev, core);
 
vdev = video_device_alloc();
@@ -1132,12 +1138,23 @@ static __maybe_unused int vdec_runtime_suspend(struct 
device *dev)
 {
struct venus_core *core = dev_get_drvdata(dev);
 
-   if (core->res->hfi_version == HFI_VERSION_1XX)
+   if (IS_V1(core))
return 0;
 
-   writel(0, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
+   if (IS_V3(core))
+   writel(0, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
+   else if (IS_V4(core))
+   writel(0, core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL);
+
+   if (IS_V4(core))
+   clk_disable_unprepare(core->core0_bus_clk);
+
clk_disable_unprepare(core->core0_clk);
-   writel(1, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
+
+   if (IS_V3(core))
+   writel(1, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
+   else if (IS_V4(core))
+   writel(1, core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL);
 
return 0;
 }
@@ -1147,12 +1164,23 @@ static __maybe_unused int vdec_runtime_resume(struct 
device *dev)
struct venus_core *core = dev_get_drvdata(dev);
int ret;
 
-   if (core->res->hfi_version == HFI_VERSION_1XX)
+   if (IS_V1(core))
return 0;
 
-   writel(0, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
+   if (IS_V3(core))
+   writel(0, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
+   else if (IS_V4(core))
+   writel(0, core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL);
+
ret = clk_prepare_enable(core->core0_clk);
-   writel(1, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
+
+   if (IS_V4(core))
+   ret |= clk_prepare_enable(core->core0_bus_clk);
+
+   if (IS_V3(core))
+   writel(1, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
+   else if (IS_V4(core))
+   writel(1, core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL);
 
return ret;
 }
diff --git a/drivers/media/platform/qcom/venus/venc.c 
b/drivers/media/platform/qcom/venus/venc.c
index 947001170a77..bc8c2e7a8d2c 100644
--- a/drivers/media/platform/qcom/venus/venc.c
+++ b/drivers/media/platform/qcom/venus/venc.c
@@ -1225,12 +1225,18 @@ static int venc_probe(struct platform_device *pdev)
if (!core)
return -EPROBE_DEFER;
 
-   if (core->res->hfi_version == HFI_VERSION_3XX) {
+   if (IS_V3(core) || IS_V4(core)) {
core->core1_clk = devm_clk_get(dev, "core");
if (IS_ERR(core->core1_clk))
return PTR_ERR(core->core1_clk);
}
 
+   if (IS_V4(core)) {
+   core->core1_bus_clk = devm_clk_get(dev, "bus");
+   if (IS_ERR(core->core1_bus_clk))
+   return PTR_ERR(core->core1_bus_clk);
+   }
+
platform_set_drvdata(pdev, core);
 
   

[PATCH 11/28] venus: add common capability parser

2018-04-24 Thread Stanimir Varbanov
This adds common capability parser for all supported Venus
versions. Having it will help to enumerate better the supported
raw formars and codecs and also the capabilities for every
codec like max/min width/height, framerate, bitrate and so on.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/Makefile |   3 +-
 drivers/media/platform/qcom/venus/core.c   |  80 ++
 drivers/media/platform/qcom/venus/core.h   |  68 +++--
 drivers/media/platform/qcom/venus/hfi.c|   5 +-
 drivers/media/platform/qcom/venus/hfi_helper.h |  28 +-
 drivers/media/platform/qcom/venus/hfi_msgs.c   | 348 ++---
 drivers/media/platform/qcom/venus/hfi_parser.c | 294 +
 drivers/media/platform/qcom/venus/hfi_parser.h |  45 
 drivers/media/platform/qcom/venus/vdec.c   |  38 +--
 drivers/media/platform/qcom/venus/venc.c   |  52 ++--
 10 files changed, 524 insertions(+), 437 deletions(-)
 create mode 100644 drivers/media/platform/qcom/venus/hfi_parser.c
 create mode 100644 drivers/media/platform/qcom/venus/hfi_parser.h

diff --git a/drivers/media/platform/qcom/venus/Makefile 
b/drivers/media/platform/qcom/venus/Makefile
index bfd4edf7c83f..b44b11b03e12 100644
--- a/drivers/media/platform/qcom/venus/Makefile
+++ b/drivers/media/platform/qcom/venus/Makefile
@@ -2,7 +2,8 @@
 # Makefile for Qualcomm Venus driver
 
 venus-core-objs += core.o helpers.o firmware.o \
-  hfi_venus.o hfi_msgs.o hfi_cmds.o hfi.o
+  hfi_venus.o hfi_msgs.o hfi_cmds.o hfi.o \
+  hfi_parser.o
 
 venus-dec-objs += vdec.o vdec_ctrls.o
 venus-enc-objs += venc.o venc_ctrls.o
diff --git a/drivers/media/platform/qcom/venus/core.c 
b/drivers/media/platform/qcom/venus/core.c
index 41eef376eb2d..1b72bfbb6297 100644
--- a/drivers/media/platform/qcom/venus/core.c
+++ b/drivers/media/platform/qcom/venus/core.c
@@ -152,6 +152,78 @@ static void venus_clks_disable(struct venus_core *core)
clk_disable_unprepare(core->clks[i]);
 }
 
+static u32 to_v4l2_codec_type(u32 codec)
+{
+   switch (codec) {
+   case HFI_VIDEO_CODEC_H264:
+   return V4L2_PIX_FMT_H264;
+   case HFI_VIDEO_CODEC_H263:
+   return V4L2_PIX_FMT_H263;
+   case HFI_VIDEO_CODEC_MPEG1:
+   return V4L2_PIX_FMT_MPEG1;
+   case HFI_VIDEO_CODEC_MPEG2:
+   return V4L2_PIX_FMT_MPEG2;
+   case HFI_VIDEO_CODEC_MPEG4:
+   return V4L2_PIX_FMT_MPEG4;
+   case HFI_VIDEO_CODEC_VC1:
+   return V4L2_PIX_FMT_VC1_ANNEX_G;
+   case HFI_VIDEO_CODEC_VP8:
+   return V4L2_PIX_FMT_VP8;
+   case HFI_VIDEO_CODEC_VP9:
+   return V4L2_PIX_FMT_VP9;
+   case HFI_VIDEO_CODEC_DIVX:
+   case HFI_VIDEO_CODEC_DIVX_311:
+   return V4L2_PIX_FMT_XVID;
+   default:
+   return 0;
+   }
+}
+
+static int venus_enumerate_codecs(struct venus_core *core, u32 type)
+{
+   const struct hfi_inst_ops dummy_ops = {};
+   struct venus_inst inst;
+   unsigned int i;
+   u32 codec, codecs;
+   int ret;
+
+   if (core->res->hfi_version != HFI_VERSION_1XX)
+   return 0;
+
+   memset(, 0, sizeof(inst));
+   mutex_init();
+   inst.core = core;
+   inst.session_type = type;
+   if (type == VIDC_SESSION_TYPE_DEC)
+   codecs = core->dec_codecs;
+   else
+   codecs = core->enc_codecs;
+
+   ret = hfi_session_create(, _ops);
+   if (ret)
+   return ret;
+
+   for (i = 0; i < MAX_CODEC_NUM; i++) {
+   codec = (1 << i) & codecs;
+   if (!codec)
+   continue;
+
+   ret = hfi_session_init(, to_v4l2_codec_type(codec));
+   if (ret)
+   goto done;
+
+   ret = hfi_session_deinit();
+   if (ret)
+   goto done;
+   }
+
+done:
+   hfi_session_destroy();
+   mutex_destroy();
+
+   return ret;
+}
+
 static int venus_probe(struct platform_device *pdev)
 {
struct device *dev = >dev;
@@ -219,6 +291,14 @@ static int venus_probe(struct platform_device *pdev)
if (ret)
goto err_venus_shutdown;
 
+   ret = venus_enumerate_codecs(core, VIDC_SESSION_TYPE_DEC);
+   if (ret)
+   goto err_venus_shutdown;
+
+   ret = venus_enumerate_codecs(core, VIDC_SESSION_TYPE_ENC);
+   if (ret)
+   goto err_venus_shutdown;
+
ret = v4l2_device_register(dev, >v4l2_dev);
if (ret)
goto err_core_deinit;
diff --git a/drivers/media/platform/qcom/venus/core.h 
b/drivers/media/platform/qcom/venus/core.h
index b5b9a84e9155..fe2d2b9e8af8 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -57,6 +57,29 @@ struct venus_format {
   

[PATCH 10/28] venus: vdec: call session_continue in insufficient event

2018-04-24 Thread Stanimir Varbanov
Call session_continue for Venus 4xx version even when the event
says that the buffer resources are not sufficient. Leaving a
comment with more information about the workaround.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/vdec.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/media/platform/qcom/venus/vdec.c 
b/drivers/media/platform/qcom/venus/vdec.c
index c45452634e7e..91c7384ff9c8 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -873,6 +873,14 @@ static void vdec_event_notify(struct venus_inst *inst, u32 
event,
 
dev_dbg(dev, "event not sufficient resources (%ux%u)\n",
data->width, data->height);
+   /*
+* Workaround: Even that the firmware send and event for
+* insufficient buffer resources it is safe to call
+* session_continue because actually the event says that
+* the number of capture buffers is lower.
+*/
+   if (IS_V4(core))
+   hfi_session_continue(inst);
break;
case HFI_EVENT_RELEASE_BUFFER_REFERENCE:
venus_helper_release_buf_ref(inst, data->tag);
-- 
2.14.1



[PATCH 04/28] venus: hfi_cmds: add set_properties for 4xx version

2018-04-24 Thread Stanimir Varbanov
Adds set_properties method to handle newer 4xx properties and
fall-back to 3xx for the rest.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/hfi_cmds.c | 64 +++-
 1 file changed, 63 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/qcom/venus/hfi_cmds.c 
b/drivers/media/platform/qcom/venus/hfi_cmds.c
index 1cfeb7743041..6bd287154796 100644
--- a/drivers/media/platform/qcom/venus/hfi_cmds.c
+++ b/drivers/media/platform/qcom/venus/hfi_cmds.c
@@ -1166,6 +1166,65 @@ pkt_session_set_property_3xx(struct 
hfi_session_set_property_pkt *pkt,
return ret;
 }
 
+static int
+pkt_session_set_property_4xx(struct hfi_session_set_property_pkt *pkt,
+void *cookie, u32 ptype, void *pdata)
+{
+   void *prop_data;
+   int ret = 0;
+
+   if (!pkt || !cookie || !pdata)
+   return -EINVAL;
+
+   prop_data = >data[1];
+
+   pkt->shdr.hdr.size = sizeof(*pkt);
+   pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_SET_PROPERTY;
+   pkt->shdr.session_id = hash32_ptr(cookie);
+   pkt->num_properties = 1;
+   pkt->data[0] = ptype;
+
+   /*
+* Any session set property which is different in 3XX packetization
+* should be added as a new case below. All unchanged session set
+* properties will be handled in the default case.
+*/
+   switch (ptype) {
+   case HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL: {
+   struct hfi_buffer_count_actual *in = pdata;
+   struct hfi_buffer_count_actual_4xx *count = prop_data;
+
+   count->count_actual = in->count_actual;
+   count->type = in->type;
+   count->count_min_host = in->count_actual;
+   pkt->shdr.hdr.size += sizeof(u32) + sizeof(*count);
+   break;
+   }
+   case HFI_PROPERTY_PARAM_WORK_MODE: {
+   struct hfi_video_work_mode *in = pdata, *wm = prop_data;
+
+   wm->video_work_mode = in->video_work_mode;
+   pkt->shdr.hdr.size += sizeof(u32) + sizeof(*wm);
+   break;
+   }
+   case HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE: {
+   struct hfi_videocores_usage_type *in = pdata, *cu = prop_data;
+
+   cu->video_core_enable_mask = in->video_core_enable_mask;
+   pkt->shdr.hdr.size += sizeof(u32) + sizeof(*cu);
+   break;
+   }
+   case HFI_PROPERTY_CONFIG_VENC_MAX_BITRATE:
+   /* not implemented on Venus 4xx */
+   break;
+   default:
+   ret = pkt_session_set_property_3xx(pkt, cookie, ptype, pdata);
+   break;
+   }
+
+   return ret;
+}
+
 int pkt_session_get_property(struct hfi_session_get_property_pkt *pkt,
 void *cookie, u32 ptype)
 {
@@ -1181,7 +1240,10 @@ int pkt_session_set_property(struct 
hfi_session_set_property_pkt *pkt,
if (hfi_ver == HFI_VERSION_1XX)
return pkt_session_set_property_1x(pkt, cookie, ptype, pdata);
 
-   return pkt_session_set_property_3xx(pkt, cookie, ptype, pdata);
+   if (hfi_ver == HFI_VERSION_3XX)
+   return pkt_session_set_property_3xx(pkt, cookie, ptype, pdata);
+
+   return pkt_session_set_property_4xx(pkt, cookie, ptype, pdata);
 }
 
 void pkt_set_version(enum hfi_version version)
-- 
2.14.1



[PATCH 21/28] venus: helpers: extend set_num_bufs helper with one more argument

2018-04-24 Thread Stanimir Varbanov
Extend venus_helper_set_num_bufs() helper function with one more
argument to set number of output buffers for the secondary decoder
output.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/helpers.c | 16 ++--
 drivers/media/platform/qcom/venus/helpers.h |  3 ++-
 drivers/media/platform/qcom/venus/vdec.c|  2 +-
 drivers/media/platform/qcom/venus/venc.c|  2 +-
 4 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index adf8701a64bb..f04d16953b3a 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -513,7 +513,8 @@ int venus_helper_set_core_usage(struct venus_inst *inst, 
u32 usage)
 EXPORT_SYMBOL_GPL(venus_helper_set_core_usage);
 
 int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs,
- unsigned int output_bufs)
+ unsigned int output_bufs,
+ unsigned int output2_bufs)
 {
u32 ptype = HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL;
struct hfi_buffer_count_actual buf_count;
@@ -529,7 +530,18 @@ int venus_helper_set_num_bufs(struct venus_inst *inst, 
unsigned int input_bufs,
buf_count.type = HFI_BUFFER_OUTPUT;
buf_count.count_actual = output_bufs;
 
-   return hfi_session_set_property(inst, ptype, _count);
+   ret = hfi_session_set_property(inst, ptype, _count);
+   if (ret)
+   return ret;
+
+   if (output2_bufs) {
+   buf_count.type = HFI_BUFFER_OUTPUT2;
+   buf_count.count_actual = output2_bufs;
+
+   ret = hfi_session_set_property(inst, ptype, _count);
+   }
+
+   return ret;
 }
 EXPORT_SYMBOL_GPL(venus_helper_set_num_bufs);
 
diff --git a/drivers/media/platform/qcom/venus/helpers.h 
b/drivers/media/platform/qcom/venus/helpers.h
index d5e727e1ecab..8ff4bd3ef958 100644
--- a/drivers/media/platform/qcom/venus/helpers.h
+++ b/drivers/media/platform/qcom/venus/helpers.h
@@ -41,7 +41,8 @@ int venus_helper_set_output_resolution(struct venus_inst 
*inst,
 int venus_helper_set_work_mode(struct venus_inst *inst, u32 mode);
 int venus_helper_set_core_usage(struct venus_inst *inst, u32 usage);
 int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs,
- unsigned int output_bufs);
+ unsigned int output_bufs,
+ unsigned int output2_bufs);
 int venus_helper_set_raw_format(struct venus_inst *inst, u32 hfi_format,
u32 buftype);
 int venus_helper_set_color_format(struct venus_inst *inst, u32 fmt);
diff --git a/drivers/media/platform/qcom/venus/vdec.c 
b/drivers/media/platform/qcom/venus/vdec.c
index ceaf1a338eb3..8d188b11b85a 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -758,7 +758,7 @@ static int vdec_start_streaming(struct vb2_queue *q, 
unsigned int count)
goto deinit_sess;
 
ret = venus_helper_set_num_bufs(inst, inst->num_input_bufs,
-   VB2_MAX_FRAME);
+   VB2_MAX_FRAME, VB2_MAX_FRAME);
if (ret)
goto deinit_sess;
 
diff --git a/drivers/media/platform/qcom/venus/venc.c 
b/drivers/media/platform/qcom/venus/venc.c
index 3b3299bff1cd..c9c40d1ce7c6 100644
--- a/drivers/media/platform/qcom/venus/venc.c
+++ b/drivers/media/platform/qcom/venus/venc.c
@@ -963,7 +963,7 @@ static int venc_start_streaming(struct vb2_queue *q, 
unsigned int count)
goto deinit_sess;
 
ret = venus_helper_set_num_bufs(inst, inst->num_input_bufs,
-   inst->num_output_bufs);
+   inst->num_output_bufs, 0);
if (ret)
goto deinit_sess;
 
-- 
2.14.1



[PATCH 12/28] venus: helpers: make a commmon function for power_enable

2018-04-24 Thread Stanimir Varbanov
Make common function which will enable power when enabling/disabling
clocks and also covers Venus 3xx/4xx versions.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/helpers.c | 51 +
 drivers/media/platform/qcom/venus/helpers.h |  2 ++
 drivers/media/platform/qcom/venus/vdec.c| 25 --
 drivers/media/platform/qcom/venus/venc.c| 25 --
 4 files changed, 67 insertions(+), 36 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index d9065cc8a7d3..2b21f6ed7502 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -13,6 +13,7 @@
  *
  */
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -24,6 +25,7 @@
 #include "core.h"
 #include "helpers.h"
 #include "hfi_helper.h"
+#include "hfi_venus_io.h"
 
 struct intbuf {
struct list_head list;
@@ -781,3 +783,52 @@ void venus_helper_init_instance(struct venus_inst *inst)
}
 }
 EXPORT_SYMBOL_GPL(venus_helper_init_instance);
+
+int venus_helper_power_enable(struct venus_core *core, u32 session_type,
+ bool enable)
+{
+   void __iomem *ctrl, *stat;
+   u32 val;
+   int ret;
+
+   if (!IS_V3(core) && !IS_V4(core))
+   return -EINVAL;
+
+   if (IS_V3(core)) {
+   if (session_type == VIDC_SESSION_TYPE_DEC)
+   ctrl = core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL;
+   else
+   ctrl = core->base + WRAPPER_VENC_VCODEC_POWER_CONTROL;
+   if (enable)
+   writel(0, ctrl);
+   else
+   writel(1, ctrl);
+
+   return 0;
+   }
+
+   if (session_type == VIDC_SESSION_TYPE_DEC) {
+   ctrl = core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL;
+   stat = core->base + WRAPPER_VCODEC0_MMCC_POWER_STATUS;
+   } else {
+   ctrl = core->base + WRAPPER_VCODEC1_MMCC_POWER_CONTROL;
+   stat = core->base + WRAPPER_VCODEC1_MMCC_POWER_STATUS;
+   }
+
+   if (enable) {
+   writel(0, ctrl);
+
+   ret = readl_poll_timeout(stat, val, val & BIT(1), 1, 100);
+   if (ret)
+   return ret;
+   } else {
+   writel(1, ctrl);
+
+   ret = readl_poll_timeout(stat, val, !(val & BIT(1)), 1, 100);
+   if (ret)
+   return ret;
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(venus_helper_power_enable);
diff --git a/drivers/media/platform/qcom/venus/helpers.h 
b/drivers/media/platform/qcom/venus/helpers.h
index 971392be5df5..0e64aa95624a 100644
--- a/drivers/media/platform/qcom/venus/helpers.h
+++ b/drivers/media/platform/qcom/venus/helpers.h
@@ -43,4 +43,6 @@ int venus_helper_set_color_format(struct venus_inst *inst, 
u32 fmt);
 void venus_helper_acquire_buf_ref(struct vb2_v4l2_buffer *vbuf);
 void venus_helper_release_buf_ref(struct venus_inst *inst, unsigned int idx);
 void venus_helper_init_instance(struct venus_inst *inst);
+int venus_helper_power_enable(struct venus_core *core, u32 session_type,
+ bool enable);
 #endif
diff --git a/drivers/media/platform/qcom/venus/vdec.c 
b/drivers/media/platform/qcom/venus/vdec.c
index cd278a695899..0ddc2c4df934 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -1131,26 +1131,21 @@ static int vdec_remove(struct platform_device *pdev)
 static __maybe_unused int vdec_runtime_suspend(struct device *dev)
 {
struct venus_core *core = dev_get_drvdata(dev);
+   int ret;
 
if (IS_V1(core))
return 0;
 
-   if (IS_V3(core))
-   writel(0, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
-   else if (IS_V4(core))
-   writel(0, core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL);
+   ret = venus_helper_power_enable(core, VIDC_SESSION_TYPE_DEC, true);
 
if (IS_V4(core))
clk_disable_unprepare(core->core0_bus_clk);
 
clk_disable_unprepare(core->core0_clk);
 
-   if (IS_V3(core))
-   writel(1, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
-   else if (IS_V4(core))
-   writel(1, core->base + WRAPPER_VCODEC0_MMCC_POWER_CONTROL);
+   ret |= venus_helper_power_enable(core, VIDC_SESSION_TYPE_DEC, false);
 
-   return 0;
+   return ret;
 }
 
 static __maybe_unused int vdec_runtime_resume(struct device *dev)
@@ -1161,20 +1156,14 @@ static __maybe_unused int vdec_runtime_resume(struct 
device *dev)
if (IS_V1(core))
return 0;
 
-   if (IS_V3(core))
-   writel(0, core->base + WRAPPER_VDEC_VCODEC_POWER_CONTROL);
- 

[PATCH 19/28] venus: helpers: add a new helper to set raw format

2018-04-24 Thread Stanimir Varbanov
The new helper will has one more argument for buffer type, that
way the decoder can configure the format on it's secondary
output.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/helpers.c | 52 ++---
 drivers/media/platform/qcom/venus/helpers.h |  2 ++
 2 files changed, 35 insertions(+), 19 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index 5512fbfdebb9..0d55604f7484 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -410,6 +410,20 @@ static int session_register_bufs(struct venus_inst *inst)
return ret;
 }
 
+static u32 to_hfi_raw_fmt(u32 v4l2_fmt)
+{
+   switch (v4l2_fmt) {
+   case V4L2_PIX_FMT_NV12:
+   return HFI_COLOR_FORMAT_NV12;
+   case V4L2_PIX_FMT_NV21:
+   return HFI_COLOR_FORMAT_NV21;
+   default:
+   break;
+   }
+
+   return 0;
+}
+
 int venus_helper_get_bufreq(struct venus_inst *inst, u32 type,
struct hfi_buffer_requirements *req)
 {
@@ -491,35 +505,35 @@ int venus_helper_set_num_bufs(struct venus_inst *inst, 
unsigned int input_bufs,
 }
 EXPORT_SYMBOL_GPL(venus_helper_set_num_bufs);
 
-int venus_helper_set_color_format(struct venus_inst *inst, u32 pixfmt)
+int venus_helper_set_raw_format(struct venus_inst *inst, u32 hfi_format,
+   u32 buftype)
 {
-   struct hfi_uncompressed_format_select fmt;
u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT;
-   int ret;
+   struct hfi_uncompressed_format_select fmt;
+
+   fmt.buffer_type = buftype;
+   fmt.format = hfi_format;
+
+   return hfi_session_set_property(inst, ptype, );
+}
+EXPORT_SYMBOL_GPL(venus_helper_set_raw_format);
+
+int venus_helper_set_color_format(struct venus_inst *inst, u32 pixfmt)
+{
+   u32 hfi_format, buftype;
 
if (inst->session_type == VIDC_SESSION_TYPE_DEC)
-   fmt.buffer_type = HFI_BUFFER_OUTPUT;
+   buftype = HFI_BUFFER_OUTPUT;
else if (inst->session_type == VIDC_SESSION_TYPE_ENC)
-   fmt.buffer_type = HFI_BUFFER_INPUT;
+   buftype = HFI_BUFFER_INPUT;
else
return -EINVAL;
 
-   switch (pixfmt) {
-   case V4L2_PIX_FMT_NV12:
-   fmt.format = HFI_COLOR_FORMAT_NV12;
-   break;
-   case V4L2_PIX_FMT_NV21:
-   fmt.format = HFI_COLOR_FORMAT_NV21;
-   break;
-   default:
+   hfi_format = to_hfi_raw_fmt(pixfmt);
+   if (!hfi_format)
return -EINVAL;
-   }
 
-   ret = hfi_session_set_property(inst, ptype, );
-   if (ret)
-   return ret;
-
-   return 0;
+   return venus_helper_set_raw_format(inst, hfi_format, buftype);
 }
 EXPORT_SYMBOL_GPL(venus_helper_set_color_format);
 
diff --git a/drivers/media/platform/qcom/venus/helpers.h 
b/drivers/media/platform/qcom/venus/helpers.h
index 0de9989adcdb..79af7845efbd 100644
--- a/drivers/media/platform/qcom/venus/helpers.h
+++ b/drivers/media/platform/qcom/venus/helpers.h
@@ -40,6 +40,8 @@ int venus_helper_set_output_resolution(struct venus_inst 
*inst,
   u32 buftype);
 int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs,
  unsigned int output_bufs);
+int venus_helper_set_raw_format(struct venus_inst *inst, u32 hfi_format,
+   u32 buftype);
 int venus_helper_set_color_format(struct venus_inst *inst, u32 fmt);
 int venus_helper_set_dyn_bufmode(struct venus_inst *inst);
 int venus_helper_set_bufsize(struct venus_inst *inst, u32 bufsize, u32 
buftype);
-- 
2.14.1



[PATCH 18/28] venus: helpers: add buffer type argument to a helper

2018-04-24 Thread Stanimir Varbanov
This adds one more function argument to pass buffer type to
set_output_resolution() helper function. That is a preparation
to support secondary decoder output.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/helpers.c | 5 +++--
 drivers/media/platform/qcom/venus/helpers.h | 3 ++-
 drivers/media/platform/qcom/venus/venc.c| 3 ++-
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index 94664a3ce3e2..5512fbfdebb9 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -456,12 +456,13 @@ int venus_helper_set_input_resolution(struct venus_inst 
*inst,
 EXPORT_SYMBOL_GPL(venus_helper_set_input_resolution);
 
 int venus_helper_set_output_resolution(struct venus_inst *inst,
-  unsigned int width, unsigned int height)
+  unsigned int width, unsigned int height,
+  u32 buftype)
 {
u32 ptype = HFI_PROPERTY_PARAM_FRAME_SIZE;
struct hfi_framesize fs;
 
-   fs.buffer_type = HFI_BUFFER_OUTPUT;
+   fs.buffer_type = buftype;
fs.width = width;
fs.height = height;
 
diff --git a/drivers/media/platform/qcom/venus/helpers.h 
b/drivers/media/platform/qcom/venus/helpers.h
index cd306bd8978f..0de9989adcdb 100644
--- a/drivers/media/platform/qcom/venus/helpers.h
+++ b/drivers/media/platform/qcom/venus/helpers.h
@@ -36,7 +36,8 @@ int venus_helper_get_bufreq(struct venus_inst *inst, u32 type,
 int venus_helper_set_input_resolution(struct venus_inst *inst,
  unsigned int width, unsigned int height);
 int venus_helper_set_output_resolution(struct venus_inst *inst,
-  unsigned int width, unsigned int height);
+  unsigned int width, unsigned int height,
+  u32 buftype);
 int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs,
  unsigned int output_bufs);
 int venus_helper_set_color_format(struct venus_inst *inst, u32 fmt);
diff --git a/drivers/media/platform/qcom/venus/venc.c 
b/drivers/media/platform/qcom/venus/venc.c
index f87d891325ea..8970f14b3a82 100644
--- a/drivers/media/platform/qcom/venus/venc.c
+++ b/drivers/media/platform/qcom/venus/venc.c
@@ -795,7 +795,8 @@ static int venc_init_session(struct venus_inst *inst)
goto deinit;
 
ret = venus_helper_set_output_resolution(inst, inst->width,
-inst->height);
+inst->height,
+HFI_BUFFER_OUTPUT);
if (ret)
goto deinit;
 
-- 
2.14.1



[PATCH 17/28] venus: delete no longer used bufmode flag from instance

2018-04-24 Thread Stanimir Varbanov
Delete no longer used flag cap_bufs_mode_dynamic from instance
structure.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/core.h   | 2 --
 drivers/media/platform/qcom/venus/hfi_parser.c | 6 +-
 2 files changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/core.h 
b/drivers/media/platform/qcom/venus/core.h
index c46334454cd9..255292899204 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -249,7 +249,6 @@ struct venus_buffer {
  * @priv:  a private for HFI operations callbacks
  * @session_type:  the type of the session (decoder or encoder)
  * @hprop: a union used as a holder by get property
- * @cap_bufs_mode_dynamic: buffers allocation mode capability
  */
 struct venus_inst {
struct list_head list;
@@ -298,7 +297,6 @@ struct venus_inst {
const struct hfi_inst_ops *ops;
u32 session_type;
union hfi_get_property hprop;
-   bool cap_bufs_mode_dynamic;
 };
 
 #define IS_V1(core)((core)->res->hfi_version == HFI_VERSION_1XX)
diff --git a/drivers/media/platform/qcom/venus/hfi_parser.c 
b/drivers/media/platform/qcom/venus/hfi_parser.c
index 4b155997abbb..ac92fd347ce1 100644
--- a/drivers/media/platform/qcom/venus/hfi_parser.c
+++ b/drivers/media/platform/qcom/venus/hfi_parser.c
@@ -74,13 +74,9 @@ static void parse_alloc_mode(struct venus_core *core, struct 
venus_inst *inst,
 
while (num_entries--) {
if (mode->buffer_type == HFI_BUFFER_OUTPUT ||
-   mode->buffer_type == HFI_BUFFER_OUTPUT2) {
-   if (*type == HFI_BUFFER_MODE_DYNAMIC && inst)
-   inst->cap_bufs_mode_dynamic = true;
-
+   mode->buffer_type == HFI_BUFFER_OUTPUT2)
for_each_codec(core->caps, ARRAY_SIZE(core->caps),
   codecs, domain, fill_buf_mode, type, 1);
-   }
 
type++;
}
-- 
2.14.1



[PATCH 15/28] venus: add a helper function to set dynamic buffer mode

2018-04-24 Thread Stanimir Varbanov
Adds a new helper function to set dymaic buffer mode if it is
supported by current HFI version.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/helpers.c | 22 ++
 drivers/media/platform/qcom/venus/helpers.h |  1 +
 drivers/media/platform/qcom/venus/vdec.c| 15 +++
 3 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index 1eda19adbf28..824ad4d2d064 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -522,6 +522,28 @@ int venus_helper_set_color_format(struct venus_inst *inst, 
u32 pixfmt)
 }
 EXPORT_SYMBOL_GPL(venus_helper_set_color_format);
 
+int venus_helper_set_dyn_bufmode(struct venus_inst *inst)
+{
+   u32 ptype = HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE;
+   struct hfi_buffer_alloc_mode mode;
+   int ret;
+
+   if (!is_dynamic_bufmode(inst))
+   return 0;
+
+   mode.type = HFI_BUFFER_OUTPUT;
+   mode.mode = HFI_BUFFER_MODE_DYNAMIC;
+
+   ret = hfi_session_set_property(inst, ptype, );
+   if (ret)
+   return ret;
+
+   mode.type = HFI_BUFFER_OUTPUT2;
+
+   return hfi_session_set_property(inst, ptype, );
+}
+EXPORT_SYMBOL_GPL(venus_helper_set_dyn_bufmode);
+
 static void delayed_process_buf_func(struct work_struct *work)
 {
struct venus_buffer *buf, *n;
diff --git a/drivers/media/platform/qcom/venus/helpers.h 
b/drivers/media/platform/qcom/venus/helpers.h
index 0e64aa95624a..52b961ed491e 100644
--- a/drivers/media/platform/qcom/venus/helpers.h
+++ b/drivers/media/platform/qcom/venus/helpers.h
@@ -40,6 +40,7 @@ int venus_helper_set_output_resolution(struct venus_inst 
*inst,
 int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs,
  unsigned int output_bufs);
 int venus_helper_set_color_format(struct venus_inst *inst, u32 fmt);
+int venus_helper_set_dyn_bufmode(struct venus_inst *inst);
 void venus_helper_acquire_buf_ref(struct vb2_v4l2_buffer *vbuf);
 void venus_helper_release_buf_ref(struct venus_inst *inst, unsigned int idx);
 void venus_helper_init_instance(struct venus_inst *inst);
diff --git a/drivers/media/platform/qcom/venus/vdec.c 
b/drivers/media/platform/qcom/venus/vdec.c
index 0ddc2c4df934..1de9cc64cf2f 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -557,18 +557,9 @@ static int vdec_set_properties(struct venus_inst *inst)
return ret;
}
 
-   if (core->res->hfi_version == HFI_VERSION_3XX ||
-   inst->cap_bufs_mode_dynamic) {
-   struct hfi_buffer_alloc_mode mode;
-
-   ptype = HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE;
-   mode.type = HFI_BUFFER_OUTPUT;
-   mode.mode = HFI_BUFFER_MODE_DYNAMIC;
-
-   ret = hfi_session_set_property(inst, ptype, );
-   if (ret)
-   return ret;
-   }
+   ret = venus_helper_set_dyn_bufmode(inst);
+   if (ret)
+   return ret;
 
if (ctr->post_loop_deb_mode) {
ptype = HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER;
-- 
2.14.1



[PATCH 14/28] venus: helpers: rename a helper function and use buffer mode from caps

2018-04-24 Thread Stanimir Varbanov
Rename is_reg_unreg_needed() to better name is_dynamic_bufmode() and
use buffer mode from enumerated per codec capabilities.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/helpers.c | 21 +++--
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index 2b21f6ed7502..1eda19adbf28 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -354,18 +354,19 @@ session_process_buf(struct venus_inst *inst, struct 
vb2_v4l2_buffer *vbuf)
return 0;
 }
 
-static inline int is_reg_unreg_needed(struct venus_inst *inst)
+static inline int is_dynamic_bufmode(struct venus_inst *inst)
 {
-   if (inst->session_type == VIDC_SESSION_TYPE_DEC &&
-   inst->core->res->hfi_version == HFI_VERSION_3XX)
-   return 0;
+   struct venus_core *core = inst->core;
+   struct venus_caps *caps;
 
-   if (inst->session_type == VIDC_SESSION_TYPE_DEC &&
-   inst->cap_bufs_mode_dynamic &&
-   inst->core->res->hfi_version == HFI_VERSION_1XX)
+   caps = venus_caps_by_codec(core, inst->hfi_codec, inst->session_type);
+   if (!caps)
return 0;
 
-   return 1;
+   if (caps->cap_bufs_mode_dynamic)
+   return 1;
+
+   return 0;
 }
 
 static int session_unregister_bufs(struct venus_inst *inst)
@@ -374,7 +375,7 @@ static int session_unregister_bufs(struct venus_inst *inst)
struct hfi_buffer_desc bd;
int ret = 0;
 
-   if (!is_reg_unreg_needed(inst))
+   if (is_dynamic_bufmode(inst))
return 0;
 
list_for_each_entry_safe(buf, n, >registeredbufs, reg_list) {
@@ -394,7 +395,7 @@ static int session_register_bufs(struct venus_inst *inst)
struct venus_buffer *buf;
int ret = 0;
 
-   if (!is_reg_unreg_needed(inst))
+   if (is_dynamic_bufmode(inst))
return 0;
 
list_for_each_entry(buf, >registeredbufs, reg_list) {
-- 
2.14.1



[PATCH 13/28] venus: core: delete not used flag for buffer mode

2018-04-24 Thread Stanimir Varbanov
Delete not used flag for capture buffer allocation mode.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/core.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/core.h 
b/drivers/media/platform/qcom/venus/core.h
index fe2d2b9e8af8..c46334454cd9 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -249,7 +249,6 @@ struct venus_buffer {
  * @priv:  a private for HFI operations callbacks
  * @session_type:  the type of the session (decoder or encoder)
  * @hprop: a union used as a holder by get property
- * @cap_bufs_mode_static:  buffers allocation mode capability
  * @cap_bufs_mode_dynamic: buffers allocation mode capability
  */
 struct venus_inst {
@@ -299,7 +298,6 @@ struct venus_inst {
const struct hfi_inst_ops *ops;
u32 session_type;
union hfi_get_property hprop;
-   bool cap_bufs_mode_static;
bool cap_bufs_mode_dynamic;
 };
 
-- 
2.14.1



[PATCH 27/28] venus: add sdm845 compatible and resource data

2018-04-24 Thread Stanimir Varbanov
This adds sdm845 DT compatible string with it's resource
data table.

Cc: devicet...@vger.kernel.org
Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 .../devicetree/bindings/media/qcom,venus.txt   |  1 +
 drivers/media/platform/qcom/venus/core.c   | 22 ++
 2 files changed, 23 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/qcom,venus.txt 
b/Documentation/devicetree/bindings/media/qcom,venus.txt
index 2693449daf73..00d0d1bf7647 100644
--- a/Documentation/devicetree/bindings/media/qcom,venus.txt
+++ b/Documentation/devicetree/bindings/media/qcom,venus.txt
@@ -6,6 +6,7 @@
Definition: Value should contain one of:
- "qcom,msm8916-venus"
- "qcom,msm8996-venus"
+   - "qcom,sdm845-venus"
 - reg:
Usage: required
Value type: 
diff --git a/drivers/media/platform/qcom/venus/core.c 
b/drivers/media/platform/qcom/venus/core.c
index 1b72bfbb6297..13084880cc42 100644
--- a/drivers/media/platform/qcom/venus/core.c
+++ b/drivers/media/platform/qcom/venus/core.c
@@ -445,9 +445,31 @@ static const struct venus_resources msm8996_res = {
.fwname = "qcom/venus-4.2/venus.mdt",
 };
 
+static const struct freq_tbl sdm845_freq_table[] = {
+   { 1944000, 38000 }, /* 4k UHD @ 60 */
+   {  972000, 32000 }, /* 4k UHD @ 30 */
+   {  489600, 2 }, /* 1080p @ 60 */
+   {  244800, 1 }, /* 1080p @ 30 */
+};
+
+static const struct venus_resources sdm845_res = {
+   .freq_tbl = sdm845_freq_table,
+   .freq_tbl_size = ARRAY_SIZE(sdm845_freq_table),
+   .clks = {"core", "iface", "bus" },
+   .clks_num = 3,
+   .max_load = 2563200,
+   .hfi_version = HFI_VERSION_4XX,
+   .vmem_id = VIDC_RESOURCE_NONE,
+   .vmem_size = 0,
+   .vmem_addr = 0,
+   .dma_mask = 0xe000 - 1,
+   .fwname = "qcom/venus-5.2/venus.mdt",
+};
+
 static const struct of_device_id venus_dt_match[] = {
{ .compatible = "qcom,msm8916-venus", .data = _res, },
{ .compatible = "qcom,msm8996-venus", .data = _res, },
+   { .compatible = "qcom,sdm845-venus", .data = _res, },
{ }
 };
 MODULE_DEVICE_TABLE(of, venus_dt_match);
-- 
2.14.1



[PATCH 20/28] venus: helpers,vdec,venc: add helpers to set work mode and core usage

2018-04-24 Thread Stanimir Varbanov
These are new properties applicable to Venus version 4xx. Add the
helpers and call them from decoder and encoder drivers.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/helpers.c | 28 
 drivers/media/platform/qcom/venus/helpers.h |  2 ++
 drivers/media/platform/qcom/venus/vdec.c|  8 
 drivers/media/platform/qcom/venus/venc.c|  8 
 4 files changed, 46 insertions(+)

diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index 0d55604f7484..adf8701a64bb 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -484,6 +484,34 @@ int venus_helper_set_output_resolution(struct venus_inst 
*inst,
 }
 EXPORT_SYMBOL_GPL(venus_helper_set_output_resolution);
 
+int venus_helper_set_work_mode(struct venus_inst *inst, u32 mode)
+{
+   u32 ptype = HFI_PROPERTY_PARAM_WORK_MODE;
+   struct hfi_video_work_mode wm;
+
+   if (!IS_V4(inst->core))
+   return 0;
+
+   wm.video_work_mode = mode;
+
+   return hfi_session_set_property(inst, ptype, );
+}
+EXPORT_SYMBOL_GPL(venus_helper_set_work_mode);
+
+int venus_helper_set_core_usage(struct venus_inst *inst, u32 usage)
+{
+   u32 ptype = HFI_PROPERTY_CONFIG_VIDEOCORES_USAGE;
+   struct hfi_videocores_usage_type cu;
+
+   if (!IS_V4(inst->core))
+   return 0;
+
+   cu.video_core_enable_mask = usage;
+
+   return hfi_session_set_property(inst, ptype, );
+}
+EXPORT_SYMBOL_GPL(venus_helper_set_core_usage);
+
 int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs,
  unsigned int output_bufs)
 {
diff --git a/drivers/media/platform/qcom/venus/helpers.h 
b/drivers/media/platform/qcom/venus/helpers.h
index 79af7845efbd..d5e727e1ecab 100644
--- a/drivers/media/platform/qcom/venus/helpers.h
+++ b/drivers/media/platform/qcom/venus/helpers.h
@@ -38,6 +38,8 @@ int venus_helper_set_input_resolution(struct venus_inst *inst,
 int venus_helper_set_output_resolution(struct venus_inst *inst,
   unsigned int width, unsigned int height,
   u32 buftype);
+int venus_helper_set_work_mode(struct venus_inst *inst, u32 mode);
+int venus_helper_set_core_usage(struct venus_inst *inst, u32 usage);
 int venus_helper_set_num_bufs(struct venus_inst *inst, unsigned int input_bufs,
  unsigned int output_bufs);
 int venus_helper_set_raw_format(struct venus_inst *inst, u32 hfi_format,
diff --git a/drivers/media/platform/qcom/venus/vdec.c 
b/drivers/media/platform/qcom/venus/vdec.c
index b43607dee4fe..ceaf1a338eb3 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -550,6 +550,14 @@ static int vdec_set_properties(struct venus_inst *inst)
u32 ptype;
int ret;
 
+   ret = venus_helper_set_work_mode(inst, VIDC_WORK_MODE_2);
+   if (ret)
+   return ret;
+
+   ret = venus_helper_set_core_usage(inst, VIDC_CORE_ID_1);
+   if (ret)
+   return ret;
+
if (core->res->hfi_version == HFI_VERSION_1XX) {
ptype = HFI_PROPERTY_PARAM_VDEC_CONTINUE_DATA_TRANSFER;
ret = hfi_session_set_property(inst, ptype, );
diff --git a/drivers/media/platform/qcom/venus/venc.c 
b/drivers/media/platform/qcom/venus/venc.c
index 8970f14b3a82..3b3299bff1cd 100644
--- a/drivers/media/platform/qcom/venus/venc.c
+++ b/drivers/media/platform/qcom/venus/venc.c
@@ -643,6 +643,14 @@ static int venc_set_properties(struct venus_inst *inst)
u32 ptype, rate_control, bitrate, profile = 0, level = 0;
int ret;
 
+   ret = venus_helper_set_work_mode(inst, VIDC_WORK_MODE_2);
+   if (ret)
+   return ret;
+
+   ret = venus_helper_set_core_usage(inst, VIDC_CORE_ID_2);
+   if (ret)
+   return ret;
+
ptype = HFI_PROPERTY_CONFIG_FRAME_RATE;
frate.buffer_type = HFI_BUFFER_OUTPUT;
frate.framerate = inst->fps * (1 << 16);
-- 
2.14.1



[PATCH 26/28] venus: implementing multi-stream support

2018-04-24 Thread Stanimir Varbanov
This is implementing a multi-stream decoder support. The multi
stream gives an option to use the secondary decoder output
with different raw format (or the same in case of crop).

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/core.h|   1 +
 drivers/media/platform/qcom/venus/helpers.c | 204 +++-
 drivers/media/platform/qcom/venus/helpers.h |   6 +
 drivers/media/platform/qcom/venus/vdec.c|  91 -
 drivers/media/platform/qcom/venus/venc.c|   1 +
 5 files changed, 299 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/core.h 
b/drivers/media/platform/qcom/venus/core.h
index 4d6c05f156c4..85e66e2dd672 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -259,6 +259,7 @@ struct venus_inst {
struct list_head list;
struct mutex lock;
struct venus_core *core;
+   struct list_head dpbbufs;
struct list_head internalbufs;
struct list_head registeredbufs;
struct list_head delayed_process;
diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index ed569705ecac..87dcf9973e6f 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -85,6 +85,112 @@ bool venus_helper_check_codec(struct venus_inst *inst, u32 
v4l2_pixfmt)
 }
 EXPORT_SYMBOL_GPL(venus_helper_check_codec);
 
+static int venus_helper_queue_dpb_bufs(struct venus_inst *inst)
+{
+   struct intbuf *buf;
+   int ret = 0;
+
+   if (list_empty(>dpbbufs))
+   return 0;
+
+   list_for_each_entry(buf, >dpbbufs, list) {
+   struct hfi_frame_data fdata;
+
+   memset(, 0, sizeof(fdata));
+   fdata.alloc_len = buf->size;
+   fdata.device_addr = buf->da;
+   fdata.buffer_type = buf->type;
+
+   ret = hfi_session_process_buf(inst, );
+   if (ret)
+   goto fail;
+   }
+
+fail:
+   return ret;
+}
+
+int venus_helper_free_dpb_bufs(struct venus_inst *inst)
+{
+   struct intbuf *buf, *n;
+
+   if (list_empty(>dpbbufs))
+   return 0;
+
+   list_for_each_entry_safe(buf, n, >dpbbufs, list) {
+   list_del_init(>list);
+   dma_free_attrs(inst->core->dev, buf->size, buf->va, buf->da,
+  buf->attrs);
+   kfree(buf);
+   }
+
+   INIT_LIST_HEAD(>dpbbufs);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(venus_helper_free_dpb_bufs);
+
+int venus_helper_alloc_dpb_bufs(struct venus_inst *inst)
+{
+   struct venus_core *core = inst->core;
+   struct device *dev = core->dev;
+   enum hfi_version ver = core->res->hfi_version;
+   struct hfi_buffer_requirements bufreq;
+   u32 buftype = inst->dpb_buftype;
+   unsigned int dpb_size = 0;
+   struct intbuf *buf;
+   unsigned int i;
+   u32 count;
+   int ret;
+
+   /* no need to allocate dpb buffers */
+   if (!inst->dpb_fmt)
+   return 0;
+
+   if (inst->dpb_buftype == HFI_BUFFER_OUTPUT)
+   dpb_size = inst->output_buf_size;
+   else if (inst->dpb_buftype == HFI_BUFFER_OUTPUT2)
+   dpb_size = inst->output2_buf_size;
+
+   if (!dpb_size)
+   return 0;
+
+   ret = venus_helper_get_bufreq(inst, buftype, );
+   if (ret)
+   return ret;
+
+   count = HFI_BUFREQ_COUNT_MIN(, ver);
+
+   for (i = 0; i < count; i++) {
+   buf = kzalloc(sizeof(*buf), GFP_KERNEL);
+   if (!buf) {
+   ret = -ENOMEM;
+   goto fail;
+   }
+
+   buf->type = buftype;
+   buf->size = dpb_size;
+   buf->attrs = DMA_ATTR_WRITE_COMBINE |
+DMA_ATTR_NO_KERNEL_MAPPING;
+   buf->va = dma_alloc_attrs(dev, buf->size, >da, GFP_KERNEL,
+ buf->attrs);
+   if (!buf->va) {
+   kfree(buf);
+   ret = -ENOMEM;
+   goto fail;
+   }
+
+   list_add_tail(>list, >dpbbufs);
+   }
+
+   return 0;
+
+fail:
+   venus_helper_free_dpb_bufs(inst);
+   return ret;
+}
+EXPORT_SYMBOL_GPL(venus_helper_alloc_dpb_bufs);
+
 static int intbufs_set_buffer(struct venus_inst *inst, u32 type)
 {
struct venus_core *core = inst->core;
@@ -342,7 +448,10 @@ session_process_buf(struct venus_inst *inst, struct 
vb2_v4l2_buffer *vbuf)
if (vbuf->flags & V4L2_BUF_FLAG_LAST || !fdata.filled_len)
fdata.flags |= HFI_BUFFERFLAG_EOS;
} else if (type == V4L2_BU

[PATCH 23/28] venus: vdec: get required input buffers as well

2018-04-24 Thread Stanimir Varbanov
Rework and rename vdec_cap_num_buffers() to get the number of
input buffers too.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/vdec.c | 41 +++-
 1 file changed, 24 insertions(+), 17 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/vdec.c 
b/drivers/media/platform/qcom/venus/vdec.c
index 8d188b11b85a..6ed9b7c4bd6e 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -603,19 +603,32 @@ static int vdec_init_session(struct venus_inst *inst)
return ret;
 }
 
-static int vdec_cap_num_buffers(struct venus_inst *inst, unsigned int *num)
+static int vdec_num_buffers(struct venus_inst *inst, unsigned int *in_num,
+   unsigned int *out_num)
 {
+   enum hfi_version ver = inst->core->res->hfi_version;
struct hfi_buffer_requirements bufreq;
int ret;
 
+   *in_num = *out_num = 0;
+
ret = vdec_init_session(inst);
if (ret)
return ret;
 
+   ret = venus_helper_get_bufreq(inst, HFI_BUFFER_INPUT, );
+   if (ret)
+   goto deinit;
+
+   *in_num = HFI_BUFREQ_COUNT_MIN(, ver);
+
ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, );
+   if (ret)
+   goto deinit;
 
-   *num = bufreq.count_actual;
+   *out_num = HFI_BUFREQ_COUNT_MIN(, ver);
 
+deinit:
hfi_session_deinit(inst);
 
return ret;
@@ -626,7 +639,7 @@ static int vdec_queue_setup(struct vb2_queue *q,
unsigned int sizes[], struct device *alloc_devs[])
 {
struct venus_inst *inst = vb2_get_drv_priv(q);
-   unsigned int p, num;
+   unsigned int p, in_num, out_num;
int ret = 0;
 
if (*num_planes) {
@@ -649,35 +662,29 @@ static int vdec_queue_setup(struct vb2_queue *q,
return 0;
}
 
+   ret = vdec_num_buffers(inst, _num, _num);
+   if (ret)
+   return ret;
+
switch (q->type) {
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
*num_planes = inst->fmt_out->num_planes;
sizes[0] = get_framesize_compressed(inst->out_width,
inst->out_height);
inst->input_buf_size = sizes[0];
+   *num_buffers = max(*num_buffers, in_num);
inst->num_input_bufs = *num_buffers;
-
-   ret = vdec_cap_num_buffers(inst, );
-   if (ret)
-   break;
-
-   inst->num_output_bufs = num;
+   inst->num_output_bufs = out_num;
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
*num_planes = inst->fmt_cap->num_planes;
 
-   ret = vdec_cap_num_buffers(inst, );
-   if (ret)
-   break;
-
-   *num_buffers = max(*num_buffers, num);
-
for (p = 0; p < *num_planes; p++)
sizes[p] = get_framesize_uncompressed(p, inst->width,
  inst->height);
-
-   inst->num_output_bufs = *num_buffers;
inst->output_buf_size = sizes[0];
+   *num_buffers = max(*num_buffers, out_num);
+   inst->num_output_bufs = *num_buffers;
break;
default:
ret = -EINVAL;
-- 
2.14.1



[PATCH 22/28] venus: helpers: add a helper to return opb buffer sizes

2018-04-24 Thread Stanimir Varbanov
Add a helper function to return current output picture buffer size.
OPB sizes can vary depending on the selected decoder output(s).

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/core.h| 10 ++
 drivers/media/platform/qcom/venus/helpers.c | 15 +++
 drivers/media/platform/qcom/venus/helpers.h |  1 +
 3 files changed, 26 insertions(+)

diff --git a/drivers/media/platform/qcom/venus/core.h 
b/drivers/media/platform/qcom/venus/core.h
index 255292899204..4d6c05f156c4 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -234,6 +234,11 @@ struct venus_buffer {
  * @num_output_bufs:   holds number of output buffers
  * @input_buf_size holds input buffer size
  * @output_buf_size:   holds output buffer size
+ * @output2_buf_size:  holds secondary decoder output buffer size
+ * @dpb_buftype:   decoded picture buffer type
+ * @dpb_fmt:   decodec picture buffre raw format
+ * @opb_buftype:   output picture buffer type
+ * @opb_fmt:   output picture buffer raw format
  * @reconfig:  a flag raised by decoder when the stream resolution changed
  * @reconfig_width:holds the new width
  * @reconfig_height:   holds the new height
@@ -282,6 +287,11 @@ struct venus_inst {
unsigned int num_output_bufs;
unsigned int input_buf_size;
unsigned int output_buf_size;
+   unsigned int output2_buf_size;
+   u32 dpb_buftype;
+   u32 dpb_fmt;
+   u32 opb_buftype;
+   u32 opb_fmt;
bool reconfig;
u32 reconfig_width;
u32 reconfig_height;
diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index f04d16953b3a..f0a0fca60c76 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -611,6 +611,21 @@ int venus_helper_set_bufsize(struct venus_inst *inst, u32 
bufsize, u32 buftype)
 }
 EXPORT_SYMBOL_GPL(venus_helper_set_bufsize);
 
+unsigned int venus_helper_get_opb_size(struct venus_inst *inst)
+{
+   /* the encoder has only one output */
+   if (inst->session_type == VIDC_SESSION_TYPE_ENC)
+   return inst->output_buf_size;
+
+   if (inst->opb_buftype == HFI_BUFFER_OUTPUT)
+   return inst->output_buf_size;
+   else if (inst->opb_buftype == HFI_BUFFER_OUTPUT2)
+   return inst->output2_buf_size;
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(venus_helper_get_opb_size);
+
 static void delayed_process_buf_func(struct work_struct *work)
 {
struct venus_buffer *buf, *n;
diff --git a/drivers/media/platform/qcom/venus/helpers.h 
b/drivers/media/platform/qcom/venus/helpers.h
index 8ff4bd3ef958..92be45894a69 100644
--- a/drivers/media/platform/qcom/venus/helpers.h
+++ b/drivers/media/platform/qcom/venus/helpers.h
@@ -48,6 +48,7 @@ int venus_helper_set_raw_format(struct venus_inst *inst, u32 
hfi_format,
 int venus_helper_set_color_format(struct venus_inst *inst, u32 fmt);
 int venus_helper_set_dyn_bufmode(struct venus_inst *inst);
 int venus_helper_set_bufsize(struct venus_inst *inst, u32 bufsize, u32 
buftype);
+unsigned int venus_helper_get_opb_size(struct venus_inst *inst);
 void venus_helper_acquire_buf_ref(struct vb2_v4l2_buffer *vbuf);
 void venus_helper_release_buf_ref(struct venus_inst *inst, unsigned int idx);
 void venus_helper_init_instance(struct venus_inst *inst);
-- 
2.14.1



[PATCH 24/28] venus: vdec: new function for output configuration

2018-04-24 Thread Stanimir Varbanov
Make a new function vdec_output_conf() for decoder output
configuration. vdec_output_conf() will set properties via
HFI interface related to the output configuration, and
keep vdec_set_properties() which will set properties
related to decoding parameters.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/vdec.c | 35 ++--
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/vdec.c 
b/drivers/media/platform/qcom/venus/vdec.c
index 6ed9b7c4bd6e..ced3330c396a 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -545,6 +545,23 @@ static const struct v4l2_ioctl_ops vdec_ioctl_ops = {
 static int vdec_set_properties(struct venus_inst *inst)
 {
struct vdec_controls *ctr = >controls.dec;
+   struct hfi_enable en = { .enable = 1 };
+   u32 ptype;
+   int ret;
+
+   if (ctr->post_loop_deb_mode) {
+   ptype = HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER;
+   en.enable = 1;
+   ret = hfi_session_set_property(inst, ptype, );
+   if (ret)
+   return ret;
+   }
+
+   return 0;
+}
+
+static int vdec_output_conf(struct venus_inst *inst)
+{
struct venus_core *core = inst->core;
struct hfi_enable en = { .enable = 1 };
u32 ptype;
@@ -569,14 +586,6 @@ static int vdec_set_properties(struct venus_inst *inst)
if (ret)
return ret;
 
-   if (ctr->post_loop_deb_mode) {
-   ptype = HFI_PROPERTY_CONFIG_VDEC_POST_LOOP_DEBLOCKER;
-   en.enable = 1;
-   ret = hfi_session_set_property(inst, ptype, );
-   if (ret)
-   return ret;
-   }
-
return 0;
 }
 
@@ -724,7 +733,6 @@ static int vdec_verify_conf(struct venus_inst *inst)
 static int vdec_start_streaming(struct vb2_queue *q, unsigned int count)
 {
struct venus_inst *inst = vb2_get_drv_priv(q);
-   struct venus_core *core = inst->core;
int ret;
 
mutex_lock(>lock);
@@ -753,12 +761,9 @@ static int vdec_start_streaming(struct vb2_queue *q, 
unsigned int count)
if (ret)
goto deinit_sess;
 
-   if (core->res->hfi_version == HFI_VERSION_3XX) {
-   ret = venus_helper_set_bufsize(inst, inst->output_buf_size,
-  HFI_BUFFER_OUTPUT);
-   if (ret)
-   goto deinit_sess;
-   }
+   ret = vdec_output_conf(inst);
+   if (ret)
+   goto deinit_sess;
 
ret = vdec_verify_conf(inst);
if (ret)
-- 
2.14.1



[PATCH 25/28] venus: move frame size calculations in common place

2018-04-24 Thread Stanimir Varbanov
move calculations of raw and compressed in a common helper
and make it identical for encoder and decoder.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/helpers.c | 98 +
 drivers/media/platform/qcom/venus/helpers.h |  2 +
 drivers/media/platform/qcom/venus/vdec.c| 54 
 drivers/media/platform/qcom/venus/venc.c| 56 -
 4 files changed, 126 insertions(+), 84 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index f0a0fca60c76..ed569705ecac 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -455,6 +455,104 @@ int venus_helper_get_bufreq(struct venus_inst *inst, u32 
type,
 }
 EXPORT_SYMBOL_GPL(venus_helper_get_bufreq);
 
+static u32 get_framesize_raw_nv12(u32 width, u32 height)
+{
+   u32 y_stride, uv_stride, y_plane;
+   u32 y_sclines, uv_sclines, uv_plane;
+   u32 size;
+
+   y_stride = ALIGN(width, 128);
+   uv_stride = ALIGN(width, 128);
+   y_sclines = ALIGN(height, 32);
+   uv_sclines = ALIGN(((height + 1) >> 1), 16);
+
+   y_plane = y_stride * y_sclines;
+   uv_plane = uv_stride * uv_sclines + SZ_4K;
+   size = y_plane + uv_plane + SZ_8K;
+
+   return ALIGN(size, SZ_4K);
+}
+
+static u32 get_framesize_raw_nv12_ubwc(u32 width, u32 height)
+{
+   u32 y_meta_stride, y_meta_plane;
+   u32 y_stride, y_plane;
+   u32 uv_meta_stride, uv_meta_plane;
+   u32 uv_stride, uv_plane;
+   u32 extradata = SZ_16K;
+
+   y_meta_stride = ALIGN(DIV_ROUND_UP(width, 32), 64);
+   y_meta_plane = y_meta_stride * ALIGN(DIV_ROUND_UP(height, 8), 16);
+   y_meta_plane = ALIGN(y_meta_plane, SZ_4K);
+
+   y_stride = ALIGN(width, 128);
+   y_plane = ALIGN(y_stride * ALIGN(height, 32), SZ_4K);
+
+   uv_meta_stride = ALIGN(DIV_ROUND_UP(width / 2, 16), 64);
+   uv_meta_plane = uv_meta_stride * ALIGN(DIV_ROUND_UP(height / 2, 8), 16);
+   uv_meta_plane = ALIGN(uv_meta_plane, SZ_4K);
+
+   uv_stride = ALIGN(width, 128);
+   uv_plane = ALIGN(uv_stride * ALIGN(height / 2, 32), SZ_4K);
+
+   return ALIGN(y_meta_plane + y_plane + uv_meta_plane + uv_plane +
+max(extradata, y_stride * 48), SZ_4K);
+}
+
+u32 venus_helper_get_framesz_raw(u32 hfi_fmt, u32 width, u32 height)
+{
+   switch (hfi_fmt) {
+   case HFI_COLOR_FORMAT_NV12:
+   case HFI_COLOR_FORMAT_NV21:
+   return get_framesize_raw_nv12(width, height);
+   case HFI_COLOR_FORMAT_NV12_UBWC:
+   return get_framesize_raw_nv12_ubwc(width, height);
+   default:
+   return 0;
+   }
+}
+EXPORT_SYMBOL_GPL(venus_helper_get_framesz_raw);
+
+u32 venus_helper_get_framesz(u32 v4l2_fmt, u32 width, u32 height)
+{
+   u32 hfi_fmt, sz;
+   bool compressed;
+
+   switch (v4l2_fmt) {
+   case V4L2_PIX_FMT_MPEG:
+   case V4L2_PIX_FMT_H264:
+   case V4L2_PIX_FMT_H264_NO_SC:
+   case V4L2_PIX_FMT_H264_MVC:
+   case V4L2_PIX_FMT_H263:
+   case V4L2_PIX_FMT_MPEG1:
+   case V4L2_PIX_FMT_MPEG2:
+   case V4L2_PIX_FMT_MPEG4:
+   case V4L2_PIX_FMT_XVID:
+   case V4L2_PIX_FMT_VC1_ANNEX_G:
+   case V4L2_PIX_FMT_VC1_ANNEX_L:
+   case V4L2_PIX_FMT_VP8:
+   case V4L2_PIX_FMT_VP9:
+   case V4L2_PIX_FMT_HEVC:
+   compressed = true;
+   break;
+   default:
+   compressed = false;
+   break;
+   }
+
+   if (compressed) {
+   sz = ALIGN(height, 32) * ALIGN(width, 32) * 3 / 2 / 2;
+   return ALIGN(sz, SZ_4K);
+   }
+
+   hfi_fmt = to_hfi_raw_fmt(v4l2_fmt);
+   if (!hfi_fmt)
+   return 0;
+
+   return venus_helper_get_framesz_raw(hfi_fmt, width, height);
+}
+EXPORT_SYMBOL_GPL(venus_helper_get_framesz);
+
 int venus_helper_set_input_resolution(struct venus_inst *inst,
  unsigned int width, unsigned int height)
 {
diff --git a/drivers/media/platform/qcom/venus/helpers.h 
b/drivers/media/platform/qcom/venus/helpers.h
index 92be45894a69..92b167a47166 100644
--- a/drivers/media/platform/qcom/venus/helpers.h
+++ b/drivers/media/platform/qcom/venus/helpers.h
@@ -33,6 +33,8 @@ void venus_helper_m2m_device_run(void *priv);
 void venus_helper_m2m_job_abort(void *priv);
 int venus_helper_get_bufreq(struct venus_inst *inst, u32 type,
struct hfi_buffer_requirements *req);
+u32 venus_helper_get_framesz_raw(u32 hfi_fmt, u32 width, u32 height);
+u32 venus_helper_get_framesz(u32 v4l2_fmt, u32 width, u32 height);
 int venus_helper_set_input_resolution(struct venus_inst *inst,
  unsigned int width, unsigned int height);
 int venus_helper_set_output_resolution(struct venus_inst *inst,
diff --git a/drivers/media/platform/qcom/ven

[PATCH 28/28] venus: add HEVC codec support

2018-04-24 Thread Stanimir Varbanov
This add HEVC codec support for venus versions 3xx and 4xx.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/helpers.c | 3 +++
 drivers/media/platform/qcom/venus/hfi.c | 2 ++
 drivers/media/platform/qcom/venus/vdec.c| 4 
 drivers/media/platform/qcom/venus/venc.c| 4 
 4 files changed, 13 insertions(+)

diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index 87dcf9973e6f..fecadba039cf 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -71,6 +71,9 @@ bool venus_helper_check_codec(struct venus_inst *inst, u32 
v4l2_pixfmt)
case V4L2_PIX_FMT_XVID:
codec = HFI_VIDEO_CODEC_DIVX;
break;
+   case V4L2_PIX_FMT_HEVC:
+   codec = HFI_VIDEO_CODEC_HEVC;
+   break;
default:
return false;
}
diff --git a/drivers/media/platform/qcom/venus/hfi.c 
b/drivers/media/platform/qcom/venus/hfi.c
index 94ca27b0bb99..24207829982f 100644
--- a/drivers/media/platform/qcom/venus/hfi.c
+++ b/drivers/media/platform/qcom/venus/hfi.c
@@ -49,6 +49,8 @@ static u32 to_codec_type(u32 pixfmt)
return HFI_VIDEO_CODEC_VP9;
case V4L2_PIX_FMT_XVID:
return HFI_VIDEO_CODEC_DIVX;
+   case V4L2_PIX_FMT_HEVC:
+   return HFI_VIDEO_CODEC_HEVC;
default:
return 0;
}
diff --git a/drivers/media/platform/qcom/venus/vdec.c 
b/drivers/media/platform/qcom/venus/vdec.c
index 7deee104ac56..a114f421edad 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -77,6 +77,10 @@ static const struct venus_format vdec_formats[] = {
.pixfmt = V4L2_PIX_FMT_XVID,
.num_planes = 1,
.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+   }, {
+   .pixfmt = V4L2_PIX_FMT_HEVC,
+   .num_planes = 1,
+   .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
},
 };
 
diff --git a/drivers/media/platform/qcom/venus/venc.c 
b/drivers/media/platform/qcom/venus/venc.c
index a703bce78abc..fdb76b69786f 100644
--- a/drivers/media/platform/qcom/venus/venc.c
+++ b/drivers/media/platform/qcom/venus/venc.c
@@ -59,6 +59,10 @@ static const struct venus_format venc_formats[] = {
.pixfmt = V4L2_PIX_FMT_VP8,
.num_planes = 1,
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+   }, {
+   .pixfmt = V4L2_PIX_FMT_HEVC,
+   .num_planes = 1,
+   .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
},
 };
 
-- 
2.14.1



[PATCH 16/28] venus: add helper function to set actual buffer size

2018-04-24 Thread Stanimir Varbanov
Add and use a helper function to set actual buffer size for
particular buffer type. This is also preparation to use
the second decoder output.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/helpers.c | 12 
 drivers/media/platform/qcom/venus/helpers.h |  1 +
 drivers/media/platform/qcom/venus/vdec.c| 10 ++
 3 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/helpers.c 
b/drivers/media/platform/qcom/venus/helpers.c
index 824ad4d2d064..94664a3ce3e2 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -544,6 +544,18 @@ int venus_helper_set_dyn_bufmode(struct venus_inst *inst)
 }
 EXPORT_SYMBOL_GPL(venus_helper_set_dyn_bufmode);
 
+int venus_helper_set_bufsize(struct venus_inst *inst, u32 bufsize, u32 buftype)
+{
+   u32 ptype = HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL;
+   struct hfi_buffer_size_actual bufsz;
+
+   bufsz.type = buftype;
+   bufsz.size = bufsize;
+
+   return hfi_session_set_property(inst, ptype, );
+}
+EXPORT_SYMBOL_GPL(venus_helper_set_bufsize);
+
 static void delayed_process_buf_func(struct work_struct *work)
 {
struct venus_buffer *buf, *n;
diff --git a/drivers/media/platform/qcom/venus/helpers.h 
b/drivers/media/platform/qcom/venus/helpers.h
index 52b961ed491e..cd306bd8978f 100644
--- a/drivers/media/platform/qcom/venus/helpers.h
+++ b/drivers/media/platform/qcom/venus/helpers.h
@@ -41,6 +41,7 @@ int venus_helper_set_num_bufs(struct venus_inst *inst, 
unsigned int input_bufs,
  unsigned int output_bufs);
 int venus_helper_set_color_format(struct venus_inst *inst, u32 fmt);
 int venus_helper_set_dyn_bufmode(struct venus_inst *inst);
+int venus_helper_set_bufsize(struct venus_inst *inst, u32 bufsize, u32 
buftype);
 void venus_helper_acquire_buf_ref(struct vb2_v4l2_buffer *vbuf);
 void venus_helper_release_buf_ref(struct venus_inst *inst, unsigned int idx);
 void venus_helper_init_instance(struct venus_inst *inst);
diff --git a/drivers/media/platform/qcom/venus/vdec.c 
b/drivers/media/platform/qcom/venus/vdec.c
index 1de9cc64cf2f..b43607dee4fe 100644
--- a/drivers/media/platform/qcom/venus/vdec.c
+++ b/drivers/media/platform/qcom/venus/vdec.c
@@ -710,7 +710,6 @@ static int vdec_start_streaming(struct vb2_queue *q, 
unsigned int count)
 {
struct venus_inst *inst = vb2_get_drv_priv(q);
struct venus_core *core = inst->core;
-   u32 ptype;
int ret;
 
mutex_lock(>lock);
@@ -740,13 +739,8 @@ static int vdec_start_streaming(struct vb2_queue *q, 
unsigned int count)
goto deinit_sess;
 
if (core->res->hfi_version == HFI_VERSION_3XX) {
-   struct hfi_buffer_size_actual buf_sz;
-
-   ptype = HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL;
-   buf_sz.type = HFI_BUFFER_OUTPUT;
-   buf_sz.size = inst->output_buf_size;
-
-   ret = hfi_session_set_property(inst, ptype, _sz);
+   ret = venus_helper_set_bufsize(inst, inst->output_buf_size,
+  HFI_BUFFER_OUTPUT);
if (ret)
goto deinit_sess;
}
-- 
2.14.1



[PATCH 00/28] Venus updates

2018-04-24 Thread Stanimir Varbanov
Hello,

This patch set aims to:

* add initial support for Venus version 4xx (found on sdm845).

* introduce a common capability parser to enumerate better
  supported uncompressed formats, capabilities by codec,
  supported codecs and so on.

* also contains various cleanups, readability improvements
  and fixes.

* adds HEVC codec support for the Venus versions which has
  support for it.

* add multi-stream support (secondary decoder output), which
  will give as an opportunity to use UBWC compressed formats
  to optimize internal interconnect bandwidth on higher
  resolutions.

Comments are welcome!

regards,
Stan

Stanimir Varbanov (28):
  venus: hfi_msgs: correct pointer increment
  venus: hfi: preparation to support venus 4xx
  venus: hfi: update sequence event to handle more properties
  venus: hfi_cmds: add set_properties for 4xx version
  venus: hfi: support session continue for 4xx version
  venus: hfi: handle buffer output2 type as well
  venus: hfi_venus: add halt AXI support for Venus 4xx
  venus: hfi_venus: add suspend function for 4xx version
  venus: venc,vdec: adds clocks needed for venus 4xx
  venus: vdec: call session_continue in insufficient event
  venus: add common capability parser
  venus: helpers: make a commmon function for power_enable
  venus: core: delete not used flag for buffer mode
  venus: helpers: rename a helper function and use buffer mode from caps
  venus: add a helper function to set dynamic buffer mode
  venus: add helper function to set actual buffer size
  venus: delete no longer used bufmode flag from instance
  venus: helpers: add buffer type argument to a helper
  venus: helpers: add a new helper to set raw format
  venus: helpers,vdec,venc: add helpers to set work mode and core usage
  venus: helpers: extend set_num_bufs helper with one more argument
  venus: helpers: add a helper to return opb buffer sizes
  venus: vdec: get required input buffers as well
  venus: vdec: new function for output configuration
  venus: move frame size calculations in common place
  venus: implementing multi-stream support
  venus: add sdm845 compatible and resource data
  venus: add HEVC codec support

 .../devicetree/bindings/media/qcom,venus.txt   |   1 +
 drivers/media/platform/qcom/venus/Makefile |   3 +-
 drivers/media/platform/qcom/venus/core.c   | 102 
 drivers/media/platform/qcom/venus/core.h   |  91 ++--
 drivers/media/platform/qcom/venus/helpers.c| 558 +++--
 drivers/media/platform/qcom/venus/helpers.h|  23 +-
 drivers/media/platform/qcom/venus/hfi.c|  12 +-
 drivers/media/platform/qcom/venus/hfi.h|   9 +
 drivers/media/platform/qcom/venus/hfi_cmds.c   |  64 ++-
 drivers/media/platform/qcom/venus/hfi_helper.h | 112 -
 drivers/media/platform/qcom/venus/hfi_msgs.c   | 401 +++
 drivers/media/platform/qcom/venus/hfi_parser.c | 290 +++
 drivers/media/platform/qcom/venus/hfi_parser.h |  45 ++
 drivers/media/platform/qcom/venus/hfi_venus.c  |  69 +++
 drivers/media/platform/qcom/venus/hfi_venus_io.h   |  24 +
 drivers/media/platform/qcom/venus/vdec.c   | 324 +++-
 drivers/media/platform/qcom/venus/venc.c   | 166 +++---
 17 files changed, 1641 insertions(+), 653 deletions(-)
 create mode 100644 drivers/media/platform/qcom/venus/hfi_parser.c
 create mode 100644 drivers/media/platform/qcom/venus/hfi_parser.h

-- 
2.14.1



Re: [PATCH v2] venus: vdec: fix format enumeration

2018-03-23 Thread Stanimir Varbanov

Hi Hans,

Could you take this patch it not too late.

On 20.03.2018 15:42, Stanimir Varbanov wrote:

Hi Alex,

Thanks!

On 03/19/2018 11:32 AM, Alexandre Courbot wrote:

find_format_by_index() stops enumerating formats as soon as the index
matches, and returns NULL if venus_helper_check_codec() finds out that
the format is not supported. This prevents formats to be properly
enumerated if a non-supported format is present, as the enumeration will
end with it.

Fix this by moving the call to venus_helper_check_codec() into the loop,
and keep enumerating when it fails.

Fixes: 29f0133ec6 media: venus: use helper function to check supported codecs

Signed-off-by: Alexandre Courbot <acour...@chromium.org>
---
  drivers/media/platform/qcom/venus/vdec.c | 13 +++--
  drivers/media/platform/qcom/venus/venc.c | 13 +++--
  2 files changed, 14 insertions(+), 12 deletions(-)


Acked-by: Stanimir Varbanov <stanimir.varba...@linaro.org>



regards,
Stan


Re: [PATCH v2] venus: vdec: fix format enumeration

2018-03-20 Thread Stanimir Varbanov
Hi Alex,

Thanks!

On 03/19/2018 11:32 AM, Alexandre Courbot wrote:
> find_format_by_index() stops enumerating formats as soon as the index
> matches, and returns NULL if venus_helper_check_codec() finds out that
> the format is not supported. This prevents formats to be properly
> enumerated if a non-supported format is present, as the enumeration will
> end with it.
> 
> Fix this by moving the call to venus_helper_check_codec() into the loop,
> and keep enumerating when it fails.
> 
> Fixes: 29f0133ec6 media: venus: use helper function to check supported codecs
> 
> Signed-off-by: Alexandre Courbot <acour...@chromium.org>
> ---
>  drivers/media/platform/qcom/venus/vdec.c | 13 +++--
>  drivers/media/platform/qcom/venus/venc.c | 13 +++--
>  2 files changed, 14 insertions(+), 12 deletions(-)

Acked-by: Stanimir Varbanov <stanimir.varba...@linaro.org>

-- 
regards,
Stan


Re: [PATCH] venus: vdec: fix format enumeration

2018-03-15 Thread Stanimir Varbanov
Hi Alex,

Thanks for the patch!

On 13.03.2018 11:11, Alexandre Courbot wrote:
> find_format_by_index() stops enumerating formats as soon as the index
> matches, and returns NULL if venus_helper_check_codec() finds out that
> the format is not supported. This prevents formats to be properly
> enumerated if a non-supported format is present, as the enumeration will
> end with it.

Please add fixes tag,

Fixes: 29f0133ec6 media: venus: use helper function to check supported
codecs

> 
> Fix this by moving the call to venus_helper_check_codec() into the loop,
> and keep enumerating when it fails.

Good catch!

> 
> Signed-off-by: Alexandre Courbot 
> 
> Change-Id: I4ff66e0b85172598efa59a6f01da8cb60597a6a5

You forgot to delete gerrit id.

> ---
>   drivers/media/platform/qcom/venus/vdec.c | 13 +++--
>   drivers/media/platform/qcom/venus/venc.c |  9 +++--
>   2 files changed, 14 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/media/platform/qcom/venus/vdec.c 
> b/drivers/media/platform/qcom/venus/vdec.c
> index c9e9576bb08a..3677302cfe43 100644
> --- a/drivers/media/platform/qcom/venus/vdec.c
> +++ b/drivers/media/platform/qcom/venus/vdec.c
> @@ -135,20 +135,21 @@ find_format_by_index(struct venus_inst *inst, unsigned 
> int index, u32 type)
>   return NULL;
>   
>   for (i = 0; i < size; i++) {
> + bool valid;
> +
>   if (fmt[i].type != type)
>   continue;
> - if (k == index)
> + valid = (type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
> +  venus_helper_check_codec(inst, fmt[i].pixfmt));

open and close braces are not needed.

> + if (k == index && valid)
>   break;
> - k++;
> + if (valid)
> + k++;
>   }
>   
>   if (i == size)
>   return NULL;
>   
> - if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
> - !venus_helper_check_codec(inst, fmt[i].pixfmt))
> - return NULL;
> -
>   return [i];
>   }
>   
> diff --git a/drivers/media/platform/qcom/venus/venc.c 
> b/drivers/media/platform/qcom/venus/venc.c
> index e3a10a852cad..5eba4c7cd52e 100644
> --- a/drivers/media/platform/qcom/venus/venc.c
> +++ b/drivers/media/platform/qcom/venus/venc.c
> @@ -120,11 +120,16 @@ find_format_by_index(struct venus_inst *inst, unsigned 
> int index, u32 type)
>   return NULL;
>   
>   for (i = 0; i < size; i++) {
> + bool valid;
> +
>   if (fmt[i].type != type)
>   continue;
> - if (k == index)
> + valid = (type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
> +  venus_helper_check_codec(inst, fmt[i].pixfmt));
> + if (k == index && valid)
>   break;
> - k++;
> + if (valid)
> + k++;
>   }
>   
>   if (i == size)

maybe we should delete the condition:

if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
!venus_helper_check_codec(inst, fmt[i].pixfmt))

as we do for the decoder?

regards,
Stan


Re: [Patch v6 10/12] [media] v4l2: Add v4l2 control IDs for HEVC encoder

2017-12-09 Thread Stanimir Varbanov

Hi Smitha,

Thanks for the patches!

On 12/08/2017 11:08 AM, Smitha T Murthy wrote:

Add v4l2 controls for HEVC encoder

Signed-off-by: Smitha T Murthy 
Reviewed-by: Andrzej Hajda 
---
 drivers/media/v4l2-core/v4l2-ctrls.c | 118 +++
 include/uapi/linux/v4l2-controls.h   |  92 ++-
 2 files changed, 209 insertions(+), 1 deletion(-)

diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c 
b/drivers/media/v4l2-core/v4l2-ctrls.c
index 4e53a86..3f98318 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -480,6 +480,56 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
NULL,
};
 
+	static const char * const hevc_profile[] = {

+   "Main",


You forgot "Main 10" profile.


+   "Main Still Picture",
+   NULL,
+   };
+   static const char * const hevc_level[] = {
+   "1",
+   "2",
+   "2.1",
+   "3",
+   "3.1",
+   "4",
+   "4.1",
+   "5",
+   "5.1",
+   "5.2",
+   "6",
+   "6.1",
+   "6.2",
+   NULL,
+   };
+   static const char * const hevc_hierarchial_coding_type[] = {
+   "B",
+   "P",
+   NULL,
+   };
+   static const char * const hevc_refresh_type[] = {
+   "None",
+   "CRA",
+   "IDR",
+   NULL,
+   };
+   static const char * const hevc_size_of_length_field[] = {
+   "0",
+   "1",
+   "2",
+   "4",
+   NULL,
+   };
+   static const char * const hevc_tier_flag[] = {
+   "Main",
+   "High",
+   NULL,
+   };
+   static const char * const hevc_loop_filter_mode[] = {
+   "Disabled",
+   "Enabled",
+   "Disabled at slice boundary",
+   "NULL",
+   };
 
 	switch (id) {

case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
@@ -575,6 +625,20 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
return dv_it_content_type;
case V4L2_CID_DETECT_MD_MODE:
return detect_md_mode;
+   case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE:
+   return hevc_profile;
+   case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL:
+   return hevc_level;
+   case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE:
+   return hevc_hierarchial_coding_type;
+   case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE:
+   return hevc_refresh_type;
+   case V4L2_CID_MPEG_VIDEO_HEVC_SIZE_OF_LENGTH_FIELD:
+   return hevc_size_of_length_field;
+   case V4L2_CID_MPEG_VIDEO_HEVC_TIER_FLAG:


Could you drop _FLAG suffix? Looking (briefly) into the spec they not
specify `tier flag` but just `tier`.


+   return hevc_tier_flag;
+   case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE:
+   return hevc_loop_filter_mode;
 
 	default:

return NULL;
@@ -776,6 +840,53 @@ const char *v4l2_ctrl_get_name(u32 id)
case V4L2_CID_MPEG_VIDEO_VPX_P_FRAME_QP:return "VPX P-Frame 
QP Value";
case V4L2_CID_MPEG_VIDEO_VPX_PROFILE:   return "VPX 
Profile";
 
+	/* HEVC controls */

+   case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP:   return "HEVC I-Frame 
QP Value";
+   case V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP:   return "HEVC P-Frame 
QP Value";
+   case V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP:   return "HEVC B-Frame 
QP Value";
+   case V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP:   return "HEVC Minimum 
QP Value";
+   case V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP:   return "HEVC Maximum 
QP Value";
+   case V4L2_CID_MPEG_VIDEO_HEVC_PROFILE:  return "HEVC 
Profile";
+   case V4L2_CID_MPEG_VIDEO_HEVC_LEVEL:return "HEVC 
Level";
+   case V4L2_CID_MPEG_VIDEO_HEVC_TIER_FLAG:return "HEVC Tier 
Flag";
+   case V4L2_CID_MPEG_VIDEO_HEVC_FRAME_RATE_RESOLUTION:return "HEVC Frame 
Rate Resolution";
+   case V4L2_CID_MPEG_VIDEO_HEVC_MAX_PARTITION_DEPTH:  return "HEVC Maximum 
Coding Unit Depth";
+   case V4L2_CID_MPEG_VIDEO_HEVC_REFRESH_TYPE: return "HEVC Refresh 
Type";
+   case V4L2_CID_MPEG_VIDEO_HEVC_CONST_INTRA_PRED: return "HEVC 
Constant Intra Prediction";
+   case V4L2_CID_MPEG_VIDEO_HEVC_LOSSLESS_CU:  return "HEVC 
Lossless Encoding";
+   case V4L2_CID_MPEG_VIDEO_HEVC_WAVEFRONT:return "HEVC 
Wavefront";
+   case V4L2_CID_MPEG_VIDEO_HEVC_LOOP_FILTER_MODE: return "HEVC Loop 
Filter";
+   case V4L2_CID_MPEG_VIDEO_HEVC_HIER_QP:  return "HEVC QP 
Values";
+   case 

[PATCH v2] venus: venc: set correctly GOP size and number of B-frames

2017-12-01 Thread Stanimir Varbanov
This change fixes the calculation of B-frames and GOP size by
adopt v4l2 controls with the firmware interface expectations.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
Drop usage of do_div to avoid compiler warnings on 32bit systems.

 drivers/media/platform/qcom/venus/venc.c   | 15 ---
 drivers/media/platform/qcom/venus/venc_ctrls.c | 59 +-
 2 files changed, 68 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/venc.c 
b/drivers/media/platform/qcom/venus/venc.c
index 36d31540c59d..e3a10a852cad 100644
--- a/drivers/media/platform/qcom/venus/venc.c
+++ b/drivers/media/platform/qcom/venus/venc.c
@@ -685,8 +685,13 @@ static int venc_set_properties(struct venus_inst *inst)
return ret;
}
 
+   /* IDR periodicity, n:
+* n = 0 - only the first I-frame is IDR frame
+* n = 1 - all I-frames will be IDR frames
+* n > 1 - every n-th I-frame will be IDR frame
+*/
ptype = HFI_PROPERTY_CONFIG_VENC_IDR_PERIOD;
-   idrp.idr_period = ctr->gop_size;
+   idrp.idr_period = 0;
ret = hfi_session_set_property(inst, ptype, );
if (ret)
return ret;
@@ -700,10 +705,6 @@ static int venc_set_properties(struct venus_inst *inst)
return ret;
}
 
-   /* intra_period = pframes + bframes + 1 */
-   if (!ctr->num_p_frames)
-   ctr->num_p_frames = 2 * 15 - 1,
-
ptype = HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD;
intra_period.pframes = ctr->num_p_frames;
intra_period.bframes = ctr->num_b_frames;
@@ -800,6 +801,10 @@ static int venc_init_session(struct venus_inst *inst)
if (ret)
goto deinit;
 
+   ret = venc_set_properties(inst);
+   if (ret)
+   goto deinit;
+
return 0;
 deinit:
hfi_session_deinit(inst);
diff --git a/drivers/media/platform/qcom/venus/venc_ctrls.c 
b/drivers/media/platform/qcom/venus/venc_ctrls.c
index ab0fe51ff0f7..8dbb32ebae89 100644
--- a/drivers/media/platform/qcom/venus/venc_ctrls.c
+++ b/drivers/media/platform/qcom/venus/venc_ctrls.c
@@ -30,10 +30,57 @@
 #define AT_SLICE_BOUNDARY  \
V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY
 
+static int venc_calc_bpframes(u32 gop_size, u32 conseq_b, u32 *bf, u32 *pf)
+{
+   uint32_t half = (gop_size - 1) >> 1;
+   uint32_t b, p, ratio;
+   bool found = false;
+
+   if (!gop_size)
+   return -EINVAL;
+
+   *bf = *pf = 0;
+
+   if (!conseq_b) {
+   *pf = gop_size -  1;
+   return 0;
+   }
+
+   b = p = half;
+
+   for (; b <= gop_size - 1; b++, p--) {
+   if (b % p)
+   continue;
+
+   ratio = b / p;
+
+   if (ratio == conseq_b) {
+   found = true;
+   break;
+   }
+
+   if (ratio > conseq_b)
+   break;
+   }
+
+   if (found == false)
+   return -EINVAL;
+
+   if (b + p + 1 != gop_size)
+   return -EINVAL;
+
+   *bf = b;
+   *pf = p;
+
+   return 0;
+}
+
 static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
 {
struct venus_inst *inst = ctrl_to_inst(ctrl);
struct venc_controls *ctr = >controls.enc;
+   u32 bframes;
+   int ret;
 
switch (ctrl->id) {
case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
@@ -102,6 +149,11 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
break;
case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+   ret = venc_calc_bpframes(ctrl->val, ctr->num_b_frames, ,
+>num_p_frames);
+   if (ret)
+   return ret;
+
ctr->gop_size = ctrl->val;
break;
case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:
@@ -114,7 +166,12 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
ctr->vp8_max_qp = ctrl->val;
break;
case V4L2_CID_MPEG_VIDEO_B_FRAMES:
-   ctr->num_b_frames = ctrl->val;
+   ret = venc_calc_bpframes(ctr->gop_size, ctrl->val, ,
+>num_p_frames);
+   if (ret)
+   return ret;
+
+   ctr->num_b_frames = bframes;
break;
default:
return -EINVAL;
-- 
2.11.0



[PATCH 2/2] venus: venc: set correctly GOP size and number of B-frames

2017-11-29 Thread Stanimir Varbanov
This change fixes the calculation of B-frames and GOP size by
adopt v4l2 controls with the firmware interface expectations.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/venc.c   | 15 ---
 drivers/media/platform/qcom/venus/venc_ctrls.c | 60 +-
 2 files changed, 69 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/venc.c 
b/drivers/media/platform/qcom/venus/venc.c
index 36d31540c59d..e3a10a852cad 100644
--- a/drivers/media/platform/qcom/venus/venc.c
+++ b/drivers/media/platform/qcom/venus/venc.c
@@ -685,8 +685,13 @@ static int venc_set_properties(struct venus_inst *inst)
return ret;
}
 
+   /* IDR periodicity, n:
+* n = 0 - only the first I-frame is IDR frame
+* n = 1 - all I-frames will be IDR frames
+* n > 1 - every n-th I-frame will be IDR frame
+*/
ptype = HFI_PROPERTY_CONFIG_VENC_IDR_PERIOD;
-   idrp.idr_period = ctr->gop_size;
+   idrp.idr_period = 0;
ret = hfi_session_set_property(inst, ptype, );
if (ret)
return ret;
@@ -700,10 +705,6 @@ static int venc_set_properties(struct venus_inst *inst)
return ret;
}
 
-   /* intra_period = pframes + bframes + 1 */
-   if (!ctr->num_p_frames)
-   ctr->num_p_frames = 2 * 15 - 1,
-
ptype = HFI_PROPERTY_CONFIG_VENC_INTRA_PERIOD;
intra_period.pframes = ctr->num_p_frames;
intra_period.bframes = ctr->num_b_frames;
@@ -800,6 +801,10 @@ static int venc_init_session(struct venus_inst *inst)
if (ret)
goto deinit;
 
+   ret = venc_set_properties(inst);
+   if (ret)
+   goto deinit;
+
return 0;
 deinit:
hfi_session_deinit(inst);
diff --git a/drivers/media/platform/qcom/venus/venc_ctrls.c 
b/drivers/media/platform/qcom/venus/venc_ctrls.c
index ab0fe51ff0f7..53130d4774d3 100644
--- a/drivers/media/platform/qcom/venus/venc_ctrls.c
+++ b/drivers/media/platform/qcom/venus/venc_ctrls.c
@@ -30,10 +30,58 @@
 #define AT_SLICE_BOUNDARY  \
V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY
 
+static int venc_calc_bpframes(u32 gop_size, u32 conseq_b, u32 *bf, u32 *pf)
+{
+   uint32_t half = (gop_size - 1) >> 1;
+   uint32_t b, p, ratio;
+   bool found = false;
+
+   if (!gop_size)
+   return -EINVAL;
+
+   *bf = *pf = 0;
+
+   if (!conseq_b) {
+   *pf = gop_size -  1;
+   return 0;
+   }
+
+   b = p = half;
+
+   for (; b <= gop_size - 1; b++, p--) {
+   if (b % p)
+   continue;
+
+   ratio = b;
+   do_div(ratio, p);
+
+   if (ratio == conseq_b) {
+   found = true;
+   break;
+   }
+
+   if (ratio > conseq_b)
+   break;
+   }
+
+   if (found == false)
+   return -EINVAL;
+
+   if (b + p + 1 != gop_size)
+   return -EINVAL;
+
+   *bf = b;
+   *pf = p;
+
+   return 0;
+}
+
 static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
 {
struct venus_inst *inst = ctrl_to_inst(ctrl);
struct venc_controls *ctr = >controls.enc;
+   u32 bframes;
+   int ret;
 
switch (ctrl->id) {
case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
@@ -102,6 +150,11 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB:
break;
case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+   ret = venc_calc_bpframes(ctrl->val, ctr->num_b_frames, ,
+>num_p_frames);
+   if (ret)
+   return ret;
+
ctr->gop_size = ctrl->val;
break;
case V4L2_CID_MPEG_VIDEO_H264_I_PERIOD:
@@ -114,7 +167,12 @@ static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
ctr->vp8_max_qp = ctrl->val;
break;
case V4L2_CID_MPEG_VIDEO_B_FRAMES:
-   ctr->num_b_frames = ctrl->val;
+   ret = venc_calc_bpframes(ctr->gop_size, ctrl->val, ,
+>num_p_frames);
+   if (ret)
+   return ret;
+
+   ctr->num_b_frames = bframes;
break;
default:
return -EINVAL;
-- 
2.11.0



[PATCH 1/2] venus: cleanup set_property controls

2017-11-29 Thread Stanimir Varbanov
Move ptype (property type) initialization out of switch case
and save few lines of code.

Signed-off-by: Stanimir Varbanov <stanimir.varba...@linaro.org>
---
 drivers/media/platform/qcom/venus/hfi_cmds.c | 73 +---
 1 file changed, 2 insertions(+), 71 deletions(-)

diff --git a/drivers/media/platform/qcom/venus/hfi_cmds.c 
b/drivers/media/platform/qcom/venus/hfi_cmds.c
index b83c5b8ddccb..1cfeb7743041 100644
--- a/drivers/media/platform/qcom/venus/hfi_cmds.c
+++ b/drivers/media/platform/qcom/venus/hfi_cmds.c
@@ -421,12 +421,12 @@ static int pkt_session_set_property_1x(struct 
hfi_session_set_property_pkt *pkt,
pkt->shdr.hdr.pkt_type = HFI_CMD_SESSION_SET_PROPERTY;
pkt->shdr.session_id = hash32_ptr(cookie);
pkt->num_properties = 1;
+   pkt->data[0] = ptype;
 
switch (ptype) {
case HFI_PROPERTY_CONFIG_FRAME_RATE: {
struct hfi_framerate *in = pdata, *frate = prop_data;
 
-   pkt->data[0] = HFI_PROPERTY_CONFIG_FRAME_RATE;
frate->buffer_type = in->buffer_type;
frate->framerate = in->framerate;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*frate);
@@ -436,7 +436,6 @@ static int pkt_session_set_property_1x(struct 
hfi_session_set_property_pkt *pkt,
struct hfi_uncompressed_format_select *in = pdata;
struct hfi_uncompressed_format_select *hfi = prop_data;
 
-   pkt->data[0] = HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SELECT;
hfi->buffer_type = in->buffer_type;
hfi->format = in->format;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*hfi);
@@ -445,7 +444,6 @@ static int pkt_session_set_property_1x(struct 
hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_FRAME_SIZE: {
struct hfi_framesize *in = pdata, *fsize = prop_data;
 
-   pkt->data[0] = HFI_PROPERTY_PARAM_FRAME_SIZE;
fsize->buffer_type = in->buffer_type;
fsize->height = in->height;
fsize->width = in->width;
@@ -455,7 +453,6 @@ static int pkt_session_set_property_1x(struct 
hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_CONFIG_REALTIME: {
struct hfi_enable *in = pdata, *en = prop_data;
 
-   pkt->data[0] = HFI_PROPERTY_CONFIG_REALTIME;
en->enable = in->enable;
pkt->shdr.hdr.size += sizeof(u32) * 2;
break;
@@ -463,7 +460,6 @@ static int pkt_session_set_property_1x(struct 
hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL: {
struct hfi_buffer_count_actual *in = pdata, *count = prop_data;
 
-   pkt->data[0] = HFI_PROPERTY_PARAM_BUFFER_COUNT_ACTUAL;
count->count_actual = in->count_actual;
count->type = in->type;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*count);
@@ -472,7 +468,6 @@ static int pkt_session_set_property_1x(struct 
hfi_session_set_property_pkt *pkt,
case HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL: {
struct hfi_buffer_size_actual *in = pdata, *sz = prop_data;
 
-   pkt->data[0] = HFI_PROPERTY_PARAM_BUFFER_SIZE_ACTUAL;
sz->size = in->size;
sz->type = in->type;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*sz);
@@ -482,8 +477,6 @@ static int pkt_session_set_property_1x(struct 
hfi_session_set_property_pkt *pkt,
struct hfi_buffer_display_hold_count_actual *in = pdata;
struct hfi_buffer_display_hold_count_actual *count = prop_data;
 
-   pkt->data[0] =
-   HFI_PROPERTY_PARAM_BUFFER_DISPLAY_HOLD_COUNT_ACTUAL;
count->hold_count = in->hold_count;
count->type = in->type;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*count);
@@ -493,7 +486,6 @@ static int pkt_session_set_property_1x(struct 
hfi_session_set_property_pkt *pkt,
struct hfi_nal_stream_format_select *in = pdata;
struct hfi_nal_stream_format_select *fmt = prop_data;
 
-   pkt->data[0] = HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SELECT;
fmt->format = in->format;
pkt->shdr.hdr.size += sizeof(u32) + sizeof(*fmt);
break;
@@ -510,7 +502,6 @@ static int pkt_session_set_property_1x(struct 
hfi_session_set_property_pkt *pkt,
break;
}
 
-   pkt->data[0] = HFI_PROPERTY_PARAM_VDEC_OUTPUT_ORDER;
pkt->data[1] = *in;
pkt->shdr.hdr.size += sizeof(u32) * 2;
break;
@@ -518,7 +509,6 @@ static int pkt_session_set_property_1x(struct 
hfi_session_set_property_pkt *pkt,

Re: [PATCH 2/2] media: venus: venc: Apply inloop deblocking filter

2017-11-24 Thread Stanimir Varbanov
Hi Loic,

Thanks for the patch!

On 11/24/2017 11:34 AM, Loic Poulain wrote:
> Deblocking filter allows to reduce blocking artifacts and improve
> visual quality. This is configurable via the V4L2 API but eventually
> not applied to the encoder.
> 
> Note that alpha and beta deblocking values are 32-bit signed (-6;+6).
> 
> Signed-off-by: Loic Poulain <loic.poul...@linaro.org>
> ---
>  drivers/media/platform/qcom/venus/core.h   |  4 ++--
>  drivers/media/platform/qcom/venus/hfi_helper.h |  4 ++--
>  drivers/media/platform/qcom/venus/venc.c   | 22 ++
>  3 files changed, 26 insertions(+), 4 deletions(-)

Reviewed-by: Stanimir Varbanov <stanimir.varba...@linaro.org>

-- 
regards,
Stan


  1   2   3   4   >