diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-04-28 09:24:36 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-04-28 09:24:36 -0700 |
commit | 3aa139aa9fdc138a84243dc49dc18d9b40e1c6e4 (patch) | |
tree | 5f533d8f1c48f0e8bc02b4f8079ed9ffdc14ebc1 /drivers/staging | |
parent | acd3d28594536e9096c1ea76c5867d8a68babef6 (diff) | |
parent | 0b276e470a4d43e1365d3eb53c608a3d208cabd4 (diff) | |
download | linux-3aa139aa9fdc138a84243dc49dc18d9b40e1c6e4.tar.gz |
Merge tag 'media/v5.13-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab:
- addition of a maintainer's profile for the media subsystem
- addition of i.MX8 IP support
- qcom/camss gained support for hardware version Titan 170
- new RC keymaps
- Lots of other improvements, cleanups and bug fixes
* tag 'media/v5.13-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (488 commits)
media: coda: fix macroblocks count control usage
media: rkisp1: params: fix wrong bits settings
media: cedrus: Fix H265 status definitions
media: meson-ge2d: fix rotation parameters
media: v4l2-ctrls: fix reference to freed memory
media: venus : hfi: add venus image info into smem
media: venus: Fix internal buffer size calculations for v6.
media: venus: helpers: keep max bandwidth when mbps exceeds the supported range
media: venus: fix hw overload error log condition
media: venus: core: correct firmware name for sm8250
media: venus: core,pm: fix potential infinite loop
media: venus: core: Fix kerneldoc warnings
media: gscpa/stv06xx: fix memory leak
media: cx25821: remove unused including <linux/version.h>
media: staging: media/meson: remove redundant dev_err call
media: adv7842: support 1 block EDIDs, fix clearing EDID
media: adv7842: configure all pads
media: allegro: change kernel-doc comment blocks to normal comments
media: camss: ispif: Remove redundant dev_err call in msm_ispif_subdev_init()
media: i2c: rdamc21: Fix warning on u8 cast
...
Diffstat (limited to 'drivers/staging')
67 files changed, 1608 insertions, 1555 deletions
diff --git a/drivers/staging/media/atomisp/Kconfig b/drivers/staging/media/atomisp/Kconfig index 37577bb72998..aeed5803dfb1 100644 --- a/drivers/staging/media/atomisp/Kconfig +++ b/drivers/staging/media/atomisp/Kconfig @@ -2,9 +2,9 @@ menuconfig INTEL_ATOMISP bool "Enable support to Intel Atom ISP camera drivers" depends on X86 && EFI && PCI && ACPI + depends on COMMON_CLK select IOSF_MBI select MEDIA_CONTROLLER - select COMMON_CLK help Enable support for the Intel ISP2 camera interfaces and MIPI sensor drivers. @@ -15,6 +15,7 @@ config VIDEO_ATOMISP depends on PMIC_OPREGION select IOSF_MBI select VIDEOBUF_VMALLOC + select VIDEO_V4L2_SUBDEV_API help Say Y here if your platform supports Intel Atom SoC camera imaging subsystem. diff --git a/drivers/staging/media/atomisp/Makefile b/drivers/staging/media/atomisp/Makefile index 1dfad0dd02d0..51498b2e85b8 100644 --- a/drivers/staging/media/atomisp/Makefile +++ b/drivers/staging/media/atomisp/Makefile @@ -126,7 +126,6 @@ atomisp-objs += \ pci/runtime/inputfifo/src/inputfifo.o \ pci/runtime/isp_param/src/isp_param.o \ pci/runtime/isys/src/csi_rx_rmgr.o \ - pci/runtime/isys/src/ibuf_ctrl_rmgr.o \ pci/runtime/isys/src/isys_dma_rmgr.o \ pci/runtime/isys/src/isys_init.o \ pci/runtime/isys/src/isys_stream2mmio_rmgr.o \ @@ -323,7 +322,9 @@ DEFINES := -DHRT_HW -DHRT_ISP_CSS_CUSTOM_HOST -DHRT_USE_VIR_ADDRS -D__HOST__ #DEFINES += -DUSE_KMEM_CACHE ifeq ($(CONFIG_VIDEO_ATOMISP_ISP2401),y) -atomisp-objs += $(obj-cht) +atomisp-objs += \ + $(obj-cht) \ + pci/runtime/isys/src/ibuf_ctrl_rmgr.o DEFINES += -DISP2401 -DISP2401_NEW_INPUT_SYSTEM -DSYSTEM_hive_isp_css_2401_system else atomisp-objs += $(obj-byt) diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c index 2b71de722ec3..d170d0adfea4 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-gc0310.c @@ -192,8 +192,8 @@ static int __gc0310_buf_reg_array(struct i2c_client *client, } static int __gc0310_write_reg_is_consecutive(struct i2c_client *client, - struct gc0310_write_ctrl *ctrl, - const struct gc0310_reg *next) + struct gc0310_write_ctrl *ctrl, + const struct gc0310_reg *next) { if (ctrl->index == 0) return 1; @@ -874,12 +874,12 @@ static int gc0310_s_power(struct v4l2_subdev *sd, int on) if (on == 0) return power_down(sd); - else { - ret = power_up(sd); - if (!ret) - return gc0310_init(sd); - } - return ret; + + ret = power_up(sd); + if (ret) + return ret; + + return gc0310_init(sd); } /* diff --git a/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c b/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c index 7ca7378b1859..362ed44b4eff 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-lm3554.c @@ -771,7 +771,6 @@ static int lm3554_gpio_init(struct i2c_client *client) ret = gpiod_direction_output(pdata->gpio_reset, 0); if (ret < 0) return ret; - dev_info(&client->dev, "flash led reset successfully\n"); if (!pdata->gpio_strobe) return -EINVAL; @@ -783,7 +782,7 @@ static int lm3554_gpio_init(struct i2c_client *client) return 0; } -static int lm3554_gpio_uninit(struct i2c_client *client) +static void lm3554_gpio_uninit(struct i2c_client *client) { struct v4l2_subdev *sd = i2c_get_clientdata(client); struct lm3554 *flash = to_lm3554(sd); @@ -792,13 +791,13 @@ static int lm3554_gpio_uninit(struct i2c_client *client) ret = gpiod_direction_output(pdata->gpio_strobe, 0); if (ret < 0) - return ret; + dev_err(&client->dev, + "gpio request/direction_output fail for gpio_strobe"); ret = gpiod_direction_output(pdata->gpio_reset, 0); if (ret < 0) - return ret; - - return 0; + dev_err(&client->dev, + "gpio request/direction_output fail for gpio_reset"); } static void *lm3554_platform_data_func(struct i2c_client *client) @@ -843,8 +842,10 @@ static int lm3554_probe(struct i2c_client *client) return -ENOMEM; flash->pdata = lm3554_platform_data_func(client); - if (IS_ERR(flash->pdata)) - return PTR_ERR(flash->pdata); + if (IS_ERR(flash->pdata)) { + err = PTR_ERR(flash->pdata); + goto fail1; + } v4l2_i2c_subdev_init(&flash->sd, client, &lm3554_ops); flash->sd.internal_ops = &lm3554_internal_ops; @@ -856,7 +857,7 @@ static int lm3554_probe(struct i2c_client *client) ARRAY_SIZE(lm3554_controls)); if (ret) { dev_err(&client->dev, "error initialize a ctrl_handler.\n"); - goto fail2; + goto fail3; } for (i = 0; i < ARRAY_SIZE(lm3554_controls); i++) @@ -865,14 +866,14 @@ static int lm3554_probe(struct i2c_client *client) if (flash->ctrl_handler.error) { dev_err(&client->dev, "ctrl_handler error.\n"); - goto fail2; + goto fail3; } flash->sd.ctrl_handler = &flash->ctrl_handler; err = media_entity_pads_init(&flash->sd.entity, 0, NULL); if (err) { dev_err(&client->dev, "error initialize a media entity.\n"); - goto fail1; + goto fail2; } flash->sd.entity.function = MEDIA_ENT_F_FLASH; @@ -884,14 +885,15 @@ static int lm3554_probe(struct i2c_client *client) err = lm3554_gpio_init(client); if (err) { dev_err(&client->dev, "gpio request/direction_output fail"); - goto fail2; + goto fail3; } return atomisp_register_i2c_module(&flash->sd, NULL, LED_FLASH); -fail2: +fail3: media_entity_cleanup(&flash->sd.entity); v4l2_ctrl_handler_free(&flash->ctrl_handler); -fail1: +fail2: v4l2_device_unregister_subdev(&flash->sd); +fail1: kfree(flash); return err; @@ -901,7 +903,6 @@ static int lm3554_remove(struct i2c_client *client) { struct v4l2_subdev *sd = i2c_get_clientdata(client); struct lm3554 *flash = to_lm3554(sd); - int ret; media_entity_cleanup(&flash->sd.entity); v4l2_ctrl_handler_free(&flash->ctrl_handler); @@ -911,16 +912,11 @@ static int lm3554_remove(struct i2c_client *client) del_timer_sync(&flash->flash_off_delay); - ret = lm3554_gpio_uninit(client); - if (ret < 0) - goto fail; + lm3554_gpio_uninit(client); kfree(flash); return 0; -fail: - dev_err(&client->dev, "gpio request/direction_output fail"); - return ret; } static const struct dev_pm_ops lm3554_pm_ops = { diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c index eecefcd734d0..1209492c1826 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c @@ -1175,8 +1175,6 @@ static int ov2722_remove(struct i2c_client *client) struct v4l2_subdev *sd = i2c_get_clientdata(client); struct ov2722_device *dev = to_ov2722_sensor(sd); - dev_dbg(&client->dev, "ov2722_remove...\n"); - dev->platform_data->csi_cfg(sd, 0); v4l2_ctrl_handler_free(&dev->ctrl_handler); v4l2_device_unregister_subdev(sd); diff --git a/drivers/staging/media/atomisp/i2c/gc2235.h b/drivers/staging/media/atomisp/i2c/gc2235.h index 68252b8f516d..ba5db1230033 100644 --- a/drivers/staging/media/atomisp/i2c/gc2235.h +++ b/drivers/staging/media/atomisp/i2c/gc2235.h @@ -218,7 +218,7 @@ static struct gc2235_reg const gc2235_stream_off[] = { }; static struct gc2235_reg const gc2235_init_settings[] = { - /* Sysytem */ + /* System */ { GC2235_8BIT, 0xfe, 0x80 }, { GC2235_8BIT, 0xfe, 0x80 }, { GC2235_8BIT, 0xfe, 0x80 }, diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c index 592ea990d4ca..14abc1ca00e8 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c +++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c @@ -4265,8 +4265,7 @@ int atomisp_set_parameters(struct video_device *vdev, apply_parameter_failed: if (css_param) atomisp_free_css_parameters(css_param); - if (param) - kvfree(param); + kvfree(param); return ret; } @@ -4626,8 +4625,7 @@ atomisp_v4l2_framebuffer_to_css_frame(const struct v4l2_framebuffer *arg, err: if (ret && res) ia_css_frame_free(res); - if (tmp_buf) - vfree(tmp_buf); + vfree(tmp_buf); if (ret == 0) *result = res; return ret; @@ -4837,7 +4835,7 @@ static void __atomisp_init_stream_info(u16 stream_index, } /* This function looks up the closest available resolution. */ -int atomisp_try_fmt(struct video_device *vdev, struct v4l2_format *f, +int atomisp_try_fmt(struct video_device *vdev, struct v4l2_pix_format *f, bool *res_overflow) { struct atomisp_device *isp = video_get_drvdata(vdev); @@ -4859,18 +4857,18 @@ int atomisp_try_fmt(struct video_device *vdev, struct v4l2_format *f, return -EINVAL; stream_index = atomisp_source_pad_to_stream_id(asd, source_pad); - fmt = atomisp_get_format_bridge(f->fmt.pix.pixelformat); + fmt = atomisp_get_format_bridge(f->pixelformat); if (!fmt) { dev_err(isp->dev, "unsupported pixelformat!\n"); fmt = atomisp_output_fmts; } - if (f->fmt.pix.width <= 0 || f->fmt.pix.height <= 0) + if (f->width <= 0 || f->height <= 0) return -EINVAL; snr_mbus_fmt->code = fmt->mbus_code; - snr_mbus_fmt->width = f->fmt.pix.width; - snr_mbus_fmt->height = f->fmt.pix.height; + snr_mbus_fmt->width = f->width; + snr_mbus_fmt->height = f->height; __atomisp_init_stream_info(stream_index, stream_info); @@ -4892,7 +4890,7 @@ int atomisp_try_fmt(struct video_device *vdev, struct v4l2_format *f, return -EINVAL; } - f->fmt.pix.pixelformat = fmt->pixelformat; + f->pixelformat = fmt->pixelformat; /* * If the format is jpeg or custom RAW, then the width and height will @@ -4900,17 +4898,17 @@ int atomisp_try_fmt(struct video_device *vdev, struct v4l2_format *f, * the below conditions. So just assign to what is being returned from * the sensor driver. */ - if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_JPEG || - f->fmt.pix.pixelformat == V4L2_PIX_FMT_CUSTOM_M10MO_RAW) { - f->fmt.pix.width = snr_mbus_fmt->width; - f->fmt.pix.height = snr_mbus_fmt->height; + if (f->pixelformat == V4L2_PIX_FMT_JPEG || + f->pixelformat == V4L2_PIX_FMT_CUSTOM_M10MO_RAW) { + f->width = snr_mbus_fmt->width; + f->height = snr_mbus_fmt->height; return 0; } - if (snr_mbus_fmt->width < f->fmt.pix.width - && snr_mbus_fmt->height < f->fmt.pix.height) { - f->fmt.pix.width = snr_mbus_fmt->width; - f->fmt.pix.height = snr_mbus_fmt->height; + if (snr_mbus_fmt->width < f->width + && snr_mbus_fmt->height < f->height) { + f->width = snr_mbus_fmt->width; + f->height = snr_mbus_fmt->height; /* Set the flag when resolution requested is * beyond the max value supported by sensor */ @@ -4919,12 +4917,10 @@ int atomisp_try_fmt(struct video_device *vdev, struct v4l2_format *f, } /* app vs isp */ - f->fmt.pix.width = rounddown( - clamp_t(u32, f->fmt.pix.width, ATOM_ISP_MIN_WIDTH, - ATOM_ISP_MAX_WIDTH), ATOM_ISP_STEP_WIDTH); - f->fmt.pix.height = rounddown( - clamp_t(u32, f->fmt.pix.height, ATOM_ISP_MIN_HEIGHT, - ATOM_ISP_MAX_HEIGHT), ATOM_ISP_STEP_HEIGHT); + f->width = rounddown(clamp_t(u32, f->width, ATOM_ISP_MIN_WIDTH, + ATOM_ISP_MAX_WIDTH), ATOM_ISP_STEP_WIDTH); + f->height = rounddown(clamp_t(u32, f->height, ATOM_ISP_MIN_HEIGHT, + ATOM_ISP_MAX_HEIGHT), ATOM_ISP_STEP_HEIGHT); return 0; } @@ -5083,11 +5079,8 @@ static int __enable_continuous_mode(struct atomisp_sub_device *asd, atomisp_css_enable_continuous(asd, enable); atomisp_css_enable_cvf(asd, asd->continuous_viewfinder->val); - if (atomisp_css_continuous_set_num_raw_frames(asd, - asd->continuous_raw_buffer_size->val)) { - dev_err(isp->dev, "css_continuous_set_num_raw_frames failed\n"); - return -EINVAL; - } + atomisp_css_continuous_set_num_raw_frames(asd, + asd->continuous_raw_buffer_size->val); if (!enable) { atomisp_css_enable_raw_binning(asd, false); @@ -5407,27 +5400,12 @@ static int atomisp_set_fmt_to_isp(struct video_device *vdev, return -EINVAL; } - if (asd->continuous_mode->val && - (configure_pp_input == atomisp_css_preview_configure_pp_input || - configure_pp_input == atomisp_css_video_configure_pp_input)) { - /* for isp 2.2, configure pp input is available for continuous - * mode */ - ret = configure_pp_input(asd, isp_sink_crop->width, - isp_sink_crop->height); - if (ret) { - dev_err(isp->dev, "configure_pp_input %ux%u\n", - isp_sink_crop->width, - isp_sink_crop->height); - return -EINVAL; - } - } else { - ret = configure_pp_input(asd, isp_sink_crop->width, - isp_sink_crop->height); - if (ret) { - dev_err(isp->dev, "configure_pp_input %ux%u\n", - isp_sink_crop->width, isp_sink_crop->height); - return -EINVAL; - } + ret = configure_pp_input(asd, isp_sink_crop->width, isp_sink_crop->height); + if (ret) { + dev_err(isp->dev, "configure_pp_input %ux%u\n", + isp_sink_crop->width, + isp_sink_crop->height); + return -EINVAL; } if (asd->copy_mode) ret = atomisp_css_copy_get_output_frame_info(asd, stream_index, @@ -5481,7 +5459,7 @@ static void atomisp_get_dis_envelop(struct atomisp_sub_device *asd, } static void atomisp_check_copy_mode(struct atomisp_sub_device *asd, - int source_pad, struct v4l2_format *f) + int source_pad, struct v4l2_pix_format *f) { #if defined(ISP2401_NEW_INPUT_SYSTEM) struct v4l2_mbus_framefmt *sink, *src; @@ -5492,8 +5470,8 @@ static void atomisp_check_copy_mode(struct atomisp_sub_device *asd, V4L2_SUBDEV_FORMAT_ACTIVE, source_pad); if ((sink->code == src->code && - sink->width == f->fmt.pix.width && - sink->height == f->fmt.pix.height) || + sink->width == f->width && + sink->height == f->height) || ((asd->isp->inputs[asd->input_curr].type == SOC_CAMERA) && (asd->isp->inputs[asd->input_curr].camera_caps-> sensor[asd->sensor_curr].stream_num > 1))) @@ -5507,7 +5485,7 @@ static void atomisp_check_copy_mode(struct atomisp_sub_device *asd, } static int atomisp_set_fmt_to_snr(struct video_device *vdev, - struct v4l2_format *f, unsigned int pixelformat, + struct v4l2_pix_format *f, unsigned int pixelformat, unsigned int padding_w, unsigned int padding_h, unsigned int dvs_env_w, unsigned int dvs_env_h) { @@ -5535,7 +5513,7 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev, if (!format) return -EINVAL; - v4l2_fill_mbus_format(ffmt, &f->fmt.pix, format->mbus_code); + v4l2_fill_mbus_format(ffmt, f, format->mbus_code); ffmt->height += padding_h + dvs_env_h; ffmt->width += padding_w + dvs_env_w; @@ -5605,8 +5583,8 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f) const struct atomisp_format_bridge *format_bridge; const struct atomisp_format_bridge *snr_format_bridge; struct ia_css_frame_info output_info, raw_output_info; - struct v4l2_format snr_fmt = *f; - struct v4l2_format backup_fmt = *f, s_fmt = *f; + struct v4l2_pix_format snr_fmt = f->fmt.pix; + struct v4l2_pix_format backup_fmt = snr_fmt, s_fmt; unsigned int dvs_env_w = 0, dvs_env_h = 0; unsigned int padding_w = pad_w, padding_h = pad_h; bool res_overflow = false, crop_needs_override = false; @@ -5780,11 +5758,10 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f) dev_warn(isp->dev, "Try format failed with error %d\n", ret); return ret; } - f->fmt.pix.width = snr_fmt.fmt.pix.width; - f->fmt.pix.height = snr_fmt.fmt.pix.height; + f->fmt.pix.width = snr_fmt.width; + f->fmt.pix.height = snr_fmt.height; - snr_format_bridge = - atomisp_get_format_bridge(snr_fmt.fmt.pix.pixelformat); + snr_format_bridge = atomisp_get_format_bridge(snr_fmt.pixelformat); if (!snr_format_bridge) { dev_warn(isp->dev, "Can't find bridge format\n"); return -EINVAL; @@ -5865,11 +5842,11 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f) * and height while set_mbus_fmt() so actual resolutions are * being used in while set media bus format. */ - s_fmt = *f; + s_fmt = f->fmt.pix; if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_JPEG || f->fmt.pix.pixelformat == V4L2_PIX_FMT_CUSTOM_M10MO_RAW) { - s_fmt.fmt.pix.width = backup_fmt.fmt.pix.width; - s_fmt.fmt.pix.height = backup_fmt.fmt.pix.height; + s_fmt.width = backup_fmt.width; + s_fmt.height = backup_fmt.height; } ret = atomisp_set_fmt_to_snr(vdev, &s_fmt, f->fmt.pix.pixelformat, padding_w, diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.h b/drivers/staging/media/atomisp/pci/atomisp_cmd.h index 1c0d464c2ac1..412baeb91944 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_cmd.h +++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.h @@ -333,7 +333,7 @@ int atomisp_get_sensor_mode_data(struct atomisp_sub_device *asd, int atomisp_get_fmt(struct video_device *vdev, struct v4l2_format *f); /* This function looks up the closest available resolution. */ -int atomisp_try_fmt(struct video_device *vdev, struct v4l2_format *f, +int atomisp_try_fmt(struct video_device *vdev, struct v4l2_pix_format *f, bool *res_overflow); int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f); diff --git a/drivers/staging/media/atomisp/pci/atomisp_compat.h b/drivers/staging/media/atomisp/pci/atomisp_compat.h index 6a2a81a3eb23..a60551450c45 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_compat.h +++ b/drivers/staging/media/atomisp/pci/atomisp_compat.h @@ -247,12 +247,12 @@ int atomisp_css_input_configure_port(struct atomisp_sub_device *asd, void atomisp_create_pipes_stream(struct atomisp_sub_device *asd); void atomisp_destroy_pipes_stream_force(struct atomisp_sub_device *asd); -int atomisp_css_stop(struct atomisp_sub_device *asd, - enum ia_css_pipe_id pipe_id, bool in_reset); +void atomisp_css_stop(struct atomisp_sub_device *asd, + enum ia_css_pipe_id pipe_id, bool in_reset); -int atomisp_css_continuous_set_num_raw_frames( - struct atomisp_sub_device *asd, - int num_frames); +void atomisp_css_continuous_set_num_raw_frames( + struct atomisp_sub_device *asd, + int num_frames); int atomisp_css_copy_configure_output(struct atomisp_sub_device *asd, unsigned int stream_index, diff --git a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c index faa0935e536a..ce3165291eec 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c +++ b/drivers/staging/media/atomisp/pci/atomisp_compat_css20.c @@ -1142,7 +1142,7 @@ int atomisp_css_start(struct atomisp_sub_device *asd, * Thus the stream created in set_fmt get destroyed and need to be * recreated in the next stream on. */ - if (asd->stream_prepared == false) { + if (!asd->stream_prepared) { if (__create_pipes(asd)) { dev_err(isp->dev, "create pipe error.\n"); return -EINVAL; @@ -2098,8 +2098,8 @@ int atomisp_css_input_configure_port( return 0; } -int atomisp_css_stop(struct atomisp_sub_device *asd, - enum ia_css_pipe_id pipe_id, bool in_reset) +void atomisp_css_stop(struct atomisp_sub_device *asd, + enum ia_css_pipe_id pipe_id, bool in_reset) { struct atomisp_device *isp = asd->isp; struct atomisp_s3a_buf *s3a_buf; @@ -2188,12 +2188,11 @@ int atomisp_css_stop(struct atomisp_sub_device *asd, atomisp_flush_params_queue(&asd->video_out_video_capture); atomisp_free_css_parameters(&asd->params.css_param); memset(&asd->params.css_param, 0, sizeof(asd->params.css_param)); - return 0; } -int atomisp_css_continuous_set_num_raw_frames( - struct atomisp_sub_device *asd, - int num_frames) +void atomisp_css_continuous_set_num_raw_frames( + struct atomisp_sub_device *asd, + int num_frames) { if (asd->enable_raw_buffer_lock->val) { asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL] @@ -2217,7 +2216,6 @@ int atomisp_css_continuous_set_num_raw_frames( asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL] .stream_config.target_num_cont_raw_buf = num_frames; - return 0; } static enum ia_css_pipe_mode __pipe_id_to_pipe_mode( diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c index 453bb6913550..f1e6b2597853 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_fops.c +++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c @@ -221,6 +221,9 @@ int atomisp_q_video_buffers_to_css(struct atomisp_sub_device *asd, unsigned long irqflags; int err = 0; + if (WARN_ON(css_pipe_id >= IA_CSS_PIPE_ID_NUM)) + return -EINVAL; + while (pipe->buffers_in_css < ATOMISP_CSS_Q_DEPTH) { struct videobuf_buffer *vb; diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c index 2ae50decfc8b..6f5fe5092154 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c +++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c @@ -843,7 +843,7 @@ static int atomisp_try_fmt_cap(struct file *file, void *fh, int ret; rt_mutex_lock(&isp->mutex); - ret = atomisp_try_fmt(vdev, f, NULL); + ret = atomisp_try_fmt(vdev, &f->fmt.pix, NULL); rt_mutex_unlock(&isp->mutex); return ret; } @@ -948,10 +948,8 @@ int atomisp_alloc_css_stat_bufs(struct atomisp_sub_device *asd, dev_dbg(isp->dev, "allocating %d dis buffers\n", count); while (count--) { dis_buf = kzalloc(sizeof(struct atomisp_dis_buf), GFP_KERNEL); - if (!dis_buf) { - kfree(s3a_buf); + if (!dis_buf) goto error; - } if (atomisp_css_allocate_stat_buffers( asd, stream_id, NULL, dis_buf, NULL)) { kfree(dis_buf); @@ -2013,7 +2011,7 @@ int __atomisp_streamoff(struct file *file, void *fh, enum v4l2_buf_type type) } if (first_streamoff) { css_pipe_id = atomisp_get_css_pipe_id(asd); - ret = atomisp_css_stop(asd, css_pipe_id, false); + atomisp_css_stop(asd, css_pipe_id, false); } /* cancel work queue*/ if (asd->video_out_capture.users) { diff --git a/drivers/staging/media/atomisp/pci/hmm/hmm_bo.c b/drivers/staging/media/atomisp/pci/hmm/hmm_bo.c index f13af2329f48..0168f9839c90 100644 --- a/drivers/staging/media/atomisp/pci/hmm/hmm_bo.c +++ b/drivers/staging/media/atomisp/pci/hmm/hmm_bo.c @@ -857,16 +857,17 @@ static void free_private_pages(struct hmm_buffer_object *bo, kfree(bo->page_obj); } -static void free_user_pages(struct hmm_buffer_object *bo) +static void free_user_pages(struct hmm_buffer_object *bo, + unsigned int page_nr) { int i; hmm_mem_stat.usr_size -= bo->pgnr; if (bo->mem_type == HMM_BO_MEM_TYPE_PFN) { - unpin_user_pages(bo->pages, bo->pgnr); + unpin_user_pages(bo->pages, page_nr); } else { - for (i = 0; i < bo->pgnr; i++) + for (i = 0; i < page_nr; i++) put_page(bo->pages[i]); } kfree(bo->pages); @@ -942,6 +943,8 @@ static int alloc_user_pages(struct hmm_buffer_object *bo, dev_err(atomisp_dev, "get_user_pages err: bo->pgnr = %d, pgnr actually pinned = %d.\n", bo->pgnr, page_nr); + if (page_nr < 0) + page_nr = 0; goto out_of_mem; } @@ -954,7 +957,7 @@ static int alloc_user_pages(struct hmm_buffer_object *bo, out_of_mem: - free_user_pages(bo); + free_user_pages(bo, page_nr); return -ENOMEM; } @@ -1037,7 +1040,7 @@ void hmm_bo_free_pages(struct hmm_buffer_object *bo) if (bo->type == HMM_BO_PRIVATE) free_private_pages(bo, &dynamic_pool, &reserved_pool); else if (bo->type == HMM_BO_USER) - free_user_pages(bo); + free_user_pages(bo, bo->pgnr); else dev_err(atomisp_dev, "invalid buffer type.\n"); mutex_unlock(&bo->mutex); diff --git a/drivers/staging/media/atomisp/pci/ia_css_firmware.h b/drivers/staging/media/atomisp/pci/ia_css_firmware.h index e5e2f6fb37e0..01d2faf557cf 100644 --- a/drivers/staging/media/atomisp/pci/ia_css_firmware.h +++ b/drivers/staging/media/atomisp/pci/ia_css_firmware.h @@ -31,6 +31,8 @@ struct ia_css_fw { unsigned int bytes; /** length in bytes of firmware data */ }; +struct device; + /* @brief Loads the firmware * @param[in] env Environment, provides functions to access the * environment in which the CSS code runs. This is diff --git a/drivers/staging/media/atomisp/pci/ia_css_mipi.h b/drivers/staging/media/atomisp/pci/ia_css_mipi.h index 7b6d796d6ee0..9e50e1c619be 100644 --- a/drivers/staging/media/atomisp/pci/ia_css_mipi.h +++ b/drivers/staging/media/atomisp/pci/ia_css_mipi.h @@ -25,23 +25,6 @@ #include "ia_css_stream_format.h" #include "ia_css_input_port.h" -/* Backward compatible for CSS API 2.0 only - * TO BE REMOVED when all drivers move to CSS API 2.1. - */ -/* @brief Specify a CSS MIPI frame buffer. - * - * @param[in] size_mem_words The frame size in memory words (32B). - * @param[in] contiguous Allocate memory physically contiguously or not. - * @return The error code. - * - * \deprecated{Use ia_css_mipi_buffer_config instead.} - * - * Specifies a CSS MIPI frame buffer: size in memory words (32B). - */ -int -ia_css_mipi_frame_specify(const unsigned int size_mem_words, - const bool contiguous); - /* @brief Register size of a CSS MIPI frame for check during capturing. * * @param[in] port CSI-2 port this check is registered. diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_1.0/ia_css_sdis.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_1.0/ia_css_sdis.host.c index 3e72dabe7ef6..13caa55fd51a 100644 --- a/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_1.0/ia_css_sdis.host.c +++ b/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_1.0/ia_css_sdis.host.c @@ -386,8 +386,7 @@ ia_css_isp_dvs_statistics_map_allocate( return me; err: - if (me) - kvfree(me); + kvfree(me); return NULL; } diff --git a/drivers/staging/media/atomisp/pci/isp/modes/interface/isp_types.h b/drivers/staging/media/atomisp/pci/isp/modes/interface/isp_types.h index ae273c826808..d1c42c77fa50 100644 --- a/drivers/staging/media/atomisp/pci/isp/modes/interface/isp_types.h +++ b/drivers/staging/media/atomisp/pci/isp/modes/interface/isp_types.h @@ -1,26 +1,29 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/** -Support for Intel Camera Imaging ISP subsystem. -Copyright (c) 2010 - 2015, Intel Corporation. - -This program is free software; you can redistribute it and/or modify it -under the terms and conditions of the GNU General Public License, -version 2, as published by the Free Software Foundation. - -This program is distributed in the hope it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -more details. -*/ +/* + * Support for Intel Camera Imaging ISP subsystem. + * Copyright (c) 2010 - 2015, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ #ifndef _ISP_TYPES_H_ #define _ISP_TYPES_H_ -/* Workaround: hivecc complains about "tag "sh_css_3a_output" already declared" - without this extra decl. */ +/* + * Workaround: hivecc complains about "tag "sh_css_3a_output" already declared" + * without this extra decl. + */ struct ia_css_3a_output; -/* Input stream formats, these correspond to the MIPI formats and the way +/* + * Input stream formats, these correspond to the MIPI formats and the way * the CSS receiver sends these to the input formatter. * The bit depth of each pixel element is stored in the global variable * isp_bits_per_pixel. @@ -37,8 +40,10 @@ enum sh_stream_format { }; struct s_isp_frames { - /* global variables that are written to by either the SP or the host, - every ISP binary needs these. */ + /* + * Global variables that are written to by either the SP or the host, + * every ISP binary needs these. + */ /* output frame */ char *xmem_base_addr_y; char *xmem_base_addr_uv; diff --git a/drivers/staging/media/atomisp/pci/runtime/isp_param/src/isp_param.c b/drivers/staging/media/atomisp/pci/runtime/isp_param/src/isp_param.c index e861777385a0..823ec54b6281 100644 --- a/drivers/staging/media/atomisp/pci/runtime/isp_param/src/isp_param.c +++ b/drivers/staging/media/atomisp/pci/runtime/isp_param/src/isp_param.c @@ -155,8 +155,7 @@ ia_css_isp_param_destroy_isp_parameters( for (mem = 0; mem < IA_CSS_NUM_MEMORIES; mem++) { for (pclass = 0; pclass < IA_CSS_NUM_PARAM_CLASSES; pclass++) { - if (mem_params->params[pclass][mem].address) - kvfree(mem_params->params[pclass][mem].address); + kvfree(mem_params->params[pclass][mem].address); if (css_params->params[pclass][mem].address) hmm_free(css_params->params[pclass][mem].address); mem_params->params[pclass][mem].address = NULL; diff --git a/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c b/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c index 317ea30ede7a..82f3c19dc455 100644 --- a/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c +++ b/drivers/staging/media/atomisp/pci/runtime/isys/src/virtual_isys.c @@ -179,12 +179,12 @@ ia_css_isys_error_t ia_css_isys_stream_create( isys_stream->linked_isys_stream_id = isys_stream_descr->linked_isys_stream_id; rc = create_input_system_input_port(isys_stream_descr, &isys_stream->input_port); - if (rc == false) + if (!rc) return false; rc = create_input_system_channel(isys_stream_descr, false, &isys_stream->channel); - if (rc == false) { + if (!rc) { destroy_input_system_input_port(&isys_stream->input_port); return false; } @@ -204,7 +204,7 @@ ia_css_isys_error_t ia_css_isys_stream_create( if (isys_stream_descr->metadata.enable) { rc = create_input_system_channel(isys_stream_descr, true, &isys_stream->md_channel); - if (rc == false) { + if (!rc) { destroy_input_system_input_port(&isys_stream->input_port); destroy_input_system_channel(&isys_stream->channel); return false; @@ -248,7 +248,7 @@ ia_css_isys_error_t ia_css_isys_stream_calculate_cfg( isys_stream_descr, &isys_stream_cfg->channel_cfg, false); - if (rc == false) + if (!rc) return false; /* configure metadata channel */ @@ -260,7 +260,7 @@ ia_css_isys_error_t ia_css_isys_stream_calculate_cfg( isys_stream_descr, &isys_stream_cfg->md_channel_cfg, true); - if (rc == false) + if (!rc) return false; } @@ -269,7 +269,7 @@ ia_css_isys_error_t ia_css_isys_stream_calculate_cfg( &isys_stream->input_port, isys_stream_descr, &isys_stream_cfg->input_port_cfg); - if (rc == false) + if (!rc) return false; isys_stream->valid = 1; diff --git a/drivers/staging/media/atomisp/pci/runtime/queue/src/queue.c b/drivers/staging/media/atomisp/pci/runtime/queue/src/queue.c index aea6c66a3cee..2f1c2df59f71 100644 --- a/drivers/staging/media/atomisp/pci/runtime/queue/src/queue.c +++ b/drivers/staging/media/atomisp/pci/runtime/queue/src/queue.c @@ -22,9 +22,7 @@ /***************************************************************************** * Queue Public APIs *****************************************************************************/ -int ia_css_queue_local_init( - ia_css_queue_t *qhandle, - ia_css_queue_local_t *desc) +int ia_css_queue_local_init(ia_css_queue_t *qhandle, ia_css_queue_local_t *desc) { if (NULL == qhandle || NULL == desc || NULL == desc->cb_elems || NULL == desc->cb_desc) { @@ -43,9 +41,7 @@ int ia_css_queue_local_init( return 0; } -int ia_css_queue_remote_init( - ia_css_queue_t *qhandle, - ia_css_queue_remote_t *desc) +int ia_css_queue_remote_init(ia_css_queue_t *qhandle, ia_css_queue_remote_t *desc) { if (NULL == qhandle || NULL == desc) { /* Invalid parameters, return error*/ @@ -69,8 +65,7 @@ int ia_css_queue_remote_init( return 0; } -int ia_css_queue_uninit( - ia_css_queue_t *qhandle) +int ia_css_queue_uninit(ia_css_queue_t *qhandle) { if (!qhandle) return -EINVAL; @@ -84,9 +79,7 @@ int ia_css_queue_uninit( return 0; } -int ia_css_queue_enqueue( - ia_css_queue_t *qhandle, - uint32_t item) +int ia_css_queue_enqueue(ia_css_queue_t *qhandle, uint32_t item) { int error = 0; @@ -143,9 +136,7 @@ int ia_css_queue_enqueue( return 0; } -int ia_css_queue_dequeue( - ia_css_queue_t *qhandle, - uint32_t *item) +int ia_css_queue_dequeue(ia_css_queue_t *qhandle, uint32_t *item) { int error = 0; @@ -200,9 +191,7 @@ int ia_css_queue_dequeue( return 0; } -int ia_css_queue_is_full( - ia_css_queue_t *qhandle, - bool *is_full) +int ia_css_queue_is_full(ia_css_queue_t *qhandle, bool *is_full) { int error = 0; @@ -234,9 +223,7 @@ int ia_css_queue_is_full( return -EINVAL; } -int ia_css_queue_get_free_space( - ia_css_queue_t *qhandle, - uint32_t *size) +int ia_css_queue_get_free_space(ia_css_queue_t *qhandle, uint32_t *size) { int error = 0; @@ -268,9 +255,7 @@ int ia_css_queue_get_free_space( return -EINVAL; } -int ia_css_queue_get_used_space( - ia_css_queue_t *qhandle, - uint32_t *size) +int ia_css_queue_get_used_space(ia_css_queue_t *qhandle, uint32_t *size) { int error = 0; @@ -302,10 +287,7 @@ int ia_css_queue_get_used_space( return -EINVAL; } -int ia_css_queue_peek( - ia_css_queue_t *qhandle, - u32 offset, - uint32_t *element) +int ia_css_queue_peek(ia_css_queue_t *qhandle, u32 offset, uint32_t *element) { u32 num_elems = 0; int error = 0; @@ -354,9 +336,7 @@ int ia_css_queue_peek( return -EINVAL; } -int ia_css_queue_is_empty( - ia_css_queue_t *qhandle, - bool *is_empty) +int ia_css_queue_is_empty(ia_css_queue_t *qhandle, bool *is_empty) { int error = 0; @@ -388,9 +368,7 @@ int ia_css_queue_is_empty( return -EINVAL; } -int ia_css_queue_get_size( - ia_css_queue_t *qhandle, - uint32_t *size) +int ia_css_queue_get_size(ia_css_queue_t *qhandle, uint32_t *size) { int error = 0; diff --git a/drivers/staging/media/atomisp/pci/runtime/rmgr/src/rmgr_vbuf.c b/drivers/staging/media/atomisp/pci/runtime/rmgr/src/rmgr_vbuf.c index b4f53be18e7f..d96aaa4bc75d 100644 --- a/drivers/staging/media/atomisp/pci/runtime/rmgr/src/rmgr_vbuf.c +++ b/drivers/staging/media/atomisp/pci/runtime/rmgr/src/rmgr_vbuf.c @@ -30,34 +30,22 @@ static struct ia_css_rmgr_vbuf_handle handle_table[NUM_HANDLES]; /* * @brief VBUF resource pool - refpool */ -static struct ia_css_rmgr_vbuf_pool refpool = { - false, /* copy_on_write */ - false, /* recycle */ - 0, /* size */ - 0, /* index */ - NULL, /* handles */ -}; +static struct ia_css_rmgr_vbuf_pool refpool; /* * @brief VBUF resource pool - writepool */ static struct ia_css_rmgr_vbuf_pool writepool = { - true, /* copy_on_write */ - false, /* recycle */ - 0, /* size */ - 0, /* index */ - NULL, /* handles */ + .copy_on_write = true, }; /* * @brief VBUF resource pool - hmmbufferpool */ static struct ia_css_rmgr_vbuf_pool hmmbufferpool = { - true, /* copy_on_write */ - true, /* recycle */ - 32, /* size */ - 0, /* index */ - NULL, /* handles */ + .copy_on_write = true, + .recycle = true, + .size = 32, }; struct ia_css_rmgr_vbuf_pool *vbuf_ref = &refpool; @@ -98,7 +86,7 @@ void ia_css_rmgr_refcount_retain_vbuf(struct ia_css_rmgr_vbuf_handle **handle) } } /* if the loop dus not break and *handle == NULL - this is an error handle and report it. + * this is an error handle and report it. */ if (!*handle) { ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR, @@ -119,8 +107,7 @@ void ia_css_rmgr_refcount_retain_vbuf(struct ia_css_rmgr_vbuf_handle **handle) void ia_css_rmgr_refcount_release_vbuf(struct ia_css_rmgr_vbuf_handle **handle) { if ((!handle) || ((*handle) == NULL) || (((*handle)->count) == 0)) { - ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR, - "ia_css_rmgr_refcount_release_vbuf() invalid arguments!\n"); + ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR, "%s invalid arguments!\n", __func__); return; } /* decrease reference count */ @@ -175,10 +162,9 @@ void ia_css_rmgr_uninit_vbuf(struct ia_css_rmgr_vbuf_pool *pool) { u32 i; - ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_rmgr_uninit_vbuf()\n"); + ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "%s\n", __func__); if (!pool) { - ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR, - "ia_css_rmgr_uninit_vbuf(): NULL argument\n"); + ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR, "%s NULL argument\n", __func__); return; } if (pool->handles) { @@ -192,8 +178,7 @@ void ia_css_rmgr_uninit_vbuf(struct ia_css_rmgr_vbuf_pool *pool) /* free memory */ hmm_free(pool->handles[i]->vptr); /* remove from refcount admin */ - ia_css_rmgr_refcount_release_vbuf( - &pool->handles[i]); + ia_css_rmgr_refcount_release_vbuf(&pool->handles[i]); } } /* now free the pool handles list */ @@ -253,7 +238,8 @@ void rmgr_pop_handle(struct ia_css_rmgr_vbuf_pool *pool, *handle = pool->handles[i]; pool->handles[i] = NULL; /* dont release, we are returning it... - ia_css_rmgr_refcount_release_vbuf(handle); */ + * ia_css_rmgr_refcount_release_vbuf(handle); + */ return; } } @@ -296,7 +282,8 @@ void ia_css_rmgr_acq_vbuf(struct ia_css_rmgr_vbuf_pool *pool, } if ((*handle)->vptr == 0x0) { /* we need to allocate */ - (*handle)->vptr = hmm_alloc((*handle)->size, HMM_BO_PRIVATE, 0, NULL, 0); + (*handle)->vptr = hmm_alloc((*handle)->size, + HMM_BO_PRIVATE, 0, NULL, 0); } else { /* we popped a buffer */ return; diff --git a/drivers/staging/media/atomisp/pci/runtime/spctrl/src/spctrl.c b/drivers/staging/media/atomisp/pci/runtime/spctrl/src/spctrl.c index 753a99703f1e..7f4592565af6 100644 --- a/drivers/staging/media/atomisp/pci/runtime/spctrl/src/spctrl.c +++ b/drivers/staging/media/atomisp/pci/runtime/spctrl/src/spctrl.c @@ -37,8 +37,7 @@ static struct spctrl_context_info spctrl_cofig_info[N_SP_ID]; static bool spctrl_loaded[N_SP_ID] = {0}; /* Load firmware */ -int ia_css_spctrl_load_fw(sp_ID_t sp_id, - ia_css_spctrl_cfg *spctrl_cfg) +int ia_css_spctrl_load_fw(sp_ID_t sp_id, ia_css_spctrl_cfg *spctrl_cfg) { ia_css_ptr code_addr = mmgr_NULL; struct ia_css_sp_init_dmem_cfg *init_dmem_cfg; @@ -106,8 +105,8 @@ int ia_css_spctrl_load_fw(sp_ID_t sp_id, void sh_css_spctrl_reload_fw(sp_ID_t sp_id) { /* now we program the base address into the icache and - * invalidate the cache. - */ + * invalidate the cache. + */ sp_ctrl_store(sp_id, SP_ICACHE_ADDR_REG, (hrt_data)spctrl_cofig_info[sp_id].code_addr); sp_ctrl_setbit(sp_id, SP_ICACHE_INV_REG, SP_ICACHE_INV_BIT); diff --git a/drivers/staging/media/atomisp/pci/runtime/timer/src/timer.c b/drivers/staging/media/atomisp/pci/runtime/timer/src/timer.c index 679ef8242574..08f5c3ea6d29 100644 --- a/drivers/staging/media/atomisp/pci/runtime/timer/src/timer.c +++ b/drivers/staging/media/atomisp/pci/runtime/timer/src/timer.c @@ -19,14 +19,11 @@ #include "gp_timer.h" /*gp_timer_read()*/ #include "assert_support.h" -int -ia_css_timer_get_current_tick( - struct ia_css_clock_tick *curr_ts) { +int ia_css_timer_get_current_tick(struct ia_css_clock_tick *curr_ts) +{ assert(curr_ts); if (!curr_ts) - { return -EINVAL; - } curr_ts->ticks = (clock_value_t)gp_timer_read(GP_TIMER_SEL); return 0; } diff --git a/drivers/staging/media/atomisp/pci/sh_css.c b/drivers/staging/media/atomisp/pci/sh_css.c index ddee04c8248d..27dd8ce8ba0a 100644 --- a/drivers/staging/media/atomisp/pci/sh_css.c +++ b/drivers/staging/media/atomisp/pci/sh_css.c @@ -49,9 +49,6 @@ #include "ia_css_pipe_util.h" #include "ia_css_pipe_binarydesc.h" #include "ia_css_pipe_stagedesc.h" -#ifndef ISP2401 -#include "ia_css_isys.h" -#endif #include "tag.h" #include "assert_support.h" @@ -1063,7 +1060,7 @@ sh_css_config_input_network(struct ia_css_stream *stream) { ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "sh_css_config_input_network() enter 0x%p:\n", stream); - if (stream->config.continuous == true) + if (stream->config.continuous) { if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_CAPTURE) { pipe = stream->last_pipe; @@ -5626,7 +5623,7 @@ static int load_video_binaries(struct ia_css_pipe *pipe) } else { /* output from main binary is not yuv line. currently this is * possible only when bci is enabled on vfpp output */ - assert(pipe->config.enable_vfpp_bci == true); + assert(pipe->config.enable_vfpp_bci); ia_css_pipe_get_yuvscaler_binarydesc(pipe, &vf_pp_descr, &mycs->video_binary.vf_frame_info, pipe_vf_out_info, NULL, NULL); @@ -8072,7 +8069,7 @@ create_host_regular_capture_pipeline(struct ia_css_pipe *pipe) { struct ia_css_frame *tmp_out_frame = NULL; for (i = 0; i < num_yuv_scaler; i++) { - if (is_output_stage[i] == true) + if (is_output_stage[i]) tmp_out_frame = out_frame; else tmp_out_frame = NULL; @@ -8464,7 +8461,7 @@ sh_css_pipeline_add_acc_stage(struct ia_css_pipeline *pipeline, /* In QoS case, load_extension already called, so skipping */ int err = 0; - if (fw->loaded == false) + if (!fw->loaded) err = acc_load_extension(fw); ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, @@ -9701,8 +9698,8 @@ ia_css_stream_destroy(struct ia_css_stream *stream) { assert(entry); if (entry) { /* get the SP thread id */ - if (ia_css_pipeline_get_sp_thread_id( - ia_css_pipe_get_pipe_num(entry), &sp_thread_id) != true) + if (!ia_css_pipeline_get_sp_thread_id( + ia_css_pipe_get_pipe_num(entry), &sp_thread_id)) return -EINVAL; /* get the target input terminal */ sp_pipeline_input_terminal = diff --git a/drivers/staging/media/atomisp/pci/sh_css_firmware.c b/drivers/staging/media/atomisp/pci/sh_css_firmware.c index db25e39bea88..f4ce8ace9d50 100644 --- a/drivers/staging/media/atomisp/pci/sh_css_firmware.c +++ b/drivers/staging/media/atomisp/pci/sh_css_firmware.c @@ -366,7 +366,7 @@ void sh_css_unload_firmware(void) if (fw_minibuffer[i].name) kfree((void *)fw_minibuffer[i].name); if (fw_minibuffer[i].buffer) - vfree((void *)fw_minibuffer[i].buffer); + kvfree(fw_minibuffer[i].buffer); } kfree(fw_minibuffer); fw_minibuffer = NULL; diff --git a/drivers/staging/media/atomisp/pci/sh_css_mipi.c b/drivers/staging/media/atomisp/pci/sh_css_mipi.c index d5ae7f0b5864..3f34cc81be87 100644 --- a/drivers/staging/media/atomisp/pci/sh_css_mipi.c +++ b/drivers/staging/media/atomisp/pci/sh_css_mipi.c @@ -33,17 +33,6 @@ static u32 ref_count_mipi_allocation[N_CSI_PORTS]; /* Initialized in mipi_init */ -int -ia_css_mipi_frame_specify(const unsigned int size_mem_words, - const bool contiguous) { - int err = 0; - - my_css.size_mem_words = size_mem_words; - (void)contiguous; - - return err; -} - /* * Check if a source port or TPG/PRBS ID is valid */ diff --git a/drivers/staging/media/atomisp/pci/sh_css_params.c b/drivers/staging/media/atomisp/pci/sh_css_params.c index 9fad28b97201..644e14575987 100644 --- a/drivers/staging/media/atomisp/pci/sh_css_params.c +++ b/drivers/staging/media/atomisp/pci/sh_css_params.c @@ -1575,8 +1575,7 @@ ia_css_isp_3a_statistics_map_allocate( return me; err: - if (me) - kvfree(me); + kvfree(me); return NULL; } @@ -3006,8 +3005,7 @@ ia_css_stream_isp_parameters_uninit(struct ia_css_stream *stream) } kvfree(params); - if (per_frame_params) - kvfree(per_frame_params); + kvfree(per_frame_params); stream->isp_params_configs = NULL; stream->per_frame_isp_params_configs = NULL; @@ -4649,10 +4647,8 @@ ia_css_dvs2_6axis_config_allocate(const struct ia_css_stream *stream) params = stream->isp_params_configs; /* Backward compatibility by default consider pipe as Video*/ - if (!params || (params && - !params->pipe_dvs_6axis_config[IA_CSS_PIPE_ID_VIDEO])) { + if (!params || !params->pipe_dvs_6axis_config[IA_CSS_PIPE_ID_VIDEO]) goto err; - } dvs_config = kvcalloc(1, sizeof(struct ia_css_dvs_6axis_config), GFP_KERNEL); diff --git a/drivers/staging/media/hantro/hantro.h b/drivers/staging/media/hantro/hantro.h index 65f9f7ea7dcf..6c1b888abe75 100644 --- a/drivers/staging/media/hantro/hantro.h +++ b/drivers/staging/media/hantro/hantro.h @@ -214,6 +214,7 @@ struct hantro_dev { * * @codec_ops: Set of operations related to codec mode. * @postproc: Post-processing context. + * @h264_dec: H.264-decoding context. * @jpeg_enc: JPEG-encoding context. * @mpeg2_dec: MPEG-2-decoding context. * @vp8_dec: VP8-decoding context. @@ -293,7 +294,7 @@ struct hantro_postproc_regs { /* Logging helpers */ /** - * debug - Module parameter to control level of debugging messages. + * DOC: hantro_debug: Module parameter to control level of debugging messages. * * Level of debugging messages can be controlled by bits of * module parameter called "debug". Meaning of particular diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c index e5f200e64993..595e82a82728 100644 --- a/drivers/staging/media/hantro/hantro_drv.c +++ b/drivers/staging/media/hantro/hantro_drv.c @@ -299,7 +299,7 @@ static const struct hantro_ctrl controls[] = { }, { .codec = HANTRO_VP8_DECODER, .cfg = { - .id = V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER, + .id = V4L2_CID_STATELESS_VP8_FRAME, }, }, { .codec = HANTRO_H264_DECODER, diff --git a/drivers/staging/media/hantro/hantro_g1_vp8_dec.c b/drivers/staging/media/hantro/hantro_g1_vp8_dec.c index a5cdf150cd16..57002ba70176 100644 --- a/drivers/staging/media/hantro/hantro_g1_vp8_dec.c +++ b/drivers/staging/media/hantro/hantro_g1_vp8_dec.c @@ -10,7 +10,6 @@ */ #include <media/v4l2-mem2mem.h> -#include <media/vp8-ctrls.h> #include "hantro_hw.h" #include "hantro.h" @@ -133,17 +132,17 @@ static const struct hantro_reg vp8_dec_pred_bc_tap[8][4] = { * Set loop filters */ static void cfg_lf(struct hantro_ctx *ctx, - const struct v4l2_ctrl_vp8_frame_header *hdr) + const struct v4l2_ctrl_vp8_frame *hdr) { - const struct v4l2_vp8_segment_header *seg = &hdr->segment_header; - const struct v4l2_vp8_loopfilter_header *lf = &hdr->lf_header; + const struct v4l2_vp8_segment *seg = &hdr->segment; + const struct v4l2_vp8_loop_filter *lf = &hdr->lf; struct hantro_dev *vpu = ctx->dev; unsigned int i; u32 reg; - if (!(seg->flags & V4L2_VP8_SEGMENT_HEADER_FLAG_ENABLED)) { + if (!(seg->flags & V4L2_VP8_SEGMENT_FLAG_ENABLED)) { hantro_reg_write(vpu, &vp8_dec_lf_level[0], lf->level); - } else if (seg->flags & V4L2_VP8_SEGMENT_HEADER_FLAG_DELTA_VALUE_MODE) { + } else if (seg->flags & V4L2_VP8_SEGMENT_FLAG_DELTA_VALUE_MODE) { for (i = 0; i < 4; i++) { u32 lf_level = clamp(lf->level + seg->lf_update[i], 0, 63); @@ -161,7 +160,7 @@ static void cfg_lf(struct hantro_ctx *ctx, reg |= G1_REG_REF_PIC_FILT_TYPE_E; vdpu_write_relaxed(vpu, reg, G1_REG_REF_PIC(0)); - if (lf->flags & V4L2_VP8_LF_HEADER_ADJ_ENABLE) { + if (lf->flags & V4L2_VP8_LF_ADJ_ENABLE) { for (i = 0; i < 4; i++) { hantro_reg_write(vpu, &vp8_dec_mb_adj[i], lf->mb_mode_delta[i]); @@ -175,16 +174,16 @@ static void cfg_lf(struct hantro_ctx *ctx, * Set quantization parameters */ static void cfg_qp(struct hantro_ctx *ctx, - const struct v4l2_ctrl_vp8_frame_header *hdr) + const struct v4l2_ctrl_vp8_frame *hdr) { - const struct v4l2_vp8_quantization_header *q = &hdr->quant_header; - const struct v4l2_vp8_segment_header *seg = &hdr->segment_header; + const struct v4l2_vp8_quantization *q = &hdr->quant; + const struct v4l2_vp8_segment *seg = &hdr->segment; struct hantro_dev *vpu = ctx->dev; unsigned int i; - if (!(seg->flags & V4L2_VP8_SEGMENT_HEADER_FLAG_ENABLED)) { + if (!(seg->flags & V4L2_VP8_SEGMENT_FLAG_ENABLED)) { hantro_reg_write(vpu, &vp8_dec_quant[0], q->y_ac_qi); - } else if (seg->flags & V4L2_VP8_SEGMENT_HEADER_FLAG_DELTA_VALUE_MODE) { + } else if (seg->flags & V4L2_VP8_SEGMENT_FLAG_DELTA_VALUE_MODE) { for (i = 0; i < 4; i++) { u32 quant = clamp(q->y_ac_qi + seg->quant_update[i], 0, 127); @@ -230,11 +229,11 @@ static void cfg_qp(struct hantro_ctx *ctx, * 4. the addresses set to the VPU must be 64-bits aligned */ static void cfg_parts(struct hantro_ctx *ctx, - const struct v4l2_ctrl_vp8_frame_header *hdr) + const struct v4l2_ctrl_vp8_frame *hdr) { struct hantro_dev *vpu = ctx->dev; struct vb2_v4l2_buffer *vb2_src; - u32 first_part_offset = VP8_FRAME_IS_KEY_FRAME(hdr) ? 10 : 3; + u32 first_part_offset = V4L2_VP8_FRAME_IS_KEY_FRAME(hdr) ? 10 : 3; u32 mb_size, mb_offset_bytes, mb_offset_bits, mb_start_bits; u32 dct_size_part_size, dct_part_offset; struct hantro_reg reg; @@ -328,7 +327,7 @@ static void cfg_parts(struct hantro_ctx *ctx, * normal 6-tap filters */ static void cfg_tap(struct hantro_ctx *ctx, - const struct v4l2_ctrl_vp8_frame_header *hdr) + const struct v4l2_ctrl_vp8_frame *hdr) { struct hantro_dev *vpu = ctx->dev; struct hantro_reg reg; @@ -368,7 +367,7 @@ static void cfg_tap(struct hantro_ctx *ctx, } static void cfg_ref(struct hantro_ctx *ctx, - const struct v4l2_ctrl_vp8_frame_header *hdr) + const struct v4l2_ctrl_vp8_frame *hdr) { struct hantro_dev *vpu = ctx->dev; struct vb2_v4l2_buffer *vb2_dst; @@ -385,7 +384,7 @@ static void cfg_ref(struct hantro_ctx *ctx, WARN_ON(!ref && hdr->golden_frame_ts); if (!ref) ref = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0); - if (hdr->flags & V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_GOLDEN) + if (hdr->flags & V4L2_VP8_FRAME_FLAG_SIGN_BIAS_GOLDEN) ref |= G1_REG_ADDR_REF_TOPC_E; vdpu_write_relaxed(vpu, ref, G1_REG_ADDR_REF(4)); @@ -393,15 +392,15 @@ static void cfg_ref(struct hantro_ctx *ctx, WARN_ON(!ref && hdr->alt_frame_ts); if (!ref) ref = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0); - if (hdr->flags & V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_ALT) + if (hdr->flags & V4L2_VP8_FRAME_FLAG_SIGN_BIAS_ALT) ref |= G1_REG_ADDR_REF_TOPC_E; vdpu_write_relaxed(vpu, ref, G1_REG_ADDR_REF(5)); } static void cfg_buffers(struct hantro_ctx *ctx, - const struct v4l2_ctrl_vp8_frame_header *hdr) + const struct v4l2_ctrl_vp8_frame *hdr) { - const struct v4l2_vp8_segment_header *seg = &hdr->segment_header; + const struct v4l2_vp8_segment *seg = &hdr->segment; struct hantro_dev *vpu = ctx->dev; struct vb2_v4l2_buffer *vb2_dst; dma_addr_t dst_dma; @@ -415,9 +414,9 @@ static void cfg_buffers(struct hantro_ctx *ctx, /* Set segment map address */ reg = G1_REG_FWD_PIC1_SEGMENT_BASE(ctx->vp8_dec.segment_map.dma); - if (seg->flags & V4L2_VP8_SEGMENT_HEADER_FLAG_ENABLED) { + if (seg->flags & V4L2_VP8_SEGMENT_FLAG_ENABLED) { reg |= G1_REG_FWD_PIC1_SEGMENT_E; - if (seg->flags & V4L2_VP8_SEGMENT_HEADER_FLAG_UPDATE_MAP) + if (seg->flags & V4L2_VP8_SEGMENT_FLAG_UPDATE_MAP) reg |= G1_REG_FWD_PIC1_SEGMENT_UPD_E; } vdpu_write_relaxed(vpu, reg, G1_REG_FWD_PIC(0)); @@ -428,7 +427,7 @@ static void cfg_buffers(struct hantro_ctx *ctx, void hantro_g1_vp8_dec_run(struct hantro_ctx *ctx) { - const struct v4l2_ctrl_vp8_frame_header *hdr; + const struct v4l2_ctrl_vp8_frame *hdr; struct hantro_dev *vpu = ctx->dev; size_t height = ctx->dst_fmt.height; size_t width = ctx->dst_fmt.width; @@ -437,12 +436,12 @@ void hantro_g1_vp8_dec_run(struct hantro_ctx *ctx) hantro_start_prepare_run(ctx); - hdr = hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER); + hdr = hantro_get_ctrl(ctx, V4L2_CID_STATELESS_VP8_FRAME); if (WARN_ON(!hdr)) return; /* Reset segment_map buffer in keyframe */ - if (VP8_FRAME_IS_KEY_FRAME(hdr) && ctx->vp8_dec.segment_map.cpu) + if (V4L2_VP8_FRAME_IS_KEY_FRAME(hdr) && ctx->vp8_dec.segment_map.cpu) memset(ctx->vp8_dec.segment_map.cpu, 0, ctx->vp8_dec.segment_map.size); @@ -460,11 +459,11 @@ void hantro_g1_vp8_dec_run(struct hantro_ctx *ctx) vdpu_write_relaxed(vpu, reg, G1_REG_CONFIG); reg = G1_REG_DEC_CTRL0_DEC_MODE(10); - if (!VP8_FRAME_IS_KEY_FRAME(hdr)) + if (!V4L2_VP8_FRAME_IS_KEY_FRAME(hdr)) reg |= G1_REG_DEC_CTRL0_PIC_INTER_E; - if (!(hdr->flags & V4L2_VP8_FRAME_HEADER_FLAG_MB_NO_SKIP_COEFF)) + if (!(hdr->flags & V4L2_VP8_FRAME_FLAG_MB_NO_SKIP_COEFF)) reg |= G1_REG_DEC_CTRL0_SKIP_MODE; - if (hdr->lf_header.level == 0) + if (hdr->lf.level == 0) reg |= G1_REG_DEC_CTRL0_FILTERING_DIS; vdpu_write_relaxed(vpu, reg, G1_REG_DEC_CTRL0); diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h index 34c9e4649a25..83b3e42b63a3 100644 --- a/drivers/staging/media/hantro/hantro_hw.h +++ b/drivers/staging/media/hantro/hantro_hw.h @@ -27,6 +27,7 @@ struct hantro_variant; /** * struct hantro_aux_buf - auxiliary DMA buffer for hardware data + * * @cpu: CPU pointer to the buffer. * @dma: DMA address of the buffer. * @size: Size of the buffer. @@ -41,6 +42,7 @@ struct hantro_aux_buf { /** * struct hantro_jpeg_enc_hw_ctx + * * @bounce_buffer: Bounce buffer */ struct hantro_jpeg_enc_hw_ctx { @@ -52,6 +54,7 @@ struct hantro_jpeg_enc_hw_ctx { /** * struct hantro_h264_dec_ctrls + * * @decode: Decode params * @scaling: Scaling info * @sps: SPS info @@ -66,6 +69,7 @@ struct hantro_h264_dec_ctrls { /** * struct hantro_h264_dec_reflists + * * @p: P reflist * @b0: B0 reflist * @b1: B1 reflist @@ -78,6 +82,7 @@ struct hantro_h264_dec_reflists { /** * struct hantro_h264_dec_hw_ctx + * * @priv: Private auxiliary buffer for hardware. * @dpb: DPB * @reflists: P/B0/B1 reflists @@ -92,6 +97,7 @@ struct hantro_h264_dec_hw_ctx { /** * struct hantro_mpeg2_dec_hw_ctx + * * @qtable: Quantization table */ struct hantro_mpeg2_dec_hw_ctx { @@ -99,7 +105,8 @@ struct hantro_mpeg2_dec_hw_ctx { }; /** - * struct hantro_vp8d_hw_ctx + * struct hantro_vp8_dec_hw_ctx + * * @segment_map: Segment map buffer. * @prob_tbl: Probability table buffer. */ @@ -140,6 +147,11 @@ struct hantro_codec_ops { /** * enum hantro_enc_fmt - source format ID for hardware registers. + * + * @RK3288_VPU_ENC_FMT_YUV420P: Y/CbCr 4:2:0 planar format + * @RK3288_VPU_ENC_FMT_YUV420SP: Y/CbCr 4:2:0 semi-planar format + * @RK3288_VPU_ENC_FMT_YUYV422: YUV 4:2:2 packed format (YUYV) + * @RK3288_VPU_ENC_FMT_UYVY422: YUV 4:2:2 packed format (UYVY) */ enum hantro_enc_fmt { RK3288_VPU_ENC_FMT_YUV420P = 0, @@ -216,6 +228,6 @@ void rk3399_vpu_vp8_dec_run(struct hantro_ctx *ctx); int hantro_vp8_dec_init(struct hantro_ctx *ctx); void hantro_vp8_dec_exit(struct hantro_ctx *ctx); void hantro_vp8_prob_update(struct hantro_ctx *ctx, - const struct v4l2_ctrl_vp8_frame_header *hdr); + const struct v4l2_ctrl_vp8_frame *hdr); #endif /* HANTRO_HW_H_ */ diff --git a/drivers/staging/media/hantro/hantro_vp8.c b/drivers/staging/media/hantro/hantro_vp8.c index 91ec9a05645b..381bc1d3bfda 100644 --- a/drivers/staging/media/hantro/hantro_vp8.c +++ b/drivers/staging/media/hantro/hantro_vp8.c @@ -47,9 +47,9 @@ const u32 hantro_vp8_dec_mc_filter[8][6] = { }; void hantro_vp8_prob_update(struct hantro_ctx *ctx, - const struct v4l2_ctrl_vp8_frame_header *hdr) + const struct v4l2_ctrl_vp8_frame *hdr) { - const struct v4l2_vp8_entropy_header *entropy = &hdr->entropy_header; + const struct v4l2_vp8_entropy *entropy = &hdr->entropy; u32 i, j, k; u8 *dst; @@ -60,9 +60,9 @@ void hantro_vp8_prob_update(struct hantro_ctx *ctx, dst[1] = hdr->prob_intra; dst[2] = hdr->prob_last; dst[3] = hdr->prob_gf; - dst[4] = hdr->segment_header.segment_probs[0]; - dst[5] = hdr->segment_header.segment_probs[1]; - dst[6] = hdr->segment_header.segment_probs[2]; + dst[4] = hdr->segment.segment_probs[0]; + dst[5] = hdr->segment.segment_probs[1]; + dst[6] = hdr->segment.segment_probs[2]; dst[7] = 0; dst += 8; diff --git a/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c b/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c index a4a792f00b11..8661a3cc1e6b 100644 --- a/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c +++ b/drivers/staging/media/hantro/rk3399_vpu_hw_vp8_dec.c @@ -13,7 +13,6 @@ */ #include <media/v4l2-mem2mem.h> -#include <media/vp8-ctrls.h> #include "hantro_hw.h" #include "hantro.h" @@ -274,17 +273,17 @@ static const struct hantro_reg vp8_dec_start_dec = { }; static void cfg_lf(struct hantro_ctx *ctx, - const struct v4l2_ctrl_vp8_frame_header *hdr) + const struct v4l2_ctrl_vp8_frame *hdr) { - const struct v4l2_vp8_segment_header *seg = &hdr->segment_header; - const struct v4l2_vp8_loopfilter_header *lf = &hdr->lf_header; + const struct v4l2_vp8_segment *seg = &hdr->segment; + const struct v4l2_vp8_loop_filter *lf = &hdr->lf; struct hantro_dev *vpu = ctx->dev; unsigned int i; u32 reg; - if (!(seg->flags & V4L2_VP8_SEGMENT_HEADER_FLAG_ENABLED)) { + if (!(seg->flags & V4L2_VP8_SEGMENT_FLAG_ENABLED)) { hantro_reg_write(vpu, &vp8_dec_lf_level[0], lf->level); - } else if (seg->flags & V4L2_VP8_SEGMENT_HEADER_FLAG_DELTA_VALUE_MODE) { + } else if (seg->flags & V4L2_VP8_SEGMENT_FLAG_DELTA_VALUE_MODE) { for (i = 0; i < 4; i++) { u32 lf_level = clamp(lf->level + seg->lf_update[i], 0, 63); @@ -302,7 +301,7 @@ static void cfg_lf(struct hantro_ctx *ctx, reg |= VDPU_REG_REF_PIC_FILT_TYPE_E; vdpu_write_relaxed(vpu, reg, VDPU_REG_FILTER_MB_ADJ); - if (lf->flags & V4L2_VP8_LF_HEADER_ADJ_ENABLE) { + if (lf->flags & V4L2_VP8_LF_ADJ_ENABLE) { for (i = 0; i < 4; i++) { hantro_reg_write(vpu, &vp8_dec_mb_adj[i], lf->mb_mode_delta[i]); @@ -313,16 +312,16 @@ static void cfg_lf(struct hantro_ctx *ctx, } static void cfg_qp(struct hantro_ctx *ctx, - const struct v4l2_ctrl_vp8_frame_header *hdr) + const struct v4l2_ctrl_vp8_frame *hdr) { - const struct v4l2_vp8_quantization_header *q = &hdr->quant_header; - const struct v4l2_vp8_segment_header *seg = &hdr->segment_header; + const struct v4l2_vp8_quantization *q = &hdr->quant; + const struct v4l2_vp8_segment *seg = &hdr->segment; struct hantro_dev *vpu = ctx->dev; unsigned int i; - if (!(seg->flags & V4L2_VP8_SEGMENT_HEADER_FLAG_ENABLED)) { + if (!(seg->flags & V4L2_VP8_SEGMENT_FLAG_ENABLED)) { hantro_reg_write(vpu, &vp8_dec_quant[0], q->y_ac_qi); - } else if (seg->flags & V4L2_VP8_SEGMENT_HEADER_FLAG_DELTA_VALUE_MODE) { + } else if (seg->flags & V4L2_VP8_SEGMENT_FLAG_DELTA_VALUE_MODE) { for (i = 0; i < 4; i++) { u32 quant = clamp(q->y_ac_qi + seg->quant_update[i], 0, 127); @@ -343,11 +342,11 @@ static void cfg_qp(struct hantro_ctx *ctx, } static void cfg_parts(struct hantro_ctx *ctx, - const struct v4l2_ctrl_vp8_frame_header *hdr) + const struct v4l2_ctrl_vp8_frame *hdr) { struct hantro_dev *vpu = ctx->dev; struct vb2_v4l2_buffer *vb2_src; - u32 first_part_offset = VP8_FRAME_IS_KEY_FRAME(hdr) ? 10 : 3; + u32 first_part_offset = V4L2_VP8_FRAME_IS_KEY_FRAME(hdr) ? 10 : 3; u32 mb_size, mb_offset_bytes, mb_offset_bits, mb_start_bits; u32 dct_size_part_size, dct_part_offset; dma_addr_t src_dma; @@ -426,7 +425,7 @@ static void cfg_parts(struct hantro_ctx *ctx, * normal 6-tap filters */ static void cfg_tap(struct hantro_ctx *ctx, - const struct v4l2_ctrl_vp8_frame_header *hdr) + const struct v4l2_ctrl_vp8_frame *hdr) { struct hantro_dev *vpu = ctx->dev; int i, j; @@ -445,7 +444,7 @@ static void cfg_tap(struct hantro_ctx *ctx, } static void cfg_ref(struct hantro_ctx *ctx, - const struct v4l2_ctrl_vp8_frame_header *hdr) + const struct v4l2_ctrl_vp8_frame *hdr) { struct hantro_dev *vpu = ctx->dev; struct vb2_v4l2_buffer *vb2_dst; @@ -462,7 +461,7 @@ static void cfg_ref(struct hantro_ctx *ctx, WARN_ON(!ref && hdr->golden_frame_ts); if (!ref) ref = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0); - if (hdr->flags & V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_GOLDEN) + if (hdr->flags & V4L2_VP8_FRAME_FLAG_SIGN_BIAS_GOLDEN) ref |= VDPU_REG_VP8_GREF_SIGN_BIAS; vdpu_write_relaxed(vpu, ref, VDPU_REG_VP8_ADDR_REF2_5(2)); @@ -470,15 +469,15 @@ static void cfg_ref(struct hantro_ctx *ctx, WARN_ON(!ref && hdr->alt_frame_ts); if (!ref) ref = vb2_dma_contig_plane_dma_addr(&vb2_dst->vb2_buf, 0); - if (hdr->flags & V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_ALT) + if (hdr->flags & V4L2_VP8_FRAME_FLAG_SIGN_BIAS_ALT) ref |= VDPU_REG_VP8_AREF_SIGN_BIAS; vdpu_write_relaxed(vpu, ref, VDPU_REG_VP8_ADDR_REF2_5(3)); } static void cfg_buffers(struct hantro_ctx *ctx, - const struct v4l2_ctrl_vp8_frame_header *hdr) + const struct v4l2_ctrl_vp8_frame *hdr) { - const struct v4l2_vp8_segment_header *seg = &hdr->segment_header; + const struct v4l2_vp8_segment *seg = &hdr->segment; struct hantro_dev *vpu = ctx->dev; struct vb2_v4l2_buffer *vb2_dst; dma_addr_t dst_dma; @@ -492,9 +491,9 @@ static void cfg_buffers(struct hantro_ctx *ctx, /* Set segment map address */ reg = VDPU_REG_FWD_PIC1_SEGMENT_BASE(ctx->vp8_dec.segment_map.dma); - if (seg->flags & V4L2_VP8_SEGMENT_HEADER_FLAG_ENABLED) { + if (seg->flags & V4L2_VP8_SEGMENT_FLAG_ENABLED) { reg |= VDPU_REG_FWD_PIC1_SEGMENT_E; - if (seg->flags & V4L2_VP8_SEGMENT_HEADER_FLAG_UPDATE_MAP) + if (seg->flags & V4L2_VP8_SEGMENT_FLAG_UPDATE_MAP) reg |= VDPU_REG_FWD_PIC1_SEGMENT_UPD_E; } vdpu_write_relaxed(vpu, reg, VDPU_REG_VP8_SEGMENT_VAL); @@ -506,7 +505,7 @@ static void cfg_buffers(struct hantro_ctx *ctx, void rk3399_vpu_vp8_dec_run(struct hantro_ctx *ctx) { - const struct v4l2_ctrl_vp8_frame_header *hdr; + const struct v4l2_ctrl_vp8_frame *hdr; struct hantro_dev *vpu = ctx->dev; size_t height = ctx->dst_fmt.height; size_t width = ctx->dst_fmt.width; @@ -515,12 +514,12 @@ void rk3399_vpu_vp8_dec_run(struct hantro_ctx *ctx) hantro_start_prepare_run(ctx); - hdr = hantro_get_ctrl(ctx, V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER); + hdr = hantro_get_ctrl(ctx, V4L2_CID_STATELESS_VP8_FRAME); if (WARN_ON(!hdr)) return; /* Reset segment_map buffer in keyframe */ - if (VP8_FRAME_IS_KEY_FRAME(hdr) && ctx->vp8_dec.segment_map.cpu) + if (V4L2_VP8_FRAME_IS_KEY_FRAME(hdr) && ctx->vp8_dec.segment_map.cpu) memset(ctx->vp8_dec.segment_map.cpu, 0, ctx->vp8_dec.segment_map.size); @@ -537,7 +536,7 @@ void rk3399_vpu_vp8_dec_run(struct hantro_ctx *ctx) reg = VDPU_REG_CONFIG_DEC_TIMEOUT_E | VDPU_REG_CONFIG_DEC_CLK_GATE_E; - if (!VP8_FRAME_IS_KEY_FRAME(hdr)) + if (!V4L2_VP8_FRAME_IS_KEY_FRAME(hdr)) reg |= VDPU_REG_DEC_CTRL0_PIC_INTER_E; vdpu_write_relaxed(vpu, reg, VDPU_REG_EN_FLAGS); @@ -555,9 +554,9 @@ void rk3399_vpu_vp8_dec_run(struct hantro_ctx *ctx) reg = VDPU_REG_DEC_CTRL0_DEC_MODE(10); vdpu_write_relaxed(vpu, reg, VDPU_REG_DEC_FORMAT); - if (!(hdr->flags & V4L2_VP8_FRAME_HEADER_FLAG_MB_NO_SKIP_COEFF)) + if (!(hdr->flags & V4L2_VP8_FRAME_FLAG_MB_NO_SKIP_COEFF)) hantro_reg_write(vpu, &vp8_dec_skip_mode, 1); - if (hdr->lf_header.level == 0) + if (hdr->lf.level == 0) hantro_reg_write(vpu, &vp8_dec_filter_disable, 1); /* Frame dimensions */ diff --git a/drivers/staging/media/imx/Kconfig b/drivers/staging/media/imx/Kconfig index 15322dc3124a..c3bf433ba3e3 100644 --- a/drivers/staging/media/imx/Kconfig +++ b/drivers/staging/media/imx/Kconfig @@ -2,13 +2,14 @@ config VIDEO_IMX_MEDIA tristate "i.MX5/6 V4L2 media core driver" depends on ARCH_MXC || COMPILE_TEST + depends on HAS_DMA + depends on VIDEO_DEV depends on VIDEO_V4L2 select MEDIA_CONTROLLER - select VIDEO_V4L2_SUBDEV_API - depends on HAS_DMA - select VIDEOBUF2_DMA_CONTIG select V4L2_FWNODE select V4L2_MEM2MEM_DEV + select VIDEOBUF2_DMA_CONTIG + select VIDEO_V4L2_SUBDEV_API help Say yes here to enable support for video4linux media controller driver for the i.MX5/6 SOC. @@ -18,7 +19,6 @@ menu "i.MX5/6/7/8 Media Sub devices" config VIDEO_IMX_CSI tristate "i.MX5/6 Camera Sensor Interface driver" - depends on VIDEO_IMX_MEDIA && VIDEO_DEV && I2C depends on IMX_IPUV3_CORE default y help @@ -26,7 +26,6 @@ config VIDEO_IMX_CSI config VIDEO_IMX7_CSI tristate "i.MX6UL/L / i.MX7 / i.MX8M Camera Sensor Interface driver" - depends on VIDEO_IMX_MEDIA && VIDEO_DEV && I2C default y help Enable support for video4linux camera sensor interface driver for diff --git a/drivers/staging/media/imx/Makefile b/drivers/staging/media/imx/Makefile index 69cc5da04a2e..6ac33275cc97 100644 --- a/drivers/staging/media/imx/Makefile +++ b/drivers/staging/media/imx/Makefile @@ -1,11 +1,11 @@ # SPDX-License-Identifier: GPL-2.0 +imx-media-common-objs := imx-media-capture.o imx-media-dev-common.o \ + imx-media-of.o imx-media-utils.o + imx6-media-objs := imx-media-dev.o imx-media-internal-sd.o \ imx-ic-common.o imx-ic-prp.o imx-ic-prpencvf.o imx-media-vdic.o \ imx-media-csc-scaler.o -imx-media-common-objs := imx-media-capture.o imx-media-dev-common.o \ - imx-media-of.o imx-media-utils.o - imx6-media-csi-objs := imx-media-csi.o imx-media-fim.o obj-$(CONFIG_VIDEO_IMX_MEDIA) += imx-media-common.o diff --git a/drivers/staging/media/imx/TODO b/drivers/staging/media/imx/TODO index 9cfc1c1e78dc..2384f4c6b09d 100644 --- a/drivers/staging/media/imx/TODO +++ b/drivers/staging/media/imx/TODO @@ -17,9 +17,12 @@ - This media driver supports inheriting V4L2 controls to the video capture devices, from the subdevices in the capture device's pipeline. The controls for each capture device are updated in the - link_notify callback when the pipeline is modified. It should be - decided whether this feature is useful enough to make it generally - available by exporting to v4l2-core. + link_notify callback when the pipeline is modified. This feature should be + removed, userspace should use the subdev-based userspace API instead. + +- Similarly to the legacy control handling, legacy format handling where + formats on the video nodes are influenced by the active format of the + connected subdev should be removed. - i.MX7: all of the above, since it uses the imx media core diff --git a/drivers/staging/media/imx/imx-ic-prp.c b/drivers/staging/media/imx/imx-ic-prp.c index 5b09e11b1a0e..f21ed881295f 100644 --- a/drivers/staging/media/imx/imx-ic-prp.c +++ b/drivers/staging/media/imx/imx-ic-prp.c @@ -442,7 +442,9 @@ static int prp_registered(struct v4l2_subdev *sd) /* set a default mbus format */ imx_media_enum_ipu_formats(&code, 0, PIXFMT_SEL_YUV); - return imx_media_init_mbus_fmt(&priv->format_mbus, 640, 480, code, + return imx_media_init_mbus_fmt(&priv->format_mbus, + IMX_MEDIA_DEF_PIX_WIDTH, + IMX_MEDIA_DEF_PIX_HEIGHT, code, V4L2_FIELD_NONE, NULL); } diff --git a/drivers/staging/media/imx/imx-ic-prpencvf.c b/drivers/staging/media/imx/imx-ic-prpencvf.c index 74f5de466d5d..d990553de87b 100644 --- a/drivers/staging/media/imx/imx-ic-prpencvf.c +++ b/drivers/staging/media/imx/imx-ic-prpencvf.c @@ -204,7 +204,7 @@ static void prp_vb2_buf_done(struct prp_priv *priv, struct ipuv3_channel *ch) done = priv->active_vb2_buf[priv->ipu_buf_num]; if (done) { - done->vbuf.field = vdev->fmt.fmt.pix.field; + done->vbuf.field = vdev->fmt.field; done->vbuf.sequence = priv->frame_sequence; vb = &done->vbuf.vb2_buf; vb->timestamp = ktime_get_ns(); @@ -229,7 +229,7 @@ static void prp_vb2_buf_done(struct prp_priv *priv, struct ipuv3_channel *ch) ipu_idmac_clear_buffer(ch, priv->ipu_buf_num); if (priv->interweave_swap && ch == priv->out_ch) - phys += vdev->fmt.fmt.pix.bytesperline; + phys += vdev->fmt.bytesperline; ipu_cpmem_set_buffer(ch, priv->ipu_buf_num, phys); } @@ -362,7 +362,7 @@ static int prp_setup_channel(struct prp_priv *priv, ipu_cpmem_zero(channel); memset(&image, 0, sizeof(image)); - image.pix = vdev->fmt.fmt.pix; + image.pix = vdev->fmt; image.rect = vdev->compose; /* @@ -457,7 +457,7 @@ static int prp_setup_rotation(struct prp_priv *priv) int ret; infmt = &priv->format_mbus[PRPENCVF_SINK_PAD]; - outfmt = &vdev->fmt.fmt.pix; + outfmt = &vdev->fmt; incc = priv->cc[PRPENCVF_SINK_PAD]; outcc = vdev->cc; @@ -586,7 +586,7 @@ static int prp_setup_norotation(struct prp_priv *priv) int ret; infmt = &priv->format_mbus[PRPENCVF_SINK_PAD]; - outfmt = &vdev->fmt.fmt.pix; + outfmt = &vdev->fmt; incc = priv->cc[PRPENCVF_SINK_PAD]; outcc = vdev->cc; @@ -665,17 +665,14 @@ static int prp_start(struct prp_priv *priv) { struct imx_ic_priv *ic_priv = priv->ic_priv; struct imx_media_video_dev *vdev = priv->vdev; - struct v4l2_pix_format *outfmt; int ret; ret = prp_get_ipu_resources(priv); if (ret) return ret; - outfmt = &vdev->fmt.fmt.pix; - ret = imx_media_alloc_dma_buf(ic_priv->ipu_dev, &priv->underrun_buf, - outfmt->sizeimage); + vdev->fmt.sizeimage); if (ret) goto out_put_ipu; @@ -1255,8 +1252,9 @@ static int prp_registered(struct v4l2_subdev *sd) for (i = 0; i < PRPENCVF_NUM_PADS; i++) { ret = imx_media_init_mbus_fmt(&priv->format_mbus[i], - 640, 480, code, V4L2_FIELD_NONE, - &priv->cc[i]); + IMX_MEDIA_DEF_PIX_WIDTH, + IMX_MEDIA_DEF_PIX_HEIGHT, code, + V4L2_FIELD_NONE, &priv->cc[i]); if (ret) return ret; } @@ -1267,11 +1265,11 @@ static int prp_registered(struct v4l2_subdev *sd) priv->vdev = imx_media_capture_device_init(ic_priv->ipu_dev, &ic_priv->sd, - PRPENCVF_SRC_PAD); + PRPENCVF_SRC_PAD, true); if (IS_ERR(priv->vdev)) return PTR_ERR(priv->vdev); - ret = imx_media_capture_device_register(priv->vdev); + ret = imx_media_capture_device_register(priv->vdev, 0); if (ret) goto remove_vdev; diff --git a/drivers/staging/media/imx/imx-media-capture.c b/drivers/staging/media/imx/imx-media-capture.c index e10ce103a5b4..93ba09236010 100644 --- a/drivers/staging/media/imx/imx-media-capture.c +++ b/drivers/staging/media/imx/imx-media-capture.c @@ -29,30 +29,24 @@ #define IMX_CAPTURE_NAME "imx-capture" struct capture_priv { - struct imx_media_video_dev vdev; + struct imx_media_dev *md; /* Media device */ + struct device *dev; /* Physical device */ - struct v4l2_subdev *src_sd; - int src_sd_pad; - struct device *dev; + struct imx_media_video_dev vdev; /* Video device */ + struct media_pad vdev_pad; /* Video device pad */ - struct imx_media_dev *md; + struct v4l2_subdev *src_sd; /* Source subdev */ + int src_sd_pad; /* Source subdev pad */ - struct media_pad vdev_pad; + struct mutex mutex; /* Protect vdev operations */ - struct mutex mutex; /* capture device mutex */ + struct vb2_queue q; /* The videobuf2 queue */ + struct list_head ready_q; /* List of queued buffers */ + spinlock_t q_lock; /* Protect ready_q */ - /* the videobuf2 queue */ - struct vb2_queue q; - /* list of ready imx_media_buffer's from q */ - struct list_head ready_q; - /* protect ready_q */ - spinlock_t q_lock; + struct v4l2_ctrl_handler ctrl_hdlr; /* Controls inherited from subdevs */ - /* controls inherited from subdevs */ - struct v4l2_ctrl_handler ctrl_hdlr; - - /* misc status */ - bool stop; /* streaming is stopping */ + bool legacy_api; /* Use the legacy (pre-MC) API */ }; #define to_capture_priv(v) container_of(v, struct capture_priv, vdev) @@ -60,28 +54,232 @@ struct capture_priv { /* In bytes, per queue */ #define VID_MEM_LIMIT SZ_64M -static const struct vb2_ops capture_qops; - -/* - * Video ioctls follow +/* ----------------------------------------------------------------------------- + * MC-Centric Video IOCTLs */ -static int vidioc_querycap(struct file *file, void *fh, - struct v4l2_capability *cap) +static const struct imx_media_pixfmt *capture_find_format(u32 code, u32 fourcc) +{ + const struct imx_media_pixfmt *cc; + + cc = imx_media_find_ipu_format(code, PIXFMT_SEL_YUV_RGB); + if (cc) { + enum imx_pixfmt_sel fmt_sel = cc->cs == IPUV3_COLORSPACE_YUV + ? PIXFMT_SEL_YUV : PIXFMT_SEL_RGB; + + cc = imx_media_find_pixel_format(fourcc, fmt_sel); + if (!cc) { + imx_media_enum_pixel_formats(&fourcc, 0, fmt_sel, 0); + cc = imx_media_find_pixel_format(fourcc, fmt_sel); + } + + return cc; + } + + return imx_media_find_mbus_format(code, PIXFMT_SEL_ANY); +} + +static int capture_querycap(struct file *file, void *fh, + struct v4l2_capability *cap) { struct capture_priv *priv = video_drvdata(file); strscpy(cap->driver, IMX_CAPTURE_NAME, sizeof(cap->driver)); strscpy(cap->card, IMX_CAPTURE_NAME, sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), - "platform:%s", priv->src_sd->name); + "platform:%s", dev_name(priv->dev)); return 0; } +static int capture_enum_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_fmtdesc *f) +{ + return imx_media_enum_pixel_formats(&f->pixelformat, f->index, + PIXFMT_SEL_ANY, f->mbus_code); +} + static int capture_enum_framesizes(struct file *file, void *fh, struct v4l2_frmsizeenum *fsize) { + const struct imx_media_pixfmt *cc; + + if (fsize->index > 0) + return -EINVAL; + + cc = imx_media_find_pixel_format(fsize->pixel_format, PIXFMT_SEL_ANY); + if (!cc) + return -EINVAL; + + /* + * TODO: The constraints are hardware-specific and may depend on the + * pixel format. This should come from the driver using + * imx_media_capture. + */ + fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; + fsize->stepwise.min_width = 1; + fsize->stepwise.max_width = 65535; + fsize->stepwise.min_height = 1; + fsize->stepwise.max_height = 65535; + fsize->stepwise.step_width = 1; + fsize->stepwise.step_height = 1; + + return 0; +} + +static int capture_g_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct capture_priv *priv = video_drvdata(file); + + f->fmt.pix = priv->vdev.fmt; + + return 0; +} + +static const struct imx_media_pixfmt * +__capture_try_fmt(struct v4l2_pix_format *pixfmt, struct v4l2_rect *compose) +{ + struct v4l2_mbus_framefmt fmt_src; + const struct imx_media_pixfmt *cc; + + /* + * Find the pixel format, default to the first supported format if not + * found. + */ + cc = imx_media_find_pixel_format(pixfmt->pixelformat, PIXFMT_SEL_ANY); + if (!cc) { + imx_media_enum_pixel_formats(&pixfmt->pixelformat, 0, + PIXFMT_SEL_ANY, 0); + cc = imx_media_find_pixel_format(pixfmt->pixelformat, + PIXFMT_SEL_ANY); + } + + /* Allow IDMAC interweave but enforce field order from source. */ + if (V4L2_FIELD_IS_INTERLACED(pixfmt->field)) { + switch (pixfmt->field) { + case V4L2_FIELD_SEQ_TB: + pixfmt->field = V4L2_FIELD_INTERLACED_TB; + break; + case V4L2_FIELD_SEQ_BT: + pixfmt->field = V4L2_FIELD_INTERLACED_BT; + break; + default: + break; + } + } + + v4l2_fill_mbus_format(&fmt_src, pixfmt, 0); + imx_media_mbus_fmt_to_pix_fmt(pixfmt, &fmt_src, cc); + + if (compose) { + compose->width = fmt_src.width; + compose->height = fmt_src.height; + } + + return cc; +} + +static int capture_try_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_format *f) +{ + __capture_try_fmt(&f->fmt.pix, NULL); + return 0; +} + +static int capture_s_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_format *f) +{ + struct capture_priv *priv = video_drvdata(file); + const struct imx_media_pixfmt *cc; + + if (vb2_is_busy(&priv->q)) { + dev_err(priv->dev, "%s queue busy\n", __func__); + return -EBUSY; + } + + cc = __capture_try_fmt(&f->fmt.pix, &priv->vdev.compose); + + priv->vdev.cc = cc; + priv->vdev.fmt = f->fmt.pix; + + return 0; +} + +static int capture_g_selection(struct file *file, void *fh, + struct v4l2_selection *s) +{ + struct capture_priv *priv = video_drvdata(file); + + switch (s->target) { + case V4L2_SEL_TGT_COMPOSE: + case V4L2_SEL_TGT_COMPOSE_DEFAULT: + case V4L2_SEL_TGT_COMPOSE_BOUNDS: + /* The compose rectangle is fixed to the source format. */ + s->r = priv->vdev.compose; + break; + case V4L2_SEL_TGT_COMPOSE_PADDED: + /* + * The hardware writes with a configurable but fixed DMA burst + * size. If the source format width is not burst size aligned, + * the written frame contains padding to the right. + */ + s->r.left = 0; + s->r.top = 0; + s->r.width = priv->vdev.fmt.width; + s->r.height = priv->vdev.fmt.height; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int capture_subscribe_event(struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub) +{ + switch (sub->type) { + case V4L2_EVENT_IMX_FRAME_INTERVAL_ERROR: + return v4l2_event_subscribe(fh, sub, 0, NULL); + default: + return -EINVAL; + } +} + +static const struct v4l2_ioctl_ops capture_ioctl_ops = { + .vidioc_querycap = capture_querycap, + + .vidioc_enum_fmt_vid_cap = capture_enum_fmt_vid_cap, + .vidioc_enum_framesizes = capture_enum_framesizes, + + .vidioc_g_fmt_vid_cap = capture_g_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = capture_try_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = capture_s_fmt_vid_cap, + + .vidioc_g_selection = capture_g_selection, + + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_create_bufs = vb2_ioctl_create_bufs, + .vidioc_prepare_buf = vb2_ioctl_prepare_buf, + .vidioc_querybuf = vb2_ioctl_querybuf, + .vidioc_qbuf = vb2_ioctl_qbuf, + .vidioc_dqbuf = vb2_ioctl_dqbuf, + .vidioc_expbuf = vb2_ioctl_expbuf, + .vidioc_streamon = vb2_ioctl_streamon, + .vidioc_streamoff = vb2_ioctl_streamoff, + + .vidioc_subscribe_event = capture_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, +}; + +/* ----------------------------------------------------------------------------- + * Legacy Video IOCTLs + */ + +static int capture_legacy_enum_framesizes(struct file *file, void *fh, + struct v4l2_frmsizeenum *fsize) +{ struct capture_priv *priv = video_drvdata(file); const struct imx_media_pixfmt *cc; struct v4l2_subdev_frame_size_enum fse = { @@ -119,8 +317,8 @@ static int capture_enum_framesizes(struct file *file, void *fh, return 0; } -static int capture_enum_frameintervals(struct file *file, void *fh, - struct v4l2_frmivalenum *fival) +static int capture_legacy_enum_frameintervals(struct file *file, void *fh, + struct v4l2_frmivalenum *fival) { struct capture_priv *priv = video_drvdata(file); const struct imx_media_pixfmt *cc; @@ -150,8 +348,8 @@ static int capture_enum_frameintervals(struct file *file, void *fh, return 0; } -static int capture_enum_fmt_vid_cap(struct file *file, void *fh, - struct v4l2_fmtdesc *f) +static int capture_legacy_enum_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_fmtdesc *f) { struct capture_priv *priv = video_drvdata(file); const struct imx_media_pixfmt *cc_src; @@ -163,7 +361,7 @@ static int capture_enum_fmt_vid_cap(struct file *file, void *fh, fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE; ret = v4l2_subdev_call(priv->src_sd, pad, get_fmt, NULL, &fmt_src); if (ret) { - v4l2_err(priv->src_sd, "failed to get src_sd format\n"); + dev_err(priv->dev, "failed to get src_sd format\n"); return ret; } @@ -174,7 +372,8 @@ static int capture_enum_fmt_vid_cap(struct file *file, void *fh, (cc_src->cs == IPUV3_COLORSPACE_YUV) ? PIXFMT_SEL_YUV : PIXFMT_SEL_RGB; - ret = imx_media_enum_pixel_formats(&fourcc, f->index, fmt_sel); + ret = imx_media_enum_pixel_formats(&fourcc, f->index, fmt_sel, + 0); if (ret) return ret; } else { @@ -193,50 +392,19 @@ static int capture_enum_fmt_vid_cap(struct file *file, void *fh, return 0; } -static int capture_g_fmt_vid_cap(struct file *file, void *fh, - struct v4l2_format *f) -{ - struct capture_priv *priv = video_drvdata(file); - - *f = priv->vdev.fmt; - - return 0; -} - -static int __capture_try_fmt_vid_cap(struct capture_priv *priv, - struct v4l2_subdev_format *fmt_src, - struct v4l2_format *f, - const struct imx_media_pixfmt **retcc, - struct v4l2_rect *compose) +static const struct imx_media_pixfmt * +__capture_legacy_try_fmt(struct capture_priv *priv, + struct v4l2_subdev_format *fmt_src, + struct v4l2_pix_format *pixfmt) { - const struct imx_media_pixfmt *cc, *cc_src; - - cc_src = imx_media_find_ipu_format(fmt_src->format.code, - PIXFMT_SEL_YUV_RGB); - if (cc_src) { - enum imx_pixfmt_sel fmt_sel; - u32 fourcc; - - fmt_sel = (cc_src->cs == IPUV3_COLORSPACE_YUV) ? - PIXFMT_SEL_YUV : PIXFMT_SEL_RGB; - fourcc = f->fmt.pix.pixelformat; - - cc = imx_media_find_pixel_format(fourcc, fmt_sel); - if (!cc) { - imx_media_enum_pixel_formats(&fourcc, 0, fmt_sel); - cc = imx_media_find_pixel_format(fourcc, fmt_sel); - } - } else { - cc_src = imx_media_find_mbus_format(fmt_src->format.code, - PIXFMT_SEL_ANY); - if (WARN_ON(!cc_src)) - return -EINVAL; + const struct imx_media_pixfmt *cc; - cc = cc_src; - } + cc = capture_find_format(fmt_src->format.code, pixfmt->pixelformat); + if (WARN_ON(!cc)) + return NULL; /* allow IDMAC interweave but enforce field order from source */ - if (V4L2_FIELD_IS_INTERLACED(f->fmt.pix.field)) { + if (V4L2_FIELD_IS_INTERLACED(pixfmt->field)) { switch (fmt_src->format.field) { case V4L2_FIELD_SEQ_TB: fmt_src->format.field = V4L2_FIELD_INTERLACED_TB; @@ -249,23 +417,13 @@ static int __capture_try_fmt_vid_cap(struct capture_priv *priv, } } - imx_media_mbus_fmt_to_pix_fmt(&f->fmt.pix, &fmt_src->format, cc); - - if (retcc) - *retcc = cc; + imx_media_mbus_fmt_to_pix_fmt(pixfmt, &fmt_src->format, cc); - if (compose) { - compose->left = 0; - compose->top = 0; - compose->width = fmt_src->format.width; - compose->height = fmt_src->format.height; - } - - return 0; + return cc; } -static int capture_try_fmt_vid_cap(struct file *file, void *fh, - struct v4l2_format *f) +static int capture_legacy_try_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_format *f) { struct capture_priv *priv = video_drvdata(file); struct v4l2_subdev_format fmt_src; @@ -277,18 +435,22 @@ static int capture_try_fmt_vid_cap(struct file *file, void *fh, if (ret) return ret; - return __capture_try_fmt_vid_cap(priv, &fmt_src, f, NULL, NULL); + if (!__capture_legacy_try_fmt(priv, &fmt_src, &f->fmt.pix)) + return -EINVAL; + + return 0; } -static int capture_s_fmt_vid_cap(struct file *file, void *fh, - struct v4l2_format *f) +static int capture_legacy_s_fmt_vid_cap(struct file *file, void *fh, + struct v4l2_format *f) { struct capture_priv *priv = video_drvdata(file); struct v4l2_subdev_format fmt_src; + const struct imx_media_pixfmt *cc; int ret; if (vb2_is_busy(&priv->q)) { - v4l2_err(priv->src_sd, "%s queue busy\n", __func__); + dev_err(priv->dev, "%s queue busy\n", __func__); return -EBUSY; } @@ -298,31 +460,34 @@ static int capture_s_fmt_vid_cap(struct file *file, void *fh, if (ret) return ret; - ret = __capture_try_fmt_vid_cap(priv, &fmt_src, f, &priv->vdev.cc, - &priv->vdev.compose); - if (ret) - return ret; + cc = __capture_legacy_try_fmt(priv, &fmt_src, &f->fmt.pix); + if (!cc) + return -EINVAL; - priv->vdev.fmt.fmt.pix = f->fmt.pix; + priv->vdev.cc = cc; + priv->vdev.fmt = f->fmt.pix; + priv->vdev.compose.width = fmt_src.format.width; + priv->vdev.compose.height = fmt_src.format.height; return 0; } -static int capture_querystd(struct file *file, void *fh, v4l2_std_id *std) +static int capture_legacy_querystd(struct file *file, void *fh, + v4l2_std_id *std) { struct capture_priv *priv = video_drvdata(file); return v4l2_subdev_call(priv->src_sd, video, querystd, std); } -static int capture_g_std(struct file *file, void *fh, v4l2_std_id *std) +static int capture_legacy_g_std(struct file *file, void *fh, v4l2_std_id *std) { struct capture_priv *priv = video_drvdata(file); return v4l2_subdev_call(priv->src_sd, video, g_std, std); } -static int capture_s_std(struct file *file, void *fh, v4l2_std_id std) +static int capture_legacy_s_std(struct file *file, void *fh, v4l2_std_id std) { struct capture_priv *priv = video_drvdata(file); @@ -332,38 +497,8 @@ static int capture_s_std(struct file *file, void *fh, v4l2_std_id std) return v4l2_subdev_call(priv->src_sd, video, s_std, std); } -static int capture_g_selection(struct file *file, void *fh, - struct v4l2_selection *s) -{ - struct capture_priv *priv = video_drvdata(file); - - switch (s->target) { - case V4L2_SEL_TGT_COMPOSE: - case V4L2_SEL_TGT_COMPOSE_DEFAULT: - case V4L2_SEL_TGT_COMPOSE_BOUNDS: - /* The compose rectangle is fixed to the source format. */ - s->r = priv->vdev.compose; - break; - case V4L2_SEL_TGT_COMPOSE_PADDED: - /* - * The hardware writes with a configurable but fixed DMA burst - * size. If the source format width is not burst size aligned, - * the written frame contains padding to the right. - */ - s->r.left = 0; - s->r.top = 0; - s->r.width = priv->vdev.fmt.fmt.pix.width; - s->r.height = priv->vdev.fmt.fmt.pix.height; - break; - default: - return -EINVAL; - } - - return 0; -} - -static int capture_g_parm(struct file *file, void *fh, - struct v4l2_streamparm *a) +static int capture_legacy_g_parm(struct file *file, void *fh, + struct v4l2_streamparm *a) { struct capture_priv *priv = video_drvdata(file); struct v4l2_subdev_frame_interval fi; @@ -384,8 +519,8 @@ static int capture_g_parm(struct file *file, void *fh, return 0; } -static int capture_s_parm(struct file *file, void *fh, - struct v4l2_streamparm *a) +static int capture_legacy_s_parm(struct file *file, void *fh, + struct v4l2_streamparm *a) { struct capture_priv *priv = video_drvdata(file); struct v4l2_subdev_frame_interval fi; @@ -407,8 +542,8 @@ static int capture_s_parm(struct file *file, void *fh, return 0; } -static int capture_subscribe_event(struct v4l2_fh *fh, - const struct v4l2_event_subscription *sub) +static int capture_legacy_subscribe_event(struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub) { switch (sub->type) { case V4L2_EVENT_IMX_FRAME_INTERVAL_ERROR: @@ -422,42 +557,42 @@ static int capture_subscribe_event(struct v4l2_fh *fh, } } -static const struct v4l2_ioctl_ops capture_ioctl_ops = { - .vidioc_querycap = vidioc_querycap, +static const struct v4l2_ioctl_ops capture_legacy_ioctl_ops = { + .vidioc_querycap = capture_querycap, - .vidioc_enum_framesizes = capture_enum_framesizes, - .vidioc_enum_frameintervals = capture_enum_frameintervals, + .vidioc_enum_framesizes = capture_legacy_enum_framesizes, + .vidioc_enum_frameintervals = capture_legacy_enum_frameintervals, - .vidioc_enum_fmt_vid_cap = capture_enum_fmt_vid_cap, - .vidioc_g_fmt_vid_cap = capture_g_fmt_vid_cap, - .vidioc_try_fmt_vid_cap = capture_try_fmt_vid_cap, - .vidioc_s_fmt_vid_cap = capture_s_fmt_vid_cap, + .vidioc_enum_fmt_vid_cap = capture_legacy_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = capture_g_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = capture_legacy_try_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = capture_legacy_s_fmt_vid_cap, - .vidioc_querystd = capture_querystd, - .vidioc_g_std = capture_g_std, - .vidioc_s_std = capture_s_std, + .vidioc_querystd = capture_legacy_querystd, + .vidioc_g_std = capture_legacy_g_std, + .vidioc_s_std = capture_legacy_s_std, - .vidioc_g_selection = capture_g_selection, + .vidioc_g_selection = capture_g_selection, - .vidioc_g_parm = capture_g_parm, - .vidioc_s_parm = capture_s_parm, + .vidioc_g_parm = capture_legacy_g_parm, + .vidioc_s_parm = capture_legacy_s_parm, - .vidioc_reqbufs = vb2_ioctl_reqbufs, - .vidioc_create_bufs = vb2_ioctl_create_bufs, - .vidioc_prepare_buf = vb2_ioctl_prepare_buf, - .vidioc_querybuf = vb2_ioctl_querybuf, - .vidioc_qbuf = vb2_ioctl_qbuf, - .vidioc_dqbuf = vb2_ioctl_dqbuf, - .vidioc_expbuf = vb2_ioctl_expbuf, - .vidioc_streamon = vb2_ioctl_streamon, - .vidioc_streamoff = vb2_ioctl_streamoff, + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_create_bufs = vb2_ioctl_create_bufs, + .vidioc_prepare_buf = vb2_ioctl_prepare_buf, + .vidioc_querybuf = vb2_ioctl_querybuf, + .vidioc_qbuf = vb2_ioctl_qbuf, + .vidioc_dqbuf = vb2_ioctl_dqbuf, + .vidioc_expbuf = vb2_ioctl_expbuf, + .vidioc_streamon = vb2_ioctl_streamon, + .vidioc_streamoff = vb2_ioctl_streamoff, - .vidioc_subscribe_event = capture_subscribe_event, - .vidioc_unsubscribe_event = v4l2_event_unsubscribe, + .vidioc_subscribe_event = capture_legacy_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; -/* - * Queue operations +/* ----------------------------------------------------------------------------- + * Queue Operations */ static int capture_queue_setup(struct vb2_queue *vq, @@ -467,7 +602,7 @@ static int capture_queue_setup(struct vb2_queue *vq, struct device *alloc_devs[]) { struct capture_priv *priv = vb2_get_drv_priv(vq); - struct v4l2_pix_format *pix = &priv->vdev.fmt.fmt.pix; + struct v4l2_pix_format *pix = &priv->vdev.fmt; unsigned int count = *nbuffers; if (vq->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) @@ -506,12 +641,12 @@ static int capture_buf_prepare(struct vb2_buffer *vb) { struct vb2_queue *vq = vb->vb2_queue; struct capture_priv *priv = vb2_get_drv_priv(vq); - struct v4l2_pix_format *pix = &priv->vdev.fmt.fmt.pix; + struct v4l2_pix_format *pix = &priv->vdev.fmt; if (vb2_plane_size(vb, 0) < pix->sizeimage) { - v4l2_err(priv->src_sd, - "data will not fit into plane (%lu < %lu)\n", - vb2_plane_size(vb, 0), (long)pix->sizeimage); + dev_err(priv->dev, + "data will not fit into plane (%lu < %lu)\n", + vb2_plane_size(vb, 0), (long)pix->sizeimage); return -EINVAL; } @@ -537,27 +672,35 @@ static int capture_validate_fmt(struct capture_priv *priv) { struct v4l2_subdev_format fmt_src; const struct imx_media_pixfmt *cc; - struct v4l2_rect compose; - struct v4l2_format f; int ret; + /* Retrieve the media bus format on the source subdev. */ fmt_src.pad = priv->src_sd_pad; fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE; ret = v4l2_subdev_call(priv->src_sd, pad, get_fmt, NULL, &fmt_src); if (ret) return ret; - v4l2_fill_pix_format(&f.fmt.pix, &fmt_src.format); + /* + * Verify that the media bus size matches the size set on the video + * node. It is sufficient to check the compose rectangle size without + * checking the rounded size from vdev.fmt, as the rounded size is + * derived directly from the compose rectangle size, and will thus + * always match if the compose rectangle matches. + */ + if (priv->vdev.compose.width != fmt_src.format.width || + priv->vdev.compose.height != fmt_src.format.height) + return -EPIPE; + + /* + * Verify that the media bus code is compatible with the pixel format + * set on the video node. + */ + cc = capture_find_format(fmt_src.format.code, 0); + if (!cc || priv->vdev.cc->cs != cc->cs) + return -EPIPE; - ret = __capture_try_fmt_vid_cap(priv, &fmt_src, &f, &cc, &compose); - if (ret) - return ret; - - return (priv->vdev.fmt.fmt.pix.width != f.fmt.pix.width || - priv->vdev.fmt.fmt.pix.height != f.fmt.pix.height || - priv->vdev.cc->cs != cc->cs || - priv->vdev.compose.width != compose.width || - priv->vdev.compose.height != compose.height) ? -EINVAL : 0; + return 0; } static int capture_start_streaming(struct vb2_queue *vq, unsigned int count) @@ -569,19 +712,17 @@ static int capture_start_streaming(struct vb2_queue *vq, unsigned int count) ret = capture_validate_fmt(priv); if (ret) { - v4l2_err(priv->src_sd, "capture format not valid\n"); + dev_err(priv->dev, "capture format not valid\n"); goto return_bufs; } ret = imx_media_pipeline_set_stream(priv->md, &priv->src_sd->entity, true); if (ret) { - v4l2_err(priv->src_sd, "pipeline start failed with %d\n", ret); + dev_err(priv->dev, "pipeline start failed with %d\n", ret); goto return_bufs; } - priv->stop = false; - return 0; return_bufs: @@ -602,14 +743,10 @@ static void capture_stop_streaming(struct vb2_queue *vq) unsigned long flags; int ret; - spin_lock_irqsave(&priv->q_lock, flags); - priv->stop = true; - spin_unlock_irqrestore(&priv->q_lock, flags); - ret = imx_media_pipeline_set_stream(priv->md, &priv->src_sd->entity, false); if (ret) - v4l2_warn(priv->src_sd, "pipeline stop failed with %d\n", ret); + dev_warn(priv->dev, "pipeline stop failed with %d\n", ret); /* release all active buffers */ spin_lock_irqsave(&priv->q_lock, flags); @@ -631,9 +768,10 @@ static const struct vb2_ops capture_qops = { .stop_streaming = capture_stop_streaming, }; -/* - * File operations +/* ----------------------------------------------------------------------------- + * File Operations */ + static int capture_open(struct file *file) { struct capture_priv *priv = video_drvdata(file); @@ -644,13 +782,16 @@ static int capture_open(struct file *file) return -ERESTARTSYS; ret = v4l2_fh_open(file); - if (ret) - v4l2_err(priv->src_sd, "v4l2_fh_open failed\n"); + if (ret) { + dev_err(priv->dev, "v4l2_fh_open failed\n"); + goto out; + } ret = v4l2_pipeline_pm_get(&vfd->entity); if (ret) v4l2_fh_release(file); +out: mutex_unlock(&priv->mutex); return ret; } @@ -684,15 +825,9 @@ static const struct v4l2_file_operations capture_fops = { .mmap = vb2_fop_mmap, }; -static struct video_device capture_videodev = { - .fops = &capture_fops, - .ioctl_ops = &capture_ioctl_ops, - .minor = -1, - .release = video_device_release, - .vfl_dir = VFL_DIR_RX, - .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM, - .device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING, -}; +/* ----------------------------------------------------------------------------- + * Public API + */ struct imx_media_buffer * imx_media_capture_device_next_buf(struct imx_media_video_dev *vdev) @@ -731,14 +866,45 @@ void imx_media_capture_device_error(struct imx_media_video_dev *vdev) } EXPORT_SYMBOL_GPL(imx_media_capture_device_error); -int imx_media_capture_device_register(struct imx_media_video_dev *vdev) +static int capture_init_format(struct capture_priv *priv) +{ + struct v4l2_subdev_format fmt_src = { + .pad = priv->src_sd_pad, + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + struct imx_media_video_dev *vdev = &priv->vdev; + int ret; + + if (priv->legacy_api) { + ret = v4l2_subdev_call(priv->src_sd, pad, get_fmt, NULL, + &fmt_src); + if (ret) { + dev_err(priv->dev, "failed to get source format\n"); + return ret; + } + } else { + fmt_src.format.code = MEDIA_BUS_FMT_UYVY8_2X8; + fmt_src.format.width = IMX_MEDIA_DEF_PIX_WIDTH; + fmt_src.format.height = IMX_MEDIA_DEF_PIX_HEIGHT; + } + + imx_media_mbus_fmt_to_pix_fmt(&vdev->fmt, &fmt_src.format, NULL); + vdev->compose.width = fmt_src.format.width; + vdev->compose.height = fmt_src.format.height; + + vdev->cc = imx_media_find_pixel_format(vdev->fmt.pixelformat, + PIXFMT_SEL_ANY); + + return 0; +} + +int imx_media_capture_device_register(struct imx_media_video_dev *vdev, + u32 link_flags) { struct capture_priv *priv = to_capture_priv(vdev); struct v4l2_subdev *sd = priv->src_sd; struct v4l2_device *v4l2_dev = sd->v4l2_dev; struct video_device *vfd = vdev->vfd; - struct vb2_queue *vq = &priv->q; - struct v4l2_subdev_format fmt_src; int ret; /* get media device */ @@ -746,68 +912,36 @@ int imx_media_capture_device_register(struct imx_media_video_dev *vdev) vfd->v4l2_dev = v4l2_dev; - ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1); - if (ret) { - v4l2_err(sd, "Failed to register video device\n"); + /* Initialize the default format and compose rectangle. */ + ret = capture_init_format(priv); + if (ret < 0) return ret; - } - vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - vq->io_modes = VB2_MMAP | VB2_DMABUF; - vq->drv_priv = priv; - vq->buf_struct_size = sizeof(struct imx_media_buffer); - vq->ops = &capture_qops; - vq->mem_ops = &vb2_dma_contig_memops; - vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; - vq->lock = &priv->mutex; - vq->min_buffers_needed = 2; - vq->dev = priv->dev; - - ret = vb2_queue_init(vq); + /* Register the video device. */ + ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1); if (ret) { - v4l2_err(sd, "vb2_queue_init failed\n"); - goto unreg; + dev_err(priv->dev, "Failed to register video device\n"); + return ret; } - INIT_LIST_HEAD(&priv->ready_q); + dev_info(priv->dev, "Registered %s as /dev/%s\n", vfd->name, + video_device_node_name(vfd)); - /* create the link from the src_sd devnode pad to device node */ + /* Create the link from the src_sd devnode pad to device node. */ + if (link_flags & MEDIA_LNK_FL_IMMUTABLE) + link_flags |= MEDIA_LNK_FL_ENABLED; ret = media_create_pad_link(&sd->entity, priv->src_sd_pad, - &vfd->entity, 0, 0); + &vfd->entity, 0, link_flags); if (ret) { - v4l2_err(sd, "failed to create link to device node\n"); - goto unreg; - } - - /* setup default format */ - fmt_src.pad = priv->src_sd_pad; - fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE; - ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt_src); - if (ret) { - v4l2_err(sd, "failed to get src_sd format\n"); - goto unreg; + dev_err(priv->dev, "failed to create link to device node\n"); + video_unregister_device(vfd); + return ret; } - vdev->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - imx_media_mbus_fmt_to_pix_fmt(&vdev->fmt.fmt.pix, - &fmt_src.format, NULL); - vdev->compose.width = fmt_src.format.width; - vdev->compose.height = fmt_src.format.height; - vdev->cc = imx_media_find_pixel_format(vdev->fmt.fmt.pix.pixelformat, - PIXFMT_SEL_ANY); - - v4l2_info(sd, "Registered %s as /dev/%s\n", vfd->name, - video_device_node_name(vfd)); - - vfd->ctrl_handler = &priv->ctrl_hdlr; - - /* add vdev to the video device list */ + /* Add vdev to the video devices list. */ imx_media_add_video_device(priv->md, vdev); return 0; -unreg: - video_unregister_device(vfd); - return ret; } EXPORT_SYMBOL_GPL(imx_media_capture_device_register); @@ -823,10 +957,11 @@ EXPORT_SYMBOL_GPL(imx_media_capture_device_unregister); struct imx_media_video_dev * imx_media_capture_device_init(struct device *dev, struct v4l2_subdev *src_sd, - int pad) + int pad, bool legacy_api) { struct capture_priv *priv; struct video_device *vfd; + struct vb2_queue *vq; int ret; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); @@ -836,22 +971,36 @@ imx_media_capture_device_init(struct device *dev, struct v4l2_subdev *src_sd, priv->src_sd = src_sd; priv->src_sd_pad = pad; priv->dev = dev; + priv->legacy_api = legacy_api; mutex_init(&priv->mutex); + INIT_LIST_HEAD(&priv->ready_q); spin_lock_init(&priv->q_lock); - snprintf(capture_videodev.name, sizeof(capture_videodev.name), - "%s capture", src_sd->name); - + /* Allocate and initialize the video device. */ vfd = video_device_alloc(); if (!vfd) return ERR_PTR(-ENOMEM); - *vfd = capture_videodev; + vfd->fops = &capture_fops; + vfd->ioctl_ops = legacy_api ? &capture_legacy_ioctl_ops + : &capture_ioctl_ops; + vfd->minor = -1; + vfd->release = video_device_release; + vfd->vfl_dir = VFL_DIR_RX; + vfd->tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM; + vfd->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING + | (!legacy_api ? V4L2_CAP_IO_MC : 0); vfd->lock = &priv->mutex; vfd->queue = &priv->q; + + snprintf(vfd->name, sizeof(vfd->name), "%s capture", src_sd->name); + + video_set_drvdata(vfd, priv); priv->vdev.vfd = vfd; + INIT_LIST_HEAD(&priv->vdev.list); + /* Initialize the video device pad. */ priv->vdev_pad.flags = MEDIA_PAD_FL_SINK; ret = media_entity_pads_init(&vfd->entity, 1, &priv->vdev_pad); if (ret) { @@ -859,11 +1008,31 @@ imx_media_capture_device_init(struct device *dev, struct v4l2_subdev *src_sd, return ERR_PTR(ret); } - INIT_LIST_HEAD(&priv->vdev.list); + /* Initialize the vb2 queue. */ + vq = &priv->q; + vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vq->io_modes = VB2_MMAP | VB2_DMABUF; + vq->drv_priv = priv; + vq->buf_struct_size = sizeof(struct imx_media_buffer); + vq->ops = &capture_qops; + vq->mem_ops = &vb2_dma_contig_memops; + vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + vq->lock = &priv->mutex; + vq->min_buffers_needed = 2; + vq->dev = priv->dev; - video_set_drvdata(vfd, priv); + ret = vb2_queue_init(vq); + if (ret) { + dev_err(priv->dev, "vb2_queue_init failed\n"); + video_device_release(vfd); + return ERR_PTR(ret); + } - v4l2_ctrl_handler_init(&priv->ctrl_hdlr, 0); + if (legacy_api) { + /* Initialize the control handler. */ + v4l2_ctrl_handler_init(&priv->ctrl_hdlr, 0); + vfd->ctrl_handler = &priv->ctrl_hdlr; + } return &priv->vdev; } diff --git a/drivers/staging/media/imx/imx-media-csc-scaler.c b/drivers/staging/media/imx/imx-media-csc-scaler.c index 63a0204502a8..eb6da9b9d8ba 100644 --- a/drivers/staging/media/imx/imx-media-csc-scaler.c +++ b/drivers/staging/media/imx/imx-media-csc-scaler.c @@ -167,7 +167,7 @@ static int ipu_csc_scaler_enum_fmt(struct file *file, void *fh, int ret; ret = imx_media_enum_pixel_formats(&fourcc, f->index, - PIXFMT_SEL_YUV_RGB); + PIXFMT_SEL_YUV_RGB, 0); if (ret) return ret; diff --git a/drivers/staging/media/imx/imx-media-csi.c b/drivers/staging/media/imx/imx-media-csi.c index ef5add079774..e3bfd635a89a 100644 --- a/drivers/staging/media/imx/imx-media-csi.c +++ b/drivers/staging/media/imx/imx-media-csi.c @@ -267,7 +267,7 @@ static void csi_vb2_buf_done(struct csi_priv *priv) done = priv->active_vb2_buf[priv->ipu_buf_num]; if (done) { - done->vbuf.field = vdev->fmt.fmt.pix.field; + done->vbuf.field = vdev->fmt.field; done->vbuf.sequence = priv->frame_sequence; vb = &done->vbuf.vb2_buf; vb->timestamp = ktime_get_ns(); @@ -292,7 +292,7 @@ static void csi_vb2_buf_done(struct csi_priv *priv) ipu_idmac_clear_buffer(priv->idmac_ch, priv->ipu_buf_num); if (priv->interweave_swap) - phys += vdev->fmt.fmt.pix.bytesperline; + phys += vdev->fmt.bytesperline; ipu_cpmem_set_buffer(priv->idmac_ch, priv->ipu_buf_num, phys); } @@ -422,7 +422,7 @@ static int csi_idmac_setup_channel(struct csi_priv *priv) ipu_cpmem_zero(priv->idmac_ch); memset(&image, 0, sizeof(image)); - image.pix = vdev->fmt.fmt.pix; + image.pix = vdev->fmt; image.rect = vdev->compose; csi_idmac_setup_vb2_buf(priv, phys); @@ -596,7 +596,6 @@ static int csi_idmac_setup(struct csi_priv *priv) static int csi_idmac_start(struct csi_priv *priv) { struct imx_media_video_dev *vdev = priv->vdev; - struct v4l2_pix_format *outfmt; int ret; ret = csi_idmac_get_ipu_resources(priv); @@ -605,10 +604,8 @@ static int csi_idmac_start(struct csi_priv *priv) ipu_smfc_map_channel(priv->smfc, priv->csi_id, priv->vc_num); - outfmt = &vdev->fmt.fmt.pix; - ret = imx_media_alloc_dma_buf(priv->dev, &priv->underrun_buf, - outfmt->sizeimage); + vdev->fmt.sizeimage); if (ret) goto out_put_ipu; @@ -1758,8 +1755,9 @@ static int csi_registered(struct v4l2_subdev *sd) /* set a default mbus format */ ret = imx_media_init_mbus_fmt(&priv->format_mbus[i], - 640, 480, code, V4L2_FIELD_NONE, - &priv->cc[i]); + IMX_MEDIA_DEF_PIX_WIDTH, + IMX_MEDIA_DEF_PIX_HEIGHT, code, + V4L2_FIELD_NONE, &priv->cc[i]); if (ret) goto put_csi; @@ -1772,10 +1770,10 @@ static int csi_registered(struct v4l2_subdev *sd) priv->skip = &csi_skip[0]; /* init default crop and compose rectangle sizes */ - priv->crop.width = 640; - priv->crop.height = 480; - priv->compose.width = 640; - priv->compose.height = 480; + priv->crop.width = IMX_MEDIA_DEF_PIX_WIDTH; + priv->crop.height = IMX_MEDIA_DEF_PIX_HEIGHT; + priv->compose.width = IMX_MEDIA_DEF_PIX_WIDTH; + priv->compose.height = IMX_MEDIA_DEF_PIX_HEIGHT; priv->fim = imx_media_fim_init(&priv->sd); if (IS_ERR(priv->fim)) { @@ -1783,15 +1781,14 @@ static int csi_registered(struct v4l2_subdev *sd) goto put_csi; } - priv->vdev = imx_media_capture_device_init(priv->sd.dev, - &priv->sd, - CSI_SRC_PAD_IDMAC); + priv->vdev = imx_media_capture_device_init(priv->sd.dev, &priv->sd, + CSI_SRC_PAD_IDMAC, true); if (IS_ERR(priv->vdev)) { ret = PTR_ERR(priv->vdev); goto free_fim; } - ret = imx_media_capture_device_register(priv->vdev); + ret = imx_media_capture_device_register(priv->vdev, 0); if (ret) goto remove_vdev; @@ -1897,7 +1894,7 @@ static int imx_csi_notify_bound(struct v4l2_async_notifier *notifier, if (sd->entity.function == MEDIA_ENT_F_VID_MUX) sd->grp_id = IMX_MEDIA_GRP_ID_CSI_MUX; - return v4l2_create_fwnode_links_to_pad(sd, sink); + return v4l2_create_fwnode_links_to_pad(sd, sink, 0); } static const struct v4l2_async_notifier_operations csi_notify_ops = { diff --git a/drivers/staging/media/imx/imx-media-dev-common.c b/drivers/staging/media/imx/imx-media-dev-common.c index 5fe4b22ab847..d186179388d0 100644 --- a/drivers/staging/media/imx/imx-media-dev-common.c +++ b/drivers/staging/media/imx/imx-media-dev-common.c @@ -287,6 +287,8 @@ static int imx_media_link_notify(struct media_link *link, u32 flags, !(flags & MEDIA_LNK_FL_ENABLED)) { list_for_each_entry(pad_vdev, pad_vdev_list, list) { vfd = pad_vdev->vdev->vfd; + if (!vfd->ctrl_handler) + continue; dev_dbg(imxmd->md.dev, "reset controls for %s\n", vfd->entity.name); @@ -297,6 +299,8 @@ static int imx_media_link_notify(struct media_link *link, u32 flags, (link->flags & MEDIA_LNK_FL_ENABLED)) { list_for_each_entry(pad_vdev, pad_vdev_list, list) { vfd = pad_vdev->vdev->vfd; + if (!vfd->ctrl_handler) + continue; dev_dbg(imxmd->md.dev, "refresh controls for %s\n", vfd->entity.name); diff --git a/drivers/staging/media/imx/imx-media-utils.c b/drivers/staging/media/imx/imx-media-utils.c index c2088f7ceef5..5128915a5d6f 100644 --- a/drivers/staging/media/imx/imx-media-utils.c +++ b/drivers/staging/media/imx/imx-media-utils.c @@ -283,9 +283,11 @@ EXPORT_SYMBOL_GPL(imx_media_find_mbus_format); * @index: The requested match index. * @fmt_sel: Include in the enumeration entries with the given selection * criteria. + * @code: If non-zero, only include in the enumeration entries matching this + * media bus code. */ int imx_media_enum_pixel_formats(u32 *fourcc, u32 index, - enum imx_pixfmt_sel fmt_sel) + enum imx_pixfmt_sel fmt_sel, u32 code) { bool sel_ipu = fmt_sel & PIXFMT_SEL_IPU; unsigned int i; @@ -306,6 +308,25 @@ int imx_media_enum_pixel_formats(u32 *fourcc, u32 index, if (!(fmt_sel & sel)) continue; + /* + * If a media bus code is specified, only consider formats that + * match it. + */ + if (code) { + unsigned int j; + + if (!fmt->codes) + continue; + + for (j = 0; fmt->codes[j]; j++) { + if (code == fmt->codes[j]) + break; + } + + if (!fmt->codes[j]) + continue; + } + if (index == 0) { *fourcc = fmt->fourcc; return 0; diff --git a/drivers/staging/media/imx/imx-media-vdic.c b/drivers/staging/media/imx/imx-media-vdic.c index 879329f81f79..abf290bda98d 100644 --- a/drivers/staging/media/imx/imx-media-vdic.c +++ b/drivers/staging/media/imx/imx-media-vdic.c @@ -246,7 +246,7 @@ static int setup_vdi_channel(struct vdic_priv *priv, ipu_cpmem_zero(channel); memset(&image, 0, sizeof(image)); - image.pix = vdev->fmt.fmt.pix; + image.pix = vdev->fmt; image.rect = vdev->compose; /* one field to VDIC channels */ image.pix.height /= 2; @@ -856,8 +856,9 @@ static int vdic_registered(struct v4l2_subdev *sd) /* set a default mbus format */ ret = imx_media_init_mbus_fmt(&priv->format_mbus[i], - 640, 480, code, V4L2_FIELD_NONE, - &priv->cc[i]); + IMX_MEDIA_DEF_PIX_WIDTH, + IMX_MEDIA_DEF_PIX_HEIGHT, code, + V4L2_FIELD_NONE, &priv->cc[i]); if (ret) return ret; diff --git a/drivers/staging/media/imx/imx-media.h b/drivers/staging/media/imx/imx-media.h index c8b6a43d0d7c..492d9a64e704 100644 --- a/drivers/staging/media/imx/imx-media.h +++ b/drivers/staging/media/imx/imx-media.h @@ -15,6 +15,9 @@ #include <media/videobuf2-dma-contig.h> #include <video/imx-ipu-v3.h> +#define IMX_MEDIA_DEF_PIX_WIDTH 640 +#define IMX_MEDIA_DEF_PIX_HEIGHT 480 + /* * Enumeration of the IPU internal sub-devices */ @@ -102,7 +105,7 @@ struct imx_media_video_dev { struct video_device *vfd; /* the user format */ - struct v4l2_format fmt; + struct v4l2_pix_format fmt; /* the compose rectangle */ struct v4l2_rect compose; const struct imx_media_pixfmt *cc; @@ -167,7 +170,7 @@ struct imx_media_dev { const struct imx_media_pixfmt * imx_media_find_pixel_format(u32 fourcc, enum imx_pixfmt_sel sel); int imx_media_enum_pixel_formats(u32 *fourcc, u32 index, - enum imx_pixfmt_sel sel); + enum imx_pixfmt_sel sel, u32 code); const struct imx_media_pixfmt * imx_media_find_mbus_format(u32 code, enum imx_pixfmt_sel sel); int imx_media_enum_mbus_formats(u32 *code, u32 index, @@ -283,9 +286,10 @@ int imx_media_ic_unregister(struct v4l2_subdev *sd); /* imx-media-capture.c */ struct imx_media_video_dev * imx_media_capture_device_init(struct device *dev, struct v4l2_subdev *src_sd, - int pad); + int pad, bool legacy_api); void imx_media_capture_device_remove(struct imx_media_video_dev *vdev); -int imx_media_capture_device_register(struct imx_media_video_dev *vdev); +int imx_media_capture_device_register(struct imx_media_video_dev *vdev, + u32 link_flags); void imx_media_capture_device_unregister(struct imx_media_video_dev *vdev); struct imx_media_buffer * imx_media_capture_device_next_buf(struct imx_media_video_dev *vdev); diff --git a/drivers/staging/media/imx/imx6-mipi-csi2.c b/drivers/staging/media/imx/imx6-mipi-csi2.c index 4f8fcc91aaae..fc2378ac04b7 100644 --- a/drivers/staging/media/imx/imx6-mipi-csi2.c +++ b/drivers/staging/media/imx/imx6-mipi-csi2.c @@ -571,7 +571,9 @@ static int csi2_registered(struct v4l2_subdev *sd) /* set a default mbus format */ return imx_media_init_mbus_fmt(&csi2->format_mbus, - 640, 480, 0, V4L2_FIELD_NONE, NULL); + IMX_MEDIA_DEF_PIX_WIDTH, + IMX_MEDIA_DEF_PIX_HEIGHT, 0, + V4L2_FIELD_NONE, NULL); } static const struct media_entity_operations csi2_entity_ops = { @@ -619,7 +621,7 @@ static int csi2_notify_bound(struct v4l2_async_notifier *notifier, dev_dbg(csi2->dev, "Bound %s pad: %d\n", sd->name, pad); - return v4l2_create_fwnode_links_to_pad(sd, sink); + return v4l2_create_fwnode_links_to_pad(sd, sink, 0); } static void csi2_notify_unbind(struct v4l2_async_notifier *notifier, diff --git a/drivers/staging/media/imx/imx7-media-csi.c b/drivers/staging/media/imx/imx7-media-csi.c index 3046f880c014..f85a2f5f1413 100644 --- a/drivers/staging/media/imx/imx7-media-csi.c +++ b/drivers/staging/media/imx/imx7-media-csi.c @@ -18,7 +18,6 @@ #include <linux/regmap.h> #include <linux/types.h> -#include <media/v4l2-ctrls.h> #include <media/v4l2-device.h> #include <media/v4l2-event.h> #include <media/v4l2-fwnode.h> @@ -29,84 +28,88 @@ #include <media/imx.h> #include "imx-media.h" -#define IMX7_CSI_PAD_SINK 0 -#define IMX7_CSI_PAD_SRC 1 -#define IMX7_CSI_PADS_NUM 2 - -/* reset values */ -#define CSICR1_RESET_VAL 0x40000800 -#define CSICR2_RESET_VAL 0x0 -#define CSICR3_RESET_VAL 0x0 +#define IMX7_CSI_PAD_SINK 0 +#define IMX7_CSI_PAD_SRC 1 +#define IMX7_CSI_PADS_NUM 2 /* csi control reg 1 */ -#define BIT_SWAP16_EN BIT(31) -#define BIT_EXT_VSYNC BIT(30) -#define BIT_EOF_INT_EN BIT(29) -#define BIT_PRP_IF_EN BIT(28) -#define BIT_CCIR_MODE BIT(27) -#define BIT_COF_INT_EN BIT(26) -#define BIT_SF_OR_INTEN BIT(25) -#define BIT_RF_OR_INTEN BIT(24) -#define BIT_SFF_DMA_DONE_INTEN BIT(22) -#define BIT_STATFF_INTEN BIT(21) -#define BIT_FB2_DMA_DONE_INTEN BIT(20) -#define BIT_FB1_DMA_DONE_INTEN BIT(19) -#define BIT_RXFF_INTEN BIT(18) -#define BIT_SOF_POL BIT(17) -#define BIT_SOF_INTEN BIT(16) -#define BIT_MCLKDIV (0xF << 12) -#define BIT_HSYNC_POL BIT(11) -#define BIT_CCIR_EN BIT(10) -#define BIT_MCLKEN BIT(9) -#define BIT_FCC BIT(8) -#define BIT_PACK_DIR BIT(7) -#define BIT_CLR_STATFIFO BIT(6) -#define BIT_CLR_RXFIFO BIT(5) -#define BIT_GCLK_MODE BIT(4) -#define BIT_INV_DATA BIT(3) -#define BIT_INV_PCLK BIT(2) -#define BIT_REDGE BIT(1) -#define BIT_PIXEL_BIT BIT(0) - -#define SHIFT_MCLKDIV 12 +#define BIT_SWAP16_EN BIT(31) +#define BIT_EXT_VSYNC BIT(30) +#define BIT_EOF_INT_EN BIT(29) +#define BIT_PRP_IF_EN BIT(28) +#define BIT_CCIR_MODE BIT(27) +#define BIT_COF_INT_EN BIT(26) +#define BIT_SF_OR_INTEN BIT(25) +#define BIT_RF_OR_INTEN BIT(24) +#define BIT_SFF_DMA_DONE_INTEN BIT(22) +#define BIT_STATFF_INTEN BIT(21) +#define BIT_FB2_DMA_DONE_INTEN BIT(20) +#define BIT_FB1_DMA_DONE_INTEN BIT(19) +#define BIT_RXFF_INTEN BIT(18) +#define BIT_SOF_POL BIT(17) +#define BIT_SOF_INTEN BIT(16) +#define BIT_MCLKDIV(n) ((n) << 12) +#define BIT_MCLKDIV_MASK (0xf << 12) +#define BIT_HSYNC_POL BIT(11) +#define BIT_CCIR_EN BIT(10) +#define BIT_MCLKEN BIT(9) +#define BIT_FCC BIT(8) +#define BIT_PACK_DIR BIT(7) +#define BIT_CLR_STATFIFO BIT(6) +#define BIT_CLR_RXFIFO BIT(5) +#define BIT_GCLK_MODE BIT(4) +#define BIT_INV_DATA BIT(3) +#define BIT_INV_PCLK BIT(2) +#define BIT_REDGE BIT(1) +#define BIT_PIXEL_BIT BIT(0) + +/* control reg 2 */ +#define BIT_DMA_BURST_TYPE_RFF_INCR4 (1 << 30) +#define BIT_DMA_BURST_TYPE_RFF_INCR8 (2 << 30) +#define BIT_DMA_BURST_TYPE_RFF_INCR16 (3 << 30) +#define BIT_DMA_BURST_TYPE_RFF_MASK (3 << 30) /* control reg 3 */ -#define BIT_FRMCNT (0xFFFF << 16) -#define BIT_FRMCNT_RST BIT(15) -#define BIT_DMA_REFLASH_RFF BIT(14) -#define BIT_DMA_REFLASH_SFF BIT(13) -#define BIT_DMA_REQ_EN_RFF BIT(12) -#define BIT_DMA_REQ_EN_SFF BIT(11) -#define BIT_STATFF_LEVEL (0x7 << 8) -#define BIT_HRESP_ERR_EN BIT(7) -#define BIT_RXFF_LEVEL (0x7 << 4) -#define BIT_TWO_8BIT_SENSOR BIT(3) -#define BIT_ZERO_PACK_EN BIT(2) -#define BIT_ECC_INT_EN BIT(1) -#define BIT_ECC_AUTO_EN BIT(0) - -#define SHIFT_FRMCNT 16 -#define SHIFT_RXFIFO_LEVEL 4 +#define BIT_FRMCNT(n) ((n) << 16) +#define BIT_FRMCNT_MASK (0xffff << 16) +#define BIT_FRMCNT_RST BIT(15) +#define BIT_DMA_REFLASH_RFF BIT(14) +#define BIT_DMA_REFLASH_SFF BIT(13) +#define BIT_DMA_REQ_EN_RFF BIT(12) +#define BIT_DMA_REQ_EN_SFF BIT(11) +#define BIT_STATFF_LEVEL(n) ((n) << 8) +#define BIT_STATFF_LEVEL_MASK (0x7 << 8) +#define BIT_HRESP_ERR_EN BIT(7) +#define BIT_RXFF_LEVEL(n) ((n) << 4) +#define BIT_RXFF_LEVEL_MASK (0x7 << 4) +#define BIT_TWO_8BIT_SENSOR BIT(3) +#define BIT_ZERO_PACK_EN BIT(2) +#define BIT_ECC_INT_EN BIT(1) +#define BIT_ECC_AUTO_EN BIT(0) /* csi status reg */ -#define BIT_ADDR_CH_ERR_INT BIT(28) -#define BIT_FIELD0_INT BIT(27) -#define BIT_FIELD1_INT BIT(26) -#define BIT_SFF_OR_INT BIT(25) -#define BIT_RFF_OR_INT BIT(24) -#define BIT_DMA_TSF_DONE_SFF BIT(22) -#define BIT_STATFF_INT BIT(21) -#define BIT_DMA_TSF_DONE_FB2 BIT(20) -#define BIT_DMA_TSF_DONE_FB1 BIT(19) -#define BIT_RXFF_INT BIT(18) -#define BIT_EOF_INT BIT(17) -#define BIT_SOF_INT BIT(16) -#define BIT_F2_INT BIT(15) -#define BIT_F1_INT BIT(14) -#define BIT_COF_INT BIT(13) -#define BIT_HRESP_ERR_INT BIT(7) -#define BIT_ECC_INT BIT(1) -#define BIT_DRDY BIT(0) +#define BIT_ADDR_CH_ERR_INT BIT(28) +#define BIT_FIELD0_INT BIT(27) +#define BIT_FIELD1_INT BIT(26) +#define BIT_SFF_OR_INT BIT(25) +#define BIT_RFF_OR_INT BIT(24) +#define BIT_DMA_TSF_DONE_SFF BIT(22) +#define BIT_STATFF_INT BIT(21) +#define BIT_DMA_TSF_DONE_FB2 BIT(20) +#define BIT_DMA_TSF_DONE_FB1 BIT(19) +#define BIT_RXFF_INT BIT(18) +#define BIT_EOF_INT BIT(17) +#define BIT_SOF_INT BIT(16) +#define BIT_F2_INT BIT(15) +#define BIT_F1_INT BIT(14) +#define BIT_COF_INT BIT(13) +#define BIT_HRESP_ERR_INT BIT(7) +#define BIT_ECC_INT BIT(1) +#define BIT_DRDY BIT(0) + +/* csi image parameter reg */ +#define BIT_IMAGE_WIDTH(n) ((n) << 16) +#define BIT_IMAGE_HEIGHT(n) (n) /* csi control reg 18 */ #define BIT_CSI_HW_ENABLE BIT(31) @@ -115,8 +118,7 @@ #define BIT_MIPI_DATA_FORMAT_RAW12 (0x2c << 25) #define BIT_MIPI_DATA_FORMAT_RAW14 (0x2d << 25) #define BIT_MIPI_DATA_FORMAT_YUV422_8B (0x1e << 25) -#define BIT_MIPI_DATA_FORMAT_MASK (0x3F << 25) -#define BIT_MIPI_DATA_FORMAT_OFFSET 25 +#define BIT_MIPI_DATA_FORMAT_MASK (0x3f << 25) #define BIT_DATA_FROM_MIPI BIT(22) #define BIT_MIPI_YU_SWAP BIT(21) #define BIT_MIPI_DOUBLE_CMPNT BIT(20) @@ -128,29 +130,29 @@ #define BIT_TVDECODER_IN_EN BIT(1) #define BIT_NTSC_EN BIT(0) -#define CSI_MCLK_VF 1 -#define CSI_MCLK_ENC 2 -#define CSI_MCLK_RAW 4 -#define CSI_MCLK_I2C 8 - -#define CSI_CSICR1 0x0 -#define CSI_CSICR2 0x4 -#define CSI_CSICR3 0x8 -#define CSI_STATFIFO 0xC -#define CSI_CSIRXFIFO 0x10 -#define CSI_CSIRXCNT 0x14 -#define CSI_CSISR 0x18 - -#define CSI_CSIDBG 0x1C -#define CSI_CSIDMASA_STATFIFO 0x20 -#define CSI_CSIDMATS_STATFIFO 0x24 -#define CSI_CSIDMASA_FB1 0x28 -#define CSI_CSIDMASA_FB2 0x2C -#define CSI_CSIFBUF_PARA 0x30 -#define CSI_CSIIMAG_PARA 0x34 - -#define CSI_CSICR18 0x48 -#define CSI_CSICR19 0x4c +#define CSI_MCLK_VF 1 +#define CSI_MCLK_ENC 2 +#define CSI_MCLK_RAW 4 +#define CSI_MCLK_I2C 8 + +#define CSI_CSICR1 0x00 +#define CSI_CSICR2 0x04 +#define CSI_CSICR3 0x08 +#define CSI_STATFIFO 0x0c +#define CSI_CSIRXFIFO 0x10 +#define CSI_CSIRXCNT 0x14 +#define CSI_CSISR 0x18 + +#define CSI_CSIDBG 0x1c +#define CSI_CSIDMASA_STATFIFO 0x20 +#define CSI_CSIDMATS_STATFIFO 0x24 +#define CSI_CSIDMASA_FB1 0x28 +#define CSI_CSIDMASA_FB2 0x2c +#define CSI_CSIFBUF_PARA 0x30 +#define CSI_CSIIMAG_PARA 0x34 + +#define CSI_CSICR18 0x48 +#define CSI_CSICR19 0x4c struct imx7_csi { struct device *dev; @@ -167,14 +169,10 @@ struct imx7_csi { struct v4l2_subdev *src_sd; - struct media_entity *sink; - struct v4l2_mbus_framefmt format_mbus[IMX7_CSI_PADS_NUM]; const struct imx_media_pixfmt *cc[IMX7_CSI_PADS_NUM]; struct v4l2_fract frame_interval[IMX7_CSI_PADS_NUM]; - struct v4l2_ctrl_handler ctrl_hdlr; - void __iomem *regbase; int irq; struct clk *mclk; @@ -187,7 +185,6 @@ struct imx7_csi { u32 frame_sequence; bool last_eof; - bool is_init; bool is_streaming; bool is_csi2; @@ -200,6 +197,10 @@ imx7_csi_notifier_to_dev(struct v4l2_async_notifier *n) return container_of(n, struct imx7_csi, notifier); } +/* ----------------------------------------------------------------------------- + * Hardware Configuration + */ + static u32 imx7_csi_reg_read(struct imx7_csi *csi, unsigned int offset) { return readl(csi->regbase + offset); @@ -211,17 +212,6 @@ static void imx7_csi_reg_write(struct imx7_csi *csi, unsigned int value, writel(value, csi->regbase + offset); } -static void imx7_csi_hw_reset(struct imx7_csi *csi) -{ - imx7_csi_reg_write(csi, - imx7_csi_reg_read(csi, CSI_CSICR3) | BIT_FRMCNT_RST, - CSI_CSICR3); - - imx7_csi_reg_write(csi, CSICR1_RESET_VAL, CSI_CSICR1); - imx7_csi_reg_write(csi, CSICR2_RESET_VAL, CSI_CSICR2); - imx7_csi_reg_write(csi, CSICR3_RESET_VAL, CSI_CSICR3); -} - static u32 imx7_csi_irq_clear(struct imx7_csi *csi) { u32 isr; @@ -232,35 +222,28 @@ static u32 imx7_csi_irq_clear(struct imx7_csi *csi) return isr; } -static void imx7_csi_init_interface(struct imx7_csi *csi) +static void imx7_csi_init_default(struct imx7_csi *csi) { - unsigned int val = 0; - unsigned int imag_para; - - val = BIT_SOF_POL | BIT_REDGE | BIT_GCLK_MODE | BIT_HSYNC_POL | - BIT_FCC | 1 << SHIFT_MCLKDIV | BIT_MCLKEN; - imx7_csi_reg_write(csi, val, CSI_CSICR1); + imx7_csi_reg_write(csi, BIT_SOF_POL | BIT_REDGE | BIT_GCLK_MODE | + BIT_HSYNC_POL | BIT_FCC | BIT_MCLKDIV(1) | + BIT_MCLKEN, CSI_CSICR1); + imx7_csi_reg_write(csi, 0, CSI_CSICR2); + imx7_csi_reg_write(csi, BIT_FRMCNT_RST, CSI_CSICR3); - imag_para = (800 << 16) | 600; - imx7_csi_reg_write(csi, imag_para, CSI_CSIIMAG_PARA); + imx7_csi_reg_write(csi, BIT_IMAGE_WIDTH(800) | BIT_IMAGE_HEIGHT(600), + CSI_CSIIMAG_PARA); - val = BIT_DMA_REFLASH_RFF; - imx7_csi_reg_write(csi, val, CSI_CSICR3); + imx7_csi_reg_write(csi, BIT_DMA_REFLASH_RFF, CSI_CSICR3); } static void imx7_csi_hw_enable_irq(struct imx7_csi *csi) { u32 cr1 = imx7_csi_reg_read(csi, CSI_CSICR1); - cr1 |= BIT_SOF_INTEN; cr1 |= BIT_RFF_OR_INT; - - /* still capture needs DMA interrupt */ cr1 |= BIT_FB1_DMA_DONE_INTEN; cr1 |= BIT_FB2_DMA_DONE_INTEN; - cr1 |= BIT_EOF_INT_EN; - imx7_csi_reg_write(csi, cr1, CSI_CSICR1); } @@ -268,11 +251,9 @@ static void imx7_csi_hw_disable_irq(struct imx7_csi *csi) { u32 cr1 = imx7_csi_reg_read(csi, CSI_CSICR1); - cr1 &= ~BIT_SOF_INTEN; cr1 &= ~BIT_RFF_OR_INT; cr1 &= ~BIT_FB1_DMA_DONE_INTEN; cr1 &= ~BIT_FB2_DMA_DONE_INTEN; - cr1 &= ~BIT_EOF_INT_EN; imx7_csi_reg_write(csi, cr1, CSI_CSICR1); } @@ -306,49 +287,23 @@ static void imx7_csi_dma_reflash(struct imx7_csi *csi) static void imx7_csi_rx_fifo_clear(struct imx7_csi *csi) { - u32 cr1; + u32 cr1 = imx7_csi_reg_read(csi, CSI_CSICR1) & ~BIT_FCC; - cr1 = imx7_csi_reg_read(csi, CSI_CSICR1); - imx7_csi_reg_write(csi, cr1 & ~BIT_FCC, CSI_CSICR1); - cr1 = imx7_csi_reg_read(csi, CSI_CSICR1); + imx7_csi_reg_write(csi, cr1, CSI_CSICR1); imx7_csi_reg_write(csi, cr1 | BIT_CLR_RXFIFO, CSI_CSICR1); - - cr1 = imx7_csi_reg_read(csi, CSI_CSICR1); imx7_csi_reg_write(csi, cr1 | BIT_FCC, CSI_CSICR1); } -static void imx7_csi_buf_stride_set(struct imx7_csi *csi, u32 stride) -{ - imx7_csi_reg_write(csi, stride, CSI_CSIFBUF_PARA); -} - -static void imx7_csi_deinterlace_enable(struct imx7_csi *csi, bool enable) -{ - u32 cr18 = imx7_csi_reg_read(csi, CSI_CSICR18); - - if (enable) - cr18 |= BIT_DEINTERLACE_EN; - else - cr18 &= ~BIT_DEINTERLACE_EN; - - imx7_csi_reg_write(csi, cr18, CSI_CSICR18); -} - static void imx7_csi_dmareq_rff_enable(struct imx7_csi *csi) { u32 cr3 = imx7_csi_reg_read(csi, CSI_CSICR3); - u32 cr2 = imx7_csi_reg_read(csi, CSI_CSICR2); - - /* Burst Type of DMA Transfer from RxFIFO. INCR16 */ - cr2 |= 0xC0000000; cr3 |= BIT_DMA_REQ_EN_RFF; cr3 |= BIT_HRESP_ERR_EN; - cr3 &= ~BIT_RXFF_LEVEL; - cr3 |= 0x2 << 4; + cr3 &= ~BIT_RXFF_LEVEL_MASK; + cr3 |= BIT_RXFF_LEVEL(2); imx7_csi_reg_write(csi, cr3, CSI_CSICR3); - imx7_csi_reg_write(csi, cr2, CSI_CSICR2); } static void imx7_csi_dmareq_rff_disable(struct imx7_csi *csi) @@ -360,231 +315,277 @@ static void imx7_csi_dmareq_rff_disable(struct imx7_csi *csi) imx7_csi_reg_write(csi, cr3, CSI_CSICR3); } -static void imx7_csi_set_imagpara(struct imx7_csi *csi, int width, int height) +static void imx7_csi_update_buf(struct imx7_csi *csi, dma_addr_t phys, + int buf_num) { - int imag_para; - int rx_count; - - rx_count = (width * height) >> 2; - imx7_csi_reg_write(csi, rx_count, CSI_CSIRXCNT); - - imag_para = (width << 16) | height; - imx7_csi_reg_write(csi, imag_para, CSI_CSIIMAG_PARA); - - /* reflash the embedded DMA controller */ - imx7_csi_dma_reflash(csi); + if (buf_num == 1) + imx7_csi_reg_write(csi, phys, CSI_CSIDMASA_FB2); + else + imx7_csi_reg_write(csi, phys, CSI_CSIDMASA_FB1); } -static void imx7_csi_sw_reset(struct imx7_csi *csi) +static void imx7_csi_setup_vb2_buf(struct imx7_csi *csi) { - imx7_csi_hw_disable(csi); - - imx7_csi_rx_fifo_clear(csi); - - imx7_csi_dma_reflash(csi); - - usleep_range(2000, 3000); + struct imx_media_video_dev *vdev = csi->vdev; + struct imx_media_buffer *buf; + struct vb2_buffer *vb2_buf; + dma_addr_t phys[2]; + int i; - imx7_csi_irq_clear(csi); + for (i = 0; i < 2; i++) { + buf = imx_media_capture_device_next_buf(vdev); + if (buf) { + csi->active_vb2_buf[i] = buf; + vb2_buf = &buf->vbuf.vb2_buf; + phys[i] = vb2_dma_contig_plane_dma_addr(vb2_buf, 0); + } else { + csi->active_vb2_buf[i] = NULL; + phys[i] = csi->underrun_buf.phys; + } - imx7_csi_hw_enable(csi); + imx7_csi_update_buf(csi, phys[i], i); + } } -static void imx7_csi_error_recovery(struct imx7_csi *csi) +static void imx7_csi_dma_unsetup_vb2_buf(struct imx7_csi *csi, + enum vb2_buffer_state return_status) { - imx7_csi_hw_disable(csi); - - imx7_csi_rx_fifo_clear(csi); + struct imx_media_buffer *buf; + int i; - imx7_csi_dma_reflash(csi); + /* return any remaining active frames with return_status */ + for (i = 0; i < 2; i++) { + buf = csi->active_vb2_buf[i]; + if (buf) { + struct vb2_buffer *vb = &buf->vbuf.vb2_buf; - imx7_csi_hw_enable(csi); + vb->timestamp = ktime_get_ns(); + vb2_buffer_done(vb, return_status); + } + } } -static int imx7_csi_init(struct imx7_csi *csi) +static int imx7_csi_dma_setup(struct imx7_csi *csi) { + struct imx_media_video_dev *vdev = csi->vdev; int ret; - if (csi->is_init) - return 0; - - ret = clk_prepare_enable(csi->mclk); - if (ret < 0) + ret = imx_media_alloc_dma_buf(csi->dev, &csi->underrun_buf, + vdev->fmt.sizeimage); + if (ret < 0) { + v4l2_warn(&csi->sd, "consider increasing the CMA area\n"); return ret; - imx7_csi_hw_reset(csi); - imx7_csi_init_interface(csi); - imx7_csi_dmareq_rff_enable(csi); + } - csi->is_init = true; + csi->frame_sequence = 0; + csi->last_eof = false; + init_completion(&csi->last_eof_completion); + + imx7_csi_setup_vb2_buf(csi); return 0; } -static void imx7_csi_deinit(struct imx7_csi *csi) +static void imx7_csi_dma_cleanup(struct imx7_csi *csi) { - if (!csi->is_init) - return; + imx7_csi_dma_unsetup_vb2_buf(csi, VB2_BUF_STATE_ERROR); + imx_media_free_dma_buf(csi->dev, &csi->underrun_buf); +} - imx7_csi_hw_reset(csi); - imx7_csi_init_interface(csi); - imx7_csi_dmareq_rff_disable(csi); - clk_disable_unprepare(csi->mclk); +static void imx7_csi_dma_stop(struct imx7_csi *csi) +{ + unsigned long timeout_jiffies; + unsigned long flags; + int ret; - csi->is_init = false; + /* mark next EOF interrupt as the last before stream off */ + spin_lock_irqsave(&csi->irqlock, flags); + csi->last_eof = true; + spin_unlock_irqrestore(&csi->irqlock, flags); + + /* + * and then wait for interrupt handler to mark completion. + */ + timeout_jiffies = msecs_to_jiffies(IMX_MEDIA_EOF_TIMEOUT); + ret = wait_for_completion_timeout(&csi->last_eof_completion, + timeout_jiffies); + if (ret == 0) + v4l2_warn(&csi->sd, "wait last EOF timeout\n"); + + imx7_csi_hw_disable_irq(csi); } -static int imx7_csi_link_setup(struct media_entity *entity, - const struct media_pad *local, - const struct media_pad *remote, u32 flags) +static void imx7_csi_configure(struct imx7_csi *csi) { - struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity); - struct imx7_csi *csi = v4l2_get_subdevdata(sd); - struct v4l2_subdev *remote_sd; - int ret = 0; + struct imx_media_video_dev *vdev = csi->vdev; + struct v4l2_pix_format *out_pix = &vdev->fmt; + int width = out_pix->width; + u32 stride = 0; + u32 cr1, cr18; - dev_dbg(csi->dev, "link setup %s -> %s\n", remote->entity->name, - local->entity->name); + cr18 = imx7_csi_reg_read(csi, CSI_CSICR18); - mutex_lock(&csi->lock); + cr18 &= ~(BIT_CSI_HW_ENABLE | BIT_MIPI_DATA_FORMAT_MASK | + BIT_DATA_FROM_MIPI | BIT_BASEADDR_CHG_ERR_EN | + BIT_BASEADDR_SWITCH_EN | BIT_BASEADDR_SWITCH_SEL | + BIT_DEINTERLACE_EN); - if (local->flags & MEDIA_PAD_FL_SINK) { - if (!is_media_entity_v4l2_subdev(remote->entity)) { - ret = -EINVAL; - goto unlock; - } + if (out_pix->field == V4L2_FIELD_INTERLACED) { + cr18 |= BIT_DEINTERLACE_EN; + stride = out_pix->width; + } - remote_sd = media_entity_to_v4l2_subdev(remote->entity); + if (!csi->is_csi2) { + cr1 = BIT_SOF_POL | BIT_REDGE | BIT_GCLK_MODE | BIT_HSYNC_POL + | BIT_FCC | BIT_MCLKDIV(1) | BIT_MCLKEN; - if (flags & MEDIA_LNK_FL_ENABLED) { - if (csi->src_sd) { - ret = -EBUSY; - goto unlock; - } - csi->src_sd = remote_sd; - } else { - csi->src_sd = NULL; - } + cr18 |= BIT_BASEADDR_SWITCH_EN | BIT_BASEADDR_SWITCH_SEL | + BIT_BASEADDR_CHG_ERR_EN; - goto init; - } + if (out_pix->pixelformat == V4L2_PIX_FMT_UYVY || + out_pix->pixelformat == V4L2_PIX_FMT_YUYV) + width *= 2; + } else { + cr1 = BIT_SOF_POL | BIT_REDGE | BIT_HSYNC_POL | BIT_FCC + | BIT_MCLKDIV(1) | BIT_MCLKEN; + + cr18 |= BIT_DATA_FROM_MIPI; + + switch (csi->format_mbus[IMX7_CSI_PAD_SINK].code) { + case MEDIA_BUS_FMT_Y8_1X8: + case MEDIA_BUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_SGBRG8_1X8: + case MEDIA_BUS_FMT_SGRBG8_1X8: + case MEDIA_BUS_FMT_SRGGB8_1X8: + cr18 |= BIT_MIPI_DATA_FORMAT_RAW8; + break; + case MEDIA_BUS_FMT_Y10_1X10: + case MEDIA_BUS_FMT_SBGGR10_1X10: + case MEDIA_BUS_FMT_SGBRG10_1X10: + case MEDIA_BUS_FMT_SGRBG10_1X10: + case MEDIA_BUS_FMT_SRGGB10_1X10: + cr18 |= BIT_MIPI_DATA_FORMAT_RAW10; + break; + case MEDIA_BUS_FMT_Y12_1X12: + case MEDIA_BUS_FMT_SBGGR12_1X12: + case MEDIA_BUS_FMT_SGBRG12_1X12: + case MEDIA_BUS_FMT_SGRBG12_1X12: + case MEDIA_BUS_FMT_SRGGB12_1X12: + cr18 |= BIT_MIPI_DATA_FORMAT_RAW12; + break; + case MEDIA_BUS_FMT_Y14_1X14: + case MEDIA_BUS_FMT_SBGGR14_1X14: + case MEDIA_BUS_FMT_SGBRG14_1X14: + case MEDIA_BUS_FMT_SGRBG14_1X14: + case MEDIA_BUS_FMT_SRGGB14_1X14: + cr18 |= BIT_MIPI_DATA_FORMAT_RAW14; + break; + /* + * CSI-2 sources are supposed to use the 1X16 formats, but not + * all of them comply. Support both variants. + */ + case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_UYVY8_1X16: + case MEDIA_BUS_FMT_YUYV8_2X8: + case MEDIA_BUS_FMT_YUYV8_1X16: + cr18 |= BIT_MIPI_DATA_FORMAT_YUV422_8B; + break; + } - /* source pad */ - if (flags & MEDIA_LNK_FL_ENABLED) { - if (csi->sink) { - ret = -EBUSY; - goto unlock; + switch (out_pix->pixelformat) { + case V4L2_PIX_FMT_Y10: + case V4L2_PIX_FMT_Y12: + case V4L2_PIX_FMT_SBGGR8: + case V4L2_PIX_FMT_SGBRG8: + case V4L2_PIX_FMT_SGRBG8: + case V4L2_PIX_FMT_SRGGB8: + case V4L2_PIX_FMT_SBGGR16: + case V4L2_PIX_FMT_SGBRG16: + case V4L2_PIX_FMT_SGRBG16: + case V4L2_PIX_FMT_SRGGB16: + cr1 |= BIT_PIXEL_BIT; + break; } - csi->sink = remote->entity; - } else { - v4l2_ctrl_handler_free(&csi->ctrl_hdlr); - v4l2_ctrl_handler_init(&csi->ctrl_hdlr, 0); - csi->sink = NULL; } -init: - if (csi->sink || csi->src_sd) - ret = imx7_csi_init(csi); - else - imx7_csi_deinit(csi); - -unlock: - mutex_unlock(&csi->lock); + imx7_csi_reg_write(csi, cr1, CSI_CSICR1); + imx7_csi_reg_write(csi, BIT_DMA_BURST_TYPE_RFF_INCR16, CSI_CSICR2); + imx7_csi_reg_write(csi, BIT_FRMCNT_RST, CSI_CSICR3); + imx7_csi_reg_write(csi, cr18, CSI_CSICR18); - return ret; + imx7_csi_reg_write(csi, (width * out_pix->height) >> 2, CSI_CSIRXCNT); + imx7_csi_reg_write(csi, BIT_IMAGE_WIDTH(width) | + BIT_IMAGE_HEIGHT(out_pix->height), + CSI_CSIIMAG_PARA); + imx7_csi_reg_write(csi, stride, CSI_CSIFBUF_PARA); } -static int imx7_csi_pad_link_validate(struct v4l2_subdev *sd, - struct media_link *link, - struct v4l2_subdev_format *source_fmt, - struct v4l2_subdev_format *sink_fmt) +static int imx7_csi_init(struct imx7_csi *csi) { - struct imx7_csi *csi = v4l2_get_subdevdata(sd); - struct media_entity *src; - struct media_pad *pad; int ret; - ret = v4l2_subdev_link_validate_default(sd, link, source_fmt, sink_fmt); - if (ret) + ret = clk_prepare_enable(csi->mclk); + if (ret < 0) return ret; - if (!csi->src_sd) - return -EPIPE; + imx7_csi_configure(csi); - src = &csi->src_sd->entity; + ret = imx7_csi_dma_setup(csi); + if (ret < 0) + return ret; - /* - * if the source is neither a CSI MUX or CSI-2 get the one directly - * upstream from this CSI - */ - if (src->function != MEDIA_ENT_F_VID_IF_BRIDGE && - src->function != MEDIA_ENT_F_VID_MUX) - src = &csi->sd.entity; + return 0; +} - /* - * find the entity that is selected by the source. This is needed - * to distinguish between a parallel or CSI-2 pipeline. - */ - pad = imx_media_pipeline_pad(src, 0, 0, true); - if (!pad) - return -ENODEV; +static void imx7_csi_deinit(struct imx7_csi *csi) +{ + imx7_csi_dma_cleanup(csi); + imx7_csi_init_default(csi); + imx7_csi_dmareq_rff_disable(csi); + clk_disable_unprepare(csi->mclk); +} - mutex_lock(&csi->lock); +static void imx7_csi_enable(struct imx7_csi *csi) +{ + /* Clear the Rx FIFO and reflash the DMA controller. */ + imx7_csi_rx_fifo_clear(csi); + imx7_csi_dma_reflash(csi); - csi->is_csi2 = (pad->entity->function == MEDIA_ENT_F_VID_IF_BRIDGE); + usleep_range(2000, 3000); - mutex_unlock(&csi->lock); + /* Clear and enable the interrupts. */ + imx7_csi_irq_clear(csi); + imx7_csi_hw_enable_irq(csi); - return 0; + /* Enable the RxFIFO DMA and the CSI. */ + imx7_csi_dmareq_rff_enable(csi); + imx7_csi_hw_enable(csi); } -static void imx7_csi_update_buf(struct imx7_csi *csi, dma_addr_t phys, - int buf_num) +static void imx7_csi_disable(struct imx7_csi *csi) { - if (buf_num == 1) - imx7_csi_reg_write(csi, phys, CSI_CSIDMASA_FB2); - else - imx7_csi_reg_write(csi, phys, CSI_CSIDMASA_FB1); -} + imx7_csi_dma_stop(csi); -static void imx7_csi_setup_vb2_buf(struct imx7_csi *csi) -{ - struct imx_media_video_dev *vdev = csi->vdev; - struct imx_media_buffer *buf; - struct vb2_buffer *vb2_buf; - dma_addr_t phys[2]; - int i; + imx7_csi_dmareq_rff_disable(csi); - for (i = 0; i < 2; i++) { - buf = imx_media_capture_device_next_buf(vdev); - if (buf) { - csi->active_vb2_buf[i] = buf; - vb2_buf = &buf->vbuf.vb2_buf; - phys[i] = vb2_dma_contig_plane_dma_addr(vb2_buf, 0); - } else { - csi->active_vb2_buf[i] = NULL; - phys[i] = csi->underrun_buf.phys; - } + imx7_csi_hw_disable_irq(csi); - imx7_csi_update_buf(csi, phys[i], i); - } + imx7_csi_hw_disable(csi); } -static void imx7_csi_dma_unsetup_vb2_buf(struct imx7_csi *csi, - enum vb2_buffer_state return_status) +/* ----------------------------------------------------------------------------- + * Interrupt Handling + */ + +static void imx7_csi_error_recovery(struct imx7_csi *csi) { - struct imx_media_buffer *buf; - int i; + imx7_csi_hw_disable(csi); - /* return any remaining active frames with return_status */ - for (i = 0; i < 2; i++) { - buf = csi->active_vb2_buf[i]; - if (buf) { - struct vb2_buffer *vb = &buf->vbuf.vb2_buf; + imx7_csi_rx_fifo_clear(csi); - vb->timestamp = ktime_get_ns(); - vb2_buffer_done(vb, return_status); - } - } + imx7_csi_dma_reflash(csi); + + imx7_csi_hw_enable(csi); } static void imx7_csi_vb2_buf_done(struct imx7_csi *csi) @@ -596,7 +597,7 @@ static void imx7_csi_vb2_buf_done(struct imx7_csi *csi) done = csi->active_vb2_buf[csi->buf_num]; if (done) { - done->vbuf.field = vdev->fmt.fmt.pix.field; + done->vbuf.field = vdev->fmt.field; done->vbuf.sequence = csi->frame_sequence; vb = &done->vbuf.vb2_buf; vb->timestamp = ktime_get_ns(); @@ -675,188 +676,9 @@ static irqreturn_t imx7_csi_irq_handler(int irq, void *data) return IRQ_HANDLED; } -static int imx7_csi_dma_start(struct imx7_csi *csi) -{ - struct imx_media_video_dev *vdev = csi->vdev; - struct v4l2_pix_format *out_pix = &vdev->fmt.fmt.pix; - int ret; - - ret = imx_media_alloc_dma_buf(csi->dev, &csi->underrun_buf, - out_pix->sizeimage); - if (ret < 0) { - v4l2_warn(&csi->sd, "consider increasing the CMA area\n"); - return ret; - } - - csi->frame_sequence = 0; - csi->last_eof = false; - init_completion(&csi->last_eof_completion); - - imx7_csi_setup_vb2_buf(csi); - - return 0; -} - -static void imx7_csi_dma_stop(struct imx7_csi *csi) -{ - unsigned long timeout_jiffies; - unsigned long flags; - int ret; - - /* mark next EOF interrupt as the last before stream off */ - spin_lock_irqsave(&csi->irqlock, flags); - csi->last_eof = true; - spin_unlock_irqrestore(&csi->irqlock, flags); - - /* - * and then wait for interrupt handler to mark completion. - */ - timeout_jiffies = msecs_to_jiffies(IMX_MEDIA_EOF_TIMEOUT); - ret = wait_for_completion_timeout(&csi->last_eof_completion, - timeout_jiffies); - if (ret == 0) - v4l2_warn(&csi->sd, "wait last EOF timeout\n"); - - imx7_csi_hw_disable_irq(csi); - - imx7_csi_dma_unsetup_vb2_buf(csi, VB2_BUF_STATE_ERROR); - - imx_media_free_dma_buf(csi->dev, &csi->underrun_buf); -} - -static int imx7_csi_configure(struct imx7_csi *csi) -{ - struct imx_media_video_dev *vdev = csi->vdev; - struct v4l2_pix_format *out_pix = &vdev->fmt.fmt.pix; - __u32 in_code = csi->format_mbus[IMX7_CSI_PAD_SINK].code; - u32 cr1, cr18; - int width = out_pix->width; - - if (out_pix->field == V4L2_FIELD_INTERLACED) { - imx7_csi_deinterlace_enable(csi, true); - imx7_csi_buf_stride_set(csi, out_pix->width); - } else { - imx7_csi_deinterlace_enable(csi, false); - imx7_csi_buf_stride_set(csi, 0); - } - - cr18 = imx7_csi_reg_read(csi, CSI_CSICR18); - - if (!csi->is_csi2) { - if (out_pix->pixelformat == V4L2_PIX_FMT_UYVY || - out_pix->pixelformat == V4L2_PIX_FMT_YUYV) - width *= 2; - - imx7_csi_set_imagpara(csi, width, out_pix->height); - - cr18 |= (BIT_BASEADDR_SWITCH_EN | BIT_BASEADDR_SWITCH_SEL | - BIT_BASEADDR_CHG_ERR_EN); - imx7_csi_reg_write(csi, cr18, CSI_CSICR18); - - return 0; - } - - imx7_csi_set_imagpara(csi, width, out_pix->height); - - cr1 = imx7_csi_reg_read(csi, CSI_CSICR1); - cr1 &= ~BIT_GCLK_MODE; - - cr18 &= BIT_MIPI_DATA_FORMAT_MASK; - cr18 |= BIT_DATA_FROM_MIPI; - - switch (out_pix->pixelformat) { - case V4L2_PIX_FMT_UYVY: - case V4L2_PIX_FMT_YUYV: - cr18 |= BIT_MIPI_DATA_FORMAT_YUV422_8B; - break; - case V4L2_PIX_FMT_GREY: - if (in_code == MEDIA_BUS_FMT_Y8_1X8) - cr18 |= BIT_MIPI_DATA_FORMAT_RAW8; - else if (in_code == MEDIA_BUS_FMT_Y10_1X10) - cr18 |= BIT_MIPI_DATA_FORMAT_RAW10; - else - cr18 |= BIT_MIPI_DATA_FORMAT_RAW12; - break; - case V4L2_PIX_FMT_Y10: - cr18 |= BIT_MIPI_DATA_FORMAT_RAW10; - cr1 |= BIT_PIXEL_BIT; - break; - case V4L2_PIX_FMT_Y12: - cr18 |= BIT_MIPI_DATA_FORMAT_RAW12; - cr1 |= BIT_PIXEL_BIT; - break; - case V4L2_PIX_FMT_SBGGR8: - cr18 |= BIT_MIPI_DATA_FORMAT_RAW8; - break; - case V4L2_PIX_FMT_SBGGR16: - if (in_code == MEDIA_BUS_FMT_SBGGR10_1X10) - cr18 |= BIT_MIPI_DATA_FORMAT_RAW10; - else if (in_code == MEDIA_BUS_FMT_SBGGR12_1X12) - cr18 |= BIT_MIPI_DATA_FORMAT_RAW12; - else if (in_code == MEDIA_BUS_FMT_SBGGR14_1X14) - cr18 |= BIT_MIPI_DATA_FORMAT_RAW14; - cr1 |= BIT_PIXEL_BIT; - break; - default: - return -EINVAL; - } - - imx7_csi_reg_write(csi, cr1, CSI_CSICR1); - imx7_csi_reg_write(csi, cr18, CSI_CSICR18); - - return 0; -} - -static void imx7_csi_enable(struct imx7_csi *csi) -{ - imx7_csi_sw_reset(csi); - - imx7_csi_dmareq_rff_enable(csi); - imx7_csi_hw_enable_irq(csi); - imx7_csi_hw_enable(csi); -} - -static void imx7_csi_disable(struct imx7_csi *csi) -{ - imx7_csi_dmareq_rff_disable(csi); - - imx7_csi_hw_disable_irq(csi); - - imx7_csi_buf_stride_set(csi, 0); - - imx7_csi_hw_disable(csi); -} - -static int imx7_csi_streaming_start(struct imx7_csi *csi) -{ - int ret; - - ret = imx7_csi_dma_start(csi); - if (ret < 0) - return ret; - - ret = imx7_csi_configure(csi); - if (ret < 0) - goto dma_stop; - - imx7_csi_enable(csi); - - return 0; - -dma_stop: - imx7_csi_dma_stop(csi); - - return ret; -} - -static int imx7_csi_streaming_stop(struct imx7_csi *csi) -{ - imx7_csi_dma_stop(csi); - - imx7_csi_disable(csi); - - return 0; -} +/* ----------------------------------------------------------------------------- + * V4L2 Subdev Operations + */ static int imx7_csi_s_stream(struct v4l2_subdev *sd, int enable) { @@ -865,7 +687,7 @@ static int imx7_csi_s_stream(struct v4l2_subdev *sd, int enable) mutex_lock(&csi->lock); - if (!csi->src_sd || !csi->sink) { + if (!csi->src_sd) { ret = -EPIPE; goto out_unlock; } @@ -874,19 +696,23 @@ static int imx7_csi_s_stream(struct v4l2_subdev *sd, int enable) goto out_unlock; if (enable) { - ret = v4l2_subdev_call(csi->src_sd, video, s_stream, 1); + ret = imx7_csi_init(csi); if (ret < 0) goto out_unlock; - ret = imx7_csi_streaming_start(csi); + ret = v4l2_subdev_call(csi->src_sd, video, s_stream, 1); if (ret < 0) { - v4l2_subdev_call(csi->src_sd, video, s_stream, 0); + imx7_csi_deinit(csi); goto out_unlock; } + + imx7_csi_enable(csi); } else { - imx7_csi_streaming_stop(csi); + imx7_csi_disable(csi); v4l2_subdev_call(csi->src_sd, video, s_stream, 0); + + imx7_csi_deinit(csi); } csi->is_streaming = !!enable; @@ -897,6 +723,26 @@ out_unlock: return ret; } +static int imx7_csi_init_cfg(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg) +{ + struct imx7_csi *csi = v4l2_get_subdevdata(sd); + struct v4l2_mbus_framefmt *mf; + int ret; + int i; + + for (i = 0; i < IMX7_CSI_PADS_NUM; i++) { + mf = v4l2_subdev_get_try_format(sd, cfg, i); + + ret = imx_media_init_mbus_fmt(mf, 800, 600, 0, V4L2_FIELD_NONE, + &csi->cc[i]); + if (ret < 0) + return ret; + } + + return 0; +} + static struct v4l2_mbus_framefmt * imx7_csi_get_format(struct imx7_csi *csi, struct v4l2_subdev_pad_config *cfg, @@ -1081,6 +927,78 @@ out_unlock: return ret; } +static int imx7_csi_pad_link_validate(struct v4l2_subdev *sd, + struct media_link *link, + struct v4l2_subdev_format *source_fmt, + struct v4l2_subdev_format *sink_fmt) +{ + struct imx7_csi *csi = v4l2_get_subdevdata(sd); + struct imx_media_video_dev *vdev = csi->vdev; + const struct v4l2_pix_format *out_pix = &vdev->fmt; + struct media_pad *pad; + int ret; + + if (!csi->src_sd) + return -EPIPE; + + /* + * Validate the source link, and record whether the source uses the + * parallel input or the CSI-2 receiver. + */ + ret = v4l2_subdev_link_validate_default(sd, link, source_fmt, sink_fmt); + if (ret) + return ret; + + switch (csi->src_sd->entity.function) { + case MEDIA_ENT_F_VID_IF_BRIDGE: + /* The input is the CSI-2 receiver. */ + csi->is_csi2 = true; + break; + + case MEDIA_ENT_F_VID_MUX: + /* The input is the mux, check its input. */ + pad = imx_media_pipeline_pad(&csi->src_sd->entity, 0, 0, true); + if (!pad) + return -ENODEV; + + csi->is_csi2 = pad->entity->function == MEDIA_ENT_F_VID_IF_BRIDGE; + break; + + default: + /* + * The input is an external entity, it must use the parallel + * bus. + */ + csi->is_csi2 = false; + break; + } + + /* Validate the sink link, ensure the pixel format is supported. */ + switch (out_pix->pixelformat) { + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_GREY: + case V4L2_PIX_FMT_Y10: + case V4L2_PIX_FMT_Y12: + case V4L2_PIX_FMT_SBGGR8: + case V4L2_PIX_FMT_SGBRG8: + case V4L2_PIX_FMT_SGRBG8: + case V4L2_PIX_FMT_SRGGB8: + case V4L2_PIX_FMT_SBGGR16: + case V4L2_PIX_FMT_SGBRG16: + case V4L2_PIX_FMT_SGRBG16: + case V4L2_PIX_FMT_SRGGB16: + break; + + default: + dev_dbg(csi->dev, "Invalid capture pixel format 0x%08x\n", + out_pix->pixelformat); + return -EINVAL; + } + + return 0; +} + static int imx7_csi_registered(struct v4l2_subdev *sd) { struct imx7_csi *csi = v4l2_get_subdevdata(sd); @@ -1101,11 +1019,12 @@ static int imx7_csi_registered(struct v4l2_subdev *sd) } csi->vdev = imx_media_capture_device_init(csi->sd.dev, &csi->sd, - IMX7_CSI_PAD_SRC); + IMX7_CSI_PAD_SRC, false); if (IS_ERR(csi->vdev)) return PTR_ERR(csi->vdev); - ret = imx_media_capture_device_register(csi->vdev); + ret = imx_media_capture_device_register(csi->vdev, + MEDIA_LNK_FL_IMMUTABLE); if (ret) imx_media_capture_device_remove(csi->vdev); @@ -1120,47 +1039,21 @@ static void imx7_csi_unregistered(struct v4l2_subdev *sd) imx_media_capture_device_remove(csi->vdev); } -static int imx7_csi_init_cfg(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg) -{ - struct imx7_csi *csi = v4l2_get_subdevdata(sd); - struct v4l2_mbus_framefmt *mf; - int ret; - int i; - - for (i = 0; i < IMX7_CSI_PADS_NUM; i++) { - mf = v4l2_subdev_get_try_format(sd, cfg, i); - - ret = imx_media_init_mbus_fmt(mf, 800, 600, 0, V4L2_FIELD_NONE, - &csi->cc[i]); - if (ret < 0) - return ret; - } - - return 0; -} - -static const struct media_entity_operations imx7_csi_entity_ops = { - .link_setup = imx7_csi_link_setup, - .link_validate = v4l2_subdev_link_validate, - .get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1, -}; - static const struct v4l2_subdev_video_ops imx7_csi_video_ops = { - .s_stream = imx7_csi_s_stream, + .s_stream = imx7_csi_s_stream, }; static const struct v4l2_subdev_pad_ops imx7_csi_pad_ops = { - .init_cfg = imx7_csi_init_cfg, - .enum_mbus_code = imx7_csi_enum_mbus_code, - .get_fmt = imx7_csi_get_fmt, - .set_fmt = imx7_csi_set_fmt, - .link_validate = imx7_csi_pad_link_validate, + .init_cfg = imx7_csi_init_cfg, + .enum_mbus_code = imx7_csi_enum_mbus_code, + .get_fmt = imx7_csi_get_fmt, + .set_fmt = imx7_csi_set_fmt, + .link_validate = imx7_csi_pad_link_validate, }; static const struct v4l2_subdev_ops imx7_csi_subdev_ops = { - .video = &imx7_csi_video_ops, - .pad = &imx7_csi_pad_ops, + .video = &imx7_csi_video_ops, + .pad = &imx7_csi_pad_ops, }; static const struct v4l2_subdev_internal_ops imx7_csi_internal_ops = { @@ -1168,6 +1061,19 @@ static const struct v4l2_subdev_internal_ops imx7_csi_internal_ops = { .unregistered = imx7_csi_unregistered, }; +/* ----------------------------------------------------------------------------- + * Media Entity Operations + */ + +static const struct media_entity_operations imx7_csi_entity_ops = { + .link_validate = v4l2_subdev_link_validate, + .get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1, +}; + +/* ----------------------------------------------------------------------------- + * Probe & Remove + */ + static int imx7_csi_notify_bound(struct v4l2_async_notifier *notifier, struct v4l2_subdev *sd, struct v4l2_async_subdev *asd) @@ -1182,7 +1088,10 @@ static int imx7_csi_notify_bound(struct v4l2_async_notifier *notifier, if (sd->entity.function == MEDIA_ENT_F_VID_MUX) sd->grp_id = IMX_MEDIA_GRP_ID_CSI_MUX; - return v4l2_create_fwnode_links_to_pad(sd, sink); + csi->src_sd = sd; + + return v4l2_create_fwnode_links_to_pad(sd, sink, MEDIA_LNK_FL_ENABLED | + MEDIA_LNK_FL_IMMUTABLE); } static const struct v4l2_async_notifier_operations imx7_csi_notify_ops = { @@ -1290,9 +1199,6 @@ static int imx7_csi_probe(struct platform_device *pdev) csi->sd.grp_id = IMX_MEDIA_GRP_ID_CSI; snprintf(csi->sd.name, sizeof(csi->sd.name), "csi"); - v4l2_ctrl_handler_init(&csi->ctrl_hdlr, 0); - csi->sd.ctrl_handler = &csi->ctrl_hdlr; - for (i = 0; i < IMX7_CSI_PADS_NUM; i++) csi->pad[i].flags = (i == IMX7_CSI_PAD_SINK) ? MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE; @@ -1300,7 +1206,7 @@ static int imx7_csi_probe(struct platform_device *pdev) ret = media_entity_pads_init(&csi->sd.entity, IMX7_CSI_PADS_NUM, csi->pad); if (ret < 0) - goto free; + goto cleanup; ret = imx7_csi_async_register(csi); if (ret) @@ -1312,9 +1218,6 @@ subdev_notifier_cleanup: v4l2_async_notifier_unregister(&csi->notifier); v4l2_async_notifier_cleanup(&csi->notifier); -free: - v4l2_ctrl_handler_free(&csi->ctrl_hdlr); - cleanup: v4l2_async_notifier_unregister(&imxmd->notifier); v4l2_async_notifier_cleanup(&imxmd->notifier); @@ -1344,7 +1247,6 @@ static int imx7_csi_remove(struct platform_device *pdev) v4l2_async_notifier_unregister(&csi->notifier); v4l2_async_notifier_cleanup(&csi->notifier); v4l2_async_unregister_subdev(sd); - v4l2_ctrl_handler_free(&csi->ctrl_hdlr); mutex_destroy(&csi->lock); diff --git a/drivers/staging/media/imx/imx7-mipi-csis.c b/drivers/staging/media/imx/imx7-mipi-csis.c index a01a7364b4b9..025fdc488bd6 100644 --- a/drivers/staging/media/imx/imx7-mipi-csis.c +++ b/drivers/staging/media/imx/imx7-mipi-csis.c @@ -24,6 +24,7 @@ #include <linux/reset.h> #include <linux/spinlock.h> +#include <media/v4l2-common.h> #include <media/v4l2-device.h> #include <media/v4l2-fwnode.h> #include <media/v4l2-mc.h> @@ -62,77 +63,107 @@ #define MIPI_CSIS_CLK_CTRL_WCLK_SRC BIT(0) /* CSIS Interrupt mask */ -#define MIPI_CSIS_INTMSK 0x10 -#define MIPI_CSIS_INTMSK_EVEN_BEFORE BIT(31) -#define MIPI_CSIS_INTMSK_EVEN_AFTER BIT(30) -#define MIPI_CSIS_INTMSK_ODD_BEFORE BIT(29) -#define MIPI_CSIS_INTMSK_ODD_AFTER BIT(28) -#define MIPI_CSIS_INTMSK_FRAME_START BIT(24) -#define MIPI_CSIS_INTMSK_FRAME_END BIT(20) -#define MIPI_CSIS_INTMSK_ERR_SOT_HS BIT(16) -#define MIPI_CSIS_INTMSK_ERR_LOST_FS BIT(12) -#define MIPI_CSIS_INTMSK_ERR_LOST_FE BIT(8) -#define MIPI_CSIS_INTMSK_ERR_OVER BIT(4) -#define MIPI_CSIS_INTMSK_ERR_WRONG_CFG BIT(3) -#define MIPI_CSIS_INTMSK_ERR_ECC BIT(2) -#define MIPI_CSIS_INTMSK_ERR_CRC BIT(1) -#define MIPI_CSIS_INTMSK_ERR_UNKNOWN BIT(0) +#define MIPI_CSIS_INT_MSK 0x10 +#define MIPI_CSIS_INT_MSK_EVEN_BEFORE BIT(31) +#define MIPI_CSIS_INT_MSK_EVEN_AFTER BIT(30) +#define MIPI_CSIS_INT_MSK_ODD_BEFORE BIT(29) +#define MIPI_CSIS_INT_MSK_ODD_AFTER BIT(28) +#define MIPI_CSIS_INT_MSK_FRAME_START BIT(24) +#define MIPI_CSIS_INT_MSK_FRAME_END BIT(20) +#define MIPI_CSIS_INT_MSK_ERR_SOT_HS BIT(16) +#define MIPI_CSIS_INT_MSK_ERR_LOST_FS BIT(12) +#define MIPI_CSIS_INT_MSK_ERR_LOST_FE BIT(8) +#define MIPI_CSIS_INT_MSK_ERR_OVER BIT(4) +#define MIPI_CSIS_INT_MSK_ERR_WRONG_CFG BIT(3) +#define MIPI_CSIS_INT_MSK_ERR_ECC BIT(2) +#define MIPI_CSIS_INT_MSK_ERR_CRC BIT(1) +#define MIPI_CSIS_INT_MSK_ERR_UNKNOWN BIT(0) /* CSIS Interrupt source */ -#define MIPI_CSIS_INTSRC 0x14 -#define MIPI_CSIS_INTSRC_EVEN_BEFORE BIT(31) -#define MIPI_CSIS_INTSRC_EVEN_AFTER BIT(30) -#define MIPI_CSIS_INTSRC_EVEN BIT(30) -#define MIPI_CSIS_INTSRC_ODD_BEFORE BIT(29) -#define MIPI_CSIS_INTSRC_ODD_AFTER BIT(28) -#define MIPI_CSIS_INTSRC_ODD (0x3 << 28) -#define MIPI_CSIS_INTSRC_NON_IMAGE_DATA (0xf << 28) -#define MIPI_CSIS_INTSRC_FRAME_START BIT(24) -#define MIPI_CSIS_INTSRC_FRAME_END BIT(20) -#define MIPI_CSIS_INTSRC_ERR_SOT_HS BIT(16) -#define MIPI_CSIS_INTSRC_ERR_LOST_FS BIT(12) -#define MIPI_CSIS_INTSRC_ERR_LOST_FE BIT(8) -#define MIPI_CSIS_INTSRC_ERR_OVER BIT(4) -#define MIPI_CSIS_INTSRC_ERR_WRONG_CFG BIT(3) -#define MIPI_CSIS_INTSRC_ERR_ECC BIT(2) -#define MIPI_CSIS_INTSRC_ERR_CRC BIT(1) -#define MIPI_CSIS_INTSRC_ERR_UNKNOWN BIT(0) -#define MIPI_CSIS_INTSRC_ERRORS 0xfffff +#define MIPI_CSIS_INT_SRC 0x14 +#define MIPI_CSIS_INT_SRC_EVEN_BEFORE BIT(31) +#define MIPI_CSIS_INT_SRC_EVEN_AFTER BIT(30) +#define MIPI_CSIS_INT_SRC_EVEN BIT(30) +#define MIPI_CSIS_INT_SRC_ODD_BEFORE BIT(29) +#define MIPI_CSIS_INT_SRC_ODD_AFTER BIT(28) +#define MIPI_CSIS_INT_SRC_ODD (0x3 << 28) +#define MIPI_CSIS_INT_SRC_NON_IMAGE_DATA (0xf << 28) +#define MIPI_CSIS_INT_SRC_FRAME_START BIT(24) +#define MIPI_CSIS_INT_SRC_FRAME_END BIT(20) +#define MIPI_CSIS_INT_SRC_ERR_SOT_HS BIT(16) +#define MIPI_CSIS_INT_SRC_ERR_LOST_FS BIT(12) +#define MIPI_CSIS_INT_SRC_ERR_LOST_FE BIT(8) +#define MIPI_CSIS_INT_SRC_ERR_OVER BIT(4) +#define MIPI_CSIS_INT_SRC_ERR_WRONG_CFG BIT(3) +#define MIPI_CSIS_INT_SRC_ERR_ECC BIT(2) +#define MIPI_CSIS_INT_SRC_ERR_CRC BIT(1) +#define MIPI_CSIS_INT_SRC_ERR_UNKNOWN BIT(0) +#define MIPI_CSIS_INT_SRC_ERRORS 0xfffff /* D-PHY status control */ -#define MIPI_CSIS_DPHYSTATUS 0x20 -#define MIPI_CSIS_DPHYSTATUS_ULPS_DAT BIT(8) -#define MIPI_CSIS_DPHYSTATUS_STOPSTATE_DAT BIT(4) -#define MIPI_CSIS_DPHYSTATUS_ULPS_CLK BIT(1) -#define MIPI_CSIS_DPHYSTATUS_STOPSTATE_CLK BIT(0) +#define MIPI_CSIS_DPHY_STATUS 0x20 +#define MIPI_CSIS_DPHY_STATUS_ULPS_DAT BIT(8) +#define MIPI_CSIS_DPHY_STATUS_STOPSTATE_DAT BIT(4) +#define MIPI_CSIS_DPHY_STATUS_ULPS_CLK BIT(1) +#define MIPI_CSIS_DPHY_STATUS_STOPSTATE_CLK BIT(0) /* D-PHY common control */ -#define MIPI_CSIS_DPHYCTRL 0x24 -#define MIPI_CSIS_DPHYCTRL_HSS_MASK (0xff << 24) -#define MIPI_CSIS_DPHYCTRL_HSS_OFFSET 24 -#define MIPI_CSIS_DPHYCTRL_SCLKS_MASK (0x3 << 22) -#define MIPI_CSIS_DPHYCTRL_SCLKS_OFFSET 22 -#define MIPI_CSIS_DPHYCTRL_DPDN_SWAP_CLK BIT(6) -#define MIPI_CSIS_DPHYCTRL_DPDN_SWAP_DAT BIT(5) -#define MIPI_CSIS_DPHYCTRL_ENABLE_DAT BIT(1) -#define MIPI_CSIS_DPHYCTRL_ENABLE_CLK BIT(0) -#define MIPI_CSIS_DPHYCTRL_ENABLE (0x1f << 0) +#define MIPI_CSIS_DPHY_CMN_CTRL 0x24 +#define MIPI_CSIS_DPHY_CMN_CTRL_HSSETTLE(n) ((n) << 24) +#define MIPI_CSIS_DPHY_CMN_CTRL_HSSETTLE_MASK GENMASK(31, 24) +#define MIPI_CSIS_DPHY_CMN_CTRL_CLKSETTLE(n) ((n) << 22) +#define MIPI_CSIS_DPHY_CMN_CTRL_CLKSETTLE_MASK GENMASK(23, 22) +#define MIPI_CSIS_DPHY_CMN_CTRL_DPDN_SWAP_CLK BIT(6) +#define MIPI_CSIS_DPHY_CMN_CTRL_DPDN_SWAP_DAT BIT(5) +#define MIPI_CSIS_DPHY_CMN_CTRL_ENABLE_DAT BIT(1) +#define MIPI_CSIS_DPHY_CMN_CTRL_ENABLE_CLK BIT(0) +#define MIPI_CSIS_DPHY_CMN_CTRL_ENABLE (0x1f << 0) /* D-PHY Master and Slave Control register Low */ -#define MIPI_CSIS_DPHYBCTRL_L 0x30 +#define MIPI_CSIS_DPHY_BCTRL_L 0x30 +#define MIPI_CSIS_DPHY_BCTRL_L_USER_DATA_PATTERN_LOW(n) (((n) & 3U) << 30) +#define MIPI_CSIS_DPHY_BCTRL_L_BIAS_REF_VOLT_715MV (0 << 28) +#define MIPI_CSIS_DPHY_BCTRL_L_BIAS_REF_VOLT_724MV (1 << 28) +#define MIPI_CSIS_DPHY_BCTRL_L_BIAS_REF_VOLT_733MV (2 << 28) +#define MIPI_CSIS_DPHY_BCTRL_L_BIAS_REF_VOLT_706MV (3 << 28) +#define MIPI_CSIS_DPHY_BCTRL_L_BGR_CHOPPER_FREQ_3MHZ (0 << 27) +#define MIPI_CSIS_DPHY_BCTRL_L_BGR_CHOPPER_FREQ_1_5MHZ (1 << 27) +#define MIPI_CSIS_DPHY_BCTRL_L_VREG12_EXTPWR_EN_CTL BIT(26) +#define MIPI_CSIS_DPHY_BCTRL_L_REG_12P_LVL_CTL_1_2V (0 << 24) +#define MIPI_CSIS_DPHY_BCTRL_L_REG_12P_LVL_CTL_1_23V (1 << 24) +#define MIPI_CSIS_DPHY_BCTRL_L_REG_12P_LVL_CTL_1_17V (2 << 24) +#define MIPI_CSIS_DPHY_BCTRL_L_REG_12P_LVL_CTL_1_26V (3 << 24) +#define MIPI_CSIS_DPHY_BCTRL_L_REG_1P2_LVL_SEL BIT(23) +#define MIPI_CSIS_DPHY_BCTRL_L_LP_RX_HYS_LVL_80MV (0 << 21) +#define MIPI_CSIS_DPHY_BCTRL_L_LP_RX_HYS_LVL_100MV (1 << 21) +#define MIPI_CSIS_DPHY_BCTRL_L_LP_RX_HYS_LVL_120MV (2 << 21) +#define MIPI_CSIS_DPHY_BCTRL_L_LP_RX_HYS_LVL_140MV (3 << 21) +#define MIPI_CSIS_DPHY_BCTRL_L_VREF_SRC_SEL BIT(20) +#define MIPI_CSIS_DPHY_BCTRL_L_LP_RX_VREF_LVL_715MV (0 << 18) +#define MIPI_CSIS_DPHY_BCTRL_L_LP_RX_VREF_LVL_743MV (1 << 18) +#define MIPI_CSIS_DPHY_BCTRL_L_LP_RX_VREF_LVL_650MV (2 << 18) +#define MIPI_CSIS_DPHY_BCTRL_L_LP_RX_VREF_LVL_682MV (3 << 18) +#define MIPI_CSIS_DPHY_BCTRL_L_LP_RX_PULSE_REJECT BIT(17) +#define MIPI_CSIS_DPHY_BCTRL_L_MSTRCLK_LP_SLEW_RATE_DOWN_0 (0 << 15) +#define MIPI_CSIS_DPHY_BCTRL_L_MSTRCLK_LP_SLEW_RATE_DOWN_15P (1 << 15) +#define MIPI_CSIS_DPHY_BCTRL_L_MSTRCLK_LP_SLEW_RATE_DOWN_30P (3 << 15) +#define MIPI_CSIS_DPHY_BCTRL_L_MSTRCLK_LP_SLEW_RATE_UP BIT(14) +#define MIPI_CSIS_DPHY_BCTRL_L_LP_CD_HYS_60MV (0 << 13) +#define MIPI_CSIS_DPHY_BCTRL_L_LP_CD_HYS_70MV (1 << 13) +#define MIPI_CSIS_DPHY_BCTRL_L_BGR_CHOPPER_EN BIT(12) +#define MIPI_CSIS_DPHY_BCTRL_L_ERRCONTENTION_LP_EN BIT(11) +#define MIPI_CSIS_DPHY_BCTRL_L_TXTRIGGER_CLK_EN BIT(10) +#define MIPI_CSIS_DPHY_BCTRL_L_B_DPHYCTRL(n) (((n) * 25 / 1000000) << 0) + /* D-PHY Master and Slave Control register High */ -#define MIPI_CSIS_DPHYBCTRL_H 0x34 +#define MIPI_CSIS_DPHY_BCTRL_H 0x34 /* D-PHY Slave Control register Low */ -#define MIPI_CSIS_DPHYSCTRL_L 0x38 +#define MIPI_CSIS_DPHY_SCTRL_L 0x38 /* D-PHY Slave Control register High */ -#define MIPI_CSIS_DPHYSCTRL_H 0x3c +#define MIPI_CSIS_DPHY_SCTRL_H 0x3c /* ISP Configuration register */ -#define MIPI_CSIS_ISPCONFIG_CH0 0x40 -#define MIPI_CSIS_ISPCONFIG_CH1 0x50 -#define MIPI_CSIS_ISPCONFIG_CH2 0x60 -#define MIPI_CSIS_ISPCONFIG_CH3 0x70 - +#define MIPI_CSIS_ISP_CONFIG_CH(n) (0x40 + (n) * 0x10) #define MIPI_CSIS_ISPCFG_MEM_FULL_GAP_MSK (0xff << 24) #define MIPI_CSIS_ISPCFG_MEM_FULL_GAP(x) ((x) << 24) #define MIPI_CSIS_ISPCFG_DOUBLE_CMPNT BIT(12) @@ -142,28 +173,28 @@ #define MIPI_CSIS_ISPCFG_FMT_RAW10 (0x2b << 2) #define MIPI_CSIS_ISPCFG_FMT_RAW12 (0x2c << 2) #define MIPI_CSIS_ISPCFG_FMT_RAW14 (0x2d << 2) - /* User defined formats, x = 1...4 */ #define MIPI_CSIS_ISPCFG_FMT_USER(x) ((0x30 + (x) - 1) << 2) #define MIPI_CSIS_ISPCFG_FMT_MASK (0x3f << 2) /* ISP Image Resolution register */ -#define MIPI_CSIS_ISPRESOL_CH0 0x44 -#define MIPI_CSIS_ISPRESOL_CH1 0x54 -#define MIPI_CSIS_ISPRESOL_CH2 0x64 -#define MIPI_CSIS_ISPRESOL_CH3 0x74 +#define MIPI_CSIS_ISP_RESOL_CH(n) (0x44 + (n) * 0x10) #define CSIS_MAX_PIX_WIDTH 0xffff #define CSIS_MAX_PIX_HEIGHT 0xffff /* ISP SYNC register */ -#define MIPI_CSIS_ISPSYNC_CH0 0x48 -#define MIPI_CSIS_ISPSYNC_CH1 0x58 -#define MIPI_CSIS_ISPSYNC_CH2 0x68 -#define MIPI_CSIS_ISPSYNC_CH3 0x78 +#define MIPI_CSIS_ISP_SYNC_CH(n) (0x48 + (n) * 0x10) +#define MIPI_CSIS_ISP_SYNC_HSYNC_LINTV_OFFSET 18 +#define MIPI_CSIS_ISP_SYNC_VSYNC_SINTV_OFFSET 12 +#define MIPI_CSIS_ISP_SYNC_VSYNC_EINTV_OFFSET 0 + +/* ISP shadow registers */ +#define MIPI_CSIS_SDW_CONFIG_CH(n) (0x80 + (n) * 0x10) +#define MIPI_CSIS_SDW_RESOL_CH(n) (0x84 + (n) * 0x10) +#define MIPI_CSIS_SDW_SYNC_CH(n) (0x88 + (n) * 0x10) -#define MIPI_CSIS_ISPSYNC_HSYNC_LINTV_OFFSET 18 -#define MIPI_CSIS_ISPSYNC_VSYNC_SINTV_OFFSET 12 -#define MIPI_CSIS_ISPSYNC_VSYNC_EINTV_OFFSET 0 +/* Debug control register */ +#define MIPI_CSIS_DBG_CTRL 0xc0 /* Non-image packet data buffers */ #define MIPI_CSIS_PKTDATA_ODD 0x2000 @@ -186,27 +217,37 @@ struct mipi_csis_event { static const struct mipi_csis_event mipi_csis_events[] = { /* Errors */ - { MIPI_CSIS_INTSRC_ERR_SOT_HS, "SOT Error" }, - { MIPI_CSIS_INTSRC_ERR_LOST_FS, "Lost Frame Start Error" }, - { MIPI_CSIS_INTSRC_ERR_LOST_FE, "Lost Frame End Error" }, - { MIPI_CSIS_INTSRC_ERR_OVER, "FIFO Overflow Error" }, - { MIPI_CSIS_INTSRC_ERR_WRONG_CFG, "Wrong Configuration Error" }, - { MIPI_CSIS_INTSRC_ERR_ECC, "ECC Error" }, - { MIPI_CSIS_INTSRC_ERR_CRC, "CRC Error" }, - { MIPI_CSIS_INTSRC_ERR_UNKNOWN, "Unknown Error" }, + { MIPI_CSIS_INT_SRC_ERR_SOT_HS, "SOT Error" }, + { MIPI_CSIS_INT_SRC_ERR_LOST_FS, "Lost Frame Start Error" }, + { MIPI_CSIS_INT_SRC_ERR_LOST_FE, "Lost Frame End Error" }, + { MIPI_CSIS_INT_SRC_ERR_OVER, "FIFO Overflow Error" }, + { MIPI_CSIS_INT_SRC_ERR_WRONG_CFG, "Wrong Configuration Error" }, + { MIPI_CSIS_INT_SRC_ERR_ECC, "ECC Error" }, + { MIPI_CSIS_INT_SRC_ERR_CRC, "CRC Error" }, + { MIPI_CSIS_INT_SRC_ERR_UNKNOWN, "Unknown Error" }, /* Non-image data receive events */ - { MIPI_CSIS_INTSRC_EVEN_BEFORE, "Non-image data before even frame" }, - { MIPI_CSIS_INTSRC_EVEN_AFTER, "Non-image data after even frame" }, - { MIPI_CSIS_INTSRC_ODD_BEFORE, "Non-image data before odd frame" }, - { MIPI_CSIS_INTSRC_ODD_AFTER, "Non-image data after odd frame" }, + { MIPI_CSIS_INT_SRC_EVEN_BEFORE, "Non-image data before even frame" }, + { MIPI_CSIS_INT_SRC_EVEN_AFTER, "Non-image data after even frame" }, + { MIPI_CSIS_INT_SRC_ODD_BEFORE, "Non-image data before odd frame" }, + { MIPI_CSIS_INT_SRC_ODD_AFTER, "Non-image data after odd frame" }, /* Frame start/end */ - { MIPI_CSIS_INTSRC_FRAME_START, "Frame Start" }, - { MIPI_CSIS_INTSRC_FRAME_END, "Frame End" }, + { MIPI_CSIS_INT_SRC_FRAME_START, "Frame Start" }, + { MIPI_CSIS_INT_SRC_FRAME_END, "Frame End" }, }; #define MIPI_CSIS_NUM_EVENTS ARRAY_SIZE(mipi_csis_events) -static const char * const mipi_csis_clk_id[] = {"pclk", "wrap", "phy"}; +enum mipi_csis_clk { + MIPI_CSIS_CLK_PCLK, + MIPI_CSIS_CLK_WRAP, + MIPI_CSIS_CLK_PHY, +}; + +static const char * const mipi_csis_clk_id[] = { + "pclk", + "wrap", + "phy", +}; struct csis_hw_reset { struct regmap *src; @@ -229,7 +270,6 @@ struct csi_state { struct platform_device *pdev; struct phy *phy; void __iomem *regs; - struct clk *wrap_clk; int irq; u32 flags; @@ -264,13 +304,9 @@ struct csis_pix_format { static const struct csis_pix_format mipi_csis_formats[] = { /* YUV formats. */ { - .code = MEDIA_BUS_FMT_UYVY8_2X8, + .code = MEDIA_BUS_FMT_UYVY8_1X16, .fmt_reg = MIPI_CSIS_ISPCFG_FMT_YCBCR422_8BIT, - .width = 8, - }, { - .code = MEDIA_BUS_FMT_UYVY10_2X10, - .fmt_reg = MIPI_CSIS_ISPCFG_FMT_YCBCR422_8BIT, - .width = 10, + .width = 16, }, /* RAW (Bayer and greyscale) formats. */ { @@ -352,8 +388,15 @@ static const struct csis_pix_format mipi_csis_formats[] = { } }; -#define mipi_csis_write(__csis, __r, __v) writel(__v, (__csis)->regs + (__r)) -#define mipi_csis_read(__csis, __r) readl((__csis)->regs + (__r)) +static inline void mipi_csis_write(struct csi_state *state, u32 reg, u32 val) +{ + writel(val, state->regs + reg); +} + +static inline u32 mipi_csis_read(struct csi_state *state, u32 reg) +{ + return readl(state->regs + reg); +} static int mipi_csis_dump_regs(struct csi_state *state) { @@ -364,23 +407,25 @@ static int mipi_csis_dump_regs(struct csi_state *state) u32 offset; const char * const name; } registers[] = { - { 0x04, "CTRL" }, - { 0x24, "DPHYCTRL" }, - { 0x08, "CLKCTRL" }, - { 0x20, "DPHYSTS" }, - { 0x10, "INTMSK" }, - { 0x40, "CONFIG_CH0" }, - { 0x44, "RESOL_CH0" }, - { 0xC0, "DBG_CONFIG" }, - { 0x38, "DPHYSLAVE_L" }, - { 0x3C, "DPHYSLAVE_H" }, + { MIPI_CSIS_CMN_CTRL, "CMN_CTRL" }, + { MIPI_CSIS_CLK_CTRL, "CLK_CTRL" }, + { MIPI_CSIS_INT_MSK, "INT_MSK" }, + { MIPI_CSIS_DPHY_STATUS, "DPHY_STATUS" }, + { MIPI_CSIS_DPHY_CMN_CTRL, "DPHY_CMN_CTRL" }, + { MIPI_CSIS_DPHY_SCTRL_L, "DPHY_SCTRL_L" }, + { MIPI_CSIS_DPHY_SCTRL_H, "DPHY_SCTRL_H" }, + { MIPI_CSIS_ISP_CONFIG_CH(0), "ISP_CONFIG_CH0" }, + { MIPI_CSIS_ISP_RESOL_CH(0), "ISP_RESOL_CH0" }, + { MIPI_CSIS_SDW_CONFIG_CH(0), "SDW_CONFIG_CH0" }, + { MIPI_CSIS_SDW_RESOL_CH(0), "SDW_RESOL_CH0" }, + { MIPI_CSIS_DBG_CTRL, "DBG_CTRL" }, }; dev_info(dev, "--- REGISTERS ---\n"); for (i = 0; i < ARRAY_SIZE(registers); i++) { cfg = mipi_csis_read(state, registers[i].offset); - dev_info(dev, "%12s: 0x%08x\n", registers[i].name, cfg); + dev_info(dev, "%14s: 0x%08x\n", registers[i].name, cfg); } return 0; @@ -409,7 +454,7 @@ static const struct csis_pix_format *find_csis_format(u32 code) static void mipi_csis_enable_interrupts(struct csi_state *state, bool on) { - mipi_csis_write(state, MIPI_CSIS_INTMSK, on ? 0xffffffff : 0); + mipi_csis_write(state, MIPI_CSIS_INT_MSK, on ? 0xffffffff : 0); } static void mipi_csis_sw_reset(struct csi_state *state) @@ -451,13 +496,13 @@ static void mipi_csis_system_enable(struct csi_state *state, int on) val &= ~MIPI_CSIS_CMN_CTRL_ENABLE; mipi_csis_write(state, MIPI_CSIS_CMN_CTRL, val); - val = mipi_csis_read(state, MIPI_CSIS_DPHYCTRL); - val &= ~MIPI_CSIS_DPHYCTRL_ENABLE; + val = mipi_csis_read(state, MIPI_CSIS_DPHY_CMN_CTRL); + val &= ~MIPI_CSIS_DPHY_CMN_CTRL_ENABLE; if (on) { mask = (1 << (state->bus.num_data_lanes + 1)) - 1; - val |= (mask & MIPI_CSIS_DPHYCTRL_ENABLE); + val |= (mask & MIPI_CSIS_DPHY_CMN_CTRL_ENABLE); } - mipi_csis_write(state, MIPI_CSIS_DPHYCTRL, val); + mipi_csis_write(state, MIPI_CSIS_DPHY_CMN_CTRL, val); } /* Called with the state.lock mutex held */ @@ -467,23 +512,47 @@ static void __mipi_csis_set_format(struct csi_state *state) u32 val; /* Color format */ - val = mipi_csis_read(state, MIPI_CSIS_ISPCONFIG_CH0); + val = mipi_csis_read(state, MIPI_CSIS_ISP_CONFIG_CH(0)); val &= ~(MIPI_CSIS_ISPCFG_ALIGN_32BIT | MIPI_CSIS_ISPCFG_FMT_MASK); val |= state->csis_fmt->fmt_reg; - mipi_csis_write(state, MIPI_CSIS_ISPCONFIG_CH0, val); + mipi_csis_write(state, MIPI_CSIS_ISP_CONFIG_CH(0), val); /* Pixel resolution */ val = mf->width | (mf->height << 16); - mipi_csis_write(state, MIPI_CSIS_ISPRESOL_CH0, val); + mipi_csis_write(state, MIPI_CSIS_ISP_RESOL_CH(0), val); } -static void mipi_csis_set_hsync_settle(struct csi_state *state, int hs_settle) +static int mipi_csis_calculate_params(struct csi_state *state) { - u32 val = mipi_csis_read(state, MIPI_CSIS_DPHYCTRL); + s64 link_freq; + u32 lane_rate; + + /* Calculate the line rate from the pixel rate. */ + link_freq = v4l2_get_link_freq(state->src_sd->ctrl_handler, + state->csis_fmt->width, + state->bus.num_data_lanes * 2); + if (link_freq < 0) { + dev_err(state->dev, "Unable to obtain link frequency: %d\n", + (int)link_freq); + return link_freq; + } - val = (val & ~MIPI_CSIS_DPHYCTRL_HSS_MASK) | (hs_settle << 24); + lane_rate = link_freq * 2; + + if (lane_rate < 80000000 || lane_rate > 1500000000) { + dev_dbg(state->dev, "Out-of-bound lane rate %u\n", lane_rate); + return -EINVAL; + } - mipi_csis_write(state, MIPI_CSIS_DPHYCTRL, val); + /* + * The HSSETTLE counter value is document in a table, but can also + * easily be calculated. + */ + state->hs_settle = (lane_rate - 5000000) / 45000000; + dev_dbg(state->dev, "lane rate %u, Ths_settle %u\n", + lane_rate, state->hs_settle); + + return 0; } static void mipi_csis_set_params(struct csi_state *state) @@ -499,26 +568,29 @@ static void mipi_csis_set_params(struct csi_state *state) __mipi_csis_set_format(state); - mipi_csis_set_hsync_settle(state, state->hs_settle); + mipi_csis_write(state, MIPI_CSIS_DPHY_CMN_CTRL, + MIPI_CSIS_DPHY_CMN_CTRL_HSSETTLE(state->hs_settle)); - val = (0 << MIPI_CSIS_ISPSYNC_HSYNC_LINTV_OFFSET) | - (0 << MIPI_CSIS_ISPSYNC_VSYNC_SINTV_OFFSET) | - (0 << MIPI_CSIS_ISPSYNC_VSYNC_EINTV_OFFSET); - mipi_csis_write(state, MIPI_CSIS_ISPSYNC_CH0, val); + val = (0 << MIPI_CSIS_ISP_SYNC_HSYNC_LINTV_OFFSET) + | (0 << MIPI_CSIS_ISP_SYNC_VSYNC_SINTV_OFFSET) + | (0 << MIPI_CSIS_ISP_SYNC_VSYNC_EINTV_OFFSET); + mipi_csis_write(state, MIPI_CSIS_ISP_SYNC_CH(0), val); val = mipi_csis_read(state, MIPI_CSIS_CLK_CTRL); - val &= ~MIPI_CSIS_CLK_CTRL_WCLK_SRC; - if (state->wrap_clk) - val |= MIPI_CSIS_CLK_CTRL_WCLK_SRC; - else - val &= ~MIPI_CSIS_CLK_CTRL_WCLK_SRC; - + val |= MIPI_CSIS_CLK_CTRL_WCLK_SRC; val |= MIPI_CSIS_CLK_CTRL_CLKGATE_TRAIL_CH0(15); val &= ~MIPI_CSIS_CLK_CTRL_CLKGATE_EN_MSK; mipi_csis_write(state, MIPI_CSIS_CLK_CTRL, val); - mipi_csis_write(state, MIPI_CSIS_DPHYBCTRL_L, 0x1f4); - mipi_csis_write(state, MIPI_CSIS_DPHYBCTRL_H, 0); + mipi_csis_write(state, MIPI_CSIS_DPHY_BCTRL_L, + MIPI_CSIS_DPHY_BCTRL_L_BIAS_REF_VOLT_715MV | + MIPI_CSIS_DPHY_BCTRL_L_BGR_CHOPPER_FREQ_3MHZ | + MIPI_CSIS_DPHY_BCTRL_L_REG_12P_LVL_CTL_1_2V | + MIPI_CSIS_DPHY_BCTRL_L_LP_RX_HYS_LVL_80MV | + MIPI_CSIS_DPHY_BCTRL_L_LP_RX_VREF_LVL_715MV | + MIPI_CSIS_DPHY_BCTRL_L_LP_CD_HYS_60MV | + MIPI_CSIS_DPHY_BCTRL_L_B_DPHYCTRL(20000000)); + mipi_csis_write(state, MIPI_CSIS_DPHY_BCTRL_H, 0); /* Update the shadow register. */ val = mipi_csis_read(state, MIPI_CSIS_CMN_CTRL); @@ -557,12 +629,9 @@ static int mipi_csis_clk_get(struct csi_state *state) if (ret < 0) return ret; - state->wrap_clk = devm_clk_get(dev, "wrap"); - if (IS_ERR(state->wrap_clk)) - return PTR_ERR(state->wrap_clk); - /* Set clock rate */ - ret = clk_set_rate(state->wrap_clk, state->clk_frequency); + ret = clk_set_rate(state->clks[MIPI_CSIS_CLK_WRAP].clk, + state->clk_frequency); if (ret < 0) dev_err(dev, "set rate=%d failed: %d\n", state->clk_frequency, ret); @@ -617,21 +686,27 @@ static void mipi_csis_log_counters(struct csi_state *state, bool non_errors) static int mipi_csis_s_stream(struct v4l2_subdev *mipi_sd, int enable) { struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); - int ret = 0; + int ret; if (enable) { + ret = mipi_csis_calculate_params(state); + if (ret < 0) + return ret; + mipi_csis_clear_counters(state); + ret = pm_runtime_get_sync(&state->pdev->dev); if (ret < 0) { pm_runtime_put_noidle(&state->pdev->dev); return ret; } ret = v4l2_subdev_call(state->src_sd, core, s_power, 1); - if (ret < 0) - return ret; + if (ret < 0 && ret != -ENOIOCTLCMD) + goto done; } mutex_lock(&state->lock); + if (enable) { if (state->flags & ST_SUSPENDED) { ret = -EBUSY; @@ -649,6 +724,8 @@ static int mipi_csis_s_stream(struct v4l2_subdev *mipi_sd, int enable) } else { v4l2_subdev_call(state->src_sd, video, s_stream, 0); ret = v4l2_subdev_call(state->src_sd, core, s_power, 0); + if (ret == -ENOIOCTLCMD) + ret = 0; mipi_csis_stop_stream(state); state->flags &= ~ST_STREAMING; if (state->debug) @@ -657,7 +734,9 @@ static int mipi_csis_s_stream(struct v4l2_subdev *mipi_sd, int enable) unlock: mutex_unlock(&state->lock); - if (!enable) + +done: + if (!enable || ret < 0) pm_runtime_put(&state->pdev->dev); return ret; @@ -670,30 +749,26 @@ static int mipi_csis_link_setup(struct media_entity *entity, struct v4l2_subdev *mipi_sd = media_entity_to_v4l2_subdev(entity); struct csi_state *state = mipi_sd_to_csis_state(mipi_sd); struct v4l2_subdev *remote_sd; - int ret = 0; dev_dbg(state->dev, "link setup %s -> %s", remote_pad->entity->name, local_pad->entity->name); + /* We only care about the link to the source. */ + if (!(local_pad->flags & MEDIA_PAD_FL_SINK)) + return 0; + remote_sd = media_entity_to_v4l2_subdev(remote_pad->entity); - mutex_lock(&state->lock); + if (flags & MEDIA_LNK_FL_ENABLED) { + if (state->src_sd) + return -EBUSY; - if (local_pad->flags & MEDIA_PAD_FL_SINK) { - if (flags & MEDIA_LNK_FL_ENABLED) { - if (state->src_sd) { - ret = -EBUSY; - goto out; - } - state->src_sd = remote_sd; - } else { - state->src_sd = NULL; - } + state->src_sd = remote_sd; + } else { + state->src_sd = NULL; } -out: - mutex_unlock(&state->lock); - return ret; + return 0; } static struct v4l2_mbus_framefmt * @@ -719,7 +794,7 @@ static int mipi_csis_init_cfg(struct v4l2_subdev *mipi_sd, which = cfg ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE; fmt_sink = mipi_csis_get_format(state, cfg, which, CSIS_PAD_SINK); - fmt_sink->code = MEDIA_BUS_FMT_UYVY8_2X8; + fmt_sink->code = MEDIA_BUS_FMT_UYVY8_1X16; fmt_sink->width = MIPI_CSIS_DEF_PIX_WIDTH; fmt_sink->height = MIPI_CSIS_DEF_PIX_HEIGHT; fmt_sink->field = V4L2_FIELD_NONE; @@ -831,25 +906,25 @@ static int mipi_csis_set_fmt(struct v4l2_subdev *mipi_sd, */ switch (csis_fmt->width % 8) { case 0: - align = 1; + align = 0; break; case 4: - align = 2; + align = 1; break; case 2: case 6: - align = 4; + align = 2; break; case 1: case 3: case 5: case 7: - align = 8; + align = 3; break; } v4l_bound_align_image(&fmt->width, 1, CSIS_MAX_PIX_WIDTH, align, - &fmt->height, 1, CSIS_MAX_PIX_HEIGHT, 1, 0); + &fmt->height, 1, CSIS_MAX_PIX_HEIGHT, 0, 0); sdformat->format = *fmt; @@ -887,12 +962,12 @@ static irqreturn_t mipi_csis_irq_handler(int irq, void *dev_id) unsigned int i; u32 status; - status = mipi_csis_read(state, MIPI_CSIS_INTSRC); + status = mipi_csis_read(state, MIPI_CSIS_INT_SRC); spin_lock_irqsave(&state->slock, flags); /* Update the event/error counters */ - if ((status & MIPI_CSIS_INTSRC_ERRORS) || state->debug) { + if ((status & MIPI_CSIS_INT_SRC_ERRORS) || state->debug) { for (i = 0; i < MIPI_CSIS_NUM_EVENTS; i++) { if (!(status & state->events[i].mask)) continue; @@ -901,7 +976,7 @@ static irqreturn_t mipi_csis_irq_handler(int irq, void *dev_id) } spin_unlock_irqrestore(&state->slock, flags); - mipi_csis_write(state, MIPI_CSIS_INTSRC, status); + mipi_csis_write(state, MIPI_CSIS_INT_SRC, status); return IRQ_HANDLED; } @@ -943,13 +1018,10 @@ static int mipi_csis_parse_dt(struct platform_device *pdev, state->clk_frequency = DEFAULT_SCLK_CSIS_FREQ; /* Get MIPI PHY resets */ - state->mrst = devm_reset_control_get_exclusive(&pdev->dev, "mrst"); + state->mrst = devm_reset_control_get_exclusive(&pdev->dev, NULL); if (IS_ERR(state->mrst)) return PTR_ERR(state->mrst); - /* Get MIPI CSI-2 bus configuration from the endpoint node. */ - of_property_read_u32(node, "fsl,csis-hs-settle", &state->hs_settle); - return 0; } @@ -962,7 +1034,7 @@ static int mipi_csis_notify_bound(struct v4l2_async_notifier *notifier, struct csi_state *state = mipi_notifier_to_csis_state(notifier); struct media_pad *sink = &state->mipi_sd.entity.pads[CSIS_PAD_SINK]; - return v4l2_create_fwnode_links_to_pad(sd, sink); + return v4l2_create_fwnode_links_to_pad(sd, sink, 0); } static const struct v4l2_async_notifier_operations mipi_csis_notify_ops = { @@ -993,8 +1065,10 @@ static int mipi_csis_subdev_init(struct v4l2_subdev *mipi_sd, v4l2_set_subdevdata(mipi_sd, &pdev->dev); - state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK; - state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; + state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK + | MEDIA_PAD_FL_MUST_CONNECT; + state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE + | MEDIA_PAD_FL_MUST_CONNECT; return media_entity_pads_init(&mipi_sd->entity, CSIS_PADS_NUM, state->pads); } @@ -1147,9 +1221,8 @@ static int mipi_csis_probe(struct platform_device *pdev) goto unregister_all; } - dev_info(&pdev->dev, "lanes: %d, hs_settle: %d, wclk: %d, freq: %u\n", - state->bus.num_data_lanes, state->hs_settle, - state->wrap_clk ? 1 : 0, state->clk_frequency); + dev_info(&pdev->dev, "lanes: %d, freq: %u\n", + state->bus.num_data_lanes, state->clk_frequency); return 0; diff --git a/drivers/staging/media/ipu3/include/intel-ipu3.h b/drivers/staging/media/ipu3/include/intel-ipu3.h index edd8edda0647..9b644fb23dde 100644 --- a/drivers/staging/media/ipu3/include/intel-ipu3.h +++ b/drivers/staging/media/ipu3/include/intel-ipu3.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* Copyright (C) 2017 - 2018 Intel Corporation */ #ifndef __IPU3_UAPI_H diff --git a/drivers/staging/media/ipu3/ipu3-css-fw.h b/drivers/staging/media/ipu3/ipu3-css-fw.h index 79ffa7045139..3c078f15a295 100644 --- a/drivers/staging/media/ipu3/ipu3-css-fw.h +++ b/drivers/staging/media/ipu3/ipu3-css-fw.h @@ -148,6 +148,7 @@ union imgu_fw_union { struct imgu_fw_info { size_t header_size; /* size of fw header */ u32 type __aligned(8); /* enum imgu_fw_type */ + union imgu_fw_union info; /* Binary info */ struct imgu_abi_blob_info blob; /* Blob info */ /* Dynamic part */ diff --git a/drivers/staging/media/ipu3/ipu3-css-pool.h b/drivers/staging/media/ipu3/ipu3-css-pool.h index a8ccd4f70320..35519a08c08c 100644 --- a/drivers/staging/media/ipu3/ipu3-css-pool.h +++ b/drivers/staging/media/ipu3/ipu3-css-pool.h @@ -10,7 +10,7 @@ struct imgu_device; #define IPU3_CSS_POOL_SIZE 4 /** - * imgu_css_map - store DMA mapping info for buffer + * struct imgu_css_map - store DMA mapping info for buffer * * @size: size of the buffer in bytes. * @vaddr: kernel virtual address. @@ -24,7 +24,7 @@ struct imgu_css_map { }; /** - * imgu_css_pool - circular buffer pool definition + * struct imgu_css_pool - circular buffer pool definition * * @entry: array with IPU3_CSS_POOL_SIZE elements. * @entry.param: a &struct imgu_css_map for storing the mem mapping. diff --git a/drivers/staging/media/ipu3/ipu3-v4l2.c b/drivers/staging/media/ipu3/ipu3-v4l2.c index 60aa02eb7d2a..6d9c49b39531 100644 --- a/drivers/staging/media/ipu3/ipu3-v4l2.c +++ b/drivers/staging/media/ipu3/ipu3-v4l2.c @@ -686,6 +686,7 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node, dev_dbg(dev, "IPU3 pipe %u pipe_id = %u", pipe, css_pipe->pipe_id); + css_q = imgu_node_to_queue(node); for (i = 0; i < IPU3_CSS_QUEUES; i++) { unsigned int inode = imgu_map_node(imgu, i); @@ -693,6 +694,18 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node, if (inode == IMGU_NODE_STAT_3A || inode == IMGU_NODE_PARAMS) continue; + /* CSS expects some format on OUT queue */ + if (i != IPU3_CSS_QUEUE_OUT && + !imgu_pipe->nodes[inode].enabled) { + fmts[i] = NULL; + continue; + } + + if (i == css_q) { + fmts[i] = &f->fmt.pix_mp; + continue; + } + if (try) { fmts[i] = kmemdup(&imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp, sizeof(struct v4l2_pix_format_mplane), @@ -705,10 +718,6 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node, fmts[i] = &imgu_pipe->nodes[inode].vdev_fmt.fmt.pix_mp; } - /* CSS expects some format on OUT queue */ - if (i != IPU3_CSS_QUEUE_OUT && - !imgu_pipe->nodes[inode].enabled) - fmts[i] = NULL; } if (!try) { @@ -725,16 +734,10 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node, rects[IPU3_CSS_RECT_GDC]->height = pad_fmt.height; } - /* - * imgu doesn't set the node to the value given by user - * before we return success from this function, so set it here. - */ - css_q = imgu_node_to_queue(node); if (!fmts[css_q]) { ret = -EINVAL; goto out; } - *fmts[css_q] = f->fmt.pix_mp; if (try) ret = imgu_css_fmt_try(&imgu->css, fmts, rects, pipe); @@ -745,15 +748,18 @@ static int imgu_fmt(struct imgu_device *imgu, unsigned int pipe, int node, if (ret < 0) goto out; - if (try) - f->fmt.pix_mp = *fmts[css_q]; - else - f->fmt = imgu_pipe->nodes[node].vdev_fmt.fmt; + /* + * imgu doesn't set the node to the value given by user + * before we return success from this function, so set it here. + */ + if (!try) + imgu_pipe->nodes[node].vdev_fmt.fmt.pix_mp = f->fmt.pix_mp; out: if (try) { for (i = 0; i < IPU3_CSS_QUEUES; i++) - kfree(fmts[i]); + if (i != css_q) + kfree(fmts[i]); } return ret; diff --git a/drivers/staging/media/ipu3/ipu3.h b/drivers/staging/media/ipu3/ipu3.h index 8cd6a0077d99..eb46b527dd23 100644 --- a/drivers/staging/media/ipu3/ipu3.h +++ b/drivers/staging/media/ipu3/ipu3.h @@ -63,11 +63,6 @@ struct imgu_node_mapping { const char *name; }; -/** - * struct imgu_video_device - * each node registers as video device and maintains its - * own vb2_queue. - */ struct imgu_video_device { const char *name; bool output; diff --git a/drivers/staging/media/meson/vdec/codec_hevc_common.h b/drivers/staging/media/meson/vdec/codec_hevc_common.h index 88e4379ba1ee..cf072b8a9da2 100644 --- a/drivers/staging/media/meson/vdec/codec_hevc_common.h +++ b/drivers/staging/media/meson/vdec/codec_hevc_common.h @@ -49,9 +49,7 @@ static inline int codec_hevc_use_mmu(u32 revision, u32 pixfmt, int is_10bit) codec_hevc_use_fbc(pixfmt, is_10bit); } -/** - * Configure decode head read mode - */ +/* Configure decode head read mode */ void codec_hevc_setup_decode_head(struct amvdec_session *sess, int is_10bit); void codec_hevc_free_fbc_buffers(struct amvdec_session *sess, diff --git a/drivers/staging/media/meson/vdec/vdec.c b/drivers/staging/media/meson/vdec/vdec.c index 5d4db7a5b4b5..e51d69c4729d 100644 --- a/drivers/staging/media/meson/vdec/vdec.c +++ b/drivers/staging/media/meson/vdec/vdec.c @@ -1008,17 +1008,13 @@ static int vdec_probe(struct platform_device *pdev) r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dos"); core->dos_base = devm_ioremap_resource(dev, r); - if (IS_ERR(core->dos_base)) { - dev_err(dev, "Couldn't remap DOS memory\n"); + if (IS_ERR(core->dos_base)) return PTR_ERR(core->dos_base); - } r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "esparser"); core->esparser_base = devm_ioremap_resource(dev, r); - if (IS_ERR(core->esparser_base)) { - dev_err(dev, "Couldn't remap ESPARSER memory\n"); + if (IS_ERR(core->esparser_base)) return PTR_ERR(core->esparser_base); - } core->regmap_ao = syscon_regmap_lookup_by_phandle(dev->of_node, diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index dae9073e7d3c..68588e9dab0b 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c @@ -456,6 +456,8 @@ static int iss_pipeline_enable(struct iss_pipeline *pipe, pipe->do_propagation = false; + mutex_lock(&iss->media_dev.graph_mutex); + entity = &pipe->output->video.entity; while (1) { pad = &entity->pads[0]; @@ -472,6 +474,7 @@ static int iss_pipeline_enable(struct iss_pipeline *pipe, ret = v4l2_subdev_call(subdev, video, s_stream, mode); if (ret < 0 && ret != -ENOIOCTLCMD) { iss_pipeline_disable(pipe, entity); + mutex_unlock(&iss->media_dev.graph_mutex); return ret; } @@ -480,7 +483,9 @@ static int iss_pipeline_enable(struct iss_pipeline *pipe, pipe->do_propagation = true; } + mutex_unlock(&iss->media_dev.graph_mutex); iss_print_status(pipe->output->iss); + return 0; } @@ -960,7 +965,7 @@ iss_register_subdev_group(struct iss_device *iss, } subdev = v4l2_i2c_new_subdev_board(&iss->v4l2_dev, adapter, - board_info->board_info, NULL); + board_info->board_info, NULL); if (!subdev) { dev_err(iss->dev, "Unable to register subdev %s\n", board_info->board_info->type); @@ -1236,8 +1241,10 @@ static int iss_probe(struct platform_device *pdev) if (ret < 0) goto error; - if (!omap4iss_get(iss)) + if (!omap4iss_get(iss)) { + ret = -EINVAL; goto error; + } ret = iss_reset(iss); if (ret < 0) diff --git a/drivers/staging/media/omap4iss/iss_regs.h b/drivers/staging/media/omap4iss/iss_regs.h index 09a7375c89ac..cfe0bb075072 100644 --- a/drivers/staging/media/omap4iss/iss_regs.h +++ b/drivers/staging/media/omap4iss/iss_regs.h @@ -197,7 +197,7 @@ #define CSI2_TIMING_STOP_STATE_COUNTER_IO1_MASK (0x1fff << 0) #define CSI2_TIMING_STOP_STATE_COUNTER_IO1_SHIFT 0 -#define CSI2_CTX_CTRL1(i) (0x70 + (0x20 * i)) +#define CSI2_CTX_CTRL1(i) (0x70 + (0x20 * (i))) #define CSI2_CTX_CTRL1_GENERIC BIT(30) #define CSI2_CTX_CTRL1_TRANSCODE (0xf << 24) #define CSI2_CTX_CTRL1_FEC_NUMBER_MASK (0xff << 16) @@ -210,7 +210,7 @@ #define CSI2_CTX_CTRL1_PING_PONG BIT(3) #define CSI2_CTX_CTRL1_CTX_EN BIT(0) -#define CSI2_CTX_CTRL2(i) (0x74 + (0x20 * i)) +#define CSI2_CTX_CTRL2(i) (0x74 + (0x20 * (i))) #define CSI2_CTX_CTRL2_FRAME_MASK (0xffff << 16) #define CSI2_CTX_CTRL2_FRAME_SHIFT 16 #define CSI2_CTX_CTRL2_USER_DEF_MAP_SHIFT 13 @@ -222,19 +222,19 @@ #define CSI2_CTX_CTRL2_FORMAT_MASK (0x3ff << 0) #define CSI2_CTX_CTRL2_FORMAT_SHIFT 0 -#define CSI2_CTX_DAT_OFST(i) (0x78 + (0x20 * i)) +#define CSI2_CTX_DAT_OFST(i) (0x78 + (0x20 * (i))) #define CSI2_CTX_DAT_OFST_MASK (0xfff << 5) -#define CSI2_CTX_PING_ADDR(i) (0x7c + (0x20 * i)) +#define CSI2_CTX_PING_ADDR(i) (0x7c + (0x20 * (i))) #define CSI2_CTX_PING_ADDR_MASK 0xffffffe0 -#define CSI2_CTX_PONG_ADDR(i) (0x80 + (0x20 * i)) +#define CSI2_CTX_PONG_ADDR(i) (0x80 + (0x20 * (i))) #define CSI2_CTX_PONG_ADDR_MASK CSI2_CTX_PING_ADDR_MASK -#define CSI2_CTX_IRQENABLE(i) (0x84 + (0x20 * i)) -#define CSI2_CTX_IRQSTATUS(i) (0x88 + (0x20 * i)) +#define CSI2_CTX_IRQENABLE(i) (0x84 + (0x20 * (i))) +#define CSI2_CTX_IRQSTATUS(i) (0x88 + (0x20 * (i))) -#define CSI2_CTX_CTRL3(i) (0x8c + (0x20 * i)) +#define CSI2_CTX_CTRL3(i) (0x8c + (0x20 * (i))) #define CSI2_CTX_CTRL3_ALPHA_SHIFT 5 #define CSI2_CTX_CTRL3_ALPHA_MASK \ (0x3fff << CSI2_CTX_CTRL3_ALPHA_SHIFT) diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c index 66975a37dc85..930f638f51eb 100644 --- a/drivers/staging/media/omap4iss/iss_video.c +++ b/drivers/staging/media/omap4iss/iss_video.c @@ -854,6 +854,7 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) struct iss_video *video = video_drvdata(file); struct media_graph graph; struct media_entity *entity = &video->video.entity; + struct media_device *mdev = entity->graph_obj.mdev; enum iss_pipeline_state state; struct iss_pipeline *pipe; struct iss_video *far_end; @@ -890,9 +891,11 @@ iss_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) if (ret < 0) goto err_media_pipeline_start; + mutex_lock(&mdev->graph_mutex); media_graph_walk_start(&graph, entity); while ((entity = media_graph_walk_next(&graph))) media_entity_enum_set(&pipe->ent_enum, entity); + mutex_unlock(&mdev->graph_mutex); /* * Verify that the currently configured format matches the output of diff --git a/drivers/staging/media/rkvdec/rkvdec.c b/drivers/staging/media/rkvdec/rkvdec.c index d3eb81ee8dc2..d821661d30f3 100644 --- a/drivers/staging/media/rkvdec/rkvdec.c +++ b/drivers/staging/media/rkvdec/rkvdec.c @@ -55,16 +55,13 @@ static const struct v4l2_ctrl_ops rkvdec_ctrl_ops = { static const struct rkvdec_ctrl_desc rkvdec_h264_ctrl_descs[] = { { - .mandatory = true, .cfg.id = V4L2_CID_STATELESS_H264_DECODE_PARAMS, }, { - .mandatory = true, .cfg.id = V4L2_CID_STATELESS_H264_SPS, .cfg.ops = &rkvdec_ctrl_ops, }, { - .mandatory = true, .cfg.id = V4L2_CID_STATELESS_H264_PPS, }, { @@ -585,25 +582,7 @@ static const struct vb2_ops rkvdec_queue_ops = { static int rkvdec_request_validate(struct media_request *req) { - struct media_request_object *obj; - const struct rkvdec_ctrls *ctrls; - struct v4l2_ctrl_handler *hdl; - struct rkvdec_ctx *ctx = NULL; - unsigned int count, i; - int ret; - - list_for_each_entry(obj, &req->objects, list) { - if (vb2_request_object_is_buffer(obj)) { - struct vb2_buffer *vb; - - vb = container_of(obj, struct vb2_buffer, req_obj); - ctx = vb2_get_drv_priv(vb->vb2_queue); - break; - } - } - - if (!ctx) - return -EINVAL; + unsigned int count; count = vb2_request_buffer_cnt(req); if (!count) @@ -611,31 +590,6 @@ static int rkvdec_request_validate(struct media_request *req) else if (count > 1) return -EINVAL; - hdl = v4l2_ctrl_request_hdl_find(req, &ctx->ctrl_hdl); - if (!hdl) - return -ENOENT; - - ret = 0; - ctrls = ctx->coded_fmt_desc->ctrls; - for (i = 0; ctrls && i < ctrls->num_ctrls; i++) { - u32 id = ctrls->ctrls[i].cfg.id; - struct v4l2_ctrl *ctrl; - - if (!ctrls->ctrls[i].mandatory) - continue; - - ctrl = v4l2_ctrl_request_hdl_ctrl_find(hdl, id); - if (!ctrl) { - ret = -ENOENT; - break; - } - } - - v4l2_ctrl_request_hdl_put(hdl); - - if (ret) - return ret; - return vb2_request_validate(req); } @@ -1118,7 +1072,7 @@ static struct platform_driver rkvdec_driver = { .remove = rkvdec_remove, .driver = { .name = "rkvdec", - .of_match_table = of_match_ptr(of_rkvdec_match), + .of_match_table = of_rkvdec_match, .pm = &rkvdec_pm_ops, }, }; diff --git a/drivers/staging/media/rkvdec/rkvdec.h b/drivers/staging/media/rkvdec/rkvdec.h index 77a137cca88e..52ac3874c5e5 100644 --- a/drivers/staging/media/rkvdec/rkvdec.h +++ b/drivers/staging/media/rkvdec/rkvdec.h @@ -25,7 +25,6 @@ struct rkvdec_ctx; struct rkvdec_ctrl_desc { - u32 mandatory : 1; struct v4l2_ctrl_config cfg; }; diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c index 7bd9291c8d5f..92812d1a39d4 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus.c @@ -147,7 +147,7 @@ static const struct cedrus_control cedrus_controls[] = { }, { .cfg = { - .id = V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER, + .id = V4L2_CID_STATELESS_VP8_FRAME, }, .codec = CEDRUS_CODEC_VP8, }, diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.h b/drivers/staging/media/sunxi/cedrus/cedrus.h index 251a6a660351..15f147dad4cb 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus.h +++ b/drivers/staging/media/sunxi/cedrus/cedrus.h @@ -79,7 +79,7 @@ struct cedrus_h265_run { }; struct cedrus_vp8_run { - const struct v4l2_ctrl_vp8_frame_header *frame_params; + const struct v4l2_ctrl_vp8_frame *frame_params; }; struct cedrus_run { diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c index a9090daf626a..d696b3ec70c0 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_dec.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_dec.c @@ -72,7 +72,7 @@ void cedrus_device_run(void *priv) case V4L2_PIX_FMT_VP8_FRAME: run.vp8.frame_params = cedrus_find_control_data(ctx, - V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER); + V4L2_CID_STATELESS_VP8_FRAME); break; default: diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h index 7718c561823f..92ace87c1c7d 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_regs.h +++ b/drivers/staging/media/sunxi/cedrus/cedrus_regs.h @@ -443,16 +443,17 @@ #define VE_DEC_H265_STATUS_STCD_BUSY BIT(21) #define VE_DEC_H265_STATUS_WB_BUSY BIT(20) #define VE_DEC_H265_STATUS_BS_DMA_BUSY BIT(19) -#define VE_DEC_H265_STATUS_IQIT_BUSY BIT(18) +#define VE_DEC_H265_STATUS_IT_BUSY BIT(18) #define VE_DEC_H265_STATUS_INTER_BUSY BIT(17) #define VE_DEC_H265_STATUS_MORE_DATA BIT(16) -#define VE_DEC_H265_STATUS_VLD_BUSY BIT(14) -#define VE_DEC_H265_STATUS_DEBLOCKING_BUSY BIT(13) -#define VE_DEC_H265_STATUS_DEBLOCKING_DRAM_BUSY BIT(12) -#define VE_DEC_H265_STATUS_INTRA_BUSY BIT(11) -#define VE_DEC_H265_STATUS_SAO_BUSY BIT(10) -#define VE_DEC_H265_STATUS_MVP_BUSY BIT(9) -#define VE_DEC_H265_STATUS_SWDEC_BUSY BIT(8) +#define VE_DEC_H265_STATUS_DBLK_BUSY BIT(15) +#define VE_DEC_H265_STATUS_IREC_BUSY BIT(14) +#define VE_DEC_H265_STATUS_INTRA_BUSY BIT(13) +#define VE_DEC_H265_STATUS_MCRI_BUSY BIT(12) +#define VE_DEC_H265_STATUS_IQIT_BUSY BIT(11) +#define VE_DEC_H265_STATUS_MVP_BUSY BIT(10) +#define VE_DEC_H265_STATUS_IS_BUSY BIT(9) +#define VE_DEC_H265_STATUS_VLD_BUSY BIT(8) #define VE_DEC_H265_STATUS_OVER_TIME BIT(3) #define VE_DEC_H265_STATUS_VLD_DATA_REQ BIT(2) #define VE_DEC_H265_STATUS_ERROR BIT(1) diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_vp8.c b/drivers/staging/media/sunxi/cedrus/cedrus_vp8.c index ff613ebd1180..f4016684b32d 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus_vp8.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus_vp8.c @@ -423,7 +423,8 @@ static const u8 prob_table_init[] = { * This table is a copy of k_mv_entropy_update_probs from the VP8 * specification. * - * FIXME: If any other driver uses it, move this table to media/vp8-ctrls.h + * FIXME: If any other driver uses it, we can consider moving + * this table so it can be shared. */ static const u8 k_mv_entropy_update_probs[2][V4L2_VP8_MV_PROB_CNT] = { { 237, 246, 253, 253, 254, 254, 254, 254, 254, @@ -522,11 +523,11 @@ static void cedrus_irq_clear(struct cedrus_dev *dev) } static void cedrus_read_header(struct cedrus_dev *dev, - const struct v4l2_ctrl_vp8_frame_header *slice) + const struct v4l2_ctrl_vp8_frame *slice) { int i, j; - if (VP8_FRAME_IS_KEY_FRAME(slice)) { + if (V4L2_VP8_FRAME_IS_KEY_FRAME(slice)) { read_bits(dev, 1, VP8_PROB_HALF); read_bits(dev, 1, VP8_PROB_HALF); } @@ -550,12 +551,12 @@ static void cedrus_read_header(struct cedrus_dev *dev, for (i = 0; i < QUANT_DELTA_COUNT; i++) get_delta_q(dev); - if (!VP8_FRAME_IS_KEY_FRAME(slice)) + if (!V4L2_VP8_FRAME_IS_KEY_FRAME(slice)) process_ref_frame_info(dev); read_bits(dev, 1, VP8_PROB_HALF); - if (!VP8_FRAME_IS_KEY_FRAME(slice)) + if (!V4L2_VP8_FRAME_IS_KEY_FRAME(slice)) read_bits(dev, 1, VP8_PROB_HALF); cedrus_write(dev, VE_H264_TRIGGER_TYPE, VE_H264_TRIGGER_TYPE_VP8_UPDATE_COEF); @@ -565,7 +566,7 @@ static void cedrus_read_header(struct cedrus_dev *dev, if (read_bits(dev, 1, VP8_PROB_HALF)) read_bits(dev, 8, VP8_PROB_HALF); - if (!VP8_FRAME_IS_KEY_FRAME(slice)) { + if (!V4L2_VP8_FRAME_IS_KEY_FRAME(slice)) { read_bits(dev, 8, VP8_PROB_HALF); read_bits(dev, 8, VP8_PROB_HALF); read_bits(dev, 8, VP8_PROB_HALF); @@ -590,34 +591,34 @@ static void cedrus_read_header(struct cedrus_dev *dev, } } -static void cedrus_vp8_update_probs(const struct v4l2_ctrl_vp8_frame_header *slice, +static void cedrus_vp8_update_probs(const struct v4l2_ctrl_vp8_frame *slice, u8 *prob_table) { int i, j, k; - memcpy(&prob_table[0x1008], slice->entropy_header.y_mode_probs, - sizeof(slice->entropy_header.y_mode_probs)); - memcpy(&prob_table[0x1010], slice->entropy_header.uv_mode_probs, - sizeof(slice->entropy_header.uv_mode_probs)); + memcpy(&prob_table[0x1008], slice->entropy.y_mode_probs, + sizeof(slice->entropy.y_mode_probs)); + memcpy(&prob_table[0x1010], slice->entropy.uv_mode_probs, + sizeof(slice->entropy.uv_mode_probs)); - memcpy(&prob_table[0x1018], slice->segment_header.segment_probs, - sizeof(slice->segment_header.segment_probs)); + memcpy(&prob_table[0x1018], slice->segment.segment_probs, + sizeof(slice->segment.segment_probs)); prob_table[0x101c] = slice->prob_skip_false; prob_table[0x101d] = slice->prob_intra; prob_table[0x101e] = slice->prob_last; prob_table[0x101f] = slice->prob_gf; - memcpy(&prob_table[0x1020], slice->entropy_header.mv_probs[0], + memcpy(&prob_table[0x1020], slice->entropy.mv_probs[0], V4L2_VP8_MV_PROB_CNT); - memcpy(&prob_table[0x1040], slice->entropy_header.mv_probs[1], + memcpy(&prob_table[0x1040], slice->entropy.mv_probs[1], V4L2_VP8_MV_PROB_CNT); for (i = 0; i < 4; ++i) for (j = 0; j < 8; ++j) for (k = 0; k < 3; ++k) memcpy(&prob_table[i * 512 + j * 64 + k * 16], - slice->entropy_header.coeff_probs[i][j][k], 11); + slice->entropy.coeff_probs[i][j][k], 11); } static enum cedrus_irq_status @@ -653,7 +654,7 @@ static void cedrus_vp8_irq_disable(struct cedrus_ctx *ctx) static void cedrus_vp8_setup(struct cedrus_ctx *ctx, struct cedrus_run *run) { - const struct v4l2_ctrl_vp8_frame_header *slice = run->vp8.frame_params; + const struct v4l2_ctrl_vp8_frame *slice = run->vp8.frame_params; struct vb2_queue *cap_q = &ctx->fh.m2m_ctx->cap_q_ctx.q; struct vb2_buffer *src_buf = &run->src->vb2_buf; struct cedrus_dev *dev = ctx->dev; @@ -672,7 +673,7 @@ static void cedrus_vp8_setup(struct cedrus_ctx *ctx, reg = slice->first_part_size * 8; cedrus_write(dev, VE_VP8_FIRST_DATA_PART_LEN, reg); - header_size = VP8_FRAME_IS_KEY_FRAME(slice) ? 10 : 3; + header_size = V4L2_VP8_FRAME_IS_KEY_FRAME(slice) ? 10 : 3; reg = slice->first_part_size + header_size; cedrus_write(dev, VE_VP8_PART_SIZE_OFFSET, reg); @@ -719,34 +720,34 @@ static void cedrus_vp8_setup(struct cedrus_ctx *ctx, reg |= VE_VP8_PPS_FULL_PIXEL; break; } - if (slice->segment_header.flags & V4L2_VP8_SEGMENT_HEADER_FLAG_UPDATE_MAP) + if (slice->segment.flags & V4L2_VP8_SEGMENT_FLAG_UPDATE_MAP) reg |= VE_VP8_PPS_UPDATE_MB_SEGMENTATION_MAP; - if (!(slice->segment_header.flags & V4L2_VP8_SEGMENT_HEADER_FLAG_DELTA_VALUE_MODE)) + if (!(slice->segment.flags & V4L2_VP8_SEGMENT_FLAG_DELTA_VALUE_MODE)) reg |= VE_VP8_PPS_MB_SEGMENT_ABS_DELTA; - if (slice->segment_header.flags & V4L2_VP8_SEGMENT_HEADER_FLAG_ENABLED) + if (slice->segment.flags & V4L2_VP8_SEGMENT_FLAG_ENABLED) reg |= VE_VP8_PPS_SEGMENTATION_ENABLE; if (ctx->codec.vp8.last_filter_type) reg |= VE_VP8_PPS_LAST_LOOP_FILTER_SIMPLE; - reg |= VE_VP8_PPS_SHARPNESS_LEVEL(slice->lf_header.sharpness_level); - if (slice->lf_header.flags & V4L2_VP8_LF_FILTER_TYPE_SIMPLE) + reg |= VE_VP8_PPS_SHARPNESS_LEVEL(slice->lf.sharpness_level); + if (slice->lf.flags & V4L2_VP8_LF_FILTER_TYPE_SIMPLE) reg |= VE_VP8_PPS_LOOP_FILTER_SIMPLE; - reg |= VE_VP8_PPS_LOOP_FILTER_LEVEL(slice->lf_header.level); - if (slice->lf_header.flags & V4L2_VP8_LF_HEADER_ADJ_ENABLE) + reg |= VE_VP8_PPS_LOOP_FILTER_LEVEL(slice->lf.level); + if (slice->lf.flags & V4L2_VP8_LF_ADJ_ENABLE) reg |= VE_VP8_PPS_MODE_REF_LF_DELTA_ENABLE; - if (slice->lf_header.flags & V4L2_VP8_LF_HEADER_DELTA_UPDATE) + if (slice->lf.flags & V4L2_VP8_LF_DELTA_UPDATE) reg |= VE_VP8_PPS_MODE_REF_LF_DELTA_UPDATE; reg |= VE_VP8_PPS_TOKEN_PARTITION(ilog2(slice->num_dct_parts)); - if (slice->flags & V4L2_VP8_FRAME_HEADER_FLAG_MB_NO_SKIP_COEFF) + if (slice->flags & V4L2_VP8_FRAME_FLAG_MB_NO_SKIP_COEFF) reg |= VE_VP8_PPS_MB_NO_COEFF_SKIP; reg |= VE_VP8_PPS_RELOAD_ENTROPY_PROBS; - if (slice->flags & V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_GOLDEN) + if (slice->flags & V4L2_VP8_FRAME_FLAG_SIGN_BIAS_GOLDEN) reg |= VE_VP8_PPS_GOLDEN_SIGN_BIAS; - if (slice->flags & V4L2_VP8_FRAME_HEADER_FLAG_SIGN_BIAS_ALT) + if (slice->flags & V4L2_VP8_FRAME_FLAG_SIGN_BIAS_ALT) reg |= VE_VP8_PPS_ALTREF_SIGN_BIAS; if (ctx->codec.vp8.last_frame_p_type) reg |= VE_VP8_PPS_LAST_PIC_TYPE_P_FRAME; reg |= VE_VP8_PPS_LAST_SHARPNESS_LEVEL(ctx->codec.vp8.last_sharpness_level); - if (!(slice->flags & V4L2_VP8_FRAME_HEADER_FLAG_KEY_FRAME)) + if (!(slice->flags & V4L2_VP8_FRAME_FLAG_KEY_FRAME)) reg |= VE_VP8_PPS_PIC_TYPE_P_FRAME; cedrus_write(dev, VE_VP8_PPS, reg); @@ -758,12 +759,12 @@ static void cedrus_vp8_setup(struct cedrus_ctx *ctx, cedrus_write(dev, VE_H264_ERROR_CASE, 0); reg = 0; - reg |= VE_VP8_QP_INDEX_DELTA_UVAC(slice->quant_header.uv_ac_delta); - reg |= VE_VP8_QP_INDEX_DELTA_UVDC(slice->quant_header.uv_dc_delta); - reg |= VE_VP8_QP_INDEX_DELTA_Y2AC(slice->quant_header.y2_ac_delta); - reg |= VE_VP8_QP_INDEX_DELTA_Y2DC(slice->quant_header.y2_dc_delta); - reg |= VE_VP8_QP_INDEX_DELTA_Y1DC(slice->quant_header.y_dc_delta); - reg |= VE_VP8_QP_INDEX_DELTA_BASE_QINDEX(slice->quant_header.y_ac_qi); + reg |= VE_VP8_QP_INDEX_DELTA_UVAC(slice->quant.uv_ac_delta); + reg |= VE_VP8_QP_INDEX_DELTA_UVDC(slice->quant.uv_dc_delta); + reg |= VE_VP8_QP_INDEX_DELTA_Y2AC(slice->quant.y2_ac_delta); + reg |= VE_VP8_QP_INDEX_DELTA_Y2DC(slice->quant.y2_dc_delta); + reg |= VE_VP8_QP_INDEX_DELTA_Y1DC(slice->quant.y_dc_delta); + reg |= VE_VP8_QP_INDEX_DELTA_BASE_QINDEX(slice->quant.y_ac_qi); cedrus_write(dev, VE_VP8_QP_INDEX_DELTA, reg); reg = 0; @@ -777,31 +778,31 @@ static void cedrus_vp8_setup(struct cedrus_ctx *ctx, cedrus_write(dev, VE_VP8_PICSIZE, reg); reg = 0; - reg |= VE_VP8_SEGMENT3(slice->segment_header.quant_update[3]); - reg |= VE_VP8_SEGMENT2(slice->segment_header.quant_update[2]); - reg |= VE_VP8_SEGMENT1(slice->segment_header.quant_update[1]); - reg |= VE_VP8_SEGMENT0(slice->segment_header.quant_update[0]); + reg |= VE_VP8_SEGMENT3(slice->segment.quant_update[3]); + reg |= VE_VP8_SEGMENT2(slice->segment.quant_update[2]); + reg |= VE_VP8_SEGMENT1(slice->segment.quant_update[1]); + reg |= VE_VP8_SEGMENT0(slice->segment.quant_update[0]); cedrus_write(dev, VE_VP8_SEGMENT_FEAT_MB_LV0, reg); reg = 0; - reg |= VE_VP8_SEGMENT3(slice->segment_header.lf_update[3]); - reg |= VE_VP8_SEGMENT2(slice->segment_header.lf_update[2]); - reg |= VE_VP8_SEGMENT1(slice->segment_header.lf_update[1]); - reg |= VE_VP8_SEGMENT0(slice->segment_header.lf_update[0]); + reg |= VE_VP8_SEGMENT3(slice->segment.lf_update[3]); + reg |= VE_VP8_SEGMENT2(slice->segment.lf_update[2]); + reg |= VE_VP8_SEGMENT1(slice->segment.lf_update[1]); + reg |= VE_VP8_SEGMENT0(slice->segment.lf_update[0]); cedrus_write(dev, VE_VP8_SEGMENT_FEAT_MB_LV1, reg); reg = 0; - reg |= VE_VP8_LF_DELTA3(slice->lf_header.ref_frm_delta[3]); - reg |= VE_VP8_LF_DELTA2(slice->lf_header.ref_frm_delta[2]); - reg |= VE_VP8_LF_DELTA1(slice->lf_header.ref_frm_delta[1]); - reg |= VE_VP8_LF_DELTA0(slice->lf_header.ref_frm_delta[0]); + reg |= VE_VP8_LF_DELTA3(slice->lf.ref_frm_delta[3]); + reg |= VE_VP8_LF_DELTA2(slice->lf.ref_frm_delta[2]); + reg |= VE_VP8_LF_DELTA1(slice->lf.ref_frm_delta[1]); + reg |= VE_VP8_LF_DELTA0(slice->lf.ref_frm_delta[0]); cedrus_write(dev, VE_VP8_REF_LF_DELTA, reg); reg = 0; - reg |= VE_VP8_LF_DELTA3(slice->lf_header.mb_mode_delta[3]); - reg |= VE_VP8_LF_DELTA2(slice->lf_header.mb_mode_delta[2]); - reg |= VE_VP8_LF_DELTA1(slice->lf_header.mb_mode_delta[1]); - reg |= VE_VP8_LF_DELTA0(slice->lf_header.mb_mode_delta[0]); + reg |= VE_VP8_LF_DELTA3(slice->lf.mb_mode_delta[3]); + reg |= VE_VP8_LF_DELTA2(slice->lf.mb_mode_delta[2]); + reg |= VE_VP8_LF_DELTA1(slice->lf.mb_mode_delta[1]); + reg |= VE_VP8_LF_DELTA0(slice->lf.mb_mode_delta[0]); cedrus_write(dev, VE_VP8_MODE_LF_DELTA, reg); luma_addr = cedrus_dst_buf_addr(ctx, run->dst->vb2_buf.index, 0); @@ -846,13 +847,13 @@ static void cedrus_vp8_setup(struct cedrus_ctx *ctx, VE_H264_CTRL_DECODE_ERR_INT | VE_H264_CTRL_SLICE_DECODE_INT); - if (slice->lf_header.level) { + if (slice->lf.level) { ctx->codec.vp8.last_filter_type = - !!(slice->lf_header.flags & V4L2_VP8_LF_FILTER_TYPE_SIMPLE); + !!(slice->lf.flags & V4L2_VP8_LF_FILTER_TYPE_SIMPLE); ctx->codec.vp8.last_frame_p_type = - !VP8_FRAME_IS_KEY_FRAME(slice); + !V4L2_VP8_FRAME_IS_KEY_FRAME(slice); ctx->codec.vp8.last_sharpness_level = - slice->lf_header.sharpness_level; + slice->lf.sharpness_level; } } diff --git a/drivers/staging/media/tegra-video/csi.h b/drivers/staging/media/tegra-video/csi.h index 386f7c664259..4ee05a1785cf 100644 --- a/drivers/staging/media/tegra-video/csi.h +++ b/drivers/staging/media/tegra-video/csi.h @@ -139,7 +139,7 @@ struct tegra_csi_soc { * @clks: clock for CSI and CIL * @soc: pointer to SoC data structure * @ops: csi operations - * @channels: list head for CSI channels + * @csi_chans: list head for CSI channels */ struct tegra_csi { struct device *dev; diff --git a/drivers/staging/media/zoran/zoran_device.c b/drivers/staging/media/zoran/zoran_device.c index e569a1341d01..cf788d9cd1df 100644 --- a/drivers/staging/media/zoran/zoran_device.c +++ b/drivers/staging/media/zoran/zoran_device.c @@ -291,11 +291,11 @@ static void zr36057_set_vfe(struct zoran *zr, int video_width, int video_height, const struct zoran_format *format) { const struct tvnorm *tvn; - unsigned int h_start, HEnd, v_start, VEnd; - unsigned int DispMode; - unsigned int VidWinWid, VidWinHt; + unsigned int h_start, h_end, v_start, v_end; + unsigned int disp_mode; + unsigned int vid_win_wid, vid_win_ht; unsigned int hcrop1, hcrop2, vcrop1, vcrop2; - unsigned int wa, We, ha, He; + unsigned int wa, we, ha, he; unsigned int X, Y, hor_dcm, ver_dcm; u32 reg; @@ -316,12 +316,12 @@ static void zr36057_set_vfe(struct zoran *zr, int video_width, int video_height, /**** zr36057 ****/ /* horizontal */ - VidWinWid = video_width; - X = DIV_ROUND_UP(VidWinWid * 64, tvn->wa); - We = (VidWinWid * 64) / X; + vid_win_wid = video_width; + X = DIV_ROUND_UP(vid_win_wid * 64, tvn->wa); + we = (vid_win_wid * 64) / X; hor_dcm = 64 - X; - hcrop1 = 2 * ((tvn->wa - We) / 4); - hcrop2 = tvn->wa - We - hcrop1; + hcrop1 = 2 * ((tvn->wa - we) / 4); + hcrop2 = tvn->wa - we - hcrop1; h_start = tvn->h_start ? tvn->h_start : 1; /* (Ronald) Original comment: * "| 1 Doesn't have any effect, tested on both a DC10 and a DC10+" @@ -331,29 +331,29 @@ static void zr36057_set_vfe(struct zoran *zr, int video_width, int video_height, * However, the DC10 has '0' as h_start, but does need |1, so we * use a dirty check... */ - HEnd = h_start + tvn->wa - 1; + h_end = h_start + tvn->wa - 1; h_start += hcrop1; - HEnd -= hcrop2; + h_end -= hcrop2; reg = ((h_start & ZR36057_VFEHCR_HMASK) << ZR36057_VFEHCR_H_START) - | ((HEnd & ZR36057_VFEHCR_HMASK) << ZR36057_VFEHCR_H_END); + | ((h_end & ZR36057_VFEHCR_HMASK) << ZR36057_VFEHCR_H_END); if (zr->card.vfe_pol.hsync_pol) reg |= ZR36057_VFEHCR_HS_POL; btwrite(reg, ZR36057_VFEHCR); /* Vertical */ - DispMode = !(video_height > BUZ_MAX_HEIGHT / 2); - VidWinHt = DispMode ? video_height : video_height / 2; - Y = DIV_ROUND_UP(VidWinHt * 64 * 2, tvn->ha); - He = (VidWinHt * 64) / Y; + disp_mode = !(video_height > BUZ_MAX_HEIGHT / 2); + vid_win_ht = disp_mode ? video_height : video_height / 2; + Y = DIV_ROUND_UP(vid_win_ht * 64 * 2, tvn->ha); + he = (vid_win_ht * 64) / Y; ver_dcm = 64 - Y; - vcrop1 = (tvn->ha / 2 - He) / 2; - vcrop2 = tvn->ha / 2 - He - vcrop1; + vcrop1 = (tvn->ha / 2 - he) / 2; + vcrop2 = tvn->ha / 2 - he - vcrop1; v_start = tvn->v_start; - VEnd = v_start + tvn->ha / 2; // - 1; FIXME SnapShot times out with -1 in 768*576 on the DC10 - LP + v_end = v_start + tvn->ha / 2; // - 1; FIXME SnapShot times out with -1 in 768*576 on the DC10 - LP v_start += vcrop1; - VEnd -= vcrop2; + v_end -= vcrop2; reg = ((v_start & ZR36057_VFEVCR_VMASK) << ZR36057_VFEVCR_V_START) - | ((VEnd & ZR36057_VFEVCR_VMASK) << ZR36057_VFEVCR_V_END); + | ((v_end & ZR36057_VFEVCR_VMASK) << ZR36057_VFEVCR_V_END); if (zr->card.vfe_pol.vsync_pol) reg |= ZR36057_VFEVCR_VS_POL; btwrite(reg, ZR36057_VFEVCR); @@ -362,7 +362,7 @@ static void zr36057_set_vfe(struct zoran *zr, int video_width, int video_height, reg = 0; reg |= (hor_dcm << ZR36057_VFESPFR_HOR_DCM); reg |= (ver_dcm << ZR36057_VFESPFR_VER_DCM); - reg |= (DispMode << ZR36057_VFESPFR_DISP_MODE); + reg |= (disp_mode << ZR36057_VFESPFR_DISP_MODE); /* RJ: I don't know, why the following has to be the opposite * of the corresponding ZR36060 setting, but only this way * we get the correct colors when uncompressing to the screen */ @@ -383,8 +383,8 @@ static void zr36057_set_vfe(struct zoran *zr, int video_width, int video_height, /* display configuration */ reg = (16 << ZR36057_VDCR_MIN_PIX) - | (VidWinHt << ZR36057_VDCR_VID_WIN_HT) - | (VidWinWid << ZR36057_VDCR_VID_WIN_WID); + | (vid_win_ht << ZR36057_VDCR_VID_WIN_HT) + | (vid_win_wid << ZR36057_VDCR_VID_WIN_WID); if (pci_pci_problems & PCIPCI_TRITON) // || zr->revision < 1) // Revision 1 has also Triton support reg &= ~ZR36057_VDCR_TRITON; |