linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] Address issues preventing camorama to work with atomisp
@ 2021-11-04 12:05 Mauro Carvalho Chehab
  2021-11-04 12:05 ` [PATCH 1/7] media: atomisp-ov2680: use v4l2_find_nearest_size() Mauro Carvalho Chehab
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Mauro Carvalho Chehab @ 2021-11-04 12:05 UTC (permalink / raw)
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, Sakari Ailus,
	linux-kernel, linux-media, linux-staging

This patch series address some issues at atomisp that are preventing camorama
to work with atomisp driver.

After this series, I can use camorama just like on any other device. The frame
rate is slow (~7fps), though. Not sure if this is due to some sensor limitation or
because of some other issue.

Anyway this is a start :-)

Some notes:

1. Patch 1 fixes an issue at ov2680 logic. It probably needs to be reflected at the
   other supported sensors;

2. MMAP is not working. So, it requires a newer version of camorama that has
   support for USERPTR.

3. There's nothing special on Camorama for atomisp, except that it has support
   for USERPTR.

4. Camorama currently doesn't allow changing the resolution of the camera.
   That's because of several things:

   a. The driver has a scaler, supporting resolutions from 32x16 to 1600x1200
      on Asus T101HA.
   b. The atomisp driver doesn't implement ENUM_FRAMEINTERVALS;
   c. camorama is not prepared for cameras with scalers on it. It just lets one to
      select the resolutions enumerated by  ENUM_FRAMEINTERVALS.

Mauro Carvalho Chehab (7):
  media: atomisp-ov2680: use v4l2_find_nearest_size()
  media: atomisp: move a debug printf to a better place
  media: atomisp: fix VIDIOC_S_FMT logic
  media: atomisp: fix enum_fmt logic
  media: atomisp: move atomisp_g_fmt_cap()
  media: atomisp: fix try_fmt logic
  media: atomisp: fix g_fmt logic

 .../media/atomisp/i2c/atomisp-ov2680.c        | 127 +++-----------
 drivers/staging/media/atomisp/i2c/ov2680.h    |   3 +-
 .../staging/media/atomisp/pci/atomisp_cmd.c   |  59 +++++--
 .../staging/media/atomisp/pci/atomisp_ioctl.c | 157 ++++++++++--------
 4 files changed, 162 insertions(+), 184 deletions(-)

-- 
2.31.1



^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/7] media: atomisp-ov2680: use v4l2_find_nearest_size()
  2021-11-04 12:05 [PATCH 0/7] Address issues preventing camorama to work with atomisp Mauro Carvalho Chehab
@ 2021-11-04 12:05 ` Mauro Carvalho Chehab
  2021-11-04 12:05 ` [PATCH 2/7] media: atomisp: move a debug printf to a better place Mauro Carvalho Chehab
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Mauro Carvalho Chehab @ 2021-11-04 12:05 UTC (permalink / raw)
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, Bhaskar Chowdhury,
	Deepak R Varma, Greg Kroah-Hartman, Hans Verkuil,
	Laurent Pinchart, Mauro Carvalho Chehab, Randy Dunlap,
	Sakari Ailus, Tomi Valkeinen, linux-kernel, linux-media,
	linux-staging

Instead of reinventing the wheel, use v4l2_find_nearest_size()
in order to get the closest resolution.

This should address a bug where the wrong resolution was
selected.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---

To mailbombing on a large number of people, only mailing lists were C/C on the cover.
See [PATCH 0/7] at: https://lore.kernel.org/all/cover.1636026959.git.mchehab+huawei@kernel.org/

 .../media/atomisp/i2c/atomisp-ov2680.c        | 127 ++++--------------
 drivers/staging/media/atomisp/i2c/ov2680.h    |   3 +-
 2 files changed, 25 insertions(+), 105 deletions(-)

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
index 2111e4a478c1..160efa432934 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
@@ -147,7 +147,7 @@ static int ov2680_g_bin_factor_x(struct v4l2_subdev *sd, s32 *val)
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
 	dev_dbg(&client->dev,  "++++ov2680_g_bin_factor_x\n");
-	*val = ov2680_res[dev->fmt_idx].bin_factor_x;
+	*val = dev->res->bin_factor_x;
 
 	return 0;
 }
@@ -157,7 +157,7 @@ static int ov2680_g_bin_factor_y(struct v4l2_subdev *sd, s32 *val)
 	struct ov2680_device *dev = to_ov2680_sensor(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	*val = ov2680_res[dev->fmt_idx].bin_factor_y;
+	*val = dev->res->bin_factor_y;
 	dev_dbg(&client->dev,  "++++ov2680_g_bin_factor_y\n");
 	return 0;
 }
@@ -254,7 +254,7 @@ static long __ov2680_set_exposure(struct v4l2_subdev *sd, int coarse_itg,
 		"+++++++__ov2680_set_exposure coarse_itg %d, gain %d, digitgain %d++\n",
 		coarse_itg, gain, digitgain);
 
-	vts = ov2680_res[dev->fmt_idx].lines_per_frame;
+	vts = dev->res->lines_per_frame;
 
 	/* group hold */
 	ret = ov2680_write_reg(client, 1,
@@ -843,76 +843,6 @@ static int ov2680_s_power(struct v4l2_subdev *sd, int on)
 	return ret;
 }
 
-/*
- * distance - calculate the distance
- * @res: resolution
- * @w: width
- * @h: height
- *
- * Get the gap between resolution and w/h.
- * res->width/height smaller than w/h wouldn't be considered.
- * Returns the value of gap or -1 if fail.
- */
-#define LARGEST_ALLOWED_RATIO_MISMATCH 600
-static int distance(struct ov2680_resolution *res, u32 w, u32 h)
-{
-	unsigned int w_ratio = (res->width << 13) / w;
-	unsigned int h_ratio;
-	int match;
-
-	if (h == 0)
-		return -1;
-	h_ratio = (res->height << 13) / h;
-	if (h_ratio == 0)
-		return -1;
-	match   = abs(((w_ratio << 13) / h_ratio) - 8192);
-
-	if ((w_ratio < 8192) || (h_ratio < 8192)  ||
-	    (match > LARGEST_ALLOWED_RATIO_MISMATCH))
-		return -1;
-
-	return w_ratio + h_ratio;
-}
-
-/* Return the nearest higher resolution index */
-static int nearest_resolution_index(int w, int h)
-{
-	int i;
-	int idx = -1;
-	int dist;
-	int min_dist = INT_MAX;
-	struct ov2680_resolution *tmp_res = NULL;
-
-	for (i = 0; i < N_RES; i++) {
-		tmp_res = &ov2680_res[i];
-		dist = distance(tmp_res, w, h);
-		if (dist == -1)
-			continue;
-		if (dist < min_dist) {
-			min_dist = dist;
-			idx = i;
-		}
-	}
-
-	return idx;
-}
-
-static int get_resolution_index(int w, int h)
-{
-	int i;
-
-	for (i = 0; i < N_RES; i++) {
-		if (w != ov2680_res[i].width)
-			continue;
-		if (h != ov2680_res[i].height)
-			continue;
-
-		return i;
-	}
-
-	return -1;
-}
-
 static int ov2680_set_fmt(struct v4l2_subdev *sd,
 			  struct v4l2_subdev_state *sd_state,
 			  struct v4l2_subdev_format *format)
@@ -921,8 +851,8 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
 	struct ov2680_device *dev = to_ov2680_sensor(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	struct camera_mipi_info *ov2680_info = NULL;
+	static struct ov2680_resolution *res;
 	int ret = 0;
-	int idx = 0;
 
 	dev_dbg(&client->dev, "%s: %s: pad: %d, fmt: %p\n",
 		__func__,
@@ -940,41 +870,34 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
 		return -EINVAL;
 
 	mutex_lock(&dev->input_lock);
-	idx = nearest_resolution_index(fmt->width, fmt->height);
-	if (idx == -1) {
-		/* return the largest resolution */
-		fmt->width = ov2680_res[N_RES - 1].width;
-		fmt->height = ov2680_res[N_RES - 1].height;
-	} else {
-		fmt->width = ov2680_res[idx].width;
-		fmt->height = ov2680_res[idx].height;
-	}
+
+	res = v4l2_find_nearest_size(ov2680_res_preview,
+				ARRAY_SIZE(ov2680_res_preview), width,
+				height, fmt->width, fmt->height);
+	if (!res)
+		res = &ov2680_res[N_RES - 1];
+
+	fmt->width = res->width;
+	fmt->height = res->height;
+
 	fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
 	if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
 		sd_state->pads->try_fmt = *fmt;
 		mutex_unlock(&dev->input_lock);
 		return 0;
 	}
-	dev->fmt_idx = get_resolution_index(fmt->width, fmt->height);
-	dev_dbg(&client->dev, "%s: Resolution index: %d\n",
-		__func__, dev->fmt_idx);
-	if (dev->fmt_idx == -1) {
-		dev_err(&client->dev, "get resolution fail\n");
-		mutex_unlock(&dev->input_lock);
-		return -EINVAL;
-	}
-	dev_dbg(&client->dev, "%s: i=%d, w=%d, h=%d\n",
-		__func__, dev->fmt_idx, fmt->width, fmt->height);
+
+	dev_dbg(&client->dev, "%s: %dx%d\n",
+		__func__, fmt->width, fmt->height);
 
 	// IS IT NEEDED?
 	power_up(sd);
-	ret = ov2680_write_reg_array(client, ov2680_res[dev->fmt_idx].regs);
+	ret = ov2680_write_reg_array(client, dev->res->regs);
 	if (ret)
 		dev_err(&client->dev,
 			"ov2680 write resolution register err: %d\n", ret);
 
-	ret = ov2680_get_intg_factor(client, ov2680_info,
-				     &ov2680_res[dev->fmt_idx]);
+	ret = ov2680_get_intg_factor(client, ov2680_info, res);
 	if (ret) {
 		dev_err(&client->dev, "failed to get integration factor\n");
 		goto err;
@@ -989,8 +912,6 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
 	if (v_flag)
 		ov2680_v_flip(sd, v_flag);
 
-	v4l2_info(client, "\n%s idx %d\n", __func__, dev->fmt_idx);
-
 	/*
 	 * ret = startup(sd);
 	 * if (ret)
@@ -1014,8 +935,8 @@ static int ov2680_get_fmt(struct v4l2_subdev *sd,
 	if (!fmt)
 		return -EINVAL;
 
-	fmt->width = ov2680_res[dev->fmt_idx].width;
-	fmt->height = ov2680_res[dev->fmt_idx].height;
+	fmt->width = dev->res->width;
+	fmt->height = dev->res->height;
 	fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10;
 
 	return 0;
@@ -1155,7 +1076,7 @@ static int ov2680_g_frame_interval(struct v4l2_subdev *sd,
 	struct ov2680_device *dev = to_ov2680_sensor(sd);
 
 	interval->interval.numerator = 1;
-	interval->interval.denominator = ov2680_res[dev->fmt_idx].fps;
+	interval->interval.denominator = dev->res->fps;
 
 	return 0;
 }
@@ -1193,7 +1114,7 @@ static int ov2680_g_skip_frames(struct v4l2_subdev *sd, u32 *frames)
 	struct ov2680_device *dev = to_ov2680_sensor(sd);
 
 	mutex_lock(&dev->input_lock);
-	*frames = ov2680_res[dev->fmt_idx].skip_frames;
+	*frames = dev->res->skip_frames;
 	mutex_unlock(&dev->input_lock);
 
 	return 0;
@@ -1257,7 +1178,7 @@ static int ov2680_probe(struct i2c_client *client)
 
 	mutex_init(&dev->input_lock);
 
-	dev->fmt_idx = 0;
+	dev->res = &ov2680_res_preview[0];
 	v4l2_i2c_subdev_init(&dev->sd, client, &ov2680_ops);
 
 	pdata = gmin_camera_platform_data(&dev->sd,
diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
index 874115f35fca..535440ed14d7 100644
--- a/drivers/staging/media/atomisp/i2c/ov2680.h
+++ b/drivers/staging/media/atomisp/i2c/ov2680.h
@@ -172,11 +172,10 @@ struct ov2680_device {
 	struct v4l2_mbus_framefmt format;
 	struct mutex input_lock;
 	struct v4l2_ctrl_handler ctrl_handler;
+	struct ov2680_resolution *res;
 	struct camera_sensor_platform_data *platform_data;
 	int vt_pix_clk_freq_mhz;
-	int fmt_idx;
 	int run_mode;
-	u8 res;
 	u8 type;
 };
 
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/7] media: atomisp: move a debug printf to a better place
  2021-11-04 12:05 [PATCH 0/7] Address issues preventing camorama to work with atomisp Mauro Carvalho Chehab
  2021-11-04 12:05 ` [PATCH 1/7] media: atomisp-ov2680: use v4l2_find_nearest_size() Mauro Carvalho Chehab
