Skip to contentSkip to conversation

Samsung IOMMU videobuf2 allocator and s5p-fimc update

PATCH In review Marek Szyprowski 7 participants 29 messages Mar 4, 2011 – Mar 15, 2011

Subsystems (5)
lore
Share & tools
lore

Marek Szyprowski

author maintainer
#0 lore raw

cover Samsung IOMMU videobuf2 allocator and s5p-fimc update

Hello,

This patch series introduces new type of videbuf2 memory allocator - vb2-s5p-iommu. This allocator can be used only on Samsung SoCs that have IOMMU module. Currently only Samsung EXYNOS4 (former S5PV310) platform has SYSMMU modules. The allocator is then used by s5p-fimc driver. To make it possible some additional changes are required. Mainly platform support for s5p-fimc for EXYNOS4 machines need to be defined. The proposed solution has been tested on Universal C210 board (Samsung S5PC210/EXYNOS4 based).

We decided to use driver private address space mode of the iommu driver. This way each vb2-s5p-iommu client gets it's own address space for memory buffers. This reduces kernel virtual memory fragmentation as well as solves some non-trivial page table updates issues. The drawback is the fact that the interface for s5p-sysmmu has been changed.

This IOMMU allocator has no dependences on other subsystems besides Samsung platfrom core. We also ported s5p-mfc and s5p-tv drivers to this allocator, they will be posted in separate patch series. This will enable to get them working on EXYNOS4 (S5PV310) platform. Support for S5PV210/S5PC110 platform still depends on CMA allocator that needs more discussion on memory management mailing list and development. The patches with updated s5p-mfc and s5p-tv drivers will follow.

To get FIMC module working on EXYNOS4/UniversalC210 board we also added support for power domains and power gating.

This patch series contains a collection of patches for various platform subsystems. Here is a detailed list:

[PATCH 1/7] ARM: S5PV310: Add platform definitions for FIMC
- adds basic platform resources for FIMC modules (for s5p-fimc driver)

[PATCH 2/7] ARM: S5PV310: power domains: fixes and code cleanup
- adds support for block gating in Samsung power domain driver and performs some cleanup

[PATCH 3/7] ARM: Samsung: update/rewrite Samsung SYSMMU (IOMMU) driver
- a complete rewrite of sysmmu driver for Samsung platform:
- the new version introduces device private page tables (address space) mode
- simplified the resource management (no more horrible single platform device with 32 resources is needed)
- some other API chages required by upcoming videobuf2 allocator

[PATCH 4/7] v4l: videobuf2: add Samsung SYSMMU (IOMMU) based allocator
- introduces new memory allocator for videobuf2, it uses s5p-sysmmu iommu driver, memory for video buffers is acuired by alloc_page() kernel function

[PATCH 5/7] s5p-fimc: add pm_runtime support
- adds support for pm_runtime in s5p-fimc driver

[PATCH 6/7] s5p-fimc: Add support for vb2-s5p-iommu allocator
- adds support for the newly introduces videbuf2-s5p-iommu allocator on EXYNOS4 platform

[PATCH 7/7] ARM: S5PC210: enable FIMC on Universal_C210
- adds all required machine definitions to get FIMC modules working on Universal C210 boards

The patch series is based on git://linuxtv.org/media_tree.git tree, staging/for_v2.6.39 branch with the following Samsung platform patches:
1. [PATCH] ARM: Samsung: change suspend/resume code to depend on CONFIG_SUSPEND
http://www.mail-archive.com/linux-samsung-soc at vger.kernel.org/msg04025.html
2. [PATCH v2] ARM: S5PC210: add support for i2c PMICs on Universal_C210 board
http://www.mail-archive.com/linux-samsung-soc at vger.kernel.org/msg04029.html

This series has not been rebased onto the latest changes (S5PV310 renamed to EXYNOS4) in
git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git,
for-next branch. We will rebase them soon, but first we want to get feedback and comments on the s5p-iommu videobuf2 allocator idea.

Best regards

Signature · 59 lines
Marek Szyprowski
Samsung Poland R&D Center


Complete patch summary:

Andrzej Pietrasiewicz (2):
  ARM: Samsung: update/rewrite Samsung SYSMMU (IOMMU) driver
  v4l: videobuf2: add Samsung SYSMMU (IOMMU) based allocator

Marek Szyprowski (3):
  s5p-fimc: add pm_runtime support
  s5p-fimc: Add support for vb2-s5p-iommu allocator
  ARM: S5PC210: enable FIMC on Universal_C210

Sylwester Nawrocki (1):
  ARM: S5PV310: Add platform definitions for FIMC

Tomasz Stanislawski (1):
  ARM: S5PV310: power domains: fixes and code cleanup

 arch/arm/mach-s5pv310/Kconfig                    |    6 +
 arch/arm/mach-s5pv310/clock.c                    |   91 ++
 arch/arm/mach-s5pv310/cpu.c                      |    7 +
 arch/arm/mach-s5pv310/dev-pd.c                   |   93 ++-
 arch/arm/mach-s5pv310/dev-sysmmu.c               |  582 +++++++++----
 arch/arm/mach-s5pv310/include/mach/irqs.h        |   40 +-
 arch/arm/mach-s5pv310/include/mach/map.h         |    8 +
 arch/arm/mach-s5pv310/include/mach/regs-clock.h  |   12 +
 arch/arm/mach-s5pv310/include/mach/regs-sysmmu.h |   23 +-
 arch/arm/mach-s5pv310/include/mach/sysmmu.h      |  122 ---
 arch/arm/mach-s5pv310/mach-universal_c210.c      |   20 +
 arch/arm/plat-s5p/Kconfig                        |   22 +-
 arch/arm/plat-s5p/Makefile                       |    1 +
 arch/arm/plat-s5p/dev-fimc3.c                    |   43 +
 arch/arm/plat-s5p/include/plat/sysmmu.h          |  127 +++
 arch/arm/plat-s5p/sysmmu.c                       |  988 +++++++++++++++-------
 arch/arm/plat-samsung/include/plat/devs.h        |    3 +-
 arch/arm/plat-samsung/include/plat/fimc-core.h   |    5 +
 arch/arm/plat-samsung/include/plat/pd.h          |    1 +
 drivers/media/video/Kconfig                      |   11 +-
 drivers/media/video/Makefile                     |    1 +
 drivers/media/video/s5p-fimc/fimc-capture.c      |    9 +-
 drivers/media/video/s5p-fimc/fimc-core.c         |   36 +-
 drivers/media/video/s5p-fimc/fimc-mem.h          |   87 ++
 drivers/media/video/videobuf2-s5p-iommu.c        |  444 ++++++++++
 include/media/videobuf2-s5p-iommu.h              |   50 ++
 26 files changed, 2129 insertions(+), 703 deletions(-)
 rewrite arch/arm/mach-s5pv310/dev-sysmmu.c (86%)
 delete mode 100644 arch/arm/mach-s5pv310/include/mach/sysmmu.h
 create mode 100644 arch/arm/plat-s5p/dev-fimc3.c
 create mode 100644 arch/arm/plat-s5p/include/plat/sysmmu.h
 rewrite arch/arm/plat-s5p/sysmmu.c (85%)
 create mode 100644 drivers/media/video/s5p-fimc/fimc-mem.h
 create mode 100644 drivers/media/video/videobuf2-s5p-iommu.c
 create mode 100644 include/media/videobuf2-s5p-iommu.h

-- 
1.7.1.569.g6f426
author maintainer
#1 lore raw

PATCH 1/7 ARM: S5PV310: Add platform definitions for FIMC

From: Sylwester Nawrocki <[email protected]>

Add support for fourth FIMC platform device definition and define resources for FIMC modules on S5PV310 machines.

---
 arch/arm/mach-s5pv310/cpu.c                    |    7 ++++
 arch/arm/mach-s5pv310/include/mach/irqs.h      |    4 ++
 arch/arm/mach-s5pv310/include/mach/map.h       |    8 ++++
 arch/arm/plat-s5p/Kconfig                      |    5 +++
 arch/arm/plat-s5p/Makefile                     |    1 +
 arch/arm/plat-s5p/dev-fimc3.c                  |   43 ++++++++++++++++++++++++
 arch/arm/plat-samsung/include/plat/devs.h      |    1 +
 arch/arm/plat-samsung/include/plat/fimc-core.h |    5 +++
 8 files changed, 74 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/plat-s5p/dev-fimc3.c
arch/arm/mach-s5pv310/cpu.c +7 -0
index 0db0fb6..0bdb0b0 100644
@@ -21,6 +21,8 @@
 #include <plat/clock.h>
 #include <plat/s5pv310.h>
 #include <plat/sdhci.h>
+#include <plat/devs.h>
+#include <plat/fimc-core.h>
 
 #include <mach/regs-irq.h>
 
@@ -114,6 +116,11 @@ void __init s5pv310_map_io(void)
 	s5pv310_default_sdhci1();
 	s5pv310_default_sdhci2();
 	s5pv310_default_sdhci3();
+
+	s3c_fimc_setname(0, "s5pv310-fimc");
+	s3c_fimc_setname(1, "s5pv310-fimc");
+	s3c_fimc_setname(2, "s5pv310-fimc");
+	s3c_fimc_setname(3, "s5pv310-fimc");
 }
 
 void __init s5pv310_init_clocks(int xtal)
arch/arm/mach-s5pv310/include/mach/irqs.h +4 -0
index 536b0b5..0e99968 100644
@@ -107,6 +107,10 @@
 
 #define IRQ_MIPI_CSIS0		COMBINER_IRQ(30, 0)
 #define IRQ_MIPI_CSIS1		COMBINER_IRQ(30, 1)
+#define IRQ_FIMC0		COMBINER_IRQ(32, 0)
+#define IRQ_FIMC1		COMBINER_IRQ(32, 1)
+#define IRQ_FIMC2		COMBINER_IRQ(33, 0)
+#define IRQ_FIMC3		COMBINER_IRQ(33, 1)
 
 #define IRQ_ONENAND_AUDI	COMBINER_IRQ(34, 0)
 
arch/arm/mach-s5pv310/include/mach/map.h +8 -0
index 901657f..0db3a47 100644
@@ -25,6 +25,10 @@
 
 #define S5PV310_PA_SYSRAM		0x02025000
 
+#define S5PV310_PA_FIMC0		0x11800000
+#define S5PV310_PA_FIMC1		0x11810000
+#define S5PV310_PA_FIMC2		0x11820000
+#define S5PV310_PA_FIMC3		0x11830000
 #define S5PV310_PA_I2S0			0x03830000
 #define S5PV310_PA_I2S1			0xE3100000
 #define S5PV310_PA_I2S2			0xE2A00000
@@ -121,6 +125,10 @@
 #define S5P_PA_CHIPID			S5PV310_PA_CHIPID
 #define S5P_PA_MIPI_CSIS0		S5PV310_PA_MIPI_CSIS0
 #define S5P_PA_MIPI_CSIS1		S5PV310_PA_MIPI_CSIS1
+#define S5P_PA_FIMC0			S5PV310_PA_FIMC0
+#define S5P_PA_FIMC1			S5PV310_PA_FIMC1
+#define S5P_PA_FIMC2			S5PV310_PA_FIMC2
+#define S5P_PA_FIMC3			S5PV310_PA_FIMC3
 #define S5P_PA_ONENAND			S5PC210_PA_ONENAND
 #define S5P_PA_ONENAND_DMA		S5PC210_PA_ONENAND_DMA
 #define S5P_PA_SDRAM			S5PV310_PA_SDRAM
arch/arm/plat-s5p/Kconfig +5 -0
index 557f8c5..0db2a7a 100644
@@ -60,6 +60,11 @@ config S5P_DEV_FIMC2
 	help
 	  Compile in platform device definitions for FIMC controller 2
 
+config S5P_DEV_FIMC3
+	bool
+	help
+	  Compile in platform device definitions for FIMC controller 3
+	  
 config S5P_DEV_ONENAND
 	bool
 	help
arch/arm/plat-s5p/Makefile +1 -0
index ce5a0a7..cfcd1db 100644
@@ -28,6 +28,7 @@ obj-$(CONFIG_SUSPEND)		+= irq-pm.o
 obj-$(CONFIG_S5P_DEV_FIMC0)	+= dev-fimc0.o
 obj-$(CONFIG_S5P_DEV_FIMC1)	+= dev-fimc1.o
 obj-$(CONFIG_S5P_DEV_FIMC2)	+= dev-fimc2.o
+obj-$(CONFIG_S5P_DEV_FIMC3)	+= dev-fimc3.o
 obj-$(CONFIG_S5P_DEV_ONENAND)	+= dev-onenand.o
 obj-$(CONFIG_S5P_DEV_CSIS0)	+= dev-csis0.o
 obj-$(CONFIG_S5P_DEV_CSIS1)	+= dev-csis1.o
arch/arm/plat-s5p/dev-fimc3.c new file +43 -0

43 lines not on this page · raw message

arch/arm/plat-samsung/include/plat/devs.h +1 -0
index b4d208b..b0123f3 100644
@@ -133,6 +133,7 @@ extern struct platform_device samsung_device_keypad;
 extern struct platform_device s5p_device_fimc0;
 extern struct platform_device s5p_device_fimc1;
 extern struct platform_device s5p_device_fimc2;
+extern struct platform_device s5p_device_fimc3;
 
 extern struct platform_device s5p_device_mipi_csis0;
 extern struct platform_device s5p_device_mipi_csis1;
arch/arm/plat-samsung/include/plat/fimc-core.h +5 -0
index 81a3bfe..945a99d 100644
@@ -38,6 +38,11 @@ static inline void s3c_fimc_setname(int id, char *name)
 		s5p_device_fimc2.name = name;
 		break;
 #endif
+#ifdef CONFIG_S5P_DEV_FIMC3
+	case 3:
+		s5p_device_fimc3.name = name;
+		break;
+#endif
 	}
 }
 
Signature · 1 line
1.7.1.569.g6f426
#2 lore raw

PATCH 1/7 ARM: S5PV310: Add platform definitions for FIMC

Review

Quoted 181 lines · Marek Szyprowski

From: Sylwester Nawrocki <[email protected]>

Add support for fourth FIMC platform device definition and define resources for FIMC modules on S5PV310 machines.

---
 arch/arm/mach-s5pv310/cpu.c                    |    7 ++++
 arch/arm/mach-s5pv310/include/mach/irqs.h      |    4 ++
 arch/arm/mach-s5pv310/include/mach/map.h       |    8 ++++
 arch/arm/plat-s5p/Kconfig                      |    5 +++
 arch/arm/plat-s5p/Makefile                     |    1 +
 arch/arm/plat-s5p/dev-fimc3.c                  |   43
++++++++++++++++++++++++
 arch/arm/plat-samsung/include/plat/devs.h      |    1 +
 arch/arm/plat-samsung/include/plat/fimc-core.h |    5 +++
 8 files changed, 74 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/plat-s5p/dev-fimc3.c
arch/arm/mach-s5pv310/cpu.c +7 -0
index 0db0fb6..0bdb0b0 100644
@@ -21,6 +21,8 @@
 #include <plat/clock.h>
 #include <plat/s5pv310.h>
 #include <plat/sdhci.h>
+#include <plat/devs.h>
+#include <plat/fimc-core.h>
 
 #include <mach/regs-irq.h>
 
@@ -114,6 +116,11 @@ void __init s5pv310_map_io(void)
 	s5pv310_default_sdhci1();
 	s5pv310_default_sdhci2();
 	s5pv310_default_sdhci3();
+
+	s3c_fimc_setname(0, "s5pv310-fimc");
+	s3c_fimc_setname(1, "s5pv310-fimc");
+	s3c_fimc_setname(2, "s5pv310-fimc");
+	s3c_fimc_setname(3, "s5pv310-fimc");
 }
 
 void __init s5pv310_init_clocks(int xtal)
arch/arm/mach- renamed from arch/arm/mach-s5pv310/include/mach/irqs.h +0 -0

s5pv310/include/mach/irqs.h
index 536b0b5..0e99968 100644

arch/arm/mach-s5pv310/include/mach/irqs.h +4 -0
@@ -107,6 +107,10 @@
 
 #define IRQ_MIPI_CSIS0		COMBINER_IRQ(30, 0)
 #define IRQ_MIPI_CSIS1		COMBINER_IRQ(30, 1)
