Commit a7bab6f8 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

Merge tag 'br-v6.2e' of git://linuxtv.org/hverkuil/media_tree into media_stage

Tag branch

* tag 'br-v6.2e' of git://linuxtv.org/hverkuil/media_tree: (29 commits)
  media: davinci/vpbe: Fix a typo ("defualt_mode")
  media: sun6i-csi: Remove unnecessary print function dev_err()
  media: Documentation: Drop deprecated bytesused == 0
  media: platform: exynos4-is: fix return value check in fimc_md_probe()
  media: dvb-core: remove variable n, turn for-loop to while-loop
  media: vivid: fix compose size exceed boundary
  media: rkisp1: make const arrays ae_wnd_num and hist_wnd_num static
  media: dvb-core: Fix UAF due to refcount races at releasing
  media: rkvdec: Add required padding
  media: aspeed: Extend debug message
  media: aspeed: Support aspeed mode to reduce compressed data
  media: Documentation: aspeed-video: Add user documentation for the aspeed-video driver
  media: v4l2-ctrls: Reserve controls for ASPEED
  media: v4l: Add definition for the Aspeed JPEG format
  staging: media: tegra-video: fix device_node use after free
  staging: media: tegra-video: fix chan->mipi value on error
  media: cedrus: initialize controls a bit later
  media: cedrus: prefer untiled capture format
  media: cedrus: Remove cedrus_codec enum
  media: cedrus: set codec ops immediately
  ...