@ 2021-11-04 12:05 ` Mauro Carvalho Chehab
  2021-11-04 12:05 ` [PATCH 3/7] media: atomisp: fix VIDIOC_S_FMT logic Mauro Carvalho Chehab
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Mauro Carvalho Chehab @ 2021-11-04 12:05 UTC (permalink / raw)
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, Alex Dewar,
	Aline Santana Cordeiro, Arnd Bergmann, Greg Kroah-Hartman,
	Hans Verkuil, Laurent Pinchart, Mauro Carvalho Chehab,
	Sakari Ailus, Tomi Valkeinen, Tsuchiya Yuto, Yang Li,
	linux-kernel, linux-media, linux-staging

The sensor width/height report is alread being printed after
its calculus. The only reason for an extra debug printk is
when dis is used. So, change its message to reflect and move
it to be inside the if checks.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---

To mailbombing on a large number of people, only mailing lists were C/C on the cover.
See [PATCH 0/7] at: https://lore.kernel.org/all/cover.1636026959.git.mchehab+huawei@kernel.org/

 drivers/staging/media/atomisp/pci/atomisp_cmd.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
index feb75491a273..76c9e89afb48 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
@@ -5583,6 +5583,10 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev,
 				       pad, set_fmt, &pad_state, &vformat);
 		if (ret)
 			return ret;
