bcm27xx: update 5.4 patches from RPi foundation
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
This commit is contained in:
		| @@ -243,6 +243,8 @@ CONFIG_HAVE_SYSCALL_TRACEPOINTS=y | |||||||
| CONFIG_HAVE_UID16=y | CONFIG_HAVE_UID16=y | ||||||
| CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y | CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y | ||||||
| CONFIG_HW_CONSOLE=y | CONFIG_HW_CONSOLE=y | ||||||
|  | CONFIG_HZ=100 | ||||||
|  | CONFIG_HZ_100=y | ||||||
| CONFIG_HZ_FIXED=0 | CONFIG_HZ_FIXED=0 | ||||||
| CONFIG_I2C=y | CONFIG_I2C=y | ||||||
| # CONFIG_I2C_BCM2708 is not set | # CONFIG_I2C_BCM2708 is not set | ||||||
|   | |||||||
| @@ -311,6 +311,8 @@ CONFIG_HIGHMEM=y | |||||||
| CONFIG_HIGHPTE=y | CONFIG_HIGHPTE=y | ||||||
| CONFIG_HOTPLUG_CPU=y | CONFIG_HOTPLUG_CPU=y | ||||||
| CONFIG_HW_CONSOLE=y | CONFIG_HW_CONSOLE=y | ||||||
|  | CONFIG_HZ=100 | ||||||
|  | CONFIG_HZ_100=y | ||||||
| CONFIG_HZ_FIXED=0 | CONFIG_HZ_FIXED=0 | ||||||
| CONFIG_I2C=y | CONFIG_I2C=y | ||||||
| # CONFIG_I2C_BCM2708 is not set | # CONFIG_I2C_BCM2708 is not set | ||||||
|   | |||||||
| @@ -367,6 +367,8 @@ CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y | |||||||
| CONFIG_HOLES_IN_ZONE=y | CONFIG_HOLES_IN_ZONE=y | ||||||
| CONFIG_HOTPLUG_CPU=y | CONFIG_HOTPLUG_CPU=y | ||||||
| CONFIG_HW_CONSOLE=y | CONFIG_HW_CONSOLE=y | ||||||
|  | CONFIG_HZ=250 | ||||||
|  | CONFIG_HZ_250=y | ||||||
| CONFIG_I2C=y | CONFIG_I2C=y | ||||||
| # CONFIG_I2C_BCM2708 is not set | # CONFIG_I2C_BCM2708 is not set | ||||||
| CONFIG_I2C_BOARDINFO=y | CONFIG_I2C_BOARDINFO=y | ||||||
|   | |||||||
| @@ -373,6 +373,8 @@ CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y | |||||||
| CONFIG_HOLES_IN_ZONE=y | CONFIG_HOLES_IN_ZONE=y | ||||||
| CONFIG_HOTPLUG_CPU=y | CONFIG_HOTPLUG_CPU=y | ||||||
| CONFIG_HW_CONSOLE=y | CONFIG_HW_CONSOLE=y | ||||||
|  | CONFIG_HZ=250 | ||||||
|  | CONFIG_HZ_250=y | ||||||
| CONFIG_I2C=y | CONFIG_I2C=y | ||||||
| # CONFIG_I2C_BCM2708 is not set | # CONFIG_I2C_BCM2708 is not set | ||||||
| CONFIG_I2C_BOARDINFO=y | CONFIG_I2C_BOARDINFO=y | ||||||
|   | |||||||
| @@ -0,0 +1,89 @@ | |||||||
|  | From 12b60ef71cc005ee7290f692169d46a7e78df01a Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Yukimasa Sugizaki <4298265+Terminus-IMRC@users.noreply.github.com> | ||||||
|  | Date: Fri, 20 Mar 2020 19:01:23 +0900 | ||||||
|  | Subject: [PATCH] drm/v3d: Replace wait_for macros to remove use of | ||||||
|  |  msleep (#3510) | ||||||
|  |  | ||||||
|  | commit 9daee6141cc9c75b09659b02b1cb9eeb2f5e16cc upstream. | ||||||
|  |  | ||||||
|  | The wait_for macro's for Broadcom V3D driver used msleep, which is | ||||||
|  | inappropriate due to its inaccuracy at low values (minimum wait time | ||||||
|  | is about 30ms on the Raspberry Pi).  This sleep was triggering in | ||||||
|  | v3d_clean_caches(), causing us to only be able to dispatch ~33 compute | ||||||
|  | jobs per second. | ||||||
|  |  | ||||||
|  | This patch replaces the macro with the one from the Intel i915 version | ||||||
|  | which uses usleep_range to provide more accurate waits. | ||||||
|  |  | ||||||
|  | v2: Split from the vc4 patch so that we can confidently apply to | ||||||
|  |     stable (by anholt) | ||||||
|  |  | ||||||
|  | Signed-off-by: James Hughes <james.hughes@raspberrypi.com> | ||||||
|  | Signed-off-by: Eric Anholt <eric@anholt.net> | ||||||
|  | Link: https://patchwork.freedesktop.org/patch/msgid/20200217153145.13780-1-james.hughes@raspberrypi.com | ||||||
|  | Link: https://github.com/raspberrypi/linux/issues/3460 | ||||||
|  | Fixes: 57692c94dcbe ("drm/v3d: Introduce a new DRM driver for Broadcom V3D V3.x+") | ||||||
|  |  | ||||||
|  | Co-authored-by: James Hughes <james.hughes@raspberrypi.com> | ||||||
|  | --- | ||||||
|  |  drivers/gpu/drm/v3d/v3d_drv.h | 41 ++++++++++++++++++++++++----------- | ||||||
|  |  1 file changed, 28 insertions(+), 13 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/gpu/drm/v3d/v3d_drv.h | ||||||
|  | +++ b/drivers/gpu/drm/v3d/v3d_drv.h | ||||||
|  | @@ -260,27 +260,42 @@ struct v3d_csd_job { | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  /** | ||||||
|  | - * _wait_for - magic (register) wait macro | ||||||
|  | + * __wait_for - magic wait macro | ||||||
|  |   * | ||||||
|  | - * Does the right thing for modeset paths when run under kdgb or similar atomic | ||||||
|  | - * contexts. Note that it's important that we check the condition again after | ||||||
|  | - * having timed out, since the timeout could be due to preemption or similar and | ||||||
|  | - * we've never had a chance to check the condition before the timeout. | ||||||
|  | + * Macro to help avoid open coding check/wait/timeout patterns. Note that it's | ||||||
|  | + * important that we check the condition again after having timed out, since the | ||||||
|  | + * timeout could be due to preemption or similar and we've never had a chance to | ||||||
|  | + * check the condition before the timeout. | ||||||
|  |   */ | ||||||
|  | -#define wait_for(COND, MS) ({ \ | ||||||
|  | -	unsigned long timeout__ = jiffies + msecs_to_jiffies(MS) + 1;	\ | ||||||
|  | -	int ret__ = 0;							\ | ||||||
|  | -	while (!(COND)) {						\ | ||||||
|  | -		if (time_after(jiffies, timeout__)) {			\ | ||||||
|  | -			if (!(COND))					\ | ||||||
|  | -				ret__ = -ETIMEDOUT;			\ | ||||||
|  | +#define __wait_for(OP, COND, US, Wmin, Wmax) ({ \ | ||||||
|  | +	const ktime_t end__ = ktime_add_ns(ktime_get_raw(), 1000ll * (US)); \ | ||||||
|  | +	long wait__ = (Wmin); /* recommended min for usleep is 10 us */	\ | ||||||
|  | +	int ret__;							\ | ||||||
|  | +	might_sleep();							\ | ||||||
|  | +	for (;;) {							\ | ||||||
|  | +		const bool expired__ = ktime_after(ktime_get_raw(), end__); \ | ||||||
|  | +		OP;							\ | ||||||
|  | +		/* Guarantee COND check prior to timeout */		\ | ||||||
|  | +		barrier();						\ | ||||||
|  | +		if (COND) {						\ | ||||||
|  | +			ret__ = 0;					\ | ||||||
|  |  			break;						\ | ||||||
|  |  		}							\ | ||||||
|  | -		msleep(1);					\ | ||||||
|  | +		if (expired__) {					\ | ||||||
|  | +			ret__ = -ETIMEDOUT;				\ | ||||||
|  | +			break;						\ | ||||||
|  | +		}							\ | ||||||
|  | +		usleep_range(wait__, wait__ * 2);			\ | ||||||
|  | +		if (wait__ < (Wmax))					\ | ||||||
|  | +			wait__ <<= 1;					\ | ||||||
|  |  	}								\ | ||||||
|  |  	ret__;								\ | ||||||
|  |  }) | ||||||
|  |   | ||||||
|  | +#define _wait_for(COND, US, Wmin, Wmax)	__wait_for(, (COND), (US), (Wmin), \ | ||||||
|  | +						   (Wmax)) | ||||||
|  | +#define wait_for(COND, MS)		_wait_for((COND), (MS) * 1000, 10, 1000) | ||||||
|  | + | ||||||
|  |  static inline unsigned long nsecs_to_jiffies_timeout(const u64 n) | ||||||
|  |  { | ||||||
|  |  	/* nsecs_to_jiffies64() does not guard against overflow */ | ||||||
| @@ -0,0 +1,96 @@ | |||||||
|  | From 863dace20e48954a7e013a2e88e27c692ce165b0 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Nick B <nick@pelagiris.org> | ||||||
|  | Date: Mon, 9 Mar 2020 09:05:39 -0400 | ||||||
|  | Subject: [PATCH] Reduce noise from rpi poe hat fan | ||||||
|  |  | ||||||
|  | This adds 2 extra states, at 40c and 45c, with PWM of 31 and 63 (out | ||||||
|  | of 255) for the rpi poe hat fan.  This significantly improves user | ||||||
|  | experience by providing a smoother ramp up of the fan, from a pwm 0 | ||||||
|  | to 31 to 63 then finally to 150, and additionally makes it very easy | ||||||
|  | for users to further tweak the values as needed for their specific | ||||||
|  | application. | ||||||
|  |  | ||||||
|  | The possible concerns I have are that a hysteresis of 2000 (2c) could | ||||||
|  | be too narrow, and that running the fan more at a reduced temperature | ||||||
|  | (40000 - 40c) could cause problems. | ||||||
|  |  | ||||||
|  | Signed-off-by: Nick B <nick@pelagiris.org> | ||||||
|  | --- | ||||||
|  |  .../arm/boot/dts/overlays/rpi-poe-overlay.dts | 35 ++++++++++++++++--- | ||||||
|  |  1 file changed, 30 insertions(+), 5 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/arch/arm/boot/dts/overlays/rpi-poe-overlay.dts | ||||||
|  | +++ b/arch/arm/boot/dts/overlays/rpi-poe-overlay.dts | ||||||
|  | @@ -14,9 +14,9 @@ | ||||||
|  |  				compatible = "raspberrypi,rpi-poe-fan"; | ||||||
|  |  				firmware = <&firmware>; | ||||||
|  |  				cooling-min-state = <0>; | ||||||
|  | -				cooling-max-state = <2>; | ||||||
|  | +				cooling-max-state = <4>; | ||||||
|  |  				#cooling-cells = <2>; | ||||||
|  | -				cooling-levels = <0 150 255>; | ||||||
|  | +				cooling-levels = <0 31 63 150 255>; | ||||||
|  |  				status = "okay"; | ||||||
|  |  			}; | ||||||
|  |  		}; | ||||||
|  | @@ -27,12 +27,21 @@ | ||||||
|  |  		__overlay__ { | ||||||
|  |  			trips { | ||||||
|  |  				trip0: trip0 { | ||||||
|  | -					temperature = <50000>; | ||||||
|  | -					hysteresis = <5000>; | ||||||
|  | +					temperature = <40000>; | ||||||
|  | +					hysteresis = <2000>; | ||||||
|  |  					type = "active"; | ||||||
|  |  				}; | ||||||
|  |  				trip1: trip1 { | ||||||
|  | - | ||||||
|  | +					temperature = <45000>; | ||||||
|  | +					hysteresis = <2000>; | ||||||
|  | +					type = "active"; | ||||||
|  | +				}; | ||||||
|  | +				trip2: trip2 { | ||||||
|  | +					temperature = <50000>; | ||||||
|  | +					hysteresis = <2000>; | ||||||
|  | +					type = "active"; | ||||||
|  | +				}; | ||||||
|  | +				trip3: trip3 { | ||||||
|  |  					temperature = <55000>; | ||||||
|  |  					hysteresis = <5000>; | ||||||
|  |  					type = "active"; | ||||||
|  | @@ -47,6 +56,14 @@ | ||||||
|  |  					trip = <&trip1>; | ||||||
|  |  					cooling-device = <&fan0 1 2>; | ||||||
|  |  				}; | ||||||
|  | +				map2 { | ||||||
|  | +					trip = <&trip2>; | ||||||
|  | +					cooling-device = <&fan0 2 3>; | ||||||
|  | +				}; | ||||||
|  | +				map3 { | ||||||
|  | +					trip = <&trip3>; | ||||||
|  | +					cooling-device = <&fan0 3 4>; | ||||||
|  | +				}; | ||||||
|  |  			}; | ||||||
|  |  		}; | ||||||
|  |  	}; | ||||||
|  | @@ -58,6 +75,10 @@ | ||||||
|  |  			poe_fan_temp0_hyst =	<&trip0>,"hysteresis:0"; | ||||||
|  |  			poe_fan_temp1 =		<&trip1>,"temperature:0"; | ||||||
|  |  			poe_fan_temp1_hyst =	<&trip1>,"hysteresis:0"; | ||||||
|  | +			poe_fan_temp2 =		<&trip2>,"temperature:0"; | ||||||
|  | +			poe_fan_temp2_hyst =	<&trip2>,"hysteresis:0"; | ||||||
|  | +			poe_fan_temp3 =		<&trip3>,"temperature:0"; | ||||||
|  | +			poe_fan_temp3_hyst =	<&trip3>,"hysteresis:0"; | ||||||
|  |  		}; | ||||||
|  |  	}; | ||||||
|  |   | ||||||
|  | @@ -66,5 +87,9 @@ | ||||||
|  |  		poe_fan_temp0_hyst =	<&trip0>,"hysteresis:0"; | ||||||
|  |  		poe_fan_temp1 =		<&trip1>,"temperature:0"; | ||||||
|  |  		poe_fan_temp1_hyst =	<&trip1>,"hysteresis:0"; | ||||||
|  | +		poe_fan_temp2 =		<&trip2>,"temperature:0"; | ||||||
|  | +		poe_fan_temp2_hyst =	<&trip2>,"hysteresis:0"; | ||||||
|  | +		poe_fan_temp3 =		<&trip3>,"temperature:0"; | ||||||
|  | +		poe_fan_temp3_hyst =	<&trip3>,"hysteresis:0"; | ||||||
|  |  	}; | ||||||
|  |  }; | ||||||
| @@ -1,4 +1,4 @@ | |||||||
| From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | From 60f3874207c50db6f6d9dbac40977843cb77acd5 Mon Sep 17 00:00:00 2001 | ||||||
| From: =?UTF-8?q?Petr=20=C5=A0tetiar?= <ynezz@true.cz> | From: =?UTF-8?q?Petr=20=C5=A0tetiar?= <ynezz@true.cz> | ||||||
| Date: Sat, 7 Mar 2020 22:37:52 +0100 | Date: Sat, 7 Mar 2020 22:37:52 +0100 | ||||||
| Subject: [PATCH] add Sensirion SPS30 to i2c-sensor overlay | Subject: [PATCH] add Sensirion SPS30 to i2c-sensor overlay | ||||||
| @@ -10,12 +10,14 @@ Add support for Sensirion SPS30 particulate matter sensor with fixed | |||||||
| address 0x69. | address 0x69. | ||||||
| 
 | 
 | ||||||
| Signed-off-by: Petr Štetiar <ynezz@true.cz> | Signed-off-by: Petr Štetiar <ynezz@true.cz> | ||||||
|  | ---
 | ||||||
|  |  arch/arm/boot/dts/overlays/README                 |  3 +++ | ||||||
|  |  arch/arm/boot/dts/overlays/i2c-sensor-overlay.dts | 15 +++++++++++++++ | ||||||
|  |  2 files changed, 18 insertions(+) | ||||||
| 
 | 
 | ||||||
| diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README
 |  | ||||||
| index 62ad35f78bad..0d7d00ac92c4 100644
 |  | ||||||
| --- a/arch/arm/boot/dts/overlays/README
 | --- a/arch/arm/boot/dts/overlays/README
 | ||||||
| +++ b/arch/arm/boot/dts/overlays/README
 | +++ b/arch/arm/boot/dts/overlays/README
 | ||||||
| @@ -1261,6 +1261,9 @@ Params: addr                    Set the address for the BME280, BME680, BMP280,
 | @@ -1261,6 +1261,9 @@ Params: addr                    Set the
 | ||||||
|          si7020                  Select the Silicon Labs Si7013/20/21 humidity/ |          si7020                  Select the Silicon Labs Si7013/20/21 humidity/ | ||||||
|                                  temperature sensor |                                  temperature sensor | ||||||
|   |   | ||||||
| @@ -25,8 +27,6 @@ index 62ad35f78bad..0d7d00ac92c4 100644 | |||||||
|          tmp102                  Select the Texas Instruments TMP102 temp sensor |          tmp102                  Select the Texas Instruments TMP102 temp sensor | ||||||
|                                  Valid addresses 0x48-0x4b, default 0x48 |                                  Valid addresses 0x48-0x4b, default 0x48 | ||||||
|   |   | ||||||
| diff --git a/arch/arm/boot/dts/overlays/i2c-sensor-overlay.dts b/arch/arm/boot/dts/overlays/i2c-sensor-overlay.dts
 |  | ||||||
| index 40881d72a157..ce97837b0db5 100644
 |  | ||||||
| --- a/arch/arm/boot/dts/overlays/i2c-sensor-overlay.dts
 | --- a/arch/arm/boot/dts/overlays/i2c-sensor-overlay.dts
 | ||||||
| +++ b/arch/arm/boot/dts/overlays/i2c-sensor-overlay.dts
 | +++ b/arch/arm/boot/dts/overlays/i2c-sensor-overlay.dts
 | ||||||
| @@ -231,6 +231,20 @@
 | @@ -231,6 +231,20 @@
 | ||||||