parents 997149b8 d668c0a7
.. SPDX-License-Identifier: GPL-2.0
.. include:: <isonum.txt>
ASPEED video driver
===================
ASPEED Video Engine found on AST2400/2500/2600 SoC supports high performance
video compressions with a wide range of video quality and compression ratio
options. The adopted compressing algorithm is a modified JPEG algorithm.
There are 2 types of compressions in this IP.
* JPEG JFIF standard mode: for single frame and management compression
* ASPEED proprietary mode: for multi-frame and differential compression.
Support 2-pass (high quality) video compression scheme (Patent pending by
ASPEED). Provide visually lossless video compression quality or to reduce
the network average loading under intranet KVM applications.
VIDIOC_S_FMT can be used to choose which format you want. V4L2_PIX_FMT_JPEG
stands for JPEG JFIF standard mode; V4L2_PIX_FMT_AJPG stands for ASPEED
proprietary mode.
More details on the ASPEED video hardware operations can be found in
*chapter 6.2.16 KVM Video Driver* of SDK_User_Guide which available on
AspeedTech-BMC/openbmc/releases.
The ASPEED video driver implements the following driver-specific control:
``V4L2_CID_ASPEED_HQ_MODE``
---------------------------
Enable/Disable ASPEED's High quality mode. This is a private control
that can be used to enable high quality for aspeed proprietary mode.
.. flat-table::
:header-rows: 0
:stub-columns: 0
:widths: 1 4
* - ``(0)``
- ASPEED HQ mode is disabled.
* - ``(1)``
- ASPEED HQ mode is enabled.
``V4L2_CID_ASPEED_HQ_JPEG_QUALITY``
-----------------------------------
Define the quality of ASPEED's High quality mode. This is a private control
that can be used to decide compression quality if High quality mode enabled
. Higher the value, better the quality and bigger the size.
.. flat-table::
:header-rows: 0
:stub-columns: 0
:widths: 1 4
* - ``(1)``
- minimum
* - ``(12)``
- maximum
* - ``(1)``
- step
* - ``(1)``
- default
**Copyright** |copy| 2022 ASPEED Technology Inc.
......@@ -31,6 +31,7 @@ For more details see the file COPYING in the source distribution of Linux.
:maxdepth: 5
:numbered:
aspeed-video
ccs
cx2341x-uapi
dw100
......
......@@ -187,10 +187,8 @@ struct v4l2_buffer
on the negotiated data format and may change with each buffer for
compressed variable size data like JPEG images. Drivers must set
this field when ``type`` refers to a capture stream, applications
when it refers to an output stream. If the application sets this
to 0 for an output stream, then ``bytesused`` will be set to the
size of the buffer (see the ``length`` field of this struct) by
the driver. For multiplanar formats this field is ignored and the
when it refers to an output stream. For multiplanar formats this field
is ignored and the
``planes`` pointer is used instead.
* - __u32
- ``flags``
......@@ -327,10 +325,7 @@ struct v4l2_plane
- ``bytesused``
- The number of bytes occupied by data in the plane (its payload).
Drivers must set this field when ``type`` refers to a capture
stream, applications when it refers to an output stream. If the
application sets this to 0 for an output stream, then
``bytesused`` will be set to the size of the plane (see the
``length`` field of this struct) by the driver.
stream, applications when it refers to an output stream.
.. note::
......
......@@ -258,6 +258,23 @@ please make a proposal on the linux-media mailing list.
and it is used by various multimedia hardware blocks like GPU, display
controllers, ISP and video accelerators.
It contains four planes for progressive video.
* .. _V4L2-PIX-FMT-AJPG:
- ``V4L2_PIX_FMT_AJPG``
- 'AJPG'
- ASPEED JPEG format used by the aspeed-video driver on Aspeed platforms,
which is generally adapted for remote KVM.
On each frame compression, I will compare the new frame with previous
one to decide which macroblock's data is changed, and only the changed
macroblocks will be compressed.
The implementation is based on AST2600 A3 datasheet, revision 0.9, which
is not publicly available. Or you can reference Video stream data format
– ASPEED mode compression of SDK_User_Guide which available on
AspeedTech-BMC/openbmc/releases.
Decoder's implementation can be found here,
`aspeed_codec <https://github.com/AspeedTech-BMC/aspeed_codec/>`__
.. raw:: latex
\normalsize
......@@ -790,6 +790,11 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
if (mutex_lock_interruptible(&dmxdev->mutex))
return -ERESTARTSYS;
if (dmxdev->exit) {
mutex_unlock(&dmxdev->mutex);
return -ENODEV;
}
for (i = 0; i < dmxdev->filternum; i++)
if (dmxdev->filter[i].state == DMXDEV_STATE_FREE)
break;
......@@ -1448,7 +1453,10 @@ EXPORT_SYMBOL(dvb_dmxdev_init);
void dvb_dmxdev_release(struct dmxdev *dmxdev)
{
mutex_lock(&dmxdev->mutex);
dmxdev->exit = 1;
mutex_unlock(&dmxdev->mutex);
if (dmxdev->dvbdev->users > 1) {
wait_event(dmxdev->dvbdev->wait_queue,
dmxdev->dvbdev->users == 1);
......
......@@ -233,7 +233,7 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
{
struct dvb_demux *demux = feed->demux;
struct dmx_section_feed *sec = &feed->feed.sec;
u16 limit, seclen, n;
u16 limit, seclen;
if (sec->tsfeedp >= DMX_MAX_SECFEED_SIZE)
return 0;
......@@ -262,7 +262,7 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
/* to be sure always set secbuf */
sec->secbuf = sec->secbuf_base + sec->secbufp;
for (n = 0; sec->secbufp + 2 < limit; n++) {
while (sec->secbufp + 2 < limit) {
seclen = section_length(sec->secbuf);
if (seclen <= 0 || seclen > DMX_MAX_SECTION_SIZE
|| seclen + sec->secbufp > limit)
......
......@@ -51,14 +51,14 @@ struct img_sw_addr {
struct img_plane_format {
u32 size;
u16 stride;
u32 stride;
} __packed;
struct img_pix_format {
u16 width;
u16 height;
u32 width;
u32 height;
u32 colorformat; /* enum mdp_color */
u16 ycbcr_prof; /* enum mdp_ycbcr_profile */
u32 ycbcr_prof; /* enum mdp_ycbcr_profile */
struct img_plane_format plane_fmt[IMG_MAX_PLANES];
} __packed;
......@@ -72,10 +72,10 @@ struct img_image_buffer {
#define IMG_SUBPIXEL_SHIFT 20
struct img_crop {
s16 left;
s16 top;
u16 width;
u16 height;
s32 left;
s32 top;
u32 width;
u32 height;
u32 left_subpix;
u32 top_subpix;
u32 width_subpix;
......@@ -90,24 +90,24 @@ struct img_crop {
struct img_input {
struct img_image_buffer buffer;
u16 flags; /* HDR, DRE, dither */
u32 flags; /* HDR, DRE, dither */
} __packed;
struct img_output {
struct img_image_buffer buffer;
struct img_crop crop;
s16 rotation;
u16 flags; /* H-flip, sharpness, dither */
s32 rotation;
u32 flags; /* H-flip, sharpness, dither */
} __packed;
struct img_ipi_frameparam {
u32 index;
u32 frame_no;
struct img_timeval timestamp;
u8 type; /* enum mdp_stream_type */
u8 state;
u8 num_inputs;
u8 num_outputs;
u32 type; /* enum mdp_stream_type */
u32 state;
u32 num_inputs;
u32 num_outputs;
u64 drv_data;
struct img_input inputs[IMG_MAX_HW_INPUTS];
struct img_output outputs[IMG_MAX_HW_OUTPUTS];
......@@ -123,51 +123,51 @@ struct img_sw_buffer {
} __packed;
struct img_ipi_param {
u8 usage;
u32 usage;
struct img_sw_buffer frm_param;
} __packed;
struct img_frameparam {
struct list_head list_entry;
struct img_ipi_frameparam frameparam;
};
} __packed;
/* ISP-MDP generic output information */
struct img_comp_frame {
u32 output_disable:1;
u32 bypass:1;
u16 in_width;
u16 in_height;
u16 out_width;
u16 out_height;
u32 output_disable;
u32 bypass;
u32 in_width;
u32 in_height;
u32 out_width;
u32 out_height;
struct img_crop crop;
u16 in_total_width;
u16 out_total_width;
u32 in_total_width;
u32 out_total_width;
} __packed;
struct img_region {
s16 left;
s16 right;
s16 top;
s16 bottom;
s32 left;
s32 right;
s32 top;
s32 bottom;
} __packed;
struct img_offset {
s16 left;
s16 top;
s32 left;
s32 top;
u32 left_subpix;
u32 top_subpix;
} __packed;
struct img_comp_subfrm {
u32 tile_disable:1;
u32 tile_disable;
struct img_region in;
struct img_region out;
struct img_offset luma;
struct img_offset chroma;
s16 out_vertical; /* Output vertical index */
s16 out_horizontal; /* Output horizontal index */
s32 out_vertical; /* Output vertical index */
s32 out_horizontal; /* Output horizontal index */
} __packed;
#define IMG_MAX_SUBFRAMES 14
......@@ -250,8 +250,8 @@ struct isp_data {
} __packed;
struct img_compparam {
u16 type; /* enum mdp_comp_type */
u16 id; /* enum mtk_mdp_comp_id */
u32 type; /* enum mdp_comp_id */
u32 id; /* engine alias_id */
u32 input;
u32 outputs[IMG_MAX_HW_OUTPUTS];
u32 num_outputs;
......@@ -273,12 +273,12 @@ struct img_mux {
u32 reg;
u32 value;
u32 subsys_id;
};
} __packed;
struct img_mmsys_ctrl {
struct img_mux sets[IMG_MAX_COMPONENTS * 2];
u32 num_sets;
};
} __packed;
struct img_config {
struct img_compparam components[IMG_MAX_COMPONENTS];
......
......@@ -252,10 +252,9 @@ static int mdp_cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *pkt,
dma_addr_t dma_addr;
pkt->va_base = kzalloc(size, GFP_KERNEL);
if (!pkt->va_base) {
kfree(pkt);
if (!pkt->va_base)
return -ENOMEM;
}
pkt->buf_size = size;
pkt->cl = (void *)client;
......@@ -368,25 +367,30 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
if (!cmd) {
ret = -ENOMEM;
goto err_cmdq_data;
goto err_cancel_job;
}
if (mdp_cmdq_pkt_create(mdp->cmdq_clt, &cmd->pkt, SZ_16K)) {
ret = -ENOMEM;
goto err_cmdq_data;
}
ret = mdp_cmdq_pkt_create(mdp->cmdq_clt, &cmd->pkt, SZ_16K);
if (ret)
goto err_free_cmd;
comps = kcalloc(param->config->num_components, sizeof(*comps),
GFP_KERNEL);
if (!comps) {
ret = -ENOMEM;
goto err_cmdq_data;
goto err_destroy_pkt;
}
path = kzalloc(sizeof(*path), GFP_KERNEL);
if (!path) {
ret = -ENOMEM;
goto err_cmdq_data;
goto err_free_comps;
}
ret = mtk_mutex_prepare(mdp->mdp_mutex[MDP_PIPE_RDMA0]);
if (ret) {
dev_err(dev, "Fail to enable mutex clk\n");
goto err_free_path;
}
path->mdp_dev = mdp;
......@@ -406,15 +410,13 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
ret = mdp_path_ctx_init(mdp, path);
if (ret) {
dev_err(dev, "mdp_path_ctx_init error\n");
goto err_cmdq_data;
goto err_free_path;
}
mtk_mutex_prepare(mdp->mdp_mutex[MDP_PIPE_RDMA0]);
ret = mdp_path_config(mdp, cmd, path);
if (ret) {
dev_err(dev, "mdp_path_config error\n");
goto err_cmdq_data;
goto err_free_path;
}
cmdq_pkt_finalize(&cmd->pkt);
......@@ -431,10 +433,8 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
cmd->mdp_ctx = param->mdp_ctx;
ret = mdp_comp_clocks_on(&mdp->pdev->dev, cmd->comps, cmd->num_comps);
if (ret) {
dev_err(dev, "comp %d failed to enable clock!\n", ret);
goto err_clock_off;
}
if (ret)
goto err_free_path;
dma_sync_single_for_device(mdp->cmdq_clt->chan->mbox->dev,
cmd->pkt.pa_base, cmd->pkt.cmd_buf_size,
......@@ -450,17 +450,20 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
return 0;
err_clock_off:
mtk_mutex_unprepare(mdp->mdp_mutex[MDP_PIPE_RDMA0]);
mdp_comp_clocks_off(&mdp->pdev->dev, cmd->comps,
cmd->num_comps);
err_cmdq_data:
err_free_path:
mtk_mutex_unprepare(mdp->mdp_mutex[MDP_PIPE_RDMA0]);
kfree(path);
atomic_dec(&mdp->job_count);
wake_up(&mdp->callback_wq);
if (cmd && cmd->pkt.buf_size > 0)
mdp_cmdq_pkt_destroy(&cmd->pkt);
err_free_comps:
kfree(comps);
err_destroy_pkt:
mdp_cmdq_pkt_destroy(&cmd->pkt);
err_free_cmd:
kfree(cmd);
err_cancel_job:
atomic_dec(&mdp->job_count);
return ret;
}
EXPORT_SYMBOL_GPL(mdp_cmdq_send);
......@@ -699,12 +699,22 @@ int mdp_comp_clock_on(struct device *dev, struct mdp_comp *comp)
dev_err(dev,
"Failed to enable clk %d. type:%d id:%d\n",
i, comp->type, comp->id);
pm_runtime_put(comp->comp_dev);
return ret;
goto err_revert;
}
}
return 0;
err_revert:
while (--i >= 0) {
if (IS_ERR_OR_NULL(comp->clks[i]))
continue;
clk_disable_unprepare(comp->clks[i]);
}
if (comp->comp_dev)
pm_runtime_put_sync(comp->comp_dev);
return ret;
}
void mdp_comp_clock_off(struct device *dev, struct mdp_comp *comp)
......@@ -723,11 +733,13 @@ void mdp_comp_clock_off(struct device *dev, struct mdp_comp *comp)
int mdp_comp_clocks_on(struct device *dev, struct mdp_comp *comps, int num)
{
int i;
int i, ret;
for (i = 0; i < num; i++)
if (mdp_comp_clock_on(dev, &comps[i]) != 0)
return ++i;
for (i = 0; i < num; i++) {
ret = mdp_comp_clock_on(dev, &comps[i]);
if (ret)
return ret;
}
return 0;
}
......
......@@ -196,27 +196,27 @@ static int mdp_probe(struct platform_device *pdev)
mm_pdev = __get_pdev_by_id(pdev, MDP_INFRA_MMSYS);
if (!mm_pdev) {
ret = -ENODEV;
goto err_return;
goto err_destroy_device;
}
mdp->mdp_mmsys = &mm_pdev->dev;
mm_pdev = __get_pdev_by_id(pdev, MDP_INFRA_MUTEX);
if (WARN_ON(!mm_pdev)) {
ret = -ENODEV;
goto err_return;
goto err_destroy_device;
}
for (i = 0; i < MDP_PIPE_MAX; i++) {
mdp->mdp_mutex[i] = mtk_mutex_get(&mm_pdev->dev);
if (!mdp->mdp_mutex[i]) {
ret = -ENODEV;
goto err_return;
goto err_free_mutex;
}
}
ret = mdp_comp_config(mdp);
if (ret) {
dev_err(dev, "Failed to config mdp components\n");
goto err_return;
goto err_free_mutex;
}
mdp->job_wq = alloc_workqueue(MDP_MODULE_NAME, WQ_FREEZABLE, 0);
......@@ -287,11 +287,12 @@ static int mdp_probe(struct platform_device *pdev)
destroy_workqueue(mdp->job_wq);
err_deinit_comp:
mdp_comp_destroy(mdp);
err_return:
err_free_mutex:
for (i = 0; i < MDP_PIPE_MAX; i++)
if (mdp)
mtk_mutex_put(mdp->mdp_mutex[i]);
mtk_mutex_put(mdp->mdp_mutex[i]);
err_destroy_device:
kfree(mdp);
err_return:
dev_dbg(dev, "Errno %d\n", ret);
return ret;
}
......
......@@ -715,7 +715,7 @@ static void rkisp1_aec_config_v12(struct rkisp1_params *params,
u32 exp_ctrl;
u32 block_hsize, block_vsize;
u32 wnd_num_idx = 1;
const u32 ae_wnd_num[] = { 5, 9, 15, 15 };
static const u32 ae_wnd_num[] = { 5, 9, 15, 15 };
/* avoid to override the old enable value */
exp_ctrl = rkisp1_read(params->rkisp1, RKISP1_CIF_ISP_EXP_CTRL);
......@@ -822,7 +822,7 @@ static void rkisp1_hst_config_v12(struct rkisp1_params *params,
u32 block_hsize, block_vsize;
u32 wnd_num_idx, hist_weight_num, hist_ctrl, value;
u8 weight15x15[RKISP1_CIF_ISP_HIST_WEIGHT_REG_SIZE_V12];
const u32 hist_wnd_num[] = { 5, 9, 15, 15 };
static const u32 hist_wnd_num[] = { 5, 9, 15, 15 };
/* now we just support 9x9 window */
wnd_num_idx = 1;
......
......@@ -1472,7 +1472,7 @@ static int fimc_md_probe(struct platform_device *pdev)
pinctrl = devm_pinctrl_get(dev);
if (IS_ERR(pinctrl)) {
ret = PTR_ERR(pinctrl);
if (ret != EPROBE_DEFER)
if (ret != -EPROBE_DEFER)
dev_err(dev, "Failed to get pinctrl: %d\n", ret);
goto err_clk;
}
......
......@@ -913,7 +913,6 @@ static int sun6i_csi_resources_setup(struct sun6i_csi_device *csi_dev,
irq = platform_get_irq(platform_dev, 0);
if (irq < 0) {
dev_err(dev, "failed to get interrupt\n");
ret = -ENXIO;
goto error_clock_rate_exclusive;
}
......
......@@ -973,6 +973,7 @@ int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection
if (dev->has_compose_cap) {
v4l2_rect_set_min_size(compose, &min_rect);
v4l2_rect_set_max_size(compose, &max_rect);
v4l2_rect_map_inside(compose, &fmt);
}
dev->fmt_cap_rect = fmt;
tpg_s_buf_height(&dev->tpg, fmt.height);
......
......@@ -1497,6 +1497,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
case V4L2_PIX_FMT_MT21C: descr = "Mediatek Compressed Format"; break;
case V4L2_PIX_FMT_QC08C: descr = "QCOM Compressed 8-bit Format"; break;
case V4L2_PIX_FMT_QC10C: descr = "QCOM Compressed 10-bit Format"; break;
case V4L2_PIX_FMT_AJPG: descr = "Aspeed JPEG"; break;
default:
if (fmt->description[0])
return;
......
......@@ -84,6 +84,8 @@ struct rkvdec_vp9_probs {
struct rkvdec_vp9_inter_frame_probs inter;
struct rkvdec_vp9_intra_only_frame_probs intra_only;
};
/* 128 bit alignment */
u8 padding1[11];
};
/* Data structure describing auxiliary buffer format. */
......@@ -1006,6 +1008,7 @@ static int rkvdec_vp9_start(struct rkvdec_ctx *ctx)
ctx->priv = vp9_ctx;
BUILD_BUG_ON(sizeof(priv_tbl->probs) % 16); /* ensure probs size is 128-bit aligned */
priv_tbl = dma_alloc_coherent(rkvdec->dev, sizeof(*priv_tbl),
&vp9_ctx->priv_tbl.dma, GFP_KERNEL);
if (!priv_tbl) {
......
......@@ -77,56 +77,56 @@ static const struct cedrus_control cedrus_controls[] = {
.cfg = {
.id = V4L2_CID_STATELESS_MPEG2_SEQUENCE,
},
.codec = CEDRUS_CODEC_MPEG2,
.capabilities = CEDRUS_CAPABILITY_MPEG2_DEC,
},
{
.cfg = {
.id = V4L2_CID_STATELESS_MPEG2_PICTURE,
},
.codec = CEDRUS_CODEC_MPEG2,
.capabilities = CEDRUS_CAPABILITY_MPEG2_DEC,
},
{
.cfg = {
.id = V4L2_CID_STATELESS_MPEG2_QUANTISATION,
},
.codec = CEDRUS_CODEC_MPEG2,
.capabilities = CEDRUS_CAPABILITY_MPEG2_DEC,
},
{
.cfg = {
.id = V4L2_CID_STATELESS_H264_DECODE_PARAMS,
},
.codec = CEDRUS_CODEC_H264,
.capabilities = CEDRUS_CAPABILITY_H264_DEC,
},
{
.cfg = {
.id = V4L2_CID_STATELESS_H264_SLICE_PARAMS,
},
.codec = CEDRUS_CODEC_H264,
.capabilities = CEDRUS_CAPABILITY_H264_DEC,
},
{
.cfg = {
.id = V4L2_CID_STATELESS_H264_SPS,
.ops = &cedrus_ctrl_ops,
},
.codec = CEDRUS_CODEC_H264,
.capabilities = CEDRUS_CAPABILITY_H264_DEC,
},
{
.cfg = {
.id = V4L2_CID_STATELESS_H264_PPS,
},
.codec = CEDRUS_CODEC_H264,
.capabilities = CEDRUS_CAPABILITY_H264_DEC,
},
{
.cfg = {
.id = V4L2_CID_STATELESS_H264_SCALING_MATRIX,
},
.codec = CEDRUS_CODEC_H264,
.capabilities = CEDRUS_CAPABILITY_H264_DEC,
},
{
.cfg = {
.id = V4L2_CID_STATELESS_H264_PRED_WEIGHTS,
},
.codec = CEDRUS_CODEC_H264,
.capabilities = CEDRUS_CAPABILITY_H264_DEC,
},
{
.cfg = {
......@@ -134,7 +134,7 @@ static const struct cedrus_control cedrus_controls[] = {
.max = V4L2_STATELESS_H264_DECODE_MODE_SLICE_BASED,
.def = V4L2_STATELESS_H264_DECODE_MODE_SLICE_BASED,
},
.codec = CEDRUS_CODEC_H264,
.capabilities = CEDRUS_CAPABILITY_H264_DEC,
},
{
.cfg = {
......@@ -142,7 +142,7 @@ static const struct cedrus_control cedrus_controls[] = {
.max = V4L2_STATELESS_H264_START_CODE_NONE,
.def = V4L2_STATELESS_H264_START_CODE_NONE,
},
.codec = CEDRUS_CODEC_H264,
.capabilities = CEDRUS_CAPABILITY_H264_DEC,
},
/*
* We only expose supported profiles information,
......@@ -160,20 +160,20 @@ static const struct cedrus_control cedrus_controls[] = {
.menu_skip_mask =
BIT(V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED),
},
.codec = CEDRUS_CODEC_H264,
.capabilities = CEDRUS_CAPABILITY_H264_DEC,
},
{
.cfg = {
.id = V4L2_CID_STATELESS_HEVC_SPS,
.ops = &cedrus_ctrl_ops,
},
.codec = CEDRUS_CODEC_H265,
.capabilities = CEDRUS_CAPABILITY_H265_DEC,
},
{
.cfg = {
.id = V4L2_CID_STATELESS_HEVC_PPS,
},
.codec = CEDRUS_CODEC_H265,
.capabilities = CEDRUS_CAPABILITY_H265_DEC,
},
{
.cfg = {
......@@ -181,13 +181,13 @@ static const struct cedrus_control cedrus_controls[] = {
/* The driver can only handle 1 entry per slice for now */
.dims = { 1 },
},
.codec = CEDRUS_CODEC_H265,
.capabilities = CEDRUS_CAPABILITY_H265_DEC,
},
{
.cfg = {
.id = V4L2_CID_STATELESS_HEVC_SCALING_MATRIX,
},
.codec = CEDRUS_CODEC_H265,
.capabilities = CEDRUS_CAPABILITY_H265_DEC,
},
{
.cfg = {
......@@ -197,7 +197,7 @@ static const struct cedrus_control cedrus_controls[] = {
.max = 0xffffffff,
.step = 1,
},
.codec = CEDRUS_CODEC_H265,
.capabilities = CEDRUS_CAPABILITY_H265_DEC,
},
{
.cfg = {
......@@ -205,7 +205,7 @@ static const struct cedrus_control cedrus_controls[] = {
.max = V4L2_STATELESS_HEVC_DECODE_MODE_SLICE_BASED,
.def = V4L2_STATELESS_HEVC_DECODE_MODE_SLICE_BASED,
},
.codec = CEDRUS_CODEC_H265,
.capabilities = CEDRUS_CAPABILITY_H265_DEC,
},
{
.cfg = {
......@@ -213,19 +213,19 @@ static const struct cedrus_control cedrus_controls[] = {
.max = V4L2_STATELESS_HEVC_START_CODE_NONE,
.def = V4L2_STATELESS_HEVC_START_CODE_NONE,
},
.codec = CEDRUS_CODEC_H265,
.capabilities = CEDRUS_CAPABILITY_H265_DEC,
},
{
.cfg = {
.id = V4L2_CID_STATELESS_VP8_FRAME,
},
.codec = CEDRUS_CODEC_VP8,
.capabilities = CEDRUS_CAPABILITY_VP8_DEC,
},
{
.cfg = {
.id = V4L2_CID_STATELESS_HEVC_DECODE_PARAMS,
},
.codec = CEDRUS_CODEC_H265,
.capabilities = CEDRUS_CAPABILITY_H265_DEC,
},
};
......@@ -258,7 +258,7 @@ static int cedrus_init_ctrls(struct cedrus_dev *dev, struct cedrus_ctx *ctx)
struct v4l2_ctrl_handler *hdl = &ctx->hdl;
struct v4l2_ctrl *ctrl;
unsigned int ctrl_size;
unsigned int i;
unsigned int i, j;
v4l2_ctrl_handler_init(hdl, CEDRUS_CONTROLS_COUNT);
if (hdl->error) {
......@@ -274,7 +274,11 @@ static int cedrus_init_ctrls(struct cedrus_dev *dev, struct cedrus_ctx *ctx)
if (!ctx->ctrls)
return -ENOMEM;
j = 0;
for (i = 0; i < CEDRUS_CONTROLS_COUNT; i++) {
if (!cedrus_is_capable(ctx, cedrus_controls[i].capabilities))
continue;
ctrl = v4l2_ctrl_new_custom(hdl, &cedrus_controls[i].cfg,
NULL);
if (hdl->error) {
......@@ -289,7 +293,7 @@ static int cedrus_init_ctrls(struct cedrus_dev *dev, struct cedrus_ctx *ctx)
return hdl->error;
}
ctx->ctrls[i] = ctrl;
ctx->ctrls[j++] = ctrl;
}
ctx->fh.ctrl_handler = hdl;
......@@ -351,26 +355,18 @@ static int cedrus_open(struct file *file)
file->private_data = &ctx->fh;
ctx->dev = dev;
ret = cedrus_init_ctrls(dev, ctx);
if (ret)
goto err_free;
ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx,
&cedrus_queue_init);
if (IS_ERR(ctx->fh.m2m_ctx)) {
ret = PTR_ERR(ctx->fh.m2m_ctx);
goto err_ctrls;
goto err_free;
}
ctx->dst_fmt.pixelformat = V4L2_PIX_FMT_NV12_32L32;
cedrus_prepare_format(&ctx->dst_fmt);
ctx->src_fmt.pixelformat = V4L2_PIX_FMT_MPEG2_SLICE;
/*
* TILED_NV12 has more strict requirements, so copy the width and
* height to src_fmt to ensure that is matches the dst_fmt resolution.
*/
ctx->src_fmt.width = ctx->dst_fmt.width;
ctx->src_fmt.height = ctx->dst_fmt.height;
cedrus_prepare_format(&ctx->src_fmt);
cedrus_reset_out_format(ctx);
ret = cedrus_init_ctrls(dev, ctx);
if (ret)
goto err_m2m_release;
v4l2_fh_add(&ctx->fh);
......@@ -378,8 +374,8 @@ static int cedrus_open(struct file *file)
return 0;
err_ctrls:
v4l2_ctrl_handler_free(&ctx->hdl);
err_m2m_release:
v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
err_free:
kfree(ctx);
mutex_unlock(&dev->dev_mutex);
......@@ -460,11 +456,6 @@ static int cedrus_probe(struct platform_device *pdev)
return ret;
}
dev->dec_ops[CEDRUS_CODEC_MPEG2] = &cedrus_dec_ops_mpeg2;
dev->dec_ops[CEDRUS_CODEC_H264] = &cedrus_dec_ops_h264;
dev->dec_ops[CEDRUS_CODEC_H265] = &cedrus_dec_ops_h265;
dev->dec_ops[CEDRUS_CODEC_VP8] = &cedrus_dec_ops_vp8;
mutex_init(&dev->dev_mutex);
INIT_DELAYED_WORK(&dev->watchdog_work, cedrus_watchdog);
......
......@@ -35,14 +35,6 @@
#define CEDRUS_CAPABILITY_VP8_DEC BIT(4)
#define CEDRUS_CAPABILITY_H265_10_DEC BIT(5)
enum cedrus_codec {
CEDRUS_CODEC_MPEG2,
CEDRUS_CODEC_H264,
CEDRUS_CODEC_H265,
CEDRUS_CODEC_VP8,
CEDRUS_CODEC_LAST,
};
enum cedrus_irq_status {
CEDRUS_IRQ_NONE,
CEDRUS_IRQ_ERROR,
......@@ -57,7 +49,7 @@ enum cedrus_h264_pic_type {
struct cedrus_control {
struct v4l2_ctrl_config cfg;
enum cedrus_codec codec;
unsigned int capabilities;
};
struct cedrus_h264_run {
......@@ -118,7 +110,7 @@ struct cedrus_ctx {
struct v4l2_pix_format src_fmt;
struct v4l2_pix_format dst_fmt;
enum cedrus_codec current_codec;
struct cedrus_dec_ops *current_codec;
struct v4l2_ctrl_handler hdl;
struct v4l2_ctrl **ctrls;
......@@ -185,7 +177,6 @@ struct cedrus_dev {
struct platform_device *pdev;
struct device *dev;
struct v4l2_m2m_dev *m2m_dev;
struct cedrus_dec_ops *dec_ops[CEDRUS_CODEC_LAST];
/* Device file mutex */
struct mutex dev_mutex;
......@@ -268,6 +259,12 @@ vb2_to_cedrus_buffer(const struct vb2_buffer *p)
return vb2_v4l2_to_cedrus_buffer(to_vb2_v4l2_buffer(p));
}
static inline bool
cedrus_is_capable(struct cedrus_ctx *ctx, unsigned int capabilities)
{
return (ctx->dev->capabilities & capabilities) == capabilities;
}
void *cedrus_find_control_data(struct cedrus_ctx *ctx, u32 id);
u32 cedrus_get_num_of_controls(struct cedrus_ctx *ctx, u32 id);
......
......@@ -94,7 +94,7 @@ void cedrus_device_run(void *priv)
cedrus_dst_format_set(dev, &ctx->dst_fmt);
error = dev->dec_ops[ctx->current_codec]->setup(ctx, &run);
error = ctx->current_codec->setup(ctx, &run);
if (error)
v4l2_err(&ctx->dev->v4l2_dev,
"Failed to setup decoding job: %d\n", error);
......@@ -110,7 +110,7 @@ void cedrus_device_run(void *priv)
schedule_delayed_work(&dev->watchdog_work,
msecs_to_jiffies(2000));
dev->dec_ops[ctx->current_codec]->trigger(ctx);
ctx->current_codec->trigger(ctx);
} else {
v4l2_m2m_buf_done_and_job_finish(ctx->dev->m2m_dev,
ctx->fh.m2m_ctx,
......
......@@ -497,7 +497,7 @@ static int cedrus_h264_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
{
struct cedrus_dev *dev = ctx->dev;
cedrus_engine_enable(ctx, CEDRUS_CODEC_H264);
cedrus_engine_enable(ctx);
cedrus_write(dev, VE_H264_SDROT_CTRL, 0);
cedrus_write(dev, VE_H264_EXTRA_BUFFER1,
......
......@@ -463,7 +463,7 @@ static int cedrus_h265_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
}
/* Activate H265 engine. */
cedrus_engine_enable(ctx, CEDRUS_CODEC_H265);
cedrus_engine_enable(ctx);
/* Source offset and length in bits. */
......
......@@ -31,7 +31,7 @@
#include "cedrus_hw.h"
#include "cedrus_regs.h"
int cedrus_engine_enable(struct cedrus_ctx *ctx, enum cedrus_codec codec)
int cedrus_engine_enable(struct cedrus_ctx *ctx)
{
u32 reg = 0;
......@@ -42,18 +42,18 @@ int cedrus_engine_enable(struct cedrus_ctx *ctx, enum cedrus_codec codec)
reg |= VE_MODE_REC_WR_MODE_2MB;
reg |= VE_MODE_DDR_MODE_BW_128;
switch (codec) {
case CEDRUS_CODEC_MPEG2:
switch (ctx->src_fmt.pixelformat) {
case V4L2_PIX_FMT_MPEG2_SLICE:
reg |= VE_MODE_DEC_MPEG;
break;
/* H.264 and VP8 both use the same decoding mode bit. */
case CEDRUS_CODEC_H264:
case CEDRUS_CODEC_VP8:
case V4L2_PIX_FMT_H264_SLICE:
case V4L2_PIX_FMT_VP8_FRAME:
reg |= VE_MODE_DEC_H264;
break;
case CEDRUS_CODEC_H265:
case V4L2_PIX_FMT_HEVC_SLICE:
reg |= VE_MODE_DEC_H265;
break;
......@@ -132,12 +132,12 @@ static irqreturn_t cedrus_irq(int irq, void *data)
return IRQ_NONE;
}
status = dev->dec_ops[ctx->current_codec]->irq_status(ctx);
status = ctx->current_codec->irq_status(ctx);
if (status == CEDRUS_IRQ_NONE)
return IRQ_NONE;
dev->dec_ops[ctx->current_codec]->irq_disable(ctx);
dev->dec_ops[ctx->current_codec]->irq_clear(ctx);
ctx->current_codec->irq_disable(ctx);
ctx->current_codec->irq_clear(ctx);
if (status == CEDRUS_IRQ_ERROR)
state = VB2_BUF_STATE_ERROR;
......
......@@ -16,7 +16,7 @@
#ifndef _CEDRUS_HW_H_
#define _CEDRUS_HW_H_
int cedrus_engine_enable(struct cedrus_ctx *ctx, enum cedrus_codec codec);
int cedrus_engine_enable(struct cedrus_ctx *ctx);
void cedrus_engine_disable(struct cedrus_dev *dev);
void cedrus_dst_format_set(struct cedrus_dev *dev,
......
......@@ -66,7 +66,7 @@ static int cedrus_mpeg2_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
quantisation = run->mpeg2.quantisation;
/* Activate MPEG engine. */
cedrus_engine_enable(ctx, CEDRUS_CODEC_MPEG2);
cedrus_engine_enable(ctx);
/* Set intra quantisation matrix. */
matrix = quantisation->intra_quantiser_matrix;
......
......@@ -56,13 +56,13 @@ static struct cedrus_format cedrus_formats[] = {
.capabilities = CEDRUS_CAPABILITY_VP8_DEC,
},
{
.pixelformat = V4L2_PIX_FMT_NV12_32L32,
.pixelformat = V4L2_PIX_FMT_NV12,
.directions = CEDRUS_DECODE_DST,
.capabilities = CEDRUS_CAPABILITY_UNTILED,
},
{
.pixelformat = V4L2_PIX_FMT_NV12,
.pixelformat = V4L2_PIX_FMT_NV12_32L32,
.directions = CEDRUS_DECODE_DST,
.capabilities = CEDRUS_CAPABILITY_UNTILED,
},
};
......@@ -73,8 +73,8 @@ static inline struct cedrus_ctx *cedrus_file2ctx(struct file *file)
return container_of(file->private_data, struct cedrus_ctx, fh);
}
static struct cedrus_format *cedrus_find_format(u32 pixelformat, u32 directions,
unsigned int capabilities)
static struct cedrus_format *cedrus_find_format(struct cedrus_ctx *ctx,
u32 pixelformat, u32 directions)
{
struct cedrus_format *first_valid_fmt = NULL;
struct cedrus_format *fmt;
......@@ -83,7 +83,7 @@ static struct cedrus_format *cedrus_find_format(u32 pixelformat, u32 directions,
for (i = 0; i < CEDRUS_FORMATS_COUNT; i++) {
fmt = &cedrus_formats[i];
if ((fmt->capabilities & capabilities) != fmt->capabilities ||
if (!cedrus_is_capable(ctx, fmt->capabilities) ||
!(fmt->directions & directions))
continue;
......@@ -177,19 +177,13 @@ static int cedrus_enum_fmt(struct file *file, struct v4l2_fmtdesc *f,
u32 direction)
{
struct cedrus_ctx *ctx = cedrus_file2ctx(file);
struct cedrus_dev *dev = ctx->dev;
unsigned int capabilities = dev->capabilities;
struct cedrus_format *fmt;
unsigned int i, index;
/* Index among formats that match the requested direction. */
index = 0;
for (i = 0; i < CEDRUS_FORMATS_COUNT; i++) {
fmt = &cedrus_formats[i];
if (fmt->capabilities && (fmt->capabilities & capabilities) !=
fmt->capabilities)
if (!cedrus_is_capable(ctx, cedrus_formats[i].capabilities))
continue;
if (!(cedrus_formats[i].directions & direction))
......@@ -241,15 +235,12 @@ static int cedrus_g_fmt_vid_out(struct file *file, void *priv,
return 0;
}
static int cedrus_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
static int cedrus_try_fmt_vid_cap_p(struct cedrus_ctx *ctx,
struct v4l2_pix_format *pix_fmt)
{
struct cedrus_ctx *ctx = cedrus_file2ctx(file);
struct cedrus_dev *dev = ctx->dev;
struct v4l2_pix_format *pix_fmt = &f->fmt.pix;
struct cedrus_format *fmt =
cedrus_find_format(pix_fmt->pixelformat, CEDRUS_DECODE_DST,
dev->capabilities);
cedrus_find_format(ctx, pix_fmt->pixelformat,
CEDRUS_DECODE_DST);
if (!fmt)
return -EINVAL;
......@@ -262,15 +253,18 @@ static int cedrus_try_fmt_vid_cap(struct file *file, void *priv,
return 0;
}
static int cedrus_try_fmt_vid_out(struct file *file, void *priv,
static int cedrus_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct cedrus_ctx *ctx = cedrus_file2ctx(file);
struct cedrus_dev *dev = ctx->dev;
struct v4l2_pix_format *pix_fmt = &f->fmt.pix;
return cedrus_try_fmt_vid_cap_p(cedrus_file2ctx(file), &f->fmt.pix);
}
static int cedrus_try_fmt_vid_out_p(struct cedrus_ctx *ctx,
struct v4l2_pix_format *pix_fmt)
{
struct cedrus_format *fmt =
cedrus_find_format(pix_fmt->pixelformat, CEDRUS_DECODE_SRC,
dev->capabilities);
cedrus_find_format(ctx, pix_fmt->pixelformat,
CEDRUS_DECODE_SRC);
if (!fmt)
return -EINVAL;
......@@ -281,6 +275,12 @@ static int cedrus_try_fmt_vid_out(struct file *file, void *priv,
return 0;
}
static int cedrus_try_fmt_vid_out(struct file *file, void *priv,
struct v4l2_format *f)
{
return cedrus_try_fmt_vid_out_p(cedrus_file2ctx(file), &f->fmt.pix);
}
static int cedrus_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
......@@ -301,18 +301,76 @@ static int cedrus_s_fmt_vid_cap(struct file *file, void *priv,
return 0;
}
static int cedrus_s_fmt_vid_out(struct file *file, void *priv,
struct v4l2_format *f)
void cedrus_reset_cap_format(struct cedrus_ctx *ctx)
{
ctx->dst_fmt.pixelformat = 0;
cedrus_try_fmt_vid_cap_p(ctx, &ctx->dst_fmt);
}
static int cedrus_s_fmt_vid_out_p(struct cedrus_ctx *ctx,
struct v4l2_pix_format *pix_fmt)
{
struct cedrus_ctx *ctx = cedrus_file2ctx(file);
struct vb2_queue *vq;
struct vb2_queue *peer_vq;
int ret;
ret = cedrus_try_fmt_vid_out(file, priv, f);
ret = cedrus_try_fmt_vid_out_p(ctx, pix_fmt);
if (ret)
return ret;
ctx->src_fmt = *pix_fmt;
vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
switch (ctx->src_fmt.pixelformat) {
case V4L2_PIX_FMT_H264_SLICE:
case V4L2_PIX_FMT_HEVC_SLICE:
vq->subsystem_flags |=
VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF;
break;
default:
vq->subsystem_flags &=
~VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF;
break;
}
switch (ctx->src_fmt.pixelformat) {
case V4L2_PIX_FMT_MPEG2_SLICE:
ctx->current_codec = &cedrus_dec_ops_mpeg2;
break;
case V4L2_PIX_FMT_H264_SLICE:
ctx->current_codec = &cedrus_dec_ops_h264;
break;
case V4L2_PIX_FMT_HEVC_SLICE:
ctx->current_codec = &cedrus_dec_ops_h265;
break;
case V4L2_PIX_FMT_VP8_FRAME:
ctx->current_codec = &cedrus_dec_ops_vp8;
break;
}
/* Propagate format information to capture. */
ctx->dst_fmt.colorspace = pix_fmt->colorspace;
ctx->dst_fmt.xfer_func = pix_fmt->xfer_func;
ctx->dst_fmt.ycbcr_enc = pix_fmt->ycbcr_enc;
ctx->dst_fmt.quantization = pix_fmt->quantization;
cedrus_reset_cap_format(ctx);
return 0;
}
void cedrus_reset_out_format(struct cedrus_ctx *ctx)
{
ctx->src_fmt.pixelformat = 0;
cedrus_s_fmt_vid_out_p(ctx, &ctx->src_fmt);
}
static int cedrus_s_fmt_vid_out(struct file *file, void *priv,
struct v4l2_format *f)
{
struct cedrus_ctx *ctx = cedrus_file2ctx(file);
struct vb2_queue *vq;
struct vb2_queue *peer_vq;
vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
/*
* In order to support dynamic resolution change,
......@@ -332,34 +390,7 @@ static int cedrus_s_fmt_vid_out(struct file *file, void *priv,
if (vb2_is_busy(peer_vq))
return -EBUSY;
ret = cedrus_try_fmt_vid_out(file, priv, f);
if (ret)
return ret;
ctx->src_fmt = f->fmt.pix;
switch (ctx->src_fmt.pixelformat) {
case V4L2_PIX_FMT_H264_SLICE:
case V4L2_PIX_FMT_HEVC_SLICE:
vq->subsystem_flags |=
VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF;
break;
default:
vq->subsystem_flags &=
~VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF;
break;
}
/* Propagate format information to capture. */
ctx->dst_fmt.colorspace = f->fmt.pix.colorspace;
ctx->dst_fmt.xfer_func = f->fmt.pix.xfer_func;
ctx->dst_fmt.ycbcr_enc = f->fmt.pix.ycbcr_enc;
ctx->dst_fmt.quantization = f->fmt.pix.quantization;
ctx->dst_fmt.width = ctx->src_fmt.width;
ctx->dst_fmt.height = ctx->src_fmt.height;
cedrus_prepare_format(&ctx->dst_fmt);
return 0;
return cedrus_s_fmt_vid_out_p(cedrus_file2ctx(file), &f->fmt.pix);
}
const struct v4l2_ioctl_ops cedrus_ioctl_ops = {
......@@ -475,34 +506,13 @@ static int cedrus_start_streaming(struct vb2_queue *vq, unsigned int count)
struct cedrus_dev *dev = ctx->dev;
int ret = 0;
switch (ctx->src_fmt.pixelformat) {
case V4L2_PIX_FMT_MPEG2_SLICE:
ctx->current_codec = CEDRUS_CODEC_MPEG2;
break;
case V4L2_PIX_FMT_H264_SLICE:
ctx->current_codec = CEDRUS_CODEC_H264;
break;
case V4L2_PIX_FMT_HEVC_SLICE:
ctx->current_codec = CEDRUS_CODEC_H265;
break;
case V4L2_PIX_FMT_VP8_FRAME:
ctx->current_codec = CEDRUS_CODEC_VP8;
break;
default:
return -EINVAL;
}
if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
ret = pm_runtime_resume_and_get(dev->dev);
if (ret < 0)
goto err_cleanup;
if (dev->dec_ops[ctx->current_codec]->start) {
ret = dev->dec_ops[ctx->current_codec]->start(ctx);
if (ctx->current_codec->start) {
ret = ctx->current_codec->start(ctx);
if (ret)
goto err_pm;
}
......@@ -524,8 +534,8 @@ static void cedrus_stop_streaming(struct vb2_queue *vq)
struct cedrus_dev *dev = ctx->dev;
if (V4L2_TYPE_IS_OUTPUT(vq->type)) {
if (dev->dec_ops[ctx->current_codec]->stop)
dev->dec_ops[ctx->current_codec]->stop(ctx);
if (ctx->current_codec->stop)
ctx->current_codec->stop(ctx);
pm_runtime_put(dev->dev);
}
......
......@@ -27,5 +27,7 @@ extern const struct v4l2_ioctl_ops cedrus_ioctl_ops;
int cedrus_queue_init(void *priv, struct vb2_queue *src_vq,
struct vb2_queue *dst_vq);
void cedrus_prepare_format(struct v4l2_pix_format *pix_fmt);
void cedrus_reset_cap_format(struct cedrus_ctx *ctx);
void cedrus_reset_out_format(struct cedrus_ctx *ctx);
#endif
......@@ -662,7 +662,7 @@ static int cedrus_vp8_setup(struct cedrus_ctx *ctx, struct cedrus_run *run)
int header_size;
u32 reg;
cedrus_engine_enable(ctx, CEDRUS_CODEC_VP8);
cedrus_engine_enable(ctx);
cedrus_write(dev, VE_H264_CTRL, VE_H264_CTRL_VP8);
......
......@@ -433,7 +433,7 @@ static int tegra_csi_channel_alloc(struct tegra_csi *csi,
for (i = 0; i < chan->numgangports; i++)
chan->csi_port_nums[i] = port_num + i * CSI_PORTS_PER_BRICK;
chan->of_node = node;
chan->of_node = of_node_get(node);
chan->numpads = num_pads;
if (num_pads & 0x2) {
chan->pads[0].flags = MEDIA_PAD_FL_SINK;
......@@ -448,6 +448,7 @@ static int tegra_csi_channel_alloc(struct tegra_csi *csi,
chan->mipi = tegra_mipi_request(csi->dev, node);
if (IS_ERR(chan->mipi)) {
ret = PTR_ERR(chan->mipi);
chan->mipi = NULL;
dev_err(csi->dev, "failed to get mipi device: %d\n", ret);
}
......@@ -640,6 +641,7 @@ static void tegra_csi_channels_cleanup(struct tegra_csi *csi)
media_entity_cleanup(&subdev->entity);
}
of_node_put(chan->of_node);
list_del(&chan->list);
kfree(chan);
}
......
......@@ -56,7 +56,7 @@ struct tegra_csi;
* @framerate: active framerate for TPG
* @h_blank: horizontal blanking for TPG active format
* @v_blank: vertical blanking for TPG active format
* @mipi: mipi device for corresponding csi channel pads
* @mipi: mipi device for corresponding csi channel pads, or NULL if not applicable (TPG, error)
* @pixel_rate: active pixel rate from the sensor on this channel
*/
struct tegra_csi_channel {
......
......@@ -28,7 +28,7 @@ struct vpbe_output {
*/
char *subdev_name;
/*
* defualt_mode identifies the default timings set at the venc or
* default_mode identifies the default timings set at the venc or
* external encoder.
*/
char *default_mode;
......
/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
/*
* Copyright (C) 2021 ASPEED Technology Inc.
*/
#ifndef _UAPI_LINUX_ASPEED_VIDEO_H
#define _UAPI_LINUX_ASPEED_VIDEO_H
#include <linux/v4l2-controls.h>
#define V4L2_CID_ASPEED_HQ_MODE (V4L2_CID_USER_ASPEED_BASE + 1)
#define V4L2_CID_ASPEED_HQ_JPEG_QUALITY (V4L2_CID_USER_ASPEED_BASE + 2)
#endif /* _UAPI_LINUX_ASPEED_VIDEO_H */
......@@ -231,6 +231,12 @@ enum v4l2_colorfx {
*/
#define V4L2_CID_USER_DW100_BASE (V4L2_CID_USER_BASE + 0x1190)
/*
* The base for Aspeed driver controls.
* We reserve 16 controls for this driver.
*/
#define V4L2_CID_USER_ASPEED_BASE (V4L2_CID_USER_BASE + 0x11a0)
/* MPEG-class control IDs */
/* The MPEG controls are applicable to all codec controls
* and the 'MPEG' part of the define is historical */
......
......@@ -775,6 +775,7 @@ struct v4l2_pix_format {
#define V4L2_PIX_FMT_HI240 v4l2_fourcc('H', 'I', '2', '4') /* BTTV 8-bit dithered RGB */
#define V4L2_PIX_FMT_QC08C v4l2_fourcc('Q', '0', '8', 'C') /* Qualcomm 8-bit compressed */
#define V4L2_PIX_FMT_QC10C v4l2_fourcc('Q', '1', '0', 'C') /* Qualcomm 10-bit compressed */
#define V4L2_PIX_FMT_AJPG v4l2_fourcc('A', 'J', 'P', 'G') /* Aspeed JPEG */
/* 10bit raw packed, 32 bytes for every 25 pixels, last LSB 6 bits unused */
#define V4L2_PIX_FMT_IPU3_SBGGR10 v4l2_fourcc('i', 'p', '3', 'b') /* IPU3 packed 10-bit BGGR bayer */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment