Linux Media Controller development
 help / color / mirror / Atom feed
From: Antti Laakso <antti.laakso@linux.intel.com>
To: linux-media@vger.kernel.org, mchehab@kernel.org,
	sakari.ailus@linux.intel.com
Cc: daxing.li@intel.com, ong.hock.yu@intel.com, antti.laakso@linux.intel.com
Subject: [PATCH v2 14/44] media: ipu6: Add ipu7 mmu support
Date: Fri, 21 Aug 2026 14:42:32 +0300	[thread overview]
Message-ID: <20260821114302.365532-15-antti.laakso@linux.intel.com> (raw)
In-Reply-To: <20260821114302.365532-1-antti.laakso@linux.intel.com>

The ipu7 mmu have similar page tables as ipu6, but e.g. register interface
is different. Add own driver handling ipu7 mmu specifics.

Signed-off-by: Antti Laakso <antti.laakso@linux.intel.com>
---
 drivers/media/pci/intel/ipu6/Makefile      |   1 +
 drivers/media/pci/intel/ipu6/ipu6-mmu.c    |  14 +-
 drivers/media/pci/intel/ipu6/ipu6-mmu.h    |   8 +-
 drivers/media/pci/intel/ipu6/ipu7-mmu-hw.c | 599 +++++++++++++++++++++
 drivers/media/pci/intel/ipu6/ipu7-mmu-hw.h | 155 ++++++
 5 files changed, 773 insertions(+), 4 deletions(-)
 create mode 100644 drivers/media/pci/intel/ipu6/ipu7-mmu-hw.c
 create mode 100644 drivers/media/pci/intel/ipu6/ipu7-mmu-hw.h

diff --git a/drivers/media/pci/intel/ipu6/Makefile b/drivers/media/pci/intel/ipu6/Makefile
index 2106ab84acde..c0daf0995b22 100644
--- a/drivers/media/pci/intel/ipu6/Makefile
+++ b/drivers/media/pci/intel/ipu6/Makefile
@@ -5,6 +5,7 @@ intel-ipu6-y			:= ipu6.o \
 				ipu6-dma.o \
 				ipu6-mmu.o \
 				ipu6-mmu-hw.o \
+				ipu7-mmu-hw.o \
 				ipu6-buttress.o \
 				ipu6-cpd.o \
 				ipu6-fw-com.o
diff --git a/drivers/media/pci/intel/ipu6/ipu6-mmu.c b/drivers/media/pci/intel/ipu6/ipu6-mmu.c
index 98ac59d00b78..243d438786ba 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-mmu.c
+++ b/drivers/media/pci/intel/ipu6/ipu6-mmu.c
@@ -473,7 +473,12 @@ static struct ipu6_mmu_info *ipu6_mmu_alloc(struct ipu6_device *isp)
 	if (!mmu_info)
 		return NULL;
 
-	mmu_info->aperture_start = 0;
+	if (IS_IPU7(isp))
+		mmu_info->aperture_start = isp->secure_mode ?
+			IPU7_FW_CODE_REGION_END : IPU7_FW_CODE_REGION_START;
+	else
+		mmu_info->aperture_start = 0;
+
 	mmu_info->aperture_end =
 		(dma_addr_t)DMA_BIT_MASK(isp->secure_mode ?
 					 IPU6_MMU_ADDR_BITS :
@@ -532,6 +537,7 @@ EXPORT_SYMBOL_NS_GPL(ipu6_mmu_hw_cleanup, "INTEL_IPU6");
 static struct ipu6_dma_mapping *alloc_dma_mapping(struct ipu6_device *isp)
 {
 	struct ipu6_dma_mapping *dmap;
+	unsigned long base_pfn;
 
 	dmap = kzalloc_obj(*dmap);
 	if (!dmap)
@@ -543,7 +549,9 @@ static struct ipu6_dma_mapping *alloc_dma_mapping(struct ipu6_device *isp)
 		return NULL;
 	}
 
-	init_iova_domain(&dmap->iovad, SZ_4K, 1);
+	base_pfn = max_t(unsigned long, 1,
+			 PFN_DOWN(dmap->mmu_info->aperture_start));
+	init_iova_domain(&dmap->iovad, SZ_4K, base_pfn);
 	dmap->mmu_info->dmap = dmap;
 
 	dev_dbg(&isp->pdev->dev, "alloc mapping\n");
@@ -676,7 +684,7 @@ struct ipu6_mmu *ipu6_mmu_init(struct device *dev,
 	if (!mmu)
 		return ERR_PTR(-ENOMEM);
 
-	mmu->ops = &ipu6_mmu_ops;
+	mmu->ops = IS_IPU7(isp) ? &ipu7_mmu_ops : &ipu6_mmu_ops;
 	mmu->mmid = mmid;
 	mmu->ready = false;
 	INIT_LIST_HEAD(&mmu->vma_list);
diff --git a/drivers/media/pci/intel/ipu6/ipu6-mmu.h b/drivers/media/pci/intel/ipu6/ipu6-mmu.h
index a741f1c0e284..44880478d242 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-mmu.h
+++ b/drivers/media/pci/intel/ipu6/ipu6-mmu.h
@@ -8,6 +8,8 @@
 #include <linux/spinlock_types.h>
 #include <linux/types.h>
 
+#include "ipu7-mmu-hw.h"
+
 struct device;
 struct page;
 
@@ -171,7 +173,10 @@ struct ipu6_mmu_hw_ops {
 struct ipu6_mmu {
 	struct list_head node;
 
-	struct ipu6_mmu_hw *ipu6_mmu_hw;
+	union {
+		struct ipu6_mmu_hw *ipu6_mmu_hw;
+		struct ipu7_mmu_hw *ipu7_mmu_hw;
+	};
 	unsigned int nr_mmus;
 	unsigned int mmid;
 
@@ -192,6 +197,7 @@ struct ipu6_mmu {
 };
 
 extern const struct ipu6_mmu_hw_ops ipu6_mmu_ops;
+extern const struct ipu6_mmu_hw_ops ipu7_mmu_ops;
 
 struct ipu6_mmu *ipu6_mmu_init(struct device *dev,
 			       void __iomem *base, int mmid);
diff --git a/drivers/media/pci/intel/ipu6/ipu7-mmu-hw.c b/drivers/media/pci/intel/ipu6/ipu7-mmu-hw.c
new file mode 100644
index 000000000000..3cd9a818733c
--- /dev/null
+++ b/drivers/media/pci/intel/ipu6/ipu7-mmu-hw.c
@@ -0,0 +1,599 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2026 Intel Corporation
+ */
+
+#include <linux/types.h>
+#include <linux/iopoll.h>
+
+#include "ipu6.h"
+#include "ipu6-dma.h"
+#include "ipu6-mmu.h"
+
+static struct ipu7_mmu_hw ipu7_isys_mmu_hwdata[] = {
+	{
+		.offset = IPU7_IS_MMU_FW_RD_OFFSET,
+		.zlx_offset = IPU7_IS_ZLX_UC_RD_OFFSET,
+		.uao_offset = IPU7_IS_UAO_UC_RD_OFFSET,
+		.info_bits = 0x20006701,
+		.refill = 0x00002726,
+		.collapse_en_bitmap = 0x0,
+		.l1_block = IPU7_IS_MMU_FW_RD_L1_BLOCKNR_REG,
+		.l2_block = IPU7_IS_MMU_FW_RD_L2_BLOCKNR_REG,
+		.nr_l1streams = IPU7_IS_MMU_FW_RD_STREAM_NUM,
+		.nr_l2streams = IPU7_IS_MMU_FW_RD_STREAM_NUM,
+		.l1_block_sz = { 0x0, 0x8, 0xa },
+		.l2_block_sz = { 0x0, 0x2, 0x4 },
+		.zlx_nr = IPU7_IS_ZLX_UC_RD_NUM,
+		.zlx_axi_pool = { 0x00000f30 },
+		.zlx_en = { 0, 0, 0, 0 },
+		.zlx_conf = { 0x0, 0x0, 0x0, 0x0 },
+		.uao_p_num = IPU7_IS_UAO_UC_RD_PLANENUM,
+		.uao_p2tlb = { 0x61, 0x64, 0x65 },
+	},
+	{
+		.offset = IPU7_IS_MMU_FW_WR_OFFSET,
+		.zlx_offset = IPU7_IS_ZLX_UC_WR_OFFSET,
+		.uao_offset = IPU7_IS_UAO_UC_WR_OFFSET,
+		.info_bits = 0x20006801,
+		.refill = 0x00002524,
+		.collapse_en_bitmap = 0x0,
+		.l1_block = IPU7_IS_MMU_FW_WR_L1_BLOCKNR_REG,
+		.l2_block = IPU7_IS_MMU_FW_WR_L2_BLOCKNR_REG,
+		.nr_l1streams = IPU7_IS_MMU_FW_WR_STREAM_NUM,
+		.nr_l2streams = IPU7_IS_MMU_FW_WR_STREAM_NUM,
+		.l1_block_sz = { 0x0, 0x8, 0xa },
+		.l2_block_sz = { 0x0, 0x2, 0x4	},
+		.zlx_nr = IPU7_IS_ZLX_UC_WR_NUM,
+		.zlx_axi_pool = { 0x00000f20 },
+		.zlx_en = { 0, 1, 1, 0 },
+		.zlx_conf = { 0x0, 0x00010101, 0x00010101 },
+		.uao_p_num = IPU7_IS_UAO_UC_WR_PLANENUM,
+		.uao_p2tlb = { 0x61, 0x62, 0x63 },
+	},
+	{
+		.offset = IPU7_IS_MMU_M0_OFFSET,
+		.zlx_offset = IPU7_IS_ZLX_M0_OFFSET,
+		.uao_offset = IPU7_IS_UAO_M0_WR_OFFSET,
+		.info_bits = 0x20006601,
+		.refill = 0x00002120,
+		.collapse_en_bitmap = 0x0,
+		.l1_block = IPU7_IS_MMU_M0_L1_BLOCKNR_REG,
+		.l2_block = IPU7_IS_MMU_M0_L2_BLOCKNR_REG,
+		.nr_l1streams = IPU7_IS_MMU_M0_STREAM_NUM,
+		.nr_l2streams = IPU7_IS_MMU_M0_STREAM_NUM,
+		.l1_block_sz = { 0x0, 0x3, 0x6, 0x8, 0xa, 0xc, 0xe, 0x10 },
+		.l2_block_sz = { 0x0, 0x2, 0x4, 0x6, 0x8, 0xa, 0xc, 0xe },
+		.zlx_nr = IPU7_IS_ZLX_M0_NUM,
+		.zlx_axi_pool = { 0x00000f10 },
+		.zlx_en = { 1, 1, 1, 1, 1, 1, 1, 1 },
+		.zlx_conf = {
+			0x00010103,
+			0x00010103,
+			0x00010101,
+			0x00010101,
+			0x00010101,
+			0x00010101,
+			0x00010101,
+			0x00010101,
+		},
+		.uao_p_num = IPU7_IS_UAO_M0_WR_PLANENUM,
+		.uao_p2tlb = {
+			0x00000049,
+			0x0000004a,
+			0x0000004b,
+			0x0000004c,
+			0x0000004d,
+			0x0000004e,
+			0x0000004f,
+			0x00000050,
+		},
+	},
+	{
+		.offset = IPU7_IS_MMU_M1_OFFSET,
+		.zlx_offset = IPU7_IS_ZLX_M1_OFFSET,
+		.uao_offset = IPU7_IS_UAO_M1_WR_OFFSET,
+		.info_bits = 0x20006901,
+		.refill = 0x00002322,
+		.collapse_en_bitmap = 0x0,
+		.l1_block = IPU7_IS_MMU_M1_L1_BLOCKNR_REG,
+		.l2_block = IPU7_IS_MMU_M1_L2_BLOCKNR_REG,
+		.nr_l1streams = IPU7_IS_MMU_M1_STREAM_NUM,
+		.nr_l2streams = IPU7_IS_MMU_M1_STREAM_NUM,
+		.l1_block_sz = {
+			0x0, 0x3, 0x6, 0x9, 0xc,
+			0xe, 0x10, 0x12, 0x14, 0x16,
+			0x18, 0x1a, 0x1c, 0x1e, 0x20, 0x22,
+		},
+		.l2_block_sz = {
+			0x0, 0x2, 0x4, 0x6, 0x8,
+			0xa, 0xc, 0xe, 0x10, 0x12,
+			0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
+		},
+		.zlx_nr = IPU7_IS_ZLX_M1_NUM,
+		.zlx_axi_pool = { 0x00000f20 },
+		.zlx_en = { 1, 1, 1, 1, 1, 1, 1, 1,
+			    1, 1, 1, 1, 1, 1, 1, 1,
+		},
+		.zlx_conf = {
+			0x00010103,
+			0x00010103,
+			0x00010103,
+			0x00010103,
+			0x00010103,
+			0x00010103,
+			0x00010103,
+			0x00010103,
+			0x00010101,
+			0x00010101,
+			0x00010101,
+			0x00010101,
+			0x00010101,
+			0x00010101,
+			0x00010101,
+			0x00010101,
+		},
+		.uao_p_num = IPU7_IS_UAO_M1_WR_PLANENUM,
+		.uao_p2tlb = {
+			0x00000051,
+			0x00000052,
+			0x00000053,
+			0x00000054,
+			0x00000055,
+			0x00000056,
+			0x00000057,
+			0x00000058,
+			0x00000059,
+			0x0000005a,
+			0x0000005b,
+			0x0000005c,
+			0x0000005d,
+			0x0000005e,
+			0x0000005f,
+			0x00000060,
+		},
+	},
+};
+
+static struct ipu7_mmu_hw ipu7_psys_mmu_hwdata[] = {
+	{
+		.name = "PS_FW_RD",
+		.offset = IPU7_PS_MMU_FW_RD_OFFSET,
+		.zlx_offset = IPU7_PS_ZLX_FW_RD_OFFSET,
+		.uao_offset = IPU7_PS_UAO_FW_RD_OFFSET,
+		.info_bits = 0x20004801,
+		.refill = 0x00002726,
+		.collapse_en_bitmap = 0x0,
+		.l1_block = IPU7_PS_MMU_FW_RD_L1_BLOCKNR_REG,
+		.l2_block = IPU7_PS_MMU_FW_RD_L2_BLOCKNR_REG,
+		.nr_l1streams = IPU7_PS_MMU_FW_RD_STREAM_NUM,
+		.nr_l2streams = IPU7_PS_MMU_FW_RD_STREAM_NUM,
+		.l1_block_sz = {
+			0, 0x8, 0xa, 0xc, 0xd,
+			0xf, 0x11, 0x12, 0x13, 0x14,
+			0x16, 0x18, 0x19, 0x1a, 0x1a,
+			0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
+		},
+		.l2_block_sz = {
+			0x0, 0x2, 0x4, 0x6, 0x8,
+			0xa, 0xc, 0xe, 0x10, 0x12,
+			0x14, 0x16, 0x18, 0x1a, 0x1c,
+			0x1e, 0x20, 0x22, 0x24, 0x26,
+		},
+		.zlx_nr = IPU7_PS_ZLX_FW_RD_NUM,
+		.zlx_axi_pool = { 0x00000f30 },
+		.zlx_en = {
+			0, 0, 0, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0, 0,
+		},
+		.zlx_conf = { 0x0 },
+		.uao_p_num = IPU7_PS_UAO_FW_RD_PLANENUM,
+		.uao_p2tlb = {
+			0x00000036,
+			0x0000003d,
+			0x0000003e,
+			0x00000039,
+			0x0000003f,
+			0x00000040,
+			0x00000041,
+			0x0000003a,
+			0x0000003b,
+			0x00000042,
+			0x00000043,
+			0x00000044,
+			0x0000003c,
+		},
+	},
+	{
+		.offset = IPU7_PS_MMU_FW_WR_OFFSET,
+		.zlx_offset = IPU7_PS_ZLX_FW_WR_OFFSET,
+		.uao_offset = IPU7_PS_UAO_FW_WR_OFFSET,
+		.info_bits = 0x20004601,
+		.refill = 0x00002322,
+		.collapse_en_bitmap = 0x0,
+		.l1_block = IPU7_PS_MMU_FW_WR_L1_BLOCKNR_REG,
+		.l2_block = IPU7_PS_MMU_FW_WR_L2_BLOCKNR_REG,
+		.nr_l1streams = IPU7_PS_MMU_FW_WR_STREAM_NUM,
+		.nr_l2streams = IPU7_PS_MMU_FW_WR_STREAM_NUM,
+		.l1_block_sz = {
+			0, 0x8, 0xa, 0xc, 0xd,
+			0xe, 0xf, 0x10, 0x10, 0x10,
+		},
+		.l2_block_sz = {
+			0x0, 0x2, 0x4, 0x6, 0x8,
+			0xa, 0xc, 0xe, 0x10, 0x12,
+		},
+		.zlx_nr = IPU7_PS_ZLX_FW_WR_NUM,
+		.zlx_axi_pool = { 0x00000f20 },
+		.zlx_en = { 0, 1, 1, 0, 0, 0, 0, 0, 0, 0 },
+		.zlx_conf = { 0x0, 0x00010101, 0x00010101 },
+		.uao_p_num = IPU7_PS_UAO_FW_WR_PLANENUM,
+		.uao_p2tlb = { 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c },
+	},
+	{
+		.offset = IPU7_PS_MMU_SRT_RD_OFFSET,
+		.zlx_offset = IPU7_PS_ZLX_DATA_RD_OFFSET,
+		.uao_offset = IPU7_PS_UAO_SRT_RD_OFFSET,
+		.info_bits = 0x20004701,
+		.refill = 0x00002120,
+		.collapse_en_bitmap = 0x0,
+		.l1_block = IPU7_PS_MMU_SRT_RD_L1_BLOCKNR_REG,
+		.l2_block = IPU7_PS_MMU_SRT_RD_L2_BLOCKNR_REG,
+		.nr_l1streams = IPU7_PS_MMU_SRT_RD_STREAM_NUM,
+		.nr_l2streams = IPU7_PS_MMU_SRT_RD_STREAM_NUM,
+		.l1_block_sz = {
+			0x0, 0x4, 0x6, 0x8, 0xb,
+			0xd, 0xf, 0x11, 0x13, 0x15,
+			0x17, 0x23, 0x2b, 0x37, 0x3f,
+			0x41, 0x43, 0x44, 0x45, 0x46,
+			0x47, 0x48, 0x49, 0x4a, 0x4b,
+			0x4c, 0x4d, 0x4e, 0x4f, 0x50,
+			0x51, 0x52, 0x53, 0x55, 0x57,
+			0x59, 0x5b, 0x5d, 0x5f, 0x61,
+		},
+		.l2_block_sz = {
+			0x0, 0x2, 0x4, 0x6, 0x8,
+			0xa, 0xc, 0xe, 0x10, 0x12,
+			0x14, 0x16, 0x18, 0x1a, 0x1c,
+			0x1e, 0x20, 0x22, 0x24, 0x26,
+			0x28, 0x2a, 0x2c, 0x2e, 0x30,
+			0x32, 0x34, 0x36, 0x38, 0x3a,
+			0x3c, 0x3e, 0x40, 0x42, 0x44,
+			0x46, 0x48, 0x4a, 0x4c, 0x4e,
+		},
+		.zlx_nr = IPU7_PS_ZLX_DATA_RD_NUM,
+		.zlx_axi_pool = { 0x00000f30 },
+		.zlx_en = {
+			1, 1, 1, 1, 1, 1, 1, 1,
+			1, 1, 1, 1, 1, 1, 1, 1,
+			0, 0, 0, 0, 0, 0, 0, 0,
+			0, 0, 0, 0, 0, 0, 0, 0,
+		},
+		.zlx_conf = {
+			0x00030303,
+			0x00010101,
+			0x00010101,
+			0x00030202,
+			0x00010101,
+			0x00010101,
+			0x00010101,
+			0x00030800,
+			0x00030500,
+			0x00020101,
+			0x00042000,
+			0x00031000,
+			0x00042000,
+			0x00031000,
+			0x00020400,
+			0x00010101,
+		},
+		.uao_p_num = IPU7_PS_UAO_SRT_RD_PLANENUM,
+		.uao_p2tlb = {
+			0x00000022,
+			0x00000023,
+			0x00000024,
+			0x00000025,
+			0x00000026,
+			0x00000027,
+			0x00000028,
+			0x00000029,
+			0x0000002a,
+			0x0000002b,
+			0x0000002c,
+			0x0000002d,
+			0x0000002e,
+			0x0000002f,
+			0x00000030,
+			0x00000031,
+			0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+			0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+			0x0000001e,
+			0x0000001f,
+			0x00000020,
+			0x00000021,
+			0x00000032,
+			0x00000033,
+			0x00000034,
+			0x00000035,
+		},
+	},
+	{
+		.offset = IPU7_PS_MMU_SRT_WR_OFFSET,
+		.zlx_offset = IPU7_PS_ZLX_DATA_WR_OFFSET,
+		.uao_offset = IPU7_PS_UAO_SRT_WR_OFFSET,
+		.info_bits = 0x20004501,
+		.refill = 0x00002120,
+		.collapse_en_bitmap = 0x0,
+		.l1_block = IPU7_PS_MMU_SRT_WR_L1_BLOCKNR_REG,
+		.l2_block = IPU7_PS_MMU_SRT_WR_L2_BLOCKNR_REG,
+		.nr_l1streams = IPU7_PS_MMU_SRT_WR_STREAM_NUM,
+		.nr_l2streams = IPU7_PS_MMU_SRT_WR_STREAM_NUM,
+		.l1_block_sz = {
+			0x0, 0x2, 0x6, 0xa, 0xc,
+			0xe, 0x10, 0x12, 0x14, 0x16,
+			0x18, 0x1a, 0x1c, 0x1e, 0x20,
+			0x22, 0x24, 0x26, 0x32, 0x3a,
+			0x3c, 0x3e, 0x4a, 0x52, 0x58,
+			0x64, 0x6c, 0x72, 0x7e, 0x86,
+			0x8c, 0x8d, 0x8e, 0x8f, 0x90,
+			0x91, 0x92, 0x94, 0x96, 0x98,
+		},
+		.l2_block_sz = {
+			0x0, 0x2, 0x4, 0x6, 0x8,
+			0xa, 0xc, 0xe, 0x10, 0x12,
+			0x14, 0x16, 0x18, 0x1a, 0x1c,
+			0x1e, 0x20, 0x22, 0x24, 0x26,
+			0x28, 0x2a, 0x2c, 0x2e, 0x30,
+			0x32, 0x34, 0x36, 0x38, 0x3a,
+			0x3c, 0x3e, 0x40, 0x42, 0x44,
+			0x46, 0x48, 0x4a, 0x4c, 0x4e,
+		},
+		.zlx_nr = IPU7_PS_ZLX_DATA_WR_NUM,
+		.zlx_axi_pool = { 0x00000f50 },
+		.zlx_en = {
+			1, 1, 1, 1, 1, 1, 1, 1,
+			0, 0, 1, 1, 1, 1, 1, 1,
+			1, 1, 1, 1, 1, 1, 1, 1,
+			1, 1, 1, 1, 1, 1, 0, 0,
+		},
+		.zlx_conf = {
+			0x00010102,
+			0x00030103,
+			0x00030103,
+			0x00010101,
+			0x00010101,
+			0x00030101,
+			0x00010101,
+			0x38010101,
+			0x0,
+			0x0,
+			0x38010101,
+			0x38010101,
+			0x38010101,
+			0x38010101,
+			0x38010101,
+			0x38010101,
+			0x00010101,
+			0x00042000,
+			0x00031000,
+			0x00010101,
+			0x00010101,
+			0x00042000,
+			0x00031000,
+			0x00031000,
+			0x00042000,
+			0x00031000,
+			0x00031000,
+			0x00042000,
+			0x00031000,
+			0x00031000,
+			0x0,
+			0x0,
+		},
+		.uao_p_num = IPU7_PS_UAO_SRT_WR_PLANENUM,
+		.uao_p2tlb = {
+			0x00000000,
+			0x00000001,
+			0x00000002,
+			0x00000003,
+			0x00000004,
+			0x00000005,
+			0x00000006,
+			0x00000007,
+			0x00000008,
+			0x00000009,
+			0x0000000a,
+			0x0000000b,
+			0x0000000c,
+			0x0000000d,
+			0x0000000e,
+			0x0000000f,
+			0x00000010,
+			0x00000011,
+			0x00000012,
+			0x00000013,
+			0x00000014,
+			0x00000015,
+			0x00000016,
+			0x00000017,
+			0x00000018,
+			0x00000019,
+			0x0000001a,
+			0x0000001b,
+			0x0000001c,
+			0x0000001d,
+			0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+			0x0000001e,
+			0x0000001f,
+			0x00000020,
+			0x00000021,
+		},
+	},
+};
+
+static const struct ipu7_mmu_hwdata ipu7_mmu_hwdata_lookup[IPU_SUBSYS_NUM] = {
+	[IPU_PSYS] = {
+		.hwdata = ipu7_psys_mmu_hwdata,
+		.nr_mmus = ARRAY_SIZE(ipu7_psys_mmu_hwdata),
+	},
+	[IPU_ISYS] = {
+		.hwdata = ipu7_isys_mmu_hwdata,
+		.nr_mmus = ARRAY_SIZE(ipu7_isys_mmu_hwdata),
+	},
+};
+
+static void __ipu7_tlb_invalidate(struct ipu6_mmu *mmu)
+{
+	struct ipu7_mmu_hw *mmu_hw = mmu->ipu7_mmu_hw;
+	unsigned long flags;
+	unsigned int i;
+	int ret;
+	u32 val;
+
+	spin_lock_irqsave(&mmu->ready_lock, flags);
+	if (!mmu->ready) {
+		spin_unlock_irqrestore(&mmu->ready_lock, flags);
+		return;
+	}
+
+	for (i = 0; i < mmu->nr_mmus; i++) {
+		writel(0xffffffffU, mmu_hw[i].base +
+		       IPU7_MMU_REG_INVALIDATE_0);
+
+		/* Need check with HW, use l1streams or l2streams */
+		if (mmu_hw[i].nr_l2streams > 32)
+			writel(0xffffffffU, mmu_hw[i].base +
+			       IPU7_MMU_REG_INVALIDATE_1);
+
+		/*
+		 * The TLB invalidation is a "single cycle" (IOMMU clock cycles)
+		 * When the actual MMIO write reaches the IPU TLB Invalidate
+		 * register, wmb() will force the TLB invalidate out if the CPU
+		 * attempts to update the IOMMU page table (or sooner).
+		 */
+		wmb();
+
+		/* wait invalidation done */
+		ret = readl_poll_timeout_atomic(mmu_hw[i].base +
+						IPU7_MMU_REG_INVALIDATION_STATUS,
+						val, !(val & 0x1U), 500,
+						IPU7_MMU_TLB_INVALIDATE_TIMEOUT);
+		if (ret)
+			dev_err(mmu->dev, "MMU[%u] TLB invalidate failed\n", i);
+	}
+
+	spin_unlock_irqrestore(&mmu->ready_lock, flags);
+}
+
+static int __ipu7_mmu_hw_init(struct ipu6_mmu *mmu)
+{
+	struct ipu6_mmu_info *mmu_info;
+	struct ipu7_mmu_hw *mmu_hw = mmu->ipu7_mmu_hw;
+	unsigned int i, j;
+
+	mmu_info = mmu->dmap->mmu_info;
+	for (i = 0; i < mmu->nr_mmus; i++) {
+		/* Write page table address per MMU */
+		writel((phys_addr_t)mmu_info->l1_pt_dma,
+		       mmu_hw[i].base + IPU7_MMU_REG_PAGE_TABLE_BASE_ADDR);
+
+		/* Set info bits and axi_refill per MMU */
+		writel(mmu_hw[i].info_bits,
+		       mmu_hw[i].base + IPU7_MMU_REG_USER_INFO_BITS);
+		writel(mmu_hw[i].refill, mmu_hw[i].base + IPU7_MMU_REG_AXI_REFILL_IF_ID);
+		writel(mmu_hw[i].collapse_en_bitmap,
+		       mmu_hw[i].base + IPU7_MMU_REG_COLLAPSE_ENABLE_BITMAP);
+
+		if (mmu_hw[i].at_sp_arb_cfg)
+			writel(mmu_hw[i].at_sp_arb_cfg,
+			       mmu_hw[i].base + IPU7_MMU_REG_AT_SP_ARB_CFG);
+
+		/* Default irq configuration */
+		writel(0x3ff, mmu_hw[i].base + IPU7_MMU_REG_IRQ_MASK);
+		writel(0x3ff, mmu_hw[i].base + IPU7_MMU_REG_IRQ_ENABLE);
+
+		/* Configure MMU TLB stream configuration for L1/L2 */
+		for (j = 0; j < mmu_hw[i].nr_l1streams; j++) {
+			writel(mmu_hw[i].l1_block_sz[j], mmu_hw[i].base +
+			       mmu_hw[i].l1_block + 4U * j);
+		}
+
+		for (j = 0; j < mmu_hw[i].nr_l2streams; j++) {
+			writel(mmu_hw[i].l2_block_sz[j], mmu_hw[i].base +
+			       mmu_hw[i].l2_block + 4U * j);
+		}
+
+		for (j = 0; j < mmu_hw[i].uao_p_num; j++) {
+			if (!mmu_hw[i].uao_p2tlb[j])
+				continue;
+			writel(mmu_hw[i].uao_p2tlb[j], mmu_hw[i].uao_base + 4U * j);
+		}
+	}
+
+	for (i = 0; i < mmu->nr_mmus; i++) {
+		for (j = 0; j < IPU7_ZLX_POOL_NUM; j++) {
+			if (!mmu_hw[i].zlx_axi_pool[j])
+				continue;
+			writel(mmu_hw[i].zlx_axi_pool[j],
+			       mmu_hw[i].zlx_base + IPU7_ZLX_REG_AXI_POOL + j * 0x4U);
+		}
+
+		for (j = 0; j < mmu_hw[i].zlx_nr; j++) {
+			if (!mmu_hw[i].zlx_conf[j])
+				continue;
+
+			writel(mmu_hw[i].zlx_conf[j],
+			       mmu_hw[i].zlx_base + IPU7_ZLX_REG_CONF + j * 0x8U);
+		}
+
+		for (j = 0; j < mmu_hw[i].zlx_nr; j++) {
+			if (!mmu_hw[i].zlx_en[j])
+				continue;
+
+			writel(mmu_hw[i].zlx_en[j],
+			       mmu_hw[i].zlx_base + IPU7_ZLX_REG_EN + j * 0x8U);
+		}
+	}
+
+	return 0;
+}
+
+static int __ipu7_mmu_init_hw_data(struct ipu6_mmu *mmu, struct device *dev,
+				   void __iomem *base)
+{
+	const struct ipu7_mmu_hwdata *lookup = ipu7_mmu_hwdata_lookup;
+	struct ipu7_mmu_hw *mmu_hw, *src;
+	unsigned int i, nr_mmus;
+
+	if (mmu->mmid >= IPU_SUBSYS_NUM)
+		return -EINVAL;
+
+	src = lookup[mmu->mmid].hwdata;
+	nr_mmus = lookup[mmu->mmid].nr_mmus;
+
+	mmu_hw = devm_kcalloc(dev, nr_mmus, sizeof(*mmu_hw), GFP_KERNEL);
+	if (!mmu_hw)
+		return -ENOMEM;
+
+	for (i = 0; i < nr_mmus; i++) {
+		if (src[i].nr_l1streams > IPU7_MMU_MAX_TLB_L1_STREAMS ||
+		    src[i].nr_l2streams > IPU7_MMU_MAX_TLB_L2_STREAMS)
+			return -EINVAL;
+
+		mmu_hw[i] = src[i];
+		mmu_hw[i].base = base + src[i].offset;
+		mmu_hw[i].zlx_base = base + src[i].zlx_offset;
+		mmu_hw[i].uao_base = base + src[i].uao_offset;
+	}
+
+	mmu->nr_mmus = nr_mmus;
+	mmu->ipu7_mmu_hw = mmu_hw;
+
+	return 0;
+}
+
+const struct ipu6_mmu_hw_ops ipu7_mmu_ops = {
+	.init_hw_data = __ipu7_mmu_init_hw_data,
+	.hw_init = __ipu7_mmu_hw_init,
+	.tlb_invalidate = __ipu7_tlb_invalidate,
+};
diff --git a/drivers/media/pci/intel/ipu6/ipu7-mmu-hw.h b/drivers/media/pci/intel/ipu6/ipu7-mmu-hw.h
new file mode 100644
index 000000000000..68663057138a
--- /dev/null
+++ b/drivers/media/pci/intel/ipu6/ipu7-mmu-hw.h
@@ -0,0 +1,155 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (C) 2026 Intel Corporation */
+
+#ifndef IPU7_MMU_HW_H
+#define IPU7_MMU_HW_H
+
+#define IPU7_MMU_REG_IRQ_MASK			0x2c
+#define IPU7_MMU_REG_IRQ_ENABLE			0x30
+#define IPU7_MMU_REG_PAGE_TABLE_BASE_ADDR	0x08
+#define IPU7_MMU_REG_USER_INFO_BITS		0x0c
+#define IPU7_MMU_REG_AXI_REFILL_IF_ID		0x10
+#define IPU7_MMU_REG_COLLAPSE_ENABLE_BITMAP	0x18
+#define IPU7_MMU_REG_AT_SP_ARB_CFG		0x20
+
+#define IPU7_ZLX_REG_AXI_POOL			0x0
+#define IPU7_ZLX_REG_EN				0x20
+#define IPU7_ZLX_REG_CONF			0x24
+#define IPU7_ZLX_POOL_NUM			8U
+
+#define IPU7_MMU_MAX_TLB_L1_STREAMS		40U
+#define IPU7_MMU_MAX_TLB_L2_STREAMS		40U
+#define IPU7_UAO_PLANE_MAX_NUM			64U
+#define IPU7_ZLX_MAX_NUM			32U
+
+#define IPU7_MMU_REG_INVALIDATE_0		0x00
+#define IPU7_MMU_REG_INVALIDATE_1		0x04
+#define IPU7_MMU_REG_INVALIDATION_STATUS	0x24
+#define IPU7_MMU_TLB_INVALIDATE_TIMEOUT		2000
+
+#define IPU7_FW_CODE_REGION_SIZE	0x1000000 /* 16MB */
+#define IPU7_FW_CODE_REGION_START	0x4000000 /* 64MB */
+#define IPU7_FW_CODE_REGION_END		(IPU7_FW_CODE_REGION_START +	\
+					 IPU7_FW_CODE_REGION_SIZE) /* 80MB */
+
+#define IPU7_IS_MMU_FW_RD_OFFSET		0x274000
+#define IPU7_IS_MMU_FW_RD_STREAM_NUM		3
+#define IPU7_IS_MMU_FW_RD_L1_BLOCKNR_REG	0x54
+#define IPU7_IS_MMU_FW_RD_L2_BLOCKNR_REG	0x60
+
+#define IPU7_IS_MMU_FW_WR_OFFSET		0x275000
+#define IPU7_IS_MMU_FW_WR_STREAM_NUM		3
+#define IPU7_IS_MMU_FW_WR_L1_BLOCKNR_REG	0x54
+#define IPU7_IS_MMU_FW_WR_L2_BLOCKNR_REG	0x60
+
+#define IPU7_IS_MMU_M0_OFFSET			0x276000
+#define IPU7_IS_MMU_M0_STREAM_NUM		8
+#define IPU7_IS_MMU_M0_L1_BLOCKNR_REG		0x54
+#define IPU7_IS_MMU_M0_L2_BLOCKNR_REG		0x74
+
+#define IPU7_IS_MMU_M1_OFFSET			0x277000
+#define IPU7_IS_MMU_M1_STREAM_NUM		16
+#define IPU7_IS_MMU_M1_L1_BLOCKNR_REG		0x54
+#define IPU7_IS_MMU_M1_L2_BLOCKNR_REG		0x94
+
+#define IPU7_PS_MMU_FW_RD_OFFSET		0x148000
+#define IPU7_PS_MMU_FW_RD_STREAM_NUM		20
+#define IPU7_PS_MMU_FW_RD_L1_BLOCKNR_REG	0x54
+#define IPU7_PS_MMU_FW_RD_L2_BLOCKNR_REG	0xa4
+
+#define IPU7_PS_MMU_FW_WR_OFFSET		0x149000
+#define IPU7_PS_MMU_FW_WR_STREAM_NUM		10
+#define IPU7_PS_MMU_FW_WR_L1_BLOCKNR_REG	0x54
+#define IPU7_PS_MMU_FW_WR_L2_BLOCKNR_REG	0x7c
+
+#define IPU7_PS_MMU_SRT_RD_OFFSET		0x14a000
+#define IPU7_PS_MMU_SRT_RD_STREAM_NUM		40
+#define IPU7_PS_MMU_SRT_RD_L1_BLOCKNR_REG	0x54
+#define IPU7_PS_MMU_SRT_RD_L2_BLOCKNR_REG	0xf4
+
+#define IPU7_PS_MMU_SRT_WR_OFFSET		0x14b000
+#define IPU7_PS_MMU_SRT_WR_STREAM_NUM		40
+#define IPU7_PS_MMU_SRT_WR_L1_BLOCKNR_REG	0x54
+#define IPU7_PS_MMU_SRT_WR_L2_BLOCKNR_REG	0xf4
+
+#define IPU7_IS_UAO_UC_RD_OFFSET		0x27c000
+#define IPU7_IS_UAO_UC_RD_PLANENUM		4
+
+#define IPU7_IS_UAO_UC_WR_OFFSET		0x27d000
+#define IPU7_IS_UAO_UC_WR_PLANENUM		4
+
+#define IPU7_IS_UAO_M0_WR_OFFSET		0x27e000
+#define IPU7_IS_UAO_M0_WR_PLANENUM		8
+
+#define IPU7_IS_UAO_M1_WR_OFFSET		0x27f000
+#define IPU7_IS_UAO_M1_WR_PLANENUM		16
+
+#define IPU7_PS_UAO_FW_RD_OFFSET		0x156000
+#define IPU7_PS_UAO_FW_RD_PLANENUM		20
+
+#define IPU7_PS_UAO_FW_WR_OFFSET		0x157000
+#define IPU7_PS_UAO_FW_WR_PLANENUM		16
+
+#define IPU7_PS_UAO_SRT_RD_OFFSET		0x154000
+#define IPU7_PS_UAO_SRT_RD_PLANENUM		40
+
+#define IPU7_PS_UAO_SRT_WR_OFFSET		0x155000
+#define IPU7_PS_UAO_SRT_WR_PLANENUM		40
+
+#define IPU7_IS_ZLX_UC_RD_OFFSET		0x278000
+#define IPU7_IS_ZLX_UC_WR_OFFSET		0x279000
+#define IPU7_IS_ZLX_M0_OFFSET			0x27a000
+#define IPU7_IS_ZLX_M1_OFFSET			0x27b000
+#define IPU7_IS_ZLX_UC_RD_NUM			4
+#define IPU7_IS_ZLX_UC_WR_NUM			4
+#define IPU7_IS_ZLX_M0_NUM			8
+#define IPU7_IS_ZLX_M1_NUM			16
+
+#define IPU7_PS_ZLX_DATA_RD_OFFSET		0x14e000
+#define IPU7_PS_ZLX_DATA_WR_OFFSET		0x14f000
+#define IPU7_PS_ZLX_FW_RD_OFFSET		0x150000
+#define IPU7_PS_ZLX_FW_WR_OFFSET		0x151000
+#define IPU7_PS_ZLX_DATA_RD_NUM			32
+#define IPU7_PS_ZLX_DATA_WR_NUM			32
+#define IPU7_PS_ZLX_FW_RD_NUM			16
+#define IPU7_PS_ZLX_FW_WR_NUM			10
+
+struct ipu7_mmu_hw {
+	char name[32];
+
+	void __iomem *base;
+	void __iomem *zlx_base;
+	void __iomem *uao_base;
+
+	u32 offset;
+	u32 zlx_offset;
+	u32 uao_offset;
+
+	u32 info_bits;
+	u32 refill;
+	u32 collapse_en_bitmap;
+	u32 at_sp_arb_cfg;
+
+	u32 l1_block;
+	u32 l2_block;
+
+	u8 nr_l1streams;
+	u8 nr_l2streams;
+	u32 l1_block_sz[IPU7_MMU_MAX_TLB_L1_STREAMS];
+	u32 l2_block_sz[IPU7_MMU_MAX_TLB_L2_STREAMS];
+
+	u8 zlx_nr;
+	u32 zlx_axi_pool[IPU7_ZLX_POOL_NUM];
+	u32 zlx_en[IPU7_ZLX_MAX_NUM];
+	u32 zlx_conf[IPU7_ZLX_MAX_NUM];
+
+	u32 uao_p_num;
+	u32 uao_p2tlb[IPU7_UAO_PLANE_MAX_NUM];
+};
+
+struct ipu7_mmu_hwdata {
+	struct ipu7_mmu_hw *hwdata;
+	unsigned int nr_mmus;
+};
+
+#endif
-- 
2.55.0


  parent reply	other threads:[~2026-08-21 11:44 UTC|newest]

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

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=20260821114302.365532-15-antti.laakso@linux.intel.com \
    --to=antti.laakso@linux.intel.com \
    --cc=daxing.li@intel.com \
    --cc=linux-media@vger.kernel.org \
    --cc=mchehab@kernel.org \
    --cc=ong.hock.yu@intel.com \
    --cc=sakari.ailus@linux.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox