Skip to contentSkip to conversation

Add hardware I/O coherency support for Armada 370/XP

PATCH Superseded Gregory CLEMENT 2 participants 9 messages Nov 20, 2012 – Nov 21, 2012

Subsystems (5)

v3 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

v3 cover Add hardware I/O coherency support for Armada 370/XP

The purpose of this patch set is to add hardware I/O Coherency support for Armada 370 and Armada XP. Theses SoCs come with an unit called coherency fabric. A beginning of the support for this unit have been introduced with the SMP patch set. This series extend this support:
the coherency fabric unit allows to use the Armada XP and the Armada 370 as nearly coherent architectures.

The third patches enables this new feature and register our own set of DMA ops, to benefit this hardware enhancement.

The first patches exports dma operation functions needed by to register our own set of dma ops.

The second patch introduces a new flag for the address decoding configuration in order to be able to set the memory windows as shared memory.

This series depend on the SMP patch set (V5 was posted few minutes earlier)

The git branch called HWIOCC-for-3.8-V3 is also available at
https://github.com/MISL-EBU-System-SW/mainline-public.git.

Changelog:
V2 -> V3:
- Rebased on to ArmadaXP-SMP-for-3.8-V5
- Use the coherent version of dma ops for .alloc() and .free()

V1 -> V2:
- Rebased on to v3.7-rc5
- Added a new patch to exports the dma ops functions
- Renamed the function for a more generic name mvebu_hwcc
- removed the non SMP case during init
- spelling and wording issues
- updating the binding documentation for coherency fabric

Gregory CLEMENT (3):
arm: dma mapping: Export dma ops functions
arm: plat-orion: Add coherency attribute when setup mbus target
arm: mvebu: Add hardware I/O Coherency support

 .../devicetree/bindings/arm/coherency-fabric.txt   |    9 ++-
 arch/arm/boot/dts/armada-370-xp.dtsi               |    3 +-
 arch/arm/include/asm/dma-mapping.h                 |   48 +++++++++++++
 arch/arm/mach-mvebu/addr-map.c                     |    3 +
 arch/arm/mach-mvebu/coherency.c                    |   73 ++++++++++++++++++++
 arch/arm/mm/dma-mapping.c                          |   25 ++-----
 arch/arm/plat-orion/addr-map.c                     |    4 ++
 arch/arm/plat-orion/include/plat/addr-map.h        |    1 +
 8 files changed, 143 insertions(+), 23 deletions(-)
Signature · 1 line
1.7.9.5
#1 lore raw

PATCH v3 1/3 arm: dma mapping: Export dma ops functions

Expose the DMA operations functions. Until now only the dma_ops structs in a whole or some dma operation were exposed. This patch exposes all the dma coherents operations. They can be reused when an architecture or a driver need to create its own set of dma_operation.

---
 arch/arm/include/asm/dma-mapping.h |   48 ++++++++++++++++++++++++++++++++++++
 arch/arm/mm/dma-mapping.c          |   25 ++++---------------
 2 files changed, 53 insertions(+), 20 deletions(-)
arch/arm/include/asm/dma-mapping.h +48 -0
index 2300484..b12d7c0 100644
@@ -112,6 +112,54 @@ static inline void dma_free_noncoherent(struct device *dev, size_t size,
 extern int dma_supported(struct device *dev, u64 mask);
 
 /**
+ * arm_dma_map_page - map a portion of a page for streaming DMA
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @page: page that buffer resides in
+ * @offset: offset into page for start of buffer
+ * @size: size of buffer to map
+ * @dir: DMA transfer direction
+ *
+ * Ensure that any data held in the cache is appropriately discarded
+ * or written back.
+ *
+ * The device owns this memory once this call has completed.  The CPU
+ * can regain ownership by calling dma_unmap_page().
+ */
+extern dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
+				    unsigned long offset, size_t size,
+				    enum dma_data_direction dir,
+				    struct dma_attrs *attrs);
+
+/**
+ * arm_dma_unmap_page - unmap a buffer previously mapped through dma_map_page()
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @handle: DMA address of buffer
+ * @size: size of buffer (same as passed to dma_map_page)
+ * @dir: DMA transfer direction (same as passed to dma_map_page)
+ *
+ * Unmap a page streaming mode DMA translation.  The handle and size
+ * must match what was provided in the previous dma_map_page() call.
+ * All other usages are undefined.
+ *
+ * After this call, reads by the CPU to the buffer are guaranteed to see
+ * whatever the device wrote there.
+ */
+extern void arm_dma_unmap_page(struct device *dev, dma_addr_t handle,
+				size_t size, enum dma_data_direction dir,
+				struct dma_attrs *attrs);
+
+extern void arm_dma_sync_single_for_cpu(struct device *dev,
+					dma_addr_t handle, size_t size,
+					enum dma_data_direction dir);
+
+extern void arm_dma_sync_single_for_device(struct device *dev,
+					dma_addr_t handle, size_t size,
+					enum dma_data_direction dir);
+
+extern int arm_dma_set_mask(struct device *dev, u64 dma_mask);
+
+
+/**
  * arm_dma_alloc - allocate consistent memory for DMA
  * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
  * @size: required memory size
arch/arm/mm/dma-mapping.c +5 -20
index 58bc3e4..dbb67ce 100644
@@ -56,20 +56,13 @@ static void __dma_page_dev_to_cpu(struct page *, unsigned long,
 		size_t, enum dma_data_direction);
 
 /**
- * arm_dma_map_page - map a portion of a page for streaming DMA
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @page: page that buffer resides in
- * @offset: offset into page for start of buffer
- * @size: size of buffer to map
- * @dir: DMA transfer direction
- *
  * Ensure that any data held in the cache is appropriately discarded
  * or written back.
  *
  * The device owns this memory once this call has completed.  The CPU
  * can regain ownership by calling dma_unmap_page().
  */
-static dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
+dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
 	     unsigned long offset, size_t size, enum dma_data_direction dir,
 	     struct dma_attrs *attrs)
 {
@@ -86,12 +79,6 @@ static dma_addr_t arm_coherent_dma_map_page(struct device *dev, struct page *pag
 }
 
 /**
- * arm_dma_unmap_page - unmap a buffer previously mapped through dma_map_page()
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @handle: DMA address of buffer
- * @size: size of buffer (same as passed to dma_map_page)
- * @dir: DMA transfer direction (same as passed to dma_map_page)
- *
  * Unmap a page streaming mode DMA translation.  The handle and size
  * must match what was provided in the previous dma_map_page() call.
  * All other usages are undefined.
@@ -99,7 +86,7 @@ static dma_addr_t arm_coherent_dma_map_page(struct device *dev, struct page *pag
  * After this call, reads by the CPU to the buffer are guaranteed to see
  * whatever the device wrote there.
  */
-static void arm_dma_unmap_page(struct device *dev, dma_addr_t handle,
+void arm_dma_unmap_page(struct device *dev, dma_addr_t handle,
 		size_t size, enum dma_data_direction dir,
 		struct dma_attrs *attrs)
 {
@@ -108,7 +95,7 @@ static void arm_dma_unmap_page(struct device *dev, dma_addr_t handle,
 				      handle & ~PAGE_MASK, size, dir);
 }
 
-static void arm_dma_sync_single_for_cpu(struct device *dev,
+void arm_dma_sync_single_for_cpu(struct device *dev,
 		dma_addr_t handle, size_t size, enum dma_data_direction dir)
 {
 	unsigned int offset = handle & (PAGE_SIZE - 1);
@@ -116,7 +103,7 @@ static void arm_dma_sync_single_for_cpu(struct device *dev,
 	__dma_page_dev_to_cpu(page, offset, size, dir);
 }
 
-static void arm_dma_sync_single_for_device(struct device *dev,
+void arm_dma_sync_single_for_device(struct device *dev,
 		dma_addr_t handle, size_t size, enum dma_data_direction dir)
 {
 	unsigned int offset = handle & (PAGE_SIZE - 1);
@@ -124,8 +111,6 @@ static void arm_dma_sync_single_for_device(struct device *dev,
 	__dma_page_cpu_to_dev(page, offset, size, dir);
 }
 
-static int arm_dma_set_mask(struct device *dev, u64 dma_mask);
-
 struct dma_map_ops arm_dma_ops = {
 	.alloc			= arm_dma_alloc,
 	.free			= arm_dma_free,
@@ -971,7 +956,7 @@ int dma_supported(struct device *dev, u64 mask)
 }
 EXPORT_SYMBOL(dma_supported);
 
-static int arm_dma_set_mask(struct device *dev, u64 dma_mask)
+int arm_dma_set_mask(struct device *dev, u64 dma_mask)
 {
 	if (!dev->dma_mask || !dma_supported(dev, dma_mask))
 		return -EIO;
Signature · 1 line
1.7.9.5
#2 lore raw

PATCH v3 1/3 arm: dma mapping: Export dma ops functions

Hello,

Quoted 6 lines · Gregory CLEMENT

Expose the DMA operations functions. Until now only the dma_ops structs in a whole or some dma operation were exposed. This patch exposes all the dma coherents operations. They can be reused when an architecture or a driver need to create its own set of dma_operation.

Besides arm_dma_set_mask() function I see no reason to export the other arm dma related functions.

Quoted 140 lines
---
  arch/arm/include/asm/dma-mapping.h |   48 ++++++++++++++++++++++++++++++++++++
  arch/arm/mm/dma-mapping.c          |   25 ++++---------------
  2 files changed, 53 insertions(+), 20 deletions(-)
arch/arm/include/asm/dma-mapping.h +48 -0
index 2300484..b12d7c0 100644
@@ -112,6 +112,54 @@ static inline void dma_free_noncoherent(struct device *dev, size_t size,
  extern int dma_supported(struct device *dev, u64 mask);
 
  /**
+ * arm_dma_map_page - map a portion of a page for streaming DMA
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @page: page that buffer resides in
+ * @offset: offset into page for start of buffer
+ * @size: size of buffer to map
+ * @dir: DMA transfer direction
+ *
+ * Ensure that any data held in the cache is appropriately discarded
+ * or written back.
+ *
+ * The device owns this memory once this call has completed.  The CPU
+ * can regain ownership by calling dma_unmap_page().
+ */
+extern dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
+				    unsigned long offset, size_t size,
+				    enum dma_data_direction dir,
+				    struct dma_attrs *attrs);
+
+/**
+ * arm_dma_unmap_page - unmap a buffer previously mapped through dma_map_page()
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @handle: DMA address of buffer
+ * @size: size of buffer (same as passed to dma_map_page)
+ * @dir: DMA transfer direction (same as passed to dma_map_page)
+ *
+ * Unmap a page streaming mode DMA translation.  The handle and size
+ * must match what was provided in the previous dma_map_page() call.
+ * All other usages are undefined.
+ *
+ * After this call, reads by the CPU to the buffer are guaranteed to see
+ * whatever the device wrote there.
+ */
+extern void arm_dma_unmap_page(struct device *dev, dma_addr_t handle,
+				size_t size, enum dma_data_direction dir,
+				struct dma_attrs *attrs);
+
+extern void arm_dma_sync_single_for_cpu(struct device *dev,
+					dma_addr_t handle, size_t size,
+					enum dma_data_direction dir);
+
+extern void arm_dma_sync_single_for_device(struct device *dev,
+					dma_addr_t handle, size_t size,
+					enum dma_data_direction dir);
+
+extern int arm_dma_set_mask(struct device *dev, u64 dma_mask);
+
+
+/**
   * arm_dma_alloc - allocate consistent memory for DMA
   * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
   * @size: required memory size
arch/arm/mm/dma-mapping.c +4 -19
index 58bc3e4..dbb67ce 100644
@@ -56,20 +56,13 @@ static void __dma_page_dev_to_cpu(struct page *, unsigned long,
  		size_t, enum dma_data_direction);
 
  /**
- * arm_dma_map_page - map a portion of a page for streaming DMA
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @page: page that buffer resides in
- * @offset: offset into page for start of buffer
- * @size: size of buffer to map
- * @dir: DMA transfer direction
- *
   * Ensure that any data held in the cache is appropriately discarded
   * or written back.
   *
   * The device owns this memory once this call has completed.  The CPU
   * can regain ownership by calling dma_unmap_page().
   */
-static dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
+dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
  	     unsigned long offset, size_t size, enum dma_data_direction dir,
  	     struct dma_attrs *attrs)
  {
@@ -86,12 +79,6 @@ static dma_addr_t arm_coherent_dma_map_page(struct device *dev, struct page *pag
  }
 
  /**
- * arm_dma_unmap_page - unmap a buffer previously mapped through dma_map_page()
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @handle: DMA address of buffer
- * @size: size of buffer (same as passed to dma_map_page)
- * @dir: DMA transfer direction (same as passed to dma_map_page)
- *
   * Unmap a page streaming mode DMA translation.  The handle and size
   * must match what was provided in the previous dma_map_page() call.
   * All other usages are undefined.
@@ -99,7 +86,7 @@ static dma_addr_t arm_coherent_dma_map_page(struct device *dev, struct page *pag
   * After this call, reads by the CPU to the buffer are guaranteed to see
   * whatever the device wrote there.
   */
-static void arm_dma_unmap_page(struct device *dev, dma_addr_t handle,
+void arm_dma_unmap_page(struct device *dev, dma_addr_t handle,
  		size_t size, enum dma_data_direction dir,
  		struct dma_attrs *attrs)
  {
@@ -108,7 +95,7 @@ static void arm_dma_unmap_page(struct device *dev, dma_addr_t handle,
  				      handle & ~PAGE_MASK, size, dir);
  }
 
-static void arm_dma_sync_single_for_cpu(struct device *dev,
+void arm_dma_sync_single_for_cpu(struct device *dev,
  		dma_addr_t handle, size_t size, enum dma_data_direction dir)
  {
  	unsigned int offset = handle & (PAGE_SIZE - 1);
@@ -116,7 +103,7 @@ static void arm_dma_sync_single_for_cpu(struct device *dev,
  	__dma_page_dev_to_cpu(page, offset, size, dir);
  }
 
-static void arm_dma_sync_single_for_device(struct device *dev,
+void arm_dma_sync_single_for_device(struct device *dev,
  		dma_addr_t handle, size_t size, enum dma_data_direction dir)
  {
  	unsigned int offset = handle & (PAGE_SIZE - 1);
@@ -124,8 +111,6 @@ static void arm_dma_sync_single_for_device(struct device *dev,
  	__dma_page_cpu_to_dev(page, offset, size, dir);
  }
 
-static int arm_dma_set_mask(struct device *dev, u64 dma_mask);
-
  struct dma_map_ops arm_dma_ops = {
  	.alloc			= arm_dma_alloc,
  	.free			= arm_dma_free,

arch/arm/mm/dma-mapping.c int dma_supported(struct device *dev, u64 mask) · line 962

Quoted 8 lines
arch/arm/mm/dma-mapping.c +1 -1
@@ -971,7 +956,7 @@ int dma_supported(struct device *dev, u64 mask)
  }
  EXPORT_SYMBOL(dma_supported);
 
-static int arm_dma_set_mask(struct device *dev, u64 dma_mask)
+int arm_dma_set_mask(struct device *dev, u64 dma_mask)
  {
  	if (!dev->dma_mask || !dma_supported(dev, dma_mask))
  		return -EIO;

Best regards

Signature · 2 lines
Marek Szyprowski
Samsung Poland R&D Center
#3 lore raw

PATCH v3 1/3 arm: dma mapping: Export dma ops functions

Quoted 1 line · Marek Szyprowski

Hello,

Hello,

Quoted 11 lines · Gregory CLEMENT
Quoted 6 lines

Expose the DMA operations functions. Until now only the dma_ops structs in a whole or some dma operation were exposed. This patch exposes all the dma coherents operations. They can be reused when an architecture or a driver need to create its own set of dma_operation.

Besides arm_dma_set_mask() function I see no reason to export the other arm dma related functions.

The idea was to let other people use the arm dma related functions, for their own dma ops. But for the mvebu machines we only need arm_dma_set_mask() indeed.

So you prefer that I only expose arm_dma_set_mask() and let future user expose other function if they need it, right?

Thanks,
Gregory

Quoted 152 lines
Quoted 141 lines
---
  arch/arm/include/asm/dma-mapping.h |   48 ++++++++++++++++++++++++++++++++++++
  arch/arm/mm/dma-mapping.c          |   25 ++++---------------
  2 files changed, 53 insertions(+), 20 deletions(-)
arch/arm/include/asm/dma-mapping.h +48 -0
index 2300484..b12d7c0 100644
@@ -112,6 +112,54 @@ static inline void dma_free_noncoherent(struct device *dev, size_t size,
  extern int dma_supported(struct device *dev, u64 mask);
 
  /**
+ * arm_dma_map_page - map a portion of a page for streaming DMA
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @page: page that buffer resides in
+ * @offset: offset into page for start of buffer
+ * @size: size of buffer to map
+ * @dir: DMA transfer direction
+ *
+ * Ensure that any data held in the cache is appropriately discarded
+ * or written back.
+ *
+ * The device owns this memory once this call has completed.  The CPU
+ * can regain ownership by calling dma_unmap_page().
+ */
+extern dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
+				    unsigned long offset, size_t size,
+				    enum dma_data_direction dir,
+				    struct dma_attrs *attrs);
+
+/**
+ * arm_dma_unmap_page - unmap a buffer previously mapped through dma_map_page()
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @handle: DMA address of buffer
+ * @size: size of buffer (same as passed to dma_map_page)
+ * @dir: DMA transfer direction (same as passed to dma_map_page)
+ *
+ * Unmap a page streaming mode DMA translation.  The handle and size
+ * must match what was provided in the previous dma_map_page() call.
+ * All other usages are undefined.
+ *
+ * After this call, reads by the CPU to the buffer are guaranteed to see
+ * whatever the device wrote there.
+ */
+extern void arm_dma_unmap_page(struct device *dev, dma_addr_t handle,
+				size_t size, enum dma_data_direction dir,
+				struct dma_attrs *attrs);
+
+extern void arm_dma_sync_single_for_cpu(struct device *dev,
+					dma_addr_t handle, size_t size,
+					enum dma_data_direction dir);
+
+extern void arm_dma_sync_single_for_device(struct device *dev,
+					dma_addr_t handle, size_t size,
+					enum dma_data_direction dir);
+
+extern int arm_dma_set_mask(struct device *dev, u64 dma_mask);
+
+
+/**
   * arm_dma_alloc - allocate consistent memory for DMA
   * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
   * @size: required memory size
arch/arm/mm/dma-mapping.c +4 -19
index 58bc3e4..dbb67ce 100644
@@ -56,20 +56,13 @@ static void __dma_page_dev_to_cpu(struct page *, unsigned long,
  		size_t, enum dma_data_direction);
 
  /**
- * arm_dma_map_page - map a portion of a page for streaming DMA
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @page: page that buffer resides in
- * @offset: offset into page for start of buffer
- * @size: size of buffer to map
- * @dir: DMA transfer direction
- *
   * Ensure that any data held in the cache is appropriately discarded
   * or written back.
   *
   * The device owns this memory once this call has completed.  The CPU
   * can regain ownership by calling dma_unmap_page().
   */
-static dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
+dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
  	     unsigned long offset, size_t size, enum dma_data_direction dir,
  	     struct dma_attrs *attrs)
  {
@@ -86,12 +79,6 @@ static dma_addr_t arm_coherent_dma_map_page(struct device *dev, struct page *pag
  }
 
  /**
- * arm_dma_unmap_page - unmap a buffer previously mapped through dma_map_page()
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @handle: DMA address of buffer
- * @size: size of buffer (same as passed to dma_map_page)
- * @dir: DMA transfer direction (same as passed to dma_map_page)
- *
   * Unmap a page streaming mode DMA translation.  The handle and size
   * must match what was provided in the previous dma_map_page() call.
   * All other usages are undefined.
@@ -99,7 +86,7 @@ static dma_addr_t arm_coherent_dma_map_page(struct device *dev, struct page *pag
   * After this call, reads by the CPU to the buffer are guaranteed to see
   * whatever the device wrote there.
   */
-static void arm_dma_unmap_page(struct device *dev, dma_addr_t handle,
+void arm_dma_unmap_page(struct device *dev, dma_addr_t handle,
  		size_t size, enum dma_data_direction dir,
  		struct dma_attrs *attrs)
  {
@@ -108,7 +95,7 @@ static void arm_dma_unmap_page(struct device *dev, dma_addr_t handle,
  				      handle & ~PAGE_MASK, size, dir);
  }
 
-static void arm_dma_sync_single_for_cpu(struct device *dev,
+void arm_dma_sync_single_for_cpu(struct device *dev,
  		dma_addr_t handle, size_t size, enum dma_data_direction dir)
  {
  	unsigned int offset = handle & (PAGE_SIZE - 1);
@@ -116,7 +103,7 @@ static void arm_dma_sync_single_for_cpu(struct device *dev,
  	__dma_page_dev_to_cpu(page, offset, size, dir);
  }
 
-static void arm_dma_sync_single_for_device(struct device *dev,
+void arm_dma_sync_single_for_device(struct device *dev,
  		dma_addr_t handle, size_t size, enum dma_data_direction dir)
  {
  	unsigned int offset = handle & (PAGE_SIZE - 1);
@@ -124,8 +111,6 @@ static void arm_dma_sync_single_for_device(struct device *dev,
  	__dma_page_cpu_to_dev(page, offset, size, dir);
  }
 
-static int arm_dma_set_mask(struct device *dev, u64 dma_mask);
-
  struct dma_map_ops arm_dma_ops = {
  	.alloc			= arm_dma_alloc,
  	.free			= arm_dma_free,

arch/arm/mm/dma-mapping.c int dma_supported(struct device *dev, u64 mask) · line 962

Quoted 8 lines
arch/arm/mm/dma-mapping.c +1 -1
@@ -971,7 +956,7 @@ int dma_supported(struct device *dev, u64 mask)
  }
  EXPORT_SYMBOL(dma_supported);
 
-static int arm_dma_set_mask(struct device *dev, u64 dma_mask)
+int arm_dma_set_mask(struct device *dev, u64 dma_mask)
  {
  	if (!dev->dma_mask || !dma_supported(dev, dma_mask))
  		return -EIO;

Best regards

Signature · 4 lines
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
#4 lore raw

PATCH v3 1/3 arm: dma mapping: Export dma ops functions

Hello,

Quoted 12 lines · Gregory CLEMENT
Quoted 10 lines · Marek Szyprowski
Quoted 6 lines · Gregory CLEMENT

Expose the DMA operations functions. Until now only the dma_ops structs in a whole or some dma operation were exposed. This patch exposes all the dma coherents operations. They can be reused when an architecture or a driver need to create its own set of dma_operation.

Besides arm_dma_set_mask() function I see no reason to export the other arm dma related functions.

Quoted 6 lines

The idea was to let other people use the arm dma related functions, for their own dma ops. But for the mvebu machines we only need arm_dma_set_mask() indeed.

So you prefer that I only expose arm_dma_set_mask() and let future user expose other function if they need it, right?

I would prefer to avoid exporting functions which are not used anywhere else. This improves readability of the code and simply forces others to think twice before they use some static function and check if their use case is really correct.

Best regards

Signature · 2 lines
Marek Szyprowski
Samsung Poland R&D Center
#5 lore raw

PATCH v3 1/3 arm: dma mapping: Export dma ops functions

Quoted 19 lines · Marek Szyprowski

Hello,

Quoted 16 lines · Gregory CLEMENT
Quoted 10 lines · Marek Szyprowski
Quoted 6 lines · Gregory CLEMENT

Expose the DMA operations functions. Until now only the dma_ops structs in a whole or some dma operation were exposed. This patch exposes all the dma coherents operations. They can be reused when an architecture or a driver need to create its own set of dma_operation.

Besides arm_dma_set_mask() function I see no reason to export the other arm dma related functions.

The idea was to let other people use the arm dma related functions, for their own dma ops. But for the mvebu machines we only need arm_dma_set_mask() indeed.

Quoted 7 lines
Quoted 2 lines

So you prefer that I only expose arm_dma_set_mask() and let future user expose other function if they need it, right?

I would prefer to avoid exporting functions which are not used anywhere else. This improves readability of the code and simply forces others to think twice before they use some static function and check if their use case is really correct.

OK so I will send a new version in a few minutes.

Do you think these last changes will be enough for getting your Acked-by?

Thanks,
Greogry

#6 lore raw

PATCH v3 1/3 arm: dma mapping: Export dma ops functions

Hello,

Quoted 23 lines · Gregory CLEMENT
Quoted 22 lines · Marek Szyprowski

Hello,

Quoted 18 lines · Gregory CLEMENT
Quoted 10 lines · Marek Szyprowski
Quoted 6 lines · Gregory CLEMENT

Expose the DMA operations functions. Until now only the dma_ops structs in a whole or some dma operation were exposed. This patch exposes all the dma coherents operations. They can be reused when an architecture or a driver need to create its own set of dma_operation.

Besides arm_dma_set_mask() function I see no reason to export the other arm dma related functions.

The idea was to let other people use the arm dma related functions, for their own dma ops. But for the mvebu machines we only need arm_dma_set_mask() indeed.

So you prefer that I only expose arm_dma_set_mask() and let future user expose other function if they need it, right?

Quoted 8 lines
Quoted 4 lines

I would prefer to avoid exporting functions which are not used anywhere else. This improves readability of the code and simply forces others to think twice before they use some static function and check if their use case is really correct.

OK so I will send a new version in a few minutes.

Do you think these last changes will be enough for getting your Acked-by?

Yes, I see no other issues right now.

Best regards

Signature · 2 lines
Marek Szyprowski
Samsung Poland R&D Center
#7 lore raw

PATCH v3 2/3 arm: plat-orion: Add coherency attribute when setup mbus target

In reply to Gregory CLEMENT

Recent SoC such as Armada 370/XP came with the possibility to deal with the I/O coherency by hardware. In this case the transaction attribute of the window must be flagged as "Shared transaction". Once this flag is set, then the transactions will be forced to be sent through the coherency block, in other case transaction is driven directly to DRAM.

---
 arch/arm/plat-orion/addr-map.c              |    4 ++++
 arch/arm/plat-orion/include/plat/addr-map.h |    1 +
 2 files changed, 5 insertions(+)
arch/arm/plat-orion/addr-map.c +4 -0
index a7b8060..febe386 100644
@@ -42,6 +42,8 @@ EXPORT_SYMBOL_GPL(mv_mbus_dram_info);
 #define WIN_REMAP_LO_OFF	0x0008
 #define WIN_REMAP_HI_OFF	0x000c
 
+#define ATTR_HW_COHERENCY	(0x1 << 4)
+
 /*
  * Default implementation
  */
@@ -163,6 +165,8 @@ void __init orion_setup_cpu_mbus_target(const struct orion_addr_map_cfg *cfg,
 			w = &orion_mbus_dram_info.cs[cs++];
 			w->cs_index = i;
 			w->mbus_attr = 0xf & ~(1 << i);
+			if (cfg->hw_io_coherency)
+				w->mbus_attr |= ATTR_HW_COHERENCY;
 			w->base = base & 0xffff0000;
 			w->size = (size | 0x0000ffff) + 1;
 		}
arch/arm/plat-orion/include/plat/addr-map.h +1 -0
index ec63e4a..b76c065 100644
@@ -17,6 +17,7 @@ struct orion_addr_map_cfg {
 	const int num_wins;	/* Total number of windows */
 	const int remappable_wins;
 	void __iomem *bridge_virt_base;
+	int hw_io_coherency;
 
 	/* If NULL, the default cpu_win_can_remap will be used, using
 	   the value in remappable_wins */
Signature · 1 line
1.7.9.5
#8 lore raw

PATCH v3 3/3 arm: mvebu: Add hardware I/O Coherency support

In reply to Gregory CLEMENT

Armada 370 and XP come with an unit called coherency fabric. This unit allows to use the Armada 370/XP as a nearly coherent architecture. The coherency mechanism uses snoop filters to ensure the coherency between caches, DRAM and devices. This mechanism needs a synchronization barrier which guarantees that all the memory writes initiated by the devices have reached their target and do not reside in intermediate write buffers. That's why the architecture is not totally coherent and we need to provide our own functions for some DMA operations.

Beside the use of the coherency fabric, the device units will have to set the attribute flag of the decoding address window to select the accurate coherency process for the memory transaction. This is done each device driver programs the DRAM address windows. The value of the attribute set by the driver is retrieved through the orion_addr_map_cfg struct filled during the early initialization of the platform.

---
 .../devicetree/bindings/arm/coherency-fabric.txt   |    9 ++-
 arch/arm/boot/dts/armada-370-xp.dtsi               |    3 +-
 arch/arm/mach-mvebu/addr-map.c                     |    3 +
 arch/arm/mach-mvebu/coherency.c                    |   73 ++++++++++++++++++++
 4 files changed, 85 insertions(+), 3 deletions(-)
Documentation/devicetree/bindings/arm/coherency-fabric.txt +7 -2
index 2bfbf67..17d8cd1 100644
@@ -5,12 +5,17 @@ Available on Marvell SOCs: Armada 370 and Armada XP
 Required properties:
 
 - compatible: "marvell,coherency-fabric"
-- reg: Should contain,coherency fabric registers location and length.
+
+- reg: Should contain coherency fabric registers location and
+  length. First pair for the coherency fabric registers, second pair
+  for the per-CPU fabric registers registers.
 
 Example:
 
 coherency-fabric at d0020200 {
 	compatible = "marvell,coherency-fabric";
-	reg = <0xd0020200 0xb0>;
+	reg = <0xd0020200 0xb0>,
+		<0xd0021810 0x1c>;
+
 };
 
arch/arm/boot/dts/armada-370-xp.dtsi +2 -1
index b0d075b..98a6b26 100644
@@ -38,7 +38,8 @@
 
 	coherency-fabric at d0020200 {
 		compatible = "marvell,coherency-fabric";
-		reg = <0xd0020200 0xb0>;
+		reg = <0xd0020200 0xb0>,
+		      <0xd0021810 0x1c>;
 	};
 
 	soc {
arch/arm/mach-mvebu/addr-map.c +3 -0
index fe454a4..595f6b7 100644
@@ -108,6 +108,9 @@ static int __init armada_setup_cpu_mbus(void)
 
 	addr_map_cfg.bridge_virt_base = mbus_unit_addr_decoding_base;
 
+	if (of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric"))
+		addr_map_cfg.hw_io_coherency = 1;
+
 	/*
 	 * Disable, clear and configure windows.
 	 */
arch/arm/mach-mvebu/coherency.c +73 -0

101 lines not on this page · raw message

Signature · 1 line
1.7.9.5