linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6 0/4] Device Tree support for CMA (Contiguous Memory Allocator)
@ 2013-08-19 15:04 Marek Szyprowski
  2013-08-19 15:04 ` [PATCH v6 1/4] drivers: dma-contiguous: clean source code and prepare for device tree Marek Szyprowski
                   ` (3 more replies)
  0 siblings, 4 replies; 23+ messages in thread
From: Marek Szyprowski @ 2013-08-19 15:04 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

This is a sixth version of my proposal for device tree integration for
reserved memory and Contiguous Memory Allocator. This time I've fixes
more issues pointed by Rob Herring and added support for 'status'
property. For more information, please check the change log at the end
of the mail.

Just a few words for those who see this code for the first time:

The proposed bindings allows to define contiguous memory regions of
specified base address and size. Then, the defined regions can be
assigned to the given device(s) by adding a property with a phanle to
the defined contiguous memory region. From the device tree perspective
that's all. Once the bindings are added, all the memory allocations from
dma-mapping subsystem will be served from the defined contiguous memory
regions.

Contiguous Memory Allocator is a framework, which lets to provide a
large contiguous memory buffers for (usually a multimedia) devices. The
contiguous memory is reserved during early boot and then shared with
kernel, which is allowed to allocate it for movable pages. Then, when
device driver requests a contigouous buffer, the framework migrates
movable pages out of contiguous region and gives it to the driver. When
device driver frees the buffer, it is added to kernel memory pool again.
For more information, please refer to commit c64be2bb1c6eb43c838b2c6d57
("drivers: add Contiguous Memory Allocator") and d484864dd96e1830e76895
(CMA merge commit).

Why we need device tree bindings for CMA at all?

Older ARM kernels used so called board-based initialization. Those board
files contained a definition of all hardware blocks available on the
target system and particular kernel and driver software configuration
selected by the board maintainer.

In the new approach the board files will be removed completely and
Device Tree approach is used to describe all hardware blocks available
on the target system. By definition, the bindings should be software
independent, so at least in theory it should be possible to use those
bindings with other operating systems than Linux kernel.

Reserved memory configuration belongs to the grey area. It might depend
on hardware restriction of the board or modules and low-level
configuration done by bootloader. Putting reserved and contiguous memory
regions to /memory node and having phandles to those regions in the
device nodes however matches well with the device-tree typical style of
linking devices with other resources like clocks, interrupts,
regulators, power domains, etc. This is the main reason to use such
approach instead of putting everything to /chosen node as it has been
proposed in v2 and v3. However during the discussion at Linaro Connect
in Dublin it has been decided that reserved memory is one of the
_system_ property. Such system properties are not necessarily the
hardware properties, but they are well-known and likely properties of
the system that is running, so they can be encoded to device tree. This
patch series tries to provide such encoding with the respect to the
common device tree style of bindings and documentation.

Best regards
Marek Szyprowski
Samsung R&D Institute Poland

Changelog:

v6:
- added support for 'status' property, so memory regions can be disabled
  like any other nodes
- fixed issues pointed by Rob: removed annotations from function
  declarations and replaced macros with static inline functions.
- restored of_scan_flat_dt_by_path() function to simplify reserved memory
  scanning function
- the code now uses #size-cells/#address-cells properties from root node
  for interpreting 'reg' property in reserved memory regions
- fixed some issues in dt binding documentation

v5: http://thread.gmane.org/gmane.linux.ports.arm.kernel/259278
- renamed "contiguous-memory-region" compatibility string to
  "linux,contiguous-memory-region" (this one is really specific to Linux
  kernel implementation)
- renamed "dma-memory-region" property to "memory-region" (suggested by 
  Kumar Gala)
- added support for #address-cells, #size-cells for memory regions
  (thanks to Rob Herring for suggestion)
- removed generic code to scan specific path in flat device tree (cannot
  be used to fdt one-pass scan based initialization of memory regions with
  #address-cells and #size-cells parsing)
- replaced dma_contiguous_set_default_area() and dma_contiguous_add_device()
  functions with dev_set_cma_area() call

v4: http://thread.gmane.org/gmane.linux.ports.arm.kernel/256491
- corrected Devcie Tree mailing list address (resend)
- moved back contiguous-memory bindings from /chosen/contiguous-memory
  to /memory nodes as suggested by Grant (see 
  http://article.gmane.org/gmane.linux.drivers.devicetree/41030
  for more details)
- added support for DMA reserved memory with dma_declare_coherent()
- moved code to drivers/of/of_reserved_mem.c
- added generic code to scan specific path in flat device tree

v3: http://thread.gmane.org/gmane.linux.drivers.devicetree/40013/
- fixed issues pointed by Laura and updated documentation

v2: http://thread.gmane.org/gmane.linux.drivers.devicetree/34075
- moved contiguous-memory bindings from /memory to /chosen/contiguous-memory/
  node to avoid spreading Linux specific parameters over the whole device
  tree definitions
- added support for autoconfigured regions (use zero base)
- fixes minor bugs

v1: http://thread.gmane.org/gmane.linux.drivers.devicetree/30111/
- initial proposal

Patch summary:

Marek Szyprowski (4):
  drivers: dma-contiguous: clean source code and prepare for device
    tree
  drivers: of: add function to scan fdt nodes given by path
  drivers: of: add initialization code for dma reserved memory
  ARM: init: add support for reserved memory defined by device tree

 Documentation/devicetree/bindings/memory.txt |  166 ++++++++++++++++++++++++
 arch/arm/include/asm/dma-contiguous.h        |    1 -
 arch/arm/mm/init.c                           |    3 +
 arch/x86/include/asm/dma-contiguous.h        |    1 -
 drivers/base/dma-contiguous.c                |  119 +++++++-----------
 drivers/of/Kconfig                           |    6 +
 drivers/of/Makefile                          |    1 +
 drivers/of/fdt.c                             |   76 +++++++++++
 drivers/of/of_reserved_mem.c                 |  175 ++++++++++++++++++++++++++
 drivers/of/platform.c                        |    5 +
 include/asm-generic/dma-contiguous.h         |   28 -----
 include/linux/dma-contiguous.h               |   55 +++++++-
 include/linux/of_fdt.h                       |    3 +
 include/linux/of_reserved_mem.h              |   14 +++
 14 files changed, 546 insertions(+), 107 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/memory.txt
 create mode 100644 drivers/of/of_reserved_mem.c
 delete mode 100644 include/asm-generic/dma-contiguous.h
 create mode 100644 include/linux/of_reserved_mem.h

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v6 1/4] drivers: dma-contiguous: clean source code and prepare for device tree
  2013-08-19 15:04 [PATCH v6 0/4] Device Tree support for CMA (Contiguous Memory Allocator) Marek Szyprowski
@ 2013-08-19 15:04 ` Marek Szyprowski
  2013-08-19 15:04 ` [PATCH v6 2/4] drivers: of: add function to scan fdt nodes given by path Marek Szyprowski
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 23+ messages in thread
From: Marek Szyprowski @ 2013-08-19 15:04 UTC (permalink / raw)
  To: linux-arm-kernel

This patch cleans the initialization of dma contiguous framework. The
all-in-one dma_declare_contiguous() function is now separated into
dma_contiguous_reserve_area() which only steals the the memory from
memblock allocator and dma_contiguous_add_device() function, which
assigns given device to the specified reserved memory area. This improves
the flexibility in defining contiguous memory areas and assigning device
to them, because now it is possible to assign more than one device to
the given contiguous memory area. Such split in initialization procedure
is also required for upcoming device tree support.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
Acked-by: Michal Nazarewicz <mina86@mina86.com>
Acked-by: Tomasz Figa <t.figa@samsung.com>
---
 arch/arm/include/asm/dma-contiguous.h |    1 -
 arch/x86/include/asm/dma-contiguous.h |    1 -
 drivers/base/dma-contiguous.c         |  119 ++++++++++++---------------------
 include/asm-generic/dma-contiguous.h  |   28 --------
 include/linux/dma-contiguous.h        |   55 ++++++++++++++-
 5 files changed, 97 insertions(+), 107 deletions(-)
 delete mode 100644 include/asm-generic/dma-contiguous.h

diff --git a/arch/arm/include/asm/dma-contiguous.h b/arch/arm/include/asm/dma-contiguous.h
index 3ed37b4..63277bc 100644
--- a/arch/arm/include/asm/dma-contiguous.h
+++ b/arch/arm/include/asm/dma-contiguous.h
@@ -5,7 +5,6 @@
 #ifdef CONFIG_CMA
 
 #include <linux/types.h>
-#include <asm-generic/dma-contiguous.h>
 
 void dma_contiguous_early_fixup(phys_addr_t base, unsigned long size);
 
diff --git a/arch/x86/include/asm/dma-contiguous.h b/arch/x86/include/asm/dma-contiguous.h
index c092416..b4b38ba 100644
--- a/arch/x86/include/asm/dma-contiguous.h
+++ b/arch/x86/include/asm/dma-contiguous.h
@@ -4,7 +4,6 @@
 #ifdef __KERNEL__
 
 #include <linux/types.h>
-#include <asm-generic/dma-contiguous.h>
 
 static inline void
 dma_contiguous_early_fixup(phys_addr_t base, unsigned long size) { }
diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
index 0ca5442..4b94c91 100644
--- a/drivers/base/dma-contiguous.c
+++ b/drivers/base/dma-contiguous.c
@@ -96,7 +96,7 @@ static inline __maybe_unused phys_addr_t cma_early_percent_memory(void)
 #endif
 
 /**
- * dma_contiguous_reserve() - reserve area for contiguous memory handling
+ * dma_contiguous_reserve() - reserve area(s) for contiguous memory handling
  * @limit: End address of the reserved memory (optional, 0 for any).
  *
  * This function reserves memory from early allocator. It should be
@@ -124,22 +124,29 @@ void __init dma_contiguous_reserve(phys_addr_t limit)
 #endif
 	}
 
-	if (selected_size) {
+	if (selected_size && !dma_contiguous_default_area) {
 		pr_debug("%s: reserving %ld MiB for global area\n", __func__,
 			 (unsigned long)selected_size / SZ_1M);
 
-		dma_declare_contiguous(NULL, selected_size, 0, limit);
+		dma_contiguous_reserve_area(selected_size, 0, limit,
+					    &dma_contiguous_default_area);
 	}
 };
 
 static DEFINE_MUTEX(cma_mutex);
 
-static __init int cma_activate_area(unsigned long base_pfn, unsigned long count)
+static __init int cma_activate_area(struct cma *cma)
 {
-	unsigned long pfn = base_pfn;
-	unsigned i = count >> pageblock_order;
+	int bitmap_size = BITS_TO_LONGS(cma->count) * sizeof(long);
+	unsigned long base_pfn = cma->base_pfn, pfn = base_pfn;
+	unsigned i = cma->count >> pageblock_order;
 	struct zone *zone;
 
+	cma->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
+
+	if (!cma->bitmap)
+		return -ENOMEM;
+
 	WARN_ON_ONCE(!pfn_valid(pfn));
 	zone = page_zone(pfn_to_page(pfn));
 
@@ -153,92 +160,53 @@ static __init int cma_activate_area(unsigned long base_pfn, unsigned long count)
 		}
 		init_cma_reserved_pageblock(pfn_to_page(base_pfn));
 	} while (--i);
-	return 0;
-}
-
-static __init struct cma *cma_create_area(unsigned long base_pfn,
-				     unsigned long count)
-{
-	int bitmap_size = BITS_TO_LONGS(count) * sizeof(long);
-	struct cma *cma;
-	int ret = -ENOMEM;
-
-	pr_debug("%s(base %08lx, count %lx)\n", __func__, base_pfn, count);
-
-	cma = kmalloc(sizeof *cma, GFP_KERNEL);
-	if (!cma)
-		return ERR_PTR(-ENOMEM);
-
-	cma->base_pfn = base_pfn;
-	cma->count = count;
-	cma->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
 
-	if (!cma->bitmap)
-		goto no_mem;
-
-	ret = cma_activate_area(base_pfn, count);
-	if (ret)
-		goto error;
-
-	pr_debug("%s: returned %p\n", __func__, (void *)cma);
-	return cma;
-
-error:
-	kfree(cma->bitmap);
-no_mem:
-	kfree(cma);
-	return ERR_PTR(ret);
+	return 0;
 }
 
-static struct cma_reserved {
-	phys_addr_t start;
-	unsigned long size;
-	struct device *dev;
-} cma_reserved[MAX_CMA_AREAS] __initdata;
-static unsigned cma_reserved_count __initdata;
+static struct cma cma_areas[MAX_CMA_AREAS];
+static unsigned cma_area_count;
 
 static int __init cma_init_reserved_areas(void)
 {
-	struct cma_reserved *r = cma_reserved;
-	unsigned i = cma_reserved_count;
-
-	pr_debug("%s()\n", __func__);
+	int i;
 
-	for (; i; --i, ++r) {
-		struct cma *cma;
-		cma = cma_create_area(PFN_DOWN(r->start),
-				      r->size >> PAGE_SHIFT);
-		if (!IS_ERR(cma))
-			dev_set_cma_area(r->dev, cma);
+	for (i = 0; i < cma_area_count; i++) {
+		int ret = cma_activate_area(&cma_areas[i]);
+		if (ret)
+			return ret;
 	}
+
 	return 0;
 }
 core_initcall(cma_init_reserved_areas);
 
 /**
- * dma_declare_contiguous() - reserve area for contiguous memory handling
- *			      for particular device
- * @dev:   Pointer to device structure.
- * @size:  Size of the reserved memory.
- * @base:  Start address of the reserved memory (optional, 0 for any).
+ * dma_contiguous_reserve_area() - reserve custom contiguous area
+ * @size: Size of the reserved area (in bytes),
+ * @base: Base address of the reserved area optional, use 0 for any
  * @limit: End address of the reserved memory (optional, 0 for any).
+ * @res_cma: Pointer to store the created cma region.
  *
- * This function reserves memory for specified device. It should be
- * called by board specific code when early allocator (memblock or bootmem)
- * is still activate.
+ * This function reserves memory from early allocator. It should be
+ * called by arch specific code once the early allocator (memblock or bootmem)
+ * has been activated and all other subsystems have already allocated/reserved
+ * memory. This function allows to create custom reserved areas for specific
+ * devices.
  */
-int __init dma_declare_contiguous(struct device *dev, phys_addr_t size,
-				  phys_addr_t base, phys_addr_t limit)
+int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
+				       phys_addr_t limit, struct cma **res_cma)
 {
-	struct cma_reserved *r = &cma_reserved[cma_reserved_count];
+	struct cma *cma = &cma_areas[cma_area_count];
 	phys_addr_t alignment;
+	int ret = 0;
 
 	pr_debug("%s(size %lx, base %08lx, limit %08lx)\n", __func__,
 		 (unsigned long)size, (unsigned long)base,
 		 (unsigned long)limit);
 
 	/* Sanity checks */
-	if (cma_reserved_count == ARRAY_SIZE(cma_reserved)) {
+	if (cma_area_count == ARRAY_SIZE(cma_areas)) {
 		pr_err("Not enough slots for CMA reserved regions!\n");
 		return -ENOSPC;
 	}
@@ -256,7 +224,7 @@ int __init dma_declare_contiguous(struct device *dev, phys_addr_t size,
 	if (base) {
 		if (memblock_is_region_reserved(base, size) ||
 		    memblock_reserve(base, size) < 0) {
-			base = -EBUSY;
+			ret = -EBUSY;
 			goto err;
 		}
 	} else {
@@ -266,7 +234,7 @@ int __init dma_declare_contiguous(struct device *dev, phys_addr_t size,
 		 */
 		phys_addr_t addr = __memblock_alloc_base(size, alignment, limit);
 		if (!addr) {
-			base = -ENOMEM;
+			ret = -ENOMEM;
 			goto err;
 		} else {
 			base = addr;
@@ -277,10 +245,11 @@ int __init dma_declare_contiguous(struct device *dev, phys_addr_t size,
 	 * Each reserved area must be initialised later, when more kernel
 	 * subsystems (like slab allocator) are available.
 	 */
-	r->start = base;
-	r->size = size;
-	r->dev = dev;
-	cma_reserved_count++;
+	cma->base_pfn = PFN_DOWN(base);
+	cma->count = size >> PAGE_SHIFT;
+	*res_cma = cma;
+	cma_area_count++;
+
 	pr_info("CMA: reserved %ld MiB at %08lx\n", (unsigned long)size / SZ_1M,
 		(unsigned long)base);
 
@@ -289,7 +258,7 @@ int __init dma_declare_contiguous(struct device *dev, phys_addr_t size,
 	return 0;
 err:
 	pr_err("CMA: failed to reserve %ld MiB\n", (unsigned long)size / SZ_1M);
-	return base;
+	return ret;
 }
 
 /**
diff --git a/include/asm-generic/dma-contiguous.h b/include/asm-generic/dma-contiguous.h
deleted file mode 100644
index 294b1e7..0000000
--- a/include/asm-generic/dma-contiguous.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef ASM_DMA_CONTIGUOUS_H
-#define ASM_DMA_CONTIGUOUS_H
-
-#ifdef __KERNEL__
-#ifdef CONFIG_CMA
-
-#include <linux/device.h>
-#include <linux/dma-contiguous.h>
-
-static inline struct cma *dev_get_cma_area(struct device *dev)
-{
-	if (dev && dev->cma_area)
-		return dev->cma_area;
-	return dma_contiguous_default_area;
-}
-
-static inline void dev_set_cma_area(struct device *dev, struct cma *cma)
-{
-	if (dev)
-		dev->cma_area = cma;
-	if (!dev && !dma_contiguous_default_area)
-		dma_contiguous_default_area = cma;
-}
-
-#endif
-#endif
-
-#endif
diff --git a/include/linux/dma-contiguous.h b/include/linux/dma-contiguous.h
index 01b5c84..9439659 100644
--- a/include/linux/dma-contiguous.h
+++ b/include/linux/dma-contiguous.h
@@ -67,9 +67,48 @@ struct device;
 
 extern struct cma *dma_contiguous_default_area;
 
+static inline struct cma *dev_get_cma_area(struct device *dev)
+{
+	if (dev && dev->cma_area)
+		return dev->cma_area;
+	return dma_contiguous_default_area;
+}
+
+static inline void dev_set_cma_area(struct device *dev, struct cma *cma)
+{
+	if (dev)
+		dev->cma_area = cma;
+}
+
 void dma_contiguous_reserve(phys_addr_t addr_limit);
-int dma_declare_contiguous(struct device *dev, phys_addr_t size,
-			   phys_addr_t base, phys_addr_t limit);
+
+int __init dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
+				       phys_addr_t limit, struct cma **res_cma);
+
+/**
+ * dma_declare_contiguous() - reserve area for contiguous memory handling
+ *			      for particular device
+ * @dev:   Pointer to device structure.
+ * @size:  Size of the reserved memory.
+ * @base:  Start address of the reserved memory (optional, 0 for any).
+ * @limit: End address of the reserved memory (optional, 0 for any).
+ *
+ * This function reserves memory for specified device. It should be
+ * called by board specific code when early allocator (memblock or bootmem)
+ * is still activate.
+ */
+
+static inline int dma_declare_contiguous(struct device *dev, phys_addr_t size,
+					 phys_addr_t base, phys_addr_t limit)
+{
+	struct cma *cma;
+	int ret;
+	ret = dma_contiguous_reserve_area(size, base, limit, &cma);
+	if (ret == 0)
+		dev_set_cma_area(dev, cma);
+
+	return ret;
+}
 
 struct page *dma_alloc_from_contiguous(struct device *dev, int count,
 				       unsigned int order);
@@ -80,8 +119,20 @@ bool dma_release_from_contiguous(struct device *dev, struct page *pages,
 
 #define MAX_CMA_AREAS	(0)
 
+static inline struct cma *dev_get_cma_area(struct device *dev)
+{
+	return NULL;
+}
+
+static inline void dev_set_cma_area(struct device *dev, struct cma *cma) { }
+
 static inline void dma_contiguous_reserve(phys_addr_t limit) { }
 
+static inline int dma_contiguous_reserve_area(phys_addr_t size, phys_addr_t base,
+				       phys_addr_t limit, struct cma **res_cma) {
+	return -ENOSYS;
+}
+
 static inline
 int dma_declare_contiguous(struct device *dev, phys_addr_t size,
 			   phys_addr_t base, phys_addr_t limit)
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v6 2/4] drivers: of: add function to scan fdt nodes given by path
  2013-08-19 15:04 [PATCH v6 0/4] Device Tree support for CMA (Contiguous Memory Allocator) Marek Szyprowski
  2013-08-19 15:04 ` [PATCH v6 1/4] drivers: dma-contiguous: clean source code and prepare for device tree Marek Szyprowski
@ 2013-08-19 15:04 ` Marek Szyprowski
  2013-08-26 12:09   ` Rob Herring
  2013-08-19 15:04 ` [PATCH v6 3/4] drivers: of: add initialization code for dma reserved memory Marek Szyprowski
  2013-08-19 15:04 ` [PATCH v6 4/4] ARM: init: add support for reserved memory defined by device tree Marek Szyprowski
  3 siblings, 1 reply; 23+ messages in thread
From: Marek Szyprowski @ 2013-08-19 15:04 UTC (permalink / raw)
  To: linux-arm-kernel

Add a function to scan the flattened device-tree starting from the
node given by the path. It is used to extract information (like reserved
memory), which is required on early boot before we can unflatten the tree.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Acked-by: Michal Nazarewicz <mina86@mina86.com>
Acked-by: Tomasz Figa <t.figa@samsung.com>
---
 drivers/of/fdt.c       |   76 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/of_fdt.h |    3 ++
 2 files changed, 79 insertions(+)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 6bb7cf2..585b1a6 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -543,6 +543,82 @@ int __init of_flat_dt_match(unsigned long node, const char *const *compat)
 	return of_fdt_match(initial_boot_params, node, compat);
 }
 
+struct fdt_scan_status {
+	const char *name;
+	int namelen;
+	int depth;
+	int found;
+	int (*iterator)(unsigned long node, const char *uname, int depth, void *data);
+	void *data;
+};
+
+/**
+ * fdt_scan_node_by_path - iterator for of_scan_flat_dt_by_path function
+ */
+static int __init fdt_scan_node_by_path(unsigned long node, const char *uname,
+					int depth, void *data)
+{
+	struct fdt_scan_status *st = data;
+
+	/*
+	 * if scan at the requested fdt node has been completed,
+	 * return -ENXIO to abort further scanning
+	 */
+	if (depth <= st->depth)
+		return -ENXIO;
+
+	/* requested fdt node has been found, so call iterator function */
+	if (st->found)
+		return st->iterator(node, uname, depth, st->data);
+
+	/* check if scanning automata is entering next level of fdt nodes */
+	if (depth == st->depth + 1 &&
+	    strncmp(st->name, uname, st->namelen) == 0 &&
+	    uname[st->namelen] == 0) {
+		st->depth += 1;
+		if (st->name[st->namelen] == 0) {
+			st->found = 1;
+		} else {
+			const char *next = st->name + st->namelen + 1;
+			st->name = next;
+			st->namelen = strcspn(next, "/");
+		}
+		return 0;
+	}
+
+	/* scan next fdt node */
+	return 0;
+}
+
+/**
+ * of_scan_flat_dt_by_path - scan flattened tree blob and call callback on each
+ *			     child of the given path.
+ * @path: path to start searching for children
+ * @it: callback function
+ * @data: context data pointer
+ *
+ * This function is used to scan the flattened device-tree starting from the
+ * node given by path. It is used to extract information (like reserved
+ * memory), which is required on ealy boot before we can unflatten the tree.
+ */
+int __init of_scan_flat_dt_by_path(const char *path,
+	int (*it)(unsigned long node, const char *name, int depth, void *data),
+	void *data)
+{
+	struct fdt_scan_status st = {path, 0, -1, 0, it, data};
+	int ret = 0;
+
+	if (initial_boot_params)
+                ret = of_scan_flat_dt(fdt_scan_node_by_path, &st);
+
+	if (!st.found)
+		return -ENOENT;
+	else if (ret == -ENXIO)	/* scan has been completed */
+		return 0;
+	else
+		return ret;
+}
+
 #ifdef CONFIG_BLK_DEV_INITRD
 /**
  * early_init_dt_check_for_initrd - Decode initrd location from flat tree
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index ed136ad..1151a7f 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -90,6 +90,9 @@ extern void *of_get_flat_dt_prop(unsigned long node, const char *name,
 extern int of_flat_dt_is_compatible(unsigned long node, const char *name);
 extern int of_flat_dt_match(unsigned long node, const char *const *matches);
 extern unsigned long of_get_flat_dt_root(void);
+extern int of_scan_flat_dt_by_path(const char *path,
+	int (*it)(unsigned long node, const char *name, int depth, void *data),
+	void *data);
 
 extern int early_init_dt_scan_chosen(unsigned long node, const char *uname,
 				     int depth, void *data);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v6 3/4] drivers: of: add initialization code for dma reserved memory
  2013-08-19 15:04 [PATCH v6 0/4] Device Tree support for CMA (Contiguous Memory Allocator) Marek Szyprowski
  2013-08-19 15:04 ` [PATCH v6 1/4] drivers: dma-contiguous: clean source code and prepare for device tree Marek Szyprowski
  2013-08-19 15:04 ` [PATCH v6 2/4] drivers: of: add function to scan fdt nodes given by path Marek Szyprowski
@ 2013-08-19 15:04 ` Marek Szyprowski
  2013-08-19 21:49   ` Stephen Warren
                     ` (3 more replies)
  2013-08-19 15:04 ` [PATCH v6 4/4] ARM: init: add support for reserved memory defined by device tree Marek Szyprowski
  3 siblings, 4 replies; 23+ messages in thread
From: Marek Szyprowski @ 2013-08-19 15:04 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds device tree support for contiguous and reserved memory
regions defined in device tree.

Large memory blocks can be reliably reserved only during early boot.
This must happen before the whole memory management subsystem is
initialized, because we need to ensure that the given contiguous blocks
are not yet allocated by kernel. Also it must happen before kernel
mappings for the whole low memory are created, to ensure that there will
be no mappings (for reserved blocks) or mapping with special properties
can be created (for CMA blocks). This all happens before device tree
structures are unflattened, so we need to get reserved memory layout
directly from fdt.

Later, those reserved memory regions are assigned to devices on each
device structure initialization.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
Acked-by: Michal Nazarewicz <mina86@mina86.com>
Acked-by: Tomasz Figa <t.figa@samsung.com>
---
 Documentation/devicetree/bindings/memory.txt |  166 ++++++++++++++++++++++++
 drivers/of/Kconfig                           |    6 +
 drivers/of/Makefile                          |    1 +
 drivers/of/of_reserved_mem.c                 |  175 ++++++++++++++++++++++++++
 drivers/of/platform.c                        |    5 +
 include/linux/of_reserved_mem.h              |   14 +++
 6 files changed, 367 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/memory.txt
 create mode 100644 drivers/of/of_reserved_mem.c
 create mode 100644 include/linux/of_reserved_mem.h

diff --git a/Documentation/devicetree/bindings/memory.txt b/Documentation/devicetree/bindings/memory.txt
new file mode 100644
index 0000000..90e96278
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory.txt
@@ -0,0 +1,166 @@
+*** Memory binding ***
+
+The /memory node provides basic information about the address and size
+of the physical memory. This node is usually filled or updated by the
+bootloader, depending on the actual memory configuration of the given
+hardware.
+
+The memory layout is described by the following node:
+
+/ {
+	#address-cells = <(n)>;
+	#size-cells = <(m)>;
+	memory {
+		device_type = "memory";
+		reg =  <(baseaddr1) (size1)
+			(baseaddr2) (size2)
+			...
+			(baseaddrN) (sizeN)>;
+	};
+	...
+};
+
+A memory node follows the typical device tree rules for "reg" property:
+n:		number of cells used to store base address value
+m:		number of cells used to store size value
+baseaddrX:	defines a base address of the defined memory bank
+sizeX:		the size of the defined memory bank
+
+
+More than one memory bank can be defined.
+
+
+*** Reserved memory regions ***
+
+In /memory/reserved-memory node one can create additional nodes
+describing particular reserved (excluded from normal use) memory
+regions. Such memory regions are usually designed for the special usage
+by various device drivers. A good example are contiguous memory
+allocations or memory sharing with other operating system on the same
+hardware board. Those special memory regions might depend on the board
+configuration and devices used on the target system.
+
+Parameters for each memory region can be encoded into the device tree
+with the following convention:
+
+[(label):] (name) {
+	compatible = "linux,contiguous-memory-region", "reserved-memory-region";
+	reg = <(address) (size)>;
+	(linux,default-contiguous-region);
+};
+
+compatible:	"linux,contiguous-memory-region" - enables binding of this
+		region to Contiguous Memory Allocator (special region for
+		contiguous memory allocations, shared with movable system
+		memory, Linux kernel-specific), alternatively if
+		"reserved-memory-region" - compatibility is defined, given
+		region is assigned for exclusive usage for by the respective
+		devices
+
+reg:		standard property defining the base address and size of
+		the memory region
+
+linux,default-contiguous-region: property indicating that the region
+		is the default region for all contiguous memory
+		allocations, Linux specific (optional)
+
+It is optional to specify the base address, so if one wants to use
+autoconfiguration of the base address, '0' can be specified as a base
+address in the 'reg' property.
+
+The /memory/reserved-memory node must contain the same #address-cells
+and #size-cells value as the root node.
+
+
+*** Device node's properties ***
+
+Once regions in the /memory/reserved-memory node have been defined, they
+can be assigned to device nodes to enable respective device drivers to
+access them. The following properties are defined:
+
+memory-region = <&phandle_to_defined_region>;
+
+This property indicates that the device driver should use the memory
+region pointed by the given phandle.
+
+
+*** Example ***
+
+This example defines a memory consisting of 4 memory banks. 3 contiguous
+regions are defined for Linux kernel, one default of all device drivers
+(named contig_mem, placed at 0x72000000, 64MiB), one dedicated to the
+framebuffer device (labelled display_mem, placed at 0x78000000, 8MiB)
+and one for multimedia processing (labelled multimedia_mem, placed at
+0x77000000, 64MiB). 'display_mem' region is then assigned to fb at 12300000
+device for DMA memory allocations (Linux kernel drivers will use CMA is
+available or dma-exclusive usage otherwise). 'multimedia_mem' is
+assigned to scaler at 12500000 and codec at 12600000 devices for contiguous
+memory allocations when CMA driver is enabled.
+
+The reason for creating a separate region for framebuffer device is to
+match the framebuffer base address to the one configured by bootloader,
+so once Linux kernel drivers starts no glitches on the displayed boot
+logo appears. Scaller and codec drivers should share the memory
+allocations.
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	/* ... */
+
+	memory {
+		reg =  <0x40000000 0x10000000
+			0x50000000 0x10000000
+			0x60000000 0x10000000
+			0x70000000 0x10000000>;
+
+		reserved-memory {
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			/*
+			 * global autoconfigured region for contiguous allocations
+			 * (used only with Contiguous Memory Allocator)
+			 */
+			contig_region at 0 {
+				compatible = "linux,contiguous-memory-region";
+				reg = <0x0 0x4000000>;
+				linux,default-contiguous-region;
+			};
+
+			/*
+			 * special region for framebuffer
+			 */
+			display_mem: region at 78000000 {
+				compatible = "linux,contiguous-memory-region", "reserved-memory-region";
+				reg = <0x78000000 0x800000>;
+			};
+
+			/*
+			 * special region for multimedia processing devices
+			 */
+			multimedia_mem: region at 77000000 {
+				compatible = "linux,contiguous-memory-region";
+				reg = <0x77000000 0x4000000>;
+			};
+		};
+	};
+
+	/* ... */
+
+	fb0: fb at 12300000 {
+		status = "okay";
+		memory-region = <&display_mem>;
+	};
+
+	scaler: scaler at 12500000 {
+		status = "okay";
+		memory-region = <&multimedia_mem>;
+	};
+
+	codec: codec at 12600000 {
+		status = "okay";
+		memory-region = <&multimedia_mem>;
+	};
+};
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 80e5c13..a83ab43 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -80,4 +80,10 @@ config OF_MTD
 	depends on MTD
 	def_bool y
 
+config OF_RESERVED_MEM
+	depends on CMA || (HAVE_GENERIC_DMA_COHERENT && HAVE_MEMBLOCK)
+	def_bool y
+	help
+	  Initialization code for DMA reserved memory
+
 endmenu # OF
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index 1f9c0c4..e7e3322 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_OF_MDIO)	+= of_mdio.o
 obj-$(CONFIG_OF_PCI)	+= of_pci.o
 obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
 obj-$(CONFIG_OF_MTD)	+= of_mtd.o
+obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
new file mode 100644
index 0000000..95563d33
--- /dev/null
+++ b/drivers/of/of_reserved_mem.c
@@ -0,0 +1,175 @@
+/*
+ * Device tree based initialization code for reserved memory.
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ * Author: Marek Szyprowski <m.szyprowski@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License or (at your optional) any later version of the license.
+ */
+
+#include <asm/dma-contiguous.h>
+
+#include <linux/memblock.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+#include <linux/mm.h>
+#include <linux/sizes.h>
+#include <linux/mm_types.h>
+#include <linux/dma-contiguous.h>
+#include <linux/dma-mapping.h>
+#include <linux/of_reserved_mem.h>
+
+#define MAX_RESERVED_REGIONS	16
+struct reserved_mem {
+	phys_addr_t		base;
+	unsigned long		size;
+	struct cma		*cma;
+	char			name[32];
+};
+static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
+static int reserved_mem_count;
+
+static int __init fdt_scan_reserved_mem(unsigned long node, const char *uname,
+					int depth, void *data)
+{
+	struct reserved_mem *rmem = &reserved_mem[reserved_mem_count];
+	phys_addr_t base, size;
+	int is_cma, is_reserved;
+	unsigned long len;
+	const char *status;
+	__be32 *prop;
+
+	is_cma = IS_ENABLED(CONFIG_CMA) &&
+	       of_flat_dt_is_compatible(node, "linux,contiguous-memory-region");
+	is_reserved = of_flat_dt_is_compatible(node, "reserved-memory-region");
+
+	if (!is_reserved && !is_cma) {
+		/* ignore node and scan next one */
+		return 0;
+	}
+
+	status = of_get_flat_dt_prop(node, "status", &len);
+	if (status && strcmp(status, "okay") != 0) {
+		/* ignore disabled node nad scan next one */
+		return 0;
+	}
+
+	prop = of_get_flat_dt_prop(node, "reg", &len);
+	if (!prop || (len < (dt_root_size_cells + dt_root_addr_cells) *
+			     sizeof(__be32))) {
+		pr_err("Reserved mem: node %s, incorrect \"reg\" property\n",
+		       uname);
+		/* ignore node and scan next one */
+		return 0;
+	}
+	base = dt_mem_next_cell(dt_root_addr_cells, &prop);
+	size = dt_mem_next_cell(dt_root_size_cells, &prop);
+
+	if (!size) {
+		/* ignore node and scan next one */
+		return 0;
+	}
+
+	pr_info("Reserved mem: found %s, memory base %lx, size %ld MiB\n",
+		uname, (unsigned long)base, (unsigned long)size / SZ_1M);
+
+	if (reserved_mem_count == ARRAY_SIZE(reserved_mem))
+		return -ENOSPC;
+
+	rmem->base = base;
+	rmem->size = size;
+	strlcpy(rmem->name, uname, sizeof(rmem->name));
+
+	if (is_cma) {
+		struct cma *cma;
+		if (dma_contiguous_reserve_area(size, base, 0, &cma) == 0) {
+			rmem->cma = cma;
+			reserved_mem_count++;
+			if (of_get_flat_dt_prop(node,
+						"linux,default-contiguous-region",
+						NULL))
+				dma_contiguous_default_area = cma;
+		}
+	} else if (is_reserved) {
+		if (memblock_remove(base, size) == 0)
+			reserved_mem_count++;
+		else
+			pr_err("Failed to reserve memory for %s\n", uname);
+	}
+
+	return 0;
+}
+
+static struct reserved_mem *get_dma_memory_region(struct device *dev)
+{
+	struct device_node *node;
+	const char *name;
+	int i;
+
+	node = of_parse_phandle(dev->of_node, "memory-region", 0);
+	if (!node)
+		return NULL;
+
+	name = kbasename(node->full_name);
+	for (i = 0; i < reserved_mem_count; i++)
+		if (strcmp(name, reserved_mem[i].name) == 0)
+			return &reserved_mem[i];
+	return NULL;
+}
+
+/**
+ * of_reserved_mem_device_init() - assign reserved memory region to given device
+ *
+ * This function assign memory region pointed by "memory-region" device tree
+ * property to the given device.
+ */
+void of_reserved_mem_device_init(struct device *dev)
+{
+	struct reserved_mem *region = get_dma_memory_region(dev);
+	if (!region)
+		return;
+
+	if (region->cma) {
+		dev_set_cma_area(dev, region->cma);
+		pr_info("Assigned CMA %s to %s device\n", region->name,
+			dev_name(dev));
+	} else {
+		if (dma_declare_coherent_memory(dev, region->base, region->base,
+		    region->size, DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) != 0)
+			pr_info("Declared reserved memory %s to %s device\n",
+				region->name, dev_name(dev));
+	}
+}
+
+/**
+ * of_reserved_mem_device_release() - release reserved memory device structures
+ *
+ * This function releases structures allocated for memory region handling for
+ * the given device.
+ */
+void of_reserved_mem_device_release(struct device *dev)
+{
+	struct reserved_mem *region = get_dma_memory_region(dev);
+	if (!region && !region->cma)
+		dma_release_declared_memory(dev);
+}
+
+/**
+ * early_init_dt_scan_reserved_mem() - create reserved memory regions
+ *
+ * This function grabs memory from early allocator for device exclusive use
+ * defined in device tree structures. It should be called by arch specific code
+ * once the early allocator (memblock) has been activated and all other
+ * subsystems have already allocated/reserved memory.
+ */
+void __init early_init_dt_scan_reserved_mem(void)
+{
+	of_scan_flat_dt_by_path("/memory/reserved-memory",
+				fdt_scan_reserved_mem, NULL);
+}
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index e0a6514..1e4e91d 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -21,6 +21,7 @@
 #include <linux/of_device.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
+#include <linux/of_reserved_mem.h>
 #include <linux/platform_device.h>
 
 const struct of_device_id of_default_bus_match_table[] = {
@@ -196,6 +197,7 @@ EXPORT_SYMBOL(of_device_alloc);
  * Returns pointer to created platform device, or NULL if a device was not
  * registered.  Unavailable devices will not get registered.
  */
+
 struct platform_device *of_platform_device_create_pdata(
 					struct device_node *np,
 					const char *bus_id,
@@ -218,6 +220,8 @@ struct platform_device *of_platform_device_create_pdata(
 	dev->dev.bus = &platform_bus_type;
 	dev->dev.platform_data = platform_data;
 
+	of_reserved_mem_device_init(&dev->dev);
+
 	/* We do not fill the DMA ops for platform devices by default.
 	 * This is currently the responsibility of the platform code
 	 * to do such, possibly using a device notifier
@@ -225,6 +229,7 @@ struct platform_device *of_platform_device_create_pdata(
 
 	if (of_device_add(dev) != 0) {
 		platform_device_put(dev);
+		of_reserved_mem_device_release(&dev->dev);
 		return NULL;
 	}
 
diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
new file mode 100644
index 0000000..c841282
--- /dev/null
+++ b/include/linux/of_reserved_mem.h
@@ -0,0 +1,14 @@
+#ifndef __OF_RESERVED_MEM_H
+#define __OF_RESERVED_MEM_H
+
+#ifdef CONFIG_OF_RESERVED_MEM
+void of_reserved_mem_device_init(struct device *dev);
+void of_reserved_mem_device_release(struct device *dev);
+void early_init_dt_scan_reserved_mem(void);
+#else
+static inline void of_reserved_mem_device_init(struct device *dev) { }
+static inline void of_reserved_mem_device_release(struct device *dev) { }
+static inline void early_init_dt_scan_reserved_mem(void) { }
+#endif
+
+#endif /* __OF_RESERVED_MEM_H */
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v6 4/4] ARM: init: add support for reserved memory defined by device tree
  2013-08-19 15:04 [PATCH v6 0/4] Device Tree support for CMA (Contiguous Memory Allocator) Marek Szyprowski
                   ` (2 preceding siblings ...)
  2013-08-19 15:04 ` [PATCH v6 3/4] drivers: of: add initialization code for dma reserved memory Marek Szyprowski
@ 2013-08-19 15:04 ` Marek Szyprowski
  3 siblings, 0 replies; 23+ messages in thread
From: Marek Szyprowski @ 2013-08-19 15:04 UTC (permalink / raw)
  To: linux-arm-kernel

Enable reserved memory initialization from device tree.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
Acked-by: Michal Nazarewicz <mina86@mina86.com>
Acked-by: Tomasz Figa <t.figa@samsung.com>
---
 arch/arm/mm/init.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 15225d8..6a2fe44 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -17,6 +17,7 @@
 #include <linux/nodemask.h>
 #include <linux/initrd.h>
 #include <linux/of_fdt.h>
+#include <linux/of_reserved_mem.h>
 #include <linux/highmem.h>
 #include <linux/gfp.h>
 #include <linux/memblock.h>
@@ -377,6 +378,8 @@ void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc)
 	if (mdesc->reserve)
 		mdesc->reserve();
 
+	early_init_dt_scan_reserved_mem();
+
 	/*
 	 * reserve memory for DMA contigouos allocations,
 	 * must come from DMA area inside low memory
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v6 3/4] drivers: of: add initialization code for dma reserved memory
  2013-08-19 15:04 ` [PATCH v6 3/4] drivers: of: add initialization code for dma reserved memory Marek Szyprowski
@ 2013-08-19 21:49   ` Stephen Warren
  2013-08-19 22:02     ` Tomasz Figa
  2013-08-21 15:56   ` Matt Sealey
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 23+ messages in thread
From: Stephen Warren @ 2013-08-19 21:49 UTC (permalink / raw)
  To: linux-arm-kernel

On 08/19/2013 09:04 AM, Marek Szyprowski wrote:
> This patch adds device tree support for contiguous and reserved memory
> regions defined in device tree.

> diff --git a/Documentation/devicetree/bindings/memory.txt b/Documentation/devicetree/bindings/memory.txt

> +*** Reserved memory regions ***
> +
> +In /memory/reserved-memory node one can create additional nodes

s/additional/child/ or s/additional/sub/ would make it clearer where the
"additional" nodes should be placed.

> +compatible:	"linux,contiguous-memory-region" - enables binding of this
> +		region to Contiguous Memory Allocator (special region for
> +		contiguous memory allocations, shared with movable system
> +		memory, Linux kernel-specific), alternatively if
> +		"reserved-memory-region" - compatibility is defined, given
> +		region is assigned for exclusive usage for by the respective
> +		devices

"alternatively" makes it sound like the two compatible values are
mutually-exclusive. Perhaps make this a list, like:

----------
compatible: One or more of:

	- "linux,contiguous-memory-region" - enables binding of this
	  region to Contiguous Memory Allocator (special region for
	  contiguous memory allocations, shared with movable system
	  memory, Linux kernel-specific).
	- "reserved-memory-region" - compatibility is defined, given
	  region is assigned for exclusive usage for by the respective
	  devices.
----------

"linux,contiguous-memory-region" is already long enough, but I'd
slightly bikeshed towards "linux,contiguous-memory-allocator-region", or
perhaps "linux,cma-region" since it's not really describing whether the
memory is contiguous (at the level of /memory, each chunk of memory is
contiguous...)

> +*** Device node's properties ***
> +
> +Once regions in the /memory/reserved-memory node have been defined, they
> +can be assigned to device nodes to enable respective device drivers to
> +access them. The following properties are defined:
> +
> +memory-region = <&phandle_to_defined_region>;

I think the naming of that property should more obviously match this
binding and/or compatible value; perhaps cma-region or
contiguous-memory-region?

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v6 3/4] drivers: of: add initialization code for dma reserved memory
  2013-08-19 21:49   ` Stephen Warren
@ 2013-08-19 22:02     ` Tomasz Figa
  2013-08-19 22:17       ` Stephen Warren
  2013-08-29 21:12       ` Grant Likely
  0 siblings, 2 replies; 23+ messages in thread
From: Tomasz Figa @ 2013-08-19 22:02 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Stephen,

On Monday 19 of August 2013 15:49:20 Stephen Warren wrote:
> On 08/19/2013 09:04 AM, Marek Szyprowski wrote:
> > This patch adds device tree support for contiguous and reserved memory
> > regions defined in device tree.
> > 
> > diff --git a/Documentation/devicetree/bindings/memory.txt
> > b/Documentation/devicetree/bindings/memory.txt
> > 
> > +*** Reserved memory regions ***
> > +
> > +In /memory/reserved-memory node one can create additional nodes
> 
> s/additional/child/ or s/additional/sub/ would make it clearer where the
> "additional" nodes should be placed.
> 
> > +compatible:	"linux,contiguous-memory-region" - enables binding 
of
> > this
> > +		region to Contiguous Memory Allocator (special region for
> > +		contiguous memory allocations, shared with movable system
> > +		memory, Linux kernel-specific), alternatively if
> > +		"reserved-memory-region" - compatibility is defined, given
> > +		region is assigned for exclusive usage for by the 
respective
> > +		devices
> 
> "alternatively" makes it sound like the two compatible values are
> mutually-exclusive. Perhaps make this a list, like:
> 
> ----------
> compatible: One or more of:
> 
> 	- "linux,contiguous-memory-region" - enables binding of this
> 	  region to Contiguous Memory Allocator (special region for
> 	  contiguous memory allocations, shared with movable system
> 	  memory, Linux kernel-specific).
> 	- "reserved-memory-region" - compatibility is defined, given
> 	  region is assigned for exclusive usage for by the respective
> 	  devices.
> ----------
> 
> "linux,contiguous-memory-region" is already long enough, but I'd
> slightly bikeshed towards "linux,contiguous-memory-allocator-region", or
> perhaps "linux,cma-region" since it's not really describing whether the
> memory is contiguous (at the level of /memory, each chunk of memory is
> contiguous...)

I'm not really sure if we need the "linux" prefix for "contiguous-memory-
region". The concept of contiguous memory region is rather OS independent 
and tells us that memory allocated from this region will be contiguous. 
IMHO any OS is free to implement its own contiguous memory allocation 
method, without being limited to Linux CMA.

Keep in mind that rationale behind those contiguous regions was that there 
are devices that require buffers contiguous in memory to operate 
correctly.

But this is just nitpicking and I don't really have any strong opinion on 
this.

> > +*** Device node's properties ***
> > +
> > +Once regions in the /memory/reserved-memory node have been defined,
> > they +can be assigned to device nodes to enable respective device
> > drivers to +access them. The following properties are defined:
> > +
> > +memory-region = <&phandle_to_defined_region>;
> 
> I think the naming of that property should more obviously match this
> binding and/or compatible value; perhaps cma-region or
> contiguous-memory-region?

This property is not CMA-specific. Any memory region can be given using 
the memory-region property and used to allocate buffers for particular 
device.

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v6 3/4] drivers: of: add initialization code for dma reserved memory
  2013-08-19 22:02     ` Tomasz Figa
@ 2013-08-19 22:17       ` Stephen Warren
  2013-08-19 22:24         ` Tomasz Figa
  2013-08-20 10:57         ` Marek Szyprowski
  2013-08-29 21:12       ` Grant Likely
  1 sibling, 2 replies; 23+ messages in thread
From: Stephen Warren @ 2013-08-19 22:17 UTC (permalink / raw)
  To: linux-arm-kernel

On 08/19/2013 04:02 PM, Tomasz Figa wrote:
> Hi Stephen,
> 
> On Monday 19 of August 2013 15:49:20 Stephen Warren wrote:
>> On 08/19/2013 09:04 AM, Marek Szyprowski wrote:
>>> This patch adds device tree support for contiguous and reserved memory
>>> regions defined in device tree.
>>>
>>> diff --git a/Documentation/devicetree/bindings/memory.txt
>>> b/Documentation/devicetree/bindings/memory.txt
>>>
>>> +*** Reserved memory regions ***
>>> +
>>> +In /memory/reserved-memory node one can create additional nodes
>>
>> s/additional/child/ or s/additional/sub/ would make it clearer where the
>> "additional" nodes should be placed.
>>
>>> +compatible:	"linux,contiguous-memory-region" - enables binding 
> of
>>> this
>>> +		region to Contiguous Memory Allocator (special region for
>>> +		contiguous memory allocations, shared with movable system
>>> +		memory, Linux kernel-specific), alternatively if
>>> +		"reserved-memory-region" - compatibility is defined, given
>>> +		region is assigned for exclusive usage for by the 
> respective
>>> +		devices
>>
>> "alternatively" makes it sound like the two compatible values are
>> mutually-exclusive. Perhaps make this a list, like:
>>
>> ----------
>> compatible: One or more of:
>>
>> 	- "linux,contiguous-memory-region" - enables binding of this
>> 	  region to Contiguous Memory Allocator (special region for
>> 	  contiguous memory allocations, shared with movable system
>> 	  memory, Linux kernel-specific).
>> 	- "reserved-memory-region" - compatibility is defined, given
>> 	  region is assigned for exclusive usage for by the respective
>> 	  devices.
>> ----------
>>
>> "linux,contiguous-memory-region" is already long enough, but I'd
>> slightly bikeshed towards "linux,contiguous-memory-allocator-region", or
>> perhaps "linux,cma-region" since it's not really describing whether the
>> memory is contiguous (at the level of /memory, each chunk of memory is
>> contiguous...)
> 
> I'm not really sure if we need the "linux" prefix for "contiguous-memory-
> region". The concept of contiguous memory region is rather OS independent 
> and tells us that memory allocated from this region will be contiguous. 
> IMHO any OS is free to implement its own contiguous memory allocation 
> method, without being limited to Linux CMA.
> 
> Keep in mind that rationale behind those contiguous regions was that there 
> are devices that require buffers contiguous in memory to operate 
> correctly.
> 
> But this is just nitpicking and I don't really have any strong opinion on 
> this.
> 
>>> +*** Device node's properties ***
>>> +
>>> +Once regions in the /memory/reserved-memory node have been defined,
>>> they +can be assigned to device nodes to enable respective device
>>> drivers to +access them. The following properties are defined:
>>> +
>>> +memory-region = <&phandle_to_defined_region>;
>>
>> I think the naming of that property should more obviously match this
>> binding and/or compatible value; perhaps cma-region or
>> contiguous-memory-region?
> 
> This property is not CMA-specific. Any memory region can be given using 
> the memory-region property and used to allocate buffers for particular 
> device.

OK, that makes sense.

What I'm looking for is some way to make it obvious that when you see a
"memory-region" property in a node, you go look at the "memory.txt"
rather than the DT binding for the node where that property appears.
Right now, it doesn't seem that obvious to me.

I think the real issue here is that my brief reading of memory.txt
implies that arbitrary device nodes can include the memory-region
property without the node's own binding having to document it; the
property name is essentially "forced into" all other bindings.

I think instead, memory.txt should say:

----------
** Device node's properties ***

Once regions in the /memory/reserved-memory node have been defined, they
may be referenced by other device nodes. Bindings that wish to reference
memory regions should explicitly document their use of the following
property:

memory-region = <&phandle_to_defined_region>;

This property indicates that the device driver should use the memory
region pointed by the given phandle.
----------

Also, what if a device needs multiple separate memory regions? Perhaps a
GPU is forced to allocate displayable surfaces from addresses 0..32M and
textures/off-screen-render-targets from 256M..384M or something whacky
like that. In that case, we could either:

a) Adjust memory.txt to allow multiple entries in memory-regions, and
add an associated memory-region-names property.

or:

b) Adjust memory.txt not to mention any specific property names, but
simply mention that other DT nodes can refer to define memory regions by
phandle, and leave it up to individual bindings to define which property
they use to reference the memory regions, perhaps with memory.txt
providing a recommendation of memory-region for the simple case, but
perhaps also allowing a custom case, e.g.:

display-memory-region = <&phandl1e1>;
texture-memory-region = <&phahndle2>;

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v6 3/4] drivers: of: add initialization code for dma reserved memory
  2013-08-19 22:17       ` Stephen Warren
@ 2013-08-19 22:24         ` Tomasz Figa
  2013-08-19 22:27           ` Stephen Warren
  2013-08-20 10:57         ` Marek Szyprowski
  1 sibling, 1 reply; 23+ messages in thread
From: Tomasz Figa @ 2013-08-19 22:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 19 of August 2013 16:17:30 Stephen Warren wrote:
> On 08/19/2013 04:02 PM, Tomasz Figa wrote:
> > Hi Stephen,
> > 
> > On Monday 19 of August 2013 15:49:20 Stephen Warren wrote:
> >> On 08/19/2013 09:04 AM, Marek Szyprowski wrote:
> >>> This patch adds device tree support for contiguous and reserved
> >>> memory
> >>> regions defined in device tree.
> >>> 
> >>> diff --git a/Documentation/devicetree/bindings/memory.txt
> >>> b/Documentation/devicetree/bindings/memory.txt
> >>> 
> >>> +*** Reserved memory regions ***
> >>> +
> >>> +In /memory/reserved-memory node one can create additional nodes
> >> 
> >> s/additional/child/ or s/additional/sub/ would make it clearer where
> >> the "additional" nodes should be placed.
> >> 
> >>> +compatible:	"linux,contiguous-memory-region" - enables binding
> > 
> > of
> > 
> >>> this
> >>> +		region to Contiguous Memory Allocator (special region for
> >>> +		contiguous memory allocations, shared with movable system
> >>> +		memory, Linux kernel-specific), alternatively if
> >>> +		"reserved-memory-region" - compatibility is defined, given
> >>> +		region is assigned for exclusive usage for by the
> > 
> > respective
> > 
> >>> +		devices
> >> 
> >> "alternatively" makes it sound like the two compatible values are
> >> mutually-exclusive. Perhaps make this a list, like:
> >> 
> >> ----------
> >> 
> >> compatible: One or more of:
> >> 	- "linux,contiguous-memory-region" - enables binding of this
> >> 	
> >> 	  region to Contiguous Memory Allocator (special region for
> >> 	  contiguous memory allocations, shared with movable system
> >> 	  memory, Linux kernel-specific).
> >> 	
> >> 	- "reserved-memory-region" - compatibility is defined, given
> >> 	
> >> 	  region is assigned for exclusive usage for by the respective
> >> 	  devices.
> >> 
> >> ----------
> >> 
> >> "linux,contiguous-memory-region" is already long enough, but I'd
> >> slightly bikeshed towards "linux,contiguous-memory-allocator-region",
> >> or perhaps "linux,cma-region" since it's not really describing
> >> whether the memory is contiguous (at the level of /memory, each
> >> chunk of memory is contiguous...)
> > 
> > I'm not really sure if we need the "linux" prefix for
> > "contiguous-memory- region". The concept of contiguous memory region
> > is rather OS independent and tells us that memory allocated from this
> > region will be contiguous. IMHO any OS is free to implement its own
> > contiguous memory allocation method, without being limited to Linux
> > CMA.
> > 
> > Keep in mind that rationale behind those contiguous regions was that
> > there are devices that require buffers contiguous in memory to
> > operate correctly.
> > 
> > But this is just nitpicking and I don't really have any strong opinion
> > on this.
> > 
> >>> +*** Device node's properties ***
> >>> +
> >>> +Once regions in the /memory/reserved-memory node have been defined,
> >>> they +can be assigned to device nodes to enable respective device
> >>> drivers to +access them. The following properties are defined:
> >>> +
> >>> +memory-region = <&phandle_to_defined_region>;
> >> 
> >> I think the naming of that property should more obviously match this
> >> binding and/or compatible value; perhaps cma-region or
> >> contiguous-memory-region?
> > 
> > This property is not CMA-specific. Any memory region can be given
> > using
> > the memory-region property and used to allocate buffers for particular
> > device.
> 
> OK, that makes sense.
> 
> What I'm looking for is some way to make it obvious that when you see a
> "memory-region" property in a node, you go look at the "memory.txt"
> rather than the DT binding for the node where that property appears.
> Right now, it doesn't seem that obvious to me.
> 
> I think the real issue here is that my brief reading of memory.txt
> implies that arbitrary device nodes can include the memory-region
> property without the node's own binding having to document it; the
> property name is essentially "forced into" all other bindings.
> 
> I think instead, memory.txt should say:
> 
> ----------
> ** Device node's properties ***
> 
> Once regions in the /memory/reserved-memory node have been defined, they
> may be referenced by other device nodes. Bindings that wish to
> reference memory regions should explicitly document their use of the
> following property:
> 
> memory-region = <&phandle_to_defined_region>;
> 
> This property indicates that the device driver should use the memory
> region pointed by the given phandle.
> ----------
> 
> Also, what if a device needs multiple separate memory regions? Perhaps a
> GPU is forced to allocate displayable surfaces from addresses 0..32M
> and textures/off-screen-render-targets from 256M..384M or something
> whacky like that. In that case, we could either:
> 
> a) Adjust memory.txt to allow multiple entries in memory-regions, and
> add an associated memory-region-names property.
> 
> or:
> 
> b) Adjust memory.txt not to mention any specific property names, but
> simply mention that other DT nodes can refer to define memory regions by
> phandle, and leave it up to individual bindings to define which
> property they use to reference the memory regions, perhaps with
> memory.txt providing a recommendation of memory-region for the simple
> case, but perhaps also allowing a custom case, e.g.:
> 
> display-memory-region = <&phandl1e1>;
> texture-memory-region = <&phahndle2>;

Well, such setup simply cannot be handled by Linux today, as one device 
(aka one struct device) can only have one memory region bound to it. So 
this is not something we can implement today.

I agree that the device tree should be able to describe such 
configurations, though, but I'm not sure if this should be done from this 
side.

IMHO the concept of memport (or bus master) can be used to represent cases 
when multiple parts of an IP have different requirements for memory they 
work with. This is what Marek's patches adjusting MFC bindings to use 
memory-regions are also about.

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v6 3/4] drivers: of: add initialization code for dma reserved memory
  2013-08-19 22:24         ` Tomasz Figa
@ 2013-08-19 22:27           ` Stephen Warren
  2013-08-19 22:40             ` Tomasz Figa
  0 siblings, 1 reply; 23+ messages in thread
From: Stephen Warren @ 2013-08-19 22:27 UTC (permalink / raw)
  To: linux-arm-kernel

On 08/19/2013 04:24 PM, Tomasz Figa wrote:
> On Monday 19 of August 2013 16:17:30 Stephen Warren wrote:
>> On 08/19/2013 04:02 PM, Tomasz Figa wrote:
>>> Hi Stephen,
>>>
>>> On Monday 19 of August 2013 15:49:20 Stephen Warren wrote:
>>>> On 08/19/2013 09:04 AM, Marek Szyprowski wrote:
>>>>> This patch adds device tree support for contiguous and reserved
>>>>> memory
>>>>> regions defined in device tree.
>>>>>
>>>>> diff --git a/Documentation/devicetree/bindings/memory.txt
>>>>> b/Documentation/devicetree/bindings/memory.txt
>>>>>
>>>>> +*** Reserved memory regions ***
>>>>> +
>>>>> +In /memory/reserved-memory node one can create additional nodes
>>>>
>>>> s/additional/child/ or s/additional/sub/ would make it clearer where
>>>> the "additional" nodes should be placed.
>>>>
>>>>> +compatible:	"linux,contiguous-memory-region" - enables binding
>>>
>>> of
>>>
>>>>> this
>>>>> +		region to Contiguous Memory Allocator (special region for
>>>>> +		contiguous memory allocations, shared with movable system
>>>>> +		memory, Linux kernel-specific), alternatively if
>>>>> +		"reserved-memory-region" - compatibility is defined, given
>>>>> +		region is assigned for exclusive usage for by the
>>>
>>> respective
>>>
>>>>> +		devices
>>>>
>>>> "alternatively" makes it sound like the two compatible values are
>>>> mutually-exclusive. Perhaps make this a list, like:
>>>>
>>>> ----------
>>>>
>>>> compatible: One or more of:
>>>> 	- "linux,contiguous-memory-region" - enables binding of this
>>>> 	
>>>> 	  region to Contiguous Memory Allocator (special region for
>>>> 	  contiguous memory allocations, shared with movable system
>>>> 	  memory, Linux kernel-specific).
>>>> 	
>>>> 	- "reserved-memory-region" - compatibility is defined, given
>>>> 	
>>>> 	  region is assigned for exclusive usage for by the respective
>>>> 	  devices.
>>>>
>>>> ----------
>>>>
>>>> "linux,contiguous-memory-region" is already long enough, but I'd
>>>> slightly bikeshed towards "linux,contiguous-memory-allocator-region",
>>>> or perhaps "linux,cma-region" since it's not really describing
>>>> whether the memory is contiguous (at the level of /memory, each
>>>> chunk of memory is contiguous...)
>>>
>>> I'm not really sure if we need the "linux" prefix for
>>> "contiguous-memory- region". The concept of contiguous memory region
>>> is rather OS independent and tells us that memory allocated from this
>>> region will be contiguous. IMHO any OS is free to implement its own
>>> contiguous memory allocation method, without being limited to Linux
>>> CMA.
>>>
>>> Keep in mind that rationale behind those contiguous regions was that
>>> there are devices that require buffers contiguous in memory to
>>> operate correctly.
>>>
>>> But this is just nitpicking and I don't really have any strong opinion
>>> on this.
>>>
>>>>> +*** Device node's properties ***
>>>>> +
>>>>> +Once regions in the /memory/reserved-memory node have been defined,
>>>>> they +can be assigned to device nodes to enable respective device
>>>>> drivers to +access them. The following properties are defined:
>>>>> +
>>>>> +memory-region = <&phandle_to_defined_region>;
>>>>
>>>> I think the naming of that property should more obviously match this
>>>> binding and/or compatible value; perhaps cma-region or
>>>> contiguous-memory-region?
>>>
>>> This property is not CMA-specific. Any memory region can be given
>>> using
>>> the memory-region property and used to allocate buffers for particular
>>> device.
>>
>> OK, that makes sense.
>>
>> What I'm looking for is some way to make it obvious that when you see a
>> "memory-region" property in a node, you go look at the "memory.txt"
>> rather than the DT binding for the node where that property appears.
>> Right now, it doesn't seem that obvious to me.
>>
>> I think the real issue here is that my brief reading of memory.txt
>> implies that arbitrary device nodes can include the memory-region
>> property without the node's own binding having to document it; the
>> property name is essentially "forced into" all other bindings.
>>
>> I think instead, memory.txt should say:
>>
>> ----------
>> ** Device node's properties ***
>>
>> Once regions in the /memory/reserved-memory node have been defined, they
>> may be referenced by other device nodes. Bindings that wish to
>> reference memory regions should explicitly document their use of the
>> following property:
>>
>> memory-region = <&phandle_to_defined_region>;
>>
>> This property indicates that the device driver should use the memory
>> region pointed by the given phandle.
>> ----------
>>
>> Also, what if a device needs multiple separate memory regions? Perhaps a
>> GPU is forced to allocate displayable surfaces from addresses 0..32M
>> and textures/off-screen-render-targets from 256M..384M or something
>> whacky like that. In that case, we could either:
>>
>> a) Adjust memory.txt to allow multiple entries in memory-regions, and
>> add an associated memory-region-names property.
>>
>> or:
>>
>> b) Adjust memory.txt not to mention any specific property names, but
>> simply mention that other DT nodes can refer to define memory regions by
>> phandle, and leave it up to individual bindings to define which
>> property they use to reference the memory regions, perhaps with
>> memory.txt providing a recommendation of memory-region for the simple
>> case, but perhaps also allowing a custom case, e.g.:
>>
>> display-memory-region = <&phandl1e1>;
>> texture-memory-region = <&phahndle2>;
> 
> Well, such setup simply cannot be handled by Linux today, as one device 
> (aka one struct device) can only have one memory region bound to it. So 
> this is not something we can implement today.

Don't you just create "fake" struct devices to make this work, so that
the top-level struct device is instantiated from DT, and the others
created manually in the top-level device's probe routine, and the memory
regions get attached to those "fake" child devices? Seems pretty
conceptually easy.

> I agree that the device tree should be able to describe such 
> configurations,

good:-)

> though, but I'm not sure if this should be done from this side.

I'm not sure what "from this side" means. It seems pretty simple to
adjust this patch to allow such HW to be represented, so shouldn't we
just do it and be done with the question?

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v6 3/4] drivers: of: add initialization code for dma reserved memory
  2013-08-19 22:27           ` Stephen Warren
@ 2013-08-19 22:40             ` Tomasz Figa
  2013-08-19 22:54               ` Stephen Warren
  0 siblings, 1 reply; 23+ messages in thread
From: Tomasz Figa @ 2013-08-19 22:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 19 of August 2013 16:27:14 Stephen Warren wrote:
> On 08/19/2013 04:24 PM, Tomasz Figa wrote:
> > On Monday 19 of August 2013 16:17:30 Stephen Warren wrote:
> >> On 08/19/2013 04:02 PM, Tomasz Figa wrote:
> >>> Hi Stephen,
> >>> 
> >>> On Monday 19 of August 2013 15:49:20 Stephen Warren wrote:
> >>>> On 08/19/2013 09:04 AM, Marek Szyprowski wrote:
> >>>>> This patch adds device tree support for contiguous and reserved
> >>>>> memory
> >>>>> regions defined in device tree.
> >>>>> 
> >>>>> diff --git a/Documentation/devicetree/bindings/memory.txt
> >>>>> b/Documentation/devicetree/bindings/memory.txt
> >>>>> 
> >>>>> +*** Reserved memory regions ***
> >>>>> +
> >>>>> +In /memory/reserved-memory node one can create additional nodes
> >>>> 
> >>>> s/additional/child/ or s/additional/sub/ would make it clearer
> >>>> where
> >>>> the "additional" nodes should be placed.
> >>>> 
> >>>>> +compatible:	"linux,contiguous-memory-region" - enables binding
> >>> 
> >>> of
> >>> 
> >>>>> this
> >>>>> +		region to Contiguous Memory Allocator (special 
region for
> >>>>> +		contiguous memory allocations, shared with movable 
system
> >>>>> +		memory, Linux kernel-specific), alternatively if
> >>>>> +		"reserved-memory-region" - compatibility is 
defined, given
> >>>>> +		region is assigned for exclusive usage for by the
> >>> 
> >>> respective
> >>> 
> >>>>> +		devices
> >>>> 
> >>>> "alternatively" makes it sound like the two compatible values are
> >>>> mutually-exclusive. Perhaps make this a list, like:
> >>>> 
> >>>> ----------
> >>>> 
> >>>> compatible: One or more of:
> >>>> 	- "linux,contiguous-memory-region" - enables binding of this
> >>>> 	
> >>>> 	  region to Contiguous Memory Allocator (special region for
> >>>> 	  contiguous memory allocations, shared with movable system
> >>>> 	  memory, Linux kernel-specific).
> >>>> 	
> >>>> 	- "reserved-memory-region" - compatibility is defined, given
> >>>> 	
> >>>> 	  region is assigned for exclusive usage for by the respective
> >>>> 	  devices.
> >>>> 
> >>>> ----------
> >>>> 
> >>>> "linux,contiguous-memory-region" is already long enough, but I'd
> >>>> slightly bikeshed towards
> >>>> "linux,contiguous-memory-allocator-region",
> >>>> or perhaps "linux,cma-region" since it's not really describing
> >>>> whether the memory is contiguous (at the level of /memory, each
> >>>> chunk of memory is contiguous...)
> >>> 
> >>> I'm not really sure if we need the "linux" prefix for
> >>> "contiguous-memory- region". The concept of contiguous memory region
> >>> is rather OS independent and tells us that memory allocated from
> >>> this
> >>> region will be contiguous. IMHO any OS is free to implement its own
> >>> contiguous memory allocation method, without being limited to Linux
> >>> CMA.
> >>> 
> >>> Keep in mind that rationale behind those contiguous regions was that
> >>> there are devices that require buffers contiguous in memory to
> >>> operate correctly.
> >>> 
> >>> But this is just nitpicking and I don't really have any strong
> >>> opinion
> >>> on this.
> >>> 
> >>>>> +*** Device node's properties ***
> >>>>> +
> >>>>> +Once regions in the /memory/reserved-memory node have been
> >>>>> defined,
> >>>>> they +can be assigned to device nodes to enable respective device
> >>>>> drivers to +access them. The following properties are defined:
> >>>>> +
> >>>>> +memory-region = <&phandle_to_defined_region>;
> >>>> 
> >>>> I think the naming of that property should more obviously match
> >>>> this
> >>>> binding and/or compatible value; perhaps cma-region or
> >>>> contiguous-memory-region?
> >>> 
> >>> This property is not CMA-specific. Any memory region can be given
> >>> using
> >>> the memory-region property and used to allocate buffers for
> >>> particular
> >>> device.
> >> 
> >> OK, that makes sense.
> >> 
> >> What I'm looking for is some way to make it obvious that when you see
> >> a
> >> "memory-region" property in a node, you go look at the "memory.txt"
> >> rather than the DT binding for the node where that property appears.
> >> Right now, it doesn't seem that obvious to me.
> >> 
> >> I think the real issue here is that my brief reading of memory.txt
> >> implies that arbitrary device nodes can include the memory-region
> >> property without the node's own binding having to document it; the
> >> property name is essentially "forced into" all other bindings.
> >> 
> >> I think instead, memory.txt should say:
> >> 
> >> ----------
> >> ** Device node's properties ***
> >> 
> >> Once regions in the /memory/reserved-memory node have been defined,
> >> they may be referenced by other device nodes. Bindings that wish to
> >> reference memory regions should explicitly document their use of the
> >> following property:
> >> 
> >> memory-region = <&phandle_to_defined_region>;
> >> 
> >> This property indicates that the device driver should use the memory
> >> region pointed by the given phandle.
> >> ----------
> >> 
> >> Also, what if a device needs multiple separate memory regions?
> >> Perhaps a GPU is forced to allocate displayable surfaces from
> >> addresses 0..32M and textures/off-screen-render-targets from
> >> 256M..384M or something whacky like that. In that case, we could
> >> either:
> >> 
> >> a) Adjust memory.txt to allow multiple entries in memory-regions, and
> >> add an associated memory-region-names property.
> >> 
> >> or:
> >> 
> >> b) Adjust memory.txt not to mention any specific property names, but
> >> simply mention that other DT nodes can refer to define memory regions
> >> by phandle, and leave it up to individual bindings to define which
> >> property they use to reference the memory regions, perhaps with
> >> memory.txt providing a recommendation of memory-region for the
> >> simple case, but perhaps also allowing a custom case, e.g.:
> >> 
> >> display-memory-region = <&phandl1e1>;
> >> texture-memory-region = <&phahndle2>;
> > 
> > Well, such setup simply cannot be handled by Linux today, as one
> > device
> > (aka one struct device) can only have one memory region bound to it.
> > So
> > this is not something we can implement today.
> 
> Don't you just create "fake" struct devices to make this work, so that
> the top-level struct device is instantiated from DT, and the others
> created manually in the top-level device's probe routine, and the memory
> regions get attached to those "fake" child devices? Seems pretty
> conceptually easy.

Correct. However you need those fake struct devices to be attached to some 
memory region and often other things like IOMMU. In fact, they aren't 
entirely fake, as they usually represent real bus masters of the IP.

> > I agree that the device tree should be able to describe such
> > configurations,
> 
> good:-)
> 
> > though, but I'm not sure if this should be done from this side.
> 
> I'm not sure what "from this side" means. It seems pretty simple to
> adjust this patch to allow such HW to be represented, so shouldn't we
> just do it and be done with the question?

Well, if it's just about modifying the binding to support such cases, but 
without actually adding support for them in Linux, then I guess it's fine. 
Otherwise a lot of memory management code (mostly the DMA mapping API and 
a lot of its users) would have to be almost completely reworked, which 
wouldn't be an easy task.

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v6 3/4] drivers: of: add initialization code for dma reserved memory
  2013-08-19 22:40             ` Tomasz Figa
@ 2013-08-19 22:54               ` Stephen Warren
  0 siblings, 0 replies; 23+ messages in thread
From: Stephen Warren @ 2013-08-19 22:54 UTC (permalink / raw)
  To: linux-arm-kernel

On 08/19/2013 04:40 PM, Tomasz Figa wrote:
> On Monday 19 of August 2013 16:27:14 Stephen Warren wrote:
>> On 08/19/2013 04:24 PM, Tomasz Figa wrote:
>>> On Monday 19 of August 2013 16:17:30 Stephen Warren wrote:
>>>> On 08/19/2013 04:02 PM, Tomasz Figa wrote:
>>>>> Hi Stephen,
>>>>>
>>>>> On Monday 19 of August 2013 15:49:20 Stephen Warren wrote:
>>>>>> On 08/19/2013 09:04 AM, Marek Szyprowski wrote:
>>>>>>> This patch adds device tree support for contiguous and reserved
>>>>>>> memory regions defined in device tree.
>>>>>>>
>>>>>>> diff --git a/Documentation/devicetree/bindings/memory.txt
>>>>>>> b/Documentation/devicetree/bindings/memory.txt
...
>>>> Also, what if a device needs multiple separate memory regions?
>>>> Perhaps a GPU is forced to allocate displayable surfaces from
>>>> addresses 0..32M and textures/off-screen-render-targets from
>>>> 256M..384M or something whacky like that. In that case, we could
>>>> either:
>>>>
>>>> a) Adjust memory.txt to allow multiple entries in memory-regions, and
>>>> add an associated memory-region-names property.
>>>>
>>>> or:
>>>>
>>>> b) Adjust memory.txt not to mention any specific property names, but
>>>> simply mention that other DT nodes can refer to define memory regions
>>>> by phandle, and leave it up to individual bindings to define which
>>>> property they use to reference the memory regions, perhaps with
>>>> memory.txt providing a recommendation of memory-region for the
>>>> simple case, but perhaps also allowing a custom case, e.g.:
>>>>
>>>> display-memory-region = <&phandl1e1>;
>>>> texture-memory-region = <&phahndle2>;
>>>
>>> Well, such setup simply cannot be handled by Linux today, as one
...
>>> I agree that the device tree should be able to describe such
>>> configurations,
...
> Well, if it's just about modifying the binding to support such cases, but 
> without actually adding support for them in Linux, then I guess it's fine. 

Yes. I don't care so much if the SW won't work (yet?), but I want to
make sure the binding isn't going to need semantic changes.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v6 3/4] drivers: of: add initialization code for dma reserved memory
  2013-08-19 22:17       ` Stephen Warren
  2013-08-19 22:24         ` Tomasz Figa
@ 2013-08-20 10:57         ` Marek Szyprowski
  2013-08-20 16:35           ` Stephen Warren
  1 sibling, 1 reply; 23+ messages in thread
From: Marek Szyprowski @ 2013-08-20 10:57 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On 8/20/2013 12:17 AM, Stephen Warren wrote:
> On 08/19/2013 04:02 PM, Tomasz Figa wrote:
> > Hi Stephen,
> >
> > On Monday 19 of August 2013 15:49:20 Stephen Warren wrote:
> >> On 08/19/2013 09:04 AM, Marek Szyprowski wrote:
> >>> This patch adds device tree support for contiguous and reserved memory
> >>> regions defined in device tree.
> >>>
> >>> diff --git a/Documentation/devicetree/bindings/memory.txt
> >>> b/Documentation/devicetree/bindings/memory.txt
> >>>
> >>> +*** Reserved memory regions ***
> >>> +
> >>> +In /memory/reserved-memory node one can create additional nodes
> >>
> >> s/additional/child/ or s/additional/sub/ would make it clearer where the
> >> "additional" nodes should be placed.
> >>
> >>> +compatible:	"linux,contiguous-memory-region" - enables binding
> > of
> >>> this
> >>> +		region to Contiguous Memory Allocator (special region for
> >>> +		contiguous memory allocations, shared with movable system
> >>> +		memory, Linux kernel-specific), alternatively if
> >>> +		"reserved-memory-region" - compatibility is defined, given
> >>> +		region is assigned for exclusive usage for by the
> > respective
> >>> +		devices
> >>
> >> "alternatively" makes it sound like the two compatible values are
> >> mutually-exclusive. Perhaps make this a list, like:
> >>
> >> ----------
> >> compatible: One or more of:
> >>
> >> 	- "linux,contiguous-memory-region" - enables binding of this
> >> 	  region to Contiguous Memory Allocator (special region for
> >> 	  contiguous memory allocations, shared with movable system
> >> 	  memory, Linux kernel-specific).
> >> 	- "reserved-memory-region" - compatibility is defined, given
> >> 	  region is assigned for exclusive usage for by the respective
> >> 	  devices.
> >> ----------
> >>
> >> "linux,contiguous-memory-region" is already long enough, but I'd
> >> slightly bikeshed towards "linux,contiguous-memory-allocator-region", or
> >> perhaps "linux,cma-region" since it's not really describing whether the
> >> memory is contiguous (at the level of /memory, each chunk of memory is
> >> contiguous...)
> >
> > I'm not really sure if we need the "linux" prefix for "contiguous-memory-
> > region". The concept of contiguous memory region is rather OS independent
> > and tells us that memory allocated from this region will be contiguous.
> > IMHO any OS is free to implement its own contiguous memory allocation
> > method, without being limited to Linux CMA.
> >
> > Keep in mind that rationale behind those contiguous regions was that there
> > are devices that require buffers contiguous in memory to operate
> > correctly.
> >
> > But this is just nitpicking and I don't really have any strong opinion on
> > this.
> >
> >>> +*** Device node's properties ***
> >>> +
> >>> +Once regions in the /memory/reserved-memory node have been defined,
> >>> they +can be assigned to device nodes to enable respective device
> >>> drivers to +access them. The following properties are defined:
> >>> +
> >>> +memory-region = <&phandle_to_defined_region>;
> >>
> >> I think the naming of that property should more obviously match this
> >> binding and/or compatible value; perhaps cma-region or
> >> contiguous-memory-region?
> >
> > This property is not CMA-specific. Any memory region can be given using
> > the memory-region property and used to allocate buffers for particular
> > device.
>
> OK, that makes sense.
>
> What I'm looking for is some way to make it obvious that when you see a
> "memory-region" property in a node, you go look at the "memory.txt"
> rather than the DT binding for the node where that property appears.
> Right now, it doesn't seem that obvious to me.
>
> I think the real issue here is that my brief reading of memory.txt
> implies that arbitrary device nodes can include the memory-region
> property without the node's own binding having to document it; the
> property name is essentially "forced into" all other bindings.
>
> I think instead, memory.txt should say:
>
> ----------
> ** Device node's properties ***
>
> Once regions in the /memory/reserved-memory node have been defined, they
> may be referenced by other device nodes. Bindings that wish to reference
> memory regions should explicitly document their use of the following
> property:
>
> memory-region = <&phandle_to_defined_region>;
>
> This property indicates that the device driver should use the memory
> region pointed by the given phandle.
> ----------
>
> Also, what if a device needs multiple separate memory regions? Perhaps a
> GPU is forced to allocate displayable surfaces from addresses 0..32M and
> textures/off-screen-render-targets from 256M..384M or something whacky
> like that. In that case, we could either:
>
> a) Adjust memory.txt to allow multiple entries in memory-regions, and
> add an associated memory-region-names property.
>
> or:
>
> b) Adjust memory.txt not to mention any specific property names, but
> simply mention that other DT nodes can refer to define memory regions by
> phandle, and leave it up to individual bindings to define which property
> they use to reference the memory regions, perhaps with memory.txt
> providing a recommendation of memory-region for the simple case, but
> perhaps also allowing a custom case, e.g.:
>
> display-memory-region = <&phandl1e1>;
> texture-memory-region = <&phahndle2>;

Support for multiple regions is something that need to be discussed
separately. In case of Exynos hardware it is also related to iommu bindings
and configuration, because each busmuster on the internal memory bus has
separate iommu controller. Having each busmaster defined as a separate node,
enables to put there the associated memory region and/or iommu controller as
well as dma window properties (in case of limited dma window).

However right now I would like to focus on the simple case (1 device,
1 memory region) and define bindings which can be extended later.
I hope that my current proposal covers this (I will send updated binding
documentation asap) and the initial support for reserved memory can be
merged to -next soon.

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

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v6 3/4] drivers: of: add initialization code for dma reserved memory
  2013-08-20 10:57         ` Marek Szyprowski
@ 2013-08-20 16:35           ` Stephen Warren
  2013-08-21 14:38             ` Marek Szyprowski
  2013-08-21 15:39             ` Tomasz Figa
  0 siblings, 2 replies; 23+ messages in thread
From: Stephen Warren @ 2013-08-20 16:35 UTC (permalink / raw)
  To: linux-arm-kernel

On 08/20/2013 04:57 AM, Marek Szyprowski wrote:
> Hello,
> 
> On 8/20/2013 12:17 AM, Stephen Warren wrote:
>> On 08/19/2013 04:02 PM, Tomasz Figa wrote:
>> > Hi Stephen,
>> >
>> > On Monday 19 of August 2013 15:49:20 Stephen Warren wrote:
>> >> On 08/19/2013 09:04 AM, Marek Szyprowski wrote:
>> >>> This patch adds device tree support for contiguous and reserved
>> memory
>> >>> regions defined in device tree.
>> >>>
>> >>> diff --git a/Documentation/devicetree/bindings/memory.txt
>> >>> b/Documentation/devicetree/bindings/memory.txt
>> >>>
>> >>> +*** Reserved memory regions ***
>> >>> +
>> >>> +In /memory/reserved-memory node one can create additional nodes
>> >>
>> >> s/additional/child/ or s/additional/sub/ would make it clearer
>> where the
>> >> "additional" nodes should be placed.
>> >>
>> >>> +compatible:    "linux,contiguous-memory-region" - enables binding
>> > of
>> >>> this
>> >>> +        region to Contiguous Memory Allocator (special region for
>> >>> +        contiguous memory allocations, shared with movable system
>> >>> +        memory, Linux kernel-specific), alternatively if
>> >>> +        "reserved-memory-region" - compatibility is defined, given
>> >>> +        region is assigned for exclusive usage for by the
>> > respective
>> >>> +        devices
>> >>
>> >> "alternatively" makes it sound like the two compatible values are
>> >> mutually-exclusive. Perhaps make this a list, like:
>> >>
>> >> ----------
>> >> compatible: One or more of:
>> >>
>> >>     - "linux,contiguous-memory-region" - enables binding of this
>> >>       region to Contiguous Memory Allocator (special region for
>> >>       contiguous memory allocations, shared with movable system
>> >>       memory, Linux kernel-specific).
>> >>     - "reserved-memory-region" - compatibility is defined, given
>> >>       region is assigned for exclusive usage for by the respective
>> >>       devices.
>> >> ----------
>> >>
>> >> "linux,contiguous-memory-region" is already long enough, but I'd
>> >> slightly bikeshed towards
>> "linux,contiguous-memory-allocator-region", or
>> >> perhaps "linux,cma-region" since it's not really describing whether
>> the
>> >> memory is contiguous (at the level of /memory, each chunk of memory is
>> >> contiguous...)
>> >
>> > I'm not really sure if we need the "linux" prefix for
>> "contiguous-memory-
>> > region". The concept of contiguous memory region is rather OS
>> independent
>> > and tells us that memory allocated from this region will be contiguous.
>> > IMHO any OS is free to implement its own contiguous memory allocation
>> > method, without being limited to Linux CMA.
>> >
>> > Keep in mind that rationale behind those contiguous regions was that
>> there
>> > are devices that require buffers contiguous in memory to operate
>> > correctly.
>> >
>> > But this is just nitpicking and I don't really have any strong
>> opinion on
>> > this.
>> >
>> >>> +*** Device node's properties ***
>> >>> +
>> >>> +Once regions in the /memory/reserved-memory node have been defined,
>> >>> they +can be assigned to device nodes to enable respective device
>> >>> drivers to +access them. The following properties are defined:
>> >>> +
>> >>> +memory-region = <&phandle_to_defined_region>;
>> >>
>> >> I think the naming of that property should more obviously match this
>> >> binding and/or compatible value; perhaps cma-region or
>> >> contiguous-memory-region?
>> >
>> > This property is not CMA-specific. Any memory region can be given using
>> > the memory-region property and used to allocate buffers for particular
>> > device.
>>
>> OK, that makes sense.
>>
>> What I'm looking for is some way to make it obvious that when you see a
>> "memory-region" property in a node, you go look at the "memory.txt"
>> rather than the DT binding for the node where that property appears.
>> Right now, it doesn't seem that obvious to me.
>>
>> I think the real issue here is that my brief reading of memory.txt
>> implies that arbitrary device nodes can include the memory-region
>> property without the node's own binding having to document it; the
>> property name is essentially "forced into" all other bindings.
>>
>> I think instead, memory.txt should say:
>>
>> ----------
>> ** Device node's properties ***
>>
>> Once regions in the /memory/reserved-memory node have been defined, they
>> may be referenced by other device nodes. Bindings that wish to reference
>> memory regions should explicitly document their use of the following
>> property:
>>
>> memory-region = <&phandle_to_defined_region>;
>>
>> This property indicates that the device driver should use the memory
>> region pointed by the given phandle.
>> ----------
>>
>> Also, what if a device needs multiple separate memory regions? Perhaps a
>> GPU is forced to allocate displayable surfaces from addresses 0..32M and
>> textures/off-screen-render-targets from 256M..384M or something whacky
>> like that. In that case, we could either:
>>
>> a) Adjust memory.txt to allow multiple entries in memory-regions, and
>> add an associated memory-region-names property.
>>
>> or:
>>
>> b) Adjust memory.txt not to mention any specific property names, but
>> simply mention that other DT nodes can refer to define memory regions by
>> phandle, and leave it up to individual bindings to define which property
>> they use to reference the memory regions, perhaps with memory.txt
>> providing a recommendation of memory-region for the simple case, but
>> perhaps also allowing a custom case, e.g.:
>>
>> display-memory-region = <&phandl1e1>;
>> texture-memory-region = <&phahndle2>;
> 
> Support for multiple regions is something that need to be discussed
> separately. In case of Exynos hardware it is also related to iommu bindings
> and configuration, because each busmuster on the internal memory bus has
> separate iommu controller. Having each busmaster defined as a separate
> node,
> enables to put there the associated memory region and/or iommu
> controller as
> well as dma window properties (in case of limited dma window).
> 
> However right now I would like to focus on the simple case (1 device,
> 1 memory region) and define bindings which can be extended later.
> I hope that my current proposal covers this (I will send updated binding
> documentation asap) and the initial support for reserved memory can be
> merged to -next soon.

I don't believe that's a good approach unless you have at least a
partial idea of how the current bindings will be extended to support
multiple memory regions.

Without a clear idea how that will eventually work, you run a real risk
of not being able to extend the bindings in a 100% backwards-compatible
way, and hence wishing to break DT ABI.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v6 3/4] drivers: of: add initialization code for dma reserved memory
  2013-08-20 16:35           ` Stephen Warren
@ 2013-08-21 14:38             ` Marek Szyprowski
  2013-08-22 20:08               ` Stephen Warren
  2013-08-21 15:39             ` Tomasz Figa
  1 sibling, 1 reply; 23+ messages in thread
From: Marek Szyprowski @ 2013-08-21 14:38 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

On 8/20/2013 6:35 PM, Stephen Warren wrote:
> On 08/20/2013 04:57 AM, Marek Szyprowski wrote:
> > Hello,
> >
> > On 8/20/2013 12:17 AM, Stephen Warren wrote:
> >> On 08/19/2013 04:02 PM, Tomasz Figa wrote:
> >> > Hi Stephen,
> >> >
> >> > On Monday 19 of August 2013 15:49:20 Stephen Warren wrote:
> >> >> On 08/19/2013 09:04 AM, Marek Szyprowski wrote:
> >> >>> This patch adds device tree support for contiguous and reserved
> >> memory
> >> >>> regions defined in device tree.
> >> >>>
> >> >>> diff --git a/Documentation/devicetree/bindings/memory.txt
> >> >>> b/Documentation/devicetree/bindings/memory.txt
> >> >>>
> >> >>> +*** Reserved memory regions ***
> >> >>> +
> >> >>> +In /memory/reserved-memory node one can create additional nodes
> >> >>
> >> >> s/additional/child/ or s/additional/sub/ would make it clearer
> >> where the
> >> >> "additional" nodes should be placed.
> >> >>
> >> >>> +compatible:    "linux,contiguous-memory-region" - enables binding
> >> > of
> >> >>> this
> >> >>> +        region to Contiguous Memory Allocator (special region for
> >> >>> +        contiguous memory allocations, shared with movable system
> >> >>> +        memory, Linux kernel-specific), alternatively if
> >> >>> +        "reserved-memory-region" - compatibility is defined, given
> >> >>> +        region is assigned for exclusive usage for by the
> >> > respective
> >> >>> +        devices
> >> >>
> >> >> "alternatively" makes it sound like the two compatible values are
> >> >> mutually-exclusive. Perhaps make this a list, like:
> >> >>
> >> >> ----------
> >> >> compatible: One or more of:
> >> >>
> >> >>     - "linux,contiguous-memory-region" - enables binding of this
> >> >>       region to Contiguous Memory Allocator (special region for
> >> >>       contiguous memory allocations, shared with movable system
> >> >>       memory, Linux kernel-specific).
> >> >>     - "reserved-memory-region" - compatibility is defined, given
> >> >>       region is assigned for exclusive usage for by the respective
> >> >>       devices.
> >> >> ----------
> >> >>
> >> >> "linux,contiguous-memory-region" is already long enough, but I'd
> >> >> slightly bikeshed towards
> >> "linux,contiguous-memory-allocator-region", or
> >> >> perhaps "linux,cma-region" since it's not really describing whether
> >> the
> >> >> memory is contiguous (at the level of /memory, each chunk of memory is
> >> >> contiguous...)
> >> >
> >> > I'm not really sure if we need the "linux" prefix for
> >> "contiguous-memory-
> >> > region". The concept of contiguous memory region is rather OS
> >> independent
> >> > and tells us that memory allocated from this region will be contiguous.
> >> > IMHO any OS is free to implement its own contiguous memory allocation
> >> > method, without being limited to Linux CMA.
> >> >
> >> > Keep in mind that rationale behind those contiguous regions was that
> >> there
> >> > are devices that require buffers contiguous in memory to operate
> >> > correctly.
> >> >
> >> > But this is just nitpicking and I don't really have any strong
> >> opinion on
> >> > this.
> >> >
> >> >>> +*** Device node's properties ***
> >> >>> +
> >> >>> +Once regions in the /memory/reserved-memory node have been defined,
> >> >>> they +can be assigned to device nodes to enable respective device
> >> >>> drivers to +access them. The following properties are defined:
> >> >>> +
> >> >>> +memory-region = <&phandle_to_defined_region>;
> >> >>
> >> >> I think the naming of that property should more obviously match this
> >> >> binding and/or compatible value; perhaps cma-region or
> >> >> contiguous-memory-region?
> >> >
> >> > This property is not CMA-specific. Any memory region can be given using
> >> > the memory-region property and used to allocate buffers for particular
> >> > device.
> >>
> >> OK, that makes sense.
> >>
> >> What I'm looking for is some way to make it obvious that when you see a
> >> "memory-region" property in a node, you go look at the "memory.txt"
> >> rather than the DT binding for the node where that property appears.
> >> Right now, it doesn't seem that obvious to me.
> >>
> >> I think the real issue here is that my brief reading of memory.txt
> >> implies that arbitrary device nodes can include the memory-region
> >> property without the node's own binding having to document it; the
> >> property name is essentially "forced into" all other bindings.
> >>
> >> I think instead, memory.txt should say:
> >>
> >> ----------
> >> ** Device node's properties ***
> >>
> >> Once regions in the /memory/reserved-memory node have been defined, they
> >> may be referenced by other device nodes. Bindings that wish to reference
> >> memory regions should explicitly document their use of the following
> >> property:
> >>
> >> memory-region = <&phandle_to_defined_region>;
> >>
> >> This property indicates that the device driver should use the memory
> >> region pointed by the given phandle.
> >> ----------
> >>
> >> Also, what if a device needs multiple separate memory regions? Perhaps a
> >> GPU is forced to allocate displayable surfaces from addresses 0..32M and
> >> textures/off-screen-render-targets from 256M..384M or something whacky
> >> like that. In that case, we could either:
> >>
> >> a) Adjust memory.txt to allow multiple entries in memory-regions, and
> >> add an associated memory-region-names property.
> >>
> >> or:
> >>
> >> b) Adjust memory.txt not to mention any specific property names, but
> >> simply mention that other DT nodes can refer to define memory regions by
> >> phandle, and leave it up to individual bindings to define which property
> >> they use to reference the memory regions, perhaps with memory.txt
> >> providing a recommendation of memory-region for the simple case, but
> >> perhaps also allowing a custom case, e.g.:
> >>
> >> display-memory-region = <&phandl1e1>;
> >> texture-memory-region = <&phahndle2>;
> >
> > Support for multiple regions is something that need to be discussed
> > separately. In case of Exynos hardware it is also related to iommu bindings
> > and configuration, because each busmuster on the internal memory bus has
> > separate iommu controller. Having each busmaster defined as a separate
> > node,
> > enables to put there the associated memory region and/or iommu
> > controller as
> > well as dma window properties (in case of limited dma window).
> >
> > However right now I would like to focus on the simple case (1 device,
> > 1 memory region) and define bindings which can be extended later.
> > I hope that my current proposal covers this (I will send updated binding
> > documentation asap) and the initial support for reserved memory can be
> > merged to -next soon.
>
> I don't believe that's a good approach unless you have at least a
> partial idea of how the current bindings will be extended to support
> multiple memory regions.
>
> Without a clear idea how that will eventually work, you run a real risk
> of not being able to extend the bindings in a 100% backwards-compatible
> way, and hence wishing to break DT ABI.

Both already proposed approaches for extending them to support multiple
memory regions are compatible with the 'single memory region' approach
defined in my patches. Adding additional property with region names is
probably the simplest way from binding perspective, while adding additional
child nodes for each bus master or memory interface gives much more
flexibility in describing hardware properties. Besides memory region, one
can assign iommu controller or dma window properties to each such node.

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

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v6 3/4] drivers: of: add initialization code for dma reserved memory
  2013-08-20 16:35           ` Stephen Warren
  2013-08-21 14:38             ` Marek Szyprowski
@ 2013-08-21 15:39             ` Tomasz Figa
  2013-08-29 21:20               ` Grant Likely
  1 sibling, 1 reply; 23+ messages in thread
From: Tomasz Figa @ 2013-08-21 15:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Tuesday 20 of August 2013 10:35:51 Stephen Warren wrote:
> On 08/20/2013 04:57 AM, Marek Szyprowski wrote:
> > Hello,
> > 
> > On 8/20/2013 12:17 AM, Stephen Warren wrote:
> >> On 08/19/2013 04:02 PM, Tomasz Figa wrote:
> >> > Hi Stephen,
> >> > 
> >> > On Monday 19 of August 2013 15:49:20 Stephen Warren wrote:
> >> >> On 08/19/2013 09:04 AM, Marek Szyprowski wrote:
> >> >>> This patch adds device tree support for contiguous and reserved
> >> 
> >> memory
> >> 
> >> >>> regions defined in device tree.
> >> >>> 
> >> >>> diff --git a/Documentation/devicetree/bindings/memory.txt
> >> >>> b/Documentation/devicetree/bindings/memory.txt
> >> >>> 
> >> >>> +*** Reserved memory regions ***
> >> >>> +
> >> >>> +In /memory/reserved-memory node one can create additional nodes
> >> >> 
> >> >> s/additional/child/ or s/additional/sub/ would make it clearer
> >> 
> >> where the
> >> 
> >> >> "additional" nodes should be placed.
> >> >> 
> >> >>> +compatible:    "linux,contiguous-memory-region" - enables binding
> >> > 
> >> > of
> >> > 
> >> >>> this
> >> >>> +        region to Contiguous Memory Allocator (special region for
> >> >>> +        contiguous memory allocations, shared with movable system
> >> >>> +        memory, Linux kernel-specific), alternatively if
> >> >>> +        "reserved-memory-region" - compatibility is defined,
> >> >>> given
> >> >>> +        region is assigned for exclusive usage for by the
> >> > 
> >> > respective
> >> > 
> >> >>> +        devices
> >> >> 
> >> >> "alternatively" makes it sound like the two compatible values are
> >> >> mutually-exclusive. Perhaps make this a list, like:
> >> >> 
> >> >> ----------
> >> >> 
> >> >> compatible: One or more of:
> >> >>     - "linux,contiguous-memory-region" - enables binding of this
> >> >>     
> >> >>       region to Contiguous Memory Allocator (special region for
> >> >>       contiguous memory allocations, shared with movable system
> >> >>       memory, Linux kernel-specific).
> >> >>     
> >> >>     - "reserved-memory-region" - compatibility is defined, given
> >> >>     
> >> >>       region is assigned for exclusive usage for by the respective
> >> >>       devices.
> >> >> 
> >> >> ----------
> >> >> 
> >> >> "linux,contiguous-memory-region" is already long enough, but I'd
> >> >> slightly bikeshed towards
> >> 
> >> "linux,contiguous-memory-allocator-region", or
> >> 
> >> >> perhaps "linux,cma-region" since it's not really describing whether
> >> 
> >> the
> >> 
> >> >> memory is contiguous (at the level of /memory, each chunk of memory
> >> >> is
> >> >> contiguous...)
> >> > 
> >> > I'm not really sure if we need the "linux" prefix for
> >> 
> >> "contiguous-memory-
> >> 
> >> > region". The concept of contiguous memory region is rather OS
> >> 
> >> independent
> >> 
> >> > and tells us that memory allocated from this region will be
> >> > contiguous.
> >> > IMHO any OS is free to implement its own contiguous memory
> >> > allocation
> >> > method, without being limited to Linux CMA.
> >> > 
> >> > Keep in mind that rationale behind those contiguous regions was that
> >> 
> >> there
> >> 
> >> > are devices that require buffers contiguous in memory to operate
> >> > correctly.
> >> > 
> >> > But this is just nitpicking and I don't really have any strong
> >> 
> >> opinion on
> >> 
> >> > this.
> >> > 
> >> >>> +*** Device node's properties ***
> >> >>> +
> >> >>> +Once regions in the /memory/reserved-memory node have been
> >> >>> defined,
> >> >>> they +can be assigned to device nodes to enable respective device
> >> >>> drivers to +access them. The following properties are defined:
> >> >>> +
> >> >>> +memory-region = <&phandle_to_defined_region>;
> >> >> 
> >> >> I think the naming of that property should more obviously match
> >> >> this
> >> >> binding and/or compatible value; perhaps cma-region or
> >> >> contiguous-memory-region?
> >> > 
> >> > This property is not CMA-specific. Any memory region can be given
> >> > using
> >> > the memory-region property and used to allocate buffers for
> >> > particular
> >> > device.
> >> 
> >> OK, that makes sense.
> >> 
> >> What I'm looking for is some way to make it obvious that when you see
> >> a
> >> "memory-region" property in a node, you go look at the "memory.txt"
> >> rather than the DT binding for the node where that property appears.
> >> Right now, it doesn't seem that obvious to me.
> >> 
> >> I think the real issue here is that my brief reading of memory.txt
> >> implies that arbitrary device nodes can include the memory-region
> >> property without the node's own binding having to document it; the
> >> property name is essentially "forced into" all other bindings.
> >> 
> >> I think instead, memory.txt should say:
> >> 
> >> ----------
> >> ** Device node's properties ***
> >> 
> >> Once regions in the /memory/reserved-memory node have been defined,
> >> they
> >> may be referenced by other device nodes. Bindings that wish to
> >> reference
> >> memory regions should explicitly document their use of the following
> >> property:
> >> 
> >> memory-region = <&phandle_to_defined_region>;
> >> 
> >> This property indicates that the device driver should use the memory
> >> region pointed by the given phandle.
> >> ----------
> >> 
> >> Also, what if a device needs multiple separate memory regions? Perhaps
> >> a
> >> GPU is forced to allocate displayable surfaces from addresses 0..32M
> >> and
> >> textures/off-screen-render-targets from 256M..384M or something whacky
> >> like that. In that case, we could either:
> >> 
> >> a) Adjust memory.txt to allow multiple entries in memory-regions, and
> >> add an associated memory-region-names property.
> >> 
> >> or:
> >> 
> >> b) Adjust memory.txt not to mention any specific property names, but
> >> simply mention that other DT nodes can refer to define memory regions
> >> by
> >> phandle, and leave it up to individual bindings to define which
> >> property
> >> they use to reference the memory regions, perhaps with memory.txt
> >> providing a recommendation of memory-region for the simple case, but
> >> perhaps also allowing a custom case, e.g.:
> >> 
> >> display-memory-region = <&phandl1e1>;
> >> texture-memory-region = <&phahndle2>;
> > 
> > Support for multiple regions is something that need to be discussed
> > separately. In case of Exynos hardware it is also related to iommu
> > bindings and configuration, because each busmuster on the internal
> > memory bus has separate iommu controller. Having each busmaster
> > defined as a separate node,
> > enables to put there the associated memory region and/or iommu
> > controller as
> > well as dma window properties (in case of limited dma window).
> > 
> > However right now I would like to focus on the simple case (1 device,
> > 1 memory region) and define bindings which can be extended later.
> > I hope that my current proposal covers this (I will send updated
> > binding
> > documentation asap) and the initial support for reserved memory can be
> > merged to -next soon.
> 
> I don't believe that's a good approach unless you have at least a
> partial idea of how the current bindings will be extended to support
> multiple memory regions.

I believe that at least three "at least partial" ideas have been brought in 
this thread. Moreover, I don't think that defining the simple binding now 
would stop us from extending it according to any of those ideas in any way.

> Without a clear idea how that will eventually work, you run a real risk
> of not being able to extend the bindings in a 100% backwards-compatible
> way, and hence wishing to break DT ABI.

As a fallback you can always define a new binding, while keeping support 
for old one. Of course this is the last resort, but it is not that simple 
to find a case that couldn't be supported without breaking the ABI.

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v6 3/4] drivers: of: add initialization code for dma reserved memory
  2013-08-19 15:04 ` [PATCH v6 3/4] drivers: of: add initialization code for dma reserved memory Marek Szyprowski
  2013-08-19 21:49   ` Stephen Warren
@ 2013-08-21 15:56   ` Matt Sealey
       [not found]   ` <1377247141-11284-1-git-send-email-m.szyprowski@samsung.com>
  2013-08-26 12:20   ` [PATCH v6 3/4] " Rob Herring
  3 siblings, 0 replies; 23+ messages in thread
From: Matt Sealey @ 2013-08-21 15:56 UTC (permalink / raw)
  To: linux-arm-kernel

I have a suggestion here.

I recall that CHRP had a reserved node definition which essentially,
since it was not a lot more than a definition of the bare minimum node
that can describe a memory region, acted as a way to carve out
peripheral addresses. In this case, the device_type would be
"reserved" and a property to mark it as for the Linux contiguous
memory allocator would be prudent here. This way nothing new is being
defined except the property. In the case you want default regions and
supplemental regions, give the linux,contiguous-memory-region property
a value. In the case of the reserved node, the name could be "default"
though and CMA could special-case this.

It doesn't even need to be called reserved-memory or be a child node
of it's own, then, but I also guess this would mean duplicating
#address-cells and #size-cells in every node (that said.. isn't there
a case for a 32-bit system having a >32-bit memory map somewhere that
the kernel somehow needs to know about? On PowerPC I've seen 8GB
hooked up to it on CPUs that didn't have 36-bit addressing, and
therefore could not do anything with that amount of memory. But the
DMA controllers in this case were designed around 36-bit addressing
and could easily access the upper 4GB.. it would have come in handy
for a kind of DMA-assisted buffering whereby you wanted to put all
your network or "graphics" stuff in a safe place and copy it in and
out as needed, or even as 4GB of magical swap space driven by a custom
DMA driver)

The naming of nodes is not really "important" in device-tree, in this
case it might make sense in the same way the regulator guys specify
regulators. In any case where the "default" name does not exist, then
the first parsed becomes the default, but this does mean we'd be kind
of restricting the namespace for everyone based on a Linux kernel
behavior..

If you can search for the device_type = "memory" node you can also
search for all nodes matching device_type = "reserved" under the
memory node, with the appropriate property in place to bundle them up
for adding to CMA, and just carve it out. In fact, this would work
without needing to be in the /memory node at all. Hooray for
device_type, long live device_type? :D

-- Matt

On Mon, Aug 19, 2013 at 10:04 AM, Marek Szyprowski
<m.szyprowski@samsung.com> wrote:
> This patch adds device tree support for contiguous and reserved memory
> regions defined in device tree.
>
> Large memory blocks can be reliably reserved only during early boot.
> This must happen before the whole memory management subsystem is
> initialized, because we need to ensure that the given contiguous blocks
> are not yet allocated by kernel. Also it must happen before kernel
> mappings for the whole low memory are created, to ensure that there will
> be no mappings (for reserved blocks) or mapping with special properties
> can be created (for CMA blocks). This all happens before device tree
> structures are unflattened, so we need to get reserved memory layout
> directly from fdt.
>
> Later, those reserved memory regions are assigned to devices on each
> device structure initialization.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
> Acked-by: Michal Nazarewicz <mina86@mina86.com>
> Acked-by: Tomasz Figa <t.figa@samsung.com>
> ---
>  Documentation/devicetree/bindings/memory.txt |  166 ++++++++++++++++++++++++
>  drivers/of/Kconfig                           |    6 +
>  drivers/of/Makefile                          |    1 +
>  drivers/of/of_reserved_mem.c                 |  175 ++++++++++++++++++++++++++
>  drivers/of/platform.c                        |    5 +
>  include/linux/of_reserved_mem.h              |   14 +++
>  6 files changed, 367 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/memory.txt
>  create mode 100644 drivers/of/of_reserved_mem.c
>  create mode 100644 include/linux/of_reserved_mem.h
>
> diff --git a/Documentation/devicetree/bindings/memory.txt b/Documentation/devicetree/bindings/memory.txt
> new file mode 100644
> index 0000000..90e96278
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/memory.txt
> @@ -0,0 +1,166 @@
> +*** Memory binding ***
> +
> +The /memory node provides basic information about the address and size
> +of the physical memory. This node is usually filled or updated by the
> +bootloader, depending on the actual memory configuration of the given
> +hardware.
> +
> +The memory layout is described by the following node:
> +
> +/ {
> +       #address-cells = <(n)>;
> +       #size-cells = <(m)>;
> +       memory {
> +               device_type = "memory";
> +               reg =  <(baseaddr1) (size1)
> +                       (baseaddr2) (size2)
> +                       ...
> +                       (baseaddrN) (sizeN)>;
> +       };
> +       ...
> +};
> +
> +A memory node follows the typical device tree rules for "reg" property:
> +n:             number of cells used to store base address value
> +m:             number of cells used to store size value
> +baseaddrX:     defines a base address of the defined memory bank
> +sizeX:         the size of the defined memory bank
> +
> +
> +More than one memory bank can be defined.
> +
> +
> +*** Reserved memory regions ***
> +
> +In /memory/reserved-memory node one can create additional nodes
> +describing particular reserved (excluded from normal use) memory
> +regions. Such memory regions are usually designed for the special usage
> +by various device drivers. A good example are contiguous memory
> +allocations or memory sharing with other operating system on the same
> +hardware board. Those special memory regions might depend on the board
> +configuration and devices used on the target system.
> +
> +Parameters for each memory region can be encoded into the device tree
> +with the following convention:
> +
> +[(label):] (name) {
> +       compatible = "linux,contiguous-memory-region", "reserved-memory-region";
> +       reg = <(address) (size)>;
> +       (linux,default-contiguous-region);
> +};
> +
> +compatible:    "linux,contiguous-memory-region" - enables binding of this
> +               region to Contiguous Memory Allocator (special region for
> +               contiguous memory allocations, shared with movable system
> +               memory, Linux kernel-specific), alternatively if
> +               "reserved-memory-region" - compatibility is defined, given
> +               region is assigned for exclusive usage for by the respective
> +               devices
> +
> +reg:           standard property defining the base address and size of
> +               the memory region
> +
> +linux,default-contiguous-region: property indicating that the region
> +               is the default region for all contiguous memory
> +               allocations, Linux specific (optional)
> +
> +It is optional to specify the base address, so if one wants to use
> +autoconfiguration of the base address, '0' can be specified as a base
> +address in the 'reg' property.
> +
> +The /memory/reserved-memory node must contain the same #address-cells
> +and #size-cells value as the root node.
> +
> +
> +*** Device node's properties ***
> +
> +Once regions in the /memory/reserved-memory node have been defined, they
> +can be assigned to device nodes to enable respective device drivers to
> +access them. The following properties are defined:
> +
> +memory-region = <&phandle_to_defined_region>;
> +
> +This property indicates that the device driver should use the memory
> +region pointed by the given phandle.
> +
> +
> +*** Example ***
> +
> +This example defines a memory consisting of 4 memory banks. 3 contiguous
> +regions are defined for Linux kernel, one default of all device drivers
> +(named contig_mem, placed at 0x72000000, 64MiB), one dedicated to the
> +framebuffer device (labelled display_mem, placed at 0x78000000, 8MiB)
> +and one for multimedia processing (labelled multimedia_mem, placed at
> +0x77000000, 64MiB). 'display_mem' region is then assigned to fb at 12300000
> +device for DMA memory allocations (Linux kernel drivers will use CMA is
> +available or dma-exclusive usage otherwise). 'multimedia_mem' is
> +assigned to scaler at 12500000 and codec at 12600000 devices for contiguous
> +memory allocations when CMA driver is enabled.
> +
> +The reason for creating a separate region for framebuffer device is to
> +match the framebuffer base address to the one configured by bootloader,
> +so once Linux kernel drivers starts no glitches on the displayed boot
> +logo appears. Scaller and codec drivers should share the memory
> +allocations.
> +
> +/ {
> +       #address-cells = <1>;
> +       #size-cells = <1>;
> +
> +       /* ... */
> +
> +       memory {
> +               reg =  <0x40000000 0x10000000
> +                       0x50000000 0x10000000
> +                       0x60000000 0x10000000
> +                       0x70000000 0x10000000>;
> +
> +               reserved-memory {
> +                       #address-cells = <1>;
> +                       #size-cells = <1>;
> +
> +                       /*
> +                        * global autoconfigured region for contiguous allocations
> +                        * (used only with Contiguous Memory Allocator)
> +                        */
> +                       contig_region at 0 {
> +                               compatible = "linux,contiguous-memory-region";
> +                               reg = <0x0 0x4000000>;
> +                               linux,default-contiguous-region;
> +                       };
> +
> +                       /*
> +                        * special region for framebuffer
> +                        */
> +                       display_mem: region at 78000000 {
> +                               compatible = "linux,contiguous-memory-region", "reserved-memory-region";
> +                               reg = <0x78000000 0x800000>;
> +                       };
> +
> +                       /*
> +                        * special region for multimedia processing devices
> +                        */
> +                       multimedia_mem: region at 77000000 {
> +                               compatible = "linux,contiguous-memory-region";
> +                               reg = <0x77000000 0x4000000>;
> +                       };
> +               };
> +       };
> +
> +       /* ... */
> +
> +       fb0: fb at 12300000 {
> +               status = "okay";
> +               memory-region = <&display_mem>;
> +       };
> +
> +       scaler: scaler at 12500000 {
> +               status = "okay";
> +               memory-region = <&multimedia_mem>;
> +       };
> +
> +       codec: codec at 12600000 {
> +               status = "okay";
> +               memory-region = <&multimedia_mem>;
> +       };
> +};
> diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
> index 80e5c13..a83ab43 100644
> --- a/drivers/of/Kconfig
> +++ b/drivers/of/Kconfig
> @@ -80,4 +80,10 @@ config OF_MTD
>         depends on MTD
>         def_bool y
>
> +config OF_RESERVED_MEM
> +       depends on CMA || (HAVE_GENERIC_DMA_COHERENT && HAVE_MEMBLOCK)
> +       def_bool y
> +       help
> +         Initialization code for DMA reserved memory
> +
>  endmenu # OF
> diff --git a/drivers/of/Makefile b/drivers/of/Makefile
> index 1f9c0c4..e7e3322 100644
> --- a/drivers/of/Makefile
> +++ b/drivers/of/Makefile
> @@ -10,3 +10,4 @@ obj-$(CONFIG_OF_MDIO) += of_mdio.o
>  obj-$(CONFIG_OF_PCI)   += of_pci.o
>  obj-$(CONFIG_OF_PCI_IRQ)  += of_pci_irq.o
>  obj-$(CONFIG_OF_MTD)   += of_mtd.o
> +obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
> diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
> new file mode 100644
> index 0000000..95563d33
> --- /dev/null
> +++ b/drivers/of/of_reserved_mem.c
> @@ -0,0 +1,175 @@
> +/*
> + * Device tree based initialization code for reserved memory.
> + *
> + * Copyright (c) 2013 Samsung Electronics Co., Ltd.
> + *             http://www.samsung.com
> + * Author: Marek Szyprowski <m.szyprowski@samsung.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of the
> + * License or (at your optional) any later version of the license.
> + */
> +
> +#include <asm/dma-contiguous.h>
> +
> +#include <linux/memblock.h>
> +#include <linux/err.h>
> +#include <linux/of.h>
> +#include <linux/of_fdt.h>
> +#include <linux/of_platform.h>
> +#include <linux/mm.h>
> +#include <linux/sizes.h>
> +#include <linux/mm_types.h>
> +#include <linux/dma-contiguous.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/of_reserved_mem.h>
> +
> +#define MAX_RESERVED_REGIONS   16
> +struct reserved_mem {
> +       phys_addr_t             base;
> +       unsigned long           size;
> +       struct cma              *cma;
> +       char                    name[32];
> +};
> +static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
> +static int reserved_mem_count;
> +
> +static int __init fdt_scan_reserved_mem(unsigned long node, const char *uname,
> +                                       int depth, void *data)
> +{
> +       struct reserved_mem *rmem = &reserved_mem[reserved_mem_count];
> +       phys_addr_t base, size;
> +       int is_cma, is_reserved;
> +       unsigned long len;
> +       const char *status;
> +       __be32 *prop;
> +
> +       is_cma = IS_ENABLED(CONFIG_CMA) &&
> +              of_flat_dt_is_compatible(node, "linux,contiguous-memory-region");
> +       is_reserved = of_flat_dt_is_compatible(node, "reserved-memory-region");
> +
> +       if (!is_reserved && !is_cma) {
> +               /* ignore node and scan next one */
> +               return 0;
> +       }
> +
> +       status = of_get_flat_dt_prop(node, "status", &len);
> +       if (status && strcmp(status, "okay") != 0) {
> +               /* ignore disabled node nad scan next one */
> +               return 0;
> +       }
> +
> +       prop = of_get_flat_dt_prop(node, "reg", &len);
> +       if (!prop || (len < (dt_root_size_cells + dt_root_addr_cells) *
> +                            sizeof(__be32))) {
> +               pr_err("Reserved mem: node %s, incorrect \"reg\" property\n",
> +                      uname);
> +               /* ignore node and scan next one */
> +               return 0;
> +       }
> +       base = dt_mem_next_cell(dt_root_addr_cells, &prop);
> +       size = dt_mem_next_cell(dt_root_size_cells, &prop);
> +
> +       if (!size) {
> +               /* ignore node and scan next one */
> +               return 0;
> +       }
> +
> +       pr_info("Reserved mem: found %s, memory base %lx, size %ld MiB\n",
> +               uname, (unsigned long)base, (unsigned long)size / SZ_1M);
> +
> +       if (reserved_mem_count == ARRAY_SIZE(reserved_mem))
> +               return -ENOSPC;
> +
> +       rmem->base = base;
> +       rmem->size = size;
> +       strlcpy(rmem->name, uname, sizeof(rmem->name));
> +
> +       if (is_cma) {
> +               struct cma *cma;
> +               if (dma_contiguous_reserve_area(size, base, 0, &cma) == 0) {
> +                       rmem->cma = cma;
> +                       reserved_mem_count++;
> +                       if (of_get_flat_dt_prop(node,
> +                                               "linux,default-contiguous-region",
> +                                               NULL))
> +                               dma_contiguous_default_area = cma;
> +               }
> +       } else if (is_reserved) {
> +               if (memblock_remove(base, size) == 0)
> +                       reserved_mem_count++;
> +               else
> +                       pr_err("Failed to reserve memory for %s\n", uname);
> +       }
> +
> +       return 0;
> +}
> +
> +static struct reserved_mem *get_dma_memory_region(struct device *dev)
> +{
> +       struct device_node *node;
> +       const char *name;
> +       int i;
> +
> +       node = of_parse_phandle(dev->of_node, "memory-region", 0);
> +       if (!node)
> +               return NULL;
> +
> +       name = kbasename(node->full_name);
> +       for (i = 0; i < reserved_mem_count; i++)
> +               if (strcmp(name, reserved_mem[i].name) == 0)
> +                       return &reserved_mem[i];
> +       return NULL;
> +}
> +
> +/**
> + * of_reserved_mem_device_init() - assign reserved memory region to given device
> + *
> + * This function assign memory region pointed by "memory-region" device tree
> + * property to the given device.
> + */
> +void of_reserved_mem_device_init(struct device *dev)
> +{
> +       struct reserved_mem *region = get_dma_memory_region(dev);
> +       if (!region)
> +               return;
> +
> +       if (region->cma) {
> +               dev_set_cma_area(dev, region->cma);
> +               pr_info("Assigned CMA %s to %s device\n", region->name,
> +                       dev_name(dev));
> +       } else {
> +               if (dma_declare_coherent_memory(dev, region->base, region->base,
> +                   region->size, DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) != 0)
> +                       pr_info("Declared reserved memory %s to %s device\n",
> +                               region->name, dev_name(dev));
> +       }
> +}
> +
> +/**
> + * of_reserved_mem_device_release() - release reserved memory device structures
> + *
> + * This function releases structures allocated for memory region handling for
> + * the given device.
> + */
> +void of_reserved_mem_device_release(struct device *dev)
> +{
> +       struct reserved_mem *region = get_dma_memory_region(dev);
> +       if (!region && !region->cma)
> +               dma_release_declared_memory(dev);
> +}
> +
> +/**
> + * early_init_dt_scan_reserved_mem() - create reserved memory regions
> + *
> + * This function grabs memory from early allocator for device exclusive use
> + * defined in device tree structures. It should be called by arch specific code
> + * once the early allocator (memblock) has been activated and all other
> + * subsystems have already allocated/reserved memory.
> + */
> +void __init early_init_dt_scan_reserved_mem(void)
> +{
> +       of_scan_flat_dt_by_path("/memory/reserved-memory",
> +                               fdt_scan_reserved_mem, NULL);
> +}
> diff --git a/drivers/of/platform.c b/drivers/of/platform.c
> index e0a6514..1e4e91d 100644
> --- a/drivers/of/platform.c
> +++ b/drivers/of/platform.c
> @@ -21,6 +21,7 @@
>  #include <linux/of_device.h>
>  #include <linux/of_irq.h>
>  #include <linux/of_platform.h>
> +#include <linux/of_reserved_mem.h>
>  #include <linux/platform_device.h>
>
>  const struct of_device_id of_default_bus_match_table[] = {
> @@ -196,6 +197,7 @@ EXPORT_SYMBOL(of_device_alloc);
>   * Returns pointer to created platform device, or NULL if a device was not
>   * registered.  Unavailable devices will not get registered.
>   */
> +
>  struct platform_device *of_platform_device_create_pdata(
>                                         struct device_node *np,
>                                         const char *bus_id,
> @@ -218,6 +220,8 @@ struct platform_device *of_platform_device_create_pdata(
>         dev->dev.bus = &platform_bus_type;
>         dev->dev.platform_data = platform_data;
>
> +       of_reserved_mem_device_init(&dev->dev);
> +
>         /* We do not fill the DMA ops for platform devices by default.
>          * This is currently the responsibility of the platform code
>          * to do such, possibly using a device notifier
> @@ -225,6 +229,7 @@ struct platform_device *of_platform_device_create_pdata(
>
>         if (of_device_add(dev) != 0) {
>                 platform_device_put(dev);
> +               of_reserved_mem_device_release(&dev->dev);
>                 return NULL;
>         }
>
> diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
> new file mode 100644
> index 0000000..c841282
> --- /dev/null
> +++ b/include/linux/of_reserved_mem.h
> @@ -0,0 +1,14 @@
> +#ifndef __OF_RESERVED_MEM_H
> +#define __OF_RESERVED_MEM_H
> +
> +#ifdef CONFIG_OF_RESERVED_MEM
> +void of_reserved_mem_device_init(struct device *dev);
> +void of_reserved_mem_device_release(struct device *dev);
> +void early_init_dt_scan_reserved_mem(void);
> +#else
> +static inline void of_reserved_mem_device_init(struct device *dev) { }
> +static inline void of_reserved_mem_device_release(struct device *dev) { }
> +static inline void early_init_dt_scan_reserved_mem(void) { }
> +#endif
> +
> +#endif /* __OF_RESERVED_MEM_H */
> --
> 1.7.9.5
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v6 3/4] drivers: of: add initialization code for dma reserved memory
  2013-08-21 14:38             ` Marek Szyprowski
@ 2013-08-22 20:08               ` Stephen Warren
  0 siblings, 0 replies; 23+ messages in thread
From: Stephen Warren @ 2013-08-22 20:08 UTC (permalink / raw)
  To: linux-arm-kernel

On 08/21/2013 08:38 AM, Marek Szyprowski wrote:
...
>> >> b) Adjust memory.txt not to mention any specific property names, but
>> >> simply mention that other DT nodes can refer to define memory regions by
>> >> phandle, and leave it up to individual bindings to define which property
>> >> they use to reference the memory regions, perhaps with memory.txt
>> >> providing a recommendation of memory-region for the simple case

I think if we just make that change to the binding doc, it'll be fine.
It's obvious how to extend the binding then.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v6 3/4 UPDATED] drivers: of: add initialization code for dma reserved memory
       [not found]   ` <1377247141-11284-1-git-send-email-m.szyprowski@samsung.com>
@ 2013-08-23 19:27     ` Stephen Warren
  0 siblings, 0 replies; 23+ messages in thread
From: Stephen Warren @ 2013-08-23 19:27 UTC (permalink / raw)
  To: linux-arm-kernel

On 08/23/2013 02:39 AM,  wrote:
> From: Marek Szyprowski <m.szyprowski@samsung.com>
> 
> This patch adds device tree support for contiguous and reserved memory
> regions defined in device tree.
> 
> Large memory blocks can be reliably reserved only during early boot.
> This must happen before the whole memory management subsystem is
> initialized, because we need to ensure that the given contiguous blocks
> are not yet allocated by kernel. Also it must happen before kernel
> mappings for the whole low memory are created, to ensure that there will
> be no mappings (for reserved blocks) or mapping with special properties
> can be created (for CMA blocks). This all happens before device tree
> structures are unflattened, so we need to get reserved memory layout
> directly from fdt.
> 
> Later, those reserved memory regions are assigned to devices on each
> device structure initialization.

I think the binding looks OK now; just a couple minor comments below.

> diff --git a/Documentation/devicetree/bindings/memory.txt b/Documentation/devicetree/bindings/memory.txt

> +*** Reserved memory regions ***

> +compatible:	one or more of:
> +	- "linux,contiguous-memory-region" - enables binding of this
> +	  region to Contiguous Memory Allocator (special region for
> +	  contiguous memory allocations, shared with movable system
> +	  memory, Linux kernel-specific).
> +	- "reserved-memory-region" - compatibility is defined, given
> +	  region is assigned for exclusive usage for by the respective
> +	  devices.

I'm slightly hesitant to agree with "linux" in the name here, since it
seems like the concept of a memory region where DMA buffers/... should
be allocated is pretty OS-independant. Similar for:

> +linux,default-contiguous-region: property indicating that the region
> +	is the default region for all contiguous memory
> +	allocations, Linux specific (optional)

But, I guess there's nothing stopping any other OS from parsing this
same property, so I suppose it's OK. What do other DT maintainers think?

> +*** Example ***

> +		reserved-memory {
...
> +			contig_region at 0 {
...
> +			display_mem: region at 78000000 {
...
> +			multimedia_mem: region at 77000000 {

Nit: I think all 3 of those nodes should be called region, but it's
probably fine as-is.

So, the binding,
Acked-by: Stephen Warren <swarren@nvidia.com>

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v6 2/4] drivers: of: add function to scan fdt nodes given by path
  2013-08-19 15:04 ` [PATCH v6 2/4] drivers: of: add function to scan fdt nodes given by path Marek Szyprowski
@ 2013-08-26 12:09   ` Rob Herring
  0 siblings, 0 replies; 23+ messages in thread
From: Rob Herring @ 2013-08-26 12:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 19, 2013 at 10:04 AM, Marek Szyprowski
<m.szyprowski@samsung.com> wrote:
> Add a function to scan the flattened device-tree starting from the
> node given by the path. It is used to extract information (like reserved
> memory), which is required on early boot before we can unflatten the tree.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> Acked-by: Michal Nazarewicz <mina86@mina86.com>
> Acked-by: Tomasz Figa <t.figa@samsung.com>

Reviewed-by: Rob Herring <rob.herring@calxeda.com>

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v6 3/4] drivers: of: add initialization code for dma reserved memory
  2013-08-19 15:04 ` [PATCH v6 3/4] drivers: of: add initialization code for dma reserved memory Marek Szyprowski
                     ` (2 preceding siblings ...)
       [not found]   ` <1377247141-11284-1-git-send-email-m.szyprowski@samsung.com>
@ 2013-08-26 12:20   ` Rob Herring
  3 siblings, 0 replies; 23+ messages in thread
From: Rob Herring @ 2013-08-26 12:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Aug 19, 2013 at 10:04 AM, Marek Szyprowski
<m.szyprowski@samsung.com> wrote:
> This patch adds device tree support for contiguous and reserved memory
> regions defined in device tree.
>
> Large memory blocks can be reliably reserved only during early boot.
> This must happen before the whole memory management subsystem is
> initialized, because we need to ensure that the given contiguous blocks
> are not yet allocated by kernel. Also it must happen before kernel
> mappings for the whole low memory are created, to ensure that there will
> be no mappings (for reserved blocks) or mapping with special properties
> can be created (for CMA blocks). This all happens before device tree
> structures are unflattened, so we need to get reserved memory layout
> directly from fdt.
>
> Later, those reserved memory regions are assigned to devices on each
> device structure initialization.
>
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> Acked-by: Kyungmin Park <kyungmin.park@samsung.com>
> Acked-by: Michal Nazarewicz <mina86@mina86.com>
> Acked-by: Tomasz Figa <t.figa@samsung.com>

Reviewed-by: Rob Herring <rob.herring@calxeda.com>

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v6 3/4] drivers: of: add initialization code for dma reserved memory
  2013-08-19 22:02     ` Tomasz Figa
  2013-08-19 22:17       ` Stephen Warren
@ 2013-08-29 21:12       ` Grant Likely
  1 sibling, 0 replies; 23+ messages in thread
From: Grant Likely @ 2013-08-29 21:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, 20 Aug 2013 00:02:37 +0200, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> Hi Stephen,
> 
> On Monday 19 of August 2013 15:49:20 Stephen Warren wrote:
> > On 08/19/2013 09:04 AM, Marek Szyprowski wrote:
> > > This patch adds device tree support for contiguous and reserved memory
> > > regions defined in device tree.
> > > 
> > > diff --git a/Documentation/devicetree/bindings/memory.txt
> > > b/Documentation/devicetree/bindings/memory.txt
> > > 
> > > +*** Reserved memory regions ***
> > > +
> > > +In /memory/reserved-memory node one can create additional nodes
> > 
> > s/additional/child/ or s/additional/sub/ would make it clearer where the
> > "additional" nodes should be placed.
> > 
> > > +compatible:	"linux,contiguous-memory-region" - enables binding 
> of
> > > this
> > > +		region to Contiguous Memory Allocator (special region for
> > > +		contiguous memory allocations, shared with movable system
> > > +		memory, Linux kernel-specific), alternatively if
> > > +		"reserved-memory-region" - compatibility is defined, given
> > > +		region is assigned for exclusive usage for by the 
> respective
> > > +		devices
> > 
> > "alternatively" makes it sound like the two compatible values are
> > mutually-exclusive. Perhaps make this a list, like:
> > 
> > ----------
> > compatible: One or more of:
> > 
> > 	- "linux,contiguous-memory-region" - enables binding of this
> > 	  region to Contiguous Memory Allocator (special region for
> > 	  contiguous memory allocations, shared with movable system
> > 	  memory, Linux kernel-specific).
> > 	- "reserved-memory-region" - compatibility is defined, given
> > 	  region is assigned for exclusive usage for by the respective
> > 	  devices.
> > ----------
> > 
> > "linux,contiguous-memory-region" is already long enough, but I'd
> > slightly bikeshed towards "linux,contiguous-memory-allocator-region", or
> > perhaps "linux,cma-region" since it's not really describing whether the
> > memory is contiguous (at the level of /memory, each chunk of memory is
> > contiguous...)
> 
> I'm not really sure if we need the "linux" prefix for "contiguous-memory-
> region". The concept of contiguous memory region is rather OS independent 
> and tells us that memory allocated from this region will be contiguous. 
> IMHO any OS is free to implement its own contiguous memory allocation 
> method, without being limited to Linux CMA.
> 
> Keep in mind that rationale behind those contiguous regions was that there 
> are devices that require buffers contiguous in memory to operate 
> correctly.
> 
> But this is just nitpicking and I don't really have any strong opinion on 
> this.

Actually, I think this is important. It is something that describes the
expected usage of the hardware (flicker-free framebuffer is a really
good example) and isn't really linux-specific from that perspective.
I think you can drop the 'linux,' prefix string.

g.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v6 3/4] drivers: of: add initialization code for dma reserved memory
  2013-08-21 15:39             ` Tomasz Figa
@ 2013-08-29 21:20               ` Grant Likely
  0 siblings, 0 replies; 23+ messages in thread
From: Grant Likely @ 2013-08-29 21:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, 21 Aug 2013 17:39:48 +0200, Tomasz Figa <t.figa@samsung.com> wrote:
> On Tuesday 20 of August 2013 10:35:51 Stephen Warren wrote:
> > >> a) Adjust memory.txt to allow multiple entries in memory-regions, and
> > >> add an associated memory-region-names property.
> > >> 
> > I don't believe that's a good approach unless you have at least a
> > partial idea of how the current bindings will be extended to support
> > multiple memory regions.
> 
> I believe that at least three "at least partial" ideas have been brought in 
> this thread. Moreover, I don't think that defining the simple binding now 
> would stop us from extending it according to any of those ideas in any way.

I would plan on extending later with suggestion 'a)' above. Making the
memory-region an array of phandles is a better match with how most of
the core bindings work.  I actually regret the *-gpio properties that
were defined earlier becasue it makes it harder for software to look at
a tree and determine if there are any gpio references.

It of course doesn't need to be done immediately, only when it becomes
required.

g.

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2013-08-29 21:20 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-19 15:04 [PATCH v6 0/4] Device Tree support for CMA (Contiguous Memory Allocator) Marek Szyprowski
2013-08-19 15:04 ` [PATCH v6 1/4] drivers: dma-contiguous: clean source code and prepare for device tree Marek Szyprowski
2013-08-19 15:04 ` [PATCH v6 2/4] drivers: of: add function to scan fdt nodes given by path Marek Szyprowski
2013-08-26 12:09   ` Rob Herring
2013-08-19 15:04 ` [PATCH v6 3/4] drivers: of: add initialization code for dma reserved memory Marek Szyprowski
2013-08-19 21:49   ` Stephen Warren
2013-08-19 22:02     ` Tomasz Figa
2013-08-19 22:17       ` Stephen Warren
2013-08-19 22:24         ` Tomasz Figa
2013-08-19 22:27           ` Stephen Warren
2013-08-19 22:40             ` Tomasz Figa
2013-08-19 22:54               ` Stephen Warren
2013-08-20 10:57         ` Marek Szyprowski
2013-08-20 16:35           ` Stephen Warren
2013-08-21 14:38             ` Marek Szyprowski
2013-08-22 20:08               ` Stephen Warren
2013-08-21 15:39             ` Tomasz Figa
2013-08-29 21:20               ` Grant Likely
2013-08-29 21:12       ` Grant Likely
2013-08-21 15:56   ` Matt Sealey
     [not found]   ` <1377247141-11284-1-git-send-email-m.szyprowski@samsung.com>
2013-08-23 19:27     ` [PATCH v6 3/4 UPDATED] " Stephen Warren
2013-08-26 12:20   ` [PATCH v6 3/4] " Rob Herring
2013-08-19 15:04 ` [PATCH v6 4/4] ARM: init: add support for reserved memory defined by device tree Marek Szyprowski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).