+#define IRQ_FIMC0		COMBINER_IRQ(32, 0)
+#define IRQ_FIMC1		COMBINER_IRQ(32, 1)
+#define IRQ_FIMC2		COMBINER_IRQ(33, 0)
+#define IRQ_FIMC3		COMBINER_IRQ(33, 1)
 
 #define IRQ_ONENAND_AUDI	COMBINER_IRQ(34, 0)
 
arch/arm/mach- renamed from arch/arm/mach-s5pv310/include/mach/map.h +0 -0

s5pv310/include/mach/map.h
index 901657f..0db3a47 100644

arch/arm/mach-s5pv310/include/mach/map.h +8 -0
@@ -25,6 +25,10 @@
 
 #define S5PV310_PA_SYSRAM		0x02025000
 
+#define S5PV310_PA_FIMC0		0x11800000
+#define S5PV310_PA_FIMC1		0x11810000
+#define S5PV310_PA_FIMC2		0x11820000
+#define S5PV310_PA_FIMC3		0x11830000
 #define S5PV310_PA_I2S0			0x03830000
 #define S5PV310_PA_I2S1			0xE3100000
 #define S5PV310_PA_I2S2			0xE2A00000
@@ -121,6 +125,10 @@
 #define S5P_PA_CHIPID			S5PV310_PA_CHIPID
 #define S5P_PA_MIPI_CSIS0		S5PV310_PA_MIPI_CSIS0
 #define S5P_PA_MIPI_CSIS1		S5PV310_PA_MIPI_CSIS1
+#define S5P_PA_FIMC0			S5PV310_PA_FIMC0
+#define S5P_PA_FIMC1			S5PV310_PA_FIMC1
+#define S5P_PA_FIMC2			S5PV310_PA_FIMC2
+#define S5P_PA_FIMC3			S5PV310_PA_FIMC3
 #define S5P_PA_ONENAND			S5PC210_PA_ONENAND
 #define S5P_PA_ONENAND_DMA		S5PC210_PA_ONENAND_DMA
 #define S5P_PA_SDRAM			S5PV310_PA_SDRAM
arch/arm/plat-s5p/Kconfig +5 -0
index 557f8c5..0db2a7a 100644
@@ -60,6 +60,11 @@ config S5P_DEV_FIMC2
 	help
 	  Compile in platform device definitions for FIMC controller 2
 
+config S5P_DEV_FIMC3
+	bool
+	help
+	  Compile in platform device definitions for FIMC controller 3
+
 config S5P_DEV_ONENAND
 	bool
 	help
arch/arm/plat-s5p/Makefile +1 -0
index ce5a0a7..cfcd1db 100644
@@ -28,6 +28,7 @@ obj-$(CONFIG_SUSPEND)		+= irq-pm.o
 obj-$(CONFIG_S5P_DEV_FIMC0)	+= dev-fimc0.o
 obj-$(CONFIG_S5P_DEV_FIMC1)	+= dev-fimc1.o
 obj-$(CONFIG_S5P_DEV_FIMC2)	+= dev-fimc2.o
+obj-$(CONFIG_S5P_DEV_FIMC3)	+= dev-fimc3.o
 obj-$(CONFIG_S5P_DEV_ONENAND)	+= dev-onenand.o
 obj-$(CONFIG_S5P_DEV_CSIS0)	+= dev-csis0.o
 obj-$(CONFIG_S5P_DEV_CSIS1)	+= dev-csis1.o
arch/arm/plat-s5p/dev-fimc3.c new file +43 -0
new file mode 100644
index 0000000..ef31bec
@@ -0,0 +1,43 @@
+/* linux/arch/arm/plat-s5p/dev-fimc3.c
+ *
+ * Copyright (c) 2010 Samsung Electronics
+ *
+ * Base S5P FIMC3 resource and device definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <mach/map.h>
+
+static struct resource s5p_fimc3_resource[] = {
+	[0] = {
+		.start	= S5P_PA_FIMC3,
+		.end	= S5P_PA_FIMC3 + SZ_4K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_FIMC3,
+		.end	= IRQ_FIMC3,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static u64 s5p_fimc3_dma_mask = DMA_BIT_MASK(32);
+
+struct platform_device s5p_device_fimc3 = {
+	.name		= "s5p-fimc",
+	.id		= 3,
+	.num_resources	= ARRAY_SIZE(s5p_fimc3_resource),
+	.resource	= s5p_fimc3_resource,
+	.dev		= {
+		.dma_mask		= &s5p_fimc3_dma_mask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+};
arch/arm/plat- renamed from arch/arm/plat-samsung/include/plat/devs.h +0 -0

samsung/include/plat/devs.h
index b4d208b..b0123f3 100644

arch/arm/plat-samsung/include/plat/devs.h +1 -0
@@ -133,6 +133,7 @@ extern struct platform_device samsung_device_keypad;
 extern struct platform_device s5p_device_fimc0;
 extern struct platform_device s5p_device_fimc1;
 extern struct platform_device s5p_device_fimc2;
+extern struct platform_device s5p_device_fimc3;
 
 extern struct platform_device s5p_device_mipi_csis0;
 extern struct platform_device s5p_device_mipi_csis1;
(quoted diff) +0 -0

b/arch/arm/plat-

Quoted 7 lines

samsung/include/plat/fimc-core.h
index 81a3bfe..945a99d 100644

arch/arm/plat-samsung/include/plat/fimc-core.h +0 -0
@@ -38,6 +38,11 @@ static inline void s3c_fimc_setname(int id, char *name)
 		s5p_device_fimc2.name = name;
 		break;

arch/arm/plat-samsung/include/plat/fimc-core.h static inline void s3c_fimc_setname(int id, char *name)

Quoted 10 lines
arch/arm/plat-samsung/include/plat/fimc-core.h +5 -1
 #endif
+#ifdef CONFIG_S5P_DEV_FIMC3
+	case 3:
+		s5p_device_fimc3.name = name;
+		break;
+#endif
 	}
 }
 
--

Ok, applied this based on my for-next.
Thanks.

Best regards,
Kgene.
--
Kukjin Kim <[email protected]>, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd.

author maintainer
#3 lore raw

PATCH 2/7 ARM: S5PV310: power domains: fixes and code cleanup

In reply to Marek Szyprowski

From: Tomasz Stanislawski <[email protected]>

This patch extends power domain driver with support for enabling and disabling modules in S5P_CLKGATE_BLOCK register. It also performs a little code cleanup to avoid confusion between s5pv310_device_pd array index and power domain id.

---
 arch/arm/mach-s5pv310/dev-pd.c                  |   93 +++++++++++++++++------
 arch/arm/mach-s5pv310/include/mach/regs-clock.h |    9 ++
 arch/arm/plat-samsung/include/plat/pd.h         |    1 +
 3 files changed, 81 insertions(+), 22 deletions(-)
arch/arm/mach-s5pv310/dev-pd.c +71 -22
index 58a50c2..e051998 100644
@@ -16,13 +16,17 @@
 #include <linux/delay.h>
 
 #include <mach/regs-pmu.h>
+#include <mach/regs-clock.h>
 
 #include <plat/pd.h>
 
+static spinlock_t gate_block_slock = SPIN_LOCK_UNLOCKED;
+
 static int s5pv310_pd_enable(struct device *dev)
 {
 	struct samsung_pd_info *pdata =  dev->platform_data;
 	u32 timeout;
+	int ret = 0;
 
 	__raw_writel(S5P_INT_LOCAL_PWR_EN, pdata->base);
 
@@ -31,21 +35,39 @@ static int s5pv310_pd_enable(struct device *dev)
 	while ((__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN)
 		!= S5P_INT_LOCAL_PWR_EN) {
 		if (timeout == 0) {
-			printk(KERN_ERR "Power domain %s enable failed.\n",
-				dev_name(dev));
-			return -ETIMEDOUT;
+			dev_err(dev, "enable failed\n");
+			ret = -ETIMEDOUT;
+			goto done;
 		}
 		timeout--;
 		udelay(100);
 	}
 
-	return 0;
+	/* configure clk gate mask if it is present */
+	if (pdata->gate_mask) {
+		unsigned long flags;
+		unsigned long value;
+
+		spin_lock_irqsave(&gate_block_slock, flags);
+
+		value  = __raw_readl(S5P_CLKGATE_BLOCK);
+		value |= pdata->gate_mask;
+		__raw_writel(value, S5P_CLKGATE_BLOCK);
+
+		spin_unlock_irqrestore(&gate_block_slock, flags);
+	}
+
+done:
+	dev_info(dev, "enable finished\n");
+
+	return ret;
 }
 
 static int s5pv310_pd_disable(struct device *dev)
 {
 	struct samsung_pd_info *pdata =  dev->platform_data;
 	u32 timeout;
+	int ret = 0;
 
 	__raw_writel(0, pdata->base);
 
@@ -53,81 +75,108 @@ static int s5pv310_pd_disable(struct device *dev)
 	timeout = 10;
 	while (__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN) {
 		if (timeout == 0) {
-			printk(KERN_ERR "Power domain %s disable failed.\n",
-				dev_name(dev));
-			return -ETIMEDOUT;
+			dev_err(dev, "disable failed\n");
+			ret = -ETIMEDOUT;
+			goto done;
 		}
 		timeout--;
 		udelay(100);
 	}
 
-	return 0;
+	if (pdata->gate_mask) {
+		unsigned long flags;
+		unsigned long value;
+
+		spin_lock_irqsave(&gate_block_slock, flags);
+
+		value  = __raw_readl(S5P_CLKGATE_BLOCK);
+		value &= ~pdata->gate_mask;
+		__raw_writel(value, S5P_CLKGATE_BLOCK);
+
+		spin_unlock_irqrestore(&gate_block_slock, flags);
+	}
+done:
+	dev_info(dev, "disable finished\n");
+
+	return ret;
 }
 
 struct platform_device s5pv310_device_pd[] = {
-	{
+	[PD_MFC] = {
 		.name		= "samsung-pd",
-		.id		= 0,
+		.id		= PD_MFC,
 		.dev = {
 			.platform_data = &(struct samsung_pd_info) {
 				.enable		= s5pv310_pd_enable,
 				.disable	= s5pv310_pd_disable,
 				.base		= S5P_PMU_MFC_CONF,
+				.gate_mask	= S5P_CLKGATE_BLOCK_MFC,
 			},
 		},
-	}, {
+	},
+	[PD_G3D] = {
 		.name		= "samsung-pd",
-		.id		= 1,
+		.id		= PD_G3D,
 		.dev = {
 			.platform_data = &(struct samsung_pd_info) {
 				.enable		= s5pv310_pd_enable,
 				.disable	= s5pv310_pd_disable,
 				.base		= S5P_PMU_G3D_CONF,
+				.gate_mask	= S5P_CLKGATE_BLOCK_G3D,
 			},
 		},
-	}, {
+	},
+	[PD_LCD0] = {
 		.name		= "samsung-pd",
-		.id		= 2,
+		.id		= PD_LCD0,
 		.dev = {
 			.platform_data = &(struct samsung_pd_info) {
 				.enable		= s5pv310_pd_enable,
 				.disable	= s5pv310_pd_disable,
 				.base		= S5P_PMU_LCD0_CONF,
+				.gate_mask	= S5P_CLKGATE_BLOCK_LCD0,
 			},
 		},
-	}, {
+	},
+	[PD_LCD1] = {
 		.name		= "samsung-pd",
-		.id		= 3,
+		.id		= PD_LCD1,
 		.dev = {
 			.platform_data = &(struct samsung_pd_info) {
 				.enable		= s5pv310_pd_enable,
 				.disable	= s5pv310_pd_disable,
 				.base		= S5P_PMU_LCD1_CONF,
+				.gate_mask	= S5P_CLKGATE_BLOCK_LCD1,
 			},
 		},
-	}, {
+	},
+	[PD_TV] = {
 		.name		= "samsung-pd",
-		.id		= 4,
+		.id		= PD_TV,
 		.dev = {
 			.platform_data = &(struct samsung_pd_info) {
 				.enable		= s5pv310_pd_enable,
 				.disable	= s5pv310_pd_disable,
 				.base		= S5P_PMU_TV_CONF,
+				.gate_mask	= S5P_CLKGATE_BLOCK_TV,
 			},
 		},
-	}, {
+	},
+	[PD_CAM] = {
 		.name		= "samsung-pd",
-		.id		= 5,
+		.id		= PD_CAM,
 		.dev = {
 			.platform_data = &(struct samsung_pd_info) {
 				.enable		= s5pv310_pd_enable,
 				.disable	= s5pv310_pd_disable,
 				.base		= S5P_PMU_CAM_CONF,
+				.gate_mask	= S5P_CLKGATE_BLOCK_CAM,
 			},
 		},
-	}, {
+	},
+	[PD_GPS] = {
 		.name		= "samsung-pd",
-		.id		= 6,
+		.id		= PD_GPS,
 		.dev = {
 			.platform_data = &(struct samsung_pd_info) {
 				.enable		= s5pv310_pd_enable,
arch/arm/mach-s5pv310/include/mach/regs-clock.h +9 -0
index b5c4ada..341571a 100644
@@ -73,6 +73,7 @@
 #define S5P_CLKGATE_IP_FSYS		S5P_CLKREG(0x0C940)
 #define S5P_CLKGATE_IP_PERIL		S5P_CLKREG(0x0C950)
 #define S5P_CLKGATE_IP_PERIR		S5P_CLKREG(0x0C960)
+#define S5P_CLKGATE_BLOCK		S5P_CLKREG(0x0C970)
 
 #define S5P_CLKSRC_DMC			S5P_CLKREG(0x10200)
 #define S5P_CLKDIV_DMC0			S5P_CLKREG(0x10500)
@@ -160,6 +161,14 @@
 #define S5P_CLKDIV_BUS_GPLR_SHIFT	(4)
 #define S5P_CLKDIV_BUS_GPLR_MASK	(0x7 << S5P_CLKDIV_BUS_GPLR_SHIFT)
 
+/* CLKGATE_BLOCK */
+#define S5P_CLKGATE_BLOCK_CAM		(1 << 0)
+#define S5P_CLKGATE_BLOCK_TV		(1 << 1)
+#define S5P_CLKGATE_BLOCK_MFC		(1 << 2)
+#define S5P_CLKGATE_BLOCK_G3D		(1 << 3)
+#define S5P_CLKGATE_BLOCK_LCD0		(1 << 4)
+#define S5P_CLKGATE_BLOCK_LCD1		(1 << 5)
+
 /* Compatibility defines */
 
 #define S5P_EPLL_CON			S5P_EPLL_CON0
arch/arm/plat-samsung/include/plat/pd.h +1 -0
index 5f0ad85..36ba851 100644
@@ -15,6 +15,7 @@ struct samsung_pd_info {
 	int (*enable)(struct device *dev);
 	int (*disable)(struct device *dev);
 	void __iomem *base;
+	unsigned long gate_mask;
 };
 
 enum s5pv310_pd_block {
Signature · 1 line
1.7.1.569.g6f426
author maintainer
#4 lore raw

PATCH 3/7 ARM: Samsung: update/rewrite Samsung SYSMMU (IOMMU) driver

In reply to Marek Szyprowski

From: Andrzej Pietrasiewicz <[email protected]>

This patch performs a complete rewrite of sysmmu driver for Samsung platform:
- the new version introduces an api to construct device private page tables and enables to use device private address space mode
- simplified the resource management: no more single platform device with 32 resources is needed, better fits into linux driver model, each sysmmu instance has it's own resource definition
- added support for sysmmu clocks
- some other minor API chages required by upcoming videobuf2 allocator

---
 arch/arm/mach-s5pv310/clock.c                    |   91 ++
 arch/arm/mach-s5pv310/dev-sysmmu.c               |  582 +++++++++----
 arch/arm/mach-s5pv310/include/mach/irqs.h        |   36 +-
 arch/arm/mach-s5pv310/include/mach/regs-clock.h  |    3 +
 arch/arm/mach-s5pv310/include/mach/regs-sysmmu.h |   23 +-
 arch/arm/mach-s5pv310/include/mach/sysmmu.h      |  122 ---
 arch/arm/plat-s5p/Kconfig                        |   17 +-
 arch/arm/plat-s5p/include/plat/sysmmu.h          |  127 +++
 arch/arm/plat-s5p/sysmmu.c                       |  988 +++++++++++++++-------
 arch/arm/plat-samsung/include/plat/devs.h        |    2 +-
 10 files changed, 1323 insertions(+), 668 deletions(-)
 rewrite arch/arm/mach-s5pv310/dev-sysmmu.c (86%)
 delete mode 100644 arch/arm/mach-s5pv310/include/mach/sysmmu.h
 create mode 100644 arch/arm/plat-s5p/include/plat/sysmmu.h

rewrite arch/arm/plat-s5p/sysmmu.c (85%)

arch/arm/mach-s5pv310/clock.c +91 -0
index fc7c2f8..f142b8c 100644
@@ -20,6 +20,7 @@
 #include <plat/pll.h>
 #include <plat/s5p-clock.h>
 #include <plat/clock-clksrc.h>
+#include <plat/sysmmu.h>
 
 #include <mach/map.h>
 #include <mach/regs-clock.h>
@@ -116,6 +117,21 @@ static int s5pv310_clk_ip_perir_ctrl(struct clk *clk, int enable)
 	return s5p_gatectrl(S5P_CLKGATE_IP_PERIR, clk, enable);
 }
 
+static int s5pv310_clk_ip_dmc_ctrl(struct clk *clk, int enable)
+{
+	return s5p_gatectrl(S5P_CLKGATE_IP_DMC, clk, enable);
+}
+
+static int s5pv310_clk_ip_mfc_ctrl(struct clk *clk, int enable)
+{
+	return s5p_gatectrl(S5P_CLKGATE_IP_MFC, clk, enable);
+}
+
+static int s5pv310_clk_ip_tv_ctrl(struct clk *clk, int enable)
+{
+	return s5p_gatectrl(S5P_CLKGATE_IP_TV, clk, enable);
+}
+
 /* Core list of CMU_CPU side */
 
 static struct clksrc_clk clk_mout_apll = {
@@ -422,6 +438,81 @@ static struct clk init_clocks_off[] = {
 		.enable		= s5pv310_clk_ip_cam_ctrl,
 		.ctrlbit	= (1 << 3),
 	}, {
+		.name           = "sysmmu",
+		.id             = S5P_SYSMMU_MFC_L,
+		.enable         = s5pv310_clk_ip_mfc_ctrl,
+		.ctrlbit        = ((15 << 1) | 1),
+	}, {
+		.name           = "sysmmu",
+		.id             = S5P_SYSMMU_MFC_R,
+		.enable         = s5pv310_clk_ip_mfc_ctrl,
+		.ctrlbit        = ((15 << 1) | 1),
+	}, {
+		.name		= "sysmmu",
+		.id		= S5P_SYSMMU_FIMC0,
+		.enable		= s5pv310_clk_ip_cam_ctrl,
+		.ctrlbit	= (1 << 7),
+	}, {
+		.name		= "sysmmu",
+		.id		= S5P_SYSMMU_FIMC1,
+		.enable		= s5pv310_clk_ip_cam_ctrl,
+		.ctrlbit	= (1 << 8),
+	} , {
+		.name		= "sysmmu",
+		.id		= S5P_SYSMMU_FIMC2,
+		.enable		= s5pv310_clk_ip_cam_ctrl,
+		.ctrlbit	= (1 << 9),
+	} , {
+		.name		= "sysmmu",
+		.id		= S5P_SYSMMU_FIMC3,
+		.enable		= s5pv310_clk_ip_cam_ctrl,
+		.ctrlbit	= (1 << 10),
+	} , {
+		.name		= "sysmmu",
+		.id		= S5P_SYSMMU_JPEG,
+		.enable		= s5pv310_clk_ip_cam_ctrl,
+		.ctrlbit	= (1 << 11),
+	} , {
+		.name		= "sysmmu",
+		.id		= S5P_SYSMMU_TV,
+		.enable		= s5pv310_clk_ip_tv_ctrl,
+		.ctrlbit	= (1 << 4),
+	} , {
+		.name		= "sysmmu",
+		.id		= S5P_SYSMMU_G2D,
+		.enable		= s5pv310_clk_ip_image_ctrl,
+		.ctrlbit	= (1 << 3),
+	} , {
+		.name		= "sysmmu",
+		.id		= S5P_SYSMMU_ROTATOR,
+		.enable		= s5pv310_clk_ip_image_ctrl,
+		.ctrlbit	= (1 << 4),
+	} , {
+		.name		= "sysmmu",
+		.id		= S5P_SYSMMU_MDMA,
+		.enable		= s5pv310_clk_ip_image_ctrl,
+		.ctrlbit	= (1 << 5),
+	} , {
+		.name		= "sysmmu",
+		.id		= S5P_SYSMMU_FIMD0,
+		.enable		= s5pv310_clk_ip_lcd0_ctrl,
+		.ctrlbit	= (1 << 4),
+	} , {
+		.name		= "sysmmu",
+		.id		= S5P_SYSMMU_FIMD1,
+		.enable		= s5pv310_clk_ip_lcd1_ctrl,
+		.ctrlbit	= (1 << 4),
+	} , {
+		.name		= "sysmmu",
+		.id		= S5P_SYSMMU_PCIe,
+		.enable		= s5pv310_clk_ip_fsys_ctrl,
+		.ctrlbit	= (1 << 18),
+	} , {
+		.name		= "sysmmu",
+		.id		= S5P_SYSMMU_SSS,
+		.enable		= s5pv310_clk_ip_dmc_ctrl,
+		.ctrlbit	= (1 << 12),
+	} , {
 		.name		= "fimd",
 		.id		= 0,
 		.enable		= s5pv310_clk_ip_lcd0_ctrl,
arch/arm/mach-s5pv310/dev-sysmmu.c +395 -187

582 lines not on this page · raw message

arch/arm/mach-s5pv310/include/mach/irqs.h +19 -17
index 0e99968..f6b99c6 100644
@@ -55,23 +55,24 @@
 #define COMBINER_GROUP(x)	((x) * MAX_IRQ_IN_COMBINER + IRQ_SPI(64))
 #define COMBINER_IRQ(x, y)	(COMBINER_GROUP(x) + y)
 
-#define IRQ_SYSMMU_MDMA0_0	COMBINER_IRQ(4, 0)
-#define IRQ_SYSMMU_SSS_0	COMBINER_IRQ(4, 1)
-#define IRQ_SYSMMU_FIMC0_0	COMBINER_IRQ(4, 2)
-#define IRQ_SYSMMU_FIMC1_0	COMBINER_IRQ(4, 3)
-#define IRQ_SYSMMU_FIMC2_0	COMBINER_IRQ(4, 4)
-#define IRQ_SYSMMU_FIMC3_0	COMBINER_IRQ(4, 5)
-#define IRQ_SYSMMU_JPEG_0	COMBINER_IRQ(4, 6)
-#define IRQ_SYSMMU_2D_0		COMBINER_IRQ(4, 7)
-
-#define IRQ_SYSMMU_ROTATOR_0	COMBINER_IRQ(5, 0)
-#define IRQ_SYSMMU_MDMA1_0	COMBINER_IRQ(5, 1)
-#define IRQ_SYSMMU_LCD0_M0_0	COMBINER_IRQ(5, 2)
-#define IRQ_SYSMMU_LCD1_M1_0	COMBINER_IRQ(5, 3)
-#define IRQ_SYSMMU_TV_M0_0	COMBINER_IRQ(5, 4)
-#define IRQ_SYSMMU_MFC_M0_0	COMBINER_IRQ(5, 5)
-#define IRQ_SYSMMU_MFC_M1_0	COMBINER_IRQ(5, 6)
-#define IRQ_SYSMMU_PCIE_0	COMBINER_IRQ(5, 7)
+#define IRQ_SYSMMU_MDMA0	COMBINER_IRQ(4, 0)
+#define IRQ_SYSMMU_SSS		COMBINER_IRQ(4, 1)
+#define IRQ_SYSMMU_FIMC0	COMBINER_IRQ(4, 2)
+#define IRQ_SYSMMU_FIMC1	COMBINER_IRQ(4, 3)
+#define IRQ_SYSMMU_FIMC2	COMBINER_IRQ(4, 4)
+#define IRQ_SYSMMU_FIMC3	COMBINER_IRQ(4, 5)
+#define IRQ_SYSMMU_JPEG		COMBINER_IRQ(4, 6)
+#define IRQ_SYSMMU_2D		COMBINER_IRQ(4, 7)
+
+#define IRQ_SYSMMU_ROTATOR	COMBINER_IRQ(5, 0)
+#define IRQ_SYSMMU_MDMA1	COMBINER_IRQ(5, 1)
+#define IRQ_SYSMMU_FIMD0	COMBINER_IRQ(5, 2)
+#define IRQ_SYSMMU_FIMD1	COMBINER_IRQ(5, 3)
+#define IRQ_SYSMMU_TV		COMBINER_IRQ(5, 4)
+#define IRQ_SYSMMU_MFC_L	COMBINER_IRQ(5, 5)
+#define IRQ_SYSMMU_MFC_R	COMBINER_IRQ(5, 6)
+#define IRQ_SYSMMU_PCIE		COMBINER_IRQ(5, 7)
+
 
 #define IRQ_PDMA0		COMBINER_IRQ(21, 0)
 #define IRQ_PDMA1		COMBINER_IRQ(21, 1)
@@ -147,4 +148,5 @@
 
 #define NR_IRQS			(S5P_IRQ_EINT_BASE + 32)
 
+
 #endif /* __ASM_ARCH_IRQS_H */
arch/arm/mach-s5pv310/include/mach/regs-clock.h +3 -0
index 341571a..9ef5f0c 100644
@@ -67,6 +67,8 @@
 #define S5P_CLKDIV_STAT_TOP		S5P_CLKREG(0x0C610)
 
 #define S5P_CLKGATE_IP_CAM		S5P_CLKREG(0x0C920)
+#define S5P_CLKGATE_IP_MFC		S5P_CLKREG(0x0C928)
+#define S5P_CLKGATE_IP_TV		S5P_CLKREG(0x0C924)
 #define S5P_CLKGATE_IP_IMAGE		S5P_CLKREG(0x0C930)
 #define S5P_CLKGATE_IP_LCD0		S5P_CLKREG(0x0C934)
 #define S5P_CLKGATE_IP_LCD1		S5P_CLKREG(0x0C938)
@@ -78,6 +80,7 @@
 #define S5P_CLKSRC_DMC			S5P_CLKREG(0x10200)
 #define S5P_CLKDIV_DMC0			S5P_CLKREG(0x10500)
 #define S5P_CLKDIV_STAT_DMC0		S5P_CLKREG(0x10600)
+#define S5P_CLKGATE_IP_DMC		S5P_CLKREG(0x10900)
 
 #define S5P_APLL_LOCK			S5P_CLKREG(0x14000)
 #define S5P_MPLL_LOCK			S5P_CLKREG(0x14004)
arch/arm/mach-s5pv310/include/mach/regs-sysmmu.h +16 -7
index 0b28e81..dd2a954 100644
@@ -13,12 +13,21 @@
 #ifndef __ASM_ARCH_REGS_SYSMMU_H
 #define __ASM_ARCH_REGS_SYSMMU_H __FILE__
 
-#define S5P_MMU_CTRL			0x000
-#define S5P_MMU_CFG			0x004
-#define S5P_MMU_STATUS			0x008
-#define S5P_MMU_FLUSH			0x00C
-#define S5P_PT_BASE_ADDR		0x014
-#define S5P_INT_STATUS			0x018
-#define S5P_PAGE_FAULT_ADDR		0x024
+#define S5P_MMU_CTRL		(0x000)
+#define S5P_MMU_CFG		(0x004)
+#define S5P_MMU_STATUS		(0x008)
+#define S5P_MMU_FLUSH		(0x00C)
+#define S5P_MMU_FLUSH_ENTRY	(0x010)
+#define S5P_PT_BASE_ADDR	(0x014)
+#define S5P_INT_STATUS		(0x018)
+#define S5P_INT_CLEAR		(0x01C)
+#define S5P_INT_MASK		(0x020)
+#define S5P_PAGE_FAULT_ADDR	(0x024)
+#define S5P_AW_FAULT_ADDR	(0x028)
+#define S5P_AR_FAULT_ADDR	(0x02C)
+#define S5P_DEFAULT_SLAVE_ADDR	(0x030)
+#define S5P_MMU_VERSION		(0x034)
+#define S5P_TLB_READ            (0x038)
+#define S5P_TLB_DATA            (0x03C)
 
 #endif /* __ASM_ARCH_REGS_SYSMMU_H */
arch/arm/mach-s5pv310/include/mach/sysmmu.h deleted +0 -122

122 lines not on this page · raw message

arch/arm/plat-s5p/Kconfig +9 -8
index 0db2a7a..4166964 100644
@@ -37,14 +37,6 @@ config S5P_GPIO_INT
 	help
 	  Common code for the GPIO interrupts (other than external interrupts.)
 
-comment "System MMU"
-
-config S5P_SYSTEM_MMU
-	bool "S5P SYSTEM MMU"
-	depends on ARCH_S5PV310
-	help
-	  Say Y here if you want to enable System MMU
-
 config S5P_DEV_FIMC0
 	bool
 	help
@@ -79,3 +71,12 @@ config S5P_DEV_CSIS1
 	bool
 	help
 	  Compile in platform device definitions for MIPI-CSIS channel 1
+
+comment "System MMU"
+
+config S5P_SYSTEM_MMU
+	bool "S5P SYSTEM MMU"
+	depends on ARCH_S5PV310
+	help
+	  Say Y here if you want to enable System MMU
+
arch/arm/plat-s5p/include/plat/sysmmu.h new file +127 -0

127 lines not on this page · raw message

arch/arm/plat-s5p/sysmmu.c +662 -326

988 lines not on this page · raw message

arch/arm/plat-samsung/include/plat/devs.h +1 -1
index b0123f3..9f42dee 100644
@@ -138,7 +138,7 @@ extern struct platform_device s5p_device_fimc3;
 extern struct platform_device s5p_device_mipi_csis0;
 extern struct platform_device s5p_device_mipi_csis1;
 
-extern struct platform_device s5pv310_device_sysmmu;
+extern struct platform_device s5pv310_device_sysmmu[];
 
 /* s3c2440 specific devices */
 
Signature · 1 line
1.7.1.569.g6f426
author maintainer
#5 lore raw

PATCH 3/7 ARM: Samsung: update/rewrite Samsung SYSMMU (IOMMU) driver

From: Andrzej Pietrasiewicz <[email protected]>

This patch performs a complete rewrite of sysmmu driver for Samsung platform:
- the new version introduces an api to construct device private page tables and enables to use device private address space mode
- simplified the resource management: no more single platform device with 32 resources is needed, better fits into linux driver model, each sysmmu instance has it's own resource definition
- added support for sysmmu clocks
- some other minor API chages required by upcoming videobuf2 allocator

---

Hello,

I'm really sorry for breaking this patch in the previous mail. The semi-colon is missing in the "EXPORT_SYMBOL_GPL(s5p_sysmmu_unmap_area)" line. This is the fixed version.

Best regards
--
Marek Szyprowski
Samsung Poland R&D Center

---
 arch/arm/mach-s5pv310/clock.c                    |   91 ++
 arch/arm/mach-s5pv310/dev-sysmmu.c               |  582 +++++++++----
 arch/arm/mach-s5pv310/include/mach/irqs.h        |   36 +-
 arch/arm/mach-s5pv310/include/mach/regs-clock.h  |    3 +
 arch/arm/mach-s5pv310/include/mach/regs-sysmmu.h |   23 +-
 arch/arm/mach-s5pv310/include/mach/sysmmu.h      |  122 ---
 arch/arm/plat-s5p/Kconfig                        |   17 +-
 arch/arm/plat-s5p/include/plat/sysmmu.h          |  127 +++
 arch/arm/plat-s5p/sysmmu.c                       |  988 +++++++++++++++-------
 arch/arm/plat-samsung/include/plat/devs.h        |    2 +-
 10 files changed, 1323 insertions(+), 668 deletions(-)
 rewrite arch/arm/mach-s5pv310/dev-sysmmu.c (86%)
 delete mode 100644 arch/arm/mach-s5pv310/include/mach/sysmmu.h
 create mode 100644 arch/arm/plat-s5p/include/plat/sysmmu.h

rewrite arch/arm/plat-s5p/sysmmu.c (85%)

arch/arm/mach-s5pv310/clock.c +91 -0
index fc7c2f8..f142b8c 100644
@@ -20,6 +20,7 @@
 #include <plat/pll.h>
 #include <plat/s5p-clock.h>
 #include <plat/clock-clksrc.h>
+#include <plat/sysmmu.h>
 
 #include <mach/map.h>
 #include <mach/regs-clock.h>
@@ -116,6 +117,21 @@ static int s5pv310_clk_ip_perir_ctrl(struct clk *clk, int enable)
 	return s5p_gatectrl(S5P_CLKGATE_IP_PERIR, clk, enable);
 }
 
+static int s5pv310_clk_ip_dmc_ctrl(struct clk *clk, int enable)
+{
+	return s5p_gatectrl(S5P_CLKGATE_IP_DMC, clk, enable);
+}
+
+static int s5pv310_clk_ip_mfc_ctrl(struct clk *clk, int enable)
+{
+	return s5p_gatectrl(S5P_CLKGATE_IP_MFC, clk, enable);
+}
+
+static int s5pv310_clk_ip_tv_ctrl(struct clk *clk, int enable)
+{
+	return s5p_gatectrl(S5P_CLKGATE_IP_TV, clk, enable);
+}
+
 /* Core list of CMU_CPU side */
 
 static struct clksrc_clk clk_mout_apll = {
@@ -422,6 +438,81 @@ static struct clk init_clocks_off[] = {
 		.enable		= s5pv310_clk_ip_cam_ctrl,
 		.ctrlbit	= (1 << 3),
 	}, {
+		.name           = "sysmmu",
+		.id             = S5P_SYSMMU_MFC_L,
+		.enable         = s5pv310_clk_ip_mfc_ctrl,
+		.ctrlbit        = ((15 << 1) | 1),
+	}, {
+		.name           = "sysmmu",
+		.id             = S5P_SYSMMU_MFC_R,
+		.enable         = s5pv310_clk_ip_mfc_ctrl,
+		.ctrlbit        = ((15 << 1) | 1),
+	}, {
+		.name		= "sysmmu",
+		.id		= S5P_SYSMMU_FIMC0,
+		.enable		= s5pv310_clk_ip_cam_ctrl,
+		.ctrlbit	= (1 << 7),
+	}, {
+		.name		= "sysmmu",
+		.id		= S5P_SYSMMU_FIMC1,
+		.enable		= s5pv310_clk_ip_cam_ctrl,
+		.ctrlbit	= (1 << 8),
+	} , {
+		.name		= "sysmmu",
+		.id		= S5P_SYSMMU_FIMC2,
+		.enable		= s5pv310_clk_ip_cam_ctrl,
+		.ctrlbit	= (1 << 9),
+	} , {
+		.name		= "sysmmu",
+		.id		= S5P_SYSMMU_FIMC3,
+		.enable		= s5pv310_clk_ip_cam_ctrl,
+		.ctrlbit	= (1 << 10),
+	} , {
+		.name		= "sysmmu",
+		.id		= S5P_SYSMMU_JPEG,
+		.enable		= s5pv310_clk_ip_cam_ctrl,
+		.ctrlbit	= (1 << 11),
+	} , {
+		.name		= "sysmmu",
+		.id		= S5P_SYSMMU_TV,
+		.enable		= s5pv310_clk_ip_tv_ctrl,
+		.ctrlbit	= (1 << 4),
+	} , {
+		.name		= "sysmmu",
+		.id		= S5P_SYSMMU_G2D,
+		.enable		= s5pv310_clk_ip_image_ctrl,
+		.ctrlbit	= (1 << 3),
+	} , {
+		.name		= "sysmmu",
+		.id		= S5P_SYSMMU_ROTATOR,
+		.enable		= s5pv310_clk_ip_image_ctrl,
+		.ctrlbit	= (1 << 4),
+	} , {
+		.name		= "sysmmu",
+		.id		= S5P_SYSMMU_MDMA,
+		.enable		= s5pv310_clk_ip_image_ctrl,
+		.ctrlbit	= (1 << 5),
+	} , {
+		.name		= "sysmmu",
+		.id		= S5P_SYSMMU_FIMD0,
+		.enable		= s5pv310_clk_ip_lcd0_ctrl,
+		.ctrlbit	= (1 << 4),
+	} , {
+		.name		= "sysmmu",
+		.id		= S5P_SYSMMU_FIMD1,
+		.enable		= s5pv310_clk_ip_lcd1_ctrl,
+		.ctrlbit	= (1 << 4),
+	} , {
+		.name		= "sysmmu",
+		.id		= S5P_SYSMMU_PCIe,
+		.enable		= s5pv310_clk_ip_fsys_ctrl,
+		.ctrlbit	= (1 << 18),
+	} , {
+		.name		= "sysmmu",
+		.id		= S5P_SYSMMU_SSS,
+		.enable		= s5pv310_clk_ip_dmc_ctrl,
+		.ctrlbit	= (1 << 12),
+	} , {
 		.name		= "fimd",
 		.id		= 0,
 		.enable		= s5pv310_clk_ip_lcd0_ctrl,
arch/arm/mach-s5pv310/dev-sysmmu.c +395 -187

582 lines not on this page · raw message

arch/arm/mach-s5pv310/include/mach/irqs.h +19 -17
index 0e99968..f6b99c6 100644
@@ -55,23 +55,24 @@
 #define COMBINER_GROUP(x)	((x) * MAX_IRQ_IN_COMBINER + IRQ_SPI(64))
 #define COMBINER_IRQ(x, y)	(COMBINER_GROUP(x) + y)
 
-#define IRQ_SYSMMU_MDMA0_0	COMBINER_IRQ(4, 0)
-#define IRQ_SYSMMU_SSS_0	COMBINER_IRQ(4, 1)
-#define IRQ_SYSMMU_FIMC0_0	COMBINER_IRQ(4, 2)
-#define IRQ_SYSMMU_FIMC1_0	COMBINER_IRQ(4, 3)
-#define IRQ_SYSMMU_FIMC2_0	COMBINER_IRQ(4, 4)
-#define IRQ_SYSMMU_FIMC3_0	COMBINER_IRQ(4, 5)
-#define IRQ_SYSMMU_JPEG_0	COMBINER_IRQ(4, 6)
-#define IRQ_SYSMMU_2D_0		COMBINER_IRQ(4, 7)
-
-#define IRQ_SYSMMU_ROTATOR_0	COMBINER_IRQ(5, 0)
-#define IRQ_SYSMMU_MDMA1_0	COMBINER_IRQ(5, 1)
-#define IRQ_SYSMMU_LCD0_M0_0	COMBINER_IRQ(5, 2)
-#define IRQ_SYSMMU_LCD1_M1_0	COMBINER_IRQ(5, 3)
-#define IRQ_SYSMMU_TV_M0_0	COMBINER_IRQ(5, 4)
-#define IRQ_SYSMMU_MFC_M0_0	COMBINER_IRQ(5, 5)
-#define IRQ_SYSMMU_MFC_M1_0	COMBINER_IRQ(5, 6)
-#define IRQ_SYSMMU_PCIE_0	COMBINER_IRQ(5, 7)
+#define IRQ_SYSMMU_MDMA0	COMBINER_IRQ(4, 0)
+#define IRQ_SYSMMU_SSS		COMBINER_IRQ(4, 1)
+#define IRQ_SYSMMU_FIMC0	COMBINER_IRQ(4, 2)
+#define IRQ_SYSMMU_FIMC1	COMBINER_IRQ(4, 3)
+#define IRQ_SYSMMU_FIMC2	COMBINER_IRQ(4, 4)
+#define IRQ_SYSMMU_FIMC3	COMBINER_IRQ(4, 5)
+#define IRQ_SYSMMU_JPEG		COMBINER_IRQ(4, 6)
+#define IRQ_SYSMMU_2D		COMBINER_IRQ(4, 7)
+
+#define IRQ_SYSMMU_ROTATOR	COMBINER_IRQ(5, 0)
+#define IRQ_SYSMMU_MDMA1	COMBINER_IRQ(5, 1)
+#define IRQ_SYSMMU_FIMD0	COMBINER_IRQ(5, 2)
+#define IRQ_SYSMMU_FIMD1	COMBINER_IRQ(5, 3)
+#define IRQ_SYSMMU_TV		COMBINER_IRQ(5, 4)
+#define IRQ_SYSMMU_MFC_L	COMBINER_IRQ(5, 5)
+#define IRQ_SYSMMU_MFC_R	COMBINER_IRQ(5, 6)
+#define IRQ_SYSMMU_PCIE		COMBINER_IRQ(5, 7)
+
 
 #define IRQ_PDMA0		COMBINER_IRQ(21, 0)
 #define IRQ_PDMA1		COMBINER_IRQ(21, 1)
@@ -147,4 +148,5 @@
 
 #define NR_IRQS			(S5P_IRQ_EINT_BASE + 32)
 
+
 #endif /* __ASM_ARCH_IRQS_H */
arch/arm/mach-s5pv310/include/mach/regs-clock.h +3 -0
index 341571a..9ef5f0c 100644
@@ -67,6 +67,8 @@
 #define S5P_CLKDIV_STAT_TOP		S5P_CLKREG(0x0C610)
 
 #define S5P_CLKGATE_IP_CAM		S5P_CLKREG(0x0C920)
+#define S5P_CLKGATE_IP_MFC		S5P_CLKREG(0x0C928)
+#define S5P_CLKGATE_IP_TV		S5P_CLKREG(0x0C924)
 #define S5P_CLKGATE_IP_IMAGE		S5P_CLKREG(0x0C930)
 #define S5P_CLKGATE_IP_LCD0		S5P_CLKREG(0x0C934)
 #define S5P_CLKGATE_IP_LCD1		S5P_CLKREG(0x0C938)
@@ -78,6 +80,7 @@
 #define S5P_CLKSRC_DMC			S5P_CLKREG(0x10200)
 #define S5P_CLKDIV_DMC0			S5P_CLKREG(0x10500)
 #define S5P_CLKDIV_STAT_DMC0		S5P_CLKREG(0x10600)
+#define S5P_CLKGATE_IP_DMC		S5P_CLKREG(0x10900)
 
 #define S5P_APLL_LOCK			S5P_CLKREG(0x14000)
 #define S5P_MPLL_LOCK			S5P_CLKREG(0x14004)
arch/arm/mach-s5pv310/include/mach/regs-sysmmu.h +16 -7
index 0b28e81..dd2a954 100644
@@ -13,12 +13,21 @@
 #ifndef __ASM_ARCH_REGS_SYSMMU_H
 #define __ASM_ARCH_REGS_SYSMMU_H __FILE__
 
-#define S5P_MMU_CTRL			0x000
-#define S5P_MMU_CFG			0x004
-#define S5P_MMU_STATUS			0x008
-#define S5P_MMU_FLUSH			0x00C
-#define S5P_PT_BASE_ADDR		0x014
-#define S5P_INT_STATUS			0x018
-#define S5P_PAGE_FAULT_ADDR		0x024
+#define S5P_MMU_CTRL		(0x000)
+#define S5P_MMU_CFG		(0x004)
+#define S5P_MMU_STATUS		(0x008)
+#define S5P_MMU_FLUSH		(0x00C)
+#define S5P_MMU_FLUSH_ENTRY	(0x010)
+#define S5P_PT_BASE_ADDR	(0x014)
+#define S5P_INT_STATUS		(0x018)
+#define S5P_INT_CLEAR		(0x01C)
+#define S5P_INT_MASK		(0x020)
+#define S5P_PAGE_FAULT_ADDR	(0x024)
+#define S5P_AW_FAULT_ADDR	(0x028)
+#define S5P_AR_FAULT_ADDR	(0x02C)
+#define S5P_DEFAULT_SLAVE_ADDR	(0x030)
+#define S5P_MMU_VERSION		(0x034)
+#define S5P_TLB_READ            (0x038)
+#define S5P_TLB_DATA            (0x03C)
 
 #endif /* __ASM_ARCH_REGS_SYSMMU_H */
arch/arm/mach-s5pv310/include/mach/sysmmu.h deleted +0 -122

122 lines not on this page · raw message

arch/arm/plat-s5p/Kconfig +9 -8
index 0db2a7a..4166964 100644
@@ -37,14 +37,6 @@ config S5P_GPIO_INT
 	help
 	  Common code for the GPIO interrupts (other than external interrupts.)
 
-comment "System MMU"
-
-config S5P_SYSTEM_MMU
-	bool "S5P SYSTEM MMU"
-	depends on ARCH_S5PV310
-	help
-	  Say Y here if you want to enable System MMU
-
 config S5P_DEV_FIMC0
 	bool
 	help
@@ -79,3 +71,12 @@ config S5P_DEV_CSIS1
 	bool
 	help
 	  Compile in platform device definitions for MIPI-CSIS channel 1
+
+comment "System MMU"
+
+config S5P_SYSTEM_MMU
+	bool "S5P SYSTEM MMU"
+	depends on ARCH_S5PV310
+	help
+	  Say Y here if you want to enable System MMU
+
arch/arm/plat-s5p/include/plat/sysmmu.h new file +127 -0

127 lines not on this page · raw message

arch/arm/plat-s5p/sysmmu.c +662 -326

988 lines not on this page · raw message

arch/arm/plat-samsung/include/plat/devs.h +1 -1
index b0123f3..9f42dee 100644
@@ -138,7 +138,7 @@ extern struct platform_device s5p_device_fimc3;
 extern struct platform_device s5p_device_mipi_csis0;
 extern struct platform_device s5p_device_mipi_csis1;
 
-extern struct platform_device s5pv310_device_sysmmu;
+extern struct platform_device s5pv310_device_sysmmu[];
 
 /* s3c2440 specific devices */
 
Signature · 1 line
1.7.1.569.g6f426
#6 lore raw

PATCH 3/7 ARM: Samsung: update/rewrite Samsung SYSMMU (IOMMU) driver

Quoted 11 lines · Marek Szyprowski

From: Andrzej Pietrasiewicz <[email protected]>

This patch performs a complete rewrite of sysmmu driver for Samsung platform:
- the new version introduces an api to construct device private page tables and enables to use device private address space mode
- simplified the resource management: no more single platform device with 32 resources is needed, better fits into linux driver model, each sysmmu instance has it's own resource definition
- added support for sysmmu clocks
- some other minor API chages required by upcoming videobuf2 allocator

Quoted 3 lines

Please explain why create a new IOMMU API when we already have two generic ones (include/linux/iommu.h and include/linux/dma-mapping.h).

Is there something that cannot be done with the common code? The first approach should be to extend the existing APIs to do what you need.

Arnd

author maintainer
#7 lore raw

PATCH 3/7 ARM: Samsung: update/rewrite Samsung SYSMMU (IOMMU) driver

Hello,

Quoted 16 lines · Arnd Bergmann
Quoted 11 lines · Marek Szyprowski

From: Andrzej Pietrasiewicz <[email protected]>

This patch performs a complete rewrite of sysmmu driver for Samsung platform:
- the new version introduces an api to construct device private page tables and enables to use device private address space mode
- simplified the resource management: no more single platform device with 32 resources is needed, better fits into linux driver model, each sysmmu instance has it's own resource definition
- added support for sysmmu clocks
- some other minor API chages required by upcoming videobuf2 allocator

Quoted 3 lines
Quoted 6 lines

Please explain why create a new IOMMU API when we already have two generic ones (include/linux/iommu.h and include/linux/dma-mapping.h).

Is there something that cannot be done with the common code? The first approach should be to extend the existing APIs to do what you need.

We followed the style of iommu API for other mainline ARM platforms (both OMAP and MSM also have custom API for their iommu modules). I've briefly checked include/linux/iommu.h API and I've noticed that it has been designed mainly for KVM support. There is also include/linux/intel-iommu.h interface, but I it is very specific to intel gfx chips.

Is there any example how include/linux/dma-mapping.h interface can be used for iommu mappings?

Best regards
--
Marek Szyprowski
Samsung Poland R&D Center

#8 lore raw

Re: [PATCH 3/7] ARM: Samsung: update/rewrite Samsung SYSMMU (IOMMU) driver

Quoted 5 lines · Marek Szyprowski

We followed the style of iommu API for other mainline ARM platforms (both OMAP and MSM also have custom API for their iommu modules). I've briefly checked include/linux/iommu.h API and I've noticed that it has been designed mainly for KVM support. There is also include/linux/intel-iommu.h interface, but I it is very specific to intel gfx chips.

The MSM code actually uses the generic iommu.h code, using register_iommu, so the drivers can use the regular iommu_map.

I believe the omap code predates the iommu API, and should really be changed to use that. At least it was added before I started reviewing the code.

The iommu API is not really meant to be KVM specific, it's just that the in-tree users are basically limited to KVM at the moment. Another user that is coming up soon is the vmio device driver that can be used to transparently pass devices to user space. The idea behind the IOMMU API is that you can map arbitrary bus addresses to physical memory addresses, but it does not deal with allocating the bus addresses or providing buffer management such as cache flushes.

Quoted 2 lines

Is there any example how include/linux/dma-mapping.h interface can be used for iommu mappings?

The dma-mapping API is the normal interface that you should use for IOMMUs that sit between DMA devices and kernel memory. The idea is that you completely abstract the concept of an IOMMU so the device driver uses the same code for talking to a device with an IOMMU and another device with a linear mapping or an swiotlb bounce buffer.

This means that the user of the dma-mapping API does not get to choose the bus addresses, but instead you use the API to get a bus address for a chunk of memory, and then you can pass that address to a device.

See arch/powerpc/kernel/iommu.c and arch/x86/kernel/amd_iommu.c for common examples of how this is implemented. The latter one actually implements both the iommu_ops for iommu.h and dma_map_ops for dma-mapping.h.

Arnd

author maintainer
#9 lore raw

RE: [PATCH 3/7] ARM: Samsung: update/rewrite Samsung SYSMMU (IOMMU) driver

Hello,

Quoted 13 lines · Arnd Bergmann
Quoted 5 lines · Marek Szyprowski

We followed the style of iommu API for other mainline ARM platforms (both OMAP and MSM also have custom API for their iommu modules). I've briefly checked include/linux/iommu.h API and I've noticed that it has been designed mainly for KVM support. There is also include/linux/intel-iommu.h interface, but I it is very specific to intel gfx chips.

The MSM code actually uses the generic iommu.h code, using register_iommu, so the drivers can use the regular iommu_map.

I believe the omap code predates the iommu API, and should really be changed to use that. At least it was added before I started reviewing the code.

Quoted 7 lines

The iommu API is not really meant to be KVM specific, it's just that the in-tree users are basically limited to KVM at the moment. Another user that is coming up soon is the vmio device driver that can be used to transparently pass devices to user space. The idea behind the IOMMU API is that you can map arbitrary bus addresses to physical memory addresses, but it does not deal with allocating the bus addresses or providing buffer management such as cache flushes.

Yea, I've noticed this and this basically what we expect from iommu driver. However the iommu.h API requires a separate call to map each single memory page. This is quite ineffective approach and imho the API need to be extended to allow mapping of the arbitrary set of pages.

Quoted 9 lines
Quoted 2 lines

Is there any example how include/linux/dma-mapping.h interface can be used for iommu mappings?

The dma-mapping API is the normal interface that you should use for IOMMUs that sit between DMA devices and kernel memory. The idea is that you completely abstract the concept of an IOMMU so the device driver uses the same code for talking to a device with an IOMMU and another device with a linear mapping or an swiotlb bounce buffer.

Quoted 7 lines

This means that the user of the dma-mapping API does not get to choose the bus addresses, but instead you use the API to get a bus address for a chunk of memory, and then you can pass that address to a device.

See arch/powerpc/kernel/iommu.c and arch/x86/kernel/amd_iommu.c for common examples of how this is implemented. The latter one actually implements both the iommu_ops for iommu.h and dma_map_ops for dma-mapping.h.

Thanks for your comments! We will check how is it suitable for our case.

Best regards
--
Marek Szyprowski
Samsung Poland R&D Center

#10 lore raw

Re: [PATCH 3/7] ARM: Samsung: update/rewrite Samsung SYSMMU (IOMMU) driver

Quoted 8 lines · Marek Szyprowski
Quoted 7 lines

The iommu API is not really meant to be KVM specific, it's just that the in-tree users are basically limited to KVM at the moment. Another user that is coming up soon is the vmio device driver that can be used to transparently pass devices to user space. The idea behind the IOMMU API is that you can map arbitrary bus addresses to physical memory addresses, but it does not deal with allocating the bus addresses or providing buffer management such as cache flushes.

Quoted 4 lines

Yea, I've noticed this and this basically what we expect from iommu driver. However the iommu.h API requires a separate call to map each single memory page. This is quite ineffective approach and imho the API need to be extended to allow mapping of the arbitrary set of pages.

We can always discuss extensions to the existing infrastructure, adding an interface for mapping an array of page pointers in the iommu API sounds like a good idea.

I also think that we should not really have separate iommu and dma-mapping interfaces, but rather have a portable way to define an iommu so that it can be used through the dma-mapping interfaces. I'm not asking you to do that as a prerequisite to merging your driver, but it may be good to keep in mind that the current situation is still lacking and that any suggestion for improving this as part of your work to support the samsung IOMMU is welcome.

Note that the ARM implementation of the dma-mapping.h interface currently does not support IOMMUs, but that could be changed by wrapping it using the include/asm-generic/dma-mapping-common.h infrastructure.

Arnd

author maintainer
#11 lore raw

RE: [PATCH 3/7] ARM: Samsung: update/rewrite Samsung SYSMMU (IOMMU) driver

Hello,

Quoted 9 lines · Arnd Bergmann
Quoted 8 lines · Marek Szyprowski
Quoted 7 lines

The iommu API is not really meant to be KVM specific, it's just that the in-tree users are basically limited to KVM at the moment. Another user that is coming up soon is the vmio device driver that can be used to transparently pass devices to user space. The idea behind the IOMMU API is that you can map arbitrary bus addresses to physical memory addresses, but it does not deal with allocating the bus addresses or providing buffer management such as cache flushes.

Quoted 8 lines
Quoted 4 lines

Yea, I've noticed this and this basically what we expect from iommu driver. However the iommu.h API requires a separate call to map each single memory page. This is quite ineffective approach and imho the API need to be extended to allow mapping of the arbitrary set of pages.

We can always discuss extensions to the existing infrastructure, adding an interface for mapping an array of page pointers in the iommu API sounds like a good idea.

We will investigate this API further. From the first sight it looks it won't take much work to port/rewrite our driver to fit into iommu.h API.

Quoted 7 lines

I also think that we should not really have separate iommu and dma-mapping interfaces, but rather have a portable way to define an iommu so that it can be used through the dma-mapping interfaces. I'm not asking you to do that as a prerequisite to merging your driver, but it may be good to keep in mind that the current situation is still lacking and that any suggestion for improving this as part of your work to support the samsung IOMMU is welcome.

Well creating a portable iommu framework and merging it with dma-mapping interface looks like a much harder (and time consuming) task. There is definitely a need for it. I hope that it can be developed incrementally starting from the current iommu.h and dma-mapping.h interfaces. Please note that there might be some subtle differences in the hardware that such framework must be aware. The first obvious one is the hardware design. Some platform has central iommu unit, other (like Samsung Exynos4) has a separate iommu unit per each device driver (this is still a simplification, because a video codec device has 2 memory interfaces and 2 iommu units). Currently I probably have not enough knowledge to predict the other possible issues that need to be taken into account in the portable and generic iommu/dma-mapping frame-work.

Quoted 3 lines

Note that the ARM implementation of the dma-mapping.h interface currently does not support IOMMUs, but that could be changed by wrapping it using the include/asm-generic/dma-mapping-common.h infrastructure.

ARM dma-mapping framework also requires some additional research for better DMA support (there are still issues with multiple mappings to be resolved).

Best regards
--
Marek Szyprowski
Samsung Poland R&D Center

#12 lore raw

Re: [PATCH 3/7] ARM: Samsung: update/rewrite Samsung SYSMMU (IOMMU) driver

Quoted 16 lines · Marek Szyprowski
Quoted 14 lines · Arnd Bergmann
Quoted 12 lines · Marek Szyprowski
Quoted 7 lines

The iommu API is not really meant to be KVM specific, it's just that the in-tree users are basically limited to KVM at the moment. Another user that is coming up soon is the vmio device driver that can be used to transparently pass devices to user space. The idea behind the IOMMU API is that you can map arbitrary bus addresses to physical memory addresses, but it does not deal with allocating the bus addresses or providing buffer management such as cache flushes.

Yea, I've noticed this and this basically what we expect from iommu driver. However the iommu.h API requires a separate call to map each single memory page. This is quite ineffective approach and imho the API need to be extended to allow mapping of the arbitrary set of pages.

Quoted 6 lines
Quoted 3 lines

We can always discuss extensions to the existing infrastructure, adding an interface for mapping an array of page pointers in the iommu API sounds like a good idea.

We will investigate this API further. From the first sight it looks it won't take much work to port/rewrite our driver to fit into iommu.h API.

Ok, sounds good.

Quoted 8 lines
Quoted 7 lines

I also think that we should not really have separate iommu and dma-mapping interfaces, but rather have a portable way to define an iommu so that it can be used through the dma-mapping interfaces. I'm not asking you to do that as a prerequisite to merging your driver, but it may be good to keep in mind that the current situation is still lacking and that any suggestion for improving this as part of your work to support the samsung IOMMU is welcome.

Quoted 4 lines

Well creating a portable iommu framework and merging it with dma-mapping interface looks like a much harder (and time consuming) task. There is definitely a need for it. I hope that it can be developed incrementally starting from the current iommu.h and dma-mapping.h interfaces.

Yes, that is the idea. Maybe we should add it to the list things that the Linaro kernel working group can target for the November release?

Quoted 7 lines

Please note that there might be some subtle differences
in the hardware that such framework must be aware. The first obvious one is the hardware design. Some platform has central iommu unit, other (like Samsung Exynos4) has a separate iommu unit per each device driver (this is still a simplification, because a video codec device has 2 memory interfaces and 2 iommu units). Currently I probably have not enough knowledge to predict the other possible issues that need to be taken into account in the portable and generic iommu/dma-mapping frame-work.

The dma-mapping API can deal well with one IOMMU per device, but would need some tricks to work with one device that has two separate IOMMUs.

I'm not very familar with the iommu API, but in the common KVM scenario, you need one IOMMU per device, so it should handle that just fine as well.

Quoted 6 lines
Quoted 3 lines

Note that the ARM implementation of the dma-mapping.h interface currently does not support IOMMUs, but that could be changed by wrapping it using the include/asm-generic/dma-mapping-common.h infrastructure.

ARM dma-mapping framework also requires some additional research for better DMA support (there are still issues with multiple mappings to be resolved).

You mean mapping the same memory into multiple devices, or a different problem?

Arnd

author maintainer
#13 lore raw

RE: [PATCH 3/7] ARM: Samsung: update/rewrite Samsung SYSMMU (IOMMU) driver

Hello,

Quoted 50 lines · Arnd Bergmann
Quoted 16 lines · Marek Szyprowski
Quoted 14 lines · Arnd Bergmann
Quoted 12 lines · Marek Szyprowski
Quoted 7 lines

The iommu API is not really meant to be KVM specific, it's just that the in-tree users are basically limited to KVM at the moment. Another user that is coming up soon is the vmio device driver that can be used to transparently pass devices to user space. The idea behind the IOMMU API is that you can map arbitrary bus addresses to physical memory addresses, but it does not deal with allocating the bus addresses or providing buffer management such as cache flushes.

Yea, I've noticed this and this basically what we expect from iommu driver. However the iommu.h API requires a separate call to map each single memory page. This is quite ineffective approach and imho the API need to be extended to allow mapping of the arbitrary set of pages.

Quoted 6 lines
Quoted 3 lines

We can always discuss extensions to the existing infrastructure, adding an interface for mapping an array of page pointers in the iommu API sounds like a good idea.

We will investigate this API further. From the first sight it looks it won't take much work to port/rewrite our driver to fit into iommu.h API.

Ok, sounds good.

Quoted 8 lines
Quoted 7 lines

I also think that we should not really have separate iommu and dma-mapping interfaces, but rather have a portable way to define an iommu so that it can be used through the dma-mapping interfaces. I'm not asking you to do that as a prerequisite to merging your driver, but it may be good to keep in mind that the current situation is still lacking and that any suggestion for improving this as part of your work to support the samsung IOMMU is welcome.

Quoted 4 lines

Well creating a portable iommu framework and merging it with dma-mapping interface looks like a much harder (and time consuming) task. There is definitely a need for it. I hope that it can be developed incrementally starting from the current iommu.h and dma-mapping.h interfaces.

Yes, that is the idea. Maybe we should add it to the list things that the Linaro kernel working group can target for the November release?

Quoted 7 lines

Please note that there might be some subtle differences
in the hardware that such framework must be aware. The first obvious one is the hardware design. Some platform has central iommu unit, other (like Samsung Exynos4) has a separate iommu unit per each device driver (this is still a simplification, because a video codec device has 2 memory interfaces and 2 iommu units). Currently I probably have not enough knowledge to predict the other possible issues that need to be taken into account in the portable and generic iommu/dma-mapping frame-work.

Quoted 2 lines

The dma-mapping API can deal well with one IOMMU per device, but would need some tricks to work with one device that has two separate IOMMUs.

We need to investigate the internals of dma-mapping API first. Right now I know too little in this area.

Quoted 2 lines

I'm not very familar with the iommu API, but in the common KVM scenario, you need one IOMMU per device, so it should handle that just fine as well.

Well, afair there are also systems with one central iommu module, which is shared between devices. I have no idea how such model will fit into the dma-mapping API.

Quoted 8 lines
Quoted 6 lines
Quoted 3 lines

Note that the ARM implementation of the dma-mapping.h interface currently does not support IOMMUs, but that could be changed by wrapping it using the include/asm-generic/dma-mapping-common.h infrastructure.

ARM dma-mapping framework also requires some additional research for better DMA support (there are still issues with multiple mappings to be resolved).

You mean mapping the same memory into multiple devices, or a different problem?

Mapping the same memory area multiple times with different cache settings is not legal on ARMv7+ systems. Currently the problems might caused by the low-memory kernel linear mapping and second mapping created for example by dma_alloc_coherent() function.

Best regards
--
Marek Szyprowski
Samsung Poland R&D Center

#14 lore raw

Re: [PATCH 3/7] ARM: Samsung: update/rewrite Samsung SYSMMU (IOMMU) driver

Quoted 6 lines · Marek Szyprowski
Quoted 6 lines
Quoted 5 lines
Quoted 2 lines

does not support IOMMUs, but that could be changed by wrapping it using the include/asm-generic/dma-mapping-common.h infrastructure.

ARM dma-mapping framework also requires some additional research for better DMA support (there are still issues with multiple mappings to be resolved).

Quoted 6 lines
Quoted 1 line

You mean mapping the same memory into multiple devices, or a different problem?

Mapping the same memory area multiple times with different cache settings is not legal on ARMv7+ systems. Currently the problems might caused by the low-memory kernel linear mapping and second mapping created for example by dma_alloc_coherent() function.

Yes, I know this problem, but I don't think the case you describe is a serious limitation (there are more interesting cases, though): dma_map_single() etc will create additional *bus* addresses for a physical address, not additional virtual addresses.

dma_alloc_coherent should allocate memory that is not also mapped cached, which is what I thought we do correctly.

Arnd

#15 lore raw

Re: [PATCH 3/7] ARM: Samsung: update/rewrite Samsung SYSMMU (IOMMU) driver

2011/3/12 Arnd Bergmann <[email protected]>:

Quoted 14 lines · Marek Szyprowski
Quoted 6 lines
Quoted 6 lines
Quoted 5 lines
Quoted 2 lines

does not support IOMMUs, but that could be changed by wrapping it using the include/asm-generic/dma-mapping-common.h infrastructure.

ARM dma-mapping framework also requires some additional research for better DMA support (there are still issues with multiple mappings to be resolved).

Quoted 6 lines
Quoted 1 line

You mean mapping the same memory into multiple devices, or a different problem?

Mapping the same memory area multiple times with different cache settings is not legal on ARMv7+ systems. Currently the problems might caused by the low-memory kernel linear mapping and second mapping created for example by dma_alloc_coherent() function.

Quoted 7 lines

Yes, I know this problem, but I don't think the case you describe is a serious limitation (there are more interesting cases, though): dma_map_single() etc will create additional *bus* addresses for a physical address, not additional virtual addresses.

dma_alloc_coherent should allocate memory that is not also mapped cached, which is what I thought we do correctly.

I have also noticed that dma_map_single/page/sg() can map physical memory into an arbitrary device address region.
But it is not enough solution for various kinds of IOMMUs. As Kukjin Kim addressed, we need to support larger page size than 4KB because we can reduce TLB miss when we have larger page size.

Our IOMMU(system mmu) supports all page size of ARM architecture including 16MB, 1MB, 64KB and 4KB.
Since the largest size supported by buddy system of 32-bit architecture is 4MB, our system support all page sizes except 16MB.
We proved that larger page size is helpful for DMA performance significantly (more than 10%, approximately).
Big page size is not a problem for peripheral devices
because their address space is not suffer from external fragmentation.

Thanks to Arnd, I never knew about include/linux/iommu.h

Similar to dma-mappings.h, however, It is not enough for our requirements even though it allows private data to be stored in iommu_domain for platform-specific requirements.

I think we can consider another solution for the various requirements. I think one of the most possible solutions is VCMM.
Or we can enhance include/linux/iommu.h with reference of VCMM.

You can find the most recent VCMM submitted at
http://marc.info/?l=linux-kernel&m=129255948319341&w=2

It looks somewhat complex but includes most of required features for various IOMMUs
which will not be easily solved by include/linux/iommu.h

You can find VCMM core in
http://git.kernel.org/?p=linux/kernel/git/kki_ap/linux-2.6-samsung.git;a=blob;f=mm/vcm.c;h=9fff0106ec0078fad1488308305c8486adbed9c0;hb=refs/heads/2.6.36-samsung

and platform specific implementation of VCMM in
http://git.kernel.org/?p=linux/kernel/git/kki_ap/linux-2.6-samsung.git;a=blob;f=arch/arm/plat-s5p/s5p-vcm.c;h=7498c800aef8b01082e1b1c3ea0f66cefe3c85a1;hb=refs/heads/2.6.36-samsung

Cho KyongHo.

#16 lore raw

Re: [PATCH 3/7] ARM: Samsung: update/rewrite Samsung SYSMMU (IOMMU) driver

Quoted 6 lines · KyongHo Cho

I have also noticed that dma_map_single/page/sg() can map physical memory into an arbitrary device address region.
But it is not enough solution for various kinds of IOMMUs. As Kukjin Kim addressed, we need to support larger page size than 4KB because we can reduce TLB miss when we have larger page size.

Quoted 8 lines

Our IOMMU(system mmu) supports all page size of ARM architecture including 16MB, 1MB, 64KB and 4KB.
Since the largest size supported by buddy system of 32-bit architecture is 4MB, our system support all page sizes except 16MB.
We proved that larger page size is helpful for DMA performance significantly (more than 10%, approximately).
Big page size is not a problem for peripheral devices
because their address space is not suffer from external fragmentation.

1. dma_map_single() et.al. is used for mapping *system* *RAM* for devices using whatever is necessary. It must not be used for trying to setup arbitary other mappings.

2. It doesn't matter where the memory for dma_map_single() et.al. comes from provided the virtual address is a valid system RAM address or the struct page * is a valid struct page in the memory map (iow, you can't create this yourself.)

3. In the case of an IOMMU, the DMA API does not limit you to only using 4K pages to setup the IOMMU mappings. You can use whatever you like provided the hardware can cope with it. You can coalesce several existing entries together provided you track what you're doing and can undo what's been done when the mapping is no longer required.

So really there's no reason not to use 64K, 1M and 16M IOMMU entries if that's the size of buffer which has been passed to the DMA API.

#17 lore raw

Re: [PATCH 3/7] ARM: Samsung: update/rewrite Samsung SYSMMU (IOMMU) driver

2011/3/14 Russell King - ARM Linux <[email protected]>:

Quoted 16 lines · KyongHo Cho
Quoted 6 lines

I have also noticed that dma_map_single/page/sg() can map physical memory into an arbitrary device address region.
But it is not enough solution for various kinds of IOMMUs. As Kukjin Kim addressed, we need to support larger page size than 4KB because we can reduce TLB miss when we have larger page size.

Quoted 8 lines

Our IOMMU(system mmu) supports all page size of ARM architecture including 16MB, 1MB, 64KB and 4KB.
Since the largest size supported by buddy system of 32-bit architecture is 4MB, our system support all page sizes except 16MB.
We proved that larger page size is helpful for DMA performance significantly (more than 10%, approximately).
Big page size is not a problem for peripheral devices
because their address space is not suffer from external fragmentation.

Quoted 8 lines

1. dma_map_single() et.al. is used for mapping *system* *RAM* for devices ? using whatever is necessary. ?It must not be used for trying to setup ? arbitary other mappings.

2. It doesn't matter where the memory for dma_map_single() et.al. comes ? from provided the virtual address is a valid system RAM address or ? the struct page * is a valid struct page in the memory map (iow, you ? can't create this yourself.)

You mean that we cannot have arbitrary virtual address mapping for iommu based device?
actually, we have memory mapping to arbitrary device virtual address space, not kernel virtual address space.

Quoted 15 lines

3. In the case of an IOMMU, the DMA API does not limit you to only using ? 4K pages to setup the IOMMU mappings. ?You can use whatever you like ? provided the hardware can cope with it. ?You can coalesce several ? existing entries together provided you track what you're doing and can ? undo what's been done when the mapping is no longer required.

So really there's no reason not to use 64K, 1M and 16M IOMMU entries if that's the size of buffer which has been passed to the DMA API.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

#18 lore raw

Re: [PATCH 3/7] ARM: Samsung: update/rewrite Samsung SYSMMU (IOMMU) driver

Quoted 21 lines · InKi Dae

2011/3/14 Russell King - ARM Linux <[email protected]>:

Quoted 20 lines · KyongHo Cho
Quoted 6 lines

I have also noticed that dma_map_single/page/sg() can map physical memory into an arbitrary device address region.
But it is not enough solution for various kinds of IOMMUs. As Kukjin Kim addressed, we need to support larger page size than 4KB because we can reduce TLB miss when we have larger page size.

Quoted 8 lines

Our IOMMU(system mmu) supports all page size of ARM architecture including 16MB, 1MB, 64KB and 4KB.
Since the largest size supported by buddy system of 32-bit architecture is 4MB, our system support all page sizes except 16MB.
We proved that larger page size is helpful for DMA performance significantly (more than 10%, approximately).
Big page size is not a problem for peripheral devices
because their address space is not suffer from external fragmentation.

1. dma_map_single() et.al. is used for mapping *system* *RAM* for devices ? using whatever is necessary. ?It must not be used for trying to setup ? arbitary other mappings.

Quoted 7 lines
Quoted 4 lines

2. It doesn't matter where the memory for dma_map_single() et.al. comes ? from provided the virtual address is a valid system RAM address or ? the struct page * is a valid struct page in the memory map (iow, you ? can't create this yourself.)

You mean that we cannot have arbitrary virtual address mapping for iommu based device?

No. I mean exactly what I said - I'm talking about the DMA API in the above two points. The implication is that you can not create arbitary mappings of non-system RAM with the DMA API.

Quoted 18 lines

actually, we have memory mapping to arbitrary device virtual address space, not kernel virtual address space.

Quoted 15 lines

3. In the case of an IOMMU, the DMA API does not limit you to only using ? 4K pages to setup the IOMMU mappings. ?You can use whatever you like ? provided the hardware can cope with it. ?You can coalesce several ? existing entries together provided you track what you're doing and can ? undo what's been done when the mapping is no longer required.

So really there's no reason not to use 64K, 1M and 16M IOMMU entries if that's the size of buffer which has been passed to the DMA API.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

#19 lore raw

Re: [PATCH 3/7] ARM: Samsung: update/rewrite Samsung SYSMMU (IOMMU) driver

Russell King - ARM Linux ? ?:

Quoted 25 lines · InKi Dae
Quoted 24 lines

2011/3/14 Russell King - ARM Linux <[email protected]>:

Quoted 23 lines · KyongHo Cho
Quoted 6 lines

I have also noticed that dma_map_single/page/sg() can map physical memory into an arbitrary device address region.
But it is not enough solution for various kinds of IOMMUs. As Kukjin Kim addressed, we need to support larger page size than 4KB because we can reduce TLB miss when we have larger page size.

Quoted 8 lines

Our IOMMU(system mmu) supports all page size of ARM architecture including 16MB, 1MB, 64KB and 4KB.
Since the largest size supported by buddy system of 32-bit architecture is 4MB, our system support all page sizes except 16MB.
We proved that larger page size is helpful for DMA performance significantly (more than 10%, approximately).
Big page size is not a problem for peripheral devices
because their address space is not suffer from external fragmentation.

1. dma_map_single() et.al. is used for mapping *system* *RAM* for devices using whatever is necessary. It must not be used for trying to setup arbitary other mappings.

2. It doesn't matter where the memory for dma_map_single() et.al. comes from provided the virtual address is a valid system RAM address or the struct page * is a valid struct page in the memory map (iow, you can't create this yourself.)

Quoted 7 lines
Quoted 2 lines

You mean that we cannot have arbitrary virtual address mapping for iommu based device?

No. I mean exactly what I said - I'm talking about the DMA API in the above two points. The implication is that you can not create arbitary mappings of non-system RAM with the DMA API.

sorry but I couldn't understand exactly what you said. could you give me your answer one more time?
does non-system RAM mean reserved memory regions? if not, is it arbitrary virtual address space that isn't kernel or user virtual address space and is the space for iommu based deivce?

Quoted 18 lines
Quoted 17 lines

actually, we have memory mapping to arbitrary device virtual address space, not kernel virtual address space.

Quoted 14 lines

3. In the case of an IOMMU, the DMA API does not limit you to only using 4K pages to setup the IOMMU mappings. You can use whatever you like provided the hardware can cope with it. You can coalesce several existing entries together provided you track what you're doing and can undo what's been done when the mapping is no longer required.

So really there's no reason not to use 64K, 1M and 16M IOMMU entries if that's the size of buffer which has been passed to the DMA API.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

#20 lore raw

Re: [PATCH 3/7] ARM: Samsung: update/rewrite Samsung SYSMMU (IOMMU) driver

Quoted 33 lines · daeinki

Russell King - ARM Linux ? ?:

Quoted 25 lines · InKi Dae
Quoted 24 lines

2011/3/14 Russell King - ARM Linux <[email protected]>:

Quoted 23 lines · KyongHo Cho
Quoted 6 lines

I have also noticed that dma_map_single/page/sg() can map physical memory into an arbitrary device address region.
But it is not enough solution for various kinds of IOMMUs. As Kukjin Kim addressed, we need to support larger page size than 4KB because we can reduce TLB miss when we have larger page size.

Quoted 8 lines

Our IOMMU(system mmu) supports all page size of ARM architecture including 16MB, 1MB, 64KB and 4KB.
Since the largest size supported by buddy system of 32-bit architecture is 4MB, our system support all page sizes except 16MB.
We proved that larger page size is helpful for DMA performance significantly (more than 10%, approximately).
Big page size is not a problem for peripheral devices
because their address space is not suffer from external fragmentation.

1. dma_map_single() et.al. is used for mapping *system* *RAM* for devices using whatever is necessary. It must not be used for trying to setup arbitary other mappings.

2. It doesn't matter where the memory for dma_map_single() et.al. comes from provided the virtual address is a valid system RAM address or the struct page * is a valid struct page in the memory map (iow, you can't create this yourself.)

Quoted 7 lines
Quoted 2 lines

You mean that we cannot have arbitrary virtual address mapping for iommu based device?

No. I mean exactly what I said - I'm talking about the DMA API in the above two points. The implication is that you can not create arbitary mappings of non-system RAM with the DMA API.

Quoted 5 lines

sorry but I couldn't understand exactly what you said. could you give me your answer one more time?
does non-system RAM mean reserved memory regions? if not, is it arbitrary virtual address space that isn't kernel or user virtual address space and is the space for iommu based deivce?

For dma_map_single(dev, addr, size, dir), basically:

	for (a = addr; a < addr + size; a += PAGE_SIZE)
		BUG_ON(!virt_addr_valid(a));

For dma_map_page(dev, page, offset, size, dir), 'page' must be something obtained from one of the page-based kernel allocators (so either refering to a page in the *existing* lowmem or highmem memory) _and_ you must not use offset/size to then point@something outside that.

So, if you take something out of the kernel's knowledge of what is memory, you can't then use the DMA API with it.

#21 lore raw

Re: [PATCH 3/7] ARM: Samsung: update/rewrite Samsung SYSMMU (IOMMU) driver

In reply to KyongHo Cho
Quoted 3 lines · KyongHo Cho

I think we can consider another solution for the various requirements. I think one of the most possible solutions is VCMM.
Or we can enhance include/linux/iommu.h with reference of VCMM.

I think extending or changing the existing interface would be much preferred. It's always better to limit the number of interfaces that do the same thing, and we already have more duplication than we want with the two dma-mapping.h and iommu.h interfaces.

Note that any aspect of the existing interface can be changed if necessary, as long as there is a way to migrate all the existing users. Since the iommu API is not exported to user space, there is no requirement to keep it stable.

Arnd

author maintainer
#22 lore raw

PATCH 4/7 v4l: videobuf2: add Samsung SYSMMU (IOMMU) based allocator

In reply to Marek Szyprowski

From: Andrzej Pietrasiewicz <[email protected]>

This patch adds new videobuf2 memory allocator dedicated to Samsung SoC series with IOMMU module. It requires s5p-sysmmu low level driver for controlling iommu. This allocator aquires memory with standard alloc_page() call and doesn't suffer from memory fragmentation issues. Curretnly it supports only iommu module on Sasmung S5PV310 SoC series.

---
 drivers/media/video/Kconfig               |    8 +-
 drivers/media/video/Makefile              |    1 +
 drivers/media/video/videobuf2-s5p-iommu.c |  444 +++++++++++++++++++++++++++++
 include/media/videobuf2-s5p-iommu.h       |   50 ++++
 4 files changed, 502 insertions(+), 1 deletions(-)
 create mode 100644 drivers/media/video/videobuf2-s5p-iommu.c
 create mode 100644 include/media/videobuf2-s5p-iommu.h
drivers/media/video/Kconfig +7 -1
index e2f5a69..9806505 100644
@@ -60,12 +60,18 @@ config VIDEOBUF2_VMALLOC
 	select VIDEOBUF2_MEMOPS
 	tristate
 
-
 config VIDEOBUF2_DMA_SG
 	#depends on HAS_DMA
 	select VIDEOBUF2_CORE
 	select VIDEOBUF2_MEMOPS
 	tristate
+
+config VIDEOBUF2_S5P_IOMMU
+	select GENERIC_ALLOCATOR
+	select VIDEOBUF2_CORE
+	select VIDEOBUF2_MEMOPS
+	tristate
+
 #
 # Multimedia Video device configuration
 #
drivers/media/video/Makefile +1 -0
index ac54652..fd9488d 100644
@@ -118,6 +118,7 @@ obj-$(CONFIG_VIDEOBUF2_MEMOPS)		+= videobuf2-memops.o
 obj-$(CONFIG_VIDEOBUF2_VMALLOC)		+= videobuf2-vmalloc.o
 obj-$(CONFIG_VIDEOBUF2_DMA_CONTIG)	+= videobuf2-dma-contig.o
 obj-$(CONFIG_VIDEOBUF2_DMA_SG)		+= videobuf2-dma-sg.o
+obj-$(CONFIG_VIDEOBUF2_S5P_IOMMU)	+= videobuf2-s5p-iommu.o
 
 obj-$(CONFIG_V4L2_MEM2MEM_DEV) += v4l2-mem2mem.o
 
drivers/media/video/videobuf2-s5p-iommu.c new file +444 -0

444 lines not on this page · raw message

include/media/videobuf2-s5p-iommu.h new file +50 -0

50 lines not on this page · raw message

Signature · 1 line
1.7.1.569.g6f426
author maintainer
#23 lore raw

PATCH 5/7 s5p-fimc: add pm_runtime support

In reply to Marek Szyprowski

This patch adds basic support for pm_runtime to s5p-fimc driver. PM runtime support is required to enable the driver on S5PV310 series with power domain driver enabled.

---
 drivers/media/video/s5p-fimc/fimc-capture.c |    5 +++++
 drivers/media/video/s5p-fimc/fimc-core.c    |   14 ++++++++++++++
 2 files changed, 19 insertions(+), 0 deletions(-)
drivers/media/video/s5p-fimc/fimc-capture.c +5 -0
index 59123a6..f8d7de5 100644
@@ -18,6 +18,7 @@
 #include <linux/interrupt.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/list.h>
 #include <linux/slab.h>
 #include <linux/clk.h>
@@ -395,6 +396,8 @@ static int fimc_capture_open(struct file *file)
 	if (fimc_m2m_active(fimc))
 		return -EBUSY;
 
+	pm_runtime_get_sync(&fimc->pdev->dev);
+
 	if (++fimc->vid_cap.refcnt == 1) {
 		ret = fimc_isp_subdev_init(fimc, 0);
 		if (ret) {
@@ -425,6 +428,8 @@ static int fimc_capture_close(struct file *file)
 		fimc_subdev_unregister(fimc);
 	}
 
+	pm_runtime_put_sync(&fimc->pdev->dev);
+
 	return 0;
 }
 
drivers/media/video/s5p-fimc/fimc-core.c +14 -0
index db3e730..c92dbdb 100644
@@ -20,6 +20,7 @@
 #include <linux/interrupt.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/list.h>
 #include <linux/io.h>
 #include <linux/slab.h>
@@ -1407,6 +1408,8 @@ static int fimc_m2m_open(struct file *file)
 	if (fimc->vid_cap.refcnt > 0)
 		return -EBUSY;
 
+	pm_runtime_get_sync(&fimc->pdev->dev);
+
 	fimc->m2m.refcnt++;
 	set_bit(ST_OUTDMA_RUN, &fimc->state);
 
@@ -1449,6 +1452,8 @@ static int fimc_m2m_release(struct file *file)
 	if (--fimc->m2m.refcnt <= 0)
 		clear_bit(ST_OUTDMA_RUN, &fimc->state);
 
+	pm_runtime_put_sync(&fimc->pdev->dev);
+
 	return 0;
 }
 
@@ -1646,6 +1651,11 @@ static int fimc_probe(struct platform_device *pdev)
 		goto err_req_region;
 	}
 
+	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_enable(&pdev->dev);
+
+	pm_runtime_get_sync(&pdev->dev);
+
 	fimc->num_clocks = MAX_FIMC_CLOCKS - 1;
 
 	/* Check if a video capture node needs to be registered. */
@@ -1703,6 +1713,8 @@ static int fimc_probe(struct platform_device *pdev)
 	dev_dbg(&pdev->dev, "%s(): fimc-%d registered successfully\n",
 		__func__, fimc->id);
 
+	pm_runtime_put_sync(&pdev->dev);
+
 	return 0;
 
 err_m2m:
@@ -1737,6 +1749,8 @@ static int __devexit fimc_remove(struct platform_device *pdev)
 
 	vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx);
 