+
+		dev_dbg(isp->dev, "video dis: sensor width: %d, height: %d\n",
+			ffmt->width, ffmt->height);
+
 		if (ffmt->width < req_ffmt->width ||
 		    ffmt->height < req_ffmt->height) {
 			req_ffmt->height -= dvs_env_h;
@@ -5593,8 +5597,6 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev,
 			asd->params.video_dis_en = false;
 		}
 	}
-	dev_dbg(isp->dev, "sensor width: %d, height: %d\n",
-		ffmt->width, ffmt->height);
 	vformat.which = V4L2_SUBDEV_FORMAT_ACTIVE;
 	ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, pad,
 			       set_fmt, NULL, &vformat);
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/7] media: atomisp: fix VIDIOC_S_FMT logic
  2021-11-04 12:05 [PATCH 0/7] Address issues preventing camorama to work with atomisp Mauro Carvalho Chehab
  2021-11-04 12:05 ` [PATCH 1/7] media: atomisp-ov2680: use v4l2_find_nearest_size() Mauro Carvalho Chehab
  2021-11-04 12:05 ` [PATCH 2/7] media: atomisp: move a debug printf to a better place Mauro Carvalho Chehab
@ 2021-11-04 12:05 ` Mauro Carvalho Chehab
  2021-11-04 12:05 ` [PATCH 4/7] media: atomisp: fix enum_fmt logic Mauro Carvalho Chehab
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Mauro Carvalho Chehab @ 2021-11-04 12:05 UTC (permalink / raw)
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, Alex Dewar,
	Aline Santana Cordeiro, Arnd Bergmann, Greg Kroah-Hartman,
	Hans Verkuil, Mauro Carvalho Chehab, Sakari Ailus,
	Tomi Valkeinen, Tsuchiya Yuto, Yang Li, linux-kernel,
	linux-media, linux-staging

