diff options
Diffstat (limited to 'users/flokli')
-rw-r--r-- | users/flokli/ipu6-softisp/README.md | 5 | ||||
-rw-r--r-- | users/flokli/ipu6-softisp/kernel/softisp.patch | 3006 |
2 files changed, 1974 insertions, 1037 deletions
diff --git a/users/flokli/ipu6-softisp/README.md b/users/flokli/ipu6-softisp/README.md index 9c09e9a158e4..2ab727ace44f 100644 --- a/users/flokli/ipu6-softisp/README.md +++ b/users/flokli/ipu6-softisp/README.md @@ -5,7 +5,7 @@ https://copr.fedorainfracloud.org/coprs/jwrdegoede/ipu6-softisp/. It's supposed to be included in your NixOS configuration imports, and will: - - Add some patches to your kernel, which should apply on 6.7.x + - Add some patches to your kernel, which should apply on 6.8.x - Add the `ipu6-camera-bins` firmware (still needed) - Enable some kernel config options - Add an udev rule so libcamera can do DMABUF things @@ -16,6 +16,9 @@ It's supposed to be included in your NixOS configuration imports, and will: Please make sure you don't have any of the `hardware.ipu6` options still enabled, as they use the closed-source userspace stack and will conflict. +Also make sure to track nixos-unstable for this. This code will get periodically +updated to be compatible with nixos-unstable! + The testing instructions from https://copr.fedorainfracloud.org/coprs/jwrdegoede/ipu6-softisp/ still apply. diff --git a/users/flokli/ipu6-softisp/kernel/softisp.patch b/users/flokli/ipu6-softisp/kernel/softisp.patch index eb0b00564810..8731ed914c1d 100644 --- a/users/flokli/ipu6-softisp/kernel/softisp.patch +++ b/users/flokli/ipu6-softisp/kernel/softisp.patch @@ -1,7 +1,1112 @@ -From 4e34bb68beec288e6fbc71170ff6d3ed39b76ce6 Mon Sep 17 00:00:00 2001 +From 037f05a9772f3243907bb826e913971ee20e9487 Mon Sep 17 00:00:00 2001 +From: Sakari Ailus <sakari.ailus@linux.intel.com> +Date: Tue, 8 Aug 2023 10:55:31 +0300 +Subject: [PATCH 01/33] media: mc: Add INTERNAL pad flag + +Internal source pads will be used as routing endpoints in V4L2 +[GS]_ROUTING IOCTLs, to indicate that the stream begins in the entity. + +Also prevent creating links to pads that have been flagged as internal. + +Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> +--- + Documentation/userspace-api/media/glossary.rst | 6 ++++++ + Documentation/userspace-api/media/mediactl/media-types.rst | 6 ++++++ + drivers/media/mc/mc-entity.c | 6 +++++- + include/uapi/linux/media.h | 1 + + 4 files changed, 18 insertions(+), 1 deletion(-) + +diff --git a/Documentation/userspace-api/media/glossary.rst b/Documentation/userspace-api/media/glossary.rst +index 96a360edbf3b..f7b99a4527c7 100644 +--- a/Documentation/userspace-api/media/glossary.rst ++++ b/Documentation/userspace-api/media/glossary.rst +@@ -173,6 +173,12 @@ Glossary + An integrated circuit that integrates all components of a computer + or other electronic systems. + ++_media-glossary-stream: ++ Stream ++ A distinct flow of data (image data or metadata) over a media pipeline ++ from source to sink. A source may be e.g. an image sensor and a sink ++ e.g. a memory buffer. ++ + V4L2 API + **V4L2 userspace API** + +diff --git a/Documentation/userspace-api/media/mediactl/media-types.rst b/Documentation/userspace-api/media/mediactl/media-types.rst +index 0ffeece1e0c8..28941da27790 100644 +--- a/Documentation/userspace-api/media/mediactl/media-types.rst ++++ b/Documentation/userspace-api/media/mediactl/media-types.rst +@@ -361,6 +361,7 @@ Types and flags used to represent the media graph elements + .. _MEDIA-PAD-FL-SINK: + .. _MEDIA-PAD-FL-SOURCE: + .. _MEDIA-PAD-FL-MUST-CONNECT: ++.. _MEDIA-PAD-FL-INTERNAL: + + .. flat-table:: Media pad flags + :header-rows: 0 +@@ -382,6 +383,11 @@ Types and flags used to represent the media graph elements + when this flag isn't set; the absence of the flag doesn't imply + there is none. + ++ * - ``MEDIA_PAD_FL_INTERNAL`` ++ - The internal flag indicates an internal pad that has no external ++ connections. Such a pad shall not be connected with a link. The ++ internal flag indicates that the :ref:``stream ++ <media-glossary-stream>`` either starts or ends in the entity. + + One and only one of ``MEDIA_PAD_FL_SINK`` and ``MEDIA_PAD_FL_SOURCE`` + must be set for every pad. +diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c +index 543a392f8635..1fc80fd3e5e3 100644 +--- a/drivers/media/mc/mc-entity.c ++++ b/drivers/media/mc/mc-entity.c +@@ -1075,7 +1075,8 @@ int media_get_pad_index(struct media_entity *entity, u32 pad_type, + + for (i = 0; i < entity->num_pads; i++) { + if ((entity->pads[i].flags & +- (MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_SOURCE)) != pad_type) ++ (MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_SOURCE | ++ MEDIA_PAD_FL_INTERNAL)) != pad_type) + continue; + + if (entity->pads[i].sig_type == sig_type) +@@ -1098,6 +1099,9 @@ media_create_pad_link(struct media_entity *source, u16 source_pad, + return -EINVAL; + if (WARN_ON(!(source->pads[source_pad].flags & MEDIA_PAD_FL_SOURCE))) + return -EINVAL; ++ if (WARN_ON(source->pads[source_pad].flags & MEDIA_PAD_FL_SOURCE && ++ source->pads[source_pad].flags & MEDIA_PAD_FL_INTERNAL)) ++ return -EINVAL; + if (WARN_ON(!(sink->pads[sink_pad].flags & MEDIA_PAD_FL_SINK))) + return -EINVAL; + +diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h +index 1c80b1d6bbaf..80cfd12a43fc 100644 +--- a/include/uapi/linux/media.h ++++ b/include/uapi/linux/media.h +@@ -208,6 +208,7 @@ struct media_entity_desc { + #define MEDIA_PAD_FL_SINK (1U << 0) + #define MEDIA_PAD_FL_SOURCE (1U << 1) + #define MEDIA_PAD_FL_MUST_CONNECT (1U << 2) ++#define MEDIA_PAD_FL_INTERNAL (1U << 3) + + struct media_pad_desc { + __u32 entity; /* entity ID */ +-- +2.43.2 + + +From 5f0cdae874f1c0237936c2c12a9fc019b93de4c9 Mon Sep 17 00:00:00 2001 +From: Sakari Ailus <sakari.ailus@linux.intel.com> +Date: Tue, 8 Aug 2023 10:55:32 +0300 +Subject: [PATCH 02/33] media: uapi: Add generic serial metadata mbus formats + +Add generic serial metadata mbus formats. These formats describe data +width and packing but not the content itself. The reason for specifying +such formats is that the formats as such are fairly device specific but +they are still handled by CSI-2 receiver drivers that should not be aware +of device specific formats. What makes generic metadata formats possible +is that these formats are parsed by software only, after capturing the +data to system memory. + +Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> +--- + .../media/v4l/subdev-formats.rst | 257 ++++++++++++++++++ + include/uapi/linux/media-bus-format.h | 9 + + 2 files changed, 266 insertions(+) + +diff --git a/Documentation/userspace-api/media/v4l/subdev-formats.rst b/Documentation/userspace-api/media/v4l/subdev-formats.rst +index eb3cd20b0cf2..7d107873cddd 100644 +--- a/Documentation/userspace-api/media/v4l/subdev-formats.rst ++++ b/Documentation/userspace-api/media/v4l/subdev-formats.rst +@@ -8306,3 +8306,260 @@ The following table lists the existing metadata formats. + both sides of the link and the bus format is a fixed + metadata format that is not configurable from userspace. + Width and height will be set to 0 for this format. ++ ++Generic Serial Metadata Formats ++^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ++ ++Generic serial metadata formats are used on serial busses where the actual data ++content is more or less device specific but the data is transmitted and received ++by multiple devices that do not process the data in any way, simply writing ++it to system memory for processing in software at the end of the pipeline. ++ ++The more specific variant describing the actual data is used on the internal ++source pad of the originating sub-device. ++ ++"b" in an array cell signifies a byte of data, followed by the number of byte ++and finally the bit number in subscript. "p" indicates a padding bit. ++ ++.. _media-bus-format-generic-meta: ++ ++.. cssclass: longtable ++ ++.. flat-table:: Generic Serial Metadata Formats ++ :header-rows: 2 ++ :stub-columns: 0 ++ ++ * - Identifier ++ - Code ++ - ++ - :cspan:`23` Data organization ++ * - ++ - ++ - Bit ++ - 23 ++ - 22 ++ - 21 ++ - 20 ++ - 19 ++ - 18 ++ - 17 ++ - 16 ++ - 15 ++ - 14 ++ - 13 ++ - 12 ++ - 11 ++ - 10 ++ - 9 ++ - 8 ++ - 7 ++ - 6 ++ - 5 ++ - 4 ++ - 3 ++ - 2 ++ - 1 ++ - 0 ++ * .. _MEDIA-BUS-FMT-META-8: ++ ++ - MEDIA_BUS_FMT_META_8 ++ - 0x8001 ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - b0\ :sub:`7` ++ - b0\ :sub:`6` ++ - b0\ :sub:`5` ++ - b0\ :sub:`4` ++ - b0\ :sub:`3` ++ - b0\ :sub:`2` ++ - b0\ :sub:`1` ++ - b0\ :sub:`0` ++ * .. _MEDIA-BUS-FMT-META-10: ++ ++ - MEDIA_BUS_FMT_META_10 ++ - 0x8002 ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - b0\ :sub:`7` ++ - b0\ :sub:`6` ++ - b0\ :sub:`5` ++ - b0\ :sub:`4` ++ - b0\ :sub:`3` ++ - b0\ :sub:`2` ++ - b0\ :sub:`1` ++ - b0\ :sub:`0` ++ - p ++ - p ++ * .. _MEDIA-BUS-FMT-META-12: ++ ++ - MEDIA_BUS_FMT_META_12 ++ - 0x8003 ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - b0\ :sub:`7` ++ - b0\ :sub:`6` ++ - b0\ :sub:`5` ++ - b0\ :sub:`4` ++ - b0\ :sub:`3` ++ - b0\ :sub:`2` ++ - b0\ :sub:`1` ++ - b0\ :sub:`0` ++ - p ++ - p ++ - p ++ - p ++ * .. _MEDIA-BUS-FMT-META-14: ++ ++ - MEDIA_BUS_FMT_META_14 ++ - 0x8004 ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - b0\ :sub:`7` ++ - b0\ :sub:`6` ++ - b0\ :sub:`5` ++ - b0\ :sub:`4` ++ - b0\ :sub:`3` ++ - b0\ :sub:`2` ++ - b0\ :sub:`1` ++ - b0\ :sub:`0` ++ - p ++ - p ++ - p ++ - p ++ - p ++ - p ++ * .. _MEDIA-BUS-FMT-META-16: ++ ++ - MEDIA_BUS_FMT_META_16 ++ - 0x8005 ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - ++ - b0\ :sub:`7` ++ - b0\ :sub:`6` ++ - b0\ :sub:`5` ++ - b0\ :sub:`4` ++ - b0\ :sub:`3` ++ - b0\ :sub:`2` ++ - b0\ :sub:`1` ++ - b0\ :sub:`0` ++ - p ++ - p ++ - p ++ - p ++ - p ++ - p ++ - p ++ - p ++ * .. _MEDIA-BUS-FMT-META-20: ++ ++ - MEDIA_BUS_FMT_META_20 ++ - 0x8007 ++ - ++ - ++ - ++ - ++ - ++ - b0\ :sub:`7` ++ - b0\ :sub:`6` ++ - b0\ :sub:`5` ++ - b0\ :sub:`4` ++ - b0\ :sub:`3` ++ - b0\ :sub:`2` ++ - b0\ :sub:`1` ++ - b0\ :sub:`0` ++ - p ++ - p ++ - p ++ - p ++ - p ++ - p ++ - p ++ - p ++ - p ++ - p ++ - p ++ - p ++ * .. _MEDIA-BUS-FMT-META-24: ++ ++ - MEDIA_BUS_FMT_META_24 ++ - 0x8009 ++ - ++ - b0\ :sub:`7` ++ - b0\ :sub:`6` ++ - b0\ :sub:`5` ++ - b0\ :sub:`4` ++ - b0\ :sub:`3` ++ - b0\ :sub:`2` ++ - b0\ :sub:`1` ++ - b0\ :sub:`0` ++ - p ++ - p ++ - p ++ - p ++ - p ++ - p ++ - p ++ - p ++ - p ++ - p ++ - p ++ - p ++ - p ++ - p ++ - p ++ - p +diff --git a/include/uapi/linux/media-bus-format.h b/include/uapi/linux/media-bus-format.h +index f05f747e444d..d4c1d991014b 100644 +--- a/include/uapi/linux/media-bus-format.h ++++ b/include/uapi/linux/media-bus-format.h +@@ -174,4 +174,13 @@ + */ + #define MEDIA_BUS_FMT_METADATA_FIXED 0x7001 + ++/* Generic line based metadata formats for serial buses. Next is 0x8008. */ ++#define MEDIA_BUS_FMT_META_8 0x8001 ++#define MEDIA_BUS_FMT_META_10 0x8002 ++#define MEDIA_BUS_FMT_META_12 0x8003 ++#define MEDIA_BUS_FMT_META_14 0x8004 ++#define MEDIA_BUS_FMT_META_16 0x8005 ++#define MEDIA_BUS_FMT_META_20 0x8006 ++#define MEDIA_BUS_FMT_META_24 0x8007 ++ + #endif /* __LINUX_MEDIA_BUS_FORMAT_H */ +-- +2.43.2 + + +From 8af4eeaee34159605ec86b57fa638a82fd968f31 Mon Sep 17 00:00:00 2001 +From: Sakari Ailus <sakari.ailus@linux.intel.com> +Date: Tue, 8 Aug 2023 10:55:33 +0300 +Subject: [PATCH 03/33] media: uapi: Document which mbus format fields are + valid for metadata + +Now that metadata mbus formats have been added, it is necessary to define +which fields in struct v4l2_mbus_format are applicable to them (not many). + +Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> +--- + include/uapi/linux/v4l2-mediabus.h | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +diff --git a/include/uapi/linux/v4l2-mediabus.h b/include/uapi/linux/v4l2-mediabus.h +index 6b07b73473b5..3cadb3b58b85 100644 +--- a/include/uapi/linux/v4l2-mediabus.h ++++ b/include/uapi/linux/v4l2-mediabus.h +@@ -19,12 +19,18 @@ + * @width: image width + * @height: image height + * @code: data format code (from enum v4l2_mbus_pixelcode) +- * @field: used interlacing type (from enum v4l2_field) +- * @colorspace: colorspace of the data (from enum v4l2_colorspace) +- * @ycbcr_enc: YCbCr encoding of the data (from enum v4l2_ycbcr_encoding) +- * @hsv_enc: HSV encoding of the data (from enum v4l2_hsv_encoding) +- * @quantization: quantization of the data (from enum v4l2_quantization) +- * @xfer_func: transfer function of the data (from enum v4l2_xfer_func) ++ * @field: used interlacing type (from enum v4l2_field), not applicable ++ * to metadata mbus codes ++ * @colorspace: colorspace of the data (from enum v4l2_colorspace), zero on ++ * metadata mbus codes ++ * @ycbcr_enc: YCbCr encoding of the data (from enum v4l2_ycbcr_encoding), zero ++ * on metadata mbus codes ++ * @hsv_enc: HSV encoding of the data (from enum v4l2_hsv_encoding), zero on ++ * metadata mbus codes ++ * @quantization: quantization of the data (from enum v4l2_quantization), zero ++ * on metadata mbus codes ++ * @xfer_func: transfer function of the data (from enum v4l2_xfer_func), zero ++ * on metadata mbus codes + * @flags: flags (V4L2_MBUS_FRAMEFMT_*) + * @reserved: reserved bytes that can be later used + */ +-- +2.43.2 + + +From ed5884d40def9adfa77841427e52733746158a77 Mon Sep 17 00:00:00 2001 +From: Sakari Ailus <sakari.ailus@linux.intel.com> +Date: Tue, 8 Aug 2023 10:55:34 +0300 +Subject: [PATCH 04/33] media: uapi: Add a macro to tell whether an mbus code + is metadata + +Add a macro to tell whether a given mbus code is metadata. + +Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> +--- + include/uapi/linux/media-bus-format.h | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/include/uapi/linux/media-bus-format.h b/include/uapi/linux/media-bus-format.h +index d4c1d991014b..6fcd7d276bc6 100644 +--- a/include/uapi/linux/media-bus-format.h ++++ b/include/uapi/linux/media-bus-format.h +@@ -183,4 +183,7 @@ + #define MEDIA_BUS_FMT_META_20 0x8006 + #define MEDIA_BUS_FMT_META_24 0x8007 + ++#define MEDIA_BUS_FMT_IS_META(code) \ ++ ((code) & 0xf000 == 0x7000 || (code) & 0xf000 == 0x8000) ++ + #endif /* __LINUX_MEDIA_BUS_FORMAT_H */ +-- +2.43.2 + + +From c0e682a815c5baf012c8963968385c197e7e0943 Mon Sep 17 00:00:00 2001 +From: Sakari Ailus <sakari.ailus@linux.intel.com> +Date: Tue, 8 Aug 2023 10:55:35 +0300 +Subject: [PATCH 05/33] media: uapi: Add generic 8-bit metadata format + definitions + +Generic 8-bit metadata formats define the in-memory data layout but not +the format of the data itself. The reasoning for having such formats is to +allow CSI-2 receiver drivers to receive and DMA drivers to write the data +to memory without knowing a large number of device specific formats. + +These formats may be used only in conjunction of a Media controller +pipeline where the internal pad of the source sub-device defines the +specific format of the data (using an mbus code). + +Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> +--- + .../userspace-api/media/v4l/meta-formats.rst | 1 + + .../media/v4l/metafmt-generic.rst | 331 ++++++++++++++++++ + drivers/media/v4l2-core/v4l2-ioctl.c | 8 + + include/uapi/linux/videodev2.h | 9 + + 4 files changed, 349 insertions(+) + create mode 100644 Documentation/userspace-api/media/v4l/metafmt-generic.rst + +diff --git a/Documentation/userspace-api/media/v4l/meta-formats.rst b/Documentation/userspace-api/media/v4l/meta-formats.rst +index 0bb61fc5bc00..919f595576b9 100644 +--- a/Documentation/userspace-api/media/v4l/meta-formats.rst ++++ b/Documentation/userspace-api/media/v4l/meta-formats.rst +@@ -19,3 +19,4 @@ These formats are used for the :ref:`metadata` interface only. + metafmt-vsp1-hgo + metafmt-vsp1-hgt + metafmt-vivid ++ metafmt-generic +diff --git a/Documentation/userspace-api/media/v4l/metafmt-generic.rst b/Documentation/userspace-api/media/v4l/metafmt-generic.rst +new file mode 100644 +index 000000000000..a27bfc721edf +--- /dev/null ++++ b/Documentation/userspace-api/media/v4l/metafmt-generic.rst +@@ -0,0 +1,331 @@ ++.. SPDX-License-Identifier: GPL-2.0 OR GFDL-1.1-no-invariants-or-later ++ ++************************************************************************************************************************************************************************************************************************************************************************************************************************** ++V4L2_META_FMT_GENERIC_8 ('MET8'), V4L2_META_FMT_GENERIC_CSI2_10 ('MC1A'), V4L2_META_FMT_GENERIC_CSI2_12 ('MC1C'), V4L2_META_FMT_GENERIC_CSI2_14 ('MC1E'), V4L2_META_FMT_GENERIC_CSI2_16 ('MC1G'), V4L2_META_FMT_GENERIC_CSI2_20 ('MC1K'), V4L2_META_FMT_GENERIC_CSI2_24 ('MC1O'), V4L2_META_FMT_GENERIC_CSI2_2_24 ('MC2O') ++************************************************************************************************************************************************************************************************************************************************************************************************************************** ++ ++ ++Generic line-based metadata formats ++ ++ ++Description ++=========== ++ ++These generic line-based metadata formats define the memory layout of the data ++without defining the format or meaning of the metadata itself. These formats may ++only be used with a Media controller pipeline where the more specific format is ++defined in an :ref:`internal source pad <MEDIA-PAD-FL-INTERNAL>` of the source ++sub-device. See also :ref:`source routes <v4l2-subdev-source-routes>`. ++ ++.. _v4l2-meta-fmt-generic-8: ++ ++V4L2_META_FMT_GENERIC_8 ++----------------------- ++ ++The V4L2_META_FMT_GENERIC_8 format is a plain 8-bit metadata format. ++ ++This format is also used on CSI-2 on both 8 bits per sample as well as on ++16 bits per sample when two bytes of metadata are packed into one sample. ++ ++**Byte Order Of V4L2_META_FMT_GENERIC_8.** ++Each cell is one byte. "M" denotes a byte of metadata. ++ ++.. tabularcolumns:: |p{2.4cm}|p{1.2cm}|p{1.2cm}|p{1.2cm}|p{1.2cm}| ++ ++.. flat-table:: ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 12 8 8 8 8 ++ ++ * - start + 0: ++ - M\ :sub:`00` ++ - M\ :sub:`10` ++ - M\ :sub:`20` ++ - M\ :sub:`30` ++ * - start + 4: ++ - M\ :sub:`01` ++ - M\ :sub:`11` ++ - M\ :sub:`21` ++ - M\ :sub:`31` ++ ++.. _v4l2-meta-fmt-generic-csi2-10: ++ ++V4L2_META_FMT_GENERIC_CSI2_10 ++----------------------------- ++ ++V4L2_META_FMT_GENERIC_CSI2_10 contains packed 8-bit generic metadata, 10 bits ++for each 8 bits of data. Every four bytes of metadata is followed by a single ++byte of padding. The way the data is stored follows the CSI-2 specification. ++ ++This format is also used on CSI-2 on 20 bits per sample format that packs two ++bytes of metadata into one sample. ++ ++This format is little endian. ++ ++**Byte Order Of V4L2_META_FMT_GENERIC_CSI2_10.** ++Each cell is one byte. "M" denotes a byte of metadata and "p" a byte of padding. ++ ++.. tabularcolumns:: |p{2.4cm}|p{1.2cm}|p{1.2cm}|p{1.2cm}|p{1.2cm}|p{.8cm}| ++ ++.. flat-table:: ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 12 8 8 8 8 8 ++ ++ * - start + 0: ++ - M\ :sub:`00` ++ - M\ :sub:`10` ++ - M\ :sub:`20` ++ - M\ :sub:`30` ++ - p ++ * - start + 5: ++ - M\ :sub:`01` ++ - M\ :sub:`11` ++ - M\ :sub:`21` ++ - M\ :sub:`31` ++ - p ++ ++.. _v4l2-meta-fmt-generic-csi2-12: ++ ++V4L2_META_FMT_GENERIC_CSI2_12 ++----------------------------- ++ ++V4L2_META_FMT_GENERIC_CSI2_12 contains packed 8-bit generic metadata, 12 bits ++for each 8 bits of data. Every four bytes of metadata is followed by two bytes ++of padding. The way the data is stored follows the CSI-2 specification. ++ ++This format is little endian. ++ ++**Byte Order Of V4L2_META_FMT_GENERIC_CSI2_12.** ++Each cell is one byte. "M" denotes a byte of metadata and "p" a byte of padding. ++ ++.. tabularcolumns:: |p{2.4cm}|p{1.2cm}|p{1.2cm}|p{1.2cm}|p{1.2cm}|p{.8cm}|p{.8cm}| ++ ++.. flat-table:: ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 12 8 8 8 8 8 8 ++ ++ * - start + 0: ++ - M\ :sub:`00` ++ - M\ :sub:`10` ++ - M\ :sub:`20` ++ - M\ :sub:`30` ++ - p ++ - p ++ * - start + 6: ++ - M\ :sub:`01` ++ - M\ :sub:`11` ++ - M\ :sub:`21` ++ - M\ :sub:`31` ++ - p ++ - p ++ ++.. _v4l2-meta-fmt-generic-csi2-14: ++ ++V4L2_META_FMT_GENERIC_CSI2_14 ++----------------------------- ++ ++V4L2_META_FMT_GENERIC_CSI2_14 contains packed 8-bit generic metadata, 14 bits ++for each 8 bits of data. Every four bytes of metadata is followed by three ++bytes of padding. The way the data is stored follows the CSI-2 specification. ++ ++This format is little endian. ++ ++**Byte Order Of V4L2_META_FMT_GENERIC_CSI2_14.** ++Each cell is one byte. "M" denotes a byte of metadata and "p" a byte of padding. ++ ++.. tabularcolumns:: |p{2.4cm}|p{1.2cm}|p{1.2cm}|p{1.2cm}|p{1.2cm}|p{.8cm}|p{.8cm}|p{.8cm}| ++ ++.. flat-table:: ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 12 8 8 8 8 8 8 8 ++ ++ * - start + 0: ++ - M\ :sub:`00` ++ - M\ :sub:`10` ++ - M\ :sub:`20` ++ - M\ :sub:`30` ++ - p ++ - p ++ - p ++ * - start + 7: ++ - M\ :sub:`01` ++ - M\ :sub:`11` ++ - M\ :sub:`21` ++ - M\ :sub:`31` ++ - p ++ - p ++ - p ++ ++.. _v4l2-meta-fmt-generic-csi2-16: ++ ++V4L2_META_FMT_GENERIC_CSI2_16 ++----------------------------- ++ ++V4L2_META_FMT_GENERIC_CSI2_16 contains packed 8-bit generic metadata, 16 bits ++for each 8 bits of data. Every byte of metadata is followed by one byte of ++padding. The way the data is stored follows the CSI-2 specification. ++ ++This format is little endian. ++ ++**Byte Order Of V4L2_META_FMT_GENERIC_CSI2_16.** ++Each cell is one byte. "M" denotes a byte of metadata and "p" a byte of padding. ++ ++.. tabularcolumns:: |p{2.4cm}|p{1.2cm}|p{.8cm}|p{1.2cm}|p{.8cm}|p{1.2cm}|p{.8cm}|p{1.2cm}|p{.8cm}| ++ ++.. flat-table:: ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 12 8 8 8 8 8 8 8 8 ++ ++ * - start + 0: ++ - M\ :sub:`00` ++ - p ++ - M\ :sub:`10` ++ - p ++ - M\ :sub:`20` ++ - p ++ - M\ :sub:`30` ++ - p ++ * - start + 8: ++ - M\ :sub:`01` ++ - p ++ - M\ :sub:`11` ++ - p ++ - M\ :sub:`21` ++ - p ++ - M\ :sub:`31` ++ - p ++ ++.. _v4l2-meta-fmt-generic-csi2-20: ++ ++V4L2_META_FMT_GENERIC_CSI2_20 ++----------------------------- ++ ++V4L2_META_FMT_GENERIC_CSI2_20 contains packed 8-bit generic metadata, 20 bits ++for each 8 bits of data. Every byte of metadata is followed by alternating one ++and two bytes of padding. The way the data is stored follows the CSI-2 ++specification. ++ ++This format is little endian. ++ ++**Byte Order Of V4L2_META_FMT_GENERIC_CSI2_20.** ++Each cell is one byte. "M" denotes a byte of metadata and "p" a byte of padding. ++ ++.. tabularcolumns:: |p{2.4cm}|p{1.2cm}|p{.8cm}|p{1.2cm}|p{.8cm}|p{.8cm}|p{1.2cm}|p{.8cm}|p{1.2cm}|p{.8cm}|p{.8cm}| ++ ++.. flat-table:: ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 12 8 8 8 8 8 8 8 8 8 8 ++ ++ * - start + 0: ++ - M\ :sub:`00` ++ - p ++ - M\ :sub:`10` ++ - p ++ - p ++ - M\ :sub:`20` ++ - p ++ - M\ :sub:`30` ++ - p ++ - p ++ * - start + 10: ++ - M\ :sub:`01` ++ - p ++ - M\ :sub:`11` ++ - p ++ - p ++ - M\ :sub:`21` ++ - p ++ - M\ :sub:`31` ++ - p ++ - p ++ ++.. _v4l2-meta-fmt-generic-csi2-24: ++ ++V4L2_META_FMT_GENERIC_CSI2_24 ++----------------------------- ++ ++V4L2_META_FMT_GENERIC_CSI2_24 contains packed 8-bit generic metadata, 24 bits ++for each 8 bits of data. Every byte of metadata is followed by two bytes of ++padding. The way the data is stored follows the CSI-2 specification. ++ ++This format is little endian. ++ ++**Byte Order Of V4L2_META_FMT_GENERIC_CSI2_24.** ++Each cell is one byte. "M" denotes a byte of metadata and "p" a byte of padding. ++ ++.. tabularcolumns:: |p{2.4cm}|p{1.2cm}|p{.8cm}|p{.8cm}|p{1.2cm}|p{.8cm}|p{.8cm}|p{1.2cm}|p{.8cm}|p{.8cm}|p{1.2cm}|p{.8cm}|p{.8cm}| ++ ++.. flat-table:: ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 12 8 8 8 8 8 8 8 8 8 8 8 8 ++ ++ * - start + 0: ++ - M\ :sub:`00` ++ - p ++ - p ++ - M\ :sub:`10` ++ - p ++ - p ++ - M\ :sub:`20` ++ - p ++ - p ++ - M\ :sub:`30` ++ - p ++ - p ++ * - start + 12: ++ - M\ :sub:`01` ++ - p ++ - p ++ - M\ :sub:`11` ++ - p ++ - p ++ - M\ :sub:`21` ++ - p ++ - p ++ - M\ :sub:`31` ++ - p ++ - p ++ ++.. _v4l2-meta-fmt-generic-csi2-2-24: ++ ++V4L2_META_FMT_GENERIC_CSI2_2_24 ++------------------------------- ++ ++V4L2_META_FMT_GENERIC_CSI2_2_24 contains packed 8-bit generic metadata, 24 bits ++for each two times 8 bits of data. Every two bytes of metadata are followed by ++one byte of padding. The way the data is stored follows the CSI-2 ++specification. ++ ++This format is little endian. ++ ++**Byte Order Of V4L2_META_FMT_GENERIC_CSI2_2_24.** ++Each cell is one byte. "M" denotes a byte of metadata and "p" a byte of padding. ++ ++.. tabularcolumns:: |p{2.4cm}|p{1.2cm}|p{1.2cm}|p{.8cm}|p{1.2cm}|p{1.2cm}|p{.8cm}| ++ ++.. flat-table:: ++ :header-rows: 0 ++ :stub-columns: 0 ++ :widths: 12 8 8 8 8 8 8 ++ ++ * - start + 0: ++ - M\ :sub:`00` ++ - M\ :sub:`10` ++ - p ++ - M\ :sub:`20` ++ - M\ :sub:`30` ++ - p ++ * - start + 6: ++ - M\ :sub:`01` ++ - M\ :sub:`11` ++ - p ++ - M\ :sub:`21` ++ - M\ :sub:`31` ++ - p ++ +diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c +index 33076af4dfdb..4eb3db1773e1 100644 +--- a/drivers/media/v4l2-core/v4l2-ioctl.c ++++ b/drivers/media/v4l2-core/v4l2-ioctl.c +@@ -1452,6 +1452,14 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) + case V4L2_PIX_FMT_Y210: descr = "10-bit YUYV Packed"; break; + case V4L2_PIX_FMT_Y212: descr = "12-bit YUYV Packed"; break; + case V4L2_PIX_FMT_Y216: descr = "16-bit YUYV Packed"; break; ++ case V4L2_META_FMT_GENERIC_8: descr = "8-bit Generic Metadata"; break; ++ case V4L2_META_FMT_GENERIC_CSI2_10: descr = "8b Generic Meta, 10b CSI-2"; break; ++ case V4L2_META_FMT_GENERIC_CSI2_12: descr = "8b Generic Meta, 12b CSI-2"; break; ++ case V4L2_META_FMT_GENERIC_CSI2_14: descr = "8b Generic Meta, 14b CSI-2"; break; ++ case V4L2_META_FMT_GENERIC_CSI2_16: descr = "8b Generic Meta, 16b CSI-2"; break; ++ case V4L2_META_FMT_GENERIC_CSI2_20: descr = "8b Generic Meta, 20b CSI-2"; break; ++ case V4L2_META_FMT_GENERIC_CSI2_24: descr = "8b Generic Meta, 24b CSI-2"; break; ++ case V4L2_META_FMT_GENERIC_CSI2_2_24: descr = "2x8b Generic Meta, 24b CSI-2"; break; + + default: + /* Compressed formats */ +diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h +index 68e7ac178cc2..2c4e03d47789 100644 +--- a/include/uapi/linux/videodev2.h ++++ b/include/uapi/linux/videodev2.h +@@ -839,6 +839,15 @@ struct v4l2_pix_format { + #define V4L2_META_FMT_RK_ISP1_PARAMS v4l2_fourcc('R', 'K', '1', 'P') /* Rockchip ISP1 3A Parameters */ + #define V4L2_META_FMT_RK_ISP1_STAT_3A v4l2_fourcc('R', 'K', '1', 'S') /* Rockchip ISP1 3A Statistics */ + ++#define V4L2_META_FMT_GENERIC_8 v4l2_fourcc('M', 'E', 'T', '8') /* Generic 8-bit metadata */ ++#define V4L2_META_FMT_GENERIC_CSI2_10 v4l2_fourcc('M', 'C', '1', 'A') /* 10-bit CSI-2 packed 8-bit metadata */ ++#define V4L2_META_FMT_GENERIC_CSI2_12 v4l2_fourcc('M', 'C', '1', 'C') /* 12-bit CSI-2 packed 8-bit metadata */ ++#define V4L2_META_FMT_GENERIC_CSI2_14 v4l2_fourcc('M', 'C', '1', 'E') /* 14-bit CSI-2 packed 8-bit metadata */ ++#define V4L2_META_FMT_GENERIC_CSI2_16 v4l2_fourcc('M', 'C', '1', 'G') /* 16-bit CSI-2 packed 8-bit metadata */ ++#define V4L2_META_FMT_GENERIC_CSI2_20 v4l2_fourcc('M', 'C', '1', 'K') /* 20-bit CSI-2 packed 8-bit metadata */ ++#define V4L2_META_FMT_GENERIC_CSI2_24 v4l2_fourcc('M', 'C', '1', 'O') /* 24-bit CSI-2 packed 8-bit metadata */ ++#define V4L2_META_FMT_GENERIC_CSI2_2_24 v4l2_fourcc('M', 'C', '2', 'O') /* 2 bytes of 8-bit metadata, 24-bit CSI-2 packed */ ++ + /* priv field value to indicates that subsequent fields are valid. */ + #define V4L2_PIX_FMT_PRIV_MAGIC 0xfeedcafe + +-- +2.43.2 + + +From 453627c23062ff0aa01e0e46e3b7922ddf82f998 Mon Sep 17 00:00:00 2001 +From: Sakari Ailus <sakari.ailus@linux.intel.com> +Date: Tue, 8 Aug 2023 10:55:36 +0300 +Subject: [PATCH 06/33] media: v4l: Support line-based metadata capture + +many camera sensors, among other devices, transmit embedded data and image +data for each CSI-2 frame. This embedded data typically contains register +configuration of the sensor that has been used to capture the image data +of the same frame. + +The embedded data is received by the CSI-2 receiver and has the same +properties as the image data, including that it is line based: it has +width, height and bytesperline (stride). + +Add these fields to struct v4l2_meta_format and document them. + +Also add V4L2_FMT_FLAG_META_LINE_BASED to tell a given format is +line-based i.e. these fields of struct v4l2_meta_format are valid for it. + +Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> +--- + .../userspace-api/media/v4l/dev-meta.rst | 15 +++++++++++++++ + .../userspace-api/media/v4l/vidioc-enum-fmt.rst | 7 +++++++ + .../media/videodev2.h.rst.exceptions | 1 + + drivers/media/v4l2-core/v4l2-ioctl.c | 5 +++-- + include/uapi/linux/videodev2.h | 10 ++++++++++ + 5 files changed, 36 insertions(+), 2 deletions(-) + +diff --git a/Documentation/userspace-api/media/v4l/dev-meta.rst b/Documentation/userspace-api/media/v4l/dev-meta.rst +index 0e7e1ee1471a..4b24bae6e171 100644 +--- a/Documentation/userspace-api/media/v4l/dev-meta.rst ++++ b/Documentation/userspace-api/media/v4l/dev-meta.rst +@@ -65,3 +65,18 @@ to 0. + - ``buffersize`` + - Maximum buffer size in bytes required for data. The value is set by the + driver. ++ * - __u32 ++ - ``width`` ++ - Width of a line of metadata in samples. Valid when :c:type`v4l2_fmtdesc` ++ flag ``V4L2_FMT_FLAG_META_LINE_BASED`` is set, otherwise zero. See ++ :c:func:`VIDIOC_ENUM_FMT`. ++ * - __u32 ++ - ``height`` ++ - Number of rows of metadata. Valid when :c:type`v4l2_fmtdesc` flag ++ ``V4L2_FMT_FLAG_META_LINE_BASED`` is set, otherwise zero. See ++ :c:func:`VIDIOC_ENUM_FMT`. ++ * - __u32 ++ - ``bytesperline`` ++ - Offset in bytes between the beginning of two consecutive lines. Valid ++ when :c:type`v4l2_fmtdesc` flag ``V4L2_FMT_FLAG_META_LINE_BASED`` is ++ set, otherwise zero. See :c:func:`VIDIOC_ENUM_FMT`. +diff --git a/Documentation/userspace-api/media/v4l/vidioc-enum-fmt.rst b/Documentation/userspace-api/media/v4l/vidioc-enum-fmt.rst +index 000c154b0f98..6d7664345a4e 100644 +--- a/Documentation/userspace-api/media/v4l/vidioc-enum-fmt.rst ++++ b/Documentation/userspace-api/media/v4l/vidioc-enum-fmt.rst +@@ -227,6 +227,13 @@ the ``mbus_code`` field is handled differently: + The application can ask to configure the quantization of the capture + device when calling the :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctl with + :ref:`V4L2_PIX_FMT_FLAG_SET_CSC <v4l2-pix-fmt-flag-set-csc>` set. ++ * - ``V4L2_FMT_FLAG_META_LINE_BASED`` ++ - 0x0200 ++ - The metadata format is line-based. In this case the ``width``, ++ ``height`` and ``bytesperline`` fields of :c:type:`v4l2_meta_format` are ++ valid. The buffer consists of ``height`` lines, each having ``width`` ++ bytes of data and offset between the beginning of each two consecutive ++ lines is ``bytesperline``. + + Return Value + ============ +diff --git a/Documentation/userspace-api/media/videodev2.h.rst.exceptions b/Documentation/userspace-api/media/videodev2.h.rst.exceptions +index 3e58aac4ef0b..bdc628e8c1d6 100644 +--- a/Documentation/userspace-api/media/videodev2.h.rst.exceptions ++++ b/Documentation/userspace-api/media/videodev2.h.rst.exceptions +@@ -215,6 +215,7 @@ replace define V4L2_FMT_FLAG_CSC_XFER_FUNC fmtdesc-flags + replace define V4L2_FMT_FLAG_CSC_YCBCR_ENC fmtdesc-flags + replace define V4L2_FMT_FLAG_CSC_HSV_ENC fmtdesc-flags + replace define V4L2_FMT_FLAG_CSC_QUANTIZATION fmtdesc-flags ++replace define V4L2_FMT_FLAG_META_LINE_BASED fmtdesc-flags + + # V4L2 timecode types + replace define V4L2_TC_TYPE_24FPS timecode-type +diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c +index 4eb3db1773e1..1fcec1515bcc 100644 +--- a/drivers/media/v4l2-core/v4l2-ioctl.c ++++ b/drivers/media/v4l2-core/v4l2-ioctl.c +@@ -343,8 +343,9 @@ static void v4l_print_format(const void *arg, bool write_only) + case V4L2_BUF_TYPE_META_OUTPUT: + meta = &p->fmt.meta; + pixelformat = meta->dataformat; +- pr_cont(", dataformat=%p4cc, buffersize=%u\n", +- &pixelformat, meta->buffersize); ++ pr_cont(", dataformat=%p4cc, buffersize=%u, width=%u, height=%u, bytesperline=%u\n", ++ &pixelformat, meta->buffersize, meta->width, ++ meta->height, meta->bytesperline); + break; + } + } +diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h +index 2c4e03d47789..48fb44772098 100644 +--- a/include/uapi/linux/videodev2.h ++++ b/include/uapi/linux/videodev2.h +@@ -878,6 +878,7 @@ struct v4l2_fmtdesc { + #define V4L2_FMT_FLAG_CSC_YCBCR_ENC 0x0080 + #define V4L2_FMT_FLAG_CSC_HSV_ENC V4L2_FMT_FLAG_CSC_YCBCR_ENC + #define V4L2_FMT_FLAG_CSC_QUANTIZATION 0x0100 ++#define V4L2_FMT_FLAG_META_LINE_BASED 0x0200 + + /* Frame Size and frame rate enumeration */ + /* +@@ -2424,10 +2425,19 @@ struct v4l2_sdr_format { + * struct v4l2_meta_format - metadata format definition + * @dataformat: little endian four character code (fourcc) + * @buffersize: maximum size in bytes required for data ++ * @width: number of bytes of data per line (valid for line based ++ * formats only, see format documentation) ++ * @height: number of lines of data per buffer (valid for line based ++ * formats only) ++ * @bytesperline: offset between the beginnings of two adjacent lines in ++ * bytes (valid for line based formats only) + */ + struct v4l2_meta_format { + __u32 dataformat; + __u32 buffersize; ++ __u32 width; ++ __u32 height; ++ __u32 bytesperline; + } __attribute__ ((packed)); + + /** +-- +2.43.2 + + +From 090bb3894bda739ff06e8a431815210b731056b7 Mon Sep 17 00:00:00 2001 +From: Sakari Ailus <sakari.ailus@linux.intel.com> +Date: Tue, 8 Aug 2023 10:55:37 +0300 +Subject: [PATCH 07/33] media: Add media bus codes for MIPI CCS embedded data + +Add new MIPI CCS embedded data media bus formats. + +Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> +--- + .../media/v4l/subdev-formats.rst | 32 +++++++++++++++++++ + include/uapi/linux/media-bus-format.h | 10 +++++- + 2 files changed, 41 insertions(+), 1 deletion(-) + +diff --git a/Documentation/userspace-api/media/v4l/subdev-formats.rst b/Documentation/userspace-api/media/v4l/subdev-formats.rst +index 7d107873cddd..7afb057a09c5 100644 +--- a/Documentation/userspace-api/media/v4l/subdev-formats.rst ++++ b/Documentation/userspace-api/media/v4l/subdev-formats.rst +@@ -8563,3 +8563,35 @@ and finally the bit number in subscript. "p" indicates a padding bit. + - p + - p + - p ++ ++MIPI CCS Embedded Data Formats ++^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ++ ++`MIPI CCS <https://www.mipi.org/specifications/camera-command-set>`_ defines an ++metadata format for sensor embedded data, which is used to store the register ++configuration used for capturing a given frame. The format is defined in the CCS ++specification. ++ ++The bit depth of the CCS embedded data matches the pixel data bit depth ++configured on the sensor. The formats used and their corresponding generic ++formats are listed in the table below. ++ ++.. flat-table: CCS embedded data mbus formats and corresponding generic formats ++ :header-rows: 1 ++ ++ * - CCS embedded data mbus format ++ - Generic metadata format ++ * - MEDIA_BUS_FMT_CCS_EMBEDDED_8 ++ - MEDIA_BUS_FMT_META_8 ++ * - MEDIA_BUS_FMT_CCS_EMBEDDED_10 ++ - MEDIA_BUS_FMT_META_10 ++ * - MEDIA_BUS_FMT_CCS_EMBEDDED_12 ++ - MEDIA_BUS_FMT_META_12 ++ * - MEDIA_BUS_FMT_CCS_EMBEDDED_14 ++ - MEDIA_BUS_FMT_META_14 ++ * - MEDIA_BUS_FMT_CCS_EMBEDDED_16 ++ - MEDIA_BUS_FMT_META_16 ++ * - MEDIA_BUS_FMT_CCS_EMBEDDED_20 ++ - MEDIA_BUS_FMT_META_20 ++ * - MEDIA_BUS_FMT_CCS_EMBEDDED_24 ++ - MEDIA_BUS_FMT_META_24 +diff --git a/include/uapi/linux/media-bus-format.h b/include/uapi/linux/media-bus-format.h +index 6fcd7d276bc6..d5014ef3c43a 100644 +--- a/include/uapi/linux/media-bus-format.h ++++ b/include/uapi/linux/media-bus-format.h +@@ -183,7 +183,15 @@ + #define MEDIA_BUS_FMT_META_20 0x8006 + #define MEDIA_BUS_FMT_META_24 0x8007 + ++/* Specific metadata formats. Next is 0x9008. */ ++#define MEDIA_BUS_FMT_CCS_EMBEDDED_8 0x9001 ++#define MEDIA_BUS_FMT_CCS_EMBEDDED_10 0x9002 ++#define MEDIA_BUS_FMT_CCS_EMBEDDED_12 0x9003 ++#define MEDIA_BUS_FMT_CCS_EMBEDDED_14 0x9004 ++#define MEDIA_BUS_FMT_CCS_EMBEDDED_16 0x9005 ++#define MEDIA_BUS_FMT_CCS_EMBEDDED_20 0x9006 ++#define MEDIA_BUS_FMT_CCS_EMBEDDED_24 0x9007 ++ + #define MEDIA_BUS_FMT_IS_META(code) \ + ((code) & 0xf000 == 0x7000 || (code) & 0xf000 == 0x8000) +- + #endif /* __LINUX_MEDIA_BUS_FORMAT_H */ +-- +2.43.2 + + +From 44f8084f055969874d2216ba4e6e225046931e73 Mon Sep 17 00:00:00 2001 From: Bingbu Cao <bingbu.cao@intel.com> Date: Thu, 11 Jan 2024 14:55:15 +0800 -Subject: [PATCH 01/31] media: intel/ipu6: add Intel IPU6 PCI device driver +Subject: [PATCH 08/33] media: intel/ipu6: add Intel IPU6 PCI device driver Intel Image Processing Unit 6th Gen includes input and processing systems but the hardware presents itself as a single PCI device in system. @@ -12,8 +1117,6 @@ specific variants to support multiple IPU6 devices in single device driver. Signed-off-by: Bingbu Cao <bingbu.cao@intel.com> -Link: https://lore.kernel.org/r/20240111065531.2418836-2-bingbu.cao@intel.com -Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- .../media/pci/intel/ipu6/ipu6-platform-regs.h | 179 ++++ drivers/media/pci/intel/ipu6/ipu6.c | 966 ++++++++++++++++++ @@ -1212,10 +2315,10 @@ index 000000000000..04e7e7e61ca5 +#define IPU6_NAME "intel-ipu6" +#define IPU6_MEDIA_DEV_MODEL_NAME "ipu6" + -+#define IPU6SE_FIRMWARE_NAME "intel/ipu/ipu6se_fw.bin" -+#define IPU6EP_FIRMWARE_NAME "intel/ipu/ipu6ep_fw.bin" -+#define IPU6_FIRMWARE_NAME "intel/ipu/ipu6_fw.bin" -+#define IPU6EPMTL_FIRMWARE_NAME "intel/ipu/ipu6epmtl_fw.bin" ++#define IPU6SE_FIRMWARE_NAME "intel/ipu6se_fw.bin" ++#define IPU6EP_FIRMWARE_NAME "intel/ipu6ep_fw.bin" ++#define IPU6_FIRMWARE_NAME "intel/ipu6_fw.bin" ++#define IPU6EPMTL_FIRMWARE_NAME "intel/ipu6epmtl_fw.bin" + +enum ipu6_version { + IPU6_VER_INVALID = 0, @@ -1543,12 +2646,13 @@ index 000000000000..04e7e7e61ca5 + dma_addr_t pkg_dir_dma_addr); +#endif /* IPU6_H */ -- -2.43.0 +2.43.2 -From 79ff4f8a1383c679fc4bbee832e51e6369cbc21c Mon Sep 17 00:00:00 2001 + +From f52c1b80222269f99d52b0af5937995e22c9ed6d Mon Sep 17 00:00:00 2001 From: Bingbu Cao <bingbu.cao@intel.com> Date: Thu, 11 Jan 2024 14:55:16 +0800 -Subject: [PATCH 02/31] media: intel/ipu6: add IPU auxiliary devices +Subject: [PATCH 09/33] media: intel/ipu6: add IPU auxiliary devices Even the IPU input system and processing system are in a single PCI device, each system has its own power sequence, the processing system @@ -1561,8 +2665,6 @@ Register the IS/PS devices on auxiliary bus and attach power domain to implement the power sequence dependency. Signed-off-by: Bingbu Cao <bingbu.cao@intel.com> -Link: https://lore.kernel.org/r/20240111065531.2418836-3-bingbu.cao@intel.com -Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/media/pci/intel/ipu6/ipu6-bus.c | 165 ++++++++++++++++++++++++ drivers/media/pci/intel/ipu6/ipu6-bus.h | 58 +++++++++ @@ -1806,12 +2908,13 @@ index 000000000000..d46181354836 + +#endif -- -2.43.0 +2.43.2 + -From 5836e6b1138ff9cba76ab74c1eab0ec57e50dfc1 Mon Sep 17 00:00:00 2001 +From a74d85716ec13ff2f55997c73c9f06367174d7a6 Mon Sep 17 00:00:00 2001 From: Bingbu Cao <bingbu.cao@intel.com> Date: Thu, 11 Jan 2024 14:55:17 +0800 -Subject: [PATCH 03/31] media: intel/ipu6: add IPU6 buttress interface driver +Subject: [PATCH 10/33] media: intel/ipu6: add IPU6 buttress interface driver The IPU6 buttress is the interface between IPU device (input system and processing system) with rest of the SoC. It contains overall IPU @@ -1820,8 +2923,6 @@ interfaces with the Intel Converged Security Engine and Punit to do firmware authentication and power management. Signed-off-by: Bingbu Cao <bingbu.cao@intel.com> -Link: https://lore.kernel.org/r/20240111065531.2418836-4-bingbu.cao@intel.com -Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/media/pci/intel/ipu6/ipu6-buttress.c | 912 ++++++++++++++++++ drivers/media/pci/intel/ipu6/ipu6-buttress.h | 102 ++ @@ -3096,12 +4197,13 @@ index 000000000000..87239af96502 + BUTTRESS_ISR_SAI_VIOLATION) +#endif /* IPU6_PLATFORM_BUTTRESS_REGS_H */ -- -2.43.0 +2.43.2 + -From 4e01328e611be4ba5a2c9fe2baedfeb239db9d99 Mon Sep 17 00:00:00 2001 +From 12bd5bdd53a7c829cc5cd61a6887f89ffb036f8f Mon Sep 17 00:00:00 2001 From: Bingbu Cao <bingbu.cao@intel.com> Date: Thu, 11 Jan 2024 14:55:18 +0800 -Subject: [PATCH 04/31] media: intel/ipu6: CPD parsing for get firmware +Subject: [PATCH 11/33] media: intel/ipu6: CPD parsing for get firmware components For IPU6, firmware is generated and released as signed @@ -3111,8 +4213,6 @@ header, manifest, metadata and module data. Driver can parse them according to the CPD layout to acquire each component. Signed-off-by: Bingbu Cao <bingbu.cao@intel.com> -Link: https://lore.kernel.org/r/20240111065531.2418836-5-bingbu.cao@intel.com -Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/media/pci/intel/ipu6/ipu6-cpd.c | 362 ++++++++++++++++++++++++ drivers/media/pci/intel/ipu6/ipu6-cpd.h | 105 +++++++ @@ -3600,12 +4700,13 @@ index 000000000000..37465d507386 + unsigned long cpd_file_size); +#endif /* IPU6_CPD_H */ -- -2.43.0 +2.43.2 -From 05c36b7a6306ed7ef15b9fd6039920a7d08626cc Mon Sep 17 00:00:00 2001 + +From 86b4cd540a9cb10de7a521882495f5eba6cc919f Mon Sep 17 00:00:00 2001 From: Bingbu Cao <bingbu.cao@intel.com> Date: Thu, 11 Jan 2024 14:55:19 +0800 -Subject: [PATCH 05/31] media: intel/ipu6: add IPU6 DMA mapping API and MMU +Subject: [PATCH 12/33] media: intel/ipu6: add IPU6 DMA mapping API and MMU table he Intel IPU6 has an internal microcontroller (scalar processor, SP) which @@ -3616,8 +4717,6 @@ This patch adds a driver for the IPU MMU and a DMA mapping implementation using the internal MMU. The system IOMMU may be used besides the IPU MMU. Signed-off-by: Bingbu Cao <bingbu.cao@intel.com> -Link: https://lore.kernel.org/r/20240111065531.2418836-6-bingbu.cao@intel.com -Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/media/pci/intel/ipu6/ipu6-dma.c | 502 ++++++++++++++ drivers/media/pci/intel/ipu6/ipu6-dma.h | 19 + @@ -5093,12 +6192,13 @@ index 000000000000..95df7931a2e5 + dma_addr_t iova); +#endif -- -2.43.0 +2.43.2 + -From 6e686c2ff23611004d6e4f9a543116d65cbcf5f3 Mon Sep 17 00:00:00 2001 +From a4363013580d8a552e8084faedbb98bd2482c057 Mon Sep 17 00:00:00 2001 From: Bingbu Cao <bingbu.cao@intel.com> Date: Thu, 11 Jan 2024 14:55:20 +0800 -Subject: [PATCH 06/31] media: intel/ipu6: add syscom interfaces between +Subject: [PATCH 13/33] media: intel/ipu6: add syscom interfaces between firmware and driver Syscom is an inter-process(or) communication mechanism between an IPU @@ -5110,8 +6210,6 @@ or memory to reside the read and write indices which are updated by consumer and producer. Signed-off-by: Bingbu Cao <bingbu.cao@intel.com> -Link: https://lore.kernel.org/r/20240111065531.2418836-7-bingbu.cao@intel.com -Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/media/pci/intel/ipu6/ipu6-fw-com.c | 413 +++++++++++++++++++++ drivers/media/pci/intel/ipu6/ipu6-fw-com.h | 47 +++ @@ -5592,12 +6690,13 @@ index 000000000000..660c406b3ac9 + +#endif -- -2.43.0 +2.43.2 + -From 6784d60f5fe68eca8bfc92785b5badd0bf415048 Mon Sep 17 00:00:00 2001 +From e690b8a96eb4fbe1d948ad80047a9af7c601b761 Mon Sep 17 00:00:00 2001 From: Bingbu Cao <bingbu.cao@intel.com> Date: Thu, 11 Jan 2024 14:55:21 +0800 -Subject: [PATCH 07/31] media: intel/ipu6: input system ABI between firmware +Subject: [PATCH 14/33] media: intel/ipu6: input system ABI between firmware and driver Implement the input system firmware ABIs between the firmware and @@ -5605,8 +6704,6 @@ driver - include stream configuration, control command, capture request and response, etc. Signed-off-by: Bingbu Cao <bingbu.cao@intel.com> -Link: https://lore.kernel.org/r/20240111065531.2418836-8-bingbu.cao@intel.com -Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/media/pci/intel/ipu6/ipu6-fw-isys.c | 487 +++++++++++++++++ drivers/media/pci/intel/ipu6/ipu6-fw-isys.h | 573 ++++++++++++++++++++ @@ -6687,12 +7784,13 @@ index 000000000000..a7ffa0e22bf0 +void ipu6_fw_isys_put_resp(void *context, unsigned int queue); +#endif -- -2.43.0 +2.43.2 -From 2d13721450bd1d8e778c0727a7c3eac6cc1fd6c0 Mon Sep 17 00:00:00 2001 + +From e69a245fa4db99e5983170aab73f962dc99d3149 Mon Sep 17 00:00:00 2001 From: Bingbu Cao <bingbu.cao@intel.com> Date: Thu, 11 Jan 2024 14:55:22 +0800 -Subject: [PATCH 08/31] media: intel/ipu6: add IPU6 CSI2 receiver v4l2 +Subject: [PATCH 15/33] media: intel/ipu6: add IPU6 CSI2 receiver v4l2 sub-device Input system CSI2 receiver is exposed as a v4l2 sub-device. @@ -6702,8 +7800,6 @@ by linked with ISYS CSI2's sink pad. CSI2 source pad is linked to the sink pad of video capture device. Signed-off-by: Bingbu Cao <bingbu.cao@intel.com> -Link: https://lore.kernel.org/r/20240111065531.2418836-9-bingbu.cao@intel.com -Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c | 666 ++++++++++++++++++ drivers/media/pci/intel/ipu6/ipu6-isys-csi2.h | 81 +++ @@ -8126,12 +9222,13 @@ index 000000000000..2034e1109d98 + +#endif /* IPU6_ISYS_CSI2_REG_H */ -- -2.43.0 +2.43.2 + -From ba67c52b68d458e2c8ae4af08bd01a6ebe60b475 Mon Sep 17 00:00:00 2001 +From 71d3da5e8f1ea094e26030a12ceed4553cbe182a Mon Sep 17 00:00:00 2001 From: Bingbu Cao <bingbu.cao@intel.com> Date: Thu, 11 Jan 2024 14:55:23 +0800 -Subject: [PATCH 09/31] media: intel/ipu6: add the CSI2 DPHY implementation +Subject: [PATCH 16/33] media: intel/ipu6: add the CSI2 DPHY implementation IPU6 CSI2 DPHY hardware varies on different platforms, current IPU6 has three DPHY hardware instance which maybe used on tigerlake, @@ -8142,8 +9239,6 @@ Each PHY has its own register space, input system driver call the DPHY callback which was set at isys_probe(). Signed-off-by: Bingbu Cao <bingbu.cao@intel.com> -Link: https://lore.kernel.org/r/20240111065531.2418836-10-bingbu.cao@intel.com -Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- .../media/pci/intel/ipu6/ipu6-isys-dwc-phy.c | 536 +++++++++++++ .../media/pci/intel/ipu6/ipu6-isys-jsl-phy.c | 242 ++++++ @@ -9670,20 +10765,19 @@ index 000000000000..9abf389a05f1 + return ipu6_isys_mcd_phy_powerdown_ack(isys, phy_id); +} -- -2.43.0 +2.43.2 + -From a3b3658e56d3fe9e0cb03166e38a023dba853594 Mon Sep 17 00:00:00 2001 +From 5d8544bd1d6dc7fce10a3bf01d10d926b8990b54 Mon Sep 17 00:00:00 2001 From: Bingbu Cao <bingbu.cao@intel.com> Date: Thu, 11 Jan 2024 14:55:24 +0800 -Subject: [PATCH 10/31] media: intel/ipu6: add input system driver +Subject: [PATCH 17/33] media: intel/ipu6: add input system driver Input system driver do basic isys hardware setup and irq handling and work with fwnode and v4l2 to register the ISYS v4l2 devices. Signed-off-by: Bingbu Cao <bingbu.cao@intel.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Link: https://lore.kernel.org/r/20240111065531.2418836-11-bingbu.cao@intel.com -Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/media/pci/intel/ipu6/ipu6-isys.c | 1353 ++++++++++++++++++++++ drivers/media/pci/intel/ipu6/ipu6-isys.h | 207 ++++ @@ -11264,12 +12358,13 @@ index 000000000000..cf7a90bfedc9 + bool on); +#endif /* IPU6_ISYS_H */ -- -2.43.0 +2.43.2 -From 32d07a2e879187ea87b90256ac32a41080e3b8bc Mon Sep 17 00:00:00 2001 + +From 7cdb944c1cc8beb6f61268e2fe177d585fa5f415 Mon Sep 17 00:00:00 2001 From: Bingbu Cao <bingbu.cao@intel.com> Date: Thu, 11 Jan 2024 14:55:25 +0800 -Subject: [PATCH 11/31] media: intel/ipu6: input system video capture nodes +Subject: [PATCH 18/33] media: intel/ipu6: input system video capture nodes Register v4l2 video device and setup the vb2 queue to support basic video capture. Video streaming callback @@ -11279,8 +12374,6 @@ data type and stream ID and then queue buffers to firmware to do capture. Signed-off-by: Bingbu Cao <bingbu.cao@intel.com> -Link: https://lore.kernel.org/r/20240111065531.2418836-12-bingbu.cao@intel.com -Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- .../media/pci/intel/ipu6/ipu6-isys-queue.c | 825 +++++++++++ .../media/pci/intel/ipu6/ipu6-isys-queue.h | 76 + @@ -13607,12 +14700,13 @@ index 000000000000..21cd33c7e277 + +#endif /* IPU6_ISYS_VIDEO_H */ -- -2.43.0 +2.43.2 + -From abf929b4fbd35689080a8629c6bfebe0de699fe5 Mon Sep 17 00:00:00 2001 +From cc79447bab87ce8c498b0e7a5f849c7d4f6262c0 Mon Sep 17 00:00:00 2001 From: Bingbu Cao <bingbu.cao@intel.com> Date: Thu, 11 Jan 2024 14:55:26 +0800 -Subject: [PATCH 12/31] media: add Kconfig and Makefile for IPU6 +Subject: [PATCH 19/33] media: add Kconfig and Makefile for IPU6 Add IPU6 support in Kconfig and Makefile, with this patch you can build the Intel IPU6 and input system modules by select the @@ -13620,8 +14714,6 @@ CONFIG_VIDEO_INTEL_IPU6 in config. Signed-off-by: Bingbu Cao <bingbu.cao@intel.com> Signed-off-by: Andreas Helbech Kleist <andreaskleist@gmail.com> -Link: https://lore.kernel.org/r/20240111065531.2418836-13-bingbu.cao@intel.com -Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/media/pci/intel/Kconfig | 1 + drivers/media/pci/intel/Makefile | 1 + @@ -13705,28 +14797,27 @@ index 000000000000..a821b0a1567f + +obj-$(CONFIG_VIDEO_INTEL_IPU6) += intel-ipu6-isys.o -- -2.43.0 +2.43.2 + -From 59872e5aa96479948da4b1d04a10101d8cb86da2 Mon Sep 17 00:00:00 2001 +From edc6bed6991727e64f1eb60c0392403c39b96ba4 Mon Sep 17 00:00:00 2001 From: Bingbu Cao <bingbu.cao@intel.com> Date: Thu, 11 Jan 2024 14:55:27 +0800 -Subject: [PATCH 13/31] MAINTAINERS: add maintainers for Intel IPU6 input +Subject: [PATCH 20/33] MAINTAINERS: add maintainers for Intel IPU6 input system driver Update MAINTAINERS file for Intel IPU6 input system driver. Signed-off-by: Bingbu Cao <bingbu.cao@intel.com> -Link: https://lore.kernel.org/r/20240111065531.2418836-14-bingbu.cao@intel.com -Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- MAINTAINERS | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS -index a7c4cf8201e0..bedffa6941ab 100644 +index 1aabf1c15bb3..5346d472cb0f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -10733,6 +10733,16 @@ F: Documentation/admin-guide/media/ipu3_rcb.svg +@@ -10899,6 +10899,16 @@ F: Documentation/admin-guide/media/ipu3_rcb.svg F: Documentation/userspace-api/media/v4l/metafmt-intel-ipu3.rst F: drivers/staging/media/ipu3/ @@ -13744,12 +14835,13 @@ index a7c4cf8201e0..bedffa6941ab 100644 M: Sumesh K Naduvalath <sumesh.k.naduvalath@intel.com> L: platform-driver-x86@vger.kernel.org -- -2.43.0 +2.43.2 -From 7acc1618d2f9cbb0d6b07ce9a1eace25663b9fb2 Mon Sep 17 00:00:00 2001 + +From a12041e5f7fb32b93669f19b579bc1940a026bbe Mon Sep 17 00:00:00 2001 From: Bingbu Cao <bingbu.cao@intel.com> Date: Thu, 11 Jan 2024 14:55:28 +0800 -Subject: [PATCH 14/31] Documentation: add Intel IPU6 ISYS driver admin-guide +Subject: [PATCH 21/33] Documentation: add Intel IPU6 ISYS driver admin-guide doc This document mainly describe the functionality of IPU6 and @@ -13757,8 +14849,6 @@ IPU6 isys driver, and gives an example that how user can do imaging capture with tools. Signed-off-by: Bingbu Cao <bingbu.cao@intel.com> -Link: https://lore.kernel.org/r/20240111065531.2418836-15-bingbu.cao@intel.com -Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- Documentation/admin-guide/media/ipu6-isys.rst | 158 ++++++++++++++++ .../admin-guide/media/ipu6_isys_graph.svg | 174 ++++++++++++++++++ @@ -14112,7 +15202,7 @@ index 000000000000..707747c75280 +</g> +</svg> diff --git a/Documentation/admin-guide/media/v4l-drivers.rst b/Documentation/admin-guide/media/v4l-drivers.rst -index 61283d67ceef..50bdef2d1762 100644 +index f4bb2605f07e..4120eded9a13 100644 --- a/Documentation/admin-guide/media/v4l-drivers.rst +++ b/Documentation/admin-guide/media/v4l-drivers.rst @@ -16,6 +16,7 @@ Video4Linux (V4L) driver-specific documentation @@ -14124,20 +15214,19 @@ index 61283d67ceef..50bdef2d1762 100644 mgb4 omap3isp -- -2.43.0 +2.43.2 + -From 878747fcd0bb4f27933d3d32525472b8a0425724 Mon Sep 17 00:00:00 2001 +From 3e80683ecc9ffe38fdf6e6232089794b6019816b Mon Sep 17 00:00:00 2001 From: Bingbu Cao <bingbu.cao@intel.com> Date: Thu, 11 Jan 2024 14:55:29 +0800 -Subject: [PATCH 15/31] Documentation: add documentation of Intel IPU6 driver +Subject: [PATCH 22/33] Documentation: add documentation of Intel IPU6 driver and hardware overview Add a documentation for an overview of IPU6 hardware and describe the main the components of IPU6 driver. Signed-off-by: Bingbu Cao <bingbu.cao@intel.com> -Link: https://lore.kernel.org/r/20240111065531.2418836-16-bingbu.cao@intel.com -Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- .../driver-api/media/drivers/index.rst | 1 + .../driver-api/media/drivers/ipu6.rst | 205 ++++++++++++++++++ @@ -14368,12 +15457,659 @@ index 000000000000..b6357155c13b + + -- -2.43.0 +2.43.2 + + +From d883f3386e7185d9404cb25e32df986656a4e82a Mon Sep 17 00:00:00 2001 +From: Bingbu Cao <bingbu.cao@intel.com> +Date: Thu, 11 Jan 2024 14:55:30 +0800 +Subject: [PATCH 23/33] media: ipu6/isys: support line-based metadata capture + support + +Some camera sensor can output the embedded data in specific +data type. This patch add the support for embedded data capture +in IPU6 IS driver. + +It's based on Sakari's line-based metadata capture support change: +<URL:https://git.linuxtv.org/sailus/media_tree.git/log/?h=metadata> + +Signed-off-by: Hongju Wang <hongju.wang@intel.com> +Signed-off-by: Bingbu Cao <bingbu.cao@intel.com> +--- + drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c | 5 + + .../media/pci/intel/ipu6/ipu6-isys-queue.c | 44 ++-- + .../media/pci/intel/ipu6/ipu6-isys-subdev.c | 5 + + .../media/pci/intel/ipu6/ipu6-isys-video.c | 201 +++++++++++++++--- + .../media/pci/intel/ipu6/ipu6-isys-video.h | 7 +- + 5 files changed, 216 insertions(+), 46 deletions(-) + +diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c b/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c +index ac9fa3e0d7ab..a6430d531129 100644 +--- a/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c ++++ b/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c +@@ -42,6 +42,11 @@ static const u32 csi2_supported_codes[] = { + MEDIA_BUS_FMT_SGBRG8_1X8, + MEDIA_BUS_FMT_SGRBG8_1X8, + MEDIA_BUS_FMT_SRGGB8_1X8, ++ MEDIA_BUS_FMT_META_8, ++ MEDIA_BUS_FMT_META_10, ++ MEDIA_BUS_FMT_META_12, ++ MEDIA_BUS_FMT_META_16, ++ MEDIA_BUS_FMT_META_24, + 0 + }; + +diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c b/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c +index 735d2d642d87..15fa7ed22b2f 100644 +--- a/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c ++++ b/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c +@@ -35,11 +35,14 @@ static int queue_setup(struct vb2_queue *q, unsigned int *num_buffers, + /* num_planes == 0: we're being called through VIDIOC_REQBUFS */ + if (!*num_planes) { + use_fmt = true; +- *num_planes = av->mpix.num_planes; ++ if (av->vfmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) ++ *num_planes = av->vfmt.fmt.pix_mp.num_planes; ++ else if (av->vfmt.type == V4L2_BUF_TYPE_META_CAPTURE) ++ *num_planes = 1; + } + + for (i = 0; i < *num_planes; i++) { +- size = av->mpix.plane_fmt[i].sizeimage; ++ size = ipu6_get_data_size(&av->vfmt, i); + if (use_fmt) { + sizes[i] = size; + } else if (sizes[i] < size) { +@@ -59,16 +62,17 @@ static int ipu6_isys_buf_prepare(struct vb2_buffer *vb) + struct ipu6_isys_queue *aq = vb2_queue_to_isys_queue(vb->vb2_queue); + struct ipu6_isys_video *av = ipu6_isys_queue_to_video(aq); + struct device *dev = &av->isys->adev->auxdev.dev; ++ u32 bytesperline = ipu6_get_bytes_per_line(&av->vfmt); ++ u32 height = ipu6_get_frame_height(&av->vfmt); ++ u32 size = ipu6_get_data_size(&av->vfmt, 0); + + dev_dbg(dev, "buffer: %s: configured size %u, buffer size %lu\n", +- av->vdev.name, av->mpix.plane_fmt[0].sizeimage, +- vb2_plane_size(vb, 0)); ++ av->vdev.name, size, vb2_plane_size(vb, 0)); + +- if (av->mpix.plane_fmt[0].sizeimage > vb2_plane_size(vb, 0)) ++ if (size > vb2_plane_size(vb, 0)) + return -EINVAL; + +- vb2_set_plane_payload(vb, 0, av->mpix.plane_fmt[0].bytesperline * +- av->mpix.height); ++ vb2_set_plane_payload(vb, 0, bytesperline * height); + vb->planes[0].data_offset = 0; + + return 0; +@@ -437,18 +441,22 @@ static int ipu6_isys_link_fmt_validate(struct ipu6_isys_queue *aq) + return ret; + } + +- if (format.width != av->mpix.width || +- format.height != av->mpix.height) { +- dev_dbg(dev, "wrong width or height %ux%u (%ux%u expected)\n", +- av->mpix.width, av->mpix.height, +- format.width, format.height); ++ if (format.width != ipu6_get_frame_width(&av->vfmt) || ++ format.height != ipu6_get_frame_height(&av->vfmt)) { ++ dev_err(dev, "wrong width or height %ux%u (%ux%u expected)\n", ++ ipu6_get_frame_width(&av->vfmt), ++ ipu6_get_frame_height(&av->vfmt), format.width, ++ format.height); + return -EINVAL; + } + +- if (format.field != av->mpix.field) { +- dev_dbg(dev, "wrong field value 0x%8.8x (0x%8.8x expected)\n", +- av->mpix.field, format.field); +- return -EINVAL; ++ if (av->vfmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { ++ if (format.field != av->vfmt.fmt.pix_mp.field) { ++ dev_dbg(dev, ++ "wrong field value 0x%8.8x (%8.8x expected)\n", ++ av->vfmt.fmt.pix_mp.field, format.field); ++ return -EINVAL; ++ } + } + + if (format.code != av->pfmt->code) { +@@ -531,8 +539,8 @@ static int start_streaming(struct vb2_queue *q, unsigned int count) + int nr_queues, ret; + + dev_dbg(dev, "stream: %s: width %u, height %u, css pixelformat %u\n", +- av->vdev.name, av->mpix.width, av->mpix.height, +- av->pfmt->css_pixelformat); ++ av->vdev.name, ipu6_get_frame_width(&av->vfmt), ++ ipu6_get_frame_height(&av->vfmt), av->pfmt->css_pixelformat); + + ret = ipu6_isys_setup_video(av, &source_entity, &nr_queues); + if (ret < 0) { +diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-subdev.c b/drivers/media/pci/intel/ipu6/ipu6-isys-subdev.c +index 510c5ca34f9f..3c9263ac02a3 100644 +--- a/drivers/media/pci/intel/ipu6/ipu6-isys-subdev.c ++++ b/drivers/media/pci/intel/ipu6/ipu6-isys-subdev.c +@@ -20,25 +20,30 @@ unsigned int ipu6_isys_mbus_code_to_bpp(u32 code) + { + switch (code) { + case MEDIA_BUS_FMT_RGB888_1X24: ++ case MEDIA_BUS_FMT_META_24: + return 24; + case MEDIA_BUS_FMT_RGB565_1X16: + case MEDIA_BUS_FMT_UYVY8_1X16: + case MEDIA_BUS_FMT_YUYV8_1X16: ++ case MEDIA_BUS_FMT_META_16: + return 16; + case MEDIA_BUS_FMT_SBGGR12_1X12: + case MEDIA_BUS_FMT_SGBRG12_1X12: + case MEDIA_BUS_FMT_SGRBG12_1X12: + case MEDIA_BUS_FMT_SRGGB12_1X12: ++ case MEDIA_BUS_FMT_META_12: + return 12; + case MEDIA_BUS_FMT_SBGGR10_1X10: + case MEDIA_BUS_FMT_SGBRG10_1X10: + case MEDIA_BUS_FMT_SGRBG10_1X10: + case MEDIA_BUS_FMT_SRGGB10_1X10: ++ case MEDIA_BUS_FMT_META_10: + return 10; + case MEDIA_BUS_FMT_SBGGR8_1X8: + case MEDIA_BUS_FMT_SGBRG8_1X8: + case MEDIA_BUS_FMT_SGRBG8_1X8: + case MEDIA_BUS_FMT_SRGGB8_1X8: ++ case MEDIA_BUS_FMT_META_8: + return 8; + default: + WARN_ON(1); +diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-video.c b/drivers/media/pci/intel/ipu6/ipu6-isys-video.c +index 847eac26bcd6..1a023bf1e1a6 100644 +--- a/drivers/media/pci/intel/ipu6/ipu6-isys-video.c ++++ b/drivers/media/pci/intel/ipu6/ipu6-isys-video.c +@@ -85,6 +85,11 @@ const struct ipu6_isys_pixelformat ipu6_isys_pfmts[] = { + IPU6_FW_ISYS_FRAME_FORMAT_RGB565}, + {V4L2_PIX_FMT_BGR24, 24, 24, MEDIA_BUS_FMT_RGB888_1X24, + IPU6_FW_ISYS_FRAME_FORMAT_RGBA888}, ++ {V4L2_META_FMT_GENERIC_8, 8, 8, MEDIA_BUS_FMT_META_8, 0}, ++ {V4L2_META_FMT_GENERIC_CSI2_10, 10, 10, MEDIA_BUS_FMT_META_10, 0}, ++ {V4L2_META_FMT_GENERIC_CSI2_12, 12, 12, MEDIA_BUS_FMT_META_12, 0}, ++ {V4L2_META_FMT_GENERIC_CSI2_16, 16, 16, MEDIA_BUS_FMT_META_16, 0}, ++ {V4L2_META_FMT_GENERIC_CSI2_24, 24, 24, MEDIA_BUS_FMT_META_24, 0}, + }; + + static int video_open(struct file *file) +@@ -181,12 +186,12 @@ static int ipu6_isys_vidioc_enum_framesizes(struct file *file, void *fh, + return 0; + } + +-static int vidioc_g_fmt_vid_cap_mplane(struct file *file, void *fh, +- struct v4l2_format *fmt) ++static int vidioc_get_format(struct file *file, void *fh, ++ struct v4l2_format *fmt) + { + struct ipu6_isys_video *av = video_drvdata(file); + +- fmt->fmt.pix_mp = av->mpix; ++ *fmt = av->vfmt; + + return 0; + } +@@ -245,30 +250,114 @@ ipu6_isys_video_try_fmt_vid_mplane(struct ipu6_isys_video *av, + return pfmt; + } + +-static int vidioc_s_fmt_vid_cap_mplane(struct file *file, void *fh, +- struct v4l2_format *f) ++static const struct ipu6_isys_pixelformat * ++ipu6_isys_video_try_fmt_meta(struct ipu6_isys_video *av, ++ struct v4l2_meta_format *meta) ++{ ++ const struct ipu6_isys_pixelformat *pfmt = ++ ipu6_isys_get_pixelformat(meta->dataformat); ++ ++ memset(&av->vfmt, 0, sizeof(av->vfmt)); ++ av->vfmt.type = V4L2_BUF_TYPE_META_CAPTURE; ++ av->pfmt = pfmt; ++ ++ meta->dataformat = pfmt->pixelformat; ++ meta->width = clamp(meta->width, IPU6_ISYS_MIN_WIDTH, ++ IPU6_ISYS_MAX_WIDTH); ++ meta->height = clamp(meta->height, IPU6_ISYS_MIN_HEIGHT, ++ IPU6_ISYS_MAX_HEIGHT); ++ ++ if (pfmt->bpp != pfmt->bpp_packed) ++ meta->bytesperline = meta->width * ++ DIV_ROUND_UP(pfmt->bpp, BITS_PER_BYTE); ++ else ++ meta->bytesperline = ++ DIV_ROUND_UP(meta->width * pfmt->bpp, BITS_PER_BYTE); ++ ++ meta->bytesperline = ALIGN(meta->bytesperline, av->isys->line_align); ++ meta->buffersize = ++ max(max(meta->buffersize, meta->bytesperline * meta->height + ++ max(meta->bytesperline, ++ av->isys->pdata->ipdata->isys_dma_overshoot)), 1U); ++ ++ return pfmt; ++} ++ ++static const struct ipu6_isys_pixelformat * ++ipu6_isys_video_try_fmt(struct ipu6_isys_video *av, struct v4l2_format *f) ++{ ++ if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) ++ return ipu6_isys_video_try_fmt_vid_mplane(av, &f->fmt.pix_mp); ++ else if (f->type == V4L2_BUF_TYPE_META_CAPTURE) ++ return ipu6_isys_video_try_fmt_meta(av, &f->fmt.meta); ++ else ++ return &ipu6_isys_pfmts[0]; ++} ++ ++static int vidioc_set_format(struct file *file, void *fh, ++ struct v4l2_format *f) + { + struct ipu6_isys_video *av = video_drvdata(file); + + if (av->aq.vbq.streaming) + return -EBUSY; + +- av->pfmt = ipu6_isys_video_try_fmt_vid_mplane(av, &f->fmt.pix_mp); +- av->mpix = f->fmt.pix_mp; ++ if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && ++ f->type != V4L2_BUF_TYPE_META_CAPTURE) ++ return -EINVAL; ++ ++ av->pfmt = ipu6_isys_video_try_fmt(av, f); ++ av->vfmt = *f; + + return 0; + } + +-static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *fh, +- struct v4l2_format *f) ++static int vidioc_try_format(struct file *file, void *fh, ++ struct v4l2_format *f) + { + struct ipu6_isys_video *av = video_drvdata(file); + +- ipu6_isys_video_try_fmt_vid_mplane(av, &f->fmt.pix_mp); ++ if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && ++ f->type != V4L2_BUF_TYPE_META_CAPTURE) ++ return -EINVAL; ++ ++ ipu6_isys_video_try_fmt(av, f); + + return 0; + } + ++static int vidioc_request_qbufs(struct file *file, void *priv, ++ struct v4l2_requestbuffers *p) ++{ ++ struct ipu6_isys_video *av = video_drvdata(file); ++ int ret; ++ ++ av->aq.vbq.is_multiplanar = V4L2_TYPE_IS_MULTIPLANAR(p->type); ++ av->aq.vbq.is_output = V4L2_TYPE_IS_OUTPUT(p->type); ++ ++ ret = vb2_queue_change_type(&av->aq.vbq, p->type); ++ if (ret) ++ return ret; ++ ++ return vb2_ioctl_reqbufs(file, priv, p); ++} ++ ++static int vidioc_create_bufs(struct file *file, void *priv, ++ struct v4l2_create_buffers *p) ++{ ++ struct ipu6_isys_video *av = video_drvdata(file); ++ int ret; ++ ++ av->aq.vbq.is_multiplanar = V4L2_TYPE_IS_MULTIPLANAR(p->format.type); ++ av->aq.vbq.is_output = V4L2_TYPE_IS_OUTPUT(p->format.type); ++ ++ ret = vb2_queue_change_type(&av->aq.vbq, p->format.type); ++ if (ret) ++ return ret; ++ ++ return vb2_ioctl_create_bufs(file, priv, p); ++} ++ + static int link_validate(struct media_link *link) + { + struct ipu6_isys_video *av = +@@ -279,6 +368,8 @@ static int link_validate(struct media_link *link) + struct v4l2_mbus_framefmt *s_fmt; + struct media_pad *s_pad; + u32 s_stream; ++ u32 height; ++ u32 width; + int ret = -EPIPE; + + if (!link->source->entity) +@@ -305,11 +396,13 @@ static int link_validate(struct media_link *link) + goto unlock; + } + +- if (s_fmt->width != av->mpix.width || +- s_fmt->height != av->mpix.height || s_fmt->code != av->pfmt->code) { ++ height = ipu6_get_frame_height(&av->vfmt); ++ width = ipu6_get_frame_width(&av->vfmt); ++ if (s_fmt->width != width || s_fmt->height != height || ++ s_fmt->code != av->pfmt->code) { + dev_err(dev, "format mismatch %dx%d,%x != %dx%d,%x\n", +- s_fmt->width, s_fmt->height, s_fmt->code, +- av->mpix.width, av->mpix.height, av->pfmt->code); ++ s_fmt->width, s_fmt->height, s_fmt->code, width, height, ++ av->pfmt->code); + goto unlock; + } + +@@ -393,10 +486,10 @@ static int ipu6_isys_fw_pin_cfg(struct ipu6_isys_video *av, + + output_pin = &cfg->output_pins[output_pins]; + output_pin->input_pin_id = input_pins; +- output_pin->output_res.width = av->mpix.width; +- output_pin->output_res.height = av->mpix.height; ++ output_pin->output_res.width = ipu6_get_frame_width(&av->vfmt); ++ output_pin->output_res.height = ipu6_get_frame_height(&av->vfmt); + +- output_pin->stride = av->mpix.plane_fmt[0].bytesperline; ++ output_pin->stride = ipu6_get_bytes_per_line(&av->vfmt); + if (av->pfmt->bpp != av->pfmt->bpp_packed) + output_pin->pt = IPU6_FW_ISYS_PIN_TYPE_RAW_SOC; + else +@@ -663,8 +756,8 @@ void ipu6_isys_configure_stream_watermark(struct ipu6_isys_video *av, + + esd = media_entity_to_v4l2_subdev(av->stream->source_entity); + +- av->watermark.width = av->mpix.width; +- av->watermark.height = av->mpix.height; ++ av->watermark.width = ipu6_get_frame_width(&av->vfmt); ++ av->watermark.height = ipu6_get_frame_height(&av->vfmt); + av->watermark.sram_gran_shift = isys->pdata->ipdata->sram_gran_shift; + av->watermark.sram_gran_size = isys->pdata->ipdata->sram_gran_size; + +@@ -992,11 +1085,15 @@ static const struct v4l2_ioctl_ops ioctl_ops_mplane = { + .vidioc_querycap = ipu6_isys_vidioc_querycap, + .vidioc_enum_fmt_vid_cap = ipu6_isys_vidioc_enum_fmt, + .vidioc_enum_framesizes = ipu6_isys_vidioc_enum_framesizes, +- .vidioc_g_fmt_vid_cap_mplane = vidioc_g_fmt_vid_cap_mplane, +- .vidioc_s_fmt_vid_cap_mplane = vidioc_s_fmt_vid_cap_mplane, +- .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt_vid_cap_mplane, +- .vidioc_reqbufs = vb2_ioctl_reqbufs, +- .vidioc_create_bufs = vb2_ioctl_create_bufs, ++ .vidioc_g_fmt_vid_cap_mplane = vidioc_get_format, ++ .vidioc_s_fmt_vid_cap_mplane = vidioc_set_format, ++ .vidioc_try_fmt_vid_cap_mplane = vidioc_try_format, ++ .vidioc_enum_fmt_meta_cap = ipu6_isys_vidioc_enum_fmt, ++ .vidioc_g_fmt_meta_cap = vidioc_get_format, ++ .vidioc_s_fmt_meta_cap = vidioc_set_format, ++ .vidioc_try_fmt_meta_cap = vidioc_try_format, ++ .vidioc_reqbufs = vidioc_request_qbufs, ++ .vidioc_create_bufs = vidioc_create_bufs, + .vidioc_prepare_buf = vb2_ioctl_prepare_buf, + .vidioc_querybuf = vb2_ioctl_querybuf, + .vidioc_qbuf = vb2_ioctl_qbuf, +@@ -1199,7 +1296,8 @@ int ipu6_isys_video_init(struct ipu6_isys_video *av) + + mutex_init(&av->mutex); + av->vdev.device_caps = V4L2_CAP_STREAMING | V4L2_CAP_IO_MC | +- V4L2_CAP_VIDEO_CAPTURE_MPLANE; ++ V4L2_CAP_VIDEO_CAPTURE_MPLANE | ++ V4L2_CAP_META_CAPTURE; + av->vdev.vfl_dir = VFL_DIR_RX; + + ret = ipu6_isys_queue_init(&av->aq); +@@ -1220,8 +1318,8 @@ int ipu6_isys_video_init(struct ipu6_isys_video *av) + av->vdev.queue = &av->aq.vbq; + av->vdev.lock = &av->mutex; + +- ipu6_isys_video_try_fmt_vid_mplane(av, &format.fmt.pix_mp); +- av->mpix = format.fmt.pix_mp; ++ ipu6_isys_video_try_fmt(av, &format); ++ av->vfmt = format; + + set_bit(V4L2_FL_USES_V4L2_FH, &av->vdev.flags); + video_set_drvdata(&av->vdev, av); +@@ -1251,3 +1349,52 @@ void ipu6_isys_video_cleanup(struct ipu6_isys_video *av) + media_entity_cleanup(&av->vdev.entity); + mutex_destroy(&av->mutex); + } ++ ++u32 ipu6_get_data_size(struct v4l2_format *vfmt, int plane) ++{ ++ if (vfmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) ++ return vfmt->fmt.pix_mp.plane_fmt[plane].sizeimage; ++ else if (vfmt->type == V4L2_BUF_TYPE_META_CAPTURE) ++ return vfmt->fmt.meta.buffersize; ++ ++ WARN_ON_ONCE(1); ++ ++ return 0; ++} ++ ++u32 ipu6_get_bytes_per_line(struct v4l2_format *vfmt) ++{ ++ if (vfmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) ++ return vfmt->fmt.pix_mp.plane_fmt[0].bytesperline; ++ else if (vfmt->type == V4L2_BUF_TYPE_META_CAPTURE) ++ return vfmt->fmt.meta.bytesperline; ++ ++ WARN_ON_ONCE(1); ++ ++ return 0; ++} ++ ++u32 ipu6_get_frame_width(struct v4l2_format *vfmt) ++{ ++ if (vfmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) ++ return vfmt->fmt.pix_mp.width; ++ else if (vfmt->type == V4L2_BUF_TYPE_META_CAPTURE) ++ return vfmt->fmt.meta.width; ++ ++ WARN_ON_ONCE(1); ++ ++ return 0; ++} ++ ++u32 ipu6_get_frame_height(struct v4l2_format *vfmt) ++{ ++ if (vfmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) ++ return vfmt->fmt.pix_mp.height; ++ else if (vfmt->type == V4L2_BUF_TYPE_META_CAPTURE) ++ return vfmt->fmt.meta.height; ++ ++ WARN_ON_ONCE(1); ++ ++ return 0; ++} ++ +diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-video.h b/drivers/media/pci/intel/ipu6/ipu6-isys-video.h +index 21cd33c7e277..2634ec0fd68b 100644 +--- a/drivers/media/pci/intel/ipu6/ipu6-isys-video.h ++++ b/drivers/media/pci/intel/ipu6/ipu6-isys-video.h +@@ -90,7 +90,7 @@ struct ipu6_isys_video { + struct mutex mutex; + struct media_pad pad; + struct video_device vdev; +- struct v4l2_pix_format_mplane mpix; ++ struct v4l2_format vfmt; + const struct ipu6_isys_pixelformat *pfmt; + struct ipu6_isys *isys; + struct ipu6_isys_stream *stream; +@@ -133,4 +133,9 @@ void ipu6_isys_configure_stream_watermark(struct ipu6_isys_video *av, + bool state); + void ipu6_isys_update_stream_watermark(struct ipu6_isys_video *av, bool state); + ++u32 ipu6_get_data_size(struct v4l2_format *vfmt, int plane); ++u32 ipu6_get_bytes_per_line(struct v4l2_format *vfmt); ++u32 ipu6_get_frame_width(struct v4l2_format *vfmt); ++u32 ipu6_get_frame_height(struct v4l2_format *vfmt); ++ + #endif /* IPU6_ISYS_VIDEO_H */ +-- +2.43.2 + + +From 9a6fb311b81433ebbd8e0769bed19958a6a5a5f6 Mon Sep 17 00:00:00 2001 +From: Bingbu Cao <bingbu.cao@intel.com> +Date: Thu, 11 Jan 2024 14:55:31 +0800 +Subject: [PATCH 24/33] media: ipu6/isys: support new v4l2 subdev state APIs + +Add support for the upcoming v4l2-subdev API changes in kernel 6.8. +This patch is based on Sakari's branch: +<URL:https://git.linuxtv.org/sailus/media_tree.git/log/?h=metadata> + +Signed-off-by: Hans de Goede <hdegoede@redhat.com> +Signed-off-by: Bingbu Cao <bingbu.cao@intel.com> +--- + drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c | 8 +++----- + .../media/pci/intel/ipu6/ipu6-isys-subdev.c | 19 +++++++++++-------- + .../media/pci/intel/ipu6/ipu6-isys-subdev.h | 2 -- + .../media/pci/intel/ipu6/ipu6-isys-video.c | 3 +-- + 4 files changed, 15 insertions(+), 17 deletions(-) -From 7103b8fabe3158d203b72036abc2a964687d46b8 Mon Sep 17 00:00:00 2001 +diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c b/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c +index a6430d531129..6f258cf92fc1 100644 +--- a/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c ++++ b/drivers/media/pci/intel/ipu6/ipu6-isys-csi2.c +@@ -403,12 +403,11 @@ static int ipu6_isys_csi2_set_sel(struct v4l2_subdev *sd, + if (!sink_ffmt) + return -EINVAL; + +- src_ffmt = v4l2_subdev_state_get_stream_format(state, sel->pad, +- sel->stream); ++ src_ffmt = v4l2_subdev_state_get_format(state, sel->pad, sel->stream); + if (!src_ffmt) + return -EINVAL; + +- crop = v4l2_subdev_state_get_stream_crop(state, sel->pad, sel->stream); ++ crop = v4l2_subdev_state_get_crop(state, sel->pad, sel->stream); + if (!crop) + return -EINVAL; + +@@ -453,7 +452,7 @@ static int ipu6_isys_csi2_get_sel(struct v4l2_subdev *sd, + if (!sink_ffmt) + return -EINVAL; + +- crop = v4l2_subdev_state_get_stream_crop(state, sel->pad, sel->stream); ++ crop = v4l2_subdev_state_get_crop(state, sel->pad, sel->stream); + if (!crop) + return -EINVAL; + +@@ -480,7 +479,6 @@ static const struct v4l2_subdev_video_ops csi2_sd_video_ops = { + }; + + static const struct v4l2_subdev_pad_ops csi2_sd_pad_ops = { +- .init_cfg = ipu6_isys_subdev_init_cfg, + .get_fmt = v4l2_subdev_get_fmt, + .set_fmt = ipu6_isys_subdev_set_fmt, + .get_selection = ipu6_isys_csi2_get_sel, +diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-subdev.c b/drivers/media/pci/intel/ipu6/ipu6-isys-subdev.c +index 3c9263ac02a3..aeccd6f93986 100644 +--- a/drivers/media/pci/intel/ipu6/ipu6-isys-subdev.c ++++ b/drivers/media/pci/intel/ipu6/ipu6-isys-subdev.c +@@ -156,8 +156,7 @@ int ipu6_isys_subdev_set_fmt(struct v4l2_subdev *sd, + format->format.field = V4L2_FIELD_NONE; + + /* Store the format and propagate it to the source pad. */ +- fmt = v4l2_subdev_state_get_stream_format(state, format->pad, +- format->stream); ++ fmt = v4l2_subdev_state_get_format(state, format->pad, format->stream); + if (!fmt) + return -EINVAL; + +@@ -182,8 +181,7 @@ int ipu6_isys_subdev_set_fmt(struct v4l2_subdev *sd, + if (ret) + return -EINVAL; + +- crop = v4l2_subdev_state_get_stream_crop(state, other_pad, +- other_stream); ++ crop = v4l2_subdev_state_get_crop(state, other_pad, other_stream); + /* reset crop */ + crop->left = 0; + crop->top = 0; +@@ -241,7 +239,7 @@ int ipu6_isys_get_stream_pad_fmt(struct v4l2_subdev *sd, u32 pad, u32 stream, + return -EINVAL; + + state = v4l2_subdev_lock_and_get_active_state(sd); +- fmt = v4l2_subdev_state_get_stream_format(state, pad, stream); ++ fmt = v4l2_subdev_state_get_format(state, pad, stream); + if (fmt) + *format = *fmt; + v4l2_subdev_unlock_state(state); +@@ -259,7 +257,7 @@ int ipu6_isys_get_stream_pad_crop(struct v4l2_subdev *sd, u32 pad, u32 stream, + return -EINVAL; + + state = v4l2_subdev_lock_and_get_active_state(sd); +- rect = v4l2_subdev_state_get_stream_crop(state, pad, stream); ++ rect = v4l2_subdev_state_get_crop(state, pad, stream); + if (rect) + *crop = *rect; + v4l2_subdev_unlock_state(state); +@@ -291,8 +289,8 @@ u32 ipu6_isys_get_src_stream_by_src_pad(struct v4l2_subdev *sd, u32 pad) + return source_stream; + } + +-int ipu6_isys_subdev_init_cfg(struct v4l2_subdev *sd, +- struct v4l2_subdev_state *state) ++static int ipu6_isys_subdev_init_state(struct v4l2_subdev *sd, ++ struct v4l2_subdev_state *state) + { + struct v4l2_subdev_route route = { + .sink_pad = 0, +@@ -317,6 +315,10 @@ int ipu6_isys_subdev_set_routing(struct v4l2_subdev *sd, + return subdev_set_routing(sd, state, routing); + } + ++static const struct v4l2_subdev_internal_ops ipu6_isys_subdev_internal_ops = { ++ .init_state = ipu6_isys_subdev_init_state, ++}; ++ + int ipu6_isys_subdev_init(struct ipu6_isys_subdev *asd, + const struct v4l2_subdev_ops *ops, + unsigned int nr_ctrls, +@@ -334,6 +336,7 @@ int ipu6_isys_subdev_init(struct ipu6_isys_subdev *asd, + V4L2_SUBDEV_FL_STREAMS; + asd->sd.owner = THIS_MODULE; + asd->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; ++ asd->sd.internal_ops = &ipu6_isys_subdev_internal_ops; + + asd->pad = devm_kcalloc(&asd->isys->adev->auxdev.dev, num_pads, + sizeof(*asd->pad), GFP_KERNEL); +diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-subdev.h b/drivers/media/pci/intel/ipu6/ipu6-isys-subdev.h +index adea2a55761d..f4e32b094b5b 100644 +--- a/drivers/media/pci/intel/ipu6/ipu6-isys-subdev.h ++++ b/drivers/media/pci/intel/ipu6/ipu6-isys-subdev.h +@@ -46,8 +46,6 @@ int ipu6_isys_get_stream_pad_fmt(struct v4l2_subdev *sd, u32 pad, u32 stream, + struct v4l2_mbus_framefmt *format); + int ipu6_isys_get_stream_pad_crop(struct v4l2_subdev *sd, u32 pad, u32 stream, + struct v4l2_rect *crop); +-int ipu6_isys_subdev_init_cfg(struct v4l2_subdev *sd, +- struct v4l2_subdev_state *state); + int ipu6_isys_subdev_set_routing(struct v4l2_subdev *sd, + struct v4l2_subdev_state *state, + enum v4l2_subdev_format_whence which, +diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-video.c b/drivers/media/pci/intel/ipu6/ipu6-isys-video.c +index 1a023bf1e1a6..62d4043fc2a1 100644 +--- a/drivers/media/pci/intel/ipu6/ipu6-isys-video.c ++++ b/drivers/media/pci/intel/ipu6/ipu6-isys-video.c +@@ -389,8 +389,7 @@ static int link_validate(struct media_link *link) + + v4l2_subdev_lock_state(s_state); + +- s_fmt = v4l2_subdev_state_get_stream_format(s_state, s_pad->index, +- s_stream); ++ s_fmt = v4l2_subdev_state_get_format(s_state, s_pad->index, s_stream); + if (!s_fmt) { + dev_err(dev, "failed to get source pad format\n"); + goto unlock; +-- +2.43.2 + + +From 53ca77877d2cc7ecc39bb0ef26a1871a1c26afd1 Mon Sep 17 00:00:00 2001 From: Hans de Goede <hdegoede@redhat.com> Date: Mon, 15 Jan 2024 15:57:06 +0100 -Subject: [PATCH 16/31] media: intel/ipu6: Disable packed bayer v4l2-buffer +Subject: [PATCH 25/33] media: intel/ipu6: Disable packed bayer v4l2-buffer formats on TGL Using CSI2 packing to store 10bpp bayer data in the v4l2-buffers does not @@ -14383,11 +16119,11 @@ Disable packed bayer formats on Tiger Lake for now. Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- - .../media/pci/intel/ipu6/ipu6-isys-video.c | 60 +++++++++++++------ - 1 file changed, 43 insertions(+), 17 deletions(-) + .../media/pci/intel/ipu6/ipu6-isys-video.c | 65 ++++++++++++------- + 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-video.c b/drivers/media/pci/intel/ipu6/ipu6-isys-video.c -index 847eac26bcd6..16d15f05a6dc 100644 +index 62d4043fc2a1..c971ffe0b948 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-isys-video.c +++ b/drivers/media/pci/intel/ipu6/ipu6-isys-video.c @@ -61,6 +61,17 @@ const struct ipu6_isys_pixelformat ipu6_isys_pfmts[] = { @@ -14408,7 +16144,7 @@ index 847eac26bcd6..16d15f05a6dc 100644 {V4L2_PIX_FMT_SBGGR12P, 12, 12, MEDIA_BUS_FMT_SBGGR12_1X12, IPU6_FW_ISYS_FRAME_FORMAT_RAW12}, {V4L2_PIX_FMT_SGBRG12P, 12, 12, MEDIA_BUS_FMT_SGBRG12_1X12, -@@ -77,14 +88,6 @@ const struct ipu6_isys_pixelformat ipu6_isys_pfmts[] = { +@@ -77,19 +88,6 @@ const struct ipu6_isys_pixelformat ipu6_isys_pfmts[] = { IPU6_FW_ISYS_FRAME_FORMAT_RAW10}, {V4L2_PIX_FMT_SRGGB10P, 10, 10, MEDIA_BUS_FMT_SRGGB10_1X10, IPU6_FW_ISYS_FRAME_FORMAT_RAW10}, @@ -14420,10 +16156,15 @@ index 847eac26bcd6..16d15f05a6dc 100644 - IPU6_FW_ISYS_FRAME_FORMAT_RGB565}, - {V4L2_PIX_FMT_BGR24, 24, 24, MEDIA_BUS_FMT_RGB888_1X24, - IPU6_FW_ISYS_FRAME_FORMAT_RGBA888}, +- {V4L2_META_FMT_GENERIC_8, 8, 8, MEDIA_BUS_FMT_META_8, 0}, +- {V4L2_META_FMT_GENERIC_CSI2_10, 10, 10, MEDIA_BUS_FMT_META_10, 0}, +- {V4L2_META_FMT_GENERIC_CSI2_12, 12, 12, MEDIA_BUS_FMT_META_12, 0}, +- {V4L2_META_FMT_GENERIC_CSI2_16, 16, 16, MEDIA_BUS_FMT_META_16, 0}, +- {V4L2_META_FMT_GENERIC_CSI2_24, 24, 24, MEDIA_BUS_FMT_META_24, 0}, }; static int video_open(struct file *file) -@@ -109,14 +112,27 @@ static int video_release(struct file *file) +@@ -114,14 +112,27 @@ static int video_release(struct file *file) return vb2_fop_release(file); } @@ -14454,7 +16195,7 @@ index 847eac26bcd6..16d15f05a6dc 100644 if (pfmt->pixelformat == pixelformat) return pfmt; } -@@ -138,24 +154,34 @@ int ipu6_isys_vidioc_querycap(struct file *file, void *fh, +@@ -143,24 +154,34 @@ int ipu6_isys_vidioc_querycap(struct file *file, void *fh, int ipu6_isys_vidioc_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f) { @@ -14462,13 +16203,13 @@ index 847eac26bcd6..16d15f05a6dc 100644 + struct ipu6_isys_video *av = video_drvdata(file); + const struct ipu6_isys_pixelformat *fmt; + unsigned int i, nfmts, found = 0; - -- if (f->index >= ARRAY_SIZE(ipu6_isys_pfmts)) ++ + nfmts = ARRAY_SIZE(ipu6_isys_pfmts); + /* Disable packed formats on TGL for now, TGL has 8 CSI ports */ + if (av->isys->pdata->ipdata->csi2.nports != 8) + nfmts += ARRAY_SIZE(ipu6_isys_pfmts_packed); -+ + +- if (f->index >= ARRAY_SIZE(ipu6_isys_pfmts)) + if (f->index >= nfmts) return -EINVAL; @@ -14496,12 +16237,13 @@ index 847eac26bcd6..16d15f05a6dc 100644 } found++; -- -2.43.0 +2.43.2 + -From ddd2826369e8ee4ba5b04502e1e20869590742da Mon Sep 17 00:00:00 2001 +From ed407043f03e9af2b09ab8ad449c2716ce7fde01 Mon Sep 17 00:00:00 2001 From: Hans de Goede <hdegoede@redhat.com> Date: Mon, 6 Nov 2023 12:13:42 +0100 -Subject: [PATCH 17/31] media: Add ov01a1s driver +Subject: [PATCH 26/33] media: Add ov01a1s driver Add ov01a1s driver from: https://github.com/intel/ipu6-drivers/ @@ -14515,10 +16257,10 @@ Signed-off-by: Hans de Goede <hdegoede@redhat.com> create mode 100644 drivers/media/i2c/ov01a1s.c diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig -index 59ee0ca2c978..d5a516e4fce2 100644 +index 4c3435921f19..08f934740980 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig -@@ -283,6 +283,15 @@ config VIDEO_OV01A10 +@@ -313,6 +313,15 @@ config VIDEO_OV01A10 To compile this driver as a module, choose M here: the module will be called ov01a10. @@ -14535,10 +16277,10 @@ index 59ee0ca2c978..d5a516e4fce2 100644 tristate "OmniVision OV02A10 sensor support" help diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile -index f5010f80a21f..ed5aa45e3506 100644 +index dfbe6448b549..53ea54c2cf01 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile -@@ -73,6 +73,7 @@ obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o +@@ -76,6 +76,7 @@ obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o obj-$(CONFIG_VIDEO_MT9V111) += mt9v111.o obj-$(CONFIG_VIDEO_OG01A1B) += og01a1b.o obj-$(CONFIG_VIDEO_OV01A10) += ov01a10.o @@ -15744,12 +17486,70 @@ index 000000000000..0dcce8b492b4 +MODULE_DESCRIPTION("OmniVision OV01A1S sensor driver"); +MODULE_LICENSE("GPL v2"); -- -2.43.0 +2.43.2 -From 07d707663a69f65c366d3ac75c2bf41749f33224 Mon Sep 17 00:00:00 2001 + +From 9f58ae728245ad7ac604737ab16781d7ccb2006e Mon Sep 17 00:00:00 2001 +From: Florian Klink <flokli@flokli.de> +Date: Sun, 17 Mar 2024 14:24:05 +0200 +Subject: [PATCH 27/33] ov01a1s.c: support Linux 6.8.0 + +Used https://github.com/intel/ipu6-drivers/pull/213 as an inspiration. +--- + drivers/media/i2c/ov01a1s.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/drivers/media/i2c/ov01a1s.c b/drivers/media/i2c/ov01a1s.c +index 0dcce8b492b4..923b12b2a948 100644 +--- a/drivers/media/i2c/ov01a1s.c ++++ b/drivers/media/i2c/ov01a1s.c +@@ -832,8 +832,10 @@ static int ov01a1s_set_format(struct v4l2_subdev *sd, + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { + #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 14, 0) + *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; +-#else ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 8, 0) + *v4l2_subdev_get_try_format(sd, sd_state, fmt->pad) = fmt->format; ++#else ++ *v4l2_subdev_state_get_format(sd_state, fmt->pad) = fmt->format; + #endif + } else { + ov01a1s->cur_mode = mode; +@@ -871,9 +873,11 @@ static int ov01a1s_get_format(struct v4l2_subdev *sd, + #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 14, 0) + fmt->format = *v4l2_subdev_get_try_format(&ov01a1s->sd, cfg, + fmt->pad); +-#else ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 8, 0) + fmt->format = *v4l2_subdev_get_try_format(&ov01a1s->sd, + sd_state, fmt->pad); ++#else ++ fmt->format = *v4l2_subdev_state_get_format(sd_state, fmt->pad); + #endif + else + ov01a1s_update_pad_format(ov01a1s->cur_mode, &fmt->format); +@@ -929,9 +933,12 @@ static int ov01a1s_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) + #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 14, 0) + ov01a1s_update_pad_format(&supported_modes[0], + v4l2_subdev_get_try_format(sd, fh->pad, 0)); +-#else ++#elif LINUX_VERSION_CODE < KERNEL_VERSION(6, 8, 0) + ov01a1s_update_pad_format(&supported_modes[0], + v4l2_subdev_get_try_format(sd, fh->state, 0)); ++#else ++ ov01a1s_update_pad_format(&supported_modes[0], ++ v4l2_subdev_state_get_format(fh->state, 0)); + #endif + mutex_unlock(&ov01a1s->mutex); + +-- +2.43.2 + + +From 80bee1ca899ebfa4126d1e69ea821a2c30aba00c Mon Sep 17 00:00:00 2001 From: Hans de Goede <hdegoede@redhat.com> Date: Mon, 6 Nov 2023 12:33:56 +0100 -Subject: [PATCH 18/31] media: ov01a1s: Remove non upstream iVSC support +Subject: [PATCH 28/33] media: ov01a1s: Remove non upstream iVSC support Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- @@ -15757,7 +17557,7 @@ Signed-off-by: Hans de Goede <hdegoede@redhat.com> 1 file changed, 71 deletions(-) diff --git a/drivers/media/i2c/ov01a1s.c b/drivers/media/i2c/ov01a1s.c -index 0dcce8b492b4..c97c1a661022 100644 +index 923b12b2a948..22b406bdeae9 100644 --- a/drivers/media/i2c/ov01a1s.c +++ b/drivers/media/i2c/ov01a1s.c @@ -17,9 +17,6 @@ @@ -15883,7 +17683,7 @@ index 0dcce8b492b4..c97c1a661022 100644 return ret; } -@@ -1044,18 +985,6 @@ static int ov01a1s_parse_power(struct ov01a1s *ov01a1s) +@@ -1051,18 +992,6 @@ static int ov01a1s_parse_power(struct ov01a1s *ov01a1s) { int ret = 0; @@ -15903,915 +17703,13 @@ index 0dcce8b492b4..c97c1a661022 100644 ret = ov01a1s_parse_gpio(ov01a1s); #elif IS_ENABLED(CONFIG_POWER_CTRL_LOGIC) -- -2.43.0 - -From 3f59512af8a39b5d22694e2996d8441d5e723423 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Mon, 4 Dec 2023 13:39:38 +0100 -Subject: [PATCH 19/31] media: ov2740: Add support for reset GPIO - -On some ACPI platforms, such as Chromebooks the ACPI methods to -change the power-state (_PS0 and _PS3) fully take care of powering -on/off the sensor. - -On other ACPI platforms, such as e.g. various ThinkPad models with -IPU6 + ov2740 sensor, the sensor driver must control the reset GPIO -and the sensor's clock itself. - -Add support for having the driver control an optional reset GPIO. - -Reviewed-by: Bingbu Cao <bingbu.cao@intel.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> -Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> ---- - drivers/media/i2c/ov2740.c | 48 ++++++++++++++++++++++++++++++++++++-- - 1 file changed, 46 insertions(+), 2 deletions(-) - -diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c -index 24e468485fbf..e5f9569a229d 100644 ---- a/drivers/media/i2c/ov2740.c -+++ b/drivers/media/i2c/ov2740.c -@@ -4,6 +4,7 @@ - #include <asm/unaligned.h> - #include <linux/acpi.h> - #include <linux/delay.h> -+#include <linux/gpio/consumer.h> - #include <linux/i2c.h> - #include <linux/module.h> - #include <linux/pm_runtime.h> -@@ -333,6 +334,9 @@ struct ov2740 { - struct v4l2_ctrl *hblank; - struct v4l2_ctrl *exposure; - -+ /* GPIOs, clocks */ -+ struct gpio_desc *reset_gpio; -+ - /* Current mode */ - const struct ov2740_mode *cur_mode; - -@@ -1058,6 +1062,26 @@ static int ov2740_register_nvmem(struct i2c_client *client, - return 0; - } - -+static int ov2740_suspend(struct device *dev) -+{ -+ struct v4l2_subdev *sd = dev_get_drvdata(dev); -+ struct ov2740 *ov2740 = to_ov2740(sd); -+ -+ gpiod_set_value_cansleep(ov2740->reset_gpio, 1); -+ return 0; -+} -+ -+static int ov2740_resume(struct device *dev) -+{ -+ struct v4l2_subdev *sd = dev_get_drvdata(dev); -+ struct ov2740 *ov2740 = to_ov2740(sd); -+ -+ gpiod_set_value_cansleep(ov2740->reset_gpio, 0); -+ msleep(20); -+ -+ return 0; -+} -+ - static int ov2740_probe(struct i2c_client *client) - { - struct device *dev = &client->dev; -@@ -1073,12 +1097,24 @@ static int ov2740_probe(struct i2c_client *client) - if (!ov2740) - return -ENOMEM; - -+ ov2740->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); -+ if (IS_ERR(ov2740->reset_gpio)) -+ return dev_err_probe(dev, PTR_ERR(ov2740->reset_gpio), -+ "failed to get reset GPIO\n"); -+ - v4l2_i2c_subdev_init(&ov2740->sd, client, &ov2740_subdev_ops); - full_power = acpi_dev_state_d0(&client->dev); - if (full_power) { -- ret = ov2740_identify_module(ov2740); -+ /* ACPI does not always clear the reset GPIO / enable the clock */ -+ ret = ov2740_resume(dev); - if (ret) -- return dev_err_probe(dev, ret, "failed to find sensor\n"); -+ return dev_err_probe(dev, ret, "failed to power on sensor\n"); -+ -+ ret = ov2740_identify_module(ov2740); -+ if (ret) { -+ dev_err_probe(dev, ret, "failed to find sensor\n"); -+ goto probe_error_power_off; -+ } - } - - ov2740->cur_mode = &supported_modes[0]; -@@ -1132,9 +1168,16 @@ static int ov2740_probe(struct i2c_client *client) - probe_error_v4l2_ctrl_handler_free: - v4l2_ctrl_handler_free(ov2740->sd.ctrl_handler); - -+probe_error_power_off: -+ if (full_power) -+ ov2740_suspend(dev); -+ - return ret; - } - -+static DEFINE_RUNTIME_DEV_PM_OPS(ov2740_pm_ops, ov2740_suspend, ov2740_resume, -+ NULL); -+ - static const struct acpi_device_id ov2740_acpi_ids[] = { - {"INT3474"}, - {} -@@ -1146,6 +1189,7 @@ static struct i2c_driver ov2740_i2c_driver = { - .driver = { - .name = "ov2740", - .acpi_match_table = ov2740_acpi_ids, -+ .pm = pm_sleep_ptr(&ov2740_pm_ops), - }, - .probe = ov2740_probe, - .remove = ov2740_remove, --- -2.43.0 - -From ddde5ef9b19c4e4755be62c588209db986e57400 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Mon, 4 Dec 2023 13:39:39 +0100 -Subject: [PATCH 20/31] media: ov2740: Add support for external clock - -On some ACPI platforms, such as Chromebooks the ACPI methods to -change the power-state (_PS0 and _PS3) fully take care of powering -on/off the sensor. - -On other ACPI platforms, such as e.g. various ThinkPad models with -IPU6 + ov2740 sensor, the sensor driver must control the reset GPIO -and the sensor's clock itself. - -Add support for having the driver control an optional clock. - -Reviewed-by: Bingbu Cao <bingbu.cao@intel.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> -Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> ---- - drivers/media/i2c/ov2740.c | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - -diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c -index e5f9569a229d..0396e40419ca 100644 ---- a/drivers/media/i2c/ov2740.c -+++ b/drivers/media/i2c/ov2740.c -@@ -3,6 +3,7 @@ - - #include <asm/unaligned.h> - #include <linux/acpi.h> -+#include <linux/clk.h> - #include <linux/delay.h> - #include <linux/gpio/consumer.h> - #include <linux/i2c.h> -@@ -336,6 +337,7 @@ struct ov2740 { - - /* GPIOs, clocks */ - struct gpio_desc *reset_gpio; -+ struct clk *clk; - - /* Current mode */ - const struct ov2740_mode *cur_mode; -@@ -1068,6 +1070,7 @@ static int ov2740_suspend(struct device *dev) - struct ov2740 *ov2740 = to_ov2740(sd); - - gpiod_set_value_cansleep(ov2740->reset_gpio, 1); -+ clk_disable_unprepare(ov2740->clk); - return 0; - } - -@@ -1075,6 +1078,11 @@ static int ov2740_resume(struct device *dev) - { - struct v4l2_subdev *sd = dev_get_drvdata(dev); - struct ov2740 *ov2740 = to_ov2740(sd); -+ int ret; -+ -+ ret = clk_prepare_enable(ov2740->clk); -+ if (ret) -+ return ret; - - gpiod_set_value_cansleep(ov2740->reset_gpio, 0); - msleep(20); -@@ -1102,6 +1110,11 @@ static int ov2740_probe(struct i2c_client *client) - return dev_err_probe(dev, PTR_ERR(ov2740->reset_gpio), - "failed to get reset GPIO\n"); - -+ ov2740->clk = devm_clk_get_optional(dev, "clk"); -+ if (IS_ERR(ov2740->clk)) -+ return dev_err_probe(dev, PTR_ERR(ov2740->clk), -+ "failed to get clock\n"); -+ - v4l2_i2c_subdev_init(&ov2740->sd, client, &ov2740_subdev_ops); - full_power = acpi_dev_state_d0(&client->dev); - if (full_power) { --- -2.43.0 - -From be361f059239a5444a436a73888cc1c1665d90a7 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Mon, 4 Dec 2023 13:39:40 +0100 -Subject: [PATCH 21/31] media: ov2740: Move fwnode_graph_get_next_endpoint() - call up - -If the bridge has not yet setup the fwnode-graph then -the fwnode_property_read_u32("clock-frequency") call will fail. +2.43.2 -Move the fwnode_graph_get_next_endpoint() call to above reading -the clock-frequency. - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> -Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> ---- - drivers/media/i2c/ov2740.c | 26 +++++++++++++++++--------- - 1 file changed, 17 insertions(+), 9 deletions(-) - -diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c -index 0396e40419ca..35b2f43bd3e5 100644 ---- a/drivers/media/i2c/ov2740.c -+++ b/drivers/media/i2c/ov2740.c -@@ -926,19 +926,27 @@ static int ov2740_check_hwcfg(struct device *dev) - int ret; - unsigned int i, j; - -- ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk); -- if (ret) -- return ret; -- -- if (mclk != OV2740_MCLK) -- return dev_err_probe(dev, -EINVAL, -- "external clock %d is not supported\n", -- mclk); -- -+ /* -+ * Sometimes the fwnode graph is initialized by the bridge driver, -+ * wait for this. -+ */ - ep = fwnode_graph_get_next_endpoint(fwnode, NULL); - if (!ep) - return -EPROBE_DEFER; - -+ ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk); -+ if (ret) { -+ fwnode_handle_put(ep); -+ return ret; -+ } -+ -+ if (mclk != OV2740_MCLK) { -+ fwnode_handle_put(ep); -+ return dev_err_probe(dev, -EINVAL, -+ "external clock %d is not supported\n", -+ mclk); -+ } -+ - ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg); - fwnode_handle_put(ep); - if (ret) --- -2.43.0 -From 4d499411eccc2db42d0d21365039f479c9367214 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Mon, 4 Dec 2023 13:39:41 +0100 -Subject: [PATCH 22/31] media: ov2740: Improve ov2740_check_hwcfg() error - reporting - -Make ov2740_check_hwcfg() report an error on failure in all error paths, -so that it is always clear why the probe() failed. - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> -Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> ---- - drivers/media/i2c/ov2740.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c -index 35b2f43bd3e5..87176948f766 100644 ---- a/drivers/media/i2c/ov2740.c -+++ b/drivers/media/i2c/ov2740.c -@@ -937,7 +937,8 @@ static int ov2740_check_hwcfg(struct device *dev) - ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk); - if (ret) { - fwnode_handle_put(ep); -- return ret; -+ return dev_err_probe(dev, ret, -+ "reading clock-frequency property\n"); - } - - if (mclk != OV2740_MCLK) { -@@ -950,7 +951,7 @@ static int ov2740_check_hwcfg(struct device *dev) - ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg); - fwnode_handle_put(ep); - if (ret) -- return ret; -+ return dev_err_probe(dev, ret, "parsing endpoint failed\n"); - - if (bus_cfg.bus.mipi_csi2.num_data_lanes != OV2740_DATA_LANES) { - ret = dev_err_probe(dev, -EINVAL, --- -2.43.0 - -From 28c5209404274ded2f2fb2c93611da32e03a2538 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Mon, 4 Dec 2023 13:39:43 +0100 -Subject: [PATCH 24/31] media: ov2740: Check hwcfg after allocating the ov2740 - struct - -Alloc ov2740_data and set up the drvdata pointer before calling -ov2740_check_hwcfg(). - -This is a preparation patch to allow ov2740_check_hwcfg() -to store some of the parsed data in the ov2740 struct. - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> -Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> ---- - drivers/media/i2c/ov2740.c | 11 ++++++----- - 1 file changed, 6 insertions(+), 5 deletions(-) - -diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c -index a646be427ab2..28f4659a6bfb 100644 ---- a/drivers/media/i2c/ov2740.c -+++ b/drivers/media/i2c/ov2740.c -@@ -1095,14 +1095,16 @@ static int ov2740_probe(struct i2c_client *client) - bool full_power; - int ret; - -- ret = ov2740_check_hwcfg(&client->dev); -- if (ret) -- return dev_err_probe(dev, ret, "failed to check HW configuration\n"); -- - ov2740 = devm_kzalloc(&client->dev, sizeof(*ov2740), GFP_KERNEL); - if (!ov2740) - return -ENOMEM; - -+ v4l2_i2c_subdev_init(&ov2740->sd, client, &ov2740_subdev_ops); -+ -+ ret = ov2740_check_hwcfg(dev); -+ if (ret) -+ return dev_err_probe(dev, ret, "failed to check HW configuration\n"); -+ - ov2740->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); - if (IS_ERR(ov2740->reset_gpio)) - return dev_err_probe(dev, PTR_ERR(ov2740->reset_gpio), -@@ -1113,7 +1115,6 @@ static int ov2740_probe(struct i2c_client *client) - return dev_err_probe(dev, PTR_ERR(ov2740->clk), - "failed to get clock\n"); - -- v4l2_i2c_subdev_init(&ov2740->sd, client, &ov2740_subdev_ops); - full_power = acpi_dev_state_d0(&client->dev); - if (full_power) { - /* ACPI does not always clear the reset GPIO / enable the clock */ --- -2.43.0 - -From 5e06f2a1cbbaf0ceffd62475ad4170f7224372be Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Mon, 4 Dec 2023 13:39:44 +0100 -Subject: [PATCH 25/31] media: ov2740: Add support for 180 MHz link frequency - -On various Lenovo Thinkpad models with an ov2740 sensor the 360 MHz -link frequency is not supported. - -Add support for 180 MHz link frequency, even though this has half the -pixel clock, this supports the same framerate by using half the VTS value -(significantly reducing the amount of empty lines send during vblank). - -Normally if there are multiple link-frequencies then the sensor driver -choses the lowest link-frequency still usable for the chosen resolution. - -In this case the board supports only 1 link-frequency. Which frequency -is supported is checked in ov2740_check_hwcfg() and then a different -set of supported_modes (using only the supported link-freq) is selected. - -The register settings for this were taken from the ov2740 sensor driver -in the out of tree IPU6 driver: - -https://github.com/intel/ipu6-drivers/ - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> -Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> ---- - drivers/media/i2c/ov2740.c | 263 +++++++++++++++++++++++++++++++++---- - 1 file changed, 239 insertions(+), 24 deletions(-) - -diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c -index 28f4659a6bfb..85629992d3aa 100644 ---- a/drivers/media/i2c/ov2740.c -+++ b/drivers/media/i2c/ov2740.c -@@ -16,6 +16,7 @@ - #include <media/v4l2-fwnode.h> - - #define OV2740_LINK_FREQ_360MHZ 360000000ULL -+#define OV2740_LINK_FREQ_180MHZ 180000000ULL - #define OV2740_SCLK 72000000LL - #define OV2740_MCLK 19200000 - #define OV2740_DATA_LANES 2 -@@ -30,9 +31,6 @@ - - /* vertical-timings from sensor */ - #define OV2740_REG_VTS 0x380e --#define OV2740_VTS_DEF 0x088a --#define OV2740_VTS_MIN 0x0460 --#define OV2740_VTS_MAX 0x7fff - - /* horizontal-timings from sensor */ - #define OV2740_REG_HTS 0x380c -@@ -86,6 +84,7 @@ struct nvm_data { - - enum { - OV2740_LINK_FREQ_360MHZ_INDEX, -+ OV2740_LINK_FREQ_180MHZ_INDEX, - }; - - struct ov2740_reg { -@@ -118,6 +117,9 @@ struct ov2740_mode { - /* Min vertical timining size */ - u32 vts_min; - -+ /* Max vertical timining size */ -+ u32 vts_max; -+ - /* Link frequency needed for this resolution */ - u32 link_freq_index; - -@@ -134,7 +136,18 @@ static const struct ov2740_reg mipi_data_rate_720mbps[] = { - {0x0312, 0x11}, - }; - --static const struct ov2740_reg mode_1932x1092_regs[] = { -+static const struct ov2740_reg mipi_data_rate_360mbps[] = { -+ {0x0103, 0x01}, -+ {0x0302, 0x4b}, -+ {0x0303, 0x01}, -+ {0x030d, 0x4b}, -+ {0x030e, 0x02}, -+ {0x030a, 0x01}, -+ {0x0312, 0x11}, -+ {0x4837, 0x2c}, -+}; -+ -+static const struct ov2740_reg mode_1932x1092_regs_360mhz[] = { - {0x3000, 0x00}, - {0x3018, 0x32}, - {0x3031, 0x0a}, -@@ -287,6 +300,159 @@ static const struct ov2740_reg mode_1932x1092_regs[] = { - {0x3813, 0x01}, - }; - -+static const struct ov2740_reg mode_1932x1092_regs_180mhz[] = { -+ {0x3000, 0x00}, -+ {0x3018, 0x32}, /* 0x32 for 2 lanes, 0x12 for 1 lane */ -+ {0x3031, 0x0a}, -+ {0x3080, 0x08}, -+ {0x3083, 0xB4}, -+ {0x3103, 0x00}, -+ {0x3104, 0x01}, -+ {0x3106, 0x01}, -+ {0x3500, 0x00}, -+ {0x3501, 0x44}, -+ {0x3502, 0x40}, -+ {0x3503, 0x88}, -+ {0x3507, 0x00}, -+ {0x3508, 0x00}, -+ {0x3509, 0x80}, -+ {0x350c, 0x00}, -+ {0x350d, 0x80}, -+ {0x3510, 0x00}, -+ {0x3511, 0x00}, -+ {0x3512, 0x20}, -+ {0x3632, 0x00}, -+ {0x3633, 0x10}, -+ {0x3634, 0x10}, -+ {0x3635, 0x10}, -+ {0x3645, 0x13}, -+ {0x3646, 0x81}, -+ {0x3636, 0x10}, -+ {0x3651, 0x0a}, -+ {0x3656, 0x02}, -+ {0x3659, 0x04}, -+ {0x365a, 0xda}, -+ {0x365b, 0xa2}, -+ {0x365c, 0x04}, -+ {0x365d, 0x1d}, -+ {0x365e, 0x1a}, -+ {0x3662, 0xd7}, -+ {0x3667, 0x78}, -+ {0x3669, 0x0a}, -+ {0x366a, 0x92}, -+ {0x3700, 0x54}, -+ {0x3702, 0x10}, -+ {0x3706, 0x42}, -+ {0x3709, 0x30}, -+ {0x370b, 0xc2}, -+ {0x3714, 0x63}, -+ {0x3715, 0x01}, -+ {0x3716, 0x00}, -+ {0x371a, 0x3e}, -+ {0x3732, 0x0e}, -+ {0x3733, 0x10}, -+ {0x375f, 0x0e}, -+ {0x3768, 0x30}, -+ {0x3769, 0x44}, -+ {0x376a, 0x22}, -+ {0x377b, 0x20}, -+ {0x377c, 0x00}, -+ {0x377d, 0x0c}, -+ {0x3798, 0x00}, -+ {0x37a1, 0x55}, -+ {0x37a8, 0x6d}, -+ {0x37c2, 0x04}, -+ {0x37c5, 0x00}, -+ {0x37c8, 0x00}, -+ {0x3800, 0x00}, -+ {0x3801, 0x00}, -+ {0x3802, 0x00}, -+ {0x3803, 0x00}, -+ {0x3804, 0x07}, -+ {0x3805, 0x8f}, -+ {0x3806, 0x04}, -+ {0x3807, 0x47}, -+ {0x3808, 0x07}, -+ {0x3809, 0x88}, -+ {0x380a, 0x04}, -+ {0x380b, 0x40}, -+ {0x380c, 0x08}, -+ {0x380d, 0x70}, -+ {0x380e, 0x04}, -+ {0x380f, 0x56}, -+ {0x3810, 0x00}, -+ {0x3811, 0x04}, -+ {0x3812, 0x00}, -+ {0x3813, 0x04}, -+ {0x3814, 0x01}, -+ {0x3815, 0x01}, -+ {0x3820, 0x80}, -+ {0x3821, 0x46}, -+ {0x3822, 0x84}, -+ {0x3829, 0x00}, -+ {0x382a, 0x01}, -+ {0x382b, 0x01}, -+ {0x3830, 0x04}, -+ {0x3836, 0x01}, -+ {0x3837, 0x08}, -+ {0x3839, 0x01}, -+ {0x383a, 0x00}, -+ {0x383b, 0x08}, -+ {0x383c, 0x00}, -+ {0x3f0b, 0x00}, -+ {0x4001, 0x20}, -+ {0x4009, 0x07}, -+ {0x4003, 0x10}, -+ {0x4010, 0xe0}, -+ {0x4016, 0x00}, -+ {0x4017, 0x10}, -+ {0x4044, 0x02}, -+ {0x4304, 0x08}, -+ {0x4307, 0x30}, -+ {0x4320, 0x80}, -+ {0x4322, 0x00}, -+ {0x4323, 0x00}, -+ {0x4324, 0x00}, -+ {0x4325, 0x00}, -+ {0x4326, 0x00}, -+ {0x4327, 0x00}, -+ {0x4328, 0x00}, -+ {0x4329, 0x00}, -+ {0x432c, 0x03}, -+ {0x432d, 0x81}, -+ {0x4501, 0x84}, -+ {0x4502, 0x40}, -+ {0x4503, 0x18}, -+ {0x4504, 0x04}, -+ {0x4508, 0x02}, -+ {0x4601, 0x10}, -+ {0x4800, 0x00}, -+ {0x4816, 0x52}, -+ {0x5000, 0x73}, /* 0x7f enable DPC */ -+ {0x5001, 0x00}, -+ {0x5005, 0x38}, -+ {0x501e, 0x0d}, -+ {0x5040, 0x00}, -+ {0x5901, 0x00}, -+ {0x3800, 0x00}, -+ {0x3801, 0x00}, -+ {0x3802, 0x00}, -+ {0x3803, 0x00}, -+ {0x3804, 0x07}, -+ {0x3805, 0x8f}, -+ {0x3806, 0x04}, -+ {0x3807, 0x47}, -+ {0x3808, 0x07}, -+ {0x3809, 0x8c}, -+ {0x380a, 0x04}, -+ {0x380b, 0x44}, -+ {0x3810, 0x00}, -+ {0x3811, 0x00}, -+ {0x3812, 0x00}, -+ {0x3813, 0x01}, -+ {0x4003, 0x40}, /* set Black level to 0x40 */ -+}; -+ - static const char * const ov2740_test_pattern_menu[] = { - "Disabled", - "Color Bar", -@@ -297,6 +463,7 @@ static const char * const ov2740_test_pattern_menu[] = { - - static const s64 link_freq_menu_items[] = { - OV2740_LINK_FREQ_360MHZ, -+ OV2740_LINK_FREQ_180MHZ, - }; - - static const struct ov2740_link_freq_config link_freq_configs[] = { -@@ -306,23 +473,46 @@ static const struct ov2740_link_freq_config link_freq_configs[] = { - .regs = mipi_data_rate_720mbps, - } - }, -+ [OV2740_LINK_FREQ_180MHZ_INDEX] = { -+ .reg_list = { -+ .num_of_regs = ARRAY_SIZE(mipi_data_rate_360mbps), -+ .regs = mipi_data_rate_360mbps, -+ } -+ }, - }; - --static const struct ov2740_mode supported_modes[] = { -+static const struct ov2740_mode supported_modes_360mhz[] = { - { - .width = 1932, - .height = 1092, - .hts = 2160, -- .vts_def = OV2740_VTS_DEF, -- .vts_min = OV2740_VTS_MIN, -+ .vts_min = 1120, -+ .vts_def = 2186, -+ .vts_max = 32767, - .reg_list = { -- .num_of_regs = ARRAY_SIZE(mode_1932x1092_regs), -- .regs = mode_1932x1092_regs, -+ .num_of_regs = ARRAY_SIZE(mode_1932x1092_regs_360mhz), -+ .regs = mode_1932x1092_regs_360mhz, - }, - .link_freq_index = OV2740_LINK_FREQ_360MHZ_INDEX, - }, - }; - -+static const struct ov2740_mode supported_modes_180mhz[] = { -+ { -+ .width = 1932, -+ .height = 1092, -+ .hts = 2160, -+ .vts_min = 1110, -+ .vts_def = 1110, -+ .vts_max = 2047, -+ .reg_list = { -+ .num_of_regs = ARRAY_SIZE(mode_1932x1092_regs_180mhz), -+ .regs = mode_1932x1092_regs_180mhz, -+ }, -+ .link_freq_index = OV2740_LINK_FREQ_180MHZ_INDEX, -+ }, -+}; -+ - struct ov2740 { - struct v4l2_subdev sd; - struct media_pad pad; -@@ -345,6 +535,10 @@ struct ov2740 { - /* NVM data inforamtion */ - struct nvm_data *nvm; - -+ /* Supported modes */ -+ const struct ov2740_mode *supported_modes; -+ int supported_modes_count; -+ - /* True if the device has been identified */ - bool identified; - }; -@@ -589,7 +783,7 @@ static int ov2740_init_controls(struct ov2740 *ov2740) - pixel_rate, 1, pixel_rate); - - vblank_min = cur_mode->vts_min - cur_mode->height; -- vblank_max = OV2740_VTS_MAX - cur_mode->height; -+ vblank_max = cur_mode->vts_max - cur_mode->height; - vblank_default = cur_mode->vts_def - cur_mode->height; - ov2740->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops, - V4L2_CID_VBLANK, vblank_min, -@@ -816,10 +1010,10 @@ static int ov2740_set_format(struct v4l2_subdev *sd, - const struct ov2740_mode *mode; - s32 vblank_def, h_blank; - -- mode = v4l2_find_nearest_size(supported_modes, -- ARRAY_SIZE(supported_modes), width, -- height, fmt->format.width, -- fmt->format.height); -+ mode = v4l2_find_nearest_size(ov2740->supported_modes, -+ ov2740->supported_modes_count, -+ width, height, -+ fmt->format.width, fmt->format.height); - - ov2740_update_pad_format(mode, &fmt->format); - *v4l2_subdev_get_pad_format(sd, sd_state, fmt->pad) = fmt->format; -@@ -836,7 +1030,7 @@ static int ov2740_set_format(struct v4l2_subdev *sd, - vblank_def = mode->vts_def - mode->height; - __v4l2_ctrl_modify_range(ov2740->vblank, - mode->vts_min - mode->height, -- OV2740_VTS_MAX - mode->height, 1, vblank_def); -+ mode->vts_max - mode->height, 1, vblank_def); - __v4l2_ctrl_s_ctrl(ov2740->vblank, vblank_def); - h_blank = mode->hts - mode->width; - __v4l2_ctrl_modify_range(ov2740->hblank, h_blank, h_blank, 1, h_blank); -@@ -860,7 +1054,10 @@ static int ov2740_enum_frame_size(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_frame_size_enum *fse) - { -- if (fse->index >= ARRAY_SIZE(supported_modes)) -+ struct ov2740 *ov2740 = to_ov2740(sd); -+ const struct ov2740_mode *supported_modes = ov2740->supported_modes; -+ -+ if (fse->index >= ov2740->supported_modes_count) - return -EINVAL; - - if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10) -@@ -877,9 +1074,10 @@ static int ov2740_enum_frame_size(struct v4l2_subdev *sd, - static int ov2740_init_cfg(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state) - { -- ov2740_update_pad_format(&supported_modes[0], -- v4l2_subdev_get_pad_format(sd, sd_state, 0)); -+ struct ov2740 *ov2740 = to_ov2740(sd); - -+ ov2740_update_pad_format(&ov2740->supported_modes[0], -+ v4l2_subdev_get_pad_format(sd, sd_state, 0)); - return 0; - } - -@@ -906,6 +1104,8 @@ static const struct media_entity_operations ov2740_subdev_entity_ops = { - - static int ov2740_check_hwcfg(struct device *dev) - { -+ struct v4l2_subdev *sd = dev_get_drvdata(dev); -+ struct ov2740 *ov2740 = to_ov2740(sd); - struct fwnode_handle *ep; - struct fwnode_handle *fwnode = dev_fwnode(dev); - struct v4l2_fwnode_endpoint bus_cfg = { -@@ -961,14 +1161,29 @@ static int ov2740_check_hwcfg(struct device *dev) - break; - } - -- if (j == bus_cfg.nr_of_link_frequencies) { -- ret = dev_err_probe(dev, -EINVAL, -- "no link frequency %lld supported\n", -- link_freq_menu_items[i]); -- goto check_hwcfg_error; -+ if (j == bus_cfg.nr_of_link_frequencies) -+ continue; -+ -+ switch (i) { -+ case OV2740_LINK_FREQ_360MHZ_INDEX: -+ ov2740->supported_modes = supported_modes_360mhz; -+ ov2740->supported_modes_count = -+ ARRAY_SIZE(supported_modes_360mhz); -+ break; -+ case OV2740_LINK_FREQ_180MHZ_INDEX: -+ ov2740->supported_modes = supported_modes_180mhz; -+ ov2740->supported_modes_count = -+ ARRAY_SIZE(supported_modes_180mhz); -+ break; - } -+ -+ break; /* Prefer modes from first available link-freq */ - } - -+ if (!ov2740->supported_modes) -+ ret = dev_err_probe(dev, -EINVAL, -+ "no supported link frequencies\n"); -+ - check_hwcfg_error: - v4l2_fwnode_endpoint_free(&bus_cfg); - -@@ -1129,7 +1344,7 @@ static int ov2740_probe(struct i2c_client *client) - } - } - -- ov2740->cur_mode = &supported_modes[0]; -+ ov2740->cur_mode = &ov2740->supported_modes[0]; - ret = ov2740_init_controls(ov2740); - if (ret) { - dev_err_probe(dev, ret, "failed to init controls\n"); --- -2.43.0 - -From b8c88a81135741a39f56d63673bfd2d2f5f12b3a Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Mon, 4 Dec 2023 13:39:45 +0100 -Subject: [PATCH 26/31] media: ov2740: Add a sleep after resetting the sensor - -Split the resetting of the sensor out of the link_freq_config reg_list -and add a delay after this. - -This hopefully fixes the stream sometimes not starting, this was -taken from the ov2740 sensor driver in the out of tree IPU6 driver: - -https://github.com/intel/ipu6-drivers/ - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> -Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> ---- - drivers/media/i2c/ov2740.c | 11 +++++++++-- - 1 file changed, 9 insertions(+), 2 deletions(-) - -diff --git a/drivers/media/i2c/ov2740.c b/drivers/media/i2c/ov2740.c -index 85629992d3aa..9666f6e293d9 100644 ---- a/drivers/media/i2c/ov2740.c -+++ b/drivers/media/i2c/ov2740.c -@@ -128,7 +128,6 @@ struct ov2740_mode { - }; - - static const struct ov2740_reg mipi_data_rate_720mbps[] = { -- {0x0103, 0x01}, - {0x0302, 0x4b}, - {0x030d, 0x4b}, - {0x030e, 0x02}, -@@ -137,7 +136,6 @@ static const struct ov2740_reg mipi_data_rate_720mbps[] = { - }; - - static const struct ov2740_reg mipi_data_rate_360mbps[] = { -- {0x0103, 0x01}, - {0x0302, 0x4b}, - {0x0303, 0x01}, - {0x030d, 0x4b}, -@@ -935,6 +933,15 @@ static int ov2740_start_streaming(struct ov2740 *ov2740) - if (ov2740->nvm) - ov2740_load_otp_data(ov2740->nvm); - -+ /* Reset the sensor */ -+ ret = ov2740_write_reg(ov2740, 0x0103, 1, 0x01); -+ if (ret) { -+ dev_err(&client->dev, "failed to reset\n"); -+ return ret; -+ } -+ -+ usleep_range(10000, 15000); -+ - link_freq_index = ov2740->cur_mode->link_freq_index; - reg_list = &link_freq_configs[link_freq_index].reg_list; - ret = ov2740_write_reg_list(ov2740, reg_list); --- -2.43.0 - -From e807d266be092024e9963ffb6c7b9ace1153ec15 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Mon, 4 Dec 2023 13:39:46 +0100 -Subject: [PATCH 27/31] media: ipu-bridge: Change ov2740 link-frequency to 180 - MHz - -The only known devices that use an ov2740 sensor in combination with -the ipu-bridge code are various Lenovo ThinkPad models, which all -need the link-frequency to be 180 MHz for things to work properly. - -The ov2740 driver used to only support 360 MHz link-frequency, -which is why the ipu-bridge entry used 360 MHz, but now the -ov2740 driver has been extended to also support 180 MHz. - -The ov2740 is actually used with 360 MHz link-frequency on Chromebooks. -On Chromebooks the camera/sensor fwnode graph is part of the ACPI tables. -The ipu-bridge code is used to dynamically generate the graph when it is -missing, so it is not used on Chromebooks and the ov2740 will keep using -360 MHz link-frequency there as before. - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> -Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> -Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> ---- - drivers/media/pci/intel/ipu-bridge.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/media/pci/intel/ipu-bridge.c b/drivers/media/pci/intel/ipu-bridge.c -index e38198e259c0..f980e3125a7b 100644 ---- a/drivers/media/pci/intel/ipu-bridge.c -+++ b/drivers/media/pci/intel/ipu-bridge.c -@@ -53,7 +53,7 @@ static const struct ipu_sensor_config ipu_supported_sensors[] = { - /* Omnivision ov8856 */ - IPU_SENSOR_CONFIG("OVTI8856", 3, 180000000, 360000000, 720000000), - /* Omnivision ov2740 */ -- IPU_SENSOR_CONFIG("INT3474", 1, 360000000), -+ IPU_SENSOR_CONFIG("INT3474", 1, 180000000), - /* Hynix hi556 */ - IPU_SENSOR_CONFIG("INT3537", 1, 437000000), - /* Omnivision ov13b10 */ --- -2.43.0 - -From d1c04b1284f0ce4d32ea73f6a325e08b31b2a323 Mon Sep 17 00:00:00 2001 +From e624515c64d782b452a4676c1e117815267559ae Mon Sep 17 00:00:00 2001 From: Hans de Goede <hdegoede@redhat.com> Date: Tue, 23 Jan 2024 14:58:35 +0100 -Subject: [PATCH 28/31] media: hi556: Return -EPROBE_DEFER if no endpoint is +Subject: [PATCH 29/33] media: hi556: Return -EPROBE_DEFER if no endpoint is found With ipu bridge, endpoints may only be created when ipu bridge has @@ -16823,10 +17721,10 @@ Signed-off-by: Hans de Goede <hdegoede@redhat.com> 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/media/i2c/hi556.c b/drivers/media/i2c/hi556.c -index f6ea9b7b9700..258614b33f51 100644 +index 38c77d515786..96bae9914d52 100644 --- a/drivers/media/i2c/hi556.c +++ b/drivers/media/i2c/hi556.c -@@ -1207,8 +1207,13 @@ static int hi556_check_hwcfg(struct device *dev) +@@ -1206,8 +1206,13 @@ static int hi556_check_hwcfg(struct device *dev) int ret = 0; unsigned int i, j; @@ -16842,7 +17740,7 @@ index f6ea9b7b9700..258614b33f51 100644 ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk); if (ret) { -@@ -1221,10 +1226,6 @@ static int hi556_check_hwcfg(struct device *dev) +@@ -1220,10 +1225,6 @@ static int hi556_check_hwcfg(struct device *dev) return -EINVAL; } @@ -16854,12 +17752,13 @@ index f6ea9b7b9700..258614b33f51 100644 fwnode_handle_put(ep); if (ret) -- -2.43.0 +2.43.2 -From 109e64438f05a0cd791e5d84084672b2fcf12cf2 Mon Sep 17 00:00:00 2001 + +From b127d1003050fb894ea764b600d5f399af413b68 Mon Sep 17 00:00:00 2001 From: Hans de Goede <hdegoede@redhat.com> Date: Tue, 23 Jan 2024 14:48:26 +0100 -Subject: [PATCH 29/31] media: hi556: Add support for reset GPIO +Subject: [PATCH 30/33] media: hi556: Add support for reset GPIO On some ACPI platforms, such as Chromebooks the ACPI methods to change the power-state (_PS0 and _PS3) fully take care of powering @@ -16876,7 +17775,7 @@ Signed-off-by: Hans de Goede <hdegoede@redhat.com> 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/drivers/media/i2c/hi556.c b/drivers/media/i2c/hi556.c -index 258614b33f51..7398391989ea 100644 +index 96bae9914d52..f5a39b83598b 100644 --- a/drivers/media/i2c/hi556.c +++ b/drivers/media/i2c/hi556.c @@ -4,6 +4,7 @@ @@ -16897,7 +17796,7 @@ index 258614b33f51..7398391989ea 100644 /* Current mode */ const struct hi556_mode *cur_mode; -@@ -1277,6 +1281,25 @@ static void hi556_remove(struct i2c_client *client) +@@ -1276,6 +1280,25 @@ static void hi556_remove(struct i2c_client *client) mutex_destroy(&hi556->mutex); } @@ -16923,7 +17822,7 @@ index 258614b33f51..7398391989ea 100644 static int hi556_probe(struct i2c_client *client) { struct hi556 *hi556; -@@ -1296,12 +1319,24 @@ static int hi556_probe(struct i2c_client *client) +@@ -1295,12 +1318,24 @@ static int hi556_probe(struct i2c_client *client) v4l2_i2c_subdev_init(&hi556->sd, client, &hi556_subdev_ops); @@ -16949,7 +17848,7 @@ index 258614b33f51..7398391989ea 100644 } } -@@ -1346,9 +1381,16 @@ static int hi556_probe(struct i2c_client *client) +@@ -1345,9 +1380,16 @@ static int hi556_probe(struct i2c_client *client) v4l2_ctrl_handler_free(hi556->sd.ctrl_handler); mutex_destroy(&hi556->mutex); @@ -16966,7 +17865,7 @@ index 258614b33f51..7398391989ea 100644 #ifdef CONFIG_ACPI static const struct acpi_device_id hi556_acpi_ids[] = { {"INT3537"}, -@@ -1362,6 +1404,7 @@ static struct i2c_driver hi556_i2c_driver = { +@@ -1361,6 +1403,7 @@ static struct i2c_driver hi556_i2c_driver = { .driver = { .name = "hi556", .acpi_match_table = ACPI_PTR(hi556_acpi_ids), @@ -16975,12 +17874,13 @@ index 258614b33f51..7398391989ea 100644 .probe = hi556_probe, .remove = hi556_remove, -- -2.43.0 +2.43.2 + -From 23a74772614fcba8ad2ed9370db613ab0540072e Mon Sep 17 00:00:00 2001 +From ee651202ba2ca38da067b5379edd7b4f339cf7a8 Mon Sep 17 00:00:00 2001 From: Hans de Goede <hdegoede@redhat.com> Date: Tue, 23 Jan 2024 14:54:22 +0100 -Subject: [PATCH 30/31] media: hi556: Add support for external clock +Subject: [PATCH 31/33] media: hi556: Add support for external clock On some ACPI platforms, such as Chromebooks the ACPI methods to change the power-state (_PS0 and _PS3) fully take care of powering @@ -16997,7 +17897,7 @@ Signed-off-by: Hans de Goede <hdegoede@redhat.com> 1 file changed, 13 insertions(+) diff --git a/drivers/media/i2c/hi556.c b/drivers/media/i2c/hi556.c -index 7398391989ea..fb6ba6984e38 100644 +index f5a39b83598b..b783e0f56687 100644 --- a/drivers/media/i2c/hi556.c +++ b/drivers/media/i2c/hi556.c @@ -3,6 +3,7 @@ @@ -17016,7 +17916,7 @@ index 7398391989ea..fb6ba6984e38 100644 /* Current mode */ const struct hi556_mode *cur_mode; -@@ -1287,6 +1289,7 @@ static int hi556_suspend(struct device *dev) +@@ -1286,6 +1288,7 @@ static int hi556_suspend(struct device *dev) struct hi556 *hi556 = to_hi556(sd); gpiod_set_value_cansleep(hi556->reset_gpio, 1); @@ -17024,7 +17924,7 @@ index 7398391989ea..fb6ba6984e38 100644 return 0; } -@@ -1294,6 +1297,11 @@ static int hi556_resume(struct device *dev) +@@ -1293,6 +1296,11 @@ static int hi556_resume(struct device *dev) { struct v4l2_subdev *sd = dev_get_drvdata(dev); struct hi556 *hi556 = to_hi556(sd); @@ -17036,7 +17936,7 @@ index 7398391989ea..fb6ba6984e38 100644 gpiod_set_value_cansleep(hi556->reset_gpio, 0); usleep_range(5000, 5500); -@@ -1325,6 +1333,11 @@ static int hi556_probe(struct i2c_client *client) +@@ -1324,6 +1332,11 @@ static int hi556_probe(struct i2c_client *client) return dev_err_probe(&client->dev, PTR_ERR(hi556->reset_gpio), "failed to get reset GPIO\n"); @@ -17049,12 +17949,13 @@ index 7398391989ea..fb6ba6984e38 100644 if (full_power) { /* Ensure non ACPI managed resources are enabled */ -- -2.43.0 +2.43.2 + -From 6c3b454ee3ab07dd2e10011d685f6bd9f03bee71 Mon Sep 17 00:00:00 2001 +From 16be71996d451b8137ba63070e760448814c11a1 Mon Sep 17 00:00:00 2001 From: Hans de Goede <hdegoede@redhat.com> Date: Wed, 24 Jan 2024 18:45:02 +0100 -Subject: [PATCH 31/31] media: hi556: Add support for avdd regulator +Subject: [PATCH 32/33] media: hi556: Add support for avdd regulator On some ACPI platforms, such as Chromebooks the ACPI methods to change the power-state (_PS0 and _PS3) fully take care of powering @@ -17074,7 +17975,7 @@ Signed-off-by: Hans de Goede <hdegoede@redhat.com> 1 file changed, 24 insertions(+) diff --git a/drivers/media/i2c/hi556.c b/drivers/media/i2c/hi556.c -index fb6ba6984e38..90eff282a6e2 100644 +index b783e0f56687..5641c249d4b1 100644 --- a/drivers/media/i2c/hi556.c +++ b/drivers/media/i2c/hi556.c @@ -9,6 +9,7 @@ @@ -17093,7 +17994,7 @@ index fb6ba6984e38..90eff282a6e2 100644 /* Current mode */ const struct hi556_mode *cur_mode; -@@ -1287,8 +1289,17 @@ static int hi556_suspend(struct device *dev) +@@ -1286,8 +1288,17 @@ static int hi556_suspend(struct device *dev) { struct v4l2_subdev *sd = dev_get_drvdata(dev); struct hi556 *hi556 = to_hi556(sd); @@ -17111,7 +18012,7 @@ index fb6ba6984e38..90eff282a6e2 100644 clk_disable_unprepare(hi556->clk); return 0; } -@@ -1303,6 +1314,13 @@ static int hi556_resume(struct device *dev) +@@ -1302,6 +1313,13 @@ static int hi556_resume(struct device *dev) if (ret) return ret; @@ -17125,7 +18026,7 @@ index fb6ba6984e38..90eff282a6e2 100644 gpiod_set_value_cansleep(hi556->reset_gpio, 0); usleep_range(5000, 5500); return 0; -@@ -1338,6 +1356,12 @@ static int hi556_probe(struct i2c_client *client) +@@ -1337,6 +1355,12 @@ static int hi556_probe(struct i2c_client *client) return dev_err_probe(&client->dev, PTR_ERR(hi556->clk), "failed to get clock\n"); @@ -17139,5 +18040,38 @@ index fb6ba6984e38..90eff282a6e2 100644 if (full_power) { /* Ensure non ACPI managed resources are enabled */ -- -2.43.0 +2.43.2 + + +From 6bd6e73829cf264120f629c88c552c4eb59c7eee Mon Sep 17 00:00:00 2001 +From: Florian Klink <flokli@flokli.de> +Date: Sun, 17 Mar 2024 17:07:53 +0200 +Subject: [PATCH 33/33] media: intel/ipu6: fix firmware paths + +linux-firmware ships them in intel/ipu, not intel/. +--- + drivers/media/pci/intel/ipu6/ipu6.h | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/media/pci/intel/ipu6/ipu6.h b/drivers/media/pci/intel/ipu6/ipu6.h +index 04e7e7e61ca5..da8a95a9edf8 100644 +--- a/drivers/media/pci/intel/ipu6/ipu6.h ++++ b/drivers/media/pci/intel/ipu6/ipu6.h +@@ -24,10 +24,10 @@ struct ipu6_bus_device; + #define IPU6_NAME "intel-ipu6" + #define IPU6_MEDIA_DEV_MODEL_NAME "ipu6" + +-#define IPU6SE_FIRMWARE_NAME "intel/ipu6se_fw.bin" +-#define IPU6EP_FIRMWARE_NAME "intel/ipu6ep_fw.bin" +-#define IPU6_FIRMWARE_NAME "intel/ipu6_fw.bin" +-#define IPU6EPMTL_FIRMWARE_NAME "intel/ipu6epmtl_fw.bin" ++#define IPU6SE_FIRMWARE_NAME "intel/ipu/ipu6se_fw.bin" ++#define IPU6EP_FIRMWARE_NAME "intel/ipu/ipu6ep_fw.bin" ++#define IPU6_FIRMWARE_NAME "intel/ipu/ipu6_fw.bin" ++#define IPU6EPMTL_FIRMWARE_NAME "intel/ipu/ipu6epmtl_fw.bin" + + enum ipu6_version { + IPU6_VER_INVALID = 0, +-- +2.43.2 |