| @@ -0,0 +1,157 @@ | |||||||
|  | From 4af6218f1d01e5ae54dc43e4bd2421617c777570 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Ricardo Ribalda Delgado <ribalda@kernel.org> | ||||||
|  | Date: Mon, 7 Oct 2019 12:06:31 -0300 | ||||||
|  | Subject: [PATCH] media: add V4L2_CTRL_TYPE_AREA control type | ||||||
|  |  | ||||||
|  | Commit d1dc49370f8371b00e682ac409aa1987ce641e93 upstream. | ||||||
|  |  | ||||||
|  | This type contains the width and the height of a rectangular area. | ||||||
|  |  | ||||||
|  | Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> | ||||||
|  | Signed-off-by: Ricardo Ribalda Delgado <ribalda@kernel.org> | ||||||
|  | Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> | ||||||
|  | Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | ||||||
|  | --- | ||||||
|  |  drivers/media/v4l2-core/v4l2-ctrls.c | 21 ++++++++++++++ | ||||||
|  |  include/media/v4l2-ctrls.h           | 42 ++++++++++++++++++++++++++++ | ||||||
|  |  include/uapi/linux/videodev2.h       |  6 ++++ | ||||||
|  |  3 files changed, 69 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/media/v4l2-core/v4l2-ctrls.c | ||||||
|  | +++ b/drivers/media/v4l2-core/v4l2-ctrls.c | ||||||
|  | @@ -1673,6 +1673,7 @@ static int std_validate_compound(const s | ||||||
|  |  { | ||||||
|  |  	struct v4l2_ctrl_mpeg2_slice_params *p_mpeg2_slice_params; | ||||||
|  |  	struct v4l2_ctrl_vp8_frame_header *p_vp8_frame_header; | ||||||
|  | +	struct v4l2_area *area; | ||||||
|  |  	void *p = ptr.p + idx * ctrl->elem_size; | ||||||
|  |   | ||||||
|  |  	switch ((u32)ctrl->type) { | ||||||
|  | @@ -1749,6 +1750,11 @@ static int std_validate_compound(const s | ||||||
|  |  		zero_padding(p_vp8_frame_header->entropy_header); | ||||||
|  |  		zero_padding(p_vp8_frame_header->coder_state); | ||||||
|  |  		break; | ||||||
|  | +	case V4L2_CTRL_TYPE_AREA: | ||||||
|  | +		area = p; | ||||||
|  | +		if (!area->width || !area->height) | ||||||
|  | +			return -EINVAL; | ||||||
|  | +		break; | ||||||
|  |  	default: | ||||||
|  |  		return -EINVAL; | ||||||
|  |  	} | ||||||
|  | @@ -2422,6 +2428,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(s | ||||||
|  |  	case V4L2_CTRL_TYPE_VP8_FRAME_HEADER: | ||||||
|  |  		elem_size = sizeof(struct v4l2_ctrl_vp8_frame_header); | ||||||
|  |  		break; | ||||||
|  | +	case V4L2_CTRL_TYPE_AREA: | ||||||
|  | +		elem_size = sizeof(struct v4l2_area); | ||||||
|  | +		break; | ||||||
|  |  	default: | ||||||
|  |  		if (type < V4L2_CTRL_COMPOUND_TYPES) | ||||||
|  |  			elem_size = sizeof(s32); | ||||||
|  | @@ -4086,6 +4095,18 @@ int __v4l2_ctrl_s_ctrl_string(struct v4l | ||||||
|  |  } | ||||||
|  |  EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_string); | ||||||
|  |   | ||||||
|  | +int __v4l2_ctrl_s_ctrl_area(struct v4l2_ctrl *ctrl, | ||||||
|  | +			    const struct v4l2_area *area) | ||||||
|  | +{ | ||||||
|  | +	lockdep_assert_held(ctrl->handler->lock); | ||||||
|  | + | ||||||
|  | +	/* It's a driver bug if this happens. */ | ||||||
|  | +	WARN_ON(ctrl->type != V4L2_CTRL_TYPE_AREA); | ||||||
|  | +	*ctrl->p_new.p_area = *area; | ||||||
|  | +	return set_ctrl(NULL, ctrl, 0); | ||||||
|  | +} | ||||||
|  | +EXPORT_SYMBOL(__v4l2_ctrl_s_ctrl_area); | ||||||
|  | + | ||||||
|  |  void v4l2_ctrl_request_complete(struct media_request *req, | ||||||
|  |  				struct v4l2_ctrl_handler *main_hdl) | ||||||
|  |  { | ||||||
|  | --- a/include/media/v4l2-ctrls.h | ||||||
|  | +++ b/include/media/v4l2-ctrls.h | ||||||
|  | @@ -50,6 +50,7 @@ struct poll_table_struct; | ||||||
|  |   * @p_h264_slice_params:	Pointer to a struct v4l2_ctrl_h264_slice_params. | ||||||
|  |   * @p_h264_decode_params:	Pointer to a struct v4l2_ctrl_h264_decode_params. | ||||||
|  |   * @p_vp8_frame_header:		Pointer to a VP8 frame header structure. | ||||||
|  | + * @p_area:			Pointer to an area. | ||||||
|  |   * @p:				Pointer to a compound value. | ||||||
|  |   */ | ||||||
|  |  union v4l2_ctrl_ptr { | ||||||
|  | @@ -68,6 +69,7 @@ union v4l2_ctrl_ptr { | ||||||
|  |  	struct v4l2_ctrl_h264_slice_params *p_h264_slice_params; | ||||||
|  |  	struct v4l2_ctrl_h264_decode_params *p_h264_decode_params; | ||||||
|  |  	struct v4l2_ctrl_vp8_frame_header *p_vp8_frame_header; | ||||||
|  | +	struct v4l2_area *p_area; | ||||||
|  |  	void *p; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | @@ -1063,6 +1065,46 @@ static inline int v4l2_ctrl_s_ctrl_strin | ||||||
|  |  	v4l2_ctrl_unlock(ctrl); | ||||||
|  |   | ||||||
|  |  	return rval; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +/** | ||||||
|  | + * __v4l2_ctrl_s_ctrl_area() - Unlocked variant of v4l2_ctrl_s_ctrl_area(). | ||||||
|  | + * | ||||||
|  | + * @ctrl:	The control. | ||||||
|  | + * @area:	The new area. | ||||||
|  | + * | ||||||
|  | + * This sets the control's new area safely by going through the control | ||||||
|  | + * framework. This function assumes the control's handler is already locked, | ||||||
|  | + * allowing it to be used from within the &v4l2_ctrl_ops functions. | ||||||
|  | + * | ||||||
|  | + * This function is for area type controls only. | ||||||
|  | + */ | ||||||
|  | +int __v4l2_ctrl_s_ctrl_area(struct v4l2_ctrl *ctrl, | ||||||
|  | +			    const struct v4l2_area *area); | ||||||
|  | + | ||||||
|  | +/** | ||||||
|  | + * v4l2_ctrl_s_ctrl_area() - Helper function to set a control's area value | ||||||
|  | + *	 from within a driver. | ||||||
|  | + * | ||||||
|  | + * @ctrl:	The control. | ||||||
|  | + * @area:	The new area. | ||||||
|  | + * | ||||||
|  | + * This sets the control's new area safely by going through the control | ||||||
|  | + * framework. This function will lock the control's handler, so it cannot be | ||||||
|  | + * used from within the &v4l2_ctrl_ops functions. | ||||||
|  | + * | ||||||
|  | + * This function is for area type controls only. | ||||||
|  | + */ | ||||||
|  | +static inline int v4l2_ctrl_s_ctrl_area(struct v4l2_ctrl *ctrl, | ||||||
|  | +					const struct v4l2_area *area) | ||||||
|  | +{ | ||||||
|  | +	int rval; | ||||||
|  | + | ||||||
|  | +	v4l2_ctrl_lock(ctrl); | ||||||
|  | +	rval = __v4l2_ctrl_s_ctrl_area(ctrl, area); | ||||||
|  | +	v4l2_ctrl_unlock(ctrl); | ||||||
|  | + | ||||||
|  | +	return rval; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  /* Internal helper functions that deal with control events. */ | ||||||
|  | --- a/include/uapi/linux/videodev2.h | ||||||
|  | +++ b/include/uapi/linux/videodev2.h | ||||||
|  | @@ -427,6 +427,11 @@ struct v4l2_fract { | ||||||
|  |  	__u32   denominator; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | +struct v4l2_area { | ||||||
|  | +	__u32   width; | ||||||
|  | +	__u32   height; | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  |  /** | ||||||
|  |    * struct v4l2_capability - Describes V4L2 device caps returned by VIDIOC_QUERYCAP | ||||||
|  |    * | ||||||
|  | @@ -1725,6 +1730,7 @@ enum v4l2_ctrl_type { | ||||||
|  |  	V4L2_CTRL_TYPE_U8	     = 0x0100, | ||||||
|  |  	V4L2_CTRL_TYPE_U16	     = 0x0101, | ||||||
|  |  	V4L2_CTRL_TYPE_U32	     = 0x0102, | ||||||
|  | +	V4L2_CTRL_TYPE_AREA          = 0x0106, | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  /*  Used in the VIDIOC_QUERYCTRL ioctl for querying controls */ | ||||||
| @@ -0,0 +1,52 @@ | |||||||
|  | From 12eba72027d415bb3dfd4c8124813a322b27c793 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Ricardo Ribalda Delgado <ribalda@kernel.org> | ||||||
|  | Date: Mon, 7 Oct 2019 12:06:33 -0300 | ||||||
|  | Subject: [PATCH] media: add V4L2_CID_UNIT_CELL_SIZE control | ||||||
|  |  | ||||||
|  | Commit 61fd036d01111679b01e4b92e6bd0cdd33809aea upstream. | ||||||
|  |  | ||||||
|  | This control returns the unit cell size in nanometres. The struct provides | ||||||
|  | the width and the height in separated fields to take into consideration | ||||||
|  | asymmetric pixels and/or hardware binning. | ||||||
|  | This control is required for automatic calibration of sensors/cameras. | ||||||
|  |  | ||||||
|  | Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> | ||||||
|  | Signed-off-by: Ricardo Ribalda Delgado <ribalda@kernel.org> | ||||||
|  | Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> | ||||||
|  | Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | ||||||
|  | --- | ||||||
|  |  drivers/media/v4l2-core/v4l2-ctrls.c | 5 +++++ | ||||||
|  |  include/uapi/linux/v4l2-controls.h   | 1 + | ||||||
|  |  2 files changed, 6 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/media/v4l2-core/v4l2-ctrls.c | ||||||
|  | +++ b/drivers/media/v4l2-core/v4l2-ctrls.c | ||||||
|  | @@ -995,6 +995,7 @@ const char *v4l2_ctrl_get_name(u32 id) | ||||||
|  |  	case V4L2_CID_AUTO_FOCUS_RANGE:		return "Auto Focus, Range"; | ||||||
|  |  	case V4L2_CID_PAN_SPEED:		return "Pan, Speed"; | ||||||
|  |  	case V4L2_CID_TILT_SPEED:		return "Tilt, Speed"; | ||||||
|  | +	case V4L2_CID_UNIT_CELL_SIZE:		return "Unit Cell Size"; | ||||||
|  |   | ||||||
|  |  	/* FM Radio Modulator controls */ | ||||||
|  |  	/* Keep the order of the 'case's the same as in v4l2-controls.h! */ | ||||||
|  | @@ -1376,6 +1377,10 @@ void v4l2_ctrl_fill(u32 id, const char * | ||||||
|  |  	case V4L2_CID_MPEG_VIDEO_VP8_FRAME_HEADER: | ||||||
|  |  		*type = V4L2_CTRL_TYPE_VP8_FRAME_HEADER; | ||||||
|  |  		break; | ||||||
|  | +	case V4L2_CID_UNIT_CELL_SIZE: | ||||||
|  | +		*type = V4L2_CTRL_TYPE_AREA; | ||||||
|  | +		*flags |= V4L2_CTRL_FLAG_READ_ONLY; | ||||||
|  | +		break; | ||||||
|  |  	default: | ||||||
|  |  		*type = V4L2_CTRL_TYPE_INTEGER; | ||||||
|  |  		break; | ||||||
|  | --- a/include/uapi/linux/v4l2-controls.h | ||||||
|  | +++ b/include/uapi/linux/v4l2-controls.h | ||||||
|  | @@ -1035,6 +1035,7 @@ enum v4l2_jpeg_chroma_subsampling { | ||||||
|  |  #define V4L2_CID_TEST_PATTERN_GREENR		(V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 5) | ||||||
|  |  #define V4L2_CID_TEST_PATTERN_BLUE		(V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 6) | ||||||
|  |  #define V4L2_CID_TEST_PATTERN_GREENB		(V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 7) | ||||||
|  | +#define V4L2_CID_UNIT_CELL_SIZE			(V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 8) | ||||||
|  |   | ||||||
|  |   | ||||||
|  |  /* Image processing controls */ | ||||||
| @@ -0,0 +1,228 @@ | |||||||
|  | From c63ea6a840ad87e32239eb6b771ac8bbc3279b54 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Benoit Parrot <bparrot@ti.com> | ||||||
|  | Date: Mon, 7 Oct 2019 12:10:07 -0300 | ||||||
|  | Subject: [PATCH] media: v4l2-common: add pixel encoding support | ||||||
|  |  | ||||||
|  | Commit d5a897c8428b38053df4b427a4277b1a0722bfa0 upstream. | ||||||
|  |  | ||||||
|  | It is often useful to figure out if a pixel_format is either YUV or RGB | ||||||
|  | especially for driver who can perform the pixel encoding conversion. | ||||||
|  |  | ||||||
|  | Instead of having each driver implement its own "is_this_yuv/rgb" | ||||||
|  | function based on a restricted set of pixel value, it is better to do | ||||||
|  | this in centralized manner. | ||||||
|  |  | ||||||
|  | We therefore add a pixel_enc member to the v4l2_format_info structure to | ||||||
|  | quickly identify the related pixel encoding. | ||||||
|  | And add helper functions to check pixel encoding. | ||||||
|  |  | ||||||
|  | Signed-off-by: Benoit Parrot <bparrot@ti.com> | ||||||
|  | Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> | ||||||
|  | Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | ||||||
|  | --- | ||||||
|  |  drivers/media/v4l2-core/v4l2-common.c | 126 +++++++++++++------------- | ||||||
|  |  include/media/v4l2-common.h           |  33 ++++++- | ||||||
|  |  2 files changed, 95 insertions(+), 64 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/media/v4l2-core/v4l2-common.c | ||||||
|  | +++ b/drivers/media/v4l2-core/v4l2-common.c | ||||||
|  | @@ -236,77 +236,77 @@ const struct v4l2_format_info *v4l2_form | ||||||
|  |  { | ||||||
|  |  	static const struct v4l2_format_info formats[] = { | ||||||
|  |  		/* RGB formats */ | ||||||
|  | -		{ .format = V4L2_PIX_FMT_BGR24,   .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_RGB24,   .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_HSV24,   .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_BGR32,   .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_XBGR32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_BGRX32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_RGB32,   .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_XRGB32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_RGBX32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_HSV32,   .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_ARGB32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_RGBA32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_ABGR32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_BGRA32,  .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_GREY,    .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_BGR24,   .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_RGB24,   .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_HSV24,   .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_BGR32,   .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_XBGR32,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_BGRX32,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_RGB32,   .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_XRGB32,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_RGBX32,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_HSV32,   .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_ARGB32,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_RGBA32,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_ABGR32,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_BGRA32,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_GREY,    .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  |   | ||||||
|  |  		/* YUV packed formats */ | ||||||
|  | -		{ .format = V4L2_PIX_FMT_YUYV,    .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_YVYU,    .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_UYVY,    .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_VYUY,    .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_YUYV,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_YVYU,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_UYVY,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_VYUY,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 }, | ||||||
|  |   | ||||||
|  |  		/* YUV planar formats */ | ||||||
|  | -		{ .format = V4L2_PIX_FMT_NV12,    .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_NV21,    .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_NV16,    .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_NV61,    .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_NV24,    .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_NV42,    .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | - | ||||||
|  | -		{ .format = V4L2_PIX_FMT_YUV410,  .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_YVU410,  .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_YUV411P, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_YUV420,  .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_YVU420,  .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_YUV422P, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_NV12,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_NV21,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_NV16,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_NV61,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_NV24,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_NV42,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | + | ||||||
|  | +		{ .format = V4L2_PIX_FMT_YUV410,  .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_YVU410,  .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_YUV411P, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_YUV420,  .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_YVU420,  .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_YUV422P, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 }, | ||||||
|  |   | ||||||
|  |  		/* YUV planar formats, non contiguous variant */ | ||||||
|  | -		{ .format = V4L2_PIX_FMT_YUV420M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_YVU420M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_YUV422M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_YVU422M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_YUV444M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_YVU444M, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | - | ||||||
|  | -		{ .format = V4L2_PIX_FMT_NV12M,   .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_NV21M,   .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_NV16M,   .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_NV61M,   .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_YUV420M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_YVU420M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_YUV422M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_YVU422M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_YUV444M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_YVU444M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | + | ||||||
|  | +		{ .format = V4L2_PIX_FMT_NV12M,   .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_NV21M,   .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_NV16M,   .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_NV61M,   .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, | ||||||
|  |   | ||||||
|  |  		/* Bayer RGB formats */ | ||||||
|  | -		{ .format = V4L2_PIX_FMT_SBGGR8,	.mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_SGBRG8,	.mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_SGRBG8,	.mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_SRGGB8,	.mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_SBGGR10,	.mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_SGBRG10,	.mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_SGRBG10,	.mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_SRGGB10,	.mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_SBGGR10ALAW8,	.mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_SGBRG10ALAW8,	.mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_SGRBG10ALAW8,	.mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_SRGGB10ALAW8,	.mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_SBGGR10DPCM8,	.mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_SGBRG10DPCM8,	.mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_SGRBG10DPCM8,	.mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_SRGGB10DPCM8,	.mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_SBGGR12,	.mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_SGBRG12,	.mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_SGRBG12,	.mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | -		{ .format = V4L2_PIX_FMT_SRGGB12,	.mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_SBGGR8,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_SGBRG8,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_SGRBG8,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_SRGGB8,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_SBGGR10,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_SGBRG10,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_SGRBG10,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_SRGGB10,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_SBGGR10ALAW8,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_SGBRG10ALAW8,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_SGRBG10ALAW8,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_SRGGB10ALAW8,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_SBGGR10DPCM8,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_SGBRG10DPCM8,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_SGRBG10DPCM8,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_SRGGB10DPCM8,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_SBGGR12,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_SGBRG12,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_SGRBG12,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_SRGGB12,	.pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  |  	}; | ||||||
|  |  	unsigned int i; | ||||||
|  |   | ||||||
|  | --- a/include/media/v4l2-common.h | ||||||
|  | +++ b/include/media/v4l2-common.h | ||||||
|  | @@ -457,8 +457,24 @@ int v4l2_s_parm_cap(struct video_device | ||||||
|  |  /* Pixel format and FourCC helpers */ | ||||||
|  |   | ||||||
|  |  /** | ||||||
|  | + * enum v4l2_pixel_encoding - specifies the pixel encoding value | ||||||
|  | + * | ||||||
|  | + * @V4L2_PIXEL_ENC_UNKNOWN:	Pixel encoding is unknown/un-initialized | ||||||
|  | + * @V4L2_PIXEL_ENC_YUV:		Pixel encoding is YUV | ||||||
|  | + * @V4L2_PIXEL_ENC_RGB:		Pixel encoding is RGB | ||||||
|  | + * @V4L2_PIXEL_ENC_BAYER:	Pixel encoding is Bayer | ||||||
|  | + */ | ||||||
|  | +enum v4l2_pixel_encoding { | ||||||
|  | +	V4L2_PIXEL_ENC_UNKNOWN = 0, | ||||||
|  | +	V4L2_PIXEL_ENC_YUV = 1, | ||||||
|  | +	V4L2_PIXEL_ENC_RGB = 2, | ||||||
|  | +	V4L2_PIXEL_ENC_BAYER = 3, | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  | +/** | ||||||
|  |   * struct v4l2_format_info - information about a V4L2 format | ||||||
|  |   * @format: 4CC format identifier (V4L2_PIX_FMT_*) | ||||||
|  | + * @pixel_enc: Pixel encoding (see enum v4l2_pixel_encoding above) | ||||||
|  |   * @mem_planes: Number of memory planes, which includes the alpha plane (1 to 4). | ||||||
|  |   * @comp_planes: Number of component planes, which includes the alpha plane (1 to 4). | ||||||
|  |   * @bpp: Array of per-plane bytes per pixel | ||||||
|  | @@ -469,6 +485,7 @@ int v4l2_s_parm_cap(struct video_device | ||||||
|  |   */ | ||||||
|  |  struct v4l2_format_info { | ||||||
|  |  	u32 format; | ||||||
|  | +	u8 pixel_enc; | ||||||
|  |  	u8 mem_planes; | ||||||
|  |  	u8 comp_planes; | ||||||
|  |  	u8 bpp[4]; | ||||||
|  | @@ -478,8 +495,22 @@ struct v4l2_format_info { | ||||||
|  |  	u8 block_h[4]; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | -const struct v4l2_format_info *v4l2_format_info(u32 format); | ||||||
|  | +static inline bool v4l2_is_format_rgb(const struct v4l2_format_info *f) | ||||||
|  | +{ | ||||||
|  | +	return f && f->pixel_enc == V4L2_PIXEL_ENC_RGB; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +static inline bool v4l2_is_format_yuv(const struct v4l2_format_info *f) | ||||||
|  | +{ | ||||||
|  | +	return f && f->pixel_enc == V4L2_PIXEL_ENC_YUV; | ||||||
|  | +} | ||||||
|  |   | ||||||
|  | +static inline bool v4l2_is_format_bayer(const struct v4l2_format_info *f) | ||||||
|  | +{ | ||||||
|  | +	return f && f->pixel_enc == V4L2_PIXEL_ENC_BAYER; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +const struct v4l2_format_info *v4l2_format_info(u32 format); | ||||||
|  |  void v4l2_apply_frmsize_constraints(u32 *width, u32 *height, | ||||||
|  |  				    const struct v4l2_frmsize_stepwise *frmsize); | ||||||
|  |  int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat, | ||||||
| @@ -0,0 +1,28 @@ | |||||||
|  | From 560f3a9051578499e72ce4b1beaedd007ff46f96 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Benoit Parrot <bparrot@ti.com> | ||||||
|  | Date: Mon, 7 Oct 2019 12:10:08 -0300 | ||||||
|  | Subject: [PATCH] media: v4l2-common: add RGB565 and RGB55 to | ||||||
|  |  v4l2_format_info | ||||||
|  |  | ||||||
|  | Commit b373f84d77e1c409aacb4ff5bb5726c45fc8b166 upstream. | ||||||
|  |  | ||||||
|  | Add RGB565 and RGB555 to the v4l2_format_info table. | ||||||
|  |  | ||||||
|  | Signed-off-by: Benoit Parrot <bparrot@ti.com> | ||||||
|  | Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> | ||||||
|  | Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | ||||||
|  | --- | ||||||
|  |  drivers/media/v4l2-core/v4l2-common.c | 2 ++ | ||||||
|  |  1 file changed, 2 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/media/v4l2-core/v4l2-common.c | ||||||
|  | +++ b/drivers/media/v4l2-core/v4l2-common.c | ||||||
|  | @@ -251,6 +251,8 @@ const struct v4l2_format_info *v4l2_form | ||||||
|  |  		{ .format = V4L2_PIX_FMT_ABGR32,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  |  		{ .format = V4L2_PIX_FMT_BGRA32,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  |  		{ .format = V4L2_PIX_FMT_GREY,    .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_RGB565,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  | +		{ .format = V4L2_PIX_FMT_RGB555,  .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, | ||||||
|  |   | ||||||
|  |  		/* YUV packed formats */ | ||||||
|  |  		{ .format = V4L2_PIX_FMT_YUYV,    .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 }, | ||||||
| @@ -0,0 +1,184 @@ | |||||||
|  | From dfcdc4ed9a514cd5d77dd18c6527f257f8aaf378 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Hans Verkuil <hverkuil-cisco@xs4all.nl> | ||||||
|  | Date: Fri, 11 Oct 2019 06:32:40 -0300 | ||||||
|  | Subject: [PATCH] media: vb2: add V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF | ||||||
|  |  | ||||||
|  | This patch adds support for the V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF | ||||||
|  | flag. | ||||||
|  |  | ||||||
|  | It also adds a new V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF | ||||||
|  | capability. | ||||||
|  |  | ||||||
|  | Drivers should set vb2_queue->subsystem_flags to | ||||||
|  | VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF to indicate support | ||||||
|  | for this flag. | ||||||
|  |  | ||||||
|  | Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> | ||||||
|  | Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | ||||||
|  | --- | ||||||
|  |  Documentation/media/uapi/v4l/buffer.rst         | 13 +++++++++++++ | ||||||
|  |  Documentation/media/uapi/v4l/vidioc-reqbufs.rst |  6 ++++++ | ||||||
|  |  drivers/media/common/videobuf2/videobuf2-v4l2.c | 12 ++++++++++-- | ||||||
|  |  include/media/videobuf2-core.h                  |  3 +++ | ||||||
|  |  include/media/videobuf2-v4l2.h                  |  5 +++++ | ||||||
|  |  include/uapi/linux/videodev2.h                  | 13 ++++++++----- | ||||||
|  |  6 files changed, 45 insertions(+), 7 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/Documentation/media/uapi/v4l/buffer.rst | ||||||
|  | +++ b/Documentation/media/uapi/v4l/buffer.rst | ||||||
|  | @@ -607,6 +607,19 @@ Buffer Flags | ||||||
|  |  	applications shall use this flag for output buffers if the data in | ||||||
|  |  	this buffer has not been created by the CPU but by some | ||||||
|  |  	DMA-capable unit, in which case caches have not been used. | ||||||
|  | +    * .. _`V4L2-BUF-FLAG-M2M-HOLD-CAPTURE-BUF`: | ||||||
|  | + | ||||||
|  | +      - ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` | ||||||
|  | +      - 0x00000200 | ||||||
|  | +      - Only valid if ``V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF`` is | ||||||
|  | +	set. It is typically used with stateless decoders where multiple | ||||||
|  | +	output buffers each decode to a slice of the decoded frame. | ||||||
|  | +	Applications can set this flag when queueing the output buffer | ||||||
|  | +	to prevent the driver from dequeueing the capture buffer after | ||||||
|  | +	the output buffer has been decoded (i.e. the capture buffer is | ||||||
|  | +	'held'). If the timestamp of this output buffer differs from that | ||||||
|  | +	of the previous output buffer, then that indicates the start of a | ||||||
|  | +	new frame and the previously held capture buffer is dequeued. | ||||||
|  |      * .. _`V4L2-BUF-FLAG-LAST`: | ||||||
|  |   | ||||||
|  |        - ``V4L2_BUF_FLAG_LAST`` | ||||||
|  | --- a/Documentation/media/uapi/v4l/vidioc-reqbufs.rst | ||||||
|  | +++ b/Documentation/media/uapi/v4l/vidioc-reqbufs.rst | ||||||
|  | @@ -125,6 +125,7 @@ aborting or finishing any DMA in progres | ||||||
|  |  .. _V4L2-BUF-CAP-SUPPORTS-DMABUF: | ||||||
|  |  .. _V4L2-BUF-CAP-SUPPORTS-REQUESTS: | ||||||
|  |  .. _V4L2-BUF-CAP-SUPPORTS-ORPHANED-BUFS: | ||||||
|  | +.. _V4L2-BUF-CAP-SUPPORTS-M2M-HOLD-CAPTURE-BUF: | ||||||
|  |   | ||||||
|  |  .. cssclass:: longtable | ||||||
|  |   | ||||||
|  | @@ -150,6 +151,11 @@ aborting or finishing any DMA in progres | ||||||
|  |        - The kernel allows calling :ref:`VIDIOC_REQBUFS` while buffers are still | ||||||
|  |          mapped or exported via DMABUF. These orphaned buffers will be freed | ||||||
|  |          when they are unmapped or when the exported DMABUF fds are closed. | ||||||
|  | +    * - ``V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF`` | ||||||
|  | +      - 0x00000020 | ||||||
|  | +      - Only valid for stateless decoders. If set, then userspace can set the | ||||||
|  | +        ``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` flag to hold off on returning the | ||||||
|  | +	capture buffer until the OUTPUT timestamp changes. | ||||||
|  |   | ||||||
|  |  Return Value | ||||||
|  |  ============ | ||||||
|  | --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c | ||||||
|  | +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c | ||||||
|  | @@ -49,8 +49,11 @@ module_param(debug, int, 0644); | ||||||
|  |  				 V4L2_BUF_FLAG_REQUEST_FD | \ | ||||||
|  |  				 V4L2_BUF_FLAG_TIMESTAMP_MASK) | ||||||
|  |  /* Output buffer flags that should be passed on to the driver */ | ||||||
|  | -#define V4L2_BUFFER_OUT_FLAGS	(V4L2_BUF_FLAG_PFRAME | V4L2_BUF_FLAG_BFRAME | \ | ||||||
|  | -				 V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_TIMECODE) | ||||||
|  | +#define V4L2_BUFFER_OUT_FLAGS	(V4L2_BUF_FLAG_PFRAME | \ | ||||||
|  | +				 V4L2_BUF_FLAG_BFRAME | \ | ||||||
|  | +				 V4L2_BUF_FLAG_KEYFRAME | \ | ||||||
|  | +				 V4L2_BUF_FLAG_TIMECODE | \ | ||||||
|  | +				 V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF) | ||||||
|  |   | ||||||
|  |  /* | ||||||
|  |   * __verify_planes_array() - verify that the planes array passed in struct | ||||||
|  | @@ -194,6 +197,7 @@ static int vb2_fill_vb2_v4l2_buffer(stru | ||||||
|  |  	} | ||||||
|  |  	vbuf->sequence = 0; | ||||||
|  |  	vbuf->request_fd = -1; | ||||||
|  | +	vbuf->is_held = false; | ||||||
|  |   | ||||||
|  |  	if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) { | ||||||
|  |  		switch (b->memory) { | ||||||
|  | @@ -321,6 +325,8 @@ static int vb2_fill_vb2_v4l2_buffer(stru | ||||||
|  |  		 */ | ||||||
|  |  		vbuf->flags &= ~V4L2_BUF_FLAG_TIMECODE; | ||||||
|  |  		vbuf->field = b->field; | ||||||
|  | +		if (!(q->subsystem_flags & VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF)) | ||||||
|  | +			vbuf->flags &= ~V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF; | ||||||
|  |  	} else { | ||||||
|  |  		/* Zero any output buffer flags as this is a capture buffer */ | ||||||
|  |  		vbuf->flags &= ~V4L2_BUFFER_OUT_FLAGS; | ||||||
|  | @@ -654,6 +660,8 @@ static void fill_buf_caps(struct vb2_que | ||||||
|  |  		*caps |= V4L2_BUF_CAP_SUPPORTS_USERPTR; | ||||||
|  |  	if (q->io_modes & VB2_DMABUF) | ||||||
|  |  		*caps |= V4L2_BUF_CAP_SUPPORTS_DMABUF; | ||||||
|  | +	if (q->subsystem_flags & VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF) | ||||||
|  | +		*caps |= V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF; | ||||||
|  |  #ifdef CONFIG_MEDIA_CONTROLLER_REQUEST_API | ||||||
|  |  	if (q->supports_requests) | ||||||
|  |  		*caps |= V4L2_BUF_CAP_SUPPORTS_REQUESTS; | ||||||
|  | --- a/include/media/videobuf2-core.h | ||||||
|  | +++ b/include/media/videobuf2-core.h | ||||||
|  | @@ -505,6 +505,8 @@ struct vb2_buf_ops { | ||||||
|  |   * @buf_ops:	callbacks to deliver buffer information. | ||||||
|  |   *		between user-space and kernel-space. | ||||||
|  |   * @drv_priv:	driver private data. | ||||||
|  | + * @subsystem_flags: Flags specific to the subsystem (V4L2/DVB/etc.). Not used | ||||||
|  | + *		by the vb2 core. | ||||||
|  |   * @buf_struct_size: size of the driver-specific buffer structure; | ||||||
|  |   *		"0" indicates the driver doesn't want to use a custom buffer | ||||||
|  |   *		structure type. for example, ``sizeof(struct vb2_v4l2_buffer)`` | ||||||
|  | @@ -571,6 +573,7 @@ struct vb2_queue { | ||||||
|  |  	const struct vb2_buf_ops	*buf_ops; | ||||||
|  |   | ||||||
|  |  	void				*drv_priv; | ||||||
|  | +	u32				subsystem_flags; | ||||||
|  |  	unsigned int			buf_struct_size; | ||||||
|  |  	u32				timestamp_flags; | ||||||
|  |  	gfp_t				gfp_flags; | ||||||
|  | --- a/include/media/videobuf2-v4l2.h | ||||||
|  | +++ b/include/media/videobuf2-v4l2.h | ||||||
|  | @@ -33,6 +33,7 @@ | ||||||
|  |   * @timecode:	frame timecode. | ||||||
|  |   * @sequence:	sequence count of this frame. | ||||||
|  |   * @request_fd:	the request_fd associated with this buffer | ||||||
|  | + * @is_held:	if true, then this capture buffer was held | ||||||
|  |   * @planes:	plane information (userptr/fd, length, bytesused, data_offset). | ||||||
|  |   * | ||||||
|  |   * Should contain enough information to be able to cover all the fields | ||||||
|  | @@ -46,9 +47,13 @@ struct vb2_v4l2_buffer { | ||||||
|  |  	struct v4l2_timecode	timecode; | ||||||
|  |  	__u32			sequence; | ||||||
|  |  	__s32			request_fd; | ||||||
|  | +	bool			is_held; | ||||||
|  |  	struct vb2_plane	planes[VB2_MAX_PLANES]; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | +/* VB2 V4L2 flags as set in vb2_queue.subsystem_flags */ | ||||||
|  | +#define VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF (1 << 0) | ||||||
|  | + | ||||||
|  |  /* | ||||||
|  |   * to_vb2_v4l2_buffer() - cast struct vb2_buffer * to struct vb2_v4l2_buffer * | ||||||
|  |   */ | ||||||
|  | --- a/include/uapi/linux/videodev2.h | ||||||
|  | +++ b/include/uapi/linux/videodev2.h | ||||||
|  | @@ -925,11 +925,12 @@ struct v4l2_requestbuffers { | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  /* capabilities for struct v4l2_requestbuffers and v4l2_create_buffers */ | ||||||
|  | -#define V4L2_BUF_CAP_SUPPORTS_MMAP	(1 << 0) | ||||||
|  | -#define V4L2_BUF_CAP_SUPPORTS_USERPTR	(1 << 1) | ||||||
|  | -#define V4L2_BUF_CAP_SUPPORTS_DMABUF	(1 << 2) | ||||||
|  | -#define V4L2_BUF_CAP_SUPPORTS_REQUESTS	(1 << 3) | ||||||
|  | -#define V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS (1 << 4) | ||||||
|  | +#define V4L2_BUF_CAP_SUPPORTS_MMAP			(1 << 0) | ||||||
|  | +#define V4L2_BUF_CAP_SUPPORTS_USERPTR			(1 << 1) | ||||||
|  | +#define V4L2_BUF_CAP_SUPPORTS_DMABUF			(1 << 2) | ||||||
|  | +#define V4L2_BUF_CAP_SUPPORTS_REQUESTS			(1 << 3) | ||||||
|  | +#define V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS		(1 << 4) | ||||||
|  | +#define V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF	(1 << 5) | ||||||
|  |   | ||||||
|  |  /** | ||||||
|  |   * struct v4l2_plane - plane info for multi-planar buffers | ||||||
|  | @@ -1051,6 +1052,8 @@ static inline __u64 v4l2_timeval_to_ns(c | ||||||
|  |  #define V4L2_BUF_FLAG_IN_REQUEST		0x00000080 | ||||||
|  |  /* timecode field is valid */ | ||||||
|  |  #define V4L2_BUF_FLAG_TIMECODE			0x00000100 | ||||||
|  | +/* Don't return the capture buffer until OUTPUT timestamp changes */ | ||||||
|  | +#define V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF	0x00000200 | ||||||
|  |  /* Buffer is prepared for queuing */ | ||||||
|  |  #define V4L2_BUF_FLAG_PREPARED			0x00000400 | ||||||
|  |  /* Cache handling flags */ | ||||||
| @@ -0,0 +1,260 @@ | |||||||
|  | From dc9b786e4b9a1262b536b3c9d0fa88e34a2b3f8f Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Hans Verkuil <hverkuil-cisco@xs4all.nl> | ||||||
|  | Date: Fri, 11 Oct 2019 06:32:41 -0300 | ||||||
|  | Subject: [PATCH] media: v4l2-mem2mem: support held capture buffers | ||||||
|  |  | ||||||
|  | Commit f8cca8c97a63d77f48334cde81d15014f43530ef upstream. | ||||||
|  |  | ||||||
|  | Check for held buffers that are ready to be returned to vb2 in | ||||||
|  | __v4l2_m2m_try_queue(). This avoids drivers having to handle this | ||||||
|  | case. | ||||||
|  |  | ||||||
|  | Add v4l2_m2m_buf_done_and_job_finish() to correctly return source | ||||||
|  | and destination buffers and mark the job as finished while taking | ||||||
|  | a held destination buffer into account (i.e. that buffer won't be | ||||||
|  | returned). This has to be done while job_spinlock is held to avoid | ||||||
|  | race conditions. | ||||||
|  |  | ||||||
|  | Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> | ||||||
|  | Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | ||||||
|  | --- | ||||||
|  |  drivers/media/v4l2-core/v4l2-mem2mem.c | 130 ++++++++++++++++++------- | ||||||
|  |  include/media/v4l2-mem2mem.h           |  33 ++++++- | ||||||
|  |  2 files changed, 128 insertions(+), 35 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/media/v4l2-core/v4l2-mem2mem.c | ||||||
|  | +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c | ||||||
|  | @@ -284,7 +284,8 @@ static void v4l2_m2m_try_run(struct v4l2 | ||||||
|  |  static void __v4l2_m2m_try_queue(struct v4l2_m2m_dev *m2m_dev, | ||||||
|  |  				 struct v4l2_m2m_ctx *m2m_ctx) | ||||||
|  |  { | ||||||
|  | -	unsigned long flags_job, flags_out, flags_cap; | ||||||
|  | +	unsigned long flags_job; | ||||||
|  | +	struct vb2_v4l2_buffer *dst, *src; | ||||||
|  |   | ||||||
|  |  	dprintk("Trying to schedule a job for m2m_ctx: %p\n", m2m_ctx); | ||||||
|  |   | ||||||
|  | @@ -307,20 +308,30 @@ static void __v4l2_m2m_try_queue(struct | ||||||
|  |  		goto job_unlock; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	spin_lock_irqsave(&m2m_ctx->out_q_ctx.rdy_spinlock, flags_out); | ||||||
|  | -	if (list_empty(&m2m_ctx->out_q_ctx.rdy_queue) | ||||||
|  | -	    && !m2m_ctx->out_q_ctx.buffered) { | ||||||
|  | +	src = v4l2_m2m_next_src_buf(m2m_ctx); | ||||||
|  | +	dst = v4l2_m2m_next_dst_buf(m2m_ctx); | ||||||
|  | +	if (!src && !m2m_ctx->out_q_ctx.buffered) { | ||||||
|  |  		dprintk("No input buffers available\n"); | ||||||
|  | -		goto out_unlock; | ||||||
|  | +		goto job_unlock; | ||||||
|  |  	} | ||||||
|  | -	spin_lock_irqsave(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags_cap); | ||||||
|  | -	if (list_empty(&m2m_ctx->cap_q_ctx.rdy_queue) | ||||||
|  | -	    && !m2m_ctx->cap_q_ctx.buffered) { | ||||||
|  | +	if (!dst && !m2m_ctx->cap_q_ctx.buffered) { | ||||||
|  |  		dprintk("No output buffers available\n"); | ||||||
|  | -		goto cap_unlock; | ||||||
|  | +		goto job_unlock; | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	if (src && dst && | ||||||
|  | +	    dst->is_held && dst->vb2_buf.copied_timestamp && | ||||||
|  | +	    dst->vb2_buf.timestamp != src->vb2_buf.timestamp) { | ||||||
|  | +		dst->is_held = false; | ||||||
|  | +		v4l2_m2m_dst_buf_remove(m2m_ctx); | ||||||
|  | +		v4l2_m2m_buf_done(dst, VB2_BUF_STATE_DONE); | ||||||
|  | +		dst = v4l2_m2m_next_dst_buf(m2m_ctx); | ||||||
|  | + | ||||||
|  | +		if (!dst && !m2m_ctx->cap_q_ctx.buffered) { | ||||||
|  | +			dprintk("No output buffers available after returning held buffer\n"); | ||||||
|  | +			goto job_unlock; | ||||||
|  | +		} | ||||||
|  |  	} | ||||||
|  | -	spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags_cap); | ||||||
|  | -	spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags_out); | ||||||
|  |   | ||||||
|  |  	if (m2m_dev->m2m_ops->job_ready | ||||||
|  |  		&& (!m2m_dev->m2m_ops->job_ready(m2m_ctx->priv))) { | ||||||
|  | @@ -331,13 +342,6 @@ static void __v4l2_m2m_try_queue(struct | ||||||
|  |  	list_add_tail(&m2m_ctx->queue, &m2m_dev->job_queue); | ||||||
|  |  	m2m_ctx->job_flags |= TRANS_QUEUED; | ||||||
|  |   | ||||||
|  | -	spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job); | ||||||
|  | -	return; | ||||||
|  | - | ||||||
|  | -cap_unlock: | ||||||
|  | -	spin_unlock_irqrestore(&m2m_ctx->cap_q_ctx.rdy_spinlock, flags_cap); | ||||||
|  | -out_unlock: | ||||||
|  | -	spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags_out); | ||||||
|  |  job_unlock: | ||||||
|  |  	spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job); | ||||||
|  |  } | ||||||
|  | @@ -412,37 +416,97 @@ static void v4l2_m2m_cancel_job(struct v | ||||||
|  |  	} | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev, | ||||||
|  | -			 struct v4l2_m2m_ctx *m2m_ctx) | ||||||
|  | +/* | ||||||
|  | + * Schedule the next job, called from v4l2_m2m_job_finish() or | ||||||
|  | + * v4l2_m2m_buf_done_and_job_finish(). | ||||||
|  | + */ | ||||||
|  | +static void v4l2_m2m_schedule_next_job(struct v4l2_m2m_dev *m2m_dev, | ||||||
|  | +				       struct v4l2_m2m_ctx *m2m_ctx) | ||||||
|  |  { | ||||||
|  | -	unsigned long flags; | ||||||
|  | +	/* | ||||||
|  | +	 * This instance might have more buffers ready, but since we do not | ||||||
|  | +	 * allow more than one job on the job_queue per instance, each has | ||||||
|  | +	 * to be scheduled separately after the previous one finishes. | ||||||
|  | +	 */ | ||||||
|  | +	__v4l2_m2m_try_queue(m2m_dev, m2m_ctx); | ||||||
|  |   | ||||||
|  | -	spin_lock_irqsave(&m2m_dev->job_spinlock, flags); | ||||||
|  | +	/* | ||||||
|  | +	 * We might be running in atomic context, | ||||||
|  | +	 * but the job must be run in non-atomic context. | ||||||
|  | +	 */ | ||||||
|  | +	schedule_work(&m2m_dev->job_work); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +/* | ||||||
|  | + * Assumes job_spinlock is held, called from v4l2_m2m_job_finish() or | ||||||
|  | + * v4l2_m2m_buf_done_and_job_finish(). | ||||||
|  | + */ | ||||||
|  | +static bool _v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev, | ||||||
|  | +				 struct v4l2_m2m_ctx *m2m_ctx) | ||||||
|  | +{ | ||||||
|  |  	if (!m2m_dev->curr_ctx || m2m_dev->curr_ctx != m2m_ctx) { | ||||||
|  | -		spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); | ||||||
|  |  		dprintk("Called by an instance not currently running\n"); | ||||||
|  | -		return; | ||||||
|  | +		return false; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	list_del(&m2m_dev->curr_ctx->queue); | ||||||
|  |  	m2m_dev->curr_ctx->job_flags &= ~(TRANS_QUEUED | TRANS_RUNNING); | ||||||
|  |  	wake_up(&m2m_dev->curr_ctx->finished); | ||||||
|  |  	m2m_dev->curr_ctx = NULL; | ||||||
|  | +	return true; | ||||||
|  | +} | ||||||
|  |   | ||||||
|  | -	spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); | ||||||
|  | - | ||||||
|  | -	/* This instance might have more buffers ready, but since we do not | ||||||
|  | -	 * allow more than one job on the job_queue per instance, each has | ||||||
|  | -	 * to be scheduled separately after the previous one finishes. */ | ||||||
|  | -	__v4l2_m2m_try_queue(m2m_dev, m2m_ctx); | ||||||
|  | +void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev, | ||||||
|  | +			 struct v4l2_m2m_ctx *m2m_ctx) | ||||||
|  | +{ | ||||||
|  | +	unsigned long flags; | ||||||
|  | +	bool schedule_next; | ||||||
|  |   | ||||||
|  | -	/* We might be running in atomic context, | ||||||
|  | -	 * but the job must be run in non-atomic context. | ||||||
|  | +	/* | ||||||
|  | +	 * This function should not be used for drivers that support | ||||||
|  | +	 * holding capture buffers. Those should use | ||||||
|  | +	 * v4l2_m2m_buf_done_and_job_finish() instead. | ||||||
|  |  	 */ | ||||||
|  | -	schedule_work(&m2m_dev->job_work); | ||||||
|  | +	WARN_ON(m2m_ctx->cap_q_ctx.q.subsystem_flags & | ||||||
|  | +		VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF); | ||||||
|  | +	spin_lock_irqsave(&m2m_dev->job_spinlock, flags); | ||||||
|  | +	schedule_next = _v4l2_m2m_job_finish(m2m_dev, m2m_ctx); | ||||||
|  | +	spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); | ||||||
|  | + | ||||||
|  | +	if (schedule_next) | ||||||
|  | +		v4l2_m2m_schedule_next_job(m2m_dev, m2m_ctx); | ||||||
|  |  } | ||||||
|  |  EXPORT_SYMBOL(v4l2_m2m_job_finish); | ||||||
|  |   | ||||||
|  | +void v4l2_m2m_buf_done_and_job_finish(struct v4l2_m2m_dev *m2m_dev, | ||||||
|  | +				      struct v4l2_m2m_ctx *m2m_ctx, | ||||||
|  | +				      enum vb2_buffer_state state) | ||||||
|  | +{ | ||||||
|  | +	struct vb2_v4l2_buffer *src_buf, *dst_buf; | ||||||
|  | +	bool schedule_next = false; | ||||||
|  | +	unsigned long flags; | ||||||
|  | + | ||||||
|  | +	spin_lock_irqsave(&m2m_dev->job_spinlock, flags); | ||||||
|  | +	src_buf = v4l2_m2m_src_buf_remove(m2m_ctx); | ||||||
|  | +	dst_buf = v4l2_m2m_next_dst_buf(m2m_ctx); | ||||||
|  | + | ||||||
|  | +	if (WARN_ON(!src_buf || !dst_buf)) | ||||||
|  | +		goto unlock; | ||||||
|  | +	v4l2_m2m_buf_done(src_buf, state); | ||||||
|  | +	dst_buf->is_held = src_buf->flags & V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF; | ||||||
|  | +	if (!dst_buf->is_held) { | ||||||
|  | +		v4l2_m2m_dst_buf_remove(m2m_ctx); | ||||||
|  | +		v4l2_m2m_buf_done(dst_buf, state); | ||||||
|  | +	} | ||||||
|  | +	schedule_next = _v4l2_m2m_job_finish(m2m_dev, m2m_ctx); | ||||||
|  | +unlock: | ||||||
|  | +	spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); | ||||||
|  | + | ||||||
|  | +	if (schedule_next) | ||||||
|  | +		v4l2_m2m_schedule_next_job(m2m_dev, m2m_ctx); | ||||||
|  | +} | ||||||
|  | +EXPORT_SYMBOL(v4l2_m2m_buf_done_and_job_finish); | ||||||
|  | + | ||||||
|  |  int v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, | ||||||
|  |  		     struct v4l2_requestbuffers *reqbufs) | ||||||
|  |  { | ||||||
|  | --- a/include/media/v4l2-mem2mem.h | ||||||
|  | +++ b/include/media/v4l2-mem2mem.h | ||||||
|  | @@ -21,7 +21,8 @@ | ||||||
|  |   *		callback. | ||||||
|  |   *		The job does NOT have to end before this callback returns | ||||||
|  |   *		(and it will be the usual case). When the job finishes, | ||||||
|  | - *		v4l2_m2m_job_finish() has to be called. | ||||||
|  | + *		v4l2_m2m_job_finish() or v4l2_m2m_buf_done_and_job_finish() | ||||||
|  | + *		has to be called. | ||||||
|  |   * @job_ready:	optional. Should return 0 if the driver does not have a job | ||||||
|  |   *		fully prepared to run yet (i.e. it will not be able to finish a | ||||||
|  |   *		transaction without sleeping). If not provided, it will be | ||||||
|  | @@ -33,7 +34,8 @@ | ||||||
|  |   *		stop the device safely; e.g. in the next interrupt handler), | ||||||
|  |   *		even if the transaction would not have been finished by then. | ||||||
|  |   *		After the driver performs the necessary steps, it has to call | ||||||
|  | - *		v4l2_m2m_job_finish() (as if the transaction ended normally). | ||||||
|  | + *		v4l2_m2m_job_finish() or v4l2_m2m_buf_done_and_job_finish() as | ||||||
|  | + *		if the transaction ended normally. | ||||||
|  |   *		This function does not have to (and will usually not) wait | ||||||
|  |   *		until the device enters a state when it can be stopped. | ||||||
|  |   */ | ||||||
|  | @@ -173,6 +175,33 @@ void v4l2_m2m_try_schedule(struct v4l2_m | ||||||
|  |  void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev, | ||||||
|  |  			 struct v4l2_m2m_ctx *m2m_ctx); | ||||||
|  |   | ||||||
|  | +/** | ||||||
|  | + * v4l2_m2m_buf_done_and_job_finish() - return source/destination buffers with | ||||||
|  | + * state and inform the framework that a job has been finished and have it | ||||||
|  | + * clean up | ||||||
|  | + * | ||||||
|  | + * @m2m_dev: opaque pointer to the internal data to handle M2M context | ||||||
|  | + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx | ||||||
|  | + * @state: vb2 buffer state passed to v4l2_m2m_buf_done(). | ||||||
|  | + * | ||||||
|  | + * Drivers that set V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF must use this | ||||||
|  | + * function instead of job_finish() to take held buffers into account. It is | ||||||
|  | + * optional for other drivers. | ||||||
|  | + * | ||||||
|  | + * This function removes the source buffer from the ready list and returns | ||||||
|  | + * it with the given state. The same is done for the destination buffer, unless | ||||||
|  | + * it is marked 'held'. In that case the buffer is kept on the ready list. | ||||||
|  | + * | ||||||
|  | + * After that the job is finished (see job_finish()). | ||||||
|  | + * | ||||||
|  | + * This allows for multiple output buffers to be used to fill in a single | ||||||
|  | + * capture buffer. This is typically used by stateless decoders where | ||||||
|  | + * multiple e.g. H.264 slices contribute to a single decoded frame. | ||||||
|  | + */ | ||||||
|  | +void v4l2_m2m_buf_done_and_job_finish(struct v4l2_m2m_dev *m2m_dev, | ||||||
|  | +				      struct v4l2_m2m_ctx *m2m_ctx, | ||||||
|  | +				      enum vb2_buffer_state state); | ||||||
|  | + | ||||||
|  |  static inline void | ||||||
|  |  v4l2_m2m_buf_done(struct vb2_v4l2_buffer *buf, enum vb2_buffer_state state) | ||||||
|  |  { | ||||||
| @@ -0,0 +1,57 @@ | |||||||
|  | From b2ea711d2c21ec021de4ff09a0a2b5b4224f9749 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Hans Verkuil <hverkuil-cisco@xs4all.nl> | ||||||
|  | Date: Fri, 11 Oct 2019 06:32:42 -0300 | ||||||
|  | Subject: [PATCH] media: videodev2.h: add V4L2_DEC_CMD_FLUSH | ||||||
|  |  | ||||||
|  | Add this new V4L2_DEC_CMD_FLUSH decoder command and document it. | ||||||
|  |  | ||||||
|  | Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> | ||||||
|  | Reviewed-by: Alexandre Courbot <acourbot@chromium.org> | ||||||
|  | Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> | ||||||
|  | Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net> | ||||||
|  | Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | ||||||
|  | --- | ||||||
|  |  Documentation/media/uapi/v4l/vidioc-decoder-cmd.rst | 10 +++++++++- | ||||||
|  |  Documentation/media/videodev2.h.rst.exceptions      |  1 + | ||||||
|  |  include/uapi/linux/videodev2.h                      |  1 + | ||||||
|  |  3 files changed, 11 insertions(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/Documentation/media/uapi/v4l/vidioc-decoder-cmd.rst | ||||||
|  | +++ b/Documentation/media/uapi/v4l/vidioc-decoder-cmd.rst | ||||||
|  | @@ -208,7 +208,15 @@ introduced in Linux 3.3. They are, howev | ||||||
|  |  	been started yet, the driver will return an ``EPERM`` error code. When | ||||||
|  |  	the decoder is already running, this command does nothing. No | ||||||
|  |  	flags are defined for this command. | ||||||
|  | - | ||||||
|  | +    * - ``V4L2_DEC_CMD_FLUSH`` | ||||||
|  | +      - 4 | ||||||
|  | +      - Flush any held capture buffers. Only valid for stateless decoders. | ||||||
|  | +	This command is typically used when the application reached the | ||||||
|  | +	end of the stream and the last output buffer had the | ||||||
|  | +	``V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF`` flag set. This would prevent | ||||||
|  | +	dequeueing the capture buffer containing the last decoded frame. | ||||||
|  | +	So this command can be used to explicitly flush that final decoded | ||||||
|  | +	frame. This command does nothing if there are no held capture buffers. | ||||||
|  |   | ||||||
|  |  Return Value | ||||||
|  |  ============ | ||||||
|  | --- a/Documentation/media/videodev2.h.rst.exceptions | ||||||
|  | +++ b/Documentation/media/videodev2.h.rst.exceptions | ||||||
|  | @@ -434,6 +434,7 @@ replace define V4L2_DEC_CMD_START decode | ||||||
|  |  replace define V4L2_DEC_CMD_STOP decoder-cmds | ||||||
|  |  replace define V4L2_DEC_CMD_PAUSE decoder-cmds | ||||||
|  |  replace define V4L2_DEC_CMD_RESUME decoder-cmds | ||||||
|  | +replace define V4L2_DEC_CMD_FLUSH decoder-cmds | ||||||
|  |   | ||||||
|  |  replace define V4L2_DEC_CMD_START_MUTE_AUDIO decoder-cmds | ||||||
|  |  replace define V4L2_DEC_CMD_PAUSE_TO_BLACK decoder-cmds | ||||||
|  | --- a/include/uapi/linux/videodev2.h | ||||||
|  | +++ b/include/uapi/linux/videodev2.h | ||||||
|  | @@ -1989,6 +1989,7 @@ struct v4l2_encoder_cmd { | ||||||
|  |  #define V4L2_DEC_CMD_STOP        (1) | ||||||
|  |  #define V4L2_DEC_CMD_PAUSE       (2) | ||||||
|  |  #define V4L2_DEC_CMD_RESUME      (3) | ||||||
|  | +#define V4L2_DEC_CMD_FLUSH       (4) | ||||||
|  |   | ||||||
|  |  /* Flags for V4L2_DEC_CMD_START */ | ||||||
|  |  #define V4L2_DEC_CMD_START_MUTE_AUDIO	(1 << 0) | ||||||
| @@ -0,0 +1,96 @@ | |||||||
|  | From 1decb017f990ea61ab421e316bf1af3a5199b73a Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Jernej Skrabec <jernej.skrabec@siol.net> | ||||||
|  | Date: Fri, 11 Oct 2019 06:32:43 -0300 | ||||||
|  | Subject: [PATCH] media: v4l2-mem2mem: add stateless_(try_)decoder_cmd | ||||||
|  |  ioctl helpers | ||||||
|  |  | ||||||
|  | Commit bef41d93aac64b54c3008ca6170bec54f85784f5 upstream. | ||||||
|  |  | ||||||
|  | These helpers are used by stateless codecs when they support multiple | ||||||
|  | slices per frame and hold capture buffer flag is set. It's expected that | ||||||
|  | all such codecs will use this code. | ||||||
|  |  | ||||||
|  | Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net> | ||||||
|  | Co-developed-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> | ||||||
|  | Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> | ||||||
|  | Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | ||||||
|  | --- | ||||||
|  |  drivers/media/v4l2-core/v4l2-mem2mem.c | 53 ++++++++++++++++++++++++++ | ||||||
|  |  include/media/v4l2-mem2mem.h           |  4 ++ | ||||||
|  |  2 files changed, 57 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/drivers/media/v4l2-core/v4l2-mem2mem.c | ||||||
|  | +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c | ||||||
|  | @@ -1218,6 +1218,59 @@ int v4l2_m2m_ioctl_try_decoder_cmd(struc | ||||||
|  |  } | ||||||
|  |  EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_try_decoder_cmd); | ||||||
|  |   | ||||||
|  | +int v4l2_m2m_ioctl_stateless_try_decoder_cmd(struct file *file, void *fh, | ||||||
|  | +					     struct v4l2_decoder_cmd *dc) | ||||||
|  | +{ | ||||||
|  | +	if (dc->cmd != V4L2_DEC_CMD_FLUSH) | ||||||
|  | +		return -EINVAL; | ||||||
|  | + | ||||||
|  | +	dc->flags = 0; | ||||||
|  | + | ||||||
|  | +	return 0; | ||||||
|  | +} | ||||||
|  | +EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_stateless_try_decoder_cmd); | ||||||
|  | + | ||||||
|  | +int v4l2_m2m_ioctl_stateless_decoder_cmd(struct file *file, void *priv, | ||||||
|  | +					 struct v4l2_decoder_cmd *dc) | ||||||
|  | +{ | ||||||
|  | +	struct v4l2_fh *fh = file->private_data; | ||||||
|  | +	struct vb2_v4l2_buffer *out_vb, *cap_vb; | ||||||
|  | +	struct v4l2_m2m_dev *m2m_dev = fh->m2m_ctx->m2m_dev; | ||||||
|  | +	unsigned long flags; | ||||||
|  | +	int ret; | ||||||
|  | + | ||||||
|  | +	ret = v4l2_m2m_ioctl_stateless_try_decoder_cmd(file, priv, dc); | ||||||
|  | +	if (ret < 0) | ||||||
|  | +		return ret; | ||||||
|  | + | ||||||
|  | +	spin_lock_irqsave(&m2m_dev->job_spinlock, flags); | ||||||
|  | +	out_vb = v4l2_m2m_last_src_buf(fh->m2m_ctx); | ||||||
|  | +	cap_vb = v4l2_m2m_last_dst_buf(fh->m2m_ctx); | ||||||
|  | + | ||||||
|  | +	/* | ||||||
|  | +	 * If there is an out buffer pending, then clear any HOLD flag. | ||||||
|  | +	 * | ||||||
|  | +	 * By clearing this flag we ensure that when this output | ||||||
|  | +	 * buffer is processed any held capture buffer will be released. | ||||||
|  | +	 */ | ||||||
|  | +	if (out_vb) { | ||||||
|  | +		out_vb->flags &= ~V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF; | ||||||
|  | +	} else if (cap_vb && cap_vb->is_held) { | ||||||
|  | +		/* | ||||||
|  | +		 * If there were no output buffers, but there is a | ||||||
|  | +		 * capture buffer that is held, then release that | ||||||
|  | +		 * buffer. | ||||||
|  | +		 */ | ||||||
|  | +		cap_vb->is_held = false; | ||||||
|  | +		v4l2_m2m_dst_buf_remove(fh->m2m_ctx); | ||||||
|  | +		v4l2_m2m_buf_done(cap_vb, VB2_BUF_STATE_DONE); | ||||||
|  | +	} | ||||||
|  | +	spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); | ||||||
|  | + | ||||||
|  | +	return 0; | ||||||
|  | +} | ||||||
|  | +EXPORT_SYMBOL_GPL(v4l2_m2m_ioctl_stateless_decoder_cmd); | ||||||
|  | + | ||||||
|  |  /* | ||||||
|  |   * v4l2_file_operations helpers. It is assumed here same lock is used | ||||||
|  |   * for the output and the capture buffer queue. | ||||||
|  | --- a/include/media/v4l2-mem2mem.h | ||||||
|  | +++ b/include/media/v4l2-mem2mem.h | ||||||
|  | @@ -701,6 +701,10 @@ int v4l2_m2m_ioctl_try_encoder_cmd(struc | ||||||
|  |  				   struct v4l2_encoder_cmd *ec); | ||||||
|  |  int v4l2_m2m_ioctl_try_decoder_cmd(struct file *file, void *fh, | ||||||
|  |  				   struct v4l2_decoder_cmd *dc); | ||||||
|  | +int v4l2_m2m_ioctl_stateless_try_decoder_cmd(struct file *file, void *fh, | ||||||
|  | +					     struct v4l2_decoder_cmd *dc); | ||||||
|  | +int v4l2_m2m_ioctl_stateless_decoder_cmd(struct file *file, void *priv, | ||||||
|  | +					 struct v4l2_decoder_cmd *dc); | ||||||
|  |  int v4l2_m2m_fop_mmap(struct file *file, struct vm_area_struct *vma); | ||||||
|  |  __poll_t v4l2_m2m_fop_poll(struct file *file, poll_table *wait); | ||||||
|  |   | ||||||
| @@ -0,0 +1,69 @@ | |||||||
|  | From 1d55acac432983ad8301f5430c42ac549b4b4c6f Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Hans Verkuil <hverkuil-cisco@xs4all.nl> | ||||||
|  | Date: Fri, 11 Oct 2019 06:32:44 -0300 | ||||||
|  | Subject: [PATCH] media: v4l2-mem2mem: add new_frame detection | ||||||
|  |  | ||||||
|  | Commit f07602ac388723233e9e3c5a05b54baf34e0a3e9 upstream. | ||||||
|  |  | ||||||
|  | Drivers that support VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF | ||||||
|  | typically want to know if a new frame is started (i.e. the first | ||||||
|  | slice is about to be processed). Add a new_frame bool to v4l2_m2m_ctx | ||||||
|  | and set it accordingly. | ||||||
|  |  | ||||||
|  | Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> | ||||||
|  | Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | ||||||
|  | --- | ||||||
|  |  drivers/media/v4l2-core/v4l2-mem2mem.c | 11 +++++++++-- | ||||||
|  |  include/media/v4l2-mem2mem.h           |  7 +++++++ | ||||||
|  |  2 files changed, 16 insertions(+), 2 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/media/v4l2-core/v4l2-mem2mem.c | ||||||
|  | +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c | ||||||
|  | @@ -319,8 +319,10 @@ static void __v4l2_m2m_try_queue(struct | ||||||
|  |  		goto job_unlock; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	if (src && dst && | ||||||
|  | -	    dst->is_held && dst->vb2_buf.copied_timestamp && | ||||||
|  | +	m2m_ctx->new_frame = true; | ||||||
|  | + | ||||||
|  | +	if (src && dst && dst->is_held && | ||||||
|  | +	    dst->vb2_buf.copied_timestamp && | ||||||
|  |  	    dst->vb2_buf.timestamp != src->vb2_buf.timestamp) { | ||||||
|  |  		dst->is_held = false; | ||||||
|  |  		v4l2_m2m_dst_buf_remove(m2m_ctx); | ||||||
|  | @@ -333,6 +335,11 @@ static void __v4l2_m2m_try_queue(struct | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | +	if (src && dst && (m2m_ctx->cap_q_ctx.q.subsystem_flags & | ||||||
|  | +			   VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF)) | ||||||
|  | +		m2m_ctx->new_frame = !dst->vb2_buf.copied_timestamp || | ||||||
|  | +			dst->vb2_buf.timestamp != src->vb2_buf.timestamp; | ||||||
|  | + | ||||||
|  |  	if (m2m_dev->m2m_ops->job_ready | ||||||
|  |  		&& (!m2m_dev->m2m_ops->job_ready(m2m_ctx->priv))) { | ||||||
|  |  		dprintk("Driver not ready\n"); | ||||||
|  | --- a/include/media/v4l2-mem2mem.h | ||||||
|  | +++ b/include/media/v4l2-mem2mem.h | ||||||
|  | @@ -75,6 +75,11 @@ struct v4l2_m2m_queue_ctx { | ||||||
|  |   * struct v4l2_m2m_ctx - Memory to memory context structure | ||||||
|  |   * | ||||||
|  |   * @q_lock: struct &mutex lock | ||||||
|  | + * @new_frame: valid in the device_run callback: if true, then this | ||||||
|  | + *		starts a new frame; if false, then this is a new slice | ||||||
|  | + *		for an existing frame. This is always true unless | ||||||
|  | + *		V4L2_BUF_CAP_SUPPORTS_M2M_HOLD_CAPTURE_BUF is set, which | ||||||
|  | + *		indicates slicing support. | ||||||
|  |   * @m2m_dev: opaque pointer to the internal data to handle M2M context | ||||||
|  |   * @cap_q_ctx: Capture (output to memory) queue context | ||||||
|  |   * @out_q_ctx: Output (input from memory) queue context | ||||||
|  | @@ -91,6 +96,8 @@ struct v4l2_m2m_ctx { | ||||||
|  |  	/* optional cap/out vb2 queues lock */ | ||||||
|  |  	struct mutex			*q_lock; | ||||||
|  |   | ||||||
|  | +	bool				new_frame; | ||||||
|  | + | ||||||
|  |  	/* internal use only */ | ||||||
|  |  	struct v4l2_m2m_dev		*m2m_dev; | ||||||
|  |   | ||||||
| @@ -0,0 +1,46 @@ | |||||||
|  | From 20076d276d045c03f809bb16f0e1fafcfe63a81f Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Ricardo Ribalda Delgado <ribalda@kernel.org> | ||||||
|  | Date: Mon, 7 Oct 2019 12:06:32 -0300 | ||||||
|  | Subject: [PATCH] media: Documentation: media: Document | ||||||
|  |  V4L2_CTRL_TYPE_AREA | ||||||
|  |  | ||||||
|  | Commit 8ae3a0862993c09a8ef0f9abb379553370c517e3 upstream. | ||||||
|  |  | ||||||
|  | A struct v4l2_area containing the width and the height of a rectangular | ||||||
|  | area. | ||||||
|  |  | ||||||
|  | Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> | ||||||
|  | Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> | ||||||
|  | Signed-off-by: Ricardo Ribalda Delgado <ribalda@kernel.org> | ||||||
|  | Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> | ||||||
|  | Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | ||||||
|  | --- | ||||||
|  |  Documentation/media/uapi/v4l/vidioc-queryctrl.rst | 6 ++++++ | ||||||
|  |  Documentation/media/videodev2.h.rst.exceptions    | 1 + | ||||||
|  |  2 files changed, 7 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/Documentation/media/uapi/v4l/vidioc-queryctrl.rst | ||||||
|  | +++ b/Documentation/media/uapi/v4l/vidioc-queryctrl.rst | ||||||
|  | @@ -443,6 +443,12 @@ See also the examples in :ref:`control`. | ||||||
|  |        - n/a | ||||||
|  |        - A struct :c:type:`v4l2_ctrl_mpeg2_quantization`, containing MPEG-2 | ||||||
|  |  	quantization matrices for stateless video decoders. | ||||||
|  | +    * - ``V4L2_CTRL_TYPE_AREA`` | ||||||
|  | +      - n/a | ||||||
|  | +      - n/a | ||||||
|  | +      - n/a | ||||||
|  | +      - A struct :c:type:`v4l2_area`, containing the width and the height | ||||||
|  | +        of a rectangular area. Units depend on the use case. | ||||||
|  |      * - ``V4L2_CTRL_TYPE_H264_SPS`` | ||||||
|  |        - n/a | ||||||
|  |        - n/a | ||||||
|  | --- a/Documentation/media/videodev2.h.rst.exceptions | ||||||
|  | +++ b/Documentation/media/videodev2.h.rst.exceptions | ||||||
|  | @@ -141,6 +141,7 @@ replace symbol V4L2_CTRL_TYPE_H264_PPS : | ||||||
|  |  replace symbol V4L2_CTRL_TYPE_H264_SCALING_MATRIX :c:type:`v4l2_ctrl_type` | ||||||
|  |  replace symbol V4L2_CTRL_TYPE_H264_SLICE_PARAMS :c:type:`v4l2_ctrl_type` | ||||||
|  |  replace symbol V4L2_CTRL_TYPE_H264_DECODE_PARAMS :c:type:`v4l2_ctrl_type` | ||||||
|  | +replace symbol V4L2_CTRL_TYPE_AREA :c:type:`v4l2_ctrl_type` | ||||||
|  |   | ||||||
|  |  # V4L2 capability defines | ||||||
|  |  replace define V4L2_CAP_VIDEO_CAPTURE device-capabilities | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -0,0 +1,37 @@ | |||||||
|  | From 73d8a76ec5b5e1240af4142a9ccbd39179d779af Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Jernej Skrabec <jernej.skrabec@siol.net> | ||||||
|  | Date: Wed, 6 Nov 2019 08:02:53 +0100 | ||||||
|  | Subject: [PATCH] media: v4l2-mem2mem: Fix hold buf flag checks | ||||||
|  |  | ||||||
|  | Commit 1076df3a77b490d33429560a9e0603b3673223e2 upstream. | ||||||
|  |  | ||||||
|  | Hold buf flag is set on output queue, not capture. Fix that. | ||||||
|  |  | ||||||
|  | Fixes: f07602ac3887 ("media: v4l2-mem2mem: add new_frame detection") | ||||||
|  | Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net> | ||||||
|  | Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> | ||||||
|  | Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org> | ||||||
|  | --- | ||||||
|  |  drivers/media/v4l2-core/v4l2-mem2mem.c | 4 ++-- | ||||||
|  |  1 file changed, 2 insertions(+), 2 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/media/v4l2-core/v4l2-mem2mem.c | ||||||
|  | +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c | ||||||
|  | @@ -335,7 +335,7 @@ static void __v4l2_m2m_try_queue(struct | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | -	if (src && dst && (m2m_ctx->cap_q_ctx.q.subsystem_flags & | ||||||
|  | +	if (src && dst && (m2m_ctx->out_q_ctx.q.subsystem_flags & | ||||||
|  |  			   VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF)) | ||||||
|  |  		m2m_ctx->new_frame = !dst->vb2_buf.copied_timestamp || | ||||||
|  |  			dst->vb2_buf.timestamp != src->vb2_buf.timestamp; | ||||||
|  | @@ -474,7 +474,7 @@ void v4l2_m2m_job_finish(struct v4l2_m2m | ||||||
|  |  	 * holding capture buffers. Those should use | ||||||
|  |  	 * v4l2_m2m_buf_done_and_job_finish() instead. | ||||||
|  |  	 */ | ||||||
|  | -	WARN_ON(m2m_ctx->cap_q_ctx.q.subsystem_flags & | ||||||
|  | +	WARN_ON(m2m_ctx->out_q_ctx.q.subsystem_flags & | ||||||
|  |  		VB2_V4L2_FL_SUPPORTS_M2M_HOLD_CAPTURE_BUF); | ||||||
|  |  	spin_lock_irqsave(&m2m_dev->job_spinlock, flags); | ||||||
|  |  	schedule_next = _v4l2_m2m_job_finish(m2m_dev, m2m_ctx); | ||||||
| @@ -0,0 +1,50 @@ | |||||||
|  | From 662256810630f6ac6d06ee0cdc5f4660b25f7e98 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Paul Kocialkowski <paul.kocialkowski@bootlin.com> | ||||||
|  | Date: Tue, 22 Oct 2019 12:26:53 -0300 | ||||||
|  | Subject: [PATCH] media: pixfmt: Document the HEVC slice pixel format | ||||||
|  |  | ||||||
|  | Commit de06f289283298e2938445019999cec46435375c upstream. | ||||||
|  |  | ||||||
|  | Document the current state of the HEVC slice pixel format. | ||||||
|  | The format will need to evolve in the future, which is why it is | ||||||
|  | not part of the public API. | ||||||
|  |  | ||||||
|  | Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com> | ||||||
|  | Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> | ||||||
|  | Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | ||||||
|  | --- | ||||||
|  |  .../media/uapi/v4l/pixfmt-compressed.rst      | 23 +++++++++++++++++++ | ||||||
|  |  1 file changed, 23 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/Documentation/media/uapi/v4l/pixfmt-compressed.rst | ||||||
|  | +++ b/Documentation/media/uapi/v4l/pixfmt-compressed.rst | ||||||
|  | @@ -188,6 +188,29 @@ Compressed Formats | ||||||
|  |  	If :ref:`VIDIOC_ENUM_FMT` reports ``V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM`` | ||||||
|  |  	then the decoder has no	requirements since it can parse all the | ||||||
|  |  	information from the raw bytestream. | ||||||
|  | +    * .. _V4L2-PIX-FMT-HEVC-SLICE: | ||||||
|  | + | ||||||
|  | +      - ``V4L2_PIX_FMT_HEVC_SLICE`` | ||||||
|  | +      - 'S265' | ||||||
|  | +      - HEVC parsed slice data, as extracted from the HEVC bitstream. | ||||||
|  | +	This format is adapted for stateless video decoders that implement a | ||||||
|  | +	HEVC pipeline (using the :ref:`mem2mem` and :ref:`media-request-api`). | ||||||
|  | +	This pixelformat has two modifiers that must be set at least once | ||||||
|  | +	through the ``V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE`` | ||||||
|  | +        and ``V4L2_CID_MPEG_VIDEO_HEVC_START_CODE`` controls. | ||||||
|  | +	Metadata associated with the frame to decode is required to be passed | ||||||
|  | +	through the following controls : | ||||||
|  | +        * ``V4L2_CID_MPEG_VIDEO_HEVC_SPS`` | ||||||
|  | +        * ``V4L2_CID_MPEG_VIDEO_HEVC_PPS`` | ||||||
|  | +        * ``V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS`` | ||||||
|  | +	See the :ref:`associated Codec Control IDs <v4l2-mpeg-hevc>`. | ||||||
|  | +	Buffers associated with this pixel format must contain the appropriate | ||||||
|  | +	number of macroblocks to decode a full corresponding frame. | ||||||
|  | + | ||||||
|  | +	.. note:: | ||||||
|  | + | ||||||
|  | +	   This format is not yet part of the public kernel API and it | ||||||
|  | +	   is expected to change. | ||||||
|  |      * .. _V4L2-PIX-FMT-FWHT: | ||||||
|  |   | ||||||
|  |        - ``V4L2_PIX_FMT_FWHT`` | ||||||
| @@ -0,0 +1,150 @@ | |||||||
|  | From 70b5a28786215c996503210abd3e44c200771640 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Jernej Skrabec <jernej.skrabec@siol.net> | ||||||
|  | Date: Fri, 13 Dec 2019 17:04:25 +0100 | ||||||
|  | Subject: [PATCH] media: uapi: hevc: Add scaling matrix control | ||||||
|  |  | ||||||
|  | Taken from https://patchwork.linuxtv.org/patch/60728/ | ||||||
|  | Changes (mainly documentation) have been requested. | ||||||
|  |  | ||||||
|  | HEVC has a scaling matrix concept. Add support for it. | ||||||
|  |  | ||||||
|  | Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net> | ||||||
|  | --- | ||||||
|  |  .../media/uapi/v4l/ext-ctrls-codec.rst        | 41 +++++++++++++++++++ | ||||||
|  |  .../media/uapi/v4l/pixfmt-compressed.rst      |  1 + | ||||||
|  |  drivers/media/v4l2-core/v4l2-ctrls.c          | 10 +++++ | ||||||
|  |  include/media/hevc-ctrls.h                    | 11 +++++ | ||||||
|  |  4 files changed, 63 insertions(+) | ||||||
|  |  | ||||||
|  | --- a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst | ||||||
|  | +++ b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst | ||||||
|  | @@ -4174,6 +4174,47 @@ enum v4l2_mpeg_video_hevc_size_of_length | ||||||
|  |        - ``padding[6]`` | ||||||
|  |        - Applications and drivers must set this to zero. | ||||||
|  |   | ||||||
|  | +``V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX (struct)`` | ||||||
|  | +    Specifies the scaling matrix (as extracted from the bitstream) for | ||||||
|  | +    the associated HEVC slice data. The bitstream parameters are | ||||||
|  | +    defined according to :ref:`hevc`, section 7.4.5 "Scaling list | ||||||
|  | +    data semantics". For further documentation, refer to the above | ||||||
|  | +    specification, unless there is an explicit comment stating | ||||||
|  | +    otherwise. | ||||||
|  | + | ||||||
|  | +    .. note:: | ||||||
|  | + | ||||||
|  | +       This compound control is not yet part of the public kernel API and | ||||||
|  | +       it is expected to change. | ||||||
|  | + | ||||||
|  | +.. c:type:: v4l2_ctrl_hevc_scaling_matrix | ||||||
|  | + | ||||||
|  | +.. cssclass:: longtable | ||||||
|  | + | ||||||
|  | +.. flat-table:: struct v4l2_ctrl_hevc_scaling_matrix | ||||||
|  | +    :header-rows:  0 | ||||||
|  | +    :stub-columns: 0 | ||||||
|  | +    :widths:       1 1 2 | ||||||
|  | + | ||||||
|  | +    * - __u8 | ||||||
|  | +      - ``scaling_list_4x4[6][16]`` | ||||||
|  | +      - | ||||||
|  | +    * - __u8 | ||||||
|  | +      - ``scaling_list_8x8[6][64]`` | ||||||
|  | +      - | ||||||
|  | +    * - __u8 | ||||||
|  | +      - ``scaling_list_16x16[6][64]`` | ||||||
|  | +      - | ||||||
|  | +    * - __u8 | ||||||
|  | +      - ``scaling_list_32x32[2][64]`` | ||||||
|  | +      - | ||||||
|  | +    * - __u8 | ||||||
|  | +      - ``scaling_list_dc_coef_16x16[6]`` | ||||||
|  | +      - | ||||||
|  | +    * - __u8 | ||||||
|  | +      - ``scaling_list_dc_coef_32x32[2]`` | ||||||
|  | +      - | ||||||
|  | + | ||||||
|  |  ``V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE (enum)`` | ||||||
|  |      Specifies the decoding mode to use. Currently exposes slice-based and | ||||||
|  |      frame-based decoding but new modes might be added later on. | ||||||
|  | --- a/Documentation/media/uapi/v4l/pixfmt-compressed.rst | ||||||
|  | +++ b/Documentation/media/uapi/v4l/pixfmt-compressed.rst | ||||||
|  | @@ -203,6 +203,7 @@ Compressed Formats | ||||||
|  |          * ``V4L2_CID_MPEG_VIDEO_HEVC_SPS`` | ||||||
|  |          * ``V4L2_CID_MPEG_VIDEO_HEVC_PPS`` | ||||||
|  |          * ``V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS`` | ||||||
|  | +        * ``V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX`` | ||||||
|  |  	See the :ref:`associated Codec Control IDs <v4l2-mpeg-hevc>`. | ||||||
|  |  	Buffers associated with this pixel format must contain the appropriate | ||||||
|  |  	number of macroblocks to decode a full corresponding frame. | ||||||
|  | --- a/drivers/media/v4l2-core/v4l2-ctrls.c | ||||||
|  | +++ b/drivers/media/v4l2-core/v4l2-ctrls.c | ||||||
|  | @@ -974,6 +974,7 @@ const char *v4l2_ctrl_get_name(u32 id) | ||||||
|  |  	case V4L2_CID_MPEG_VIDEO_HEVC_SPS:			return "HEVC Sequence Parameter Set"; | ||||||
|  |  	case V4L2_CID_MPEG_VIDEO_HEVC_PPS:			return "HEVC Picture Parameter Set"; | ||||||
|  |  	case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS:		return "HEVC Slice Parameters"; | ||||||
|  | +	case V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX:		return "HEVC Scaling Matrix"; | ||||||
|  |  	case V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE:		return "HEVC Decode Mode"; | ||||||
|  |  	case V4L2_CID_MPEG_VIDEO_HEVC_START_CODE:		return "HEVC Start Code"; | ||||||
|  |   | ||||||
|  | @@ -1406,6 +1407,9 @@ void v4l2_ctrl_fill(u32 id, const char * | ||||||
|  |  	case V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS: | ||||||
|  |  		*type = V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS; | ||||||
|  |  		break; | ||||||
|  | +	case V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX: | ||||||
|  | +		*type = V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX; | ||||||
|  | +		break; | ||||||
|  |  	case V4L2_CID_UNIT_CELL_SIZE: | ||||||
|  |  		*type = V4L2_CTRL_TYPE_AREA; | ||||||
|  |  		*flags |= V4L2_CTRL_FLAG_READ_ONLY; | ||||||
|  | @@ -1852,6 +1856,9 @@ static int std_validate_compound(const s | ||||||
|  |  		zero_padding(*p_hevc_slice_params); | ||||||
|  |  		break; | ||||||
|  |   | ||||||
|  | +	case V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX: | ||||||
|  | +		break; | ||||||
|  | + | ||||||
|  |  	case V4L2_CTRL_TYPE_AREA: | ||||||
|  |  		area = p; | ||||||
|  |  		if (!area->width || !area->height) | ||||||
|  | @@ -2540,6 +2547,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(s | ||||||
|  |  	case V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS: | ||||||
|  |  		elem_size = sizeof(struct v4l2_ctrl_hevc_slice_params); | ||||||
|  |  		break; | ||||||
|  | +	case V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX: | ||||||
|  | +		elem_size = sizeof(struct v4l2_ctrl_hevc_scaling_matrix); | ||||||
|  | +		break; | ||||||
|  |  	case V4L2_CTRL_TYPE_AREA: | ||||||
|  |  		elem_size = sizeof(struct v4l2_area); | ||||||
|  |  		break; | ||||||
|  | --- a/include/media/hevc-ctrls.h | ||||||
|  | +++ b/include/media/hevc-ctrls.h | ||||||
|  | @@ -19,6 +19,7 @@ | ||||||
|  |  #define V4L2_CID_MPEG_VIDEO_HEVC_SPS		(V4L2_CID_MPEG_BASE + 1008) | ||||||
|  |  #define V4L2_CID_MPEG_VIDEO_HEVC_PPS		(V4L2_CID_MPEG_BASE + 1009) | ||||||
|  |  #define V4L2_CID_MPEG_VIDEO_HEVC_SLICE_PARAMS	(V4L2_CID_MPEG_BASE + 1010) | ||||||
|  | +#define V4L2_CID_MPEG_VIDEO_HEVC_SCALING_MATRIX	(V4L2_CID_MPEG_BASE + 1011) | ||||||
|  |  #define V4L2_CID_MPEG_VIDEO_HEVC_DECODE_MODE	(V4L2_CID_MPEG_BASE + 1015) | ||||||
|  |  #define V4L2_CID_MPEG_VIDEO_HEVC_START_CODE	(V4L2_CID_MPEG_BASE + 1016) | ||||||
|  |   | ||||||
|  | @@ -26,6 +27,7 @@ | ||||||
|  |  #define V4L2_CTRL_TYPE_HEVC_SPS 0x0120 | ||||||
|  |  #define V4L2_CTRL_TYPE_HEVC_PPS 0x0121 | ||||||
|  |  #define V4L2_CTRL_TYPE_HEVC_SLICE_PARAMS 0x0122 | ||||||
|  | +#define V4L2_CTRL_TYPE_HEVC_SCALING_MATRIX 0x0123 | ||||||
|  |   | ||||||
|  |  enum v4l2_mpeg_video_hevc_decode_mode { | ||||||
|  |  	V4L2_MPEG_VIDEO_HEVC_DECODE_MODE_SLICE_BASED, | ||||||
|  | @@ -209,4 +211,13 @@ struct v4l2_ctrl_hevc_slice_params { | ||||||
|  |  	__u64	flags; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  | +struct v4l2_ctrl_hevc_scaling_matrix { | ||||||
|  | +	__u8	scaling_list_4x4[6][16]; | ||||||
|  | +	__u8	scaling_list_8x8[6][64]; | ||||||
|  | +	__u8	scaling_list_16x16[6][64]; | ||||||
|  | +	__u8	scaling_list_32x32[2][64]; | ||||||
|  | +	__u8	scaling_list_dc_coef_16x16[6]; | ||||||
|  | +	__u8	scaling_list_dc_coef_32x32[2]; | ||||||
|  | +}; | ||||||
|  | + | ||||||
|  |  #endif | ||||||
| @@ -0,0 +1,61 @@ | |||||||
|  | From 88eb3b015b6f61252fd214d39fc7fc0379ee0442 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Jernej Skrabec <jernej.skrabec@siol.net> | ||||||
|  | Date: Fri, 13 Dec 2019 17:04:27 +0100 | ||||||
|  | Subject: [PATCH] media: uapi: hevc: Add segment address field | ||||||
|  |  | ||||||
|  | From https://patchwork.linuxtv.org/patch/60725/ | ||||||
|  | Changes requested, but mainly docs. | ||||||
|  |  | ||||||
|  | If HEVC frame consists of multiple slices, segment address has to be | ||||||
|  | known in order to properly decode it. | ||||||
|  |  | ||||||
|  | Add segment address field to slice parameters. | ||||||
|  |  | ||||||
|  | Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net> | ||||||
|  | --- | ||||||
|  |  Documentation/media/uapi/v4l/ext-ctrls-codec.rst | 5 ++++- | ||||||
|  |  include/media/hevc-ctrls.h                       | 5 ++++- | ||||||
|  |  2 files changed, 8 insertions(+), 2 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/Documentation/media/uapi/v4l/ext-ctrls-codec.rst | ||||||
|  | +++ b/Documentation/media/uapi/v4l/ext-ctrls-codec.rst | ||||||
|  | @@ -3969,6 +3969,9 @@ enum v4l2_mpeg_video_hevc_size_of_length | ||||||
|  |      * - __u32 | ||||||
|  |        - ``data_bit_offset`` | ||||||
|  |        - Offset (in bits) to the video data in the current slice data. | ||||||
|  | +    * - __u32 | ||||||
|  | +      - ``slice_segment_addr`` | ||||||
|  | +      - | ||||||
|  |      * - __u8 | ||||||
|  |        - ``nal_unit_type`` | ||||||
|  |        - | ||||||
|  | @@ -4046,7 +4049,7 @@ enum v4l2_mpeg_video_hevc_size_of_length | ||||||
|  |        - ``num_rps_poc_lt_curr`` | ||||||
|  |        - The number of reference pictures in the long-term set. | ||||||
|  |      * - __u8 | ||||||
|  | -      - ``padding[7]`` | ||||||
|  | +      - ``padding[5]`` | ||||||
|  |        - Applications and drivers must set this to zero. | ||||||
|  |      * - struct :c:type:`v4l2_hevc_dpb_entry` | ||||||
|  |        - ``dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]`` | ||||||
|  | --- a/include/media/hevc-ctrls.h | ||||||
|  | +++ b/include/media/hevc-ctrls.h | ||||||
|  | @@ -167,6 +167,9 @@ struct v4l2_ctrl_hevc_slice_params { | ||||||
|  |  	__u32	bit_size; | ||||||
|  |  	__u32	data_bit_offset; | ||||||
|  |   | ||||||
|  | +	/* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ | ||||||
|  | +	__u32	slice_segment_addr; | ||||||
|  | + | ||||||
|  |  	/* ISO/IEC 23008-2, ITU-T Rec. H.265: NAL unit header */ | ||||||
|  |  	__u8	nal_unit_type; | ||||||
|  |  	__u8	nuh_temporal_id_plus1; | ||||||
|  | @@ -200,7 +203,7 @@ struct v4l2_ctrl_hevc_slice_params { | ||||||
|  |  	__u8	num_rps_poc_st_curr_after; | ||||||
|  |  	__u8	num_rps_poc_lt_curr; | ||||||
|  |   | ||||||
|  | -	__u8	padding; | ||||||
|  | +	__u8	padding[5]; | ||||||
|  |   | ||||||
|  |  	/* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ | ||||||
|  |  	struct v4l2_hevc_dpb_entry dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; | ||||||
| @@ -0,0 +1,23 @@ | |||||||
|  | From e8355c6b60adb6704c9fb863f380f2d7b457d82c Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Dave Stevenson <dave.stevenson@raspberrypi.com> | ||||||
|  | Date: Mon, 23 Mar 2020 18:34:01 +0000 | ||||||
|  | Subject: [PATCH] media: hevc_ctrls: Add slice param dependent slice | ||||||
|  |  segment | ||||||
|  |  | ||||||
|  | Adds V4L2_HEVC_SLICE_PARAMS_FLAG_DEPENDENT_SLICE_SEGMENT define. | ||||||
|  |  | ||||||
|  | Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> | ||||||
|  | --- | ||||||
|  |  include/media/hevc-ctrls.h | 1 + | ||||||
|  |  1 file changed, 1 insertion(+) | ||||||
|  |  | ||||||
|  | --- a/include/media/hevc-ctrls.h | ||||||
|  | +++ b/include/media/hevc-ctrls.h | ||||||
|  | @@ -162,6 +162,7 @@ struct v4l2_hevc_pred_weight_table { | ||||||
|  |  #define V4L2_HEVC_SLICE_PARAMS_FLAG_USE_INTEGER_MV		(1ULL << 6) | ||||||
|  |  #define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_DEBLOCKING_FILTER_DISABLED (1ULL << 7) | ||||||
|  |  #define V4L2_HEVC_SLICE_PARAMS_FLAG_SLICE_LOOP_FILTER_ACROSS_SLICES_ENABLED (1ULL << 8) | ||||||
|  | +#define V4L2_HEVC_SLICE_PARAMS_FLAG_DEPENDENT_SLICE_SEGMENT	(1ULL << 9) | ||||||
|  |   | ||||||
|  |  struct v4l2_ctrl_hevc_slice_params { | ||||||
|  |  	__u32	bit_size; | ||||||
| @@ -0,0 +1,40 @@ | |||||||
|  | From 6a42d17668699234bfa2d459e29cc2732e59759b Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Dave Stevenson <dave.stevenson@raspberrypi.com> | ||||||
|  | Date: Mon, 23 Mar 2020 19:00:17 +0000 | ||||||
|  | Subject: [PATCH] media: uapi: Add hevc ctrls for WPP decoding | ||||||
|  |  | ||||||
|  | WPP can allow greater parallelism within the decode, but needs | ||||||
|  | offset information to be passed in. | ||||||
|  |  | ||||||
|  | Adds num_entry_point_offsets and entry_point_offset_minus1 to | ||||||
|  | v4l2_ctrl_hevc_slice_params. | ||||||
|  |  | ||||||
|  | This is based on Jernej Skrabec's patches for cedrus which | ||||||
|  | implement the same feature. | ||||||
|  |  | ||||||
|  | Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> | ||||||
|  | --- | ||||||
|  |  include/media/hevc-ctrls.h | 5 ++++- | ||||||
|  |  1 file changed, 4 insertions(+), 1 deletion(-) | ||||||
|  |  | ||||||
|  | --- a/include/media/hevc-ctrls.h | ||||||
|  | +++ b/include/media/hevc-ctrls.h | ||||||
|  | @@ -170,6 +170,7 @@ struct v4l2_ctrl_hevc_slice_params { | ||||||
|  |   | ||||||
|  |  	/* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ | ||||||
|  |  	__u32	slice_segment_addr; | ||||||
|  | +	__u32	num_entry_point_offsets; | ||||||
|  |   | ||||||
|  |  	/* ISO/IEC 23008-2, ITU-T Rec. H.265: NAL unit header */ | ||||||
|  |  	__u8	nal_unit_type; | ||||||
|  | @@ -204,7 +205,9 @@ struct v4l2_ctrl_hevc_slice_params { | ||||||
|  |  	__u8	num_rps_poc_st_curr_after; | ||||||
|  |  	__u8	num_rps_poc_lt_curr; | ||||||
|  |   | ||||||
|  | -	__u8	padding[5]; | ||||||
|  | +	__u8	padding; | ||||||
|  | + | ||||||
|  | +	__u32	entry_point_offset_minus1[256]; | ||||||
|  |   | ||||||
|  |  	/* ISO/IEC 23008-2, ITU-T Rec. H.265: General slice segment header */ | ||||||
|  |  	struct v4l2_hevc_dpb_entry dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; | ||||||
| @@ -0,0 +1,302 @@ | |||||||
|  | From a8f52dad0ed65192eb880a4a1ca90b236e99711e Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Dave Stevenson <dave.stevenson@raspberrypi.com> | ||||||
|  | Date: Fri, 24 Jan 2020 14:28:21 +0000 | ||||||
|  | Subject: [PATCH] media: videodev2.h: Add a format for column YUV4:2:0 | ||||||
|  |  modes | ||||||
|  |  | ||||||
|  | Some of the Broadcom codec blocks use a column based YUV4:2:0 image | ||||||
|  | format, so add the documentation and defines for both 8 and 10 bit | ||||||
|  | versions. | ||||||
|  |  | ||||||
|  | Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> | ||||||
|  | --- | ||||||
|  |  .../media/uapi/v4l/pixfmt-nv12-col128.rst     | 215 ++++++++++++++++++ | ||||||
|  |  Documentation/media/uapi/v4l/pixfmt-nv12.rst  |  14 +- | ||||||
|  |  Documentation/media/uapi/v4l/yuv-formats.rst  |   1 + | ||||||
|  |  drivers/media/v4l2-core/v4l2-ioctl.c          |   2 + | ||||||
|  |  include/uapi/linux/videodev2.h                |   4 + | ||||||
|  |  5 files changed, 233 insertions(+), 3 deletions(-) | ||||||
|  |  create mode 100644 Documentation/media/uapi/v4l/pixfmt-nv12-col128.rst | ||||||
|  |  | ||||||
|  | --- /dev/null | ||||||
|  | +++ b/Documentation/media/uapi/v4l/pixfmt-nv12-col128.rst | ||||||
|  | @@ -0,0 +1,215 @@ | ||||||
|  | +.. Permission is granted to copy, distribute and/or modify this | ||||||
|  | +.. document under the terms of the GNU Free Documentation License, | ||||||
|  | +.. Version 1.1 or any later version published by the Free Software | ||||||
|  | +.. Foundation, with no Invariant Sections, no Front-Cover Texts | ||||||
|  | +.. and no Back-Cover Texts. A copy of the license is included at | ||||||
|  | +.. Documentation/media/uapi/fdl-appendix.rst. | ||||||
|  | +.. | ||||||
|  | +.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections | ||||||
|  | + | ||||||
|  | +.. _V4L2_PIX_FMT_NV12_COL128: | ||||||
|  | +.. _V4L2_PIX_FMT_NV12_10_COL128: | ||||||
|  | + | ||||||
|  | +******************************************************************************** | ||||||
|  | +V4L2_PIX_FMT_NV12_COL128, V4L2_PIX_FMT_NV12_10_COL128 | ||||||
|  | +******************************************************************************** | ||||||
|  | + | ||||||
|  | + | ||||||
|  | +V4L2_PIX_FMT_NV21_COL128 | ||||||
|  | +Formats with ½ horizontal and vertical chroma resolution. This format | ||||||
|  | +has two planes - one for luminance and one for chrominance. Chroma | ||||||
|  | +samples are interleaved. The difference to ``V4L2_PIX_FMT_NV12`` is the | ||||||
|  | +memory layout. The image is split into columns of 128 bytes wide rather than | ||||||
|  | +being in raster order. | ||||||
|  | + | ||||||
|  | +V4L2_PIX_FMT_NV12_10_COL128 | ||||||
|  | +Follows the same pattern as ``V4L2_PIX_FMT_NV21_COL128`` with 128 byte, but is | ||||||
|  | +a 10bit format with 3 10-bit samples being packed into 4 bytes. Each 128 byte | ||||||
|  | +wide column therefore contains 96 samples. | ||||||
|  | + | ||||||
|  | + | ||||||
|  | +Description | ||||||
|  | +=========== | ||||||
|  | + | ||||||
|  | +This is the two-plane versions of the YUV 4:2:0 format where data is | ||||||
|  | +grouped into 128 byte wide columns. The three components are separated into | ||||||
|  | +two sub-images or planes. The Y plane has one byte per pixel and pixels | ||||||
|  | +are grouped into 128 byte wide columns. The CbCr plane has the same width, | ||||||
|  | +in bytes, as the Y plane (and the image), but is half as tall in pixels. | ||||||
|  | +The chroma plane is also in 128 byte columns, reflecting 64 Cb and 64 Cr | ||||||
|  | +samples. | ||||||
|  | + | ||||||
|  | +The chroma samples for a column follow the luma samples. If there is any | ||||||
|  | +paddding, then that will be reflected via the selection API. | ||||||
|  | +The luma height must be a multiple of 2 lines. | ||||||
|  | + | ||||||
|  | +The normal bytesperline is effectively fixed at 128. However the format | ||||||
|  | +requires knowledge of the stride between columns, therefore the bytesperline | ||||||
|  | +value has been repurposed to denote the number of 128 byte long lines between | ||||||
|  | +the start of each column. | ||||||
|  | + | ||||||
|  | +**Byte Order.** | ||||||
|  | + | ||||||
|  | + | ||||||
|  | +.. flat-table:: | ||||||
|  | +    :header-rows:  0 | ||||||
|  | +    :stub-columns: 0 | ||||||
|  | +    :widths: 12 12 12 12 12 4 12 12 12 12 | ||||||
|  | + | ||||||
|  | +    * - start + 0: | ||||||
|  | +      - Y'\ :sub:`0,0` | ||||||
|  | +      - Y'\ :sub:`0,1` | ||||||
|  | +      - Y'\ :sub:`0,2` | ||||||
|  | +      - Y'\ :sub:`0,3` | ||||||
|  | +      - ... | ||||||
|  | +      - Y'\ :sub:`0,124` | ||||||
|  | +      - Y'\ :sub:`0,125` | ||||||
|  | +      - Y'\ :sub:`0,126` | ||||||
|  | +      - Y'\ :sub:`0,127` | ||||||
|  | +    * - start + 128: | ||||||
|  | +      - Y'\ :sub:`1,0` | ||||||
|  | +      - Y'\ :sub:`1,1` | ||||||
|  | +      - Y'\ :sub:`1,2` | ||||||
|  | +      - Y'\ :sub:`1,3` | ||||||
|  | +      - ... | ||||||
|  | +      - Y'\ :sub:`1,124` | ||||||
|  | +      - Y'\ :sub:`1,125` | ||||||
|  | +      - Y'\ :sub:`1,126` | ||||||
|  | +      - Y'\ :sub:`1,127` | ||||||
|  | +    * - start + 256: | ||||||
|  | +      - Y'\ :sub:`2,0` | ||||||
|  | +      - Y'\ :sub:`2,1` | ||||||
|  | +      - Y'\ :sub:`2,2` | ||||||
|  | +      - Y'\ :sub:`2,3` | ||||||
|  | +      - ... | ||||||
|  | +      - Y'\ :sub:`2,124` | ||||||
|  | +      - Y'\ :sub:`2,125` | ||||||
|  | +      - Y'\ :sub:`2,126` | ||||||
|  | +      - Y'\ :sub:`2,127` | ||||||
|  | +    * - ... | ||||||
|  | +      - ... | ||||||
|  | +      - ... | ||||||
|  | +      - ... | ||||||
|  | +      - ... | ||||||
|  | +      - ... | ||||||
|  | +      - ... | ||||||
|  | +      - ... | ||||||
|  | +    * - start + ((height-1) * 128): | ||||||
|  | +      - Y'\ :sub:`height-1,0` | ||||||
|  | +      - Y'\ :sub:`height-1,1` | ||||||
|  | +      - Y'\ :sub:`height-1,2` | ||||||
|  | +      - Y'\ :sub:`height-1,3` | ||||||
|  | +      - ... | ||||||
|  | +      - Y'\ :sub:`height-1,124` | ||||||
|  | +      - Y'\ :sub:`height-1,125` | ||||||
|  | +      - Y'\ :sub:`height-1,126` | ||||||
|  | +      - Y'\ :sub:`height-1,127` | ||||||
|  | +    * - start + ((height) * 128): | ||||||
|  | +      - Cb\ :sub:`0,0` | ||||||
|  | +      - Cr\ :sub:`0,0` | ||||||
|  | +      - Cb\ :sub:`0,1` | ||||||
|  | +      - Cr\ :sub:`0,1` | ||||||
|  | +      - ... | ||||||
|  | +      - Cb\ :sub:`0,62` | ||||||
|  | +      - Cr\ :sub:`0,62` | ||||||
|  | +      - Cb\ :sub:`0,63` | ||||||
|  | +      - Cr\ :sub:`0,63` | ||||||
|  | +    * - start + ((height+1) * 128): | ||||||
|  | +      - Cb\ :sub:`1,0` | ||||||
|  | +      - Cr\ :sub:`1,0` | ||||||
|  | +      - Cb\ :sub:`1,1` | ||||||
|  | +      - Cr\ :sub:`1,1` | ||||||
|  | +      - ... | ||||||
|  | +      - Cb\ :sub:`1,62` | ||||||
|  | +      - Cr\ :sub:`1,62` | ||||||
|  | +      - Cb\ :sub:`1,63` | ||||||
|  | +      - Cr\ :sub:`1,63` | ||||||
|  | +    * - ... | ||||||
|  | +      - ... | ||||||
|  | +      - ... | ||||||
|  | +      - ... | ||||||
|  | +      - ... | ||||||
|  | +      - ... | ||||||
|  | +      - ... | ||||||
|  | +      - ... | ||||||
|  | +    * - start + ((height+(height/2)-1) * 128): | ||||||
|  | +      - Cb\ :sub:`(height/2)-1,0` | ||||||
|  | +      - Cr\ :sub:`(height/2)-1,0` | ||||||
|  | +      - Cb\ :sub:`(height/2)-1,1` | ||||||
|  | +      - Cr\ :sub:`(height/2)-1,1` | ||||||
|  | +      - ... | ||||||
|  | +      - Cb\ :sub:`(height/2)-1,62` | ||||||
|  | +      - Cr\ :sub:`(height/2)-1,62` | ||||||
|  | +      - Cb\ :sub:`(height/2)-1,63` | ||||||
|  | +      - Cr\ :sub:`(height/2)-1,63` | ||||||
|  | +    * - start + (bytesperline * 128): | ||||||
|  | +      - Y'\ :sub:`0,128` | ||||||
|  | +      - Y'\ :sub:`0,129` | ||||||
|  | +      - Y'\ :sub:`0,130` | ||||||
|  | +      - Y'\ :sub:`0,131` | ||||||
|  | +      - ... | ||||||
|  | +      - Y'\ :sub:`0,252` | ||||||
|  | +      - Y'\ :sub:`0,253` | ||||||
|  | +      - Y'\ :sub:`0,254` | ||||||
|  | +      - Y'\ :sub:`0,255` | ||||||
|  | +    * - ... | ||||||
|  | +      - ... | ||||||
|  | +      - ... | ||||||
|  | +      - ... | ||||||
|  | +      - ... | ||||||
|  | +      - ... | ||||||
|  | +      - ... | ||||||
|  | +      - ... | ||||||
|  | + | ||||||
|  | +V4L2_PIX_FMT_NV12_10_COL128 uses the same 128 byte column structure, but | ||||||
|  | +encodes 10-bit YUV. | ||||||
|  | +3 10-bit values are packed into 4 bytes as bits 9:0, 19:10, and 29:20, with | ||||||
|  | +bits 30 & 31 unused. For the luma plane, bits 9:0 are Y0, 19:10 are Y1, and | ||||||
|  | +29:20 are Y2. For the chroma plane the samples always come in pairs of Cr | ||||||
|  | +and Cb, so it needs to be considered 6 values packed in 8 bytes. | ||||||
|  | + | ||||||
|  | +Bit-packed representation. | ||||||
|  | + | ||||||
|  | +.. raw:: latex | ||||||
|  | + | ||||||
|  | +    \small | ||||||
|  | + | ||||||
|  | +.. tabularcolumns:: |p{1.2cm}||p{1.2cm}||p{1.2cm}||p{1.2cm}|p{3.2cm}|p{3.2cm}| | ||||||
|  | + | ||||||
|  | +.. flat-table:: | ||||||
|  | +    :header-rows:  0 | ||||||
|  | +    :stub-columns: 0 | ||||||
|  | +    :widths: 8 8 8 8 | ||||||
|  | + | ||||||
|  | +    * - Y'\ :sub:`00[7:0]` | ||||||
|  | +      - Y'\ :sub:`01[5:0] (bits 7--2)` Y'\ :sub:`00[9:8]`\ (bits 1--0) | ||||||
|  | +      - Y'\ :sub:`02[3:0] (bits 7--4)` Y'\ :sub:`01[9:6]`\ (bits 3--0) | ||||||
|  | +      - unused (bits 7--6)` Y'\ :sub:`02[9:4]`\ (bits 5--0) | ||||||
|  | + | ||||||
|  | +.. raw:: latex | ||||||
|  | + | ||||||
|  | +    \small | ||||||
|  | + | ||||||
|  | +.. tabularcolumns:: |p{1.2cm}||p{1.2cm}||p{1.2cm}||p{1.2cm}|p{3.2cm}|p{3.2cm}| | ||||||
|  | + | ||||||
|  | +.. flat-table:: | ||||||
|  | +    :header-rows:  0 | ||||||
|  | +    :stub-columns: 0 | ||||||
|  | +    :widths: 12 12 12 12 12 12 12 12 | ||||||
|  | + | ||||||
|  | +    * - Cb\ :sub:`00[7:0]` | ||||||
|  | +      - Cr\ :sub:`00[5:0]`\ (bits 7--2) Cb\ :sub:`00[9:8]`\ (bits 1--0) | ||||||
|  | +      - Cb\ :sub:`01[3:0]`\ (bits 7--4) Cr\ :sub:`00[9:6]`\ (bits 3--0) | ||||||
|  | +      - unused (bits 7--6) Cb\ :sub:`02[9:4]`\ (bits 5--0) | ||||||
|  | +      - Cr\ :sub:`01[7:0]` | ||||||
|  | +      - Cb\ :sub:`02[5:0]`\ (bits 7--2) Cr\ :sub:`01[9:8]`\ (bits 1--0) | ||||||
|  | +      - Cr\ :sub:`02[3:0]`\ (bits 7--4) Cb\ :sub:`02[9:6]`\ (bits 3--0) | ||||||
|  | +      - unused (bits 7--6) Cr\ :sub:`02[9:4]`\ (bits 5--0) | ||||||
|  | + | ||||||
|  | +.. raw:: latex | ||||||
|  | + | ||||||
|  | +    \normalsize | ||||||
|  | + | ||||||
|  | + | ||||||
|  | + | ||||||
|  | + | ||||||
|  | --- a/Documentation/media/uapi/v4l/pixfmt-nv12.rst | ||||||
|  | +++ b/Documentation/media/uapi/v4l/pixfmt-nv12.rst | ||||||
|  | @@ -10,9 +10,9 @@ | ||||||
|  |  .. _V4L2-PIX-FMT-NV12: | ||||||
|  |  .. _V4L2-PIX-FMT-NV21: | ||||||
|  |   | ||||||
|  | -****************************************************** | ||||||
|  | -V4L2_PIX_FMT_NV12 ('NV12'), V4L2_PIX_FMT_NV21 ('NV21') | ||||||
|  | -****************************************************** | ||||||
|  | +******************************************************************************** | ||||||
|  | +V4L2_PIX_FMT_NV12 ('NV12'), V4L2_PIX_FMT_NV21 ('NV21'), V4L2_PIX_FMT_NV12_COL128 | ||||||
|  | +******************************************************************************** | ||||||
|  |   | ||||||
|  |   | ||||||
|  |  V4L2_PIX_FMT_NV21 | ||||||
|  | @@ -38,6 +38,14 @@ with a Cr byte. | ||||||
|  |  If the Y plane has pad bytes after each row, then the CbCr plane has as | ||||||
|  |  many pad bytes after its rows. | ||||||
|  |   | ||||||
|  | +``V4L2_PIX_FMT_NV12_COL128`` is the tiled version of | ||||||
|  | +``V4L2_PIX_FMT_NV12`` with the image broken down into 128 pixel wide columns of | ||||||
|  | +Y followed by the associated combined CbCr plane. | ||||||
|  | +The normal bytesperline is effectively fixed at 128. However the format | ||||||
|  | +requires knowledge of the stride between columns, therefore the bytesperline | ||||||
|  | +value has been repurposed to denote the number of 128 byte long lines between | ||||||
|  | +the start of each column. | ||||||
|  | + | ||||||
|  |  **Byte Order.** | ||||||
|  |  Each cell is one byte. | ||||||
|  |   | ||||||
|  | --- a/Documentation/media/uapi/v4l/yuv-formats.rst | ||||||
|  | +++ b/Documentation/media/uapi/v4l/yuv-formats.rst | ||||||
|  | @@ -57,6 +57,7 @@ to brightness information. | ||||||
|  |      pixfmt-nv12 | ||||||
|  |      pixfmt-nv12m | ||||||
|  |      pixfmt-nv12mt | ||||||
|  | +    pixfmt-nv12-col128 | ||||||
|  |      pixfmt-nv16 | ||||||
|  |      pixfmt-nv16m | ||||||
|  |      pixfmt-nv24 | ||||||
|  | --- a/drivers/media/v4l2-core/v4l2-ioctl.c | ||||||
|  | +++ b/drivers/media/v4l2-core/v4l2-ioctl.c | ||||||
|  | @@ -1258,6 +1258,8 @@ static void v4l_fill_fmtdesc(struct v4l2 | ||||||
|  |  	case V4L2_PIX_FMT_NV61M:	descr = "Y/CrCb 4:2:2 (N-C)"; break; | ||||||
|  |  	case V4L2_PIX_FMT_NV12MT:	descr = "Y/CbCr 4:2:0 (64x32 MB, N-C)"; break; | ||||||
|  |  	case V4L2_PIX_FMT_NV12MT_16X16:	descr = "Y/CbCr 4:2:0 (16x16 MB, N-C)"; break; | ||||||
|  | +	case V4L2_PIX_FMT_NV12_COL128:	descr = "Y/CbCr 4:2:0 (128b cols)"; break; | ||||||
|  | +	case V4L2_PIX_FMT_NV12_10_COL128: descr = "10-bit Y/CbCr 4:2:0 (128b cols)"; break; | ||||||
|  |  	case V4L2_PIX_FMT_YUV420M:	descr = "Planar YUV 4:2:0 (N-C)"; break; | ||||||
|  |  	case V4L2_PIX_FMT_YVU420M:	descr = "Planar YVU 4:2:0 (N-C)"; break; | ||||||
|  |  	case V4L2_PIX_FMT_YUV422M:	descr = "Planar YUV 4:2:2 (N-C)"; break; | ||||||
|  | --- a/include/uapi/linux/videodev2.h | ||||||
|  | +++ b/include/uapi/linux/videodev2.h | ||||||
|  | @@ -737,6 +737,10 @@ struct v4l2_pix_format { | ||||||
|  |  #define V4L2_PIX_FMT_INZI     v4l2_fourcc('I', 'N', 'Z', 'I') /* Intel Planar Greyscale 10-bit and Depth 16-bit */ | ||||||
|  |  #define V4L2_PIX_FMT_SUNXI_TILED_NV12 v4l2_fourcc('S', 'T', '1', '2') /* Sunxi Tiled NV12 Format */ | ||||||
|  |  #define V4L2_PIX_FMT_CNF4     v4l2_fourcc('C', 'N', 'F', '4') /* Intel 4-bit packed depth confidence information */ | ||||||
|  | +#define V4L2_PIX_FMT_NV12_COL128 v4l2_fourcc('N', 'C', '1', '2') /* 12  Y/CbCr 4:2:0 128 pixel wide column */ | ||||||
|  | +#define V4L2_PIX_FMT_NV12_10_COL128 v4l2_fourcc('N', 'C', '3', '0') | ||||||
|  | +								/* Y/CbCr 4:2:0 10bpc, 3x10 packed as 4 bytes in | ||||||
|  | +								 * a 128 bytes / 96 pixel wide column */ | ||||||
|  |   | ||||||
|  |  /* 10bit raw bayer packed, 32 bytes for every 25 pixels, last LSB 6 bits unused */ | ||||||
|  |  #define V4L2_PIX_FMT_IPU3_SBGGR10	v4l2_fourcc('i', 'p', '3', 'b') /* IPU3 packed 10-bit BGGR bayer */ | ||||||
| @@ -0,0 +1,274 @@ | |||||||
|  | From b8ae9d55d468a9f55524296247dba93531c29c99 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: John Cox <jc@kynesim.co.uk> | ||||||
|  | Date: Thu, 5 Mar 2020 14:46:54 +0000 | ||||||
|  | Subject: [PATCH] media: v4l2-mem2mem: allow request job buffer | ||||||
|  |  processing after job finish | ||||||
|  |  | ||||||
|  | Allow the capture buffer to be detached from a v4l2 request job such | ||||||
|  | that another job can start before the capture buffer is returned. This | ||||||
|  | allows h/w codecs that can process multiple requests at the same time | ||||||
|  | to operate more efficiently. | ||||||
|  |  | ||||||
|  | Signed-off-by: John Cox <jc@kynesim.co.uk> | ||||||
|  | --- | ||||||
|  |  drivers/media/v4l2-core/v4l2-mem2mem.c | 105 +++++++++++++++++++++++-- | ||||||
|  |  include/media/v4l2-mem2mem.h           |  47 +++++++++++ | ||||||
|  |  include/media/videobuf2-v4l2.h         |   3 + | ||||||
|  |  3 files changed, 149 insertions(+), 6 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/media/v4l2-core/v4l2-mem2mem.c | ||||||
|  | +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c | ||||||
|  | @@ -399,15 +399,18 @@ static void v4l2_m2m_cancel_job(struct v | ||||||
|  |  { | ||||||
|  |  	struct v4l2_m2m_dev *m2m_dev; | ||||||
|  |  	unsigned long flags; | ||||||
|  | +	bool det_abort_req; | ||||||
|  |   | ||||||
|  |  	m2m_dev = m2m_ctx->m2m_dev; | ||||||
|  |  	spin_lock_irqsave(&m2m_dev->job_spinlock, flags); | ||||||
|  |   | ||||||
|  | +	det_abort_req = !list_empty(&m2m_ctx->det_list); | ||||||
|  |  	m2m_ctx->job_flags |= TRANS_ABORT; | ||||||
|  |  	if (m2m_ctx->job_flags & TRANS_RUNNING) { | ||||||
|  |  		spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); | ||||||
|  |  		if (m2m_dev->m2m_ops->job_abort) | ||||||
|  |  			m2m_dev->m2m_ops->job_abort(m2m_ctx->priv); | ||||||
|  | +		det_abort_req = false; | ||||||
|  |  		dprintk("m2m_ctx %p running, will wait to complete\n", m2m_ctx); | ||||||
|  |  		wait_event(m2m_ctx->finished, | ||||||
|  |  				!(m2m_ctx->job_flags & TRANS_RUNNING)); | ||||||
|  | @@ -421,6 +424,11 @@ static void v4l2_m2m_cancel_job(struct v | ||||||
|  |  		/* Do nothing, was not on queue/running */ | ||||||
|  |  		spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); | ||||||
|  |  	} | ||||||
|  | + | ||||||
|  | +	/* Wait for detached buffers to come back too */ | ||||||
|  | +	if (det_abort_req && m2m_dev->m2m_ops->job_abort) | ||||||
|  | +		m2m_dev->m2m_ops->job_abort(m2m_ctx->priv); | ||||||
|  | +	wait_event(m2m_ctx->det_empty, list_empty(&m2m_ctx->det_list)); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  /* | ||||||
|  | @@ -458,6 +466,7 @@ static bool _v4l2_m2m_job_finish(struct | ||||||
|  |   | ||||||
|  |  	list_del(&m2m_dev->curr_ctx->queue); | ||||||
|  |  	m2m_dev->curr_ctx->job_flags &= ~(TRANS_QUEUED | TRANS_RUNNING); | ||||||
|  | +	m2m_ctx->cap_detached = false; | ||||||
|  |  	wake_up(&m2m_dev->curr_ctx->finished); | ||||||
|  |  	m2m_dev->curr_ctx = NULL; | ||||||
|  |  	return true; | ||||||
|  | @@ -485,6 +494,80 @@ void v4l2_m2m_job_finish(struct v4l2_m2m | ||||||
|  |  } | ||||||
|  |  EXPORT_SYMBOL(v4l2_m2m_job_finish); | ||||||
|  |   | ||||||
|  | +struct vb2_v4l2_buffer *_v4l2_m2m_cap_buf_detach(struct v4l2_m2m_ctx *m2m_ctx) | ||||||
|  | +{ | ||||||
|  | +	struct vb2_v4l2_buffer *buf; | ||||||
|  | + | ||||||
|  | +	buf = v4l2_m2m_dst_buf_remove(m2m_ctx); | ||||||
|  | +	list_add_tail(&container_of(buf, struct v4l2_m2m_buffer, vb)->list, | ||||||
|  | +		      &m2m_ctx->det_list); | ||||||
|  | +	m2m_ctx->cap_detached = true; | ||||||
|  | +	buf->is_held = true; | ||||||
|  | +	buf->det_state = VB2_BUF_STATE_ACTIVE; | ||||||
|  | + | ||||||
|  | +	return buf; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +struct vb2_v4l2_buffer *v4l2_m2m_cap_buf_detach(struct v4l2_m2m_dev *m2m_dev, | ||||||
|  | +						struct v4l2_m2m_ctx *m2m_ctx) | ||||||
|  | +{ | ||||||
|  | +	unsigned long flags; | ||||||
|  | +	struct vb2_v4l2_buffer *src_buf, *dst_buf; | ||||||
|  | + | ||||||
|  | +	spin_lock_irqsave(&m2m_dev->job_spinlock, flags); | ||||||
|  | + | ||||||
|  | +	dst_buf = NULL; | ||||||
|  | +	src_buf = v4l2_m2m_next_src_buf(m2m_ctx); | ||||||
|  | + | ||||||
|  | +	if (!(src_buf->flags & V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF) && | ||||||
|  | +	    !m2m_ctx->cap_detached) | ||||||
|  | +		dst_buf = _v4l2_m2m_cap_buf_detach(m2m_ctx); | ||||||
|  | + | ||||||
|  | +	spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); | ||||||
|  | +	return dst_buf; | ||||||
|  | +} | ||||||
|  | +EXPORT_SYMBOL(v4l2_m2m_cap_buf_detach); | ||||||
|  | + | ||||||
|  | +static void _v4l2_m2m_cap_buf_return(struct v4l2_m2m_ctx *m2m_ctx, | ||||||
|  | +				     struct vb2_v4l2_buffer *buf, | ||||||
|  | +				     enum vb2_buffer_state state) | ||||||
|  | +{ | ||||||
|  | +	buf->det_state = state; | ||||||
|  | + | ||||||
|  | +	/* | ||||||
|  | +	 * Always signal done in the order we got stuff | ||||||
|  | +	 * Stop if we find a buf that is still in use | ||||||
|  | +	 */ | ||||||
|  | +	while (!list_empty(&m2m_ctx->det_list)) { | ||||||
|  | +		buf = &list_first_entry(&m2m_ctx->det_list, | ||||||
|  | +					struct v4l2_m2m_buffer, list)->vb; | ||||||
|  | +		state = buf->det_state; | ||||||
|  | +		if (state != VB2_BUF_STATE_DONE && | ||||||
|  | +		    state != VB2_BUF_STATE_ERROR) | ||||||
|  | +			return; | ||||||
|  | +		list_del(&container_of(buf, struct v4l2_m2m_buffer, vb)->list); | ||||||
|  | +		buf->det_state = VB2_BUF_STATE_DEQUEUED; | ||||||
|  | +		v4l2_m2m_buf_done(buf, state); | ||||||
|  | +	} | ||||||
|  | +	wake_up(&m2m_ctx->det_empty); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +void v4l2_m2m_cap_buf_return(struct v4l2_m2m_dev *m2m_dev, | ||||||
|  | +			     struct v4l2_m2m_ctx *m2m_ctx, | ||||||
|  | +			     struct vb2_v4l2_buffer *buf, | ||||||
|  | +			     enum vb2_buffer_state state) | ||||||
|  | +{ | ||||||
|  | +	unsigned long flags; | ||||||
|  | + | ||||||
|  | +	if (!buf) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  | +	spin_lock_irqsave(&m2m_dev->job_spinlock, flags); | ||||||
|  | +	_v4l2_m2m_cap_buf_return(m2m_ctx, buf, state); | ||||||
|  | +	spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); | ||||||
|  | +} | ||||||
|  | +EXPORT_SYMBOL(v4l2_m2m_cap_buf_return); | ||||||
|  | + | ||||||
|  |  void v4l2_m2m_buf_done_and_job_finish(struct v4l2_m2m_dev *m2m_dev, | ||||||
|  |  				      struct v4l2_m2m_ctx *m2m_ctx, | ||||||
|  |  				      enum vb2_buffer_state state) | ||||||
|  | @@ -495,15 +578,23 @@ void v4l2_m2m_buf_done_and_job_finish(st | ||||||
|  |   | ||||||
|  |  	spin_lock_irqsave(&m2m_dev->job_spinlock, flags); | ||||||
|  |  	src_buf = v4l2_m2m_src_buf_remove(m2m_ctx); | ||||||
|  | -	dst_buf = v4l2_m2m_next_dst_buf(m2m_ctx); | ||||||
|  |   | ||||||
|  | -	if (WARN_ON(!src_buf || !dst_buf)) | ||||||
|  | +	if (WARN_ON(!src_buf)) | ||||||
|  |  		goto unlock; | ||||||
|  |  	v4l2_m2m_buf_done(src_buf, state); | ||||||
|  | -	dst_buf->is_held = src_buf->flags & V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF; | ||||||
|  | -	if (!dst_buf->is_held) { | ||||||
|  | -		v4l2_m2m_dst_buf_remove(m2m_ctx); | ||||||
|  | -		v4l2_m2m_buf_done(dst_buf, state); | ||||||
|  | + | ||||||
|  | +	if (!m2m_ctx->cap_detached) { | ||||||
|  | +		dst_buf = v4l2_m2m_next_dst_buf(m2m_ctx); | ||||||
|  | +		if (WARN_ON(!dst_buf)) | ||||||
|  | +			goto unlock; | ||||||
|  | + | ||||||
|  | +		dst_buf->is_held = src_buf->flags | ||||||
|  | +				    & V4L2_BUF_FLAG_M2M_HOLD_CAPTURE_BUF; | ||||||
|  | + | ||||||
|  | +		if (!dst_buf->is_held) { | ||||||
|  | +			dst_buf = _v4l2_m2m_cap_buf_detach(m2m_ctx); | ||||||
|  | +			_v4l2_m2m_cap_buf_return(m2m_ctx, dst_buf, state); | ||||||
|  | +		} | ||||||
|  |  	} | ||||||
|  |  	schedule_next = _v4l2_m2m_job_finish(m2m_dev, m2m_ctx); | ||||||
|  |  unlock: | ||||||
|  | @@ -983,12 +1074,14 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(s | ||||||
|  |  	m2m_ctx->priv = drv_priv; | ||||||
|  |  	m2m_ctx->m2m_dev = m2m_dev; | ||||||
|  |  	init_waitqueue_head(&m2m_ctx->finished); | ||||||
|  | +	init_waitqueue_head(&m2m_ctx->det_empty); | ||||||
|  |   | ||||||
|  |  	out_q_ctx = &m2m_ctx->out_q_ctx; | ||||||
|  |  	cap_q_ctx = &m2m_ctx->cap_q_ctx; | ||||||
|  |   | ||||||
|  |  	INIT_LIST_HEAD(&out_q_ctx->rdy_queue); | ||||||
|  |  	INIT_LIST_HEAD(&cap_q_ctx->rdy_queue); | ||||||
|  | +	INIT_LIST_HEAD(&m2m_ctx->det_list); | ||||||
|  |  	spin_lock_init(&out_q_ctx->rdy_spinlock); | ||||||
|  |  	spin_lock_init(&cap_q_ctx->rdy_spinlock); | ||||||
|  |   | ||||||
|  | --- a/include/media/v4l2-mem2mem.h | ||||||
|  | +++ b/include/media/v4l2-mem2mem.h | ||||||
|  | @@ -88,6 +88,9 @@ struct v4l2_m2m_queue_ctx { | ||||||
|  |   *		%TRANS_QUEUED, %TRANS_RUNNING and %TRANS_ABORT. | ||||||
|  |   * @finished: Wait queue used to signalize when a job queue finished. | ||||||
|  |   * @priv: Instance private data | ||||||
|  | + * @cap_detached: Current job's capture buffer has been detached | ||||||
|  | + * @det_list: List of detached (post-job but still in flight) capture buffers | ||||||
|  | + * @det_empty: Wait queue signalled when det_list goes empty | ||||||
|  |   * | ||||||
|  |   * The memory to memory context is specific to a file handle, NOT to e.g. | ||||||
|  |   * a device. | ||||||
|  | @@ -111,6 +114,11 @@ struct v4l2_m2m_ctx { | ||||||
|  |  	wait_queue_head_t		finished; | ||||||
|  |   | ||||||
|  |  	void				*priv; | ||||||
|  | + | ||||||
|  | +	/* Detached buffer handling */ | ||||||
|  | +	bool	cap_detached; | ||||||
|  | +	struct list_head		det_list; | ||||||
|  | +	wait_queue_head_t		det_empty; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  /** | ||||||
|  | @@ -216,6 +224,45 @@ v4l2_m2m_buf_done(struct vb2_v4l2_buffer | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  /** | ||||||
|  | + * v4l2_m2m_cap_buf_detach() - detach the capture buffer from the job and | ||||||
|  | + * return it. | ||||||
|  | + * | ||||||
|  | + * @m2m_dev: opaque pointer to the internal data to handle M2M context | ||||||
|  | + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx | ||||||
|  | + * | ||||||
|  | + * This function is designed to be used in conjunction with | ||||||
|  | + * v4l2_m2m_buf_done_and_job_finish(). It allows the next job to start | ||||||
|  | + * execution before the capture buffer is returned to the user which can be | ||||||
|  | + * important if the underlying processing has multiple phases that are more | ||||||
|  | + * efficiently executed in parallel. | ||||||
|  | + * | ||||||
|  | + * If used then it must be called before v4l2_m2m_buf_done_and_job_finish() | ||||||
|  | + * as otherwise the buffer will have already gone. | ||||||
|  | + * | ||||||
|  | + * It is the callers reponsibilty to ensure that all detached buffers are | ||||||
|  | + * returned. | ||||||
|  | + */ | ||||||
|  | +struct vb2_v4l2_buffer *v4l2_m2m_cap_buf_detach(struct v4l2_m2m_dev *m2m_dev, | ||||||
|  | +						struct v4l2_m2m_ctx *m2m_ctx); | ||||||
|  | + | ||||||
|  | +/** | ||||||
|  | + * v4l2_m2m_cap_buf_return() - return a capture buffer, previously detached | ||||||
|  | + * with v4l2_m2m_cap_buf_detach() to the user. | ||||||
|  | + * | ||||||
|  | + * @m2m_dev: opaque pointer to the internal data to handle M2M context | ||||||
|  | + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx | ||||||
|  | + * @buf: the buffer to return | ||||||
|  | + * @state: vb2 buffer state passed to v4l2_m2m_buf_done(). | ||||||
|  | + * | ||||||
|  | + * Buffers returned by this function will be returned to the user in the order | ||||||
|  | + * of the original jobs rather than the order in which this function is called. | ||||||
|  | + */ | ||||||
|  | +void v4l2_m2m_cap_buf_return(struct v4l2_m2m_dev *m2m_dev, | ||||||
|  | +			     struct v4l2_m2m_ctx *m2m_ctx, | ||||||
|  | +			     struct vb2_v4l2_buffer *buf, | ||||||
|  | +			     enum vb2_buffer_state state); | ||||||
|  | + | ||||||
|  | +/** | ||||||
|  |   * v4l2_m2m_reqbufs() - multi-queue-aware REQBUFS multiplexer | ||||||
|  |   * | ||||||
|  |   * @file: pointer to struct &file | ||||||
|  | --- a/include/media/videobuf2-v4l2.h | ||||||
|  | +++ b/include/media/videobuf2-v4l2.h | ||||||
|  | @@ -35,6 +35,8 @@ | ||||||
|  |   * @request_fd:	the request_fd associated with this buffer | ||||||
|  |   * @is_held:	if true, then this capture buffer was held | ||||||
|  |   * @planes:	plane information (userptr/fd, length, bytesused, data_offset). | ||||||
|  | + * @det_state:	if a detached request capture buffer then this contains its | ||||||
|  | + *		current state | ||||||
|  |   * | ||||||
|  |   * Should contain enough information to be able to cover all the fields | ||||||
|  |   * of &struct v4l2_buffer at ``videodev2.h``. | ||||||
|  | @@ -49,6 +51,7 @@ struct vb2_v4l2_buffer { | ||||||
|  |  	__s32			request_fd; | ||||||
|  |  	bool			is_held; | ||||||
|  |  	struct vb2_plane	planes[VB2_MAX_PLANES]; | ||||||
|  | +	enum vb2_buffer_state	det_state; | ||||||
|  |  }; | ||||||
|  |   | ||||||
|  |  /* VB2 V4L2 flags as set in vb2_queue.subsystem_flags */ | ||||||
| @@ -0,0 +1,106 @@ | |||||||
|  | From 15b4e8fa2d5101b989856c42cdae6ec764c99db0 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Dave Stevenson <dave.stevenson@raspberrypi.com> | ||||||
|  | Date: Tue, 17 Mar 2020 10:53:16 +0000 | ||||||
|  | Subject: [PATCH] media: dt-bindings: media: Add binding for the | ||||||
|  |  Raspberry PI HEVC decoder | ||||||
|  |  | ||||||
|  | Adds a binding for the HEVC decoder found on the BCM2711 / Raspberry Pi 4. | ||||||
|  |  | ||||||
|  | Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> | ||||||
|  | --- | ||||||
|  |  .../bindings/media/rpivid_hevc.yaml           | 72 +++++++++++++++++++ | ||||||
|  |  MAINTAINERS                                   |  7 ++ | ||||||
|  |  2 files changed, 79 insertions(+) | ||||||
|  |  create mode 100644 Documentation/devicetree/bindings/media/rpivid_hevc.yaml | ||||||
|  |  | ||||||
|  | --- /dev/null | ||||||
|  | +++ b/Documentation/devicetree/bindings/media/rpivid_hevc.yaml | ||||||
|  | @@ -0,0 +1,72 @@ | ||||||
|  | +# SPDX-License-Identifier: GPL-2.0-only | ||||||
|  | +%YAML 1.2 | ||||||
|  | +--- | ||||||
|  | +$id: http://devicetree.org/schemas/media/rpivid_hevc.yaml# | ||||||
|  | +$schema: http://devicetree.org/meta-schemas/core.yaml# | ||||||
|  | + | ||||||
|  | +title: Raspberry Pi HEVC Decoder | ||||||
|  | + | ||||||
|  | +maintainers: | ||||||
|  | +  - Raspberry Pi <kernel-list@raspberrypi.com> | ||||||
|  | + | ||||||
|  | +description: |- | ||||||
|  | +  The Camera Adaptation Layer (CAL) is a key component for image capture | ||||||
|  | +  applications. The capture module provides the system interface and the | ||||||
|  | +  processing capability to connect CSI2 image-sensor modules to the | ||||||
|  | +  DRA72x device. | ||||||
|  | + | ||||||
|  | +properties: | ||||||
|  | +  compatible: | ||||||
|  | +    enum: | ||||||
|  | +      - raspberrypi,rpivid-vid-decoder | ||||||
|  | + | ||||||
|  | +  reg: | ||||||
|  | +    minItems: 2 | ||||||
|  | +    items: | ||||||
|  | +      - description: The HEVC main register region | ||||||
|  | +      - description: The Interrupt controller register region | ||||||
|  | + | ||||||
|  | +  reg-names: | ||||||
|  | +    minItems: 2 | ||||||
|  | +    items: | ||||||
|  | +      - const: hevc | ||||||
|  | +      - const: intc | ||||||
|  | + | ||||||
|  | +  interrupts: | ||||||
|  | +    maxItems: 1 | ||||||
|  | + | ||||||
|  | +  clocks: | ||||||
|  | +    items: | ||||||
|  | +      - description: The HEVC block clock | ||||||
|  | + | ||||||
|  | +  clock-names: | ||||||
|  | +    items: | ||||||
|  | +      - const: hevc | ||||||
|  | + | ||||||
|  | +required: | ||||||
|  | +  - compatible | ||||||
|  | +  - reg | ||||||
|  | +  - reg-names | ||||||
|  | +  - interrupts | ||||||
|  | +  - clocks | ||||||
|  | + | ||||||
|  | +additionalProperties: false | ||||||
|  | + | ||||||
|  | +examples: | ||||||
|  | +  - | | ||||||
|  | +    #include <dt-bindings/interrupt-controller/arm-gic.h> | ||||||
|  | + | ||||||
|  | +    video-codec@7eb10000 { | ||||||
|  | +        compatible = "raspberrypi,rpivid-vid-decoder"; | ||||||
|  | +        reg = <0x0 0x7eb10000 0x1000>,	/* INTC */ | ||||||
|  | +              <0x0 0x7eb00000 0x10000>; /* HEVC */ | ||||||
|  | +        reg-names = "intc", | ||||||
|  | +                    "hevc"; | ||||||
|  | + | ||||||
|  | +        interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; | ||||||
|  | + | ||||||
|  | +        clocks = <&clk 0>; | ||||||
|  | +        clock-names = "hevc"; | ||||||
|  | +    }; | ||||||
|  | + | ||||||
|  | +... | ||||||
|  | --- a/MAINTAINERS | ||||||
|  | +++ b/MAINTAINERS | ||||||
|  | @@ -3198,6 +3198,13 @@ N:	bcm2711 | ||||||
|  |  N:	bcm2835 | ||||||
|  |  F:	drivers/staging/vc04_services | ||||||
|  |   | ||||||
|  | +BROADCOM BCM2711 HEVC DECODER | ||||||
|  | +M:	Raspberry Pi Kernel Maintenance <kernel-list@raspberrypi.com> | ||||||
|  | +L:	linux-media@vger.kernel.org | ||||||
|  | +S:	Maintained | ||||||
|  | +F:	Documentation/devicetree/bindings/media/rpivid_hevc.jaml | ||||||
|  | +F:	drivers/staging/media/rpivid | ||||||
|  | + | ||||||
|  |  BROADCOM BCM2835 CAMERA DRIVER | ||||||
|  |  M:	Dave Stevenson <dave.stevenson@raspberrypi.org> | ||||||
|  |  L:	linux-media@vger.kernel.org | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -0,0 +1,102 @@ | |||||||
|  | From b1d6499e00b6061ecc7061335199acf86f54d31a Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Dave Stevenson <dave.stevenson@raspberrypi.com> | ||||||
|  | Date: Fri, 13 Mar 2020 16:52:55 +0000 | ||||||
|  | Subject: [PATCH] dtoverlays: Add overlay to enable the HEVC V4L2 | ||||||
|  |  driver | ||||||
|  |  | ||||||
|  | This replaces the rpivid_mem register mapping driver. | ||||||
|  | When the driver is complete, these DT changes should be | ||||||
|  | merged into the base DT instead of being an overlay. | ||||||
|  |  | ||||||
|  | Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> | ||||||
|  | --- | ||||||
|  |  arch/arm/boot/dts/overlays/Makefile           |  1 + | ||||||
|  |  arch/arm/boot/dts/overlays/README             |  7 +++ | ||||||
|  |  .../boot/dts/overlays/rpivid-v4l2-overlay.dts | 55 +++++++++++++++++++ | ||||||
|  |  4 files changed, 63 insertions(+), 2 deletions(-) | ||||||
|  |  create mode 100644 arch/arm/boot/dts/overlays/rpivid-v4l2-overlay.dts | ||||||
|  |  | ||||||
|  | --- a/arch/arm/boot/dts/overlays/Makefile | ||||||
|  | +++ b/arch/arm/boot/dts/overlays/Makefile | ||||||
|  | @@ -140,6 +140,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ | ||||||
|  |  	rpi-proto.dtbo \ | ||||||
|  |  	rpi-sense.dtbo \ | ||||||
|  |  	rpi-tv.dtbo \ | ||||||
|  | +	rpivid-v4l2.dtbo \ | ||||||
|  |  	rra-digidac1-wm8741-audio.dtbo \ | ||||||
|  |  	sc16is750-i2c.dtbo \ | ||||||
|  |  	sc16is752-i2c.dtbo \ | ||||||
|  | --- a/arch/arm/boot/dts/overlays/README | ||||||
|  | +++ b/arch/arm/boot/dts/overlays/README | ||||||
|  | @@ -2064,6 +2064,13 @@ Load:   dtoverlay=rpi-tv | ||||||
|  |  Params: <None> | ||||||
|  |   | ||||||
|  |   | ||||||
|  | +Name:   rpivid-v4l2 | ||||||
|  | +Info:   Load the V4L2 stateless video decoder driver for the HEVC block, | ||||||
|  | +        disabling the memory mapped devices in the process. | ||||||
|  | +Load:   dtoverlay=rpivid-v4l2 | ||||||
|  | +Params: <None> | ||||||
|  | + | ||||||
|  | + | ||||||
|  |  Name:   rra-digidac1-wm8741-audio | ||||||
|  |  Info:   Configures the Red Rocks Audio DigiDAC1 soundcard | ||||||
|  |  Load:   dtoverlay=rra-digidac1-wm8741-audio | ||||||
|  | --- /dev/null | ||||||
|  | +++ b/arch/arm/boot/dts/overlays/rpivid-v4l2-overlay.dts | ||||||
|  | @@ -0,0 +1,55 @@ | ||||||
|  | +// SPDX-License-Identifier: GPL-2.0-only | ||||||
|  | +// Definitions for Raspberry Pi video decode engine | ||||||
|  | +/dts-v1/; | ||||||
|  | +/plugin/; | ||||||
|  | + | ||||||
|  | +#include <dt-bindings/interrupt-controller/arm-gic.h> | ||||||
|  | + | ||||||
|  | +/{ | ||||||
|  | +	compatible = "brcm,bcm2711"; | ||||||
|  | + | ||||||
|  | +	fragment@0 { | ||||||
|  | +		target = <&scb>; | ||||||
|  | +		__overlay__ { | ||||||
|  | +			/* needed to avoid dtc warning */ | ||||||
|  | +			#address-cells = <2>; | ||||||
|  | +			#size-cells = <1>; | ||||||
|  | +			codec@7eb10000 { | ||||||
|  | +				compatible = "raspberrypi,rpivid-vid-decoder"; | ||||||
|  | +				reg = <0x0 0x7eb10000 0x1000>,	/* INTC */ | ||||||
|  | +				      <0x0 0x7eb00000 0x10000>; /* HEVC */ | ||||||
|  | +				reg-names = "intc", | ||||||
|  | +					    "hevc"; | ||||||
|  | + | ||||||
|  | +				interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; | ||||||
|  | + | ||||||
|  | +				clocks = <&hevc_clk>; | ||||||
|  | +				clock-names = "hevc"; | ||||||
|  | + | ||||||
|  | +				hevc_clk: hevc_clk { | ||||||
|  | +					compatible = "fixed-clock"; | ||||||
|  | +					#clock-cells = <0>; | ||||||
|  | +					clock-frequency = <500000000>; | ||||||
|  | +				}; | ||||||
|  | +			}; | ||||||
|  | +		}; | ||||||
|  | +	}; | ||||||
|  | + | ||||||
|  | +	fragment@1 { | ||||||
|  | +		target = <&scb>; | ||||||
|  | +		__overlay__ { | ||||||
|  | +			hevc-decoder@7eb00000 { | ||||||
|  | +				status = "disabled"; | ||||||
|  | +			}; | ||||||
|  | +			rpivid-local-intc@7eb10000 { | ||||||
|  | +				status = "disabled"; | ||||||
|  | +			}; | ||||||
|  | +			h264-decoder@7eb20000 { | ||||||
|  | +				status = "disabled"; | ||||||
|  | +			}; | ||||||
|  | +			vp9-decoder@7eb30000 { | ||||||
|  | +				status = "disabled"; | ||||||
|  | +			}; | ||||||
|  | +		}; | ||||||
|  | +	}; | ||||||
|  | +}; | ||||||
		Reference in New Issue
	
	Block a user
	 Álvaro Fernández Rojas
					Álvaro Fernández Rojas