There are several issues on S_FMT implementation:

- it doesn't properly handle pad_h/pad_w;
- it reports a wrong visible size to userspace;
- it allows setting the format to a raw mode, which
  currently causes the pipeline to break.

Address such issues, for it to start working with generic
apps.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---

To mailbombing on a large number of people, only mailing lists were C/C on the cover.
See [PATCH 0/7] at: https://lore.kernel.org/all/cover.1636026959.git.mchehab+huawei@kernel.org/

 .../staging/media/atomisp/pci/atomisp_cmd.c   | 46 ++++++++++++++++++-
 1 file changed, 44 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
index 76c9e89afb48..851046ecbdbf 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
@@ -5635,13 +5635,17 @@ 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_pix_format snr_fmt = f->fmt.pix;
-	struct v4l2_pix_format backup_fmt = snr_fmt, s_fmt;
+	struct v4l2_pix_format snr_fmt;
+	struct v4l2_pix_format backup_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;
 	struct v4l2_mbus_framefmt *isp_sink_fmt;
 	struct v4l2_mbus_framefmt isp_source_fmt = {0};
+	struct v4l2_subdev_format vformat = {
+		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
+	};
+	struct v4l2_mbus_framefmt *ffmt = &vformat.format;
 	struct v4l2_rect isp_sink_crop;
 	u16 source_pad = atomisp_subdev_source_pad(vdev);
 	struct v4l2_subdev_fh fh;
@@ -5672,9 +5676,38 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f)
 	if (!format_bridge)
 		return -EINVAL;
 
+	/* Currently, raw formats are broken!!! */
+
+	if (format_bridge->sh_fmt == IA_CSS_FRAME_FORMAT_RAW) {
+		f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
+
+		format_bridge = atomisp_get_format_bridge(f->fmt.pix.pixelformat);
+		if (!format_bridge)
+			return -EINVAL;
+	}
 	pipe->sh_fmt = format_bridge->sh_fmt;
 	pipe->pix.pixelformat = f->fmt.pix.pixelformat;
 
+	/* Ensure that the resolution is equal or below the maximum supported */
+
+	vformat.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+	v4l2_fill_mbus_format(ffmt, &f->fmt.pix, format_bridge->mbus_code);
+	ffmt->height += padding_h;
+	ffmt->width += padding_w;
+
+	ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, pad,
+			       set_fmt, NULL, &vformat);
+	if (ret)
+		return ret;
+
+	f->fmt.pix.width = ffmt->width - padding_w;
+	f->fmt.pix.height = ffmt->height - padding_h;
+
+	snr_fmt = f->fmt.pix;
+	backup_fmt = snr_fmt;
+
+	/**********************************************************************/
+
 	if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_VF ||
 	    (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW
 	     && asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO)) {
@@ -6080,6 +6113,15 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f)
 	else
 		isp->need_gfx_throttle = true;
 
+	/* Report the needed sizes */
+	f->fmt.pix.sizeimage = pipe->pix.sizeimage;
+	f->fmt.pix.bytesperline = pipe->pix.bytesperline;
+
+	dev_dbg(isp->dev, "%s: %dx%d, image size: %d, %d bytes per line\n",
+		__func__,
+		f->fmt.pix.width, f->fmt.pix.height,
+		f->fmt.pix.sizeimage, f->fmt.pix.bytesperline);
+
 	return 0;
 }
 
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/7] media: atomisp: fix enum_fmt logic
  2021-11-04 12:05 [PATCH 0/7] Address issues preventing camorama to work with atomisp Mauro Carvalho Chehab
                   ` (2 preceding siblings ...)
  2021-11-04 12:05 ` [PATCH 3/7] media: atomisp: fix VIDIOC_S_FMT logic Mauro Carvalho Chehab
@ 2021-11-04 12:05 ` Mauro Carvalho Chehab
  2021-11-04 12:05 ` [PATCH 5/7] media: atomisp: move atomisp_g_fmt_cap() Mauro Carvalho Chehab
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Mauro Carvalho Chehab @ 2021-11-04 12:05 UTC (permalink / raw)
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, Andy Shevchenko,
	Dan Carpenter, Greg Kroah-Hartman, Kaixu Xia,
	Mauro Carvalho Chehab, Peter Zijlstra, Sakari Ailus,
	Thomas Gleixner, Tsuchiya Yuto, linux-kernel, linux-media,
	linux-staging

Currently, the enum lists the sensor's native format as a
supported format. However, trying to setup a pipeline using
it doesn't work.

So, exclude such formats from the enum.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---

To mailbombing on a large number of people, only mailing lists were C/C on the cover.
See [PATCH 0/7] at: https://lore.kernel.org/all/cover.1636026959.git.mchehab+huawei@kernel.org/

 drivers/staging/media/atomisp/pci/atomisp_ioctl.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