+	pm_runtime_disable(&pdev->dev);
+
 	iounmap(fimc->regs);
 	release_resource(fimc->regs_res);
 	kfree(fimc->regs_res);
Signature · 1 line
1.7.1.569.g6f426
author maintainer
#24 lore raw

PATCH 6/7 s5p-fimc: Add support for vb2-s5p-iommu allocator

In reply to Marek Szyprowski

This patch adds support for videobuf2-s5p-iommu allocator to s5p-fimc driver. This allocator is selected only on systems that contains support for S5P SYSMMU module. Otherwise the standard videobuf2-dma-contig is used.

---
 drivers/media/video/Kconfig                 |    3 +-
 drivers/media/video/s5p-fimc/fimc-capture.c |    4 +-
 drivers/media/video/s5p-fimc/fimc-core.c    |   22 ++++---
 drivers/media/video/s5p-fimc/fimc-mem.h     |   87 +++++++++++++++++++++++++++
 4 files changed, 104 insertions(+), 12 deletions(-)
 create mode 100644 drivers/media/video/s5p-fimc/fimc-mem.h
drivers/media/video/Kconfig +2 -1
index 9806505..12fb325 100644
@@ -1018,7 +1018,8 @@ config VIDEO_MEM2MEM_TESTDEV
 config  VIDEO_SAMSUNG_S5P_FIMC
 	tristate "Samsung S5P FIMC (video postprocessor) driver"
 	depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
