All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sakari Ailus <sakari.ailus@linux.intel.com>
To: linux-media@vger.kernel.org
Cc: Antti Laakso <antti.laakso@linux.intel.com>,
	sarang.sapre@intel.com, daxing.li@intel.com,
	ong.hock.yu@intel.com
Subject: [PATCH v4 15/45] media: ipu6: Add ipu7 cpd handling
Date: Mon,  7 Sep 2026 14:29:34 +0300	[thread overview]
Message-ID: <20260907113004.2489993-16-sakari.ailus@linux.intel.com> (raw)
In-Reply-To: <20260907113004.2489993-1-sakari.ailus@linux.intel.com>

From: Antti Laakso <antti.laakso@linux.intel.com>

The firmware format differs slightly between ipu6 and ipu7.
Add support for ipu7 firmware validation and handling.

Signed-off-by: Antti Laakso <antti.laakso@linux.intel.com>
[Sakari Ailus: Use ipu6_ prefix for ipu7 related global symbols.]
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
---
 drivers/media/pci/intel/ipu6/ipu6-cpd.c | 169 +++++++++++++++++++++---
 drivers/media/pci/intel/ipu6/ipu6-cpd.h |  43 ++++++
 2 files changed, 197 insertions(+), 15 deletions(-)

diff --git a/drivers/media/pci/intel/ipu6/ipu6-cpd.c b/drivers/media/pci/intel/ipu6/ipu6-cpd.c
index 966a16a300f8..c4b2d954a9d4 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-cpd.c
+++ b/drivers/media/pci/intel/ipu6/ipu6-cpd.c
@@ -16,6 +16,7 @@
 #include "ipu6-bus.h"
 #include "ipu6-cpd.h"
 #include "ipu6-dma.h"
+#include "ipu7-mmu-hw.h"
 
 /* 15 entries + header*/
 #define MAX_PKG_DIR_ENT_CNT		16
@@ -62,6 +63,20 @@ static inline const struct ipu6_cpd_ent *ipu6_cpd_get_entry(const void *cpd,
 #define ipu6_cpd_get_metadata(cpd) ipu6_cpd_get_entry(cpd, METADATA_IDX)
 #define ipu6_cpd_get_moduledata(cpd) ipu6_cpd_get_entry(cpd, MODULEDATA_IDX)
 
+#define IPU7_CPD_BINARY_START_IDX	1U
+#define IPU7_CPD_METADATA_START_IDX	2U
+#define IPU7_CPD_BINARY_NUM		2U /* ISYS + PSYS */
+#define IPU7_CPD_METADATA_ATTR		0xa
+#define IPU7_CPD_METADATA_IPL		0x1c
+/*
+ * Entries include:
+ * 1 manifest entry.
+ * 1 metadata entry for each sub system(ISYS and PSYS).
+ * 1 binary entry for each sub system(ISYS and PSYS).
+ */
+#define IPU7_CPD_ENTRY_NUM	(IPU7_CPD_BINARY_NUM * 2U + 1U)
+#define IPU7_MAX_MANIFEST_SIZE	(SZ_4K * sizeof(u32))
+
 static const struct ipu6_cpd_metadata_cmpnt_hdr *
 ipu6_cpd_metadata_get_cmpnt(struct ipu6_device *isp, const void *metadata,
 			    unsigned int metadata_size, u8 idx)
@@ -309,39 +324,163 @@ static int ipu6_cpd_validate_metadata(struct ipu6_device *isp,
 	return 0;
 }
 
-int ipu6_cpd_validate_cpd_file(struct ipu6_device *isp, const void *cpd_file,
-			       unsigned long cpd_file_size)
+static struct ipu7_cpd_metadata *ipu7_cpd_get_metadata(const void *cpd, int idx)
 {
-	const struct ipu6_cpd_hdr *hdr = cpd_file;
-	const struct ipu6_cpd_ent *ent;
-	int ret;
+	const struct ipu6_cpd_ent *cpd_ent =
+		ipu6_cpd_get_entry(cpd, IPU7_CPD_METADATA_START_IDX + idx * 2);
 
-	ret = ipu6_cpd_validate_cpd(isp, cpd_file, cpd_file_size,
-				    cpd_file_size);
-	if (ret)
-		return ret;
+	return (struct ipu7_cpd_metadata *)((u8 *)cpd + cpd_ent->offset);
+}
 
-	/* Check for CPD file marker */
-	if (hdr->hdr_mark != CPD_HDR_MARK) {
-		dev_err(&isp->pdev->dev, "Invalid CPD header\n");
+static int ipu7_cpd_validate_metadata(struct ipu6_device *isp,
+				      const void *cpd, int idx)
+{
+	const struct ipu6_cpd_ent *cpd_ent =
+		ipu6_cpd_get_entry(cpd, IPU7_CPD_METADATA_START_IDX + idx * 2);
+	const struct ipu6_cpd_ent *bin_ent =
+		ipu6_cpd_get_entry(cpd, IPU7_CPD_BINARY_START_IDX + idx * 2);
+	const struct ipu7_cpd_metadata *metadata =
+		ipu7_cpd_get_metadata(cpd, idx);
+	struct device *dev = &isp->pdev->dev;
+	u32 offset;
+
+	/* Sanity check for metadata size */
+	if (cpd_ent->len != sizeof(struct ipu7_cpd_metadata)) {
+		dev_err(dev, "Invalid metadata size\n");
+		return -EINVAL;
+	}
+
+	/* Validate type and length of metadata sections */
+	if (metadata->attr.hdr.type != IPU7_CPD_METADATA_ATTR) {
+		dev_err(dev, "Invalid metadata attr type (%d)\n",
+			metadata->attr.hdr.type);
 		return -EINVAL;
 	}
+	if (metadata->attr.hdr.len != sizeof(struct ipu7_cpd_metadata_attr)) {
+		dev_err(dev, "Invalid metadata attr size (%d)\n",
+			metadata->attr.hdr.len);
+		return -EINVAL;
+	}
+	if (metadata->ipl.hdr.type != IPU7_CPD_METADATA_IPL) {
+		dev_err(dev, "Invalid metadata ipl type (%d)\n",
+			metadata->ipl.hdr.type);
+		return -EINVAL;
+	}
+	if (metadata->ipl.hdr.len != sizeof(struct ipu7_cpd_metadata_ipl)) {
+		dev_err(dev, "Invalid metadata ipl size (%d)\n",
+			metadata->ipl.hdr.len);
+		return -EINVAL;
+	}
+
+	offset = metadata->ipl.param[0];
+	if (offset > IPU7_FW_CODE_REGION_SIZE ||
+	    bin_ent->len > IPU7_FW_CODE_REGION_SIZE - offset) {
+		dev_err(dev, "Incorrect binary size %u and offset %u\n",
+			bin_ent->len, offset);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int __ipu7_validate_cpd_file(struct ipu6_device *isp, const void *cpd_file,
+				    unsigned long cpd_file_size)
+{
+	const struct ipu6_cpd_ent *ent;
+	const struct ipu7_cpd_hdr *hdr = cpd_file;
+	unsigned int i;
 
-	/* Sanity check for manifest size */
 	ent = ipu6_cpd_get_manifest(cpd_file);
-	if (ent->len > MAX_MANIFEST_SIZE) {
+	if (ent->len > IPU7_MAX_MANIFEST_SIZE) {
 		dev_err(&isp->pdev->dev, "Invalid CPD manifest size\n");
 		return -EINVAL;
 	}
+	/* Sanity check for CPD entry header */
+	if (hdr->ent_cnt != IPU7_CPD_ENTRY_NUM) {
+		dev_err(&isp->pdev->dev, "Invalid CPD entry number %d\n",
+			hdr->ent_cnt);
+		return -EINVAL;
+	}
 
 	/* Validate metadata */
+	for (i = 0; i < IPU7_CPD_BINARY_NUM; i++) {
+		int ret = ipu7_cpd_validate_metadata(isp, cpd_file, i);
+
+		if (ret) {
+			dev_err(&isp->pdev->dev, "Invalid metadata(%d)\n", i);
+			return ret;
+		}
+	}
+	return 0;
+}
+
+static int __ipu6_validate_cpd_file(struct ipu6_device *isp, const void *cpd_file,
+				    unsigned long cpd_file_size)
+{
+	const struct ipu6_cpd_ent *ent;
+	int ret;
+
+	ent = ipu6_cpd_get_manifest(cpd_file);
+	if (ent->len > MAX_MANIFEST_SIZE) {
+		dev_err(&isp->pdev->dev, "Invalid CPD manifest size\n");
+		return -EINVAL;
+	}
+
 	ent = ipu6_cpd_get_metadata(cpd_file);
 	ret = ipu6_cpd_validate_metadata(isp, cpd_file + ent->offset, ent->len);
 	if (ret)
 		return ret;
 
-	/* Validate moduledata */
 	ent = ipu6_cpd_get_moduledata(cpd_file);
 	return ipu6_cpd_validate_moduledata(isp, cpd_file + ent->offset,
 					    ent->len);
 }
+
+int ipu6_cpd_validate_cpd_file(struct ipu6_device *isp, const void *cpd_file,
+			       unsigned long cpd_file_size)
+{
+	const struct ipu6_cpd_hdr *hdr = cpd_file;
+	int ret;
+
+	ret = ipu6_cpd_validate_cpd(isp, cpd_file, cpd_file_size,
+				    cpd_file_size);
+	if (ret)
+		return ret;
+
+	/* Check for CPD file marker */
+	if (hdr->hdr_mark != CPD_HDR_MARK) {
+		dev_err(&isp->pdev->dev, "Invalid CPD header\n");
+		return -EINVAL;
+	}
+
+	if (IS_IPU7(isp))
+		return __ipu7_validate_cpd_file(isp, cpd_file, cpd_file_size);
+
+	return __ipu6_validate_cpd_file(isp, cpd_file, cpd_file_size);
+}
+
+int ipu6_ipu7_cpd_copy_binary(const void *cpd, const char *name, void *dst,
+			      u32 *entry)
+{
+	unsigned int i;
+
+	for (i = 0; i < IPU7_CPD_BINARY_NUM; i++) {
+		const struct ipu7_cpd_metadata *metadata;
+		u8 idx = IPU7_CPD_BINARY_START_IDX + i * 2U;
+		const struct ipu6_cpd_ent *ent =
+			ipu6_cpd_get_entry(cpd, idx);
+
+		if (strncmp(ent->name, name, sizeof(ent->name)))
+			continue;
+
+		metadata = ipu7_cpd_get_metadata(cpd, i);
+		memcpy(dst + metadata->ipl.param[0], cpd + ent->offset,
+		       ent->len);
+		*entry = metadata->ipl.param[2];
+
+		return 0;
+	}
+
+	return -ENOENT;
+}
+EXPORT_SYMBOL_NS_GPL(ipu6_ipu7_cpd_copy_binary, "INTEL_IPU6");
diff --git a/drivers/media/pci/intel/ipu6/ipu6-cpd.h b/drivers/media/pci/intel/ipu6/ipu6-cpd.h
index e0e4fdeca902..c3a4859d8e79 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-cpd.h
+++ b/drivers/media/pci/intel/ipu6/ipu6-cpd.h
@@ -98,8 +98,51 @@ struct ipu6_cpd_client_pkg_hdr {
 	u32 prog_bin_size;
 } __packed;
 
+/* IPU7 */
+
+struct ipu7_cpd_hdr {
+	u32 hdr_mark;
+	u32 ent_cnt;
+	u8 hdr_ver;
+	u8 ent_ver;
+	u8 hdr_len;
+	u8 rsvd;
+	u8 partition_name[4];
+	u32 crc32;
+} __packed;
+
+struct ipu7_cpd_metadata_hdr {
+	u32 type;
+	u32 len;
+} __packed;
+
+struct ipu7_cpd_metadata_attr {
+	struct ipu7_cpd_metadata_hdr hdr;
+	u8 compression_type;
+	u8 encryption_type;
+	u8 rsvd[2];
+	u32 uncompressed_size;
+	u32 compressed_size;
+	u32 module_id;
+	u8 hash[48];
+} __packed;
+
+struct ipu7_cpd_metadata_ipl {
+	struct ipu7_cpd_metadata_hdr hdr;
+	u32 param[4];
+	u8 rsvd[8];
+} __packed;
+
+struct ipu7_cpd_metadata {
+	struct ipu7_cpd_metadata_attr attr;
+	struct ipu7_cpd_metadata_ipl ipl;
+} __packed;
+
 int ipu6_cpd_create_pkg_dir(struct ipu6_bus_device *adev, const void *src);
 void ipu6_cpd_free_pkg_dir(struct ipu6_bus_device *adev);
 int ipu6_cpd_validate_cpd_file(struct ipu6_device *isp, const void *cpd_file,
 			       unsigned long cpd_file_size);
+int ipu6_ipu7_cpd_copy_binary(const void *cpd, const char *name, void *dst,
+			      u32 *entry);
+
 #endif /* IPU6_CPD_H */
-- 
2.47.3


  parent reply	other threads:[~2026-09-07 11:30 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-07 11:29 [PATCH v4 00/45] media: ipu6: Add support for ipu7 hardware Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 01/45] media: ipu6: Add helpers for IPU runtime variation Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 02/45] media: ipu6: Rename pointer to firmware context Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 03/45] media: ipu6: Rename buttress_ipc pointer Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 04/45] media: ipu6: Remove duplicate warnings in cpd validation Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 05/45] media: ipu6: Remove unused ipu6 firmware struct Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 06/45] media: ipu6: Cleanup ipu6_mmu_init() Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 07/45] media: ipu6: Simplify firmware com arguments Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 08/45] media: ipu6: Add helper to identify ipu7 Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 09/45] media: ipu6: Prepare buttress for ipu7 support Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 10/45] media: ipu6: Use single struct for registers Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 11/45] media: ipu6: Rename IPU subsys ID Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 12/45] media: ipu6: Add ipu7 buttress support Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 13/45] media: ipu6: Prepare mmu driver for hw variation Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 14/45] media: ipu6: Add ipu7 mmu support Sakari Ailus
2026-09-07 11:29 ` Sakari Ailus [this message]
2026-09-07 11:29 ` [PATCH v4 16/45] media: ipu6: Add check for pkg_dir before freeing Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 17/45] media: ipu6: Rename isys fw msg union Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 18/45] media: ipu6: Move isys isr handlers to fw file Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 19/45] media: ipu6: Move hw specific buffer handling down Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 20/45] media: ipu6: Isolate hw specific buffer handling Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 21/45] media: ipu6: Add isys firmware ops Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 22/45] media: ipu6: Add ipu7 fw start/stop functionality Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 23/45] media: ipu6: Add ipu7 fw com methods Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 24/45] media: ipu6: Add ipu7 fw isys ops Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 25/45] media: ipu6: Add ipu7 csi2 register definitions Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 26/45] media: ipu6: Add ipu7 isr handler Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 27/45] media: ipu6: Add ipu7 csi phy driver Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 28/45] media: ipu6: Split ipu6 csi2 stream enable/disable Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 29/45] media: ipu6: Add support for ipu7 csi2 receiver Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 30/45] media: ipu6: Parse bus type for ipu7 Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 31/45] media: ipu6: Enable ipu7 isys interrupts Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 32/45] media: ipu6: Skip watermark configuration for ipu7 Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 33/45] media: ipu6: The SPC init is valid only for ipu6 Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 34/45] media: ipu6: The VC arbitration mechanism is ipu6 only Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 35/45] media: ipu6: Move buttress mem alloc out from probe Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 36/45] media: ipu6: Read correct SKU ID for ipu7 Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 37/45] media: ipu6: Add support for fixed iova region Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 38/45] media: ipu6: Make fw mapping function reusable Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 39/45] media: ipu6: Move isys fw mapping to pci_probe Sakari Ailus
2026-09-07 11:29 ` [PATCH v4 40/45] media: ipu6: Map ipu7 firmware Sakari Ailus
2026-09-07 11:30 ` [PATCH v4 41/45] media: ipu6: Set model name for ipu7 Sakari Ailus
2026-09-07 11:30 ` [PATCH v4 42/45] media: ipu6: Add ipu7.5 buttress support Sakari Ailus
2026-09-07 11:30 ` [PATCH v4 43/45] media: ipu6: Add ipu7.5 mmu initialization data Sakari Ailus
2026-09-07 11:30 ` [PATCH v4 44/45] media: ipu6: Enable support for IPU 7 and IPU 7.5 Sakari Ailus
2026-09-07 11:30 ` [PATCH v4 45/45] staging: media: ipu7: Update TODO file Sakari Ailus

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260907113004.2489993-16-sakari.ailus@linux.intel.com \
    --to=sakari.ailus@linux.intel.com \
    --cc=antti.laakso@linux.intel.com \
    --cc=daxing.li@intel.com \
    --cc=linux-media@vger.kernel.org \
    --cc=ong.hock.yu@intel.com \
    --cc=sarang.sapre@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.