index 8df052f6190d..30483a84ed80 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
@@ -775,6 +775,7 @@ static int atomisp_enum_fmt_cap(struct file *file, void *fh,
 	struct v4l2_subdev_mbus_code_enum code = {
 		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
 	};
+	const struct atomisp_format_bridge *format;
 	struct v4l2_subdev *camera;
 	unsigned int i, fi = 0;
 	int rval;
@@ -806,15 +807,15 @@ static int atomisp_enum_fmt_cap(struct file *file, void *fh,
 		return rval;
 
 	for (i = 0; i < ARRAY_SIZE(atomisp_output_fmts); i++) {
-		const struct atomisp_format_bridge *format =
-			    &atomisp_output_fmts[i];
+		format = &atomisp_output_fmts[i];
 
 		/*
 		 * Is the atomisp-supported format is valid for the
 		 * sensor (configuration)? If not, skip it.
+		 *
+		 * FIXME: fix the pipeline to allow sensor format too.
 		 */
-		if (format->sh_fmt == IA_CSS_FRAME_FORMAT_RAW
-		    && format->mbus_code != code.code)
+		if (format->sh_fmt == IA_CSS_FRAME_FORMAT_RAW)
 			continue;
 
 		/* Found a match. Now let's pick f->index'th one. */
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 5/7] media: atomisp: move atomisp_g_fmt_cap()
  2021-11-04 12:05 [PATCH 0/7] Address issues preventing camorama to work with atomisp Mauro Carvalho Chehab
                   ` (3 preceding siblings ...)
  2021-11-04 12:05 ` [PATCH 4/7] media: atomisp: fix enum_fmt logic Mauro Carvalho Chehab
@ 2021-11-04 12:05 ` Mauro Carvalho Chehab
  2021-11-04 12:05 ` [PATCH 6/7] media: atomisp: fix try_fmt logic Mauro Carvalho Chehab
  2021-11-04 12:05 ` [PATCH 7/7] media: atomisp: fix g_fmt logic Mauro Carvalho Chehab
  6 siblings, 0 replies; 8+ messages in thread
From: Mauro Carvalho Chehab @ 2021-11-04 12:05 UTC (permalink / raw)
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, Arnd Bergmann,
	Dan Carpenter, Greg Kroah-Hartman, Ingo Molnar,
	Mauro Carvalho Chehab, Peter Zijlstra, Sakari Ailus,
	Tsuchiya Yuto, linux-kernel, linux-media, linux-staging

move atomisp_g_fmt_cap() for it to be after try_fmt, as we'll
re-use try_fmt there.

No functional changes.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---

To mailbombing on a large number of people, only mailing lists were C/C on the cover.
See [PATCH 0/7] at: https://lore.kernel.org/all/cover.1636026959.git.mchehab+huawei@kernel.org/

 .../staging/media/atomisp/pci/atomisp_ioctl.c | 56 +++++++++----------
 1 file changed, 28 insertions(+), 28 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
index 30483a84ed80..84ff97dabbed 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
@@ -833,6 +833,34 @@ static int atomisp_enum_fmt_cap(struct file *file, void *fh,
 	return -EINVAL;
 }
 
+static int atomisp_g_fmt_file(struct file *file, void *fh,
+			      struct v4l2_format *f)
+{
+	struct video_device *vdev = video_devdata(file);
+	struct atomisp_device *isp = video_get_drvdata(vdev);
+	struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
+
+	rt_mutex_lock(&isp->mutex);
+	f->fmt.pix = pipe->pix;
+	rt_mutex_unlock(&isp->mutex);
+
+	return 0;
+}
+
+/* This function looks up the closest available resolution. */
+static int atomisp_try_fmt_cap(struct file *file, void *fh,
+			       struct v4l2_format *f)
+{
+	struct video_device *vdev = video_devdata(file);
+	struct atomisp_device *isp = video_get_drvdata(vdev);
+	int ret;
+
+	rt_mutex_lock(&isp->mutex);
+	ret = atomisp_try_fmt(vdev, &f->fmt.pix, NULL);
+	rt_mutex_unlock(&isp->mutex);
+	return ret;
+}
+
 static int atomisp_g_fmt_cap(struct file *file, void *fh,
 			     struct v4l2_format *f)
 {
@@ -907,34 +935,6 @@ static int atomisp_g_fmt_cap(struct file *file, void *fh,
 	return 0;
 }
 
-static int atomisp_g_fmt_file(struct file *file, void *fh,
-			      struct v4l2_format *f)
-{
-	struct video_device *vdev = video_devdata(file);
-	struct atomisp_device *isp = video_get_drvdata(vdev);
-	struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
-
-	rt_mutex_lock(&isp->mutex);
-	f->fmt.pix = pipe->pix;
-	rt_mutex_unlock(&isp->mutex);
-
-	return 0;
-}
-
-/* This function looks up the closest available resolution. */
-static int atomisp_try_fmt_cap(struct file *file, void *fh,
-			       struct v4l2_format *f)
-{
-	struct video_device *vdev = video_devdata(file);
-	struct atomisp_device *isp = video_get_drvdata(vdev);
-	int ret;
-
-	rt_mutex_lock(&isp->mutex);
-	ret = atomisp_try_fmt(vdev, &f->fmt.pix, NULL);
-	rt_mutex_unlock(&isp->mutex);
-	return ret;
-}
-
 static int atomisp_s_fmt_cap(struct file *file, void *fh,
 			     struct v4l2_format *f)
 {
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 6/7] media: atomisp: fix try_fmt logic
  2021-11-04 12:05 [PATCH 0/7] Address issues preventing camorama to work with atomisp Mauro Carvalho Chehab
                   ` (4 preceding siblings ...)
  2021-11-04 12:05 ` [PATCH 5/7] media: atomisp: move atomisp_g_fmt_cap() Mauro Carvalho Chehab
@ 2021-11-04 12:05 ` Mauro Carvalho Chehab
  2021-11-04 12:05 ` [PATCH 7/7] media: atomisp: fix g_fmt logic Mauro Carvalho Chehab
  6 siblings, 0 replies; 8+ messages in thread
From: Mauro Carvalho Chehab @ 2021-11-04 12:05 UTC (permalink / raw)
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, Alex Dewar,
	Aline Santana Cordeiro, Arnd Bergmann, Greg Kroah-Hartman,
	Hans Verkuil, Kaixu Xia, Mauro Carvalho Chehab, Peter Zijlstra,
	Sakari Ailus, Thomas Gleixner, Tomi Valkeinen, Tsuchiya Yuto,
	linux-kernel, linux-media, linux-staging

The internal try_fmt logic is not meant to provide everything
that the V4L2 API should provide. Also, it doesn't decrement
the pads that are used only internally by the driver, but aren't
part of the device's output.

Fix it.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---

To mailbombing on a large number of people, only mailing lists were C/C on the cover.
See [PATCH 0/7] at: https://lore.kernel.org/all/cover.1636026959.git.mchehab+huawei@kernel.org/

 .../staging/media/atomisp/pci/atomisp_cmd.c   |  7 --
 .../staging/media/atomisp/pci/atomisp_ioctl.c | 72 ++++++++++++++++++-
 2 files changed, 71 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
index 851046ecbdbf..0ddee36cdcd7 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c
@@ -4918,13 +4918,6 @@ int atomisp_try_fmt(struct video_device *vdev, struct v4l2_pix_format *f,
 	}
 
 	f->pixelformat = fmt->pixelformat;
-	/*
-	 * FIXME: do we need to setup this differently, depending on the
-	 * sensor or the pipeline?
-	 */
-	f->colorspace = V4L2_COLORSPACE_REC709;
-	f->ycbcr_enc = V4L2_YCBCR_ENC_709;
-	f->xfer_func = V4L2_XFER_FUNC_709;
 
 	/*
 	 * If the format is jpeg or custom RAW, then the width and height will
diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
index 84ff97dabbed..1e6da6116a06 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
@@ -847,6 +847,72 @@ static int atomisp_g_fmt_file(struct file *file, void *fh,
 	return 0;
 }
 
+static int atomisp_adjust_fmt(struct v4l2_format *f)
+{
+	const struct atomisp_format_bridge *format_bridge;
+	u32 padded_width;
+
+	format_bridge = atomisp_get_format_bridge(f->fmt.pix.pixelformat);
+
+	padded_width = f->fmt.pix.width + pad_w;
+
+	if (format_bridge->planar) {
+		f->fmt.pix.bytesperline = padded_width;
+		f->fmt.pix.sizeimage = PAGE_ALIGN(f->fmt.pix.height *
+						  DIV_ROUND_UP(format_bridge->depth *
+						  padded_width, 8));
+	} else {
+		f->fmt.pix.bytesperline = DIV_ROUND_UP(format_bridge->depth *
+						      padded_width, 8);
+		f->fmt.pix.sizeimage = PAGE_ALIGN(f->fmt.pix.height * f->fmt.pix.bytesperline);
+	}
+
+	if (f->fmt.pix.field == V4L2_FIELD_ANY)
+		f->fmt.pix.field = V4L2_FIELD_NONE;
+
+	format_bridge = atomisp_get_format_bridge(f->fmt.pix.pixelformat);
+	if (!format_bridge)
+		return -EINVAL;
+
+	/* Currently, raw formats are broken!!! */
+	if (format_bridge->sh_fmt == IA_CSS_FRAME_FORMAT_RAW) {
+		f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
+
+		format_bridge = atomisp_get_format_bridge(f->fmt.pix.pixelformat);
+		if (!format_bridge)
+			return -EINVAL;
+	}
+
+	padded_width = f->fmt.pix.width + pad_w;
+
+	if (format_bridge->planar) {
+		f->fmt.pix.bytesperline = padded_width;
+		f->fmt.pix.sizeimage = PAGE_ALIGN(f->fmt.pix.height *
+						  DIV_ROUND_UP(format_bridge->depth *
+						  padded_width, 8));
+	} else {
+		f->fmt.pix.bytesperline = DIV_ROUND_UP(format_bridge->depth *
+						      padded_width, 8);
+		f->fmt.pix.sizeimage = PAGE_ALIGN(f->fmt.pix.height * f->fmt.pix.bytesperline);
+	}
+
+	if (f->fmt.pix.field == V4L2_FIELD_ANY)
+		f->fmt.pix.field = V4L2_FIELD_NONE;
+
+	/*
+	 * FIXME: do we need to setup this differently, depending on the
+	 * sensor or the pipeline?
+	 */
+	f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
+	f->fmt.pix.ycbcr_enc = V4L2_YCBCR_ENC_709;
+	f->fmt.pix.xfer_func = V4L2_XFER_FUNC_709;
+
+	f->fmt.pix.width -= pad_w;
+	f->fmt.pix.height -= pad_h;
+
+	return 0;
+}
+
 /* This function looks up the closest available resolution. */
 static int atomisp_try_fmt_cap(struct file *file, void *fh,
 			       struct v4l2_format *f)
@@ -858,7 +924,11 @@ static int atomisp_try_fmt_cap(struct file *file, void *fh,
 	rt_mutex_lock(&isp->mutex);
 	ret = atomisp_try_fmt(vdev, &f->fmt.pix, NULL);
 	rt_mutex_unlock(&isp->mutex);
-	return ret;
+
+	if (ret)
+		return ret;
+
+	return atomisp_adjust_fmt(f);
 }
 
 static int atomisp_g_fmt_cap(struct file *file, void *fh,
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 7/7] media: atomisp: fix g_fmt logic
  2021-11-04 12:05 [PATCH 0/7] Address issues preventing camorama to work with atomisp Mauro Carvalho Chehab
                   ` (5 preceding siblings ...)
  2021-11-04 12:05 ` [PATCH 6/7] media: atomisp: fix try_fmt logic Mauro Carvalho Chehab
@ 2021-11-04 12:05 ` Mauro Carvalho Chehab
  6 siblings, 0 replies; 8+ messages in thread
From: Mauro Carvalho Chehab @ 2021-11-04 12:05 UTC (permalink / raw)
  Cc: linuxarm, mauro.chehab, Mauro Carvalho Chehab, Arnd Bergmann,
	Dan Carpenter, Greg Kroah-Hartman, Kaixu Xia,
	Mauro Carvalho Chehab, Peter Zijlstra, Sakari Ailus,
	Tsuchiya Yuto, linux-kernel, linux-media, linux-staging

The g_fmt logic is currently broken, as it is not returning
the same imagesize as previoulsy calculated by s_fmt.

Fix it by just re-using whatever it was defined at s_fmt,
if this was called before.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---

To mailbombing on a large number of people, only mailing lists were C/C on the cover.
See [PATCH 0/7] at: https://lore.kernel.org/all/cover.1636026959.git.mchehab+huawei@kernel.org/

 .../staging/media/atomisp/pci/atomisp_ioctl.c | 64 ++-----------------
 1 file changed, 7 insertions(+), 57 deletions(-)

diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
index 1e6da6116a06..2fb64d5cbead 100644
--- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
+++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
@@ -934,75 +934,25 @@ static int atomisp_try_fmt_cap(struct file *file, void *fh,
 static int atomisp_g_fmt_cap(struct file *file, void *fh,
 			     struct v4l2_format *f)
 {
-	struct v4l2_subdev_format fmt = {
-		.which = V4L2_SUBDEV_FORMAT_ACTIVE
-	};
 	struct video_device *vdev = video_devdata(file);
 	struct atomisp_device *isp = video_get_drvdata(vdev);
-	struct v4l2_fmtdesc fmtdesc = { 0 };
 	struct atomisp_video_pipe *pipe;
-	struct atomisp_sub_device *asd;
-	struct v4l2_subdev *camera;
-	u32 depth;
-	int ret;
 
 	rt_mutex_lock(&isp->mutex);
 	pipe = atomisp_to_video_pipe(vdev);
 	rt_mutex_unlock(&isp->mutex);
 
 	f->fmt.pix = pipe->pix;
-	if (!f->fmt.pix.width) {
-		asd = atomisp_to_video_pipe(vdev)->asd;
-		if (!asd)
-		    return -EINVAL;
 
-		camera = isp->inputs[asd->input_curr].camera;
-		if(!camera)
-			return -EINVAL;
+	/* If s_fmt was issued, just return whatever is was previouly set */
+	if (f->fmt.pix.sizeimage)
+		return 0;
 
-		ret = atomisp_enum_fmt_cap(file, fh, &fmtdesc);
-		if (ret)
-			return ret;
+	f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+	f->fmt.pix.width = 10000;
+	f->fmt.pix.height = 10000;
 
-		rt_mutex_lock(&isp->mutex);
-		ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
-				       pad, get_fmt, NULL, &fmt);
-		rt_mutex_unlock(&isp->mutex);
-		if (ret)
-			return ret;
-
-		v4l2_fill_pix_format(&f->fmt.pix, &fmt.format);
-
-		f->fmt.pix.pixelformat = fmtdesc.pixelformat;
-
-		/*
-		 * HACK: The atomisp does something different here, as it
-		 * seems to set the sensor to a slightly higher resolution than
-		 * the visible ones. That seems to be needed by atomisp's ISP
-		 * in order to properly handle the frames. So, s_fmt adds 16
-		 * extra columns/lines. See atomisp_subdev_set_selection().
-		 *
-		 * Yet, the V4L2 userspace API doesn't expect those, so it
-		 * needs to be decremented when reporting the visible
-		 * resolution to userspace.
-		 */
-		f->fmt.pix.width -= pad_w;
-		f->fmt.pix.height -= pad_h;
-	}
-
-	depth = atomisp_get_pixel_depth(f->fmt.pix.pixelformat);
-	f->fmt.pix.bytesperline = DIV_ROUND_UP(f->fmt.pix.width * depth, 8);
-	f->fmt.pix.sizeimage = PAGE_ALIGN(f->fmt.pix.height * f->fmt.pix.bytesperline);
-
-	/*
-	 * FIXME: do we need to setup this differently, depending on the
-	 * sensor or the pipeline?
-	 */
-	f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
-	f->fmt.pix.ycbcr_enc = V4L2_YCBCR_ENC_709;
-	f->fmt.pix.xfer_func = V4L2_XFER_FUNC_709;
-
-	return 0;
+	return atomisp_try_fmt_cap(file, fh, f);
 }
 
 static int atomisp_s_fmt_cap(struct file *file, void *fh,
-- 
2.31.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2021-11-04 12:06 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-04 12:05 [PATCH 0/7] Address issues preventing camorama to work with atomisp Mauro Carvalho Chehab
2021-11-04 12:05 ` [PATCH 1/7] media: atomisp-ov2680: use v4l2_find_nearest_size() Mauro Carvalho Chehab
2021-11-04 12:05 ` [PATCH 2/7] media: atomisp: move a debug printf to a better place Mauro Carvalho Chehab
2021-11-04 12:05 ` [PATCH 3/7] media: atomisp: fix VIDIOC_S_FMT logic Mauro Carvalho Chehab
2021-11-04 12:05 ` [PATCH 4/7] media: atomisp: fix enum_fmt logic Mauro Carvalho Chehab
2021-11-04 12:05 ` [PATCH 5/7] media: atomisp: move atomisp_g_fmt_cap() Mauro Carvalho Chehab
2021-11-04 12:05 ` [PATCH 6/7] media: atomisp: fix try_fmt logic Mauro Carvalho Chehab
2021-11-04 12:05 ` [PATCH 7/7] media: atomisp: fix g_fmt logic Mauro Carvalho Chehab

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).