* Re: [PATCH RESEND V11 1/4] dt-bindings: fsl: scu: add thermal binding
From: Rob Herring @ 2019-04-10 13:46 UTC (permalink / raw)
To: Anson Huang
Cc: mark.rutland@arm.com, shawnguo@kernel.org, s.hauer@pengutronix.de,
kernel@pengutronix.de, festevam@gmail.com,
catalin.marinas@arm.com, will.deacon@arm.com, rui.zhang@intel.com,
edubezval@gmail.com, daniel.lezcano@linaro.org, Aisheng Dong,
ulf.hansson@linaro.org, Peng Fan, Daniel Baluta,
horms+renesas@verge.net.au, heiko@sntech.de, Andy Gross
In-Reply-To: <1554881866-26333-1-git-send-email-Anson.Huang@nxp.com>
On Wed, Apr 10, 2019 at 07:43:04AM +0000, Anson Huang wrote:
> NXP i.MX8QXP is an ARMv8 SoC with a Cortex-M4 core inside as
> system controller, the system controller is in charge of system
> power, clock and thermal sensors etc. management, Linux kernel
> has to communicate with system controller via MU (message unit)
> IPC to get temperature from thermal sensors, this patch adds
> binding doc for i.MX system controller thermal driver.
>
> Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
> ---
> Changes since V10:
> - remove property "imx,sensor-resource-id".
> ---
> .../devicetree/bindings/arm/freescale/fsl,scu.txt | 16 ++++++++++++++++
> 1 file changed, 16 insertions(+)
Reviewed-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
* [dpdk-dev] [PATCH 2/2] bpf: remove use of weak functions
From: Bruce Richardson @ 2019-04-10 13:45 UTC (permalink / raw)
To: konstantin.ananyev, aconole; +Cc: dev, Bruce Richardson
In-Reply-To: <20190410134517.63896-1-bruce.richardson@intel.com>
Weak functions don't work well with static libraries and require the use of
"whole-archive" flag to ensure that the correct function is used when
linking. Since the weak function is only used as a placeholder within this
library alone, we can replace it with a non-weak version protected using
preprocessor ifdefs.
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
lib/librte_bpf/bpf_load.c | 4 +++-
lib/librte_bpf/meson.build | 1 +
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/lib/librte_bpf/bpf_load.c b/lib/librte_bpf/bpf_load.c
index d9d163b7d..194103ec7 100644
--- a/lib/librte_bpf/bpf_load.c
+++ b/lib/librte_bpf/bpf_load.c
@@ -131,7 +131,8 @@ rte_bpf_load(const struct rte_bpf_prm *prm)
return bpf;
}
-__rte_experimental __rte_weak struct rte_bpf *
+#ifndef RTE_LIBRTE_BPF_ELF
+__rte_experimental struct rte_bpf *
rte_bpf_elf_load(const struct rte_bpf_prm *prm, const char *fname,
const char *sname)
{
@@ -146,3 +147,4 @@ rte_bpf_elf_load(const struct rte_bpf_prm *prm, const char *fname,
rte_errno = ENOTSUP;
return NULL;
}
+#endif
diff --git a/lib/librte_bpf/meson.build b/lib/librte_bpf/meson.build
index 8a79878ff..11c1fb558 100644
--- a/lib/librte_bpf/meson.build
+++ b/lib/librte_bpf/meson.build
@@ -20,6 +20,7 @@ deps += ['mbuf', 'net', 'ethdev']
dep = dependency('libelf', required: false)
if dep.found()
+ dpdk_conf.set('RTE_LIBRTE_BPF_ELF', 1)
sources += files('bpf_load_elf.c')
ext_deps += dep
endif
--
2.20.1
^ permalink raw reply related
* Re: [PATCH v8 2/2] media: cedrus: Add H264 decoding support
From: Paul Kocialkowski @ 2019-04-10 13:45 UTC (permalink / raw)
To: Maxime Ripard, hans.verkuil, acourbot, sakari.ailus,
Laurent Pinchart
Cc: Jernej Skrabec, jonas, jenskuske, linux-sunxi, linux-kernel,
jernej.skrabec, tfiga, Chen-Yu Tsai, posciak, Thomas Petazzoni,
nicolas.dufresne, ezequiel, linux-arm-kernel, linux-media
In-Reply-To: <157519b5571e24c9ef4189d30f8434b5b61121b1.1554382670.git-series.maxime.ripard@bootlin.com>
Hi,
Le jeudi 04 avril 2019 à 14:59 +0200, Maxime Ripard a écrit :
> Introduce some basic H264 decoding support in cedrus. So far, only the
> baseline profile videos have been tested, and some more advanced features
> used in higher profiles are not even implemented.
With the change to rename V4L2_PIX_FMT_H264_SLICE_RAW and make it
private, this is:
Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Cheers,
Paul
> Reviewed-by: Jernej Skrabec <jernej.skrabec@siol.net>
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
> drivers/staging/media/sunxi/cedrus/Makefile | 3 +-
> drivers/staging/media/sunxi/cedrus/cedrus.c | 31 +-
> drivers/staging/media/sunxi/cedrus/cedrus.h | 38 +-
> drivers/staging/media/sunxi/cedrus/cedrus_dec.c | 13 +-
> drivers/staging/media/sunxi/cedrus/cedrus_h264.c | 574 +++++++++++++++-
> drivers/staging/media/sunxi/cedrus/cedrus_hw.c | 4 +-
> drivers/staging/media/sunxi/cedrus/cedrus_regs.h | 91 ++-
> drivers/staging/media/sunxi/cedrus/cedrus_video.c | 9 +-
> 8 files changed, 761 insertions(+), 2 deletions(-)
> create mode 100644 drivers/staging/media/sunxi/cedrus/cedrus_h264.c
>
> diff --git a/drivers/staging/media/sunxi/cedrus/Makefile b/drivers/staging/media/sunxi/cedrus/Makefile
> index 808842f0119e..c85ac6db0302 100644
> --- a/drivers/staging/media/sunxi/cedrus/Makefile
> +++ b/drivers/staging/media/sunxi/cedrus/Makefile
> @@ -1,4 +1,5 @@
> # SPDX-License-Identifier: GPL-2.0
> obj-$(CONFIG_VIDEO_SUNXI_CEDRUS) += sunxi-cedrus.o
>
> -sunxi-cedrus-y = cedrus.o cedrus_video.o cedrus_hw.o cedrus_dec.o cedrus_mpeg2.o
> +sunxi-cedrus-y = cedrus.o cedrus_video.o cedrus_hw.o cedrus_dec.o \
> + cedrus_mpeg2.o cedrus_h264.o
> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
> index b98add3cdedd..d613f5c24a2f 100644
> --- a/drivers/staging/media/sunxi/cedrus/cedrus.c
> +++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
> @@ -40,6 +40,36 @@ static const struct cedrus_control cedrus_controls[] = {
> .codec = CEDRUS_CODEC_MPEG2,
> .required = false,
> },
> + {
> + .id = V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS,
> + .elem_size = sizeof(struct v4l2_ctrl_h264_decode_params),
> + .codec = CEDRUS_CODEC_H264,
> + .required = true,
> + },
> + {
> + .id = V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS,
> + .elem_size = sizeof(struct v4l2_ctrl_h264_slice_params),
> + .codec = CEDRUS_CODEC_H264,
> + .required = true,
> + },
> + {
> + .id = V4L2_CID_MPEG_VIDEO_H264_SPS,
> + .elem_size = sizeof(struct v4l2_ctrl_h264_sps),
> + .codec = CEDRUS_CODEC_H264,
> + .required = true,
> + },
> + {
> + .id = V4L2_CID_MPEG_VIDEO_H264_PPS,
> + .elem_size = sizeof(struct v4l2_ctrl_h264_pps),
> + .codec = CEDRUS_CODEC_H264,
> + .required = true,
> + },
> + {
> + .id = V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX,
> + .elem_size = sizeof(struct v4l2_ctrl_h264_scaling_matrix),
> + .codec = CEDRUS_CODEC_H264,
> + .required = true,
> + },
> };
>
> #define CEDRUS_CONTROLS_COUNT ARRAY_SIZE(cedrus_controls)
> @@ -278,6 +308,7 @@ static int cedrus_probe(struct platform_device *pdev)
> }
>
> dev->dec_ops[CEDRUS_CODEC_MPEG2] = &cedrus_dec_ops_mpeg2;
> + dev->dec_ops[CEDRUS_CODEC_H264] = &cedrus_dec_ops_h264;
>
> mutex_init(&dev->dev_mutex);
>
> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
> index c57c04b41d2e..bef79f630520 100644
> --- a/drivers/staging/media/sunxi/cedrus/cedrus.h
> +++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
> @@ -32,7 +32,7 @@
>
> enum cedrus_codec {
> CEDRUS_CODEC_MPEG2,
> -
> + CEDRUS_CODEC_H264,
> CEDRUS_CODEC_LAST,
> };
>
> @@ -42,6 +42,12 @@ enum cedrus_irq_status {
> CEDRUS_IRQ_OK,
> };
>
> +enum cedrus_h264_pic_type {
> + CEDRUS_H264_PIC_TYPE_FRAME = 0,
> + CEDRUS_H264_PIC_TYPE_FIELD,
> + CEDRUS_H264_PIC_TYPE_MBAFF,
> +};
> +
> struct cedrus_control {
> u32 id;
> u32 elem_size;
> @@ -49,6 +55,14 @@ struct cedrus_control {
> unsigned char required:1;
> };
>
> +struct cedrus_h264_run {
> + const struct v4l2_ctrl_h264_decode_params *decode_params;
> + const struct v4l2_ctrl_h264_pps *pps;
> + const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix;
> + const struct v4l2_ctrl_h264_slice_params *slice_params;
> + const struct v4l2_ctrl_h264_sps *sps;
> +};
> +
> struct cedrus_mpeg2_run {
> const struct v4l2_ctrl_mpeg2_slice_params *slice_params;
> const struct v4l2_ctrl_mpeg2_quantization *quantization;
> @@ -59,12 +73,20 @@ struct cedrus_run {
> struct vb2_v4l2_buffer *dst;
>
> union {
> + struct cedrus_h264_run h264;
> struct cedrus_mpeg2_run mpeg2;
> };
> };
>
> struct cedrus_buffer {
> struct v4l2_m2m_buffer m2m_buf;
> +
> + union {
> + struct {
> + unsigned int position;
> + enum cedrus_h264_pic_type pic_type;
> + } h264;
> + } codec;
> };
>
> struct cedrus_ctx {
> @@ -79,6 +101,19 @@ struct cedrus_ctx {
> struct v4l2_ctrl **ctrls;
>
> struct vb2_buffer *dst_bufs[VIDEO_MAX_FRAME];
> +
> + union {
> + struct {
> + void *mv_col_buf;
> + dma_addr_t mv_col_buf_dma;
> + ssize_t mv_col_buf_field_size;
> + ssize_t mv_col_buf_size;
> + void *pic_info_buf;
> + dma_addr_t pic_info_buf_dma;
> + void *neighbor_info_buf;
> + dma_addr_t neighbor_info_buf_dma;
> + } h264;
> + } codec;
> };
>
> struct cedrus_dec_ops {
> @@ -121,6 +156,7 @@ struct cedrus_dev {
> };
>
> extern struct cedrus_dec_ops cedrus_dec_ops_mpeg2;
> +extern struct cedrus_dec_ops cedrus_dec_ops_h264;
>
> static inline void cedrus_write(struct cedrus_dev *dev, u32 reg, u32 val)
> {
> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
> index 4d6d602cdde6..bdad87eb9d79 100644
> --- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
> +++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
> @@ -46,6 +46,19 @@ void cedrus_device_run(void *priv)
> V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION);
> break;
>
> + case V4L2_PIX_FMT_H264_SLICE_RAW:
> + run.h264.decode_params = cedrus_find_control_data(ctx,
> + V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS);
> + run.h264.pps = cedrus_find_control_data(ctx,
> + V4L2_CID_MPEG_VIDEO_H264_PPS);
> + run.h264.scaling_matrix = cedrus_find_control_data(ctx,
> + V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX);
> + run.h264.slice_params = cedrus_find_control_data(ctx,
> + V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS);
> + run.h264.sps = cedrus_find_control_data(ctx,
> + V4L2_CID_MPEG_VIDEO_H264_SPS);
> + break;
> +
> default:
> break;
> }
> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
> new file mode 100644
> index 000000000000..2c98a3e46d2b
> --- /dev/null
> +++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
> @@ -0,0 +1,574 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Cedrus VPU driver
> + *
> + * Copyright (c) 2013 Jens Kuske <jenskuske@gmail.com>
> + * Copyright (c) 2018 Bootlin
> + */
> +
> +#include <linux/types.h>
> +
> +#include <media/videobuf2-dma-contig.h>
> +
> +#include "cedrus.h"
> +#include "cedrus_hw.h"
> +#include "cedrus_regs.h"
> +
> +enum cedrus_h264_sram_off {
> + CEDRUS_SRAM_H264_PRED_WEIGHT_TABLE = 0x000,
> + CEDRUS_SRAM_H264_FRAMEBUFFER_LIST = 0x100,
> + CEDRUS_SRAM_H264_REF_LIST_0 = 0x190,
> + CEDRUS_SRAM_H264_REF_LIST_1 = 0x199,
> + CEDRUS_SRAM_H264_SCALING_LIST_8x8_0 = 0x200,
> + CEDRUS_SRAM_H264_SCALING_LIST_8x8_1 = 0x210,
> + CEDRUS_SRAM_H264_SCALING_LIST_4x4 = 0x220,
> +};
> +
> +struct cedrus_h264_sram_ref_pic {
> + __le32 top_field_order_cnt;
> + __le32 bottom_field_order_cnt;
> + __le32 frame_info;
> + __le32 luma_ptr;
> + __le32 chroma_ptr;
> + __le32 mv_col_top_ptr;
> + __le32 mv_col_bot_ptr;
> + __le32 reserved;
> +} __packed;
> +
> +#define CEDRUS_H264_FRAME_NUM 18
> +
> +#define CEDRUS_NEIGHBOR_INFO_BUF_SIZE (16 * SZ_1K)
> +#define CEDRUS_PIC_INFO_BUF_SIZE (128 * SZ_1K)
> +
> +static void cedrus_h264_write_sram(struct cedrus_dev *dev,
> + enum cedrus_h264_sram_off off,
> + const void *data, size_t len)
> +{
> + const u32 *buffer = data;
> + size_t count = DIV_ROUND_UP(len, 4);
> +
> + cedrus_write(dev, VE_AVC_SRAM_PORT_OFFSET, off << 2);
> +
> + while (count--)
> + cedrus_write(dev, VE_AVC_SRAM_PORT_DATA, *buffer++);
> +}
> +
> +static dma_addr_t cedrus_h264_mv_col_buf_addr(struct cedrus_ctx *ctx,
> + unsigned int position,
> + unsigned int field)
> +{
> + dma_addr_t addr = ctx->codec.h264.mv_col_buf_dma;
> +
> + /* Adjust for the position */
> + addr += position * ctx->codec.h264.mv_col_buf_field_size * 2;
> +
> + /* Adjust for the field */
> + addr += field * ctx->codec.h264.mv_col_buf_field_size;
> +
> + return addr;
> +}
> +
> +static void cedrus_fill_ref_pic(struct cedrus_ctx *ctx,
> + struct cedrus_buffer *buf,
> + unsigned int top_field_order_cnt,
> + unsigned int bottom_field_order_cnt,
> + struct cedrus_h264_sram_ref_pic *pic)
> +{
> + struct vb2_buffer *vbuf = &buf->m2m_buf.vb.vb2_buf;
> + unsigned int position = buf->codec.h264.position;
> +
> + pic->top_field_order_cnt = top_field_order_cnt;
> + pic->bottom_field_order_cnt = bottom_field_order_cnt;
> + pic->frame_info = buf->codec.h264.pic_type << 8;
> +
> + pic->luma_ptr = cedrus_buf_addr(vbuf, &ctx->dst_fmt, 0);
> + pic->chroma_ptr = cedrus_buf_addr(vbuf, &ctx->dst_fmt, 1);
> + pic->mv_col_top_ptr = cedrus_h264_mv_col_buf_addr(ctx, position, 0);
> + pic->mv_col_bot_ptr = cedrus_h264_mv_col_buf_addr(ctx, position, 1);
> +}
> +
> +static void cedrus_write_frame_list(struct cedrus_ctx *ctx,
> + struct cedrus_run *run)
> +{
> + struct cedrus_h264_sram_ref_pic pic_list[CEDRUS_H264_FRAME_NUM];
> + const struct v4l2_ctrl_h264_decode_params *decode = run->h264.decode_params;
> + const struct v4l2_ctrl_h264_slice_params *slice = run->h264.slice_params;
> + const struct v4l2_ctrl_h264_sps *sps = run->h264.sps;
> + struct vb2_queue *cap_q = &ctx->fh.m2m_ctx->cap_q_ctx.q;
> + struct cedrus_buffer *output_buf;
> + struct cedrus_dev *dev = ctx->dev;
> + unsigned long used_dpbs = 0;
> + unsigned int position;
> + unsigned int output = 0;
> + unsigned int i;
> +
> + memset(pic_list, 0, sizeof(pic_list));
> +
> + for (i = 0; i < ARRAY_SIZE(decode->dpb); i++) {
> + const struct v4l2_h264_dpb_entry *dpb = &decode->dpb[i];
> + struct cedrus_buffer *cedrus_buf;
> + int buf_idx;
> +
> + if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_VALID))
> + continue;
> +
> + buf_idx = vb2_find_timestamp(cap_q, dpb->reference_ts, 0);
> + if (buf_idx < 0)
> + continue;
> +
> + cedrus_buf = vb2_to_cedrus_buffer(ctx->dst_bufs[buf_idx]);
> + position = cedrus_buf->codec.h264.position;
> + used_dpbs |= BIT(position);
> +
> + if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
> + continue;
> +
> + cedrus_fill_ref_pic(ctx, cedrus_buf,
> + dpb->top_field_order_cnt,
> + dpb->bottom_field_order_cnt,
> + &pic_list[position]);
> +
> + output = max(position, output);
> + }
> +
> + position = find_next_zero_bit(&used_dpbs, CEDRUS_H264_FRAME_NUM,
> + output);
> + if (position >= CEDRUS_H264_FRAME_NUM)
> + position = find_first_zero_bit(&used_dpbs, CEDRUS_H264_FRAME_NUM);
> +
> + output_buf = vb2_to_cedrus_buffer(&run->dst->vb2_buf);
> + output_buf->codec.h264.position = position;
> +
> + if (slice->flags & V4L2_H264_SLICE_FLAG_FIELD_PIC)
> + output_buf->codec.h264.pic_type = CEDRUS_H264_PIC_TYPE_FIELD;
> + else if (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD)
> + output_buf->codec.h264.pic_type = CEDRUS_H264_PIC_TYPE_MBAFF;
> + else
> + output_buf->codec.h264.pic_type = CEDRUS_H264_PIC_TYPE_FRAME;
> +
> + cedrus_fill_ref_pic(ctx, output_buf,
> + decode->top_field_order_cnt,
> + decode->bottom_field_order_cnt,
> + &pic_list[position]);
> +
> + cedrus_h264_write_sram(dev, CEDRUS_SRAM_H264_FRAMEBUFFER_LIST,
> + pic_list, sizeof(pic_list));
> +
> + cedrus_write(dev, VE_H264_OUTPUT_FRAME_IDX, position);
> +}
> +
> +#define CEDRUS_MAX_REF_IDX 32
> +
> +static void _cedrus_write_ref_list(struct cedrus_ctx *ctx,
> + struct cedrus_run *run,
> + const u8 *ref_list, u8 num_ref,
> + enum cedrus_h264_sram_off sram)
> +{
> + const struct v4l2_ctrl_h264_decode_params *decode = run->h264.decode_params;
> + struct vb2_queue *cap_q = &ctx->fh.m2m_ctx->cap_q_ctx.q;
> + struct cedrus_dev *dev = ctx->dev;
> + u8 sram_array[CEDRUS_MAX_REF_IDX];
> + unsigned int i;
> + size_t size;
> +
> + memset(sram_array, 0, sizeof(sram_array));
> +
> + for (i = 0; i < num_ref; i++) {
> + const struct v4l2_h264_dpb_entry *dpb;
> + const struct cedrus_buffer *cedrus_buf;
> + const struct vb2_v4l2_buffer *ref_buf;
> + unsigned int position;
> + int buf_idx;
> + u8 dpb_idx;
> +
> + dpb_idx = ref_list[i];
> + dpb = &decode->dpb[dpb_idx];
> +
> + if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
> + continue;
> +
> + buf_idx = vb2_find_timestamp(cap_q, dpb->reference_ts, 0);
> + if (buf_idx < 0)
> + continue;
> +
> + ref_buf = to_vb2_v4l2_buffer(ctx->dst_bufs[buf_idx]);
> + cedrus_buf = vb2_v4l2_to_cedrus_buffer(ref_buf);
> + position = cedrus_buf->codec.h264.position;
> +
> + sram_array[i] |= position << 1;
> + if (ref_buf->field == V4L2_FIELD_BOTTOM)
> + sram_array[i] |= BIT(0);
> + }
> +
> + size = min_t(size_t, ALIGN(num_ref, 4), sizeof(sram_array));
> + cedrus_h264_write_sram(dev, sram, &sram_array, size);
> +}
> +
> +static void cedrus_write_ref_list0(struct cedrus_ctx *ctx,
> + struct cedrus_run *run)
> +{
> + const struct v4l2_ctrl_h264_slice_params *slice = run->h264.slice_params;
> +
> + _cedrus_write_ref_list(ctx, run,
> + slice->ref_pic_list0,
> + slice->num_ref_idx_l0_active_minus1 + 1,
> + CEDRUS_SRAM_H264_REF_LIST_0);
> +}
> +
> +static void cedrus_write_ref_list1(struct cedrus_ctx *ctx,
> + struct cedrus_run *run)
> +{
> + const struct v4l2_ctrl_h264_slice_params *slice = run->h264.slice_params;
> +
> + _cedrus_write_ref_list(ctx, run,
> + slice->ref_pic_list1,
> + slice->num_ref_idx_l1_active_minus1 + 1,
> + CEDRUS_SRAM_H264_REF_LIST_1);
> +}
> +
> +static void cedrus_write_scaling_lists(struct cedrus_ctx *ctx,
> + struct cedrus_run *run)
> +{
> + const struct v4l2_ctrl_h264_scaling_matrix *scaling =
> + run->h264.scaling_matrix;
> + struct cedrus_dev *dev = ctx->dev;
> +
> + cedrus_h264_write_sram(dev, CEDRUS_SRAM_H264_SCALING_LIST_8x8_0,
> + scaling->scaling_list_8x8[0],
> + sizeof(scaling->scaling_list_8x8[0]));
> +
> + cedrus_h264_write_sram(dev, CEDRUS_SRAM_H264_SCALING_LIST_8x8_1,
> + scaling->scaling_list_8x8[3],
> + sizeof(scaling->scaling_list_8x8[3]));
> +
> + cedrus_h264_write_sram(dev, CEDRUS_SRAM_H264_SCALING_LIST_4x4,
> + scaling->scaling_list_4x4,
> + sizeof(scaling->scaling_list_4x4));
> +}
> +
> +static void cedrus_write_pred_weight_table(struct cedrus_ctx *ctx,
> + struct cedrus_run *run)
> +{
> + const struct v4l2_ctrl_h264_slice_params *slice =
> + run->h264.slice_params;
> + const struct v4l2_h264_pred_weight_table *pred_weight =
> + &slice->pred_weight_table;
> + struct cedrus_dev *dev = ctx->dev;
> + int i, j, k;
> +
> + cedrus_write(dev, VE_H264_SHS_WP,
> + ((pred_weight->chroma_log2_weight_denom & 0x7) << 4) |
> + ((pred_weight->luma_log2_weight_denom & 0x7) << 0));
> +
> + cedrus_write(dev, VE_AVC_SRAM_PORT_OFFSET,
> + CEDRUS_SRAM_H264_PRED_WEIGHT_TABLE << 2);
> +
> + for (i = 0; i < ARRAY_SIZE(pred_weight->weight_factors); i++) {
> + const struct v4l2_h264_weight_factors *factors =
> + &pred_weight->weight_factors[i];
> +
> + for (j = 0; j < ARRAY_SIZE(factors->luma_weight); j++) {
> + u32 val;
> +
> + val = (((u32)factors->luma_offset[j] & 0x1ff) << 16) |
> + (factors->luma_weight[j] & 0x1ff);
> + cedrus_write(dev, VE_AVC_SRAM_PORT_DATA, val);
> + }
> +
> + for (j = 0; j < ARRAY_SIZE(factors->chroma_weight); j++) {
> + for (k = 0; k < ARRAY_SIZE(factors->chroma_weight[0]); k++) {
> + u32 val;
> +
> + val = (((u32)factors->chroma_offset[j][k] & 0x1ff) << 16) |
> + (factors->chroma_weight[j][k] & 0x1ff);
> + cedrus_write(dev, VE_AVC_SRAM_PORT_DATA, val);
> + }
> + }
> + }
> +}
> +
> +static void cedrus_set_params(struct cedrus_ctx *ctx,
> + struct cedrus_run *run)
> +{
> + const struct v4l2_ctrl_h264_decode_params *decode = run->h264.decode_params;
> + const struct v4l2_ctrl_h264_slice_params *slice = run->h264.slice_params;
> + const struct v4l2_ctrl_h264_pps *pps = run->h264.pps;
> + const struct v4l2_ctrl_h264_sps *sps = run->h264.sps;
> + struct vb2_buffer *src_buf = &run->src->vb2_buf;
> + struct cedrus_dev *dev = ctx->dev;
> + dma_addr_t src_buf_addr;
> + u32 offset = slice->header_bit_size;
> + u32 len = (slice->size * 8) - offset;
> + u32 reg;
> +
> + cedrus_write(dev, VE_H264_VLD_LEN, len);
> + cedrus_write(dev, VE_H264_VLD_OFFSET, offset);
> +
> + src_buf_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
> + cedrus_write(dev, VE_H264_VLD_END,
> + src_buf_addr + vb2_get_plane_payload(src_buf, 0));
> + cedrus_write(dev, VE_H264_VLD_ADDR,
> + VE_H264_VLD_ADDR_VAL(src_buf_addr) |
> + VE_H264_VLD_ADDR_FIRST | VE_H264_VLD_ADDR_VALID |
> + VE_H264_VLD_ADDR_LAST);
> +
> + /*
> + * FIXME: Since the bitstream parsing is done in software, and
> + * in userspace, this shouldn't be needed anymore. But it
> + * turns out that removing it breaks the decoding process,
> + * without any clear indication why.
> + */
> + cedrus_write(dev, VE_H264_TRIGGER_TYPE,
> + VE_H264_TRIGGER_TYPE_INIT_SWDEC);
> +
> + if (((pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED) &&
> + (slice->slice_type == V4L2_H264_SLICE_TYPE_P ||
> + slice->slice_type == V4L2_H264_SLICE_TYPE_SP)) ||
> + (pps->weighted_bipred_idc == 1 &&
> + slice->slice_type == V4L2_H264_SLICE_TYPE_B))
> + cedrus_write_pred_weight_table(ctx, run);
> +
> + if ((slice->slice_type == V4L2_H264_SLICE_TYPE_P) ||
> + (slice->slice_type == V4L2_H264_SLICE_TYPE_SP) ||
> + (slice->slice_type == V4L2_H264_SLICE_TYPE_B))
> + cedrus_write_ref_list0(ctx, run);
> +
> + if (slice->slice_type == V4L2_H264_SLICE_TYPE_B)
> + cedrus_write_ref_list1(ctx, run);
> +
> + // picture parameters
> + reg = 0;
> + /*
> + * FIXME: the kernel headers are allowing the default value to
> + * be passed, but the libva doesn't give us that.
> + */
> + reg |= (slice->num_ref_idx_l0_active_minus1 & 0x1f) << 10;
> + reg |= (slice->num_ref_idx_l1_active_minus1 & 0x1f) << 5;
> + reg |= (pps->weighted_bipred_idc & 0x3) << 2;
> + if (pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE)
> + reg |= VE_H264_PPS_ENTROPY_CODING_MODE;
> + if (pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED)
> + reg |= VE_H264_PPS_WEIGHTED_PRED;
> + if (pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED)
> + reg |= VE_H264_PPS_CONSTRAINED_INTRA_PRED;
> + if (pps->flags & V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE)
> + reg |= VE_H264_PPS_TRANSFORM_8X8_MODE;
> + cedrus_write(dev, VE_H264_PPS, reg);
> +
> + // sequence parameters
> + reg = 0;
> + reg |= (sps->chroma_format_idc & 0x7) << 19;
> + reg |= (sps->pic_width_in_mbs_minus1 & 0xff) << 8;
> + reg |= sps->pic_height_in_map_units_minus1 & 0xff;
> + if (sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY)
> + reg |= VE_H264_SPS_MBS_ONLY;
> + if (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD)
> + reg |= VE_H264_SPS_MB_ADAPTIVE_FRAME_FIELD;
> + if (sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE)
> + reg |= VE_H264_SPS_DIRECT_8X8_INFERENCE;
> + cedrus_write(dev, VE_H264_SPS, reg);
> +
> + // slice parameters
> + reg = 0;
> + reg |= decode->nal_ref_idc ? BIT(12) : 0;
> + reg |= (slice->slice_type & 0xf) << 8;
> + reg |= slice->cabac_init_idc & 0x3;
> + reg |= VE_H264_SHS_FIRST_SLICE_IN_PIC;
> + if (slice->flags & V4L2_H264_SLICE_FLAG_FIELD_PIC)
> + reg |= VE_H264_SHS_FIELD_PIC;
> + if (slice->flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD)
> + reg |= VE_H264_SHS_BOTTOM_FIELD;
> + if (slice->flags & V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED)
> + reg |= VE_H264_SHS_DIRECT_SPATIAL_MV_PRED;
> + cedrus_write(dev, VE_H264_SHS, reg);
> +
> + reg = 0;
> + reg |= VE_H264_SHS2_NUM_REF_IDX_ACTIVE_OVRD;
> + reg |= (slice->num_ref_idx_l0_active_minus1 & 0x1f) << 24;
> + reg |= (slice->num_ref_idx_l1_active_minus1 & 0x1f) << 16;
> + reg |= (slice->disable_deblocking_filter_idc & 0x3) << 8;
> + reg |= (slice->slice_alpha_c0_offset_div2 & 0xf) << 4;
> + reg |= slice->slice_beta_offset_div2 & 0xf;
> + cedrus_write(dev, VE_H264_SHS2, reg);
> +
> + reg = 0;
> + reg |= (pps->second_chroma_qp_index_offset & 0x3f) << 16;
> + reg |= (pps->chroma_qp_index_offset & 0x3f) << 8;
> + reg |= (pps->pic_init_qp_minus26 + 26 + slice->slice_qp_delta) & 0x3f;
> + cedrus_write(dev, VE_H264_SHS_QP, reg);
> +
> + // clear status flags
> + cedrus_write(dev, VE_H264_STATUS, cedrus_read(dev, VE_H264_STATUS));
> +
> + // enable int
> + cedrus_write(dev, VE_H264_CTRL,
> + VE_H264_CTRL_SLICE_DECODE_INT |
> + VE_H264_CTRL_DECODE_ERR_INT |
> + VE_H264_CTRL_VLD_DATA_REQ_INT);
> +}
> +
> +static enum cedrus_irq_status
> +cedrus_h264_irq_status(struct cedrus_ctx *ctx)
> +{
> + struct cedrus_dev *dev = ctx->dev;
> + u32 reg = cedrus_read(dev, VE_H264_STATUS);
> +
> + if (reg & (VE_H264_STATUS_DECODE_ERR_INT |
> + VE_H264_STATUS_VLD_DATA_REQ_INT))
> + return CEDRUS_IRQ_ERROR;
> +
> + if (reg & VE_H264_CTRL_SLICE_DECODE_INT)
> + return CEDRUS_IRQ_OK;
> +
> + return CEDRUS_IRQ_NONE;
> +}
> +
> +static void cedrus_h264_irq_clear(struct cedrus_ctx *ctx)
> +{
> + struct cedrus_dev *dev = ctx->dev;
> +
> + cedrus_write(dev, VE_H264_STATUS,
> + VE_H264_STATUS_INT_MASK);
> +}
> +
> +static void cedrus_h264_irq_disable(struct cedrus_ctx *ctx)
> +{
> + struct cedrus_dev *dev = ctx->dev;
> + u32 reg = cedrus_read(dev, VE_H264_CTRL);
> +
> + cedrus_write(dev, VE_H264_CTRL,
> + reg & ~VE_H264_CTRL_INT_MASK);
> +}
> +
> +static void cedrus_h264_setup(struct cedrus_ctx *ctx,
> + struct cedrus_run *run)
> +{
> + struct cedrus_dev *dev = ctx->dev;
> +
> + cedrus_engine_enable(dev, CEDRUS_CODEC_H264);
> +
> + cedrus_write(dev, VE_H264_SDROT_CTRL, 0);
> + cedrus_write(dev, VE_H264_EXTRA_BUFFER1,
> + ctx->codec.h264.pic_info_buf_dma);
> + cedrus_write(dev, VE_H264_EXTRA_BUFFER2,
> + ctx->codec.h264.neighbor_info_buf_dma);
> +
> + cedrus_write_scaling_lists(ctx, run);
> + cedrus_write_frame_list(ctx, run);
> +
> + cedrus_set_params(ctx, run);
> +}
> +
> +static int cedrus_h264_start(struct cedrus_ctx *ctx)
> +{
> + struct cedrus_dev *dev = ctx->dev;
> + unsigned int field_size;
> + unsigned int mv_col_size;
> + int ret;
> +
> + /*
> + * FIXME: It seems that the H6 cedarX code is using a formula
> + * here based on the size of the frame, while all the older
> + * code is using a fixed size, so that might need to be
> + * changed at some point.
> + */
> + ctx->codec.h264.pic_info_buf =
> + dma_alloc_coherent(dev->dev, CEDRUS_PIC_INFO_BUF_SIZE,
> + &ctx->codec.h264.pic_info_buf_dma,
> + GFP_KERNEL);
> + if (!ctx->codec.h264.pic_info_buf)
> + return -ENOMEM;
> +
> + /*
> + * That buffer is supposed to be 16kiB in size, and be aligned
> + * on 16kiB as well. However, dma_alloc_coherent provides the
> + * guarantee that we'll have a CPU and DMA address aligned on
> + * the smallest page order that is greater to the requested
> + * size, so we don't have to overallocate.
> + */
> + ctx->codec.h264.neighbor_info_buf =
> + dma_alloc_coherent(dev->dev, CEDRUS_NEIGHBOR_INFO_BUF_SIZE,
> + &ctx->codec.h264.neighbor_info_buf_dma,
> + GFP_KERNEL);
> + if (!ctx->codec.h264.neighbor_info_buf) {
> + ret = -ENOMEM;
> + goto err_pic_buf;
> + }
> +
> + field_size = DIV_ROUND_UP(ctx->src_fmt.width, 16) *
> + DIV_ROUND_UP(ctx->src_fmt.height, 16) * 16;
> +
> + /*
> + * FIXME: This is actually conditional to
> + * V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE not being set, we
> + * might have to rework this if memory efficiency ever is
> + * something we need to work on.
> + */
> + field_size = field_size * 2;
> +
> + /*
> + * FIXME: This is actually conditional to
> + * V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY not being set, we might
> + * have to rework this if memory efficiency ever is something
> + * we need to work on.
> + */
> + field_size = field_size * 2;
> + ctx->codec.h264.mv_col_buf_field_size = field_size;
> +
> + mv_col_size = field_size * 2 * CEDRUS_H264_FRAME_NUM;
> + ctx->codec.h264.mv_col_buf_size = mv_col_size;
> + ctx->codec.h264.mv_col_buf = dma_alloc_coherent(dev->dev,
> + ctx->codec.h264.mv_col_buf_size,
> + &ctx->codec.h264.mv_col_buf_dma,
> + GFP_KERNEL);
> + if (!ctx->codec.h264.mv_col_buf) {
> + ret = -ENOMEM;
> + goto err_neighbor_buf;
> + }
> +
> + return 0;
> +
> +err_neighbor_buf:
> + dma_free_coherent(dev->dev, CEDRUS_NEIGHBOR_INFO_BUF_SIZE,
> + ctx->codec.h264.neighbor_info_buf,
> + ctx->codec.h264.neighbor_info_buf_dma);
> +
> +err_pic_buf:
> + dma_free_coherent(dev->dev, CEDRUS_PIC_INFO_BUF_SIZE,
> + ctx->codec.h264.pic_info_buf,
> + ctx->codec.h264.pic_info_buf_dma);
> + return ret;
> +}
> +
> +static void cedrus_h264_stop(struct cedrus_ctx *ctx)
> +{
> + struct cedrus_dev *dev = ctx->dev;
> +
> + dma_free_coherent(dev->dev, ctx->codec.h264.mv_col_buf_size,
> + ctx->codec.h264.mv_col_buf,
> + ctx->codec.h264.mv_col_buf_dma);
> + dma_free_coherent(dev->dev, CEDRUS_NEIGHBOR_INFO_BUF_SIZE,
> + ctx->codec.h264.neighbor_info_buf,
> + ctx->codec.h264.neighbor_info_buf_dma);
> + dma_free_coherent(dev->dev, CEDRUS_PIC_INFO_BUF_SIZE,
> + ctx->codec.h264.pic_info_buf,
> + ctx->codec.h264.pic_info_buf_dma);
> +}
> +
> +static void cedrus_h264_trigger(struct cedrus_ctx *ctx)
> +{
> + struct cedrus_dev *dev = ctx->dev;
> +
> + cedrus_write(dev, VE_H264_TRIGGER_TYPE,
> + VE_H264_TRIGGER_TYPE_AVC_SLICE_DECODE);
> +}
> +
> +struct cedrus_dec_ops cedrus_dec_ops_h264 = {
> + .irq_clear = cedrus_h264_irq_clear,
> + .irq_disable = cedrus_h264_irq_disable,
> + .irq_status = cedrus_h264_irq_status,
> + .setup = cedrus_h264_setup,
> + .start = cedrus_h264_start,
> + .stop = cedrus_h264_stop,
> + .trigger = cedrus_h264_trigger,
> +};
> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
> index fbfff7c1c771..748f7f673547 100644
> --- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
> +++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
> @@ -46,6 +46,10 @@ int cedrus_engine_enable(struct cedrus_dev *dev, enum cedrus_codec codec)
> reg |= VE_MODE_DEC_MPEG;
> break;
>
> + case CEDRUS_CODEC_H264:
> + reg |= VE_MODE_DEC_H264;
> + break;
> +
> default:
> return -EINVAL;
> }
> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
> index de2d6b6f64bf..3e9931416e45 100644
> --- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
> +++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
> @@ -232,4 +232,95 @@
> #define VE_DEC_MPEG_ROT_LUMA (VE_ENGINE_DEC_MPEG + 0xcc)
> #define VE_DEC_MPEG_ROT_CHROMA (VE_ENGINE_DEC_MPEG + 0xd0)
>
> +#define VE_H264_SPS 0x200
> +#define VE_H264_SPS_MBS_ONLY BIT(18)
> +#define VE_H264_SPS_MB_ADAPTIVE_FRAME_FIELD BIT(17)
> +#define VE_H264_SPS_DIRECT_8X8_INFERENCE BIT(16)
> +
> +#define VE_H264_PPS 0x204
> +#define VE_H264_PPS_ENTROPY_CODING_MODE BIT(15)
> +#define VE_H264_PPS_WEIGHTED_PRED BIT(4)
> +#define VE_H264_PPS_CONSTRAINED_INTRA_PRED BIT(1)
> +#define VE_H264_PPS_TRANSFORM_8X8_MODE BIT(0)
> +
> +#define VE_H264_SHS 0x208
> +#define VE_H264_SHS_FIRST_SLICE_IN_PIC BIT(5)
> +#define VE_H264_SHS_FIELD_PIC BIT(4)
> +#define VE_H264_SHS_BOTTOM_FIELD BIT(3)
> +#define VE_H264_SHS_DIRECT_SPATIAL_MV_PRED BIT(2)
> +
> +#define VE_H264_SHS2 0x20c
> +#define VE_H264_SHS2_NUM_REF_IDX_ACTIVE_OVRD BIT(12)
> +
> +#define VE_H264_SHS_WP 0x210
> +
> +#define VE_H264_SHS_QP 0x21c
> +#define VE_H264_SHS_QP_SCALING_MATRIX_DEFAULT BIT(24)
> +
> +#define VE_H264_CTRL 0x220
> +#define VE_H264_CTRL_VLD_DATA_REQ_INT BIT(2)
> +#define VE_H264_CTRL_DECODE_ERR_INT BIT(1)
> +#define VE_H264_CTRL_SLICE_DECODE_INT BIT(0)
> +
> +#define VE_H264_CTRL_INT_MASK (VE_H264_CTRL_VLD_DATA_REQ_INT | \
> + VE_H264_CTRL_DECODE_ERR_INT | \
> + VE_H264_CTRL_SLICE_DECODE_INT)
> +
> +#define VE_H264_TRIGGER_TYPE 0x224
> +#define VE_H264_TRIGGER_TYPE_AVC_SLICE_DECODE (8 << 0)
> +#define VE_H264_TRIGGER_TYPE_INIT_SWDEC (7 << 0)
> +
> +#define VE_H264_STATUS 0x228
> +#define VE_H264_STATUS_VLD_DATA_REQ_INT VE_H264_CTRL_VLD_DATA_REQ_INT
> +#define VE_H264_STATUS_DECODE_ERR_INT VE_H264_CTRL_DECODE_ERR_INT
> +#define VE_H264_STATUS_SLICE_DECODE_INT VE_H264_CTRL_SLICE_DECODE_INT
> +
> +#define VE_H264_STATUS_INT_MASK VE_H264_CTRL_INT_MASK
> +
> +#define VE_H264_CUR_MB_NUM 0x22c
> +
> +#define VE_H264_VLD_ADDR 0x230
> +#define VE_H264_VLD_ADDR_FIRST BIT(30)
> +#define VE_H264_VLD_ADDR_LAST BIT(29)
> +#define VE_H264_VLD_ADDR_VALID BIT(28)
> +#define VE_H264_VLD_ADDR_VAL(x) (((x) & 0x0ffffff0) | ((x) >> 28))
> +
> +#define VE_H264_VLD_OFFSET 0x234
> +#define VE_H264_VLD_LEN 0x238
> +#define VE_H264_VLD_END 0x23c
> +#define VE_H264_SDROT_CTRL 0x240
> +#define VE_H264_OUTPUT_FRAME_IDX 0x24c
> +#define VE_H264_EXTRA_BUFFER1 0x250
> +#define VE_H264_EXTRA_BUFFER2 0x254
> +#define VE_H264_BASIC_BITS 0x2dc
> +#define VE_AVC_SRAM_PORT_OFFSET 0x2e0
> +#define VE_AVC_SRAM_PORT_DATA 0x2e4
> +
> +#define VE_ISP_INPUT_SIZE 0xa00
> +#define VE_ISP_INPUT_STRIDE 0xa04
> +#define VE_ISP_CTRL 0xa08
> +#define VE_ISP_INPUT_LUMA 0xa78
> +#define VE_ISP_INPUT_CHROMA 0xa7c
> +
> +#define VE_AVC_PARAM 0xb04
> +#define VE_AVC_QP 0xb08
> +#define VE_AVC_MOTION_EST 0xb10
> +#define VE_AVC_CTRL 0xb14
> +#define VE_AVC_TRIGGER 0xb18
> +#define VE_AVC_STATUS 0xb1c
> +#define VE_AVC_BASIC_BITS 0xb20
> +#define VE_AVC_UNK_BUF 0xb60
> +#define VE_AVC_VLE_ADDR 0xb80
> +#define VE_AVC_VLE_END 0xb84
> +#define VE_AVC_VLE_OFFSET 0xb88
> +#define VE_AVC_VLE_MAX 0xb8c
> +#define VE_AVC_VLE_LENGTH 0xb90
> +#define VE_AVC_REF_LUMA 0xba0
> +#define VE_AVC_REF_CHROMA 0xba4
> +#define VE_AVC_REC_LUMA 0xbb0
> +#define VE_AVC_REC_CHROMA 0xbb4
> +#define VE_AVC_REF_SLUMA 0xbb8
> +#define VE_AVC_REC_SLUMA 0xbbc
> +#define VE_AVC_MB_INFO 0xbc0
> +
> #endif
> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
> index 9673874ece10..e2b530b1a956 100644
> --- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
> +++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
> @@ -38,6 +38,10 @@ static struct cedrus_format cedrus_formats[] = {
> .directions = CEDRUS_DECODE_SRC,
> },
> {
> + .pixelformat = V4L2_PIX_FMT_H264_SLICE_RAW,
> + .directions = CEDRUS_DECODE_SRC,
> + },
> + {
> .pixelformat = V4L2_PIX_FMT_SUNXI_TILED_NV12,
> .directions = CEDRUS_DECODE_DST,
> },
> @@ -100,6 +104,7 @@ static void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt)
>
> switch (pix_fmt->pixelformat) {
> case V4L2_PIX_FMT_MPEG2_SLICE:
> + case V4L2_PIX_FMT_H264_SLICE_RAW:
> /* Zero bytes per line for encoded source. */
> bytesperline = 0;
>
> @@ -464,6 +469,10 @@ static int cedrus_start_streaming(struct vb2_queue *vq, unsigned int count)
> ctx->current_codec = CEDRUS_CODEC_MPEG2;
> break;
>
> + case V4L2_PIX_FMT_H264_SLICE_RAW:
> + ctx->current_codec = CEDRUS_CODEC_H264;
> + break;
> +
> default:
> return -EINVAL;
> }
--
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [dpdk-dev] [PATCH 1/2] acl: remove use of weak functions
From: Bruce Richardson @ 2019-04-10 13:45 UTC (permalink / raw)
To: konstantin.ananyev, aconole; +Cc: dev, Bruce Richardson
In-Reply-To: <20190410134517.63896-1-bruce.richardson@intel.com>
Weak functions don't work well with static libraries and require the use of
"whole-archive" flag to ensure that the correct function is used when
linking. Since the weak functions are only used as placeholders within
this library alone, we can replace them with non-weak functions using
preprocessor ifdefs.
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
lib/librte_acl/meson.build | 7 ++++++-
lib/librte_acl/rte_acl.c | 18 ++++++++++++++----
mk/rte.app.mk | 3 ---
3 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/lib/librte_acl/meson.build b/lib/librte_acl/meson.build
index 2207dbafe..98ece7d85 100644
--- a/lib/librte_acl/meson.build
+++ b/lib/librte_acl/meson.build
@@ -6,7 +6,7 @@ sources = files('acl_bld.c', 'acl_gen.c', 'acl_run_scalar.c',
'rte_acl.c', 'tb_mem.c')
headers = files('rte_acl.h', 'rte_acl_osdep.h')
-if arch_subdir == 'x86'
+if dpdk_conf.has('RTE_ARCH_X86')
sources += files('acl_run_sse.c')
# compile AVX2 version if either:
@@ -28,4 +28,9 @@ if arch_subdir == 'x86'
cflags += '-DCC_AVX2_SUPPORT'
endif
+elif dpdk_conf.has('RTE_ARCH_ARM') or dpdk_conf.has('RTE_ARCH_ARM64')
+ cflags += '-flax-vector-conversions'
+ sources += files('acl_run_neon.c')
+elif dpdk_conf.has('RTE_ARCH_PPC_64')
+ sources += files('acl_run_altivec.c')
endif
diff --git a/lib/librte_acl/rte_acl.c b/lib/librte_acl/rte_acl.c
index c436a9bfd..fd5bd5e4e 100644
--- a/lib/librte_acl/rte_acl.c
+++ b/lib/librte_acl/rte_acl.c
@@ -13,11 +13,13 @@ static struct rte_tailq_elem rte_acl_tailq = {
};
EAL_REGISTER_TAILQ(rte_acl_tailq)
+#ifndef RTE_ARCH_X86
+#ifndef CC_AVX2_SUPPORT
/*
* If the compiler doesn't support AVX2 instructions,
* then the dummy one would be used instead for AVX2 classify method.
*/
-__rte_weak int
+int
rte_acl_classify_avx2(__rte_unused const struct rte_acl_ctx *ctx,
__rte_unused const uint8_t **data,
__rte_unused uint32_t *results,
@@ -26,8 +28,9 @@ rte_acl_classify_avx2(__rte_unused const struct rte_acl_ctx *ctx,
{
return -ENOTSUP;
}
+#endif
-__rte_weak int
+int
rte_acl_classify_sse(__rte_unused const struct rte_acl_ctx *ctx,
__rte_unused const uint8_t **data,
__rte_unused uint32_t *results,
@@ -36,8 +39,11 @@ rte_acl_classify_sse(__rte_unused const struct rte_acl_ctx *ctx,
{
return -ENOTSUP;
}
+#endif
-__rte_weak int
+#ifndef RTE_ARCH_ARM
+#ifndef RTE_ARCH_ARM64
+int
rte_acl_classify_neon(__rte_unused const struct rte_acl_ctx *ctx,
__rte_unused const uint8_t **data,
__rte_unused uint32_t *results,
@@ -46,8 +52,11 @@ rte_acl_classify_neon(__rte_unused const struct rte_acl_ctx *ctx,
{
return -ENOTSUP;
}
+#endif
+#endif
-__rte_weak int
+#ifndef RTE_ARCH_PPC_64
+int
rte_acl_classify_altivec(__rte_unused const struct rte_acl_ctx *ctx,
__rte_unused const uint8_t **data,
__rte_unused uint32_t *results,
@@ -56,6 +65,7 @@ rte_acl_classify_altivec(__rte_unused const struct rte_acl_ctx *ctx,
{
return -ENOTSUP;
}
+#endif
static const rte_acl_classify_t classify_fns[] = {
[RTE_ACL_CLASSIFY_DEFAULT] = rte_acl_classify_scalar,
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 7d994bece..fdec636b4 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -46,10 +46,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR) += -lrte_distributor
_LDLIBS-$(CONFIG_RTE_LIBRTE_IP_FRAG) += -lrte_ip_frag
_LDLIBS-$(CONFIG_RTE_LIBRTE_METER) += -lrte_meter
_LDLIBS-$(CONFIG_RTE_LIBRTE_LPM) += -lrte_lpm
-# librte_acl needs --whole-archive because of weak functions
-_LDLIBS-$(CONFIG_RTE_LIBRTE_ACL) += --whole-archive
_LDLIBS-$(CONFIG_RTE_LIBRTE_ACL) += -lrte_acl
-_LDLIBS-$(CONFIG_RTE_LIBRTE_ACL) += --no-whole-archive
_LDLIBS-$(CONFIG_RTE_LIBRTE_TELEMETRY) += --no-as-needed
_LDLIBS-$(CONFIG_RTE_LIBRTE_TELEMETRY) += --whole-archive
_LDLIBS-$(CONFIG_RTE_LIBRTE_TELEMETRY) += -lrte_telemetry -ljansson
--
2.20.1
^ permalink raw reply related
* Re: LPC3250 periph clock at 13MHz instead of 10.4MHz
From: Alexandre Belloni @ 2019-04-10 13:44 UTC (permalink / raw)
To: Vladimir Zapolskiy; +Cc: Gregory CLEMENT, linux-arm-kernel
In-Reply-To: <aa8416ba-c81d-d857-e2b7-4b555455e500@mleia.com>
Hi Vladimir,
On 13/02/2019 19:21:44+0200, Vladimir Zapolskiy wrote:
> > Am I missing something?
> >
>
> I think I encountered quite a similar issue previously, but under another
> circumstances, when I begin to modify HCLK PLL clock rate, can you check
> my comment at https://lore.kernel.org/linux-clk/56D685F6.5060400@mleia.com/
> and verify if it's about the same problem?
>
> Since the problem hits you also, I plan to spend some time on this weekend
> to capture more details, fortunately there is a known workaround to pin
> UART input clock rate to 13MHz, it might be desired to carve it in the code.
>
I'm pretty sure this is the same issue and that it doesn't only affect
the UARTs but also timers.
The 2.6.27.8 kernel code would indicated that the timers are only driven
by sysclk, that is either 13MHz from the oscillator or 13.008896 from
PLL397. I'm wondering how many other peripherals are affected.
--
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [dpdk-dev] [PATCH 0/2] remove use of weak functions from libraries
From: Bruce Richardson @ 2019-04-10 13:45 UTC (permalink / raw)
To: konstantin.ananyev, aconole; +Cc: dev, Bruce Richardson
Weak functions don't work well with static library builds as the linker
always picks the first version of a function irrespective of whether it is
weak or not. The solution to this is to use the "whole-archive" flag when
linking, but this has the nasty side-effect that it causes the resulting
binary to be larger than it needs to be.
A further problem with this approach of using "whole-archive" is that one
either needs to link all libraries with this flag or track what libraries
need it or not - the latter being especially a problem for apps not using
the DPDK build system itself (i.e. most apps not shipped with DPDK itself).
For meson builds this information needs to make its way all the way through
to the pkgconfig file generated - not a trivial undertaking.
Thankfully, though, the use of weak functions is limited to use for
multiple functions within a single library, meaning that when the lib is
being built, the build system itself can know whether the "weak" function
is needed or not. This allows us to change the weak function to a
conditionally compiled regular function used in fallback case. This makes
the need for "whole-archive" flag, and any special linking measures for the
library, go away.
[This set does not touch the drivers, only the libraries, since there are
other special linker flags needed for drivers in general, making the
problem less severe for driver .a files.]
Bruce Richardson (2):
acl: remove use of weak functions
bpf: remove use of weak functions
lib/librte_acl/meson.build | 7 ++++++-
lib/librte_acl/rte_acl.c | 18 ++++++++++++++----
lib/librte_bpf/bpf_load.c | 4 +++-
lib/librte_bpf/meson.build | 1 +
mk/rte.app.mk | 3 ---
5 files changed, 24 insertions(+), 9 deletions(-)
--
2.20.1
^ permalink raw reply
* Re: [PATCH v8 2/2] media: cedrus: Add H264 decoding support
From: Paul Kocialkowski @ 2019-04-10 13:45 UTC (permalink / raw)
To: Maxime Ripard, hans.verkuil, acourbot, sakari.ailus,
Laurent Pinchart
Cc: tfiga, posciak, Chen-Yu Tsai, linux-kernel, linux-arm-kernel,
linux-media, nicolas.dufresne, jenskuske, jernej.skrabec, jonas,
ezequiel, linux-sunxi, Thomas Petazzoni, Jernej Skrabec
In-Reply-To: <157519b5571e24c9ef4189d30f8434b5b61121b1.1554382670.git-series.maxime.ripard@bootlin.com>
Hi,
Le jeudi 04 avril 2019 à 14:59 +0200, Maxime Ripard a écrit :
> Introduce some basic H264 decoding support in cedrus. So far, only the
> baseline profile videos have been tested, and some more advanced features
> used in higher profiles are not even implemented.
With the change to rename V4L2_PIX_FMT_H264_SLICE_RAW and make it
private, this is:
Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Cheers,
Paul
> Reviewed-by: Jernej Skrabec <jernej.skrabec@siol.net>
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
> drivers/staging/media/sunxi/cedrus/Makefile | 3 +-
> drivers/staging/media/sunxi/cedrus/cedrus.c | 31 +-
> drivers/staging/media/sunxi/cedrus/cedrus.h | 38 +-
> drivers/staging/media/sunxi/cedrus/cedrus_dec.c | 13 +-
> drivers/staging/media/sunxi/cedrus/cedrus_h264.c | 574 +++++++++++++++-
> drivers/staging/media/sunxi/cedrus/cedrus_hw.c | 4 +-
> drivers/staging/media/sunxi/cedrus/cedrus_regs.h | 91 ++-
> drivers/staging/media/sunxi/cedrus/cedrus_video.c | 9 +-
> 8 files changed, 761 insertions(+), 2 deletions(-)
> create mode 100644 drivers/staging/media/sunxi/cedrus/cedrus_h264.c
>
> diff --git a/drivers/staging/media/sunxi/cedrus/Makefile b/drivers/staging/media/sunxi/cedrus/Makefile
> index 808842f0119e..c85ac6db0302 100644
> --- a/drivers/staging/media/sunxi/cedrus/Makefile
> +++ b/drivers/staging/media/sunxi/cedrus/Makefile
> @@ -1,4 +1,5 @@
> # SPDX-License-Identifier: GPL-2.0
> obj-$(CONFIG_VIDEO_SUNXI_CEDRUS) += sunxi-cedrus.o
>
> -sunxi-cedrus-y = cedrus.o cedrus_video.o cedrus_hw.o cedrus_dec.o cedrus_mpeg2.o
> +sunxi-cedrus-y = cedrus.o cedrus_video.o cedrus_hw.o cedrus_dec.o \
> + cedrus_mpeg2.o cedrus_h264.o
> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c
> index b98add3cdedd..d613f5c24a2f 100644
> --- a/drivers/staging/media/sunxi/cedrus/cedrus.c
> +++ b/drivers/staging/media/sunxi/cedrus/cedrus.c
> @@ -40,6 +40,36 @@ static const struct cedrus_control cedrus_controls[] = {
> .codec = CEDRUS_CODEC_MPEG2,
> .required = false,
> },
> + {
> + .id = V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS,
> + .elem_size = sizeof(struct v4l2_ctrl_h264_decode_params),
> + .codec = CEDRUS_CODEC_H264,
> + .required = true,
> + },
> + {
> + .id = V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS,
> + .elem_size = sizeof(struct v4l2_ctrl_h264_slice_params),
> + .codec = CEDRUS_CODEC_H264,
> + .required = true,
> + },
> + {
> + .id = V4L2_CID_MPEG_VIDEO_H264_SPS,
> + .elem_size = sizeof(struct v4l2_ctrl_h264_sps),
> + .codec = CEDRUS_CODEC_H264,
> + .required = true,
> + },
> + {
> + .id = V4L2_CID_MPEG_VIDEO_H264_PPS,
> + .elem_size = sizeof(struct v4l2_ctrl_h264_pps),
> + .codec = CEDRUS_CODEC_H264,
> + .required = true,
> + },
> + {
> + .id = V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX,
> + .elem_size = sizeof(struct v4l2_ctrl_h264_scaling_matrix),
> + .codec = CEDRUS_CODEC_H264,
> + .required = true,
> + },
> };
>
> #define CEDRUS_CONTROLS_COUNT ARRAY_SIZE(cedrus_controls)
> @@ -278,6 +308,7 @@ static int cedrus_probe(struct platform_device *pdev)
> }
>
> dev->dec_ops[CEDRUS_CODEC_MPEG2] = &cedrus_dec_ops_mpeg2;
> + dev->dec_ops[CEDRUS_CODEC_H264] = &cedrus_dec_ops_h264;
>
> mutex_init(&dev->dev_mutex);
>
> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h
> index c57c04b41d2e..bef79f630520 100644
> --- a/drivers/staging/media/sunxi/cedrus/cedrus.h
> +++ b/drivers/staging/media/sunxi/cedrus/cedrus.h
> @@ -32,7 +32,7 @@
>
> enum cedrus_codec {
> CEDRUS_CODEC_MPEG2,
> -
> + CEDRUS_CODEC_H264,
> CEDRUS_CODEC_LAST,
> };
>
> @@ -42,6 +42,12 @@ enum cedrus_irq_status {
> CEDRUS_IRQ_OK,
> };
>
> +enum cedrus_h264_pic_type {
> + CEDRUS_H264_PIC_TYPE_FRAME = 0,
> + CEDRUS_H264_PIC_TYPE_FIELD,
> + CEDRUS_H264_PIC_TYPE_MBAFF,
> +};
> +
> struct cedrus_control {
> u32 id;
> u32 elem_size;
> @@ -49,6 +55,14 @@ struct cedrus_control {
> unsigned char required:1;
> };
>
> +struct cedrus_h264_run {
> + const struct v4l2_ctrl_h264_decode_params *decode_params;
> + const struct v4l2_ctrl_h264_pps *pps;
> + const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix;
> + const struct v4l2_ctrl_h264_slice_params *slice_params;
> + const struct v4l2_ctrl_h264_sps *sps;
> +};
> +
> struct cedrus_mpeg2_run {
> const struct v4l2_ctrl_mpeg2_slice_params *slice_params;
> const struct v4l2_ctrl_mpeg2_quantization *quantization;
> @@ -59,12 +73,20 @@ struct cedrus_run {
> struct vb2_v4l2_buffer *dst;
>
> union {
> + struct cedrus_h264_run h264;
> struct cedrus_mpeg2_run mpeg2;
> };
> };
>
> struct cedrus_buffer {
> struct v4l2_m2m_buffer m2m_buf;
> +
> + union {
> + struct {
> + unsigned int position;
> + enum cedrus_h264_pic_type pic_type;
> + } h264;
> + } codec;
> };
>
> struct cedrus_ctx {
> @@ -79,6 +101,19 @@ struct cedrus_ctx {
> struct v4l2_ctrl **ctrls;
>
> struct vb2_buffer *dst_bufs[VIDEO_MAX_FRAME];
> +
> + union {
> + struct {
> + void *mv_col_buf;
> + dma_addr_t mv_col_buf_dma;
> + ssize_t mv_col_buf_field_size;
> + ssize_t mv_col_buf_size;
> + void *pic_info_buf;
> + dma_addr_t pic_info_buf_dma;
> + void *neighbor_info_buf;
> + dma_addr_t neighbor_info_buf_dma;
> + } h264;
> + } codec;
> };
>
> struct cedrus_dec_ops {
> @@ -121,6 +156,7 @@ struct cedrus_dev {
> };
>
> extern struct cedrus_dec_ops cedrus_dec_ops_mpeg2;
> +extern struct cedrus_dec_ops cedrus_dec_ops_h264;
>
> static inline void cedrus_write(struct cedrus_dev *dev, u32 reg, u32 val)
> {
> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
> index 4d6d602cdde6..bdad87eb9d79 100644
> --- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
> +++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c
> @@ -46,6 +46,19 @@ void cedrus_device_run(void *priv)
> V4L2_CID_MPEG_VIDEO_MPEG2_QUANTIZATION);
> break;
>
> + case V4L2_PIX_FMT_H264_SLICE_RAW:
> + run.h264.decode_params = cedrus_find_control_data(ctx,
> + V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS);
> + run.h264.pps = cedrus_find_control_data(ctx,
> + V4L2_CID_MPEG_VIDEO_H264_PPS);
> + run.h264.scaling_matrix = cedrus_find_control_data(ctx,
> + V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX);
> + run.h264.slice_params = cedrus_find_control_data(ctx,
> + V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS);
> + run.h264.sps = cedrus_find_control_data(ctx,
> + V4L2_CID_MPEG_VIDEO_H264_SPS);
> + break;
> +
> default:
> break;
> }
> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h264.c b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
> new file mode 100644
> index 000000000000..2c98a3e46d2b
> --- /dev/null
> +++ b/drivers/staging/media/sunxi/cedrus/cedrus_h264.c
> @@ -0,0 +1,574 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Cedrus VPU driver
> + *
> + * Copyright (c) 2013 Jens Kuske <jenskuske@gmail.com>
> + * Copyright (c) 2018 Bootlin
> + */
> +
> +#include <linux/types.h>
> +
> +#include <media/videobuf2-dma-contig.h>
> +
> +#include "cedrus.h"
> +#include "cedrus_hw.h"
> +#include "cedrus_regs.h"
> +
> +enum cedrus_h264_sram_off {
> + CEDRUS_SRAM_H264_PRED_WEIGHT_TABLE = 0x000,
> + CEDRUS_SRAM_H264_FRAMEBUFFER_LIST = 0x100,
> + CEDRUS_SRAM_H264_REF_LIST_0 = 0x190,
> + CEDRUS_SRAM_H264_REF_LIST_1 = 0x199,
> + CEDRUS_SRAM_H264_SCALING_LIST_8x8_0 = 0x200,
> + CEDRUS_SRAM_H264_SCALING_LIST_8x8_1 = 0x210,
> + CEDRUS_SRAM_H264_SCALING_LIST_4x4 = 0x220,
> +};
> +
> +struct cedrus_h264_sram_ref_pic {
> + __le32 top_field_order_cnt;
> + __le32 bottom_field_order_cnt;
> + __le32 frame_info;
> + __le32 luma_ptr;
> + __le32 chroma_ptr;
> + __le32 mv_col_top_ptr;
> + __le32 mv_col_bot_ptr;
> + __le32 reserved;
> +} __packed;
> +
> +#define CEDRUS_H264_FRAME_NUM 18
> +
> +#define CEDRUS_NEIGHBOR_INFO_BUF_SIZE (16 * SZ_1K)
> +#define CEDRUS_PIC_INFO_BUF_SIZE (128 * SZ_1K)
> +
> +static void cedrus_h264_write_sram(struct cedrus_dev *dev,
> + enum cedrus_h264_sram_off off,
> + const void *data, size_t len)
> +{
> + const u32 *buffer = data;
> + size_t count = DIV_ROUND_UP(len, 4);
> +
> + cedrus_write(dev, VE_AVC_SRAM_PORT_OFFSET, off << 2);
> +
> + while (count--)
> + cedrus_write(dev, VE_AVC_SRAM_PORT_DATA, *buffer++);
> +}
> +
> +static dma_addr_t cedrus_h264_mv_col_buf_addr(struct cedrus_ctx *ctx,
> + unsigned int position,
> + unsigned int field)
> +{
> + dma_addr_t addr = ctx->codec.h264.mv_col_buf_dma;
> +
> + /* Adjust for the position */
> + addr += position * ctx->codec.h264.mv_col_buf_field_size * 2;
> +
> + /* Adjust for the field */
> + addr += field * ctx->codec.h264.mv_col_buf_field_size;
> +
> + return addr;
> +}
> +
> +static void cedrus_fill_ref_pic(struct cedrus_ctx *ctx,
> + struct cedrus_buffer *buf,
> + unsigned int top_field_order_cnt,
> + unsigned int bottom_field_order_cnt,
> + struct cedrus_h264_sram_ref_pic *pic)
> +{
> + struct vb2_buffer *vbuf = &buf->m2m_buf.vb.vb2_buf;
> + unsigned int position = buf->codec.h264.position;
> +
> + pic->top_field_order_cnt = top_field_order_cnt;
> + pic->bottom_field_order_cnt = bottom_field_order_cnt;
> + pic->frame_info = buf->codec.h264.pic_type << 8;
> +
> + pic->luma_ptr = cedrus_buf_addr(vbuf, &ctx->dst_fmt, 0);
> + pic->chroma_ptr = cedrus_buf_addr(vbuf, &ctx->dst_fmt, 1);
> + pic->mv_col_top_ptr = cedrus_h264_mv_col_buf_addr(ctx, position, 0);
> + pic->mv_col_bot_ptr = cedrus_h264_mv_col_buf_addr(ctx, position, 1);
> +}
> +
> +static void cedrus_write_frame_list(struct cedrus_ctx *ctx,
> + struct cedrus_run *run)
> +{
> + struct cedrus_h264_sram_ref_pic pic_list[CEDRUS_H264_FRAME_NUM];
> + const struct v4l2_ctrl_h264_decode_params *decode = run->h264.decode_params;
> + const struct v4l2_ctrl_h264_slice_params *slice = run->h264.slice_params;
> + const struct v4l2_ctrl_h264_sps *sps = run->h264.sps;
> + struct vb2_queue *cap_q = &ctx->fh.m2m_ctx->cap_q_ctx.q;
> + struct cedrus_buffer *output_buf;
> + struct cedrus_dev *dev = ctx->dev;
> + unsigned long used_dpbs = 0;
> + unsigned int position;
> + unsigned int output = 0;
> + unsigned int i;
> +
> + memset(pic_list, 0, sizeof(pic_list));
> +
> + for (i = 0; i < ARRAY_SIZE(decode->dpb); i++) {
> + const struct v4l2_h264_dpb_entry *dpb = &decode->dpb[i];
> + struct cedrus_buffer *cedrus_buf;
> + int buf_idx;
> +
> + if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_VALID))
> + continue;
> +
> + buf_idx = vb2_find_timestamp(cap_q, dpb->reference_ts, 0);
> + if (buf_idx < 0)
> + continue;
> +
> + cedrus_buf = vb2_to_cedrus_buffer(ctx->dst_bufs[buf_idx]);
> + position = cedrus_buf->codec.h264.position;
> + used_dpbs |= BIT(position);
> +
> + if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
> + continue;
> +
> + cedrus_fill_ref_pic(ctx, cedrus_buf,
> + dpb->top_field_order_cnt,
> + dpb->bottom_field_order_cnt,
> + &pic_list[position]);
> +
> + output = max(position, output);
> + }
> +
> + position = find_next_zero_bit(&used_dpbs, CEDRUS_H264_FRAME_NUM,
> + output);
> + if (position >= CEDRUS_H264_FRAME_NUM)
> + position = find_first_zero_bit(&used_dpbs, CEDRUS_H264_FRAME_NUM);
> +
> + output_buf = vb2_to_cedrus_buffer(&run->dst->vb2_buf);
> + output_buf->codec.h264.position = position;
> +
> + if (slice->flags & V4L2_H264_SLICE_FLAG_FIELD_PIC)
> + output_buf->codec.h264.pic_type = CEDRUS_H264_PIC_TYPE_FIELD;
> + else if (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD)
> + output_buf->codec.h264.pic_type = CEDRUS_H264_PIC_TYPE_MBAFF;
> + else
> + output_buf->codec.h264.pic_type = CEDRUS_H264_PIC_TYPE_FRAME;
> +
> + cedrus_fill_ref_pic(ctx, output_buf,
> + decode->top_field_order_cnt,
> + decode->bottom_field_order_cnt,
> + &pic_list[position]);
> +
> + cedrus_h264_write_sram(dev, CEDRUS_SRAM_H264_FRAMEBUFFER_LIST,
> + pic_list, sizeof(pic_list));
> +
> + cedrus_write(dev, VE_H264_OUTPUT_FRAME_IDX, position);
> +}
> +
> +#define CEDRUS_MAX_REF_IDX 32
> +
> +static void _cedrus_write_ref_list(struct cedrus_ctx *ctx,
> + struct cedrus_run *run,
> + const u8 *ref_list, u8 num_ref,
> + enum cedrus_h264_sram_off sram)
> +{
> + const struct v4l2_ctrl_h264_decode_params *decode = run->h264.decode_params;
> + struct vb2_queue *cap_q = &ctx->fh.m2m_ctx->cap_q_ctx.q;
> + struct cedrus_dev *dev = ctx->dev;
> + u8 sram_array[CEDRUS_MAX_REF_IDX];
> + unsigned int i;
> + size_t size;
> +
> + memset(sram_array, 0, sizeof(sram_array));
> +
> + for (i = 0; i < num_ref; i++) {
> + const struct v4l2_h264_dpb_entry *dpb;
> + const struct cedrus_buffer *cedrus_buf;
> + const struct vb2_v4l2_buffer *ref_buf;
> + unsigned int position;
> + int buf_idx;
> + u8 dpb_idx;
> +
> + dpb_idx = ref_list[i];
> + dpb = &decode->dpb[dpb_idx];
> +
> + if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
> + continue;
> +
> + buf_idx = vb2_find_timestamp(cap_q, dpb->reference_ts, 0);
> + if (buf_idx < 0)
> + continue;
> +
> + ref_buf = to_vb2_v4l2_buffer(ctx->dst_bufs[buf_idx]);
> + cedrus_buf = vb2_v4l2_to_cedrus_buffer(ref_buf);
> + position = cedrus_buf->codec.h264.position;
> +
> + sram_array[i] |= position << 1;
> + if (ref_buf->field == V4L2_FIELD_BOTTOM)
> + sram_array[i] |= BIT(0);
> + }
> +
> + size = min_t(size_t, ALIGN(num_ref, 4), sizeof(sram_array));
> + cedrus_h264_write_sram(dev, sram, &sram_array, size);
> +}
> +
> +static void cedrus_write_ref_list0(struct cedrus_ctx *ctx,
> + struct cedrus_run *run)
> +{
> + const struct v4l2_ctrl_h264_slice_params *slice = run->h264.slice_params;
> +
> + _cedrus_write_ref_list(ctx, run,
> + slice->ref_pic_list0,
> + slice->num_ref_idx_l0_active_minus1 + 1,
> + CEDRUS_SRAM_H264_REF_LIST_0);
> +}
> +
> +static void cedrus_write_ref_list1(struct cedrus_ctx *ctx,
> + struct cedrus_run *run)
> +{
> + const struct v4l2_ctrl_h264_slice_params *slice = run->h264.slice_params;
> +
> + _cedrus_write_ref_list(ctx, run,
> + slice->ref_pic_list1,
> + slice->num_ref_idx_l1_active_minus1 + 1,
> + CEDRUS_SRAM_H264_REF_LIST_1);
> +}
> +
> +static void cedrus_write_scaling_lists(struct cedrus_ctx *ctx,
> + struct cedrus_run *run)
> +{
> + const struct v4l2_ctrl_h264_scaling_matrix *scaling =
> + run->h264.scaling_matrix;
> + struct cedrus_dev *dev = ctx->dev;
> +
> + cedrus_h264_write_sram(dev, CEDRUS_SRAM_H264_SCALING_LIST_8x8_0,
> + scaling->scaling_list_8x8[0],
> + sizeof(scaling->scaling_list_8x8[0]));
> +
> + cedrus_h264_write_sram(dev, CEDRUS_SRAM_H264_SCALING_LIST_8x8_1,
> + scaling->scaling_list_8x8[3],
> + sizeof(scaling->scaling_list_8x8[3]));
> +
> + cedrus_h264_write_sram(dev, CEDRUS_SRAM_H264_SCALING_LIST_4x4,
> + scaling->scaling_list_4x4,
> + sizeof(scaling->scaling_list_4x4));
> +}
> +
> +static void cedrus_write_pred_weight_table(struct cedrus_ctx *ctx,
> + struct cedrus_run *run)
> +{
> + const struct v4l2_ctrl_h264_slice_params *slice =
> + run->h264.slice_params;
> + const struct v4l2_h264_pred_weight_table *pred_weight =
> + &slice->pred_weight_table;
> + struct cedrus_dev *dev = ctx->dev;
> + int i, j, k;
> +
> + cedrus_write(dev, VE_H264_SHS_WP,
> + ((pred_weight->chroma_log2_weight_denom & 0x7) << 4) |
> + ((pred_weight->luma_log2_weight_denom & 0x7) << 0));
> +
> + cedrus_write(dev, VE_AVC_SRAM_PORT_OFFSET,
> + CEDRUS_SRAM_H264_PRED_WEIGHT_TABLE << 2);
> +
> + for (i = 0; i < ARRAY_SIZE(pred_weight->weight_factors); i++) {
> + const struct v4l2_h264_weight_factors *factors =
> + &pred_weight->weight_factors[i];
> +
> + for (j = 0; j < ARRAY_SIZE(factors->luma_weight); j++) {
> + u32 val;
> +
> + val = (((u32)factors->luma_offset[j] & 0x1ff) << 16) |
> + (factors->luma_weight[j] & 0x1ff);
> + cedrus_write(dev, VE_AVC_SRAM_PORT_DATA, val);
> + }
> +
> + for (j = 0; j < ARRAY_SIZE(factors->chroma_weight); j++) {
> + for (k = 0; k < ARRAY_SIZE(factors->chroma_weight[0]); k++) {
> + u32 val;
> +
> + val = (((u32)factors->chroma_offset[j][k] & 0x1ff) << 16) |
> + (factors->chroma_weight[j][k] & 0x1ff);
> + cedrus_write(dev, VE_AVC_SRAM_PORT_DATA, val);
> + }
> + }
> + }
> +}
> +
> +static void cedrus_set_params(struct cedrus_ctx *ctx,
> + struct cedrus_run *run)
> +{
> + const struct v4l2_ctrl_h264_decode_params *decode = run->h264.decode_params;
> + const struct v4l2_ctrl_h264_slice_params *slice = run->h264.slice_params;
> + const struct v4l2_ctrl_h264_pps *pps = run->h264.pps;
> + const struct v4l2_ctrl_h264_sps *sps = run->h264.sps;
> + struct vb2_buffer *src_buf = &run->src->vb2_buf;
> + struct cedrus_dev *dev = ctx->dev;
> + dma_addr_t src_buf_addr;
> + u32 offset = slice->header_bit_size;
> + u32 len = (slice->size * 8) - offset;
> + u32 reg;
> +
> + cedrus_write(dev, VE_H264_VLD_LEN, len);
> + cedrus_write(dev, VE_H264_VLD_OFFSET, offset);
> +
> + src_buf_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
> + cedrus_write(dev, VE_H264_VLD_END,
> + src_buf_addr + vb2_get_plane_payload(src_buf, 0));
> + cedrus_write(dev, VE_H264_VLD_ADDR,
> + VE_H264_VLD_ADDR_VAL(src_buf_addr) |
> + VE_H264_VLD_ADDR_FIRST | VE_H264_VLD_ADDR_VALID |
> + VE_H264_VLD_ADDR_LAST);
> +
> + /*
> + * FIXME: Since the bitstream parsing is done in software, and
> + * in userspace, this shouldn't be needed anymore. But it
> + * turns out that removing it breaks the decoding process,
> + * without any clear indication why.
> + */
> + cedrus_write(dev, VE_H264_TRIGGER_TYPE,
> + VE_H264_TRIGGER_TYPE_INIT_SWDEC);
> +
> + if (((pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED) &&
> + (slice->slice_type == V4L2_H264_SLICE_TYPE_P ||
> + slice->slice_type == V4L2_H264_SLICE_TYPE_SP)) ||
> + (pps->weighted_bipred_idc == 1 &&
> + slice->slice_type == V4L2_H264_SLICE_TYPE_B))
> + cedrus_write_pred_weight_table(ctx, run);
> +
> + if ((slice->slice_type == V4L2_H264_SLICE_TYPE_P) ||
> + (slice->slice_type == V4L2_H264_SLICE_TYPE_SP) ||
> + (slice->slice_type == V4L2_H264_SLICE_TYPE_B))
> + cedrus_write_ref_list0(ctx, run);
> +
> + if (slice->slice_type == V4L2_H264_SLICE_TYPE_B)
> + cedrus_write_ref_list1(ctx, run);
> +
> + // picture parameters
> + reg = 0;
> + /*
> + * FIXME: the kernel headers are allowing the default value to
> + * be passed, but the libva doesn't give us that.
> + */
> + reg |= (slice->num_ref_idx_l0_active_minus1 & 0x1f) << 10;
> + reg |= (slice->num_ref_idx_l1_active_minus1 & 0x1f) << 5;
> + reg |= (pps->weighted_bipred_idc & 0x3) << 2;
> + if (pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE)
> + reg |= VE_H264_PPS_ENTROPY_CODING_MODE;
> + if (pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED)
> + reg |= VE_H264_PPS_WEIGHTED_PRED;
> + if (pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED)
> + reg |= VE_H264_PPS_CONSTRAINED_INTRA_PRED;
> + if (pps->flags & V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE)
> + reg |= VE_H264_PPS_TRANSFORM_8X8_MODE;
> + cedrus_write(dev, VE_H264_PPS, reg);
> +
> + // sequence parameters
> + reg = 0;
> + reg |= (sps->chroma_format_idc & 0x7) << 19;
> + reg |= (sps->pic_width_in_mbs_minus1 & 0xff) << 8;
> + reg |= sps->pic_height_in_map_units_minus1 & 0xff;
> + if (sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY)
> + reg |= VE_H264_SPS_MBS_ONLY;
> + if (sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD)
> + reg |= VE_H264_SPS_MB_ADAPTIVE_FRAME_FIELD;
> + if (sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE)
> + reg |= VE_H264_SPS_DIRECT_8X8_INFERENCE;
> + cedrus_write(dev, VE_H264_SPS, reg);
> +
> + // slice parameters
> + reg = 0;
> + reg |= decode->nal_ref_idc ? BIT(12) : 0;
> + reg |= (slice->slice_type & 0xf) << 8;
> + reg |= slice->cabac_init_idc & 0x3;
> + reg |= VE_H264_SHS_FIRST_SLICE_IN_PIC;
> + if (slice->flags & V4L2_H264_SLICE_FLAG_FIELD_PIC)
> + reg |= VE_H264_SHS_FIELD_PIC;
> + if (slice->flags & V4L2_H264_SLICE_FLAG_BOTTOM_FIELD)
> + reg |= VE_H264_SHS_BOTTOM_FIELD;
> + if (slice->flags & V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED)
> + reg |= VE_H264_SHS_DIRECT_SPATIAL_MV_PRED;
> + cedrus_write(dev, VE_H264_SHS, reg);
> +
> + reg = 0;
> + reg |= VE_H264_SHS2_NUM_REF_IDX_ACTIVE_OVRD;
> + reg |= (slice->num_ref_idx_l0_active_minus1 & 0x1f) << 24;
> + reg |= (slice->num_ref_idx_l1_active_minus1 & 0x1f) << 16;
> + reg |= (slice->disable_deblocking_filter_idc & 0x3) << 8;
> + reg |= (slice->slice_alpha_c0_offset_div2 & 0xf) << 4;
> + reg |= slice->slice_beta_offset_div2 & 0xf;
> + cedrus_write(dev, VE_H264_SHS2, reg);
> +
> + reg = 0;
> + reg |= (pps->second_chroma_qp_index_offset & 0x3f) << 16;
> + reg |= (pps->chroma_qp_index_offset & 0x3f) << 8;
> + reg |= (pps->pic_init_qp_minus26 + 26 + slice->slice_qp_delta) & 0x3f;
> + cedrus_write(dev, VE_H264_SHS_QP, reg);
> +
> + // clear status flags
> + cedrus_write(dev, VE_H264_STATUS, cedrus_read(dev, VE_H264_STATUS));
> +
> + // enable int
> + cedrus_write(dev, VE_H264_CTRL,
> + VE_H264_CTRL_SLICE_DECODE_INT |
> + VE_H264_CTRL_DECODE_ERR_INT |
> + VE_H264_CTRL_VLD_DATA_REQ_INT);
> +}
> +
> +static enum cedrus_irq_status
> +cedrus_h264_irq_status(struct cedrus_ctx *ctx)
> +{
> + struct cedrus_dev *dev = ctx->dev;
> + u32 reg = cedrus_read(dev, VE_H264_STATUS);
> +
> + if (reg & (VE_H264_STATUS_DECODE_ERR_INT |
> + VE_H264_STATUS_VLD_DATA_REQ_INT))
> + return CEDRUS_IRQ_ERROR;
> +
> + if (reg & VE_H264_CTRL_SLICE_DECODE_INT)
> + return CEDRUS_IRQ_OK;
> +
> + return CEDRUS_IRQ_NONE;
> +}
> +
> +static void cedrus_h264_irq_clear(struct cedrus_ctx *ctx)
> +{
> + struct cedrus_dev *dev = ctx->dev;
> +
> + cedrus_write(dev, VE_H264_STATUS,
> + VE_H264_STATUS_INT_MASK);
> +}
> +
> +static void cedrus_h264_irq_disable(struct cedrus_ctx *ctx)
> +{
> + struct cedrus_dev *dev = ctx->dev;
> + u32 reg = cedrus_read(dev, VE_H264_CTRL);
> +
> + cedrus_write(dev, VE_H264_CTRL,
> + reg & ~VE_H264_CTRL_INT_MASK);
> +}
> +
> +static void cedrus_h264_setup(struct cedrus_ctx *ctx,
> + struct cedrus_run *run)
> +{
> + struct cedrus_dev *dev = ctx->dev;
> +
> + cedrus_engine_enable(dev, CEDRUS_CODEC_H264);
> +
> + cedrus_write(dev, VE_H264_SDROT_CTRL, 0);
> + cedrus_write(dev, VE_H264_EXTRA_BUFFER1,
> + ctx->codec.h264.pic_info_buf_dma);
> + cedrus_write(dev, VE_H264_EXTRA_BUFFER2,
> + ctx->codec.h264.neighbor_info_buf_dma);
> +
> + cedrus_write_scaling_lists(ctx, run);
> + cedrus_write_frame_list(ctx, run);
> +
> + cedrus_set_params(ctx, run);
> +}
> +
> +static int cedrus_h264_start(struct cedrus_ctx *ctx)
> +{
> + struct cedrus_dev *dev = ctx->dev;
> + unsigned int field_size;
> + unsigned int mv_col_size;
> + int ret;
> +
> + /*
> + * FIXME: It seems that the H6 cedarX code is using a formula
> + * here based on the size of the frame, while all the older
> + * code is using a fixed size, so that might need to be
> + * changed at some point.
> + */
> + ctx->codec.h264.pic_info_buf =
> + dma_alloc_coherent(dev->dev, CEDRUS_PIC_INFO_BUF_SIZE,
> + &ctx->codec.h264.pic_info_buf_dma,
> + GFP_KERNEL);
> + if (!ctx->codec.h264.pic_info_buf)
> + return -ENOMEM;
> +
> + /*
> + * That buffer is supposed to be 16kiB in size, and be aligned
> + * on 16kiB as well. However, dma_alloc_coherent provides the
> + * guarantee that we'll have a CPU and DMA address aligned on
> + * the smallest page order that is greater to the requested
> + * size, so we don't have to overallocate.
> + */
> + ctx->codec.h264.neighbor_info_buf =
> + dma_alloc_coherent(dev->dev, CEDRUS_NEIGHBOR_INFO_BUF_SIZE,
> + &ctx->codec.h264.neighbor_info_buf_dma,
> + GFP_KERNEL);
> + if (!ctx->codec.h264.neighbor_info_buf) {
> + ret = -ENOMEM;
> + goto err_pic_buf;
> + }
> +
> + field_size = DIV_ROUND_UP(ctx->src_fmt.width, 16) *
> + DIV_ROUND_UP(ctx->src_fmt.height, 16) * 16;
> +
> + /*
> + * FIXME: This is actually conditional to
> + * V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE not being set, we
> + * might have to rework this if memory efficiency ever is
> + * something we need to work on.
> + */
> + field_size = field_size * 2;
> +
> + /*
> + * FIXME: This is actually conditional to
> + * V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY not being set, we might
> + * have to rework this if memory efficiency ever is something
> + * we need to work on.
> + */
> + field_size = field_size * 2;
> + ctx->codec.h264.mv_col_buf_field_size = field_size;
> +
> + mv_col_size = field_size * 2 * CEDRUS_H264_FRAME_NUM;
> + ctx->codec.h264.mv_col_buf_size = mv_col_size;
> + ctx->codec.h264.mv_col_buf = dma_alloc_coherent(dev->dev,
> + ctx->codec.h264.mv_col_buf_size,
> + &ctx->codec.h264.mv_col_buf_dma,
> + GFP_KERNEL);
> + if (!ctx->codec.h264.mv_col_buf) {
> + ret = -ENOMEM;
> + goto err_neighbor_buf;
> + }
> +
> + return 0;
> +
> +err_neighbor_buf:
> + dma_free_coherent(dev->dev, CEDRUS_NEIGHBOR_INFO_BUF_SIZE,
> + ctx->codec.h264.neighbor_info_buf,
> + ctx->codec.h264.neighbor_info_buf_dma);
> +
> +err_pic_buf:
> + dma_free_coherent(dev->dev, CEDRUS_PIC_INFO_BUF_SIZE,
> + ctx->codec.h264.pic_info_buf,
> + ctx->codec.h264.pic_info_buf_dma);
> + return ret;
> +}
> +
> +static void cedrus_h264_stop(struct cedrus_ctx *ctx)
> +{
> + struct cedrus_dev *dev = ctx->dev;
> +
> + dma_free_coherent(dev->dev, ctx->codec.h264.mv_col_buf_size,
> + ctx->codec.h264.mv_col_buf,
> + ctx->codec.h264.mv_col_buf_dma);
> + dma_free_coherent(dev->dev, CEDRUS_NEIGHBOR_INFO_BUF_SIZE,
> + ctx->codec.h264.neighbor_info_buf,
> + ctx->codec.h264.neighbor_info_buf_dma);
> + dma_free_coherent(dev->dev, CEDRUS_PIC_INFO_BUF_SIZE,
> + ctx->codec.h264.pic_info_buf,
> + ctx->codec.h264.pic_info_buf_dma);
> +}
> +
> +static void cedrus_h264_trigger(struct cedrus_ctx *ctx)
> +{
> + struct cedrus_dev *dev = ctx->dev;
> +
> + cedrus_write(dev, VE_H264_TRIGGER_TYPE,
> + VE_H264_TRIGGER_TYPE_AVC_SLICE_DECODE);
> +}
> +
> +struct cedrus_dec_ops cedrus_dec_ops_h264 = {
> + .irq_clear = cedrus_h264_irq_clear,
> + .irq_disable = cedrus_h264_irq_disable,
> + .irq_status = cedrus_h264_irq_status,
> + .setup = cedrus_h264_setup,
> + .start = cedrus_h264_start,
> + .stop = cedrus_h264_stop,
> + .trigger = cedrus_h264_trigger,
> +};
> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
> index fbfff7c1c771..748f7f673547 100644
> --- a/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
> +++ b/drivers/staging/media/sunxi/cedrus/cedrus_hw.c
> @@ -46,6 +46,10 @@ int cedrus_engine_enable(struct cedrus_dev *dev, enum cedrus_codec codec)
> reg |= VE_MODE_DEC_MPEG;
> break;
>
> + case CEDRUS_CODEC_H264:
> + reg |= VE_MODE_DEC_H264;
> + break;
> +
> default:
> return -EINVAL;
> }
> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
> index de2d6b6f64bf..3e9931416e45 100644
> --- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
> +++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h
> @@ -232,4 +232,95 @@
> #define VE_DEC_MPEG_ROT_LUMA (VE_ENGINE_DEC_MPEG + 0xcc)
> #define VE_DEC_MPEG_ROT_CHROMA (VE_ENGINE_DEC_MPEG + 0xd0)
>
> +#define VE_H264_SPS 0x200
> +#define VE_H264_SPS_MBS_ONLY BIT(18)
> +#define VE_H264_SPS_MB_ADAPTIVE_FRAME_FIELD BIT(17)
> +#define VE_H264_SPS_DIRECT_8X8_INFERENCE BIT(16)
> +
> +#define VE_H264_PPS 0x204
> +#define VE_H264_PPS_ENTROPY_CODING_MODE BIT(15)
> +#define VE_H264_PPS_WEIGHTED_PRED BIT(4)
> +#define VE_H264_PPS_CONSTRAINED_INTRA_PRED BIT(1)
> +#define VE_H264_PPS_TRANSFORM_8X8_MODE BIT(0)
> +
> +#define VE_H264_SHS 0x208
> +#define VE_H264_SHS_FIRST_SLICE_IN_PIC BIT(5)
> +#define VE_H264_SHS_FIELD_PIC BIT(4)
> +#define VE_H264_SHS_BOTTOM_FIELD BIT(3)
> +#define VE_H264_SHS_DIRECT_SPATIAL_MV_PRED BIT(2)
> +
> +#define VE_H264_SHS2 0x20c
> +#define VE_H264_SHS2_NUM_REF_IDX_ACTIVE_OVRD BIT(12)
> +
> +#define VE_H264_SHS_WP 0x210
> +
> +#define VE_H264_SHS_QP 0x21c
> +#define VE_H264_SHS_QP_SCALING_MATRIX_DEFAULT BIT(24)
> +
> +#define VE_H264_CTRL 0x220
> +#define VE_H264_CTRL_VLD_DATA_REQ_INT BIT(2)
> +#define VE_H264_CTRL_DECODE_ERR_INT BIT(1)
> +#define VE_H264_CTRL_SLICE_DECODE_INT BIT(0)
> +
> +#define VE_H264_CTRL_INT_MASK (VE_H264_CTRL_VLD_DATA_REQ_INT | \
> + VE_H264_CTRL_DECODE_ERR_INT | \
> + VE_H264_CTRL_SLICE_DECODE_INT)
> +
> +#define VE_H264_TRIGGER_TYPE 0x224
> +#define VE_H264_TRIGGER_TYPE_AVC_SLICE_DECODE (8 << 0)
> +#define VE_H264_TRIGGER_TYPE_INIT_SWDEC (7 << 0)
> +
> +#define VE_H264_STATUS 0x228
> +#define VE_H264_STATUS_VLD_DATA_REQ_INT VE_H264_CTRL_VLD_DATA_REQ_INT
> +#define VE_H264_STATUS_DECODE_ERR_INT VE_H264_CTRL_DECODE_ERR_INT
> +#define VE_H264_STATUS_SLICE_DECODE_INT VE_H264_CTRL_SLICE_DECODE_INT
> +
> +#define VE_H264_STATUS_INT_MASK VE_H264_CTRL_INT_MASK
> +
> +#define VE_H264_CUR_MB_NUM 0x22c
> +
> +#define VE_H264_VLD_ADDR 0x230
> +#define VE_H264_VLD_ADDR_FIRST BIT(30)
> +#define VE_H264_VLD_ADDR_LAST BIT(29)
> +#define VE_H264_VLD_ADDR_VALID BIT(28)
> +#define VE_H264_VLD_ADDR_VAL(x) (((x) & 0x0ffffff0) | ((x) >> 28))
> +
> +#define VE_H264_VLD_OFFSET 0x234
> +#define VE_H264_VLD_LEN 0x238
> +#define VE_H264_VLD_END 0x23c
> +#define VE_H264_SDROT_CTRL 0x240
> +#define VE_H264_OUTPUT_FRAME_IDX 0x24c
> +#define VE_H264_EXTRA_BUFFER1 0x250
> +#define VE_H264_EXTRA_BUFFER2 0x254
> +#define VE_H264_BASIC_BITS 0x2dc
> +#define VE_AVC_SRAM_PORT_OFFSET 0x2e0
> +#define VE_AVC_SRAM_PORT_DATA 0x2e4
> +
> +#define VE_ISP_INPUT_SIZE 0xa00
> +#define VE_ISP_INPUT_STRIDE 0xa04
> +#define VE_ISP_CTRL 0xa08
> +#define VE_ISP_INPUT_LUMA 0xa78
> +#define VE_ISP_INPUT_CHROMA 0xa7c
> +
> +#define VE_AVC_PARAM 0xb04
> +#define VE_AVC_QP 0xb08
> +#define VE_AVC_MOTION_EST 0xb10
> +#define VE_AVC_CTRL 0xb14
> +#define VE_AVC_TRIGGER 0xb18
> +#define VE_AVC_STATUS 0xb1c
> +#define VE_AVC_BASIC_BITS 0xb20
> +#define VE_AVC_UNK_BUF 0xb60
> +#define VE_AVC_VLE_ADDR 0xb80
> +#define VE_AVC_VLE_END 0xb84
> +#define VE_AVC_VLE_OFFSET 0xb88
> +#define VE_AVC_VLE_MAX 0xb8c
> +#define VE_AVC_VLE_LENGTH 0xb90
> +#define VE_AVC_REF_LUMA 0xba0
> +#define VE_AVC_REF_CHROMA 0xba4
> +#define VE_AVC_REC_LUMA 0xbb0
> +#define VE_AVC_REC_CHROMA 0xbb4
> +#define VE_AVC_REF_SLUMA 0xbb8
> +#define VE_AVC_REC_SLUMA 0xbbc
> +#define VE_AVC_MB_INFO 0xbc0
> +
> #endif
> diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_video.c b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
> index 9673874ece10..e2b530b1a956 100644
> --- a/drivers/staging/media/sunxi/cedrus/cedrus_video.c
> +++ b/drivers/staging/media/sunxi/cedrus/cedrus_video.c
> @@ -38,6 +38,10 @@ static struct cedrus_format cedrus_formats[] = {
> .directions = CEDRUS_DECODE_SRC,
> },
> {
> + .pixelformat = V4L2_PIX_FMT_H264_SLICE_RAW,
> + .directions = CEDRUS_DECODE_SRC,
> + },
> + {
> .pixelformat = V4L2_PIX_FMT_SUNXI_TILED_NV12,
> .directions = CEDRUS_DECODE_DST,
> },
> @@ -100,6 +104,7 @@ static void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt)
>
> switch (pix_fmt->pixelformat) {
> case V4L2_PIX_FMT_MPEG2_SLICE:
> + case V4L2_PIX_FMT_H264_SLICE_RAW:
> /* Zero bytes per line for encoded source. */
> bytesperline = 0;
>
> @@ -464,6 +469,10 @@ static int cedrus_start_streaming(struct vb2_queue *vq, unsigned int count)
> ctx->current_codec = CEDRUS_CODEC_MPEG2;
> break;
>
> + case V4L2_PIX_FMT_H264_SLICE_RAW:
> + ctx->current_codec = CEDRUS_CODEC_H264;
> + break;
> +
> default:
> return -EINVAL;
> }
--
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [PATCH v8 1/2] media: uapi: Add H264 low-level decoder API compound controls.
From: Paul Kocialkowski @ 2019-04-10 13:44 UTC (permalink / raw)
To: Maxime Ripard, hans.verkuil, acourbot, sakari.ailus,
Laurent Pinchart
Cc: jonas, jenskuske, linux-sunxi, linux-kernel, jernej.skrabec,
tfiga, Chen-Yu Tsai, posciak, Thomas Petazzoni, Guenter Roeck,
nicolas.dufresne, ezequiel, linux-arm-kernel, linux-media
In-Reply-To: <f537c99d8b5a974f8687f4f0d018c025a4220f7a.1554382670.git-series.maxime.ripard@bootlin.com>
Hi,
Le jeudi 04 avril 2019 à 14:59 +0200, Maxime Ripard a écrit :
> From: Pawel Osciak <posciak@chromium.org>
>
> Stateless video codecs will require both the H264 metadata and slices in
> order to be able to decode frames.
>
> This introduces the definitions for a new pixel format for H264 slices that
> have been parsed, as well as the structures used to pass the metadata from
> the userspace to the kernel.
With V4L2_PIX_FMT_H264_SLICE_RAW renamed to V4L2_PIX_FMT_H264_SLICE and
moved to the private h264-ctrls.h, this is:
Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Cheers,
Paul
> Reviewed-by: Tomasz Figa <tfiga@chromium.org>
> Signed-off-by: Pawel Osciak <posciak@chromium.org>
> Signed-off-by: Guenter Roeck <groeck@chromium.org>
> Co-developed-by: Maxime Ripard <maxime.ripard@bootlin.com>
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
> Documentation/media/uapi/v4l/biblio.rst | 9 +-
> Documentation/media/uapi/v4l/ext-ctrls-codec.rst | 569 ++++++++++++++-
> Documentation/media/uapi/v4l/pixfmt-compressed.rst | 19 +-
> Documentation/media/uapi/v4l/vidioc-queryctrl.rst | 30 +-
> Documentation/media/videodev2.h.rst.exceptions | 5 +-
> drivers/media/v4l2-core/v4l2-ctrls.c | 42 +-
> drivers/media/v4l2-core/v4l2-ioctl.c | 1 +-
> include/media/h264-ctrls.h | 192 +++++-
> include/media/v4l2-ctrls.h | 13 +-
> include/uapi/linux/videodev2.h | 1 +-
> 10 files changed, 880 insertions(+), 1 deletion(-)
> create mode 100644 include/media/h264-ctrls.h
>
> diff --git a/Documentation/media/uapi/v4l/biblio.rst b/Documentation/media/uapi/v4l/biblio.rst
> index ec33768c055e..8f4eb8823d82 100644
> --- a/Documentation/media/uapi/v4l/biblio.rst
> +++ b/Documentation/media/uapi/v4l/biblio.rst
> @@ -122,6 +122,15 @@ ITU BT.1119
>
> :author: International Telecommunication Union (http://www.itu.ch)
>
> +.. _h264:
> +
> +ITU-T Rec. H.264 Specification (04/2017 Edition)
> +================================================
> +
> +:title: ITU-T Recommendation H.264 "Advanced Video Coding for Generic Audiovisual Services"
> +
> +:author: International Telecommunication Union (http://www.itu.ch)
> +
> .. _jfif:
>
> JFIF
> diff --git a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
> index 67a122339c0e..fe720f239f70 100644
> --- a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
> +++ b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
> @@ -1371,6 +1371,575 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
> - Layer number
>
>
> +.. _v4l2-mpeg-h264:
> +
> +``V4L2_CID_MPEG_VIDEO_H264_SPS (struct)``
> + Specifies the sequence parameter set (as extracted from the
> + bitstream) for the associated H264 slice data. This includes the
> + necessary parameters for configuring a stateless hardware decoding
> + pipeline for H264. The bitstream parameters are defined according
> + to :ref:`h264`, section 7.4.2.1.1 "Sequence Parameter Set Data
> + Semantics". For further documentation, refer to the above
> + specification, unless there is an explicit comment stating
> + otherwise.
> +
> + .. note::
> +
> + This compound control is not yet part of the public kernel API and
> + it is expected to change.
> +
> +.. c:type:: v4l2_ctrl_h264_sps
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_ctrl_h264_sps
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u8
> + - ``profile_idc``
> + -
> + * - __u8
> + - ``constraint_set_flags``
> + - See :ref:`Sequence Parameter Set Constraints Set Flags <h264_sps_constraints_set_flags>`
> + * - __u8
> + - ``level_idc``
> + -
> + * - __u8
> + - ``seq_parameter_set_id``
> + -
> + * - __u8
> + - ``chroma_format_idc``
> + -
> + * - __u8
> + - ``bit_depth_luma_minus8``
> + -
> + * - __u8
> + - ``bit_depth_chroma_minus8``
> + -
> + * - __u8
> + - ``log2_max_frame_num_minus4``
> + -
> + * - __u8
> + - ``pic_order_cnt_type``
> + -
> + * - __u8
> + - ``log2_max_pic_order_cnt_lsb_minus4``
> + -
> + * - __u8
> + - ``max_num_ref_frames``
> + -
> + * - __u8
> + - ``num_ref_frames_in_pic_order_cnt_cycle``
> + -
> + * - __s32
> + - ``offset_for_ref_frame[255]``
> + -
> + * - __s32
> + - ``offset_for_non_ref_pic``
> + -
> + * - __s32
> + - ``offset_for_top_to_bottom_field``
> + -
> + * - __u16
> + - ``pic_width_in_mbs_minus1``
> + -
> + * - __u16
> + - ``pic_height_in_map_units_minus1``
> + -
> + * - __u32
> + - ``flags``
> + - See :ref:`Sequence Parameter Set Flags <h264_sps_flags>`
> +
> +.. _h264_sps_constraints_set_flags:
> +
> +``Sequence Parameter Set Constraints Set Flags``
> +
> +.. cssclass:: longtable
> +
> +.. flat-table::
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - ``V4L2_H264_SPS_CONSTRAINT_SET0_FLAG``
> + - 0x00000001
> + -
> + * - ``V4L2_H264_SPS_CONSTRAINT_SET1_FLAG``
> + - 0x00000002
> + -
> + * - ``V4L2_H264_SPS_CONSTRAINT_SET2_FLAG``
> + - 0x00000004
> + -
> + * - ``V4L2_H264_SPS_CONSTRAINT_SET3_FLAG``
> + - 0x00000008
> + -
> + * - ``V4L2_H264_SPS_CONSTRAINT_SET4_FLAG``
> + - 0x00000010
> + -
> + * - ``V4L2_H264_SPS_CONSTRAINT_SET5_FLAG``
> + - 0x00000020
> + -
> +
> +.. _h264_sps_flags:
> +
> +``Sequence Parameter Set Flags``
> +
> +.. cssclass:: longtable
> +
> +.. flat-table::
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - ``V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE``
> + - 0x00000001
> + -
> + * - ``V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS``
> + - 0x00000002
> + -
> + * - ``V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO``
> + - 0x00000004
> + -
> + * - ``V4L2_H264_SPS_FLAG_GAPS_IN_FRAME_NUM_VALUE_ALLOWED``
> + - 0x00000008
> + -
> + * - ``V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY``
> + - 0x00000010
> + -
> + * - ``V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD``
> + - 0x00000020
> + -
> + * - ``V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE``
> + - 0x00000040
> + -
> +
> +``V4L2_CID_MPEG_VIDEO_H264_PPS (struct)``
> + Specifies the picture parameter set (as extracted from the
> + bitstream) for the associated H264 slice data. This includes the
> + necessary parameters for configuring a stateless hardware decoding
> + pipeline for H264. The bitstream parameters are defined according
> + to :ref:`h264`, section 7.4.2.2 "Picture Parameter Set RBSP
> + Semantics". For further documentation, refer to the above
> + specification, unless there is an explicit comment stating
> + otherwise.
> +
> + .. note::
> +
> + This compound control is not yet part of the public kernel API and
> + it is expected to change.
> +
> +.. c:type:: v4l2_ctrl_h264_pps
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_ctrl_h264_pps
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u8
> + - ``pic_parameter_set_id``
> + -
> + * - __u8
> + - ``seq_parameter_set_id``
> + -
> + * - __u8
> + - ``num_slice_groups_minus1``
> + -
> + * - __u8
> + - ``num_ref_idx_l0_default_active_minus1``
> + -
> + * - __u8
> + - ``num_ref_idx_l1_default_active_minus1``
> + -
> + * - __u8
> + - ``weighted_bipred_idc``
> + -
> + * - __s8
> + - ``pic_init_qp_minus26``
> + -
> + * - __s8
> + - ``pic_init_qs_minus26``
> + -
> + * - __s8
> + - ``chroma_qp_index_offset``
> + -
> + * - __s8
> + - ``second_chroma_qp_index_offset``
> + -
> + * - __u16
> + - ``flags``
> + - See :ref:`Picture Parameter Set Flags <h264_pps_flags>`
> +
> +.. _h264_pps_flags:
> +
> +``Picture Parameter Set Flags``
> +
> +.. cssclass:: longtable
> +
> +.. flat-table::
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - ``V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE``
> + - 0x00000001
> + -
> + * - ``V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT``
> + - 0x00000002
> + -
> + * - ``V4L2_H264_PPS_FLAG_WEIGHTED_PRED``
> + - 0x00000004
> + -
> + * - ``V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT``
> + - 0x00000008
> + -
> + * - ``V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED``
> + - 0x00000010
> + -
> + * - ``V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT``
> + - 0x00000020
> + -
> + * - ``V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE``
> + - 0x00000040
> + -
> + * - ``V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT``
> + - 0x00000080
> + -
> +
> +``V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX (struct)``
> + Specifies the scaling matrix (as extracted from the bitstream) for
> + the associated H264 slice data. The bitstream parameters are
> + defined according to :ref:`h264`, section 7.4.2.1.1.1 "Scaling
> + List Semantics".For further documentation, refer to the above
> + specification, unless there is an explicit comment stating
> + otherwise.
> +
> + .. note::
> +
> + This compound control is not yet part of the public kernel API and
> + it is expected to change.
> +
> +.. c:type:: v4l2_ctrl_h264_scaling_matrix
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_ctrl_h264_scaling_matrix
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u8
> + - ``scaling_list_4x4[6][16]``
> + -
> + * - __u8
> + - ``scaling_list_8x8[6][64]``
> + -
> +
> +``V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS (struct)``
> + Specifies the slice parameters (as extracted from the bitstream)
> + for the associated H264 slice data. This includes the necessary
> + parameters for configuring a stateless hardware decoding pipeline
> + for H264. The bitstream parameters are defined according to
> + :ref:`h264`, section 7.4.3 "Slice Header Semantics". For further
> + documentation, refer to the above specification, unless there is
> + an explicit comment stating otherwise.
> +
> + .. note::
> +
> + This compound control is not yet part of the public kernel API
> + and it is expected to change.
> +
> + This structure is expected to be passed as an array, with one
> + entry for each slice included in the bitstream buffer.
> +
> +.. c:type:: v4l2_ctrl_h264_slice_params
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_ctrl_h264_slice_params
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u32
> + - ``size``
> + -
> + * - __u32
> + - ``header_bit_size``
> + -
> + * - __u16
> + - ``first_mb_in_slice``
> + -
> + * - __u8
> + - ``slice_type``
> + -
> + * - __u8
> + - ``pic_parameter_set_id``
> + -
> + * - __u8
> + - ``colour_plane_id``
> + -
> + * - __u8
> + - ``redundant_pic_cnt``
> + -
> + * - __u16
> + - ``frame_num``
> + -
> + * - __u16
> + - ``idr_pic_id``
> + -
> + * - __u16
> + - ``pic_order_cnt_lsb``
> + -
> + * - __s32
> + - ``delta_pic_order_cnt_bottom``
> + -
> + * - __s32
> + - ``delta_pic_order_cnt0``
> + -
> + * - __s32
> + - ``delta_pic_order_cnt1``
> + -
> + * - struct :c:type:`v4l2_h264_pred_weight_table`
> + - ``pred_weight_table``
> + -
> + * - __u32
> + - ``dec_ref_pic_marking_bit_size``
> + -
> + * - __u32
> + - ``pic_order_cnt_bit_size``
> + -
> + * - __u8
> + - ``cabac_init_idc``
> + -
> + * - __s8
> + - ``slice_qp_delta``
> + -
> + * - __s8
> + - ``slice_qs_delta``
> + -
> + * - __u8
> + - ``disable_deblocking_filter_idc``
> + -
> + * - __s8
> + - ``slice_alpha_c0_offset_div2``
> + -
> + * - __s8
> + - ``slice_beta_offset_div2``
> + -
> + * - __u8
> + - ``num_ref_idx_l0_active_minus1``
> + -
> + * - __u8
> + - ``num_ref_idx_l1_active_minus1``
> + -
> + * - __u32
> + - ``slice_group_change_cycle``
> + -
> + * - __u8
> + - ``ref_pic_list0[32]``
> + - Reference picture list after applying the per-slice modifications
> + * - __u8
> + - ``ref_pic_list1[32]``
> + - Reference picture list after applying the per-slice modifications
> + * - __u32
> + - ``flags``
> + - See :ref:`Slice Parameter Flags <h264_slice_flags>`
> +
> +.. _h264_slice_flags:
> +
> +``Slice Parameter Set Flags``
> +
> +.. cssclass:: longtable
> +
> +.. flat-table::
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - ``V4L2_H264_SLICE_FLAG_FIELD_PIC``
> + - 0x00000001
> + -
> + * - ``V4L2_H264_SLICE_FLAG_BOTTOM_FIELD``
> + - 0x00000002
> + -
> + * - ``V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED``
> + - 0x00000004
> + -
> + * - ``V4L2_H264_SLICE_FLAG_SP_FOR_SWITCH``
> + - 0x00000008
> + -
> +
> +``Prediction Weight Table``
> +
> + The bitstream parameters are defined according to :ref:`h264`,
> + section 7.4.3.2 "Prediction Weight Table Semantics". For further
> + documentation, refer to the above specification, unless there is
> + an explicit comment stating otherwise.
> +
> +.. c:type:: v4l2_h264_pred_weight_table
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_h264_pred_weight_table
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u16
> + - ``luma_log2_weight_denom``
> + -
> + * - __u16
> + - ``chroma_log2_weight_denom``
> + -
> + * - struct :c:type:`v4l2_h264_weight_factors`
> + - ``weight_factors[2]``
> + - The weight factors at index 0 are the weight factors for the reference
> + list 0, the one at index 1 for the reference list 1.
> +
> +.. c:type:: v4l2_h264_weight_factors
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_h264_weight_factors
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __s16
> + - ``luma_weight[32]``
> + -
> + * - __s16
> + - ``luma_offset[32]``
> + -
> + * - __s16
> + - ``chroma_weight[32][2]``
> + -
> + * - __s16
> + - ``chroma_offset[32][2]``
> + -
> +
> +``V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS (struct)``
> + Specifies the decode parameters (as extracted from the bitstream)
> + for the associated H264 slice data. This includes the necessary
> + parameters for configuring a stateless hardware decoding pipeline
> + for H264. The bitstream parameters are defined according to
> + :ref:`h264`. For further documentation, refer to the above
> + specification, unless there is an explicit comment stating
> + otherwise.
> +
> + .. note::
> +
> + This compound control is not yet part of the public kernel API and
> + it is expected to change.
> +
> +.. c:type:: v4l2_ctrl_h264_decode_params
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_ctrl_h264_decode_params
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u32
> + - ``num_slices``
> + - Number of slices needed to decode the current frame
> + * - __u32
> + - ``nal_ref_idc``
> + - NAL reference ID value coming from the NAL Unit header
> + * - __u8
> + - ``ref_pic_list_p0[32]``
> + - Backward reference list used by P-frames in the original bitstream order
> + * - __u8
> + - ``ref_pic_list_b0[32]``
> + - Backward reference list used by B-frames in the original bitstream order
> + * - __u8
> + - ``ref_pic_list_b1[32]``
> + - Forward reference list used by B-frames in the original bitstream order
> + * - __s32
> + - ``top_field_order_cnt``
> + - Picture Order Count for the coded top field
> + * - __s32
> + - ``bottom_field_order_cnt``
> + - Picture Order Count for the coded bottom field
> + * - __u32
> + - ``flags``
> + - See :ref:`Decode Parameters Flags <h264_decode_params_flags>`
> + * - struct :c:type:`v4l2_h264_dpb_entry`
> + - ``dpb[16]``
> + -
> +
> +.. _h264_decode_params_flags:
> +
> +``Decode Parameters Flags``
> +
> +.. cssclass:: longtable
> +
> +.. flat-table::
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - ``V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC``
> + - 0x00000001
> + - That picture is an IDR picture
> +
> +.. c:type:: v4l2_h264_dpb_entry
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_h264_dpb_entry
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u64
> + - ``reference_ts``
> + - Timestamp of the V4L2 capture buffer to use as reference, used
> + with B-coded and P-coded frames. The timestamp refers to the
> + ``timestamp`` field in struct :c:type:`v4l2_buffer`. Use the
> + :c:func:`v4l2_timeval_to_ns()` function to convert the struct
> + :c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64.
> + * - __u16
> + - ``frame_num``
> + -
> + * - __u16
> + - ``pic_num``
> + -
> + * - __s32
> + - ``top_field_order_cnt``
> + -
> + * - __s32
> + - ``bottom_field_order_cnt``
> + -
> + * - __u32
> + - ``flags``
> + - See :ref:`DPB Entry Flags <h264_dpb_flags>`
> +
> +.. _h264_dpb_flags:
> +
> +``DPB Entries Flags``
> +
> +.. cssclass:: longtable
> +
> +.. flat-table::
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - ``V4L2_H264_DPB_ENTRY_FLAG_VALID``
> + - 0x00000001
> + - The DPB entry is valid and should be considered
> + * - ``V4L2_H264_DPB_ENTRY_FLAG_ACTIVE``
> + - 0x00000002
> + - The DPB entry is currently being used as a reference frame
> + * - ``V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM``
> + - 0x00000004
> + - The DPB entry is a long term reference frame
>
> .. _v4l2-mpeg-mpeg2:
>
> diff --git a/Documentation/media/uapi/v4l/pixfmt-compressed.rst b/Documentation/media/uapi/v4l/pixfmt-compressed.rst
> index 6c961cfb74da..ea0a8a68759b 100644
> --- a/Documentation/media/uapi/v4l/pixfmt-compressed.rst
> +++ b/Documentation/media/uapi/v4l/pixfmt-compressed.rst
> @@ -52,6 +52,25 @@ Compressed Formats
> - ``V4L2_PIX_FMT_H264_MVC``
> - 'M264'
> - H264 MVC video elementary stream.
> + * .. _V4L2-PIX-FMT-H264-SLICE:
> +
> + - ``V4L2_PIX_FMT_H264_SLICE_RAW``
> + - 'S264'
> + - H264 parsed slice data, as extracted from the H264 bitstream.
> + This format is adapted for stateless video decoders that
> + implement an H264 pipeline (using the :ref:`codec` and
> + :ref:`media-request-api`). Metadata associated with the frame
> + to decode are required to be passed through the
> + ``V4L2_CID_MPEG_VIDEO_H264_SPS``,
> + ``V4L2_CID_MPEG_VIDEO_H264_PPS``,
> + ``V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX``,
> + ``V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS`` and
> + ``V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS`` controls. See the
> + :ref:`associated Codec Control IDs <v4l2-mpeg-h264>`.
> + Exactly one output and one capture buffer must be provided for
> + use with this pixel format. The output buffer must contain the
> + appropriate number of macroblocks to decode a full
> + corresponding frame to the matching capture buffer.
> * .. _V4L2-PIX-FMT-H263:
>
> - ``V4L2_PIX_FMT_H263``
> diff --git a/Documentation/media/uapi/v4l/vidioc-queryctrl.rst b/Documentation/media/uapi/v4l/vidioc-queryctrl.rst
> index f824162d0ea9..dc500632095d 100644
> --- a/Documentation/media/uapi/v4l/vidioc-queryctrl.rst
> +++ b/Documentation/media/uapi/v4l/vidioc-queryctrl.rst
> @@ -443,6 +443,36 @@ See also the examples in :ref:`control`.
> - n/a
> - A struct :c:type:`v4l2_ctrl_mpeg2_quantization`, containing MPEG-2
> quantization matrices for stateless video decoders.
> + * - ``V4L2_CTRL_TYPE_H264_SPS``
> + - n/a
> + - n/a
> + - n/a
> + - A struct :c:type:`v4l2_ctrl_h264_sps`, containing H264
> + sequence parameters for stateless video decoders.
> + * - ``V4L2_CTRL_TYPE_H264_PPS``
> + - n/a
> + - n/a
> + - n/a
> + - A struct :c:type:`v4l2_ctrl_h264_pps`, containing H264
> + picture parameters for stateless video decoders.
> + * - ``V4L2_CTRL_TYPE_H264_SCALING_MATRIX``
> + - n/a
> + - n/a
> + - n/a
> + - A struct :c:type:`v4l2_ctrl_h264_scaling_matrix`, containing H264
> + scaling matrices for stateless video decoders.
> + * - ``V4L2_CTRL_TYPE_H264_SLICE_PARAMS``
> + - n/a
> + - n/a
> + - n/a
> + - A struct :c:type:`v4l2_ctrl_h264_slice_params`, containing H264
> + slice parameters for stateless video decoders.
> + * - ``V4L2_CTRL_TYPE_H264_DECODE_PARAMS``
> + - n/a
> + - n/a
> + - n/a
> + - A struct :c:type:`v4l2_ctrl_h264_decode_params`, containing H264
> + decode parameters for stateless video decoders.
>
> .. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
>
> diff --git a/Documentation/media/videodev2.h.rst.exceptions b/Documentation/media/videodev2.h.rst.exceptions
> index 64d348e67df9..55cbe324b9fc 100644
> --- a/Documentation/media/videodev2.h.rst.exceptions
> +++ b/Documentation/media/videodev2.h.rst.exceptions
> @@ -136,6 +136,11 @@ replace symbol V4L2_CTRL_TYPE_U32 :c:type:`v4l2_ctrl_type`
> replace symbol V4L2_CTRL_TYPE_U8 :c:type:`v4l2_ctrl_type`
> replace symbol V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
> replace symbol V4L2_CTRL_TYPE_MPEG2_QUANTIZATION :c:type:`v4l2_ctrl_type`
> +replace symbol V4L2_CTRL_TYPE_H264_SPS :c:type:`v4l2_ctrl_type`
> +replace symbol V4L2_CTRL_TYPE_H264_PPS :c:type:`v4l2_ctrl_type`
> +replace symbol V4L2_CTRL_TYPE_H264_SCALING_MATRIX :c:type:`v4l2_ctrl_type`
> +replace symbol V4L2_CTRL_TYPE_H264_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
> +replace symbol V4L2_CTRL_TYPE_H264_DECODE_PARAMS :c:type:`v4l2_ctrl_type`
>
> # V4L2 capability defines
> replace define V4L2_CAP_VIDEO_CAPTURE device-capabilities
> diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
> index b1ae2e555c68..46aec8c3acde 100644
> --- a/drivers/media/v4l2-core/v4l2-ctrls.c
> +++ b/drivers/media/v4l2-core/v4l2-ctrls.c
> @@ -828,6 +828,11 @@ const char *v4l2_ctrl_get_name(u32 id)
> case V4L2_CID_MPEG_VIDEO_H264_CONSTRAINED_INTRA_PREDICTION:
> return "H264 Constrained Intra Pred";
> case V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET: return "H264 Chroma QP Index Offset";
> + case V4L2_CID_MPEG_VIDEO_H264_SPS: return "H264 Sequence Parameter Set";
> + case V4L2_CID_MPEG_VIDEO_H264_PPS: return "H264 Picture Parameter Set";
> + case V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX: return "H264 Scaling Matrix";
> + case V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS: return "H264 Slice Parameters";
> + case V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS: return "H264 Decode Parameters";
> case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value";
> case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP: return "MPEG4 P-Frame QP Value";
> case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP: return "MPEG4 B-Frame QP Value";
> @@ -1309,6 +1314,21 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
> case V4L2_CID_MPEG_VIDEO_FWHT_PARAMS:
> *type = V4L2_CTRL_TYPE_FWHT_PARAMS;
> break;
> + case V4L2_CID_MPEG_VIDEO_H264_SPS:
> + *type = V4L2_CTRL_TYPE_H264_SPS;
> + break;
> + case V4L2_CID_MPEG_VIDEO_H264_PPS:
> + *type = V4L2_CTRL_TYPE_H264_PPS;
> + break;
> + case V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX:
> + *type = V4L2_CTRL_TYPE_H264_SCALING_MATRIX;
> + break;
> + case V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS:
> + *type = V4L2_CTRL_TYPE_H264_SLICE_PARAMS;
> + break;
> + case V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS:
> + *type = V4L2_CTRL_TYPE_H264_DECODE_PARAMS;
> + break;
> default:
> *type = V4L2_CTRL_TYPE_INTEGER;
> break;
> @@ -1678,6 +1698,13 @@ static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx,
> case V4L2_CTRL_TYPE_FWHT_PARAMS:
> return 0;
>
> + case V4L2_CTRL_TYPE_H264_SPS:
> + case V4L2_CTRL_TYPE_H264_PPS:
> + case V4L2_CTRL_TYPE_H264_SCALING_MATRIX:
> + case V4L2_CTRL_TYPE_H264_SLICE_PARAMS:
> + case V4L2_CTRL_TYPE_H264_DECODE_PARAMS:
> + return 0;
> +
> default:
> return -EINVAL;
> }
> @@ -2261,6 +2288,21 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
> case V4L2_CTRL_TYPE_FWHT_PARAMS:
> elem_size = sizeof(struct v4l2_ctrl_fwht_params);
> break;
> + case V4L2_CTRL_TYPE_H264_SPS:
> + elem_size = sizeof(struct v4l2_ctrl_h264_sps);
> + break;
> + case V4L2_CTRL_TYPE_H264_PPS:
> + elem_size = sizeof(struct v4l2_ctrl_h264_pps);
> + break;
> + case V4L2_CTRL_TYPE_H264_SCALING_MATRIX:
> + elem_size = sizeof(struct v4l2_ctrl_h264_scaling_matrix);
> + break;
> + case V4L2_CTRL_TYPE_H264_SLICE_PARAMS:
> + elem_size = sizeof(struct v4l2_ctrl_h264_slice_params);
> + break;
> + case V4L2_CTRL_TYPE_H264_DECODE_PARAMS:
> + elem_size = sizeof(struct v4l2_ctrl_h264_decode_params);
> + break;
> default:
> if (type < V4L2_CTRL_COMPOUND_TYPES)
> elem_size = sizeof(s32);
> diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
> index ac87c3e37280..f6e1254064d2 100644
> --- a/drivers/media/v4l2-core/v4l2-ioctl.c
> +++ b/drivers/media/v4l2-core/v4l2-ioctl.c
> @@ -1325,6 +1325,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
> case V4L2_PIX_FMT_H264: descr = "H.264"; break;
> case V4L2_PIX_FMT_H264_NO_SC: descr = "H.264 (No Start Codes)"; break;
> case V4L2_PIX_FMT_H264_MVC: descr = "H.264 MVC"; break;
> + case V4L2_PIX_FMT_H264_SLICE_RAW: descr = "H.264 Parsed Slice Data"; break;
> case V4L2_PIX_FMT_H263: descr = "H.263"; break;
> case V4L2_PIX_FMT_MPEG1: descr = "MPEG-1 ES"; break;
> case V4L2_PIX_FMT_MPEG2: descr = "MPEG-2 ES"; break;
> diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h
> new file mode 100644
> index 000000000000..e2f83b3cdbef
> --- /dev/null
> +++ b/include/media/h264-ctrls.h
> @@ -0,0 +1,192 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * These are the H.264 state controls for use with stateless H.264
> + * codec drivers.
> + *
> + * It turns out that these structs are not stable yet and will undergo
> + * more changes. So keep them private until they are stable and ready to
> + * become part of the official public API.
> + */
> +
> +#ifndef _H264_CTRLS_H_
> +#define _H264_CTRLS_H_
> +
> +/*
> + * This is put insanely high to avoid conflicting with controls that
> + * would be added during the phase where those controls are not
> + * stable. It should be fixed eventually.
> + */
> +#define V4L2_CID_MPEG_VIDEO_H264_SPS (V4L2_CID_MPEG_BASE+1000)
> +#define V4L2_CID_MPEG_VIDEO_H264_PPS (V4L2_CID_MPEG_BASE+1001)
> +#define V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX (V4L2_CID_MPEG_BASE+1002)
> +#define V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS (V4L2_CID_MPEG_BASE+1003)
> +#define V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS (V4L2_CID_MPEG_BASE+1004)
> +
> +/* enum v4l2_ctrl_type type values */
> +#define V4L2_CTRL_TYPE_H264_SPS 0x0110
> +#define V4L2_CTRL_TYPE_H264_PPS 0x0111
> +#define V4L2_CTRL_TYPE_H264_SCALING_MATRIX 0x0112
> +#define V4L2_CTRL_TYPE_H264_SLICE_PARAMS 0x0113
> +#define V4L2_CTRL_TYPE_H264_DECODE_PARAMS 0x0114
> +
> +#define V4L2_H264_SPS_CONSTRAINT_SET0_FLAG 0x01
> +#define V4L2_H264_SPS_CONSTRAINT_SET1_FLAG 0x02
> +#define V4L2_H264_SPS_CONSTRAINT_SET2_FLAG 0x04
> +#define V4L2_H264_SPS_CONSTRAINT_SET3_FLAG 0x08
> +#define V4L2_H264_SPS_CONSTRAINT_SET4_FLAG 0x10
> +#define V4L2_H264_SPS_CONSTRAINT_SET5_FLAG 0x20
> +
> +#define V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE 0x01
> +#define V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS 0x02
> +#define V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO 0x04
> +#define V4L2_H264_SPS_FLAG_GAPS_IN_FRAME_NUM_VALUE_ALLOWED 0x08
> +#define V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY 0x10
> +#define V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD 0x20
> +#define V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE 0x40
> +
> +struct v4l2_ctrl_h264_sps {
> + __u8 profile_idc;
> + __u8 constraint_set_flags;
> + __u8 level_idc;
> + __u8 seq_parameter_set_id;
> + __u8 chroma_format_idc;
> + __u8 bit_depth_luma_minus8;
> + __u8 bit_depth_chroma_minus8;
> + __u8 log2_max_frame_num_minus4;
> + __u8 pic_order_cnt_type;
> + __u8 log2_max_pic_order_cnt_lsb_minus4;
> + __u8 max_num_ref_frames;
> + __u8 num_ref_frames_in_pic_order_cnt_cycle;
> + __s32 offset_for_ref_frame[255];
> + __s32 offset_for_non_ref_pic;
> + __s32 offset_for_top_to_bottom_field;
> + __u16 pic_width_in_mbs_minus1;
> + __u16 pic_height_in_map_units_minus1;
> + __u32 flags;
> +};
> +
> +#define V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE 0x0001
> +#define V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT 0x0002
> +#define V4L2_H264_PPS_FLAG_WEIGHTED_PRED 0x0004
> +#define V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT 0x0008
> +#define V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED 0x0010
> +#define V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT 0x0020
> +#define V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE 0x0040
> +#define V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT 0x0080
> +
> +struct v4l2_ctrl_h264_pps {
> + __u8 pic_parameter_set_id;
> + __u8 seq_parameter_set_id;
> + __u8 num_slice_groups_minus1;
> + __u8 num_ref_idx_l0_default_active_minus1;
> + __u8 num_ref_idx_l1_default_active_minus1;
> + __u8 weighted_bipred_idc;
> + __s8 pic_init_qp_minus26;
> + __s8 pic_init_qs_minus26;
> + __s8 chroma_qp_index_offset;
> + __s8 second_chroma_qp_index_offset;
> + __u16 flags;
> +};
> +
> +struct v4l2_ctrl_h264_scaling_matrix {
> + __u8 scaling_list_4x4[6][16];
> + __u8 scaling_list_8x8[6][64];
> +};
> +
> +struct v4l2_h264_weight_factors {
> + __s16 luma_weight[32];
> + __s16 luma_offset[32];
> + __s16 chroma_weight[32][2];
> + __s16 chroma_offset[32][2];
> +};
> +
> +struct v4l2_h264_pred_weight_table {
> + __u16 luma_log2_weight_denom;
> + __u16 chroma_log2_weight_denom;
> + struct v4l2_h264_weight_factors weight_factors[2];
> +};
> +
> +#define V4L2_H264_SLICE_TYPE_P 0
> +#define V4L2_H264_SLICE_TYPE_B 1
> +#define V4L2_H264_SLICE_TYPE_I 2
> +#define V4L2_H264_SLICE_TYPE_SP 3
> +#define V4L2_H264_SLICE_TYPE_SI 4
> +
> +#define V4L2_H264_SLICE_FLAG_FIELD_PIC 0x01
> +#define V4L2_H264_SLICE_FLAG_BOTTOM_FIELD 0x02
> +#define V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED 0x04
> +#define V4L2_H264_SLICE_FLAG_SP_FOR_SWITCH 0x08
> +
> +struct v4l2_ctrl_h264_slice_params {
> + /* Size in bytes, including header */
> + __u32 size;
> + /* Offset in bits to slice_data() from the beginning of this slice. */
> + __u32 header_bit_size;
> +
> + __u16 first_mb_in_slice;
> + __u8 slice_type;
> + __u8 pic_parameter_set_id;
> + __u8 colour_plane_id;
> + __u8 redundant_pic_cnt;
> + __u16 frame_num;
> + __u16 idr_pic_id;
> + __u16 pic_order_cnt_lsb;
> + __s32 delta_pic_order_cnt_bottom;
> + __s32 delta_pic_order_cnt0;
> + __s32 delta_pic_order_cnt1;
> +
> + struct v4l2_h264_pred_weight_table pred_weight_table;
> + /* Size in bits of dec_ref_pic_marking() syntax element. */
> + __u32 dec_ref_pic_marking_bit_size;
> + /* Size in bits of pic order count syntax. */
> + __u32 pic_order_cnt_bit_size;
> +
> + __u8 cabac_init_idc;
> + __s8 slice_qp_delta;
> + __s8 slice_qs_delta;
> + __u8 disable_deblocking_filter_idc;
> + __s8 slice_alpha_c0_offset_div2;
> + __s8 slice_beta_offset_div2;
> + __u8 num_ref_idx_l0_active_minus1;
> + __u8 num_ref_idx_l1_active_minus1;
> + __u32 slice_group_change_cycle;
> +
> + /*
> + * Entries on each list are indices into
> + * v4l2_ctrl_h264_decode_params.dpb[].
> + */
> + __u8 ref_pic_list0[32];
> + __u8 ref_pic_list1[32];
> +
> + __u32 flags;
> +};
> +
> +#define V4L2_H264_DPB_ENTRY_FLAG_VALID 0x01
> +#define V4L2_H264_DPB_ENTRY_FLAG_ACTIVE 0x02
> +#define V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM 0x04
> +
> +struct v4l2_h264_dpb_entry {
> + __u64 reference_ts;
> + __u16 frame_num;
> + __u16 pic_num;
> + /* Note that field is indicated by v4l2_buffer.field */
> + __s32 top_field_order_cnt;
> + __s32 bottom_field_order_cnt;
> + __u32 flags; /* V4L2_H264_DPB_ENTRY_FLAG_* */
> +};
> +
> +#define V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC 0x01
> +
> +struct v4l2_ctrl_h264_decode_params {
> + struct v4l2_h264_dpb_entry dpb[16];
> + __u16 num_slices;
> + __u16 nal_ref_idc;
> + __u8 ref_pic_list_p0[32];
> + __u8 ref_pic_list_b0[32];
> + __u8 ref_pic_list_b1[32];
> + __s32 top_field_order_cnt;
> + __s32 bottom_field_order_cnt;
> + __u32 flags; /* V4L2_H264_DECODE_PARAM_FLAG_* */
> +};
> +
> +#endif
> diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
> index bd621cec65a5..dce6f33fd749 100644
> --- a/include/media/v4l2-ctrls.h
> +++ b/include/media/v4l2-ctrls.h
> @@ -23,11 +23,12 @@
> #include <media/media-request.h>
>
> /*
> - * Include the mpeg2 and fwht stateless codec compound control definitions.
> + * Include the stateless codec compound control definitions.
> * This will move to the public headers once this API is fully stable.
> */
> #include <media/mpeg2-ctrls.h>
> #include <media/fwht-ctrls.h>
> +#include <media/h264-ctrls.h>
>
> /* forward references */
> struct file;
> @@ -51,6 +52,11 @@ struct poll_table_struct;
> * @p_mpeg2_slice_params: Pointer to a MPEG2 slice parameters structure.
> * @p_mpeg2_quantization: Pointer to a MPEG2 quantization data structure.
> * @p_fwht_params: Pointer to a FWHT stateless parameters structure.
> + * @p_h264_sps: Pointer to a struct v4l2_ctrl_h264_sps.
> + * @p_h264_pps: Pointer to a struct v4l2_ctrl_h264_pps.
> + * @p_h264_scaling_matrix: Pointer to a struct v4l2_ctrl_h264_scaling_matrix.
> + * @p_h264_slice_param: Pointer to a struct v4l2_ctrl_h264_slice_params.
> + * @p_h264_decode_param: Pointer to a struct v4l2_ctrl_h264_decode_params.
> * @p: Pointer to a compound value.
> */
> union v4l2_ctrl_ptr {
> @@ -63,6 +69,11 @@ union v4l2_ctrl_ptr {
> struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params;
> struct v4l2_ctrl_mpeg2_quantization *p_mpeg2_quantization;
> struct v4l2_ctrl_fwht_params *p_fwht_params;
> + struct v4l2_ctrl_h264_sps *p_h264_sps;
> + struct v4l2_ctrl_h264_pps *p_h264_pps;
> + struct v4l2_ctrl_h264_scaling_matrix *p_h264_scaling_matrix;
> + struct v4l2_ctrl_h264_slice_params *p_h264_slice_param;
> + struct v4l2_ctrl_h264_decode_params *p_h264_decode_param;
> void *p;
> };
>
> diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
> index 496e6453450c..838732acdefc 100644
> --- a/include/uapi/linux/videodev2.h
> +++ b/include/uapi/linux/videodev2.h
> @@ -657,6 +657,7 @@ struct v4l2_pix_format {
> #define V4L2_PIX_FMT_H264 v4l2_fourcc('H', '2', '6', '4') /* H264 with start codes */
> #define V4L2_PIX_FMT_H264_NO_SC v4l2_fourcc('A', 'V', 'C', '1') /* H264 without start codes */
> #define V4L2_PIX_FMT_H264_MVC v4l2_fourcc('M', '2', '6', '4') /* H264 MVC */
> +#define V4L2_PIX_FMT_H264_SLICE_RAW v4l2_fourcc('S', '2', '6', '4') /* H264 parsed slices */
> #define V4L2_PIX_FMT_H263 v4l2_fourcc('H', '2', '6', '3') /* H263 */
> #define V4L2_PIX_FMT_MPEG1 v4l2_fourcc('M', 'P', 'G', '1') /* MPEG-1 ES */
> #define V4L2_PIX_FMT_MPEG2 v4l2_fourcc('M', 'P', 'G', '2') /* MPEG-2 ES */
--
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH] rtc: sirfsoc: Make sysrtc_regmap_config static
From: Yue Haibing @ 2019-04-10 13:43 UTC (permalink / raw)
To: a.zummo, alexandre.belloni, baohua
Cc: linux-rtc, YueHaibing, linux-kernel, linux-arm-kernel
From: YueHaibing <yuehaibing@huawei.com>
Fix sparse warning:
drivers/rtc/rtc-sirfsoc.c:282:28: warning:
symbol 'sysrtc_regmap_config' was not declared. Should it be static?
Reported-by: Hulk Robot <hulkci@huawei.com>
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
drivers/rtc/rtc-sirfsoc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/rtc/rtc-sirfsoc.c b/drivers/rtc/rtc-sirfsoc.c
index 2a9e151..9ba28d1 100644
--- a/drivers/rtc/rtc-sirfsoc.c
+++ b/drivers/rtc/rtc-sirfsoc.c
@@ -279,7 +279,7 @@ static const struct of_device_id sirfsoc_rtc_of_match[] = {
{},
};
-const struct regmap_config sysrtc_regmap_config = {
+static const struct regmap_config sysrtc_regmap_config = {
.reg_bits = 32,
.val_bits = 32,
.fast_io = true,
--
2.7.4
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH] rtc: sirfsoc: Make sysrtc_regmap_config static
From: Yue Haibing @ 2019-04-10 13:43 UTC (permalink / raw)
To: a.zummo, alexandre.belloni, baohua
Cc: linux-kernel, linux-arm-kernel, linux-rtc, YueHaibing
From: YueHaibing <yuehaibing@huawei.com>
Fix sparse warning:
drivers/rtc/rtc-sirfsoc.c:282:28: warning:
symbol 'sysrtc_regmap_config' was not declared. Should it be static?
Reported-by: Hulk Robot <hulkci@huawei.com>
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
drivers/rtc/rtc-sirfsoc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/rtc/rtc-sirfsoc.c b/drivers/rtc/rtc-sirfsoc.c
index 2a9e151..9ba28d1 100644
--- a/drivers/rtc/rtc-sirfsoc.c
+++ b/drivers/rtc/rtc-sirfsoc.c
@@ -279,7 +279,7 @@ static const struct of_device_id sirfsoc_rtc_of_match[] = {
{},
};
-const struct regmap_config sysrtc_regmap_config = {
+static const struct regmap_config sysrtc_regmap_config = {
.reg_bits = 32,
.val_bits = 32,
.fast_io = true,
--
2.7.4
^ permalink raw reply related
* Re: [PATCH v8 1/2] media: uapi: Add H264 low-level decoder API compound controls.
From: Paul Kocialkowski @ 2019-04-10 13:44 UTC (permalink / raw)
To: Maxime Ripard, hans.verkuil, acourbot, sakari.ailus,
Laurent Pinchart
Cc: tfiga, posciak, Chen-Yu Tsai, linux-kernel, linux-arm-kernel,
linux-media, nicolas.dufresne, jenskuske, jernej.skrabec, jonas,
ezequiel, linux-sunxi, Thomas Petazzoni, Guenter Roeck
In-Reply-To: <f537c99d8b5a974f8687f4f0d018c025a4220f7a.1554382670.git-series.maxime.ripard@bootlin.com>
Hi,
Le jeudi 04 avril 2019 à 14:59 +0200, Maxime Ripard a écrit :
> From: Pawel Osciak <posciak@chromium.org>
>
> Stateless video codecs will require both the H264 metadata and slices in
> order to be able to decode frames.
>
> This introduces the definitions for a new pixel format for H264 slices that
> have been parsed, as well as the structures used to pass the metadata from
> the userspace to the kernel.
With V4L2_PIX_FMT_H264_SLICE_RAW renamed to V4L2_PIX_FMT_H264_SLICE and
moved to the private h264-ctrls.h, this is:
Reviewed-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Cheers,
Paul
> Reviewed-by: Tomasz Figa <tfiga@chromium.org>
> Signed-off-by: Pawel Osciak <posciak@chromium.org>
> Signed-off-by: Guenter Roeck <groeck@chromium.org>
> Co-developed-by: Maxime Ripard <maxime.ripard@bootlin.com>
> Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> ---
> Documentation/media/uapi/v4l/biblio.rst | 9 +-
> Documentation/media/uapi/v4l/ext-ctrls-codec.rst | 569 ++++++++++++++-
> Documentation/media/uapi/v4l/pixfmt-compressed.rst | 19 +-
> Documentation/media/uapi/v4l/vidioc-queryctrl.rst | 30 +-
> Documentation/media/videodev2.h.rst.exceptions | 5 +-
> drivers/media/v4l2-core/v4l2-ctrls.c | 42 +-
> drivers/media/v4l2-core/v4l2-ioctl.c | 1 +-
> include/media/h264-ctrls.h | 192 +++++-
> include/media/v4l2-ctrls.h | 13 +-
> include/uapi/linux/videodev2.h | 1 +-
> 10 files changed, 880 insertions(+), 1 deletion(-)
> create mode 100644 include/media/h264-ctrls.h
>
> diff --git a/Documentation/media/uapi/v4l/biblio.rst b/Documentation/media/uapi/v4l/biblio.rst
> index ec33768c055e..8f4eb8823d82 100644
> --- a/Documentation/media/uapi/v4l/biblio.rst
> +++ b/Documentation/media/uapi/v4l/biblio.rst
> @@ -122,6 +122,15 @@ ITU BT.1119
>
> :author: International Telecommunication Union (http://www.itu.ch)
>
> +.. _h264:
> +
> +ITU-T Rec. H.264 Specification (04/2017 Edition)
> +================================================
> +
> +:title: ITU-T Recommendation H.264 "Advanced Video Coding for Generic Audiovisual Services"
> +
> +:author: International Telecommunication Union (http://www.itu.ch)
> +
> .. _jfif:
>
> JFIF
> diff --git a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
> index 67a122339c0e..fe720f239f70 100644
> --- a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
> +++ b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst
> @@ -1371,6 +1371,575 @@ enum v4l2_mpeg_video_h264_hierarchical_coding_type -
> - Layer number
>
>
> +.. _v4l2-mpeg-h264:
> +
> +``V4L2_CID_MPEG_VIDEO_H264_SPS (struct)``
> + Specifies the sequence parameter set (as extracted from the
> + bitstream) for the associated H264 slice data. This includes the
> + necessary parameters for configuring a stateless hardware decoding
> + pipeline for H264. The bitstream parameters are defined according
> + to :ref:`h264`, section 7.4.2.1.1 "Sequence Parameter Set Data
> + Semantics". For further documentation, refer to the above
> + specification, unless there is an explicit comment stating
> + otherwise.
> +
> + .. note::
> +
> + This compound control is not yet part of the public kernel API and
> + it is expected to change.
> +
> +.. c:type:: v4l2_ctrl_h264_sps
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_ctrl_h264_sps
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u8
> + - ``profile_idc``
> + -
> + * - __u8
> + - ``constraint_set_flags``
> + - See :ref:`Sequence Parameter Set Constraints Set Flags <h264_sps_constraints_set_flags>`
> + * - __u8
> + - ``level_idc``
> + -
> + * - __u8
> + - ``seq_parameter_set_id``
> + -
> + * - __u8
> + - ``chroma_format_idc``
> + -
> + * - __u8
> + - ``bit_depth_luma_minus8``
> + -
> + * - __u8
> + - ``bit_depth_chroma_minus8``
> + -
> + * - __u8
> + - ``log2_max_frame_num_minus4``
> + -
> + * - __u8
> + - ``pic_order_cnt_type``
> + -
> + * - __u8
> + - ``log2_max_pic_order_cnt_lsb_minus4``
> + -
> + * - __u8
> + - ``max_num_ref_frames``
> + -
> + * - __u8
> + - ``num_ref_frames_in_pic_order_cnt_cycle``
> + -
> + * - __s32
> + - ``offset_for_ref_frame[255]``
> + -
> + * - __s32
> + - ``offset_for_non_ref_pic``
> + -
> + * - __s32
> + - ``offset_for_top_to_bottom_field``
> + -
> + * - __u16
> + - ``pic_width_in_mbs_minus1``
> + -
> + * - __u16
> + - ``pic_height_in_map_units_minus1``
> + -
> + * - __u32
> + - ``flags``
> + - See :ref:`Sequence Parameter Set Flags <h264_sps_flags>`
> +
> +.. _h264_sps_constraints_set_flags:
> +
> +``Sequence Parameter Set Constraints Set Flags``
> +
> +.. cssclass:: longtable
> +
> +.. flat-table::
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - ``V4L2_H264_SPS_CONSTRAINT_SET0_FLAG``
> + - 0x00000001
> + -
> + * - ``V4L2_H264_SPS_CONSTRAINT_SET1_FLAG``
> + - 0x00000002
> + -
> + * - ``V4L2_H264_SPS_CONSTRAINT_SET2_FLAG``
> + - 0x00000004
> + -
> + * - ``V4L2_H264_SPS_CONSTRAINT_SET3_FLAG``
> + - 0x00000008
> + -
> + * - ``V4L2_H264_SPS_CONSTRAINT_SET4_FLAG``
> + - 0x00000010
> + -
> + * - ``V4L2_H264_SPS_CONSTRAINT_SET5_FLAG``
> + - 0x00000020
> + -
> +
> +.. _h264_sps_flags:
> +
> +``Sequence Parameter Set Flags``
> +
> +.. cssclass:: longtable
> +
> +.. flat-table::
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - ``V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE``
> + - 0x00000001
> + -
> + * - ``V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS``
> + - 0x00000002
> + -
> + * - ``V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO``
> + - 0x00000004
> + -
> + * - ``V4L2_H264_SPS_FLAG_GAPS_IN_FRAME_NUM_VALUE_ALLOWED``
> + - 0x00000008
> + -
> + * - ``V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY``
> + - 0x00000010
> + -
> + * - ``V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD``
> + - 0x00000020
> + -
> + * - ``V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE``
> + - 0x00000040
> + -
> +
> +``V4L2_CID_MPEG_VIDEO_H264_PPS (struct)``
> + Specifies the picture parameter set (as extracted from the
> + bitstream) for the associated H264 slice data. This includes the
> + necessary parameters for configuring a stateless hardware decoding
> + pipeline for H264. The bitstream parameters are defined according
> + to :ref:`h264`, section 7.4.2.2 "Picture Parameter Set RBSP
> + Semantics". For further documentation, refer to the above
> + specification, unless there is an explicit comment stating
> + otherwise.
> +
> + .. note::
> +
> + This compound control is not yet part of the public kernel API and
> + it is expected to change.
> +
> +.. c:type:: v4l2_ctrl_h264_pps
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_ctrl_h264_pps
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u8
> + - ``pic_parameter_set_id``
> + -
> + * - __u8
> + - ``seq_parameter_set_id``
> + -
> + * - __u8
> + - ``num_slice_groups_minus1``
> + -
> + * - __u8
> + - ``num_ref_idx_l0_default_active_minus1``
> + -
> + * - __u8
> + - ``num_ref_idx_l1_default_active_minus1``
> + -
> + * - __u8
> + - ``weighted_bipred_idc``
> + -
> + * - __s8
> + - ``pic_init_qp_minus26``
> + -
> + * - __s8
> + - ``pic_init_qs_minus26``
> + -
> + * - __s8
> + - ``chroma_qp_index_offset``
> + -
> + * - __s8
> + - ``second_chroma_qp_index_offset``
> + -
> + * - __u16
> + - ``flags``
> + - See :ref:`Picture Parameter Set Flags <h264_pps_flags>`
> +
> +.. _h264_pps_flags:
> +
> +``Picture Parameter Set Flags``
> +
> +.. cssclass:: longtable
> +
> +.. flat-table::
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - ``V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE``
> + - 0x00000001
> + -
> + * - ``V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT``
> + - 0x00000002
> + -
> + * - ``V4L2_H264_PPS_FLAG_WEIGHTED_PRED``
> + - 0x00000004
> + -
> + * - ``V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT``
> + - 0x00000008
> + -
> + * - ``V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED``
> + - 0x00000010
> + -
> + * - ``V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT``
> + - 0x00000020
> + -
> + * - ``V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE``
> + - 0x00000040
> + -
> + * - ``V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT``
> + - 0x00000080
> + -
> +
> +``V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX (struct)``
> + Specifies the scaling matrix (as extracted from the bitstream) for
> + the associated H264 slice data. The bitstream parameters are
> + defined according to :ref:`h264`, section 7.4.2.1.1.1 "Scaling
> + List Semantics".For further documentation, refer to the above
> + specification, unless there is an explicit comment stating
> + otherwise.
> +
> + .. note::
> +
> + This compound control is not yet part of the public kernel API and
> + it is expected to change.
> +
> +.. c:type:: v4l2_ctrl_h264_scaling_matrix
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_ctrl_h264_scaling_matrix
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u8
> + - ``scaling_list_4x4[6][16]``
> + -
> + * - __u8
> + - ``scaling_list_8x8[6][64]``
> + -
> +
> +``V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS (struct)``
> + Specifies the slice parameters (as extracted from the bitstream)
> + for the associated H264 slice data. This includes the necessary
> + parameters for configuring a stateless hardware decoding pipeline
> + for H264. The bitstream parameters are defined according to
> + :ref:`h264`, section 7.4.3 "Slice Header Semantics". For further
> + documentation, refer to the above specification, unless there is
> + an explicit comment stating otherwise.
> +
> + .. note::
> +
> + This compound control is not yet part of the public kernel API
> + and it is expected to change.
> +
> + This structure is expected to be passed as an array, with one
> + entry for each slice included in the bitstream buffer.
> +
> +.. c:type:: v4l2_ctrl_h264_slice_params
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_ctrl_h264_slice_params
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u32
> + - ``size``
> + -
> + * - __u32
> + - ``header_bit_size``
> + -
> + * - __u16
> + - ``first_mb_in_slice``
> + -
> + * - __u8
> + - ``slice_type``
> + -
> + * - __u8
> + - ``pic_parameter_set_id``
> + -
> + * - __u8
> + - ``colour_plane_id``
> + -
> + * - __u8
> + - ``redundant_pic_cnt``
> + -
> + * - __u16
> + - ``frame_num``
> + -
> + * - __u16
> + - ``idr_pic_id``
> + -
> + * - __u16
> + - ``pic_order_cnt_lsb``
> + -
> + * - __s32
> + - ``delta_pic_order_cnt_bottom``
> + -
> + * - __s32
> + - ``delta_pic_order_cnt0``
> + -
> + * - __s32
> + - ``delta_pic_order_cnt1``
> + -
> + * - struct :c:type:`v4l2_h264_pred_weight_table`
> + - ``pred_weight_table``
> + -
> + * - __u32
> + - ``dec_ref_pic_marking_bit_size``
> + -
> + * - __u32
> + - ``pic_order_cnt_bit_size``
> + -
> + * - __u8
> + - ``cabac_init_idc``
> + -
> + * - __s8
> + - ``slice_qp_delta``
> + -
> + * - __s8
> + - ``slice_qs_delta``
> + -
> + * - __u8
> + - ``disable_deblocking_filter_idc``
> + -
> + * - __s8
> + - ``slice_alpha_c0_offset_div2``
> + -
> + * - __s8
> + - ``slice_beta_offset_div2``
> + -
> + * - __u8
> + - ``num_ref_idx_l0_active_minus1``
> + -
> + * - __u8
> + - ``num_ref_idx_l1_active_minus1``
> + -
> + * - __u32
> + - ``slice_group_change_cycle``
> + -
> + * - __u8
> + - ``ref_pic_list0[32]``
> + - Reference picture list after applying the per-slice modifications
> + * - __u8
> + - ``ref_pic_list1[32]``
> + - Reference picture list after applying the per-slice modifications
> + * - __u32
> + - ``flags``
> + - See :ref:`Slice Parameter Flags <h264_slice_flags>`
> +
> +.. _h264_slice_flags:
> +
> +``Slice Parameter Set Flags``
> +
> +.. cssclass:: longtable
> +
> +.. flat-table::
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - ``V4L2_H264_SLICE_FLAG_FIELD_PIC``
> + - 0x00000001
> + -
> + * - ``V4L2_H264_SLICE_FLAG_BOTTOM_FIELD``
> + - 0x00000002
> + -
> + * - ``V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED``
> + - 0x00000004
> + -
> + * - ``V4L2_H264_SLICE_FLAG_SP_FOR_SWITCH``
> + - 0x00000008
> + -
> +
> +``Prediction Weight Table``
> +
> + The bitstream parameters are defined according to :ref:`h264`,
> + section 7.4.3.2 "Prediction Weight Table Semantics". For further
> + documentation, refer to the above specification, unless there is
> + an explicit comment stating otherwise.
> +
> +.. c:type:: v4l2_h264_pred_weight_table
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_h264_pred_weight_table
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u16
> + - ``luma_log2_weight_denom``
> + -
> + * - __u16
> + - ``chroma_log2_weight_denom``
> + -
> + * - struct :c:type:`v4l2_h264_weight_factors`
> + - ``weight_factors[2]``
> + - The weight factors at index 0 are the weight factors for the reference
> + list 0, the one at index 1 for the reference list 1.
> +
> +.. c:type:: v4l2_h264_weight_factors
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_h264_weight_factors
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __s16
> + - ``luma_weight[32]``
> + -
> + * - __s16
> + - ``luma_offset[32]``
> + -
> + * - __s16
> + - ``chroma_weight[32][2]``
> + -
> + * - __s16
> + - ``chroma_offset[32][2]``
> + -
> +
> +``V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS (struct)``
> + Specifies the decode parameters (as extracted from the bitstream)
> + for the associated H264 slice data. This includes the necessary
> + parameters for configuring a stateless hardware decoding pipeline
> + for H264. The bitstream parameters are defined according to
> + :ref:`h264`. For further documentation, refer to the above
> + specification, unless there is an explicit comment stating
> + otherwise.
> +
> + .. note::
> +
> + This compound control is not yet part of the public kernel API and
> + it is expected to change.
> +
> +.. c:type:: v4l2_ctrl_h264_decode_params
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_ctrl_h264_decode_params
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u32
> + - ``num_slices``
> + - Number of slices needed to decode the current frame
> + * - __u32
> + - ``nal_ref_idc``
> + - NAL reference ID value coming from the NAL Unit header
> + * - __u8
> + - ``ref_pic_list_p0[32]``
> + - Backward reference list used by P-frames in the original bitstream order
> + * - __u8
> + - ``ref_pic_list_b0[32]``
> + - Backward reference list used by B-frames in the original bitstream order
> + * - __u8
> + - ``ref_pic_list_b1[32]``
> + - Forward reference list used by B-frames in the original bitstream order
> + * - __s32
> + - ``top_field_order_cnt``
> + - Picture Order Count for the coded top field
> + * - __s32
> + - ``bottom_field_order_cnt``
> + - Picture Order Count for the coded bottom field
> + * - __u32
> + - ``flags``
> + - See :ref:`Decode Parameters Flags <h264_decode_params_flags>`
> + * - struct :c:type:`v4l2_h264_dpb_entry`
> + - ``dpb[16]``
> + -
> +
> +.. _h264_decode_params_flags:
> +
> +``Decode Parameters Flags``
> +
> +.. cssclass:: longtable
> +
> +.. flat-table::
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - ``V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC``
> + - 0x00000001
> + - That picture is an IDR picture
> +
> +.. c:type:: v4l2_h264_dpb_entry
> +
> +.. cssclass:: longtable
> +
> +.. flat-table:: struct v4l2_h264_dpb_entry
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - __u64
> + - ``reference_ts``
> + - Timestamp of the V4L2 capture buffer to use as reference, used
> + with B-coded and P-coded frames. The timestamp refers to the
> + ``timestamp`` field in struct :c:type:`v4l2_buffer`. Use the
> + :c:func:`v4l2_timeval_to_ns()` function to convert the struct
> + :c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64.
> + * - __u16
> + - ``frame_num``
> + -
> + * - __u16
> + - ``pic_num``
> + -
> + * - __s32
> + - ``top_field_order_cnt``
> + -
> + * - __s32
> + - ``bottom_field_order_cnt``
> + -
> + * - __u32
> + - ``flags``
> + - See :ref:`DPB Entry Flags <h264_dpb_flags>`
> +
> +.. _h264_dpb_flags:
> +
> +``DPB Entries Flags``
> +
> +.. cssclass:: longtable
> +
> +.. flat-table::
> + :header-rows: 0
> + :stub-columns: 0
> + :widths: 1 1 2
> +
> + * - ``V4L2_H264_DPB_ENTRY_FLAG_VALID``
> + - 0x00000001
> + - The DPB entry is valid and should be considered
> + * - ``V4L2_H264_DPB_ENTRY_FLAG_ACTIVE``
> + - 0x00000002
> + - The DPB entry is currently being used as a reference frame
> + * - ``V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM``
> + - 0x00000004
> + - The DPB entry is a long term reference frame
>
> .. _v4l2-mpeg-mpeg2:
>
> diff --git a/Documentation/media/uapi/v4l/pixfmt-compressed.rst b/Documentation/media/uapi/v4l/pixfmt-compressed.rst
> index 6c961cfb74da..ea0a8a68759b 100644
> --- a/Documentation/media/uapi/v4l/pixfmt-compressed.rst
> +++ b/Documentation/media/uapi/v4l/pixfmt-compressed.rst
> @@ -52,6 +52,25 @@ Compressed Formats
> - ``V4L2_PIX_FMT_H264_MVC``
> - 'M264'
> - H264 MVC video elementary stream.
> + * .. _V4L2-PIX-FMT-H264-SLICE:
> +
> + - ``V4L2_PIX_FMT_H264_SLICE_RAW``
> + - 'S264'
> + - H264 parsed slice data, as extracted from the H264 bitstream.
> + This format is adapted for stateless video decoders that
> + implement an H264 pipeline (using the :ref:`codec` and
> + :ref:`media-request-api`). Metadata associated with the frame
> + to decode are required to be passed through the
> + ``V4L2_CID_MPEG_VIDEO_H264_SPS``,
> + ``V4L2_CID_MPEG_VIDEO_H264_PPS``,
> + ``V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX``,
> + ``V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS`` and
> + ``V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS`` controls. See the
> + :ref:`associated Codec Control IDs <v4l2-mpeg-h264>`.
> + Exactly one output and one capture buffer must be provided for
> + use with this pixel format. The output buffer must contain the
> + appropriate number of macroblocks to decode a full
> + corresponding frame to the matching capture buffer.
> * .. _V4L2-PIX-FMT-H263:
>
> - ``V4L2_PIX_FMT_H263``
> diff --git a/Documentation/media/uapi/v4l/vidioc-queryctrl.rst b/Documentation/media/uapi/v4l/vidioc-queryctrl.rst
> index f824162d0ea9..dc500632095d 100644
> --- a/Documentation/media/uapi/v4l/vidioc-queryctrl.rst
> +++ b/Documentation/media/uapi/v4l/vidioc-queryctrl.rst
> @@ -443,6 +443,36 @@ See also the examples in :ref:`control`.
> - n/a
> - A struct :c:type:`v4l2_ctrl_mpeg2_quantization`, containing MPEG-2
> quantization matrices for stateless video decoders.
> + * - ``V4L2_CTRL_TYPE_H264_SPS``
> + - n/a
> + - n/a
> + - n/a
> + - A struct :c:type:`v4l2_ctrl_h264_sps`, containing H264
> + sequence parameters for stateless video decoders.
> + * - ``V4L2_CTRL_TYPE_H264_PPS``
> + - n/a
> + - n/a
> + - n/a
> + - A struct :c:type:`v4l2_ctrl_h264_pps`, containing H264
> + picture parameters for stateless video decoders.
> + * - ``V4L2_CTRL_TYPE_H264_SCALING_MATRIX``
> + - n/a
> + - n/a
> + - n/a
> + - A struct :c:type:`v4l2_ctrl_h264_scaling_matrix`, containing H264
> + scaling matrices for stateless video decoders.
> + * - ``V4L2_CTRL_TYPE_H264_SLICE_PARAMS``
> + - n/a
> + - n/a
> + - n/a
> + - A struct :c:type:`v4l2_ctrl_h264_slice_params`, containing H264
> + slice parameters for stateless video decoders.
> + * - ``V4L2_CTRL_TYPE_H264_DECODE_PARAMS``
> + - n/a
> + - n/a
> + - n/a
> + - A struct :c:type:`v4l2_ctrl_h264_decode_params`, containing H264
> + decode parameters for stateless video decoders.
>
> .. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
>
> diff --git a/Documentation/media/videodev2.h.rst.exceptions b/Documentation/media/videodev2.h.rst.exceptions
> index 64d348e67df9..55cbe324b9fc 100644
> --- a/Documentation/media/videodev2.h.rst.exceptions
> +++ b/Documentation/media/videodev2.h.rst.exceptions
> @@ -136,6 +136,11 @@ replace symbol V4L2_CTRL_TYPE_U32 :c:type:`v4l2_ctrl_type`
> replace symbol V4L2_CTRL_TYPE_U8 :c:type:`v4l2_ctrl_type`
> replace symbol V4L2_CTRL_TYPE_MPEG2_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
> replace symbol V4L2_CTRL_TYPE_MPEG2_QUANTIZATION :c:type:`v4l2_ctrl_type`
> +replace symbol V4L2_CTRL_TYPE_H264_SPS :c:type:`v4l2_ctrl_type`
> +replace symbol V4L2_CTRL_TYPE_H264_PPS :c:type:`v4l2_ctrl_type`
> +replace symbol V4L2_CTRL_TYPE_H264_SCALING_MATRIX :c:type:`v4l2_ctrl_type`
> +replace symbol V4L2_CTRL_TYPE_H264_SLICE_PARAMS :c:type:`v4l2_ctrl_type`
> +replace symbol V4L2_CTRL_TYPE_H264_DECODE_PARAMS :c:type:`v4l2_ctrl_type`
>
> # V4L2 capability defines
> replace define V4L2_CAP_VIDEO_CAPTURE device-capabilities
> diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
> index b1ae2e555c68..46aec8c3acde 100644
> --- a/drivers/media/v4l2-core/v4l2-ctrls.c
> +++ b/drivers/media/v4l2-core/v4l2-ctrls.c
> @@ -828,6 +828,11 @@ const char *v4l2_ctrl_get_name(u32 id)
> case V4L2_CID_MPEG_VIDEO_H264_CONSTRAINED_INTRA_PREDICTION:
> return "H264 Constrained Intra Pred";
> case V4L2_CID_MPEG_VIDEO_H264_CHROMA_QP_INDEX_OFFSET: return "H264 Chroma QP Index Offset";
> + case V4L2_CID_MPEG_VIDEO_H264_SPS: return "H264 Sequence Parameter Set";
> + case V4L2_CID_MPEG_VIDEO_H264_PPS: return "H264 Picture Parameter Set";
> + case V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX: return "H264 Scaling Matrix";
> + case V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS: return "H264 Slice Parameters";
> + case V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS: return "H264 Decode Parameters";
> case V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP: return "MPEG4 I-Frame QP Value";
> case V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP: return "MPEG4 P-Frame QP Value";
> case V4L2_CID_MPEG_VIDEO_MPEG4_B_FRAME_QP: return "MPEG4 B-Frame QP Value";
> @@ -1309,6 +1314,21 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
> case V4L2_CID_MPEG_VIDEO_FWHT_PARAMS:
> *type = V4L2_CTRL_TYPE_FWHT_PARAMS;
> break;
> + case V4L2_CID_MPEG_VIDEO_H264_SPS:
> + *type = V4L2_CTRL_TYPE_H264_SPS;
> + break;
> + case V4L2_CID_MPEG_VIDEO_H264_PPS:
> + *type = V4L2_CTRL_TYPE_H264_PPS;
> + break;
> + case V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX:
> + *type = V4L2_CTRL_TYPE_H264_SCALING_MATRIX;
> + break;
> + case V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS:
> + *type = V4L2_CTRL_TYPE_H264_SLICE_PARAMS;
> + break;
> + case V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS:
> + *type = V4L2_CTRL_TYPE_H264_DECODE_PARAMS;
> + break;
> default:
> *type = V4L2_CTRL_TYPE_INTEGER;
> break;
> @@ -1678,6 +1698,13 @@ static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx,
> case V4L2_CTRL_TYPE_FWHT_PARAMS:
> return 0;
>
> + case V4L2_CTRL_TYPE_H264_SPS:
> + case V4L2_CTRL_TYPE_H264_PPS:
> + case V4L2_CTRL_TYPE_H264_SCALING_MATRIX:
> + case V4L2_CTRL_TYPE_H264_SLICE_PARAMS:
> + case V4L2_CTRL_TYPE_H264_DECODE_PARAMS:
> + return 0;
> +
> default:
> return -EINVAL;
> }
> @@ -2261,6 +2288,21 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
> case V4L2_CTRL_TYPE_FWHT_PARAMS:
> elem_size = sizeof(struct v4l2_ctrl_fwht_params);
> break;
> + case V4L2_CTRL_TYPE_H264_SPS:
> + elem_size = sizeof(struct v4l2_ctrl_h264_sps);
> + break;
> + case V4L2_CTRL_TYPE_H264_PPS:
> + elem_size = sizeof(struct v4l2_ctrl_h264_pps);
> + break;
> + case V4L2_CTRL_TYPE_H264_SCALING_MATRIX:
> + elem_size = sizeof(struct v4l2_ctrl_h264_scaling_matrix);
> + break;
> + case V4L2_CTRL_TYPE_H264_SLICE_PARAMS:
> + elem_size = sizeof(struct v4l2_ctrl_h264_slice_params);
> + break;
> + case V4L2_CTRL_TYPE_H264_DECODE_PARAMS:
> + elem_size = sizeof(struct v4l2_ctrl_h264_decode_params);
> + break;
> default:
> if (type < V4L2_CTRL_COMPOUND_TYPES)
> elem_size = sizeof(s32);
> diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
> index ac87c3e37280..f6e1254064d2 100644
> --- a/drivers/media/v4l2-core/v4l2-ioctl.c
> +++ b/drivers/media/v4l2-core/v4l2-ioctl.c
> @@ -1325,6 +1325,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
> case V4L2_PIX_FMT_H264: descr = "H.264"; break;
> case V4L2_PIX_FMT_H264_NO_SC: descr = "H.264 (No Start Codes)"; break;
> case V4L2_PIX_FMT_H264_MVC: descr = "H.264 MVC"; break;
> + case V4L2_PIX_FMT_H264_SLICE_RAW: descr = "H.264 Parsed Slice Data"; break;
> case V4L2_PIX_FMT_H263: descr = "H.263"; break;
> case V4L2_PIX_FMT_MPEG1: descr = "MPEG-1 ES"; break;
> case V4L2_PIX_FMT_MPEG2: descr = "MPEG-2 ES"; break;
> diff --git a/include/media/h264-ctrls.h b/include/media/h264-ctrls.h
> new file mode 100644
> index 000000000000..e2f83b3cdbef
> --- /dev/null
> +++ b/include/media/h264-ctrls.h
> @@ -0,0 +1,192 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * These are the H.264 state controls for use with stateless H.264
> + * codec drivers.
> + *
> + * It turns out that these structs are not stable yet and will undergo
> + * more changes. So keep them private until they are stable and ready to
> + * become part of the official public API.
> + */
> +
> +#ifndef _H264_CTRLS_H_
> +#define _H264_CTRLS_H_
> +
> +/*
> + * This is put insanely high to avoid conflicting with controls that
> + * would be added during the phase where those controls are not
> + * stable. It should be fixed eventually.
> + */
> +#define V4L2_CID_MPEG_VIDEO_H264_SPS (V4L2_CID_MPEG_BASE+1000)
> +#define V4L2_CID_MPEG_VIDEO_H264_PPS (V4L2_CID_MPEG_BASE+1001)
> +#define V4L2_CID_MPEG_VIDEO_H264_SCALING_MATRIX (V4L2_CID_MPEG_BASE+1002)
> +#define V4L2_CID_MPEG_VIDEO_H264_SLICE_PARAMS (V4L2_CID_MPEG_BASE+1003)
> +#define V4L2_CID_MPEG_VIDEO_H264_DECODE_PARAMS (V4L2_CID_MPEG_BASE+1004)
> +
> +/* enum v4l2_ctrl_type type values */
> +#define V4L2_CTRL_TYPE_H264_SPS 0x0110
> +#define V4L2_CTRL_TYPE_H264_PPS 0x0111
> +#define V4L2_CTRL_TYPE_H264_SCALING_MATRIX 0x0112
> +#define V4L2_CTRL_TYPE_H264_SLICE_PARAMS 0x0113
> +#define V4L2_CTRL_TYPE_H264_DECODE_PARAMS 0x0114
> +
> +#define V4L2_H264_SPS_CONSTRAINT_SET0_FLAG 0x01
> +#define V4L2_H264_SPS_CONSTRAINT_SET1_FLAG 0x02
> +#define V4L2_H264_SPS_CONSTRAINT_SET2_FLAG 0x04
> +#define V4L2_H264_SPS_CONSTRAINT_SET3_FLAG 0x08
> +#define V4L2_H264_SPS_CONSTRAINT_SET4_FLAG 0x10
> +#define V4L2_H264_SPS_CONSTRAINT_SET5_FLAG 0x20
> +
> +#define V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE 0x01
> +#define V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS 0x02
> +#define V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO 0x04
> +#define V4L2_H264_SPS_FLAG_GAPS_IN_FRAME_NUM_VALUE_ALLOWED 0x08
> +#define V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY 0x10
> +#define V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD 0x20
> +#define V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE 0x40
> +
> +struct v4l2_ctrl_h264_sps {
> + __u8 profile_idc;
> + __u8 constraint_set_flags;
> + __u8 level_idc;
> + __u8 seq_parameter_set_id;
> + __u8 chroma_format_idc;
> + __u8 bit_depth_luma_minus8;
> + __u8 bit_depth_chroma_minus8;
> + __u8 log2_max_frame_num_minus4;
> + __u8 pic_order_cnt_type;
> + __u8 log2_max_pic_order_cnt_lsb_minus4;
> + __u8 max_num_ref_frames;
> + __u8 num_ref_frames_in_pic_order_cnt_cycle;
> + __s32 offset_for_ref_frame[255];
> + __s32 offset_for_non_ref_pic;
> + __s32 offset_for_top_to_bottom_field;
> + __u16 pic_width_in_mbs_minus1;
> + __u16 pic_height_in_map_units_minus1;
> + __u32 flags;
> +};
> +
> +#define V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE 0x0001
> +#define V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT 0x0002
> +#define V4L2_H264_PPS_FLAG_WEIGHTED_PRED 0x0004
> +#define V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT 0x0008
> +#define V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED 0x0010
> +#define V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT 0x0020
> +#define V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE 0x0040
> +#define V4L2_H264_PPS_FLAG_PIC_SCALING_MATRIX_PRESENT 0x0080
> +
> +struct v4l2_ctrl_h264_pps {
> + __u8 pic_parameter_set_id;
> + __u8 seq_parameter_set_id;
> + __u8 num_slice_groups_minus1;
> + __u8 num_ref_idx_l0_default_active_minus1;
> + __u8 num_ref_idx_l1_default_active_minus1;
> + __u8 weighted_bipred_idc;
> + __s8 pic_init_qp_minus26;
> + __s8 pic_init_qs_minus26;
> + __s8 chroma_qp_index_offset;
> + __s8 second_chroma_qp_index_offset;
> + __u16 flags;
> +};
> +
> +struct v4l2_ctrl_h264_scaling_matrix {
> + __u8 scaling_list_4x4[6][16];
> + __u8 scaling_list_8x8[6][64];
> +};
> +
> +struct v4l2_h264_weight_factors {
> + __s16 luma_weight[32];
> + __s16 luma_offset[32];
> + __s16 chroma_weight[32][2];
> + __s16 chroma_offset[32][2];
> +};
> +
> +struct v4l2_h264_pred_weight_table {
> + __u16 luma_log2_weight_denom;
> + __u16 chroma_log2_weight_denom;
> + struct v4l2_h264_weight_factors weight_factors[2];
> +};
> +
> +#define V4L2_H264_SLICE_TYPE_P 0
> +#define V4L2_H264_SLICE_TYPE_B 1
> +#define V4L2_H264_SLICE_TYPE_I 2
> +#define V4L2_H264_SLICE_TYPE_SP 3
> +#define V4L2_H264_SLICE_TYPE_SI 4
> +
> +#define V4L2_H264_SLICE_FLAG_FIELD_PIC 0x01
> +#define V4L2_H264_SLICE_FLAG_BOTTOM_FIELD 0x02
> +#define V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED 0x04
> +#define V4L2_H264_SLICE_FLAG_SP_FOR_SWITCH 0x08
> +
> +struct v4l2_ctrl_h264_slice_params {
> + /* Size in bytes, including header */
> + __u32 size;
> + /* Offset in bits to slice_data() from the beginning of this slice. */
> + __u32 header_bit_size;
> +
> + __u16 first_mb_in_slice;
> + __u8 slice_type;
> + __u8 pic_parameter_set_id;
> + __u8 colour_plane_id;
> + __u8 redundant_pic_cnt;
> + __u16 frame_num;
> + __u16 idr_pic_id;
> + __u16 pic_order_cnt_lsb;
> + __s32 delta_pic_order_cnt_bottom;
> + __s32 delta_pic_order_cnt0;
> + __s32 delta_pic_order_cnt1;
> +
> + struct v4l2_h264_pred_weight_table pred_weight_table;
> + /* Size in bits of dec_ref_pic_marking() syntax element. */
> + __u32 dec_ref_pic_marking_bit_size;
> + /* Size in bits of pic order count syntax. */
> + __u32 pic_order_cnt_bit_size;
> +
> + __u8 cabac_init_idc;
> + __s8 slice_qp_delta;
> + __s8 slice_qs_delta;
> + __u8 disable_deblocking_filter_idc;
> + __s8 slice_alpha_c0_offset_div2;
> + __s8 slice_beta_offset_div2;
> + __u8 num_ref_idx_l0_active_minus1;
> + __u8 num_ref_idx_l1_active_minus1;
> + __u32 slice_group_change_cycle;
> +
> + /*
> + * Entries on each list are indices into
> + * v4l2_ctrl_h264_decode_params.dpb[].
> + */
> + __u8 ref_pic_list0[32];
> + __u8 ref_pic_list1[32];
> +
> + __u32 flags;
> +};
> +
> +#define V4L2_H264_DPB_ENTRY_FLAG_VALID 0x01
> +#define V4L2_H264_DPB_ENTRY_FLAG_ACTIVE 0x02
> +#define V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM 0x04
> +
> +struct v4l2_h264_dpb_entry {
> + __u64 reference_ts;
> + __u16 frame_num;
> + __u16 pic_num;
> + /* Note that field is indicated by v4l2_buffer.field */
> + __s32 top_field_order_cnt;
> + __s32 bottom_field_order_cnt;
> + __u32 flags; /* V4L2_H264_DPB_ENTRY_FLAG_* */
> +};
> +
> +#define V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC 0x01
> +
> +struct v4l2_ctrl_h264_decode_params {
> + struct v4l2_h264_dpb_entry dpb[16];
> + __u16 num_slices;
> + __u16 nal_ref_idc;
> + __u8 ref_pic_list_p0[32];
> + __u8 ref_pic_list_b0[32];
> + __u8 ref_pic_list_b1[32];
> + __s32 top_field_order_cnt;
> + __s32 bottom_field_order_cnt;
> + __u32 flags; /* V4L2_H264_DECODE_PARAM_FLAG_* */
> +};
> +
> +#endif
> diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
> index bd621cec65a5..dce6f33fd749 100644
> --- a/include/media/v4l2-ctrls.h
> +++ b/include/media/v4l2-ctrls.h
> @@ -23,11 +23,12 @@
> #include <media/media-request.h>
>
> /*
> - * Include the mpeg2 and fwht stateless codec compound control definitions.
> + * Include the stateless codec compound control definitions.
> * This will move to the public headers once this API is fully stable.
> */
> #include <media/mpeg2-ctrls.h>
> #include <media/fwht-ctrls.h>
> +#include <media/h264-ctrls.h>
>
> /* forward references */
> struct file;
> @@ -51,6 +52,11 @@ struct poll_table_struct;
> * @p_mpeg2_slice_params: Pointer to a MPEG2 slice parameters structure.
> * @p_mpeg2_quantization: Pointer to a MPEG2 quantization data structure.
> * @p_fwht_params: Pointer to a FWHT stateless parameters structure.
> + * @p_h264_sps: Pointer to a struct v4l2_ctrl_h264_sps.
> + * @p_h264_pps: Pointer to a struct v4l2_ctrl_h264_pps.
> + * @p_h264_scaling_matrix: Pointer to a struct v4l2_ctrl_h264_scaling_matrix.
> + * @p_h264_slice_param: Pointer to a struct v4l2_ctrl_h264_slice_params.
> + * @p_h264_decode_param: Pointer to a struct v4l2_ctrl_h264_decode_params.
> * @p: Pointer to a compound value.
> */
> union v4l2_ctrl_ptr {
> @@ -63,6 +69,11 @@ union v4l2_ctrl_ptr {
> struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params;
> struct v4l2_ctrl_mpeg2_quantization *p_mpeg2_quantization;
> struct v4l2_ctrl_fwht_params *p_fwht_params;
> + struct v4l2_ctrl_h264_sps *p_h264_sps;
> + struct v4l2_ctrl_h264_pps *p_h264_pps;
> + struct v4l2_ctrl_h264_scaling_matrix *p_h264_scaling_matrix;
> + struct v4l2_ctrl_h264_slice_params *p_h264_slice_param;
> + struct v4l2_ctrl_h264_decode_params *p_h264_decode_param;
> void *p;
> };
>
> diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
> index 496e6453450c..838732acdefc 100644
> --- a/include/uapi/linux/videodev2.h
> +++ b/include/uapi/linux/videodev2.h
> @@ -657,6 +657,7 @@ struct v4l2_pix_format {
> #define V4L2_PIX_FMT_H264 v4l2_fourcc('H', '2', '6', '4') /* H264 with start codes */
> #define V4L2_PIX_FMT_H264_NO_SC v4l2_fourcc('A', 'V', 'C', '1') /* H264 without start codes */
> #define V4L2_PIX_FMT_H264_MVC v4l2_fourcc('M', '2', '6', '4') /* H264 MVC */
> +#define V4L2_PIX_FMT_H264_SLICE_RAW v4l2_fourcc('S', '2', '6', '4') /* H264 parsed slices */
> #define V4L2_PIX_FMT_H263 v4l2_fourcc('H', '2', '6', '3') /* H263 */
> #define V4L2_PIX_FMT_MPEG1 v4l2_fourcc('M', 'P', 'G', '1') /* MPEG-1 ES */
> #define V4L2_PIX_FMT_MPEG2 v4l2_fourcc('M', 'P', 'G', '2') /* MPEG-2 ES */
--
Paul Kocialkowski, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com
^ permalink raw reply
* [Bug 110381] Failed to updateMST allocation table forpipe idx:0
From: bugzilla-daemon @ 2019-04-10 13:44 UTC (permalink / raw)
To: dri-devel
[-- Attachment #1.1: Type: text/plain, Size: 6597 bytes --]
https://bugs.freedesktop.org/show_bug.cgi?id=110381
Bug ID: 110381
Summary: Failed to updateMST allocation table forpipe idx:0
Product: DRI
Version: XOrg git
Hardware: Other
OS: All
Status: NEW
Severity: normal
Priority: medium
Component: DRM/AMDgpu
Assignee: dri-devel@lists.freedesktop.org
Reporter: pmenzel+bugs.freedesktop.org@molgen.mpg.de
Created attachment 143918
--> https://bugs.freedesktop.org/attachment.cgi?id=143918&action=edit
Linux 5.1-rc4 messages (dmesg)
Using Linux 5.1-rc4, turning off the MST monitor Dell UP3214Q, and back on the
next day, nothing was shown, and Linux logged the messages below.
```
[…]
[108910.142836] [drm] DM_MST: stopping TM on aconnector: 00000000989f4d41 [id:
59]
[108910.142888] [drm] DM_MST: Disabling connector: 0000000082f81687 [id: 70]
[master: 00000000989f4d41]
[108910.142922] [drm] DM_MST: Disabling connector: 00000000129f9b45 [id: 84]
[master: 00000000989f4d41]
[108973.867216] usb 1-10: USB disconnect, device number 24
[174644.517901] [drm] DM_MST: starting TM on aconnector: 00000000989f4d41 [id:
59]
[174644.541360] [drm] DM_MST: added connector: 000000004c0a3cc0 [id: 89]
[master: 00000000989f4d41]
[174644.595463] [drm] SADs count is: -2, don't need to read it
[174644.935425] [drm] DM_MST: added connector: 00000000a88f0665 [id: 112]
[master: 00000000989f4d41]
[174645.191251] [drm] Failed to updateMST allocation table forpipe idx:0
[174645.201033] [drm] SADs count is: -2, don't need to read it
[174645.695078] WARNING: CPU: 2 PID: 404 at
drivers/gpu/drm/amd/amdgpu/../display/dc/core/dc_link.c:2354
update_mst_stream_alloc_table+0x144/0x150 [amdgpu]
[174645.695079] Modules linked in: dm_mod nls_iso8859_1 nls_cp437 vfat fat fuse
rpcsec_gss_krb5 nfsv4 nfs 8021q garp stp mrp llc snd_hda_codec_realtek
snd_hda_codec_generic i915 amdgpu input_leds led_class chash gpu_sched ttm
iosf_mbi x86_pkg_temp_thermal drm_kms_helper kvm_intel drm snd_hda_codec_hdmi
kvm snd_hda_intel snd_hda_codec intel_gtt fb_sys_fops wmi_bmof irqbypass
snd_hda_core syscopyarea sysfillrect snd_pcm snd_timer sysimgblt snd
crc32c_intel video soundcore wmi nfsd auth_rpcgss oid_registry nfs_acl lockd
grace sunrpc efivarfs ip_tables x_tables unix ipv6 autofs4
[174645.695091] CPU: 2 PID: 404 Comm: Xorg Kdump: loaded Tainted: G W
5.1.0-rc4.mx64.256 #1
[174645.695091] Hardware name: Dell Inc. Precision 3630 Tower/0NNNCT, BIOS
1.0.4 07/17/2018
[174645.695101] RIP: 0010:update_mst_stream_alloc_table+0x144/0x150 [amdgpu]
[174645.695102] Code: 63 d0 48 83 c2 13 48 c1 e2 04 4d 8b 4c 10 08 4d 8b 54 10
10 4d 89 0c 24 4d 89 54 24 08 39 c1 75 81 e9 67 ff ff ff 31 c0 eb f3 <0f> 0b e9
14 ff ff ff e8 90 45 95 e0 0f 1f 44 00 00 41 55 41 54 49
[174645.695103] RSP: 0018:ffffc900051df6b0 EFLAGS: 00010202
[174645.695103] RAX: 0000000000000002 RBX: ffff88833fc945c0 RCX:
0000000000000000
[174645.695103] RDX: ffffc900051df784 RSI: ffff88844c43b440 RDI:
ffffc900051df710
[174645.695104] RBP: ffffc900051df750 R08: ffff888469f16e00 R09:
ffff8883bf1a1000
[174645.695104] R10: ffffc900051df768 R11: ffffc900051df6b0 R12:
ffff888469f16e00
[174645.695104] R13: ffff88833fc94000 R14: 0000000000000002 R15:
ffff888452b6e000
[174645.695105] FS: 00007f9af42199c0(0000) GS:ffff88846c080000(0000)
knlGS:0000000000000000
[174645.695105] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[174645.695106] CR2: 00007f9ae44bf000 CR3: 00000002ed2c4001 CR4:
00000000003606e0
[174645.695106] DR0: 0000000000000000 DR1: 0000000000000000 DR2:
0000000000000000
[174645.695107] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7:
0000000000000400
[174645.695107] Call Trace:
[174645.695111] ? mutex_lock+0xe/0x30
[174645.695121] ? core_link_enable_stream+0x47a/0x1090 [amdgpu]
[174645.695130] core_link_enable_stream+0x47a/0x1090 [amdgpu]
[174645.695142] dce110_apply_ctx_to_hw+0x3f1/0x480 [amdgpu]
[174645.695154] ? dce110_apply_ctx_for_surface+0x250/0x2b0 [amdgpu]
[174645.695164] dc_commit_state+0x2d6/0x560 [amdgpu]
[174645.695169] ? drm_calc_timestamping_constants+0xe5/0x150 [drm]
[174645.695187] amdgpu_dm_atomic_commit_tail+0x388/0x1960 [amdgpu]
[174645.695204] ? bw_calcs+0x6f8/0x1cd0 [amdgpu]
[174645.695217] ? dce112_validate_bandwidth+0x3e/0x70 [amdgpu]
[174645.695226] ? dc_validate_global_state+0x2d4/0x360 [amdgpu]
[174645.695236] ? amdgpu_bo_pin_restricted+0x68/0x290 [amdgpu]
[174645.695237] ? _cond_resched+0x15/0x40
[174645.695238] ? wait_for_common+0x3d/0x180
[174645.695239] ? _cond_resched+0x15/0x40
[174645.695240] ? wait_for_common+0x3d/0x180
[174645.695257] ? dm_plane_helper_prepare_fb+0x117/0x370 [amdgpu]
[174645.695260] ? commit_tail+0x3d/0x70 [drm_kms_helper]
[174645.695262] commit_tail+0x3d/0x70 [drm_kms_helper]
[174645.695264] drm_atomic_helper_commit+0xfc/0x110 [drm_kms_helper]
[174645.695266] drm_atomic_helper_set_config+0x80/0x90 [drm_kms_helper]
[174645.695271] drm_mode_setcrtc+0x170/0x6c0 [drm]
[174645.695275] ? drm_mode_getcrtc+0x180/0x180 [drm]
[174645.695279] drm_ioctl_kernel+0x88/0xf0 [drm]
[174645.695281] ? try_to_wake_up+0x214/0x4d0
[174645.695283] drm_ioctl+0x2f8/0x3b0 [drm]
[174645.695287] ? drm_mode_getcrtc+0x180/0x180 [drm]
[174645.695295] amdgpu_drm_ioctl+0x49/0x80 [amdgpu]
[174645.695297] do_vfs_ioctl+0xa4/0x630
[174645.695298] ksys_ioctl+0x3a/0x70
[174645.695299] __x64_sys_ioctl+0x16/0x20
[174645.695300] do_syscall_64+0x48/0x100
[174645.695301] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[174645.695303] RIP: 0033:0x7f9af1d92647
[174645.695303] Code: 00 00 00 48 8b 05 41 58 2c 00 64 c7 00 26 00 00 00 48 c7
c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 b8 10 00 00 00 0f 05 <48> 3d 01
f0 ff ff 73 01 c3 48 8b 0d 11 58 2c 00 f7 d8 64 89 01 48
[174645.695304] RSP: 002b:00007ffdbd6659a8 EFLAGS: 00000246 ORIG_RAX:
0000000000000010
[174645.695305] RAX: ffffffffffffffda RBX: 00007ffdbd6659e0 RCX:
00007f9af1d92647
[174645.695305] RDX: 00007ffdbd6659e0 RSI: 00000000c06864a2 RDI:
000000000000000b
[174645.695305] RBP: 00007ffdbd6659e0 R08: 0000000000000000 R09:
000000000156a8e0
[174645.695306] R10: 00007ffdbd665aa0 R11: 0000000000000246 R12:
00000000c06864a2
[174645.695306] R13: 000000000000000b R14: 0000000000000000 R15:
000000000156a8e0
[174645.695307] ---[ end trace 61acd18b4e2a5a43 ]---
```
Please find the full log attached.
--
You are receiving this mail because:
You are the assignee for the bug.
[-- Attachment #1.2: Type: text/html, Size: 8059 bytes --]
[-- Attachment #2: Type: text/plain, Size: 159 bytes --]
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* Re: [PATCH 07/10] media: coda: limit frame interval enumeration to supported frame sizes
From: Hans Verkuil @ 2019-04-10 13:43 UTC (permalink / raw)
To: Philipp Zabel, linux-media; +Cc: kernel
In-Reply-To: <20190408123256.22868-7-p.zabel@pengutronix.de>
On 4/8/19 2:32 PM, Philipp Zabel wrote:
> Let VIDIOC_ENUM_FRAMEINTERVALS return -EINVAL if userspace queries
> frame intervals for unsupported frame sizes.
>
> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
> ---
> drivers/media/platform/coda/coda-common.c | 33 ++++++++++++++++++-----
> 1 file changed, 27 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c
> index 943f003c26c4..2966eb1c4d2d 100644
> --- a/drivers/media/platform/coda/coda-common.c
> +++ b/drivers/media/platform/coda/coda-common.c
> @@ -1117,7 +1117,8 @@ static int coda_enum_frameintervals(struct file *file, void *fh,
> struct v4l2_frmivalenum *f)
> {
> struct coda_ctx *ctx = fh_to_ctx(fh);
> - int i;
> + struct coda_q_data *q_data;
> + const struct coda_codec *codec;
>
> if (f->index)
> return -EINVAL;
> @@ -1126,12 +1127,32 @@ static int coda_enum_frameintervals(struct file *file, void *fh,
> if (!ctx->vdoa && f->pixel_format == V4L2_PIX_FMT_YUYV)
> return -EINVAL;
>
> - for (i = 0; i < CODA_MAX_FORMATS; i++) {
> - if (f->pixel_format == ctx->cvd->src_formats[i] ||
> - f->pixel_format == ctx->cvd->dst_formats[i])
> - break;
> + if (ctx->inst_type == CODA_INST_ENCODER) {
> + if (coda_format_normalize_yuv(f->pixel_format) ==
> + V4L2_PIX_FMT_YUV420) {
> + q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
> + codec = coda_find_codec(ctx->dev, f->pixel_format,
> + q_data->fourcc);
> + } else {
> + codec = coda_find_codec(ctx->dev, V4L2_PIX_FMT_YUV420,
> + f->pixel_format);
> + }
> + } else {
> + if (coda_format_normalize_yuv(f->pixel_format) ==
> + V4L2_PIX_FMT_YUV420) {
> + q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
> + codec = coda_find_codec(ctx->dev, q_data->fourcc,
> + f->pixel_format);
> + } else {
> + codec = coda_find_codec(ctx->dev, f->pixel_format,
> + V4L2_PIX_FMT_YUV420);
> + }
> }
> - if (i == CODA_MAX_FORMATS)
> + if (!codec)
> + return -EINVAL;
> +
> + if (f->width < MIN_W || f->width > codec->max_w ||
> + f->height < MIN_H || f->height > codec->max_h)
> return -EINVAL;
>
> f->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
>
Why support VIDIOC_ENUM_FRAMEINTERVALS at all? It makes no sense for a codec.
I'd remove it altogether.
Regards,
Hans
^ permalink raw reply
* Re: [PATCH 4/7] drm/i915/icl: Disable video turbo mode for rp control
From: Chris Wilson @ 2019-04-10 13:43 UTC (permalink / raw)
To: Mika Kuoppala, intel-gfx
In-Reply-To: <20190410132436.23679-1-mika.kuoppala@linux.intel.com>
Quoting Mika Kuoppala (2019-04-10 14:24:36)
> There is no video turbo mode for gen11, so don't set it.
>
> v2: inline (Chris)
> v3: brackets (Chris)
>
> Cc: Chris Wilson <chris@chris-wilson.co.uk>
> Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>
-Chris
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply
* Re: Tun congestion/BQL
From: Toke Høiland-Jørgensen @ 2019-04-10 13:42 UTC (permalink / raw)
To: Jason Wang, David Woodhouse, netdev
In-Reply-To: <8c64c80d-165c-076b-fca3-5374edc87853@redhat.com>
Jason Wang <jasowang@redhat.com> writes:
> On 2019/4/10 下午9:01, David Woodhouse wrote:
>> On Wed, 2019-04-10 at 15:01 +0300, David Woodhouse wrote:
>>> --- a/drivers/net/tun.c
>>> +++ b/drivers/net/tun.c
>>> @@ -1125,7 +1128,9 @@ static netdev_tx_t tun_net_xmit(struct sk_buff
>>> *skb, struct net_device *dev)
>>> if (tfile->flags & TUN_FASYNC)
>>> kill_fasync(&tfile->fasync, SIGIO, POLL_IN);
>>> tfile->socket.sk->sk_data_ready(tfile->socket.sk);
>>>
>>> + if (!ptr_ring_empty(&tfile->tx_ring))
>>> + netif_stop_queue(tun->dev);
>>> rcu_read_unlock();
>>> return NETDEV_TX_OK;
>>>
>>>
>> Hm, that should be using ptr_ring_full() shouldn't it? So...
>>
>> --- a/drivers/net/tun.c
>> +++ b/drivers/net/tun.c
>> @@ -1121,6 +1121,9 @@ static netdev_tx_t tun_net_xmit(struct s
>> if (ptr_ring_produce(&tfile->tx_ring, skb))
>> goto drop;
>>
>> + if (ptr_ring_full(&tfile->tx_ring))
>> + netif_stop_queue(tun->dev);
>> +
>> /* Notify and wake up reader process */
>> if (tfile->flags & TUN_FASYNC)
>> kill_fasync(&tfile->fasync, SIGIO, POLL_IN);
>> @@ -2229,6 +2232,7 @@ static ssize_t tun_do_read(struct tun_st
>> consume_skb(skb);
>> }
>>
>> + netif_wake_queue(tun->dev);
>> return ret;
>> }
>>
>>
>> That doesn't seem to make much difference at all; it's still dropping a
>> lot of packets because ptr_ring_produce() is returning non-zero.
>
>
> I think you need try to stop the queue just in this case? Ideally we may
> want to stop the queue when the queue is about to full, but we don't
> have such helper currently.
Ideally we want to react when the queue starts building rather than when
it starts getting full; by pushing back on upper layers (or, if
forwarding, dropping packets to signal congestion).
In practice, this means tuning the TX ring to the *minimum* size it can
be without starving (this is basically what BQL does for Ethernet), and
keeping packets queued in the qdisc layer instead, where it can be
managed...
-Toke
^ permalink raw reply
* [PATCH v4 04/36] thunderbolt: Block reads and writes if switch is unplugged
From: Mika Westerberg @ 2019-04-10 13:36 UTC (permalink / raw)
To: linux-kernel
Cc: Michael Jamet, Yehezkel Bernat, Andreas Noever, Lukas Wunner,
David S . Miller, Andy Shevchenko, Christian Kellner,
Mario.Limonciello, Joe Perches, Mika Westerberg, netdev
In-Reply-To: <20190410133653.88061-1-mika.westerberg@linux.intel.com>
If switch is already disconnected there is no point sending it commands
and waiting for timeout. Instead in that case return error immediately.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/thunderbolt/tb.h | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
index aea668c40d27..496dcd03ede1 100644
--- a/drivers/thunderbolt/tb.h
+++ b/drivers/thunderbolt/tb.h
@@ -277,6 +277,8 @@ static inline struct tb_port *tb_port_at(u64 route, struct tb_switch *sw)
static inline int tb_sw_read(struct tb_switch *sw, void *buffer,
enum tb_cfg_space space, u32 offset, u32 length)
{
+ if (sw->is_unplugged)
+ return -ENODEV;
return tb_cfg_read(sw->tb->ctl,
buffer,
tb_route(sw),
@@ -289,6 +291,8 @@ static inline int tb_sw_read(struct tb_switch *sw, void *buffer,
static inline int tb_sw_write(struct tb_switch *sw, void *buffer,
enum tb_cfg_space space, u32 offset, u32 length)
{
+ if (sw->is_unplugged)
+ return -ENODEV;
return tb_cfg_write(sw->tb->ctl,
buffer,
tb_route(sw),
@@ -301,6 +305,8 @@ static inline int tb_sw_write(struct tb_switch *sw, void *buffer,
static inline int tb_port_read(struct tb_port *port, void *buffer,
enum tb_cfg_space space, u32 offset, u32 length)
{
+ if (port->sw->is_unplugged)
+ return -ENODEV;
return tb_cfg_read(port->sw->tb->ctl,
buffer,
tb_route(port->sw),
@@ -313,6 +319,8 @@ static inline int tb_port_read(struct tb_port *port, void *buffer,
static inline int tb_port_write(struct tb_port *port, const void *buffer,
enum tb_cfg_space space, u32 offset, u32 length)
{
+ if (port->sw->is_unplugged)
+ return -ENODEV;
return tb_cfg_write(port->sw->tb->ctl,
buffer,
tb_route(port->sw),
--
2.20.1
^ permalink raw reply related
* [PATCH v4 03/36] thunderbolt: Drop duplicated get_switch_at_route()
From: Mika Westerberg @ 2019-04-10 13:36 UTC (permalink / raw)
To: linux-kernel
Cc: Michael Jamet, Yehezkel Bernat, Andreas Noever, Lukas Wunner,
David S . Miller, Andy Shevchenko, Christian Kellner,
Mario.Limonciello, Joe Perches, Mika Westerberg, netdev
In-Reply-To: <20190410133653.88061-1-mika.westerberg@linux.intel.com>
tb_switch_find_by_route() does the same already so use it instead and
remove duplicated get_switch_at_route().
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: Lukas Wunner <lukas@wunner.de>
---
drivers/thunderbolt/icm.c | 12 ++++++++----
drivers/thunderbolt/switch.c | 18 ------------------
drivers/thunderbolt/tb.c | 9 ++++++---
drivers/thunderbolt/tb.h | 1 -
4 files changed, 14 insertions(+), 26 deletions(-)
diff --git a/drivers/thunderbolt/icm.c b/drivers/thunderbolt/icm.c
index 8b7f9131e9d1..7c923e16a7d8 100644
--- a/drivers/thunderbolt/icm.c
+++ b/drivers/thunderbolt/icm.c
@@ -798,9 +798,11 @@ icm_fr_xdomain_connected(struct tb *tb, const struct icm_pkg_header *hdr)
* connected another host to the same port, remove the switch
* first.
*/
- sw = get_switch_at_route(tb->root_switch, route);
- if (sw)
+ sw = tb_switch_find_by_route(tb, route);
+ if (sw) {
remove_switch(sw);
+ tb_switch_put(sw);
+ }
sw = tb_switch_find_by_link_depth(tb, link, depth);
if (!sw) {
@@ -1143,9 +1145,11 @@ icm_tr_xdomain_connected(struct tb *tb, const struct icm_pkg_header *hdr)
* connected another host to the same port, remove the switch
* first.
*/
- sw = get_switch_at_route(tb->root_switch, route);
- if (sw)
+ sw = tb_switch_find_by_route(tb, route);
+ if (sw) {
remove_switch(sw);
+ tb_switch_put(sw);
+ }
sw = tb_switch_find_by_route(tb, get_parent_route(route));
if (!sw) {
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
index 504365d46827..5c2c0201ae7f 100644
--- a/drivers/thunderbolt/switch.c
+++ b/drivers/thunderbolt/switch.c
@@ -644,24 +644,6 @@ int tb_switch_reset(struct tb *tb, u64 route)
return res.err;
}
-struct tb_switch *get_switch_at_route(struct tb_switch *sw, u64 route)
-{
- u8 next_port = route; /*
- * Routes use a stride of 8 bits,
- * eventhough a port index has 6 bits at most.
- * */
- if (route == 0)
- return sw;
- if (next_port > sw->config.max_port_number)
- return NULL;
- if (tb_is_upstream_port(&sw->ports[next_port]))
- return NULL;
- if (!sw->ports[next_port].remote)
- return NULL;
- return get_switch_at_route(sw->ports[next_port].remote->sw,
- route >> TB_ROUTE_SHIFT);
-}
-
/**
* tb_plug_events_active() - enable/disable plug events on a switch
*
diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c
index 30e02c716f6c..d8f4ed0f2ef8 100644
--- a/drivers/thunderbolt/tb.c
+++ b/drivers/thunderbolt/tb.c
@@ -258,7 +258,7 @@ static void tb_handle_hotplug(struct work_struct *work)
if (!tcm->hotplug_active)
goto out; /* during init, suspend or shutdown */
- sw = get_switch_at_route(tb->root_switch, ev->route);
+ sw = tb_switch_find_by_route(tb, ev->route);
if (!sw) {
tb_warn(tb,
"hotplug event from non existent switch %llx:%x (unplug: %d)\n",
@@ -269,14 +269,14 @@ static void tb_handle_hotplug(struct work_struct *work)
tb_warn(tb,
"hotplug event from non existent port %llx:%x (unplug: %d)\n",
ev->route, ev->port, ev->unplug);
- goto out;
+ goto put_sw;
}
port = &sw->ports[ev->port];
if (tb_is_upstream_port(port)) {
tb_warn(tb,
"hotplug event for upstream port %llx:%x (unplug: %d)\n",
ev->route, ev->port, ev->unplug);
- goto out;
+ goto put_sw;
}
if (ev->unplug) {
if (port->remote) {
@@ -306,6 +306,9 @@ static void tb_handle_hotplug(struct work_struct *work)
tb_activate_pcie_devices(tb);
}
}
+
+put_sw:
+ tb_switch_put(sw);
out:
mutex_unlock(&tb->lock);
kfree(ev);
diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
index 8058ea02d572..aea668c40d27 100644
--- a/drivers/thunderbolt/tb.h
+++ b/drivers/thunderbolt/tb.h
@@ -399,7 +399,6 @@ void tb_switch_suspend(struct tb_switch *sw);
int tb_switch_resume(struct tb_switch *sw);
int tb_switch_reset(struct tb *tb, u64 route);
void tb_sw_set_unplugged(struct tb_switch *sw);
-struct tb_switch *get_switch_at_route(struct tb_switch *sw, u64 route);
struct tb_switch *tb_switch_find_by_link_depth(struct tb *tb, u8 link,
u8 depth);
struct tb_switch *tb_switch_find_by_uuid(struct tb *tb, const uuid_t *uuid);
--
2.20.1
^ permalink raw reply related
* [PATCH v4 06/36] thunderbolt: Do not allocate switch if depth is greater than 6
From: Mika Westerberg @ 2019-04-10 13:36 UTC (permalink / raw)
To: linux-kernel
Cc: Michael Jamet, Yehezkel Bernat, Andreas Noever, Lukas Wunner,
David S . Miller, Andy Shevchenko, Christian Kellner,
Mario.Limonciello, Joe Perches, Mika Westerberg, netdev
In-Reply-To: <20190410133653.88061-1-mika.westerberg@linux.intel.com>
Maximum depth in Thunderbolt topology is 6 so make sure it is not
possible to allocate switches that exceed the depth limit.
While at it update tb_switch_alloc() to use upper/lower_32_bits()
following tb_switch_alloc_safe_mode().
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/thunderbolt/icm.c | 5 ++---
drivers/thunderbolt/switch.c | 18 ++++++++++++------
drivers/thunderbolt/tb.h | 1 +
3 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/drivers/thunderbolt/icm.c b/drivers/thunderbolt/icm.c
index 7c923e16a7d8..bec360eef6cf 100644
--- a/drivers/thunderbolt/icm.c
+++ b/drivers/thunderbolt/icm.c
@@ -42,7 +42,6 @@
#define ICM_TIMEOUT 5000 /* ms */
#define ICM_APPROVE_TIMEOUT 10000 /* ms */
#define ICM_MAX_LINK 4
-#define ICM_MAX_DEPTH 6
/**
* struct icm - Internal connection manager private data
@@ -714,7 +713,7 @@ icm_fr_device_disconnected(struct tb *tb, const struct icm_pkg_header *hdr)
depth = (pkg->link_info & ICM_LINK_INFO_DEPTH_MASK) >>
ICM_LINK_INFO_DEPTH_SHIFT;
- if (link > ICM_MAX_LINK || depth > ICM_MAX_DEPTH) {
+ if (link > ICM_MAX_LINK || depth > TB_SWITCH_MAX_DEPTH) {
tb_warn(tb, "invalid topology %u.%u, ignoring\n", link, depth);
return;
}
@@ -744,7 +743,7 @@ icm_fr_xdomain_connected(struct tb *tb, const struct icm_pkg_header *hdr)
depth = (pkg->link_info & ICM_LINK_INFO_DEPTH_MASK) >>
ICM_LINK_INFO_DEPTH_SHIFT;
- if (link > ICM_MAX_LINK || depth > ICM_MAX_DEPTH) {
+ if (link > ICM_MAX_LINK || depth > TB_SWITCH_MAX_DEPTH) {
tb_warn(tb, "invalid topology %u.%u, ignoring\n", link, depth);
return;
}
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
index 7fa4ab076404..1e29c06947af 100644
--- a/drivers/thunderbolt/switch.c
+++ b/drivers/thunderbolt/switch.c
@@ -1130,10 +1130,16 @@ static int tb_switch_get_generation(struct tb_switch *sw)
struct tb_switch *tb_switch_alloc(struct tb *tb, struct device *parent,
u64 route)
{
- int i;
- int cap;
struct tb_switch *sw;
- int upstream_port = tb_cfg_get_upstream_port(tb->ctl, route);
+ int upstream_port;
+ int i, cap, depth;
+
+ /* Make sure we do not exceed maximum topology limit */
+ depth = tb_route_length(route);
+ if (depth > TB_SWITCH_MAX_DEPTH)
+ return NULL;
+
+ upstream_port = tb_cfg_get_upstream_port(tb->ctl, route);
if (upstream_port < 0)
return NULL;
@@ -1150,9 +1156,9 @@ struct tb_switch *tb_switch_alloc(struct tb *tb, struct device *parent,
/* configure switch */
sw->config.upstream_port_number = upstream_port;
- sw->config.depth = tb_route_length(route);
- sw->config.route_lo = route;
- sw->config.route_hi = route >> 32;
+ sw->config.depth = depth;
+ sw->config.route_hi = upper_32_bits(route);
+ sw->config.route_lo = lower_32_bits(route);
sw->config.enabled = 0;
/* initialize ports */
diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
index f7b0c43c29a7..93c1ea21feeb 100644
--- a/drivers/thunderbolt/tb.h
+++ b/drivers/thunderbolt/tb.h
@@ -43,6 +43,7 @@ struct tb_switch_nvm {
};
#define TB_SWITCH_KEY_SIZE 32
+#define TB_SWITCH_MAX_DEPTH 6
/**
* struct tb_switch - a thunderbolt switch
--
2.20.1
^ permalink raw reply related
* [PATCH v4 10/36] thunderbolt: Configure lanes when switch is initialized
From: Mika Westerberg @ 2019-04-10 13:36 UTC (permalink / raw)
To: linux-kernel
Cc: Michael Jamet, Yehezkel Bernat, Andreas Noever, Lukas Wunner,
David S . Miller, Andy Shevchenko, Christian Kellner,
Mario.Limonciello, Joe Perches, Mika Westerberg, netdev
In-Reply-To: <20190410133653.88061-1-mika.westerberg@linux.intel.com>
Thunderbolt 2 devices and beyond need to have additional bits set in
link controller specific registers. This includes two bits in LC_SX_CTRL
that tell the link controller which lane is connected and whether it is
upstream facing or not.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/thunderbolt/lc.c | 114 ++++++++++++++++++++++++++++++++++
drivers/thunderbolt/switch.c | 9 +++
drivers/thunderbolt/tb.h | 2 +
drivers/thunderbolt/tb_regs.h | 11 ++++
4 files changed, 136 insertions(+)
diff --git a/drivers/thunderbolt/lc.c b/drivers/thunderbolt/lc.c
index 2134a55ed837..a5dddf176546 100644
--- a/drivers/thunderbolt/lc.c
+++ b/drivers/thunderbolt/lc.c
@@ -19,3 +19,117 @@ int tb_lc_read_uuid(struct tb_switch *sw, u32 *uuid)
return -EINVAL;
return tb_sw_read(sw, uuid, TB_CFG_SWITCH, sw->cap_lc + TB_LC_FUSE, 4);
}
+
+static int read_lc_desc(struct tb_switch *sw, u32 *desc)
+{
+ if (!sw->cap_lc)
+ return -EINVAL;
+ return tb_sw_read(sw, desc, TB_CFG_SWITCH, sw->cap_lc + TB_LC_DESC, 1);
+}
+
+static int find_port_lc_cap(struct tb_port *port)
+{
+ struct tb_switch *sw = port->sw;
+ int start, phys, ret, size;
+ u32 desc;
+
+ ret = read_lc_desc(sw, &desc);
+ if (ret)
+ return ret;
+
+ /* Start of port LC registers */
+ start = (desc & TB_LC_DESC_SIZE_MASK) >> TB_LC_DESC_SIZE_SHIFT;
+ size = (desc & TB_LC_DESC_PORT_SIZE_MASK) >> TB_LC_DESC_PORT_SIZE_SHIFT;
+ phys = tb_phy_port_from_link(port->port);
+
+ return sw->cap_lc + start + phys * size;
+}
+
+static int tb_lc_configure_lane(struct tb_port *port, bool configure)
+{
+ bool upstream = tb_is_upstream_port(port);
+ struct tb_switch *sw = port->sw;
+ u32 ctrl, lane;
+ int cap, ret;
+
+ if (sw->generation < 2)
+ return 0;
+
+ cap = find_port_lc_cap(port);
+ if (cap < 0)
+ return cap;
+
+ ret = tb_sw_read(sw, &ctrl, TB_CFG_SWITCH, cap + TB_LC_SX_CTRL, 1);
+ if (ret)
+ return ret;
+
+ /* Resolve correct lane */
+ if (port->port % 2)
+ lane = TB_LC_SX_CTRL_L1C;
+ else
+ lane = TB_LC_SX_CTRL_L2C;
+
+ if (configure) {
+ ctrl |= lane;
+ if (upstream)
+ ctrl |= TB_LC_SX_CTRL_UPSTREAM;
+ } else {
+ ctrl &= ~lane;
+ if (upstream)
+ ctrl &= ~TB_LC_SX_CTRL_UPSTREAM;
+ }
+
+ return tb_sw_write(sw, &ctrl, TB_CFG_SWITCH, cap + TB_LC_SX_CTRL, 1);
+}
+
+/**
+ * tb_lc_configure_link() - Let LC know about configured link
+ * @sw: Switch that is being added
+ *
+ * Informs LC of both parent switch and @sw that there is established
+ * link between the two.
+ */
+int tb_lc_configure_link(struct tb_switch *sw)
+{
+ struct tb_port *up, *down;
+ int ret;
+
+ if (!sw->config.enabled || !tb_route(sw))
+ return 0;
+
+ up = tb_upstream_port(sw);
+ down = tb_port_at(tb_route(sw), tb_to_switch(sw->dev.parent));
+
+ /* Configure parent link toward this switch */
+ ret = tb_lc_configure_lane(down, true);
+ if (ret)
+ return ret;
+
+ /* Configure upstream link from this switch to the parent */
+ ret = tb_lc_configure_lane(up, true);
+ if (ret)
+ tb_lc_configure_lane(down, false);
+
+ return ret;
+}
+
+/**
+ * tb_lc_unconfigure_link() - Let LC know about unconfigured link
+ * @sw: Switch to unconfigure
+ *
+ * Informs LC of both parent switch and @sw that the link between the
+ * two does not exist anymore.
+ */
+void tb_lc_unconfigure_link(struct tb_switch *sw)
+{
+ struct tb_port *up, *down;
+
+ if (sw->is_unplugged || !sw->config.enabled || !tb_route(sw))
+ return;
+
+ up = tb_upstream_port(sw);
+ down = tb_port_at(tb_route(sw), tb_to_switch(sw->dev.parent));
+
+ tb_lc_configure_lane(up, false);
+ tb_lc_configure_lane(down, false);
+}
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
index 63ff4c753d89..dd218dc4781b 100644
--- a/drivers/thunderbolt/switch.c
+++ b/drivers/thunderbolt/switch.c
@@ -1276,6 +1276,10 @@ int tb_switch_configure(struct tb_switch *sw)
if (ret)
return ret;
+ ret = tb_lc_configure_link(sw);
+ if (ret)
+ return ret;
+
return tb_plug_events_active(sw, true);
}
@@ -1486,6 +1490,7 @@ void tb_switch_remove(struct tb_switch *sw)
if (!sw->is_unplugged)
tb_plug_events_active(sw, false);
+ tb_lc_unconfigure_link(sw);
tb_switch_nvm_remove(sw);
@@ -1545,6 +1550,10 @@ int tb_switch_resume(struct tb_switch *sw)
if (err)
return err;
+ err = tb_lc_configure_link(sw);
+ if (err)
+ return err;
+
err = tb_plug_events_active(sw, true);
if (err)
return err;
diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
index e52d39b25266..69e0534224d8 100644
--- a/drivers/thunderbolt/tb.h
+++ b/drivers/thunderbolt/tb.h
@@ -465,6 +465,8 @@ int tb_drom_read(struct tb_switch *sw);
int tb_drom_read_uid_only(struct tb_switch *sw, u64 *uid);
int tb_lc_read_uuid(struct tb_switch *sw, u32 *uuid);
+int tb_lc_configure_link(struct tb_switch *sw);
+void tb_lc_unconfigure_link(struct tb_switch *sw);
static inline int tb_route_length(u64 route)
{
diff --git a/drivers/thunderbolt/tb_regs.h b/drivers/thunderbolt/tb_regs.h
index 4895ae9f0b40..e0f867dad5cf 100644
--- a/drivers/thunderbolt/tb_regs.h
+++ b/drivers/thunderbolt/tb_regs.h
@@ -238,6 +238,17 @@ struct tb_regs_hop {
} __packed;
/* Common link controller registers */
+#define TB_LC_DESC 0x02
+#define TB_LC_DESC_SIZE_SHIFT 8
+#define TB_LC_DESC_SIZE_MASK GENMASK(15, 8)
+#define TB_LC_DESC_PORT_SIZE_SHIFT 16
+#define TB_LC_DESC_PORT_SIZE_MASK GENMASK(27, 16)
#define TB_LC_FUSE 0x03
+/* Link controller registers */
+#define TB_LC_SX_CTRL 0x96
+#define TB_LC_SX_CTRL_L1C BIT(16)
+#define TB_LC_SX_CTRL_L2C BIT(20)
+#define TB_LC_SX_CTRL_UPSTREAM BIT(30)
+
#endif
--
2.20.1
^ permalink raw reply related
* Re: [PATCH 2/2] ARM: dts: stm32: Enable STM32F769 clock driver
From: Alexandre Torgue @ 2019-04-10 13:40 UTC (permalink / raw)
To: Gabriel Fernandez, michael turquette, stephen boyd, rob herring,
mark rutland, maxime coquelin
Cc: linux-clk, devicetree, linux-kernel, linux-stm32
In-Reply-To: <20190405075332.28530-3-gabriel.fernandez@st.com>
Hi Gabriel
On 4/5/19 9:53 AM, Gabriel Fernandez wrote:
> This patch enables clocks for STM32F769 boards.
>
> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
> ---
> arch/arm/boot/dts/stm32f769-disco.dts | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/arch/arm/boot/dts/stm32f769-disco.dts b/arch/arm/boot/dts/stm32f769-disco.dts
> index 3c7216844a9b..6f1d0ac8c31c 100644
> --- a/arch/arm/boot/dts/stm32f769-disco.dts
> +++ b/arch/arm/boot/dts/stm32f769-disco.dts
> @@ -102,6 +102,10 @@
> };
> };
>
> +&rcc {
> + compatible = "st,stm32f769-rcc", "st,stm32f746-rcc", "st,stm32-rcc";
> +};
> +
> &cec {
> pinctrl-0 = <&cec_pins_a>;
> pinctrl-names = "default";
>
Even if driver part is not yet merged, this DT part can be taken as we
will run with "st,stm32f746-rcc" compatible (the current one).
So:
Applied on stm32-next.
Thanks.
Alex
^ permalink raw reply
* [PATCH v4 13/36] thunderbolt: Cache adapter specific capability offset into struct port
From: Mika Westerberg @ 2019-04-10 13:36 UTC (permalink / raw)
To: linux-kernel
Cc: Michael Jamet, Yehezkel Bernat, Andreas Noever, Lukas Wunner,
David S . Miller, Andy Shevchenko, Christian Kellner,
Mario.Limonciello, Joe Perches, Mika Westerberg, netdev
In-Reply-To: <20190410133653.88061-1-mika.westerberg@linux.intel.com>
The adapter specific capability either is there or not if the port does
not hold an adapter. Instead of always finding it on-demand we read the
offset just once when the port is initialized.
While there we update the struct port documentation to follow kernel-doc
format.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/thunderbolt/switch.c | 4 ++++
drivers/thunderbolt/tb.c | 8 ++++----
drivers/thunderbolt/tb.h | 2 ++
drivers/thunderbolt/tunnel_pci.c | 9 +++------
4 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
index b3f93ebe6e39..9756e6279dc9 100644
--- a/drivers/thunderbolt/switch.c
+++ b/drivers/thunderbolt/switch.c
@@ -586,6 +586,10 @@ static int tb_init_port(struct tb_port *port)
port->cap_phy = cap;
else
tb_port_WARN(port, "non switch port without a PHY\n");
+ } else if (port->port != 0) {
+ cap = tb_port_find_cap(port, TB_PORT_CAP_ADAP);
+ if (cap > 0)
+ port->cap_adap = cap;
}
tb_dump_port(port->sw->tb, &port->config);
diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c
index d8f4ed0f2ef8..e71530d0af65 100644
--- a/drivers/thunderbolt/tb.c
+++ b/drivers/thunderbolt/tb.c
@@ -151,8 +151,8 @@ static struct tb_port *tb_find_unused_down_port(struct tb_switch *sw)
continue;
if (sw->ports[i].config.type != TB_TYPE_PCIE_DOWN)
continue;
- cap = tb_port_find_cap(&sw->ports[i], TB_PORT_CAP_ADAP);
- if (cap < 0)
+ cap = sw->ports[i].cap_adap;
+ if (!cap)
continue;
res = tb_port_read(&sw->ports[i], &data, TB_CFG_PORT, cap, 1);
if (res < 0)
@@ -197,8 +197,8 @@ static void tb_activate_pcie_devices(struct tb *tb)
}
/* check whether port is already activated */
- cap = tb_port_find_cap(up_port, TB_PORT_CAP_ADAP);
- if (cap < 0)
+ cap = up_port->cap_adap;
+ if (!cap)
continue;
if (tb_port_read(up_port, &data, TB_CFG_PORT, cap, 1))
continue;
diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
index 985a48a67a43..b4d7c4d408bd 100644
--- a/drivers/thunderbolt/tb.h
+++ b/drivers/thunderbolt/tb.h
@@ -121,6 +121,7 @@ struct tb_switch {
* @remote: Remote port (%NULL if not connected)
* @xdomain: Remote host (%NULL if not connected)
* @cap_phy: Offset, zero if not found
+ * @cap_adap: Offset of the adapter specific capability (%0 if not present)
* @port: Port number on switch
* @disabled: Disabled by eeprom
* @dual_link_port: If the switch is connected using two ports, points
@@ -133,6 +134,7 @@ struct tb_port {
struct tb_port *remote;
struct tb_xdomain *xdomain;
int cap_phy;
+ int cap_adap;
u8 port;
bool disabled;
struct tb_port *dual_link_port;
diff --git a/drivers/thunderbolt/tunnel_pci.c b/drivers/thunderbolt/tunnel_pci.c
index 0637537ea53f..2de4edccbd6d 100644
--- a/drivers/thunderbolt/tunnel_pci.c
+++ b/drivers/thunderbolt/tunnel_pci.c
@@ -148,12 +148,9 @@ bool tb_pci_is_invalid(struct tb_pci_tunnel *tunnel)
static int tb_pci_port_active(struct tb_port *port, bool active)
{
u32 word = active ? 0x80000000 : 0x0;
- int cap = tb_port_find_cap(port, TB_PORT_CAP_ADAP);
- if (cap < 0) {
- tb_port_warn(port, "TB_PORT_CAP_ADAP not found: %d\n", cap);
- return cap;
- }
- return tb_port_write(port, &word, TB_CFG_PORT, cap, 1);
+ if (!port->cap_adap)
+ return -ENXIO;
+ return tb_port_write(port, &word, TB_CFG_PORT, port->cap_adap, 1);
}
/**
--
2.20.1
^ permalink raw reply related
* [PATCH v4 12/36] thunderbolt: Properly disable path
From: Mika Westerberg @ 2019-04-10 13:36 UTC (permalink / raw)
To: linux-kernel
Cc: Michael Jamet, Yehezkel Bernat, Andreas Noever, Lukas Wunner,
David S . Miller, Andy Shevchenko, Christian Kellner,
Mario.Limonciello, Joe Perches, Mika Westerberg, netdev
In-Reply-To: <20190410133653.88061-1-mika.westerberg@linux.intel.com>
We need to wait until all buffers have been drained before the path can
be considered disabled. Do this for every hop in a path.
This adds another bit field to struct tb_regs_hop even if we are trying
to get rid of them but we can clean them up another day.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/thunderbolt/path.c | 47 ++++++++++++++++++++++++++++++++---
drivers/thunderbolt/tb_regs.h | 3 ++-
2 files changed, 45 insertions(+), 5 deletions(-)
diff --git a/drivers/thunderbolt/path.c b/drivers/thunderbolt/path.c
index a11956522bac..8c2e19a6117a 100644
--- a/drivers/thunderbolt/path.c
+++ b/drivers/thunderbolt/path.c
@@ -7,6 +7,8 @@
#include <linux/slab.h>
#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/ktime.h>
#include "tb.h"
@@ -74,14 +76,51 @@ static void __tb_path_deallocate_nfc(struct tb_path *path, int first_hop)
}
}
+static int __tb_path_deactivate_hop(struct tb_port *port, int hop_index)
+{
+ struct tb_regs_hop hop;
+ ktime_t timeout;
+ int ret;
+
+ /* Disable the path */
+ ret = tb_port_read(port, &hop, TB_CFG_HOPS, 2 * hop_index, 2);
+ if (ret)
+ return ret;
+
+ /* Already disabled */
+ if (!hop.enable)
+ return 0;
+
+ hop.enable = 0;
+
+ ret = tb_port_write(port, &hop, TB_CFG_HOPS, 2 * hop_index, 2);
+ if (ret)
+ return ret;
+
+ /* Wait until it is drained */
+ timeout = ktime_add_ms(ktime_get(), 500);
+ do {
+ ret = tb_port_read(port, &hop, TB_CFG_HOPS, 2 * hop_index, 2);
+ if (ret)
+ return ret;
+
+ if (!hop.pending)
+ return 0;
+
+ usleep_range(10, 20);
+ } while (ktime_before(ktime_get(), timeout));
+
+ return -ETIMEDOUT;
+}
+
static void __tb_path_deactivate_hops(struct tb_path *path, int first_hop)
{
int i, res;
- struct tb_regs_hop hop = { };
+
for (i = first_hop; i < path->path_length; i++) {
- res = tb_port_write(path->hops[i].in_port, &hop, TB_CFG_HOPS,
- 2 * path->hops[i].in_hop_index, 2);
- if (res)
+ res = __tb_path_deactivate_hop(path->hops[i].in_port,
+ path->hops[i].in_hop_index);
+ if (res && res != -ENODEV)
tb_port_warn(path->hops[i].in_port,
"hop deactivation failed for hop %d, index %d\n",
i, path->hops[i].in_hop_index);
diff --git a/drivers/thunderbolt/tb_regs.h b/drivers/thunderbolt/tb_regs.h
index 1ab6e0fb31c0..82ac4ec8757f 100644
--- a/drivers/thunderbolt/tb_regs.h
+++ b/drivers/thunderbolt/tb_regs.h
@@ -234,7 +234,8 @@ struct tb_regs_hop {
bool egress_fc:1;
bool ingress_shared_buffer:1;
bool egress_shared_buffer:1;
- u32 unknown3:4; /* set to zero */
+ bool pending:1;
+ u32 unknown3:3; /* set to zero */
} __packed;
/* Common link controller registers */
--
2.20.1
^ permalink raw reply related
* [PATCH v4 18/36] thunderbolt: Add helper function to iterate from one port to another
From: Mika Westerberg @ 2019-04-10 13:36 UTC (permalink / raw)
To: linux-kernel
Cc: Michael Jamet, Yehezkel Bernat, Andreas Noever, Lukas Wunner,
David S . Miller, Andy Shevchenko, Christian Kellner,
Mario.Limonciello, Joe Perches, Mika Westerberg, netdev
In-Reply-To: <20190410133653.88061-1-mika.westerberg@linux.intel.com>
We need to be able to walk from one port to another when we are creating
paths where there are multiple switches between two ports. For this
reason introduce a new function tb_next_port_on_path().
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: Lukas Wunner <lukas@wunner.de>
---
drivers/thunderbolt/switch.c | 54 ++++++++++++++++++++++++++++++++++++
drivers/thunderbolt/tb.h | 2 ++
2 files changed, 56 insertions(+)
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
index 6f98b3d6eb2a..ecd41f7b7649 100644
--- a/drivers/thunderbolt/switch.c
+++ b/drivers/thunderbolt/switch.c
@@ -676,6 +676,60 @@ void tb_port_release_out_hopid(struct tb_port *port, int hopid)
ida_simple_remove(&port->out_hopids, hopid);
}
+/**
+ * tb_next_port_on_path() - Return next port for given port on a path
+ * @start: Start port of the walk
+ * @end: End port of the walk
+ * @prev: Previous port (%NULL if this is the first)
+ *
+ * This function can be used to walk from one port to another if they
+ * are connected through zero or more switches. If the @prev is dual
+ * link port, the function follows that link and returns another end on
+ * that same link.
+ *
+ * If the @end port has been reached, return %NULL.
+ *
+ * Domain tb->lock must be held when this function is called.
+ */
+struct tb_port *tb_next_port_on_path(struct tb_port *start, struct tb_port *end,
+ struct tb_port *prev)
+{
+ struct tb_port *next;
+
+ if (!prev)
+ return start;
+
+ if (prev->sw == end->sw) {
+ if (prev == end)
+ return NULL;
+ return end;
+ }
+
+ if (start->sw->config.depth < end->sw->config.depth) {
+ if (prev->remote &&
+ prev->remote->sw->config.depth > prev->sw->config.depth)
+ next = prev->remote;
+ else
+ next = tb_port_at(tb_route(end->sw), prev->sw);
+ } else {
+ if (tb_is_upstream_port(prev)) {
+ next = prev->remote;
+ } else {
+ next = tb_upstream_port(prev->sw);
+ /*
+ * Keep the same link if prev and next are both
+ * dual link ports.
+ */
+ if (next->dual_link_port &&
+ next->link_nr != prev->link_nr) {
+ next = next->dual_link_port;
+ }
+ }
+ }
+
+ return next;
+}
+
/**
* tb_pci_port_enable() - Enable PCIe adapter port
* @port: PCIe port to enable
diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
index 43bc4f490021..11d5ab53ad36 100644
--- a/drivers/thunderbolt/tb.h
+++ b/drivers/thunderbolt/tb.h
@@ -495,6 +495,8 @@ int tb_port_alloc_in_hopid(struct tb_port *port, int hopid, int max_hopid);
void tb_port_release_in_hopid(struct tb_port *port, int hopid);
int tb_port_alloc_out_hopid(struct tb_port *port, int hopid, int max_hopid);
void tb_port_release_out_hopid(struct tb_port *port, int hopid);
+struct tb_port *tb_next_port_on_path(struct tb_port *start, struct tb_port *end,
+ struct tb_port *prev);
int tb_switch_find_vse_cap(struct tb_switch *sw, enum tb_switch_vse_cap vsec);
int tb_port_find_cap(struct tb_port *port, enum tb_port_cap cap);
--
2.20.1
^ permalink raw reply related
* [PATCH v4 11/36] thunderbolt: Set sleep bit when suspending switch
From: Mika Westerberg @ 2019-04-10 13:36 UTC (permalink / raw)
To: linux-kernel
Cc: Michael Jamet, Yehezkel Bernat, Andreas Noever, Lukas Wunner,
David S . Miller, Andy Shevchenko, Christian Kellner,
Mario.Limonciello, Joe Perches, Mika Westerberg, netdev
In-Reply-To: <20190410133653.88061-1-mika.westerberg@linux.intel.com>
Thunderbolt 2 devices and beyond link controller needs to be notified
when a switch is going to be suspended by setting bit 31 in LC_SX_CTRL
register. Add this functionality to the software connection manager.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/thunderbolt/lc.c | 44 +++++++++++++++++++++++++++++++++++
drivers/thunderbolt/switch.c | 6 ++---
drivers/thunderbolt/tb.h | 1 +
drivers/thunderbolt/tb_regs.h | 2 ++
4 files changed, 49 insertions(+), 4 deletions(-)
diff --git a/drivers/thunderbolt/lc.c b/drivers/thunderbolt/lc.c
index a5dddf176546..ae1e92611c3e 100644
--- a/drivers/thunderbolt/lc.c
+++ b/drivers/thunderbolt/lc.c
@@ -133,3 +133,47 @@ void tb_lc_unconfigure_link(struct tb_switch *sw)
tb_lc_configure_lane(up, false);
tb_lc_configure_lane(down, false);
}
+
+/**
+ * tb_lc_set_sleep() - Inform LC that the switch is going to sleep
+ * @sw: Switch to set sleep
+ *
+ * Let the switch link controllers know that the switch is going to
+ * sleep.
+ */
+int tb_lc_set_sleep(struct tb_switch *sw)
+{
+ int start, size, nlc, ret, i;
+ u32 desc;
+
+ if (sw->generation < 2)
+ return 0;
+
+ ret = read_lc_desc(sw, &desc);
+ if (ret)
+ return ret;
+
+ /* Figure out number of link controllers */
+ nlc = desc & TB_LC_DESC_NLC_MASK;
+ start = (desc & TB_LC_DESC_SIZE_MASK) >> TB_LC_DESC_SIZE_SHIFT;
+ size = (desc & TB_LC_DESC_PORT_SIZE_MASK) >> TB_LC_DESC_PORT_SIZE_SHIFT;
+
+ /* For each link controller set sleep bit */
+ for (i = 0; i < nlc; i++) {
+ unsigned int offset = sw->cap_lc + start + i * size;
+ u32 ctrl;
+
+ ret = tb_sw_read(sw, &ctrl, TB_CFG_SWITCH,
+ offset + TB_LC_SX_CTRL, 1);
+ if (ret)
+ return ret;
+
+ ctrl |= TB_LC_SX_CTRL_SLP;
+ ret = tb_sw_write(sw, &ctrl, TB_CFG_SWITCH,
+ offset + TB_LC_SX_CTRL, 1);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
index dd218dc4781b..b3f93ebe6e39 100644
--- a/drivers/thunderbolt/switch.c
+++ b/drivers/thunderbolt/switch.c
@@ -1586,10 +1586,8 @@ void tb_switch_suspend(struct tb_switch *sw)
if (!tb_is_upstream_port(&sw->ports[i]) && sw->ports[i].remote)
tb_switch_suspend(sw->ports[i].remote->sw);
}
- /*
- * TODO: invoke tb_cfg_prepare_to_sleep here? does not seem to have any
- * effect?
- */
+
+ tb_lc_set_sleep(sw);
}
struct tb_sw_lookup {
diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
index 69e0534224d8..985a48a67a43 100644
--- a/drivers/thunderbolt/tb.h
+++ b/drivers/thunderbolt/tb.h
@@ -467,6 +467,7 @@ int tb_drom_read_uid_only(struct tb_switch *sw, u64 *uid);
int tb_lc_read_uuid(struct tb_switch *sw, u32 *uuid);
int tb_lc_configure_link(struct tb_switch *sw);
void tb_lc_unconfigure_link(struct tb_switch *sw);
+int tb_lc_set_sleep(struct tb_switch *sw);
static inline int tb_route_length(u64 route)
{
diff --git a/drivers/thunderbolt/tb_regs.h b/drivers/thunderbolt/tb_regs.h
index e0f867dad5cf..1ab6e0fb31c0 100644
--- a/drivers/thunderbolt/tb_regs.h
+++ b/drivers/thunderbolt/tb_regs.h
@@ -239,6 +239,7 @@ struct tb_regs_hop {
/* Common link controller registers */
#define TB_LC_DESC 0x02
+#define TB_LC_DESC_NLC_MASK GENMASK(3, 0)
#define TB_LC_DESC_SIZE_SHIFT 8
#define TB_LC_DESC_SIZE_MASK GENMASK(15, 8)
#define TB_LC_DESC_PORT_SIZE_SHIFT 16
@@ -250,5 +251,6 @@ struct tb_regs_hop {
#define TB_LC_SX_CTRL_L1C BIT(16)
#define TB_LC_SX_CTRL_L2C BIT(20)
#define TB_LC_SX_CTRL_UPSTREAM BIT(30)
+#define TB_LC_SX_CTRL_SLP BIT(31)
#endif
--
2.20.1
^ permalink raw reply related
* [PATCH v4 09/36] thunderbolt: Move LC specific functionality into a separate file
From: Mika Westerberg @ 2019-04-10 13:36 UTC (permalink / raw)
To: linux-kernel
Cc: Michael Jamet, Yehezkel Bernat, Andreas Noever, Lukas Wunner,
David S . Miller, Andy Shevchenko, Christian Kellner,
Mario.Limonciello, Joe Perches, Mika Westerberg, netdev
In-Reply-To: <20190410133653.88061-1-mika.westerberg@linux.intel.com>
We will be adding more link controller functionality in subsequent
patches and it does not make sense to keep all that in switch.c, so
separate LC functionality into its own file.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
drivers/thunderbolt/Makefile | 2 +-
drivers/thunderbolt/lc.c | 21 +++++++++++++++++++++
drivers/thunderbolt/switch.c | 21 ++++++++++-----------
drivers/thunderbolt/tb.h | 3 +++
drivers/thunderbolt/tb_regs.h | 2 ++
5 files changed, 37 insertions(+), 12 deletions(-)
create mode 100644 drivers/thunderbolt/lc.c
diff --git a/drivers/thunderbolt/Makefile b/drivers/thunderbolt/Makefile
index f2f0de27252b..8531f15d3b3c 100644
--- a/drivers/thunderbolt/Makefile
+++ b/drivers/thunderbolt/Makefile
@@ -1,3 +1,3 @@
obj-${CONFIG_THUNDERBOLT} := thunderbolt.o
thunderbolt-objs := nhi.o ctl.o tb.o switch.o cap.o path.o tunnel_pci.o eeprom.o
-thunderbolt-objs += domain.o dma_port.o icm.o property.o xdomain.o
+thunderbolt-objs += domain.o dma_port.o icm.o property.o xdomain.o lc.o
diff --git a/drivers/thunderbolt/lc.c b/drivers/thunderbolt/lc.c
new file mode 100644
index 000000000000..2134a55ed837
--- /dev/null
+++ b/drivers/thunderbolt/lc.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Thunderbolt link controller support
+ *
+ * Copyright (C) 2019, Intel Corporation
+ * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
+ */
+
+#include "tb.h"
+
+/**
+ * tb_lc_read_uuid() - Read switch UUID from link controller common register
+ * @sw: Switch whose UUID is read
+ * @uuid: UUID is placed here
+ */
+int tb_lc_read_uuid(struct tb_switch *sw, u32 *uuid)
+{
+ if (!sw->cap_lc)
+ return -EINVAL;
+ return tb_sw_read(sw, uuid, TB_CFG_SWITCH, sw->cap_lc + TB_LC_FUSE, 4);
+}
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
index 1e29c06947af..63ff4c753d89 100644
--- a/drivers/thunderbolt/switch.c
+++ b/drivers/thunderbolt/switch.c
@@ -1182,6 +1182,10 @@ struct tb_switch *tb_switch_alloc(struct tb *tb, struct device *parent,
}
sw->cap_plug_events = cap;
+ cap = tb_switch_find_vse_cap(sw, TB_VSE_CAP_LINK_CONTROLLER);
+ if (cap > 0)
+ sw->cap_lc = cap;
+
/* Root switch is always authorized */
if (!route)
sw->authorized = true;
@@ -1278,22 +1282,17 @@ int tb_switch_configure(struct tb_switch *sw)
static int tb_switch_set_uuid(struct tb_switch *sw)
{
u32 uuid[4];
- int cap, ret;
+ int ret;
- ret = 0;
if (sw->uuid)
- return ret;
+ return 0;
/*
* The newer controllers include fused UUID as part of link
* controller specific registers
*/
- cap = tb_switch_find_vse_cap(sw, TB_VSE_CAP_LINK_CONTROLLER);
- if (cap > 0) {
- ret = tb_sw_read(sw, uuid, TB_CFG_SWITCH, cap + 3, 4);
- if (ret)
- return ret;
- } else {
+ ret = tb_lc_read_uuid(sw, uuid);
+ if (ret) {
/*
* ICM generates UUID based on UID and fills the upper
* two words with ones. This is not strictly following
@@ -1308,8 +1307,8 @@ static int tb_switch_set_uuid(struct tb_switch *sw)
sw->uuid = kmemdup(uuid, sizeof(uuid), GFP_KERNEL);
if (!sw->uuid)
- ret = -ENOMEM;
- return ret;
+ return -ENOMEM;
+ return 0;
}
static int tb_switch_add_dma_port(struct tb_switch *sw)
diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
index a166265dfcf9..e52d39b25266 100644
--- a/drivers/thunderbolt/tb.h
+++ b/drivers/thunderbolt/tb.h
@@ -63,6 +63,7 @@ struct tb_switch_nvm {
* @device_name: Name of the device (or %NULL if not known)
* @generation: Switch Thunderbolt generation
* @cap_plug_events: Offset to the plug events capability (%0 if not found)
+ * @cap_lc: Offset to the link controller capability (%0 if not found)
* @is_unplugged: The switch is going away
* @drom: DROM of the switch (%NULL if not found)
* @nvm: Pointer to the NVM if the switch has one (%NULL otherwise)
@@ -96,6 +97,7 @@ struct tb_switch {
const char *device_name;
unsigned int generation;
int cap_plug_events;
+ int cap_lc;
bool is_unplugged;
u8 *drom;
struct tb_switch_nvm *nvm;
@@ -462,6 +464,7 @@ bool tb_path_is_invalid(struct tb_path *path);
int tb_drom_read(struct tb_switch *sw);
int tb_drom_read_uid_only(struct tb_switch *sw, u64 *uid);
+int tb_lc_read_uuid(struct tb_switch *sw, u32 *uuid);
static inline int tb_route_length(u64 route)
{
diff --git a/drivers/thunderbolt/tb_regs.h b/drivers/thunderbolt/tb_regs.h
index 6f1ff04ee195..4895ae9f0b40 100644
--- a/drivers/thunderbolt/tb_regs.h
+++ b/drivers/thunderbolt/tb_regs.h
@@ -237,5 +237,7 @@ struct tb_regs_hop {
u32 unknown3:4; /* set to zero */
} __packed;
+/* Common link controller registers */
+#define TB_LC_FUSE 0x03
#endif
--
2.20.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.