-	select VIDEOBUF2_DMA_CONTIG
+	select VIDEOBUF2_S5P_IOMMU if S5P_SYSTEM_MMU
+	select VIDEOBUF2_DMA_CONTIG if !S5P_SYSTEM_MMU
 	select V4L2_MEM2MEM_DEV
 	help
 	  This is a v4l2 driver for the S5P camera interface
drivers/media/video/s5p-fimc/fimc-capture.c +2 -2
index f8d7de5..6819908 100644
@@ -29,8 +29,8 @@
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-mem2mem.h>
 #include <media/videobuf2-core.h>
-#include <media/videobuf2-dma-contig.h>
 
+#include "fimc-mem.h"
 #include "fimc-core.h"
 
 static struct v4l2_subdev *fimc_subdev_register(struct fimc_dev *fimc,
@@ -881,7 +881,7 @@ int fimc_register_capture_device(struct fimc_dev *fimc)
 	q->io_modes = VB2_MMAP | VB2_USERPTR;
 	q->drv_priv = fimc->vid_cap.ctx;
 	q->ops = &fimc_capture_qops;
-	q->mem_ops = &vb2_dma_contig_memops;
+	q->mem_ops = &fimc_vb2_allocator_memops;
 	q->buf_struct_size = sizeof(struct fimc_vid_buffer);
 
 	vb2_queue_init(q);
drivers/media/video/s5p-fimc/fimc-core.c +13 -9
index c92dbdb..f06aaea 100644
@@ -27,8 +27,8 @@
 #include <linux/clk.h>
 #include <media/v4l2-ioctl.h>
 #include <media/videobuf2-core.h>
-#include <media/videobuf2-dma-contig.h>
 
+#include "fimc-mem.h"
 #include "fimc-core.h"
 
 static char *fimc_clocks[MAX_FIMC_CLOCKS] = {
@@ -458,7 +458,7 @@ int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
 	dbg("memplanes= %d, colplanes= %d, pix_size= %d",
 		frame->fmt->memplanes, frame->fmt->colplanes, pix_size);
 
-	paddr->y = vb2_dma_contig_plane_paddr(vb, 0);
+	paddr->y = fimc_vb2_plane_addr(vb, 0);
 
 	if (frame->fmt->memplanes == 1) {
 		switch (frame->fmt->colplanes) {
@@ -486,10 +486,10 @@ int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
 		}
 	} else {
 		if (frame->fmt->memplanes >= 2)
-			paddr->cb = vb2_dma_contig_plane_paddr(vb, 1);
+			paddr->cb = fimc_vb2_plane_addr(vb, 1);
 
 		if (frame->fmt->memplanes == 3)
-			paddr->cr = vb2_dma_contig_plane_paddr(vb, 2);
+			paddr->cr = fimc_vb2_plane_addr(vb, 2);
 	}
 
 	dbg("PHYS_ADDR: y= 0x%X  cb= 0x%X cr= 0x%X ret= %d",
@@ -1375,7 +1375,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
 	src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
 	src_vq->drv_priv = ctx;
 	src_vq->ops = &fimc_qops;
-	src_vq->mem_ops = &vb2_dma_contig_memops;
+	src_vq->mem_ops = &fimc_vb2_allocator_memops;
 	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
 
 	ret = vb2_queue_init(src_vq);
@@ -1387,7 +1387,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
 	dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
 	dst_vq->drv_priv = ctx;
 	dst_vq->ops = &fimc_qops;
-	dst_vq->mem_ops = &vb2_dma_contig_memops;
+	dst_vq->mem_ops = &fimc_vb2_allocator_memops;
 	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
 
 	return vb2_queue_init(dst_vq);
@@ -1685,12 +1685,15 @@ static int fimc_probe(struct platform_device *pdev)
 		goto err_clk;
 	}
 
-	/* Initialize contiguous memory allocator */
-	fimc->alloc_ctx = vb2_dma_contig_init_ctx(&fimc->pdev->dev);
+	/* Initialize memory allocator */
+	fimc->alloc_ctx = fimc_vb2_allocator_init(pdev);
 	if (IS_ERR(fimc->alloc_ctx)) {
 		ret = PTR_ERR(fimc->alloc_ctx);
 		goto err_irq;
 	}
+	ret = fimc_vb2_allocator_enable(fimc->alloc_ctx);
+	if (ret)
+		goto err_irq;
 
 	ret = fimc_register_m2m_device(fimc);
 	if (ret)
@@ -1747,7 +1750,8 @@ static int __devexit fimc_remove(struct platform_device *pdev)
 
 	fimc_clk_release(fimc);
 
-	vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx);
+	fimc_vb2_allocator_disable(fimc->alloc_ctx);
+	fimc_vb2_allocator_cleanup(fimc->alloc_ctx);
 
 	pm_runtime_disable(&pdev->dev);
 
drivers/media/video/s5p-fimc/fimc-mem.h new file +87 -0

87 lines not on this page · raw message

Signature · 1 line
1.7.1.569.g6f426
author maintainer
#25 lore raw

PATCH 7/7 ARM: S5PC210: enable FIMC on Universal_C210

In reply to Marek Szyprowski

This patch adds definitions to enable support for s5p-fimc driver together with required power domains and sysmmu controller on Universal C210 board.

---
 arch/arm/mach-s5pv310/Kconfig               |    6 ++++++
 arch/arm/mach-s5pv310/mach-universal_c210.c |   20 ++++++++++++++++++++
 2 files changed, 26 insertions(+), 0 deletions(-)
arch/arm/mach-s5pv310/Kconfig +6 -0
index a8b0425..c850086 100644
@@ -97,12 +97,18 @@ config MACH_UNIVERSAL_C210
 	bool "Mobile UNIVERSAL_C210 Board"
 	select CPU_S5PV310
 	select S5P_DEV_ONENAND
+	select S5P_DEV_FIMC0
+	select S5P_DEV_FIMC1
+	select S5P_DEV_FIMC2
+	select S5P_DEV_FIMC3
 	select S3C_DEV_HSMMC
 	select S3C_DEV_HSMMC2
 	select S3C_DEV_HSMMC3
 	select S5PV310_SETUP_SDHCI
 	select S3C_DEV_I2C1
 	select S3C_DEV_I2C5
+	select S5PV310_DEV_PD
+	select S5PV310_DEV_SYSMMU
 	select S5PV310_SETUP_I2C1
 	select S5PV310_SETUP_I2C5
 	help
arch/arm/mach-s5pv310/mach-universal_c210.c +20 -0
index eece381..f153895 100644
@@ -24,7 +24,9 @@
 #include <plat/s5pv310.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
+#include <plat/pd.h>
 #include <plat/sdhci.h>
+#include <plat/sysmmu.h>
 
 #include <mach/map.h>
 #include <mach/gpio.h>
@@ -816,6 +818,15 @@ static struct platform_device *universal_devices[] __initdata = {
 	&s3c_device_hsmmc0,
 	&s3c_device_hsmmc2,
 	&s3c_device_hsmmc3,
+	&s5p_device_fimc0,
+	&s5p_device_fimc1,
+	&s5p_device_fimc2,
+	&s5p_device_fimc3,
+	&s5pv310_device_pd[PD_CAM],
+	&s5pv310_device_sysmmu[S5P_SYSMMU_FIMC0],
+	&s5pv310_device_sysmmu[S5P_SYSMMU_FIMC1],
+	&s5pv310_device_sysmmu[S5P_SYSMMU_FIMC2],
+	&s5pv310_device_sysmmu[S5P_SYSMMU_FIMC3],
 
 	/* Universal Devices */
 	&universal_gpio_keys,
@@ -842,6 +853,15 @@ static void __init universal_machine_init(void)
 
 	/* Last */
 	platform_add_devices(universal_devices, ARRAY_SIZE(universal_devices));
+
+	s5p_device_fimc0.dev.parent = &s5pv310_device_pd[PD_CAM].dev;
+	s5p_device_fimc1.dev.parent = &s5pv310_device_pd[PD_CAM].dev;
+	s5p_device_fimc2.dev.parent = &s5pv310_device_pd[PD_CAM].dev;
+	s5p_device_fimc3.dev.parent = &s5pv310_device_pd[PD_CAM].dev;
+	s5pv310_device_sysmmu[S5P_SYSMMU_FIMC0].dev.parent = &s5pv310_device_pd[PD_CAM].dev;
+	s5pv310_device_sysmmu[S5P_SYSMMU_FIMC1].dev.parent = &s5pv310_device_pd[PD_CAM].dev;
+	s5pv310_device_sysmmu[S5P_SYSMMU_FIMC2].dev.parent = &s5pv310_device_pd[PD_CAM].dev;
+	s5pv310_device_sysmmu[S5P_SYSMMU_FIMC3].dev.parent = &s5pv310_device_pd[PD_CAM].dev;
 }
 
 MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")
Signature · 1 line
1.7.1.569.g6f426
#26 lore raw

cover Samsung IOMMU videobuf2 allocator and s5p-fimc update

In reply to Marek Szyprowski

Hello,

There are comments for your System MMU driver below.

It's good that System MMU has functionality of mapping but System MMU have to use other mapping of virtual memory allocator.

And would be better to change sysmmu_list to use array of defined in s5p_sysmmu_ip enumeration, so that can get enhancement of memory space usage, speed, and readability of codes.

TLB replacement policy does not need to use LRU. Of course, current System MMU also needs it. I think, the round robin is enough, because to access memory has no temporal locality and to make LRU need to access to System MMU register one more. The reset value is round robin.

In the setting of SHARED page table in s5p_sysmmu_control_locked, get the page table base address of ARM core from cp15 register now. But current->mm-

Quoted 1 line

pgd is better for more compatibility.

When it make page table with PRIVATE page table methods, the size of the structure to manage the second page table is quite big. It is much better rather that to make slab with cache size of 1KB.
Besides, the page mapping implementation is not safe in your System MMU driver. Because only first one confirms primary page table entry, when it assigns four second page tables consecutively at a time.

The System MMU driver cannot apply runtime pm by oneself with calling pm_runtime_put_sync(). The reason is because a device with System MMU can on/off power. I think just clock gating is enough. However, I can't find clock enable/disable in your driver.

By PRIVATE page table method, each system MMU comes to have a page table only for oneself. In this case, the problem is that each MFC System MMU L and R having another page table.

In your System MMU driver, the page size is always 4KB crucially. This says TLB thrashing and produces a result to lose a TLB hit rate. It is a big problem with the device such as rotator which does not do sequential access especially.

And the IRQ handler just outputs only a message. It should be implemented in call back function to be able to handle from each device driver.

When it sets System MMU in SHARED page table, kernel virtual memory is broken by a method such as s5p_sysmmu_map_area() :(

Thanks.

Best regards,
Kgene.
--
Kukjin Kim <[email protected]>, Senior Engineer, SW Solution Development Team, Samsung Electronics Co., Ltd.

Quoted 64 lines · Marek Szyprowski

Hello,

This patch series introduces new type of videbuf2 memory allocator - vb2-s5p-iommu. This allocator can be used only on Samsung SoCs that have IOMMU module. Currently only Samsung EXYNOS4 (former S5PV310) platform has SYSMMU modules. The allocator is then used by s5p-fimc driver. To make it possible some additional changes are required. Mainly platform support for s5p-fimc for EXYNOS4 machines need to be defined. The proposed solution has been tested on Universal C210 board (Samsung S5PC210/EXYNOS4 based).

We decided to use driver private address space mode of the iommu driver. This way each vb2-s5p-iommu client gets it's own address space for memory buffers. This reduces kernel virtual memory fragmentation as well as solves some non-trivial page table updates issues. The drawback is the fact that the interface for s5p-sysmmu has been changed.

This IOMMU allocator has no dependences on other subsystems besides Samsung platfrom core. We also ported s5p-mfc and s5p-tv drivers to this allocator, they will be posted in separate patch series. This will enable to get them working on EXYNOS4 (S5PV310) platform. Support for S5PV210/S5PC110 platform still depends on CMA allocator that needs more discussion on memory management mailing list and development. The patches with updated s5p-mfc and s5p-tv drivers will follow.

To get FIMC module working on EXYNOS4/UniversalC210 board we also added support for power domains and power gating.

This patch series contains a collection of patches for various platform subsystems. Here is a detailed list:

[PATCH 1/7] ARM: S5PV310: Add platform definitions for FIMC
- adds basic platform resources for FIMC modules (for s5p-fimc driver)

[PATCH 2/7] ARM: S5PV310: power domains: fixes and code cleanup
- adds support for block gating in Samsung power domain driver and performs some cleanup

[PATCH 3/7] ARM: Samsung: update/rewrite Samsung SYSMMU (IOMMU) driver
- a complete rewrite of sysmmu driver for Samsung platform:
- the new version introduces device private page tables (address space) mode
- simplified the resource management (no more horrible single platform device with 32 resources is needed)
- some other API chages required by upcoming videobuf2 allocator

[PATCH 4/7] v4l: videobuf2: add Samsung SYSMMU (IOMMU) based allocator
- introduces new memory allocator for videobuf2, it uses s5p-sysmmu iommu driver, memory for video buffers is acuired by alloc_page() kernel function

[PATCH 5/7] s5p-fimc: add pm_runtime support
- adds support for pm_runtime in s5p-fimc driver

[PATCH 6/7] s5p-fimc: Add support for vb2-s5p-iommu allocator
- adds support for the newly introduces videbuf2-s5p-iommu allocator on EXYNOS4 platform

[PATCH 7/7] ARM: S5PC210: enable FIMC on Universal_C210
- adds all required machine definitions to get FIMC modules working on Universal C210 boards

Quoted 5 lines

The patch series is based on git://linuxtv.org/media_tree.git tree, staging/for_v2.6.39 branch with the following Samsung platform patches:
1. [PATCH] ARM: Samsung: change suspend/resume code to depend on CONFIG_SUSPEND
http://www.mail-archive.com/linux-samsung-

soc at vger.kernel.org/msg04025.html

Quoted 1 line

2. [PATCH v2] ARM: S5PC210: add support for i2c PMICs on Universal_C210

board

Quoted 1 line

http://www.mail-archive.com/linux-samsung-

soc at vger.kernel.org/msg04029.html

Quoted 30 lines

This series has not been rebased onto the latest changes (S5PV310 renamed to EXYNOS4) in
git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung.git,
for-next branch. We will rebase them soon, but first we want to get feedback and comments on the s5p-iommu videobuf2 allocator idea.

Best regards
--
Marek Szyprowski
Samsung Poland R&D Center

Complete patch summary:

Andrzej Pietrasiewicz (2):
ARM: Samsung: update/rewrite Samsung SYSMMU (IOMMU) driver
v4l: videobuf2: add Samsung SYSMMU (IOMMU) based allocator

Marek Szyprowski (3):
s5p-fimc: add pm_runtime support
s5p-fimc: Add support for vb2-s5p-iommu allocator
ARM: S5PC210: enable FIMC on Universal_C210

Sylwester Nawrocki (1):
ARM: S5PV310: Add platform definitions for FIMC

Tomasz Stanislawski (1):
ARM: S5PV310: power domains: fixes and code cleanup

Quoted 16 lines
 arch/arm/mach-s5pv310/Kconfig                    |    6 +
 arch/arm/mach-s5pv310/clock.c                    |   91 ++
 arch/arm/mach-s5pv310/cpu.c                      |    7 +
 arch/arm/mach-s5pv310/dev-pd.c                   |   93 ++-
 arch/arm/mach-s5pv310/dev-sysmmu.c               |  582 +++++++++----
 arch/arm/mach-s5pv310/include/mach/irqs.h        |   40 +-
 arch/arm/mach-s5pv310/include/mach/map.h         |    8 +
 arch/arm/mach-s5pv310/include/mach/regs-clock.h  |   12 +
 arch/arm/mach-s5pv310/include/mach/regs-sysmmu.h |   23 +-
 arch/arm/mach-s5pv310/include/mach/sysmmu.h      |  122 ---
 arch/arm/mach-s5pv310/mach-universal_c210.c      |   20 +
 arch/arm/plat-s5p/Kconfig                        |   22 +-
 arch/arm/plat-s5p/Makefile                       |    1 +
 arch/arm/plat-s5p/dev-fimc3.c                    |   43 +
 arch/arm/plat-s5p/include/plat/sysmmu.h          |  127 +++
 arch/arm/plat-s5p/sysmmu.c                       |  988 +++++++++++++++--

---

Quoted 23 lines

--

 arch/arm/plat-samsung/include/plat/devs.h        |    3 +-
 arch/arm/plat-samsung/include/plat/fimc-core.h   |    5 +
 arch/arm/plat-samsung/include/plat/pd.h          |    1 +
 drivers/media/video/Kconfig                      |   11 +-
 drivers/media/video/Makefile                     |    1 +
 drivers/media/video/s5p-fimc/fimc-capture.c      |    9 +-
 drivers/media/video/s5p-fimc/fimc-core.c         |   36 +-
 drivers/media/video/s5p-fimc/fimc-mem.h          |   87 ++
 drivers/media/video/videobuf2-s5p-iommu.c        |  444 ++++++++++
 include/media/videobuf2-s5p-iommu.h              |   50 ++
 26 files changed, 2129 insertions(+), 703 deletions(-)
 rewrite arch/arm/mach-s5pv310/dev-sysmmu.c (86%)
 delete mode 100644 arch/arm/mach-s5pv310/include/mach/sysmmu.h
 create mode 100644 arch/arm/plat-s5p/dev-fimc3.c
 create mode 100644 arch/arm/plat-s5p/include/plat/sysmmu.h
 rewrite arch/arm/plat-s5p/sysmmu.c (85%)
 create mode 100644 drivers/media/video/s5p-fimc/fimc-mem.h
 create mode 100644 drivers/media/video/videobuf2-s5p-iommu.c
 create mode 100644 include/media/videobuf2-s5p-iommu.h

--
1.7.1.569.g6f426

author maintainer
#27 lore raw

cover Samsung IOMMU videobuf2 allocator and s5p-fimc update

Hello,

Quoted 3 lines · Kukjin Kim

Hello,

There are comments for your System MMU driver below.

Please take into account that this was an initial version of our SYSMMU driver to start the discussion, so there were a few minor problems left. Thanks for pointing them out btw. :)

Quoted 2 lines

It's good that System MMU has functionality of mapping but System MMU have to use other mapping of virtual memory allocator.

Could you elaborate on this? I'm not sure I understand right your problem.

SYSMMU driver is a low-level driver for the SYSMMU module. The driver should provide all the basic functionality that is (or might be) hardware dependent. Creating a mapping is one of such elementary functionalities. Sysmmu client (let it be videobuf2-s5p-iommu, vcmm, maybe even other driver directly) should not need to know the format of page descriptors or the way they are arranged in the memory. The sysmmu should provide low level functions to create and remove a mapping. Managing a virtual space is something that MIGHT be client dependent and should be left to the client.

This design allows for different approaches to coexist. Videobuf2-s5p-iommu client will manage the virtual space with gen_alloc framework, while vcmm will use its own methods.

It would be great if one decide to unify iommu interfaces across the kernel, but this will be a long road. We need to start from something simple (platform private) and working first.

Quoted 3 lines

And would be better to change sysmmu_list to use array of defined in s5p_sysmmu_ip enumeration, so that can get enhancement of memory space usage, speed, and readability of codes.

Yes, the list can be simplified to an array, but this is really a minor issue.

Quoted 4 lines

TLB replacement policy does not need to use LRU. Of course, current System MMU also needs it. I think, the round robin is enough, because to access memory has no temporal locality and to make LRU need to access to System MMU register one more. The reset value is round robin.

Well, the best possibility is to allow sysmmu clients to decide which policy should be used. For some devices (I'm thinking of MFC) LRU policy might give a little speedup.

Quoted 3 lines

In the setting of SHARED page table in s5p_sysmmu_control_locked, get the page table base address of ARM core from cp15 register now. But current->mm-

Quoted 1 line

pgd is better for more compatibility.

Right, this way the pgd table pointer can be acquired in a more system friendly way.

Quoted 3 lines

When it make page table with PRIVATE page table methods, the size of the structure to manage the second page table is quite big. It is much better rather that to make slab with cache size of 1KB.

Yes, our initial driver uses directly 4KB pages to manage 4 consecutive second page tables. However usually the allocations of client devices will be few but quite large each. So most of pages used to hold second level page tables will be effectively reused.

You are right however that the approach with a slab with 1KB units will result in code that is cleaner and easier to understand.

Quoted 3 lines

Besides, the page mapping implementation is not safe in your System MMU driver. Because only first one confirms primary page table entry, when it assigns four second page tables consecutively at a time.

That's a direct result of the 4-second-level-at-once method of allocating second level pages, but this can be cleaned by using 1KB with slab.

Quoted 4 lines

The System MMU driver cannot apply runtime pm by oneself with calling pm_runtime_put_sync(). The reason is because a device with System MMU can on/off power. I think just clock gating is enough. However, I can't find clock enable/disable in your driver.

Clock is enabled in probe() and disabled in remove(). pm_runtime_get/put_sync() only increases/decreases use count of a respective power domain, so the actual device driver also has to call pm_runtime_get/put. Calling pm_runtime_put_sync() will not shut down the power if the sysmmu client driver has called pm_runtime_get() without pm_runtime_put(). I see no problems here. Could you elaborate your issue?

Quoted 4 lines

By PRIVATE page table method, each system MMU comes to have a page table only for oneself. In this case, the problem is that each MFC System MMU L and R having another page table.

Yes, true. This is consequence of the MFC hardware design and the fact that it has 2 AXI master interfaces and 2 SYSMMU controllers. Each of them have to be configured separately. Each of them has a separate virtual driver's address space. Such configuration is used by the MFC driver posted in v7 patch series.

Quoted 4 lines

In your System MMU driver, the page size is always 4KB crucially. This says TLB thrashing and produces a result to lose a TLB hit rate. It is a big problem with the device such as rotator which does not do sequential access especially.

The page size is set to 4KB, because Linux kernel uses 4KB pages by default. Once support for other page size is available in the kernel, then sysmmu can be extended also.

Quoted 2 lines

And the IRQ handler just outputs only a message. It should be implemented in call back function to be able to handle from each device driver.

This was only for debugging purpose, but you are right that the sysmmu API in this area need to be extended.

Quoted 2 lines

When it sets System MMU in SHARED page table, kernel virtual memory is broken by a method such as s5p_sysmmu_map_area()

Yes, there should be a check added to prevent messing with ARM pgd in SHARED mode.

Best regards
--
Marek Szyprowski
Samsung Poland R&D Center

#28 lore raw

cover Samsung IOMMU videobuf2 allocator and s5p-fimc update

Hello, Mr. Kukjin.

2011/3/8 Marek Szyprowski <[email protected]>:

Quoted 4 lines

Hello,

On Tuesday, March 08, 2011 8:29 AM Kukjin Kim wrote:

Quoted 12 lines
Quoted 3 lines

Hello,

There are comments for your System MMU driver below.

Please take into account that this was an initial version of our SYSMMU driver to start the discussion, so there were a few minor problems left. Thanks for pointing them out btw. :)

Quoted 2 lines

It's good that System MMU has functionality of mapping but System MMU have to use other mapping of virtual memory allocator.

you mean that other page sizes such as large, small page and so on should be supported in mapping also? otherwise use 64k not 4k page?

Quoted 116 lines

Could you elaborate on this? I'm not sure I understand right your problem.

SYSMMU driver is a low-level driver for the SYSMMU module. The driver should provide all the basic functionality that is (or might be) hardware dependent. Creating a mapping is one of such elementary functionalities. Sysmmu client (let it be videobuf2-s5p-iommu, vcmm, maybe even other driver directly) should not need to know the format of page descriptors or the way they are arranged in the memory. The sysmmu should provide low level functions to create and remove a mapping. Managing a virtual space is something that MIGHT be client dependent and should be left to the client.

This design allows for different approaches to coexist. Videobuf2-s5p-iommu client will manage the virtual space with gen_alloc framework, while vcmm will use its own methods.

It would be great if one decide to unify iommu interfaces across the kernel, but this will be a long road. We need to start from something simple (platform private) and working first.

Quoted 3 lines

And would be better to change sysmmu_list to use array of defined in s5p_sysmmu_ip enumeration, so that can get enhancement of memory space usage, speed, and readability of codes.

Yes, the list can be simplified to an array, but this is really a minor issue.

Quoted 4 lines

TLB replacement policy does not need to use LRU. Of course, current System MMU also needs it. I think, the round robin is enough, because to access memory has no temporal locality and to make LRU need to access to System MMU register one more. The reset value is round robin.

Well, the best possibility is to allow sysmmu clients to decide which policy should be used. For some devices (I'm thinking of MFC) LRU policy might give a little speedup.

Quoted 3 lines

In the setting of SHARED page table in s5p_sysmmu_control_locked, get the page table base address of ARM core from cp15 register now. But current->mm-

Quoted 1 line

pgd is better for more compatibility.

Right, this way the pgd table pointer can be acquired in a more system friendly way.

Quoted 3 lines

When it make page table with PRIVATE page table methods, the size of the structure to manage the second page table is quite big. It is much better rather that to make slab with cache size of 1KB.

Yes, our initial driver uses directly 4KB pages to manage 4 consecutive second page tables. However usually the allocations of client devices will be few but quite large each. So most of pages used to hold second level page tables will be effectively reused.

You are right however that the approach with a slab with 1KB units will result in code that is cleaner and easier to understand.

Quoted 3 lines

Besides, the page mapping implementation is not safe in your System MMU driver. Because only first one confirms primary page table entry, when it assigns four second page tables consecutively at a time.

That's a direct result of the 4-second-level-at-once method of allocating second level pages, but this can be cleaned by using 1KB with slab.

Quoted 4 lines

The System MMU driver cannot apply runtime pm by oneself with calling pm_runtime_put_sync(). The reason is because a device with System MMU can on/off power. I think just clock gating is enough. However, I can't find clock enable/disable in your driver.

Clock is enabled in probe() and disabled in remove(). pm_runtime_get/put_sync() only increases/decreases use count of a respective power domain, so the actual device driver also has to call pm_runtime_get/put. Calling pm_runtime_put_sync() will not shut down the power if the sysmmu client driver has called pm_runtime_get() without pm_runtime_put(). I see no problems here. Could you elaborate your issue?

Quoted 4 lines

By PRIVATE page table method, each system MMU comes to have a page table only for oneself. In this case, the problem is that each MFC System MMU L and R having another page table.

Yes, true. This is consequence of the MFC hardware design and the fact that it has 2 AXI master interfaces and 2 SYSMMU controllers. Each of them have to be configured separately. Each of them has a separate virtual driver's address space. Such configuration is used by the MFC driver posted in v7 patch series.

Quoted 4 lines

In your System MMU driver, the page size is always 4KB crucially. This says TLB thrashing and produces a result to lose a TLB hit rate. It is a big problem with the device such as rotator which does not do sequential access especially.

The page size is set to 4KB, because Linux kernel uses 4KB pages by default. Once support for other page size is available in the kernel, then sysmmu can be extended also.

Quoted 2 lines

And the IRQ handler just outputs only a message. It should be implemented in call back function to be able to handle from each device driver.

This was only for debugging purpose, but you are right that the sysmmu API in this area need to be extended.

Quoted 2 lines

When it sets System MMU in SHARED page table, kernel virtual memory is broken by a method such as s5p_sysmmu_map_area()

Yes, there should be a check added to prevent messing with ARM pgd in SHARED mode.

Best regards
--
Marek Szyprowski
Samsung Poland R&D Center

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel